Merge ../linux-2.6/
diff --git a/Documentation/Changes b/Documentation/Changes
index afebdbc..dfec756 100644
--- a/Documentation/Changes
+++ b/Documentation/Changes
@@ -57,7 +57,7 @@
 o  jfsutils               1.1.3                   # fsck.jfs -V
 o  reiserfsprogs          3.6.3                   # reiserfsck -V 2>&1|grep reiserfsprogs
 o  xfsprogs               2.6.0                   # xfs_db -V
-o  pcmciautils            001
+o  pcmciautils            004
 o  pcmcia-cs              3.1.21                  # cardmgr -V
 o  quota-tools            3.09                    # quota -V
 o  PPP                    2.4.0                   # pppd --version
diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl
index 6df1dfd..375ae76 100644
--- a/Documentation/DocBook/libata.tmpl
+++ b/Documentation/DocBook/libata.tmpl
@@ -84,6 +84,14 @@
 	Called from ata_bus_probe() and ata_bus_reset() error paths,
 	as well as when unregistering from the SCSI module (rmmod, hot
 	unplug).
+	This function should do whatever needs to be done to take the
+	port out of use.  In most cases, ata_port_disable() can be used
+	as this hook.
+	</para>
+	<para>
+	Called from ata_bus_probe() on a failed probe.
+	Called from ata_bus_reset() on a failed bus reset.
+	Called from ata_scsi_release().
 	</para>
 
 	</sect2>
@@ -98,6 +106,13 @@
 	found.  Typically used to apply device-specific fixups prior to
 	issue of SET FEATURES - XFER MODE, and prior to operation.
 	</para>
+	<para>
+	Called by ata_device_add() after ata_dev_identify() determines
+	a device is present.
+	</para>
+	<para>
+	This entry may be specified as NULL in ata_port_operations.
+	</para>
 
 	</sect2>
 
@@ -135,6 +150,8 @@
 	registers / DMA buffers.  ->tf_read() is called to read the
 	hardware registers / DMA buffers, to obtain the current set of
 	taskfile register values.
+	Most drivers for taskfile-based hardware (PIO or MMIO) use
+	ata_tf_load() and ata_tf_read() for these hooks.
 	</para>
 
 	</sect2>
@@ -147,6 +164,8 @@
 	<para>
 	causes an ATA command, previously loaded with
 	->tf_load(), to be initiated in hardware.
+	Most drivers for taskfile-based hardware use ata_exec_command()
+	for this hook.
 	</para>
 
 	</sect2>
@@ -161,6 +180,10 @@
 indicating whether or not it is OK to use DMA for the supplied PACKET
 command.
 	</para>
+	<para>
+	This hook may be specified as NULL, in which case libata will
+	assume that atapi dma can be supported.
+	</para>
 
 	</sect2>
 
@@ -175,6 +198,14 @@
 	Reads the Status/AltStatus/Error ATA shadow register from
 	hardware.  On some hardware, reading the Status register has
 	the side effect of clearing the interrupt condition.
+	Most drivers for taskfile-based hardware use
+	ata_check_status() for this hook.
+	</para>
+	<para>
+	Note that because this is called from ata_device_add(), at
+	least a dummy function that clears device interrupts must be
+	provided for all drivers, even if the controller doesn't
+	actually have a taskfile status register.
 	</para>
 
 	</sect2>
@@ -188,7 +219,13 @@
 	Issues the low-level hardware command(s) that causes one of N
 	hardware devices to be considered 'selected' (active and
 	available for use) on the ATA bus.  This generally has no
-meaning on FIS-based devices.
+	meaning on FIS-based devices.
+	</para>
+	<para>
+	Most drivers for taskfile-based hardware use
+	ata_std_dev_select() for this hook.  Controllers which do not
+	support second drives on a port (such as SATA contollers) will
+	use ata_noop_dev_select().
 	</para>
 
 	</sect2>
@@ -204,6 +241,8 @@
 	for device presence (PATA and SATA), typically a soft reset
 	(SRST) will be performed.  Drivers typically use the helper
 	functions ata_bus_reset() or sata_phy_reset() for this hook.
+	Many SATA drivers use sata_phy_reset() or call it from within
+	their own phy_reset() functions.
 	</para>
 
 	</sect2>
@@ -227,6 +266,25 @@
 These hooks are typically either no-ops, or simply not implemented, in
 FIS-based drivers.
 	</para>
+	<para>
+Most legacy IDE drivers use ata_bmdma_setup() for the bmdma_setup()
+hook.  ata_bmdma_setup() will write the pointer to the PRD table to
+the IDE PRD Table Address register, enable DMA in the DMA Command
+register, and call exec_command() to begin the transfer.
+	</para>
+	<para>
+Most legacy IDE drivers use ata_bmdma_start() for the bmdma_start()
+hook.  ata_bmdma_start() will write the ATA_DMA_START flag to the DMA
+Command register.
+	</para>
+	<para>
+Many legacy IDE drivers use ata_bmdma_stop() for the bmdma_stop()
+hook.  ata_bmdma_stop() clears the ATA_DMA_START flag in the DMA
+command register.
+	</para>
+	<para>
+Many legacy IDE drivers use ata_bmdma_status() as the bmdma_status() hook.
+	</para>
 
 	</sect2>
 
@@ -250,6 +308,10 @@
 	helper function ata_qc_issue_prot() for taskfile protocol-based
 	dispatch.  More advanced drivers implement their own ->qc_issue.
 	</para>
+	<para>
+	ata_qc_issue_prot() calls ->tf_load(), ->bmdma_setup(), and
+	->bmdma_start() as necessary to initiate a transfer.
+	</para>
 
 	</sect2>
 
@@ -279,6 +341,21 @@
 	before the interrupt handler is registered, to be sure hardware
 	is quiet.
 	</para>
+	<para>
+	The second argument, dev_instance, should be cast to a pointer
+	to struct ata_host_set.
+	</para>
+	<para>
+	Most legacy IDE drivers use ata_interrupt() for the
+	irq_handler hook, which scans all ports in the host_set,
+	determines which queued command was active (if any), and calls
+	ata_host_intr(ap,qc).
+	</para>
+	<para>
+	Most legacy IDE drivers use ata_bmdma_irq_clear() for the
+	irq_clear() hook, which simply clears the interrupt and error
+	flags in the DMA status register.
+	</para>
 
 	</sect2>
 
@@ -292,6 +369,7 @@
 	<para>
 	Read and write standard SATA phy registers.  Currently only used
 	if ->phy_reset hook called the sata_phy_reset() helper function.
+	sc_reg is one of SCR_STATUS, SCR_CONTROL, SCR_ERROR, or SCR_ACTIVE.
 	</para>
 
 	</sect2>
@@ -307,17 +385,29 @@
 	->port_start() is called just after the data structures for each
 	port are initialized.  Typically this is used to alloc per-port
 	DMA buffers / tables / rings, enable DMA engines, and similar
-	tasks.  
+	tasks.  Some drivers also use this entry point as a chance to
+	allocate driver-private memory for ap->private_data.
+	</para>
+	<para>
+	Many drivers use ata_port_start() as this hook or call
+	it from their own port_start() hooks.  ata_port_start()
+	allocates space for a legacy IDE PRD table and returns.
 	</para>
 	<para>
 	->port_stop() is called after ->host_stop().  It's sole function
 	is to release DMA/memory resources, now that they are no longer
-	actively being used.
+	actively being used.  Many drivers also free driver-private
+	data from port at this time.
+	</para>
+	<para>
+	Many drivers use ata_port_stop() as this hook, which frees the
+	PRD table.
 	</para>
 	<para>
 	->host_stop() is called after all ->port_stop() calls
 have completed.  The hook must finalize hardware shutdown, release DMA
 and other resources, etc.
+	This hook may be specified as NULL, in which case it is not called.
 	</para>
 
 	</sect2>
diff --git a/Documentation/SubmittingDrivers b/Documentation/SubmittingDrivers
index de3b252..c3cca92 100644
--- a/Documentation/SubmittingDrivers
+++ b/Documentation/SubmittingDrivers
@@ -13,13 +13,14 @@
 -------------------------
 
 Major and minor numbers for block and character devices are allocated
-by the Linux assigned name and number authority (currently better
-known as H Peter Anvin). The site is http://www.lanana.org/. This
+by the Linux assigned name and number authority (currently this is
+Torben Mathiasen). The site is http://www.lanana.org/. This
 also deals with allocating numbers for devices that are not going to
 be submitted to the mainstream kernel.
+See Documentation/devices.txt for more information on this.
 
-If you don't use assigned numbers then when you device is submitted it will
-get given an assigned number even if that is different from values you may
+If you don't use assigned numbers then when your device is submitted it will
+be given an assigned number even if that is different from values you may
 have shipped to customers before.
 
 Who To Submit Drivers To
@@ -32,7 +33,8 @@
 	If the code area has a general maintainer then please submit it to
 	the maintainer listed in MAINTAINERS in the kernel file. If the
 	maintainer does not respond or you cannot find the appropriate
-	maintainer then please contact Alan Cox <alan@lxorguk.ukuu.org.uk>
+	maintainer then please contact the 2.2 kernel maintainer:
+	Marc-Christian Petersen <m.c.p@wolk-project.de>.
 
 Linux 2.4:
 	The same rules apply as 2.2. The final contact point for Linux 2.4
@@ -48,7 +50,7 @@
 
 Licensing:	The code must be released to us under the
 		GNU General Public License. We don't insist on any kind
-		of exclusively GPL licensing, and if you wish the driver
+		of exclusive GPL licensing, and if you wish the driver
 		to be useful to other communities such as BSD you may well
 		wish to release under multiple licenses.
 
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index 4d1f41b..6761a7b 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -35,7 +35,7 @@
 
 To create a patch for a single file, it is often sufficient to do:
 
-	SRCTREE= linux-2.4
+	SRCTREE= linux-2.6
 	MYFILE=  drivers/net/mydriver.c
 
 	cd $SRCTREE
@@ -48,17 +48,18 @@
 or unmodified kernel source tree, and generate a diff against your
 own source tree.  For example:
 
-	MYSRC= /devel/linux-2.4
+	MYSRC= /devel/linux-2.6
 
-	tar xvfz linux-2.4.0-test11.tar.gz
-	mv linux linux-vanilla
-	wget http://www.moses.uklinux.net/patches/dontdiff
-	diff -uprN -X dontdiff linux-vanilla $MYSRC > /tmp/patch
-	rm -f dontdiff
+	tar xvfz linux-2.6.12.tar.gz
+	mv linux-2.6.12 linux-2.6.12-vanilla
+	diff -uprN -X linux-2.6.12-vanilla/Documentation/dontdiff \
+		linux-2.6.12-vanilla $MYSRC > /tmp/patch
 
 "dontdiff" is a list of files which are generated by the kernel during
 the build process, and should be ignored in any diff(1)-generated
-patch.  dontdiff is maintained by Tigran Aivazian <tigran@veritas.com>
+patch.  The "dontdiff" file is included in the kernel tree in
+2.6.12 and later.  For earlier kernel versions, you can get it
+from <http://www.xenotime.net/linux/doc/dontdiff>.
 
 Make sure your patch does not include any extra files which do not
 belong in a patch submission.  Make sure to review your patch -after-
@@ -66,18 +67,20 @@
 
 If your changes produce a lot of deltas, you may want to look into
 splitting them into individual patches which modify things in
-logical stages, this will facilitate easier reviewing by other
+logical stages.  This will facilitate easier reviewing by other
 kernel developers, very important if you want your patch accepted.
-There are a number of scripts which can aid in this;
+There are a number of scripts which can aid in this:
 
 Quilt:
 http://savannah.nongnu.org/projects/quilt
 
 Randy Dunlap's patch scripts:
-http://developer.osdl.org/rddunlap/scripts/patching-scripts.tgz
+http://www.xenotime.net/linux/scripts/patching-scripts-002.tar.gz
 
 Andrew Morton's patch scripts:
-http://www.zip.com.au/~akpm/linux/patches/patch-scripts-0.16
+http://www.zip.com.au/~akpm/linux/patches/patch-scripts-0.20
+
+
 
 2) Describe your changes.
 
@@ -163,6 +166,8 @@
  since people copy, as long as it's trivial)
  Any fix by the author/maintainer of the file. (ie. patch monkey
  in re-transmission mode)
+URL: <http://www.kernel.org/pub/linux/kernel/people/rusty/trivial/>
+
 
 
 
@@ -291,6 +296,17 @@
 point out some special detail about the sign-off. 
 
 
+
+12) More references for submitting patches
+
+Andrew Morton, "The perfect patch" (tpp).
+  <http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt>
+
+Jeff Garzik, "Linux kernel patch submission format."
+  <http://linux.yyz.us/patch-format.html>
+
+
+
 -----------------------------------
 SECTION 2 - HINTS, TIPS, AND TRICKS
 -----------------------------------
@@ -359,7 +375,5 @@
 4) Don't over-design.
 
 Don't try to anticipate nebulous future cases which may or may not
-be useful:  "Make it as simple as you can, and no simpler"
-
-
+be useful:  "Make it as simple as you can, and no simpler."
 
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 89cd417..4ec75c0 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -622,6 +622,17 @@
 	ips=		[HW,SCSI] Adaptec / IBM ServeRAID controller
 			See header of drivers/scsi/ips.c.
 
+	irqfixup	[HW]
+			When an interrupt is not handled search all handlers
+			for it. Intended to get systems with badly broken
+			firmware running.
+
+	irqpoll		[HW]
+			When an interrupt is not handled search all handlers
+			for it. Also check all handlers each timer
+			interrupt. Intended to get systems with badly broken
+			firmware running.
+
 	isapnp=		[ISAPNP]
 			Format: <RDP>, <reset>, <pci_scan>, <verbosity>
 
@@ -1030,6 +1041,10 @@
 		irqmask=0xMMMM		[IA-32] Set a bit mask of IRQs allowed to be assigned
 					automatically to PCI devices. You can make the kernel
 					exclude IRQs of your ISA cards this way.
+		pirqaddr=0xAAAAA	[IA-32] Specify the physical address
+					of the PIRQ table (normally generated
+					by the BIOS) if it is outside the
+					F0000h-100000h range.
 		lastbus=N		[IA-32] Scan all buses till bus #N. Can be useful
 					if the kernel is unable to find your secondary buses
 					and you want to tell it explicitly which ones they are.
diff --git a/Documentation/networking/fib_trie.txt b/Documentation/networking/fib_trie.txt
new file mode 100644
index 0000000..f50d0c6
--- /dev/null
+++ b/Documentation/networking/fib_trie.txt
@@ -0,0 +1,145 @@
+			LC-trie implementation notes.
+
+Node types
+----------
+leaf 
+	An end node with data. This has a copy of the relevant key, along
+	with 'hlist' with routing table entries sorted by prefix length.
+	See struct leaf and struct leaf_info.
+
+trie node or tnode
+	An internal node, holding an array of child (leaf or tnode) pointers,
+	indexed	through a subset of the key. See Level Compression.
+
+A few concepts explained
+------------------------
+Bits (tnode) 
+	The number of bits in the key segment used for indexing into the
+	child array - the "child index". See Level Compression.
+
+Pos (tnode)
+	The position (in the key) of the key segment used for indexing into
+	the child array. See Path Compression.
+
+Path Compression / skipped bits
+	Any given tnode is linked to from the child array of its parent, using
+	a segment of the key specified by the parent's "pos" and "bits" 
+	In certain cases, this tnode's own "pos" will not be immediately
+	adjacent to the parent (pos+bits), but there will be some bits
+	in the key skipped over because they represent a single path with no
+	deviations. These "skipped bits" constitute Path Compression.
+	Note that the search algorithm will simply skip over these bits when
+	searching, making it necessary to save the keys in the leaves to
+	verify that they actually do match the key we are searching for.
+
+Level Compression / child arrays
+	the trie is kept level balanced moving, under certain conditions, the
+	children of a full child (see "full_children") up one level, so that
+	instead of a pure binary tree, each internal node ("tnode") may
+	contain an arbitrarily large array of links to several children.
+	Conversely, a tnode with a mostly empty	child array (see empty_children)
+	may be "halved", having some of its children moved downwards one level,
+	in order to avoid ever-increasing child arrays.
+
+empty_children
+	the number of positions in the child array of a given tnode that are
+	NULL.
+
+full_children
+	the number of children of a given tnode that aren't path compressed.
+	(in other words, they aren't NULL or leaves and their "pos" is equal
+	to this	tnode's "pos"+"bits").
+
+	(The word "full" here is used more in the sense of "complete" than
+	as the opposite of "empty", which might be a tad confusing.)
+
+Comments
+---------
+
+We have tried to keep the structure of the code as close to fib_hash as 
+possible to allow verification and help up reviewing. 
+
+fib_find_node()
+	A good start for understanding this code. This function implements a
+	straightforward trie lookup.
+
+fib_insert_node()
+	Inserts a new leaf node in the trie. This is bit more complicated than
+	fib_find_node(). Inserting a new node means we might have to run the
+	level compression algorithm on part of the trie.
+
+trie_leaf_remove()
+	Looks up a key, deletes it and runs the level compression algorithm.
+
+trie_rebalance()
+	The key function for the dynamic trie after any change in the trie
+	it is run to optimize and reorganize. Tt will walk the trie upwards 
+	towards the root from a given tnode, doing a resize() at each step 
+	to implement level compression.
+
+resize()
+	Analyzes a tnode and optimizes the child array size by either inflating
+	or shrinking it repeatedly until it fullfills the criteria for optimal
+	level compression. This part follows the original paper pretty closely
+	and there may be some room for experimentation here.
+
+inflate()
+	Doubles the size of the child array within a tnode. Used by resize().
+
+halve()
+	Halves the size of the child array within a tnode - the inverse of
+	inflate(). Used by resize();
+
+fn_trie_insert(), fn_trie_delete(), fn_trie_select_default()
+	The route manipulation functions. Should conform pretty closely to the
+	corresponding functions in fib_hash.
+
+fn_trie_flush()
+	This walks the full trie (using nextleaf()) and searches for empty
+	leaves which have to be removed.
+
+fn_trie_dump()
+	Dumps the routing table ordered by prefix length. This is somewhat
+	slower than the corresponding fib_hash function, as we have to walk the
+	entire trie for each prefix length. In comparison, fib_hash is organized
+	as one "zone"/hash per prefix length.
+
+Locking
+-------
+
+fib_lock is used for an RW-lock in the same way that this is done in fib_hash.
+However, the functions are somewhat separated for other possible locking
+scenarios. It might conceivably be possible to run trie_rebalance via RCU
+to avoid read_lock in the fn_trie_lookup() function.
+
+Main lookup mechanism
+---------------------
+fn_trie_lookup() is the main lookup function.
+
+The lookup is in its simplest form just like fib_find_node(). We descend the
+trie, key segment by key segment, until we find a leaf. check_leaf() does
+the fib_semantic_match in the leaf's sorted prefix hlist.
+
+If we find a match, we are done.
+
+If we don't find a match, we enter prefix matching mode. The prefix length,
+starting out at the same as the key length, is reduced one step at a time,
+and we backtrack upwards through the trie trying to find a longest matching
+prefix. The goal is always to reach a leaf and get a positive result from the
+fib_semantic_match mechanism.
+
+Inside each tnode, the search for longest matching prefix consists of searching
+through the child array, chopping off (zeroing) the least significant "1" of
+the child index until we find a match or the child index consists of nothing but
+zeros.
+
+At this point we backtrack (t->stats.backtrack++) up the trie, continuing to
+chop off part of the key in order to find the longest matching prefix.
+
+At this point we will repeatedly descend subtries to look for a match, and there
+are some optimizations available that can provide us with "shortcuts" to avoid
+descending into dead ends. Look for "HL_OPTIMIZE" sections in the code.
+
+To alleviate any doubts about the correctness of the route selection process,
+a new netlink operation has been added. Look for NETLINK_FIB_LOOKUP, which
+gives userland access to fib_lookup().
diff --git a/Documentation/pcmcia/devicetable.txt b/Documentation/pcmcia/devicetable.txt
index 045511a..3351c035 100644
--- a/Documentation/pcmcia/devicetable.txt
+++ b/Documentation/pcmcia/devicetable.txt
@@ -19,9 +19,8 @@
 If the hash is incorrect, the kernel will inform you about this in "dmesg"
 upon module initialization, and tell you of the correct hash.
 
-You can determine the hash of the product ID strings by running
-"pcmcia-modalias %n.%m" [%n being replaced with the socket number and %m being
-replaced with the device function] from pcmciautils. It generates a string
+You can determine the hash of the product ID strings by catting the file
+"modalias" in the sysfs directory of the PCMCIA device. It generates a string
 in the following form:
 pcmcia:m0149cC1ABf06pfn00fn00pa725B842DpbF1EFEE84pc0877B627pd00000000
 
diff --git a/Documentation/serial/driver b/Documentation/serial/driver
index e9c0178..ac7eabb 100644
--- a/Documentation/serial/driver
+++ b/Documentation/serial/driver
@@ -107,8 +107,8 @@
 	indicate that the signal is permanently active.  If RI is
 	not available, the signal should not be indicated as active.
 
-	Locking: none.
-	Interrupts: caller dependent.
+	Locking: port->lock taken.
+	Interrupts: locally disabled.
 	This call must not sleep
 
   stop_tx(port,tty_stop)
diff --git a/Documentation/video4linux/API.html b/Documentation/video4linux/API.html
index 4b3d8f6..441407b 100644
--- a/Documentation/video4linux/API.html
+++ b/Documentation/video4linux/API.html
@@ -1,399 +1,16 @@
-<HTML><HEAD>
-<TITLE>Video4Linux Kernel API Reference v0.1:19990430</TITLE>
-</HEAD>
-<! Revision History: >
-<!   4/30/1999 - Fred Gleason (fredg@wava.com)>
-<! Documented extensions for the Radio Data System (RDS) extensions >
-<BODY bgcolor="#ffffff">
-<H3>Devices</H3>
-Video4Linux provides the following sets of device files. These live on the
-character device formerly known as "/dev/bttv". /dev/bttv should be a
-symlink to /dev/video0 for most people. 
-<P>
-<TABLE>
-<TR><TH>Device Name</TH><TH>Minor Range</TH><TH>Function</TH>
-<TR><TD>/dev/video</TD><TD>0-63</TD><TD>Video Capture Interface</TD>
-<TR><TD>/dev/radio</TD><TD>64-127</TD><TD>AM/FM Radio Devices</TD>
-<TR><TD>/dev/vtx</TD><TD>192-223</TD><TD>Teletext Interface Chips</TD>
-<TR><TD>/dev/vbi</TD><TD>224-239</TD><TD>Raw VBI Data (Intercast/teletext)</TD>
-</TABLE>
-<P>
-Video4Linux programs open and scan the devices to find what they are looking
-for. Capability queries define what each interface supports. The 
-described API is only defined for video capture cards. The relevant subset
-applies to radio cards. Teletext interfaces talk the existing VTX API.
-<P>
-<H3>Capability Query Ioctl</H3>
-The <B>VIDIOCGCAP</B> ioctl call is used to obtain the capability
-information for a video device. The <b>struct video_capability</b> object
-passed to the ioctl is completed and returned. It contains the following
-information
-<P>
-<TABLE>
-<TR><TD><b>name[32]</b><TD>Canonical name for this interface</TD>
-<TR><TD><b>type</b><TD>Type of interface</TD>
-<TR><TD><b>channels</b><TD>Number of radio/tv channels if appropriate</TD>
-<TR><TD><b>audios</b><TD>Number of audio devices if appropriate</TD>
-<TR><TD><b>maxwidth</b><TD>Maximum capture width in pixels</TD>
-<TR><TD><b>maxheight</b><TD>Maximum capture height in pixels</TD>
-<TR><TD><b>minwidth</b><TD>Minimum capture width in pixels</TD>
-<TR><TD><b>minheight</b><TD>Minimum capture height in pixels</TD>
-</TABLE>
-<P>
-The type field lists the capability flags for the device. These are
-as follows
-<P>
-<TABLE>
-<TR><TH>Name</TH><TH>Description</TH>
-<TR><TD><b>VID_TYPE_CAPTURE</b><TD>Can capture to memory</TD>
-<TR><TD><b>VID_TYPE_TUNER</b><TD>Has a tuner of some form</TD>
-<TR><TD><b>VID_TYPE_TELETEXT</b><TD>Has teletext capability</TD>
-<TR><TD><b>VID_TYPE_OVERLAY</b><TD>Can overlay its image onto the frame buffer</TD>
-<TR><TD><b>VID_TYPE_CHROMAKEY</b><TD>Overlay is Chromakeyed</TD>
-<TR><TD><b>VID_TYPE_CLIPPING</b><TD>Overlay clipping is supported</TD>
-<TR><TD><b>VID_TYPE_FRAMERAM</b><TD>Overlay overwrites frame buffer memory</TD>
-<TR><TD><b>VID_TYPE_SCALES</b><TD>The hardware supports image scaling</TD>
-<TR><TD><b>VID_TYPE_MONOCHROME</b><TD>Image capture is grey scale only</TD>
-<TR><TD><b>VID_TYPE_SUBCAPTURE</b><TD>Capture can be of only part of the image</TD>
-</TABLE>
-<P>
-The minimum and maximum sizes listed for a capture device do not imply all
-that all height/width ratios or sizes within the range are possible. A
-request to set a size will be honoured by the largest available capture
-size whose capture is no large than the requested rectangle in either
-direction. For example the quickcam has 3 fixed settings. 
-<P>
-<H3>Frame Buffer</H3>
-Capture cards that drop data directly onto the frame buffer must be told the
-base address of the frame buffer, its size and organisation. This is a 
-privileged ioctl and one that eventually X itself should set.
-<P>
-The <b>VIDIOCSFBUF</b> ioctl sets the frame buffer parameters for a capture
-card. If the card does not do direct writes to the frame buffer then this
-ioctl will be unsupported. The <b>VIDIOCGFBUF</b> ioctl returns the
-currently used parameters. The structure used in both cases is a 
-<b>struct video_buffer</b>.
-<P>
-<TABLE>
-<TR><TD><b>void *base</b></TD><TD>Base physical address of the buffer</TD>
-<TR><TD><b>int height</b></TD><TD>Height of the frame buffer</TD>
-<TR><TD><b>int width</b></TD><TD>Width of the frame buffer</TD>
-<TR><TD><b>int depth</b></TD><TD>Depth of the frame buffer</TD>
-<TR><TD><b>int bytesperline</b></TD><TD>Number of bytes of memory between the start of two adjacent lines</TD>
-</TABLE>
-<P>
-Note that these values reflect the physical layout of the frame buffer. 
-The visible area may be smaller. In fact under XFree86 this is commonly the
-case. XFree86 DGA can provide the parameters required to set up this ioctl.
-Setting the base address to NULL indicates there is no physical frame buffer
-access.
-<P>
-<H3>Capture Windows</H3>
-The capture area is described by a <b>struct video_window</b>. This defines
-a capture area and the clipping information if relevant. The 
-<b>VIDIOCGWIN</b> ioctl recovers the current settings and the 
-<b>VIDIOCSWIN</b> sets new values. A successful call to <b>VIDIOCSWIN</b> 
-indicates that a suitable set of parameters have been chosen. They do not
-indicate that exactly what was requested was granted. The program should
-call <b>VIDIOCGWIN</b> to check if the nearest match was suitable. The
-<b>struct video_window</b> contains the following fields.
-<P>
-<TABLE>
-<TR><TD><b>x</b><TD>The X co-ordinate specified in X windows format.</TD>
-<TR><TD><b>y</b><TD>The Y co-ordinate specified in X windows format.</TD>
-<TR><TD><b>width</b><TD>The width of the image capture.</TD>
-<TR><TD><b>height</b><TD>The height of the image capture.</TD>
-<TR><TD><b>chromakey</b><TD>A host order RGB32 value for the chroma key.</TD>
-<TR><TD><b>flags</b><TD>Additional capture flags.</TD>
-<TR><TD><b>clips</b><TD>A list of clipping rectangles. <em>(Set only)</em></TD>
-<TR><TD><b>clipcount</b><TD>The number of clipping rectangles. <em>(Set only)</em></TD>
-</TABLE>
-<P>
-Clipping rectangles are passed as an array. Each clip consists of the following
-fields available to the user.
-<P>
-<TABLE>
-<TR><TD><b>x</b></TD><TD>X co-ordinate of rectangle to skip</TD>
-<TR><TD><b>y</b></TD><TD>Y co-ordinate of rectangle to skip</TD>
-<TR><TD><b>width</b></TD><TD>Width of rectangle to skip</TD>
-<TR><TD><b>height</b></TD><TD>Height of rectangle to skip</TD>
-</TABLE>
-<P>
-Merely setting the window does not enable capturing. Overlay capturing
-(i.e. PCI-PCI transfer to the frame buffer of the video card)
-is activated by passing the <b>VIDIOCCAPTURE</b> ioctl a value of 1, and
-disabled by passing it a value of 0. 
-<P>
-Some capture devices can capture a subfield of the image they actually see.
-This is indicated when VIDEO_TYPE_SUBCAPTURE is defined.
-The video_capture describes the time and special subfields to capture.
-The video_capture structure contains the following fields.
-<P>
-<TABLE>
-<TR><TD><b>x</b></TD><TD>X co-ordinate of source rectangle to grab</TD>
-<TR><TD><b>y</b></TD><TD>Y co-ordinate of source rectangle to grab</TD>
-<TR><TD><b>width</b></TD><TD>Width of source rectangle to grab</TD>
-<TR><TD><b>height</b></TD><TD>Height of source rectangle to grab</TD>
-<TR><TD><b>decimation</b></TD><TD>Decimation to apply</TD>
-<TR><TD><b>flags</b></TD><TD>Flag settings for grabbing</TD>
-</TABLE>
-The available flags are
-<P>
-<TABLE>
-<TR><TH>Name</TH><TH>Description</TH>
-<TR><TD><b>VIDEO_CAPTURE_ODD</b><TD>Capture only odd frames</TD>
-<TR><TD><b>VIDEO_CAPTURE_EVEN</b><TD>Capture only even frames</TD>
-</TABLE>
-<P>
-<H3>Video Sources</H3>
-Each video4linux video or audio device captures from one or more 
-source <b>channels</b>. Each channel can be queries with the 
-<b>VDIOCGCHAN</b> ioctl call. Before invoking this function the caller
-must set the channel field to the channel that is being queried. On return
-the <b>struct video_channel</b> is filled in with information about the
-nature of the channel itself.
-<P>
-The <b>VIDIOCSCHAN</b> ioctl takes an integer argument and switches the
-capture to this input. It is not defined whether parameters such as colour
-settings or tuning are maintained across a channel switch. The caller should
-maintain settings as desired for each channel. (This is reasonable as 
-different video inputs may have different properties).
-<P>
-The <b>struct video_channel</b> consists of the following
-<P>
-<TABLE>
-<TR><TD><b>channel</b></TD><TD>The channel number</TD>
-<TR><TD><b>name</b></TD><TD>The input name - preferably reflecting the label
-on the card input itself</TD>
-<TR><TD><b>tuners</b></TD><TD>Number of tuners for this input</TD>
-<TR><TD><b>flags</b></TD><TD>Properties the tuner has</TD>
-<TR><TD><b>type</b></TD><TD>Input type (if known)</TD>
-<TR><TD><b>norm</b><TD>The norm for this channel</TD>
-</TABLE>
-<P>
-The flags defined are
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_VC_TUNER</b><TD>Channel has tuners.</TD>
-<TR><TD><b>VIDEO_VC_AUDIO</b><TD>Channel has audio.</TD>
-<TR><TD><b>VIDEO_VC_NORM</b><TD>Channel has norm setting.</TD>
-</TABLE>
-<P>
-The types defined are
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_TYPE_TV</b><TD>The input is a TV input.</TD>
-<TR><TD><b>VIDEO_TYPE_CAMERA</b><TD>The input is a camera.</TD>
-</TABLE>
-<P>
-<H3>Image Properties</H3>
-The image properties of the picture can be queried with the <b>VIDIOCGPICT</b>
-ioctl which fills in a <b>struct video_picture</b>. The <b>VIDIOCSPICT</b> 
-ioctl allows values to be changed. All values except for the palette type
-are scaled between 0-65535. 
-<P>
-The <b>struct video_picture</b> consists of the following fields
-<P>
-<TABLE>
-<TR><TD><b>brightness</b><TD>Picture brightness</TD>
-<TR><TD><b>hue</b><TD>Picture hue (colour only)</TD>
-<TR><TD><b>colour</b><TD>Picture colour (colour only)</TD>
-<TR><TD><b>contrast</b><TD>Picture contrast</TD>
-<TR><TD><b>whiteness</b><TD>The whiteness (greyscale only)</TD>
-<TR><TD><b>depth</b><TD>The capture depth (may need to match the frame buffer depth)</TD>
-<TR><TD><b>palette</b><TD>Reports the palette that should be used for this image</TD>
-</TABLE>
-<P>
-The following palettes are defined
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_PALETTE_GREY</b><TD>Linear intensity grey scale (255 is brightest).</TD>
-<TR><TD><b>VIDEO_PALETTE_HI240</b><TD>The BT848 8bit colour cube.</TD>
-<TR><TD><b>VIDEO_PALETTE_RGB565</b><TD>RGB565 packed into 16 bit words.</TD>
-<TR><TD><b>VIDEO_PALETTE_RGB555</b><TD>RGV555 packed into 16 bit words, top bit undefined.</TD>
-<TR><TD><b>VIDEO_PALETTE_RGB24</b><TD>RGB888 packed into 24bit words.</TD>
-<TR><TD><b>VIDEO_PALETTE_RGB32</b><TD>RGB888 packed into the low 3 bytes of 32bit words. The top 8bits are undefined.</TD>
-<TR><TD><b>VIDEO_PALETTE_YUV422</b><TD>Video style YUV422 - 8bits packed 4bits Y 2bits U 2bits V</TD>
-<TR><TD><b>VIDEO_PALETTE_YUYV</b><TD>Describe me</TD>
-<TR><TD><b>VIDEO_PALETTE_UYVY</b><TD>Describe me</TD>
-<TR><TD><b>VIDEO_PALETTE_YUV420</b><TD>YUV420 capture</TD>
-<TR><TD><b>VIDEO_PALETTE_YUV411</b><TD>YUV411 capture</TD>
-<TR><TD><b>VIDEO_PALETTE_RAW</b><TD>RAW capture (BT848)</TD>
-<TR><TD><b>VIDEO_PALETTE_YUV422P</b><TD>YUV 4:2:2 Planar</TD>
-<TR><TD><b>VIDEO_PALETTE_YUV411P</b><TD>YUV 4:1:1 Planar</TD>
-</TABLE>
-<P>
-<H3>Tuning</H3>
-Each video input channel can have one or more tuners associated with it. Many
-devices will not have tuners. TV cards and radio cards will have one or more
-tuners attached.
-<P>
-Tuners are described by a <b>struct video_tuner</b> which can be obtained by
-the <b>VIDIOCGTUNER</b> ioctl. Fill in the tuner number in the structure
-then pass the structure to the ioctl to have the data filled in. The 
-tuner can be switched using <b>VIDIOCSTUNER</b> which takes an integer argument
-giving the tuner to use. A struct tuner has the following fields
-<P>
-<TABLE>
-<TR><TD><b>tuner</b><TD>Number of the tuner</TD>
-<TR><TD><b>name</b><TD>Canonical name for this tuner (eg FM/AM/TV)</TD>
-<TR><TD><b>rangelow</b><TD>Lowest tunable frequency</TD>
-<TR><TD><b>rangehigh</b><TD>Highest tunable frequency</TD>
-<TR><TD><b>flags</b><TD>Flags describing the tuner</TD>
-<TR><TD><b>mode</b><TD>The video signal mode if relevant</TD>
-<TR><TD><b>signal</b><TD>Signal strength if known - between 0-65535</TD>
-</TABLE>
-<P>
-The following flags exist
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_TUNER_PAL</b><TD>PAL tuning is supported</TD>
-<TR><TD><b>VIDEO_TUNER_NTSC</b><TD>NTSC tuning is supported</TD>
-<TR><TD><b>VIDEO_TUNER_SECAM</b><TD>SECAM tuning is supported</TD>
-<TR><TD><b>VIDEO_TUNER_LOW</b><TD>Frequency is in a lower range</TD>
-<TR><TD><b>VIDEO_TUNER_NORM</b><TD>The norm for this tuner is settable</TD>
-<TR><TD><b>VIDEO_TUNER_STEREO_ON</b><TD>The tuner is seeing stereo audio</TD>
-<TR><TD><b>VIDEO_TUNER_RDS_ON</b><TD>The tuner is seeing a RDS datastream</TD>
-<TR><TD><b>VIDEO_TUNER_MBS_ON</b><TD>The tuner is seeing a MBS datastream</TD>
-</TABLE>
-<P>
-The following modes are defined
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_MODE_PAL</b><TD>The tuner is in PAL mode</TD>
-<TR><TD><b>VIDEO_MODE_NTSC</b><TD>The tuner is in NTSC mode</TD>
-<TR><TD><b>VIDEO_MODE_SECAM</b><TD>The tuner is in SECAM mode</TD>
-<TR><TD><b>VIDEO_MODE_AUTO</b><TD>The tuner auto switches, or mode does not apply</TD>
-</TABLE>
-<P>
-Tuning frequencies are an unsigned 32bit value in 1/16th MHz or if the
-<b>VIDEO_TUNER_LOW</b> flag is set they are in 1/16th KHz. The current
-frequency is obtained as an unsigned long via the <b>VIDIOCGFREQ</b> ioctl and
-set by the <b>VIDIOCSFREQ</b> ioctl.
-<P>
-<H3>Audio</H3>
-TV and Radio devices have one or more audio inputs that may be selected. 
-The audio properties are queried by passing a <b>struct video_audio</b> to <b>VIDIOCGAUDIO</b> ioctl. The
-<b>VIDIOCSAUDIO</b> ioctl sets audio properties.
-<P>
-The structure contains the following fields
-<P>
-<TABLE>
-<TR><TD><b>audio</b><TD>The channel number</TD>
-<TR><TD><b>volume</b><TD>The volume level</TD>
-<TR><TD><b>bass</b><TD>The bass level</TD>
-<TR><TD><b>treble</b><TD>The treble level</TD>
-<TR><TD><b>flags</b><TD>Flags describing the audio channel</TD>
-<TR><TD><b>name</b><TD>Canonical name for the audio input</TD>
-<TR><TD><b>mode</b><TD>The mode the audio input is in</TD>
-<TR><TD><b>balance</b><TD>The left/right balance</TD>
-<TR><TD><b>step</b><TD>Actual step used by the hardware</TD>
-</TABLE>
-<P>
-The following flags are defined
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_AUDIO_MUTE</b><TD>The audio is muted</TD>
-<TR><TD><b>VIDEO_AUDIO_MUTABLE</b><TD>Audio muting is supported</TD>
-<TR><TD><b>VIDEO_AUDIO_VOLUME</b><TD>The volume is controllable</TD>
-<TR><TD><b>VIDEO_AUDIO_BASS</b><TD>The bass is controllable</TD>
-<TR><TD><b>VIDEO_AUDIO_TREBLE</b><TD>The treble is controllable</TD>
-<TR><TD><b>VIDEO_AUDIO_BALANCE</b><TD>The balance is controllable</TD>
-</TABLE>
-<P>
-The following decoding modes are defined
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_SOUND_MONO</b><TD>Mono signal</TD>
-<TR><TD><b>VIDEO_SOUND_STEREO</b><TD>Stereo signal (NICAM for TV)</TD>
-<TR><TD><b>VIDEO_SOUND_LANG1</b><TD>European TV alternate language 1</TD>
-<TR><TD><b>VIDEO_SOUND_LANG2</b><TD>European TV alternate language 2</TD>
-</TABLE>
-<P>
-<H3>Reading Images</H3>
-Each call to the <b>read</b> syscall returns the next available image
-from the device. It is up to the caller to set format and size (using
-the VIDIOCSPICT and VIDIOCSWIN ioctls) and then to pass a suitable
-size buffer and length to the function. Not all devices will support
-read operations.
-<P>
-A second way to handle image capture is via the mmap interface if supported.
-To use the mmap interface a user first sets the desired image size and depth
-properties. Next the VIDIOCGMBUF ioctl is issued. This reports the size
-of buffer to mmap and the offset within the buffer for each frame. The
-number of frames supported is device dependent and may only be one. 
-<P>
-The video_mbuf structure contains the following fields
-<P>
-<TABLE>
-<TR><TD><b>size</b><TD>The number of bytes to map</TD>
-<TR><TD><b>frames</b><TD>The number of frames</TD>
-<TR><TD><b>offsets</b><TD>The offset of each frame</TD>
-</TABLE>
-<P>
-Once the mmap has been made the VIDIOCMCAPTURE ioctl starts the
-capture to a frame using the format and image size specified in the
-video_mmap (which should match or be below the initial query size).
-When the VIDIOCMCAPTURE ioctl returns the frame is <em>not</em>
-captured yet, the driver just instructed the hardware to start the
-capture.  The application has to use the VIDIOCSYNC ioctl to wait
-until the capture of a frame is finished.  VIDIOCSYNC takes the frame
-number you want to wait for as argument.
-<p>
-It is allowed to call VIDIOCMCAPTURE multiple times (with different
-frame numbers in video_mmap->frame of course) and thus have multiple
-outstanding capture requests.  A simple way do to double-buffering
-using this feature looks like this:
-<pre>
-/* setup everything */
-VIDIOCMCAPTURE(0)
-while (whatever) {
-   VIDIOCMCAPTURE(1)
-   VIDIOCSYNC(0)
-   /* process frame 0 while the hardware captures frame 1 */
-   VIDIOCMCAPTURE(0)
-   VIDIOCSYNC(1)
-   /* process frame 1 while the hardware captures frame 0 */
-}
-</pre>
-Note that you are <em>not</em> limited to only two frames.  The API
-allows up to 32 frames, the VIDIOCGMBUF ioctl returns the number of
-frames the driver granted.  Thus it is possible to build deeper queues
-to avoid loosing frames on load peaks.
-<p>
-While capturing to memory the driver will make a "best effort" attempt
-to capture to screen as well if requested. This normally means all
-frames that "miss" memory mapped capture will go to the display.
-<P>
-A final ioctl exists to allow a device to obtain related devices if a
-driver has multiple components (for example video0 may not be associated
-with vbi0 which would cause an intercast display program to make a bad
-mistake). The VIDIOCGUNIT ioctl reports the unit numbers of the associated
-devices if any exist. The video_unit structure has the following fields.
-<P>
-<TABLE>
-<TR><TD><b>video</b><TD>Video capture device</TD>
-<TR><TD><b>vbi</b><TD>VBI capture device</TD>
-<TR><TD><b>radio</b><TD>Radio device</TD>
-<TR><TD><b>audio</b><TD>Audio mixer</TD>
-<TR><TD><b>teletext</b><TD>Teletext device</TD>
-</TABLE>
-<P>
-<H3>RDS Datastreams</H3>
-For radio devices that support it, it is possible to receive Radio Data
-System (RDS) data by means of a read() on the device.  The data is packed in
-groups of three, as follows:
-<TABLE>
-<TR><TD>First Octet</TD><TD>Least Significant Byte of RDS Block</TD></TR>
-<TR><TD>Second Octet</TD><TD>Most Significant Byte of RDS Block
-<TR><TD>Third Octet</TD><TD>Bit 7:</TD><TD>Error bit.  Indicates that
-an uncorrectable error occurred during reception of this block.</TD></TR>
-<TR><TD>&nbsp;</TD><TD>Bit 6:</TD><TD>Corrected bit.  Indicates that  
-an error was corrected for this data block.</TD></TR>
-<TR><TD>&nbsp;</TD><TD>Bits 5-3:</TD><TD>Received Offset.  Indicates the  
-offset received by the sync system.</TD></TR>
-<TR><TD>&nbsp;</TD><TD>Bits 2-0:</TD><TD>Offset Name.  Indicates the  
-offset applied to this data.</TD></TR>
-</TABLE>
-</BODY>
-</HTML>
+<TITLE>V4L API</TITLE>
+<H1>Video For Linux APIs</H1>
+<table border=0>
+<tr>
+<td>
+<A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L1_API.html>
+V4L original API</a>
+</td><td>
+Obsoleted by V4L2 API
+</td></tr><tr><td>
+<A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L2_API.html>
+V4L2 API</a>
+</td><td>
+Should be used for new projects
+</td></tr>
+</table>
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index 216f705..4377aa1 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -13,17 +13,17 @@
 card=12 - ASUS PVR-416
 card=13 - MSI TV-@nywhere
 card=14 - KWorld/VStream XPert DVB-T
-card=15 - DVICO FusionHDTV DVB-T1
+card=15 - DViCO FusionHDTV DVB-T1
 card=16 - KWorld LTV883RF
-card=17 - DViCO - FusionHDTV 3 Gold
+card=17 - DViCO FusionHDTV 3 Gold-Q
 card=18 - Hauppauge Nova-T DVB-T
 card=19 - Conexant DVB-T reference design
 card=20 - Provideo PV259
-card=21 - DVICO FusionHDTV DVB-T Plus
+card=21 - DViCO FusionHDTV DVB-T Plus
 card=22 - digitalnow DNTV Live! DVB-T
 card=23 - pcHDTV HD3000 HDTV
 card=24 - Hauppauge WinTV 28xxx (Roslyn) models
 card=25 - Digital-Logic MICROSPACE Entertainment Center (MEC)
 card=26 - IODATA GV/BCTV7E
 card=27 - PixelView PlayTV Ultra Pro (Stereo)
-card=28 - DViCO - FusionHDTV 3 Gold-T
+card=28 - DViCO FusionHDTV 3 Gold-T
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index d5ed95d..735e8ba 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -54,3 +54,9 @@
  55 -> LifeView FlyDVB-T DUO                    [5168:0306]
  56 -> Avermedia AVerTV 307                     [1461:a70a]
  57 -> Avermedia AVerTV GO 007 FM               [1461:f31f]
+ 58 -> ADS Tech Instant TV (saa7135)            [1421:0350,1421:0370]
+ 59 -> Kworld/Tevion V-Stream Xpert TV PVR7134
+ 60 -> Typhoon DVB-T Duo Digital/Analog Cardbus
+ 61 -> Philips TOUGH DVB-T reference design
+ 62 -> Compro VideoMate TV Gold+II
+ 63 -> Kworld Xpert TV PVR7134
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner
index aeb8df8..e78020f 100644
--- a/Documentation/video4linux/CARDLIST.tuner
+++ b/Documentation/video4linux/CARDLIST.tuner
@@ -59,3 +59,6 @@
 tuner=58 - Ymec TVision TVF-8531MF
 tuner=59 - Ymec TVision TVF-5533MF
 tuner=60 - Thomson DDT 7611 (ATSC/NTSC)
+tuner=61 - Tena TNF9533-D/IF
+tuner=62 - Philips TEA5767HN FM Radio
+tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner
diff --git a/Documentation/video4linux/README.saa7134 b/Documentation/video4linux/README.saa7134
index 1a446c6..1f788e4 100644
--- a/Documentation/video4linux/README.saa7134
+++ b/Documentation/video4linux/README.saa7134
@@ -57,6 +57,15 @@
  - 24.576MHz -> .audio_clock=0x200000
 (xtal * .audio_clock = 51539600)
 
+Some details about 30/34/35:
+
+ - saa7130 - low-price chip, doesn't have mute, that is why all those
+ cards should have .mute field defined in their tuner structure.
+
+ - saa7134 - usual chip
+
+ - saa7133/35 - saa7135 is probably a marketing decision, since all those
+ chips identifies itself as 33 on pci.
 
 Credits
 =======
diff --git a/MAINTAINERS b/MAINTAINERS
index 4db63de..302b319 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -512,11 +512,11 @@
 S:	Supported
 
 BTTV VIDEO4LINUX DRIVER
-P:	Gerd Knorr
-M:	kraxel@bytesex.org
+P:	Mauro Carvalho Chehab
+M:	mchehab@brturbo.com.br
 L:	video4linux-list@redhat.com
-W:	http://bytesex.org/bttv/
-S:	Orphan
+W:	http://linuxtv.org
+S:	Maintained
 
 BUSLOGIC SCSI DRIVER
 P:	Leonard N. Zubkoff
@@ -2161,7 +2161,7 @@
 P:	David S. Miller
 M:	davem@davemloft.net
 P:	Eddie C. Dost
-M:	ecd@skynet.be
+M:	ecd@brainaid.de
 P:	Jakub Jelinek
 M:	jj@sunsite.ms.mff.cuni.cz
 P:	Anton Blanchard
@@ -2625,10 +2625,11 @@
 S:	Maintained
 
 VIDEO FOR LINUX
-P:	Gerd Knorr
-M:	kraxel@bytesex.org
+P:	Mauro Carvalho Chehab
+M:	mchehab@brturbo.com.br
 L:	video4linux-list@redhat.com
-S:	Orphan
+W:	http://linuxtv.org
+S:	Maintained
 
 W1 DALLAS'S 1-WIRE BUS
 P:	Evgeniy Polyakov
diff --git a/Makefile b/Makefile
index 1fdace7..278d509 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
-SUBLEVEL = 12
-EXTRAVERSION =
+SUBLEVEL = 13
+EXTRAVERSION =-rc2
 NAME=Woozy Numbat
 
 # *DOCUMENTATION*
diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c
index e6ded33..9d34ce2 100644
--- a/arch/alpha/kernel/irq_alpha.c
+++ b/arch/alpha/kernel/irq_alpha.c
@@ -55,6 +55,8 @@
 #ifdef CONFIG_SMP
 	  {
 		long cpu;
+
+		local_irq_disable();
 		smp_percpu_timer_interrupt(regs);
 		cpu = smp_processor_id();
 		if (cpu != boot_cpuid) {
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index fd7bd17..6f509a6 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -240,7 +240,7 @@
 	siginfo_t info;
 	int signo, code;
 
-	if (regs->ps == 0) {
+	if ((regs->ps & ~IPL_MAX) == 0) {
 		if (type == 1) {
 			const unsigned int *data
 			  = (const unsigned int *) regs->pc;
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c8d94dc..620f2ca 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -361,6 +361,11 @@
 	  Alternatively, if you want dynamic tick automatically enabled
 	  during boot, pass "dyntick=enable" via the kernel command string.
 
+	  Please note that dynamic tick may affect the accuracy of
+	  timekeeping on some platforms depending on the implementation.
+	  Currently at least OMAP platform is known to have accurate
+	  timekeeping with dynamic tick.
+
 config ARCH_DISCONTIGMEM_ENABLE
 	bool
 	default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 8330495..eb933dc 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -56,7 +56,7 @@
 tune-$(CONFIG_CPU_V6)		:=-mtune=strongarm
 
 # Need -Uarm for gcc < 3.x
-CFLAGS_ABI	:=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
+CFLAGS_ABI	:=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,)
 CFLAGS		+=$(CFLAGS_ABI) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
 AFLAGS		+=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float
 
diff --git a/arch/arm/configs/omnimeter_defconfig b/arch/arm/configs/omnimeter_defconfig
deleted file mode 100644
index 78fdb4a..0000000
--- a/arch/arm/configs/omnimeter_defconfig
+++ /dev/null
@@ -1,803 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 21:31:45 2005
-#
-CONFIG_ARM=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-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_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-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 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 is not set
-# 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=y
-# 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
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_COLLIE is not set
-# CONFIG_SA1100_H3100 is not set
-# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
-# CONFIG_SA1100_BADGE4 is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_HACKKIT is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_SSP is not set
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_SA1100=y
-CONFIG_CPU_32v4=y
-CONFIG_CPU_ABRT_EV4=y
-CONFIG_CPU_CACHE_V4WB=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_TLB_V4WB=y
-CONFIG_CPU_MINICACHE=y
-
-#
-# Processor Features
-#
-
-#
-# Bus support
-#
-CONFIG_ISA=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-CONFIG_PCCARD=y
-# CONFIG_PCMCIA_DEBUG is not set
-CONFIG_PCMCIA=y
-
-#
-# PC-card bridges
-#
-CONFIG_I82365=y
-# CONFIG_TCIC is not set
-CONFIG_PCMCIA_SA1100=y
-CONFIG_PCCARD_NONSTATIC=y
-
-#
-# Kernel Features
-#
-# CONFIG_PREEMPT is not set
-CONFIG_DISCONTIGMEM=y
-# CONFIG_LEDS is not set
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="keepinitrd mem=16M root=/dev/ram ramdisk=8192 initrd=0xd0000000,4M"
-# CONFIG_XIP_KERNEL is not set
-
-#
-# CPU Frequency scaling
-#
-# CONFIG_CPU_FREQ is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-# CONFIG_FPE_NWFPE is not set
-# CONFIG_FPE_FASTFPE is not set
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_ARTHUR is not set
-
-#
-# Power management options
-#
-# CONFIG_PM is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD 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_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# 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_IDECS is not set
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-# CONFIG_IDE_ARM is not set
-# CONFIG_IDE_CHIPSETS 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 is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=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=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 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 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
-
-#
-# 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
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# 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_SMC91X is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_NET_PCI is not set
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# 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
-CONFIG_PCMCIA_WAVELAN=y
-# CONFIG_PCMCIA_NETWAVE is not set
-
-#
-# Wireless 802.11 Frequency Hopping cards support
-#
-# CONFIG_PCMCIA_RAYCS is not set
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-# CONFIG_HERMES is not set
-# CONFIG_ATMEL is not set
-
-#
-# Wireless 802.11b Pcmcia/Cardbus cards support
-#
-CONFIG_AIRO_CS=y
-CONFIG_PCMCIA_WL3501=y
-CONFIG_NET_WIRELESS=y
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=y
-# CONFIG_PCMCIA_3C574 is not set
-# CONFIG_PCMCIA_FMVJ18X is not set
-CONFIG_PCMCIA_PCNET=y
-# CONFIG_PCMCIA_NMCLAN is not set
-# CONFIG_PCMCIA_SMC91C92 is not set
-# CONFIG_PCMCIA_XIRC2PS is not set
-# CONFIG_PCMCIA_AXNET is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=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_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_SERPORT=y
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_SA1100=y
-CONFIG_SERIAL_SA1100_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-# CONFIG_SYNCLINK_CS is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-CONFIG_FB=y
-CONFIG_FB_CFB_FILLRECT=y
-CONFIG_FB_CFB_COPYAREA=y
-CONFIG_FB_CFB_IMAGEBLIT=y
-CONFIG_FB_SOFT_CURSOR=y
-# CONFIG_FB_MODE_HELPERS is not set
-# CONFIG_FB_TILEBLITTING is not set
-CONFIG_FB_SA1100=y
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_MDA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x8=y
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_6x11 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
-
-#
-# 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 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 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
-
-#
-# XFS support
-#
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-# CONFIG_VFAT_FS is not set
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_SYSFS=y
-# CONFIG_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
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-CONFIG_LOCKD=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
-
-#
-# 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_DEBUG_BUGVERBOSE=y
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 4c38bd8..835d450 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -30,9 +30,6 @@
 extern void __modsi3(void);
 extern void __muldi3(void);
 extern void __ucmpdi2(void);
-extern void __udivdi3(void);
-extern void __umoddi3(void);
-extern void __udivmoddi4(void);
 extern void __udivsi3(void);
 extern void __umodsi3(void);
 extern void __do_div64(void);
@@ -44,7 +41,10 @@
  * This has a special calling convention; it doesn't
  * modify any of the usual registers, except for LR.
  */
+#define EXPORT_CRC_ALIAS(sym) __CRC_SYMBOL(sym, "")
+
 #define EXPORT_SYMBOL_ALIAS(sym,orig)		\
+ EXPORT_CRC_ALIAS(sym)				\
  const struct kernel_symbol __ksymtab_##sym	\
   __attribute__((section("__ksymtab"))) =	\
     { (unsigned long)&orig, #sym };
@@ -134,9 +134,6 @@
 EXPORT_SYMBOL(__modsi3);
 EXPORT_SYMBOL(__muldi3);
 EXPORT_SYMBOL(__ucmpdi2);
-EXPORT_SYMBOL(__udivdi3);
-EXPORT_SYMBOL(__umoddi3);
-EXPORT_SYMBOL(__udivmoddi4);
 EXPORT_SYMBOL(__udivsi3);
 EXPORT_SYMBOL(__umodsi3);
 EXPORT_SYMBOL(__do_div64);
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index bd4823c..1155cf0 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -344,9 +344,9 @@
 	str	r6, [r0]
 #endif
 
+#ifdef CONFIG_DEBUG_LL
 	bic	r7, r7, #0x0c			@ turn off cacheable
 						@ and bufferable bits
-#ifdef CONFIG_DEBUG_LL
 	/*
 	 * Map in IO space for serial debugging.
 	 * This allows debug messages to be output
@@ -372,28 +372,24 @@
 	teq	r1, #MACH_TYPE_NETWINDER
 	teqne	r1, #MACH_TYPE_CATS
 	bne	1f
-	add	r0, r4, #0x3fc0			@ ff000000
-	mov	r3, #0x7c000000
-	orr	r3, r3, r7
-	str	r3, [r0], #4
-	add	r3, r3, #1 << 20
-	str	r3, [r0], #4
+	add	r0, r4, #0xff000000 >> 18
+	orr	r3, r7, #0x7c000000
+	str	r3, [r0]
 1:
 #endif
-#endif
 #ifdef CONFIG_ARCH_RPC
 	/*
 	 * Map in screen at 0x02000000 & SCREEN2_BASE
 	 * Similar reasons here - for debug.  This is
 	 * only for Acorn RiscPC architectures.
 	 */
-	add	r0, r4, #0x80			@ 02000000
-	mov	r3, #0x02000000
-	orr	r3, r3, r7
+	add	r0, r4, #0x02000000 >> 18
+	orr	r3, r7, #0x02000000
 	str	r3, [r0]
-	add	r0, r4, #0x3600			@ d8000000
+	add	r0, r4, #0xd8000000 >> 18
 	str	r3, [r0]
 #endif
+#endif
 	mov	pc, lr
 	.ltorg
 
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 8cf733d..c9b6977 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -359,7 +359,8 @@
 	      "I" (offsetof(struct stack, abt[0])),
 	      "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE),
 	      "I" (offsetof(struct stack, und[0])),
-	      "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE));
+	      "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
+	    : "r14");
 }
 
 static struct machine_desc * __init setup_machine(unsigned int nr)
@@ -736,8 +737,8 @@
 	if (mdesc->soft_reboot)
 		reboot_setup("s");
 
-	if (mdesc->param_offset)
-		tags = phys_to_virt(mdesc->param_offset);
+	if (mdesc->boot_params)
+		tags = phys_to_virt(mdesc->boot_params);
 
 	/*
 	 * If we have the old style parameters, convert them to
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 3489275..a931409 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -502,3 +502,126 @@
 {
 	return -EINVAL;
 }
+
+static int
+on_each_cpu_mask(void (*func)(void *), void *info, int retry, int wait,
+		 cpumask_t mask)
+{
+	int ret = 0;
+
+	preempt_disable();
+
+	ret = smp_call_function_on_cpu(func, info, retry, wait, mask);
+	if (cpu_isset(smp_processor_id(), mask))
+		func(info);
+
+	preempt_enable();
+
+	return ret;
+}
+
+/**********************************************************************/
+
+/*
+ * TLB operations
+ */
+struct tlb_args {
+	struct vm_area_struct *ta_vma;
+	unsigned long ta_start;
+	unsigned long ta_end;
+};
+
+static inline void ipi_flush_tlb_all(void *ignored)
+{
+	local_flush_tlb_all();
+}
+
+static inline void ipi_flush_tlb_mm(void *arg)
+{
+	struct mm_struct *mm = (struct mm_struct *)arg;
+
+	local_flush_tlb_mm(mm);
+}
+
+static inline void ipi_flush_tlb_page(void *arg)
+{
+	struct tlb_args *ta = (struct tlb_args *)arg;
+
+	local_flush_tlb_page(ta->ta_vma, ta->ta_start);
+}
+
+static inline void ipi_flush_tlb_kernel_page(void *arg)
+{
+	struct tlb_args *ta = (struct tlb_args *)arg;
+
+	local_flush_tlb_kernel_page(ta->ta_start);
+}
+
+static inline void ipi_flush_tlb_range(void *arg)
+{
+	struct tlb_args *ta = (struct tlb_args *)arg;
+
+	local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
+}
+
+static inline void ipi_flush_tlb_kernel_range(void *arg)
+{
+	struct tlb_args *ta = (struct tlb_args *)arg;
+
+	local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
+}
+
+void flush_tlb_all(void)
+{
+	on_each_cpu(ipi_flush_tlb_all, NULL, 1, 1);
+}
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+	cpumask_t mask = mm->cpu_vm_mask;
+
+	on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, 1, mask);
+}
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
+{
+	cpumask_t mask = vma->vm_mm->cpu_vm_mask;
+	struct tlb_args ta;
+
+	ta.ta_vma = vma;
+	ta.ta_start = uaddr;
+
+	on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, 1, mask);
+}
+
+void flush_tlb_kernel_page(unsigned long kaddr)
+{
+	struct tlb_args ta;
+
+	ta.ta_start = kaddr;
+
+	on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1, 1);
+}
+
+void flush_tlb_range(struct vm_area_struct *vma,
+                     unsigned long start, unsigned long end)
+{
+	cpumask_t mask = vma->vm_mm->cpu_vm_mask;
+	struct tlb_args ta;
+
+	ta.ta_vma = vma;
+	ta.ta_start = start;
+	ta.ta_end = end;
+
+	on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, 1, mask);
+}
+
+void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+	struct tlb_args ta;
+
+	ta.ta_start = start;
+	ta.ta_end = end;
+
+	on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1, 1);
+}
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 2fb0a4c..df2cb06 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -230,16 +230,8 @@
 	do_exit(SIGSEGV);
 }
 
-void die_if_kernel(const char *str, struct pt_regs *regs, int err)
-{
-	if (user_mode(regs))
-    		return;
-
-    	die(str, regs, err);
-}
-
-static void notify_die(const char *str, struct pt_regs *regs, siginfo_t *info,
-		       unsigned long err, unsigned long trap)
+void notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
+		unsigned long err, unsigned long trap)
 {
 	if (user_mode(regs)) {
 		current->thread.error_code = err;
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index c0e6583..8725d63 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -11,7 +11,7 @@
 		   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 udivdi3.o lib1funcs.o div64.o	      \
+		   ucmpdi2.o lib1funcs.o div64.o	              \
 		   io-readsb.o io-writesb.o io-readsl.o io-writesl.o
 
 ifeq ($(CONFIG_CPU_32v3),y)
diff --git a/arch/arm/lib/longlong.h b/arch/arm/lib/longlong.h
deleted file mode 100644
index 90ae647..0000000
--- a/arch/arm/lib/longlong.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/* longlong.h -- based on code from gcc-2.95.3
-
-   definitions for mixed size 32/64 bit arithmetic.
-   Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
-
-   This definition 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.
-
-   This definition 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; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-/* Borrowed from GCC 2.95.3, I Molton 29/07/01 */
-
-#ifndef SI_TYPE_SIZE
-#define SI_TYPE_SIZE 32
-#endif
-
-#define __BITS4 (SI_TYPE_SIZE / 4)
-#define __ll_B (1L << (SI_TYPE_SIZE / 2))
-#define __ll_lowpart(t) ((u32) (t) % __ll_B)
-#define __ll_highpart(t) ((u32) (t) / __ll_B)
-
-/* Define auxiliary asm macros.
-
-   1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
-   multiplies two u32 integers MULTIPLER and MULTIPLICAND,
-   and generates a two-part u32 product in HIGH_PROD and
-   LOW_PROD.
-
-   2) __umulsidi3(a,b) multiplies two u32 integers A and B,
-   and returns a u64 product.  This is just a variant of umul_ppmm.
-
-   3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
-   denominator) divides a two-word unsigned integer, composed by the
-   integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and
-   places the quotient in QUOTIENT and the remainder in REMAINDER.
-   HIGH_NUMERATOR must be less than DENOMINATOR for correct operation.
-   If, in addition, the most significant bit of DENOMINATOR must be 1,
-   then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1.
-
-   4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
-   denominator).  Like udiv_qrnnd but the numbers are signed.  The
-   quotient is rounded towards 0.
-
-   5) count_leading_zeros(count, x) counts the number of zero-bits from
-   the msb to the first non-zero bit.  This is the number of steps X
-   needs to be shifted left to set the msb.  Undefined for X == 0.
-
-   6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
-   high_addend_2, low_addend_2) adds two two-word unsigned integers,
-   composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and
-   LOW_ADDEND_2 respectively.  The result is placed in HIGH_SUM and
-   LOW_SUM.  Overflow (i.e. carry out) is not stored anywhere, and is
-   lost.
-
-   7) sub_ddmmss(high_difference, low_difference, high_minuend,
-   low_minuend, high_subtrahend, low_subtrahend) subtracts two
-   two-word unsigned integers, composed by HIGH_MINUEND_1 and
-   LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2
-   respectively.  The result is placed in HIGH_DIFFERENCE and
-   LOW_DIFFERENCE.  Overflow (i.e. carry out) is not stored anywhere,
-   and is lost.
-
-   If any of these macros are left undefined for a particular CPU,
-   C macros are used.  */
-
-#if defined (__arm__)
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
-  __asm__ ("adds	%1, %4, %5					\n\
-	adc	%0, %2, %3"						\
-	   : "=r" ((u32) (sh)),					\
-	     "=&r" ((u32) (sl))					\
-	   : "%r" ((u32) (ah)),					\
-	     "rI" ((u32) (bh)),					\
-	     "%r" ((u32) (al)),					\
-	     "rI" ((u32) (bl)))
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
-  __asm__ ("subs	%1, %4, %5					\n\
-	sbc	%0, %2, %3"						\
-	   : "=r" ((u32) (sh)),					\
-	     "=&r" ((u32) (sl))					\
-	   : "r" ((u32) (ah)),					\
-	     "rI" ((u32) (bh)),					\
-	     "r" ((u32) (al)),					\
-	     "rI" ((u32) (bl)))
-#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 UMUL_TIME 20
-#define UDIV_TIME 100
-#endif				/* __arm__ */
-
-#define __umulsidi3(u, v) \
-  ({DIunion __w;							\
-    umul_ppmm (__w.s.high, __w.s.low, u, v);				\
-    __w.ll; })
-
-#define __udiv_qrnnd_c(q, r, n1, n0, d) \
-  do {									\
-    u32 __d1, __d0, __q1, __q0;					\
-    u32 __r1, __r0, __m;						\
-    __d1 = __ll_highpart (d);						\
-    __d0 = __ll_lowpart (d);						\
-									\
-    __r1 = (n1) % __d1;							\
-    __q1 = (n1) / __d1;							\
-    __m = (u32) __q1 * __d0;					\
-    __r1 = __r1 * __ll_B | __ll_highpart (n0);				\
-    if (__r1 < __m)							\
-      {									\
-	__q1--, __r1 += (d);						\
-	if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
-	  if (__r1 < __m)						\
-	    __q1--, __r1 += (d);					\
-      }									\
-    __r1 -= __m;							\
-									\
-    __r0 = __r1 % __d1;							\
-    __q0 = __r1 / __d1;							\
-    __m = (u32) __q0 * __d0;					\
-    __r0 = __r0 * __ll_B | __ll_lowpart (n0);				\
-    if (__r0 < __m)							\
-      {									\
-	__q0--, __r0 += (d);						\
-	if (__r0 >= (d))						\
-	  if (__r0 < __m)						\
-	    __q0--, __r0 += (d);					\
-      }									\
-    __r0 -= __m;							\
-									\
-    (q) = (u32) __q1 * __ll_B | __q0;				\
-    (r) = __r0;								\
-  } while (0)
-
-#define UDIV_NEEDS_NORMALIZATION 1
-#define udiv_qrnnd __udiv_qrnnd_c
-
-#define count_leading_zeros(count, x) \
-  do {									\
-    u32 __xr = (x);							\
-    u32 __a;							\
-									\
-    if (SI_TYPE_SIZE <= 32)						\
-      {									\
-	__a = __xr < ((u32)1<<2*__BITS4)				\
-	  ? (__xr < ((u32)1<<__BITS4) ? 0 : __BITS4)		\
-	  : (__xr < ((u32)1<<3*__BITS4) ?  2*__BITS4 : 3*__BITS4);	\
-      }									\
-    else								\
-      {									\
-	for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8)			\
-	  if (((__xr >> __a) & 0xff) != 0)				\
-	    break;							\
-      }									\
-									\
-    (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a);		\
-  } while (0)
diff --git a/arch/arm/lib/udivdi3.c b/arch/arm/lib/udivdi3.c
deleted file mode 100644
index e343be4..0000000
--- a/arch/arm/lib/udivdi3.c
+++ /dev/null
@@ -1,222 +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"
-#include "longlong.h"
-
-static const u8 __clz_tab[] = {
-	0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
-	    5, 5, 5, 5, 5, 5, 5, 5,
-	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-	    6, 6, 6, 6, 6, 6, 6, 6,
-	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-	    7, 7, 7, 7, 7, 7, 7, 7,
-	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-	    7, 7, 7, 7, 7, 7, 7, 7,
-	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-	    8, 8, 8, 8, 8, 8, 8, 8,
-	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-	    8, 8, 8, 8, 8, 8, 8, 8,
-	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-	    8, 8, 8, 8, 8, 8, 8, 8,
-	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-	    8, 8, 8, 8, 8, 8, 8, 8,
-};
-
-u64 __udivmoddi4(u64 n, u64 d, u64 * rp)
-{
-	DIunion ww;
-	DIunion nn, dd;
-	DIunion rr;
-	u32 d0, d1, n0, n1, n2;
-	u32 q0, q1;
-	u32 b, bm;
-
-	nn.ll = n;
-	dd.ll = d;
-
-	d0 = dd.s.low;
-	d1 = dd.s.high;
-	n0 = nn.s.low;
-	n1 = nn.s.high;
-
-	if (d1 == 0) {
-		if (d0 > n1) {
-			/* 0q = nn / 0D */
-
-			count_leading_zeros(bm, d0);
-
-			if (bm != 0) {
-				/* Normalize, i.e. make the most significant bit of the
-				   denominator set.  */
-
-				d0 = d0 << bm;
-				n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
-				n0 = n0 << bm;
-			}
-
-			udiv_qrnnd(q0, n0, n1, n0, d0);
-			q1 = 0;
-
-			/* Remainder in n0 >> bm.  */
-		} else {
-			/* qq = NN / 0d */
-
-			if (d0 == 0)
-				d0 = 1 / d0;	/* Divide intentionally by zero.  */
-
-			count_leading_zeros(bm, d0);
-
-			if (bm == 0) {
-				/* From (n1 >= d0) /\ (the most significant bit of d0 is set),
-				   conclude (the most significant bit of n1 is set) /\ (the
-				   leading quotient digit q1 = 1).
-
-				   This special case is necessary, not an optimization.
-				   (Shifts counts of SI_TYPE_SIZE are undefined.)  */
-
-				n1 -= d0;
-				q1 = 1;
-			} else {
-				/* Normalize.  */
-
-				b = SI_TYPE_SIZE - bm;
-
-				d0 = d0 << bm;
-				n2 = n1 >> b;
-				n1 = (n1 << bm) | (n0 >> b);
-				n0 = n0 << bm;
-
-				udiv_qrnnd(q1, n1, n2, n1, d0);
-			}
-
-			/* n1 != d0...  */
-
-			udiv_qrnnd(q0, n0, n1, n0, d0);
-
-			/* Remainder in n0 >> bm.  */
-		}
-
-		if (rp != 0) {
-			rr.s.low = n0 >> bm;
-			rr.s.high = 0;
-			*rp = rr.ll;
-		}
-	} else {
-		if (d1 > n1) {
-			/* 00 = nn / DD */
-
-			q0 = 0;
-			q1 = 0;
-
-			/* Remainder in n1n0.  */
-			if (rp != 0) {
-				rr.s.low = n0;
-				rr.s.high = n1;
-				*rp = rr.ll;
-			}
-		} else {
-			/* 0q = NN / dd */
-
-			count_leading_zeros(bm, d1);
-			if (bm == 0) {
-				/* From (n1 >= d1) /\ (the most significant bit of d1 is set),
-				   conclude (the most significant bit of n1 is set) /\ (the
-				   quotient digit q0 = 0 or 1).
-
-				   This special case is necessary, not an optimization.  */
-
-				/* The condition on the next line takes advantage of that
-				   n1 >= d1 (true due to program flow).  */
-				if (n1 > d1 || n0 >= d0) {
-					q0 = 1;
-					sub_ddmmss(n1, n0, n1, n0, d1, d0);
-				} else
-					q0 = 0;
-
-				q1 = 0;
-
-				if (rp != 0) {
-					rr.s.low = n0;
-					rr.s.high = n1;
-					*rp = rr.ll;
-				}
-			} else {
-				u32 m1, m0;
-				/* Normalize.  */
-
-				b = SI_TYPE_SIZE - bm;
-
-				d1 = (d1 << bm) | (d0 >> b);
-				d0 = d0 << bm;
-				n2 = n1 >> b;
-				n1 = (n1 << bm) | (n0 >> b);
-				n0 = n0 << bm;
-
-				udiv_qrnnd(q0, n1, n2, n1, d1);
-				umul_ppmm(m1, m0, q0, d0);
-
-				if (m1 > n1 || (m1 == n1 && m0 > n0)) {
-					q0--;
-					sub_ddmmss(m1, m0, m1, m0, d1, d0);
-				}
-
-				q1 = 0;
-
-				/* Remainder in (n1n0 - m1m0) >> bm.  */
-				if (rp != 0) {
-					sub_ddmmss(n1, n0, n1, n0, m1, m0);
-					rr.s.low = (n1 << b) | (n0 >> bm);
-					rr.s.high = n1 >> bm;
-					*rp = rr.ll;
-				}
-			}
-		}
-	}
-
-	ww.s.low = q0;
-	ww.s.high = q1;
-	return ww.ll;
-}
-
-u64 __udivdi3(u64 n, u64 d)
-{
-	return __udivmoddi4(n, d, (u64 *) 0);
-}
-
-u64 __umoddi3(u64 u, u64 v)
-{
-	u64 w;
-
-	(void)__udivmoddi4(u, v, &w);
-
-	return w;
-}
diff --git a/arch/arm/mach-aaec2000/aaed2000.c b/arch/arm/mach-aaec2000/aaed2000.c
index 5417ca3..c9d8998 100644
--- a/arch/arm/mach-aaec2000/aaed2000.c
+++ b/arch/arm/mach-aaec2000/aaed2000.c
@@ -40,9 +40,11 @@
 }
 
 MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform")
-	MAINTAINER("Nicolas Bellido Y Ortega")
-	BOOT_MEM(0xf0000000, PIO_BASE, VIO_BASE)
-	MAPIO(aaed2000_map_io)
-	INITIRQ(aaed2000_init_irq)
+	/* Maintainer: Nicolas Bellido Y Ortega */
+	.phys_ram	= 0xf0000000,
+	.phys_io	= PIO_BASE,
+	.io_pg_offst	= ((VIO_BASE) >> 18) & 0xfffc,
+	.map_io		= aaed2000_map_io,
+	.init_irq	= aaed2000_init_irq,
 	.timer		= &aaec2000_timer,
 MACHINE_END
diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c
index c106704..dc73feb 100644
--- a/arch/arm/mach-clps711x/autcpu12.c
+++ b/arch/arm/mach-clps711x/autcpu12.c
@@ -59,11 +59,13 @@
 }
 
 MACHINE_START(AUTCPU12, "autronix autcpu12")
-	MAINTAINER("Thomas Gleixner")
-        BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
-	BOOT_PARAMS(0xc0020000)
-	MAPIO(autcpu12_map_io)
-	INITIRQ(clps711x_init_irq)
+	/* Maintainer: Thomas Gleixner */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xff000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0020000,
+	.map_io		= autcpu12_map_io,
+	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
 MACHINE_END
 
diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c
index 7664f9c..a46c82c 100644
--- a/arch/arm/mach-clps711x/cdb89712.c
+++ b/arch/arm/mach-clps711x/cdb89712.c
@@ -49,10 +49,12 @@
 }
 
 MACHINE_START(CDB89712, "Cirrus-CDB89712")
-	MAINTAINER("Ray Lehtiniemi")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(cdb89712_map_io)
-	INITIRQ(clps711x_init_irq)
+	/* Maintainer: Ray Lehtiniemi */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xff000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= cdb89712_map_io,
+	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
 MACHINE_END
diff --git a/arch/arm/mach-clps711x/ceiva.c b/arch/arm/mach-clps711x/ceiva.c
index e4093be..780d918 100644
--- a/arch/arm/mach-clps711x/ceiva.c
+++ b/arch/arm/mach-clps711x/ceiva.c
@@ -53,10 +53,12 @@
 
 
 MACHINE_START(CEIVA, "CEIVA/Polaroid Photo MAX Digital Picture Frame")
-	MAINTAINER("Rob Scott")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(ceiva_map_io)
-	INITIRQ(clps711x_init_irq)
+	/* Maintainer: Rob Scott */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xff000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= ceiva_map_io,
+	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
 MACHINE_END
diff --git a/arch/arm/mach-clps711x/clep7312.c b/arch/arm/mach-clps711x/clep7312.c
index 9ca21cb..c83f3fd 100644
--- a/arch/arm/mach-clps711x/clep7312.c
+++ b/arch/arm/mach-clps711x/clep7312.c
@@ -37,12 +37,14 @@
 
 
 MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312")
-	MAINTAINER("Nobody")
-        BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
-	BOOT_PARAMS(0xc0000100)
-	FIXUP(fixup_clep7312)
-	MAPIO(clps711x_map_io)
-	INITIRQ(clps711x_init_irq)
+	/* Maintainer: Nobody */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xff000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.fixup		= fixup_clep7312,
+	.map_io		= clps711x_map_io,
+	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
 MACHINE_END
 
diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c
index c6c4632..255c98b 100644
--- a/arch/arm/mach-clps711x/edb7211-arch.c
+++ b/arch/arm/mach-clps711x/edb7211-arch.c
@@ -51,11 +51,13 @@
 }
 
 MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
-	MAINTAINER("Jon McClintock")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
-	BOOT_PARAMS(0xc0020100)	/* 0xc0000000 - 0xc001ffff can be video RAM */
-	FIXUP(fixup_edb7211)
-	MAPIO(edb7211_map_io)
-	INITIRQ(clps711x_init_irq)
+	/* Maintainer: Jon McClintock */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xff000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0020100,	/* 0xc0000000 - 0xc001ffff can be video RAM */
+	.fixup		= fixup_edb7211,
+	.map_io		= edb7211_map_io,
+	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
 MACHINE_END
diff --git a/arch/arm/mach-clps711x/fortunet.c b/arch/arm/mach-clps711x/fortunet.c
index c1c5b8e..f83a597 100644
--- a/arch/arm/mach-clps711x/fortunet.c
+++ b/arch/arm/mach-clps711x/fortunet.c
@@ -75,11 +75,13 @@
 }
 
 MACHINE_START(FORTUNET, "ARM-FortuNet")
-	MAINTAINER("FortuNet Inc.")
-        BOOT_MEM(0xc0000000, 0x80000000, 0xf0000000)
-	BOOT_PARAMS(0x00000000)
-	FIXUP(fortunet_fixup)
-	MAPIO(clps711x_map_io)
-	INITIRQ(clps711x_init_irq)
+	/* Maintainer: FortuNet Inc. */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf0000000) >> 18) & 0xfffc,
+	.boot_params	= 0x00000000,
+	.fixup		= fortunet_fixup,
+	.map_io		= clps711x_map_io,
+	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
 MACHINE_END
diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c
index 29269df..5bdb90e 100644
--- a/arch/arm/mach-clps711x/p720t.c
+++ b/arch/arm/mach-clps711x/p720t.c
@@ -79,12 +79,14 @@
 }
 
 MACHINE_START(P720T, "ARM-Prospector720T")
-	MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
-	BOOT_PARAMS(0xc0000100)
-	FIXUP(fixup_p720t)
-	MAPIO(p720t_map_io)
-	INITIRQ(clps711x_init_irq)
+	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xff000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.fixup		= fixup_p720t,
+	.map_io		= p720t_map_io,
+	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
 MACHINE_END
 
diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c
index 90e85f43..112f1d68 100644
--- a/arch/arm/mach-clps7500/core.c
+++ b/arch/arm/mach-clps7500/core.c
@@ -366,11 +366,13 @@
 }
 
 MACHINE_START(CLPS7500, "CL-PS7500")
-	MAINTAINER("Philip Blundell")
-	BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
-	MAPIO(clps7500_map_io)
-	INITIRQ(clps7500_init_irq)
-		.init_machine	= clps7500_init,
-		.timer		= &clps7500_timer,
+	/* Maintainer: Philip Blundell */
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0x03000000,
+	.io_pg_offst	= ((0xe0000000) >> 18) & 0xfffc,
+	.map_io		= clps7500_map_io,
+	.init_irq	= clps7500_init_irq,
+	.init_machine	= clps7500_init,
+	.timer		= &clps7500_timer,
 MACHINE_END
 
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index 86ffdbb..23c4da1 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -233,13 +233,15 @@
 arch_initcall(ebsa110_init);
 
 MACHINE_START(EBSA110, "EBSA110")
-	MAINTAINER("Russell King")
-	BOOT_MEM(0x00000000, 0xe0000000, 0xe0000000)
-	BOOT_PARAMS(0x00000400)
-	DISABLE_PARPORT(0)
-	DISABLE_PARPORT(2)
-	SOFT_REBOOT
-	MAPIO(ebsa110_map_io)
-	INITIRQ(ebsa110_init_irq)
+	/* Maintainer: Russell King */
+	.phys_ram	= 0x00000000,
+	.phys_io	= 0xe0000000,
+	.io_pg_offst	= ((0xe0000000) >> 18) & 0xfffc,
+	.boot_params	= 0x00000400,
+	.reserve_lp0	= 1,
+	.reserve_lp2	= 1,
+	.soft_reboot	= 1,
+	.map_io		= ebsa110_map_io,
+	.init_irq	= ebsa110_init_irq,
 	.timer		= &ebsa110_timer,
 MACHINE_END
diff --git a/arch/arm/mach-epxa10db/arch.c b/arch/arm/mach-epxa10db/arch.c
index 1b40340..7daa021 100644
--- a/arch/arm/mach-epxa10db/arch.c
+++ b/arch/arm/mach-epxa10db/arch.c
@@ -63,10 +63,12 @@
 extern struct sys_timer epxa10db_timer;
 
 MACHINE_START(CAMELOT, "Altera Epxa10db")
-	MAINTAINER("Altera Corporation")
-	BOOT_MEM(0x00000000, 0x7fffc000, 0xffffc000)
-	MAPIO(epxa10db_map_io)
-	INITIRQ(epxa10db_init_irq)
+	/* Maintainer: Altera Corporation */
+	.phys_ram	= 0x00000000,
+	.phys_io	= 0x7fffc000,
+	.io_pg_offst	= ((0xffffc000) >> 18) & 0xfffc,
+	.map_io		= epxa10db_map_io,
+	.init_irq	= epxa10db_init_irq,
 	.timer		= &epxa10db_timer,
 MACHINE_END
 
diff --git a/arch/arm/mach-footbridge/cats-hw.c b/arch/arm/mach-footbridge/cats-hw.c
index d1ced86..49b898a 100644
--- a/arch/arm/mach-footbridge/cats-hw.c
+++ b/arch/arm/mach-footbridge/cats-hw.c
@@ -84,12 +84,14 @@
 }
 
 MACHINE_START(CATS, "Chalice-CATS")
-	MAINTAINER("Philip Blundell")
-	BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
-	BOOT_PARAMS(0x00000100)
-	SOFT_REBOOT
-	FIXUP(fixup_cats)
-	MAPIO(footbridge_map_io)
-	INITIRQ(footbridge_init_irq)
+	/* Maintainer: Philip Blundell */
+	.phys_ram	= 0x00000000,
+	.phys_io	= DC21285_ARMCSR_BASE,
+	.io_pg_offst	= ((0xfe000000) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.soft_reboot	= 1,
+	.fixup		= fixup_cats,
+	.map_io		= footbridge_map_io,
+	.init_irq	= footbridge_init_irq,
 	.timer		= &isa_timer,
 MACHINE_END
diff --git a/arch/arm/mach-footbridge/co285.c b/arch/arm/mach-footbridge/co285.c
index e154191..548a790 100644
--- a/arch/arm/mach-footbridge/co285.c
+++ b/arch/arm/mach-footbridge/co285.c
@@ -28,11 +28,13 @@
 }
 
 MACHINE_START(CO285, "co-EBSA285")
-	MAINTAINER("Mark van Doesburg")
-	BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0x7cf00000)
-	FIXUP(fixup_coebsa285)
-	MAPIO(footbridge_map_io)
-	INITIRQ(footbridge_init_irq)
+	/* Maintainer: Mark van Doesburg */
+	.phys_ram	= 0x00000000,
+	.phys_io	= DC21285_ARMCSR_BASE,
+	.io_pg_offst	= ((0x7cf00000) >> 18) & 0xfffc,
+	.fixup		= fixup_coebsa285,
+	.map_io		= footbridge_map_io,
+	.init_irq	= footbridge_init_irq,
 	.timer		= &footbridge_timer,
 MACHINE_END
 
diff --git a/arch/arm/mach-footbridge/ebsa285.c b/arch/arm/mach-footbridge/ebsa285.c
index d0931f5a..1c37605 100644
--- a/arch/arm/mach-footbridge/ebsa285.c
+++ b/arch/arm/mach-footbridge/ebsa285.c
@@ -13,12 +13,15 @@
 #include "common.h"
 
 MACHINE_START(EBSA285, "EBSA285")
-	MAINTAINER("Russell King")
-	BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
-	BOOT_PARAMS(0x00000100)
-	VIDEO(0x000a0000, 0x000bffff)
-	MAPIO(footbridge_map_io)
-	INITIRQ(footbridge_init_irq)
+	/* Maintainer: Russell King */
+	.phys_ram	= 0x00000000,
+	.phys_io	= DC21285_ARMCSR_BASE,
+	.io_pg_offst	= ((0xfe000000) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.video_start	= 0x000a0000,
+	.video_end	= 0x000bffff,
+	.map_io		= footbridge_map_io,
+	.init_irq	= footbridge_init_irq,
 	.timer		= &footbridge_timer,
 MACHINE_END
 
diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c
index 1e1dfd7..775f85f 100644
--- a/arch/arm/mach-footbridge/netwinder-hw.c
+++ b/arch/arm/mach-footbridge/netwinder-hw.c
@@ -647,14 +647,17 @@
 }
 
 MACHINE_START(NETWINDER, "Rebel-NetWinder")
-	MAINTAINER("Russell King/Rebel.com")
-	BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
-	BOOT_PARAMS(0x00000100)
-	VIDEO(0x000a0000, 0x000bffff)
-	DISABLE_PARPORT(0)
-	DISABLE_PARPORT(2)
-	FIXUP(fixup_netwinder)
-	MAPIO(footbridge_map_io)
-	INITIRQ(footbridge_init_irq)
+	/* Maintainer: Russell King/Rebel.com */
+	.phys_ram	= 0x00000000,
+	.phys_io	= DC21285_ARMCSR_BASE,
+	.io_pg_offst	= ((0xfe000000) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.video_start	= 0x000a0000,
+	.video_end	= 0x000bffff,
+	.reserve_lp0	= 1,
+	.reserve_lp2	= 1,
+	.fixup		= fixup_netwinder,
+	.map_io		= footbridge_map_io,
+	.init_irq	= footbridge_init_irq,
 	.timer		= &isa_timer,
 MACHINE_END
diff --git a/arch/arm/mach-footbridge/personal.c b/arch/arm/mach-footbridge/personal.c
index 415086d..0146b8b 100644
--- a/arch/arm/mach-footbridge/personal.c
+++ b/arch/arm/mach-footbridge/personal.c
@@ -13,11 +13,13 @@
 #include "common.h"
 
 MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer")
-	MAINTAINER("Jamey Hicks / George France")
-	BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(footbridge_map_io)
-	INITIRQ(footbridge_init_irq)
+	/* Maintainer: Jamey Hicks / George France */
+	.phys_ram	= 0x00000000,
+	.phys_io	= DC21285_ARMCSR_BASE,
+	.io_pg_offst	= ((0xfe000000) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= footbridge_map_io,
+	.init_irq	= footbridge_init_irq,
 	.timer		= &footbridge_timer,
 MACHINE_END
 
diff --git a/arch/arm/mach-h720x/h7201-eval.c b/arch/arm/mach-h720x/h7201-eval.c
index 9b24b9b..fa59e9e 100644
--- a/arch/arm/mach-h720x/h7201-eval.c
+++ b/arch/arm/mach-h720x/h7201-eval.c
@@ -30,10 +30,12 @@
 #include "common.h"
 
 MACHINE_START(H7201, "Hynix GMS30C7201")
-	MAINTAINER("Robert Schwebel, Pengutronix")
-	BOOT_MEM(0x40000000, 0x80000000, 0xf0000000)
-	BOOT_PARAMS(0xc0001000)
-	MAPIO(h720x_map_io)
-	INITIRQ(h720x_init_irq)
-	.timer = &h7201_timer,
+	/* Maintainer: Robert Schwebel, Pengutronix */
+	.phys_ram	= 0x40000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf0000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0001000,
+	.map_io		= h720x_map_io,
+	.init_irq	= h720x_init_irq,
+	.timer		= &h7201_timer,
 MACHINE_END
diff --git a/arch/arm/mach-h720x/h7202-eval.c b/arch/arm/mach-h720x/h7202-eval.c
index 3456a00..db9078a 100644
--- a/arch/arm/mach-h720x/h7202-eval.c
+++ b/arch/arm/mach-h720x/h7202-eval.c
@@ -71,11 +71,13 @@
 }
 
 MACHINE_START(H7202, "Hynix HMS30C7202")
-	MAINTAINER("Robert Schwebel, Pengutronix")
-	BOOT_MEM(0x40000000, 0x80000000, 0xf0000000)
-	BOOT_PARAMS(0x40000100)
-	MAPIO(h720x_map_io)
-	INITIRQ(h7202_init_irq)
-	.timer = &h7202_timer,
-	INIT_MACHINE(init_eval_h7202)
+	/* Maintainer: Robert Schwebel, Pengutronix */
+	.phys_ram	= 0x40000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf0000000) >> 18) & 0xfffc,
+	.boot_params	= 0x40000100,
+	.map_io		= h720x_map_io,
+	.init_irq	= h7202_init_irq,
+	.timer		= &h7202_timer,
+	.init_machine	= init_eval_h7202,
 MACHINE_END
diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c
index 625dd01..5d25434 100644
--- a/arch/arm/mach-imx/mx1ads.c
+++ b/arch/arm/mach-imx/mx1ads.c
@@ -78,11 +78,13 @@
 }
 
 MACHINE_START(MX1ADS, "Motorola MX1ADS")
-	MAINTAINER("Sascha Hauer, Pengutronix")
-	BOOT_MEM(0x08000000, 0x00200000, 0xe0200000)
-	BOOT_PARAMS(0x08000100)
-	MAPIO(mx1ads_map_io)
-	INITIRQ(imx_init_irq)
+	/* Maintainer: Sascha Hauer, Pengutronix */
+	.phys_ram	= 0x08000000,
+	.phys_io	= 0x00200000,
+	.io_pg_offst	= ((0xe0200000) >> 18) & 0xfffc,
+	.boot_params	= 0x08000100,
+	.map_io		= mx1ads_map_io,
+	.init_irq	= imx_init_irq,
 	.timer		= &imx_timer,
-	INIT_MACHINE(mx1ads_init)
+	.init_machine	= mx1ads_init,
 MACHINE_END
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 9222e57..dacbf50 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -20,6 +20,7 @@
 #include <asm/irq.h>
 #include <asm/io.h>
 #include <asm/hardware/amba.h>
+#include <asm/hardware/arm_timer.h>
 #include <asm/arch/cm.h>
 #include <asm/system.h>
 #include <asm/leds.h>
@@ -156,16 +157,6 @@
 #define TICKS2USECS(x)	((x) / TICKS_PER_uSEC)
 #endif
 
-/*
- * What does it look like?
- */
-typedef struct TimerStruct {
-	unsigned long TimerLoad;
-	unsigned long TimerValue;
-	unsigned long TimerControl;
-	unsigned long TimerClear;
-} TimerStruct_t;
-
 static unsigned long timer_reload;
 
 /*
@@ -174,7 +165,6 @@
  */
 unsigned long integrator_gettimeoffset(void)
 {
-	volatile TimerStruct_t *timer1 = (TimerStruct_t *)TIMER1_VA_BASE;
 	unsigned long ticks1, ticks2, status;
 
 	/*
@@ -183,11 +173,11 @@
 	 * an interrupt.  We get around this by ensuring that the
 	 * counter has not reloaded between our two reads.
 	 */
-	ticks2 = timer1->TimerValue & 0xffff;
+	ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff;
 	do {
 		ticks1 = ticks2;
 		status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS);
-		ticks2 = timer1->TimerValue & 0xffff;
+		ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff;
 	} while (ticks2 > ticks1);
 
 	/*
@@ -213,14 +203,12 @@
 static irqreturn_t
 integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
-
 	write_seqlock(&xtime_lock);
 
 	/*
 	 * clear the interrupt
 	 */
-	timer1->TimerClear = 1;
+	writel(1, TIMER1_VA_BASE + TIMER_INTCLR);
 
 	/*
 	 * the clock tick routines are only processed on the
@@ -256,32 +244,29 @@
  */
 void __init integrator_time_init(unsigned long reload, unsigned int ctrl)
 {
-	volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
-	volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
-	volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE;
-	unsigned int timer_ctrl = 0x80 | 0x40;	/* periodic */
+	unsigned int timer_ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
 
 	timer_reload = reload;
 	timer_ctrl |= ctrl;
 
 	if (timer_reload > 0x100000) {
 		timer_reload >>= 8;
-		timer_ctrl |= 0x08; /* /256 */
+		timer_ctrl |= TIMER_CTRL_DIV256;
 	} else if (timer_reload > 0x010000) {
 		timer_reload >>= 4;
-		timer_ctrl |= 0x04; /* /16 */
+		timer_ctrl |= TIMER_CTRL_DIV16;
 	}
 
 	/*
 	 * Initialise to a known state (all timers off)
 	 */
-	timer0->TimerControl = 0;
-	timer1->TimerControl = 0;
-	timer2->TimerControl = 0;
+	writel(0, TIMER0_VA_BASE + TIMER_CTRL);
+	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
+	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
 
-	timer1->TimerLoad    = timer_reload;
-	timer1->TimerValue   = timer_reload;
-	timer1->TimerControl = timer_ctrl;
+	writel(timer_reload, TIMER1_VA_BASE + TIMER_LOAD);
+	writel(timer_reload, TIMER1_VA_BASE + TIMER_VALUE);
+	writel(timer_ctrl, TIMER1_VA_BASE + TIMER_CTRL);
 
 	/*
 	 * Make irqs happen for the system timer
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 91ba9fd..36e2b6e 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -292,11 +292,13 @@
 };
 
 MACHINE_START(INTEGRATOR, "ARM-Integrator")
-	MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
-	BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(ap_map_io)
-	INITIRQ(ap_init_irq)
+	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+	.phys_ram	= 0x00000000,
+	.phys_io	= 0x16000000,
+	.io_pg_offst	= ((0xf1600000) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= ap_map_io,
+	.init_irq	= ap_init_irq,
 	.timer		= &ap_timer,
-	INIT_MACHINE(ap_init)
+	.init_machine	= ap_init,
 MACHINE_END
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index e0a01ee..569f328 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -532,11 +532,13 @@
 };
 
 MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
-	MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
-	BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(intcp_map_io)
-	INITIRQ(intcp_init_irq)
+	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+	.phys_ram	= 0x00000000,
+	.phys_io	= 0x16000000,
+	.io_pg_offst	= ((0xf1600000) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= intcp_map_io,
+	.init_irq	= intcp_init_irq,
 	.timer		= &cp_timer,
-	INIT_MACHINE(intcp_init)
+	.init_machine	= intcp_init,
 MACHINE_END
diff --git a/arch/arm/mach-iop3xx/iop321-setup.c b/arch/arm/mach-iop3xx/iop321-setup.c
index bf23e0f..0f921ba 100644
--- a/arch/arm/mach-iop3xx/iop321-setup.c
+++ b/arch/arm/mach-iop3xx/iop321-setup.c
@@ -146,23 +146,27 @@
 
 #if defined(CONFIG_ARCH_IQ80321)
 MACHINE_START(IQ80321, "Intel IQ80321")
-	MAINTAINER("Intel Corporation")
-	BOOT_MEM(PHYS_OFFSET, IQ80321_UART, IQ80321_UART)
-	MAPIO(iq80321_map_io)
-	INITIRQ(iop321_init_irq)
+	/* Maintainer: Intel Corporation */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= IQ80321_UART,
+	.io_pg_offst	= ((IQ80321_UART) >> 18) & 0xfffc,
+	.map_io		= iq80321_map_io,
+	.init_irq	= iop321_init_irq,
 	.timer		= &iop321_timer,
-    BOOT_PARAMS(0xa0000100)
-	INIT_MACHINE(iop32x_init)
+	.boot_params	= 0xa0000100,
+	.init_machine	= iop32x_init,
 MACHINE_END
 #elif defined(CONFIG_ARCH_IQ31244)
 MACHINE_START(IQ31244, "Intel IQ31244")
-    MAINTAINER("Intel Corp.")
-    BOOT_MEM(PHYS_OFFSET, IQ31244_UART, IQ31244_UART)
-    MAPIO(iq31244_map_io)
-    INITIRQ(iop321_init_irq)
+	/* Maintainer: Intel Corp. */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= IQ31244_UART,
+	.io_pg_offst	= ((IQ31244_UART) >> 18) & 0xfffc,
+	.map_io		= iq31244_map_io,
+	.init_irq	= iop321_init_irq,
 	.timer		= &iop321_timer,
-    BOOT_PARAMS(0xa0000100)
-	INIT_MACHINE(iop32x_init)
+	.boot_params	= 0xa0000100,
+	.init_machine	= iop32x_init,
 MACHINE_END
 #else
 #error No machine descriptor defined for this IOP3XX implementation
diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c
index 622e7914..fc74b72 100644
--- a/arch/arm/mach-iop3xx/iop331-setup.c
+++ b/arch/arm/mach-iop3xx/iop331-setup.c
@@ -148,26 +148,28 @@
 
 #if defined(CONFIG_ARCH_IQ80331)
 MACHINE_START(IQ80331, "Intel IQ80331")
-    MAINTAINER("Intel Corp.")
-    BOOT_MEM(PHYS_OFFSET, 0xfefff000, 0xfffff000) // virtual, physical
-    //BOOT_MEM(PHYS_OFFSET, IOP331_UART0_VIRT, IOP331_UART0_PHYS)
-    MAPIO(iq80331_map_io)
-    INITIRQ(iop331_init_irq)
+	/* Maintainer: Intel Corp. */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= 0xfefff000,
+	.io_pg_offst	= ((0xfffff000) >> 18) & 0xfffc, // virtual, physical
+	.map_io		= iq80331_map_io,
+	.init_irq	= iop331_init_irq,
 	.timer		= &iop331_timer,
-    BOOT_PARAMS(0x0100)
-	INIT_MACHINE(iop33x_init)
+	.boot_params	= 0x0100,
+	.init_machine	= iop33x_init,
 MACHINE_END
 
 #elif defined(CONFIG_MACH_IQ80332)
 MACHINE_START(IQ80332, "Intel IQ80332")
-    MAINTAINER("Intel Corp.")
-    BOOT_MEM(PHYS_OFFSET, 0xfefff000, 0xfffff000) // virtual, physical
-    //BOOT_MEM(PHYS_OFFSET, IOP331_UART0_VIRT, IOP331_UART0_PHYS)
-    MAPIO(iq80332_map_io)
-    INITIRQ(iop331_init_irq)
+	/* Maintainer: Intel Corp. */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= 0xfefff000,
+	.io_pg_offst	= ((0xfffff000) >> 18) & 0xfffc, // virtual, physical
+	.map_io		= iq80332_map_io,
+	.init_irq	= iop331_init_irq,
 	.timer		= &iop331_timer,
-    BOOT_PARAMS(0x0100)
-	INIT_MACHINE(iop33x_init)
+	.boot_params	= 0x0100,
+	.init_machine	= iop33x_init,
 MACHINE_END
 
 #else
diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c
index f3a291b..b7ebf38 100644
--- a/arch/arm/mach-ixp2000/enp2611.c
+++ b/arch/arm/mach-ixp2000/enp2611.c
@@ -223,13 +223,15 @@
 
 
 MACHINE_START(ENP2611, "Radisys ENP-2611 PCI network processor board")
-	MAINTAINER("Lennert Buytenhek <buytenh@wantstofly.org>")
-	BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(ixp2000_map_io)
-	INITIRQ(ixp2000_init_irq)
+	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+	.phys_ram	= 0x00000000,
+	.phys_io	= IXP2000_UART_PHYS_BASE,
+	.io_pg_offst	= ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= ixp2000_map_io,
+	.init_irq	= ixp2000_init_irq,
 	.timer		= &enp2611_timer,
-	INIT_MACHINE(enp2611_init_machine)
+	.init_machine	= enp2611_init_machine,
 MACHINE_END
 
 
diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c
index df3ff26..fd280a9 100644
--- a/arch/arm/mach-ixp2000/ixdp2400.c
+++ b/arch/arm/mach-ixp2000/ixdp2400.c
@@ -168,12 +168,14 @@
 }
 
 MACHINE_START(IXDP2400, "Intel IXDP2400 Development Platform")
-	MAINTAINER("MontaVista Software, Inc.")
-	BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(ixdp2x00_map_io)
-	INITIRQ(ixdp2400_init_irq)
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_ram	= 0x00000000,
+	.phys_io	= IXP2000_UART_PHYS_BASE,
+	.io_pg_offst	= ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= ixdp2x00_map_io,
+	.init_irq	= ixdp2400_init_irq,
 	.timer		= &ixdp2400_timer,
-	INIT_MACHINE(ixdp2x00_init_machine)
+	.init_machine	= ixdp2x00_init_machine,
 MACHINE_END
 
diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c
index 468a4bb..f9073aa 100644
--- a/arch/arm/mach-ixp2000/ixdp2800.c
+++ b/arch/arm/mach-ixp2000/ixdp2800.c
@@ -284,12 +284,14 @@
 }
 
 MACHINE_START(IXDP2800, "Intel IXDP2800 Development Platform")
-	MAINTAINER("MontaVista Software, Inc.")
-	BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(ixdp2x00_map_io)
-	INITIRQ(ixdp2800_init_irq)
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_ram	= 0x00000000,
+	.phys_io	= IXP2000_UART_PHYS_BASE,
+	.io_pg_offst	= ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= ixdp2x00_map_io,
+	.init_irq	= ixdp2800_init_irq,
 	.timer		= &ixdp2800_timer,
-	INIT_MACHINE(ixdp2x00_init_machine)
+	.init_machine	= ixdp2x00_init_machine,
 MACHINE_END
 
diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c
index e94dace..c735887 100644
--- a/arch/arm/mach-ixp2000/ixdp2x01.c
+++ b/arch/arm/mach-ixp2000/ixdp2x01.c
@@ -375,25 +375,29 @@
 
 #ifdef CONFIG_ARCH_IXDP2401
 MACHINE_START(IXDP2401, "Intel IXDP2401 Development Platform")
-	MAINTAINER("MontaVista Software, Inc.")
-	BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(ixdp2x01_map_io)
-	INITIRQ(ixdp2x01_init_irq)
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_ram	= 0x00000000,
+	.phys_io	= IXP2000_UART_PHYS_BASE,
+	.io_pg_offst	= ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= ixdp2x01_map_io,
+	.init_irq	= ixdp2x01_init_irq,
 	.timer		= &ixdp2x01_timer,
-	INIT_MACHINE(ixdp2x01_init_machine)
+	.init_machine	= ixdp2x01_init_machine,
 MACHINE_END
 #endif
 
 #ifdef CONFIG_ARCH_IXDP2801
 MACHINE_START(IXDP2801, "Intel IXDP2801 Development Platform")
-	MAINTAINER("MontaVista Software, Inc.")
-	BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(ixdp2x01_map_io)
-	INITIRQ(ixdp2x01_init_irq)
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_ram	= 0x00000000,
+	.phys_io	= IXP2000_UART_PHYS_BASE,
+	.io_pg_offst	= ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= ixdp2x01_map_io,
+	.init_irq	= ixdp2x01_init_irq,
 	.timer		= &ixdp2x01_timer,
-	INIT_MACHINE(ixdp2x01_init_machine)
+	.init_machine	= ixdp2x01_init_machine,
 MACHINE_END
 #endif
 
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index aa92e37..2b54436 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -453,8 +453,8 @@
 	local_write_config(PCI_COMMAND, 2, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
 
 	res[0].name = "PCI I/O Space";
-	res[0].start = 0x00001000;
-	res[0].end = 0xffff0000;
+	res[0].start = 0x00000000;
+	res[0].end = 0x0000ffff;
 	res[0].flags = IORESOURCE_IO;
 
 	res[1].name = "PCI Memory Space";
diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c
index 8a05a12..4ff4393 100644
--- a/arch/arm/mach-ixp4xx/coyote-setup.c
+++ b/arch/arm/mach-ixp4xx/coyote-setup.c
@@ -56,21 +56,24 @@
 	.flags	= IORESOURCE_MEM,
 };
 
-static struct plat_serial8250_port coyote_uart_data = {
-	.mapbase	= IXP4XX_UART2_BASE_PHYS,
-	.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
-	.irq		= IRQ_IXP4XX_UART2,
-	.flags		= UPF_BOOT_AUTOCONF,
-	.iotype		= UPIO_MEM,
-	.regshift	= 2,
-	.uartclk	= IXP4XX_UART_XTAL,
+static struct plat_serial8250_port coyote_uart_data[] = {
+	{
+		.mapbase	= IXP4XX_UART2_BASE_PHYS,
+		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+		.irq		= IRQ_IXP4XX_UART2,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= IXP4XX_UART_XTAL,
+	},
+	{ },
 };
 
 static struct platform_device coyote_uart = {
 	.name		= "serial8250",
 	.id		= 0,
 	.dev			= {
-		.platform_data	= &coyote_uart_data,
+		.platform_data	= coyote_uart_data,
 	},
 	.num_resources	= 1,
 	.resource	= &coyote_uart_resource,
@@ -87,10 +90,10 @@
 	*IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
 
 	if (machine_is_ixdpg425()) {
-		coyote_uart_data.membase =
+		coyote_uart_data[0].membase =
 			(char*)(IXP4XX_UART1_BASE_VIRT + REG_OFFSET);
-		coyote_uart_data.mapbase = IXP4XX_UART1_BASE_PHYS;
-		coyote_uart_data.irq = IRQ_IXP4XX_UART1;
+		coyote_uart_data[0].mapbase = IXP4XX_UART1_BASE_PHYS;
+		coyote_uart_data[0].irq = IRQ_IXP4XX_UART1;
 	}
 
 
@@ -100,14 +103,15 @@
 
 #ifdef CONFIG_ARCH_ADI_COYOTE
 MACHINE_START(ADI_COYOTE, "ADI Engineering Coyote")
-        MAINTAINER("MontaVista Software, Inc.")
-        BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS,
-                IXP4XX_PERIPHERAL_BASE_VIRT)
-        MAPIO(coyote_map_io)
-        INITIRQ(ixp4xx_init_irq)
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
+	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
+	.map_io		= coyote_map_io,
+	.init_irq	= ixp4xx_init_irq,
 	.timer		= &ixp4xx_timer,
-        BOOT_PARAMS(0x0100)
-	INIT_MACHINE(coyote_init)
+	.boot_params	= 0x0100,
+	.init_machine	= coyote_init,
 MACHINE_END
 #endif
 
@@ -117,14 +121,15 @@
  */
 #ifdef CONFIG_MACH_IXDPG425
 MACHINE_START(IXDPG425, "Intel IXDPG425")
-        MAINTAINER("MontaVista Software, Inc.")
-        BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS,
-                IXP4XX_PERIPHERAL_BASE_VIRT)
-        MAPIO(coyote_map_io)
-        INITIRQ(ixp4xx_init_irq)
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
+	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
+	.map_io		= coyote_map_io,
+	.init_irq	= ixp4xx_init_irq,
 	.timer		= &ixp4xx_timer,
-        BOOT_PARAMS(0x0100)
-	INIT_MACHINE(coyote_init)
+	.boot_params	= 0x0100,
+	.init_machine	= coyote_init,
 MACHINE_END
 #endif
 
diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
index e77c86e..8ba1cd9 100644
--- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c
+++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
@@ -140,14 +140,15 @@
 
 
 MACHINE_START(GTWX5715, "Gemtek GTWX5715 (Linksys WRV54G)")
-        MAINTAINER("George Joseph")
-        BOOT_MEM(PHYS_OFFSET, IXP4XX_UART2_BASE_PHYS,
-                IXP4XX_UART2_BASE_VIRT)
-        MAPIO(gtwx5715_map_io)
-        INITIRQ(ixp4xx_init_irq)
-		  .timer		= &ixp4xx_timer,
-        BOOT_PARAMS(0x0100)
-        INIT_MACHINE(gtwx5715_init)
+	/* Maintainer: George Joseph */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= IXP4XX_UART2_BASE_PHYS,
+	.io_pg_offst	= ((IXP4XX_UART2_BASE_VIRT) >> 18) & 0xfffc,
+	.map_io		= gtwx5715_map_io,
+	.init_irq	= ixp4xx_init_irq,
+	.timer		= &ixp4xx_timer,
+	.boot_params	= 0x0100,
+	.init_machine	= gtwx5715_init,
 MACHINE_END
 
 
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
index 77346c1..c2ba759 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -95,7 +95,8 @@
 		.iotype		= UPIO_MEM,
 		.regshift	= 2,
 		.uartclk	= IXP4XX_UART_XTAL,
-	}
+	},
+	{ },
 };
 
 static struct platform_device ixdp425_uart = {
@@ -128,36 +129,39 @@
 }
 
 MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
-	MAINTAINER("MontaVista Software, Inc.")
-	BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS,
-		IXP4XX_PERIPHERAL_BASE_VIRT)
-	MAPIO(ixdp425_map_io)
-	INITIRQ(ixp4xx_init_irq)
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
+	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
+	.map_io		= ixdp425_map_io,
+	.init_irq	= ixp4xx_init_irq,
 	.timer		= &ixp4xx_timer,
-	BOOT_PARAMS(0x0100)
-	INIT_MACHINE(ixdp425_init)
+	.boot_params	= 0x0100,
+	.init_machine	= ixdp425_init,
 MACHINE_END
 
 MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
-	MAINTAINER("MontaVista Software, Inc.")
-	BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS,
-		IXP4XX_PERIPHERAL_BASE_VIRT)
-	MAPIO(ixdp425_map_io)
-	INITIRQ(ixp4xx_init_irq)
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
+	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
+	.map_io		= ixdp425_map_io,
+	.init_irq	= ixp4xx_init_irq,
 	.timer		= &ixp4xx_timer,
-	BOOT_PARAMS(0x0100)
-	INIT_MACHINE(ixdp425_init)
+	.boot_params	= 0x0100,
+	.init_machine	= ixdp425_init,
 MACHINE_END
 
 MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
-	MAINTAINER("MontaVista Software, Inc.")
-	BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS,
-		IXP4XX_PERIPHERAL_BASE_VIRT)
-	MAPIO(ixdp425_map_io)
-	INITIRQ(ixp4xx_init_irq)
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
+	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
+	.map_io		= ixdp425_map_io,
+	.init_irq	= ixp4xx_init_irq,
 	.timer		= &ixp4xx_timer,
-	BOOT_PARAMS(0x0100)
-	INIT_MACHINE(ixdp425_init)
+	.boot_params	= 0x0100,
+	.init_machine	= ixdp425_init,
 MACHINE_END
 
 /*
@@ -168,14 +172,15 @@
  */
 #ifdef CONFIG_ARCH_AVILA
 MACHINE_START(AVILA, "Gateworks Avila Network Platform")
-	MAINTAINER("Deepak Saxena <dsaxena@plexity.net>")
-	BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS,
-		IXP4XX_PERIPHERAL_BASE_VIRT)
-	MAPIO(ixdp425_map_io)
-	INITIRQ(ixp4xx_init_irq)
+	/* Maintainer: Deepak Saxena <dsaxena@plexity.net> */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
+	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
+	.map_io		= ixdp425_map_io,
+	.init_irq	= ixp4xx_init_irq,
 	.timer		= &ixp4xx_timer,
-	BOOT_PARAMS(0x0100)
-	INIT_MACHINE(ixdp425_init)
+	.boot_params	= 0x0100,
+	.init_machine	= ixdp425_init,
 MACHINE_END
 #endif
 
diff --git a/arch/arm/mach-l7200/core.c b/arch/arm/mach-l7200/core.c
index 606ca95..2a7fee2 100644
--- a/arch/arm/mach-l7200/core.c
+++ b/arch/arm/mach-l7200/core.c
@@ -81,9 +81,11 @@
 }
 
 MACHINE_START(L7200, "LinkUp Systems L7200")
-	MAINTAINER("Steve Hill / Scott McConnell")
-	BOOT_MEM(0xf0000000, 0x80040000, 0xd0000000)
-	MAPIO(l7200_map_io)
-	INITIRQ(l7200_init_irq)
+	/* Maintainer: Steve Hill / Scott McConnell */
+	.phys_ram	= 0xf0000000,
+	.phys_io	= 0x80040000,
+	.io_pg_offst	= ((0xd0000000) >> 18) & 0xfffc,
+	.map_io		= l7200_map_io,
+	.init_irq	= l7200_init_irq,
 MACHINE_END
 
diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c
index be5d17f..cb3dcd3 100644
--- a/arch/arm/mach-lh7a40x/arch-kev7a400.c
+++ b/arch/arm/mach-lh7a40x/arch-kev7a400.c
@@ -102,10 +102,12 @@
 }
 
 MACHINE_START (KEV7A400, "Sharp KEV7a400")
-	MAINTAINER ("Marc Singer")
-	BOOT_MEM (0xc0000000, 0x80000000, io_p2v (0x80000000))
-	BOOT_PARAMS (0xc0000100)
-	MAPIO (kev7a400_map_io)
-	INITIRQ (lh7a400_init_irq)
+	/* Maintainer: Marc Singer */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((io_p2v (0x80000000))>>18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= kev7a400_map_io,
+	.init_irq	= lh7a400_init_irq,
 	.timer		= &lh7a40x_timer,
 MACHINE_END
diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
index c823447..6eb61a1 100644
--- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
+++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
@@ -260,13 +260,15 @@
 #ifdef CONFIG_MACH_LPD7A400
 
 MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10")
-	MAINTAINER ("Marc Singer")
-	BOOT_MEM (0xc0000000, 0x80000000, io_p2v (0x80000000))
-	BOOT_PARAMS (0xc0000100)
-	MAPIO (lpd7a400_map_io)
-	INITIRQ (lh7a400_init_irq)
+	/* Maintainer: Marc Singer */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((io_p2v (0x80000000))>>18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= lpd7a400_map_io,
+	.init_irq	= lh7a400_init_irq,
 	.timer		= &lh7a40x_timer,
-	INIT_MACHINE (lpd7a40x_init)
+	.init_machine	= lpd7a40x_init,
 MACHINE_END
 
 #endif
@@ -274,13 +276,15 @@
 #ifdef CONFIG_MACH_LPD7A404
 
 MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10")
-	MAINTAINER ("Marc Singer")
-	BOOT_MEM (0xc0000000, 0x80000000, io_p2v (0x80000000))
-	BOOT_PARAMS (0xc0000100)
-	MAPIO (lpd7a400_map_io)
-	INITIRQ (lh7a404_init_irq)
+	/* Maintainer: Marc Singer */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((io_p2v (0x80000000))>>18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= lpd7a400_map_io,
+	.init_irq	= lh7a404_init_irq,
 	.timer		= &lh7a40x_timer,
-	INIT_MACHINE (lpd7a40x_init)
+	.init_machine	= lpd7a40x_init,
 MACHINE_END
 
 #endif
diff --git a/arch/arm/mach-omap/board-generic.c b/arch/arm/mach-omap/board-generic.c
index 2102a2c..384bc7c 100644
--- a/arch/arm/mach-omap/board-generic.c
+++ b/arch/arm/mach-omap/board-generic.c
@@ -88,11 +88,13 @@
 }
 
 MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
-	MAINTAINER("Tony Lindgren <tony@atomide.com>")
-	BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
-	BOOT_PARAMS(0x10000100)
-	MAPIO(omap_generic_map_io)
-	INITIRQ(omap_generic_init_irq)
-	INIT_MACHINE(omap_generic_init)
+	/* Maintainer: Tony Lindgren <tony@atomide.com> */
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= omap_generic_map_io,
+	.init_irq	= omap_generic_init_irq,
+	.init_machine	= omap_generic_init,
 	.timer		= &omap_timer,
 MACHINE_END
diff --git a/arch/arm/mach-omap/board-h2.c b/arch/arm/mach-omap/board-h2.c
index 1f06783..f37c76a 100644
--- a/arch/arm/mach-omap/board-h2.c
+++ b/arch/arm/mach-omap/board-h2.c
@@ -177,11 +177,13 @@
 }
 
 MACHINE_START(OMAP_H2, "TI-H2")
-	MAINTAINER("Imre Deak <imre.deak@nokia.com>")
-	BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
-	BOOT_PARAMS(0x10000100)
-	MAPIO(h2_map_io)
-	INITIRQ(h2_init_irq)
-	INIT_MACHINE(h2_init)
+	/* Maintainer: Imre Deak <imre.deak@nokia.com> */
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= h2_map_io,
+	.init_irq	= h2_init_irq,
+	.init_machine	= h2_init,
 	.timer		= &omap_timer,
 MACHINE_END
diff --git a/arch/arm/mach-omap/board-h3.c b/arch/arm/mach-omap/board-h3.c
index 486a5a0..705e485 100644
--- a/arch/arm/mach-omap/board-h3.c
+++ b/arch/arm/mach-omap/board-h3.c
@@ -195,11 +195,13 @@
 }
 
 MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
-	MAINTAINER("Texas Instruments, Inc.")
-	BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
-	BOOT_PARAMS(0x10000100)
-	MAPIO(h3_map_io)
-	INITIRQ(h3_init_irq)
-	INIT_MACHINE(h3_init)
+	/* Maintainer: Texas Instruments, Inc. */
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= h3_map_io,
+	.init_irq	= h3_init_irq,
+	.init_machine	= h3_init,
 	.timer		= &omap_timer,
 MACHINE_END
diff --git a/arch/arm/mach-omap/board-innovator.c b/arch/arm/mach-omap/board-innovator.c
index 57cf4da..523363f 100644
--- a/arch/arm/mach-omap/board-innovator.c
+++ b/arch/arm/mach-omap/board-innovator.c
@@ -270,11 +270,13 @@
 }
 
 MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
-	MAINTAINER("MontaVista Software, Inc.")
-	BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
-	BOOT_PARAMS(0x10000100)
-	MAPIO(innovator_map_io)
-	INITIRQ(innovator_init_irq)
-	INIT_MACHINE(innovator_init)
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= innovator_map_io,
+	.init_irq	= innovator_init_irq,
+	.init_machine	= innovator_init,
 	.timer		= &omap_timer,
 MACHINE_END
diff --git a/arch/arm/mach-omap/board-netstar.c b/arch/arm/mach-omap/board-netstar.c
index 54acbd2..8c65373 100644
--- a/arch/arm/mach-omap/board-netstar.c
+++ b/arch/arm/mach-omap/board-netstar.c
@@ -141,11 +141,13 @@
 postcore_initcall(netstar_late_init);
 
 MACHINE_START(NETSTAR, "NetStar OMAP5910")
-	MAINTAINER("Ladislav Michl <michl@2n.cz>")
-	BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
-	BOOT_PARAMS(0x10000100)
-	MAPIO(netstar_map_io)
-	INITIRQ(netstar_init_irq)
-	INIT_MACHINE(netstar_init)
-	.timer = &omap_timer,
+	/* Maintainer: Ladislav Michl <michl@2n.cz> */
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= netstar_map_io,
+	.init_irq	= netstar_init_irq,
+	.init_machine	= netstar_init,
+	.timer		= &omap_timer,
 MACHINE_END
diff --git a/arch/arm/mach-omap/board-osk.c b/arch/arm/mach-omap/board-osk.c
index a951fc8..cb43343 100644
--- a/arch/arm/mach-omap/board-osk.c
+++ b/arch/arm/mach-omap/board-osk.c
@@ -159,11 +159,13 @@
 }
 
 MACHINE_START(OMAP_OSK, "TI-OSK")
-	MAINTAINER("Dirk Behme <dirk.behme@de.bosch.com>")
-	BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
-	BOOT_PARAMS(0x10000100)
-	MAPIO(osk_map_io)
-	INITIRQ(osk_init_irq)
-	INIT_MACHINE(osk_init)
+	/* Maintainer: Dirk Behme <dirk.behme@de.bosch.com> */
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= osk_map_io,
+	.init_irq	= osk_init_irq,
+	.init_machine	= osk_init,
 	.timer		= &omap_timer,
 MACHINE_END
diff --git a/arch/arm/mach-omap/board-perseus2.c b/arch/arm/mach-omap/board-perseus2.c
index 64515ae..d534204 100644
--- a/arch/arm/mach-omap/board-perseus2.c
+++ b/arch/arm/mach-omap/board-perseus2.c
@@ -179,11 +179,13 @@
 }
 
 MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
-	MAINTAINER("Kevin Hilman <kjh@hilman.org>")
-	BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
-	BOOT_PARAMS(0x10000100)
-	MAPIO(omap_perseus2_map_io)
-	INITIRQ(omap_perseus2_init_irq)
-	INIT_MACHINE(omap_perseus2_init)
+	/* Maintainer: Kevin Hilman <kjh@hilman.org> */
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= omap_perseus2_map_io,
+	.init_irq	= omap_perseus2_init_irq,
+	.init_machine	= omap_perseus2_init,
 	.timer		= &omap_timer,
 MACHINE_END
diff --git a/arch/arm/mach-omap/board-voiceblue.c b/arch/arm/mach-omap/board-voiceblue.c
index f1a5bff..6b0c500 100644
--- a/arch/arm/mach-omap/board-voiceblue.c
+++ b/arch/arm/mach-omap/board-voiceblue.c
@@ -246,11 +246,13 @@
 EXPORT_SYMBOL(voiceblue_wdt_ping);
 
 MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910")
-	MAINTAINER("Ladislav Michl <michl@2n.cz>")
-	BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
-	BOOT_PARAMS(0x10000100)
-	MAPIO(voiceblue_map_io)
-	INITIRQ(voiceblue_init_irq)
-	INIT_MACHINE(voiceblue_init)
-	.timer = &omap_timer,
+	/* Maintainer: Ladislav Michl <michl@2n.cz> */
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= voiceblue_map_io,
+	.init_irq	= voiceblue_init_irq,
+	.init_machine	= voiceblue_init,
+	.timer		= &omap_timer,
 MACHINE_END
diff --git a/arch/arm/mach-omap/pm.c b/arch/arm/mach-omap/pm.c
index 00fac15..6b03ccd 100644
--- a/arch/arm/mach-omap/pm.c
+++ b/arch/arm/mach-omap/pm.c
@@ -41,7 +41,9 @@
 #include <linux/pm.h>
 
 #include <asm/io.h>
+#include <asm/mach/time.h>
 #include <asm/mach-types.h>
+
 #include <asm/arch/omap16xx.h>
 #include <asm/arch/pm.h>
 #include <asm/arch/mux.h>
@@ -80,13 +82,13 @@
 		return;
 	}
 	mask32 = omap_readl(ARM_SYSST);
-	local_fiq_enable();
-	local_irq_enable();
 
-#if defined(CONFIG_OMAP_32K_TIMER) && defined(CONFIG_NO_IDLE_HZ)
-	/* Override timer to use VST for the next cycle */
-	omap_32k_timer_next_vst_interrupt();
-#endif
+	/*
+	 * Since an interrupt may set up a timer, we don't want to
+	 * reprogram the hardware timer with interrupts enabled.
+	 * Re-enable interrupts only after returning from idle.
+	 */
+	timer_dyn_reprogram();
 
 	if ((mask32 & DSP_IDLE) == 0) {
 		__asm__ volatile ("mcr	p15, 0, r0, c7, c0, 4");
@@ -102,6 +104,8 @@
 
 		func_ptr();
 	}
+	local_fiq_enable();
+	local_irq_enable();
 }
 
 /*
diff --git a/arch/arm/mach-omap/time.c b/arch/arm/mach-omap/time.c
index 589e8b2..dd34e9f 100644
--- a/arch/arm/mach-omap/time.c
+++ b/arch/arm/mach-omap/time.c
@@ -4,7 +4,7 @@
  * OMAP Timers
  *
  * Copyright (C) 2004 Nokia Corporation
- * Partial timer rewrite and additional VST timer support by
+ * Partial timer rewrite and additional dynamic tick timer support by
  * Tony Lindgen <tony@atomide.com> and
  * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
  *
@@ -261,7 +261,6 @@
  * so with HZ = 100, TVR = 327.68.
  */
 #define OMAP_32K_TIMER_TICK_PERIOD	((32768 / HZ) - 1)
-#define MAX_SKIP_JIFFIES		25
 #define TIMER_32K_SYNCHRONIZED		0xfffbc410
 
 #define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate)			\
@@ -347,6 +346,42 @@
 	return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_NO_IDLE_HZ
+/*
+ * Programs the next timer interrupt needed. Called when dynamic tick is
+ * enabled, and to reprogram the ticks to skip from pm_idle. Note that
+ * we can keep the timer continuous, and don't need to set it to run in
+ * one-shot mode. This is because the timer will get reprogrammed again
+ * after next interrupt.
+ */
+void omap_32k_timer_reprogram(unsigned long next_tick)
+{
+	omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1);
+}
+
+static struct irqaction omap_32k_timer_irq;
+extern struct timer_update_handler timer_update;
+
+static int omap_32k_timer_enable_dyn_tick(void)
+{
+	/* No need to reprogram timer, just use the next interrupt */
+	return 0;
+}
+
+static int omap_32k_timer_disable_dyn_tick(void)
+{
+	omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
+	return 0;
+}
+
+static struct dyn_tick_timer omap_dyn_tick_timer = {
+	.enable		= omap_32k_timer_enable_dyn_tick,
+	.disable	= omap_32k_timer_disable_dyn_tick,
+	.reprogram	= omap_32k_timer_reprogram,
+	.handler	= omap_32k_timer_interrupt,
+};
+#endif	/* CONFIG_NO_IDLE_HZ */
+
 static struct irqaction omap_32k_timer_irq = {
 	.name		= "32KHz timer",
 	.flags		= SA_INTERRUPT | SA_TIMER,
@@ -355,6 +390,11 @@
 
 static __init void omap_init_32k_timer(void)
 {
+
+#ifdef CONFIG_NO_IDLE_HZ
+	omap_timer.dyn_tick = &omap_dyn_tick_timer;
+#endif
+
 	setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
 	omap_timer.offset  = omap_32k_timer_gettimeoffset;
 	omap_32k_last_tick = omap_32k_sync_timer_read();
diff --git a/arch/arm/mach-omap/usb.c b/arch/arm/mach-omap/usb.c
index 7f37857..fd483ff 100644
--- a/arch/arm/mach-omap/usb.c
+++ b/arch/arm/mach-omap/usb.c
@@ -41,7 +41,6 @@
 
 /* These routines should handle the standard chip-specific modes
  * for usb0/1/2 ports, covering basic mux and transceiver setup.
- * Call omap_usb_init() once, from INIT_MACHINE().
  *
  * Some board-*.c files will need to set up additional mux options,
  * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup.
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index c4e6d25..efc2f65 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -24,3 +24,7 @@
 
 # Misc features
 obj-$(CONFIG_PM) += pm.o sleep.o
+
+ifeq ($(CONFIG_PXA27x),y)
+obj-$(CONFIG_PM) += standby.o
+endif
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index f691cf7..86b862f 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -287,34 +287,40 @@
 
 #ifdef CONFIG_MACH_CORGI
 MACHINE_START(CORGI, "SHARP Corgi")
-	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
-	FIXUP(fixup_corgi)
-	MAPIO(corgi_map_io)
-	INITIRQ(corgi_init_irq)
-	.init_machine = corgi_init,
-	.timer = &pxa_timer,
+	.phys_ram	= 0xa0000000,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.fixup		= fixup_corgi,
+	.map_io		= corgi_map_io,
+	.init_irq	= corgi_init_irq,
+	.init_machine	= corgi_init,
+	.timer		= &pxa_timer,
 MACHINE_END
 #endif
 
 #ifdef CONFIG_MACH_SHEPHERD
 MACHINE_START(SHEPHERD, "SHARP Shepherd")
-	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
-	FIXUP(fixup_corgi)
-	MAPIO(corgi_map_io)
-	INITIRQ(corgi_init_irq)
-	.init_machine = corgi_init,
-	.timer = &pxa_timer,
+	.phys_ram	= 0xa0000000,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.fixup		= fixup_corgi,
+	.map_io		= corgi_map_io,
+	.init_irq	= corgi_init_irq,
+	.init_machine	= corgi_init,
+	.timer		= &pxa_timer,
 MACHINE_END
 #endif
 
 #ifdef CONFIG_MACH_HUSKY
 MACHINE_START(HUSKY, "SHARP Husky")
-	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
-	FIXUP(fixup_corgi)
-	MAPIO(corgi_map_io)
-	INITIRQ(corgi_init_irq)
-	.init_machine = corgi_init,
-	.timer = &pxa_timer,
+	.phys_ram	= 0xa0000000,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.fixup		= fixup_corgi,
+	.map_io		= corgi_map_io,
+	.init_irq	= corgi_init_irq,
+	.init_machine	= corgi_init,
+	.timer		= &pxa_timer,
 MACHINE_END
 #endif
 
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index c5a66bf..386e107 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -181,10 +181,12 @@
 
 
 MACHINE_START(PXA_IDP, "Vibren PXA255 IDP")
-	MAINTAINER("Vibren Technologies")
-	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
-	MAPIO(idp_map_io)
-	INITIRQ(idp_init_irq)
+	/* Maintainer: Vibren Technologies */
+	.phys_ram	= 0xa0000000,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.map_io		= idp_map_io,
+	.init_irq	= idp_init_irq,
 	.timer		= &pxa_timer,
-	INIT_MACHINE(idp_init)
+	.init_machine	= idp_init,
 MACHINE_END
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index f2c9e0d..6309853 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -268,10 +268,12 @@
 }
 
 MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)")
-	MAINTAINER("MontaVista Software Inc.")
-	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
-	MAPIO(lubbock_map_io)
-	INITIRQ(lubbock_init_irq)
+	/* Maintainer: MontaVista Software Inc. */
+	.phys_ram	= 0xa0000000,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.map_io		= lubbock_map_io,
+	.init_irq	= lubbock_init_irq,
 	.timer		= &pxa_timer,
-	INIT_MACHINE(lubbock_init)
+	.init_machine	= lubbock_init,
 MACHINE_END
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 9896afc..827b7b5 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -345,10 +345,12 @@
 }
 
 MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
-	MAINTAINER("MontaVista Software Inc.")
-	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
-	MAPIO(mainstone_map_io)
-	INITIRQ(mainstone_init_irq)
+	/* Maintainer: MontaVista Software Inc. */
+	.phys_ram	= 0xa0000000,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.map_io		= mainstone_map_io,
+	.init_irq	= mainstone_init_irq,
 	.timer		= &pxa_timer,
-	INIT_MACHINE(mainstone_init)
+	.init_machine	= mainstone_init,
 MACHINE_END
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index b6c746e..0e4f6fa 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -180,10 +180,12 @@
 }
 
 MACHINE_START(POODLE, "SHARP Poodle")
-	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
-	FIXUP(fixup_poodle)
-	MAPIO(poodle_map_io)
-	INITIRQ(pxa_init_irq)
-	.timer = &pxa_timer,
-	.init_machine = poodle_init,
+	.phys_ram	= 0xa0000000,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.fixup		= fixup_poodle,
+	.map_io		= poodle_map_io,
+	.init_irq	= pxa_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= poodle_init,
 MACHINE_END
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 893964f..9a791b0 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -126,6 +126,7 @@
 {
 	switch (state) {
 	case PM_SUSPEND_MEM:
+	case PM_SUSPEND_STANDBY:
 		return 0;
 	default:
 		return -EINVAL;
@@ -138,7 +139,10 @@
 	extern void pxa_cpu_suspend(unsigned int);
 	extern void pxa_cpu_resume(void);
 
-	CKEN = CKEN22_MEMC | CKEN9_OSTIMER;
+	if (state == PM_SUSPEND_STANDBY)
+		CKEN = CKEN22_MEMC | CKEN9_OSTIMER | CKEN16_LCD |CKEN0_PWM0;
+	else
+		CKEN = CKEN22_MEMC | CKEN9_OSTIMER;
 
 	/* ensure voltage-change sequencer not initiated, which hangs */
 	PCFR &= ~PCFR_FVC;
@@ -147,6 +151,9 @@
 	PEDR = 0xDF12FE1B;
 
 	switch (state) {
+	case PM_SUSPEND_STANDBY:
+		pxa_cpu_standby();
+		break;
 	case PM_SUSPEND_MEM:
 		/* set resume return address */
 		PSPR = virt_to_phys(pxa_cpu_resume);
diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S
new file mode 100644
index 0000000..8a3f27b
--- /dev/null
+++ b/arch/arm/mach-pxa/standby.S
@@ -0,0 +1,32 @@
+/*
+ * PXA27x standby mode
+ *
+ * Author: David Burrage
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/pxa-regs.h>
+
+		.text
+
+ENTRY(pxa_cpu_standby)
+	ldr	r0, =PSSR
+	mov	r1, #(PSSR_PH | PSSR_STS)
+	mov	r2, #2
+	mov	r3, #UNCACHED_PHYS_0	@ Read mem context in.
+	ldr	ip, [r3]
+	b	1f
+
+	.align	5
+1:	mcr	p14, 0, r2, c7, c0, 0	@ put the system into Standby
+	str	r1, [r0]		@ make sure PSSR_PH/STS are clear
+	mov	pc, lr
diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c
index 4371068..a102686 100644
--- a/arch/arm/mach-rpc/riscpc.c
+++ b/arch/arm/mach-rpc/riscpc.c
@@ -163,12 +163,14 @@
 extern struct sys_timer ioc_timer;
 
 MACHINE_START(RISCPC, "Acorn-RiscPC")
-	MAINTAINER("Russell King")
-	BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
-	BOOT_PARAMS(0x10000100)
-	DISABLE_PARPORT(0)
-	DISABLE_PARPORT(1)
-	MAPIO(rpc_map_io)
-	INITIRQ(rpc_init_irq)
+	/* Maintainer: Russell King */
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0x03000000,
+	.io_pg_offst	= ((0xe0000000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.reserve_lp0	= 1,
+	.reserve_lp1	= 1,
+	.map_io		= rpc_map_io,
+	.init_irq	= rpc_init_irq,
 	.timer		= &ioc_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index 534df0c..d4d03d0 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -154,6 +154,11 @@
 	  the CRC data block will take more memory, but wil identify any
 	  faults with better precision.
 
+config PM_SIMTEC
+	bool
+	depends on PM && (ARCH_BAST || MACH_VR1000)
+	default y
+
 config S3C2410_LOWLEVEL_UART_PORT
 	int "S3C2410 UART to use for low-level messages"
 	default 0
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
index 7c379aa..f99b689 100644
--- a/arch/arm/mach-s3c2410/Makefile
+++ b/arch/arm/mach-s3c2410/Makefile
@@ -18,6 +18,7 @@
 # Power Management support
 
 obj-$(CONFIG_PM)	   += pm.o sleep.o
+obj-$(CONFIG_PM_SIMTEC)	   += pm-simtec.o
 
 # S3C2440 support
 
diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c
index 64792f6..4664bd1 100644
--- a/arch/arm/mach-s3c2410/devs.c
+++ b/arch/arm/mach-s3c2410/devs.c
@@ -96,8 +96,8 @@
 	.num_resources	  = ARRAY_SIZE(s3c_lcd_resource),
 	.resource	  = s3c_lcd_resource,
 	.dev              = {
-		.dma_mask = &s3c_device_lcd_dmamask,
-		.coherent_dma_mask = 0xffffffffUL
+		.dma_mask		= &s3c_device_lcd_dmamask,
+		.coherent_dma_mask	= 0xffffffffUL
 	}
 };
 
diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c
index b668c48..cf9f46d 100644
--- a/arch/arm/mach-s3c2410/irq.c
+++ b/arch/arm/mach-s3c2410/irq.c
@@ -40,8 +40,11 @@
  *   04-Nov-2004  Ben Dooks
  *		  Fix standard IRQ wake for EINT0..4 and RTC
  *
- *   22-Feb-2004  Ben Dooks
+ *   22-Feb-2005  Ben Dooks
  *		  Fixed edge-triggering on ADC IRQ
+ *
+ *   28-Jun-2005  Ben Dooks
+ *		  Mark IRQ_LCD valid
 */
 
 #include <linux/init.h>
@@ -366,7 +369,6 @@
 #define INTMSK_UART1	 (1UL << (IRQ_UART1 - IRQ_EINT0))
 #define INTMSK_UART2	 (1UL << (IRQ_UART2 - IRQ_EINT0))
 #define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
-#define INTMSK_LCD	 (1UL << (IRQ_LCD - IRQ_EINT0))
 
 static inline void
 s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit,
@@ -716,7 +718,6 @@
 		case IRQ_UART0:
 		case IRQ_UART1:
 		case IRQ_UART2:
-		case IRQ_LCD:
 		case IRQ_ADCPARENT:
 			set_irq_chip(irqno, &s3c_irq_level_chip);
 			set_irq_handler(irqno, do_level_IRQ);
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index f3e9700..ccb6bce 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -27,6 +27,7 @@
  *     10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
  *     14-Mar-2006 BJD  Updated for __iomem changes
  *     22-Jun-2006 BJD  Added DM9000 platform information
+ *     28-Jun-2006 BJD  Moved pm functionality out to common code
 */
 
 #include <linux/kernel.h>
@@ -67,7 +68,6 @@
 #include "devs.h"
 #include "cpu.h"
 #include "usb-simtec.h"
-#include "pm.h"
 
 #define COPYRIGHT ", (c) 2004-2005 Simtec Electronics"
 
@@ -405,44 +405,14 @@
 	usb_simtec_init();
 }
 
-void __init bast_init_irq(void)
-{
-	s3c24xx_init_irq();
-}
-
-#ifdef CONFIG_PM
-
-/* bast_init_machine
- *
- * enable the power management functions for the EB2410ITX
-*/
-
-static __init void bast_init_machine(void)
-{
-	unsigned long gstatus4;
-
-	printk(KERN_INFO "BAST Power Manangement" COPYRIGHT "\n");
-
-	gstatus4  = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30;
-	gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28;
-	gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK);
-
-	__raw_writel(gstatus4, S3C2410_GSTATUS4);
-
-	s3c2410_pm_init();
-}
-
-#else
-#define bast_init_machine NULL
-#endif
-
 
 MACHINE_START(BAST, "Simtec-BAST")
-     MAINTAINER("Ben Dooks <ben@simtec.co.uk>")
-     BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
-     BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
-     MAPIO(bast_map_io)
-     INITIRQ(bast_init_irq)
-	.init_machine	= bast_init_machine,
+	/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
+	.phys_ram	= S3C2410_SDRAM_PA,
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
+	.map_io		= bast_map_io,
+	.init_irq	= s3c24xx_init_irq,
 	.timer		= &s3c24xx_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index 2924afc..ea4fb1a 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -117,10 +117,12 @@
 }
 
 MACHINE_START(H1940, "IPAQ-H1940")
-     MAINTAINER("Ben Dooks <ben@fluff.org>")
-     BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
-     BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
-     MAPIO(h1940_map_io)
-     INITIRQ(h1940_init_irq)
+	/* Maintainer: Ben Dooks <ben@fluff.org> */
+	.phys_ram	= S3C2410_SDRAM_PA,
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
+	.map_io		= h1940_map_io,
+	.init_irq	= h1940_init_irq,
 	.timer		= &s3c24xx_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
index bd15998..79044d9 100644
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -137,10 +137,11 @@
 }
 
 MACHINE_START(N30, "Acer-N30")
-     MAINTAINER("Christer Weinigel <christer@weinigel.se>, Ben Dooks <ben-linux@fluff.org>")
-     BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
-     BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
-
+	/* Maintainer: Christer Weinigel <christer@weinigel.se>, Ben Dooks <ben-linux@fluff.org> */
+	.phys_ram	= S3C2410_SDRAM_PA,
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.timer		= &s3c24xx_timer,
 	.init_machine	= n30_init,
 	.init_irq	= n30_init_irq,
diff --git a/arch/arm/mach-s3c2410/mach-nexcoder.c b/arch/arm/mach-s3c2410/mach-nexcoder.c
index 70487bf..d24c242 100644
--- a/arch/arm/mach-s3c2410/mach-nexcoder.c
+++ b/arch/arm/mach-s3c2410/mach-nexcoder.c
@@ -147,9 +147,11 @@
 
 
 MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440")
-     MAINTAINER("Guillaume GOURAT <guillaume.gourat@nexvision.tv>")
-     BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
-     BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
+	/* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
+	.phys_ram	= S3C2410_SDRAM_PA,
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= nexcoder_map_io,
 	.init_irq	= s3c24xx_init_irq,
 	.timer		= &s3c24xx_timer,
diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c
index 67d8ce8..d901ed4 100644
--- a/arch/arm/mach-s3c2410/mach-otom.c
+++ b/arch/arm/mach-s3c2410/mach-otom.c
@@ -115,9 +115,11 @@
 
 
 MACHINE_START(OTOM, "Nex Vision - Otom 1.1")
-     MAINTAINER("Guillaume GOURAT <guillaume.gourat@nexvision.tv>")
-     BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
-     BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
+	/* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
+	.phys_ram	= S3C2410_SDRAM_PA,
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= otom11_map_io,
 	.init_irq	= s3c24xx_init_irq,
 	.timer		= &s3c24xx_timer,
diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c
index f8d3a97..a73d61c 100644
--- a/arch/arm/mach-s3c2410/mach-rx3715.c
+++ b/arch/arm/mach-s3c2410/mach-rx3715.c
@@ -131,11 +131,13 @@
 #endif
 
 MACHINE_START(RX3715, "IPAQ-RX3715")
-     MAINTAINER("Ben Dooks <ben@fluff.org>")
-     BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
-     BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
-     MAPIO(rx3715_map_io)
-     INITIRQ(rx3715_init_irq)
-     INIT_MACHINE(rx3715_init_machine)
+	/* Maintainer: Ben Dooks <ben@fluff.org> */
+	.phys_ram	= S3C2410_SDRAM_PA,
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
+	.map_io		= rx3715_map_io,
+	.init_irq	= rx3715_init_irq,
+	.init_machine	= rx3715_init_machine,
 	.timer		= &s3c24xx_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
index c1a4a14..67e903a 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -112,11 +112,13 @@
 
 MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
 				    * to SMDK2410 */
-     MAINTAINER("Jonas Dietsche")
-     BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
-     BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
-     MAPIO(smdk2410_map_io)
-     INITIRQ(smdk2410_init_irq)
+	/* Maintainer: Jonas Dietsche */
+	.phys_ram	= S3C2410_SDRAM_PA,
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
+	.map_io		= smdk2410_map_io,
+	.init_irq	= smdk2410_init_irq,
 	.timer		= &s3c24xx_timer,
 MACHINE_END
 
diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c
index 7857176..3575221 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2440.c
@@ -124,9 +124,11 @@
 }
 
 MACHINE_START(S3C2440, "SMDK2440")
-	MAINTAINER("Ben Dooks <ben@fluff.org>")
-	BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
-	BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
+	/* Maintainer: Ben Dooks <ben@fluff.org> */
+	.phys_ram	= S3C2410_SDRAM_PA,
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 
 	.init_irq	= s3c24xx_init_irq,
 	.map_io		= smdk2440_map_io,
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 76be074..924e846 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -371,16 +371,14 @@
 	usb_simtec_init();
 }
 
-void __init vr1000_init_irq(void)
-{
-	s3c24xx_init_irq();
-}
 
 MACHINE_START(VR1000, "Thorcom-VR1000")
-     MAINTAINER("Ben Dooks <ben@simtec.co.uk>")
-     BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
-     BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
-     MAPIO(vr1000_map_io)
-     INITIRQ(vr1000_init_irq)
+	/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
+	.phys_ram	= S3C2410_SDRAM_PA,
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
+	.map_io		= vr1000_map_io,
+	.init_irq	= s3c24xx_init_irq,
 	.timer		= &s3c24xx_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s3c2410/pm-simtec.c b/arch/arm/mach-s3c2410/pm-simtec.c
new file mode 100644
index 0000000..2cb7988
--- /dev/null
+++ b/arch/arm/mach-s3c2410/pm-simtec.c
@@ -0,0 +1,65 @@
+/* linux/arch/arm/mach-s3c2410/pm-simtec.c
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * Power Management helpers for Simtec S3C24XX implementations
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#include <asm/arch/map.h>
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-mem.h>
+
+#include <asm/mach-types.h>
+
+#include "pm.h"
+
+#define COPYRIGHT ", (c) 2005 Simtec Electronics"
+
+/* pm_simtec_init
+ *
+ * enable the power management functions
+*/
+
+static __init int pm_simtec_init(void)
+{
+	unsigned long gstatus4;
+
+	/* check which machine we are running on */
+
+	if (!machine_is_bast() && !machine_is_vr1000())
+		return 0;
+
+	printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n");
+
+	gstatus4  = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30;
+	gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28;
+	gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK);
+
+	__raw_writel(gstatus4, S3C2410_GSTATUS4);
+
+	return s3c2410_pm_init();
+}
+
+arch_initcall(pm_simtec_init);
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index bedf88f..4d4d303 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -431,11 +431,13 @@
 
 
 MACHINE_START(ASSABET, "Intel-Assabet")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	BOOT_PARAMS(0xc0000100)
-	FIXUP(fixup_assabet)
-	MAPIO(assabet_map_io)
-	INITIRQ(sa1100_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.fixup		= fixup_assabet,
+	.map_io		= assabet_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 	.init_machine	= assabet_init,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
index 6a60b49..b6169cb 100644
--- a/arch/arm/mach-sa1100/badge4.c
+++ b/arch/arm/mach-sa1100/badge4.c
@@ -285,9 +285,11 @@
 }
 
 MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(badge4_map_io)
-	INITIRQ(sa1100_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= badge4_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index f8edde5..0aa918e 100644
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -123,10 +123,12 @@
 }
 
 MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube")
-	MAINTAINER("support@intrinsyc.com")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	MAPIO(cerf_map_io)
-	INITIRQ(cerf_init_irq)
+	/* Maintainer: support@intrinsyc.com */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.map_io		= cerf_map_io,
+	.init_irq	= cerf_init_irq,
 	.timer		= &sa1100_timer,
 	.init_machine	= cerf_init,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 9928789..8cb6911 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -184,9 +184,11 @@
 }
 
 MACHINE_START(COLLIE, "Sharp-Collie")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	MAPIO(collie_map_io)
-	INITIRQ(sa1100_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.map_io		= collie_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 	.init_machine	= collie_init,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c
index 8d2a89a..04c94ab 100644
--- a/arch/arm/mach-sa1100/cpu-sa1110.c
+++ b/arch/arm/mach-sa1100/cpu-sa1110.c
@@ -271,8 +271,7 @@
 	 */
 	sdram_set_refresh(2);
 	if (!irqs_disabled()) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(20 * HZ / 1000);
+		msleep(20);
 	} else {
 		mdelay(20);
 	}
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index 65dbe99..e7aa2681 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -380,10 +380,12 @@
 }
 
 MACHINE_START(H3100, "Compaq iPAQ H3100")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(h3100_map_io)
-	INITIRQ(sa1100_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= h3100_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 	.init_machine	= h3xxx_mach_init,
 MACHINE_END
@@ -496,10 +498,12 @@
 }
 
 MACHINE_START(H3600, "Compaq iPAQ H3600")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(h3600_map_io)
-	INITIRQ(sa1100_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= h3600_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 	.init_machine	= h3xxx_mach_init,
 MACHINE_END
@@ -881,10 +885,12 @@
 }
 
 MACHINE_START(H3800, "Compaq iPAQ H3800")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(h3800_map_io)
-	INITIRQ(h3800_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= h3800_map_io,
+	.init_irq	= h3800_init_irq,
 	.timer		= &sa1100_timer,
 	.init_machine	= h3xxx_mach_init,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
index 5708417..502d65c 100644
--- a/arch/arm/mach-sa1100/hackkit.c
+++ b/arch/arm/mach-sa1100/hackkit.c
@@ -191,10 +191,12 @@
  */
 
 MACHINE_START(HACKKIT, "HackKit Cpu Board")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(hackkit_map_io)
-	INITIRQ(sa1100_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= hackkit_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 	.init_machine	= hackkit_init,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index 6be7829..eee3cbc 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -97,9 +97,11 @@
 }
 
 MACHINE_START(JORNADA720, "HP Jornada 720")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(jornada720_map_io)
-	INITIRQ(sa1100_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= jornada720_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c
index 51c08cc..870b488 100644
--- a/arch/arm/mach-sa1100/lart.c
+++ b/arch/arm/mach-sa1100/lart.c
@@ -41,9 +41,11 @@
 }
 
 MACHINE_START(LART, "LART")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(lart_map_io)
-	INITIRQ(sa1100_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= lart_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c
index 5606bd7..e17b58f 100644
--- a/arch/arm/mach-sa1100/pleb.c
+++ b/arch/arm/mach-sa1100/pleb.c
@@ -146,9 +146,11 @@
 }
 
 MACHINE_START(PLEB, "PLEB")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	MAPIO(pleb_map_io)
-	INITIRQ(sa1100_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.map_io		= pleb_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 	.init_machine   = pleb_init,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c
index edddd55..43a0035 100644
--- a/arch/arm/mach-sa1100/shannon.c
+++ b/arch/arm/mach-sa1100/shannon.c
@@ -76,10 +76,12 @@
 }
 
 MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(shannon_map_io)
-	INITIRQ(sa1100_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= shannon_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 	.init_machine	= shannon_init,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index 8d113d6..7797858 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -215,10 +215,12 @@
 
 
 MACHINE_START(SIMPAD, "Simpad")
-	MAINTAINER("Holger Freyther")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-        BOOT_PARAMS(0xc0000100)
-	MAPIO(simpad_map_io)
-	INITIRQ(sa1100_init_irq)
+	/* Maintainer: Holger Freyther */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= simpad_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 MACHINE_END
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
index aa0e2f6..7264458 100644
--- a/arch/arm/mach-shark/core.c
+++ b/arch/arm/mach-shark/core.c
@@ -105,10 +105,12 @@
 };
 
 MACHINE_START(SHARK, "Shark")
-	MAINTAINER("Alexander Schulz")
-	BOOT_MEM(0x08000000, 0x40000000, 0xe0000000)
-	BOOT_PARAMS(0x08003000)
-	MAPIO(shark_map_io)
-	INITIRQ(shark_init_irq)
+	/* Maintainer: Alexander Schulz */
+	.phys_ram	= 0x08000000,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= ((0xe0000000) >> 18) & 0xfffc,
+	.boot_params	= 0x08003000,
+	.map_io		= shark_map_io,
+	.init_irq	= shark_init_irq,
 	.timer		= &shark_timer,
 MACHINE_END
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 9d1f225..f01c0f8 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -33,6 +33,7 @@
 #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>
@@ -788,38 +789,25 @@
  */
 #define TIMER_INTERVAL	(TICKS_PER_uSEC * mSEC_10)
 #if TIMER_INTERVAL >= 0x100000
-#define TIMER_RELOAD	(TIMER_INTERVAL >> 8)		/* Divide by 256 */
-#define TIMER_CTRL	0x88				/* Enable, Clock / 256 */
+#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_CTRL	0x84				/* Enable, Clock / 16 */
+#define TIMER_DIVISOR	(TIMER_CTRL_DIV16)
 #define TICKS2USECS(x)	(16 * (x) / TICKS_PER_uSEC)
 #else
 #define TIMER_RELOAD	(TIMER_INTERVAL)
-#define TIMER_CTRL	0x80				/* Enable */
+#define TIMER_DIVISOR	(TIMER_CTRL_DIV1)
 #define TICKS2USECS(x)	((x) / TICKS_PER_uSEC)
 #endif
 
-#define TIMER_CTRL_IE	(1 << 5)	/* Interrupt Enable */
-
-/*
- * What does it look like?
- */
-typedef struct TimerStruct {
-	unsigned long TimerLoad;
-	unsigned long TimerValue;
-	unsigned long TimerControl;
-	unsigned long TimerClear;
-} TimerStruct_t;
-
 /*
  * Returns number of ms since last clock interrupt.  Note that interrupts
  * will have been disabled by do_gettimeoffset()
  */
 static unsigned long versatile_gettimeoffset(void)
 {
-	volatile TimerStruct_t *timer0 = (TimerStruct_t *)TIMER0_VA_BASE;
 	unsigned long ticks1, ticks2, status;
 
 	/*
@@ -828,11 +816,11 @@
 	 * an interrupt.  We get around this by ensuring that the
 	 * counter has not reloaded between our two reads.
 	 */
-	ticks2 = timer0->TimerValue & 0xffff;
+	ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
 	do {
 		ticks1 = ticks2;
 		status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS);
-		ticks2 = timer0->TimerValue & 0xffff;
+		ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
 	} while (ticks2 > ticks1);
 
 	/*
@@ -859,12 +847,10 @@
  */
 static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
-
 	write_seqlock(&xtime_lock);
 
 	// ...clear the interrupt
-	timer0->TimerClear = 1;
+	writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
 
 	timer_tick(regs);
 
@@ -884,31 +870,32 @@
  */
 static void __init versatile_timer_init(void)
 {
-	volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
-	volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
-	volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE;
-	volatile TimerStruct_t *timer3 = (volatile TimerStruct_t *)TIMER3_VA_BASE;
+	u32 val;
 
 	/* 
 	 * set clock frequency: 
 	 *	VERSATILE_REFCLK is 32KHz
 	 *	VERSATILE_TIMCLK is 1MHz
 	 */
-	*(volatile unsigned int *)IO_ADDRESS(VERSATILE_SCTL_BASE) |= 
-	  ((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | 
-	   (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel));
+	val = readl(IO_ADDRESS(VERSATILE_SCTL_BASE));
+	writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) |
+	       (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | 
+	       (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) |
+	       (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
+	       IO_ADDRESS(VERSATILE_SCTL_BASE));
 
 	/*
 	 * Initialise to a known state (all timers off)
 	 */
-	timer0->TimerControl = 0;
-	timer1->TimerControl = 0;
-	timer2->TimerControl = 0;
-	timer3->TimerControl = 0;
+	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);
 
-	timer0->TimerLoad    = TIMER_RELOAD;
-	timer0->TimerValue   = TIMER_RELOAD;
-	timer0->TimerControl = TIMER_CTRL | 0x40 | TIMER_CTRL_IE;  /* periodic + IE */
+	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
diff --git a/arch/arm/mach-versatile/versatile_ab.c b/arch/arm/mach-versatile/versatile_ab.c
index d332084..8b0b3be 100644
--- a/arch/arm/mach-versatile/versatile_ab.c
+++ b/arch/arm/mach-versatile/versatile_ab.c
@@ -35,11 +35,13 @@
 #include "core.h"
 
 MACHINE_START(VERSATILE_AB, "ARM-Versatile AB")
-	MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
-	BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(versatile_map_io)
-	INITIRQ(versatile_init_irq)
+	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+	.phys_ram	= 0x00000000,
+	.phys_io	= 0x101f1000,
+	.io_pg_offst	= ((0xf11f1000) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= versatile_map_io,
+	.init_irq	= versatile_init_irq,
 	.timer		= &versatile_timer,
-	INIT_MACHINE(versatile_init)
+	.init_machine	= versatile_init,
 MACHINE_END
diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c
index 2702099..7c3078c 100644
--- a/arch/arm/mach-versatile/versatile_pb.c
+++ b/arch/arm/mach-versatile/versatile_pb.c
@@ -99,11 +99,13 @@
 arch_initcall(versatile_pb_init);
 
 MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")
-	MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
-	BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(versatile_map_io)
-	INITIRQ(versatile_init_irq)
+	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+	.phys_ram	= 0x00000000,
+	.phys_io	= 0x101f1000,
+	.io_pg_offst	= ((0xf11f1000) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= versatile_map_io,
+	.init_irq	= versatile_init_irq,
 	.timer		= &versatile_timer,
-	INIT_MACHINE(versatile_init)
+	.init_machine	= versatile_init,
 MACHINE_END
diff --git a/arch/arm/mm/blockops.c b/arch/arm/mm/blockops.c
index 806c6ee..4f5ee2d 100644
--- a/arch/arm/mm/blockops.c
+++ b/arch/arm/mm/blockops.c
@@ -25,13 +25,14 @@
 {
 	asm(
 	"add	r1, r0, %0							\n\
+	sub	r1, r1, %1							\n\
 1:	.word	0xec401f0e	@ mcrr	p15, 0, r0, r1, c14, 0	@ blocking	\n\
 	mov	r0, #0								\n\
 	mcr	p15, 0, r0, c7, c5, 0						\n\
 	mcr	p15, 0, r0, c7, c10, 4						\n\
 	mov	pc, lr"
 	:
-	: "I" (PAGE_SIZE));
+	: "I" (PAGE_SIZE), "I" (L1_CACHE_BYTES));
 }
 
 /*
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index e25b4fd..65bfe84 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -372,49 +372,50 @@
 static struct fsr_info {
 	int	(*fn)(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
 	int	sig;
+	int	code;
 	const char *name;
 } fsr_info[] = {
 	/*
 	 * The following are the standard ARMv3 and ARMv4 aborts.  ARMv5
 	 * defines these to be "precise" aborts.
 	 */
-	{ do_bad,		SIGSEGV, "vector exception"		   },
-	{ do_bad,		SIGILL,	 "alignment exception"		   },
-	{ do_bad,		SIGKILL, "terminal exception"		   },
-	{ do_bad,		SIGILL,	 "alignment exception"		   },
-	{ do_bad,		SIGBUS,	 "external abort on linefetch"	   },
-	{ do_translation_fault,	SIGSEGV, "section translation fault"	   },
-	{ do_bad,		SIGBUS,	 "external abort on linefetch"	   },
-	{ do_page_fault,	SIGSEGV, "page translation fault"	   },
-	{ do_bad,		SIGBUS,	 "external abort on non-linefetch" },
-	{ do_bad,		SIGSEGV, "section domain fault"		   },
-	{ do_bad,		SIGBUS,	 "external abort on non-linefetch" },
-	{ do_bad,		SIGSEGV, "page domain fault"		   },
-	{ do_bad,		SIGBUS,	 "external abort on translation"   },
-	{ do_sect_fault,	SIGSEGV, "section permission fault"	   },
-	{ do_bad,		SIGBUS,	 "external abort on translation"   },
-	{ do_page_fault,	SIGSEGV, "page permission fault"	   },
+	{ do_bad,		SIGSEGV, 0,		"vector exception"		   },
+	{ do_bad,		SIGILL,	 BUS_ADRALN,	"alignment exception"		   },
+	{ do_bad,		SIGKILL, 0,		"terminal exception"		   },
+	{ do_bad,		SIGILL,	 BUS_ADRALN,	"alignment exception"		   },
+	{ do_bad,		SIGBUS,	 0,		"external abort on linefetch"	   },
+	{ do_translation_fault,	SIGSEGV, SEGV_MAPERR,	"section translation fault"	   },
+	{ do_bad,		SIGBUS,	 0,		"external abort on linefetch"	   },
+	{ do_page_fault,	SIGSEGV, SEGV_MAPERR,	"page translation fault"	   },
+	{ do_bad,		SIGBUS,	 0,		"external abort on non-linefetch"  },
+	{ do_bad,		SIGSEGV, SEGV_ACCERR,	"section domain fault"		   },
+	{ do_bad,		SIGBUS,	 0,		"external abort on non-linefetch"  },
+	{ do_bad,		SIGSEGV, SEGV_ACCERR,	"page domain fault"		   },
+	{ do_bad,		SIGBUS,	 0,		"external abort on translation"	   },
+	{ do_sect_fault,	SIGSEGV, SEGV_ACCERR,	"section permission fault"	   },
+	{ do_bad,		SIGBUS,	 0,		"external abort on translation"	   },
+	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"page permission fault"		   },
 	/*
 	 * The following are "imprecise" aborts, which are signalled by bit
 	 * 10 of the FSR, and may not be recoverable.  These are only
 	 * supported if the CPU abort handler supports bit 10.
 	 */
-	{ do_bad,		SIGBUS,  "unknown 16"			   },
-	{ do_bad,		SIGBUS,  "unknown 17"			   },
-	{ do_bad,		SIGBUS,  "unknown 18"			   },
-	{ do_bad,		SIGBUS,  "unknown 19"			   },
-	{ do_bad,		SIGBUS,  "lock abort"			   }, /* xscale */
-	{ do_bad,		SIGBUS,  "unknown 21"			   },
-	{ do_bad,		SIGBUS,  "imprecise external abort"	   }, /* xscale */
-	{ do_bad,		SIGBUS,  "unknown 23"			   },
-	{ do_bad,		SIGBUS,  "dcache parity error"		   }, /* xscale */
-	{ do_bad,		SIGBUS,  "unknown 25"			   },
-	{ do_bad,		SIGBUS,  "unknown 26"			   },
-	{ do_bad,		SIGBUS,  "unknown 27"			   },
-	{ do_bad,		SIGBUS,  "unknown 28"			   },
-	{ do_bad,		SIGBUS,  "unknown 29"			   },
-	{ do_bad,		SIGBUS,  "unknown 30"			   },
-	{ do_bad,		SIGBUS,  "unknown 31"			   }
+	{ do_bad,		SIGBUS,  0,		"unknown 16"			   },
+	{ do_bad,		SIGBUS,  0,		"unknown 17"			   },
+	{ do_bad,		SIGBUS,  0,		"unknown 18"			   },
+	{ do_bad,		SIGBUS,  0,		"unknown 19"			   },
+	{ do_bad,		SIGBUS,  0,		"lock abort"			   }, /* xscale */
+	{ do_bad,		SIGBUS,  0,		"unknown 21"			   },
+	{ do_bad,		SIGBUS,  BUS_OBJERR,	"imprecise external abort"	   }, /* xscale */
+	{ do_bad,		SIGBUS,  0,		"unknown 23"			   },
+	{ do_bad,		SIGBUS,  0,		"dcache parity error"		   }, /* xscale */
+	{ do_bad,		SIGBUS,  0,		"unknown 25"			   },
+	{ do_bad,		SIGBUS,  0,		"unknown 26"			   },
+	{ do_bad,		SIGBUS,  0,		"unknown 27"			   },
+	{ do_bad,		SIGBUS,  0,		"unknown 28"			   },
+	{ do_bad,		SIGBUS,  0,		"unknown 29"			   },
+	{ do_bad,		SIGBUS,  0,		"unknown 30"			   },
+	{ do_bad,		SIGBUS,  0,		"unknown 31"			   }
 };
 
 void __init
@@ -435,15 +436,19 @@
 do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
 	const struct fsr_info *inf = fsr_info + (fsr & 15) + ((fsr & (1 << 10)) >> 6);
+	struct siginfo info;
 
 	if (!inf->fn(addr, fsr, regs))
 		return;
 
 	printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n",
 		inf->name, fsr, addr);
-	force_sig(inf->sig, current);
-	show_pte(current->mm, addr);
-	die_if_kernel("Oops", regs, 0);
+
+	info.si_signo = inf->sig;
+	info.si_errno = 0;
+	info.si_code  = inf->code;
+	info.si_addr  = (void __user *)addr;
+	notify_die("", regs, &info, fsr, 0);
 }
 
 asmlinkage void
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 6dcb23d..edffa47 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -437,7 +437,7 @@
 	memtable_init(mi);
 	if (mdesc->map_io)
 		mdesc->map_io();
-	flush_tlb_all();
+	local_flush_tlb_all();
 
 	/*
 	 * initialise the zones within each node
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index 052ab44..c3bd503 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -682,7 +682,7 @@
 	}
 
 	flush_cache_all();
-	flush_tlb_all();
+	local_flush_tlb_all();
 
 	top_pmd = pmd_off_k(0xffff0000);
 }
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index 1f32523..5c0ae52 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -445,14 +445,14 @@
 	/*
 	 *  R
 	 * .RVI ZFRS BLDP WCAM
-	 * .0.1 1001 ..11 0101	/* FIXME: why no V bit? */
+	 * .011 1001 ..11 0101
 	 */
 	.type	arm1020_cr1_clear, #object
 	.type	arm1020_cr1_set, #object
 arm1020_cr1_clear:
 	.word	0x593f
 arm1020_cr1_set:
-	.word	0x1935
+	.word	0x3935
 
 	__INITDATA
 
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index 142a2c2..d69389c 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -427,14 +427,14 @@
 	/*
 	 *  R
 	 * .RVI ZFRS BLDP WCAM
-	 * .0.1 1001 ..11 0101	/* FIXME: why no V bit? */
+	 * .011 1001 ..11 0101
 	 */
 	.type	arm1020e_cr1_clear, #object
 	.type	arm1020e_cr1_set, #object
 arm1020e_cr1_clear:
 	.word	0x5f3f
 arm1020e_cr1_set:
-	.word	0x1935
+	.word	0x3935
 
 	__INITDATA
 
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index e3d8510..352db98 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -200,7 +200,7 @@
 	mcr	p15, 0, r4, c2, c0, 1		@ load TTB1
 #ifdef CONFIG_VFP
 	mrc	p15, 0, r0, c1, c0, 2
-	orr	r0, r0, #(3 << 20)
+	orr	r0, r0, #(0xf << 20)
 	mcr	p15, 0, r0, c1, c0, 2		@ Enable full access to VFP
 #endif
 	mrc	p15, 0, r0, c1, c0, 0		@ read control register
diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile
index ba1a6e9..8ffb523 100644
--- a/arch/arm/oprofile/Makefile
+++ b/arch/arm/oprofile/Makefile
@@ -6,6 +6,6 @@
 		oprofilefs.o oprofile_stats.o \
 		timer_int.o )
 
-oprofile-y				:= $(DRIVER_OBJS) init.o
+oprofile-y				:= $(DRIVER_OBJS) init.o backtrace.o
 oprofile-$(CONFIG_CPU_XSCALE)		+= common.o op_model_xscale.o
 
diff --git a/arch/arm/oprofile/backtrace.c b/arch/arm/oprofile/backtrace.c
new file mode 100644
index 0000000..ec58d3e
--- /dev/null
+++ b/arch/arm/oprofile/backtrace.c
@@ -0,0 +1,144 @@
+/*
+ * Arm specific backtracing code for oprofile
+ *
+ * Copyright 2005 Openedhand Ltd.
+ *
+ * Author: Richard Purdie <rpurdie@openedhand.com>
+ *
+ * Based on i386 oprofile backtrace code by John Levon, David Smith
+ *
+ * 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/oprofile.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/ptrace.h>
+#include <asm/uaccess.h>
+
+
+/*
+ * The registers we're interested in are at the end of the variable
+ * length saved register structure. The fp points at the end of this
+ * structure so the address of this struct is:
+ * (struct frame_tail *)(xxx->fp)-1
+ */
+struct frame_tail {
+	struct frame_tail *fp;
+	unsigned long sp;
+	unsigned long lr;
+} __attribute__((packed));
+
+
+#ifdef CONFIG_FRAME_POINTER
+static struct frame_tail* kernel_backtrace(struct frame_tail *tail)
+{
+	oprofile_add_trace(tail->lr);
+
+	/* frame pointers should strictly progress back up the stack
+	 * (towards higher addresses) */
+	if (tail >= tail->fp)
+		return NULL;
+
+	return tail->fp-1;
+}
+#endif
+
+static struct frame_tail* user_backtrace(struct frame_tail *tail)
+{
+	struct frame_tail buftail;
+
+	/* 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)))
+		return NULL;
+
+	oprofile_add_trace(buftail.lr);
+
+	/* frame pointers should strictly progress back up the stack
+	 * (towards higher addresses) */
+	if (tail >= buftail.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;
+}
+
+/*
+ * |             | /\ Higher addresses
+ * |             |
+ * --------------- stack base (address of current_thread_info)
+ * | thread info |
+ * .             .
+ * |    stack    |
+ * --------------- saved regs->ARM_fp value if valid (frame_tail address)
+ * .             .
+ * --------------- struct pt_regs stored on stack (struct pt_regs *)
+ * |             |
+ * .             .
+ * |             |
+ * --------------- %esp
+ * |             |
+ * |             | \/ Lower addresses
+ *
+ * Thus, &pt_regs <-> stack base restricts the valid(ish) fp values
+ */
+static int valid_kernel_stack(struct frame_tail *tail, struct pt_regs *regs)
+{
+	unsigned long tailaddr = (unsigned long)tail;
+	unsigned long stack = (unsigned long)regs;
+	unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE;
+
+	return (tailaddr > stack) && (tailaddr < stack_base);
+}
+
+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;
+
+	if (!user_mode(regs)) {
+
+#ifdef CONFIG_FRAME_POINTER
+		while (depth-- && tail && valid_kernel_stack(tail, regs)) {
+			tail = kernel_backtrace(tail);
+		}
+#endif
+		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;
+		tail = user_backtrace(tail);
+	}
+}
+
diff --git a/arch/arm/oprofile/init.c b/arch/arm/oprofile/init.c
index cce3d30..d315a3a 100644
--- a/arch/arm/oprofile/init.c
+++ b/arch/arm/oprofile/init.c
@@ -20,6 +20,8 @@
 	ret = pmu_init(ops, &op_xscale_spec);
 #endif
 
+	ops->backtrace = arm_backtrace;
+
 	return ret;
 }
 
diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h
index 2d4caf4..2148d07 100644
--- a/arch/arm/oprofile/op_arm_model.h
+++ b/arch/arm/oprofile/op_arm_model.h
@@ -24,6 +24,8 @@
 extern struct op_arm_model_spec op_xscale_spec;
 #endif
 
+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);
 #endif /* OP_ARM_MODEL_H */
diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h
index 55a02bc..4b97950 100644
--- a/arch/arm/vfp/vfp.h
+++ b/arch/arm/vfp/vfp.h
@@ -117,7 +117,13 @@
 	if (nh >= m)
 		return ~0ULL;
 	mh = m >> 32;
-	z = (mh << 32 <= nh) ? 0xffffffff00000000ULL : (nh / mh) << 32;
+	if (mh << 32 <= nh) {
+		z = 0xffffffff00000000ULL;
+	} else {
+		z = nh;
+		do_div(z, mh);
+		z <<= 32;
+	}
 	mul64to128(&termh, &terml, m, z);
 	sub128(&remh, &reml, nh, nl, termh, terml);
 	ml = m << 32;
@@ -126,7 +132,12 @@
 		add128(&remh, &reml, remh, reml, mh, ml);
 	}
 	remh = (remh << 32) | (reml >> 32);
-	z |= (mh << 32 <= remh) ? 0xffffffff : remh / mh;
+	if (mh << 32 <= remh) {
+		z |= 0xffffffff;
+	} else {
+		do_div(remh, mh);
+		z |= remh;
+	}
 	return z;
 }
 
diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c
index fa3053e..b801cd6 100644
--- a/arch/arm/vfp/vfpdouble.c
+++ b/arch/arm/vfp/vfpdouble.c
@@ -32,6 +32,8 @@
  */
 #include <linux/kernel.h>
 #include <linux/bitops.h>
+
+#include <asm/div64.h>
 #include <asm/ptrace.h>
 #include <asm/vfp.h>
 
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 3aeedd2..22f3da4 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -89,7 +89,7 @@
 	current->thread.error_code = 0;
 	current->thread.trap_no = 6;
 
-	force_sig_info(SIGFPE, &info, current);
+	send_sig_info(SIGFPE, &info, current);
 }
 
 static void vfp_panic(char *reason)
diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c
index 6849fe3..14dd696 100644
--- a/arch/arm/vfp/vfpsingle.c
+++ b/arch/arm/vfp/vfpsingle.c
@@ -32,6 +32,8 @@
  */
 #include <linux/kernel.h>
 #include <linux/bitops.h>
+
+#include <asm/div64.h>
 #include <asm/ptrace.h>
 #include <asm/vfp.h>
 
@@ -303,7 +305,11 @@
 		if (z <= a)
 			return (s32)a >> 1;
 	}
-	return (u32)(((u64)a << 31) / z) + (z >> 1);
+	{
+		u64 v = (u64)a << 31;
+		do_div(v, z);
+		return v + (z >> 1);
+	}
 }
 
 static u32 vfp_single_fsqrt(int sd, int unused, s32 m, u32 fpscr)
@@ -1107,7 +1113,11 @@
 		vsn.significand >>= 1;
 		vsd.exponent++;
 	}
-	vsd.significand = ((u64)vsn.significand << 32) / vsm.significand;
+	{
+		u64 significand = (u64)vsn.significand << 32;
+		do_div(significand, vsm.significand);
+		vsd.significand = significand;
+	}
 	if ((vsd.significand & 0x3f) == 0)
 		vsd.significand |= ((u64)vsm.significand * vsd.significand != (u64)vsn.significand << 32);
 
diff --git a/arch/i386/boot/tools/build.c b/arch/i386/boot/tools/build.c
index 4a17956..6835f6d 100644
--- a/arch/i386/boot/tools/build.c
+++ b/arch/i386/boot/tools/build.c
@@ -70,7 +70,8 @@
 
 int main(int argc, char ** argv)
 {
-	unsigned int i, c, sz, setup_sectors;
+	unsigned int i, sz, setup_sectors;
+	int c;
 	u32 sys_size;
 	byte major_root, minor_root;
 	struct stat sb;
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index 9f63ae0..b7808a8 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -159,9 +159,15 @@
 #endif
 
 #ifdef CONFIG_PCI_MMCONFIG
-static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
+/* The physical address of the MMCONFIG aperture.  Set from ACPI tables. */
+struct acpi_table_mcfg_config *pci_mmcfg_config;
+int pci_mmcfg_config_num;
+
+int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
 {
 	struct acpi_table_mcfg *mcfg;
+	unsigned long i;
+	int config_size;
 
 	if (!phys_addr || !size)
 		return -EINVAL;
@@ -172,18 +178,38 @@
 		return -ENODEV;
 	}
 
-	if (mcfg->base_reserved) {
-		printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n");
+	/* how many config structures do we have */
+	pci_mmcfg_config_num = 0;
+	i = size - sizeof(struct acpi_table_mcfg);
+	while (i >= sizeof(struct acpi_table_mcfg_config)) {
+		++pci_mmcfg_config_num;
+		i -= sizeof(struct acpi_table_mcfg_config);
+	};
+	if (pci_mmcfg_config_num == 0) {
+		printk(KERN_ERR PREFIX "MMCONFIG has no entries\n");
 		return -ENODEV;
 	}
 
-	pci_mmcfg_base_addr = mcfg->base_address;
+	config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config);
+	pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL);
+	if (!pci_mmcfg_config) {
+		printk(KERN_WARNING PREFIX
+		       "No memory for MCFG config tables\n");
+		return -ENOMEM;
+	}
+
+	memcpy(pci_mmcfg_config, &mcfg->config, config_size);
+	for (i = 0; i < pci_mmcfg_config_num; ++i) {
+		if (mcfg->config[i].base_reserved) {
+			printk(KERN_ERR PREFIX
+			       "MMCONFIG not in low 4GB of memory\n");
+			return -ENODEV;
+		}
+	}
 
 	return 0;
 }
-#else
-#define	acpi_parse_mcfg NULL
-#endif /* !CONFIG_PCI_MMCONFIG */
+#endif /* CONFIG_PCI_MMCONFIG */
 
 #ifdef CONFIG_X86_LOCAL_APIC
 static int __init
@@ -507,6 +533,22 @@
 EXPORT_SYMBOL(acpi_unmap_lsapic);
 #endif /* CONFIG_ACPI_HOTPLUG_CPU */
 
+int
+acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
+{
+	/* TBD */
+	return -EINVAL;
+}
+EXPORT_SYMBOL(acpi_register_ioapic);
+
+int
+acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base)
+{
+	/* TBD */
+	return -EINVAL;
+}
+EXPORT_SYMBOL(acpi_unregister_ioapic);
+
 static unsigned long __init
 acpi_scan_rsdp (
 	unsigned long		start,
@@ -1123,7 +1165,6 @@
 	acpi_process_madt();
 
 	acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
-	acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
 
 	return 0;
 }
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 93df90b..bd1dbf3 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -35,6 +35,7 @@
 #include <asm/desc.h>
 #include <asm/arch_hooks.h>
 #include <asm/hpet.h>
+#include <asm/i8253.h>
 
 #include <mach_apic.h>
 
@@ -879,7 +880,6 @@
  */
 static unsigned int __devinit get_8254_timer_count(void)
 {
-	extern spinlock_t i8253_lock;
 	unsigned long flags;
 
 	unsigned int count;
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index d48ce92..064211d 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -228,10 +228,10 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/desc.h>
+#include <asm/i8253.h>
 
 #include "io_ports.h"
 
-extern spinlock_t i8253_lock;
 extern unsigned long get_cmos_time(void);
 extern void machine_real_restart(unsigned char *, int);
 
@@ -1168,8 +1168,7 @@
 static void reinit_timer(void)
 {
 #ifdef INIT_TIMER_AFTER_SUSPEND
-	unsigned long	flags;
-	extern spinlock_t i8253_lock;
+	unsigned long flags;
 
 	spin_lock_irqsave(&i8253_lock, flags);
 	/* set the clock to 100 Hz */
diff --git a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
index 1a49adb..e86ea48 100644
--- a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
+++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
@@ -190,7 +190,7 @@
 
 	/* detect which companion chip is used */
 	while ((gx_pci = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, gx_pci)) != NULL) {
-		if ((pci_match_device (gx_chipset_tbl, gx_pci)) != NULL) {
+		if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL) {
 			return gx_pci;
 		}
 	}
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 35eb8e2..6578f40 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -37,6 +37,7 @@
 #include <asm/smp.h>
 #include <asm/desc.h>
 #include <asm/timer.h>
+#include <asm/i8259.h>
 
 #include <mach_apic.h>
 
@@ -1566,7 +1567,6 @@
 
 void /*__init*/ print_PIC(void)
 {
-	extern spinlock_t i8259A_lock;
 	unsigned int v;
 	unsigned long flags;
 
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index fc8b175..a6d8c45 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -537,7 +537,7 @@
 	.pre_handler = trampoline_probe_handler
 };
 
-int __init arch_init(void)
+int __init arch_init_kprobes(void)
 {
 	return register_kprobe(&trampoline_p);
 }
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index e68d9fd..2854c35 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -68,7 +68,8 @@
 
 #include "io_ports.h"
 
-extern spinlock_t i8259A_lock;
+#include <asm/i8259.h>
+
 int pit_latch_buggy;              /* extern */
 
 #include "do_timer.h"
@@ -85,6 +86,8 @@
 DEFINE_SPINLOCK(rtc_lock);
 EXPORT_SYMBOL(rtc_lock);
 
+#include <asm/i8253.h>
+
 DEFINE_SPINLOCK(i8253_lock);
 EXPORT_SYMBOL(i8253_lock);
 
diff --git a/arch/i386/kernel/timers/timer_cyclone.c b/arch/i386/kernel/timers/timer_cyclone.c
index f6f1206..13892a6 100644
--- a/arch/i386/kernel/timers/timer_cyclone.c
+++ b/arch/i386/kernel/timers/timer_cyclone.c
@@ -17,9 +17,9 @@
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/fixmap.h>
-#include "io_ports.h"
+#include <asm/i8253.h>
 
-extern spinlock_t i8253_lock;
+#include "io_ports.h"
 
 /* Number of usecs that the last interrupt was delayed */
 static int delay_at_last_interrupt;
diff --git a/arch/i386/kernel/timers/timer_pit.c b/arch/i386/kernel/timers/timer_pit.c
index 967d545..06de036a 100644
--- a/arch/i386/kernel/timers/timer_pit.c
+++ b/arch/i386/kernel/timers/timer_pit.c
@@ -15,9 +15,8 @@
 #include <asm/smp.h>
 #include <asm/io.h>
 #include <asm/arch_hooks.h>
+#include <asm/i8253.h>
 
-extern spinlock_t i8259A_lock;
-extern spinlock_t i8253_lock;
 #include "do_timer.h"
 #include "io_ports.h"
 
@@ -166,7 +165,6 @@
 
 void setup_pit_timer(void)
 {
-	extern spinlock_t i8253_lock;
 	unsigned long flags;
 
 	spin_lock_irqsave(&i8253_lock, flags);
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
index f46e625..8f4e4d5 100644
--- a/arch/i386/kernel/timers/timer_tsc.c
+++ b/arch/i386/kernel/timers/timer_tsc.c
@@ -24,6 +24,7 @@
 #include "mach_timer.h"
 
 #include <asm/hpet.h>
+#include <asm/i8253.h>
 
 #ifdef CONFIG_HPET_TIMER
 static unsigned long hpet_usec_quotient;
@@ -35,8 +36,6 @@
 
 int tsc_disable __devinitdata = 0;
 
-extern spinlock_t i8253_lock;
-
 static int use_tsc;
 /* Number of usecs that the last interrupt was delayed */
 static int delay_at_last_interrupt;
diff --git a/arch/i386/mach-voyager/voyager_basic.c b/arch/i386/mach-voyager/voyager_basic.c
index 602aea2..3e439ce 100644
--- a/arch/i386/mach-voyager/voyager_basic.c
+++ b/arch/i386/mach-voyager/voyager_basic.c
@@ -30,6 +30,7 @@
 #include <linux/irq.h>
 #include <asm/tlbflush.h>
 #include <asm/arch_hooks.h>
+#include <asm/i8253.h>
 
 /*
  * Power off function, if any
@@ -182,7 +183,6 @@
 		 * and swiftly introduce it to something sharp and
 		 * pointy.  */
 		__u16 val;
-		extern spinlock_t i8253_lock;
 
 		spin_lock(&i8253_lock);
 		
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c
index 720975e..70bcd53 100644
--- a/arch/i386/pci/common.c
+++ b/arch/i386/pci/common.c
@@ -25,7 +25,8 @@
 
 int pci_routeirq;
 int pcibios_last_bus = -1;
-struct pci_bus *pci_root_bus = NULL;
+unsigned long pirq_table_addr;
+struct pci_bus *pci_root_bus;
 struct pci_raw_ops *raw_pci_ops;
 
 static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
@@ -133,7 +134,7 @@
 
 	printk("PCI: Probing PCI hardware (bus %02x)\n", busnum);
 
-	return pci_scan_bus(busnum, &pci_root_ops, NULL);
+	return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, NULL);
 }
 
 extern u8 pci_cache_line_size;
@@ -164,6 +165,7 @@
 	if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
 		pcibios_sort();
 #endif
+	pci_assign_unassigned_resources();
 	return 0;
 }
 
@@ -188,6 +190,9 @@
 	} else if (!strcmp(str, "biosirq")) {
 		pci_probe |= PCI_BIOS_IRQ_SCAN;
 		return NULL;
+	} else if (!strncmp(str, "pirqaddr=", 9)) {
+		pirq_table_addr = simple_strtoul(str+9, NULL, 0);
+		return NULL;
 	}
 #endif
 #ifdef CONFIG_PCI_DIRECT
diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c
index c205ea7..93a364c 100644
--- a/arch/i386/pci/i386.c
+++ b/arch/i386/pci/i386.c
@@ -106,11 +106,16 @@
 		if ((dev = bus->self)) {
 			for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
 				r = &dev->resource[idx];
-				if (!r->start)
+				if (!r->flags)
 					continue;
 				pr = pci_find_parent_resource(dev, r);
-				if (!pr || request_resource(pr, r) < 0)
+				if (!r->start || !pr || request_resource(pr, r) < 0) {
 					printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev));
+					/* Something is wrong with the region.
+					   Invalidate the resource to prevent child
+					   resource allocations in this range. */
+					r->flags = 0;
+				}
 			}
 		}
 		pcibios_allocate_bus_resources(&bus->children);
@@ -227,7 +232,7 @@
 
 	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/i386/pci/irq.c b/arch/i386/pci/irq.c
index 83458f8..78ca1ec 100644
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -58,6 +58,35 @@
 int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
 
 /*
+ *  Check passed address for the PCI IRQ Routing Table signature
+ *  and perform checksum verification.
+ */
+
+static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr)
+{
+	struct irq_routing_table *rt;
+	int i;
+	u8 sum;
+
+	rt = (struct irq_routing_table *) addr;
+	if (rt->signature != PIRQ_SIGNATURE ||
+	    rt->version != PIRQ_VERSION ||
+	    rt->size % 16 ||
+	    rt->size < sizeof(struct irq_routing_table))
+		return NULL;
+	sum = 0;
+	for (i=0; i < rt->size; i++)
+		sum += addr[i];
+	if (!sum) {
+		DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+		return rt;
+	}
+	return NULL;
+}
+
+
+
+/*
  *  Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
  */
 
@@ -65,23 +94,17 @@
 {
 	u8 *addr;
 	struct irq_routing_table *rt;
-	int i;
-	u8 sum;
 
-	for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
-		rt = (struct irq_routing_table *) addr;
-		if (rt->signature != PIRQ_SIGNATURE ||
-		    rt->version != PIRQ_VERSION ||
-		    rt->size % 16 ||
-		    rt->size < sizeof(struct irq_routing_table))
-			continue;
-		sum = 0;
-		for(i=0; i<rt->size; i++)
-			sum += addr[i];
-		if (!sum) {
-			DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+	if (pirq_table_addr) {
+		rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr));
+		if (rt)
 			return rt;
-		}
+		printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n");
+	}
+	for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
+		rt = pirq_check_routing_table(addr);
+		if (rt)
+			return rt;
 	}
 	return NULL;
 }
diff --git a/arch/i386/pci/legacy.c b/arch/i386/pci/legacy.c
index 1492e37..149a958 100644
--- a/arch/i386/pci/legacy.c
+++ b/arch/i386/pci/legacy.c
@@ -45,6 +45,8 @@
 
 	printk("PCI: Probing PCI hardware\n");
 	pci_root_bus = pcibios_scan_root(0);
+	if (pci_root_bus)
+		pci_bus_add_devices(pci_root_bus);
 
 	pcibios_fixup_peer_bridges();
 
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c
index 021a50aa..60f0e7a 100644
--- a/arch/i386/pci/mmconfig.c
+++ b/arch/i386/pci/mmconfig.c
@@ -11,11 +11,9 @@
 
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/acpi.h>
 #include "pci.h"
 
-/* The physical address of the MMCONFIG aperture.  Set from ACPI tables. */
-u32 pci_mmcfg_base_addr;
-
 #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG))
 
 /* The base address of the last MMCONFIG device accessed */
@@ -24,10 +22,31 @@
 /*
  * Functions for accessing PCI configuration space with MMCONFIG accesses
  */
-
-static inline void pci_exp_set_dev_base(int bus, int devfn)
+static u32 get_base_addr(unsigned int seg, int bus)
 {
-	u32 dev_base = pci_mmcfg_base_addr | (bus << 20) | (devfn << 12);
+	int cfg_num = -1;
+	struct acpi_table_mcfg_config *cfg;
+
+	while (1) {
+		++cfg_num;
+		if (cfg_num >= pci_mmcfg_config_num) {
+			/* something bad is going on, no cfg table is found. */
+			/* so we fall back to the old way we used to do this */
+			/* and just rely on the first entry to be correct. */
+			return pci_mmcfg_config[0].base_address;
+		}
+		cfg = &pci_mmcfg_config[cfg_num];
+		if (cfg->pci_segment_group_number != seg)
+			continue;
+		if ((cfg->start_bus_number <= bus) &&
+		    (cfg->end_bus_number >= bus))
+			return cfg->base_address;
+	}
+}
+
+static inline void pci_exp_set_dev_base(unsigned int seg, int bus, int devfn)
+{
+	u32 dev_base = get_base_addr(seg, bus) | (bus << 20) | (devfn << 12);
 	if (dev_base != mmcfg_last_accessed_device) {
 		mmcfg_last_accessed_device = dev_base;
 		set_fixmap_nocache(FIX_PCIE_MCFG, dev_base);
@@ -44,7 +63,7 @@
 
 	spin_lock_irqsave(&pci_config_lock, flags);
 
-	pci_exp_set_dev_base(bus, devfn);
+	pci_exp_set_dev_base(seg, bus, devfn);
 
 	switch (len) {
 	case 1:
@@ -73,7 +92,7 @@
 
 	spin_lock_irqsave(&pci_config_lock, flags);
 
-	pci_exp_set_dev_base(bus, devfn);
+	pci_exp_set_dev_base(seg, bus, devfn);
 
 	switch (len) {
 	case 1:
@@ -101,7 +120,11 @@
 {
 	if ((pci_probe & PCI_PROBE_MMCONF) == 0)
 		goto out;
-	if (!pci_mmcfg_base_addr)
+
+	acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
+	if ((pci_mmcfg_config_num == 0) ||
+	    (pci_mmcfg_config == NULL) ||
+	    (pci_mmcfg_config[0].base_address == 0))
 		goto out;
 
 	/* Kludge for now. Don't use mmconfig on AMD systems because
diff --git a/arch/i386/pci/numa.c b/arch/i386/pci/numa.c
index 9e36954..adbe17a 100644
--- a/arch/i386/pci/numa.c
+++ b/arch/i386/pci/numa.c
@@ -115,6 +115,8 @@
 		return 0;
 
 	pci_root_bus = pcibios_scan_root(0);
+	if (pci_root_bus)
+		pci_bus_add_devices(pci_root_bus);
 	if (num_online_nodes() > 1)
 		for_each_online_node(quad) {
 			if (quad == 0)
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h
index a8fc80c..a80f0f5 100644
--- a/arch/i386/pci/pci.h
+++ b/arch/i386/pci/pci.h
@@ -27,6 +27,7 @@
 #define PCI_ASSIGN_ALL_BUSSES	0x4000
 
 extern unsigned int pci_probe;
+extern unsigned long pirq_table_addr;
 
 /* pci-i386.c */
 
diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig
index 487d2e3..c056139 100644
--- a/arch/ia64/configs/sn2_defconfig
+++ b/arch/ia64/configs/sn2_defconfig
@@ -99,7 +99,7 @@
 # Firmware Drivers
 #
 CONFIG_EFI_VARS=y
-# CONFIG_EFI_PCDP is not set
+CONFIG_EFI_PCDP=y
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 
@@ -650,7 +650,7 @@
 #
 # Console display driver support
 #
-# CONFIG_VGA_CONSOLE is not set
+CONFIG_VGA_CONSOLE=y
 CONFIG_DUMMY_CONSOLE=y
 
 #
diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig
index 47f4534..73454ee 100644
--- 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.12-20050621
-# Tue Jun 21 14:03:24 2005
+# Linux kernel version: 2.6.13-rc1-20050629
+# Wed Jun 29 15:28:12 2005
 #
 
 #
@@ -80,18 +80,29 @@
 # 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 is not set
 CONFIG_VIRTUAL_MEM_MAP=y
 CONFIG_HOLES_IN_ZONE=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=4
 CONFIG_HOTPLUG_CPU=y
 # CONFIG_SCHED_SMT is not set
 # CONFIG_PREEMPT is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_COMPAT=y
@@ -257,6 +268,7 @@
 # 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
@@ -395,6 +407,7 @@
 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
@@ -407,6 +420,8 @@
 # CONFIG_INET_TUNNEL is not set
 CONFIG_IP_TCPDIAG=y
 # CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
 # CONFIG_IPV6 is not set
 # CONFIG_NETFILTER is not set
 
@@ -598,9 +613,7 @@
 # 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
@@ -629,7 +642,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
 
 #
@@ -743,6 +755,7 @@
 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
@@ -779,9 +792,11 @@
 # 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_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
@@ -838,7 +853,7 @@
 # CONFIG_USB_TEST is not set
 
 #
-# USB ATM/DSL drivers
+# USB DSL modem support
 #
 
 #
@@ -857,12 +872,17 @@
 # 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
@@ -922,7 +942,6 @@
 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
@@ -953,15 +972,18 @@
 #
 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
@@ -1069,6 +1091,7 @@
 # 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
@@ -1090,7 +1113,7 @@
 # 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/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig
index 21d6f9b..b7755e4 100644
--- 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.10
-# Wed Dec 29 09:05:48 2004
+# Linux kernel version: 2.6.13-rc1-20050629
+# Wed Jun 29 15:31:11 2005
 #
 
 #
@@ -12,6 +12,7 @@
 CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -24,23 +25,26 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=17
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+# CONFIG_CPUSETS is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE 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
@@ -59,12 +63,15 @@
 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 is not set
 CONFIG_IA64_HP_ZX1=y
+# 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
@@ -73,22 +80,36 @@
 # 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 is not set
 CONFIG_VIRTUAL_MEM_MAP=y
+CONFIG_HOLES_IN_ZONE=y
 # 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=16
 # CONFIG_HOTPLUG_CPU is not set
+# CONFIG_SCHED_SMT is not set
 # CONFIG_PREEMPT is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_COMPAT=y
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
+CONFIG_ACPI_DEALLOCATE_IRQ=y
 
 #
 # Firmware Drivers
@@ -120,6 +141,7 @@
 CONFIG_ACPI_POWER=y
 CONFIG_ACPI_PCI=y
 CONFIG_ACPI_SYSTEM=y
+# CONFIG_ACPI_CONTAINER is not set
 
 #
 # Bus options (PCI, PCMCIA)
@@ -129,6 +151,7 @@
 # CONFIG_PCI_MSI is not set
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCI Hotplug Support
@@ -138,7 +161,6 @@
 CONFIG_HOTPLUG_PCI_ACPI=y
 # CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
 # CONFIG_HOTPLUG_PCI_CPCI is not set
-# CONFIG_HOTPLUG_PCI_PCIE is not set
 # CONFIG_HOTPLUG_PCI_SHPC is not set
 
 #
@@ -147,10 +169,6 @@
 # CONFIG_PCCARD is not set
 
 #
-# PC-card bridges
-#
-
-#
 # Device Drivers
 #
 
@@ -184,6 +202,7 @@
 # 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
@@ -203,6 +222,7 @@
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -246,6 +266,7 @@
 # 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
@@ -275,6 +296,7 @@
 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
@@ -288,6 +310,7 @@
 #
 CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -303,13 +326,10 @@
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_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
@@ -319,8 +339,6 @@
 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 is not set
 CONFIG_SCSI_QLOGIC_1280=y
@@ -331,7 +349,7 @@
 # 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_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -344,9 +362,9 @@
 #
 # Fusion MPT device support
 #
-CONFIG_FUSION=y
-CONFIG_FUSION_MAX_SGE=40
-# CONFIG_FUSION_CTL is not set
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -368,12 +386,12 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV 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
@@ -386,6 +404,8 @@
 # CONFIG_INET_TUNNEL is not set
 # CONFIG_IP_TCPDIAG is not set
 # CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
 
 #
 # IP: Virtual Server Configuration
@@ -405,8 +425,6 @@
 CONFIG_IP_NF_ARPTABLES=y
 # CONFIG_IP_NF_ARPFILTER is not set
 # CONFIG_IP_NF_ARP_MANGLE is not set
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
 
 #
 # SCTP Configuration (EXPERIMENTAL)
@@ -483,7 +501,6 @@
 # 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
@@ -505,9 +522,11 @@
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 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)
@@ -565,18 +584,6 @@
 # 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_RAW is not set
-
-#
 # Input Device Drivers
 #
 # CONFIG_INPUT_KEYBOARD is not set
@@ -586,6 +593,16 @@
 # 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_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -603,7 +620,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
 
 #
@@ -611,6 +627,7 @@
 #
 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
@@ -644,6 +661,12 @@
 # CONFIG_DRM_SIS 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
@@ -668,6 +691,7 @@
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
@@ -691,10 +715,14 @@
 # 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
@@ -705,21 +733,29 @@
 # 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_SMSC47B397 is not set
+# CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
 
 #
 # Other 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
@@ -746,6 +782,7 @@
 #
 # Video Adapters
 #
+# CONFIG_TUNER_MULTI_I2C is not set
 # CONFIG_VIDEO_BT848 is not set
 # CONFIG_VIDEO_CPIA is not set
 # CONFIG_VIDEO_SAA5246A is not set
@@ -778,6 +815,11 @@
 # 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 is not set
 # CONFIG_FB_CIRRUS is not set
@@ -785,6 +827,7 @@
 # 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
@@ -801,6 +844,7 @@
 # CONFIG_FB_VOODOO1 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
 
 #
@@ -820,6 +864,7 @@
 # CONFIG_LOGO_LINUX_MONO is not set
 # CONFIG_LOGO_LINUX_VGA16 is not set
 CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -869,6 +914,8 @@
 # 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
@@ -876,6 +923,7 @@
 # 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
@@ -893,13 +941,14 @@
 # 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
@@ -909,6 +958,8 @@
 #
 # USB support
 #
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -920,8 +971,6 @@
 # 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
@@ -929,7 +978,10 @@
 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=y
 # CONFIG_USB_SL811_HCD is not set
 
@@ -947,12 +999,11 @@
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_RW_DETECT is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
 # 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
@@ -966,9 +1017,11 @@
 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_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
@@ -978,7 +1031,6 @@
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
 
 #
 # USB Multimedia devices
@@ -992,6 +1044,7 @@
 # CONFIG_USB_SE401 is not set
 # CONFIG_USB_SN9C102 is not set
 # CONFIG_USB_STV680 is not set
+# CONFIG_USB_PWC is not set
 
 #
 # USB Network Adapters
@@ -1001,6 +1054,7 @@
 # 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
@@ -1016,7 +1070,6 @@
 #
 # 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
@@ -1025,9 +1078,11 @@
 # 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
 
 #
-# USB ATM/DSL drivers
+# USB DSL modem support
 #
 
 #
@@ -1041,12 +1096,22 @@
 # 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 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
@@ -1056,6 +1121,10 @@
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1089,7 +1158,6 @@
 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
@@ -1120,15 +1188,18 @@
 #
 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 is not set
 # CONFIG_NFSD_TCP is not set
 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
@@ -1209,6 +1280,8 @@
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
 
 #
 # Profiling support
@@ -1218,14 +1291,18 @@
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=17
 # 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=y
 CONFIG_IA64_GRANULE_16MB=y
 # CONFIG_IA64_GRANULE_64MB is not set
 CONFIG_IA64_PRINT_HAZARDS=y
@@ -1252,6 +1329,7 @@
 # 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
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index b8db6e3..1195759 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -156,10 +156,13 @@
 */
 #define DELAYED_RESOURCE_CNT	64
 
+#define PCI_DEVICE_ID_HP_SX2000_IOC	0x12ec
+
 #define ZX1_IOC_ID	((PCI_DEVICE_ID_HP_ZX1_IOC << 16) | PCI_VENDOR_ID_HP)
 #define ZX2_IOC_ID	((PCI_DEVICE_ID_HP_ZX2_IOC << 16) | PCI_VENDOR_ID_HP)
 #define REO_IOC_ID	((PCI_DEVICE_ID_HP_REO_IOC << 16) | PCI_VENDOR_ID_HP)
 #define SX1000_IOC_ID	((PCI_DEVICE_ID_HP_SX1000_IOC << 16) | PCI_VENDOR_ID_HP)
+#define SX2000_IOC_ID	((PCI_DEVICE_ID_HP_SX2000_IOC << 16) | PCI_VENDOR_ID_HP)
 
 #define ZX1_IOC_OFFSET	0x1000	/* ACPI reports SBA, we want IOC */
 
@@ -1726,6 +1729,7 @@
 	{ ZX1_IOC_ID, "zx1", ioc_zx1_init },
 	{ ZX2_IOC_ID, "zx2", NULL },
 	{ SX1000_IOC_ID, "sx1000", NULL },
+	{ SX2000_IOC_ID, "sx2000", NULL },
 };
 
 static struct ioc * __init
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
index 786e707..7a8ae0f 100644
--- a/arch/ia64/hp/sim/simserial.c
+++ b/arch/ia64/hp/sim/simserial.c
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/serial.h>
 #include <linux/serialP.h>
+#include <linux/sysrq.h>
 
 #include <asm/irq.h>
 #include <asm/hw_irq.h>
@@ -149,12 +150,17 @@
 				seen_esc = 2;
 				continue;
 			} else if ( seen_esc == 2 ) {
-				if ( ch == 'P' ) show_state();		/* F1 key */
-#ifdef CONFIG_KDB
-				if ( ch == 'S' )
-					kdb(KDB_REASON_KEYBOARD, 0, (kdb_eframe_t) regs);
+				if ( ch == 'P' ) /* F1 */
+					show_state();
+#ifdef CONFIG_MAGIC_SYSRQ
+				if ( ch == 'S' ) { /* F4 */
+					do
+						ch = ia64_ssc(0, 0, 0, 0,
+							      SSC_GETCHAR);
+					while (!ch);
+					handle_sysrq(ch, regs, NULL);
+				}
 #endif
-
 				seen_esc = 0;
 				continue;
 			}
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 72dfd9e..cda06f8 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -236,9 +236,7 @@
 	if (BAD_MADT_ENTRY(iosapic, end))
 		return -EINVAL;
 
-	iosapic_init(iosapic->address, iosapic->global_irq_base);
-
-	return 0;
+	return iosapic_init(iosapic->address, iosapic->global_irq_base);
 }
 
 
@@ -772,7 +770,7 @@
  
 
 #ifdef CONFIG_ACPI_NUMA
-acpi_status __init
+acpi_status __devinit
 acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
 {
 	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
@@ -825,4 +823,28 @@
 	return AE_OK;
 }
 #endif /* CONFIG_NUMA */
+
+int
+acpi_register_ioapic (acpi_handle handle, u64 phys_addr, u32 gsi_base)
+{
+	int err;
+
+	if ((err = iosapic_init(phys_addr, gsi_base)))
+		return err;
+
+#if CONFIG_ACPI_NUMA
+	acpi_map_iosapic(handle, 0, NULL, NULL);
+#endif /* CONFIG_ACPI_NUMA */
+
+	return 0;
+}
+EXPORT_SYMBOL(acpi_register_ioapic);
+
+int
+acpi_unregister_ioapic (acpi_handle handle, u32 gsi_base)
+{
+	return iosapic_remove(gsi_base);
+}
+EXPORT_SYMBOL(acpi_unregister_ioapic);
+
 #endif /* CONFIG_ACPI_BOOT */
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 785a51b..69f88d56 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -470,18 +470,6 @@
 	br.cond.sptk.many b7
 END(load_switch_stack)
 
-GLOBAL_ENTRY(__ia64_syscall)
-	.regstk 6,0,0,0
-	mov r15=in5				// put syscall number in place
-	break __BREAK_SYSCALL
-	movl r2=errno
-	cmp.eq p6,p7=-1,r10
-	;;
-(p6)	st4 [r2]=r8
-(p6)	mov r8=-1
-	br.ret.sptk.many rp
-END(__ia64_syscall)
-
 GLOBAL_ENTRY(execve)
 	mov r15=__NR_execve			// put syscall number in place
 	break __BREAK_SYSCALL
@@ -637,7 +625,7 @@
  *	      r8-r11: restored (syscall return value(s))
  *		 r12: restored (user-level stack pointer)
  *		 r13: restored (user-level thread pointer)
- *		 r14: cleared
+ *		 r14: set to __kernel_syscall_via_epc
  *		 r15: restored (syscall #)
  *	     r16-r17: cleared
  *		 r18: user-level b6
@@ -658,7 +646,7 @@
  *		  pr: restored (user-level pr)
  *		  b0: restored (user-level rp)
  *	          b6: restored
- *		  b7: cleared
+ *		  b7: set to __kernel_syscall_via_epc
  *	     ar.unat: restored (user-level ar.unat)
  *	      ar.pfs: restored (user-level ar.pfs)
  *	      ar.rsc: restored (user-level ar.rsc)
@@ -704,72 +692,79 @@
 	;;
 (p6)	ld4 r31=[r18]				// load current_thread_info()->flags
 	ld8 r19=[r2],PT(B6)-PT(LOADRS)		// load ar.rsc value for "loadrs"
-	mov b7=r0		// clear b7
+	nop.i 0
 	;;
-	ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE)	// load ar.bspstore (may be garbage)
+	mov r16=ar.bsp				// M2  get existing backing store pointer
 	ld8 r18=[r2],PT(R9)-PT(B6)		// load b6
 (p6)	and r15=TIF_WORK_MASK,r31		// any work other than TIF_SYSCALL_TRACE?
 	;;
-	mov r16=ar.bsp				// M2  get existing backing store pointer
+	ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE)	// load ar.bspstore (may be garbage)
 (p6)	cmp4.ne.unc p6,p0=r15, r0		// any special work pending?
 (p6)	br.cond.spnt .work_pending_syscall
 	;;
 	// start restoring the state saved on the kernel stack (struct pt_regs):
 	ld8 r9=[r2],PT(CR_IPSR)-PT(R9)
 	ld8 r11=[r3],PT(CR_IIP)-PT(R11)
-	mov f6=f0		// clear f6
+(pNonSys) break 0		//      bug check: we shouldn't be here if pNonSys is TRUE!
 	;;
 	invala			// M0|1 invalidate ALAT
-	rsm psr.i | psr.ic	// M2 initiate turning off of interrupt and interruption collection
-	mov f9=f0		// clear f9
+	rsm psr.i | psr.ic	// M2   turn off interrupts and interruption collection
+	cmp.eq p9,p0=r0,r0	// A    set p9 to indicate that we should restore cr.ifs
 
-	ld8 r29=[r2],16		// load cr.ipsr
-	ld8 r28=[r3],16			// load cr.iip
-	mov f8=f0		// clear f8
+	ld8 r29=[r2],16		// M0|1 load cr.ipsr
+	ld8 r28=[r3],16		// M0|1 load cr.iip
+	mov r22=r0		// A    clear r22
 	;;
 	ld8 r30=[r2],16		// M0|1 load cr.ifs
 	ld8 r25=[r3],16		// M0|1 load ar.unat
-	cmp.eq p9,p0=r0,r0	// set p9 to indicate that we should restore cr.ifs
-	;;
-	ld8 r26=[r2],PT(B0)-PT(AR_PFS)	// M0|1 load ar.pfs
-(pKStk)	mov r22=psr		// M2 read PSR now that interrupts are disabled
-	mov f10=f0		// clear f10
-	;;
-	ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0
-	ld8 r27=[r3],PT(PR)-PT(AR_RSC)	// load ar.rsc
-	mov f11=f0		// clear f11
-	;;
-	ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT)	// load ar.rnat (may be garbage)
-	ld8 r31=[r3],PT(R1)-PT(PR)		// load predicates
 (pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
 	;;
-	ld8 r20=[r2],PT(R12)-PT(AR_FPSR)	// load ar.fpsr
-	ld8.fill r1=[r3],16	// load r1
-(pUStk) mov r17=1
+	ld8 r26=[r2],PT(B0)-PT(AR_PFS)	// M0|1 load ar.pfs
+(pKStk)	mov r22=psr			// M2   read PSR now that interrupts are disabled
+	nop 0
 	;;
-	srlz.d			// M0  ensure interruption collection is off
-	ld8.fill r13=[r3],16
-	mov f7=f0		// clear f7
+	ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0
+	ld8 r27=[r3],PT(PR)-PT(AR_RSC)	// M0|1 load ar.rsc
+	mov f6=f0			// F    clear f6
 	;;
-	ld8.fill r12=[r2]	// restore r12 (sp)
-	mov.m ar.ssd=r0		// M2 clear ar.ssd
-	mov r22=r0		// clear r22
+	ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT)	// M0|1 load ar.rnat (may be garbage)
+	ld8 r31=[r3],PT(R1)-PT(PR)		// M0|1 load predicates
+	mov f7=f0				// F    clear f7
+	;;
+	ld8 r20=[r2],PT(R12)-PT(AR_FPSR)	// M0|1 load ar.fpsr
+	ld8.fill r1=[r3],16			// M0|1 load r1
+(pUStk) mov r17=1				// A
+	;;
+(pUStk) st1 [r14]=r17				// M2|3
+	ld8.fill r13=[r3],16			// M0|1
+	mov f8=f0				// F    clear f8
+	;;
+	ld8.fill r12=[r2]			// M0|1 restore r12 (sp)
+	ld8.fill r15=[r3]			// M0|1 restore r15
+	mov b6=r18				// I0   restore b6
 
-	ld8.fill r15=[r3]	// restore r15
-(pUStk) st1 [r14]=r17
-	addl r3=THIS_CPU(ia64_phys_stacked_size_p8),r0
-	;;
-(pUStk)	ld4 r17=[r3]		// r17 = cpu_data->phys_stacked_size_p8
-	mov.m ar.csd=r0		// M2 clear ar.csd
-	mov b6=r18		// I0  restore b6
-	;;
-	mov r14=r0		// clear r14
-	shr.u r18=r19,16	// I0|1 get byte size of existing "dirty" partition
-(pKStk) br.cond.dpnt.many skip_rbs_switch
+	addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A
+	mov f9=f0					// F    clear f9
+(pKStk) br.cond.dpnt.many skip_rbs_switch		// B
 
-	mov.m ar.ccv=r0		// clear ar.ccv
-(pNonSys) br.cond.dpnt.many dont_preserve_current_frame
-	br.cond.sptk.many rbs_switch
+	srlz.d				// M0   ensure interruption collection is off (for cover)
+	shr.u r18=r19,16		// I0|1 get byte size of existing "dirty" partition
+	cover				// B    add current frame into dirty partition & set cr.ifs
+	;;
+(pUStk) ld4 r17=[r17]			// M0|1 r17 = cpu_data->phys_stacked_size_p8
+	mov r19=ar.bsp			// M2   get new backing store pointer
+	mov f10=f0			// F    clear f10
+
+	nop.m 0
+	movl r14=__kernel_syscall_via_epc // X
+	;;
+	mov.m ar.csd=r0			// M2   clear ar.csd
+	mov.m ar.ccv=r0			// M2   clear ar.ccv
+	mov b7=r14			// I0   clear b7 (hint with __kernel_syscall_via_epc)
+
+	mov.m ar.ssd=r0			// M2   clear ar.ssd
+	mov f11=f0			// F    clear f11
+	br.cond.sptk.many rbs_switch	// B
 END(ia64_leave_syscall)
 
 #ifdef CONFIG_IA32_SUPPORT
@@ -885,7 +880,7 @@
 	ldf.fill f7=[r2],PT(F11)-PT(F7)
 	ldf.fill f8=[r3],32
 	;;
-	srlz.i			// ensure interruption collection is off
+	srlz.d	// ensure that inter. collection is off (VHPT is don't care, since text is pinned)
 	mov ar.ccv=r15
 	;;
 	ldf.fill f11=[r2]
@@ -945,11 +940,10 @@
 	 * NOTE: alloc, loadrs, and cover can't be predicated.
 	 */
 (pNonSys) br.cond.dpnt dont_preserve_current_frame
-
-rbs_switch:
 	cover				// add current frame into dirty partition and set cr.ifs
 	;;
 	mov r19=ar.bsp			// get new backing store pointer
+rbs_switch:
 	sub r16=r16,r18			// krbs = old bsp - size of dirty partition
 	cmp.ne p9,p0=r0,r0		// clear p9 to skip restore of cr.ifs
 	;;
@@ -1024,14 +1018,14 @@
 	mov loc5=0
 	mov loc6=0
 	mov loc7=0
-(pRecurse) br.call.sptk.few b0=rse_clear_invalid
+(pRecurse) br.call.dptk.few b0=rse_clear_invalid
 	;;
 	mov loc8=0
 	mov loc9=0
 	cmp.ne pReturn,p0=r0,in1	// if recursion count != 0, we need to do a br.ret
 	mov loc10=0
 	mov loc11=0
-(pReturn) br.ret.sptk.many b0
+(pReturn) br.ret.dptk.many b0
 #endif /* !CONFIG_ITANIUM */
 #	undef pRecurse
 #	undef pReturn
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S
index 962b6c4..7d7684a 100644
--- a/arch/ia64/kernel/fsys.S
+++ b/arch/ia64/kernel/fsys.S
@@ -531,93 +531,114 @@
 	.altrp b6
 	.body
 	/*
-	 * We get here for syscalls that don't have a lightweight handler.  For those, we
-	 * need to bubble down into the kernel and that requires setting up a minimal
-	 * pt_regs structure, and initializing the CPU state more or less as if an
-	 * interruption had occurred.  To make syscall-restarts work, we setup pt_regs
-	 * such that cr_iip points to the second instruction in syscall_via_break.
-	 * Decrementing the IP hence will restart the syscall via break and not
-	 * decrementing IP will return us to the caller, as usual.  Note that we preserve
-	 * the value of psr.pp rather than initializing it from dcr.pp.  This makes it
-	 * possible to distinguish fsyscall execution from other privileged execution.
+	 * We get here for syscalls that don't have a lightweight
+	 * handler.  For those, we need to bubble down into the kernel
+	 * and that requires setting up a minimal pt_regs structure,
+	 * and initializing the CPU state more or less as if an
+	 * interruption had occurred.  To make syscall-restarts work,
+	 * we setup pt_regs such that cr_iip points to the second
+	 * instruction in syscall_via_break.  Decrementing the IP
+	 * hence will restart the syscall via break and not
+	 * decrementing IP will return us to the caller, as usual.
+	 * Note that we preserve the value of psr.pp rather than
+	 * initializing it from dcr.pp.  This makes it possible to
+	 * distinguish fsyscall execution from other privileged
+	 * execution.
 	 *
 	 * On entry:
-	 *	- normal fsyscall handler register usage, except that we also have:
+	 *	- normal fsyscall handler register usage, except
+	 *	  that we also have:
 	 *	- r18: address of syscall entry point
 	 *	- r21: ar.fpsr
 	 *	- r26: ar.pfs
 	 *	- r27: ar.rsc
 	 *	- r29: psr
+	 *
+	 * We used to clear some PSR bits here but that requires slow
+	 * serialization.  Fortuntely, that isn't really necessary.
+	 * The rationale is as follows: we used to clear bits
+	 * ~PSR_PRESERVED_BITS in PSR.L.  Since
+	 * PSR_PRESERVED_BITS==PSR.{UP,MFL,MFH,PK,DT,PP,SP,RT,IC}, we
+	 * ended up clearing PSR.{BE,AC,I,DFL,DFH,DI,DB,SI,TB}.
+	 * However,
+	 *
+	 * PSR.BE : already is turned off in __kernel_syscall_via_epc()
+	 * PSR.AC : don't care (kernel normally turns PSR.AC on)
+	 * PSR.I  : already turned off by the time fsys_bubble_down gets
+	 *	    invoked
+	 * PSR.DFL: always 0 (kernel never turns it on)
+	 * PSR.DFH: don't care --- kernel never touches f32-f127 on its own
+	 *	    initiative
+	 * PSR.DI : always 0 (kernel never turns it on)
+	 * PSR.SI : always 0 (kernel never turns it on)
+	 * PSR.DB : don't care --- kernel never enables kernel-level
+	 *	    breakpoints
+	 * PSR.TB : must be 0 already; if it wasn't zero on entry to
+	 *          __kernel_syscall_via_epc, the branch to fsys_bubble_down
+	 *          will trigger a taken branch; the taken-trap-handler then
+	 *          converts the syscall into a break-based system-call.
 	 */
-#	define PSR_PRESERVED_BITS	(IA64_PSR_UP | IA64_PSR_MFL | IA64_PSR_MFH | IA64_PSR_PK \
-					 | IA64_PSR_DT | IA64_PSR_PP | IA64_PSR_SP | IA64_PSR_RT \
-					 | IA64_PSR_IC)
 	/*
-	 * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc.  The rest we have
-	 * to synthesize.
+	 * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc.
+	 * The rest we have to synthesize.
 	 */
-#	define PSR_ONE_BITS		((3 << IA64_PSR_CPL0_BIT) | (0x1 << IA64_PSR_RI_BIT) \
+#	define PSR_ONE_BITS		((3 << IA64_PSR_CPL0_BIT)	\
+					 | (0x1 << IA64_PSR_RI_BIT)	\
 					 | IA64_PSR_BN | IA64_PSR_I)
 
-	invala
-	movl r8=PSR_ONE_BITS
+	invala					// M0|1
+	movl r14=ia64_ret_from_syscall		// X
 
-	mov r25=ar.unat			// save ar.unat (5 cyc)
-	movl r9=PSR_PRESERVED_BITS
+	nop.m 0
+	movl r28=__kernel_syscall_via_break	// X	create cr.iip
+	;;
 
-	mov ar.rsc=0			// set enforced lazy mode, pl 0, little-endian, loadrs=0
-	movl r28=__kernel_syscall_via_break
+	mov r2=r16				// A    get task addr to addl-addressable register
+	adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 // A
+	mov r31=pr				// I0   save pr (2 cyc)
 	;;
-	mov r23=ar.bspstore		// save ar.bspstore (12 cyc)
-	mov r31=pr			// save pr (2 cyc)
-	mov r20=r1			// save caller's gp in r20
+	st1 [r16]=r0				// M2|3 clear current->thread.on_ustack flag
+	addl r22=IA64_RBS_OFFSET,r2		// A    compute base of RBS
+	add r3=TI_FLAGS+IA64_TASK_SIZE,r2	// A
 	;;
-	mov r2=r16			// copy current task addr to addl-addressable register
-	and r9=r9,r29
-	mov r19=b6			// save b6 (2 cyc)
+	ld4 r3=[r3]				// M0|1 r3 = current_thread_info()->flags
+	lfetch.fault.excl.nt1 [r22]		// M0|1 prefetch register backing-store
+	nop.i 0
 	;;
-	mov psr.l=r9			// slam the door (17 cyc to srlz.i)
-	or r29=r8,r29			// construct cr.ipsr value to save
-	addl r22=IA64_RBS_OFFSET,r2	// compute base of RBS
+	mov ar.rsc=0				// M2   set enforced lazy mode, pl 0, LE, loadrs=0
+	nop.m 0
+	nop.i 0
 	;;
-	// GAS reports a spurious RAW hazard on the read of ar.rnat because it thinks
-	// we may be reading ar.itc after writing to psr.l.  Avoid that message with
-	// this directive:
-	dv_serialize_data
-	mov.m r24=ar.rnat		// read ar.rnat (5 cyc lat)
-	lfetch.fault.excl.nt1 [r22]
-	adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r2
+	mov r23=ar.bspstore			// M2 (12 cyc) save ar.bspstore
+	mov.m r24=ar.rnat			// M2 (5 cyc) read ar.rnat (dual-issues!)
+	nop.i 0
+	;;
+	mov ar.bspstore=r22			// M2 (6 cyc) switch to kernel RBS
+	movl r8=PSR_ONE_BITS			// X
+	;;
+	mov r25=ar.unat				// M2 (5 cyc) save ar.unat
+	mov r19=b6				// I0   save b6 (2 cyc)
+	mov r20=r1				// A    save caller's gp in r20
+	;;
+	or r29=r8,r29				// A    construct cr.ipsr value to save
+	mov b6=r18				// I0   copy syscall entry-point to b6 (7 cyc)
+	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // A compute base of memory stack
 
-	// ensure previous insn group is issued before we stall for srlz.i:
+	mov r18=ar.bsp				// M2   save (kernel) ar.bsp (12 cyc)
+	cmp.ne pKStk,pUStk=r0,r0		// A    set pKStk <- 0, pUStk <- 1
+	br.call.sptk.many b7=ia64_syscall_setup	// B
 	;;
-	srlz.i				// ensure new psr.l has been established
-	/////////////////////////////////////////////////////////////////////////////
-	////////// from this point on, execution is not interruptible anymore
-	/////////////////////////////////////////////////////////////////////////////
-	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2	// compute base of memory stack
-	cmp.ne pKStk,pUStk=r0,r0	// set pKStk <- 0, pUStk <- 1
+	mov ar.rsc=0x3				// M2   set eager mode, pl 0, LE, loadrs=0
+	mov rp=r14				// I0   set the real return addr
+	and r3=_TIF_SYSCALL_TRACEAUDIT,r3	// A
 	;;
-	st1 [r16]=r0			// clear current->thread.on_ustack flag
-	mov ar.bspstore=r22		// switch to kernel RBS
-	mov b6=r18			// copy syscall entry-point to b6 (7 cyc)
-	add r3=TI_FLAGS+IA64_TASK_SIZE,r2
-	;;
-	ld4 r3=[r3]				// r2 = current_thread_info()->flags
-	mov r18=ar.bsp			// save (kernel) ar.bsp (12 cyc)
-	mov ar.rsc=0x3			// set eager mode, pl 0, little-endian, loadrs=0
-	br.call.sptk.many b7=ia64_syscall_setup
-	;;
-	ssm psr.i
-	movl r2=ia64_ret_from_syscall
-	;;
-	mov rp=r2				// set the real return addr
-	and r3=_TIF_SYSCALL_TRACEAUDIT,r3
-	;;
-	cmp.eq p8,p0=r3,r0
+	ssm psr.i				// M2   we're on kernel stacks now, reenable irqs
+	cmp.eq p8,p0=r3,r0			// A
+(p10)	br.cond.spnt.many ia64_ret_from_syscall	// B    return if bad call-frame or r15 is a NaT
 
-(p10)	br.cond.spnt.many ia64_ret_from_syscall	// p10==true means out registers are more than 8
-(p8)	br.call.sptk.many b6=b6		// ignore this return addr
-	br.cond.sptk ia64_trace_syscall
+	nop.m 0
+(p8)	br.call.sptk.many b6=b6			// B    (ignore return address)
+	br.cond.spnt ia64_trace_syscall		// B
 END(fsys_bubble_down)
 
 	.rodata
diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S
index facf75a..86948ce 100644
--- a/arch/ia64/kernel/gate.S
+++ b/arch/ia64/kernel/gate.S
@@ -72,38 +72,40 @@
 	 * bundle get executed.  The remaining code must be safe even if
 	 * they do not get executed.
 	 */
-	adds r17=-1024,r15
-	mov r10=0				// default to successful syscall execution
-	epc
+	adds r17=-1024,r15			// A
+	mov r10=0				// A    default to successful syscall execution
+	epc					// B	causes split-issue
 }
 	;;
-	rsm psr.be // note: on McKinley "rsm psr.be/srlz.d" is slightly faster than "rum psr.be"
-	LOAD_FSYSCALL_TABLE(r14)
+	rsm psr.be | psr.i			// M2 (5 cyc to srlz.d)
+	LOAD_FSYSCALL_TABLE(r14)		// X
+	;;
+	mov r16=IA64_KR(CURRENT)		// M2 (12 cyc)
+	shladd r18=r17,3,r14			// A
+	mov r19=NR_syscalls-1			// A
+	;;
+	lfetch [r18]				// M0|1
+	mov r29=psr				// M2 (12 cyc)
+	// If r17 is a NaT, p6 will be zero
+	cmp.geu p6,p7=r19,r17			// A    (sysnr > 0 && sysnr < 1024+NR_syscalls)?
+	;;
+	mov r21=ar.fpsr				// M2 (12 cyc)
+	tnat.nz p10,p9=r15			// I0
+	mov.i r26=ar.pfs			// I0 (would stall anyhow due to srlz.d...)
+	;;
+	srlz.d					// M0 (forces split-issue) ensure PSR.BE==0
+(p6)	ld8 r18=[r18]				// M0|1
+	nop.i 0
+	;;
+	nop.m 0
+(p6)	tbit.z.unc p8,p0=r18,0			// I0 (dual-issues with "mov b7=r18"!)
+	nop.i 0
+	;;
+(p8)	ssm psr.i
+(p6)	mov b7=r18				// I0
+(p8)	br.dptk.many b7				// B
 
-	mov r16=IA64_KR(CURRENT)		// 12 cycle read latency
-	tnat.nz p10,p9=r15
-	mov r19=NR_syscalls-1
-	;;
-	shladd r18=r17,3,r14
-
-	srlz.d
-	cmp.ne p8,p0=r0,r0			// p8 <- FALSE
-	/* Note: if r17 is a NaT, p6 will be set to zero.  */
-	cmp.geu p6,p7=r19,r17			// (syscall > 0 && syscall < 1024+NR_syscalls)?
-	;;
-(p6)	ld8 r18=[r18]
-	mov r21=ar.fpsr
-	add r14=-8,r14				// r14 <- addr of fsys_bubble_down entry
-	;;
-(p6)	mov b7=r18
-(p6)	tbit.z p8,p0=r18,0
-(p8)	br.dptk.many b7
-
-(p6)	rsm psr.i
-	mov r27=ar.rsc
-	mov r26=ar.pfs
-	;;
-	mov r29=psr				// read psr (12 cyc load latency)
+	mov r27=ar.rsc				// M2 (12 cyc)
 /*
  * brl.cond doesn't work as intended because the linker would convert this branch
  * into a branch to a PLT.  Perhaps there will be a way to avoid this with some
@@ -111,6 +113,8 @@
  * instead.
  */
 #ifdef CONFIG_ITANIUM
+(p6)	add r14=-8,r14				// r14 <- addr of fsys_bubble_down entry
+	;;
 (p6)	ld8 r14=[r14]				// r14 <- fsys_bubble_down
 	;;
 (p6)	mov b7=r14
@@ -118,7 +122,7 @@
 #else
 	BRL_COND_FSYS_BUBBLE_DOWN(p6)
 #endif
-
+	ssm psr.i
 	mov r10=-1
 (p10)	mov r8=EINVAL
 (p9)	mov r8=ENOSYS
diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c
index 7bbf019..0157281 100644
--- a/arch/ia64/kernel/ia64_ksyms.c
+++ b/arch/ia64/kernel/ia64_ksyms.c
@@ -58,9 +58,6 @@
 EXPORT_SYMBOL(__strncpy_from_user);
 EXPORT_SYMBOL(__strnlen_user);
 
-#include <asm/unistd.h>
-EXPORT_SYMBOL(__ia64_syscall);
-
 /* from arch/ia64/lib */
 extern void __divsi3(void);
 extern void __udivsi3(void);
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 88b0143..c170be0 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -129,14 +129,13 @@
 	char __iomem	*addr;		/* base address of IOSAPIC */
 	unsigned int 	gsi_base;	/* first GSI assigned to this IOSAPIC */
 	unsigned short 	num_rte;	/* number of RTE in this IOSAPIC */
+	int		rtes_inuse;	/* # of RTEs in use on this IOSAPIC */
 #ifdef CONFIG_NUMA
 	unsigned short	node;		/* numa node association via pxm */
 #endif
 } iosapic_lists[NR_IOSAPICS];
 
-static int num_iosapic;
-
-static unsigned char pcat_compat __initdata;	/* 8259 compatibility flag */
+static unsigned char pcat_compat __devinitdata;	/* 8259 compatibility flag */
 
 static int iosapic_kmalloc_ok;
 static LIST_HEAD(free_rte_list);
@@ -149,7 +148,7 @@
 {
 	int i;
 
-	for (i = 0; i < num_iosapic; i++) {
+	for (i = 0; i < NR_IOSAPICS; i++) {
 		if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte)
 			return i;
 	}
@@ -598,6 +597,7 @@
 		rte->refcnt++;
 		list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes);
 		iosapic_intr_info[vector].count++;
+		iosapic_lists[index].rtes_inuse++;
 	}
 	else if (vector_is_shared(vector)) {
 		struct iosapic_intr_info *info = &iosapic_intr_info[vector];
@@ -778,7 +778,7 @@
 iosapic_unregister_intr (unsigned int gsi)
 {
 	unsigned long flags;
-	int irq, vector;
+	int irq, vector, index;
 	irq_desc_t *idesc;
 	u32 low32;
 	unsigned long trigger, polarity;
@@ -819,6 +819,9 @@
 		list_del(&rte->rte_list);
 		iosapic_intr_info[vector].count--;
 		iosapic_free_rte(rte);
+		index = find_iosapic(gsi);
+		iosapic_lists[index].rtes_inuse--;
+		WARN_ON(iosapic_lists[index].rtes_inuse < 0);
 
 		trigger	 = iosapic_intr_info[vector].trigger;
 		polarity = iosapic_intr_info[vector].polarity;
@@ -952,30 +955,86 @@
 	}
 }
 
-void __init
+static inline int
+iosapic_alloc (void)
+{
+	int index;
+
+	for (index = 0; index < NR_IOSAPICS; index++)
+		if (!iosapic_lists[index].addr)
+			return index;
+
+	printk(KERN_WARNING "%s: failed to allocate iosapic\n", __FUNCTION__);
+	return -1;
+}
+
+static inline void
+iosapic_free (int index)
+{
+	memset(&iosapic_lists[index], 0, sizeof(iosapic_lists[0]));
+}
+
+static inline int
+iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver)
+{
+	int index;
+	unsigned int gsi_end, base, end;
+
+	/* check gsi range */
+	gsi_end = gsi_base + ((ver >> 16) & 0xff);
+	for (index = 0; index < NR_IOSAPICS; index++) {
+		if (!iosapic_lists[index].addr)
+			continue;
+
+		base = iosapic_lists[index].gsi_base;
+		end  = base + iosapic_lists[index].num_rte - 1;
+
+		if (gsi_base < base && gsi_end < base)
+			continue;/* OK */
+
+		if (gsi_base > end && gsi_end > end)
+			continue; /* OK */
+
+		return -EBUSY;
+	}
+	return 0;
+}
+
+int __devinit
 iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
 {
-	int num_rte;
+	int num_rte, err, index;
 	unsigned int isa_irq, ver;
 	char __iomem *addr;
+	unsigned long flags;
 
-	addr = ioremap(phys_addr, 0);
-	ver = iosapic_version(addr);
+	spin_lock_irqsave(&iosapic_lock, flags);
+	{
+		addr = ioremap(phys_addr, 0);
+		ver = iosapic_version(addr);
 
-	/*
-	 * The MAX_REDIR register holds the highest input pin
-	 * number (starting from 0).
-	 * We add 1 so that we can use it for number of pins (= RTEs)
-	 */
-	num_rte = ((ver >> 16) & 0xff) + 1;
+		if ((err = iosapic_check_gsi_range(gsi_base, ver))) {
+			iounmap(addr);
+			spin_unlock_irqrestore(&iosapic_lock, flags);
+			return err;
+		}
 
-	iosapic_lists[num_iosapic].addr = addr;
-	iosapic_lists[num_iosapic].gsi_base = gsi_base;
-	iosapic_lists[num_iosapic].num_rte = num_rte;
+		/*
+		 * The MAX_REDIR register holds the highest input pin
+		 * number (starting from 0).
+		 * We add 1 so that we can use it for number of pins (= RTEs)
+		 */
+		num_rte = ((ver >> 16) & 0xff) + 1;
+
+		index = iosapic_alloc();
+		iosapic_lists[index].addr = addr;
+		iosapic_lists[index].gsi_base = gsi_base;
+		iosapic_lists[index].num_rte = num_rte;
 #ifdef CONFIG_NUMA
-	iosapic_lists[num_iosapic].node = MAX_NUMNODES;
+		iosapic_lists[index].node = MAX_NUMNODES;
 #endif
-	num_iosapic++;
+	}
+	spin_unlock_irqrestore(&iosapic_lock, flags);
 
 	if ((gsi_base == 0) && pcat_compat) {
 		/*
@@ -986,10 +1045,43 @@
 		for (isa_irq = 0; isa_irq < 16; ++isa_irq)
 			iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE);
 	}
+	return 0;
 }
 
+#ifdef CONFIG_HOTPLUG
+int
+iosapic_remove (unsigned int gsi_base)
+{
+	int index, err = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&iosapic_lock, flags);
+	{
+		index = find_iosapic(gsi_base);
+		if (index < 0) {
+			printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n",
+			       __FUNCTION__, gsi_base);
+			goto out;
+		}
+
+		if (iosapic_lists[index].rtes_inuse) {
+			err = -EBUSY;
+			printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n",
+			       __FUNCTION__, gsi_base);
+			goto out;
+		}
+
+		iounmap(iosapic_lists[index].addr);
+		iosapic_free(index);
+	}
+ out:
+	spin_unlock_irqrestore(&iosapic_lock, flags);
+	return err;
+}
+#endif /* CONFIG_HOTPLUG */
+
 #ifdef CONFIG_NUMA
-void __init
+void __devinit
 map_iosapic_to_node(unsigned int gsi_base, int node)
 {
 	int index;
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S
index 2bc085a..3bb3a13 100644
--- a/arch/ia64/kernel/ivt.S
+++ b/arch/ia64/kernel/ivt.S
@@ -1,7 +1,7 @@
 /*
  * arch/ia64/kernel/ivt.S
  *
- * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
+ * Copyright (C) 1998-2001, 2003, 2005 Hewlett-Packard Co
  *	Stephane Eranian <eranian@hpl.hp.com>
  *	David Mosberger <davidm@hpl.hp.com>
  * Copyright (C) 2000, 2002-2003 Intel Co
@@ -692,82 +692,118 @@
 	 * to prevent leaking bits from kernel to user level.
 	 */
 	DBG_FAULT(11)
-	mov r16=IA64_KR(CURRENT)		// r16 = current task; 12 cycle read lat.
-	mov r17=cr.iim
-	mov r18=__IA64_BREAK_SYSCALL
-	mov r21=ar.fpsr
-	mov r29=cr.ipsr
-	mov r19=b6
-	mov r25=ar.unat
-	mov r27=ar.rsc
-	mov r26=ar.pfs
-	mov r28=cr.iip
-	mov r31=pr				// prepare to save predicates
-	mov r20=r1
+	mov.m r16=IA64_KR(CURRENT)		// M2 r16 <- current task (12 cyc)
+	mov r29=cr.ipsr				// M2 (12 cyc)
+	mov r31=pr				// I0 (2 cyc)
+
+	mov r17=cr.iim				// M2 (2 cyc)
+	mov.m r27=ar.rsc			// M2 (12 cyc)
+	mov r18=__IA64_BREAK_SYSCALL		// A
+
+	mov.m ar.rsc=0				// M2
+	mov.m r21=ar.fpsr			// M2 (12 cyc)
+	mov r19=b6				// I0 (2 cyc)
 	;;
+	mov.m r23=ar.bspstore			// M2 (12 cyc)
+	mov.m r24=ar.rnat			// M2 (5 cyc)
+	mov.i r26=ar.pfs			// I0 (2 cyc)
+
+	invala					// M0|1
+	nop.m 0					// M
+	mov r20=r1				// A			save r1
+
+	nop.m 0
+	movl r30=sys_call_table			// X
+
+	mov r28=cr.iip				// M2 (2 cyc)
+	cmp.eq p0,p7=r18,r17			// I0 is this a system call?
+(p7)	br.cond.spnt non_syscall		// B  no ->
+	//
+	// From this point on, we are definitely on the syscall-path
+	// and we can use (non-banked) scratch registers.
+	//
+///////////////////////////////////////////////////////////////////////
+	mov r1=r16				// A    move task-pointer to "addl"-addressable reg
+	mov r2=r16				// A    setup r2 for ia64_syscall_setup
+	add r9=TI_FLAGS+IA64_TASK_SIZE,r16	// A	r9 = &current_thread_info()->flags
+
 	adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16
-	cmp.eq p0,p7=r18,r17			// is this a system call? (p7 <- false, if so)
-(p7)	br.cond.spnt non_syscall
-	;;
-	ld1 r17=[r16]				// load current->thread.on_ustack flag
-	st1 [r16]=r0				// clear current->thread.on_ustack flag
-	add r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16	// set r1 for MINSTATE_START_SAVE_MIN_VIRT
-	;;
-	invala
-
-	/* adjust return address so we skip over the break instruction: */
-
-	extr.u r8=r29,41,2			// extract ei field from cr.ipsr
-	;;
-	cmp.eq p6,p7=2,r8			// isr.ei==2?
-	mov r2=r1				// setup r2 for ia64_syscall_setup
-	;;
-(p6)	mov r8=0				// clear ei to 0
-(p6)	adds r28=16,r28				// switch cr.iip to next bundle cr.ipsr.ei wrapped
-(p7)	adds r8=1,r8				// increment ei to next slot
-	;;
-	cmp.eq pKStk,pUStk=r0,r17		// are we in kernel mode already?
-	dep r29=r8,r29,41,2			// insert new ei into cr.ipsr
-	;;
-
-	// switch from user to kernel RBS:
-	MINSTATE_START_SAVE_MIN_VIRT
-	br.call.sptk.many b7=ia64_syscall_setup
-	;;
-	MINSTATE_END_SAVE_MIN_VIRT		// switch to bank 1
-	ssm psr.ic | PSR_DEFAULT_BITS
-	;;
-	srlz.i					// guarantee that interruption collection is on
+	adds r15=-1024,r15			// A    subtract 1024 from syscall number
 	mov r3=NR_syscalls - 1
 	;;
-(p15)	ssm psr.i				// restore psr.i
-	// p10==true means out registers are more than 8 or r15's Nat is true
-(p10)	br.cond.spnt.many ia64_ret_from_syscall
-	;;
-	movl r16=sys_call_table
+	ld1.bias r17=[r16]			// M0|1 r17 = current->thread.on_ustack flag
+	ld4 r9=[r9]				// M0|1 r9 = current_thread_info()->flags
+	extr.u r8=r29,41,2			// I0   extract ei field from cr.ipsr
 
-	adds r15=-1024,r15			// r15 contains the syscall number---subtract 1024
-	movl r2=ia64_ret_from_syscall
+	shladd r30=r15,3,r30			// A    r30 = sys_call_table + 8*(syscall-1024)
+	addl r22=IA64_RBS_OFFSET,r1		// A    compute base of RBS
+	cmp.leu p6,p7=r15,r3			// A    syscall number in range?
 	;;
-	shladd r20=r15,3,r16			// r20 = sys_call_table + 8*(syscall-1024)
-	cmp.leu p6,p7=r15,r3			// (syscall > 0 && syscall < 1024 + NR_syscalls) ?
-	mov rp=r2				// set the real return addr
-	;;
-(p6)	ld8 r20=[r20]				// load address of syscall entry point
-(p7)	movl r20=sys_ni_syscall
 
-	add r2=TI_FLAGS+IA64_TASK_SIZE,r13
+	lfetch.fault.excl.nt1 [r22]		// M0|1 prefetch RBS
+(p6)	ld8 r30=[r30]				// M0|1 load address of syscall entry point
+	tnat.nz.or p7,p0=r15			// I0	is syscall nr a NaT?
+
+	mov.m ar.bspstore=r22			// M2   switch to kernel RBS
+	cmp.eq p8,p9=2,r8			// A    isr.ei==2?
 	;;
-	ld4 r2=[r2]				// r2 = current_thread_info()->flags
+
+(p8)	mov r8=0				// A    clear ei to 0
+(p7)	movl r30=sys_ni_syscall			// X
+
+(p8)	adds r28=16,r28				// A    switch cr.iip to next bundle
+(p9)	adds r8=1,r8				// A    increment ei to next slot
+	nop.i 0
 	;;
-	and r2=_TIF_SYSCALL_TRACEAUDIT,r2	// mask trace or audit
+
+	mov.m r25=ar.unat			// M2 (5 cyc)
+	dep r29=r8,r29,41,2			// I0   insert new ei into cr.ipsr
+	adds r15=1024,r15			// A    restore original syscall number
+	//
+	// If any of the above loads miss in L1D, we'll stall here until
+	// the data arrives.
+	//
+///////////////////////////////////////////////////////////////////////
+	st1 [r16]=r0				// M2|3 clear current->thread.on_ustack flag
+	mov b6=r30				// I0   setup syscall handler branch reg early
+	cmp.eq pKStk,pUStk=r0,r17		// A    were we on kernel stacks already?
+
+	and r9=_TIF_SYSCALL_TRACEAUDIT,r9	// A    mask trace or audit
+	mov r18=ar.bsp				// M2 (12 cyc)
+(pKStk)	br.cond.spnt .break_fixup		// B	we're already in kernel-mode -- fix up RBS
 	;;
-	cmp.eq p8,p0=r2,r0
-	mov b6=r20
+.back_from_break_fixup:
+(pUStk)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A    compute base of memory stack
+	cmp.eq p14,p0=r9,r0			// A    are syscalls being traced/audited?
+	br.call.sptk.many b7=ia64_syscall_setup	// B
+1:
+	mov ar.rsc=0x3				// M2   set eager mode, pl 0, LE, loadrs=0
+	nop 0
+	bsw.1					// B (6 cyc) regs are saved, switch to bank 1
 	;;
-(p8)	br.call.sptk.many b6=b6			// ignore this return addr
-	br.cond.sptk ia64_trace_syscall
+
+	ssm psr.ic | PSR_DEFAULT_BITS		// M2	now it's safe to re-enable intr.-collection
+	movl r3=ia64_ret_from_syscall		// X
+	;;
+
+	srlz.i					// M0   ensure interruption collection is on
+	mov rp=r3				// I0   set the real return addr
+(p10)	br.cond.spnt.many ia64_ret_from_syscall	// B    return if bad call-frame or r15 is a NaT
+
+(p15)	ssm psr.i				// M2   restore psr.i
+(p14)	br.call.sptk.many b6=b6			// B    invoke syscall-handker (ignore return addr)
+	br.cond.spnt.many ia64_trace_syscall	// B	do syscall-tracing thingamagic
 	// NOT REACHED
+///////////////////////////////////////////////////////////////////////
+	// On entry, we optimistically assumed that we're coming from user-space.
+	// For the rare cases where a system-call is done from within the kernel,
+	// we fix things up at this point:
+.break_fixup:
+	add r1=-IA64_PT_REGS_SIZE,sp		// A    allocate space for pt_regs structure
+	mov ar.rnat=r24				// M2	restore kernel's AR.RNAT
+	;;
+	mov ar.bspstore=r23			// M2	restore kernel's AR.BSPSTORE
+	br.cond.sptk .back_from_break_fixup
 END(break_fault)
 
 	.org ia64_ivt+0x3000
@@ -842,8 +878,6 @@
 	 *	- r31: saved pr
 	 *	-  b0: original contents (to be saved)
 	 * On exit:
-	 *	- executing on bank 1 registers
-	 *	- psr.ic enabled, interrupts restored
 	 *	-  p10: TRUE if syscall is invoked with more than 8 out
 	 *		registers or r15's Nat is true
 	 *	-  r1: kernel's gp
@@ -851,8 +885,11 @@
 	 *	-  r8: -EINVAL if p10 is true
 	 *	- r12: points to kernel stack
 	 *	- r13: points to current task
+	 *	- r14: preserved (same as on entry)
+	 *	- p13: preserved
 	 *	- p15: TRUE if interrupts need to be re-enabled
 	 *	- ar.fpsr: set to kernel settings
+	 *	-  b6: preserved (same as on entry)
 	 */
 GLOBAL_ENTRY(ia64_syscall_setup)
 #if PT(B6) != 0
@@ -920,10 +957,10 @@
 (p13)	mov in5=-1
 	;;
 	st8 [r16]=r21,PT(R8)-PT(AR_FPSR)	// save ar.fpsr
-	tnat.nz p14,p0=in6
+	tnat.nz p13,p0=in6
 	cmp.lt p10,p9=r11,r8	// frame size can't be more than local+8
 	;;
-	stf8 [r16]=f1		// ensure pt_regs.r8 != 0 (see handle_syscall_error)
+	mov r8=1
 (p9)	tnat.nz p10,p0=r15
 	adds r12=-16,r1		// switch to kernel memory stack (with 16 bytes of scratch)
 
@@ -934,9 +971,9 @@
 	mov r13=r2				// establish `current'
 	movl r1=__gp				// establish kernel global pointer
 	;;
-(p14)	mov in6=-1
+	st8 [r16]=r8		// ensure pt_regs.r8 != 0 (see handle_syscall_error)
+(p13)	mov in6=-1
 (p8)	mov in7=-1
-	nop.i 0
 
 	cmp.eq pSys,pNonSys=r0,r0		// set pSys=1, pNonSys=0
 	movl r17=FPSR_DEFAULT
@@ -1007,6 +1044,8 @@
 	FAULT(17)
 
 ENTRY(non_syscall)
+	mov ar.rsc=r27			// restore ar.rsc before SAVE_MIN_WITH_COVER
+	;;
 	SAVE_MIN_WITH_COVER
 
 	// There is no particular reason for this code to be here, other than that
@@ -1204,6 +1243,25 @@
 // 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50)
 ENTRY(nat_consumption)
 	DBG_FAULT(26)
+
+	mov r16=cr.ipsr
+	mov r17=cr.isr
+	mov r31=pr				// save PR
+	;;
+	and r18=0xf,r17				// r18 = cr.ipsr.code{3:0}
+	tbit.z p6,p0=r17,IA64_ISR_NA_BIT
+	;;
+	cmp.ne.or p6,p0=IA64_ISR_CODE_LFETCH,r18
+	dep r16=-1,r16,IA64_PSR_ED_BIT,1
+(p6)	br.cond.spnt 1f		// branch if (cr.ispr.na == 0 || cr.ipsr.code{3:0} != LFETCH)
+	;;
+	mov cr.ipsr=r16		// set cr.ipsr.na
+	mov pr=r31,-1
+	;;
+	rfi
+
+1:	mov pr=r31,-1
+	;;
 	FAULT(26)
 END(nat_consumption)
 
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 3aa3167..884f5cd 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -713,7 +713,7 @@
 	.pre_handler = trampoline_probe_handler
 };
 
-int __init arch_init(void)
+int __init arch_init_kprobes(void)
 {
 	trampoline_p.addr =
 		(kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip;
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 6d57aeb..bbb8bc7 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -725,12 +725,32 @@
 			break;
 	}
 
+	/*
+	 * Note: at the time of this call, the target task is blocked
+	 * in notify_resume_user() and by clearling PRED_LEAVE_SYSCALL
+	 * (aka, "pLvSys") we redirect execution from
+	 * .work_pending_syscall_end to .work_processed_kernel.
+	 */
 	unw_get_pr(&prev_info, &pr);
-	pr &= ~(1UL << PRED_SYSCALL);
+	pr &= ~((1UL << PRED_SYSCALL) | (1UL << PRED_LEAVE_SYSCALL));
 	pr |=  (1UL << PRED_NON_SYSCALL);
 	unw_set_pr(&prev_info, pr);
 
 	pt->cr_ifs = (1UL << 63) | cfm;
+	/*
+	 * Clear the memory that is NOT written on syscall-entry to
+	 * ensure we do not leak kernel-state to user when execution
+	 * resumes.
+	 */
+	pt->r2 = 0;
+	pt->r3 = 0;
+	pt->r14 = 0;
+	memset(&pt->r16, 0, 16*8);	/* clear r16-r31 */
+	memset(&pt->f6, 0, 6*16);	/* clear f6-f11 */
+	pt->b7 = 0;
+	pt->ar_ccv = 0;
+	pt->ar_csd = 0;
+	pt->ar_ssd = 0;
 }
 
 static int
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index d14692e..2693e15 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -72,6 +72,8 @@
 unsigned long ia64_cycles_per_usec;
 struct ia64_boot_param *ia64_boot_param;
 struct screen_info screen_info;
+unsigned long vga_console_iobase;
+unsigned long vga_console_membase;
 
 unsigned long ia64_max_cacheline_size;
 unsigned long ia64_iobase;	/* virtual address for I/O accesses */
@@ -273,23 +275,25 @@
 static inline int __init
 early_console_setup (char *cmdline)
 {
+	int earlycons = 0;
+
 #ifdef CONFIG_SERIAL_SGI_L1_CONSOLE
 	{
 		extern int sn_serial_console_early_setup(void);
 		if (!sn_serial_console_early_setup())
-			return 0;
+			earlycons++;
 	}
 #endif
 #ifdef CONFIG_EFI_PCDP
 	if (!efi_setup_pcdp_console(cmdline))
-		return 0;
+		earlycons++;
 #endif
 #ifdef CONFIG_SERIAL_8250_CONSOLE
 	if (!early_serial_console_init(cmdline))
-		return 0;
+		earlycons++;
 #endif
 
-	return -1;
+	return (earlycons) ? 0 : -1;
 }
 
 static inline void
diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c
index b49d4dd..0166a98 100644
--- a/arch/ia64/kernel/smp.c
+++ b/arch/ia64/kernel/smp.c
@@ -231,13 +231,16 @@
 void
 smp_flush_tlb_mm (struct mm_struct *mm)
 {
+	preempt_disable();
 	/* this happens for the common case of a single-threaded fork():  */
 	if (likely(mm == current->active_mm && atomic_read(&mm->mm_users) == 1))
 	{
 		local_finish_flush_tlb_mm(mm);
+		preempt_enable();
 		return;
 	}
 
+	preempt_enable();
 	/*
 	 * We could optimize this further by using mm->cpu_vm_mask to track which CPUs
 	 * have been running in the address space.  It's not clear that this is worth the
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index e3fc4ed..720a861 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -312,7 +312,7 @@
 	acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window,
 			&info);
 
-	pbus = pci_scan_bus(bus, &pci_root_ops, controller);
+	pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller);
 	if (pbus)
 		pcibios_setup_root_windows(pbus, controller);
 
@@ -373,6 +373,25 @@
 	res->end = region->end + offset;
 }
 
+static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
+{
+	unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;
+	struct resource *devr = &dev->resource[idx];
+
+	if (!dev->bus)
+		return 0;
+	for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) {
+		struct resource *busr = dev->bus->resource[i];
+
+		if (!busr || ((busr->flags ^ devr->flags) & type_mask))
+			continue;
+		if ((devr->start) && (devr->start >= busr->start) &&
+				(devr->end <= busr->end))
+			return 1;
+	}
+	return 0;
+}
+
 static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
 {
 	struct pci_bus_region region;
@@ -386,7 +405,8 @@
 		region.start = dev->resource[i].start;
 		region.end = dev->resource[i].end;
 		pcibios_bus_to_resource(dev, &dev->resource[i], &region);
-		pci_claim_resource(dev, i);
+		if ((is_valid_resource(dev, i)))
+			pci_claim_resource(dev, i);
 	}
 }
 
@@ -398,6 +418,10 @@
 {
 	struct pci_dev *dev;
 
+	if (b->self) {
+		pci_read_bridge_bases(b);
+		pcibios_fixup_device_resources(b->self);
+	}
 	list_for_each_entry(dev, &b->devices, bus_list)
 		pcibios_fixup_device_resources(dev);
 
@@ -418,18 +442,24 @@
 	u16 cmd, old_cmd;
 	int idx;
 	struct resource *r;
+	unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;
 
 	if (!dev)
 		return -EINVAL;
 
 	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 desired resources.  */
 		if (!(mask & (1 << idx)))
 			continue;
 
 		r = &dev->resource[idx];
+		if (!(r->flags & type_mask))
+			continue;
+		if ((idx == PCI_ROM_RESOURCE) &&
+				(!(r->flags & IORESOURCE_ROM_ENABLE)))
+			continue;
 		if (!r->start && r->end) {
 			printk(KERN_ERR
 			       "PCI: Device %s not available because of resource collisions\n",
@@ -441,8 +471,6 @@
 		if (r->flags & IORESOURCE_MEM)
 			cmd |= PCI_COMMAND_MEMORY;
 	}
-	if (dev->resource[PCI_ROM_RESOURCE].start)
-		cmd |= PCI_COMMAND_MEMORY;
 	if (cmd != old_cmd) {
 		printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
 		pci_write_config_word(dev, PCI_COMMAND, cmd);
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 9e07f54..783eb43 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -384,7 +384,7 @@
 	extern void register_sn_procfs(void);
 #endif
 
-	if (!ia64_platform_is("sn2") || IS_RUNNING_ON_SIMULATOR())
+	if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM())
 		return 0;
 
 	/*
diff --git a/arch/ia64/sn/kernel/iomv.c b/arch/ia64/sn/kernel/iomv.c
index fec6d8b..7ce3cda 100644
--- a/arch/ia64/sn/kernel/iomv.c
+++ b/arch/ia64/sn/kernel/iomv.c
@@ -9,12 +9,16 @@
 #include <linux/module.h>
 #include <asm/io.h>
 #include <asm/delay.h>
+#include <asm/vga.h>
 #include <asm/sn/nodepda.h>
 #include <asm/sn/simulator.h>
 #include <asm/sn/pda.h>
 #include <asm/sn/sn_cpuid.h>
 #include <asm/sn/shub_mmr.h>
 
+#define IS_LEGACY_VGA_IOPORT(p) \
+	(((p) >= 0x3b0 && (p) <= 0x3bb) || ((p) >= 0x3c0 && (p) <= 0x3df))
+
 /**
  * sn_io_addr - convert an in/out port to an i/o address
  * @port: port to convert
@@ -26,6 +30,8 @@
 void *sn_io_addr(unsigned long port)
 {
 	if (!IS_RUNNING_ON_SIMULATOR()) {
+		if (IS_LEGACY_VGA_IOPORT(port))
+			port += vga_console_iobase;
 		/* On sn2, legacy I/O ports don't point at anything */
 		if (port < (64 * 1024))
 			return NULL;
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index 44bfc7f..22e10d2 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -36,6 +36,7 @@
 #include <asm/machvec.h>
 #include <asm/system.h>
 #include <asm/processor.h>
+#include <asm/vga.h>
 #include <asm/sn/arch.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/pda.h>
@@ -95,6 +96,7 @@
 EXPORT_SYMBOL(sn_coherency_id);
 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];
 
@@ -273,14 +275,17 @@
 
 	ia64_sn_plat_set_error_handling_features();
 
-	/*
-	 * If the generic code has enabled vga console support - lets
-	 * get rid of it again. This is a kludge for the fact that ACPI
-	 * currtently has no way of informing us if legacy VGA is available
-	 * or not.
-	 */
 #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
-	if (conswitchp == &vga_con) {
+	/*
+	 * If there was a primary vga adapter identified through the
+	 * EFI PCDP table, make it the preferred console.  Otherwise
+	 * zero out conswitchp.
+	 */
+
+	if (vga_console_membase) {
+		/* usable vga ... make tty0 the preferred default console */
+		add_preferred_console("tty", 0, NULL);
+	} else {
 		printk(KERN_DEBUG "SGI: Disabling VGA console\n");
 #ifdef CONFIG_DUMMY_CONSOLE
 		conswitchp = &dummy_con;
@@ -350,7 +355,7 @@
 
 	ia64_mark_idle = &snidle;
 
-	/* 
+	/*
 	 * For the bootcpu, we do this here. All other cpus will make the
 	 * call as part of cpu_init in slave cpu initialization.
 	 */
@@ -397,7 +402,7 @@
 		nodepdaindr[cnode] =
 		    alloc_bootmem_node(NODE_DATA(cnode), sizeof(nodepda_t));
 		memset(nodepdaindr[cnode], 0, sizeof(nodepda_t));
-		memset(nodepdaindr[cnode]->phys_cpuid, -1, 
+		memset(nodepdaindr[cnode]->phys_cpuid, -1,
 		    sizeof(nodepdaindr[cnode]->phys_cpuid));
 	}
 
@@ -427,7 +432,7 @@
 	}
 
 	/*
-	 * Initialize the per node hubdev.  This includes IO Nodes and 
+	 * Initialize the per node hubdev.  This includes IO Nodes and
 	 * headless/memless nodes.
 	 */
 	for (cnode = 0; cnode < numionodes; cnode++) {
@@ -455,6 +460,14 @@
 	int i;
 	static int wars_have_been_checked;
 
+	if (smp_processor_id() == 0 && IS_MEDUSA()) {
+		if (ia64_sn_is_fake_prom())
+			sn_prom_type = 2;
+		else
+			sn_prom_type = 1;
+		printk("Running on medusa with %s PROM\n", (sn_prom_type == 1) ? "real" : "fake");
+	}
+
 	memset(pda, 0, sizeof(pda));
 	if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2, &sn_hub_info->nasid_bitmask, &sn_hub_info->nasid_shift,
 				&sn_system_size, &sn_sharing_domain_size, &sn_partition_id,
@@ -520,7 +533,7 @@
 	 */
 	{
 		u64 pio1[] = {SH1_PIO_WRITE_STATUS_0, 0, SH1_PIO_WRITE_STATUS_1, 0};
-		u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_1, 
+		u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_1,
 			SH2_PIO_WRITE_STATUS_2, SH2_PIO_WRITE_STATUS_3};
 		u64 *pio;
 		pio = is_shub1() ? pio1 : pio2;
@@ -552,6 +565,10 @@
 	int nasid = 0;
 	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;
@@ -563,8 +580,6 @@
 		cnodeid = -1;
 		klgraph_header = __va(ia64_sn_get_klconfig_addr(nasid));
 		if (!klgraph_header) {
-			if (IS_RUNNING_ON_SIMULATOR())
-				continue;
 			BUG();	/* All nodes must have klconfig tables! */
 		}
 		cnodeid = nasid_to_cnodeid(nasid);
@@ -630,8 +645,8 @@
 nasid_slice_to_cpuid(int nasid, int slice)
 {
 	long cpu;
-	
-	for (cpu=0; cpu < NR_CPUS; cpu++) 
+
+	for (cpu=0; cpu < NR_CPUS; cpu++)
 		if (cpuid_to_nasid(cpu) == nasid &&
 					cpuid_to_slice(cpu) == slice)
 			return cpu;
diff --git a/arch/ia64/sn/kernel/sn2/ptc_deadlock.S b/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
index 7947312..96cb71d 100644
--- a/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
+++ b/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
@@ -6,6 +6,7 @@
  * Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved.
  */
 
+#include <asm/types.h>
 #include <asm/sn/shub_mmr.h>
 
 #define DEADLOCKBIT	SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c
index a087b27..8716f4d 100644
--- a/arch/ia64/sn/kernel/tiocx.c
+++ b/arch/ia64/sn/kernel/tiocx.c
@@ -204,8 +204,8 @@
 	cx_dev->dev.parent = NULL;
 	cx_dev->dev.bus = &tiocx_bus_type;
 	cx_dev->dev.release = tiocx_bus_release;
-	snprintf(cx_dev->dev.bus_id, BUS_ID_SIZE, "%d.0x%x",
-		 cx_dev->cx_id.nasid, cx_dev->cx_id.part_num);
+	snprintf(cx_dev->dev.bus_id, BUS_ID_SIZE, "%d",
+		 cx_dev->cx_id.nasid);
 	device_register(&cx_dev->dev);
 	get_device(&cx_dev->dev);
 
@@ -236,7 +236,6 @@
  */
 static int cx_device_reload(struct cx_dev *cx_dev)
 {
-	device_remove_file(&cx_dev->dev, &dev_attr_cxdev_control);
 	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);
@@ -383,6 +382,7 @@
 	switch (tiocx_btchar_get(nasid)) {
 	case L1_BRICKTYPE_SA:
 	case L1_BRICKTYPE_ATHENA:
+	case L1_BRICKTYPE_DAYTONA:
 		return 1;
 	}
 	return 0;
@@ -409,7 +409,7 @@
 		uint64_t cx_id;
 
 		cx_id =
-		    *(volatile int32_t *)(TIO_SWIN_BASE(nasid, TIOCX_CORELET) +
+		    *(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);
@@ -458,6 +458,10 @@
 
 	switch (n) {
 	case 1:
+		tio_corelet_reset(cx_dev->cx_id.nasid, TIOCX_CORELET);
+		tiocx_reload(cx_dev);
+		break;
+	case 2:
 		tiocx_reload(cx_dev);
 		break;
 	case 3:
@@ -537,7 +541,7 @@
 	bus_unregister(&tiocx_bus_type);
 }
 
-module_init(tiocx_init);
+subsys_initcall(tiocx_init);
 module_exit(tiocx_exit);
 
 /************************************************************************
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c
index 8dae9eb..05aa8c2f 100644
--- a/arch/ia64/sn/pci/tioca_provider.c
+++ b/arch/ia64/sn/pci/tioca_provider.c
@@ -336,7 +336,7 @@
 	if (!ct_addr)
 		return 0;
 
-	bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffff);
+	bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffffUL);
 	node_upper = ct_addr >> 48;
 
 	if (node_upper > 64) {
@@ -464,7 +464,7 @@
  * For mappings created using the direct modes (64 or 48) there are no
  * resources to release.
  */
-void
+static void
 tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir)
 {
 	int i, entry;
@@ -514,7 +514,7 @@
  * The mapping mode used is based on the devices dma_mask.  As a last resort
  * use the GART mapped mode.
  */
-uint64_t
+static uint64_t
 tioca_dma_map(struct pci_dev *pdev, uint64_t paddr, size_t byte_count)
 {
 	uint64_t mapaddr;
@@ -580,7 +580,7 @@
  * On successful setup, returns the kernel version of tioca_common back to
  * the caller.
  */
-void *
+static void *
 tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft)
 {
 	struct tioca_common *tioca_common;
diff --git a/arch/parisc/configs/712_defconfig b/arch/parisc/configs/712_defconfig
index 872085d..6efaa92 100644
--- a/arch/parisc/configs/712_defconfig
+++ b/arch/parisc/configs/712_defconfig
@@ -506,7 +506,7 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=8
+CONFIG_SERIAL_8250_NR_UARTS=17
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig
index d28ebfa..30fc03e 100644
--- a/arch/parisc/configs/a500_defconfig
+++ b/arch/parisc/configs/a500_defconfig
@@ -662,7 +662,7 @@
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_CS=m
-CONFIG_SERIAL_8250_NR_UARTS=8
+CONFIG_SERIAL_8250_NR_UARTS=17
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
diff --git a/arch/parisc/configs/b180_defconfig b/arch/parisc/configs/b180_defconfig
index 1700d7a..46c9511 100644
--- a/arch/parisc/configs/b180_defconfig
+++ b/arch/parisc/configs/b180_defconfig
@@ -514,7 +514,7 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_NR_UARTS=13
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
diff --git a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig
index b279801..67aca6c 100644
--- a/arch/parisc/configs/c3000_defconfig
+++ b/arch/parisc/configs/c3000_defconfig
@@ -661,7 +661,7 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_NR_UARTS=13
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
diff --git a/arch/parisc/defconfig b/arch/parisc/defconfig
index ebd6301..fdae21c5 100644
--- a/arch/parisc/defconfig
+++ b/arch/parisc/defconfig
@@ -517,7 +517,7 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_NR_UARTS=13
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c
index 4ea7158..ece6a9f 100644
--- a/arch/ppc/8xx_io/enet.c
+++ b/arch/ppc/8xx_io/enet.c
@@ -714,17 +714,25 @@
 	immap->im_ioport.iop_pcdat &= ~PC_ENET_LBK;	/* Disable Loopback */
 #endif	/* PC_ENET_LBK */
 
+#ifdef PE_ENET_TCLK
+	/* Configure port E for TCLK and RCLK.
+	*/
+	cp->cp_pepar |=  (PE_ENET_TCLK | PE_ENET_RCLK);
+	cp->cp_pedir &= ~(PE_ENET_TCLK | PE_ENET_RCLK);
+	cp->cp_peso  &= ~(PE_ENET_TCLK | PE_ENET_RCLK);
+#else
+	/* Configure port A for TCLK and RCLK.
+	*/
+	immap->im_ioport.iop_papar |=  (PA_ENET_TCLK | PA_ENET_RCLK);
+	immap->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);
+#endif
+
 	/* Configure port C pins to enable CLSN and RENA.
 	*/
 	immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
 	immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
 	immap->im_ioport.iop_pcso  |=  (PC_ENET_CLSN | PC_ENET_RENA);
 
-	/* Configure port A for TCLK and RCLK.
-	*/
-	immap->im_ioport.iop_papar |=  (PA_ENET_TCLK | PA_ENET_RCLK);
-	immap->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);
-
 	/* Configure Serial Interface clock routing.
 	 * First, clear all SCC bits to zero, then set the ones we want.
 	 */
@@ -896,14 +904,18 @@
 	/* It is now OK to enable the Ethernet transmitter.
 	 * Unfortunately, there are board implementation differences here.
 	 */
-#if   (!defined (PB_ENET_TENA) &&  defined (PC_ENET_TENA))
+#if   (!defined (PB_ENET_TENA) &&  defined (PC_ENET_TENA) && !defined (PE_ENET_TENA))
 	immap->im_ioport.iop_pcpar |=  PC_ENET_TENA;
 	immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA;
-#elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA))
+#elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA) && !defined (PE_ENET_TENA))
 	cp->cp_pbpar |= PB_ENET_TENA;
 	cp->cp_pbdir |= PB_ENET_TENA;
+#elif ( !defined (PB_ENET_TENA) && !defined (PC_ENET_TENA) && defined (PE_ENET_TENA))
+	cp->cp_pepar |=  PE_ENET_TENA;
+	cp->cp_pedir &= ~PE_ENET_TENA;
+	cp->cp_peso  |=  PE_ENET_TENA;
 #else
-#error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA
+#error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA, PE_ENET_TENA
 #endif
 
 #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
@@ -936,6 +948,29 @@
 	*((volatile uint *)BCSR1) &= ~BCSR1_ETHEN;
 #endif
 
+#ifdef CONFIG_MPC885ADS
+
+	/* Deassert PHY reset and enable the PHY.
+	 */
+	{
+		volatile uint __iomem *bcsr = ioremap(BCSR_ADDR, BCSR_SIZE);
+		uint tmp;
+
+		tmp = in_be32(bcsr + 1 /* BCSR1 */);
+		tmp |= BCSR1_ETHEN;
+		out_be32(bcsr + 1, tmp);
+		tmp = in_be32(bcsr + 4 /* BCSR4 */);
+		tmp |= BCSR4_ETH10_RST;
+		out_be32(bcsr + 4, tmp);
+		iounmap(bcsr);
+	}
+
+	/* On MPC885ADS SCC ethernet PHY defaults to the full duplex mode
+	 * upon reset. SCC is set to half duplex by default. So this
+	 * inconsistency should be better fixed by the software.
+	 */
+#endif
+
 	dev->base_addr = (unsigned long)ep;
 #if 0
 	dev->name = "CPM_ENET";
@@ -969,3 +1004,4 @@
 }
 
 module_init(scc_enet_init);
+
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index a7835cd..23b0d2f 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -284,6 +284,9 @@
 
 menu "Platform options"
 
+config FADS
+	bool
+
 choice
 	prompt "8xx Machine Type"
 	depends on 8xx
@@ -399,8 +402,25 @@
 	  26MB DRAM, 4MB flash, Ethernet, a 16K-gate FPGA, USB, an LCD/video
 	  controller, and two RS232 ports.
 
-config FADS
+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"
diff --git a/arch/ppc/configs/mpc86x_ads_defconfig b/arch/ppc/configs/mpc86x_ads_defconfig
new file mode 100644
index 0000000..f63c6f5
--- /dev/null
+++ b/arch/ppc/configs/mpc86x_ads_defconfig
@@ -0,0 +1,633 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.12-rc4
+# Tue Jun 14 13:36:35 2005
+#
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_PPC=y
+CONFIG_PPC32=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+
+#
+# Code maturity level options
+#
+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_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_BASE_FULL is not set
+CONFIG_FUTEX=y
+# CONFIG_EPOLL is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+# CONFIG_SHMEM is not set
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=1
+
+#
+# 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 is not set
+
+#
+# Processor
+#
+# CONFIG_6xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_POWER3 is not set
+# CONFIG_POWER4 is not set
+CONFIG_8xx=y
+# CONFIG_E500 is not set
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_CPU_FREQ is not set
+CONFIG_EMBEDDEDBOOT=y
+# CONFIG_PM is not set
+CONFIG_NOT_COHERENT_CACHE=y
+
+#
+# Platform options
+#
+CONFIG_FADS=y
+# CONFIG_RPXLITE is not set
+# CONFIG_RPXCLASSIC is not set
+# CONFIG_BSEIP is not set
+# CONFIG_MPC8XXFADS is not set
+CONFIG_MPC86XADS=y
+# CONFIG_TQM823L is not set
+# CONFIG_TQM850L is not set
+# CONFIG_TQM855L is not set
+# CONFIG_TQM860L is not set
+# CONFIG_FPS850L is not set
+# CONFIG_SPD823TS is not set
+# CONFIG_IVMS8 is not set
+# CONFIG_IVML24 is not set
+# CONFIG_SM850 is not set
+# CONFIG_HERMES_PRO is not set
+# CONFIG_IP860 is not set
+# CONFIG_LWMON is not set
+# CONFIG_PCU_E is not set
+# CONFIG_CCM is not set
+# CONFIG_LANTEC is not set
+# CONFIG_MBX is not set
+# CONFIG_WINCEPT is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+# CONFIG_PCI_QSPAN is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_CONSISTENT_START=0xff100000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_BOOT_LOAD=0x00400000
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+# CONFIG_STANDALONE is not set
+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=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 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_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+
+#
+# Macintosh device drivers
+#
+
+#
+# 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 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 is not set
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 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 is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_OAKNET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_CPM=y
+CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_CPM_SCC1 is not set
+# CONFIG_SERIAL_CPM_SCC2 is not set
+# CONFIG_SERIAL_CPM_SCC3 is not set
+# CONFIG_SERIAL_CPM_SCC4 is not set
+CONFIG_SERIAL_CPM_SMC1=y
+# CONFIG_SERIAL_CPM_SMC2 is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM 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_AGP is not set
+# CONFIG_DRM 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
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# 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
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_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_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# MPC8xx CPM Options
+#
+CONFIG_SCC_ENET=y
+CONFIG_SCC1_ENET=y
+# CONFIG_SCC2_ENET is not set
+# CONFIG_SCC3_ENET is not set
+# CONFIG_FEC_ENET is not set
+# CONFIG_ENET_BIG_BUFFERS is not set
+
+#
+# Generic MPC8xx Options
+#
+# CONFIG_8xx_COPYBACK is not set
+# CONFIG_8xx_CPU6 is not set
+CONFIG_NO_UCODE_PATCH=y
+# CONFIG_USB_SOF_UCODE_PATCH is not set
+# CONFIG_I2C_SPI_UCODE_PATCH is not set
+# CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C 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
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/ppc/configs/mpc885ads_defconfig b/arch/ppc/configs/mpc885ads_defconfig
new file mode 100644
index 0000000..016f94d
--- /dev/null
+++ b/arch/ppc/configs/mpc885ads_defconfig
@@ -0,0 +1,622 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.12-rc6
+# Thu Jun  9 21:17:29 2005
+#
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_PPC=y
+CONFIG_PPC32=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+
+#
+# Code maturity level options
+#
+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_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+# 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 is not set
+
+#
+# Processor
+#
+# CONFIG_6xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_POWER3 is not set
+# CONFIG_POWER4 is not set
+CONFIG_8xx=y
+# CONFIG_E500 is not set
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_CPU_FREQ is not set
+CONFIG_EMBEDDEDBOOT=y
+# CONFIG_PM is not set
+CONFIG_NOT_COHERENT_CACHE=y
+
+#
+# Platform options
+#
+# CONFIG_RPXLITE is not set
+# CONFIG_RPXCLASSIC is not set
+# CONFIG_BSEIP is not set
+# CONFIG_FADS is not set
+CONFIG_MPC885ADS=y
+# CONFIG_TQM823L is not set
+# CONFIG_TQM850L is not set
+# CONFIG_TQM855L is not set
+# CONFIG_TQM860L is not set
+# CONFIG_FPS850L is not set
+# CONFIG_SPD823TS is not set
+# CONFIG_IVMS8 is not set
+# CONFIG_IVML24 is not set
+# CONFIG_SM850 is not set
+# CONFIG_HERMES_PRO is not set
+# CONFIG_IP860 is not set
+# CONFIG_LWMON is not set
+# CONFIG_PCU_E is not set
+# CONFIG_CCM is not set
+# CONFIG_LANTEC is not set
+# CONFIG_MBX is not set
+# CONFIG_WINCEPT is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+# CONFIG_PCI_QSPAN is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_CONSISTENT_START=0xff100000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_BOOT_LOAD=0x00400000
+
+#
+# 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 is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+
+#
+# Macintosh device drivers
+#
+
+#
+# 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 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=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_OAKNET 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=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_PPP_DEFLATE=y
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_CPM=y
+CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_CPM_SCC1 is not set
+# CONFIG_SERIAL_CPM_SCC2 is not set
+# CONFIG_SERIAL_CPM_SCC3 is not set
+# CONFIG_SERIAL_CPM_SCC4 is not set
+CONFIG_SERIAL_CPM_SMC1=y
+CONFIG_SERIAL_CPM_SMC2=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM 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_AGP is not set
+# CONFIG_DRM 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
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# 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
+#
+# CONFIG_INFINIBAND 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_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVPTS_FS_XATTR is not set
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_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
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# MPC8xx CPM Options
+#
+CONFIG_SCC_ENET=y
+# CONFIG_SCC1_ENET is not set
+# CONFIG_SCC2_ENET is not set
+CONFIG_SCC3_ENET=y
+# CONFIG_FEC_ENET is not set
+# CONFIG_ENET_BIG_BUFFERS is not set
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+CONFIG_8xx_CPU6=y
+CONFIG_NO_UCODE_PATCH=y
+# CONFIG_USB_SOF_UCODE_PATCH is not set
+# CONFIG_I2C_SPI_UCODE_PATCH is not set
+# CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+
+#
+# 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
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 6d7b92d..70cfb6f 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -1495,7 +1495,7 @@
 		*offset += hose->pci_mem_offset;
 		res_bit = IORESOURCE_MEM;
 	} else {
-		io_offset = (unsigned long)hose->io_base_virt;
+		io_offset = hose->io_base_virt - ___IO_BASE;
 		*offset += io_offset;
 		res_bit = IORESOURCE_IO;
 	}
@@ -1522,7 +1522,7 @@
 
 		/* found it! construct the final physical address */
 		if (mmap_state == pci_mmap_io)
-			*offset += hose->io_base_phys - _IO_BASE;
+			*offset += hose->io_base_phys - io_offset;
 		return rp;
 	}
 
@@ -1739,6 +1739,23 @@
 	return result;
 }
 
+void pci_resource_to_user(const struct pci_dev *dev, int bar,
+			  const struct resource *rsrc,
+			  u64 *start, u64 *end)
+{
+	struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
+	unsigned long offset = 0;
+
+	if (hose == NULL)
+		return;
+
+	if (rsrc->flags & IORESOURCE_IO)
+		offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys;
+
+	*start = rsrc->start + offset;
+	*end = rsrc->end + offset;
+}
+
 void __init
 pci_init_resource(struct resource *res, unsigned long start, unsigned long end,
 		  int flags, char *name)
diff --git a/arch/ppc/kernel/relocate_kernel.S b/arch/ppc/kernel/relocate_kernel.S
index 7ff69c4..9b2ad48 100644
--- a/arch/ppc/kernel/relocate_kernel.S
+++ b/arch/ppc/kernel/relocate_kernel.S
@@ -34,9 +34,9 @@
 
 	mr	r8, r0
 	ori     r8, r8, MSR_RI|MSR_ME
-	mtspr	SRR1, r8
+	mtspr	SPRN_SRR1, r8
 	addi	r8, r4, 1f - relocate_new_kernel
-	mtspr	SRR0, r8
+	mtspr	SPRN_SRR0, r8
 	sync
 	rfi
 
diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
index 7358665..bf4ddca 100644
--- a/arch/ppc/kernel/time.c
+++ b/arch/ppc/kernel/time.c
@@ -89,6 +89,9 @@
 
 extern unsigned long wall_jiffies;
 
+/* used for timezone offset */
+static long timezone_offset;
+
 DEFINE_SPINLOCK(rtc_lock);
 
 EXPORT_SYMBOL(rtc_lock);
@@ -170,7 +173,7 @@
 		     xtime.tv_sec - last_rtc_update >= 659 &&
 		     abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ &&
 		     jiffies - wall_jiffies == 1) {
-		  	if (ppc_md.set_rtc_time(xtime.tv_sec+1 + time_offset) == 0)
+		  	if (ppc_md.set_rtc_time(xtime.tv_sec+1 + timezone_offset) == 0)
 				last_rtc_update = xtime.tv_sec+1;
 			else
 				/* Try again one minute later */
@@ -286,7 +289,7 @@
 	unsigned old_stamp, stamp, elapsed;
 
         if (ppc_md.time_init != NULL)
-                time_offset = ppc_md.time_init();
+                timezone_offset = ppc_md.time_init();
 
 	if (__USE_RTC()) {
 		/* 601 processor: dec counts down by 128 every 128ns */
@@ -331,10 +334,10 @@
 	set_dec(tb_ticks_per_jiffy);
 
 	/* If platform provided a timezone (pmac), we correct the time */
-        if (time_offset) {
-		sys_tz.tz_minuteswest = -time_offset / 60;
+        if (timezone_offset) {
+		sys_tz.tz_minuteswest = -timezone_offset / 60;
 		sys_tz.tz_dsttime = 0;
-		xtime.tv_sec -= time_offset;
+		xtime.tv_sec -= timezone_offset;
         }
         set_normalized_timespec(&wall_to_monotonic,
                                 -xtime.tv_sec, -xtime.tv_nsec);
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c
index ddd2e9a..f761fdf 100644
--- a/arch/ppc/platforms/85xx/mpc8540_ads.c
+++ b/arch/ppc/platforms/85xx/mpc8540_ads.c
@@ -111,8 +111,8 @@
 		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
 	}
 
+	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC);
 	if (pdata) {
-		pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC);
 		pdata->board_flags = 0;
 		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
 		pdata->phyid = 3;
diff --git a/arch/ppc/platforms/fads.h b/arch/ppc/platforms/fads.h
index 632b817..b60c564 100644
--- a/arch/ppc/platforms/fads.h
+++ b/arch/ppc/platforms/fads.h
@@ -3,7 +3,18 @@
  * the Motorola 860T FADS board.  Copied from the MBX stuff.
  *
  * Copyright (c) 1998 Dan Malek (dmalek@jlc.net)
+ *
+ * Added MPC86XADS support.
+ * The MPC86xADS manual says the board "is compatible with the MPC8xxFADS
+ * for SW point of view". This is 99% correct.
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ * 2005 (c) MontaVista Software, Inc.  This file is licensed under the
+ * terms of the GNU General Public License version 2.  This program is licensed
+ * "as is" without any warranty of any kind, whether express or implied.
  */
+
 #ifdef __KERNEL__
 #ifndef __ASM_FADS_H__
 #define __ASM_FADS_H__
@@ -12,18 +23,45 @@
 
 #include <asm/ppcboot.h>
 
+#if defined(CONFIG_MPC86XADS)
+
+/* U-Boot maps BCSR to 0xff080000 */
+#define BCSR_ADDR		((uint)0xff080000)
+
+/* MPC86XADS has one more CPLD and an additional BCSR.
+ */
+#define CFG_PHYDEV_ADDR		((uint)0xff0a0000)
+#define BCSR5			((uint)(CFG_PHYDEV_ADDR + 0x300))
+
+#define BCSR5_T1_RST		0x10
+#define BCSR5_ATM155_RST	0x08
+#define BCSR5_ATM25_RST		0x04
+#define BCSR5_MII1_EN		0x02
+#define BCSR5_MII1_RST		0x01
+
+/* There is no PHY link change interrupt */
+#define PHY_INTERRUPT	(-1)
+
+#else /* FADS */
+
 /* Memory map is configured by the PROM startup.
  * I tried to follow the FADS manual, although the startup PROM
  * dictates this and we simply have to move some of the physical
  * addresses for Linux.
  */
 #define BCSR_ADDR		((uint)0xff010000)
+
+/* PHY link change interrupt */
+#define PHY_INTERRUPT	SIU_IRQ2
+
+#endif /* CONFIG_MPC86XADS */
+
 #define BCSR_SIZE		((uint)(64 * 1024))
-#define	BCSR0			((uint)0xff010000)
-#define	BCSR1			((uint)0xff010004)
-#define	BCSR2			((uint)0xff010008)
-#define	BCSR3			((uint)0xff01000c)
-#define	BCSR4			((uint)0xff010010)
+#define BCSR0			((uint)(BCSR_ADDR + 0x00))
+#define BCSR1			((uint)(BCSR_ADDR + 0x04))
+#define BCSR2			((uint)(BCSR_ADDR + 0x08))
+#define BCSR3			((uint)(BCSR_ADDR + 0x0c))
+#define BCSR4			((uint)(BCSR_ADDR + 0x10))
 
 #define IMAP_ADDR		((uint)0xff000000)
 #define IMAP_SIZE		((uint)(64 * 1024))
@@ -34,8 +72,17 @@
 /* Bits of interest in the BCSRs.
  */
 #define BCSR1_ETHEN		((uint)0x20000000)
+#define BCSR1_IRDAEN		((uint)0x10000000)
 #define BCSR1_RS232EN_1		((uint)0x01000000)
+#define BCSR1_PCCEN		((uint)0x00800000)
+#define BCSR1_PCCVCC0		((uint)0x00400000)
+#define BCSR1_PCCVPP0		((uint)0x00200000)
+#define BCSR1_PCCVPP1		((uint)0x00100000)
+#define BCSR1_PCCVPP_MASK	(BCSR1_PCCVPP0 | BCSR1_PCCVPP1)
 #define BCSR1_RS232EN_2		((uint)0x00040000)
+#define BCSR1_PCCVCC1		((uint)0x00010000)
+#define BCSR1_PCCVCC_MASK	(BCSR1_PCCVCC0 | BCSR1_PCCVCC1)
+
 #define BCSR4_ETHLOOP		((uint)0x80000000)	/* EEST Loopback */
 #define BCSR4_EEFDX		((uint)0x40000000)	/* EEST FDX enable */
 #define BCSR4_FETH_EN		((uint)0x08000000)	/* PHY enable */
@@ -44,14 +91,64 @@
 #define BCSR4_FETHFDE		((uint)0x02000000)	/* PHY FDX advertise */
 #define BCSR4_FETHRST		((uint)0x00200000)	/* PHY Reset */
 
+/* IO_BASE definition for pcmcia.
+ */
+#define _IO_BASE	0x80000000
+#define _IO_BASE_SIZE	0x1000
+
+#ifdef CONFIG_IDE
+#define MAX_HWIFS 1
+#endif
+
 /* Interrupt level assignments.
  */
 #define FEC_INTERRUPT	SIU_LEVEL1	/* FEC interrupt */
-#define PHY_INTERRUPT	SIU_IRQ2	/* PHY link change interrupt */
 
 /* We don't use the 8259.
  */
 #define NR_8259_INTS	0
 
+/* CPM Ethernet through SCC1 or SCC2 */
+
+#ifdef CONFIG_SCC1_ENET		/* Probably 860 variant */
+/* Bits in parallel I/O port registers that have to be set/cleared
+ * to configure the pins for SCC1 use.
+ * TCLK - CLK1, RCLK - CLK2.
+ */
+#define PA_ENET_RXD	((ushort)0x0001)
+#define PA_ENET_TXD	((ushort)0x0002)
+#define PA_ENET_TCLK	((ushort)0x0100)
+#define PA_ENET_RCLK	((ushort)0x0200)
+#define PB_ENET_TENA	((uint)0x00001000)
+#define PC_ENET_CLSN	((ushort)0x0010)
+#define PC_ENET_RENA	((ushort)0x0020)
+
+/* Control bits in the SICR to route TCLK (CLK1) and RCLK (CLK2) to
+ * SCC1.  Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
+ */
+#define SICR_ENET_MASK	((uint)0x000000ff)
+#define SICR_ENET_CLKRT	((uint)0x0000002c)
+#endif /* CONFIG_SCC1_ENET */
+
+#ifdef CONFIG_SCC2_ENET		/* Probably 823/850 variant */
+/* Bits in parallel I/O port registers that have to be set/cleared
+ * to configure the pins for SCC1 use.
+ * TCLK - CLK1, RCLK - CLK2.
+ */
+#define PA_ENET_RXD	((ushort)0x0004)
+#define PA_ENET_TXD	((ushort)0x0008)
+#define PA_ENET_TCLK	((ushort)0x0400)
+#define PA_ENET_RCLK	((ushort)0x0200)
+#define PB_ENET_TENA	((uint)0x00002000)
+#define PC_ENET_CLSN	((ushort)0x0040)
+#define PC_ENET_RENA	((ushort)0x0080)
+
+/* Control bits in the SICR to route TCLK and RCLK to
+ * SCC2.  Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
+ */
+#define SICR_ENET_MASK	((uint)0x0000ff00)
+#define SICR_ENET_CLKRT	((uint)0x00002e00)
+#endif /* CONFIG_SCC2_ENET */
+
 #endif /* __ASM_FADS_H__ */
 #endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/mpc885ads.h b/arch/ppc/platforms/mpc885ads.h
new file mode 100644
index 0000000..eb38663
--- /dev/null
+++ b/arch/ppc/platforms/mpc885ads.h
@@ -0,0 +1,92 @@
+/*
+ * A collection of structures, addresses, and values associated with
+ * the Freescale MPC885ADS board.
+ * Copied from the FADS stuff.
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * 2005 (c) MontaVista Software, Inc.  This file is licensed under the
+ * terms of the GNU General Public License version 2.  This program is licensed
+ * "as is" without any warranty of any kind, whether express or implied.
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_MPC885ADS_H__
+#define __ASM_MPC885ADS_H__
+
+#include <linux/config.h>
+
+#include <asm/ppcboot.h>
+
+/* U-Boot maps BCSR to 0xff080000 */
+#define BCSR_ADDR		((uint)0xff080000)
+#define BCSR_SIZE		((uint)32)
+#define BCSR0			((uint)(BCSR_ADDR + 0x00))
+#define BCSR1			((uint)(BCSR_ADDR + 0x04))
+#define BCSR2			((uint)(BCSR_ADDR + 0x08))
+#define BCSR3			((uint)(BCSR_ADDR + 0x0c))
+#define BCSR4			((uint)(BCSR_ADDR + 0x10))
+
+#define CFG_PHYDEV_ADDR		((uint)0xff0a0000)
+#define BCSR5			((uint)(CFG_PHYDEV_ADDR + 0x300))
+
+#define IMAP_ADDR		((uint)0xff000000)
+#define IMAP_SIZE		((uint)(64 * 1024))
+
+#define PCMCIA_MEM_ADDR		((uint)0xff020000)
+#define PCMCIA_MEM_SIZE		((uint)(64 * 1024))
+
+/* Bits of interest in the BCSRs.
+ */
+#define BCSR1_ETHEN		((uint)0x20000000)
+#define BCSR1_IRDAEN		((uint)0x10000000)
+#define BCSR1_RS232EN_1		((uint)0x01000000)
+#define BCSR1_PCCEN		((uint)0x00800000)
+#define BCSR1_PCCVCC0		((uint)0x00400000)
+#define BCSR1_PCCVPP0		((uint)0x00200000)
+#define BCSR1_PCCVPP1		((uint)0x00100000)
+#define BCSR1_PCCVPP_MASK	(BCSR1_PCCVPP0 | BCSR1_PCCVPP1)
+#define BCSR1_RS232EN_2		((uint)0x00040000)
+#define BCSR1_PCCVCC1		((uint)0x00010000)
+#define BCSR1_PCCVCC_MASK	(BCSR1_PCCVCC0 | BCSR1_PCCVCC1)
+
+#define BCSR4_ETH10_RST		((uint)0x80000000)	/* 10Base-T PHY reset*/
+#define BCSR4_USB_LO_SPD	((uint)0x04000000)
+#define BCSR4_USB_VCC		((uint)0x02000000)
+#define BCSR4_USB_FULL_SPD	((uint)0x00040000)
+#define BCSR4_USB_EN		((uint)0x00020000)
+
+#define BCSR5_MII2_EN		0x40
+#define BCSR5_MII2_RST		0x20
+#define BCSR5_T1_RST		0x10
+#define BCSR5_ATM155_RST	0x08
+#define BCSR5_ATM25_RST		0x04
+#define BCSR5_MII1_EN		0x02
+#define BCSR5_MII1_RST		0x01
+
+/* Interrupt level assignments */
+#define PHY_INTERRUPT	SIU_IRQ7	/* PHY link change interrupt */
+#define SIU_INT_FEC1	SIU_LEVEL1	/* FEC1 interrupt */
+#define SIU_INT_FEC2	SIU_LEVEL3	/* FEC2 interrupt */
+#define FEC_INTERRUPT	SIU_INT_FEC1	/* FEC interrupt */
+
+/* We don't use the 8259 */
+#define NR_8259_INTS	0
+
+/* CPM Ethernet through SCC3 */
+#define PA_ENET_RXD	((ushort)0x0040)
+#define PA_ENET_TXD	((ushort)0x0080)
+#define PE_ENET_TCLK	((uint)0x00004000)
+#define PE_ENET_RCLK	((uint)0x00008000)
+#define PE_ENET_TENA	((uint)0x00000010)
+#define PC_ENET_CLSN	((ushort)0x0400)
+#define PC_ENET_RENA	((ushort)0x0800)
+
+/* Control bits in the SICR to route TCLK (CLK5) and RCLK (CLK6) to
+ * SCC3.  Also, make sure GR3 (bit 8) and SC3 (bit 9) are zero */
+#define SICR_ENET_MASK	((uint)0x00ff0000)
+#define SICR_ENET_CLKRT	((uint)0x002c0000)
+
+#endif /* __ASM_MPC885ADS_H__ */
+#endif /* __KERNEL__ */
diff --git a/arch/ppc/syslib/of_device.c b/arch/ppc/syslib/of_device.c
index 49c0e34..1eb4f72 100644
--- a/arch/ppc/syslib/of_device.c
+++ b/arch/ppc/syslib/of_device.c
@@ -3,6 +3,7 @@
 #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>
 
@@ -15,20 +16,20 @@
  * Used by a driver to check whether an of_device present in the
  * system is in its list of supported devices.
  */
-const struct of_match * of_match_device(const struct of_match *matches,
+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 || matches->type || matches->compatible) {
+	while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
 		int match = 1;
-		if (matches->name && matches->name != OF_ANY_MATCH)
+		if (matches->name[0])
 			match &= dev->node->name
 				&& !strcmp(matches->name, dev->node->name);
-		if (matches->type && matches->type != OF_ANY_MATCH)
+		if (matches->type[0])
 			match &= dev->node->type
 				&& !strcmp(matches->type, dev->node->type);
-		if (matches->compatible && matches->compatible != OF_ANY_MATCH)
+		if (matches->compatible[0])
 			match &= device_is_compatible(dev->node,
 				matches->compatible);
 		if (match)
@@ -42,7 +43,7 @@
 {
 	struct of_device * of_dev = to_of_device(dev);
 	struct of_platform_driver * of_drv = to_of_platform_driver(drv);
-	const struct of_match * matches = of_drv->match_table;
+	const struct of_device_id * matches = of_drv->match_table;
 
 	if (!matches)
 		return 0;
@@ -75,7 +76,7 @@
 	int error = -ENODEV;
 	struct of_platform_driver *drv;
 	struct of_device *of_dev;
-	const struct of_match *match;
+	const struct of_device_id *match;
 
 	drv = to_of_platform_driver(dev->driver);
 	of_dev = to_of_device(dev);
diff --git a/arch/ppc/syslib/ppc4xx_pic.c b/arch/ppc/syslib/ppc4xx_pic.c
index 05686fa..4008621 100644
--- a/arch/ppc/syslib/ppc4xx_pic.c
+++ b/arch/ppc/syslib/ppc4xx_pic.c
@@ -110,6 +110,10 @@
 
 static void __init ppc4xx_pic_impl_init(void)
 {
+#if defined(CONFIG_440GX)
+	/* Disable 440GP compatibility mode if it was enabled in firmware */
+	SDR_WRITE(DCRN_SDR_MFR, SDR_READ(DCRN_SDR_MFR) & ~DCRN_SDR_MFR_PCM);
+#endif
 	/* Configure Base UIC */
 	mtdcr(DCRN_UIC_CR(UICB), 0);
 	mtdcr(DCRN_UIC_TR(UICB), 0);
diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile
index d3e1d6a..683b2d4 100644
--- a/arch/ppc64/boot/Makefile
+++ b/arch/ppc64/boot/Makefile
@@ -52,7 +52,7 @@
 src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section)))
 gz-sec  = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section)))
 
-hostprogs-y		:= piggy addnote addRamDisk
+hostprogs-y		:= addnote addRamDisk
 targets 		+= zImage zImage.initrd imagesize.c \
 			   $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
 			   $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
@@ -78,9 +78,6 @@
 quiet_cmd_addnote = ADDNOTE $@ 
       cmd_addnote = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(obj-boot) && $(obj)/addnote $@
 
-quiet_cmd_piggy = PIGGY   $@
-      cmd_piggy = $(obj)/piggyback $(@:.o=) < $< | $(CROSS32AS) -o $@
-
 $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE
 	$(call if_changed,gzip)
 
diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c
index da12ea2..199d980 100644
--- a/arch/ppc64/boot/main.c
+++ b/arch/ppc64/boot/main.c
@@ -17,7 +17,6 @@
 
 extern void *finddevice(const char *);
 extern int getprop(void *, const char *, void *, int);
-extern void printk(char *fmt, ...);
 extern void printf(const char *fmt, ...);
 extern int sprintf(char *buf, const char *fmt, ...);
 void gunzip(void *, int, unsigned char *, int *);
@@ -147,10 +146,10 @@
 		}
 		a1 = initrd.addr;
 		a2 = initrd.size;
-		printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r",
+		printf("initial ramdisk moving 0x%lx <- 0x%lx (0x%lx bytes)\n\r",
 		       initrd.addr, (unsigned long)_initrd_start, initrd.size);
 		memmove((void *)initrd.addr, (void *)_initrd_start, initrd.size);
-		printf("initrd head: 0x%lx\n\r", *((u32 *)initrd.addr));
+		printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd.addr));
 	}
 
 	/* Eventually gunzip the kernel */
@@ -201,9 +200,6 @@
 
 	flush_cache((void *)vmlinux.addr, vmlinux.size);
 
-	if (a1)
-		printf("initrd head: 0x%lx\n\r", *((u32 *)initrd.addr));
-
 	kernel_entry = (kernel_entry_t)vmlinux.addr;
 #ifdef DEBUG
 	printf( "kernel:\n\r"
diff --git a/arch/ppc64/boot/mknote.c b/arch/ppc64/boot/mknote.c
deleted file mode 100644
index 120cc1d..0000000
--- a/arch/ppc64/boot/mknote.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) Cort Dougan 1999.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Generate a note section as per the CHRP specification.
- *
- */
-
-#include <stdio.h>
-
-#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff );
-
-int main(void)
-{
-/* header */
-	/* namesz */
-	PL(strlen("PowerPC")+1);
-	/* descrsz */
-	PL(6*4);
-	/* type */
-	PL(0x1275);
-	/* name */
-	printf("PowerPC"); printf("%c", 0);
-	
-/* descriptor */
-	/* real-mode */
-	PL(0xffffffff);
-	/* real-base */
-	PL(0x00c00000);
-	/* real-size */
-	PL(0xffffffff);
-	/* virt-base */
-	PL(0xffffffff);
-	/* virt-size */
-	PL(0xffffffff);
-	/* load-base */
-	PL(0x4000);
-	return 0;
-}
diff --git a/arch/ppc64/boot/piggyback.c b/arch/ppc64/boot/piggyback.c
deleted file mode 100644
index 235c7a8..0000000
--- a/arch/ppc64/boot/piggyback.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2001 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 <stdio.h>
-#include <unistd.h>
-#include <string.h>
-
-extern long ce_exec_config[];
-
-int main(int argc, char *argv[])
-{
-	int i, cnt, pos, len;
-	unsigned int cksum, val;
-	unsigned char *lp;
-	unsigned char buf[8192];
-	char *varname;
-	if (argc != 2)
-	{
-		fprintf(stderr, "usage: %s name <in-file >out-file\n",
-			argv[0]);
-		exit(1);
-	}
-
-	varname = strrchr(argv[1], '/');
-	if (varname)
-		varname++;
-	else
-		varname = argv[1];
-
-	fprintf(stdout, "#\n");
-	fprintf(stdout, "# Miscellaneous data structures:\n");
-	fprintf(stdout, "# WARNING - this file is automatically generated!\n");
-	fprintf(stdout, "#\n");
-	fprintf(stdout, "\n");
-	fprintf(stdout, "\t.data\n");
-	fprintf(stdout, "\t.globl %s_data\n", varname);
-	fprintf(stdout, "%s_data:\n", varname);
-	pos = 0;
-	cksum = 0;
-	while ((len = read(0, buf, sizeof(buf))) > 0)
-	{
-		cnt = 0;
-		lp = (unsigned char *)buf;
-		len = (len + 3) & ~3;  /* Round up to longwords */
-		for (i = 0;  i < len;  i += 4)
-		{
-			if (cnt == 0)
-			{
-				fprintf(stdout, "\t.long\t");
-			}
-			fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
-			val = *(unsigned long *)lp;
-			cksum ^= val;
-			lp += 4;
-			if (++cnt == 4)
-			{
-				cnt = 0;
-				fprintf(stdout, " # %x \n", pos+i-12);
-				fflush(stdout);
-			} else
-			{
-				fprintf(stdout, ",");
-			}
-		}
-		if (cnt)
-		{
-			fprintf(stdout, "0\n");
-		}
-		pos += len;
-	}
-	fprintf(stdout, "\t.globl %s_len\n", varname);
-	fprintf(stdout, "%s_len:\t.long\t0x%x\n", varname, pos);
-	fflush(stdout);
-	fclose(stdout);
-	fprintf(stderr, "cksum = %x\n", cksum);
-	exit(0);
-}
-
diff --git a/arch/ppc64/boot/prom.c b/arch/ppc64/boot/prom.c
index d5218b1..5e48b80 100644
--- a/arch/ppc64/boot/prom.c
+++ b/arch/ppc64/boot/prom.c
@@ -40,7 +40,7 @@
 int getprop(void *phandle, const char *name, void *buf, int buflen);
 void chrpboot(int a1, int a2, void *prom);	/* in main.c */
 
-void printk(char *fmt, ...);
+int printf(char *fmt, ...);
 
 /* there is no convenient header to get this from...  -- paulus */
 extern unsigned long strlen(const char *);
@@ -220,7 +220,7 @@
 		case 1:
 			return ch;
 		case -1:
-			printk("read(stdin) returned -1\r\n");
+			printf("read(stdin) returned -1\r\n");
 			return -1;
 		}
 	}
@@ -627,18 +627,6 @@
 
 static char sprint_buf[1024];
 
-void
-printk(char *fmt, ...)
-{
-	va_list args;
-	int n;
-
-	va_start(args, fmt);
-	n = vsprintf(sprint_buf, fmt, args);
-	va_end(args);
-	write(stdout, sprint_buf, n);
-}
-
 int
 printf(char *fmt, ...)
 {
diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c
index cdea00d..4231861 100644
--- a/arch/ppc64/kernel/ItLpQueue.c
+++ b/arch/ppc64/kernel/ItLpQueue.c
@@ -1,7 +1,7 @@
 /*
  * 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
@@ -11,156 +11,252 @@
 #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>
 
-static __inline__ int set_inUse( struct ItLpQueue * lpQueue )
-{
-	int t;
-	u32 * inUseP = &(lpQueue->xInUseWord);
+/*
+ * 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")));
 
-	__asm__ __volatile__("\n\
-1:	lwarx	%0,0,%2		\n\
-	cmpwi	0,%0,0		\n\
-	li	%0,0		\n\
-	bne-	2f		\n\
-	addi	%0,%0,1		\n\
-	stwcx.	%0,0,%2		\n\
-	bne-	1b		\n\
-2:	eieio"
-	: "=&r" (t), "=m" (lpQueue->xInUseWord)
-	: "r" (inUseP), "m" (lpQueue->xInUseWord)
-	: "cc");
+DEFINE_PER_CPU(unsigned long[HvLpEvent_Type_NumTypes], hvlpevent_counts);
 
-	return t;
-}
-
-static __inline__ void clear_inUse( struct ItLpQueue * lpQueue )
-{
-	lpQueue->xInUseWord = 0;
-}
+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];
-unsigned long ItLpQueueInProcess = 0;
 
-struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue )
+static struct HvLpEvent * get_next_hvlpevent(void)
 {
-	struct HvLpEvent * nextLpEvent = 
-		(struct HvLpEvent *)lpQueue->xSlicCurEventPtr;
-	if ( nextLpEvent->xFlags.xValid ) {
+	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 */
-		lpQueue->xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 +
-				      LpEventAlign ) /
-				      LpEventAlign ) *
-				      LpEventAlign;
+		hvlpevent_queue.xSlicCurEventPtr += ((event->xSizeMinus1 +
+				LpEventAlign) / LpEventAlign) * LpEventAlign;
+
 		/* Wrap to beginning if no room at end */
-		if (lpQueue->xSlicCurEventPtr > lpQueue->xSlicLastValidEventPtr)
-			lpQueue->xSlicCurEventPtr = lpQueue->xSlicEventStackPtr;
+		if (hvlpevent_queue.xSlicCurEventPtr >
+				hvlpevent_queue.xSlicLastValidEventPtr) {
+			hvlpevent_queue.xSlicCurEventPtr =
+				hvlpevent_queue.xSlicEventStackPtr;
+		}
+	} else {
+		event = NULL;
 	}
-	else 
-		nextLpEvent = NULL;
 
-	return nextLpEvent;
+	return event;
 }
 
-int ItLpQueue_isLpIntPending( struct ItLpQueue * lpQueue )
+static unsigned long spread_lpevents = NR_CPUS;
+
+int hvlpevent_is_pending(void)
 {
-	int retval = 0;
-	struct HvLpEvent * nextLpEvent;
-	if ( lpQueue ) {
-		nextLpEvent = (struct HvLpEvent *)lpQueue->xSlicCurEventPtr;
-		retval = nextLpEvent->xFlags.xValid | lpQueue->xPlicOverflowIntPending;
-	}
-	return retval;
+	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;
 }
 
-void ItLpQueue_clearValid( struct HvLpEvent * event )
+static void hvlpevent_clear_valid(struct HvLpEvent * event)
 {
-	/* Clear the valid bit of the event
-	 * Also clear bits within this event that might
-	 * look like valid bits (on 64-byte boundaries)
-   	 */
-	unsigned extra = (( event->xSizeMinus1 + LpEventAlign ) /
-						 LpEventAlign ) - 1;
-	switch ( extra ) {
-	  case 3:
-	   ((struct HvLpEvent*)((char*)event+3*LpEventAlign))->xFlags.xValid=0;
-	  case 2:
-	   ((struct HvLpEvent*)((char*)event+2*LpEventAlign))->xFlags.xValid=0;
-	  case 1:
-	   ((struct HvLpEvent*)((char*)event+1*LpEventAlign))->xFlags.xValid=0;
-	  case 0:
-	   ;	
+	/* 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;
 }
 
-unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs )
+void process_hvlpevents(struct pt_regs *regs)
 {
-	unsigned numIntsProcessed = 0;
-	struct HvLpEvent * nextLpEvent;
+	struct HvLpEvent * event;
 
 	/* If we have recursed, just return */
-	if ( !set_inUse( lpQueue ) )
-		return 0;
-	
-	if (ItLpQueueInProcess == 0)
-		ItLpQueueInProcess = 1;
-	else
-		BUG();
+	if (!spin_trylock(&hvlpevent_queue.lock))
+		return;
 
 	for (;;) {
-		nextLpEvent = ItLpQueue_getNextLpEvent( lpQueue );
-		if ( nextLpEvent ) {
-			/* Count events to return to caller
-			 * and count processed events in lpQueue
- 			 */
-			++numIntsProcessed;
-			lpQueue->xLpIntCount++;		
-			/* Call appropriate handler here, passing 
+		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 
+			 *
+			 *  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 ( nextLpEvent->xType < HvLpEvent_Type_NumTypes )
-				lpQueue->xLpIntCountByType[nextLpEvent->xType]++;
-			if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes &&
-			     lpEventHandler[nextLpEvent->xType] ) 
-				lpEventHandler[nextLpEvent->xType](nextLpEvent, regs);
+			 */
+			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", nextLpEvent->xType );
-			
-			ItLpQueue_clearValid( nextLpEvent );
-		} else if ( lpQueue->xPlicOverflowIntPending )
+				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( lpQueue->xIndex);
+			HvCallEvent_getOverflowLpEvents(hvlpevent_queue.xIndex);
 		else
 			break;
 	}
 
-	ItLpQueueInProcess = 0;
-	mb();
-	clear_inUse( lpQueue );
-
-	get_paca()->lpevent_count += numIntsProcessed;
-
-	return numIntsProcessed;
+	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
index badc5a4..6ffcf67 100644
--- a/arch/ppc64/kernel/LparData.c
+++ b/arch/ppc64/kernel/LparData.c
@@ -28,13 +28,6 @@
 #include <asm/iSeries/IoHriProcessorVpd.h>
 #include <asm/iSeries/ItSpCommArea.h>
 
-/* The LpQueue is used to pass event data from the hypervisor to
- * the partition.  This is where I/O interrupt events are communicated.
- */
-
-/* May be filled in by the hypervisor so cannot end up in the BSS */
-struct ItLpQueue xItLpQueue __attribute__((__section__(".data")));
-
 
 /* The HvReleaseData is the root of the information shared between 
  * the hypervisor and Linux.  
@@ -200,7 +193,7 @@
 		0,0,0,			/* 13 - 15 */
 		sizeof(struct IoHriProcessorVpd),/* 16 length of Proc Vpd */
 		0,0,0,0,0,0,		/* 17 - 22  */
-		sizeof(struct ItLpQueue),/*     23 length of Lp Queue */
+		sizeof(struct hvlpevent_queue),	/* 23 length of Lp Queue */
 		0,0			/* 24 - 25 */
 		},
 	.xSlicVpdAdrs = {			/* VPD addresses */
@@ -218,7 +211,7 @@
 		0,0,0,			/* 13 - 15 */
 		&xIoHriProcessorVpd,	/*      16 Proc Vpd */
 		0,0,0,0,0,0,		/* 17 - 22 */
-		&xItLpQueue,		/*      23 Lp Queue */
+		&hvlpevent_queue,	/*      23 Lp Queue */
 		0,0
 	}
 };
diff --git a/arch/ppc64/kernel/iSeries_proc.c b/arch/ppc64/kernel/iSeries_proc.c
index 356bd99..0fe3116 100644
--- a/arch/ppc64/kernel/iSeries_proc.c
+++ b/arch/ppc64/kernel/iSeries_proc.c
@@ -40,50 +40,6 @@
 }
 core_initcall(iseries_proc_create);
 
-static char *event_types[9] = {
-	"Hypervisor\t\t",
-	"Machine Facilities\t",
-	"Session Manager\t",
-	"SPD I/O\t\t",
-	"Virtual Bus\t\t",
-	"PCI I/O\t\t",
-	"RIO I/O\t\t",
-	"Virtual Lan\t\t",
-	"Virtual I/O\t\t"
-};
-
-static int proc_lpevents_show(struct seq_file *m, void *v)
-{
-	unsigned int i;
-
-	seq_printf(m, "LpEventQueue 0\n");
-	seq_printf(m, "  events processed:\t%lu\n",
-		   (unsigned long)xItLpQueue.xLpIntCount);
-
-	for (i = 0; i < 9; ++i)
-		seq_printf(m, "    %s %10lu\n", event_types[i],
-			   (unsigned long)xItLpQueue.xLpIntCountByType[i]);
-
-	seq_printf(m, "\n  events processed by processor:\n");
-
-	for_each_online_cpu(i)
-		seq_printf(m, "    CPU%02d  %10u\n", i, paca[i].lpevent_count);
-
-	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 unsigned long startTitan = 0;
 static unsigned long startTb = 0;
 
@@ -148,10 +104,6 @@
 {
 	struct proc_dir_entry *e;
 
-	e = create_proc_entry("iSeries/lpevents", S_IFREG|S_IRUGO, NULL);
-	if (e)
-		e->proc_fops = &proc_lpevents_operations;
-
 	e = create_proc_entry("iSeries/titanTod", S_IFREG|S_IRUGO, NULL);
 	if (e)
 		e->proc_fops = &proc_titantod_operations;
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
index 86966ce..b3f770f 100644
--- a/arch/ppc64/kernel/iSeries_setup.c
+++ b/arch/ppc64/kernel/iSeries_setup.c
@@ -24,7 +24,6 @@
 #include <linux/smp.h>
 #include <linux/param.h>
 #include <linux/string.h>
-#include <linux/bootmem.h>
 #include <linux/initrd.h>
 #include <linux/seq_file.h>
 #include <linux/kdev_t.h>
@@ -676,7 +675,6 @@
  */
 static void __init iSeries_setup_arch(void)
 {
-	void *eventStack;
 	unsigned procIx = get_paca()->lppaca.dyn_hv_phys_proc_index;
 
 	/* Add an eye catcher and the systemcfg layout version number */
@@ -685,24 +683,7 @@
 	systemcfg->version.minor = SYSTEMCFG_MINOR;
 
 	/* Setup the Lp Event Queue */
-
-	/* Allocate a page for the Event Stack
-	 * The hypervisor wants 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);
-
-	/* Initialize fields in our Lp Event Queue */
-	xItLpQueue.xSlicEventStackPtr = (char *)eventStack;
-	xItLpQueue.xSlicCurEventPtr = (char *)eventStack;
-	xItLpQueue.xSlicLastValidEventPtr = (char *)eventStack +
-					(LpEventStackSize - LpEventMaxSize);
-	xItLpQueue.xIndex = 0;
+	setup_hvlpevent_queue();
 
 	/* Compute processor frequency */
 	procFreqHz = ((1UL << 34) * 1000000) /
@@ -853,28 +834,6 @@
 
 late_initcall(iSeries_src_init);
 
-static int set_spread_lpevents(char *str)
-{
-	unsigned long i;
-	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)) {
-		for (i = 1; i < val; ++i)
-			paca[i].lpqueue_ptr = paca[0].lpqueue_ptr;
-
-		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);
-
 #ifndef CONFIG_PCI
 void __init iSeries_init_IRQ(void) { }
 #endif
diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c
index bdf13b4..08952c7 100644
--- a/arch/ppc64/kernel/idle.c
+++ b/arch/ppc64/kernel/idle.c
@@ -88,7 +88,7 @@
 
 	while (1) {
 		if (lpaca->lppaca.shared_proc) {
-			if (ItLpQueue_isLpIntPending(lpaca->lpqueue_ptr))
+			if (hvlpevent_is_pending())
 				process_iSeries_events();
 			if (!need_resched())
 				yield_shared_processor();
@@ -100,7 +100,7 @@
 
 				while (!need_resched()) {
 					HMT_medium();
-					if (ItLpQueue_isLpIntPending(lpaca->lpqueue_ptr))
+					if (hvlpevent_is_pending())
 						process_iSeries_events();
 					HMT_low();
 				}
diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c
index 3defc8c..f41afe5 100644
--- a/arch/ppc64/kernel/irq.c
+++ b/arch/ppc64/kernel/irq.c
@@ -66,7 +66,6 @@
 int distribute_irqs = 1;
 int __irq_offset_value;
 int ppc_spurious_interrupts;
-unsigned long lpevent_count;
 u64 ppc64_interrupt_controller;
 
 int show_interrupts(struct seq_file *p, void *v)
@@ -245,7 +244,7 @@
 
 		spin_lock(&desc->lock);
 		if (!noirqdebug)
-			note_interrupt(irq, desc, action_ret);
+			note_interrupt(irq, desc, action_ret, regs);
 		if (likely(!(desc->status & IRQ_PENDING)))
 			break;
 		desc->status &= ~IRQ_PENDING;
@@ -269,7 +268,6 @@
 void do_IRQ(struct pt_regs *regs)
 {
 	struct paca_struct *lpaca;
-	struct ItLpQueue *lpq;
 
 	irq_enter();
 
@@ -295,9 +293,8 @@
 		iSeries_smp_message_recv(regs);
 	}
 #endif /* CONFIG_SMP */
-	lpq = lpaca->lpqueue_ptr;
-	if (lpq && ItLpQueue_isLpIntPending(lpq))
-		lpevent_count += ItLpQueue_process(lpq, regs);
+	if (hvlpevent_is_pending())
+		process_hvlpevents(regs);
 
 	irq_exit();
 
diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c
index 1d2ff6d..a3d5195 100644
--- a/arch/ppc64/kernel/kprobes.c
+++ b/arch/ppc64/kernel/kprobes.c
@@ -444,7 +444,7 @@
 	.pre_handler = trampoline_probe_handler
 };
 
-int __init arch_init(void)
+int __init arch_init_kprobes(void)
 {
 	return register_kprobe(&trampoline_p);
 }
diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c
index d98bebf..ef4a338 100644
--- a/arch/ppc64/kernel/mf.c
+++ b/arch/ppc64/kernel/mf.c
@@ -801,10 +801,8 @@
 		return rc;
 	/* We need to poll here as we are not yet taking interrupts */
 	while (rtc_data.busy) {
-		extern unsigned long lpevent_count;
-		struct ItLpQueue *lpq = get_paca()->lpqueue_ptr;
-		if (lpq && ItLpQueue_isLpIntPending(lpq))
-			lpevent_count += ItLpQueue_process(lpq, NULL);
+		if (hvlpevent_is_pending())
+			process_hvlpevents(NULL);
 	}
 	return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
 }
diff --git a/arch/ppc64/kernel/nvram.c b/arch/ppc64/kernel/nvram.c
index 4e71781..4fb1a9f 100644
--- a/arch/ppc64/kernel/nvram.c
+++ b/arch/ppc64/kernel/nvram.c
@@ -338,9 +338,8 @@
  */
 static int nvram_create_os_partition(void)
 {
-	struct list_head * p;
-	struct nvram_partition *part = NULL;
-	struct nvram_partition *new_part = NULL;
+	struct nvram_partition *part;
+	struct nvram_partition *new_part;
 	struct nvram_partition *free_part = NULL;
 	int seq_init[2] = { 0, 0 };
 	loff_t tmp_index;
@@ -349,8 +348,7 @@
 	
 	/* Find a free partition that will give us the maximum needed size 
 	   If can't find one that will give us the minimum size needed */
-	list_for_each(p, &nvram_part->partition) {
-		part = list_entry(p, struct nvram_partition, partition);
+	list_for_each_entry(part, &nvram_part->partition, partition) {
 		if (part->header.signature != NVRAM_SIG_FREE)
 			continue;
 
diff --git a/arch/ppc64/kernel/of_device.c b/arch/ppc64/kernel/of_device.c
index 66bd5ab7..b80e819 100644
--- a/arch/ppc64/kernel/of_device.c
+++ b/arch/ppc64/kernel/of_device.c
@@ -3,6 +3,7 @@
 #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>
 
@@ -15,20 +16,20 @@
  * Used by a driver to check whether an of_device present in the
  * system is in its list of supported devices.
  */
-const struct of_match * of_match_device(const struct of_match *matches,
+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 || matches->type || matches->compatible) {
+	while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
 		int match = 1;
-		if (matches->name && matches->name != OF_ANY_MATCH)
+		if (matches->name[0])
 			match &= dev->node->name
 				&& !strcmp(matches->name, dev->node->name);
-		if (matches->type && matches->type != OF_ANY_MATCH)
+		if (matches->type[0])
 			match &= dev->node->type
 				&& !strcmp(matches->type, dev->node->type);
-		if (matches->compatible && matches->compatible != OF_ANY_MATCH)
+		if (matches->compatible[0])
 			match &= device_is_compatible(dev->node,
 				matches->compatible);
 		if (match)
@@ -42,7 +43,7 @@
 {
 	struct of_device * of_dev = to_of_device(dev);
 	struct of_platform_driver * of_drv = to_of_platform_driver(drv);
-	const struct of_match * matches = of_drv->match_table;
+	const struct of_device_id * matches = of_drv->match_table;
 
 	if (!matches)
 		return 0;
@@ -75,7 +76,7 @@
 	int error = -ENODEV;
 	struct of_platform_driver *drv;
 	struct of_device *of_dev;
-	const struct of_match *match;
+	const struct of_device_id *match;
 
 	drv = to_of_platform_driver(dev->driver);
 	of_dev = to_of_device(dev);
diff --git a/arch/ppc64/kernel/pacaData.c b/arch/ppc64/kernel/pacaData.c
index a3e0975c..6316188 100644
--- a/arch/ppc64/kernel/pacaData.c
+++ b/arch/ppc64/kernel/pacaData.c
@@ -42,21 +42,7 @@
  * processors.  The processor VPD array needs one entry per physical
  * processor (not thread).
  */
-#ifdef CONFIG_PPC_ISERIES
-#define EXTRA_INITS(number, lpq)					    \
-	.lppaca_ptr = &paca[number].lppaca,				    \
-	.lpqueue_ptr = (lpq),		/* &xItLpQueue, */		    \
-	.reg_save_ptr = &paca[number].reg_save,				    \
-	.reg_save = {							    \
-		.xDesc = 0xd397d9e2,	/* "LpRS" */			    \
-		.xSize = sizeof(struct ItLpRegSave)			    \
-	},
-#else
-#define EXTRA_INITS(number, lpq)
-#endif
-
-#define PACAINITDATA(number,start,lpq,asrr,asrv)			    \
-{									    \
+#define PACA_INIT_COMMON(number, start, asrr, asrv)			    \
 	.lock_token = 0x8000,						    \
 	.paca_index = (number),		/* Paca Index */		    \
 	.default_decr = 0x00ff0000,	/* Initial Decr */		    \
@@ -74,147 +60,79 @@
 		.end_of_quantum = 0xfffffffffffffffful,			    \
 		.slb_count = 64,					    \
 	},								    \
-	EXTRA_INITS((number), (lpq))					    \
+
+#ifdef CONFIG_PPC_ISERIES
+#define PACA_INIT_ISERIES(number)					    \
+	.lppaca_ptr = &paca[number].lppaca,				    \
+	.reg_save_ptr = &paca[number].reg_save,				    \
+	.reg_save = {							    \
+		.xDesc = 0xd397d9e2,	/* "LpRS" */			    \
+		.xSize = sizeof(struct ItLpRegSave)			    \
+	}
+
+#define PACA_INIT(number)						    \
+{									    \
+	PACA_INIT_COMMON(number, 0, 0, 0)				    \
+	PACA_INIT_ISERIES(number)					    \
 }
 
-struct paca_struct paca[] = {
-#ifdef CONFIG_PPC_ISERIES
-	PACAINITDATA( 0, 1, &xItLpQueue, 0, STAB0_VIRT_ADDR),
+#define BOOTCPU_PACA_INIT(number)					    \
+{									    \
+	PACA_INIT_COMMON(number, 1, 0, STAB0_VIRT_ADDR)			    \
+	PACA_INIT_ISERIES(number)					    \
+}
+
 #else
-	PACAINITDATA( 0, 1, NULL, STAB0_PHYS_ADDR, STAB0_VIRT_ADDR),
+#define PACA_INIT(number)						    \
+{									    \
+	PACA_INIT_COMMON(number, 0, 0, 0)				    \
+}
+
+#define BOOTCPU_PACA_INIT(number)					    \
+{									    \
+	PACA_INIT_COMMON(number, 1, STAB0_PHYS_ADDR, STAB0_VIRT_ADDR)	    \
+}
 #endif
+
+struct paca_struct paca[] = {
+	BOOTCPU_PACA_INIT(0),
 #if NR_CPUS > 1
-	PACAINITDATA( 1, 0, NULL, 0, 0),
-	PACAINITDATA( 2, 0, NULL, 0, 0),
-	PACAINITDATA( 3, 0, NULL, 0, 0),
+	PACA_INIT(  1), PACA_INIT(  2), PACA_INIT(  3),
 #if NR_CPUS > 4
-	PACAINITDATA( 4, 0, NULL, 0, 0),
-	PACAINITDATA( 5, 0, NULL, 0, 0),
-	PACAINITDATA( 6, 0, NULL, 0, 0),
-	PACAINITDATA( 7, 0, NULL, 0, 0),
+	PACA_INIT(  4), PACA_INIT(  5), PACA_INIT(  6), PACA_INIT(  7),
 #if NR_CPUS > 8
-	PACAINITDATA( 8, 0, NULL, 0, 0),
-	PACAINITDATA( 9, 0, NULL, 0, 0),
-	PACAINITDATA(10, 0, NULL, 0, 0),
-	PACAINITDATA(11, 0, NULL, 0, 0),
-	PACAINITDATA(12, 0, NULL, 0, 0),
-	PACAINITDATA(13, 0, NULL, 0, 0),
-	PACAINITDATA(14, 0, NULL, 0, 0),
-	PACAINITDATA(15, 0, NULL, 0, 0),
-	PACAINITDATA(16, 0, NULL, 0, 0),
-	PACAINITDATA(17, 0, NULL, 0, 0),
-	PACAINITDATA(18, 0, NULL, 0, 0),
-	PACAINITDATA(19, 0, NULL, 0, 0),
-	PACAINITDATA(20, 0, NULL, 0, 0),
-	PACAINITDATA(21, 0, NULL, 0, 0),
-	PACAINITDATA(22, 0, NULL, 0, 0),
-	PACAINITDATA(23, 0, NULL, 0, 0),
-	PACAINITDATA(24, 0, NULL, 0, 0),
-	PACAINITDATA(25, 0, NULL, 0, 0),
-	PACAINITDATA(26, 0, NULL, 0, 0),
-	PACAINITDATA(27, 0, NULL, 0, 0),
-	PACAINITDATA(28, 0, NULL, 0, 0),
-	PACAINITDATA(29, 0, NULL, 0, 0),
-	PACAINITDATA(30, 0, NULL, 0, 0),
-	PACAINITDATA(31, 0, NULL, 0, 0),
+	PACA_INIT(  8), PACA_INIT(  9), PACA_INIT( 10), PACA_INIT( 11),
+	PACA_INIT( 12), PACA_INIT( 13), PACA_INIT( 14), PACA_INIT( 15),
+	PACA_INIT( 16), PACA_INIT( 17), PACA_INIT( 18), PACA_INIT( 19),
+	PACA_INIT( 20), PACA_INIT( 21), PACA_INIT( 22), PACA_INIT( 23),
+	PACA_INIT( 24), PACA_INIT( 25), PACA_INIT( 26), PACA_INIT( 27),
+	PACA_INIT( 28), PACA_INIT( 29), PACA_INIT( 30), PACA_INIT( 31),
 #if NR_CPUS > 32
-	PACAINITDATA(32, 0, NULL, 0, 0),
-	PACAINITDATA(33, 0, NULL, 0, 0),
-	PACAINITDATA(34, 0, NULL, 0, 0),
-	PACAINITDATA(35, 0, NULL, 0, 0),
-	PACAINITDATA(36, 0, NULL, 0, 0),
-	PACAINITDATA(37, 0, NULL, 0, 0),
-	PACAINITDATA(38, 0, NULL, 0, 0),
-	PACAINITDATA(39, 0, NULL, 0, 0),
-	PACAINITDATA(40, 0, NULL, 0, 0),
-	PACAINITDATA(41, 0, NULL, 0, 0),
-	PACAINITDATA(42, 0, NULL, 0, 0),
-	PACAINITDATA(43, 0, NULL, 0, 0),
-	PACAINITDATA(44, 0, NULL, 0, 0),
-	PACAINITDATA(45, 0, NULL, 0, 0),
-	PACAINITDATA(46, 0, NULL, 0, 0),
-	PACAINITDATA(47, 0, NULL, 0, 0),
-	PACAINITDATA(48, 0, NULL, 0, 0),
-	PACAINITDATA(49, 0, NULL, 0, 0),
-	PACAINITDATA(50, 0, NULL, 0, 0),
-	PACAINITDATA(51, 0, NULL, 0, 0),
-	PACAINITDATA(52, 0, NULL, 0, 0),
-	PACAINITDATA(53, 0, NULL, 0, 0),
-	PACAINITDATA(54, 0, NULL, 0, 0),
-	PACAINITDATA(55, 0, NULL, 0, 0),
-	PACAINITDATA(56, 0, NULL, 0, 0),
-	PACAINITDATA(57, 0, NULL, 0, 0),
-	PACAINITDATA(58, 0, NULL, 0, 0),
-	PACAINITDATA(59, 0, NULL, 0, 0),
-	PACAINITDATA(60, 0, NULL, 0, 0),
-	PACAINITDATA(61, 0, NULL, 0, 0),
-	PACAINITDATA(62, 0, NULL, 0, 0),
-	PACAINITDATA(63, 0, NULL, 0, 0),
+	PACA_INIT( 32), PACA_INIT( 33), PACA_INIT( 34), PACA_INIT( 35),
+	PACA_INIT( 36), PACA_INIT( 37), PACA_INIT( 38), PACA_INIT( 39),
+	PACA_INIT( 40), PACA_INIT( 41), PACA_INIT( 42), PACA_INIT( 43),
+	PACA_INIT( 44), PACA_INIT( 45), PACA_INIT( 46), PACA_INIT( 47),
+	PACA_INIT( 48), PACA_INIT( 49), PACA_INIT( 50), PACA_INIT( 51),
+	PACA_INIT( 52), PACA_INIT( 53), PACA_INIT( 54), PACA_INIT( 55),
+	PACA_INIT( 56), PACA_INIT( 57), PACA_INIT( 58), PACA_INIT( 59),
+	PACA_INIT( 60), PACA_INIT( 61), PACA_INIT( 62), PACA_INIT( 63),
 #if NR_CPUS > 64
-	PACAINITDATA(64, 0, NULL, 0, 0),
-	PACAINITDATA(65, 0, NULL, 0, 0),
-	PACAINITDATA(66, 0, NULL, 0, 0),
-	PACAINITDATA(67, 0, NULL, 0, 0),
-	PACAINITDATA(68, 0, NULL, 0, 0),
-	PACAINITDATA(69, 0, NULL, 0, 0),
-	PACAINITDATA(70, 0, NULL, 0, 0),
-	PACAINITDATA(71, 0, NULL, 0, 0),
-	PACAINITDATA(72, 0, NULL, 0, 0),
-	PACAINITDATA(73, 0, NULL, 0, 0),
-	PACAINITDATA(74, 0, NULL, 0, 0),
-	PACAINITDATA(75, 0, NULL, 0, 0),
-	PACAINITDATA(76, 0, NULL, 0, 0),
-	PACAINITDATA(77, 0, NULL, 0, 0),
-	PACAINITDATA(78, 0, NULL, 0, 0),
-	PACAINITDATA(79, 0, NULL, 0, 0),
-	PACAINITDATA(80, 0, NULL, 0, 0),
-	PACAINITDATA(81, 0, NULL, 0, 0),
-	PACAINITDATA(82, 0, NULL, 0, 0),
-	PACAINITDATA(83, 0, NULL, 0, 0),
-	PACAINITDATA(84, 0, NULL, 0, 0),
-	PACAINITDATA(85, 0, NULL, 0, 0),
-	PACAINITDATA(86, 0, NULL, 0, 0),
-	PACAINITDATA(87, 0, NULL, 0, 0),
-	PACAINITDATA(88, 0, NULL, 0, 0),
-	PACAINITDATA(89, 0, NULL, 0, 0),
-	PACAINITDATA(90, 0, NULL, 0, 0),
-	PACAINITDATA(91, 0, NULL, 0, 0),
-	PACAINITDATA(92, 0, NULL, 0, 0),
-	PACAINITDATA(93, 0, NULL, 0, 0),
-	PACAINITDATA(94, 0, NULL, 0, 0),
-	PACAINITDATA(95, 0, NULL, 0, 0),
-	PACAINITDATA(96, 0, NULL, 0, 0),
-	PACAINITDATA(97, 0, NULL, 0, 0),
-	PACAINITDATA(98, 0, NULL, 0, 0),
-	PACAINITDATA(99, 0, NULL, 0, 0),
-	PACAINITDATA(100, 0, NULL, 0, 0),
-	PACAINITDATA(101, 0, NULL, 0, 0),
-	PACAINITDATA(102, 0, NULL, 0, 0),
-	PACAINITDATA(103, 0, NULL, 0, 0),
-	PACAINITDATA(104, 0, NULL, 0, 0),
-	PACAINITDATA(105, 0, NULL, 0, 0),
-	PACAINITDATA(106, 0, NULL, 0, 0),
-	PACAINITDATA(107, 0, NULL, 0, 0),
-	PACAINITDATA(108, 0, NULL, 0, 0),
-	PACAINITDATA(109, 0, NULL, 0, 0),
-	PACAINITDATA(110, 0, NULL, 0, 0),
-	PACAINITDATA(111, 0, NULL, 0, 0),
-	PACAINITDATA(112, 0, NULL, 0, 0),
-	PACAINITDATA(113, 0, NULL, 0, 0),
-	PACAINITDATA(114, 0, NULL, 0, 0),
-	PACAINITDATA(115, 0, NULL, 0, 0),
-	PACAINITDATA(116, 0, NULL, 0, 0),
-	PACAINITDATA(117, 0, NULL, 0, 0),
-	PACAINITDATA(118, 0, NULL, 0, 0),
-	PACAINITDATA(119, 0, NULL, 0, 0),
-	PACAINITDATA(120, 0, NULL, 0, 0),
-	PACAINITDATA(121, 0, NULL, 0, 0),
-	PACAINITDATA(122, 0, NULL, 0, 0),
-	PACAINITDATA(123, 0, NULL, 0, 0),
-	PACAINITDATA(124, 0, NULL, 0, 0),
-	PACAINITDATA(125, 0, NULL, 0, 0),
-	PACAINITDATA(126, 0, NULL, 0, 0),
-	PACAINITDATA(127, 0, NULL, 0, 0),
+	PACA_INIT( 64), PACA_INIT( 65), PACA_INIT( 66), PACA_INIT( 67),
+	PACA_INIT( 68), PACA_INIT( 69), PACA_INIT( 70), PACA_INIT( 71),
+	PACA_INIT( 72), PACA_INIT( 73), PACA_INIT( 74), PACA_INIT( 75),
+	PACA_INIT( 76), PACA_INIT( 77), PACA_INIT( 78), PACA_INIT( 79),
+	PACA_INIT( 80), PACA_INIT( 81), PACA_INIT( 82), PACA_INIT( 83),
+	PACA_INIT( 84), PACA_INIT( 85), PACA_INIT( 86), PACA_INIT( 87),
+	PACA_INIT( 88), PACA_INIT( 89), PACA_INIT( 90), PACA_INIT( 91),
+	PACA_INIT( 92), PACA_INIT( 93), PACA_INIT( 94), PACA_INIT( 95),
+	PACA_INIT( 96), PACA_INIT( 97), PACA_INIT( 98), PACA_INIT( 99),
+	PACA_INIT(100), PACA_INIT(101), PACA_INIT(102), PACA_INIT(103),
+	PACA_INIT(104), PACA_INIT(105), PACA_INIT(106), PACA_INIT(107),
+	PACA_INIT(108), PACA_INIT(109), PACA_INIT(110), PACA_INIT(111),
+	PACA_INIT(112), PACA_INIT(113), PACA_INIT(114), PACA_INIT(115),
+	PACA_INIT(116), PACA_INIT(117), PACA_INIT(118), PACA_INIT(119),
+	PACA_INIT(120), PACA_INIT(121), PACA_INIT(122), PACA_INIT(123),
+	PACA_INIT(124), PACA_INIT(125), PACA_INIT(126), PACA_INIT(127),
 #endif
 #endif
 #endif
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
index 580676f..ae6f579 100644
--- a/arch/ppc64/kernel/pci.c
+++ b/arch/ppc64/kernel/pci.c
@@ -351,7 +351,7 @@
 		*offset += hose->pci_mem_offset;
 		res_bit = IORESOURCE_MEM;
 	} else {
-		io_offset = (unsigned long)hose->io_base_virt;
+		io_offset = (unsigned long)hose->io_base_virt - pci_io_base;
 		*offset += io_offset;
 		res_bit = IORESOURCE_IO;
 	}
@@ -378,7 +378,7 @@
 
 		/* found it! construct the final physical address */
 		if (mmap_state == pci_mmap_io)
-			*offset += hose->io_base_phys - io_offset;
+		       	*offset += hose->io_base_phys - io_offset;
 		return rp;
 	}
 
@@ -944,4 +944,22 @@
 }
 EXPORT_SYMBOL(pci_read_irq_line);
 
+void pci_resource_to_user(const struct pci_dev *dev, int bar,
+			  const struct resource *rsrc,
+			  u64 *start, u64 *end)
+{
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+	unsigned long offset = 0;
+
+	if (hose == NULL)
+		return;
+
+	if (rsrc->flags & IORESOURCE_IO)
+		offset = pci_io_base - (unsigned long)hose->io_base_virt +
+			hose->io_base_phys;
+
+	*start = rsrc->start + offset;
+	*end = rsrc->end + offset;
+}
+
 #endif /* CONFIG_PPC_MULTIPLATFORM */
diff --git a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c
index c8fa656..2f704a2 100644
--- a/arch/ppc64/kernel/sysfs.c
+++ b/arch/ppc64/kernel/sysfs.c
@@ -400,7 +400,12 @@
 		struct cpu *c = &per_cpu(cpu_devices, cpu);
 
 #ifdef CONFIG_NUMA
-		parent = &node_devices[cpu_to_node(cpu)];
+		/* The node to which a cpu belongs can't be known
+		 * until the cpu is made present.
+		 */
+		parent = NULL;
+		if (cpu_present(cpu))
+			parent = &node_devices[cpu_to_node(cpu)];
 #endif
 		/*
 		 * For now, we just see if the system supports making
diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c
index 2a532db..909462e 100644
--- a/arch/ppc64/kernel/time.c
+++ b/arch/ppc64/kernel/time.c
@@ -99,7 +99,6 @@
 struct gettimeofday_struct do_gtod;
 
 extern unsigned long wall_jiffies;
-extern unsigned long lpevent_count;
 extern int smp_tb_synchronized;
 
 extern struct timezone sys_tz;
@@ -367,11 +366,8 @@
 	set_dec(next_dec);
 
 #ifdef CONFIG_PPC_ISERIES
-	{
-		struct ItLpQueue *lpq = lpaca->lpqueue_ptr;
-		if (lpq && ItLpQueue_isLpIntPending(lpq))
-			lpevent_count += ItLpQueue_process(lpq, regs);
-	}
+	if (hvlpevent_is_pending())
+		process_hvlpevents(regs);
 #endif
 
 /* collect purr register values often, for accurate calculations */
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 262e13d..7a117ef 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -270,66 +270,10 @@
 
 source "drivers/Kconfig"
 
-config PRINTER
-	tristate "Parallel printer support"
-	depends on PARPORT
-	---help---
-	  If you intend to attach a printer to the parallel port of your Linux
-	  box (as opposed to using a serial printer; if the connector at the
-	  printer has 9 or 25 holes ["female"], then it's serial), say Y.
-	  Also read the Printing-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  It is possible to share one parallel port among several devices
-	  (e.g. printer and ZIP drive) and it is safe to compile the
-	  corresponding drivers into the kernel.  If you want to compile this
-	  driver as a module however, choose M here and read
-	  <file:Documentation/parport.txt>.  The module will be called lp.
-
-	  If you have several parallel ports, you can specify which ports to
-	  use with the "lp" kernel command line option.  (Try "man bootparam"
-	  or see the documentation of your boot loader (silo) about how to pass
-	  options to the kernel at boot time.)  The syntax of the "lp" command
-	  line option can be found in <file:drivers/char/lp.c>.
-
-	  If you have more than 8 printers, you need to increase the LP_NO
-	  macro in lp.c and the PARPORT_MAX macro in parport.h.
-
-source "mm/Kconfig"
-
-endmenu
-
-source "drivers/base/Kconfig"
-
-source "drivers/video/Kconfig"
-
-source "drivers/mtd/Kconfig"
-
-source "drivers/serial/Kconfig"
-
 if !SUN4
 source "drivers/sbus/char/Kconfig"
 endif
 
-source "drivers/block/Kconfig"
-
-# Don't frighten a common SBus user
-if PCI
-
-source "drivers/ide/Kconfig"
-
-endif
-
-source "drivers/isdn/Kconfig"
-
-source "drivers/scsi/Kconfig"
-
-source "drivers/fc4/Kconfig"
-
-source "drivers/md/Kconfig"
-
-source "net/Kconfig"
-
 # This one must be before the filesystem configs. -DaveM
 
 menu "Unix98 PTY support"
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index e2b050e..d78bc13 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -444,6 +444,24 @@
 	  If you have more than 8 printers, you need to increase the LP_NO
 	  macro in lp.c and the PARPORT_MAX macro in parport.h.
 
+config PPDEV
+	tristate "Support for user-space parallel port device drivers"
+	depends on PARPORT
+	---help---
+	  Saying Y to this adds support for /dev/parport device nodes.  This
+	  is needed for programs that want portable access to the parallel
+	  port, for instance deviceid (which displays Plug-and-Play device
+	  IDs).
+
+	  This is the parallel port equivalent of SCSI generic support (sg).
+	  It is safe to say N to this -- it is not needed for normal printing
+	  or parallel port CD-ROM/disk support.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ppdev.
+
+	  If unsure, say N.
+
 config ENVCTRL
 	tristate "SUNW, envctrl support"
 	depends on PCI
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index eee516a..d3973d8 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -553,13 +553,11 @@
 	sllx		%g3, 5, %g3
 	or		%g2, %lo(ivector_table), %g2
 	add		%g2, %g3, %g3
-	ldx		[%g3 + 0x08], %g2	/* irq_info */
 	ldub		[%g3 + 0x04], %g4	/* pil */
-	brz,pn		%g2, do_ivec_spurious
-	 mov		1, %g2
-
+	mov		1, %g2
 	sllx		%g2, %g4, %g2
 	sllx		%g4, 2, %g4
+
 	lduw		[%g6 + %g4], %g5	/* g5 = irq_work(cpu, pil) */
 	stw		%g5, [%g3 + 0x00]	/* bucket->irq_chain = g5 */
 	stw		%g3, [%g6 + %g4]	/* irq_work(cpu, pil) = bucket */
@@ -567,9 +565,9 @@
 	retry
 do_ivec_xcall:
 	mov		0x50, %g1
-
 	ldxa		[%g1 + %g0] ASI_INTR_R, %g1
 	srl		%g3, 0, %g3
+
 	mov		0x60, %g7
 	ldxa		[%g7 + %g0] ASI_INTR_R, %g7
 	stxa		%g0, [%g0] ASI_INTR_RECEIVE
@@ -581,19 +579,6 @@
 1:	jmpl		%g3, %g0
 	 nop
 
-do_ivec_spurious:
-	stw		%g3, [%g6 + 0x00]	/* irq_work(cpu, 0) = bucket */
-	rdpr		%pstate, %g5
-
-	wrpr		%g5, PSTATE_IG | PSTATE_AG, %pstate
-	sethi		%hi(109f), %g7
-	ba,pt		%xcc, etrap
-109:	 or		%g7, %lo(109b), %g7
-	call		catch_disabled_ivec
-	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 clr		%l6
-
 	.globl		save_alternate_globals
 save_alternate_globals: /* %o0 = save_area */
 	rdpr		%pstate, %o5
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index 4247125..daa2fb9 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -71,31 +71,7 @@
 struct irq_work_struct __irq_work[NR_CPUS];
 #define irq_work(__cpu, __pil)	&(__irq_work[(__cpu)].irq_worklists[(__pil)])
 
-#ifdef CONFIG_PCI
-/* This is a table of physical addresses used to deal with IBF_DMA_SYNC.
- * It is used for PCI only to synchronize DMA transfers with IRQ delivery
- * for devices behind busses other than APB on Sabre systems.
- *
- * Currently these physical addresses are just config space accesses
- * to the command register for that device.
- */
-unsigned long pci_dma_wsync;
-unsigned long dma_sync_reg_table[256];
-unsigned char dma_sync_reg_table_entry = 0;
-#endif
-
-/* This is based upon code in the 32-bit Sparc kernel written mostly by
- * David Redman (djhr@tadpole.co.uk).
- */
-#define MAX_STATIC_ALLOC	4
-static struct irqaction static_irqaction[MAX_STATIC_ALLOC];
-static int static_irq_count;
-
-/* This is exported so that fast IRQ handlers can get at it... -DaveM */
-struct irqaction *irq_action[NR_IRQS+1] = {
-	  NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL,
-	  NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL
-};
+static struct irqaction *irq_action[NR_IRQS+1];
 
 /* This only synchronizes entities which modify IRQ handler
  * state and some selected user-level spots that want to
@@ -241,17 +217,22 @@
  * the CPU %tick register and not by some normal vectored interrupt
  * source.  To handle this special case, we use this dummy INO bucket.
  */
+static struct irq_desc pil0_dummy_desc;
 static struct ino_bucket pil0_dummy_bucket = {
-	0,	/* irq_chain */
-	0,	/* pil */
-	0,	/* pending */
-	0,	/* flags */
-	0,	/* __unused */
-	NULL,	/* irq_info */
-	0UL,	/* iclr */
-	0UL,	/* imap */
+	.irq_info	=	&pil0_dummy_desc,
 };
 
+static void build_irq_error(const char *msg, unsigned int ino, int pil, int inofixup,
+			    unsigned long iclr, unsigned long imap,
+			    struct ino_bucket *bucket)
+{
+	prom_printf("IRQ: INO %04x (%d:%016lx:%016lx) --> "
+		    "(%d:%d:%016lx:%016lx), halting...\n",
+		    ino, bucket->pil, bucket->iclr, bucket->imap,
+		    pil, inofixup, iclr, imap);
+	prom_halt();
+}
+
 unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap)
 {
 	struct ino_bucket *bucket;
@@ -280,28 +261,35 @@
 		prom_halt();
 	}
 
+	bucket = &ivector_table[ino];
+	if (bucket->flags & IBF_ACTIVE)
+		build_irq_error("IRQ: Trying to build active INO bucket.\n",
+				ino, pil, inofixup, iclr, imap, bucket);
+
+	if (bucket->irq_info) {
+		if (bucket->imap != imap || bucket->iclr != iclr)
+			build_irq_error("IRQ: Trying to reinit INO bucket.\n",
+					ino, pil, inofixup, iclr, imap, bucket);
+
+		goto out;
+	}
+
+	bucket->irq_info = kmalloc(sizeof(struct irq_desc), GFP_ATOMIC);
+	if (!bucket->irq_info) {
+		prom_printf("IRQ: Error, kmalloc(irq_desc) failed.\n");
+		prom_halt();
+	}
+	memset(bucket->irq_info, 0, sizeof(struct irq_desc));
+
 	/* Ok, looks good, set it up.  Don't touch the irq_chain or
 	 * the pending flag.
 	 */
-	bucket = &ivector_table[ino];
-	if ((bucket->flags & IBF_ACTIVE) ||
-	    (bucket->irq_info != NULL)) {
-		/* This is a gross fatal error if it happens here. */
-		prom_printf("IRQ: Trying to reinit INO bucket, fatal error.\n");
-		prom_printf("IRQ: Request INO %04x (%d:%d:%016lx:%016lx)\n",
-			    ino, pil, inofixup, iclr, imap);
-		prom_printf("IRQ: Existing (%d:%016lx:%016lx)\n",
-			    bucket->pil, bucket->iclr, bucket->imap);
-		prom_printf("IRQ: Cannot continue, halting...\n");
-		prom_halt();
-	}
 	bucket->imap  = imap;
 	bucket->iclr  = iclr;
 	bucket->pil   = pil;
 	bucket->flags = 0;
 
-	bucket->irq_info = NULL;
-
+out:
 	return __irq(bucket);
 }
 
@@ -319,26 +307,65 @@
 	__asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate));
 }
 
+static int check_irq_sharing(int pil, unsigned long irqflags)
+{
+	struct irqaction *action, *tmp;
+
+	action = *(irq_action + pil);
+	if (action) {
+		if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) {
+			for (tmp = action; tmp->next; tmp = tmp->next)
+				;
+		} else {
+			return -EBUSY;
+		}
+	}
+	return 0;
+}
+
+static void append_irq_action(int pil, struct irqaction *action)
+{
+	struct irqaction **pp = irq_action + pil;
+
+	while (*pp)
+		pp = &((*pp)->next);
+	*pp = action;
+}
+
+static struct irqaction *get_action_slot(struct ino_bucket *bucket)
+{
+	struct irq_desc *desc = bucket->irq_info;
+	int max_irq, i;
+
+	max_irq = 1;
+	if (bucket->flags & IBF_PCI)
+		max_irq = MAX_IRQ_DESC_ACTION;
+	for (i = 0; i < max_irq; i++) {
+		struct irqaction *p = &desc->action[i];
+		u32 mask = (1 << i);
+
+		if (desc->action_active_mask & mask)
+			continue;
+
+		desc->action_active_mask |= mask;
+		return p;
+	}
+	return NULL;
+}
+
 int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
 		unsigned long irqflags, const char *name, void *dev_id)
 {
-	struct irqaction *action, *tmp = NULL;
+	struct irqaction *action;
 	struct ino_bucket *bucket = __bucket(irq);
 	unsigned long flags;
 	int pending = 0;
 
-	if ((bucket != &pil0_dummy_bucket) &&
-	    (bucket < &ivector_table[0] ||
-	     bucket >= &ivector_table[NUM_IVECS])) {
-		unsigned int *caller;
-
-		__asm__ __volatile__("mov %%i7, %0" : "=r" (caller));
-		printk(KERN_CRIT "request_irq: Old style IRQ registry attempt "
-		       "from %p, irq %08x.\n", caller, irq);
+	if (unlikely(!handler))
 		return -EINVAL;
-	}	
-	if (!handler)
-	    return -EINVAL;
+
+	if (unlikely(!bucket->irq_info))
+		return -ENODEV;
 
 	if ((bucket != &pil0_dummy_bucket) && (irqflags & SA_SAMPLE_RANDOM)) {
 		/*
@@ -356,93 +383,20 @@
 
 	spin_lock_irqsave(&irq_action_lock, flags);
 
-	action = *(bucket->pil + irq_action);
-	if (action) {
-		if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ))
-			for (tmp = action; tmp->next; tmp = tmp->next)
-				;
-		else {
-			spin_unlock_irqrestore(&irq_action_lock, flags);
-			return -EBUSY;
-		}
-		action = NULL;		/* Or else! */
+	if (check_irq_sharing(bucket->pil, irqflags)) {
+		spin_unlock_irqrestore(&irq_action_lock, flags);
+		return -EBUSY;
 	}
 
-	/* If this is flagged as statically allocated then we use our
-	 * private struct which is never freed.
-	 */
-	if (irqflags & SA_STATIC_ALLOC) {
-	    if (static_irq_count < MAX_STATIC_ALLOC)
-		action = &static_irqaction[static_irq_count++];
-	    else
-		printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed "
-		       "using kmalloc\n", irq, name);
-	}	
-	if (action == NULL)
-	    action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
-						 GFP_ATOMIC);
-	
+	action = get_action_slot(bucket);
 	if (!action) { 
 		spin_unlock_irqrestore(&irq_action_lock, flags);
 		return -ENOMEM;
 	}
 
-	if (bucket == &pil0_dummy_bucket) {
-		bucket->irq_info = action;
-		bucket->flags |= IBF_ACTIVE;
-	} else {
-		if ((bucket->flags & IBF_ACTIVE) != 0) {
-			void *orig = bucket->irq_info;
-			void **vector = NULL;
-
-			if ((bucket->flags & IBF_PCI) == 0) {
-				printk("IRQ: Trying to share non-PCI bucket.\n");
-				goto free_and_ebusy;
-			}
-			if ((bucket->flags & IBF_MULTI) == 0) {
-				vector = kmalloc(sizeof(void *) * 4, GFP_ATOMIC);
-				if (vector == NULL)
-					goto free_and_enomem;
-
-				/* We might have slept. */
-				if ((bucket->flags & IBF_MULTI) != 0) {
-					int ent;
-
-					kfree(vector);
-					vector = (void **)bucket->irq_info;
-					for(ent = 0; ent < 4; ent++) {
-						if (vector[ent] == NULL) {
-							vector[ent] = action;
-							break;
-						}
-					}
-					if (ent == 4)
-						goto free_and_ebusy;
-				} else {
-					vector[0] = orig;
-					vector[1] = action;
-					vector[2] = NULL;
-					vector[3] = NULL;
-					bucket->irq_info = vector;
-					bucket->flags |= IBF_MULTI;
-				}
-			} else {
-				int ent;
-
-				vector = (void **)orig;
-				for (ent = 0; ent < 4; ent++) {
-					if (vector[ent] == NULL) {
-						vector[ent] = action;
-						break;
-					}
-				}
-				if (ent == 4)
-					goto free_and_ebusy;
-			}
-		} else {
-			bucket->irq_info = action;
-			bucket->flags |= IBF_ACTIVE;
-		}
+	bucket->flags |= IBF_ACTIVE;
+	pending = 0;
+	if (bucket != &pil0_dummy_bucket) {
 		pending = bucket->pending;
 		if (pending)
 			bucket->pending = 0;
@@ -456,10 +410,7 @@
 	put_ino_in_irqaction(action, irq);
 	put_smpaff_in_irqaction(action, CPU_MASK_NONE);
 
-	if (tmp)
-		tmp->next = action;
-	else
-		*(bucket->pil + irq_action) = action;
+	append_irq_action(bucket->pil, action);
 
 	enable_irq(irq);
 
@@ -468,147 +419,103 @@
 		atomic_bucket_insert(bucket);
 		set_softint(1 << bucket->pil);
 	}
+
 	spin_unlock_irqrestore(&irq_action_lock, flags);
-	if ((bucket != &pil0_dummy_bucket) && (!(irqflags & SA_STATIC_ALLOC)))
+
+	if (bucket != &pil0_dummy_bucket)
 		register_irq_proc(__irq_ino(irq));
 
 #ifdef CONFIG_SMP
 	distribute_irqs();
 #endif
 	return 0;
-
-free_and_ebusy:
-	kfree(action);
-	spin_unlock_irqrestore(&irq_action_lock, flags);
-	return -EBUSY;
-
-free_and_enomem:
-	kfree(action);
-	spin_unlock_irqrestore(&irq_action_lock, flags);
-	return -ENOMEM;
 }
 
 EXPORT_SYMBOL(request_irq);
 
+static struct irqaction *unlink_irq_action(unsigned int irq, void *dev_id)
+{
+	struct ino_bucket *bucket = __bucket(irq);
+	struct irqaction *action, **pp;
+
+	pp = irq_action + bucket->pil;
+	action = *pp;
+	if (unlikely(!action))
+		return NULL;
+
+	if (unlikely(!action->handler)) {
+		printk("Freeing free IRQ %d\n", bucket->pil);
+		return NULL;
+	}
+
+	while (action && action->dev_id != dev_id) {
+		pp = &action->next;
+		action = *pp;
+	}
+
+	if (likely(action))
+		*pp = action->next;
+
+	return action;
+}
+
 void free_irq(unsigned int irq, void *dev_id)
 {
 	struct irqaction *action;
-	struct irqaction *tmp = NULL;
+	struct ino_bucket *bucket;
 	unsigned long flags;
-	struct ino_bucket *bucket = __bucket(irq), *bp;
 
-	if ((bucket != &pil0_dummy_bucket) &&
-	    (bucket < &ivector_table[0] ||
-	     bucket >= &ivector_table[NUM_IVECS])) {
-		unsigned int *caller;
-
-		__asm__ __volatile__("mov %%i7, %0" : "=r" (caller));
-		printk(KERN_CRIT "free_irq: Old style IRQ removal attempt "
-		       "from %p, irq %08x.\n", caller, irq);
-		return;
-	}
-	
 	spin_lock_irqsave(&irq_action_lock, flags);
 
-	action = *(bucket->pil + irq_action);
-	if (!action->handler) {
-		printk("Freeing free IRQ %d\n", bucket->pil);
-		return;
-	}
-	if (dev_id) {
-		for ( ; action; action = action->next) {
-			if (action->dev_id == dev_id)
-				break;
-			tmp = action;
-		}
-		if (!action) {
-			printk("Trying to free free shared IRQ %d\n", bucket->pil);
-			spin_unlock_irqrestore(&irq_action_lock, flags);
-			return;
-		}
-	} else if (action->flags & SA_SHIRQ) {
-		printk("Trying to free shared IRQ %d with NULL device ID\n", bucket->pil);
-		spin_unlock_irqrestore(&irq_action_lock, flags);
-		return;
-	}
-
-	if (action->flags & SA_STATIC_ALLOC) {
-		printk("Attempt to free statically allocated IRQ %d (%s)\n",
-		       bucket->pil, action->name);
-		spin_unlock_irqrestore(&irq_action_lock, flags);
-		return;
-	}
-
-	if (action && tmp)
-		tmp->next = action->next;
-	else
-		*(bucket->pil + irq_action) = action->next;
+	action = unlink_irq_action(irq, dev_id);
 
 	spin_unlock_irqrestore(&irq_action_lock, flags);
 
+	if (unlikely(!action))
+		return;
+
 	synchronize_irq(irq);
 
 	spin_lock_irqsave(&irq_action_lock, flags);
 
+	bucket = __bucket(irq);
 	if (bucket != &pil0_dummy_bucket) {
+		struct irq_desc *desc = bucket->irq_info;
 		unsigned long imap = bucket->imap;
-		void **vector, *orig;
-		int ent;
+		int ent, i;
 
-		orig = bucket->irq_info;
-		vector = (void **)orig;
+		for (i = 0; i < MAX_IRQ_DESC_ACTION; i++) {
+			struct irqaction *p = &desc->action[i];
 
-		if ((bucket->flags & IBF_MULTI) != 0) {
-			int other = 0;
-			void *orphan = NULL;
-			for (ent = 0; ent < 4; ent++) {
-				if (vector[ent] == action)
-					vector[ent] = NULL;
-				else if (vector[ent] != NULL) {
-					orphan = vector[ent];
-					other++;
-				}
-			}
-
-			/* Only free when no other shared irq
-			 * uses this bucket.
-			 */
-			if (other) {
-				if (other == 1) {
-					/* Convert back to non-shared bucket. */
-					bucket->irq_info = orphan;
-					bucket->flags &= ~(IBF_MULTI);
-					kfree(vector);
-				}
-				goto out;
-			}
-		} else {
-			bucket->irq_info = NULL;
-		}
-
-		/* This unique interrupt source is now inactive. */
-		bucket->flags &= ~IBF_ACTIVE;
-
-		/* See if any other buckets share this bucket's IMAP
-		 * and are still active.
-		 */
-		for (ent = 0; ent < NUM_IVECS; ent++) {
-			bp = &ivector_table[ent];
-			if (bp != bucket	&&
-			    bp->imap == imap	&&
-			    (bp->flags & IBF_ACTIVE) != 0)
+			if (p == action) {
+				desc->action_active_mask &= ~(1 << i);
 				break;
+			}
 		}
 
-		/* Only disable when no other sub-irq levels of
-		 * the same IMAP are active.
-		 */
-		if (ent == NUM_IVECS)
-			disable_irq(irq);
+		if (!desc->action_active_mask) {
+			/* This unique interrupt source is now inactive. */
+			bucket->flags &= ~IBF_ACTIVE;
+
+			/* See if any other buckets share this bucket's IMAP
+			 * and are still active.
+			 */
+			for (ent = 0; ent < NUM_IVECS; ent++) {
+				struct ino_bucket *bp = &ivector_table[ent];
+				if (bp != bucket	&&
+				    bp->imap == imap	&&
+				    (bp->flags & IBF_ACTIVE) != 0)
+					break;
+			}
+
+			/* Only disable when no other sub-irq levels of
+			 * the same IMAP are active.
+			 */
+			if (ent == NUM_IVECS)
+				disable_irq(irq);
+		}
 	}
 
-out:
-	kfree(action);
 	spin_unlock_irqrestore(&irq_action_lock, flags);
 }
 
@@ -647,99 +554,55 @@
 }
 #endif /* CONFIG_SMP */
 
-void catch_disabled_ivec(struct pt_regs *regs)
+static void process_bucket(int irq, struct ino_bucket *bp, struct pt_regs *regs)
 {
-	int cpu = smp_processor_id();
-	struct ino_bucket *bucket = __bucket(*irq_work(cpu, 0));
+	struct irq_desc *desc = bp->irq_info;
+	unsigned char flags = bp->flags;
+	u32 action_mask, i;
+	int random;
 
-	/* We can actually see this on Ultra/PCI PCI cards, which are bridges
-	 * to other devices.  Here a single IMAP enabled potentially multiple
-	 * unique interrupt sources (which each do have a unique ICLR register.
-	 *
-	 * So what we do is just register that the IVEC arrived, when registered
-	 * for real the request_irq() code will check the bit and signal
-	 * a local CPU interrupt for it.
-	 */
-#if 0
-	printk("IVEC: Spurious interrupt vector (%x) received at (%016lx)\n",
-	       bucket - &ivector_table[0], regs->tpc);
-#endif
-	*irq_work(cpu, 0) = 0;
-	bucket->pending = 1;
-}
+	bp->flags |= IBF_INPROGRESS;
 
-/* Tune this... */
-#define FORWARD_VOLUME		12
-
-#ifdef CONFIG_SMP
-
-static inline void redirect_intr(int cpu, struct ino_bucket *bp)
-{
-	/* Ok, here is what is going on:
-	 * 1) Retargeting IRQs on Starfire is very
-	 *    expensive so just forget about it on them.
-	 * 2) Moving around very high priority interrupts
-	 *    is a losing game.
-	 * 3) If the current cpu is idle, interrupts are
-	 *    useful work, so keep them here.  But do not
-	 *    pass to our neighbour if he is not very idle.
-	 * 4) If sysadmin explicitly asks for directed intrs,
-	 *    Just Do It.
-	 */
-	struct irqaction *ap = bp->irq_info;
-	cpumask_t cpu_mask;
-	unsigned int buddy, ticks;
-
-	cpu_mask = get_smpaff_in_irqaction(ap);
-	cpus_and(cpu_mask, cpu_mask, cpu_online_map);
-	if (cpus_empty(cpu_mask))
-		cpu_mask = cpu_online_map;
-
-	if (this_is_starfire != 0 ||
-	    bp->pil >= 10 || current->pid == 0)
+	if (unlikely(!(flags & IBF_ACTIVE))) {
+		bp->pending = 1;
 		goto out;
-
-	/* 'cpu' is the MID (ie. UPAID), calculate the MID
-	 * of our buddy.
-	 */
-	buddy = cpu + 1;
-	if (buddy >= NR_CPUS)
-		buddy = 0;
-
-	ticks = 0;
-	while (!cpu_isset(buddy, cpu_mask)) {
-		if (++buddy >= NR_CPUS)
-			buddy = 0;
-		if (++ticks > NR_CPUS) {
-			put_smpaff_in_irqaction(ap, CPU_MASK_NONE);
-			goto out;
-		}
 	}
 
-	if (buddy == cpu)
-		goto out;
+	if (desc->pre_handler)
+		desc->pre_handler(bp,
+				  desc->pre_handler_arg1,
+				  desc->pre_handler_arg2);
 
-	/* Voo-doo programming. */
-	if (cpu_data(buddy).idle_volume < FORWARD_VOLUME)
-		goto out;
+	action_mask = desc->action_active_mask;
+	random = 0;
+	for (i = 0; i < MAX_IRQ_DESC_ACTION; i++) {
+		struct irqaction *p = &desc->action[i];
+		u32 mask = (1 << i);
 
-	/* This just so happens to be correct on Cheetah
-	 * at the moment.
-	 */
-	buddy <<= 26;
+		if (!(action_mask & mask))
+			continue;
 
-	/* Push it to our buddy. */
-	upa_writel(buddy | IMAP_VALID, bp->imap);
+		action_mask &= ~mask;
 
+		if (p->handler(__irq(bp), p->dev_id, regs) == IRQ_HANDLED)
+			random |= p->flags;
+
+		if (!action_mask)
+			break;
+	}
+	if (bp->pil != 0) {
+		upa_writel(ICLR_IDLE, bp->iclr);
+		/* Test and add entropy */
+		if (random & SA_SAMPLE_RANDOM)
+			add_interrupt_randomness(irq);
+	}
 out:
-	return;
+	bp->flags &= ~IBF_INPROGRESS;
 }
 
-#endif
-
 void handler_irq(int irq, struct pt_regs *regs)
 {
-	struct ino_bucket *bp, *nbp;
+	struct ino_bucket *bp;
 	int cpu = smp_processor_id();
 
 #ifndef CONFIG_SMP
@@ -757,8 +620,6 @@
 		clear_softint(clr_mask);
 	}
 #else
-	int should_forward = 0;
-
 	clear_softint(1 << irq);
 #endif
 
@@ -773,63 +634,12 @@
 #else
 	bp = __bucket(xchg32(irq_work(cpu, irq), 0));
 #endif
-	for ( ; bp != NULL; bp = nbp) {
-		unsigned char flags = bp->flags;
-		unsigned char random = 0;
+	while (bp) {
+		struct ino_bucket *nbp = __bucket(bp->irq_chain);
 
-		nbp = __bucket(bp->irq_chain);
 		bp->irq_chain = 0;
-
-		bp->flags |= IBF_INPROGRESS;
-
-		if ((flags & IBF_ACTIVE) != 0) {
-#ifdef CONFIG_PCI
-			if ((flags & IBF_DMA_SYNC) != 0) {
-				upa_readl(dma_sync_reg_table[bp->synctab_ent]);
-				upa_readq(pci_dma_wsync);
-			}
-#endif
-			if ((flags & IBF_MULTI) == 0) {
-				struct irqaction *ap = bp->irq_info;
-				int ret;
-
-				ret = ap->handler(__irq(bp), ap->dev_id, regs);
-				if (ret == IRQ_HANDLED)
-					random |= ap->flags;
-			} else {
-				void **vector = (void **)bp->irq_info;
-				int ent;
-				for (ent = 0; ent < 4; ent++) {
-					struct irqaction *ap = vector[ent];
-					if (ap != NULL) {
-						int ret;
-
-						ret = ap->handler(__irq(bp),
-								  ap->dev_id,
-								  regs);
-						if (ret == IRQ_HANDLED)
-							random |= ap->flags;
-					}
-				}
-			}
-			/* Only the dummy bucket lacks IMAP/ICLR. */
-			if (bp->pil != 0) {
-#ifdef CONFIG_SMP
-				if (should_forward) {
-					redirect_intr(cpu, bp);
-					should_forward = 0;
-				}
-#endif
-				upa_writel(ICLR_IDLE, bp->iclr);
-
-				/* Test and add entropy */
-				if (random & SA_SAMPLE_RANDOM)
-					add_interrupt_randomness(irq);
-			}
-		} else
-			bp->pending = 1;
-
-		bp->flags &= ~IBF_INPROGRESS;
+		process_bucket(irq, bp, regs);
+		bp = nbp;
 	}
 	irq_exit();
 }
@@ -959,7 +769,10 @@
 	 */
 	for (level = 1; level < NR_IRQS; level++) {
 		struct irqaction *p = irq_action[level];
-		if (level == 12) continue;
+
+		if (level == 12)
+			continue;
+
 		while(p) {
 			cpu = retarget_one_irq(p, cpu);
 			p = p->next;
@@ -1104,7 +917,8 @@
 			int count, int *eof, void *data)
 {
 	struct ino_bucket *bp = ivector_table + (long)data;
-	struct irqaction *ap = bp->irq_info;
+	struct irq_desc *desc = bp->irq_info;
+	struct irqaction *ap = desc->action;
 	cpumask_t mask;
 	int len;
 
@@ -1122,11 +936,13 @@
 static inline void set_intr_affinity(int irq, cpumask_t hw_aff)
 {
 	struct ino_bucket *bp = ivector_table + irq;
+	struct irq_desc *desc = bp->irq_info;
+	struct irqaction *ap = desc->action;
 
 	/* Users specify affinity in terms of hw cpu ids.
 	 * As soon as we do this, handler_irq() might see and take action.
 	 */
-	put_smpaff_in_irqaction((struct irqaction *)bp->irq_info, hw_aff);
+	put_smpaff_in_irqaction(ap, hw_aff);
 
 	/* Migration is simply done by the next cpu to service this
 	 * interrupt.
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index bdac631..bbf11f8 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -433,3 +433,8 @@
 	return 0;
 }
 
+/* architecture specific initialization */
+int arch_init_kprobes(void)
+{
+	return 0;
+}
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 534320e..91ab466 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -1303,8 +1303,7 @@
 {
 	u64 tmp;
 
-	/* PROM sets the IRQ retry value too low, increase it. */
-	psycho_write(p->pbm_A.controller_regs + PSYCHO_IRQ_RETRY, 0xff);
+	psycho_write(p->pbm_A.controller_regs + PSYCHO_IRQ_RETRY, 5);
 
 	/* Enable arbiter for all PCI slots. */
 	tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIA_CTRL);
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index 53d333b..52bf343 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -595,6 +595,23 @@
 	return ret;
 }
 
+/* When a device lives behind a bridge deeper in the PCI bus topology
+ * than APB, a special sequence must run to make sure all pending DMA
+ * transfers at the time of IRQ delivery are visible in the coherency
+ * domain by the cpu.  This sequence is to perform a read on the far
+ * side of the non-APB bridge, then perform a read of Sabre's DMA
+ * write-sync register.
+ */
+static void sabre_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2)
+{
+	struct pci_dev *pdev = _arg1;
+	unsigned long sync_reg = (unsigned long) _arg2;
+	u16 _unused;
+
+	pci_read_config_word(pdev, PCI_VENDOR_ID, &_unused);
+	sabre_read(sync_reg);
+}
+
 static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm,
 					   struct pci_dev *pdev,
 					   unsigned int ino)
@@ -639,24 +656,14 @@
 	if (pdev) {
 		struct pcidev_cookie *pcp = pdev->sysdata;
 
-		/* When a device lives behind a bridge deeper in the
-		 * PCI bus topology than APB, a special sequence must
-		 * run to make sure all pending DMA transfers at the
-		 * time of IRQ delivery are visible in the coherency
-		 * domain by the cpu.  This sequence is to perform
-		 * a read on the far side of the non-APB bridge, then
-		 * perform a read of Sabre's DMA write-sync register.
-		 *
-		 * Currently, the PCI_CONFIG register for the device
-		 * is used for this read from the far side of the bridge.
-		 */
 		if (pdev->bus->number != pcp->pbm->pci_first_busno) {
-			bucket->flags |= IBF_DMA_SYNC;
-			bucket->synctab_ent = dma_sync_reg_table_entry++;
-			dma_sync_reg_table[bucket->synctab_ent] =
-				(unsigned long) sabre_pci_config_mkaddr(
-					pcp->pbm,
-					pdev->bus->number, pdev->devfn, PCI_COMMAND);
+			struct pci_controller_info *p = pcp->pbm->parent;
+			struct irq_desc *d = bucket->irq_info;
+
+			d->pre_handler = sabre_wsync_handler;
+			d->pre_handler_arg1 = pdev;
+			d->pre_handler_arg2 = (void *)
+				p->pbm_A.controller_regs + SABRE_WRSYNC;
 		}
 	}
 	return __irq(bucket);
@@ -1626,10 +1633,9 @@
 	 */
 	p->pbm_A.controller_regs = pr_regs[0].phys_addr;
 	p->pbm_B.controller_regs = pr_regs[0].phys_addr;
-	pci_dma_wsync = p->pbm_A.controller_regs + SABRE_WRSYNC;
 
-	printk("PCI: Found SABRE, main regs at %016lx, wsync at %016lx\n",
-	       p->pbm_A.controller_regs, pci_dma_wsync);
+	printk("PCI: Found SABRE, main regs at %016lx\n",
+	       p->pbm_A.controller_regs);
 
 	/* Clear interrupts */
 
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c
index 5753175..6a182bb 100644
--- a/arch/sparc64/kernel/pci_schizo.c
+++ b/arch/sparc64/kernel/pci_schizo.c
@@ -15,6 +15,7 @@
 #include <asm/iommu.h>
 #include <asm/irq.h>
 #include <asm/upa.h>
+#include <asm/pstate.h>
 
 #include "pci_impl.h"
 #include "iommu_common.h"
@@ -326,6 +327,44 @@
 	return ret;
 }
 
+static void tomatillo_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2)
+{
+	unsigned long sync_reg = (unsigned long) _arg2;
+	u64 mask = 1 << (__irq_ino(__irq(bucket)) & IMAP_INO);
+	u64 val;
+	int limit;
+
+	schizo_write(sync_reg, mask);
+
+	limit = 100000;
+	val = 0;
+	while (--limit) {
+		val = schizo_read(sync_reg);
+		if (!(val & mask))
+			break;
+	}
+	if (limit <= 0) {
+		printk("tomatillo_wsync_handler: DMA won't sync [%lx:%lx]\n",
+		       val, mask);
+	}
+
+	if (_arg1) {
+		static unsigned char cacheline[64]
+			__attribute__ ((aligned (64)));
+
+		__asm__ __volatile__("rd %%fprs, %0\n\t"
+				     "or %0, %4, %1\n\t"
+				     "wr %1, 0x0, %%fprs\n\t"
+				     "stda %%f0, [%5] %6\n\t"
+				     "wr %0, 0x0, %%fprs\n\t"
+				     "membar #Sync"
+				     : "=&r" (mask), "=&r" (val)
+				     : "0" (mask), "1" (val),
+				     "i" (FPRS_FEF), "r" (&cacheline[0]),
+				     "i" (ASI_BLK_COMMIT_P));
+	}
+}
+
 static unsigned int schizo_irq_build(struct pci_pbm_info *pbm,
 				     struct pci_dev *pdev,
 				     unsigned int ino)
@@ -369,6 +408,15 @@
 	bucket = __bucket(build_irq(pil, ign_fixup, iclr, imap));
 	bucket->flags |= IBF_PCI;
 
+	if (pdev && pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) {
+		struct irq_desc *p = bucket->irq_info;
+
+		p->pre_handler = tomatillo_wsync_handler;
+		p->pre_handler_arg1 = ((pbm->chip_version <= 4) ?
+				       (void *) 1 : (void *) 0);
+		p->pre_handler_arg2 = (void *) pbm->sync_reg;
+	}
+
 	return __irq(bucket);
 }
 
@@ -885,6 +933,7 @@
 
 #define SCHIZO_PCI_CTRL		(0x2000UL)
 #define SCHIZO_PCICTRL_BUS_UNUS	(1UL << 63UL) /* Safari */
+#define SCHIZO_PCICTRL_DTO_INT	(1UL << 61UL) /* Tomatillo */
 #define SCHIZO_PCICTRL_ARB_PRIO (0x1ff << 52UL) /* Tomatillo */
 #define SCHIZO_PCICTRL_ESLCK	(1UL << 51UL) /* Safari */
 #define SCHIZO_PCICTRL_ERRSLOT	(7UL << 48UL) /* Safari */
@@ -1887,37 +1936,27 @@
 {
 	u64 tmp;
 
-	/* Set IRQ retry to infinity. */
-	schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY,
-		     SCHIZO_IRQ_RETRY_INF);
+	schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, 5);
 
-	/* Enable arbiter for all PCI slots.  Also, disable PCI interval
-	 * timer so that DTO (Discard TimeOuts) are not reported because
-	 * some Schizo revisions report them erroneously.
-	 */
 	tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_CTRL);
-	if (pbm->chip_type == PBM_CHIP_TYPE_SCHIZO_PLUS &&
-	    pbm->chip_version == 0x5 &&
-	    pbm->chip_revision == 0x1)
-		tmp |= 0x0f;
-	else
-		tmp |= 0xff;
 
-	tmp &= ~SCHIZO_PCICTRL_PTO;
+	/* Enable arbiter for all PCI slots.  */
+	tmp |= 0xff;
+
 	if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO &&
 	    pbm->chip_version >= 0x2)
 		tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT;
-	else
-		tmp |= 0x1UL << SCHIZO_PCICTRL_PTO_SHIFT;
 
 	if (!prom_getbool(pbm->prom_node, "no-bus-parking"))
 		tmp |= SCHIZO_PCICTRL_PARK;
+	else
+		tmp &= ~SCHIZO_PCICTRL_PARK;
 
 	if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO &&
 	    pbm->chip_version <= 0x1)
-		tmp |= (1UL << 61);
+		tmp |= SCHIZO_PCICTRL_DTO_INT;
 	else
-		tmp &= ~(1UL << 61);
+		tmp &= ~SCHIZO_PCICTRL_DTO_INT;
 
 	if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO)
 		tmp |= (SCHIZO_PCICTRL_MRM_PREF |
@@ -2015,6 +2054,9 @@
 	pbm->pbm_regs = pr_regs[0].phys_addr;
 	pbm->controller_regs = pr_regs[1].phys_addr - 0x10000UL;
 
+	if (chip_type == PBM_CHIP_TYPE_TOMATILLO)
+		pbm->sync_reg = pr_regs[3].phys_addr + 0x1a18UL;
+
 	sprintf(pbm->name,
 		(chip_type == PBM_CHIP_TYPE_TOMATILLO ?
 		 "TOMATILLO%d PBM%c" :
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index 71b4e38..b40db38 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -973,7 +973,7 @@
 	int err;
 
 	/* Register IRQ handler. */
-	err = request_irq(build_irq(0, 0, 0UL, 0UL), cfunc, SA_STATIC_ALLOC,
+	err = request_irq(build_irq(0, 0, 0UL, 0UL), cfunc, 0,
 			  "timer", NULL);
 
 	if (err) {
diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S
index 7a2431d..3637708 100644
--- a/arch/sparc64/mm/ultra.S
+++ b/arch/sparc64/mm/ultra.S
@@ -72,6 +72,7 @@
 	flush		%g6
 	retl
 	 wrpr		%g7, 0x0, %pstate
+	nop
 
 	.align		32
 	.globl		__flush_tlb_kernel_range
@@ -249,7 +250,7 @@
 	retl
 	 wrpr		%g7, 0x0, %pstate
 
-__cheetah_flush_tlb_pending:	/* 22 insns */
+__cheetah_flush_tlb_pending:	/* 23 insns */
 	/* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
 	rdpr		%pstate, %g7
 	sllx		%o1, 3, %o1
@@ -317,7 +318,7 @@
 	sethi		%hi(__cheetah_flush_tlb_pending), %o1
 	or		%o1, %lo(__cheetah_flush_tlb_pending), %o1
 	call		cheetah_patch_one
-	 mov		22, %o2
+	 mov		23, %o2
 
 #ifdef DCACHE_ALIASING_POSSIBLE
 	sethi		%hi(__flush_dcache_page), %o0
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile
index 8a73794..4289156 100644
--- a/arch/x86_64/Makefile
+++ b/arch/x86_64/Makefile
@@ -65,7 +65,9 @@
 head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o
 
 libs-y 					+= arch/x86_64/lib/
-core-y					+= arch/x86_64/kernel/ arch/x86_64/mm/
+core-y					+= arch/x86_64/kernel/ \
+					   arch/x86_64/mm/ \
+					   arch/x86_64/crypto/
 core-$(CONFIG_IA32_EMULATION)		+= arch/x86_64/ia32/
 drivers-$(CONFIG_PCI)			+= arch/x86_64/pci/
 drivers-$(CONFIG_OPROFILE)		+= arch/x86_64/oprofile/
diff --git a/arch/x86_64/crypto/Makefile b/arch/x86_64/crypto/Makefile
new file mode 100644
index 0000000..426d20f
--- /dev/null
+++ b/arch/x86_64/crypto/Makefile
@@ -0,0 +1,9 @@
+# 
+# x86_64/crypto/Makefile 
+# 
+# Arch-specific CryptoAPI modules.
+# 
+
+obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o
+
+aes-x86_64-y := aes-x86_64-asm.o aes.o
diff --git a/arch/x86_64/crypto/aes-x86_64-asm.S b/arch/x86_64/crypto/aes-x86_64-asm.S
new file mode 100644
index 0000000..483cbb2
--- /dev/null
+++ b/arch/x86_64/crypto/aes-x86_64-asm.S
@@ -0,0 +1,186 @@
+/* AES (Rijndael) implementation (FIPS PUB 197) for x86_64
+ *
+ * Copyright (C) 2005 Andreas Steinmetz, <ast@domdv.de>
+ *
+ * License:
+ * This code can be distributed under the terms of the GNU General Public
+ * License (GPL) Version 2 provided that the above header down to and
+ * including this sentence is retained in full.
+ */
+
+.extern aes_ft_tab
+.extern aes_it_tab
+.extern aes_fl_tab
+.extern aes_il_tab
+
+.text
+
+#define R1	%rax
+#define R1E	%eax
+#define R1X	%ax
+#define R1H	%ah
+#define R1L	%al
+#define R2	%rbx
+#define R2E	%ebx
+#define R2X	%bx
+#define R2H	%bh
+#define R2L	%bl
+#define R3	%rcx
+#define R3E	%ecx
+#define R3X	%cx
+#define R3H	%ch
+#define R3L	%cl
+#define R4	%rdx
+#define R4E	%edx
+#define R4X	%dx
+#define R4H	%dh
+#define R4L	%dl
+#define R5	%rsi
+#define R5E	%esi
+#define R6	%rdi
+#define R6E	%edi
+#define R7	%rbp
+#define R7E	%ebp
+#define R8	%r8
+#define R9	%r9
+#define R10	%r10
+#define R11	%r11
+
+#define prologue(FUNC,BASE,B128,B192,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11) \
+	.global	FUNC;			\
+	.type	FUNC,@function;		\
+	.align	8;			\
+FUNC:	movq	r1,r2;			\
+	movq	r3,r4;			\
+	leaq	BASE+52(r8),r9;		\
+	movq	r10,r11;		\
+	movl	(r7),r5 ## E;		\
+	movl	4(r7),r1 ## E;		\
+	movl	8(r7),r6 ## E;		\
+	movl	12(r7),r7 ## E;		\
+	movl	(r8),r10 ## E;		\
+	xorl	-48(r9),r5 ## E;	\
+	xorl	-44(r9),r1 ## E;	\
+	xorl	-40(r9),r6 ## E;	\
+	xorl	-36(r9),r7 ## E;	\
+	cmpl	$24,r10 ## E;		\
+	jb	B128;			\
+	leaq	32(r9),r9;		\
+	je	B192;			\
+	leaq	32(r9),r9;
+
+#define epilogue(r1,r2,r3,r4,r5,r6,r7,r8,r9) \
+	movq	r1,r2;			\
+	movq	r3,r4;			\
+	movl	r5 ## E,(r9);		\
+	movl	r6 ## E,4(r9);		\
+	movl	r7 ## E,8(r9);		\
+	movl	r8 ## E,12(r9);		\
+	ret;
+
+#define round(TAB,OFFSET,r1,r2,r3,r4,r5,r6,r7,r8,ra,rb,rc,rd) \
+	movzbl	r2 ## H,r5 ## E;	\
+	movzbl	r2 ## L,r6 ## E;	\
+	movl	TAB+1024(,r5,4),r5 ## E;\
+	movw	r4 ## X,r2 ## X;	\
+	movl	TAB(,r6,4),r6 ## E;	\
+	roll	$16,r2 ## E;		\
+	shrl	$16,r4 ## E;		\
+	movzbl	r4 ## H,r7 ## E;	\
+	movzbl	r4 ## L,r4 ## E;	\
+	xorl	OFFSET(r8),ra ## E;	\
+	xorl	OFFSET+4(r8),rb ## E;	\
+	xorl	TAB+3072(,r7,4),r5 ## E;\
+	xorl	TAB+2048(,r4,4),r6 ## E;\
+	movzbl	r1 ## L,r7 ## E;	\
+	movzbl	r1 ## H,r4 ## E;	\
+	movl	TAB+1024(,r4,4),r4 ## E;\
+	movw	r3 ## X,r1 ## X;	\
+	roll	$16,r1 ## E;		\
+	shrl	$16,r3 ## E;		\
+	xorl	TAB(,r7,4),r5 ## E;	\
+	movzbl	r3 ## H,r7 ## E;	\
+	movzbl	r3 ## L,r3 ## E;	\
+	xorl	TAB+3072(,r7,4),r4 ## E;\
+	xorl	TAB+2048(,r3,4),r5 ## E;\
+	movzbl	r1 ## H,r7 ## E;	\
+	movzbl	r1 ## L,r3 ## E;	\
+	shrl	$16,r1 ## E;		\
+	xorl	TAB+3072(,r7,4),r6 ## E;\
+	movl	TAB+2048(,r3,4),r3 ## E;\
+	movzbl	r1 ## H,r7 ## E;	\
+	movzbl	r1 ## L,r1 ## E;	\
+	xorl	TAB+1024(,r7,4),r6 ## E;\
+	xorl	TAB(,r1,4),r3 ## E;	\
+	movzbl	r2 ## H,r1 ## E;	\
+	movzbl	r2 ## L,r7 ## E;	\
+	shrl	$16,r2 ## E;		\
+	xorl	TAB+3072(,r1,4),r3 ## E;\
+	xorl	TAB+2048(,r7,4),r4 ## E;\
+	movzbl	r2 ## H,r1 ## E;	\
+	movzbl	r2 ## L,r2 ## E;	\
+	xorl	OFFSET+8(r8),rc ## E;	\
+	xorl	OFFSET+12(r8),rd ## E;	\
+	xorl	TAB+1024(,r1,4),r3 ## E;\
+	xorl	TAB(,r2,4),r4 ## E;
+
+#define move_regs(r1,r2,r3,r4) \
+	movl	r3 ## E,r1 ## E;	\
+	movl	r4 ## E,r2 ## E;
+
+#define entry(FUNC,BASE,B128,B192) \
+	prologue(FUNC,BASE,B128,B192,R2,R8,R7,R9,R1,R3,R4,R6,R10,R5,R11)
+
+#define return epilogue(R8,R2,R9,R7,R5,R6,R3,R4,R11)
+
+#define encrypt_round(TAB,OFFSET) \
+	round(TAB,OFFSET,R1,R2,R3,R4,R5,R6,R7,R10,R5,R6,R3,R4) \
+	move_regs(R1,R2,R5,R6)
+
+#define encrypt_final(TAB,OFFSET) \
+	round(TAB,OFFSET,R1,R2,R3,R4,R5,R6,R7,R10,R5,R6,R3,R4)
+
+#define decrypt_round(TAB,OFFSET) \
+	round(TAB,OFFSET,R2,R1,R4,R3,R6,R5,R7,R10,R5,R6,R3,R4) \
+	move_regs(R1,R2,R5,R6)
+
+#define decrypt_final(TAB,OFFSET) \
+	round(TAB,OFFSET,R2,R1,R4,R3,R6,R5,R7,R10,R5,R6,R3,R4)
+
+/* void aes_encrypt(void *ctx, u8 *out, const u8 *in) */
+
+	entry(aes_encrypt,0,enc128,enc192)
+	encrypt_round(aes_ft_tab,-96)
+	encrypt_round(aes_ft_tab,-80)
+enc192:	encrypt_round(aes_ft_tab,-64)
+	encrypt_round(aes_ft_tab,-48)
+enc128:	encrypt_round(aes_ft_tab,-32)
+	encrypt_round(aes_ft_tab,-16)
+	encrypt_round(aes_ft_tab,  0)
+	encrypt_round(aes_ft_tab, 16)
+	encrypt_round(aes_ft_tab, 32)
+	encrypt_round(aes_ft_tab, 48)
+	encrypt_round(aes_ft_tab, 64)
+	encrypt_round(aes_ft_tab, 80)
+	encrypt_round(aes_ft_tab, 96)
+	encrypt_final(aes_fl_tab,112)
+	return
+
+/* void aes_decrypt(void *ctx, u8 *out, const u8 *in) */
+
+	entry(aes_decrypt,240,dec128,dec192)
+	decrypt_round(aes_it_tab,-96)
+	decrypt_round(aes_it_tab,-80)
+dec192:	decrypt_round(aes_it_tab,-64)
+	decrypt_round(aes_it_tab,-48)
+dec128:	decrypt_round(aes_it_tab,-32)
+	decrypt_round(aes_it_tab,-16)
+	decrypt_round(aes_it_tab,  0)
+	decrypt_round(aes_it_tab, 16)
+	decrypt_round(aes_it_tab, 32)
+	decrypt_round(aes_it_tab, 48)
+	decrypt_round(aes_it_tab, 64)
+	decrypt_round(aes_it_tab, 80)
+	decrypt_round(aes_it_tab, 96)
+	decrypt_final(aes_il_tab,112)
+	return
diff --git a/arch/x86_64/crypto/aes.c b/arch/x86_64/crypto/aes.c
new file mode 100644
index 0000000..2b5c401
--- /dev/null
+++ b/arch/x86_64/crypto/aes.c
@@ -0,0 +1,324 @@
+/*
+ * Cryptographic API.
+ *
+ * AES Cipher Algorithm.
+ *
+ * Based on Brian Gladman's code.
+ *
+ * Linux developers:
+ *  Alexander Kjeldaas <astor@fast.no>
+ *  Herbert Valerio Riedel <hvr@hvrlab.org>
+ *  Kyle McMartin <kyle@debian.org>
+ *  Adam J. Richter <adam@yggdrasil.com> (conversion to 2.5 API).
+ *  Andreas Steinmetz <ast@domdv.de> (adapted to x86_64 assembler)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * ---------------------------------------------------------------------------
+ * Copyright (c) 2002, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
+ * All rights reserved.
+ *
+ * LICENSE TERMS
+ *
+ * The free distribution and use of this software in both source and binary
+ * form is allowed (with or without changes) provided that:
+ *
+ *   1. distributions of this source code include the above copyright
+ *      notice, this list of conditions and the following disclaimer;
+ *
+ *   2. distributions in binary form include the above copyright
+ *      notice, this list of conditions and the following disclaimer
+ *      in the documentation and/or other associated materials;
+ *
+ *   3. the copyright holder's name is not used to endorse products
+ *      built using this software without specific written permission.
+ *
+ * ALTERNATIVELY, provided that this notice is retained in full, this product
+ * may be distributed under the terms of the GNU General Public License (GPL),
+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
+ *
+ * DISCLAIMER
+ *
+ * This software is provided 'as is' with no explicit or implied warranties
+ * in respect of its properties, including, but not limited to, correctness
+ * and/or fitness for purpose.
+ * ---------------------------------------------------------------------------
+ */
+
+/* Some changes from the Gladman version:
+    s/RIJNDAEL(e_key)/E_KEY/g
+    s/RIJNDAEL(d_key)/D_KEY/g
+*/
+
+#include <asm/byteorder.h>
+#include <linux/bitops.h>
+#include <linux/crypto.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+
+#define AES_MIN_KEY_SIZE	16
+#define AES_MAX_KEY_SIZE	32
+
+#define AES_BLOCK_SIZE		16
+
+/*
+ * #define byte(x, nr) ((unsigned char)((x) >> (nr*8)))
+ */
+static inline u8 byte(const u32 x, const unsigned n)
+{
+	return x >> (n << 3);
+}
+
+#define u32_in(x) le32_to_cpu(*(const __le32 *)(x))
+
+struct aes_ctx
+{
+	u32 key_length;
+	u32 E[60];
+	u32 D[60];
+};
+
+#define E_KEY ctx->E
+#define D_KEY ctx->D
+
+static u8 pow_tab[256] __initdata;
+static u8 log_tab[256] __initdata;
+static u8 sbx_tab[256] __initdata;
+static u8 isb_tab[256] __initdata;
+static u32 rco_tab[10];
+u32 aes_ft_tab[4][256];
+u32 aes_it_tab[4][256];
+
+u32 aes_fl_tab[4][256];
+u32 aes_il_tab[4][256];
+
+static inline u8 f_mult(u8 a, u8 b)
+{
+	u8 aa = log_tab[a], cc = aa + log_tab[b];
+
+	return pow_tab[cc + (cc < aa ? 1 : 0)];
+}
+
+#define ff_mult(a, b) (a && b ? f_mult(a, b) : 0)
+
+#define ls_box(x)				\
+	(aes_fl_tab[0][byte(x, 0)] ^		\
+	 aes_fl_tab[1][byte(x, 1)] ^		\
+	 aes_fl_tab[2][byte(x, 2)] ^		\
+	 aes_fl_tab[3][byte(x, 3)])
+
+static void __init gen_tabs(void)
+{
+	u32 i, t;
+	u8 p, q;
+
+	/* log and power tables for GF(2**8) finite field with
+	   0x011b as modular polynomial - the simplest primitive
+	   root is 0x03, used here to generate the tables */
+
+	for (i = 0, p = 1; i < 256; ++i) {
+		pow_tab[i] = (u8)p;
+		log_tab[p] = (u8)i;
+
+		p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0);
+	}
+
+	log_tab[1] = 0;
+
+	for (i = 0, p = 1; i < 10; ++i) {
+		rco_tab[i] = p;
+
+		p = (p << 1) ^ (p & 0x80 ? 0x01b : 0);
+	}
+
+	for (i = 0; i < 256; ++i) {
+		p = (i ? pow_tab[255 - log_tab[i]] : 0);
+		q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2));
+		p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2));
+		sbx_tab[i] = p;
+		isb_tab[p] = (u8)i;
+	}
+
+	for (i = 0; i < 256; ++i) {
+		p = sbx_tab[i];
+
+		t = p;
+		aes_fl_tab[0][i] = t;
+		aes_fl_tab[1][i] = rol32(t, 8);
+		aes_fl_tab[2][i] = rol32(t, 16);
+		aes_fl_tab[3][i] = rol32(t, 24);
+
+		t = ((u32)ff_mult(2, p)) |
+		    ((u32)p << 8) |
+		    ((u32)p << 16) | ((u32)ff_mult(3, p) << 24);
+
+		aes_ft_tab[0][i] = t;
+		aes_ft_tab[1][i] = rol32(t, 8);
+		aes_ft_tab[2][i] = rol32(t, 16);
+		aes_ft_tab[3][i] = rol32(t, 24);
+
+		p = isb_tab[i];
+
+		t = p;
+		aes_il_tab[0][i] = t;
+		aes_il_tab[1][i] = rol32(t, 8);
+		aes_il_tab[2][i] = rol32(t, 16);
+		aes_il_tab[3][i] = rol32(t, 24);
+
+		t = ((u32)ff_mult(14, p)) |
+		    ((u32)ff_mult(9, p) << 8) |
+		    ((u32)ff_mult(13, p) << 16) |
+		    ((u32)ff_mult(11, p) << 24);
+
+		aes_it_tab[0][i] = t;
+		aes_it_tab[1][i] = rol32(t, 8);
+		aes_it_tab[2][i] = rol32(t, 16);
+		aes_it_tab[3][i] = rol32(t, 24);
+	}
+}
+
+#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
+
+#define imix_col(y, x)			\
+	u    = star_x(x);		\
+	v    = star_x(u);		\
+	w    = star_x(v);		\
+	t    = w ^ (x);			\
+	(y)  = u ^ v ^ w;		\
+	(y) ^= ror32(u ^ t,  8) ^	\
+	       ror32(v ^ t, 16) ^	\
+	       ror32(t, 24)
+
+/* initialise the key schedule from the user supplied key */
+
+#define loop4(i)					\
+{							\
+	t = ror32(t,  8); t = ls_box(t) ^ rco_tab[i];	\
+	t ^= E_KEY[4 * i];     E_KEY[4 * i + 4] = t;	\
+	t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t;	\
+	t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t;	\
+	t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t;	\
+}
+
+#define loop6(i)					\
+{							\
+	t = ror32(t,  8); t = ls_box(t) ^ rco_tab[i];	\
+	t ^= E_KEY[6 * i];     E_KEY[6 * i + 6] = t;	\
+	t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t;	\
+	t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t;	\
+	t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t;	\
+	t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t;	\
+	t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t;	\
+}
+
+#define loop8(i)					\
+{							\
+	t = ror32(t,  8); ; t = ls_box(t) ^ rco_tab[i];	\
+	t ^= E_KEY[8 * i];     E_KEY[8 * i + 8] = t;	\
+	t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t;	\
+	t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t;	\
+	t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t;	\
+	t  = E_KEY[8 * i + 4] ^ ls_box(t);		\
+	E_KEY[8 * i + 12] = t;				\
+	t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t;	\
+	t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t;	\
+	t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t;	\
+}
+
+static int aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len,
+		       u32 *flags)
+{
+	struct aes_ctx *ctx = ctx_arg;
+	u32 i, j, t, u, v, w;
+
+	if (key_len != 16 && key_len != 24 && key_len != 32) {
+		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+		return -EINVAL;
+	}
+
+	ctx->key_length = key_len;
+
+	D_KEY[key_len + 24] = E_KEY[0] = u32_in(in_key);
+	D_KEY[key_len + 25] = E_KEY[1] = u32_in(in_key + 4);
+	D_KEY[key_len + 26] = E_KEY[2] = u32_in(in_key + 8);
+	D_KEY[key_len + 27] = E_KEY[3] = u32_in(in_key + 12);
+
+	switch (key_len) {
+	case 16:
+		t = E_KEY[3];
+		for (i = 0; i < 10; ++i)
+			loop4(i);
+		break;
+
+	case 24:
+		E_KEY[4] = u32_in(in_key + 16);
+		t = E_KEY[5] = u32_in(in_key + 20);
+		for (i = 0; i < 8; ++i)
+			loop6 (i);
+		break;
+
+	case 32:
+		E_KEY[4] = u32_in(in_key + 16);
+		E_KEY[5] = u32_in(in_key + 20);
+		E_KEY[6] = u32_in(in_key + 24);
+		t = E_KEY[7] = u32_in(in_key + 28);
+		for (i = 0; i < 7; ++i)
+			loop8(i);
+		break;
+	}
+
+	D_KEY[0] = E_KEY[key_len + 24];
+	D_KEY[1] = E_KEY[key_len + 25];
+	D_KEY[2] = E_KEY[key_len + 26];
+	D_KEY[3] = E_KEY[key_len + 27];
+
+	for (i = 4; i < key_len + 24; ++i) {
+		j = key_len + 24 - (i & ~3) + (i & 3);
+		imix_col(D_KEY[j], E_KEY[i]);
+	}
+
+	return 0;
+}
+
+extern void aes_encrypt(void *ctx_arg, u8 *out, const u8 *in);
+extern void aes_decrypt(void *ctx_arg, u8 *out, const u8 *in);
+
+static struct crypto_alg aes_alg = {
+	.cra_name		=	"aes",
+	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
+	.cra_blocksize		=	AES_BLOCK_SIZE,
+	.cra_ctxsize		=	sizeof(struct aes_ctx),
+	.cra_module		=	THIS_MODULE,
+	.cra_list		=	LIST_HEAD_INIT(aes_alg.cra_list),
+	.cra_u			=	{
+		.cipher = {
+			.cia_min_keysize	=	AES_MIN_KEY_SIZE,
+			.cia_max_keysize	=	AES_MAX_KEY_SIZE,
+			.cia_setkey	   	= 	aes_set_key,
+			.cia_encrypt	 	=	aes_encrypt,
+			.cia_decrypt	  	=	aes_decrypt
+		}
+	}
+};
+
+static int __init aes_init(void)
+{
+	gen_tabs();
+	return crypto_register_alg(&aes_alg);
+}
+
+static void __exit aes_fini(void)
+{
+	crypto_unregister_alg(&aes_alg);
+}
+
+module_init(aes_init);
+module_exit(aes_fini);
+
+MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
+MODULE_LICENSE("GPL");
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index 157190d..d206d7e 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -1064,7 +1064,6 @@
 
 void __apicdebuginit print_PIC(void)
 {
-	extern spinlock_t i8259A_lock;
 	unsigned int v;
 	unsigned long flags;
 
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
index acd2a77..5c6dc70 100644
--- a/arch/x86_64/kernel/kprobes.c
+++ b/arch/x86_64/kernel/kprobes.c
@@ -682,7 +682,7 @@
 	.pre_handler = trampoline_probe_handler
 };
 
-int __init arch_init(void)
+int __init arch_init_kprobes(void)
 {
 	return register_kprobe(&trampoline_p);
 }
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c
index b693c23..657e88a 100644
--- a/arch/x86_64/pci/mmconfig.c
+++ b/arch/x86_64/pci/mmconfig.c
@@ -7,25 +7,50 @@
 
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/acpi.h>
 #include "pci.h"
 
 #define MMCONFIG_APER_SIZE (256*1024*1024)
 
-/* The physical address of the MMCONFIG aperture.  Set from ACPI tables. */
-u32 pci_mmcfg_base_addr;
-
 /* Static virtual mapping of the MMCONFIG aperture */
-char *pci_mmcfg_virt;
+struct mmcfg_virt {
+	struct acpi_table_mcfg_config *cfg;
+	char *virt;
+};
+static struct mmcfg_virt *pci_mmcfg_virt;
 
-static inline char *pci_dev_base(unsigned int bus, unsigned int devfn)
+static char *get_virt(unsigned int seg, int bus)
 {
-	return pci_mmcfg_virt + ((bus << 20) | (devfn << 12));
+	int cfg_num = -1;
+	struct acpi_table_mcfg_config *cfg;
+
+	while (1) {
+		++cfg_num;
+		if (cfg_num >= pci_mmcfg_config_num) {
+			/* something bad is going on, no cfg table is found. */
+			/* so we fall back to the old way we used to do this */
+			/* and just rely on the first entry to be correct. */
+			return pci_mmcfg_virt[0].virt;
+		}
+		cfg = pci_mmcfg_virt[cfg_num].cfg;
+		if (cfg->pci_segment_group_number != seg)
+			continue;
+		if ((cfg->start_bus_number <= bus) &&
+		    (cfg->end_bus_number >= bus))
+			return pci_mmcfg_virt[cfg_num].virt;
+	}
+}
+
+static inline char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
+{
+
+	return get_virt(seg, bus) + ((bus << 20) | (devfn << 12));
 }
 
 static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
 			  unsigned int devfn, int reg, int len, u32 *value)
 {
-	char *addr = pci_dev_base(bus, devfn); 
+	char *addr = pci_dev_base(seg, bus, devfn);
 
 	if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095)))
 		return -EINVAL;
@@ -48,7 +73,7 @@
 static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 			   unsigned int devfn, int reg, int len, u32 value)
 {
-	char *addr = pci_dev_base(bus,devfn);
+	char *addr = pci_dev_base(seg, bus, devfn);
 
 	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
 		return -EINVAL;
@@ -75,9 +100,15 @@
 
 static int __init pci_mmcfg_init(void)
 {
+	int i;
+
 	if ((pci_probe & PCI_PROBE_MMCONF) == 0)
 		return 0;
-	if (!pci_mmcfg_base_addr)
+
+	acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
+	if ((pci_mmcfg_config_num == 0) ||
+	    (pci_mmcfg_config == NULL) ||
+	    (pci_mmcfg_config[0].base_address == 0))
 		return 0;
 
 	/* Kludge for now. Don't use mmconfig on AMD systems because
@@ -88,13 +119,22 @@
 		return 0; 
 
 	/* RED-PEN i386 doesn't do _nocache right now */
-	pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_base_addr, MMCONFIG_APER_SIZE);
-	if (!pci_mmcfg_virt) { 
-		printk("PCI: Cannot map mmconfig aperture\n");
+	pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);
+	if (pci_mmcfg_virt == NULL) {
+		printk("PCI: Can not allocate memory for mmconfig structures\n");
 		return 0;
-	}	
+	}
+	for (i = 0; i < pci_mmcfg_config_num; ++i) {
+		pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];
+		pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE);
+		if (!pci_mmcfg_virt[i].virt) {
+			printk("PCI: Cannot map mmconfig aperture for segment %d\n",
+			       pci_mmcfg_config[i].pci_segment_group_number);
+			return 0;
+		}
+		printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[i].base_address);
+	}
 
-	printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_base_addr);
 	raw_pci_ops = &pci_mmcfg;
 	pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
 
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 3e89767..c9b5d29 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -132,7 +132,7 @@
 config GENERIC_CALIBRATE_DELAY
 	bool "Auto calibration of the BogoMIPS value"
 	---help---
-	  The BogoMIPS value can easily derived from the CPU frequency.
+	  The BogoMIPS value can easily be derived from the CPU frequency.
 
 config CMDLINE_BOOL
 	bool "Default bootloader kernel arguments"
@@ -158,6 +158,8 @@
 	depends on XTENSA_PLATFORM_ISS
 	default y
 
+source "mm/Kconfig"
+
 endmenu
 
 menu "Bus options"
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile
index 4fa2745..27847e4 100644
--- a/arch/xtensa/Makefile
+++ b/arch/xtensa/Makefile
@@ -21,23 +21,17 @@
 
 # Platform configuration
 
-platform-y					:= common
 platform-$(CONFIG_XTENSA_PLATFORM_XT2000)	:= xt2000
 platform-$(CONFIG_XTENSA_PLATFORM_ISS)		:= iss
 
 PLATFORM = $(platform-y)
 export PLATFORM
 
-#LDFLAGS_vmlinux		:= -T$(word 1,$(LINKSCRIPT))
-AFLAGS_vmlinux.lds.o	:= -Uxtensa
-CPPFLAGS		+= -Iarch/xtensa -Iinclude/asm  -mlongcalls  -g
-AFLAGS			+= -Iarch/xtensa -Iinclude/asm
-CPP			= $(CC) -E $(CFLAGS)
+CPPFLAGS	+= $(if $(KBUILD_SRC),-I$(srctree)/include/asm-xtensa/)
+CPPFLAGS	+= -Iinclude/asm
+CFLAGS		+= -pipe -mlongcalls
 
-cflags-y	+= -Iarch/xtensa -pipe -mlongcalls
-
-
-KBUILD_DEFCONFIG := common_defconfig
+KBUILD_DEFCONFIG := iss_defconfig
 
 # ramdisk/initrd support
 # You need a compressed ramdisk image, named ramdisk.gz in
@@ -62,30 +56,36 @@
 LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
 
 head-y		:= arch/xtensa/kernel/head.o
-core-y		+= arch/xtensa/kernel/ \
-		   arch/xtensa/mm/ arch/xtensa/platform-$(PLATFORM)/
+core-y		+= arch/xtensa/kernel/ arch/xtensa/mm/
+ifneq ($(PLATFORM),)
+core-y		+= arch/xtensa/platform-$(PLATFORM)/
+endif
 libs-y		+= arch/xtensa/lib/ $(LIBGCC)
 
-boot	:= arch/xtensa/boot
+boot		:= arch/xtensa/boot
+
+archinc		:= include/asm-xtensa
 
 arch/xtensa/kernel/asm-offsets.s: \
-	arch/xtensa/kernel/asm-offsets.c \
-	include/asm-xtensa/.platform
+	arch/xtensa/kernel/asm-offsets.c $(archinc)/.platform
 
 include/asm-xtensa/offsets.h: arch/xtensa/kernel/asm-offsets.s
 	$(call filechk,gen-asm-offsets)
 
-prepare: include/asm-xtensa/.platform include/asm-xtensa/offsets.h
+prepare: $(archinc)/.platform $(archinc)/offsets.h
 
 # Update machine cpu and platform symlinks if something which affects
 # them changed.
 
-include/asm-xtensa/.platform: $(wildcard include/config/arch/*.h)
-	@echo '  Setting up cpu ($(CPU)) and platform ($(PLATFORM)) symlinks'
-	$(Q)rm -f include/asm-xtensa/platform
-	$(Q)rm -f include/asm-xtensa/xtensa/config
-	$(Q)(cd include/asm-xtensa/; ln -sf platform-$(PLATFORM) platform)
-	$(Q)(cd include/asm-xtensa/xtensa; ln -sf config-$(CPU) config)
+$(archinc)/.platform: $(wildcard include/config/arch/*.h) include/config/MARKER
+	@echo '  SYMLINK $(archinc)/xtensa/config -> $(archinc)/xtensa/config-$(CPU)'
+	$(Q)mkdir -p $(archinc)
+	$(Q)mkdir -p $(archinc)/xtensa
+	$(Q)ln -fsn $(srctree)/$(archinc)/xtensa/config-$(CPU) $(archinc)/xtensa/config
+	@echo '  SYMLINK $(archinc)/platform -> $(archinc)/platform-$(PLATFORM)'
+	$(Q)ln -fsn $(srctree)/$(archinc)/platform-$(PLATFORM) $(archinc)/platform
+	@touch $@
+
 
 all: zImage
 
@@ -94,7 +94,9 @@
 zImage zImage.initrd: vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $@
 
-CLEAN_FILES	+= arch/xtensa/vmlinux.lds include/asm-xtensa/offset.h
+CLEAN_FILES	+= arch/xtensa/vmlinux.lds $(archinc)/offset.h \
+		   $(archinc)/platform $(archinc)/xtensa/config \
+		   $(archinc)/.platform
 
 define archhelp
   @echo '* zImage      - Compressed kernel image (arch/xtensa/boot/images/zImage.*)'
diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile
index 260f456..820b31d 100644
--- a/arch/xtensa/boot/Makefile
+++ b/arch/xtensa/boot/Makefile
@@ -11,21 +11,19 @@
 CFLAGS 		+= -fno-builtin -Iarch/$(ARCH)/boot/include
 HOSTFLAGS	+= -Iarch/$(ARCH)/boot/include
 
-BIG_ENDIAN	:= $(shell echo -e "\#ifdef __XTENSA_EL__\nint little;\n\#else\nint big;\n\#endif" | $(CC) -E -|grep -c big)
-
+BIG_ENDIAN	:= $(shell echo -e __XTENSA_EB__ | $(CC) -E - | grep -v "\#")
 
 export CFLAGS
 export AFLAGS
 export BIG_ENDIAN
 
+subdir-y	:= lib
+
 # Subdirs for the boot loader(s)
 
 bootdir-$(CONFIG_XTENSA_PLATFORM_ISS)	 += boot-elf
 bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf
 
-subdir-y	:= lib/
-
-subdir-y	+= boot-elf/ boot-redboot/
 
 zImage zImage.initrd Image Image.initrd: $(bootdir-y)
 
@@ -33,5 +31,3 @@
 	      $(addprefix $(obj)/,$(host-progs))
 	$(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS)
 
-
-
diff --git a/arch/xtensa/boot/boot-elf/Makefile b/arch/xtensa/boot/boot-elf/Makefile
index f6ef6a3..734db7f 100644
--- a/arch/xtensa/boot/boot-elf/Makefile
+++ b/arch/xtensa/boot/boot-elf/Makefile
@@ -27,7 +27,7 @@
 		--set-section-flags image=contents,alloc,load,load,data \
 		$(OBJS) $@.tmp
 	$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \
-		-T arch/$(ARCH)/boot/boot-elf/boot.ld \
+		-T $(srctree)/arch/$(ARCH)/boot/boot-elf/boot.ld \
 		-o arch/$(ARCH)/boot/$@.elf $@.tmp
 	rm -f $@.tmp vmlinux.tmp
 
@@ -41,7 +41,7 @@
 		--set-section-flags image=contents,alloc,load,load,data \
 		$(OBJS) $@.tmp
 	$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \
-		-T arch/$(ARCH)/boot/boot-elf/boot.ld \
+		-T $(srctree)/arch/$(ARCH)/boot/boot-elf/boot.ld \
 		-o arch/$(ARCH)/boot/$@.elf $@.tmp
 	rm -f $@.tmp vmlinux.tmp
 
diff --git a/arch/xtensa/boot/boot-redboot/Makefile b/arch/xtensa/boot/boot-redboot/Makefile
index ca8a68b..f53262c 100644
--- a/arch/xtensa/boot/boot-redboot/Makefile
+++ b/arch/xtensa/boot/boot-redboot/Makefile
@@ -12,24 +12,24 @@
 OBJCOPY_ARGS 	:= -O elf32-xtensa-le
 endif
 
-LD_ARGS	= -T $(obj)/boot.ld
+LD_ARGS	= -T $(srctree)/$(obj)/boot.ld
 
 boot-y	:= bootstrap.o
 
 OBJS	:= $(addprefix $(obj)/,$(boot-y))
-LIBS	:= arch/$(ARCH)/boot/lib/lib.a arch/$(ARCH)/lib/lib.a
+LIBS	:= arch/xtensa/boot/lib/lib.a arch/xtensa/lib/lib.a
 
 LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
 
 zImage: vmlinux $(OBJS) $(LIBS)
 	$(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \
-		$(TOPDIR)/vmlinux vmlinux.tmp
+		vmlinux vmlinux.tmp
 	gzip -vf9 vmlinux.tmp
 	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
 		--add-section image=vmlinux.tmp.gz \
 		--set-section-flags image=contents,alloc,load,load,data \
 		$(OBJS) $@.tmp
 	$(LD) $(LD_ARGS) -o $@.elf $@.tmp $(LIBS) -L/xtensa-elf/lib $(LIBGCC)
-	$(OBJCOPY) -S -O binary $@.elf arch/$(ARCH)/boot/images/$@.redboot
-#	rm -f $@.tmp $@.elf vmlinux.tmp.gz
+	$(OBJCOPY) -S -O binary $@.elf arch/$(ARCH)/boot/$@.redboot
+	rm -f $@.tmp $@.elf vmlinux.tmp.gz
 
diff --git a/arch/xtensa/boot/include/zlib.h b/arch/xtensa/boot/include/zlib.h
deleted file mode 100644
index ea29b62..0000000
--- a/arch/xtensa/boot/include/zlib.h
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * BK Id: SCCS/s.zlib.h 1.8 05/18/01 15:17:23 cort
- */
-/*
- * 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@prep.ai.mit.edu    madler@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/xtensa/boot/lib/Makefile b/arch/xtensa/boot/lib/Makefile
index c0a74dc..9e73bb8 100644
--- a/arch/xtensa/boot/lib/Makefile
+++ b/arch/xtensa/boot/lib/Makefile
@@ -2,5 +2,16 @@
 # Makefile for some libs needed by zImage.
 #
 
+zlib	:= infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c
 
-lib-y := zlib.o zmem.o
+lib-y	+= $(zlib:.c=.o) zmem.o
+
+EXTRA_CFLAGS	+= -Ilib/zlib_inflate
+
+quiet_cmd_copy_zlib = COPY    $@
+      cmd_copy_zlib = cat $< > $@
+
+$(addprefix $(obj)/,$(zlib)): $(obj)/%: $(srctree)/lib/zlib_inflate/%
+	$(call cmd,copy_zlib)
+
+clean-files	:= $(zlib)
diff --git a/arch/xtensa/boot/lib/memcpy.S b/arch/xtensa/boot/lib/memcpy.S
deleted file mode 100644
index a029f5d..0000000
--- a/arch/xtensa/boot/lib/memcpy.S
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *  arch/xtensa/lib/memcpy.S
- *
- *  ANSI C standard library function memcpy
- *
- *  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) 2002 Tensilica Inc.
- */
-
-#define _ASMLANGUAGE
-#include <xtensa/config/core.h>
-
-.text
-.align	4
-.global	bcopy
-.type   bcopy,@function
-bcopy:
-        movi    a14, xthal_bcopy        // a14 safe to use regardless of whether caller
-                                        //   used call4 or call8 (can't have used call12)
-        jx      a14                     // let the Core HAL do the work
-
-.text
-.align	4
-.global	memcpy
-.type   memcpy,@function
-memcpy:
-.global	memmove
-.type   memmove,@function
-memmove:
-        movi    a14, xthal_memcpy      // a14 safe to use regardless of whether caller
-                                        //   used call4 or call8 (can't have used call12)
-        jx      a14                     // let the Core HAL do the work
-
diff --git a/arch/xtensa/boot/lib/zlib.c b/arch/xtensa/boot/lib/zlib.c
deleted file mode 100644
index e3859f6..0000000
--- a/arch/xtensa/boot/lib/zlib.c
+++ /dev/null
@@ -1,2150 +0,0 @@
-/*
- * BK Id: SCCS/s.zlib.c 1.8 05/18/01 15:17:24 cort
- */
-/*
- * 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
- *
- */
-
-/*+++++*/
-/* 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 */
-
-#include <linux/string.h>
-#define zmemcpy memcpy
-#define zmemzero(dest, len)	memset(dest, 0, len)
-
-/* 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)
-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)
-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, w)
-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)
-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, f)
-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)
-z_stream *z;
-{
-    if (z->state->mode != BLOCKS)
-	return Z_DATA_ERROR;
-    return inflate_addhistory(z->state->blocks, z);
-}
-
-
-int inflateSync(z)
-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}
-
-/*
- * The IBM 150 firmware munges the data right after _etext[].  This
- * protects it. -- Cort
- */
-local uInt protect_mask[] = {0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 ,0 ,0};
-/* 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(s, z, c)
-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, c, w)
-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(s, z, r)
-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(s, z, c)
-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(s, z)
-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(s)
-    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(b, n, s, d, e, t, m, zs)
-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_OK;
-  }
-
-
-  /* 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);
-
-
-  /* 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(c, bb, tb, z)
-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(nl, nd, c, bl, bd, tl, td, z)
-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(q, n, s)
-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(q, p, n)
-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(bl, bd, tl, td)
-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(t, z)
-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(bl, bd, tl, td, z)
-uInt bl, bd;
-inflate_huft *tl, *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(s, z, r)
-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(c, z)
-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(s, z, r)
-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(bl, bd, tl, td, s, z)
-uInt bl, bd;
-inflate_huft *tl, *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(adler, buf, len)
-    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/xtensa/boot/lib/zmem.c b/arch/xtensa/boot/lib/zmem.c
index 7848f12..d9862aa 100644
--- a/arch/xtensa/boot/lib/zmem.c
+++ b/arch/xtensa/boot/lib/zmem.c
@@ -1,4 +1,4 @@
-#include "zlib.h"
+#include <linux/zlib.h>
 
 /* bits taken from ppc */
 
@@ -9,11 +9,10 @@
   for (;;);
 }
 
-void *zalloc(void *x, unsigned items, unsigned size)
+void *zalloc(unsigned size)
 {
         void *p = avail_ram;
 
-        size *= items;
         size = (size + 7) & -8;
         avail_ram += size;
         if (avail_ram > end_avail) {
@@ -24,11 +23,6 @@
         return p;
 }
 
-void zfree(void *x, void *addr, unsigned nb)
-{
-}
-
-
 #define HEAD_CRC        2
 #define EXTRA_FIELD     4
 #define ORIG_NAME       8
@@ -43,7 +37,6 @@
 	int r, i, flags;
 
         /* skip header */
-
         i = 10;
         flags = src[3];
         if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
@@ -65,9 +58,8 @@
                 exit();
         }
 
-        s.zalloc = zalloc;
-        s.zfree = zfree;
-        r = inflateInit2(&s, -MAX_WBITS);
+	s.workspace = zalloc(zlib_inflate_workspacesize());
+        r = zlib_inflateInit2(&s, -MAX_WBITS);
         if (r != Z_OK) {
                 //puts("inflateInit2 returned "); puthex(r); puts("\n");
                 exit();
@@ -76,12 +68,12 @@
         s.avail_in = *lenp - i;
         s.next_out = dst;
         s.avail_out = dstlen;
-        r = inflate(&s, Z_FINISH);
+        r = zlib_inflate(&s, Z_FINISH);
         if (r != Z_OK && r != Z_STREAM_END) {
                 //puts("inflate returned "); puthex(r); puts("\n");
                 exit();
         }
         *lenp = s.next_out - (unsigned char *) dst;
-        inflateEnd(&s);
+        zlib_inflateEnd(&s);
 }
 
diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c
index d29a816..09887c9 100644
--- a/arch/xtensa/kernel/pci.c
+++ b/arch/xtensa/kernel/pci.c
@@ -57,50 +57,6 @@
 
 static int pci_bus_count;
 
-static void pcibios_fixup_resources(struct pci_dev* dev);
-
-#if 0 // FIXME
-struct pci_fixup pcibios_fixups[] = {
-	{ DECLARE_PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources },
-	{ 0 }
-};
-#endif
-
-void
-pcibios_update_resource(struct pci_dev *dev, struct resource *root,
-			struct resource *res, int resource)
-{
-	u32 new, check, mask;
-	int reg;
-	struct pci_controller* pci_ctrl = dev->sysdata;
-
-	new = res->start;
-	if (pci_ctrl && res->flags & IORESOURCE_IO) {
-		new -= pci_ctrl->io_space.base;
-	}
-	new |= (res->flags & PCI_REGION_FLAG_MASK);
-	if (resource < 6) {
-		reg = PCI_BASE_ADDRESS_0 + 4*resource;
-	} else if (resource == PCI_ROM_RESOURCE) {
-		res->flags |= PCI_ROM_ADDRESS_ENABLE;
-		reg = dev->rom_base_reg;
-	} else {
-	/* Somebody might have asked allocation of a non-standard resource */
-		return;
-	}
-
-	pci_write_config_dword(dev, reg, new);
-	pci_read_config_dword(dev, reg, &check);
-	mask = (new & PCI_BASE_ADDRESS_SPACE_IO) ?
-		PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK;
-
-	if ((new ^ check) & mask) {
-		printk(KERN_ERR "PCI: Error while updating region "
-		       "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
-		       new, check);
-	}
-}
-
 /*
  * We need to avoid collisions with `mirrored' VGA ports
  * and other strange ISA hardware, so we always want the
@@ -125,7 +81,7 @@
 
 		if (size > 0x100) {
 			printk(KERN_ERR "PCI: I/O Region %s/%d too large"
-			       " (%ld bytes)\n", dev->slot_name,
+			       " (%ld bytes)\n", pci_name(dev),
 			       dev->resource - res, size);
 		}
 
@@ -149,7 +105,7 @@
 		r = &dev->resource[idx];
 		if (!r->start && r->end) {
 			printk (KERN_ERR "PCI: Device %s not available because "
-				"of resource collisions\n", dev->slot_name);
+				"of resource collisions\n", pci_name(dev));
 			return -EINVAL;
 		}
 		if (r->flags & IORESOURCE_IO)
@@ -161,7 +117,7 @@
 		cmd |= PCI_COMMAND_MEMORY;
 	if (cmd != old_cmd) {
 		printk("PCI: Enabling device %s (%04x -> %04x)\n",
-			dev->slot_name, old_cmd, cmd);
+			pci_name(dev), old_cmd, cmd);
 		pci_write_config_word(dev, PCI_COMMAND, cmd);
 	}
 	return 0;
@@ -293,7 +249,7 @@
 		r = &dev->resource[idx];
 		if (!r->start && r->end) {
 			printk(KERN_ERR "PCI: Device %s not available because "
-			       "of resource collisions\n", dev->slot_name);
+			       "of resource collisions\n", pci_name(dev));
 			return -EINVAL;
 		}
 		if (r->flags & IORESOURCE_IO)
@@ -303,7 +259,7 @@
 	}
 	if (cmd != old_cmd) {
 		printk("PCI: Enabling device %s (%04x -> %04x)\n",
-		       dev->slot_name, old_cmd, cmd);
+		       pci_name(dev), old_cmd, cmd);
 		pci_write_config_word(dev, PCI_COMMAND, cmd);
 	}
 
@@ -325,47 +281,6 @@
 
 #endif /* CONFIG_PROC_FS */
 
-
-static void
-pcibios_fixup_resources(struct pci_dev *dev)
-{
-	struct pci_controller* pci_ctrl = (struct pci_controller *)dev->sysdata;
-	int i;
-	unsigned long offset;
-
-	if (!pci_ctrl) {
-		printk(KERN_ERR "No pci_ctrl for PCI dev %s!\n",dev->slot_name);
-		return;
-	}
-	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
-		struct resource *res = dev->resource + i;
-		if (!res->start || !res->flags)
-			continue;
-		if (res->end == 0xffffffff) {
-			DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n",
-			    dev->slot_name, i, res->start, res->end);
-			res->end -= res->start;
-			res->start = 0;
-			continue;
-		}
-		offset = 0;
-		if (res->flags & IORESOURCE_IO)
-			offset = (unsigned long) pci_ctrl->io_space.base;
-		else if (res->flags & IORESOURCE_MEM)
-			offset = (unsigned long) pci_ctrl->mem_space.base;
-
-		if (offset != 0) {
-			res->start += offset;
-			res->end += offset;
-#ifdef DEBUG
-			printk("Fixup res %d (%lx) of dev %s: %lx -> %lx\n",
-			       i, res->flags, dev->slot_name,
-			       res->start - offset, res->start);
-#endif
-		}
-	}
-}
-
 /*
  * Platform support for /proc/bus/pci/X/Y mmap()s,
  * modelled on the sparc64 implementation by Dave Miller.
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
index 9ef07a4..2659efd 100644
--- a/arch/xtensa/kernel/ptrace.c
+++ b/arch/xtensa/kernel/ptrace.c
@@ -22,6 +22,7 @@
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/security.h>
+#include <linux/signal.h>
 
 #include <asm/pgtable.h>
 #include <asm/page.h>
@@ -239,7 +240,7 @@
 	case PTRACE_CONT: /* restart after signal. */
 	{
 		ret = -EIO;
-		if ((unsigned long) data > _NSIG)
+		if (!valid_signal(data))
 			break;
 		if (request == PTRACE_SYSCALL)
 			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -269,7 +270,7 @@
 
 	case PTRACE_SINGLESTEP:
 		ret = -EIO;
-		if ((unsigned long) data > _NSIG)
+		if (!valid_signal(data))
 			break;
 		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 		child->ptrace |= PT_SINGLESTEP;
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 90d6089..256c0b1 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -146,7 +146,7 @@
 
 config CRYPTO_AES
 	tristate "AES cipher algorithms"
-	depends on CRYPTO && !((X86 || UML_X86) && !64BIT)
+	depends on CRYPTO && !(X86 || UML_X86)
 	help
 	  AES cipher algorithms (FIPS-197). AES uses the Rijndael 
 	  algorithm.
@@ -184,6 +184,26 @@
 
 	  See <http://csrc.nist.gov/encryption/aes/> for more information.
 
+config CRYPTO_AES_X86_64
+	tristate "AES cipher algorithms (x86_64)"
+	depends on CRYPTO && ((X86 || UML_X86) && 64BIT)
+	help
+	  AES cipher algorithms (FIPS-197). AES uses the Rijndael 
+	  algorithm.
+
+	  Rijndael appears to be consistently a very good performer in
+	  both hardware and software across a wide range of computing 
+	  environments regardless of its use in feedback or non-feedback 
+	  modes. Its key setup time is excellent, and its key agility is 
+	  good. Rijndael's very low memory requirements make it very well 
+	  suited for restricted-space environments, in which it also 
+	  demonstrates excellent performance. Rijndael's operations are 
+	  among the easiest to defend against power and timing attacks.	
+
+	  The AES specifies three key sizes: 128, 192 and 256 bits	  
+
+	  See <http://csrc.nist.gov/encryption/aes/> for more information.
+
 config CRYPTO_CAST5
 	tristate "CAST5 (CAST-128) cipher algorithm"
 	depends on CRYPTO
diff --git a/crypto/api.c b/crypto/api.c
index 394169a..b472881 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -13,9 +13,12 @@
  * any later version.
  *
  */
+
+#include <linux/compiler.h>
 #include <linux/init.h>
 #include <linux/crypto.h>
 #include <linux/errno.h>
+#include <linux/kmod.h>
 #include <linux/rwsem.h>
 #include <linux/slab.h>
 #include "internal.h"
@@ -33,7 +36,7 @@
 	module_put(alg->cra_module);
 }
 
-struct crypto_alg *crypto_alg_lookup(const char *name)
+static struct crypto_alg *crypto_alg_lookup(const char *name)
 {
 	struct crypto_alg *q, *alg = NULL;
 
@@ -54,6 +57,13 @@
 	return alg;
 }
 
+/* A far more intelligent version of this is planned.  For now, just
+ * try an exact match on the name of the algorithm. */
+static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
+{
+	return try_then_request_module(crypto_alg_lookup(name), name);
+}
+
 static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
 {
 	tfm->crt_flags = 0;
@@ -117,20 +127,46 @@
 	}
 }
 
+static unsigned int crypto_ctxsize(struct crypto_alg *alg, int flags)
+{
+	unsigned int len;
+
+	switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
+	default:
+		BUG();
+
+	case CRYPTO_ALG_TYPE_CIPHER:
+		len = crypto_cipher_ctxsize(alg, flags);
+		break;
+		
+	case CRYPTO_ALG_TYPE_DIGEST:
+		len = crypto_digest_ctxsize(alg, flags);
+		break;
+		
+	case CRYPTO_ALG_TYPE_COMPRESS:
+		len = crypto_compress_ctxsize(alg, flags);
+		break;
+	}
+
+	return len + alg->cra_alignmask;
+}
+
 struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
 {
 	struct crypto_tfm *tfm = NULL;
 	struct crypto_alg *alg;
+	unsigned int tfm_size;
 
 	alg = crypto_alg_mod_lookup(name);
 	if (alg == NULL)
 		goto out;
-	
-	tfm = kmalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL);
+
+	tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, flags);
+	tfm = kmalloc(tfm_size, GFP_KERNEL);
 	if (tfm == NULL)
 		goto out_put;
 
-	memset(tfm, 0, sizeof(*tfm) + alg->cra_ctxsize);
+	memset(tfm, 0, tfm_size);
 	
 	tfm->__crt_alg = alg;
 	
@@ -155,8 +191,14 @@
 
 void crypto_free_tfm(struct crypto_tfm *tfm)
 {
-	struct crypto_alg *alg = tfm->__crt_alg;
-	int size = sizeof(*tfm) + alg->cra_ctxsize;
+	struct crypto_alg *alg;
+	int size;
+
+	if (unlikely(!tfm))
+		return;
+
+	alg = tfm->__crt_alg;
+	size = sizeof(*tfm) + alg->cra_ctxsize;
 
 	crypto_exit_ops(tfm);
 	crypto_alg_put(alg);
@@ -168,6 +210,12 @@
 {
 	int ret = 0;
 	struct crypto_alg *q;
+
+	if (alg->cra_alignmask & (alg->cra_alignmask + 1))
+		return -EINVAL;
+
+	if (alg->cra_alignmask > PAGE_SIZE)
+		return -EINVAL;
 	
 	down_write(&crypto_alg_sem);
 	
diff --git a/crypto/cipher.c b/crypto/cipher.c
index f434ce7..1c92c6b 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -4,6 +4,7 @@
  * Cipher operations.
  *
  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -22,10 +23,6 @@
 #include "internal.h"
 #include "scatterwalk.h"
 
-typedef void (cryptfn_t)(void *, u8 *, const u8 *);
-typedef void (procfn_t)(struct crypto_tfm *, u8 *,
-                        u8*, cryptfn_t, void *);
-
 static inline void xor_64(u8 *a, const u8 *b)
 {
 	((u32 *)a)[0] ^= ((u32 *)b)[0];
@@ -39,63 +36,70 @@
 	((u32 *)a)[2] ^= ((u32 *)b)[2];
 	((u32 *)a)[3] ^= ((u32 *)b)[3];
 }
- 
-static inline void *prepare_src(struct scatter_walk *walk, int bsize,
-				void *tmp, int in_place)
-{
-	void *src = walk->data;
-	int n = bsize;
 
-	if (unlikely(scatterwalk_across_pages(walk, bsize))) {
+static unsigned int crypt_slow(const struct cipher_desc *desc,
+			       struct scatter_walk *in,
+			       struct scatter_walk *out, unsigned int bsize)
+{
+	unsigned int alignmask = crypto_tfm_alg_alignmask(desc->tfm);
+	u8 buffer[bsize * 2 + alignmask];
+	u8 *src = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
+	u8 *dst = src + bsize;
+	unsigned int n;
+
+	n = scatterwalk_copychunks(src, in, bsize, 0);
+	scatterwalk_advance(in, n);
+
+	desc->prfn(desc, dst, src, bsize);
+
+	n = scatterwalk_copychunks(dst, out, bsize, 1);
+	scatterwalk_advance(out, n);
+
+	return bsize;
+}
+
+static inline unsigned int crypt_fast(const struct cipher_desc *desc,
+				      struct scatter_walk *in,
+				      struct scatter_walk *out,
+				      unsigned int nbytes, u8 *tmp)
+{
+	u8 *src, *dst;
+
+	src = in->data;
+	dst = scatterwalk_samebuf(in, out) ? src : out->data;
+
+	if (tmp) {
+		memcpy(tmp, in->data, nbytes);
 		src = tmp;
-		n = scatterwalk_copychunks(src, walk, bsize, 0);
-	}
-	scatterwalk_advance(walk, n);
-	return src;
-}
-
-static inline void *prepare_dst(struct scatter_walk *walk, int bsize,
-				void *tmp, int in_place)
-{
-	void *dst = walk->data;
-
-	if (unlikely(scatterwalk_across_pages(walk, bsize)) || in_place)
 		dst = tmp;
-	return dst;
-}
+	}
 
-static inline void complete_src(struct scatter_walk *walk, int bsize,
-				void *src, int in_place)
-{
-}
+	nbytes = desc->prfn(desc, dst, src, nbytes);
 
-static inline void complete_dst(struct scatter_walk *walk, int bsize,
-				void *dst, int in_place)
-{
-	int n = bsize;
+	if (tmp)
+		memcpy(out->data, tmp, nbytes);
 
-	if (unlikely(scatterwalk_across_pages(walk, bsize)))
-		n = scatterwalk_copychunks(dst, walk, bsize, 1);
-	else if (in_place)
-		memcpy(walk->data, dst, bsize);
-	scatterwalk_advance(walk, n);
+	scatterwalk_advance(in, nbytes);
+	scatterwalk_advance(out, nbytes);
+
+	return nbytes;
 }
 
 /* 
  * Generic encrypt/decrypt wrapper for ciphers, handles operations across
  * multiple page boundaries by using temporary blocks.  In user context,
- * the kernel is given a chance to schedule us once per block.
+ * the kernel is given a chance to schedule us once per page.
  */
-static int crypt(struct crypto_tfm *tfm,
+static int crypt(const struct cipher_desc *desc,
 		 struct scatterlist *dst,
 		 struct scatterlist *src,
-                 unsigned int nbytes, cryptfn_t crfn,
-                 procfn_t prfn, void *info)
+		 unsigned int nbytes)
 {
 	struct scatter_walk walk_in, walk_out;
+	struct crypto_tfm *tfm = desc->tfm;
 	const unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
-	u8 tmp_src[bsize];
-	u8 tmp_dst[bsize];
+	unsigned int alignmask = crypto_tfm_alg_alignmask(tfm);
+	unsigned long buffer = 0;
 
 	if (!nbytes)
 		return 0;
@@ -109,64 +113,144 @@
 	scatterwalk_start(&walk_out, dst);
 
 	for(;;) {
-		u8 *src_p, *dst_p;
-		int in_place;
+		unsigned int n = nbytes;
+		u8 *tmp = NULL;
+
+		if (!scatterwalk_aligned(&walk_in, alignmask) ||
+		    !scatterwalk_aligned(&walk_out, alignmask)) {
+			if (!buffer) {
+				buffer = __get_free_page(GFP_ATOMIC);
+				if (!buffer)
+					n = 0;
+			}
+			tmp = (u8 *)buffer;
+		}
 
 		scatterwalk_map(&walk_in, 0);
 		scatterwalk_map(&walk_out, 1);
 
-		in_place = scatterwalk_samebuf(&walk_in, &walk_out);
+		n = scatterwalk_clamp(&walk_in, n);
+		n = scatterwalk_clamp(&walk_out, n);
 
-		do {
-			src_p = prepare_src(&walk_in, bsize, tmp_src,
-					    in_place);
-			dst_p = prepare_dst(&walk_out, bsize, tmp_dst,
-					    in_place);
+		if (likely(n >= bsize))
+			n = crypt_fast(desc, &walk_in, &walk_out, n, tmp);
+		else
+			n = crypt_slow(desc, &walk_in, &walk_out, bsize);
 
-			prfn(tfm, dst_p, src_p, crfn, info);
-
-			complete_src(&walk_in, bsize, src_p, in_place);
-			complete_dst(&walk_out, bsize, dst_p, in_place);
-
-			nbytes -= bsize;
-		} while (nbytes &&
-			 !scatterwalk_across_pages(&walk_in, bsize) &&
-			 !scatterwalk_across_pages(&walk_out, bsize));
+		nbytes -= n;
 
 		scatterwalk_done(&walk_in, 0, nbytes);
 		scatterwalk_done(&walk_out, 1, nbytes);
 
 		if (!nbytes)
-			return 0;
+			break;
 
 		crypto_yield(tfm);
 	}
+
+	if (buffer)
+		free_page(buffer);
+
+	return 0;
 }
 
-static void cbc_process_encrypt(struct crypto_tfm *tfm, u8 *dst, u8 *src,
-				cryptfn_t fn, void *info)
+static int crypt_iv_unaligned(struct cipher_desc *desc,
+			      struct scatterlist *dst,
+			      struct scatterlist *src,
+			      unsigned int nbytes)
 {
-	u8 *iv = info;
+	struct crypto_tfm *tfm = desc->tfm;
+	unsigned int alignmask = crypto_tfm_alg_alignmask(tfm);
+	u8 *iv = desc->info;
 
-	tfm->crt_u.cipher.cit_xor_block(iv, src);
-	fn(crypto_tfm_ctx(tfm), dst, iv);
-	memcpy(iv, dst, crypto_tfm_alg_blocksize(tfm));
+	if (unlikely(((unsigned long)iv & alignmask))) {
+		unsigned int ivsize = tfm->crt_cipher.cit_ivsize;
+		u8 buffer[ivsize + alignmask];
+		u8 *tmp = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
+		int err;
+
+		desc->info = memcpy(tmp, iv, ivsize);
+		err = crypt(desc, dst, src, nbytes);
+		memcpy(iv, tmp, ivsize);
+
+		return err;
+	}
+
+	return crypt(desc, dst, src, nbytes);
 }
 
-static void cbc_process_decrypt(struct crypto_tfm *tfm, u8 *dst, u8 *src,
-				cryptfn_t fn, void *info)
+static unsigned int cbc_process_encrypt(const struct cipher_desc *desc,
+					u8 *dst, const u8 *src,
+					unsigned int nbytes)
 {
-	u8 *iv = info;
+	struct crypto_tfm *tfm = desc->tfm;
+	void (*xor)(u8 *, const u8 *) = tfm->crt_u.cipher.cit_xor_block;
+	int bsize = crypto_tfm_alg_blocksize(tfm);
 
-	fn(crypto_tfm_ctx(tfm), dst, src);
-	tfm->crt_u.cipher.cit_xor_block(dst, iv);
-	memcpy(iv, src, crypto_tfm_alg_blocksize(tfm));
+	void (*fn)(void *, u8 *, const u8 *) = desc->crfn;
+	u8 *iv = desc->info;
+	unsigned int done = 0;
+
+	do {
+		xor(iv, src);
+		fn(crypto_tfm_ctx(tfm), dst, iv);
+		memcpy(iv, dst, bsize);
+
+		src += bsize;
+		dst += bsize;
+	} while ((done += bsize) < nbytes);
+
+	return done;
 }
 
-static void ecb_process(struct crypto_tfm *tfm, u8 *dst, u8 *src,
-			cryptfn_t fn, void *info)
+static unsigned int cbc_process_decrypt(const struct cipher_desc *desc,
+					u8 *dst, const u8 *src,
+					unsigned int nbytes)
 {
-	fn(crypto_tfm_ctx(tfm), dst, src);
+	struct crypto_tfm *tfm = desc->tfm;
+	void (*xor)(u8 *, const u8 *) = tfm->crt_u.cipher.cit_xor_block;
+	int bsize = crypto_tfm_alg_blocksize(tfm);
+
+	u8 stack[src == dst ? bsize : 0];
+	u8 *buf = stack;
+	u8 **dst_p = src == dst ? &buf : &dst;
+
+	void (*fn)(void *, u8 *, const u8 *) = desc->crfn;
+	u8 *iv = desc->info;
+	unsigned int done = 0;
+
+	do {
+		u8 *tmp_dst = *dst_p;
+
+		fn(crypto_tfm_ctx(tfm), tmp_dst, src);
+		xor(tmp_dst, iv);
+		memcpy(iv, src, bsize);
+		if (tmp_dst != dst)
+			memcpy(dst, tmp_dst, bsize);
+
+		src += bsize;
+		dst += bsize;
+	} while ((done += bsize) < nbytes);
+
+	return done;
+}
+
+static unsigned int ecb_process(const struct cipher_desc *desc, u8 *dst,
+				const u8 *src, unsigned int nbytes)
+{
+	struct crypto_tfm *tfm = desc->tfm;
+	int bsize = crypto_tfm_alg_blocksize(tfm);
+	void (*fn)(void *, u8 *, const u8 *) = desc->crfn;
+	unsigned int done = 0;
+
+	do {
+		fn(crypto_tfm_ctx(tfm), dst, src);
+
+		src += bsize;
+		dst += bsize;
+	} while ((done += bsize) < nbytes);
+
+	return done;
 }
 
 static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
@@ -185,9 +269,14 @@
 		       struct scatterlist *dst,
                        struct scatterlist *src, unsigned int nbytes)
 {
-	return crypt(tfm, dst, src, nbytes,
-	             tfm->__crt_alg->cra_cipher.cia_encrypt,
-	             ecb_process, NULL);
+	struct cipher_desc desc;
+	struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher;
+
+	desc.tfm = tfm;
+	desc.crfn = cipher->cia_encrypt;
+	desc.prfn = cipher->cia_encrypt_ecb ?: ecb_process;
+
+	return crypt(&desc, dst, src, nbytes);
 }
 
 static int ecb_decrypt(struct crypto_tfm *tfm,
@@ -195,9 +284,14 @@
                        struct scatterlist *src,
 		       unsigned int nbytes)
 {
-	return crypt(tfm, dst, src, nbytes,
-	             tfm->__crt_alg->cra_cipher.cia_decrypt,
-	             ecb_process, NULL);
+	struct cipher_desc desc;
+	struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher;
+
+	desc.tfm = tfm;
+	desc.crfn = cipher->cia_decrypt;
+	desc.prfn = cipher->cia_decrypt_ecb ?: ecb_process;
+
+	return crypt(&desc, dst, src, nbytes);
 }
 
 static int cbc_encrypt(struct crypto_tfm *tfm,
@@ -205,9 +299,15 @@
                        struct scatterlist *src,
 		       unsigned int nbytes)
 {
-	return crypt(tfm, dst, src, nbytes,
-	             tfm->__crt_alg->cra_cipher.cia_encrypt,
-	             cbc_process_encrypt, tfm->crt_cipher.cit_iv);
+	struct cipher_desc desc;
+	struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher;
+
+	desc.tfm = tfm;
+	desc.crfn = cipher->cia_encrypt;
+	desc.prfn = cipher->cia_encrypt_cbc ?: cbc_process_encrypt;
+	desc.info = tfm->crt_cipher.cit_iv;
+
+	return crypt(&desc, dst, src, nbytes);
 }
 
 static int cbc_encrypt_iv(struct crypto_tfm *tfm,
@@ -215,9 +315,15 @@
                           struct scatterlist *src,
                           unsigned int nbytes, u8 *iv)
 {
-	return crypt(tfm, dst, src, nbytes,
-	             tfm->__crt_alg->cra_cipher.cia_encrypt,
-	             cbc_process_encrypt, iv);
+	struct cipher_desc desc;
+	struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher;
+
+	desc.tfm = tfm;
+	desc.crfn = cipher->cia_encrypt;
+	desc.prfn = cipher->cia_encrypt_cbc ?: cbc_process_encrypt;
+	desc.info = iv;
+
+	return crypt_iv_unaligned(&desc, dst, src, nbytes);
 }
 
 static int cbc_decrypt(struct crypto_tfm *tfm,
@@ -225,9 +331,15 @@
                        struct scatterlist *src,
 		       unsigned int nbytes)
 {
-	return crypt(tfm, dst, src, nbytes,
-	             tfm->__crt_alg->cra_cipher.cia_decrypt,
-	             cbc_process_decrypt, tfm->crt_cipher.cit_iv);
+	struct cipher_desc desc;
+	struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher;
+
+	desc.tfm = tfm;
+	desc.crfn = cipher->cia_decrypt;
+	desc.prfn = cipher->cia_decrypt_cbc ?: cbc_process_decrypt;
+	desc.info = tfm->crt_cipher.cit_iv;
+
+	return crypt(&desc, dst, src, nbytes);
 }
 
 static int cbc_decrypt_iv(struct crypto_tfm *tfm,
@@ -235,9 +347,15 @@
                           struct scatterlist *src,
                           unsigned int nbytes, u8 *iv)
 {
-	return crypt(tfm, dst, src, nbytes,
-	             tfm->__crt_alg->cra_cipher.cia_decrypt,
-	             cbc_process_decrypt, iv);
+	struct cipher_desc desc;
+	struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher;
+
+	desc.tfm = tfm;
+	desc.crfn = cipher->cia_decrypt;
+	desc.prfn = cipher->cia_decrypt_cbc ?: cbc_process_decrypt;
+	desc.info = iv;
+
+	return crypt_iv_unaligned(&desc, dst, src, nbytes);
 }
 
 static int nocrypt(struct crypto_tfm *tfm,
@@ -306,6 +424,8 @@
 	}
 	
 	if (ops->cit_mode == CRYPTO_TFM_MODE_CBC) {
+		unsigned int align;
+		unsigned long addr;
 	    	
 	    	switch (crypto_tfm_alg_blocksize(tfm)) {
 	    	case 8:
@@ -325,9 +445,11 @@
 	    	}
 	    	
 		ops->cit_ivsize = crypto_tfm_alg_blocksize(tfm);
-	    	ops->cit_iv = kmalloc(ops->cit_ivsize, GFP_KERNEL);
-		if (ops->cit_iv == NULL)
-			ret = -ENOMEM;
+		align = crypto_tfm_alg_alignmask(tfm) + 1;
+		addr = (unsigned long)crypto_tfm_ctx(tfm);
+		addr = ALIGN(addr, align);
+		addr += ALIGN(tfm->__crt_alg->cra_ctxsize, align);
+		ops->cit_iv = (void *)addr;
 	}
 
 out:	
@@ -336,6 +458,4 @@
 
 void crypto_exit_cipher_ops(struct crypto_tfm *tfm)
 {
-	if (tfm->crt_cipher.cit_iv)
-		kfree(tfm->crt_cipher.cit_iv);
 }
diff --git a/crypto/des.c b/crypto/des.c
index 1c7e6de..a3c863d 100644
--- a/crypto/des.c
+++ b/crypto/des.c
@@ -1,18 +1,9 @@
-/* 
+/*
  * Cryptographic API.
  *
  * DES & Triple DES EDE Cipher Algorithms.
  *
- * Originally released as descore by Dana L. How <how@isl.stanford.edu>.
- * Modified by Raimar Falke <rf13@inf.tu-dresden.de> for the Linux-Kernel.
- * Derived from Cryptoapi and Nettle implementations, adapted for in-place
- * scatterlist interface.  Changed LGPL to GPL per section 3 of the LGPL.
- *
- * Copyright (c) 1992 Dana L. How.
- * Copyright (c) Raimar Falke <rf13@inf.tu-dresden.de> 
- * Copyright (c) Gisle Sælensminde <gisle@ii.uib.no>
- * Copyright (C) 2001 Niels Möller.
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2005 Dag Arne Osvik <da@osvik.no>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,11 +11,11 @@
  * (at your option) any later version.
  *
  */
+
+#include <linux/bitops.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/mm.h>
 #include <linux/errno.h>
-#include <asm/scatterlist.h>
 #include <linux/crypto.h>
 
 #define DES_KEY_SIZE		8
@@ -35,1157 +26,826 @@
 #define DES3_EDE_EXPKEY_WORDS	(3 * DES_EXPKEY_WORDS)
 #define DES3_EDE_BLOCK_SIZE	DES_BLOCK_SIZE
 
-#define ROR(d,c,o)	((d) = (d) >> (c) | (d) << (o))
+#define ROL(x, r) ((x) = rol32((x), (r)))
+#define ROR(x, r) ((x) = ror32((x), (r)))
 
 struct des_ctx {
-	u8 iv[DES_BLOCK_SIZE];
 	u32 expkey[DES_EXPKEY_WORDS];
 };
 
 struct des3_ede_ctx {
-	u8 iv[DES_BLOCK_SIZE];
 	u32 expkey[DES3_EDE_EXPKEY_WORDS];
 };
 
-static const u32 des_keymap[] = {
-	0x02080008, 0x02082000, 0x00002008, 0x00000000,
-	0x02002000, 0x00080008, 0x02080000, 0x02082008,
-	0x00000008, 0x02000000, 0x00082000, 0x00002008,
-	0x00082008, 0x02002008, 0x02000008, 0x02080000,
-	0x00002000, 0x00082008, 0x00080008, 0x02002000,
-	0x02082008, 0x02000008, 0x00000000, 0x00082000,
-	0x02000000, 0x00080000, 0x02002008, 0x02080008,
-	0x00080000, 0x00002000, 0x02082000, 0x00000008,
-	0x00080000, 0x00002000, 0x02000008, 0x02082008,
-	0x00002008, 0x02000000, 0x00000000, 0x00082000,
-	0x02080008, 0x02002008, 0x02002000, 0x00080008,
-	0x02082000, 0x00000008, 0x00080008, 0x02002000,
-	0x02082008, 0x00080000, 0x02080000, 0x02000008,
-	0x00082000, 0x00002008, 0x02002008, 0x02080000,
-	0x00000008, 0x02082000, 0x00082008, 0x00000000,
-	0x02000000, 0x02080008, 0x00002000, 0x00082008,
+/* Lookup tables for key expansion */
 
-	0x08000004, 0x00020004, 0x00000000, 0x08020200,
-	0x00020004, 0x00000200, 0x08000204, 0x00020000,
-	0x00000204, 0x08020204, 0x00020200, 0x08000000,
-	0x08000200, 0x08000004, 0x08020000, 0x00020204,
-	0x00020000, 0x08000204, 0x08020004, 0x00000000,
-	0x00000200, 0x00000004, 0x08020200, 0x08020004,
-	0x08020204, 0x08020000, 0x08000000, 0x00000204,
-	0x00000004, 0x00020200, 0x00020204, 0x08000200,
-	0x00000204, 0x08000000, 0x08000200, 0x00020204,
-	0x08020200, 0x00020004, 0x00000000, 0x08000200,
-	0x08000000, 0x00000200, 0x08020004, 0x00020000,
-	0x00020004, 0x08020204, 0x00020200, 0x00000004,
-	0x08020204, 0x00020200, 0x00020000, 0x08000204,
-	0x08000004, 0x08020000, 0x00020204, 0x00000000,
-	0x00000200, 0x08000004, 0x08000204, 0x08020200,
-	0x08020000, 0x00000204, 0x00000004, 0x08020004,
-
-	0x80040100, 0x01000100, 0x80000000, 0x81040100,
-	0x00000000, 0x01040000, 0x81000100, 0x80040000,
-	0x01040100, 0x81000000, 0x01000000, 0x80000100,
-	0x81000000, 0x80040100, 0x00040000, 0x01000000,
-	0x81040000, 0x00040100, 0x00000100, 0x80000000,
-	0x00040100, 0x81000100, 0x01040000, 0x00000100,
-	0x80000100, 0x00000000, 0x80040000, 0x01040100,
-	0x01000100, 0x81040000, 0x81040100, 0x00040000,
-	0x81040000, 0x80000100, 0x00040000, 0x81000000,
-	0x00040100, 0x01000100, 0x80000000, 0x01040000,
-	0x81000100, 0x00000000, 0x00000100, 0x80040000,
-	0x00000000, 0x81040000, 0x01040100, 0x00000100,
-	0x01000000, 0x81040100, 0x80040100, 0x00040000,
-	0x81040100, 0x80000000, 0x01000100, 0x80040100,
-	0x80040000, 0x00040100, 0x01040000, 0x81000100,
-	0x80000100, 0x01000000, 0x81000000, 0x01040100,
-
-	0x04010801, 0x00000000, 0x00010800, 0x04010000,
-	0x04000001, 0x00000801, 0x04000800, 0x00010800,
-	0x00000800, 0x04010001, 0x00000001, 0x04000800,
-	0x00010001, 0x04010800, 0x04010000, 0x00000001,
-	0x00010000, 0x04000801, 0x04010001, 0x00000800,
-	0x00010801, 0x04000000, 0x00000000, 0x00010001,
-	0x04000801, 0x00010801, 0x04010800, 0x04000001,
-	0x04000000, 0x00010000, 0x00000801, 0x04010801,
-	0x00010001, 0x04010800, 0x04000800, 0x00010801,
-	0x04010801, 0x00010001, 0x04000001, 0x00000000,
-	0x04000000, 0x00000801, 0x00010000, 0x04010001,
-	0x00000800, 0x04000000, 0x00010801, 0x04000801,
-	0x04010800, 0x00000800, 0x00000000, 0x04000001,
-	0x00000001, 0x04010801, 0x00010800, 0x04010000,
-	0x04010001, 0x00010000, 0x00000801, 0x04000800,
-	0x04000801, 0x00000001, 0x04010000, 0x00010800,
-
-	0x00000400, 0x00000020, 0x00100020, 0x40100000,
-	0x40100420, 0x40000400, 0x00000420, 0x00000000,
-	0x00100000, 0x40100020, 0x40000020, 0x00100400,
-	0x40000000, 0x00100420, 0x00100400, 0x40000020,
-	0x40100020, 0x00000400, 0x40000400, 0x40100420,
-	0x00000000, 0x00100020, 0x40100000, 0x00000420,
-	0x40100400, 0x40000420, 0x00100420, 0x40000000,
-	0x40000420, 0x40100400, 0x00000020, 0x00100000,
-	0x40000420, 0x00100400, 0x40100400, 0x40000020,
-	0x00000400, 0x00000020, 0x00100000, 0x40100400,
-	0x40100020, 0x40000420, 0x00000420, 0x00000000,
-	0x00000020, 0x40100000, 0x40000000, 0x00100020,
-	0x00000000, 0x40100020, 0x00100020, 0x00000420,
-	0x40000020, 0x00000400, 0x40100420, 0x00100000,
-	0x00100420, 0x40000000, 0x40000400, 0x40100420,
-	0x40100000, 0x00100420, 0x00100400, 0x40000400,
-
-	0x00800000, 0x00001000, 0x00000040, 0x00801042,
-	0x00801002, 0x00800040, 0x00001042, 0x00801000,
-	0x00001000, 0x00000002, 0x00800002, 0x00001040,
-	0x00800042, 0x00801002, 0x00801040, 0x00000000,
-	0x00001040, 0x00800000, 0x00001002, 0x00000042,
-	0x00800040, 0x00001042, 0x00000000, 0x00800002,
-	0x00000002, 0x00800042, 0x00801042, 0x00001002,
-	0x00801000, 0x00000040, 0x00000042, 0x00801040,
-	0x00801040, 0x00800042, 0x00001002, 0x00801000,
-	0x00001000, 0x00000002, 0x00800002, 0x00800040,
-	0x00800000, 0x00001040, 0x00801042, 0x00000000,
-	0x00001042, 0x00800000, 0x00000040, 0x00001002,
-	0x00800042, 0x00000040, 0x00000000, 0x00801042,
-	0x00801002, 0x00801040, 0x00000042, 0x00001000,
-	0x00001040, 0x00801002, 0x00800040, 0x00000042,
-	0x00000002, 0x00001042, 0x00801000, 0x00800002,
-
-	0x10400000, 0x00404010, 0x00000010, 0x10400010,
-	0x10004000, 0x00400000, 0x10400010, 0x00004010,
-	0x00400010, 0x00004000, 0x00404000, 0x10000000,
-	0x10404010, 0x10000010, 0x10000000, 0x10404000,
-	0x00000000, 0x10004000, 0x00404010, 0x00000010,
-	0x10000010, 0x10404010, 0x00004000, 0x10400000,
-	0x10404000, 0x00400010, 0x10004010, 0x00404000,
-	0x00004010, 0x00000000, 0x00400000, 0x10004010,
-	0x00404010, 0x00000010, 0x10000000, 0x00004000,
-	0x10000010, 0x10004000, 0x00404000, 0x10400010,
-	0x00000000, 0x00404010, 0x00004010, 0x10404000,
-	0x10004000, 0x00400000, 0x10404010, 0x10000000,
-	0x10004010, 0x10400000, 0x00400000, 0x10404010,
-	0x00004000, 0x00400010, 0x10400010, 0x00004010,
-	0x00400010, 0x00000000, 0x10404000, 0x10000010,
-	0x10400000, 0x10004010, 0x00000010, 0x00404000,
-
-	0x00208080, 0x00008000, 0x20200000, 0x20208080,
-	0x00200000, 0x20008080, 0x20008000, 0x20200000,
-	0x20008080, 0x00208080, 0x00208000, 0x20000080,
-	0x20200080, 0x00200000, 0x00000000, 0x20008000,
-	0x00008000, 0x20000000, 0x00200080, 0x00008080,
-	0x20208080, 0x00208000, 0x20000080, 0x00200080,
-	0x20000000, 0x00000080, 0x00008080, 0x20208000,
-	0x00000080, 0x20200080, 0x20208000, 0x00000000,
-	0x00000000, 0x20208080, 0x00200080, 0x20008000,
-	0x00208080, 0x00008000, 0x20000080, 0x00200080,
-	0x20208000, 0x00000080, 0x00008080, 0x20200000,
-	0x20008080, 0x20000000, 0x20200000, 0x00208000,
-	0x20208080, 0x00008080, 0x00208000, 0x20200080,
-	0x00200000, 0x20000080, 0x20008000, 0x00000000,
-	0x00008000, 0x00200000, 0x20200080, 0x00208080,
-	0x20000000, 0x20208000, 0x00000080, 0x20008080,
+static const u8 pc1[256] = {
+	0x00, 0x00, 0x40, 0x04, 0x10, 0x10, 0x50, 0x14,
+	0x04, 0x40, 0x44, 0x44, 0x14, 0x50, 0x54, 0x54,
+	0x02, 0x02, 0x42, 0x06, 0x12, 0x12, 0x52, 0x16,
+	0x06, 0x42, 0x46, 0x46, 0x16, 0x52, 0x56, 0x56,
+	0x80, 0x08, 0xc0, 0x0c, 0x90, 0x18, 0xd0, 0x1c,
+	0x84, 0x48, 0xc4, 0x4c, 0x94, 0x58, 0xd4, 0x5c,
+	0x82, 0x0a, 0xc2, 0x0e, 0x92, 0x1a, 0xd2, 0x1e,
+	0x86, 0x4a, 0xc6, 0x4e, 0x96, 0x5a, 0xd6, 0x5e,
+	0x20, 0x20, 0x60, 0x24, 0x30, 0x30, 0x70, 0x34,
+	0x24, 0x60, 0x64, 0x64, 0x34, 0x70, 0x74, 0x74,
+	0x22, 0x22, 0x62, 0x26, 0x32, 0x32, 0x72, 0x36,
+	0x26, 0x62, 0x66, 0x66, 0x36, 0x72, 0x76, 0x76,
+	0xa0, 0x28, 0xe0, 0x2c, 0xb0, 0x38, 0xf0, 0x3c,
+	0xa4, 0x68, 0xe4, 0x6c, 0xb4, 0x78, 0xf4, 0x7c,
+	0xa2, 0x2a, 0xe2, 0x2e, 0xb2, 0x3a, 0xf2, 0x3e,
+	0xa6, 0x6a, 0xe6, 0x6e, 0xb6, 0x7a, 0xf6, 0x7e,
+	0x08, 0x80, 0x48, 0x84, 0x18, 0x90, 0x58, 0x94,
+	0x0c, 0xc0, 0x4c, 0xc4, 0x1c, 0xd0, 0x5c, 0xd4,
+	0x0a, 0x82, 0x4a, 0x86, 0x1a, 0x92, 0x5a, 0x96,
+	0x0e, 0xc2, 0x4e, 0xc6, 0x1e, 0xd2, 0x5e, 0xd6,
+	0x88, 0x88, 0xc8, 0x8c, 0x98, 0x98, 0xd8, 0x9c,
+	0x8c, 0xc8, 0xcc, 0xcc, 0x9c, 0xd8, 0xdc, 0xdc,
+	0x8a, 0x8a, 0xca, 0x8e, 0x9a, 0x9a, 0xda, 0x9e,
+	0x8e, 0xca, 0xce, 0xce, 0x9e, 0xda, 0xde, 0xde,
+	0x28, 0xa0, 0x68, 0xa4, 0x38, 0xb0, 0x78, 0xb4,
+	0x2c, 0xe0, 0x6c, 0xe4, 0x3c, 0xf0, 0x7c, 0xf4,
+	0x2a, 0xa2, 0x6a, 0xa6, 0x3a, 0xb2, 0x7a, 0xb6,
+	0x2e, 0xe2, 0x6e, 0xe6, 0x3e, 0xf2, 0x7e, 0xf6,
+	0xa8, 0xa8, 0xe8, 0xac, 0xb8, 0xb8, 0xf8, 0xbc,
+	0xac, 0xe8, 0xec, 0xec, 0xbc, 0xf8, 0xfc, 0xfc,
+	0xaa, 0xaa, 0xea, 0xae, 0xba, 0xba, 0xfa, 0xbe,
+	0xae, 0xea, 0xee, 0xee, 0xbe, 0xfa, 0xfe, 0xfe
 };
 
-static const u8 rotors[] = {
-	34, 13,  5, 46, 47, 18, 32, 41, 11, 53, 33, 20,
-	14, 36, 30, 24, 49,  2, 15, 37, 42, 50,  0, 21,
-	38, 48,  6, 26, 39,  4, 52, 25, 12, 27, 31, 40,
-	1, 17, 28, 29, 23, 51, 35,  7,  3, 22,  9, 43,
-
-	41, 20, 12, 53, 54, 25, 39, 48, 18, 31, 40, 27,
-	21, 43, 37,  0,  1,  9, 22, 44, 49,  2,  7, 28,
-	45, 55, 13, 33, 46, 11,  6, 32, 19, 34, 38, 47,
-	8, 24, 35, 36, 30,  3, 42, 14, 10, 29, 16, 50,
-
-	55, 34, 26, 38, 11, 39, 53,  5, 32, 45, 54, 41,
-	35,  2, 51, 14, 15, 23, 36,  3,  8, 16, 21, 42,
-	6, 12, 27, 47, 31, 25, 20, 46, 33, 48, 52,  4,
-	22,  7, 49, 50, 44, 17,  1, 28, 24, 43, 30,  9,
-
-	12, 48, 40, 52, 25, 53, 38, 19, 46,  6, 11, 55,
-	49, 16, 10, 28, 29, 37, 50, 17, 22, 30, 35,  1,
-	20, 26, 41,  4, 45, 39, 34, 31, 47,  5, 13, 18,
-	36, 21,  8,  9,  3,  0, 15, 42,  7,  2, 44, 23,
-
-	26,  5, 54, 13, 39, 38, 52, 33, 31, 20, 25, 12,
-	8, 30, 24, 42, 43, 51,  9,  0, 36, 44, 49, 15,
-	34, 40, 55, 18,  6, 53, 48, 45,  4, 19, 27, 32,
-	50, 35, 22, 23, 17, 14, 29,  1, 21, 16,  3, 37,
-
-	40, 19, 11, 27, 53, 52, 13, 47, 45, 34, 39, 26,
-	22, 44,  7,  1,  2, 10, 23, 14, 50,  3,  8, 29,
-	48, 54, 12, 32, 20, 38,  5,  6, 18, 33, 41, 46,
-	9, 49, 36, 37,  0, 28, 43, 15, 35, 30, 17, 51,
-
-	54, 33, 25, 41, 38, 13, 27,  4,  6, 48, 53, 40,
-	36,  3, 21, 15, 16, 24, 37, 28,  9, 17, 22, 43,
-	5, 11, 26, 46, 34, 52, 19, 20, 32, 47, 55, 31,
-	23,  8, 50, 51, 14, 42,  2, 29, 49, 44,  0, 10,
-
-	11, 47, 39, 55, 52, 27, 41, 18, 20,  5, 38, 54,
-	50, 17, 35, 29, 30,  7, 51, 42, 23,  0, 36,  2,
-	19, 25, 40, 31, 48, 13, 33, 34, 46,  4, 12, 45,
-	37, 22,  9, 10, 28,  1, 16, 43,  8,  3, 14, 24,
-
-	18, 54, 46,  5,  6, 34, 48, 25, 27, 12, 45,  4,
-	2, 24, 42, 36, 37, 14,  3, 49, 30,  7, 43,  9,
-	26, 32, 47, 38, 55, 20, 40, 41, 53, 11, 19, 52,
-	44, 29, 16, 17, 35,  8, 23, 50, 15, 10, 21,  0,
-
-	32, 11, 31, 19, 20, 48,  5, 39, 41, 26,  6, 18,
-	16,  7,  1, 50, 51, 28, 17,  8, 44, 21,  2, 23,
-	40, 46,  4, 52, 12, 34, 54, 55, 38, 25, 33, 13,
-	3, 43, 30,  0, 49, 22, 37,  9, 29, 24, 35, 14,
-
-	46, 25, 45, 33, 34,  5, 19, 53, 55, 40, 20, 32,
-	30, 21, 15,  9, 10, 42,  0, 22,  3, 35, 16, 37,
-	54, 31, 18, 13, 26, 48, 11, 12, 52, 39, 47, 27,
-	17,  2, 44, 14,  8, 36, 51, 23, 43,  7, 49, 28,
-
-	31, 39,  6, 47, 48, 19, 33, 38, 12, 54, 34, 46,
-	44, 35, 29, 23, 24,  1, 14, 36, 17, 49, 30, 51,
-	11, 45, 32, 27, 40,  5, 25, 26, 13, 53,  4, 41,
-	0, 16,  3, 28, 22, 50, 10, 37,  2, 21,  8, 42,
-
-	45, 53, 20,  4,  5, 33, 47, 52, 26, 11, 48, 31,
-	3, 49, 43, 37,  7, 15, 28, 50,  0,  8, 44, 10,
-	25,  6, 46, 41, 54, 19, 39, 40, 27, 38, 18, 55,
-	14, 30, 17, 42, 36,  9, 24, 51, 16, 35, 22,  1,
-
-	6, 38, 34, 18, 19, 47,  4, 13, 40, 25,  5, 45,
-	17,  8,  2, 51, 21, 29, 42,  9, 14, 22,  3, 24,
-	39, 20, 31, 55, 11, 33, 53, 54, 41, 52, 32, 12,
-	28, 44,  0,  1, 50, 23,  7, 10, 30, 49, 36, 15,
-
-	20, 52, 48, 32, 33,  4, 18, 27, 54, 39, 19,  6,
-	0, 22, 16, 10, 35, 43,  1, 23, 28, 36, 17,  7,
-	53, 34, 45, 12, 25, 47, 38, 11, 55, 13, 46, 26,
-	42,  3, 14, 15,  9, 37, 21, 24, 44,  8, 50, 29,
-
-	27,  6, 55, 39, 40, 11, 25, 34,  4, 46, 26, 13,
-	7, 29, 23, 17, 42, 50,  8, 30, 35, 43, 24, 14,
-	31, 41, 52, 19, 32, 54, 45, 18,  5, 20, 53, 33,
-	49, 10, 21, 22, 16, 44, 28,  0, 51, 15,  2, 36,
+static const u8 rs[256] = {
+	0x00, 0x00, 0x80, 0x80, 0x02, 0x02, 0x82, 0x82,
+	0x04, 0x04, 0x84, 0x84, 0x06, 0x06, 0x86, 0x86,
+	0x08, 0x08, 0x88, 0x88, 0x0a, 0x0a, 0x8a, 0x8a,
+	0x0c, 0x0c, 0x8c, 0x8c, 0x0e, 0x0e, 0x8e, 0x8e,
+	0x10, 0x10, 0x90, 0x90, 0x12, 0x12, 0x92, 0x92,
+	0x14, 0x14, 0x94, 0x94, 0x16, 0x16, 0x96, 0x96,
+	0x18, 0x18, 0x98, 0x98, 0x1a, 0x1a, 0x9a, 0x9a,
+	0x1c, 0x1c, 0x9c, 0x9c, 0x1e, 0x1e, 0x9e, 0x9e,
+	0x20, 0x20, 0xa0, 0xa0, 0x22, 0x22, 0xa2, 0xa2,
+	0x24, 0x24, 0xa4, 0xa4, 0x26, 0x26, 0xa6, 0xa6,
+	0x28, 0x28, 0xa8, 0xa8, 0x2a, 0x2a, 0xaa, 0xaa,
+	0x2c, 0x2c, 0xac, 0xac, 0x2e, 0x2e, 0xae, 0xae,
+	0x30, 0x30, 0xb0, 0xb0, 0x32, 0x32, 0xb2, 0xb2,
+	0x34, 0x34, 0xb4, 0xb4, 0x36, 0x36, 0xb6, 0xb6,
+	0x38, 0x38, 0xb8, 0xb8, 0x3a, 0x3a, 0xba, 0xba,
+	0x3c, 0x3c, 0xbc, 0xbc, 0x3e, 0x3e, 0xbe, 0xbe,
+	0x40, 0x40, 0xc0, 0xc0, 0x42, 0x42, 0xc2, 0xc2,
+	0x44, 0x44, 0xc4, 0xc4, 0x46, 0x46, 0xc6, 0xc6,
+	0x48, 0x48, 0xc8, 0xc8, 0x4a, 0x4a, 0xca, 0xca,
+	0x4c, 0x4c, 0xcc, 0xcc, 0x4e, 0x4e, 0xce, 0xce,
+	0x50, 0x50, 0xd0, 0xd0, 0x52, 0x52, 0xd2, 0xd2,
+	0x54, 0x54, 0xd4, 0xd4, 0x56, 0x56, 0xd6, 0xd6,
+	0x58, 0x58, 0xd8, 0xd8, 0x5a, 0x5a, 0xda, 0xda,
+	0x5c, 0x5c, 0xdc, 0xdc, 0x5e, 0x5e, 0xde, 0xde,
+	0x60, 0x60, 0xe0, 0xe0, 0x62, 0x62, 0xe2, 0xe2,
+	0x64, 0x64, 0xe4, 0xe4, 0x66, 0x66, 0xe6, 0xe6,
+	0x68, 0x68, 0xe8, 0xe8, 0x6a, 0x6a, 0xea, 0xea,
+	0x6c, 0x6c, 0xec, 0xec, 0x6e, 0x6e, 0xee, 0xee,
+	0x70, 0x70, 0xf0, 0xf0, 0x72, 0x72, 0xf2, 0xf2,
+	0x74, 0x74, 0xf4, 0xf4, 0x76, 0x76, 0xf6, 0xf6,
+	0x78, 0x78, 0xf8, 0xf8, 0x7a, 0x7a, 0xfa, 0xfa,
+	0x7c, 0x7c, 0xfc, 0xfc, 0x7e, 0x7e, 0xfe, 0xfe
 };
 
-static const u8 parity[] = {
-	8,1,0,8,0,8,8,0,0,8,8,0,8,0,2,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,3,
-	0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
-	0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
-	8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
-	0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
-	8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
-	8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
-	4,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,5,0,8,0,8,8,0,0,8,8,0,8,0,6,8,
+static const u32 pc2[1024] = {
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00040000, 0x00000000, 0x04000000, 0x00100000,
+	0x00400000, 0x00000008, 0x00000800, 0x40000000,
+	0x00440000, 0x00000008, 0x04000800, 0x40100000,
+	0x00000400, 0x00000020, 0x08000000, 0x00000100,
+	0x00040400, 0x00000020, 0x0c000000, 0x00100100,
+	0x00400400, 0x00000028, 0x08000800, 0x40000100,
+	0x00440400, 0x00000028, 0x0c000800, 0x40100100,
+	0x80000000, 0x00000010, 0x00000000, 0x00800000,
+	0x80040000, 0x00000010, 0x04000000, 0x00900000,
+	0x80400000, 0x00000018, 0x00000800, 0x40800000,
+	0x80440000, 0x00000018, 0x04000800, 0x40900000,
+	0x80000400, 0x00000030, 0x08000000, 0x00800100,
+	0x80040400, 0x00000030, 0x0c000000, 0x00900100,
+	0x80400400, 0x00000038, 0x08000800, 0x40800100,
+	0x80440400, 0x00000038, 0x0c000800, 0x40900100,
+	0x10000000, 0x00000000, 0x00200000, 0x00001000,
+	0x10040000, 0x00000000, 0x04200000, 0x00101000,
+	0x10400000, 0x00000008, 0x00200800, 0x40001000,
+	0x10440000, 0x00000008, 0x04200800, 0x40101000,
+	0x10000400, 0x00000020, 0x08200000, 0x00001100,
+	0x10040400, 0x00000020, 0x0c200000, 0x00101100,
+	0x10400400, 0x00000028, 0x08200800, 0x40001100,
+	0x10440400, 0x00000028, 0x0c200800, 0x40101100,
+	0x90000000, 0x00000010, 0x00200000, 0x00801000,
+	0x90040000, 0x00000010, 0x04200000, 0x00901000,
+	0x90400000, 0x00000018, 0x00200800, 0x40801000,
+	0x90440000, 0x00000018, 0x04200800, 0x40901000,
+	0x90000400, 0x00000030, 0x08200000, 0x00801100,
+	0x90040400, 0x00000030, 0x0c200000, 0x00901100,
+	0x90400400, 0x00000038, 0x08200800, 0x40801100,
+	0x90440400, 0x00000038, 0x0c200800, 0x40901100,
+	0x00000200, 0x00080000, 0x00000000, 0x00000004,
+	0x00040200, 0x00080000, 0x04000000, 0x00100004,
+	0x00400200, 0x00080008, 0x00000800, 0x40000004,
+	0x00440200, 0x00080008, 0x04000800, 0x40100004,
+	0x00000600, 0x00080020, 0x08000000, 0x00000104,
+	0x00040600, 0x00080020, 0x0c000000, 0x00100104,
+	0x00400600, 0x00080028, 0x08000800, 0x40000104,
+	0x00440600, 0x00080028, 0x0c000800, 0x40100104,
+	0x80000200, 0x00080010, 0x00000000, 0x00800004,
+	0x80040200, 0x00080010, 0x04000000, 0x00900004,
+	0x80400200, 0x00080018, 0x00000800, 0x40800004,
+	0x80440200, 0x00080018, 0x04000800, 0x40900004,
+	0x80000600, 0x00080030, 0x08000000, 0x00800104,
+	0x80040600, 0x00080030, 0x0c000000, 0x00900104,
+	0x80400600, 0x00080038, 0x08000800, 0x40800104,
+	0x80440600, 0x00080038, 0x0c000800, 0x40900104,
+	0x10000200, 0x00080000, 0x00200000, 0x00001004,
+	0x10040200, 0x00080000, 0x04200000, 0x00101004,
+	0x10400200, 0x00080008, 0x00200800, 0x40001004,
+	0x10440200, 0x00080008, 0x04200800, 0x40101004,
+	0x10000600, 0x00080020, 0x08200000, 0x00001104,
+	0x10040600, 0x00080020, 0x0c200000, 0x00101104,
+	0x10400600, 0x00080028, 0x08200800, 0x40001104,
+	0x10440600, 0x00080028, 0x0c200800, 0x40101104,
+	0x90000200, 0x00080010, 0x00200000, 0x00801004,
+	0x90040200, 0x00080010, 0x04200000, 0x00901004,
+	0x90400200, 0x00080018, 0x00200800, 0x40801004,
+	0x90440200, 0x00080018, 0x04200800, 0x40901004,
+	0x90000600, 0x00080030, 0x08200000, 0x00801104,
+	0x90040600, 0x00080030, 0x0c200000, 0x00901104,
+	0x90400600, 0x00080038, 0x08200800, 0x40801104,
+	0x90440600, 0x00080038, 0x0c200800, 0x40901104,
+	0x00000002, 0x00002000, 0x20000000, 0x00000001,
+	0x00040002, 0x00002000, 0x24000000, 0x00100001,
+	0x00400002, 0x00002008, 0x20000800, 0x40000001,
+	0x00440002, 0x00002008, 0x24000800, 0x40100001,
+	0x00000402, 0x00002020, 0x28000000, 0x00000101,
+	0x00040402, 0x00002020, 0x2c000000, 0x00100101,
+	0x00400402, 0x00002028, 0x28000800, 0x40000101,
+	0x00440402, 0x00002028, 0x2c000800, 0x40100101,
+	0x80000002, 0x00002010, 0x20000000, 0x00800001,
+	0x80040002, 0x00002010, 0x24000000, 0x00900001,
+	0x80400002, 0x00002018, 0x20000800, 0x40800001,
+	0x80440002, 0x00002018, 0x24000800, 0x40900001,
+	0x80000402, 0x00002030, 0x28000000, 0x00800101,
+	0x80040402, 0x00002030, 0x2c000000, 0x00900101,
+	0x80400402, 0x00002038, 0x28000800, 0x40800101,
+	0x80440402, 0x00002038, 0x2c000800, 0x40900101,
+	0x10000002, 0x00002000, 0x20200000, 0x00001001,
+	0x10040002, 0x00002000, 0x24200000, 0x00101001,
+	0x10400002, 0x00002008, 0x20200800, 0x40001001,
+	0x10440002, 0x00002008, 0x24200800, 0x40101001,
+	0x10000402, 0x00002020, 0x28200000, 0x00001101,
+	0x10040402, 0x00002020, 0x2c200000, 0x00101101,
+	0x10400402, 0x00002028, 0x28200800, 0x40001101,
+	0x10440402, 0x00002028, 0x2c200800, 0x40101101,
+	0x90000002, 0x00002010, 0x20200000, 0x00801001,
+	0x90040002, 0x00002010, 0x24200000, 0x00901001,
+	0x90400002, 0x00002018, 0x20200800, 0x40801001,
+	0x90440002, 0x00002018, 0x24200800, 0x40901001,
+	0x90000402, 0x00002030, 0x28200000, 0x00801101,
+	0x90040402, 0x00002030, 0x2c200000, 0x00901101,
+	0x90400402, 0x00002038, 0x28200800, 0x40801101,
+	0x90440402, 0x00002038, 0x2c200800, 0x40901101,
+	0x00000202, 0x00082000, 0x20000000, 0x00000005,
+	0x00040202, 0x00082000, 0x24000000, 0x00100005,
+	0x00400202, 0x00082008, 0x20000800, 0x40000005,
+	0x00440202, 0x00082008, 0x24000800, 0x40100005,
+	0x00000602, 0x00082020, 0x28000000, 0x00000105,
+	0x00040602, 0x00082020, 0x2c000000, 0x00100105,
+	0x00400602, 0x00082028, 0x28000800, 0x40000105,
+	0x00440602, 0x00082028, 0x2c000800, 0x40100105,
+	0x80000202, 0x00082010, 0x20000000, 0x00800005,
+	0x80040202, 0x00082010, 0x24000000, 0x00900005,
+	0x80400202, 0x00082018, 0x20000800, 0x40800005,
+	0x80440202, 0x00082018, 0x24000800, 0x40900005,
+	0x80000602, 0x00082030, 0x28000000, 0x00800105,
+	0x80040602, 0x00082030, 0x2c000000, 0x00900105,
+	0x80400602, 0x00082038, 0x28000800, 0x40800105,
+	0x80440602, 0x00082038, 0x2c000800, 0x40900105,
+	0x10000202, 0x00082000, 0x20200000, 0x00001005,
+	0x10040202, 0x00082000, 0x24200000, 0x00101005,
+	0x10400202, 0x00082008, 0x20200800, 0x40001005,
+	0x10440202, 0x00082008, 0x24200800, 0x40101005,
+	0x10000602, 0x00082020, 0x28200000, 0x00001105,
+	0x10040602, 0x00082020, 0x2c200000, 0x00101105,
+	0x10400602, 0x00082028, 0x28200800, 0x40001105,
+	0x10440602, 0x00082028, 0x2c200800, 0x40101105,
+	0x90000202, 0x00082010, 0x20200000, 0x00801005,
+	0x90040202, 0x00082010, 0x24200000, 0x00901005,
+	0x90400202, 0x00082018, 0x20200800, 0x40801005,
+	0x90440202, 0x00082018, 0x24200800, 0x40901005,
+	0x90000602, 0x00082030, 0x28200000, 0x00801105,
+	0x90040602, 0x00082030, 0x2c200000, 0x00901105,
+	0x90400602, 0x00082038, 0x28200800, 0x40801105,
+	0x90440602, 0x00082038, 0x2c200800, 0x40901105,
+
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000008, 0x00080000, 0x10000000,
+	0x02000000, 0x00000000, 0x00000080, 0x00001000,
+	0x02000000, 0x00000008, 0x00080080, 0x10001000,
+	0x00004000, 0x00000000, 0x00000040, 0x00040000,
+	0x00004000, 0x00000008, 0x00080040, 0x10040000,
+	0x02004000, 0x00000000, 0x000000c0, 0x00041000,
+	0x02004000, 0x00000008, 0x000800c0, 0x10041000,
+	0x00020000, 0x00008000, 0x08000000, 0x00200000,
+	0x00020000, 0x00008008, 0x08080000, 0x10200000,
+	0x02020000, 0x00008000, 0x08000080, 0x00201000,
+	0x02020000, 0x00008008, 0x08080080, 0x10201000,
+	0x00024000, 0x00008000, 0x08000040, 0x00240000,
+	0x00024000, 0x00008008, 0x08080040, 0x10240000,
+	0x02024000, 0x00008000, 0x080000c0, 0x00241000,
+	0x02024000, 0x00008008, 0x080800c0, 0x10241000,
+	0x00000000, 0x01000000, 0x00002000, 0x00000020,
+	0x00000000, 0x01000008, 0x00082000, 0x10000020,
+	0x02000000, 0x01000000, 0x00002080, 0x00001020,
+	0x02000000, 0x01000008, 0x00082080, 0x10001020,
+	0x00004000, 0x01000000, 0x00002040, 0x00040020,
+	0x00004000, 0x01000008, 0x00082040, 0x10040020,
+	0x02004000, 0x01000000, 0x000020c0, 0x00041020,
+	0x02004000, 0x01000008, 0x000820c0, 0x10041020,
+	0x00020000, 0x01008000, 0x08002000, 0x00200020,
+	0x00020000, 0x01008008, 0x08082000, 0x10200020,
+	0x02020000, 0x01008000, 0x08002080, 0x00201020,
+	0x02020000, 0x01008008, 0x08082080, 0x10201020,
+	0x00024000, 0x01008000, 0x08002040, 0x00240020,
+	0x00024000, 0x01008008, 0x08082040, 0x10240020,
+	0x02024000, 0x01008000, 0x080020c0, 0x00241020,
+	0x02024000, 0x01008008, 0x080820c0, 0x10241020,
+	0x00000400, 0x04000000, 0x00100000, 0x00000004,
+	0x00000400, 0x04000008, 0x00180000, 0x10000004,
+	0x02000400, 0x04000000, 0x00100080, 0x00001004,
+	0x02000400, 0x04000008, 0x00180080, 0x10001004,
+	0x00004400, 0x04000000, 0x00100040, 0x00040004,
+	0x00004400, 0x04000008, 0x00180040, 0x10040004,
+	0x02004400, 0x04000000, 0x001000c0, 0x00041004,
+	0x02004400, 0x04000008, 0x001800c0, 0x10041004,
+	0x00020400, 0x04008000, 0x08100000, 0x00200004,
+	0x00020400, 0x04008008, 0x08180000, 0x10200004,
+	0x02020400, 0x04008000, 0x08100080, 0x00201004,
+	0x02020400, 0x04008008, 0x08180080, 0x10201004,
+	0x00024400, 0x04008000, 0x08100040, 0x00240004,
+	0x00024400, 0x04008008, 0x08180040, 0x10240004,
+	0x02024400, 0x04008000, 0x081000c0, 0x00241004,
+	0x02024400, 0x04008008, 0x081800c0, 0x10241004,
+	0x00000400, 0x05000000, 0x00102000, 0x00000024,
+	0x00000400, 0x05000008, 0x00182000, 0x10000024,
+	0x02000400, 0x05000000, 0x00102080, 0x00001024,
+	0x02000400, 0x05000008, 0x00182080, 0x10001024,
+	0x00004400, 0x05000000, 0x00102040, 0x00040024,
+	0x00004400, 0x05000008, 0x00182040, 0x10040024,
+	0x02004400, 0x05000000, 0x001020c0, 0x00041024,
+	0x02004400, 0x05000008, 0x001820c0, 0x10041024,
+	0x00020400, 0x05008000, 0x08102000, 0x00200024,
+	0x00020400, 0x05008008, 0x08182000, 0x10200024,
+	0x02020400, 0x05008000, 0x08102080, 0x00201024,
+	0x02020400, 0x05008008, 0x08182080, 0x10201024,
+	0x00024400, 0x05008000, 0x08102040, 0x00240024,
+	0x00024400, 0x05008008, 0x08182040, 0x10240024,
+	0x02024400, 0x05008000, 0x081020c0, 0x00241024,
+	0x02024400, 0x05008008, 0x081820c0, 0x10241024,
+	0x00000800, 0x00010000, 0x20000000, 0x00000010,
+	0x00000800, 0x00010008, 0x20080000, 0x10000010,
+	0x02000800, 0x00010000, 0x20000080, 0x00001010,
+	0x02000800, 0x00010008, 0x20080080, 0x10001010,
+	0x00004800, 0x00010000, 0x20000040, 0x00040010,
+	0x00004800, 0x00010008, 0x20080040, 0x10040010,
+	0x02004800, 0x00010000, 0x200000c0, 0x00041010,
+	0x02004800, 0x00010008, 0x200800c0, 0x10041010,
+	0x00020800, 0x00018000, 0x28000000, 0x00200010,
+	0x00020800, 0x00018008, 0x28080000, 0x10200010,
+	0x02020800, 0x00018000, 0x28000080, 0x00201010,
+	0x02020800, 0x00018008, 0x28080080, 0x10201010,
+	0x00024800, 0x00018000, 0x28000040, 0x00240010,
+	0x00024800, 0x00018008, 0x28080040, 0x10240010,
+	0x02024800, 0x00018000, 0x280000c0, 0x00241010,
+	0x02024800, 0x00018008, 0x280800c0, 0x10241010,
+	0x00000800, 0x01010000, 0x20002000, 0x00000030,
+	0x00000800, 0x01010008, 0x20082000, 0x10000030,
+	0x02000800, 0x01010000, 0x20002080, 0x00001030,
+	0x02000800, 0x01010008, 0x20082080, 0x10001030,
+	0x00004800, 0x01010000, 0x20002040, 0x00040030,
+	0x00004800, 0x01010008, 0x20082040, 0x10040030,
+	0x02004800, 0x01010000, 0x200020c0, 0x00041030,
+	0x02004800, 0x01010008, 0x200820c0, 0x10041030,
+	0x00020800, 0x01018000, 0x28002000, 0x00200030,
+	0x00020800, 0x01018008, 0x28082000, 0x10200030,
+	0x02020800, 0x01018000, 0x28002080, 0x00201030,
+	0x02020800, 0x01018008, 0x28082080, 0x10201030,
+	0x00024800, 0x01018000, 0x28002040, 0x00240030,
+	0x00024800, 0x01018008, 0x28082040, 0x10240030,
+	0x02024800, 0x01018000, 0x280020c0, 0x00241030,
+	0x02024800, 0x01018008, 0x280820c0, 0x10241030,
+	0x00000c00, 0x04010000, 0x20100000, 0x00000014,
+	0x00000c00, 0x04010008, 0x20180000, 0x10000014,
+	0x02000c00, 0x04010000, 0x20100080, 0x00001014,
+	0x02000c00, 0x04010008, 0x20180080, 0x10001014,
+	0x00004c00, 0x04010000, 0x20100040, 0x00040014,
+	0x00004c00, 0x04010008, 0x20180040, 0x10040014,
+	0x02004c00, 0x04010000, 0x201000c0, 0x00041014,
+	0x02004c00, 0x04010008, 0x201800c0, 0x10041014,
+	0x00020c00, 0x04018000, 0x28100000, 0x00200014,
+	0x00020c00, 0x04018008, 0x28180000, 0x10200014,
+	0x02020c00, 0x04018000, 0x28100080, 0x00201014,
+	0x02020c00, 0x04018008, 0x28180080, 0x10201014,
+	0x00024c00, 0x04018000, 0x28100040, 0x00240014,
+	0x00024c00, 0x04018008, 0x28180040, 0x10240014,
+	0x02024c00, 0x04018000, 0x281000c0, 0x00241014,
+	0x02024c00, 0x04018008, 0x281800c0, 0x10241014,
+	0x00000c00, 0x05010000, 0x20102000, 0x00000034,
+	0x00000c00, 0x05010008, 0x20182000, 0x10000034,
+	0x02000c00, 0x05010000, 0x20102080, 0x00001034,
+	0x02000c00, 0x05010008, 0x20182080, 0x10001034,
+	0x00004c00, 0x05010000, 0x20102040, 0x00040034,
+	0x00004c00, 0x05010008, 0x20182040, 0x10040034,
+	0x02004c00, 0x05010000, 0x201020c0, 0x00041034,
+	0x02004c00, 0x05010008, 0x201820c0, 0x10041034,
+	0x00020c00, 0x05018000, 0x28102000, 0x00200034,
+	0x00020c00, 0x05018008, 0x28182000, 0x10200034,
+	0x02020c00, 0x05018000, 0x28102080, 0x00201034,
+	0x02020c00, 0x05018008, 0x28182080, 0x10201034,
+	0x00024c00, 0x05018000, 0x28102040, 0x00240034,
+	0x00024c00, 0x05018008, 0x28182040, 0x10240034,
+	0x02024c00, 0x05018000, 0x281020c0, 0x00241034,
+	0x02024c00, 0x05018008, 0x281820c0, 0x10241034
 };
 
+/* S-box lookup tables */
 
-static void des_small_fips_encrypt(u32 *expkey, u8 *dst, const u8 *src)
+static const u32 S1[64] = {
+	0x01010400, 0x00000000, 0x00010000, 0x01010404,
+	0x01010004, 0x00010404, 0x00000004, 0x00010000,
+	0x00000400, 0x01010400, 0x01010404, 0x00000400,
+	0x01000404, 0x01010004, 0x01000000, 0x00000004,
+	0x00000404, 0x01000400, 0x01000400, 0x00010400,
+	0x00010400, 0x01010000, 0x01010000, 0x01000404,
+	0x00010004, 0x01000004, 0x01000004, 0x00010004,
+	0x00000000, 0x00000404, 0x00010404, 0x01000000,
+	0x00010000, 0x01010404, 0x00000004, 0x01010000,
+	0x01010400, 0x01000000, 0x01000000, 0x00000400,
+	0x01010004, 0x00010000, 0x00010400, 0x01000004,
+	0x00000400, 0x00000004, 0x01000404, 0x00010404,
+	0x01010404, 0x00010004, 0x01010000, 0x01000404,
+	0x01000004, 0x00000404, 0x00010404, 0x01010400,
+	0x00000404, 0x01000400, 0x01000400, 0x00000000,
+	0x00010004, 0x00010400, 0x00000000, 0x01010004
+};
+
+static const u32 S2[64] = {
+	0x80108020, 0x80008000, 0x00008000, 0x00108020,
+	0x00100000, 0x00000020, 0x80100020, 0x80008020,
+	0x80000020, 0x80108020, 0x80108000, 0x80000000,
+	0x80008000, 0x00100000, 0x00000020, 0x80100020,
+	0x00108000, 0x00100020, 0x80008020, 0x00000000,
+	0x80000000, 0x00008000, 0x00108020, 0x80100000,
+	0x00100020, 0x80000020, 0x00000000, 0x00108000,
+	0x00008020, 0x80108000, 0x80100000, 0x00008020,
+	0x00000000, 0x00108020, 0x80100020, 0x00100000,
+	0x80008020, 0x80100000, 0x80108000, 0x00008000,
+	0x80100000, 0x80008000, 0x00000020, 0x80108020,
+	0x00108020, 0x00000020, 0x00008000, 0x80000000,
+	0x00008020, 0x80108000, 0x00100000, 0x80000020,
+	0x00100020, 0x80008020, 0x80000020, 0x00100020,
+	0x00108000, 0x00000000, 0x80008000, 0x00008020,
+	0x80000000, 0x80100020, 0x80108020, 0x00108000
+};
+
+static const u32 S3[64] = {
+	0x00000208, 0x08020200, 0x00000000, 0x08020008,
+	0x08000200, 0x00000000, 0x00020208, 0x08000200,
+	0x00020008, 0x08000008, 0x08000008, 0x00020000,
+	0x08020208, 0x00020008, 0x08020000, 0x00000208,
+	0x08000000, 0x00000008, 0x08020200, 0x00000200,
+	0x00020200, 0x08020000, 0x08020008, 0x00020208,
+	0x08000208, 0x00020200, 0x00020000, 0x08000208,
+	0x00000008, 0x08020208, 0x00000200, 0x08000000,
+	0x08020200, 0x08000000, 0x00020008, 0x00000208,
+	0x00020000, 0x08020200, 0x08000200, 0x00000000,
+	0x00000200, 0x00020008, 0x08020208, 0x08000200,
+	0x08000008, 0x00000200, 0x00000000, 0x08020008,
+	0x08000208, 0x00020000, 0x08000000, 0x08020208,
+	0x00000008, 0x00020208, 0x00020200, 0x08000008,
+	0x08020000, 0x08000208, 0x00000208, 0x08020000,
+	0x00020208, 0x00000008, 0x08020008, 0x00020200
+};
+
+static const u32 S4[64] = {
+	0x00802001, 0x00002081, 0x00002081, 0x00000080,
+	0x00802080, 0x00800081, 0x00800001, 0x00002001,
+	0x00000000, 0x00802000, 0x00802000, 0x00802081,
+	0x00000081, 0x00000000, 0x00800080, 0x00800001,
+	0x00000001, 0x00002000, 0x00800000, 0x00802001,
+	0x00000080, 0x00800000, 0x00002001, 0x00002080,
+	0x00800081, 0x00000001, 0x00002080, 0x00800080,
+	0x00002000, 0x00802080, 0x00802081, 0x00000081,
+	0x00800080, 0x00800001, 0x00802000, 0x00802081,
+	0x00000081, 0x00000000, 0x00000000, 0x00802000,
+	0x00002080, 0x00800080, 0x00800081, 0x00000001,
+	0x00802001, 0x00002081, 0x00002081, 0x00000080,
+	0x00802081, 0x00000081, 0x00000001, 0x00002000,
+	0x00800001, 0x00002001, 0x00802080, 0x00800081,
+	0x00002001, 0x00002080, 0x00800000, 0x00802001,
+	0x00000080, 0x00800000, 0x00002000, 0x00802080
+};
+
+static const u32 S5[64] = {
+	0x00000100, 0x02080100, 0x02080000, 0x42000100,
+	0x00080000, 0x00000100, 0x40000000, 0x02080000,
+	0x40080100, 0x00080000, 0x02000100, 0x40080100,
+	0x42000100, 0x42080000, 0x00080100, 0x40000000,
+	0x02000000, 0x40080000, 0x40080000, 0x00000000,
+	0x40000100, 0x42080100, 0x42080100, 0x02000100,
+	0x42080000, 0x40000100, 0x00000000, 0x42000000,
+	0x02080100, 0x02000000, 0x42000000, 0x00080100,
+	0x00080000, 0x42000100, 0x00000100, 0x02000000,
+	0x40000000, 0x02080000, 0x42000100, 0x40080100,
+	0x02000100, 0x40000000, 0x42080000, 0x02080100,
+	0x40080100, 0x00000100, 0x02000000, 0x42080000,
+	0x42080100, 0x00080100, 0x42000000, 0x42080100,
+	0x02080000, 0x00000000, 0x40080000, 0x42000000,
+	0x00080100, 0x02000100, 0x40000100, 0x00080000,
+	0x00000000, 0x40080000, 0x02080100, 0x40000100
+};
+
+static const u32 S6[64] = {
+	0x20000010, 0x20400000, 0x00004000, 0x20404010,
+	0x20400000, 0x00000010, 0x20404010, 0x00400000,
+	0x20004000, 0x00404010, 0x00400000, 0x20000010,
+	0x00400010, 0x20004000, 0x20000000, 0x00004010,
+	0x00000000, 0x00400010, 0x20004010, 0x00004000,
+	0x00404000, 0x20004010, 0x00000010, 0x20400010,
+	0x20400010, 0x00000000, 0x00404010, 0x20404000,
+	0x00004010, 0x00404000, 0x20404000, 0x20000000,
+	0x20004000, 0x00000010, 0x20400010, 0x00404000,
+	0x20404010, 0x00400000, 0x00004010, 0x20000010,
+	0x00400000, 0x20004000, 0x20000000, 0x00004010,
+	0x20000010, 0x20404010, 0x00404000, 0x20400000,
+	0x00404010, 0x20404000, 0x00000000, 0x20400010,
+	0x00000010, 0x00004000, 0x20400000, 0x00404010,
+	0x00004000, 0x00400010, 0x20004010, 0x00000000,
+	0x20404000, 0x20000000, 0x00400010, 0x20004010
+};
+
+static const u32 S7[64] = {
+	0x00200000, 0x04200002, 0x04000802, 0x00000000,
+	0x00000800, 0x04000802, 0x00200802, 0x04200800,
+	0x04200802, 0x00200000, 0x00000000, 0x04000002,
+	0x00000002, 0x04000000, 0x04200002, 0x00000802,
+	0x04000800, 0x00200802, 0x00200002, 0x04000800,
+	0x04000002, 0x04200000, 0x04200800, 0x00200002,
+	0x04200000, 0x00000800, 0x00000802, 0x04200802,
+	0x00200800, 0x00000002, 0x04000000, 0x00200800,
+	0x04000000, 0x00200800, 0x00200000, 0x04000802,
+	0x04000802, 0x04200002, 0x04200002, 0x00000002,
+	0x00200002, 0x04000000, 0x04000800, 0x00200000,
+	0x04200800, 0x00000802, 0x00200802, 0x04200800,
+	0x00000802, 0x04000002, 0x04200802, 0x04200000,
+	0x00200800, 0x00000000, 0x00000002, 0x04200802,
+	0x00000000, 0x00200802, 0x04200000, 0x00000800,
+	0x04000002, 0x04000800, 0x00000800, 0x00200002
+};
+
+static const u32 S8[64] = {
+	0x10001040, 0x00001000, 0x00040000, 0x10041040,
+	0x10000000, 0x10001040, 0x00000040, 0x10000000,
+	0x00040040, 0x10040000, 0x10041040, 0x00041000,
+	0x10041000, 0x00041040, 0x00001000, 0x00000040,
+	0x10040000, 0x10000040, 0x10001000, 0x00001040,
+	0x00041000, 0x00040040, 0x10040040, 0x10041000,
+	0x00001040, 0x00000000, 0x00000000, 0x10040040,
+	0x10000040, 0x10001000, 0x00041040, 0x00040000,
+	0x00041040, 0x00040000, 0x10041000, 0x00001000,
+	0x00000040, 0x10040040, 0x00001000, 0x00041040,
+	0x10001000, 0x00000040, 0x10000040, 0x10040000,
+	0x10040040, 0x10000000, 0x00040000, 0x10001040,
+	0x00000000, 0x10041040, 0x00040040, 0x10000040,
+	0x10040000, 0x10001000, 0x10001040, 0x00000000,
+	0x10041040, 0x00041000, 0x00041000, 0x00001040,
+	0x00001040, 0x00040040, 0x10000000, 0x10041000
+};
+
+/* Encryption components: IP, FP, and round function */
+
+#define IP(L, R, T)		\
+	ROL(R, 4);		\
+	T  = L;			\
+	L ^= R;			\
+	L &= 0xf0f0f0f0;	\
+	R ^= L;			\
+	L ^= T;			\
+	ROL(R, 12);		\
+	T  = L;			\
+	L ^= R;			\
+	L &= 0xffff0000;	\
+	R ^= L;			\
+	L ^= T;			\
+	ROR(R, 14);		\
+	T  = L;			\
+	L ^= R;			\
+	L &= 0xcccccccc;	\
+	R ^= L;			\
+	L ^= T;			\
+	ROL(R, 6);		\
+	T  = L;			\
+	L ^= R;			\
+	L &= 0xff00ff00;	\
+	R ^= L;			\
+	L ^= T;			\
+	ROR(R, 7);		\
+	T  = L;			\
+	L ^= R;			\
+	L &= 0xaaaaaaaa;	\
+	R ^= L;			\
+	L ^= T;			\
+	ROL(L, 1);
+
+#define FP(L, R, T)		\
+	ROR(L, 1);		\
+	T  = L;			\
+	L ^= R;			\
+	L &= 0xaaaaaaaa;	\
+	R ^= L;			\
+	L ^= T;			\
+	ROL(R, 7);		\
+	T  = L;			\
+	L ^= R;			\
+	L &= 0xff00ff00;	\
+	R ^= L;			\
+	L ^= T;			\
+	ROR(R, 6);		\
+	T  = L;			\
+	L ^= R;			\
+	L &= 0xcccccccc;	\
+	R ^= L;			\
+	L ^= T;			\
+	ROL(R, 14);		\
+	T  = L;			\
+	L ^= R;			\
+	L &= 0xffff0000;	\
+	R ^= L;			\
+	L ^= T;			\
+	ROR(R, 12);		\
+	T  = L;			\
+	L ^= R;			\
+	L &= 0xf0f0f0f0;	\
+	R ^= L;			\
+	L ^= T;			\
+	ROR(R, 4);
+
+#define ROUND(L, R, A, B, K, d)					\
+	B = K[0];			A = K[1];	K += d;	\
+	B ^= R;				A ^= R;			\
+	B &= 0x3f3f3f3f;		ROR(A, 4);		\
+	L ^= S8[0xff & B];		A &= 0x3f3f3f3f;	\
+	L ^= S6[0xff & (B >> 8)];	B >>= 16;		\
+	L ^= S7[0xff & A];					\
+	L ^= S5[0xff & (A >> 8)];	A >>= 16;		\
+	L ^= S4[0xff & B];					\
+	L ^= S2[0xff & (B >> 8)];				\
+	L ^= S3[0xff & A];					\
+	L ^= S1[0xff & (A >> 8)];
+
+/*
+ * PC2 lookup tables are organized as 2 consecutive sets of 4 interleaved
+ * tables of 128 elements.  One set is for C_i and the other for D_i, while
+ * the 4 interleaved tables correspond to four 7-bit subsets of C_i or D_i.
+ *
+ * After PC1 each of the variables a,b,c,d contains a 7 bit subset of C_i
+ * or D_i in bits 7-1 (bit 0 being the least significant).
+ */
+
+#define T1(x) pt[2 * (x) + 0]
+#define T2(x) pt[2 * (x) + 1]
+#define T3(x) pt[2 * (x) + 2]
+#define T4(x) pt[2 * (x) + 3]
+
+#define PC2(a, b, c, d) (T4(d) | T3(c) | T2(b) | T1(a))
+
+/*
+ * Encryption key expansion
+ *
+ * RFC2451: Weak key checks SHOULD be performed.
+ *
+ * FIPS 74:
+ *
+ *   Keys having duals are keys which produce all zeros, all ones, or
+ *   alternating zero-one patterns in the C and D registers after Permuted
+ *   Choice 1 has operated on the key.
+ *
+ */
+static unsigned long ekey(u32 *pe, const u8 *k)
 {
-	u32 x, y, z;
-	
-	x  = src[7];
-	x <<= 8;
-	x |= src[6];
-	x <<= 8;
-	x |= src[5];
-	x <<= 8;
-	x |= src[4];
-	y  = src[3];
-	y <<= 8;
-	y |= src[2];
-	y <<= 8;
-	y |= src[1];
-	y <<= 8;
-	y |= src[0];
-	z  = ((x >> 004) ^ y) & 0x0F0F0F0FL;
-	x ^= z << 004;
-	y ^= z;
-	z  = ((y >> 020) ^ x) & 0x0000FFFFL;
-	y ^= z << 020;
-	x ^= z;
-	z  = ((x >> 002) ^ y) & 0x33333333L;
-	x ^= z << 002;
-	y ^= z;
-	z  = ((y >> 010) ^ x) & 0x00FF00FFL;
-	y ^= z << 010;
-	x ^= z;
-	x  = x >> 1 | x << 31;
-	z  = (x ^ y) & 0x55555555L;
-	y ^= z;
-	x ^= z;
-	y  = y >> 1 | y << 31;
-	z  = expkey[0];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[1];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[2];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[3];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[4];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[5];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[6];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[7];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[8];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[9];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[10];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[11];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[12];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[13];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[14];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[15];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[16];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[17];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[18];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[19];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[20];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[21];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[22];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[23];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[24];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[25];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[26];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[27];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[28];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[29];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[30];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[31];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	x  = x << 1 | x >> 31;
-	z  = (x ^ y) & 0x55555555L;
-	y ^= z;
-	x ^= z;
-	y  = y << 1 | y >> 31;
-	z  = ((x >> 010) ^ y) & 0x00FF00FFL;
-	x ^= z << 010;
-	y ^= z;
-	z  = ((y >> 002) ^ x) & 0x33333333L;
-	y ^= z << 002;
-	x ^= z;
-	z  = ((x >> 020) ^ y) & 0x0000FFFFL;
-	x ^= z << 020;
-	y ^= z;
-	z  = ((y >> 004) ^ x) & 0x0F0F0F0FL;
-	y ^= z << 004;
-	x ^= z;
-	dst[0] = x;
-	x >>= 8;
-	dst[1] = x;
-	x >>= 8;
-	dst[2] = x;
-	x >>= 8;
-	dst[3] = x;
-	dst[4] = y;
-	y >>= 8;
-	dst[5] = y;
-	y >>= 8;
-	dst[6] = y;
-	y >>= 8;
-	dst[7] = y;
-}
+	/* K&R: long is at least 32 bits */
+	unsigned long a, b, c, d, w;
+	const u32 *pt = pc2;
 
-static void des_small_fips_decrypt(u32 *expkey, u8 *dst, const u8 *src)
-{
-	u32 x, y, z;
-	
-	x  = src[7];
-	x <<= 8;
-	x |= src[6];
-	x <<= 8;
-	x |= src[5];
-	x <<= 8;
-	x |= src[4];
-	y  = src[3];
-	y <<= 8;
-	y |= src[2];
-	y <<= 8;
-	y |= src[1];
-	y <<= 8;
-	y |= src[0];
-	z  = ((x >> 004) ^ y) & 0x0F0F0F0FL;
-	x ^= z << 004;
-	y ^= z;
-	z  = ((y >> 020) ^ x) & 0x0000FFFFL;
-	y ^= z << 020;
-	x ^= z;
-	z  = ((x >> 002) ^ y) & 0x33333333L;
-	x ^= z << 002;
-	y ^= z;
-	z  = ((y >> 010) ^ x) & 0x00FF00FFL;
-	y ^= z << 010;
-	x ^= z;
-	x  = x >> 1 | x << 31;
-	z  = (x ^ y) & 0x55555555L;
-	y ^= z;
-	x ^= z;
-	y  = y >> 1 | y << 31;
-	z  = expkey[31];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[30];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[29];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[28];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[27];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[26];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[25];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[24];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[23];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[22];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[21];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[20];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[19];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[18];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[17];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[16];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[15];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[14];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[13];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[12];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[11];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[10];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[9];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[8];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[7];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[6];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[5];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[4];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[3];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[2];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[1];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[0];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	x  = x << 1 | x >> 31;
-	z  = (x ^ y) & 0x55555555L;
-	y ^= z;
-	x ^= z;
-	y  = y << 1 | y >> 31;
-	z  = ((x >> 010) ^ y) & 0x00FF00FFL;
-	x ^= z << 010;
-	y ^= z;
-	z  = ((y >> 002) ^ x) & 0x33333333L;
-	y ^= z << 002;
-	x ^= z;
-	z  = ((x >> 020) ^ y) & 0x0000FFFFL;
-	x ^= z << 020;
-	y ^= z;
-	z  = ((y >> 004) ^ x) & 0x0F0F0F0FL;
-	y ^= z << 004;
-	x ^= z;
-	dst[0] = x;
-	x >>= 8;
-	dst[1] = x;
-	x >>= 8;
-	dst[2] = x;
-	x >>= 8;
-	dst[3] = x;
-	dst[4] = y;
-	y >>= 8;
-	dst[5] = y;
-	y >>= 8;
-	dst[6] = y;
-	y >>= 8;
-	dst[7] = y;
+	d = k[4]; d &= 0x0e; d <<= 4; d |= k[0] & 0x1e; d = pc1[d];
+	c = k[5]; c &= 0x0e; c <<= 4; c |= k[1] & 0x1e; c = pc1[c];
+	b = k[6]; b &= 0x0e; b <<= 4; b |= k[2] & 0x1e; b = pc1[b];
+	a = k[7]; a &= 0x0e; a <<= 4; a |= k[3] & 0x1e; a = pc1[a];
+
+	pe[15 * 2 + 0] = PC2(a, b, c, d); d = rs[d];
+	pe[14 * 2 + 0] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[13 * 2 + 0] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[12 * 2 + 0] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[11 * 2 + 0] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[10 * 2 + 0] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[ 9 * 2 + 0] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[ 8 * 2 + 0] = PC2(d, a, b, c); c = rs[c];
+	pe[ 7 * 2 + 0] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[ 6 * 2 + 0] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[ 5 * 2 + 0] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[ 4 * 2 + 0] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[ 3 * 2 + 0] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[ 2 * 2 + 0] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[ 1 * 2 + 0] = PC2(c, d, a, b); b = rs[b];
+	pe[ 0 * 2 + 0] = PC2(b, c, d, a);
+
+	/* Check if first half is weak */
+	w  = (a ^ c) | (b ^ d) | (rs[a] ^ c) | (b ^ rs[d]);
+
+	/* Skip to next table set */
+	pt += 512;
+
+	d = k[0]; d &= 0xe0; d >>= 4; d |= k[4] & 0xf0; d = pc1[d + 1];
+	c = k[1]; c &= 0xe0; c >>= 4; c |= k[5] & 0xf0; c = pc1[c + 1];
+	b = k[2]; b &= 0xe0; b >>= 4; b |= k[6] & 0xf0; b = pc1[b + 1];
+	a = k[3]; a &= 0xe0; a >>= 4; a |= k[7] & 0xf0; a = pc1[a + 1];
+
+	/* Check if second half is weak */
+	w |= (a ^ c) | (b ^ d) | (rs[a] ^ c) | (b ^ rs[d]);
+
+	pe[15 * 2 + 1] = PC2(a, b, c, d); d = rs[d];
+	pe[14 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[13 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[12 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[11 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[10 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[ 9 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[ 8 * 2 + 1] = PC2(d, a, b, c); c = rs[c];
+	pe[ 7 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[ 6 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[ 5 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[ 4 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[ 3 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[ 2 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[ 1 * 2 + 1] = PC2(c, d, a, b); b = rs[b];
+	pe[ 0 * 2 + 1] = PC2(b, c, d, a);
+
+	/* Fixup: 2413 5768 -> 1357 2468 */
+	for (d = 0; d < 16; ++d) {
+		a = pe[2 * d];
+		b = pe[2 * d + 1];
+		c = a ^ b;
+		c &= 0xffff0000;
+		a ^= c;
+		b ^= c;
+		ROL(b, 18);
+		pe[2 * d] = a;
+		pe[2 * d + 1] = b;
+	}
+
+	/* Zero if weak key */
+	return w;
 }
 
 /*
- * RFC2451: Weak key checks SHOULD be performed.
+ * Decryption key expansion
+ *
+ * No weak key checking is performed, as this is only used by triple DES
+ *
  */
-static int setkey(u32 *expkey, const u8 *key, unsigned int keylen, u32 *flags)
+static void dkey(u32 *pe, const u8 *k)
 {
-	const u8 *k;
-	u8 *b0, *b1;
-	u32 n, w;
-	u8 bits0[56], bits1[56];
+	/* K&R: long is at least 32 bits */
+	unsigned long a, b, c, d;
+	const u32 *pt = pc2;
 
-	n  = parity[key[0]]; n <<= 4;
-	n |= parity[key[1]]; n <<= 4;
-	n |= parity[key[2]]; n <<= 4;
-	n |= parity[key[3]]; n <<= 4;
-	n |= parity[key[4]]; n <<= 4;
-	n |= parity[key[5]]; n <<= 4;
-	n |= parity[key[6]]; n <<= 4;
-	n |= parity[key[7]];
-	w = 0x88888888L;
-	
-	if ((*flags & CRYPTO_TFM_REQ_WEAK_KEY)
-	    && !((n - (w >> 3)) & w)) {  /* 1 in 10^10 keys passes this test */
-		if (n < 0x41415151) {
-			if (n < 0x31312121) {
-				if (n < 0x14141515) {
-					/* 01 01 01 01 01 01 01 01 */
-					if (n == 0x11111111) goto weak;
-					/* 01 1F 01 1F 01 0E 01 0E */
-					if (n == 0x13131212) goto weak;
-				} else {
-					/* 01 E0 01 E0 01 F1 01 F1 */
-					if (n == 0x14141515) goto weak;
-					/* 01 FE 01 FE 01 FE 01 FE */
-					if (n == 0x16161616) goto weak;
-				}
-			} else {
-				if (n < 0x34342525) {
-					/* 1F 01 1F 01 0E 01 0E 01 */
-					if (n == 0x31312121) goto weak;
-					/* 1F 1F 1F 1F 0E 0E 0E 0E (?) */
-					if (n == 0x33332222) goto weak;
-				} else {
-					/* 1F E0 1F E0 0E F1 0E F1 */
-					if (n == 0x34342525) goto weak;
-					/* 1F FE 1F FE 0E FE 0E FE */
-					if (n == 0x36362626) goto weak;
-				}
-			}
-		} else {
-			if (n < 0x61616161) {
-				if (n < 0x44445555) {
-					/* E0 01 E0 01 F1 01 F1 01 */
-					if (n == 0x41415151) goto weak;
-					/* E0 1F E0 1F F1 0E F1 0E */
-					if (n == 0x43435252) goto weak;
-				} else {
-					/* E0 E0 E0 E0 F1 F1 F1 F1 (?) */
-					if (n == 0x44445555) goto weak;
-					/* E0 FE E0 FE F1 FE F1 FE */
-					if (n == 0x46465656) goto weak;
-				}
-			} else {
-				if (n < 0x64646565) {
-					/* FE 01 FE 01 FE 01 FE 01 */
-					if (n == 0x61616161) goto weak;
-					/* FE 1F FE 1F FE 0E FE 0E */
-					if (n == 0x63636262) goto weak;
-				} else {
-					/* FE E0 FE E0 FE F1 FE F1 */
-					if (n == 0x64646565) goto weak;
-					/* FE FE FE FE FE FE FE FE */
-					if (n == 0x66666666) goto weak;
-				}
-			}
-		}
-	
-		goto not_weak;
-weak:
-		*flags |= CRYPTO_TFM_RES_WEAK_KEY;
-		return -EINVAL;
+	d = k[4]; d &= 0x0e; d <<= 4; d |= k[0] & 0x1e; d = pc1[d];
+	c = k[5]; c &= 0x0e; c <<= 4; c |= k[1] & 0x1e; c = pc1[c];
+	b = k[6]; b &= 0x0e; b <<= 4; b |= k[2] & 0x1e; b = pc1[b];
+	a = k[7]; a &= 0x0e; a <<= 4; a |= k[3] & 0x1e; a = pc1[a];
+
+	pe[ 0 * 2] = PC2(a, b, c, d); d = rs[d];
+	pe[ 1 * 2] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[ 2 * 2] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[ 3 * 2] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[ 4 * 2] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[ 5 * 2] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[ 6 * 2] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[ 7 * 2] = PC2(d, a, b, c); c = rs[c];
+	pe[ 8 * 2] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[ 9 * 2] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[10 * 2] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[11 * 2] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[12 * 2] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[13 * 2] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[14 * 2] = PC2(c, d, a, b); b = rs[b];
+	pe[15 * 2] = PC2(b, c, d, a);
+
+	/* Skip to next table set */
+	pt += 512;
+
+	d = k[0]; d &= 0xe0; d >>= 4; d |= k[4] & 0xf0; d = pc1[d + 1];
+	c = k[1]; c &= 0xe0; c >>= 4; c |= k[5] & 0xf0; c = pc1[c + 1];
+	b = k[2]; b &= 0xe0; b >>= 4; b |= k[6] & 0xf0; b = pc1[b + 1];
+	a = k[3]; a &= 0xe0; a >>= 4; a |= k[7] & 0xf0; a = pc1[a + 1];
+
+	pe[ 0 * 2 + 1] = PC2(a, b, c, d); d = rs[d];
+	pe[ 1 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[ 2 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[ 3 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[ 4 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[ 5 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[ 6 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[ 7 * 2 + 1] = PC2(d, a, b, c); c = rs[c];
+	pe[ 8 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[ 9 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[10 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[11 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[12 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[13 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[14 * 2 + 1] = PC2(c, d, a, b); b = rs[b];
+	pe[15 * 2 + 1] = PC2(b, c, d, a);
+
+	/* Fixup: 2413 5768 -> 1357 2468 */
+	for (d = 0; d < 16; ++d) {
+		a = pe[2 * d];
+		b = pe[2 * d + 1];
+		c = a ^ b;
+		c &= 0xffff0000;
+		a ^= c;
+		b ^= c;
+		ROL(b, 18);
+		pe[2 * d] = a;
+		pe[2 * d + 1] = b;
 	}
-
-not_weak:
-
-	/* explode the bits */
-	n = 56;
-	b0 = bits0;
-	b1 = bits1;
-	
-	do {
-		w = (256 | *key++) << 2;
-		do {
-			--n;
-			b1[n] = 8 & w;
-			w >>= 1;
-			b0[n] = 4 & w;
-		} while ( w >= 16 );
-	} while ( n );
-	
-	/* put the bits in the correct places */
-	n = 16;
-	k = rotors;
-	
-	do {
-		w   = (b1[k[ 0   ]] | b0[k[ 1   ]]) << 4;
-		w  |= (b1[k[ 2   ]] | b0[k[ 3   ]]) << 2;
-		w  |=  b1[k[ 4   ]] | b0[k[ 5   ]];
-		w <<= 8;
-		w  |= (b1[k[ 6   ]] | b0[k[ 7   ]]) << 4;
-		w  |= (b1[k[ 8   ]] | b0[k[ 9   ]]) << 2;
-		w  |=  b1[k[10   ]] | b0[k[11   ]];
-		w <<= 8;
-		w  |= (b1[k[12   ]] | b0[k[13   ]]) << 4;
-		w  |= (b1[k[14   ]] | b0[k[15   ]]) << 2;
-		w  |=  b1[k[16   ]] | b0[k[17   ]];
-		w <<= 8;
-		w  |= (b1[k[18   ]] | b0[k[19   ]]) << 4;
-		w  |= (b1[k[20   ]] | b0[k[21   ]]) << 2;
-		w  |=  b1[k[22   ]] | b0[k[23   ]];
-		expkey[0] = w;
-		
-		w   = (b1[k[ 0+24]] | b0[k[ 1+24]]) << 4;
-		w  |= (b1[k[ 2+24]] | b0[k[ 3+24]]) << 2;
-		w  |=  b1[k[ 4+24]] | b0[k[ 5+24]];
-		w <<= 8;
-		w  |= (b1[k[ 6+24]] | b0[k[ 7+24]]) << 4;
-		w  |= (b1[k[ 8+24]] | b0[k[ 9+24]]) << 2;
-		w  |=  b1[k[10+24]] | b0[k[11+24]];
-		w <<= 8;
-		w  |= (b1[k[12+24]] | b0[k[13+24]]) << 4;
-		w  |= (b1[k[14+24]] | b0[k[15+24]]) << 2;
-		w  |=  b1[k[16+24]] | b0[k[17+24]];
-		w <<= 8;
-		w  |= (b1[k[18+24]] | b0[k[19+24]]) << 4;
-		w  |= (b1[k[20+24]] | b0[k[21+24]]) << 2;
-		w  |=  b1[k[22+24]] | b0[k[23+24]];
-		
-		ROR(w, 4, 28);      /* could be eliminated */
-		expkey[1] = w;
-
-		k += 48;
-		expkey += 2;
-	} while (--n);
-
-	return 0;
 }
 
 static int des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
 {
-	return setkey(((struct des_ctx *)ctx)->expkey, key, keylen, flags);
+	struct des_ctx *dctx = ctx;
+	u32 tmp[DES_EXPKEY_WORDS];
+	int ret;
+
+	/* Expand to tmp */
+	ret = ekey(tmp, key);
+
+	if (unlikely(ret == 0) && (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
+		*flags |= CRYPTO_TFM_RES_WEAK_KEY;
+		return -EINVAL;
+	}
+
+	/* Copy to output */
+	memcpy(dctx->expkey, tmp, sizeof(dctx->expkey));
+
+	return 0;
 }
 
 static void des_encrypt(void *ctx, u8 *dst, const u8 *src)
 {
-	des_small_fips_encrypt(((struct des_ctx *)ctx)->expkey, dst, src);
+	const u32 *K = ((struct des_ctx *)ctx)->expkey;
+	const __le32 *s = (const __le32 *)src;
+	__le32 *d = (__le32 *)dst;
+	u32 L, R, A, B;
+	int i;
+
+	L = le32_to_cpu(s[0]);
+	R = le32_to_cpu(s[1]);
+
+	IP(L, R, A);
+	for (i = 0; i < 8; i++) {
+		ROUND(L, R, A, B, K, 2);
+		ROUND(R, L, A, B, K, 2);
+	}
+	FP(R, L, A);
+
+	d[0] = cpu_to_le32(R);
+	d[1] = cpu_to_le32(L);
 }
 
 static void des_decrypt(void *ctx, u8 *dst, const u8 *src)
 {
-	des_small_fips_decrypt(((struct des_ctx *)ctx)->expkey, dst, src);
+	const u32 *K = ((struct des_ctx *)ctx)->expkey + DES_EXPKEY_WORDS - 2;
+	const __le32 *s = (const __le32 *)src;
+	__le32 *d = (__le32 *)dst;
+	u32 L, R, A, B;
+	int i;
+
+	L = le32_to_cpu(s[0]);
+	R = le32_to_cpu(s[1]);
+
+	IP(L, R, A);
+	for (i = 0; i < 8; i++) {
+		ROUND(L, R, A, B, K, -2);
+		ROUND(R, L, A, B, K, -2);
+	}
+	FP(R, L, A);
+
+	d[0] = cpu_to_le32(R);
+	d[1] = cpu_to_le32(L);
 }
 
-/* 
+/*
  * RFC2451:
  *
  *   For DES-EDE3, there is no known need to reject weak or
@@ -1199,44 +859,86 @@
  *
  */
 static int des3_ede_setkey(void *ctx, const u8 *key,
-                           unsigned int keylen, u32 *flags)
+			   unsigned int keylen, u32 *flags)
 {
-	unsigned int i, off;
+	const u32 *K = (const u32 *)key;
 	struct des3_ede_ctx *dctx = ctx;
+	u32 *expkey = dctx->expkey;
 
-	if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && 
-	    memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
-	    					DES_KEY_SIZE))) {
-
+	if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) ||
+		     !((K[2] ^ K[4]) | (K[3] ^ K[5]))))
+	{
 		*flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
 		return -EINVAL;
 	}
-	
-	for (i = 0, off = 0; i < 3; i++, off += DES_EXPKEY_WORDS,
-							key += DES_KEY_SIZE) {
-		int ret = setkey(&dctx->expkey[off], key, DES_KEY_SIZE, flags);
-		if (ret < 0)
-			return ret;
-	}	
+
+	ekey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE;
+	dkey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE;
+	ekey(expkey, key);
+
 	return 0;
 }
 
 static void des3_ede_encrypt(void *ctx, u8 *dst, const u8 *src)
 {
 	struct des3_ede_ctx *dctx = ctx;
-	
-	des_small_fips_encrypt(dctx->expkey, dst, src);
-	des_small_fips_decrypt(&dctx->expkey[DES_EXPKEY_WORDS], dst, dst);
-	des_small_fips_encrypt(&dctx->expkey[DES_EXPKEY_WORDS * 2], dst, dst);
+	const u32 *K = dctx->expkey;
+	const __le32 *s = (const __le32 *)src;
+	__le32 *d = (__le32 *)dst;
+	u32 L, R, A, B;
+	int i;
+
+	L = le32_to_cpu(s[0]);
+	R = le32_to_cpu(s[1]);
+
+	IP(L, R, A);
+	for (i = 0; i < 8; i++) {
+		ROUND(L, R, A, B, K, 2);
+		ROUND(R, L, A, B, K, 2);
+	}
+	for (i = 0; i < 8; i++) {
+		ROUND(R, L, A, B, K, 2);
+		ROUND(L, R, A, B, K, 2);
+	}
+	for (i = 0; i < 8; i++) {
+		ROUND(L, R, A, B, K, 2);
+		ROUND(R, L, A, B, K, 2);
+	}
+	FP(R, L, A);
+
+	d[0] = cpu_to_le32(R);
+	d[1] = cpu_to_le32(L);
 }
 
 static void des3_ede_decrypt(void *ctx, u8 *dst, const u8 *src)
 {
 	struct des3_ede_ctx *dctx = ctx;
+	const u32 *K = dctx->expkey + DES3_EDE_EXPKEY_WORDS - 2;
+	const __le32 *s = (const __le32 *)src;
+	__le32 *d = (__le32 *)dst;
+	u32 L, R, A, B;
+	int i;
 
-	des_small_fips_decrypt(&dctx->expkey[DES_EXPKEY_WORDS * 2], dst, src);
-	des_small_fips_encrypt(&dctx->expkey[DES_EXPKEY_WORDS], dst, dst);
-	des_small_fips_decrypt(dctx->expkey, dst, dst);
+	L = le32_to_cpu(s[0]);
+	R = le32_to_cpu(s[1]);
+
+	IP(L, R, A);
+	for (i = 0; i < 8; i++) {
+		ROUND(L, R, A, B, K, -2);
+		ROUND(R, L, A, B, K, -2);
+	}
+	for (i = 0; i < 8; i++) {
+		ROUND(R, L, A, B, K, -2);
+		ROUND(L, R, A, B, K, -2);
+	}
+	for (i = 0; i < 8; i++) {
+		ROUND(L, R, A, B, K, -2);
+		ROUND(R, L, A, B, K, -2);
+	}
+	FP(R, L, A);
+
+	d[0] = cpu_to_le32(R);
+	d[1] = cpu_to_le32(L);
 }
 
 static struct crypto_alg des_alg = {
@@ -1249,7 +951,7 @@
 	.cra_u			=	{ .cipher = {
 	.cia_min_keysize	=	DES_KEY_SIZE,
 	.cia_max_keysize	=	DES_KEY_SIZE,
-	.cia_setkey		= 	des_setkey,
+	.cia_setkey		=	des_setkey,
 	.cia_encrypt		=	des_encrypt,
 	.cia_decrypt		=	des_decrypt } }
 };
@@ -1264,9 +966,9 @@
 	.cra_u			=	{ .cipher = {
 	.cia_min_keysize	=	DES3_EDE_KEY_SIZE,
 	.cia_max_keysize	=	DES3_EDE_KEY_SIZE,
-	.cia_setkey	   	= 	des3_ede_setkey,
-	.cia_encrypt	 	=	des3_ede_encrypt,
-	.cia_decrypt	  	=	des3_ede_decrypt } }
+	.cia_setkey		=	des3_ede_setkey,
+	.cia_encrypt		=	des3_ede_encrypt,
+	.cia_decrypt		=	des3_ede_decrypt } }
 };
 
 MODULE_ALIAS("des3_ede");
@@ -1274,7 +976,7 @@
 static int __init init(void)
 {
 	int ret = 0;
-	
+
 	ret = crypto_register_alg(&des_alg);
 	if (ret < 0)
 		goto out;
@@ -1282,7 +984,7 @@
 	ret = crypto_register_alg(&des3_ede_alg);
 	if (ret < 0)
 		crypto_unregister_alg(&des_alg);
-out:	
+out:
 	return ret;
 }
 
@@ -1297,3 +999,4 @@
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");
+MODULE_AUTHOR("Dag Arne Osvik <da@osvik.no>");
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 847df92..da0456b 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -49,8 +49,7 @@
 
 void crypto_free_hmac_block(struct crypto_tfm *tfm)
 {
-	if (tfm->crt_digest.dit_hmac_block)
-		kfree(tfm->crt_digest.dit_hmac_block);
+	kfree(tfm->crt_digest.dit_hmac_block);
 }
 
 void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen)
diff --git a/crypto/internal.h b/crypto/internal.h
index 964b9a6..6861287 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -16,7 +16,7 @@
 #include <linux/highmem.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
-#include <linux/kmod.h>
+#include <linux/kernel.h>
 #include <asm/kmap_types.h>
 
 extern enum km_type crypto_km_types[];
@@ -42,20 +42,6 @@
 		cond_resched();
 }
 
-static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
-{
-	return (void *)&tfm[1];
-}
-
-struct crypto_alg *crypto_alg_lookup(const char *name);
-
-/* A far more intelligent version of this is planned.  For now, just
- * try an exact match on the name of the algorithm. */
-static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
-{
-	return try_then_request_module(crypto_alg_lookup(name), name);
-}
-
 #ifdef CONFIG_CRYPTO_HMAC
 int crypto_alloc_hmac_block(struct crypto_tfm *tfm);
 void crypto_free_hmac_block(struct crypto_tfm *tfm);
@@ -76,6 +62,33 @@
 { }
 #endif
 
+static inline unsigned int crypto_digest_ctxsize(struct crypto_alg *alg,
+						 int flags)
+{
+	return alg->cra_ctxsize;
+}
+
+static inline unsigned int crypto_cipher_ctxsize(struct crypto_alg *alg,
+						 int flags)
+{
+	unsigned int len = alg->cra_ctxsize;
+	
+	switch (flags & CRYPTO_TFM_MODE_MASK) {
+	case CRYPTO_TFM_MODE_CBC:
+		len = ALIGN(len, alg->cra_alignmask + 1);
+		len += alg->cra_blocksize;
+		break;
+	}
+
+	return len;
+}
+
+static inline unsigned int crypto_compress_ctxsize(struct crypto_alg *alg,
+						   int flags)
+{
+	return alg->cra_ctxsize;
+}
+
 int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
 int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
 int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
index 50c9461..47ac90e 100644
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -100,7 +100,7 @@
 int scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
 			   size_t nbytes, int out)
 {
-	do {
+	while (nbytes > walk->len_this_page) {
 		memcpy_dir(buf, walk->data, walk->len_this_page, out);
 		buf += walk->len_this_page;
 		nbytes -= walk->len_this_page;
@@ -108,7 +108,7 @@
 		scatterwalk_unmap(walk, out);
 		scatterwalk_pagedone(walk, out, 1);
 		scatterwalk_map(walk, out);
-	} while (nbytes > walk->len_this_page);
+	}
 
 	memcpy_dir(buf, walk->data, nbytes, out);
 	return nbytes;
diff --git a/crypto/scatterwalk.h b/crypto/scatterwalk.h
index 02aa56c..e79925c 100644
--- a/crypto/scatterwalk.h
+++ b/crypto/scatterwalk.h
@@ -40,10 +40,10 @@
 	       walk_in->offset == walk_out->offset;
 }
 
-static inline int scatterwalk_across_pages(struct scatter_walk *walk,
-					   unsigned int nbytes)
+static inline unsigned int scatterwalk_clamp(struct scatter_walk *walk,
+					     unsigned int nbytes)
 {
-	return nbytes > walk->len_this_page;
+	return nbytes > walk->len_this_page ? walk->len_this_page : nbytes;
 }
 
 static inline void scatterwalk_advance(struct scatter_walk *walk,
@@ -55,6 +55,12 @@
 	walk->len_this_segment -= nbytes;
 }
 
+static inline unsigned int scatterwalk_aligned(struct scatter_walk *walk,
+					       unsigned int alignmask)
+{
+	return !(walk->offset & alignmask);
+}
+
 void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg);
 int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, size_t nbytes, int out);
 void scatterwalk_map(struct scatter_walk *walk, int out);
diff --git a/crypto/serpent.c b/crypto/serpent.c
index 7d152e8..3cf2c50 100644
--- a/crypto/serpent.c
+++ b/crypto/serpent.c
@@ -210,7 +210,6 @@
 	x4 ^= x2;
 
 struct serpent_ctx {
-	u8 iv[SERPENT_BLOCK_SIZE];
 	u32 expkey[SERPENT_EXPKEY_WORDS];
 };
 
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 5a0adbf..97013dd 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -153,7 +153,7 @@
 		return_VALUE(-ENODEV);
 	}
 
-	result = acpi_bus_scan(*device);
+	result = acpi_bus_start(*device);
 
 	return_VALUE(result);
 }
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
index 5d19b39..5148f3c 100644
--- a/drivers/acpi/pci_bind.c
+++ b/drivers/acpi/pci_bind.c
@@ -61,15 +61,14 @@
 
 
 /**
- * acpi_os_get_pci_id
+ * acpi_get_pci_id
  * ------------------
  * This function is used by the ACPI Interpreter (a.k.a. Core Subsystem)
  * to resolve PCI information for ACPI-PCI devices defined in the namespace.
  * This typically occurs when resolving PCI operation region information.
  */
-#ifdef ACPI_FUTURE_USAGE
 acpi_status
-acpi_os_get_pci_id (
+acpi_get_pci_id (
 	acpi_handle		handle,
 	struct acpi_pci_id	*id)
 {
@@ -78,7 +77,7 @@
 	struct acpi_device	*device = NULL;
 	struct acpi_pci_data	*data = NULL;
 
-	ACPI_FUNCTION_TRACE("acpi_os_get_pci_id");
+	ACPI_FUNCTION_TRACE("acpi_get_pci_id");
 
 	if (!id)
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
@@ -92,7 +91,7 @@
 	}
 
 	status = acpi_get_data(handle, acpi_pci_data_handler, (void**) &data);
-	if (ACPI_FAILURE(status) || !data || !data->dev) {
+	if (ACPI_FAILURE(status) || !data) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
 			"Invalid ACPI-PCI context for device %s\n",
 			acpi_device_bid(device)));
@@ -115,7 +114,7 @@
 
 	return_ACPI_STATUS(AE_OK);
 }
-#endif  /*  ACPI_FUTURE_USAGE  */
+EXPORT_SYMBOL(acpi_get_pci_id);
 
 	
 int
@@ -129,6 +128,8 @@
 	char			*pathname = NULL;
 	struct acpi_buffer	buffer = {0, NULL};
 	acpi_handle		handle = NULL;
+	struct pci_dev		*dev;
+	struct pci_bus 		*bus;
 
 	ACPI_FUNCTION_TRACE("acpi_pci_bind");
 
@@ -193,8 +194,20 @@
 	 * Locate matching device in PCI namespace.  If it doesn't exist
 	 * this typically means that the device isn't currently inserted
 	 * (e.g. docking station, port replicator, etc.).
+	 * We cannot simply search the global pci device list, since
+	 * PCI devices are added to the global pci list when the root
+	 * bridge start ops are run, which may not have happened yet.
 	 */
-	data->dev = pci_find_slot(data->id.bus, PCI_DEVFN(data->id.device, data->id.function));
+	bus = pci_find_bus(data->id.segment, data->id.bus);
+	if (bus) {
+		list_for_each_entry(dev, &bus->devices, bus_list) {
+			if (dev->devfn == PCI_DEVFN(data->id.device,
+						data->id.function)) {
+				data->dev = dev;
+				break;
+			}
+		}
+	}
 	if (!data->dev) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 			"Device %02x:%02x:%02x.%02x not present in PCI namespace\n",
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 8dbf802..d1f42b9 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -433,7 +433,7 @@
 		printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: no GSI",
 			pci_name(dev), ('A' + pin));
 		/* Interrupt Line values above 0xF are forbidden */
-		if (dev->irq >= 0 && (dev->irq <= 0xF)) {
+		if (dev->irq > 0 && (dev->irq <= 0xF)) {
 			printk(" - using IRQ %d\n", dev->irq);
 			acpi_register_gsi(dev->irq, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW);
 			return_VALUE(0);
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 7e6b8e3..5d2f77f 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -46,6 +46,7 @@
 
 static int acpi_pci_root_add (struct acpi_device *device);
 static int acpi_pci_root_remove (struct acpi_device *device, int type);
+static int acpi_pci_root_start (struct acpi_device *device);
 
 static struct acpi_driver acpi_pci_root_driver = {
 	.name =		ACPI_PCI_ROOT_DRIVER_NAME,
@@ -54,6 +55,7 @@
 	.ops =		{
 				.add =    acpi_pci_root_add,
 				.remove = acpi_pci_root_remove,
+				.start =  acpi_pci_root_start,
 			},
 };
 
@@ -169,6 +171,7 @@
 	if (!root)
 		return_VALUE(-ENOMEM);
 	memset(root, 0, sizeof(struct acpi_pci_root));
+	INIT_LIST_HEAD(&root->node);
 
 	root->handle = device->handle;
 	strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
@@ -298,12 +301,31 @@
 			root->id.bus);
 
 end:
-	if (result)
+	if (result) {
+		if (!list_empty(&root->node))
+			list_del(&root->node);
 		kfree(root);
+	}
 
 	return_VALUE(result);
 }
 
+static int
+acpi_pci_root_start (
+	struct acpi_device	*device)
+{
+	struct acpi_pci_root	*root;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_root_start");
+
+	list_for_each_entry(root, &acpi_pci_roots, node) {
+		if (root->handle == device->handle) {
+			pci_bus_add_devices(root->bus);
+			return_VALUE(0);
+		}
+	}
+	return_VALUE(-ENODEV);
+}
 
 static int
 acpi_pci_root_remove (
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index f477874..76156ac 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -723,7 +723,7 @@
 		return_VALUE(-ENODEV);
 	}
 
-	acpi_bus_scan(*device);
+	acpi_bus_start(*device);
 
 	pr = acpi_driver_data(*device);
 	if (!pr)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index e858855..337d49b 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -553,20 +553,29 @@
 	 * upon possible configuration and currently allocated resources.
 	 */
 
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n"));
+	return_VALUE(0);
+}
+
+int
+acpi_start_single_object (
+		struct acpi_device *device)
+{
+	int result = 0;
+	struct acpi_driver *driver;
+
+	ACPI_FUNCTION_TRACE("acpi_start_single_object");
+
+	if (!(driver = device->driver))
+		return_VALUE(0);
+
 	if (driver->ops.start) {
 		result = driver->ops.start(device);
 		if (result && driver->ops.remove)
 			driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
-		return_VALUE(result);
 	}
 
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n"));
-
-	if (driver->ops.scan) {
-		driver->ops.scan(device);
-	}
-
-	return_VALUE(0);
+	return_VALUE(result);
 }
 
 static int acpi_driver_attach(struct acpi_driver * drv)
@@ -586,6 +595,7 @@
 
 		if (!acpi_bus_match(dev, drv)) {
 			if (!acpi_bus_driver_init(dev, drv)) {
+				acpi_start_single_object(dev);
 				atomic_inc(&drv->references);
 				count++;
 				ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n",
@@ -1009,8 +1019,8 @@
 }
 
 
-int
-acpi_bus_add (
+static int
+acpi_add_single_object (
 	struct acpi_device	**child,
 	struct acpi_device	*parent,
 	acpi_handle		handle,
@@ -1019,7 +1029,7 @@
 	int			result = 0;
 	struct acpi_device	*device = NULL;
 
-	ACPI_FUNCTION_TRACE("acpi_bus_add");
+	ACPI_FUNCTION_TRACE("acpi_add_single_object");
 
 	if (!child)
 		return_VALUE(-EINVAL);
@@ -1140,7 +1150,7 @@
 	 *
 	 * TBD: Assumes LDM provides driver hot-plug capability.
 	 */
-	acpi_bus_find_driver(device);
+	result = acpi_bus_find_driver(device);
 
 end:
 	if (!result)
@@ -1153,10 +1163,10 @@
 
 	return_VALUE(result);
 }
-EXPORT_SYMBOL(acpi_bus_add);
 
 
-int acpi_bus_scan (struct acpi_device	*start)
+static int acpi_bus_scan (struct acpi_device	*start,
+		struct acpi_bus_ops *ops)
 {
 	acpi_status		status = AE_OK;
 	struct acpi_device	*parent = NULL;
@@ -1229,9 +1239,20 @@
 			continue;
 		}
 
-		status = acpi_bus_add(&child, parent, chandle, type);
-		if (ACPI_FAILURE(status))
-			continue;
+		if (ops->acpi_op_add)
+			status = acpi_add_single_object(&child, parent,
+					chandle, type);
+		 else
+			status = acpi_bus_get_device(chandle, &child);
+
+		 if (ACPI_FAILURE(status))
+			 continue;
+
+		if (ops->acpi_op_start) {
+			status = acpi_start_single_object(child);
+			if (ACPI_FAILURE(status))
+				continue;
+		}
 
 		/*
 		 * If the device is present, enabled, and functioning then
@@ -1257,8 +1278,50 @@
 
 	return_VALUE(0);
 }
-EXPORT_SYMBOL(acpi_bus_scan);
 
+int
+acpi_bus_add (
+	struct acpi_device	**child,
+	struct acpi_device	*parent,
+	acpi_handle		handle,
+	int			type)
+{
+	int result;
+	struct acpi_bus_ops ops;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_add");
+
+	result = acpi_add_single_object(child, parent, handle, type);
+	if (!result) {
+		memset(&ops, 0, sizeof(ops));
+		ops.acpi_op_add = 1;
+		result = acpi_bus_scan(*child, &ops);
+	}
+	return_VALUE(result);
+}
+EXPORT_SYMBOL(acpi_bus_add);
+
+int
+acpi_bus_start (
+	struct acpi_device *device)
+{
+	int result;
+	struct acpi_bus_ops ops;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_start");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	result = acpi_start_single_object(device);
+	if (!result) {
+		memset(&ops, 0, sizeof(ops));
+		ops.acpi_op_start = 1;
+		result = acpi_bus_scan(device, &ops);
+	}
+	return_VALUE(result);
+}
+EXPORT_SYMBOL(acpi_bus_start);
 
 static int
 acpi_bus_trim(struct acpi_device	*start,
@@ -1331,13 +1394,19 @@
 	/*
 	 * Enumerate all fixed-feature devices.
 	 */
-	if (acpi_fadt.pwr_button == 0)
-		result = acpi_bus_add(&device, acpi_root, 
+	if (acpi_fadt.pwr_button == 0) {
+		result = acpi_add_single_object(&device, acpi_root,
 			NULL, ACPI_BUS_TYPE_POWER_BUTTON);
+		if (!result)
+			result = acpi_start_single_object(device);
+	}
 
-	if (acpi_fadt.sleep_button == 0)
-		result = acpi_bus_add(&device, acpi_root, 
+	if (acpi_fadt.sleep_button == 0) {
+		result = acpi_add_single_object(&device, acpi_root,
 			NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);
+		if (!result)
+			result = acpi_start_single_object(device);
+	}
 
 	return_VALUE(result);
 }
@@ -1346,6 +1415,7 @@
 static int __init acpi_scan_init(void)
 {
 	int result;
+	struct acpi_bus_ops ops;
 
 	ACPI_FUNCTION_TRACE("acpi_scan_init");
 
@@ -1357,17 +1427,23 @@
 	/*
 	 * Create the root device in the bus's device tree
 	 */
-	result = acpi_bus_add(&acpi_root, NULL, ACPI_ROOT_OBJECT, 
+	result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,
 		ACPI_BUS_TYPE_SYSTEM);
 	if (result)
 		goto Done;
 
+	result = acpi_start_single_object(acpi_root);
+
 	/*
 	 * Enumerate devices in the ACPI namespace.
 	 */
 	result = acpi_bus_scan_fixed(acpi_root);
-	if (!result) 
-		result = acpi_bus_scan(acpi_root);
+	if (!result) {
+		memset(&ops, 0, sizeof(ops));
+		ops.acpi_op_add = 1;
+		ops.acpi_op_start = 1;
+		result = acpi_bus_scan(acpi_root, &ops);
+	}
 
 	if (result)
 		acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 645f6269..783752b 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -5,6 +5,7 @@
 extern void bus_remove_driver(struct device_driver *);
 
 extern void driver_detach(struct device_driver * drv);
+extern int driver_probe_device(struct device_driver *, struct device *);
 
 static inline struct class_device *to_class_dev(struct kobject *obj)
 {
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index c3fac7f..96fe2f9 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -133,6 +133,58 @@
 decl_subsys(bus, &ktype_bus, NULL);
 
 
+/* Manually detach a device from it's associated driver. */
+static int driver_helper(struct device *dev, void *data)
+{
+	const char *name = data;
+
+	if (strcmp(name, dev->bus_id) == 0)
+		return 1;
+	return 0;
+}
+
+static ssize_t driver_unbind(struct device_driver *drv,
+			     const char *buf, size_t count)
+{
+	struct bus_type *bus = get_bus(drv->bus);
+	struct device *dev;
+	int err = -ENODEV;
+
+	dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
+	if ((dev) &&
+	    (dev->driver == drv)) {
+		device_release_driver(dev);
+		err = count;
+	}
+	return err;
+}
+static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind);
+
+/*
+ * Manually attach a device to a driver.
+ * Note: the driver must want to bind to the device,
+ * it is not possible to override the driver's id table.
+ */
+static ssize_t driver_bind(struct device_driver *drv,
+			   const char *buf, size_t count)
+{
+	struct bus_type *bus = get_bus(drv->bus);
+	struct device *dev;
+	int err = -ENODEV;
+
+	dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
+	if ((dev) &&
+	    (dev->driver == NULL)) {
+		down(&dev->sem);
+		err = driver_probe_device(drv, dev);
+		up(&dev->sem);
+		put_device(dev);
+	}
+	return err;
+}
+static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind);
+
+
 static struct device * next_device(struct klist_iter * i)
 {
 	struct klist_node * n = klist_next(i);
@@ -177,6 +229,39 @@
 	return error;
 }
 
+/**
+ * bus_find_device - device iterator for locating a particular device.
+ * @bus: bus type
+ * @start: Device to begin with
+ * @data: Data to pass to match function
+ * @match: Callback function to check device
+ *
+ * This is similar to the bus_for_each_dev() function above, but it
+ * returns a reference to a device that is 'found' for later use, as
+ * determined by the @match callback.
+ *
+ * The callback should return 0 if the device doesn't match and non-zero
+ * if it does.  If the callback returns non-zero, this function will
+ * return to the caller and not iterate over any more devices.
+ */
+struct device * bus_find_device(struct bus_type *bus,
+				struct device *start, void *data,
+				int (*match)(struct device *, void *))
+{
+	struct klist_iter i;
+	struct device *dev;
+
+	if (!bus)
+		return NULL;
+
+	klist_iter_init_node(&bus->klist_devices, &i,
+			     (start ? &start->knode_bus : NULL));
+	while ((dev = next_device(&i)))
+		if (match(dev, data) && get_device(dev))
+			break;
+	klist_iter_exit(&i);
+	return dev;
+}
 
 
 static struct device_driver * next_driver(struct klist_iter * i)
@@ -363,6 +448,8 @@
 		module_add_driver(drv->owner, drv);
 
 		driver_add_attrs(bus, drv);
+		driver_create_file(drv, &driver_attr_unbind);
+		driver_create_file(drv, &driver_attr_bind);
 	}
 	return error;
 }
@@ -380,6 +467,8 @@
 void bus_remove_driver(struct device_driver * drv)
 {
 	if (drv->bus) {
+		driver_remove_file(drv, &driver_attr_bind);
+		driver_remove_file(drv, &driver_attr_unbind);
 		driver_remove_attrs(drv->bus, drv);
 		klist_remove(&drv->knode_bus);
 		pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
@@ -394,31 +483,22 @@
 /* Helper for bus_rescan_devices's iter */
 static int bus_rescan_devices_helper(struct device *dev, void *data)
 {
-	int *count = data;
-
-	if (!dev->driver && (device_attach(dev) > 0))
-		(*count)++;
-
+	if (!dev->driver)
+		device_attach(dev);
 	return 0;
 }
 
-
 /**
- *	bus_rescan_devices - rescan devices on the bus for possible drivers
- *	@bus:	the bus to scan.
+ * bus_rescan_devices - rescan devices on the bus for possible drivers
+ * @bus: the bus to scan.
  *
- *	This function will look for devices on the bus with no driver
- *	attached and rescan it against existing drivers to see if it
- *	matches any. Calls device_attach(). Returns the number of devices
- *	that were sucessfully bound to a driver.
+ * This function will look for devices on the bus with no driver
+ * attached and rescan it against existing drivers to see if it matches
+ * any by calling device_attach() for the unbound devices.
  */
-int bus_rescan_devices(struct bus_type * bus)
+void bus_rescan_devices(struct bus_type * bus)
 {
-	int count = 0;
-
-	bus_for_each_dev(bus, NULL, &count, bus_rescan_devices_helper);
-
-	return count;
+	bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper);
 }
 
 
@@ -557,6 +637,7 @@
 
 
 EXPORT_SYMBOL_GPL(bus_for_each_dev);
+EXPORT_SYMBOL_GPL(bus_find_device);
 EXPORT_SYMBOL_GPL(bus_for_each_drv);
 
 EXPORT_SYMBOL_GPL(bus_add_device);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 86d7975..efe03a0 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -333,7 +333,7 @@
 	struct device * parent = dev->parent;
 
 	if (parent)
-		klist_remove(&dev->knode_parent);
+		klist_del(&dev->knode_parent);
 
 	/* Notify the platform of the removal, in case they
 	 * need to do anything...
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 6db3a78..16323f9 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -65,7 +65,7 @@
  *
  *	This function must be called with @dev->sem held.
  */
-static int driver_probe_device(struct device_driver * drv, struct device * dev)
+int driver_probe_device(struct device_driver * drv, struct device * dev)
 {
 	int ret = 0;
 
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 1b64588..291c595 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -56,6 +56,41 @@
 
 
 /**
+ * driver_find_device - device iterator for locating a particular device.
+ * @driver: The device's driver
+ * @start: Device to begin with
+ * @data: Data to pass to match function
+ * @match: Callback function to check device
+ *
+ * This is similar to the driver_for_each_device() function above, but
+ * it returns a reference to a device that is 'found' for later use, as
+ * determined by the @match callback.
+ *
+ * The callback should return 0 if the device doesn't match and non-zero
+ * if it does.  If the callback returns non-zero, this function will
+ * return to the caller and not iterate over any more devices.
+ */
+struct device * driver_find_device(struct device_driver *drv,
+				   struct device * start, void * data,
+				   int (*match)(struct device *, void *))
+{
+	struct klist_iter i;
+	struct device *dev;
+
+	if (!drv)
+		return NULL;
+
+	klist_iter_init_node(&drv->klist_devices, &i,
+			     (start ? &start->knode_driver : NULL));
+	while ((dev = next_device(&i)))
+		if (match(dev, data) && get_device(dev))
+			break;
+	klist_iter_exit(&i);
+	return dev;
+}
+EXPORT_SYMBOL_GPL(driver_find_device);
+
+/**
  *	driver_create_file - create sysfs file for driver.
  *	@drv:	driver.
  *	@attr:	driver attribute descriptor.
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 97fe13f..6522814 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -74,6 +74,8 @@
 firmware_timeout_store(struct class *class, const char *buf, size_t count)
 {
 	loading_timeout = simple_strtol(buf, NULL, 10);
+	if (loading_timeout < 0)
+		loading_timeout = 0;
 	return count;
 }
 
@@ -138,6 +140,10 @@
 	switch (loading) {
 	case 1:
 		down(&fw_lock);
+		if (!fw_priv->fw) {
+			up(&fw_lock);
+			break;
+		}
 		vfree(fw_priv->fw->data);
 		fw_priv->fw->data = NULL;
 		fw_priv->fw->size = 0;
@@ -178,7 +184,7 @@
 
 	down(&fw_lock);
 	fw = fw_priv->fw;
-	if (test_bit(FW_STATUS_DONE, &fw_priv->status)) {
+	if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) {
 		ret_count = -ENODEV;
 		goto out;
 	}
@@ -238,9 +244,10 @@
 
 	if (!capable(CAP_SYS_RAWIO))
 		return -EPERM;
+
 	down(&fw_lock);
 	fw = fw_priv->fw;
-	if (test_bit(FW_STATUS_DONE, &fw_priv->status)) {
+	if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) {
 		retval = -ENODEV;
 		goto out;
 	}
@@ -418,7 +425,7 @@
 
 	fw_priv = class_get_devdata(class_dev);
 
-	if (loading_timeout) {
+	if (loading_timeout > 0) {
 		fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
 		add_timer(&fw_priv->timeout);
 	}
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 653512b..3e9fb6e 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -786,7 +786,6 @@
 
  	case CCISS_GETLUNINFO: {
  		LogvolInfo_struct luninfo;
- 		int i;
  		
  		luninfo.LunID = drv->LunID;
  		luninfo.num_opens = drv->usage_count;
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 234fdcf..692a5fc 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -1867,19 +1867,20 @@
 
 #define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist)
 /*
- * Get a free request, queue_lock must not be held
+ * Get a free request, queue_lock must be held.
+ * Returns NULL on failure, with queue_lock held.
+ * 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)
 {
 	struct request *rq = NULL;
 	struct request_list *rl = &q->rq;
-	struct io_context *ioc = get_io_context(gfp_mask);
+	struct io_context *ioc = current_io_context(GFP_ATOMIC);
 
 	if (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags)))
 		goto out;
 
-	spin_lock_irq(q->queue_lock);
 	if (rl->count[rw]+1 >= q->nr_requests) {
 		/*
 		 * The queue will fill after this allocation, so set it as
@@ -1907,11 +1908,18 @@
 		 * The queue is full and the allocating process is not a
 		 * "batcher", and not exempted by the IO scheduler
 		 */
-		spin_unlock_irq(q->queue_lock);
 		goto out;
 	}
 
 get_rq:
+	/*
+	 * Only allow batching queuers to allocate up to 50% over the defined
+	 * limit of requests, otherwise we could have thousands of requests
+	 * allocated with any setting of ->nr_requests
+	 */
+	if (rl->count[rw] >= (3 * q->nr_requests / 2))
+		goto out;
+
 	rl->count[rw]++;
 	rl->starved[rw] = 0;
 	if (rl->count[rw] >= queue_congestion_on_threshold(q))
@@ -1941,7 +1949,6 @@
 		if (unlikely(rl->count[rw] == 0))
 			rl->starved[rw] = 1;
 
-		spin_unlock_irq(q->queue_lock);
 		goto out;
 	}
 
@@ -1951,21 +1958,23 @@
 	rq_init(q, rq);
 	rq->rl = rl;
 out:
-	put_io_context(ioc);
 	return rq;
 }
 
 /*
  * No available requests for this queue, unplug the device and wait for some
  * requests to become available.
+ *
+ * Called with q->queue_lock held, and returns with it unlocked.
  */
 static struct request *get_request_wait(request_queue_t *q, int rw,
 					struct bio *bio)
 {
-	DEFINE_WAIT(wait);
 	struct request *rq;
 
-	do {
+	rq = get_request(q, rw, bio, GFP_NOIO);
+	while (!rq) {
+		DEFINE_WAIT(wait);
 		struct request_list *rl = &q->rq;
 
 		prepare_to_wait_exclusive(&rl->wait[rw], &wait,
@@ -1976,7 +1985,8 @@
 		if (!rq) {
 			struct io_context *ioc;
 
-			generic_unplug_device(q);
+			__generic_unplug_device(q);
+			spin_unlock_irq(q->queue_lock);
 			io_schedule();
 
 			/*
@@ -1985,12 +1995,13 @@
 			 * up to a big batch of them for a small period time.
 			 * See ioc_batching, ioc_set_batching
 			 */
-			ioc = get_io_context(GFP_NOIO);
+			ioc = current_io_context(GFP_NOIO);
 			ioc_set_batching(q, ioc);
-			put_io_context(ioc);
+
+			spin_lock_irq(q->queue_lock);
 		}
 		finish_wait(&rl->wait[rw], &wait);
-	} while (!rq);
+	}
 
 	return rq;
 }
@@ -2001,14 +2012,18 @@
 
 	BUG_ON(rw != READ && rw != WRITE);
 
-	if (gfp_mask & __GFP_WAIT)
+	spin_lock_irq(q->queue_lock);
+	if (gfp_mask & __GFP_WAIT) {
 		rq = get_request_wait(q, rw, NULL);
-	else
+	} else {
 		rq = get_request(q, rw, NULL, gfp_mask);
+		if (!rq)
+			spin_unlock_irq(q->queue_lock);
+	}
+	/* q->queue_lock is unlocked at this point */
 
 	return rq;
 }
-
 EXPORT_SYMBOL(blk_get_request);
 
 /**
@@ -2512,7 +2527,7 @@
 
 static int __make_request(request_queue_t *q, struct bio *bio)
 {
-	struct request *req, *freereq = NULL;
+	struct request *req;
 	int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err, sync;
 	unsigned short prio;
 	sector_t sector;
@@ -2540,14 +2555,9 @@
 		goto end_io;
 	}
 
-again:
 	spin_lock_irq(q->queue_lock);
 
-	if (elv_queue_empty(q)) {
-		blk_plug_device(q);
-		goto get_rq;
-	}
-	if (barrier)
+	if (unlikely(barrier) || elv_queue_empty(q))
 		goto get_rq;
 
 	el_ret = elv_merge(q, &req, bio);
@@ -2592,40 +2602,24 @@
 				elv_merged_request(q, req);
 			goto out;
 
-		/*
-		 * elevator says don't/can't merge. get new request
-		 */
-		case ELEVATOR_NO_MERGE:
-			break;
-
+		/* ELV_NO_MERGE: elevator says don't/can't merge. */
 		default:
-			printk("elevator returned crap (%d)\n", el_ret);
-			BUG();
+			;
 	}
 
+get_rq:
+	/*
+	 * Grab a free request. This is might sleep but can not fail.
+	 * Returns with the queue unlocked.
+	 */
+	req = get_request_wait(q, rw, bio);
+
 	/*
-	 * Grab a free request from the freelist - if that is empty, check
-	 * if we are doing read ahead and abort instead of blocking for
-	 * a free slot.
+	 * After dropping the lock and possibly sleeping here, our request
+	 * may now be mergeable after it had proven unmergeable (above).
+	 * We don't worry about that case for efficiency. It won't happen
+	 * often, and the elevators are able to handle it.
 	 */
-get_rq:
-	if (freereq) {
-		req = freereq;
-		freereq = NULL;
-	} else {
-		spin_unlock_irq(q->queue_lock);
-		if ((freereq = get_request(q, rw, bio, GFP_ATOMIC)) == NULL) {
-			/*
-			 * READA bit set
-			 */
-			err = -EWOULDBLOCK;
-			if (bio_rw_ahead(bio))
-				goto end_io;
-	
-			freereq = get_request_wait(q, rw, bio);
-		}
-		goto again;
-	}
 
 	req->flags |= REQ_CMD;
 
@@ -2654,10 +2648,11 @@
 	req->rq_disk = bio->bi_bdev->bd_disk;
 	req->start_time = jiffies;
 
+	spin_lock_irq(q->queue_lock);
+	if (elv_queue_empty(q))
+		blk_plug_device(q);
 	add_request(q, req);
 out:
-	if (freereq)
-		__blk_put_request(q, freereq);
 	if (sync)
 		__generic_unplug_device(q);
 
@@ -3284,24 +3279,20 @@
 
 /*
  * If the current task has no IO context then create one and initialise it.
- * If it does have a context, take a ref on it.
+ * Otherwise, return its existing IO context.
  *
- * This is always called in the context of the task which submitted the I/O.
- * But weird things happen, so we disable local interrupts to ensure exclusive
- * access to *current.
+ * This returned IO context doesn't have a specifically elevated refcount,
+ * 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 *get_io_context(int gfp_flags)
+struct io_context *current_io_context(int gfp_flags)
 {
 	struct task_struct *tsk = current;
-	unsigned long flags;
 	struct io_context *ret;
 
-	local_irq_save(flags);
 	ret = tsk->io_context;
-	if (ret)
-		goto out;
-
-	local_irq_restore(flags);
+	if (likely(ret))
+		return ret;
 
 	ret = kmem_cache_alloc(iocontext_cachep, gfp_flags);
 	if (ret) {
@@ -3312,27 +3303,27 @@
 		ret->nr_batch_requests = 0; /* because this is 0 */
 		ret->aic = NULL;
 		ret->cic = NULL;
-
-		local_irq_save(flags);
-
-		/*
-		 * very unlikely, someone raced with us in setting up the task
-		 * io context. free new context and just grab a reference.
-		 */
-		if (!tsk->io_context)
-			tsk->io_context = ret;
-		else {
-			kmem_cache_free(iocontext_cachep, ret);
-			ret = tsk->io_context;
-		}
-
-out:
-		atomic_inc(&ret->refcount);
-		local_irq_restore(flags);
+		tsk->io_context = ret;
 	}
 
 	return ret;
 }
+EXPORT_SYMBOL(current_io_context);
+
+/*
+ * If the current task has no IO context then create one and initialise it.
+ * If it does have a context, take a ref on it.
+ *
+ * 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 *ret;
+	ret = current_io_context(gfp_flags);
+	if (likely(ret))
+		atomic_inc(&ret->refcount);
+	return ret;
+}
 EXPORT_SYMBOL(get_io_context);
 
 void copy_io_context(struct io_context **pdst, struct io_context **psrc)
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 1407945..59f589d 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -686,6 +686,15 @@
 	.subvendor	= PCI_ANY_ID,
 	.subdevice	= PCI_ANY_ID,
 	},
+	/* SIS 760 */
+	{
+	.class		= (PCI_CLASS_BRIDGE_HOST << 8),
+	.class_mask	= ~0,
+	.vendor		= PCI_VENDOR_ID_SI,
+	.device		= PCI_DEVICE_ID_SI_760,
+	.subvendor	= PCI_ANY_ID,
+	.subdevice	= PCI_ANY_ID,
+	},
 	{ }
 };
 
diff --git a/drivers/char/hw_random.c b/drivers/char/hw_random.c
index 7e6ac14c..3480535 100644
--- a/drivers/char/hw_random.c
+++ b/drivers/char/hw_random.c
@@ -579,7 +579,7 @@
 
 	/* Probe for Intel, AMD RNGs */
 	for_each_pci_dev(pdev) {
-		ent = pci_match_device (rng_pci_tbl, pdev);
+		ent = pci_match_id(rng_pci_tbl, pdev);
 		if (ent) {
 			rng_ops = &rng_vendor_ops[ent->driver_data];
 			goto match;
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 1813d0d..e16c13f 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -1088,8 +1088,8 @@
 		long                  seqid;
 		int                   broadcast = 0;
 
-		if (addr->channel > IPMI_NUM_CHANNELS) {
-			spin_lock_irqsave(&intf->counter_lock, flags);
+		if (addr->channel >= IPMI_MAX_CHANNELS) {
+		        spin_lock_irqsave(&intf->counter_lock, flags);
 			intf->sent_invalid_commands++;
 			spin_unlock_irqrestore(&intf->counter_lock, flags);
 			rv = -EINVAL;
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 7c24fbe..95f7046 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -451,7 +451,7 @@
 		int n = (sizeof(moxa_pcibrds) / sizeof(moxa_pcibrds[0])) - 1;
 		i = 0;
 		while (i < n) {
-			while ((p = pci_find_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL)
+			while ((p = pci_get_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL)
 			{
 				if (pci_enable_device(p))
 					continue;
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 7db3370..d7d4840 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -1095,7 +1095,7 @@
 
 #ifdef CONFIG_PCI
     /* First look for the JET devices: */
-    while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 
+    while ((pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX,
                                     PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, 
                                     pdev))) {
        if (pci_enable_device(pdev)) continue;
@@ -1169,7 +1169,7 @@
   */
 
     /* Then look for the older RIO/PCI devices: */
-    while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 
+    while ((pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX,
                                     PCI_DEVICE_ID_SPECIALIX_RIO, 
                                     pdev))) {
        if (pci_enable_device(pdev)) continue;
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index ff4f098..d8f9e94 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -78,6 +78,7 @@
 #include <linux/sysctl.h>
 #include <linux/wait.h>
 #include <linux/bcd.h>
+#include <linux/delay.h>
 
 #include <asm/current.h>
 #include <asm/uaccess.h>
@@ -894,7 +895,6 @@
 	struct proc_dir_entry *ent;
 #if defined(__alpha__) || defined(__mips__)
 	unsigned int year, ctrl;
-	unsigned long uip_watchdog;
 	char *guess = NULL;
 #endif
 #ifdef __sparc__
@@ -1000,12 +1000,8 @@
 	/* Each operating system on an Alpha uses its own epoch.
 	   Let's try to guess which one we are using now. */
 	
-	uip_watchdog = jiffies;
 	if (rtc_is_updating() != 0)
-		while (jiffies - uip_watchdog < 2*HZ/100) { 
-			barrier();
-			cpu_relax();
-		}
+		msleep(20);
 	
 	spin_lock_irq(&rtc_lock);
 	year = CMOS_READ(RTC_YEAR);
@@ -1213,7 +1209,6 @@
 
 void rtc_get_rtc_time(struct rtc_time *rtc_tm)
 {
-	unsigned long uip_watchdog = jiffies;
 	unsigned char ctrl;
 #ifdef CONFIG_MACH_DECSTATION
 	unsigned int real_year;
@@ -1221,7 +1216,7 @@
 
 	/*
 	 * read RTC once any update in progress is done. The update
-	 * can take just over 2ms. We wait 10 to 20ms. There is no need to
+	 * can take just over 2ms. We wait 20ms. There is no need to
 	 * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP.
 	 * If you need to know *exactly* when a second has started, enable
 	 * periodic update complete interrupts, (via ioctl) and then 
@@ -1230,10 +1225,7 @@
 	 */
 
 	if (rtc_is_updating() != 0)
-		while (jiffies - uip_watchdog < 2*HZ/100) {
-			barrier();
-			cpu_relax();
-		}
+		msleep(20);
 
 	/*
 	 * Only the values that we read from the RTC are set. We leave
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c
index 659335d8..ec78d2f 100644
--- a/drivers/char/tipar.c
+++ b/drivers/char/tipar.c
@@ -396,7 +396,7 @@
 static int __init
 tipar_setup(char *str)
 {
-	int ints[2];
+	int ints[3];
 
 	str = get_options(str, ARRAY_SIZE(ints), ints);
 
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 854475c..049d128 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -464,7 +464,7 @@
 
 	pci_set_drvdata(pci_dev, NULL);
 	misc_deregister(&chip->vendor->miscdev);
-	kfree(&chip->vendor->miscdev.name);
+	kfree(chip->vendor->miscdev.name);
 
 	sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
 
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 5859799..f19cf9d 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -476,11 +476,11 @@
 			ld = tty_ldisc_ref(tty);
 			switch (arg) {
 			case TCIFLUSH:
-				if (ld->flush_buffer)
+				if (ld && ld->flush_buffer)
 					ld->flush_buffer(tty);
 				break;
 			case TCIOFLUSH:
-				if (ld->flush_buffer)
+				if (ld && ld->flush_buffer)
 					ld->flush_buffer(tty);
 				/* fall through */
 			case TCOFLUSH:
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 8971484..1d44f69 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -25,6 +25,7 @@
 #include <linux/fs.h>
 #include <linux/console.h>
 #include <linux/signal.h>
+#include <linux/timex.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -386,7 +387,7 @@
 		if (!perm)
 			return -EPERM;
 		if (arg)
-			arg = 1193182 / arg;
+			arg = CLOCK_TICK_RATE / arg;
 		kd_mksound(arg, 0);
 		return 0;
 
@@ -403,7 +404,7 @@
 		ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
 		count = ticks ? (arg & 0xffff) : 0;
 		if (count)
-			count = 1193182 / count;
+			count = CLOCK_TICK_RATE / count;
 		kd_mksound(count, ticks);
 		return 0;
 	}
diff --git a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c
index b14d642..5d07ee5 100644
--- a/drivers/char/watchdog/i8xx_tco.c
+++ b/drivers/char/watchdog/i8xx_tco.c
@@ -401,7 +401,7 @@
 	 */
 
 	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-		if (pci_match_device(i8xx_tco_pci_tbl, dev)) {
+		if (pci_match_id(i8xx_tco_pci_tbl, dev)) {
 			i8xx_tco_pci = dev;
 			break;
 		}
diff --git a/drivers/char/watchdog/ixp2000_wdt.c b/drivers/char/watchdog/ixp2000_wdt.c
index 4e98c21..4b03951 100644
--- a/drivers/char/watchdog/ixp2000_wdt.c
+++ b/drivers/char/watchdog/ixp2000_wdt.c
@@ -162,7 +162,7 @@
 	if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) {
 		wdt_disable();
 	} else {
-		printk(KERN_CRIT "WATCHDOG: Device closed unexpectdly - "
+		printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
 					"timer will not stop\n");
 	}
 
diff --git a/drivers/char/watchdog/ixp4xx_wdt.c b/drivers/char/watchdog/ixp4xx_wdt.c
index 82396e0..83df369 100644
--- a/drivers/char/watchdog/ixp4xx_wdt.c
+++ b/drivers/char/watchdog/ixp4xx_wdt.c
@@ -156,7 +156,7 @@
 	if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) {
 		wdt_disable();
 	} else {
-		printk(KERN_CRIT "WATCHDOG: Device closed unexpectdly - "
+		printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
 					"timer will not stop\n");
 	}
 
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
index ed708b4..71407c5 100644
--- a/drivers/crypto/padlock-aes.c
+++ b/drivers/crypto/padlock-aes.c
@@ -49,6 +49,7 @@
 #include <linux/errno.h>
 #include <linux/crypto.h>
 #include <linux/interrupt.h>
+#include <linux/kernel.h>
 #include <asm/byteorder.h>
 #include "padlock.h"
 
@@ -59,8 +60,12 @@
 #define AES_EXTENDED_KEY_SIZE_B	(AES_EXTENDED_KEY_SIZE * sizeof(uint32_t))
 
 struct aes_ctx {
-	uint32_t e_data[AES_EXTENDED_KEY_SIZE+4];
-	uint32_t d_data[AES_EXTENDED_KEY_SIZE+4];
+	uint32_t e_data[AES_EXTENDED_KEY_SIZE];
+	uint32_t d_data[AES_EXTENDED_KEY_SIZE];
+	struct {
+		struct cword encrypt;
+		struct cword decrypt;
+	} cword;
 	uint32_t *E;
 	uint32_t *D;
 	int key_length;
@@ -280,10 +285,15 @@
 	return 0;
 }
 
+static inline struct aes_ctx *aes_ctx(void *ctx)
+{
+	return (struct aes_ctx *)ALIGN((unsigned long)ctx, PADLOCK_ALIGNMENT);
+}
+
 static int
 aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t *flags)
 {
-	struct aes_ctx *ctx = ctx_arg;
+	struct aes_ctx *ctx = aes_ctx(ctx_arg);
 	uint32_t i, t, u, v, w;
 	uint32_t P[AES_EXTENDED_KEY_SIZE];
 	uint32_t rounds;
@@ -295,25 +305,36 @@
 
 	ctx->key_length = key_len;
 
+	/*
+	 * If the hardware is capable of generating the extended key
+	 * itself we must supply the plain key for both encryption
+	 * and decryption.
+	 */
 	ctx->E = ctx->e_data;
-	ctx->D = ctx->d_data;
-
-	/* Ensure 16-Bytes alignmentation of keys for VIA PadLock. */
-	if ((int)(ctx->e_data) & 0x0F)
-		ctx->E += 4 - (((int)(ctx->e_data) & 0x0F) / sizeof (ctx->e_data[0]));
-
-	if ((int)(ctx->d_data) & 0x0F)
-		ctx->D += 4 - (((int)(ctx->d_data) & 0x0F) / sizeof (ctx->d_data[0]));
+	ctx->D = ctx->e_data;
 
 	E_KEY[0] = uint32_t_in (in_key);
 	E_KEY[1] = uint32_t_in (in_key + 4);
 	E_KEY[2] = uint32_t_in (in_key + 8);
 	E_KEY[3] = uint32_t_in (in_key + 12);
 
+	/* Prepare control words. */
+	memset(&ctx->cword, 0, sizeof(ctx->cword));
+
+	ctx->cword.decrypt.encdec = 1;
+	ctx->cword.encrypt.rounds = 10 + (key_len - 16) / 4;
+	ctx->cword.decrypt.rounds = ctx->cword.encrypt.rounds;
+	ctx->cword.encrypt.ksize = (key_len - 16) / 8;
+	ctx->cword.decrypt.ksize = ctx->cword.encrypt.ksize;
+
 	/* Don't generate extended keys if the hardware can do it. */
 	if (aes_hw_extkey_available(key_len))
 		return 0;
 
+	ctx->D = ctx->d_data;
+	ctx->cword.encrypt.keygen = 1;
+	ctx->cword.decrypt.keygen = 1;
+
 	switch (key_len) {
 	case 16:
 		t = E_KEY[3];
@@ -369,10 +390,9 @@
 
 /* ====== Encryption/decryption routines ====== */
 
-/* This is the real call to PadLock. */
-static inline void
-padlock_xcrypt_ecb(uint8_t *input, uint8_t *output, uint8_t *key,
-		   void *control_word, uint32_t count)
+/* These are the real call to PadLock. */
+static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key,
+				      void *control_word, u32 count)
 {
 	asm volatile ("pushfl; popfl");		/* enforce key reload. */
 	asm volatile (".byte 0xf3,0x0f,0xa7,0xc8"	/* rep xcryptecb */
@@ -380,60 +400,70 @@
 		      : "d"(control_word), "b"(key), "c"(count));
 }
 
-static void
-aes_padlock(void *ctx_arg, uint8_t *out_arg, const uint8_t *in_arg, int encdec)
+static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
+				     u8 *iv, void *control_word, u32 count)
 {
-	/* Don't blindly modify this structure - the items must 
-	   fit on 16-Bytes boundaries! */
-	struct padlock_xcrypt_data {
-		uint8_t buf[AES_BLOCK_SIZE];
-		union cword cword;
-	};
-
-	struct aes_ctx *ctx = ctx_arg;
-	char bigbuf[sizeof(struct padlock_xcrypt_data) + 16];
-	struct padlock_xcrypt_data *data;
-	void *key;
-
-	/* Place 'data' at the first 16-Bytes aligned address in 'bigbuf'. */
-	if (((long)bigbuf) & 0x0F)
-		data = (void*)(bigbuf + 16 - ((long)bigbuf & 0x0F));
-	else
-		data = (void*)bigbuf;
-
-	/* Prepare Control word. */
-	memset (data, 0, sizeof(struct padlock_xcrypt_data));
-	data->cword.b.encdec = !encdec;	/* in the rest of cryptoapi ENC=1/DEC=0 */
-	data->cword.b.rounds = 10 + (ctx->key_length - 16) / 4;
-	data->cword.b.ksize = (ctx->key_length - 16) / 8;
-
-	/* Is the hardware capable to generate the extended key? */
-	if (!aes_hw_extkey_available(ctx->key_length))
-		data->cword.b.keygen = 1;
-
-	/* ctx->E starts with a plain key - if the hardware is capable
-	   to generate the extended key itself we must supply
-	   the plain key for both Encryption and Decryption. */
-	if (encdec == CRYPTO_DIR_ENCRYPT || data->cword.b.keygen == 0)
-		key = ctx->E;
-	else
-		key = ctx->D;
-	
-	memcpy(data->buf, in_arg, AES_BLOCK_SIZE);
-	padlock_xcrypt_ecb(data->buf, data->buf, key, &data->cword, 1);
-	memcpy(out_arg, data->buf, AES_BLOCK_SIZE);
+	/* Enforce key reload. */
+	asm volatile ("pushfl; popfl");
+	/* rep xcryptcbc */
+	asm volatile (".byte 0xf3,0x0f,0xa7,0xd0"
+		      : "+S" (input), "+D" (output), "+a" (iv)
+		      : "d" (control_word), "b" (key), "c" (count));
+	return iv;
 }
 
 static void
 aes_encrypt(void *ctx_arg, uint8_t *out, const uint8_t *in)
 {
-	aes_padlock(ctx_arg, out, in, CRYPTO_DIR_ENCRYPT);
+	struct aes_ctx *ctx = aes_ctx(ctx_arg);
+	padlock_xcrypt_ecb(in, out, ctx->E, &ctx->cword.encrypt, 1);
 }
 
 static void
 aes_decrypt(void *ctx_arg, uint8_t *out, const uint8_t *in)
 {
-	aes_padlock(ctx_arg, out, in, CRYPTO_DIR_DECRYPT);
+	struct aes_ctx *ctx = aes_ctx(ctx_arg);
+	padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt, 1);
+}
+
+static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out,
+				    const u8 *in, unsigned int nbytes)
+{
+	struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm));
+	padlock_xcrypt_ecb(in, out, ctx->E, &ctx->cword.encrypt,
+			   nbytes / AES_BLOCK_SIZE);
+	return nbytes & ~(AES_BLOCK_SIZE - 1);
+}
+
+static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out,
+				    const u8 *in, unsigned int nbytes)
+{
+	struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm));
+	padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt,
+			   nbytes / AES_BLOCK_SIZE);
+	return nbytes & ~(AES_BLOCK_SIZE - 1);
+}
+
+static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out,
+				    const u8 *in, unsigned int nbytes)
+{
+	struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm));
+	u8 *iv;
+
+	iv = padlock_xcrypt_cbc(in, out, ctx->E, desc->info,
+				&ctx->cword.encrypt, nbytes / AES_BLOCK_SIZE);
+	memcpy(desc->info, iv, AES_BLOCK_SIZE);
+
+	return nbytes & ~(AES_BLOCK_SIZE - 1);
+}
+
+static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out,
+				    const u8 *in, unsigned int nbytes)
+{
+	struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm));
+	padlock_xcrypt_cbc(in, out, ctx->D, desc->info, &ctx->cword.decrypt,
+			   nbytes / AES_BLOCK_SIZE);
+	return nbytes & ~(AES_BLOCK_SIZE - 1);
 }
 
 static struct crypto_alg aes_alg = {
@@ -441,6 +471,7 @@
 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize		=	AES_BLOCK_SIZE,
 	.cra_ctxsize		=	sizeof(struct aes_ctx),
+	.cra_alignmask		=	PADLOCK_ALIGNMENT - 1,
 	.cra_module		=	THIS_MODULE,
 	.cra_list		=	LIST_HEAD_INIT(aes_alg.cra_list),
 	.cra_u			=	{
@@ -449,7 +480,11 @@
 			.cia_max_keysize	=	AES_MAX_KEY_SIZE,
 			.cia_setkey	   	= 	aes_set_key,
 			.cia_encrypt	 	=	aes_encrypt,
-			.cia_decrypt	  	=	aes_decrypt
+			.cia_decrypt	  	=	aes_decrypt,
+			.cia_encrypt_ecb 	=	aes_encrypt_ecb,
+			.cia_decrypt_ecb  	=	aes_decrypt_ecb,
+			.cia_encrypt_cbc 	=	aes_encrypt_cbc,
+			.cia_decrypt_cbc  	=	aes_decrypt_cbc,
 		}
 	}
 };
diff --git a/drivers/crypto/padlock.h b/drivers/crypto/padlock.h
index 7a50060..3cf2b7a 100644
--- a/drivers/crypto/padlock.h
+++ b/drivers/crypto/padlock.h
@@ -13,18 +13,18 @@
 #ifndef _CRYPTO_PADLOCK_H
 #define _CRYPTO_PADLOCK_H
 
+#define PADLOCK_ALIGNMENT 16
+
 /* Control word. */
-union cword {
-	uint32_t cword[4];
-	struct {
-		int rounds:4;
-		int algo:3;
-		int keygen:1;
-		int interm:1;
-		int encdec:1;
-		int ksize:2;
-	} b;
-};
+struct cword {
+	int __attribute__ ((__packed__))
+		rounds:4,
+		algo:3,
+		keygen:1,
+		interm:1,
+		encdec:1,
+		ksize:2;
+} __attribute__ ((__aligned__(PADLOCK_ALIGNMENT)));
 
 #define PFX	"padlock: "
 
diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c
index 839b44a..53c95c0 100644
--- a/drivers/firmware/pcdp.c
+++ b/drivers/firmware/pcdp.c
@@ -16,6 +16,7 @@
 #include <linux/console.h>
 #include <linux/efi.h>
 #include <linux/serial.h>
+#include <asm/vga.h>
 #include "pcdp.h"
 
 static int __init
@@ -40,10 +41,27 @@
 }
 
 static int __init
-setup_vga_console(struct pcdp_vga *vga)
+setup_vga_console(struct pcdp_device *dev)
 {
 #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
-	if (efi_mem_type(0xA0000) == EFI_CONVENTIONAL_MEMORY) {
+	u8 *if_ptr;
+
+	if_ptr = ((u8 *)dev + sizeof(struct pcdp_device));
+	if (if_ptr[0] == PCDP_IF_PCI) {
+		struct pcdp_if_pci if_pci;
+
+		/* struct copy since ifptr might not be correctly aligned */
+
+		memcpy(&if_pci, if_ptr, sizeof(if_pci));
+
+		if (if_pci.trans & PCDP_PCI_TRANS_IOPORT)
+			vga_console_iobase = if_pci.ioport_tra;
+
+		if (if_pci.trans & PCDP_PCI_TRANS_MMIO)
+			vga_console_membase = if_pci.mmio_tra;
+	}
+
+	if (efi_mem_type(vga_console_membase + 0xA0000) == EFI_CONVENTIONAL_MEMORY) {
 		printk(KERN_ERR "PCDP: VGA selected, but frame buffer is not MMIO!\n");
 		return -ENODEV;
 	}
@@ -95,7 +113,7 @@
 	     dev = (struct pcdp_device *) ((u8 *) dev + dev->length)) {
 		if (dev->flags & PCDP_PRIMARY_CONSOLE) {
 			if (dev->type == PCDP_CONSOLE_VGA) {
-				return setup_vga_console((struct pcdp_vga *) dev);
+				return setup_vga_console(dev);
 			}
 		}
 	}
diff --git a/drivers/firmware/pcdp.h b/drivers/firmware/pcdp.h
index 1dc7c88..e72cc47 100644
--- a/drivers/firmware/pcdp.h
+++ b/drivers/firmware/pcdp.h
@@ -52,11 +52,34 @@
 	u32				clock_rate;
 	u8				pci_prog_intfc;
 	u8				flags;
-};
+} __attribute__((packed));
+
+#define PCDP_IF_PCI	1
+
+/* pcdp_if_pci.trans */
+#define PCDP_PCI_TRANS_IOPORT	0x02
+#define PCDP_PCI_TRANS_MMIO	0x01
+
+struct pcdp_if_pci {
+	u8			interconnect;
+	u8			reserved;
+	u16			length;
+	u8			segment;
+	u8			bus;
+	u8			dev;
+	u8			fun;
+	u16			dev_id;
+	u16			vendor_id;
+	u32			acpi_interrupt;
+	u64			mmio_tra;
+	u64			ioport_tra;
+	u8			flags;
+	u8			trans;
+} __attribute__((packed));
 
 struct pcdp_vga {
 	u8			count;		/* address space descriptors */
-};
+} __attribute__((packed));
 
 /* pcdp_device.flags */
 #define PCDP_PRIMARY_CONSOLE	1
@@ -66,7 +89,9 @@
 	u8			flags;
 	u16			length;
 	u16			efi_index;
-};
+	/* next data is pcdp_if_pci or pcdp_if_acpi (not yet supported) */
+	/* next data is device specific type (currently only pcdp_vga) */
+} __attribute__((packed));
 
 struct pcdp {
 	u8			signature[4];
@@ -81,4 +106,4 @@
 	u32			num_uarts;
 	struct pcdp_uart	uart[0];	/* actual size is num_uarts */
 	/* remainder of table is pcdp_device structures */
-};
+} __attribute__((packed));
diff --git a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c
index 363e545..94ae808 100644
--- a/drivers/i2c/busses/i2c-keywest.c
+++ b/drivers/i2c/busses/i2c-keywest.c
@@ -698,7 +698,7 @@
 }
 
 static int
-create_iface_macio(struct macio_dev* dev, const struct of_match *match)
+create_iface_macio(struct macio_dev* dev, const struct of_device_id *match)
 {
 	return create_iface(dev->ofdev.node, &dev->ofdev.dev);
 }
@@ -710,7 +710,7 @@
 }
 
 static int
-create_iface_of_platform(struct of_device* dev, const struct of_match *match)
+create_iface_of_platform(struct of_device* dev, const struct of_device_id *match)
 {
 	return create_iface(dev->node, &dev->dev);
 }
@@ -721,10 +721,9 @@
 	return dispose_iface(&dev->dev);
 }
 
-static struct of_match i2c_keywest_match[] = 
+static struct of_device_id i2c_keywest_match[] = 
 {
 	{
-	.name 		= OF_ANY_MATCH,
 	.type		= "i2c",
 	.compatible	= "keywest"
 	},
diff --git a/drivers/i2c/chips/atxp1.c b/drivers/i2c/chips/atxp1.c
index 5c6597a..0bcf82b 100644
--- a/drivers/i2c/chips/atxp1.c
+++ b/drivers/i2c/chips/atxp1.c
@@ -144,7 +144,7 @@
 	if (vid == cvid)
 		return count;
 
-	dev_info(dev, "Setting VCore to %d mV (0x%02x)\n", vcore, vid);
+	dev_dbg(dev, "Setting VCore to %d mV (0x%02x)\n", vcore, vid);
 
 	/* Write every 25 mV step to increase stability */
 	if (cvid > vid) {
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index 5be8ad6d..cca9c07 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -20,7 +20,6 @@
 # Core IDE code - must come before legacy
 ide-core-$(CONFIG_BLK_DEV_IDEPCI)	+= setup-pci.o
 ide-core-$(CONFIG_BLK_DEV_IDEDMA)	+= ide-dma.o
-ide-core-$(CONFIG_BLK_DEV_IDE_TCQ)	+= ide-tcq.o
 ide-core-$(CONFIG_PROC_FS)		+= ide-proc.o
 ide-core-$(CONFIG_BLK_DEV_IDEPNP)	+= ide-pnp.o
 
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 6806d40..b09a653 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -487,8 +487,7 @@
 	u8 err = 0;
 
 	local_irq_set(flags);
-	printk("%s: %s: status=0x%02x", drive->name, msg, stat);
-	printk(" { ");
+	printk("%s: %s: status=0x%02x { ", drive->name, msg, stat);
 	if (stat & BUSY_STAT)
 		printk("Busy ");
 	else {
@@ -500,15 +499,13 @@
 		if (stat & INDEX_STAT)	printk("Index ");
 		if (stat & ERR_STAT)	printk("Error ");
 	}
-	printk("}");
-	printk("\n");
+	printk("}\n");
 	if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
 		err = hwif->INB(IDE_ERROR_REG);
-		printk("%s: %s: error=0x%02x", drive->name, msg, err);
-		printk(" { ");
+		printk("%s: %s: error=0x%02x { ", drive->name, msg, err);
 		if (err & ABRT_ERR)	printk("DriveStatusError ");
 		if (err & ICRC_ERR)
-			printk("Bad%s ", (err & ABRT_ERR) ? "CRC" : "Sector");
+			printk((err & ABRT_ERR) ? "BadCRC " : "BadSector ");
 		if (err & ECC_ERR)	printk("UncorrectableError ");
 		if (err & ID_ERR)	printk("SectorIdNotFound ");
 		if (err & TRK0_ERR)	printk("TrackZeroNotFound ");
@@ -546,8 +543,8 @@
 				printk(", sector=%llu",
 					(unsigned long long)HWGROUP(drive)->rq->sector);
 		}
+		printk("\n");
 	}
-	printk("\n");
 	ide_dump_opcode(drive);
 	local_irq_restore(flags);
 	return err;
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c
index e884cd4..242029c 100644
--- a/drivers/ide/legacy/hd.c
+++ b/drivers/ide/legacy/hd.c
@@ -156,11 +156,13 @@
 
 
 #if (HD_DELAY > 0)
+
+#include <asm/i8253.h>
+
 unsigned long last_req;
 
 unsigned long read_timer(void)
 {
-        extern spinlock_t i8253_lock;
 	unsigned long t, flags;
 	int i;
 
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index 67efb38..6cf4939 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -583,7 +583,7 @@
  *	appropriate also sets up the 1533 southbridge.
  */
   
-static unsigned int __init init_chipset_ali15x3 (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const char *name)
 {
 	unsigned long flags;
 	u8 tmpbyte;
@@ -677,7 +677,7 @@
  *	FIXME: frobs bits that are not defined on newer ALi devicea
  */
 
-static unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif)
+static unsigned int __devinit ata66_ali15x3 (ide_hwif_t *hwif)
 {
 	struct pci_dev *dev	= hwif->pci_dev;
 	unsigned int ata66	= 0;
@@ -748,7 +748,7 @@
  *	Initialize the IDE structure side of the ALi 15x3 driver.
  */
  
-static void __init init_hwif_common_ali15x3 (ide_hwif_t *hwif)
+static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif)
 {
 	hwif->autodma = 0;
 	hwif->tuneproc = &ali15x3_tune_drive;
@@ -794,7 +794,7 @@
  *	Sparc systems
  */
 
-static void __init init_hwif_ali15x3 (ide_hwif_t *hwif)
+static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif)
 {
 	u8 ideic, inmir;
 	s8 irq_routing_table[] = { -1,  9, 3, 10, 4,  5, 7,  6,
@@ -847,7 +847,7 @@
  *	the actual work.
  */
 
-static void __init init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase)
+static void __devinit init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase)
 {
 	if (m5229_revision < 0x20)
 		return;
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index 4e0f13d..844a6c9 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -73,6 +73,7 @@
 	{ PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE,	0x50, AMD_UDMA_133 },
 	{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE,	0x50, AMD_UDMA_133 },
 	{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE,	0x50, AMD_UDMA_133 },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE,	0x50, AMD_UDMA_133 },
 	{ 0 }
 };
 
@@ -309,7 +310,7 @@
  * and initialize its drive independent registers.
  */
 
-static unsigned int __init init_chipset_amd74xx(struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const char *name)
 {
 	unsigned char t;
 	unsigned int u;
@@ -413,7 +414,7 @@
 	return dev->irq;
 }
 
-static void __init init_hwif_amd74xx(ide_hwif_t *hwif)
+static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
 {
 	int i;
 
@@ -489,6 +490,7 @@
 	/* 13 */ DECLARE_NV_DEV("NFORCE-CK804"),
 	/* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"),
 	/* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"),
+	/* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"),
 };
 
 static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
@@ -524,6 +526,7 @@
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 },
 	{ 0, },
 };
 MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl);
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
index 0381961..09269e5 100644
--- a/drivers/ide/pci/cs5530.c
+++ b/drivers/ide/pci/cs5530.c
@@ -217,7 +217,7 @@
  *	Initialize the cs5530 bridge for reliable IDE DMA operation.
  */
 
-static unsigned int __init init_chipset_cs5530 (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const char *name)
 {
 	struct pci_dev *master_0 = NULL, *cs5530_0 = NULL;
 	unsigned long flags;
@@ -308,7 +308,7 @@
  *	performs channel-specific pre-initialization before drive probing.
  */
 
-static void __init init_hwif_cs5530 (ide_hwif_t *hwif)
+static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif)
 {
 	unsigned long basereg;
 	u32 d0_timings;
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index 80d67e9..5a33513 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -391,7 +391,7 @@
 /*
  * this function is called during init and is used to setup the cy82c693 chip
  */
-static unsigned int __init init_chipset_cy82c693(struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const char *name)
 {
 	if (PCI_FUNC(dev->devfn) != 1)
 		return 0;
@@ -443,7 +443,7 @@
 /*
  * the init function - called for each ide channel once
  */
-static void __init init_hwif_cy82c693(ide_hwif_t *hwif)
+static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif)
 {
 	hwif->autodma = 0;
 
@@ -467,9 +467,9 @@
 	hwif->drives[1].autodma = hwif->autodma;
 }
 
-static __initdata ide_hwif_t *primary;
+static __devinitdata ide_hwif_t *primary;
 
-void __init init_iops_cy82c693(ide_hwif_t *hwif)
+void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
 {
 	if (PCI_FUNC(hwif->pci_dev->devfn) == 1)
 		primary = hwif;
diff --git a/drivers/ide/pci/it8172.c b/drivers/ide/pci/it8172.c
index 631927c..9346292 100644
--- a/drivers/ide/pci/it8172.c
+++ b/drivers/ide/pci/it8172.c
@@ -216,7 +216,7 @@
 	return 0;
 }
 
-static unsigned int __init init_chipset_it8172 (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_it8172 (struct pci_dev *dev, const char *name)
 {
 	unsigned char progif;
     
@@ -230,7 +230,7 @@
 }
 
 
-static void __init init_hwif_it8172 (ide_hwif_t *hwif)
+static void __devinit init_hwif_it8172 (ide_hwif_t *hwif)
 {
 	struct pci_dev* dev = hwif->pci_dev;
 	unsigned long cmdBase, ctrlBase;
diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c
index 205a32f..fcd5142 100644
--- a/drivers/ide/pci/ns87415.c
+++ b/drivers/ide/pci/ns87415.c
@@ -195,7 +195,7 @@
 	return __ide_dma_check(drive);
 }
 
-static void __init init_hwif_ns87415 (ide_hwif_t *hwif)
+static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
 {
 	struct pci_dev *dev = hwif->pci_dev;
 	unsigned int ctrl, using_inta;
diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c
index cf4fd91..7a7c2ef 100644
--- a/drivers/ide/pci/opti621.c
+++ b/drivers/ide/pci/opti621.c
@@ -326,7 +326,7 @@
 /*
  * init_hwif_opti621() is called once for each hwif found at boot.
  */
-static void __init init_hwif_opti621 (ide_hwif_t *hwif)
+static void __devinit init_hwif_opti621 (ide_hwif_t *hwif)
 {
 	hwif->autodma = 0;
 	hwif->drives[0].drive_data = PIO_DONT_KNOW;
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
index 3bc3bf1..10592ce 100644
--- a/drivers/ide/pci/sc1200.c
+++ b/drivers/ide/pci/sc1200.c
@@ -459,7 +459,7 @@
  * This gets invoked by the IDE driver once for each channel,
  * and performs channel-specific pre-initialization before drive probing.
  */
-static void __init init_hwif_sc1200 (ide_hwif_t *hwif)
+static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif)
 {
 	if (hwif->mate)
 		hwif->serialized = hwif->mate->serialized = 1;
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
index 1d970a0..ea0806c 100644
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -386,7 +386,7 @@
  * channel 0 here at least, but channel 1 has to be enabled by
  * firmware or arch code. We still set both to 16 bits mode.
  */
-static unsigned int __init init_chipset_sl82c105(struct pci_dev *dev, const char *msg)
+static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const char *msg)
 {
 	u32 val;
 
@@ -399,7 +399,7 @@
 	return dev->irq;
 }
 
-static void __init init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base)
+static void __devinit init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base)
 {
 	unsigned int rev;
 	u8 dma_state;
@@ -431,7 +431,7 @@
  * Initialise the chip
  */
 
-static void __init init_hwif_sl82c105(ide_hwif_t *hwif)
+static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
 {
 	struct pci_dev *dev = hwif->pci_dev;
 	u32 val;
diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c
index 7fbf363..5112c72 100644
--- a/drivers/ide/pci/slc90e66.c
+++ b/drivers/ide/pci/slc90e66.c
@@ -196,7 +196,7 @@
 }
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
-static void __init init_hwif_slc90e66 (ide_hwif_t *hwif)
+static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
 {
 	u8 reg47 = 0;
 	u8 mask = hwif->channel ? 0x01 : 0x02;  /* bit0:Primary */
diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c
index a1df2bf..f96b568 100644
--- a/drivers/ide/pci/triflex.c
+++ b/drivers/ide/pci/triflex.c
@@ -130,7 +130,7 @@
 	return hwif->ide_dma_off_quietly(drive);
 }
 
-static void __init init_hwif_triflex(ide_hwif_t *hwif)
+static void __devinit init_hwif_triflex(ide_hwif_t *hwif)
 {
 	hwif->tuneproc = &triflex_tune_drive;
 	hwif->speedproc = &triflex_tune_chipset;
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index 069dbff..a4d099c 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -415,7 +415,7 @@
  *	and initialize its drive independent registers.
  */
 
-static unsigned int __init init_chipset_via82cxxx(struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name)
 {
 	struct pci_dev *isa = NULL;
 	u8 t, v;
@@ -576,7 +576,7 @@
 	return 0;
 }
 
-static void __init init_hwif_via82cxxx(ide_hwif_t *hwif)
+static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
 {
 	int i;
 
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 818380b..be0fcc8 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1419,7 +1419,7 @@
  * Attach to a macio probed interface
  */
 static int __devinit
-pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_match *match)
+pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
 {
 	void __iomem *base;
 	unsigned long regbase;
@@ -1637,27 +1637,19 @@
 	return rc;
 }
 
-static struct of_match pmac_ide_macio_match[] = 
+static struct of_device_id pmac_ide_macio_match[] = 
 {
 	{
 	.name 		= "IDE",
-	.type		= OF_ANY_MATCH,
-	.compatible	= OF_ANY_MATCH
 	},
 	{
 	.name 		= "ATA",
-	.type		= OF_ANY_MATCH,
-	.compatible	= OF_ANY_MATCH
 	},
 	{
-	.name 		= OF_ANY_MATCH,
 	.type		= "ide",
-	.compatible	= OF_ANY_MATCH
 	},
 	{
-	.name 		= OF_ANY_MATCH,
 	.type		= "ata",
-	.compatible	= OF_ANY_MATCH
 	},
 	{},
 };
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index e501675..77da827 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -847,7 +847,7 @@
 		d = list_entry(l, struct pci_driver, node);
 		if(d->id_table)
 		{
-			const struct pci_device_id *id = pci_match_device(d->id_table, dev);
+			const struct pci_device_id *id = pci_match_id(d->id_table, dev);
 			if(id != NULL)
 			{
 				if(d->probe(dev, id) >= 0)
diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h
index 73bd8ef..0b31429 100644
--- a/drivers/ieee1394/ieee1394_core.h
+++ b/drivers/ieee1394/ieee1394_core.h
@@ -38,8 +38,8 @@
 
         /* These are core internal. */
         signed char tlabel;
-        char ack_code;
-        char tcode;
+	signed char ack_code;
+	unsigned char tcode;
 
         unsigned expect_response:1;
         unsigned no_waiter:1;
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index 3e72c9b..ab09cf40 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -60,12 +60,13 @@
 
 #if defined(__i386__)
 
+#include <asm/i8253.h>
+
 #define DELTA(x,y)      ((y)-(x)+((y)<(x)?1193182/HZ:0))
 #define GET_TIME(x)     do { x = get_time_pit(); } while (0)
 
 static unsigned int get_time_pit(void)
 {
-	extern spinlock_t i8253_lock;
 	unsigned long flags;
 	unsigned int count;
 
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
index 504b7d5..c3a5739 100644
--- a/drivers/input/joystick/analog.c
+++ b/drivers/input/joystick/analog.c
@@ -140,12 +140,14 @@
  */
 
 #ifdef __i386__
+
+#include <asm/i8253.h>
+
 #define GET_TIME(x)	do { if (cpu_has_tsc) rdtscl(x); else x = get_time_pit(); } while (0)
 #define DELTA(x,y)	(cpu_has_tsc ? ((y) - (x)) : ((x) - (y) + ((x) < (y) ? CLOCK_TICK_RATE / HZ : 0)))
 #define TIME_NAME	(cpu_has_tsc?"TSC":"PIT")
 static unsigned int get_time_pit(void)
 {
-        extern spinlock_t i8253_lock;
         unsigned long flags;
         unsigned int count;
 
diff --git a/drivers/isdn/hardware/eicon/dadapter.c b/drivers/isdn/hardware/eicon/dadapter.c
index 6e548a2..8949789 100644
--- a/drivers/isdn/hardware/eicon/dadapter.c
+++ b/drivers/isdn/hardware/eicon/dadapter.c
@@ -44,7 +44,7 @@
   Array to held adapter information
    -------------------------------------------------------------------------- */
 static DESCRIPTOR  HandleTable[NEW_MAX_DESCRIPTORS];
-dword Adapters = 0; /* Number of adapters */
+static dword Adapters = 0; /* Number of adapters */
 /* --------------------------------------------------------------------------
   Shadow IDI_DIMAINT
   and 'shadow' debug stuff
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c
index 6e7e060..7333377a 100644
--- a/drivers/isdn/hisax/hfc4s8s_l1.c
+++ b/drivers/isdn/hisax/hfc4s8s_l1.c
@@ -312,7 +312,7 @@
 /* function to read critical counter registers that   */
 /* may be udpated by the chip during read             */
 /******************************************************/
-static volatile u_char
+static u_char
 Read_hfc8_stable(hfc4s8s_hw * hw, int reg)
 {
 	u_char ref8;
@@ -324,7 +324,7 @@
 	return in8;
 }
 
-static volatile int
+static int
 Read_hfc16_stable(hfc4s8s_hw * hw, int reg)
 {
 	int ref16;
@@ -1465,7 +1465,7 @@
 /******************************************/
 /* disable memory mapped ports / io ports */
 /******************************************/
-void
+static void
 release_pci_ports(hfc4s8s_hw * hw)
 {
 	pci_write_config_word(hw->pdev, PCI_COMMAND, 0);
@@ -1481,7 +1481,7 @@
 /*****************************************/
 /* enable memory mapped ports / io ports */
 /*****************************************/
-void
+static void
 enable_pci_ports(hfc4s8s_hw * hw)
 {
 #ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c
index 8ee25b2..1fd3d4e 100644
--- a/drivers/isdn/hysdn/hycapi.c
+++ b/drivers/isdn/hysdn/hycapi.c
@@ -42,6 +42,8 @@
 
 static hycapi_appl hycapi_applications[CAPI_MAXAPPL];
 
+static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
+
 static inline int _hycapi_appCheck(int app_id, int ctrl_no)
 {
 	if((ctrl_no <= 0) || (ctrl_no > CAPI_MAXCONTR) || (app_id <= 0) ||
@@ -57,7 +59,7 @@
 Kernel-Capi callback reset_ctr
 ******************************/     
 
-void 
+static void
 hycapi_reset_ctr(struct capi_ctr *ctrl)
 {
 	hycapictrl_info *cinfo = ctrl->driverdata;
@@ -73,7 +75,7 @@
 Kernel-Capi callback remove_ctr
 ******************************/     
 
-void 
+static void
 hycapi_remove_ctr(struct capi_ctr *ctrl)
 {
 	int i;
@@ -215,7 +217,7 @@
 The application is recorded in the internal list.
 *************************************************************/
 
-void 
+static void
 hycapi_register_appl(struct capi_ctr *ctrl, __u16 appl, 
 		     capi_register_params *rp)
 {
@@ -291,7 +293,7 @@
 registration at controller-level
 ******************************************************************/
 
-void 
+static void
 hycapi_release_appl(struct capi_ctr *ctrl, __u16 appl)
 {
 	int chk;
@@ -364,7 +366,7 @@
 
 ***************************************************************/
 
-u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
+static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
 {
 	__u16 appl_id;
 	int _len, _len2;
@@ -437,8 +439,8 @@
 
 *********************************************************************/
 
-int hycapi_read_proc(char *page, char **start, off_t off,
-		     int count, int *eof, struct capi_ctr *ctrl)
+static int hycapi_read_proc(char *page, char **start, off_t off,
+			    int count, int *eof, struct capi_ctr *ctrl)
 {
 	hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
 	hysdn_card *card = cinfo->card;
@@ -485,7 +487,7 @@
 
 **************************************************************/
 
-int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
+static int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
 {
 #ifdef HYCAPI_PRINTFNAMES
 	printk(KERN_NOTICE "hycapi_load_firmware\n");    
@@ -494,7 +496,7 @@
 }
 
 
-char *hycapi_procinfo(struct capi_ctr *ctrl)
+static char *hycapi_procinfo(struct capi_ctr *ctrl)
 {
 	hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
 #ifdef HYCAPI_PRINTFNAMES
diff --git a/drivers/isdn/hysdn/hysdn_boot.c b/drivers/isdn/hysdn/hysdn_boot.c
index 6c04281..7bfba19 100644
--- a/drivers/isdn/hysdn/hysdn_boot.c
+++ b/drivers/isdn/hysdn/hysdn_boot.c
@@ -53,7 +53,7 @@
 /*  to be called at start of POF file reading,       */
 /*  before starting any decryption on any POF record. */
 /*****************************************************/
-void
+static void
 StartDecryption(struct boot_data *boot)
 {
 	boot->Cryptor = CRYPT_STARTTERM;
@@ -66,7 +66,7 @@
 /*       to HI and LO boot loader and (all) seq tags, because  */
 /*       global Cryptor is started for whole POF.              */
 /***************************************************************/
-void
+static void
 DecryptBuf(struct boot_data *boot, int cnt)
 {
 	uchar *bufp = boot->buf.BootBuf;
diff --git a/drivers/isdn/hysdn/hysdn_defs.h b/drivers/isdn/hysdn/hysdn_defs.h
index 4cee26e..432f6f9 100644
--- a/drivers/isdn/hysdn/hysdn_defs.h
+++ b/drivers/isdn/hysdn/hysdn_defs.h
@@ -227,7 +227,6 @@
 /*****************/
 /* exported vars */
 /*****************/
-extern int cardmax;		/* number of found cards */
 extern hysdn_card *card_root;	/* pointer to first card */
 
 
@@ -244,7 +243,6 @@
 /* hysdn_proclog.c */
 extern int hysdn_proclog_init(hysdn_card *);	/* init proc log entry */
 extern void hysdn_proclog_release(hysdn_card *);	/* deinit proc log entry */
-extern void put_log_buffer(hysdn_card *, char *);	/* output log data */
 extern void hysdn_addlog(hysdn_card *, char *,...);	/* output data to log */
 extern void hysdn_card_errlog(hysdn_card *, tErrLogEntry *, int);	/* output card log */
 
@@ -278,16 +276,6 @@
 extern int hycapi_capi_create(hysdn_card *);	/* create a new capi device */
 extern int hycapi_capi_release(hysdn_card *);	/* delete the device */
 extern int hycapi_capi_stop(hysdn_card *card);   /* suspend */
-extern int hycapi_load_firmware(struct capi_ctr *, capiloaddata *);
-extern void hycapi_reset_ctr(struct capi_ctr *);
-extern void hycapi_remove_ctr(struct capi_ctr *);
-extern void hycapi_register_appl(struct capi_ctr *, __u16 appl,
-				 capi_register_params *);
-extern void hycapi_release_appl(struct capi_ctr *, __u16 appl);
-extern u16  hycapi_send_message(struct capi_ctr *, struct sk_buff *skb);
-extern char *hycapi_procinfo(struct capi_ctr *);
-extern int hycapi_read_proc(char *page, char **start, off_t off,
-			    int count, int *eof, struct capi_ctr *card);
 extern void hycapi_rx_capipkt(hysdn_card * card, uchar * buf, word len);
 extern void hycapi_tx_capiack(hysdn_card * card);
 extern struct sk_buff *hycapi_tx_capiget(hysdn_card *card);
diff --git a/drivers/isdn/hysdn/hysdn_init.c b/drivers/isdn/hysdn/hysdn_init.c
index 5cac2bf..12c8137 100644
--- a/drivers/isdn/hysdn/hysdn_init.c
+++ b/drivers/isdn/hysdn/hysdn_init.c
@@ -34,7 +34,7 @@
 MODULE_LICENSE("GPL");
 
 static char *hysdn_init_revision = "$Revision: 1.6.6.6 $";
-int cardmax;			/* number of found cards */
+static int cardmax;		/* number of found cards */
 hysdn_card *card_root = NULL;	/* pointer to first card */
 
 /**********************************************/
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index 8ef2b7c..4d57011 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -22,6 +22,8 @@
 /* the proc subdir for the interface is defined in the procconf module */
 extern struct proc_dir_entry *hysdn_proc_entry;
 
+static void put_log_buffer(hysdn_card * card, char *cp);
+
 /*************************************************/
 /* structure keeping ascii log for device output */
 /*************************************************/
@@ -93,7 +95,7 @@
 /* opened for read got the contents.        */
 /* Flushes buffers not longer in use.       */
 /********************************************/
-void
+static void
 put_log_buffer(hysdn_card * card, char *cp)
 {
 	struct log_data *ib;
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile
index f5ae171..236291b 100644
--- a/drivers/macintosh/Makefile
+++ b/drivers/macintosh/Makefile
@@ -4,7 +4,7 @@
 
 # Each configuration option enables a list of files.
 
-obj-$(CONFIG_PPC_PMAC)		+= macio_asic.o
+obj-$(CONFIG_PPC_PMAC)		+= macio_asic.o macio_sysfs.o
 
 obj-$(CONFIG_PMAC_MEDIABAY)	+= mediabay.o
 obj-$(CONFIG_MAC_EMUMOUSEBTN)	+= mac_hid.o
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index d0bda7e..1ee0033 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -33,7 +33,7 @@
 {
 	struct macio_dev * macio_dev = to_macio_device(dev);
 	struct macio_driver * macio_drv = to_macio_driver(drv);
-	const struct of_match * matches = macio_drv->match_table;
+	const struct of_device_id * matches = macio_drv->match_table;
 
 	if (!matches) 
 		return 0;
@@ -66,7 +66,7 @@
 	int error = -ENODEV;
 	struct macio_driver *drv;
 	struct macio_dev *macio_dev;
-	const struct of_match *match;
+	const struct of_device_id *match;
 
 	drv = to_macio_driver(dev->driver);
 	macio_dev = to_macio_device(dev);
@@ -126,11 +126,85 @@
 	return 0;
 }
 
+static int macio_hotplug (struct device *dev, char **envp, int num_envp,
+                          char *buffer, int buffer_size)
+{
+	struct macio_dev * macio_dev;
+	struct of_device * of;
+	char *scratch, *compat;
+	int i = 0;
+	int length = 0;
+	int cplen, seen = 0;
+
+	if (!dev)
+		return -ENODEV;
+
+	macio_dev = to_macio_device(dev);
+	if (!macio_dev)
+		return -ENODEV;
+
+	of = &macio_dev->ofdev;
+	scratch = buffer;
+
+	/* stuff we want to pass to /sbin/hotplug */
+	envp[i++] = scratch;
+	length += scnprintf (scratch, buffer_size - length, "OF_NAME=%s",
+	                     of->node->name);
+	if ((buffer_size - length <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	++length;
+	scratch += length;
+
+	envp[i++] = scratch;
+	length += scnprintf (scratch, buffer_size - length, "OF_TYPE=%s",
+	                     of->node->type);
+	if ((buffer_size - length <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	++length;
+	scratch += length;
+
+        /* Since the compatible field can contain pretty much anything
+         * it's not really legal to split it out with commas. We split it
+         * up using a number of environment variables instead. */
+
+	compat = (char *) get_property(of->node, "compatible", &cplen);
+	while (compat && cplen > 0) {
+		int l;
+                envp[i++] = scratch;
+		length += scnprintf (scratch, buffer_size - length,
+		                     "OF_COMPATIBLE_%d=%s", seen, compat);
+		if ((buffer_size - length <= 0) || (i >= num_envp))
+			return -ENOMEM;
+		length++;
+		scratch += length;
+		l = strlen (compat) + 1;
+		compat += l;
+		cplen -= l;
+		seen++;
+	}
+
+	envp[i++] = scratch;
+	length += scnprintf (scratch, buffer_size - length,
+	                     "OF_COMPATIBLE_N=%d", seen);
+	if ((buffer_size - length <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	++length;
+	scratch += length;
+
+	envp[i] = NULL;
+
+	return 0;
+}
+
+extern struct device_attribute macio_dev_attrs[];
+
 struct bus_type macio_bus_type = {
        .name	= "macio",
        .match	= macio_bus_match,
+       .hotplug = macio_hotplug,
        .suspend	= macio_device_suspend,
        .resume	= macio_device_resume,
+       .dev_attrs = macio_dev_attrs,
 };
 
 static int __init macio_bus_driver_init(void)
diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c
new file mode 100644
index 0000000..97d22bb
--- /dev/null
+++ b/drivers/macintosh/macio_sysfs.c
@@ -0,0 +1,50 @@
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/stat.h>
+#include <asm/macio.h>
+
+
+#define macio_config_of_attr(field, format_string)			\
+static ssize_t								\
+field##_show (struct device *dev, struct device_attribute *attr,	\
+              char *buf)						\
+{									\
+	struct macio_dev *mdev = to_macio_device (dev);			\
+	return sprintf (buf, format_string, mdev->ofdev.node->field);	\
+}
+
+static ssize_t
+compatible_show (struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct of_device *of;
+	char *compat;
+	int cplen;
+	int length = 0;
+
+	of = &to_macio_device (dev)->ofdev;
+	compat = (char *) get_property(of->node, "compatible", &cplen);
+	if (!compat) {
+		*buf = '\0';
+		return 0;
+	}
+	while (cplen > 0) {
+		int l;
+		length += sprintf (buf, "%s\n", 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");
+
+struct device_attribute macio_dev_attrs[] = {
+	__ATTR_RO(name),
+	__ATTR_RO(type),
+	__ATTR_RO(compatible),
+	__ATTR_NULL
+};
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
index 4be709e..7c16c25 100644
--- a/drivers/macintosh/mediabay.c
+++ b/drivers/macintosh/mediabay.c
@@ -642,7 +642,7 @@
 	}
 }
 
-static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_match *match)
+static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_device_id *match)
 {
 	struct media_bay_info* bay;
 	u32 __iomem *regbase;
@@ -797,23 +797,20 @@
  * Therefore we do it all by polling the media bay once each tick.
  */
 
-static struct of_match media_bay_match[] =
+static struct of_device_id media_bay_match[] =
 {
 	{
 	.name		= "media-bay",
-	.type		= OF_ANY_MATCH,
 	.compatible	= "keylargo-media-bay",
 	.data		= &keylargo_mb_ops,
 	},
 	{
 	.name		= "media-bay",
-	.type		= OF_ANY_MATCH,
 	.compatible	= "heathrow-media-bay",
 	.data		= &heathrow_mb_ops,
 	},
 	{
 	.name		= "media-bay",
-	.type		= OF_ANY_MATCH,
 	.compatible	= "ohare-media-bay",
 	.data		= &ohare_mb_ops,
 	},
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index feb4e24..703e3197 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -120,6 +120,7 @@
 #include <asm/system.h>
 #include <asm/sections.h>
 #include <asm/of_device.h>
+#include <asm/macio.h>
 
 #include "therm_pm72.h"
 
@@ -1986,7 +1987,7 @@
 	}
 }
 
-static int fcu_of_probe(struct of_device* dev, const struct of_match *match)
+static int fcu_of_probe(struct of_device* dev, const struct of_device_id *match)
 {
 	int rc;
 
@@ -2009,12 +2010,10 @@
 	return 0;
 }
 
-static struct of_match fcu_of_match[] = 
+static struct of_device_id fcu_match[] = 
 {
 	{
-	.name 		= OF_ANY_MATCH,
 	.type		= "fcu",
-	.compatible	= OF_ANY_MATCH
 	},
 	{},
 };
@@ -2022,7 +2021,7 @@
 static struct of_platform_driver fcu_of_platform_driver = 
 {
 	.name 		= "temperature",
-	.match_table	= fcu_of_match,
+	.match_table	= fcu_match,
 	.probe		= fcu_of_probe,
 	.remove		= fcu_of_remove
 };
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index 61400f0..cbb72eb 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -43,6 +43,7 @@
 #include <asm/system.h>
 #include <asm/sections.h>
 #include <asm/of_device.h>
+#include <asm/macio.h>
 
 #define LOG_TEMP		0			/* continously log temperature */
 
@@ -450,7 +451,7 @@
 /************************************************************************/
 
 static int
-therm_of_probe( struct of_device *dev, const struct of_match *match )
+therm_of_probe( struct of_device *dev, const struct of_device_id *match )
 {
 	return i2c_add_driver( &g4fan_driver );
 }
@@ -461,9 +462,8 @@
 	return i2c_del_driver( &g4fan_driver );
 }
 
-static struct of_match therm_of_match[] = {{
+static struct of_device_id therm_of_match[] = {{
 	.name		= "fan",
-	.type		= OF_ANY_MATCH,
 	.compatible	= "adm1030"
     }, {}
 };
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 3802f7a..4a0c57d 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -338,6 +338,7 @@
 
 	if (atomic_dec_and_test(&rdev->mddev->pending_writes))
 		wake_up(&rdev->mddev->sb_wait);
+	bio_put(bio);
 	return 0;
 }
 
diff --git a/drivers/media/dvb/frontends/tda80xx.c b/drivers/media/dvb/frontends/tda80xx.c
index 032d348..88e1250 100644
--- a/drivers/media/dvb/frontends/tda80xx.c
+++ b/drivers/media/dvb/frontends/tda80xx.c
@@ -27,7 +27,6 @@
 #include <linux/spinlock.h>
 #include <linux/threads.h>
 #include <linux/interrupt.h>
-#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 2dc906f..810e7aa 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -7,8 +7,7 @@
 zoran-objs      :=	zr36120.o zr36120_i2c.o zr36120_mem.o
 zr36067-objs	:=	zoran_procfs.o zoran_device.o \
 			zoran_driver.o zoran_card.o
-tuner-objs	:=	tuner-core.o tuner-simple.o mt20xx.o tda8290.o
-
+tuner-objs	:=	tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o
 obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o
 
 obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index 290289a..7d62b39 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -1,5 +1,5 @@
 /*
-    $Id: bttv-driver.c,v 1.38 2005/06/10 17:20:24 mchehab Exp $
+    $Id: bttv-driver.c,v 1.40 2005/06/16 21:38:45 nsh Exp $
 
     bttv - Bt848 frame grabber driver
 
@@ -76,6 +76,9 @@
 static unsigned int whitecrush_lower = 0x7F;
 static unsigned int vcr_hack    = 0;
 static unsigned int irq_iswitch = 0;
+static unsigned int uv_ratio    = 50;
+static unsigned int full_luma_range = 0;
+static unsigned int coring      = 0;
 
 /* API features (turn on/off stuff for testing) */
 static unsigned int v4l2        = 1;
@@ -106,6 +109,9 @@
 module_param(whitecrush_upper,  int, 0444);
 module_param(whitecrush_lower,  int, 0444);
 module_param(vcr_hack,          int, 0444);
+module_param(uv_ratio,          int, 0444);
+module_param(full_luma_range,   int, 0444);
+module_param(coring,            int, 0444);
 
 module_param_array(radio, int, NULL, 0444);
 
@@ -124,6 +130,9 @@
 MODULE_PARM_DESC(whitecrush_lower,"sets the white crush lower value, default is 127");
 MODULE_PARM_DESC(vcr_hack,"enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)");
 MODULE_PARM_DESC(irq_iswitch,"switch inputs in irq handler");
+MODULE_PARM_DESC(uv_ratio,"ratio between u and v gains, default is 50");
+MODULE_PARM_DESC(full_luma_range,"use the full luma range, default is 0 (no)");
+MODULE_PARM_DESC(coring,"set the luma coring level, default is 0 (no)");
 
 MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards");
 MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr");
@@ -484,7 +493,10 @@
 #define V4L2_CID_PRIVATE_VCR_HACK    (V4L2_CID_PRIVATE_BASE + 5)
 #define V4L2_CID_PRIVATE_WHITECRUSH_UPPER   (V4L2_CID_PRIVATE_BASE + 6)
 #define V4L2_CID_PRIVATE_WHITECRUSH_LOWER   (V4L2_CID_PRIVATE_BASE + 7)
-#define V4L2_CID_PRIVATE_LASTP1      (V4L2_CID_PRIVATE_BASE + 8)
+#define V4L2_CID_PRIVATE_UV_RATIO    (V4L2_CID_PRIVATE_BASE + 8)
+#define V4L2_CID_PRIVATE_FULL_LUMA_RANGE    (V4L2_CID_PRIVATE_BASE + 9)
+#define V4L2_CID_PRIVATE_CORING      (V4L2_CID_PRIVATE_BASE + 10)
+#define V4L2_CID_PRIVATE_LASTP1      (V4L2_CID_PRIVATE_BASE + 11)
 
 static const struct v4l2_queryctrl no_ctl = {
 	.name  = "42",
@@ -618,8 +630,32 @@
 		.step          = 1,
 		.default_value = 0x7F,
 		.type          = V4L2_CTRL_TYPE_INTEGER,
+	},{
+		.id            = V4L2_CID_PRIVATE_UV_RATIO,
+		.name          = "uv ratio",
+		.minimum       = 0,
+		.maximum       = 100,
+		.step          = 1,
+		.default_value = 50,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+	},{
+		.id            = V4L2_CID_PRIVATE_FULL_LUMA_RANGE,
+		.name          = "full luma range",
+		.minimum       = 0,
+		.maximum       = 1,
+		.type          = V4L2_CTRL_TYPE_BOOLEAN,
+	},{
+		.id            = V4L2_CID_PRIVATE_CORING,
+		.name          = "coring",
+		.minimum       = 0,
+		.maximum       = 3,
+		.step          = 1,
+		.default_value = 0,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
 	}
 
+
+
 };
 static const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls);
 
@@ -833,8 +869,8 @@
 	btv->saturation = color;
 
 	/* 0-511 for the color */
-	val_u   = color >> 7;
-	val_v   = ((color>>7)*180L)/254;
+	val_u   = ((color * btv->opt_uv_ratio) / 50) >> 7;
+	val_v   = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254;
         hibits  = (val_u >> 7) & 2;
 	hibits |= (val_v >> 8) & 1;
         btwrite(val_u & 0xff, BT848_SAT_U_LO);
@@ -1151,6 +1187,15 @@
 	case V4L2_CID_PRIVATE_WHITECRUSH_LOWER:
 		c->value = btv->opt_whitecrush_lower;
 		break;
+	case V4L2_CID_PRIVATE_UV_RATIO:
+		c->value = btv->opt_uv_ratio;
+		break;
+	case V4L2_CID_PRIVATE_FULL_LUMA_RANGE:
+		c->value = btv->opt_full_luma_range;
+		break;
+	case V4L2_CID_PRIVATE_CORING:
+		c->value = btv->opt_coring;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -1247,6 +1292,18 @@
 		btv->opt_whitecrush_lower = c->value;
 		btwrite(c->value, BT848_WC_DOWN);
 		break;
+	case V4L2_CID_PRIVATE_UV_RATIO:
+		btv->opt_uv_ratio = c->value;
+		bt848_sat(btv, btv->saturation);
+		break;
+	case V4L2_CID_PRIVATE_FULL_LUMA_RANGE:
+		btv->opt_full_luma_range = c->value;
+		btaor((c->value<<7), ~BT848_OFORM_RANGE, BT848_OFORM);
+		break;
+	case V4L2_CID_PRIVATE_CORING:
+		btv->opt_coring = c->value;
+		btaor((c->value<<5), ~BT848_OFORM_CORE32, BT848_OFORM);
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -3117,11 +3174,6 @@
                         return -EINVAL;
 		memset(v,0,sizeof(*v));
                 strcpy(v->name, "Radio");
-                /* japan:          76.0 MHz -  89.9 MHz
-                   western europe: 87.5 MHz - 108.0 MHz
-                   russia:         65.0 MHz - 108.0 MHz */
-                v->rangelow=(int)(65*16);
-                v->rangehigh=(int)(108*16);
                 bttv_call_i2c_clients(btv,cmd,v);
                 return 0;
         }
@@ -3876,6 +3928,9 @@
 	btv->opt_vcr_hack   = vcr_hack;
 	btv->opt_whitecrush_upper  = whitecrush_upper;
 	btv->opt_whitecrush_lower  = whitecrush_lower;
+	btv->opt_uv_ratio   = uv_ratio;
+	btv->opt_full_luma_range   = full_luma_range;
+	btv->opt_coring     = coring;
 
 	/* fill struct bttv with some useful defaults */
 	btv->init.btv         = btv;
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
index 7b6f1e8..f3293e4 100644
--- a/drivers/media/video/bttvp.h
+++ b/drivers/media/video/bttvp.h
@@ -1,5 +1,5 @@
 /*
-    $Id: bttvp.h,v 1.17 2005/02/16 12:14:10 kraxel Exp $
+    $Id: bttvp.h,v 1.19 2005/06/16 21:38:45 nsh Exp $
 
     bttv - Bt848 frame grabber driver
 
@@ -326,6 +326,9 @@
 	int opt_vcr_hack;
 	int opt_whitecrush_upper;
 	int opt_whitecrush_lower;
+	int opt_uv_ratio;
+	int opt_full_luma_range;
+	int opt_coring;
 
 	/* radio data/state */
 	int has_radio;
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c
index 95ad17b..9c005cb 100644
--- a/drivers/media/video/mt20xx.c
+++ b/drivers/media/video/mt20xx.c
@@ -1,5 +1,5 @@
 /*
- * $Id: mt20xx.c,v 1.4 2005/03/04 09:24:56 kraxel Exp $
+ * $Id: mt20xx.c,v 1.5 2005/06/16 08:29:49 nsh Exp $
  *
  * i2c tv tuner chip device driver
  * controls microtune tuners, mt2032 + mt2050 at the moment.
@@ -295,8 +295,8 @@
 	int if2 = t->radio_if2;
 
 	// per Manual for FM tuning: first if center freq. 1085 MHz
-        mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
-			   1085*1000*1000,if2,if2,if2);
+        mt2032_set_if_freq(c, freq * 1000 / 16,
+			      1085*1000*1000,if2,if2,if2);
 }
 
 // Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
index b27cc34..f59d460 100644
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/video/tda8290.c
@@ -1,5 +1,5 @@
 /*
- * $Id: tda8290.c,v 1.7 2005/03/07 12:01:51 kraxel Exp $
+ * $Id: tda8290.c,v 1.11 2005/06/18 06:09:06 nsh Exp $
  *
  * i2c tv tuner chip device driver
  * controls the philips tda8290+75 tuner chip combo.
@@ -69,7 +69,7 @@
 static unsigned char i2c_enable_bridge[2] = 	{ 0x21, 0xC0 };
 static unsigned char i2c_disable_bridge[2] = 	{ 0x21, 0x80 };
 static unsigned char i2c_init_tda8275[14] = 	{ 0x00, 0x00, 0x00, 0x00,
-						  0x7C, 0x04, 0xA3, 0x3F,
+						  0xfC, 0x04, 0xA3, 0x3F,
 						  0x2A, 0x04, 0xFF, 0x00,
 						  0x00, 0x40 };
 static unsigned char i2c_set_VS[2] = 		{ 0x30, 0x6F };
@@ -138,16 +138,24 @@
 
 static void set_frequency(struct tuner *t, u16 ifc)
 {
-	u32 N = (((t->freq<<3)+ifc)&0x3fffc);
+	u32 freq;
+	u32 N;
 
-	N = N >> get_freq_entry(div_table, t->freq);
+	if (t->mode == V4L2_TUNER_RADIO)
+		freq = t->freq / 1000;
+	else
+		freq = t->freq;
+
+	N = (((freq<<3)+ifc)&0x3fffc);
+
+	N = N >> get_freq_entry(div_table, freq);
 	t->i2c_set_freq[0] = 0;
 	t->i2c_set_freq[1] = (unsigned char)(N>>8);
 	t->i2c_set_freq[2] = (unsigned char) N;
 	t->i2c_set_freq[3] = 0x40;
 	t->i2c_set_freq[4] = 0x52;
-	t->i2c_set_freq[5] = get_freq_entry(band_table, t->freq);
-	t->i2c_set_freq[6] = get_freq_entry(agc_table,  t->freq);
+	t->i2c_set_freq[5] = get_freq_entry(band_table, freq);
+	t->i2c_set_freq[6] = get_freq_entry(agc_table,  freq);
 	t->i2c_set_freq[7] = 0x8f;
 }
 
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index 3977363..ee35562 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -368,7 +368,7 @@
 		if (t->radio_mode == V4L2_TUNER_MODE_MONO)
 			norm = &radio_mono;
 		else
-		        norm = &radio_stereo;
+			norm = &radio_stereo;
 	} else {
 		for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
 			if (tvnorms[i].std & t->std) {
@@ -566,7 +566,6 @@
 	if (UNSET != t->pinnacle_id) {
 		tda9887_set_pinnacle(t,buf);
 	}
-
 	tda9887_set_config(t,buf);
 	tda9887_set_insmod(t,buf);
 
@@ -615,8 +614,8 @@
 	t->pinnacle_id = UNSET;
 	t->radio_mode = V4L2_TUNER_MODE_STEREO;
 
-        i2c_set_clientdata(&t->client, t);
-        i2c_attach_client(&t->client);
+	i2c_set_clientdata(&t->client, t);
+	i2c_attach_client(&t->client);
 
 	return 0;
 }
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c
new file mode 100644
index 0000000..a29f08f
--- /dev/null
+++ b/drivers/media/video/tea5767.c
@@ -0,0 +1,334 @@
+/*
+ * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
+ * I2C address is allways 0xC0.
+ *
+ * $Id: tea5767.c,v 1.11 2005/06/21 15:40:33 mchehab Exp $
+ *
+ * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
+ * This code is placed under the terms of the GNU General Public License
+ *
+ * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa
+ * from their contributions on DScaler.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/videodev.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
+#include <media/tuner.h>
+
+/* Declared at tuner-core.c */
+extern unsigned int tuner_debug;
+
+#define PREFIX "TEA5767 "
+
+/*****************************************************************************/
+
+/******************************
+ * Write mode register values *
+ ******************************/
+
+/* First register */
+#define TEA5767_MUTE		0x80 /* Mutes output */
+#define TEA5767_SEARCH		0x40 /* Activates station search */
+/* Bits 0-5 for divider MSB */
+
+/* Second register */
+/* Bits 0-7 for divider LSB */
+
+/* Third register */
+
+/* Station search from botton to up */
+#define TEA5767_SEARCH_UP	0x80
+
+/* Searches with ADC output = 10 */
+#define TEA5767_SRCH_HIGH_LVL	0x60
+
+/* Searches with ADC output = 10 */
+#define TEA5767_SRCH_MID_LVL	0x40
+
+/* Searches with ADC output = 5 */
+#define TEA5767_SRCH_LOW_LVL	0x20
+
+/* if on, div=4*(Frf+Fif)/Fref otherwise, div=4*(Frf-Fif)/Freq) */
+#define TEA5767_HIGH_LO_INJECT	0x10
+
+/* Disable stereo */
+#define TEA5767_MONO		0x08
+
+/* Disable right channel and turns to mono */
+#define TEA5767_MUTE_RIGHT	0x04
+
+/* Disable left channel and turns to mono */
+#define TEA5767_MUTE_LEFT	0x02
+
+#define TEA5767_PORT1_HIGH	0x01
+
+/* Forth register */
+#define TEA5767_PORT2_HIGH	0x80
+/* Chips stops working. Only I2C bus remains on */
+#define TEA5767_STDBY		0x40
+
+/* Japan freq (76-108 MHz. If disabled, 87.5-108 MHz */
+#define TEA5767_JAPAN_BAND	0x20
+
+/* Unselected means 32.768 KHz freq as reference. Otherwise Xtal at 13 MHz */
+#define TEA5767_XTAL_32768	0x10
+
+/* Cuts weak signals */
+#define TEA5767_SOFT_MUTE	0x08
+
+/* Activates high cut control */
+#define TEA5767_HIGH_CUT_CTRL	0x04
+
+/* Activates stereo noise control */
+#define TEA5767_ST_NOISE_CTL	0x02
+
+/* If activate PORT 1 indicates SEARCH or else it is used as PORT1 */
+#define TEA5767_SRCH_IND	0x01
+
+/* Fiveth register */
+
+/* By activating, it will use Xtal at 13 MHz as reference for divider */
+#define TEA5767_PLLREF_ENABLE	0x80
+
+/* By activating, deemphasis=50, or else, deemphasis of 50us */
+#define TEA5767_DEEMPH_75	0X40
+
+/*****************************
+ * Read mode register values *
+ *****************************/
+
+/* First register */
+#define TEA5767_READY_FLAG_MASK	0x80
+#define TEA5767_BAND_LIMIT_MASK	0X40
+/* Bits 0-5 for divider MSB after search or preset */
+
+/* Second register */
+/* Bits 0-7 for divider LSB after search or preset */
+
+/* Third register */
+#define TEA5767_STEREO_MASK	0x80
+#define TEA5767_IF_CNTR_MASK	0x7f
+
+/* Four register */
+#define TEA5767_ADC_LEVEL_MASK	0xf0
+
+/* should be 0 */
+#define TEA5767_CHIP_ID_MASK	0x0f
+
+/* Fiveth register */
+/* Reserved for future extensions */
+#define TEA5767_RESERVED_MASK	0xff
+
+/*****************************************************************************/
+
+static void set_tv_freq(struct i2c_client *c, unsigned int freq)
+{
+	struct tuner *t = i2c_get_clientdata(c);
+
+	tuner_warn("This tuner doesn't support TV freq.\n");
+}
+
+static void tea5767_status_dump(unsigned char *buffer)
+{
+	unsigned int div, frq;
+
+	if (TEA5767_READY_FLAG_MASK & buffer[0])
+		printk(PREFIX "Ready Flag ON\n");
+	else
+		printk(PREFIX "Ready Flag OFF\n");
+
+	if (TEA5767_BAND_LIMIT_MASK & buffer[0])
+		printk(PREFIX "Tuner at band limit\n");
+	else
+		printk(PREFIX "Tuner not at band limit\n");
+
+	div=((buffer[0]&0x3f)<<8) | buffer[1];
+
+	switch (TEA5767_HIGH_LO_32768) {
+	case TEA5767_HIGH_LO_13MHz:
+		frq = 1000*(div*50-700-225)/4; /* Freq in KHz */
+		break;
+	case TEA5767_LOW_LO_13MHz:
+		frq = 1000*(div*50+700+225)/4; /* Freq in KHz */
+		break;
+	case TEA5767_LOW_LO_32768:
+		frq = 1000*(div*32768/1000+700+225)/4; /* Freq in KHz */
+		break;
+	case TEA5767_HIGH_LO_32768:
+	default:
+		frq = 1000*(div*32768/1000-700-225)/4; /* Freq in KHz */
+		break;
+	}
+        buffer[0] = (div>>8) & 0x3f;
+        buffer[1] = div      & 0xff;
+
+	printk(PREFIX "Frequency %d.%03d KHz (divider = 0x%04x)\n",
+						frq/1000,frq%1000,div);
+
+	if (TEA5767_STEREO_MASK & buffer[2])
+		printk(PREFIX "Stereo\n");
+	else
+		printk(PREFIX "Mono\n");
+
+	printk(PREFIX "IF Counter = %d\n",buffer[2] & TEA5767_IF_CNTR_MASK);
+
+	printk(PREFIX "ADC Level = %d\n",(buffer[3] & TEA5767_ADC_LEVEL_MASK)>>4);
+
+	printk(PREFIX "Chip ID = %d\n",(buffer[3] & TEA5767_CHIP_ID_MASK));
+
+	printk(PREFIX "Reserved = 0x%02x\n",(buffer[4] & TEA5767_RESERVED_MASK));
+}
+
+/* Freq should be specifyed at 62.5 Hz */
+static void set_radio_freq(struct i2c_client *c, unsigned int frq)
+{
+	struct tuner *t = i2c_get_clientdata(c);
+        unsigned char buffer[5];
+	unsigned div;
+	int rc;
+
+	if ( tuner_debug )
+		printk(PREFIX "radio freq counter %d\n",frq);
+
+	/* Rounds freq to next decimal value - for 62.5 KHz step */
+	/* frq = 20*(frq/16)+radio_frq[frq%16]; */
+
+	buffer[2] = TEA5767_PORT1_HIGH;
+	buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL | TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND;
+	buffer[4]=0;
+
+	if (t->audmode == V4L2_TUNER_MODE_MONO) {
+		tuner_dbg("TEA5767 set to mono\n");
+		buffer[2] |= TEA5767_MONO;
+	} else
+ 		tuner_dbg("TEA5767 set to stereo\n");
+
+	switch (t->type) {
+	case TEA5767_HIGH_LO_13MHz:
+		tuner_dbg("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n");
+		buffer[2] |= TEA5767_HIGH_LO_INJECT;
+		buffer[4] |= TEA5767_PLLREF_ENABLE;
+		div = (frq*4/16+700+225+25)/50;
+		break;
+	case TEA5767_LOW_LO_13MHz:
+		tuner_dbg("TEA5767 radio LOW LO inject xtal @ 13 MHz\n");
+
+		buffer[4] |= TEA5767_PLLREF_ENABLE;
+		div = (frq*4/16-700-225+25)/50;
+		break;
+	case TEA5767_LOW_LO_32768:
+		tuner_dbg("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n");
+		buffer[3] |= TEA5767_XTAL_32768;
+		/* const 700=4000*175 Khz - to adjust freq to right value */
+		div = (1000*(frq*4/16-700-225)+16384)>>15;
+		break;
+	case TEA5767_HIGH_LO_32768:
+	default:
+		tuner_dbg("TEA5767 radio HIGH LO inject xtal @ 32,768 MHz\n");
+
+		buffer[2] |= TEA5767_HIGH_LO_INJECT;
+		buffer[3] |= TEA5767_XTAL_32768;
+		div = (1000*(frq*4/16+700+225)+16384)>>15;
+		break;
+	}
+        buffer[0] = (div>>8) & 0x3f;
+        buffer[1] = div      & 0xff;
+
+	if ( tuner_debug )
+		tea5767_status_dump(buffer);
+
+        if (5 != (rc = i2c_master_send(c,buffer,5)))
+		tuner_warn("i2c i/o error: rc == %d (should be 5)\n",rc);
+}
+
+static int tea5767_signal(struct i2c_client *c)
+{
+	unsigned char buffer[5];
+	int rc;
+	struct tuner *t = i2c_get_clientdata(c);
+
+	memset(buffer,0,sizeof(buffer));
+        if (5 != (rc = i2c_master_recv(c,buffer,5)))
+                tuner_warn ( "i2c i/o error: rc == %d (should be 5)\n",rc);
+
+	return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) <<(13-4));
+}
+
+static int tea5767_stereo(struct i2c_client *c)
+{
+	unsigned char buffer[5];
+	int rc;
+	struct tuner *t = i2c_get_clientdata(c);
+
+	memset(buffer,0,sizeof(buffer));
+        if (5 != (rc = i2c_master_recv(c,buffer,5)))
+                tuner_warn ( "i2c i/o error: rc == %d (should be 5)\n",rc);
+
+	rc = buffer[2] & TEA5767_STEREO_MASK;
+
+	if ( tuner_debug )
+		tuner_dbg("TEA5767 radio ST GET = %02x\n", rc);
+
+	return ( (buffer[2] & TEA5767_STEREO_MASK) ? V4L2_TUNER_SUB_STEREO: 0);
+}
+
+int tea_detection(struct i2c_client *c)
+{
+	unsigned char buffer[5]= { 0xff, 0xff, 0xff, 0xff, 0xff };
+	int rc;
+	struct tuner *t = i2c_get_clientdata(c);
+
+        if (5 != (rc = i2c_master_recv(c,buffer,5))) {
+                tuner_warn ( "it is not a TEA5767. Received %i chars.\n",rc );
+		return EINVAL;
+	}
+
+	/* If all bytes are the same then it's a TV tuner and not a tea5767 chip. */
+	if (buffer[0] == buffer[1] &&  buffer[0] == buffer[2] &&
+	    buffer[0] == buffer[3] &&  buffer[0] == buffer[4]) {
+                tuner_warn ( "All bytes are equal. It is not a TEA5767\n" );
+		return EINVAL;
+	}
+
+	/*  Status bytes:
+	 *  Byte 4: bit 3:1 : CI (Chip Identification) == 0
+	 *	    bit 0   : internally set to 0
+	 *  Byte 5: bit 7:0 : == 0
+	 */
+
+	if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) {
+                tuner_warn ( "Chip ID is not zero. It is not a TEA5767\n" );
+		return EINVAL;
+	}
+	tuner_warn ( "TEA5767 detected.\n" );
+	return 0;
+}
+
+int tea5767_tuner_init(struct i2c_client *c)
+{
+	struct tuner *t = i2c_get_clientdata(c);
+
+	if (tea_detection(c)==EINVAL) return EINVAL;
+
+        tuner_info("type set to %d (%s)\n",
+                   t->type, TEA5767_TUNER_NAME);
+        strlcpy(c->name, TEA5767_TUNER_NAME, sizeof(c->name));
+
+	t->tv_freq    = set_tv_freq;
+	t->radio_freq = set_radio_freq;
+	t->has_signal = tea5767_signal;
+	t->is_stereo  = tea5767_stereo;
+
+	return (0);
+}
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index eaabfc8..6f6bf4a 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -1,5 +1,5 @@
 /*
- * $Id: tuner-core.c,v 1.15 2005/06/12 01:36:14 mchehab Exp $
+ * $Id: tuner-core.c,v 1.29 2005/06/21 15:40:33 mchehab Exp $
  *
  * i2c tv tuner chip device driver
  * core core, i.e. kernel interfaces, registering and so on
@@ -26,7 +26,6 @@
 /*
  * comment line bellow to return to old behavor, where only one I2C device is supported
  */
-#define CONFIG_TUNER_MULTI_I2C /**/
 
 #define UNSET (-1U)
 
@@ -58,9 +57,7 @@
 MODULE_LICENSE("GPL");
 
 static int this_adap;
-#ifdef CONFIG_TUNER_MULTI_I2C
 static unsigned short first_tuner, tv_tuner, radio_tuner;
-#endif
 
 static struct i2c_driver driver;
 static struct i2c_client client_template;
@@ -81,26 +78,9 @@
 		return;
 	}
 	if (freq < tv_range[0]*16 || freq > tv_range[1]*16) {
-
-		if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) {
-			/* V4L2_TUNER_CAP_LOW frequency */
-
-			tuner_dbg("V4L2_TUNER_CAP_LOW freq selected for TV. Tuners yet doesn't support converting it to valid freq.\n");
-
-			t->tv_freq(c,freq>>10);
-
-			return;
-                } else {
-			/* FIXME: better do that chip-specific, but
-			   right now we don't have that in the config
-			   struct and this way is still better than no
-			   check at all */
 			tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n",
 				   freq/16,freq%16*100/16,tv_range[0],tv_range[1]);
-			return;
-		}
 	}
-	tuner_dbg("62.5 Khz freq step selected for TV.\n");
 	t->tv_freq(c,freq);
 }
 
@@ -116,31 +96,18 @@
 		tuner_info("no radio tuning for this one, sorry.\n");
 		return;
 	}
-	if (freq < radio_range[0]*16 || freq > radio_range[1]*16) {
-		if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) {
-			/* V4L2_TUNER_CAP_LOW frequency */
-			if (t->type == TUNER_TEA5767) {
-				tuner_info("radio freq step 62.5Hz (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000);
-				t->radio_freq(c,freq>>10);
-				return;
-			}
-
-			tuner_dbg("V4L2_TUNER_CAP_LOW freq selected for Radio. Tuners yet doesn't support converting it to valid freq.\n");
-
-			tuner_info("radio freq (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000);
-
-			t->radio_freq(c,freq>>10);
-			return;
-
-                } else {
-			tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n",
-			   freq/16,freq%16*100/16,
-				   radio_range[0],radio_range[1]);
-			return;
-		}
+	if (freq >= radio_range[0]*16000 && freq <= radio_range[1]*16000) {
+		if (tuner_debug)
+			tuner_info("radio freq step 62.5Hz (%d.%06d)\n",
+			 		    freq/16000,freq%16000*1000/16);
+		t->radio_freq(c,freq);
+        } else {
+		tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n",
+			    freq/16,freq%16*100/16,
+			    radio_range[0],radio_range[1]);
 	}
-	tuner_dbg("62.5 Khz freq step selected for Radio.\n");
-	t->radio_freq(c,freq);
+
+	return;
 }
 
 static void set_freq(struct i2c_client *c, unsigned long freq)
@@ -166,8 +133,8 @@
 static void set_type(struct i2c_client *c, unsigned int type)
 {
 	struct tuner *t = i2c_get_clientdata(c);
+	unsigned char buffer[4];
 
-	tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type);
 	/* sanity check */
 	if (type == UNSET || type == TUNER_ABSENT)
 		return;
@@ -179,8 +146,8 @@
 		t->type = type;
 		return;
 	}
-	if (t->initialized)
-		/* run only once */
+	if ((t->initialized) && (t->type == type))
+		/* run only once except type change  Hac 04/05*/
 		return;
 
 	t->initialized = 1;
@@ -193,25 +160,42 @@
 	case TUNER_PHILIPS_TDA8290:
 		tda8290_init(c);
 		break;
+	case TUNER_TEA5767:
+		if (tea5767_tuner_init(c)==EINVAL) t->type=TUNER_ABSENT;
+		break;
+	case TUNER_PHILIPS_FMD1216ME_MK3:
+		buffer[0] = 0x0b;
+		buffer[1] = 0xdc;
+		buffer[2] = 0x9c;
+		buffer[3] = 0x60;
+    		i2c_master_send(c,buffer,4);
+		mdelay(1);
+		buffer[2] = 0x86;
+		buffer[3] = 0x54;
+    		i2c_master_send(c,buffer,4);
+		default_tuner_init(c);
+		break;
 	default:
+		/* TEA5767 autodetection code */
+			if (tea5767_tuner_init(c)!=EINVAL) {
+				t->type = TUNER_TEA5767;
+				if (first_tuner == 0x60)
+					first_tuner++;
+				break;
+			}
+
 		default_tuner_init(c);
 		break;
 	}
+	tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type);
 }
 
-#ifdef CONFIG_TUNER_MULTI_I2C
 #define CHECK_ADDR(tp,cmd,tun)	if (client->addr!=tp) { \
-			  return 0; } else \
+			  return 0; } else if (tuner_debug) \
 			  tuner_info ("Cmd %s accepted to "tun"\n",cmd);
 #define CHECK_MODE(cmd)	if (t->mode == V4L2_TUNER_RADIO) { \
 		 	CHECK_ADDR(radio_tuner,cmd,"radio") } else \
 			{ CHECK_ADDR(tv_tuner,cmd,"TV"); }
-#else
-#define CHECK_ADDR(tp,cmd,tun) tuner_info ("Cmd %s accepted to "tun"\n",cmd);
-#define CHECK_MODE(cmd) tuner_info ("Cmd %s accepted\n",cmd);
-#endif
-
-#ifdef CONFIG_TUNER_MULTI_I2C
 
 static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr)
 {
@@ -242,9 +226,6 @@
 	}
 	set_type(c,tun_addr->type);
 }
-#else
-#define set_addr(c,tun_addr) set_type(c,(tun_addr)->type)
-#endif
 
 static char pal[] = "-";
 module_param_string(pal, pal, sizeof(pal), 0644);
@@ -284,17 +265,12 @@
 {
 	struct tuner *t;
 
-#ifndef CONFIG_TUNER_MULTI_I2C
-	if (this_adap > 0)
-		return -1;
-#else
 	/* by default, first I2C card is both tv and radio tuner */
 	if (this_adap == 0) {
 		first_tuner = addr;
 		tv_tuner = addr;
 		radio_tuner = addr;
 	}
-#endif
 	this_adap++;
 
         client_template.adapter = adap;
@@ -308,6 +284,7 @@
 	i2c_set_clientdata(&t->i2c, t);
 	t->type       = UNSET;
 	t->radio_if2  = 10700*1000; /* 10.7MHz - FM radio */
+	t->audmode    = V4L2_TUNER_MODE_STEREO;
 
         i2c_attach_client(&t->i2c);
 	tuner_info("chip found @ 0x%x (%s)\n",
@@ -325,11 +302,9 @@
 	}
 	this_adap = 0;
 
-#ifdef CONFIG_TUNER_MULTI_I2C
 	first_tuner = 0;
 	tv_tuner = 0;
 	radio_tuner = 0;
-#endif
 
 	if (adap->class & I2C_CLASS_TV_ANALOG)
 		return i2c_probe(adap, &addr_data, tuner_attach);
@@ -392,8 +367,7 @@
 			t->radio_if2 = 41300 * 1000;
 			break;
 		}
-                break;
-
+		break;
 	/* --- v4l ioctls --- */
 	/* take care: bttv does userspace copying, we'll get a
 	   kernel pointer here... */
@@ -440,11 +414,18 @@
 				vt->signal = t->has_signal(client);
 			if (t->is_stereo) {
 				if (t->is_stereo(client))
-					vt-> flags |= VIDEO_TUNER_STEREO_ON;
+					vt->flags |= VIDEO_TUNER_STEREO_ON;
 				else
-					vt-> flags &= 0xffff ^ VIDEO_TUNER_STEREO_ON;
+					vt->flags &= ~VIDEO_TUNER_STEREO_ON;
 			}
 			vt->flags |= V4L2_TUNER_CAP_LOW; /* Allow freqs at 62.5 Hz */
+
+			vt->rangelow = radio_range[0] * 16000;
+			vt->rangehigh = radio_range[1] * 16000;
+
+		} else {
+			vt->rangelow = tv_range[0] * 16;
+			vt->rangehigh = tv_range[1] * 16;
 		}
 
 		return 0;
@@ -510,20 +491,46 @@
 				tuner -> signal = t->has_signal(client);
 			if (t->is_stereo) {
 				if (t->is_stereo(client)) {
-					tuner -> capability |= V4L2_TUNER_CAP_STEREO;
-					tuner -> rxsubchans |= V4L2_TUNER_SUB_STEREO;
+					tuner -> rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
 				} else {
-					tuner -> rxsubchans &= 0xffff ^ V4L2_TUNER_SUB_STEREO;
+					tuner -> rxsubchans = V4L2_TUNER_SUB_MONO;
 				}
 			}
+			tuner->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
+			tuner->audmode = t->audmode;
+
+			tuner->rangelow = radio_range[0] * 16000;
+			tuner->rangehigh = radio_range[1] * 16000;
+		} else {
+			tuner->rangelow = tv_range[0] * 16;
+			tuner->rangehigh = tv_range[1] * 16;
 		}
-		/* Wow to deal with V4L2_TUNER_CAP_LOW ? For now, it accepts from low at 62.5KHz step  to high at 62.5 Hz */
-		tuner->rangelow = tv_range[0] * 16;
-//		tuner->rangehigh = tv_range[1] * 16;
-//		tuner->rangelow = tv_range[0] * 16384;
-		tuner->rangehigh = tv_range[1] * 16384;
 		break;
 	}
+	case VIDIOC_S_TUNER: /* Allow changing radio range and audio mode */
+	{
+		struct v4l2_tuner *tuner = arg;
+
+		CHECK_ADDR(radio_tuner,"VIDIOC_S_TUNER","radio");
+		SWITCH_V4L2;
+
+		/* To switch the audio mode, applications initialize the
+		   index and audmode fields and the reserved array and
+		   call the VIDIOC_S_TUNER ioctl. */
+		/* rxsubchannels: V4L2_TUNER_MODE_MONO, V4L2_TUNER_MODE_STEREO,
+		   V4L2_TUNER_MODE_LANG1, V4L2_TUNER_MODE_LANG2,
+		   V4L2_TUNER_MODE_SAP */
+
+		if (tuner->audmode == V4L2_TUNER_MODE_MONO)
+			t->audmode = V4L2_TUNER_MODE_MONO;
+		else
+			t->audmode = V4L2_TUNER_MODE_STEREO;
+
+		set_radio_freq(client, t->freq);
+		break;
+	}
+	case TDA9887_SET_CONFIG: /* Nothing to do on tuner-core */
+		break;
 	default:
 		tuner_dbg ("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd);
 		/* nothing */
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index 539f305..c39ed62 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -1,5 +1,5 @@
 /*
- * $Id: tuner-simple.c,v 1.21 2005/06/10 19:53:26 nsh Exp $
+ * $Id: tuner-simple.c,v 1.31 2005/06/21 16:02:25 mkrufky Exp $
  *
  * i2c tv tuner chip device driver
  * controls all those simple 4-control-bytes style tuners.
@@ -207,28 +207,27 @@
 	{ "LG PAL (TAPE series)", LGINNOTEK, PAL,
           16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623},
 
-        { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
-          16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
-        { "Philips FQ1236A MK4", Philips, NTSC,
-          16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
+	{ "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
+	  16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
+	{ "Philips FQ1236A MK4", Philips, NTSC,
+	  16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
 
 	/* Should work for TVF8531MF, TVF8831MF, TVF8731MF */
 	{ "Ymec TVision TVF-8531MF", Philips, NTSC,
 	  16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
 	{ "Ymec TVision TVF-5533MF", Philips, NTSC,
 	  16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
-
 	{ "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
 	  16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
-	{ "Tena TNF9533-D/IF", LGINNOTEK, PAL,
-	  16*160.25, 16*464.25, 0x01,0x02,0x08,0x8e,623},
+	/* Should work for TNF9533-D/IF, TNF9533-B/DF */
+	{ "Tena TNF9533-D/IF", Philips, PAL,
+          16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623},
 
-	/*
-	 * This entry is for TEA5767 FM radio only chip used on several boards
-	 * w/TV tuner
-	 */
+	/* This entry is for TEA5767 FM radio only chip used on several boards w/TV tuner */
 	{ TEA5767_TUNER_NAME, Philips, RADIO,
-	  -1, -1, 0, 0, 0, TEA5767_LOW_LO_32768,0},
+          -1, -1, 0, 0, 0, TEA5767_LOW_LO_32768,0},
+	{ "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL,
+	  16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 },
 };
 
 unsigned const int tuner_count = ARRAY_SIZE(tuners);
@@ -455,24 +454,24 @@
 	int rc;
 
 	tun=&tuners[t->type];
-	div = freq + (int)(16*10.7);
+	div = (freq / 1000) + (int)(16*10.7);
 	buffer[2] = tun->config;
 
 	switch (t->type) {
 	case TUNER_TENA_9533_DI:
 	case TUNER_YMEC_TVF_5533MF:
-
 		/*These values are empirically determinated */
-		div = (freq*122)/16 - 20;
+		div = (freq * 122) / 16000 - 20;
 		buffer[2] = 0x88; /* could be also 0x80 */
 		buffer[3] = 0x19; /* could be also 0x10, 0x18, 0x99 */
 		break;
 	case TUNER_PHILIPS_FM1216ME_MK3:
 	case TUNER_PHILIPS_FM1236_MK3:
+	case TUNER_PHILIPS_FMD1216ME_MK3:
 		buffer[3] = 0x19;
 		break;
 	case TUNER_PHILIPS_FM1256_IH3:
-		div = (20 * freq)/16 + 333 * 2;
+		div = (20 * freq) / 16000 + 333 * 2;
 	        buffer[2] = 0x80;
 		buffer[3] = 0x19;
 		break;
@@ -505,6 +504,7 @@
 	t->radio_freq = default_set_radio_freq;
 	t->has_signal = tuner_signal;
 	t->is_stereo  = tuner_stereo;
+
 	return 0;
 }
 
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index d8d6539..353deb2 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -364,9 +364,7 @@
 	.id_table	= mptfc_pci_table,
 	.probe		= mptfc_probe,
 	.remove		= __devexit_p(mptscsih_remove),
-	.driver         = {
-		.shutdown = mptscsih_shutdown,
-        },
+	.shutdown	= mptscsih_shutdown,
 #ifdef CONFIG_PM
 	.suspend	= mptscsih_suspend,
 	.resume		= mptscsih_resume,
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index a0078ae..4f973a4 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -170,7 +170,7 @@
 #endif
 
 void 		mptscsih_remove(struct pci_dev *);
-void 		mptscsih_shutdown(struct device *);
+void 		mptscsih_shutdown(struct pci_dev *);
 #ifdef CONFIG_PM
 int 		mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
 int 		mptscsih_resume(struct pci_dev *pdev);
@@ -988,7 +988,7 @@
 #endif
 #endif
 
-	mptscsih_shutdown(&pdev->dev);
+	mptscsih_shutdown(pdev);
 
 	sz1=0;
 
@@ -1026,9 +1026,9 @@
  *
  */
 void
-mptscsih_shutdown(struct device * dev)
+mptscsih_shutdown(struct pci_dev *pdev)
 {
-	MPT_ADAPTER 		*ioc = pci_get_drvdata(to_pci_dev(dev));
+	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
 	struct Scsi_Host 	*host = ioc->sh;
 	MPT_SCSI_HOST		*hd;
 
@@ -1054,7 +1054,7 @@
 int
 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
 {
-	mptscsih_shutdown(&pdev->dev);
+	mptscsih_shutdown(pdev);
 	return mpt_suspend(pdev,state);
 }
 
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index d73aec3..5ea89bf 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -82,7 +82,7 @@
 #endif
 
 extern void mptscsih_remove(struct pci_dev *);
-extern void mptscsih_shutdown(struct device *);
+extern void mptscsih_shutdown(struct pci_dev *);
 #ifdef CONFIG_PM
 extern int mptscsih_suspend(struct pci_dev *pdev, u32 state);
 extern int mptscsih_resume(struct pci_dev *pdev);
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 5f9a61b..e0c0ee5 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -419,9 +419,7 @@
 	.id_table	= mptspi_pci_table,
 	.probe		= mptspi_probe,
 	.remove		= __devexit_p(mptscsih_remove),
-	.driver         = {
-		.shutdown = mptscsih_shutdown,
-        },
+	.shutdown	= mptscsih_shutdown,
 #ifdef CONFIG_PM
 	.suspend	= mptscsih_suspend,
 	.resume		= mptscsih_resume,
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
index 3a5f6ac..7a42966 100644
--- a/drivers/mmc/mmci.c
+++ b/drivers/mmc/mmci.c
@@ -20,6 +20,7 @@
 #include <linux/mmc/host.h>
 #include <linux/mmc/protocol.h>
 
+#include <asm/div64.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/scatterlist.h>
@@ -70,6 +71,7 @@
 static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
 {
 	unsigned int datactrl, timeout, irqmask;
+	unsigned long long clks;
 	void __iomem *base;
 
 	DBG(host, "blksz %04x blks %04x flags %08x\n",
@@ -81,9 +83,10 @@
 
 	mmci_init_sg(host, data);
 
-	timeout = data->timeout_clks +
-		  ((unsigned long long)data->timeout_ns * host->cclk) /
-		   1000000000ULL;
+	clks = (unsigned long long)data->timeout_ns * host->cclk;
+	do_div(clks, 1000000000UL);
+
+	timeout = data->timeout_clks + (unsigned int)clks;
 
 	base = host->base;
 	writel(timeout, base + MMCIDATATIMER);
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index b7fbd30..0c41d4b 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -54,28 +54,6 @@
 #define DBGF(x...)	do { } while (0)
 #endif
 
-#ifdef CONFIG_MMC_DEBUG
-void DBG_REG(int reg, u8 value)
-{
-	int i;
-	
-	printk(KERN_DEBUG "wbsd: Register %d: 0x%02X %3d '%c' ",
-		reg, (int)value, (int)value, (value < 0x20)?'.':value);
-	
-	for (i = 7;i >= 0;i--)
-	{
-		if (value & (1 << i))
-			printk("x");
-		else
-			printk(".");
-	}
-	
-	printk("\n");
-}
-#else
-#define DBG_REG(r, v) do {}  while (0)
-#endif
-
 /*
  * Device resources
  */
@@ -92,6 +70,13 @@
 
 #endif /* CONFIG_PNP */
 
+static const int config_ports[] = { 0x2E, 0x4E };
+static const int unlock_codes[] = { 0x83, 0x87 };
+
+static const int valid_ids[] = {
+	0x7112,
+	};
+
 #ifdef CONFIG_PNP
 static unsigned int nopnp = 0;
 #else
@@ -1051,6 +1036,20 @@
 \*****************************************************************************/
 
 /*
+ * Helper function for card detection
+ */
+static void wbsd_detect_card(unsigned long data)
+{
+	struct wbsd_host *host = (struct wbsd_host*)data;
+	
+	BUG_ON(host == NULL);
+	
+	DBG("Executing card detection\n");
+	
+	mmc_detect_change(host->mmc);	
+}
+
+/*
  * Tasklets
  */
 
@@ -1075,7 +1074,6 @@
 {
 	struct wbsd_host* host = (struct wbsd_host*)param;
 	u8 csr;
-	int change = 0;
 	
 	spin_lock(&host->lock);
 	
@@ -1094,14 +1092,20 @@
 		{
 			DBG("Card inserted\n");
 			host->flags |= WBSD_FCARD_PRESENT;
-			change = 1;
+			
+			/*
+			 * Delay card detection to allow electrical connections
+			 * to stabilise.
+			 */
+			mod_timer(&host->timer, jiffies + HZ/2);
 		}
+		
+		spin_unlock(&host->lock);
 	}
 	else if (host->flags & WBSD_FCARD_PRESENT)
 	{
 		DBG("Card removed\n");
 		host->flags &= ~WBSD_FCARD_PRESENT;
-		change = 1;
 		
 		if (host->mrq)
 		{
@@ -1112,15 +1116,14 @@
 			host->mrq->cmd->error = MMC_ERR_FAILED;
 			tasklet_schedule(&host->finish_tasklet);
 		}
-	}
-	
-	/*
-	 * Unlock first since we might get a call back.
-	 */
-	spin_unlock(&host->lock);
+		
+		/*
+		 * Unlock first since we might get a call back.
+		 */
+		spin_unlock(&host->lock);
 
-	if (change)
 		mmc_detect_change(host->mmc);
+	}
 }
 
 static void wbsd_tasklet_fifo(unsigned long param)
@@ -1325,6 +1328,13 @@
 	spin_lock_init(&host->lock);
 	
 	/*
+	 * Set up detection timer
+	 */
+	init_timer(&host->timer);
+	host->timer.data = (unsigned long)host;
+	host->timer.function = wbsd_detect_card;
+	
+	/*
 	 * Maximum number of segments. Worst case is one sector per segment
 	 * so this will be 64kB/512.
 	 */
@@ -1351,11 +1361,17 @@
 static void __devexit wbsd_free_mmc(struct device* dev)
 {
 	struct mmc_host* mmc;
+	struct wbsd_host* host;
 	
 	mmc = dev_get_drvdata(dev);
 	if (!mmc)
 		return;
 	
+	host = mmc_priv(mmc);
+	BUG_ON(host == NULL);
+	
+	del_timer_sync(&host->timer);
+	
 	mmc_free_host(mmc);
 	
 	dev_set_drvdata(dev, NULL);
diff --git a/drivers/mmc/wbsd.h b/drivers/mmc/wbsd.h
index 864f3082..661a9f6 100644
--- a/drivers/mmc/wbsd.h
+++ b/drivers/mmc/wbsd.h
@@ -8,13 +8,6 @@
  * published by the Free Software Foundation.
  */
 
-const int config_ports[] = { 0x2E, 0x4E };
-const int unlock_codes[] = { 0x83, 0x87 };
-
-const int valid_ids[] = {
-	0x7112,
-	};
-
 #define LOCK_CODE		0xAA
 
 #define WBSD_CONF_SWRST		0x02
@@ -187,4 +180,6 @@
 	struct tasklet_struct	timeout_tasklet;
 	struct tasklet_struct	finish_tasklet;
 	struct tasklet_struct	block_tasklet;
+	
+	struct timer_list	timer;		/* Card detection timer */
 };
diff --git a/drivers/mtd/afs.c b/drivers/mtd/afs.c
index 801e6c7..7363e10 100644
--- a/drivers/mtd/afs.c
+++ b/drivers/mtd/afs.c
@@ -219,7 +219,7 @@
 	 */
 	for (idx = off = 0; off < mtd->size; off += mtd->erasesize) {
 		struct image_info_struct iis;
-		u_int iis_ptr, img_ptr, size;
+		u_int iis_ptr, img_ptr;
 
 		/* Read the footer. */
 		ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask);
@@ -236,21 +236,9 @@
 			continue;
 
 		strcpy(str, iis.name);
-		size = mtd->erasesize + off - img_ptr;
-
-		/*
-		 * In order to support JFFS2 partitions on this layout,
-		 * we must lie to MTD about the real size of JFFS2
-		 * partitions; this ensures that the AFS flash footer
-		 * won't be erased by JFFS2.  Please ensure that your
-		 * JFFS2 partitions are given image numbers between
-		 * 1000 and 2000 inclusive.
-		 */
-		if (iis.imageNumber >= 1000 && iis.imageNumber < 2000)
-			size -= mtd->erasesize;
 
 		parts[idx].name		= str;
-		parts[idx].size		= size;
+		parts[idx].size		= (iis.length + mtd->erasesize - 1) & ~(mtd->erasesize - 1);
 		parts[idx].offset	= img_ptr;
 		parts[idx].mask_flags	= 0;
 
diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c
index d272ea3..91d1c4c 100644
--- a/drivers/net/3c515.c
+++ b/drivers/net/3c515.c
@@ -822,7 +822,7 @@
 				break;	/* Bad news!  */
 			skb->dev = dev;	/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
-			vp->rx_ring[i].addr = isa_virt_to_bus(skb->tail);
+			vp->rx_ring[i].addr = isa_virt_to_bus(skb->data);
 		}
 		vp->rx_ring[i - 1].next = isa_virt_to_bus(&vp->rx_ring[0]);	/* Wrap the ring. */
 		outl(isa_virt_to_bus(&vp->rx_ring[0]), ioaddr + UpListPtr);
@@ -1406,7 +1406,7 @@
 				break;	/* Bad news!  */
 			skb->dev = dev;	/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
-			vp->rx_ring[entry].addr = isa_virt_to_bus(skb->tail);
+			vp->rx_ring[entry].addr = isa_virt_to_bus(skb->data);
 			vp->rx_skbuff[entry] = skb;
 		}
 		vp->rx_ring[entry].status = 0;	/* Clear complete bit. */
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 80ec9aa..07746b9 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -1802,7 +1802,7 @@
 				break;			/* Bad news!  */
 			skb->dev = dev;			/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
-			vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
+			vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
 		}
 		if (i != RX_RING_SIZE) {
 			int j;
@@ -2632,7 +2632,7 @@
 				pci_dma_sync_single_for_cpu(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
 				/* 'skb_put()' points to the start of sk_buff data area. */
 				memcpy(skb_put(skb, pkt_len),
-					   vp->rx_skbuff[entry]->tail,
+					   vp->rx_skbuff[entry]->data,
 					   pkt_len);
 				pci_dma_sync_single_for_device(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
 				vp->rx_copy++;
@@ -2678,7 +2678,7 @@
 			}
 			skb->dev = dev;			/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
-			vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
+			vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
 			vp->rx_skbuff[entry] = skb;
 		}
 		vp->rx_ring[entry].status = 0;	/* Clear complete bit. */
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index e4b3c5c..7b293f0 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -596,7 +596,7 @@
 
 		mapping =
 		cp->rx_skb[rx_tail].mapping =
-			pci_map_single(cp->pdev, new_skb->tail,
+			pci_map_single(cp->pdev, new_skb->data,
 				       buflen, PCI_DMA_FROMDEVICE);
 		cp->rx_skb[rx_tail].skb = new_skb;
 
@@ -1101,7 +1101,7 @@
 		skb_reserve(skb, RX_OFFSET);
 
 		cp->rx_skb[i].mapping = pci_map_single(cp->pdev,
-			skb->tail, cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
+			skb->data, cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
 		cp->rx_skb[i].skb = skb;
 
 		cp->rx_ring[i].opts2 = 0;
diff --git a/drivers/net/82596.c b/drivers/net/82596.c
index 65f97b1..13b745b 100644
--- a/drivers/net/82596.c
+++ b/drivers/net/82596.c
@@ -546,11 +546,11 @@
 		rbd->b_next = WSWAPrbd(virt_to_bus(rbd+1));
 		rbd->b_addr = WSWAPrbd(virt_to_bus(rbd));
 		rbd->skb = skb;
-		rbd->v_data = skb->tail;
-		rbd->b_data = WSWAPchar(virt_to_bus(skb->tail));
+		rbd->v_data = skb->data;
+		rbd->b_data = WSWAPchar(virt_to_bus(skb->data));
 		rbd->size = PKT_BUF_SZ;
 #ifdef __mc68000__
-		cache_clear(virt_to_phys(skb->tail), PKT_BUF_SZ);
+		cache_clear(virt_to_phys(skb->data), PKT_BUF_SZ);
 #endif
 	}
 	lp->rbd_head = lp->rbds;
@@ -816,10 +816,10 @@
 				rx_in_place = 1;
 				rbd->skb = newskb;
 				newskb->dev = dev;
-				rbd->v_data = newskb->tail;
-				rbd->b_data = WSWAPchar(virt_to_bus(newskb->tail));
+				rbd->v_data = newskb->data;
+				rbd->b_data = WSWAPchar(virt_to_bus(newskb->data));
 #ifdef __mc68000__
-				cache_clear(virt_to_phys(newskb->tail), PKT_BUF_SZ);
+				cache_clear(virt_to_phys(newskb->data), PKT_BUF_SZ);
 #endif
 			}
 			else
@@ -840,7 +840,7 @@
 				skb->protocol=eth_type_trans(skb,dev);
 				skb->len = pkt_len;
 #ifdef __mc68000__
-				cache_clear(virt_to_phys(rbd->skb->tail),
+				cache_clear(virt_to_phys(rbd->skb->data),
 						pkt_len);
 #endif
 				netif_rx(skb);
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index b7dd726..8618012 100755
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -87,6 +87,7 @@
 #include <linux/if_vlan.h>
 #include <linux/ctype.h>	
 #include <linux/crc32.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -2006,12 +2007,11 @@
 	}
 
 	/* Initialize DMA */
-	if(!pci_dma_supported(pdev, 0xffffffff)){
+	if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) < 0) {
 		printk(KERN_ERR "amd8111e: DMA not supported,"
 			"exiting.\n");
-		goto  err_free_reg;
-	} else
-		pdev->dma_mask = 0xffffffff;
+		goto err_free_reg;
+	}
 	
 	reg_addr = pci_resource_start(pdev, 0);
 	reg_len = pci_resource_len(pdev, 0);
diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c
index 2e28c20..942a281 100644
--- a/drivers/net/arm/etherh.c
+++ b/drivers/net/arm/etherh.c
@@ -68,7 +68,6 @@
 	void __iomem	*dma_base;
 	unsigned int	id;
 	void __iomem	*ctrl_port;
-	void __iomem	*base;
 	unsigned char	ctrl;
 	u32		supported;
 };
@@ -178,7 +177,7 @@
 	switch (etherh_priv(dev)->id) {
 	case PROD_I3_ETHERLAN600:
 	case PROD_I3_ETHERLAN600A:
-		addr = etherh_priv(dev)->base + EN0_RCNTHI;
+		addr = (void *)dev->base_addr + EN0_RCNTHI;
 
 		switch (dev->if_port) {
 		case IF_PORT_10BASE2:
@@ -219,7 +218,7 @@
 	switch (etherh_priv(dev)->id) {
 	case PROD_I3_ETHERLAN600:
 	case PROD_I3_ETHERLAN600A:
-		addr = etherh_priv(dev)->base + EN0_RCNTHI;
+		addr = (void *)dev->base_addr + EN0_RCNTHI;
 		switch (dev->if_port) {
 		case IF_PORT_10BASE2:
 			stat = 1;
@@ -282,7 +281,7 @@
 etherh_reset(struct net_device *dev)
 {
 	struct ei_device *ei_local = netdev_priv(dev);
-	void __iomem *addr = etherh_priv(dev)->base;
+	void __iomem *addr = (void *)dev->base_addr;
 
 	writeb(E8390_NODMA+E8390_PAGE0+E8390_STOP, addr);
 
@@ -328,7 +327,7 @@
 
 	ei_local->dmaing = 1;
 
-	addr = etherh_priv(dev)->base;
+	addr = (void *)dev->base_addr;
 	dma_base = etherh_priv(dev)->dma_base;
 
 	count = (count + 1) & ~1;
@@ -388,7 +387,7 @@
 
 	ei_local->dmaing = 1;
 
-	addr = etherh_priv(dev)->base;
+	addr = (void *)dev->base_addr;
 	dma_base = etherh_priv(dev)->dma_base;
 
 	buf = skb->data;
@@ -428,7 +427,7 @@
 
 	ei_local->dmaing = 1;
 
-	addr = etherh_priv(dev)->base;
+	addr = (void *)dev->base_addr;
 	dma_base = etherh_priv(dev)->dma_base;
 
 	writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD);
@@ -697,8 +696,7 @@
 		eh->ctrl_port = eh->ioc_fast;
 	}
 
-	eh->base = eh->memc + data->ns8390_offset;
-	dev->base_addr = (unsigned long)eh->base;
+	dev->base_addr = (unsigned long)eh->memc + data->ns8390_offset;
 	eh->dma_base = eh->memc + data->dataport_offset;
 	eh->ctrl_port += data->ctrlport_offset;
 
diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c
index b8ab2b6..e613cc2 100644
--- a/drivers/net/at1700.c
+++ b/drivers/net/at1700.c
@@ -34,10 +34,6 @@
 	only is it difficult to detect, it also moves around in I/O space in
 	response to inb()s from other device probes!
 */
-/*
-	99/03/03  Allied Telesis RE1000 Plus support by T.Hagawa
-	99/12/30	port to 2.3.35 by K.Takai
-*/
 
 #include <linux/config.h>
 #include <linux/errno.h>
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 00e5257..8dc657f 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1261,7 +1261,7 @@
 	spin_unlock_irqrestore(&bp->lock, flags);
 }
 
-static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_match *match)
+static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_id *match)
 {
 	int j, rev, ret;
 	struct bmac_data *bp;
@@ -1645,16 +1645,13 @@
 	return 0;
 }
 
-static struct of_match bmac_match[] = 
+static struct of_device_id bmac_match[] = 
 {
 	{
 	.name 		= "bmac",
-	.type		= OF_ANY_MATCH,
-	.compatible	= OF_ANY_MATCH,
 	.data		= (void *)0,
 	},
 	{
-	.name 		= OF_ANY_MATCH,
 	.type		= "network",
 	.compatible	= "bmac+",
 	.data		= (void *)1,
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
index aa42b7a..430c628 100644
--- a/drivers/net/dl2k.c
+++ b/drivers/net/dl2k.c
@@ -547,7 +547,7 @@
 				skb_reserve (skb, 2);
 				np->rx_ring[entry].fraginfo =
 				    cpu_to_le64 (pci_map_single
-					 (np->pdev, skb->tail, np->rx_buf_sz,
+					 (np->pdev, skb->data, np->rx_buf_sz,
 					  PCI_DMA_FROMDEVICE));
 			}
 			np->rx_ring[entry].fraginfo |=
@@ -618,7 +618,7 @@
 		/* Rubicon now supports 40 bits of addressing space. */
 		np->rx_ring[i].fraginfo =
 		    cpu_to_le64 ( pci_map_single (
-			 	  np->pdev, skb->tail, np->rx_buf_sz,
+			 	  np->pdev, skb->data, np->rx_buf_sz,
 				  PCI_DMA_FROMDEVICE));
 		np->rx_ring[i].fraginfo |= cpu_to_le64 (np->rx_buf_sz) << 48;
 	}
@@ -906,7 +906,7 @@
 				/* 16 byte align the IP header */
 				skb_reserve (skb, 2);
 				eth_copy_and_sum (skb,
-						  np->rx_skbuff[entry]->tail,
+						  np->rx_skbuff[entry]->data,
 						  pkt_len, 0);
 				skb_put (skb, pkt_len);
 				pci_dma_sync_single_for_device(np->pdev,
@@ -950,7 +950,7 @@
 			skb_reserve (skb, 2);
 			np->rx_ring[entry].fraginfo =
 			    cpu_to_le64 (pci_map_single
-					 (np->pdev, skb->tail, np->rx_buf_sz,
+					 (np->pdev, skb->data, np->rx_buf_sz,
 					  PCI_DMA_FROMDEVICE));
 		}
 		np->rx_ring[entry].fraginfo |=
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 1e56c8e..d0fa244 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -2447,9 +2447,8 @@
 #endif
 
 
-static void e100_shutdown(struct device *dev)
+static void e100_shutdown(struct pci_dev *pdev)
 {
-	struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct nic *nic = netdev_priv(netdev);
 
@@ -2470,11 +2469,7 @@
 	.suspend =      e100_suspend,
 	.resume =       e100_resume,
 #endif
-
-	.driver = {
-		.shutdown = e100_shutdown,
-	}
-
+	.shutdown =	e100_shutdown,
 };
 
 static int __init e100_init_module(void)
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
index 98b3a2f..1795425 100644
--- a/drivers/net/eepro100.c
+++ b/drivers/net/eepro100.c
@@ -1269,7 +1269,7 @@
 		if (skb == NULL)
 			break;			/* OK.  Just initially short of Rx bufs. */
 		skb->dev = dev;			/* Mark as being used by this device. */
-		rxf = (struct RxFD *)skb->tail;
+		rxf = (struct RxFD *)skb->data;
 		sp->rx_ringp[i] = rxf;
 		sp->rx_ring_dma[i] =
 			pci_map_single(sp->pdev, rxf,
@@ -1661,7 +1661,7 @@
 		sp->rx_ringp[entry] = NULL;
 		return NULL;
 	}
-	rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->tail;
+	rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->data;
 	sp->rx_ring_dma[entry] =
 		pci_map_single(sp->pdev, rxf,
 					   PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE);
@@ -1808,10 +1808,10 @@
 
 #if 1 || USE_IP_CSUM
 				/* Packet is in one chunk -- we can copy + cksum. */
-				eth_copy_and_sum(skb, sp->rx_skbuff[entry]->tail, pkt_len, 0);
+				eth_copy_and_sum(skb, sp->rx_skbuff[entry]->data, pkt_len, 0);
 				skb_put(skb, pkt_len);
 #else
-				memcpy(skb_put(skb, pkt_len), sp->rx_skbuff[entry]->tail,
+				memcpy(skb_put(skb, pkt_len), sp->rx_skbuff[entry]->data,
 					   pkt_len);
 #endif
 				pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[entry],
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index 81ebaed..87f5227 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -1003,7 +1003,7 @@
 		skb->dev = dev;			/* Mark as being used by this device. */
 		skb_reserve(skb, 2);	/* 16 byte align the IP header. */
 		ep->rx_ring[i].bufaddr = pci_map_single(ep->pci_dev, 
-			skb->tail, ep->rx_buf_sz, PCI_DMA_FROMDEVICE);
+			skb->data, ep->rx_buf_sz, PCI_DMA_FROMDEVICE);
 		ep->rx_ring[i].rxstatus = cpu_to_le32(DescOwn);
 	}
 	ep->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
@@ -1274,7 +1274,7 @@
 							    ep->rx_ring[entry].bufaddr,
 							    ep->rx_buf_sz,
 							    PCI_DMA_FROMDEVICE);
-				eth_copy_and_sum(skb, ep->rx_skbuff[entry]->tail, pkt_len, 0);
+				eth_copy_and_sum(skb, ep->rx_skbuff[entry]->data, pkt_len, 0);
 				skb_put(skb, pkt_len);
 				pci_dma_sync_single_for_device(ep->pci_dev,
 							       ep->rx_ring[entry].bufaddr,
@@ -1308,7 +1308,7 @@
 			skb->dev = dev;			/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
 			ep->rx_ring[entry].bufaddr = pci_map_single(ep->pci_dev, 
-				skb->tail, ep->rx_buf_sz, PCI_DMA_FROMDEVICE);
+				skb->data, ep->rx_buf_sz, PCI_DMA_FROMDEVICE);
 			work_done++;
 		}
 		ep->rx_ring[entry].rxstatus = cpu_to_le32(DescOwn);
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
index 9e0303f..55dbe9a 100644
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -1107,7 +1107,7 @@
 
 		skb->dev = dev;	/* Mark as being used by this device. */
 		np->lack_rxbuf->skbuff = skb;
-		np->lack_rxbuf->buffer = pci_map_single(np->pci_dev, skb->tail,
+		np->lack_rxbuf->buffer = pci_map_single(np->pci_dev, skb->data,
 			np->rx_buf_sz, PCI_DMA_FROMDEVICE);
 		np->lack_rxbuf->status = RXOWN;
 		++np->really_rx_count;
@@ -1300,7 +1300,7 @@
 		++np->really_rx_count;
 		np->rx_ring[i].skbuff = skb;
 		skb->dev = dev;	/* Mark as being used by this device. */
-		np->rx_ring[i].buffer = pci_map_single(np->pci_dev, skb->tail,
+		np->rx_ring[i].buffer = pci_map_single(np->pci_dev, skb->data,
 			np->rx_buf_sz, PCI_DMA_FROMDEVICE);
 		np->rx_ring[i].status = RXOWN;
 		np->rx_ring[i].control |= RXIC;
@@ -1737,11 +1737,11 @@
 
 #if ! defined(__alpha__)
 				eth_copy_and_sum(skb, 
-					np->cur_rx->skbuff->tail, pkt_len, 0);
+					np->cur_rx->skbuff->data, pkt_len, 0);
 				skb_put(skb, pkt_len);
 #else
 				memcpy(skb_put(skb, pkt_len),
-					np->cur_rx->skbuff->tail, pkt_len);
+					np->cur_rx->skbuff->data, pkt_len);
 #endif
 				pci_dma_sync_single_for_device(np->pci_dev,
 							       np->cur_rx->buffer,
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index 3d96714..d9df1d9 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -1149,7 +1149,7 @@
 		skb->dev = dev;         /* Mark as being used by this device. */
 		skb_reserve(skb, 2); /* 16 byte align the IP header. */
                 hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev, 
-			skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+			skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
 		hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn | 
 			DescEndPacket | DescIntr | (hmp->rx_buf_sz - 2));
 	}
@@ -1210,7 +1210,7 @@
 		skb->dev = dev;         /* Mark as being used by this device. */
 		skb_reserve(skb, 2); /* 16 byte align the IP header. */
                 hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev, 
-			skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+			skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
 		/* -2 because it doesn't REALLY have that first 2 bytes -KDU */
 		hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn | 
 			DescEndPacket | DescIntr | (hmp->rx_buf_sz -2));
@@ -1509,7 +1509,7 @@
 					    desc->addr,
 					    hmp->rx_buf_sz,
 					    PCI_DMA_FROMDEVICE);
-		buf_addr = (u8 *) hmp->rx_skbuff[entry]->tail;
+		buf_addr = (u8 *) hmp->rx_skbuff[entry]->data;
 		frame_status = le32_to_cpu(get_unaligned((s32*)&(buf_addr[data_size - 12])));
 		if (hamachi_debug > 4)
 			printk(KERN_DEBUG "  hamachi_rx() status was %8.8x.\n",
@@ -1678,7 +1678,7 @@
 			skb->dev = dev;		/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
                 	desc->addr = cpu_to_leXX(pci_map_single(hmp->pci_dev, 
-				skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+				skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
 		}
 		desc->status_n_length = cpu_to_le32(hmp->rx_buf_sz);
 		if (entry >= RX_RING_SIZE-1)
@@ -1772,9 +1772,9 @@
 				   readl(ioaddr + RxCurPtr) == (long)&hmp->rx_ring[i] ? '>' : ' ',
 				   i, hmp->rx_ring[i].status_n_length, hmp->rx_ring[i].addr);
 			if (hamachi_debug > 6) {
-				if (*(u8*)hmp->rx_skbuff[i]->tail != 0x69) {
+				if (*(u8*)hmp->rx_skbuff[i]->data != 0x69) {
 					u16 *addr = (u16 *)
-						hmp->rx_skbuff[i]->tail;
+						hmp->rx_skbuff[i]->data;
 					int j;
 
 					for (j = 0; j < 0x50; j++)
diff --git a/drivers/net/lance.c b/drivers/net/lance.c
index ca90f0d..b4929be 100644
--- a/drivers/net/lance.c
+++ b/drivers/net/lance.c
@@ -862,7 +862,7 @@
 		lp->rx_skbuff[i] = skb;
 		if (skb) {
 			skb->dev = dev;
-			rx_buff = skb->tail;
+			rx_buff = skb->data;
 		} else
 			rx_buff = kmalloc(PKT_BUF_SZ, GFP_DMA | gfp);
 		if (rx_buff == NULL)
diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c
index 5e263fc..41bad07 100644
--- a/drivers/net/lasi_82596.c
+++ b/drivers/net/lasi_82596.c
@@ -553,14 +553,14 @@
 		if (skb == NULL)
 			panic("%s: alloc_skb() failed", __FILE__);
 		skb_reserve(skb, 2);
-		dma_addr = dma_map_single(lp->dev, skb->tail,PKT_BUF_SZ,
+		dma_addr = dma_map_single(lp->dev, skb->data,PKT_BUF_SZ,
 					  DMA_FROM_DEVICE);
 		skb->dev = dev;
 		rbd->v_next = rbd+1;
 		rbd->b_next = WSWAPrbd(virt_to_dma(lp,rbd+1));
 		rbd->b_addr = WSWAPrbd(virt_to_dma(lp,rbd));
 		rbd->skb = skb;
-		rbd->v_data = skb->tail;
+		rbd->v_data = skb->data;
 		rbd->b_data = WSWAPchar(dma_addr);
 		rbd->size = PKT_BUF_SZ;
 	}
@@ -783,8 +783,8 @@
 				rx_in_place = 1;
 				rbd->skb = newskb;
 				newskb->dev = dev;
-				dma_addr = dma_map_single(lp->dev, newskb->tail, PKT_BUF_SZ, DMA_FROM_DEVICE);
-				rbd->v_data = newskb->tail;
+				dma_addr = dma_map_single(lp->dev, newskb->data, PKT_BUF_SZ, DMA_FROM_DEVICE);
+				rbd->v_data = newskb->data;
 				rbd->b_data = WSWAPchar(dma_addr);
 				CHECK_WBACK_INV(rbd, sizeof(struct i596_rbd));
 			}
diff --git a/drivers/net/mace.c b/drivers/net/mace.c
index 6ed2d7d..81d0a26 100644
--- a/drivers/net/mace.c
+++ b/drivers/net/mace.c
@@ -109,7 +109,7 @@
 }
 
 
-static int __devinit mace_probe(struct macio_dev *mdev, const struct of_match *match)
+static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_id *match)
 {
 	struct device_node *mace = macio_get_of_node(mdev);
 	struct net_device *dev;
@@ -1009,12 +1009,10 @@
     return IRQ_HANDLED;
 }
 
-static struct of_match mace_match[] = 
+static struct of_device_id mace_match[] = 
 {
 	{
 	.name 		= "mace",
-	.type		= OF_ANY_MATCH,
-	.compatible	= OF_ANY_MATCH
 	},
 	{},
 };
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index babb59e..9d6d254 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -1926,7 +1926,7 @@
 				break; /* Better luck next round. */
 			skb->dev = dev; /* Mark as being used by this device. */
 			np->rx_dma[entry] = pci_map_single(np->pci_dev,
-				skb->tail, buflen, PCI_DMA_FROMDEVICE);
+				skb->data, buflen, PCI_DMA_FROMDEVICE);
 			np->rx_ring[entry].addr = cpu_to_le32(np->rx_dma[entry]);
 		}
 		np->rx_ring[entry].cmd_status = cpu_to_le32(np->rx_buf_sz);
@@ -2280,7 +2280,7 @@
 					buflen,
 					PCI_DMA_FROMDEVICE);
 				eth_copy_and_sum(skb,
-					np->rx_skbuff[entry]->tail, pkt_len, 0);
+					np->rx_skbuff[entry]->data, pkt_len, 0);
 				skb_put(skb, pkt_len);
 				pci_dma_sync_single_for_device(np->pci_dev,
 					np->rx_dma[entry],
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index cc796527..e64df4d 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -574,7 +574,7 @@
 
 	dev->rx_info.next_empty = (next_empty + 1) % NR_RX_DESC;
 	cmdsts = REAL_RX_BUF_SIZE | CMDSTS_INTR;
-	buf = pci_map_single(dev->pci_dev, skb->tail,
+	buf = pci_map_single(dev->pci_dev, skb->data,
 			     REAL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
 	build_rx_desc(dev, sg, 0, buf, cmdsts, 0);
 	/* update link of previous rx */
@@ -604,7 +604,7 @@
 		if (unlikely(!skb))
 			break;
 
-		res = (long)skb->tail & 0xf;
+		res = (long)skb->data & 0xf;
 		res = 0x10 - res;
 		res &= 0xf;
 		skb_reserve(skb, res);
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 3213f3e..113b680 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -1602,7 +1602,7 @@
 
 	rmb();
 	if (lp->rx_dma_addr[i] == 0)
-	    lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->tail,
+	    lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->data,
 		    PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE);
 	lp->rx_ring[i].base = (u32)le32_to_cpu(lp->rx_dma_addr[i]);
 	lp->rx_ring[i].buf_length = le16_to_cpu(2-PKT_BUF_SZ);
@@ -1983,7 +1983,7 @@
 			lp->rx_skbuff[entry] = newskb;
 			newskb->dev = dev;
 			lp->rx_dma_addr[entry] =
-			    pci_map_single(lp->pci_dev, newskb->tail,
+			    pci_map_single(lp->pci_dev, newskb->data,
 				    PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE);
 			lp->rx_ring[entry].base = le32_to_cpu(lp->rx_dma_addr[entry]);
 			rx_in_place = 1;
@@ -2020,7 +2020,7 @@
 						PKT_BUF_SZ-2,
 						PCI_DMA_FROMDEVICE);
 		    eth_copy_and_sum(skb,
-			    (unsigned char *)(lp->rx_skbuff[entry]->tail),
+			    (unsigned char *)(lp->rx_skbuff[entry]->data),
 			    pkt_len,0);
 		    pci_dma_sync_single_for_device(lp->pci_dev,
 						   lp->rx_dma_addr[entry],
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index ce449fe..d5afe05 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1876,7 +1876,7 @@
 	skb_reserve(skb, NET_IP_ALIGN);
 	*sk_buff = skb;
 
-	mapping = pci_map_single(pdev, skb->tail, rx_buf_sz,
+	mapping = pci_map_single(pdev, skb->data, rx_buf_sz,
 				 PCI_DMA_FROMDEVICE);
 
 	rtl8169_map_to_asic(desc, mapping, rx_buf_sz);
@@ -2336,7 +2336,7 @@
 		skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
 		if (skb) {
 			skb_reserve(skb, NET_IP_ALIGN);
-			eth_copy_and_sum(skb, sk_buff[0]->tail, pkt_size, 0);
+			eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0);
 			*sk_buff = skb;
 			rtl8169_mark_to_asic(desc, rx_buf_sz);
 			ret = 0;
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index bb639a8..ea638b1 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -1699,11 +1699,9 @@
 #else
 		ba = &nic->ba[ring_no][block_no][off];
 		skb_reserve(skb, BUF0_LEN);
-		tmp = (unsigned long) skb->data;
-		tmp += ALIGN_SIZE;
-		tmp &= ~ALIGN_SIZE;
-		skb->data = (void *) tmp;
-		skb->tail = (void *) tmp;
+		tmp = ((unsigned long) skb->data & ALIGN_SIZE);
+		if (tmp)
+			skb_reserve(skb, (ALIGN_SIZE + 1) - tmp);
 
 		memset(rxdp, 0, sizeof(RxD_t));
 		rxdp->Buffer2_ptr = pci_map_single
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index fd2e7c3..7abd55a 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -963,11 +963,11 @@
 	/*
 	 * Do not interrupt per DMA transfer.
 	 */
-	dsc->dscr_a = virt_to_phys(sb_new->tail) |
+	dsc->dscr_a = virt_to_phys(sb_new->data) |
 		V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
 		0;
 #else
-	dsc->dscr_a = virt_to_phys(sb_new->tail) |
+	dsc->dscr_a = virt_to_phys(sb_new->data) |
 		V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
 		M_DMA_DSCRA_INTERRUPT;
 #endif
diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c
index 20edeb3..3ad0b67 100644
--- a/drivers/net/shaper.c
+++ b/drivers/net/shaper.c
@@ -135,10 +135,8 @@
 {
 	struct shaper *shaper = dev->priv;
  	struct sk_buff *ptr;
-   
-	if (down_trylock(&shaper->sem))
-		return -1;
-
+  
+	spin_lock(&shaper->lock);
  	ptr=shaper->sendq.prev;
  	
  	/*
@@ -232,7 +230,7 @@
                 shaper->stats.collisions++;
  	}
 	shaper_kick(shaper);
-	up(&shaper->sem);
+	spin_unlock(&shaper->lock);
  	return 0;
 }
 
@@ -271,11 +269,9 @@
 {
 	struct shaper *shaper = (struct shaper *)data;
 
-	if (!down_trylock(&shaper->sem)) {
-		shaper_kick(shaper);
-		up(&shaper->sem);
-	} else
-		mod_timer(&shaper->timer, jiffies);
+	spin_lock(&shaper->lock);
+	shaper_kick(shaper);
+	spin_unlock(&shaper->lock);
 }
 
 /*
@@ -332,21 +328,6 @@
 
 
 /*
- *	Flush the shaper queues on a closedown
- */
- 
-static void shaper_flush(struct shaper *shaper)
-{
-	struct sk_buff *skb;
-
-	down(&shaper->sem);
-	while((skb=skb_dequeue(&shaper->sendq))!=NULL)
-		dev_kfree_skb(skb);
-	shaper_kick(shaper);
-	up(&shaper->sem);
-}
-
-/*
  *	Bring the interface up. We just disallow this until a 
  *	bind.
  */
@@ -375,7 +356,15 @@
 static int shaper_close(struct net_device *dev)
 {
 	struct shaper *shaper=dev->priv;
-	shaper_flush(shaper);
+	struct sk_buff *skb;
+
+	while ((skb = skb_dequeue(&shaper->sendq)) != NULL)
+		dev_kfree_skb(skb);
+
+	spin_lock_bh(&shaper->lock);
+	shaper_kick(shaper);
+	spin_unlock_bh(&shaper->lock);
+
 	del_timer_sync(&shaper->timer);
 	return 0;
 }
@@ -576,6 +565,7 @@
 	init_timer(&sh->timer);
 	sh->timer.function=shaper_timer;
 	sh->timer.data=(unsigned long)sh;
+	spin_lock_init(&sh->lock);
 }
 
 /*
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index 127324f..23b713c 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -1154,7 +1154,7 @@
 		sis_priv->rx_skbuff[i] = skb;
 		sis_priv->rx_ring[i].cmdsts = RX_BUF_SIZE;
                 sis_priv->rx_ring[i].bufptr = pci_map_single(sis_priv->pci_dev,
-                        skb->tail, RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+                        skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
 	}
 	sis_priv->dirty_rx = (unsigned int) (i - NUM_RX_DESC);
 
@@ -1776,7 +1776,7 @@
 			sis_priv->rx_skbuff[entry] = skb;
 			sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
                 	sis_priv->rx_ring[entry].bufptr = 
-				pci_map_single(sis_priv->pci_dev, skb->tail, 
+				pci_map_single(sis_priv->pci_dev, skb->data, 
 					RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
 			sis_priv->dirty_rx++;
 		}
@@ -1809,7 +1809,7 @@
 			sis_priv->rx_skbuff[entry] = skb;
 			sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
                 	sis_priv->rx_ring[entry].bufptr =
-				pci_map_single(sis_priv->pci_dev, skb->tail,
+				pci_map_single(sis_priv->pci_dev, skb->data,
 					RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
 		}
 	}
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 30e8d58..3dbb1cb 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -7,7 +7,7 @@
  * of the original driver such as link fail-over and link management because
  * those should be done at higher levels.
  *
- * Copyright (C) 2004, Stephen Hemminger <shemminger@osdl.org>
+ * Copyright (C) 2004, 2005 Stephen Hemminger <shemminger@osdl.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -42,19 +42,20 @@
 #include "skge.h"
 
 #define DRV_NAME		"skge"
-#define DRV_VERSION		"0.6"
+#define DRV_VERSION		"0.7"
 #define PFX			DRV_NAME " "
 
 #define DEFAULT_TX_RING_SIZE	128
 #define DEFAULT_RX_RING_SIZE	512
 #define MAX_TX_RING_SIZE	1024
 #define MAX_RX_RING_SIZE	4096
+#define RX_COPY_THRESHOLD	128
+#define RX_BUF_SIZE		1536
 #define PHY_RETRIES	        1000
 #define ETH_JUMBO_MTU		9000
 #define TX_WATCHDOG		(5 * HZ)
 #define NAPI_WEIGHT		64
 #define BLINK_HZ		(HZ/4)
-#define LINK_POLL_HZ		(HZ/10)
 
 MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver");
 MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>");
@@ -70,28 +71,17 @@
 MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
 
 static const struct pci_device_id skge_id_table[] = {
-	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940,
-	  PCI_ANY_ID, PCI_ANY_ID },
-	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940B,
-	  PCI_ANY_ID, PCI_ANY_ID },
-	{ PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE,
-	  PCI_ANY_ID, PCI_ANY_ID },
-	{ PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU,
-	  PCI_ANY_ID, PCI_ANY_ID },
-	{ PCI_VENDOR_ID_SYSKONNECT, 0x9E00, /* SK-9Exx  */
-	  PCI_ANY_ID, PCI_ANY_ID },
-	{ PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T,
-	  PCI_ANY_ID, PCI_ANY_ID },
-	{ PCI_VENDOR_ID_MARVELL, 0x4320, /* Gigabit Ethernet Controller */
-	  PCI_ANY_ID, PCI_ANY_ID },
-	{ PCI_VENDOR_ID_MARVELL, 0x5005, /* Marvell (11ab), Belkin */
-	  PCI_ANY_ID, PCI_ANY_ID },
-	{ PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD,
-	  PCI_ANY_ID, PCI_ANY_ID },
-	{ PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1032,
-	  PCI_ANY_ID, PCI_ANY_ID },
-	{ PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1064,
-	  PCI_ANY_ID, PCI_ANY_ID },
+	{ PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940B) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx  */
+	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T), },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */
+	{ PCI_DEVICE(PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1032) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1064) },
 	{ 0 }
 };
 MODULE_DEVICE_TABLE(pci, skge_id_table);
@@ -99,19 +89,22 @@
 static int skge_up(struct net_device *dev);
 static int skge_down(struct net_device *dev);
 static void skge_tx_clean(struct skge_port *skge);
-static void skge_xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
-static void skge_gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
+static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
+static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
 static void genesis_get_stats(struct skge_port *skge, u64 *data);
 static void yukon_get_stats(struct skge_port *skge, u64 *data);
 static void yukon_init(struct skge_hw *hw, int port);
 static void yukon_reset(struct skge_hw *hw, int port);
 static void genesis_mac_init(struct skge_hw *hw, int port);
 static void genesis_reset(struct skge_hw *hw, int port);
+static void genesis_link_up(struct skge_port *skge);
 
+/* Avoid conditionals by using array */
 static const int txqaddr[] = { Q_XA1, Q_XA2 };
 static const int rxqaddr[] = { Q_R1, Q_R2 };
 static const u32 rxirqmask[] = { IS_R1_F, IS_R2_F };
 static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F };
+static const u32 portirqmask[] = { IS_PORT_1, IS_PORT_2 };
 
 /* Don't need to look at whole 16K.
  * last interesting register is descriptor poll timer.
@@ -154,7 +147,7 @@
 static int wol_supported(const struct skge_hw *hw)
 {
 	return !((hw->chip_id == CHIP_ID_GENESIS ||
-		  (hw->chip_id == CHIP_ID_YUKON && chip_rev(hw) == 0)));
+		  (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0)));
 }
 
 static void skge_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
@@ -170,7 +163,7 @@
 	struct skge_port *skge = netdev_priv(dev);
 	struct skge_hw *hw = skge->hw;
 
-	if(wol->wolopts != WAKE_MAGIC && wol->wolopts != 0)
+	if (wol->wolopts != WAKE_MAGIC && wol->wolopts != 0)
 		return -EOPNOTSUPP;
 
 	if (wol->wolopts == WAKE_MAGIC && !wol_supported(hw))
@@ -190,6 +183,36 @@
 	return 0;
 }
 
+/* Determine supported/adverised modes based on hardware.
+ * Note: ethtoool ADVERTISED_xxx == SUPPORTED_xxx
+ */
+static u32 skge_supported_modes(const struct skge_hw *hw)
+{
+	u32 supported;
+
+	if (iscopper(hw)) {
+		supported = SUPPORTED_10baseT_Half
+			| SUPPORTED_10baseT_Full
+			| SUPPORTED_100baseT_Half
+			| SUPPORTED_100baseT_Full
+			| SUPPORTED_1000baseT_Half
+			| SUPPORTED_1000baseT_Full
+			| SUPPORTED_Autoneg| SUPPORTED_TP;
+
+		if (hw->chip_id == CHIP_ID_GENESIS)
+			supported &= ~(SUPPORTED_10baseT_Half
+					     | SUPPORTED_10baseT_Full
+					     | SUPPORTED_100baseT_Half
+					     | SUPPORTED_100baseT_Full);
+
+		else if (hw->chip_id == CHIP_ID_YUKON)
+			supported &= ~SUPPORTED_1000baseT_Half;
+	} else
+		supported = SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE
+			| SUPPORTED_Autoneg;
+
+	return supported;
+}
 
 static int skge_get_settings(struct net_device *dev,
 			     struct ethtool_cmd *ecmd)
@@ -198,38 +221,13 @@
 	struct skge_hw *hw = skge->hw;
 
 	ecmd->transceiver = XCVR_INTERNAL;
+	ecmd->supported = skge_supported_modes(hw);
 
 	if (iscopper(hw)) {
-		if (hw->chip_id == CHIP_ID_GENESIS)
-			ecmd->supported = SUPPORTED_1000baseT_Full
-				| SUPPORTED_1000baseT_Half
-				| SUPPORTED_Autoneg | SUPPORTED_TP;
-		else {
-			ecmd->supported = SUPPORTED_10baseT_Half
-				| SUPPORTED_10baseT_Full
-				| SUPPORTED_100baseT_Half
-				| SUPPORTED_100baseT_Full
-				| SUPPORTED_1000baseT_Half
-				| SUPPORTED_1000baseT_Full
-				| SUPPORTED_Autoneg| SUPPORTED_TP;
-
-			if (hw->chip_id == CHIP_ID_YUKON)
-				ecmd->supported &= ~SUPPORTED_1000baseT_Half;
-
-			else if (hw->chip_id == CHIP_ID_YUKON_FE)
-				ecmd->supported &= ~(SUPPORTED_1000baseT_Half
-						     | SUPPORTED_1000baseT_Full);
-		}
-
 		ecmd->port = PORT_TP;
 		ecmd->phy_address = hw->phy_addr;
-	} else {
-		ecmd->supported = SUPPORTED_1000baseT_Full
-			| SUPPORTED_FIBRE
-			| SUPPORTED_Autoneg;
-
+	} else
 		ecmd->port = PORT_FIBRE;
-	}
 
 	ecmd->advertising = skge->advertising;
 	ecmd->autoneg = skge->autoneg;
@@ -238,65 +236,57 @@
 	return 0;
 }
 
-static u32 skge_modes(const struct skge_hw *hw)
-{
-	u32 modes = ADVERTISED_Autoneg
-		| ADVERTISED_1000baseT_Full | ADVERTISED_1000baseT_Half
-		| ADVERTISED_100baseT_Full | ADVERTISED_100baseT_Half
-		| ADVERTISED_10baseT_Full | ADVERTISED_10baseT_Half;
-
-	if (iscopper(hw)) {
-		modes |= ADVERTISED_TP;
-		switch(hw->chip_id) {
-		case CHIP_ID_GENESIS:
-			modes &= ~(ADVERTISED_100baseT_Full
-				   | ADVERTISED_100baseT_Half
-				   | ADVERTISED_10baseT_Full
-				   | ADVERTISED_10baseT_Half);
-			break;
-
-		case CHIP_ID_YUKON:
-			modes &= ~ADVERTISED_1000baseT_Half;
-			break;
-
-		case CHIP_ID_YUKON_FE:
-			modes &= ~(ADVERTISED_1000baseT_Half|ADVERTISED_1000baseT_Full);
-			break;
-		}
-	} else {
-		modes |= ADVERTISED_FIBRE;
-		modes &= ~ADVERTISED_1000baseT_Half;
-	}
-	return modes;
-}
-
 static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
 	struct skge_port *skge = netdev_priv(dev);
 	const struct skge_hw *hw = skge->hw;
+	u32 supported = skge_supported_modes(hw);
 
 	if (ecmd->autoneg == AUTONEG_ENABLE) {
-		if (ecmd->advertising & skge_modes(hw))
-			return -EINVAL;
+		ecmd->advertising = supported;
+		skge->duplex = -1;
+		skge->speed = -1;
 	} else {
+		u32 setting;
+
 		switch(ecmd->speed) {
 		case SPEED_1000:
-			if (hw->chip_id == CHIP_ID_YUKON_FE)
+			if (ecmd->duplex == DUPLEX_FULL)
+				setting = SUPPORTED_1000baseT_Full;
+			else if (ecmd->duplex == DUPLEX_HALF)
+				setting = SUPPORTED_1000baseT_Half;
+			else
 				return -EINVAL;
 			break;
 		case SPEED_100:
+			if (ecmd->duplex == DUPLEX_FULL)
+				setting = SUPPORTED_100baseT_Full;
+			else if (ecmd->duplex == DUPLEX_HALF)
+				setting = SUPPORTED_100baseT_Half;
+			else
+				return -EINVAL;
+			break;
+
 		case SPEED_10:
-			if (iscopper(hw) || hw->chip_id == CHIP_ID_GENESIS)
+			if (ecmd->duplex == DUPLEX_FULL)
+				setting = SUPPORTED_10baseT_Full;
+			else if (ecmd->duplex == DUPLEX_HALF)
+				setting = SUPPORTED_10baseT_Half;
+			else
 				return -EINVAL;
 			break;
 		default:
 			return -EINVAL;
 		}
+
+		if ((setting & supported) == 0)
+			return -EINVAL;
+
+		skge->speed = ecmd->speed;
+		skge->duplex = ecmd->duplex;
 	}
 
 	skge->autoneg = ecmd->autoneg;
-	skge->speed = ecmd->speed;
-	skge->duplex = ecmd->duplex;
 	skge->advertising = ecmd->advertising;
 
 	if (netif_running(dev)) {
@@ -393,7 +383,7 @@
 {
 	int i;
 
-	switch(stringset) {
+	switch (stringset) {
 	case ETH_SS_STATS:
 		for (i = 0; i < ARRAY_SIZE(skge_stats); i++)
 			memcpy(data + i * ETH_GSTRING_LEN,
@@ -511,14 +501,6 @@
 	return 0;
 }
 
-/* Only Yukon II supports TSO (not implemented yet) */
-static int skge_set_tso(struct net_device *dev, u32 data)
-{
-	if (data)
-		return -EOPNOTSUPP;
-	return 0;
-}
-
 static void skge_get_pauseparam(struct net_device *dev,
 				struct ethtool_pauseparam *ecmd)
 {
@@ -540,9 +522,9 @@
 	skge->autoneg = ecmd->autoneg;
 	if (ecmd->rx_pause && ecmd->tx_pause)
 		skge->flow_control = FLOW_MODE_SYMMETRIC;
-	else if(ecmd->rx_pause && !ecmd->tx_pause)
+	else if (ecmd->rx_pause && !ecmd->tx_pause)
 		skge->flow_control = FLOW_MODE_REM_SEND;
-	else if(!ecmd->rx_pause && ecmd->tx_pause)
+	else if (!ecmd->rx_pause && ecmd->tx_pause)
 		skge->flow_control = FLOW_MODE_LOC_SEND;
 	else
 		skge->flow_control = FLOW_MODE_NONE;
@@ -559,8 +541,6 @@
 {
 	if (hw->chip_id == CHIP_ID_GENESIS)
 		return 53215; /* or:  53.125 MHz */
-	else if (hw->chip_id == CHIP_ID_YUKON_EC)
-		return 125000; /* or: 125.000 MHz */
 	else
 		return 78215; /* or:  78.125 MHz */
 }
@@ -643,30 +623,18 @@
 static void skge_led_on(struct skge_hw *hw, int port)
 {
 	if (hw->chip_id == CHIP_ID_GENESIS) {
-		skge_write8(hw, SKGEMAC_REG(port, LNK_LED_REG), LINKLED_ON);
+		skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON);
 		skge_write8(hw, B0_LED, LED_STAT_ON);
 
-		skge_write8(hw, SKGEMAC_REG(port, RX_LED_TST), LED_T_ON);
-		skge_write32(hw, SKGEMAC_REG(port, RX_LED_VAL), 100);
-		skge_write8(hw, SKGEMAC_REG(port, RX_LED_CTRL), LED_START);
+		skge_write8(hw, SK_REG(port, RX_LED_TST), LED_T_ON);
+		skge_write32(hw, SK_REG(port, RX_LED_VAL), 100);
+		skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START);
 
-		switch (hw->phy_type) {
-		case SK_PHY_BCOM:
-			skge_xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL,
-					  PHY_B_PEC_LED_ON);
-			break;
-		case SK_PHY_LONE:
-			skge_xm_phy_write(hw, port, PHY_LONE_LED_CFG,
-					  0x0800);
-			break;
-		default:
-			skge_write8(hw, SKGEMAC_REG(port, TX_LED_TST), LED_T_ON);
-			skge_write32(hw, SKGEMAC_REG(port, TX_LED_VAL), 100);
-			skge_write8(hw, SKGEMAC_REG(port, TX_LED_CTRL), LED_START);
-		}
+		/* For Broadcom Phy only */
+		xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON);
 	} else {
-		skge_gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
-		skge_gm_phy_write(hw, port, PHY_MARV_LED_OVER,
+		gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
+		gm_phy_write(hw, port, PHY_MARV_LED_OVER,
 				  PHY_M_LED_MO_DUP(MO_LED_ON)  |
 				  PHY_M_LED_MO_10(MO_LED_ON)   |
 				  PHY_M_LED_MO_100(MO_LED_ON)  |
@@ -678,28 +646,17 @@
 static void skge_led_off(struct skge_hw *hw, int port)
 {
 	if (hw->chip_id == CHIP_ID_GENESIS) {
-		skge_write8(hw, SKGEMAC_REG(port, LNK_LED_REG), LINKLED_OFF);
+		skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
 		skge_write8(hw, B0_LED, LED_STAT_OFF);
 
-		skge_write32(hw, SKGEMAC_REG(port, RX_LED_VAL), 0);
-		skge_write8(hw, SKGEMAC_REG(port, RX_LED_CTRL), LED_T_OFF);
+		skge_write32(hw, SK_REG(port, RX_LED_VAL), 0);
+		skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF);
 
-		switch (hw->phy_type) {
-		case SK_PHY_BCOM:
-			skge_xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL,
-					  PHY_B_PEC_LED_OFF);
-			break;
-		case SK_PHY_LONE:
-			skge_xm_phy_write(hw, port, PHY_LONE_LED_CFG,
-					  PHY_L_LC_LEDT);
-			break;
-		default:
-			skge_write32(hw, SKGEMAC_REG(port, TX_LED_VAL), 0);
-			skge_write8(hw, SKGEMAC_REG(port, TX_LED_CTRL), LED_T_OFF);
-		}
+		/* Broadcom only */
+		xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF);
 	} else {
-		skge_gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
-		skge_gm_phy_write(hw, port, PHY_MARV_LED_OVER,
+		gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
+		gm_phy_write(hw, port, PHY_MARV_LED_OVER,
 				  PHY_M_LED_MO_DUP(MO_LED_OFF)  |
 				  PHY_M_LED_MO_10(MO_LED_OFF)   |
 				  PHY_M_LED_MO_100(MO_LED_OFF)  |
@@ -730,7 +687,7 @@
 {
 	struct skge_port *skge = netdev_priv(dev);
 
-	if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
+	if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
 		data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
 
 	/* start blinking */
@@ -763,8 +720,6 @@
 	.set_pauseparam = skge_set_pauseparam,
 	.get_coalesce	= skge_get_coalesce,
 	.set_coalesce	= skge_set_coalesce,
-	.get_tso	= ethtool_op_get_tso,
-	.set_tso	= skge_set_tso,
 	.get_sg		= ethtool_op_get_sg,
 	.set_sg		= skge_set_sg,
 	.get_tx_csum	= ethtool_op_get_tx_csum,
@@ -793,6 +748,7 @@
 
 	for (i = 0, e = ring->start, d = vaddr; i < ring->count; i++, e++, d++) {
 		e->desc = d;
+		e->skb = NULL;
 		if (i == ring->count - 1) {
 			e->next = ring->start;
 			d->next_offset = base;
@@ -806,24 +762,23 @@
 	return 0;
 }
 
-/* Setup buffer for receiving */
-static inline int skge_rx_alloc(struct skge_port *skge,
-				struct skge_element *e)
+static struct sk_buff *skge_rx_alloc(struct net_device *dev, unsigned int size)
 {
-	unsigned long bufsize = skge->netdev->mtu + ETH_HLEN; /* VLAN? */
-	struct skge_rx_desc *rd = e->desc;
-	struct sk_buff *skb;
-	u64 map;
+	struct sk_buff *skb = dev_alloc_skb(size);
 
-	skb = dev_alloc_skb(bufsize + NET_IP_ALIGN);
-	if (unlikely(!skb)) {
-		printk(KERN_DEBUG PFX "%s: out of memory for receive\n",
-		       skge->netdev->name);
-		return -ENOMEM;
+	if (likely(skb)) {
+		skb->dev = dev;
+		skb_reserve(skb, NET_IP_ALIGN);
 	}
+	return skb;
+}
 
-	skb->dev = skge->netdev;
-	skb_reserve(skb, NET_IP_ALIGN);
+/* Allocate and setup a new buffer for receiving */
+static void skge_rx_setup(struct skge_port *skge, struct skge_element *e,
+			  struct sk_buff *skb, unsigned int bufsize)
+{
+	struct skge_rx_desc *rd = e->desc;
+	u64 map;
 
 	map = pci_map_single(skge->hw->pdev, skb->data, bufsize,
 			     PCI_DMA_FROMDEVICE);
@@ -841,55 +796,69 @@
 	rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | bufsize;
 	pci_unmap_addr_set(e, mapaddr, map);
 	pci_unmap_len_set(e, maplen, bufsize);
-	return 0;
 }
 
-/* Free all unused buffers in receive ring, assumes receiver stopped */
+/* Resume receiving using existing skb,
+ * Note: DMA address is not changed by chip.
+ * 	 MTU not changed while receiver active.
+ */
+static void skge_rx_reuse(struct skge_element *e, unsigned int size)
+{
+	struct skge_rx_desc *rd = e->desc;
+
+	rd->csum2 = 0;
+	rd->csum2_start = ETH_HLEN;
+
+	wmb();
+
+	rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | size;
+}
+
+
+/* Free all  buffers in receive ring, assumes receiver stopped */
 static void skge_rx_clean(struct skge_port *skge)
 {
 	struct skge_hw *hw = skge->hw;
 	struct skge_ring *ring = &skge->rx_ring;
 	struct skge_element *e;
 
-	for (e = ring->to_clean; e != ring->to_use; e = e->next) {
+	e = ring->start;
+	do {
 		struct skge_rx_desc *rd = e->desc;
 		rd->control = 0;
-
-		pci_unmap_single(hw->pdev,
-				 pci_unmap_addr(e, mapaddr),
-				 pci_unmap_len(e, maplen),
-				 PCI_DMA_FROMDEVICE);
-		dev_kfree_skb(e->skb);
-		e->skb = NULL;
-	}
-	ring->to_clean = e;
+		if (e->skb) {
+			pci_unmap_single(hw->pdev,
+					 pci_unmap_addr(e, mapaddr),
+					 pci_unmap_len(e, maplen),
+					 PCI_DMA_FROMDEVICE);
+			dev_kfree_skb(e->skb);
+			e->skb = NULL;
+		}
+	} while ((e = e->next) != ring->start);
 }
 
+
 /* Allocate buffers for receive ring
- * For receive: to_use   is refill location
- *              to_clean is next received frame.
- *
- * if (to_use == to_clean)
- *	 then ring all frames in ring need buffers
- * if (to_use->next == to_clean)
- *	 then ring all frames in ring have buffers
+ * For receive:  to_clean is next received frame.
  */
 static int skge_rx_fill(struct skge_port *skge)
 {
 	struct skge_ring *ring = &skge->rx_ring;
 	struct skge_element *e;
-	int ret = 0;
+	unsigned int bufsize = skge->rx_buf_size;
 
-	for (e = ring->to_use; e->next != ring->to_clean; e = e->next) {
-		if (skge_rx_alloc(skge, e)) {
-			ret = 1;
-			break;
-		}
+	e = ring->start;
+	do {
+		struct sk_buff *skb = skge_rx_alloc(skge->netdev, bufsize);
 
-	}
-	ring->to_use = e;
+		if (!skb)
+			return -ENOMEM;
 
-	return ret;
+		skge_rx_setup(skge, e, skb, bufsize);
+	} while ( (e = e->next) != ring->start);
+
+	ring->to_clean = ring->start;
+	return 0;
 }
 
 static void skge_link_up(struct skge_port *skge)
@@ -919,50 +888,50 @@
 		printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name);
 }
 
-static u16 skge_xm_phy_read(struct skge_hw *hw, int port,  u16 reg)
+static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg)
 {
 	int i;
 	u16 v;
 
-	skge_xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
-	v = skge_xm_read16(hw, port, XM_PHY_DATA);
-	if (hw->phy_type != SK_PHY_XMAC) {
-		for (i = 0; i < PHY_RETRIES; i++) {
-			udelay(1);
-			if (skge_xm_read16(hw, port, XM_MMU_CMD)
-			    & XM_MMU_PHY_RDY)
-				goto ready;
-		}
+	xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
+	v = xm_read16(hw, port, XM_PHY_DATA);
 
-		printk(KERN_WARNING PFX "%s: phy read timed out\n",
-		       hw->dev[port]->name);
-		return 0;
-	ready:
-		v = skge_xm_read16(hw, port, XM_PHY_DATA);
+	/* Need to wait for external PHY */
+	for (i = 0; i < PHY_RETRIES; i++) {
+		udelay(1);
+		if (xm_read16(hw, port, XM_MMU_CMD)
+		    & XM_MMU_PHY_RDY)
+			goto ready;
 	}
 
+	printk(KERN_WARNING PFX "%s: phy read timed out\n",
+	       hw->dev[port]->name);
+	return 0;
+ ready:
+	v = xm_read16(hw, port, XM_PHY_DATA);
+
 	return v;
 }
 
-static void skge_xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
+static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
 {
 	int i;
 
-	skge_xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
+	xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
 	for (i = 0; i < PHY_RETRIES; i++) {
-		if (!(skge_xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
+		if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
 			goto ready;
-		cpu_relax();
+		udelay(1);
 	}
 	printk(KERN_WARNING PFX "%s: phy write failed to come ready\n",
 	       hw->dev[port]->name);
 
 
  ready:
-	skge_xm_write16(hw, port, XM_PHY_DATA, val);
+	xm_write16(hw, port, XM_PHY_DATA, val);
 	for (i = 0; i < PHY_RETRIES; i++) {
 		udelay(1);
-		if (!(skge_xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
+		if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
 			return;
 	}
 	printk(KERN_WARNING PFX "%s: phy write timed out\n",
@@ -999,34 +968,112 @@
 
 static void genesis_reset(struct skge_hw *hw, int port)
 {
-	int i;
-	u64 zero = 0;
+	const u8 zero[8]  = { 0 };
 
 	/* reset the statistics module */
-	skge_xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT);
-	skge_xm_write16(hw, port, XM_IMSK, 0xffff);	/* disable XMAC IRQs */
-	skge_xm_write32(hw, port, XM_MODE, 0);		/* clear Mode Reg */
-	skge_xm_write16(hw, port, XM_TX_CMD, 0);	/* reset TX CMD Reg */
-	skge_xm_write16(hw, port, XM_RX_CMD, 0);	/* reset RX CMD Reg */
+	xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT);
+	xm_write16(hw, port, XM_IMSK, 0xffff);	/* disable XMAC IRQs */
+	xm_write32(hw, port, XM_MODE, 0);		/* clear Mode Reg */
+	xm_write16(hw, port, XM_TX_CMD, 0);	/* reset TX CMD Reg */
+	xm_write16(hw, port, XM_RX_CMD, 0);	/* reset RX CMD Reg */
 
-	/* disable all PHY IRQs */
-	if  (hw->phy_type == SK_PHY_BCOM)
-		skge_xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff);
+	/* disable Broadcom PHY IRQ */
+	xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff);
 
-	skge_xm_outhash(hw, port, XM_HSM, (u8 *) &zero);
-	for (i = 0; i < 15; i++)
-		skge_xm_outaddr(hw, port, XM_EXM(i), (u8 *) &zero);
-	skge_xm_outhash(hw, port, XM_SRC_CHK, (u8 *) &zero);
+	xm_outhash(hw, port, XM_HSM, zero);
 }
 
 
-static void genesis_mac_init(struct skge_hw *hw, int port)
+/* Convert mode to MII values  */
+static const u16 phy_pause_map[] = {
+	[FLOW_MODE_NONE] =	0,
+	[FLOW_MODE_LOC_SEND] =	PHY_AN_PAUSE_ASYM,
+	[FLOW_MODE_SYMMETRIC] = PHY_AN_PAUSE_CAP,
+	[FLOW_MODE_REM_SEND]  = PHY_AN_PAUSE_CAP | PHY_AN_PAUSE_ASYM,
+};
+
+
+/* Check status of Broadcom phy link */
+static void bcom_check_link(struct skge_hw *hw, int port)
 {
-	struct skge_port *skge = netdev_priv(hw->dev[port]);
+	struct net_device *dev = hw->dev[port];
+	struct skge_port *skge = netdev_priv(dev);
+	u16 status;
+
+	/* read twice because of latch */
+	(void) xm_phy_read(hw, port, PHY_BCOM_STAT);
+	status = xm_phy_read(hw, port, PHY_BCOM_STAT);
+
+	pr_debug("bcom_check_link status=0x%x\n", status);
+
+	if ((status & PHY_ST_LSYNC) == 0) {
+		u16 cmd = xm_read16(hw, port, XM_MMU_CMD);
+		cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
+		xm_write16(hw, port, XM_MMU_CMD, cmd);
+		/* dummy read to ensure writing */
+		(void) xm_read16(hw, port, XM_MMU_CMD);
+
+		if (netif_carrier_ok(dev))
+			skge_link_down(skge);
+	} else {
+		if (skge->autoneg == AUTONEG_ENABLE &&
+		    (status & PHY_ST_AN_OVER)) {
+			u16 lpa = xm_phy_read(hw, port, PHY_BCOM_AUNE_LP);
+			u16 aux = xm_phy_read(hw, port, PHY_BCOM_AUX_STAT);
+
+			if (lpa & PHY_B_AN_RF) {
+				printk(KERN_NOTICE PFX "%s: remote fault\n",
+				       dev->name);
+				return;
+			}
+
+			/* Check Duplex mismatch */
+			switch(aux & PHY_B_AS_AN_RES_MSK) {
+			case PHY_B_RES_1000FD:
+				skge->duplex = DUPLEX_FULL;
+				break;
+			case PHY_B_RES_1000HD:
+				skge->duplex = DUPLEX_HALF;
+				break;
+			default:
+				printk(KERN_NOTICE PFX "%s: duplex mismatch\n",
+				       dev->name);
+				return;
+			}
+
+
+			/* We are using IEEE 802.3z/D5.0 Table 37-4 */
+			switch (aux & PHY_B_AS_PAUSE_MSK) {
+			case PHY_B_AS_PAUSE_MSK:
+				skge->flow_control = FLOW_MODE_SYMMETRIC;
+				break;
+			case PHY_B_AS_PRR:
+				skge->flow_control = FLOW_MODE_REM_SEND;
+				break;
+			case PHY_B_AS_PRT:
+				skge->flow_control = FLOW_MODE_LOC_SEND;
+				break;
+			default:
+				skge->flow_control = FLOW_MODE_NONE;
+			}
+
+			skge->speed = SPEED_1000;
+		}
+
+		if (!netif_carrier_ok(dev))
+			genesis_link_up(skge);
+	}
+}
+
+/* Broadcom 5400 only supports giagabit! SysKonnect did not put an additional
+ * Phy on for 100 or 10Mbit operation
+ */
+static void bcom_phy_init(struct skge_port *skge, int jumbo)
+{
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
 	int i;
-	u32 r;
-	u16 id1;
-	u16 ctrl1, ctrl2, ctrl3, ctrl4, ctrl5;
+	u16 id1, r, ext, ctl;
 
 	/* magic workaround patterns for Broadcom */
 	static const struct {
@@ -1042,16 +1089,120 @@
 		{ 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 },
 	};
 
+	pr_debug("bcom_phy_init\n");
+
+	/* read Id from external PHY (all have the same address) */
+	id1 = xm_phy_read(hw, port, PHY_XMAC_ID1);
+
+	/* Optimize MDIO transfer by suppressing preamble. */
+	r = xm_read16(hw, port, XM_MMU_CMD);
+	r |=  XM_MMU_NO_PRE;
+	xm_write16(hw, port, XM_MMU_CMD,r);
+
+	switch(id1) {
+	case PHY_BCOM_ID1_C0:
+		/*
+		 * Workaround BCOM Errata for the C0 type.
+		 * Write magic patterns to reserved registers.
+		 */
+		for (i = 0; i < ARRAY_SIZE(C0hack); i++)
+			xm_phy_write(hw, port,
+				     C0hack[i].reg, C0hack[i].val);
+
+		break;
+	case PHY_BCOM_ID1_A1:
+		/*
+		 * Workaround BCOM Errata for the A1 type.
+		 * Write magic patterns to reserved registers.
+		 */
+		for (i = 0; i < ARRAY_SIZE(A1hack); i++)
+			xm_phy_write(hw, port,
+				     A1hack[i].reg, A1hack[i].val);
+		break;
+	}
+
+	/*
+	 * Workaround BCOM Errata (#10523) for all BCom PHYs.
+	 * Disable Power Management after reset.
+	 */
+	r = xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL);
+	r |= PHY_B_AC_DIS_PM;
+	xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r);
+
+	/* Dummy read */
+	xm_read16(hw, port, XM_ISRC);
+
+	ext = PHY_B_PEC_EN_LTR; /* enable tx led */
+	ctl = PHY_CT_SP1000;	/* always 1000mbit */
+
+	if (skge->autoneg == AUTONEG_ENABLE) {
+		/*
+		 * Workaround BCOM Errata #1 for the C5 type.
+		 * 1000Base-T Link Acquisition Failure in Slave Mode
+		 * Set Repeater/DTE bit 10 of the 1000Base-T Control Register
+		 */
+		u16 adv = PHY_B_1000C_RD;
+		if (skge->advertising & ADVERTISED_1000baseT_Half)
+			adv |= PHY_B_1000C_AHD;
+		if (skge->advertising & ADVERTISED_1000baseT_Full)
+			adv |= PHY_B_1000C_AFD;
+		xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, adv);
+
+		ctl |= PHY_CT_ANE | PHY_CT_RE_CFG;
+	} else {
+		if (skge->duplex == DUPLEX_FULL)
+			ctl |= PHY_CT_DUP_MD;
+		/* Force to slave */
+		xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, PHY_B_1000C_MSE);
+	}
+
+	/* Set autonegotiation pause parameters */
+	xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV,
+		     phy_pause_map[skge->flow_control] | PHY_AN_CSMA);
+
+	/* Handle Jumbo frames */
+	if (jumbo) {
+		xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL,
+			     PHY_B_AC_TX_TST | PHY_B_AC_LONG_PACK);
+
+		ext |= PHY_B_PEC_HIGH_LA;
+
+	}
+
+	xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext);
+	xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl);
+
+	/* Use link status change interrrupt */
+	xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
+
+	bcom_check_link(hw, port);
+}
+
+static void genesis_mac_init(struct skge_hw *hw, int port)
+{
+	struct net_device *dev = hw->dev[port];
+	struct skge_port *skge = netdev_priv(dev);
+	int jumbo = hw->dev[port]->mtu > ETH_DATA_LEN;
+	int i;
+	u32 r;
+	const u8 zero[6]  = { 0 };
+
+	/* Clear MIB counters */
+	xm_write16(hw, port, XM_STAT_CMD,
+			XM_SC_CLR_RXC | XM_SC_CLR_TXC);
+	/* Clear two times according to Errata #3 */
+	xm_write16(hw, port, XM_STAT_CMD,
+			XM_SC_CLR_RXC | XM_SC_CLR_TXC);
 
 	/* initialize Rx, Tx and Link LED */
-	skge_write8(hw, SKGEMAC_REG(port, LNK_LED_REG), LINKLED_ON);
-	skge_write8(hw, SKGEMAC_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON);
+	skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON);
+	skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON);
 
-	skge_write8(hw, SKGEMAC_REG(port, RX_LED_CTRL), LED_START);
-	skge_write8(hw, SKGEMAC_REG(port, TX_LED_CTRL), LED_START);
+	skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START);
+	skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START);
 
 	/* Unreset the XMAC. */
-	skge_write16(hw, SKGEMAC_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
+	skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
 
 	/*
 	 * Perform additional initialization for external PHYs,
@@ -1059,67 +1210,56 @@
 	 * GMII mode.
 	 */
 	spin_lock_bh(&hw->phy_lock);
-	if (hw->phy_type != SK_PHY_XMAC) {
-		/* Take PHY out of reset. */
-		r = skge_read32(hw, B2_GP_IO);
-		if (port == 0)
-			r |= GP_DIR_0|GP_IO_0;
-		else
-			r |= GP_DIR_2|GP_IO_2;
+	/* Take external Phy out of reset */
+	r = skge_read32(hw, B2_GP_IO);
+	if (port == 0)
+		r |= GP_DIR_0|GP_IO_0;
+	else
+		r |= GP_DIR_2|GP_IO_2;
 
-		skge_write32(hw, B2_GP_IO, r);
-		skge_read32(hw, B2_GP_IO);
+	skge_write32(hw, B2_GP_IO, r);
+	skge_read32(hw, B2_GP_IO);
+	spin_unlock_bh(&hw->phy_lock);
 
-		/* Enable GMII mode on the XMAC. */
-		skge_xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
+	/* Enable GMII interfac */
+	xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
 
-		id1 = skge_xm_phy_read(hw, port, PHY_XMAC_ID1);
+	bcom_phy_init(skge, jumbo);
 
-		/* Optimize MDIO transfer by suppressing preamble. */
-		skge_xm_write16(hw, port, XM_MMU_CMD,
-				skge_xm_read16(hw, port, XM_MMU_CMD)
-				| XM_MMU_NO_PRE);
+	/* Set Station Address */
+	xm_outaddr(hw, port, XM_SA, dev->dev_addr);
 
-		if (id1 == PHY_BCOM_ID1_C0) {
-			/*
-			 * Workaround BCOM Errata for the C0 type.
-			 * Write magic patterns to reserved registers.
-			 */
-			for (i = 0; i < ARRAY_SIZE(C0hack); i++)
-				skge_xm_phy_write(hw, port,
-					  C0hack[i].reg, C0hack[i].val);
+	/* We don't use match addresses so clear */
+	for (i = 1; i < 16; i++)
+		xm_outaddr(hw, port, XM_EXM(i), zero);
 
-		} else if (id1 == PHY_BCOM_ID1_A1) {
-			/*
-			 * Workaround BCOM Errata for the A1 type.
-			 * Write magic patterns to reserved registers.
-			 */
-			for (i = 0; i < ARRAY_SIZE(A1hack); i++)
-				skge_xm_phy_write(hw, port,
-					  A1hack[i].reg, A1hack[i].val);
-		}
-
-		/*
-		 * Workaround BCOM Errata (#10523) for all BCom PHYs.
-		 * Disable Power Management after reset.
-		 */
-		r = skge_xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL);
-		skge_xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r | PHY_B_AC_DIS_PM);
-	}
-
-	/* Dummy read */
-	skge_xm_read16(hw, port, XM_ISRC);
-
-	r = skge_xm_read32(hw, port, XM_MODE);
-	skge_xm_write32(hw, port, XM_MODE, r|XM_MD_CSA);
+	/* configure Rx High Water Mark (XM_RX_HI_WM) */
+	xm_write16(hw, port, XM_RX_HI_WM, 1450);
 
 	/* We don't need the FCS appended to the packet. */
-	r = skge_xm_read16(hw, port, XM_RX_CMD);
-	skge_xm_write16(hw, port, XM_RX_CMD, r | XM_RX_STRIP_FCS);
+	r = XM_RX_LENERR_OK | XM_RX_STRIP_FCS;
+	if (jumbo)
+		r |= XM_RX_BIG_PK_OK;
+
+	if (skge->duplex == DUPLEX_HALF) {
+		/*
+		 * If in manual half duplex mode the other side might be in
+		 * full duplex mode, so ignore if a carrier extension is not seen
+		 * on frames received
+		 */
+		r |= XM_RX_DIS_CEXT;
+	}
+	xm_write16(hw, port, XM_RX_CMD, r);
+
 
 	/* We want short frames padded to 60 bytes. */
-	r = skge_xm_read16(hw, port, XM_TX_CMD);
-	skge_xm_write16(hw, port, XM_TX_CMD, r | XM_TX_AUTO_PAD);
+	xm_write16(hw, port, XM_TX_CMD, XM_TX_AUTO_PAD);
+
+	/*
+	 * Bump up the transmit threshold. This helps hold off transmit
+	 * underruns when we're blasting traffic from both ports at once.
+	 */
+	xm_write16(hw, port, XM_TX_THR, 512);
 
 	/*
 	 * Enable the reception of all error frames. This is is
@@ -1135,19 +1275,22 @@
 	 * case the XMAC will start transfering frames out of the
 	 * RX FIFO as soon as the FIFO threshold is reached.
 	 */
-	r = skge_xm_read32(hw, port, XM_MODE);
-	skge_xm_write32(hw, port, XM_MODE,
-		     XM_MD_RX_CRCE|XM_MD_RX_LONG|XM_MD_RX_RUNT|
-		     XM_MD_RX_ERR|XM_MD_RX_IRLE);
+	xm_write32(hw, port, XM_MODE, XM_DEF_MODE);
 
-	skge_xm_outaddr(hw, port, XM_SA, hw->dev[port]->dev_addr);
-	skge_xm_outaddr(hw, port, XM_EXM(0), hw->dev[port]->dev_addr);
 
 	/*
-	 * Bump up the transmit threshold. This helps hold off transmit
-	 * underruns when we're blasting traffic from both ports at once.
+	 * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK)
+	 *	- Enable all bits excepting 'Octets Rx OK Low CntOv'
+	 *	  and 'Octets Rx OK Hi Cnt Ov'.
 	 */
-	skge_xm_write16(hw, port, XM_TX_THR, 512);
+	xm_write32(hw, port, XM_RX_EV_MSK, XMR_DEF_MSK);
+
+	/*
+	 * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK)
+	 *	- Enable all bits excepting 'Octets Tx OK Low CntOv'
+	 *	  and 'Octets Tx OK Hi Cnt Ov'.
+	 */
+	xm_write32(hw, port, XM_TX_EV_MSK, XMT_DEF_MSK);
 
 	/* Configure MAC arbiter */
 	skge_write16(hw, B3_MA_TO_CTRL, MA_RST_CLR);
@@ -1164,137 +1307,30 @@
 	skge_write8(hw, B3_MA_RCINI_TX2, 0);
 
 	/* Configure Rx MAC FIFO */
-	skge_write8(hw, SKGEMAC_REG(port, RX_MFF_CTRL2), MFF_RST_CLR);
-	skge_write16(hw, SKGEMAC_REG(port, RX_MFF_CTRL1), MFF_ENA_TIM_PAT);
-	skge_write8(hw, SKGEMAC_REG(port, RX_MFF_CTRL2), MFF_ENA_OP_MD);
+	skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_CLR);
+	skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_ENA_TIM_PAT);
+	skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_ENA_OP_MD);
 
 	/* Configure Tx MAC FIFO */
-	skge_write8(hw, SKGEMAC_REG(port, TX_MFF_CTRL2), MFF_RST_CLR);
-	skge_write16(hw, SKGEMAC_REG(port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF);
-	skge_write8(hw, SKGEMAC_REG(port, TX_MFF_CTRL2), MFF_ENA_OP_MD);
+	skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_CLR);
+	skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF);
+	skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_ENA_OP_MD);
 
-	if (hw->dev[port]->mtu > ETH_DATA_LEN) {
+	if (jumbo) {
 		/* Enable frame flushing if jumbo frames used */
-		skge_write16(hw, SKGEMAC_REG(port,RX_MFF_CTRL1), MFF_ENA_FLUSH);
+		skge_write16(hw, SK_REG(port,RX_MFF_CTRL1), MFF_ENA_FLUSH);
 	} else {
 		/* enable timeout timers if normal frames */
 		skge_write16(hw, B3_PA_CTRL,
-			     port == 0 ? PA_ENA_TO_TX1 : PA_ENA_TO_TX2);
+			     (port == 0) ? PA_ENA_TO_TX1 : PA_ENA_TO_TX2);
 	}
-
-
-	r = skge_xm_read16(hw, port, XM_RX_CMD);
-	if (hw->dev[port]->mtu > ETH_DATA_LEN)
-		skge_xm_write16(hw, port, XM_RX_CMD, r | XM_RX_BIG_PK_OK);
-	else
-		skge_xm_write16(hw, port, XM_RX_CMD, r & ~(XM_RX_BIG_PK_OK));
-
-	switch (hw->phy_type) {
-	case SK_PHY_XMAC:
-		if (skge->autoneg == AUTONEG_ENABLE) {
-			ctrl1 = PHY_X_AN_FD | PHY_X_AN_HD;
-
-			switch (skge->flow_control) {
-			case FLOW_MODE_NONE:
-				ctrl1 |= PHY_X_P_NO_PAUSE;
-				break;
-			case FLOW_MODE_LOC_SEND:
-				ctrl1 |= PHY_X_P_ASYM_MD;
-				break;
-			case FLOW_MODE_SYMMETRIC:
-				ctrl1 |= PHY_X_P_SYM_MD;
-				break;
-			case FLOW_MODE_REM_SEND:
-				ctrl1 |= PHY_X_P_BOTH_MD;
-				break;
-			}
-
-			skge_xm_phy_write(hw, port, PHY_XMAC_AUNE_ADV, ctrl1);
-			ctrl2 = PHY_CT_ANE | PHY_CT_RE_CFG;
-		} else {
-			ctrl2 = 0;
-			if (skge->duplex == DUPLEX_FULL)
-				ctrl2 |= PHY_CT_DUP_MD;
-		}
-
-		skge_xm_phy_write(hw, port, PHY_XMAC_CTRL, ctrl2);
-		break;
-
-	case SK_PHY_BCOM:
-		ctrl1 = PHY_CT_SP1000;
-		ctrl2 = 0;
-		ctrl3 = PHY_SEL_TYPE;
-		ctrl4 = PHY_B_PEC_EN_LTR;
-		ctrl5 = PHY_B_AC_TX_TST;
-
-		if (skge->autoneg == AUTONEG_ENABLE) {
-			/*
-			 * Workaround BCOM Errata #1 for the C5 type.
-			 * 1000Base-T Link Acquisition Failure in Slave Mode
-			 * Set Repeater/DTE bit 10 of the 1000Base-T Control Register
-			 */
-			ctrl2 |= PHY_B_1000C_RD;
-			if (skge->advertising & ADVERTISED_1000baseT_Half)
-				ctrl2 |= PHY_B_1000C_AHD;
-			if (skge->advertising & ADVERTISED_1000baseT_Full)
-				ctrl2 |= PHY_B_1000C_AFD;
-
-			/* Set Flow-control capabilities */
-			switch (skge->flow_control) {
-			case FLOW_MODE_NONE:
-				ctrl3 |= PHY_B_P_NO_PAUSE;
-				break;
-			case FLOW_MODE_LOC_SEND:
-				ctrl3 |= PHY_B_P_ASYM_MD;
-				break;
-			case FLOW_MODE_SYMMETRIC:
-				ctrl3 |= PHY_B_P_SYM_MD;
-				break;
-			case FLOW_MODE_REM_SEND:
-				ctrl3 |= PHY_B_P_BOTH_MD;
-				break;
-			}
-
-			/* Restart Auto-negotiation */
-			ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG;
-		} else {
-			if (skge->duplex == DUPLEX_FULL)
-				ctrl1 |= PHY_CT_DUP_MD;
-
-			ctrl2 |= PHY_B_1000C_MSE;	/* set it to Slave */
-		}
-
-		skge_xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, ctrl2);
-		skge_xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV, ctrl3);
-
-		if (skge->netdev->mtu > ETH_DATA_LEN) {
-			ctrl4 |= PHY_B_PEC_HIGH_LA;
-			ctrl5 |= PHY_B_AC_LONG_PACK;
-
-			skge_xm_phy_write(hw, port,PHY_BCOM_AUX_CTRL, ctrl5);
-		}
-
-		skge_xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ctrl4);
-		skge_xm_phy_write(hw, port, PHY_BCOM_CTRL, ctrl1);
-		break;
-	}
-	spin_unlock_bh(&hw->phy_lock);
-
-	/* Clear MIB counters */
-	skge_xm_write16(hw, port, XM_STAT_CMD,
-			XM_SC_CLR_RXC | XM_SC_CLR_TXC);
-	/* Clear two times according to Errata #3 */
-	skge_xm_write16(hw, port, XM_STAT_CMD,
-			XM_SC_CLR_RXC | XM_SC_CLR_TXC);
-
-	/* Start polling for link status */
-	mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ);
 }
 
 static void genesis_stop(struct skge_port *skge)
 {
 	struct skge_hw *hw = skge->hw;
 	int port = skge->port;
+	u32 reg;
 
 	/* Clear Tx packet arbiter timeout IRQ */
 	skge_write16(hw, B3_PA_CTRL,
@@ -1304,33 +1340,30 @@
 	 * If the transfer stucks at the MAC the STOP command will not
 	 * terminate if we don't flush the XMAC's transmit FIFO !
 	 */
-	skge_xm_write32(hw, port, XM_MODE,
-			skge_xm_read32(hw, port, XM_MODE)|XM_MD_FTF);
+	xm_write32(hw, port, XM_MODE,
+			xm_read32(hw, port, XM_MODE)|XM_MD_FTF);
 
 
 	/* Reset the MAC */
-	skge_write16(hw, SKGEMAC_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
+	skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
 
 	/* For external PHYs there must be special handling */
-	if (hw->phy_type != SK_PHY_XMAC) {
-		u32 reg = skge_read32(hw, B2_GP_IO);
-
-		if (port == 0) {
-			reg |= GP_DIR_0;
-			reg &= ~GP_IO_0;
-		} else {
-			reg |= GP_DIR_2;
-			reg &= ~GP_IO_2;
-		}
-		skge_write32(hw, B2_GP_IO, reg);
-		skge_read32(hw, B2_GP_IO);
+	reg = skge_read32(hw, B2_GP_IO);
+	if (port == 0) {
+		reg |= GP_DIR_0;
+		reg &= ~GP_IO_0;
+	} else {
+		reg |= GP_DIR_2;
+		reg &= ~GP_IO_2;
 	}
+	skge_write32(hw, B2_GP_IO, reg);
+	skge_read32(hw, B2_GP_IO);
 
-	skge_xm_write16(hw, port, XM_MMU_CMD,
-			skge_xm_read16(hw, port, XM_MMU_CMD)
+	xm_write16(hw, port, XM_MMU_CMD,
+			xm_read16(hw, port, XM_MMU_CMD)
 			& ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));
 
-	skge_xm_read16(hw, port, XM_MMU_CMD);
+	xm_read16(hw, port, XM_MMU_CMD);
 }
 
 
@@ -1341,11 +1374,11 @@
 	int i;
 	unsigned long timeout = jiffies + HZ;
 
-	skge_xm_write16(hw, port,
+	xm_write16(hw, port,
 			XM_STAT_CMD, XM_SC_SNP_TXC | XM_SC_SNP_RXC);
 
 	/* wait for update to complete */
-	while (skge_xm_read16(hw, port, XM_STAT_CMD)
+	while (xm_read16(hw, port, XM_STAT_CMD)
 	       & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) {
 		if (time_after(jiffies, timeout))
 			break;
@@ -1353,68 +1386,60 @@
 	}
 
 	/* special case for 64 bit octet counter */
-	data[0] = (u64) skge_xm_read32(hw, port, XM_TXO_OK_HI) << 32
-		| skge_xm_read32(hw, port, XM_TXO_OK_LO);
-	data[1] = (u64) skge_xm_read32(hw, port, XM_RXO_OK_HI) << 32
-		| skge_xm_read32(hw, port, XM_RXO_OK_LO);
+	data[0] = (u64) xm_read32(hw, port, XM_TXO_OK_HI) << 32
+		| xm_read32(hw, port, XM_TXO_OK_LO);
+	data[1] = (u64) xm_read32(hw, port, XM_RXO_OK_HI) << 32
+		| xm_read32(hw, port, XM_RXO_OK_LO);
 
 	for (i = 2; i < ARRAY_SIZE(skge_stats); i++)
-		data[i] = skge_xm_read32(hw, port, skge_stats[i].xmac_offset);
+		data[i] = xm_read32(hw, port, skge_stats[i].xmac_offset);
 }
 
 static void genesis_mac_intr(struct skge_hw *hw, int port)
 {
 	struct skge_port *skge = netdev_priv(hw->dev[port]);
-	u16 status = skge_xm_read16(hw, port, XM_ISRC);
+	u16 status = xm_read16(hw, port, XM_ISRC);
 
-	pr_debug("genesis_intr status %x\n", status);
-	if (hw->phy_type == SK_PHY_XMAC) {
-		/* LInk down, start polling for state change */
-		if (status & XM_IS_INP_ASS) {
-			skge_xm_write16(hw, port, XM_IMSK,
-					skge_xm_read16(hw, port, XM_IMSK) | XM_IS_INP_ASS);
-			mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ);
-		}
-		else if (status & XM_IS_AND)
-			mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ);
-	}
+	if (netif_msg_intr(skge))
+		printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n",
+		       skge->netdev->name, status);
 
 	if (status & XM_IS_TXF_UR) {
-		skge_xm_write32(hw, port, XM_MODE, XM_MD_FTF);
+		xm_write32(hw, port, XM_MODE, XM_MD_FTF);
 		++skge->net_stats.tx_fifo_errors;
 	}
 	if (status & XM_IS_RXF_OV) {
-		skge_xm_write32(hw, port, XM_MODE, XM_MD_FRF);
+		xm_write32(hw, port, XM_MODE, XM_MD_FRF);
 		++skge->net_stats.rx_fifo_errors;
 	}
 }
 
-static void skge_gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
+static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
 {
 	int i;
 
-	skge_gma_write16(hw, port, GM_SMI_DATA, val);
-	skge_gma_write16(hw, port, GM_SMI_CTRL,
+	gma_write16(hw, port, GM_SMI_DATA, val);
+	gma_write16(hw, port, GM_SMI_CTRL,
 			 GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg));
 	for (i = 0; i < PHY_RETRIES; i++) {
 		udelay(1);
 
-		if (!(skge_gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
+		if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
 			break;
 	}
 }
 
-static u16 skge_gm_phy_read(struct skge_hw *hw, int port, u16 reg)
+static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
 {
 	int i;
 
-	skge_gma_write16(hw, port, GM_SMI_CTRL,
+	gma_write16(hw, port, GM_SMI_CTRL,
 			 GM_SMI_CT_PHY_AD(hw->phy_addr)
 			 | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
 
 	for (i = 0; i < PHY_RETRIES; i++) {
 		udelay(1);
-		if (skge_gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
+		if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
 			goto ready;
 	}
 
@@ -1422,24 +1447,7 @@
 	       hw->dev[port]->name);
 	return 0;
  ready:
-	return skge_gma_read16(hw, port, GM_SMI_DATA);
-}
-
-static void genesis_link_down(struct skge_port *skge)
-{
-	struct skge_hw *hw = skge->hw;
-	int port = skge->port;
-
-	pr_debug("genesis_link_down\n");
-
-	skge_xm_write16(hw, port, XM_MMU_CMD,
-			skge_xm_read16(hw, port, XM_MMU_CMD)
-			& ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));
-
-	/* dummy read to ensure writing */
-	(void) skge_xm_read16(hw, port, XM_MMU_CMD);
-
-	skge_link_down(skge);
+	return gma_read16(hw, port, GM_SMI_DATA);
 }
 
 static void genesis_link_up(struct skge_port *skge)
@@ -1450,7 +1458,7 @@
 	u32 mode, msk;
 
 	pr_debug("genesis_link_up\n");
-	cmd = skge_xm_read16(hw, port, XM_MMU_CMD);
+	cmd = xm_read16(hw, port, XM_MMU_CMD);
 
 	/*
 	 * enabling pause frame reception is required for 1000BT
@@ -1458,14 +1466,15 @@
 	 */
 	if (skge->flow_control == FLOW_MODE_NONE ||
 	    skge->flow_control == FLOW_MODE_LOC_SEND)
+		/* Disable Pause Frame Reception */
 		cmd |= XM_MMU_IGN_PF;
 	else
 		/* Enable Pause Frame Reception */
 		cmd &= ~XM_MMU_IGN_PF;
 
-	skge_xm_write16(hw, port, XM_MMU_CMD, cmd);
+	xm_write16(hw, port, XM_MMU_CMD, cmd);
 
-	mode = skge_xm_read32(hw, port, XM_MODE);
+	mode = xm_read32(hw, port, XM_MODE);
 	if (skge->flow_control == FLOW_MODE_SYMMETRIC ||
 	    skge->flow_control == FLOW_MODE_LOC_SEND) {
 		/*
@@ -1479,10 +1488,10 @@
 		/* XM_PAUSE_DA = '010000C28001' (default) */
 		/* XM_MAC_PTIME = 0xffff (maximum) */
 		/* remember this value is defined in big endian (!) */
-		skge_xm_write16(hw, port, XM_MAC_PTIME, 0xffff);
+		xm_write16(hw, port, XM_MAC_PTIME, 0xffff);
 
 		mode |= XM_PAUSE_MODE;
-		skge_write16(hw, SKGEMAC_REG(port, RX_MFF_CTRL1), MFF_ENA_PAUSE);
+		skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_ENA_PAUSE);
 	} else {
 		/*
 		 * disable pause frame generation is required for 1000BT
@@ -1491,125 +1500,68 @@
 		/* Disable Pause Mode in Mode Register */
 		mode &= ~XM_PAUSE_MODE;
 
-		skge_write16(hw, SKGEMAC_REG(port, RX_MFF_CTRL1), MFF_DIS_PAUSE);
+		skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_DIS_PAUSE);
 	}
 
-	skge_xm_write32(hw, port, XM_MODE, mode);
+	xm_write32(hw, port, XM_MODE, mode);
 
 	msk = XM_DEF_MSK;
-	if (hw->phy_type != SK_PHY_XMAC)
-		msk |= XM_IS_INP_ASS;	/* disable GP0 interrupt bit */
+	/* disable GP0 interrupt bit for external Phy */
+	msk |= XM_IS_INP_ASS;
 
-	skge_xm_write16(hw, port, XM_IMSK, msk);
-	skge_xm_read16(hw, port, XM_ISRC);
+	xm_write16(hw, port, XM_IMSK, msk);
+	xm_read16(hw, port, XM_ISRC);
 
 	/* get MMU Command Reg. */
-	cmd = skge_xm_read16(hw, port, XM_MMU_CMD);
-	if (hw->phy_type != SK_PHY_XMAC && skge->duplex == DUPLEX_FULL)
+	cmd = xm_read16(hw, port, XM_MMU_CMD);
+	if (skge->duplex == DUPLEX_FULL)
 		cmd |= XM_MMU_GMII_FD;
 
-	if (hw->phy_type == SK_PHY_BCOM) {
-		/*
-		 * Workaround BCOM Errata (#10523) for all BCom Phys
-		 * Enable Power Management after link up
-		 */
-		skge_xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL,
-				  skge_xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL)
-				  & ~PHY_B_AC_DIS_PM);
-		skge_xm_phy_write(hw, port, PHY_BCOM_INT_MASK,
-				  PHY_B_DEF_MSK);
-	}
+	/*
+	 * Workaround BCOM Errata (#10523) for all BCom Phys
+	 * Enable Power Management after link up
+	 */
+	xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL,
+		     xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL)
+		     & ~PHY_B_AC_DIS_PM);
+	xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
 
 	/* enable Rx/Tx */
-	skge_xm_write16(hw, port, XM_MMU_CMD,
+	xm_write16(hw, port, XM_MMU_CMD,
 			cmd | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
 	skge_link_up(skge);
 }
 
 
-static void genesis_bcom_intr(struct skge_port *skge)
+static inline void bcom_phy_intr(struct skge_port *skge)
 {
 	struct skge_hw *hw = skge->hw;
 	int port = skge->port;
-	u16 stat = skge_xm_phy_read(hw, port, PHY_BCOM_INT_STAT);
+	u16 isrc;
 
-	pr_debug("genesis_bcom intr stat=%x\n", stat);
+	isrc = xm_phy_read(hw, port, PHY_BCOM_INT_STAT);
+	if (netif_msg_intr(skge))
+		printk(KERN_DEBUG PFX "%s: phy interrupt status 0x%x\n",
+		       skge->netdev->name, isrc);
+
+	if (isrc & PHY_B_IS_PSE)
+		printk(KERN_ERR PFX "%s: uncorrectable pair swap error\n",
+		       hw->dev[port]->name);
 
 	/* Workaround BCom Errata:
 	 *	enable and disable loopback mode if "NO HCD" occurs.
 	 */
-	if (stat & PHY_B_IS_NO_HDCL) {
-		u16 ctrl = skge_xm_phy_read(hw, port, PHY_BCOM_CTRL);
-		skge_xm_phy_write(hw, port, PHY_BCOM_CTRL,
+	if (isrc & PHY_B_IS_NO_HDCL) {
+		u16 ctrl = xm_phy_read(hw, port, PHY_BCOM_CTRL);
+		xm_phy_write(hw, port, PHY_BCOM_CTRL,
 				  ctrl | PHY_CT_LOOP);
-		skge_xm_phy_write(hw, port, PHY_BCOM_CTRL,
+		xm_phy_write(hw, port, PHY_BCOM_CTRL,
 				  ctrl & ~PHY_CT_LOOP);
 	}
 
-	stat = skge_xm_phy_read(hw, port, PHY_BCOM_STAT);
-	if (stat & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) {
-		u16 aux = skge_xm_phy_read(hw, port, PHY_BCOM_AUX_STAT);
-		if ( !(aux & PHY_B_AS_LS) && netif_carrier_ok(skge->netdev))
-			genesis_link_down(skge);
+	if (isrc & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE))
+		bcom_check_link(hw, port);
 
-		else if (stat & PHY_B_IS_LST_CHANGE) {
-			if (aux & PHY_B_AS_AN_C) {
-				switch (aux & PHY_B_AS_AN_RES_MSK) {
-				case PHY_B_RES_1000FD:
-					skge->duplex = DUPLEX_FULL;
-					break;
-				case PHY_B_RES_1000HD:
-					skge->duplex = DUPLEX_HALF;
-					break;
-				}
-
-				switch (aux & PHY_B_AS_PAUSE_MSK) {
-				case PHY_B_AS_PAUSE_MSK:
-					skge->flow_control = FLOW_MODE_SYMMETRIC;
-					break;
-				case PHY_B_AS_PRR:
-					skge->flow_control = FLOW_MODE_REM_SEND;
-					break;
-				case PHY_B_AS_PRT:
-					skge->flow_control = FLOW_MODE_LOC_SEND;
-					break;
-				default:
-					skge->flow_control = FLOW_MODE_NONE;
-				}
-				skge->speed = SPEED_1000;
-			}
-			genesis_link_up(skge);
-		}
-		else
-			mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ);
-	}
-}
-
-/* Perodic poll of phy status to check for link transistion  */
-static void skge_link_timer(unsigned long __arg)
-{
-	struct skge_port *skge = (struct skge_port *) __arg;
-	struct skge_hw *hw = skge->hw;
-	int port = skge->port;
-
-	if (hw->chip_id != CHIP_ID_GENESIS || !netif_running(skge->netdev))
-		return;
-
-	spin_lock_bh(&hw->phy_lock);
-	if (hw->phy_type == SK_PHY_BCOM)
-		genesis_bcom_intr(skge);
-	else {
-		int i;
-		for (i = 0; i < 3; i++)
-			if (skge_xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS)
-				break;
-
-		if (i == 3)
-			mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ);
-		else
-			genesis_link_up(skge);
-	}
-	spin_unlock_bh(&hw->phy_lock);
 }
 
 /* Marvell Phy Initailization */
@@ -1621,31 +1573,27 @@
 
 	pr_debug("yukon_init\n");
 	if (skge->autoneg == AUTONEG_ENABLE) {
-		u16 ectrl = skge_gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
+		u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
 
 		ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
 			  PHY_M_EC_MAC_S_MSK);
 		ectrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ);
 
-		/* on PHY 88E1111 there is a change for downshift control */
-		if (hw->chip_id == CHIP_ID_YUKON_EC)
-			ectrl |= PHY_M_EC_M_DSC_2(0) | PHY_M_EC_DOWN_S_ENA;
-		else
-			ectrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);
+		ectrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);
 
-		skge_gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl);
+		gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl);
 	}
 
-	ctrl = skge_gm_phy_read(hw, port, PHY_MARV_CTRL);
+	ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
 	if (skge->autoneg == AUTONEG_DISABLE)
 		ctrl &= ~PHY_CT_ANE;
 
 	ctrl |= PHY_CT_RESET;
-	skge_gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+	gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
 
 	ctrl = 0;
 	ct1000 = 0;
-	adv = PHY_SEL_TYPE;
+	adv = PHY_AN_CSMA;
 
 	if (skge->autoneg == AUTONEG_ENABLE) {
 		if (iscopper(hw)) {
@@ -1661,41 +1609,12 @@
 				adv |= PHY_M_AN_10_FD;
 			if (skge->advertising & ADVERTISED_10baseT_Half)
 				adv |= PHY_M_AN_10_HD;
-
-			/* Set Flow-control capabilities */
-			switch (skge->flow_control) {
-			case FLOW_MODE_NONE:
-				adv |= PHY_B_P_NO_PAUSE;
-				break;
-			case FLOW_MODE_LOC_SEND:
-				adv |= PHY_B_P_ASYM_MD;
-				break;
-			case FLOW_MODE_SYMMETRIC:
-				adv |= PHY_B_P_SYM_MD;
-				break;
-			case FLOW_MODE_REM_SEND:
-				adv |= PHY_B_P_BOTH_MD;
-				break;
-			}
-		} else {	/* special defines for FIBER (88E1011S only) */
+		} else	/* special defines for FIBER (88E1011S only) */
 			adv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD;
 
-			/* Set Flow-control capabilities */
-			switch (skge->flow_control) {
-			case FLOW_MODE_NONE:
-				adv |= PHY_M_P_NO_PAUSE_X;
-				break;
-			case FLOW_MODE_LOC_SEND:
-				adv |= PHY_M_P_ASYM_MD_X;
-				break;
-			case FLOW_MODE_SYMMETRIC:
-				adv |= PHY_M_P_SYM_MD_X;
-				break;
-			case FLOW_MODE_REM_SEND:
-				adv |= PHY_M_P_BOTH_MD_X;
-				break;
-			}
-		}
+		/* Set Flow-control capabilities */
+		adv |= phy_pause_map[skge->flow_control];
+
 		/* Restart Auto-negotiation */
 		ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
 	} else {
@@ -1717,36 +1636,23 @@
 		ctrl |= PHY_CT_RESET;
 	}
 
-	if (hw->chip_id != CHIP_ID_YUKON_FE)
-		skge_gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000);
+	gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000);
 
-	skge_gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv);
-	skge_gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+	gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv);
+	gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
 
 	/* Setup Phy LED's */
 	ledctrl = PHY_M_LED_PULS_DUR(PULS_170MS);
 	ledover = 0;
 
-	if (hw->chip_id == CHIP_ID_YUKON_FE) {
-		/* on 88E3082 these bits are at 11..9 (shifted left) */
-		ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) << 1;
+	ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL;
 
-		skge_gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR,
-				  ((skge_gm_phy_read(hw, port, PHY_MARV_FE_LED_PAR)
-
-				    & ~PHY_M_FELP_LED1_MSK)
-				   | PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_ACT_BL)));
-	} else {
-		/* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */
-		ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL;
-
-		/* turn off the Rx LED (LED_RX) */
-		ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
-	}
+	/* turn off the Rx LED (LED_RX) */
+	ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
 
 	/* disable blink mode (LED_DUPLEX) on collisions */
 	ctrl |= PHY_M_LEDC_DP_CTRL;
-	skge_gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
+	gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
 
 	if (skge->autoneg == AUTONEG_DISABLE || skge->speed == SPEED_100) {
 		/* turn on 100 Mbps LED (LED_LINK100) */
@@ -1754,25 +1660,25 @@
 	}
 
 	if (ledover)
-		skge_gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
+		gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
 
 	/* Enable phy interrupt on autonegotiation complete (or link up) */
 	if (skge->autoneg == AUTONEG_ENABLE)
-		skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL);
+		gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL);
 	else
-		skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
+		gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
 }
 
 static void yukon_reset(struct skge_hw *hw, int port)
 {
-	skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);/* disable PHY IRQs */
-	skge_gma_write16(hw, port, GM_MC_ADDR_H1, 0);	/* clear MC hash */
-	skge_gma_write16(hw, port, GM_MC_ADDR_H2, 0);
-	skge_gma_write16(hw, port, GM_MC_ADDR_H3, 0);
-	skge_gma_write16(hw, port, GM_MC_ADDR_H4, 0);
+	gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);/* disable PHY IRQs */
+	gma_write16(hw, port, GM_MC_ADDR_H1, 0);	/* clear MC hash */
+	gma_write16(hw, port, GM_MC_ADDR_H2, 0);
+	gma_write16(hw, port, GM_MC_ADDR_H3, 0);
+	gma_write16(hw, port, GM_MC_ADDR_H4, 0);
 
-	skge_gma_write16(hw, port, GM_RX_CTRL,
-			 skge_gma_read16(hw, port, GM_RX_CTRL)
+	gma_write16(hw, port, GM_RX_CTRL,
+			 gma_read16(hw, port, GM_RX_CTRL)
 			 | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
 }
 
@@ -1785,17 +1691,17 @@
 
 	/* WA code for COMA mode -- set PHY reset */
 	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
-	    chip_rev(hw) == CHIP_REV_YU_LITE_A3)
+	    hw->chip_rev == CHIP_REV_YU_LITE_A3)
 		skge_write32(hw, B2_GP_IO,
 			     (skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9));
 
 	/* hard reset */
-	skge_write32(hw, SKGEMAC_REG(port, GPHY_CTRL), GPC_RST_SET);
-	skge_write32(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_RST_SET);
+	skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
+	skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
 
 	/* WA code for COMA mode -- clear PHY reset */
 	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
-	    chip_rev(hw) == CHIP_REV_YU_LITE_A3)
+	    hw->chip_rev == CHIP_REV_YU_LITE_A3)
 		skge_write32(hw, B2_GP_IO,
 			     (skge_read32(hw, B2_GP_IO) | GP_DIR_9)
 			     & ~GP_IO_9);
@@ -1806,13 +1712,13 @@
 	reg |= iscopper(hw) ? GPC_HWCFG_GMII_COP : GPC_HWCFG_GMII_FIB;
 
 	/* Clear GMC reset */
-	skge_write32(hw, SKGEMAC_REG(port, GPHY_CTRL), reg | GPC_RST_SET);
-	skge_write32(hw, SKGEMAC_REG(port, GPHY_CTRL), reg | GPC_RST_CLR);
-	skge_write32(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
+	skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_SET);
+	skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_CLR);
+	skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
 	if (skge->autoneg == AUTONEG_DISABLE) {
 		reg = GM_GPCR_AU_ALL_DIS;
-		skge_gma_write16(hw, port, GM_GP_CTRL,
-				 skge_gma_read16(hw, port, GM_GP_CTRL) | reg);
+		gma_write16(hw, port, GM_GP_CTRL,
+				 gma_read16(hw, port, GM_GP_CTRL) | reg);
 
 		switch (skge->speed) {
 		case SPEED_1000:
@@ -1828,7 +1734,7 @@
 		reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL;
 	switch (skge->flow_control) {
 	case FLOW_MODE_NONE:
-		skge_write32(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
+		skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
 		reg |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
 		break;
 	case FLOW_MODE_LOC_SEND:
@@ -1836,7 +1742,7 @@
 		reg |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
 	}
 
-	skge_gma_write16(hw, port, GM_GP_CTRL, reg);
+	gma_write16(hw, port, GM_GP_CTRL, reg);
 	skge_read16(hw, GMAC_IRQ_SRC);
 
 	spin_lock_bh(&hw->phy_lock);
@@ -1844,25 +1750,25 @@
 	spin_unlock_bh(&hw->phy_lock);
 
 	/* MIB clear */
-	reg = skge_gma_read16(hw, port, GM_PHY_ADDR);
-	skge_gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR);
+	reg = gma_read16(hw, port, GM_PHY_ADDR);
+	gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR);
 
 	for (i = 0; i < GM_MIB_CNT_SIZE; i++)
-		skge_gma_read16(hw, port, GM_MIB_CNT_BASE + 8*i);
-	skge_gma_write16(hw, port, GM_PHY_ADDR, reg);
+		gma_read16(hw, port, GM_MIB_CNT_BASE + 8*i);
+	gma_write16(hw, port, GM_PHY_ADDR, reg);
 
 	/* transmit control */
-	skge_gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF));
+	gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF));
 
 	/* receive control reg: unicast + multicast + no FCS  */
-	skge_gma_write16(hw, port, GM_RX_CTRL,
+	gma_write16(hw, port, GM_RX_CTRL,
 			 GM_RXCR_UCF_ENA | GM_RXCR_CRC_DIS | GM_RXCR_MCF_ENA);
 
 	/* transmit flow control */
-	skge_gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff);
+	gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff);
 
 	/* transmit parameter */
-	skge_gma_write16(hw, port, GM_TX_PARAM,
+	gma_write16(hw, port, GM_TX_PARAM,
 			 TX_JAM_LEN_VAL(TX_JAM_LEN_DEF) |
 			 TX_JAM_IPG_VAL(TX_JAM_IPG_DEF) |
 			 TX_IPG_JAM_DATA(TX_IPG_JAM_DEF));
@@ -1872,33 +1778,33 @@
 	if (hw->dev[port]->mtu > 1500)
 		reg |= GM_SMOD_JUMBO_ENA;
 
-	skge_gma_write16(hw, port, GM_SERIAL_MODE, reg);
+	gma_write16(hw, port, GM_SERIAL_MODE, reg);
 
 	/* physical address: used for pause frames */
-	skge_gm_set_addr(hw, port, GM_SRC_ADDR_1L, addr);
+	gma_set_addr(hw, port, GM_SRC_ADDR_1L, addr);
 	/* virtual address for data */
-	skge_gm_set_addr(hw, port, GM_SRC_ADDR_2L, addr);
+	gma_set_addr(hw, port, GM_SRC_ADDR_2L, addr);
 
 	/* enable interrupt mask for counter overflows */
-	skge_gma_write16(hw, port, GM_TX_IRQ_MSK, 0);
-	skge_gma_write16(hw, port, GM_RX_IRQ_MSK, 0);
-	skge_gma_write16(hw, port, GM_TR_IRQ_MSK, 0);
+	gma_write16(hw, port, GM_TX_IRQ_MSK, 0);
+	gma_write16(hw, port, GM_RX_IRQ_MSK, 0);
+	gma_write16(hw, port, GM_TR_IRQ_MSK, 0);
 
 	/* Initialize Mac Fifo */
 
 	/* Configure Rx MAC FIFO */
-	skge_write16(hw, SKGEMAC_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK);
+	skge_write16(hw, SK_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK);
 	reg = GMF_OPER_ON | GMF_RX_F_FL_ON;
 	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
-	    chip_rev(hw) == CHIP_REV_YU_LITE_A3)
+	    hw->chip_rev == CHIP_REV_YU_LITE_A3)
 		reg &= ~GMF_RX_F_FL_ON;
-	skge_write8(hw, SKGEMAC_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
-	skge_write16(hw, SKGEMAC_REG(port, RX_GMF_CTRL_T), reg);
-	skge_write16(hw, SKGEMAC_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF);
+	skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
+	skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg);
+	skge_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF);
 
 	/* Configure Tx MAC FIFO */
-	skge_write8(hw, SKGEMAC_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR);
-	skge_write16(hw, SKGEMAC_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
+	skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR);
+	skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
 }
 
 static void yukon_stop(struct skge_port *skge)
@@ -1907,19 +1813,19 @@
 	int port = skge->port;
 
 	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
-	    chip_rev(hw) == CHIP_REV_YU_LITE_A3) {
+	    hw->chip_rev == CHIP_REV_YU_LITE_A3) {
 		skge_write32(hw, B2_GP_IO,
 			     skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9);
 	}
 
-	skge_gma_write16(hw, port, GM_GP_CTRL,
-			 skge_gma_read16(hw, port, GM_GP_CTRL)
+	gma_write16(hw, port, GM_GP_CTRL,
+			 gma_read16(hw, port, GM_GP_CTRL)
 			 & ~(GM_GPCR_RX_ENA|GM_GPCR_RX_ENA));
-	skge_gma_read16(hw, port, GM_GP_CTRL);
+	gma_read16(hw, port, GM_GP_CTRL);
 
 	/* set GPHY Control reset */
-	skge_gma_write32(hw, port, GPHY_CTRL, GPC_RST_SET);
-	skge_gma_write32(hw, port, GMAC_CTRL, GMC_RST_SET);
+	gma_write32(hw, port, GPHY_CTRL, GPC_RST_SET);
+	gma_write32(hw, port, GMAC_CTRL, GMC_RST_SET);
 }
 
 static void yukon_get_stats(struct skge_port *skge, u64 *data)
@@ -1928,39 +1834,40 @@
 	int port = skge->port;
 	int i;
 
-	data[0] = (u64) skge_gma_read32(hw, port, GM_TXO_OK_HI) << 32
-		| skge_gma_read32(hw, port, GM_TXO_OK_LO);
-	data[1] = (u64) skge_gma_read32(hw, port, GM_RXO_OK_HI) << 32
-		| skge_gma_read32(hw, port, GM_RXO_OK_LO);
+	data[0] = (u64) gma_read32(hw, port, GM_TXO_OK_HI) << 32
+		| gma_read32(hw, port, GM_TXO_OK_LO);
+	data[1] = (u64) gma_read32(hw, port, GM_RXO_OK_HI) << 32
+		| gma_read32(hw, port, GM_RXO_OK_LO);
 
 	for (i = 2; i < ARRAY_SIZE(skge_stats); i++)
-		data[i] = skge_gma_read32(hw, port,
+		data[i] = gma_read32(hw, port,
 					  skge_stats[i].gma_offset);
 }
 
 static void yukon_mac_intr(struct skge_hw *hw, int port)
 {
-	struct skge_port *skge = netdev_priv(hw->dev[port]);
-	u8 status = skge_read8(hw, SKGEMAC_REG(port, GMAC_IRQ_SRC));
+	struct net_device *dev = hw->dev[port];
+	struct skge_port *skge = netdev_priv(dev);
+	u8 status = skge_read8(hw, SK_REG(port, GMAC_IRQ_SRC));
 
-	pr_debug("yukon_intr status %x\n", status);
+	if (netif_msg_intr(skge))
+		printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n",
+		       dev->name, status);
+
 	if (status & GM_IS_RX_FF_OR) {
 		++skge->net_stats.rx_fifo_errors;
-		skge_gma_write8(hw, port, RX_GMF_CTRL_T, GMF_CLI_RX_FO);
+		gma_write8(hw, port, RX_GMF_CTRL_T, GMF_CLI_RX_FO);
 	}
 	if (status & GM_IS_TX_FF_UR) {
 		++skge->net_stats.tx_fifo_errors;
-		skge_gma_write8(hw, port, TX_GMF_CTRL_T, GMF_CLI_TX_FU);
+		gma_write8(hw, port, TX_GMF_CTRL_T, GMF_CLI_TX_FU);
 	}
 
 }
 
 static u16 yukon_speed(const struct skge_hw *hw, u16 aux)
 {
-	if (hw->chip_id == CHIP_ID_YUKON_FE)
-		return (aux & PHY_M_PS_SPEED_100) ? SPEED_100 : SPEED_10;
-
-	switch(aux & PHY_M_PS_SPEED_MSK) {
+	switch (aux & PHY_M_PS_SPEED_MSK) {
 	case PHY_M_PS_SPEED_1000:
 		return SPEED_1000;
 	case PHY_M_PS_SPEED_100:
@@ -1981,15 +1888,15 @@
 	/* Enable Transmit FIFO Underrun */
 	skge_write8(hw, GMAC_IRQ_MSK, GMAC_DEF_MSK);
 
-	reg = skge_gma_read16(hw, port, GM_GP_CTRL);
+	reg = gma_read16(hw, port, GM_GP_CTRL);
 	if (skge->duplex == DUPLEX_FULL || skge->autoneg == AUTONEG_ENABLE)
 		reg |= GM_GPCR_DUP_FULL;
 
 	/* enable Rx/Tx */
 	reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
-	skge_gma_write16(hw, port, GM_GP_CTRL, reg);
+	gma_write16(hw, port, GM_GP_CTRL, reg);
 
-	skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
+	gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
 	skge_link_up(skge);
 }
 
@@ -1999,16 +1906,15 @@
 	int port = skge->port;
 
 	pr_debug("yukon_link_down\n");
-	skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
-	skge_gm_phy_write(hw, port, GM_GP_CTRL,
-			  skge_gm_phy_read(hw, port, GM_GP_CTRL)
+	gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
+	gm_phy_write(hw, port, GM_GP_CTRL,
+			  gm_phy_read(hw, port, GM_GP_CTRL)
 			  & ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA));
 
-	if (hw->chip_id != CHIP_ID_YUKON_FE &&
-	    skge->flow_control == FLOW_MODE_REM_SEND) {
+	if (skge->flow_control == FLOW_MODE_REM_SEND) {
 		/* restore Asymmetric Pause bit */
-		skge_gm_phy_write(hw, port, PHY_MARV_AUNE_ADV,
-				  skge_gm_phy_read(hw, port,
+		gm_phy_write(hw, port, PHY_MARV_AUNE_ADV,
+				  gm_phy_read(hw, port,
 						   PHY_MARV_AUNE_ADV)
 				  | PHY_M_AN_ASP);
 
@@ -2027,20 +1933,21 @@
 	const char *reason = NULL;
 	u16 istatus, phystat;
 
-	istatus = skge_gm_phy_read(hw, port, PHY_MARV_INT_STAT);
-	phystat = skge_gm_phy_read(hw, port, PHY_MARV_PHY_STAT);
-	pr_debug("yukon phy intr istat=%x phy_stat=%x\n", istatus, phystat);
+	istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT);
+	phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT);
+
+	if (netif_msg_intr(skge))
+		printk(KERN_DEBUG PFX "%s: phy interrupt status 0x%x 0x%x\n",
+		       skge->netdev->name, istatus, phystat);
 
 	if (istatus & PHY_M_IS_AN_COMPL) {
-		if (skge_gm_phy_read(hw, port, PHY_MARV_AUNE_LP)
+		if (gm_phy_read(hw, port, PHY_MARV_AUNE_LP)
 		    & PHY_M_AN_RF) {
 			reason = "remote fault";
 			goto failed;
 		}
 
-		if (!(hw->chip_id == CHIP_ID_YUKON_FE || hw->chip_id == CHIP_ID_YUKON_EC)
-		    && (skge_gm_phy_read(hw, port, PHY_MARV_1000T_STAT)
-			& PHY_B_1000S_MSF)) {
+		if (gm_phy_read(hw, port, PHY_MARV_1000T_STAT) & PHY_B_1000S_MSF) {
 			reason = "master/slave fault";
 			goto failed;
 		}
@@ -2054,10 +1961,6 @@
 			? DUPLEX_FULL : DUPLEX_HALF;
 		skge->speed = yukon_speed(hw, phystat);
 
-		/* Tx & Rx Pause Enabled bits are at 9..8 */
-		if (hw->chip_id == CHIP_ID_YUKON_XL)
-			phystat >>= 6;
-
 		/* We are using IEEE 802.3z/D5.0 Table 37-4 */
 		switch (phystat & PHY_M_PS_PAUSE_MSK) {
 		case PHY_M_PS_PAUSE_MSK:
@@ -2075,9 +1978,9 @@
 
 		if (skge->flow_control == FLOW_MODE_NONE ||
 		    (skge->speed < SPEED_1000 && skge->duplex == DUPLEX_HALF))
-			skge_write8(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
+			skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
 		else
-			skge_write8(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
+			skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
 		yukon_link_up(skge);
 		return;
 	}
@@ -2161,6 +2064,12 @@
 	if (netif_msg_ifup(skge))
 		printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
 
+	if (dev->mtu > RX_BUF_SIZE)
+		skge->rx_buf_size = dev->mtu + ETH_HLEN + NET_IP_ALIGN;
+	else
+		skge->rx_buf_size = RX_BUF_SIZE;
+
+
 	rx_size = skge->rx_ring.count * sizeof(struct skge_rx_desc);
 	tx_size = skge->tx_ring.count * sizeof(struct skge_tx_desc);
 	skge->mem_size = tx_size + rx_size;
@@ -2173,7 +2082,8 @@
 	if ((err = skge_ring_alloc(&skge->rx_ring, skge->mem, skge->dma)))
 		goto free_pci_mem;
 
-	if (skge_rx_fill(skge))
+	err = skge_rx_fill(skge);
+	if (err)
 		goto free_rx_ring;
 
 	if ((err = skge_ring_alloc(&skge->tx_ring, skge->mem + rx_size,
@@ -2182,6 +2092,10 @@
 
 	skge->tx_avail = skge->tx_ring.count - 1;
 
+	/* Enable IRQ from port */
+	hw->intr_mask |= portirqmask[port];
+	skge_write32(hw, B0_IMSK, hw->intr_mask);
+
 	/* Initialze MAC */
 	if (hw->chip_id == CHIP_ID_GENESIS)
 		genesis_mac_init(hw, port);
@@ -2189,7 +2103,7 @@
 		yukon_mac_init(hw, port);
 
 	/* Configure RAMbuffers */
-	chunk = hw->ram_size / (isdualport(hw) ? 4 : 2);
+	chunk = hw->ram_size / ((hw->ports + 1)*2);
 	ram_addr = hw->ram_offset + 2 * chunk * port;
 
 	skge_ramset(hw, rxqaddr[port], ram_addr, chunk);
@@ -2227,7 +2141,6 @@
 	netif_stop_queue(dev);
 
 	del_timer_sync(&skge->led_blink);
-	del_timer_sync(&skge->link_check);
 
 	/* Stop transmitter */
 	skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP);
@@ -2240,12 +2153,12 @@
 		yukon_stop(skge);
 
 	/* Disable Force Sync bit and Enable Alloc bit */
-	skge_write8(hw, SKGEMAC_REG(port, TXA_CTRL),
+	skge_write8(hw, SK_REG(port, TXA_CTRL),
 		    TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
 
 	/* Stop Interval Timer and Limit Counter of Tx Arbiter */
-	skge_write32(hw, SKGEMAC_REG(port, TXA_ITI_INI), 0L);
-	skge_write32(hw, SKGEMAC_REG(port, TXA_LIM_INI), 0L);
+	skge_write32(hw, SK_REG(port, TXA_ITI_INI), 0L);
+	skge_write32(hw, SK_REG(port, TXA_LIM_INI), 0L);
 
 	/* Reset PCI FIFO */
 	skge_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_SET_RESET);
@@ -2260,13 +2173,13 @@
 	skge_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_SET_RESET);
 
 	if (hw->chip_id == CHIP_ID_GENESIS) {
-		skge_write8(hw, SKGEMAC_REG(port, TX_MFF_CTRL2), MFF_RST_SET);
-		skge_write8(hw, SKGEMAC_REG(port, RX_MFF_CTRL2), MFF_RST_SET);
-		skge_write8(hw, SKGEMAC_REG(port, TX_LED_CTRL), LED_STOP);
-		skge_write8(hw, SKGEMAC_REG(port, RX_LED_CTRL), LED_STOP);
+		skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_SET);
+		skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_SET);
+		skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_STOP);
+		skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_STOP);
 	} else {
-		skge_write8(hw, SKGEMAC_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
-		skge_write8(hw, SKGEMAC_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
+		skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
+		skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
 	}
 
 	/* turn off led's */
@@ -2299,10 +2212,10 @@
 
 	local_irq_save(flags);
 	if (!spin_trylock(&skge->tx_lock)) {
- 		/* Collision - tell upper layer to requeue */ 
- 		local_irq_restore(flags); 
- 		return NETDEV_TX_LOCKED; 
- 	} 
+ 		/* Collision - tell upper layer to requeue */
+ 		local_irq_restore(flags);
+ 		return NETDEV_TX_LOCKED;
+ 	}
 
 	if (unlikely(skge->tx_avail < skb_shinfo(skb)->nr_frags +1)) {
 		netif_stop_queue(dev);
@@ -2333,7 +2246,7 @@
 		 * does.  Looks like hardware is wrong?
 		 */
 		if (ip->protocol == IPPROTO_UDP
-	            && chip_rev(hw) == 0 && hw->chip_id == CHIP_ID_YUKON)
+	            && hw->chip_rev == 0 && hw->chip_id == CHIP_ID_YUKON)
 			control = BMU_TCP_CHECK;
 		else
 			control = BMU_UDP_CHECK;
@@ -2394,6 +2307,7 @@
 
 static inline void skge_tx_free(struct skge_hw *hw, struct skge_element *e)
 {
+	/* This ring element can be skb or fragment */
 	if (e->skb) {
 		pci_unmap_single(hw->pdev,
 			       pci_unmap_addr(e, mapaddr),
@@ -2438,16 +2352,17 @@
 static int skge_change_mtu(struct net_device *dev, int new_mtu)
 {
 	int err = 0;
+	int running = netif_running(dev);
 
-	if(new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
+	if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
 		return -EINVAL;
 
-	dev->mtu = new_mtu;
 
-	if (netif_running(dev)) {
+	if (running)
 		skge_down(dev);
+	dev->mtu = new_mtu;
+	if (running)
 		skge_up(dev);
-	}
 
 	return err;
 }
@@ -2462,7 +2377,9 @@
 	u32 mode;
 	u8 filter[8];
 
-	mode = skge_xm_read32(hw, port, XM_MODE);
+	pr_debug("genesis_set_multicast flags=%x count=%d\n", dev->flags, dev->mc_count);
+
+	mode = xm_read32(hw, port, XM_MODE);
 	mode |= XM_MD_ENA_HASH;
 	if (dev->flags & IFF_PROMISC)
 		mode |= XM_MD_ENA_PROM;
@@ -2473,17 +2390,16 @@
 		memset(filter, 0xff, sizeof(filter));
 	else {
 		memset(filter, 0, sizeof(filter));
-		for(i = 0; list && i < count; i++, list = list->next) {
-			u32 crc = crc32_le(~0, list->dmi_addr, ETH_ALEN);
-			u8 bit = 63 - (crc & 63);
-
+		for (i = 0; list && i < count; i++, list = list->next) {
+			u32 crc, bit;
+			crc = ether_crc_le(ETH_ALEN, list->dmi_addr);
+			bit = ~crc & 0x3f;
 			filter[bit/8] |= 1 << (bit%8);
 		}
 	}
 
-	skge_xm_outhash(hw, port, XM_HSM, filter);
-
-	skge_xm_write32(hw, port, XM_MODE, mode);
+	xm_write32(hw, port, XM_MODE, mode);
+	xm_outhash(hw, port, XM_HSM, filter);
 }
 
 static void yukon_set_multicast(struct net_device *dev)
@@ -2497,7 +2413,7 @@
 
 	memset(filter, 0, sizeof(filter));
 
-	reg = skge_gma_read16(hw, port, GM_RX_CTRL);
+	reg = gma_read16(hw, port, GM_RX_CTRL);
 	reg |= GM_RXCR_UCF_ENA;
 
 	if (dev->flags & IFF_PROMISC) 		/* promiscious */
@@ -2510,23 +2426,23 @@
 		int i;
 		reg |= GM_RXCR_MCF_ENA;
 
-		for(i = 0; list && i < dev->mc_count; i++, list = list->next) {
+		for (i = 0; list && i < dev->mc_count; i++, list = list->next) {
 			u32 bit = ether_crc(ETH_ALEN, list->dmi_addr) & 0x3f;
 			filter[bit/8] |= 1 << (bit%8);
 		}
 	}
 
 
-	skge_gma_write16(hw, port, GM_MC_ADDR_H1,
+	gma_write16(hw, port, GM_MC_ADDR_H1,
 			 (u16)filter[0] | ((u16)filter[1] << 8));
-	skge_gma_write16(hw, port, GM_MC_ADDR_H2,
+	gma_write16(hw, port, GM_MC_ADDR_H2,
 			 (u16)filter[2] | ((u16)filter[3] << 8));
-	skge_gma_write16(hw, port, GM_MC_ADDR_H3,
+	gma_write16(hw, port, GM_MC_ADDR_H3,
 			 (u16)filter[4] | ((u16)filter[5] << 8));
-	skge_gma_write16(hw, port, GM_MC_ADDR_H4,
+	gma_write16(hw, port, GM_MC_ADDR_H4,
 			 (u16)filter[6] | ((u16)filter[7] << 8));
 
-	skge_gma_write16(hw, port, GM_RX_CTRL, reg);
+	gma_write16(hw, port, GM_RX_CTRL, reg);
 }
 
 static inline int bad_phy_status(const struct skge_hw *hw, u32 status)
@@ -2545,28 +2461,76 @@
 		printk(KERN_DEBUG PFX "%s: rx err, slot %d control 0x%x status 0x%x\n",
 		       skge->netdev->name, slot, control, status);
 
-	if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF)
-	    || (control & BMU_BBC) > skge->netdev->mtu + VLAN_ETH_HLEN)
+	if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF))
 		skge->net_stats.rx_length_errors++;
-	else {
-		if (skge->hw->chip_id == CHIP_ID_GENESIS) {
-			if (status & (XMR_FS_RUNT|XMR_FS_LNG_ERR))
-				skge->net_stats.rx_length_errors++;
-			if (status & XMR_FS_FRA_ERR)
-				skge->net_stats.rx_frame_errors++;
-			if (status & XMR_FS_FCS_ERR)
-				skge->net_stats.rx_crc_errors++;
-		} else {
-			if (status & (GMR_FS_LONG_ERR|GMR_FS_UN_SIZE))
-				skge->net_stats.rx_length_errors++;
-			if (status & GMR_FS_FRAGMENT)
-				skge->net_stats.rx_frame_errors++;
-			if (status & GMR_FS_CRC_ERR)
-				skge->net_stats.rx_crc_errors++;
-		}
+	else if (skge->hw->chip_id == CHIP_ID_GENESIS) {
+		if (status & (XMR_FS_RUNT|XMR_FS_LNG_ERR))
+			skge->net_stats.rx_length_errors++;
+		if (status & XMR_FS_FRA_ERR)
+			skge->net_stats.rx_frame_errors++;
+		if (status & XMR_FS_FCS_ERR)
+			skge->net_stats.rx_crc_errors++;
+	} else {
+		if (status & (GMR_FS_LONG_ERR|GMR_FS_UN_SIZE))
+			skge->net_stats.rx_length_errors++;
+		if (status & GMR_FS_FRAGMENT)
+			skge->net_stats.rx_frame_errors++;
+		if (status & GMR_FS_CRC_ERR)
+			skge->net_stats.rx_crc_errors++;
 	}
 }
 
+/* Get receive buffer from descriptor.
+ * Handles copy of small buffers and reallocation failures
+ */
+static inline struct sk_buff *skge_rx_get(struct skge_port *skge,
+					  struct skge_element *e,
+					  unsigned int len)
+{
+	struct sk_buff *nskb, *skb;
+
+	if (len < RX_COPY_THRESHOLD) {
+		nskb = skge_rx_alloc(skge->netdev, len + NET_IP_ALIGN);
+		if (unlikely(!nskb))
+			return NULL;
+
+		pci_dma_sync_single_for_cpu(skge->hw->pdev,
+					    pci_unmap_addr(e, mapaddr),
+					    len, PCI_DMA_FROMDEVICE);
+		memcpy(nskb->data, e->skb->data, len);
+		pci_dma_sync_single_for_device(skge->hw->pdev,
+					       pci_unmap_addr(e, mapaddr),
+					       len, PCI_DMA_FROMDEVICE);
+
+		if (skge->rx_csum) {
+			struct skge_rx_desc *rd = e->desc;
+			nskb->csum = le16_to_cpu(rd->csum2);
+			nskb->ip_summed = CHECKSUM_HW;
+		}
+		skge_rx_reuse(e, skge->rx_buf_size);
+		return nskb;
+	} else {
+		nskb = skge_rx_alloc(skge->netdev, skge->rx_buf_size);
+		if (unlikely(!nskb))
+			return NULL;
+
+		pci_unmap_single(skge->hw->pdev,
+				 pci_unmap_addr(e, mapaddr),
+				 pci_unmap_len(e, maplen),
+				 PCI_DMA_FROMDEVICE);
+		skb = e->skb;
+		if (skge->rx_csum) {
+			struct skge_rx_desc *rd = e->desc;
+			skb->csum = le16_to_cpu(rd->csum2);
+			skb->ip_summed = CHECKSUM_HW;
+		}
+
+		skge_rx_setup(skge, e, nskb, skge->rx_buf_size);
+		return skb;
+	}
+}
+
+
 static int skge_poll(struct net_device *dev, int *budget)
 {
 	struct skge_port *skge = netdev_priv(dev);
@@ -2575,13 +2539,12 @@
 	struct skge_element *e;
 	unsigned int to_do = min(dev->quota, *budget);
 	unsigned int work_done = 0;
-	int done;
-	static const u32 irqmask[] = { IS_PORT_1, IS_PORT_2 };
 
-	for (e = ring->to_clean; e != ring->to_use && work_done < to_do;
-	     e = e->next) {
+	pr_debug("skge_poll\n");
+
+	for (e = ring->to_clean; work_done < to_do; e = e->next) {
 		struct skge_rx_desc *rd = e->desc;
-		struct sk_buff *skb = e->skb;
+		struct sk_buff *skb;
 		u32 control, len, status;
 
 		rmb();
@@ -2590,19 +2553,12 @@
 			break;
 
 		len = control & BMU_BBC;
-		e->skb = NULL;
-
-		pci_unmap_single(hw->pdev,
-				 pci_unmap_addr(e, mapaddr),
-				 pci_unmap_len(e, maplen),
-				 PCI_DMA_FROMDEVICE);
-
 		status = rd->status;
-		if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF)
-		     || len > dev->mtu + VLAN_ETH_HLEN
-		     || bad_phy_status(hw, status)) {
+
+		if (unlikely((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF)
+			     || bad_phy_status(hw, status))) {
 			skge_rx_error(skge, e - ring->start, control, status);
-			dev_kfree_skb(skb);
+			skge_rx_reuse(e, skge->rx_buf_size);
 			continue;
 		}
 
@@ -2610,43 +2566,37 @@
 		    printk(KERN_DEBUG PFX "%s: rx slot %td status 0x%x len %d\n",
 			   dev->name, e - ring->start, rd->status, len);
 
-		skb_put(skb, len);
-		skb->protocol = eth_type_trans(skb, dev);
+		skb = skge_rx_get(skge, e, len);
+		if (likely(skb)) {
+			skb_put(skb, len);
+			skb->protocol = eth_type_trans(skb, dev);
 
-		if (skge->rx_csum) {
-			skb->csum = le16_to_cpu(rd->csum2);
-			skb->ip_summed = CHECKSUM_HW;
-		}
+			dev->last_rx = jiffies;
+			netif_receive_skb(skb);
 
-		dev->last_rx = jiffies;
-		netif_receive_skb(skb);
-
-		++work_done;
+			++work_done;
+		} else
+			skge_rx_reuse(e, skge->rx_buf_size);
 	}
 	ring->to_clean = e;
 
-	*budget -= work_done;
-	dev->quota -= work_done;
-	done = work_done < to_do;
-
-	if (skge_rx_fill(skge))
-		done = 0;
-
 	/* restart receiver */
 	wmb();
 	skge_write8(hw, Q_ADDR(rxqaddr[skge->port], Q_CSR),
 		    CSR_START | CSR_IRQ_CL_F);
 
-	if (done) {
-		local_irq_disable();
-		hw->intr_mask |= irqmask[skge->port];
-		/* Order is important since data can get interrupted */
-		skge_write32(hw, B0_IMSK, hw->intr_mask);
-		__netif_rx_complete(dev);
-		local_irq_enable();
-	}
+	*budget -= work_done;
+	dev->quota -= work_done;
 
-	return !done;
+	if (work_done >=  to_do)
+		return 1; /* not done */
+
+	local_irq_disable();
+	__netif_rx_complete(dev);
+	hw->intr_mask |= portirqmask[skge->port];
+	skge_write32(hw, B0_IMSK, hw->intr_mask);
+	local_irq_enable();
+	return 0;
 }
 
 static inline void skge_tx_intr(struct net_device *dev)
@@ -2657,7 +2607,7 @@
 	struct skge_element *e;
 
 	spin_lock(&skge->tx_lock);
-	for(e = ring->to_clean; e != ring->to_use; e = e->next) {
+	for (e = ring->to_clean; e != ring->to_use; e = e->next) {
 		struct skge_tx_desc *td = e->desc;
 		u32 control;
 
@@ -2690,12 +2640,12 @@
 	       : (port == 0 ? "(port A)": "(port B"));
 
 	if (hw->chip_id == CHIP_ID_GENESIS)
-		skge_write16(hw, SKGEMAC_REG(port, TX_MFF_CTRL1),
+		skge_write16(hw, SK_REG(port, TX_MFF_CTRL1),
 			     MFF_CLR_PERR);
 	else
 		/* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */
-		skge_write8(hw, SKGEMAC_REG(port, TX_GMF_CTRL_T),
-			    (hw->chip_id == CHIP_ID_YUKON && chip_rev(hw) == 0)
+		skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T),
+			    (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0)
 			    ? GMF_CLI_TX_FC : GMF_CLI_TX_PE);
 }
 
@@ -2703,16 +2653,16 @@
 {
 	u16 status;
 
-	status = skge_read16(hw, SKGEPCI_REG(PCI_STATUS));
+	pci_read_config_word(hw->pdev, PCI_STATUS, &status);
 	skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-	skge_write16(hw, SKGEPCI_REG(PCI_STATUS),
-		     status | PCI_STATUS_ERROR_BITS);
+	pci_write_config_word(hw->pdev, PCI_STATUS,
+			      status | PCI_STATUS_ERROR_BITS);
 	skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
 }
 
 static void skge_mac_intr(struct skge_hw *hw, int port)
 {
-	if (hw->chip_id == CHIP_ID_GENESIS) 
+	if (hw->chip_id == CHIP_ID_GENESIS)
 		genesis_mac_intr(hw, port);
 	else
 		yukon_mac_intr(hw, port);
@@ -2726,9 +2676,9 @@
 	if (hw->chip_id == CHIP_ID_GENESIS) {
 		/* clear xmac errors */
 		if (hwstatus & (IS_NO_STAT_M1|IS_NO_TIST_M1))
-			skge_write16(hw, SKGEMAC_REG(0, RX_MFF_CTRL1), MFF_CLR_INSTAT);
+			skge_write16(hw, SK_REG(0, RX_MFF_CTRL1), MFF_CLR_INSTAT);
 		if (hwstatus & (IS_NO_STAT_M2|IS_NO_TIST_M2))
-			skge_write16(hw, SKGEMAC_REG(0, RX_MFF_CTRL2), MFF_CLR_INSTAT);
+			skge_write16(hw, SK_REG(0, RX_MFF_CTRL2), MFF_CLR_INSTAT);
 	} else {
 		/* Timestamp (unused) overflow */
 		if (hwstatus & IS_IRQ_TIST_OV)
@@ -2803,8 +2753,8 @@
 
 			if (hw->chip_id != CHIP_ID_GENESIS)
 				yukon_phy_intr(skge);
-			else if (hw->phy_type == SK_PHY_BCOM)
-				genesis_bcom_intr(skge);
+			else
+				bcom_phy_intr(skge);
 		}
 	}
 	spin_unlock(&hw->phy_lock);
@@ -2824,19 +2774,14 @@
 		return IRQ_NONE;
 
 	status &= hw->intr_mask;
-
-	if ((status & IS_R1_F) && netif_rx_schedule_prep(hw->dev[0])) {
-		status &= ~IS_R1_F;
+	if (status & IS_R1_F) {
 		hw->intr_mask &= ~IS_R1_F;
-		skge_write32(hw, B0_IMSK, hw->intr_mask);
-		__netif_rx_schedule(hw->dev[0]);
+		netif_rx_schedule(hw->dev[0]);
 	}
 
-	if ((status & IS_R2_F) && netif_rx_schedule_prep(hw->dev[1])) {
-		status &= ~IS_R2_F;
+	if (status & IS_R2_F) {
 		hw->intr_mask &= ~IS_R2_F;
-		skge_write32(hw, B0_IMSK, hw->intr_mask);
-		__netif_rx_schedule(hw->dev[1]);
+		netif_rx_schedule(hw->dev[1]);
 	}
 
 	if (status & IS_XA1_F)
@@ -2845,9 +2790,27 @@
 	if (status & IS_XA2_F)
 		skge_tx_intr(hw->dev[1]);
 
+	if (status & IS_PA_TO_RX1) {
+		struct skge_port *skge = netdev_priv(hw->dev[0]);
+		++skge->net_stats.rx_over_errors;
+		skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_RX1);
+	}
+
+	if (status & IS_PA_TO_RX2) {
+		struct skge_port *skge = netdev_priv(hw->dev[1]);
+		++skge->net_stats.rx_over_errors;
+		skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_RX2);
+	}
+
+	if (status & IS_PA_TO_TX1)
+		skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_TX1);
+
+	if (status & IS_PA_TO_TX2)
+		skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_TX2);
+
 	if (status & IS_MAC1)
 		skge_mac_intr(hw, 0);
-	
+
 	if (status & IS_MAC2)
 		skge_mac_intr(hw, 1);
 
@@ -2859,8 +2822,7 @@
 		tasklet_schedule(&hw->ext_tasklet);
 	}
 
-	if (status)
-		skge_write32(hw, B0_IMSK, hw->intr_mask);
+	skge_write32(hw, B0_IMSK, hw->intr_mask);
 
 	return IRQ_HANDLED;
 }
@@ -2904,9 +2866,6 @@
 	{ CHIP_ID_YUKON,	 "Yukon" },
 	{ CHIP_ID_YUKON_LITE,	 "Yukon-Lite"},
 	{ CHIP_ID_YUKON_LP,	 "Yukon-LP"},
-	{ CHIP_ID_YUKON_XL,	 "Yukon-2 XL"},
-	{ CHIP_ID_YUKON_EC,	 "YUKON-2 EC"},
-	{ CHIP_ID_YUKON_FE,	 "YUKON-2 FE"},
 };
 
 static const char *skge_board_name(const struct skge_hw *hw)
@@ -2930,8 +2889,8 @@
 static int skge_reset(struct skge_hw *hw)
 {
 	u16 ctst;
-	u8 t8;
-	int i, ports;
+	u8 t8, mac_cfg;
+	int i;
 
 	ctst = skge_read16(hw, B0_CTST);
 
@@ -2952,12 +2911,9 @@
 	hw->phy_type = skge_read8(hw, B2_E_1) & 0xf;
 	hw->pmd_type = skge_read8(hw, B2_PMD_TYP);
 
-	switch(hw->chip_id) {
+	switch (hw->chip_id) {
 	case CHIP_ID_GENESIS:
 		switch (hw->phy_type) {
-		case SK_PHY_XMAC:
-			hw->phy_addr = PHY_ADDR_XMAC;
-			break;
 		case SK_PHY_BCOM:
 			hw->phy_addr = PHY_ADDR_BCOM;
 			break;
@@ -2986,8 +2942,9 @@
 		return -EOPNOTSUPP;
 	}
 
-	hw->mac_cfg = skge_read8(hw, B2_MAC_CFG);
-	ports = isdualport(hw) ? 2 : 1;
+	mac_cfg = skge_read8(hw, B2_MAC_CFG);
+	hw->ports = (mac_cfg & CFG_SNG_MAC) ? 1 : 2;
+	hw->chip_rev = (mac_cfg & CFG_CHIP_R_MSK) >> 4;
 
 	/* read the adapters RAM size */
 	t8 = skge_read8(hw, B2_E_0);
@@ -3010,9 +2967,9 @@
 		/* switch power to VCC (WA for VAUX problem) */
 		skge_write8(hw, B0_POWER_CTRL,
 			    PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);
-		for (i = 0; i < ports; i++) {
-			skge_write16(hw, SKGEMAC_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
-			skge_write16(hw, SKGEMAC_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
+		for (i = 0; i < hw->ports; i++) {
+			skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
+			skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
 		}
 	}
 
@@ -3022,8 +2979,8 @@
 	skge_write8(hw, B0_LED, LED_STAT_ON);
 
 	/* enable the Tx Arbiters */
-	for (i = 0; i < ports; i++)
-		skge_write8(hw, SKGEMAC_REG(i, TXA_CTRL), TXA_ENA_ARB);
+	for (i = 0; i < hw->ports; i++)
+		skge_write8(hw, SK_REG(i, TXA_CTRL), TXA_ENA_ARB);
 
 	/* Initialize ram interface */
 	skge_write16(hw, B3_RI_CTRL, RI_RST_CLR);
@@ -3050,16 +3007,14 @@
 	skge_write32(hw, B2_IRQM_INI, skge_usecs2clk(hw, 100));
 	skge_write32(hw, B2_IRQM_CTRL, TIM_START);
 
-	hw->intr_mask = IS_HW_ERR | IS_EXT_REG | IS_PORT_1;
-	if (isdualport(hw))
-		hw->intr_mask |= IS_PORT_2;
+	hw->intr_mask = IS_HW_ERR | IS_EXT_REG;
 	skge_write32(hw, B0_IMSK, hw->intr_mask);
 
 	if (hw->chip_id != CHIP_ID_GENESIS)
 		skge_write8(hw, GMAC_IRQ_MSK, 0);
 
 	spin_lock_bh(&hw->phy_lock);
-	for (i = 0; i < ports; i++) {
+	for (i = 0; i < hw->ports; i++) {
 		if (hw->chip_id == CHIP_ID_GENESIS)
 			genesis_reset(hw, i);
 		else
@@ -3071,7 +3026,8 @@
 }
 
 /* Initialize network device */
-static struct net_device *skge_devinit(struct skge_hw *hw, int port)
+static struct net_device *skge_devinit(struct skge_hw *hw, int port,
+				       int highmem)
 {
 	struct skge_port *skge;
 	struct net_device *dev = alloc_etherdev(sizeof(*skge));
@@ -3104,6 +3060,8 @@
 #endif
 	dev->irq = hw->pdev->irq;
 	dev->features = NETIF_F_LLTX;
+	if (highmem)
+		dev->features |= NETIF_F_HIGHDMA;
 
 	skge = netdev_priv(dev);
 	skge->netdev = dev;
@@ -3117,7 +3075,7 @@
 	skge->flow_control = FLOW_MODE_SYMMETRIC;
 	skge->duplex = -1;
 	skge->speed = -1;
-	skge->advertising = skge_modes(hw);
+	skge->advertising = skge_supported_modes(hw);
 
 	hw->dev[port] = dev;
 
@@ -3125,10 +3083,6 @@
 
 	spin_lock_init(&skge->tx_lock);
 
-	init_timer(&skge->link_check);
-	skge->link_check.function = skge_link_timer;
-	skge->link_check.data = (unsigned long) skge;
-
 	init_timer(&skge->led_blink);
 	skge->led_blink.function = skge_blink_timer;
 	skge->led_blink.data = (unsigned long) skge;
@@ -3232,14 +3186,11 @@
 
 	printk(KERN_INFO PFX "addr 0x%lx irq %d chip %s rev %d\n",
 	       pci_resource_start(pdev, 0), pdev->irq,
-	       skge_board_name(hw), chip_rev(hw));
+	       skge_board_name(hw), hw->chip_rev);
 
-	if ((dev = skge_devinit(hw, 0)) == NULL)
+	if ((dev = skge_devinit(hw, 0, using_dac)) == NULL)
 		goto err_out_led_off;
 
-	if (using_dac)
-		dev->features |= NETIF_F_HIGHDMA;
-
 	if ((err = register_netdev(dev))) {
 		printk(KERN_ERR PFX "%s: cannot register net device\n",
 		       pci_name(pdev));
@@ -3248,10 +3199,7 @@
 
 	skge_show_addr(dev);
 
-	if (isdualport(hw) && (dev1 = skge_devinit(hw, 1))) {
-		if (using_dac)
-			dev1->features |= NETIF_F_HIGHDMA;
-
+	if (hw->ports > 1 && (dev1 = skge_devinit(hw, 1, using_dac))) {
 		if (register_netdev(dev1) == 0)
 			skge_show_addr(dev1);
 		else {
@@ -3288,7 +3236,7 @@
 	struct skge_hw *hw  = pci_get_drvdata(pdev);
 	struct net_device *dev0, *dev1;
 
-	if(!hw)
+	if (!hw)
 		return;
 
 	if ((dev1 = hw->dev[1]))
@@ -3316,7 +3264,7 @@
 	struct skge_hw *hw  = pci_get_drvdata(pdev);
 	int i, wol = 0;
 
-	for(i = 0; i < 2; i++) {
+	for (i = 0; i < 2; i++) {
 		struct net_device *dev = hw->dev[i];
 
 		if (dev) {
@@ -3349,11 +3297,11 @@
 
 	skge_reset(hw);
 
-	for(i = 0; i < 2; i++) {
+	for (i = 0; i < 2; i++) {
 		struct net_device *dev = hw->dev[i];
 		if (dev) {
 			netif_device_attach(dev);
-			if(netif_running(dev))
+			if (netif_running(dev))
 				skge_up(dev);
 		}
 	}
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index 36c62b6..fced3d2 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -7,31 +7,7 @@
 /* PCI config registers */
 #define PCI_DEV_REG1	0x40
 #define PCI_DEV_REG2	0x44
-#ifndef PCI_VPD
-#define PCI_VPD		0x50
-#endif
-
-/*	PCI_OUR_REG_2		32 bit	Our Register 2 */
-enum {
-	PCI_VPD_WR_THR  = 0xff<<24, /* Bit 31..24:	VPD Write Threshold */
-	PCI_DEV_SEL	= 0x7f<<17, /* Bit 23..17:	EEPROM Device Select */
-	PCI_VPD_ROM_SZ  = 7   <<14, /* Bit 16..14:	VPD ROM Size	*/
- 				    /* Bit 13..12:	reserved	*/
-	PCI_EN_DUMMY_RD = 1<<3, /* Enable Dummy Read */
-	PCI_REV_DESC    = 1<<2, /* Reverse Desc. Bytes */
-	PCI_USEDATA64   = 1<<0, /* Use 64Bit Data bus ext */
-};
-
-/*	PCI_VPD_ADR_REG		16 bit	VPD Address Register */
-enum {
-	PCI_VPD_FLAG	= 1<<15,  /* starts VPD rd/wr cycle */
-	PCI_VPD_ADR_MSK =0x7fffL, /* Bit 14.. 0:	VPD Address Mask */
-	VPD_RES_ID	= 0x82,
-	VPD_RES_READ	= 0x90,
-	VPD_RES_WRITE	= 0x81,
-	VPD_RES_END	= 0x78,
-};
-
+#define  PCI_REV_DESC	 0x4
 
 #define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
 			       PCI_STATUS_SIG_SYSTEM_ERROR | \
@@ -39,7 +15,6 @@
 			       PCI_STATUS_REC_TARGET_ABORT | \
 			       PCI_STATUS_PARITY)
 
-
 enum csr_regs {
 	B0_RAP	= 0x0000,
 	B0_CTST	= 0x0004,
@@ -229,8 +204,11 @@
 	IS_XA2_F	= 1<<1,		/* Q_XA2 End of Frame */
 	IS_XA2_C	= 1<<0,		/* Q_XA2 Encoding Error */
 
-	IS_PORT_1	= IS_XA1_F| IS_R1_F| IS_MAC1,
-	IS_PORT_2	= IS_XA2_F| IS_R2_F| IS_MAC2,
+	IS_TO_PORT1	= IS_PA_TO_RX1 | IS_PA_TO_TX1,
+	IS_TO_PORT2	= IS_PA_TO_RX2 | IS_PA_TO_TX2,
+
+	IS_PORT_1	= IS_XA1_F| IS_R1_F | IS_TO_PORT1 | IS_MAC1,
+	IS_PORT_2	= IS_XA2_F| IS_R2_F | IS_TO_PORT2 | IS_MAC2,
 };
 
 
@@ -288,14 +266,6 @@
 	CHIP_REV_YU_LITE_A3  = 7,	/* Chip Rev. for YUKON-Lite A3 */
 };
 
-/*	B2_LD_TEST		 8 bit	EPROM loader test register */
-enum {
-	LD_T_ON		= 1<<3,	/* Loader Test mode on */
-	LD_T_OFF	= 1<<2,	/* Loader Test mode off */
-	LD_T_STEP	= 1<<1,	/* Decrement FPROM addr. Counter */
-	LD_START	= 1<<0,	/* Start loading FPROM */
-};
-
 /*	B2_TI_CTRL		 8 bit	Timer control */
 /*	B2_IRQM_CTRL	 8 bit	IRQ Moderation Timer Control */
 enum {
@@ -313,16 +283,6 @@
 	TIM_T_STEP	= 1<<0,	/* Test step */
 };
 
-/*	B28_DPT_INI	32 bit	Descriptor Poll Timer Init Val */
-/*	B28_DPT_VAL	32 bit	Descriptor Poll Timer Curr Val */
-/*	B28_DPT_CTRL	 8 bit	Descriptor Poll Timer Ctrl Reg */
-enum {
-	DPT_MSK	= 0x00ffffffL,	/* Bit 23.. 0:	Desc Poll Timer Bits */
-
-	DPT_START	= 1<<1,	/* Start Descriptor Poll Timer */
-	DPT_STOP	= 1<<0,	/* Stop  Descriptor Poll Timer */
-};
-
 /*	B2_GP_IO		32 bit	General Purpose I/O Register */
 enum {
 	GP_DIR_9 = 1<<25, /* IO_9 direct, 0=In/1=Out */
@@ -348,30 +308,6 @@
 	GP_IO_0	= 1<<0,	/* IO_0 pin */
 };
 
-/* Rx/Tx Path related Arbiter Test Registers */
-/*	B3_MA_TO_TEST	16 bit	MAC Arbiter Timeout Test Reg */
-/*	B3_MA_RC_TEST	16 bit	MAC Arbiter Recovery Test Reg */
-/*	B3_PA_TEST		16 bit	Packet Arbiter Test Register */
-/*			Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */
-enum {
-	TX2_T_EV	= 1<<15,/* TX2 Timeout/Recv Event occured */
-	TX2_T_ON	= 1<<14,/* TX2 Timeout/Recv Timer Test On */
-	TX2_T_OFF	= 1<<13,/* TX2 Timeout/Recv Timer Tst Off */
-	TX2_T_STEP	= 1<<12,/* TX2 Timeout/Recv Timer Step */
-	TX1_T_EV	= 1<<11,/* TX1 Timeout/Recv Event occured */
-	TX1_T_ON	= 1<<10,/* TX1 Timeout/Recv Timer Test On */
-	TX1_T_OFF	= 1<<9,	/* TX1 Timeout/Recv Timer Tst Off */
-	TX1_T_STEP	= 1<<8,	/* TX1 Timeout/Recv Timer Step */
-	RX2_T_EV	= 1<<7,	/* RX2 Timeout/Recv Event occured */
-	RX2_T_ON	= 1<<6,	/* RX2 Timeout/Recv Timer Test On */
-	RX2_T_OFF	= 1<<5,	/* RX2 Timeout/Recv Timer Tst Off */
-	RX2_T_STEP	= 1<<4,	/* RX2 Timeout/Recv Timer Step */
-	RX1_T_EV	= 1<<3,	/* RX1 Timeout/Recv Event occured */
-	RX1_T_ON	= 1<<2,	/* RX1 Timeout/Recv Timer Test On */
-	RX1_T_OFF	= 1<<1,	/* RX1 Timeout/Recv Timer Tst Off */
-	RX1_T_STEP	= 1<<0,	/* RX1 Timeout/Recv Timer Step */
-};
-
 /* Descriptor Bit Definition */
 /*	TxCtrl		Transmit Buffer Control Field */
 /*	RxCtrl		Receive  Buffer Control Field */
@@ -428,14 +364,6 @@
 	RI_RST_SET	= 1<<0,	/* Set   RAM Interface Reset */
 };
 
-/*	B3_RI_TEST		 8 bit	RAM Iface Test Register */
-enum {
-	RI_T_EV	= 1<<3,	/* Timeout Event occured */
-	RI_T_ON	= 1<<2,	/* Timeout Timer Test On */
-	RI_T_OFF	= 1<<1,	/* Timeout Timer Test Off */
-	RI_T_STEP	= 1<<0,	/* Timeout Timer Step */
-};
-
 /* MAC Arbiter Registers */
 /*	B3_MA_TO_CTRL	16 bit	MAC Arbiter Timeout Ctrl Reg */
 enum {
@@ -452,19 +380,6 @@
 #define SK_PKT_TO_MAX	0xffff		/* Maximum value */
 #define SK_RI_TO_53	36		/* RAM interface timeout */
 
-
-/*	B3_MA_RC_CTRL	16 bit	MAC Arbiter Recovery Ctrl Reg */
-enum {
-	MA_ENA_REC_TX2	= 1<<7,	/* Enable  Recovery Timer TX2 */
-	MA_DIS_REC_TX2	= 1<<6,	/* Disable Recovery Timer TX2 */
-	MA_ENA_REC_TX1	= 1<<5,	/* Enable  Recovery Timer TX1 */
-	MA_DIS_REC_TX1	= 1<<4,	/* Disable Recovery Timer TX1 */
-	MA_ENA_REC_RX2	= 1<<3,	/* Enable  Recovery Timer RX2 */
-	MA_DIS_REC_RX2	= 1<<2,	/* Disable Recovery Timer RX2 */
-	MA_ENA_REC_RX1	= 1<<1,	/* Enable  Recovery Timer RX1 */
-	MA_DIS_REC_RX1	= 1<<0,	/* Disable Recovery Timer RX1 */
-};
-
 /* Packet Arbiter Registers */
 /*	B3_PA_CTRL		16 bit	Packet Arbiter Ctrl Register */
 enum {
@@ -488,7 +403,7 @@
 						PA_ENA_TO_TX1 | PA_ENA_TO_TX2)
 
 
-/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
+/* Transmit Arbiter Registers MAC 1 and 2, use SK_REG() to access */
 /*	TXA_ITI_INI		32 bit	Tx Arb Interval Timer Init Val */
 /*	TXA_ITI_VAL		32 bit	Tx Arb Interval Timer Value */
 /*	TXA_LIM_INI		32 bit	Tx Arb Limit Counter Init Val */
@@ -511,7 +426,7 @@
 /*
  *	Bank 4 - 5
  */
-/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
+/* Transmit Arbiter Registers MAC 1 and 2, use SK_REG() to access */
 enum {
 	TXA_ITI_INI	= 0x0200,/* 32 bit	Tx Arb Interval Timer Init Val*/
 	TXA_ITI_VAL	= 0x0204,/* 32 bit	Tx Arb Interval Timer Value */
@@ -537,7 +452,7 @@
 
 /* Queue Register Offsets, use Q_ADDR() to access */
 enum {
-	B8_Q_REGS = 0x0400, /* base of Queue registers */	
+	B8_Q_REGS = 0x0400, /* base of Queue registers */
 	Q_D	= 0x00,	/* 8*32	bit	Current Descriptor */
 	Q_DA_L	= 0x20,	/* 32 bit	Current Descriptor Address Low dWord */
 	Q_DA_H	= 0x24,	/* 32 bit	Current Descriptor Address High dWord */
@@ -618,8 +533,7 @@
 enum {
 	PHY_ADDR_XMAC	= 0<<8,
 	PHY_ADDR_BCOM	= 1<<8,
-	PHY_ADDR_LONE	= 3<<8,
-	PHY_ADDR_NAT	= 0<<8,
+
 /* GPHY address (bits 15..11 of SMI control reg) */
 	PHY_ADDR_MARV	= 0,
 };
@@ -986,7 +900,7 @@
 	LINKLED_BLINK_OFF    = 0x10,
 	LINKLED_BLINK_ON     = 0x20,
 };
-	
+
 /* GMAC and GPHY Control Registers (YUKON only) */
 enum {
 	GMAC_CTRL	= 0x0f00,/* 32 bit	GMAC Control Reg */
@@ -1151,54 +1065,6 @@
 	PHY_MARV_FE_SPEC_2	= 0x1c,/* 16 bit r/w	Specific Control Reg. 2 */
 };
 
-/* Level One-PHY Registers, indirect addressed over XMAC */
-enum {
-	PHY_LONE_CTRL		= 0x00,/* 16 bit r/w	PHY Control Register */
-	PHY_LONE_STAT		= 0x01,/* 16 bit r/o	PHY Status Register */
-	PHY_LONE_ID0		= 0x02,/* 16 bit r/o	PHY ID0 Register */
-	PHY_LONE_ID1		= 0x03,/* 16 bit r/o	PHY ID1 Register */
-	PHY_LONE_AUNE_ADV	= 0x04,/* 16 bit r/w	Auto-Neg. Advertisement */
-	PHY_LONE_AUNE_LP	= 0x05,/* 16 bit r/o	Link Part Ability Reg */
-	PHY_LONE_AUNE_EXP	= 0x06,/* 16 bit r/o	Auto-Neg. Expansion Reg */
-	PHY_LONE_NEPG		= 0x07,/* 16 bit r/w	Next Page Register */
-	PHY_LONE_NEPG_LP	= 0x08,/* 16 bit r/o	Next Page Link Partner */
-	/* Level One-specific registers */
-	PHY_LONE_1000T_CTRL	= 0x09,/* 16 bit r/w	1000Base-T Control Reg */
-	PHY_LONE_1000T_STAT	= 0x0a,/* 16 bit r/o	1000Base-T Status Reg */
-	PHY_LONE_EXT_STAT	= 0x0f,/* 16 bit r/o	Extended Status Reg */
-	PHY_LONE_PORT_CFG	= 0x10,/* 16 bit r/w	Port Configuration Reg*/
-	PHY_LONE_Q_STAT		= 0x11,/* 16 bit r/o	Quick Status Reg */
-	PHY_LONE_INT_ENAB	= 0x12,/* 16 bit r/w	Interrupt Enable Reg */
-	PHY_LONE_INT_STAT	= 0x13,/* 16 bit r/o	Interrupt Status Reg */
-	PHY_LONE_LED_CFG	= 0x14,/* 16 bit r/w	LED Configuration Reg */
-	PHY_LONE_PORT_CTRL	= 0x15,/* 16 bit r/w	Port Control Reg */
-	PHY_LONE_CIM		= 0x16,/* 16 bit r/o	CIM Reg */
-};
-
-/* National-PHY Registers, indirect addressed over XMAC */
-enum {
-	PHY_NAT_CTRL		= 0x00,/* 16 bit r/w	PHY Control Register */
-	PHY_NAT_STAT		= 0x01,/* 16 bit r/w	PHY Status Register */
-	PHY_NAT_ID0		= 0x02,/* 16 bit r/o	PHY ID0 Register */
-	PHY_NAT_ID1		= 0x03,/* 16 bit r/o	PHY ID1 Register */
-	PHY_NAT_AUNE_ADV	= 0x04,/* 16 bit r/w	Auto-Neg. Advertisement */
-	PHY_NAT_AUNE_LP		= 0x05,/* 16 bit r/o	Link Partner Ability Reg */
-	PHY_NAT_AUNE_EXP	= 0x06,/* 16 bit r/o	Auto-Neg. Expansion Reg */
-	PHY_NAT_NEPG		= 0x07,/* 16 bit r/w	Next Page Register */
-	PHY_NAT_NEPG_LP		= 0x08,/* 16 bit r/o	Next Page Link Partner Reg */
-	/* National-specific registers */
-	PHY_NAT_1000T_CTRL	= 0x09,/* 16 bit r/w	1000Base-T Control Reg */
-	PHY_NAT_1000T_STAT	= 0x0a,/* 16 bit r/o	1000Base-T Status Reg */
-	PHY_NAT_EXT_STAT	= 0x0f,/* 16 bit r/o	Extended Status Register */
-	PHY_NAT_EXT_CTRL1	= 0x10,/* 16 bit r/o	Extended Control Reg1 */
-	PHY_NAT_Q_STAT1		= 0x11,/* 16 bit r/o	Quick Status Reg1 */
-	PHY_NAT_10B_OP		= 0x12,/* 16 bit r/o	10Base-T Operations Reg */
-	PHY_NAT_EXT_CTRL2	= 0x13,/* 16 bit r/o	Extended Control Reg1 */
-	PHY_NAT_Q_STAT2		= 0x14,/* 16 bit r/o	Quick Status Reg2 */
-
-	PHY_NAT_PHY_ADDR	= 0x19,/* 16 bit r/o	PHY Address Register */
-};
-
 enum {
 	PHY_CT_RESET	= 1<<15, /* Bit 15: (sc)	clear all PHY related regs */
 	PHY_CT_LOOP	= 1<<14, /* Bit 14:	enable Loopback over PHY */
@@ -1253,8 +1119,29 @@
 	PHY_MARV_ID1_Y2	= 0x0C91, /* Yukon-2 (PHY 88E1112) */
 };
 
+/* Advertisement register bits */
 enum {
 	PHY_AN_NXT_PG	= 1<<15, /* Bit 15:	Request Next Page */
+	PHY_AN_ACK	= 1<<14, /* Bit 14:	(ro) Acknowledge Received */
+	PHY_AN_RF	= 1<<13, /* Bit 13:	Remote Fault Bits */
+
+	PHY_AN_PAUSE_ASYM = 1<<11,/* Bit 11:	Try for asymmetric */
+	PHY_AN_PAUSE_CAP = 1<<10, /* Bit 10:	Try for pause */
+	PHY_AN_100BASE4	= 1<<9, /* Bit 9:	Try for 100mbps 4k packets */
+	PHY_AN_100FULL	= 1<<8, /* Bit 8:	Try for 100mbps full-duplex */
+	PHY_AN_100HALF	= 1<<7, /* Bit 7:	Try for 100mbps half-duplex */
+	PHY_AN_10FULL	= 1<<6, /* Bit 6:	Try for 10mbps full-duplex */
+	PHY_AN_10HALF	= 1<<5, /* Bit 5:	Try for 10mbps half-duplex */
+	PHY_AN_CSMA	= 1<<0, /* Bit 0:	Only selector supported */
+	PHY_AN_SEL	= 0x1f, /* Bit 4..0:	Selector Field, 00001=Ethernet*/
+	PHY_AN_FULL	= PHY_AN_100FULL | PHY_AN_10FULL | PHY_AN_CSMA,
+	PHY_AN_ALL	= PHY_AN_10HALF | PHY_AN_10FULL |
+		  	  PHY_AN_100HALF | PHY_AN_100FULL,
+};
+
+/* Xmac Specific */
+enum {
+	PHY_X_AN_NXT_PG	= 1<<15, /* Bit 15:	Request Next Page */
 	PHY_X_AN_ACK	= 1<<14, /* Bit 14:	(ro) Acknowledge Received */
 	PHY_X_AN_RFB	= 3<<12,/* Bit 13..12:	Remote Fault Bits */
 
@@ -1263,82 +1150,6 @@
 	PHY_X_AN_FD	= 1<<5, /* Bit  5:	Full Duplex */
 };
 
-enum {
-	PHY_B_AN_RF	= 1<<13, /* Bit 13:	Remote Fault */
-
-	PHY_B_AN_ASP	= 1<<11, /* Bit 11:	Asymmetric Pause */
-	PHY_B_AN_PC	= 1<<10, /* Bit 10:	Pause Capable */
-	PHY_B_AN_SEL	= 0x1f, /* Bit 4..0:	Selector Field, 00001=Ethernet*/
-};
-
-enum {
-	PHY_L_AN_RF	= 1<<13, /* Bit 13:	Remote Fault */
-								/* Bit 12:	reserved */
-	PHY_L_AN_ASP	= 1<<11, /* Bit 11:	Asymmetric Pause */
-	PHY_L_AN_PC	= 1<<10, /* Bit 10:	Pause Capable */
-
-	PHY_L_AN_SEL	= 0x1f, /* Bit 4..0:	Selector Field, 00001=Ethernet*/
-};
-
-/*  PHY_NAT_AUNE_ADV	16 bit r/w	Auto-Negotiation Advertisement */
-/*  PHY_NAT_AUNE_LP	16 bit r/o	Link Partner Ability Reg *****/
-/*  PHY_AN_NXT_PG	(see XMAC) Bit 15:	Request Next Page */
-enum {
-	PHY_N_AN_RF	= 1<<13, /* Bit 13:	Remote Fault */
-
-	PHY_N_AN_100F	= 1<<11, /* Bit 11:	100Base-T2 FD Support */
-	PHY_N_AN_100H	= 1<<10, /* Bit 10:	100Base-T2 HD Support */
-
-	PHY_N_AN_SEL	= 0x1f, /* Bit 4..0:	Selector Field, 00001=Ethernet*/
-};
-
-/* field type definition for PHY_x_AN_SEL */
-enum {
-	PHY_SEL_TYPE	 = 1,	/* 00001 = Ethernet */
-};
-
-enum {
-	PHY_ANE_LP_NP	= 1<<3, /* Bit  3:	Link Partner can Next Page */
-	PHY_ANE_LOC_NP	= 1<<2, /* Bit  2:	Local PHY can Next Page */
-	PHY_ANE_RX_PG	= 1<<1, /* Bit  1:	Page Received */
-};
-
-enum {
-	PHY_ANE_PAR_DF	= 1<<4, /* Bit  4:	Parallel Detection Fault */
-
-	PHY_ANE_LP_CAP	= 1<<0, /* Bit  0:	Link Partner Auto-Neg. Cap. */ 	
-};
-
-enum {
-	PHY_NP_MORE	= 1<<15, /* Bit 15:	More, Next Pages to follow */
-	PHY_NP_ACK1	= 1<<14, /* Bit 14: (ro)	Ack1, for receiving a message */
-	PHY_NP_MSG_VAL	= 1<<13, /* Bit 13:	Message Page valid */
-	PHY_NP_ACK2	= 1<<12, /* Bit 12:	Ack2, comply with msg content */
-	PHY_NP_TOG	= 1<<11, /* Bit 11:	Toggle Bit, ensure sync */
-	PHY_NP_MSG	= 0x07ff, /* Bit 10..0:	Message from/to Link Partner */
-};
-
-enum {
-	PHY_X_EX_FD	= 1<<15, /* Bit 15:	Device Supports Full Duplex */
-	PHY_X_EX_HD	= 1<<14, /* Bit 14:	Device Supports Half Duplex */
-};
-
-enum {
-	PHY_X_RS_PAUSE	= 3<<7,/* Bit  8..7:	selected Pause Mode */
-	PHY_X_RS_HD	= 1<<6, /* Bit  6:	Half Duplex Mode selected */
-	PHY_X_RS_FD	= 1<<5, /* Bit  5:	Full Duplex Mode selected */
-	PHY_X_RS_ABLMIS	= 1<<4, /* Bit  4:	duplex or pause cap mismatch */
-	PHY_X_RS_PAUMIS	= 1<<3, /* Bit  3:	pause capability mismatch */
-};
-
-/** Remote Fault Bits (PHY_X_AN_RFB) encoding  */
-enum {
-	X_RFB_OK	= 0<<12,/* Bit 13..12	No errors, Link OK */
-	X_RFB_LF	= 1<<12, /* Bit 13..12	Link Failure */
-	X_RFB_OFF	= 2<<12,/* Bit 13..12	Offline */
-	X_RFB_AN_ERR	= 3<<12,/* Bit 13..12	Auto-Negotiation Error */
-};
-
 /* Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding */
 enum {
 	PHY_X_P_NO_PAUSE	= 0<<7,/* Bit  8..7:	no Pause Mode */
@@ -1418,6 +1229,16 @@
 	PHY_B_PES_MLT3_ER	= 1<<0, /* Bit  0:	MLT3 code Error */
 };
 
+/*  PHY_BCOM_AUNE_ADV	16 bit r/w	Auto-Negotiation Advertisement *****/
+/*  PHY_BCOM_AUNE_LP	16 bit r/o	Link Partner Ability Reg *****/
+enum {
+	PHY_B_AN_RF	= 1<<13, /* Bit 13:	Remote Fault */
+
+	PHY_B_AN_ASP	= 1<<11, /* Bit 11:	Asymmetric Pause */
+	PHY_B_AN_PC	= 1<<10, /* Bit 10:	Pause Capable */
+};
+
+
 /*****  PHY_BCOM_FC_CTR		16 bit r/w	False Carrier Counter *****/
 enum {
 	PHY_B_FC_CTR	= 0xff, /* Bit  7..0:	False Carrier Counter */
@@ -1478,7 +1299,9 @@
 	PHY_B_IS_LST_CHANGE	= 1<<1, /* Bit  1:	Link Status Changed */
 	PHY_B_IS_CRC_ER	= 1<<0, /* Bit  0:	CRC Error */
 };
-#define PHY_B_DEF_MSK	(~(PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE))
+#define PHY_B_DEF_MSK	\
+	(~(PHY_B_IS_PSE | PHY_B_IS_AN_PR | PHY_B_IS_DUP_CHANGE | \
+	    PHY_B_IS_LSP_CHANGE | PHY_B_IS_LST_CHANGE))
 
 /* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */
 enum {
@@ -1495,166 +1318,6 @@
 	PHY_B_RES_1000HD	= 6<<8,/* Bit 10..8:	1000Base-T Half Dup. */
 };
 
-/*
- * Level One-Specific
- */
-/*****  PHY_LONE_1000T_CTRL	16 bit r/w	1000Base-T Control Reg *****/
-enum {
-	PHY_L_1000C_TEST	= 7<<13,/* Bit 15..13:	Test Modes */
-	PHY_L_1000C_MSE	= 1<<12, /* Bit 12:	Master/Slave Enable */
-	PHY_L_1000C_MSC	= 1<<11, /* Bit 11:	M/S Configuration */
-	PHY_L_1000C_RD	= 1<<10, /* Bit 10:	Repeater/DTE */
-	PHY_L_1000C_AFD	= 1<<9, /* Bit  9:	Advertise Full Duplex */
-	PHY_L_1000C_AHD	= 1<<8, /* Bit  8:	Advertise Half Duplex */
-};
-
-/*****  PHY_LONE_1000T_STAT	16 bit r/o	1000Base-T Status Reg *****/
-enum {
-	PHY_L_1000S_MSF	= 1<<15, /* Bit 15:	Master/Slave Fault */
-	PHY_L_1000S_MSR	= 1<<14, /* Bit 14:	Master/Slave Result */
-	PHY_L_1000S_LRS	= 1<<13, /* Bit 13:	Local Receiver Status */
-	PHY_L_1000S_RRS	= 1<<12, /* Bit 12:	Remote Receiver Status */
-	PHY_L_1000S_LP_FD = 1<<11, /* Bit 11:	Link Partner can FD */
-	PHY_L_1000S_LP_HD = 1<<10, /* Bit 10:	Link Partner can HD */
-
-	PHY_L_1000S_IEC	 = 0xff, /* Bit  7..0:	Idle Error Count */
-
-/*****  PHY_LONE_EXT_STAT	16 bit r/o	Extended Status Register *****/
-	PHY_L_ES_X_FD_CAP = 1<<15, /* Bit 15:	1000Base-X FD capable */
-	PHY_L_ES_X_HD_CAP = 1<<14, /* Bit 14:	1000Base-X HD capable */
-	PHY_L_ES_T_FD_CAP = 1<<13, /* Bit 13:	1000Base-T FD capable */
-	PHY_L_ES_T_HD_CAP = 1<<12, /* Bit 12:	1000Base-T HD capable */
-};
-
-/*****  PHY_LONE_PORT_CFG	16 bit r/w	Port Configuration Reg *****/
-enum {
-	PHY_L_PC_REP_MODE	= 1<<15, /* Bit 15:	Repeater Mode */
-
-	PHY_L_PC_TX_DIS	= 1<<13, /* Bit 13:	Tx output Disabled */
-	PHY_L_PC_BY_SCR	= 1<<12, /* Bit 12:	Bypass Scrambler */
-	PHY_L_PC_BY_45	= 1<<11, /* Bit 11:	Bypass 4B5B-Decoder */
-	PHY_L_PC_JAB_DIS	= 1<<10, /* Bit 10:	Jabber Disabled */
-	PHY_L_PC_SQE	= 1<<9, /* Bit  9:	Enable Heartbeat */
-	PHY_L_PC_TP_LOOP	= 1<<8, /* Bit  8:	TP Loopback */
-	PHY_L_PC_SSS	= 1<<7, /* Bit  7:	Smart Speed Selection */
-	PHY_L_PC_FIFO_SIZE	= 1<<6, /* Bit  6:	FIFO Size */
-	PHY_L_PC_PRE_EN	= 1<<5, /* Bit  5:	Preamble Enable */
-	PHY_L_PC_CIM	= 1<<4, /* Bit  4:	Carrier Integrity Mon */
-	PHY_L_PC_10_SER	= 1<<3, /* Bit  3:	Use Serial Output */
-	PHY_L_PC_ANISOL	= 1<<2, /* Bit  2:	Unisolate Port */
-	PHY_L_PC_TEN_BIT	= 1<<1, /* Bit  1:	10bit iface mode on */
-	PHY_L_PC_ALTCLOCK	= 1<<0, /* Bit  0: (ro)	ALTCLOCK Mode on */
-};
-
-/*****  PHY_LONE_Q_STAT		16 bit r/o	Quick Status Reg *****/
-enum {
-	PHY_L_QS_D_RATE	= 3<<14,/* Bit 15..14:	Data Rate */
-	PHY_L_QS_TX_STAT	= 1<<13, /* Bit 13:	Transmitting */
-	PHY_L_QS_RX_STAT	= 1<<12, /* Bit 12:	Receiving */
-	PHY_L_QS_COL_STAT	= 1<<11, /* Bit 11:	Collision */
-	PHY_L_QS_L_STAT	= 1<<10, /* Bit 10:	Link is up */
-	PHY_L_QS_DUP_MOD	= 1<<9, /* Bit  9:	Full/Half Duplex */
-	PHY_L_QS_AN	= 1<<8, /* Bit  8:	AutoNeg is On */
-	PHY_L_QS_AN_C	= 1<<7, /* Bit  7:	AN is Complete */
-	PHY_L_QS_LLE	= 7<<4,/* Bit  6..4:	Line Length Estim. */
-	PHY_L_QS_PAUSE	= 1<<3, /* Bit  3:	LP advertised Pause */
-	PHY_L_QS_AS_PAUSE	= 1<<2, /* Bit  2:	LP adv. asym. Pause */
-	PHY_L_QS_ISOLATE	= 1<<1, /* Bit  1:	CIM Isolated */
-	PHY_L_QS_EVENT	= 1<<0, /* Bit  0:	Event has occurred */
-};
-
-/*****  PHY_LONE_INT_ENAB	16 bit r/w	Interrupt Enable Reg *****/
-/*****  PHY_LONE_INT_STAT	16 bit r/o	Interrupt Status Reg *****/
-enum {
-	PHY_L_IS_AN_F	= 1<<13, /* Bit 13:	Auto-Negotiation fault */
-	PHY_L_IS_CROSS	= 1<<11, /* Bit 11:	Crossover used */
-	PHY_L_IS_POL	= 1<<10, /* Bit 10:	Polarity correct. used */
-	PHY_L_IS_SS	= 1<<9, /* Bit  9:	Smart Speed Downgrade */
-	PHY_L_IS_CFULL	= 1<<8, /* Bit  8:	Counter Full */
-	PHY_L_IS_AN_C	= 1<<7, /* Bit  7:	AutoNeg Complete */
-	PHY_L_IS_SPEED	= 1<<6, /* Bit  6:	Speed Changed */
-	PHY_L_IS_DUP	= 1<<5, /* Bit  5:	Duplex Changed */
-	PHY_L_IS_LS	= 1<<4, /* Bit  4:	Link Status Changed */
-	PHY_L_IS_ISOL	= 1<<3, /* Bit  3:	Isolate Occured */
-	PHY_L_IS_MDINT	= 1<<2, /* Bit  2: (ro)	STAT: MII Int Pending */
-	PHY_L_IS_INTEN	= 1<<1, /* Bit  1:	ENAB: Enable IRQs */
-	PHY_L_IS_FORCE	= 1<<0, /* Bit  0:	ENAB: Force Interrupt */
-};
-
-/* int. mask */
-#define PHY_L_DEF_MSK	(PHY_L_IS_LS | PHY_L_IS_ISOL | PHY_L_IS_INTEN)
-
-/*****  PHY_LONE_LED_CFG	16 bit r/w	LED Configuration Reg *****/
-enum {
-	PHY_L_LC_LEDC	= 3<<14,/* Bit 15..14:	Col/Blink/On/Off */
-	PHY_L_LC_LEDR	= 3<<12,/* Bit 13..12:	Rx/Blink/On/Off */
-	PHY_L_LC_LEDT	= 3<<10,/* Bit 11..10:	Tx/Blink/On/Off */
-	PHY_L_LC_LEDG	= 3<<8,/* Bit  9..8:	Giga/Blink/On/Off */
-	PHY_L_LC_LEDS	= 3<<6,/* Bit  7..6:	10-100/Blink/On/Off */
-	PHY_L_LC_LEDL	= 3<<4,/* Bit  5..4:	Link/Blink/On/Off */
-	PHY_L_LC_LEDF	= 3<<2,/* Bit  3..2:	Duplex/Blink/On/Off */
-	PHY_L_LC_PSTRECH= 1<<1, /* Bit  1:	Strech LED Pulses */
-	PHY_L_LC_FREQ	= 1<<0, /* Bit  0:	30/100 ms */
-};
-
-/*****  PHY_LONE_PORT_CTRL	16 bit r/w	Port Control Reg *****/
-enum {
-	PHY_L_PC_TX_TCLK = 1<<15, /* Bit 15:	Enable TX_TCLK */
-	PHY_L_PC_ALT_NP	 = 1<<13, /* Bit 14:	Alternate Next Page */
-	PHY_L_PC_GMII_ALT= 1<<12, /* Bit 13:	Alternate GMII driver */
-	PHY_L_PC_TEN_CRS = 1<<10, /* Bit 10:	Extend CRS*/
-};
-
-/*****  PHY_LONE_CIM		16 bit r/o	CIM Reg *****/
-enum {
-	PHY_L_CIM_ISOL	    = 0xff<<8,/* Bit 15..8:	Isolate Count */
-	PHY_L_CIM_FALSE_CAR = 0xff,   /* Bit  7..0:	False Carrier Count */
-};
-
-/*
- * Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding
- */
-enum {
-	PHY_L_P_NO_PAUSE= 0<<10,/* Bit 11..10:	no Pause Mode */
-	PHY_L_P_SYM_MD	= 1<<10, /* Bit 11..10:	symmetric Pause Mode */
-	PHY_L_P_ASYM_MD	= 2<<10,/* Bit 11..10:	asymmetric Pause Mode */
-	PHY_L_P_BOTH_MD	= 3<<10,/* Bit 11..10:	both Pause Mode */
-};
-
-/*
- * National-Specific
- */
-/*****  PHY_NAT_1000T_CTRL	16 bit r/w	1000Base-T Control Reg *****/
-enum {
-	PHY_N_1000C_TEST= 7<<13,/* Bit 15..13:	Test Modes */
-	PHY_N_1000C_MSE	= 1<<12, /* Bit 12:	Master/Slave Enable */
-	PHY_N_1000C_MSC	= 1<<11, /* Bit 11:	M/S Configuration */
-	PHY_N_1000C_RD	= 1<<10, /* Bit 10:	Repeater/DTE */
-	PHY_N_1000C_AFD	= 1<<9, /* Bit  9:	Advertise Full Duplex */
-	PHY_N_1000C_AHD	= 1<<8, /* Bit  8:	Advertise Half Duplex */
-	PHY_N_1000C_APC	= 1<<7, /* Bit  7:	Asymmetric Pause Cap. */};
-
-
-/*****  PHY_NAT_1000T_STAT	16 bit r/o	1000Base-T Status Reg *****/
-enum {
-	PHY_N_1000S_MSF	= 1<<15, /* Bit 15:	Master/Slave Fault */
-	PHY_N_1000S_MSR	= 1<<14, /* Bit 14:	Master/Slave Result */
-	PHY_N_1000S_LRS	= 1<<13, /* Bit 13:	Local Receiver Status */
-	PHY_N_1000S_RRS	= 1<<12, /* Bit 12:	Remote Receiver Status*/
-	PHY_N_1000S_LP_FD= 1<<11, /* Bit 11:	Link Partner can FD */
-	PHY_N_1000S_LP_HD= 1<<10, /* Bit 10:	Link Partner can HD */
-	PHY_N_1000C_LP_APC= 1<<9, /* Bit  9:	LP Asym. Pause Cap. */
-	PHY_N_1000S_IEC	= 0xff, /* Bit  7..0:	Idle Error Count */
-};
-
-/*****  PHY_NAT_EXT_STAT	16 bit r/o	Extended Status Register *****/
-enum {
-	PHY_N_ES_X_FD_CAP= 1<<15, /* Bit 15:	1000Base-X FD capable */
-	PHY_N_ES_X_HD_CAP= 1<<14, /* Bit 14:	1000Base-X HD capable */
-	PHY_N_ES_T_FD_CAP= 1<<13, /* Bit 13:	1000Base-T FD capable */
-	PHY_N_ES_T_HD_CAP= 1<<12, /* Bit 12:	1000Base-T HD capable */
-};
-
 /** Marvell-Specific */
 enum {
 	PHY_M_AN_NXT_PG	= 1<<15, /* Request Next Page */
@@ -1718,7 +1381,7 @@
 	PHY_M_PC_EN_DET_PLUS	= 3<<8, /* Energy Detect Plus (Mode 2) */
 };
 
-#define PHY_M_PC_MDI_XMODE(x)	(((x)<<5) & PHY_M_PC_MDIX_MSK)	
+#define PHY_M_PC_MDI_XMODE(x)	(((x)<<5) & PHY_M_PC_MDIX_MSK)
 
 enum {
 	PHY_M_PC_MAN_MDI	= 0, /* 00 = Manual MDI configuration */
@@ -2105,7 +1768,7 @@
 	GM_GPSR_FC_RX_DIS	= 1<<2,	/* Bit  2:	Rx Flow-Control Mode Disabled */
 	GM_GPSR_PROM_EN		= 1<<1,	/* Bit  1:	Promiscuous Mode Enabled */
 };
-	
+
 /*	GM_GP_CTRL	16 bit r/w	General Purpose Control Register */
 enum {
 	GM_GPCR_PROM_ENA	= 1<<14,	/* Bit 14:	Enable Promiscuous Mode */
@@ -2127,7 +1790,7 @@
 
 #define GM_GPCR_SPEED_1000	(GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
 #define GM_GPCR_AU_ALL_DIS	(GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS|GM_GPCR_AU_SPD_DIS)
-	
+
 /*	GM_TX_CTRL			16 bit r/w	Transmit Control Register */
 enum {
 	GM_TXCR_FORCE_JAM	= 1<<15, /* Bit 15:	Force Jam / Flow-Control */
@@ -2138,7 +1801,7 @@
 
 #define TX_COL_THR(x)		(((x)<<10) & GM_TXCR_COL_THR_MSK)
 #define TX_COL_DEF		0x04
-	
+
 /*	GM_RX_CTRL			16 bit r/w	Receive Control Register */
 enum {
 	GM_RXCR_UCF_ENA	= 1<<15, /* Bit 15:	Enable Unicast filtering */
@@ -2146,7 +1809,7 @@
 	GM_RXCR_CRC_DIS	= 1<<13, /* Bit 13:	Remove 4-byte CRC */
 	GM_RXCR_PASS_FC	= 1<<12, /* Bit 12:	Pass FC packets to FIFO */
 };
-	
+
 /*	GM_TX_PARAM		16 bit r/w	Transmit Parameter Register */
 enum {
 	GM_TXPA_JAMLEN_MSK	= 0x03<<14,	/* Bit 15..14:	Jam Length */
@@ -2171,7 +1834,7 @@
 	GM_SMOD_JUMBO_ENA	= 1<<8,	/* Bit  8:	Enable Jumbo (Max. Frame Len) */
 	 GM_SMOD_IPG_MSK	= 0x1f	/* Bit 4..0:	Inter-Packet Gap (IPG) */
 };
-	
+
 #define DATA_BLIND_VAL(x)	(((x)<<11) & GM_SMOD_DATABL_MSK)
 #define DATA_BLIND_DEF		0x04
 
@@ -2186,7 +1849,7 @@
 	GM_SMI_CT_RD_VAL	= 1<<4,	/* Bit  4:	Read Valid (Read completed) */
 	GM_SMI_CT_BUSY		= 1<<3,	/* Bit  3:	Busy (Operation in progress) */
 };
-	
+
 #define GM_SMI_CT_PHY_AD(x)	(((x)<<11) & GM_SMI_CT_PHY_A_MSK)
 #define GM_SMI_CT_REG_AD(x)	(((x)<<6) & GM_SMI_CT_REG_A_MSK)
 
@@ -2195,7 +1858,7 @@
 	GM_PAR_MIB_CLR	= 1<<5,	/* Bit  5:	Set MIB Clear Counter Mode */
 	GM_PAR_MIB_TST	= 1<<4,	/* Bit  4:	MIB Load Counter (Test Mode) */
 };
-	
+
 /* Receive Frame Status Encoding */
 enum {
 	GMR_FS_LEN	= 0xffff<<16, /* Bit 31..16:	Rx Frame Length */
@@ -2217,12 +1880,12 @@
 /*
  * GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR)
  */
-	GMR_FS_ANY_ERR	= GMR_FS_CRC_ERR | GMR_FS_LONG_ERR | 
-		  	  GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC | 
+	GMR_FS_ANY_ERR	= GMR_FS_CRC_ERR | GMR_FS_LONG_ERR |
+		  	  GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC |
 			  GMR_FS_JABBER,
 /* Rx GMAC FIFO Flush Mask (default) */
 	RX_FF_FL_DEF_MSK = GMR_FS_CRC_ERR | GMR_FS_RX_FF_OV |GMR_FS_MII_ERR |
-			   GMR_FS_BAD_FC | GMR_FS_GOOD_FC | GMR_FS_UN_SIZE | 
+			   GMR_FS_BAD_FC | GMR_FS_GOOD_FC | GMR_FS_UN_SIZE |
 			   GMR_FS_JABBER,
 };
 
@@ -2540,10 +2203,6 @@
 };
 
 
-/*	XM_PHY_ADDR	16 bit r/w	PHY Address Register */
-#define XM_PHY_ADDR_SZ	0x1f	/* Bit  4..0:	PHY Address bits */
-
-
 /*	XM_GP_PORT	32 bit r/w	General Purpose Port Register */
 enum {
 	XM_GP_ANIP	= 1<<6,	/* Bit  6: (ro)	Auto-Neg. in progress */
@@ -2662,8 +2321,8 @@
 };
 
 #define XM_PAUSE_MODE	(XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I)
-#define XM_DEF_MODE		(XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\
-				XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CAA)
+#define XM_DEF_MODE	(XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\
+			 XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA)
 
 /*	XM_STAT_CMD	16 bit r/w	Statistics Command Register */
 enum {
@@ -2793,28 +2452,20 @@
 	u32		     intr_mask;
 	struct net_device    *dev[2];
 
-	u8		     mac_cfg;
 	u8	     	     chip_id;
+	u8		     chip_rev;
 	u8		     phy_type;
 	u8		     pmd_type;
 	u16		     phy_addr;
+	u8		     ports;
 
 	u32	     	     ram_size;
 	u32	     	     ram_offset;
-	
+
 	struct tasklet_struct ext_tasklet;
 	spinlock_t	     phy_lock;
 };
 
-static inline int isdualport(const struct skge_hw *hw)
-{
-	return !(hw->mac_cfg & CFG_SNG_MAC);
-}
-
-static inline u8 chip_rev(const struct skge_hw *hw)
-{
-	return (hw->mac_cfg & CFG_CHIP_R_MSK) >> 4;
-}
 
 static inline int iscopper(const struct skge_hw *hw)
 {
@@ -2827,7 +2478,7 @@
 	FLOW_MODE_REM_SEND	= 2, /* Symmetric or just remote */
 	FLOW_MODE_SYMMETRIC	= 3, /* Both stations may send PAUSE */
 };
-	
+
 struct skge_port {
 	u32		     msg_enable;
 	struct skge_hw	     *hw;
@@ -2853,8 +2504,8 @@
 	void		     *mem;	/* PCI memory for rings */
 	dma_addr_t	     dma;
 	unsigned long	     mem_size;
+	unsigned int	     rx_buf_size;
 
-	struct timer_list    link_check;
 	struct timer_list    led_blink;
 };
 
@@ -2863,7 +2514,6 @@
 static inline u32 skge_read32(const struct skge_hw *hw, int reg)
 {
 	return readl(hw->regs + reg);
-
 }
 
 static inline u16 skge_read16(const struct skge_hw *hw, int reg)
@@ -2892,114 +2542,87 @@
 }
 
 /* MAC Related Registers inside the device. */
-#define SKGEMAC_REG(port,reg)	(((port)<<7)+(reg))
-
-/* PCI config space can be accessed via memory mapped space */
-#define SKGEPCI_REG(reg) ((reg)+ 0x380)
-
-#define SKGEXM_REG(port, reg) \
+#define SK_REG(port,reg)	(((port)<<7)+(reg))
+#define SK_XMAC_REG(port, reg) \
 	((BASE_XMAC_1 + (port) * (BASE_XMAC_2 - BASE_XMAC_1)) | (reg) << 1)
 
-static inline u32 skge_xm_read32(const struct skge_hw *hw, int port, int reg)
+static inline u32 xm_read32(const struct skge_hw *hw, int port, int reg)
 {
-	return skge_read32(hw, SKGEXM_REG(port,reg));
+	u32 v;
+	v = skge_read16(hw, SK_XMAC_REG(port, reg));
+	v |= (u32)skge_read16(hw, SK_XMAC_REG(port, reg+2)) << 16;
+	return v;
 }
 
-static inline u16 skge_xm_read16(const struct skge_hw *hw, int port, int reg)
+static inline u16 xm_read16(const struct skge_hw *hw, int port, int reg)
 {
-	return skge_read16(hw, SKGEXM_REG(port,reg));
+	return skge_read16(hw, SK_XMAC_REG(port,reg));
 }
 
-static inline u8 skge_xm_read8(const struct skge_hw *hw, int port, int reg)
+static inline void xm_write32(const struct skge_hw *hw, int port, int r, u32 v)
 {
-	return skge_read8(hw, SKGEXM_REG(port,reg));
+	skge_write16(hw, SK_XMAC_REG(port,r), v & 0xffff);
+	skge_write16(hw, SK_XMAC_REG(port,r+2), v >> 16);
 }
 
-static inline void skge_xm_write32(const struct skge_hw *hw, int port, int r, u32 v)
+static inline void xm_write16(const struct skge_hw *hw, int port, int r, u16 v)
 {
-	skge_write32(hw, SKGEXM_REG(port,r), v);
+	skge_write16(hw, SK_XMAC_REG(port,r), v);
 }
 
-static inline void skge_xm_write16(const struct skge_hw *hw, int port, int r, u16 v)
-{
-	skge_write16(hw, SKGEXM_REG(port,r), v);
-}
-
-static inline void skge_xm_write8(const struct skge_hw *hw, int port, int r, u8 v)
-{
-	skge_write8(hw, SKGEXM_REG(port,r), v);
-}
-
-static inline void skge_xm_outhash(const struct skge_hw *hw, int port, int reg,
+static inline void xm_outhash(const struct skge_hw *hw, int port, int reg,
 				   const u8 *hash)
 {
-	skge_xm_write16(hw, port, reg, 
-			(u16)hash[0] | ((u16)hash[1] << 8));
-	skge_xm_write16(hw, port, reg+2, 
-			(u16)hash[2] | ((u16)hash[3] << 8));
-	skge_xm_write16(hw, port, reg+4, 
-			(u16)hash[4] | ((u16)hash[5] << 8));
-	skge_xm_write16(hw, port, reg+6, 
-			(u16)hash[6] | ((u16)hash[7] << 8));
+	xm_write16(hw, port, reg,   (u16)hash[0] | ((u16)hash[1] << 8));
+	xm_write16(hw, port, reg+2, (u16)hash[2] | ((u16)hash[3] << 8));
+	xm_write16(hw, port, reg+4, (u16)hash[4] | ((u16)hash[5] << 8));
+	xm_write16(hw, port, reg+6, (u16)hash[6] | ((u16)hash[7] << 8));
 }
 
-static inline void skge_xm_outaddr(const struct skge_hw *hw, int port, int reg,
+static inline void xm_outaddr(const struct skge_hw *hw, int port, int reg,
 				   const u8 *addr)
 {
-	skge_xm_write16(hw, port, reg, 
-			(u16)addr[0] | ((u16)addr[1] << 8));
-	skge_xm_write16(hw, port, reg, 
-			(u16)addr[2] | ((u16)addr[3] << 8));
-	skge_xm_write16(hw, port, reg, 
-			(u16)addr[4] | ((u16)addr[5] << 8));
+	xm_write16(hw, port, reg,   (u16)addr[0] | ((u16)addr[1] << 8));
+	xm_write16(hw, port, reg+2, (u16)addr[2] | ((u16)addr[3] << 8));
+	xm_write16(hw, port, reg+4, (u16)addr[4] | ((u16)addr[5] << 8));
 }
 
+#define SK_GMAC_REG(port,reg) \
+	(BASE_GMAC_1 + (port) * (BASE_GMAC_2-BASE_GMAC_1) + (reg))
 
-#define SKGEGMA_REG(port,reg) \
-	((reg) + BASE_GMAC_1 + \
-	 (port) * (BASE_GMAC_2-BASE_GMAC_1))
-
-static inline u16 skge_gma_read16(const struct skge_hw *hw, int port, int reg)
+static inline u16 gma_read16(const struct skge_hw *hw, int port, int reg)
 {
-	return skge_read16(hw, SKGEGMA_REG(port,reg));
+	return skge_read16(hw, SK_GMAC_REG(port,reg));
 }
 
-static inline u32 skge_gma_read32(const struct skge_hw *hw, int port, int reg)
+static inline u32 gma_read32(const struct skge_hw *hw, int port, int reg)
 {
-	return (u32) skge_read16(hw, SKGEGMA_REG(port,reg))
-		| ((u32)skge_read16(hw, SKGEGMA_REG(port,reg+4)) << 16);
+	return (u32) skge_read16(hw, SK_GMAC_REG(port,reg))
+		| ((u32)skge_read16(hw, SK_GMAC_REG(port,reg+4)) << 16);
 }
 
-static inline u8 skge_gma_read8(const struct skge_hw *hw, int port, int reg)
+static inline void gma_write16(const struct skge_hw *hw, int port, int r, u16 v)
 {
-	return skge_read8(hw, SKGEGMA_REG(port,reg));
+	skge_write16(hw, SK_GMAC_REG(port,r), v);
 }
 
-static inline void skge_gma_write16(const struct skge_hw *hw, int port, int r, u16 v)
+static inline void gma_write32(const struct skge_hw *hw, int port, int r, u32 v)
 {
-	skge_write16(hw, SKGEGMA_REG(port,r), v);
+	skge_write16(hw, SK_GMAC_REG(port, r), (u16) v);
+	skge_write32(hw, SK_GMAC_REG(port, r+4), (u16)(v >> 16));
 }
 
-static inline void skge_gma_write32(const struct skge_hw *hw, int port, int r, u32 v)
+static inline void gma_write8(const struct skge_hw *hw, int port, int r, u8 v)
 {
-	skge_write16(hw, SKGEGMA_REG(port, r), (u16) v);
-	skge_write32(hw, SKGEGMA_REG(port, r+4), (u16)(v >> 16));
+	skge_write8(hw, SK_GMAC_REG(port,r), v);
 }
 
-static inline void skge_gma_write8(const struct skge_hw *hw, int port, int r, u8 v)
-{
-	skge_write8(hw, SKGEGMA_REG(port,r), v);
-}
-
-static inline void skge_gm_set_addr(struct skge_hw *hw, int port, int reg,
+static inline void gma_set_addr(struct skge_hw *hw, int port, int reg,
 				    const u8 *addr)
 {
-	skge_gma_write16(hw, port, reg,
-			 (u16) addr[0] | ((u16) addr[1] << 8));
-	skge_gma_write16(hw, port, reg+4,
-			 (u16) addr[2] | ((u16) addr[3] << 8));
-	skge_gma_write16(hw, port, reg+8,
-			 (u16) addr[4] | ((u16) addr[5] << 8));
+	gma_write16(hw, port, reg,  (u16) addr[0] | ((u16) addr[1] << 8));
+	gma_write16(hw, port, reg+4,(u16) addr[2] | ((u16) addr[3] << 8));
+	gma_write16(hw, port, reg+8,(u16) addr[4] | ((u16) addr[5] << 8));
 }
-		
+
 #endif
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 16363b5..404ea42 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -74,6 +74,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/if_arp.h>
 #include <linux/if_slip.h>
+#include <linux/delay.h>
 #include <linux/init.h>
 #include "slip.h"
 #ifdef CONFIG_INET
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index cfb9d3c..1438fdd 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -1998,7 +1998,7 @@
       	if (retval)
       		goto err_out;
 
-	set_irq_type(dev->irq, IRQT_RISING);
+	set_irq_type(dev->irq, SMC_IRQ_TRIGGER_TYPE);
 
 #ifdef SMC_USE_PXA_DMA
 	{
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 946528e..7089d86 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -182,6 +182,16 @@
 #define SMC_insl(a, r, p, l)	readsl((a) + (r), p, l)
 #define SMC_outsl(a, r, p, l)	writesl((a) + (r), p, l)
 
+#include <asm/mach-types.h>
+#include <asm/arch/cpu.h>
+
+#define	SMC_IRQ_TRIGGER_TYPE (( \
+		   machine_is_omap_h2() \
+		|| machine_is_omap_h3() \
+		|| (machine_is_omap_innovator() && !cpu_is_omap150()) \
+	) ? IRQT_FALLING : IRQT_RISING)
+
+
 #elif	defined(CONFIG_SH_SH4202_MICRODEV)
 
 #define SMC_CAN_USE_8BIT	0
@@ -300,6 +310,9 @@
 
 #endif
 
+#ifndef	SMC_IRQ_TRIGGER_TYPE
+#define	SMC_IRQ_TRIGGER_TYPE	IRQT_RISING
+#endif
 
 #ifdef SMC_USE_PXA_DMA
 /*
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index 12e2b68..88b89dc 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -1286,7 +1286,7 @@
 		np->rx_info[i].skb = skb;
 		if (skb == NULL)
 			break;
-		np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
+		np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
 		skb->dev = dev;			/* Mark as being used by this device. */
 		/* Grrr, we cannot offset to correctly align the IP header. */
 		np->rx_ring[i].rxaddr = cpu_to_dma(np->rx_info[i].mapping | RxDescValid);
@@ -1572,7 +1572,7 @@
 			pci_dma_sync_single_for_cpu(np->pci_dev,
 						    np->rx_info[entry].mapping,
 						    pkt_len, PCI_DMA_FROMDEVICE);
-			eth_copy_and_sum(skb, np->rx_info[entry].skb->tail, pkt_len, 0);
+			eth_copy_and_sum(skb, np->rx_info[entry].skb->data, pkt_len, 0);
 			pci_dma_sync_single_for_device(np->pci_dev,
 						       np->rx_info[entry].mapping,
 						       pkt_len, PCI_DMA_FROMDEVICE);
@@ -1696,7 +1696,7 @@
 			if (skb == NULL)
 				break;	/* Better luck next round. */
 			np->rx_info[entry].mapping =
-				pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
+				pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
 			skb->dev = dev;	/* Mark as being used by this device. */
 			np->rx_ring[entry].rxaddr =
 				cpu_to_dma(np->rx_info[entry].mapping | RxDescValid);
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index 08cb717..d500a57 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -1028,7 +1028,7 @@
 		skb->dev = dev;		/* Mark as being used by this device. */
 		skb_reserve(skb, 2);	/* 16 byte align the IP header. */
 		np->rx_ring[i].frag[0].addr = cpu_to_le32(
-			pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz,
+			pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz,
 				PCI_DMA_FROMDEVICE));
 		np->rx_ring[i].frag[0].length = cpu_to_le32(np->rx_buf_sz | LastFrag);
 	}
@@ -1341,7 +1341,7 @@
 							    np->rx_buf_sz,
 							    PCI_DMA_FROMDEVICE);
 
-				eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0);
+				eth_copy_and_sum(skb, np->rx_skbuff[entry]->data, pkt_len, 0);
 				pci_dma_sync_single_for_device(np->pci_dev,
 							       desc->frag[0].addr,
 							       np->rx_buf_sz,
@@ -1400,7 +1400,7 @@
 			skb->dev = dev;		/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
 			np->rx_ring[entry].frag[0].addr = cpu_to_le32(
-				pci_map_single(np->pci_dev, skb->tail,
+				pci_map_single(np->pci_dev, skb->data,
 					np->rx_buf_sz, PCI_DMA_FROMDEVICE));
 		}
 		/* Perhaps we need not reset this field. */
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 7e371b1..5464068 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -66,8 +66,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"3.32"
-#define DRV_MODULE_RELDATE	"June 24, 2005"
+#define DRV_MODULE_VERSION	"3.33"
+#define DRV_MODULE_RELDATE	"July 5, 2005"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -5117,7 +5117,7 @@
 }
 
 static void __tg3_set_rx_mode(struct net_device *);
-static void tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
+static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
 {
 	tw32(HOSTCC_RXCOL_TICKS, ec->rx_coalesce_usecs);
 	tw32(HOSTCC_TXCOL_TICKS, ec->tx_coalesce_usecs);
@@ -5460,7 +5460,7 @@
 		udelay(10);
 	}
 
-	tg3_set_coalesce(tp, &tp->coal);
+	__tg3_set_coalesce(tp, &tp->coal);
 
 	/* set status block DMA address */
 	tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH,
@@ -7821,6 +7821,60 @@
 	return 0;
 }
 
+static int tg3_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
+{
+	struct tg3 *tp = netdev_priv(dev);
+	u32 max_rxcoal_tick_int = 0, max_txcoal_tick_int = 0;
+	u32 max_stat_coal_ticks = 0, min_stat_coal_ticks = 0;
+
+	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+		max_rxcoal_tick_int = MAX_RXCOAL_TICK_INT;
+		max_txcoal_tick_int = MAX_TXCOAL_TICK_INT;
+		max_stat_coal_ticks = MAX_STAT_COAL_TICKS;
+		min_stat_coal_ticks = MIN_STAT_COAL_TICKS;
+	}
+
+	if ((ec->rx_coalesce_usecs > MAX_RXCOL_TICKS) ||
+	    (ec->tx_coalesce_usecs > MAX_TXCOL_TICKS) ||
+	    (ec->rx_max_coalesced_frames > MAX_RXMAX_FRAMES) ||
+	    (ec->tx_max_coalesced_frames > MAX_TXMAX_FRAMES) ||
+	    (ec->rx_coalesce_usecs_irq > max_rxcoal_tick_int) ||
+	    (ec->tx_coalesce_usecs_irq > max_txcoal_tick_int) ||
+	    (ec->rx_max_coalesced_frames_irq > MAX_RXCOAL_MAXF_INT) ||
+	    (ec->tx_max_coalesced_frames_irq > MAX_TXCOAL_MAXF_INT) ||
+	    (ec->stats_block_coalesce_usecs > max_stat_coal_ticks) ||
+	    (ec->stats_block_coalesce_usecs < min_stat_coal_ticks))
+		return -EINVAL;
+
+	/* No rx interrupts will be generated if both are zero */
+	if ((ec->rx_coalesce_usecs == 0) &&
+	    (ec->rx_max_coalesced_frames == 0))
+		return -EINVAL;
+
+	/* No tx interrupts will be generated if both are zero */
+	if ((ec->tx_coalesce_usecs == 0) &&
+	    (ec->tx_max_coalesced_frames == 0))
+		return -EINVAL;
+
+	/* Only copy relevant parameters, ignore all others. */
+	tp->coal.rx_coalesce_usecs = ec->rx_coalesce_usecs;
+	tp->coal.tx_coalesce_usecs = ec->tx_coalesce_usecs;
+	tp->coal.rx_max_coalesced_frames = ec->rx_max_coalesced_frames;
+	tp->coal.tx_max_coalesced_frames = ec->tx_max_coalesced_frames;
+	tp->coal.rx_coalesce_usecs_irq = ec->rx_coalesce_usecs_irq;
+	tp->coal.tx_coalesce_usecs_irq = ec->tx_coalesce_usecs_irq;
+	tp->coal.rx_max_coalesced_frames_irq = ec->rx_max_coalesced_frames_irq;
+	tp->coal.tx_max_coalesced_frames_irq = ec->tx_max_coalesced_frames_irq;
+	tp->coal.stats_block_coalesce_usecs = ec->stats_block_coalesce_usecs;
+
+	if (netif_running(dev)) {
+		tg3_full_lock(tp, 0);
+		__tg3_set_coalesce(tp, &tp->coal);
+		tg3_full_unlock(tp);
+	}
+	return 0;
+}
+
 static struct ethtool_ops tg3_ethtool_ops = {
 	.get_settings		= tg3_get_settings,
 	.set_settings		= tg3_set_settings,
@@ -7856,6 +7910,7 @@
 	.get_stats_count	= tg3_get_stats_count,
 	.get_ethtool_stats	= tg3_get_ethtool_stats,
 	.get_coalesce		= tg3_get_coalesce,
+	.set_coalesce		= tg3_set_coalesce,
 };
 
 static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
@@ -9800,6 +9855,12 @@
 		ec->tx_coalesce_usecs = LOW_TXCOL_TICKS_CLRTCKS;
 		ec->tx_coalesce_usecs_irq = DEFAULT_TXCOAL_TICK_INT_CLRTCKS;
 	}
+
+	if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+		ec->rx_coalesce_usecs_irq = 0;
+		ec->tx_coalesce_usecs_irq = 0;
+		ec->stats_block_coalesce_usecs = 0;
+	}
 }
 
 static int __devinit tg3_init_one(struct pci_dev *pdev,
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 99c5f96..70ad450 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -879,31 +879,41 @@
 #define  LOW_RXCOL_TICKS_CLRTCKS	 0x00000014
 #define  DEFAULT_RXCOL_TICKS		 0x00000048
 #define  HIGH_RXCOL_TICKS		 0x00000096
+#define  MAX_RXCOL_TICKS		 0x000003ff
 #define HOSTCC_TXCOL_TICKS		0x00003c0c
 #define  LOW_TXCOL_TICKS		 0x00000096
 #define  LOW_TXCOL_TICKS_CLRTCKS	 0x00000048
 #define  DEFAULT_TXCOL_TICKS		 0x0000012c
 #define  HIGH_TXCOL_TICKS		 0x00000145
+#define  MAX_TXCOL_TICKS		 0x000003ff
 #define HOSTCC_RXMAX_FRAMES		0x00003c10
 #define  LOW_RXMAX_FRAMES		 0x00000005
 #define  DEFAULT_RXMAX_FRAMES		 0x00000008
 #define  HIGH_RXMAX_FRAMES		 0x00000012
+#define  MAX_RXMAX_FRAMES		 0x000000ff
 #define HOSTCC_TXMAX_FRAMES		0x00003c14
 #define  LOW_TXMAX_FRAMES		 0x00000035
 #define  DEFAULT_TXMAX_FRAMES		 0x0000004b
 #define  HIGH_TXMAX_FRAMES		 0x00000052
+#define  MAX_TXMAX_FRAMES		 0x000000ff
 #define HOSTCC_RXCOAL_TICK_INT		0x00003c18
 #define  DEFAULT_RXCOAL_TICK_INT	 0x00000019
 #define  DEFAULT_RXCOAL_TICK_INT_CLRTCKS 0x00000014
+#define  MAX_RXCOAL_TICK_INT		 0x000003ff
 #define HOSTCC_TXCOAL_TICK_INT		0x00003c1c
 #define  DEFAULT_TXCOAL_TICK_INT	 0x00000019
 #define  DEFAULT_TXCOAL_TICK_INT_CLRTCKS 0x00000014
+#define  MAX_TXCOAL_TICK_INT		 0x000003ff
 #define HOSTCC_RXCOAL_MAXF_INT		0x00003c20
 #define  DEFAULT_RXCOAL_MAXF_INT	 0x00000005
+#define  MAX_RXCOAL_MAXF_INT		 0x000000ff
 #define HOSTCC_TXCOAL_MAXF_INT		0x00003c24
 #define  DEFAULT_TXCOAL_MAXF_INT	 0x00000005
+#define  MAX_TXCOAL_MAXF_INT		 0x000000ff
 #define HOSTCC_STAT_COAL_TICKS		0x00003c28
 #define  DEFAULT_STAT_COAL_TICKS	 0x000f4240
+#define  MAX_STAT_COAL_TICKS		 0xd693d400
+#define  MIN_STAT_COAL_TICKS		 0x00000064
 /* 0x3c2c --> 0x3c30 unused */
 #define HOSTCC_STATS_BLK_HOST_ADDR	0x00003c30 /* 64-bit */
 #define HOSTCC_STATUS_BLK_HOST_ADDR	0x00003c38 /* 64-bit */
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index dd357dd..fc353e3 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -446,13 +446,13 @@
 
 			mapping =
 			de->rx_skb[rx_tail].mapping =
-				pci_map_single(de->pdev, copy_skb->tail,
+				pci_map_single(de->pdev, copy_skb->data,
 					       buflen, PCI_DMA_FROMDEVICE);
 			de->rx_skb[rx_tail].skb = copy_skb;
 		} else {
 			pci_dma_sync_single_for_cpu(de->pdev, mapping, len, PCI_DMA_FROMDEVICE);
 			skb_reserve(copy_skb, RX_OFFSET);
-			memcpy(skb_put(copy_skb, len), skb->tail, len);
+			memcpy(skb_put(copy_skb, len), skb->data, len);
 
 			pci_dma_sync_single_for_device(de->pdev, mapping, len, PCI_DMA_FROMDEVICE);
 
@@ -1269,7 +1269,7 @@
 		skb->dev = de->dev;
 
 		de->rx_skb[i].mapping = pci_map_single(de->pdev,
-			skb->tail, de->rx_buf_sz, PCI_DMA_FROMDEVICE);
+			skb->data, de->rx_buf_sz, PCI_DMA_FROMDEVICE);
 		de->rx_skb[i].skb = skb;
 
 		de->rx_ring[i].opts1 = cpu_to_le32(DescOwn);
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
index 7b89970..74e9075 100644
--- a/drivers/net/tulip/dmfe.c
+++ b/drivers/net/tulip/dmfe.c
@@ -945,8 +945,8 @@
 
 				/* Received Packet CRC check need or not */
 				if ( (db->dm910x_chk_mode & 1) &&
-					(cal_CRC(skb->tail, rxlen, 1) !=
-					(*(u32 *) (skb->tail+rxlen) ))) { /* FIXME (?) */
+					(cal_CRC(skb->data, rxlen, 1) !=
+					(*(u32 *) (skb->data+rxlen) ))) { /* FIXME (?) */
 					/* Found a error received packet */
 					dmfe_reuse_skb(db, rxptr->rx_skb_ptr);
 					db->dm910x_chk_mode = 3;
@@ -959,7 +959,7 @@
 						/* size less than COPY_SIZE, allocate a rxlen SKB */
 						skb->dev = dev;
 						skb_reserve(skb, 2); /* 16byte align */
-						memcpy(skb_put(skb, rxlen), rxptr->rx_skb_ptr->tail, rxlen);
+						memcpy(skb_put(skb, rxlen), rxptr->rx_skb_ptr->data, rxlen);
 						dmfe_reuse_skb(db, rxptr->rx_skb_ptr);
 					} else {
 						skb->dev = dev;
@@ -1252,7 +1252,7 @@
 
 	if (!(rxptr->rdes0 & cpu_to_le32(0x80000000))) {
 		rxptr->rx_skb_ptr = skb;
-		rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->tail, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) );
+		rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->data, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) );
 		wmb();
 		rxptr->rdes0 = cpu_to_le32(0x80000000);
 		db->rx_avail_cnt++;
@@ -1463,7 +1463,7 @@
 		if ( ( skb = dev_alloc_skb(RX_ALLOC_SIZE) ) == NULL )
 			break;
 		rxptr->rx_skb_ptr = skb; /* FIXME (?) */
-		rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->tail, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) );
+		rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->data, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) );
 		wmb();
 		rxptr->rdes0 = cpu_to_le32(0x80000000);
 		rxptr = rxptr->next_rx_desc;
diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c
index afb5cda..bb35581 100644
--- a/drivers/net/tulip/interrupt.c
+++ b/drivers/net/tulip/interrupt.c
@@ -78,7 +78,7 @@
 			if (skb == NULL)
 				break;
 
-			mapping = pci_map_single(tp->pdev, skb->tail, PKT_BUF_SZ,
+			mapping = pci_map_single(tp->pdev, skb->data, PKT_BUF_SZ,
 						 PCI_DMA_FROMDEVICE);
 			tp->rx_buffers[entry].mapping = mapping;
 
@@ -199,12 +199,12 @@
 								   tp->rx_buffers[entry].mapping,
 								   pkt_len, PCI_DMA_FROMDEVICE);
 #if ! defined(__alpha__)
-                                       eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail,
+                                       eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->data,
                                                         pkt_len, 0);
                                        skb_put(skb, pkt_len);
 #else
                                        memcpy(skb_put(skb, pkt_len),
-                                              tp->rx_buffers[entry].skb->tail,
+                                              tp->rx_buffers[entry].skb->data,
                                               pkt_len);
 #endif
                                        pci_dma_sync_single_for_device(tp->pdev,
@@ -423,12 +423,12 @@
 							    tp->rx_buffers[entry].mapping,
 							    pkt_len, PCI_DMA_FROMDEVICE);
 #if ! defined(__alpha__)
-				eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail,
+				eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->data,
 						 pkt_len, 0);
 				skb_put(skb, pkt_len);
 #else
 				memcpy(skb_put(skb, pkt_len),
-				       tp->rx_buffers[entry].skb->tail,
+				       tp->rx_buffers[entry].skb->data,
 				       pkt_len);
 #endif
 				pci_dma_sync_single_for_device(tp->pdev,
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index 08e0f80..d45d8f5 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -625,7 +625,7 @@
 		tp->rx_buffers[i].skb = skb;
 		if (skb == NULL)
 			break;
-		mapping = pci_map_single(tp->pdev, skb->tail,
+		mapping = pci_map_single(tp->pdev, skb->data,
 					 PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
 		tp->rx_buffers[i].mapping = mapping;
 		skb->dev = dev;			/* Mark as being used by this device. */
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index db4b32c..5b1af39 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -849,7 +849,7 @@
 		if (skb == NULL)
 			break;
 		skb->dev = dev;			/* Mark as being used by this device. */
-		np->rx_addr[i] = pci_map_single(np->pci_dev,skb->tail,
+		np->rx_addr[i] = pci_map_single(np->pci_dev,skb->data,
 					skb->len,PCI_DMA_FROMDEVICE);
 
 		np->rx_ring[i].buffer1 = np->rx_addr[i];
@@ -1269,7 +1269,7 @@
 				pci_dma_sync_single_for_cpu(np->pci_dev,np->rx_addr[entry],
 							    np->rx_skbuff[entry]->len,
 							    PCI_DMA_FROMDEVICE);
-				eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0);
+				eth_copy_and_sum(skb, np->rx_skbuff[entry]->data, pkt_len, 0);
 				skb_put(skb, pkt_len);
 				pci_dma_sync_single_for_device(np->pci_dev,np->rx_addr[entry],
 							       np->rx_skbuff[entry]->len,
@@ -1315,7 +1315,7 @@
 				break;			/* Better luck next round. */
 			skb->dev = dev;			/* Mark as being used by this device. */
 			np->rx_addr[entry] = pci_map_single(np->pci_dev,
-							skb->tail,
+							skb->data,
 							skb->len, PCI_DMA_FROMDEVICE);
 			np->rx_ring[entry].buffer1 = np->rx_addr[entry];
 		}
diff --git a/drivers/net/tulip/xircom_tulip_cb.c b/drivers/net/tulip/xircom_tulip_cb.c
index b8a9b39..887d724 100644
--- a/drivers/net/tulip/xircom_tulip_cb.c
+++ b/drivers/net/tulip/xircom_tulip_cb.c
@@ -899,7 +899,7 @@
 			break;
 		skb->dev = dev;			/* Mark as being used by this device. */
 		tp->rx_ring[i].status = Rx0DescOwned;	/* Owned by Xircom chip */
-		tp->rx_ring[i].buffer1 = virt_to_bus(skb->tail);
+		tp->rx_ring[i].buffer1 = virt_to_bus(skb->data);
 	}
 	tp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
 
@@ -1291,7 +1291,7 @@
 			if (skb == NULL)
 				break;
 			skb->dev = dev;			/* Mark as being used by this device. */
-			tp->rx_ring[entry].buffer1 = virt_to_bus(skb->tail);
+			tp->rx_ring[entry].buffer1 = virt_to_bus(skb->data);
 			work_done++;
 		}
 		tp->rx_ring[entry].status = Rx0DescOwned;
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 8f33929..0b5ca25 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -1661,7 +1661,7 @@
 #endif
 
 	skb->dev = tp->dev;
-	dma_addr = pci_map_single(tp->pdev, skb->tail,
+	dma_addr = pci_map_single(tp->pdev, skb->data,
 				  PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
 
 	/* Since no card does 64 bit DAC, the high bits will never
@@ -1721,7 +1721,7 @@
 			pci_dma_sync_single_for_cpu(tp->pdev, dma_addr,
 						    PKT_BUF_SZ,
 						    PCI_DMA_FROMDEVICE);
-			eth_copy_and_sum(new_skb, skb->tail, pkt_len, 0);
+			eth_copy_and_sum(new_skb, skb->data, pkt_len, 0);
 			pci_dma_sync_single_for_device(tp->pdev, dma_addr,
 						       PKT_BUF_SZ,
 						       PCI_DMA_FROMDEVICE);
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index be1c104..fc7738f 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -507,7 +507,7 @@
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static struct ethtool_ops netdev_ethtool_ops;
 static int  rhine_close(struct net_device *dev);
-static void rhine_shutdown (struct device *gdev);
+static void rhine_shutdown (struct pci_dev *pdev);
 
 #define RHINE_WAIT_FOR(condition) do {					\
 	int i=1024;							\
@@ -990,7 +990,7 @@
 		skb->dev = dev;                 /* Mark as being used by this device. */
 
 		rp->rx_skbuff_dma[i] =
-			pci_map_single(rp->pdev, skb->tail, rp->rx_buf_sz,
+			pci_map_single(rp->pdev, skb->data, rp->rx_buf_sz,
 				       PCI_DMA_FROMDEVICE);
 
 		rp->rx_ring[i].addr = cpu_to_le32(rp->rx_skbuff_dma[i]);
@@ -1518,7 +1518,7 @@
 							    PCI_DMA_FROMDEVICE);
 
 				eth_copy_and_sum(skb,
-						 rp->rx_skbuff[entry]->tail,
+						 rp->rx_skbuff[entry]->data,
 						 pkt_len, 0);
 				skb_put(skb, pkt_len);
 				pci_dma_sync_single_for_device(rp->pdev,
@@ -1561,7 +1561,7 @@
 				break;	/* Better luck next round. */
 			skb->dev = dev;	/* Mark as being used by this device. */
 			rp->rx_skbuff_dma[entry] =
-				pci_map_single(rp->pdev, skb->tail,
+				pci_map_single(rp->pdev, skb->data,
 					       rp->rx_buf_sz,
 					       PCI_DMA_FROMDEVICE);
 			rp->rx_ring[entry].addr = cpu_to_le32(rp->rx_skbuff_dma[entry]);
@@ -1895,9 +1895,8 @@
 	pci_set_drvdata(pdev, NULL);
 }
 
-static void rhine_shutdown (struct device *gendev)
+static void rhine_shutdown (struct pci_dev *pdev)
 {
-	struct pci_dev *pdev = to_pci_dev(gendev);
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct rhine_private *rp = netdev_priv(dev);
 	void __iomem *ioaddr = rp->base;
@@ -1956,7 +1955,7 @@
 	pci_save_state(pdev);
 
 	spin_lock_irqsave(&rp->lock, flags);
-	rhine_shutdown(&pdev->dev);
+	rhine_shutdown(pdev);
 	spin_unlock_irqrestore(&rp->lock, flags);
 
 	free_irq(dev->irq, dev);
@@ -2010,9 +2009,7 @@
 	.suspend	= rhine_suspend,
 	.resume		= rhine_resume,
 #endif /* CONFIG_PM */
-	.driver = {
-		.shutdown = rhine_shutdown,
-	}
+	.shutdown =	rhine_shutdown,
 };
 
 
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 15e7102..abc5cee 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -1335,7 +1335,7 @@
 			if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN)
 				skb_reserve(new_skb, 2);
 
-			memcpy(new_skb->data, rx_skb[0]->tail, pkt_size);
+			memcpy(new_skb->data, rx_skb[0]->data, pkt_size);
 			*rx_skb = new_skb;
 			ret = 0;
 		}
@@ -1456,9 +1456,9 @@
 	 *	Do the gymnastics to get the buffer head for data at
 	 *	64byte alignment.
 	 */
-	skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->tail & 63);
+	skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->data & 63);
 	rd_info->skb->dev = vptr->dev;
-	rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->tail, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE);
+	rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE);
 	
 	/*
 	 *	Fill in the descriptor to match
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index c1b6896..8749684 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -72,7 +72,7 @@
 	}
 	skb_reserve(skb, 4);
 	cisco_hard_header(skb, dev, CISCO_KEEPALIVE, NULL, NULL, 0);
-	data = (cisco_packet*)skb->tail;
+	data = (cisco_packet*)skb->data;
 
 	data->type = htonl(type);
 	data->par1 = htonl(par1);
diff --git a/drivers/net/wireless/airport.c b/drivers/net/wireless/airport.c
index b4f4bd7..9d49670 100644
--- a/drivers/net/wireless/airport.c
+++ b/drivers/net/wireless/airport.c
@@ -184,7 +184,7 @@
 }
 
 static int
-airport_attach(struct macio_dev *mdev, const struct of_match *match)
+airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
 {
 	struct orinoco_private *priv;
 	struct net_device *dev;
@@ -266,16 +266,16 @@
 MODULE_DESCRIPTION("Driver for the Apple Airport wireless card.");
 MODULE_LICENSE("Dual MPL/GPL");
 
-static struct of_match airport_match[] = 
+static struct of_device_id airport_match[] = 
 {
 	{
 	.name 		= "radio",
-	.type		= OF_ANY_MATCH,
-	.compatible	= OF_ANY_MATCH
 	},
 	{},
 };
 
+MODULE_DEVICE_TABLE (of, airport_match);
+
 static struct macio_driver airport_driver = 
 {
 	.name 		= DRIVER_NAME,
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index 9da9254..1c25065 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -786,7 +786,7 @@
 		skb->dev = dev;		/* Mark as being used by this device. */
 		skb_reserve(skb, 2);	/* 16 byte align the IP header. */
 		yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev,
-			skb->tail, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+			skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
 	}
 	yp->rx_ring[i-1].dbdma_cmd = cpu_to_le32(CMD_STOP);
 	yp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
@@ -1111,7 +1111,7 @@
 		pci_dma_sync_single_for_cpu(yp->pci_dev, desc->addr,
 			yp->rx_buf_sz, PCI_DMA_FROMDEVICE);
 		desc_status = le32_to_cpu(desc->result_status) >> 16;
-		buf_addr = rx_skb->tail;
+		buf_addr = rx_skb->data;
 		data_size = (le32_to_cpu(desc->dbdma_cmd) - 
 			le32_to_cpu(desc->result_status)) & 0xffff;
 		frame_status = le16_to_cpu(get_unaligned((s16*)&(buf_addr[data_size - 2])));
@@ -1185,7 +1185,7 @@
 					break;
 				skb->dev = dev;
 				skb_reserve(skb, 2);	/* 16 byte align the IP header */
-				eth_copy_and_sum(skb, rx_skb->tail, pkt_len, 0);
+				eth_copy_and_sum(skb, rx_skb->data, pkt_len, 0);
 				skb_put(skb, pkt_len);
 				pci_dma_sync_single_for_device(yp->pci_dev, desc->addr,
 											   yp->rx_buf_sz,
@@ -1211,7 +1211,7 @@
 			skb->dev = dev;	/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
 			yp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(yp->pci_dev,
-				skb->tail, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+				skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
 		}
 		yp->rx_ring[entry].dbdma_cmd = cpu_to_le32(CMD_STOP);
 		yp->rx_ring[entry].result_status = 0;	/* Clear complete bit. */
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index b0d2a73..2f2dbef2 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -993,6 +993,7 @@
 	bus = pci_scan_bus_parented(&dev->dev, dino_current_bus,
 				    &dino_cfg_ops, NULL);
 	if(bus) {
+		pci_bus_add_devices(bus);
 		/* This code *depends* on scanning being single threaded
 		 * if it isn't, this global bus number count will fail
 		 */
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index dc83880..7fdd80b 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -1570,6 +1570,8 @@
 	lba_bus = lba_dev->hba.hba_bus =
 		pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start,
 				cfg_ops, NULL);
+	if (lba_bus)
+		pci_bus_add_devices(lba_bus);
 
 	/* This is in lieu of calling pci_assign_unassigned_resources() */
 	if (is_pdc_pat()) {
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 80edfa3..4598c6a 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -3008,7 +3008,7 @@
 	int ret = 0;
 
 	while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
-		id = pci_match_device (parport_pc_pci_tbl, pdev);
+		id = pci_match_id(parport_pc_pci_tbl, pdev);
 		if (id == NULL || id->driver_data >= last_sio)
 			continue;
 
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 7dea494..3657f61 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -19,6 +19,7 @@
 #
 # Some architectures use the generic PCI setup functions
 #
+obj-$(CONFIG_X86) += setup-bus.o
 obj-$(CONFIG_ALPHA) += setup-bus.o setup-irq.o
 obj-$(CONFIG_ARM) += setup-bus.o setup-irq.o
 obj-$(CONFIG_PARISC) += setup-bus.o
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index dbd3360..fedae89 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -121,10 +121,13 @@
 		 * If there is an unattached subordinate bus, attach
 		 * it and then scan for unattached PCI devices.
 		 */
-		if (dev->subordinate && list_empty(&dev->subordinate->node)) {
-			spin_lock(&pci_bus_lock);
-			list_add_tail(&dev->subordinate->node, &dev->bus->children);
-			spin_unlock(&pci_bus_lock);
+		if (dev->subordinate) {
+		       if (list_empty(&dev->subordinate->node)) {
+			       spin_lock(&pci_bus_lock);
+			       list_add_tail(&dev->subordinate->node,
+					       &dev->bus->children);
+			       spin_unlock(&pci_bus_lock);
+		       }
 			pci_bus_add_devices(dev->subordinate);
 
 			sysfs_create_link(&dev->subordinate->class_dev.kobj, &dev->dev.kobj, "bridge");
diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c
index 3903f8c..b844bc9 100644
--- a/drivers/pci/hotplug.c
+++ b/drivers/pci/hotplug.c
@@ -54,7 +54,7 @@
 
 	envp[i++] = scratch;
 	length += scnprintf (scratch, buffer_size - length,
-			    "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n",
+			    "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
 			    pdev->vendor, pdev->device,
 			    pdev->subsystem_vendor, pdev->subsystem_device,
 			    (u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
index 93c120d..3e632ff 100644
--- a/drivers/pci/hotplug/Makefile
+++ b/drivers/pci/hotplug/Makefile
@@ -36,9 +36,7 @@
 				ibmphp_hpc.o
 
 acpiphp-objs		:=	acpiphp_core.o	\
-				acpiphp_glue.o	\
-				acpiphp_pci.o	\
-				acpiphp_res.o
+				acpiphp_glue.o
 
 rpaphp-objs		:=	rpaphp_core.o	\
 				rpaphp_pci.o	\
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index d949987..293603e 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -7,6 +7,8 @@
  * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
  * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
  * Copyright (C) 2002,2003 NEC Corporation
+ * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com)
+ * Copyright (C) 2003-2005 Hewlett Packard
  *
  * All rights reserved.
  *
@@ -52,7 +54,6 @@
 
 struct acpiphp_bridge;
 struct acpiphp_slot;
-struct pci_resource;
 
 /*
  * struct slot - slot information for each *physical* slot
@@ -65,15 +66,6 @@
 	struct acpiphp_slot	*acpi_slot;
 };
 
-/*
- * struct pci_resource - describes pci resource (mem, pfmem, io, bus)
- */
-struct pci_resource {
-	struct pci_resource * next;
-	u64 base;
-	u32 length;
-};
-
 /**
  * struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters
  * @cache_line_size in DWORD
@@ -101,10 +93,6 @@
 	int type;
 	int nr_slots;
 
-	u8 seg;
-	u8 bus;
-	u8 sub;
-
 	u32 flags;
 
 	/* This bus (host bridge) or Secondary bus (PCI-to-PCI bridge) */
@@ -117,12 +105,6 @@
 	struct hpp_param hpp;
 
 	spinlock_t res_lock;
-
-	/* available resources on this bus */
-	struct pci_resource *mem_head;
-	struct pci_resource *p_mem_head;
-	struct pci_resource *io_head;
-	struct pci_resource *bus_head;
 };
 
 
@@ -163,12 +145,6 @@
 
 	u8		function;	/* pci function# */
 	u32		flags;		/* see below */
-
-	/* resources used for this function */
-	struct pci_resource *mem_head;
-	struct pci_resource *p_mem_head;
-	struct pci_resource *io_head;
-	struct pci_resource *bus_head;
 };
 
 /**
@@ -243,25 +219,6 @@
 extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot);
 extern u32 acpiphp_get_address (struct acpiphp_slot *slot);
 
-/* acpiphp_pci.c */
-extern struct pci_dev *acpiphp_allocate_pcidev (struct pci_bus *pbus, int dev, int fn);
-extern int acpiphp_configure_slot (struct acpiphp_slot *slot);
-extern int acpiphp_configure_function (struct acpiphp_func *func);
-extern void acpiphp_unconfigure_function (struct acpiphp_func *func);
-extern int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge);
-extern int acpiphp_init_func_resource (struct acpiphp_func *func);
-
-/* acpiphp_res.c */
-extern struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size);
-extern struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size);
-extern struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size);
-extern int acpiphp_resource_sort_and_combine (struct pci_resource **head);
-extern struct pci_resource *acpiphp_make_resource (u64 base, u32 length);
-extern void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to);
-extern void acpiphp_free_resource (struct pci_resource **res);
-extern void acpiphp_dump_resource (struct acpiphp_bridge *bridge); /* debug */
-extern void acpiphp_dump_func_resource (struct acpiphp_func *func); /* debug */
-
 /* variables */
 extern int acpiphp_debug;
 
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index 4539e61..60c4c38 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -7,6 +7,8 @@
  * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
  * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
  * Copyright (C) 2002,2003 NEC Corporation
+ * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com)
+ * Copyright (C) 2003-2005 Hewlett Packard
  *
  * All rights reserved.
  *
@@ -53,8 +55,8 @@
 static int num_slots;
 static struct acpiphp_attention_info *attention_info;
 
-#define DRIVER_VERSION	"0.4"
-#define DRIVER_AUTHOR	"Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kochi@bq.jp.nec.com>"
+#define DRIVER_VERSION	"0.5"
+#define DRIVER_AUTHOR	"Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kochi@bq.jp.nec.com>, Matthew Wilcox <willy@hp.com>"
 #define DRIVER_DESC	"ACPI Hot Plug PCI Controller Driver"
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
@@ -281,8 +283,7 @@
 /**
  * get_address - get pci address of a slot
  * @hotplug_slot: slot to get status
- * @busdev: pointer to struct pci_busdev (seg, bus, dev)
- *
+ * @value: pointer to struct pci_busdev (seg, bus, dev)
  */
 static int get_address(struct hotplug_slot *hotplug_slot, u32 *value)
 {
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index e7f4129..424e7de 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -4,6 +4,10 @@
  * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
  * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
  * Copyright (C) 2002,2003 NEC Corporation
+ * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com)
+ * Copyright (C) 2003-2005 Hewlett Packard
+ * Copyright (C) 2005 Rajesh Shah (rajesh.shah@intel.com)
+ * Copyright (C) 2005 Intel Corporation
  *
  * All rights reserved.
  *
@@ -26,6 +30,16 @@
  *
  */
 
+/*
+ * Lifetime rules for pci_dev:
+ *  - The one in acpiphp_func has its refcount elevated by pci_get_slot()
+ *    when the driver is loaded or when an insertion event occurs.  It loses
+ *    a refcount when its ejected or the driver unloads.
+ *  - The one in acpiphp_bridge has its refcount elevated by pci_get_slot()
+ *    when the bridge is scanned and it loses a refcount when the bridge
+ *    is removed.
+ */
+
 #include <linux/init.h>
 #include <linux/module.h>
 
@@ -178,21 +192,18 @@
 
 		bridge->nr_slots++;
 
-		dbg("found ACPI PCI Hotplug slot at PCI %02x:%02x Slot:%d\n",
-		    slot->bridge->bus, slot->device, slot->sun);
+		dbg("found ACPI PCI Hotplug slot %d at PCI %04x:%02x:%02x\n",
+				slot->sun, pci_domain_nr(bridge->pci_bus),
+				bridge->pci_bus->number, slot->device);
 	}
 
 	newfunc->slot = slot;
 	list_add_tail(&newfunc->sibling, &slot->funcs);
 
 	/* associate corresponding pci_dev */
-	newfunc->pci_dev = pci_find_slot(bridge->bus,
+	newfunc->pci_dev = pci_get_slot(bridge->pci_bus,
 					 PCI_DEVFN(device, function));
 	if (newfunc->pci_dev) {
-		if (acpiphp_init_func_resource(newfunc) < 0) {
-			kfree(newfunc);
-			return AE_ERROR;
-		}
 		slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);
 	}
 
@@ -227,62 +238,6 @@
 }
 
 
-/* decode ACPI _CRS data and convert into our internal resource list
- * TBD: _TRA, etc.
- */
-static acpi_status
-decode_acpi_resource(struct acpi_resource *resource, void *context)
-{
-	struct acpiphp_bridge *bridge = (struct acpiphp_bridge *) context;
-	struct acpi_resource_address64 address;
-	struct pci_resource *res;
-
-	if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
-	    resource->id != ACPI_RSTYPE_ADDRESS32 &&
-	    resource->id != ACPI_RSTYPE_ADDRESS64)
-		return AE_OK;
-
-	acpi_resource_to_address64(resource, &address);
-
-	if (address.producer_consumer == ACPI_PRODUCER && address.address_length > 0) {
-		dbg("resource type: %d: 0x%llx - 0x%llx\n", address.resource_type,
-		    (unsigned long long)address.min_address_range,
-		    (unsigned long long)address.max_address_range);
-		res = acpiphp_make_resource(address.min_address_range,
-				    address.address_length);
-		if (!res) {
-			err("out of memory\n");
-			return AE_OK;
-		}
-
-		switch (address.resource_type) {
-		case ACPI_MEMORY_RANGE:
-			if (address.attribute.memory.cache_attribute == ACPI_PREFETCHABLE_MEMORY) {
-				res->next = bridge->p_mem_head;
-				bridge->p_mem_head = res;
-			} else {
-				res->next = bridge->mem_head;
-				bridge->mem_head = res;
-			}
-			break;
-		case ACPI_IO_RANGE:
-			res->next = bridge->io_head;
-			bridge->io_head = res;
-			break;
-		case ACPI_BUS_NUMBER_RANGE:
-			res->next = bridge->bus_head;
-			bridge->bus_head = res;
-			break;
-		default:
-			/* invalid type */
-			kfree(res);
-			break;
-		}
-	}
-
-	return AE_OK;
-}
-
 /* decode ACPI 2.0 _HPP hot plug parameters */
 static void decode_hpp(struct acpiphp_bridge *bridge)
 {
@@ -346,34 +301,29 @@
 	/* decode ACPI 2.0 _HPP (hot plug parameters) */
 	decode_hpp(bridge);
 
-	/* subtract all resources already allocated */
-	acpiphp_detect_pci_resource(bridge);
-
 	/* register all slot objects under this bridge */
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1,
 				     register_slot, bridge, NULL);
 
 	/* install notify handler */
-	status = acpi_install_notify_handler(bridge->handle,
+	if (bridge->type != BRIDGE_TYPE_HOST) {
+		status = acpi_install_notify_handler(bridge->handle,
 					     ACPI_SYSTEM_NOTIFY,
 					     handle_hotplug_event_bridge,
 					     bridge);
 
-	if (ACPI_FAILURE(status)) {
-		err("failed to register interrupt notify handler\n");
+		if (ACPI_FAILURE(status)) {
+			err("failed to register interrupt notify handler\n");
+		}
 	}
 
 	list_add(&bridge->list, &bridge_list);
-
-	dbg("Bridge resource:\n");
-	acpiphp_dump_resource(bridge);
 }
 
 
 /* allocate and initialize host bridge data structure */
-static void add_host_bridge(acpi_handle *handle, int seg, int bus)
+static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus)
 {
-	acpi_status status;
 	struct acpiphp_bridge *bridge;
 
 	bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
@@ -384,52 +334,19 @@
 
 	bridge->type = BRIDGE_TYPE_HOST;
 	bridge->handle = handle;
-	bridge->seg = seg;
-	bridge->bus = bus;
 
-	bridge->pci_bus = pci_find_bus(seg, bus);
+	bridge->pci_bus = pci_bus;
 
 	spin_lock_init(&bridge->res_lock);
 
-	/* to be overridden when we decode _CRS	*/
-	bridge->sub = bridge->bus;
-
-	/* decode resources */
-
-	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
-		decode_acpi_resource, bridge);
-
-	if (ACPI_FAILURE(status)) {
-		err("failed to decode bridge resources\n");
-		kfree(bridge);
-		return;
-	}
-
-	acpiphp_resource_sort_and_combine(&bridge->io_head);
-	acpiphp_resource_sort_and_combine(&bridge->mem_head);
-	acpiphp_resource_sort_and_combine(&bridge->p_mem_head);
-	acpiphp_resource_sort_and_combine(&bridge->bus_head);
-
-	dbg("ACPI _CRS resource:\n");
-	acpiphp_dump_resource(bridge);
-
-	if (bridge->bus_head) {
-		bridge->bus = bridge->bus_head->base;
-		bridge->sub = bridge->bus_head->base + bridge->bus_head->length - 1;
-	}
-
 	init_bridge_misc(bridge);
 }
 
 
 /* allocate and initialize PCI-to-PCI bridge data structure */
-static void add_p2p_bridge(acpi_handle *handle, int seg, int bus, int dev, int fn)
+static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev)
 {
 	struct acpiphp_bridge *bridge;
-	u8 tmp8;
-	u16 tmp16;
-	u64 base64, limit64;
-	u32 base, limit, base32u, limit32u;
 
 	bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
 	if (bridge == NULL) {
@@ -441,133 +358,22 @@
 
 	bridge->type = BRIDGE_TYPE_P2P;
 	bridge->handle = handle;
-	bridge->seg = seg;
 
-	bridge->pci_dev = pci_find_slot(bus, PCI_DEVFN(dev, fn));
-	if (!bridge->pci_dev) {
-		err("Can't get pci_dev\n");
-		kfree(bridge);
-		return;
-	}
-
-	bridge->pci_bus = bridge->pci_dev->subordinate;
+	bridge->pci_dev = pci_dev_get(pci_dev);
+	bridge->pci_bus = pci_dev->subordinate;
 	if (!bridge->pci_bus) {
 		err("This is not a PCI-to-PCI bridge!\n");
-		kfree(bridge);
-		return;
+		goto err;
 	}
 
 	spin_lock_init(&bridge->res_lock);
 
-	bridge->bus = bridge->pci_bus->number;
-	bridge->sub = bridge->pci_bus->subordinate;
-
-	/*
-	 * decode resources under this P2P bridge
-	 */
-
-	/* I/O resources */
-	pci_read_config_byte(bridge->pci_dev, PCI_IO_BASE, &tmp8);
-	base = tmp8;
-	pci_read_config_byte(bridge->pci_dev, PCI_IO_LIMIT, &tmp8);
-	limit = tmp8;
-
-	switch (base & PCI_IO_RANGE_TYPE_MASK) {
-	case PCI_IO_RANGE_TYPE_16:
-		base = (base << 8) & 0xf000;
-		limit = ((limit << 8) & 0xf000) + 0xfff;
-		bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
-		if (!bridge->io_head) {
-			err("out of memory\n");
-			kfree(bridge);
-			return;
-		}
-		dbg("16bit I/O range: %04x-%04x\n",
-		    (u32)bridge->io_head->base,
-		    (u32)(bridge->io_head->base + bridge->io_head->length - 1));
-		break;
-	case PCI_IO_RANGE_TYPE_32:
-		pci_read_config_word(bridge->pci_dev, PCI_IO_BASE_UPPER16, &tmp16);
-		base = ((u32)tmp16 << 16) | ((base << 8) & 0xf000);
-		pci_read_config_word(bridge->pci_dev, PCI_IO_LIMIT_UPPER16, &tmp16);
-		limit = (((u32)tmp16 << 16) | ((limit << 8) & 0xf000)) + 0xfff;
-		bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
-		if (!bridge->io_head) {
-			err("out of memory\n");
-			kfree(bridge);
-			return;
-		}
-		dbg("32bit I/O range: %08x-%08x\n",
-		    (u32)bridge->io_head->base,
-		    (u32)(bridge->io_head->base + bridge->io_head->length - 1));
-		break;
-	case 0x0f:
-		dbg("I/O space unsupported\n");
-		break;
-	default:
-		warn("Unknown I/O range type\n");
-	}
-
-	/* Memory resources (mandatory for P2P bridge) */
-	pci_read_config_word(bridge->pci_dev, PCI_MEMORY_BASE, &tmp16);
-	base = (tmp16 & 0xfff0) << 16;
-	pci_read_config_word(bridge->pci_dev, PCI_MEMORY_LIMIT, &tmp16);
-	limit = ((tmp16 & 0xfff0) << 16) | 0xfffff;
-	bridge->mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
-	if (!bridge->mem_head) {
-		err("out of memory\n");
-		kfree(bridge);
-		return;
-	}
-	dbg("32bit Memory range: %08x-%08x\n",
-	    (u32)bridge->mem_head->base,
-	    (u32)(bridge->mem_head->base + bridge->mem_head->length-1));
-
-	/* Prefetchable Memory resources (optional) */
-	pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_BASE, &tmp16);
-	base = tmp16;
-	pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_LIMIT, &tmp16);
-	limit = tmp16;
-
-	switch (base & PCI_MEMORY_RANGE_TYPE_MASK) {
-	case PCI_PREF_RANGE_TYPE_32:
-		base = (base & 0xfff0) << 16;
-		limit = ((limit & 0xfff0) << 16) | 0xfffff;
-		bridge->p_mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
-		if (!bridge->p_mem_head) {
-			err("out of memory\n");
-			kfree(bridge);
-			return;
-		}
-		dbg("32bit Prefetchable memory range: %08x-%08x\n",
-		    (u32)bridge->p_mem_head->base,
-		    (u32)(bridge->p_mem_head->base + bridge->p_mem_head->length - 1));
-		break;
-	case PCI_PREF_RANGE_TYPE_64:
-		pci_read_config_dword(bridge->pci_dev, PCI_PREF_BASE_UPPER32, &base32u);
-		pci_read_config_dword(bridge->pci_dev, PCI_PREF_LIMIT_UPPER32, &limit32u);
-		base64 = ((u64)base32u << 32) | ((base & 0xfff0) << 16);
-		limit64 = (((u64)limit32u << 32) | ((limit & 0xfff0) << 16)) + 0xfffff;
-
-		bridge->p_mem_head = acpiphp_make_resource(base64, limit64 - base64 + 1);
-		if (!bridge->p_mem_head) {
-			err("out of memory\n");
-			kfree(bridge);
-			return;
-		}
-		dbg("64bit Prefetchable memory range: %08x%08x-%08x%08x\n",
-		    (u32)(bridge->p_mem_head->base >> 32),
-		    (u32)(bridge->p_mem_head->base & 0xffffffff),
-		    (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) >> 32),
-		    (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) & 0xffffffff));
-		break;
-	case 0x0f:
-		break;
-	default:
-		warn("Unknown prefetchale memory type\n");
-	}
-
 	init_bridge_misc(bridge);
+	return;
+ err:
+	pci_dev_put(pci_dev);
+	kfree(bridge);
+	return;
 }
 
 
@@ -577,14 +383,10 @@
 {
 	acpi_status status;
 	acpi_handle dummy_handle;
-	unsigned long *segbus = context;
 	unsigned long tmp;
-	int seg, bus, device, function;
+	int device, function;
 	struct pci_dev *dev;
-
-	/* get PCI address */
-	seg = (*segbus >> 8) & 0xff;
-	bus = *segbus & 0xff;
+	struct pci_bus *pci_bus = context;
 
 	status = acpi_get_handle(handle, "_ADR", &dummy_handle);
 	if (ACPI_FAILURE(status))
@@ -599,20 +401,19 @@
 	device = (tmp >> 16) & 0xffff;
 	function = tmp & 0xffff;
 
-	dev = pci_find_slot(bus, PCI_DEVFN(device, function));
+	dev = pci_get_slot(pci_bus, PCI_DEVFN(device, function));
 
-	if (!dev)
-		return AE_OK;
-
-	if (!dev->subordinate)
-		return AE_OK;
+	if (!dev || !dev->subordinate)
+		goto out;
 
 	/* check if this bridge has ejectable slots */
 	if (detect_ejectable_slots(handle) > 0) {
 		dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev));
-		add_p2p_bridge(handle, seg, bus, device, function);
+		add_p2p_bridge(handle, dev);
 	}
 
+ out:
+	pci_dev_put(dev);
 	return AE_OK;
 }
 
@@ -624,6 +425,7 @@
 	unsigned long tmp;
 	int seg, bus;
 	acpi_handle dummy_handle;
+	struct pci_bus *pci_bus;
 
 	/* if the bridge doesn't have _STA, we assume it is always there */
 	status = acpi_get_handle(handle, "_STA", &dummy_handle);
@@ -653,18 +455,22 @@
 		bus = 0;
 	}
 
-	/* check if this bridge has ejectable slots */
-	if (detect_ejectable_slots(handle) > 0) {
-		dbg("found PCI host-bus bridge with hot-pluggable slots\n");
-		add_host_bridge(handle, seg, bus);
+	pci_bus = pci_find_bus(seg, bus);
+	if (!pci_bus) {
+		err("Can't find bus %04x:%02x\n", seg, bus);
 		return 0;
 	}
 
-	tmp = seg << 8 | bus;
+	/* check if this bridge has ejectable slots */
+	if (detect_ejectable_slots(handle) > 0) {
+		dbg("found PCI host-bus bridge with hot-pluggable slots\n");
+		add_host_bridge(handle, pci_bus);
+		return 0;
+	}
 
 	/* search P2P bridges under this host bridge */
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     find_p2p_bridge, &tmp, NULL);
+				     find_p2p_bridge, pci_bus, NULL);
 
 	if (ACPI_FAILURE(status))
 		warn("find_p2p_bridge faied (error code = 0x%x)\n",status);
@@ -672,12 +478,205 @@
 	return 0;
 }
 
+static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle)
+{
+	struct list_head *head;
+	list_for_each(head, &bridge_list) {
+		struct acpiphp_bridge *bridge = list_entry(head,
+						struct acpiphp_bridge, list);
+		if (bridge->handle == handle)
+			return bridge;
+	}
+
+	return NULL;
+}
+
+static void cleanup_bridge(struct acpiphp_bridge *bridge)
+{
+	struct list_head *list, *tmp;
+	struct acpiphp_slot *slot;
+	acpi_status status;
+	acpi_handle handle = bridge->handle;
+
+	status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+					    handle_hotplug_event_bridge);
+	if (ACPI_FAILURE(status))
+		err("failed to remove notify handler\n");
+
+	slot = bridge->slots;
+	while (slot) {
+		struct acpiphp_slot *next = slot->next;
+		list_for_each_safe (list, tmp, &slot->funcs) {
+			struct acpiphp_func *func;
+			func = list_entry(list, struct acpiphp_func, sibling);
+			status = acpi_remove_notify_handler(func->handle,
+						ACPI_SYSTEM_NOTIFY,
+						handle_hotplug_event_func);
+			if (ACPI_FAILURE(status))
+				err("failed to remove notify handler\n");
+			pci_dev_put(func->pci_dev);
+			list_del(list);
+			kfree(func);
+		}
+		kfree(slot);
+		slot = next;
+	}
+
+	pci_dev_put(bridge->pci_dev);
+	list_del(&bridge->list);
+	kfree(bridge);
+}
+
+static acpi_status
+cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	struct acpiphp_bridge *bridge;
+
+	if (!(bridge = acpiphp_handle_to_bridge(handle)))
+		return AE_OK;
+	cleanup_bridge(bridge);
+	return AE_OK;
+}
 
 static void remove_bridge(acpi_handle handle)
 {
-	/* No-op for now .. */
+	struct acpiphp_bridge *bridge;
+
+	bridge = acpiphp_handle_to_bridge(handle);
+	if (bridge) {
+		cleanup_bridge(bridge);
+	} else {
+		/* clean-up p2p bridges under this host bridge */
+		acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
+				(u32)1, cleanup_p2p_bridge, NULL, NULL);
+	}
 }
 
+static struct pci_dev * get_apic_pci_info(acpi_handle handle)
+{
+	struct acpi_pci_id id;
+	struct pci_bus *bus;
+	struct pci_dev *dev;
+
+	if (ACPI_FAILURE(acpi_get_pci_id(handle, &id)))
+		return NULL;
+
+	bus = pci_find_bus(id.segment, id.bus);
+	if (!bus)
+		return NULL;
+
+	dev = pci_get_slot(bus, PCI_DEVFN(id.device, id.function));
+	if (!dev)
+		return NULL;
+
+	if ((dev->class != PCI_CLASS_SYSTEM_PIC_IOAPIC) &&
+	    (dev->class != PCI_CLASS_SYSTEM_PIC_IOXAPIC))
+	{
+		pci_dev_put(dev);
+		return NULL;
+	}
+
+	return dev;
+}
+
+static int get_gsi_base(acpi_handle handle, u32 *gsi_base)
+{
+	acpi_status status;
+	int result = -1;
+	unsigned long gsb;
+	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	union acpi_object *obj;
+	void *table;
+
+	status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb);
+	if (ACPI_SUCCESS(status)) {
+		*gsi_base = (u32)gsb;
+		return 0;
+	}
+
+	status = acpi_evaluate_object(handle, "_MAT", NULL, &buffer);
+	if (ACPI_FAILURE(status) || !buffer.length || !buffer.pointer)
+		return -1;
+
+	obj = buffer.pointer;
+	if (obj->type != ACPI_TYPE_BUFFER)
+		goto out;
+
+	table = obj->buffer.pointer;
+	switch (((acpi_table_entry_header *)table)->type) {
+	case ACPI_MADT_IOSAPIC:
+		*gsi_base = ((struct acpi_table_iosapic *)table)->global_irq_base;
+		result = 0;
+		break;
+	case ACPI_MADT_IOAPIC:
+		*gsi_base = ((struct acpi_table_ioapic *)table)->global_irq_base;
+		result = 0;
+		break;
+	default:
+		break;
+	}
+ out:
+	acpi_os_free(buffer.pointer);
+	return result;
+}
+
+static acpi_status
+ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	acpi_status status;
+	unsigned long sta;
+	acpi_handle tmp;
+	struct pci_dev *pdev;
+	u32 gsi_base;
+	u64 phys_addr;
+
+	/* Evaluate _STA if present */
+	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
+	if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL)
+		return AE_CTRL_DEPTH;
+
+	/* Scan only PCI bus scope */
+	status = acpi_get_handle(handle, "_HID", &tmp);
+	if (ACPI_SUCCESS(status))
+		return AE_CTRL_DEPTH;
+
+	if (get_gsi_base(handle, &gsi_base))
+		return AE_OK;
+
+	pdev = get_apic_pci_info(handle);
+	if (!pdev)
+		return AE_OK;
+
+	if (pci_enable_device(pdev)) {
+		pci_dev_put(pdev);
+		return AE_OK;
+	}
+
+	pci_set_master(pdev);
+
+	if (pci_request_region(pdev, 0, "I/O APIC(acpiphp)")) {
+		pci_disable_device(pdev);
+		pci_dev_put(pdev);
+		return AE_OK;
+	}
+
+	phys_addr = pci_resource_start(pdev, 0);
+	if (acpi_register_ioapic(handle, phys_addr, gsi_base)) {
+		pci_release_region(pdev, 0);
+		pci_disable_device(pdev);
+		pci_dev_put(pdev);
+		return AE_OK;
+	}
+
+	return AE_OK;
+}
+
+static int acpiphp_configure_ioapics(acpi_handle handle)
+{
+	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
+			    ACPI_UINT32_MAX, ioapic_add, NULL, NULL);
+	return 0;
+}
 
 static int power_on_slot(struct acpiphp_slot *slot)
 {
@@ -719,8 +718,6 @@
 	acpi_status status;
 	struct acpiphp_func *func;
 	struct list_head *l;
-	struct acpi_object_list arg_list;
-	union acpi_object arg;
 
 	int retval = 0;
 
@@ -731,7 +728,7 @@
 	list_for_each (l, &slot->funcs) {
 		func = list_entry(l, struct acpiphp_func, sibling);
 
-		if (func->pci_dev && (func->flags & FUNC_HAS_PS3)) {
+		if (func->flags & FUNC_HAS_PS3) {
 			status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL);
 			if (ACPI_FAILURE(status)) {
 				warn("%s: _PS3 failed\n", __FUNCTION__);
@@ -742,27 +739,6 @@
 		}
 	}
 
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
-
-		/* We don't want to call _EJ0 on non-existing functions. */
-		if (func->pci_dev && (func->flags & FUNC_HAS_EJ0)) {
-			/* _EJ0 method take one argument */
-			arg_list.count = 1;
-			arg_list.pointer = &arg;
-			arg.type = ACPI_TYPE_INTEGER;
-			arg.integer.value = 1;
-
-			status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL);
-			if (ACPI_FAILURE(status)) {
-				warn("%s: _EJ0 failed\n", __FUNCTION__);
-				retval = -1;
-				goto err_exit;
-			} else
-				break;
-		}
-	}
-
 	/* TBD: evaluate _STA to check if the slot is disabled */
 
 	slot->flags &= (~SLOT_POWEREDON);
@@ -782,70 +758,56 @@
  */
 static int enable_device(struct acpiphp_slot *slot)
 {
-	u8 bus;
 	struct pci_dev *dev;
-	struct pci_bus *child;
+	struct pci_bus *bus = slot->bridge->pci_bus;
 	struct list_head *l;
 	struct acpiphp_func *func;
 	int retval = 0;
-	int num;
+	int num, max, pass;
 
 	if (slot->flags & SLOT_ENABLED)
 		goto err_exit;
 
 	/* sanity check: dev should be NULL when hot-plugged in */
-	dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));
+	dev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0));
 	if (dev) {
 		/* This case shouldn't happen */
 		err("pci_dev structure already exists.\n");
+		pci_dev_put(dev);
 		retval = -1;
 		goto err_exit;
 	}
 
-	/* allocate resources to device */
-	retval = acpiphp_configure_slot(slot);
-	if (retval)
-		goto err_exit;
-
-	/* returned `dev' is the *first function* only! */
-	num = pci_scan_slot(slot->bridge->pci_bus, PCI_DEVFN(slot->device, 0));
-	if (num)
-		pci_bus_add_devices(slot->bridge->pci_bus);
-	dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));
-
-	if (!dev) {
+	num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0));
+	if (num == 0) {
 		err("No new device found\n");
 		retval = -1;
 		goto err_exit;
 	}
 
-	if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
-		pci_read_config_byte(dev, PCI_SECONDARY_BUS, &bus);
-		child = (struct pci_bus*) pci_add_new_bus(dev->bus, dev, bus);
-		pci_do_scan_bus(child);
+	max = bus->secondary;
+	for (pass = 0; pass < 2; pass++) {
+		list_for_each_entry(dev, &bus->devices, bus_list) {
+			if (PCI_SLOT(dev->devfn) != slot->device)
+				continue;
+			if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+			    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
+				max = pci_scan_bridge(bus, dev, max, pass);
+		}
 	}
 
+	pci_bus_assign_resources(bus);
+	pci_bus_add_devices(bus);
+
 	/* associate pci_dev to our representation */
 	list_for_each (l, &slot->funcs) {
 		func = list_entry(l, struct acpiphp_func, sibling);
-
-		func->pci_dev = pci_find_slot(slot->bridge->bus,
-					      PCI_DEVFN(slot->device,
+		func->pci_dev = pci_get_slot(bus, PCI_DEVFN(slot->device,
 							func->function));
-		if (!func->pci_dev)
-			continue;
-
-		/* configure device */
-		retval = acpiphp_configure_function(func);
-		if (retval)
-			goto err_exit;
 	}
 
 	slot->flags |= SLOT_ENABLED;
 
-	dbg("Available resources:\n");
-	acpiphp_dump_resource(slot->bridge);
-
  err_exit:
 	return retval;
 }
@@ -866,9 +828,12 @@
 
 	list_for_each (l, &slot->funcs) {
 		func = list_entry(l, struct acpiphp_func, sibling);
+		if (!func->pci_dev)
+			continue;
 
-		if (func->pci_dev)
-			acpiphp_unconfigure_function(func);
+		pci_remove_bus_device(func->pci_dev);
+		pci_dev_put(func->pci_dev);
+		func->pci_dev = NULL;
 	}
 
 	slot->flags &= (~SLOT_ENABLED);
@@ -920,6 +885,39 @@
 }
 
 /**
+ * acpiphp_eject_slot - physically eject the slot
+ */
+static int acpiphp_eject_slot(struct acpiphp_slot *slot)
+{
+	acpi_status status;
+	struct acpiphp_func *func;
+	struct list_head *l;
+	struct acpi_object_list arg_list;
+	union acpi_object arg;
+
+	list_for_each (l, &slot->funcs) {
+		func = list_entry(l, struct acpiphp_func, sibling);
+
+		/* We don't want to call _EJ0 on non-existing functions. */
+		if ((func->flags & FUNC_HAS_EJ0)) {
+			/* _EJ0 method take one argument */
+			arg_list.count = 1;
+			arg_list.pointer = &arg;
+			arg.type = ACPI_TYPE_INTEGER;
+			arg.integer.value = 1;
+
+			status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL);
+			if (ACPI_FAILURE(status)) {
+				warn("%s: _EJ0 failed\n", __FUNCTION__);
+				return -1;
+			} else
+				break;
+		}
+	}
+	return 0;
+}
+
+/**
  * acpiphp_check_bridge - re-enumerate devices
  *
  * Iterate over all slots under this bridge and make sure that if a
@@ -942,6 +940,8 @@
 			if (retval) {
 				err("Error occurred in disabling\n");
 				goto err_exit;
+			} else {
+				acpiphp_eject_slot(slot);
 			}
 			disabled++;
 		} else {
@@ -962,6 +962,144 @@
 	return retval;
 }
 
+static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge)
+{
+	u16 pci_cmd, pci_bctl;
+	struct pci_dev *cdev;
+
+	/* 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;
+	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
+			bridge->hpp.cache_line_size);
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER,
+			bridge->hpp.latency_timer);
+	pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
+	if (bridge->hpp.enable_SERR)
+		pci_cmd |= PCI_COMMAND_SERR;
+	else
+		pci_cmd &= ~PCI_COMMAND_SERR;
+	if (bridge->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,
+				bridge->hpp.latency_timer);
+		pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
+		if (bridge->hpp.enable_SERR)
+			pci_bctl |= PCI_BRIDGE_CTL_SERR;
+		else
+			pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
+		if (bridge->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_hpp(cdev, bridge);
+		}
+	}
+}
+
+static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus)
+{
+	struct acpiphp_bridge bridge;
+	struct pci_dev *dev;
+
+	memset(&bridge, 0, sizeof(bridge));
+	bridge.handle = handle;
+	decode_hpp(&bridge);
+	list_for_each_entry(dev, &bus->devices, bus_list)
+		program_hpp(dev, &bridge);
+
+}
+
+/*
+ * Remove devices for which we could not assign resources, call
+ * arch specific code to fix-up the bus
+ */
+static void acpiphp_sanitize_bus(struct pci_bus *bus)
+{
+	struct pci_dev *dev;
+	int i;
+	unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		for (i=0; i<PCI_BRIDGE_RESOURCES; i++) {
+			struct resource *res = &dev->resource[i];
+			if ((res->flags & type_mask) && !res->start &&
+					res->end) {
+				/* Could not assign a required resources
+				 * for this device, remove it */
+				pci_remove_bus_device(dev);
+				break;
+			}
+		}
+	}
+}
+
+/* Program resources in newly inserted bridge */
+static int acpiphp_configure_bridge (acpi_handle handle)
+{
+	struct acpi_pci_id pci_id;
+	struct pci_bus *bus;
+
+	if (ACPI_FAILURE(acpi_get_pci_id(handle, &pci_id))) {
+		err("cannot get PCI domain and bus number for bridge\n");
+		return -EINVAL;
+	}
+	bus = pci_find_bus(pci_id.segment, pci_id.bus);
+	if (!bus) {
+		err("cannot find bus %d:%d\n",
+				pci_id.segment, pci_id.bus);
+		return -EINVAL;
+	}
+
+	pci_bus_size_bridges(bus);
+	pci_bus_assign_resources(bus);
+	acpiphp_sanitize_bus(bus);
+	acpiphp_set_hpp_values(handle, bus);
+	pci_enable_bridges(bus);
+	acpiphp_configure_ioapics(handle);
+	return 0;
+}
+
+static void handle_bridge_insertion(acpi_handle handle, u32 type)
+{
+	struct acpi_device *device, *pdevice;
+	acpi_handle phandle;
+
+	if ((type != ACPI_NOTIFY_BUS_CHECK) &&
+			(type != ACPI_NOTIFY_DEVICE_CHECK)) {
+		err("unexpected notification type %d\n", type);
+		return;
+	}
+
+	acpi_get_parent(handle, &phandle);
+	if (acpi_bus_get_device(phandle, &pdevice)) {
+		dbg("no parent device, assuming NULL\n");
+		pdevice = NULL;
+	}
+	if (acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE)) {
+		err("cannot add bridge to acpi list\n");
+		return;
+	}
+	if (!acpiphp_configure_bridge(handle) &&
+		!acpi_bus_start(device))
+		add_bridge(handle);
+	else
+		err("cannot configure and start bridge\n");
+
+}
+
 /*
  * ACPI event handlers
  */
@@ -982,8 +1120,19 @@
 	char objname[64];
 	struct acpi_buffer buffer = { .length = sizeof(objname),
 				      .pointer = objname };
+	struct acpi_device *device;
 
-	bridge = (struct acpiphp_bridge *)context;
+	if (acpi_bus_get_device(handle, &device)) {
+		/* This bridge must have just been physically inserted */
+		handle_bridge_insertion(handle, type);
+		return;
+	}
+
+	bridge = acpiphp_handle_to_bridge(handle);
+	if (!bridge) {
+		err("cannot get bridge info\n");
+		return;
+	}
 
 	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 
@@ -1031,7 +1180,6 @@
 	}
 }
 
-
 /**
  * handle_hotplug_event_func - handle ACPI event on functions (i.e. slots)
  *
@@ -1074,7 +1222,8 @@
 	case ACPI_NOTIFY_EJECT_REQUEST:
 		/* request device eject */
 		dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname);
-		acpiphp_disable_slot(func->slot);
+		if (!(acpiphp_disable_slot(func->slot)))
+			acpiphp_eject_slot(func->slot);
 		break;
 
 	default:
@@ -1083,6 +1232,47 @@
 	}
 }
 
+static int is_root_bridge(acpi_handle handle)
+{
+	acpi_status status;
+	struct acpi_device_info *info;
+	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	int i;
+
+	status = acpi_get_object_info(handle, &buffer);
+	if (ACPI_SUCCESS(status)) {
+		info = buffer.pointer;
+		if ((info->valid & ACPI_VALID_HID) &&
+			!strcmp(PCI_ROOT_HID_STRING,
+					info->hardware_id.value)) {
+			acpi_os_free(buffer.pointer);
+			return 1;
+		}
+		if (info->valid & ACPI_VALID_CID) {
+			for (i=0; i < info->compatibility_id.count; i++) {
+				if (!strcmp(PCI_ROOT_HID_STRING,
+					info->compatibility_id.id[i].value)) {
+					acpi_os_free(buffer.pointer);
+					return 1;
+				}
+			}
+		}
+	}
+	return 0;
+}
+
+static acpi_status
+find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	int *count = (int *)context;
+
+	if (is_root_bridge(handle)) {
+		acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+				handle_hotplug_event_bridge, NULL);
+			(*count)++;
+	}
+	return AE_OK ;
+}
 
 static struct acpi_pci_driver acpi_pci_hp_driver = {
 	.add =		add_bridge,
@@ -1095,15 +1285,15 @@
  */
 int __init acpiphp_glue_init(void)
 {
-	int num;
+	int num = 0;
 
-	if (list_empty(&pci_root_buses))
-		return -1;
-
-	num = acpi_pci_register_driver(&acpi_pci_hp_driver);
+	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+			ACPI_UINT32_MAX, find_root_bridges, &num, NULL);
 
 	if (num <= 0)
 		return -1;
+	else
+		acpi_pci_register_driver(&acpi_pci_hp_driver);
 
 	return 0;
 }
@@ -1116,46 +1306,6 @@
  */
 void __exit acpiphp_glue_exit(void)
 {
-	struct list_head *l1, *l2, *n1, *n2;
-	struct acpiphp_bridge *bridge;
-	struct acpiphp_slot *slot, *next;
-	struct acpiphp_func *func;
-	acpi_status status;
-
-	list_for_each_safe (l1, n1, &bridge_list) {
-		bridge = (struct acpiphp_bridge *)l1;
-		slot = bridge->slots;
-		while (slot) {
-			next = slot->next;
-			list_for_each_safe (l2, n2, &slot->funcs) {
-				func = list_entry(l2, struct acpiphp_func, sibling);
-				acpiphp_free_resource(&func->io_head);
-				acpiphp_free_resource(&func->mem_head);
-				acpiphp_free_resource(&func->p_mem_head);
-				acpiphp_free_resource(&func->bus_head);
-				status = acpi_remove_notify_handler(func->handle,
-								    ACPI_SYSTEM_NOTIFY,
-								    handle_hotplug_event_func);
-				if (ACPI_FAILURE(status))
-					err("failed to remove notify handler\n");
-				kfree(func);
-			}
-			kfree(slot);
-			slot = next;
-		}
-		status = acpi_remove_notify_handler(bridge->handle, ACPI_SYSTEM_NOTIFY,
-						    handle_hotplug_event_bridge);
-		if (ACPI_FAILURE(status))
-			err("failed to remove notify handler\n");
-
-		acpiphp_free_resource(&bridge->io_head);
-		acpiphp_free_resource(&bridge->mem_head);
-		acpiphp_free_resource(&bridge->p_mem_head);
-		acpiphp_free_resource(&bridge->bus_head);
-
-		kfree(bridge);
-	}
-
 	acpi_pci_unregister_driver(&acpi_pci_hp_driver);
 }
 
@@ -1173,11 +1323,14 @@
 
 	list_for_each (node, &bridge_list) {
 		bridge = (struct acpiphp_bridge *)node;
-		dbg("Bus%d %dslot(s)\n", bridge->bus, bridge->nr_slots);
+		dbg("Bus %04x:%02x has %d slot%s\n",
+				pci_domain_nr(bridge->pci_bus),
+				bridge->pci_bus->number, bridge->nr_slots,
+				bridge->nr_slots == 1 ? "" : "s");
 		num_slots += bridge->nr_slots;
 	}
 
-	dbg("Total %dslots\n", num_slots);
+	dbg("Total %d slots\n", num_slots);
 	return num_slots;
 }
 
@@ -1254,7 +1407,6 @@
 	return retval;
 }
 
-
 /**
  * acpiphp_disable_slot - power off slot
  */
@@ -1274,13 +1426,6 @@
 	if (retval)
 		goto err_exit;
 
-	acpiphp_resource_sort_and_combine(&slot->bridge->io_head);
-	acpiphp_resource_sort_and_combine(&slot->bridge->mem_head);
-	acpiphp_resource_sort_and_combine(&slot->bridge->p_mem_head);
-	acpiphp_resource_sort_and_combine(&slot->bridge->bus_head);
-	dbg("Available resources:\n");
-	acpiphp_dump_resource(slot->bridge);
-
  err_exit:
 	up(&slot->crit_sect);
 	return retval;
@@ -1293,11 +1438,7 @@
  */
 u8 acpiphp_get_power_status(struct acpiphp_slot *slot)
 {
-	unsigned int sta;
-
-	sta = get_slot_status(slot);
-
-	return (sta & ACPI_STA_ENABLED) ? 1 : 0;
+	return (slot->flags & SLOT_POWEREDON);
 }
 
 
@@ -1335,9 +1476,10 @@
 u32 acpiphp_get_address(struct acpiphp_slot *slot)
 {
 	u32 address;
+	struct pci_bus *pci_bus = slot->bridge->pci_bus;
 
-	address = ((slot->bridge->seg) << 16) |
-		  ((slot->bridge->bus) << 8) |
+	address = (pci_domain_nr(pci_bus) << 16) |
+		  (pci_bus->number << 8) |
 		  slot->device;
 
 	return address;
diff --git a/drivers/pci/hotplug/acpiphp_pci.c b/drivers/pci/hotplug/acpiphp_pci.c
deleted file mode 100644
index 54d97c9..0000000
--- a/drivers/pci/hotplug/acpiphp_pci.c
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * ACPI PCI HotPlug PCI configuration space management
- *
- * Copyright (C) 1995,2001 Compaq Computer Corporation
- * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2001,2002 IBM Corp.
- * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
- * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
- * Copyright (C) 2002 NEC 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 <t-kochi@bq.jp.nec.com>
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/acpi.h>
-#include "../pci.h"
-#include "pci_hotplug.h"
-#include "acpiphp.h"
-
-#define MY_NAME "acpiphp_pci"
-
-
-/* allocate mem/pmem/io resource to a new function */
-static int init_config_space (struct acpiphp_func *func)
-{
-	u32 bar, len;
-	u32 address[] = {
-		PCI_BASE_ADDRESS_0,
-		PCI_BASE_ADDRESS_1,
-		PCI_BASE_ADDRESS_2,
-		PCI_BASE_ADDRESS_3,
-		PCI_BASE_ADDRESS_4,
-		PCI_BASE_ADDRESS_5,
-		0
-	};
-	int count;
-	struct acpiphp_bridge *bridge;
-	struct pci_resource *res;
-	struct pci_bus *pbus;
-	int bus, device, function;
-	unsigned int devfn;
-	u16 tmp;
-
-	bridge = func->slot->bridge;
-	pbus = bridge->pci_bus;
-	bus = bridge->bus;
-	device = func->slot->device;
-	function = func->function;
-	devfn = PCI_DEVFN(device, function);
-
-	for (count = 0; address[count]; count++) {	/* for 6 BARs */
-		pci_bus_write_config_dword(pbus, devfn,
-					   address[count], 0xFFFFFFFF);
-		pci_bus_read_config_dword(pbus, devfn, address[count], &bar);
-
-		if (!bar)	/* This BAR is not implemented */
-			continue;
-
-		dbg("Device %02x.%02x BAR %d wants %x\n", device, function, count, bar);
-
-		if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
-			/* This is IO */
-
-			len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
-			len = len & ~(len - 1);
-
-			dbg("len in IO %x, BAR %d\n", len, count);
-
-			spin_lock(&bridge->res_lock);
-			res = acpiphp_get_io_resource(&bridge->io_head, len);
-			spin_unlock(&bridge->res_lock);
-
-			if (!res) {
-				err("cannot allocate requested io for %02x:%02x.%d len %x\n",
-				    bus, device, function, len);
-				return -1;
-			}
-			pci_bus_write_config_dword(pbus, devfn,
-						   address[count],
-						   (u32)res->base);
-			res->next = func->io_head;
-			func->io_head = res;
-
-		} else {
-			/* This is Memory */
-			if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH) {
-				/* pfmem */
-
-				len = bar & 0xFFFFFFF0;
-				len = ~len + 1;
-
-				dbg("len in PFMEM %x, BAR %d\n", len, count);
-
-				spin_lock(&bridge->res_lock);
-				res = acpiphp_get_resource(&bridge->p_mem_head, len);
-				spin_unlock(&bridge->res_lock);
-
-				if (!res) {
-					err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n",
-					    bus, device, function, len);
-					return -1;
-				}
-
-				pci_bus_write_config_dword(pbus, devfn,
-							   address[count],
-							   (u32)res->base);
-
-				if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) {	/* takes up another dword */
-					dbg("inside the pfmem 64 case, count %d\n", count);
-					count += 1;
-					pci_bus_write_config_dword(pbus, devfn,
-								   address[count],
-								   (u32)(res->base >> 32));
-				}
-
-				res->next = func->p_mem_head;
-				func->p_mem_head = res;
-
-			} else {
-				/* regular memory */
-
-				len = bar & 0xFFFFFFF0;
-				len = ~len + 1;
-
-				dbg("len in MEM %x, BAR %d\n", len, count);
-
-				spin_lock(&bridge->res_lock);
-				res = acpiphp_get_resource(&bridge->mem_head, len);
-				spin_unlock(&bridge->res_lock);
-
-				if (!res) {
-					err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n",
-					    bus, device, function, len);
-					return -1;
-				}
-
-				pci_bus_write_config_dword(pbus, devfn,
-							   address[count],
-							   (u32)res->base);
-
-				if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-					/* takes up another dword */
-					dbg("inside mem 64 case, reg. mem, count %d\n", count);
-					count += 1;
-					pci_bus_write_config_dword(pbus, devfn,
-								   address[count],
-								   (u32)(res->base >> 32));
-				}
-
-				res->next = func->mem_head;
-				func->mem_head = res;
-
-			}
-		}
-	}
-
-	/* disable expansion rom */
-	pci_bus_write_config_dword(pbus, devfn, PCI_ROM_ADDRESS, 0x00000000);
-
-	/* set PCI parameters from _HPP */
-	pci_bus_write_config_byte(pbus, devfn, PCI_CACHE_LINE_SIZE,
-				  bridge->hpp.cache_line_size);
-	pci_bus_write_config_byte(pbus, devfn, PCI_LATENCY_TIMER,
-				  bridge->hpp.latency_timer);
-
-	pci_bus_read_config_word(pbus, devfn, PCI_COMMAND, &tmp);
-	if (bridge->hpp.enable_SERR)
-		tmp |= PCI_COMMAND_SERR;
-	if (bridge->hpp.enable_PERR)
-		tmp |= PCI_COMMAND_PARITY;
-	pci_bus_write_config_word(pbus, devfn, PCI_COMMAND, tmp);
-
-	return 0;
-}
-
-/* detect_used_resource - subtract resource under dev from bridge */
-static int detect_used_resource (struct acpiphp_bridge *bridge, struct pci_dev *dev)
-{
-	int count;
-
-	dbg("Device %s\n", pci_name(dev));
-
-	for (count = 0; count < DEVICE_COUNT_RESOURCE; count++) {
-		struct pci_resource *res;
-		struct pci_resource **head;
-		unsigned long base = dev->resource[count].start;
-		unsigned long len = dev->resource[count].end - base + 1;
-		unsigned long flags = dev->resource[count].flags;
-
-		if (!flags)
-			continue;
-
-		dbg("BAR[%d] 0x%lx - 0x%lx (0x%lx)\n", count, base,
-				base + len - 1, flags);
-
-		if (flags & IORESOURCE_IO) {
-			head = &bridge->io_head;
-		} else if (flags & IORESOURCE_PREFETCH) {
-			head = &bridge->p_mem_head;
-		} else {
-			head = &bridge->mem_head;
-		}
-
-		spin_lock(&bridge->res_lock);
-		res = acpiphp_get_resource_with_base(head, base, len);
-		spin_unlock(&bridge->res_lock);
-		if (res)
-			kfree(res);
-	}
-
-	return 0;
-}
-
-
-/**
- * acpiphp_detect_pci_resource - detect resources under bridge
- * @bridge: detect all resources already used under this bridge
- *
- * collect all resources already allocated for all devices under a bridge.
- */
-int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge)
-{
-	struct list_head *l;
-	struct pci_dev *dev;
-
-	list_for_each (l, &bridge->pci_bus->devices) {
-		dev = pci_dev_b(l);
-		detect_used_resource(bridge, dev);
-	}
-
-	return 0;
-}
-
-
-/**
- * acpiphp_init_slot_resource - gather resource usage information of a slot
- * @slot: ACPI slot object to be checked, should have valid pci_dev member
- *
- * TBD: PCI-to-PCI bridge case
- *      use pci_dev->resource[]
- */
-int acpiphp_init_func_resource (struct acpiphp_func *func)
-{
-	u64 base;
-	u32 bar, len;
-	u32 address[] = {
-		PCI_BASE_ADDRESS_0,
-		PCI_BASE_ADDRESS_1,
-		PCI_BASE_ADDRESS_2,
-		PCI_BASE_ADDRESS_3,
-		PCI_BASE_ADDRESS_4,
-		PCI_BASE_ADDRESS_5,
-		0
-	};
-	int count;
-	struct pci_resource *res;
-	struct pci_dev *dev;
-
-	dev = func->pci_dev;
-	dbg("Hot-pluggable device %s\n", pci_name(dev));
-
-	for (count = 0; address[count]; count++) {	/* for 6 BARs */
-		pci_read_config_dword(dev, address[count], &bar);
-
-		if (!bar)	/* This BAR is not implemented */
-			continue;
-
-		pci_write_config_dword(dev, address[count], 0xFFFFFFFF);
-		pci_read_config_dword(dev, address[count], &len);
-
-		if (len & PCI_BASE_ADDRESS_SPACE_IO) {
-			/* This is IO */
-			base = bar & 0xFFFFFFFC;
-			len = len & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
-			len = len & ~(len - 1);
-
-			dbg("BAR[%d] %08x - %08x (IO)\n", count, (u32)base, (u32)base + len - 1);
-
-			res = acpiphp_make_resource(base, len);
-			if (!res)
-				goto no_memory;
-
-			res->next = func->io_head;
-			func->io_head = res;
-
-		} else {
-			/* This is Memory */
-			base = bar & 0xFFFFFFF0;
-			if (len & PCI_BASE_ADDRESS_MEM_PREFETCH) {
-				/* pfmem */
-
-				len &= 0xFFFFFFF0;
-				len = ~len + 1;
-
-				if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {	/* takes up another dword */
-					dbg("prefetch mem 64\n");
-					count += 1;
-				}
-				dbg("BAR[%d] %08x - %08x (PMEM)\n", count, (u32)base, (u32)base + len - 1);
-				res = acpiphp_make_resource(base, len);
-				if (!res)
-					goto no_memory;
-
-				res->next = func->p_mem_head;
-				func->p_mem_head = res;
-
-			} else {
-				/* regular memory */
-
-				len &= 0xFFFFFFF0;
-				len = ~len + 1;
-
-				if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-					/* takes up another dword */
-					dbg("mem 64\n");
-					count += 1;
-				}
-				dbg("BAR[%d] %08x - %08x (MEM)\n", count, (u32)base, (u32)base + len - 1);
-				res = acpiphp_make_resource(base, len);
-				if (!res)
-					goto no_memory;
-
-				res->next = func->mem_head;
-				func->mem_head = res;
-
-			}
-		}
-
-		pci_write_config_dword(dev, address[count], bar);
-	}
-#if 1
-	acpiphp_dump_func_resource(func);
-#endif
-
-	return 0;
-
- no_memory:
-	err("out of memory\n");
-	acpiphp_free_resource(&func->io_head);
-	acpiphp_free_resource(&func->mem_head);
-	acpiphp_free_resource(&func->p_mem_head);
-
-	return -1;
-}
-
-
-/**
- * acpiphp_configure_slot - allocate PCI resources
- * @slot: slot to be configured
- *
- * initializes a PCI functions on a device inserted
- * into the slot
- *
- */
-int acpiphp_configure_slot (struct acpiphp_slot *slot)
-{
-	struct acpiphp_func *func;
-	struct list_head *l;
-	u8 hdr;
-	u32 dvid;
-	int retval = 0;
-	int is_multi = 0;
-
-	pci_bus_read_config_byte(slot->bridge->pci_bus,
-				 PCI_DEVFN(slot->device, 0),
-				 PCI_HEADER_TYPE, &hdr);
-
-	if (hdr & 0x80)
-		is_multi = 1;
-
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
-		if (is_multi || func->function == 0) {
-			pci_bus_read_config_dword(slot->bridge->pci_bus,
-						  PCI_DEVFN(slot->device,
-							    func->function),
-						  PCI_VENDOR_ID, &dvid);
-			if (dvid != 0xffffffff) {
-				retval = init_config_space(func);
-				if (retval)
-					break;
-			}
-		}
-	}
-
-	return retval;
-}
-
-/**
- * acpiphp_configure_function - configure PCI function
- * @func: function to be configured
- *
- * initializes a PCI functions on a device inserted
- * into the slot
- *
- */
-int acpiphp_configure_function (struct acpiphp_func *func)
-{
-	/* all handled by the pci core now */
-	return 0;
-}
-
-/**
- * acpiphp_unconfigure_function - unconfigure PCI function
- * @func: function to be unconfigured
- *
- */
-void acpiphp_unconfigure_function (struct acpiphp_func *func)
-{
-	struct acpiphp_bridge *bridge;
-
-	/* if pci_dev is NULL, ignore it */
-	if (!func->pci_dev)
-		return;
-
-	pci_remove_bus_device(func->pci_dev);
-
-	/* free all resources */
-	bridge = func->slot->bridge;
-
-	spin_lock(&bridge->res_lock);
-	acpiphp_move_resource(&func->io_head, &bridge->io_head);
-	acpiphp_move_resource(&func->mem_head, &bridge->mem_head);
-	acpiphp_move_resource(&func->p_mem_head, &bridge->p_mem_head);
-	acpiphp_move_resource(&func->bus_head, &bridge->bus_head);
-	spin_unlock(&bridge->res_lock);
-}
diff --git a/drivers/pci/hotplug/acpiphp_res.c b/drivers/pci/hotplug/acpiphp_res.c
deleted file mode 100644
index f54b1fa..0000000
--- a/drivers/pci/hotplug/acpiphp_res.c
+++ /dev/null
@@ -1,700 +0,0 @@
-/*
- * ACPI PCI HotPlug Utility functions
- *
- * Copyright (C) 1995,2001 Compaq Computer Corporation
- * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2001 IBM Corp.
- * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
- * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
- * Copyright (C) 2002 NEC 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 <gregkh@us.ibm.com>, <t-kochi@bq.jp.nec.com>
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <linux/sysctl.h>
-#include <linux/pci.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-
-#include <linux/ioctl.h>
-#include <linux/fcntl.h>
-
-#include <linux/list.h>
-
-#include "pci_hotplug.h"
-#include "acpiphp.h"
-
-#define MY_NAME "acpiphp_res"
-
-
-/*
- * sort_by_size - sort nodes 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;
-}
-
-#if 0
-/*
- * sort_by_max_size - sort nodes 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;
-}
-#endif
-
-/**
- * get_io_resource - get resource for I/O ports
- *
- * 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.
- *
- * difference from get_resource is handling of ISA aliasing space.
- *
- */
-struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size)
-{
-	struct pci_resource *prevnode;
-	struct pci_resource *node;
-	struct pci_resource *split_node;
-	u64 temp_qword;
-
-	if (!(*head))
-		return NULL;
-
-	if (acpiphp_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_qword = (node->base | (size-1)) + 1;
-
-			/* Short circuit if adjusted size is too small */
-			if ((node->length - (temp_qword - node->base)) < size)
-				continue;
-
-			split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
-
-			if (!split_node)
-				return NULL;
-
-			node->base = temp_qword;
-			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 = acpiphp_make_resource(node->base + size, node->length - size);
-
-			if (!split_node)
-				return NULL;
-
-			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) && !(node->base & 0xfffff000))
-			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;
-}
-
-
-#if 0
-/**
- * get_max_resource - get the largest 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.
- */
-static struct pci_resource *acpiphp_get_max_resource (struct pci_resource **head, u32 size)
-{
-	struct pci_resource *max;
-	struct pci_resource *temp;
-	struct pci_resource *split_node;
-	u64 temp_qword;
-
-	if (!(*head))
-		return NULL;
-
-	if (acpiphp_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_qword = (max->base | (size-1)) + 1;
-
-			/* Short circuit if adjusted size is too small */
-			if ((max->length - (temp_qword - max->base)) < size)
-				continue;
-
-			split_node = acpiphp_make_resource(max->base, temp_qword - max->base);
-
-			if (!split_node)
-				return NULL;
-
-			max->base = temp_qword;
-			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 */
-			temp_qword = ((max->base + max->length) & ~(size - 1));
-
-			split_node = acpiphp_make_resource(temp_qword,
-							   max->length + max->base - temp_qword);
-
-			if (!split_node)
-				return NULL;
-
-			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;
-
-		/* 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;
-}
-#endif
-
-/**
- * get_resource - get resource (mem, pfmem)
- *
- * 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.
- *
- */
-struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size)
-{
-	struct pci_resource *prevnode;
-	struct pci_resource *node;
-	struct pci_resource *split_node;
-	u64 temp_qword;
-
-	if (!(*head))
-		return NULL;
-
-	if (acpiphp_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 =%x node=%p, base=%x, length=%x\n",
-		    __FUNCTION__, size, node, (u32)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_qword = (node->base | (size-1)) + 1;
-
-			/* Short circuit if adjusted size is too small */
-			if ((node->length - (temp_qword - node->base)) < size)
-				continue;
-
-			split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
-
-			if (!split_node)
-				return NULL;
-
-			node->base = temp_qword;
-			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 = acpiphp_make_resource(node->base + size, node->length - size);
-
-			if (!split_node)
-				return NULL;
-
-			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;
-}
-
-/**
- * get_resource_with_base - get resource with specific base address
- *
- * this function
- * returns the first node of "size" length located at specified base address.
- * If it finds a node larger than "size" it will split it up.
- *
- * size must be a power of two.
- *
- */
-struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size)
-{
-	struct pci_resource *prevnode;
-	struct pci_resource *node;
-	struct pci_resource *split_node;
-	u64 temp_qword;
-
-	if (!(*head))
-		return NULL;
-
-	if (acpiphp_resource_sort_and_combine(head))
-		return NULL;
-
-	for (node = *head; node; node = node->next) {
-		dbg(": 1st req_base=%x req_size =%x node=%p, base=%x, length=%x\n",
-		    (u32)base, size, node, (u32)node->base, node->length);
-		if (node->base > base)
-			continue;
-
-		if ((node->base + node->length) < (base + size))
-			continue;
-
-		if (node->base < base) {
-			dbg(": split 1\n");
-			/* this one isn't base aligned properly
-			   so we'll make a new entry and split it up */
-			temp_qword = base;
-
-			/* Short circuit if adjusted size is too small */
-			if ((node->length - (temp_qword - node->base)) < size)
-				continue;
-
-			split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
-
-			if (!split_node)
-				return NULL;
-
-			node->base = temp_qword;
-			node->length -= split_node->length;
-
-			/* Put it in the list */
-			split_node->next = node->next;
-			node->next = split_node;
-		}
-
-		dbg(": 2nd req_base=%x req_size =%x node=%p, base=%x, length=%x\n",
-		    (u32)base, size, node, (u32)node->base, node->length);
-
-		/* Don't need to check if too small since we already did */
-		if (node->length > size) {
-			dbg(": split 2\n");
-			/* this one is longer than we need
-			   so we'll make a new entry and split it up */
-			split_node = acpiphp_make_resource(node->base + size, node->length - size);
-
-			if (!split_node)
-				return NULL;
-
-			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(": got one!!!\n");
-		/* 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;
-}
-
-
-/**
- * acpiphp_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 acpiphp_resource_sort_and_combine (struct pci_resource **head)
-{
-	struct pci_resource *node1;
-	struct pci_resource *node2;
-	int out_of_order = 1;
-
-	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",(u32)(*head)->base);
-	dbg("*head->next->base = 0x%x\n", (u32)(*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;
-}
-
-
-/**
- * acpiphp_make_resource - make resource structure
- * @base: base address of a resource
- * @length: length of a resource
- */
-struct pci_resource *acpiphp_make_resource (u64 base, u32 length)
-{
-	struct pci_resource *res;
-
-	res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-	if (res) {
-		memset(res, 0, sizeof(struct pci_resource));
-		res->base = base;
-		res->length = length;
-	}
-
-	return res;
-}
-
-
-/**
- * acpiphp_move_resource - move linked resources from one to another
- * @from: head of linked resource list
- * @to: head of linked resource list
- */
-void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to)
-{
-	struct pci_resource *tmp;
-
-	while (*from) {
-		tmp = (*from)->next;
-		(*from)->next = *to;
-		*to = *from;
-		*from = tmp;
-	}
-
-	/* *from = NULL is guaranteed */
-}
-
-
-/**
- * acpiphp_free_resource - free all linked resources
- * @res: head of linked resource list
- */
-void acpiphp_free_resource (struct pci_resource **res)
-{
-	struct pci_resource *tmp;
-
-	while (*res) {
-		tmp = (*res)->next;
-		kfree(*res);
-		*res = tmp;
-	}
-
-	/* *res = NULL is guaranteed */
-}
-
-
-/* debug support functions;  will go away sometime :) */
-static void dump_resource(struct pci_resource *head)
-{
-	struct pci_resource *p;
-	int cnt;
-
-	p = head;
-	cnt = 0;
-
-	while (p) {
-		dbg("[%02d] %08x - %08x\n",
-		    cnt++, (u32)p->base, (u32)p->base + p->length - 1);
-		p = p->next;
-	}
-}
-
-void acpiphp_dump_resource(struct acpiphp_bridge *bridge)
-{
-	dbg("I/O resource:\n");
-	dump_resource(bridge->io_head);
-	dbg("MEM resource:\n");
-	dump_resource(bridge->mem_head);
-	dbg("PMEM resource:\n");
-	dump_resource(bridge->p_mem_head);
-	dbg("BUS resource:\n");
-	dump_resource(bridge->bus_head);
-}
-
-void acpiphp_dump_func_resource(struct acpiphp_func *func)
-{
-	dbg("I/O resource:\n");
-	dump_resource(func->io_head);
-	dbg("MEM resource:\n");
-	dump_resource(func->mem_head);
-	dbg("PMEM resource:\n");
-	dump_resource(func->p_mem_head);
-	dbg("BUS resource:\n");
-	dump_resource(func->bus_head);
-}
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
index afbccfa..8c6d398 100644
--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -60,6 +60,7 @@
 static void __iomem *cpqhp_rom_start;
 static int power_mode;
 static int debug;
+static int initialized;
 
 #define DRIVER_VERSION	"0.9.8"
 #define DRIVER_AUTHOR	"Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>"
@@ -1271,7 +1272,6 @@
 {
 	int loop;
 	int retval = 0;
-	static int initialized = 0;
 
 	if (initialized)
 		return 0;
@@ -1441,7 +1441,8 @@
 	}
 
 	// Stop the notification mechanism
-	cpqhp_event_stop_thread();
+	if (initialized)
+		cpqhp_event_stop_thread();
 
 	//unmap the rom address
 	if (cpqhp_rom_start)
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 30206ac..b5ab9aa6 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -28,10 +28,10 @@
 static kmem_cache_t* msi_cachep;
 
 static int pci_msi_enable = 1;
-static int last_alloc_vector = 0;
-static int nr_released_vectors = 0;
+static int last_alloc_vector;
+static int nr_released_vectors;
 static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS;
-static int nr_msix_devices = 0;
+static int nr_msix_devices;
 
 #ifndef CONFIG_X86_IO_APIC
 int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};
@@ -170,44 +170,30 @@
 	return 0;	/* never anything pending */
 }
 
-static void release_msi(unsigned int vector);
-static void shutdown_msi_irq(unsigned int vector)
-{
-	release_msi(vector);
-}
-
-#define shutdown_msi_irq_wo_maskbit	shutdown_msi_irq
-static void enable_msi_irq_wo_maskbit(unsigned int vector) {}
-static void disable_msi_irq_wo_maskbit(unsigned int vector) {}
-static void ack_msi_irq_wo_maskbit(unsigned int vector) {}
-static void end_msi_irq_wo_maskbit(unsigned int vector)
-{
-	move_msi(vector);
-	ack_APIC_irq();
-}
-
 static unsigned int startup_msi_irq_w_maskbit(unsigned int vector)
 {
+	startup_msi_irq_wo_maskbit(vector);
+	unmask_MSI_irq(vector);
+	return 0;	/* never anything pending */
+}
+
+static void shutdown_msi_irq(unsigned int vector)
+{
 	struct msi_desc *entry;
 	unsigned long flags;
 
 	spin_lock_irqsave(&msi_lock, flags);
 	entry = msi_desc[vector];
-	if (!entry || !entry->dev) {
-		spin_unlock_irqrestore(&msi_lock, flags);
-		return 0;
-	}
-	entry->msi_attrib.state = 1;	/* Mark it active */
+	if (entry && entry->dev)
+		entry->msi_attrib.state = 0;	/* Mark it not active */
 	spin_unlock_irqrestore(&msi_lock, flags);
-
-	unmask_MSI_irq(vector);
-	return 0;	/* never anything pending */
 }
 
-#define shutdown_msi_irq_w_maskbit	shutdown_msi_irq
-#define enable_msi_irq_w_maskbit	unmask_MSI_irq
-#define disable_msi_irq_w_maskbit	mask_MSI_irq
-#define ack_msi_irq_w_maskbit		mask_MSI_irq
+static void end_msi_irq_wo_maskbit(unsigned int vector)
+{
+	move_msi(vector);
+	ack_APIC_irq();
+}
 
 static void end_msi_irq_w_maskbit(unsigned int vector)
 {
@@ -216,6 +202,10 @@
 	ack_APIC_irq();
 }
 
+static void do_nothing(unsigned int vector)
+{
+}
+
 /*
  * Interrupt Type for MSI-X PCI/PCI-X/PCI-Express Devices,
  * which implement the MSI-X Capability Structure.
@@ -223,10 +213,10 @@
 static struct hw_interrupt_type msix_irq_type = {
 	.typename	= "PCI-MSI-X",
 	.startup	= startup_msi_irq_w_maskbit,
-	.shutdown	= shutdown_msi_irq_w_maskbit,
-	.enable		= enable_msi_irq_w_maskbit,
-	.disable	= disable_msi_irq_w_maskbit,
-	.ack		= ack_msi_irq_w_maskbit,
+	.shutdown	= shutdown_msi_irq,
+	.enable		= unmask_MSI_irq,
+	.disable	= mask_MSI_irq,
+	.ack		= mask_MSI_irq,
 	.end		= end_msi_irq_w_maskbit,
 	.set_affinity	= set_msi_irq_affinity
 };
@@ -239,10 +229,10 @@
 static struct hw_interrupt_type msi_irq_w_maskbit_type = {
 	.typename	= "PCI-MSI",
 	.startup	= startup_msi_irq_w_maskbit,
-	.shutdown	= shutdown_msi_irq_w_maskbit,
-	.enable		= enable_msi_irq_w_maskbit,
-	.disable	= disable_msi_irq_w_maskbit,
-	.ack		= ack_msi_irq_w_maskbit,
+	.shutdown	= shutdown_msi_irq,
+	.enable		= unmask_MSI_irq,
+	.disable	= mask_MSI_irq,
+	.ack		= mask_MSI_irq,
 	.end		= end_msi_irq_w_maskbit,
 	.set_affinity	= set_msi_irq_affinity
 };
@@ -255,10 +245,10 @@
 static struct hw_interrupt_type msi_irq_wo_maskbit_type = {
 	.typename	= "PCI-MSI",
 	.startup	= startup_msi_irq_wo_maskbit,
-	.shutdown	= shutdown_msi_irq_wo_maskbit,
-	.enable		= enable_msi_irq_wo_maskbit,
-	.disable	= disable_msi_irq_wo_maskbit,
-	.ack		= ack_msi_irq_wo_maskbit,
+	.shutdown	= shutdown_msi_irq,
+	.enable		= do_nothing,
+	.disable	= do_nothing,
+	.ack		= do_nothing,
 	.end		= end_msi_irq_wo_maskbit,
 	.set_affinity	= set_msi_irq_affinity
 };
@@ -407,7 +397,7 @@
 {
 	struct msi_desc *entry;
 
-	entry = (struct msi_desc*) kmem_cache_alloc(msi_cachep, SLAB_KERNEL);
+	entry = kmem_cache_alloc(msi_cachep, SLAB_KERNEL);
 	if (!entry)
 		return NULL;
 
@@ -796,18 +786,6 @@
 	}
 }
 
-static void release_msi(unsigned int vector)
-{
-	struct msi_desc *entry;
-	unsigned long flags;
-
-	spin_lock_irqsave(&msi_lock, flags);
-	entry = msi_desc[vector];
-	if (entry && entry->dev)
-		entry->msi_attrib.state = 0;	/* Mark it not active */
-	spin_unlock_irqrestore(&msi_lock, flags);
-}
-
 static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
 {
 	struct msi_desc *entry;
@@ -924,7 +902,7 @@
 /**
  * pci_enable_msix - configure device's MSI-X capability structure
  * @dev: pointer to the pci_dev data structure of MSI-X device function
- * @data: pointer to an array of MSI-X entries
+ * @entries: pointer to an array of MSI-X entries
  * @nvec: number of MSI-X vectors requested for allocation by device driver
  *
  * Setup the MSI-X capability structure of device function with the number
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h
index bef21ae..390f185 100644
--- a/drivers/pci/msi.h
+++ b/drivers/pci/msi.h
@@ -41,11 +41,11 @@
 #define PCI_MSIX_FLAGS_BIRMASK		(7 << 0)
 #define PCI_MSIX_FLAGS_BITMASK		(1 << 0)
 
-#define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET	0
-#define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET	4
-#define PCI_MSIX_ENTRY_DATA_OFFSET		8
-#define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET	12
 #define PCI_MSIX_ENTRY_SIZE			16
+#define  PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET	0
+#define  PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET	4
+#define  PCI_MSIX_ENTRY_DATA_OFFSET		8
+#define  PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET	12
 
 #define msi_control_reg(base)		(base + PCI_MSI_FLAGS)
 #define msi_lower_address_reg(base)	(base + PCI_MSI_ADDRESS_LO)
@@ -64,7 +64,6 @@
 #define msi_enable(control, num) multi_msi_enable(control, num); \
 	control |= PCI_MSI_FLAGS_ENABLE
 
-#define msix_control_reg		msi_control_reg
 #define msix_table_offset_reg(base)	(base + 0x04)
 #define msix_pba_offset_reg(base)	(base + 0x08)
 #define msix_enable(control)	 	control |= PCI_MSIX_FLAGS_ENABLE
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index e65bf2b..e4115a0 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -7,7 +7,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/device.h>
-#include <linux/pci-dynids.h>
 #include "pci.h"
 
 /*
@@ -18,36 +17,12 @@
  * Dynamic device IDs are disabled for !CONFIG_HOTPLUG
  */
 
-#ifdef CONFIG_HOTPLUG
-/**
- * pci_device_probe_dynamic()
- *
- * Walk the dynamic ID list looking for a match.
- * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error.
- */
-static int
-pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
-{
-	int error = -ENODEV;
-	struct list_head *pos;
-	struct dynid *dynid;
+struct pci_dynid {
+	struct list_head node;
+	struct pci_device_id id;
+};
 
-	spin_lock(&drv->dynids.lock);
-	list_for_each(pos, &drv->dynids.list) {
-		dynid = list_entry(pos, struct dynid, node);
-		if (pci_match_one_device(&dynid->id, pci_dev)) {
-			spin_unlock(&drv->dynids.lock);
-			error = drv->probe(pci_dev, &dynid->id);
-			if (error >= 0) {
-				pci_dev->driver = drv;
-				return 0;
-			}
-			return error;
-		}
-	}
-	spin_unlock(&drv->dynids.lock);
-	return error;
-}
+#ifdef CONFIG_HOTPLUG
 
 /**
  * store_new_id
@@ -58,8 +33,7 @@
 static inline ssize_t
 store_new_id(struct device_driver *driver, const char *buf, size_t count)
 {
-	struct dynid *dynid;
-	struct bus_type * bus;
+	struct pci_dynid *dynid;
 	struct pci_driver *pdrv = to_pci_driver(driver);
 	__u32 vendor=PCI_ANY_ID, device=PCI_ANY_ID, subvendor=PCI_ANY_ID,
 		subdevice=PCI_ANY_ID, class=0, class_mask=0;
@@ -91,37 +65,22 @@
 	list_add_tail(&pdrv->dynids.list, &dynid->node);
 	spin_unlock(&pdrv->dynids.lock);
 
-	bus = get_bus(pdrv->driver.bus);
-	if (bus) {
-		if (get_driver(&pdrv->driver)) {
-			down_write(&bus->subsys.rwsem);
-			driver_attach(&pdrv->driver);
-			up_write(&bus->subsys.rwsem);
-			put_driver(&pdrv->driver);
-		}
-		put_bus(bus);
+	if (get_driver(&pdrv->driver)) {
+		driver_attach(&pdrv->driver);
+		put_driver(&pdrv->driver);
 	}
 
 	return count;
 }
-
 static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
-static inline void
-pci_init_dynids(struct pci_dynids *dynids)
-{
-	spin_lock_init(&dynids->lock);
-	INIT_LIST_HEAD(&dynids->list);
-}
 
 static void
 pci_free_dynids(struct pci_driver *drv)
 {
-	struct list_head *pos, *n;
-	struct dynid *dynid;
+	struct pci_dynid *dynid, *n;
 
 	spin_lock(&drv->dynids.lock);
-	list_for_each_safe(pos, n, &drv->dynids.list) {
-		dynid = list_entry(pos, struct dynid, node);
+	list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) {
 		list_del(&dynid->node);
 		kfree(dynid);
 	}
@@ -138,83 +97,70 @@
 	return error;
 }
 
-static int
-pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv)
-{
-	struct list_head *pos;
-	struct dynid *dynid;
-
-	spin_lock(&pci_drv->dynids.lock);
-	list_for_each(pos, &pci_drv->dynids.list) {
-		dynid = list_entry(pos, struct dynid, node);
-		if (pci_match_one_device(&dynid->id, pci_dev)) {
-			spin_unlock(&pci_drv->dynids.lock);
-			return 1;
-		}
-	}
-	spin_unlock(&pci_drv->dynids.lock);
-	return 0;
-}
-
 #else /* !CONFIG_HOTPLUG */
-static inline int pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
-{
-	return -ENODEV;
-}
-static inline void pci_init_dynids(struct pci_dynids *dynids) {}
 static inline void pci_free_dynids(struct pci_driver *drv) {}
 static inline int pci_create_newid_file(struct pci_driver *drv)
 {
 	return 0;
 }
-static inline int pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv)
-{
-	return 0;
-}
 #endif
 
 /**
- * pci_match_device - Tell if a PCI device structure has a matching
- *                    PCI device id structure
+ * pci_match_id - See if a pci device matches a given pci_id table
  * @ids: array of PCI device id structures to search in
- * @dev: the PCI device structure to match against
- * 
+ * @dev: the PCI device structure to match against.
+ *
  * 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.
+ *
+ * Depreciated, don't use this as it will not catch any dynamic ids
+ * that a driver might want to check for.
  */
-const struct pci_device_id *
-pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev)
+const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
+					 struct pci_dev *dev)
 {
-	while (ids->vendor || ids->subvendor || ids->class_mask) {
-		if (pci_match_one_device(ids, dev))
-			return ids;
-		ids++;
+	if (ids) {
+		while (ids->vendor || ids->subvendor || ids->class_mask) {
+			if (pci_match_one_device(ids, dev))
+				return ids;
+			ids++;
+		}
 	}
 	return NULL;
 }
 
 /**
- * pci_device_probe_static()
- * 
- * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error.
+ * pci_match_device - 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 PCI driver to match against
+ *
+ * Used by a driver to check whether a PCI device present in the
+ * 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_device_probe_static(struct pci_driver *drv, struct pci_dev *pci_dev)
-{		   
-	int error = -ENODEV;
+const struct pci_device_id *pci_match_device(struct pci_driver *drv,
+					     struct pci_dev *dev)
+{
 	const struct pci_device_id *id;
+	struct pci_dynid *dynid;
 
-	if (!drv->id_table)
-		return error;
-	id = pci_match_device(drv->id_table, pci_dev);
+	id = pci_match_id(drv->id_table, dev);
 	if (id)
-		error = drv->probe(pci_dev, id);
-	if (error >= 0) {
-		pci_dev->driver = drv;
-		error = 0;
+		return id;
+
+	/* static ids didn't match, lets look at the dynamic ones */
+	spin_lock(&drv->dynids.lock);
+	list_for_each_entry(dynid, &drv->dynids.list, node) {
+		if (pci_match_one_device(&dynid->id, dev)) {
+			spin_unlock(&drv->dynids.lock);
+			return &dynid->id;
+		}
 	}
-	return error;
+	spin_unlock(&drv->dynids.lock);
+	return NULL;
 }
 
 /**
@@ -225,13 +171,20 @@
  */
 static int
 __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
-{		   
+{
+	const struct pci_device_id *id;
 	int error = 0;
 
 	if (!pci_dev->driver && drv->probe) {
-		error = pci_device_probe_static(drv, pci_dev);
-		if (error == -ENODEV)
-			error = pci_device_probe_dynamic(drv, pci_dev);
+		error = -ENODEV;
+
+		id = pci_match_device(drv, pci_dev);
+		if (id)
+			error = drv->probe(pci_dev, id);
+		if (error >= 0) {
+			pci_dev->driver = drv;
+			error = 0;
+		}
 	}
 	return error;
 }
@@ -371,12 +324,6 @@
 	.sysfs_ops = &pci_driver_sysfs_ops,
 };
 
-static int
-pci_populate_driver_dir(struct pci_driver *drv)
-{
-	return pci_create_newid_file(drv);
-}
-
 /**
  * pci_register_driver - register a new pci driver
  * @drv: the driver structure to register
@@ -401,13 +348,15 @@
 		drv->driver.shutdown = pci_device_shutdown;
 	drv->driver.owner = drv->owner;
 	drv->driver.kobj.ktype = &pci_driver_kobj_type;
-	pci_init_dynids(&drv->dynids);
+
+	spin_lock_init(&drv->dynids.lock);
+	INIT_LIST_HEAD(&drv->dynids.list);
 
 	/* register with core */
 	error = driver_register(&drv->driver);
 
 	if (!error)
-		pci_populate_driver_dir(drv);
+		error = pci_create_newid_file(drv);
 
 	return error;
 }
@@ -463,21 +412,17 @@
  * 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) 
+static int pci_bus_match(struct device *dev, struct device_driver *drv)
 {
-	const struct pci_dev * pci_dev = to_pci_dev(dev);
-	struct pci_driver * pci_drv = to_pci_driver(drv);
-	const struct pci_device_id * ids = pci_drv->id_table;
+	struct pci_dev *pci_dev = to_pci_dev(dev);
+	struct pci_driver *pci_drv = to_pci_driver(drv);
 	const struct pci_device_id *found_id;
 
-	if (!ids)
-		return 0;
-
-	found_id = pci_match_device(ids, pci_dev);
+	found_id = pci_match_device(pci_drv, pci_dev);
 	if (found_id)
 		return 1;
 
-	return pci_bus_match_dynids(pci_dev, pci_drv);
+	return 0;
 }
 
 /**
@@ -536,6 +481,7 @@
 
 postcore_initcall(pci_driver_init);
 
+EXPORT_SYMBOL(pci_match_id);
 EXPORT_SYMBOL(pci_match_device);
 EXPORT_SYMBOL(pci_register_driver);
 EXPORT_SYMBOL(pci_unregister_driver);
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index a15f940..cc9d653 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -60,15 +60,18 @@
 	char * str = buf;
 	int i;
 	int max = 7;
+	u64 start, end;
 
 	if (pci_dev->subordinate)
 		max = DEVICE_COUNT_RESOURCE;
 
 	for (i = 0; i < max; i++) {
-		str += sprintf(str,"0x%016lx 0x%016lx 0x%016lx\n",
-			       pci_resource_start(pci_dev,i),
-			       pci_resource_end(pci_dev,i),
-			       pci_resource_flags(pci_dev,i));
+		struct resource *res =  &pci_dev->resource[i];
+		pci_resource_to_user(pci_dev, i, res, &start, &end);
+		str += sprintf(str,"0x%016llx 0x%016llx 0x%016llx\n",
+			       (unsigned long long)start,
+			       (unsigned long long)end,
+			       (unsigned long long)res->flags);
 	}
 	return (str - buf);
 }
@@ -313,8 +316,21 @@
 						       struct device, kobj));
 	struct resource *res = (struct resource *)attr->private;
 	enum pci_mmap_state mmap_type;
+	u64 start, end;
+	int i;
 
-	vma->vm_pgoff += res->start >> PAGE_SHIFT;
+	for (i = 0; i < PCI_ROM_RESOURCE; i++)
+		if (res == &pdev->resource[i])
+			break;
+	if (i >= PCI_ROM_RESOURCE)
+		return -ENODEV;
+
+	/* pci_mmap_page_range() expects the same kind of entry as coming
+	 * from /proc/bus/pci/ which is a "user visible" value. If this is
+	 * different from the resource itself, arch will do necessary fixup.
+	 */
+	pci_resource_to_user(pdev, i, res, &start, &end);
+	vma->vm_pgoff += start >> PAGE_SHIFT;
 	mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
 
 	return pci_mmap_page_range(pdev, vma, mmap_type, 0);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index f04b9ff..d382bdb 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -334,10 +334,6 @@
 /**
  * pci_save_state - save the PCI configuration space of a device before suspending
  * @dev: - PCI device that we're dealing with
- * @buffer: - buffer to hold config space context
- *
- * @buffer must be large enough to hold the entire PCI 2.2 config space 
- * (>= 64 bytes).
  */
 int
 pci_save_state(struct pci_dev *dev)
@@ -352,8 +348,6 @@
 /** 
  * pci_restore_state - Restore the saved state of a PCI device
  * @dev: - PCI device that we're dealing with
- * @buffer: - saved PCI config space
- *
  */
 int 
 pci_restore_state(struct pci_dev *dev)
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h
index 537b372..a63bd8f 100644
--- a/drivers/pci/pcie/portdrv.h
+++ b/drivers/pci/pcie/portdrv.h
@@ -27,6 +27,11 @@
 
 #define get_descriptor_id(type, service) (((type - 4) << 4) | service)
 
+struct pcie_port_device_ext {
+	int interrupt_mode;	/* [0:INTx | 1:MSI | 2:MSI-X] */
+	unsigned int saved_msi_config_space[5];
+};
+
 extern struct bus_type pcie_port_bus_type;
 extern int pcie_port_device_probe(struct pci_dev *dev);
 extern int pcie_port_device_register(struct pci_dev *dev);
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index f5c5f10..4db6998 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -275,10 +275,17 @@
 
 int pcie_port_device_register(struct pci_dev *dev)
 {
+	struct pcie_port_device_ext *p_ext;
 	int status, type, capabilities, irq_mode, i;
 	int vectors[PCIE_PORT_DEVICE_MAXSERVICES];
 	u16 reg16;
 
+	/* Allocate port device extension */
+	if (!(p_ext = kmalloc(sizeof(struct pcie_port_device_ext), GFP_KERNEL)))
+		return -ENOMEM;
+
+	pci_set_drvdata(dev, p_ext);
+
 	/* Get port type */
 	pci_read_config_word(dev,
 		pci_find_capability(dev, PCI_CAP_ID_EXP) +
@@ -288,6 +295,7 @@
 	/* Now get port services */
 	capabilities = get_port_device_capability(dev);
 	irq_mode = assign_interrupt_mode(dev, vectors, capabilities);
+	p_ext->interrupt_mode = irq_mode;
 
 	/* Allocate child services if any */
 	for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index e9095ee..30bac7e 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -29,6 +29,78 @@
 /* global data */
 static const char device_name[] = "pcieport-driver";
 
+static void pci_save_msi_state(struct pci_dev *dev)
+{
+	struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
+	int i = 0, pos;
+	u16 control;
+
+   	if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) <= 0)
+		return;
+
+	pci_read_config_dword(dev, pos, &p_ext->saved_msi_config_space[i++]);
+	control = p_ext->saved_msi_config_space[0] >> 16;
+	pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_LO,
+		&p_ext->saved_msi_config_space[i++]);
+	if (control & PCI_MSI_FLAGS_64BIT) {
+		pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_HI,
+			&p_ext->saved_msi_config_space[i++]);
+		pci_read_config_dword(dev, pos + PCI_MSI_DATA_64,
+			&p_ext->saved_msi_config_space[i++]);
+	} else
+		pci_read_config_dword(dev, pos + PCI_MSI_DATA_32,
+			&p_ext->saved_msi_config_space[i++]);
+	if (control & PCI_MSI_FLAGS_MASKBIT)
+		pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT,
+			&p_ext->saved_msi_config_space[i++]);
+}
+
+static void pci_restore_msi_state(struct pci_dev *dev)
+{
+	struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
+	int i = 0, pos;
+	u16 control;
+
+   	if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) <= 0)
+		return;
+
+	control = p_ext->saved_msi_config_space[i++] >> 16;
+	pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control);
+	pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO,
+		p_ext->saved_msi_config_space[i++]);
+	if (control & PCI_MSI_FLAGS_64BIT) {
+		pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_HI,
+			p_ext->saved_msi_config_space[i++]);
+		pci_write_config_dword(dev, pos + PCI_MSI_DATA_64,
+			p_ext->saved_msi_config_space[i++]);
+	} else
+		pci_write_config_dword(dev, pos + PCI_MSI_DATA_32,
+			p_ext->saved_msi_config_space[i++]);
+	if (control & PCI_MSI_FLAGS_MASKBIT)
+		pci_write_config_dword(dev, pos + PCI_MSI_MASK_BIT,
+			p_ext->saved_msi_config_space[i++]);
+}
+
+static void pcie_portdrv_save_config(struct pci_dev *dev)
+{
+	struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
+
+	pci_save_state(dev);
+	if (p_ext->interrupt_mode == PCIE_PORT_MSI_MODE)
+		pci_save_msi_state(dev);
+}
+
+static void pcie_portdrv_restore_config(struct pci_dev *dev)
+{
+	struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
+
+	pci_restore_state(dev);
+	if (p_ext->interrupt_mode == PCIE_PORT_MSI_MODE)
+		pci_restore_msi_state(dev);
+	pci_enable_device(dev);
+	pci_set_master(dev);
+}
+
 /*
  * pcie_portdrv_probe - Probe PCI-Express port devices
  * @dev: PCI-Express port device being probed
@@ -64,16 +136,21 @@
 static void pcie_portdrv_remove (struct pci_dev *dev)
 {
 	pcie_port_device_remove(dev);
+	kfree(pci_get_drvdata(dev));
 }
 
 #ifdef CONFIG_PM
 static int pcie_portdrv_suspend (struct pci_dev *dev, pm_message_t state)
 {
-	return pcie_port_device_suspend(dev, state);
+	int ret = pcie_port_device_suspend(dev, state);
+
+	pcie_portdrv_save_config(dev);
+	return ret;
 }
 
 static int pcie_portdrv_resume (struct pci_dev *dev)
 {
+	pcie_portdrv_restore_config(dev);
 	return pcie_port_device_resume(dev);
 }
 #endif
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index fd48b20..df3bdae 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -239,9 +239,8 @@
 
 	if (dev->transparent) {
 		printk(KERN_INFO "PCI: Transparent bridge - %s\n", pci_name(dev));
-		for(i = 0; i < PCI_BUS_NUM_RESOURCES; i++)
-			child->resource[i] = child->parent->resource[i];
-		return;
+		for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++)
+			child->resource[i] = child->parent->resource[i - 3];
 	}
 
 	for(i=0; i<3; i++)
@@ -374,8 +373,11 @@
 	struct pci_bus *child;
 
 	child = pci_alloc_child_bus(parent, dev, busnr);
-	if (child)
+	if (child) {
+		spin_lock(&pci_bus_lock);
 		list_add_tail(&child->node, &parent->children);
+		spin_unlock(&pci_bus_lock);
+	}
 	return child;
 }
 
@@ -395,6 +397,16 @@
 	pci_write_config_word(dev, rpcap + PCI_EXP_RTCTL, rpctl);
 }
 
+static void __devinit pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max)
+{
+	struct pci_bus *parent = child->parent;
+	while (parent->parent && parent->subordinate < max) {
+		parent->subordinate = max;
+		pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, max);
+		parent = parent->parent;
+	}
+}
+
 unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus);
 
 /*
@@ -411,7 +423,7 @@
 {
 	struct pci_bus *child;
 	int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
-	u32 buses;
+	u32 buses, i;
 	u16 bctl;
 
 	pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
@@ -447,7 +459,7 @@
 			return max;
 		}
 
-		child = pci_alloc_child_bus(bus, dev, busnr);
+		child = pci_add_new_bus(bus, dev, busnr);
 		if (!child)
 			return max;
 		child->primary = buses & 0xFF;
@@ -470,7 +482,11 @@
 		/* Clear errors */
 		pci_write_config_word(dev, PCI_STATUS, 0xffff);
 
-		child = pci_alloc_child_bus(bus, dev, ++max);
+		/* Prevent assigning a bus number that already exists.
+		 * This can happen when a bridge is hot-plugged */
+		if (pci_find_bus(pci_domain_nr(bus), max+1))
+			return max;
+		child = pci_add_new_bus(bus, dev, ++max);
 		buses = (buses & 0xff000000)
 		      | ((unsigned int)(child->primary)     <<  0)
 		      | ((unsigned int)(child->secondary)   <<  8)
@@ -492,7 +508,13 @@
 
 		if (!is_cardbus) {
 			child->bridge_ctl = PCI_BRIDGE_CTL_NO_ISA;
-
+			/*
+			 * Adjust subordinate busnr in parent buses.
+			 * We do this before scanning for children because
+			 * some devices may not be detected if the bios
+			 * was lazy.
+			 */
+			pci_fixup_parent_subordinate_busnr(child, max);
 			/* Now we can scan all subordinate buses... */
 			max = pci_scan_child_bus(child);
 		} else {
@@ -501,7 +523,12 @@
 			 * as cards with a PCI-to-PCI bridge can be
 			 * inserted later.
 			 */
-			max += CARDBUS_RESERVE_BUSNR;
+			for (i=0; i<CARDBUS_RESERVE_BUSNR; i++)
+				if (pci_find_bus(pci_domain_nr(bus),
+							max+i+1))
+					break;
+			max += i;
+			pci_fixup_parent_subordinate_busnr(child, max);
 		}
 		/*
 		 * Set the subordinate bus number to its real value.
@@ -757,7 +784,9 @@
 	 * and the bus list for fixup functions, etc.
 	 */
 	INIT_LIST_HEAD(&dev->global_list);
+	spin_lock(&pci_bus_lock);
 	list_add_tail(&dev->bus_list, &bus->devices);
+	spin_unlock(&pci_bus_lock);
 
 	return dev;
 }
@@ -878,7 +907,9 @@
 		pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus);
 		goto err_out;
 	}
+	spin_lock(&pci_bus_lock);
 	list_add_tail(&b->node, &pci_root_buses);
+	spin_unlock(&pci_bus_lock);
 
 	memset(dev, 0, sizeof(*dev));
 	dev->parent = parent;
@@ -911,8 +942,6 @@
 
 	b->subordinate = pci_scan_child_bus(b);
 
-	pci_bus_add_devices(b);
-
 	return b;
 
 sys_create_link_err:
@@ -922,7 +951,9 @@
 class_dev_reg_err:
 	device_unregister(dev);
 dev_reg_err:
+	spin_lock(&pci_bus_lock);
 	list_del(&b->node);
+	spin_unlock(&pci_bus_lock);
 err_out:
 	kfree(dev);
 	kfree(b);
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index e68bbfb..7988fc8 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -355,14 +355,20 @@
 			dev->device,
 			dev->irq);
 	/* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */
-	for(i=0; i<7; i++)
+	for (i=0; i<7; i++) {
+		u64 start, end;
+		pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);
 		seq_printf(m, LONG_FORMAT,
-			dev->resource[i].start |
+			((unsigned long)start) |
 			(dev->resource[i].flags & PCI_REGION_FLAG_MASK));
-	for(i=0; i<7; i++)
+	}
+	for (i=0; i<7; i++) {
+		u64 start, end;
+		pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);
 		seq_printf(m, LONG_FORMAT,
 			dev->resource[i].start < dev->resource[i].end ?
-			dev->resource[i].end - dev->resource[i].start + 1 : 0);
+			(unsigned long)(end - start) + 1 : 0);
+	}
 	seq_putc(m, '\t');
 	if (drv)
 		seq_printf(m, "%s", drv->name);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 968033f..1521fd5 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -767,6 +767,7 @@
 	if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK)) {
 		if (dev->device == PCI_DEVICE_ID_INTEL_82845_HB)
 			switch(dev->subsystem_device) {
+			case 0x8025: /* P4B-LX */
 			case 0x8070: /* P4B */
 			case 0x8088: /* P4B533 */
 			case 0x1626: /* L3C notebook */
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 96f077f..27a294b 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -18,17 +18,21 @@
 
 static void pci_destroy_dev(struct pci_dev *dev)
 {
-	pci_proc_detach_device(dev);
-	pci_remove_sysfs_dev_files(dev);
-	device_unregister(&dev->dev);
+	if (!list_empty(&dev->global_list)) {
+		pci_proc_detach_device(dev);
+		pci_remove_sysfs_dev_files(dev);
+		device_unregister(&dev->dev);
+		spin_lock(&pci_bus_lock);
+		list_del(&dev->global_list);
+		dev->global_list.next = dev->global_list.prev = NULL;
+		spin_unlock(&pci_bus_lock);
+	}
 
 	/* Remove the device from the device lists, and prevent any further
 	 * list accesses from this device */
 	spin_lock(&pci_bus_lock);
 	list_del(&dev->bus_list);
-	list_del(&dev->global_list);
 	dev->bus_list.next = dev->bus_list.prev = NULL;
-	dev->global_list.next = dev->global_list.prev = NULL;
 	spin_unlock(&pci_bus_lock);
 
 	pci_free_resources(dev);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 1ba84be..9fe48f7 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -72,7 +72,11 @@
 	for (list = head.next; list;) {
 		res = list->res;
 		idx = res - &list->dev->resource[0];
-		pci_assign_resource(list->dev, idx);
+		if (pci_assign_resource(list->dev, idx)) {
+			res->start = 0;
+			res->end = 0;
+			res->flags = 0;
+		}
 		tmp = list;
 		list = list->next;
 		kfree(tmp);
@@ -270,6 +274,8 @@
 
 	for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
 		r = bus->resource[i];
+		if (r == &ioport_resource || r == &iomem_resource)
+			continue;
 		if (r && (r->flags & type_mask) == type && !r->parent)
 			return r;
 	}
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index cabddd4..d5afd55 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -847,7 +847,7 @@
 pcmcia_device_stringattr(prod_id3, prod_id[2]);
 pcmcia_device_stringattr(prod_id4, prod_id[3]);
 
-static ssize_t modalias_show(struct device *dev, char *buf)
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
 	int i;
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
index 8f0f469..87302fb 100644
--- a/drivers/sbus/char/bpp.c
+++ b/drivers/sbus/char/bpp.c
@@ -79,10 +79,6 @@
 
       unsigned char run_length;
       unsigned char repeat_byte;
-
-      /* These members manage timeouts for programmed delays */
-      wait_queue_head_t wait_queue;
-      struct timer_list timer_list;
 };
 
 static struct inst instances[BPP_NO];
@@ -297,16 +293,10 @@
 
 #endif /* __sparc__ */
 
-static void bpp_wake_up(unsigned long val)
-{ wake_up(&instances[val].wait_queue); }
-
 static void snooze(unsigned long snooze_time, unsigned minor)
 {
-      init_timer(&instances[minor].timer_list);
-      instances[minor].timer_list.expires = jiffies + snooze_time + 1;
-      instances[minor].timer_list.data    = minor;
-      add_timer(&instances[minor].timer_list);
-      sleep_on (&instances[minor].wait_queue);
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(snooze_time + 1);
 }
 
 static int wait_for(unsigned short set, unsigned short clr,
@@ -880,11 +870,8 @@
       instances[idx].enhanced = 0;
       instances[idx].direction = 0;
       instances[idx].mode = COMPATIBILITY;
-      instances[idx].wait_queue = 0;
       instances[idx].run_length = 0;
       instances[idx].run_flag = 0;
-      init_timer(&instances[idx].timer_list);
-      instances[idx].timer_list.function = bpp_wake_up;
       if (!request_region(lpAddr,3, dev_name)) return;
 
       /*
@@ -977,11 +964,8 @@
       instances[idx].enhanced = 0;
       instances[idx].direction = 0;
       instances[idx].mode = COMPATIBILITY;
-      init_waitqueue_head(&instances[idx].wait_queue);
       instances[idx].run_length = 0;
       instances[idx].run_flag = 0;
-      init_timer(&instances[idx].timer_list);
-      instances[idx].timer_list.function = bpp_wake_up;
 
       if (!rp) return;
 
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index 34dbc37..bc6e462 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -1916,9 +1916,9 @@
 } /* End __twa_shutdown() */
 
 /* Wrapper for __twa_shutdown */
-static void twa_shutdown(struct device *dev)
+static void twa_shutdown(struct pci_dev *pdev)
 {
-	struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev));
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
 	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
 
 	__twa_shutdown(tw_dev);
@@ -2140,9 +2140,7 @@
 	.id_table	= twa_pci_tbl,
 	.probe		= twa_probe,
 	.remove		= twa_remove,
-	.driver		= {
-		.shutdown = twa_shutdown
-	}
+	.shutdown	= twa_shutdown
 };
 
 /* This function is called on driver initialization */
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index b6dc576..973c51f 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -2264,9 +2264,9 @@
 } /* End __tw_shutdown() */
 
 /* Wrapper for __tw_shutdown */
-static void tw_shutdown(struct device *dev)
+static void tw_shutdown(struct pci_dev *pdev)
 {
-	struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev));
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
 	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
 
 	__tw_shutdown(tw_dev);
@@ -2451,9 +2451,7 @@
 	.id_table	= tw_pci_tbl,
 	.probe		= tw_probe,
 	.remove		= tw_remove,
-	.driver		= {
-		.shutdown = tw_shutdown
-	}
+	.shutdown	= tw_shutdown,
 };
 
 /* This function is called on driver initialization */
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 9a547ca9..c562369 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -304,26 +304,19 @@
 	struct device *dev = ap->host_set->dev;
 	struct ahci_host_priv *hpriv = ap->host_set->private_data;
 	struct ahci_port_priv *pp;
-	int rc;
 	void *mem, *mmio = ap->host_set->mmio_base;
 	void *port_mmio = ahci_port_base(mmio, ap->port_no);
 	dma_addr_t mem_dma;
 
-	rc = ata_port_start(ap);
-	if (rc)
-		return rc;
-
 	pp = kmalloc(sizeof(*pp), GFP_KERNEL);
-	if (!pp) {
-		rc = -ENOMEM;
-		goto err_out;
-	}
+	if (!pp)
+		return -ENOMEM;
 	memset(pp, 0, sizeof(*pp));
 
 	mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL);
 	if (!mem) {
-		rc = -ENOMEM;
-		goto err_out_kfree;
+		kfree(pp);
+		return -ENOMEM;
 	}
 	memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ);
 
@@ -373,12 +366,6 @@
 	readl(port_mmio + PORT_CMD); /* flush */
 
 	return 0;
-
-err_out_kfree:
-	kfree(pp);
-err_out:
-	ata_port_stop(ap);
-	return rc;
 }
 
 
@@ -404,7 +391,6 @@
 	dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ,
 			  pp->cmd_slot, pp->cmd_slot_dma);
 	kfree(pp);
-	ata_port_stop(ap);
 }
 
 static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in)
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 80d0226..babd483 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -6012,7 +6012,7 @@
 
 /**
  * ipr_shutdown - Shutdown handler.
- * @dev:	device struct
+ * @pdev:	pci device struct
  *
  * This function is invoked upon system shutdown/reboot. It will issue
  * an adapter shutdown to the adapter to flush the write cache.
@@ -6020,9 +6020,9 @@
  * Return value:
  * 	none
  **/
-static void ipr_shutdown(struct device *dev)
+static void ipr_shutdown(struct pci_dev *pdev)
 {
-	struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(to_pci_dev(dev));
+	struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev);
 	unsigned long lock_flags = 0;
 
 	spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
@@ -6068,9 +6068,7 @@
 	.id_table = ipr_pci_table,
 	.probe = ipr_probe,
 	.remove = ipr_remove,
-	.driver = {
-		.shutdown = ipr_shutdown,
-	},
+	.shutdown = ipr_shutdown,
 };
 
 /**
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 36b401f..cb535fa 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -1408,7 +1408,9 @@
 	if (ap->flags & ATA_FLAG_SATA_RESET) {
 		/* issue phy wake/reset */
 		scr_write_flush(ap, SCR_CONTROL, 0x301);
-		udelay(400);			/* FIXME: a guess */
+		/* Couldn't find anything in SATA I/II specs, but
+		 * AHCI-1.1 10.4.2 says at least 1 ms. */
+		mdelay(1);
 	}
 	scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */
 
@@ -1920,6 +1922,7 @@
 	"HITACHI CDR-8335",
 	"HITACHI CDR-8435",
 	"Toshiba CD-ROM XM-6202B",
+	"TOSHIBA CD-ROM XM-1702BC",
 	"CD-532E-A",
 	"E-IDE CD-ROM CR-840",
 	"CD-ROM Drive/F5A",
@@ -1927,7 +1930,6 @@
 	"SAMSUNG CD-ROM SC-148C",
 	"SAMSUNG CD-ROM SC",
 	"SanDisk SDP3B-64",
-	"SAMSUNG CD-ROM SN-124",
 	"ATAPI CD-ROM DRIVE 40X MAXIMUM",
 	"_NEC DV5800A",
 };
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c
index edd47d1..932dcf0 100644
--- a/drivers/scsi/mac53c94.c
+++ b/drivers/scsi/mac53c94.c
@@ -424,7 +424,7 @@
 	.use_clustering	= DISABLE_CLUSTERING,
 };
 
-static int mac53c94_probe(struct macio_dev *mdev, const struct of_match *match)
+static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *match)
 {
 	struct device_node *node = macio_get_of_node(mdev);
 	struct pci_dev *pdev = macio_get_pci_dev(mdev);
@@ -544,15 +544,14 @@
 }
 
 
-static struct of_match mac53c94_match[] = 
+static struct of_device_id mac53c94_match[] = 
 {
 	{
 	.name 		= "53c94",
-	.type		= OF_ANY_MATCH,
-	.compatible	= OF_ANY_MATCH
 	},
 	{},
 };
+MODULE_DEVICE_TABLE (of, mac53c94_match);
 
 static struct macio_driver mac53c94_driver = 
 {
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index ec81532..a70cdf3 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -5036,9 +5036,9 @@
 }
 
 static void
-megaraid_shutdown(struct device *dev)
+megaraid_shutdown(struct pci_dev *pdev)
 {
-	struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev));
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
 	adapter_t *adapter = (adapter_t *)host->hostdata;
 
 	__megaraid_shutdown(adapter);
@@ -5070,9 +5070,7 @@
 	.id_table	= megaraid_pci_tbl,
 	.probe		= megaraid_probe_one,
 	.remove		= __devexit_p(megaraid_remove_one),
-	.driver		= {
-		.shutdown = megaraid_shutdown,
-	},
+	.shutdown	= megaraid_shutdown,
 };
 
 static int __init megaraid_init(void)
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index b05737a..ff19332 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -1847,7 +1847,7 @@
 	.use_clustering			= DISABLE_CLUSTERING,
 };
 
-static int mesh_probe(struct macio_dev *mdev, const struct of_match *match)
+static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match)
 {
 	struct device_node *mesh = macio_get_of_node(mdev);
 	struct pci_dev* pdev = macio_get_pci_dev(mdev);
@@ -2012,20 +2012,18 @@
 }
 
 
-static struct of_match mesh_match[] = 
+static struct of_device_id mesh_match[] = 
 {
 	{
 	.name 		= "mesh",
-	.type		= OF_ANY_MATCH,
-	.compatible	= OF_ANY_MATCH
 	},
 	{
-	.name 		= OF_ANY_MATCH,
 	.type		= "scsi",
 	.compatible	= "chrp,mesh0"
 	},
 	{},
 };
+MODULE_DEVICE_TABLE (of, mesh_match);
 
 static struct macio_driver mesh_driver = 
 {
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 621dee8..10506f9 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -632,7 +632,7 @@
 {
 	struct scsi_host_sg_pool *sgp;
 
-	BUG_ON(index > SG_MEMPOOL_NR);
+	BUG_ON(index >= SG_MEMPOOL_NR);
 
 	sgp = scsi_sg_pools + index;
 	mempool_free(sgl, sgp->pool);
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 34e75bc..7e8fc7c 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -105,7 +105,7 @@
 	SERIAL_PORT_DFNS /* defined in asm/serial.h */
 };
 
-#define UART_NR	(ARRAY_SIZE(old_serial_port) + CONFIG_SERIAL_8250_NR_UARTS)
+#define UART_NR	CONFIG_SERIAL_8250_NR_UARTS
 
 #ifdef CONFIG_SERIAL_8250_RSA
 
@@ -993,21 +993,24 @@
 	up->port.irq = (irq > 0) ? irq : 0;
 }
 
+static inline void __stop_tx(struct uart_8250_port *p)
+{
+	if (p->ier & UART_IER_THRI) {
+		p->ier &= ~UART_IER_THRI;
+		serial_out(p, UART_IER, p->ier);
+	}
+}
+
 static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop)
 {
 	struct uart_8250_port *up = (struct uart_8250_port *)port;
 
-	if (up->ier & UART_IER_THRI) {
-		up->ier &= ~UART_IER_THRI;
-		serial_out(up, UART_IER, up->ier);
-	}
+	__stop_tx(up);
 
 	/*
-	 * We only do this from uart_stop - if we run out of
-	 * characters to send, we don't want to prevent the
-	 * FIFO from emptying.
+	 * We really want to stop the transmitter from sending.
 	 */
-	if (up->port.type == PORT_16C950 && tty_stop) {
+	if (up->port.type == PORT_16C950) {
 		up->acr |= UART_ACR_TXDIS;
 		serial_icr_write(up, UART_ACR, up->acr);
 	}
@@ -1031,10 +1034,11 @@
 				transmit_chars(up);
 		}
 	}
+
 	/*
-	 * We only do this from uart_start
+	 * Re-enable the transmitter if we disabled it.
 	 */
-	if (tty_start && up->port.type == PORT_16C950) {
+	if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) {
 		up->acr &= ~UART_ACR_TXDIS;
 		serial_icr_write(up, UART_ACR, up->acr);
 	}
@@ -1155,7 +1159,7 @@
 		return;
 	}
 	if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
-		serial8250_stop_tx(&up->port, 0);
+		__stop_tx(up);
 		return;
 	}
 
@@ -1174,7 +1178,7 @@
 	DEBUG_INTR("THRE...");
 
 	if (uart_circ_empty(xmit))
-		serial8250_stop_tx(&up->port, 0);
+		__stop_tx(up);
 }
 
 static _INLINE_ void check_modem_status(struct uart_8250_port *up)
@@ -1376,13 +1380,10 @@
 static unsigned int serial8250_get_mctrl(struct uart_port *port)
 {
 	struct uart_8250_port *up = (struct uart_8250_port *)port;
-	unsigned long flags;
 	unsigned char status;
 	unsigned int ret;
 
-	spin_lock_irqsave(&up->port.lock, flags);
 	status = serial_in(up, UART_MSR);
-	spin_unlock_irqrestore(&up->port.lock, flags);
 
 	ret = 0;
 	if (status & UART_MSR_DCD)
@@ -2060,7 +2061,8 @@
 		up->port.ops = &serial8250_pops;
 	}
 
-	for (i = 0, up = serial8250_ports; i < ARRAY_SIZE(old_serial_port);
+	for (i = 0, up = serial8250_ports;
+	     i < ARRAY_SIZE(old_serial_port) && i < UART_NR;
 	     i++, up++) {
 		up->port.iobase   = old_serial_port[i].port;
 		up->port.irq      = irq_canonicalize(old_serial_port[i].irq);
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index e879bce..e0d0a47 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -86,7 +86,7 @@
 	  namespace, say Y here.  If unsure, say N.
 
 config SERIAL_8250_NR_UARTS
-	int "Maximum number of non-legacy 8250/16550 serial ports"
+	int "Maximum number of 8250/16550 serial ports"
 	depends on SERIAL_8250
 	default "4"
 	help
diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c
index 5400dc2..6104aee 100644
--- a/drivers/serial/au1x00_uart.c
+++ b/drivers/serial/au1x00_uart.c
@@ -556,13 +556,10 @@
 static unsigned int serial8250_get_mctrl(struct uart_port *port)
 {
 	struct uart_8250_port *up = (struct uart_8250_port *)port;
-	unsigned long flags;
 	unsigned char status;
 	unsigned int ret;
 
-	spin_lock_irqsave(&up->port.lock, flags);
 	status = serial_in(up, UART_MSR);
-	spin_unlock_irqrestore(&up->port.lock, flags);
 
 	ret = 0;
 	if (status & UART_MSR_DCD)
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
index de26cf7..7911912 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -94,12 +94,42 @@
 		((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits;
 	}
 
+#ifdef CONFIG_MPC885ADS
+	/* Enable SMC1 transceivers */
+	{
+		volatile uint __iomem *bcsr1 = ioremap(BCSR1, 4);
+		uint tmp;
+
+		tmp = in_be32(bcsr1);
+		tmp &= ~BCSR1_RS232EN_1;
+		out_be32(bcsr1, tmp);
+		iounmap(bcsr1);
+	}
+#endif
+
 	pinfo->brg = 1;
 }
 
 void smc2_lineif(struct uart_cpm_port *pinfo)
 {
-	/* XXX SMC2: insert port configuration here */
+#ifdef CONFIG_MPC885ADS
+	volatile cpm8xx_t *cp = cpmp;
+	volatile uint __iomem *bcsr1;
+	uint tmp;
+
+	cp->cp_pepar |= 0x00000c00;
+	cp->cp_pedir &= ~0x00000c00;
+	cp->cp_peso &= ~0x00000400;
+	cp->cp_peso |= 0x00000800;
+
+	/* Enable SMC2 transceivers */
+	bcsr1 = ioremap(BCSR1, 4);
+	tmp = in_be32(bcsr1);
+	tmp &= ~BCSR1_RS232EN_2;
+	out_be32(bcsr1, tmp);
+	iounmap(bcsr1);
+#endif
+
 	pinfo->brg = 2;
 }
 
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c
index 3ea46c0..ea5bf4d 100644
--- a/drivers/serial/ip22zilog.c
+++ b/drivers/serial/ip22zilog.c
@@ -518,27 +518,28 @@
 static __inline__ unsigned char ip22zilog_read_channel_status(struct uart_port *port)
 {
 	struct zilog_channel *channel;
-	unsigned long flags;
 	unsigned char status;
 
-	spin_lock_irqsave(&port->lock, flags);
-
 	channel = ZILOG_CHANNEL_FROM_PORT(port);
 	status = readb(&channel->control);
 	ZSDELAY();
 
-	spin_unlock_irqrestore(&port->lock, flags);
-
 	return status;
 }
 
 /* The port lock is not held.  */
 static unsigned int ip22zilog_tx_empty(struct uart_port *port)
 {
+	unsigned long flags;
 	unsigned char status;
 	unsigned int ret;
 
+	spin_lock_irqsave(&port->lock, flags);
+
 	status = ip22zilog_read_channel_status(port);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+
 	if (status & Tx_BUF_EMP)
 		ret = TIOCSER_TEMT;
 	else
@@ -547,7 +548,7 @@
 	return ret;
 }
 
-/* The port lock is not held.  */
+/* The port lock is held and interrupts are disabled.  */
 static unsigned int ip22zilog_get_mctrl(struct uart_port *port)
 {
 	unsigned char status;
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index a2a6433..e43276c 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -1058,12 +1058,9 @@
 {
 	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
 	u32 mflags, status;
-	ulong iflags;
 
-	spin_lock_irqsave(&pi->port.lock, iflags);
 	status = (pi->mirror_regs) ? pi->MPSC_CHR_10_m :
 		readl(pi->mpsc_base + MPSC_CHR_10);
-	spin_unlock_irqrestore(&pi->port.lock, iflags);
 
 	mflags = 0;
 	if (status & 0x1)
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index 85abd8a..7db2f37 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -604,7 +604,7 @@
 /* 
  * Get Modem Control bits (only the input ones, the core will
  * or that with a cached value of the control ones)
- * The port lock is not held.
+ * The port lock is held and interrupts are disabled.
  */
 static unsigned int pmz_get_mctrl(struct uart_port *port)
 {
@@ -615,7 +615,7 @@
 	if (ZS_IS_ASLEEP(uap) || uap->node == NULL)
 		return 0;
 
-	status = pmz_peek_status(to_pmz(port));
+	status = read_zsreg(uap, R0);
 
 	ret = 0;
 	if (status & DCD)
@@ -1545,7 +1545,7 @@
 /*
  * Called upon match with an escc node in the devive-tree.
  */
-static int pmz_attach(struct macio_dev *mdev, const struct of_match *match)
+static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match)
 {
 	int i;
 	
@@ -1850,20 +1850,17 @@
 	return rc;
 }
 
-static struct of_match pmz_match[] = 
+static struct of_device_id pmz_match[] = 
 {
 	{
 	.name 		= "ch-a",
-	.type		= OF_ANY_MATCH,
-	.compatible	= OF_ANY_MATCH
 	},
 	{
 	.name 		= "ch-b",
-	.type		= OF_ANY_MATCH,
-	.compatible	= OF_ANY_MATCH
 	},
 	{},
 };
+MODULE_DEVICE_TABLE (of, pmz_match);
 
 static struct macio_driver pmz_driver = 
 {
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index 08b08d6..461c81c 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -274,14 +274,11 @@
 static unsigned int serial_pxa_get_mctrl(struct uart_port *port)
 {
 	struct uart_pxa_port *up = (struct uart_pxa_port *)port;
-	unsigned long flags;
 	unsigned char status;
 	unsigned int ret;
 
 return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
-	spin_lock_irqsave(&up->port.lock, flags);
 	status = serial_in(up, UART_MSR);
-	spin_unlock_irqrestore(&up->port.lock, flags);
 
 	ret = 0;
 	if (status & UART_MSR_DCD)
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 5c46784..7365d4b 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -522,14 +522,11 @@
 static int s3c24xx_serial_startup(struct uart_port *port)
 {
 	struct s3c24xx_uart_port *ourport = to_ourport(port);
-	unsigned long flags;
 	int ret;
 
 	dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n",
 	    port->mapbase, port->membase);
 
-	local_irq_save(flags);
-
 	rx_enabled(port) = 1;
 
 	ret = request_irq(RX_IRQ(port),
@@ -563,12 +560,10 @@
 	/* the port reset code should have done the correct
 	 * register setup for the port controls */
 
-	local_irq_restore(flags);
 	return ret;
 
  err:
 	s3c24xx_serial_shutdown(port);
-	local_irq_restore(flags);
 	return ret;
 }
 
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 36b1ae0..54699c3 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -182,6 +182,13 @@
 				uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
 		}
 
+		if (info->flags & UIF_CTS_FLOW) {
+			spin_lock_irq(&port->lock);
+			if (!(port->ops->get_mctrl(port) & TIOCM_CTS))
+				info->tty->hw_stopped = 1;
+			spin_unlock_irq(&port->lock);
+		}
+
 		info->flags |= UIF_INITIALIZED;
 
 		clear_bit(TTY_IO_ERROR, &info->tty->flags);
@@ -828,7 +835,10 @@
 	if ((!file || !tty_hung_up_p(file)) &&
 	    !(tty->flags & (1 << TTY_IO_ERROR))) {
 		result = port->mctrl;
+
+		spin_lock_irq(&port->lock);
 		result |= port->ops->get_mctrl(port);
+		spin_unlock_irq(&port->lock);
 	}
 	up(&state->sem);
 
@@ -1131,6 +1141,16 @@
 		spin_unlock_irqrestore(&state->port->lock, flags);
 	}
 
+	/* Handle turning on CRTSCTS */
+	if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
+		spin_lock_irqsave(&state->port->lock, flags);
+		if (!(state->port->ops->get_mctrl(state->port) & TIOCM_CTS)) {
+			tty->hw_stopped = 1;
+			state->port->ops->stop_tx(state->port, 0);
+		}
+		spin_unlock_irqrestore(&state->port->lock, flags);
+	}
+
 #if 0
 	/*
 	 * No need to wake up processes in open wait, since they
@@ -1369,6 +1389,7 @@
 	DECLARE_WAITQUEUE(wait, current);
 	struct uart_info *info = state->info;
 	struct uart_port *port = state->port;
+	unsigned int mctrl;
 
 	info->blocked_open++;
 	state->count--;
@@ -1416,7 +1437,10 @@
 		 * and wait for the carrier to indicate that the
 		 * modem is ready for us.
 		 */
-		if (port->ops->get_mctrl(port) & TIOCM_CAR)
+		spin_lock_irq(&port->lock);
+		mctrl = port->ops->get_mctrl(port);
+		spin_unlock_irq(&port->lock);
+		if (mctrl & TIOCM_CAR)
 			break;
 
 		up(&state->sem);
@@ -1618,7 +1642,9 @@
 
 	if(capable(CAP_SYS_ADMIN))
 	{
+		spin_lock_irq(&port->lock);
 		status = port->ops->get_mctrl(port);
+		spin_unlock_irq(&port->lock);
 
 		ret += sprintf(buf + ret, " tx:%d rx:%d",
 				port->icount.tx, port->icount.rx);
@@ -1782,6 +1808,12 @@
 	struct termios termios;
 	int i;
 
+	/*
+	 * Ensure that the serial console lock is initialised
+	 * early.
+	 */
+	spin_lock_init(&port->lock);
+
 	memset(&termios, 0, sizeof(struct termios));
 
 	termios.c_cflag = CREAD | HUPCL | CLOCAL;
@@ -2170,10 +2202,16 @@
 
 	state->port = port;
 
-	spin_lock_init(&port->lock);
 	port->cons = drv->cons;
 	port->info = state->info;
 
+	/*
+	 * If this port is a console, then the spinlock is already
+	 * initialised.
+	 */
+	if (!uart_console(port))
+		spin_lock_init(&port->lock);
+
 	uart_configure_port(drv, state, port);
 
 	/*
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 3f1051a..d085030 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -442,13 +442,10 @@
 static unsigned int serial_txx9_get_mctrl(struct uart_port *port)
 {
 	struct uart_txx9_port *up = (struct uart_txx9_port *)port;
-	unsigned long flags;
 	unsigned int ret;
 
-	spin_lock_irqsave(&up->port.lock, flags);
 	ret =  ((sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS)
 		| ((sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS);
-	spin_unlock_irqrestore(&up->port.lock, flags);
 
 	return ret;
 }
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 10e2990..8d19888 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -426,18 +426,15 @@
 		sunsab_tx_idle(up);
 }
 
-/* port->lock is not held.  */
+/* port->lock is held by caller and interrupts are disabled.  */
 static unsigned int sunsab_get_mctrl(struct uart_port *port)
 {
 	struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
-	unsigned long flags;
 	unsigned char val;
 	unsigned int result;
 
 	result = 0;
 
-	spin_lock_irqsave(&up->port.lock, flags);
-
 	val = readb(&up->regs->r.pvr);
 	result |= (val & up->pvr_dsr_bit) ? 0 : TIOCM_DSR;
 
@@ -447,8 +444,6 @@
 	val = readb(&up->regs->r.star);
 	result |= (val & SAB82532_STAR_CTS) ? TIOCM_CTS : 0;
 
-	spin_unlock_irqrestore(&up->port.lock, flags);
-
 	return result;
 }
 
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index ddc97c9..d57a355 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -572,13 +572,10 @@
 static unsigned int sunsu_get_mctrl(struct uart_port *port)
 {
 	struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
-	unsigned long flags;
 	unsigned char status;
 	unsigned int ret;
 
-	spin_lock_irqsave(&up->port.lock, flags);
 	status = serial_in(up, UART_MSR);
-	spin_unlock_irqrestore(&up->port.lock, flags);
 
 	ret = 0;
 	if (status & UART_MSR_DCD)
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 8e65206..bff42a7 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -610,27 +610,28 @@
 static __inline__ unsigned char sunzilog_read_channel_status(struct uart_port *port)
 {
 	struct zilog_channel __iomem *channel;
-	unsigned long flags;
 	unsigned char status;
 
-	spin_lock_irqsave(&port->lock, flags);
-
 	channel = ZILOG_CHANNEL_FROM_PORT(port);
 	status = sbus_readb(&channel->control);
 	ZSDELAY();
 
-	spin_unlock_irqrestore(&port->lock, flags);
-
 	return status;
 }
 
 /* The port lock is not held.  */
 static unsigned int sunzilog_tx_empty(struct uart_port *port)
 {
+	unsigned long flags;
 	unsigned char status;
 	unsigned int ret;
 
+	spin_lock_irqsave(&port->lock, flags);
+
 	status = sunzilog_read_channel_status(port);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+
 	if (status & Tx_BUF_EMP)
 		ret = TIOCSER_TEMT;
 	else
@@ -639,7 +640,7 @@
 	return ret;
 }
 
-/* The port lock is not held.  */
+/* The port lock is held and interrupts are disabled.  */
 static unsigned int sunzilog_get_mctrl(struct uart_port *port)
 {
 	unsigned char status;
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index b209adb..9dd0fbc 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -142,7 +142,6 @@
 #define CURSOR_DRAW_DELAY		(1)
 
 /* # VBL ints between cursor state changes */
-#define ARM_CURSOR_BLINK_RATE		(10)
 #define ATARI_CURSOR_BLINK_RATE		(42)
 #define MAC_CURSOR_BLINK_RATE		(32)
 #define DEFAULT_CURSOR_BLINK_RATE	(20)
@@ -288,7 +287,7 @@
 	release_console_sem();
 }
 
-#if (defined(__arm__) && defined(IRQ_VSYNCPULSE)) || defined(CONFIG_ATARI) || defined(CONFIG_MAC)
+#if defined(CONFIG_ATARI) || defined(CONFIG_MAC)
 static int cursor_blink_rate;
 static irqreturn_t fb_vbl_handler(int irq, void *dev_id, struct pt_regs *fp)
 {
@@ -878,11 +877,6 @@
 	}
 #endif				/* CONFIG_MAC */
 
-#if defined(__arm__) && defined(IRQ_VSYNCPULSE)
-	cursor_blink_rate = ARM_CURSOR_BLINK_RATE;
-	irqres = request_irq(IRQ_VSYNCPULSE, fb_vbl_handler, SA_SHIRQ,
-			     "framebuffer vbl", info);
-#endif
 	/* Initialize the work queue. If the driver provides its
 	 * own work queue this means it will use something besides 
 	 * default timer to flash the cursor. */
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index 3dd1de1..b00887e 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -523,7 +523,7 @@
 #define invalidate_cache(addr)
 #endif
 
-static int __devinit platinumfb_probe(struct of_device* odev, const struct of_match *match)
+static int __devinit platinumfb_probe(struct of_device* odev, const struct of_device_id *match)
 {
 	struct device_node	*dp = odev->node;
 	struct fb_info		*info;
@@ -647,12 +647,10 @@
 	return 0;
 }
 
-static struct of_match platinumfb_match[] = 
+static struct of_device_id platinumfb_match[] = 
 {
 	{
 	.name 		= "platinum",
-	.type		= OF_ANY_MATCH,
-	.compatible	= OF_ANY_MATCH,
 	},
 	{},
 };
diff --git a/fs/aio.c b/fs/aio.c
index 7afa222..06d7d43 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -58,6 +58,7 @@
 static LIST_HEAD(fput_head);
 
 static void aio_kick_handler(void *);
+static void aio_queue_work(struct kioctx *);
 
 /* aio_setup
  *	Creates the slab caches used by the aio routines, panic on
@@ -747,6 +748,14 @@
 		 * has already been kicked */
 		if (kiocbIsKicked(iocb)) {
 			__queue_kicked_iocb(iocb);
+
+			/*
+			 * __queue_kicked_iocb will always return 1 here, because
+			 * iocb->ki_run_list is empty at this point so it should
+			 * be safe to unconditionally queue the context into the
+			 * work queue.
+			 */
+			aio_queue_work(ctx);
 		}
 	}
 	return ret;
diff --git a/fs/buffer.c b/fs/buffer.c
index 13e5938..561e63a 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -278,7 +278,7 @@
  */
 static void do_sync(unsigned long wait)
 {
-	wakeup_bdflush(0);
+	wakeup_pdflush(0);
 	sync_inodes(0);		/* All mappings, inodes and their blockdevs */
 	DQUOT_SYNC(NULL);
 	sync_supers();		/* Write the superblocks */
@@ -497,7 +497,7 @@
 	struct zone **zones;
 	pg_data_t *pgdat;
 
-	wakeup_bdflush(1024);
+	wakeup_pdflush(1024);
 	yield();
 
 	for_each_pgdat(pgdat) {
diff --git a/fs/char_dev.c b/fs/char_dev.c
index e82aac9..a69a5d8 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -150,7 +150,7 @@
 	struct char_device_struct *cd = NULL, **cp;
 	int i = major_to_index(major);
 
-	up(&chrdevs_lock);
+	down(&chrdevs_lock);
 	for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
 		if ((*cp)->major == major &&
 		    (*cp)->baseminor == baseminor &&
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index ccd632f..e463dca 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -749,24 +749,24 @@
  * 	to find a free region that is of my size and has not
  * 	been reserved.
  *
- *	on succeed, it returns the reservation window to be appended to.
- *	failed, return NULL.
  */
-static struct ext3_reserve_window_node *find_next_reservable_window(
+static int find_next_reservable_window(
 				struct ext3_reserve_window_node *search_head,
-				unsigned long size, int *start_block,
+				struct ext3_reserve_window_node *my_rsv,
+				struct super_block * sb, int start_block,
 				int last_block)
 {
 	struct rb_node *next;
 	struct ext3_reserve_window_node *rsv, *prev;
 	int cur;
+	int size = my_rsv->rsv_goal_size;
 
 	/* TODO: make the start of the reservation window byte-aligned */
 	/* cur = *start_block & ~7;*/
-	cur = *start_block;
+	cur = start_block;
 	rsv = search_head;
 	if (!rsv)
-		return NULL;
+		return -1;
 
 	while (1) {
 		if (cur <= rsv->rsv_end)
@@ -782,11 +782,11 @@
 		 * space with expected-size (or more)...
 		 */
 		if (cur > last_block)
-			return NULL;		/* fail */
+			return -1;		/* fail */
 
 		prev = rsv;
 		next = rb_next(&rsv->rsv_node);
-		rsv = list_entry(next, struct ext3_reserve_window_node, rsv_node);
+		rsv = list_entry(next,struct ext3_reserve_window_node,rsv_node);
 
 		/*
 		 * Reached the last reservation, we can just append to the
@@ -813,8 +813,25 @@
 	 * return the reservation window that we could append to.
 	 * succeed.
 	 */
-	*start_block = cur;
-	return prev;
+
+	if ((prev != my_rsv) && (!rsv_is_empty(&my_rsv->rsv_window)))
+		rsv_window_remove(sb, my_rsv);
+
+	/*
+	 * Let's book the whole avaliable window for now.  We will check the
+	 * disk bitmap later and then, if there are free blocks then we adjust
+	 * the window size if it's larger than requested.
+	 * Otherwise, we will remove this node from the tree next time
+	 * call find_next_reservable_window.
+	 */
+	my_rsv->rsv_start = cur;
+	my_rsv->rsv_end = cur + size - 1;
+	my_rsv->rsv_alloc_hit = 0;
+
+	if (prev != my_rsv)
+		ext3_rsv_window_add(sb, my_rsv);
+
+	return 0;
 }
 
 /**
@@ -852,6 +869,7 @@
  *	@sb: the super block
  *	@group: the group we are trying to allocate in
  *	@bitmap_bh: the block group block bitmap
+ *
  */
 static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv,
 		int goal, struct super_block *sb,
@@ -860,10 +878,10 @@
 	struct ext3_reserve_window_node *search_head;
 	int group_first_block, group_end_block, start_block;
 	int first_free_block;
-	int reservable_space_start;
-	struct ext3_reserve_window_node *prev_rsv;
 	struct rb_root *fs_rsv_root = &EXT3_SB(sb)->s_rsv_window_root;
 	unsigned long size;
+	int ret;
+	spinlock_t *rsv_lock = &EXT3_SB(sb)->s_rsv_window_lock;
 
 	group_first_block = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
 				group * EXT3_BLOCKS_PER_GROUP(sb);
@@ -875,6 +893,7 @@
 		start_block = goal + group_first_block;
 
 	size = my_rsv->rsv_goal_size;
+
 	if (!rsv_is_empty(&my_rsv->rsv_window)) {
 		/*
 		 * if the old reservation is cross group boundary
@@ -908,6 +927,8 @@
 			my_rsv->rsv_goal_size= size;
 		}
 	}
+
+	spin_lock(rsv_lock);
 	/*
 	 * shift the search start to the window near the goal block
 	 */
@@ -921,11 +942,16 @@
 	 * need to check the bitmap after we found a reservable window.
 	 */
 retry:
-	prev_rsv = find_next_reservable_window(search_head, size,
-						&start_block, group_end_block);
-	if (prev_rsv == NULL)
-		goto failed;
-	reservable_space_start = start_block;
+	ret = find_next_reservable_window(search_head, my_rsv, sb,
+						start_block, group_end_block);
+
+	if (ret == -1) {
+		if (!rsv_is_empty(&my_rsv->rsv_window))
+			rsv_window_remove(sb, my_rsv);
+		spin_unlock(rsv_lock);
+		return -1;
+	}
+
 	/*
 	 * On success, find_next_reservable_window() returns the
 	 * reservation window where there is a reservable space after it.
@@ -937,8 +963,9 @@
 	 * block. Search start from the start block of the reservable space
 	 * we just found.
 	 */
+	spin_unlock(rsv_lock);
 	first_free_block = bitmap_search_next_usable_block(
-			reservable_space_start - group_first_block,
+			my_rsv->rsv_start - group_first_block,
 			bitmap_bh, group_end_block - group_first_block + 1);
 
 	if (first_free_block < 0) {
@@ -946,54 +973,29 @@
 		 * no free block left on the bitmap, no point
 		 * to reserve the space. return failed.
 		 */
-		goto failed;
+		spin_lock(rsv_lock);
+		if (!rsv_is_empty(&my_rsv->rsv_window))
+			rsv_window_remove(sb, my_rsv);
+		spin_unlock(rsv_lock);
+		return -1;		/* failed */
 	}
+
 	start_block = first_free_block + group_first_block;
 	/*
 	 * check if the first free block is within the
-	 * free space we just found
+	 * free space we just reserved
 	 */
-	if ((start_block >= reservable_space_start) &&
-	  (start_block < reservable_space_start + size))
-		goto found_rsv_window;
+	if (start_block >= my_rsv->rsv_start && start_block < my_rsv->rsv_end)
+		return 0;		/* success */
 	/*
 	 * if the first free bit we found is out of the reservable space
-	 * this means there is no free block on the reservable space
-	 * we should continue search for next reservable space,
+	 * continue search for next reservable space,
 	 * start from where the free block is,
 	 * we also shift the list head to where we stopped last time
 	 */
-	search_head = prev_rsv;
+	search_head = my_rsv;
+	spin_lock(rsv_lock);
 	goto retry;
-
-found_rsv_window:
-	/*
-	 * great! the reservable space contains some free blocks.
-	 * if the search returns that we should add the new
-	 * window just next to where the old window, we don't
- 	 * need to remove the old window first then add it to the
-	 * same place, just update the new start and new end.
-	 */
-	if (my_rsv != prev_rsv)  {
-		if (!rsv_is_empty(&my_rsv->rsv_window))
-			rsv_window_remove(sb, my_rsv);
-	}
-	my_rsv->rsv_start = reservable_space_start;
-	my_rsv->rsv_end = my_rsv->rsv_start + size - 1;
-	my_rsv->rsv_alloc_hit = 0;
-	if (my_rsv != prev_rsv)  {
-		ext3_rsv_window_add(sb, my_rsv);
-	}
-	return 0;		/* succeed */
-failed:
-	/*
-	 * failed to find a new reservation window in the current
-	 * group, remove the current(stale) reservation window
-	 * if there is any
-	 */
-	if (!rsv_is_empty(&my_rsv->rsv_window))
-		rsv_window_remove(sb, my_rsv);
-	return -1;		/* failed */
 }
 
 /*
@@ -1023,7 +1025,6 @@
 			int goal, struct ext3_reserve_window_node * my_rsv,
 			int *errp)
 {
-	spinlock_t *rsv_lock;
 	unsigned long group_first_block;
 	int ret = 0;
 	int fatal;
@@ -1052,7 +1053,6 @@
 		ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal, NULL);
 		goto out;
 	}
-	rsv_lock = &EXT3_SB(sb)->s_rsv_window_lock;
 	/*
 	 * goal is a group relative block number (if there is a goal)
 	 * 0 < goal < EXT3_BLOCKS_PER_GROUP(sb)
@@ -1078,30 +1078,21 @@
 	 * then we could go to allocate from the reservation window directly.
 	 */
 	while (1) {
-		struct ext3_reserve_window rsv_copy;
-
-		rsv_copy._rsv_start = my_rsv->rsv_start;
-		rsv_copy._rsv_end = my_rsv->rsv_end;
-
-		if (rsv_is_empty(&rsv_copy) || (ret < 0) ||
-			!goal_in_my_reservation(&rsv_copy, goal, group, sb)) {
-			spin_lock(rsv_lock);
+		if (rsv_is_empty(&my_rsv->rsv_window) || (ret < 0) ||
+			!goal_in_my_reservation(&my_rsv->rsv_window, goal, group, sb)) {
 			ret = alloc_new_reservation(my_rsv, goal, sb,
 							group, bitmap_bh);
-			rsv_copy._rsv_start = my_rsv->rsv_start;
-			rsv_copy._rsv_end = my_rsv->rsv_end;
-			spin_unlock(rsv_lock);
 			if (ret < 0)
 				break;			/* failed */
 
-			if (!goal_in_my_reservation(&rsv_copy, goal, group, sb))
+			if (!goal_in_my_reservation(&my_rsv->rsv_window, goal, group, sb))
 				goal = -1;
 		}
-		if ((rsv_copy._rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb))
-		    || (rsv_copy._rsv_end < group_first_block))
+		if ((my_rsv->rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb))
+		    || (my_rsv->rsv_end < group_first_block))
 			BUG();
 		ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal,
-					   &rsv_copy);
+					   &my_rsv->rsv_window);
 		if (ret >= 0) {
 			my_rsv->rsv_alloc_hit++;
 			break;				/* succeed */
diff --git a/fs/ext3/file.c b/fs/ext3/file.c
index 5ad8cf02..98e7834 100644
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -36,7 +36,11 @@
 	/* if we are the last writer on the inode, drop the block reservation */
 	if ((filp->f_mode & FMODE_WRITE) &&
 			(atomic_read(&inode->i_writecount) == 1))
+	{
+		down(&EXT3_I(inode)->truncate_sem);
 		ext3_discard_reservation(inode);
+		up(&EXT3_I(inode)->truncate_sem);
+	}
 	if (is_dx(inode) && filp->private_data)
 		ext3_htree_free_dir_info(filp->private_data);
 
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index b4b3e8a..a6d1779 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -944,7 +944,8 @@
 					"for remount\n");
 				return 0;
 			}
-			match_int(&args[0], &option);
+			if (match_int(&args[0], &option) != 0)
+				return 0;
 			*n_blocks_count = option;
 			break;
 		case Opt_nobh:
diff --git a/fs/fat/cache.c b/fs/fat/cache.c
index 7c52e46..77c24fc 100644
--- a/fs/fat/cache.c
+++ b/fs/fat/cache.c
@@ -56,7 +56,7 @@
 	return 0;
 }
 
-void __exit fat_cache_destroy(void)
+void fat_cache_destroy(void)
 {
 	if (kmem_cache_destroy(fat_cache_cachep))
 		printk(KERN_INFO "fat_cache: not all structures were freed\n");
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 8ccee84..96ae85b 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -1327,16 +1327,25 @@
 EXPORT_SYMBOL(fat_fill_super);
 
 int __init fat_cache_init(void);
-void __exit fat_cache_destroy(void);
+void fat_cache_destroy(void);
 
 static int __init init_fat_fs(void)
 {
-	int ret;
+	int err;
 
-	ret = fat_cache_init();
-	if (ret < 0)
-		return ret;
-	return fat_init_inodecache();
+	err = fat_cache_init();
+	if (err)
+		return err;
+
+	err = fat_init_inodecache();
+	if (err)
+		goto failed;
+
+	return 0;
+
+failed:
+	fat_cache_destroy();
+	return err;
 }
 
 static void __exit exit_fat_fs(void)
diff --git a/fs/freevxfs/vxfs.h b/fs/freevxfs/vxfs.h
index 8da0252..583bd78 100644
--- a/fs/freevxfs/vxfs.h
+++ b/fs/freevxfs/vxfs.h
@@ -37,7 +37,6 @@
  * superblocks of the Veritas Filesystem.
  */
 #include <linux/types.h>
-#include "vxfs_kcompat.h"
 
 
 /*
diff --git a/fs/freevxfs/vxfs_bmap.c b/fs/freevxfs/vxfs_bmap.c
index bc4b57d..d3f6b28 100644
--- a/fs/freevxfs/vxfs_bmap.c
+++ b/fs/freevxfs/vxfs_bmap.c
@@ -101,7 +101,7 @@
 	return 0;
 
 fail_size:
-	printk("vxfs: indirect extent to big!\n");
+	printk("vxfs: indirect extent too big!\n");
 fail_buf:
 	return 0;
 }
diff --git a/fs/freevxfs/vxfs_fshead.c b/fs/freevxfs/vxfs_fshead.c
index 05b19f7..6dee109 100644
--- a/fs/freevxfs/vxfs_fshead.c
+++ b/fs/freevxfs/vxfs_fshead.c
@@ -78,17 +78,18 @@
 	struct buffer_head		*bp;
 
 	bp = vxfs_bread(ip, which);
-	if (buffer_mapped(bp)) {
+	if (bp) {
 		struct vxfs_fsh		*fhp;
 
-		if (!(fhp = kmalloc(sizeof(*fhp), SLAB_KERNEL)))
-			return NULL;
+		if (!(fhp = kmalloc(sizeof(*fhp), GFP_KERNEL)))
+			goto out;
 		memcpy(fhp, bp->b_data, sizeof(*fhp));
 
-		brelse(bp);
+		put_bh(bp);
 		return (fhp);
 	}
-
+out:
+	brelse(bp);
 	return NULL;
 }
 
diff --git a/fs/freevxfs/vxfs_kcompat.h b/fs/freevxfs/vxfs_kcompat.h
deleted file mode 100644
index 342a4cc..0000000
--- a/fs/freevxfs/vxfs_kcompat.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef _VXFS_KCOMPAT_H
-#define _VXFS_KCOMPAT_H
-
-#include <linux/version.h>
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-
-#include <linux/blkdev.h>
-
-typedef long sector_t;
-
-/* From include/linux/fs.h (Linux 2.5.2-pre3)  */
-static inline struct buffer_head * sb_bread(struct super_block *sb, int block)
-{
-	return bread(sb->s_dev, block, sb->s_blocksize);
-}
-
-/* Dito.  */
-static inline void map_bh(struct buffer_head *bh, struct super_block *sb, int block)
-{
-	bh->b_state |= 1 << BH_Mapped;
-	bh->b_dev = sb->s_dev;
-	bh->b_blocknr = block;
-}
-
-/* From fs/block_dev.c (Linux 2.5.2-pre2)  */
-static inline int sb_set_blocksize(struct super_block *sb, int size)
-{
-	int bits;
-	if (set_blocksize(sb->s_dev, size) < 0)
-		return 0;
-	sb->s_blocksize = size;
-	for (bits = 9, size >>= 9; size >>= 1; bits++)
-		;
-	sb->s_blocksize_bits = bits;
-	return sb->s_blocksize;
-}
-
-/* Dito.  */
-static inline int sb_min_blocksize(struct super_block *sb, int size)
-{
-	int minsize = get_hardsect_size(sb->s_dev);
-	if (size < minsize)
-		size = minsize;
-	return sb_set_blocksize(sb, size);
-}
-
-#endif /* Kernel 2.4 */
-#endif /* _VXFS_KCOMPAT_H */
diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c
index 506ae25..554eb45 100644
--- a/fs/freevxfs/vxfs_lookup.c
+++ b/fs/freevxfs/vxfs_lookup.c
@@ -61,13 +61,13 @@
 };
 
  
-static __inline__ u_long
+static inline u_long
 dir_pages(struct inode *inode)
 {
 	return (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 }
  
-static __inline__ u_long
+static inline u_long
 dir_blocks(struct inode *ip)
 {
 	u_long			bsize = ip->i_sb->s_blocksize;
@@ -79,7 +79,7 @@
  *
  * len <= VXFS_NAMELEN and de != NULL are guaranteed by caller.
  */
-static __inline__ int
+static inline int
 vxfs_match(int len, const char * const name, struct vxfs_direct *de)
 {
 	if (len != de->d_namelen)
@@ -89,7 +89,7 @@
 	return !memcmp(name, de->d_name, len);
 }
 
-static __inline__ struct vxfs_direct *
+static inline struct vxfs_direct *
 vxfs_next_entry(struct vxfs_direct *de)
 {
 	return ((struct vxfs_direct *)((char*)de + de->d_reclen));
diff --git a/fs/freevxfs/vxfs_olt.c b/fs/freevxfs/vxfs_olt.c
index 7a204e3..1334762 100644
--- a/fs/freevxfs/vxfs_olt.c
+++ b/fs/freevxfs/vxfs_olt.c
@@ -38,7 +38,7 @@
 #include "vxfs_olt.h"
 
 
-static __inline__ void
+static inline void
 vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp)
 {
 	if (infp->vsi_fshino)
@@ -46,7 +46,7 @@
 	infp->vsi_fshino = fshp->olt_fsino[0];
 }
 
-static __inline__ void
+static inline void
 vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp)
 {
 	if (infp->vsi_iext)
@@ -54,7 +54,7 @@
 	infp->vsi_iext = ilistp->olt_iext[0]; 
 }
 
-static __inline__ u_long
+static inline u_long
 vxfs_oblock(struct super_block *sbp, daddr_t block, u_long bsize)
 {
 	if (sbp->s_blocksize % bsize)
@@ -104,8 +104,8 @@
 		goto fail;
 	}
 
-	oaddr = (char *)bp->b_data + op->olt_size;
-	eaddr = (char *)bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize);
+	oaddr = bp->b_data + op->olt_size;
+	eaddr = bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize);
 
 	while (oaddr < eaddr) {
 		struct vxfs_oltcommon	*ocp =
diff --git a/fs/freevxfs/vxfs_subr.c b/fs/freevxfs/vxfs_subr.c
index 5e30561..50aae77 100644
--- a/fs/freevxfs/vxfs_subr.c
+++ b/fs/freevxfs/vxfs_subr.c
@@ -36,7 +36,6 @@
 #include <linux/slab.h>
 #include <linux/pagemap.h>
 
-#include "vxfs_kcompat.h"
 #include "vxfs_extern.h"
 
 
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index 0ae2c7b..27f66d3 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -155,12 +155,11 @@
 
 	sbp->s_flags |= MS_RDONLY;
 
-	infp = kmalloc(sizeof(*infp), GFP_KERNEL);
+	infp = kcalloc(1, sizeof(*infp), GFP_KERNEL);
 	if (!infp) {
 		printk(KERN_WARNING "vxfs: unable to allocate incore superblock\n");
 		return -ENOMEM;
 	}
-	memset(infp, 0, sizeof(*infp));
 
 	bsize = sb_min_blocksize(sbp, BLOCK_SIZE);
 	if (!bsize) {
@@ -196,7 +195,7 @@
 #endif
 
 	sbp->s_magic = rsbp->vs_magic;
-	sbp->s_fs_info = (void *)infp;
+	sbp->s_fs_info = infp;
 
 	infp->vsi_raw = rsbp;
 	infp->vsi_bp = bp;
@@ -263,7 +262,7 @@
 			sizeof(struct vxfs_inode_info), 0, 
 			SLAB_RECLAIM_ACCOUNT, NULL, NULL);
 	if (vxfs_inode_cachep)
-		return (register_filesystem(&vxfs_fs_type));
+		return register_filesystem(&vxfs_fs_type);
 	return -ENOMEM;
 }
 
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c
index ee3536f..1b7a3ef 100644
--- a/fs/nfs/nfs3acl.c
+++ b/fs/nfs/nfs3acl.c
@@ -2,7 +2,7 @@
 #include <linux/nfs.h>
 #include <linux/nfs3.h>
 #include <linux/nfs_fs.h>
-#include <linux/xattr_acl.h>
+#include <linux/posix_acl_xattr.h>
 #include <linux/nfsacl.h>
 
 #define NFSDBG_FACILITY	NFSDBG_PROC
@@ -53,9 +53,9 @@
 	struct posix_acl *acl;
 	int type, error = 0;
 
-	if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0)
+	if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
 		type = ACL_TYPE_ACCESS;
-	else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0)
+	else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
 		type = ACL_TYPE_DEFAULT;
 	else
 		return -EOPNOTSUPP;
@@ -82,9 +82,9 @@
 	struct posix_acl *acl;
 	int type, error;
 
-	if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0)
+	if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
 		type = ACL_TYPE_ACCESS;
-	else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0)
+	else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
 		type = ACL_TYPE_DEFAULT;
 	else
 		return -EOPNOTSUPP;
@@ -103,9 +103,9 @@
 	struct inode *inode = dentry->d_inode;
 	int type;
 
-	if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0)
+	if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
 		type = ACL_TYPE_ACCESS;
-	else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0)
+	else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
 		type = ACL_TYPE_DEFAULT;
 	else
 		return -EOPNOTSUPP;
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index de340ff..be24ead 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -46,10 +46,9 @@
 #include <linux/nfsd/nfsfh.h>
 #include <linux/quotaops.h>
 #include <linux/dnotify.h>
-#include <linux/xattr_acl.h>
 #include <linux/posix_acl.h>
-#ifdef CONFIG_NFSD_V4
 #include <linux/posix_acl_xattr.h>
+#ifdef CONFIG_NFSD_V4
 #include <linux/xattr.h>
 #include <linux/nfs4.h>
 #include <linux/nfs4_acl.h>
@@ -1872,10 +1871,10 @@
 		return ERR_PTR(-EOPNOTSUPP);
 	switch(type) {
 		case ACL_TYPE_ACCESS:
-			name = XATTR_NAME_ACL_ACCESS;
+			name = POSIX_ACL_XATTR_ACCESS;
 			break;
 		case ACL_TYPE_DEFAULT:
-			name = XATTR_NAME_ACL_DEFAULT;
+			name = POSIX_ACL_XATTR_DEFAULT;
 			break;
 		default:
 			return ERR_PTR(-EOPNOTSUPP);
@@ -1919,17 +1918,17 @@
 		return -EOPNOTSUPP;
 	switch(type) {
 		case ACL_TYPE_ACCESS:
-			name = XATTR_NAME_ACL_ACCESS;
+			name = POSIX_ACL_XATTR_ACCESS;
 			break;
 		case ACL_TYPE_DEFAULT:
-			name = XATTR_NAME_ACL_DEFAULT;
+			name = POSIX_ACL_XATTR_DEFAULT;
 			break;
 		default:
 			return -EOPNOTSUPP;
 	}
 
 	if (acl && acl->a_count) {
-		size = xattr_acl_size(acl->a_count);
+		size = posix_acl_xattr_size(acl->a_count);
 		value = kmalloc(size, GFP_KERNEL);
 		if (!value)
 			return -ENOMEM;
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
index 94dc424..76caedf 100644
--- a/fs/reiserfs/ioctl.c
+++ b/fs/reiserfs/ioctl.c
@@ -36,10 +36,16 @@
 	/* following two cases are taken from fs/ext2/ioctl.c by Remy
 	   Card (card@masi.ibp.fr) */
 	case REISERFS_IOC_GETFLAGS:
+		if (!reiserfs_attrs (inode->i_sb))
+			return -ENOTTY;
+
 		flags = REISERFS_I(inode) -> i_attrs;
 		i_attrs_to_sd_attrs( inode, ( __u16 * ) &flags );
 		return put_user(flags, (int __user *) arg);
 	case REISERFS_IOC_SETFLAGS: {
+		if (!reiserfs_attrs (inode->i_sb))
+			return -ENOTTY;
+
 		if (IS_RDONLY(inode))
 			return -EROFS;
 
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 660aefc..4b80ab9 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1053,10 +1053,9 @@
 
 static void handle_attrs( struct super_block *s )
 {
-	struct reiserfs_super_block * rs;
+	struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s);
 
 	if( reiserfs_attrs( s ) ) {
-		rs = SB_DISK_SUPER_BLOCK (s);
 		if( old_format_only(s) ) {
 			reiserfs_warning(s, "reiserfs: cannot support attributes on 3.5.x disk format" );
 			REISERFS_SB(s) -> s_mount_opt &= ~ ( 1 << REISERFS_ATTRS );
@@ -1066,6 +1065,8 @@
 				reiserfs_warning(s, "reiserfs: cannot support attributes until flag is set in super-block" );
 				REISERFS_SB(s) -> s_mount_opt &= ~ ( 1 << REISERFS_ATTRS );
 		}
+	} else if (le32_to_cpu( rs -> s_flags ) & reiserfs_attrs_cleared) {
+		REISERFS_SB(s)->s_mount_opt |= REISERFS_ATTRS;
 	}
 }
 
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 3f6dc71..ac191ed 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -159,14 +159,12 @@
 	char *nameptr;
 	uint8_t lfi;
 	uint16_t liu;
-	loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
+	loff_t size;
 	kernel_lb_addr bloc, eloc;
 	uint32_t extoffset, elen, offset;
 	struct buffer_head *bh = NULL;
 
-	if (!dir)
-		return NULL;
-
+	size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
 	f_pos = (udf_ext0_offset(dir) >> 2);
 
 	fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index c627bc4..9ad1424 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -108,6 +108,21 @@
 typedef int (*acpi_op_match)	(struct acpi_device *device,
 				 struct acpi_driver *driver);
 
+struct acpi_bus_ops {
+	u32 			acpi_op_add:1;
+	u32			acpi_op_remove:1;
+	u32			acpi_op_lock:1;
+	u32			acpi_op_start:1;
+	u32			acpi_op_stop:1;
+	u32			acpi_op_suspend:1;
+	u32			acpi_op_resume:1;
+	u32			acpi_op_scan:1;
+	u32			acpi_op_bind:1;
+	u32			acpi_op_unbind:1;
+	u32			acpi_op_match:1;
+	u32			reserved:21;
+};
+
 struct acpi_device_ops {
 	acpi_op_add		add;
 	acpi_op_remove		remove;
@@ -327,9 +342,9 @@
 int acpi_bus_receive_event (struct acpi_bus_event *event);
 int acpi_bus_register_driver (struct acpi_driver *driver);
 int acpi_bus_unregister_driver (struct acpi_driver *driver);
-int acpi_bus_scan (struct acpi_device *start);
 int acpi_bus_add (struct acpi_device **child, struct acpi_device *parent,
 		acpi_handle handle, int type);
+int acpi_bus_start (struct acpi_device *device);
 
 
 int acpi_match_ids (struct acpi_device	*device, char	*ids);
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index c62e92e..4ec722d 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -68,6 +68,7 @@
 
 struct pci_bus;
 
+acpi_status acpi_get_pci_id (acpi_handle handle, struct acpi_pci_id *id);
 int acpi_pci_bind (struct acpi_device *device);
 int acpi_pci_unbind (struct acpi_device *device);
 int acpi_pci_bind_root (struct acpi_device *device, struct acpi_pci_id *id, struct pci_bus *bus);
diff --git a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h
index 0c7b57b..b7806aa 100644
--- a/include/asm-alpha/pci.h
+++ b/include/asm-alpha/pci.h
@@ -223,6 +223,25 @@
 	/* Nothing to do. */
 }
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	unsigned long cacheline_size;
+	u8 byte;
+
+	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte);
+	if (byte == 0)
+		cacheline_size = 1024;
+	else
+		cacheline_size = (int) byte * 4;
+
+	*strat = PCI_DMA_BURST_BOUNDARY;
+	*strategy_parameter = cacheline_size;
+}
+#endif
+
 /* TODO: integrate with include/asm-generic/pci.h ? */
 static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 {
diff --git a/include/asm-alpha/serial.h b/include/asm-alpha/serial.h
index 7b2d9ee..7e4b298 100644
--- a/include/asm-alpha/serial.h
+++ b/include/asm-alpha/serial.h
@@ -22,54 +22,9 @@
 #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
 #endif
 
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define FOURPORT_FLAGS ASYNC_FOURPORT
-#define ACCENT_FLAGS 0
-#define BOCA_FLAGS 0
-#endif
-	
-#define STD_SERIAL_PORT_DEFNS			\
+#define SERIAL_PORT_DFNS			\
 	/* UART CLK   PORT IRQ     FLAGS        */			\
 	{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },	/* ttyS0 */	\
 	{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS },	/* ttyS1 */	\
 	{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },	/* ttyS2 */	\
 	{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },	/* ttyS3 */
-
-
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define EXTRA_SERIAL_PORT_DEFNS			\
-	{ 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, 	/* ttyS4 */	\
-	{ 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS },	/* ttyS5 */	\
-	{ 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS },	/* ttyS6 */	\
-	{ 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS },	/* ttyS7 */	\
-	{ 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS },	/* ttyS8 */	\
-	{ 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS },	/* ttyS9 */	\
-	{ 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS },	/* ttyS10 */	\
-	{ 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS },	/* ttyS11 */	\
-	{ 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS },	/* ttyS12 */	\
-	{ 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS },	/* ttyS13 */	\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS14 (spare) */		\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS15 (spare) */		\
-	{ 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS },	/* ttyS16 */	\
-	{ 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS },	/* ttyS17 */	\
-	{ 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS },	/* ttyS18 */	\
-	{ 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS },	/* ttyS19 */	\
-	{ 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS },	/* ttyS20 */	\
-	{ 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS },	/* ttyS21 */	\
-	{ 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS },	/* ttyS22 */	\
-	{ 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS },	/* ttyS23 */	\
-	{ 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS },	/* ttyS24 */	\
-	{ 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS },	/* ttyS25 */	\
-	{ 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS },	/* ttyS26 */	\
-	{ 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS },	/* ttyS27 */	\
-	{ 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS },	/* ttyS28 */	\
-	{ 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS },	/* ttyS29 */	\
-	{ 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS },	/* ttyS30 */	\
-	{ 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS },	/* ttyS31 */
-#else
-#define EXTRA_SERIAL_PORT_DEFNS
-#endif
-
-#define SERIAL_PORT_DFNS		\
-	STD_SERIAL_PORT_DEFNS		\
-	EXTRA_SERIAL_PORT_DEFNS
diff --git a/include/asm-arm/arch-ixp4xx/io.h b/include/asm-arm/arch-ixp4xx/io.h
index c27b9d3..7495026 100644
--- a/include/asm-arm/arch-ixp4xx/io.h
+++ b/include/asm-arm/arch-ixp4xx/io.h
@@ -3,7 +3,7 @@
  *
  * Author: Deepak Saxena <dsaxena@plexity.net>
  *
- * Copyright (C) 2002-2004  MontaVista Software, Inc.
+ * Copyright (C) 2002-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
@@ -383,6 +383,180 @@
 		*vaddr++ = inl(io_addr);
 }
 
+#define	__is_io_address(p)	(((unsigned long)p >= 0x0) && \
+					((unsigned long)p <= 0x0000ffff))
+static inline unsigned int
+__ixp4xx_ioread8(void __iomem *port)
+{
+	if (__is_io_address(port))
+		return	(unsigned int)__ixp4xx_inb((unsigned int)port);
+	else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+		return (unsigned int)__raw_readb((u32)port);
+#else
+		return (unsigned int)__ixp4xx_readb((u32)port);
+#endif
+}
+
+static inline void
+__ixp4xx_ioread8_rep(u32 port, u8 *vaddr, u32 count)
+{
+	if (__is_io_address(port))
+		__ixp4xx_insb(port, vaddr, count);
+	else
+#ifndef	CONFIG_IXP4XX_INDIRECT_PCI
+		__raw_readsb((void __iomem *)port, vaddr, count);
+#else
+		__ixp4xx_readsb(port, vaddr, count);
+#endif
+}
+
+static inline unsigned int
+__ixp4xx_ioread16(void __iomem *port)
+{
+	if (__is_io_address(port))
+		return	(unsigned int)__ixp4xx_inw((unsigned int)port);
+	else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+		return le16_to_cpu(__raw_readw((u32)port));
+#else
+		return (unsigned int)__ixp4xx_readw((u32)port);
+#endif
+}
+
+static inline void
+__ixp4xx_ioread16_rep(u32 port, u16 *vaddr, u32 count)
+{
+	if (__is_io_address(port))
+		__ixp4xx_insw(port, vaddr, count);
+	else
+#ifndef	CONFIG_IXP4XX_INDIRECT_PCI
+		__raw_readsw((void __iomem *)port, vaddr, count);
+#else
+		__ixp4xx_readsw(port, vaddr, count);
+#endif
+}
+
+static inline unsigned int
+__ixp4xx_ioread32(void __iomem *port)
+{
+	if (__is_io_address(port))
+		return	(unsigned int)__ixp4xx_inl((unsigned int)port);
+	else {
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+		return le32_to_cpu(__raw_readl((u32)port));
+#else
+		return (unsigned int)__ixp4xx_readl((u32)port);
+#endif
+	}
+}
+
+static inline void
+__ixp4xx_ioread32_rep(u32 port, u32 *vaddr, u32 count)
+{
+	if (__is_io_address(port))
+		__ixp4xx_insl(port, vaddr, count);
+	else
+#ifndef	CONFIG_IXP4XX_INDIRECT_PCI
+		__raw_readsl((void __iomem *)port, vaddr, count);
+#else
+		__ixp4xx_readsl(port, vaddr, count);
+#endif
+}
+
+static inline void
+__ixp4xx_iowrite8(u8 value, void __iomem *port)
+{
+	if (__is_io_address(port))
+		__ixp4xx_outb(value, (unsigned int)port);
+	else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+		__raw_writeb(value, (u32)port);
+#else
+		__ixp4xx_writeb(value, (u32)port);
+#endif
+}
+
+static inline void
+__ixp4xx_iowrite8_rep(u32 port, u8 *vaddr, u32 count)
+{
+	if (__is_io_address(port))
+		__ixp4xx_outsb(port, vaddr, count);
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+		__raw_writesb((void __iomem *)port, vaddr, count);
+#else
+		__ixp4xx_writesb(port, vaddr, count);
+#endif
+}
+
+static inline void
+__ixp4xx_iowrite16(u16 value, void __iomem *port)
+{
+	if (__is_io_address(port))
+		__ixp4xx_outw(value, (unsigned int)port);
+	else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+		__raw_writew(cpu_to_le16(value), (u32)port);
+#else
+		__ixp4xx_writew(value, (u32)port);
+#endif
+}
+
+static inline void
+__ixp4xx_iowrite16_rep(u32 port, u16 *vaddr, u32 count)
+{
+	if (__is_io_address(port))
+		__ixp4xx_outsw(port, vaddr, count);
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+		__raw_readsw((void __iomem *)port, vaddr, count);
+#else
+		__ixp4xx_writesw(port, vaddr, count);
+#endif
+}
+
+static inline void
+__ixp4xx_iowrite32(u32 value, void __iomem *port)
+{
+	if (__is_io_address(port))
+		__ixp4xx_outl(value, (unsigned int)port);
+	else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+		__raw_writel(cpu_to_le32(value), (u32)port);
+#else
+		__ixp4xx_writel(value, (u32)port);
+#endif
+}
+
+static inline void
+__ixp4xx_iowrite32_rep(u32 port, u32 *vaddr, u32 count)
+{
+	if (__is_io_address(port))
+		__ixp4xx_outsl(port, vaddr, count);
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+		__raw_readsl((void __iomem *)port, vaddr, count);
+#else
+		__ixp4xx_outsl(port, vaddr, count);
+#endif
+}
+
+#define	ioread8(p)			__ixp4xx_ioread8(p)
+#define	ioread16(p)			__ixp4xx_ioread16(p)
+#define	ioread32(p)			__ixp4xx_ioread32(p)
+
+#define	ioread8_rep(p, v, c)		__ixp4xx_ioread8_rep(p, v, c)
+#define	ioread16_rep(p, v, c)		__ixp4xx_ioread16_rep(p, v, c)
+#define	ioread32_rep(p, v, c)		__ixp4xx_ioread32_rep(p, v, c)
+
+#define	iowrite8(v,p)			__ixp4xx_iowrite8(v,p)
+#define	iowrite16(v,p)			__ixp4xx_iowrite16(v,p)
+#define	iowrite32(v,p)			__ixp4xx_iowrite32(v,p)
+
+#define	iowrite8_rep(p, v, c)		__ixp4xx_iowrite8_rep(p, v, c)
+#define	iowrite16_rep(p, v, c)		__ixp4xx_iowrite16_rep(p, v, c)
+#define	iowrite32_rep(p, v, c)		__ixp4xx_iowrite32_rep(p, v, c)
+
+#define	ioport_map(port, nr)		((void __iomem*)port)
+#define	ioport_unmap(addr)
 
 #endif	//  __ASM_ARM_ARCH_IO_H
 
diff --git a/include/asm-arm/arch-pxa/debug-macro.S b/include/asm-arm/arch-pxa/debug-macro.S
index f288e74..b6ec688 100644
--- a/include/asm-arm/arch-pxa/debug-macro.S
+++ b/include/asm-arm/arch-pxa/debug-macro.S
@@ -11,6 +11,8 @@
  *
 */
 
+#include "hardware.h"
+
 		.macro	addruart,rx
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index b5e54a9e..51f0fe0 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -1505,6 +1505,7 @@
 #define PSSR_OTGPH	(1 << 6)	/* OTG Peripheral control Hold */
 #define PSSR_RDH	(1 << 5)	/* Read Disable Hold */
 #define PSSR_PH		(1 << 4)	/* Peripheral Control Hold */
+#define PSSR_STS	(1 << 3)	/* Standby Mode Status */
 #define PSSR_VFS	(1 << 2)	/* VDD Fault Status */
 #define PSSR_BFS	(1 << 1)	/* Battery Fault Status */
 #define PSSR_SSS	(1 << 0)	/* Software Sleep Status */
@@ -1965,6 +1966,7 @@
 #define MECR_NOS	(1 << 0)	/* Number Of Sockets: 0 -> 1 sock, 1 -> 2 sock */
 #define MECR_CIT	(1 << 1)	/* Card Is There: 0 -> no card, 1 -> card inserted */
 
+#define MDREFR_K0DB4	(1 << 29)	/* SDCLK0 Divide by 4 Control/Status */
 #define MDREFR_K2FREE	(1 << 25)	/* SDRAM Free-Running Control */
 #define MDREFR_K1FREE	(1 << 24)	/* SDRAM Free-Running Control */
 #define MDREFR_K0FREE	(1 << 23)	/* SDRAM Free-Running Control */
diff --git a/include/asm-arm/arch-s3c2410/audio.h b/include/asm-arm/arch-s3c2410/audio.h
new file mode 100644
index 0000000..0d276e6
--- /dev/null
+++ b/include/asm-arm/arch-s3c2410/audio.h
@@ -0,0 +1,49 @@
+/* linux/include/asm-arm/arch-s3c2410/audio.h
+ *
+ * (c) 2004-2005 Simtec Electronics
+ *	http://www.simtec.co.uk/products/SWLINUX/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX - Audio platfrom_device info
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Changelog:
+ *	20-Nov-2004 BJD  Created file
+ *	07-Mar-2005 BJD  Added suspend/resume calls
+*/
+
+#ifndef __ASM_ARCH_AUDIO_H
+#define __ASM_ARCH_AUDIO_H __FILE__
+
+/* struct s3c24xx_iis_ops
+ *
+ * called from the s3c24xx audio core to deal with the architecture
+ * or the codec's setup and control.
+ *
+ * the pointer to itself is passed through in case the caller wants to
+ * embed this in an larger structure for easy reference to it's context.
+*/
+
+struct s3c24xx_iis_ops {
+	struct module *owner;
+
+	int	(*startup)(struct s3c24xx_iis_ops *me);
+	void	(*shutdown)(struct s3c24xx_iis_ops *me);
+	int	(*suspend)(struct s3c24xx_iis_ops *me);
+	int	(*resume)(struct s3c24xx_iis_ops *me);
+
+	int	(*open)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm);
+	int	(*close)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm);
+	int	(*prepare)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm, snd_pcm_runtime_t *rt);
+};
+
+struct s3c24xx_platdata_iis {
+	const char		*codec_clk;
+	struct s3c24xx_iis_ops	*ops;
+	int			(*match_dev)(struct device *dev);
+};
+
+#endif /* __ASM_ARCH_AUDIO_H */
diff --git a/include/asm-arm/hardware/arm_timer.h b/include/asm-arm/hardware/arm_timer.h
new file mode 100644
index 0000000..04be3bd
--- /dev/null
+++ b/include/asm-arm/hardware/arm_timer.h
@@ -0,0 +1,21 @@
+#ifndef __ASM_ARM_HARDWARE_ARM_TIMER_H
+#define __ASM_ARM_HARDWARE_ARM_TIMER_H
+
+#define TIMER_LOAD	0x00
+#define TIMER_VALUE	0x04
+#define TIMER_CTRL	0x08
+#define TIMER_CTRL_ONESHOT	(1 << 0)
+#define TIMER_CTRL_32BIT	(1 << 1)
+#define TIMER_CTRL_DIV1		(0 << 2)
+#define TIMER_CTRL_DIV16	(1 << 2)
+#define TIMER_CTRL_DIV256	(2 << 2)
+#define TIMER_CTRL_IE		(1 << 5)	/* Interrupt Enable (versatile only) */
+#define TIMER_CTRL_PERIODIC	(1 << 6)
+#define TIMER_CTRL_ENABLE	(1 << 7)
+
+#define TIMER_INTCLR	0x0c
+#define TIMER_RIS	0x10
+#define TIMER_MIS	0x14
+#define TIMER_BGLOAD	0x18
+
+#endif
diff --git a/include/asm-arm/mach/arch.h b/include/asm-arm/mach/arch.h
index 3a32e92..56c6bf4 100644
--- a/include/asm-arm/mach/arch.h
+++ b/include/asm-arm/mach/arch.h
@@ -26,7 +26,7 @@
 						 * page tabe entry	*/
 
 	const char		*name;		/* architecture name	*/
-	unsigned int		param_offset;	/* parameter page	*/
+	unsigned long		boot_params;	/* tagged list		*/
 
 	unsigned int		video_start;	/* start of video RAM	*/
 	unsigned int		video_end;	/* end of video RAM	*/
@@ -54,38 +54,6 @@
 	.nr		= MACH_TYPE_##_type,	\
 	.name		= _name,
 
-#define MAINTAINER(n)
-
-#define BOOT_MEM(_pram,_pio,_vio)		\
-	.phys_ram	= _pram,		\
-	.phys_io	= _pio,			\
-	.io_pg_offst	= ((_vio)>>18)&0xfffc,
-
-#define BOOT_PARAMS(_params)			\
-	.param_offset	= _params,
-
-#define VIDEO(_start,_end)			\
-	.video_start	= _start,		\
-	.video_end	= _end,
-
-#define DISABLE_PARPORT(_n)			\
-	.reserve_lp##_n	= 1,
-
-#define SOFT_REBOOT				\
-	.soft_reboot	= 1,
-
-#define FIXUP(_func)				\
-	.fixup		= _func,
-
-#define MAPIO(_func)				\
-	.map_io		= _func,
-
-#define INITIRQ(_func)				\
-	.init_irq	= _func,
-
-#define INIT_MACHINE(_func)			\
-	.init_machine	= _func,
-
 #define MACHINE_END				\
 };
 
diff --git a/include/asm-arm/pci.h b/include/asm-arm/pci.h
index 40ffaef..e300646 100644
--- a/include/asm-arm/pci.h
+++ b/include/asm-arm/pci.h
@@ -42,6 +42,16 @@
 #define pci_unmap_len(PTR, LEN_NAME)		((PTR)->LEN_NAME)
 #define pci_unmap_len_set(PTR, LEN_NAME, VAL)	(((PTR)->LEN_NAME) = (VAL))
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
 #define HAVE_PCI_MMAP
 extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
                                enum pci_mmap_state mmap_state, int write_combine);
diff --git a/include/asm-arm/stat.h b/include/asm-arm/stat.h
index ca8e7a8..ec4e2c2 100644
--- a/include/asm-arm/stat.h
+++ b/include/asm-arm/stat.h
@@ -89,6 +89,6 @@
 	unsigned long	st_ctime_nsec;
 
 	unsigned long long	st_ino;
-};
+} __attribute__((packed));
 
 #endif
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
index 3d0d286..2f44b20 100644
--- a/include/asm-arm/system.h
+++ b/include/asm-arm/system.h
@@ -85,7 +85,9 @@
 void die(const char *msg, struct pt_regs *regs, int err)
 		__attribute__((noreturn));
 
-void die_if_kernel(const char *str, struct pt_regs *regs, int err);
+struct siginfo;
+void notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
+		unsigned long err, unsigned long trap);
 
 void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
 				       struct pt_regs *),
@@ -290,7 +292,6 @@
 })
 
 #ifdef CONFIG_SMP
-#error SMP not supported
 
 #define smp_mb()		mb()
 #define smp_rmb()		rmb()
@@ -304,6 +305,8 @@
 #define smp_wmb()		barrier()
 #define smp_read_barrier_depends()		do { } while(0)
 
+#endif /* CONFIG_SMP */
+
 #if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110)
 /*
  * On the StrongARM, "swp" is terminally broken since it bypasses the
@@ -316,9 +319,16 @@
  *
  * We choose (1) since its the "easiest" to achieve here and is not
  * dependent on the processor type.
+ *
+ * NOTE that this solution won't work on an SMP system, so explcitly
+ * forbid it here.
  */
+#ifdef CONFIG_SMP
+#error SMP is not supported on SA1100/SA110
+#else
 #define swp_is_buggy
 #endif
+#endif
 
 static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
 {
@@ -361,8 +371,6 @@
 	return ret;
 }
 
-#endif /* CONFIG_SMP */
-
 #endif /* __ASSEMBLY__ */
 
 #define arch_align_stack(x) (x)
diff --git a/include/asm-arm/tlbflush.h b/include/asm-arm/tlbflush.h
index 8a864b1..9387a5e 100644
--- a/include/asm-arm/tlbflush.h
+++ b/include/asm-arm/tlbflush.h
@@ -235,7 +235,7 @@
 
 #define tlb_flag(f)	((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f)))
 
-static inline void flush_tlb_all(void)
+static inline void local_flush_tlb_all(void)
 {
 	const int zero = 0;
 	const unsigned int __tlb_flag = __cpu_tlb_flags;
@@ -253,7 +253,7 @@
 		asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
 }
 
-static inline void flush_tlb_mm(struct mm_struct *mm)
+static inline void local_flush_tlb_mm(struct mm_struct *mm)
 {
 	const int zero = 0;
 	const int asid = ASID(mm);
@@ -282,7 +282,7 @@
 }
 
 static inline void
-flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
+local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
 {
 	const int zero = 0;
 	const unsigned int __tlb_flag = __cpu_tlb_flags;
@@ -313,7 +313,7 @@
 		asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr));
 }
 
-static inline void flush_tlb_kernel_page(unsigned long kaddr)
+static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
 {
 	const int zero = 0;
 	const unsigned int __tlb_flag = __cpu_tlb_flags;
@@ -384,8 +384,24 @@
 /*
  * Convert calls to our calling convention.
  */
-#define flush_tlb_range(vma,start,end)	__cpu_flush_user_tlb_range(start,end,vma)
-#define flush_tlb_kernel_range(s,e)	__cpu_flush_kern_tlb_range(s,e)
+#define local_flush_tlb_range(vma,start,end)	__cpu_flush_user_tlb_range(start,end,vma)
+#define local_flush_tlb_kernel_range(s,e)	__cpu_flush_kern_tlb_range(s,e)
+
+#ifndef CONFIG_SMP
+#define flush_tlb_all		local_flush_tlb_all
+#define flush_tlb_mm		local_flush_tlb_mm
+#define flush_tlb_page		local_flush_tlb_page
+#define flush_tlb_kernel_page	local_flush_tlb_kernel_page
+#define flush_tlb_range		local_flush_tlb_range
+#define flush_tlb_kernel_range	local_flush_tlb_kernel_range
+#else
+extern void flush_tlb_all(void);
+extern void flush_tlb_mm(struct mm_struct *mm);
+extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr);
+extern void flush_tlb_kernel_page(unsigned long kaddr);
+extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
+extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
+#endif
 
 /*
  * if PG_dcache_dirty is set for the page, we need to ensure that any
diff --git a/include/asm-arm26/serial.h b/include/asm-arm26/serial.h
index 21e1df3..5fc747d 100644
--- a/include/asm-arm26/serial.h
+++ b/include/asm-arm26/serial.h
@@ -30,34 +30,16 @@
 #if defined(CONFIG_ARCH_A5K)
      /* UART CLK        PORT  IRQ     FLAGS        */
 
-#define STD_SERIAL_PORT_DEFNS                                           \
+#define SERIAL_PORT_DFNS                                                \
         { 0, BASE_BAUD, 0x3F8, 10, STD_COM_FLAGS },     /* ttyS0 */     \
         { 0, BASE_BAUD, 0x2F8, 10, STD_COM_FLAGS },     /* ttyS1 */
 
 #else
 
-#define STD_SERIAL_PORT_DEFNS                                           \
+#define SERIAL_PORT_DFNS                                                \
         { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS0 */     \
         { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS1 */
 
 #endif
 
-#define EXTRA_SERIAL_PORT_DEFNS \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS2 */     \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS3 */     \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS4 */     \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS5 */     \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS6 */     \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS7 */     \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS8 */     \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS9 */     \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS10 */    \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS11 */    \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS12 */    \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS13 */
-
-#define SERIAL_PORT_DFNS		\
-	STD_SERIAL_PORT_DEFNS		\
-	EXTRA_SERIAL_PORT_DEFNS
-
 #endif
diff --git a/include/asm-frv/pci.h b/include/asm-frv/pci.h
index a6a4692..b4efe5e 100644
--- a/include/asm-frv/pci.h
+++ b/include/asm-frv/pci.h
@@ -57,6 +57,16 @@
  */
 #define PCI_DMA_BUS_IS_PHYS	(1)
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
 /*
  *	These are pretty much arbitary with the CoMEM implementation.
  *	We have the whole address space to ourselves.
diff --git a/include/asm-i386/i8253.h b/include/asm-i386/i8253.h
new file mode 100644
index 0000000..015d8df
--- /dev/null
+++ b/include/asm-i386/i8253.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_I8253_H__
+#define __ASM_I8253_H__
+
+extern spinlock_t i8253_lock;
+
+#endif	/* __ASM_I8253_H__ */
diff --git a/include/asm-i386/mach-default/do_timer.h b/include/asm-i386/mach-default/do_timer.h
index 03dd13a..5621141 100644
--- a/include/asm-i386/mach-default/do_timer.h
+++ b/include/asm-i386/mach-default/do_timer.h
@@ -1,6 +1,7 @@
 /* defines for inline arch setup functions */
 
 #include <asm/apic.h>
+#include <asm/i8259.h>
 
 /**
  * do_timer_interrupt_hook - hook into timer tick
diff --git a/include/asm-i386/pci.h b/include/asm-i386/pci.h
index fb749b8..3561899 100644
--- a/include/asm-i386/pci.h
+++ b/include/asm-i386/pci.h
@@ -99,6 +99,16 @@
 {
 }
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
 #endif /* __KERNEL__ */
 
 /* implement the pci_ DMA API in terms of the generic device dma_ one */
diff --git a/include/asm-i386/serial.h b/include/asm-i386/serial.h
index 21ddecc..e1ecfcc 100644
--- a/include/asm-i386/serial.h
+++ b/include/asm-i386/serial.h
@@ -22,109 +22,9 @@
 #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
 #endif
 
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define FOURPORT_FLAGS ASYNC_FOURPORT
-#define ACCENT_FLAGS 0
-#define BOCA_FLAGS 0
-#define HUB6_FLAGS 0
-#endif
-
-#define MCA_COM_FLAGS	(STD_COM_FLAGS|ASYNC_BOOT_ONLYMCA)
-
-/*
- * The following define the access methods for the HUB6 card. All
- * access is through two ports for all 24 possible chips. The card is
- * selected through the high 2 bits, the port on that card with the
- * "middle" 3 bits, and the register on that port with the bottom
- * 3 bits.
- *
- * While the access port and interrupt is configurable, the default
- * port locations are 0x302 for the port control register, and 0x303
- * for the data read/write register. Normally, the interrupt is at irq3
- * but can be anything from 3 to 7 inclusive. Note that using 3 will
- * require disabling com2.
- */
-
-#define C_P(card,port) (((card)<<6|(port)<<3) + 1)
-
-#define STD_SERIAL_PORT_DEFNS			\
+#define SERIAL_PORT_DFNS			\
 	/* UART CLK   PORT IRQ     FLAGS        */			\
 	{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },	/* ttyS0 */	\
 	{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS },	/* ttyS1 */	\
 	{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },	/* ttyS2 */	\
 	{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },	/* ttyS3 */
-
-
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define EXTRA_SERIAL_PORT_DEFNS			\
-	{ 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, 	/* ttyS4 */	\
-	{ 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS },	/* ttyS5 */	\
-	{ 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS },	/* ttyS6 */	\
-	{ 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS },	/* ttyS7 */	\
-	{ 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS },	/* ttyS8 */	\
-	{ 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS },	/* ttyS9 */	\
-	{ 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS },	/* ttyS10 */	\
-	{ 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS },	/* ttyS11 */	\
-	{ 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS },	/* ttyS12 */	\
-	{ 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS },	/* ttyS13 */	\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS14 (spare) */		\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS15 (spare) */		\
-	{ 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS },	/* ttyS16 */	\
-	{ 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS },	/* ttyS17 */	\
-	{ 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS },	/* ttyS18 */	\
-	{ 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS },	/* ttyS19 */	\
-	{ 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS },	/* ttyS20 */	\
-	{ 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS },	/* ttyS21 */	\
-	{ 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS },	/* ttyS22 */	\
-	{ 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS },	/* ttyS23 */	\
-	{ 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS },	/* ttyS24 */	\
-	{ 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS },	/* ttyS25 */	\
-	{ 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS },	/* ttyS26 */	\
-	{ 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS },	/* ttyS27 */	\
-	{ 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS },	/* ttyS28 */	\
-	{ 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS },	/* ttyS29 */	\
-	{ 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS },	/* ttyS30 */	\
-	{ 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS },	/* ttyS31 */
-#else
-#define EXTRA_SERIAL_PORT_DEFNS
-#endif
-
-/* You can have up to four HUB6's in the system, but I've only
- * included two cards here for a total of twelve ports.
- */
-#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS))
-#define HUB6_SERIAL_PORT_DFNS		\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) },  /* ttyS32 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) },  /* ttyS33 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) },  /* ttyS34 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) },  /* ttyS35 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) },  /* ttyS36 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) },  /* ttyS37 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) },  /* ttyS38 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) },  /* ttyS39 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) },  /* ttyS40 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) },  /* ttyS41 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) },  /* ttyS42 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) },  /* ttyS43 */
-#else
-#define HUB6_SERIAL_PORT_DFNS
-#endif
-
-#ifdef CONFIG_MCA
-#define MCA_SERIAL_PORT_DFNS			\
-	{ 0, BASE_BAUD, 0x3220, 3, MCA_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x3228, 3, MCA_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x4220, 3, MCA_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x4228, 3, MCA_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x5220, 3, MCA_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x5228, 3, MCA_COM_FLAGS },
-#else
-#define MCA_SERIAL_PORT_DFNS
-#endif
-
-#define SERIAL_PORT_DFNS		\
-	STD_SERIAL_PORT_DEFNS		\
-	EXTRA_SERIAL_PORT_DEFNS		\
-	HUB6_SERIAL_PORT_DFNS		\
-	MCA_SERIAL_PORT_DFNS
-
diff --git a/include/asm-ia64/iosapic.h b/include/asm-ia64/iosapic.h
index 38a7a72..1093f35 100644
--- a/include/asm-ia64/iosapic.h
+++ b/include/asm-ia64/iosapic.h
@@ -71,8 +71,11 @@
 }
 
 extern void __init iosapic_system_init (int pcat_compat);
-extern void __init iosapic_init (unsigned long address,
+extern int __devinit iosapic_init (unsigned long address,
 				    unsigned int gsi_base);
+#ifdef CONFIG_HOTPLUG
+extern int iosapic_remove (unsigned int gsi_base);
+#endif /* CONFIG_HOTPLUG */
 extern int gsi_to_vector (unsigned int gsi);
 extern int gsi_to_irq (unsigned int gsi);
 extern void iosapic_enable_intr (unsigned int vector);
@@ -94,11 +97,14 @@
 
 extern void iosapic_pci_fixup (int);
 #ifdef CONFIG_NUMA
-extern void __init map_iosapic_to_node (unsigned int, int);
+extern void __devinit map_iosapic_to_node (unsigned int, int);
 #endif
 #else
 #define iosapic_system_init(pcat_compat)			do { } while (0)
-#define iosapic_init(address,gsi_base)				do { } while (0)
+#define iosapic_init(address,gsi_base)				(-EINVAL)
+#ifdef CONFIG_HOTPLUG
+#define iosapic_remove(gsi_base)				(-ENODEV)
+#endif /* CONFIG_HOTPLUG */
 #define iosapic_register_intr(gsi,polarity,trigger)		(gsi)
 #define iosapic_unregister_intr(irq)				do { } while (0)
 #define iosapic_override_isa_irq(isa_irq,gsi,polarity,trigger)	do { } while (0)
diff --git a/include/asm-ia64/mmu_context.h b/include/asm-ia64/mmu_context.h
index 0096e7e..e3e5fed 100644
--- a/include/asm-ia64/mmu_context.h
+++ b/include/asm-ia64/mmu_context.h
@@ -132,6 +132,9 @@
 	ia64_srlz_i();			/* srlz.i implies srlz.d */
 }
 
+/*
+ * Must be called with preemption off
+ */
 static inline void
 activate_context (struct mm_struct *mm)
 {
diff --git a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h
index a8314ee..0c4c5d8 100644
--- a/include/asm-ia64/pci.h
+++ b/include/asm-ia64/pci.h
@@ -82,6 +82,25 @@
 #define sg_dma_len(sg)		((sg)->dma_length)
 #define sg_dma_address(sg)	((sg)->dma_address)
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	unsigned long cacheline_size;
+	u8 byte;
+
+	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte);
+	if (byte == 0)
+		cacheline_size = 1024;
+	else
+		cacheline_size = (int) byte * 4;
+
+	*strat = PCI_DMA_BURST_MULTIPLE;
+	*strategy_parameter = cacheline_size;
+}
+#endif
+
 #define HAVE_PCI_MMAP
 extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
 				enum pci_mmap_state mmap_state, int write_combine);
diff --git a/include/asm-ia64/sn/addrs.h b/include/asm-ia64/sn/addrs.h
index 1bfdfb4..103d745 100644
--- a/include/asm-ia64/sn/addrs.h
+++ b/include/asm-ia64/sn/addrs.h
@@ -216,6 +216,10 @@
 #define TIO_SWIN_WIDGETNUM(x)		(((x)  >> TIO_SWIN_SIZE_BITS) & TIO_SWIN_WIDGET_MASK)
 
 
+#define TIO_IOSPACE_ADDR(n,x)					\
+	/* Move in the Chiplet ID for TIO Local Block MMR */	\
+	(REMOTE_ADDR(n,x) | 1UL << (NASID_SHIFT - 2))
+
 /*
  * The following macros produce the correct base virtual address for
  * the hub registers. The REMOTE_HUB_* macro produce
@@ -233,13 +237,16 @@
 #define REMOTE_HUB_ADDR(n,x)						\
 	((n & 1) ?							\
 	/* TIO: */							\
-	((volatile u64 *)(GLOBAL_MMR_ADDR(n,x)))			\
-	: /* SHUB: */							\
-	(((x) & BWIN_TOP) ? ((volatile u64 *)(GLOBAL_MMR_ADDR(n,x)))\
+	(is_shub2() ?							\
+	/* TIO on Shub2 */						\
+	(volatile u64 *)(TIO_IOSPACE_ADDR(n,x))				\
+	: /* TIO on shub1 */						\
+	(volatile u64 *)(GLOBAL_MMR_ADDR(n,x)))				\
+									\
+	: /* SHUB1 and SHUB2 MMRs: */					\
+	(((x) & BWIN_TOP) ? ((volatile u64 *)(GLOBAL_MMR_ADDR(n,x)))	\
 	: ((volatile u64 *)(NODE_SWIN_BASE(n,1) + 0x800000 + (x)))))
 
-
-
 #define HUB_L(x)			(*((volatile typeof(*x) *)x))
 #define	HUB_S(x,d)			(*((volatile typeof(*x) *)x) = (d))
 
diff --git a/include/asm-ia64/sn/l1.h b/include/asm-ia64/sn/l1.h
index 08050d3..2e5f0aa 100644
--- a/include/asm-ia64/sn/l1.h
+++ b/include/asm-ia64/sn/l1.h
@@ -33,5 +33,6 @@
 #define L1_BRICKTYPE_PA		0x6a            /* j */
 #define L1_BRICKTYPE_IA		0x6b            /* k */
 #define L1_BRICKTYPE_ATHENA	0x2b            /* + */
+#define L1_BRICKTYPE_DAYTONA	0x7a            /* z */
 
 #endif /* _ASM_IA64_SN_L1_H */
diff --git a/include/asm-ia64/sn/shub_mmr.h b/include/asm-ia64/sn/shub_mmr.h
index 323fa0c..7de1d1d 100644
--- a/include/asm-ia64/sn/shub_mmr.h
+++ b/include/asm-ia64/sn/shub_mmr.h
@@ -14,96 +14,98 @@
 /*                        Register "SH_IPI_INT"                         */
 /*               SHub Inter-Processor Interrupt Registers               */
 /* ==================================================================== */
-#define SH1_IPI_INT                               0x0000000110000380
-#define SH2_IPI_INT                               0x0000000010000380
+#define SH1_IPI_INT			__IA64_UL_CONST(0x0000000110000380)
+#define SH2_IPI_INT			__IA64_UL_CONST(0x0000000010000380)
 
 /*   SH_IPI_INT_TYPE                                                    */
 /*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
-#define SH_IPI_INT_TYPE_SHFT                     0
-#define SH_IPI_INT_TYPE_MASK                     0x0000000000000007
+#define SH_IPI_INT_TYPE_SHFT				0
+#define SH_IPI_INT_TYPE_MASK		__IA64_UL_CONST(0x0000000000000007)
 
 /*   SH_IPI_INT_AGT                                                     */
 /*   Description:  Agent, must be 0 for SHub                            */
-#define SH_IPI_INT_AGT_SHFT                      3
-#define SH_IPI_INT_AGT_MASK                      0x0000000000000008
+#define SH_IPI_INT_AGT_SHFT				3
+#define SH_IPI_INT_AGT_MASK		__IA64_UL_CONST(0x0000000000000008)
 
 /*   SH_IPI_INT_PID                                                     */
 /*   Description:  Processor ID, same setting as on targeted McKinley  */
-#define SH_IPI_INT_PID_SHFT                      4
-#define SH_IPI_INT_PID_MASK                      0x00000000000ffff0
+#define SH_IPI_INT_PID_SHFT                      	4
+#define SH_IPI_INT_PID_MASK		__IA64_UL_CONST(0x00000000000ffff0)
 
 /*   SH_IPI_INT_BASE                                                    */
 /*   Description:  Optional interrupt vector area, 2MB aligned          */
-#define SH_IPI_INT_BASE_SHFT                     21
-#define SH_IPI_INT_BASE_MASK                     0x0003ffffffe00000
+#define SH_IPI_INT_BASE_SHFT				21
+#define SH_IPI_INT_BASE_MASK 		__IA64_UL_CONST(0x0003ffffffe00000)
 
 /*   SH_IPI_INT_IDX                                                     */
 /*   Description:  Targeted McKinley interrupt vector                   */
-#define SH_IPI_INT_IDX_SHFT                      52
-#define SH_IPI_INT_IDX_MASK                      0x0ff0000000000000
+#define SH_IPI_INT_IDX_SHFT				52
+#define SH_IPI_INT_IDX_MASK		__IA64_UL_CONST(0x0ff0000000000000)
 
 /*   SH_IPI_INT_SEND                                                    */
 /*   Description:  Send Interrupt Message to PI, This generates a puls  */
-#define SH_IPI_INT_SEND_SHFT                     63
-#define SH_IPI_INT_SEND_MASK                     0x8000000000000000
+#define SH_IPI_INT_SEND_SHFT				63
+#define SH_IPI_INT_SEND_MASK		__IA64_UL_CONST(0x8000000000000000)
 
 /* ==================================================================== */
 /*                     Register "SH_EVENT_OCCURRED"                     */
 /*                    SHub Interrupt Event Occurred                     */
 /* ==================================================================== */
-#define SH1_EVENT_OCCURRED                        0x0000000110010000
-#define SH1_EVENT_OCCURRED_ALIAS                  0x0000000110010008
-#define SH2_EVENT_OCCURRED                        0x0000000010010000
-#define SH2_EVENT_OCCURRED_ALIAS                  0x0000000010010008
+#define SH1_EVENT_OCCURRED		__IA64_UL_CONST(0x0000000110010000)
+#define SH1_EVENT_OCCURRED_ALIAS	__IA64_UL_CONST(0x0000000110010008)
+#define SH2_EVENT_OCCURRED		__IA64_UL_CONST(0x0000000010010000)
+#define SH2_EVENT_OCCURRED_ALIAS 	__IA64_UL_CONST(0x0000000010010008)
 
 /* ==================================================================== */
 /*                     Register "SH_PI_CAM_CONTROL"                     */
 /*                      CRB CAM MMR Access Control                      */
 /* ==================================================================== */
-#define SH1_PI_CAM_CONTROL                        0x0000000120050300
+#define SH1_PI_CAM_CONTROL		__IA64_UL_CONST(0x0000000120050300)
 
 /* ==================================================================== */
 /*                        Register "SH_SHUB_ID"                         */
 /*                            SHub ID Number                            */
 /* ==================================================================== */
-#define SH1_SHUB_ID                               0x0000000110060580
-#define SH1_SHUB_ID_REVISION_SHFT                 28
-#define SH1_SHUB_ID_REVISION_MASK                 0x00000000f0000000
+#define SH1_SHUB_ID			__IA64_UL_CONST(0x0000000110060580)
+#define SH1_SHUB_ID_REVISION_SHFT			28
+#define SH1_SHUB_ID_REVISION_MASK	__IA64_UL_CONST(0x00000000f0000000)
 
 /* ==================================================================== */
 /*                          Register "SH_RTC"                           */
 /*                           Real-time Clock                            */
 /* ==================================================================== */
-#define SH1_RTC                                   0x00000001101c0000
-#define SH2_RTC					  0x00000002101c0000
-#define SH_RTC_MASK                               0x007fffffffffffff
+#define SH1_RTC				__IA64_UL_CONST(0x00000001101c0000)
+#define SH2_RTC				__IA64_UL_CONST(0x00000002101c0000)
+#define SH_RTC_MASK			__IA64_UL_CONST(0x007fffffffffffff)
 
 /* ==================================================================== */
 /*                   Register "SH_PIO_WRITE_STATUS_0|1"                 */
 /*                      PIO Write Status for CPU 0 & 1                  */
 /* ==================================================================== */
-#define SH1_PIO_WRITE_STATUS_0                    0x0000000120070200
-#define SH1_PIO_WRITE_STATUS_1                    0x0000000120070280
-#define SH2_PIO_WRITE_STATUS_0                    0x0000000020070200
-#define SH2_PIO_WRITE_STATUS_1                    0x0000000020070280
-#define SH2_PIO_WRITE_STATUS_2                    0x0000000020070300
-#define SH2_PIO_WRITE_STATUS_3                    0x0000000020070380
+#define SH1_PIO_WRITE_STATUS_0		__IA64_UL_CONST(0x0000000120070200)
+#define SH1_PIO_WRITE_STATUS_1		__IA64_UL_CONST(0x0000000120070280)
+#define SH2_PIO_WRITE_STATUS_0		__IA64_UL_CONST(0x0000000020070200)
+#define SH2_PIO_WRITE_STATUS_1		__IA64_UL_CONST(0x0000000020070280)
+#define SH2_PIO_WRITE_STATUS_2		__IA64_UL_CONST(0x0000000020070300)
+#define SH2_PIO_WRITE_STATUS_3		__IA64_UL_CONST(0x0000000020070380)
 
 /*   SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK                               */
 /*   Description:  Deadlock response detected                           */
-#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT 1
-#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK 0x0000000000000002
+#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT		1
+#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK \
+					__IA64_UL_CONST(0x0000000000000002)
 
 /*   SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT                          */
 /*   Description:  Count of currently pending PIO writes                */
-#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_SHFT 56
-#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK 0x3f00000000000000
+#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_SHFT	56
+#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK \
+					__IA64_UL_CONST(0x3f00000000000000)
 
 /* ==================================================================== */
 /*                Register "SH_PIO_WRITE_STATUS_0_ALIAS"                */
 /* ==================================================================== */
-#define SH1_PIO_WRITE_STATUS_0_ALIAS              0x0000000120070208
-#define SH2_PIO_WRITE_STATUS_0_ALIAS              0x0000000020070208
+#define SH1_PIO_WRITE_STATUS_0_ALIAS	__IA64_UL_CONST(0x0000000120070208)
+#define SH2_PIO_WRITE_STATUS_0_ALIAS	__IA64_UL_CONST(0x0000000020070208)
 
 /* ==================================================================== */
 /*                     Register "SH_EVENT_OCCURRED"                     */
@@ -111,33 +113,33 @@
 /* ==================================================================== */
 /*   SH_EVENT_OCCURRED_UART_INT                                         */
 /*   Description:  Pending Junk Bus UART Interrupt                      */
-#define SH_EVENT_OCCURRED_UART_INT_SHFT          20
-#define SH_EVENT_OCCURRED_UART_INT_MASK          0x0000000000100000
+#define SH_EVENT_OCCURRED_UART_INT_SHFT			20
+#define SH_EVENT_OCCURRED_UART_INT_MASK	__IA64_UL_CONST(0x0000000000100000)
 
 /*   SH_EVENT_OCCURRED_IPI_INT                                          */
 /*   Description:  Pending IPI Interrupt                                */
-#define SH_EVENT_OCCURRED_IPI_INT_SHFT           28
-#define SH_EVENT_OCCURRED_IPI_INT_MASK           0x0000000010000000
+#define SH_EVENT_OCCURRED_IPI_INT_SHFT			28
+#define SH_EVENT_OCCURRED_IPI_INT_MASK	__IA64_UL_CONST(0x0000000010000000)
 
 /*   SH_EVENT_OCCURRED_II_INT0                                          */
 /*   Description:  Pending II 0 Interrupt                               */
-#define SH_EVENT_OCCURRED_II_INT0_SHFT           29
-#define SH_EVENT_OCCURRED_II_INT0_MASK           0x0000000020000000
+#define SH_EVENT_OCCURRED_II_INT0_SHFT			29
+#define SH_EVENT_OCCURRED_II_INT0_MASK	__IA64_UL_CONST(0x0000000020000000)
 
 /*   SH_EVENT_OCCURRED_II_INT1                                          */
 /*   Description:  Pending II 1 Interrupt                               */
-#define SH_EVENT_OCCURRED_II_INT1_SHFT           30
-#define SH_EVENT_OCCURRED_II_INT1_MASK           0x0000000040000000
+#define SH_EVENT_OCCURRED_II_INT1_SHFT			30
+#define SH_EVENT_OCCURRED_II_INT1_MASK	__IA64_UL_CONST(0x0000000040000000)
 
 /*   SH2_EVENT_OCCURRED_EXTIO_INT2                                      */
 /*   Description:  Pending SHUB 2 EXT IO INT2                           */
-#define SH2_EVENT_OCCURRED_EXTIO_INT2_SHFT       33
-#define SH2_EVENT_OCCURRED_EXTIO_INT2_MASK       0x0000000200000000
+#define SH2_EVENT_OCCURRED_EXTIO_INT2_SHFT		33
+#define SH2_EVENT_OCCURRED_EXTIO_INT2_MASK __IA64_UL_CONST(0x0000000200000000)
 
 /*   SH2_EVENT_OCCURRED_EXTIO_INT3                                      */
 /*   Description:  Pending SHUB 2 EXT IO INT3                           */
-#define SH2_EVENT_OCCURRED_EXTIO_INT3_SHFT       34
-#define SH2_EVENT_OCCURRED_EXTIO_INT3_MASK       0x0000000400000000
+#define SH2_EVENT_OCCURRED_EXTIO_INT3_SHFT		34
+#define SH2_EVENT_OCCURRED_EXTIO_INT3_MASK __IA64_UL_CONST(0x0000000400000000)
 
 #define SH_ALL_INT_MASK \
 	(SH_EVENT_OCCURRED_UART_INT_MASK | SH_EVENT_OCCURRED_IPI_INT_MASK | \
@@ -149,310 +151,310 @@
 /* ==================================================================== */
 /*                         LEDS                                         */
 /* ==================================================================== */
-#define SH1_REAL_JUNK_BUS_LED0			 0x7fed00000UL
-#define SH1_REAL_JUNK_BUS_LED1			 0x7fed10000UL
-#define SH1_REAL_JUNK_BUS_LED2			 0x7fed20000UL
-#define SH1_REAL_JUNK_BUS_LED3			 0x7fed30000UL
+#define SH1_REAL_JUNK_BUS_LED0			0x7fed00000UL
+#define SH1_REAL_JUNK_BUS_LED1			0x7fed10000UL
+#define SH1_REAL_JUNK_BUS_LED2			0x7fed20000UL
+#define SH1_REAL_JUNK_BUS_LED3			0x7fed30000UL
 
-#define SH2_REAL_JUNK_BUS_LED0			 0xf0000000UL
-#define SH2_REAL_JUNK_BUS_LED1			 0xf0010000UL
-#define SH2_REAL_JUNK_BUS_LED2			 0xf0020000UL
-#define SH2_REAL_JUNK_BUS_LED3			 0xf0030000UL
+#define SH2_REAL_JUNK_BUS_LED0			0xf0000000UL
+#define SH2_REAL_JUNK_BUS_LED1			0xf0010000UL
+#define SH2_REAL_JUNK_BUS_LED2			0xf0020000UL
+#define SH2_REAL_JUNK_BUS_LED3			0xf0030000UL
 
 /* ==================================================================== */
 /*                         Register "SH1_PTC_0"                         */
 /*       Puge Translation Cache Message Configuration Information       */
 /* ==================================================================== */
-#define SH1_PTC_0                                 0x00000001101a0000
+#define SH1_PTC_0			__IA64_UL_CONST(0x00000001101a0000)
 
 /*   SH1_PTC_0_A                                                        */
 /*   Description:  Type                                                 */
-#define SH1_PTC_0_A_SHFT                          0
+#define SH1_PTC_0_A_SHFT				0
 
 /*   SH1_PTC_0_PS                                                       */
 /*   Description:  Page Size                                            */
-#define SH1_PTC_0_PS_SHFT                         2
+#define SH1_PTC_0_PS_SHFT				2
 
 /*   SH1_PTC_0_RID                                                      */
 /*   Description:  Region ID                                            */
-#define SH1_PTC_0_RID_SHFT                        8
+#define SH1_PTC_0_RID_SHFT				8
 
 /*   SH1_PTC_0_START                                                    */
 /*   Description:  Start                                                */
-#define SH1_PTC_0_START_SHFT                      63
+#define SH1_PTC_0_START_SHFT				63
 
 /* ==================================================================== */
 /*                         Register "SH1_PTC_1"                         */
 /*       Puge Translation Cache Message Configuration Information       */
 /* ==================================================================== */
-#define SH1_PTC_1                                 0x00000001101a0080
+#define SH1_PTC_1			__IA64_UL_CONST(0x00000001101a0080)
 
 /*   SH1_PTC_1_START                                                    */
 /*   Description:  PTC_1 Start                                          */
-#define SH1_PTC_1_START_SHFT                      63
-
+#define SH1_PTC_1_START_SHFT				63
 
 /* ==================================================================== */
 /*                         Register "SH2_PTC"                           */
 /*       Puge Translation Cache Message Configuration Information       */
 /* ==================================================================== */
-#define SH2_PTC                                   0x0000000170000000
+#define SH2_PTC				__IA64_UL_CONST(0x0000000170000000)
 
 /*   SH2_PTC_A                                                          */
 /*   Description:  Type                                                 */
-#define SH2_PTC_A_SHFT                            0
+#define SH2_PTC_A_SHFT					0
 
 /*   SH2_PTC_PS                                                         */
 /*   Description:  Page Size                                            */
-#define SH2_PTC_PS_SHFT                           2
+#define SH2_PTC_PS_SHFT					2
 
 /*   SH2_PTC_RID                                                      */
 /*   Description:  Region ID                                            */
-#define SH2_PTC_RID_SHFT                          4
+#define SH2_PTC_RID_SHFT				4
 
 /*   SH2_PTC_START                                                      */
 /*   Description:  Start                                                */
-#define SH2_PTC_START_SHFT                        63
+#define SH2_PTC_START_SHFT				63
 
 /*   SH2_PTC_ADDR_RID                                                   */
 /*   Description:  Region ID                                            */
-#define SH2_PTC_ADDR_SHFT                         4
-#define SH2_PTC_ADDR_MASK                         0x1ffffffffffff000
+#define SH2_PTC_ADDR_SHFT				4
+#define SH2_PTC_ADDR_MASK		__IA64_UL_CONST(0x1ffffffffffff000)
 
 /* ==================================================================== */
 /*                    Register "SH_RTC1_INT_CONFIG"                     */
 /*                SHub RTC 1 Interrupt Config Registers                 */
 /* ==================================================================== */
 
-#define SH1_RTC1_INT_CONFIG                      0x0000000110001480
-#define SH2_RTC1_INT_CONFIG                      0x0000000010001480
-#define SH_RTC1_INT_CONFIG_MASK                  0x0ff3ffffffefffff
-#define SH_RTC1_INT_CONFIG_INIT                  0x0000000000000000
+#define SH1_RTC1_INT_CONFIG		__IA64_UL_CONST(0x0000000110001480)
+#define SH2_RTC1_INT_CONFIG		__IA64_UL_CONST(0x0000000010001480)
+#define SH_RTC1_INT_CONFIG_MASK		__IA64_UL_CONST(0x0ff3ffffffefffff)
+#define SH_RTC1_INT_CONFIG_INIT		__IA64_UL_CONST(0x0000000000000000)
 
 /*   SH_RTC1_INT_CONFIG_TYPE                                            */
 /*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
-#define SH_RTC1_INT_CONFIG_TYPE_SHFT             0
-#define SH_RTC1_INT_CONFIG_TYPE_MASK             0x0000000000000007
+#define SH_RTC1_INT_CONFIG_TYPE_SHFT			0
+#define SH_RTC1_INT_CONFIG_TYPE_MASK	__IA64_UL_CONST(0x0000000000000007)
 
 /*   SH_RTC1_INT_CONFIG_AGT                                             */
 /*   Description:  Agent, must be 0 for SHub                            */
-#define SH_RTC1_INT_CONFIG_AGT_SHFT              3
-#define SH_RTC1_INT_CONFIG_AGT_MASK              0x0000000000000008
+#define SH_RTC1_INT_CONFIG_AGT_SHFT			3
+#define SH_RTC1_INT_CONFIG_AGT_MASK	__IA64_UL_CONST(0x0000000000000008)
 
 /*   SH_RTC1_INT_CONFIG_PID                                             */
 /*   Description:  Processor ID, same setting as on targeted McKinley  */
-#define SH_RTC1_INT_CONFIG_PID_SHFT              4
-#define SH_RTC1_INT_CONFIG_PID_MASK              0x00000000000ffff0
+#define SH_RTC1_INT_CONFIG_PID_SHFT			4
+#define SH_RTC1_INT_CONFIG_PID_MASK	__IA64_UL_CONST(0x00000000000ffff0)
 
 /*   SH_RTC1_INT_CONFIG_BASE                                            */
 /*   Description:  Optional interrupt vector area, 2MB aligned          */
-#define SH_RTC1_INT_CONFIG_BASE_SHFT             21
-#define SH_RTC1_INT_CONFIG_BASE_MASK             0x0003ffffffe00000
+#define SH_RTC1_INT_CONFIG_BASE_SHFT			21
+#define SH_RTC1_INT_CONFIG_BASE_MASK	__IA64_UL_CONST(0x0003ffffffe00000)
 
 /*   SH_RTC1_INT_CONFIG_IDX                                             */
 /*   Description:  Targeted McKinley interrupt vector                   */
-#define SH_RTC1_INT_CONFIG_IDX_SHFT              52
-#define SH_RTC1_INT_CONFIG_IDX_MASK              0x0ff0000000000000
+#define SH_RTC1_INT_CONFIG_IDX_SHFT			52
+#define SH_RTC1_INT_CONFIG_IDX_MASK	__IA64_UL_CONST(0x0ff0000000000000)
 
 /* ==================================================================== */
 /*                    Register "SH_RTC1_INT_ENABLE"                     */
 /*                SHub RTC 1 Interrupt Enable Registers                 */
 /* ==================================================================== */
 
-#define SH1_RTC1_INT_ENABLE                      0x0000000110001500
-#define SH2_RTC1_INT_ENABLE                      0x0000000010001500
-#define SH_RTC1_INT_ENABLE_MASK                  0x0000000000000001
-#define SH_RTC1_INT_ENABLE_INIT                  0x0000000000000000
+#define SH1_RTC1_INT_ENABLE		__IA64_UL_CONST(0x0000000110001500)
+#define SH2_RTC1_INT_ENABLE		__IA64_UL_CONST(0x0000000010001500)
+#define SH_RTC1_INT_ENABLE_MASK		__IA64_UL_CONST(0x0000000000000001)
+#define SH_RTC1_INT_ENABLE_INIT		__IA64_UL_CONST(0x0000000000000000)
 
 /*   SH_RTC1_INT_ENABLE_RTC1_ENABLE                                     */
 /*   Description:  Enable RTC 1 Interrupt                               */
-#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_SHFT      0
-#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_MASK      0x0000000000000001
+#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_SHFT		0
+#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_MASK \
+					__IA64_UL_CONST(0x0000000000000001)
 
 /* ==================================================================== */
 /*                    Register "SH_RTC2_INT_CONFIG"                     */
 /*                SHub RTC 2 Interrupt Config Registers                 */
 /* ==================================================================== */
 
-#define SH1_RTC2_INT_CONFIG                      0x0000000110001580
-#define SH2_RTC2_INT_CONFIG                      0x0000000010001580
-#define SH_RTC2_INT_CONFIG_MASK                  0x0ff3ffffffefffff
-#define SH_RTC2_INT_CONFIG_INIT                  0x0000000000000000
+#define SH1_RTC2_INT_CONFIG		__IA64_UL_CONST(0x0000000110001580)
+#define SH2_RTC2_INT_CONFIG		__IA64_UL_CONST(0x0000000010001580)
+#define SH_RTC2_INT_CONFIG_MASK		__IA64_UL_CONST(0x0ff3ffffffefffff)
+#define SH_RTC2_INT_CONFIG_INIT		__IA64_UL_CONST(0x0000000000000000)
 
 /*   SH_RTC2_INT_CONFIG_TYPE                                            */
 /*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
-#define SH_RTC2_INT_CONFIG_TYPE_SHFT             0
-#define SH_RTC2_INT_CONFIG_TYPE_MASK             0x0000000000000007
+#define SH_RTC2_INT_CONFIG_TYPE_SHFT			0
+#define SH_RTC2_INT_CONFIG_TYPE_MASK	__IA64_UL_CONST(0x0000000000000007)
 
 /*   SH_RTC2_INT_CONFIG_AGT                                             */
 /*   Description:  Agent, must be 0 for SHub                            */
-#define SH_RTC2_INT_CONFIG_AGT_SHFT              3
-#define SH_RTC2_INT_CONFIG_AGT_MASK              0x0000000000000008
+#define SH_RTC2_INT_CONFIG_AGT_SHFT			3
+#define SH_RTC2_INT_CONFIG_AGT_MASK	__IA64_UL_CONST(0x0000000000000008)
 
 /*   SH_RTC2_INT_CONFIG_PID                                             */
 /*   Description:  Processor ID, same setting as on targeted McKinley  */
-#define SH_RTC2_INT_CONFIG_PID_SHFT              4
-#define SH_RTC2_INT_CONFIG_PID_MASK              0x00000000000ffff0
+#define SH_RTC2_INT_CONFIG_PID_SHFT			4
+#define SH_RTC2_INT_CONFIG_PID_MASK	__IA64_UL_CONST(0x00000000000ffff0)
 
 /*   SH_RTC2_INT_CONFIG_BASE                                            */
 /*   Description:  Optional interrupt vector area, 2MB aligned          */
-#define SH_RTC2_INT_CONFIG_BASE_SHFT             21
-#define SH_RTC2_INT_CONFIG_BASE_MASK             0x0003ffffffe00000
+#define SH_RTC2_INT_CONFIG_BASE_SHFT			21
+#define SH_RTC2_INT_CONFIG_BASE_MASK	__IA64_UL_CONST(0x0003ffffffe00000)
 
 /*   SH_RTC2_INT_CONFIG_IDX                                             */
 /*   Description:  Targeted McKinley interrupt vector                   */
-#define SH_RTC2_INT_CONFIG_IDX_SHFT              52
-#define SH_RTC2_INT_CONFIG_IDX_MASK              0x0ff0000000000000
+#define SH_RTC2_INT_CONFIG_IDX_SHFT			52
+#define SH_RTC2_INT_CONFIG_IDX_MASK	__IA64_UL_CONST(0x0ff0000000000000)
 
 /* ==================================================================== */
 /*                    Register "SH_RTC2_INT_ENABLE"                     */
 /*                SHub RTC 2 Interrupt Enable Registers                 */
 /* ==================================================================== */
 
-#define SH1_RTC2_INT_ENABLE                      0x0000000110001600
-#define SH2_RTC2_INT_ENABLE                      0x0000000010001600
-#define SH_RTC2_INT_ENABLE_MASK                  0x0000000000000001
-#define SH_RTC2_INT_ENABLE_INIT                  0x0000000000000000
+#define SH1_RTC2_INT_ENABLE		__IA64_UL_CONST(0x0000000110001600)
+#define SH2_RTC2_INT_ENABLE		__IA64_UL_CONST(0x0000000010001600)
+#define SH_RTC2_INT_ENABLE_MASK		__IA64_UL_CONST(0x0000000000000001)
+#define SH_RTC2_INT_ENABLE_INIT		__IA64_UL_CONST(0x0000000000000000)
 
 /*   SH_RTC2_INT_ENABLE_RTC2_ENABLE                                     */
 /*   Description:  Enable RTC 2 Interrupt                               */
-#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_SHFT      0
-#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_MASK      0x0000000000000001
+#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_SHFT		0
+#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_MASK \
+					__IA64_UL_CONST(0x0000000000000001)
 
 /* ==================================================================== */
 /*                    Register "SH_RTC3_INT_CONFIG"                     */
 /*                SHub RTC 3 Interrupt Config Registers                 */
 /* ==================================================================== */
 
-#define SH1_RTC3_INT_CONFIG                      0x0000000110001680
-#define SH2_RTC3_INT_CONFIG                      0x0000000010001680
-#define SH_RTC3_INT_CONFIG_MASK                  0x0ff3ffffffefffff
-#define SH_RTC3_INT_CONFIG_INIT                  0x0000000000000000
+#define SH1_RTC3_INT_CONFIG		__IA64_UL_CONST(0x0000000110001680)
+#define SH2_RTC3_INT_CONFIG		__IA64_UL_CONST(0x0000000010001680)
+#define SH_RTC3_INT_CONFIG_MASK		__IA64_UL_CONST(0x0ff3ffffffefffff)
+#define SH_RTC3_INT_CONFIG_INIT		__IA64_UL_CONST(0x0000000000000000)
 
 /*   SH_RTC3_INT_CONFIG_TYPE                                            */
 /*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
-#define SH_RTC3_INT_CONFIG_TYPE_SHFT             0
-#define SH_RTC3_INT_CONFIG_TYPE_MASK             0x0000000000000007
+#define SH_RTC3_INT_CONFIG_TYPE_SHFT			0
+#define SH_RTC3_INT_CONFIG_TYPE_MASK	__IA64_UL_CONST(0x0000000000000007)
 
 /*   SH_RTC3_INT_CONFIG_AGT                                             */
 /*   Description:  Agent, must be 0 for SHub                            */
-#define SH_RTC3_INT_CONFIG_AGT_SHFT              3
-#define SH_RTC3_INT_CONFIG_AGT_MASK              0x0000000000000008
+#define SH_RTC3_INT_CONFIG_AGT_SHFT			3
+#define SH_RTC3_INT_CONFIG_AGT_MASK	__IA64_UL_CONST(0x0000000000000008)
 
 /*   SH_RTC3_INT_CONFIG_PID                                             */
 /*   Description:  Processor ID, same setting as on targeted McKinley  */
-#define SH_RTC3_INT_CONFIG_PID_SHFT              4
-#define SH_RTC3_INT_CONFIG_PID_MASK              0x00000000000ffff0
+#define SH_RTC3_INT_CONFIG_PID_SHFT			4
+#define SH_RTC3_INT_CONFIG_PID_MASK	__IA64_UL_CONST(0x00000000000ffff0)
 
 /*   SH_RTC3_INT_CONFIG_BASE                                            */
 /*   Description:  Optional interrupt vector area, 2MB aligned          */
-#define SH_RTC3_INT_CONFIG_BASE_SHFT             21
-#define SH_RTC3_INT_CONFIG_BASE_MASK             0x0003ffffffe00000
+#define SH_RTC3_INT_CONFIG_BASE_SHFT			21
+#define SH_RTC3_INT_CONFIG_BASE_MASK	__IA64_UL_CONST(0x0003ffffffe00000)
 
 /*   SH_RTC3_INT_CONFIG_IDX                                             */
 /*   Description:  Targeted McKinley interrupt vector                   */
-#define SH_RTC3_INT_CONFIG_IDX_SHFT              52
-#define SH_RTC3_INT_CONFIG_IDX_MASK              0x0ff0000000000000
+#define SH_RTC3_INT_CONFIG_IDX_SHFT			52
+#define SH_RTC3_INT_CONFIG_IDX_MASK	__IA64_UL_CONST(0x0ff0000000000000)
 
 /* ==================================================================== */
 /*                    Register "SH_RTC3_INT_ENABLE"                     */
 /*                SHub RTC 3 Interrupt Enable Registers                 */
 /* ==================================================================== */
 
-#define SH1_RTC3_INT_ENABLE                      0x0000000110001700
-#define SH2_RTC3_INT_ENABLE                      0x0000000010001700
-#define SH_RTC3_INT_ENABLE_MASK                  0x0000000000000001
-#define SH_RTC3_INT_ENABLE_INIT                  0x0000000000000000
+#define SH1_RTC3_INT_ENABLE		__IA64_UL_CONST(0x0000000110001700)
+#define SH2_RTC3_INT_ENABLE		__IA64_UL_CONST(0x0000000010001700)
+#define SH_RTC3_INT_ENABLE_MASK		__IA64_UL_CONST(0x0000000000000001)
+#define SH_RTC3_INT_ENABLE_INIT		__IA64_UL_CONST(0x0000000000000000)
 
 /*   SH_RTC3_INT_ENABLE_RTC3_ENABLE                                     */
 /*   Description:  Enable RTC 3 Interrupt                               */
-#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_SHFT      0
-#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_MASK      0x0000000000000001
+#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_SHFT		0
+#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_MASK \
+					__IA64_UL_CONST(0x0000000000000001)
 
 /*   SH_EVENT_OCCURRED_RTC1_INT                                         */
 /*   Description:  Pending RTC 1 Interrupt                              */
-#define SH_EVENT_OCCURRED_RTC1_INT_SHFT          24
-#define SH_EVENT_OCCURRED_RTC1_INT_MASK          0x0000000001000000
+#define SH_EVENT_OCCURRED_RTC1_INT_SHFT			24
+#define SH_EVENT_OCCURRED_RTC1_INT_MASK	__IA64_UL_CONST(0x0000000001000000)
 
 /*   SH_EVENT_OCCURRED_RTC2_INT                                         */
 /*   Description:  Pending RTC 2 Interrupt                              */
-#define SH_EVENT_OCCURRED_RTC2_INT_SHFT          25
-#define SH_EVENT_OCCURRED_RTC2_INT_MASK          0x0000000002000000
+#define SH_EVENT_OCCURRED_RTC2_INT_SHFT			25
+#define SH_EVENT_OCCURRED_RTC2_INT_MASK	__IA64_UL_CONST(0x0000000002000000)
 
 /*   SH_EVENT_OCCURRED_RTC3_INT                                         */
 /*   Description:  Pending RTC 3 Interrupt                              */
-#define SH_EVENT_OCCURRED_RTC3_INT_SHFT          26
-#define SH_EVENT_OCCURRED_RTC3_INT_MASK          0x0000000004000000
+#define SH_EVENT_OCCURRED_RTC3_INT_SHFT			26
+#define SH_EVENT_OCCURRED_RTC3_INT_MASK	__IA64_UL_CONST(0x0000000004000000)
 
 /* ==================================================================== */
 /*                       Register "SH_IPI_ACCESS"                       */
 /*                 CPU interrupt Access Permission Bits                 */
 /* ==================================================================== */
 
-#define SH1_IPI_ACCESS                           0x0000000110060480
-#define SH2_IPI_ACCESS0                          0x0000000010060c00
-#define SH2_IPI_ACCESS1                          0x0000000010060c80
-#define SH2_IPI_ACCESS2                          0x0000000010060d00
-#define SH2_IPI_ACCESS3                          0x0000000010060d80
+#define SH1_IPI_ACCESS			__IA64_UL_CONST(0x0000000110060480)
+#define SH2_IPI_ACCESS0			__IA64_UL_CONST(0x0000000010060c00)
+#define SH2_IPI_ACCESS1			__IA64_UL_CONST(0x0000000010060c80)
+#define SH2_IPI_ACCESS2			__IA64_UL_CONST(0x0000000010060d00)
+#define SH2_IPI_ACCESS3			__IA64_UL_CONST(0x0000000010060d80)
 
 /* ==================================================================== */
 /*                        Register "SH_INT_CMPB"                        */
 /*                  RTC Compare Value for Processor B                   */
 /* ==================================================================== */
 
-#define SH1_INT_CMPB                             0x00000001101b0080
-#define SH2_INT_CMPB                             0x00000000101b0080
-#define SH_INT_CMPB_MASK                         0x007fffffffffffff
-#define SH_INT_CMPB_INIT                         0x0000000000000000
+#define SH1_INT_CMPB			__IA64_UL_CONST(0x00000001101b0080)
+#define SH2_INT_CMPB			__IA64_UL_CONST(0x00000000101b0080)
+#define SH_INT_CMPB_MASK		__IA64_UL_CONST(0x007fffffffffffff)
+#define SH_INT_CMPB_INIT		__IA64_UL_CONST(0x0000000000000000)
 
 /*   SH_INT_CMPB_REAL_TIME_CMPB                                         */
 /*   Description:  Real Time Clock Compare                              */
-#define SH_INT_CMPB_REAL_TIME_CMPB_SHFT          0
-#define SH_INT_CMPB_REAL_TIME_CMPB_MASK          0x007fffffffffffff
+#define SH_INT_CMPB_REAL_TIME_CMPB_SHFT			0
+#define SH_INT_CMPB_REAL_TIME_CMPB_MASK	__IA64_UL_CONST(0x007fffffffffffff)
 
 /* ==================================================================== */
 /*                        Register "SH_INT_CMPC"                        */
 /*                  RTC Compare Value for Processor C                   */
 /* ==================================================================== */
 
-#define SH1_INT_CMPC                             0x00000001101b0100
-#define SH2_INT_CMPC                             0x00000000101b0100
-#define SH_INT_CMPC_MASK                         0x007fffffffffffff
-#define SH_INT_CMPC_INIT                         0x0000000000000000
+#define SH1_INT_CMPC			__IA64_UL_CONST(0x00000001101b0100)
+#define SH2_INT_CMPC			__IA64_UL_CONST(0x00000000101b0100)
+#define SH_INT_CMPC_MASK		__IA64_UL_CONST(0x007fffffffffffff)
+#define SH_INT_CMPC_INIT		__IA64_UL_CONST(0x0000000000000000)
 
 /*   SH_INT_CMPC_REAL_TIME_CMPC                                         */
 /*   Description:  Real Time Clock Compare                              */
-#define SH_INT_CMPC_REAL_TIME_CMPC_SHFT          0
-#define SH_INT_CMPC_REAL_TIME_CMPC_MASK          0x007fffffffffffff
+#define SH_INT_CMPC_REAL_TIME_CMPC_SHFT			0
+#define SH_INT_CMPC_REAL_TIME_CMPC_MASK	__IA64_UL_CONST(0x007fffffffffffff)
 
 /* ==================================================================== */
 /*                        Register "SH_INT_CMPD"                        */
 /*                  RTC Compare Value for Processor D                   */
 /* ==================================================================== */
 
-#define SH1_INT_CMPD                             0x00000001101b0180
-#define SH2_INT_CMPD                             0x00000000101b0180
-#define SH_INT_CMPD_MASK                         0x007fffffffffffff
-#define SH_INT_CMPD_INIT                         0x0000000000000000
+#define SH1_INT_CMPD			__IA64_UL_CONST(0x00000001101b0180)
+#define SH2_INT_CMPD			__IA64_UL_CONST(0x00000000101b0180)
+#define SH_INT_CMPD_MASK		__IA64_UL_CONST(0x007fffffffffffff)
+#define SH_INT_CMPD_INIT		__IA64_UL_CONST(0x0000000000000000)
 
 /*   SH_INT_CMPD_REAL_TIME_CMPD                                         */
 /*   Description:  Real Time Clock Compare                              */
-#define SH_INT_CMPD_REAL_TIME_CMPD_SHFT          0
-#define SH_INT_CMPD_REAL_TIME_CMPD_MASK          0x007fffffffffffff
+#define SH_INT_CMPD_REAL_TIME_CMPD_SHFT			0
+#define SH_INT_CMPD_REAL_TIME_CMPD_MASK	__IA64_UL_CONST(0x007fffffffffffff)
 
 /* ==================================================================== */
 /*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC0"                 */
 /*                      privilege vector for acc=0                      */
 /* ==================================================================== */
-
-#define SH1_MD_DQLP_MMR_DIR_PRIVEC0              0x0000000100030300
+#define SH1_MD_DQLP_MMR_DIR_PRIVEC0	__IA64_UL_CONST(0x0000000100030300)
 
 /* ==================================================================== */
 /*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC0"                 */
 /*                      privilege vector for acc=0                      */
 /* ==================================================================== */
-
-#define SH1_MD_DQRP_MMR_DIR_PRIVEC0              0x0000000100050300
+#define SH1_MD_DQRP_MMR_DIR_PRIVEC0	__IA64_UL_CONST(0x0000000100050300)
 
 /* ==================================================================== */
 /* Some MMRs are functionally identical (or close enough) on both SHUB1 */
@@ -484,17 +486,17 @@
 /*                    Engine 0 Control and Status Register                    */
 /* ========================================================================== */
 
-#define SH2_BT_ENG_CSR_0                         0x0000000030040000
-#define SH2_BT_ENG_SRC_ADDR_0                    0x0000000030040080
-#define SH2_BT_ENG_DEST_ADDR_0                   0x0000000030040100
-#define SH2_BT_ENG_NOTIF_ADDR_0                  0x0000000030040180
+#define SH2_BT_ENG_CSR_0		__IA64_UL_CONST(0x0000000030040000)
+#define SH2_BT_ENG_SRC_ADDR_0		__IA64_UL_CONST(0x0000000030040080)
+#define SH2_BT_ENG_DEST_ADDR_0		__IA64_UL_CONST(0x0000000030040100)
+#define SH2_BT_ENG_NOTIF_ADDR_0		__IA64_UL_CONST(0x0000000030040180)
 
 /* ========================================================================== */
 /*                       BTE interfaces 1-3                                   */
 /* ========================================================================== */
 
-#define SH2_BT_ENG_CSR_1                         0x0000000030050000
-#define SH2_BT_ENG_CSR_2                         0x0000000030060000
-#define SH2_BT_ENG_CSR_3                         0x0000000030070000
+#define SH2_BT_ENG_CSR_1		__IA64_UL_CONST(0x0000000030050000)
+#define SH2_BT_ENG_CSR_2		__IA64_UL_CONST(0x0000000030060000)
+#define SH2_BT_ENG_CSR_3		__IA64_UL_CONST(0x0000000030070000)
 
 #endif /* _ASM_IA64_SN_SHUB_MMR_H */
diff --git a/include/asm-ia64/sn/simulator.h b/include/asm-ia64/sn/simulator.h
index 78eb4f8..cf770e2 100644
--- a/include/asm-ia64/sn/simulator.h
+++ b/include/asm-ia64/sn/simulator.h
@@ -10,16 +10,17 @@
 
 #include <linux/config.h>
 
-#ifdef CONFIG_IA64_SGI_SN_SIM
-
 #define SNMAGIC 0xaeeeeeee8badbeefL
-#define IS_RUNNING_ON_SIMULATOR() ({long sn; asm("mov %0=cpuid[%1]" : "=r"(sn) : "r"(2)); sn == SNMAGIC;})
+#define IS_MEDUSA()			({long sn; asm("mov %0=cpuid[%1]" : "=r"(sn) : "r"(2)); sn == SNMAGIC;})
 
-#define SIMULATOR_SLEEP()	asm("nop.i 0x8beef")
-
+#ifdef CONFIG_IA64_SGI_SN_SIM
+#define SIMULATOR_SLEEP()		asm("nop.i 0x8beef")
+#define IS_RUNNING_ON_SIMULATOR() 	(sn_prom_type)
+#define IS_RUNNING_ON_FAKE_PROM()	(sn_prom_type == 2)
+extern int sn_prom_type;		/* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */
 #else
-
 #define IS_RUNNING_ON_SIMULATOR()	(0)
+#define IS_RUNNING_ON_FAKE_PROM()	(0)
 #define SIMULATOR_SLEEP()
 
 #endif
diff --git a/include/asm-ia64/sn/sn2/sn_hwperf.h b/include/asm-ia64/sn/sn2/sn_hwperf.h
index b0c4d6d..df75f4c 100644
--- a/include/asm-ia64/sn/sn2/sn_hwperf.h
+++ b/include/asm-ia64/sn/sn2/sn_hwperf.h
@@ -223,4 +223,6 @@
 #define SN_HWPERF_OP_RECONFIGURE	253
 #define SN_HWPERF_OP_INVAL		254
 
+int sn_topology_open(struct inode *inode, struct file *file);
+int sn_topology_release(struct inode *inode, struct file *file);
 #endif				/* SN_HWPERF_H */
diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h
index eb0395a..1455375 100644
--- a/include/asm-ia64/sn/sn_sal.h
+++ b/include/asm-ia64/sn/sn_sal.h
@@ -132,6 +132,8 @@
 #define SALRET_INVALID_ARG	(-2)
 #define SALRET_ERROR		(-3)
 
+#define SN_SAL_FAKE_PROM			   0x02009999
+
 
 /**
  * sn_sal_rev_major - get the major SGI SAL revision number
@@ -1105,4 +1107,12 @@
 	return (int) rv.status;
 }
 
+static inline int
+ia64_sn_is_fake_prom(void)
+{
+	struct ia64_sal_retval rv;
+	SAL_CALL_NOLOCK(rv, SN_SAL_FAKE_PROM, 0, 0, 0, 0, 0, 0, 0);
+	return (rv.status == 0);
+}
+
 #endif /* _ASM_IA64_SN_SN_SAL_H */
diff --git a/include/asm-ia64/sn/tioca_provider.h b/include/asm-ia64/sn/tioca_provider.h
index b6acc22..5ccec60 100644
--- a/include/asm-ia64/sn/tioca_provider.h
+++ b/include/asm-ia64/sn/tioca_provider.h
@@ -201,6 +201,7 @@
 }
 
 extern uint32_t	tioca_gart_found;
+extern struct list_head tioca_list;
 extern int tioca_init_provider(void);
 extern void tioca_fastwrite_enable(struct tioca_kernel *tioca_kern);
 #endif /* _ASM_IA64_SN_TIO_CA_AGP_PROVIDER_H */
diff --git a/include/asm-ia64/vga.h b/include/asm-ia64/vga.h
index 1f446d6..bc3349f 100644
--- a/include/asm-ia64/vga.h
+++ b/include/asm-ia64/vga.h
@@ -14,7 +14,10 @@
  * videoram directly without any black magic.
  */
 
-#define VGA_MAP_MEM(x)	((unsigned long) ioremap((x), 0))
+extern unsigned long vga_console_iobase;
+extern unsigned long vga_console_membase;
+
+#define VGA_MAP_MEM(x)	((unsigned long) ioremap(vga_console_membase + (x), 0))
 
 #define vga_readb(x)	(*(x))
 #define vga_writeb(x,y)	(*(y) = (x))
diff --git a/include/asm-m68k/serial.h b/include/asm-m68k/serial.h
index 9f5bcdc..3fe29f8 100644
--- a/include/asm-m68k/serial.h
+++ b/include/asm-m68k/serial.h
@@ -26,54 +26,9 @@
 #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
 #endif
 
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define FOURPORT_FLAGS ASYNC_FOURPORT
-#define ACCENT_FLAGS 0
-#define BOCA_FLAGS 0
-#endif
-
-#define STD_SERIAL_PORT_DEFNS			\
+#define SERIAL_PORT_DFNS			\
 	/* UART CLK   PORT IRQ     FLAGS        */			\
 	{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },	/* ttyS0 */	\
 	{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS },	/* ttyS1 */	\
 	{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },	/* ttyS2 */	\
 	{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },	/* ttyS3 */
-
-
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define EXTRA_SERIAL_PORT_DEFNS			\
-	{ 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS },	/* ttyS4 */	\
-	{ 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS },	/* ttyS5 */	\
-	{ 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS },	/* ttyS6 */	\
-	{ 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS },	/* ttyS7 */	\
-	{ 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS },	/* ttyS8 */	\
-	{ 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS },	/* ttyS9 */	\
-	{ 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS },	/* ttyS10 */	\
-	{ 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS },	/* ttyS11 */	\
-	{ 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS },	/* ttyS12 */	\
-	{ 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS },	/* ttyS13 */	\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS14 (spare) */		\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS15 (spare) */		\
-	{ 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS },	/* ttyS16 */	\
-	{ 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS },	/* ttyS17 */	\
-	{ 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS },	/* ttyS18 */	\
-	{ 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS },	/* ttyS19 */	\
-	{ 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS },	/* ttyS20 */	\
-	{ 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS },	/* ttyS21 */	\
-	{ 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS },	/* ttyS22 */	\
-	{ 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS },	/* ttyS23 */	\
-	{ 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS },	/* ttyS24 */	\
-	{ 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS },	/* ttyS25 */	\
-	{ 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS },	/* ttyS26 */	\
-	{ 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS },	/* ttyS27 */	\
-	{ 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS },	/* ttyS28 */	\
-	{ 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS },	/* ttyS29 */	\
-	{ 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS },	/* ttyS30 */	\
-	{ 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS },	/* ttyS31 */
-#else
-#define EXTRA_SERIAL_PORT_DEFNS
-#endif
-
-#define SERIAL_PORT_DFNS		\
-	STD_SERIAL_PORT_DEFNS		\
-	EXTRA_SERIAL_PORT_DEFNS
diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h
index c9c576b..2d323b6 100644
--- a/include/asm-mips/pci.h
+++ b/include/asm-mips/pci.h
@@ -130,6 +130,16 @@
 extern void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev,
 	dma64_addr_t dma_addr, size_t len, int direction);
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
 extern void pcibios_resource_to_bus(struct pci_dev *dev,
 	struct pci_bus_region *region, struct resource *res);
 
diff --git a/include/asm-mips/serial.h b/include/asm-mips/serial.h
index 8a70ff5..4eed8e2a 100644
--- a/include/asm-mips/serial.h
+++ b/include/asm-mips/serial.h
@@ -29,32 +29,6 @@
 #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
 #endif
 
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define FOURPORT_FLAGS ASYNC_FOURPORT
-#define ACCENT_FLAGS 0
-#define BOCA_FLAGS 0
-#define HUB6_FLAGS 0
-#define RS_TABLE_SIZE	64
-#else
-#define RS_TABLE_SIZE
-#endif
-
-/*
- * The following define the access methods for the HUB6 card. All
- * access is through two ports for all 24 possible chips. The card is
- * selected through the high 2 bits, the port on that card with the
- * "middle" 3 bits, and the register on that port with the bottom
- * 3 bits.
- *
- * While the access port and interrupt is configurable, the default
- * port locations are 0x302 for the port control register, and 0x303
- * for the data read/write register. Normally, the interrupt is at irq3
- * but can be anything from 3 to 7 inclusive. Note that using 3 will
- * require disabling com2.
- */
-
-#define C_P(card,port) (((card)<<6|(port)<<3) + 1)
-
 #ifdef CONFIG_MACH_JAZZ
 #include <asm/jazz.h>
 
@@ -240,66 +214,10 @@
 	{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },	/* ttyS2 */	\
 	{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },	/* ttyS3 */
 
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define EXTRA_SERIAL_PORT_DEFNS			\
-	{ 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, 	/* ttyS4 */	\
-	{ 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS },	/* ttyS5 */	\
-	{ 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS },	/* ttyS6 */	\
-	{ 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS },	/* ttyS7 */	\
-	{ 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS },	/* ttyS8 */	\
-	{ 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS },	/* ttyS9 */	\
-	{ 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS },	/* ttyS10 */	\
-	{ 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS },	/* ttyS11 */	\
-	{ 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS },	/* ttyS12 */	\
-	{ 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS },	/* ttyS13 */	\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },			/* ttyS14 (spare) */ \
-	{ 0, BASE_BAUD, 0x000, 0, 0 },			/* ttyS15 (spare) */ \
-	{ 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS },	/* ttyS16 */	\
-	{ 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS },	/* ttyS17 */	\
-	{ 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS },	/* ttyS18 */	\
-	{ 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS },	/* ttyS19 */	\
-	{ 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS },	/* ttyS20 */	\
-	{ 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS },	/* ttyS21 */	\
-	{ 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS },	/* ttyS22 */	\
-	{ 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS },	/* ttyS23 */	\
-	{ 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS },	/* ttyS24 */	\
-	{ 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS },	/* ttyS25 */	\
-	{ 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS },	/* ttyS26 */	\
-	{ 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS },	/* ttyS27 */	\
-	{ 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS },	/* ttyS28 */	\
-	{ 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS },	/* ttyS29 */	\
-	{ 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS },	/* ttyS30 */	\
-	{ 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS },	/* ttyS31 */
-#else /* CONFIG_SERIAL_MANY_PORTS */
-#define EXTRA_SERIAL_PORT_DEFNS
-#endif /* CONFIG_SERIAL_MANY_PORTS */
-
 #else /* CONFIG_HAVE_STD_PC_SERIAL_PORTS */
 #define STD_SERIAL_PORT_DEFNS
-#define EXTRA_SERIAL_PORT_DEFNS
 #endif /* CONFIG_HAVE_STD_PC_SERIAL_PORTS */
 
-/* You can have up to four HUB6's in the system, but I've only
- * included two cards here for a total of twelve ports.
- */
-#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS))
-#define HUB6_SERIAL_PORT_DFNS		\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) },  /* ttyS32 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) },  /* ttyS33 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) },  /* ttyS34 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) },  /* ttyS35 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) },  /* ttyS36 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) },  /* ttyS37 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) },  /* ttyS38 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) },  /* ttyS39 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) },  /* ttyS40 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) },  /* ttyS41 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) },  /* ttyS42 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) },  /* ttyS43 */
-#else
-#define HUB6_SERIAL_PORT_DFNS
-#endif
-
 #ifdef CONFIG_MOMENCO_JAGUAR_ATX
 /* Ordinary NS16552 duart with a 20MHz crystal.  */
 #define JAGUAR_ATX_UART_CLK	20000000
@@ -427,8 +345,6 @@
 	COBALT_SERIAL_PORT_DEFNS			\
 	DDB5477_SERIAL_PORT_DEFNS			\
 	EV96100_SERIAL_PORT_DEFNS			\
-	EXTRA_SERIAL_PORT_DEFNS				\
-	HUB6_SERIAL_PORT_DFNS				\
 	IP32_SERIAL_PORT_DEFNS                          \
 	ITE_SERIAL_PORT_DEFNS           		\
 	IVR_SERIAL_PORT_DEFNS           		\
diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h
index 0763c29..ee741c1 100644
--- a/include/asm-parisc/pci.h
+++ b/include/asm-parisc/pci.h
@@ -230,6 +230,25 @@
 /* export the pci_ DMA API in terms of the dma_ one */
 #include <asm-generic/pci-dma-compat.h>
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	unsigned long cacheline_size;
+	u8 byte;
+
+	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte);
+	if (byte == 0)
+		cacheline_size = 1024;
+	else
+		cacheline_size = (int) byte * 4;
+
+	*strat = PCI_DMA_BURST_MULTIPLE;
+	*strategy_parameter = cacheline_size;
+}
+#endif
+
 extern void
 pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
 			 struct resource *res);
diff --git a/include/asm-parisc/serial.h b/include/asm-parisc/serial.h
index 239c5dc..82fd820 100644
--- a/include/asm-parisc/serial.h
+++ b/include/asm-parisc/serial.h
@@ -19,18 +19,4 @@
  * A500 w/ PCI serial cards: 5 + 4 * card ~= 17
  */
  
-#define STD_SERIAL_PORT_DEFNS			\
-	{ 0, },		/* ttyS0 */	\
-	{ 0, },		/* ttyS1 */	\
-	{ 0, },		/* ttyS2 */	\
-	{ 0, },		/* ttyS3 */	\
-	{ 0, },		/* ttyS4 */	\
-	{ 0, },		/* ttyS5 */	\
-	{ 0, },		/* ttyS6 */	\
-	{ 0, },		/* ttyS7 */	\
-	{ 0, },		/* ttyS8 */
-
-
-#define SERIAL_PORT_DFNS		\
-	STD_SERIAL_PORT_DEFNS
-
+#define SERIAL_PORT_DFNS
diff --git a/include/asm-ppc/macio.h b/include/asm-ppc/macio.h
index 2cafc99..a481b77 100644
--- a/include/asm-ppc/macio.h
+++ b/include/asm-ppc/macio.h
@@ -1,6 +1,7 @@
 #ifndef __MACIO_ASIC_H__
 #define __MACIO_ASIC_H__
 
+#include <linux/mod_devicetable.h>
 #include <asm/of_device.h>
 
 extern struct bus_type macio_bus_type;
@@ -120,10 +121,10 @@
 struct macio_driver
 {
 	char			*name;
-	struct of_match		*match_table;
+	struct of_device_id	*match_table;
 	struct module		*owner;
 
-	int	(*probe)(struct macio_dev* dev, const struct of_match *match);
+	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);
diff --git a/include/asm-ppc/mpc8xx.h b/include/asm-ppc/mpc8xx.h
index 714d69c..7c31f2d 100644
--- a/include/asm-ppc/mpc8xx.h
+++ b/include/asm-ppc/mpc8xx.h
@@ -68,6 +68,10 @@
 #include <platforms/lantec.h>
 #endif
 
+#if defined(CONFIG_MPC885ADS)
+#include <platforms/mpc885ads.h>
+#endif
+
 /* Currently, all 8xx boards that support a processor to PCI/ISA bridge
  * use the same memory map.
  */
diff --git a/include/asm-ppc/of_device.h b/include/asm-ppc/of_device.h
index 7229735..4b264cf 100644
--- a/include/asm-ppc/of_device.h
+++ b/include/asm-ppc/of_device.h
@@ -24,20 +24,8 @@
 };
 #define	to_of_device(d) container_of(d, struct of_device, dev)
 
-/*
- * Struct used for matching a device
- */
-struct of_match
-{
-	char	*name;
-	char	*type;
-	char	*compatible;
-	void	*data;
-};
-#define OF_ANY_MATCH		((char *)-1L)
-
-extern const struct of_match *of_match_device(
-	const struct of_match *matches, const 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);
@@ -49,10 +37,10 @@
 struct of_platform_driver
 {
 	char			*name;
-	struct of_match		*match_table;
+	struct of_device_id	*match_table;
 	struct module		*owner;
 
-	int	(*probe)(struct of_device* dev, const struct of_match *match);
+	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);
diff --git a/include/asm-ppc/pc_serial.h b/include/asm-ppc/pc_serial.h
index fa9cbb6..8f994f9 100644
--- a/include/asm-ppc/pc_serial.h
+++ b/include/asm-ppc/pc_serial.h
@@ -35,93 +35,9 @@
 #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
 #endif
 
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define FOURPORT_FLAGS ASYNC_FOURPORT
-#define ACCENT_FLAGS 0
-#define BOCA_FLAGS 0
-#define HUB6_FLAGS 0
-#endif
-	
-/*
- * The following define the access methods for the HUB6 card. All
- * access is through two ports for all 24 possible chips. The card is
- * selected through the high 2 bits, the port on that card with the
- * "middle" 3 bits, and the register on that port with the bottom
- * 3 bits.
- *
- * While the access port and interrupt is configurable, the default
- * port locations are 0x302 for the port control register, and 0x303
- * for the data read/write register. Normally, the interrupt is at irq3
- * but can be anything from 3 to 7 inclusive. Note that using 3 will
- * require disabling com2.
- */
-
-#define C_P(card,port) (((card)<<6|(port)<<3) + 1)
-
-#define STD_SERIAL_PORT_DEFNS			\
+#define SERIAL_PORT_DFNS			\
 	/* UART CLK   PORT IRQ     FLAGS        */			\
 	{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },	/* ttyS0 */	\
 	{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS },	/* ttyS1 */	\
 	{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },	/* ttyS2 */	\
 	{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },	/* ttyS3 */
-
-
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define EXTRA_SERIAL_PORT_DEFNS			\
-	{ 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, 	/* ttyS4 */	\
-	{ 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS },	/* ttyS5 */	\
-	{ 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS },	/* ttyS6 */	\
-	{ 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS },	/* ttyS7 */	\
-	{ 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS },	/* ttyS8 */	\
-	{ 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS },	/* ttyS9 */	\
-	{ 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS },	/* ttyS10 */	\
-	{ 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS },	/* ttyS11 */	\
-	{ 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS },	/* ttyS12 */	\
-	{ 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS },	/* ttyS13 */	\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS14 (spare) */		\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS15 (spare) */		\
-	{ 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS },	/* ttyS16 */	\
-	{ 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS },	/* ttyS17 */	\
-	{ 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS },	/* ttyS18 */	\
-	{ 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS },	/* ttyS19 */	\
-	{ 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS },	/* ttyS20 */	\
-	{ 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS },	/* ttyS21 */	\
-	{ 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS },	/* ttyS22 */	\
-	{ 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS },	/* ttyS23 */	\
-	{ 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS },	/* ttyS24 */	\
-	{ 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS },	/* ttyS25 */	\
-	{ 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS },	/* ttyS26 */	\
-	{ 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS },	/* ttyS27 */	\
-	{ 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS },	/* ttyS28 */	\
-	{ 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS },	/* ttyS29 */	\
-	{ 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS },	/* ttyS30 */	\
-	{ 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS },	/* ttyS31 */
-#else
-#define EXTRA_SERIAL_PORT_DEFNS
-#endif
-
-/* You can have up to four HUB6's in the system, but I've only
- * included two cards here for a total of twelve ports.
- */
-#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS))
-#define HUB6_SERIAL_PORT_DFNS		\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) },  /* ttyS32 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) },  /* ttyS33 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) },  /* ttyS34 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) },  /* ttyS35 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) },  /* ttyS36 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) },  /* ttyS37 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) },  /* ttyS38 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) },  /* ttyS39 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) },  /* ttyS40 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) },  /* ttyS41 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) },  /* ttyS42 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) },  /* ttyS43 */
-#else
-#define HUB6_SERIAL_PORT_DFNS
-#endif
-
-#define SERIAL_PORT_DFNS		\
-	STD_SERIAL_PORT_DEFNS		\
-	EXTRA_SERIAL_PORT_DEFNS		\
-	HUB6_SERIAL_PORT_DFNS
diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h
index ce5ae6d..db0a2a0 100644
--- a/include/asm-ppc/pci.h
+++ b/include/asm-ppc/pci.h
@@ -69,6 +69,16 @@
 #define pci_unmap_len(PTR, LEN_NAME)		(0)
 #define pci_unmap_len_set(PTR, LEN_NAME, VAL)	do { } while (0)
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
 /*
  * At present there are very few 32-bit PPC machines that can have
  * memory above the 4GB point, and we don't support that.
@@ -103,6 +113,12 @@
 					 unsigned long size,
 					 pgprot_t prot);
 
+#define HAVE_ARCH_PCI_RESOURCE_TO_USER
+extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
+				 const struct resource *rsrc,
+				 u64 *start, u64 *end);
+
+
 #endif	/* __KERNEL__ */
 
 #endif /* __PPC_PCI_H */
diff --git a/include/asm-ppc64/byteorder.h b/include/asm-ppc64/byteorder.h
index 8032753..8b57da6 100644
--- a/include/asm-ppc64/byteorder.h
+++ b/include/asm-ppc64/byteorder.h
@@ -40,7 +40,6 @@
 	__asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
 }
 
-#if 0
 static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value)
 {
 	__u16 result;
@@ -63,17 +62,8 @@
 	return result;
 }
 
-static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 value)
-{
-	__u64 result;
-#error implement me
-}
-
 #define __arch__swab16(x) ___arch__swab16(x)
 #define __arch__swab32(x) ___arch__swab32(x)
-#define __arch__swab64(x) ___arch__swab64(x)
-
-#endif
 
 /* The same, but returns converted value from the location pointer by addr. */
 #define __arch__swab16p(addr) ld_le16(addr)
diff --git a/include/asm-ppc64/iSeries/ItLpQueue.h b/include/asm-ppc64/iSeries/ItLpQueue.h
index 393299e..69b26ad 100644
--- a/include/asm-ppc64/iSeries/ItLpQueue.h
+++ b/include/asm-ppc64/iSeries/ItLpQueue.h
@@ -41,7 +41,7 @@
 #define LpEventMaxSize		256
 #define LpEventAlign		64
 
-struct ItLpQueue {
+struct hvlpevent_queue {
 /*
  * The xSlicCurEventPtr is the pointer to the next event stack entry
  * that will become valid.  The OS must peek at this entry to determine
@@ -69,16 +69,13 @@
 	char	*xSlicEventStackPtr;	// 0x20
 	u8	xIndex;			// 0x28 unique sequential index.
 	u8	xSlicRsvd[3];		// 0x29-2b
-	u32	xInUseWord;		// 0x2C
-	u64	xLpIntCount;		// 0x30 Total Lp Int msgs processed
-	u64	xLpIntCountByType[9];	// 0x38-0x7F Event counts by type
+	spinlock_t	lock;
 };
 
-extern struct ItLpQueue xItLpQueue;
+extern struct hvlpevent_queue hvlpevent_queue;
 
-extern struct HvLpEvent *ItLpQueue_getNextLpEvent(struct ItLpQueue *);
-extern int ItLpQueue_isLpIntPending(struct ItLpQueue *);
-extern unsigned ItLpQueue_process(struct ItLpQueue *, struct pt_regs *);
-extern void ItLpQueue_clearValid(struct HvLpEvent *);
+extern int hvlpevent_is_pending(void);
+extern void process_hvlpevents(struct pt_regs *);
+extern void setup_hvlpevent_queue(void);
 
 #endif /* _ITLPQUEUE_H */
diff --git a/include/asm-ppc64/paca.h b/include/asm-ppc64/paca.h
index ae76cae..2f0f36f 100644
--- a/include/asm-ppc64/paca.h
+++ b/include/asm-ppc64/paca.h
@@ -20,7 +20,6 @@
 #include	<asm/types.h>
 #include	<asm/lppaca.h>
 #include	<asm/iSeries/ItLpRegSave.h>
-#include	<asm/iSeries/ItLpQueue.h>
 #include	<asm/mmu.h>
 
 register struct paca_struct *local_paca asm("r13");
@@ -62,7 +61,6 @@
 	u16 paca_index;			/* Logical processor number */
 
 	u32 default_decr;		/* Default decrementer value */
-	struct ItLpQueue *lpqueue_ptr;	/* LpQueue handled by this CPU */
 	u64 kernel_toc;			/* Kernel TOC address */
 	u64 stab_real;			/* Absolute address of segment table */
 	u64 stab_addr;			/* Virtual address of segment table */
@@ -91,7 +89,6 @@
 	u64 next_jiffy_update_tb;	/* TB value for next jiffy update */
 	u64 saved_r1;			/* r1 save for RTAS calls */
 	u64 saved_msr;			/* MSR saved here by enter_rtas */
-	u32 lpevent_count;		/* lpevents processed  */
 	u8 proc_enabled;		/* irq soft-enable flag */
 
 	/* not yet used */
diff --git a/include/asm-ppc64/pci.h b/include/asm-ppc64/pci.h
index 6cd593f..d12dfce 100644
--- a/include/asm-ppc64/pci.h
+++ b/include/asm-ppc64/pci.h
@@ -78,6 +78,25 @@
 	return 0;
 }
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	unsigned long cacheline_size;
+	u8 byte;
+
+	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte);
+	if (byte == 0)
+		cacheline_size = 1024;
+	else
+		cacheline_size = (int) byte * 4;
+
+	*strat = PCI_DMA_BURST_MULTIPLE;
+	*strategy_parameter = cacheline_size;
+}
+#endif
+
 extern int pci_domain_nr(struct pci_bus *bus);
 
 /* Decide whether to display the domain number in /proc */
@@ -136,6 +155,13 @@
 					 unsigned long size,
 					 pgprot_t prot);
 
+#ifdef CONFIG_PPC_MULTIPLATFORM
+#define HAVE_ARCH_PCI_RESOURCE_TO_USER
+extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
+				 const struct resource *rsrc,
+				 u64 *start, u64 *end);
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+
 
 #endif	/* __KERNEL__ */
 
diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h
index b4a9f05..864cae7 100644
--- a/include/asm-s390/system.h
+++ b/include/asm-s390/system.h
@@ -107,11 +107,9 @@
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 extern void account_user_vtime(struct task_struct *);
 extern void account_system_vtime(struct task_struct *);
-#else
-#define account_system_vtime(prev) do { } while (0)
 #endif
 
-#define finish_arch_switch(rq, prev) do {				     \
+#define finish_arch_switch(prev) do {					     \
 	set_fs(current->thread.mm_segment);				     \
 	account_system_vtime(prev);					     \
 } while (0)
diff --git a/include/asm-sh/bigsur/serial.h b/include/asm-sh/bigsur/serial.h
index 540f122..7233af4 100644
--- a/include/asm-sh/bigsur/serial.h
+++ b/include/asm-sh/bigsur/serial.h
@@ -14,13 +14,10 @@
 #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
 
 
-#define STD_SERIAL_PORT_DEFNS                   \
+#define SERIAL_PORT_DFNS                   \
         /* UART CLK   PORT IRQ     FLAGS        */                      \
         { 0, BASE_BAUD, 0x3F8, HD64465_IRQ_UART, STD_COM_FLAGS } /* ttyS0 */ 
 
-
-#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS
-
 /* XXX: This should be moved ino irq.h */
 #define irq_cannonicalize(x) (x)
 
diff --git a/include/asm-sh/ec3104/serial.h b/include/asm-sh/ec3104/serial.h
index f8eb163..cfe4d78 100644
--- a/include/asm-sh/ec3104/serial.h
+++ b/include/asm-sh/ec3104/serial.h
@@ -10,13 +10,11 @@
  * it's got the keyboard controller behind it so we can't really use it
  * (without moving the keyboard driver to userspace, which doesn't sound
  * like a very good idea) */
-#define STD_SERIAL_PORT_DEFNS			\
+#define SERIAL_PORT_DFNS			\
 	/* UART CLK   PORT IRQ     FLAGS        */			\
 	{ 0, BASE_BAUD, 0x11C00, EC3104_IRQBASE+7, STD_COM_FLAGS }, /* ttyS0 */	\
 	{ 0, BASE_BAUD, 0x12000, EC3104_IRQBASE+8, STD_COM_FLAGS }, /* ttyS1 */	\
 	{ 0, BASE_BAUD, 0x12400, EC3104_IRQBASE+9, STD_COM_FLAGS }, /* ttyS2 */
 
-#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS
-
 /* XXX: This should be moved ino irq.h */
 #define irq_cannonicalize(x) (x)
diff --git a/include/asm-sh/pci.h b/include/asm-sh/pci.h
index 9c3b63d..2604488 100644
--- a/include/asm-sh/pci.h
+++ b/include/asm-sh/pci.h
@@ -96,6 +96,16 @@
 #define sg_dma_address(sg)	(virt_to_bus((sg)->dma_address))
 #define sg_dma_len(sg)		((sg)->length)
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
 /* Board-specific fixup routines. */
 extern void pcibios_fixup(void);
 extern void pcibios_fixup_irqs(void);
diff --git a/include/asm-sh/serial.h b/include/asm-sh/serial.h
index 5474dbd..f51e232 100644
--- a/include/asm-sh/serial.h
+++ b/include/asm-sh/serial.h
@@ -29,20 +29,18 @@
 #ifdef CONFIG_HD64465
 #include <asm/hd64465.h>
 
-#define STD_SERIAL_PORT_DEFNS                   \
+#define SERIAL_PORT_DFNS                   \
         /* UART CLK   PORT IRQ     FLAGS        */                      \
         { 0, BASE_BAUD, 0x3F8, HD64465_IRQ_UART, STD_COM_FLAGS }  /* ttyS0 */
 
 #else
 
-#define STD_SERIAL_PORT_DEFNS			\
+#define SERIAL_PORT_DFNS			\
 	/* UART CLK   PORT IRQ     FLAGS        */			\
 	{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },	/* ttyS0 */	\
 	{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }	/* ttyS1 */
 
 #endif
 
-#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS
-
 #endif
 #endif /* _ASM_SERIAL_H */
diff --git a/include/asm-sh64/pci.h b/include/asm-sh64/pci.h
index 8cc14e139..c68870e 100644
--- a/include/asm-sh64/pci.h
+++ b/include/asm-sh64/pci.h
@@ -86,6 +86,16 @@
 #define sg_dma_address(sg)	((sg)->dma_address)
 #define sg_dma_len(sg)		((sg)->length)
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
 /* Board-specific fixup routines. */
 extern void pcibios_fixup(void);
 extern void pcibios_fixup_irqs(void);
diff --git a/include/asm-sh64/serial.h b/include/asm-sh64/serial.h
index 8e39b4e..29c9be1 100644
--- a/include/asm-sh64/serial.h
+++ b/include/asm-sh64/serial.h
@@ -20,13 +20,11 @@
 
 #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
 
-#define STD_SERIAL_PORT_DEFNS			\
+#define SERIAL_PORT_DFNS			\
 	/* UART CLK   PORT IRQ     FLAGS        */			\
 	{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },	/* ttyS0 */	\
 	{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }	/* ttyS1 */
 
-#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS
-
 /* XXX: This should be moved ino irq.h */
 #define irq_cannonicalize(x) (x)
 
diff --git a/include/asm-sparc/pci.h b/include/asm-sparc/pci.h
index d200a25..44bb387 100644
--- a/include/asm-sparc/pci.h
+++ b/include/asm-sparc/pci.h
@@ -144,6 +144,16 @@
 
 #define pci_dac_dma_supported(dev, mask)	(0)
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
 static inline void pcibios_add_platform_entries(struct pci_dev *dev)
 {
 }
diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h
index 018e2e4..8b70edc 100644
--- a/include/asm-sparc64/irq.h
+++ b/include/asm-sparc64/irq.h
@@ -16,6 +16,18 @@
 #include <asm/pil.h>
 #include <asm/ptrace.h>
 
+struct ino_bucket;
+
+#define MAX_IRQ_DESC_ACTION	4
+
+struct irq_desc {
+	void			(*pre_handler)(struct ino_bucket *, void *, void *);
+	void			*pre_handler_arg1;
+	void			*pre_handler_arg2;
+	u32			action_active_mask;
+	struct irqaction	action[MAX_IRQ_DESC_ACTION];
+};
+
 /* You should not mess with this directly. That's the job of irq.c.
  *
  * If you make changes here, please update hand coded assembler of
@@ -42,24 +54,11 @@
 	/* Miscellaneous flags. */
 /*0x06*/unsigned char flags;
 
-	/* This is used to deal with IBF_DMA_SYNC on
-	 * Sabre systems.
-	 */
-/*0x07*/unsigned char synctab_ent;
+	/* Currently unused.  */
+/*0x07*/unsigned char __pad;
 
-	/* Reference to handler for this IRQ.  If this is
-	 * non-NULL this means it is active and should be
-	 * serviced.  Else the pending member is set to one
-	 * and later registry of the interrupt checks for
-	 * this condition.
-	 *
-	 * Normally this is just an irq_action structure.
-	 * But, on PCI, if multiple interrupt sources behind
-	 * a bridge have multiple interrupt sources that share
-	 * the same INO bucket, this points to an array of
-	 * pointers to four IRQ action structures.
-	 */
-/*0x08*/void *irq_info;
+	/* Reference to IRQ descriptor for this bucket. */
+/*0x08*/struct irq_desc *irq_info;
 
 	/* Sun5 Interrupt Clear Register. */
 /*0x10*/unsigned long iclr;
@@ -69,12 +68,6 @@
 
 };
 
-#ifdef CONFIG_PCI
-extern unsigned long pci_dma_wsync;
-extern unsigned long dma_sync_reg_table[256];
-extern unsigned char dma_sync_reg_table_entry;
-#endif
-
 /* IMAP/ICLR register defines */
 #define IMAP_VALID		0x80000000	/* IRQ Enabled		*/
 #define IMAP_TID_UPA		0x7c000000	/* UPA TargetID		*/
@@ -90,11 +83,9 @@
 #define ICLR_PENDING		0x00000003	/* Pending state	*/
 
 /* Only 8-bits are available, be careful.  -DaveM */
-#define IBF_DMA_SYNC	0x01	/* DMA synchronization behind PCI bridge needed. */
-#define IBF_PCI		0x02	/* Indicates PSYCHO/SABRE/SCHIZO PCI interrupt.	 */
-#define IBF_ACTIVE	0x04	/* This interrupt is active and has a handler.	 */
-#define IBF_MULTI	0x08	/* On PCI, indicates shared bucket.		 */
-#define IBF_INPROGRESS	0x10	/* IRQ is being serviced.			 */
+#define IBF_PCI		0x02	/* PSYCHO/SABRE/SCHIZO PCI interrupt.	 */
+#define IBF_ACTIVE	0x04	/* Interrupt is active and has a handler.*/
+#define IBF_INPROGRESS	0x10	/* IRQ is being serviced.		 */
 
 #define NUM_IVECS	(IMAP_INR + 1)
 extern struct ino_bucket ivector_table[NUM_IVECS];
diff --git a/include/asm-sparc64/parport.h b/include/asm-sparc64/parport.h
index b7e6355..56b5197d 100644
--- a/include/asm-sparc64/parport.h
+++ b/include/asm-sparc64/parport.h
@@ -27,12 +27,12 @@
 
 static __inline__ void enable_dma(unsigned int dmanr)
 {
+	ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1);
+
 	if (ebus_dma_request(&sparc_ebus_dmas[dmanr].info,
 			     sparc_ebus_dmas[dmanr].addr,
 			     sparc_ebus_dmas[dmanr].count))
 		BUG();
-
-	ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1);
 }
 
 static __inline__ void disable_dma(unsigned int dmanr)
diff --git a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h
index 4c15610a..38bbbcc 100644
--- a/include/asm-sparc64/pbm.h
+++ b/include/asm-sparc64/pbm.h
@@ -145,6 +145,9 @@
 	/* Physical address base of PBM registers. */
 	unsigned long			pbm_regs;
 
+	/* Physical address of DMA sync register, if any.  */
+	unsigned long			sync_reg;
+
 	/* Opaque 32-bit system bus Port ID. */
 	u32				portid;
 
diff --git a/include/asm-sparc64/pci.h b/include/asm-sparc64/pci.h
index 2a0c85c..84e41c1 100644
--- a/include/asm-sparc64/pci.h
+++ b/include/asm-sparc64/pci.h
@@ -220,6 +220,25 @@
 	return (dma_addr == PCI_DMA_ERROR_CODE);
 }
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	unsigned long cacheline_size;
+	u8 byte;
+
+	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte);
+	if (byte == 0)
+		cacheline_size = 1024;
+	else
+		cacheline_size = (int) byte * 4;
+
+	*strat = PCI_DMA_BURST_BOUNDARY;
+	*strategy_parameter = cacheline_size;
+}
+#endif
+
 /* Return the index of the PCI controller for device PDEV. */
 
 extern int pci_domain_nr(struct pci_bus *bus);
diff --git a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h
index becdf1b..e3059bb 100644
--- a/include/asm-sparc64/signal.h
+++ b/include/asm-sparc64/signal.h
@@ -162,21 +162,6 @@
 #define MINSIGSTKSZ	4096
 #define SIGSTKSZ	16384
 
-#ifdef __KERNEL__
-/*
- * DJHR
- * SA_STATIC_ALLOC is used for the SPARC system to indicate that this
- * interrupt handler's irq structure should be statically allocated
- * by the request_irq routine.
- * The alternative is that arch/sparc/kernel/irq.c has carnal knowledge
- * of interrupt usage and that sucks. Also without a flag like this
- * it may be possible for the free_irq routine to attempt to free
- * statically allocated data.. which is NOT GOOD.
- *
- */
-#define SA_STATIC_ALLOC		0x80
-#endif
-
 #include <asm-generic/signal.h>
 
 struct __new_sigaction {
diff --git a/include/asm-v850/pci.h b/include/asm-v850/pci.h
index e419414..8e79be0 100644
--- a/include/asm-v850/pci.h
+++ b/include/asm-v850/pci.h
@@ -81,6 +81,16 @@
 pci_free_consistent (struct pci_dev *pdev, size_t size, void *cpu_addr,
 		     dma_addr_t dma_addr);
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
 static inline void pcibios_add_platform_entries(struct pci_dev *dev)
 {
 }
diff --git a/include/asm-x86_64/io_apic.h b/include/asm-x86_64/io_apic.h
index 3257374..a8babd2 100644
--- a/include/asm-x86_64/io_apic.h
+++ b/include/asm-x86_64/io_apic.h
@@ -217,4 +217,6 @@
 
 void enable_NMI_through_LVT0 (void * dummy);
 
+extern spinlock_t i8259A_lock;
+
 #endif
diff --git a/include/asm-x86_64/pci.h b/include/asm-x86_64/pci.h
index 8712520..c1961db 100644
--- a/include/asm-x86_64/pci.h
+++ b/include/asm-x86_64/pci.h
@@ -123,6 +123,16 @@
 	flush_write_buffers();
 }
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
 #define HAVE_PCI_MMAP
 extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 			       enum pci_mmap_state mmap_state, int write_combine);
diff --git a/include/asm-x86_64/serial.h b/include/asm-x86_64/serial.h
index dbab232..dc752ea 100644
--- a/include/asm-x86_64/serial.h
+++ b/include/asm-x86_64/serial.h
@@ -22,109 +22,9 @@
 #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
 #endif
 
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define FOURPORT_FLAGS ASYNC_FOURPORT
-#define ACCENT_FLAGS 0
-#define BOCA_FLAGS 0
-#define HUB6_FLAGS 0
-#endif
-
-#define MCA_COM_FLAGS	(STD_COM_FLAGS|ASYNC_BOOT_ONLYMCA)
-
-/*
- * The following define the access methods for the HUB6 card. All
- * access is through two ports for all 24 possible chips. The card is
- * selected through the high 2 bits, the port on that card with the
- * "middle" 3 bits, and the register on that port with the bottom
- * 3 bits.
- *
- * While the access port and interrupt is configurable, the default
- * port locations are 0x302 for the port control register, and 0x303
- * for the data read/write register. Normally, the interrupt is at irq3
- * but can be anything from 3 to 7 inclusive. Note that using 3 will
- * require disabling com2.
- */
-
-#define C_P(card,port) (((card)<<6|(port)<<3) + 1)
-
-#define STD_SERIAL_PORT_DEFNS			\
+#define SERIAL_PORT_DFNS			\
 	/* UART CLK   PORT IRQ     FLAGS        */			\
 	{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },	/* ttyS0 */	\
 	{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS },	/* ttyS1 */	\
 	{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },	/* ttyS2 */	\
 	{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },	/* ttyS3 */
-
-
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define EXTRA_SERIAL_PORT_DEFNS			\
-	{ 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, 	/* ttyS4 */	\
-	{ 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS },	/* ttyS5 */	\
-	{ 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS },	/* ttyS6 */	\
-	{ 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS },	/* ttyS7 */	\
-	{ 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS },	/* ttyS8 */	\
-	{ 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS },	/* ttyS9 */	\
-	{ 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS },	/* ttyS10 */	\
-	{ 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS },	/* ttyS11 */	\
-	{ 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS },	/* ttyS12 */	\
-	{ 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS },	/* ttyS13 */	\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS14 (spare) */		\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS15 (spare) */		\
-	{ 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS },	/* ttyS16 */	\
-	{ 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS },	/* ttyS17 */	\
-	{ 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS },	/* ttyS18 */	\
-	{ 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS },	/* ttyS19 */	\
-	{ 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS },	/* ttyS20 */	\
-	{ 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS },	/* ttyS21 */	\
-	{ 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS },	/* ttyS22 */	\
-	{ 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS },	/* ttyS23 */	\
-	{ 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS },	/* ttyS24 */	\
-	{ 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS },	/* ttyS25 */	\
-	{ 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS },	/* ttyS26 */	\
-	{ 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS },	/* ttyS27 */	\
-	{ 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS },	/* ttyS28 */	\
-	{ 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS },	/* ttyS29 */	\
-	{ 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS },	/* ttyS30 */	\
-	{ 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS },	/* ttyS31 */
-#else
-#define EXTRA_SERIAL_PORT_DEFNS
-#endif
-
-/* You can have up to four HUB6's in the system, but I've only
- * included two cards here for a total of twelve ports.
- */
-#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS))
-#define HUB6_SERIAL_PORT_DFNS		\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) },  /* ttyS32 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) },  /* ttyS33 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) },  /* ttyS34 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) },  /* ttyS35 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) },  /* ttyS36 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) },  /* ttyS37 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) },  /* ttyS38 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) },  /* ttyS39 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) },  /* ttyS40 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) },  /* ttyS41 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) },  /* ttyS42 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) },  /* ttyS43 */
-#else
-#define HUB6_SERIAL_PORT_DFNS
-#endif
-
-#ifdef CONFIG_MCA
-#define MCA_SERIAL_PORT_DFNS			\
-	{ 0, BASE_BAUD, 0x3220, 3, MCA_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x3228, 3, MCA_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x4220, 3, MCA_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x4228, 3, MCA_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x5220, 3, MCA_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x5228, 3, MCA_COM_FLAGS },
-#else
-#define MCA_SERIAL_PORT_DFNS
-#endif
-
-#define SERIAL_PORT_DFNS		\
-	STD_SERIAL_PORT_DEFNS		\
-	EXTRA_SERIAL_PORT_DEFNS		\
-	HUB6_SERIAL_PORT_DFNS		\
-	MCA_SERIAL_PORT_DFNS
-
diff --git a/include/asm-xtensa/delay.h b/include/asm-xtensa/delay.h
index 6359c55..0a123d5 100644
--- a/include/asm-xtensa/delay.h
+++ b/include/asm-xtensa/delay.h
@@ -21,7 +21,7 @@
 extern __inline__ void __delay(unsigned long loops)
 {
   /* 2 cycles per loop. */
-  __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 1, 1b"
+  __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b"
 			: "=r" (loops) : "0" (loops));
 }
 
diff --git a/include/asm-xtensa/errno.h b/include/asm-xtensa/errno.h
index ced5194..a0f3b96 100644
--- a/include/asm-xtensa/errno.h
+++ b/include/asm-xtensa/errno.h
@@ -11,132 +11,6 @@
 #ifndef _XTENSA_ERRNO_H
 #define _XTENSA_ERRNO_H
 
-#define	EPERM		 1	/* Operation not permitted */
-#define	ENOENT		 2	/* No such file or directory */
-#define	ESRCH		 3	/* No such process */
-#define	EINTR		 4	/* Interrupted system call */
-#define	EIO		 5	/* I/O error */
-#define	ENXIO		 6	/* No such device or address */
-#define	E2BIG		 7	/* Arg list too long */
-#define	ENOEXEC		 8	/* Exec format error */
-#define	EBADF		 9	/* Bad file number */
-#define	ECHILD		10	/* No child processes */
-#define	EAGAIN		11	/* Try again */
-#define	ENOMEM		12	/* Out of memory */
-#define	EACCES		13	/* Permission denied */
-#define	EFAULT		14	/* Bad address */
-#define	ENOTBLK		15	/* Block device required */
-#define	EBUSY		16	/* Device or resource busy */
-#define	EEXIST		17	/* File exists */
-#define	EXDEV		18	/* Cross-device link */
-#define	ENODEV		19	/* No such device */
-#define	ENOTDIR		20	/* Not a directory */
-#define	EISDIR		21	/* Is a directory */
-#define	EINVAL		22	/* Invalid argument */
-#define	ENFILE		23	/* File table overflow */
-#define	EMFILE		24	/* Too many open files */
-#define	ENOTTY		25	/* Not a typewriter */
-#define	ETXTBSY		26	/* Text file busy */
-#define	EFBIG		27	/* File too large */
-#define	ENOSPC		28	/* No space left on device */
-#define	ESPIPE		29	/* Illegal seek */
-#define	EROFS		30	/* Read-only file system */
-#define	EMLINK		31	/* Too many links */
-#define	EPIPE		32	/* Broken pipe */
-#define	EDOM		33	/* Math argument out of domain of func */
-#define	ERANGE		34	/* Math result not representable */
-#define	EDEADLK		35	/* Resource deadlock would occur */
-#define	ENAMETOOLONG	36	/* File name too long */
-#define	ENOLCK		37	/* No record locks available */
-#define	ENOSYS		38	/* Function not implemented */
-#define	ENOTEMPTY	39	/* Directory not empty */
-#define	ELOOP		40	/* Too many symbolic links encountered */
-#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
-#define	ENOMSG		42	/* No message of desired type */
-#define	EIDRM		43	/* Identifier removed */
-#define	ECHRNG		44	/* Channel number out of range */
-#define	EL2NSYNC	45	/* Level 2 not synchronized */
-#define	EL3HLT		46	/* Level 3 halted */
-#define	EL3RST		47	/* Level 3 reset */
-#define	ELNRNG		48	/* Link number out of range */
-#define	EUNATCH		49	/* Protocol driver not attached */
-#define	ENOCSI		50	/* No CSI structure available */
-#define	EL2HLT		51	/* Level 2 halted */
-#define	EBADE		52	/* Invalid exchange */
-#define	EBADR		53	/* Invalid request descriptor */
-#define	EXFULL		54	/* Exchange full */
-#define	ENOANO		55	/* No anode */
-#define	EBADRQC		56	/* Invalid request code */
-#define	EBADSLT		57	/* Invalid slot */
-
-#define	EDEADLOCK	EDEADLK
-
-#define	EBFONT		59	/* Bad font file format */
-#define	ENOSTR		60	/* Device not a stream */
-#define	ENODATA		61	/* No data available */
-#define	ETIME		62	/* Timer expired */
-#define	ENOSR		63	/* Out of streams resources */
-#define	ENONET		64	/* Machine is not on the network */
-#define	ENOPKG		65	/* Package not installed */
-#define	EREMOTE		66	/* Object is remote */
-#define	ENOLINK		67	/* Link has been severed */
-#define	EADV		68	/* Advertise error */
-#define	ESRMNT		69	/* Srmount error */
-#define	ECOMM		70	/* Communication error on send */
-#define	EPROTO		71	/* Protocol error */
-#define	EMULTIHOP	72	/* Multihop attempted */
-#define	EDOTDOT		73	/* RFS specific error */
-#define	EBADMSG		74	/* Not a data message */
-#define	EOVERFLOW	75	/* Value too large for defined data type */
-#define	ENOTUNIQ	76	/* Name not unique on network */
-#define	EBADFD		77	/* File descriptor in bad state */
-#define	EREMCHG		78	/* Remote address changed */
-#define	ELIBACC		79	/* Can not access a needed shared library */
-#define	ELIBBAD		80	/* Accessing a corrupted shared library */
-#define	ELIBSCN		81	/* .lib section in a.out corrupted */
-#define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
-#define	ELIBEXEC	83	/* Cannot exec a shared library directly */
-#define	EILSEQ		84	/* Illegal byte sequence */
-#define	ERESTART	85	/* Interrupted system call should be restarted */
-#define	ESTRPIPE	86	/* Streams pipe error */
-#define	EUSERS		87	/* Too many users */
-#define	ENOTSOCK	88	/* Socket operation on non-socket */
-#define	EDESTADDRREQ	89	/* Destination address required */
-#define	EMSGSIZE	90	/* Message too long */
-#define	EPROTOTYPE	91	/* Protocol wrong type for socket */
-#define	ENOPROTOOPT	92	/* Protocol not available */
-#define	EPROTONOSUPPORT	93	/* Protocol not supported */
-#define	ESOCKTNOSUPPORT	94	/* Socket type not supported */
-#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */
-#define	EPFNOSUPPORT	96	/* Protocol family not supported */
-#define	EAFNOSUPPORT	97	/* Address family not supported by protocol */
-#define	EADDRINUSE	98	/* Address already in use */
-#define	EADDRNOTAVAIL	99	/* Cannot assign requested address */
-#define	ENETDOWN	100	/* Network is down */
-#define	ENETUNREACH	101	/* Network is unreachable */
-#define	ENETRESET	102	/* Network dropped connection because of reset */
-#define	ECONNABORTED	103	/* Software caused connection abort */
-#define	ECONNRESET	104	/* Connection reset by peer */
-#define	ENOBUFS		105	/* No buffer space available */
-#define	EISCONN		106	/* Transport endpoint is already connected */
-#define	ENOTCONN	107	/* Transport endpoint is not connected */
-#define	ESHUTDOWN	108	/* Cannot send after transport endpoint shutdown */
-#define	ETOOMANYREFS	109	/* Too many references: cannot splice */
-#define	ETIMEDOUT	110	/* Connection timed out */
-#define	ECONNREFUSED	111	/* Connection refused */
-#define	EHOSTDOWN	112	/* Host is down */
-#define	EHOSTUNREACH	113	/* No route to host */
-#define	EALREADY	114	/* Operation already in progress */
-#define	EINPROGRESS	115	/* Operation now in progress */
-#define	ESTALE		116	/* Stale NFS file handle */
-#define	EUCLEAN		117	/* Structure needs cleaning */
-#define	ENOTNAM		118	/* Not a XENIX named type file */
-#define	ENAVAIL		119	/* No XENIX semaphores available */
-#define	EISNAM		120	/* Is a named type file */
-#define	EREMOTEIO	121	/* Remote I/O error */
-#define	EDQUOT		122	/* Quota exceeded */
-
-#define	ENOMEDIUM	123	/* No medium found */
-#define	EMEDIUMTYPE	124	/* Wrong medium type */
+#include <asm-generic/errno.h>
 
 #endif	/* _XTENSA_ERRNO_H */
diff --git a/include/asm-xtensa/ipc.h b/include/asm-xtensa/ipc.h
index d37bdb4d4c..a9eed4e 100644
--- a/include/asm-xtensa/ipc.h
+++ b/include/asm-xtensa/ipc.h
@@ -11,24 +11,6 @@
 #ifndef _XTENSA_IPC_H
 #define _XTENSA_IPC_H
 
-struct ipc_kludge {
-	struct msgbuf __user *msgp;
-	long msgtyp;
-};
-
-#define SEMOP		 1
-#define SEMGET		 2
-#define SEMCTL		 3
-#define SEMTIMEDOP	 4
-#define MSGSND		11
-#define MSGRCV		12
-#define MSGGET		13
-#define MSGCTL		14
-#define SHMAT		21
-#define SHMDT		22
-#define SHMGET		23
-#define SHMCTL		24
-
-#define IPCCALL(version,op)	((version)<<16 | (op))
+#include <asm-generic/ipc.h>
 
 #endif	/* _XTENSA_IPC_H */
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index b123cc0..ef84836 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -342,11 +342,19 @@
 
 /* PCI MMCONFIG */
 
+/* Defined in PCI Firmware Specification 3.0 */
+struct acpi_table_mcfg_config {
+	u32				base_address;
+	u32				base_reserved;
+	u16				pci_segment_group_number;
+	u8				start_bus_number;
+	u8				end_bus_number;
+	u8				reserved[4];
+} __attribute__ ((packed));
 struct acpi_table_mcfg {
 	struct acpi_table_header	header;
 	u8				reserved[8];
-	u32				base_address;
-	u32				base_reserved;
+	struct acpi_table_mcfg_config	config[0];
 } __attribute__ ((packed));
 
 /* Table Handlers */
@@ -391,6 +399,7 @@
 int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header);
 int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries);
 int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries);
+int acpi_parse_mcfg (unsigned long phys_addr, unsigned long size);
 void acpi_table_print (struct acpi_table_header *header, unsigned long phys_addr);
 void acpi_table_print_madt_entry (acpi_table_entry_header *madt);
 void acpi_table_print_srat_entry (acpi_table_entry_header *srat);
@@ -407,9 +416,13 @@
 int acpi_unmap_lsapic(int cpu);
 #endif /* CONFIG_ACPI_HOTPLUG_CPU */
 
+int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base);
+int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base);
+
 extern int acpi_mp_config;
 
-extern u32 pci_mmcfg_base_addr;
+extern struct acpi_table_mcfg_config *pci_mmcfg_config;
+extern int pci_mmcfg_config_num;
 
 extern int sbf_port ;
 
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 21a8674..0881b5c 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -96,6 +96,7 @@
 
 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);
 void copy_io_context(struct io_context **pdst, struct io_context **psrc);
 void swap_io_context(struct io_context **ioc1, struct io_context **ioc2);
diff --git a/include/linux/byteorder/swabb.h b/include/linux/byteorder/swabb.h
index d28d9a8..d5f2a32 100644
--- a/include/linux/byteorder/swabb.h
+++ b/include/linux/byteorder/swabb.h
@@ -92,29 +92,32 @@
 #endif /* OPTIMIZE */
 
 
-static __inline__ __const__ __u32 __fswahw32(__u32 x)
+static inline __u32 __fswahw32(__u32 x)
 {
 	return __arch__swahw32(x);
 }
-static __inline__ __u32 __swahw32p(__u32 *x)
+
+static inline __u32 __swahw32p(__u32 *x)
 {
 	return __arch__swahw32p(x);
 }
-static __inline__ void __swahw32s(__u32 *addr)
+
+static inline void __swahw32s(__u32 *addr)
 {
 	__arch__swahw32s(addr);
 }
 
-
-static __inline__ __const__ __u32 __fswahb32(__u32 x)
+static inline __u32 __fswahb32(__u32 x)
 {
 	return __arch__swahb32(x);
 }
-static __inline__ __u32 __swahb32p(__u32 *x)
+
+static inline __u32 __swahb32p(__u32 *x)
 {
 	return __arch__swahb32p(x);
 }
-static __inline__ void __swahb32s(__u32 *addr)
+
+static inline void __swahb32s(__u32 *addr)
 {
 	__arch__swahb32s(addr);
 }
diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h
index 70a4ebb..ecb0d39 100644
--- a/include/linux/compat_ioctl.h
+++ b/include/linux/compat_ioctl.h
@@ -346,10 +346,27 @@
 /* LP */
 COMPATIBLE_IOCTL(LPGETSTATUS)
 /* ppdev */
+COMPATIBLE_IOCTL(PPSETMODE)
+COMPATIBLE_IOCTL(PPRSTATUS)
+COMPATIBLE_IOCTL(PPRCONTROL)
+COMPATIBLE_IOCTL(PPWCONTROL)
+COMPATIBLE_IOCTL(PPFCONTROL)
+COMPATIBLE_IOCTL(PPRDATA)
+COMPATIBLE_IOCTL(PPWDATA)
 COMPATIBLE_IOCTL(PPCLAIM)
 COMPATIBLE_IOCTL(PPRELEASE)
-COMPATIBLE_IOCTL(PPEXCL)
 COMPATIBLE_IOCTL(PPYIELD)
+COMPATIBLE_IOCTL(PPEXCL)
+COMPATIBLE_IOCTL(PPDATADIR)
+COMPATIBLE_IOCTL(PPNEGOT)
+COMPATIBLE_IOCTL(PPWCTLONIRQ)
+COMPATIBLE_IOCTL(PPCLRIRQ)
+COMPATIBLE_IOCTL(PPSETPHASE)
+COMPATIBLE_IOCTL(PPGETMODES)
+COMPATIBLE_IOCTL(PPGETMODE)
+COMPATIBLE_IOCTL(PPGETPHASE)
+COMPATIBLE_IOCTL(PPGETFLAGS)
+COMPATIBLE_IOCTL(PPSETFLAGS)
 /* CDROM stuff */
 COMPATIBLE_IOCTL(CDROMPAUSE)
 COMPATIBLE_IOCTL(CDROMRESUME)
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 387da6a..5e2bcc6 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -61,6 +61,15 @@
 #define CRYPTO_DIR_DECRYPT		0
 
 struct scatterlist;
+struct crypto_tfm;
+
+struct cipher_desc {
+	struct crypto_tfm *tfm;
+	void (*crfn)(void *ctx, u8 *dst, const u8 *src);
+	unsigned int (*prfn)(const struct cipher_desc *desc, u8 *dst,
+			     const u8 *src, unsigned int nbytes);
+	void *info;
+};
 
 /*
  * Algorithms: modular crypto algorithm implementations, managed
@@ -73,6 +82,19 @@
 	                  unsigned int keylen, u32 *flags);
 	void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src);
 	void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src);
+
+	unsigned int (*cia_encrypt_ecb)(const struct cipher_desc *desc,
+					u8 *dst, const u8 *src,
+					unsigned int nbytes);
+	unsigned int (*cia_decrypt_ecb)(const struct cipher_desc *desc,
+					u8 *dst, const u8 *src,
+					unsigned int nbytes);
+	unsigned int (*cia_encrypt_cbc)(const struct cipher_desc *desc,
+					u8 *dst, const u8 *src,
+					unsigned int nbytes);
+	unsigned int (*cia_decrypt_cbc)(const struct cipher_desc *desc,
+					u8 *dst, const u8 *src,
+					unsigned int nbytes);
 };
 
 struct digest_alg {
@@ -102,6 +124,7 @@
 	u32 cra_flags;
 	unsigned int cra_blocksize;
 	unsigned int cra_ctxsize;
+	unsigned int cra_alignmask;
 	const char cra_name[CRYPTO_MAX_ALG_NAME];
 
 	union {
@@ -136,7 +159,6 @@
  * and core processing logic.  Managed via crypto_alloc_tfm() and
  * crypto_free_tfm(), as well as the various helpers below.
  */
-struct crypto_tfm;
 
 struct cipher_tfm {
 	void *cit_iv;
@@ -266,6 +288,16 @@
 	return tfm->__crt_alg->cra_digest.dia_digestsize;
 }
 
+static inline unsigned int crypto_tfm_alg_alignmask(struct crypto_tfm *tfm)
+{
+	return tfm->__crt_alg->cra_alignmask;
+}
+
+static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
+{
+	return (void *)&tfm[1];
+}
+
 /*
  * API wrappers.
  */
diff --git a/include/linux/device.h b/include/linux/device.h
index 7b781a7..f378c84 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -69,7 +69,7 @@
 extern int bus_register(struct bus_type * bus);
 extern void bus_unregister(struct bus_type * bus);
 
-extern int bus_rescan_devices(struct bus_type * bus);
+extern void bus_rescan_devices(struct bus_type * bus);
 
 extern struct bus_type * get_bus(struct bus_type * bus);
 extern void put_bus(struct bus_type * bus);
@@ -80,6 +80,8 @@
 
 int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data,
 		     int (*fn)(struct device *, void *));
+struct device * bus_find_device(struct bus_type *bus, struct device *start,
+				void *data, int (*match)(struct device *, void *));
 
 int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, 
 		     void * data, int (*fn)(struct device_driver *, void *));
@@ -142,6 +144,9 @@
 
 extern int driver_for_each_device(struct device_driver * drv, struct device * start,
 				  void * data, int (*fn)(struct device *, void *));
+struct device * driver_find_device(struct device_driver *drv,
+				   struct device *start, void *data,
+				   int (*match)(struct device *, void *));
 
 
 /*
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index a147825..cf3847e 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -25,6 +25,7 @@
 #define _LINUX_ETHERDEVICE_H
 
 #include <linux/if_ether.h>
+#include <linux/netdevice.h>
 #include <linux/random.h>
 
 #ifdef __KERNEL__
@@ -65,7 +66,7 @@
  */
 static inline int is_multicast_ether_addr(const u8 *addr)
 {
-	return addr[0] & 0x01;
+	return ((addr[0] != 0xff) && (0x01 & addr[0]));
 }
 
 /**
diff --git a/include/linux/i2c-dev.h b/include/linux/i2c-dev.h
index d228230..5416956 100644
--- a/include/linux/i2c-dev.h
+++ b/include/linux/i2c-dev.h
@@ -25,6 +25,7 @@
 #define _LINUX_I2C_DEV_H
 
 #include <linux/types.h>
+#include <linux/compiler.h>
 
 /* Some IOCTL commands are defined in <linux/i2c.h> */
 /* Note: 10-bit addresses are NOT supported! */
diff --git a/include/linux/if_shaper.h b/include/linux/if_shaper.h
index 004e6f0..68c896a 100644
--- a/include/linux/if_shaper.h
+++ b/include/linux/if_shaper.h
@@ -23,7 +23,7 @@
 	__u32 shapeclock;
 	unsigned long recovery;	/* Time we can next clock a packet out on
 				   an empty queue */
-	struct semaphore sem;
+	spinlock_t lock;
         struct net_device_stats stats;
 	struct net_device *dev;
 	int  (*hard_start_xmit) (struct sk_buff *skb,
diff --git a/include/linux/in6.h b/include/linux/in6.h
index f8256c5..dcf5720 100644
--- a/include/linux/in6.h
+++ b/include/linux/in6.h
@@ -156,7 +156,7 @@
 #define IPV6_CHECKSUM		7
 #define IPV6_HOPLIMIT		8
 #define IPV6_NEXTHOP		9
-#define IPV6_AUTHHDR		10
+#define IPV6_AUTHHDR		10	/* obsolete */
 #define IPV6_FLOWINFO		11
 
 #define IPV6_UNICAST_HOPS	16
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 1227779..069d3b8 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -85,9 +85,10 @@
 extern int noirqdebug_setup(char *str);
 
 extern fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
-				       struct irqaction *action);
+					struct irqaction *action);
 extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
-extern void note_interrupt(unsigned int irq, irq_desc_t *desc, int action_ret);
+extern void note_interrupt(unsigned int irq, irq_desc_t *desc,
+					int action_ret, struct pt_regs *regs);
 extern int can_request_irq(unsigned int irq, unsigned long irqflags);
 
 extern void init_irq_proc(void);
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index b7a194c..e050fc2 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -155,7 +155,7 @@
 extern void arch_arm_kprobe(struct kprobe *p);
 extern void arch_disarm_kprobe(struct kprobe *p);
 extern void arch_remove_kprobe(struct kprobe *p);
-extern int arch_init(void);
+extern int arch_init_kprobes(void);
 extern void show_registers(struct pt_regs *regs);
 extern kprobe_opcode_t *get_insn_slot(void);
 extern void free_insn_slot(kprobe_opcode_t *slot);
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 9b6d051..dce53ac 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -174,6 +174,17 @@
 	__u8 proto;
 };
 
+/*
+ * Struct used for matching a device
+ */
+struct of_device_id
+{
+	char	name[32];
+	char	type[32];
+	char	compatible[128];
+	void	*data;
+};
+
 
 /* PCMCIA */
 
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index 3029cad..27e4d16 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -168,6 +168,7 @@
 	nlh->nlmsg_flags = flags;
 	nlh->nlmsg_pid = pid;
 	nlh->nlmsg_seq = seq;
+	memset(NLMSG_DATA(nlh) + len, 0, NLMSG_ALIGN(size) - size);
 	return nlh;
 }
 
diff --git a/include/linux/pci-dynids.h b/include/linux/pci-dynids.h
deleted file mode 100644
index 183b6b0..0000000
--- a/include/linux/pci-dynids.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- *	PCI defines and function prototypes
- *	Copyright 2003 Dell Inc.
- *        by Matt Domsch <Matt_Domsch@dell.com>
- */
-
-#ifndef LINUX_PCI_DYNIDS_H
-#define LINUX_PCI_DYNIDS_H
-
-#include <linux/list.h>
-#include <linux/mod_devicetable.h>
-
-struct dynid {
-	struct list_head        node;
-	struct pci_device_id    id;
-};
-
-#endif
diff --git a/include/linux/pci.h b/include/linux/pci.h
index b5238bd..7ac1496 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -586,7 +586,7 @@
 #define PCI_NUM_RESOURCES 11
 
 #ifndef PCI_BUS_NUM_RESOURCES
-#define PCI_BUS_NUM_RESOURCES 4
+#define PCI_BUS_NUM_RESOURCES 8
 #endif
   
 #define PCI_REGION_FLAG_MASK 0x0fU	/* These bits of resource flags tell us the PCI region flags */
@@ -734,16 +734,20 @@
 /* Generic PCI functions used internally */
 
 extern struct pci_bus *pci_find_bus(int domain, int busnr);
+void pci_bus_add_devices(struct pci_bus *bus);
 struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata);
 static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata)
 {
-	return pci_scan_bus_parented(NULL, bus, ops, sysdata);
+	struct pci_bus *root_bus;
+	root_bus = pci_scan_bus_parented(NULL, bus, ops, sysdata);
+	if (root_bus)
+		pci_bus_add_devices(root_bus);
+	return root_bus;
 }
 int pci_scan_slot(struct pci_bus *bus, int devfn);
 struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn);
 unsigned int pci_scan_child_bus(struct pci_bus *bus);
 void pci_bus_add_device(struct pci_dev *dev);
-void pci_bus_add_devices(struct pci_bus *bus);
 void pci_name_device(struct pci_dev *dev);
 char *pci_class_name(u32 class);
 void pci_read_bridge_bases(struct pci_bus *child);
@@ -856,7 +860,8 @@
 void pci_unregister_driver(struct pci_driver *);
 void pci_remove_behind_bridge(struct pci_dev *);
 struct pci_driver *pci_dev_driver(const struct pci_dev *);
-const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev);
+const struct pci_device_id *pci_match_device(struct pci_driver *drv, struct pci_dev *dev);
+const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, struct pci_dev *dev);
 int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass);
 
 /* kmem_cache style wrapper around pci_alloc_consistent() */
@@ -870,6 +875,15 @@
 #define	pci_pool_alloc(pool, flags, handle) dma_pool_alloc(pool, flags, handle)
 #define	pci_pool_free(pool, vaddr, addr) dma_pool_free(pool, vaddr, addr)
 
+enum pci_dma_burst_strategy {
+	PCI_DMA_BURST_INFINITY,	/* make bursts as large as possible,
+				   strategy_parameter is N/A */
+	PCI_DMA_BURST_BOUNDARY, /* disconnect at every strategy_parameter
+				   byte boundaries */
+	PCI_DMA_BURST_MULTIPLE, /* disconnect at some multiple of
+				   strategy_parameter byte boundaries */
+};
+
 #if defined(CONFIG_ISA) || defined(CONFIG_EISA)
 extern struct pci_dev *isa_bridge;
 #endif
@@ -972,6 +986,8 @@
 }
 #endif
 
+#define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0)
+
 #endif /* !CONFIG_PCI */
 
 /* these helpers provide future and backwards compatibility
@@ -1016,6 +1032,20 @@
 #define pci_pretty_name(dev) ""
 #endif
 
+
+/* Some archs don't want to expose struct resource to userland as-is
+ * in sysfs and /proc
+ */
+#ifndef HAVE_ARCH_PCI_RESOURCE_TO_USER
+static inline void pci_resource_to_user(const struct pci_dev *dev, int bar,
+                const struct resource *rsrc, u64 *start, u64 *end)
+{
+	*start = rsrc->start;
+	*end = rsrc->end;
+}
+#endif /* HAVE_ARCH_PCI_RESOURCE_TO_USER */
+
+
 /*
  *  The world is not perfect and supplies us with broken PCI devices.
  *  For at least a part of these bugs we need a work-around, so both
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 1e0bc6a..27348c2 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -62,6 +62,8 @@
 
 #define PCI_BASE_CLASS_SYSTEM		0x08
 #define PCI_CLASS_SYSTEM_PIC		0x0800
+#define PCI_CLASS_SYSTEM_PIC_IOAPIC	0x080010
+#define PCI_CLASS_SYSTEM_PIC_IOXAPIC	0x080020
 #define PCI_CLASS_SYSTEM_DMA		0x0801
 #define PCI_CLASS_SYSTEM_TIMER		0x0802
 #define PCI_CLASS_SYSTEM_RTC		0x0803
@@ -1236,6 +1238,7 @@
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE	0x0265
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA	0x0266
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2	0x0267
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE	0x036E
 #define PCI_DEVICE_ID_NVIDIA_NVENET_12		0x0268
 #define PCI_DEVICE_ID_NVIDIA_NVENET_13		0x0269
 #define PCI_DEVICE_ID_NVIDIA_MCP51_AUDIO	0x026B
diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h
index 25d2d67..bd2c5a2 100644
--- a/include/linux/pkt_cls.h
+++ b/include/linux/pkt_cls.h
@@ -276,6 +276,7 @@
 	__u8	protocol;
 	__u8	tunnelid;
 	__u8	tunnelhdr;
+	__u8	pad;
 };
 
 /* ROUTE filter */
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index 1d9da36..60ffcb9 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -221,9 +221,11 @@
 /* gred setup */
 struct tc_gred_sopt
 {
-       __u32           DPs;
-       __u32           def_DP;
-       __u8            grio;
+       __u32		DPs;
+       __u32		def_DP;
+       __u8		grio;
+       __u8		pad1;
+       __u16		pad2;
 };
 
 /* HTB section */
@@ -351,6 +353,7 @@
 #define	TC_CBQ_OVL_DROP		3
 #define	TC_CBQ_OVL_RCLASSIC	4
 	unsigned char	priority2;
+	__u16		pad;
 	__u32		penalty;
 };
 
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index d021888..657c05a 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -363,6 +363,8 @@
 struct rta_session
 {
 	__u8	proto;
+	__u8	pad1;
+	__u16	pad2;
 
 	union {
 		struct {
@@ -635,10 +637,13 @@
 struct prefixmsg
 {
 	unsigned char	prefix_family;
+	unsigned char	prefix_pad1;
+	unsigned short	prefix_pad2;
 	int		prefix_ifindex;
 	unsigned char	prefix_type;
 	unsigned char	prefix_len;
 	unsigned char	prefix_flags;
+	unsigned char	prefix_pad3;
 };
 
 enum 
@@ -898,7 +903,9 @@
 	memcpy(skb_put(skb, attrlen), data, attrlen); })
 
 #define RTA_PUT_NOHDR(skb, attrlen, data) \
-	RTA_APPEND(skb, RTA_ALIGN(attrlen), data)
+({	RTA_APPEND(skb, RTA_ALIGN(attrlen), data); \
+	memset(skb->tail - (RTA_ALIGN(attrlen) - attrlen), 0, \
+	       RTA_ALIGN(attrlen) - attrlen); })
 
 #define RTA_PUT_U8(skb, attrtype, value) \
 ({	u8 _tmp = (value); \
@@ -978,6 +985,7 @@
 	rta = (struct rtattr*)skb_put(skb, RTA_ALIGN(size));
 	rta->rta_type = attrtype;
 	rta->rta_len = size;
+	memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size);
 	return rta;
 }
 
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 416a2e4..14b9504 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -183,7 +183,6 @@
  *	@priority: Packet queueing priority
  *	@users: User count - see {datagram,tcp}.c
  *	@protocol: Packet protocol from driver
- *	@security: Security level of packet
  *	@truesize: Buffer size 
  *	@head: Head of buffer
  *	@data: Data head pointer
@@ -249,18 +248,18 @@
 				data_len,
 				mac_len,
 				csum;
-	unsigned char		local_df,
-				cloned:1,
-				nohdr:1,
-				pkt_type,
-				ip_summed;
 	__u32			priority;
-	unsigned short		protocol,
-				security;
+	__u8			local_df:1,
+				cloned:1,
+				ip_summed:2,
+				nohdr:1;
+				/* 3 bits spare */
+	__u8			pkt_type;
+	__u16			protocol;
 
 	void			(*destructor)(struct sk_buff *skb);
 #ifdef CONFIG_NETFILTER
-        unsigned long		nfmark;
+	unsigned long		nfmark;
 	__u32			nfcache;
 	__u32			nfctinfo;
 	struct nf_conntrack	*nfct;
@@ -1211,7 +1210,7 @@
 {
 	int hlen = skb_headlen(skb);
 
-	if (offset + len <= hlen)
+	if (hlen - offset >= len)
 		return skb->data + offset;
 
 	if (skb_copy_bits(skb, offset, buffer, len) < 0)
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index ebfe125..5b5f434 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -641,6 +641,7 @@
 	NET_SCTP_ADDIP_ENABLE		 = 13,
 	NET_SCTP_PRSCTP_ENABLE		 = 14,
 	NET_SCTP_SNDBUF_POLICY		 = 15,
+	NET_SCTP_SACK_TIMEOUT		 = 16,
 };
 
 /* /proc/sys/net/bridge */
diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/linux/tc_ematch/tc_em_meta.h
index a6b2cc5..bcb762d 100644
--- a/include/linux/tc_ematch/tc_em_meta.h
+++ b/include/linux/tc_ematch/tc_em_meta.h
@@ -45,7 +45,7 @@
 	TCF_META_ID_REALDEV,
 	TCF_META_ID_PRIORITY,
 	TCF_META_ID_PROTOCOL,
-	TCF_META_ID_SECURITY,
+	TCF_META_ID_SECURITY, /* obsolete */
 	TCF_META_ID_PKTTYPE,
 	TCF_META_ID_PKTLEN,
 	TCF_META_ID_DATALEN,
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index dfd93d0..e4fd82e 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -286,7 +286,7 @@
 	__u32	max_window;	/* Maximal window ever seen from peer	*/
 	__u32	pmtu_cookie;	/* Last pmtu seen by socket		*/
 	__u32	mss_cache;	/* Cached effective mss, not including SACKS */
-	__u16	mss_cache_std;	/* Like mss_cache, but without TSO */
+	__u16	xmit_size_goal;	/* Goal for segmenting output packets	*/
 	__u16	ext_header_len;	/* Network protocol overhead (IP/IPv6 options) */
 	__u8	ca_state;	/* State of fast-retransmit machine 	*/
 	__u8	retransmits;	/* Number of unrecovered RTO timeouts.	*/
diff --git a/include/linux/usb_ch9.h b/include/linux/usb_ch9.h
index 39e7ff4..ee21e6b 100644
--- a/include/linux/usb_ch9.h
+++ b/include/linux/usb_ch9.h
@@ -19,7 +19,7 @@
 #ifndef __LINUX_USB_CH9_H
 #define __LINUX_USB_CH9_H
 
-#include <asm/types.h>		/* __u8 etc */
+#include <linux/types.h>	/* __u8 etc */
 
 /*-------------------------------------------------------------------------*/
 
@@ -294,8 +294,8 @@
 	__le16 wMaxPacketSize;
 	__u8  bInterval;
 
-	// NOTE:  these two are _only_ in audio endpoints.
-	// use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof.
+	/* NOTE:  these two are _only_ in audio endpoints. */
+	/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
 	__u8  bRefresh;
 	__u8  bSynchAddress;
 } __attribute__ ((packed));
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 4e0edce..acbfc52 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -221,6 +221,8 @@
 /*  Vendor-specific formats   */
 #define V4L2_PIX_FMT_WNVA     v4l2_fourcc('W','N','V','A') /* Winnov hw compress */
 #define V4L2_PIX_FMT_SN9C10X  v4l2_fourcc('S','9','1','0') /* SN9C10x compression */
+#define V4L2_PIX_FMT_PWC1     v4l2_fourcc('P','W','C','1') /* pwc older webcam */
+#define V4L2_PIX_FMT_PWC2     v4l2_fourcc('P','W','C','2') /* pwc newer webcam */
 
 /*
  *	F O R M A T   E N U M E R A T I O N
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index d5c3fe1..542dbae 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -85,7 +85,7 @@
 /*
  * mm/page-writeback.c
  */
-int wakeup_bdflush(long nr_pages);
+int wakeup_pdflush(long nr_pages);
 void laptop_io_completion(void);
 void laptop_sync_completion(void);
 void throttle_vm_writeout(void);
diff --git a/include/linux/xattr_acl.h b/include/linux/xattr_acl.h
deleted file mode 100644
index 7a1f9b9..0000000
--- a/include/linux/xattr_acl.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-  File: linux/xattr_acl.h
-
-  (extended attribute representation of access control lists)
-
-  (C) 2000 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-*/
-
-#ifndef _LINUX_XATTR_ACL_H
-#define _LINUX_XATTR_ACL_H
-
-#include <linux/posix_acl.h>
-
-#define XATTR_NAME_ACL_ACCESS	"system.posix_acl_access"
-#define XATTR_NAME_ACL_DEFAULT	"system.posix_acl_default"
-
-#define XATTR_ACL_VERSION	0x0002
-
-typedef struct {
-	__u16		e_tag;
-	__u16		e_perm;
-	__u32		e_id;
-} xattr_acl_entry;
-
-typedef struct {
-	__u32		a_version;
-	xattr_acl_entry	a_entries[0];
-} xattr_acl_header;
-
-static inline size_t xattr_acl_size(int count)
-{
-	return sizeof(xattr_acl_header) + count * sizeof(xattr_acl_entry);
-}
-
-static inline int xattr_acl_count(size_t size)
-{
-	if (size < sizeof(xattr_acl_header))
-		return -1;
-	size -= sizeof(xattr_acl_header);
-	if (size % sizeof(xattr_acl_entry))
-		return -1;
-	return size / sizeof(xattr_acl_entry);
-}
-
-struct posix_acl * posix_acl_from_xattr(const void *value, size_t size);
-int posix_acl_to_xattr(const struct posix_acl *acl, void *buffer, size_t size);
-
-
-
-#endif /* _LINUX_XATTR_ACL_H */
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 2dd8310..4794c56 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -1,5 +1,6 @@
 
-/*
+/* $Id: tuner.h,v 1.33 2005/06/21 14:58:08 mkrufky Exp $
+ *
     tuner.h - definition for different tuners
 
     Copyright (C) 1997 Markus Schroeder (schroedm@uni-duesseldorf.de)
@@ -23,6 +24,8 @@
 #ifndef _TUNER_H
 #define _TUNER_H
 
+#include <linux/videodev2.h>
+
 #include "id.h"
 
 #define ADDR_UNSET (255)
@@ -88,7 +91,7 @@
 #define TUNER_LG_NTSC_TAPE       47
 
 #define TUNER_TNF_8831BGFF       48
-#define TUNER_MICROTUNE_4042FI5  49	/* FusionHDTV 3 Gold - 4042 FI5 (3X 8147) */
+#define TUNER_MICROTUNE_4042FI5  49	/* DViCO FusionHDTV 3 Gold-Q - 4042 FI5 (3X 8147) */
 #define TUNER_TCL_2002N          50
 #define TUNER_PHILIPS_FM1256_IH3   51
 
@@ -98,18 +101,18 @@
 #define TUNER_LG_PAL_TAPE        55    /* Hauppauge PVR-150 PAL */
 
 #define TUNER_PHILIPS_FQ1216AME_MK4 56 /* Hauppauge PVR-150 PAL */
-#define TUNER_PHILIPS_FQ1236A_MK4 57   /* Hauppauge PVR-500MCE NTSC */
+#define TUNER_PHILIPS_FQ1236A_MK4   57   /* Hauppauge PVR-500MCE NTSC */
 
 #define TUNER_YMEC_TVF_8531MF 58
 #define TUNER_YMEC_TVF_5533MF 59	/* Pixelview Pro Ultra NTSC */
-#define TUNER_THOMSON_DTT7611 60
+#define TUNER_THOMSON_DTT7611 60	/* DViCO FusionHDTV 3 Gold-T */
 #define TUNER_TENA_9533_DI    61
+
 #define TUNER_TEA5767         62	/* Only FM Radio Tuner */
+#define TUNER_PHILIPS_FMD1216ME_MK3 63
 
 #define TEA5767_TUNER_NAME "Philips TEA5767HN FM Radio"
 
-#define TUNER_THOMSON_DTT7611    60
-
 #define NOTUNER 0
 #define PAL     1	/* PAL_BG */
 #define PAL_I   2
@@ -194,11 +197,15 @@
 	unsigned char i2c_easy_mode[2];
 	unsigned char i2c_set_freq[8];
 
+	/* used to keep track of audmode */
+	unsigned int audmode;
+
 	/* function ptrs */
 	void (*tv_freq)(struct i2c_client *c, unsigned int freq);
 	void (*radio_freq)(struct i2c_client *c, unsigned int freq);
 	int  (*has_signal)(struct i2c_client *c);
 	int  (*is_stereo)(struct i2c_client *c);
+	int  (*set_tuner)(struct i2c_client *c, struct v4l2_tuner *v);
 };
 
 extern unsigned int tuner_debug;
@@ -206,6 +213,7 @@
 
 extern int microtune_init(struct i2c_client *c);
 extern int tda8290_init(struct i2c_client *c);
+extern int tea5767_tuner_init(struct i2c_client *c);
 extern int default_tuner_init(struct i2c_client *c);
 
 #define tuner_warn(fmt, arg...) \
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
index 7fe57f9..db09580 100644
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -94,6 +94,8 @@
 	u16 length;
 } __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
@@ -300,23 +302,6 @@
 #define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
 
 
-/* Information Element IDs */
-#define WLAN_EID_SSID 0
-#define WLAN_EID_SUPP_RATES 1
-#define WLAN_EID_FH_PARAMS 2
-#define WLAN_EID_DS_PARAMS 3
-#define WLAN_EID_CF_PARAMS 4
-#define WLAN_EID_TIM 5
-#define WLAN_EID_IBSS_PARAMS 6
-#define WLAN_EID_CHALLENGE 16
-#define WLAN_EID_RSN 48
-#define WLAN_EID_GENERIC 221
-
-#define IEEE80211_MGMT_HDR_LEN 24
-#define IEEE80211_DATA_HDR3_LEN 24
-#define IEEE80211_DATA_HDR4_LEN 30
-
-
 #define IEEE80211_STATMASK_SIGNAL (1<<0)
 #define IEEE80211_STATMASK_RSSI (1<<1)
 #define IEEE80211_STATMASK_NOISE (1<<2)
@@ -441,6 +426,10 @@
 
 struct ieee80211_device;
 
+#if 0 /* for later */
+#include "ieee80211_crypt.h"
+#endif
+
 #define SEC_KEY_1         (1<<0)
 #define SEC_KEY_2         (1<<1)
 #define SEC_KEY_3         (1<<2)
@@ -488,15 +477,6 @@
 
 */
 
-struct ieee80211_header_data {
-	u16 frame_ctl;
-	u16 duration_id;
-	u8 addr1[6];
-	u8 addr2[6];
-	u8 addr3[6];
-	u16 seq_ctrl;
-};
-
 #define BEACON_PROBE_SSID_ID_POSITION 12
 
 /* Management Frame Information Element Types */
@@ -541,7 +521,7 @@
 */
 
 struct ieee80211_authentication {
-	struct ieee80211_header_data header;
+	struct ieee80211_hdr_3addr header;
 	u16 algorithm;
 	u16 transaction;
 	u16 status;
@@ -550,7 +530,7 @@
 
 
 struct ieee80211_probe_response {
-	struct ieee80211_header_data header;
+	struct ieee80211_hdr_3addr header;
 	u32 time_stamp[2];
 	u16 beacon_interval;
 	u16 capability;
@@ -648,12 +628,6 @@
 #define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
 
 
-extern inline int is_broadcast_ether_addr(const u8 *addr)
-{
-	return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&   \
-		(addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
-}
-
 #define CFG_IEEE80211_RESERVE_FCS (1<<0)
 #define CFG_IEEE80211_COMPUTE_FCS (1<<1)
 
@@ -787,21 +761,21 @@
 
 extern inline int ieee80211_get_hdrlen(u16 fc)
 {
-	int hdrlen = 24;
+	int hdrlen = IEEE80211_3ADDR_LEN;
 
 	switch (WLAN_FC_GET_TYPE(fc)) {
 	case IEEE80211_FTYPE_DATA:
 		if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
-			hdrlen = 30; /* Addr4 */
+			hdrlen = IEEE80211_4ADDR_LEN;
 		break;
 	case IEEE80211_FTYPE_CTL:
 		switch (WLAN_FC_GET_STYPE(fc)) {
 		case IEEE80211_STYPE_CTS:
 		case IEEE80211_STYPE_ACK:
-			hdrlen = 10;
+			hdrlen = IEEE80211_1ADDR_LEN;
 			break;
 		default:
-			hdrlen = 16;
+			hdrlen = IEEE80211_2ADDR_LEN;
 			break;
 		}
 		break;
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 771b47e..6932446 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -183,7 +183,6 @@
 	struct ipv6_opt_hdr	*hopopt;
 	struct ipv6_opt_hdr	*dst0opt;
 	struct ipv6_rt_hdr	*srcrt;	/* Routing Header */
-	struct ipv6_opt_hdr	*auth;
 	struct ipv6_opt_hdr	*dst1opt;
 
 	/* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index fcb05a3..6492e73 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -13,13 +13,12 @@
 
 extern rwlock_t qdisc_tree_lock;
 
-#define	QDISC_ALIGN		32
-#define	QDISC_ALIGN_CONST	(QDISC_ALIGN - 1)
+#define QDISC_ALIGNTO		32
+#define QDISC_ALIGN(len)	(((len) + QDISC_ALIGNTO-1) & ~(QDISC_ALIGNTO-1))
 
 static inline void *qdisc_priv(struct Qdisc *q)
 {
-	return (char *)q + ((sizeof(struct Qdisc) + QDISC_ALIGN_CONST)
-			      & ~QDISC_ALIGN_CONST);
+	return (char *) q + QDISC_ALIGN(sizeof(struct Qdisc));
 }
 
 /* 
@@ -207,8 +206,6 @@
 
 #endif /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */
 
-extern struct Qdisc noop_qdisc;
-extern struct Qdisc_ops noop_qdisc_ops;
 extern struct Qdisc_ops pfifo_qdisc_ops;
 extern struct Qdisc_ops bfifo_qdisc_ops;
 
@@ -216,14 +213,6 @@
 extern int unregister_qdisc(struct Qdisc_ops *qops);
 extern struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle);
 extern struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle);
-extern void dev_init_scheduler(struct net_device *dev);
-extern void dev_shutdown(struct net_device *dev);
-extern void dev_activate(struct net_device *dev);
-extern void dev_deactivate(struct net_device *dev);
-extern void qdisc_reset(struct Qdisc *qdisc);
-extern void qdisc_destroy(struct Qdisc *qdisc);
-extern struct Qdisc * qdisc_create_dflt(struct net_device *dev,
-	struct Qdisc_ops *ops);
 extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
 		struct rtattr *tab);
 extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 7b97405..7b6ec99 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -164,6 +164,19 @@
 #define tcf_tree_lock(tp)	qdisc_lock_tree((tp)->q->dev)
 #define tcf_tree_unlock(tp)	qdisc_unlock_tree((tp)->q->dev)
 
+extern struct Qdisc noop_qdisc;
+extern struct Qdisc_ops noop_qdisc_ops;
+
+extern void dev_init_scheduler(struct net_device *dev);
+extern void dev_shutdown(struct net_device *dev);
+extern void dev_activate(struct net_device *dev);
+extern void dev_deactivate(struct net_device *dev);
+extern void qdisc_reset(struct Qdisc *qdisc);
+extern void qdisc_destroy(struct Qdisc *qdisc);
+extern struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops);
+extern struct Qdisc *qdisc_create_dflt(struct net_device *dev,
+				       struct Qdisc_ops *ops);
+
 static inline void
 tcf_destroy(struct tcf_proto *tp)
 {
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
index 4868c7f..5999e56 100644
--- a/include/net/sctp/constants.h
+++ b/include/net/sctp/constants.h
@@ -263,23 +263,11 @@
 enum { SCTP_MAX_DUP_TSNS = 16 };
 enum { SCTP_MAX_GABS = 16 };
 
-/* Here we define the default timers.  */
+/* Heartbeat interval - 30 secs */
+#define SCTP_DEFAULT_TIMEOUT_HEARTBEAT	(30 * HZ)
 
-/* cookie timer def = ? seconds */
-#define SCTP_DEFAULT_TIMEOUT_T1_COOKIE	(3 * HZ)
-
-/* init timer def = 3 seconds  */
-#define SCTP_DEFAULT_TIMEOUT_T1_INIT	(3 * HZ)
-
-/* shutdown timer def = 300 ms */
-#define SCTP_DEFAULT_TIMEOUT_T2_SHUTDOWN ((300 * HZ) / 1000)
-
-/* 0 seconds + RTO */
-#define SCTP_DEFAULT_TIMEOUT_HEARTBEAT	(10 * HZ)
-
-/* recv timer def = 200ms (in usec) */
+/* Delayed sack timer - 200ms */
 #define SCTP_DEFAULT_TIMEOUT_SACK	((200 * HZ) / 1000)
-#define SCTP_DEFAULT_TIMEOUT_SACK_MAX	((500 * HZ) / 1000) /* 500 ms */
 
 /* RTO.Initial              - 3  seconds
  * RTO.Min                  - 1  second
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index dfad4d3..47727c7 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -161,6 +161,9 @@
 	 */
 	int sndbuf_policy;
 
+	/* Delayed SACK timeout  200ms default*/
+	int sack_timeout;
+
 	/* HB.interval		    - 30 seconds  */
 	int hb_interval;
 
@@ -217,6 +220,7 @@
 #define sctp_sndbuf_policy	 	(sctp_globals.sndbuf_policy)
 #define sctp_max_retrans_path		(sctp_globals.max_retrans_path)
 #define sctp_max_retrans_init		(sctp_globals.max_retrans_init)
+#define sctp_sack_timeout		(sctp_globals.sack_timeout)
 #define sctp_hb_interval		(sctp_globals.hb_interval)
 #define sctp_max_instreams		(sctp_globals.max_instreams)
 #define sctp_max_outstreams		(sctp_globals.max_outstreams)
diff --git a/include/net/slhc_vj.h b/include/net/slhc_vj.h
index 0b2c278..8716d59 100644
--- a/include/net/slhc_vj.h
+++ b/include/net/slhc_vj.h
@@ -170,19 +170,14 @@
 };
 #define NULLSLCOMPR	(struct slcompress *)0
 
-#define __ARGS(x) x
-
 /* In slhc.c: */
-struct slcompress *slhc_init __ARGS((int rslots, int tslots));
-void slhc_free __ARGS((struct slcompress *comp));
+struct slcompress *slhc_init(int rslots, int tslots);
+void slhc_free(struct slcompress *comp);
 
-int slhc_compress __ARGS((struct slcompress *comp, unsigned char *icp,
-			  int isize, unsigned char *ocp, unsigned char **cpp,
-			  int compress_cid));
-int slhc_uncompress __ARGS((struct slcompress *comp, unsigned char *icp,
-			    int isize));
-int slhc_remember __ARGS((struct slcompress *comp, unsigned char *icp,
-			  int isize));
-int slhc_toss __ARGS((struct slcompress *comp));
+int slhc_compress(struct slcompress *comp, unsigned char *icp, int isize,
+		  unsigned char *ocp, unsigned char **cpp, int compress_cid);
+int slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize);
+int slhc_remember(struct slcompress *comp, unsigned char *icp, int isize);
+int slhc_toss(struct slcompress *comp);
 
 #endif	/* _SLHC_H */
diff --git a/include/net/sock.h b/include/net/sock.h
index e593af5..7b76f89 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1134,13 +1134,16 @@
 static inline struct sk_buff *sk_stream_alloc_pskb(struct sock *sk,
 						   int size, int mem, int gfp)
 {
-	struct sk_buff *skb = alloc_skb(size + sk->sk_prot->max_header, gfp);
+	struct sk_buff *skb;
+	int hdr_len;
 
+	hdr_len = SKB_DATA_ALIGN(sk->sk_prot->max_header);
+	skb = alloc_skb(size + hdr_len, gfp);
 	if (skb) {
 		skb->truesize += mem;
 		if (sk->sk_forward_alloc >= (int)skb->truesize ||
 		    sk_stream_mem_schedule(sk, skb->truesize, 0)) {
-			skb_reserve(skb, sk->sk_prot->max_header);
+			skb_reserve(skb, hdr_len);
 			return skb;
 		}
 		__kfree_skb(skb);
diff --git a/include/net/tcp.h b/include/net/tcp.h
index ec9e20c..a166918 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -721,11 +721,16 @@
 	return tp->ack.pending&TCP_ACK_SCHED;
 }
 
-static __inline__ void tcp_dec_quickack_mode(struct tcp_sock *tp)
+static __inline__ void tcp_dec_quickack_mode(struct tcp_sock *tp, unsigned int pkts)
 {
-	if (tp->ack.quick && --tp->ack.quick == 0) {
-		/* Leaving quickack mode we deflate ATO. */
-		tp->ack.ato = TCP_ATO_MIN;
+	if (tp->ack.quick) {
+		if (pkts >= tp->ack.quick) {
+			tp->ack.quick = 0;
+
+			/* Leaving quickack mode we deflate ATO. */
+			tp->ack.ato = TCP_ATO_MIN;
+		} else
+			tp->ack.quick -= pkts;
 	}
 }
 
@@ -843,7 +848,9 @@
 
 /* tcp_output.c */
 
-extern int tcp_write_xmit(struct sock *, int nonagle);
+extern void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp,
+				      unsigned int cur_mss, int nonagle);
+extern int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp);
 extern int tcp_retransmit_skb(struct sock *, struct sk_buff *);
 extern void tcp_xmit_retransmit_queue(struct sock *);
 extern void tcp_simple_retransmit(struct sock *);
@@ -855,10 +862,13 @@
 extern void tcp_send_fin(struct sock *sk);
 extern void tcp_send_active_reset(struct sock *sk, int priority);
 extern int  tcp_send_synack(struct sock *);
-extern void tcp_push_one(struct sock *, unsigned mss_now);
+extern void tcp_push_one(struct sock *, unsigned int mss_now);
 extern void tcp_send_ack(struct sock *sk);
 extern void tcp_send_delayed_ack(struct sock *sk);
 
+/* tcp_input.c */
+extern void tcp_cwnd_application_limited(struct sock *sk);
+
 /* tcp_timer.c */
 extern void tcp_init_xmit_timers(struct sock *);
 extern void tcp_clear_xmit_timers(struct sock *);
@@ -958,7 +968,7 @@
 static inline void tcp_initialize_rcv_mss(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	unsigned int hint = min(tp->advmss, tp->mss_cache_std);
+	unsigned int hint = min_t(unsigned int, tp->advmss, tp->mss_cache);
 
 	hint = min(hint, tp->rcv_wnd/2);
 	hint = min(hint, TCP_MIN_RCVMSS);
@@ -1225,28 +1235,6 @@
 	tp->left_out = tp->sacked_out + tp->lost_out;
 }
 
-extern void tcp_cwnd_application_limited(struct sock *sk);
-
-/* Congestion window validation. (RFC2861) */
-
-static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp)
-{
-	__u32 packets_out = tp->packets_out;
-
-	if (packets_out >= tp->snd_cwnd) {
-		/* Network is feed fully. */
-		tp->snd_cwnd_used = 0;
-		tp->snd_cwnd_stamp = tcp_time_stamp;
-	} else {
-		/* Network starves. */
-		if (tp->packets_out > tp->snd_cwnd_used)
-			tp->snd_cwnd_used = tp->packets_out;
-
-		if ((s32)(tcp_time_stamp - tp->snd_cwnd_stamp) >= tp->rto)
-			tcp_cwnd_application_limited(sk);
-	}
-}
-
 /* Set slow start threshould and cwnd not falling to slow start */
 static inline void __tcp_enter_cwr(struct tcp_sock *tp)
 {
@@ -1279,12 +1267,6 @@
 	return 3;
 }
 
-static __inline__ int tcp_minshall_check(const struct tcp_sock *tp)
-{
-	return after(tp->snd_sml,tp->snd_una) &&
-		!after(tp->snd_sml, tp->snd_nxt);
-}
-
 static __inline__ void tcp_minshall_update(struct tcp_sock *tp, int mss, 
 					   const struct sk_buff *skb)
 {
@@ -1292,122 +1274,18 @@
 		tp->snd_sml = TCP_SKB_CB(skb)->end_seq;
 }
 
-/* Return 0, if packet can be sent now without violation Nagle's rules:
-   1. It is full sized.
-   2. Or it contains FIN.
-   3. Or TCP_NODELAY was set.
-   4. Or TCP_CORK is not set, and all sent packets are ACKed.
-      With Minshall's modification: all sent small packets are ACKed.
- */
-
-static __inline__ int
-tcp_nagle_check(const struct tcp_sock *tp, const struct sk_buff *skb, 
-		unsigned mss_now, int nonagle)
-{
-	return (skb->len < mss_now &&
-		!(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) &&
-		((nonagle&TCP_NAGLE_CORK) ||
-		 (!nonagle &&
-		  tp->packets_out &&
-		  tcp_minshall_check(tp))));
-}
-
-extern void tcp_set_skb_tso_segs(struct sock *, struct sk_buff *);
-
-/* This checks if the data bearing packet SKB (usually sk->sk_send_head)
- * should be put on the wire right now.
- */
-static __inline__ int tcp_snd_test(struct sock *sk,
-				   struct sk_buff *skb,
-				   unsigned cur_mss, int nonagle)
-{
-	struct tcp_sock *tp = tcp_sk(sk);
-	int pkts = tcp_skb_pcount(skb);
-
-	if (!pkts) {
-		tcp_set_skb_tso_segs(sk, skb);
-		pkts = tcp_skb_pcount(skb);
-	}
-
-	/*	RFC 1122 - section 4.2.3.4
-	 *
-	 *	We must queue if
-	 *
-	 *	a) The right edge of this frame exceeds the window
-	 *	b) There are packets in flight and we have a small segment
-	 *	   [SWS avoidance and Nagle algorithm]
-	 *	   (part of SWS is done on packetization)
-	 *	   Minshall version sounds: there are no _small_
-	 *	   segments in flight. (tcp_nagle_check)
-	 *	c) We have too many packets 'in flight'
-	 *
-	 * 	Don't use the nagle rule for urgent data (or
-	 *	for the final FIN -DaveM).
-	 *
-	 *	Also, Nagle rule does not apply to frames, which
-	 *	sit in the middle of queue (they have no chances
-	 *	to get new data) and if room at tail of skb is
-	 *	not enough to save something seriously (<32 for now).
-	 */
-
-	/* Don't be strict about the congestion window for the
-	 * final FIN frame.  -DaveM
-	 */
-	return (((nonagle&TCP_NAGLE_PUSH) || tp->urg_mode
-		 || !tcp_nagle_check(tp, skb, cur_mss, nonagle)) &&
-		(((tcp_packets_in_flight(tp) + (pkts-1)) < tp->snd_cwnd) ||
-		 (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) &&
-		!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd));
-}
-
 static __inline__ void tcp_check_probe_timer(struct sock *sk, struct tcp_sock *tp)
 {
 	if (!tp->packets_out && !tp->pending)
 		tcp_reset_xmit_timer(sk, TCP_TIME_PROBE0, tp->rto);
 }
 
-static __inline__ int tcp_skb_is_last(const struct sock *sk, 
-				      const struct sk_buff *skb)
-{
-	return skb->next == (struct sk_buff *)&sk->sk_write_queue;
-}
-
-/* Push out any pending frames which were held back due to
- * TCP_CORK or attempt at coalescing tiny packets.
- * The socket must be locked by the caller.
- */
-static __inline__ void __tcp_push_pending_frames(struct sock *sk,
-						 struct tcp_sock *tp,
-						 unsigned cur_mss,
-						 int nonagle)
-{
-	struct sk_buff *skb = sk->sk_send_head;
-
-	if (skb) {
-		if (!tcp_skb_is_last(sk, skb))
-			nonagle = TCP_NAGLE_PUSH;
-		if (!tcp_snd_test(sk, skb, cur_mss, nonagle) ||
-		    tcp_write_xmit(sk, nonagle))
-			tcp_check_probe_timer(sk, tp);
-	}
-	tcp_cwnd_validate(sk, tp);
-}
-
 static __inline__ void tcp_push_pending_frames(struct sock *sk,
 					       struct tcp_sock *tp)
 {
 	__tcp_push_pending_frames(sk, tp, tcp_current_mss(sk, 1), tp->nonagle);
 }
 
-static __inline__ int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp)
-{
-	struct sk_buff *skb = sk->sk_send_head;
-
-	return (skb &&
-		tcp_snd_test(sk, skb, tcp_current_mss(sk, 1),
-			     tcp_skb_is_last(sk, skb) ? TCP_NAGLE_PUSH : tp->nonagle));
-}
-
 static __inline__ void tcp_init_wl(struct tcp_sock *tp, u32 ack, u32 seq)
 {
 	tp->snd_wl1 = seq;
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index 4def882..a05cabd 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -86,7 +86,10 @@
 		printk("okay\n");
 	else {
 		int fd = sys_open("/dev/root.old", O_RDWR, 0);
-		printk("failed\n");
+		if (error == -ENOENT)
+			printk("/initrd does not exist. Ignored.\n");
+		else
+			printk("failed\n");
 		printk(KERN_NOTICE "Unmounting old root\n");
 		sys_umount("/old", MNT_DETACH);
 		printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
diff --git a/init/main.c b/init/main.c
index d324801..b5e421e 100644
--- a/init/main.c
+++ b/init/main.c
@@ -383,6 +383,13 @@
 	numa_default_policy();
 	unlock_kernel();
 	preempt_enable_no_resched();
+
+	/*
+	 * The boot idle thread must execute schedule()
+	 * at least one to get things moving:
+	 */
+	schedule();
+
 	cpu_idle();
 } 
 
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c
index 98d62d8..3467097 100644
--- a/kernel/irq/autoprobe.c
+++ b/kernel/irq/autoprobe.c
@@ -9,6 +9,7 @@
 #include <linux/irq.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
+#include <linux/delay.h>
 
 /*
  * Autodetection depends on the fact that any interrupt that
@@ -26,7 +27,7 @@
  */
 unsigned long probe_irq_on(void)
 {
-	unsigned long val, delay;
+	unsigned long val;
 	irq_desc_t *desc;
 	unsigned int i;
 
@@ -45,8 +46,7 @@
 	}
 
 	/* Wait for longstanding interrupts to trigger. */
-	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
-		/* about 20ms delay */ barrier();
+	msleep(20);
 
 	/*
 	 * enable any unassigned irqs
@@ -68,8 +68,7 @@
 	/*
 	 * Wait for spurious interrupts to trigger
 	 */
-	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
-		/* about 100ms delay */ barrier();
+	msleep(100);
 
 	/*
 	 * Now filter out any obviously spurious interrupts
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 436c7d9..c29f83c 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -172,7 +172,7 @@
 
 		spin_lock(&desc->lock);
 		if (!noirqdebug)
-			note_interrupt(irq, desc, action_ret);
+			note_interrupt(irq, desc, action_ret, regs);
 		if (likely(!(desc->status & IRQ_PENDING)))
 			break;
 		desc->status &= ~IRQ_PENDING;
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index ba039e8..7df9abd 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -11,6 +11,83 @@
 #include <linux/kallsyms.h>
 #include <linux/interrupt.h>
 
+static int irqfixup;
+
+/*
+ * Recovery handler for misrouted interrupts.
+ */
+
+static int misrouted_irq(int irq, struct pt_regs *regs)
+{
+	int i;
+	irq_desc_t *desc;
+	int ok = 0;
+	int work = 0;	/* Did we do work for a real IRQ */
+
+	for(i = 1; i < NR_IRQS; i++) {
+		struct irqaction *action;
+
+		if (i == irq)	/* Already tried */
+			continue;
+		desc = &irq_desc[i];
+		spin_lock(&desc->lock);
+		action = desc->action;
+		/* Already running on another processor */
+		if (desc->status & IRQ_INPROGRESS) {
+			/*
+			 * Already running: If it is shared get the other
+			 * CPU to go looking for our mystery interrupt too
+			 */
+			if (desc->action && (desc->action->flags & SA_SHIRQ))
+				desc->status |= IRQ_PENDING;
+			spin_unlock(&desc->lock);
+			continue;
+		}
+		/* Honour the normal IRQ locking */
+		desc->status |= IRQ_INPROGRESS;
+		spin_unlock(&desc->lock);
+		while (action) {
+			/* Only shared IRQ handlers are safe to call */
+			if (action->flags & SA_SHIRQ) {
+				if (action->handler(i, action->dev_id, regs) ==
+						IRQ_HANDLED)
+					ok = 1;
+			}
+			action = action->next;
+		}
+		local_irq_disable();
+		/* Now clean up the flags */
+		spin_lock(&desc->lock);
+		action = desc->action;
+
+		/*
+		 * While we were looking for a fixup someone queued a real
+		 * IRQ clashing with our walk
+		 */
+
+		while ((desc->status & IRQ_PENDING) && action) {
+			/*
+			 * Perform real IRQ processing for the IRQ we deferred
+			 */
+			work = 1;
+			spin_unlock(&desc->lock);
+			handle_IRQ_event(i, regs, action);
+			spin_lock(&desc->lock);
+			desc->status &= ~IRQ_PENDING;
+		}
+		desc->status &= ~IRQ_INPROGRESS;
+		/*
+		 * If we did actual work for the real IRQ line we must let the
+		 * IRQ controller clean up too
+		 */
+		if(work)
+			desc->handler->end(i);
+		spin_unlock(&desc->lock);
+	}
+	/* So the caller can adjust the irq error counts */
+	return ok;
+}
+
 /*
  * If 99,900 of the previous 100,000 interrupts have not been handled
  * then assume that the IRQ is stuck in some manner. Drop a diagnostic
@@ -31,7 +108,8 @@
 		printk(KERN_ERR "irq event %d: bogus return value %x\n",
 				irq, action_ret);
 	} else {
-		printk(KERN_ERR "irq %d: nobody cared!\n", irq);
+		printk(KERN_ERR "irq %d: nobody cared (try booting with "
+				"the \"irqpoll\" option)\n", irq);
 	}
 	dump_stack();
 	printk(KERN_ERR "handlers:\n");
@@ -55,7 +133,8 @@
 	}
 }
 
-void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret)
+void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret,
+			struct pt_regs *regs)
 {
 	if (action_ret != IRQ_HANDLED) {
 		desc->irqs_unhandled++;
@@ -63,6 +142,15 @@
 			report_bad_irq(irq, desc, action_ret);
 	}
 
+	if (unlikely(irqfixup)) {
+		/* Don't punish working computers */
+		if ((irqfixup == 2 && irq == 0) || action_ret == IRQ_NONE) {
+			int ok = misrouted_irq(irq, regs);
+			if (action_ret == IRQ_NONE)
+				desc->irqs_unhandled -= ok;
+		}
+	}
+
 	desc->irq_count++;
 	if (desc->irq_count < 100000)
 		return;
@@ -94,3 +182,24 @@
 
 __setup("noirqdebug", noirqdebug_setup);
 
+static int __init irqfixup_setup(char *str)
+{
+	irqfixup = 1;
+	printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n");
+	printk(KERN_WARNING "This may impact system performance.\n");
+	return 1;
+}
+
+__setup("irqfixup", irqfixup_setup);
+
+static int __init irqpoll_setup(char *str)
+{
+	irqfixup = 2;
+	printk(KERN_WARNING "Misrouted IRQ fixup and polling support "
+				"enabled\n");
+	printk(KERN_WARNING "This may significantly impact system "
+				"performance\n");
+	return 1;
+}
+
+__setup("irqpoll", irqpoll_setup);
diff --git a/kernel/itimer.c b/kernel/itimer.c
index 1dc988e..a72cb0e 100644
--- a/kernel/itimer.c
+++ b/kernel/itimer.c
@@ -153,11 +153,15 @@
 
 	switch (which) {
 	case ITIMER_REAL:
+again:
 		spin_lock_irq(&tsk->sighand->siglock);
 		interval = tsk->signal->it_real_incr;
 		val = it_real_value(tsk->signal);
-		if (val)
-			del_timer_sync(&tsk->signal->real_timer);
+		/* We are sharing ->siglock with it_real_fn() */
+		if (try_to_del_timer_sync(&tsk->signal->real_timer) < 0) {
+			spin_unlock_irq(&tsk->sighand->siglock);
+			goto again;
+		}
 		tsk->signal->it_real_incr =
 			timeval_to_jiffies(&value->it_interval);
 		it_real_arm(tsk, timeval_to_jiffies(&value->it_value));
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 7843548..cdd4dcd 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -241,7 +241,7 @@
 
 static int kimage_crash_alloc(struct kimage **rimage, unsigned long entry,
 				unsigned long nr_segments,
-				struct kexec_segment *segments)
+				struct kexec_segment __user *segments)
 {
 	int result;
 	struct kimage *image;
@@ -650,7 +650,7 @@
 		}
 	}
 
-	return 0;
+	return NULL;
 }
 
 static struct page *kimage_alloc_page(struct kimage *image,
@@ -696,7 +696,7 @@
 		/* Allocate a page, if we run out of memory give up */
 		page = kimage_alloc_pages(gfp_mask, 0);
 		if (!page)
-			return 0;
+			return NULL;
 		/* If the page cannot be used file it away */
 		if (page_to_pfn(page) >
 				(KEXEC_SOURCE_MEMORY_LIMIT >> PAGE_SHIFT)) {
@@ -754,7 +754,7 @@
 	unsigned long maddr;
 	unsigned long ubytes, mbytes;
 	int result;
-	unsigned char *buf;
+	unsigned char __user *buf;
 
 	result = 0;
 	buf = segment->buf;
@@ -818,7 +818,7 @@
 	unsigned long maddr;
 	unsigned long ubytes, mbytes;
 	int result;
-	unsigned char *buf;
+	unsigned char __user *buf;
 
 	result = 0;
 	buf = segment->buf;
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 90c0e82..b023712 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -574,7 +574,7 @@
 		INIT_HLIST_HEAD(&kretprobe_inst_table[i]);
 	}
 
-	err = arch_init();
+	err = arch_init_kprobes();
 	if (!err)
 		err = register_die_notifier(&kprobe_exceptions_nb);
 
diff --git a/kernel/sched.c b/kernel/sched.c
index e2b0d3e..5f2182d 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4166,6 +4166,14 @@
 	read_unlock(&tasklist_lock);
 }
 
+/**
+ * init_idle - set up an idle thread for a given CPU
+ * @idle: task in question
+ * @cpu: cpu the idle task belongs to
+ *
+ * NOTE: this function does not set the idle thread's NEED_RESCHED
+ * flag, to make booting more robust.
+ */
 void __devinit init_idle(task_t *idle, int cpu)
 {
 	runqueue_t *rq = cpu_rq(cpu);
@@ -4183,7 +4191,6 @@
 #if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW)
 	idle->oncpu = 1;
 #endif
-	set_tsk_need_resched(idle);
 	spin_unlock_irqrestore(&rq->lock, flags);
 
 	/* Set the preempt count _outside_ the spinlocks! */
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 613b99a..a6329fa 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -354,7 +354,7 @@
  * the whole world.  Returns 0 if a pdflush thread was dispatched.  Returns
  * -1 if all pdflush threads were busy.
  */
-int wakeup_bdflush(long nr_pages)
+int wakeup_pdflush(long nr_pages)
 {
 	if (nr_pages == 0) {
 		struct writeback_state wbs;
diff --git a/mm/slab.c b/mm/slab.c
index 122d031..e57abd4 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -2372,6 +2372,9 @@
 	struct slab *slabp;
 	kmem_bufctl_t next;
 
+	if (nodeid == -1)
+		return kmem_cache_alloc(cachep, flags);
+
 	for (loop = 0;;loop++) {
 		struct list_head *q;
 
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 1fa312a..cfffe50 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -972,7 +972,7 @@
 		 * writeout.  So in laptop mode, write out the whole world.
 		 */
 		if (total_scanned > sc.swap_cluster_max + sc.swap_cluster_max/2) {
-			wakeup_bdflush(laptop_mode ? 0 : total_scanned);
+			wakeup_pdflush(laptop_mode ? 0 : total_scanned);
 			sc.may_writepage = 1;
 		}
 
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 03ae4ed..2d52fee 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -844,7 +844,7 @@
 		 * doesn't use the bridge parent of the indev by using
 		 * the BRNF_DONT_TAKE_PARENT mask. */
 		if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) {
-			nf_bridge->mask &= BRNF_DONT_TAKE_PARENT;
+			nf_bridge->mask |= BRNF_DONT_TAKE_PARENT;
 			nf_bridge->physindev = (struct net_device *)in;
 		}
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
index e4ae34b..662975b 100644
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -61,8 +61,6 @@
 {
 	struct ebt_log_info *info = (struct ebt_log_info *)data;
 	char level_string[4] = "< >";
-	union {struct iphdr iph; struct tcpudphdr ports;
-	       struct arphdr arph; struct arppayload arpp;} u;
 
 	level_string[1] = '0' + info->loglevel;
 	spin_lock_bh(&ebt_log_lock);
@@ -88,7 +86,7 @@
 		}
 		printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u,",
 		   NIPQUAD(ih->saddr), NIPQUAD(ih->daddr));
-		printk(" IP tos=0x%02X, IP proto=%d", u.iph.tos,
+		printk(" IP tos=0x%02X, IP proto=%d", ih->tos,
 		       ih->protocol);
 		if (ih->protocol == IPPROTO_TCP ||
 		    ih->protocol == IPPROTO_UDP) {
@@ -127,7 +125,7 @@
 		    ah->ar_pln == sizeof(uint32_t)) {
 			struct arppayload _arpp, *ap;
 
-			ap = skb_header_pointer(skb, sizeof(u.arph),
+			ap = skb_header_pointer(skb, sizeof(_arph),
 						sizeof(_arpp), &_arpp);
 			if (ap == NULL) {
 				printk(" INCOMPLETE ARP payload");
diff --git a/net/core/dev.c b/net/core/dev.c
index 7016e0c..7f5f62c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2089,10 +2089,11 @@
 {
 	unsigned short old_flags = dev->flags;
 
-	dev->flags |= IFF_PROMISC;
 	if ((dev->promiscuity += inc) == 0)
 		dev->flags &= ~IFF_PROMISC;
-	if (dev->flags ^ old_flags) {
+	else
+		dev->flags |= IFF_PROMISC;
+	if (dev->flags != old_flags) {
 		dev_mc_upload(dev);
 		printk(KERN_INFO "device %s %s promiscuous mode\n",
 		       dev->name, (dev->flags & IFF_PROMISC) ? "entered" :
diff --git a/net/core/filter.c b/net/core/filter.c
index f3b8820..cd91a24 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -36,7 +36,7 @@
 #include <linux/filter.h>
 
 /* No hurry in this branch */
-static u8 *load_pointer(struct sk_buff *skb, int k)
+static void *__load_pointer(struct sk_buff *skb, int k)
 {
 	u8 *ptr = NULL;
 
@@ -50,6 +50,18 @@
 	return NULL;
 }
 
+static inline void *load_pointer(struct sk_buff *skb, int k,
+                                 unsigned int size, void *buffer)
+{
+	if (k >= 0)
+		return skb_header_pointer(skb, k, size, buffer);
+	else {
+		if (k >= SKF_AD_OFF)
+			return NULL;
+		return __load_pointer(skb, k);
+	}
+}
+
 /**
  *	sk_run_filter	- 	run a filter on a socket
  *	@skb: buffer to run the filter on
@@ -64,15 +76,12 @@
  
 int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
 {
-	unsigned char *data = skb->data;
-	/* len is UNSIGNED. Byte wide insns relies only on implicit
-	   type casts to prevent reading arbitrary memory locations.
-	 */
-	unsigned int len = skb->len-skb->data_len;
 	struct sock_filter *fentry;	/* We walk down these */
+	void *ptr;
 	u32 A = 0;	   		/* Accumulator */
 	u32 X = 0;   			/* Index Register */
 	u32 mem[BPF_MEMWORDS];		/* Scratch Memory Store */
+	u32 tmp;
 	int k;
 	int pc;
 
@@ -168,86 +177,35 @@
 		case BPF_LD|BPF_W|BPF_ABS:
 			k = fentry->k;
  load_w:
-			if (k >= 0 && (unsigned int)(k+sizeof(u32)) <= len) {
-				A = ntohl(*(u32*)&data[k]);
+			ptr = load_pointer(skb, k, 4, &tmp);
+			if (ptr != NULL) {
+				A = ntohl(*(u32 *)ptr);
 				continue;
 			}
-			if (k < 0) {
-				u8 *ptr;
-
-				if (k >= SKF_AD_OFF)
-					break;
-				ptr = load_pointer(skb, k);
-				if (ptr) {
-					A = ntohl(*(u32*)ptr);
-					continue;
-				}
-			} else {
-				u32 _tmp, *p;
-				p = skb_header_pointer(skb, k, 4, &_tmp);
-				if (p != NULL) {
-					A = ntohl(*p);
-					continue;
-				}
-			}
 			return 0;
 		case BPF_LD|BPF_H|BPF_ABS:
 			k = fentry->k;
  load_h:
-			if (k >= 0 && (unsigned int)(k + sizeof(u16)) <= len) {
-				A = ntohs(*(u16*)&data[k]);
+			ptr = load_pointer(skb, k, 2, &tmp);
+			if (ptr != NULL) {
+				A = ntohs(*(u16 *)ptr);
 				continue;
 			}
-			if (k < 0) {
-				u8 *ptr;
-
-				if (k >= SKF_AD_OFF)
-					break;
-				ptr = load_pointer(skb, k);
-				if (ptr) {
-					A = ntohs(*(u16*)ptr);
-					continue;
-				}
-			} else {
-				u16 _tmp, *p;
-				p = skb_header_pointer(skb, k, 2, &_tmp);
-				if (p != NULL) {
-					A = ntohs(*p);
-					continue;
-				}
-			}
 			return 0;
 		case BPF_LD|BPF_B|BPF_ABS:
 			k = fentry->k;
 load_b:
-			if (k >= 0 && (unsigned int)k < len) {
-				A = data[k];
+			ptr = load_pointer(skb, k, 1, &tmp);
+			if (ptr != NULL) {
+				A = *(u8 *)ptr;
 				continue;
 			}
-			if (k < 0) {
-				u8 *ptr;
-
-				if (k >= SKF_AD_OFF)
-					break;
-				ptr = load_pointer(skb, k);
-				if (ptr) {
-					A = *ptr;
-					continue;
-				}
-			} else {
-				u8 _tmp, *p;
-				p = skb_header_pointer(skb, k, 1, &_tmp);
-				if (p != NULL) {
-					A = *p;
-					continue;
-				}
-			}
 			return 0;
 		case BPF_LD|BPF_W|BPF_LEN:
-			A = len;
+			A = skb->len;
 			continue;
 		case BPF_LDX|BPF_W|BPF_LEN:
-			X = len;
+			X = skb->len;
 			continue;
 		case BPF_LD|BPF_W|BPF_IND:
 			k = X + fentry->k;
@@ -259,10 +217,12 @@
 			k = X + fentry->k;
 			goto load_b;
 		case BPF_LDX|BPF_B|BPF_MSH:
-			if (fentry->k >= len)
-				return 0;
-			X = (data[fentry->k] & 0xf) << 2;
-			continue;
+			ptr = load_pointer(skb, fentry->k, 1, &tmp);
+			if (ptr != NULL) {
+				X = (*(u8 *)ptr & 0xf) << 2;
+				continue;
+			}
+			return 0;
 		case BPF_LD|BPF_IMM:
 			A = fentry->k;
 			continue;
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 851eb92..1beb782 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1598,6 +1598,8 @@
 
 	read_lock_bh(&tbl->lock);
 	ndtmsg->ndtm_family = tbl->family;
+	ndtmsg->ndtm_pad1   = 0;
+	ndtmsg->ndtm_pad2   = 0;
 
 	RTA_PUT_STRING(skb, NDTA_NAME, tbl->id);
 	RTA_PUT_MSECS(skb, NDTA_GC_INTERVAL, tbl->gc_interval);
@@ -1683,6 +1685,8 @@
 
 	read_lock_bh(&tbl->lock);
 	ndtmsg->ndtm_family = tbl->family;
+	ndtmsg->ndtm_pad1   = 0;
+	ndtmsg->ndtm_pad2   = 0;
 	RTA_PUT_STRING(skb, NDTA_NAME, tbl->id);
 
 	if (neightbl_fill_parms(skb, parms) < 0)
@@ -1872,6 +1876,8 @@
 	struct ndmsg *ndm = NLMSG_DATA(nlh);
 
 	ndm->ndm_family	 = n->ops->family;
+	ndm->ndm_pad1    = 0;
+	ndm->ndm_pad2    = 0;
 	ndm->ndm_flags	 = n->flags;
 	ndm->ndm_type	 = n->type;
 	ndm->ndm_ifindex = n->dev->ifindex;
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index e013d83..4b1bb30 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -126,6 +126,7 @@
 	rta->rta_type = attrtype;
 	rta->rta_len = size;
 	memcpy(RTA_DATA(rta), data, attrlen);
+	memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size);
 }
 
 size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size)
@@ -188,6 +189,7 @@
 	nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*r), flags);
 	r = NLMSG_DATA(nlh);
 	r->ifi_family = AF_UNSPEC;
+	r->__ifi_pad = 0;
 	r->ifi_type = dev->type;
 	r->ifi_index = dev->ifindex;
 	r->ifi_flags = dev_get_flags(dev);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index bb73b21..733deee 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -357,7 +357,6 @@
 	C(ip_summed);
 	C(priority);
 	C(protocol);
-	C(security);
 	n->destructor = NULL;
 #ifdef CONFIG_NETFILTER
 	C(nfmark);
@@ -422,7 +421,6 @@
 	new->pkt_type	= old->pkt_type;
 	new->stamp	= old->stamp;
 	new->destructor = NULL;
-	new->security	= old->security;
 #ifdef CONFIG_NETFILTER
 	new->nfmark	= old->nfmark;
 	new->nfcache	= old->nfcache;
diff --git a/net/core/wireless.c b/net/core/wireless.c
index b2fe378..3ff5639 100644
--- a/net/core/wireless.c
+++ b/net/core/wireless.c
@@ -1102,6 +1102,7 @@
 	nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(*r));
 	r = NLMSG_DATA(nlh);
 	r->ifi_family = AF_UNSPEC;
+	r->__ifi_pad = 0;
 	r->ifi_type = dev->type;
 	r->ifi_index = dev->ifindex;
 	r->ifi_flags = dev->flags;
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c
index 9934b25..99bc061 100644
--- a/net/decnet/dn_fib.c
+++ b/net/decnet/dn_fib.c
@@ -551,7 +551,8 @@
 		if (t < s_t)
 			continue;
 		if (t > s_t)
-			memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(int));
+			memset(&cb->args[1], 0,
+			       sizeof(cb->args) - sizeof(cb->args[0]));
 		tb = dn_fib_get_table(t, 0);
 		if (tb == NULL)
 			continue;
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 6617ea4..ab60ea6 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -92,10 +92,9 @@
 	 *	Set the source hardware address. 
 	 */
 	 
-	if(saddr)
-		memcpy(eth->h_source,saddr,dev->addr_len);
-	else
-		memcpy(eth->h_source,dev->dev_addr,dev->addr_len);
+	if(!saddr)
+		saddr = dev->dev_addr;
+	memcpy(eth->h_source,saddr,dev->addr_len);
 
 	/*
 	 *	Anyway, the loopback-device should never use this function... 
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 658e797..ef74683 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1009,6 +1009,15 @@
 static int ipv4_proc_init(void);
 extern void ipfrag_init(void);
 
+/*
+ *	IP protocol layer initialiser
+ */
+
+static struct packet_type ip_packet_type = {
+	.type = __constant_htons(ETH_P_IP),
+	.func = ip_rcv,
+};
+
 static int __init inet_init(void)
 {
 	struct sk_buff *dummy_skb;
@@ -1102,6 +1111,8 @@
 
 	ipfrag_init();
 
+	dev_add_pack(&ip_packet_type);
+
 	rc = 0;
 out:
 	return rc;
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 0671569..4be234c 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -43,7 +43,7 @@
  *		2 of the License, or (at your option) any later version.
  */
 
-#define VERSION "0.323"
+#define VERSION "0.325"
 
 #include <linux/config.h>
 #include <asm/uaccess.h>
@@ -136,6 +136,7 @@
 	unsigned int semantic_match_passed;
 	unsigned int semantic_match_miss;
 	unsigned int null_node_hit;
+	unsigned int resize_node_skipped;
 };
 #endif
 
@@ -164,8 +165,8 @@
 static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int wasfull);
 static int tnode_child_length(struct tnode *tn);
 static struct node *resize(struct trie *t, struct tnode *tn);
-static struct tnode *inflate(struct trie *t, struct tnode *tn);
-static struct tnode *halve(struct trie *t, struct tnode *tn);
+static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err);
+static struct tnode *halve(struct trie *t, struct tnode *tn, int *err);
 static void tnode_free(struct tnode *tn);
 static void trie_dump_seq(struct seq_file *seq, struct trie *t);
 extern struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio);
@@ -341,8 +342,10 @@
 static struct leaf_info *leaf_info_new(int plen)
 {
 	struct leaf_info *li = kmalloc(sizeof(struct leaf_info),  GFP_KERNEL);
-	li->plen = plen;
-	INIT_LIST_HEAD(&li->falh);
+	if(li) {
+		li->plen = plen;
+		INIT_LIST_HEAD(&li->falh);
+	}
 	return li;
 }
 
@@ -356,11 +359,32 @@
 	kfree(li);
 }
 
+static struct tnode *tnode_alloc(unsigned int size)
+{
+	if (size <= PAGE_SIZE) {
+		return kmalloc(size, GFP_KERNEL);
+	} else {
+		return (struct tnode *)
+		       __get_free_pages(GFP_KERNEL, get_order(size));
+	}
+}
+
+static void __tnode_free(struct tnode *tn)
+{
+	unsigned int size = sizeof(struct tnode) +
+	                    (1<<tn->bits) * sizeof(struct node *);
+
+	if (size <= PAGE_SIZE)
+		kfree(tn);
+	else
+		free_pages((unsigned long)tn, get_order(size));
+}
+
 static struct tnode* tnode_new(t_key key, int pos, int bits)
 {
 	int nchildren = 1<<bits;
 	int sz = sizeof(struct tnode) + nchildren * sizeof(struct node *);
-	struct tnode *tn = kmalloc(sz,  GFP_KERNEL);
+	struct tnode *tn = tnode_alloc(sz);
 
 	if(tn)  {
 		memset(tn, 0, sz);
@@ -388,7 +412,7 @@
 			printk("FL %p \n", tn);
 	}
 	else if(IS_TNODE(tn)) { 
-		kfree(tn);
+		__tnode_free(tn);
 		if(trie_debug > 0 ) 
 			printk("FT %p \n", tn);
 	}
@@ -458,6 +482,7 @@
 static struct node *resize(struct trie *t, struct tnode *tn) 
 {
 	int i;
+	int err = 0;
 
  	if (!tn)
 		return NULL;
@@ -554,12 +579,20 @@
 	 */
 
 	check_tnode(tn);
-
+	
+	err = 0;
 	while ((tn->full_children > 0 &&
 	       50 * (tn->full_children + tnode_child_length(tn) - tn->empty_children) >=
 				inflate_threshold * tnode_child_length(tn))) {
 
-		tn = inflate(t, tn);
+		tn = inflate(t, tn, &err);
+
+		if(err) {
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+			t->stats.resize_node_skipped++;
+#endif
+			break;
+		}
 	}
 
 	check_tnode(tn);
@@ -568,11 +601,22 @@
 	 * Halve as long as the number of empty children in this
 	 * node is above threshold.
 	 */
+
+	err = 0;
 	while (tn->bits > 1 &&
 	       100 * (tnode_child_length(tn) - tn->empty_children) <
-	       halve_threshold * tnode_child_length(tn))
+	       halve_threshold * tnode_child_length(tn)) {
 
-		tn = halve(t, tn);
+		tn = halve(t, tn, &err);
+
+		if(err) {
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+			t->stats.resize_node_skipped++;
+#endif
+			break;
+		}
+	}
+
   
 	/* Only one child remains */
 
@@ -597,7 +641,7 @@
 	return (struct node *) tn;
 }
 
-static struct tnode *inflate(struct trie *t, struct tnode *tn)
+static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err)
 {
 	struct tnode *inode;
 	struct tnode *oldtnode = tn;
@@ -609,8 +653,63 @@
 
 	tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits + 1);
 
-	if (!tn)
-		trie_bug("tnode_new failed");
+	if (!tn) {
+		*err = -ENOMEM;
+		return oldtnode;
+	}
+
+	/*
+	 * Preallocate and store tnodes before the actual work so we 
+	 * don't get into an inconsistent state if memory allocation 
+	 * fails. In case of failure we return the oldnode and  inflate 
+	 * of tnode is ignored.
+	 */
+			
+	for(i = 0; i < olen; i++) {
+		struct tnode *inode = (struct tnode *) tnode_get_child(oldtnode, i);
+
+		if (inode &&
+		    IS_TNODE(inode) &&
+		    inode->pos == oldtnode->pos + oldtnode->bits &&
+		    inode->bits > 1) {
+			struct tnode *left, *right;
+
+			t_key m = TKEY_GET_MASK(inode->pos, 1);
+ 
+			left = tnode_new(inode->key&(~m), inode->pos + 1,
+					 inode->bits - 1);
+
+			if(!left) {
+				*err = -ENOMEM; 
+				break;
+			}
+			
+			right = tnode_new(inode->key|m, inode->pos + 1,
+					  inode->bits - 1);
+
+			if(!right) {
+				*err = -ENOMEM; 
+				break;
+			}
+
+			put_child(t, tn, 2*i, (struct node *) left);
+			put_child(t, tn, 2*i+1, (struct node *) right);
+		}
+	}
+
+	if(*err) {
+		int size = tnode_child_length(tn);
+		int j;
+
+		for(j = 0; j < size; j++) 
+			if( tn->child[j])
+				tnode_free((struct tnode *)tn->child[j]);
+
+		tnode_free(tn);
+		
+		*err = -ENOMEM;
+		return oldtnode;
+	}
 
 	for(i = 0; i < olen; i++) {
 		struct node *node = tnode_get_child(oldtnode, i);
@@ -623,7 +722,7 @@
 
 		if(IS_LEAF(node) || ((struct tnode *) node)->pos >
 		   tn->pos + tn->bits - 1) {
-			if(tkey_extract_bits(node->key, tn->pos + tn->bits - 1,
+			if(tkey_extract_bits(node->key, oldtnode->pos + oldtnode->bits,
 					     1) == 0)
 				put_child(t, tn, 2*i, node);
 			else
@@ -663,27 +762,22 @@
 			 * the position (inode->pos)
 			 */
 
-			t_key m = TKEY_GET_MASK(inode->pos, 1);
- 
 			/* Use the old key, but set the new significant 
 			 *   bit to zero. 
 			 */
-			left = tnode_new(inode->key&(~m), inode->pos + 1,
-					 inode->bits - 1);
 
-			if(!left) 
-				trie_bug("tnode_new failed");
-			
-			
-			/* Use the old key, but set the new significant 
-			 * bit to one. 
-			 */
-			right = tnode_new(inode->key|m, inode->pos + 1,
-					  inode->bits - 1);
+			left = (struct tnode *) tnode_get_child(tn, 2*i);
+			put_child(t, tn, 2*i, NULL);
 
-			if(!right) 
-				trie_bug("tnode_new failed");
-			
+			if(!left)
+				BUG();
+
+			right = (struct tnode *) tnode_get_child(tn, 2*i+1);
+			put_child(t, tn, 2*i+1, NULL);
+
+			if(!right)
+				BUG();
+
 			size = tnode_child_length(left);
 			for(j = 0; j < size; j++) {
 				put_child(t, left, j, inode->child[j]);
@@ -699,7 +793,7 @@
 	return tn;
 }
 
-static struct tnode *halve(struct trie *t, struct tnode *tn)
+static struct tnode *halve(struct trie *t, struct tnode *tn, int *err)
 {
 	struct tnode *oldtnode = tn;
 	struct node *left, *right;
@@ -710,8 +804,48 @@
   
 	tn=tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits - 1);
 
-	if(!tn) 
-		trie_bug("tnode_new failed");
+	if (!tn) {
+		*err = -ENOMEM;
+		return oldtnode;
+	}
+
+	/*
+	 * Preallocate and store tnodes before the actual work so we 
+	 * don't get into an inconsistent state if memory allocation 
+	 * fails. In case of failure we return the oldnode and halve 
+	 * of tnode is ignored.
+	 */
+
+	for(i = 0; i < olen; i += 2) {
+		left = tnode_get_child(oldtnode, i);
+		right = tnode_get_child(oldtnode, i+1);
+    
+		/* Two nonempty children */
+		if( left && right)  {
+			struct tnode *newBinNode =
+				tnode_new(left->key, tn->pos + tn->bits, 1);
+
+			if(!newBinNode) {
+				*err = -ENOMEM; 
+				break;
+			}
+			put_child(t, tn, i/2, (struct node *)newBinNode);
+		}
+	}
+
+	if(*err) {
+		int size = tnode_child_length(tn);
+		int j;
+
+		for(j = 0; j < size; j++) 
+			if( tn->child[j])
+				tnode_free((struct tnode *)tn->child[j]);
+
+		tnode_free(tn);
+		
+		*err = -ENOMEM;
+		return oldtnode;
+	}
 
 	for(i = 0; i < olen; i += 2) {
 		left = tnode_get_child(oldtnode, i);
@@ -728,10 +862,11 @@
 		/* Two nonempty children */
 		else {
 			struct tnode *newBinNode =
-				tnode_new(left->key, tn->pos + tn->bits, 1);
+				(struct tnode *) tnode_get_child(tn, i/2);
+			put_child(t, tn, i/2, NULL);
 
 			if(!newBinNode) 
-				trie_bug("tnode_new failed");
+				BUG();
 
 			put_child(t, newBinNode, 0, left);
 			put_child(t, newBinNode, 1, right);
@@ -879,8 +1014,8 @@
 	return (struct node*) tn;
 }
 
-static struct list_head *
-fib_insert_node(struct trie *t, u32 key, int plen)
+static  struct list_head *
+fib_insert_node(struct trie *t, int *err, u32 key, int plen)
 {
 	int pos, newpos;
 	struct tnode *tp = NULL, *tn = NULL;
@@ -940,7 +1075,6 @@
 	if(tp && IS_LEAF(tp))
 		BUG();
 
-	t->revision++;
 
 	/* Case 1: n is a leaf. Compare prefixes */
 
@@ -949,8 +1083,10 @@
 		
 		li = leaf_info_new(plen);
 		
-		if(! li) 
-			BUG();
+		if(! li) {
+			*err = -ENOMEM;
+			goto err;
+		}
 
 		fa_head = &li->falh;
 		insert_leaf_info(&l->list, li);
@@ -959,14 +1095,19 @@
 	t->size++;
 	l = leaf_new();
 
-	if(! l) 
-		BUG();
+	if(! l) {
+		*err = -ENOMEM;
+		goto err;
+	}
 
 	l->key = key;
 	li = leaf_info_new(plen);
 
-	if(! li) 
-		BUG();
+	if(! li) {
+		tnode_free((struct tnode *) l);
+		*err = -ENOMEM;
+		goto err;
+	}
 
 	fa_head = &li->falh;
 	insert_leaf_info(&l->list, li);
@@ -1003,9 +1144,14 @@
 			newpos = 0;
 			tn = tnode_new(key, newpos, 1); /* First tnode */ 
 		}
-		if(!tn) 
-			trie_bug("tnode_pfx_new failed");
 
+		if(!tn) {
+			free_leaf_info(li);
+			tnode_free((struct tnode *) l);
+			*err = -ENOMEM;
+			goto err;
+		}			
+			
 		NODE_SET_PARENT(tn, tp);
 
 		missbit=tkey_extract_bits(key, newpos, 1);
@@ -1027,7 +1173,9 @@
 	}
 	/* Rebalance the trie */
 	t->trie = trie_rebalance(t, tp);
-done:;
+done:
+	t->revision++;
+err:;
 	return fa_head;
 }
 
@@ -1156,8 +1304,12 @@
 	 * Insert new entry to the list.
 	 */
 
-	if(!fa_head)
-		fa_head = fib_insert_node(t, key, plen);
+	if(!fa_head) {
+		fa_head = fib_insert_node(t, &err, key, plen);
+		err = 0;
+		if(err) 
+			goto out_free_new_fa;
+	}
 
 	write_lock_bh(&fib_lock);
 
@@ -1170,6 +1322,9 @@
 	rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, nlhdr, req);
 succeeded:
 	return 0;
+
+out_free_new_fa:
+	kmem_cache_free(fn_alias_kmem, new_fa);
 out:
 	fib_release_info(fi);
 err:;	
@@ -2279,6 +2434,7 @@
 	seq_printf(seq,"semantic match passed = %d\n", t->stats.semantic_match_passed);
 	seq_printf(seq,"semantic match miss = %d\n", t->stats.semantic_match_miss);
 	seq_printf(seq,"null node hit= %d\n", t->stats.null_node_hit);
+	seq_printf(seq,"skipped node resize = %d\n", t->stats.resize_node_skipped);
 #ifdef CLEAR_STATS
 	memset(&(t->stats), 0, sizeof(t->stats));
 #endif
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index af2ec88..c703528 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -283,14 +283,18 @@
 {
 	struct net_device *dev = skb->dev;
 	struct iphdr *iph = skb->nh.iph;
+	int err;
 
 	/*
 	 *	Initialise the virtual path cache for the packet. It describes
 	 *	how the packet travels inside Linux networking.
 	 */ 
 	if (skb->dst == NULL) {
-		if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))
+		if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) {
+			if (err == -EHOSTUNREACH)
+				IP_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
 			goto drop; 
+		}
 	}
 
 #ifdef CONFIG_NET_CLS_ROUTE
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index ee07aec..9de83e6 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -188,7 +188,13 @@
 		skb = skb2;
 	}
 
-	nf_reset(skb);
+#ifdef CONFIG_BRIDGE_NETFILTER
+	/* bridge-netfilter defers calling some IP hooks to the bridge layer
+	 * and still needs the conntrack reference.
+	 */
+	if (skb->nf_bridge == NULL)
+#endif
+		nf_reset(skb);
 
 	if (hh) {
 		int hh_alen;
@@ -383,7 +389,6 @@
 	to->pkt_type = from->pkt_type;
 	to->priority = from->priority;
 	to->protocol = from->protocol;
-	to->security = from->security;
 	dst_release(to->dst);
 	to->dst = dst_clone(from->dst);
 	to->dev = from->dev;
@@ -1323,23 +1328,8 @@
 	ip_rt_put(rt);
 }
 
-/*
- *	IP protocol layer initialiser
- */
-
-static struct packet_type ip_packet_type = {
-	.type = __constant_htons(ETH_P_IP),
-	.func = ip_rcv,
-};
-
-/*
- *	IP registers the packet type and then calls the subprotocol initialisers
- */
-
 void __init ip_init(void)
 {
-	dev_add_pack(&ip_packet_type);
-
 	ip_rt_init();
 	inet_initpeers();
 
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index f250903..d2bf8e1 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -1149,8 +1149,10 @@
 		ic_rarp_cleanup();
 #endif
 
-	if (!ic_got_reply)
+	if (!ic_got_reply) {
+		ic_myaddr = INADDR_NONE;
 		return -1;
+	}
 
 	printk("IP-Config: Got %s answer from %u.%u.%u.%u, ",
 		((ic_got_reply & IC_RARP) ? "RARP" 
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index e4f809a..7833d92 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -297,6 +297,7 @@
 static void ipmr_destroy_unres(struct mfc_cache *c)
 {
 	struct sk_buff *skb;
+	struct nlmsgerr *e;
 
 	atomic_dec(&cache_resolve_queue_len);
 
@@ -306,7 +307,9 @@
 			nlh->nlmsg_type = NLMSG_ERROR;
 			nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
 			skb_trim(skb, nlh->nlmsg_len);
-			((struct nlmsgerr*)NLMSG_DATA(nlh))->error = -ETIMEDOUT;
+			e = NLMSG_DATA(nlh);
+			e->error = -ETIMEDOUT;
+			memset(&e->msg, 0, sizeof(e->msg));
 			netlink_unicast(rtnl, skb, NETLINK_CB(skb).dst_pid, MSG_DONTWAIT);
 		} else
 			kfree_skb(skb);
@@ -499,6 +502,7 @@
 static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c)
 {
 	struct sk_buff *skb;
+	struct nlmsgerr *e;
 
 	/*
 	 *	Play the pending entries through our router
@@ -515,7 +519,9 @@
 				nlh->nlmsg_type = NLMSG_ERROR;
 				nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
 				skb_trim(skb, nlh->nlmsg_len);
-				((struct nlmsgerr*)NLMSG_DATA(nlh))->error = -EMSGSIZE;
+				e = NLMSG_DATA(nlh);
+				e->error = -EMSGSIZE;
+				memset(&e->msg, 0, sizeof(e->msg));
 			}
 			err = netlink_unicast(rtnl, skb, NETLINK_CB(skb).dst_pid, MSG_DONTWAIT);
 		} else
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c
index fd6feb5..9f16ab3 100644
--- a/net/ipv4/ipvs/ip_vs_conn.c
+++ b/net/ipv4/ipvs/ip_vs_conn.c
@@ -548,7 +548,6 @@
 {
 	if (del_timer(&cp->timer))
 		mod_timer(&cp->timer, jiffies);
-	__ip_vs_conn_put(cp);
 }
 
 
@@ -764,7 +763,6 @@
 {
 	int idx;
 	struct ip_vs_conn *cp;
-	struct ip_vs_conn *ct;
 
 	/*
 	 * Randomly scan 1/32 of the whole table every second
@@ -801,21 +799,12 @@
 					continue;
 			}
 
-			/*
-			 * Drop the entry, and drop its ct if not referenced
-			 */
-			atomic_inc(&cp->refcnt);
-			ct_write_unlock(hash);
-
-			if ((ct = cp->control))
-				atomic_inc(&ct->refcnt);
 			IP_VS_DBG(4, "del connection\n");
 			ip_vs_conn_expire_now(cp);
-			if (ct) {
+			if (cp->control) {
 				IP_VS_DBG(4, "del conn template\n");
-				ip_vs_conn_expire_now(ct);
+				ip_vs_conn_expire_now(cp->control);
 			}
-			ct_write_lock(hash);
 		}
 		ct_write_unlock(hash);
 	}
@@ -829,7 +818,6 @@
 {
 	int idx;
 	struct ip_vs_conn *cp;
-	struct ip_vs_conn *ct;
 
   flush_again:
 	for (idx=0; idx<IP_VS_CONN_TAB_SIZE; idx++) {
@@ -839,18 +827,13 @@
 		ct_write_lock_bh(idx);
 
 		list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) {
-			atomic_inc(&cp->refcnt);
-			ct_write_unlock(idx);
 
-			if ((ct = cp->control))
-				atomic_inc(&ct->refcnt);
 			IP_VS_DBG(4, "del connection\n");
 			ip_vs_conn_expire_now(cp);
-			if (ct) {
+			if (cp->control) {
 				IP_VS_DBG(4, "del conn template\n");
-				ip_vs_conn_expire_now(ct);
+				ip_vs_conn_expire_now(cp->control);
 			}
-			ct_write_lock(idx);
 		}
 		ct_write_unlock_bh(idx);
 	}
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 9cde8c6..6706d3a 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -30,7 +30,7 @@
 #include <linux/netfilter_ipv4/ipt_CLUSTERIP.h>
 #include <linux/netfilter_ipv4/ip_conntrack.h>
 
-#define CLUSTERIP_VERSION "0.6"
+#define CLUSTERIP_VERSION "0.7"
 
 #define DEBUG_CLUSTERIP
 
@@ -524,8 +524,9 @@
 	    || arp->ar_pln != 4 || arp->ar_hln != ETH_ALEN)
 		return NF_ACCEPT;
 
-	/* we only want to mangle arp replies */
-	if (arp->ar_op != htons(ARPOP_REPLY))
+	/* we only want to mangle arp requests and replies */
+	if (arp->ar_op != htons(ARPOP_REPLY)
+	    && arp->ar_op != htons(ARPOP_REQUEST))
 		return NF_ACCEPT;
 
 	payload = (void *)(arp+1);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 80cf633..726ea5e 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -54,6 +54,7 @@
  *		Marc Boucher	:	routing by fwmark
  *	Robert Olsson		:	Added rt_cache statistics
  *	Arnaldo C. Melo		:	Convert proc stuff to seq_file
+ *	Eric Dumazet		:	hashed spinlocks and rt_check_expire() fixes.
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
@@ -70,6 +71,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/bootmem.h>
 #include <linux/string.h>
 #include <linux/socket.h>
 #include <linux/sockios.h>
@@ -201,8 +203,37 @@
 
 struct rt_hash_bucket {
 	struct rtable	*chain;
-	spinlock_t	lock;
-} __attribute__((__aligned__(8)));
+};
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+/*
+ * Instead of using one spinlock for each rt_hash_bucket, we use a table of spinlocks
+ * The size of this table is a power of two and depends on the number of CPUS.
+ */
+#if NR_CPUS >= 32
+#define RT_HASH_LOCK_SZ	4096
+#elif NR_CPUS >= 16
+#define RT_HASH_LOCK_SZ	2048
+#elif NR_CPUS >= 8
+#define RT_HASH_LOCK_SZ	1024
+#elif NR_CPUS >= 4
+#define RT_HASH_LOCK_SZ	512
+#else
+#define RT_HASH_LOCK_SZ	256
+#endif
+
+static spinlock_t	*rt_hash_locks;
+# define rt_hash_lock_addr(slot) &rt_hash_locks[(slot) & (RT_HASH_LOCK_SZ - 1)]
+# define rt_hash_lock_init()	{ \
+		int i; \
+		rt_hash_locks = kmalloc(sizeof(spinlock_t) * RT_HASH_LOCK_SZ, GFP_KERNEL); \
+		if (!rt_hash_locks) panic("IP: failed to allocate rt_hash_locks\n"); \
+		for (i = 0; i < RT_HASH_LOCK_SZ; i++) \
+			spin_lock_init(&rt_hash_locks[i]); \
+		}
+#else
+# define rt_hash_lock_addr(slot) NULL
+# define rt_hash_lock_init()
+#endif
 
 static struct rt_hash_bucket 	*rt_hash_table;
 static unsigned			rt_hash_mask;
@@ -575,19 +606,26 @@
 /* This runs via a timer and thus is always in BH context. */
 static void rt_check_expire(unsigned long dummy)
 {
-	static int rover;
-	int i = rover, t;
+	static unsigned int rover;
+	unsigned int i = rover, goal;
 	struct rtable *rth, **rthp;
 	unsigned long now = jiffies;
+	u64 mult;
 
-	for (t = ip_rt_gc_interval << rt_hash_log; t >= 0;
-	     t -= ip_rt_gc_timeout) {
+	mult = ((u64)ip_rt_gc_interval) << rt_hash_log;
+	if (ip_rt_gc_timeout > 1)
+		do_div(mult, ip_rt_gc_timeout);
+	goal = (unsigned int)mult;
+	if (goal > rt_hash_mask) goal = rt_hash_mask + 1;
+	for (; goal > 0; goal--) {
 		unsigned long tmo = ip_rt_gc_timeout;
 
 		i = (i + 1) & rt_hash_mask;
 		rthp = &rt_hash_table[i].chain;
 
-		spin_lock(&rt_hash_table[i].lock);
+		if (*rthp == 0)
+			continue;
+		spin_lock(rt_hash_lock_addr(i));
 		while ((rth = *rthp) != NULL) {
 			if (rth->u.dst.expires) {
 				/* Entry is expired even if it is in use */
@@ -620,14 +658,14 @@
  			rt_free(rth);
 #endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
 		}
-		spin_unlock(&rt_hash_table[i].lock);
+		spin_unlock(rt_hash_lock_addr(i));
 
 		/* Fallback loop breaker. */
 		if (time_after(jiffies, now))
 			break;
 	}
 	rover = i;
-	mod_timer(&rt_periodic_timer, now + ip_rt_gc_interval);
+	mod_timer(&rt_periodic_timer, jiffies + ip_rt_gc_interval);
 }
 
 /* This can run from both BH and non-BH contexts, the latter
@@ -643,11 +681,11 @@
 	get_random_bytes(&rt_hash_rnd, 4);
 
 	for (i = rt_hash_mask; i >= 0; i--) {
-		spin_lock_bh(&rt_hash_table[i].lock);
+		spin_lock_bh(rt_hash_lock_addr(i));
 		rth = rt_hash_table[i].chain;
 		if (rth)
 			rt_hash_table[i].chain = NULL;
-		spin_unlock_bh(&rt_hash_table[i].lock);
+		spin_unlock_bh(rt_hash_lock_addr(i));
 
 		for (; rth; rth = next) {
 			next = rth->u.rt_next;
@@ -780,7 +818,7 @@
 
 			k = (k + 1) & rt_hash_mask;
 			rthp = &rt_hash_table[k].chain;
-			spin_lock_bh(&rt_hash_table[k].lock);
+			spin_lock_bh(rt_hash_lock_addr(k));
 			while ((rth = *rthp) != NULL) {
 				if (!rt_may_expire(rth, tmo, expire)) {
 					tmo >>= 1;
@@ -812,7 +850,7 @@
 				goal--;
 #endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
 			}
-			spin_unlock_bh(&rt_hash_table[k].lock);
+			spin_unlock_bh(rt_hash_lock_addr(k));
 			if (goal <= 0)
 				break;
 		}
@@ -882,7 +920,7 @@
 
 	rthp = &rt_hash_table[hash].chain;
 
-	spin_lock_bh(&rt_hash_table[hash].lock);
+	spin_lock_bh(rt_hash_lock_addr(hash));
 	while ((rth = *rthp) != NULL) {
 #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
 		if (!(rth->u.dst.flags & DST_BALANCED) &&
@@ -908,7 +946,7 @@
 			rth->u.dst.__use++;
 			dst_hold(&rth->u.dst);
 			rth->u.dst.lastuse = now;
-			spin_unlock_bh(&rt_hash_table[hash].lock);
+			spin_unlock_bh(rt_hash_lock_addr(hash));
 
 			rt_drop(rt);
 			*rp = rth;
@@ -949,7 +987,7 @@
 	if (rt->rt_type == RTN_UNICAST || rt->fl.iif == 0) {
 		int err = arp_bind_neighbour(&rt->u.dst);
 		if (err) {
-			spin_unlock_bh(&rt_hash_table[hash].lock);
+			spin_unlock_bh(rt_hash_lock_addr(hash));
 
 			if (err != -ENOBUFS) {
 				rt_drop(rt);
@@ -990,7 +1028,7 @@
 	}
 #endif
 	rt_hash_table[hash].chain = rt;
-	spin_unlock_bh(&rt_hash_table[hash].lock);
+	spin_unlock_bh(rt_hash_lock_addr(hash));
 	*rp = rt;
 	return 0;
 }
@@ -1058,7 +1096,7 @@
 {
 	struct rtable **rthp;
 
-	spin_lock_bh(&rt_hash_table[hash].lock);
+	spin_lock_bh(rt_hash_lock_addr(hash));
 	ip_rt_put(rt);
 	for (rthp = &rt_hash_table[hash].chain; *rthp;
 	     rthp = &(*rthp)->u.rt_next)
@@ -1067,7 +1105,7 @@
 			rt_free(rt);
 			break;
 		}
-	spin_unlock_bh(&rt_hash_table[hash].lock);
+	spin_unlock_bh(rt_hash_lock_addr(hash));
 }
 
 void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
@@ -1909,7 +1947,7 @@
 	 */
 	if ((err = fib_lookup(&fl, &res)) != 0) {
 		if (!IN_DEV_FORWARD(in_dev))
-			goto e_inval;
+			goto e_hostunreach;
 		goto no_route;
 	}
 	free_res = 1;
@@ -1933,7 +1971,7 @@
 	}
 
 	if (!IN_DEV_FORWARD(in_dev))
-		goto e_inval;
+		goto e_hostunreach;
 	if (res.type != RTN_UNICAST)
 		goto martian_destination;
 
@@ -2025,6 +2063,11 @@
 			"%u.%u.%u.%u, dev %s\n",
 			NIPQUAD(daddr), NIPQUAD(saddr), dev->name);
 #endif
+
+e_hostunreach:
+        err = -EHOSTUNREACH;
+        goto done;
+
 e_inval:
 	err = -EINVAL;
 	goto done;
@@ -3068,12 +3111,14 @@
 
 int __init ip_rt_init(void)
 {
-	int i, order, goal, rc = 0;
+	int rc = 0;
 
 	rt_hash_rnd = (int) ((num_physpages ^ (num_physpages>>8)) ^
 			     (jiffies ^ (jiffies >> 7)));
 
 #ifdef CONFIG_NET_CLS_ROUTE
+	{
+	int order;
 	for (order = 0;
 	     (PAGE_SIZE << order) < 256 * sizeof(struct ip_rt_acct) * NR_CPUS; order++)
 		/* NOTHING */;
@@ -3081,6 +3126,7 @@
 	if (!ip_rt_acct)
 		panic("IP: failed to allocate ip_rt_acct\n");
 	memset(ip_rt_acct, 0, PAGE_SIZE << order);
+	}
 #endif
 
 	ipv4_dst_ops.kmem_cachep = kmem_cache_create("ip_dst_cache",
@@ -3091,36 +3137,19 @@
 	if (!ipv4_dst_ops.kmem_cachep)
 		panic("IP: failed to allocate ip_dst_cache\n");
 
-	goal = num_physpages >> (26 - PAGE_SHIFT);
-	if (rhash_entries)
-		goal = (rhash_entries * sizeof(struct rt_hash_bucket)) >> PAGE_SHIFT;
-	for (order = 0; (1UL << order) < goal; order++)
-		/* NOTHING */;
-
-	do {
-		rt_hash_mask = (1UL << order) * PAGE_SIZE /
-			sizeof(struct rt_hash_bucket);
-		while (rt_hash_mask & (rt_hash_mask - 1))
-			rt_hash_mask--;
-		rt_hash_table = (struct rt_hash_bucket *)
-			__get_free_pages(GFP_ATOMIC, order);
-	} while (rt_hash_table == NULL && --order > 0);
-
-	if (!rt_hash_table)
-		panic("Failed to allocate IP route cache hash table\n");
-
-	printk(KERN_INFO "IP: routing cache hash table of %u buckets, %ldKbytes\n",
-	       rt_hash_mask,
-	       (long) (rt_hash_mask * sizeof(struct rt_hash_bucket)) / 1024);
-
-	for (rt_hash_log = 0; (1 << rt_hash_log) != rt_hash_mask; rt_hash_log++)
-		/* NOTHING */;
-
-	rt_hash_mask--;
-	for (i = 0; i <= rt_hash_mask; i++) {
-		spin_lock_init(&rt_hash_table[i].lock);
-		rt_hash_table[i].chain = NULL;
-	}
+	rt_hash_table = (struct rt_hash_bucket *)
+		alloc_large_system_hash("IP route cache",
+					sizeof(struct rt_hash_bucket),
+					rhash_entries,
+					(num_physpages >= 128 * 1024) ?
+						(27 - PAGE_SHIFT) :
+						(29 - PAGE_SHIFT),
+					HASH_HIGHMEM,
+					&rt_hash_log,
+					&rt_hash_mask,
+					0);
+	memset(rt_hash_table, 0, (rt_hash_mask + 1) * sizeof(struct rt_hash_bucket));
+	rt_hash_lock_init();
 
 	ipv4_dst_ops.gc_thresh = (rt_hash_mask + 1);
 	ip_rt_max_size = (rt_hash_mask + 1) * 16;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 882436d..29894c7 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -615,7 +615,7 @@
 			 size_t psize, int flags)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	int mss_now;
+	int mss_now, size_goal;
 	int err;
 	ssize_t copied;
 	long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
@@ -628,6 +628,7 @@
 	clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
 
 	mss_now = tcp_current_mss(sk, !(flags&MSG_OOB));
+	size_goal = tp->xmit_size_goal;
 	copied = 0;
 
 	err = -EPIPE;
@@ -641,7 +642,7 @@
 		int offset = poffset % PAGE_SIZE;
 		int size = min_t(size_t, psize, PAGE_SIZE - offset);
 
-		if (!sk->sk_send_head || (copy = mss_now - skb->len) <= 0) {
+		if (!sk->sk_send_head || (copy = size_goal - skb->len) <= 0) {
 new_segment:
 			if (!sk_stream_memory_free(sk))
 				goto wait_for_sndbuf;
@@ -652,7 +653,7 @@
 				goto wait_for_memory;
 
 			skb_entail(sk, tp, skb);
-			copy = mss_now;
+			copy = size_goal;
 		}
 
 		if (copy > size)
@@ -693,7 +694,7 @@
 		if (!(psize -= copy))
 			goto out;
 
-		if (skb->len != mss_now || (flags & MSG_OOB))
+		if (skb->len < mss_now || (flags & MSG_OOB))
 			continue;
 
 		if (forced_push(tp)) {
@@ -713,6 +714,7 @@
 			goto do_error;
 
 		mss_now = tcp_current_mss(sk, !(flags&MSG_OOB));
+		size_goal = tp->xmit_size_goal;
 	}
 
 out:
@@ -754,15 +756,20 @@
 
 static inline int select_size(struct sock *sk, struct tcp_sock *tp)
 {
-	int tmp = tp->mss_cache_std;
+	int tmp = tp->mss_cache;
 
 	if (sk->sk_route_caps & NETIF_F_SG) {
-		int pgbreak = SKB_MAX_HEAD(MAX_TCP_HEADER);
+		if (sk->sk_route_caps & NETIF_F_TSO)
+			tmp = 0;
+		else {
+			int pgbreak = SKB_MAX_HEAD(MAX_TCP_HEADER);
 
-		if (tmp >= pgbreak &&
-		    tmp <= pgbreak + (MAX_SKB_FRAGS - 1) * PAGE_SIZE)
-			tmp = pgbreak;
+			if (tmp >= pgbreak &&
+			    tmp <= pgbreak + (MAX_SKB_FRAGS - 1) * PAGE_SIZE)
+				tmp = pgbreak;
+		}
 	}
+
 	return tmp;
 }
 
@@ -773,7 +780,7 @@
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *skb;
 	int iovlen, flags;
-	int mss_now;
+	int mss_now, size_goal;
 	int err, copied;
 	long timeo;
 
@@ -792,6 +799,7 @@
 	clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
 
 	mss_now = tcp_current_mss(sk, !(flags&MSG_OOB));
+	size_goal = tp->xmit_size_goal;
 
 	/* Ok commence sending. */
 	iovlen = msg->msg_iovlen;
@@ -814,7 +822,7 @@
 			skb = sk->sk_write_queue.prev;
 
 			if (!sk->sk_send_head ||
-			    (copy = mss_now - skb->len) <= 0) {
+			    (copy = size_goal - skb->len) <= 0) {
 
 new_segment:
 				/* Allocate new segment. If the interface is SG,
@@ -837,7 +845,7 @@
 					skb->ip_summed = CHECKSUM_HW;
 
 				skb_entail(sk, tp, skb);
-				copy = mss_now;
+				copy = size_goal;
 			}
 
 			/* Try to append data to the end of skb. */
@@ -872,11 +880,6 @@
 					tcp_mark_push(tp, skb);
 					goto new_segment;
 				} else if (page) {
-					/* If page is cached, align
-					 * offset to L1 cache boundary
-					 */
-					off = (off + L1_CACHE_BYTES - 1) &
-					      ~(L1_CACHE_BYTES - 1);
 					if (off == PAGE_SIZE) {
 						put_page(page);
 						TCP_PAGE(sk) = page = NULL;
@@ -937,7 +940,7 @@
 			if ((seglen -= copy) == 0 && iovlen == 0)
 				goto out;
 
-			if (skb->len != mss_now || (flags & MSG_OOB))
+			if (skb->len < mss_now || (flags & MSG_OOB))
 				continue;
 
 			if (forced_push(tp)) {
@@ -957,6 +960,7 @@
 				goto do_error;
 
 			mss_now = tcp_current_mss(sk, !(flags&MSG_OOB));
+			size_goal = tp->xmit_size_goal;
 		}
 	}
 
@@ -2128,7 +2132,7 @@
 
 	info->tcpi_rto = jiffies_to_usecs(tp->rto);
 	info->tcpi_ato = jiffies_to_usecs(tp->ack.ato);
-	info->tcpi_snd_mss = tp->mss_cache_std;
+	info->tcpi_snd_mss = tp->mss_cache;
 	info->tcpi_rcv_mss = tp->ack.rcv_mss;
 
 	info->tcpi_unacked = tp->packets_out;
@@ -2178,7 +2182,7 @@
 
 	switch (optname) {
 	case TCP_MAXSEG:
-		val = tp->mss_cache_std;
+		val = tp->mss_cache;
 		if (!val && ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)))
 			val = tp->rx_opt.user_mss;
 		break;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 7bbbbc3..8de2f10 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -740,10 +740,10 @@
 	__u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0);
 
 	if (!cwnd) {
-		if (tp->mss_cache_std > 1460)
+		if (tp->mss_cache > 1460)
 			cwnd = 2;
 		else
-			cwnd = (tp->mss_cache_std > 1095) ? 3 : 4;
+			cwnd = (tp->mss_cache > 1095) ? 3 : 4;
 	}
 	return min_t(__u32, cwnd, tp->snd_cwnd_clamp);
 }
@@ -914,7 +914,7 @@
 	if (sk->sk_route_caps & NETIF_F_TSO) {
 		sk->sk_route_caps &= ~NETIF_F_TSO;
 		sock_set_flag(sk, SOCK_NO_LARGESEND);
-		tp->mss_cache = tp->mss_cache_std;
+		tp->mss_cache = tp->mss_cache;
 	}
 
 	if (!tp->sacked_out)
@@ -1077,7 +1077,7 @@
 			    (IsFack(tp) ||
 			     !before(lost_retrans,
 				     TCP_SKB_CB(skb)->ack_seq + tp->reordering *
-				     tp->mss_cache_std))) {
+				     tp->mss_cache))) {
 				TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
 				tp->retrans_out -= tcp_skb_pcount(skb);
 
@@ -1957,15 +1957,6 @@
 	}
 }
 
-/* There is one downside to this scheme.  Although we keep the
- * ACK clock ticking, adjusting packet counters and advancing
- * congestion window, we do not liberate socket send buffer
- * space.
- *
- * Mucking with skb->truesize and sk->sk_wmem_alloc et al.
- * then making a write space wakeup callback is a possible
- * future enhancement.  WARNING: it is not trivial to make.
- */
 static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb,
 			 __u32 now, __s32 *seq_rtt)
 {
@@ -2047,7 +2038,8 @@
 		 * the other end.
 		 */
 		if (after(scb->end_seq, tp->snd_una)) {
-			if (tcp_skb_pcount(skb) > 1)
+			if (tcp_skb_pcount(skb) > 1 &&
+			    after(tp->snd_una, scb->seq))
 				acked |= tcp_tso_acked(sk, skb,
 						       now, &seq_rtt);
 			break;
@@ -3308,6 +3300,28 @@
 	tp->snd_cwnd_stamp = tcp_time_stamp;
 }
 
+static inline int tcp_should_expand_sndbuf(struct sock *sk, struct tcp_sock *tp)
+{
+	/* If the user specified a specific send buffer setting, do
+	 * not modify it.
+	 */
+	if (sk->sk_userlocks & SOCK_SNDBUF_LOCK)
+		return 0;
+
+	/* If we are under global TCP memory pressure, do not expand.  */
+	if (tcp_memory_pressure)
+		return 0;
+
+	/* If we are under soft global TCP memory pressure, do not expand.  */
+	if (atomic_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0])
+		return 0;
+
+	/* If we filled the congestion window, do not expand.  */
+	if (tp->packets_out >= tp->snd_cwnd)
+		return 0;
+
+	return 1;
+}
 
 /* When incoming ACK allowed to free some skb from write_queue,
  * we remember this event in flag SOCK_QUEUE_SHRUNK and wake up socket
@@ -3319,11 +3333,8 @@
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 
-	if (tp->packets_out < tp->snd_cwnd &&
-	    !(sk->sk_userlocks & SOCK_SNDBUF_LOCK) &&
-	    !tcp_memory_pressure &&
-	    atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) {
- 		int sndmem = max_t(u32, tp->rx_opt.mss_clamp, tp->mss_cache_std) +
+	if (tcp_should_expand_sndbuf(sk, tp)) {
+ 		int sndmem = max_t(u32, tp->rx_opt.mss_clamp, tp->mss_cache) +
 			MAX_TCP_HEADER + 16 + sizeof(struct sk_buff),
 		    demanded = max_t(unsigned int, tp->snd_cwnd,
 						   tp->reordering + 1);
@@ -3346,22 +3357,9 @@
 	}
 }
 
-static void __tcp_data_snd_check(struct sock *sk, struct sk_buff *skb)
+static __inline__ void tcp_data_snd_check(struct sock *sk, struct tcp_sock *tp)
 {
-	struct tcp_sock *tp = tcp_sk(sk);
-
-	if (after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd) ||
-	    tcp_packets_in_flight(tp) >= tp->snd_cwnd ||
-	    tcp_write_xmit(sk, tp->nonagle))
-		tcp_check_probe_timer(sk, tp);
-}
-
-static __inline__ void tcp_data_snd_check(struct sock *sk)
-{
-	struct sk_buff *skb = sk->sk_send_head;
-
-	if (skb != NULL)
-		__tcp_data_snd_check(sk, skb);
+	tcp_push_pending_frames(sk, tp);
 	tcp_check_space(sk);
 }
 
@@ -3655,7 +3653,7 @@
 				 */
 				tcp_ack(sk, skb, 0);
 				__kfree_skb(skb); 
-				tcp_data_snd_check(sk);
+				tcp_data_snd_check(sk, tp);
 				return 0;
 			} else { /* Header too small */
 				TCP_INC_STATS_BH(TCP_MIB_INERRS);
@@ -3721,7 +3719,7 @@
 			if (TCP_SKB_CB(skb)->ack_seq != tp->snd_una) {
 				/* Well, only one small jumplet in fast path... */
 				tcp_ack(sk, skb, FLAG_DATA);
-				tcp_data_snd_check(sk);
+				tcp_data_snd_check(sk, tp);
 				if (!tcp_ack_scheduled(tp))
 					goto no_ack;
 			}
@@ -3799,7 +3797,7 @@
 	/* step 7: process the segment text */
 	tcp_data_queue(sk, skb);
 
-	tcp_data_snd_check(sk);
+	tcp_data_snd_check(sk, tp);
 	tcp_ack_snd_check(sk);
 	return 0;
 
@@ -4109,7 +4107,7 @@
 		/* Do step6 onward by hand. */
 		tcp_urg(sk, skb, th);
 		__kfree_skb(skb);
-		tcp_data_snd_check(sk);
+		tcp_data_snd_check(sk, tp);
 		return 0;
 	}
 
@@ -4300,7 +4298,7 @@
 
 	/* tcp_data could move socket to TIME-WAIT */
 	if (sk->sk_state != TCP_CLOSE) {
-		tcp_data_snd_check(sk);
+		tcp_data_snd_check(sk, tp);
 		tcp_ack_snd_check(sk);
 	}
 
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index ebf1123..62f62bb 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2045,7 +2045,7 @@
 	 */
 	tp->snd_ssthresh = 0x7fffffff;	/* Infinity */
 	tp->snd_cwnd_clamp = ~0;
-	tp->mss_cache_std = tp->mss_cache = 536;
+	tp->mss_cache = 536;
 
 	tp->reordering = sysctl_tcp_reordering;
 	tp->ca_ops = &tcp_init_congestion_ops;
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 0e17c24..e041d05 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -49,7 +49,7 @@
  * will allow a single TSO frame to consume.  Building TSO frames
  * which are too large can cause TCP streams to be bursty.
  */
-int sysctl_tcp_tso_win_divisor = 8;
+int sysctl_tcp_tso_win_divisor = 3;
 
 static inline void update_send_head(struct sock *sk, struct tcp_sock *tp,
 				    struct sk_buff *skb)
@@ -140,11 +140,11 @@
 		tp->ack.pingpong = 1;
 }
 
-static __inline__ void tcp_event_ack_sent(struct sock *sk)
+static __inline__ void tcp_event_ack_sent(struct sock *sk, unsigned int pkts)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 
-	tcp_dec_quickack_mode(tp);
+	tcp_dec_quickack_mode(tp, pkts);
 	tcp_clear_xmit_timer(sk, TCP_TIME_DACK);
 }
 
@@ -355,7 +355,7 @@
 		tp->af_specific->send_check(sk, th, skb->len, skb);
 
 		if (tcb->flags & TCPCB_FLAG_ACK)
-			tcp_event_ack_sent(sk);
+			tcp_event_ack_sent(sk, tcp_skb_pcount(skb));
 
 		if (skb->len != tcp_header_size)
 			tcp_event_data_sent(tp, skb, sk);
@@ -403,42 +403,11 @@
 		sk->sk_send_head = skb;
 }
 
-static inline void tcp_tso_set_push(struct sk_buff *skb)
-{
-	/* Force push to be on for any TSO frames to workaround
-	 * problems with busted implementations like Mac OS-X that
-	 * hold off socket receive wakeups until push is seen.
-	 */
-	if (tcp_skb_pcount(skb) > 1)
-		TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
-}
-
-/* Send _single_ skb sitting at the send head. This function requires
- * true push pending frames to setup probe timer etc.
- */
-void tcp_push_one(struct sock *sk, unsigned cur_mss)
-{
-	struct tcp_sock *tp = tcp_sk(sk);
-	struct sk_buff *skb = sk->sk_send_head;
-
-	if (tcp_snd_test(sk, skb, cur_mss, TCP_NAGLE_PUSH)) {
-		/* Send it out now. */
-		TCP_SKB_CB(skb)->when = tcp_time_stamp;
-		tcp_tso_set_push(skb);
-		if (!tcp_transmit_skb(sk, skb_clone(skb, sk->sk_allocation))) {
-			sk->sk_send_head = NULL;
-			tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
-			tcp_packets_out_inc(sk, tp, skb);
-			return;
-		}
-	}
-}
-
-void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb)
+static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 
-	if (skb->len <= tp->mss_cache_std ||
+	if (skb->len <= tp->mss_cache ||
 	    !(sk->sk_route_caps & NETIF_F_TSO)) {
 		/* Avoid the costly divide in the normal
 		 * non-TSO case.
@@ -448,10 +417,10 @@
 	} else {
 		unsigned int factor;
 
-		factor = skb->len + (tp->mss_cache_std - 1);
-		factor /= tp->mss_cache_std;
+		factor = skb->len + (tp->mss_cache - 1);
+		factor /= tp->mss_cache;
 		skb_shinfo(skb)->tso_segs = factor;
-		skb_shinfo(skb)->tso_size = tp->mss_cache_std;
+		skb_shinfo(skb)->tso_size = tp->mss_cache;
 	}
 }
 
@@ -537,6 +506,7 @@
 	}
 
 	/* Link BUFF into the send queue. */
+	skb_header_release(buff);
 	__skb_append(skb, buff);
 
 	return 0;
@@ -657,7 +627,7 @@
 
 	/* And store cached results */
 	tp->pmtu_cookie = pmtu;
-	tp->mss_cache = tp->mss_cache_std = mss_now;
+	tp->mss_cache = mss_now;
 
 	return mss_now;
 }
@@ -669,59 +639,318 @@
  * cannot be large. However, taking into account rare use of URG, this
  * is not a big flaw.
  */
-
-unsigned int tcp_current_mss(struct sock *sk, int large)
+unsigned int tcp_current_mss(struct sock *sk, int large_allowed)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct dst_entry *dst = __sk_dst_get(sk);
-	unsigned int do_large, mss_now;
+	u32 mss_now;
+	u16 xmit_size_goal;
+	int doing_tso = 0;
 
-	mss_now = tp->mss_cache_std;
+	mss_now = tp->mss_cache;
+
+	if (large_allowed &&
+	    (sk->sk_route_caps & NETIF_F_TSO) &&
+	    !tp->urg_mode)
+		doing_tso = 1;
+
 	if (dst) {
 		u32 mtu = dst_mtu(dst);
 		if (mtu != tp->pmtu_cookie)
 			mss_now = tcp_sync_mss(sk, mtu);
 	}
 
-	do_large = (large &&
-		    (sk->sk_route_caps & NETIF_F_TSO) &&
-		    !tp->urg_mode);
-
-	if (do_large) {
-		unsigned int large_mss, factor, limit;
-
-		large_mss = 65535 - tp->af_specific->net_header_len -
-			tp->ext_header_len - tp->tcp_header_len;
-
-		if (tp->max_window && large_mss > (tp->max_window>>1))
-			large_mss = max((tp->max_window>>1),
-					68U - tp->tcp_header_len);
-
-		factor = large_mss / mss_now;
-
-		/* Always keep large mss multiple of real mss, but
-		 * do not exceed 1/tso_win_divisor of the congestion window
-		 * so we can keep the ACK clock ticking and minimize
-		 * bursting.
-		 */
-		limit = tp->snd_cwnd;
-		if (sysctl_tcp_tso_win_divisor)
-			limit /= sysctl_tcp_tso_win_divisor;
-		limit = max(1U, limit);
-		if (factor > limit)
-			factor = limit;
-
-		tp->mss_cache = mss_now * factor;
-
-		mss_now = tp->mss_cache;
-	}
-
 	if (tp->rx_opt.eff_sacks)
 		mss_now -= (TCPOLEN_SACK_BASE_ALIGNED +
 			    (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK));
+
+	xmit_size_goal = mss_now;
+
+	if (doing_tso) {
+		xmit_size_goal = 65535 -
+			tp->af_specific->net_header_len -
+			tp->ext_header_len - tp->tcp_header_len;
+
+		if (tp->max_window &&
+		    (xmit_size_goal > (tp->max_window >> 1)))
+			xmit_size_goal = max((tp->max_window >> 1),
+					     68U - tp->tcp_header_len);
+
+		xmit_size_goal -= (xmit_size_goal % mss_now);
+	}
+	tp->xmit_size_goal = xmit_size_goal;
+
 	return mss_now;
 }
 
+/* Congestion window validation. (RFC2861) */
+
+static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp)
+{
+	__u32 packets_out = tp->packets_out;
+
+	if (packets_out >= tp->snd_cwnd) {
+		/* Network is feed fully. */
+		tp->snd_cwnd_used = 0;
+		tp->snd_cwnd_stamp = tcp_time_stamp;
+	} else {
+		/* Network starves. */
+		if (tp->packets_out > tp->snd_cwnd_used)
+			tp->snd_cwnd_used = tp->packets_out;
+
+		if ((s32)(tcp_time_stamp - tp->snd_cwnd_stamp) >= tp->rto)
+			tcp_cwnd_application_limited(sk);
+	}
+}
+
+static unsigned int tcp_window_allows(struct tcp_sock *tp, struct sk_buff *skb, unsigned int mss_now, unsigned int cwnd)
+{
+	u32 window, cwnd_len;
+
+	window = (tp->snd_una + tp->snd_wnd - TCP_SKB_CB(skb)->seq);
+	cwnd_len = mss_now * cwnd;
+	return min(window, cwnd_len);
+}
+
+/* Can at least one segment of SKB be sent right now, according to the
+ * congestion window rules?  If so, return how many segments are allowed.
+ */
+static inline unsigned int tcp_cwnd_test(struct tcp_sock *tp, struct sk_buff *skb)
+{
+	u32 in_flight, cwnd;
+
+	/* Don't be strict about the congestion window for the final FIN.  */
+	if (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)
+		return 1;
+
+	in_flight = tcp_packets_in_flight(tp);
+	cwnd = tp->snd_cwnd;
+	if (in_flight < cwnd)
+		return (cwnd - in_flight);
+
+	return 0;
+}
+
+/* This must be invoked the first time we consider transmitting
+ * SKB onto the wire.
+ */
+static inline int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb)
+{
+	int tso_segs = tcp_skb_pcount(skb);
+
+	if (!tso_segs) {
+		tcp_set_skb_tso_segs(sk, skb);
+		tso_segs = tcp_skb_pcount(skb);
+	}
+	return tso_segs;
+}
+
+static inline int tcp_minshall_check(const struct tcp_sock *tp)
+{
+	return after(tp->snd_sml,tp->snd_una) &&
+		!after(tp->snd_sml, tp->snd_nxt);
+}
+
+/* Return 0, if packet can be sent now without violation Nagle's rules:
+ * 1. It is full sized.
+ * 2. Or it contains FIN. (already checked by caller)
+ * 3. Or TCP_NODELAY was set.
+ * 4. Or TCP_CORK is not set, and all sent packets are ACKed.
+ *    With Minshall's modification: all sent small packets are ACKed.
+ */
+
+static inline int tcp_nagle_check(const struct tcp_sock *tp,
+				  const struct sk_buff *skb, 
+				  unsigned mss_now, int nonagle)
+{
+	return (skb->len < mss_now &&
+		((nonagle&TCP_NAGLE_CORK) ||
+		 (!nonagle &&
+		  tp->packets_out &&
+		  tcp_minshall_check(tp))));
+}
+
+/* Return non-zero if the Nagle test allows this packet to be
+ * sent now.
+ */
+static inline int tcp_nagle_test(struct tcp_sock *tp, struct sk_buff *skb,
+				 unsigned int cur_mss, int nonagle)
+{
+	/* Nagle rule does not apply to frames, which sit in the middle of the
+	 * write_queue (they have no chances to get new data).
+	 *
+	 * This is implemented in the callers, where they modify the 'nonagle'
+	 * argument based upon the location of SKB in the send queue.
+	 */
+	if (nonagle & TCP_NAGLE_PUSH)
+		return 1;
+
+	/* Don't use the nagle rule for urgent data (or for the final FIN).  */
+	if (tp->urg_mode ||
+	    (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN))
+		return 1;
+
+	if (!tcp_nagle_check(tp, skb, cur_mss, nonagle))
+		return 1;
+
+	return 0;
+}
+
+/* Does at least the first segment of SKB fit into the send window? */
+static inline int tcp_snd_wnd_test(struct tcp_sock *tp, struct sk_buff *skb, unsigned int cur_mss)
+{
+	u32 end_seq = TCP_SKB_CB(skb)->end_seq;
+
+	if (skb->len > cur_mss)
+		end_seq = TCP_SKB_CB(skb)->seq + cur_mss;
+
+	return !after(end_seq, tp->snd_una + tp->snd_wnd);
+}
+
+/* This checks if the data bearing packet SKB (usually sk->sk_send_head)
+ * should be put on the wire right now.  If so, it returns the number of
+ * packets allowed by the congestion window.
+ */
+static unsigned int tcp_snd_test(struct sock *sk, struct sk_buff *skb,
+				 unsigned int cur_mss, int nonagle)
+{
+	struct tcp_sock *tp = tcp_sk(sk);
+	unsigned int cwnd_quota;
+
+	tcp_init_tso_segs(sk, skb);
+
+	if (!tcp_nagle_test(tp, skb, cur_mss, nonagle))
+		return 0;
+
+	cwnd_quota = tcp_cwnd_test(tp, skb);
+	if (cwnd_quota &&
+	    !tcp_snd_wnd_test(tp, skb, cur_mss))
+		cwnd_quota = 0;
+
+	return cwnd_quota;
+}
+
+static inline int tcp_skb_is_last(const struct sock *sk, 
+				  const struct sk_buff *skb)
+{
+	return skb->next == (struct sk_buff *)&sk->sk_write_queue;
+}
+
+int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp)
+{
+	struct sk_buff *skb = sk->sk_send_head;
+
+	return (skb &&
+		tcp_snd_test(sk, skb, tcp_current_mss(sk, 1),
+			     (tcp_skb_is_last(sk, skb) ?
+			      TCP_NAGLE_PUSH :
+			      tp->nonagle)));
+}
+
+/* Trim TSO SKB to LEN bytes, put the remaining data into a new packet
+ * which is put after SKB on the list.  It is very much like
+ * tcp_fragment() except that it may make several kinds of assumptions
+ * in order to speed up the splitting operation.  In particular, we
+ * know that all the data is in scatter-gather pages, and that the
+ * packet has never been sent out before (and thus is not cloned).
+ */
+static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len)
+{
+	struct sk_buff *buff;
+	int nlen = skb->len - len;
+	u16 flags;
+
+	/* All of a TSO frame must be composed of paged data.  */
+	BUG_ON(skb->len != skb->data_len);
+
+	buff = sk_stream_alloc_pskb(sk, 0, 0, GFP_ATOMIC);
+	if (unlikely(buff == NULL))
+		return -ENOMEM;
+
+	buff->truesize = nlen;
+	skb->truesize -= nlen;
+
+	/* Correct the sequence numbers. */
+	TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len;
+	TCP_SKB_CB(buff)->end_seq = TCP_SKB_CB(skb)->end_seq;
+	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq;
+
+	/* PSH and FIN should only be set in the second packet. */
+	flags = TCP_SKB_CB(skb)->flags;
+	TCP_SKB_CB(skb)->flags = flags & ~(TCPCB_FLAG_FIN|TCPCB_FLAG_PSH);
+	TCP_SKB_CB(buff)->flags = flags;
+
+	/* This packet was never sent out yet, so no SACK bits. */
+	TCP_SKB_CB(buff)->sacked = 0;
+
+	buff->ip_summed = skb->ip_summed = CHECKSUM_HW;
+	skb_split(skb, buff, len);
+
+	/* Fix up tso_factor for both original and new SKB.  */
+	tcp_set_skb_tso_segs(sk, skb);
+	tcp_set_skb_tso_segs(sk, buff);
+
+	/* Link BUFF into the send queue. */
+	skb_header_release(buff);
+	__skb_append(skb, buff);
+
+	return 0;
+}
+
+/* Try to defer sending, if possible, in order to minimize the amount
+ * of TSO splitting we do.  View it as a kind of TSO Nagle test.
+ *
+ * This algorithm is from John Heffner.
+ */
+static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_buff *skb)
+{
+	u32 send_win, cong_win, limit, in_flight;
+
+	if (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)
+		return 0;
+
+	if (tp->ca_state != TCP_CA_Open)
+		return 0;
+
+	in_flight = tcp_packets_in_flight(tp);
+
+	BUG_ON(tcp_skb_pcount(skb) <= 1 ||
+	       (tp->snd_cwnd <= in_flight));
+
+	send_win = (tp->snd_una + tp->snd_wnd) - TCP_SKB_CB(skb)->seq;
+
+	/* From in_flight test above, we know that cwnd > in_flight.  */
+	cong_win = (tp->snd_cwnd - in_flight) * tp->mss_cache;
+
+	limit = min(send_win, cong_win);
+
+	/* If sk_send_head can be sent fully now, just do it.  */
+	if (skb->len <= limit)
+		return 0;
+
+	if (sysctl_tcp_tso_win_divisor) {
+		u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache);
+
+		/* If at least some fraction of a window is available,
+		 * just use it.
+		 */
+		chunk /= sysctl_tcp_tso_win_divisor;
+		if (limit >= chunk)
+			return 0;
+	} else {
+		/* Different approach, try not to defer past a single
+		 * ACK.  Receiver should ACK every other full sized
+		 * frame, so if we have space for more than 3 frames
+		 * then send now.
+		 */
+		if (limit > tcp_max_burst(tp) * tp->mss_cache)
+			return 0;
+	}
+
+	/* Ok, it looks like it is advisable to defer.  */
+	return 1;
+}
+
 /* This routine writes packets to the network.  It advances the
  * send_head.  This happens as incoming acks open up the remote
  * window for us.
@@ -729,57 +958,158 @@
  * Returns 1, if no segments are in flight and we have queued segments, but
  * cannot send anything now because of SWS or another problem.
  */
-int tcp_write_xmit(struct sock *sk, int nonagle)
+static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	unsigned int mss_now;
+	struct sk_buff *skb;
+	unsigned int tso_segs, sent_pkts;
+	int cwnd_quota;
 
 	/* If we are closed, the bytes will have to remain here.
 	 * In time closedown will finish, we empty the write queue and all
 	 * will be happy.
 	 */
-	if (sk->sk_state != TCP_CLOSE) {
-		struct sk_buff *skb;
-		int sent_pkts = 0;
+	if (unlikely(sk->sk_state == TCP_CLOSE))
+		return 0;
 
-		/* Account for SACKS, we may need to fragment due to this.
-		 * It is just like the real MSS changing on us midstream.
-		 * We also handle things correctly when the user adds some
-		 * IP options mid-stream.  Silly to do, but cover it.
-		 */
-		mss_now = tcp_current_mss(sk, 1);
+	skb = sk->sk_send_head;
+	if (unlikely(!skb))
+		return 0;
 
-		while ((skb = sk->sk_send_head) &&
-		       tcp_snd_test(sk, skb, mss_now,
-			       	    tcp_skb_is_last(sk, skb) ? nonagle :
-				    			       TCP_NAGLE_PUSH)) {
-			if (skb->len > mss_now) {
-				if (tcp_fragment(sk, skb, mss_now))
+	tso_segs = tcp_init_tso_segs(sk, skb);
+	cwnd_quota = tcp_cwnd_test(tp, skb);
+	if (unlikely(!cwnd_quota))
+		goto out;
+
+	sent_pkts = 0;
+	while (likely(tcp_snd_wnd_test(tp, skb, mss_now))) {
+		BUG_ON(!tso_segs);
+
+		if (tso_segs == 1) {
+			if (unlikely(!tcp_nagle_test(tp, skb, mss_now,
+						     (tcp_skb_is_last(sk, skb) ?
+						      nonagle : TCP_NAGLE_PUSH))))
+				break;
+		} else {
+			if (tcp_tso_should_defer(sk, tp, skb))
+				break;
+		}
+
+		if (tso_segs > 1) {
+			u32 limit = tcp_window_allows(tp, skb,
+						      mss_now, cwnd_quota);
+
+			if (skb->len < limit) {
+				unsigned int trim = skb->len % mss_now;
+
+				if (trim)
+					limit = skb->len - trim;
+			}
+			if (skb->len > limit) {
+				if (tso_fragment(sk, skb, limit))
 					break;
 			}
-
-			TCP_SKB_CB(skb)->when = tcp_time_stamp;
-			tcp_tso_set_push(skb);
-			if (tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)))
+		} else if (unlikely(skb->len > mss_now)) {
+			if (unlikely(tcp_fragment(sk, skb,  mss_now)))
 				break;
-
-			/* Advance the send_head.  This one is sent out.
-			 * This call will increment packets_out.
-			 */
-			update_send_head(sk, tp, skb);
-
-			tcp_minshall_update(tp, mss_now, skb);
-			sent_pkts = 1;
 		}
 
-		if (sent_pkts) {
-			tcp_cwnd_validate(sk, tp);
-			return 0;
-		}
+		TCP_SKB_CB(skb)->when = tcp_time_stamp;
 
-		return !tp->packets_out && sk->sk_send_head;
+		if (unlikely(tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC))))
+			break;
+
+		/* Advance the send_head.  This one is sent out.
+		 * This call will increment packets_out.
+		 */
+		update_send_head(sk, tp, skb);
+
+		tcp_minshall_update(tp, mss_now, skb);
+		sent_pkts++;
+
+		/* Do not optimize this to use tso_segs. If we chopped up
+		 * the packet above, tso_segs will no longer be valid.
+		 */
+		cwnd_quota -= tcp_skb_pcount(skb);
+
+		BUG_ON(cwnd_quota < 0);
+		if (!cwnd_quota)
+			break;
+
+		skb = sk->sk_send_head;
+		if (!skb)
+			break;
+		tso_segs = tcp_init_tso_segs(sk, skb);
 	}
-	return 0;
+
+	if (likely(sent_pkts)) {
+		tcp_cwnd_validate(sk, tp);
+		return 0;
+	}
+out:
+	return !tp->packets_out && sk->sk_send_head;
+}
+
+/* Push out any pending frames which were held back due to
+ * TCP_CORK or attempt at coalescing tiny packets.
+ * The socket must be locked by the caller.
+ */
+void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp,
+			       unsigned int cur_mss, int nonagle)
+{
+	struct sk_buff *skb = sk->sk_send_head;
+
+	if (skb) {
+		if (tcp_write_xmit(sk, cur_mss, nonagle))
+			tcp_check_probe_timer(sk, tp);
+	}
+}
+
+/* Send _single_ skb sitting at the send head. This function requires
+ * true push pending frames to setup probe timer etc.
+ */
+void tcp_push_one(struct sock *sk, unsigned int mss_now)
+{
+	struct tcp_sock *tp = tcp_sk(sk);
+	struct sk_buff *skb = sk->sk_send_head;
+	unsigned int tso_segs, cwnd_quota;
+
+	BUG_ON(!skb || skb->len < mss_now);
+
+	tso_segs = tcp_init_tso_segs(sk, skb);
+	cwnd_quota = tcp_snd_test(sk, skb, mss_now, TCP_NAGLE_PUSH);
+
+	if (likely(cwnd_quota)) {
+		BUG_ON(!tso_segs);
+
+		if (tso_segs > 1) {
+			u32 limit = tcp_window_allows(tp, skb,
+						      mss_now, cwnd_quota);
+
+			if (skb->len < limit) {
+				unsigned int trim = skb->len % mss_now;
+
+				if (trim)
+					limit = skb->len - trim;
+			}
+			if (skb->len > limit) {
+				if (unlikely(tso_fragment(sk, skb, limit)))
+					return;
+			}
+		} else if (unlikely(skb->len > mss_now)) {
+			if (unlikely(tcp_fragment(sk, skb, mss_now)))
+				return;
+		}
+
+		/* Send it out now. */
+		TCP_SKB_CB(skb)->when = tcp_time_stamp;
+
+		if (likely(!tcp_transmit_skb(sk, skb_clone(skb, sk->sk_allocation)))) {
+			update_send_head(sk, tp, skb);
+			tcp_cwnd_validate(sk, tp);
+			return;
+		}
+	}
 }
 
 /* This function returns the amount that we can raise the
@@ -1039,7 +1369,6 @@
 		if (sk->sk_route_caps & NETIF_F_TSO) {
 			sk->sk_route_caps &= ~NETIF_F_TSO;
 			sock_set_flag(sk, SOCK_NO_LARGESEND);
-			tp->mss_cache = tp->mss_cache_std;
 		}
 
 		if (tcp_trim_head(sk, skb, tp->snd_una - TCP_SKB_CB(skb)->seq))
@@ -1101,7 +1430,6 @@
 	 * is still in somebody's hands, else make a clone.
 	 */
 	TCP_SKB_CB(skb)->when = tcp_time_stamp;
-	tcp_tso_set_push(skb);
 
 	err = tcp_transmit_skb(sk, (skb_cloned(skb) ?
 				    pskb_copy(skb, GFP_ATOMIC):
@@ -1670,14 +1998,12 @@
 				if (sk->sk_route_caps & NETIF_F_TSO) {
 					sock_set_flag(sk, SOCK_NO_LARGESEND);
 					sk->sk_route_caps &= ~NETIF_F_TSO;
-					tp->mss_cache = tp->mss_cache_std;
 				}
 			} else if (!tcp_skb_pcount(skb))
 				tcp_set_skb_tso_segs(sk, skb);
 
 			TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
 			TCP_SKB_CB(skb)->when = tcp_time_stamp;
-			tcp_tso_set_push(skb);
 			err = tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
 			if (!err) {
 				update_send_head(sk, tp, skb);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index a54d4ef..77004b9 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2777,7 +2777,7 @@
 		read_lock_bh(&idev->lock);
 		switch (type) {
 		case UNICAST_ADDR:
-			/* unicast address */
+			/* unicast address incl. temp addr */
 			for (ifa = idev->addr_list; ifa;
 			     ifa = ifa->if_next, ip_idx++) {
 				if (ip_idx < s_ip_idx)
@@ -2788,19 +2788,6 @@
 				    NLM_F_MULTI)) <= 0)
 					goto done;
 			}
-			/* temp addr */
-#ifdef CONFIG_IPV6_PRIVACY
-			for (ifa = idev->tempaddr_list; ifa; 
-			     ifa = ifa->tmp_next, ip_idx++) {
-				if (ip_idx < s_ip_idx)
-					continue;
-				if ((err = inet6_fill_ifaddr(skb, ifa, 
-				    NETLINK_CB(cb->skb).pid, 
-				    cb->nlh->nlmsg_seq, RTM_NEWADDR,
-				    NLM_F_MULTI)) <= 0) 
-					goto done;
-			}
-#endif
 			break;
 		case MULTICAST_ADDR:
 			/* multicast address */
@@ -2923,6 +2910,7 @@
 	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags);
 	r = NLMSG_DATA(nlh);
 	r->ifi_family = AF_INET6;
+	r->__ifi_pad = 0;
 	r->ifi_type = dev->type;
 	r->ifi_index = dev->ifindex;
 	r->ifi_flags = dev_get_flags(dev);
@@ -3030,9 +3018,12 @@
 	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*pmsg), flags);
 	pmsg = NLMSG_DATA(nlh);
 	pmsg->prefix_family = AF_INET6;
+	pmsg->prefix_pad1 = 0;
+	pmsg->prefix_pad2 = 0;
 	pmsg->prefix_ifindex = idev->dev->ifindex;
 	pmsg->prefix_len = pinfo->prefix_len;
 	pmsg->prefix_type = pinfo->type;
+	pmsg->prefix_pad3 = 0;
 	
 	pmsg->prefix_flags = 0;
 	if (pinfo->onlink)
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 2b193e3..28d9bca 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -774,7 +774,6 @@
 	if (if6_proc_init())
 		goto proc_if6_fail;
 #endif
-	ipv6_packet_init();
 	ip6_route_init();
 	ip6_flowlabel_init();
 	err = addrconf_init();
@@ -791,6 +790,8 @@
 	/* Init v6 transport protocols. */
 	udpv6_init();
 	tcpv6_init();
+
+	ipv6_packet_init();
 	err = 0;
 out:
 	return err;
@@ -798,7 +799,6 @@
 addrconf_fail:
 	ip6_flowlabel_cleanup();
 	ip6_route_cleanup();
-	ipv6_packet_cleanup();
 #ifdef CONFIG_PROC_FS
 	if6_proc_exit();
 proc_if6_fail:
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 0e5f7499..b6c73da5 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -244,7 +244,6 @@
 		opt_space->opt_nflen = 0;
 	}
 	opt_space->dst1opt = fopt->dst1opt;
-	opt_space->auth = fopt->auth;
 	opt_space->opt_flen = fopt->opt_flen;
 	return opt_space;
 }
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 06e7cdae..1f2c2f9 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -465,7 +465,6 @@
 	to->pkt_type = from->pkt_type;
 	to->priority = from->priority;
 	to->protocol = from->protocol;
-	to->security = from->security;
 	dst_release(to->dst);
 	to->dst = dst_clone(from->dst);
 	to->dev = from->dev;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 9dac7fd..f6e288d 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -2018,7 +2018,7 @@
 	 */
 	tp->snd_ssthresh = 0x7fffffff;
 	tp->snd_cwnd_clamp = ~0;
-	tp->mss_cache_std = tp->mss_cache = 536;
+	tp->mss_cache = 536;
 
 	tp->reordering = sysctl_tcp_reordering;
 
diff --git a/net/sched/Makefile b/net/sched/Makefile
index 8f58cec..e48d0d4 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -4,7 +4,7 @@
 
 obj-y	:= sch_generic.o
 
-obj-$(CONFIG_NET_SCHED)		+= sch_api.o sch_fifo.o
+obj-$(CONFIG_NET_SCHED)		+= sch_api.o sch_fifo.o sch_blackhole.o
 obj-$(CONFIG_NET_CLS)		+= cls_api.o
 obj-$(CONFIG_NET_CLS_ACT)	+= act_api.o
 obj-$(CONFIG_NET_ACT_POLICE)	+= police.o
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 9594206..249c619 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -439,6 +439,8 @@
 
 	t = NLMSG_DATA(nlh);
 	t->tca_family = AF_UNSPEC;
+	t->tca__pad1 = 0;
+	t->tca__pad2 = 0;
 	
 	x = (struct rtattr*) skb->tail;
 	RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
@@ -580,6 +582,8 @@
 	nlh = NLMSG_PUT(skb, pid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t));
 	t = NLMSG_DATA(nlh);
 	t->tca_family = AF_UNSPEC;
+	t->tca__pad1 = 0;
+	t->tca__pad2 = 0;
 
 	x = (struct rtattr *) skb->tail;
 	RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
@@ -687,7 +691,9 @@
 	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags);
 	t = NLMSG_DATA(nlh);
 	t->tca_family = AF_UNSPEC;
-	
+	t->tca__pad1 = 0;
+	t->tca__pad2 = 0;
+
 	x = (struct rtattr*) skb->tail;
 	RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
 
@@ -842,6 +848,8 @@
 	                cb->nlh->nlmsg_type, sizeof(*t));
 	t = NLMSG_DATA(nlh);
 	t->tca_family = AF_UNSPEC;
+	t->tca__pad1 = 0;
+	t->tca__pad2 = 0;
 
 	x = (struct rtattr *) skb->tail;
 	RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 1616bf5..3b5714e 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -331,6 +331,8 @@
 	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags);
 	tcm = NLMSG_DATA(nlh);
 	tcm->tcm_family = AF_UNSPEC;
+	tcm->tcm__pad1 = 0;
+	tcm->tcm__pad1 = 0;
 	tcm->tcm_ifindex = tp->q->dev->ifindex;
 	tcm->tcm_parent = tp->classid;
 	tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol);
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index 232fb91..006168d 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -618,6 +618,7 @@
 	pinfo.protocol = s->protocol;
 	pinfo.tunnelid = s->tunnelid;
 	pinfo.tunnelhdr = f->tunnelhdr;
+	pinfo.pad = 0;
 	RTA_PUT(skb, TCA_RSVP_PINFO, sizeof(pinfo), &pinfo);
 	if (f->res.classid)
 		RTA_PUT(skb, TCA_RSVP_CLASSID, 4, &f->res.classid);
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index 48bb23c..53d98f8 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -205,11 +205,6 @@
 	dst->value = skb->protocol;
 }
 
-META_COLLECTOR(int_security)
-{
-	dst->value = skb->security;
-}
-
 META_COLLECTOR(int_pkttype)
 {
 	dst->value = skb->pkt_type;
@@ -524,7 +519,6 @@
 		[META_ID(REALDEV)]		= META_FUNC(int_realdev),
 		[META_ID(PRIORITY)]		= META_FUNC(int_priority),
 		[META_ID(PROTOCOL)]		= META_FUNC(int_protocol),
-		[META_ID(SECURITY)]		= META_FUNC(int_security),
 		[META_ID(PKTTYPE)]		= META_FUNC(int_pkttype),
 		[META_ID(PKTLEN)]		= META_FUNC(int_pktlen),
 		[META_ID(DATALEN)]		= META_FUNC(int_datalen),
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 97c1c75..b9a069a 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -399,10 +399,8 @@
 {
 	int err;
 	struct rtattr *kind = tca[TCA_KIND-1];
-	void *p = NULL;
 	struct Qdisc *sch;
 	struct Qdisc_ops *ops;
-	int size;
 
 	ops = qdisc_lookup_ops(kind);
 #ifdef CONFIG_KMOD
@@ -437,64 +435,55 @@
 	if (ops == NULL)
 		goto err_out;
 
-	/* ensure that the Qdisc and the private data are 32-byte aligned */
-	size = ((sizeof(*sch) + QDISC_ALIGN_CONST) & ~QDISC_ALIGN_CONST);
-	size += ops->priv_size + QDISC_ALIGN_CONST;
-
-	p = kmalloc(size, GFP_KERNEL);
-	err = -ENOBUFS;
-	if (!p)
+	sch = qdisc_alloc(dev, ops);
+	if (IS_ERR(sch)) {
+		err = PTR_ERR(sch);
 		goto err_out2;
-	memset(p, 0, size);
-	sch = (struct Qdisc *)(((unsigned long)p + QDISC_ALIGN_CONST)
-	                       & ~QDISC_ALIGN_CONST);
-	sch->padded = (char *)sch - (char *)p;
+	}
 
-	INIT_LIST_HEAD(&sch->list);
-	skb_queue_head_init(&sch->q);
-
-	if (handle == TC_H_INGRESS)
+	if (handle == TC_H_INGRESS) {
 		sch->flags |= TCQ_F_INGRESS;
-
-	sch->ops = ops;
-	sch->enqueue = ops->enqueue;
-	sch->dequeue = ops->dequeue;
-	sch->dev = dev;
-	dev_hold(dev);
-	atomic_set(&sch->refcnt, 1);
-	sch->stats_lock = &dev->queue_lock;
-	if (handle == 0) {
+		handle = TC_H_MAKE(TC_H_INGRESS, 0);
+	} else if (handle == 0) {
 		handle = qdisc_alloc_handle(dev);
 		err = -ENOMEM;
 		if (handle == 0)
 			goto err_out3;
 	}
 
-	if (handle == TC_H_INGRESS)
-                sch->handle =TC_H_MAKE(TC_H_INGRESS, 0);
-        else
-                sch->handle = handle;
+	sch->handle = handle;
 
 	if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) {
+#ifdef CONFIG_NET_ESTIMATOR
+		if (tca[TCA_RATE-1]) {
+			err = gen_new_estimator(&sch->bstats, &sch->rate_est,
+						sch->stats_lock,
+						tca[TCA_RATE-1]);
+			if (err) {
+				/*
+				 * Any broken qdiscs that would require
+				 * a ops->reset() here? The qdisc was never
+				 * in action so it shouldn't be necessary.
+				 */
+				if (ops->destroy)
+					ops->destroy(sch);
+				goto err_out3;
+			}
+		}
+#endif
 		qdisc_lock_tree(dev);
 		list_add_tail(&sch->list, &dev->qdisc_list);
 		qdisc_unlock_tree(dev);
 
-#ifdef CONFIG_NET_ESTIMATOR
-		if (tca[TCA_RATE-1])
-			gen_new_estimator(&sch->bstats, &sch->rate_est,
-				sch->stats_lock, tca[TCA_RATE-1]);
-#endif
 		return sch;
 	}
 err_out3:
 	dev_put(dev);
+	kfree((char *) sch - sch->padded);
 err_out2:
 	module_put(ops->owner);
 err_out:
 	*errp = err;
-	if (p)
-		kfree(p);
 	return NULL;
 }
 
@@ -770,6 +759,8 @@
 	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags);
 	tcm = NLMSG_DATA(nlh);
 	tcm->tcm_family = AF_UNSPEC;
+	tcm->tcm__pad1 = 0;
+	tcm->tcm__pad2 = 0;
 	tcm->tcm_ifindex = q->dev->ifindex;
 	tcm->tcm_parent = clid;
 	tcm->tcm_handle = q->handle;
diff --git a/net/sched/sch_blackhole.c b/net/sched/sch_blackhole.c
new file mode 100644
index 0000000..81f0b83
--- /dev/null
+++ b/net/sched/sch_blackhole.c
@@ -0,0 +1,54 @@
+/*
+ * net/sched/sch_blackhole.c	Black hole queue
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ *
+ * Authors:	Thomas Graf <tgraf@suug.ch>
+ *
+ * Note: Quantum tunneling is not supported.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <net/pkt_sched.h>
+
+static int blackhole_enqueue(struct sk_buff *skb, struct Qdisc *sch)
+{
+	qdisc_drop(skb, sch);
+	return NET_XMIT_SUCCESS;
+}
+
+static struct sk_buff *blackhole_dequeue(struct Qdisc *sch)
+{
+	return NULL;
+}
+
+static struct Qdisc_ops blackhole_qdisc_ops = {
+	.id		= "blackhole",
+	.priv_size	= 0,
+	.enqueue	= blackhole_enqueue,
+	.dequeue	= blackhole_dequeue,
+	.owner		= THIS_MODULE,
+};
+
+static int __init blackhole_module_init(void)
+{
+	return register_qdisc(&blackhole_qdisc_ops);
+}
+
+static void __exit blackhole_module_exit(void)
+{
+	unregister_qdisc(&blackhole_qdisc_ops);
+}
+
+module_init(blackhole_module_init)
+module_exit(blackhole_module_exit)
+
+MODULE_LICENSE("GPL");
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index d43e3b8..09453f9 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1528,6 +1528,7 @@
 
 	opt.strategy = cl->ovl_strategy;
 	opt.priority2 = cl->priority2+1;
+	opt.pad = 0;
 	opt.penalty = (cl->penalty*1000)/HZ;
 	RTA_PUT(skb, TCA_CBQ_OVL_STRATEGY, sizeof(opt), &opt);
 	return skb->len;
@@ -1563,6 +1564,8 @@
 
 	if (cl->police) {
 		opt.police = cl->police;
+		opt.__res1 = 0;
+		opt.__res2 = 0;
 		RTA_PUT(skb, TCA_CBQ_POLICE, sizeof(opt), &opt);
 	}
 	return skb->len;
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 7683b34..73e218e 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -395,24 +395,23 @@
 	.owner		=	THIS_MODULE,
 };
 
-struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops)
+struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops)
 {
 	void *p;
 	struct Qdisc *sch;
-	int size;
+	unsigned int size;
+	int err = -ENOBUFS;
 
 	/* ensure that the Qdisc and the private data are 32-byte aligned */
-	size = ((sizeof(*sch) + QDISC_ALIGN_CONST) & ~QDISC_ALIGN_CONST);
-	size += ops->priv_size + QDISC_ALIGN_CONST;
+	size = QDISC_ALIGN(sizeof(*sch));
+	size += ops->priv_size + (QDISC_ALIGNTO - 1);
 
 	p = kmalloc(size, GFP_KERNEL);
 	if (!p)
-		return NULL;
+		goto errout;
 	memset(p, 0, size);
-
-	sch = (struct Qdisc *)(((unsigned long)p + QDISC_ALIGN_CONST) 
-			       & ~QDISC_ALIGN_CONST);
-	sch->padded = (char *)sch - (char *)p;
+	sch = (struct Qdisc *) QDISC_ALIGN((unsigned long) p);
+	sch->padded = (char *) sch - (char *) p;
 
 	INIT_LIST_HEAD(&sch->list);
 	skb_queue_head_init(&sch->q);
@@ -423,11 +422,24 @@
 	dev_hold(dev);
 	sch->stats_lock = &dev->queue_lock;
 	atomic_set(&sch->refcnt, 1);
+
+	return sch;
+errout:
+	return ERR_PTR(-err);
+}
+
+struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops)
+{
+	struct Qdisc *sch;
+	
+	sch = qdisc_alloc(dev, ops);
+	if (IS_ERR(sch))
+		goto errout;
+
 	if (!ops->init || ops->init(sch, NULL) == 0)
 		return sch;
 
-	dev_put(dev);
-	kfree(p);
+errout:
 	return NULL;
 }
 
@@ -591,6 +603,7 @@
 EXPORT_SYMBOL(noop_qdisc);
 EXPORT_SYMBOL(noop_qdisc_ops);
 EXPORT_SYMBOL(qdisc_create_dflt);
+EXPORT_SYMBOL(qdisc_alloc);
 EXPORT_SYMBOL(qdisc_destroy);
 EXPORT_SYMBOL(qdisc_reset);
 EXPORT_SYMBOL(qdisc_restart);
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 2ec0320..c44bf41 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -102,9 +102,9 @@
 	/* Set up the base timeout information.  */
 	ep->timeouts[SCTP_EVENT_TIMEOUT_NONE] = 0;
 	ep->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] =
-		SCTP_DEFAULT_TIMEOUT_T1_COOKIE;
+		msecs_to_jiffies(sp->rtoinfo.srto_initial);
 	ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] =
-		SCTP_DEFAULT_TIMEOUT_T1_INIT;
+		msecs_to_jiffies(sp->rtoinfo.srto_initial);
 	ep->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] =
 		msecs_to_jiffies(sp->rtoinfo.srto_initial);
 	ep->timeouts[SCTP_EVENT_TIMEOUT_T3_RTX] = 0;
@@ -117,12 +117,9 @@
         ep->timeouts[SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD]
 		= 5 * msecs_to_jiffies(sp->rtoinfo.srto_max);
 
-	ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] =
-		SCTP_DEFAULT_TIMEOUT_HEARTBEAT;
-	ep->timeouts[SCTP_EVENT_TIMEOUT_SACK] =
-		SCTP_DEFAULT_TIMEOUT_SACK;
-	ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] =
-		sp->autoclose * HZ;
+	ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0;
+	ep->timeouts[SCTP_EVENT_TIMEOUT_SACK] = sctp_sack_timeout;
+	ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = sp->autoclose * HZ;
 
 	/* Use SCTP specific send buffer space queues.  */
 	ep->sndbuf_policy = sctp_sndbuf_policy;
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 5135e1a..e7f37fa 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1050,7 +1050,10 @@
 	sctp_sndbuf_policy		= 0;
 
 	/* HB.interval              - 30 seconds */
-	sctp_hb_interval		= 30 * HZ;
+	sctp_hb_interval		= SCTP_DEFAULT_TIMEOUT_HEARTBEAT;
+
+	/* delayed SACK timeout */
+	sctp_sack_timeout		= SCTP_DEFAULT_TIMEOUT_SACK;
 
 	/* Implementation specific variables. */
 
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index 7fc3184..dc48934 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -47,6 +47,8 @@
 static ctl_handler sctp_sysctl_jiffies_ms;
 static long rto_timer_min = 1;
 static long rto_timer_max = 86400000; /* One day */
+static long sack_timer_min = 1;
+static long sack_timer_max = 500;
 
 static ctl_table sctp_table[] = {
 	{
@@ -187,6 +189,17 @@
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec
 	},
+	{
+		.ctl_name	= NET_SCTP_SACK_TIMEOUT,
+		.procname	= "sack_timeout",
+		.data		= &sctp_sack_timeout,
+		.maxlen		= sizeof(long),
+		.mode		= 0644,
+		.proc_handler	= &proc_doulongvec_ms_jiffies_minmax,
+		.strategy	= &sctp_sysctl_jiffies_ms,
+		.extra1         = &sack_timer_min,
+		.extra2         = &sack_timer_max,
+	},
 	{ .ctl_name = 0 }
 };
 
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 0ec0fde..a63b691 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -103,7 +103,6 @@
 
 	/* Set up the heartbeat timer. */
 	init_timer(&peer->hb_timer);
-	peer->hb_interval = SCTP_DEFAULT_TIMEOUT_HEARTBEAT;
 	peer->hb_timer.function = sctp_generate_heartbeat_event;
 	peer->hb_timer.data = (unsigned long)peer;
 
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 908bff6..5180405 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -25,6 +25,8 @@
 #include <stdint.h>
 #endif
 
+#include <ctype.h>
+
 typedef uint32_t	__u32;
 typedef uint16_t	__u16;
 typedef unsigned char	__u8;
@@ -323,6 +325,22 @@
 
 
 
+static int do_of_entry (const char *filename, struct of_device_id *of, char *alias)
+{
+    char *tmp;
+    sprintf (alias, "of:N%sT%sC%s",
+                    of->name[0] ? of->name : "*",
+                    of->type[0] ? of->type : "*",
+                    of->compatible[0] ? of->compatible : "*");
+
+    /* Replace all whitespace with underscores */
+    for (tmp = alias; tmp && *tmp; tmp++)
+        if (isspace (*tmp))
+            *tmp = '_';
+
+    return 1;
+}
+
 /* Ignore any prefix, eg. v850 prepends _ */
 static inline int sym_is(const char *symbol, const char *name)
 {
@@ -401,6 +419,10 @@
 	else if (sym_is(symname, "__mod_pcmcia_device_table"))
 		do_table(symval, sym->st_size, sizeof(struct pcmcia_device_id),
 			 do_pcmcia_entry, mod);
+        else if (sym_is(symname, "__mod_of_device_table"))
+		do_table(symval, sym->st_size, sizeof(struct of_device_id),
+			 do_of_entry, mod);
+
 }
 
 /* Now add out buffered information to the generated C source */
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 17a1189..6be2738 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -68,6 +68,7 @@
 #include <linux/personality.h>
 #include <linux/sysctl.h>
 #include <linux/audit.h>
+#include <linux/string.h>
 
 #include "avc.h"
 #include "objsec.h"
@@ -1943,7 +1944,7 @@
 		}
 	} while (*in_end++);
 
-	copy_page(in_save, nosec_save);
+	strcpy(in_save, nosec_save);
 	free_page((unsigned long)nosec_save);
 out:
 	return rc;
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index defdc5a..c5557ea 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -798,13 +798,15 @@
 	{0x270f, 0xfc00}, /* Chaintech Digitop DST-1000 DVB-S */
 };
 
+static struct pci_driver driver;
+
 /* return the rate of the card, or a negative value if it's blacklisted */
 static int __devinit snd_bt87x_detect_card(struct pci_dev *pci)
 {
 	int i;
 	const struct pci_device_id *supported;
 
-	supported = pci_match_device(snd_bt87x_ids, pci);
+	supported = pci_match_device(&driver, pci);
 	if (supported)
 		return supported->driver_data;