Merge branch 'linux-2.6' into for-2.6.22
diff --git a/Documentation/ABI/obsolete/dv1394 b/Documentation/ABI/obsolete/dv1394
new file mode 100644
index 0000000..2ee3686
--- /dev/null
+++ b/Documentation/ABI/obsolete/dv1394
@@ -0,0 +1,9 @@
+What:		dv1394 (a.k.a. "OHCI-DV I/O support" for FireWire)
+Contact:	linux1394-devel@lists.sourceforge.net
+Description:
+	New application development should use raw1394 + userspace libraries
+	instead, notably libiec61883 which is functionally equivalent.
+
+Users:
+	ffmpeg/libavformat (used by a variety of media players)
+	dvgrab v1.x (replaced by dvgrab2 on top of raw1394 and resp. libraries)
diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt
index 842f0d1..f2c0a68 100644
--- a/Documentation/cpusets.txt
+++ b/Documentation/cpusets.txt
@@ -557,6 +557,9 @@
 Add some cpus:
 # /bin/echo 0-7 > cpus
 
+Add some mems:
+# /bin/echo 0-7 > mems
+
 Now attach your shell to this cpuset:
 # /bin/echo $$ > tasks
 
diff --git a/Documentation/crypto/api-intro.txt b/Documentation/crypto/api-intro.txt
index e41a79a..9b84b805 100644
--- a/Documentation/crypto/api-intro.txt
+++ b/Documentation/crypto/api-intro.txt
@@ -60,7 +60,7 @@
 	desc.tfm = tfm;
 	desc.flags = 0;
 	
-	if (crypto_hash_digest(&desc, &sg, 2, result))
+	if (crypto_hash_digest(&desc, sg, 2, result))
 		fail();
 	
 	crypto_free_hash(tfm);
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index c3b1430..19b4c96 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -39,17 +39,6 @@
 
 ---------------------------
 
-What:	dv1394 driver (CONFIG_IEEE1394_DV1394)
-When:	June 2007
-Why:	Replaced by raw1394 + userspace libraries, notably libiec61883.  This
-	shift of application support has been indicated on www.linux1394.org
-	and developers' mailinglists for quite some time.  Major applications
-	have been converted, with the exception of ffmpeg and hence xine.
-	Piped output of dvgrab2 is a partial equivalent to dv1394.
-Who:	Dan Dennedy <dan@dennedy.org>, Stefan Richter <stefanr@s5r6.in-berlin.de>
-
----------------------------
-
 What:	Video4Linux API 1 ioctls and video_decoder.h from Video devices.
 When:	December 2006
 Why:	V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6
@@ -316,3 +305,11 @@
 Who:	Johannes Berg <johannes@sipsolutions.net>
 
 ---------------------------
+
+What:	i8xx_tco watchdog driver
+When:	in 2.6.22
+Why:	the i8xx_tco watchdog driver has been replaced by the iTCO_wdt
+	watchdog driver.
+Who:	Wim Van Sebroeck <wim@iguana.be>
+
+---------------------------
diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt
index 576ce46..989f113 100644
--- a/Documentation/gpio.txt
+++ b/Documentation/gpio.txt
@@ -105,12 +105,15 @@
 
 	/* set as input or output, returning 0 or negative errno */
 	int gpio_direction_input(unsigned gpio);
-	int gpio_direction_output(unsigned gpio);
+	int gpio_direction_output(unsigned gpio, int value);
 
 The return value is zero for success, else a negative errno.  It should
 be checked, since the get/set calls don't have error returns and since
 misconfiguration is possible.  (These calls could sleep.)
 
+For output GPIOs, the value provided becomes the initial output value.
+This helps avoid signal glitching during system startup.
+
 Setting the direction can fail if the GPIO number is invalid, or when
 that particular GPIO can't be used in that mode.  It's generally a bad
 idea to rely on boot firmware to have set the direction correctly, since
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 6e92ba6..12533a9 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -79,6 +79,7 @@
 			Documentation/scsi/.
 	SELINUX SELinux support is enabled.
 	SERIAL	Serial support is enabled.
+	SH	SuperH architecture is enabled.
 	SMP	The kernel is an SMP kernel.
 	SPARC	Sparc architecture is enabled.
 	SWSUSP	Software suspend is enabled.
@@ -125,7 +126,8 @@
 			See header of drivers/scsi/53c7xx.c.
 			See also Documentation/scsi/ncr53c7xx.txt.
 
-	acpi=		[HW,ACPI] Advanced Configuration and Power Interface
+	acpi=		[HW,ACPI,X86-64,i386]
+			Advanced Configuration and Power Interface
 			Format: { force | off | ht | strict | noirq }
 			force -- enable ACPI if default was off
 			off -- disable ACPI if default was on
@@ -136,6 +138,12 @@
 
 			See also Documentation/pm.txt, pci=noacpi
 
+	acpi_apic_instance=	[ACPI, IOAPIC]
+			Format: <int>
+			2: use 2nd APIC table, if available
+			1,0: use 1st APIC table
+			default: 0
+
 	acpi_sleep=	[HW,ACPI] Sleep options
 			Format: { s3_bios, s3_mode }
 			See Documentation/power/video.txt
@@ -485,7 +493,7 @@
 
 	dtc3181e=	[HW,SCSI]
 
-	earlyprintk=	[IA-32,X86-64]
+	earlyprintk=	[IA-32,X86-64,SH]
 			earlyprintk=vga
 			earlyprintk=serial[,ttySn[,baudrate]]
 
@@ -772,6 +780,9 @@
 	lapic		[IA-32,APIC] Enable the local APIC even if BIOS
 			disabled it.
 
+	lapic_timer_c2_ok	[IA-32,x86-64,APIC] trust the local apic timer in
+			C2 power state.
+
 	lasi=		[HW,SCSI] PARISC LASI driver for the 53c700 chip
 			Format: addr:<io>,irq:<irq>
 
@@ -1115,6 +1126,8 @@
 
 	nolapic		[IA-32,APIC] Do not enable or use the local APIC.
 
+	nolapic_timer	[IA-32,APIC] Do not use the local APIC timer.
+
 	noltlbs		[PPC] Do not use large page/tlb entries for kernel
 			lowmem mapping on PPC40x.
 
@@ -1784,7 +1797,7 @@
 	usbhid.mousepoll=
 			[USBHID] The interval which mice are to be polled at.
 
-	vdso=		[IA-32]
+	vdso=		[IA-32,SH]
 			vdso=1: enable VDSO (default)
 			vdso=0: disable VDSO mapping
 
diff --git a/Documentation/networking/ax25.txt b/Documentation/networking/ax25.txt
index 37c25b0..8257dbf 100644
--- a/Documentation/networking/ax25.txt
+++ b/Documentation/networking/ax25.txt
@@ -1,16 +1,10 @@
 To use the amateur radio protocols within Linux you will need to get a
-suitable copy of the AX.25 Utilities. More detailed information about these
-and associated programs can be found on http://zone.pspt.fi/~jsn/.
-
-For more information about the AX.25, NET/ROM and ROSE protocol stacks, see
-the AX25-HOWTO written by Terry Dawson <terry@perf.no.itg.telstra.com.au>
-who is also the AX.25 Utilities maintainer.
+suitable copy of the AX.25 Utilities. More detailed information about
+AX.25, NET/ROM and ROSE, associated programs and and utilities can be
+found on http://www.linux-ax25.org.
 
 There is an active mailing list for discussing Linux amateur radio matters
-called linux-hams. To subscribe to it, send a message to
+called linux-hams@vger.kernel.org. To subscribe to it, send a message to
 majordomo@vger.kernel.org with the words "subscribe linux-hams" in the body
-of the message, the subject field is ignored.
-
-Jonathan G4KLX
-
-g4klx@g4klx.demon.co.uk
+of the message, the subject field is ignored.  You don't need to be
+subscribed to post but of course that means you might miss an answer.
diff --git a/Documentation/power/pci.txt b/Documentation/power/pci.txt
index c750f9f..b6a3cbf 100644
--- a/Documentation/power/pci.txt
+++ b/Documentation/power/pci.txt
@@ -102,31 +102,28 @@
 --------------
 
 Usage:
-	pci_save_state(dev, buffer);
+	pci_save_state(struct pci_dev *dev);
 
 Description:
-	Save first 64 bytes of PCI config space. Buffer must be allocated by
-	caller.
+	Save first 64 bytes of PCI config space, along with any additional
+	PCI-Express or PCI-X information.
 
 
 pci_restore_state
 -----------------
 
 Usage:
-	pci_restore_state(dev, buffer);
+	pci_restore_state(struct pci_dev *dev);
 
 Description:
-	Restore previously saved config space. (First 64 bytes only);
-
-	If buffer is NULL, then restore what information we know about the
-	device from bootup: BARs and interrupt line.
+	Restore previously saved config space.
 
 
 pci_set_power_state
 -------------------
 
 Usage:
-	pci_set_power_state(dev, state);
+	pci_set_power_state(struct pci_dev *dev, pci_power_t state);
 
 Description:
 	Transition device to low power state using PCI PM Capabilities
@@ -142,7 +139,7 @@
 ---------------
 
 Usage:
-	pci_enable_wake(dev, state, enable);
+	pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable);
 
 Description:
 	Enable device to generate PME# during low power state using PCI PM 
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index db398a64..73e9a17 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -866,6 +866,7 @@
 	  basic		3-jack (default)
 	  hp		HP nx6320
 	  thinkpad	Lenovo Thinkpad T60/X60/Z60
+	  toshiba	Toshiba U205
 
 	AD1986A
 	  6stack	6-jack, separate surrounds (default)
@@ -906,7 +907,8 @@
 	  5stack	D945 5stack + SPDIF
 	  macmini	Intel Mac Mini
 	  macbook	Intel Mac Book
-	  macbook-pro	Intel Mac Book Pro
+	  macbook-pro-v1 Intel Mac Book Pro 1st generation
+	  macbook-pro	Intel Mac Book Pro 2nd generation
 
 	STAC9202/9250/9251
 	  ref		Reference board, base config
diff --git a/Documentation/sparse.txt b/Documentation/sparse.txt
index f9c99c9..1a3bdc2 100644
--- a/Documentation/sparse.txt
+++ b/Documentation/sparse.txt
@@ -45,11 +45,15 @@
 Getting sparse
 ~~~~~~~~~~~~~~
 
-With git, you can just get it from
+You can get latest released versions from the Sparse homepage at
+http://www.kernel.org/pub/linux/kernel/people/josh/sparse/
 
-        rsync://rsync.kernel.org/pub/scm/devel/sparse/sparse.git
+Alternatively, you can get snapshots of the latest development version
+of sparse using git to clone..
 
-and DaveJ has tar-balls at
+        git://git.kernel.org/pub/scm/linux/kernel/git/josh/sparse.git
+
+DaveJ has hourly generated tarballs of the git tree available at..
 
         http://www.codemonkey.org.uk/projects/git-snapshots/sparse/
 
diff --git a/Documentation/sysrq.txt b/Documentation/sysrq.txt
index 452c0f1..d43aa9d 100644
--- a/Documentation/sysrq.txt
+++ b/Documentation/sysrq.txt
@@ -93,6 +93,8 @@
 
 'p'     - Will dump the current registers and flags to your console.
 
+'q'     - Will dump a list of all running timers.
+
 'r'     - Turns off keyboard raw mode and sets it to XLATE.
 
 's'     - Will attempt to sync all mounted filesystems.
diff --git a/MAINTAINERS b/MAINTAINERS
index 9993b90..ef84419 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -198,10 +198,25 @@
 W:	http://www.stud.uni-karlsruhe.de/~uh1b/
 S:	Maintained
 
+IPS SCSI RAID DRIVER
+P:	Adaptec OEM Raid Solutions
+M:	aacraid@adaptec.com
+L:	linux-scsi@vger.kernel.org
+W:	http://www.adaptec.com/
+S:	Maintained
+
+DPT_I2O SCSI RAID DRIVER
+P:	Adaptec OEM Raid Solutions
+M:	aacraid@adaptec.com
+L:	linux-scsi@vger.kernel.org
+W:	http://www.adaptec.com/
+S:	Maintained
+
 AACRAID SCSI RAID DRIVER
 P:	Adaptec OEM Raid Solutions
+M:	aacraid@adaptec.com
 L:	linux-scsi@vger.kernel.org
-W:	http://linux.dell.com/storage.shtml
+W:	http://www.adaptec.com/
 S:	Supported
 
 ACPI
@@ -1103,9 +1118,6 @@
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
-DEVICE FILESYSTEM
-S:	Obsolete
-
 DIGI INTL. EPCA DRIVER
 P:	Digi International, Inc
 M:	Eng.Linux@digi.com
@@ -1392,7 +1404,7 @@
 W:	ftp://ftp.openlinux.org/pub/people/hch/vxfs
 S:	Maintained
 
-FUJITSU FR-V PORT
+FUJITSU FR-V (FRV) PORT
 P:	David Howells
 M:	dhowells@redhat.com
 S:	Maintained
@@ -1588,12 +1600,6 @@
 T:	quilt http://khali.linux-fr.org/devel/linux-2.6/jdelvare-i2c/
 S:	Maintained
 
-I2O
-P:	Markus Lidel
-M:	markus.lidel@shadowconnect.com
-W:	http://i2o.shadowconnect.com/
-S:	Maintained
-
 i386 BOOT CODE
 P:	Riley H. Williams
 M:	Riley@Williams.Name
@@ -2931,9 +2937,12 @@
 S:	Maintained
 
 SCTP PROTOCOL
+P:	Vlad Yasevich
+M:	vladislav.yasevich@hp.com
 P:	Sridhar Samudrala
 M:	sri@us.ibm.com
 L:	lksctp-developers@lists.sourceforge.net
+W:	http://lksctp.sourceforge.net
 S:	Supported
 
 SCx200 CPU SUPPORT
@@ -3069,11 +3078,10 @@
 S:	Maintained
 
 SONY VAIO CONTROL DEVICE DRIVER
-P:	Stelian Pop
-M:	stelian@popies.net
 P:	Mattia Dongili
 M:	malattia@linux.it
-W:	http://popies.net/sonypi/
+L:	linux-acpi@vger.kernel.org
+W:	http://www.linux.it/~malattia/wiki/index.php/Sony_drivers
 S:	Maintained
 
 SOUND
@@ -3106,6 +3114,9 @@
 P:	Kylene Hall
 M:	kjhall@us.ibm.com
 W:	http://tpmdd.sourceforge.net
+P:	Marcel Selhorst
+M:	tpm@selhorst.net
+W:	http://www.prosec.rub.de/tpm/
 L:	tpmdd-devel@lists.sourceforge.net
 S:	Maintained
 
diff --git a/Makefile b/Makefile
index 6393738..6486af1 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 21
-EXTRAVERSION = -rc3
-NAME = Homicidal Dwarf Hamster
+EXTRAVERSION = -rc6
+NAME = Nocturnal Monster Puppy
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index 5e34ca6..3e07346 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -28,6 +28,7 @@
 
 config SHARPSL_PM
 	bool
+	select APM_EMULATION
 
 config SHARP_SCOOP
 	bool
diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c
index 5a0f4bc..ba99a20 100644
--- a/arch/arm/kernel/dma.c
+++ b/arch/arm/kernel/dma.c
@@ -228,6 +228,7 @@
 {
 	return dma_chan[channel].active;
 }
+EXPORT_SYMBOL(dma_channel_active);
 
 void set_dma_page(dmach_t channel, char pagenr)
 {
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 03e37af..0453dcc 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -839,8 +839,11 @@
 {
 	int cpu;
 
-	for_each_possible_cpu(cpu)
-		register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu);
+	for_each_possible_cpu(cpu) {
+		struct cpuinfo_arm *cpuinfo = &per_cpu(cpu_data, cpu);
+		cpuinfo->cpu.hotpluggable = 1;
+		register_cpu(&cpuinfo->cpu, cpu);
+	}
 
 	return 0;
 }
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index f7d342c..40586e2 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -320,16 +320,16 @@
 	at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0)
 			| AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0));
 
-	at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(2) | AT91_SMC_NCS_WRPULSE_(5)
-			| AT91_SMC_NRDPULSE_(2) | AT91_SMC_NCS_RDPULSE_(5));
+	at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3)
+			| AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3));
 
-	at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(7) | AT91_SMC_NRDCYCLE_(7));
+	at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5));
 
 	if (data->bus_width_16)
 		mode = AT91_SMC_DBW_16;
 	else
 		mode = AT91_SMC_DBW_8;
-	at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(1));
+	at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(2));
 
 	/* enable pin */
 	if (data->enable_pin)
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index 44211a0..ba4a1bb 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -215,13 +215,14 @@
 }
 EXPORT_SYMBOL(gpio_direction_input);
 
-int gpio_direction_output(unsigned pin)
+int gpio_direction_output(unsigned pin, int value)
 {
 	void __iomem	*pio = pin_to_controller(pin);
 	unsigned	mask = pin_to_mask(pin);
 
 	if (!pio || !(__raw_readl(pio + PIO_PSR) & mask))
 		return -EINVAL;
+	__raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR));
 	__raw_writel(mask, pio + PIO_OER);
 	return 0;
 }
diff --git a/arch/arm/mach-imx/cpufreq.c b/arch/arm/mach-imx/cpufreq.c
index 4f66e90..7e70e0b 100644
--- a/arch/arm/mach-imx/cpufreq.c
+++ b/arch/arm/mach-imx/cpufreq.c
@@ -50,6 +50,7 @@
 #define CR_920T_ASYNC_MODE	0xC0000000
 
 static u32 mpctl0_at_boot;
+static u32 bclk_div_at_boot;
 
 static void imx_set_async_mode(void)
 {
@@ -82,13 +83,13 @@
  * imx_compute_mpctl - compute new PLL parameters
  * @new_mpctl:	pointer to location assigned by new PLL control register value
  * @cur_mpctl:	current PLL control register parameters
+ * @f_ref:	reference source frequency Hz
  * @freq:	required frequency in Hz
  * @relation:	is one of %CPUFREQ_RELATION_L (supremum)
  *		and %CPUFREQ_RELATION_H (infimum)
  */
-long imx_compute_mpctl(u32 *new_mpctl, u32 cur_mpctl, unsigned long freq, int relation)
+long imx_compute_mpctl(u32 *new_mpctl, u32 cur_mpctl, u32 f_ref, unsigned long freq, int relation)
 {
-        u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512);
         u32 mfi;
         u32 mfn;
         u32 mfd;
@@ -182,7 +183,7 @@
 	unsigned long flags;
 	long freq;
 	long sysclk;
-	unsigned int bclk_div = 1;
+	unsigned int bclk_div = bclk_div_at_boot;
 
 	/*
 	 * Some governors do not respects CPU and policy lower limits
@@ -202,8 +203,8 @@
 
 	sysclk = imx_get_system_clk();
 
-	if (freq > sysclk + 1000000) {
-		freq = imx_compute_mpctl(&mpctl0, mpctl0_at_boot, freq, relation);
+	if (freq > sysclk / bclk_div_at_boot + 1000000) {
+		freq = imx_compute_mpctl(&mpctl0, mpctl0_at_boot, CLK32 * 512, freq, relation);
 		if (freq < 0) {
 			printk(KERN_WARNING "imx: target frequency %ld Hz cannot be set\n", freq);
 			return -EINVAL;
@@ -217,6 +218,8 @@
 
 			if(bclk_div > 16)
 				bclk_div = 16;
+			if(bclk_div < bclk_div_at_boot)
+				bclk_div = bclk_div_at_boot;
 		}
 		freq = (sysclk + bclk_div / 2) / bclk_div;
 	}
@@ -285,7 +288,7 @@
 
 static int __init imx_cpufreq_init(void)
 {
-
+	bclk_div_at_boot = __mfld2val(CSCR_BCLK_DIV, CSCR) + 1;
 	mpctl0_at_boot = 0;
 
 	if((CSCR & CSCR_MPEN) &&
diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c
index b5aa49d..7a7fa51 100644
--- a/arch/arm/mach-imx/generic.c
+++ b/arch/arm/mach-imx/generic.c
@@ -102,7 +102,7 @@
  *  f = 2 * f_ref * --------------------
  *                        pd + 1
  */
-static unsigned int imx_decode_pll(unsigned int pll)
+static unsigned int imx_decode_pll(unsigned int pll, u32 f_ref)
 {
 	unsigned long long ll;
 	unsigned long quot;
@@ -111,7 +111,6 @@
 	u32 mfn = pll & 0x3ff;
 	u32 mfd = (pll >> 16) & 0x3ff;
 	u32 pd =  (pll >> 26) & 0xf;
-	u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512);
 
 	mfi = mfi <= 5 ? 5 : mfi;
 
@@ -124,13 +123,15 @@
 
 unsigned int imx_get_system_clk(void)
 {
-	return imx_decode_pll(SPCTL0);
+	u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512);
+
+	return imx_decode_pll(SPCTL0, f_ref);
 }
 EXPORT_SYMBOL(imx_get_system_clk);
 
 unsigned int imx_get_mcu_clk(void)
 {
-	return imx_decode_pll(MPCTL0);
+	return imx_decode_pll(MPCTL0, CLK32 * 512);
 }
 EXPORT_SYMBOL(imx_get_mcu_clk);
 
diff --git a/arch/arm/mach-iop32x/Kconfig b/arch/arm/mach-iop32x/Kconfig
index c072d94..9dd49cf 100644
--- a/arch/arm/mach-iop32x/Kconfig
+++ b/arch/arm/mach-iop32x/Kconfig
@@ -4,6 +4,9 @@
 
 comment "IOP32x Platform Types"
 
+config MACH_EP80219
+	bool
+
 config MACH_GLANTANK
 	bool "Enable support for the IO-Data GLAN Tank"
 	help
@@ -19,6 +22,7 @@
 
 config ARCH_IQ31244
 	bool "Enable support for EP80219/IQ31244"
+	select MACH_EP80219
 	help
 	  Say Y here if you want to run your kernel on the Intel EP80219
 	  evaluation kit for the Intel 80219 processor (a IOP321 variant)
diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c
index 571ac35..60e7430 100644
--- a/arch/arm/mach-iop32x/iq31244.c
+++ b/arch/arm/mach-iop32x/iq31244.c
@@ -39,22 +39,35 @@
 #include <asm/arch/time.h>
 
 /*
- * The EP80219 and IQ31244 use the same machine ID.  To find out
- * which of the two we're running on, we look at the processor ID.
+ * Until March of 2007 iq31244 platforms and ep80219 platforms shared the
+ * same machine id, and the processor type was used to select board type.
+ * However this assumption breaks for an iq80219 board which is an iop219
+ * processor on an iq31244 board.  The force_ep80219 flag has been added
+ * for old boot loaders using the iq31244 machine id for an ep80219 platform.
  */
+static int force_ep80219;
+
 static int is_80219(void)
 {
 	extern int processor_id;
 	return !!((processor_id & 0xffffffe0) == 0x69052e20);
 }
 
+static int is_ep80219(void)
+{
+	if (machine_is_ep80219() || force_ep80219)
+		return 1;
+	else
+		return 0;
+}
+
 
 /*
  * EP80219/IQ31244 timer tick configuration.
  */
 static void __init iq31244_timer_init(void)
 {
-	if (is_80219()) {
+	if (is_ep80219()) {
 		/* 33.333 MHz crystal.  */
 		iop_init_time(200000000);
 	} else {
@@ -165,12 +178,18 @@
 
 static int __init iq31244_pci_init(void)
 {
-	if (machine_is_iq31244()) {
+	if (is_ep80219())
+		pci_common_init(&ep80219_pci);
+	else if (machine_is_iq31244()) {
 		if (is_80219()) {
-			pci_common_init(&ep80219_pci);
-		} else {
-			pci_common_init(&iq31244_pci);
+			printk("note: iq31244 board type has been selected\n");
+			printk("note: to select ep80219 operation:\n");
+			printk("\t1/ specify \"force_ep80219\" on the kernel"
+				" command line\n");
+			printk("\t2/ update boot loader to pass"
+				" the ep80219 id: %d\n", MACH_TYPE_EP80219);
 		}
+		pci_common_init(&iq31244_pci);
 	}
 
 	return 0;
@@ -277,10 +296,18 @@
 	platform_device_register(&iq31244_flash_device);
 	platform_device_register(&iq31244_serial_device);
 
-	if (is_80219())
+	if (is_ep80219())
 		pm_power_off = ep80219_power_off;
 }
 
+static int __init force_ep80219_setup(char *str)
+{
+	force_ep80219 = 1;
+	return 1;
+}
+
+__setup("force_ep80219", force_ep80219_setup);
+
 MACHINE_START(IQ31244, "Intel IQ31244")
 	/* Maintainer: Intel Corp. */
 	.phys_io	= IQ31244_UART,
@@ -291,3 +318,19 @@
 	.timer		= &iq31244_timer,
 	.init_machine	= iq31244_init_machine,
 MACHINE_END
+
+/* There should have been an ep80219 machine identifier from the beginning.
+ * Boot roms older than March 2007 do not know the ep80219 machine id.  Pass
+ * "force_ep80219" on the kernel command line, otherwise iq31244 operation
+ * will be selected.
+ */
+MACHINE_START(EP80219, "Intel EP80219")
+	/* Maintainer: Intel Corp. */
+	.phys_io	= IQ31244_UART,
+	.io_pg_offst	= ((IQ31244_UART) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= iq31244_map_io,
+	.init_irq	= iop32x_init_irq,
+	.timer		= &iq31244_timer,
+	.init_machine	= iq31244_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c b/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c
index a193dd9..760c9d0 100644
--- a/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c
+++ b/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c
@@ -32,7 +32,7 @@
 	board_a9m9750dev_init_machine();
 }
 
-MACHINE_START(CC9P9360DEV, "Connect Core 9P 9360 on an A9M9750 Devboard")
+MACHINE_START(CC9P9360DEV, "Digi ConnectCore 9P 9360 on an A9M9750 Devboard")
 	.map_io = mach_cc9p9360dev_map_io,
 	.init_irq = mach_cc9p9360dev_init_irq,
 	.init_machine = mach_cc9p9360dev_init_machine,
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 6e11307..ad51939 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -27,6 +27,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/input.h>
+#include <linux/workqueue.h>
 
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 0de201c..5170481 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -27,6 +27,7 @@
 
 #include <asm/arch/clock.h>
 #include <asm/arch/sram.h>
+#include <asm/div64.h>
 
 #include "prcm-regs.h"
 #include "memory.h"
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 8816f5a..162978f 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -1013,7 +1013,8 @@
 	.name		= "dss2_fck",
 	.parent		= &sys_ck,		/* fixed at sys_ck or 48MHz */
 	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
-				RATE_CKCTL | CM_CORE_SEL1 | RATE_FIXED,
+				RATE_CKCTL | CM_CORE_SEL1 | RATE_FIXED |
+				DELAYED_APP,
 	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
 	.enable_bit	= 1,
 	.src_offset	= 13,
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 7915a5a..7273877 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -28,6 +28,7 @@
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/system.h>
+#include <asm/arch/pxa-regs.h>
 #include <asm/arch/irda.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/udc.h>
@@ -35,8 +36,6 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
-
-#include <asm/arch/pxa-regs.h>
 #include <asm/arch/tosa.h>
 
 #include <asm/hardware/scoop.h>
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index 01c60d0..d052ab2 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -202,7 +202,9 @@
 
 	/* setup PM */
 
+#ifdef CONFIG_PM_H1940
 	memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024);
+#endif
 	s3c2410_pm_init();
 }
 
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index 480ccde..ae1d0a8 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -224,7 +224,9 @@
 
 static void __init rx3715_init_machine(void)
 {
+#ifdef CONFIG_PM_H1940
 	memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024);
+#endif
 	s3c2410_pm_init();
 
 	s3c24xx_fb_set_platdata(&rx3715_lcdcfg);
diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c
index 7a45b6d..7565735 100644
--- a/arch/arm/mach-s3c2443/irq.c
+++ b/arch/arm/mach-s3c2443/irq.c
@@ -137,7 +137,7 @@
 
 static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
 {
-	s3c2443_irq_demux(IRQ_S3C2443_DMA1, 6);
+	s3c2443_irq_demux(IRQ_S3C2443_DMA0, 6);
 }
 
 #define INTMSK_DMA	(1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 192a5a2..9e13c83 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -27,6 +27,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/flash.h>
 #include <asm/irq.h>
+#include <asm/gpio.h>
 
 #include "generic.h"
 
@@ -153,7 +154,7 @@
 
 EXPORT_SYMBOL(gpio_direction_input);
 
-int gpio_direction_output(unsigned gpio)
+int gpio_direction_output(unsigned gpio, int value)
 {
 	unsigned long flags;
 
@@ -161,6 +162,7 @@
 		return -EINVAL;
 
 	local_irq_save(flags);
+	gpio_set_value(gpio, value);
 	GPDR |= GPIO_GPIO(gpio);
 	local_irq_restore(flags);
 	return 0;
diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c
index f2e81cd..6f4388f 100644
--- a/arch/avr32/kernel/ptrace.c
+++ b/arch/avr32/kernel/ptrace.c
@@ -313,7 +313,7 @@
 		__mtdr(DBGREG_DC, dc);
 
 		ti = current_thread_info();
-		ti->flags |= _TIF_BREAKPOINT;
+		set_ti_thread_flag(ti, TIF_BREAKPOINT);
 
 		/* The TLB miss handlers don't check thread flags */
 		if ((regs->pc >= (unsigned long)&itlb_miss)
@@ -328,7 +328,7 @@
 		 * single step.
 		 */
 		if ((regs->sr & MODE_MASK) != MODE_SUPERVISOR)
-			ti->flags |= TIF_SINGLE_STEP;
+			set_ti_thread_flag(ti, TIF_SINGLE_STEP);
 	} else {
 		panic("Unable to handle debug trap at pc = %08lx\n",
 		      regs->pc);
diff --git a/arch/avr32/kernel/traps.c b/arch/avr32/kernel/traps.c
index 7e803f4..adc01a1 100644
--- a/arch/avr32/kernel/traps.c
+++ b/arch/avr32/kernel/traps.c
@@ -49,39 +49,45 @@
 	return;
 }
 
+static inline int valid_stack_ptr(struct thread_info *tinfo, unsigned long p)
+{
+	return (p > (unsigned long)tinfo)
+		&& (p < (unsigned long)tinfo + THREAD_SIZE - 3);
+}
+
 #ifdef CONFIG_FRAME_POINTER
 static inline void __show_trace(struct task_struct *tsk, unsigned long *sp,
 				struct pt_regs *regs)
 {
-	unsigned long __user *fp;
-	unsigned long __user *last_fp = NULL;
+	unsigned long lr, fp;
+	struct thread_info *tinfo;
 
-	if (regs) {
-		fp = (unsigned long __user *)regs->r7;
-	} else if (tsk == current) {
-		register unsigned long __user *real_fp __asm__("r7");
-		fp = real_fp;
-	} else {
-		fp = (unsigned long __user *)tsk->thread.cpu_context.r7;
-	}
+	tinfo = (struct thread_info *)
+		((unsigned long)sp & ~(THREAD_SIZE - 1));
+
+	if (regs)
+		fp = regs->r7;
+	else if (tsk == current)
+		asm("mov %0, r7" : "=r"(fp));
+	else
+		fp = tsk->thread.cpu_context.r7;
 
 	/*
-	 * Walk the stack until (a) we get an exception, (b) the frame
-	 * pointer becomes zero, or (c) the frame pointer gets stuck
-	 * at the same value.
+	 * Walk the stack as long as the frame pointer (a) is within
+	 * the kernel stack of the task, and (b) it doesn't move
+	 * downwards.
 	 */
-	while (fp && fp != last_fp) {
-		unsigned long lr, new_fp = 0;
+	while (valid_stack_ptr(tinfo, fp)) {
+		unsigned long new_fp;
 
-		last_fp = fp;
-		if (__get_user(lr, fp))
-			break;
-		if (fp && __get_user(new_fp, fp + 1))
-			break;
-		fp = (unsigned long __user *)new_fp;
-
+		lr = *(unsigned long *)fp;
 		printk(" [<%08lx>] ", lr);
 		print_symbol("%s\n", lr);
+
+		new_fp = *(unsigned long *)(fp + 4);
+		if (new_fp <= fp)
+			break;
+		fp = new_fp;
 	}
 	printk("\n");
 }
diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c
index bc23550..472703f 100644
--- a/arch/avr32/mach-at32ap/at32ap7000.c
+++ b/arch/avr32/mach-at32ap/at32ap7000.c
@@ -752,7 +752,7 @@
 DEFINE_DEV(atmel_spi, 1);
 DEV_CLK(spi_clk, atmel_spi1, pba, 1);
 
-static void
+static void __init
 at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b,
 		      unsigned int n, const u8 *pins)
 {
diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c
index 9ba5654..1eb99b8 100644
--- a/arch/avr32/mach-at32ap/pio.c
+++ b/arch/avr32/mach-at32ap/pio.c
@@ -214,7 +214,7 @@
 }
 EXPORT_SYMBOL(gpio_direction_input);
 
-int gpio_direction_output(unsigned int gpio)
+int gpio_direction_output(unsigned int gpio, int value)
 {
 	struct pio_device *pio;
 	unsigned int pin;
@@ -223,6 +223,8 @@
 	if (!pio)
 		return -ENODEV;
 
+	gpio_set_value(gpio, value);
+
 	pin = gpio & 0x1f;
 	pio_writel(pio, OER, 1 << pin);
 
diff --git a/arch/avr32/mm/cache.c b/arch/avr32/mm/cache.c
index fb13f72..8f7b1c3 100644
--- a/arch/avr32/mm/cache.c
+++ b/arch/avr32/mm/cache.c
@@ -121,9 +121,8 @@
 void flush_icache_page(struct vm_area_struct *vma, struct page *page)
 {
 	if (vma->vm_flags & VM_EXEC) {
-		void *v = kmap(page);
+		void *v = page_address(page);
 		__flush_icache_range((unsigned long)v, (unsigned long)v + PAGE_SIZE);
-		kunmap(v);
 	}
 }
 
diff --git a/arch/cris/arch-v32/drivers/pci/bios.c b/arch/cris/arch-v32/drivers/pci/bios.c
index a2b9c60..5b79a7a 100644
--- a/arch/cris/arch-v32/drivers/pci/bios.c
+++ b/arch/cris/arch-v32/drivers/pci/bios.c
@@ -100,7 +100,9 @@
 	if ((err = pcibios_enable_resources(dev, mask)) < 0)
 		return err;
 
-	return pcibios_enable_irq(dev);
+	if (!dev->msi_enabled)
+		pcibios_enable_irq(dev);
+	return 0;
 }
 
 int pcibios_assign_resources(void)
diff --git a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c
index f7279d7..0b581e3 100644
--- a/arch/frv/mb93090-mb00/pci-vdk.c
+++ b/arch/frv/mb93090-mb00/pci-vdk.c
@@ -466,6 +466,7 @@
 
 	if ((err = pcibios_enable_resources(dev, mask)) < 0)
 		return err;
-	pcibios_enable_irq(dev);
+	if (!dev->msi_enabled)
+		pcibios_enable_irq(dev);
 	return 0;
 }
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 27e8453..53d6237 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -220,7 +220,7 @@
 
 config VMI
 	bool "VMI Paravirt-ops support"
-	depends on PARAVIRT
+	depends on PARAVIRT && !COMPAT_VDSO
 	help
 	  VMI provides a paravirtualized interface to the VMware ESX server
 	  (it could be used by other hypervisors in theory too, but is not
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S
index 2c5b5cc..8143c95 100644
--- a/arch/i386/boot/video.S
+++ b/arch/i386/boot/video.S
@@ -571,6 +571,16 @@
 	jmp	_m_s
 
 check_vesa:
+#ifdef CONFIG_FIRMWARE_EDID
+	leaw	modelist+1024, %di
+	movw	$0x4f00, %ax
+	int	$0x10
+	cmpw	$0x004f, %ax
+	jnz	setbad
+
+	movw	4(%di), %ax
+	movw	%ax, vbe_version
+#endif
 	leaw	modelist+1024, %di
 	subb	$VIDEO_FIRST_VESA>>8, %bh
 	movw	%bx, %cx			# Get mode information structure
@@ -1945,6 +1955,9 @@
 	rep
 	stosl
 
+	cmpw	$0x0200, vbe_version		# only do EDID on >= VBE2.0
+	jl	no_edid
+
 	pushw   %es				# save ES
 	xorw    %di, %di                        # Report Capability
 	pushw   %di
@@ -1987,6 +2000,7 @@
 svga_prefix:	.byte	VIDEO_FIRST_BIOS>>8	# Default prefix for BIOS modes
 graphic_mode:	.byte	0	# Graphic mode with a linear frame buffer
 dac_size:	.byte	6	# DAC bit depth
+vbe_version:	.word	0	# VBE bios version
 
 # Status messages
 keymsg:		.ascii	"Press <RETURN> to see video modes available, "
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 5ae1e0b..f4efd66 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -1,10 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20-git8
-# Tue Feb 13 11:25:18 2007
+# Linux kernel version: 2.6.21-rc3
+# Wed Mar  7 15:29:47 2007
 #
 CONFIG_X86_32=y
 CONFIG_GENERIC_TIME=y
+CONFIG_CLOCKSOURCE_WATCHDOG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_SEMAPHORE_SLEEPERS=y
@@ -34,6 +37,7 @@
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
@@ -44,6 +48,7 @@
 # CONFIG_CPUSETS is not set
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
@@ -103,6 +108,9 @@
 #
 # Processor type and features
 #
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_SMP=y
 # CONFIG_X86_PC is not set
 # CONFIG_X86_ELAN is not set
@@ -235,10 +243,8 @@
 CONFIG_ACPI_AC=y
 CONFIG_ACPI_BATTERY=y
 CONFIG_ACPI_BUTTON=y
-# CONFIG_ACPI_HOTKEY is not set
 CONFIG_ACPI_FAN=y
 # CONFIG_ACPI_DOCK is not set
-# CONFIG_ACPI_BAY is not set
 CONFIG_ACPI_PROCESSOR=y
 CONFIG_ACPI_THERMAL=y
 # CONFIG_ACPI_ASUS is not set
@@ -289,6 +295,7 @@
 # CONFIG_X86_CPUFREQ_NFORCE2 is not set
 # CONFIG_X86_LONGRUN is not set
 # CONFIG_X86_LONGHAUL is not set
+# CONFIG_X86_E_POWERSAVER is not set
 
 #
 # shared options
@@ -368,7 +375,7 @@
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
 # CONFIG_INET_XFRM_MODE_BEET is not set
@@ -470,7 +477,13 @@
 #
 # Plug and Play support
 #
-# CONFIG_PNP is not set
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
 
 #
 # Block devices
@@ -490,7 +503,6 @@
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
@@ -500,6 +512,7 @@
 # CONFIG_IBM_ASM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
+# CONFIG_SONY_LAPTOP is not set
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -526,6 +539,7 @@
 #
 CONFIG_IDE_GENERIC=y
 # CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_IDEPNP is not set
 CONFIG_BLK_DEV_IDEPCI=y
 # CONFIG_IDEPCI_SHARE_IRQ is not set
 # CONFIG_BLK_DEV_OFFBOARD is not set
@@ -679,6 +693,7 @@
 # CONFIG_SATA_VITESSE is not set
 # CONFIG_SATA_INIC162X is not set
 CONFIG_SATA_INTEL_COMBINED=y
+CONFIG_SATA_ACPI=y
 # CONFIG_PATA_ALI is not set
 # CONFIG_PATA_AMD is not set
 # CONFIG_PATA_ARTOP is not set
@@ -786,6 +801,7 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_NET_SB1000 is not set
 
 #
 # ARCnet devices
@@ -979,6 +995,7 @@
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
 CONFIG_SERIAL_8250_NR_UARTS=4
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
@@ -1065,6 +1082,11 @@
 # CONFIG_HWMON_VID is not set
 
 #
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -1078,7 +1100,7 @@
 #
 # Graphics support
 #
-CONFIG_FIRMWARE_EDID=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 # CONFIG_FB is not set
 
 #
@@ -1089,7 +1111,6 @@
 CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=128
 CONFIG_VIDEO_SELECT=y
 CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -1238,6 +1259,7 @@
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1248,6 +1270,7 @@
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
 # CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1506,6 +1529,7 @@
 CONFIG_LOG_BUF_SHIFT=18
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
@@ -1525,6 +1549,7 @@
 # CONFIG_FORCED_INLINING is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
 CONFIG_EARLY_PRINTK=y
 CONFIG_DEBUG_STACKOVERFLOW=y
 # CONFIG_DEBUG_STACK_USAGE is not set
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index e5eb97a..9ea5b8e 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -1072,7 +1072,28 @@
 			       "ASUS A7V ACPI BIOS Revision 1007"),
 		     },
 	 },
-
+	{
+		/*
+		 * Latest BIOS for IBM 600E (1.16) has bad pcinum
+		 * for LPC bridge, which is needed for the PCI
+		 * interrupt links to work. DSDT fix is in bug 5966.
+		 * 2645, 2646 model numbers are shared with 600/600E/600X
+		 */
+	 .callback = disable_acpi_irq,
+	 .ident = "IBM Thinkpad 600 Series 2645",
+	 .matches = {
+		     DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
+		     DMI_MATCH(DMI_BOARD_NAME, "2645"),
+		     },
+	 },
+	{
+	 .callback = disable_acpi_irq,
+	 .ident = "IBM Thinkpad 600 Series 2646",
+	 .matches = {
+		     DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
+		     DMI_MATCH(DMI_BOARD_NAME, "2646"),
+		     },
+	 },
 	/*
 	 * Boxes that need ACPI PCI IRQ routing and PCI scan disabled
 	 */
diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c
index bf86f76..a7d22d9 100644
--- a/arch/i386/kernel/acpi/earlyquirk.c
+++ b/arch/i386/kernel/acpi/earlyquirk.c
@@ -14,11 +14,8 @@
 
 #ifdef CONFIG_ACPI
 
-static int nvidia_hpet_detected __initdata;
-
 static int __init nvidia_hpet_check(struct acpi_table_header *header)
 {
-	nvidia_hpet_detected = 1;
 	return 0;
 }
 #endif
@@ -29,9 +26,7 @@
 	/* According to Nvidia all timer overrides are bogus unless HPET
 	   is enabled. */
 	if (!acpi_use_timer_override && vendor == PCI_VENDOR_ID_NVIDIA) {
-		nvidia_hpet_detected = 0;
-		acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check);
-		if (nvidia_hpet_detected == 0) {
+		if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check)) {
 			acpi_skip_timer_override = 1;
 			  printk(KERN_INFO "Nvidia board "
                        "detected. Ignoring ACPI "
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 2383bcf..93aa911 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -28,6 +28,7 @@
 #include <linux/clockchips.h>
 #include <linux/acpi_pmtmr.h>
 #include <linux/module.h>
+#include <linux/dmi.h>
 
 #include <asm/atomic.h>
 #include <asm/smp.h>
@@ -61,6 +62,11 @@
 
 /* Local APIC timer verification ok */
 static int local_apic_timer_verify_ok;
+/* Disable local APIC timer from the kernel commandline or via dmi quirk */
+static int local_apic_timer_disabled;
+/* Local APIC timer works in C2 */
+int local_apic_timer_c2_ok;
+EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);
 
 /*
  * Debug level, exported for io_apic.c
@@ -338,6 +344,23 @@
 	void (*real_handler)(struct clock_event_device *dev);
 	unsigned long deltaj;
 	long delta, deltapm;
+	int pm_referenced = 0;
+
+	if (boot_cpu_has(X86_FEATURE_LAPIC_TIMER_BROKEN))
+		local_apic_timer_disabled = 1;
+
+	/*
+	 * The local apic timer can be disabled via the kernel
+	 * commandline or from the test above. Register the lapic
+	 * timer as a dummy clock event source on SMP systems, so the
+	 * broadcast mechanism is used. On UP systems simply ignore it.
+	 */
+	if (local_apic_timer_disabled) {
+		/* No broadcast on UP ! */
+		if (num_possible_cpus() > 1)
+			setup_APIC_timer();
+		return;
+	}
 
 	apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
 		    "calibrating APIC timer ...\n");
@@ -357,7 +380,8 @@
 	/* Let the interrupts run */
 	local_irq_enable();
 
-	while(lapic_cal_loops <= LAPIC_CAL_LOOPS);
+	while (lapic_cal_loops <= LAPIC_CAL_LOOPS)
+		cpu_relax();
 
 	local_irq_disable();
 
@@ -394,6 +418,7 @@
 			       "%lu (%ld)\n", (unsigned long) res, delta);
 			delta = (long) res;
 		}
+		pm_referenced = 1;
 	}
 
 	/* Calculate the scaled math multiplication factor */
@@ -423,69 +448,43 @@
 		    calibration_result / (1000000 / HZ),
 		    calibration_result % (1000000 / HZ));
 
-
-	apic_printk(APIC_VERBOSE, "... verify APIC timer\n");
-
-	/*
-	 * Setup the apic timer manually
-	 */
 	local_apic_timer_verify_ok = 1;
-	levt->event_handler = lapic_cal_handler;
-	lapic_timer_setup(CLOCK_EVT_MODE_PERIODIC, levt);
-	lapic_cal_loops = -1;
 
-	/* Let the interrupts run */
-	local_irq_enable();
+	/* We trust the pm timer based calibration */
+	if (!pm_referenced) {
+		apic_printk(APIC_VERBOSE, "... verify APIC timer\n");
 
-	while(lapic_cal_loops <= LAPIC_CAL_LOOPS);
+		/*
+		 * Setup the apic timer manually
+		 */
+		levt->event_handler = lapic_cal_handler;
+		lapic_timer_setup(CLOCK_EVT_MODE_PERIODIC, levt);
+		lapic_cal_loops = -1;
 
-	local_irq_disable();
+		/* Let the interrupts run */
+		local_irq_enable();
 
-	/* Stop the lapic timer */
-	lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, levt);
+		while(lapic_cal_loops <= LAPIC_CAL_LOOPS)
+			cpu_relax();
 
-	local_irq_enable();
+		local_irq_disable();
 
-	/* Jiffies delta */
-	deltaj = lapic_cal_j2 - lapic_cal_j1;
-	apic_printk(APIC_VERBOSE, "... jiffies delta = %lu\n", deltaj);
+		/* Stop the lapic timer */
+		lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, levt);
 
-	/* Check, if the PM timer is available */
-	deltapm = lapic_cal_pm2 - lapic_cal_pm1;
-	apic_printk(APIC_VERBOSE, "... PM timer delta = %ld\n", deltapm);
+		local_irq_enable();
 
-	local_apic_timer_verify_ok = 0;
+		/* Jiffies delta */
+		deltaj = lapic_cal_j2 - lapic_cal_j1;
+		apic_printk(APIC_VERBOSE, "... jiffies delta = %lu\n", deltaj);
 
-	if (deltapm) {
-		if (deltapm > (pm_100ms - pm_thresh) &&
-		    deltapm < (pm_100ms + pm_thresh)) {
-			apic_printk(APIC_VERBOSE, "... PM timer result ok\n");
-			/* Check, if the jiffies result is consistent */
-			if (deltaj < LAPIC_CAL_LOOPS-2 ||
-			    deltaj > LAPIC_CAL_LOOPS+2) {
-				/*
-				 * Not sure, what we can do about this one.
-				 * When high resultion timers are active
-				 * and the lapic timer does not stop in C3
-				 * we are fine. Otherwise more trouble might
-				 * be waiting. -- tglx
-				 */
-				printk(KERN_WARNING "Global event device %s "
-				       "has wrong frequency "
-				       "(%lu ticks instead of %d)\n",
-				       global_clock_event->name, deltaj,
-				       LAPIC_CAL_LOOPS);
-			}
-			local_apic_timer_verify_ok = 1;
-		}
-	} else {
 		/* Check, if the jiffies result is consistent */
-		if (deltaj >= LAPIC_CAL_LOOPS-2 &&
-		    deltaj <= LAPIC_CAL_LOOPS+2) {
+		if (deltaj >= LAPIC_CAL_LOOPS-2 && deltaj <= LAPIC_CAL_LOOPS+2)
 			apic_printk(APIC_VERBOSE, "... jiffies result ok\n");
-			local_apic_timer_verify_ok = 1;
-		}
-	}
+		else
+			local_apic_timer_verify_ok = 0;
+	} else
+		local_irq_enable();
 
 	if (!local_apic_timer_verify_ok) {
 		printk(KERN_WARNING
@@ -1203,6 +1202,20 @@
 }
 early_param("nolapic", parse_nolapic);
 
+static int __init parse_disable_lapic_timer(char *arg)
+{
+	local_apic_timer_disabled = 1;
+	return 0;
+}
+early_param("nolapic_timer", parse_disable_lapic_timer);
+
+static int __init parse_lapic_timer_c2_ok(char *arg)
+{
+	local_apic_timer_c2_ok = 1;
+	return 0;
+}
+early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok);
+
 static int __init apic_set_verbosity(char *str)
 {
 	if (strcmp("debug", str) == 0)
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index 41cfea5..2d47db4 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -22,6 +22,37 @@
 extern void vide(void);
 __asm__(".align 4\nvide: ret");
 
+#define ENABLE_C1E_MASK         0x18000000
+#define CPUID_PROCESSOR_SIGNATURE       1
+#define CPUID_XFAM              0x0ff00000
+#define CPUID_XFAM_K8           0x00000000
+#define CPUID_XFAM_10H          0x00100000
+#define CPUID_XFAM_11H          0x00200000
+#define CPUID_XMOD              0x000f0000
+#define CPUID_XMOD_REV_F        0x00040000
+
+/* AMD systems with C1E don't have a working lAPIC timer. Check for that. */
+static __cpuinit int amd_apic_timer_broken(void)
+{
+	u32 lo, hi;
+	u32 eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
+	switch (eax & CPUID_XFAM) {
+	case CPUID_XFAM_K8:
+		if ((eax & CPUID_XMOD) < CPUID_XMOD_REV_F)
+			break;
+	case CPUID_XFAM_10H:
+	case CPUID_XFAM_11H:
+		rdmsr(MSR_K8_ENABLE_C1E, lo, hi);
+		if (lo & ENABLE_C1E_MASK)
+			return 1;
+                break;
+        default:
+                /* err on the side of caution */
+		return 1;
+        }
+	return 0;
+}
+
 static void __cpuinit init_amd(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
@@ -241,6 +272,9 @@
 
 	if (cpuid_eax(0x80000000) >= 0x80000006)
 		num_cache_leaves = 3;
+
+	if (amd_apic_timer_broken())
+		set_bit(X86_FEATURE_LAPIC_TIMER_BROKEN, c->x86_capability);
 }
 
 static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size)
diff --git a/arch/i386/kernel/hpet.c b/arch/i386/kernel/hpet.c
index f3ab61e..17d7345 100644
--- a/arch/i386/kernel/hpet.c
+++ b/arch/i386/kernel/hpet.c
@@ -3,6 +3,8 @@
 #include <linux/errno.h>
 #include <linux/hpet.h>
 #include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/pm.h>
 
 #include <asm/hpet.h>
 #include <asm/io.h>
@@ -197,7 +199,7 @@
 	cnt += delta;
 	hpet_writel(cnt, HPET_T0_CMP);
 
-	return ((long)(hpet_readl(HPET_COUNTER) - cnt ) > 0);
+	return ((long)(hpet_readl(HPET_COUNTER) - cnt ) > 0) ? -ETIME : 0;
 }
 
 /*
@@ -307,6 +309,7 @@
 out_nohpet:
 	iounmap(hpet_virt_address);
 	hpet_virt_address = NULL;
+	boot_hpet_disable = 1;
 	return 0;
 }
 
@@ -521,3 +524,68 @@
 	return IRQ_HANDLED;
 }
 #endif
+
+
+/*
+ * Suspend/resume part
+ */
+
+#ifdef CONFIG_PM
+
+static int hpet_suspend(struct sys_device *sys_device, pm_message_t state)
+{
+	unsigned long cfg = hpet_readl(HPET_CFG);
+
+	cfg &= ~(HPET_CFG_ENABLE|HPET_CFG_LEGACY);
+	hpet_writel(cfg, HPET_CFG);
+
+	return 0;
+}
+
+static int hpet_resume(struct sys_device *sys_device)
+{
+	unsigned int id;
+
+	hpet_start_counter();
+
+	id = hpet_readl(HPET_ID);
+
+	if (id & HPET_ID_LEGSUP)
+		hpet_enable_int();
+
+	return 0;
+}
+
+static struct sysdev_class hpet_class = {
+	set_kset_name("hpet"),
+	.suspend	= hpet_suspend,
+	.resume		= hpet_resume,
+};
+
+static struct sys_device hpet_device = {
+	.id		= 0,
+	.cls		= &hpet_class,
+};
+
+
+static __init int hpet_register_sysfs(void)
+{
+	int err;
+
+	if (!is_hpet_capable())
+		return 0;
+
+	err = sysdev_class_register(&hpet_class);
+
+	if (!err) {
+		err = sysdev_register(&hpet_device);
+		if (err)
+			sysdev_class_unregister(&hpet_class);
+	}
+
+	return err;
+}
+
+device_initcall(hpet_register_sysfs);
+
+#endif
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
index e3d4b73..4afe26e 100644
--- a/arch/i386/kernel/i386_ksyms.c
+++ b/arch/i386/kernel/i386_ksyms.c
@@ -28,3 +28,5 @@
 #endif
 
 EXPORT_SYMBOL(csum_partial);
+
+EXPORT_SYMBOL(_proxy_pda);
diff --git a/arch/i386/kernel/i8253.c b/arch/i386/kernel/i8253.c
index 5cbb776..10cef5c 100644
--- a/arch/i386/kernel/i8253.c
+++ b/arch/i386/kernel/i8253.c
@@ -47,9 +47,17 @@
 		outb(LATCH >> 8 , PIT_CH0);	/* MSB */
 		break;
 
-	case CLOCK_EVT_MODE_ONESHOT:
+	/*
+	 * Avoid unnecessary state transitions, as it confuses
+	 * Geode / Cyrix based boxen.
+	 */
 	case CLOCK_EVT_MODE_SHUTDOWN:
+		if (evt->mode == CLOCK_EVT_MODE_UNUSED)
+			break;
 	case CLOCK_EVT_MODE_UNUSED:
+		if (evt->mode == CLOCK_EVT_MODE_SHUTDOWN)
+			break;
+	case CLOCK_EVT_MODE_ONESHOT:
 		/* One shot setup */
 		outb_p(0x38, PIT_MODE);
 		udelay(10);
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index e4408ff..b3ab8ff 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -736,7 +736,7 @@
 	return 0;
 }
 
-int __init irqbalance_disable(char *str)
+int __devinit irqbalance_disable(char *str)
 {
 	irqbalance_disabled = 1;
 	return 1;
diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c
index b8f1663..cbe7ec8 100644
--- a/arch/i386/kernel/microcode.c
+++ b/arch/i386/kernel/microcode.c
@@ -567,6 +567,53 @@
 	return error;
 }
 
+static int apply_microcode_on_cpu(int cpu)
+{
+	struct cpuinfo_x86 *c = cpu_data + cpu;
+	struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
+	cpumask_t old;
+	unsigned int val[2];
+	int err = 0;
+
+	if (!uci->mc)
+		return -EINVAL;
+
+	old = current->cpus_allowed;
+	set_cpus_allowed(current, cpumask_of_cpu(cpu));
+
+	/* Check if the microcode we have in memory matches the CPU */
+	if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||
+	    cpu_has(c, X86_FEATURE_IA64) || uci->sig != cpuid_eax(0x00000001))
+		err = -EINVAL;
+
+	if (!err && ((c->x86_model >= 5) || (c->x86 > 6))) {
+		/* get processor flags from MSR 0x17 */
+		rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
+		if (uci->pf != (1 << ((val[1] >> 18) & 7)))
+			err = -EINVAL;
+	}
+
+	if (!err) {
+		wrmsr(MSR_IA32_UCODE_REV, 0, 0);
+		/* see notes above for revision 1.07.  Apparent chip bug */
+		sync_core();
+		/* get the current revision from MSR 0x8B */
+		rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
+		if (uci->rev != val[1])
+			err = -EINVAL;
+	}
+
+	if (!err)
+		apply_microcode(cpu);
+	else
+		printk(KERN_ERR "microcode: Could not apply microcode to CPU%d:"
+			" sig=0x%x, pf=0x%x, rev=0x%x\n",
+			cpu, uci->sig, uci->pf, uci->rev);
+
+	set_cpus_allowed(current, old);
+	return err;
+}
+
 static void microcode_init_cpu(int cpu)
 {
 	cpumask_t old;
@@ -577,7 +624,8 @@
 	set_cpus_allowed(current, cpumask_of_cpu(cpu));
 	mutex_lock(&microcode_mutex);
 	collect_cpu_info(cpu);
-	if (uci->valid && system_state == SYSTEM_RUNNING)
+	if (uci->valid && system_state == SYSTEM_RUNNING &&
+	    !suspend_cpu_hotplug)
 		cpu_request_microcode(cpu);
 	mutex_unlock(&microcode_mutex);
 	set_cpus_allowed(current, old);
@@ -663,13 +711,24 @@
 		return 0;
 
 	pr_debug("Microcode:CPU %d added\n", cpu);
-	memset(uci, 0, sizeof(*uci));
+	/* If suspend_cpu_hotplug is set, the system is resuming and we should
+	 * use the data from before the suspend.
+	 */
+	if (suspend_cpu_hotplug) {
+		err = apply_microcode_on_cpu(cpu);
+		if (err)
+			microcode_fini_cpu(cpu);
+	}
+	if (!uci->valid)
+		memset(uci, 0, sizeof(*uci));
 
 	err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group);
 	if (err)
 		return err;
 
-	microcode_init_cpu(cpu);
+	if (!uci->valid)
+		microcode_init_cpu(cpu);
+
 	return 0;
 }
 
@@ -680,7 +739,11 @@
 	if (!cpu_online(cpu))
 		return 0;
 	pr_debug("Microcode:CPU %d removed\n", cpu);
-	microcode_fini_cpu(cpu);
+	/* If suspend_cpu_hotplug is set, the system is suspending and we should
+	 * keep the microcode in memory for the resume.
+	 */
+	if (!suspend_cpu_hotplug)
+		microcode_fini_cpu(cpu);
 	sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
 	return 0;
 }
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index 821df34..a98ba88 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -122,64 +122,129 @@
 /* checks for a bit availability (hack for oprofile) */
 int avail_to_resrv_perfctr_nmi_bit(unsigned int counter)
 {
+	int cpu;
 	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
-
-	return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner)));
+	for_each_possible_cpu (cpu) {
+		if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)))
+			return 0;
+	}
+	return 1;
 }
 
 /* checks the an msr for availability */
 int avail_to_resrv_perfctr_nmi(unsigned int msr)
 {
 	unsigned int counter;
+	int cpu;
 
 	counter = nmi_perfctr_msr_to_bit(msr);
 	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
 
-	return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner)));
+	for_each_possible_cpu (cpu) {
+		if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)))
+			return 0;
+	}
+	return 1;
+}
+
+static int __reserve_perfctr_nmi(int cpu, unsigned int msr)
+{
+	unsigned int counter;
+	if (cpu < 0)
+		cpu = smp_processor_id();
+
+	counter = nmi_perfctr_msr_to_bit(msr);
+	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
+
+	if (!test_and_set_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)))
+		return 1;
+	return 0;
+}
+
+static void __release_perfctr_nmi(int cpu, unsigned int msr)
+{
+	unsigned int counter;
+	if (cpu < 0)
+		cpu = smp_processor_id();
+
+	counter = nmi_perfctr_msr_to_bit(msr);
+	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
+
+	clear_bit(counter, &per_cpu(perfctr_nmi_owner, cpu));
 }
 
 int reserve_perfctr_nmi(unsigned int msr)
 {
-	unsigned int counter;
-
-	counter = nmi_perfctr_msr_to_bit(msr);
-	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
-
-	if (!test_and_set_bit(counter, &__get_cpu_var(perfctr_nmi_owner)))
-		return 1;
-	return 0;
+	int cpu, i;
+	for_each_possible_cpu (cpu) {
+		if (!__reserve_perfctr_nmi(cpu, msr)) {
+			for_each_possible_cpu (i) {
+				if (i >= cpu)
+					break;
+				__release_perfctr_nmi(i, msr);
+			}
+			return 0;
+		}
+	}
+	return 1;
 }
 
 void release_perfctr_nmi(unsigned int msr)
 {
-	unsigned int counter;
-
-	counter = nmi_perfctr_msr_to_bit(msr);
-	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
-
-	clear_bit(counter, &__get_cpu_var(perfctr_nmi_owner));
+	int cpu;
+	for_each_possible_cpu (cpu) {
+		__release_perfctr_nmi(cpu, msr);
+	}
 }
 
-int reserve_evntsel_nmi(unsigned int msr)
+int __reserve_evntsel_nmi(int cpu, unsigned int msr)
 {
 	unsigned int counter;
+	if (cpu < 0)
+		cpu = smp_processor_id();
 
 	counter = nmi_evntsel_msr_to_bit(msr);
 	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
 
-	if (!test_and_set_bit(counter, &__get_cpu_var(evntsel_nmi_owner)[0]))
+	if (!test_and_set_bit(counter, &per_cpu(evntsel_nmi_owner, cpu)[0]))
 		return 1;
 	return 0;
 }
 
-void release_evntsel_nmi(unsigned int msr)
+static void __release_evntsel_nmi(int cpu, unsigned int msr)
 {
 	unsigned int counter;
+	if (cpu < 0)
+		cpu = smp_processor_id();
 
 	counter = nmi_evntsel_msr_to_bit(msr);
 	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
 
-	clear_bit(counter, &__get_cpu_var(evntsel_nmi_owner)[0]);
+	clear_bit(counter, &per_cpu(evntsel_nmi_owner, cpu)[0]);
+}
+
+int reserve_evntsel_nmi(unsigned int msr)
+{
+	int cpu, i;
+	for_each_possible_cpu (cpu) {
+		if (!__reserve_evntsel_nmi(cpu, msr)) {
+			for_each_possible_cpu (i) {
+				if (i >= cpu)
+					break;
+				__release_evntsel_nmi(i, msr);
+			}
+			return 0;
+		}
+	}
+	return 1;
+}
+
+void release_evntsel_nmi(unsigned int msr)
+{
+	int cpu;
+	for_each_possible_cpu (cpu) {
+		__release_evntsel_nmi(cpu, msr);
+	}
 }
 
 static __cpuinit inline int nmi_known_cpu(void)
@@ -245,14 +310,6 @@
 	unsigned int *prev_nmi_count;
 	int cpu;
 
-	/* Enable NMI watchdog for newer systems.
-	   Probably safe on most older systems too, but let's be careful.
-	   IBM ThinkPads use INT10 inside SMM and that allows early NMI inside SMM
-	   which hangs the system. Disable watchdog for all thinkpads */
-	if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004 &&
-		!dmi_name_in_vendors("ThinkPad"))
-		nmi_watchdog = NMI_LOCAL_APIC;
-
 	if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT))
 		return 0;
 
@@ -271,7 +328,7 @@
 	for_each_possible_cpu(cpu)
 		prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count;
 	local_irq_enable();
-	mdelay((10*1000)/nmi_hz); // wait 10 ticks
+	mdelay((20*1000)/nmi_hz); // wait 20 ticks
 
 	for_each_possible_cpu(cpu) {
 #ifdef CONFIG_SMP
@@ -515,10 +572,10 @@
 
 	perfctr_msr = MSR_K7_PERFCTR0;
 	evntsel_msr = MSR_K7_EVNTSEL0;
-	if (!reserve_perfctr_nmi(perfctr_msr))
+	if (!__reserve_perfctr_nmi(-1, perfctr_msr))
 		goto fail;
 
-	if (!reserve_evntsel_nmi(evntsel_msr))
+	if (!__reserve_evntsel_nmi(-1, evntsel_msr))
 		goto fail1;
 
 	wrmsrl(perfctr_msr, 0UL);
@@ -541,7 +598,7 @@
 	wd->check_bit = 1ULL<<63;
 	return 1;
 fail1:
-	release_perfctr_nmi(perfctr_msr);
+	__release_perfctr_nmi(-1, perfctr_msr);
 fail:
 	return 0;
 }
@@ -552,8 +609,8 @@
 
 	wrmsr(wd->evntsel_msr, 0, 0);
 
-	release_evntsel_nmi(wd->evntsel_msr);
-	release_perfctr_nmi(wd->perfctr_msr);
+	__release_evntsel_nmi(-1, wd->evntsel_msr);
+	__release_perfctr_nmi(-1, wd->perfctr_msr);
 }
 
 #define P6_EVNTSEL0_ENABLE	(1 << 22)
@@ -571,10 +628,10 @@
 
 	perfctr_msr = MSR_P6_PERFCTR0;
 	evntsel_msr = MSR_P6_EVNTSEL0;
-	if (!reserve_perfctr_nmi(perfctr_msr))
+	if (!__reserve_perfctr_nmi(-1, perfctr_msr))
 		goto fail;
 
-	if (!reserve_evntsel_nmi(evntsel_msr))
+	if (!__reserve_evntsel_nmi(-1, evntsel_msr))
 		goto fail1;
 
 	wrmsrl(perfctr_msr, 0UL);
@@ -598,7 +655,7 @@
 	wd->check_bit = 1ULL<<39;
 	return 1;
 fail1:
-	release_perfctr_nmi(perfctr_msr);
+	__release_perfctr_nmi(-1, perfctr_msr);
 fail:
 	return 0;
 }
@@ -609,8 +666,8 @@
 
 	wrmsr(wd->evntsel_msr, 0, 0);
 
-	release_evntsel_nmi(wd->evntsel_msr);
-	release_perfctr_nmi(wd->perfctr_msr);
+	__release_evntsel_nmi(-1, wd->evntsel_msr);
+	__release_perfctr_nmi(-1, wd->perfctr_msr);
 }
 
 /* Note that these events don't tick when the CPU idles. This means
@@ -676,10 +733,10 @@
 		cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4);
 	}
 
-	if (!reserve_perfctr_nmi(perfctr_msr))
+	if (!__reserve_perfctr_nmi(-1, perfctr_msr))
 		goto fail;
 
-	if (!reserve_evntsel_nmi(evntsel_msr))
+	if (!__reserve_evntsel_nmi(-1, evntsel_msr))
 		goto fail1;
 
 	evntsel = P4_ESCR_EVENT_SELECT(0x3F)
@@ -703,7 +760,7 @@
 	wd->check_bit = 1ULL<<39;
 	return 1;
 fail1:
-	release_perfctr_nmi(perfctr_msr);
+	__release_perfctr_nmi(-1, perfctr_msr);
 fail:
 	return 0;
 }
@@ -715,8 +772,8 @@
 	wrmsr(wd->cccr_msr, 0, 0);
 	wrmsr(wd->evntsel_msr, 0, 0);
 
-	release_evntsel_nmi(wd->evntsel_msr);
-	release_perfctr_nmi(wd->perfctr_msr);
+	__release_evntsel_nmi(-1, wd->evntsel_msr);
+	__release_perfctr_nmi(-1, wd->perfctr_msr);
 }
 
 #define ARCH_PERFMON_NMI_EVENT_SEL	ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL
@@ -744,10 +801,10 @@
 	perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0;
 	evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL0;
 
-	if (!reserve_perfctr_nmi(perfctr_msr))
+	if (!__reserve_perfctr_nmi(-1, perfctr_msr))
 		goto fail;
 
-	if (!reserve_evntsel_nmi(evntsel_msr))
+	if (!__reserve_evntsel_nmi(-1, evntsel_msr))
 		goto fail1;
 
 	wrmsrl(perfctr_msr, 0UL);
@@ -772,7 +829,7 @@
 	wd->check_bit = 1ULL << (eax.split.bit_width - 1);
 	return 1;
 fail1:
-	release_perfctr_nmi(perfctr_msr);
+	__release_perfctr_nmi(-1, perfctr_msr);
 fail:
 	return 0;
 }
@@ -795,8 +852,8 @@
 		return;
 
 	wrmsr(wd->evntsel_msr, 0, 0);
-	release_evntsel_nmi(wd->evntsel_msr);
-	release_perfctr_nmi(wd->perfctr_msr);
+	__release_evntsel_nmi(-1, wd->evntsel_msr);
+	__release_perfctr_nmi(-1, wd->perfctr_msr);
 }
 
 void setup_apic_nmi_watchdog (void *unused)
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 9b0dd27..4ff55e6 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -45,6 +45,7 @@
 #include <linux/notifier.h>
 #include <linux/cpu.h>
 #include <linux/percpu.h>
+#include <linux/nmi.h>
 
 #include <linux/delay.h>
 #include <linux/mc146818rtc.h>
@@ -1278,8 +1279,9 @@
 
 int __cpuinit __cpu_up(unsigned int cpu)
 {
+	unsigned long flags;
 #ifdef CONFIG_HOTPLUG_CPU
-	int ret=0;
+	int ret = 0;
 
 	/*
 	 * We do warm boot only on cpus that had booted earlier
@@ -1297,23 +1299,25 @@
 	/* In case one didn't come up */
 	if (!cpu_isset(cpu, cpu_callin_map)) {
 		printk(KERN_DEBUG "skipping cpu%d, didn't come online\n", cpu);
-		local_irq_enable();
 		return -EIO;
 	}
 
-	local_irq_enable();
-
 	per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
 	/* Unleash the CPU! */
 	cpu_set(cpu, smp_commenced_mask);
 
 	/*
-	 * Check TSC synchronization with the AP:
+	 * Check TSC synchronization with the AP (keep irqs disabled
+	 * while doing so):
 	 */
+	local_irq_save(flags);
 	check_tsc_sync_source(cpu);
+	local_irq_restore(flags);
 
-	while (!cpu_isset(cpu, cpu_online_map))
+	while (!cpu_isset(cpu, cpu_online_map)) {
 		cpu_relax();
+		touch_nmi_watchdog();
+	}
 
 #ifdef CONFIG_X86_GENERICARCH
 	if (num_online_cpus() > 8 && genapic == &apic_default)
diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c
index 602660d..6cb8f53 100644
--- a/arch/i386/kernel/tsc.c
+++ b/arch/i386/kernel/tsc.c
@@ -18,6 +18,8 @@
 
 #include "mach_timer.h"
 
+static int tsc_enabled;
+
 /*
  * On some systems the TSC frequency does not
  * change with the cpu frequency. So we need
@@ -105,7 +107,7 @@
 	/*
 	 * Fall back to jiffies if there's no TSC available:
 	 */
-	if (unlikely(tsc_disable))
+	if (unlikely(!tsc_enabled))
 		/* No locking but a rare wrong value is not a big deal: */
 		return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ);
 
@@ -283,6 +285,7 @@
 {
 	if (!tsc_unstable) {
 		tsc_unstable = 1;
+		tsc_enabled = 0;
 		/* Can be called before registration */
 		if (clocksource_tsc.mult)
 			clocksource_change_rating(&clocksource_tsc, 0);
@@ -383,7 +386,9 @@
 	if (check_tsc_unstable()) {
 		clocksource_tsc.rating = 0;
 		clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS;
-	}
+	} else
+		tsc_enabled = 1;
+
 	clocksource_register(&clocksource_tsc);
 
 	return;
diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c
index fbf45fa..edc339f 100644
--- a/arch/i386/kernel/vmi.c
+++ b/arch/i386/kernel/vmi.c
@@ -23,7 +23,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/license.h>
 #include <linux/cpu.h>
 #include <linux/bootmem.h>
 #include <linux/mm.h>
@@ -48,7 +47,6 @@
    (((VROMLONGFUNC *)(rom->func)) (arg))
 
 static struct vrom_header *vmi_rom;
-static int license_gplok;
 static int disable_pge;
 static int disable_pse;
 static int disable_sep;
@@ -71,6 +69,7 @@
 	void (*flush_tlb)(int);
 	void (*set_initial_ap_state)(int, int);
 	void (*halt)(void);
+  	void (*set_lazy_mode)(int mode);
 } vmi_ops;
 
 /* XXX move this to alternative.h */
@@ -576,6 +575,26 @@
 }
 #endif
 
+static void vmi_set_lazy_mode(int mode)
+{
+	static DEFINE_PER_CPU(int, lazy_mode);
+
+	if (!vmi_ops.set_lazy_mode)
+		return;
+
+	/* Modes should never nest or overlap */
+	BUG_ON(__get_cpu_var(lazy_mode) && !(mode == PARAVIRT_LAZY_NONE ||
+					     mode == PARAVIRT_LAZY_FLUSH));
+
+	if (mode == PARAVIRT_LAZY_FLUSH) {
+		vmi_ops.set_lazy_mode(0);
+		vmi_ops.set_lazy_mode(__get_cpu_var(lazy_mode));
+	} else {
+		vmi_ops.set_lazy_mode(mode);
+		__get_cpu_var(lazy_mode) = mode;
+	}
+}
+
 static inline int __init check_vmi_rom(struct vrom_header *rom)
 {
 	struct pci_header *pci;
@@ -629,13 +648,14 @@
 		rom->api_version_maj, rom->api_version_min,
 		pci->rom_version_maj, pci->rom_version_min);
 
-        license_gplok = license_is_gpl_compatible(license);
-        if (!license_gplok) {
-                printk(KERN_WARNING "VMI: ROM license '%s' taints kernel... "
-		       "inlining disabled\n",
-                       license);
-                add_taint(TAINT_PROPRIETARY_MODULE);
-        }
+	/* Don't allow BSD/MIT here for now because we don't want to end up
+	   with any binary only shim layers */
+	if (strcmp(license, "GPL") && strcmp(license, "GPL v2")) {
+		printk(KERN_WARNING "VMI: Non GPL license `%s' found for ROM. Not used.\n",
+			license);
+		return 0;
+	}
+
 	return 1;
 }
 
@@ -805,7 +825,7 @@
 	para_wrap(load_esp0, vmi_load_esp0, set_kernel_stack, UpdateKernelStack);
 	para_fill(set_iopl_mask, SetIOPLMask);
 	para_fill(io_delay, IODelay);
-	para_fill(set_lazy_mode, SetLazyMode);
+	para_wrap(set_lazy_mode, vmi_set_lazy_mode, set_lazy_mode, SetLazyMode);
 
 	/* user and kernel flush are just handled with different flags to FlushTLB */
 	para_wrap(flush_tlb_user, vmi_flush_tlb_user, flush_tlb, FlushTLB);
diff --git a/arch/i386/lib/usercopy.c b/arch/i386/lib/usercopy.c
index d22cfc9..086b372 100644
--- a/arch/i386/lib/usercopy.c
+++ b/arch/i386/lib/usercopy.c
@@ -10,6 +10,7 @@
 #include <linux/blkdev.h>
 #include <linux/module.h>
 #include <linux/backing-dev.h>
+#include <linux/interrupt.h>
 #include <asm/uaccess.h>
 #include <asm/mmx.h>
 
@@ -719,6 +720,14 @@
 #ifndef CONFIG_X86_WP_WORKS_OK
 	if (unlikely(boot_cpu_data.wp_works_ok == 0) &&
 			((unsigned long )to) < TASK_SIZE) {
+		/*
+		 * When we are in an atomic section (see
+		 * mm/filemap.c:file_read_actor), return the full
+		 * length to take the slow path.
+		 */
+		if (in_atomic())
+			return n;
+
 		/* 
 		 * CPU does not honor the WP bit when writing
 		 * from supervisory mode, and due to preemption or SMP,
diff --git a/arch/i386/mm/highmem.c b/arch/i386/mm/highmem.c
index bb2de10..ac70d09 100644
--- a/arch/i386/mm/highmem.c
+++ b/arch/i386/mm/highmem.c
@@ -42,6 +42,7 @@
 
 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
 	set_pte(kmap_pte-idx, mk_pte(page, kmap_prot));
+	arch_flush_lazy_mmu_mode();
 
 	return (void*) vaddr;
 }
@@ -82,6 +83,7 @@
 	idx = type + KM_TYPE_NR*smp_processor_id();
 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
 	set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
+	arch_flush_lazy_mmu_mode();
 
 	return (void*) vaddr;
 }
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c
index 1bb0693..3f78d4d 100644
--- a/arch/i386/pci/common.c
+++ b/arch/i386/pci/common.c
@@ -193,6 +193,14 @@
 	},
 	{
 		.callback = set_bf_sort,
+		.ident = "Dell PowerEdge R900",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R900"),
+		},
+	},
+	{
+		.callback = set_bf_sort,
 		.ident = "HP ProLiant BL20p G3",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
@@ -426,11 +434,13 @@
 	if ((err = pcibios_enable_resources(dev, mask)) < 0)
 		return err;
 
-	return pcibios_enable_irq(dev);
+	if (!dev->msi_enabled)
+		return pcibios_enable_irq(dev);
+	return 0;
 }
 
 void pcibios_disable_device (struct pci_dev *dev)
 {
-	if (pcibios_disable_irq)
+	if (!dev->msi_enabled && pcibios_disable_irq)
 		pcibios_disable_irq(dev);
 }
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index d51f0f1..e19185d 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -13,6 +13,7 @@
 	bool
 	select PCI if (!IA64_HP_SIM)
 	select ACPI if (!IA64_HP_SIM)
+	select PM if (!IA64_HP_SIM)
 	default y
 	help
 	  The Itanium Processor Family is Intel's 64-bit successor to
diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig
index 9d1cffb..a144693 100644
--- a/arch/ia64/configs/tiger_defconfig
+++ b/arch/ia64/configs/tiger_defconfig
@@ -1,8 +1,9 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc5
-# Mon Feb 27 15:49:18 2006
+# Linux kernel version: 2.6.21-rc3
+# Thu Mar  8 11:07:09 2007
 #
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
@@ -18,16 +19,24 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 # CONFIG_CPUSETS is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -39,11 +48,9 @@
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -54,7 +61,6 @@
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 CONFIG_KMOD=y
@@ -63,6 +69,8 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
 
 #
 # IO Schedulers
@@ -82,15 +90,20 @@
 #
 CONFIG_IA64=y
 CONFIG_64BIT=y
+CONFIG_ZONE_DMA=y
 CONFIG_MMU=y
 CONFIG_SWIOTLB=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_TIME_INTERPOLATION=y
+CONFIG_DMI=y
 CONFIG_EFI=y
 CONFIG_GENERIC_IOMAP=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_DMA_IS_DMA32=y
+CONFIG_AUDIT_ARCH=y
 # CONFIG_IA64_GENERIC is not set
 CONFIG_IA64_DIG=y
 # CONFIG_IA64_HP_ZX1 is not set
@@ -107,6 +120,7 @@
 # CONFIG_PGTABLE_4 is not set
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
 CONFIG_IA64_L1_CACHE_SHIFT=7
@@ -116,9 +130,10 @@
 CONFIG_SMP=y
 CONFIG_NR_CPUS=16
 CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_SCHED_SMT is not set
 CONFIG_PERMIT_BSP_REMOVE=y
 CONFIG_FORCE_CPEI_RETARGET=y
-# CONFIG_SCHED_SMT is not set
 # CONFIG_PREEMPT is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
@@ -128,10 +143,13 @@
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_VIRTUAL_MEM_MAP=y
 CONFIG_HOLES_IN_ZONE=y
 CONFIG_IA32_SUPPORT=y
@@ -139,6 +157,9 @@
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
+# CONFIG_IA64_ESI is not set
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
 
 #
 # Firmware Drivers
@@ -154,13 +175,16 @@
 CONFIG_PM=y
 CONFIG_PM_LEGACY=y
 # CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
 
 #
 # ACPI (Advanced Configuration and Power Interface) Support
 #
 CONFIG_ACPI=y
+CONFIG_ACPI_PROCFS=y
 CONFIG_ACPI_BUTTON=m
 CONFIG_ACPI_FAN=m
+# CONFIG_ACPI_DOCK is not set
 CONFIG_ACPI_PROCESSOR=m
 CONFIG_ACPI_HOTPLUG_CPU=y
 CONFIG_ACPI_THERMAL=m
@@ -181,8 +205,8 @@
 #
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY_PROC=y
 # CONFIG_PCI_DEBUG is not set
 
 #
@@ -212,6 +236,10 @@
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -226,12 +254,21 @@
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -257,7 +294,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -286,6 +322,8 @@
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=m
 # CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -329,11 +367,17 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
@@ -350,6 +394,7 @@
 # CONFIG_BLK_DEV_IDETAPE is not set
 CONFIG_BLK_DEV_IDEFLOPPY=y
 CONFIG_BLK_DEV_IDESCSI=m
+# CONFIG_BLK_DEV_IDEACPI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
 
 #
@@ -376,8 +421,10 @@
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 CONFIG_BLK_DEV_PIIX=y
+# CONFIG_BLK_DEV_IT8213 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
@@ -387,6 +434,7 @@
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
@@ -398,6 +446,8 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+CONFIG_SCSI_NETLINK=y
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -417,14 +467,16 @@
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=y
 CONFIG_SCSI_FC_ATTRS=y
 # CONFIG_SCSI_ISCSI_ATTRS is not set
 # CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
@@ -437,29 +489,36 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 CONFIG_SCSI_SYM53C8XX_2=y
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
-# CONFIG_SCSI_IPR is not set
-CONFIG_SCSI_QLOGIC_FC=y
-# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+CONFIG_SCSI_SYM53C8XX_MMIO=y
 CONFIG_SCSI_QLOGIC_1280=y
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -470,11 +529,11 @@
 CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
-CONFIG_MD_RAID5=m
-CONFIG_MD_RAID6=m
+# CONFIG_MD_RAID456 is not set
 CONFIG_MD_MULTIPATH=m
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
@@ -563,6 +622,7 @@
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -583,13 +643,18 @@
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
 # CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
 
 #
 # Token Ring devices
@@ -631,6 +696,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -653,6 +719,7 @@
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_SERIAL is not set
@@ -682,6 +749,7 @@
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_COMPUTONE is not set
 # CONFIG_ROCKETPORT is not set
@@ -689,12 +757,14 @@
 # CONFIG_DIGIEPCA is not set
 # CONFIG_MOXA_INTELLIO is not set
 # CONFIG_MOXA_SMARTIO is not set
+# CONFIG_MOXA_SMARTIO_NEW is not set
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINKMP is not set
 # CONFIG_SYNCLINK_GT is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_SPECIALIX is not set
 # CONFIG_SX is not set
+# CONFIG_RIO is not set
 # CONFIG_STALDRV is not set
 
 #
@@ -702,7 +772,8 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_ACPI=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
 CONFIG_SERIAL_8250_NR_UARTS=6
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
@@ -734,10 +805,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 CONFIG_AGP=m
 CONFIG_AGP_I460=m
 CONFIG_DRM=m
@@ -759,7 +826,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -782,16 +848,16 @@
 #
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
 # CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
-# Misc devices
+# Multifunction device drivers
 #
-
-#
-# Multimedia Capabilities Port drivers
-#
+# CONFIG_MFD_SM501 is not set
 
 #
 # Multimedia devices
@@ -802,16 +868,19 @@
 # Digital Video Broadcasting Devices
 #
 # CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
 
 #
 # Graphics support
 #
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 # CONFIG_FB is not set
 
 #
 # Console display driver support
 #
 CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
 CONFIG_DUMMY_CONSOLE=y
 
 #
@@ -820,10 +889,17 @@
 # CONFIG_SOUND is not set
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -831,7 +907,6 @@
 # Miscellaneous USB options
 #
 CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
@@ -842,9 +917,12 @@
 CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=m
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_UHCI_HCD=y
 # CONFIG_USB_SL811_HCD is not set
@@ -873,13 +951,13 @@
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
 #
 CONFIG_USB_HID=y
-CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_HIDINPUT_POWERBOOK is not set
 # CONFIG_HID_FF is not set
 # CONFIG_USB_HIDDEV is not set
@@ -888,15 +966,14 @@
 # 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_TOUCHSCREEN is not set
 # CONFIG_USB_YEALINK is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
 
 #
 # USB Imaging devices
@@ -905,21 +982,13 @@
 # CONFIG_USB_MICROTEK is not set
 
 #
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
 # USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
 # CONFIG_USB_MON is not set
 
@@ -937,17 +1006,23 @@
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -965,15 +1040,55 @@
 # CONFIG_MMC is not set
 
 #
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
 # InfiniBand support
 #
 # CONFIG_INFINIBAND is not set
 
 #
-# EDAC - error detection and reporting (RAS)
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
 #
 
 #
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+# CONFIG_MSPEC is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -985,6 +1100,7 @@
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -997,15 +1113,16 @@
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 CONFIG_XFS_FS=y
-CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=y
@@ -1038,12 +1155,13 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -1078,7 +1196,7 @@
 CONFIG_NFSD_TCP=y
 CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=y
+CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
 CONFIG_SUNRPC_GSS=m
@@ -1089,7 +1207,9 @@
 CONFIG_SMB_NLS_REMOTE="cp437"
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
 # CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1162,15 +1282,25 @@
 CONFIG_NLS_UTF8=m
 
 #
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_IRQ_PER_CPU=y
 
 #
 # Instrumentation Support
@@ -1182,21 +1312,31 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
 CONFIG_LOG_BUF_SHIFT=20
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
 CONFIG_IA64_GRANULE_16MB=y
 # CONFIG_IA64_GRANULE_64MB is not set
 # CONFIG_IA64_PRINT_HAZARDS is not set
@@ -1215,7 +1355,11 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_MANAGER=m
 # CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
@@ -1224,7 +1368,13 @@
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
 CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
 # CONFIG_CRYPTO_SERPENT is not set
@@ -1238,6 +1388,7 @@
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_TEST is not set
 
 #
diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig
index 949dc46..1c7955c 100644
--- a/arch/ia64/configs/zx1_defconfig
+++ b/arch/ia64/configs/zx1_defconfig
@@ -1,8 +1,9 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc5
-# Mon Feb 27 15:55:36 2006
+# Linux kernel version: 2.6.21-rc3
+# Thu Mar  8 11:04:20 2007
 #
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
@@ -18,16 +19,24 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_CPUSETS is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -39,11 +48,9 @@
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -53,14 +60,16 @@
 #
 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
+CONFIG_STOP_MACHINE=y
 
 #
 # Block layer
 #
+CONFIG_BLOCK=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
 
 #
 # IO Schedulers
@@ -80,15 +89,19 @@
 #
 CONFIG_IA64=y
 CONFIG_64BIT=y
+CONFIG_ZONE_DMA=y
 CONFIG_MMU=y
-CONFIG_SWIOTLB=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_TIME_INTERPOLATION=y
+CONFIG_DMI=y
 CONFIG_EFI=y
 CONFIG_GENERIC_IOMAP=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_DMA_IS_DMA32=y
+CONFIG_AUDIT_ARCH=y
 # CONFIG_IA64_GENERIC is not set
 # CONFIG_IA64_DIG is not set
 CONFIG_IA64_HP_ZX1=y
@@ -105,6 +118,7 @@
 # CONFIG_PGTABLE_4 is not set
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
 CONFIG_IA64_L1_CACHE_SHIFT=7
@@ -113,8 +127,10 @@
 CONFIG_FORCE_MAX_ZONEORDER=17
 CONFIG_SMP=y
 CONFIG_NR_CPUS=16
-# CONFIG_HOTPLUG_CPU is not set
+CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 # CONFIG_SCHED_SMT is not set
+# CONFIG_PERMIT_BSP_REMOVE is not set
 # CONFIG_PREEMPT is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
@@ -124,11 +140,14 @@
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_VIRTUAL_MEM_MAP=y
 CONFIG_HOLES_IN_ZONE=y
 CONFIG_IA32_SUPPORT=y
@@ -136,6 +155,9 @@
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
+# CONFIG_IA64_ESI is not set
+# CONFIG_KEXEC is not set
+CONFIG_CRASH_DUMP=y
 
 #
 # Firmware Drivers
@@ -151,21 +173,25 @@
 CONFIG_PM=y
 CONFIG_PM_LEGACY=y
 # CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
 
 #
 # ACPI (Advanced Configuration and Power Interface) Support
 #
 CONFIG_ACPI=y
+CONFIG_ACPI_PROCFS=y
 CONFIG_ACPI_BUTTON=y
 CONFIG_ACPI_FAN=y
+# CONFIG_ACPI_DOCK is not set
 CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_HOTPLUG_CPU=y
 CONFIG_ACPI_THERMAL=y
 CONFIG_ACPI_BLACKLIST_YEAR=0
 # CONFIG_ACPI_DEBUG is not set
 CONFIG_ACPI_EC=y
 CONFIG_ACPI_POWER=y
 CONFIG_ACPI_SYSTEM=y
-# CONFIG_ACPI_CONTAINER is not set
+CONFIG_ACPI_CONTAINER=y
 
 #
 # CPU Frequency scaling
@@ -177,8 +203,8 @@
 #
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY_PROC=y
 # CONFIG_PCI_DEBUG is not set
 
 #
@@ -208,6 +234,10 @@
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -222,17 +252,26 @@
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
 
 #
 # IP: Virtual Server Configuration
 #
 # CONFIG_IP_VS is not set
 # CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
 
@@ -240,14 +279,15 @@
 # Core Netfilter Configuration
 #
 # CONFIG_NETFILTER_NETLINK is not set
-# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NF_CONNTRACK_ENABLED is not set
 # CONFIG_NETFILTER_XTABLES is not set
 
 #
 # IP: Netfilter Configuration
 #
-# CONFIG_IP_NF_CONNTRACK is not set
 # CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
 
 #
 # DCCP Configuration (EXPERIMENTAL)
@@ -272,7 +312,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -285,6 +324,7 @@
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
@@ -301,6 +341,8 @@
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
 # CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -344,11 +386,17 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
@@ -365,6 +413,7 @@
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_BLK_DEV_IDEACPI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
 
 #
@@ -390,8 +439,10 @@
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8213 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
@@ -401,6 +452,7 @@
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
@@ -412,6 +464,8 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+CONFIG_SCSI_NETLINK=y
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -431,14 +485,16 @@
 CONFIG_SCSI_MULTI_LUN=y
 CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_LOGGING=y
+# CONFIG_SCSI_SCAN_ASYNC is not set
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=y
 CONFIG_SCSI_FC_ATTRS=y
 # CONFIG_SCSI_ISCSI_ATTRS is not set
 # CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
@@ -451,28 +507,36 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 CONFIG_SCSI_SYM53C8XX_2=y
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
+CONFIG_SCSI_SYM53C8XX_MMIO=y
 CONFIG_SCSI_QLOGIC_1280=y
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -562,6 +626,7 @@
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -582,13 +647,18 @@
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
 # CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
 
 #
 # Token Ring devices
@@ -628,6 +698,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -666,6 +737,7 @@
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -673,7 +745,8 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_ACPI=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
 CONFIG_SERIAL_8250_NR_UARTS=8
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
@@ -705,10 +778,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 CONFIG_AGP=y
 CONFIG_AGP_HP_ZX1=y
 CONFIG_DRM=y
@@ -727,7 +796,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -754,10 +822,11 @@
 # CONFIG_I2C_I810 is not set
 # CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PASEMI is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_SCx200_ACB is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
@@ -776,9 +845,7 @@
 # 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_RTC_X1205_I2C is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -802,28 +869,31 @@
 # CONFIG_HWMON_VID is not set
 
 #
-# Misc devices
+# Multifunction device drivers
 #
-
-#
-# Multimedia Capabilities Port drivers
-#
+# CONFIG_MFD_SM501 is not set
 
 #
 # Multimedia devices
 #
 CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
 
 #
-# Video For Linux
+# Video Capture Adapters
 #
 
 #
-# Video Adapters
+# Video Capture Adapters
 #
 # CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+# CONFIG_VIDEO_VIVI is not set
 # CONFIG_VIDEO_BT848 is not set
 # CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
 # CONFIG_VIDEO_SAA5246A is not set
 # CONFIG_VIDEO_SAA5249 is not set
 # CONFIG_TUNER_3036 is not set
@@ -835,10 +905,27 @@
 # CONFIG_VIDEO_HEXIUM_ORION is not set
 # CONFIG_VIDEO_HEXIUM_GEMINI is not set
 # CONFIG_VIDEO_CX88 is not set
+# CONFIG_VIDEO_CAFE_CCIC is not set
+
+#
+# V4L USB devices
+#
+# CONFIG_VIDEO_PVRUSB2 is not set
 # CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_USBVISION is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
 # CONFIG_VIDEO_OVCAMCHIP is not set
-# CONFIG_VIDEO_AUDIO_DECODER is not set
-# CONFIG_VIDEO_DECODER is not set
+# CONFIG_USB_W9968CF is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_ZC0301 is not set
+# CONFIG_USB_PWC is not set
 
 #
 # Radio Adapters
@@ -846,22 +933,35 @@
 # CONFIG_RADIO_GEMTEK_PCI is not set
 # CONFIG_RADIO_MAXIRADIO is not set
 # CONFIG_RADIO_MAESTRO is not set
+# CONFIG_USB_DSBR is not set
 
 #
 # Digital Video Broadcasting Devices
 #
 # CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
 
 #
 # Graphics support
 #
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=m
 CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB_DDC=y
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
+CONFIG_FB_BACKLIGHT=y
 CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frambuffer hardware drivers
+#
 # CONFIG_FB_CIRRUS is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
@@ -871,12 +971,13 @@
 # CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
 CONFIG_FB_RADEON=y
 CONFIG_FB_RADEON_I2C=y
+CONFIG_FB_RADEON_BACKLIGHT=y
 CONFIG_FB_RADEON_DEBUG=y
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
@@ -890,6 +991,7 @@
 # Console display driver support
 #
 CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
 # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
@@ -904,7 +1006,6 @@
 # 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
@@ -924,9 +1025,11 @@
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=y
 CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
 CONFIG_SND_SEQUENCER_OSS=y
 # CONFIG_SND_DYNAMIC_MINORS is not set
 CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
 
@@ -936,7 +1039,6 @@
 CONFIG_SND_MPU401_UART=y
 CONFIG_SND_OPL3_LIB=y
 CONFIG_SND_AC97_CODEC=y
-CONFIG_SND_AC97_BUS=y
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_VIRMIDI is not set
 # CONFIG_SND_MTPAV is not set
@@ -947,6 +1049,7 @@
 # PCI devices
 #
 # CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
 # CONFIG_SND_ALI5451 is not set
 # CONFIG_SND_ATIIXP is not set
 # CONFIG_SND_ATIIXP_MODEM is not set
@@ -959,6 +1062,18 @@
 # CONFIG_SND_CMIPCI is not set
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_CS46XX is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
 # CONFIG_SND_EMU10K1 is not set
 # CONFIG_SND_EMU10K1X is not set
 # CONFIG_SND_ENS1370 is not set
@@ -966,7 +1081,7 @@
 # CONFIG_SND_ES1938 is not set
 # CONFIG_SND_ES1968 is not set
 CONFIG_SND_FM801=y
-CONFIG_SND_FM801_TEA575X=y
+# CONFIG_SND_FM801_TEA575X_BOOL is not set
 # CONFIG_SND_HDA_INTEL is not set
 # CONFIG_SND_HDSP is not set
 # CONFIG_SND_HDSPM is not set
@@ -979,6 +1094,7 @@
 # CONFIG_SND_MIXART is not set
 # CONFIG_SND_NM256 is not set
 # CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
 # CONFIG_SND_RME32 is not set
 # CONFIG_SND_RME96 is not set
 # CONFIG_SND_RME9652 is not set
@@ -988,6 +1104,7 @@
 # CONFIG_SND_VIA82XX_MODEM is not set
 # CONFIG_SND_VX222 is not set
 # CONFIG_SND_YMFPCI is not set
+# CONFIG_SND_AC97_POWER_SAVE is not set
 
 #
 # USB devices
@@ -995,15 +1112,28 @@
 # CONFIG_SND_USB_AUDIO is not set
 
 #
+# SoC audio support
+#
+# CONFIG_SND_SOC is not set
+
+#
 # Open Sound System
 #
 # CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
 
 #
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -1011,7 +1141,6 @@
 # Miscellaneous USB options
 #
 # CONFIG_USB_DEVICEFS is not set
-CONFIG_USB_BANDWIDTH=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
@@ -1022,9 +1151,12 @@
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_UHCI_HCD=y
 # CONFIG_USB_SL811_HCD is not set
@@ -1032,7 +1164,6 @@
 #
 # USB Device Class drivers
 #
-# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
 
@@ -1054,13 +1185,13 @@
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
 #
 CONFIG_USB_HID=y
-CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_HIDINPUT_POWERBOOK is not set
 # CONFIG_HID_FF is not set
 CONFIG_USB_HIDDEV=y
@@ -1069,15 +1200,14 @@
 # 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_TOUCHSCREEN is not set
 # CONFIG_USB_YEALINK is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
 
 #
 # USB Imaging devices
@@ -1086,27 +1216,13 @@
 # CONFIG_USB_MICROTEK is not set
 
 #
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_VICAM is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_ET61X251 is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_KONICAWC is not set
-# CONFIG_USB_OV511 is not set
-# 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
 #
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
 CONFIG_USB_MON=y
 
@@ -1124,17 +1240,23 @@
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
 
 #
 # USB DSL modem support
@@ -1151,15 +1273,55 @@
 # CONFIG_MMC is not set
 
 #
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
 # InfiniBand support
 #
 # CONFIG_INFINIBAND is not set
 
 #
-# EDAC - error detection and reporting (RAS)
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
 #
 
 #
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+# CONFIG_MSPEC is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -1171,6 +1333,7 @@
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1178,6 +1341,7 @@
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1212,12 +1376,14 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_VMCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -1331,15 +1497,25 @@
 CONFIG_NLS_UTF8=y
 
 #
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_IRQ_PER_CPU=y
 
 #
 # Instrumentation Support
@@ -1351,21 +1527,32 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
 CONFIG_LOG_BUF_SHIFT=17
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
 CONFIG_IA64_GRANULE_16MB=y
 # CONFIG_IA64_GRANULE_64MB is not set
 CONFIG_IA64_PRINT_HAZARDS=y
@@ -1384,7 +1571,11 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
 # CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
@@ -1393,7 +1584,13 @@
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
 CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
 # CONFIG_CRYPTO_SERPENT is not set
@@ -1407,6 +1604,7 @@
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_TEST is not set
 
 #
diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig
index 9001b3f..153bfdc 100644
--- a/arch/ia64/defconfig
+++ b/arch/ia64/defconfig
@@ -1,8 +1,9 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc5
-# Mon Feb 27 16:02:28 2006
+# Linux kernel version: 2.6.21-rc3
+# Thu Mar  8 11:01:03 2007
 #
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
 # Code maturity level options
@@ -18,16 +19,24 @@
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 # CONFIG_CPUSETS is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -39,11 +48,9 @@
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 # CONFIG_SLOB is not set
@@ -54,7 +61,6 @@
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 CONFIG_MODVERSIONS=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
@@ -63,6 +69,8 @@
 #
 # Block layer
 #
+CONFIG_BLOCK=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
 
 #
 # IO Schedulers
@@ -82,15 +90,20 @@
 #
 CONFIG_IA64=y
 CONFIG_64BIT=y
+CONFIG_ZONE_DMA=y
 CONFIG_MMU=y
 CONFIG_SWIOTLB=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_TIME_INTERPOLATION=y
+CONFIG_DMI=y
 CONFIG_EFI=y
 CONFIG_GENERIC_IOMAP=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_DMA_IS_DMA32=y
+CONFIG_AUDIT_ARCH=y
 CONFIG_IA64_GENERIC=y
 # CONFIG_IA64_DIG is not set
 # CONFIG_IA64_HP_ZX1 is not set
@@ -107,6 +120,7 @@
 # CONFIG_PGTABLE_4 is not set
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
 CONFIG_IA64_L1_CACHE_SHIFT=7
@@ -116,9 +130,10 @@
 CONFIG_FORCE_MAX_ZONEORDER=17
 CONFIG_SMP=y
 CONFIG_NR_CPUS=512
-CONFIG_IA64_NR_NODES=256
 CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 # CONFIG_SCHED_SMT is not set
+# CONFIG_PERMIT_BSP_REMOVE is not set
 # CONFIG_PREEMPT is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 # CONFIG_FLATMEM_MANUAL is not set
@@ -130,21 +145,34 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
 CONFIG_NUMA=y
+CONFIG_NODES_SHIFT=10
+CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_VIRTUAL_MEM_MAP=y
 CONFIG_HOLES_IN_ZONE=y
 CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
+CONFIG_HAVE_ARCH_NODEDATA_EXTENSION=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_COMPAT=y
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
 CONFIG_SGI_SN=y
+# CONFIG_IA64_ESI is not set
+
+#
+# SN Devices
+#
+CONFIG_SGI_IOC3=m
+CONFIG_KEXEC=y
+CONFIG_CRASH_DUMP=y
 
 #
 # Firmware Drivers
@@ -160,13 +188,16 @@
 CONFIG_PM=y
 CONFIG_PM_LEGACY=y
 # CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
 
 #
 # ACPI (Advanced Configuration and Power Interface) Support
 #
 CONFIG_ACPI=y
+CONFIG_ACPI_PROCFS=y
 CONFIG_ACPI_BUTTON=m
 CONFIG_ACPI_FAN=m
+# CONFIG_ACPI_DOCK is not set
 CONFIG_ACPI_PROCESSOR=m
 CONFIG_ACPI_HOTPLUG_CPU=y
 CONFIG_ACPI_THERMAL=m
@@ -188,8 +219,8 @@
 #
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY_PROC=y
 # CONFIG_PCI_DEBUG is not set
 
 #
@@ -220,6 +251,10 @@
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -234,12 +269,21 @@
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -265,7 +309,6 @@
 # CONFIG_ATALK is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 
@@ -294,6 +337,8 @@
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=m
 # CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
@@ -337,11 +382,17 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
 #
+# Misc devices
+#
+CONFIG_SGI_IOC4=y
+# CONFIG_TIFM_CORE is not set
+
+#
 # ATA/ATAPI/MFM/RLL support
 #
 CONFIG_IDE=y
@@ -358,6 +409,7 @@
 # CONFIG_BLK_DEV_IDETAPE is not set
 CONFIG_BLK_DEV_IDEFLOPPY=y
 CONFIG_BLK_DEV_IDESCSI=m
+# CONFIG_BLK_DEV_IDEACPI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
 
 #
@@ -384,8 +436,10 @@
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 CONFIG_BLK_DEV_PIIX=y
+# CONFIG_BLK_DEV_IT8213 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
@@ -396,6 +450,7 @@
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
@@ -407,6 +462,8 @@
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+CONFIG_SCSI_NETLINK=y
 CONFIG_SCSI_PROC_FS=y
 
 #
@@ -426,14 +483,16 @@
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
 
 #
-# SCSI Transport Attributes
+# SCSI Transports
 #
 CONFIG_SCSI_SPI_ATTRS=y
 CONFIG_SCSI_FC_ATTRS=y
 # CONFIG_SCSI_ISCSI_ATTRS is not set
 # CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
 # SCSI low-level drivers
@@ -446,43 +505,36 @@
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-# CONFIG_SCSI_SATA_SVW is not set
-# CONFIG_SCSI_ATA_PIIX is not set
-# CONFIG_SCSI_SATA_MV is not set
-# CONFIG_SCSI_SATA_NV is not set
-# CONFIG_SCSI_PDC_ADMA is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-# CONFIG_SCSI_SATA_SIL is not set
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-# CONFIG_SCSI_SATA_VIA is not set
-CONFIG_SCSI_SATA_VITESSE=y
+# CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
 CONFIG_SCSI_SYM53C8XX_2=y
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
+CONFIG_SCSI_SYM53C8XX_MMIO=y
 CONFIG_SCSI_QLOGIC_1280=y
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -493,11 +545,11 @@
 CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
-CONFIG_MD_RAID5=m
-CONFIG_MD_RAID6=m
+# CONFIG_MD_RAID456 is not set
 CONFIG_MD_MULTIPATH=m
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
@@ -587,6 +639,7 @@
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -607,13 +660,18 @@
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
 # CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
 
 #
 # Token Ring devices
@@ -655,6 +713,7 @@
 # Input device support
 #
 CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
 
 #
 # Userland interfaces
@@ -677,6 +736,7 @@
 # CONFIG_KEYBOARD_LKKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_SERIAL is not set
@@ -706,6 +766,7 @@
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_COMPUTONE is not set
 # CONFIG_ROCKETPORT is not set
@@ -713,12 +774,14 @@
 # CONFIG_DIGIEPCA is not set
 # CONFIG_MOXA_INTELLIO is not set
 # CONFIG_MOXA_SMARTIO is not set
+# CONFIG_MOXA_SMARTIO_NEW is not set
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINKMP is not set
 # CONFIG_SYNCLINK_GT is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_SPECIALIX is not set
 # CONFIG_SX is not set
+# CONFIG_RIO is not set
 # CONFIG_STALDRV is not set
 CONFIG_SGI_SNSC=y
 CONFIG_SGI_TIOCX=y
@@ -729,7 +792,8 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_ACPI=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
 CONFIG_SERIAL_8250_NR_UARTS=6
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
@@ -764,10 +828,6 @@
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
 CONFIG_AGP=m
 CONFIG_AGP_I460=m
 CONFIG_AGP_HP_ZX1=m
@@ -792,7 +852,6 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -815,16 +874,16 @@
 #
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
 # CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_VT1211 is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
-# Misc devices
+# Multifunction device drivers
 #
-
-#
-# Multimedia Capabilities Port drivers
-#
+# CONFIG_MFD_SM501 is not set
 
 #
 # Multimedia devices
@@ -835,16 +894,19 @@
 # Digital Video Broadcasting Devices
 #
 # CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
 
 #
 # Graphics support
 #
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 # CONFIG_FB is not set
 
 #
 # Console display driver support
 #
 CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
 CONFIG_DUMMY_CONSOLE=y
 
 #
@@ -865,9 +927,11 @@
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=m
 CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
 CONFIG_SND_SEQUENCER_OSS=y
 # CONFIG_SND_DYNAMIC_MINORS is not set
 CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
 CONFIG_SND_VERBOSE_PRINTK=y
 # CONFIG_SND_DEBUG is not set
 
@@ -877,7 +941,6 @@
 CONFIG_SND_MPU401_UART=m
 CONFIG_SND_OPL3_LIB=m
 CONFIG_SND_AC97_CODEC=m
-CONFIG_SND_AC97_BUS=m
 CONFIG_SND_DUMMY=m
 CONFIG_SND_VIRMIDI=m
 CONFIG_SND_MTPAV=m
@@ -888,6 +951,7 @@
 # PCI devices
 #
 # CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
 # CONFIG_SND_ALI5451 is not set
 # CONFIG_SND_ATIIXP is not set
 # CONFIG_SND_ATIIXP_MODEM is not set
@@ -901,6 +965,18 @@
 CONFIG_SND_CS4281=m
 CONFIG_SND_CS46XX=m
 CONFIG_SND_CS46XX_NEW_DSP=y
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
 CONFIG_SND_EMU10K1=m
 # CONFIG_SND_EMU10K1X is not set
 # CONFIG_SND_ENS1370 is not set
@@ -908,7 +984,7 @@
 # CONFIG_SND_ES1938 is not set
 # CONFIG_SND_ES1968 is not set
 CONFIG_SND_FM801=m
-# CONFIG_SND_FM801_TEA575X is not set
+# CONFIG_SND_FM801_TEA575X_BOOL is not set
 # CONFIG_SND_HDA_INTEL is not set
 # CONFIG_SND_HDSP is not set
 # CONFIG_SND_HDSPM is not set
@@ -921,6 +997,7 @@
 # CONFIG_SND_MIXART is not set
 # CONFIG_SND_NM256 is not set
 # CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
 # CONFIG_SND_RME32 is not set
 # CONFIG_SND_RME96 is not set
 # CONFIG_SND_RME9652 is not set
@@ -930,6 +1007,7 @@
 # CONFIG_SND_VIA82XX_MODEM is not set
 # CONFIG_SND_VX222 is not set
 # CONFIG_SND_YMFPCI is not set
+# CONFIG_SND_AC97_POWER_SAVE is not set
 
 #
 # USB devices
@@ -937,15 +1015,28 @@
 # CONFIG_SND_USB_AUDIO is not set
 
 #
+# SoC audio support
+#
+# CONFIG_SND_SOC is not set
+
+#
 # Open Sound System
 #
 # CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
 
 #
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=m
 # CONFIG_USB_DEBUG is not set
 
@@ -953,7 +1044,6 @@
 # Miscellaneous USB options
 #
 CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
@@ -964,9 +1054,12 @@
 CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=m
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_UHCI_HCD=m
 # CONFIG_USB_SL811_HCD is not set
@@ -974,7 +1067,6 @@
 #
 # USB Device Class drivers
 #
-# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
 
@@ -996,13 +1088,13 @@
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
 #
 CONFIG_USB_HID=m
-CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_HIDINPUT_POWERBOOK is not set
 # CONFIG_HID_FF is not set
 # CONFIG_USB_HIDDEV is not set
@@ -1017,15 +1109,14 @@
 # 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_TOUCHSCREEN is not set
 # CONFIG_USB_YEALINK is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
 
 #
 # USB Imaging devices
@@ -1034,21 +1125,13 @@
 # CONFIG_USB_MICROTEK is not set
 
 #
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
 # USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
 # CONFIG_USB_USBNET is not set
 CONFIG_USB_MON=y
 
@@ -1066,17 +1149,23 @@
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1094,26 +1183,65 @@
 # CONFIG_MMC is not set
 
 #
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
 # InfiniBand support
 #
 CONFIG_INFINIBAND=m
 # CONFIG_INFINIBAND_USER_MAD is not set
 # CONFIG_INFINIBAND_USER_ACCESS is not set
+CONFIG_INFINIBAND_ADDR_TRANS=y
 CONFIG_INFINIBAND_MTHCA=m
-# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
+CONFIG_INFINIBAND_MTHCA_DEBUG=y
+# CONFIG_INFINIBAND_AMSO1100 is not set
 CONFIG_INFINIBAND_IPOIB=m
-# CONFIG_INFINIBAND_IPOIB_DEBUG is not set
+# CONFIG_INFINIBAND_IPOIB_CM is not set
+CONFIG_INFINIBAND_IPOIB_DEBUG=y
+# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set
 # CONFIG_INFINIBAND_SRP is not set
+# CONFIG_INFINIBAND_ISER is not set
 
 #
-# SN Devices
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
 #
-CONFIG_SGI_IOC4=y
-CONFIG_SGI_IOC3=m
 
 #
-# EDAC - error detection and reporting (RAS)
+# Real Time Clock
 #
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+# CONFIG_MSPEC is not set
 
 #
 # File systems
@@ -1127,6 +1255,7 @@
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
 CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -1139,15 +1268,16 @@
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 CONFIG_XFS_FS=y
-CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=y
@@ -1180,12 +1310,14 @@
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
+CONFIG_PROC_VMCORE=y
+CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -1220,7 +1352,7 @@
 CONFIG_NFSD_TCP=y
 CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=y
+CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
 CONFIG_SUNRPC_GSS=m
@@ -1231,7 +1363,9 @@
 CONFIG_SMB_NLS_REMOTE="cp437"
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
 # CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1304,15 +1438,25 @@
 CONFIG_NLS_UTF8=m
 
 #
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
 # Library routines
 #
+CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_IRQ_PER_CPU=y
 
 #
 # HP Simulator drivers
@@ -1331,21 +1475,31 @@
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
 CONFIG_LOG_BUF_SHIFT=20
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
 CONFIG_IA64_GRANULE_16MB=y
 # CONFIG_IA64_GRANULE_64MB is not set
 # CONFIG_IA64_PRINT_HAZARDS is not set
@@ -1364,7 +1518,11 @@
 # Cryptographic options
 #
 CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_MANAGER=m
 # CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
@@ -1373,7 +1531,13 @@
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
 CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
 # CONFIG_CRYPTO_SERPENT is not set
@@ -1387,6 +1551,7 @@
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_TEST is not set
 
 #
diff --git a/arch/ia64/kernel/asm-offsets.c b/arch/ia64/kernel/asm-offsets.c
index 75a2a2c..2236fab 100644
--- a/arch/ia64/kernel/asm-offsets.c
+++ b/arch/ia64/kernel/asm-offsets.c
@@ -35,6 +35,7 @@
 	BLANK();
 
 	DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+	DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
 	DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
 
 	BLANK();
diff --git a/arch/ia64/kernel/crash.c b/arch/ia64/kernel/crash.c
index 5cdd2f5..80a94e7 100644
--- a/arch/ia64/kernel/crash.c
+++ b/arch/ia64/kernel/crash.c
@@ -21,9 +21,9 @@
 #include <asm/mca.h>
 
 int kdump_status[NR_CPUS];
-atomic_t kdump_cpu_freezed;
+static atomic_t kdump_cpu_frozen;
 atomic_t kdump_in_progress;
-int kdump_on_init = 1;
+static int kdump_on_init = 1;
 
 static inline Elf64_Word
 *append_elf_note(Elf64_Word *buf, char *name, unsigned type, void *data,
@@ -86,7 +86,7 @@
 	int cpu_num = num_online_cpus() - 1;
 	int timeout = 1000;
 	while(timeout-- > 0) {
-		if (atomic_read(&kdump_cpu_freezed) == cpu_num)
+		if (atomic_read(&kdump_cpu_frozen) == cpu_num)
 			return 0;
 		udelay(1000);
 	}
@@ -108,8 +108,8 @@
 	kexec_disable_iosapic();
 #ifdef CONFIG_SMP
 	kdump_smp_send_stop();
+	/* not all cpu response to IPI, send INIT to freeze them */
 	if (kdump_wait_cpu_freeze() && kdump_on_init) 	{
-		//not all cpu response to IPI, send INIT to freeze them
 		kdump_smp_send_init();
 	}
 #endif
@@ -136,7 +136,7 @@
 	cpuid = smp_processor_id();
 	crash_save_this_cpu();
 	current->thread.ksp = (__u64)info->sw - 16;
-	atomic_inc(&kdump_cpu_freezed);
+	atomic_inc(&kdump_cpu_frozen);
 	kdump_status[cpuid] = 1;
 	mb();
 #ifdef CONFIG_HOTPLUG_CPU
@@ -164,7 +164,7 @@
 
 	nd = (struct ia64_mca_notify_die *)args->err;
 	/* Reason code 1 means machine check rendezous*/
-	if ((val == DIE_INIT_MONARCH_ENTER || DIE_INIT_SLAVE_ENTER) &&
+	if ((val == DIE_INIT_MONARCH_ENTER || val == DIE_INIT_SLAVE_ENTER) &&
 		 nd->sos->rv_rc == 1)
 		return NOTIFY_DONE;
 
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index 4061593..f45f91d 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -971,6 +971,11 @@
 		if (!is_memory_available(md))
 			continue;
 
+#ifdef CONFIG_CRASH_DUMP
+		/* saved_max_pfn should ignore max_addr= command line arg */
+		if (saved_max_pfn < (efi_md_end(md) >> PAGE_SHIFT))
+			saved_max_pfn = (efi_md_end(md) >> PAGE_SHIFT);
+#endif
 		/*
 		 * Round ends inward to granule boundaries
 		 * Give trimmings to uncached allocator
@@ -1010,11 +1015,6 @@
 		} else
 			ae = efi_md_end(md);
 
-#ifdef CONFIG_CRASH_DUMP
-		/* saved_max_pfn should ignore max_addr= command line arg */
-		if (saved_max_pfn < (ae >> PAGE_SHIFT))
-			saved_max_pfn = (ae >> PAGE_SHIFT);
-#endif
 		/* keep within max_addr= and min_addr= command line arg */
 		as = max(as, min_addr);
 		ae = min(ae, max_addr);
@@ -1142,7 +1142,7 @@
 /* find a block of memory aligned to 64M exclude reserved regions
    rsvd_regions are sorted
  */
-unsigned long
+unsigned long __init
 kdump_find_rsvd_region (unsigned long size,
 		struct rsvd_region *r, int n)
 {
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S
index 7a05b1c..8589e84 100644
--- a/arch/ia64/kernel/fsys.S
+++ b/arch/ia64/kernel/fsys.S
@@ -10,6 +10,8 @@
  *			probably broke it along the way... ;-)
  * 13-Jul-04 clameter   Implement fsys_clock_gettime and revise fsys_gettimeofday to make
  *                      it capable of using memory based clocks without falling back to C code.
+ * 08-Feb-07 Fenghua Yu Implement fsys_getcpu.
+ *
  */
 
 #include <asm/asmmacro.h>
@@ -505,6 +507,59 @@
 #endif
 END(fsys_rt_sigprocmask)
 
+/*
+ * fsys_getcpu doesn't use the third parameter in this implementation. It reads
+ * current_thread_info()->cpu and corresponding node in cpu_to_node_map.
+ */
+ENTRY(fsys_getcpu)
+	.prologue
+	.altrp b6
+	.body
+	;;
+	add r2=TI_FLAGS+IA64_TASK_SIZE,r16
+	tnat.nz p6,p0 = r32			// guard against NaT argument
+	add r3=TI_CPU+IA64_TASK_SIZE,r16
+	;;
+	ld4 r3=[r3]				// M r3 = thread_info->cpu
+	ld4 r2=[r2]				// M r2 = thread_info->flags
+(p6)    br.cond.spnt.few .fail_einval		// B
+	;;
+	tnat.nz p7,p0 = r33			// I guard against NaT argument
+(p7)    br.cond.spnt.few .fail_einval		// B
+#ifdef CONFIG_NUMA
+	movl r17=cpu_to_node_map
+	;;
+EX(.fail_efault, probe.w.fault r32, 3)		// M This takes 5 cycles
+EX(.fail_efault, probe.w.fault r33, 3)		// M This takes 5 cycles
+	shladd r18=r3,1,r17
+	;;
+	ld2 r20=[r18]				// r20 = cpu_to_node_map[cpu]
+	and r2 = TIF_ALLWORK_MASK,r2
+	;;
+	cmp.ne p8,p0=0,r2
+(p8)	br.spnt.many fsys_fallback_syscall
+	;;
+	;;
+EX(.fail_efault, st4 [r32] = r3)
+EX(.fail_efault, st2 [r33] = r20)
+	mov r8=0
+	;;
+#else
+EX(.fail_efault, probe.w.fault r32, 3)		// M This takes 5 cycles
+EX(.fail_efault, probe.w.fault r33, 3)		// M This takes 5 cycles
+	and r2 = TIF_ALLWORK_MASK,r2
+	;;
+	cmp.ne p8,p0=0,r2
+(p8)	br.spnt.many fsys_fallback_syscall
+	;;
+EX(.fail_efault, st4 [r32] = r3)
+EX(.fail_efault, st2 [r33] = r0)
+	mov r8=0
+	;;
+#endif
+	FSYS_RETURN
+END(fsys_getcpu)
+
 ENTRY(fsys_fallback_syscall)
 	.prologue
 	.altrp b6
@@ -878,6 +933,56 @@
 	data8 0				// timer_delete
 	data8 0				// clock_settime
 	data8 fsys_clock_gettime	// clock_gettime
+	data8 0				// clock_getres		// 1255
+	data8 0				// clock_nanosleep
+	data8 0				// fstatfs64
+	data8 0				// statfs64
+	data8 0				// mbind
+	data8 0				// get_mempolicy	// 1260
+	data8 0				// set_mempolicy
+	data8 0				// mq_open
+	data8 0				// mq_unlink
+	data8 0				// mq_timedsend
+	data8 0				// mq_timedreceive	// 1265
+	data8 0				// mq_notify
+	data8 0				// mq_getsetattr
+	data8 0				// kexec_load
+	data8 0				// vserver
+	data8 0				// waitid		// 1270
+	data8 0				// add_key
+	data8 0				// request_key
+	data8 0				// keyctl
+	data8 0				// ioprio_set
+	data8 0				// ioprio_get		// 1275
+	data8 0				// move_pages
+	data8 0				// inotify_init
+	data8 0				// inotify_add_watch
+	data8 0				// inotify_rm_watch
+	data8 0				// migrate_pages	// 1280
+	data8 0				// openat
+	data8 0				// mkdirat
+	data8 0				// mknodat
+	data8 0				// fchownat
+	data8 0				// futimesat		// 1285
+	data8 0				// newfstatat
+	data8 0				// unlinkat
+	data8 0				// renameat
+	data8 0				// linkat
+	data8 0				// symlinkat		// 1290
+	data8 0				// readlinkat
+	data8 0				// fchmodat
+	data8 0				// faccessat
+	data8 0
+	data8 0							// 1295
+	data8 0				// unshare
+	data8 0				// splice
+	data8 0				// set_robust_list
+	data8 0				// get_robust_list
+	data8 0				// sync_file_range	// 1300
+	data8 0				// tee
+	data8 0				// vmsplice
+	data8 0
+	data8 fsys_getcpu		// getcpu		// 1304
 
 	// fill in zeros for the remaining entries
 	.zero:
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index d6aab40..dcfbf3e 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -446,7 +446,7 @@
 #define iosapic_disable_level_irq	mask_irq
 #define iosapic_ack_level_irq		nop
 
-struct hw_interrupt_type irq_type_iosapic_level = {
+struct irq_chip irq_type_iosapic_level = {
 	.name =		"IO-SAPIC-level",
 	.startup =	iosapic_startup_level_irq,
 	.shutdown =	iosapic_shutdown_level_irq,
@@ -454,6 +454,8 @@
 	.disable =	iosapic_disable_level_irq,
 	.ack =		iosapic_ack_level_irq,
 	.end =		iosapic_end_level_irq,
+	.mask =		mask_irq,
+	.unmask =	unmask_irq,
 	.set_affinity =	iosapic_set_affinity
 };
 
@@ -493,7 +495,7 @@
 #define iosapic_disable_edge_irq	nop
 #define iosapic_end_edge_irq		nop
 
-struct hw_interrupt_type irq_type_iosapic_edge = {
+struct irq_chip irq_type_iosapic_edge = {
 	.name =		"IO-SAPIC-edge",
 	.startup =	iosapic_startup_edge_irq,
 	.shutdown =	iosapic_disable_edge_irq,
@@ -501,6 +503,8 @@
 	.disable =	iosapic_disable_edge_irq,
 	.ack =		iosapic_ack_edge_irq,
 	.end =		iosapic_end_edge_irq,
+	.mask =		mask_irq,
+	.unmask =	unmask_irq,
 	.set_affinity =	iosapic_set_affinity
 };
 
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index a76add3..491687f 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -1192,8 +1192,6 @@
 ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
 		 struct ia64_sal_os_state *sos)
 {
-	pal_processor_state_info_t *psp = (pal_processor_state_info_t *)
-		&sos->proc_state_param;
 	int recover, cpu = smp_processor_id();
 	struct task_struct *previous_current;
 	struct ia64_mca_notify_die nd =
@@ -1223,10 +1221,8 @@
 	/* Get the MCA error record and log it */
 	ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA);
 
-	/* TLB error is only exist in this SAL error record */
-	recover = (psp->tc && !(psp->cc || psp->bc || psp->rc || psp->uc))
-	/* other error recovery */
-	   || (ia64_mca_ucmc_extension
+	/* MCA error recovery */
+	recover = (ia64_mca_ucmc_extension
 		&& ia64_mca_ucmc_extension(
 			IA64_LOG_CURR_BUFFER(SAL_INFO_TYPE_MCA),
 			sos));
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c
index afc1403..832cf1e 100644
--- a/arch/ia64/kernel/mca_drv.c
+++ b/arch/ia64/kernel/mca_drv.c
@@ -602,11 +602,40 @@
 		default:
 			break;
 		}
+	} else if (psp->cc && !psp->bc) {	/* Cache error */
+		status = recover_from_read_error(slidx, peidx, pbci, sos);
 	}
 
 	return status;
 }
 
+/*
+ * recover_from_tlb_check
+ * @peidx:	pointer of index of processor error section
+ *
+ * Return value:
+ *	1 on Success / 0 on Failure
+ */
+static int
+recover_from_tlb_check(peidx_table_t *peidx)
+{
+	sal_log_mod_error_info_t *smei;
+	pal_tlb_check_info_t *ptci;
+
+	smei = (sal_log_mod_error_info_t *)peidx_tlb_check(peidx, 0);
+	ptci = (pal_tlb_check_info_t *)&(smei->check_info);
+
+	/*
+	 * Look for signature of a duplicate TLB DTC entry, which is
+	 * a SW bug and always fatal.
+	 */
+	if (ptci->op == PAL_TLB_CHECK_OP_PURGE
+	    && !(ptci->itr || ptci->dtc || ptci->itc))
+		return fatal_mca("Duplicate TLB entry");
+
+	return mca_recovered("TLB check recovered");
+}
+
 /**
  * recover_from_processor_error
  * @platform:	whether there are some platform error section or not
@@ -618,13 +647,6 @@
  * Return value:
  *	1 on Success / 0 on Failure
  */
-/*
- *  Later we try to recover when below all conditions are satisfied.
- *   1. Only one processor error section is exist.
- *   2. BUS_CHECK is exist and the others are not exist.(Except TLB_CHECK)
- *   3. The entry of BUS_CHECK_INFO is 1.
- *   4. "External bus error" flag is set and the others are not set.
- */
 
 static int
 recover_from_processor_error(int platform, slidx_table_t *slidx,
@@ -652,38 +674,39 @@
 		return fatal_mca("error not contained");
 
 	/*
-	 * The cache check and bus check bits have four possible states
-	 *   cc bc
-	 *    0  0	Weird record, not recovered
-	 *    1  0	Cache error, not recovered
-	 *    0  1	I/O error, attempt recovery
-	 *    1  1	Memory error, attempt recovery
+	 * Look for recoverable TLB check
 	 */
-	if (psp->bc == 0 || pbci == NULL)
-		return fatal_mca("No bus check");
+	if (psp->tc && !(psp->cc || psp->bc || psp->rc || psp->uc))
+		return recover_from_tlb_check(peidx);
 
 	/*
-	 * Sorry, we cannot handle so many.
+	 * The cache check and bus check bits have four possible states
+	 *   cc bc
+	 *    1  1	Memory error, attempt recovery
+	 *    1  0	Cache error, attempt recovery
+	 *    0  1	I/O error, attempt recovery
+	 *    0  0	Other error type, not recovered
+	 */
+	if (psp->cc == 0 && (psp->bc == 0 || pbci == NULL))
+		return fatal_mca("No cache or bus check");
+
+	/*
+	 * Cannot handle more than one bus check.
 	 */
 	if (peidx_bus_check_num(peidx) > 1)
 		return fatal_mca("Too many bus checks");
-	/*
-	 * Well, here is only one bus error.
-	 */
+
 	if (pbci->ib)
 		return fatal_mca("Internal Bus error");
-	if (pbci->cc)
-		return fatal_mca("Cache-cache error");
 	if (pbci->eb && pbci->bsi > 0)
 		return fatal_mca("External bus check fatal status");
 
 	/*
-	 * This is a local MCA and estimated as recoverble external bus error.
-	 * (e.g. a load from poisoned memory)
-	 * This means "there are some platform errors".
+	 * This is a local MCA and estimated as a recoverble error.
 	 */
 	if (platform)
 		return recover_from_platform_error(slidx, peidx, pbci, sos);
+
 	/*
 	 * On account of strange SAL error record, we cannot recover.
 	 */
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index e722090..c81080d 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -68,7 +68,7 @@
 {
 	struct msi_msg	msg;
 	unsigned long	dest_phys_id;
-	unsigned int	irq, vector;
+	int	irq, vector;
 
 	irq = create_irq();
 	if (irq < 0)
@@ -76,7 +76,7 @@
 
 	set_irq_msi(irq, desc);
 	dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map));
-	vector = irq;
+	vector = irq_to_vector(irq);
 
 	msg.address_hi = 0;
 	msg.address_lo =
@@ -110,7 +110,7 @@
 
 static int ia64_msi_retrigger_irq(unsigned int irq)
 {
-	unsigned int vector = irq;
+	unsigned int vector = irq_to_vector(irq);
 	ia64_resend_irq(vector);
 
 	return 1;
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 3f89187..00f8032 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -1573,6 +1573,7 @@
 
 	      case PTRACE_DETACH:
 		/* detach a process that was attached. */
+		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 		ret = ptrace_detach(child, data);
 		goto out_tsk;
 
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 7d6fe65..dc7dd76 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -91,8 +91,6 @@
 	.name	= "Kernel code",
 	.flags	= IORESOURCE_BUSY | IORESOURCE_MEM
 };
-extern void efi_initialize_iomem_resources(struct resource *,
-		struct resource *);
 extern char _text[], _end[], _etext[];
 
 unsigned long ia64_max_cacheline_size;
@@ -642,7 +640,7 @@
 		   "features   : %s\n"
 		   "cpu number : %lu\n"
 		   "cpu regs   : %u\n"
-		   "cpu MHz    : %lu.%06lu\n"
+		   "cpu MHz    : %lu.%03lu\n"
 		   "itc MHz    : %lu.%06lu\n"
 		   "BogoMIPS   : %lu.%02lu\n",
 		   cpunum, c->vendor, c->family, c->model,
@@ -694,12 +692,15 @@
 	.show =		show_cpuinfo
 };
 
-static char brandname[128];
+#define MAX_BRANDS	8
+static char brandname[MAX_BRANDS][128];
 
 static char * __cpuinit
 get_model_name(__u8 family, __u8 model)
 {
+	static int overflow;
 	char brand[128];
+	int i;
 
 	memcpy(brand, "Unknown", 8);
 	if (ia64_pal_get_brand_info(brand)) {
@@ -711,12 +712,17 @@
 			case 2: memcpy(brand, "Madison up to 9M cache", 23); break;
 		}
 	}
-	if (brandname[0] == '\0')
-		return strcpy(brandname, brand);
-	else if (strcmp(brandname, brand) == 0)
-		return brandname;
-	else
-		return kstrdup(brand, GFP_KERNEL);
+	for (i = 0; i < MAX_BRANDS; i++)
+		if (strcmp(brandname[i], brand) == 0)
+			return brandname[i];
+	for (i = 0; i < MAX_BRANDS; i++)
+		if (brandname[i][0] == '\0')
+			return strcpy(brandname[i], brand);
+	if (overflow++ == 0)
+		printk(KERN_ERR
+		       "%s: Table overflow. Some processor model information will be missing\n",
+		       __FUNCTION__);
+	return "Unknown";
 }
 
 static void __cpuinit
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index b21ddec..ff7df439 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -375,6 +375,7 @@
 smp_callin (void)
 {
 	int cpuid, phys_id, itc_master;
+	struct cpuinfo_ia64 *last_cpuinfo, *this_cpuinfo;
 	extern void ia64_init_itm(void);
 	extern volatile int time_keeper_id;
 
@@ -424,7 +425,21 @@
 	 * Get our bogomips.
 	 */
 	ia64_init_itm();
-	calibrate_delay();
+
+	/*
+	 * Delay calibration can be skipped if new processor is identical to the
+	 * previous processor.
+	 */
+	last_cpuinfo = cpu_data(cpuid - 1);
+	this_cpuinfo = local_cpu_data;
+	if (last_cpuinfo->itc_freq != this_cpuinfo->itc_freq ||
+	    last_cpuinfo->proc_freq != this_cpuinfo->proc_freq ||
+	    last_cpuinfo->features != this_cpuinfo->features ||
+	    last_cpuinfo->revision != this_cpuinfo->revision ||
+	    last_cpuinfo->family != this_cpuinfo->family ||
+	    last_cpuinfo->archrev != this_cpuinfo->archrev ||
+	    last_cpuinfo->model != this_cpuinfo->model)
+		calibrate_delay();
 	local_cpu_data->loops_per_jiffy = loops_per_jiffy;
 
 #ifdef CONFIG_IA32_SUPPORT
diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c
index fb0f469..44ce5ed 100644
--- a/arch/ia64/mm/contig.c
+++ b/arch/ia64/mm/contig.c
@@ -97,26 +97,6 @@
 unsigned long bootmap_start;
 
 /**
- * find_max_pfn - adjust the maximum page number callback
- * @start: start of range
- * @end: end of range
- * @arg: address of pointer to global max_pfn variable
- *
- * Passed as a callback function to efi_memmap_walk() to determine the highest
- * available page frame number in the system.
- */
-int
-find_max_pfn (unsigned long start, unsigned long end, void *arg)
-{
-	unsigned long *max_pfnp = arg, pfn;
-
-	pfn = (PAGE_ALIGN(end - 1) - PAGE_OFFSET) >> PAGE_SHIFT;
-	if (pfn > *max_pfnp)
-		*max_pfnp = pfn;
-	return 0;
-}
-
-/**
  * find_bootmap_location - callback to find a memory area for the bootmap
  * @start: start of region
  * @end: end of region
@@ -177,9 +157,10 @@
 	reserve_memory();
 
 	/* first find highest page frame number */
-	max_pfn = 0;
-	efi_memmap_walk(find_max_pfn, &max_pfn);
-
+	min_low_pfn = ~0UL;
+	max_low_pfn = 0;
+	efi_memmap_walk(find_max_min_low_pfn, NULL);
+	max_pfn = max_low_pfn;
 	/* how many bytes to cover all the pages */
 	bootmap_size = bootmem_bootmap_pages(max_pfn) << PAGE_SHIFT;
 
@@ -189,7 +170,8 @@
 	if (bootmap_start == ~0UL)
 		panic("Cannot find %ld bytes for bootmap\n", bootmap_size);
 
-	bootmap_size = init_bootmem(bootmap_start >> PAGE_SHIFT, max_pfn);
+	bootmap_size = init_bootmem_node(NODE_DATA(0),
+			(bootmap_start >> PAGE_SHIFT), 0, max_pfn);
 
 	/* Free all available memory, then mark bootmem-map as being in use. */
 	efi_memmap_walk(filter_rsvd_memory, free_bootmem);
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index 11a2d88..872da7a 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -88,9 +88,6 @@
 		bdp->node_low_pfn = max(epfn, bdp->node_low_pfn);
 	}
 
-	min_low_pfn = min(min_low_pfn, bdp->node_boot_start>>PAGE_SHIFT);
-	max_low_pfn = max(max_low_pfn, bdp->node_low_pfn);
-
 	return 0;
 }
 
@@ -438,6 +435,7 @@
 	/* These actually end up getting called by call_pernode_memory() */
 	efi_memmap_walk(filter_rsvd_memory, build_node_maps);
 	efi_memmap_walk(filter_rsvd_memory, find_pernode_space);
+	efi_memmap_walk(find_max_min_low_pfn, NULL);
 
 	for_each_online_node(node)
 		if (mem_data[node].bootmem_data.node_low_pfn) {
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index f225dd7..4f36987 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -155,7 +155,7 @@
 
 	if (stack_size > MAX_USER_STACK_SIZE)
 		stack_size = MAX_USER_STACK_SIZE;
-	current->thread.rbs_bot = STACK_TOP - stack_size;
+	current->thread.rbs_bot = PAGE_ALIGN(current->mm->start_stack - stack_size);
 }
 
 /*
@@ -648,6 +648,22 @@
 	return 0;
 }
 
+int
+find_max_min_low_pfn (unsigned long start, unsigned long end, void *arg)
+{
+	unsigned long pfn_start, pfn_end;
+#ifdef CONFIG_FLATMEM
+	pfn_start = (PAGE_ALIGN(__pa(start))) >> PAGE_SHIFT;
+	pfn_end = (PAGE_ALIGN(__pa(end - 1))) >> PAGE_SHIFT;
+#else
+	pfn_start = GRANULEROUNDDOWN(__pa(start)) >> PAGE_SHIFT;
+	pfn_end = GRANULEROUNDUP(__pa(end - 1)) >> PAGE_SHIFT;
+#endif
+	min_low_pfn = min(min_low_pfn, pfn_start);
+	max_low_pfn = max(max_low_pfn, pfn_end);
+	return 0;
+}
+
 /*
  * Boot command-line option "nolwsys" can be used to disable the use of any light-weight
  * system call handler.  When this option is in effect, all fsyscalls will end up bubbling
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 474d179..0e83f3b 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -557,14 +557,17 @@
 	if (ret < 0)
 		return ret;
 
-	return acpi_pci_irq_enable(dev);
+	if (!dev->msi_enabled)
+		return acpi_pci_irq_enable(dev);
+	return 0;
 }
 
 void
 pcibios_disable_device (struct pci_dev *dev)
 {
 	BUG_ON(atomic_read(&dev->enable_cnt));
-	acpi_pci_irq_disable(dev);
+	if (!dev->msi_enabled)
+		acpi_pci_irq_disable(dev);
 }
 
 void
diff --git a/arch/ia64/sn/kernel/bte_error.c b/arch/ia64/sn/kernel/bte_error.c
index f1ec137..b6fcf81 100644
--- a/arch/ia64/sn/kernel/bte_error.c
+++ b/arch/ia64/sn/kernel/bte_error.c
@@ -78,7 +78,7 @@
 		 * There are errors which still need to be cleaned up by
 		 * hubiio_crb_error_handler
 		 */
-		mod_timer(recovery_timer, HZ * 5);
+		mod_timer(recovery_timer, jiffies + (HZ * 5));
 		BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda,
 			    smp_processor_id()));
 		return 1;
@@ -95,7 +95,7 @@
 			icrbd.ii_icrb0_d_regval =
 			    REMOTE_HUB_L(nasid, IIO_ICRB_D(i));
 			if (icrbd.d_bteop) {
-				mod_timer(recovery_timer, HZ * 5);
+				mod_timer(recovery_timer, jiffies + (HZ * 5));
 				BTE_PRINTK(("eh:%p:%d Valid %d, Giving up\n",
 					    err_nodepda, smp_processor_id(),
 					    i));
@@ -150,7 +150,7 @@
 		status = BTE_LNSTAT_LOAD(bte);
 		if ((status & IBLS_ERROR) || !(status & IBLS_BUSY))
 			continue;
-		mod_timer(recovery_timer, HZ * 5);
+		mod_timer(recovery_timer, jiffies + (HZ * 5));
 		BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda,
 			    smp_processor_id()));
 		return 1;
diff --git a/arch/ia64/sn/kernel/io_acpi_init.c b/arch/ia64/sn/kernel/io_acpi_init.c
index 8c331ca..c6216f4 100644
--- a/arch/ia64/sn/kernel/io_acpi_init.c
+++ b/arch/ia64/sn/kernel/io_acpi_init.c
@@ -53,12 +53,15 @@
 }
 
 /*
- * sn_hubdev_add - The 'add' function of the acpi_sn_hubdev_driver.
- *		   Called for every "SGIHUB" or "SGITIO" device defined
- *		   in the ACPI namespace.
+ * sn_acpi_hubdev_init() - This function is called by acpi_ns_get_device_callback()
+ *			   for all SGIHUB and SGITIO acpi devices defined in the
+ *			   DSDT. It obtains the hubdev_info pointer from the
+ *			   ACPI vendor resource, which the PROM setup, and sets up the
+ *			   hubdev_info in the pda.
  */
-static int __init
-sn_hubdev_add(struct acpi_device *device)
+
+static acpi_status __init
+sn_acpi_hubdev_init(acpi_handle handle, u32 depth, void *context, void **ret)
 {
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 	u64 addr;
@@ -67,18 +70,19 @@
 	int i;
 	u64 nasid;
 	struct acpi_resource *resource;
-	int ret = 0;
 	acpi_status status;
 	struct acpi_resource_vendor_typed *vendor;
 	extern void sn_common_hubdev_init(struct hubdev_info *);
 
-	status = acpi_get_vendor_resource(device->handle, METHOD_NAME__CRS,
+	status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS,
 					  &sn_uuid, &buffer);
 	if (ACPI_FAILURE(status)) {
 		printk(KERN_ERR
-		       "sn_hubdev_add: acpi_get_vendor_resource() failed: %d\n",
-		        status);
-		return 1;
+		       "sn_acpi_hubdev_init: acpi_get_vendor_resource() "
+		       "(0x%x) failed for: ", status);
+		acpi_ns_print_node_pathname(handle, NULL);
+		printk("\n");
+		return AE_OK;		/* Continue walking namespace */
 	}
 
 	resource = buffer.pointer;
@@ -86,9 +90,10 @@
 	if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) !=
 	    sizeof(struct hubdev_info *)) {
 		printk(KERN_ERR
-		       "sn_hubdev_add: Invalid vendor data length: %d\n",
+		       "sn_acpi_hubdev_init: Invalid vendor data length: %d for: ",
 		        vendor->byte_length);
-		ret = 1;
+		acpi_ns_print_node_pathname(handle, NULL);
+		printk("\n");
 		goto exit;
 	}
 
@@ -103,7 +108,7 @@
 
 exit:
 	kfree(buffer.pointer);
-	return ret;
+	return AE_OK;		/* Continue walking namespace */
 }
 
 /*
@@ -441,14 +446,6 @@
 
 EXPORT_SYMBOL(sn_acpi_slot_fixup);
 
-static struct acpi_driver acpi_sn_hubdev_driver = {
-	.name = "SGI HUBDEV Driver",
-	.ids = "SGIHUB,SGITIO",
-	.ops = {
-		.add = sn_hubdev_add,
-		},
-};
-
 
 /*
  * sn_acpi_bus_fixup -  Perform SN specific setup of software structs
@@ -492,7 +489,10 @@
 	/* SN Altix does not follow the IOSAPIC IRQ routing model */
 	acpi_irq_model = ACPI_IRQ_MODEL_PLATFORM;
 
-	acpi_bus_register_driver(&acpi_sn_hubdev_driver);
+	/* Setup hubdev_info for all SGIHUB/SGITIO devices */
+	acpi_get_devices("SGIHUB", sn_acpi_hubdev_init, NULL, NULL);
+	acpi_get_devices("SGITIO", sn_acpi_hubdev_init, NULL, NULL);
+
 	status = sal_ioif_init(&result);
 	if (status || result)
 		panic("sal_ioif_init failed: [%lx] %s\n",
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 600be3e..6b10e5d 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -247,10 +247,18 @@
 		addr = ((addr << 4) >> 4) | __IA64_UNCACHED_OFFSET;
 		dev->resource[idx].start = addr;
 		dev->resource[idx].end = addr + size;
+
+		/*
+		 * if it's already in the device structure, remove it before
+		 * inserting
+		 */
+		if (dev->resource[idx].parent && dev->resource[idx].parent->child)
+			release_resource(&dev->resource[idx]);
+
 		if (dev->resource[idx].flags & IORESOURCE_IO)
-			dev->resource[idx].parent = &ioport_resource;
+			insert_resource(&ioport_resource, &dev->resource[idx]);
 		else
-			dev->resource[idx].parent = &iomem_resource;
+			insert_resource(&iomem_resource, &dev->resource[idx]);
 		/* If ROM, mark as shadowed in PROM */
 		if (idx == PCI_ROM_RESOURCE)
 			dev->resource[idx].flags |= IORESOURCE_ROM_BIOS_COPY;
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index 8c5bee0..8d2a1bf 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -205,7 +205,17 @@
 		(void)sn_retarget_vector(sn_irq_info, nasid, slice);
 }
 
-struct hw_interrupt_type irq_type_sn = {
+static void
+sn_mask_irq(unsigned int irq)
+{
+}
+
+static void
+sn_unmask_irq(unsigned int irq)
+{
+}
+
+struct irq_chip irq_type_sn = {
 	.name		= "SN hub",
 	.startup	= sn_startup_irq,
 	.shutdown	= sn_shutdown_irq,
@@ -213,6 +223,8 @@
 	.disable	= sn_disable_irq,
 	.ack		= sn_ack_irq,
 	.end		= sn_end_irq,
+	.mask		= sn_mask_irq,
+	.unmask		= sn_unmask_irq,
 	.set_affinity	= sn_set_affinity_irq
 };
 
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index 8571e52..a9bed5c 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -348,8 +348,7 @@
 			continue;	/* not PCI interconnect */
 
 		if (if_pci.translation & PCDP_PCI_TRANS_IOPORT)
-			vga_console_iobase =
-				if_pci.ioport_tra | __IA64_UNCACHED_OFFSET;
+			vga_console_iobase = if_pci.ioport_tra;
 
 		if (if_pci.translation & PCDP_PCI_TRANS_MMIO)
 			vga_console_membase =
@@ -397,6 +396,8 @@
 	ia64_sn_set_os_feature(OSF_PCISEGMENT_ENABLE);
 	ia64_sn_set_os_feature(OSF_ACPI_ENABLE);
 
+	/* Load the new DSDT and SSDT tables into the global table list. */
+	acpi_table_init();
 
 #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
 	/*
@@ -427,7 +428,8 @@
 	 * 	bus containing the VGA console.
 	 */
 	if (vga_console_iobase) {
-		io_space[0].mmio_base = vga_console_iobase;
+		io_space[0].mmio_base =
+			(unsigned long) ioremap(vga_console_iobase, 0);
 		io_space[0].sparse = 0;
 	}
 
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
index 1ee977f..95af40c 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
@@ -96,10 +96,14 @@
 	}
 
 	/*
-	 * If we're mapping for MSI, set the MSI bit in the ATE
+	 * If we're mapping for MSI, set the MSI bit in the ATE.  If it's a
+	 * TIOCP based pci bus, we also need to set the PIO bit in the ATE.
 	 */
-	if (dma_flags & SN_DMA_MSI)
+	if (dma_flags & SN_DMA_MSI) {
 		ate |= PCI32_ATE_MSI;
+		if (IS_TIOCP_SOFT(pcibus_info))
+			ate |= PCI32_ATE_PIO;
+	}
 
 	ate_write(pcibus_info, ate_index, ate_count, ate);
 
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index a1cd84f..c78b143 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -250,7 +250,7 @@
 	select R5000_CPU_SCACHE
 	select SYS_HAS_CPU_R5000
 	select SYS_SUPPORTS_32BIT_KERNEL
-	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+	select SYS_SUPPORTS_64BIT_KERNEL if BROKEN
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 	select GENERIC_HARDIRQS_NO__DO_IRQ
 
@@ -470,11 +470,6 @@
 	select SOC_AU1500
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 
-config PNX8550_V2PCI
-	bool "Philips PNX8550 based Viper2-PCI board"
-	select PNX8550
-	select SYS_SUPPORTS_LITTLE_ENDIAN
-
 config PNX8550_JBS
 	bool "Philips PNX8550 based JBS board"
 	select PNX8550
@@ -547,6 +542,8 @@
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 	select ARCH_SPARSEMEM_ENABLE
 	select GENERIC_HARDIRQS_NO__DO_IRQ
+	select NR_CPUS_DEFAULT_1
+	select SYS_SUPPORTS_SMP
 	help
 	  Qemu is a software emulator which among other architectures also
 	  can simulate a MIPS32 4Kc system.  This patch adds support for the
@@ -1564,6 +1561,7 @@
 	select CPU_MIPSR2_IRQ_VI
 	select CPU_MIPSR2_SRS
 	select MIPS_MT
+	select NR_CPUS_DEFAULT_2
 	select SMP
 	select SYS_SUPPORTS_SMP
 	help
@@ -1578,7 +1576,6 @@
 	select CPU_MIPSR2_IRQ_VI
 	select CPU_MIPSR2_SRS
 	select MIPS_MT
-	select NR_CPUS_DEFAULT_2
 	select NR_CPUS_DEFAULT_8
 	select SMP
 	select SYS_SUPPORTS_SMP
@@ -1609,7 +1606,7 @@
 
 config MIPS_MT_SMTC_INSTANT_REPLAY
 	bool "Low-latency Dispatch of Deferred SMTC IPIs"
-	depends on MIPS_MT_SMTC
+	depends on MIPS_MT_SMTC && !PREEMPT
 	default y
 	help
 	  SMTC pseudo-interrupts between TCs are deferred and queued
@@ -1810,6 +1807,9 @@
 config SYS_SUPPORTS_SMP
 	bool
 
+config NR_CPUS_DEFAULT_1
+	bool
+
 config NR_CPUS_DEFAULT_2
 	bool
 
@@ -1830,8 +1830,9 @@
 
 config NR_CPUS
 	int "Maximum number of CPUs (2-64)"
-	range 2 64
+	range 1 64 if NR_CPUS_DEFAULT_1
 	depends on SMP
+	default "1" if NR_CPUS_DEFAULT_1
 	default "2" if NR_CPUS_DEFAULT_2
 	default "4" if NR_CPUS_DEFAULT_4
 	default "8" if NR_CPUS_DEFAULT_8
@@ -1842,10 +1843,13 @@
 	  This allows you to specify the maximum number of CPUs which this
 	  kernel will support.  The maximum supported value is 32 for 32-bit
 	  kernel and 64 for 64-bit kernels; the minimum value which makes
-	  sense is 2.
+	  sense is 1 for Qemu (useful only for kernel debugging purposes)
+	  and 2 for all others.
 
 	  This is purely to save memory - each supported CPU adds
-	  approximately eight kilobytes to the kernel image.
+	  approximately eight kilobytes to the kernel image.  For best
+	  performance should round up your number of processors to the next
+	  power of two.
 
 #
 # Timer Interrupt Frequency Configuration
diff --git a/arch/mips/arc/init.c b/arch/mips/arc/init.c
index 0ac8f42..e2f75b1 100644
--- a/arch/mips/arc/init.c
+++ b/arch/mips/arc/init.c
@@ -23,16 +23,16 @@
 void __init prom_init(void)
 {
 	PSYSTEM_PARAMETER_BLOCK pb = PROMBLOCK;
+
 	romvec = ROMVECTOR;
-	ULONG cnt;
-	CHAR c;
 
 	prom_argc = fw_arg0;
 	_prom_argv = (LONG *) fw_arg1;
 	_prom_envp = (LONG *) fw_arg2;
 
 	if (pb->magic != 0x53435241) {
-		printk(KERN_CRIT "Aieee, bad prom vector magic %08lx\n", pb->magic);
+		printk(KERN_CRIT "Aieee, bad prom vector magic %08lx\n",
+		       (unsigned long) pb->magic);
 		while(1)
 			;
 	}
diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig
index 4588949..39e2513 100644
--- a/arch/mips/configs/atlas_defconfig
+++ b/arch/mips/configs/atlas_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
index aa05e29..4713a13 100644
--- a/arch/mips/configs/bigsur_defconfig
+++ b/arch/mips/configs/bigsur_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig
index b2594fa..5e7ae56 100644
--- a/arch/mips/configs/capcella_defconfig
+++ b/arch/mips/configs/capcella_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
index 9090a7a..ba593b5 100644
--- a/arch/mips/configs/cobalt_defconfig
+++ b/arch/mips/configs/cobalt_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
index 4cb8cf4..0db6a8b 100644
--- a/arch/mips/configs/db1000_defconfig
+++ b/arch/mips/configs/db1000_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
index d86dedf..162add9 100644
--- a/arch/mips/configs/db1100_defconfig
+++ b/arch/mips/configs/db1100_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
index c24b600..82801ec 100644
--- a/arch/mips/configs/db1200_defconfig
+++ b/arch/mips/configs/db1200_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
index baad2c5..545f230 100644
--- a/arch/mips/configs/db1500_defconfig
+++ b/arch/mips/configs/db1500_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
index c29fdab..5bd3b43 100644
--- a/arch/mips/configs/db1550_defconfig
+++ b/arch/mips/configs/db1550_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig
index f4b316d..5b502a2 100644
--- a/arch/mips/configs/ddb5477_defconfig
+++ b/arch/mips/configs/ddb5477_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 CONFIG_DDB5477=y
diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig
index 9c38e5c..4bbdab0 100644
--- a/arch/mips/configs/decstation_defconfig
+++ b/arch/mips/configs/decstation_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig
index 922af37..b5714a6a 100644
--- a/arch/mips/configs/e55_defconfig
+++ b/arch/mips/configs/e55_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/emma2rh_defconfig b/arch/mips/configs/emma2rh_defconfig
index c0db8f1..3044579 100644
--- a/arch/mips/configs/emma2rh_defconfig
+++ b/arch/mips/configs/emma2rh_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig
index ce088b36..c10e4e0 100644
--- a/arch/mips/configs/ev64120_defconfig
+++ b/arch/mips/configs/ev64120_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig
index 82f204d..460d7a2 100644
--- a/arch/mips/configs/excite_defconfig
+++ b/arch/mips/configs/excite_defconfig
@@ -40,7 +40,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig
index cb81f13..7ec618f 100644
--- a/arch/mips/configs/ip22_defconfig
+++ b/arch/mips/configs/ip22_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index 46f6ac4..9ddc3ef 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index d9e5000..8fc1880 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/jaguar-atx_defconfig b/arch/mips/configs/jaguar-atx_defconfig
index 57ef0c4..083104d 100644
--- a/arch/mips/configs/jaguar-atx_defconfig
+++ b/arch/mips/configs/jaguar-atx_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig
index 21d979f..9331cb0 100644
--- a/arch/mips/configs/jazz_defconfig
+++ b/arch/mips/configs/jazz_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig
index 98b9fbc..21a0947 100644
--- a/arch/mips/configs/jmr3927_defconfig
+++ b/arch/mips/configs/jmr3927_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig
index b3f767f..fd4272c 100644
--- a/arch/mips/configs/lasat200_defconfig
+++ b/arch/mips/configs/lasat200_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
index a5f379d..1f64d76 100644
--- a/arch/mips/configs/malta_defconfig
+++ b/arch/mips/configs/malta_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
index 5ff53e1..a2db5c2 100644
--- a/arch/mips/configs/mipssim_defconfig
+++ b/arch/mips/configs/mipssim_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig
index 750e644..ad5c0bf 100644
--- a/arch/mips/configs/mpc30x_defconfig
+++ b/arch/mips/configs/mpc30x_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig
index 2febd0a..2854731 100644
--- a/arch/mips/configs/ocelot_3_defconfig
+++ b/arch/mips/configs/ocelot_3_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig
index b8f4573..82ff6fc 100644
--- a/arch/mips/configs/ocelot_c_defconfig
+++ b/arch/mips/configs/ocelot_c_defconfig
@@ -39,7 +39,6 @@
 CONFIG_MOMENCO_OCELOT_C=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig
index 8ade072..15a027e 100644
--- a/arch/mips/configs/ocelot_defconfig
+++ b/arch/mips/configs/ocelot_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/ocelot_g_defconfig b/arch/mips/configs/ocelot_g_defconfig
index d20a221..7078e6b 100644
--- a/arch/mips/configs/ocelot_g_defconfig
+++ b/arch/mips/configs/ocelot_g_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 CONFIG_MOMENCO_OCELOT_G=y
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
index 33fcc81..69678d9 100644
--- a/arch/mips/configs/pb1100_defconfig
+++ b/arch/mips/configs/pb1100_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
index e07c55d..0706727 100644
--- a/arch/mips/configs/pb1500_defconfig
+++ b/arch/mips/configs/pb1500_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
index df210dd..354e49b 100644
--- a/arch/mips/configs/pb1550_defconfig
+++ b/arch/mips/configs/pb1550_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig
index 106a164..fae16c5 100644
--- a/arch/mips/configs/pnx8550-jbs_defconfig
+++ b/arch/mips/configs/pnx8550-jbs_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 CONFIG_PNX8550_JBS=y
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig
index 8caa2cd..cd821e5 100644
--- a/arch/mips/configs/pnx8550-stb810_defconfig
+++ b/arch/mips/configs/pnx8550-stb810_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 CONFIG_PNX8550_STB810=y
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/pnx8550-v2pci_defconfig b/arch/mips/configs/pnx8550-v2pci_defconfig
index 43f1bec..3d6c2d7 100644
--- a/arch/mips/configs/pnx8550-v2pci_defconfig
+++ b/arch/mips/configs/pnx8550-v2pci_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-CONFIG_PNX8550_V2PCI=y
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig
index f68396d..8e8d031 100644
--- a/arch/mips/configs/qemu_defconfig
+++ b/arch/mips/configs/qemu_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig
index a6a824f..29e0df9 100644
--- a/arch/mips/configs/rbhma4500_defconfig
+++ b/arch/mips/configs/rbhma4500_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index bee3702..5593cde 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
index 3c891ed..6c4f09a 100644
--- a/arch/mips/configs/sb1250-swarm_defconfig
+++ b/arch/mips/configs/sb1250-swarm_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig
index e31d964..988b9cd 100644
--- a/arch/mips/configs/sead_defconfig
+++ b/arch/mips/configs/sead_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig
index 5771c1a..b5be8b74 100644
--- a/arch/mips/configs/tb0226_defconfig
+++ b/arch/mips/configs/tb0226_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/tb0229_defconfig b/arch/mips/configs/tb0229_defconfig
index a8eb4b1..1756d2b 100644
--- a/arch/mips/configs/tb0229_defconfig
+++ b/arch/mips/configs/tb0229_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig
index c58afa2..8bb6be4 100644
--- a/arch/mips/configs/tb0287_defconfig
+++ b/arch/mips/configs/tb0287_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig
index 2abbd68..8f019ff 100644
--- a/arch/mips/configs/workpad_defconfig
+++ b/arch/mips/configs/workpad_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig
index 44b6b7c..52b48c0 100644
--- a/arch/mips/configs/wrppmc_defconfig
+++ b/arch/mips/configs/wrppmc_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
index f24e1c6..6824606 100644
--- a/arch/mips/configs/yosemite_defconfig
+++ b/arch/mips/configs/yosemite_defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/ddb5xxx/ddb5477/irq.c b/arch/mips/ddb5xxx/ddb5477/irq.c
index 2b23234..faa4a50 100644
--- a/arch/mips/ddb5xxx/ddb5477/irq.c
+++ b/arch/mips/ddb5xxx/ddb5477/irq.c
@@ -194,7 +194,7 @@
 
 asmlinkage void plat_irq_dispatch(void)
 {
-	unsigned int pending = read_c0_cause() & read_c0_status();
+	unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
 
 	if (pending & STATUSF_IP7)
 		do_IRQ(CPU_IRQ_BASE + 7);
diff --git a/arch/mips/dec/prom/init.c b/arch/mips/dec/prom/init.c
index bf28580..a217aaf 100644
--- a/arch/mips/dec/prom/init.c
+++ b/arch/mips/dec/prom/init.c
@@ -103,9 +103,6 @@
 	if (prom_is_rex(magic))
 		rex_clear_cache();
 
-	/* Register the early console.  */
-	register_prom_console();
-
 	/* Were we compiled with the right CPU option? */
 #if defined(CONFIG_CPU_R3000)
 	if ((current_cpu_data.cputype == CPU_R4000SC) ||
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index 8cb8f59..41211f8 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -39,7 +39,6 @@
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MIPS_XXS1500 is not set
-# CONFIG_PNX8550_V2PCI is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_DDB5477 is not set
diff --git a/arch/mips/emma2rh/markeins/irq.c b/arch/mips/emma2rh/markeins/irq.c
index e266300..6bcf6a0 100644
--- a/arch/mips/emma2rh/markeins/irq.c
+++ b/arch/mips/emma2rh/markeins/irq.c
@@ -115,7 +115,7 @@
 
 asmlinkage void plat_irq_dispatch(void)
 {
-        unsigned int pending = read_c0_status() & read_c0_cause();
+        unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
 
 	if (pending & STATUSF_IP7)
 		do_IRQ(CPU_IRQ_BASE + 7);
diff --git a/arch/mips/gt64120/ev64120/irq.c b/arch/mips/gt64120/ev64120/irq.c
index 04572b9..64e4c80 100644
--- a/arch/mips/gt64120/ev64120/irq.c
+++ b/arch/mips/gt64120/ev64120/irq.c
@@ -48,7 +48,7 @@
 
 asmlinkage void plat_irq_dispatch(void)
 {
-	unsigned int pending = read_c0_status() & read_c0_cause();
+	unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
 
 	if (pending & STATUSF_IP4)		/* int2 hardware line (timer) */
 		do_IRQ(4);
diff --git a/arch/mips/gt64120/momenco_ocelot/prom.c b/arch/mips/gt64120/momenco_ocelot/prom.c
index 78f393b..c71c852 100644
--- a/arch/mips/gt64120/momenco_ocelot/prom.c
+++ b/arch/mips/gt64120/momenco_ocelot/prom.c
@@ -32,7 +32,6 @@
 	char **arg = (char **) fw_arg1;
 	char **env = (char **) fw_arg2;
 	struct callvectors *cv = (struct callvectors *) fw_arg3;
-	uint32_t tmp;
 	int i;
 
 	/* save the PROM vectors for debugging use */
diff --git a/arch/mips/gt64120/momenco_ocelot/setup.c b/arch/mips/gt64120/momenco_ocelot/setup.c
index 94f94eb..98b6fb3 100644
--- a/arch/mips/gt64120/momenco_ocelot/setup.c
+++ b/arch/mips/gt64120/momenco_ocelot/setup.c
@@ -79,7 +79,7 @@
 static void __init setup_l3cache(unsigned long size);
 
 /* setup code for a handoff from a version 1 PMON 2000 PROM */
-void PMON_v1_setup()
+static void PMON_v1_setup(void)
 {
 	/* A wired TLB entry for the GT64120A and the serial port. The
 	   GT64120A is going to be hit on every IRQ anyway - there's
diff --git a/arch/mips/gt64120/wrppmc/irq.c b/arch/mips/gt64120/wrppmc/irq.c
index d3d9659..06177bf 100644
--- a/arch/mips/gt64120/wrppmc/irq.c
+++ b/arch/mips/gt64120/wrppmc/irq.c
@@ -32,7 +32,7 @@
 
 asmlinkage void plat_irq_dispatch(void)
 {
-	unsigned int pending = read_c0_status() & read_c0_cause();
+	unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
 
 	if (pending & STATUSF_IP7)
 		do_IRQ(WRPPMC_MIPS_TIMER_IRQ);	/* CPU Compare/Count internal timer */
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c
index 295892e..015cf4b 100644
--- a/arch/mips/jazz/irq.c
+++ b/arch/mips/jazz/irq.c
@@ -122,7 +122,7 @@
 
 asmlinkage void plat_irq_dispatch(void)
 {
-	unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+	unsigned int pending = read_c0_cause() & read_c0_status();
 
 	if (pending & IE_IRQ5)
 		write_c0_compare(0);
diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c
index 46e421e..e8e0ffb 100644
--- a/arch/mips/jazz/jazzdma.c
+++ b/arch/mips/jazz/jazzdma.c
@@ -67,7 +67,8 @@
 	 * aligned and should be uncached to avoid cache flushing after every
 	 * update.
 	 */
-	vdma_pagetable_start = alloc_bootmem_low_pages(VDMA_PGTBL_SIZE);
+	vdma_pagetable_start =
+		(unsigned long) alloc_bootmem_low_pages(VDMA_PGTBL_SIZE);
 	if (!vdma_pagetable_start)
 		BUG();
 	dma_cache_wback_inv(vdma_pagetable_start, VDMA_PGTBL_SIZE);
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index 0b78fcb..686249c 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -121,7 +121,11 @@
 	SAVE_AT
 	SAVE_TEMP
 	LONG_L	v0, PT_STATUS(sp)
-	and	v0, 1
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+	and	v0, ST0_IEP
+#else
+	and	v0, ST0_IE
+#endif
 	beqz	v0, 1f
 	jal	trace_hardirqs_on
 	b	2f
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index aacd4a0..297bd56 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -128,6 +128,37 @@
 
 	.align  5
 NESTED(handle_int, PT_SIZE, sp)
+#ifdef CONFIG_TRACE_IRQFLAGS
+	/*
+	 * Check to see if the interrupted code has just disabled
+	 * interrupts and ignore this interrupt for now if so.
+	 *
+	 * local_irq_disable() disables interrupts and then calls
+	 * trace_hardirqs_off() to track the state. If an interrupt is taken
+	 * after interrupts are disabled but before the state is updated
+	 * it will appear to restore_all that it is incorrectly returning with
+	 * interrupts disabled
+	 */
+	.set	push
+	.set	noat
+	mfc0	k0, CP0_STATUS
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+	and	k0, ST0_IEP
+	bnez	k0, 1f
+
+	mfc0	k0, EP0_EPC
+	.set	noreorder
+	j	k0
+	rfe
+#else
+	and	k0, ST0_IE
+	bnez	k0, 1f
+
+	eret
+#endif
+1:
+	.set pop
+#endif
 	SAVE_ALL
 	CLI
 	TRACE_IRQS_OFF
@@ -181,13 +212,13 @@
 	 * during service by SMTC kernel, we also want to
 	 * pass the IM value to be cleared.
 	 */
-EXPORT(except_vec_vi_mori)
+FEXPORT(except_vec_vi_mori)
 	ori	a0, $0, 0
 #endif /* CONFIG_MIPS_MT_SMTC */
-EXPORT(except_vec_vi_lui)
+FEXPORT(except_vec_vi_lui)
 	lui	v0, 0		/* Patched */
 	j	except_vec_vi_handler
-EXPORT(except_vec_vi_ori)
+FEXPORT(except_vec_vi_ori)
 	 ori	v0, 0		/* Patched */
 	.set	pop
 	END(except_vec_vi)
@@ -220,7 +251,17 @@
 	_ehb
 #endif /* CONFIG_MIPS_MT_SMTC */
 	CLI
+#ifdef CONFIG_TRACE_IRQFLAGS
+	move	s0, v0
+#ifdef CONFIG_MIPS_MT_SMTC
+	move	s1, a0
+#endif
 	TRACE_IRQS_OFF
+#ifdef CONFIG_MIPS_MT_SMTC
+	move	a0, s1
+#endif
+	move	v0, s0
+#endif
 
 	LONG_L	s0, TI_REGS($28)
 	LONG_S	sp, TI_REGS($28)
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c
index 5929f883..29eadd4 100644
--- a/arch/mips/kernel/kspd.c
+++ b/arch/mips/kernel/kspd.c
@@ -70,6 +70,7 @@
 #define MTSP_SYSCALL_GETTIME	(MTSP_SYSCALL_BASE + 7)
 #define MTSP_SYSCALL_PIPEFREQ	(MTSP_SYSCALL_BASE + 8)
 #define MTSP_SYSCALL_GETTOD	(MTSP_SYSCALL_BASE + 9)
+#define MTSP_SYSCALL_IOCTL     (MTSP_SYSCALL_BASE + 10)
 
 #define MTSP_O_RDONLY		0x0000
 #define MTSP_O_WRONLY		0x0001
@@ -110,7 +111,8 @@
 	{ MTSP_SYSCALL_CLOSE, __NR_close },
 	{ MTSP_SYSCALL_READ, __NR_read },
 	{ MTSP_SYSCALL_WRITE, __NR_write },
-	{ MTSP_SYSCALL_LSEEK32, __NR_lseek }
+	{ MTSP_SYSCALL_LSEEK32, __NR_lseek },
+	{ MTSP_SYSCALL_IOCTL, __NR_ioctl }
 };
 
 static int sp_syscall(int num, int arg0, int arg1, int arg2, int arg3)
@@ -189,6 +191,8 @@
 	struct mtsp_syscall_generic generic;
 	struct mtsp_syscall_ret ret;
 	struct kspd_notifications *n;
+	unsigned long written;
+	mm_segment_t old_fs;
 	struct timeval tv;
 	struct timezone tz;
 	int cmd;
@@ -199,7 +203,11 @@
 
 	ret.retval = -1;
 
-	if (!rtlx_read(RTLX_CHANNEL_SYSIO, &sc, sizeof(struct mtsp_syscall), 0)) {
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+
+	if (!rtlx_read(RTLX_CHANNEL_SYSIO, &sc, sizeof(struct mtsp_syscall))) {
+		set_fs(old_fs);
 		printk(KERN_ERR "Expected request but nothing to read\n");
 		return;
 	}
@@ -207,7 +215,8 @@
 	size = sc.size;
 
 	if (size) {
-		if (!rtlx_read(RTLX_CHANNEL_SYSIO, &generic, size, 0)) {
+		if (!rtlx_read(RTLX_CHANNEL_SYSIO, &generic, size)) {
+			set_fs(old_fs);
 			printk(KERN_ERR "Expected request but nothing to read\n");
 			return;
 		}
@@ -280,8 +289,11 @@
 	if (vpe_getuid(SP_VPE))
 		sp_setfsuidgid( 0, 0);
 
-	if ((rtlx_write(RTLX_CHANNEL_SYSIO, &ret, sizeof(struct mtsp_syscall_ret), 0))
-	    < sizeof(struct mtsp_syscall_ret))
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	written = rtlx_write(RTLX_CHANNEL_SYSIO, &ret, sizeof(ret));
+	set_fs(old_fs);
+	if (written < sizeof(ret))
 		printk("KSPD: sp_work_handle_request failed to send to SP\n");
 }
 
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 30d433f..37849ed 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -311,6 +311,8 @@
 	return ret;
 }
 
+#ifdef CONFIG_SYSVIPC
+
 asmlinkage long
 sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
 {
@@ -368,6 +370,16 @@
 	return err;
 }
 
+#else
+
+asmlinkage long
+sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
+{
+	return -ENOSYS;
+}
+
+#endif /* CONFIG_SYSVIPC */
+
 #ifdef CONFIG_MIPS32_N32
 asmlinkage long sysn32_semctl(int semid, int semnum, int cmd, u32 arg)
 {
@@ -564,49 +576,3 @@
 	return do_fork(clone_flags, newsp, &regs, 0,
 	               parent_tidptr, child_tidptr);
 }
-
-/*
- * Implement the event wait interface for the eventpoll file. It is the kernel
- * part of the user space epoll_pwait(2).
- */
-asmlinkage long compat_sys_epoll_pwait(int epfd,
-	struct epoll_event __user *events, int maxevents, int timeout,
-	const compat_sigset_t __user *sigmask, size_t sigsetsize)
-{
-	int error;
-	sigset_t ksigmask, sigsaved;
-
-	/*
-	 * If the caller wants a certain signal mask to be set during the wait,
-	 * we apply it here.
-	 */
-	if (sigmask) {
-		if (sigsetsize != sizeof(sigset_t))
-			return -EINVAL;
-		if (!access_ok(VERIFY_READ, sigmask, sizeof(ksigmask)))
-			return -EFAULT;
-		if (__copy_conv_sigset_from_user(&ksigmask, sigmask))
-			return -EFAULT;
-		sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
-		sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
-	}
-
-	error = sys_epoll_wait(epfd, events, maxevents, timeout);
-
-	/*
-	 * If we changed the signal mask, we need to restore the original one.
-	 * In case we've got a signal while waiting, we do not restore the
-	 * signal mask yet, and we allow do_signal() to deliver the signal on
-	 * the way back to userspace, before the signal mask is restored.
-	 */
-	if (sigmask) {
-		if (error == -EINTR) {
-			memcpy(&current->saved_sigmask, &sigsaved,
-				sizeof(sigsaved));
-			set_thread_flag(TIF_RESTORE_SIGMASK);
-		} else
-			sigprocmask(SIG_SETMASK, &sigsaved, NULL);
-	}
-
-	return error;
-}
diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S
index 656bde2..28c2e2e 100644
--- a/arch/mips/kernel/r2300_switch.S
+++ b/arch/mips/kernel/r2300_switch.S
@@ -49,8 +49,7 @@
 #ifndef CONFIG_CPU_HAS_LLSC
 	sw      zero, ll_bit
 #endif
-	mfc0	t1, CP0_STATUS
-	sw	t1, THREAD_STATUS(a0)
+	mfc0	t2, CP0_STATUS
 	cpu_save_nonscratch a0
 	sw	ra, THREAD_REG31(a0)
 
@@ -60,8 +59,8 @@
 	lw	t3, TASK_THREAD_INFO(a0)
 	lw	t0, TI_FLAGS(t3)
 	li	t1, _TIF_USEDFPU
-	and	t2, t0, t1
-	beqz	t2, 1f
+	and	t1, t0
+	beqz	t1, 1f
 	nor	t1, zero, t1
 
 	and	t0, t0, t1
@@ -74,10 +73,13 @@
 	li	t1, ~ST0_CU1
 	and	t0, t0, t1
 	sw	t0, ST_OFF(t3)
+	/* clear thread_struct CU1 bit */
+	and	t2, t1
 
 	fpu_save_single a0, t0			# clobbers t0
 
 1:
+	sw	t2, THREAD_STATUS(a0)
 	/*
 	 * The order of restoring the registers takes care of the race
 	 * updating $28, $29 and kernelsp without disabling ints.
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
index 59c1577..dbd42ad 100644
--- a/arch/mips/kernel/r4k_fpu.S
+++ b/arch/mips/kernel/r4k_fpu.S
@@ -114,14 +114,6 @@
  */
 LEAF(_restore_fp_context)
 	EX	lw t0, SC_FPC_CSR(a0)
-
-	/* Fail if the CSR has exceptions pending */
-	srl	t1, t0, 5
-	and	t1, t0
-	andi	t1, 0x1f << 7
-	bnez	t1, fault
-	 nop
-
 #ifdef CONFIG_64BIT
 	EX	ldc1 $f1, SC_FPREGS+8(a0)
 	EX	ldc1 $f3, SC_FPREGS+24(a0)
@@ -165,14 +157,6 @@
 LEAF(_restore_fp_context32)
 	/* Restore an o32 sigcontext.  */
 	EX	lw t0, SC32_FPC_CSR(a0)
-
-	/* Fail if the CSR has exceptions pending */
-	srl	t1, t0, 5
-	and	t1, t0
-	andi	t1, 0x1f << 7
-	bnez	t1, fault
-	 nop
-
 	EX	ldc1 $f0, SC32_FPREGS+0(a0)
 	EX	ldc1 $f2, SC32_FPREGS+16(a0)
 	EX	ldc1 $f4, SC32_FPREGS+32(a0)
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
index cc566cf..c7698fd 100644
--- a/arch/mips/kernel/r4k_switch.S
+++ b/arch/mips/kernel/r4k_switch.S
@@ -48,8 +48,7 @@
 #ifndef CONFIG_CPU_HAS_LLSC
 	sw	zero, ll_bit
 #endif
-	mfc0	t1, CP0_STATUS
-	LONG_S	t1, THREAD_STATUS(a0)
+	mfc0	t2, CP0_STATUS
 	cpu_save_nonscratch a0
 	LONG_S	ra, THREAD_REG31(a0)
 
@@ -59,8 +58,8 @@
 	PTR_L	t3, TASK_THREAD_INFO(a0)
 	LONG_L	t0, TI_FLAGS(t3)
 	li	t1, _TIF_USEDFPU
-	and	t2, t0, t1
-	beqz	t2, 1f
+	and	t1, t0
+	beqz	t1, 1f
 	nor	t1, zero, t1
 
 	and	t0, t0, t1
@@ -73,10 +72,13 @@
 	li	t1, ~ST0_CU1
 	and	t0, t0, t1
 	LONG_S	t0, ST_OFF(t3)
+	/* clear thread_struct CU1 bit */
+	and	t2, t1
 
 	fpu_save_double a0 t0 t1		# c0_status passed in t0
 						# clobbers t1
 1:
+	LONG_S	t2, THREAD_STATUS(a0)
 
 	/*
 	 * The order of restoring the registers takes care of the race
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index e14ae09e..e6e3047 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -54,6 +54,7 @@
 	wait_queue_head_t rt_queue;
 	wait_queue_head_t lx_queue;
 	atomic_t in_open;
+	struct mutex mutex;
 } channel_wqs[RTLX_CHANNELS];
 
 static struct irqaction irq;
@@ -146,7 +147,7 @@
 
 int rtlx_open(int index, int can_sleep)
 {
-	volatile struct rtlx_info **p;
+	struct rtlx_info **p;
 	struct rtlx_channel *chan;
 	enum rtlx_state state;
 	int ret = 0;
@@ -179,13 +180,24 @@
 			}
 		}
 
+		smp_rmb();
 		if (*p == NULL) {
 			if (can_sleep) {
-				__wait_event_interruptible(channel_wqs[index].lx_queue,
-				                           *p != NULL,
-				                           ret);
-				if (ret)
+				DEFINE_WAIT(wait);
+
+				for (;;) {
+					prepare_to_wait(&channel_wqs[index].lx_queue, &wait, TASK_INTERRUPTIBLE);
+					smp_rmb();
+					if (*p != NULL)
+						break;
+					if (!signal_pending(current)) {
+						schedule();
+						continue;
+					}
+					ret = -ERESTARTSYS;
 					goto out_fail;
+				}
+				finish_wait(&channel_wqs[index].lx_queue, &wait);
 			} else {
 				printk(" *vpe_get_shared is NULL. "
 				       "Has an SP program been loaded?\n");
@@ -277,56 +289,52 @@
 	return write_spacefree(chan->rt_read, chan->rt_write, chan->buffer_size);
 }
 
-static inline void copy_to(void *dst, void *src, size_t count, int user)
+ssize_t rtlx_read(int index, void __user *buff, size_t count, int user)
 {
-	if (user)
-		copy_to_user(dst, src, count);
-	else
-		memcpy(dst, src, count);
-}
-
-static inline void copy_from(void *dst, void *src, size_t count, int user)
-{
-	if (user)
-		copy_from_user(dst, src, count);
-	else
-		memcpy(dst, src, count);
-}
-
-ssize_t rtlx_read(int index, void *buff, size_t count, int user)
-{
-	size_t fl = 0L;
+	size_t lx_write, fl = 0L;
 	struct rtlx_channel *lx;
+	unsigned long failed;
 
 	if (rtlx == NULL)
 		return -ENOSYS;
 
 	lx = &rtlx->channel[index];
 
+	mutex_lock(&channel_wqs[index].mutex);
+	smp_rmb();
+	lx_write = lx->lx_write;
+
 	/* find out how much in total */
 	count = min(count,
-		     (size_t)(lx->lx_write + lx->buffer_size - lx->lx_read)
+		     (size_t)(lx_write + lx->buffer_size - lx->lx_read)
 		     % lx->buffer_size);
 
 	/* then how much from the read pointer onwards */
-	fl = min( count, (size_t)lx->buffer_size - lx->lx_read);
+	fl = min(count, (size_t)lx->buffer_size - lx->lx_read);
 
-	copy_to(buff, &lx->lx_buffer[lx->lx_read], fl, user);
+	failed = copy_to_user(buff, lx->lx_buffer + lx->lx_read, fl);
+	if (failed)
+		goto out;
 
 	/* and if there is anything left at the beginning of the buffer */
-	if ( count - fl )
-		copy_to (buff + fl, lx->lx_buffer, count - fl, user);
+	if (count - fl)
+		failed = copy_to_user(buff + fl, lx->lx_buffer, count - fl);
 
-	/* update the index */
-	lx->lx_read += count;
-	lx->lx_read %= lx->buffer_size;
+out:
+	count -= failed;
+
+	smp_wmb();
+	lx->lx_read = (lx->lx_read + count) % lx->buffer_size;
+	smp_wmb();
+	mutex_unlock(&channel_wqs[index].mutex);
 
 	return count;
 }
 
-ssize_t rtlx_write(int index, void *buffer, size_t count, int user)
+ssize_t rtlx_write(int index, const void __user *buffer, size_t count, int user)
 {
 	struct rtlx_channel *rt;
+	size_t rt_read;
 	size_t fl;
 
 	if (rtlx == NULL)
@@ -334,24 +342,35 @@
 
 	rt = &rtlx->channel[index];
 
+	mutex_lock(&channel_wqs[index].mutex);
+	smp_rmb();
+	rt_read = rt->rt_read;
+
 	/* total number of bytes to copy */
 	count = min(count,
-		    (size_t)write_spacefree(rt->rt_read, rt->rt_write,
-					    rt->buffer_size));
+		    (size_t)write_spacefree(rt_read, rt->rt_write, rt->buffer_size));
 
 	/* first bit from write pointer to the end of the buffer, or count */
 	fl = min(count, (size_t) rt->buffer_size - rt->rt_write);
 
-	copy_from (&rt->rt_buffer[rt->rt_write], buffer, fl, user);
+	failed = copy_from_user(rt->rt_buffer + rt->rt_write, buffer, fl);
+	if (failed)
+		goto out;
 
 	/* if there's any left copy to the beginning of the buffer */
-	if( count - fl )
-		copy_from (rt->rt_buffer, buffer + fl, count - fl, user);
+	if (count - fl) {
+		failed = copy_from_user(rt->rt_buffer, buffer + fl, count - fl);
+	}
 
-	rt->rt_write += count;
-	rt->rt_write %= rt->buffer_size;
+out:
+	count -= cailed;
 
-	return(count);
+	smp_wmb();
+	rt->rt_write = (rt->rt_write + count) % rt->buffer_size;
+	smp_wmb();
+	mutex_unlock(&channel_wqs[index].mutex);
+
+	return count;
 }
 
 
@@ -403,7 +422,7 @@
 		return 0;	// -EAGAIN makes cat whinge
 	}
 
-	return rtlx_read(minor, buffer, count, 1);
+	return rtlx_read(minor, buffer, count);
 }
 
 static ssize_t file_write(struct file *file, const char __user * buffer,
@@ -429,7 +448,7 @@
 			return ret;
 	}
 
-	return rtlx_write(minor, (void *)buffer, count, 1);
+	return rtlx_write(minor, buffer, count);
 }
 
 static const struct file_operations rtlx_fops = {
@@ -468,6 +487,7 @@
 		init_waitqueue_head(&channel_wqs[i].rt_queue);
 		init_waitqueue_head(&channel_wqs[i].lx_queue);
 		atomic_set(&channel_wqs[i].in_open, 0);
+		mutex_init(&channel_wqs[i].mutex);
 
 		dev = device_create(mt_class, NULL, MKDEV(major, i),
 		                    "%s%d", module_name, i);
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h
index fdbdbdc..297dfcb 100644
--- a/arch/mips/kernel/signal-common.h
+++ b/arch/mips/kernel/signal-common.h
@@ -31,4 +31,7 @@
  */
 extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall);
 
+/* Check and clear pending FPU exceptions in saved CSR */
+extern int fpcsr_pending(unsigned int __user *fpcsr);
+
 #endif	/* __SIGNAL_COMMON_H */
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index f091786..8c3c5a5 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -82,6 +82,7 @@
 {
 	int err = 0;
 	int i;
+	unsigned int used_math;
 
 	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
 
@@ -104,26 +105,53 @@
 		err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
 	}
 
-	err |= __put_user(!!used_math(), &sc->sc_used_math);
+	used_math = !!used_math();
+	err |= __put_user(used_math, &sc->sc_used_math);
 
-	if (used_math()) {
+	if (used_math) {
 		/*
 		 * Save FPU state to signal context. Signal handler
 		 * will "inherit" current FPU state.
 		 */
-		preempt_disable();
-
-		if (!is_fpu_owner()) {
-			own_fpu();
-			restore_fp(current);
-		}
+		own_fpu(1);
+		enable_fp_in_kernel();
 		err |= save_fp_context(sc);
-
-		preempt_enable();
+		disable_fp_in_kernel();
 	}
 	return err;
 }
 
+int fpcsr_pending(unsigned int __user *fpcsr)
+{
+	int err, sig = 0;
+	unsigned int csr, enabled;
+
+	err = __get_user(csr, fpcsr);
+	enabled = FPU_CSR_UNI_X | ((csr & FPU_CSR_ALL_E) << 5);
+	/*
+	 * If the signal handler set some FPU exceptions, clear it and
+	 * send SIGFPE.
+	 */
+	if (csr & enabled) {
+		csr &= ~enabled;
+		err |= __put_user(csr, fpcsr);
+		sig = SIGFPE;
+	}
+	return err ?: sig;
+}
+
+static int
+check_and_restore_fp_context(struct sigcontext __user *sc)
+{
+	int err, sig;
+
+	err = sig = fpcsr_pending(&sc->sc_fpc_csr);
+	if (err > 0)
+		err = 0;
+	err |= restore_fp_context(sc);
+	return err ?: sig;
+}
+
 int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
 {
 	unsigned int used_math;
@@ -157,19 +185,18 @@
 	err |= __get_user(used_math, &sc->sc_used_math);
 	conditional_used_math(used_math);
 
-	preempt_disable();
-
-	if (used_math()) {
+	if (used_math) {
 		/* restore fpu context if we have used it before */
-		own_fpu();
-		err |= restore_fp_context(sc);
+		own_fpu(0);
+		enable_fp_in_kernel();
+		if (!err)
+			err = check_and_restore_fp_context(sc);
+		disable_fp_in_kernel();
 	} else {
 		/* signal handler may have used FPU.  Give it up. */
-		lose_fpu();
+		lose_fpu(0);
 	}
 
-	preempt_enable();
-
 	return err;
 }
 
@@ -332,6 +359,7 @@
 {
 	struct sigframe __user *frame;
 	sigset_t blocked;
+	int sig;
 
 	frame = (struct sigframe __user *) regs.regs[29];
 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
@@ -345,8 +373,11 @@
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
 
-	if (restore_sigcontext(&regs, &frame->sf_sc))
+	sig = restore_sigcontext(&regs, &frame->sf_sc);
+	if (sig < 0)
 		goto badframe;
+	else if (sig)
+		force_sig(sig, current);
 
 	/*
 	 * Don't let your children do this ...
@@ -368,6 +399,7 @@
 	struct rt_sigframe __user *frame;
 	sigset_t set;
 	stack_t st;
+	int sig;
 
 	frame = (struct rt_sigframe __user *) regs.regs[29];
 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
@@ -381,8 +413,11 @@
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
 
-	if (restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext))
+	sig = restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext);
+	if (sig < 0)
 		goto badframe;
+	else if (sig)
+		force_sig(sig, current);
 
 	if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st)))
 		goto badframe;
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index 19bbef0..151fd2f 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -181,6 +181,7 @@
 {
 	int err = 0;
 	int i;
+	u32 used_math;
 
 	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
 
@@ -200,26 +201,34 @@
 		err |= __put_user(mflo3(), &sc->sc_lo3);
 	}
 
-	err |= __put_user(!!used_math(), &sc->sc_used_math);
+	used_math = !!used_math();
+	err |= __put_user(used_math, &sc->sc_used_math);
 
-	if (used_math()) {
+	if (used_math) {
 		/*
 		 * Save FPU state to signal context.  Signal handler
 		 * will "inherit" current FPU state.
 		 */
-		preempt_disable();
-
-		if (!is_fpu_owner()) {
-			own_fpu();
-			restore_fp(current);
-		}
+		own_fpu(1);
+		enable_fp_in_kernel();
 		err |= save_fp_context32(sc);
-
-		preempt_enable();
+		disable_fp_in_kernel();
 	}
 	return err;
 }
 
+static int
+check_and_restore_fp_context32(struct sigcontext32 __user *sc)
+{
+	int err, sig;
+
+	err = sig = fpcsr_pending(&sc->sc_fpc_csr);
+	if (err > 0)
+		err = 0;
+	err |= restore_fp_context32(sc);
+	return err ?: sig;
+}
+
 static int restore_sigcontext32(struct pt_regs *regs,
 				struct sigcontext32 __user *sc)
 {
@@ -250,19 +259,18 @@
 	err |= __get_user(used_math, &sc->sc_used_math);
 	conditional_used_math(used_math);
 
-	preempt_disable();
-
-	if (used_math()) {
+	if (used_math) {
 		/* restore fpu context if we have used it before */
-		own_fpu();
-		err |= restore_fp_context32(sc);
+		own_fpu(0);
+		enable_fp_in_kernel();
+		if (!err)
+			err = check_and_restore_fp_context32(sc);
+		disable_fp_in_kernel();
 	} else {
 		/* signal handler may have used FPU.  Give it up. */
-		lose_fpu();
+		lose_fpu(0);
 	}
 
-	preempt_enable();
-
 	return err;
 }
 
@@ -508,6 +516,7 @@
 {
 	struct sigframe32 __user *frame;
 	sigset_t blocked;
+	int sig;
 
 	frame = (struct sigframe32 __user *) regs.regs[29];
 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
@@ -521,8 +530,11 @@
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
 
-	if (restore_sigcontext32(&regs, &frame->sf_sc))
+	sig = restore_sigcontext32(&regs, &frame->sf_sc);
+	if (sig < 0)
 		goto badframe;
+	else if (sig)
+		force_sig(sig, current);
 
 	/*
 	 * Don't let your children do this ...
@@ -545,6 +557,7 @@
 	sigset_t set;
 	stack_t st;
 	s32 sp;
+	int sig;
 
 	frame = (struct rt_sigframe32 __user *) regs.regs[29];
 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
@@ -558,8 +571,11 @@
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
 
-	if (restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext))
+	sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
+	if (sig < 0)
 		goto badframe;
+	else if (sig)
+		force_sig(sig, current);
 
 	/* The ucontext contains a stack32_t, so we must convert!  */
 	if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index ecf1f7e..a9202fa 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -127,6 +127,7 @@
 	sigset_t set;
 	stack_t st;
 	s32 sp;
+	int sig;
 
 	frame = (struct rt_sigframe_n32 __user *) regs.regs[29];
 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
@@ -140,8 +141,11 @@
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
 
-	if (restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext))
+	sig = restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext);
+	if (sig < 0)
 		goto badframe;
+	else if (sig)
+		force_sig(sig, current);
 
 	/* The ucontext contains a stack32_t, so we must convert!  */
 	if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index f253eda..5dcfab6 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -4,6 +4,7 @@
 #include <linux/sched.h>
 #include <linux/cpumask.h>
 #include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
 #include <linux/module.h>
 
 #include <asm/cpu.h>
@@ -14,6 +15,7 @@
 #include <asm/hazards.h>
 #include <asm/mmu_context.h>
 #include <asm/smp.h>
+#include <asm/mips-boards/maltaint.h>
 #include <asm/mipsregs.h>
 #include <asm/cacheflush.h>
 #include <asm/time.h>
@@ -75,7 +77,7 @@
 
 void ipi_decode(struct smtc_ipi *);
 static void post_direct_ipi(int cpu, struct smtc_ipi *pipi);
-static void setup_cross_vpe_interrupts(void);
+static void setup_cross_vpe_interrupts(unsigned int nvpe);
 void init_smtc_stats(void);
 
 /* Global SMTC Status */
@@ -168,7 +170,10 @@
 
 int imstuckcount[2][8];
 /* vpemask represents IM/IE bits of per-VPE Status registers, low-to-high */
-int vpemask[2][8] = {{0,1,1,0,0,0,0,1},{0,1,0,0,0,0,0,1}};
+int vpemask[2][8] = {
+	{0, 0, 1, 0, 0, 0, 0, 1},
+	{0, 0, 0, 0, 0, 0, 0, 1}
+};
 int tcnoprog[NR_CPUS];
 static atomic_t idle_hook_initialized = {0};
 static int clock_hang_reported[NR_CPUS];
@@ -501,8 +506,7 @@
 
 	/* If we have multiple VPEs running, set up the cross-VPE interrupt */
 
-	if (nvpe > 1)
-		setup_cross_vpe_interrupts();
+	setup_cross_vpe_interrupts(nvpe);
 
 	/* Set up queue of free IPI "messages". */
 	nipi = NR_CPUS * IPIBUF_PER_CPU;
@@ -607,7 +611,12 @@
 int setup_irq_smtc(unsigned int irq, struct irqaction * new,
 			unsigned long hwmask)
 {
+	unsigned int vpe = current_cpu_data.vpe_id;
+
 	irq_hwmask[irq] = hwmask;
+#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
+	vpemask[vpe][irq - MIPSCPU_INT_BASE] = 1;
+#endif
 
 	return setup_irq(irq, new);
 }
@@ -812,12 +821,15 @@
 	smtc_ipi_nq(&freeIPIq, pipi);
 	switch (type_copy) {
 	case SMTC_CLOCK_TICK:
+		irq_enter();
+		kstat_this_cpu.irqs[MIPSCPU_INT_BASE + MIPSCPU_INT_CPUCTR]++;
 		/* Invoke Clock "Interrupt" */
 		ipi_timer_latch[dest_copy] = 0;
 #ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
 		clock_hang_reported[dest_copy] = 0;
 #endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
 		local_timer_interrupt(0, NULL);
+		irq_exit();
 		break;
 	case LINUX_SMP_IPI:
 		switch ((int)arg_copy) {
@@ -965,8 +977,11 @@
 
 static struct irqaction irq_ipi;
 
-static void setup_cross_vpe_interrupts(void)
+static void setup_cross_vpe_interrupts(unsigned int nvpe)
 {
+	if (nvpe < 1)
+		return;
+
 	if (!cpu_has_vint)
 		panic("SMTC Kernel requires Vectored Interupt support");
 
@@ -984,10 +999,17 @@
 
 /*
  * SMTC-specific hacks invoked from elsewhere in the kernel.
+ *
+ * smtc_ipi_replay is called from raw_local_irq_restore which is only ever
+ * called with interrupts disabled.  We do rely on interrupts being disabled
+ * here because using spin_lock_irqsave()/spin_unlock_irqrestore() would
+ * result in a recursive call to raw_local_irq_restore().
  */
 
-void smtc_ipi_replay(void)
+static void __smtc_ipi_replay(void)
 {
+	unsigned int cpu = smp_processor_id();
+
 	/*
 	 * To the extent that we've ever turned interrupts off,
 	 * we may have accumulated deferred IPIs.  This is subtle.
@@ -1002,17 +1024,30 @@
 	 * is clear, and we'll handle it as a real pseudo-interrupt
 	 * and not a pseudo-pseudo interrupt.
 	 */
-	if (IPIQ[smp_processor_id()].depth > 0) {
-		struct smtc_ipi *pipi;
-		extern void self_ipi(struct smtc_ipi *);
+	if (IPIQ[cpu].depth > 0) {
+		while (1) {
+			struct smtc_ipi_q *q = &IPIQ[cpu];
+			struct smtc_ipi *pipi;
+			extern void self_ipi(struct smtc_ipi *);
 
-		while ((pipi = smtc_ipi_dq(&IPIQ[smp_processor_id()]))) {
+			spin_lock(&q->lock);
+			pipi = __smtc_ipi_dq(q);
+			spin_unlock(&q->lock);
+			if (!pipi)
+				break;
+
 			self_ipi(pipi);
-			smtc_cpu_stats[smp_processor_id()].selfipis++;
+			smtc_cpu_stats[cpu].selfipis++;
 		}
 	}
 }
 
+void smtc_ipi_replay(void)
+{
+	raw_local_irq_disable();
+	__smtc_ipi_replay();
+}
+
 EXPORT_SYMBOL(smtc_ipi_replay);
 
 void smtc_idle_loop_hook(void)
@@ -1117,7 +1152,13 @@
 	 * is in use, there should never be any.
 	 */
 #ifndef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY
-	smtc_ipi_replay();
+	{
+		unsigned long flags;
+
+		local_irq_save(flags);
+		__smtc_ipi_replay();
+		local_irq_restore(flags);
+	}
 #endif /* CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY */
 }
 
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 18f56a9..7d76a85 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -610,16 +610,6 @@
 	if (fcr31 & FPU_CSR_UNI_X) {
 		int sig;
 
-		preempt_disable();
-
-#ifdef CONFIG_PREEMPT
-		if (!is_fpu_owner()) {
-			/* We might lose fpu before disabling preempt... */
-			own_fpu();
-			BUG_ON(!used_math());
-			restore_fp(current);
-		}
-#endif
 		/*
 		 * Unimplemented operation exception.  If we've got the full
 		 * software emulator on-board, let's use it...
@@ -630,18 +620,12 @@
 		 * register operands before invoking the emulator, which seems
 		 * a bit extreme for what should be an infrequent event.
 		 */
-		save_fp(current);
 		/* Ensure 'resume' not overwrite saved fp context again. */
-		lose_fpu();
-
-		preempt_enable();
+		lose_fpu(1);
 
 		/* Run the emulator */
 		sig = fpu_emulator_cop1Handler (regs, &current->thread.fpu, 1);
 
-		preempt_disable();
-
-		own_fpu();	/* Using the FPU again.  */
 		/*
 		 * We can't allow the emulated instruction to leave any of
 		 * the cause bit set in $fcr31.
@@ -649,9 +633,7 @@
 		current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
 
 		/* Restore the hardware register state */
-		restore_fp(current);
-
-		preempt_enable();
+		own_fpu(1);	/* Using the FPU again.  */
 
 		/* If something went wrong, signal */
 		if (sig)
@@ -775,12 +757,11 @@
 {
 	unsigned int cpid;
 
-	die_if_kernel("do_cpu invoked from kernel context!", regs);
-
 	cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
 
 	switch (cpid) {
 	case 0:
+		die_if_kernel("do_cpu invoked from kernel context!", regs);
 		if (!cpu_has_llsc)
 			if (!simulate_llsc(regs))
 				return;
@@ -791,21 +772,30 @@
 		break;
 
 	case 1:
-		preempt_disable();
-
-		own_fpu();
-		if (used_math()) {	/* Using the FPU again.  */
-			restore_fp(current);
-		} else {			/* First time FPU user.  */
+		if (!test_thread_flag(TIF_ALLOW_FP_IN_KERNEL))
+			die_if_kernel("do_cpu invoked from kernel context!",
+				      regs);
+		if (used_math())	/* Using the FPU again.  */
+			own_fpu(1);
+		else {			/* First time FPU user.  */
 			init_fpu();
 			set_used_math();
 		}
 
-		if (cpu_has_fpu) {
-			preempt_enable();
+		if (raw_cpu_has_fpu) {
+			if (test_thread_flag(TIF_ALLOW_FP_IN_KERNEL)) {
+				local_irq_disable();
+				if (cpu_has_fpu)
+					regs->cp0_status |= ST0_CU1;
+				/*
+				 * We must return without enabling
+				 * interrupts to ensure keep FPU
+				 * ownership until resume.
+				 */
+				return;
+			}
 		} else {
 			int sig;
-			preempt_enable();
 			sig = fpu_emulator_cop1Handler(regs,
 						&current->thread.fpu, 0);
 			if (sig)
@@ -1259,26 +1249,26 @@
 /*
  * This is used by native signal handling
  */
-asmlinkage int (*save_fp_context)(struct sigcontext *sc);
-asmlinkage int (*restore_fp_context)(struct sigcontext *sc);
+asmlinkage int (*save_fp_context)(struct sigcontext __user *sc);
+asmlinkage int (*restore_fp_context)(struct sigcontext __user *sc);
 
-extern asmlinkage int _save_fp_context(struct sigcontext *sc);
-extern asmlinkage int _restore_fp_context(struct sigcontext *sc);
+extern asmlinkage int _save_fp_context(struct sigcontext __user *sc);
+extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc);
 
-extern asmlinkage int fpu_emulator_save_context(struct sigcontext *sc);
-extern asmlinkage int fpu_emulator_restore_context(struct sigcontext *sc);
+extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc);
+extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc);
 
 #ifdef CONFIG_SMP
-static int smp_save_fp_context(struct sigcontext *sc)
+static int smp_save_fp_context(struct sigcontext __user *sc)
 {
-	return cpu_has_fpu
+	return raw_cpu_has_fpu
 	       ? _save_fp_context(sc)
 	       : fpu_emulator_save_context(sc);
 }
 
-static int smp_restore_fp_context(struct sigcontext *sc)
+static int smp_restore_fp_context(struct sigcontext __user *sc)
 {
-	return cpu_has_fpu
+	return raw_cpu_has_fpu
 	       ? _restore_fp_context(sc)
 	       : fpu_emulator_restore_context(sc);
 }
@@ -1306,14 +1296,14 @@
 /*
  * This is used by 32-bit signal stuff on the 64-bit kernel
  */
-asmlinkage int (*save_fp_context32)(struct sigcontext32 *sc);
-asmlinkage int (*restore_fp_context32)(struct sigcontext32 *sc);
+asmlinkage int (*save_fp_context32)(struct sigcontext32 __user *sc);
+asmlinkage int (*restore_fp_context32)(struct sigcontext32 __user *sc);
 
-extern asmlinkage int _save_fp_context32(struct sigcontext32 *sc);
-extern asmlinkage int _restore_fp_context32(struct sigcontext32 *sc);
+extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc);
+extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc);
 
-extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 *sc);
-extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 *sc);
+extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 __user *sc);
+extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user *sc);
 
 static inline void signal32_init(void)
 {
diff --git a/arch/mips/math-emu/kernel_linkage.c b/arch/mips/math-emu/kernel_linkage.c
index 5b3390f..ed49ef0 100644
--- a/arch/mips/math-emu/kernel_linkage.c
+++ b/arch/mips/math-emu/kernel_linkage.c
@@ -51,7 +51,7 @@
  * with appropriate macros from uaccess.h
  */
 
-int fpu_emulator_save_context(struct sigcontext *sc)
+int fpu_emulator_save_context(struct sigcontext __user *sc)
 {
 	int i;
 	int err = 0;
@@ -65,7 +65,7 @@
 	return err;
 }
 
-int fpu_emulator_restore_context(struct sigcontext *sc)
+int fpu_emulator_restore_context(struct sigcontext __user *sc)
 {
 	int i;
 	int err = 0;
@@ -84,7 +84,7 @@
  * This is the o32 version
  */
 
-int fpu_emulator_save_context32(struct sigcontext32 *sc)
+int fpu_emulator_save_context32(struct sigcontext32 __user *sc)
 {
 	int i;
 	int err = 0;
@@ -98,7 +98,7 @@
 	return err;
 }
 
-int fpu_emulator_restore_context32(struct sigcontext32 *sc)
+int fpu_emulator_restore_context32(struct sigcontext32 __user *sc)
 {
 	int i;
 	int err = 0;
diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c
index 1acdf09..88e9c2a 100644
--- a/arch/mips/mips-boards/generic/init.c
+++ b/arch/mips/mips-boards/generic/init.c
@@ -145,7 +145,7 @@
 	char parity = '\0', bits = '\0', flow = '\0';
 	char *s;
 
-	if ((strstr(prom_getcmdline(), "console=ttyS")) == NULL) {
+	if ((strstr(prom_getcmdline(), "console=")) == NULL) {
 		s = prom_getenv("modetty0");
 		if (s) {
 			while (*s >= '0' && *s <= '9')
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c
index d1af42c..59868a1 100644
--- a/arch/mips/mm/c-r3k.c
+++ b/arch/mips/mm/c-r3k.c
@@ -260,7 +260,7 @@
 {
 }
 
-static void local_r3k_flush_data_cache_page(unsigned long addr)
+static void local_r3k_flush_data_cache_page(void *addr)
 {
 }
 
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 31819c5..4e8f1b6 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -3,7 +3,8 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1994 - 2003 by Ralf Baechle
+ * Copyright (C) 1994 - 2003, 07 by Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2007 MIPS Technologies, Inc.
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -88,6 +89,19 @@
 
 EXPORT_SYMBOL(__flush_dcache_page);
 
+void __flush_anon_page(struct page *page, unsigned long vmaddr)
+{
+	if (pages_do_alias((unsigned long)page_address(page), vmaddr)) {
+		void *kaddr;
+
+		kaddr = kmap_coherent(page, vmaddr);
+		flush_data_cache_page((unsigned long)kaddr);
+		kunmap_coherent(kaddr);
+	}
+}
+
+EXPORT_SYMBOL(__flush_anon_page);
+
 void __update_cache(struct vm_area_struct *vma, unsigned long address,
 	pte_t pte)
 {
diff --git a/arch/mips/mm/cerr-sb1.c b/arch/mips/mm/cerr-sb1.c
index 11a9166..4c72e65 100644
--- a/arch/mips/mm/cerr-sb1.c
+++ b/arch/mips/mm/cerr-sb1.c
@@ -177,8 +177,8 @@
 
 asmlinkage void sb1_cache_error(void)
 {
-	uint64_t cerr_dpa;
 	uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res;
+	unsigned long long cerr_dpa;
 
 #ifdef CONFIG_SIBYTE_BW_TRACE
 	/* Freeze the trace buffer now */
@@ -329,8 +329,9 @@
 {
 	unsigned short way;
 	int valid;
-	uint64_t taglo, va, tlo_tmp;
 	uint32_t taghi, taglolo, taglohi;
+	unsigned long long taglo, va;
+	uint64_t tlo_tmp;
 	uint8_t lru;
 	int res = 0;
 
@@ -484,8 +485,8 @@
 {
 	int valid, way;
 	unsigned char state;
-	uint64_t taglo, pa;
 	uint32_t taghi, taglolo, taglohi;
+	unsigned long long taglo, pa;
 	uint8_t ecc, lru;
 	int res = 0;
 
@@ -535,8 +536,8 @@
 		}
 
 		if (data) {
-			uint64_t datalo;
 			uint32_t datalohi, datalolo, datahi;
+			unsigned long long datalo;
 			int offset;
 			char bad_ecc = 0;
 
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index f503d02..f0eb299 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -19,6 +19,13 @@
 
 #include <dma-coherence.h>
 
+static inline unsigned long dma_addr_to_virt(dma_addr_t dma_addr)
+{
+	unsigned long addr = plat_dma_addr_to_phys(dma_addr);
+
+	return (unsigned long)phys_to_virt(addr);
+}
+
 /*
  * Warning on the terminology - Linux calls an uncached area coherent;
  * MIPS terminology calls memory areas with hardware maintained coherency
@@ -140,7 +147,7 @@
 	enum dma_data_direction direction)
 {
 	if (cpu_is_noncoherent_r10000(dev))
-		__dma_sync(plat_dma_addr_to_phys(dma_addr) + PAGE_OFFSET, size,
+		__dma_sync(dma_addr_to_virt(dma_addr), size,
 		           direction);
 
 	plat_unmap_dma_mem(dma_addr);
@@ -234,7 +241,7 @@
 	if (cpu_is_noncoherent_r10000(dev)) {
 		unsigned long addr;
 
-		addr = PAGE_OFFSET + plat_dma_addr_to_phys(dma_handle);
+		addr = dma_addr_to_virt(dma_handle);
 		__dma_sync(addr, size, direction);
 	}
 }
@@ -249,7 +256,7 @@
 	if (!plat_device_is_coherent(dev)) {
 		unsigned long addr;
 
-		addr = PAGE_OFFSET + plat_dma_addr_to_phys(dma_handle);
+		addr = dma_addr_to_virt(dma_handle);
 		__dma_sync(addr, size, direction);
 	}
 }
@@ -264,7 +271,7 @@
 	if (cpu_is_noncoherent_r10000(dev)) {
 		unsigned long addr;
 
-		addr = PAGE_OFFSET + plat_dma_addr_to_phys(dma_handle);
+		addr = dma_addr_to_virt(dma_handle);
 		__dma_sync(addr + offset, size, direction);
 	}
 }
@@ -279,7 +286,7 @@
 	if (!plat_device_is_coherent(dev)) {
 		unsigned long addr;
 
-		addr = PAGE_OFFSET + plat_dma_addr_to_phys(dma_handle);
+		addr = dma_addr_to_virt(dma_handle);
 		__dma_sync(addr + offset, size, direction);
 	}
 }
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 6f90e7e..f9c595d 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -42,7 +42,7 @@
 	siginfo_t info;
 
 #if 0
-	printk("Cpu%d[%s:%d:%0*lx:%ld:%0*lx]\n", smp_processor_id(),
+	printk("Cpu%d[%s:%d:%0*lx:%ld:%0*lx]\n", raw_smp_processor_id(),
 	       current->comm, current->pid, field, address, write,
 	       field, regs->cp0_epc);
 #endif
@@ -165,7 +165,7 @@
 
 	printk(KERN_ALERT "CPU %d Unable to handle kernel paging request at "
 	       "virtual address %0*lx, epc == %0*lx, ra == %0*lx\n",
-	       smp_processor_id(), field, address, field, regs->cp0_epc,
+	       raw_smp_processor_id(), field, address, field, regs->cp0_epc,
 	       field,  regs->regs[31]);
 	die("Oops", regs);
 
@@ -228,7 +228,7 @@
 		pmd_t *pmd, *pmd_k;
 		pte_t *pte_k;
 
-		pgd = (pgd_t *) pgd_current[smp_processor_id()] + offset;
+		pgd = (pgd_t *) pgd_current[raw_smp_processor_id()] + offset;
 		pgd_k = init_mm.pgd + offset;
 
 		if (!pgd_present(*pgd_k))
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index f08ae71c..e9951c0e 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -123,7 +123,7 @@
 static inline void kmap_coherent_init(void) {}
 #endif
 
-static inline void *kmap_coherent(struct page *page, unsigned long addr)
+void *kmap_coherent(struct page *page, unsigned long addr)
 {
 	enum fixed_addresses idx;
 	unsigned long vaddr, flags, entrylo;
@@ -177,7 +177,7 @@
 
 #define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
 
-static inline void kunmap_coherent(struct page *page)
+void kunmap_coherent(struct page *page)
 {
 #ifndef CONFIG_MIPS_MT_SMTC
 	unsigned int wired;
@@ -377,7 +377,7 @@
 #ifdef CONFIG_FLATMEM
 	free_area_init(zones_size);
 #else
-	pfn = 0;
+	pfn = min_low_pfn;
 	for (i = 0; i < MAX_NR_ZONES; i++)
 		for (j = 0; j < zones_size[i]; j++, pfn++)
 			if (!page_is_ram(pfn))
diff --git a/arch/mips/mm/pg-sb1.c b/arch/mips/mm/pg-sb1.c
index fc3c787..adb37d0 100644
--- a/arch/mips/mm/pg-sb1.c
+++ b/arch/mips/mm/pg-sb1.c
@@ -218,8 +218,7 @@
 	for (i = 0; i < DM_NUM_CHANNELS; i++) {
 		const u64 base_val = CPHYSADDR(&page_descr[i]) |
 				     V_DM_DSCR_BASE_RINGSZ(1);
-		volatile void *base_reg =
-			IOADDR(A_DM_REGISTER(i, R_DM_DSCR_BASE));
+		void *base_reg = IOADDR(A_DM_REGISTER(i, R_DM_DSCR_BASE));
 
 		__raw_writeq(base_val, base_reg);
 		__raw_writeq(base_val | M_DM_DSCR_BASE_RESET, base_reg);
diff --git a/arch/mips/momentum/ocelot_c/irq.c b/arch/mips/momentum/ocelot_c/irq.c
index 40472f7..844d566 100644
--- a/arch/mips/momentum/ocelot_c/irq.c
+++ b/arch/mips/momentum/ocelot_c/irq.c
@@ -64,7 +64,7 @@
 
 asmlinkage void plat_irq_dispatch(void)
 {
-	unsigned int pending = read_c0_cause() & read_c0_status();
+	unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
 
 	if (pending & STATUSF_IP0)
 		do_IRQ(0);
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index 9d08608..69a8bcf 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -74,13 +74,13 @@
 
 __define_perf_accessors(perfcntr, 0, 2)
 __define_perf_accessors(perfcntr, 1, 3)
-__define_perf_accessors(perfcntr, 2, 2)
-__define_perf_accessors(perfcntr, 3, 2)
+__define_perf_accessors(perfcntr, 2, 0)
+__define_perf_accessors(perfcntr, 3, 1)
 
 __define_perf_accessors(perfctrl, 0, 2)
 __define_perf_accessors(perfctrl, 1, 3)
-__define_perf_accessors(perfctrl, 2, 2)
-__define_perf_accessors(perfctrl, 3, 2)
+__define_perf_accessors(perfctrl, 2, 0)
+__define_perf_accessors(perfctrl, 3, 1)
 
 struct op_mips_model op_model_mipsxx_ops;
 
@@ -97,7 +97,6 @@
 	int i;
 
 	/* Compute the performance counter control word.  */
-	/* For now count kernel and user mode */
 	for (i = 0; i < counters; i++) {
 		reg.control[i] = 0;
 		reg.counter[i] = 0;
@@ -234,9 +233,6 @@
 		counters = __n_counters();
 	}
 
-#ifdef CONFIG_MIPS_MT_SMP
-	counters >> 1;
-#endif
 	return counters;
 }
 
@@ -270,6 +266,10 @@
 
 	reset_counters(counters);
 
+#ifdef CONFIG_MIPS_MT_SMP
+	counters >>= 1;
+#endif
+
 	op_model_mipsxx_ops.num_counters = counters;
 	switch (current_cpu_data.cputype) {
 	case CPU_20KC:
@@ -326,7 +326,11 @@
 
 static void mipsxx_exit(void)
 {
-	reset_counters(op_model_mipsxx_ops.num_counters);
+	int counters = op_model_mipsxx_ops.num_counters;
+#ifdef CONFIG_MIPS_MT_SMP
+	counters <<= 1;
+#endif
+	reset_counters(counters);
 
 	perf_irq = null_perf_irq;
 }
diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c
index f6774f5..d7b9e13 100644
--- a/arch/mips/pci/pci-bcm1480.c
+++ b/arch/mips/pci/pci-bcm1480.c
@@ -216,7 +216,7 @@
 	/*
 	 * See if the PCI bus has been configured by the firmware.
 	 */
-	reg = *((volatile uint64_t *) IOADDR(A_SCD_SYSTEM_CFG));
+	reg = __raw_readq(IOADDR(A_SCD_SYSTEM_CFG));
 	if (!(reg & M_BCM1480_SYS_PCI_HOST)) {
 		bcm1480_bus_status |= PCI_DEVICE_MODE;
 	} else {
diff --git a/arch/mips/pci/pci-ev64120.c b/arch/mips/pci/pci-ev64120.c
index 9cd859e..a84f594 100644
--- a/arch/mips/pci/pci-ev64120.c
+++ b/arch/mips/pci/pci-ev64120.c
@@ -1,4 +1,5 @@
 #include <linux/pci.h>
+#include <asm/irq.h>
 
 int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
diff --git a/arch/mips/pci/pci-sb1250.c b/arch/mips/pci/pci-sb1250.c
index 80f5e8c..75c1246 100644
--- a/arch/mips/pci/pci-sb1250.c
+++ b/arch/mips/pci/pci-sb1250.c
@@ -228,7 +228,7 @@
 	/*
 	 * See if the PCI bus has been configured by the firmware.
 	 */
-	reg = *((volatile uint64_t *) IOADDR(A_SCD_SYSTEM_CFG));
+	reg = __raw_readq(IOADDR(A_SCD_SYSTEM_CFG));
 	if (!(reg & M_SYS_PCI_HOST)) {
 		sb1250_bus_status |= PCI_DEVICE_MODE;
 	} else {
diff --git a/arch/mips/philips/pnx8550/common/int.c b/arch/mips/philips/pnx8550/common/int.c
index d48665e..aad0342 100644
--- a/arch/mips/philips/pnx8550/common/int.c
+++ b/arch/mips/philips/pnx8550/common/int.c
@@ -83,16 +83,15 @@
 
 asmlinkage void plat_irq_dispatch(void)
 {
-	unsigned int pending = read_c0_status() & read_c0_cause();
+	unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
 
 	if (pending & STATUSF_IP2)
 		hw0_irqdispatch(2);
 	else if (pending & STATUSF_IP7) {
 		if (read_c0_config7() & 0x01c0)
 			timer_irqdispatch(7);
-	}
-
-	spurious_interrupt();
+	} else
+		spurious_interrupt();
 }
 
 static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
@@ -204,19 +203,7 @@
 		 * Note, PCI INTA is active low on the bus, but inverted
 		 * in the GIC, so to us it's active high.
 		 */
-#ifdef CONFIG_PNX8550_V2PCI
-		if (gic_int_line == (PNX8550_INT_GPIO0 - PNX8550_INT_GIC_MIN)) {
-			/* PCI INT through gpio 8, which is setup in
-			 * pnx8550_setup.c and routed to GPIO
-			 * Interrupt Level 0 (GPIO Connection 58).
-			 * Set it active low. */
-
-			PNX8550_GIC_REQ(gic_int_line) = 0x1E020000;
-		} else
-#endif
-		{
-			PNX8550_GIC_REQ(i - PNX8550_INT_GIC_MIN) = 0x1E000000;
-		}
+		PNX8550_GIC_REQ(i - PNX8550_INT_GIC_MIN) = 0x1E000000;
 
 		/* mask/priority is still 0 so we will not get any
 		 * interrupts until it is unmasked */
diff --git a/arch/mips/qemu/q-smp.c b/arch/mips/qemu/q-smp.c
index 5a12354..786bbfa 100644
--- a/arch/mips/qemu/q-smp.c
+++ b/arch/mips/qemu/q-smp.c
@@ -46,3 +46,10 @@
 void prom_boot_secondary(int cpu, struct task_struct *idle)
 {
 }
+
+void __init plat_smp_setup(void)
+{
+}
+void __init plat_prepare_cpus(unsigned int max_cpus)
+{
+}
diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c
index b454924..1834832 100644
--- a/arch/mips/sgi-ip22/ip22-int.c
+++ b/arch/mips/sgi-ip22/ip22-int.c
@@ -237,7 +237,7 @@
 
 asmlinkage void plat_irq_dispatch(void)
 {
-	unsigned int pending = read_c0_cause();
+	unsigned int pending = read_c0_status() & read_c0_cause();
 
 	/*
 	 * First we check for r4k counter/timer IRQ.
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c
index 8c450d9..fb9da9a 100644
--- a/arch/mips/sgi-ip32/ip32-irq.c
+++ b/arch/mips/sgi-ip32/ip32-irq.c
@@ -454,7 +454,7 @@
 
 asmlinkage void plat_irq_dispatch(void)
 {
-	unsigned int pending = read_c0_cause();
+	unsigned int pending = read_c0_status() & read_c0_cause();
 
 	if (likely(pending & IE_IRQ0))
 		ip32_irq0();
diff --git a/arch/mips/sibyte/Kconfig b/arch/mips/sibyte/Kconfig
index 67dac62..bdf24a7 100644
--- a/arch/mips/sibyte/Kconfig
+++ b/arch/mips/sibyte/Kconfig
@@ -1,31 +1,35 @@
 config SIBYTE_SB1250
 	bool
 	select HW_HAS_PCI
-	select SIBYTE_HAS_LDT
+	select SIBYTE_ENABLE_LDT_IF_PCI
 	select SIBYTE_SB1xxx_SOC
 	select SYS_SUPPORTS_SMP
 
 config SIBYTE_BCM1120
 	bool
 	select SIBYTE_BCM112X
+	select SIBYTE_HAS_ZBUS_PROFILING
 	select SIBYTE_SB1xxx_SOC
 
 config SIBYTE_BCM1125
 	bool
 	select HW_HAS_PCI
 	select SIBYTE_BCM112X
+	select SIBYTE_HAS_ZBUS_PROFILING
 	select SIBYTE_SB1xxx_SOC
 
 config SIBYTE_BCM1125H
 	bool
 	select HW_HAS_PCI
 	select SIBYTE_BCM112X
-	select SIBYTE_HAS_LDT
+	select SIBYTE_ENABLE_LDT_IF_PCI
+	select SIBYTE_HAS_ZBUS_PROFILING
 	select SIBYTE_SB1xxx_SOC
 
 config SIBYTE_BCM112X
 	bool
 	select SIBYTE_SB1xxx_SOC
+	select SIBYTE_HAS_ZBUS_PROFILING
 
 config SIBYTE_BCM1x80
 	bool
@@ -37,6 +41,7 @@
 	bool
 	select HW_HAS_PCI
 	select SIBYTE_SB1xxx_SOC
+	select SIBYTE_HAS_ZBUS_PROFILING
 	select SYS_SUPPORTS_SMP
 
 config SIBYTE_SB1xxx_SOC
@@ -95,8 +100,10 @@
 
 config SIBYTE_HAS_LDT
 	bool
-	depends on PCI && (SIBYTE_SB1250 || SIBYTE_BCM1125H)
-	default y
+
+config SIBYTE_ENABLE_LDT_IF_PCI
+	bool
+	select SIBYTE_HAS_LDT if PCI
 
 config SIMULATION
 	bool "Running under simulation"
@@ -162,5 +169,8 @@
 	depends on SIBYTE_SB1xxx_SOC
 
 config SIBYTE_TBPROF
-	bool "Support for ZBbus profiling"
-	depends on SIBYTE_SB1xxx_SOC
+	tristate "Support for ZBbus profiling"
+	depends on SIBYTE_HAS_ZBUS_PROFILING
+
+config SIBYTE_HAS_ZBUS_PROFILING
+	bool
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
index 20af0f1..ba0c4b7 100644
--- a/arch/mips/sibyte/bcm1480/irq.c
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -141,11 +141,11 @@
 	unsigned long flags;
 	unsigned int irq_dirty;
 
-	i = first_cpu(mask);
-	if (next_cpu(i, mask) <= NR_CPUS) {
+	if (cpus_weight(mask) != 1) {
 		printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq);
 		return;
 	}
+	i = first_cpu(mask);
 
 	/* Convert logical CPU to physical CPU */
 	cpu = cpu_logical_map(i);
diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c
index bf32827..6eac36d 100644
--- a/arch/mips/sibyte/bcm1480/smp.c
+++ b/arch/mips/sibyte/bcm1480/smp.c
@@ -34,21 +34,21 @@
  * independent of board/firmware
  */
 
-static volatile void *mailbox_0_set_regs[] = {
+static void *mailbox_0_set_regs[] = {
 	IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
 	IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
 	IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
 	IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
 };
 
-static volatile void *mailbox_0_clear_regs[] = {
+static void *mailbox_0_clear_regs[] = {
 	IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
 	IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
 	IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
 	IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
 };
 
-static volatile void *mailbox_0_regs[] = {
+static void *mailbox_0_regs[] = {
 	IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
 	IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
 	IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
diff --git a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
index 212547c..ea0ca13 100644
--- a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
+++ b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
@@ -1,6 +1,4 @@
 /*
- * Copyright (C) 2001, 2002, 2003 Broadcom Corporation
- *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
@@ -14,10 +12,16 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * Copyright (C) 2001, 2002, 2003 Broadcom Corporation
+ * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org>
+ * Copyright (C) 2007 MIPS Technologies, Inc.
+ *    written by Ralf Baechle <ralf@linux-mips.org>
  */
 
-#define SBPROF_TB_DEBUG 0
+#undef DEBUG
 
+#include <linux/device.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -27,24 +31,98 @@
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
 #include <linux/errno.h>
-#include <linux/reboot.h>
-#include <linux/smp_lock.h>
+#include <linux/types.h>
 #include <linux/wait.h>
-#include <asm/uaccess.h>
+
 #include <asm/io.h>
 #include <asm/sibyte/sb1250.h>
 #include <asm/sibyte/sb1250_regs.h>
 #include <asm/sibyte/sb1250_scd.h>
 #include <asm/sibyte/sb1250_int.h>
-#include <asm/sibyte/trace_prof.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
 
-#define DEVNAME "bcm1250_tbprof"
+#define SBPROF_TB_MAJOR 240
+
+typedef u64 tb_sample_t[6*256];
+
+enum open_status {
+	SB_CLOSED,
+	SB_OPENING,
+	SB_OPEN
+};
+
+struct sbprof_tb {
+	wait_queue_head_t	tb_sync;
+	wait_queue_head_t	tb_read;
+	struct mutex		lock;
+	enum open_status	open;
+	tb_sample_t		*sbprof_tbbuf;
+	int			next_tb_sample;
+
+	volatile int		tb_enable;
+	volatile int		tb_armed;
+
+};
 
 static struct sbprof_tb sbp;
 
+#define MAX_SAMPLE_BYTES (24*1024*1024)
+#define MAX_TBSAMPLE_BYTES (12*1024*1024)
+
+#define MAX_SAMPLES (MAX_SAMPLE_BYTES/sizeof(u_int32_t))
+#define TB_SAMPLE_SIZE (sizeof(tb_sample_t))
+#define MAX_TB_SAMPLES (MAX_TBSAMPLE_BYTES/TB_SAMPLE_SIZE)
+
+/* ioctls */
+#define SBPROF_ZBSTART		_IOW('s', 0, int)
+#define SBPROF_ZBSTOP		_IOW('s', 1, int)
+#define SBPROF_ZBWAITFULL	_IOW('s', 2, int)
+
+/*
+ * Routines for using 40-bit SCD cycle counter
+ *
+ * Client responsible for either handling interrupts or making sure
+ * the cycles counter never saturates, e.g., by doing
+ * zclk_timer_init(0) at least every 2^40 - 1 ZCLKs.
+ */
+
+/*
+ * Configures SCD counter 0 to count ZCLKs starting from val;
+ * Configures SCD counters1,2,3 to count nothing.
+ * Must not be called while gathering ZBbus profiles.
+ */
+
+#define zclk_timer_init(val) \
+  __asm__ __volatile__ (".set push;" \
+			".set mips64;" \
+			"la   $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \
+			"sd   %0, 0x10($8);"   /* write val to counter0 */ \
+			"sd   %1, 0($8);"      /* config counter0 for zclks*/ \
+			".set pop" \
+			: /* no outputs */ \
+						     /* enable, counter0 */ \
+			: /* inputs */ "r"(val), "r" ((1ULL << 33) | 1ULL) \
+			: /* modifies */ "$8" )
+
+
+/* Reads SCD counter 0 and puts result in value
+   unsigned long long val; */
+#define zclk_get(val) \
+  __asm__ __volatile__ (".set push;" \
+			".set mips64;" \
+			"la   $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \
+			"ld   %0, 0x10($8);"   /* write val to counter0 */ \
+			".set pop" \
+			: /* outputs */ "=r"(val) \
+			: /* inputs */ \
+			: /* modifies */ "$8" )
+
+#define DEVNAME "bcm1250_tbprof"
+
 #define TB_FULL (sbp.next_tb_sample == MAX_TB_SAMPLES)
 
-/************************************************************************
+/*
  * Support for ZBbus sampling using the trace buffer
  *
  * We use the SCD performance counter interrupt, caused by a Zclk counter
@@ -54,30 +132,36 @@
  * overflow.
  *
  * We map the interrupt for trace_buffer_freeze to handle it on CPU 0.
- *
- ************************************************************************/
+ */
 
-static u_int64_t tb_period;
+static u64 tb_period;
 
 static void arm_tb(void)
 {
-        u_int64_t scdperfcnt;
-	u_int64_t next = (1ULL << 40) - tb_period;
-	u_int64_t tb_options = M_SCD_TRACE_CFG_FREEZE_FULL;
-	/* Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to
-	   trigger start of trace.  XXX vary sampling period */
+        u64 scdperfcnt;
+	u64 next = (1ULL << 40) - tb_period;
+	u64 tb_options = M_SCD_TRACE_CFG_FREEZE_FULL;
+
+	/*
+	 * Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to trigger
+	 *start of trace.  XXX vary sampling period
+	 */
 	__raw_writeq(0, IOADDR(A_SCD_PERF_CNT_1));
 	scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG));
-	/* Unfortunately, in Pass 2 we must clear all counters to knock down
-	   a previous interrupt request.  This means that bus profiling
-	   requires ALL of the SCD perf counters. */
+
+	/*
+	 * Unfortunately, in Pass 2 we must clear all counters to knock down a
+	 * previous interrupt request.  This means that bus profiling requires
+	 * ALL of the SCD perf counters.
+	 */
 	__raw_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) |
-						// keep counters 0,2,3 as is
-		     M_SPC_CFG_ENABLE |		// enable counting
-		     M_SPC_CFG_CLEAR |		// clear all counters
-		     V_SPC_CFG_SRC1(1),		// counter 1 counts cycles
+						/* keep counters 0,2,3 as is */
+		     M_SPC_CFG_ENABLE |		/* enable counting */
+		     M_SPC_CFG_CLEAR |		/* clear all counters */
+		     V_SPC_CFG_SRC1(1),		/* counter 1 counts cycles */
 		     IOADDR(A_SCD_PERF_CNT_CFG));
 	__raw_writeq(next, IOADDR(A_SCD_PERF_CNT_1));
+
 	/* Reset the trace buffer */
 	__raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
 #if 0 && defined(M_SCD_TRACE_CFG_FORCECNT)
@@ -91,43 +175,45 @@
 static irqreturn_t sbprof_tb_intr(int irq, void *dev_id)
 {
 	int i;
-	DBG(printk(DEVNAME ": tb_intr\n"));
+
+	pr_debug(DEVNAME ": tb_intr\n");
+
 	if (sbp.next_tb_sample < MAX_TB_SAMPLES) {
 		/* XXX should use XKPHYS to make writes bypass L2 */
-		u_int64_t *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++];
+		u64 *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++];
 		/* Read out trace */
 		__raw_writeq(M_SCD_TRACE_CFG_START_READ,
 			     IOADDR(A_SCD_TRACE_CFG));
 		__asm__ __volatile__ ("sync" : : : "memory");
 		/* Loop runs backwards because bundles are read out in reverse order */
 		for (i = 256 * 6; i > 0; i -= 6) {
-			// Subscripts decrease to put bundle in the order
-			//   t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi
+			/* Subscripts decrease to put bundle in the order */
+			/*   t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi */
 			p[i - 1] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
-								// read t2 hi
+								/* read t2 hi */
 			p[i - 2] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
-								// read t2 lo
+								/* read t2 lo */
 			p[i - 3] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
-								// read t1 hi
+								/* read t1 hi */
 			p[i - 4] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
-								// read t1 lo
+								/* read t1 lo */
 			p[i - 5] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
-								// read t0 hi
+								/* read t0 hi */
 			p[i - 6] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
-								// read t0 lo
+								/* read t0 lo */
 		}
 		if (!sbp.tb_enable) {
-			DBG(printk(DEVNAME ": tb_intr shutdown\n"));
+			pr_debug(DEVNAME ": tb_intr shutdown\n");
 			__raw_writeq(M_SCD_TRACE_CFG_RESET,
 				     IOADDR(A_SCD_TRACE_CFG));
 			sbp.tb_armed = 0;
 			wake_up(&sbp.tb_sync);
 		} else {
-			arm_tb();	// knock down current interrupt and get another one later
+			arm_tb();	/* knock down current interrupt and get another one later */
 		}
 	} else {
 		/* No more trace buffer samples */
-		DBG(printk(DEVNAME ": tb_intr full\n"));
+		pr_debug(DEVNAME ": tb_intr full\n");
 		__raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
 		sbp.tb_armed = 0;
 		if (!sbp.tb_enable) {
@@ -135,6 +221,7 @@
 		}
 		wake_up(&sbp.tb_read);
 	}
+
 	return IRQ_HANDLED;
 }
 
@@ -144,23 +231,30 @@
 	return IRQ_NONE;
 }
 
-int sbprof_zbprof_start(struct file *filp)
-{
-	u_int64_t scdperfcnt;
+/*
+ * Requires: Already called zclk_timer_init with a value that won't
+ *           saturate 40 bits.  No subsequent use of SCD performance counters
+ *           or trace buffer.
+ */
 
-	if (sbp.tb_enable)
+static int sbprof_zbprof_start(struct file *filp)
+{
+	u64 scdperfcnt;
+	int err;
+
+	if (xchg(&sbp.tb_enable, 1))
 		return -EBUSY;
 
-	DBG(printk(DEVNAME ": starting\n"));
+	pr_debug(DEVNAME ": starting\n");
 
-	sbp.tb_enable = 1;
 	sbp.next_tb_sample = 0;
 	filp->f_pos = 0;
 
-	if (request_irq
-	    (K_INT_TRACE_FREEZE, sbprof_tb_intr, 0, DEVNAME " trace freeze", &sbp)) {
+	err = request_irq(K_INT_TRACE_FREEZE, sbprof_tb_intr, 0,
+	                DEVNAME " trace freeze", &sbp);
+	if (err)
 		return -EBUSY;
-	}
+
 	/* Make sure there isn't a perf-cnt interrupt waiting */
 	scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG));
 	/* Disable and clear counters, override SRC_1 */
@@ -168,18 +262,21 @@
 		     M_SPC_CFG_ENABLE | M_SPC_CFG_CLEAR | V_SPC_CFG_SRC1(1),
 		     IOADDR(A_SCD_PERF_CNT_CFG));
 
-	/* We grab this interrupt to prevent others from trying to use
-           it, even though we don't want to service the interrupts
-           (they only feed into the trace-on-interrupt mechanism) */
-	if (request_irq
-	    (K_INT_PERF_CNT, sbprof_pc_intr, 0, DEVNAME " scd perfcnt", &sbp)) {
-		free_irq(K_INT_TRACE_FREEZE, &sbp);
-		return -EBUSY;
-	}
+	/*
+	 * We grab this interrupt to prevent others from trying to use it, even
+	 * though we don't want to service the interrupts (they only feed into
+	 * the trace-on-interrupt mechanism)
+	 */
+	err = request_irq(K_INT_PERF_CNT, sbprof_pc_intr, 0,
+	                DEVNAME " scd perfcnt", &sbp);
+	if (err)
+		goto out_free_irq;
 
-	/* I need the core to mask these, but the interrupt mapper to
-	   pass them through.  I am exploiting my knowledge that
-	   cp0_status masks out IP[5]. krw */
+	/*
+	 * I need the core to mask these, but the interrupt mapper to pass them
+	 * through.  I am exploiting my knowledge that cp0_status masks out
+	 * IP[5]. krw
+	 */
 	__raw_writeq(K_INT_MAP_I3,
 		     IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
 			    (K_INT_PERF_CNT << 3)));
@@ -201,7 +298,7 @@
 	__raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3));
 
 	/* Initialize Trace Event 0-7 */
-	//				when interrupt
+	/*				when interrupt */
 	__raw_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0));
 	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1));
 	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2));
@@ -212,10 +309,10 @@
 	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7));
 
 	/* Initialize Trace Sequence 0-7 */
-	//				     Start on event 0 (interrupt)
+	/*				     Start on event 0 (interrupt) */
 	__raw_writeq(V_SCD_TRSEQ_FUNC_START | 0x0fff,
 		     IOADDR(A_SCD_TRACE_SEQUENCE_0));
-	//			  dsamp when d used | asamp when a used
+	/*			  dsamp when d used | asamp when a used */
 	__raw_writeq(M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE |
 		     K_SCD_TRSEQ_TRIGGER_ALL,
 		     IOADDR(A_SCD_TRACE_SEQUENCE_1));
@@ -232,33 +329,41 @@
 
 	arm_tb();
 
-	DBG(printk(DEVNAME ": done starting\n"));
+	pr_debug(DEVNAME ": done starting\n");
 
 	return 0;
+
+out_free_irq:
+	free_irq(K_INT_TRACE_FREEZE, &sbp);
+
+	return err;
 }
 
-int sbprof_zbprof_stop(void)
+static int sbprof_zbprof_stop(void)
 {
-	DEFINE_WAIT(wait);
-	DBG(printk(DEVNAME ": stopping\n"));
+	int err;
+
+	pr_debug(DEVNAME ": stopping\n");
 
 	if (sbp.tb_enable) {
+		/*
+		 * XXXKW there is a window here where the intr handler may run,
+		 * see the disable, and do the wake_up before this sleep
+		 * happens.
+		 */
+		pr_debug(DEVNAME ": wait for disarm\n");
+		err = wait_event_interruptible(sbp.tb_sync, !sbp.tb_armed);
+		pr_debug(DEVNAME ": disarm complete, stat %d\n", err);
+
+		if (err)
+			return err;
+
 		sbp.tb_enable = 0;
-		/* XXXKW there is a window here where the intr handler
-		   may run, see the disable, and do the wake_up before
-		   this sleep happens. */
-		if (sbp.tb_armed) {
-			DBG(printk(DEVNAME ": wait for disarm\n"));
-			prepare_to_wait(&sbp.tb_sync, &wait, TASK_INTERRUPTIBLE);
-			schedule();
-			finish_wait(&sbp.tb_sync, &wait);
-			DBG(printk(DEVNAME ": disarm complete\n"));
-		}
 		free_irq(K_INT_TRACE_FREEZE, &sbp);
 		free_irq(K_INT_PERF_CNT, &sbp);
 	}
 
-	DBG(printk(DEVNAME ": done stopping\n"));
+	pr_debug(DEVNAME ": done stopping\n");
 
 	return 0;
 }
@@ -268,42 +373,45 @@
 	int minor;
 
 	minor = iminor(inode);
-	if (minor != 0) {
+	if (minor != 0)
 		return -ENODEV;
-	}
-	if (sbp.open) {
+
+	if (xchg(&sbp.open, SB_OPENING) != SB_CLOSED)
 		return -EBUSY;
-	}
 
 	memset(&sbp, 0, sizeof(struct sbprof_tb));
+
 	sbp.sbprof_tbbuf = vmalloc(MAX_TBSAMPLE_BYTES);
-	if (!sbp.sbprof_tbbuf) {
+	if (!sbp.sbprof_tbbuf)
 		return -ENOMEM;
-	}
+
 	memset(sbp.sbprof_tbbuf, 0, MAX_TBSAMPLE_BYTES);
 	init_waitqueue_head(&sbp.tb_sync);
 	init_waitqueue_head(&sbp.tb_read);
-	sbp.open = 1;
+	mutex_init(&sbp.lock);
+
+	sbp.open = SB_OPEN;
 
 	return 0;
 }
 
 static int sbprof_tb_release(struct inode *inode, struct file *filp)
 {
-	int minor;
+	int minor = iminor(inode);
 
-	minor = iminor(inode);
-	if (minor != 0 || !sbp.open) {
+	if (minor != 0 || !sbp.open)
 		return -ENODEV;
-	}
 
-	if (sbp.tb_armed || sbp.tb_enable) {
+	mutex_lock(&sbp.lock);
+
+	if (sbp.tb_armed || sbp.tb_enable)
 		sbprof_zbprof_stop();
-	}
 
 	vfree(sbp.sbprof_tbbuf);
 	sbp.open = 0;
 
+	mutex_unlock(&sbp.lock);
+
 	return 0;
 }
 
@@ -311,21 +419,35 @@
 			      size_t size, loff_t *offp)
 {
 	int cur_sample, sample_off, cur_count, sample_left;
-	char *src;
-	int   count   =	 0;
-	char *dest    =	 buf;
 	long  cur_off = *offp;
+	char *dest    =	 buf;
+	int   count   =	 0;
+	char *src;
+
+	if (!access_ok(VERIFY_WRITE, buf, size))
+		return -EFAULT;
+
+	mutex_lock(&sbp.lock);
 
 	count = 0;
 	cur_sample = cur_off / TB_SAMPLE_SIZE;
 	sample_off = cur_off % TB_SAMPLE_SIZE;
 	sample_left = TB_SAMPLE_SIZE - sample_off;
+
 	while (size && (cur_sample < sbp.next_tb_sample)) {
+		int err;
+
 		cur_count = size < sample_left ? size : sample_left;
 		src = (char *)(((long)sbp.sbprof_tbbuf[cur_sample])+sample_off);
-		copy_to_user(dest, src, cur_count);
-		DBG(printk(DEVNAME ": read from sample %d, %d bytes\n",
-			   cur_sample, cur_count));
+		err = __copy_to_user(dest, src, cur_count);
+		if (err) {
+			*offp = cur_off + cur_count - err;
+			mutex_unlock(&sbp.lock);
+			return err;
+		}
+
+		pr_debug(DEVNAME ": read from sample %d, %d bytes\n",
+		         cur_sample, cur_count);
 		size -= cur_count;
 		sample_left -= cur_count;
 		if (!sample_left) {
@@ -339,37 +461,43 @@
 		dest += cur_count;
 		count += cur_count;
 	}
+
 	*offp = cur_off;
+	mutex_unlock(&sbp.lock);
 
 	return count;
 }
 
-static long sbprof_tb_ioctl(struct file *filp,
-			    unsigned int command,
-			    unsigned long arg)
+static long sbprof_tb_ioctl(struct file *filp, unsigned int command,
+	unsigned long arg)
 {
 	int error = 0;
 
-	lock_kernel();
 	switch (command) {
 	case SBPROF_ZBSTART:
+		mutex_lock(&sbp.lock);
 		error = sbprof_zbprof_start(filp);
+		mutex_unlock(&sbp.lock);
 		break;
+
 	case SBPROF_ZBSTOP:
+		mutex_lock(&sbp.lock);
 		error = sbprof_zbprof_stop();
+		mutex_unlock(&sbp.lock);
 		break;
+
 	case SBPROF_ZBWAITFULL:
-		DEFINE_WAIT(wait);
-		prepare_to_wait(&sbp.tb_read, &wait, TASK_INTERRUPTIBLE);
-		schedule();
-		finish_wait(&sbp.tb_read, &wait);
-		/* XXXKW check if interrupted? */
-		return put_user(TB_FULL, (int *) arg);
+		error = wait_event_interruptible(sbp.tb_read, TB_FULL);
+		if (error)
+			break;
+
+		error = put_user(TB_FULL, (int *) arg);
+		break;
+
 	default:
 		error = -EINVAL;
 		break;
 	}
-	unlock_kernel();
 
 	return error;
 }
@@ -384,23 +512,60 @@
 	.mmap		= NULL,
 };
 
+static struct class *tb_class;
+static struct device *tb_dev;
+
 static int __init sbprof_tb_init(void)
 {
+	struct device *dev;
+	struct class *tbc;
+	int err;
+
 	if (register_chrdev(SBPROF_TB_MAJOR, DEVNAME, &sbprof_tb_fops)) {
 		printk(KERN_WARNING DEVNAME ": initialization failed (dev %d)\n",
 		       SBPROF_TB_MAJOR);
 		return -EIO;
 	}
+
+	tbc = class_create(THIS_MODULE, "sb_tracebuffer");
+	if (IS_ERR(tbc)) {
+		err = PTR_ERR(tbc);
+		goto out_chrdev;
+	}
+
+	tb_class = tbc;
+
+	dev = device_create(tbc, NULL, MKDEV(SBPROF_TB_MAJOR, 0), "tb");
+	if (IS_ERR(dev)) {
+		err = PTR_ERR(dev);
+		goto out_class;
+	}
+	tb_dev = dev;
+
 	sbp.open = 0;
 	tb_period = zbbus_mhz * 10000LL;
-	printk(KERN_INFO DEVNAME ": initialized - tb_period = %lld\n", tb_period);
+	pr_info(DEVNAME ": initialized - tb_period = %lld\n", tb_period);
+
 	return 0;
+
+out_class:
+	class_destroy(tb_class);
+out_chrdev:
+	unregister_chrdev(SBPROF_TB_MAJOR, DEVNAME);
+
+	return err;
 }
 
 static void __exit sbprof_tb_cleanup(void)
 {
+	device_destroy(tb_class, MKDEV(SBPROF_TB_MAJOR, 0));
 	unregister_chrdev(SBPROF_TB_MAJOR, DEVNAME);
+	class_destroy(tb_class);
 }
 
 module_init(sbprof_tb_init);
 module_exit(sbprof_tb_cleanup);
+
+MODULE_ALIAS_CHARDEV_MAJOR(SBPROF_TB_MAJOR);
+MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
index 1482394..0e6a13c 100644
--- a/arch/mips/sibyte/sb1250/irq.c
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -421,7 +421,7 @@
 	 * blasting the high 32 bits.
 	 */
 
-	pending = read_c0_cause() & read_c0_status();
+	pending = read_c0_cause() & read_c0_status() & ST0_IM;
 
 #ifdef CONFIG_SIBYTE_SB1250_PROF
 	if (pending & CAUSEF_IP7) /* Cpu performance counter interrupt */
diff --git a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c
index 1cb042e..87188f0 100644
--- a/arch/mips/sibyte/sb1250/setup.c
+++ b/arch/mips/sibyte/sb1250/setup.c
@@ -16,6 +16,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/reboot.h>
 #include <linux/string.h>
@@ -32,6 +33,7 @@
 unsigned int soc_type;
 unsigned int periph_rev;
 unsigned int zbbus_mhz;
+EXPORT_SYMBOL(zbbus_mhz);
 
 static char *soc_str;
 static char *pass_str;
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
index defa1f1..83572d8 100644
--- a/arch/mips/sibyte/swarm/setup.c
+++ b/arch/mips/sibyte/swarm/setup.c
@@ -169,17 +169,19 @@
 #define LEDS_PHYS MLEDS_PHYS
 #endif
 
-#define setled(index, c) \
-  ((unsigned char *)(IOADDR(LEDS_PHYS)+0x20))[(3-(index))<<3] = (c)
 void setleds(char *str)
 {
+	void *reg;
 	int i;
+
 	for (i = 0; i < 4; i++) {
-		if (!str[i]) {
-			setled(i, ' ');
-		} else {
-			setled(i, str[i]);
-		}
+		reg = IOADDR(LEDS_PHYS) + 0x20 + ((3 - i) << 3);
+
+		if (!str[i])
+			writeb(' ', reg);
+		else
+			writeb(str[i], reg);
 	}
 }
-#endif
+
+#endif /* LEDS_PHYS */
diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c
index 39e5b4a..8e8593b 100644
--- a/arch/mips/sni/pcimt.c
+++ b/arch/mips/sni/pcimt.c
@@ -333,7 +333,7 @@
 
 static void sni_pcimt_hwint(void)
 {
-	u32 pending = (read_c0_cause() & read_c0_status());
+	u32 pending = read_c0_cause() & read_c0_status();
 
 	if (pending & C_IRQ5)
 		do_IRQ (MIPS_CPU_IRQ_BASE + 7);
diff --git a/arch/mips/sni/pcit.c b/arch/mips/sni/pcit.c
index 8d6b3d5..1dfc3f0 100644
--- a/arch/mips/sni/pcit.c
+++ b/arch/mips/sni/pcit.c
@@ -271,7 +271,7 @@
 
 static void sni_pcit_hwint(void)
 {
-	u32 pending = (read_c0_cause() & read_c0_status());
+	u32 pending = read_c0_cause() & read_c0_status();
 
 	if (pending & C_IRQ1)
 		pcit_hwint1();
@@ -285,7 +285,7 @@
 
 static void sni_pcit_hwint_cplus(void)
 {
-	u32 pending = (read_c0_cause() & read_c0_status());
+	u32 pending = read_c0_cause() & read_c0_status();
 
 	if (pending & C_IRQ0)
 		pcit_hwint0();
diff --git a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/tx4927/common/tx4927_irq.c
index e7f3e5b..3d25d01 100644
--- a/arch/mips/tx4927/common/tx4927_irq.c
+++ b/arch/mips/tx4927/common/tx4927_irq.c
@@ -416,7 +416,7 @@
 
 asmlinkage void plat_irq_dispatch(void)
 {
-	unsigned int pending = read_c0_status() & read_c0_cause();
+	unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
 
 	if (pending & STATUSF_IP7)			/* cpu timer */
 		do_IRQ(TX4927_IRQ_CPU_TIMER);
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig
index 2436731..cf7e316 100644
--- a/arch/powerpc/configs/cell_defconfig
+++ b/arch/powerpc/configs/cell_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20-rc5
-# Mon Jan 22 22:12:56 2007
+# Linux kernel version: 2.6.21-rc3
+# Fri Mar  9 23:34:53 2007
 #
 CONFIG_PPC64=y
 CONFIG_64BIT=y
@@ -61,6 +61,7 @@
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
@@ -71,6 +72,7 @@
 CONFIG_CPUSETS=y
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
@@ -133,6 +135,7 @@
 # CONFIG_PPC_PSERIES is not set
 # CONFIG_PPC_ISERIES is not set
 # CONFIG_PPC_MPC52xx is not set
+# CONFIG_PPC_MPC5200 is not set
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_MAPLE is not set
 # CONFIG_PPC_PASEMI is not set
@@ -140,8 +143,10 @@
 CONFIG_PPC_CELL_NATIVE=y
 CONFIG_PPC_IBM_CELL_BLADE=y
 CONFIG_PPC_PS3=y
+CONFIG_PPC_CELLEB=y
 CONFIG_PPC_NATIVE=y
 CONFIG_UDBG_RTAS_CONSOLE=y
+CONFIG_PPC_UDBG_BEAT=y
 # CONFIG_U3_DART is not set
 CONFIG_PPC_RTAS=y
 # CONFIG_RTAS_ERROR_LOGGING is not set
@@ -181,10 +186,13 @@
 #
 # PS3 Platform Options
 #
+# CONFIG_PS3_ADVANCED is not set
 CONFIG_PS3_HTAB_SIZE=20
 # CONFIG_PS3_DYNAMIC_DMA is not set
 CONFIG_PS3_USE_LPAR_ADDR=y
 CONFIG_PS3_VUART=y
+CONFIG_PS3_PS3AV=y
+CONFIG_PS3_SYS_MANAGER=y
 
 #
 # Kernel options
@@ -226,6 +234,7 @@
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
 CONFIG_ARCH_MEMORY_PROBE=y
 CONFIG_NODES_SPAN_OTHER_NODES=y
 CONFIG_PPC_64K_PAGES=y
@@ -239,6 +248,7 @@
 #
 # Bus options
 #
+CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_ISA_DMA=y
 # CONFIG_MPIC_WEIRD is not set
 # CONFIG_PPC_I8259 is not set
@@ -274,6 +284,7 @@
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
 # CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -340,6 +351,7 @@
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_COMMENT=m
 CONFIG_NETFILTER_XT_MATCH_DCCP=m
 CONFIG_NETFILTER_XT_MATCH_DSCP=m
@@ -376,7 +388,6 @@
 CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
 CONFIG_IP_NF_MANGLE=m
 CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_ECN=m
@@ -444,6 +455,7 @@
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
 # CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
@@ -464,6 +476,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -483,7 +496,6 @@
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=131072
 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
@@ -537,6 +549,7 @@
 # CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8213 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
@@ -547,6 +560,8 @@
 # CONFIG_BLK_DEV_SLC90E66 is not set
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
+CONFIG_BLK_DEV_IDE_CELLEB=y
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
@@ -557,7 +572,7 @@
 # SCSI device support
 #
 # CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=m
+CONFIG_SCSI=y
 # CONFIG_SCSI_TGT is not set
 # CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
@@ -565,12 +580,12 @@
 #
 # SCSI support type (disk, tape, CD-ROM)
 #
-CONFIG_BLK_DEV_SD=m
+CONFIG_BLK_DEV_SD=y
 # CONFIG_CHR_DEV_ST is not set
 # CONFIG_CHR_DEV_OSST is not set
 CONFIG_BLK_DEV_SR=m
 # CONFIG_BLK_DEV_SR_VENDOR is not set
-CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SG=y
 # CONFIG_CHR_DEV_SCH is not set
 
 #
@@ -587,7 +602,7 @@
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
+CONFIG_SCSI_SAS_ATTRS=y
 # CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
@@ -617,6 +632,7 @@
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
 # CONFIG_SCSI_QLA_ISCSI is not set
@@ -629,7 +645,60 @@
 #
 # Serial ATA (prod) and Parallel ATA (experimental) drivers
 #
-# CONFIG_ATA is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+CONFIG_SATA_PROMISE=y
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+CONFIG_PATA_PDC2027X=m
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_SCC is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -655,10 +724,12 @@
 #
 # Fusion MPT device support
 #
-# CONFIG_FUSION is not set
+CONFIG_FUSION=y
 # CONFIG_FUSION_SPI is not set
 # CONFIG_FUSION_FC is not set
-# CONFIG_FUSION_SAS is not set
+CONFIG_FUSION_SAS=y
+CONFIG_FUSION_MAX_SGE=128
+# CONFIG_FUSION_CTL is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -732,15 +803,18 @@
 # CONFIG_BNX2 is not set
 CONFIG_SPIDER_NET=y
 # CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
 #
 # CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
+# CONFIG_PASEMI_MAC is not set
 
 #
 # Token Ring devices
@@ -853,16 +927,27 @@
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_TXX9=y
+CONFIG_HAS_TXX9_SERIAL=y
+CONFIG_SERIAL_TXX9_NR_UARTS=2
+CONFIG_SERIAL_TXX9_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_UNIX98_PTYS=y
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_HVC_DRIVER=y
 CONFIG_HVC_RTAS=y
+# CONFIG_HVC_BEAT is not set
 
 #
 # IPMI
 #
-# CONFIG_IPMI_HANDLER is not set
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
 
 #
 # Watchdog Cards
@@ -874,7 +959,7 @@
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
-CONFIG_WATCHDOG_RTAS=y
+# CONFIG_WATCHDOG_RTAS is not set
 
 #
 # PCI-based Watchdog Cards
@@ -929,6 +1014,7 @@
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PASEMI is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_I2C_SIS5595 is not set
@@ -973,6 +1059,11 @@
 # CONFIG_HWMON_VID is not set
 
 #
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -986,7 +1077,7 @@
 #
 # Graphics support
 #
-CONFIG_FIRMWARE_EDID=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 # CONFIG_FB is not set
 # CONFIG_FB_IBM_GXT4500 is not set
 
@@ -995,7 +1086,6 @@
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -1006,6 +1096,7 @@
 # HID Devices
 #
 CONFIG_HID=m
+# CONFIG_HID_DEBUG is not set
 
 #
 # USB support
@@ -1020,9 +1111,7 @@
 # Miscellaneous USB options
 #
 CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_MULTITHREAD_PROBE is not set
 # CONFIG_USB_OTG is not set
 
 #
@@ -1032,9 +1121,15 @@
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=m
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_HCD_PPC_OF=y
+CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
+# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
+CONFIG_USB_OHCI_HCD_PCI=y
+CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
+CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
@@ -1088,6 +1183,7 @@
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
 
 #
 # USB Imaging devices
@@ -1125,6 +1221,7 @@
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1135,6 +1232,7 @@
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
 # CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1175,6 +1273,7 @@
 CONFIG_INFINIBAND_MTHCA_DEBUG=y
 # CONFIG_INFINIBAND_AMSO1100 is not set
 CONFIG_INFINIBAND_IPOIB=m
+# CONFIG_INFINIBAND_IPOIB_CM is not set
 CONFIG_INFINIBAND_IPOIB_DEBUG=y
 CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
 # CONFIG_INFINIBAND_SRP is not set
@@ -1203,6 +1302,10 @@
 #
 
 #
+# Auxiliary Display support
+#
+
+#
 # Virtualization
 #
 
@@ -1395,7 +1498,8 @@
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
 CONFIG_PLIST=y
-CONFIG_IOMAP_COPY=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
 
 #
 # Instrumentation Support
@@ -1414,15 +1518,16 @@
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
 CONFIG_LOG_BUF_SHIFT=15
-CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_DETECT_SOFTLOCKUP is not set
 # CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_RWSEMS is not set
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -1432,6 +1537,7 @@
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_FORCED_INLINING is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 CONFIG_DEBUGGER=y
@@ -1469,8 +1575,10 @@
 # CONFIG_CRYPTO_GF128MUL is not set
 CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
 # CONFIG_CRYPTO_LRW is not set
 CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
 # CONFIG_CRYPTO_SERPENT is not set
@@ -1484,6 +1592,7 @@
 CONFIG_CRYPTO_DEFLATE=m
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_TEST is not set
 
 #
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index d7d7602..949092d 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -465,8 +465,13 @@
 #ifdef CONFIG_PPC64
 	struct thread_info *t = current_thread_info();
 
-	if (t->flags & _TIF_ABI_PENDING)
-		t->flags ^= (_TIF_ABI_PENDING | _TIF_32BIT);
+	if (test_ti_thread_flag(t, TIF_ABI_PENDING)) {
+		clear_ti_thread_flag(t, TIF_ABI_PENDING);
+		if (test_ti_thread_flag(t, TIF_32BIT))
+			clear_ti_thread_flag(t, TIF_32BIT);
+		else
+			set_ti_thread_flag(t, TIF_32BIT);
+	}
 #endif
 
 	discard_lazy_cpu_state();
diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c
index e738f93..a963f65 100644
--- a/arch/powerpc/kernel/udbg_16550.c
+++ b/arch/powerpc/kernel/udbg_16550.c
@@ -184,7 +184,7 @@
 
 void udbg_init_pas_realmode(void)
 {
-	udbg_comport = (volatile struct NS16550 __iomem *)0xfcff03f8;
+	udbg_comport = (volatile struct NS16550 __iomem *)0xfcff03f8UL;
 
 	udbg_putc = udbg_pas_real_putc;
 	udbg_getc = NULL;
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index c0d2a69..3c7fe2c 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -685,6 +685,9 @@
 				       "non-cacheable mapping\n");
 				psize = mmu_vmalloc_psize = MMU_PAGE_4K;
 			}
+#ifdef CONFIG_SPE_BASE
+			spu_flush_all_slbs(mm);
+#endif
 		}
 		if (user_region) {
 			if (psize != get_paca()->context.user_psize) {
@@ -759,6 +762,9 @@
 				mmu_psize_defs[MMU_PAGE_4K].sllp;
 			get_paca()->context = mm->context;
 			slb_flush_and_rebolt();
+#ifdef CONFIG_SPE_BASE
+			spu_flush_all_slbs(mm);
+#endif
 		}
 	}
 	if (mm->context.user_psize == MMU_PAGE_64K)
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 8c77c79..f6ffaaa 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -24,6 +24,7 @@
 #include <asm/machdep.h>
 #include <asm/cputable.h>
 #include <asm/tlb.h>
+#include <asm/spu.h>
 
 #include <linux/sysctl.h>
 
@@ -513,6 +514,9 @@
 	if ((addr + len) > 0x100000000UL)
 		err = open_high_hpage_areas(current->mm,
 					    HTLB_AREA_MASK(addr, len));
+#ifdef CONFIG_SPE_BASE
+	spu_flush_all_slbs(current->mm);
+#endif
 	if (err) {
 		printk(KERN_DEBUG "prepare_hugepage_range(%lx, %lx)"
 		       " failed (lowmask: 0x%04hx, highmask: 0x%04hx)\n",
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index c751925..fbfff95 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -128,7 +128,7 @@
 
 	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
 
-	io_be_setbit(&intr->main_mask, 15 - l2irq);
+	io_be_setbit(&intr->main_mask, 16 - l2irq);
 }
 
 static void mpc52xx_main_unmask(unsigned int virq)
@@ -141,7 +141,7 @@
 
 	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
 
-	io_be_clrbit(&intr->main_mask, 15 - l2irq);
+	io_be_clrbit(&intr->main_mask, 16 - l2irq);
 }
 
 static struct irq_chip mpc52xx_main_irqchip = {
diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/powerpc/platforms/83xx/mpc834x_mds.c
index e5d8191..8aa9a93 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c
@@ -55,9 +55,9 @@
 	struct device_node *np = NULL;
 	int port0_is_dr = 0;
 
-	if ((np = of_find_compatible_node(np, "usb", "fsl-usb2-dr")) != NULL)
+	if ((np = of_find_compatible_node(NULL, "usb", "fsl-usb2-dr")) != NULL)
 		port0_is_dr = 1;
-	if ((np = of_find_compatible_node(np, "usb", "fsl-usb2-mph")) != NULL){
+	if ((np = of_find_compatible_node(NULL, "usb", "fsl-usb2-mph")) != NULL){
 		if (port0_is_dr) {
 			printk(KERN_WARNING
 				"There is only one USB port on PB board! \n");
@@ -103,8 +103,8 @@
 		return -1;
 
 	/*
-	 * if MDS board is plug into PIB board,
-	 * force to use the PHY on MDS board
+	 * if Processor Board is plugged into PIB board,
+	 * force to use the PHY on Processor Board
 	 */
 	bcsr5 = in_8(bcsr_regs + 5);
 	if (!(bcsr5 & BCSR5_INT_USB))
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index 124e2c5..329fcd4 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -53,6 +53,7 @@
 	bool
 	select PPC_UDBG_16550
 	select PPC_INDIRECT_PCI
+	select SERIAL_8250_SHARE_IRQ if SERIAL_8250
 	default y if MPC8540_ADS || MPC85xx_CDS || MPC8560_ADS \
 		|| MPC85xx_MDS || MPC8544_DS
 
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index c43999a..eba7a26 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -38,8 +38,61 @@
 const struct spu_management_ops *spu_management_ops;
 const struct spu_priv1_ops *spu_priv1_ops;
 
+static struct list_head spu_list[MAX_NUMNODES];
+static LIST_HEAD(spu_full_list);
+static DEFINE_MUTEX(spu_mutex);
+static spinlock_t spu_list_lock = SPIN_LOCK_UNLOCKED;
+
 EXPORT_SYMBOL_GPL(spu_priv1_ops);
 
+void spu_invalidate_slbs(struct spu *spu)
+{
+	struct spu_priv2 __iomem *priv2 = spu->priv2;
+
+	if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK)
+		out_be64(&priv2->slb_invalidate_all_W, 0UL);
+}
+EXPORT_SYMBOL_GPL(spu_invalidate_slbs);
+
+/* This is called by the MM core when a segment size is changed, to
+ * request a flush of all the SPEs using a given mm
+ */
+void spu_flush_all_slbs(struct mm_struct *mm)
+{
+	struct spu *spu;
+	unsigned long flags;
+
+	spin_lock_irqsave(&spu_list_lock, flags);
+	list_for_each_entry(spu, &spu_full_list, full_list) {
+		if (spu->mm == mm)
+			spu_invalidate_slbs(spu);
+	}
+	spin_unlock_irqrestore(&spu_list_lock, flags);
+}
+
+/* The hack below stinks... try to do something better one of
+ * these days... Does it even work properly with NR_CPUS == 1 ?
+ */
+static inline void mm_needs_global_tlbie(struct mm_struct *mm)
+{
+	int nr = (NR_CPUS > 1) ? NR_CPUS : NR_CPUS + 1;
+
+	/* Global TLBIE broadcast required with SPEs. */
+	__cpus_setall(&mm->cpu_vm_mask, nr);
+}
+
+void spu_associate_mm(struct spu *spu, struct mm_struct *mm)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&spu_list_lock, flags);
+	spu->mm = mm;
+	spin_unlock_irqrestore(&spu_list_lock, flags);
+	if (mm)
+		mm_needs_global_tlbie(mm);
+}
+EXPORT_SYMBOL_GPL(spu_associate_mm);
+
 static int __spu_trap_invalid_dma(struct spu *spu)
 {
 	pr_debug("%s\n", __FUNCTION__);
@@ -74,6 +127,7 @@
 	struct spu_priv2 __iomem *priv2 = spu->priv2;
 	struct mm_struct *mm = spu->mm;
 	u64 esid, vsid, llp;
+	int psize;
 
 	pr_debug("%s\n", __FUNCTION__);
 
@@ -90,22 +144,25 @@
 	case USER_REGION_ID:
 #ifdef CONFIG_HUGETLB_PAGE
 		if (in_hugepage_area(mm->context, ea))
-			llp = mmu_psize_defs[mmu_huge_psize].sllp;
+			psize = mmu_huge_psize;
 		else
 #endif
-			llp = mmu_psize_defs[mmu_virtual_psize].sllp;
+			psize = mm->context.user_psize;
 		vsid = (get_vsid(mm->context.id, ea) << SLB_VSID_SHIFT) |
-				SLB_VSID_USER | llp;
+				SLB_VSID_USER;
 		break;
 	case VMALLOC_REGION_ID:
-		llp = mmu_psize_defs[mmu_virtual_psize].sllp;
+		if (ea < VMALLOC_END)
+			psize = mmu_vmalloc_psize;
+		else
+			psize = mmu_io_psize;
 		vsid = (get_kernel_vsid(ea) << SLB_VSID_SHIFT) |
-			SLB_VSID_KERNEL | llp;
+			SLB_VSID_KERNEL;
 		break;
 	case KERNEL_REGION_ID:
-		llp = mmu_psize_defs[mmu_linear_psize].sllp;
+		psize = mmu_linear_psize;
 		vsid = (get_kernel_vsid(ea) << SLB_VSID_SHIFT) |
-			SLB_VSID_KERNEL | llp;
+			SLB_VSID_KERNEL;
 		break;
 	default:
 		/* Future: support kernel segments so that drivers
@@ -114,9 +171,10 @@
 		pr_debug("invalid region access at %016lx\n", ea);
 		return 1;
 	}
+	llp = mmu_psize_defs[psize].sllp;
 
 	out_be64(&priv2->slb_index_W, spu->slb_replace);
-	out_be64(&priv2->slb_vsid_RW, vsid);
+	out_be64(&priv2->slb_vsid_RW, vsid | llp);
 	out_be64(&priv2->slb_esid_RW, esid);
 
 	spu->slb_replace++;
@@ -330,10 +388,6 @@
 		free_irq(spu->irqs[2], spu);
 }
 
-static struct list_head spu_list[MAX_NUMNODES];
-static LIST_HEAD(spu_full_list);
-static DEFINE_MUTEX(spu_mutex);
-
 static void spu_init_channels(struct spu *spu)
 {
 	static const struct {
@@ -593,6 +647,7 @@
 	struct spu *spu;
 	int ret;
 	static int number;
+	unsigned long flags;
 
 	ret = -ENOMEM;
 	spu = kzalloc(sizeof (*spu), GFP_KERNEL);
@@ -620,8 +675,10 @@
 		goto out_free_irqs;
 
 	mutex_lock(&spu_mutex);
+	spin_lock_irqsave(&spu_list_lock, flags);
 	list_add(&spu->list, &spu_list[spu->node]);
 	list_add(&spu->full_list, &spu_full_list);
+	spin_unlock_irqrestore(&spu_list_lock, flags);
 	mutex_unlock(&spu_mutex);
 
 	goto out;
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index b00653d..505266a 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -63,8 +63,8 @@
 spufs_mem_read(struct file *file, char __user *buffer,
 				size_t size, loff_t *pos)
 {
-	int ret;
 	struct spu_context *ctx = file->private_data;
+	ssize_t ret;
 
 	spu_acquire(ctx);
 	ret = __spufs_mem_read(ctx, buffer, size, pos);
@@ -74,25 +74,29 @@
 
 static ssize_t
 spufs_mem_write(struct file *file, const char __user *buffer,
-					size_t size, loff_t *pos)
+					size_t size, loff_t *ppos)
 {
 	struct spu_context *ctx = file->private_data;
 	char *local_store;
+	loff_t pos = *ppos;
 	int ret;
 
-	size = min_t(ssize_t, LS_SIZE - *pos, size);
-	if (size <= 0)
+	if (pos < 0)
+		return -EINVAL;
+	if (pos > LS_SIZE)
 		return -EFBIG;
-	*pos += size;
+	if (size > LS_SIZE - pos)
+		size = LS_SIZE - pos;
 
 	spu_acquire(ctx);
-
 	local_store = ctx->ops->get_ls(ctx);
-	ret = copy_from_user(local_store + *pos - size,
-			     buffer, size) ? -EFAULT : size;
-
+	ret = copy_from_user(local_store + pos, buffer, size);
 	spu_release(ctx);
-	return ret;
+
+	if (ret)
+		return -EFAULT;
+	*ppos = pos + size;
+	return size;
 }
 
 static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct *vma,
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index 353a8fa..f95a611 100644
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -143,7 +143,7 @@
 	int ret;
 	unsigned long runcntl = SPU_RUNCNTL_RUNNABLE;
 
-	ret = spu_acquire_runnable(ctx, SPU_ACTIVATE_NOWAKE);
+	ret = spu_acquire_runnable(ctx, 0);
 	if (ret)
 		return ret;
 
@@ -155,7 +155,7 @@
 			spu_release(ctx);
 			ret = spu_setup_isolated(ctx);
 			if (!ret)
-				ret = spu_acquire_runnable(ctx, SPU_ACTIVATE_NOWAKE);
+				ret = spu_acquire_runnable(ctx, 0);
 		}
 
 		/* if userspace has set the runcntrl register (eg, to issue an
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 2f25e68..39823ce 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -127,14 +127,6 @@
 	mutex_unlock(&spu_prio->active_mutex[node]);
 }
 
-static inline void mm_needs_global_tlbie(struct mm_struct *mm)
-{
-	int nr = (NR_CPUS > 1) ? NR_CPUS : NR_CPUS + 1;
-
-	/* Global TLBIE broadcast required with SPEs. */
-	__cpus_setall(&mm->cpu_vm_mask, nr);
-}
-
 static BLOCKING_NOTIFIER_HEAD(spu_switch_notifier);
 
 static void spu_switch_notify(struct spu *spu, struct spu_context *ctx)
@@ -167,8 +159,7 @@
 	ctx->spu = spu;
 	ctx->ops = &spu_hw_ops;
 	spu->pid = current->pid;
-	spu->mm = ctx->owner;
-	mm_needs_global_tlbie(spu->mm);
+	spu_associate_mm(spu, ctx->owner);
 	spu->ibox_callback = spufs_ibox_callback;
 	spu->wbox_callback = spufs_wbox_callback;
 	spu->stop_callback = spufs_stop_callback;
@@ -205,7 +196,7 @@
 	spu->stop_callback = NULL;
 	spu->mfc_callback = NULL;
 	spu->dma_callback = NULL;
-	spu->mm = NULL;
+	spu_associate_mm(spu, NULL);
 	spu->pid = 0;
 	ctx->ops = &spu_backing_ops;
 	ctx->spu = NULL;
@@ -263,7 +254,6 @@
 {
 	DEFINE_WAIT(wait);
 
-	set_bit(SPU_SCHED_WAKE, &ctx->sched_flags);
 	prepare_to_wait_exclusive(&ctx->stop_wq, &wait, TASK_INTERRUPTIBLE);
 	if (!signal_pending(current)) {
 		mutex_unlock(&ctx->state_mutex);
@@ -272,7 +262,6 @@
 	}
 	__set_current_state(TASK_RUNNING);
 	remove_wait_queue(&ctx->stop_wq, &wait);
-	clear_bit(SPU_SCHED_WAKE, &ctx->sched_flags);
 }
 
 /**
@@ -292,7 +281,7 @@
 	best = sched_find_first_bit(spu_prio->bitmap);
 	if (best < MAX_PRIO) {
 		struct spu_context *ctx = spu_grab_context(best);
-		if (ctx && test_bit(SPU_SCHED_WAKE, &ctx->sched_flags))
+		if (ctx)
 			wake_up(&ctx->stop_wq);
 	}
 	spin_unlock(&spu_prio->runq_lock);
@@ -414,8 +403,7 @@
 		}
 
 		spu_add_to_rq(ctx);
-		if (!(flags & SPU_ACTIVATE_NOWAKE))
-			spu_prio_wait(ctx);
+		spu_prio_wait(ctx);
 		spu_del_from_rq(ctx);
 	} while (!signal_pending(current));
 
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index 0c43789..5c4e47d 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -41,7 +41,7 @@
 
 /* ctx->sched_flags */
 enum {
-	SPU_SCHED_WAKE = 0,
+	SPU_SCHED_WAKE = 0, /* currently unused */
 };
 
 struct spu_context {
@@ -191,9 +191,7 @@
 int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags);
 void spu_acquire_saved(struct spu_context *ctx);
 int spu_acquire_exclusive(struct spu_context *ctx);
-enum {
-	SPU_ACTIVATE_NOWAKE = 1,
-};
+
 int spu_activate(struct spu_context *ctx, unsigned long flags);
 void spu_deactivate(struct spu_context *ctx);
 void spu_yield(struct spu_context *ctx);
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index c08981f..fd91c73 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -468,26 +468,6 @@
 			 MFC_CNTL_PURGE_DMA_COMPLETE);
 }
 
-static inline void save_mfc_slbs(struct spu_state *csa, struct spu *spu)
-{
-	struct spu_priv2 __iomem *priv2 = spu->priv2;
-	int i;
-
-	/* Save, Step 29:
-	 *     If MFC_SR1[R]='1', save SLBs in CSA.
-	 */
-	if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK) {
-		csa->priv2.slb_index_W = in_be64(&priv2->slb_index_W);
-		for (i = 0; i < 8; i++) {
-			out_be64(&priv2->slb_index_W, i);
-			eieio();
-			csa->slb_esid_RW[i] = in_be64(&priv2->slb_esid_RW);
-			csa->slb_vsid_RW[i] = in_be64(&priv2->slb_vsid_RW);
-			eieio();
-		}
-	}
-}
-
 static inline void setup_mfc_sr1(struct spu_state *csa, struct spu *spu)
 {
 	/* Save, Step 30:
@@ -708,20 +688,6 @@
 	out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESUME_DMA_QUEUE);
 }
 
-static inline void invalidate_slbs(struct spu_state *csa, struct spu *spu)
-{
-	struct spu_priv2 __iomem *priv2 = spu->priv2;
-
-	/* Save, Step 45:
-	 * Restore, Step 19:
-	 *     If MFC_SR1[R]=1, write 0 to SLB_Invalidate_All.
-	 */
-	if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK) {
-		out_be64(&priv2->slb_invalidate_all_W, 0UL);
-		eieio();
-	}
-}
-
 static inline void get_kernel_slb(u64 ea, u64 slb[2])
 {
 	u64 llp;
@@ -765,7 +731,7 @@
 	 *     MFC_SR1[R]=1 (in other words, assume that
 	 *     translation is desired by OS environment).
 	 */
-	invalidate_slbs(csa, spu);
+	spu_invalidate_slbs(spu);
 	get_kernel_slb((unsigned long)&spu_save_code[0], code_slb);
 	get_kernel_slb((unsigned long)csa->lscsa, lscsa_slb);
 	load_mfc_slb(spu, code_slb, 0);
@@ -1718,27 +1684,6 @@
 	}
 }
 
-static inline void restore_mfc_slbs(struct spu_state *csa, struct spu *spu)
-{
-	struct spu_priv2 __iomem *priv2 = spu->priv2;
-	int i;
-
-	/* Restore, Step 68:
-	 *     If MFC_SR1[R]='1', restore SLBs from CSA.
-	 */
-	if (csa->priv1.mfc_sr1_RW & MFC_STATE1_RELOCATE_MASK) {
-		for (i = 0; i < 8; i++) {
-			out_be64(&priv2->slb_index_W, i);
-			eieio();
-			out_be64(&priv2->slb_esid_RW, csa->slb_esid_RW[i]);
-			out_be64(&priv2->slb_vsid_RW, csa->slb_vsid_RW[i]);
-			eieio();
-		}
-		out_be64(&priv2->slb_index_W, csa->priv2.slb_index_W);
-		eieio();
-	}
-}
-
 static inline void restore_mfc_sr1(struct spu_state *csa, struct spu *spu)
 {
 	/* Restore, Step 69:
@@ -1875,7 +1820,6 @@
 	set_mfc_tclass_id(prev, spu);	/* Step 26. */
 	purge_mfc_queue(prev, spu);	/* Step 27. */
 	wait_purge_complete(prev, spu);	/* Step 28. */
-	save_mfc_slbs(prev, spu);	/* Step 29. */
 	setup_mfc_sr1(prev, spu);	/* Step 30. */
 	save_spu_npc(prev, spu);	/* Step 31. */
 	save_spu_privcntl(prev, spu);	/* Step 32. */
@@ -1987,7 +1931,7 @@
 	reset_spu_privcntl(prev, spu);	        /* Step 16. */
 	reset_spu_lslr(prev, spu);              /* Step 17. */
 	setup_mfc_sr1(prev, spu);	        /* Step 18. */
-	invalidate_slbs(prev, spu);	        /* Step 19. */
+	spu_invalidate_slbs(spu);        	/* Step 19. */
 	reset_ch_part1(prev, spu);	        /* Step 20. */
 	reset_ch_part2(prev, spu);	        /* Step 21. */
 	enable_interrupts(prev, spu);	        /* Step 22. */
@@ -2055,7 +1999,7 @@
 	restore_spu_mb(next, spu);	        /* Step 65. */
 	check_ppu_mb_stat(next, spu);	        /* Step 66. */
 	check_ppuint_mb_stat(next, spu);	/* Step 67. */
-	restore_mfc_slbs(next, spu);	        /* Step 68. */
+	spu_invalidate_slbs(spu);		/* Modified Step 68. */
 	restore_mfc_sr1(next, spu);	        /* Step 69. */
 	restore_other_spu_access(next, spu);	/* Step 70. */
 	restore_spu_runcntl(next, spu);	        /* Step 71. */
diff --git a/arch/powerpc/platforms/pasemi/iommu.c b/arch/powerpc/platforms/pasemi/iommu.c
index 4587c1d..07819cd 100644
--- a/arch/powerpc/platforms/pasemi/iommu.c
+++ b/arch/powerpc/platforms/pasemi/iommu.c
@@ -77,7 +77,7 @@
 #define IOBMAP_L2E_V		0x80000000
 #define IOBMAP_L2E_V_CACHED	0xc0000000
 
-static u32 *iob;
+static u32 __iomem *iob;
 static u32 iob_l1_emptyval;
 static u32 iob_l2_emptyval;
 static u32 *iob_l2_base;
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S
index 5c7e387..c1427b3 100644
--- a/arch/powerpc/platforms/pseries/hvCall.S
+++ b/arch/powerpc/platforms/pseries/hvCall.S
@@ -30,9 +30,14 @@
 	
 /*
  * postcall is performed immediately before function return which
- * allows liberal use of volatile registers.
+ * allows liberal use of volatile registers.  We branch around this
+ * in early init (eg when populating the MMU hashtable) by using an
+ * unconditional cpu feature.
  */
 #define HCALL_INST_POSTCALL					\
+BEGIN_FTR_SECTION;						\
+	b	1f;						\
+END_FTR_SECTION(0, 1);						\
 	ld	r4,STK_PARM(r3)(r1);	/* validate opcode */	\
 	cmpldi	cr7,r4,MAX_HCALL_OPCODE;			\
 	bgt-	cr7,1f;						\
@@ -123,6 +128,40 @@
 
 	blr				/* return r3 = status */
 
+/*
+ * plpar_hcall_raw can be called in real mode. kexec/kdump need some
+ * hypervisor calls to be executed in real mode. So plpar_hcall_raw
+ * does not access the per cpu hypervisor call statistics variables,
+ * since these variables may not be present in the RMO region.
+ */
+_GLOBAL(plpar_hcall_raw)
+	HMT_MEDIUM
+
+	mfcr	r0
+	stw	r0,8(r1)
+
+	std     r4,STK_PARM(r4)(r1)     /* Save ret buffer */
+
+	mr	r4,r5
+	mr	r5,r6
+	mr	r6,r7
+	mr	r7,r8
+	mr	r8,r9
+	mr	r9,r10
+
+	HVSC				/* invoke the hypervisor */
+
+	ld	r12,STK_PARM(r4)(r1)
+	std	r4,  0(r12)
+	std	r5,  8(r12)
+	std	r6, 16(r12)
+	std	r7, 24(r12)
+
+	lwz	r0,8(r1)
+	mtcrf	0xff,r0
+
+	blr				/* return r3 = status */
+
 _GLOBAL(plpar_hcall9)
 	HMT_MEDIUM
 
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 7496005..843ee96 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -378,7 +378,7 @@
 
 	/* TODO: Use bulk call */
 	for (i = 0; i < hpte_count; i++)
-		plpar_pte_remove(0, i, 0, &dummy1, &dummy2);
+		plpar_pte_remove_raw(0, i, 0, &dummy1, &dummy2);
 }
 
 /*
diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h
index 3eb7b29..2e4d10c 100644
--- a/arch/powerpc/platforms/pseries/plpar_wrappers.h
+++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h
@@ -78,6 +78,22 @@
 	return rc;
 }
 
+/* plpar_pte_remove_raw can be called in real mode. It calls plpar_hcall_raw */
+static inline long plpar_pte_remove_raw(unsigned long flags, unsigned long ptex,
+		unsigned long avpn, unsigned long *old_pteh_ret,
+		unsigned long *old_ptel_ret)
+{
+	long rc;
+	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+
+	rc = plpar_hcall_raw(H_REMOVE, retbuf, flags, ptex, avpn);
+
+	*old_pteh_ret = retbuf[0];
+	*old_ptel_ret = retbuf[1];
+
+	return rc;
+}
+
 static inline long plpar_pte_read(unsigned long flags, unsigned long ptex,
 		unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
 {
diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c
index dffeeae..1fc5819 100644
--- a/arch/powerpc/sysdev/dcr.c
+++ b/arch/powerpc/sysdev/dcr.c
@@ -129,7 +129,7 @@
 
 	if (h.token == NULL)
 		return;
-	h.token -= dcr_n * h.stride;
+	h.token += dcr_n * h.stride;
 	iounmap(h.token);
 	h.token = NULL;
 }
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index e3d71e0..43f6cc9 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -251,13 +251,13 @@
 
 	/* allocate 2 internal temporary buffers (512 bytes size each) for
 	 * the SDMA */
-	sdma_buf_offset = qe_muram_alloc(512 * 2, 64);
+ 	sdma_buf_offset = qe_muram_alloc(512 * 2, 4096);
 	if (IS_MURAM_ERR(sdma_buf_offset))
 		return -ENOMEM;
 
 	out_be32(&sdma->sdebcr, sdma_buf_offset & QE_SDEBCR_BA_MASK);
-	out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK | (0x1 >>
-					QE_SDMR_CEN_SHIFT)));
+ 	out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK |
+ 					(0x1 << QE_SDMR_CEN_SHIFT)));
 
 	return 0;
 }
diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c
index 4ca6157..697eb30 100644
--- a/arch/s390/appldata/appldata_mem.c
+++ b/arch/s390/appldata/appldata_mem.c
@@ -117,7 +117,10 @@
 	mem_data->pgpgout    = ev[PGPGOUT] >> 1;
 	mem_data->pswpin     = ev[PSWPIN];
 	mem_data->pswpout    = ev[PSWPOUT];
-	mem_data->pgalloc    = ev[PGALLOC_NORMAL] + ev[PGALLOC_DMA];
+	mem_data->pgalloc    = ev[PGALLOC_NORMAL];
+#ifdef CONFIG_ZONE_DMA
+	mem_data->pgalloc    += ev[PGALLOC_DMA];
+#endif
 	mem_data->pgfault    = ev[PGFAULT];
 	mem_data->pgmajfault = ev[PGMAJFAULT];
 
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 9790129..32a69a1 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -1665,3 +1665,20 @@
 	llgtr	%r3,%r3			# unsigned *
 	llgtr	%r4,%r4			# struct getcpu_cache *
 	jg	sys_getcpu
+
+	.globl	compat_sys_epoll_pwait_wrapper
+compat_sys_epoll_pwait_wrapper:
+	lgfr	%r2,%r2			# int
+	llgtr	%r3,%r3			# struct compat_epoll_event *
+	lgfr	%r4,%r4			# int
+	lgfr	%r5,%r5			# int
+	llgtr	%r6,%r6			# compat_sigset_t *
+	llgf	%r0,164(%r15)		# compat_size_t
+	stg	%r0,160(%r15)
+	jg	compat_sys_epoll_pwait
+
+	.globl	compat_sys_utimes_wrapper
+compat_sys_utimes_wrapper:
+	llgtr	%r2,%r2			# char *
+	llgtr	%r3,%r3			# struct compat_timeval *
+	jg	compat_sys_utimes
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index eca3fe5..dca6eaf 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -268,7 +268,7 @@
 	rc->level          = level;
 	rc->buf_size       = buf_size;
 	rc->entry_size     = sizeof(debug_entry_t) + buf_size;
-	strlcpy(rc->name, name, sizeof(rc->name)-1);
+	strlcpy(rc->name, name, sizeof(rc->name));
 	memset(rc->views, 0, DEBUG_MAX_VIEWS * sizeof(struct debug_view *));
 	memset(rc->debugfs_entries, 0 ,DEBUG_MAX_VIEWS *
 		sizeof(struct dentry*));
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index afca1c6..5e47936 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -141,9 +141,9 @@
 		machine_flags |= 4;
 }
 
+#ifdef CONFIG_64BIT
 static noinline __init int memory_fast_detect(void)
 {
-
 	unsigned long val0 = 0;
 	unsigned long val1 = 0xc;
 	int ret = -ENOSYS;
@@ -161,9 +161,15 @@
 	if (ret || val0 != val1)
 		return -ENOSYS;
 
-	memory_chunk[0].size = val0;
+	memory_chunk[0].size = val0 + 1;
 	return 0;
 }
+#else
+static inline int memory_fast_detect(void)
+{
+	return -ENOSYS;
+}
+#endif
 
 #define ADDR2G	(1UL << 31)
 
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index d125a4e..f731185 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -839,7 +839,7 @@
 	}
 	reipl_block_ccw->hdr.len = IPL_PARM_BLK_CCW_LEN;
 	reipl_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION;
-	reipl_block_ccw->hdr.blk0_len = sizeof(reipl_block_ccw->ipl_info.ccw);
+	reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN;
 	reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
 	/* check if read scp info worked and set loadparm */
 	if (SCCB_VALID)
@@ -880,8 +880,7 @@
 	} else {
 		reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN;
 		reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
-		reipl_block_fcp->hdr.blk0_len =
-			sizeof(reipl_block_fcp->ipl_info.fcp);
+		reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN;
 		reipl_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP;
 		reipl_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_IPL;
 	}
@@ -930,7 +929,7 @@
 	}
 	dump_block_ccw->hdr.len = IPL_PARM_BLK_CCW_LEN;
 	dump_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION;
-	dump_block_ccw->hdr.blk0_len = sizeof(reipl_block_ccw->ipl_info.ccw);
+	dump_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN;
 	dump_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
 	dump_capabilities |= IPL_TYPE_CCW;
 	return 0;
@@ -954,7 +953,7 @@
 	}
 	dump_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN;
 	dump_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
-	dump_block_fcp->hdr.blk0_len = sizeof(dump_block_fcp->ipl_info.fcp);
+	dump_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN;
 	dump_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP;
 	dump_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_DUMP;
 	dump_capabilities |= IPL_TYPE_FCP;
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index 8af549e..993f353 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -167,7 +167,7 @@
 	 * shall not cross any page boundaries (vmalloc area!) when writing
 	 * the new instruction.
 	 */
-	addr = (u32 *)ALIGN((unsigned long)args->ptr, 4);
+	addr = (u32 *)((unsigned long)args->ptr & -4UL);
 	if ((unsigned long)args->ptr & 2)
 		instr = ((*addr) & 0xffff0000) | args->new;
 	else
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index a52c444..c774f10 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -320,4 +320,5 @@
 SYSCALL(sys_vmsplice,sys_vmsplice,compat_sys_vmsplice_wrapper)
 NI_SYSCALL							/* 310 sys_move_pages */
 SYSCALL(sys_getcpu,sys_getcpu,sys_getcpu_wrapper)
-SYSCALL(sys_epoll_pwait,sys_epoll_pwait,sys_ni_syscall)
+SYSCALL(sys_epoll_pwait,sys_epoll_pwait,compat_sys_epoll_pwait_wrapper)
+SYSCALL(sys_utimes,sys_utimes,compat_sys_utimes_wrapper)
diff --git a/arch/sh/boards/renesas/r7780rp/Makefile b/arch/sh/boards/renesas/r7780rp/Makefile
index 3c93012..ed5f5a9 100644
--- a/arch/sh/boards/renesas/r7780rp/Makefile
+++ b/arch/sh/boards/renesas/r7780rp/Makefile
@@ -2,6 +2,6 @@
 # Makefile for the R7780RP-1 specific parts of the kernel
 #
 
-obj-y	 := setup.o io.o irq.o
+obj-y	 := setup.o irq.o
 
 obj-$(CONFIG_PUSH_SWITCH)	+= psw.o
diff --git a/arch/sh/boards/renesas/r7780rp/io.c b/arch/sh/boards/renesas/r7780rp/io.c
deleted file mode 100644
index f74d2ff..0000000
--- a/arch/sh/boards/renesas/r7780rp/io.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (C) 2001  Ian da Silva, Jeremy Siegel
- * Based largely on io_se.c.
- *
- * I/O routine for Renesas Solutions Highlander R7780RP-1
- *
- * Initial version only to support LAN access; some
- * placeholder code from io_r7780rp.c left in with the
- * expectation of later SuperIO and PCMCIA access.
- */
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/io.h>
-#include <asm/r7780rp.h>
-#include <asm/addrspace.h>
-
-static inline unsigned long port88796l(unsigned int port, int flag)
-{
-	unsigned long addr;
-
-	if (flag)
-		addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1);
-	else
-		addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1) + 0x1000;
-
-	return addr;
-}
-
-#if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE)
-#define CHECK_AX88796L_PORT(port) \
-  ((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20)))
-#else
-#define CHECK_AX88796L_PORT(port) (0)
-#endif
-
-/*
- * General outline: remap really low stuff [eventually] to SuperIO,
- * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
- * is mapped through the PCI IO window.  Stuff with high bits (PXSEG)
- * should be way beyond the window, and is used  w/o translation for
- * compatibility.
- */
-u8 r7780rp_inb(unsigned long port)
-{
-	if (CHECK_AX88796L_PORT(port))
-		return ctrl_inw(port88796l(port, 0)) & 0xff;
-	else if (is_pci_ioaddr(port))
-		return ctrl_inb(pci_ioaddr(port));
-
-	return ctrl_inw(port) & 0xff;
-}
-
-u8 r7780rp_inb_p(unsigned long port)
-{
-	u8 v;
-
-	if (CHECK_AX88796L_PORT(port))
-		v = ctrl_inw(port88796l(port, 0)) & 0xff;
-	else if (is_pci_ioaddr(port))
-		v = ctrl_inb(pci_ioaddr(port));
-	else
-		v = ctrl_inw(port) & 0xff;
-
-	ctrl_delay();
-
-	return v;
-}
-
-u16 r7780rp_inw(unsigned long port)
-{
-	if (is_pci_ioaddr(port))
-		return ctrl_inw(pci_ioaddr(port));
-
-	return ctrl_inw(port);
-}
-
-u32 r7780rp_inl(unsigned long port)
-{
-	if (is_pci_ioaddr(port))
-		return ctrl_inl(pci_ioaddr(port));
-
-	return ctrl_inl(port);
-}
-
-void r7780rp_outb(u8 value, unsigned long port)
-{
-	if (CHECK_AX88796L_PORT(port))
-		ctrl_outw(value, port88796l(port, 0));
-	else if (is_pci_ioaddr(port))
-		ctrl_outb(value, pci_ioaddr(port));
-	else
-		ctrl_outb(value, port);
-}
-
-void r7780rp_outb_p(u8 value, unsigned long port)
-{
-	if (CHECK_AX88796L_PORT(port))
-		ctrl_outw(value, port88796l(port, 0));
-	else if (is_pci_ioaddr(port))
-		ctrl_outb(value, pci_ioaddr(port));
-	else
-		ctrl_outb(value, port);
-
-	ctrl_delay();
-}
-
-void r7780rp_outw(u16 value, unsigned long port)
-{
-	if (is_pci_ioaddr(port))
-		ctrl_outw(value, pci_ioaddr(port));
-	else
-		ctrl_outw(value, port);
-}
-
-void r7780rp_outl(u32 value, unsigned long port)
-{
-	if (is_pci_ioaddr(port))
-		ctrl_outl(value, pci_ioaddr(port));
-	else
-		ctrl_outl(value, port);
-}
-
-void r7780rp_insb(unsigned long port, void *dst, unsigned long count)
-{
-	volatile u16 *p;
-	u8 *buf = dst;
-
-	if (CHECK_AX88796L_PORT(port)) {
-		p = (volatile u16 *)port88796l(port, 0);
-		while (count--)
-			*buf++ = *p & 0xff;
-	} else if (is_pci_ioaddr(port)) {
-		volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
-
-		while (count--)
-			*buf++ = *bp;
-	} else {
-		p = (volatile u16 *)port;
-		while (count--)
-			*buf++ = *p & 0xff;
-	}
-}
-
-void r7780rp_insw(unsigned long port, void *dst, unsigned long count)
-{
-	volatile u16 *p;
-	u16 *buf = dst;
-
-	if (CHECK_AX88796L_PORT(port))
-		p = (volatile u16 *)port88796l(port, 1);
-	else if (is_pci_ioaddr(port))
-		p = (volatile u16 *)pci_ioaddr(port);
-	else
-		p = (volatile u16 *)port;
-
-	while (count--)
-		*buf++ = *p;
-
-	flush_dcache_all();
-}
-
-void r7780rp_insl(unsigned long port, void *dst, unsigned long count)
-{
-	if (is_pci_ioaddr(port)) {
-		volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
-		u32 *buf = dst;
-
-		while (count--)
-			*buf++ = *p;
-	}
-}
-
-void r7780rp_outsb(unsigned long port, const void *src, unsigned long count)
-{
-	volatile u16 *p;
-	const u8 *buf = src;
-
-	if (CHECK_AX88796L_PORT(port)) {
-		p = (volatile u16 *)port88796l(port, 0);
-		while (count--)
-			*p = *buf++;
-	} else if (is_pci_ioaddr(port)) {
-		volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
-
-		while (count--)
-			*bp = *buf++;
-	} else
-		while (count--)
-			ctrl_outb(*buf++, port);
-}
-
-void r7780rp_outsw(unsigned long port, const void *src, unsigned long count)
-{
-	volatile u16 *p;
-	const u16 *buf = src;
-
-	if (CHECK_AX88796L_PORT(port))
-		p = (volatile u16 *)port88796l(port, 1);
-	else if (is_pci_ioaddr(port))
-		p = (volatile u16 *)pci_ioaddr(port);
-	else
-		p = (volatile u16 *)port;
-
-	while (count--)
-		*p = *buf++;
-
-	flush_dcache_all();
-}
-
-void r7780rp_outsl(unsigned long port, const void *src, unsigned long count)
-{
-	const u32 *buf = src;
-	u32 *p;
-
-	if (is_pci_ioaddr(port))
-		p = (u32 *)pci_ioaddr(port);
-	else
-		p = (u32 *)port;
-
-	while (count--)
-		ctrl_outl(*buf++, (unsigned long)p);
-}
-
-void __iomem *r7780rp_ioport_map(unsigned long port, unsigned int size)
-{
-	if (CHECK_AX88796L_PORT(port))
-		return (void __iomem *)port88796l(port, size > 1);
-	else if (is_pci_ioaddr(port))
-		return (void __iomem *)pci_ioaddr(port);
-
-	return (void __iomem *)port;
-}
diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c
index 0d74db9..2faba66 100644
--- a/arch/sh/boards/renesas/r7780rp/setup.c
+++ b/arch/sh/boards/renesas/r7780rp/setup.c
@@ -187,31 +187,7 @@
 struct sh_machine_vector mv_r7780rp __initmv = {
 	.mv_name		= "Highlander R7780RP-1",
 	.mv_setup		= r7780rp_setup,
-
 	.mv_nr_irqs		= 109,
-
-	.mv_inb			= r7780rp_inb,
-	.mv_inw			= r7780rp_inw,
-	.mv_inl			= r7780rp_inl,
-	.mv_outb		= r7780rp_outb,
-	.mv_outw		= r7780rp_outw,
-	.mv_outl		= r7780rp_outl,
-
-	.mv_inb_p		= r7780rp_inb_p,
-	.mv_inw_p		= r7780rp_inw,
-	.mv_inl_p		= r7780rp_inl,
-	.mv_outb_p		= r7780rp_outb_p,
-	.mv_outw_p		= r7780rp_outw,
-	.mv_outl_p		= r7780rp_outl,
-
-	.mv_insb		= r7780rp_insb,
-	.mv_insw		= r7780rp_insw,
-	.mv_insl		= r7780rp_insl,
-	.mv_outsb		= r7780rp_outsb,
-	.mv_outsw		= r7780rp_outsw,
-	.mv_outsl		= r7780rp_outsl,
-
-	.mv_ioport_map		= r7780rp_ioport_map,
 	.mv_init_irq		= init_r7780rp_IRQ,
 };
 ALIAS_MV(r7780rp)
diff --git a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c
index 44b4208..593f26a 100644
--- a/arch/sh/boards/renesas/rts7751r2d/setup.c
+++ b/arch/sh/boards/renesas/rts7751r2d/setup.c
@@ -12,6 +12,7 @@
 #include <linux/platform_device.h>
 #include <linux/pata_platform.h>
 #include <linux/serial_8250.h>
+#include <linux/sm501.h>
 #include <linux/pm.h>
 #include <asm/machvec.h>
 #include <asm/rts7751r2d.h>
@@ -111,10 +112,35 @@
 	.resource	= heartbeat_resources,
 };
 
+static struct resource sm501_resources[] = {
+	[0]	= {
+		.start	= 0x10000000,
+		.end	= 0x13e00000 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1]	= {
+		.start	= 0x13e00000,
+		.end	= 0x13ffffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[2]	= {
+		.start	= 32,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device sm501_device = {
+	.name		= "sm501",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(sm501_resources),
+	.resource	= sm501_resources,
+};
+
 static struct platform_device *rts7751r2d_devices[] __initdata = {
 	&uart_device,
 	&heartbeat_device,
 	&cf_ide_device,
+	&sm501_device,
 };
 
 static int __init rts7751r2d_devices_setup(void)
diff --git a/arch/sh/configs/rts7751r2d_defconfig b/arch/sh/configs/rts7751r2d_defconfig
index db6a02d..a59bb78 100644
--- a/arch/sh/configs/rts7751r2d_defconfig
+++ b/arch/sh/configs/rts7751r2d_defconfig
@@ -1,14 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Thu Feb 15 17:17:29 2007
+# Linux kernel version: 2.6.21-rc1
+# Thu Mar  1 16:42:40 2007
 #
 CONFIG_SUPERH=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 # CONFIG_GENERIC_TIME is not set
@@ -33,6 +32,7 @@
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
@@ -119,7 +119,6 @@
 # CONFIG_SH_SHMIN is not set
 # CONFIG_SH_7206_SOLUTION_ENGINE is not set
 # CONFIG_SH_7619_SOLUTION_ENGINE is not set
-# CONFIG_SH_ASDAP310 is not set
 # CONFIG_SH_UNKNOWN is not set
 
 #
@@ -281,7 +280,7 @@
 CONFIG_BOOT_LINK_OFFSET=0x00800000
 # CONFIG_UBC_WAKEUP is not set
 CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1"
+CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1"
 
 #
 # Bus options
@@ -433,6 +432,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -770,7 +770,26 @@
 #
 # Input device support
 #
-# CONFIG_INPUT is not set
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
 
 #
 # Hardware I/O ports
@@ -781,7 +800,10 @@
 #
 # Character devices
 #
-# CONFIG_VT is not set
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -857,6 +879,11 @@
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
+# Multifunction device drivers
+#
+CONFIG_MFD_SM501=y
+
+#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -869,9 +896,66 @@
 #
 # Graphics support
 #
-CONFIG_FIRMWARE_EDID=y
-# CONFIG_FB is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frambuffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_EPSON1355 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+CONFIG_FB_SM501=y
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+# CONFIG_LOGO_SUPERH_MONO is not set
+# CONFIG_LOGO_SUPERH_VGA16 is not set
+CONFIG_LOGO_SUPERH_CLUT224=y
 
 #
 # Sound
@@ -985,6 +1069,12 @@
 CONFIG_AC97_BUS=m
 
 #
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
 # USB support
 #
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -1237,7 +1327,7 @@
 CONFIG_EARLY_SCIF_CONSOLE=y
 CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000
 CONFIG_EARLY_PRINTK=y
-# CONFIG_KGDB is not set
+# CONFIG_SH_KGDB is not set
 
 #
 # Security options
diff --git a/arch/sh/drivers/pci/pci-auto.c b/arch/sh/drivers/pci/pci-auto.c
index ecf1634..224e007 100644
--- a/arch/sh/drivers/pci/pci-auto.c
+++ b/arch/sh/drivers/pci/pci-auto.c
@@ -214,6 +214,12 @@
 			continue;
 		}
 
+		if (bar_value < *lower_limit || (bar_value + bar_size) >= *upper_limit) {
+			DBG(" unavailable -- skipping, value %x size %x\n",
+					bar_value, bar_size);
+			continue;
+		}
+
 #ifdef CONFIG_PCI_AUTO_UPDATE_RESOURCES
 		/* Write it out and update our limit */
 		early_write_config_dword(hose, top_bus, current_bus, pci_devfn,
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index 4b339a6..726acfc 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -3,7 +3,7 @@
  *
  * CPU init code
  *
- * Copyright (C) 2002 - 2006  Paul Mundt
+ * Copyright (C) 2002 - 2007  Paul Mundt
  * Copyright (C) 2003  Richard Curnow
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -48,8 +48,19 @@
 {
 	unsigned long ccr, flags;
 
-	if (current_cpu_data.type == CPU_SH_NONE)
-		panic("Unknown CPU");
+	/* First setup the rest of the I-cache info */
+	current_cpu_data.icache.entry_mask = current_cpu_data.icache.way_incr -
+				      current_cpu_data.icache.linesz;
+
+	current_cpu_data.icache.way_size = current_cpu_data.icache.sets *
+				    current_cpu_data.icache.linesz;
+
+	/* And the D-cache too */
+	current_cpu_data.dcache.entry_mask = current_cpu_data.dcache.way_incr -
+				      current_cpu_data.dcache.linesz;
+
+	current_cpu_data.dcache.way_size = current_cpu_data.dcache.sets *
+				    current_cpu_data.dcache.linesz;
 
 	jump_to_P2();
 	ccr = ctrl_inl(CCR);
@@ -200,6 +211,9 @@
 	/* First, probe the CPU */
 	detect_cpu_and_cache_system();
 
+	if (current_cpu_data.type == CPU_SH_NONE)
+		panic("Unknown CPU");
+
 	/* Init the cache */
 	cache_init();
 
diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S
index 7f7d292..c16dc8f 100644
--- a/arch/sh/kernel/cpu/sh2/entry.S
+++ b/arch/sh/kernel/cpu/sh2/entry.S
@@ -165,6 +165,7 @@
 
 interrupt_entry:
 	mov	r9,r4
+	mov	r15,r5
 	mov.l	6f,r9
 	mov.l	7f,r8
 	jmp	@r8
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index c19205b..f3e827f 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -514,13 +514,16 @@
 
 interrupt_exception:
 	mov.l	1f, r9
+	mov.l	2f, r4
+	mov.l	@r4, r4
 	jmp	@r9
-	 nop
+	 mov	r15, r5
 	rts
 	 nop
 
 	.align 2
 1:	.long	do_IRQ
+2:	.long	INTEVT
 
 	.align	2
 ENTRY(exception_none)
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index 9d28c88..58950de 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -195,13 +195,6 @@
 
 	}
 
-	/* Setup the rest of the I-cache info */
-	current_cpu_data.icache.entry_mask = current_cpu_data.icache.way_incr -
-				      current_cpu_data.icache.linesz;
-
-	current_cpu_data.icache.way_size = current_cpu_data.icache.sets *
-				    current_cpu_data.icache.linesz;
-
 	/* And the rest of the D-cache */
 	if (current_cpu_data.dcache.ways > 1) {
 		size = sizes[(cvr >> 16) & 0xf];
@@ -209,12 +202,6 @@
 		current_cpu_data.dcache.sets		= (size >> 6);
 	}
 
-	current_cpu_data.dcache.entry_mask = current_cpu_data.dcache.way_incr -
-				      current_cpu_data.dcache.linesz;
-
-	current_cpu_data.dcache.way_size = current_cpu_data.dcache.sets *
-				    current_cpu_data.dcache.linesz;
-
 	/*
 	 * Setup the L2 cache desc
 	 *
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index ab4ebb8..b467280 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -224,7 +224,7 @@
 syscall_exit_work:
 	! r0: current_thread_info->flags
 	! r8: current_thread_info
-	tst	#_TIF_SYSCALL_TRACE, r0
+	tst	#_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP, r0
 	bt/s	work_pending
 	 tst	#_TIF_NEED_RESCHED, r0
 #ifdef CONFIG_TRACE_IRQFLAGS
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
index 66626c0..771ea42 100644
--- a/arch/sh/kernel/io_generic.c
+++ b/arch/sh/kernel/io_generic.c
@@ -14,7 +14,6 @@
 #include <linux/module.h>
 #include <linux/io.h>
 #include <asm/machvec.h>
-#include <asm/cacheflush.h>
 
 #ifdef CONFIG_CPU_SH3
 /* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a
@@ -96,7 +95,6 @@
 	while (count--)
 		*buf++ = *port_addr;
 
-	flush_dcache_all();
 	dummy_read();
 }
 
@@ -171,7 +169,6 @@
 	while (count--)
 		*port_addr = *buf++;
 
-	flush_dcache_all();
 	dummy_read();
 }
 
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index 67be2b6..9bdd8a0 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -11,7 +11,6 @@
 #include <linux/module.h>
 #include <linux/kernel_stat.h>
 #include <linux/seq_file.h>
-#include <linux/io.h>
 #include <linux/irq.h>
 #include <asm/processor.h>
 #include <asm/uaccess.h>
@@ -82,13 +81,9 @@
 static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
 #endif
 
-asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
-		      unsigned long r6, unsigned long r7,
-		      struct pt_regs __regs)
+asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs)
 {
-	struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
 	struct pt_regs *old_regs = set_irq_regs(regs);
-	int irq;
 #ifdef CONFIG_4KSTACKS
 	union irq_ctx *curctx, *irqctx;
 #endif
@@ -111,13 +106,7 @@
 	}
 #endif
 
-#ifdef CONFIG_CPU_HAS_INTEVT
-	irq = evt2irq(ctrl_inl(INTEVT));
-#else
-	irq = r4;
-#endif
-
-	irq = irq_demux(irq);
+	irq = irq_demux(evt2irq(irq));
 
 #ifdef CONFIG_4KSTACKS
 	curctx = (union irq_ctx *)current_thread_info();
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 9d6a438..e760736 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -250,12 +250,11 @@
 		childregs->regs[15] = usp;
 		ti->addr_limit = USER_DS;
 	} else {
-		childregs->regs[15] = (unsigned long)task_stack_page(p) +
-							THREAD_SIZE;
+		childregs->regs[15] = (unsigned long)childregs;
 		ti->addr_limit = KERNEL_DS;
 	}
 
-        if (clone_flags & CLONE_SETTLS)
+	if (clone_flags & CLONE_SETTLS)
 		childregs->gbr = childregs->regs[0];
 
 	childregs->regs[0] = 0; /* Set return value for child */
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
index 04ca13a0..855f724 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace.c
@@ -8,7 +8,6 @@
  * SuperH version:   Copyright (C) 1999, 2000  Kaz Kojima & Niibe Yutaka
  *
  */
-
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
@@ -20,8 +19,7 @@
 #include <linux/slab.h>
 #include <linux/security.h>
 #include <linux/signal.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
@@ -59,6 +57,23 @@
 	return 0;
 }
 
+static void ptrace_disable_singlestep(struct task_struct *child)
+{
+	clear_tsk_thread_flag(child, TIF_SINGLESTEP);
+
+	/*
+	 * Ensure the UBC is not programmed at the next context switch.
+	 *
+	 * Normally this is not needed but there are sequences such as
+	 * singlestep, signal delivery, and continue that leave the
+	 * ubc_pc non-zero leading to spurious SIGTRAPs.
+	 */
+	if (child->thread.ubc_pc != 0) {
+		ubc_usercnt -= 1;
+		child->thread.ubc_pc = 0;
+	}
+}
+
 /*
  * Called by kernel/ptrace.c when detaching..
  *
@@ -66,7 +81,7 @@
  */
 void ptrace_disable(struct task_struct *child)
 {
-	/* nothing to do.. */
+	ptrace_disable_singlestep(child);
 }
 
 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
@@ -76,7 +91,7 @@
 
 	switch (request) {
 	/* when I and D space are separate, these will need to be fixed. */
-	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+	case PTRACE_PEEKTEXT: /* read word at location addr. */
 	case PTRACE_PEEKDATA: {
 		unsigned long tmp;
 		int copied;
@@ -94,7 +109,7 @@
 		unsigned long tmp;
 
 		ret = -EIO;
-		if ((addr & 3) || addr < 0 || 
+		if ((addr & 3) || addr < 0 ||
 		    addr > sizeof(struct user) - 3)
 			break;
 
@@ -129,7 +144,7 @@
 
 	case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
 		ret = -EIO;
-		if ((addr & 3) || addr < 0 || 
+		if ((addr & 3) || addr < 0 ||
 		    addr > sizeof(struct user) - 3)
 			break;
 
@@ -156,6 +171,9 @@
 			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 		else
 			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+
+		ptrace_disable_singlestep(child);
+
 		child->exit_code = data;
 		wake_up_process(child);
 		ret = 0;
@@ -163,14 +181,15 @@
 	}
 
 /*
- * make the child exit.  Best I can do is send it a sigkill. 
- * perhaps it should be put in the status that it wants to 
+ * make the child exit.  Best I can do is send it a sigkill.
+ * perhaps it should be put in the status that it wants to
  * exit.
  */
 	case PTRACE_KILL: {
 		ret = 0;
 		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
 			break;
+		ptrace_disable_singlestep(child);
 		child->exit_code = SIGKILL;
 		wake_up_process(child);
 		break;
@@ -196,6 +215,7 @@
 			ubc_usercnt += 1;
 		child->thread.ubc_pc = pc;
 
+		set_tsk_thread_flag(child, TIF_SINGLESTEP);
 		child->exit_code = data;
 		/* give it a chance to run. */
 		wake_up_process(child);
@@ -248,14 +268,15 @@
 {
 	struct task_struct *tsk = current;
 
-	if (!test_thread_flag(TIF_SYSCALL_TRACE))
+	if (!test_thread_flag(TIF_SYSCALL_TRACE) &&
+	    !test_thread_flag(TIF_SINGLESTEP))
 		return;
 	if (!(tsk->ptrace & PT_PTRACED))
 		return;
 	/* the 0x80 provides a way for the tracing parent to distinguish
 	   between a syscall stop and SIGTRAP delivery */
-	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
-				 ? 0x80 : 0));
+	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) &&
+				 !test_thread_flag(TIF_SINGLESTEP) ? 0x80 : 0));
 
 	/*
 	 * this isn't the same as continuing with a signal, but it will do
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c
index fe1b276..6e0d10f 100644
--- a/arch/sh/kernel/sh_ksyms.c
+++ b/arch/sh/kernel/sh_ksyms.c
@@ -82,9 +82,6 @@
 DECLARE_EXPORT(__movmem_i4_even);
 DECLARE_EXPORT(__movmem_i4_odd);
 DECLARE_EXPORT(__movmemSI12_i4);
-DECLARE_EXPORT(__sdivsi3_i4i);
-DECLARE_EXPORT(__udiv_qrnnd_16);
-DECLARE_EXPORT(__udivsi3_i4i);
 #else /* GCC 3.x */
 DECLARE_EXPORT(__movstr_i4_even);
 DECLARE_EXPORT(__movstr_i4_odd);
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index 32f10a0..9f39ef1 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -589,6 +589,8 @@
 			if (test_thread_flag(TIF_RESTORE_SIGMASK))
 				clear_thread_flag(TIF_RESTORE_SIGMASK);
 		}
+
+		return;
 	}
 
  no_signal:
@@ -598,7 +600,7 @@
 		if (regs->regs[0] == -ERESTARTNOHAND ||
 		    regs->regs[0] == -ERESTARTSYS ||
 		    regs->regs[0] == -ERESTARTNOINTR) {
-		    	regs->regs[0] = save_r0;
+			regs->regs[0] = save_r0;
 			regs->pc -= 2;
 		} else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) {
 			regs->pc -= 2;
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index 75de165..78a6c09 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -3,6 +3,7 @@
  * Written by Niibe Yutaka
  */
 #include <asm/thread_info.h>
+#include <asm/cache.h>
 #include <asm-generic/vmlinux.lds.h>
 
 #ifdef CONFIG_CPU_LITTLE_ENDIAN
@@ -53,7 +54,7 @@
   . = ALIGN(PAGE_SIZE);
   .data.page_aligned : { *(.data.page_aligned) }
 
-  . = ALIGN(32);
+  . = ALIGN(L1_CACHE_BYTES);
   __per_cpu_start = .;
   .data.percpu : { *(.data.percpu) }
   __per_cpu_end = .;
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index e0cd4b7..981b040 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -237,20 +237,10 @@
 /*
  * Write back & invalidate the D-cache of the page.
  * (To avoid "alias" issues)
- *
- * This uses a lazy write-back on UP, which is explicitly
- * disabled on SMP.
  */
 void flush_dcache_page(struct page *page)
 {
-#ifndef CONFIG_SMP
-	struct address_space *mapping = page_mapping(page);
-
-	if (mapping && !mapping_mapped(mapping))
-		set_bit(PG_dcache_dirty, &page->flags);
-	else
-#endif
-	{
+	if (test_bit(PG_mapped, &page->flags)) {
 		unsigned long phys = PHYSADDR(page_address(page));
 		unsigned long addr = CACHE_OC_ADDRESS_ARRAY;
 		int i, n;
diff --git a/arch/sh/mm/cache-sh7705.c b/arch/sh/mm/cache-sh7705.c
index 31f8deb..4896d73 100644
--- a/arch/sh/mm/cache-sh7705.c
+++ b/arch/sh/mm/cache-sh7705.c
@@ -3,11 +3,11 @@
  *
  * Copyright (C) 1999, 2000  Niibe Yutaka
  * Copyright (C) 2004  Alex Song
- * Copyright (C) 2006  Paul Mundt
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
+ *
  */
 #include <linux/init.h>
 #include <linux/mman.h>
@@ -51,6 +51,7 @@
 
 			if ((data & v) == v)
 				ctrl_outl(data & ~v, addr);
+
 		}
 
 		addrstart += current_cpu_data.dcache.way_incr;
@@ -127,11 +128,7 @@
  */
 void flush_dcache_page(struct page *page)
 {
-	struct address_space *mapping = page_mapping(page);
-
-	if (mapping && !mapping_mapped(mapping))
-		set_bit(PG_dcache_dirty, &page->flags);
-	else
+	if (test_bit(PG_mapped, &page->flags))
 		__flush_dcache_page(PHYSADDR(page_address(page)));
 }
 
diff --git a/arch/sh/mm/pg-sh4.c b/arch/sh/mm/pg-sh4.c
index 969efece..df69da9 100644
--- a/arch/sh/mm/pg-sh4.c
+++ b/arch/sh/mm/pg-sh4.c
@@ -23,6 +23,7 @@
  */
 void clear_user_page(void *to, unsigned long address, struct page *page)
 {
+	__set_bit(PG_mapped, &page->flags);
 	if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
 		clear_page(to);
 	else {
@@ -58,6 +59,7 @@
 void copy_user_page(void *to, void *from, unsigned long address,
 		    struct page *page)
 {
+	__set_bit(PG_mapped, &page->flags);
 	if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
 		copy_page(to, from);
 	else {
@@ -82,3 +84,23 @@
 		mutex_unlock(&p3map_mutex[(address & CACHE_ALIAS)>>12]);
 	}
 }
+
+/*
+ * For SH-4, we have our own implementation for ptep_get_and_clear
+ */
+inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+	pte_t pte = *ptep;
+
+	pte_clear(mm, addr, ptep);
+	if (!pte_not_present(pte)) {
+		unsigned long pfn = pte_pfn(pte);
+		if (pfn_valid(pfn)) {
+			struct page *page = pfn_to_page(pfn);
+			struct address_space *mapping = page_mapping(page);
+			if (!mapping || !mapping_writably_mapped(mapping))
+				__clear_bit(PG_mapped, &page->flags);
+		}
+	}
+	return pte;
+}
diff --git a/arch/sh/mm/pg-sh7705.c b/arch/sh/mm/pg-sh7705.c
index 887ab9d..a4b015f 100644
--- a/arch/sh/mm/pg-sh7705.c
+++ b/arch/sh/mm/pg-sh7705.c
@@ -7,7 +7,9 @@
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
+ *
  */
+
 #include <linux/init.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
@@ -74,6 +76,7 @@
 {
 	struct page *page = virt_to_page(to);
 
+	__set_bit(PG_mapped, &page->flags);
 	if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) {
 		clear_page(to);
 		__flush_wback_region(to, PAGE_SIZE);
@@ -92,11 +95,12 @@
  * @from: P1 address
  * @address: U0 address to be mapped
  */
-void copy_user_page(void *to, void *from, unsigned long address,
-		    struct page *pg)
+void copy_user_page(void *to, void *from, unsigned long address, struct page *pg)
 {
 	struct page *page = virt_to_page(to);
 
+
+	__set_bit(PG_mapped, &page->flags);
 	if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) {
 		copy_page(to, from);
 		__flush_wback_region(to, PAGE_SIZE);
@@ -108,3 +112,26 @@
 		__flush_wback_region(to, PAGE_SIZE);
 	}
 }
+
+/*
+ * For SH7705, we have our own implementation for ptep_get_and_clear
+ * Copied from pg-sh4.c
+ */
+inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+	pte_t pte = *ptep;
+
+	pte_clear(mm, addr, ptep);
+	if (!pte_not_present(pte)) {
+		unsigned long pfn = pte_pfn(pte);
+		if (pfn_valid(pfn)) {
+			struct page *page = pfn_to_page(pfn);
+			struct address_space *mapping = page_mapping(page);
+			if (!mapping || !mapping_writably_mapped(mapping))
+				__clear_bit(PG_mapped, &page->flags);
+		}
+	}
+
+	return pte;
+}
+
diff --git a/arch/sh/mm/tlb-flush.c b/arch/sh/mm/tlb-flush.c
index d2f7b4a..6f45c1f 100644
--- a/arch/sh/mm/tlb-flush.c
+++ b/arch/sh/mm/tlb-flush.c
@@ -2,17 +2,15 @@
  * TLB flushing operations for SH with an MMU.
  *
  *  Copyright (C) 1999  Niibe Yutaka
- *  Copyright (C) 2003 - 2006  Paul Mundt
+ *  Copyright (C) 2003  Paul Mundt
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  */
 #include <linux/mm.h>
-#include <linux/io.h>
 #include <asm/mmu_context.h>
 #include <asm/tlbflush.h>
-#include <asm/cacheflush.h>
 
 void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 {
@@ -140,54 +138,3 @@
 	ctrl_barrier();
 	local_irq_restore(flags);
 }
-
-void update_mmu_cache(struct vm_area_struct *vma,
-		      unsigned long address, pte_t pte)
-{
-	unsigned long flags;
-	unsigned long pteval;
-	unsigned long vpn;
-	struct page *page;
-	unsigned long pfn = pte_pfn(pte);
-	struct address_space *mapping;
-
-	if (!pfn_valid(pfn))
-		return;
-
-	page = pfn_to_page(pfn);
-	mapping = page_mapping(page);
-	if (mapping) {
-		unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
-		int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
-
-		if (dirty)
-			__flush_wback_region((void *)P1SEGADDR(phys),
-					     PAGE_SIZE);
-	}
-
-	local_irq_save(flags);
-
-	/* Set PTEH register */
-	vpn = (address & MMU_VPN_MASK) | get_asid();
-	ctrl_outl(vpn, MMU_PTEH);
-
-	pteval = pte_val(pte);
-
-#ifdef CONFIG_CPU_HAS_PTEA
-	/* Set PTEA register */
-	/* TODO: make this look less hacky */
-	ctrl_outl(((pteval >> 28) & 0xe) | (pteval & 0x1), MMU_PTEA);
-#endif
-
-	/* Set PTEL register */
-	pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
-#if defined(CONFIG_SH_WRITETHROUGH) && defined(CONFIG_CPU_SH4)
-	pteval |= _PAGE_WT;
-#endif
-	/* conveniently, we want all the software flags to be 0 anyway */
-	ctrl_outl(pteval, MMU_PTEL);
-
-	/* Load the TLB */
-	asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
-	local_irq_restore(flags);
-}
diff --git a/arch/sh/mm/tlb-sh3.c b/arch/sh/mm/tlb-sh3.c
index e5e76eb..7fbfd5a 100644
--- a/arch/sh/mm/tlb-sh3.c
+++ b/arch/sh/mm/tlb-sh3.c
@@ -8,9 +8,69 @@
  *
  * Released under the terms of the GNU GPL v2.0.
  */
-#include <linux/io.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+
 #include <asm/system.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+
+void update_mmu_cache(struct vm_area_struct * vma,
+		      unsigned long address, pte_t pte)
+{
+	unsigned long flags;
+	unsigned long pteval;
+	unsigned long vpn;
+
+	/* Ptrace may call this routine. */
+	if (vma && current->active_mm != vma->vm_mm)
+		return;
+
+#if defined(CONFIG_SH7705_CACHE_32KB)
+	{
+		struct page *page = pte_page(pte);
+		unsigned long pfn = pte_pfn(pte);
+
+		if (pfn_valid(pfn) && !test_bit(PG_mapped, &page->flags)) {
+			unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
+
+			__flush_wback_region((void *)P1SEGADDR(phys),
+					     PAGE_SIZE);
+			__set_bit(PG_mapped, &page->flags);
+		}
+	}
+#endif
+
+	local_irq_save(flags);
+
+	/* Set PTEH register */
+	vpn = (address & MMU_VPN_MASK) | get_asid();
+	ctrl_outl(vpn, MMU_PTEH);
+
+	pteval = pte_val(pte);
+
+	/* Set PTEL register */
+	pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
+	/* conveniently, we want all the software flags to be 0 anyway */
+	ctrl_outl(pteval, MMU_PTEL);
+
+	/* Load the TLB */
+	asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
+	local_irq_restore(flags);
+}
 
 void local_flush_tlb_one(unsigned long asid, unsigned long page)
 {
@@ -34,3 +94,4 @@
 	for (i = 0; i < ways; i++)
 		ctrl_outl(data, addr + (i << 8));
 }
+
diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c
index 221e709..f74cf66 100644
--- a/arch/sh/mm/tlb-sh4.c
+++ b/arch/sh/mm/tlb-sh4.c
@@ -8,9 +8,74 @@
  *
  * Released under the terms of the GNU GPL v2.0.
  */
-#include <linux/io.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+
 #include <asm/system.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+
+void update_mmu_cache(struct vm_area_struct * vma,
+		      unsigned long address, pte_t pte)
+{
+	unsigned long flags;
+	unsigned long pteval;
+	unsigned long vpn;
+	struct page *page;
+	unsigned long pfn;
+
+	/* Ptrace may call this routine. */
+	if (vma && current->active_mm != vma->vm_mm)
+		return;
+
+	pfn = pte_pfn(pte);
+	if (pfn_valid(pfn)) {
+		page = pfn_to_page(pfn);
+		if (!test_bit(PG_mapped, &page->flags)) {
+			unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
+			__flush_wback_region((void *)P1SEGADDR(phys), PAGE_SIZE);
+			__set_bit(PG_mapped, &page->flags);
+		}
+	}
+
+	local_irq_save(flags);
+
+	/* Set PTEH register */
+	vpn = (address & MMU_VPN_MASK) | get_asid();
+	ctrl_outl(vpn, MMU_PTEH);
+
+	pteval = pte_val(pte);
+
+	/* Set PTEA register */
+	if (cpu_data->flags & CPU_HAS_PTEA)
+		/* TODO: make this look less hacky */
+		ctrl_outl(((pteval >> 28) & 0xe) | (pteval & 0x1), MMU_PTEA);
+
+	/* Set PTEL register */
+	pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
+#ifdef CONFIG_SH_WRITETHROUGH
+	pteval |= _PAGE_WT;
+#endif
+	/* conveniently, we want all the software flags to be 0 anyway */
+	ctrl_outl(pteval, MMU_PTEL);
+
+	/* Load the TLB */
+	asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
+	local_irq_restore(flags);
+}
 
 void local_flush_tlb_one(unsigned long asid, unsigned long page)
 {
@@ -28,3 +93,4 @@
 	ctrl_outl(data, addr);
 	back_to_P1();
 }
+
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index 113bd48..fc874e6 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -348,7 +348,7 @@
 #ifndef CONFIG_SMP
 	if(last_task_used_math == current) {
 #else
-	if(current_thread_info()->flags & _TIF_USEDFPU) {
+	if (test_thread_flag(TIF_USEDFPU)) {
 #endif
 		/* Keep process from leaving FPU in a bogon state. */
 		put_psr(get_psr() | PSR_EF);
@@ -357,7 +357,7 @@
 #ifndef CONFIG_SMP
 		last_task_used_math = NULL;
 #else
-		current_thread_info()->flags &= ~_TIF_USEDFPU;
+		clear_thread_flag(TIF_USEDFPU);
 #endif
 	}
 }
@@ -371,7 +371,7 @@
 #ifndef CONFIG_SMP
 	if(last_task_used_math == current) {
 #else
-	if(current_thread_info()->flags & _TIF_USEDFPU) {
+	if (test_thread_flag(TIF_USEDFPU)) {
 #endif
 		/* Clean the fpu. */
 		put_psr(get_psr() | PSR_EF);
@@ -380,7 +380,7 @@
 #ifndef CONFIG_SMP
 		last_task_used_math = NULL;
 #else
-		current_thread_info()->flags &= ~_TIF_USEDFPU;
+		clear_thread_flag(TIF_USEDFPU);
 #endif
 	}
 
@@ -466,13 +466,13 @@
 #ifndef CONFIG_SMP
 	if(last_task_used_math == current) {
 #else
-	if(current_thread_info()->flags & _TIF_USEDFPU) {
+	if (test_thread_flag(TIF_USEDFPU)) {
 #endif
 		put_psr(get_psr() | PSR_EF);
 		fpsave(&p->thread.float_regs[0], &p->thread.fsr,
 		       &p->thread.fpqueue[0], &p->thread.fpqdepth);
 #ifdef CONFIG_SMP
-		current_thread_info()->flags &= ~_TIF_USEDFPU;
+		clear_thread_flag(TIF_USEDFPU);
 #endif
 	}
 
@@ -609,13 +609,13 @@
 		return 1;
 	}
 #ifdef CONFIG_SMP
-	if (current_thread_info()->flags & _TIF_USEDFPU) {
+	if (test_thread_flag(TIF_USEDFPU)) {
 		put_psr(get_psr() | PSR_EF);
 		fpsave(&current->thread.float_regs[0], &current->thread.fsr,
 		       &current->thread.fpqueue[0], &current->thread.fpqdepth);
 		if (regs != NULL) {
 			regs->psr &= ~(PSR_EF);
-			current_thread_info()->flags &= ~(_TIF_USEDFPU);
+			clear_thread_flag(TIF_USEDFPU);
 		}
 	}
 #else
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S
index ea75ca5..3a69778 100644
--- a/arch/sparc/kernel/systbls.S
+++ b/arch/sparc/kernel/systbls.S
@@ -78,7 +78,8 @@
 /*285*/	.long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64
 /*290*/	.long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
 /*295*/	.long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
-/*300*/	.long sys_set_robust_list, sys_get_robust_list, sys_migrate_pages
+/*300*/	.long sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy
+/*305*/	.long sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait
 
 #ifdef CONFIG_SUNOS_EMUL
 	/* Now the SunOS syscall table. */
@@ -192,5 +193,8 @@
 	.long sunos_nosys, sunos_nosys, sunos_nosys
 	.long sunos_nosys
 /*300*/	.long sunos_nosys, sunos_nosys, sunos_nosys
+	.long sunos_nosys, sunos_nosys, sunos_nosys
+	.long sunos_nosys, sunos_nosys, sunos_nosys
+	.long sunos_nosys
 
 #endif
diff --git a/arch/sparc/kernel/traps.c b/arch/sparc/kernel/traps.c
index 6a70d21..527687a 100644
--- a/arch/sparc/kernel/traps.c
+++ b/arch/sparc/kernel/traps.c
@@ -259,7 +259,7 @@
 	} else {
 		fpload(&current->thread.float_regs[0], &current->thread.fsr);
 	}
-	current_thread_info()->flags |= _TIF_USEDFPU;
+	set_thread_flag(TIF_USEDFPU);
 #endif
 }
 
@@ -290,7 +290,7 @@
 #ifndef CONFIG_SMP
 	if(!fpt) {
 #else
-        if(!(task_thread_info(fpt)->flags & _TIF_USEDFPU)) {
+	if (!test_tsk_thread_flag(fpt, TIF_USEDFPU)) {
 #endif
 		fpsave(&fake_regs[0], &fake_fsr, &fake_queue[0], &fake_depth);
 		regs->psr &= ~PSR_EF;
@@ -333,7 +333,7 @@
 	/* nope, better SIGFPE the offending process... */
 	       
 #ifdef CONFIG_SMP
-	task_thread_info(fpt)->flags &= ~_TIF_USEDFPU;
+	clear_tsk_thread_flag(fpt, TIF_USEDFPU);
 #endif
 	if(psr & PSR_PS) {
 		/* The first fsr store/load we tried trapped,
diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c
index 53ddcd9..559335f 100644
--- a/arch/sparc/lib/atomic32.c
+++ b/arch/sparc/lib/atomic32.c
@@ -52,6 +52,7 @@
 	spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
 	return ret;
 }
+EXPORT_SYMBOL(atomic_cmpxchg);
 
 int atomic_add_unless(atomic_t *v, int a, int u)
 {
@@ -65,6 +66,7 @@
 	spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
 	return ret != u;
 }
+EXPORT_SYMBOL(atomic_add_unless);
 
 /* Atomic operations are already serializing */
 void atomic_set(atomic_t *v, int i)
diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
index c85ddf3..a532922 100644
--- a/arch/sparc/mm/init.c
+++ b/arch/sparc/mm/init.c
@@ -75,7 +75,7 @@
 	printk("Free swap:       %6ldkB\n",
 	       nr_swap_pages << (PAGE_SHIFT-10));
 	printk("%ld pages of RAM\n", totalram_pages);
-	printk("%d free pages\n", nr_free_pages());
+	printk("%ld free pages\n", nr_free_pages());
 #if 0 /* undefined pgtable_cache_size, pgd_cache_size */
 	printk("%ld pages in page table cache\n",pgtable_cache_size);
 #ifndef CONFIG_SMP
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index f75a686..1a6348b 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -136,18 +136,6 @@
 
 	  If you don't know what to do here, say N.
 
-config PREEMPT
-	bool "Preemptible Kernel"
-	help
-	  This option reduces the latency of the kernel when reacting to
-	  real-time or interactive events by allowing a low priority process to
-	  be preempted even if it is in kernel mode executing a system call.
-	  This allows applications to run more reliably even when the system is
-	  under load.
-
-	  Say Y here if you are building a kernel for a desktop, embedded
-	  or real-time system.  Say N if you are unsure.
-
 config NR_CPUS
 	int "Maximum number of CPUs (2-64)"
 	range 2 64
@@ -399,6 +387,8 @@
 	  when dealing with UltraSPARC cpus at a cost of slightly increased
 	  overhead in some places. If unsure say N here.
 
+source "kernel/Kconfig.preempt"
+
 config CMDLINE_BOOL
 	bool "Default bootloader kernel arguments"
 
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 860b8b6..120c9c3 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.21-rc2
-# Wed Feb 28 09:50:51 2007
+# Linux kernel version: 2.6.21-rc4
+# Sat Mar 17 14:18:44 2007
 #
 CONFIG_SPARC=y
 CONFIG_SPARC64=y
@@ -50,6 +50,7 @@
 # CONFIG_IKCONFIG is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
+# CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
@@ -108,7 +109,6 @@
 # General machine setup
 #
 # CONFIG_SMP is not set
-# CONFIG_PREEMPT is not set
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_TABLE=m
 # CONFIG_CPU_FREQ_DEBUG is not set
@@ -165,6 +165,9 @@
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
 CONFIG_SOLARIS_EMUL=y
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
 # CONFIG_CMDLINE_BOOL is not set
 
 #
@@ -340,7 +343,6 @@
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
 # CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 CONFIG_CDROM_PKTCDVD_WCACHE=y
diff --git a/arch/sparc64/kernel/ktlb.S b/arch/sparc64/kernel/ktlb.S
index e492db8..d4024ac 100644
--- a/arch/sparc64/kernel/ktlb.S
+++ b/arch/sparc64/kernel/ktlb.S
@@ -138,9 +138,15 @@
 	brgez,pn	%g4, kvmap_dtlb_nonlinear
 	 nop
 
+#ifdef CONFIG_DEBUG_PAGEALLOC
+	/* Index through the base page size TSB even for linear
+	 * mappings when using page allocation debugging.
+	 */
+	KERN_TSB_LOOKUP_TL1(%g4, %g6, %g5, %g1, %g2, %g3, kvmap_dtlb_load)
+#else
 	/* Correct TAG_TARGET is already in %g6, check 4mb TSB.  */
 	KERN_TSB4M_LOOKUP_TL1(%g6, %g5, %g1, %g2, %g3, kvmap_dtlb_load)
-
+#endif
 	/* TSB entry address left in %g1, lookup linear PTE.
 	 * Must preserve %g1 and %g6 (TAG).
 	 */
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 7d75cd4..b291060 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -413,8 +413,13 @@
 	struct thread_info *t = current_thread_info();
 	struct mm_struct *mm;
 
-	if (t->flags & _TIF_ABI_PENDING)
-		t->flags ^= (_TIF_ABI_PENDING | _TIF_32BIT);
+	if (test_ti_thread_flag(t, TIF_ABI_PENDING)) {
+		clear_ti_thread_flag(t, TIF_ABI_PENDING);
+		if (test_ti_thread_flag(t, TIF_32BIT))
+			clear_ti_thread_flag(t, TIF_32BIT);
+		else
+			set_ti_thread_flag(t, TIF_32BIT);
+	}
 
 	mm = t->task->mm;
 	if (mm)
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index 948b7d2..aaeb5e0 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -79,7 +79,8 @@
 	.word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_fstatat64
 /*290*/	.word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
 	.word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare
-/*300*/	.word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages
+/*300*/	.word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages, compat_sys_mbind, compat_sys_get_mempolicy
+	.word compat_sys_set_mempolicy, compat_sys_kexec_load, compat_sys_move_pages, sys_getcpu, compat_sys_epoll_pwait
 
 #endif /* CONFIG_COMPAT */
 
@@ -149,7 +150,8 @@
 	.word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64
 /*290*/	.word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
 	.word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
-/*300*/	.word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages
+/*300*/	.word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy
+	.word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait
 
 #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
     defined(CONFIG_SOLARIS_EMUL_MODULE)
@@ -264,5 +266,8 @@
 	.word sunos_nosys, sunos_nosys, sunos_nosys
 	.word sunos_nosys
 /*300*/	.word sunos_nosys, sunos_nosys, sunos_nosys
+	.word sunos_nosys, sunos_nosys, sunos_nosys
+	.word sunos_nosys, sunos_nosys, sunos_nosys
+	.word sunos_nosys
 
 #endif
diff --git a/arch/sparc64/kernel/tsb.S b/arch/sparc64/kernel/tsb.S
index eedf94f..10adb2f 100644
--- a/arch/sparc64/kernel/tsb.S
+++ b/arch/sparc64/kernel/tsb.S
@@ -546,6 +546,7 @@
 	subcc		%o1, 0x100, %o1
 	bne,pt		%xcc, 1b
 	 add		%o0, 0x100, %o0
+	membar		#Sync
 	retl
 	 wr		%g2, 0x0, %asi
 	.size		NGtsb_init, .-NGtsb_init
diff --git a/arch/sparc64/lib/NGbzero.S b/arch/sparc64/lib/NGbzero.S
index e86baec..f10e452 100644
--- a/arch/sparc64/lib/NGbzero.S
+++ b/arch/sparc64/lib/NGbzero.S
@@ -88,6 +88,7 @@
 	bne,pt		%xcc, NGbzero_loop
 	 add		%o0, 64, %o0
 
+	membar		#Sync
 	wr		%o4, 0x0, %asi
 	brz,pn		%o1, NGbzero_done
 NGbzero_medium:
diff --git a/arch/sparc64/lib/NGmemcpy.S b/arch/sparc64/lib/NGmemcpy.S
index 8e522b3..66063a9 100644
--- a/arch/sparc64/lib/NGmemcpy.S
+++ b/arch/sparc64/lib/NGmemcpy.S
@@ -247,6 +247,8 @@
 	/* fall through */
 
 60:	
+	membar		#Sync
+
 	/* %o2 contains any final bytes still needed to be copied
 	 * over. If anything is left, we copy it one byte at a time.
 	 */
diff --git a/arch/sparc64/lib/NGpage.S b/arch/sparc64/lib/NGpage.S
index 7d7c3bb..8ce3a0c 100644
--- a/arch/sparc64/lib/NGpage.S
+++ b/arch/sparc64/lib/NGpage.S
@@ -41,6 +41,7 @@
 	subcc		%g7, 64, %g7
 	bne,pt		%xcc, 1b
 	 add		%o0, 32, %o0
+	membar		#Sync
 	retl
 	 nop
 
@@ -63,6 +64,7 @@
 	subcc		%g7, 64, %g7
 	bne,pt		%xcc, 1b
 	 add		%o0, 32, %o0
+	membar		#Sync
 	retl
 	 nop
 
diff --git a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c
index 33fd0b2..00677b5 100644
--- a/arch/sparc64/mm/hugetlbpage.c
+++ b/arch/sparc64/mm/hugetlbpage.c
@@ -248,6 +248,7 @@
 	if (!pte_present(*ptep) && pte_present(entry))
 		mm->context.huge_pte_count++;
 
+	addr &= HPAGE_MASK;
 	for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
 		set_pte_at(mm, addr, ptep, entry);
 		ptep++;
@@ -266,6 +267,8 @@
 	if (pte_present(entry))
 		mm->context.huge_pte_count--;
 
+	addr &= HPAGE_MASK;
+
 	for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
 		pte_clear(mm, addr, ptep);
 		addr += PAGE_SIZE;
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index b1a1ee0..f146071 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -59,8 +59,10 @@
  */
 unsigned long kpte_linear_bitmap[KPTE_BITMAP_BYTES / sizeof(unsigned long)];
 
+#ifndef CONFIG_DEBUG_PAGEALLOC
 /* A special kernel TSB for 4MB and 256MB linear mappings.  */
 struct tsb swapper_4m_tsb[KERNEL_TSB4M_NENTRIES];
+#endif
 
 #define MAX_BANKS	32
 
@@ -1301,7 +1303,12 @@
 }
 
 /* Don't mark as init, we give this to the Hypervisor.  */
-static struct hv_tsb_descr ktsb_descr[2];
+#ifndef CONFIG_DEBUG_PAGEALLOC
+#define NUM_KTSB_DESCR	2
+#else
+#define NUM_KTSB_DESCR	1
+#endif
+static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR];
 extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES];
 
 static void __init sun4v_ktsb_init(void)
@@ -1340,6 +1347,7 @@
 	ktsb_descr[0].tsb_base = ktsb_pa;
 	ktsb_descr[0].resv = 0;
 
+#ifndef CONFIG_DEBUG_PAGEALLOC
 	/* Second KTSB for 4MB/256MB mappings.  */
 	ktsb_pa = (kern_base +
 		   ((unsigned long)&swapper_4m_tsb[0] - KERNBASE));
@@ -1352,6 +1360,7 @@
 	ktsb_descr[1].ctx_idx = 0;
 	ktsb_descr[1].tsb_base = ktsb_pa;
 	ktsb_descr[1].resv = 0;
+#endif
 }
 
 void __cpuinit sun4v_ktsb_register(void)
@@ -1364,7 +1373,7 @@
 	pa = kern_base + ((unsigned long)&ktsb_descr[0] - KERNBASE);
 
 	func = HV_FAST_MMU_TSB_CTX0;
-	arg0 = 2;
+	arg0 = NUM_KTSB_DESCR;
 	arg1 = pa;
 	__asm__ __volatile__("ta	%6"
 			     : "=&r" (func), "=&r" (arg0), "=&r" (arg1)
@@ -1393,7 +1402,9 @@
 
 	/* Invalidate both kernel TSBs.  */
 	memset(swapper_tsb, 0x40, sizeof(swapper_tsb));
+#ifndef CONFIG_DEBUG_PAGEALLOC
 	memset(swapper_4m_tsb, 0x40, sizeof(swapper_4m_tsb));
+#endif
 
 	if (tlb_type == hypervisor)
 		sun4v_pgprot_init();
@@ -1725,8 +1736,13 @@
 	pg_iobits = (_PAGE_VALID | _PAGE_PRESENT_4U | __DIRTY_BITS_4U |
 		     __ACCESS_BITS_4U | _PAGE_E_4U);
 
+#ifdef CONFIG_DEBUG_PAGEALLOC
+	kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZBITS_4U) ^
+		0xfffff80000000000;
+#else
 	kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4U) ^
 		0xfffff80000000000;
+#endif
 	kern_linear_pte_xor[0] |= (_PAGE_CP_4U | _PAGE_CV_4U |
 				   _PAGE_P_4U | _PAGE_W_4U);
 
@@ -1769,13 +1785,23 @@
 	_PAGE_E = _PAGE_E_4V;
 	_PAGE_CACHE = _PAGE_CACHE_4V;
 
+#ifdef CONFIG_DEBUG_PAGEALLOC
+	kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZBITS_4V) ^
+		0xfffff80000000000;
+#else
 	kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4V) ^
 		0xfffff80000000000;
+#endif
 	kern_linear_pte_xor[0] |= (_PAGE_CP_4V | _PAGE_CV_4V |
 				   _PAGE_P_4V | _PAGE_W_4V);
 
+#ifdef CONFIG_DEBUG_PAGEALLOC
+	kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZBITS_4V) ^
+		0xfffff80000000000;
+#else
 	kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZ256MB_4V) ^
 		0xfffff80000000000;
+#endif
 	kern_linear_pte_xor[1] |= (_PAGE_CP_4V | _PAGE_CV_4V |
 				   _PAGE_P_4V | _PAGE_W_4V);
 
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index b3a21ba..354cc6b 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -44,7 +44,7 @@
 
 config STACKTRACE_SUPPORT
 	bool
-	default y
+	default n
 
 config GENERIC_CALIBRATE_DELAY
 	bool
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 7b8baf1..9fdfad6 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -236,11 +236,11 @@
 	struct chan *chan;
 	LIST_HEAD(list);
 	struct list_head *ele;
+	unsigned long flags;
 
-	spin_lock_irq(&irqs_to_free_lock);
+	spin_lock_irqsave(&irqs_to_free_lock, flags);
 	list_splice_init(&irqs_to_free, &list);
-	INIT_LIST_HEAD(&irqs_to_free);
-	spin_unlock_irq(&irqs_to_free_lock);
+	spin_unlock_irqrestore(&irqs_to_free_lock, flags);
 
 	list_for_each(ele, &list){
 		chan = list_entry(ele, struct chan, free_list);
@@ -255,13 +255,15 @@
 
 static void close_one_chan(struct chan *chan, int delay_free_irq)
 {
+	unsigned long flags;
+
 	if(!chan->opened)
 		return;
 
 	if(delay_free_irq){
-		spin_lock_irq(&irqs_to_free_lock);
+		spin_lock_irqsave(&irqs_to_free_lock, flags);
 		list_add(&chan->free_list, &irqs_to_free);
-		spin_unlock_irq(&irqs_to_free_lock);
+		spin_unlock_irqrestore(&irqs_to_free_lock, flags);
 	}
 	else {
 		if(chan->input)
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index 310af0f..021b82c 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -56,30 +56,31 @@
 
 	pri->control = socket(AF_UNIX, SOCK_STREAM, 0);
 	if(pri->control < 0){
+		err = -errno;
 		printk("daemon_open : control socket failed, errno = %d\n", 
-		       errno);		
-		return(-errno);
+		       -err);
+		return err;
 	}
 
 	if(connect(pri->control, (struct sockaddr *) ctl_addr, 
 		   sizeof(*ctl_addr)) < 0){
-		printk("daemon_open : control connect failed, errno = %d\n",
-		       errno);
 		err = -errno;
+		printk("daemon_open : control connect failed, errno = %d\n",
+		       -err);
 		goto out;
 	}
 
 	fd = socket(AF_UNIX, SOCK_DGRAM, 0);
 	if(fd < 0){
-		printk("daemon_open : data socket failed, errno = %d\n", 
-		       errno);
 		err = -errno;
+		printk("daemon_open : data socket failed, errno = %d\n",
+		       -err);
 		goto out;
 	}
 	if(bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0){
-		printk("daemon_open : data bind failed, errno = %d\n", 
-		       errno);
 		err = -errno;
+		printk("daemon_open : data bind failed, errno = %d\n",
+		       -err);
 		goto out_close;
 	}
 
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 01d4ab6..f75d7b0 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -370,10 +370,10 @@
 	struct tty_struct *tty = line->tty;
 	int err;
 
-	/* Interrupts are enabled here because we registered the interrupt with
+	/* Interrupts are disabled here because we registered the interrupt with
 	 * IRQF_DISABLED (see line_setup_irq).*/
 
-	spin_lock_irq(&line->lock);
+	spin_lock(&line->lock);
 	err = flush_buffer(line);
 	if (err == 0) {
 		return IRQ_NONE;
@@ -381,7 +381,7 @@
 		line->head = line->buffer;
 		line->tail = line->buffer;
 	}
-	spin_unlock_irq(&line->lock);
+	spin_unlock(&line->lock);
 
 	if(tty == NULL)
 		return IRQ_NONE;
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
index 8138f5e..b827e82 100644
--- a/arch/um/drivers/mcast_user.c
+++ b/arch/um/drivers/mcast_user.c
@@ -50,6 +50,14 @@
 	pri->dev = dev;
 }
 
+static void mcast_remove(void *data)
+{
+	struct mcast_data *pri = data;
+
+	kfree(pri->mcast_addr);
+	pri->mcast_addr = NULL;
+}
+
 static int mcast_open(void *data)
 {
 	struct mcast_data *pri = data;
@@ -157,7 +165,7 @@
 	.init		= mcast_user_init,
 	.open		= mcast_open,
 	.close	 	= mcast_close,
-	.remove	 	= NULL,
+	.remove	 	= mcast_remove,
 	.set_mtu	= mcast_set_mtu,
 	.add_address	= NULL,
 	.delete_address = NULL,
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 178b2ef..65ad293 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -615,6 +615,9 @@
 	err_msg = NULL;
 	err = (*dev->remove)(n, &err_msg);
 	switch(err){
+	case 0:
+		err_msg = "";
+		break;
 	case -ENODEV:
 		if(err_msg == NULL)
 			err_msg = "Device doesn't exist";
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index fc22b9b..4b382a6 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -179,7 +179,7 @@
 	.write		= ssl_console_write,
 	.device		= ssl_console_device,
 	.setup		= ssl_console_setup,
-	.flags		= CON_PRINTBUFFER,
+	.flags		= CON_PRINTBUFFER|CON_ANYTIME,
 	.index		= -1,
 };
 
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 7ff0b0f..76d1f1c 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -153,7 +153,7 @@
 	.write		= uml_console_write,
 	.device		= uml_console_device,
 	.setup		= uml_console_setup,
-	.flags		= CON_PRINTBUFFER,
+	.flags		= CON_PRINTBUFFER|CON_ANYTIME,
 	.index		= -1,
 };
 
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index f98d26e..8bd9204 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -109,10 +109,6 @@
 
 static DEFINE_MUTEX(ubd_lock);
 
-/* XXX - this made sense in 2.4 days, now it's only used as a boolean, and
- * probably it doesn't make sense even for that. */
-static int do_ubd;
-
 static int ubd_open(struct inode * inode, struct file * filp);
 static int ubd_release(struct inode * inode, struct file * file);
 static int ubd_ioctl(struct inode * inode, struct file * file,
@@ -169,6 +165,7 @@
 	struct platform_device pdev;
 	struct request_queue *queue;
 	spinlock_t lock;
+	int active;
 };
 
 #define DEFAULT_COW { \
@@ -190,6 +187,7 @@
 	.shared =		0, \
         .cow =			DEFAULT_COW, \
 	.lock =			SPIN_LOCK_UNLOCKED,	\
+	.active =		0, \
 }
 
 /* Protected by ubd_lock */
@@ -507,7 +505,6 @@
 	struct ubd *dev;
 	int n;
 
-	do_ubd = 0;
 	n = os_read_file(thread_fd, &req, sizeof(req));
 	if(n != sizeof(req)){
 		printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
@@ -517,6 +514,7 @@
 
 	rq = req.req;
 	dev = rq->rq_disk->private_data;
+	dev->active = 0;
 
 	ubd_finish(rq, req.error);
 	reactivate_fd(thread_fd, UBD_IRQ);
@@ -1081,11 +1079,12 @@
 		}
 	}
 	else {
-		if(do_ubd || (req = elv_next_request(q)) == NULL)
+		struct ubd *dev = q->queuedata;
+		if(dev->active || (req = elv_next_request(q)) == NULL)
 			return;
 		err = prepare_request(req, &io_req);
 		if(!err){
-			do_ubd = 1;
+			dev->active = 1;
 			n = os_write_file(thread_fd, (char *) &io_req,
 					 sizeof(io_req));
 			if(n != sizeof(io_req))
diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
index 2666815..b282839 100644
--- a/arch/um/include/mconsole.h
+++ b/arch/um/include/mconsole.h
@@ -12,6 +12,8 @@
 #define u32 uint32_t
 #endif
 
+#include "sysdep/ptrace.h"
+
 #define MCONSOLE_MAGIC (0xcafebabe)
 #define MCONSOLE_MAX_DATA (512)
 #define MCONSOLE_VERSION 2
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 8629bd1..5c74da4 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -192,7 +192,9 @@
 extern void os_stop_process(int pid);
 extern void os_kill_process(int pid, int reap_child);
 extern void os_kill_ptraced_process(int pid, int reap_child);
+#ifdef UML_CONFIG_MODE_TT
 extern void os_usr1_process(int pid);
+#endif
 extern long os_ptrace_ldt(long pid, long addr, long data);
 
 extern int os_getpid(void);
@@ -261,7 +263,6 @@
 extern void unblock_signals(void);
 extern int get_signals(void);
 extern int set_signals(int enable);
-extern void os_usr1_signal(int on);
 
 /* trap.c */
 extern void os_fill_handlinfo(struct kern_handlers h);
diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h
index 66cb400..62403bd 100644
--- a/arch/um/include/sysdep-x86_64/ptrace.h
+++ b/arch/um/include/sysdep-x86_64/ptrace.h
@@ -104,10 +104,6 @@
 #endif
 #ifdef UML_CONFIG_MODE_SKAS
 	struct skas_regs {
-		/* x86_64 ptrace uses sizeof(user_regs_struct) as its register
-		 * file size, while i386 uses FRAME_SIZE.  Therefore, we need
-		 * to use UM_FRAME_SIZE here instead of HOST_FRAME_SIZE.
-		 */
 		unsigned long regs[MAX_REG_NR];
 		unsigned long fp[HOST_FP_SIZE];
                 struct faultinfo faultinfo;
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 50a288b..dbf2f5b 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -142,6 +142,7 @@
 				     .events 		= events,
 				     .current_events 	= 0 } );
 
+	err = -EBUSY;
 	spin_lock_irqsave(&irq_lock, flags);
 	for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) {
 		if ((irq_fd->fd == fd) && (irq_fd->type == type)) {
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index e85d65d..df7d662 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -64,8 +64,6 @@
 
 void mem_init(void)
 {
-	max_low_pfn = (high_physmem - uml_physmem) >> PAGE_SHIFT;
-
 	/* clear the zero-page */
 	memset((void *) empty_zero_page, 0, PAGE_SIZE);
 
@@ -80,6 +78,7 @@
 
 	/* this will put all low memory onto the freelists */
 	totalram_pages = free_all_bootmem();
+	max_low_pfn = totalram_pages;
 #ifdef CONFIG_HIGHMEM
 	totalhigh_pages = highmem >> PAGE_SHIFT;
 	totalram_pages += totalhigh_pages;
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index c692a19..76bdd67 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -21,6 +21,7 @@
 #include "longjmp.h"
 #include "skas_ptrace.h"
 #include "kern_constants.h"
+#include "uml-config.h"
 
 #define ARBITRARY_ADDR -1
 #define FAILURE_PID    -1
@@ -131,10 +132,12 @@
 		CATCH_EINTR(waitpid(pid, NULL, 0));
 }
 
+#ifdef UML_CONFIG_MODE_TT
 void os_usr1_process(int pid)
 {
 	kill(pid, SIGUSR1);
 }
+#endif
 
 /* Don't use the glibc version, which caches the result in TLS. It misses some
  * syscalls, and also breaks with clone(), which does not unshare the TLS.
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index b897e85..2667686 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -243,8 +243,3 @@
 
 	return ret;
 }
-
-void os_usr1_signal(int on)
-{
-	change_sig(SIGUSR1, on);
-}
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index b3c11cf..9383e87 100644
--- a/arch/um/os-Linux/skas/mem.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -48,7 +48,7 @@
 static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
 {
 	unsigned long regs[MAX_REG_NR];
-	int n;
+	int n, i;
 	long ret, offset;
 	unsigned long * data;
 	unsigned long * syscall;
@@ -66,9 +66,13 @@
 		 (unsigned long) &__syscall_stub_start);
 
 	n = ptrace_setregs(pid, regs);
-	if(n < 0)
+	if(n < 0){
+		printk("Registers - \n");
+		for(i = 0; i < MAX_REG_NR; i++)
+			printk("\t%d\t0x%lx\n", i, regs[i]);
 		panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n",
-		      n);
+		      -n);
+	}
 
 	wait_stub_done(pid, 0, "do_syscall_stub");
 
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index dda0678..0564422 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -67,7 +67,7 @@
 
 	if((n < 0) || !WIFSTOPPED(status) ||
 	   (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){
-		unsigned long regs[HOST_FRAME_SIZE];
+		unsigned long regs[MAX_REG_NR];
 
 		if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
 			printk("Failed to get registers from stub, "
@@ -76,7 +76,7 @@
 			int i;
 
 			printk("Stub registers -\n");
-			for(i = 0; i < HOST_FRAME_SIZE; i++)
+			for(i = 0; i < ARRAY_SIZE(regs); i++)
 				printk("\t%d - %lx\n", i, regs[i]);
 		}
 		panic("%s : failed to wait for SIGUSR1/SIGTRAP, "
@@ -328,7 +328,7 @@
 int copy_context_skas0(unsigned long new_stack, int pid)
 {
 	int err;
-	unsigned long regs[HOST_FRAME_SIZE];
+	unsigned long regs[MAX_REG_NR];
 	unsigned long fp_regs[HOST_FP_SIZE];
 	unsigned long current_stack = current_stub_stack();
 	struct stub_data *data = (struct stub_data *) current_stack;
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
index 79cd93c..84b44f9 100644
--- a/arch/um/os-Linux/sys-i386/registers.c
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -15,7 +15,7 @@
 
 /* These are set once at boot time and not changed thereafter */
 
-static unsigned long exec_regs[HOST_FRAME_SIZE];
+static unsigned long exec_regs[MAX_REG_NR];
 static unsigned long exec_fp_regs[HOST_FP_SIZE];
 static unsigned long exec_fpx_regs[HOST_XFP_SIZE];
 static int have_fpx_regs = 1;
@@ -101,6 +101,7 @@
 {
 	int err;
 
+	memset(exec_regs, 0, sizeof(exec_regs));
 	err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
 	if(err)
 		panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
@@ -124,7 +125,7 @@
 
 void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
 {
-	memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
+	memcpy(regs, exec_regs, sizeof(exec_regs));
 	if(fp_regs != NULL)
 		memcpy(fp_regs, exec_fp_regs,
 		       HOST_FP_SIZE * sizeof(unsigned long));
diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c
index a2d7e0c..e6fc217 100644
--- a/arch/um/os-Linux/sys-x86_64/registers.c
+++ b/arch/um/os-Linux/sys-x86_64/registers.c
@@ -14,7 +14,7 @@
 
 /* These are set once at boot time and not changed thereafter */
 
-static unsigned long exec_regs[HOST_FRAME_SIZE];
+static unsigned long exec_regs[MAX_REG_NR];
 static unsigned long exec_fp_regs[HOST_FP_SIZE];
 
 void init_thread_registers(union uml_pt_regs *to)
@@ -72,7 +72,7 @@
 
 void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
 {
-	memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
+	memcpy(regs, exec_regs, sizeof(exec_regs));
 	if(fp_regs != NULL)
 		memcpy(fp_regs, exec_fp_regs,
 		       HOST_FP_SIZE * sizeof(unsigned long));
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index 813077f..a9a4b85 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -10,7 +10,7 @@
 $(USER_OBJS:.o=.%): \
 	c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(basetarget).o)
 $(USER_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \
-	-Dunix -D__unix__ -D__$(SUBARCH)__
+	-Dunix -D__unix__ -D__$(SUBARCH)__ $(CF)
 
 # These are like USER_OBJS but filter USER_CFLAGS through unprofile instead of
 # using it directly.
@@ -19,7 +19,7 @@
 $(UNPROFILE_OBJS:.o=.%): \
 	c_flags = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS)) $(CFLAGS_$(basetarget).o)
 $(UNPROFILE_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \
-	-Dunix -D__unix__ -D__$(SUBARCH)__
+	-Dunix -D__unix__ -D__$(SUBARCH)__ $(CF)
 
 # The stubs and unmap.o can't try to call mcount or update basic block data
 define unprofile
diff --git a/arch/um/sys-i386/delay.c b/arch/um/sys-i386/delay.c
index 2c11b97..d623e07 100644
--- a/arch/um/sys-i386/delay.c
+++ b/arch/um/sys-i386/delay.c
@@ -27,14 +27,3 @@
 }
 
 EXPORT_SYMBOL(__udelay);
-
-void __const_udelay(unsigned long usecs)
-{
-	int i, n;
-
-	n = (loops_per_jiffy * HZ * usecs) / MILLION;
-        for(i=0;i<n;i++)
-                cpu_relax();
-}
-
-EXPORT_SYMBOL(__const_udelay);
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index 4a8b420..a939a7e 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -394,7 +394,8 @@
 static void ldt_get_host_info(void)
 {
 	long ret;
-	struct ldt_entry * ldt, *tmp;
+	struct ldt_entry * ldt;
+	short *tmp;
 	int i, size, k, order;
 
 	spin_lock(&host_ldt_lock);
diff --git a/arch/um/sys-x86_64/delay.c b/arch/um/sys-x86_64/delay.c
index 137f444..dee5be6 100644
--- a/arch/um/sys-x86_64/delay.c
+++ b/arch/um/sys-x86_64/delay.c
@@ -28,14 +28,3 @@
 }
 
 EXPORT_SYMBOL(__udelay);
-
-void __const_udelay(unsigned long usecs)
-{
-	unsigned long i, n;
-
-	n = (loops_per_jiffy * HZ * usecs) / MILLION;
-        for(i=0;i<n;i++)
-                cpu_relax();
-}
-
-EXPORT_SYMBOL(__const_udelay);
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
index 01b91f9..b3f6350 100644
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -103,6 +103,9 @@
 
         switch(code){
 	case ARCH_SET_FS:
+		current->thread.arch.fs = (unsigned long) ptr;
+		save_registers(pid, &current->thread.regs.regs);
+		break;
 	case ARCH_SET_GS:
                 save_registers(pid, &current->thread.regs.regs);
 		break;
@@ -140,9 +143,8 @@
 
 void arch_switch_to_skas(struct task_struct *from, struct task_struct *to)
 {
-        if(to->thread.arch.fs == 0)
+        if((to->thread.arch.fs == 0) || (to->mm == NULL))
                 return;
 
         arch_prctl_skas(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs);
 }
-
diff --git a/arch/x86_64/boot/video.S b/arch/x86_64/boot/video.S
index d6ff88f..6090516 100644
--- a/arch/x86_64/boot/video.S
+++ b/arch/x86_64/boot/video.S
@@ -571,6 +571,16 @@
 	jmp	_m_s
 
 check_vesa:
+#ifdef CONFIG_FIRMWARE_EDID
+	leaw	modelist+1024, %di
+	movw	$0x4f00, %ax
+	int	$0x10
+	cmpw	$0x004f, %ax
+	jnz	setbad
+
+	movw	4(%di), %ax
+	movw	%ax, vbe_version
+#endif
 	leaw	modelist+1024, %di
 	subb	$VIDEO_FIRST_VESA>>8, %bh
 	movw	%bx, %cx			# Get mode information structure
@@ -1945,6 +1955,9 @@
 	rep
 	stosl
 
+	cmpw	$0x0200, vbe_version		# only do EDID on >= VBE2.0
+	jl	no_edid
+
 	pushw   %es				# save ES
 	xorw    %di, %di                        # Report Capability
 	pushw   %di
@@ -1987,6 +2000,7 @@
 svga_prefix:	.byte	VIDEO_FIRST_BIOS>>8	# Default prefix for BIOS modes
 graphic_mode:	.byte	0	# Graphic mode with a linear frame buffer
 dac_size:	.byte	6	# DAC bit depth
+vbe_version:	.word	0	# VBE bios version
 
 # Status messages
 keymsg:		.ascii	"Press <RETURN> to see video modes available, "
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
index 293a4a4..7a1e251 100644
--- a/arch/x86_64/defconfig
+++ b/arch/x86_64/defconfig
@@ -1,11 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20-git8
-# Tue Feb 13 11:25:16 2007
+# Linux kernel version: 2.6.21-rc3
+# Wed Mar  7 15:29:47 2007
 #
 CONFIG_X86_64=y
 CONFIG_64BIT=y
 CONFIG_X86=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_ZONE_DMA32=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -43,6 +45,7 @@
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
@@ -53,6 +56,7 @@
 # CONFIG_CPUSETS is not set
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
@@ -114,11 +118,11 @@
 # CONFIG_X86_VSMP is not set
 # CONFIG_MK8 is not set
 # CONFIG_MPSC is not set
-CONFIG_MCORE2=y
-# CONFIG_GENERIC_CPU is not set
-CONFIG_X86_L1_CACHE_BYTES=64
-CONFIG_X86_L1_CACHE_SHIFT=6
-CONFIG_X86_INTERNODE_CACHE_BYTES=64
+# CONFIG_MCORE2 is not set
+CONFIG_GENERIC_CPU=y
+CONFIG_X86_L1_CACHE_BYTES=128
+CONFIG_X86_L1_CACHE_SHIFT=7
+CONFIG_X86_INTERNODE_CACHE_BYTES=128
 CONFIG_X86_TSC=y
 CONFIG_X86_GOOD_APIC=y
 # CONFIG_MICROCODE is not set
@@ -207,10 +211,8 @@
 CONFIG_ACPI_AC=y
 CONFIG_ACPI_BATTERY=y
 CONFIG_ACPI_BUTTON=y
-# CONFIG_ACPI_HOTKEY is not set
 CONFIG_ACPI_FAN=y
 # CONFIG_ACPI_DOCK is not set
-# CONFIG_ACPI_BAY is not set
 CONFIG_ACPI_PROCESSOR=y
 CONFIG_ACPI_HOTPLUG_CPU=y
 CONFIG_ACPI_THERMAL=y
@@ -319,7 +321,7 @@
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
 # CONFIG_INET_XFRM_MODE_TRANSPORT is not set
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_BEET is not set
@@ -421,7 +423,13 @@
 #
 # Plug and Play support
 #
-# CONFIG_PNP is not set
+CONFIG_PNP=y
+# CONFIG_PNP_DEBUG is not set
+
+#
+# Protocols
+#
+CONFIG_PNPACPI=y
 
 #
 # Block devices
@@ -441,7 +449,6 @@
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
@@ -451,6 +458,7 @@
 # CONFIG_IBM_ASM is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
+# CONFIG_SONY_LAPTOP is not set
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -477,6 +485,7 @@
 #
 CONFIG_IDE_GENERIC=y
 # CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_IDEPNP is not set
 CONFIG_BLK_DEV_IDEPCI=y
 # CONFIG_IDEPCI_SHARE_IRQ is not set
 # CONFIG_BLK_DEV_OFFBOARD is not set
@@ -623,6 +632,7 @@
 # CONFIG_SATA_VITESSE is not set
 # CONFIG_SATA_INIC162X is not set
 CONFIG_SATA_INTEL_COMBINED=y
+CONFIG_SATA_ACPI=y
 # CONFIG_PATA_ALI is not set
 # CONFIG_PATA_AMD is not set
 # CONFIG_PATA_ARTOP is not set
@@ -726,6 +736,7 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 CONFIG_TUN=y
+# CONFIG_NET_SB1000 is not set
 
 #
 # ARCnet devices
@@ -920,6 +931,7 @@
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_PNP=y
 CONFIG_SERIAL_8250_NR_UARTS=4
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
@@ -1001,6 +1013,7 @@
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PASEMI is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_I2C_SIS5595 is not set
@@ -1047,6 +1060,7 @@
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_K8TEMP is not set
@@ -1090,6 +1104,11 @@
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -1103,7 +1122,7 @@
 #
 # Graphics support
 #
-# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 # CONFIG_FB is not set
 
 #
@@ -1114,7 +1133,6 @@
 CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=256
 CONFIG_VIDEO_SELECT=y
 CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -1130,9 +1148,8 @@
 # Open Sound System
 #
 CONFIG_SOUND_PRIME=y
-CONFIG_OBSOLETE_OSS=y
+# CONFIG_OBSOLETE_OSS is not set
 # CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_ES1371 is not set
 CONFIG_SOUND_ICH=y
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
@@ -1263,6 +1280,7 @@
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1273,6 +1291,7 @@
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
 # CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1538,6 +1557,7 @@
 CONFIG_LOG_BUF_SHIFT=18
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
@@ -1556,6 +1576,7 @@
 # CONFIG_FORCED_INLINING is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
 # CONFIG_DEBUG_RODATA is not set
 # CONFIG_IOMMU_DEBUG is not set
 CONFIG_DEBUG_STACKOVERFLOW=y
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index eda7a0d..796df69 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -560,7 +560,7 @@
 	.quad sys_sched_yield
 	.quad sys_sched_get_priority_max
 	.quad sys_sched_get_priority_min  /* 160 */
-	.quad sys_sched_rr_get_interval
+	.quad sys32_sched_rr_get_interval
 	.quad compat_sys_nanosleep
 	.quad sys_mremap
 	.quad sys_setresuid16
diff --git a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c
index 04566fe..4de3a543 100644
--- a/arch/x86_64/ia32/ptrace32.c
+++ b/arch/x86_64/ia32/ptrace32.c
@@ -243,6 +243,7 @@
 	case PTRACE_SINGLESTEP:
 	case PTRACE_DETACH:
 	case PTRACE_SYSCALL:
+	case PTRACE_OLDSETOPTIONS:
 	case PTRACE_SETOPTIONS:
 	case PTRACE_SET_THREAD_AREA:
 	case PTRACE_GET_THREAD_AREA:
diff --git a/arch/x86_64/kernel/acpi/sleep.c b/arch/x86_64/kernel/acpi/sleep.c
index 23178ce..e1548fb 100644
--- a/arch/x86_64/kernel/acpi/sleep.c
+++ b/arch/x86_64/kernel/acpi/sleep.c
@@ -66,8 +66,10 @@
 {
 	pgd_t *slot0 = pgd_offset(current->mm, 0UL);
 	low_ptr = *slot0;
+	/* FIXME: We're playing with the current task's page tables here, which
+	 * is potentially dangerous on SMP systems.
+	 */
 	set_pgd(slot0, *pgd_offset(current->mm, PAGE_OFFSET));
-	WARN_ON(num_online_cpus() != 1);
 	local_flush_tlb();
 }
 
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index 723417d..bd3e45d 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -47,6 +47,10 @@
 
 int disable_apic_timer __initdata;
 
+/* Local APIC timer works in C2? */
+int local_apic_timer_c2_ok;
+EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);
+
 static struct resource *ioapic_resources;
 static struct resource lapic_resource = {
 	.name = "Local APIC",
@@ -930,9 +934,17 @@
 
 void smp_send_timer_broadcast_ipi(void)
 {
+	int cpu = smp_processor_id();
 	cpumask_t mask;
 
 	cpus_and(mask, cpu_online_map, timer_interrupt_broadcast_ipi_mask);
+
+	if (cpu_isset(cpu, mask)) {
+		cpu_clear(cpu, mask);
+		add_pda(apic_timer_irqs, 1);
+		smp_local_timer_interrupt();
+	}
+
 	if (!cpus_empty(mask)) {
 		send_IPI_mask(mask, LOCAL_TIMER_VECTOR);
 	}
@@ -1192,6 +1204,13 @@
 } 
 early_param("nolapic", setup_nolapic);
 
+static int __init parse_lapic_timer_c2_ok(char *arg)
+{
+	local_apic_timer_c2_ok = 1;
+	return 0;
+}
+early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok);
+
 static __init int setup_noapictimer(char *str) 
 { 
 	if (str[0] != ' ' && str[0] != 0)
diff --git a/arch/x86_64/kernel/cpufreq/Kconfig b/arch/x86_64/kernel/cpufreq/Kconfig
index ced15d0..40acb67 100644
--- a/arch/x86_64/kernel/cpufreq/Kconfig
+++ b/arch/x86_64/kernel/cpufreq/Kconfig
@@ -75,6 +75,7 @@
 config X86_P4_CLOCKMOD
 	tristate "Intel Pentium 4 clock modulation"
 	depends on EMBEDDED
+	select CPU_FREQ_TABLE
 	help
 	  This adds the clock modulation driver for Intel Pentium 4 / XEON
 	  processors.  When enabled it will lower CPU temperature by skipping
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
index 4651fd2..a490fab 100644
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -662,7 +662,7 @@
 }
 early_param("memmap", parse_memmap_opt);
 
-void finish_e820_parsing(void)
+void __init finish_e820_parsing(void)
 {
 	if (userdef) {
 		printk(KERN_INFO "user-defined physical RAM map:\n");
diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c
index 8047ea8..fede55a 100644
--- a/arch/x86_64/kernel/early-quirks.c
+++ b/arch/x86_64/kernel/early-quirks.c
@@ -16,7 +16,7 @@
 #include <asm/proto.h>
 #include <asm/dma.h>
 
-static void via_bugs(void)
+static void __init via_bugs(void)
 {
 #ifdef CONFIG_IOMMU
 	if ((end_pfn > MAX_DMA32_PFN ||  force_iommu) &&
@@ -30,16 +30,13 @@
 
 #ifdef CONFIG_ACPI
 
-static int nvidia_hpet_detected __initdata;
-
 static int __init nvidia_hpet_check(struct acpi_table_header *header)
 {
-	nvidia_hpet_detected = 1;
 	return 0;
 }
 #endif
 
-static void nvidia_bugs(void)
+static void __init nvidia_bugs(void)
 {
 #ifdef CONFIG_ACPI
 	/*
@@ -52,11 +49,7 @@
 	if (acpi_use_timer_override)
 		return;
 
-	nvidia_hpet_detected = 0;
-	if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check))
-		return;
-
-	if (nvidia_hpet_detected == 0) {
+	if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check)) {
 		acpi_skip_timer_override = 1;
 		printk(KERN_INFO "Nvidia board "
 		       "detected. Ignoring ACPI "
@@ -69,7 +62,7 @@
 
 }
 
-static void ati_bugs(void)
+static void __init ati_bugs(void)
 {
 	if (timer_over_8254 == 1) {
 		timer_over_8254 = 0;
@@ -95,7 +88,7 @@
 	void (*f)(void);
 };
 
-static struct chipset early_qrk[] = {
+static struct chipset early_qrk[] __initdata = {
 	{ PCI_VENDOR_ID_NVIDIA, nvidia_bugs },
 	{ PCI_VENDOR_ID_VIA, via_bugs },
 	{ PCI_VENDOR_ID_ATI, ati_bugs },
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c
index 21d95b7..4894266 100644
--- a/arch/x86_64/kernel/i8259.c
+++ b/arch/x86_64/kernel/i8259.c
@@ -45,7 +45,7 @@
 
 /*
  * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts:
- * (these are usually mapped to vectors 0x20-0x2f)
+ * (these are usually mapped to vectors 0x30-0x3f)
  */
 
 /*
@@ -299,7 +299,7 @@
 	 * outb_p - this has to work on a wide range of PC hardware.
 	 */
 	outb_p(0x11, 0x20);	/* ICW1: select 8259A-1 init */
-	outb_p(IRQ0_VECTOR, 0x21);	/* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
+	outb_p(IRQ0_VECTOR, 0x21);	/* ICW2: 8259A-1 IR0-7 mapped to 0x30-0x37 */
 	outb_p(0x04, 0x21);	/* 8259A-1 (the master) has a slave on IR2 */
 	if (auto_eoi)
 		outb_p(0x03, 0x21);	/* master does Auto EOI */
@@ -307,7 +307,7 @@
 		outb_p(0x01, 0x21);	/* master expects normal EOI */
 
 	outb_p(0x11, 0xA0);	/* ICW1: select 8259A-2 init */
-	outb_p(IRQ8_VECTOR, 0xA1);	/* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */
+	outb_p(IRQ8_VECTOR, 0xA1);	/* ICW2: 8259A-2 IR0-7 mapped to 0x38-0x3f */
 	outb_p(0x02, 0xA1);	/* 8259A-2 is a slave on master's IR2 */
 	outb_p(0x01, 0xA1);	/* (slave's support for AEOI in flat mode
 				    is to be investigated) */
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index 50dd8be..455aa0b 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -60,9 +60,9 @@
 /* Processor that is doing the boot up */
 unsigned int boot_cpu_id = -1U;
 /* Internal processor count */
-unsigned int num_processors __initdata = 0;
+unsigned int num_processors __cpuinitdata = 0;
 
-unsigned disabled_cpus __initdata;
+unsigned disabled_cpus __cpuinitdata;
 
 /* Bitmask of physically existing CPUs */
 physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE;
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index 486f4c6..a90996c 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -108,64 +108,128 @@
 /* checks for a bit availability (hack for oprofile) */
 int avail_to_resrv_perfctr_nmi_bit(unsigned int counter)
 {
+	int cpu;
 	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
-
-	return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner)));
+	for_each_possible_cpu (cpu) {
+		if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)))
+			return 0;
+	}
+	return 1;
 }
 
 /* checks the an msr for availability */
 int avail_to_resrv_perfctr_nmi(unsigned int msr)
 {
 	unsigned int counter;
+	int cpu;
 
 	counter = nmi_perfctr_msr_to_bit(msr);
 	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
 
-	return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner)));
+	for_each_possible_cpu (cpu) {
+		if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)))
+			return 0;
+	}
+	return 1;
+}
+
+static int __reserve_perfctr_nmi(int cpu, unsigned int msr)
+{
+	unsigned int counter;
+	if (cpu < 0)
+		cpu = smp_processor_id();
+
+	counter = nmi_perfctr_msr_to_bit(msr);
+	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
+
+	if (!test_and_set_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)))
+		return 1;
+	return 0;
+}
+
+static void __release_perfctr_nmi(int cpu, unsigned int msr)
+{
+	unsigned int counter;
+	if (cpu < 0)
+		cpu = smp_processor_id();
+
+	counter = nmi_perfctr_msr_to_bit(msr);
+	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
+
+	clear_bit(counter, &per_cpu(perfctr_nmi_owner, cpu));
 }
 
 int reserve_perfctr_nmi(unsigned int msr)
 {
-	unsigned int counter;
-
-	counter = nmi_perfctr_msr_to_bit(msr);
-	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
-
-	if (!test_and_set_bit(counter, &__get_cpu_var(perfctr_nmi_owner)))
-		return 1;
-	return 0;
+	int cpu, i;
+	for_each_possible_cpu (cpu) {
+		if (!__reserve_perfctr_nmi(cpu, msr)) {
+			for_each_possible_cpu (i) {
+				if (i >= cpu)
+					break;
+				__release_perfctr_nmi(i, msr);
+			}
+			return 0;
+		}
+	}
+	return 1;
 }
 
 void release_perfctr_nmi(unsigned int msr)
 {
-	unsigned int counter;
-
-	counter = nmi_perfctr_msr_to_bit(msr);
-	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
-
-	clear_bit(counter, &__get_cpu_var(perfctr_nmi_owner));
+	int cpu;
+	for_each_possible_cpu (cpu)
+		__release_perfctr_nmi(cpu, msr);
 }
 
-int reserve_evntsel_nmi(unsigned int msr)
+int __reserve_evntsel_nmi(int cpu, unsigned int msr)
 {
 	unsigned int counter;
+	if (cpu < 0)
+		cpu = smp_processor_id();
 
 	counter = nmi_evntsel_msr_to_bit(msr);
 	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
 
-	if (!test_and_set_bit(counter, &__get_cpu_var(evntsel_nmi_owner)))
+	if (!test_and_set_bit(counter, &per_cpu(evntsel_nmi_owner, cpu)[0]))
 		return 1;
 	return 0;
 }
 
-void release_evntsel_nmi(unsigned int msr)
+static void __release_evntsel_nmi(int cpu, unsigned int msr)
 {
 	unsigned int counter;
+	if (cpu < 0)
+		cpu = smp_processor_id();
 
 	counter = nmi_evntsel_msr_to_bit(msr);
 	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
 
-	clear_bit(counter, &__get_cpu_var(evntsel_nmi_owner));
+	clear_bit(counter, &per_cpu(evntsel_nmi_owner, cpu)[0]);
+}
+
+int reserve_evntsel_nmi(unsigned int msr)
+{
+	int cpu, i;
+	for_each_possible_cpu (cpu) {
+		if (!__reserve_evntsel_nmi(cpu, msr)) {
+			for_each_possible_cpu (i) {
+				if (i >= cpu)
+					break;
+				__release_evntsel_nmi(i, msr);
+			}
+			return 0;
+		}
+	}
+	return 1;
+}
+
+void release_evntsel_nmi(unsigned int msr)
+{
+	int cpu;
+	for_each_possible_cpu (cpu) {
+		__release_evntsel_nmi(cpu, msr);
+	}
 }
 
 static __cpuinit inline int nmi_known_cpu(void)
@@ -187,10 +251,7 @@
 {
 	if (nmi_watchdog != NMI_DEFAULT)
 		return;
-	if (nmi_known_cpu())
-		nmi_watchdog = NMI_LOCAL_APIC;
-	else
-		nmi_watchdog = NMI_IO_APIC;
+	nmi_watchdog = NMI_NONE;
 }
 
 static int endflag __initdata = 0;
@@ -256,7 +317,7 @@
 	for (cpu = 0; cpu < NR_CPUS; cpu++)
 		counts[cpu] = cpu_pda(cpu)->__nmi_count;
 	local_irq_enable();
-	mdelay((10*1000)/nmi_hz); // wait 10 ticks
+	mdelay((20*1000)/nmi_hz); // wait 20 ticks
 
 	for_each_online_cpu(cpu) {
 		if (!per_cpu(nmi_watchdog_ctlblk, cpu).enabled)
@@ -475,10 +536,10 @@
 
 	perfctr_msr = MSR_K7_PERFCTR0;
 	evntsel_msr = MSR_K7_EVNTSEL0;
-	if (!reserve_perfctr_nmi(perfctr_msr))
+	if (!__reserve_perfctr_nmi(-1, perfctr_msr))
 		goto fail;
 
-	if (!reserve_evntsel_nmi(evntsel_msr))
+	if (!__reserve_evntsel_nmi(-1, evntsel_msr))
 		goto fail1;
 
 	/* Simulator may not support it */
@@ -504,9 +565,9 @@
 	wd->check_bit = 1ULL<<63;
 	return 1;
 fail2:
-	release_evntsel_nmi(evntsel_msr);
+	__release_evntsel_nmi(-1, evntsel_msr);
 fail1:
-	release_perfctr_nmi(perfctr_msr);
+	__release_perfctr_nmi(-1, perfctr_msr);
 fail:
 	return 0;
 }
@@ -517,8 +578,8 @@
 
 	wrmsr(wd->evntsel_msr, 0, 0);
 
-	release_evntsel_nmi(wd->evntsel_msr);
-	release_perfctr_nmi(wd->perfctr_msr);
+	__release_evntsel_nmi(-1, wd->evntsel_msr);
+	__release_perfctr_nmi(-1, wd->perfctr_msr);
 }
 
 /* Note that these events don't tick when the CPU idles. This means
@@ -584,10 +645,10 @@
 		cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4);
 	}
 
-	if (!reserve_perfctr_nmi(perfctr_msr))
+	if (!__reserve_perfctr_nmi(-1, perfctr_msr))
 		goto fail;
 
-	if (!reserve_evntsel_nmi(evntsel_msr))
+	if (!__reserve_evntsel_nmi(-1, evntsel_msr))
 		goto fail1;
 
 	evntsel = P4_ESCR_EVENT_SELECT(0x3F)
@@ -612,7 +673,7 @@
 	wd->check_bit = 1ULL<<39;
 	return 1;
 fail1:
-	release_perfctr_nmi(perfctr_msr);
+	__release_perfctr_nmi(-1, perfctr_msr);
 fail:
 	return 0;
 }
@@ -624,8 +685,8 @@
 	wrmsr(wd->cccr_msr, 0, 0);
 	wrmsr(wd->evntsel_msr, 0, 0);
 
-	release_evntsel_nmi(wd->evntsel_msr);
-	release_perfctr_nmi(wd->perfctr_msr);
+	__release_evntsel_nmi(-1, wd->evntsel_msr);
+	__release_perfctr_nmi(-1, wd->perfctr_msr);
 }
 
 #define ARCH_PERFMON_NMI_EVENT_SEL	ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL
@@ -653,10 +714,10 @@
 	perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0;
 	evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL0;
 
-	if (!reserve_perfctr_nmi(perfctr_msr))
+	if (!__reserve_perfctr_nmi(-1, perfctr_msr))
 		goto fail;
 
-	if (!reserve_evntsel_nmi(evntsel_msr))
+	if (!__reserve_evntsel_nmi(-1, evntsel_msr))
 		goto fail1;
 
 	wrmsrl(perfctr_msr, 0UL);
@@ -683,7 +744,7 @@
 	wd->check_bit = 1ULL << (eax.split.bit_width - 1);
 	return 1;
 fail1:
-	release_perfctr_nmi(perfctr_msr);
+	__release_perfctr_nmi(-1, perfctr_msr);
 fail:
 	return 0;
 }
@@ -707,8 +768,8 @@
 
 	wrmsr(wd->evntsel_msr, 0, 0);
 
-	release_evntsel_nmi(wd->evntsel_msr);
-	release_perfctr_nmi(wd->perfctr_msr);
+	__release_evntsel_nmi(-1, wd->evntsel_msr);
+	__release_perfctr_nmi(-1, wd->perfctr_msr);
 }
 
 void setup_apic_nmi_watchdog(void *unused)
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
index 030eb37..2bac8c6 100644
--- a/arch/x86_64/kernel/pci-gart.c
+++ b/arch/x86_64/kernel/pci-gart.c
@@ -675,7 +675,7 @@
 	dma_ops = &gart_dma_ops;
 } 
 
-void gart_parse_options(char *p)
+void __init gart_parse_options(char *p)
 {
 	int arg;
 
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index cbbc6ad..d8d5ccc 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -382,14 +382,17 @@
 void flush_thread(void)
 {
 	struct task_struct *tsk = current;
-	struct thread_info *t = current_thread_info();
 
-	if (t->flags & _TIF_ABI_PENDING) {
-		t->flags ^= (_TIF_ABI_PENDING | _TIF_IA32);
-		if (t->flags & _TIF_IA32)
+	if (test_tsk_thread_flag(tsk, TIF_ABI_PENDING)) {
+		clear_tsk_thread_flag(tsk, TIF_ABI_PENDING);
+		if (test_tsk_thread_flag(tsk, TIF_IA32)) {
+			clear_tsk_thread_flag(tsk, TIF_IA32);
+		} else {
+			set_tsk_thread_flag(tsk, TIF_IA32);
 			current_thread_info()->status |= TS_COMPAT;
+		}
 	}
-	t->flags &= ~_TIF_DEBUG;
+	clear_tsk_thread_flag(tsk, TIF_DEBUG);
 
 	tsk->thread.debugreg0 = 0;
 	tsk->thread.debugreg1 = 0;
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 3544372..cd4643a 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -923,8 +923,9 @@
  */
 int __cpuinit __cpu_up(unsigned int cpu)
 {
-	int err;
 	int apicid = cpu_present_to_apicid(cpu);
+	unsigned long flags;
+	int err;
 
 	WARN_ON(irqs_disabled());
 
@@ -958,7 +959,9 @@
 	/*
   	 * Make sure and check TSC sync:
  	 */
+	local_irq_save(flags);
 	check_tsc_sync_source(cpu);
+	local_irq_restore(flags);
 
 	while (!cpu_isset(cpu, cpu_online_map))
 		cpu_relax();
diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c
index 180ff91..b43c698 100644
--- a/arch/x86_64/kernel/vsyscall.c
+++ b/arch/x86_64/kernel/vsyscall.c
@@ -112,7 +112,7 @@
 
 		vread = __vsyscall_gtod_data.clock.vread;
 		if (unlikely(!__vsyscall_gtod_data.sysctl_enabled || !vread)) {
-			gettimeofday(tv,0);
+			gettimeofday(tv,NULL);
 			return;
 		}
 		now = vread();
diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c
index 0dffae6..77c25b3 100644
--- a/arch/x86_64/kernel/x8664_ksyms.c
+++ b/arch/x86_64/kernel/x8664_ksyms.c
@@ -59,3 +59,4 @@
 EXPORT_SYMBOL(init_level4_pgt);
 EXPORT_SYMBOL(load_gs_index);
 
+EXPORT_SYMBOL(_proxy_pda);
diff --git a/block/elevator.c b/block/elevator.c
index 25f6ef2..96a00c8 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -964,17 +964,18 @@
 
 int elv_register(struct elevator_type *e)
 {
+	char *def = "";
 	spin_lock_irq(&elv_list_lock);
 	BUG_ON(elevator_find(e->elevator_name));
 	list_add_tail(&e->list, &elv_list);
 	spin_unlock_irq(&elv_list_lock);
 
-	printk(KERN_INFO "io scheduler %s registered", e->elevator_name);
 	if (!strcmp(e->elevator_name, chosen_elevator) ||
 			(!*chosen_elevator &&
 			 !strcmp(e->elevator_name, CONFIG_DEFAULT_IOSCHED)))
-				printk(" (default)");
-	printk("\n");
+				def = " (default)";
+
+	printk(KERN_INFO "io scheduler %s registered%s\n", e->elevator_name, def);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(elv_register);
diff --git a/block/genhd.c b/block/genhd.c
index 050a1f0..441432a 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -62,8 +62,6 @@
 	/* temporary */
 	if (major == 0) {
 		for (index = ARRAY_SIZE(major_names)-1; index > 0; index--) {
-			if (is_lanana_major(index))
-				continue;
 			if (major_names[index] == NULL)
 				break;
 		}
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 38c293b..3de0695 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1221,7 +1221,7 @@
 		 * considered part of another segment, since that might
 		 * change with the bounce page.
 		 */
-		high = page_to_pfn(bv->bv_page) >= q->bounce_pfn;
+		high = page_to_pfn(bv->bv_page) > q->bounce_pfn;
 		if (high || highprv)
 			goto new_hw_segment;
 		if (cluster) {
@@ -3658,8 +3658,8 @@
 	open_softirq(BLOCK_SOFTIRQ, blk_done_softirq, NULL);
 	register_hotcpu_notifier(&blk_cpu_notifier);
 
-	blk_max_low_pfn = max_low_pfn;
-	blk_max_pfn = max_pfn;
+	blk_max_low_pfn = max_low_pfn - 1;
+	blk_max_pfn = max_pfn - 1;
 
 	return 0;
 }
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
index 35172d3..81afd17 100644
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -59,8 +59,12 @@
 static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
 				 unsigned int more)
 {
-	if (out)
-		flush_dcache_page(scatterwalk_page(walk));
+	if (out) {
+		struct page *page;
+
+		page = walk->sg->page + ((walk->offset - 1) >> PAGE_SHIFT);
+		flush_dcache_page(page);
+	}
 
 	if (more) {
 		walk->offset += PAGE_SIZE - 1;
@@ -91,6 +95,8 @@
 		memcpy_dir(buf, vaddr, len_this_page, out);
 		scatterwalk_unmap(vaddr, out);
 
+		scatterwalk_advance(walk, len_this_page);
+
 		if (nbytes == len_this_page)
 			break;
 
@@ -99,7 +105,5 @@
 
 		scatterwalk_pagedone(walk, out, 1);
 	}
-
-	scatterwalk_advance(walk, nbytes);
 }
 EXPORT_SYMBOL_GPL(scatterwalk_copychunks);
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index f5e9da3..8eaa5aa 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -768,7 +768,7 @@
 	tv = (void *)tvmem;
 
 	tfm = crypto_alloc_comp("deflate", 0, CRYPTO_ALG_ASYNC);
-	if (tfm == NULL) {
+	if (IS_ERR(tfm)) {
 		printk("failed to load transform for deflate\n");
 		return;
 	}
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 7c49e10..e2ce4a9 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -7,6 +7,7 @@
 	depends on !X86_VISWS
 	depends on !IA64_HP_SIM
 	depends on IA64 || X86
+	depends on PM
 
 config ACPI
 	bool "ACPI Support"
@@ -243,6 +244,17 @@
 
 	  If you are not sure, say N here.
 
+config ACPI_IBM_BAY
+	bool "Legacy Removable Bay Support"
+	depends on ACPI_IBM
+	default y
+	---help---
+	  Allows the ibm_acpi driver to handle removable bays.  It will allow
+	  disabling the device in the bay, and also generate notifications when
+	  the bay lever is ejected or inserted.
+
+	  If you are not sure, say Y here.
+
 config ACPI_TOSHIBA
 	tristate "Toshiba Laptop Extras"
 	depends on X86
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
index f289fd4..3ec110c 100644
--- a/drivers/acpi/blacklist.c
+++ b/drivers/acpi/blacklist.c
@@ -79,11 +79,17 @@
 {
 	int year = dmi_get_year(DMI_BIOS_DATE);
 	/* Doesn't exist? Likely an old system */
-	if (year == -1)
+	if (year == -1) {
+		printk(KERN_ERR PREFIX "no DMI BIOS year, "
+			"acpi=force is required to enable ACPI\n" );
 		return 1;
+	}
 	/* 0? Likely a buggy new BIOS */
-	if (year == 0)
+	if (year == 0) {
+		printk(KERN_ERR PREFIX "DMI BIOS year==0, "
+			"assuming ACPI-capable machine\n" );
 		return 0;
+	}
 	if (year < CONFIG_ACPI_BLACKLIST_YEAR) {
 		printk(KERN_ERR PREFIX "BIOS age (%d) fails cutoff (%d), "
 		       "acpi=force is required to enable ACPI\n",
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index ab68883..a802962 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -100,6 +100,7 @@
 	unsigned long global_lock;
 	struct mutex lock;
 	atomic_t query_pending;
+	atomic_t event_count;
 	atomic_t leaving_burst;	/* 0 : No, 1 : Yes, 2: abort */
 	wait_queue_head_t wait;
 } *ec_ecdt;
@@ -131,10 +132,12 @@
 	outb(data, ec->data_addr);
 }
 
-static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
+static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event,
+				       unsigned old_count)
 {
 	u8 status = acpi_ec_read_status(ec);
-
+	if (old_count == atomic_read(&ec->event_count))
+		return 0;
 	if (event == ACPI_EC_EVENT_OBF_1) {
 		if (status & ACPI_EC_FLAG_OBF)
 			return 1;
@@ -146,19 +149,19 @@
 	return 0;
 }
 
-static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event)
+static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, unsigned count)
 {
 	if (acpi_ec_mode == EC_POLL) {
 		unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
 		while (time_before(jiffies, delay)) {
-			if (acpi_ec_check_status(ec, event))
+			if (acpi_ec_check_status(ec, event, 0))
 				return 0;
 		}
 	} else {
 		if (wait_event_timeout(ec->wait,
-				       acpi_ec_check_status(ec, event),
+				       acpi_ec_check_status(ec, event, count),
 				       msecs_to_jiffies(ACPI_EC_DELAY)) ||
-		    acpi_ec_check_status(ec, event)) {
+		    acpi_ec_check_status(ec, event, 0)) {
 			return 0;
 		} else {
 			printk(KERN_ERR PREFIX "acpi_ec_wait timeout,"
@@ -225,21 +228,22 @@
 					u8 * rdata, unsigned rdata_len)
 {
 	int result = 0;
-
+	unsigned count = atomic_read(&ec->event_count);
 	acpi_ec_write_cmd(ec, command);
 
 	for (; wdata_len > 0; --wdata_len) {
-		result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
+		result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, count);
 		if (result) {
 			printk(KERN_ERR PREFIX
 			       "write_cmd timeout, command = %d\n", command);
 			goto end;
 		}
+		count = atomic_read(&ec->event_count);
 		acpi_ec_write_data(ec, *(wdata++));
 	}
 
 	if (!rdata_len) {
-		result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
+		result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, count);
 		if (result) {
 			printk(KERN_ERR PREFIX
 			       "finish-write timeout, command = %d\n", command);
@@ -250,13 +254,13 @@
 	}
 
 	for (; rdata_len > 0; --rdata_len) {
-		result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1);
+		result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, count);
 		if (result) {
 			printk(KERN_ERR PREFIX "read timeout, command = %d\n",
 			       command);
 			goto end;
 		}
-
+		count = atomic_read(&ec->event_count);
 		*(rdata++) = acpi_ec_read_data(ec);
 	}
       end:
@@ -288,7 +292,7 @@
 	/* Make sure GPE is enabled before doing transaction */
 	acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
 
-	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
+	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0);
 	if (status) {
 		printk(KERN_DEBUG PREFIX
 		       "input buffer is not empty, aborting transaction\n");
@@ -369,8 +373,8 @@
 EXPORT_SYMBOL(ec_write);
 
 int ec_transaction(u8 command,
-			  const u8 * wdata, unsigned wdata_len,
-			  u8 * rdata, unsigned rdata_len)
+		   const u8 * wdata, unsigned wdata_len,
+		   u8 * rdata, unsigned rdata_len)
 {
 	struct acpi_ec *ec;
 
@@ -435,7 +439,7 @@
 	acpi_status status = AE_OK;
 	u8 value;
 	struct acpi_ec *ec = (struct acpi_ec *)data;
-
+	atomic_inc(&ec->event_count);
 	if (acpi_ec_mode == EC_INTR) {
 		wake_up(&ec->wait);
 	}
@@ -633,6 +637,7 @@
 	ec->uid = -1;
 	mutex_init(&ec->lock);
 	atomic_set(&ec->query_pending, 0);
+	atomic_set(&ec->event_count, 1);
 	if (acpi_ec_mode == EC_INTR) {
 		atomic_set(&ec->leaving_burst, 1);
 		init_waitqueue_head(&ec->wait);
@@ -807,6 +812,7 @@
 	acpi_status status;
 
 	mutex_init(&ec_ecdt->lock);
+	atomic_set(&ec_ecdt->event_count, 1);
 	if (acpi_ec_mode == EC_INTR) {
 		init_waitqueue_head(&ec_ecdt->wait);
 	}
@@ -888,6 +894,7 @@
 		return -ENOMEM;
 
 	mutex_init(&ec_ecdt->lock);
+	atomic_set(&ec_ecdt->event_count, 1);
 	if (acpi_ec_mode == EC_INTR) {
 		init_waitqueue_head(&ec_ecdt->wait);
 	}
@@ -1016,8 +1023,7 @@
 		acpi_ec_mode = EC_POLL;
 	}
 	acpi_ec_driver.ops.add = acpi_ec_add;
-	printk(KERN_NOTICE PREFIX "%s mode.\n",
-			  intr ? "interrupt" : "polling");
+	printk(KERN_NOTICE PREFIX "%s mode.\n", intr ? "interrupt" : "polling");
 
 	return 1;
 }
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index d572700..cae786c 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -196,11 +196,15 @@
 		notify_info->notify.value = (u16) notify_value;
 		notify_info->notify.handler_obj = handler_obj;
 
-		acpi_ex_relinquish_interpreter();
+		acpi_ex_exit_interpreter();
 
 		acpi_ev_notify_dispatch(notify_info);
 
-		acpi_ex_reacquire_interpreter();
+		status = acpi_ex_enter_interpreter();
+		if (ACPI_FAILURE(status)) {
+			return_ACPI_STATUS(status);
+		}
+
 	}
 
 	if (!handler_obj) {
@@ -423,6 +427,8 @@
  * the global lock appear as a standard mutex on the OS side.
  *
  *****************************************************************************/
+static acpi_thread_id acpi_ev_global_lock_thread_id;
+static int acpi_ev_global_lock_acquired;
 
 acpi_status acpi_ev_acquire_global_lock(u16 timeout)
 {
@@ -435,11 +441,24 @@
 	 * Only one thread can acquire the GL at a time, the global_lock_mutex
 	 * enforces this. This interface releases the interpreter if we must wait.
 	 */
-	status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, timeout);
+	status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, 0);
+	if (status == AE_TIME) {
+		if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) {
+			acpi_ev_global_lock_acquired++;
+			return AE_OK;
+		}
+	}
+
+	if (ACPI_FAILURE(status)) {
+		status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, timeout);
+	}
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
 
+	acpi_ev_global_lock_thread_id = acpi_os_get_thread_id();
+	acpi_ev_global_lock_acquired++;
+
 	/*
 	 * Make sure that a global lock actually exists. If not, just treat
 	 * the lock as a standard mutex.
@@ -506,6 +525,11 @@
 		return_ACPI_STATUS(AE_NOT_ACQUIRED);
 	}
 
+	acpi_ev_global_lock_acquired--;
+	if (acpi_ev_global_lock_acquired > 0) {
+		return AE_OK;
+	}
+
 	if (acpi_gbl_global_lock_present) {
 
 		/* Allow any thread to release the lock */
@@ -529,7 +553,8 @@
 	acpi_gbl_global_lock_acquired = FALSE;
 
 	/* Release the local GL mutex */
-
+	acpi_ev_global_lock_thread_id = NULL;
+	acpi_ev_global_lock_acquired = 0;
 	acpi_os_release_mutex(acpi_gbl_global_lock_mutex);
 	return_ACPI_STATUS(status);
 }
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
index e99f0c4..96b0e84 100644
--- a/drivers/acpi/events/evregion.c
+++ b/drivers/acpi/events/evregion.c
@@ -291,6 +291,7 @@
 			       u32 bit_width, acpi_integer * value)
 {
 	acpi_status status;
+	acpi_status status2;
 	acpi_adr_space_handler handler;
 	acpi_adr_space_setup region_setup;
 	union acpi_operand_object *handler_desc;
@@ -344,7 +345,7 @@
 		 * setup will potentially execute control methods
 		 * (e.g., _REG method for this region)
 		 */
-		acpi_ex_relinquish_interpreter();
+		acpi_ex_exit_interpreter();
 
 		status = region_setup(region_obj, ACPI_REGION_ACTIVATE,
 				      handler_desc->address_space.context,
@@ -352,7 +353,10 @@
 
 		/* Re-enter the interpreter */
 
-		acpi_ex_reacquire_interpreter();
+		status2 = acpi_ex_enter_interpreter();
+		if (ACPI_FAILURE(status2)) {
+			return_ACPI_STATUS(status2);
+		}
 
 		/* Check for failure of the Region Setup */
 
@@ -405,7 +409,7 @@
 		 * exit the interpreter because the handler *might* block -- we don't
 		 * know what it will do, so we can't hold the lock on the intepreter.
 		 */
-		acpi_ex_relinquish_interpreter();
+		acpi_ex_exit_interpreter();
 	}
 
 	/* Call the handler */
@@ -426,7 +430,10 @@
 		 * We just returned from a non-default handler, we must re-enter the
 		 * interpreter
 		 */
-		acpi_ex_reacquire_interpreter();
+		status2 = acpi_ex_enter_interpreter();
+		if (ACPI_FAILURE(status2)) {
+			return_ACPI_STATUS(status2);
+		}
 	}
 
 	return_ACPI_STATUS(status);
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
index 685a103..a3379ba 100644
--- a/drivers/acpi/events/evxface.c
+++ b/drivers/acpi/events/evxface.c
@@ -768,9 +768,11 @@
 		return (AE_BAD_PARAMETER);
 	}
 
-	/* Must lock interpreter to prevent race conditions */
+	status = acpi_ex_enter_interpreter();
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
 
-	acpi_ex_enter_interpreter();
 	status = acpi_ev_acquire_global_lock(timeout);
 	acpi_ex_exit_interpreter();
 
diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c
index 7c38528..ae97812 100644
--- a/drivers/acpi/executer/excreate.c
+++ b/drivers/acpi/executer/excreate.c
@@ -583,7 +583,10 @@
 	 * Get the sync_level. If method is serialized, a mutex will be
 	 * created for this method when it is parsed.
 	 */
-	if (method_flags & AML_METHOD_SERIALIZED) {
+	if (acpi_gbl_all_methods_serialized) {
+		obj_desc->method.sync_level = 0;
+		obj_desc->method.method_flags |= AML_METHOD_SERIALIZED;
+	} else if (method_flags & AML_METHOD_SERIALIZED) {
 		/*
 		 * ACPI 1.0: sync_level = 0
 		 * ACPI 2.0: sync_level = sync_level in method declaration
diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c
index 9460baf..b2edf62 100644
--- a/drivers/acpi/executer/exsystem.c
+++ b/drivers/acpi/executer/exsystem.c
@@ -66,6 +66,7 @@
 acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
 {
 	acpi_status status;
+	acpi_status status2;
 
 	ACPI_FUNCTION_TRACE(ex_system_wait_semaphore);
 
@@ -78,7 +79,7 @@
 
 		/* We must wait, so unlock the interpreter */
 
-		acpi_ex_relinquish_interpreter();
+		acpi_ex_exit_interpreter();
 
 		status = acpi_os_wait_semaphore(semaphore, 1, timeout);
 
@@ -88,7 +89,13 @@
 
 		/* Reacquire the interpreter */
 
-		acpi_ex_reacquire_interpreter();
+		status2 = acpi_ex_enter_interpreter();
+		if (ACPI_FAILURE(status2)) {
+
+			/* Report fatal error, could not acquire interpreter */
+
+			return_ACPI_STATUS(status2);
+		}
 	}
 
 	return_ACPI_STATUS(status);
@@ -112,6 +119,7 @@
 acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
 {
 	acpi_status status;
+	acpi_status status2;
 
 	ACPI_FUNCTION_TRACE(ex_system_wait_mutex);
 
@@ -124,7 +132,7 @@
 
 		/* We must wait, so unlock the interpreter */
 
-		acpi_ex_relinquish_interpreter();
+		acpi_ex_exit_interpreter();
 
 		status = acpi_os_acquire_mutex(mutex, timeout);
 
@@ -134,7 +142,13 @@
 
 		/* Reacquire the interpreter */
 
-		acpi_ex_reacquire_interpreter();
+		status2 = acpi_ex_enter_interpreter();
+		if (ACPI_FAILURE(status2)) {
+
+			/* Report fatal error, could not acquire interpreter */
+
+			return_ACPI_STATUS(status2);
+		}
 	}
 
 	return_ACPI_STATUS(status);
@@ -195,18 +209,20 @@
 
 acpi_status acpi_ex_system_do_suspend(acpi_integer how_long)
 {
+	acpi_status status;
+
 	ACPI_FUNCTION_ENTRY();
 
 	/* Since this thread will sleep, we must release the interpreter */
 
-	acpi_ex_relinquish_interpreter();
+	acpi_ex_exit_interpreter();
 
 	acpi_os_sleep(how_long);
 
 	/* And now we must get the interpreter again */
 
-	acpi_ex_reacquire_interpreter();
-	return (AE_OK);
+	status = acpi_ex_enter_interpreter();
+	return (status);
 }
 
 /*******************************************************************************
diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c
index 6b0aecc..aea461f 100644
--- a/drivers/acpi/executer/exutils.c
+++ b/drivers/acpi/executer/exutils.c
@@ -76,15 +76,14 @@
  *
  * PARAMETERS:  None
  *
- * RETURN:      None
+ * RETURN:      Status
  *
- * DESCRIPTION: Enter the interpreter execution region. Failure to enter
- *              the interpreter region is a fatal system error. Used in
- *              conjunction with exit_interpreter.
+ * DESCRIPTION: Enter the interpreter execution region.  Failure to enter
+ *              the interpreter region is a fatal system error
  *
  ******************************************************************************/
 
-void acpi_ex_enter_interpreter(void)
+acpi_status acpi_ex_enter_interpreter(void)
 {
 	acpi_status status;
 
@@ -92,42 +91,10 @@
 
 	status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
 	if (ACPI_FAILURE(status)) {
-		ACPI_ERROR((AE_INFO,
-			    "Could not acquire AML Interpreter mutex"));
+		ACPI_ERROR((AE_INFO, "Could not acquire interpreter mutex"));
 	}
 
-	return_VOID;
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ex_reacquire_interpreter
- *
- * PARAMETERS:  None
- *
- * RETURN:      None
- *
- * DESCRIPTION: Reacquire the interpreter execution region from within the
- *              interpreter code. Failure to enter the interpreter region is a
- *              fatal system error. Used in  conjuction with
- *              relinquish_interpreter
- *
- ******************************************************************************/
-
-void acpi_ex_reacquire_interpreter(void)
-{
-	ACPI_FUNCTION_TRACE(ex_reacquire_interpreter);
-
-	/*
-	 * If the global serialized flag is set, do not release the interpreter,
-	 * since it was not actually released by acpi_ex_relinquish_interpreter.
-	 * This forces the interpreter to be single threaded.
-	 */
-	if (!acpi_gbl_all_methods_serialized) {
-		acpi_ex_enter_interpreter();
-	}
-
-	return_VOID;
+	return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
@@ -138,9 +105,17 @@
  *
  * RETURN:      None
  *
- * DESCRIPTION: Exit the interpreter execution region. This is the top level
- *              routine used to exit the interpreter when all processing has
- *              been completed.
+ * DESCRIPTION: Exit the interpreter execution region
+ *
+ * Cases where the interpreter is unlocked:
+ *      1) Completion of the execution of a control method
+ *      2) Method blocked on a Sleep() AML opcode
+ *      3) Method blocked on an Acquire() AML opcode
+ *      4) Method blocked on a Wait() AML opcode
+ *      5) Method blocked to acquire the global lock
+ *      6) Method blocked to execute a serialized control method that is
+ *          already executing
+ *      7) About to invoke a user-installed opregion handler
  *
  ******************************************************************************/
 
@@ -152,46 +127,7 @@
 
 	status = acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
 	if (ACPI_FAILURE(status)) {
-		ACPI_ERROR((AE_INFO,
-			    "Could not release AML Interpreter mutex"));
-	}
-
-	return_VOID;
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ex_relinquish_interpreter
- *
- * PARAMETERS:  None
- *
- * RETURN:      None
- *
- * DESCRIPTION: Exit the interpreter execution region, from within the
- *              interpreter - before attempting an operation that will possibly
- *              block the running thread.
- *
- * Cases where the interpreter is unlocked internally
- *      1) Method to be blocked on a Sleep() AML opcode
- *      2) Method to be blocked on an Acquire() AML opcode
- *      3) Method to be blocked on a Wait() AML opcode
- *      4) Method to be blocked to acquire the global lock
- *      5) Method to be blocked waiting to execute a serialized control method
- *          that is currently executing
- *      6) About to invoke a user-installed opregion handler
- *
- ******************************************************************************/
-
-void acpi_ex_relinquish_interpreter(void)
-{
-	ACPI_FUNCTION_TRACE(ex_relinquish_interpreter);
-
-	/*
-	 * If the global serialized flag is set, do not release the interpreter.
-	 * This forces the interpreter to be single threaded.
-	 */
-	if (!acpi_gbl_all_methods_serialized) {
-		acpi_ex_exit_interpreter();
+		ACPI_ERROR((AE_INFO, "Could not release interpreter mutex"));
 	}
 
 	return_VOID;
@@ -205,8 +141,8 @@
  *
  * RETURN:      none
  *
- * DESCRIPTION: Truncate an ACPI Integer to 32 bits if the execution mode is
- *              32-bit, as determined by the revision of the DSDT.
+ * DESCRIPTION: Truncate a number to 32-bits if the currently executing method
+ *              belongs to a 32-bit ACPI table.
  *
  ******************************************************************************/
 
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index 8fa9312..c84b1fa 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -300,6 +300,11 @@
 	/*
 	 * 2) Enable all wakeup GPEs
 	 */
+	status = acpi_hw_disable_all_gpes();
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
 	acpi_gbl_system_awake_and_running = FALSE;
 
 	status = acpi_hw_enable_all_wakeup_gpes();
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 4cc534e..dc10966 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -86,6 +86,7 @@
 
 #include <linux/proc_fs.h>
 #include <linux/backlight.h>
+#include <linux/fb.h>
 #include <asm/uaccess.h>
 
 #include <linux/dmi.h>
@@ -157,6 +158,7 @@
 	   "\\_SB.PCI.ISA.SLCE",	/* 570 */
     );				/* A21e,G4x,R30,R31,R32,R40,R40e,R50e */
 #endif
+#ifdef CONFIG_ACPI_IBM_BAY
 IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST",	/* 570 */
 	   "\\_SB.PCI0.IDE0.IDES.IDSM",	/* 600e/x, 770e, 770x */
 	   "\\_SB.PCI0.SATA.SCND.MSTR",	/* T60, X60, Z60 */ 
@@ -174,6 +176,7 @@
 IBM_HANDLE(bay2_ej, bay2, "_EJ3",	/* 600e/x, 770e, A3x */
 	   "_EJ0",		/* 770x */
     );				/* all others */
+#endif /* CONFIG_ACPI_IBM_BAY */
 
 /* don't list other alternatives as we install a notify handler on the 570 */
 IBM_HANDLE(pci, root, "\\_SB.PCI");	/* 570 */
@@ -1044,6 +1047,7 @@
 	return 0;
 }
 
+#if defined(CONFIG_ACPI_IBM_DOCK) || defined(CONFIG_ACPI_IBM_BAY)
 static int _sta(acpi_handle handle)
 {
 	int status;
@@ -1053,6 +1057,7 @@
 
 	return status;
 }
+#endif
 
 #ifdef CONFIG_ACPI_IBM_DOCK
 #define dock_docked() (_sta(dock_handle) & 1)
@@ -1119,6 +1124,7 @@
 }
 #endif
 
+#ifdef CONFIG_ACPI_IBM_BAY
 static int bay_status_supported;
 static int bay_status2_supported;
 static int bay_eject_supported;
@@ -1194,6 +1200,7 @@
 {
 	acpi_bus_generate_event(ibm->device, event, 0);
 }
+#endif /* CONFIG_ACPI_IBM_BAY */
 
 static int cmos_read(char *p)
 {
@@ -1701,7 +1708,10 @@
 
 static int brightness_update_status(struct backlight_device *bd)
 {
-	return brightness_set(bd->props.brightness);
+	return brightness_set(
+		(bd->props.fb_blank == FB_BLANK_UNBLANK &&
+		 bd->props.power == FB_BLANK_UNBLANK) ?
+				bd->props.brightness : 0);
 }
 
 static struct backlight_ops ibm_backlight_data = {
@@ -1711,6 +1721,12 @@
 
 static int brightness_init(void)
 {
+	int b;
+
+	b = brightness_get(NULL);
+	if (b < 0)
+		return b;
+
 	ibm_backlight_device = backlight_device_register("ibm", NULL, NULL,
 							 &ibm_backlight_data);
 	if (IS_ERR(ibm_backlight_device)) {
@@ -1718,7 +1734,9 @@
 		return PTR_ERR(ibm_backlight_device);
 	}
 
-        ibm_backlight_device->props.max_brightness = 7;
+	ibm_backlight_device->props.max_brightness = 7;
+	ibm_backlight_device->props.brightness = b;
+	backlight_update_status(ibm_backlight_device);
 
 	return 0;
 }
@@ -2353,6 +2371,7 @@
 	 .type = ACPI_SYSTEM_NOTIFY,
 	 },
 #endif
+#ifdef CONFIG_ACPI_IBM_BAY
 	{
 	 .name = "bay",
 	 .init = bay_init,
@@ -2362,6 +2381,7 @@
 	 .handle = &bay_handle,
 	 .type = ACPI_SYSTEM_NOTIFY,
 	 },
+#endif /* CONFIG_ACPI_IBM_BAY */
 	{
 	 .name = "cmos",
 	 .read = cmos_read,
@@ -2487,7 +2507,7 @@
 	ret = acpi_bus_get_device(*ibm->handle, &ibm->device);
 	if (ret < 0) {
 		printk(IBM_ERR "%s device not present\n", ibm->name);
-		return 0;
+		return -ENODEV;
 	}
 
 	acpi_driver_data(ibm->device) = ibm;
@@ -2496,8 +2516,13 @@
 	status = acpi_install_notify_handler(*ibm->handle, ibm->type,
 					     dispatch_notify, ibm);
 	if (ACPI_FAILURE(status)) {
-		printk(IBM_ERR "acpi_install_notify_handler(%s) failed: %d\n",
-		       ibm->name, status);
+		if (status == AE_ALREADY_EXISTS) {
+			printk(IBM_NOTICE "another device driver is already handling %s events\n",
+				ibm->name);
+		} else {
+			printk(IBM_ERR "acpi_install_notify_handler(%s) failed: %d\n",
+				ibm->name, status);
+		}
 		return -ENODEV;
 	}
 	ibm->notify_installed = 1;
@@ -2533,6 +2558,8 @@
 	return ret;
 }
 
+static void ibm_exit(struct ibm_struct *ibm);
+
 static int __init ibm_init(struct ibm_struct *ibm)
 {
 	int ret;
@@ -2574,6 +2601,12 @@
 
 	if (ibm->notify) {
 		ret = setup_notify(ibm);
+		if (ret == -ENODEV) {
+			printk(IBM_NOTICE "disabling subdriver %s\n",
+				ibm->name);
+			ibm_exit(ibm);
+			return 0;
+		}
 		if (ret < 0)
 			return ret;
 	}
@@ -2647,7 +2680,9 @@
 #ifdef CONFIG_ACPI_IBM_DOCK
 IBM_PARAM(dock);
 #endif
+#ifdef CONFIG_ACPI_IBM_BAY
 IBM_PARAM(bay);
+#endif /* CONFIG_ACPI_IBM_BAY */
 IBM_PARAM(cmos);
 IBM_PARAM(led);
 IBM_PARAM(beep);
@@ -2723,12 +2758,14 @@
 	IBM_HANDLE_INIT(dock);
 #endif
 	IBM_HANDLE_INIT(pci);
+#ifdef CONFIG_ACPI_IBM_BAY
 	IBM_HANDLE_INIT(bay);
 	if (bay_handle)
 		IBM_HANDLE_INIT(bay_ej);
 	IBM_HANDLE_INIT(bay2);
 	if (bay2_handle)
 		IBM_HANDLE_INIT(bay2_ej);
+#endif /* CONFIG_ACPI_IBM_BAY */
 	IBM_HANDLE_INIT(beep);
 	IBM_HANDLE_INIT(ecrd);
 	IBM_HANDLE_INIT(ecwr);
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c
index aa6370c..26fd0dd 100644
--- a/drivers/acpi/namespace/nseval.c
+++ b/drivers/acpi/namespace/nseval.c
@@ -154,7 +154,11 @@
 		 * Execute the method via the interpreter. The interpreter is locked
 		 * here before calling into the AML parser
 		 */
-		acpi_ex_enter_interpreter();
+		status = acpi_ex_enter_interpreter();
+		if (ACPI_FAILURE(status)) {
+			return_ACPI_STATUS(status);
+		}
+
 		status = acpi_ps_execute_method(info);
 		acpi_ex_exit_interpreter();
 	} else {
@@ -178,7 +182,10 @@
 		 * resolution, we must lock it because we could access an opregion.
 		 * The opregion access code assumes that the interpreter is locked.
 		 */
-		acpi_ex_enter_interpreter();
+		status = acpi_ex_enter_interpreter();
+		if (ACPI_FAILURE(status)) {
+			return_ACPI_STATUS(status);
+		}
 
 		/* Function has a strange interface */
 
diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c
index 33db224..c4ab615 100644
--- a/drivers/acpi/namespace/nsinit.c
+++ b/drivers/acpi/namespace/nsinit.c
@@ -214,7 +214,7 @@
 			u32 level, void *context, void **return_value)
 {
 	acpi_object_type type;
-	acpi_status status = AE_OK;
+	acpi_status status;
 	struct acpi_init_walk_info *info =
 	    (struct acpi_init_walk_info *)context;
 	struct acpi_namespace_node *node =
@@ -268,7 +268,10 @@
 	/*
 	 * Must lock the interpreter before executing AML code
 	 */
-	acpi_ex_enter_interpreter();
+	status = acpi_ex_enter_interpreter();
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
 
 	/*
 	 * Each of these types can contain executable AML code within the
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index 7ac6ace..8904d0f 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -170,6 +170,7 @@
 		     struct acpi_buffer *return_buffer)
 {
 	acpi_status status;
+	acpi_status status2;
 	struct acpi_evaluate_info *info;
 	acpi_size buffer_space_needed;
 	u32 i;
@@ -328,12 +329,14 @@
 		 * Delete the internal return object. NOTE: Interpreter must be
 		 * locked to avoid race condition.
 		 */
-		acpi_ex_enter_interpreter();
+		status2 = acpi_ex_enter_interpreter();
+		if (ACPI_SUCCESS(status2)) {
 
-		/* Remove one reference on the return object (should delete it) */
+			/* Remove one reference on the return object (should delete it) */
 
-		acpi_ut_remove_reference(info->return_object);
-		acpi_ex_exit_interpreter();
+			acpi_ut_remove_reference(info->return_object);
+			acpi_ex_exit_interpreter();
+		}
 	}
 
       cleanup:
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 1ef3385..4ffecd1 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -436,8 +436,6 @@
 	cl = &device->power.states[device->power.state].resources;
 	tl = &device->power.states[state].resources;
 
-	device->power.state = ACPI_STATE_UNKNOWN;
-
 	if (!cl->count && !tl->count) {
 		result = -ENODEV;
 		goto end;
@@ -468,12 +466,15 @@
 			goto end;
 	}
 
-	/* We shouldn't change the state till all above operations succeed */
-	device->power.state = state;
-      end:
-	if (result)
+     end:
+	if (result) {
+		device->power.state = ACPI_STATE_UNKNOWN;
 		printk(KERN_WARNING PREFIX "Transitioning device [%s] to D%d\n",
 			      device->pnp.bus_id, state);
+	} else {
+	/* We shouldn't change the state till all above operations succeed */
+		device->power.state = state;
+	}
 
 	return result;
 }
@@ -687,13 +688,6 @@
 		return result;
 
 	mutex_lock(&resource->resource_lock);
-	if ((resource->state == ACPI_POWER_RESOURCE_STATE_ON) &&
-	    list_empty(&resource->reference)) {
-		mutex_unlock(&resource->resource_lock);
-		result = acpi_power_off_device(device->handle, NULL);
-		return result;
-	}
-
 	if ((resource->state == ACPI_POWER_RESOURCE_STATE_OFF) &&
 	    !list_empty(&resource->reference)) {
 		ref = container_of(resource->reference.next, struct acpi_power_reference, node);
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 6077300..cdf7894 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -268,6 +268,7 @@
 				   struct acpi_processor_cx *cx)
 {
 	struct acpi_processor_power *pwr = &pr->power;
+	u8 type = local_apic_timer_c2_ok ? ACPI_STATE_C3 : ACPI_STATE_C2;
 
 	/*
 	 * Check, if one of the previous states already marked the lapic
@@ -276,7 +277,7 @@
 	if (pwr->timer_broadcast_on_state < state)
 		return;
 
-	if (cx->type >= ACPI_STATE_C2)
+	if (cx->type >= type)
 		pr->power.timer_broadcast_on_state = state;
 }
 
diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c
index 1358c06..cc48ab0 100644
--- a/drivers/acpi/resources/rscreate.c
+++ b/drivers/acpi/resources/rscreate.c
@@ -191,6 +191,9 @@
 	user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer);
 
 	for (index = 0; index < number_of_elements; index++) {
+		int source_name_index = 2;
+		int source_index_index = 3;
+
 		/*
 		 * Point user_prt past this current structure
 		 *
@@ -261,10 +264,28 @@
 		}
 
 		/*
+		 * If BIOS erroneously reversed the _PRT source_name and source_index,
+		 * then reverse them back.
+		 */
+		if (ACPI_GET_OBJECT_TYPE (sub_object_list[3]) != ACPI_TYPE_INTEGER) {
+			if (acpi_gbl_enable_interpreter_slack) {
+				source_name_index = 3;
+				source_index_index = 2;
+				printk(KERN_WARNING "ACPI: Handling Garbled _PRT entry\n");
+			} else {
+				ACPI_ERROR((AE_INFO,
+					"(PRT[%X].source_index) Need Integer, found %s",
+					index,
+					acpi_ut_get_object_type_name(sub_object_list[3])));
+				return_ACPI_STATUS(AE_BAD_DATA);
+			}
+		}
+
+		/*
 		 * 3) Third subobject: Dereference the PRT.source_name
 		 * The name may be unresolved (slack mode), so allow a null object
 		 */
-		obj_desc = sub_object_list[2];
+		obj_desc = sub_object_list[source_name_index];
 		if (obj_desc) {
 			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
 			case ACPI_TYPE_LOCAL_REFERENCE:
@@ -339,7 +360,7 @@
 
 		/* 4) Fourth subobject: Dereference the PRT.source_index */
 
-		obj_desc = sub_object_list[3];
+		obj_desc = sub_object_list[source_index_index];
 		if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
 			user_prt->source_index = (u32) obj_desc->integer.value;
 		} else {
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 849e2c3..c341918 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -42,7 +42,9 @@
 
 static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata;
 
-void acpi_table_print_madt_entry(struct acpi_subtable_header * header)
+static int acpi_apic_instance __initdata;
+
+void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 {
 	if (!header)
 		return;
@@ -183,8 +185,10 @@
 	if (!handler)
 		return -EINVAL;
 
-	/* Locate the table (if exists). There should only be one. */
-	acpi_get_table(id, 0, &table_header);
+	if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
+		acpi_get_table(id, acpi_apic_instance, &table_header);
+	else
+		acpi_get_table(id, 0, &table_header);
 
 	if (!table_header) {
 		printk(KERN_WARNING PREFIX "%4.4s not present\n", id);
@@ -237,10 +241,15 @@
 int __init acpi_table_parse(char *id, acpi_table_handler handler)
 {
 	struct acpi_table_header *table = NULL;
+
 	if (!handler)
 		return -EINVAL;
 
-	acpi_get_table(id, 0, &table);
+	if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
+		acpi_get_table(id, acpi_apic_instance, &table);
+	else
+		acpi_get_table(id, 0, &table);
+
 	if (table) {
 		handler(table);
 		return 0;
@@ -248,6 +257,31 @@
 		return 1;
 }
 
+/* 
+ * The BIOS is supposed to supply a single APIC/MADT,
+ * but some report two.  Provide a knob to use either.
+ * (don't you wish instance 0 and 1 were not the same?)
+ */
+static void __init check_multiple_madt(void)
+{
+	struct acpi_table_header *table = NULL;
+
+	acpi_get_table(ACPI_SIG_MADT, 2, &table);
+	if (table) {
+		printk(KERN_WARNING PREFIX
+		       "BIOS bug: multiple APIC/MADT found,"
+		       " using %d\n", acpi_apic_instance);
+		printk(KERN_WARNING PREFIX
+		       "If \"acpi_apic_instance=%d\" works better, "
+		       "notify linux-acpi@vger.kernel.org\n",
+		       acpi_apic_instance ? 0 : 2);
+
+	} else
+		acpi_apic_instance = 0;
+
+	return;
+}
+
 /*
  * acpi_table_init()
  *
@@ -257,9 +291,22 @@
  * result: sdt_entry[] is initialized
  */
 
-
 int __init acpi_table_init(void)
 {
 	acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
+	check_multiple_madt();
 	return 0;
 }
+
+static int __init acpi_parse_apic_instance(char *str)
+{
+
+	acpi_apic_instance = simple_strtoul(str, NULL, 0);
+
+	printk(KERN_NOTICE PREFIX "Shall use APIC/MADT table %d\n",
+	       acpi_apic_instance);
+
+	return 0;
+}
+
+early_param("acpi_apic_instance", acpi_parse_apic_instance);
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 0771b43..00d25b3 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -102,9 +102,9 @@
 
 struct acpi_video_device_attrib {
 	u32 display_index:4;	/* A zero-based instance of the Display */
-	u32 display_port_attachment:4;	/*This field differenates displays type */
+	u32 display_port_attachment:4;	/*This field differentiates the display type */
 	u32 display_type:4;	/*Describe the specific type in use */
-	u32 vendor_specific:4;	/*Chipset Vendor Specifi */
+	u32 vendor_specific:4;	/*Chipset Vendor Specific */
 	u32 bios_can_detect:1;	/*BIOS can detect the device */
 	u32 depend_on_vga:1;	/*Non-VGA output device whose power is related to 
 				   the VGA device. */
@@ -484,16 +484,16 @@
  *		0.	The system BIOS should NOT automatically switch(toggle)
  *			the active display output.
  *		1.	The system BIOS should automatically switch (toggle) the
- *			active display output. No swich event.
+ *			active display output. No switch event.
  *		2.	The _DGS value should be locked.
  *		3.	The system BIOS should not automatically switch (toggle) the
  *			active display output, but instead generate the display switch
  *			event notify code.
  *	lcd_flag	:
  *		0.	The system BIOS should automatically control the brightness level
- *			of the LCD, when the power changes from AC to DC
+ *			of the LCD when the power changes from AC to DC
  *		1. 	The system BIOS should NOT automatically control the brightness 
- *			level of the LCD, when the power changes from AC to DC.
+ *			level of the LCD when the power changes from AC to DC.
  * Return Value:
  * 		-1	wrong arg.
  */
@@ -525,7 +525,7 @@
  *  Return Value:
  *  	None
  *
- *  Find out all required AML method defined under the output
+ *  Find out all required AML methods defined under the output
  *  device.
  */
 
@@ -636,7 +636,7 @@
  *  Return Value:
  *  	None
  *
- *  Find out all required AML method defined under the video bus device.
+ *  Find out all required AML methods defined under the video bus device.
  */
 
 static void acpi_video_bus_find_cap(struct acpi_video_bus *video)
@@ -681,19 +681,19 @@
 	 * to check well known required nodes.
 	 */
 
-	/* Does this device able to support video switching ? */
+	/* Does this device support video switching? */
 	if (video->cap._DOS) {
 		video->flags.multihead = 1;
 		status = 0;
 	}
 
-	/* Does this device able to retrieve a retrieve a video ROM ? */
+	/* Does this device support retrieving a video ROM? */
 	if (video->cap._ROM) {
 		video->flags.rom = 1;
 		status = 0;
 	}
 
-	/* Does this device able to configure which video device to POST ? */
+	/* Does this device support configuring which video device to POST? */
 	if (video->cap._GPD && video->cap._SPD && video->cap._VPO) {
 		video->flags.post = 1;
 		status = 0;
@@ -860,7 +860,7 @@
 	if (level > 100)
 		return -EFAULT;
 
-	/* validate though the list of available levels */
+	/* validate through the list of available levels */
 	for (i = 0; i < dev->brightness->count; i++)
 		if (level == dev->brightness->levels[i]) {
 			if (ACPI_SUCCESS
@@ -1065,10 +1065,10 @@
 			printk(KERN_WARNING PREFIX
 			       "The motherboard VGA device is not listed as a possible POST device.\n");
 			printk(KERN_WARNING PREFIX
-			       "This indicate a BIOS bug.  Please contact the manufacturer.\n");
+			       "This indicates a BIOS bug. Please contact the manufacturer.\n");
 		}
 		printk("%lx\n", options);
-		seq_printf(seq, "can POST: <intgrated video>");
+		seq_printf(seq, "can POST: <integrated video>");
 		if (options & 2)
 			seq_printf(seq, " <PCI video>");
 		if (options & 4)
@@ -1102,7 +1102,7 @@
 		seq_printf(seq, "<not supported>\n");
 		goto end;
 	}
-	seq_printf(seq, "device posted is <%s>\n", device_decode[id & 3]);
+	seq_printf(seq, "device POSTed is <%s>\n", device_decode[id & 3]);
 
       end:
 	return 0;
@@ -1156,7 +1156,7 @@
 	if (opt > 3)
 		return -EFAULT;
 
-	/* just in case an OEM 'forget' the motherboard... */
+	/* just in case an OEM 'forgot' the motherboard... */
 	options |= 1;
 
 	if (options & (1ul << opt)) {
@@ -1527,13 +1527,13 @@
 /*
  *  Arg:
  *  	video	: video bus device 
- *  	event	: Nontify Event
+ *  	event	: notify event
  *
  *  Return:
  *  	< 0	: error
  *  
  *	1. Find out the current active output device.
- *	2. Identify the next output device to switch
+ *	2. Identify the next output device to switch to.
  *	3. call _DSS to do actual switch.
  */
 
@@ -1723,12 +1723,12 @@
 	device = video->device;
 
 	switch (event) {
-	case ACPI_VIDEO_NOTIFY_SWITCH:	/* User request that a switch occur,
+	case ACPI_VIDEO_NOTIFY_SWITCH:	/* User requested a switch,
 					 * most likely via hotkey. */
 		acpi_bus_generate_event(device, event, 0);
 		break;
 
-	case ACPI_VIDEO_NOTIFY_PROBE:	/* User plug or remove a video
+	case ACPI_VIDEO_NOTIFY_PROBE:	/* User plugged in or removed a video
 					 * connector. */
 		acpi_video_device_enumerate(video);
 		acpi_video_device_rebind(video);
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index d16b5b0..7bdbe5a 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -564,7 +564,7 @@
 
 config PATA_SCC
 	tristate "Toshiba's Cell Reference Set IDE support"
-	depends on PCI && PPC_IBM_CELL_BLADE
+	depends on PCI && PPC_CELLEB
 	help
 	  This option enables support for the built-in IDE controller on
 	  Toshiba Cell Reference Board.
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index dc7b562..fd27227 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -80,6 +80,7 @@
 	board_ahci_pi		= 1,
 	board_ahci_vt8251	= 2,
 	board_ahci_ign_iferr	= 3,
+	board_ahci_sb600	= 4,
 
 	/* global controller registers */
 	HOST_CAP		= 0x00, /* host capabilities */
@@ -168,6 +169,7 @@
 	AHCI_FLAG_NO_NCQ		= (1 << 24),
 	AHCI_FLAG_IGN_IRQ_IF_ERR	= (1 << 25), /* ignore IRQ_IF_ERR */
 	AHCI_FLAG_HONOR_PI		= (1 << 26), /* honor PORTS_IMPL */
+	AHCI_FLAG_IGN_SERR_INTERNAL	= (1 << 27), /* ignore SERR_INTERNAL */
 };
 
 struct ahci_cmd_hdr {
@@ -362,6 +364,18 @@
 		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
 		.port_ops	= &ahci_ops,
 	},
+	/* board_ahci_sb600 */
+	{
+		.sht		= &ahci_sht,
+		.flags		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+				  ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
+				  ATA_FLAG_SKIP_D2H_BSY |
+				  AHCI_FLAG_IGN_SERR_INTERNAL,
+		.pio_mask	= 0x1f, /* pio0-4 */
+		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
+		.port_ops	= &ahci_ops,
+	},
+
 };
 
 static const struct pci_device_id ahci_pci_tbl[] = {
@@ -399,7 +413,7 @@
 	  PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr },
 
 	/* ATI */
-	{ PCI_VDEVICE(ATI, 0x4380), board_ahci }, /* ATI SB600 non-raid */
+	{ PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 non-raid */
 	{ PCI_VDEVICE(ATI, 0x4381), board_ahci }, /* ATI SB600 raid */
 
 	/* VIA */
@@ -1067,8 +1081,11 @@
 	if (ap->flags & AHCI_FLAG_IGN_IRQ_IF_ERR)
 		irq_stat &= ~PORT_IRQ_IF_ERR;
 
-	if (irq_stat & PORT_IRQ_TF_ERR)
+	if (irq_stat & PORT_IRQ_TF_ERR) {
 		err_mask |= AC_ERR_DEV;
+		if (ap->flags & AHCI_FLAG_IGN_SERR_INTERNAL)
+			serror &= ~SERR_INTERNAL;
+	}
 
 	if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) {
 		err_mask |= AC_ERR_HOST_BUS;
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index dc42ba1..b952c58 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -93,7 +93,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME	"ata_piix"
-#define DRV_VERSION	"2.10"
+#define DRV_VERSION	"2.10ac1"
 
 enum {
 	PIIX_IOCFG		= 0x54, /* IDE I/O configuration register */
@@ -667,14 +667,9 @@
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 
-	if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no])) {
-		ata_port_printk(ap, KERN_INFO, "port disabled. ignoring.\n");
-		ap->eh_context.i.action &= ~ATA_EH_RESET_MASK;
-		return 0;
-	}
-
+	if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no]))
+		return -ENOENT;
 	ich_pata_cbl_detect(ap);
-
 	return ata_std_prereset(ap);
 }
 
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index d14a48e..03a0acf 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -34,6 +34,13 @@
 	u8	tfa[REGS_PER_GTF];	/* regs. 0x1f1 - 0x1f7 */
 };
 
+/*
+ *	Helper - belongs in the PCI layer somewhere eventually
+ */
+static int is_pci_dev(struct device *dev)
+{
+	return (dev->bus == &pci_bus_type);
+}
 
 /**
  * sata_get_dev_handle - finds acpi_handle and PCI device.function
@@ -53,6 +60,9 @@
 	struct pci_dev	*pci_dev;
 	acpi_integer	addr;
 
+	if (!is_pci_dev(dev))
+		return -ENODEV;
+
 	pci_dev = to_pci_dev(dev);	/* NOTE: PCI-specific */
 	/* Please refer to the ACPI spec for the syntax of _ADR. */
 	addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
@@ -84,7 +94,12 @@
 	acpi_status status;
 	struct acpi_device_info	*dinfo = NULL;
 	int ret = -ENODEV;
-	struct pci_dev *pdev = to_pci_dev(dev);
+	struct pci_dev *pdev;
+
+	if (!is_pci_dev(dev))
+		return -ENODEV;
+
+	pdev = to_pci_dev(dev);
 
 	bus = pdev->bus->number;
 	devnum = PCI_SLOT(pdev->devfn);
@@ -290,7 +305,7 @@
 	*gtf_address = 0UL;
 	*obj_loc = 0UL;
 
-	if (noacpi)
+	if (libata_noacpi)
 		return 0;
 
 	if (ata_msg_probe(ap))
@@ -516,7 +531,7 @@
 		ata_dev_printk(atadev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
 			       __FUNCTION__, ap->port_no);
 
-	if (noacpi || !(ap->cbl == ATA_CBL_SATA))
+	if (libata_noacpi || !(ap->cbl == ATA_CBL_SATA))
 		return 0;
 
 	if (!ata_dev_enabled(atadev) || (ap->flags & ATA_FLAG_DISABLED))
@@ -559,7 +574,14 @@
 	unsigned long	gtf_address;
 	unsigned long	obj_loc;
 
-	if (noacpi)
+	if (libata_noacpi)
+		return 0;
+	/*
+	 * TBD - implement PATA support.  For now,
+	 * we should not run GTF on PATA devices since some
+	 * PATA require execution of GTM/STM before GTF.
+	 */
+	if (!(ap->cbl == ATA_CBL_SATA))
 		return 0;
 
 	for (ix = 0; ix < ATA_MAX_DEVICES; ix++) {
@@ -614,7 +636,7 @@
 	struct acpi_object_list         input;
 	union acpi_object               in_params[1];
 
-	if (noacpi)
+	if (libata_noacpi)
 		return 0;
 
 	if (ata_msg_probe(ap))
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index dc362fa..0abd72d 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -93,8 +93,8 @@
 module_param(ata_probe_timeout, int, 0444);
 MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)");
 
-int noacpi;
-module_param(noacpi, int, 0444);
+int libata_noacpi = 1;
+module_param_named(noacpi, libata_noacpi, int, 0444);
 MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in suspend/resume when set");
 
 MODULE_AUTHOR("Jeff Garzik");
@@ -826,7 +826,7 @@
 /**
  *	ata_id_to_dma_mode	-	Identify DMA mode from id block
  *	@dev: device to identify
- *	@mode: mode to assume if we cannot tell
+ *	@unknown: mode to assume if we cannot tell
  *
  *	Set up the timing values for the device based upon the identify
  *	reported values for the DMA mode. This function is used by drivers
@@ -1784,6 +1784,13 @@
 		dev->max_sectors = ATA_MAX_SECTORS;
 	}
 
+	if (ata_device_blacklisted(dev) & ATA_HORKAGE_MAX_SEC_128)
+		dev->max_sectors = min(ATA_MAX_SECTORS_128, dev->max_sectors);
+
+	/* limit ATAPI DMA to R/W commands only */
+	if (ata_device_blacklisted(dev) & ATA_HORKAGE_DMA_RW_ONLY)
+		dev->horkage |= ATA_HORKAGE_DMA_RW_ONLY;
+
 	if (ap->ops->dev_config)
 		ap->ops->dev_config(ap, dev);
 
@@ -3352,6 +3359,10 @@
 	{ "_NEC DV5800A", 	NULL,		ATA_HORKAGE_NODMA },
 	{ "SAMSUNG CD-ROM SN-124","N001",	ATA_HORKAGE_NODMA },
 
+	/* Weird ATAPI devices */
+	{ "TORiSAN DVD-ROM DRD-N216", NULL,	ATA_HORKAGE_MAX_SEC_128 |
+						ATA_HORKAGE_DMA_RW_ONLY },
+
 	/* Devices we expect to fail diagnostics */
 
 	/* Devices where NCQ should be avoided */
@@ -3359,6 +3370,15 @@
         { "WDC WD740ADFD-00",   NULL,		ATA_HORKAGE_NONCQ },
 	/* http://thread.gmane.org/gmane.linux.ide/14907 */
 	{ "FUJITSU MHT2060BH",	NULL,		ATA_HORKAGE_NONCQ },
+	/* NCQ is broken */
+	{ "Maxtor 6L250S0",     "BANC1G10",     ATA_HORKAGE_NONCQ },
+	/* NCQ hard hangs device under heavier load, needs hard power cycle */
+	{ "Maxtor 6B250S0",	"BANC1B70",	ATA_HORKAGE_NONCQ },
+	/* Blacklist entries taken from Silicon Image 3124/3132
+	   Windows driver .inf file - also several Linux problem reports */
+	{ "HTS541060G9SA00",    "MB3OC60D",     ATA_HORKAGE_NONCQ, },
+	{ "HTS541080G9SA00",    "MB4OC60D",     ATA_HORKAGE_NONCQ, },
+	{ "HTS541010G9SA00",    "MBZOC60D",     ATA_HORKAGE_NONCQ, },
 
 	/* Devices with NCQ limits */
 
@@ -3455,7 +3475,8 @@
 			       "device is on DMA blacklist, disabling DMA\n");
 	}
 
-	if ((host->flags & ATA_HOST_SIMPLEX) && host->simplex_claimed != ap) {
+	if ((host->flags & ATA_HOST_SIMPLEX) &&
+            host->simplex_claimed && host->simplex_claimed != ap) {
 		xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
 		ata_dev_printk(dev, KERN_WARNING, "simplex DMA is claimed by "
 			       "other device, disabling DMA\n");
@@ -3669,6 +3690,26 @@
 	struct ata_port *ap = qc->ap;
 	int rc = 0; /* Assume ATAPI DMA is OK by default */
 
+	/* some drives can only do ATAPI DMA on read/write */
+	if (unlikely(qc->dev->horkage & ATA_HORKAGE_DMA_RW_ONLY)) {
+		struct scsi_cmnd *cmd = qc->scsicmd;
+		u8 *scsicmd = cmd->cmnd;
+
+		switch (scsicmd[0]) {
+		case READ_10:
+		case WRITE_10:
+		case READ_12:
+		case WRITE_12:
+		case READ_6:
+		case WRITE_6:
+			/* atapi dma maybe ok */
+			break;
+		default:
+			/* turn off atapi dma */
+			return 1;
+		}
+	}
+
 	if (ap->ops->check_atapi_dma)
 		rc = ap->ops->check_atapi_dma(qc);
 
@@ -4712,8 +4753,8 @@
 {
 	struct ata_port *ap = qc->ap;
 
-	ap->ops->tf_read(ap, &qc->result_tf);
 	qc->result_tf.flags = qc->tf.flags;
+	ap->ops->tf_read(ap, &qc->result_tf);
 }
 
 /**
@@ -5684,18 +5725,22 @@
 	for (i = 0; i < host->n_ports; i++) {
 		struct ata_port *ap = host->ports[i];
 
-		if (!ap)
-			continue;
-
-		if (ap->ops->port_stop)
+		if (ap && ap->ops->port_stop)
 			ap->ops->port_stop(ap);
-
-		scsi_host_put(ap->scsi_host);
 	}
 
 	if (host->ops->host_stop)
 		host->ops->host_stop(host);
 
+	for (i = 0; i < host->n_ports; i++) {
+		struct ata_port *ap = host->ports[i];
+
+		if (ap)
+			scsi_host_put(ap->scsi_host);
+
+		host->ports[i] = NULL;
+	}
+
 	dev_set_drvdata(gendev, NULL);
 }
 
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 7349c3d..39f556c 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -982,26 +982,27 @@
  *	RETURNS:
  *	0 on success, AC_ERR_* mask on failure
  */
-static unsigned int atapi_eh_request_sense(struct ata_device *dev,
-					   unsigned char *sense_buf)
+static unsigned int atapi_eh_request_sense(struct ata_queued_cmd *qc)
 {
+	struct ata_device *dev = qc->dev;
+	unsigned char *sense_buf = qc->scsicmd->sense_buffer;
 	struct ata_port *ap = dev->ap;
 	struct ata_taskfile tf;
 	u8 cdb[ATAPI_CDB_LEN];
 
 	DPRINTK("ATAPI request sense\n");
 
-	ata_tf_init(dev, &tf);
-
 	/* FIXME: is this needed? */
 	memset(sense_buf, 0, SCSI_SENSE_BUFFERSIZE);
 
-	/* XXX: why tf_read here? */
-	ap->ops->tf_read(ap, &tf);
-
-	/* fill these in, for the case where they are -not- overwritten */
+	/* initialize sense_buf with the error register,
+	 * for the case where they are -not- overwritten
+	 */
 	sense_buf[0] = 0x70;
-	sense_buf[2] = tf.feature >> 4;
+	sense_buf[2] = qc->result_tf.feature >> 4;
+
+	/* some devices time out if garbage left in tf */ 
+	ata_tf_init(dev, &tf);
 
 	memset(cdb, 0, ATAPI_CDB_LEN);
 	cdb[0] = REQUEST_SENSE;
@@ -1165,8 +1166,7 @@
 
 	case ATA_DEV_ATAPI:
 		if (!(qc->ap->pflags & ATA_PFLAG_FROZEN)) {
-			tmp = atapi_eh_request_sense(qc->dev,
-						     qc->scsicmd->sense_buffer);
+			tmp = atapi_eh_request_sense(qc);
 			if (!tmp) {
 				/* ATA_QCFLAG_SENSE_VALID is used to
 				 * tell atapi_qc_complete() that sense
@@ -1625,8 +1625,14 @@
 		rc = prereset(ap);
 		if (rc) {
 			if (rc == -ENOENT) {
-				ata_port_printk(ap, KERN_DEBUG, "port disabled. ignoring.\n");
+				ata_port_printk(ap, KERN_DEBUG,
+						"port disabled. ignoring.\n");
 				ap->eh_context.i.action &= ~ATA_EH_RESET_MASK;
+
+				for (i = 0; i < ATA_MAX_DEVICES; i++)
+					classes[i] = ATA_DEV_NONE;
+
+				rc = 0;
 			} else
 				ata_port_printk(ap, KERN_ERR,
 					"prereset failed (errno=%d)\n", rc);
@@ -1737,12 +1743,17 @@
 {
 	struct ata_eh_context *ehc = &ap->eh_context;
 	struct ata_device *dev;
+	unsigned int new_mask = 0;
 	unsigned long flags;
 	int i, rc = 0;
 
 	DPRINTK("ENTER\n");
 
-	for (i = 0; i < ATA_MAX_DEVICES; i++) {
+	/* For PATA drive side cable detection to work, IDENTIFY must
+	 * be done backwards such that PDIAG- is released by the slave
+	 * device before the master device is identified.
+	 */
+	for (i = ATA_MAX_DEVICES - 1; i >= 0; i--) {
 		unsigned int action, readid_flags = 0;
 
 		dev = &ap->device[i];
@@ -1754,13 +1765,13 @@
 		if (action & ATA_EH_REVALIDATE && ata_dev_ready(dev)) {
 			if (ata_port_offline(ap)) {
 				rc = -EIO;
-				break;
+				goto err;
 			}
 
 			ata_eh_about_to_do(ap, dev, ATA_EH_REVALIDATE);
 			rc = ata_dev_revalidate(dev, readid_flags);
 			if (rc)
-				break;
+				goto err;
 
 			ata_eh_done(ap, dev, ATA_EH_REVALIDATE);
 
@@ -1778,40 +1789,53 @@
 
 			rc = ata_dev_read_id(dev, &dev->class, readid_flags,
 					     dev->id);
-			if (rc == 0) {
-				ehc->i.flags |= ATA_EHI_PRINTINFO;
-				rc = ata_dev_configure(dev);
-				ehc->i.flags &= ~ATA_EHI_PRINTINFO;
-			} else if (rc == -ENOENT) {
+			switch (rc) {
+			case 0:
+				new_mask |= 1 << i;
+				break;
+			case -ENOENT:
 				/* IDENTIFY was issued to non-existent
 				 * device.  No need to reset.  Just
 				 * thaw and kill the device.
 				 */
 				ata_eh_thaw_port(ap);
 				dev->class = ATA_DEV_UNKNOWN;
-				rc = 0;
-			}
-
-			if (rc) {
-				dev->class = ATA_DEV_UNKNOWN;
 				break;
-			}
-
-			if (ata_dev_enabled(dev)) {
-				spin_lock_irqsave(ap->lock, flags);
-				ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
-				spin_unlock_irqrestore(ap->lock, flags);
-
-				/* new device discovered, configure xfermode */
-				ehc->i.flags |= ATA_EHI_SETMODE;
+			default:
+				dev->class = ATA_DEV_UNKNOWN;
+				goto err;
 			}
 		}
 	}
 
-	if (rc)
-		*r_failed_dev = dev;
+	/* Configure new devices forward such that user doesn't see
+	 * device detection messages backwards.
+	 */
+	for (i = 0; i < ATA_MAX_DEVICES; i++) {
+		dev = &ap->device[i];
 
-	DPRINTK("EXIT\n");
+		if (!(new_mask & (1 << i)))
+			continue;
+
+		ehc->i.flags |= ATA_EHI_PRINTINFO;
+		rc = ata_dev_configure(dev);
+		ehc->i.flags &= ~ATA_EHI_PRINTINFO;
+		if (rc)
+			goto err;
+
+		spin_lock_irqsave(ap->lock, flags);
+		ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
+		spin_unlock_irqrestore(ap->lock, flags);
+
+		/* new device discovered, configure xfermode */
+		ehc->i.flags |= ATA_EHI_SETMODE;
+	}
+
+	return 0;
+
+ err:
+	*r_failed_dev = dev;
+	DPRINTK("EXIT rc=%d\n", rc);
 	return rc;
 }
 
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 6cc817a..e936443 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -333,7 +333,7 @@
 	scsi_cmd[8]  = args[3];
 	scsi_cmd[10] = args[4];
 	scsi_cmd[12] = args[5];
-	scsi_cmd[13] = args[6] & 0x0f;
+	scsi_cmd[13] = args[6] & 0x4f;
 	scsi_cmd[14] = args[0];
 
 	/* Good values for timeout and retries?  Values below
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index c426714..1f1e3a5 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -56,7 +56,7 @@
 extern int atapi_enabled;
 extern int atapi_dmadir;
 extern int libata_fua;
-extern int noacpi;
+extern int libata_noacpi;
 extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
 extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
 			   u64 block, u32 n_block, unsigned int tf_flags,
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c
index 7ef8342..55cc293 100644
--- a/drivers/ata/pata_cs5520.c
+++ b/drivers/ata/pata_cs5520.c
@@ -208,7 +208,7 @@
 static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
 	u8 pcicfg;
-	void *iomap[5];
+	void __iomem *iomap[5];
 	static struct ata_probe_ent probe[2];
 	int ports = 0;
 
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
index 9a0523b..c6f0e19 100644
--- a/drivers/ata/pata_ixp4xx_cf.c
+++ b/drivers/ata/pata_ixp4xx_cf.c
@@ -193,7 +193,7 @@
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq)
-		set_irq_type(irq, IRQT_HIGH);
+		set_irq_type(irq, IRQT_RISING);
 
 	/* Setup expansion bus chip selects */
 	*data->cs0_cfg = data->cs0_bits;
@@ -232,7 +232,6 @@
 	struct ata_host *host = platform_get_drvdata(dev);
 
 	ata_host_detach(host);
-	platform_set_drvdata(dev, NULL);
 
 	return 0;
 }
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c
index f5d8872..882c36e 100644
--- a/drivers/ata/pata_mpc52xx.c
+++ b/drivers/ata/pata_mpc52xx.c
@@ -329,7 +329,7 @@
 	ae->dev = dev;
 	ae->irq = priv->ata_irq;
 
-	aio->cmd_addr		= 0;	/* Don't have a classic reg block */
+	aio->cmd_addr		= NULL;	/* Don't have a classic reg block */
 	aio->altstatus_addr	= &priv->ata_regs->tf_control;
 	aio->ctl_addr		= &priv->ata_regs->tf_control;
 	aio->data_addr		= &priv->ata_regs->tf_data;
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c
index acdc52c..0a14933 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -195,7 +195,7 @@
 	/* Cases the state machine will not complete correctly without help */
 	if ((tf->flags & ATA_TFLAG_LBA48) ||  tf->protocol == ATA_PROT_ATAPI_DMA)
 	{
-		len = qc->nbytes;
+		len = qc->nbytes / 2;
 
 		if (tf->flags & ATA_TFLAG_WRITE)
 			len |= 0x06000000;
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index 3193a60..1e21688 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -672,10 +672,6 @@
 	if (rc)
 		return rc;
 
-	rc = pci_request_regions(pdev, DRV_NAME);
-	if (rc)
-		return rc;
-
 	rc = pcim_iomap_regions(pdev, 0x3f, DRV_NAME);
 	if (rc)
 		return rc;
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 388d07fa..9d9670a 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -874,8 +874,14 @@
 
 			if (status & (NV_ADMA_STAT_DONE |
 				      NV_ADMA_STAT_CPBERR)) {
-				u32 check_commands = notifier | notifier_error;
+				u32 check_commands;
 				int pos, error = 0;
+
+				if(ata_tag_valid(ap->active_tag))
+					check_commands = 1 << ap->active_tag;
+				else
+					check_commands = ap->sactive;
+
 				/** Check CPBs for completed commands */
 				while ((pos = ffs(check_commands)) && !error) {
 					pos--;
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 75d9615..5614df8 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -346,6 +346,7 @@
 	{ PCI_VDEVICE(CMD, 0x3124), BID_SIL3124 },
 	{ PCI_VDEVICE(INTEL, 0x3124), BID_SIL3124 },
 	{ PCI_VDEVICE(CMD, 0x3132), BID_SIL3132 },
+	{ PCI_VDEVICE(CMD, 0x0242), BID_SIL3132 },
 	{ PCI_VDEVICE(CMD, 0x3131), BID_SIL3131 },
 	{ PCI_VDEVICE(CMD, 0x3531), BID_SIL3131 },
 
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index 1879e0c..a787f0d 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -354,7 +354,7 @@
 		return -ENOMEM;
 
 	if (!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) {
-		void *mmio;
+		void __iomem *mmio;
 
 		mmio = pcim_iomap(pdev, SIS_SCR_PCI_BAR, 0);
 		if (!mmio)
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
index 0d7091e..2ad2527 100644
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -1177,7 +1177,7 @@
 /*--------------------------------- entries ---------------------------------*/
 
 
-static int __init zatm_init(struct atm_dev *dev)
+static int __devinit zatm_init(struct atm_dev *dev)
 {
 	struct zatm_dev *zatm_dev;
 	struct pci_dev *pci_dev;
@@ -1256,7 +1256,7 @@
 }
 
 
-static int __init zatm_start(struct atm_dev *dev)
+static int __devinit zatm_start(struct atm_dev *dev)
 {
 	struct zatm_dev *zatm_dev = ZATM_DEV(dev);
 	struct pci_dev *pdev = zatm_dev->pci_dev;
diff --git a/drivers/base/core.c b/drivers/base/core.c
index cf2a398..d7fcf82 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -28,20 +28,6 @@
 int (*platform_notify_remove)(struct device * dev) = NULL;
 
 /*
- * Detect the LANANA-assigned LOCAL/EXPERIMENTAL majors
- */
-bool is_lanana_major(unsigned int major)
-{
-	if (major >= 60 && major <= 63)
-		return 1;
-	if (major >= 120 && major <= 127)
-		return 1;
-	if (major >= 240 && major <= 254)
-		return 1;
-	return 0;
-}
-
-/*
  * sysfs bindings for devices.
  */
 
@@ -407,6 +393,35 @@
 }
 EXPORT_SYMBOL_GPL(device_remove_bin_file);
 
+/**
+ * device_schedule_callback - helper to schedule a callback for a device
+ * @dev: device.
+ * @func: callback function to invoke later.
+ *
+ * Attribute methods must not unregister themselves or their parent device
+ * (which would amount to the same thing).  Attempts to do so will deadlock,
+ * since unregistration is mutually exclusive with driver callbacks.
+ *
+ * Instead methods can call this routine, which will attempt to allocate
+ * and schedule a workqueue request to call back @func with @dev as its
+ * argument in the workqueue's process context.  @dev will be pinned until
+ * @func returns.
+ *
+ * Returns 0 if the request was submitted, -ENOMEM if storage could not
+ * be allocated.
+ *
+ * NOTE: This routine won't work if CONFIG_SYSFS isn't set!  It uses an
+ * underlying sysfs routine (since it is intended for use by attribute
+ * methods), and if sysfs isn't available you'll get nothing but -ENOSYS.
+ */
+int device_schedule_callback(struct device *dev,
+		void (*func)(struct device *))
+{
+	return sysfs_schedule_callback(&dev->kobj,
+			(void (*)(void *)) func, dev);
+}
+EXPORT_SYMBOL_GPL(device_schedule_callback);
+
 static void klist_children_get(struct klist_node *n)
 {
 	struct device *dev = container_of(n, struct device, knode_parent);
@@ -584,17 +599,17 @@
 		if (dev->kobj.parent != &dev->class->subsys.kset.kobj)
 			sysfs_create_link(&dev->class->subsys.kset.kobj,
 					  &dev->kobj, dev->bus_id);
-#ifdef CONFIG_SYSFS_DEPRECATED
 		if (parent) {
 			sysfs_create_link(&dev->kobj, &dev->parent->kobj,
 							"device");
+#ifdef CONFIG_SYSFS_DEPRECATED
 			class_name = make_class_name(dev->class->name,
 							&dev->kobj);
 			if (class_name)
 				sysfs_create_link(&dev->parent->kobj,
 						  &dev->kobj, class_name);
-		}
 #endif
+		}
 	}
 
 	if ((error = device_add_attrs(dev)))
@@ -651,17 +666,17 @@
 		if (dev->kobj.parent != &dev->class->subsys.kset.kobj)
 			sysfs_remove_link(&dev->class->subsys.kset.kobj,
 					  dev->bus_id);
-#ifdef CONFIG_SYSFS_DEPRECATED
 		if (parent) {
+#ifdef CONFIG_SYSFS_DEPRECATED
 			char *class_name = make_class_name(dev->class->name,
 							   &dev->kobj);
 			if (class_name)
 				sysfs_remove_link(&dev->parent->kobj,
 						  class_name);
 			kfree(class_name);
+#endif
 			sysfs_remove_link(&dev->kobj, "device");
 		}
-#endif
 
 		down(&dev->class->sem);
 		/* notify any interfaces that the device is now gone */
@@ -761,17 +776,17 @@
 		if (dev->kobj.parent != &dev->class->subsys.kset.kobj)
 			sysfs_remove_link(&dev->class->subsys.kset.kobj,
 					  dev->bus_id);
-#ifdef CONFIG_SYSFS_DEPRECATED
 		if (parent) {
+#ifdef CONFIG_SYSFS_DEPRECATED
 			char *class_name = make_class_name(dev->class->name,
 							   &dev->kobj);
 			if (class_name)
 				sysfs_remove_link(&dev->parent->kobj,
 						  class_name);
 			kfree(class_name);
+#endif
 			sysfs_remove_link(&dev->kobj, "device");
 		}
-#endif
 
 		down(&dev->class->sem);
 		/* notify any interfaces that the device is now gone */
@@ -787,6 +802,13 @@
 	device_remove_attrs(dev);
 	bus_remove_device(dev);
 
+	/*
+	 * Some platform devices are driven without driver attached
+	 * and managed resources may have been acquired.  Make sure
+	 * all resources are released.
+	 */
+	devres_release_all(dev);
+
 	/* Notify the platform of the removal, in case they
 	 * need to do anything...
 	 */
@@ -1058,14 +1080,14 @@
 
 	return error;
 }
-
+EXPORT_SYMBOL_GPL(device_rename);
 
 static int device_move_class_links(struct device *dev,
 				   struct device *old_parent,
 				   struct device *new_parent)
 {
+	int error = 0;
 #ifdef CONFIG_SYSFS_DEPRECATED
-	int error;
 	char *class_name;
 
 	class_name = make_class_name(dev->class->name, &dev->kobj);
@@ -1093,7 +1115,12 @@
 	kfree(class_name);
 	return error;
 #else
-	return 0;
+	if (old_parent)
+		sysfs_remove_link(&dev->kobj, "device");
+	if (new_parent)
+		error = sysfs_create_link(&dev->kobj, &new_parent->kobj,
+					  "device");
+	return error;
 #endif
 }
 
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 1214cbd..082bfde 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -183,7 +183,14 @@
 void driver_unregister(struct device_driver * drv)
 {
 	bus_remove_driver(drv);
-	wait_for_completion(&drv->unloaded);
+	/*
+	 * If the driver is a module, we are probably in
+	 * the module unload path, and we want to wait
+	 * for everything to unload before we can actually
+	 * finish the unload.
+	 */
+	if (drv->owner)
+		wait_for_completion(&drv->unloaded);
 }
 
 /**
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index fdfa3d0..bbbb973 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -54,7 +54,8 @@
 	int error;
 
 	pr_debug("PM: Adding info for %s:%s\n",
-		 dev->bus ? dev->bus->name : "No Bus", dev->kobj.name);
+		 dev->bus ? dev->bus->name : "No Bus",
+		 kobject_name(&dev->kobj));
 	down(&dpm_list_sem);
 	list_add_tail(&dev->power.entry, &dpm_active);
 	device_pm_set_parent(dev, dev->parent);
@@ -67,7 +68,8 @@
 void device_pm_remove(struct device * dev)
 {
 	pr_debug("PM: Removing info for %s:%s\n",
-		 dev->bus ? dev->bus->name : "No Bus", dev->kobj.name);
+		 dev->bus ? dev->bus->name : "No Bus",
+		 kobject_name(&dev->kobj));
 	down(&dpm_list_sem);
 	dpm_sysfs_remove(dev);
 	put_device(dev->power.pm_parent);
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 0c716ee..14d7806 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1439,7 +1439,7 @@
 
 		if (return_code == IO_OK) {
 			listlength =
-				be32_to_cpu(*(__u32 *) ld_buff->LUNListLength);
+				be32_to_cpu(*(__be32 *) ld_buff->LUNListLength);
 		} else {	/* reading number of logical volumes failed */
 			printk(KERN_WARNING "cciss: report logical volume"
 			       " command failed\n");
@@ -1915,6 +1915,7 @@
 			       "does not support reading geometry\n");
 			drv->heads = 255;
 			drv->sectors = 32;	// Sectors per track
+			drv->cylinders = total_size + 1;
 			drv->raid_level = RAID_UNKNOWN;
 		} else {
 			drv->heads = inq_buff->data_byte[6];
@@ -1961,8 +1962,8 @@
 				ctlr, buf, sizeof(ReadCapdata_struct),
 					1, logvol, 0, NULL, TYPE_CMD);
 	if (return_code == IO_OK) {
-		*total_size = be32_to_cpu(*(__u32 *) buf->total_size);
-		*block_size = be32_to_cpu(*(__u32 *) buf->block_size);
+		*total_size = be32_to_cpu(*(__be32 *) buf->total_size);
+		*block_size = be32_to_cpu(*(__be32 *) buf->block_size);
 	} else {		/* read capacity command failed */
 		printk(KERN_WARNING "cciss: read capacity failed\n");
 		*total_size = 0;
@@ -1997,8 +1998,8 @@
 				1, logvol, 0, NULL, TYPE_CMD);
 	}
 	if (return_code == IO_OK) {
-		*total_size = be64_to_cpu(*(__u64 *) buf->total_size);
-		*block_size = be32_to_cpu(*(__u32 *) buf->block_size);
+		*total_size = be64_to_cpu(*(__be64 *) buf->total_size);
+		*block_size = be32_to_cpu(*(__be32 *) buf->block_size);
 	} else {		/* read capacity command failed */
 		printk(KERN_WARNING "cciss: read capacity failed\n");
 		*total_size = 0;
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index 99e2c8c..31e0148 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -663,11 +663,11 @@
 		return Fail;
 	pi_read_block(disk->pi, pd_scratch, 512);
 	disk->can_lba = pd_scratch[99] & 2;
-	disk->sectors = le16_to_cpu(*(u16 *) (pd_scratch + 12));
-	disk->heads = le16_to_cpu(*(u16 *) (pd_scratch + 6));
-	disk->cylinders = le16_to_cpu(*(u16 *) (pd_scratch + 2));
+	disk->sectors = le16_to_cpu(*(__le16 *) (pd_scratch + 12));
+	disk->heads = le16_to_cpu(*(__le16 *) (pd_scratch + 6));
+	disk->cylinders = le16_to_cpu(*(__le16 *) (pd_scratch + 2));
 	if (disk->can_lba)
-		disk->capacity = le32_to_cpu(*(u32 *) (pd_scratch + 120));
+		disk->capacity = le32_to_cpu(*(__le32 *) (pd_scratch + 120));
 	else
 		disk->capacity = disk->sectors * disk->heads * disk->cylinders;
 
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 3429ece..d0c978f 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -386,6 +386,39 @@
 	  If you have an Alchemy AU1000 processor (MIPS based) and you want
 	  to use a console on a serial port, say Y.  Otherwise, say N.
 
+config SERIAL_DEC
+	bool "DECstation serial support"
+	depends on MACH_DECSTATION
+	default y
+	help
+	  This selects whether you want to be asked about drivers for
+	  DECstation serial ports.
+
+	  Note that the answer to this question won't directly affect the
+	  kernel: saying N will just cause the configurator to skip all
+	  the questions about DECstation serial ports.
+
+config SERIAL_DEC_CONSOLE
+	bool "Support for console on a DECstation serial port"
+	depends on SERIAL_DEC
+	default y
+	help
+	  If you say Y here, it will be possible to use a serial port as the
+	  system console (the system console is the device which receives all
+	  kernel messages and warnings and which allows logins in single user
+	  mode).  Note that the firmware uses ttyS0 as the serial console on
+	  the Maxine and ttyS2 on the others.
+
+	  If unsure, say Y.
+
+config ZS
+	bool "Z85C30 Serial Support"
+	depends on SERIAL_DEC
+	default y
+	help
+	  Documentation on the Zilog 85C350 serial communications controller
+	  is downloadable at <http://www.zilog.com/pdfs/serial/z85c30.pdf>
+
 config A2232
 	tristate "Commodore A2232 serial support (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && ZORRO && BROKEN_ON_SMP
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index e542a62..55392a4 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -18,11 +18,14 @@
 #define PCI_DEVICE_ID_INTEL_82965Q_IG       0x2992
 #define PCI_DEVICE_ID_INTEL_82965G_HB       0x29A0
 #define PCI_DEVICE_ID_INTEL_82965G_IG       0x29A2
+#define PCI_DEVICE_ID_INTEL_82965GM_HB      0x2A00
+#define PCI_DEVICE_ID_INTEL_82965GM_IG      0x2A02
 
 #define IS_I965 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82946GZ_HB || \
                  agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_1_HB || \
                  agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \
-                 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB)
+                 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \
+                 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB)
 
 
 extern int agp_memory_reserved;
@@ -428,9 +431,8 @@
 
 	if (IS_I965) {
 		u32 pgetbl_ctl;
+		pgetbl_ctl = readl(intel_i830_private.registers+I810_PGETBL_CTL);
 
-		pci_read_config_dword(agp_bridge->dev, I810_PGETBL_CTL,
-				      &pgetbl_ctl);
 		/* The 965 has a field telling us the size of the GTT,
 		 * which may be larger than what is necessary to map the
 		 * aperture.
@@ -1921,7 +1923,13 @@
 			bridge->driver = &intel_845_driver;
 		name = "965G";
 		break;
-
+	case PCI_DEVICE_ID_INTEL_82965GM_HB:
+		if (find_i830(PCI_DEVICE_ID_INTEL_82965GM_IG))
+			bridge->driver = &intel_i965_driver;
+		else
+			bridge->driver = &intel_845_driver;
+		name = "965GM";
+		break;
 	case PCI_DEVICE_ID_INTEL_7505_0:
 		bridge->driver = &intel_7505_driver;
 		name = "E7505";
@@ -2080,6 +2088,7 @@
 	ID(PCI_DEVICE_ID_INTEL_82965G_1_HB),
 	ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
 	ID(PCI_DEVICE_ID_INTEL_82965G_HB),
+	ID(PCI_DEVICE_ID_INTEL_82965GM_HB),
 	{ }
 };
 
diff --git a/drivers/char/drm/Makefile b/drivers/char/drm/Makefile
index 3ad0f64..6915a05 100644
--- a/drivers/char/drm/Makefile
+++ b/drivers/char/drm/Makefile
@@ -15,7 +15,6 @@
 i830-objs   := i830_drv.o i830_dma.o i830_irq.o
 i915-objs   := i915_drv.o i915_dma.o i915_irq.o i915_mem.o
 radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o
-ffb-objs    := ffb_drv.o ffb_context.o
 sis-objs    := sis_drv.o sis_mm.o
 savage-objs := savage_drv.o savage_bci.o savage_state.o
 via-objs    := via_irq.o via_drv.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o via_dmablit.o
@@ -36,7 +35,6 @@
 obj-$(CONFIG_DRM_I810)	+= i810.o
 obj-$(CONFIG_DRM_I830)	+= i830.o
 obj-$(CONFIG_DRM_I915)  += i915.o
-obj-$(CONFIG_DRM_FFB)   += ffb.o
 obj-$(CONFIG_DRM_SIS)   += sis.o
 obj-$(CONFIG_DRM_SAVAGE)+= savage.o
 obj-$(CONFIG_DRM_VIA)	+=via.o
diff --git a/drivers/char/drm/ffb_context.c b/drivers/char/drm/ffb_context.c
deleted file mode 100644
index ac9ab40..0000000
--- a/drivers/char/drm/ffb_context.c
+++ /dev/null
@@ -1,544 +0,0 @@
-/* $Id: ffb_context.c,v 1.5 2001/08/09 17:47:51 davem Exp $
- * ffb_context.c: Creator/Creator3D DRI/DRM context switching.
- *
- * Copyright (C) 2000 David S. Miller (davem@redhat.com)
- *
- * Almost entirely stolen from tdfx_context.c, see there
- * for authors.
- */
-
-#include <asm/upa.h>
-
-#include "ffb.h"
-#include "drmP.h"
-
-#include "ffb_drv.h"
-
-static int DRM(alloc_queue) (drm_device_t * dev, int is_2d_only) {
-	ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
-	int i;
-
-	for (i = 0; i < FFB_MAX_CTXS; i++) {
-		if (fpriv->hw_state[i] == NULL)
-			break;
-	}
-	if (i == FFB_MAX_CTXS)
-		return -1;
-
-	fpriv->hw_state[i] = kmalloc(sizeof(struct ffb_hw_context), GFP_KERNEL);
-	if (fpriv->hw_state[i] == NULL)
-		return -1;
-
-	fpriv->hw_state[i]->is_2d_only = is_2d_only;
-
-	/* Plus one because 0 is the special DRM_KERNEL_CONTEXT. */
-	return i + 1;
-}
-
-static void ffb_save_context(ffb_dev_priv_t * fpriv, int idx)
-{
-	ffb_fbcPtr ffb = fpriv->regs;
-	struct ffb_hw_context *ctx;
-	int i;
-
-	ctx = fpriv->hw_state[idx - 1];
-	if (idx == 0 || ctx == NULL)
-		return;
-
-	if (ctx->is_2d_only) {
-		/* 2D applications only care about certain pieces
-		 * of state.
-		 */
-		ctx->drawop = upa_readl(&ffb->drawop);
-		ctx->ppc = upa_readl(&ffb->ppc);
-		ctx->wid = upa_readl(&ffb->wid);
-		ctx->fg = upa_readl(&ffb->fg);
-		ctx->bg = upa_readl(&ffb->bg);
-		ctx->xclip = upa_readl(&ffb->xclip);
-		ctx->fbc = upa_readl(&ffb->fbc);
-		ctx->rop = upa_readl(&ffb->rop);
-		ctx->cmp = upa_readl(&ffb->cmp);
-		ctx->matchab = upa_readl(&ffb->matchab);
-		ctx->magnab = upa_readl(&ffb->magnab);
-		ctx->pmask = upa_readl(&ffb->pmask);
-		ctx->xpmask = upa_readl(&ffb->xpmask);
-		ctx->lpat = upa_readl(&ffb->lpat);
-		ctx->fontxy = upa_readl(&ffb->fontxy);
-		ctx->fontw = upa_readl(&ffb->fontw);
-		ctx->fontinc = upa_readl(&ffb->fontinc);
-
-		/* stencil/stencilctl only exists on FFB2+ and later
-		 * due to the introduction of 3DRAM-III.
-		 */
-		if (fpriv->ffb_type == ffb2_vertical_plus ||
-		    fpriv->ffb_type == ffb2_horizontal_plus) {
-			ctx->stencil = upa_readl(&ffb->stencil);
-			ctx->stencilctl = upa_readl(&ffb->stencilctl);
-		}
-
-		for (i = 0; i < 32; i++)
-			ctx->area_pattern[i] = upa_readl(&ffb->pattern[i]);
-		ctx->ucsr = upa_readl(&ffb->ucsr);
-		return;
-	}
-
-	/* Fetch drawop. */
-	ctx->drawop = upa_readl(&ffb->drawop);
-
-	/* If we were saving the vertex registers, this is where
-	 * we would do it.  We would save 32 32-bit words starting
-	 * at ffb->suvtx.
-	 */
-
-	/* Capture rendering attributes. */
-
-	ctx->ppc = upa_readl(&ffb->ppc);	/* Pixel Processor Control */
-	ctx->wid = upa_readl(&ffb->wid);	/* Current WID */
-	ctx->fg = upa_readl(&ffb->fg);	/* Constant FG color */
-	ctx->bg = upa_readl(&ffb->bg);	/* Constant BG color */
-	ctx->consty = upa_readl(&ffb->consty);	/* Constant Y */
-	ctx->constz = upa_readl(&ffb->constz);	/* Constant Z */
-	ctx->xclip = upa_readl(&ffb->xclip);	/* X plane clip */
-	ctx->dcss = upa_readl(&ffb->dcss);	/* Depth Cue Scale Slope */
-	ctx->vclipmin = upa_readl(&ffb->vclipmin);	/* Primary XY clip, minimum */
-	ctx->vclipmax = upa_readl(&ffb->vclipmax);	/* Primary XY clip, maximum */
-	ctx->vclipzmin = upa_readl(&ffb->vclipzmin);	/* Primary Z clip, minimum */
-	ctx->vclipzmax = upa_readl(&ffb->vclipzmax);	/* Primary Z clip, maximum */
-	ctx->dcsf = upa_readl(&ffb->dcsf);	/* Depth Cue Scale Front Bound */
-	ctx->dcsb = upa_readl(&ffb->dcsb);	/* Depth Cue Scale Back Bound */
-	ctx->dczf = upa_readl(&ffb->dczf);	/* Depth Cue Scale Z Front */
-	ctx->dczb = upa_readl(&ffb->dczb);	/* Depth Cue Scale Z Back */
-	ctx->blendc = upa_readl(&ffb->blendc);	/* Alpha Blend Control */
-	ctx->blendc1 = upa_readl(&ffb->blendc1);	/* Alpha Blend Color 1 */
-	ctx->blendc2 = upa_readl(&ffb->blendc2);	/* Alpha Blend Color 2 */
-	ctx->fbc = upa_readl(&ffb->fbc);	/* Frame Buffer Control */
-	ctx->rop = upa_readl(&ffb->rop);	/* Raster Operation */
-	ctx->cmp = upa_readl(&ffb->cmp);	/* Compare Controls */
-	ctx->matchab = upa_readl(&ffb->matchab);	/* Buffer A/B Match Ops */
-	ctx->matchc = upa_readl(&ffb->matchc);	/* Buffer C Match Ops */
-	ctx->magnab = upa_readl(&ffb->magnab);	/* Buffer A/B Magnitude Ops */
-	ctx->magnc = upa_readl(&ffb->magnc);	/* Buffer C Magnitude Ops */
-	ctx->pmask = upa_readl(&ffb->pmask);	/* RGB Plane Mask */
-	ctx->xpmask = upa_readl(&ffb->xpmask);	/* X Plane Mask */
-	ctx->ypmask = upa_readl(&ffb->ypmask);	/* Y Plane Mask */
-	ctx->zpmask = upa_readl(&ffb->zpmask);	/* Z Plane Mask */
-
-	/* Auxiliary Clips. */
-	ctx->auxclip0min = upa_readl(&ffb->auxclip[0].min);
-	ctx->auxclip0max = upa_readl(&ffb->auxclip[0].max);
-	ctx->auxclip1min = upa_readl(&ffb->auxclip[1].min);
-	ctx->auxclip1max = upa_readl(&ffb->auxclip[1].max);
-	ctx->auxclip2min = upa_readl(&ffb->auxclip[2].min);
-	ctx->auxclip2max = upa_readl(&ffb->auxclip[2].max);
-	ctx->auxclip3min = upa_readl(&ffb->auxclip[3].min);
-	ctx->auxclip3max = upa_readl(&ffb->auxclip[3].max);
-
-	ctx->lpat = upa_readl(&ffb->lpat);	/* Line Pattern */
-	ctx->fontxy = upa_readl(&ffb->fontxy);	/* XY Font Coordinate */
-	ctx->fontw = upa_readl(&ffb->fontw);	/* Font Width */
-	ctx->fontinc = upa_readl(&ffb->fontinc);	/* Font X/Y Increment */
-
-	/* These registers/features only exist on FFB2 and later chips. */
-	if (fpriv->ffb_type >= ffb2_prototype) {
-		ctx->dcss1 = upa_readl(&ffb->dcss1);	/* Depth Cue Scale Slope 1 */
-		ctx->dcss2 = upa_readl(&ffb->dcss2);	/* Depth Cue Scale Slope 2 */
-		ctx->dcss2 = upa_readl(&ffb->dcss3);	/* Depth Cue Scale Slope 3 */
-		ctx->dcs2 = upa_readl(&ffb->dcs2);	/* Depth Cue Scale 2 */
-		ctx->dcs3 = upa_readl(&ffb->dcs3);	/* Depth Cue Scale 3 */
-		ctx->dcs4 = upa_readl(&ffb->dcs4);	/* Depth Cue Scale 4 */
-		ctx->dcd2 = upa_readl(&ffb->dcd2);	/* Depth Cue Depth 2 */
-		ctx->dcd3 = upa_readl(&ffb->dcd3);	/* Depth Cue Depth 3 */
-		ctx->dcd4 = upa_readl(&ffb->dcd4);	/* Depth Cue Depth 4 */
-
-		/* And stencil/stencilctl only exists on FFB2+ and later
-		 * due to the introduction of 3DRAM-III.
-		 */
-		if (fpriv->ffb_type == ffb2_vertical_plus ||
-		    fpriv->ffb_type == ffb2_horizontal_plus) {
-			ctx->stencil = upa_readl(&ffb->stencil);
-			ctx->stencilctl = upa_readl(&ffb->stencilctl);
-		}
-	}
-
-	/* Save the 32x32 area pattern. */
-	for (i = 0; i < 32; i++)
-		ctx->area_pattern[i] = upa_readl(&ffb->pattern[i]);
-
-	/* Finally, stash away the User Constol/Status Register. */
-	ctx->ucsr = upa_readl(&ffb->ucsr);
-}
-
-static void ffb_restore_context(ffb_dev_priv_t * fpriv, int old, int idx)
-{
-	ffb_fbcPtr ffb = fpriv->regs;
-	struct ffb_hw_context *ctx;
-	int i;
-
-	ctx = fpriv->hw_state[idx - 1];
-	if (idx == 0 || ctx == NULL)
-		return;
-
-	if (ctx->is_2d_only) {
-		/* 2D applications only care about certain pieces
-		 * of state.
-		 */
-		upa_writel(ctx->drawop, &ffb->drawop);
-
-		/* If we were restoring the vertex registers, this is where
-		 * we would do it.  We would restore 32 32-bit words starting
-		 * at ffb->suvtx.
-		 */
-
-		upa_writel(ctx->ppc, &ffb->ppc);
-		upa_writel(ctx->wid, &ffb->wid);
-		upa_writel(ctx->fg, &ffb->fg);
-		upa_writel(ctx->bg, &ffb->bg);
-		upa_writel(ctx->xclip, &ffb->xclip);
-		upa_writel(ctx->fbc, &ffb->fbc);
-		upa_writel(ctx->rop, &ffb->rop);
-		upa_writel(ctx->cmp, &ffb->cmp);
-		upa_writel(ctx->matchab, &ffb->matchab);
-		upa_writel(ctx->magnab, &ffb->magnab);
-		upa_writel(ctx->pmask, &ffb->pmask);
-		upa_writel(ctx->xpmask, &ffb->xpmask);
-		upa_writel(ctx->lpat, &ffb->lpat);
-		upa_writel(ctx->fontxy, &ffb->fontxy);
-		upa_writel(ctx->fontw, &ffb->fontw);
-		upa_writel(ctx->fontinc, &ffb->fontinc);
-
-		/* stencil/stencilctl only exists on FFB2+ and later
-		 * due to the introduction of 3DRAM-III.
-		 */
-		if (fpriv->ffb_type == ffb2_vertical_plus ||
-		    fpriv->ffb_type == ffb2_horizontal_plus) {
-			upa_writel(ctx->stencil, &ffb->stencil);
-			upa_writel(ctx->stencilctl, &ffb->stencilctl);
-			upa_writel(0x80000000, &ffb->fbc);
-			upa_writel((ctx->stencilctl | 0x80000),
-				   &ffb->rawstencilctl);
-			upa_writel(ctx->fbc, &ffb->fbc);
-		}
-
-		for (i = 0; i < 32; i++)
-			upa_writel(ctx->area_pattern[i], &ffb->pattern[i]);
-		upa_writel((ctx->ucsr & 0xf0000), &ffb->ucsr);
-		return;
-	}
-
-	/* Restore drawop. */
-	upa_writel(ctx->drawop, &ffb->drawop);
-
-	/* If we were restoring the vertex registers, this is where
-	 * we would do it.  We would restore 32 32-bit words starting
-	 * at ffb->suvtx.
-	 */
-
-	/* Restore rendering attributes. */
-
-	upa_writel(ctx->ppc, &ffb->ppc);	/* Pixel Processor Control */
-	upa_writel(ctx->wid, &ffb->wid);	/* Current WID */
-	upa_writel(ctx->fg, &ffb->fg);	/* Constant FG color */
-	upa_writel(ctx->bg, &ffb->bg);	/* Constant BG color */
-	upa_writel(ctx->consty, &ffb->consty);	/* Constant Y */
-	upa_writel(ctx->constz, &ffb->constz);	/* Constant Z */
-	upa_writel(ctx->xclip, &ffb->xclip);	/* X plane clip */
-	upa_writel(ctx->dcss, &ffb->dcss);	/* Depth Cue Scale Slope */
-	upa_writel(ctx->vclipmin, &ffb->vclipmin);	/* Primary XY clip, minimum */
-	upa_writel(ctx->vclipmax, &ffb->vclipmax);	/* Primary XY clip, maximum */
-	upa_writel(ctx->vclipzmin, &ffb->vclipzmin);	/* Primary Z clip, minimum */
-	upa_writel(ctx->vclipzmax, &ffb->vclipzmax);	/* Primary Z clip, maximum */
-	upa_writel(ctx->dcsf, &ffb->dcsf);	/* Depth Cue Scale Front Bound */
-	upa_writel(ctx->dcsb, &ffb->dcsb);	/* Depth Cue Scale Back Bound */
-	upa_writel(ctx->dczf, &ffb->dczf);	/* Depth Cue Scale Z Front */
-	upa_writel(ctx->dczb, &ffb->dczb);	/* Depth Cue Scale Z Back */
-	upa_writel(ctx->blendc, &ffb->blendc);	/* Alpha Blend Control */
-	upa_writel(ctx->blendc1, &ffb->blendc1);	/* Alpha Blend Color 1 */
-	upa_writel(ctx->blendc2, &ffb->blendc2);	/* Alpha Blend Color 2 */
-	upa_writel(ctx->fbc, &ffb->fbc);	/* Frame Buffer Control */
-	upa_writel(ctx->rop, &ffb->rop);	/* Raster Operation */
-	upa_writel(ctx->cmp, &ffb->cmp);	/* Compare Controls */
-	upa_writel(ctx->matchab, &ffb->matchab);	/* Buffer A/B Match Ops */
-	upa_writel(ctx->matchc, &ffb->matchc);	/* Buffer C Match Ops */
-	upa_writel(ctx->magnab, &ffb->magnab);	/* Buffer A/B Magnitude Ops */
-	upa_writel(ctx->magnc, &ffb->magnc);	/* Buffer C Magnitude Ops */
-	upa_writel(ctx->pmask, &ffb->pmask);	/* RGB Plane Mask */
-	upa_writel(ctx->xpmask, &ffb->xpmask);	/* X Plane Mask */
-	upa_writel(ctx->ypmask, &ffb->ypmask);	/* Y Plane Mask */
-	upa_writel(ctx->zpmask, &ffb->zpmask);	/* Z Plane Mask */
-
-	/* Auxiliary Clips. */
-	upa_writel(ctx->auxclip0min, &ffb->auxclip[0].min);
-	upa_writel(ctx->auxclip0max, &ffb->auxclip[0].max);
-	upa_writel(ctx->auxclip1min, &ffb->auxclip[1].min);
-	upa_writel(ctx->auxclip1max, &ffb->auxclip[1].max);
-	upa_writel(ctx->auxclip2min, &ffb->auxclip[2].min);
-	upa_writel(ctx->auxclip2max, &ffb->auxclip[2].max);
-	upa_writel(ctx->auxclip3min, &ffb->auxclip[3].min);
-	upa_writel(ctx->auxclip3max, &ffb->auxclip[3].max);
-
-	upa_writel(ctx->lpat, &ffb->lpat);	/* Line Pattern */
-	upa_writel(ctx->fontxy, &ffb->fontxy);	/* XY Font Coordinate */
-	upa_writel(ctx->fontw, &ffb->fontw);	/* Font Width */
-	upa_writel(ctx->fontinc, &ffb->fontinc);	/* Font X/Y Increment */
-
-	/* These registers/features only exist on FFB2 and later chips. */
-	if (fpriv->ffb_type >= ffb2_prototype) {
-		upa_writel(ctx->dcss1, &ffb->dcss1);	/* Depth Cue Scale Slope 1 */
-		upa_writel(ctx->dcss2, &ffb->dcss2);	/* Depth Cue Scale Slope 2 */
-		upa_writel(ctx->dcss3, &ffb->dcss2);	/* Depth Cue Scale Slope 3 */
-		upa_writel(ctx->dcs2, &ffb->dcs2);	/* Depth Cue Scale 2 */
-		upa_writel(ctx->dcs3, &ffb->dcs3);	/* Depth Cue Scale 3 */
-		upa_writel(ctx->dcs4, &ffb->dcs4);	/* Depth Cue Scale 4 */
-		upa_writel(ctx->dcd2, &ffb->dcd2);	/* Depth Cue Depth 2 */
-		upa_writel(ctx->dcd3, &ffb->dcd3);	/* Depth Cue Depth 3 */
-		upa_writel(ctx->dcd4, &ffb->dcd4);	/* Depth Cue Depth 4 */
-
-		/* And stencil/stencilctl only exists on FFB2+ and later
-		 * due to the introduction of 3DRAM-III.
-		 */
-		if (fpriv->ffb_type == ffb2_vertical_plus ||
-		    fpriv->ffb_type == ffb2_horizontal_plus) {
-			/* Unfortunately, there is a hardware bug on
-			 * the FFB2+ chips which prevents a normal write
-			 * to the stencil control register from working
-			 * as it should.
-			 *
-			 * The state controlled by the FFB stencilctl register
-			 * really gets transferred to the per-buffer instances
-			 * of the stencilctl register in the 3DRAM chips.
-			 *
-			 * The bug is that FFB does not update buffer C correctly,
-			 * so we have to do it by hand for them.
-			 */
-
-			/* This will update buffers A and B. */
-			upa_writel(ctx->stencil, &ffb->stencil);
-			upa_writel(ctx->stencilctl, &ffb->stencilctl);
-
-			/* Force FFB to use buffer C 3dram regs. */
-			upa_writel(0x80000000, &ffb->fbc);
-			upa_writel((ctx->stencilctl | 0x80000),
-				   &ffb->rawstencilctl);
-
-			/* Now restore the correct FBC controls. */
-			upa_writel(ctx->fbc, &ffb->fbc);
-		}
-	}
-
-	/* Restore the 32x32 area pattern. */
-	for (i = 0; i < 32; i++)
-		upa_writel(ctx->area_pattern[i], &ffb->pattern[i]);
-
-	/* Finally, stash away the User Constol/Status Register.
-	 * The only state we really preserve here is the picking
-	 * control.
-	 */
-	upa_writel((ctx->ucsr & 0xf0000), &ffb->ucsr);
-}
-
-#define FFB_UCSR_FB_BUSY       0x01000000
-#define FFB_UCSR_RP_BUSY       0x02000000
-#define FFB_UCSR_ALL_BUSY      (FFB_UCSR_RP_BUSY|FFB_UCSR_FB_BUSY)
-
-static void FFBWait(ffb_fbcPtr ffb)
-{
-	int limit = 100000;
-
-	do {
-		u32 regval = upa_readl(&ffb->ucsr);
-
-		if ((regval & FFB_UCSR_ALL_BUSY) == 0)
-			break;
-	} while (--limit);
-}
-
-int ffb_driver_context_switch(drm_device_t * dev, int old, int new)
-{
-	ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
-
-#ifdef DRM_DMA_HISTOGRAM
-	dev->ctx_start = get_cycles();
-#endif
-
-	DRM_DEBUG("Context switch from %d to %d\n", old, new);
-
-	if (new == dev->last_context || dev->last_context == 0) {
-		dev->last_context = new;
-		return 0;
-	}
-
-	FFBWait(fpriv->regs);
-	ffb_save_context(fpriv, old);
-	ffb_restore_context(fpriv, old, new);
-	FFBWait(fpriv->regs);
-
-	dev->last_context = new;
-
-	return 0;
-}
-
-int ffb_driver_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
-		      unsigned long arg)
-{
-	drm_ctx_res_t res;
-	drm_ctx_t ctx;
-	int i;
-
-	DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
-	if (copy_from_user(&res, (drm_ctx_res_t __user *) arg, sizeof(res)))
-		return -EFAULT;
-	if (res.count >= DRM_RESERVED_CONTEXTS) {
-		memset(&ctx, 0, sizeof(ctx));
-		for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
-			ctx.handle = i;
-			if (copy_to_user(&res.contexts[i], &i, sizeof(i)))
-				return -EFAULT;
-		}
-	}
-	res.count = DRM_RESERVED_CONTEXTS;
-	if (copy_to_user((drm_ctx_res_t __user *) arg, &res, sizeof(res)))
-		return -EFAULT;
-	return 0;
-}
-
-int ffb_driver_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
-		      unsigned long arg)
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_ctx_t ctx;
-	int idx;
-
-	if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
-		return -EFAULT;
-	idx = DRM(alloc_queue) (dev, (ctx.flags & _DRM_CONTEXT_2DONLY));
-	if (idx < 0)
-		return -ENFILE;
-
-	DRM_DEBUG("%d\n", ctx.handle);
-	ctx.handle = idx;
-	if (copy_to_user((drm_ctx_t __user *) arg, &ctx, sizeof(ctx)))
-		return -EFAULT;
-	return 0;
-}
-
-int ffb_driver_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
-		      unsigned long arg)
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
-	struct ffb_hw_context *hwctx;
-	drm_ctx_t ctx;
-	int idx;
-
-	if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
-		return -EFAULT;
-
-	idx = ctx.handle;
-	if (idx <= 0 || idx >= FFB_MAX_CTXS)
-		return -EINVAL;
-
-	hwctx = fpriv->hw_state[idx - 1];
-	if (hwctx == NULL)
-		return -EINVAL;
-
-	if ((ctx.flags & _DRM_CONTEXT_2DONLY) == 0)
-		hwctx->is_2d_only = 0;
-	else
-		hwctx->is_2d_only = 1;
-
-	return 0;
-}
-
-int ffb_driver_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
-		      unsigned long arg)
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
-	struct ffb_hw_context *hwctx;
-	drm_ctx_t ctx;
-	int idx;
-
-	if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
-		return -EFAULT;
-
-	idx = ctx.handle;
-	if (idx <= 0 || idx >= FFB_MAX_CTXS)
-		return -EINVAL;
-
-	hwctx = fpriv->hw_state[idx - 1];
-	if (hwctx == NULL)
-		return -EINVAL;
-
-	if (hwctx->is_2d_only != 0)
-		ctx.flags = _DRM_CONTEXT_2DONLY;
-	else
-		ctx.flags = 0;
-
-	if (copy_to_user((drm_ctx_t __user *) arg, &ctx, sizeof(ctx)))
-		return -EFAULT;
-
-	return 0;
-}
-
-int ffb_driver_switchctx(struct inode *inode, struct file *filp,
-			 unsigned int cmd, unsigned long arg)
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	drm_ctx_t ctx;
-
-	if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
-		return -EFAULT;
-	DRM_DEBUG("%d\n", ctx.handle);
-	return ffb_driver_context_switch(dev, dev->last_context, ctx.handle);
-}
-
-int ffb_driver_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
-		      unsigned long arg)
-{
-	drm_ctx_t ctx;
-
-	if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
-		return -EFAULT;
-	DRM_DEBUG("%d\n", ctx.handle);
-
-	return 0;
-}
-
-int ffb_driver_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
-		     unsigned long arg)
-{
-	drm_ctx_t ctx;
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
-	ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
-	int idx;
-
-	if (copy_from_user(&ctx, (drm_ctx_t __user *) arg, sizeof(ctx)))
-		return -EFAULT;
-	DRM_DEBUG("%d\n", ctx.handle);
-
-	idx = ctx.handle - 1;
-	if (idx < 0 || idx >= FFB_MAX_CTXS)
-		return -EINVAL;
-
-	kfree(fpriv->hw_state[idx]);
-	fpriv->hw_state[idx] = NULL;
-	return 0;
-}
-
-void ffb_set_context_ioctls(void)
-{
-	DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)].func = ffb_driver_addctx;
-	DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)].func = ffb_driver_rmctx;
-	DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)].func = ffb_driver_modctx;
-	DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)].func = ffb_driver_getctx;
-	DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)].func =
-	    ffb_driver_switchctx;
-	DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)].func = ffb_driver_newctx;
-	DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)].func = ffb_driver_resctx;
-
-}
diff --git a/drivers/char/drm/ffb_drv.c b/drivers/char/drm/ffb_drv.c
deleted file mode 100644
index 9a19879..0000000
--- a/drivers/char/drm/ffb_drv.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/* $Id: ffb_drv.c,v 1.16 2001/10/18 16:00:24 davem Exp $
- * ffb_drv.c: Creator/Creator3D direct rendering driver.
- *
- * Copyright (C) 2000 David S. Miller (davem@redhat.com)
- */
-
-#include "ffb.h"
-#include "drmP.h"
-
-#include "ffb_drv.h"
-
-#include <linux/smp_lock.h>
-#include <asm/shmparam.h>
-#include <asm/oplib.h>
-#include <asm/upa.h>
-
-#define DRIVER_AUTHOR		"David S. Miller"
-
-#define DRIVER_NAME		"ffb"
-#define DRIVER_DESC		"Creator/Creator3D"
-#define DRIVER_DATE		"20000517"
-
-#define DRIVER_MAJOR		0
-#define DRIVER_MINOR		0
-#define DRIVER_PATCHLEVEL	1
-
-typedef struct _ffb_position_t {
-	int node;
-	int root;
-} ffb_position_t;
-
-static ffb_position_t *ffb_position;
-
-static void get_ffb_type(ffb_dev_priv_t * ffb_priv, int instance)
-{
-	volatile unsigned char *strap_bits;
-	unsigned char val;
-
-	strap_bits = (volatile unsigned char *)
-	    (ffb_priv->card_phys_base + 0x00200000UL);
-
-	/* Don't ask, you have to read the value twice for whatever
-	 * reason to get correct contents.
-	 */
-	val = upa_readb(strap_bits);
-	val = upa_readb(strap_bits);
-	switch (val & 0x78) {
-	case (0x0 << 5) | (0x0 << 3):
-		ffb_priv->ffb_type = ffb1_prototype;
-		printk("ffb%d: Detected FFB1 pre-FCS prototype\n", instance);
-		break;
-	case (0x0 << 5) | (0x1 << 3):
-		ffb_priv->ffb_type = ffb1_standard;
-		printk("ffb%d: Detected FFB1\n", instance);
-		break;
-	case (0x0 << 5) | (0x3 << 3):
-		ffb_priv->ffb_type = ffb1_speedsort;
-		printk("ffb%d: Detected FFB1-SpeedSort\n", instance);
-		break;
-	case (0x1 << 5) | (0x0 << 3):
-		ffb_priv->ffb_type = ffb2_prototype;
-		printk("ffb%d: Detected FFB2/vertical pre-FCS prototype\n",
-		       instance);
-		break;
-	case (0x1 << 5) | (0x1 << 3):
-		ffb_priv->ffb_type = ffb2_vertical;
-		printk("ffb%d: Detected FFB2/vertical\n", instance);
-		break;
-	case (0x1 << 5) | (0x2 << 3):
-		ffb_priv->ffb_type = ffb2_vertical_plus;
-		printk("ffb%d: Detected FFB2+/vertical\n", instance);
-		break;
-	case (0x2 << 5) | (0x0 << 3):
-		ffb_priv->ffb_type = ffb2_horizontal;
-		printk("ffb%d: Detected FFB2/horizontal\n", instance);
-		break;
-	case (0x2 << 5) | (0x2 << 3):
-		ffb_priv->ffb_type = ffb2_horizontal;
-		printk("ffb%d: Detected FFB2+/horizontal\n", instance);
-		break;
-	default:
-		ffb_priv->ffb_type = ffb2_vertical;
-		printk("ffb%d: Unknown boardID[%08x], assuming FFB2\n",
-		       instance, val);
-		break;
-	};
-}
-
-static void ffb_apply_upa_parent_ranges(int parent,
-					struct linux_prom64_registers *regs)
-{
-	struct linux_prom64_ranges ranges[PROMREG_MAX];
-	char name[128];
-	int len, i;
-
-	prom_getproperty(parent, "name", name, sizeof(name));
-	if (strcmp(name, "upa") != 0)
-		return;
-
-	len =
-	    prom_getproperty(parent, "ranges", (void *)ranges, sizeof(ranges));
-	if (len <= 0)
-		return;
-
-	len /= sizeof(struct linux_prom64_ranges);
-	for (i = 0; i < len; i++) {
-		struct linux_prom64_ranges *rng = &ranges[i];
-		u64 phys_addr = regs->phys_addr;
-
-		if (phys_addr >= rng->ot_child_base &&
-		    phys_addr < (rng->ot_child_base + rng->or_size)) {
-			regs->phys_addr -= rng->ot_child_base;
-			regs->phys_addr += rng->ot_parent_base;
-			return;
-		}
-	}
-
-	return;
-}
-
-static int ffb_init_one(drm_device_t * dev, int prom_node, int parent_node,
-			int instance)
-{
-	struct linux_prom64_registers regs[2 * PROMREG_MAX];
-	ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *) dev->dev_private;
-	int i;
-
-	ffb_priv->prom_node = prom_node;
-	if (prom_getproperty(ffb_priv->prom_node, "reg",
-			     (void *)regs, sizeof(regs)) <= 0) {
-		return -EINVAL;
-	}
-	ffb_apply_upa_parent_ranges(parent_node, &regs[0]);
-	ffb_priv->card_phys_base = regs[0].phys_addr;
-	ffb_priv->regs = (ffb_fbcPtr)
-	    (regs[0].phys_addr + 0x00600000UL);
-	get_ffb_type(ffb_priv, instance);
-	for (i = 0; i < FFB_MAX_CTXS; i++)
-		ffb_priv->hw_state[i] = NULL;
-
-	return 0;
-}
-
-static drm_map_t *ffb_find_map(struct file *filp, unsigned long off)
-{
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev;
-	drm_map_list_t *r_list;
-	struct list_head *list;
-	drm_map_t *map;
-
-	if (!priv || (dev = priv->dev) == NULL)
-		return NULL;
-
-	list_for_each(list, &dev->maplist->head) {
-		r_list = (drm_map_list_t *) list;
-		map = r_list->map;
-		if (!map)
-			continue;
-		if (r_list->user_token == off)
-			return map;
-	}
-
-	return NULL;
-}
-
-unsigned long ffb_get_unmapped_area(struct file *filp,
-				    unsigned long hint,
-				    unsigned long len,
-				    unsigned long pgoff, unsigned long flags)
-{
-	drm_map_t *map = ffb_find_map(filp, pgoff << PAGE_SHIFT);
-	unsigned long addr = -ENOMEM;
-
-	if (!map)
-		return get_unmapped_area(NULL, hint, len, pgoff, flags);
-
-	if (map->type == _DRM_FRAME_BUFFER || map->type == _DRM_REGISTERS) {
-#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
-		addr = get_fb_unmapped_area(filp, hint, len, pgoff, flags);
-#else
-		addr = get_unmapped_area(NULL, hint, len, pgoff, flags);
-#endif
-	} else if (map->type == _DRM_SHM && SHMLBA > PAGE_SIZE) {
-		unsigned long slack = SHMLBA - PAGE_SIZE;
-
-		addr = get_unmapped_area(NULL, hint, len + slack, pgoff, flags);
-		if (!(addr & ~PAGE_MASK)) {
-			unsigned long kvirt = (unsigned long)map->handle;
-
-			if ((kvirt & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) {
-				unsigned long koff, aoff;
-
-				koff = kvirt & (SHMLBA - 1);
-				aoff = addr & (SHMLBA - 1);
-				if (koff < aoff)
-					koff += SHMLBA;
-
-				addr += (koff - aoff);
-			}
-		}
-	} else {
-		addr = get_unmapped_area(NULL, hint, len, pgoff, flags);
-	}
-
-	return addr;
-}
-
-static int ffb_presetup(drm_device_t * dev)
-{
-	ffb_dev_priv_t *ffb_priv;
-	int ret = 0;
-	int i = 0;
-
-	/* Check for the case where no device was found. */
-	if (ffb_position == NULL)
-		return -ENODEV;
-
-	/* code used to use numdevs no numdevs anymore */
-	ffb_priv = kmalloc(sizeof(ffb_dev_priv_t), GFP_KERNEL);
-	if (!ffb_priv)
-		return -ENOMEM;
-	memset(ffb_priv, 0, sizeof(*ffb_priv));
-	dev->dev_private = ffb_priv;
-
-	ret = ffb_init_one(dev, ffb_position[i].node, ffb_position[i].root, i);
-	return ret;
-}
-
-static void ffb_driver_release(drm_device_t * dev, struct file *filp)
-{
-	ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
-	int context = _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock);
-	int idx;
-
-	idx = context - 1;
-	if (fpriv &&
-	    context != DRM_KERNEL_CONTEXT && fpriv->hw_state[idx] != NULL) {
-		kfree(fpriv->hw_state[idx]);
-		fpriv->hw_state[idx] = NULL;
-	}
-}
-
-static void ffb_driver_pretakedown(drm_device_t * dev)
-{
-	kfree(dev->dev_private);
-}
-
-static int ffb_driver_postcleanup(drm_device_t * dev)
-{
-	kfree(ffb_position);
-	return 0;
-}
-
-static void ffb_driver_kernel_context_switch_unlock(struct drm_device *dev,
-						    drm_lock_t * lock)
-{
-	dev->lock.filp = 0;
-	{
-		__volatile__ unsigned int *plock = &dev->lock.hw_lock->lock;
-		unsigned int old, new, prev, ctx;
-
-		ctx = lock->context;
-		do {
-			old = *plock;
-			new = ctx;
-			prev = cmpxchg(plock, old, new);
-		} while (prev != old);
-	}
-	wake_up_interruptible(&dev->lock.lock_queue);
-}
-
-static unsigned long ffb_driver_get_map_ofs(drm_map_t * map)
-{
-	return (map->offset & 0xffffffff);
-}
-
-static unsigned long ffb_driver_get_reg_ofs(drm_device_t * dev)
-{
-	ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *) dev->dev_private;
-
-	if (ffb_priv)
-		return ffb_priv->card_phys_base;
-
-	return 0;
-}
-
-static int postinit(struct drm_device *dev, unsigned long flags)
-{
-	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
-		 DRIVER_NAME,
-		 DRIVER_MAJOR,
-		 DRIVER_MINOR, DRIVER_PATCHLEVEL, DRIVER_DATE, dev->minor);
-	return 0;
-}
-
-static int version(drm_version_t * version)
-{
-	int len;
-
-	version->version_major = DRIVER_MAJOR;
-	version->version_minor = DRIVER_MINOR;
-	version->version_patchlevel = DRIVER_PATCHLEVEL;
-	DRM_COPY(version->name, DRIVER_NAME);
-	DRM_COPY(version->date, DRIVER_DATE);
-	DRM_COPY(version->desc, DRIVER_DESC);
-	return 0;
-}
-
-static drm_ioctl_desc_t ioctls[] = {
-
-};
-
-static struct drm_driver driver = {
-	.driver_features = 0,
-	.dev_priv_size = sizeof(u32),
-	.release = ffb_driver_release,
-	.presetup = ffb_presetup,
-	.pretakedown = ffb_driver_pretakedown,
-	.postcleanup = ffb_driver_postcleanup,
-	.kernel_context_switch = ffb_driver_context_switch,
-	.kernel_context_switch_unlock = ffb_driver_kernel_context_switch_unlock,
-	.get_map_ofs = ffb_driver_get_map_ofs,
-	.get_reg_ofs = ffb_driver_get_reg_ofs,
-	.postinit = postinit,
-	.version = version,
-	.ioctls = ioctls,
-	.num_ioctls = DRM_ARRAY_SIZE(ioctls),
-	.fops = {
-		 .owner = THIS_MODULE,
-		 .open = drm_open,
-		 .release = drm_release,
-		 .ioctl = drm_ioctl,
-		 .mmap = drm_mmap,
-		 .poll = drm_poll,
-		 .fasync = drm_fasync,
-		 }
-	,
-};
-
-static int __init ffb_init(void)
-{
-	return -ENODEV;
-}
-
-static void __exit ffb_exit(void)
-{
-}
-
-module_init(ffb_init);
-module_exit(ffb_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/ffb_drv.h b/drivers/char/drm/ffb_drv.h
deleted file mode 100644
index 582afa6d..0000000
--- a/drivers/char/drm/ffb_drv.h
+++ /dev/null
@@ -1,379 +0,0 @@
-/* $Id: ffb_drv.h,v 1.1 2000/06/01 04:24:39 davem Exp $
- * ffb_drv.h: Creator/Creator3D direct rendering driver.
- *
- * Copyright (C) 2000 David S. Miller (davem@redhat.com)
- */
-
-/* Auxilliary clips. */
-typedef struct {
-	volatile unsigned int min;
-	volatile unsigned int max;
-} ffb_auxclip, *ffb_auxclipPtr;
-
-/* FFB register set. */
-typedef struct _ffb_fbc {
-	/* Next vertex registers, on the right we list which drawops
-	 * use said register and the logical name the register has in
-	 * that context.
-	 *//* DESCRIPTION          DRAWOP(NAME)    */
-					/*0x00*/ unsigned int pad1[3];
-					/* Reserved                             */
-						/*0x0c*/ volatile unsigned int alpha;
-						/* ALPHA Transparency                   */
-						/*0x10*/ volatile unsigned int red;
-						/* RED                                  */
-						/*0x14*/ volatile unsigned int green;
-						/* GREEN                                */
-						/*0x18*/ volatile unsigned int blue;
-						/* BLUE                                 */
-						/*0x1c*/ volatile unsigned int z;
-						/* DEPTH                                */
-						/*0x20*/ volatile unsigned int y;
-						/* Y                    triangle(DOYF)  */
-	/*                      aadot(DYF)      */
-	/*                      ddline(DYF)     */
-	/*                      aaline(DYF)     */
-						/*0x24*/ volatile unsigned int x;
-						/* X                    triangle(DOXF)  */
-	/*                      aadot(DXF)      */
-	/*                      ddline(DXF)     */
-	/*                      aaline(DXF)     */
-					/*0x28*/ unsigned int pad2[2];
-					/* Reserved                             */
-						/*0x30*/ volatile unsigned int ryf;
-						/* Y (alias to DOYF)    ddline(RYF)     */
-	/*                      aaline(RYF)     */
-	/*                      triangle(RYF)   */
-						/*0x34*/ volatile unsigned int rxf;
-						/* X                    ddline(RXF)     */
-	/*                      aaline(RXF)     */
-	/*                      triangle(RXF)   */
-					/*0x38*/ unsigned int pad3[2];
-					/* Reserved                             */
-						/*0x40*/ volatile unsigned int dmyf;
-						/* Y (alias to DOYF)    triangle(DMYF)  */
-						/*0x44*/ volatile unsigned int dmxf;
-						/* X                    triangle(DMXF)  */
-					/*0x48*/ unsigned int pad4[2];
-					/* Reserved                             */
-						/*0x50*/ volatile unsigned int ebyi;
-						/* Y (alias to RYI)     polygon(EBYI)   */
-						/*0x54*/ volatile unsigned int ebxi;
-						/* X                    polygon(EBXI)   */
-					/*0x58*/ unsigned int pad5[2];
-					/* Reserved                             */
-						/*0x60*/ volatile unsigned int by;
-						/* Y                    brline(RYI)     */
-	/*                      fastfill(OP)    */
-	/*                      polygon(YI)     */
-	/*                      rectangle(YI)   */
-	/*                      bcopy(SRCY)     */
-	/*                      vscroll(SRCY)   */
-						/*0x64*/ volatile unsigned int bx;
-						/* X                    brline(RXI)     */
-	/*                      polygon(XI)     */
-	/*                      rectangle(XI)   */
-	/*                      bcopy(SRCX)     */
-	/*                      vscroll(SRCX)   */
-	/*                      fastfill(GO)    */
-						/*0x68*/ volatile unsigned int dy;
-						/* destination Y        fastfill(DSTY)  */
-	/*                      bcopy(DSRY)     */
-	/*                      vscroll(DSRY)   */
-						/*0x6c*/ volatile unsigned int dx;
-						/* destination X        fastfill(DSTX)  */
-	/*                      bcopy(DSTX)     */
-	/*                      vscroll(DSTX)   */
-						/*0x70*/ volatile unsigned int bh;
-						/* Y (alias to RYI)     brline(DYI)     */
-	/*                      dot(DYI)        */
-	/*                      polygon(ETYI)   */
-	/* Height               fastfill(H)     */
-	/*                      bcopy(H)        */
-	/*                      vscroll(H)      */
-	/* Y count              fastfill(NY)    */
-						/*0x74*/ volatile unsigned int bw;
-						/* X                    dot(DXI)        */
-	/*                      brline(DXI)     */
-	/*                      polygon(ETXI)   */
-	/*                      fastfill(W)     */
-	/*                      bcopy(W)        */
-	/*                      vscroll(W)      */
-	/*                      fastfill(NX)    */
-					/*0x78*/ unsigned int pad6[2];
-					/* Reserved                             */
-					/*0x80*/ unsigned int pad7[32];
-					/* Reserved                             */
-
-	/* Setup Unit's vertex state register */
-/*100*/ volatile unsigned int suvtx;
-					/*104*/ unsigned int pad8[63];
-					/* Reserved                             */
-
-	/* Frame Buffer Control Registers */
-						/*200*/ volatile unsigned int ppc;
-						/* Pixel Processor Control              */
-						/*204*/ volatile unsigned int wid;
-						/* Current WID                          */
-						/*208*/ volatile unsigned int fg;
-						/* FG data                              */
-						/*20c*/ volatile unsigned int bg;
-						/* BG data                              */
-						/*210*/ volatile unsigned int consty;
-						/* Constant Y                           */
-						/*214*/ volatile unsigned int constz;
-						/* Constant Z                           */
-						/*218*/ volatile unsigned int xclip;
-						/* X Clip                               */
-						/*21c*/ volatile unsigned int dcss;
-						/* Depth Cue Scale Slope                */
-						/*220*/ volatile unsigned int vclipmin;
-						/* Viewclip XY Min Bounds               */
-						/*224*/ volatile unsigned int vclipmax;
-						/* Viewclip XY Max Bounds               */
-							/*228*/ volatile unsigned int vclipzmin;
-							/* Viewclip Z Min Bounds                */
-							/*22c*/ volatile unsigned int vclipzmax;
-							/* Viewclip Z Max Bounds                */
-						/*230*/ volatile unsigned int dcsf;
-						/* Depth Cue Scale Front Bound          */
-						/*234*/ volatile unsigned int dcsb;
-						/* Depth Cue Scale Back Bound           */
-						/*238*/ volatile unsigned int dczf;
-						/* Depth Cue Z Front                    */
-						/*23c*/ volatile unsigned int dczb;
-						/* Depth Cue Z Back                     */
-					/*240*/ unsigned int pad9;
-					/* Reserved                             */
-						/*244*/ volatile unsigned int blendc;
-						/* Alpha Blend Control                  */
-						/*248*/ volatile unsigned int blendc1;
-						/* Alpha Blend Color 1                  */
-						/*24c*/ volatile unsigned int blendc2;
-						/* Alpha Blend Color 2                  */
-						/*250*/ volatile unsigned int fbramitc;
-						/* FB RAM Interleave Test Control       */
-						/*254*/ volatile unsigned int fbc;
-						/* Frame Buffer Control                 */
-						/*258*/ volatile unsigned int rop;
-						/* Raster OPeration                     */
-						/*25c*/ volatile unsigned int cmp;
-						/* Frame Buffer Compare                 */
-						/*260*/ volatile unsigned int matchab;
-						/* Buffer AB Match Mask                 */
-						/*264*/ volatile unsigned int matchc;
-						/* Buffer C(YZ) Match Mask              */
-						/*268*/ volatile unsigned int magnab;
-						/* Buffer AB Magnitude Mask             */
-						/*26c*/ volatile unsigned int magnc;
-						/* Buffer C(YZ) Magnitude Mask          */
-						/*270*/ volatile unsigned int fbcfg0;
-						/* Frame Buffer Config 0                */
-						/*274*/ volatile unsigned int fbcfg1;
-						/* Frame Buffer Config 1                */
-						/*278*/ volatile unsigned int fbcfg2;
-						/* Frame Buffer Config 2                */
-						/*27c*/ volatile unsigned int fbcfg3;
-						/* Frame Buffer Config 3                */
-						/*280*/ volatile unsigned int ppcfg;
-						/* Pixel Processor Config               */
-						/*284*/ volatile unsigned int pick;
-						/* Picking Control                      */
-						/*288*/ volatile unsigned int fillmode;
-						/* FillMode                             */
-						/*28c*/ volatile unsigned int fbramwac;
-						/* FB RAM Write Address Control         */
-						/*290*/ volatile unsigned int pmask;
-						/* RGB PlaneMask                        */
-						/*294*/ volatile unsigned int xpmask;
-						/* X PlaneMask                          */
-						/*298*/ volatile unsigned int ypmask;
-						/* Y PlaneMask                          */
-						/*29c*/ volatile unsigned int zpmask;
-						/* Z PlaneMask                          */
-					/*2a0*/ ffb_auxclip auxclip[4];
-					/* Auxilliary Viewport Clip             */
-
-	/* New 3dRAM III support regs */
-/*2c0*/ volatile unsigned int rawblend2;
-/*2c4*/ volatile unsigned int rawpreblend;
-/*2c8*/ volatile unsigned int rawstencil;
-/*2cc*/ volatile unsigned int rawstencilctl;
-/*2d0*/ volatile unsigned int threedram1;
-/*2d4*/ volatile unsigned int threedram2;
-/*2d8*/ volatile unsigned int passin;
-/*2dc*/ volatile unsigned int rawclrdepth;
-/*2e0*/ volatile unsigned int rawpmask;
-/*2e4*/ volatile unsigned int rawcsrc;
-/*2e8*/ volatile unsigned int rawmatch;
-/*2ec*/ volatile unsigned int rawmagn;
-/*2f0*/ volatile unsigned int rawropblend;
-/*2f4*/ volatile unsigned int rawcmp;
-/*2f8*/ volatile unsigned int rawwac;
-/*2fc*/ volatile unsigned int fbramid;
-
-						/*300*/ volatile unsigned int drawop;
-						/* Draw OPeration                       */
-					/*304*/ unsigned int pad10[2];
-					/* Reserved                             */
-						/*30c*/ volatile unsigned int lpat;
-						/* Line Pattern control                 */
-					/*310*/ unsigned int pad11;
-					/* Reserved                             */
-						/*314*/ volatile unsigned int fontxy;
-						/* XY Font coordinate                   */
-						/*318*/ volatile unsigned int fontw;
-						/* Font Width                           */
-						/*31c*/ volatile unsigned int fontinc;
-						/* Font Increment                       */
-						/*320*/ volatile unsigned int font;
-						/* Font bits                            */
-					/*324*/ unsigned int pad12[3];
-					/* Reserved                             */
-/*330*/ volatile unsigned int blend2;
-/*334*/ volatile unsigned int preblend;
-/*338*/ volatile unsigned int stencil;
-/*33c*/ volatile unsigned int stencilctl;
-
-					/*340*/ unsigned int pad13[4];
-					/* Reserved                             */
-						/*350*/ volatile unsigned int dcss1;
-						/* Depth Cue Scale Slope 1              */
-						/*354*/ volatile unsigned int dcss2;
-						/* Depth Cue Scale Slope 2              */
-						/*358*/ volatile unsigned int dcss3;
-						/* Depth Cue Scale Slope 3              */
-/*35c*/ volatile unsigned int widpmask;
-/*360*/ volatile unsigned int dcs2;
-/*364*/ volatile unsigned int dcs3;
-/*368*/ volatile unsigned int dcs4;
-					/*36c*/ unsigned int pad14;
-					/* Reserved                             */
-/*370*/ volatile unsigned int dcd2;
-/*374*/ volatile unsigned int dcd3;
-/*378*/ volatile unsigned int dcd4;
-					/*37c*/ unsigned int pad15;
-					/* Reserved                             */
-							/*380*/ volatile unsigned int pattern[32];
-							/* area Pattern                         */
-					/*400*/ unsigned int pad16[8];
-					/* Reserved                             */
-						/*420*/ volatile unsigned int reset;
-						/* chip RESET                           */
-						/*424*/ unsigned int pad17[247];
-						/* Reserved                             */
-						/*800*/ volatile unsigned int devid;
-						/* Device ID                            */
-					/*804*/ unsigned int pad18[63];
-					/* Reserved                             */
-						/*900*/ volatile unsigned int ucsr;
-						/* User Control & Status Register       */
-					/*904*/ unsigned int pad19[31];
-					/* Reserved                             */
-						/*980*/ volatile unsigned int mer;
-						/* Mode Enable Register                 */
-						/*984*/ unsigned int pad20[1439];
-						/* Reserved                             */
-} ffb_fbc, *ffb_fbcPtr;
-
-struct ffb_hw_context {
-	int is_2d_only;
-
-	unsigned int ppc;
-	unsigned int wid;
-	unsigned int fg;
-	unsigned int bg;
-	unsigned int consty;
-	unsigned int constz;
-	unsigned int xclip;
-	unsigned int dcss;
-	unsigned int vclipmin;
-	unsigned int vclipmax;
-	unsigned int vclipzmin;
-	unsigned int vclipzmax;
-	unsigned int dcsf;
-	unsigned int dcsb;
-	unsigned int dczf;
-	unsigned int dczb;
-	unsigned int blendc;
-	unsigned int blendc1;
-	unsigned int blendc2;
-	unsigned int fbc;
-	unsigned int rop;
-	unsigned int cmp;
-	unsigned int matchab;
-	unsigned int matchc;
-	unsigned int magnab;
-	unsigned int magnc;
-	unsigned int pmask;
-	unsigned int xpmask;
-	unsigned int ypmask;
-	unsigned int zpmask;
-	unsigned int auxclip0min;
-	unsigned int auxclip0max;
-	unsigned int auxclip1min;
-	unsigned int auxclip1max;
-	unsigned int auxclip2min;
-	unsigned int auxclip2max;
-	unsigned int auxclip3min;
-	unsigned int auxclip3max;
-	unsigned int drawop;
-	unsigned int lpat;
-	unsigned int fontxy;
-	unsigned int fontw;
-	unsigned int fontinc;
-	unsigned int area_pattern[32];
-	unsigned int ucsr;
-	unsigned int stencil;
-	unsigned int stencilctl;
-	unsigned int dcss1;
-	unsigned int dcss2;
-	unsigned int dcss3;
-	unsigned int dcs2;
-	unsigned int dcs3;
-	unsigned int dcs4;
-	unsigned int dcd2;
-	unsigned int dcd3;
-	unsigned int dcd4;
-	unsigned int mer;
-};
-
-#define FFB_MAX_CTXS	32
-
-enum ffb_chip_type {
-	ffb1_prototype = 0,	/* Early pre-FCS FFB */
-	ffb1_standard,		/* First FCS FFB, 100Mhz UPA, 66MHz gclk */
-	ffb1_speedsort,		/* Second FCS FFB, 100Mhz UPA, 75MHz gclk */
-	ffb2_prototype,		/* Early pre-FCS vertical FFB2 */
-	ffb2_vertical,		/* First FCS FFB2/vertical, 100Mhz UPA, 100MHZ gclk,
-				   75(SingleBuffer)/83(DoubleBuffer) MHz fclk */
-	ffb2_vertical_plus,	/* Second FCS FFB2/vertical, same timings */
-	ffb2_horizontal,	/* First FCS FFB2/horizontal, same timings as FFB2/vert */
-	ffb2_horizontal_plus,	/* Second FCS FFB2/horizontal, same timings */
-	afb_m3,			/* FCS Elite3D, 3 float chips */
-	afb_m6			/* FCS Elite3D, 6 float chips */
-};
-
-typedef struct ffb_dev_priv {
-	/* Misc software state. */
-	int prom_node;
-	enum ffb_chip_type ffb_type;
-	u64 card_phys_base;
-	struct miscdevice miscdev;
-
-	/* Controller registers. */
-	ffb_fbcPtr regs;
-
-	/* Context table. */
-	struct ffb_hw_context *hw_state[FFB_MAX_CTXS];
-} ffb_dev_priv_t;
-
-extern unsigned long ffb_get_unmapped_area(struct file *filp,
-					   unsigned long hint,
-					   unsigned long len,
-					   unsigned long pgoff,
-					   unsigned long flags);
-extern void ffb_set_context_ioctls(void);
-extern drm_ioctl_desc_t DRM(ioctls)[];
-
-extern int ffb_driver_context_switch(drm_device_t * dev, int old, int new);
diff --git a/drivers/char/ds1286.c b/drivers/char/ds1286.c
index 6d58b03..59146e3 100644
--- a/drivers/char/ds1286.c
+++ b/drivers/char/ds1286.c
@@ -197,6 +197,7 @@
 
 		hrs = alm_tm.tm_hour;
 		min = alm_tm.tm_min;
+		sec = alm_tm.tm_sec;
 
 		if (hrs >= 24)
 			hrs = 0xff;
@@ -204,9 +205,11 @@
 		if (min >= 60)
 			min = 0xff;
 
-		BIN_TO_BCD(sec);
-		BIN_TO_BCD(min);
-		BIN_TO_BCD(hrs);
+		if (sec != 0)
+			return -EINVAL;
+
+		min = BIN2BCD(min);
+		min = BIN2BCD(hrs);
 
 		spin_lock(&ds1286_lock);
 		rtc_write(hrs, RTC_HOURS_ALARM);
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index 337bbcd..8ea0275 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -710,12 +710,6 @@
 }
 
 
-static unsigned int     gs_baudrates[] = {
-  0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
-  9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
-};
-
-
 void gs_set_termios (struct tty_struct * tty, 
                      struct ktermios * old_termios)
 {
@@ -771,7 +765,6 @@
 
 	baudrate = tty_get_baud_rate(tty);
 
-	baudrate = gs_baudrates[baudrate];
 	if ((tiosp->c_cflag & CBAUD) == B38400) {
 		if (     (port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
 			baudrate = 57600;
diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c
index 5f4fdcf..1f09626 100644
--- a/drivers/char/lcd.c
+++ b/drivers/char/lcd.c
@@ -11,9 +11,6 @@
  *       March 2001: Ported from 2.0.34  by Liam Davies
  *
  */
-
-#define RTC_IO_EXTENT	0x10	/*Only really two ports, but... */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/miscdevice.h>
@@ -32,8 +29,6 @@
 
 #include "lcd.h"
 
-static DEFINE_SPINLOCK(lcd_lock);
-
 static int lcd_ioctl(struct inode *inode, struct file *file,
 		     unsigned int cmd, unsigned long arg);
 
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index e453268..7a32df5 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1376,6 +1376,8 @@
 	read_unlock(&tasklist_lock);
 
 	tty->flags = 0;
+	put_pid(tty->session);
+	put_pid(tty->pgrp);
 	tty->session = NULL;
 	tty->pgrp = NULL;
 	tty->ctrl_status = 0;
@@ -3841,6 +3843,9 @@
 {
 	struct pid *old_pgrp;
 	if (tty) {
+		/* We should not have a session or pgrp to here but.... */
+		put_pid(tty->session);
+		put_pid(tty->pgrp);
 		tty->session = get_pid(task_session(tsk));
 		tty->pgrp = get_pid(task_pgrp(tsk));
 	}
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index c3f8e38..1bbb45b 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -724,6 +724,7 @@
 		return -ENOMEM;
 	    memset(vc, 0, sizeof(*vc));
 	    vc_cons[currcons].d = vc;
+	    INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
 	    visual_init(vc, currcons, 1);
 	    if (!*vc->vc_uni_pagedir_loc)
 		con_set_default_unimap(vc);
@@ -2185,10 +2186,28 @@
 	release_console_sem();
 }
 
-void set_console(int nr)
+int set_console(int nr)
 {
+	struct vc_data *vc = vc_cons[fg_console].d;
+
+	if (!vc_cons_allocated(nr) || vt_dont_switch ||
+		(vc->vt_mode.mode == VT_AUTO && vc->vc_mode == KD_GRAPHICS)) {
+
+		/*
+		 * Console switch will fail in console_callback() or
+		 * change_console() so there is no point scheduling
+		 * the callback
+		 *
+		 * Existing set_console() users don't check the return
+		 * value so this shouldn't break anything
+		 */
+		return -EINVAL;
+	}
+
 	want_console = nr;
 	schedule_console_callback();
+
+	return 0;
 }
 
 struct tty_driver *console_driver;
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 3a5d301..c9f2dd6 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -34,7 +34,7 @@
 #include <linux/kbd_diacr.h>
 #include <linux/selection.h>
 
-static char vt_dont_switch;
+char vt_dont_switch;
 extern struct tty_driver *console_driver;
 
 #define VT_IS_IN_USE(i)	(console_driver->ttys[i] && console_driver->ttys[i]->count)
@@ -1039,10 +1039,22 @@
 
 	add_wait_queue(&vt_activate_queue, &wait);
 	for (;;) {
-		set_current_state(TASK_INTERRUPTIBLE);
 		retval = 0;
-		if (vt == fg_console)
+
+		/*
+		 * Synchronize with redraw_screen(). By acquiring the console
+		 * semaphore we make sure that the console switch is completed
+		 * before we return. If we didn't wait for the semaphore, we
+		 * could return at a point where fg_console has already been
+		 * updated, but the console switch hasn't been completed.
+		 */
+		acquire_console_sem();
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (vt == fg_console) {
+			release_console_sem();
 			break;
+		}
+		release_console_sem();
 		retval = -EINTR;
 		if (signal_pending(current))
 			break;
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
index ea09d0c..e812aa1 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -301,6 +301,7 @@
 config I8XX_TCO
 	tristate "Intel i8xx TCO Timer/Watchdog"
 	depends on WATCHDOG && (X86 || IA64) && PCI
+	default n
 	---help---
 	  Hardware driver for the TCO timer built into the Intel 82801
 	  I/O Controller Hub family.  The TCO (Total Cost of Ownership)
diff --git a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c
index 4a328ba..76c7fa3 100644
--- a/drivers/char/watchdog/machzwd.c
+++ b/drivers/char/watchdog/machzwd.c
@@ -314,21 +314,21 @@
 {
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
-	switch(cmd){
-		case WDIOC_GETSUPPORT:
-			if (copy_to_user(argp, &zf_info, sizeof(zf_info)))
-				return -EFAULT;
-			break;
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		if (copy_to_user(argp, &zf_info, sizeof(zf_info)))
+			return -EFAULT;
+		break;
 
-		case WDIOC_GETSTATUS:
-			return put_user(0, p);
+	case WDIOC_GETSTATUS:
+		return put_user(0, p);
 
-		case WDIOC_KEEPALIVE:
-			zf_ping(0);
-			break;
+	case WDIOC_KEEPALIVE:
+		zf_ping(0);
+		break;
 
-		default:
-			return -ENOTTY;
+	default:
+		return -ENOTTY;
 	}
 
 	return 0;
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c
index d42060e..5ac309e 100644
--- a/drivers/clocksource/acpi_pm.c
+++ b/drivers/clocksource/acpi_pm.c
@@ -90,7 +90,7 @@
 static inline void acpi_pm_need_workaround(void)
 {
 	clocksource_acpi_pm.read = acpi_pm_read_slow;
-	clocksource_acpi_pm.rating = 110;
+	clocksource_acpi_pm.rating = 120;
 }
 
 /*
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index a44db75..a905f78 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -128,7 +128,7 @@
  */
 static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), void *data)
 {
-	struct cn_callback_entry *__cbq;
+	struct cn_callback_entry *__cbq, *__new_cbq;
 	struct cn_dev *dev = &cdev;
 	int err = -ENODEV;
 
@@ -148,27 +148,27 @@
 			} else {
 				struct cn_callback_data *d;
 				
-				__cbq = kzalloc(sizeof(*__cbq), GFP_ATOMIC);
-				if (__cbq) {
-					d = &__cbq->data;
+				err = -ENOMEM;
+				__new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC);
+				if (__new_cbq) {
+					d = &__new_cbq->data;
 					d->callback_priv = msg;
 					d->callback = __cbq->data.callback;
 					d->ddata = data;
 					d->destruct_data = destruct_data;
-					d->free = __cbq;
+					d->free = __new_cbq;
 
-					INIT_WORK(&__cbq->work,
+					INIT_WORK(&__new_cbq->work,
 							&cn_queue_wrapper);
-					
+
 					if (queue_work(dev->cbdev->cn_queue,
-						    &__cbq->work))
+						    &__new_cbq->work))
 						err = 0;
 					else {
-						kfree(__cbq);
+						kfree(__new_cbq);
 						err = -EINVAL;
 					}
-				} else
-					err = -ENOMEM;
+				}
 			}
 			break;
 		}
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index f52facc..3162010 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1015,6 +1015,10 @@
 {
 	unsigned int cpu = sys_dev->id;
 	int retval;
+
+	if (cpu_is_offline(cpu))
+		return 0;
+
 	if (unlikely(lock_policy_rwsem_write(cpu)))
 		BUG();
 
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 1527804..322ee29 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -176,6 +176,7 @@
 	chan->client = NULL;
 	kref_put(&chan->device->refcount, dma_async_device_cleanup);
 }
+EXPORT_SYMBOL(dma_chan_cleanup);
 
 static void dma_chan_free_rcu(struct rcu_head *rcu)
 {
@@ -261,6 +262,7 @@
 
 	return client;
 }
+EXPORT_SYMBOL(dma_async_client_register);
 
 /**
  * dma_async_client_unregister - unregister a client and free the &dma_client
@@ -287,6 +289,7 @@
 	kfree(client);
 	dma_chans_rebalance();
 }
+EXPORT_SYMBOL(dma_async_client_unregister);
 
 /**
  * dma_async_client_chan_request - request DMA channels
@@ -304,6 +307,7 @@
 	client->chans_desired = number;
 	dma_chans_rebalance();
 }
+EXPORT_SYMBOL(dma_async_client_chan_request);
 
 /**
  * dma_async_device_register - registers DMA devices found
@@ -346,6 +350,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(dma_async_device_register);
 
 /**
  * dma_async_device_cleanup - function called when all references are released
@@ -390,23 +395,12 @@
 	kref_put(&device->refcount, dma_async_device_cleanup);
 	wait_for_completion(&device->done);
 }
+EXPORT_SYMBOL(dma_async_device_unregister);
 
 static int __init dma_bus_init(void)
 {
 	mutex_init(&dma_list_mutex);
 	return class_register(&dma_devclass);
 }
-
 subsys_initcall(dma_bus_init);
 
-EXPORT_SYMBOL(dma_async_client_register);
-EXPORT_SYMBOL(dma_async_client_unregister);
-EXPORT_SYMBOL(dma_async_client_chan_request);
-EXPORT_SYMBOL(dma_async_memcpy_buf_to_buf);
-EXPORT_SYMBOL(dma_async_memcpy_buf_to_pg);
-EXPORT_SYMBOL(dma_async_memcpy_pg_to_pg);
-EXPORT_SYMBOL(dma_async_memcpy_complete);
-EXPORT_SYMBOL(dma_async_memcpy_issue_pending);
-EXPORT_SYMBOL(dma_async_device_register);
-EXPORT_SYMBOL(dma_async_device_unregister);
-EXPORT_SYMBOL(dma_chan_cleanup);
diff --git a/drivers/eisa/pci_eisa.c b/drivers/eisa/pci_eisa.c
index 9e91362..74edb1d 100644
--- a/drivers/eisa/pci_eisa.c
+++ b/drivers/eisa/pci_eisa.c
@@ -19,8 +19,8 @@
 /* There is only *one* pci_eisa device per machine, right ? */
 static struct eisa_root_device pci_eisa_root;
 
-static int __devinit pci_eisa_init (struct pci_dev *pdev,
-				    const struct pci_device_id *ent)
+static int __init pci_eisa_init(struct pci_dev *pdev,
+				const struct pci_device_id *ent)
 {
 	int rc;
 
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index f4ee1af..1cca32f 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -26,6 +26,7 @@
 #include <asm/byteorder.h>
 #include <linux/input.h>
 #include <linux/wait.h>
+#include <linux/vmalloc.h>
 
 #include <linux/hid.h>
 #include <linux/hiddev.h>
@@ -654,12 +655,13 @@
 	memcpy(device->rdesc, start, size);
 	device->rsize = size;
 
-	if (!(parser = kzalloc(sizeof(struct hid_parser), GFP_KERNEL))) {
+	if (!(parser = vmalloc(sizeof(struct hid_parser)))) {
 		kfree(device->rdesc);
 		kfree(device->collection);
 		kfree(device);
 		return NULL;
 	}
+	memset(parser, 0, sizeof(struct hid_parser));
 	parser->device = device;
 
 	end = start + size;
@@ -668,7 +670,7 @@
 		if (item.format != HID_ITEM_FORMAT_SHORT) {
 			dbg("unexpected long global item");
 			hid_free_device(device);
-			kfree(parser);
+			vfree(parser);
 			return NULL;
 		}
 
@@ -676,7 +678,7 @@
 			dbg("item %u %u %u %u parsing failed\n",
 				item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag);
 			hid_free_device(device);
-			kfree(parser);
+			vfree(parser);
 			return NULL;
 		}
 
@@ -684,23 +686,23 @@
 			if (parser->collection_stack_ptr) {
 				dbg("unbalanced collection at end of report description");
 				hid_free_device(device);
-				kfree(parser);
+				vfree(parser);
 				return NULL;
 			}
 			if (parser->local.delimiter_depth) {
 				dbg("unbalanced delimiter at end of report description");
 				hid_free_device(device);
-				kfree(parser);
+				vfree(parser);
 				return NULL;
 			}
-			kfree(parser);
+			vfree(parser);
 			return device;
 		}
 	}
 
 	dbg("item fetching failed at offset %d\n", (int)(end - start));
 	hid_free_device(device);
-	kfree(parser);
+	vfree(parser);
 	return NULL;
 }
 EXPORT_SYMBOL_GPL(hid_parse_report);
@@ -753,8 +755,7 @@
 
 	report += offset >> 3;  /* adjust byte index */
 	offset &= 7;            /* now only need bit offset into one byte */
-	x = get_unaligned((u64 *) report);
-	x = le64_to_cpu(x);
+	x = le64_to_cpu(get_unaligned((__le64 *) report));
 	x = (x >> offset) & ((1ULL << n) - 1);  /* extract bit field */
 	return (u32) x;
 }
@@ -769,7 +770,7 @@
  */
 static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value)
 {
-	u64 x;
+	__le64 x;
 	u64 m = (1ULL << n) - 1;
 
 	WARN_ON(n > 32);
@@ -780,10 +781,10 @@
 	report += offset >> 3;
 	offset &= 7;
 
-	x = get_unaligned((u64 *)report);
+	x = get_unaligned((__le64 *)report);
 	x &= cpu_to_le64(~(m << offset));
 	x |= cpu_to_le64(((u64) value) << offset);
-	put_unaligned(x, (u64 *) report);
+	put_unaligned(x, (__le64 *) report);
 }
 
 /*
@@ -873,10 +874,6 @@
 	unsigned size = field->report_size;
 	unsigned n;
 
-	/* make sure the unused bits in the last byte are zeros */
-	if (count > 0 && size > 0)
-		data[(offset+count*size-1)/8] = 0;
-
 	for (n = 0; n < count; n++) {
 		if (field->logical_minimum < 0)	/* signed values */
 			implement(data, offset + n * size, size, s32ton(field->value[n], size));
@@ -972,7 +969,7 @@
 
 	if (size < rsize) {
 		dbg("report %d is too short, (%d < %d)", report->id, size, rsize);
-		return -1;
+		memset(data + size, 0, rsize - size);
 	}
 
 	if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index c3d4856..6d105a1 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -527,6 +527,7 @@
 config SENSORS_W83793
 	tristate "Winbond W83793"
 	depends on HWMON && I2C && EXPERIMENTAL
+	select HWMON_VID
 	help
 	  If you say yes here you get support for the Winbond W83793
 	  hardware monitoring chip.
diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
index e15f9e3..0c70f82 100644
--- a/drivers/i2c/busses/i2c-amd8111.c
+++ b/drivers/i2c/busses/i2c-amd8111.c
@@ -254,7 +254,8 @@
 			break;
 
 		case I2C_SMBUS_BLOCK_PROC_CALL:
-			len = min_t(u8, data->block[0], 31);
+			len = min_t(u8, data->block[0],
+				    I2C_SMBUS_BLOCK_MAX - 1);
 			amd_ec_write(smbus, AMD_SMB_CMD, command);
 			amd_ec_write(smbus, AMD_SMB_BCNT, len);
 			for (i = 0; i < len; i++)
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 6569a36..a320e7d 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -97,6 +97,7 @@
 				  int command, int hwpec);
 
 static unsigned long i801_smba;
+static unsigned char i801_original_hstcfg;
 static struct pci_driver i801_driver;
 static struct pci_dev *I801_dev;
 static int isich4;
@@ -510,6 +511,7 @@
 	}
 
 	pci_read_config_byte(I801_dev, SMBHSTCFG, &temp);
+	i801_original_hstcfg = temp;
 	temp &= ~SMBHSTCFG_I2C_EN;	/* SMBus timing */
 	if (!(temp & SMBHSTCFG_HST_EN)) {
 		dev_info(&dev->dev, "Enabling SMBus device\n");
@@ -543,6 +545,7 @@
 static void __devexit i801_remove(struct pci_dev *dev)
 {
 	i2c_del_adapter(&i801_adapter);
+	pci_write_config_byte(I801_dev, SMBHSTCFG, i801_original_hstcfg);
 	pci_release_region(dev, SMBBAR);
 	/*
 	 * do not call pci_disable_device(dev) since it can cause hard hangs on
@@ -550,11 +553,33 @@
 	 */
 }
 
+#ifdef CONFIG_PM
+static int i801_suspend(struct pci_dev *dev, pm_message_t mesg)
+{
+	pci_save_state(dev);
+	pci_write_config_byte(dev, SMBHSTCFG, i801_original_hstcfg);
+	pci_set_power_state(dev, pci_choose_state(dev, mesg));
+	return 0;
+}
+
+static int i801_resume(struct pci_dev *dev)
+{
+	pci_set_power_state(dev, PCI_D0);
+	pci_restore_state(dev);
+	return pci_enable_device(dev);
+}
+#else
+#define i801_suspend NULL
+#define i801_resume NULL
+#endif
+
 static struct pci_driver i801_driver = {
 	.name		= "i801_smbus",
 	.id_table	= i801_ids,
 	.probe		= i801_probe,
 	.remove		= __devexit_p(i801_remove),
+	.suspend	= i801_suspend,
+	.resume		= i801_resume,
 };
 
 static int __init i2c_i801_init(void)
diff --git a/drivers/i2c/chips/ds1374.c b/drivers/i2c/chips/ds1374.c
index 15edf40..8a2ff0c 100644
--- a/drivers/i2c/chips/ds1374.c
+++ b/drivers/i2c/chips/ds1374.c
@@ -207,6 +207,10 @@
 	client->driver = &ds1374_driver;
 
 	ds1374_workqueue = create_singlethread_workqueue("ds1374");
+	if (!ds1374_workqueue) {
+		kfree(client);
+		return -ENOMEM;	/* most expected reason */
+	}
 
 	if ((rc = i2c_attach_client(client)) != 0) {
 		kfree(client);
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 5d134bb..ca2e4f8 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -103,8 +103,10 @@
 	---help---
 	  There are two drivers for Serial ATA controllers.
 
-	  The main driver, "libata", exists inside the SCSI subsystem
-	  and supports most modern SATA controllers.
+	  The main driver, "libata", uses the SCSI subsystem
+	  and supports most modern SATA controllers. In order to use it
+	  you may take a look at "Serial ATA (prod) and Parallel ATA
+	  (experimental) drivers".
 
 	  The IDE driver (which you are currently configuring) supports
 	  a few first-generation SATA controllers.
@@ -434,24 +436,8 @@
 
 	  Generally say N here.
 
-config IDEDMA_PCI_AUTO
-	bool "Use PCI DMA by default when available"
-	---help---
-	  Prior to kernel version 2.1.112, Linux used to automatically use
-	  DMA for IDE drives and chipsets which support it. Due to concerns
-	  about a couple of cases where buggy hardware may have caused damage,
-	  the default is now to NOT use DMA automatically. To revert to the
-	  previous behaviour, say Y to this question.
-
-	  If you suspect your hardware is at all flakey, say N here.
-	  Do NOT email the IDE kernel people regarding this issue!
-
-	  It is normally safe to answer Y to this question unless your
-	  motherboard uses a VIA VP2 chipset, in which case you should say N.
-
 config IDEDMA_ONLYDISK
 	bool "Enable DMA only for disks "
-	depends on IDEDMA_PCI_AUTO
 	help
 	  This is used if you know your ATAPI Devices are going to fail DMA
 	  Transfers.
@@ -769,6 +755,14 @@
 	help
 	This driver adds support for Toshiba TC86C001 GOKU-S chip.
 
+config BLK_DEV_CELLEB
+	tristate "Toshiba's Cell Reference Set IDE support"
+	depends on PPC_CELLEB
+	help
+	  This driver provides support for the built-in IDE controller on
+	  Toshiba Cell Reference Board.
+	  If unsure, say Y.
+
 endif
 
 config BLK_DEV_IDE_PMAC
@@ -800,14 +794,6 @@
 	  to transfer data to and from memory.  Saying Y is safe and improves
 	  performance.
 
-config BLK_DEV_IDE_CELLEB
-	bool "Toshiba's Cell Reference Set IDE support"
-	depends on PPC_CELLEB
-	help
-	  This driver provides support for the built-in IDE controller on
-	  Toshiba Cell Reference Board.
-	  If unsure, say Y.
-
 config BLK_DEV_IDE_SWARM
 	tristate "IDE for Sibyte evaluation boards"
 	depends on SIBYTE_SB1xxx_SOC
@@ -851,19 +837,6 @@
 	  Say Y here if you want to add DMA (Direct Memory Access) support to
 	  the ICS IDE driver.
 
-config IDEDMA_ICS_AUTO
-	bool "Use ICS DMA by default"
-	depends on BLK_DEV_IDEDMA_ICS
-	help
-	  Prior to kernel version 2.1.112, Linux used to automatically use
-	  DMA for IDE drives and chipsets which support it. Due to concerns
-	  about a couple of cases where buggy hardware may have caused damage,
-	  the default is now to NOT use DMA automatically. To revert to the
-	  previous behaviour, say Y to this question.
-
-	  If you suspect your hardware is at all flakey, say N here.
-	  Do NOT email the IDE kernel people regarding this issue!
-
 config BLK_DEV_IDE_RAPIDE
 	tristate "RapIDE interface support"
 	depends on ARM && ARCH_ACORN
@@ -1086,9 +1059,6 @@
 
 	  It is normally safe to answer Y; however, the default is N.
 
-config IDEDMA_AUTO
-	def_bool IDEDMA_PCI_AUTO || IDEDMA_ICS_AUTO
-
 endif
 
 config BLK_DEV_HD_ONLY
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index 28feedf..d9f029e 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -37,7 +37,6 @@
 # built-in only drivers from ppc/
 ide-core-$(CONFIG_BLK_DEV_MPC8xx_IDE)	+= ppc/mpc8xx.o
 ide-core-$(CONFIG_BLK_DEV_IDE_PMAC)	+= ppc/pmac.o
-ide-core-$(CONFIG_BLK_DEV_IDE_CELLEB)	+= ppc/scc_pata.o
 
 # built-in only drivers from h8300/
 ide-core-$(CONFIG_H8300)		+= h8300/ide-h8300.o
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
index 40e5c66..e2953fc 100644
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -196,11 +196,6 @@
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_ICS
-
-#ifndef CONFIG_IDEDMA_ICS_AUTO
-#warning CONFIG_IDEDMA_ICS_AUTO=n support is obsolete, and will be removed soon.
-#endif
-
 /*
  * SG-DMA support.
  *
@@ -474,12 +469,6 @@
 
 static void icside_dma_init(ide_hwif_t *hwif)
 {
-	int autodma = 0;
-
-#ifdef CONFIG_IDEDMA_ICS_AUTO
-	autodma = 1;
-#endif
-
 	printk("    %s: SG-DMA", hwif->name);
 
 	hwif->atapi_dma		= 1;
@@ -489,7 +478,7 @@
 	hwif->dmatable_cpu	= NULL;
 	hwif->dmatable_dma	= 0;
 	hwif->speedproc		= icside_set_speed;
-	hwif->autodma		= autodma;
+	hwif->autodma		= 1;
 
 	hwif->ide_dma_check	= icside_dma_check;
 	hwif->dma_host_off	= icside_dma_host_off;
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 45a928c..638becd 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -735,6 +735,15 @@
 			cdrom_saw_media_change (drive);
 			/*printk("%s: media changed\n",drive->name);*/
 			return 0;
+ 		} else if ((sense_key == ILLEGAL_REQUEST) &&
+ 			   (rq->cmd[0] == GPCMD_START_STOP_UNIT)) {
+ 			/*
+ 			 * Don't print error message for this condition--
+ 			 * SFF8090i indicates that 5/24/00 is the correct
+ 			 * response to a request to close the tray if the
+ 			 * drive doesn't have that capability.
+ 			 * cdrom_log_sense() knows this!
+ 			 */
 		} else if (!(rq->cmd_flags & REQ_QUIET)) {
 			/* Otherwise, print an error. */
 			ide_dump_status(drive, "packet command error", stat);
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 08e7cd0..fd21308 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -767,7 +767,7 @@
 	switch(rc) {
 	case -1: /* DMA needs to be disabled */
 		hwif->dma_off_quietly(drive);
-		return 0;
+		return -1;
 	case  0: /* DMA needs to be enabled */
 		return hwif->ide_dma_on(drive);
 	case  1: /* DMA setting cannot be changed */
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index c193553..8670112 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -519,21 +519,24 @@
 	if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ && hwif->err_stops_fifo == 0)
 		try_to_flush_leftover_data(drive);
 
-	if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
-		/* force an abort */
-		hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG);
-
-	if (rq->errors >= ERROR_MAX || blk_noretry_request(rq))
+	if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) {
 		ide_kill_rq(drive, rq);
-	else {
-		if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
-			++rq->errors;
-			return ide_do_reset(drive);
-		}
-		if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
-			drive->special.b.recalibrate = 1;
-		++rq->errors;
+		return ide_stopped;
 	}
+
+	if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT))
+		rq->errors |= ERROR_RESET;
+
+	if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
+		++rq->errors;
+		return ide_do_reset(drive);
+	}
+
+	if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
+		drive->special.b.recalibrate = 1;
+
+	++rq->errors;
+
 	return ide_stopped;
 }
 
@@ -1025,6 +1028,13 @@
 	if (!drive->special.all) {
 		ide_driver_t *drv;
 
+		/*
+		 * We reset the drive so we need to issue a SETFEATURES.
+		 * Do it _after_ do_special() restored device parameters.
+		 */
+		if (drive->current_speed == 0xff)
+			ide_config_drive_speed(drive, drive->desired_speed);
+
 		if (rq->cmd_type == REQ_TYPE_ATA_CMD ||
 		    rq->cmd_type == REQ_TYPE_ATA_TASK ||
 		    rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
@@ -1216,6 +1226,7 @@
 #endif
 				/* so that ide_timer_expiry knows what to do */
 				hwgroup->sleeping = 1;
+				hwgroup->req_gen_timer = hwgroup->req_gen;
 				mod_timer(&hwgroup->timer, sleep);
 				/* we purposely leave hwgroup->busy==1
 				 * while sleeping */
@@ -1401,7 +1412,8 @@
 
 	spin_lock_irqsave(&ide_lock, flags);
 
-	if ((handler = hwgroup->handler) == NULL) {
+	if (((handler = hwgroup->handler) == NULL) ||
+	    (hwgroup->req_gen != hwgroup->req_gen_timer)) {
 		/*
 		 * Either a marginal timeout occurred
 		 * (got the interrupt just as timer expired),
@@ -1429,6 +1441,7 @@
 				if ((wait = expiry(drive)) > 0) {
 					/* reset timer */
 					hwgroup->timer.expires  = jiffies + wait;
+					hwgroup->req_gen_timer = hwgroup->req_gen;
 					add_timer(&hwgroup->timer);
 					spin_unlock_irqrestore(&ide_lock, flags);
 					return;
@@ -1643,6 +1656,7 @@
 		printk(KERN_ERR "%s: ide_intr: hwgroup->busy was 0 ??\n", drive->name);
 	}
 	hwgroup->handler = NULL;
+	hwgroup->req_gen++;
 	del_timer(&hwgroup->timer);
 	spin_unlock(&ide_lock);
 
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index bd513f5..3caa176b 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -583,8 +583,12 @@
 	if(!(drive->id->hw_config & 0x4000))
 		return 0;
 #endif /* CONFIG_IDEDMA_IVB */
-	if (!(drive->id->hw_config & 0x2000))
-		return 0;
+	/*
+	 * FIXME:
+	 * - change master/slave IDENTIFY order
+	 * - force bit13 (80c cable present) check
+	 *   (unless the slave device is pre-ATA3)
+	 */
 	return 1;
 }
 
@@ -885,6 +889,7 @@
 	hwgroup->handler	= handler;
 	hwgroup->expiry		= expiry;
 	hwgroup->timer.expires	= jiffies + timeout;
+	hwgroup->req_gen_timer = hwgroup->req_gen;
 	add_timer(&hwgroup->timer);
 }
 
@@ -925,6 +930,7 @@
 	hwgroup->handler	= handler;
 	hwgroup->expiry		= expiry;
 	hwgroup->timer.expires	= jiffies + timeout;
+	hwgroup->req_gen_timer = hwgroup->req_gen;
 	add_timer(&hwgroup->timer);
 	hwif->OUTBSYNC(drive, cmd, IDE_COMMAND_REG);
 	/* Drive takes 400nS to respond, we must avoid the IRQ being
@@ -1090,6 +1096,9 @@
 	if (HWIF(drive)->pre_reset != NULL)
 		HWIF(drive)->pre_reset(drive);
 
+	if (drive->current_speed != 0xff)
+		drive->desired_speed = drive->current_speed;
+	drive->current_speed = 0xff;
 }
 
 /*
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index dfbd744..ae5bf2b 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -177,11 +177,7 @@
 static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */
 #endif
 
-#ifdef CONFIG_IDEDMA_AUTO
 int noautodma = 0;
-#else
-int noautodma = 1;
-#endif
 
 EXPORT_SYMBOL(noautodma);
 
@@ -1128,17 +1124,40 @@
 static int set_using_dma (ide_drive_t *drive, int arg)
 {
 #ifdef CONFIG_BLK_DEV_IDEDMA
+	ide_hwif_t *hwif = drive->hwif;
+	int err = -EPERM;
+
 	if (!drive->id || !(drive->id->capability & 1))
-		return -EPERM;
-	if (HWIF(drive)->ide_dma_check == NULL)
-		return -EPERM;
+		goto out;
+
+	if (hwif->ide_dma_check == NULL)
+		goto out;
+
+	err = -EBUSY;
+	if (ide_spin_wait_hwgroup(drive))
+		goto out;
+	/*
+	 * set ->busy flag, unlock and let it ride
+	 */
+	hwif->hwgroup->busy = 1;
+	spin_unlock_irq(&ide_lock);
+
+	err = 0;
+
 	if (arg) {
-		if (ide_set_dma(drive))
-			return -EIO;
-		if (HWIF(drive)->ide_dma_on(drive)) return -EIO;
+		if (ide_set_dma(drive) || hwif->ide_dma_on(drive))
+			err = -EIO;
 	} else
 		ide_dma_off(drive);
-	return 0;
+
+	/*
+	 * lock, clear ->busy flag and unlock before leaving
+	 */
+	spin_lock_irq(&ide_lock);
+	hwif->hwgroup->busy = 0;
+	spin_unlock_irq(&ide_lock);
+out:
+	return err;
 #else
 	return -EPERM;
 #endif
@@ -1943,6 +1962,8 @@
 		return "tape";
 	case ide_floppy:
 		return "floppy";
+	case ide_optical:
+		return "optical";
 	default:
 		return "UNKNOWN";
 	}
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index b2dc028..d54d9fe 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -639,6 +639,7 @@
 	_auide_hwif *ahwif = &auide_hwif;
 	ide_hwif_t *hwif;
 	struct resource *res;
+	hw_regs_t *hw;
 	int ret = 0;
 
 #if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
@@ -681,7 +682,7 @@
 	/* FIXME:  This might possibly break PCMCIA IDE devices */
 
 	hwif                            = &ide_hwifs[pdev->id];
-	hw_regs_t *hw 			= &hwif->hw;
+	hw 				= &hwif->hw;
 	hwif->irq = hw->irq             = ahwif->irq;
 	hwif->chipset                   = ide_au1xxx;
 
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile
index 6591ff4..95d1ea8 100644
--- a/drivers/ide/pci/Makefile
+++ b/drivers/ide/pci/Makefile
@@ -3,6 +3,7 @@
 obj-$(CONFIG_BLK_DEV_ALI15X3)		+= alim15x3.o
 obj-$(CONFIG_BLK_DEV_AMD74XX)		+= amd74xx.o
 obj-$(CONFIG_BLK_DEV_ATIIXP)		+= atiixp.o
+obj-$(CONFIG_BLK_DEV_CELLEB)		+= scc_pata.o
 obj-$(CONFIG_BLK_DEV_CMD64X)		+= cmd64x.o
 obj-$(CONFIG_BLK_DEV_CS5520)		+= cs5520.o
 obj-$(CONFIG_BLK_DEV_CS5530)		+= cs5530.o
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
index b0d4825..561197f 100644
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -1,6 +1,6 @@
 /* $Id: cmd64x.c,v 1.21 2000/01/30 23:23:16
  *
- * linux/drivers/ide/pci/cmd64x.c		Version 1.41	Feb 3, 2007
+ * linux/drivers/ide/pci/cmd64x.c		Version 1.42	Feb 8, 2007
  *
  * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines.
  *           Note, this driver is not used at all on other systems because
@@ -189,6 +189,11 @@
 
 #endif	/* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */
 
+static u8 quantize_timing(int timing, int quant)
+{
+	return (timing + quant - 1) / quant;
+}
+
 /*
  * This routine writes the prepared setup/active/recovery counts
  * for a drive into the cmd646 chipset registers to active them.
@@ -268,47 +273,37 @@
  */
 static u8 cmd64x_tune_pio (ide_drive_t *drive, u8 mode_wanted)
 {
-	int setup_time, active_time, recovery_time;
-	int clock_time, pio_mode, cycle_time;
-	u8 recovery_count2, cycle_count;
-	int setup_count, active_count, recovery_count;
-	int bus_speed = system_bus_clock();
-	ide_pio_data_t  d;
+	int setup_time, active_time, cycle_time;
+	u8  cycle_count, setup_count, active_count, recovery_count;
+	u8  pio_mode;
+	int clock_time = 1000 / system_bus_clock();
+	ide_pio_data_t pio;
 
-	pio_mode = ide_get_best_pio_mode(drive, mode_wanted, 5, &d);
-	cycle_time = d.cycle_time;
+	pio_mode = ide_get_best_pio_mode(drive, mode_wanted, 5, &pio);
+	cycle_time = pio.cycle_time;
 
-	/*
-	 * I copied all this complicated stuff from cmd640.c and made a few
-	 * minor changes.  For now I am just going to pray that it is correct.
-	 */
 	setup_time  = ide_pio_timings[pio_mode].setup_time;
 	active_time = ide_pio_timings[pio_mode].active_time;
-	recovery_time = cycle_time - (setup_time + active_time);
-	clock_time = 1000 / bus_speed;
-	cycle_count = (cycle_time + clock_time - 1) / clock_time;
 
-	setup_count = (setup_time + clock_time - 1) / clock_time;
+	setup_count  = quantize_timing( setup_time, clock_time);
+	cycle_count  = quantize_timing( cycle_time, clock_time);
+	active_count = quantize_timing(active_time, clock_time);
 
-	active_count = (active_time + clock_time - 1) / clock_time;
-
-	recovery_count = (recovery_time + clock_time - 1) / clock_time;
-	recovery_count2 = cycle_count - (setup_count + active_count);
-	if (recovery_count2 > recovery_count)
-		recovery_count = recovery_count2;
+	recovery_count = cycle_count - active_count;
+	/* program_drive_counts() takes care of zero recovery cycles */
 	if (recovery_count > 16) {
 		active_count += recovery_count - 16;
 		recovery_count = 16;
 	}
 	if (active_count > 16)
-		active_count = 16; /* maximum allowed by cmd646 */
+		active_count = 16; /* maximum allowed by cmd64x */
 
 	program_drive_counts (drive, setup_count, active_count, recovery_count);
 
 	cmdprintk("%s: PIO mode wanted %d, selected %d (%dns)%s, "
 		"clocks=%d/%d/%d\n",
 		drive->name, mode_wanted, pio_mode, cycle_time,
-		d.overridden ? " (overriding vendor mode)" : "",
+		pio.overridden ? " (overriding vendor mode)" : "",
 		setup_count, active_count, recovery_count);
 
 	return pio_mode;
diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c
index 53f2550..be4fc96 100644
--- a/drivers/ide/pci/jmicron.c
+++ b/drivers/ide/pci/jmicron.c
@@ -240,12 +240,31 @@
 	return 0;
 }
 
+/* If libata is configured, jmicron PCI quirk will configure it such
+ * that the SATA ports are in AHCI function while the PATA ports are
+ * in a separate IDE function.  In such cases, match device class and
+ * attach only to IDE.  If libata isn't configured, keep the old
+ * behavior for backward compatibility.
+ */
+#if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE)
+#define JMB_CLASS	PCI_CLASS_STORAGE_IDE << 8
+#define JMB_CLASS_MASK	0xffff00
+#else
+#define JMB_CLASS	0
+#define JMB_CLASS_MASK	0
+#endif
+
 static struct pci_device_id jmicron_pci_tbl[] = {
-	{ PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{ PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
-	{ PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
-	{ PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
-	{ PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
+	{ PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361,
+	  PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 0},
+	{ PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363,
+	  PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 1},
+	{ PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365,
+	  PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 2},
+	{ PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366,
+	  PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 3},
+	{ PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368,
+	  PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 4},
 	{ 0, },
 };
 
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index 6ceb25b..ace9892 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -255,7 +255,7 @@
 		printk(KERN_WARNING "%s reduced to Ultra33 mode.\n", drive->name);
 	}
 
-	if (drive->media != ide_disk)
+	if (drive->media != ide_disk && drive->media != ide_cdrom)
 		return 0;
 
 	if (id->capability & 4) {
@@ -545,6 +545,7 @@
 
 	hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
 
+	hwif->atapi_dma  = 1;
 	hwif->ultra_mask = 0x7f;
 	hwif->mwdma_mask = 0x07;
 
diff --git a/drivers/ide/ppc/scc_pata.c b/drivers/ide/pci/scc_pata.c
similarity index 100%
rename from drivers/ide/ppc/scc_pata.c
rename to drivers/ide/pci/scc_pata.c
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index a52c80f..118fb32 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -505,11 +505,6 @@
 		}
 	}
 }
-
-#ifndef CONFIG_IDEDMA_PCI_AUTO
-#warning CONFIG_IDEDMA_PCI_AUTO=n support is obsolete, and will be removed soon.
-#endif
-
 #endif /* CONFIG_BLK_DEV_IDEDMA_PCI*/
 
 /**
diff --git a/drivers/ieee1394/Kconfig b/drivers/ieee1394/Kconfig
index b8a4734..cd84a55 100644
--- a/drivers/ieee1394/Kconfig
+++ b/drivers/ieee1394/Kconfig
@@ -138,9 +138,9 @@
 	tristate "OHCI-DV I/O support (deprecated)"
 	depends on IEEE1394 && IEEE1394_OHCI1394
 	help
-	  The dv1394 driver will be removed from Linux in a future release.
-	  Its functionality is now provided by raw1394 together with libraries
-	  such as libiec61883.
+	  The dv1394 driver is unsupported and may be removed from Linux in a
+	  future release.  Its functionality is now provided by raw1394 together
+	  with libraries such as libiec61883.
 
 config IEEE1394_RAWIO
 	tristate "Raw IEEE1394 I/O support"
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index dee9529..026e38f 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -2564,8 +2564,8 @@
 	int ret;
 
 	printk(KERN_WARNING
-	       "WARNING: The dv1394 driver is unsupported and will be removed "
-	       "from Linux soon. Use raw1394 instead.\n");
+	       "NOTE: The dv1394 driver is unsupported and may be removed in a "
+	       "future Linux release. Use raw1394 instead.\n");
 
 	cdev_init(&dv1394_cdev, &dv1394_fops);
 	dv1394_cdev.owner = THIS_MODULE;
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index a953135..03e44b3 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -584,7 +584,10 @@
         }
 
 	SET_MODULE_OWNER(dev);
+#if 0
+	/* FIXME - Is this the correct parent device anyway? */
 	SET_NETDEV_DEV(dev, &host->device);
+#endif
 
 	priv = netdev_priv(dev);
 
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index d441815..fde92ce 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -1821,7 +1821,7 @@
 	struct rdma_bind_list *bind_list;
 	int port, ret;
 
-	bind_list = kmalloc(sizeof *bind_list, GFP_KERNEL);
+	bind_list = kzalloc(sizeof *bind_list, GFP_KERNEL);
 	if (!bind_list)
 		return -ENOMEM;
 
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index b516b93..c859134 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -266,7 +266,7 @@
 	mutex_lock(&ctx->file->mut);
 	if (event->event == RDMA_CM_EVENT_CONNECT_REQUEST) {
 		if (!ctx->backlog) {
-			ret = -EDQUOT;
+			ret = -ENOMEM;
 			kfree(uevent);
 			goto out;
 		}
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c
index d737c73..f5e9aee 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c
@@ -36,6 +36,7 @@
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/pci.h>
+#include <linux/dma-mapping.h>
 
 #include "cxio_resource.h"
 #include "cxio_hal.h"
@@ -497,9 +498,9 @@
 	u64 sge_cmd, ctx0, ctx1;
 	u64 base_addr;
 	struct t3_modify_qp_wr *wqe;
-	struct sk_buff *skb = alloc_skb(sizeof(*wqe), GFP_KERNEL);
+	struct sk_buff *skb;
 
-
+	skb = alloc_skb(sizeof(*wqe), GFP_KERNEL);
 	if (!skb) {
 		PDBG("%s alloc_skb failed\n", __FUNCTION__);
 		return -ENOMEM;
@@ -507,7 +508,7 @@
 	err = cxio_hal_init_ctrl_cq(rdev_p);
 	if (err) {
 		PDBG("%s err %d initializing ctrl_cq\n", __FUNCTION__, err);
-		return err;
+		goto err;
 	}
 	rdev_p->ctrl_qp.workq = dma_alloc_coherent(
 					&(rdev_p->rnic_info.pdev->dev),
@@ -517,7 +518,8 @@
 					GFP_KERNEL);
 	if (!rdev_p->ctrl_qp.workq) {
 		PDBG("%s dma_alloc_coherent failed\n", __FUNCTION__);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto err;
 	}
 	pci_unmap_addr_set(&rdev_p->ctrl_qp, mapping,
 			   rdev_p->ctrl_qp.dma_addr);
@@ -555,6 +557,9 @@
 	     rdev_p->ctrl_qp.workq, 1 << T3_CTRL_QP_SIZE_LOG2);
 	skb->priority = CPL_PRIORITY_CONTROL;
 	return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb));
+err:
+	kfree_skb(skb);
+	return err;
 }
 
 static int cxio_hal_destroy_ctrl_qp(struct cxio_rdev *rdev_p)
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index b21fde8..d0ed1d3 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -305,8 +305,7 @@
  */
 static struct sk_buff *get_skb(struct sk_buff *skb, int len, gfp_t gfp)
 {
-	if (skb) {
-		BUG_ON(skb_cloned(skb));
+	if (skb && !skb_is_nonlinear(skb) && !skb_cloned(skb)) {
 		skb_trim(skb, 0);
 		skb_get(skb);
 	} else {
@@ -1415,6 +1414,7 @@
 		wake_up(&ep->com.waitq);
 		break;
 	case FPDU_MODE:
+		start_ep_timer(ep);
 		__state_set(&ep->com, CLOSING);
 		attrs.next_state = IWCH_QP_STATE_CLOSING;
 		iwch_modify_qp(ep->com.qp->rhp, ep->com.qp,
@@ -1425,7 +1425,6 @@
 		disconnect = 0;
 		break;
 	case CLOSING:
-		start_ep_timer(ep);
 		__state_set(&ep->com, MORIBUND);
 		disconnect = 0;
 		break;
@@ -1487,8 +1486,10 @@
 	case CONNECTING:
 		break;
 	case MPA_REQ_WAIT:
+		stop_ep_timer(ep);
 		break;
 	case MPA_REQ_SENT:
+		stop_ep_timer(ep);
 		connect_reply_upcall(ep, -ECONNRESET);
 		break;
 	case MPA_REP_SENT:
@@ -1507,9 +1508,10 @@
 		get_ep(&ep->com);
 		break;
 	case MORIBUND:
-		stop_ep_timer(ep);
-	case FPDU_MODE:
 	case CLOSING:
+		stop_ep_timer(ep);
+		/*FALLTHROUGH*/
+	case FPDU_MODE:
 		if (ep->com.cm_id && ep->com.qp) {
 			attrs.next_state = IWCH_QP_STATE_ERROR;
 			ret = iwch_modify_qp(ep->com.qp->rhp,
@@ -1570,7 +1572,6 @@
 	spin_lock_irqsave(&ep->com.lock, flags);
 	switch (ep->com.state) {
 	case CLOSING:
-		start_ep_timer(ep);
 		__state_set(&ep->com, MORIBUND);
 		break;
 	case MORIBUND:
@@ -1586,6 +1587,8 @@
 		__state_set(&ep->com, DEAD);
 		release = 1;
 		break;
+	case ABORTING:
+		break;
 	case DEAD:
 	default:
 		BUG_ON(1);
@@ -1659,6 +1662,7 @@
 		break;
 	case MPA_REQ_WAIT:
 		break;
+	case CLOSING:
 	case MORIBUND:
 		if (ep->com.cm_id && ep->com.qp) {
 			attrs.next_state = IWCH_QP_STATE_ERROR;
@@ -1687,12 +1691,11 @@
 		return -ECONNRESET;
 	}
 	BUG_ON(state_read(&ep->com) != MPA_REQ_RCVD);
-	state_set(&ep->com, CLOSING);
 	if (mpa_rev == 0)
 		abort_connection(ep, NULL, GFP_KERNEL);
 	else {
 		err = send_mpa_reject(ep, pdata, pdata_len);
-		err = send_halfclose(ep, GFP_KERNEL);
+		err = iwch_ep_disconnect(ep, 0, GFP_KERNEL);
 	}
 	return 0;
 }
@@ -1957,11 +1960,11 @@
 	case MPA_REQ_RCVD:
 	case MPA_REP_SENT:
 	case FPDU_MODE:
+		start_ep_timer(ep);
 		ep->com.state = CLOSING;
 		close = 1;
 		break;
 	case CLOSING:
-		start_ep_timer(ep);
 		ep->com.state = MORIBUND;
 		close = 1;
 		break;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_ev.c b/drivers/infiniband/hw/cxgb3/iwch_ev.c
index 54362af..b406766 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_ev.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_ev.c
@@ -47,12 +47,6 @@
 	struct iwch_qp_attributes attrs;
 	struct iwch_qp *qhp;
 
-	printk(KERN_ERR "%s - AE qpid 0x%x opcode %d status 0x%x "
-	       "type %d wrid.hi 0x%x wrid.lo 0x%x \n", __FUNCTION__,
-	       CQE_QPID(rsp_msg->cqe), CQE_OPCODE(rsp_msg->cqe),
-	       CQE_STATUS(rsp_msg->cqe), CQE_TYPE(rsp_msg->cqe),
-	       CQE_WRID_HI(rsp_msg->cqe), CQE_WRID_LOW(rsp_msg->cqe));
-
 	spin_lock(&rnicp->lock);
 	qhp = get_qhp(rnicp, CQE_QPID(rsp_msg->cqe));
 
@@ -73,6 +67,12 @@
 		return;
 	}
 
+	printk(KERN_ERR "%s - AE qpid 0x%x opcode %d status 0x%x "
+	       "type %d wrid.hi 0x%x wrid.lo 0x%x \n", __FUNCTION__,
+	       CQE_QPID(rsp_msg->cqe), CQE_OPCODE(rsp_msg->cqe),
+	       CQE_STATUS(rsp_msg->cqe), CQE_TYPE(rsp_msg->cqe),
+	       CQE_WRID_HI(rsp_msg->cqe), CQE_WRID_LOW(rsp_msg->cqe));
+
 	atomic_inc(&qhp->refcnt);
 	spin_unlock(&rnicp->lock);
 
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c
index 9947a14..24e0df0 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c
@@ -331,6 +331,7 @@
 	int ret = 0;
 	struct iwch_mm_entry *mm;
 	struct iwch_ucontext *ucontext;
+	u64 addr;
 
 	PDBG("%s pgoff 0x%lx key 0x%x len %d\n", __FUNCTION__, vma->vm_pgoff,
 	     key, len);
@@ -345,10 +346,11 @@
 	mm = remove_mmap(ucontext, key, len);
 	if (!mm)
 		return -EINVAL;
+	addr = mm->addr;
 	kfree(mm);
 
-	if ((mm->addr >= rdev_p->rnic_info.udbell_physbase) &&
-	    (mm->addr < (rdev_p->rnic_info.udbell_physbase +
+	if ((addr >= rdev_p->rnic_info.udbell_physbase) &&
+	    (addr < (rdev_p->rnic_info.udbell_physbase +
 		       rdev_p->rnic_info.udbell_len))) {
 
 		/*
@@ -362,7 +364,7 @@
 		vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND;
 		vma->vm_flags &= ~VM_MAYREAD;
 		ret = io_remap_pfn_range(vma, vma->vm_start,
-					 mm->addr >> PAGE_SHIFT,
+					 addr >> PAGE_SHIFT,
 				         len, vma->vm_page_prot);
 	} else {
 
@@ -370,7 +372,7 @@
 		 * Map WQ or CQ contig dma memory...
 		 */
 		ret = remap_pfn_range(vma, vma->vm_start,
-				      mm->addr >> PAGE_SHIFT,
+				      addr >> PAGE_SHIFT,
 				      len, vma->vm_page_prot);
 	}
 
@@ -463,9 +465,6 @@
 	php = to_iwch_pd(pd);
 	rhp = php->rhp;
 
-	acc = iwch_convert_access(acc);
-
-
 	mhp = kzalloc(sizeof(*mhp), GFP_KERNEL);
 	if (!mhp)
 		return ERR_PTR(-ENOMEM);
@@ -491,12 +490,7 @@
 	mhp->attr.pdid = php->pdid;
 	mhp->attr.zbva = 0;
 
-	/* NOTE: TPT perms are backwards from BIND WR perms! */
-	mhp->attr.perms = (acc & 0x1) << 3;
-	mhp->attr.perms |= (acc & 0x2) << 1;
-	mhp->attr.perms |= (acc & 0x4) >> 1;
-	mhp->attr.perms |= (acc & 0x8) >> 3;
-
+	mhp->attr.perms = iwch_ib_to_tpt_access(acc);
 	mhp->attr.va_fbo = *iova_start;
 	mhp->attr.page_size = shift - 12;
 
@@ -525,7 +519,6 @@
 	struct iwch_mr mh, *mhp;
 	struct iwch_pd *php;
 	struct iwch_dev *rhp;
-	int new_acc;
 	__be64 *page_list = NULL;
 	int shift = 0;
 	u64 total_size;
@@ -546,19 +539,20 @@
 	if (rhp != php->rhp)
 		return -EINVAL;
 
-	new_acc = mhp->attr.perms;
-
 	memcpy(&mh, mhp, sizeof *mhp);
 
 	if (mr_rereg_mask & IB_MR_REREG_PD)
 		php = to_iwch_pd(pd);
 	if (mr_rereg_mask & IB_MR_REREG_ACCESS)
-		mh.attr.perms = iwch_convert_access(acc);
-	if (mr_rereg_mask & IB_MR_REREG_TRANS)
+		mh.attr.perms = iwch_ib_to_tpt_access(acc);
+	if (mr_rereg_mask & IB_MR_REREG_TRANS) {
 		ret = build_phys_page_list(buffer_list, num_phys_buf,
 					   iova_start,
 					   &total_size, &npages,
 					   &shift, &page_list);
+		if (ret)
+			return ret;
+	}
 
 	ret = iwch_reregister_mem(rhp, php, &mh, shift, page_list, npages);
 	kfree(page_list);
@@ -568,7 +562,7 @@
 	if (mr_rereg_mask & IB_MR_REREG_PD)
 		mhp->attr.pdid = php->pdid;
 	if (mr_rereg_mask & IB_MR_REREG_ACCESS)
-		mhp->attr.perms = acc;
+		mhp->attr.perms = iwch_ib_to_tpt_access(acc);
 	if (mr_rereg_mask & IB_MR_REREG_TRANS) {
 		mhp->attr.zbva = 0;
 		mhp->attr.va_fbo = *iova_start;
@@ -613,8 +607,6 @@
 		goto err;
 	}
 
-	acc = iwch_convert_access(acc);
-
 	i = n = 0;
 
 	list_for_each_entry(chunk, &region->chunk_list, list)
@@ -630,10 +622,7 @@
 	mhp->rhp = rhp;
 	mhp->attr.pdid = php->pdid;
 	mhp->attr.zbva = 0;
-	mhp->attr.perms = (acc & 0x1) << 3;
-	mhp->attr.perms |= (acc & 0x2) << 1;
-	mhp->attr.perms |= (acc & 0x4) >> 1;
-	mhp->attr.perms |= (acc & 0x8) >> 3;
+	mhp->attr.perms = iwch_ib_to_tpt_access(acc);
 	mhp->attr.va_fbo = region->virt_base;
 	mhp->attr.page_size = shift - 12;
 	mhp->attr.len = (u32) region->length;
@@ -736,10 +725,8 @@
 	qhp = to_iwch_qp(ib_qp);
 	rhp = qhp->rhp;
 
-	if (qhp->attr.state == IWCH_QP_STATE_RTS) {
-		attrs.next_state = IWCH_QP_STATE_ERROR;
-		iwch_modify_qp(rhp, qhp, IWCH_QP_ATTR_NEXT_STATE, &attrs, 0);
-	}
+	attrs.next_state = IWCH_QP_STATE_ERROR;
+	iwch_modify_qp(rhp, qhp, IWCH_QP_ATTR_NEXT_STATE, &attrs, 0);
 	wait_event(qhp->wait, !qhp->ep);
 
 	remove_handle(rhp, &rhp->qpidr, qhp->wq.qpid);
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.h b/drivers/infiniband/hw/cxgb3/iwch_provider.h
index de0fe1b..93bcc56 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.h
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.h
@@ -286,27 +286,20 @@
 	}
 }
 
-enum iwch_mem_perms {
-	IWCH_MEM_ACCESS_LOCAL_READ = 1 << 0,
-	IWCH_MEM_ACCESS_LOCAL_WRITE = 1 << 1,
-	IWCH_MEM_ACCESS_REMOTE_READ = 1 << 2,
-	IWCH_MEM_ACCESS_REMOTE_WRITE = 1 << 3,
-	IWCH_MEM_ACCESS_ATOMICS = 1 << 4,
-	IWCH_MEM_ACCESS_BINDING = 1 << 5,
-	IWCH_MEM_ACCESS_LOCAL =
-	    (IWCH_MEM_ACCESS_LOCAL_READ | IWCH_MEM_ACCESS_LOCAL_WRITE),
-	IWCH_MEM_ACCESS_REMOTE =
-	    (IWCH_MEM_ACCESS_REMOTE_WRITE | IWCH_MEM_ACCESS_REMOTE_READ)
-	    /* cannot go beyond 1 << 31 */
-} __attribute__ ((packed));
-
-static inline u32 iwch_convert_access(int acc)
+static inline u32 iwch_ib_to_tpt_access(int acc)
 {
-	return (acc & IB_ACCESS_REMOTE_WRITE ? IWCH_MEM_ACCESS_REMOTE_WRITE : 0)
-	    | (acc & IB_ACCESS_REMOTE_READ ? IWCH_MEM_ACCESS_REMOTE_READ : 0) |
-	    (acc & IB_ACCESS_LOCAL_WRITE ? IWCH_MEM_ACCESS_LOCAL_WRITE : 0) |
-	    (acc & IB_ACCESS_MW_BIND ? IWCH_MEM_ACCESS_BINDING : 0) |
-	    IWCH_MEM_ACCESS_LOCAL_READ;
+	return (acc & IB_ACCESS_REMOTE_WRITE ? TPT_REMOTE_WRITE : 0) |
+	       (acc & IB_ACCESS_REMOTE_READ ? TPT_REMOTE_READ : 0) |
+	       (acc & IB_ACCESS_LOCAL_WRITE ? TPT_LOCAL_WRITE : 0) |
+	       TPT_LOCAL_READ;
+}
+
+static inline u32 iwch_ib_to_mwbind_access(int acc)
+{
+	return (acc & IB_ACCESS_REMOTE_WRITE ? T3_MEM_ACCESS_REM_WRITE : 0) |
+	       (acc & IB_ACCESS_REMOTE_READ ? T3_MEM_ACCESS_REM_READ : 0) |
+	       (acc & IB_ACCESS_LOCAL_WRITE ? T3_MEM_ACCESS_LOCAL_WRITE : 0) |
+	       T3_MEM_ACCESS_LOCAL_READ;
 }
 
 enum iwch_mmid_state {
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c
index 9ea00cc..0a472c9 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_qp.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c
@@ -439,7 +439,7 @@
 	wqe->bind.type = T3_VA_BASED_TO;
 
 	/* TBD: check perms */
-	wqe->bind.perms = iwch_convert_access(mw_bind->mw_access_flags);
+	wqe->bind.perms = iwch_ib_to_mwbind_access(mw_bind->mw_access_flags);
 	wqe->bind.mr_stag = cpu_to_be32(mw_bind->mr->lkey);
 	wqe->bind.mw_stag = cpu_to_be32(mw->rkey);
 	wqe->bind.mw_len = cpu_to_be32(mw_bind->length);
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index 40404c9..82ded44 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -52,6 +52,8 @@
 struct ehca_pd;
 struct ehca_av;
 
+#include <linux/wait.h>
+
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_user_verbs.h>
 
@@ -153,7 +155,9 @@
 	spinlock_t cb_lock;
 	struct hlist_head qp_hashtab[QP_HASHTAB_LEN];
 	struct list_head entry;
-	u32 nr_callbacks;
+	u32 nr_callbacks; /* #events assigned to cpu by scaling code */
+	u32 nr_events;    /* #events seen */
+	wait_queue_head_t wait_completion;
 	spinlock_t task_lock;
 	u32 ownpid;
 	/* mmap counter for resources mapped into user space */
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c
index 6ebfa27..e2cdc1a 100644
--- a/drivers/infiniband/hw/ehca/ehca_cq.c
+++ b/drivers/infiniband/hw/ehca/ehca_cq.c
@@ -146,6 +146,7 @@
 	spin_lock_init(&my_cq->spinlock);
 	spin_lock_init(&my_cq->cb_lock);
 	spin_lock_init(&my_cq->task_lock);
+	init_waitqueue_head(&my_cq->wait_completion);
 	my_cq->ownpid = current->tgid;
 
 	cq = &my_cq->ib_cq;
@@ -302,6 +303,16 @@
 	return cq;
 }
 
+static int get_cq_nr_events(struct ehca_cq *my_cq)
+{
+	int ret;
+	unsigned long flags;
+	spin_lock_irqsave(&ehca_cq_idr_lock, flags);
+	ret = my_cq->nr_events;
+	spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+	return ret;
+}
+
 int ehca_destroy_cq(struct ib_cq *cq)
 {
 	u64 h_ret;
@@ -329,10 +340,11 @@
 	}
 
 	spin_lock_irqsave(&ehca_cq_idr_lock, flags);
-	while (my_cq->nr_callbacks) {
+	while (my_cq->nr_events) {
 		spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
-		yield();
+		wait_event(my_cq->wait_completion, !get_cq_nr_events(my_cq));
 		spin_lock_irqsave(&ehca_cq_idr_lock, flags);
+		/* recheck nr_events to assure no cqe has just arrived */
 	}
 
 	idr_remove(&ehca_cq_idr, my_cq->token);
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c
index 3ec53c6..f284be1 100644
--- a/drivers/infiniband/hw/ehca/ehca_irq.c
+++ b/drivers/infiniband/hw/ehca/ehca_irq.c
@@ -66,7 +66,9 @@
 static void queue_comp_task(struct ehca_cq *__cq);
 
 static struct ehca_comp_pool* pool;
+#ifdef CONFIG_HOTPLUG_CPU
 static struct notifier_block comp_pool_callback_nb;
+#endif
 
 static inline void comp_event_callback(struct ehca_cq *cq)
 {
@@ -404,10 +406,11 @@
 	u32 token;
 	unsigned long flags;
 	struct ehca_cq *cq;
+
 	eqe_value = eqe->entry;
 	ehca_dbg(&shca->ib_device, "eqe_value=%lx", eqe_value);
 	if (EHCA_BMASK_GET(EQE_COMPLETION_EVENT, eqe_value)) {
-		ehca_dbg(&shca->ib_device, "... completion event");
+		ehca_dbg(&shca->ib_device, "Got completion event");
 		token = EHCA_BMASK_GET(EQE_CQ_TOKEN, eqe_value);
 		spin_lock_irqsave(&ehca_cq_idr_lock, flags);
 		cq = idr_find(&ehca_cq_idr, token);
@@ -419,16 +422,20 @@
 			return;
 		}
 		reset_eq_pending(cq);
-		if (ehca_scaling_code) {
+		cq->nr_events++;
+		spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+		if (ehca_scaling_code)
 			queue_comp_task(cq);
-			spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
-		} else {
-			spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+		else {
 			comp_event_callback(cq);
+			spin_lock_irqsave(&ehca_cq_idr_lock, flags);
+			cq->nr_events--;
+			if (!cq->nr_events)
+				wake_up(&cq->wait_completion);
+			spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
 		}
 	} else {
-		ehca_dbg(&shca->ib_device,
-			 "Got non completion event");
+		ehca_dbg(&shca->ib_device, "Got non completion event");
 		parse_identifier(shca, eqe_value);
 	}
 }
@@ -478,6 +485,7 @@
 					 "token=%x", token);
 				continue;
 			}
+			eqe_cache[eqe_cnt].cq->nr_events++;
 			spin_unlock(&ehca_cq_idr_lock);
 		} else
 			eqe_cache[eqe_cnt].cq = NULL;
@@ -504,12 +512,18 @@
 	/* call completion handler for cached eqes */
 	for (i = 0; i < eqe_cnt; i++)
 		if (eq->eqe_cache[i].cq) {
-			if (ehca_scaling_code) {
-				spin_lock(&ehca_cq_idr_lock);
+			if (ehca_scaling_code)
 				queue_comp_task(eq->eqe_cache[i].cq);
-				spin_unlock(&ehca_cq_idr_lock);
-			} else
-				comp_event_callback(eq->eqe_cache[i].cq);
+			else {
+				struct ehca_cq *cq = eq->eqe_cache[i].cq;
+				comp_event_callback(cq);
+				spin_lock_irqsave(&ehca_cq_idr_lock, flags);
+				cq->nr_events--;
+				if (!cq->nr_events)
+					wake_up(&cq->wait_completion);
+				spin_unlock_irqrestore(&ehca_cq_idr_lock,
+						       flags);
+			}
 		} else {
 			ehca_dbg(&shca->ib_device, "Got non completion event");
 			parse_identifier(shca, eq->eqe_cache[i].eqe->entry);
@@ -523,7 +537,6 @@
 		if (!eqe)
 			break;
 		process_eqe(shca, eqe);
-		eqe_cnt++;
 	} while (1);
 
 unlock_irq_spinlock:
@@ -567,8 +580,7 @@
 		list_add_tail(&__cq->entry, &cct->cq_list);
 		cct->cq_jobs++;
 		wake_up(&cct->wait_queue);
-	}
-	else
+	} else
 		__cq->nr_callbacks++;
 
 	spin_unlock(&__cq->task_lock);
@@ -577,18 +589,21 @@
 
 static void queue_comp_task(struct ehca_cq *__cq)
 {
-	int cpu;
 	int cpu_id;
 	struct ehca_cpu_comp_task *cct;
+	int cq_jobs;
+	unsigned long flags;
 
-	cpu = get_cpu();
 	cpu_id = find_next_online_cpu(pool);
 	BUG_ON(!cpu_online(cpu_id));
 
 	cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu_id);
 	BUG_ON(!cct);
 
-	if (cct->cq_jobs > 0) {
+	spin_lock_irqsave(&cct->task_lock, flags);
+	cq_jobs = cct->cq_jobs;
+	spin_unlock_irqrestore(&cct->task_lock, flags);
+	if (cq_jobs > 0) {
 		cpu_id = find_next_online_cpu(pool);
 		cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu_id);
 		BUG_ON(!cct);
@@ -608,11 +623,17 @@
 		cq = list_entry(cct->cq_list.next, struct ehca_cq, entry);
 		spin_unlock_irqrestore(&cct->task_lock, flags);
 		comp_event_callback(cq);
-		spin_lock_irqsave(&cct->task_lock, flags);
 
+		spin_lock_irqsave(&ehca_cq_idr_lock, flags);
+		cq->nr_events--;
+		if (!cq->nr_events)
+			wake_up(&cq->wait_completion);
+		spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
+
+		spin_lock_irqsave(&cct->task_lock, flags);
 		spin_lock(&cq->task_lock);
 		cq->nr_callbacks--;
-		if (cq->nr_callbacks == 0) {
+		if (!cq->nr_callbacks) {
 			list_del_init(cct->cq_list.next);
 			cct->cq_jobs--;
 		}
@@ -714,6 +735,7 @@
 
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
 static int comp_pool_callback(struct notifier_block *nfb,
 			      unsigned long action,
 			      void *hcpu)
@@ -756,6 +778,7 @@
 
 	return NOTIFY_OK;
 }
+#endif
 
 int ehca_create_comp_pool(void)
 {
@@ -786,9 +809,11 @@
 		}
 	}
 
+#ifdef CONFIG_HOTPLUG_CPU
 	comp_pool_callback_nb.notifier_call = comp_pool_callback;
 	comp_pool_callback_nb.priority =0;
 	register_cpu_notifier(&comp_pool_callback_nb);
+#endif
 
 	printk(KERN_INFO "eHCA scaling code enabled\n");
 
@@ -802,7 +827,9 @@
 	if (!ehca_scaling_code)
 		return;
 
+#ifdef CONFIG_HOTPLUG_CPU
 	unregister_cpu_notifier(&comp_pool_callback_nb);
+#endif
 
 	for (i = 0; i < NR_CPUS; i++) {
 		if (cpu_online(i))
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index c183512..059da96 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -52,7 +52,7 @@
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
 MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver");
-MODULE_VERSION("SVNEHCA_0021");
+MODULE_VERSION("SVNEHCA_0022");
 
 int ehca_open_aqp1     = 0;
 int ehca_debug_level   = 0;
@@ -810,7 +810,7 @@
 	int ret;
 
 	printk(KERN_INFO "eHCA Infiniband Device Driver "
-	       "(Rel.: SVNEHCA_0021)\n");
+	       "(Rel.: SVNEHCA_0022)\n");
 	idr_init(&ehca_qp_idr);
 	idr_init(&ehca_cq_idr);
 	spin_lock_init(&ehca_qp_idr_lock);
diff --git a/drivers/infiniband/hw/ipath/ipath_dma.c b/drivers/infiniband/hw/ipath/ipath_dma.c
index f6f9490..f87f003 100644
--- a/drivers/infiniband/hw/ipath/ipath_dma.c
+++ b/drivers/infiniband/hw/ipath/ipath_dma.c
@@ -167,7 +167,7 @@
 }
 
 static void ipath_dma_free_coherent(struct ib_device *dev, size_t size,
-				    void *cpu_addr, dma_addr_t dma_handle)
+				    void *cpu_addr, u64 dma_handle)
 {
 	free_pages((unsigned long) cpu_addr, get_order(size));
 }
diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c
index 5b40a84..ed55979 100644
--- a/drivers/infiniband/hw/ipath/ipath_fs.c
+++ b/drivers/infiniband/hw/ipath/ipath_fs.c
@@ -451,12 +451,18 @@
 	return ret;
 }
 
-static void remove_file(struct dentry *parent, char *name)
+static int remove_file(struct dentry *parent, char *name)
 {
 	struct dentry *tmp;
+	int ret;
 
 	tmp = lookup_one_len(name, parent, strlen(name));
 
+	if (IS_ERR(tmp)) {
+		ret = PTR_ERR(tmp);
+		goto bail;
+	}
+
 	spin_lock(&dcache_lock);
 	spin_lock(&tmp->d_lock);
 	if (!(d_unhashed(tmp) && tmp->d_inode)) {
@@ -469,6 +475,14 @@
 		spin_unlock(&tmp->d_lock);
 		spin_unlock(&dcache_lock);
 	}
+
+	ret = 0;
+bail:
+	/*
+	 * We don't expect clients to care about the return value, but
+	 * it's there if they need it.
+	 */
+	return ret;
 }
 
 static int remove_device_files(struct super_block *sb,
diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c
index 8e4846b..fdb576d 100644
--- a/drivers/infiniband/hw/mthca/mthca_mr.c
+++ b/drivers/infiniband/hw/mthca/mthca_mr.c
@@ -881,8 +881,8 @@
 		}
 		mpts = mtts = 1 << i;
 	} else {
-		mpts = dev->limits.num_mtt_segs;
-		mtts = dev->limits.num_mpts;
+		mtts = dev->limits.num_mtt_segs;
+		mpts = dev->limits.num_mpts;
 	}
 
 	if (!mthca_is_memfree(dev) &&
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 71dc84b..1c6b63a 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -1088,21 +1088,21 @@
 static int mthca_alloc_memfree(struct mthca_dev *dev,
 			       struct mthca_qp *qp)
 {
-	int ret = 0;
-
 	if (mthca_is_memfree(dev)) {
 		qp->rq.db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_RQ,
 						 qp->qpn, &qp->rq.db);
 		if (qp->rq.db_index < 0)
-			return ret;
+			return -ENOMEM;
 
 		qp->sq.db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_SQ,
 						 qp->qpn, &qp->sq.db);
-		if (qp->sq.db_index < 0)
+		if (qp->sq.db_index < 0) {
 			mthca_free_db(dev, MTHCA_DB_TYPE_RQ, qp->rq.db_index);
+			return -ENOMEM;
+		}
 	}
 
-	return ret;
+	return 0;
 }
 
 static void mthca_free_memfree(struct mthca_dev *dev,
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 3484e8b..2b242a4 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -131,7 +131,7 @@
 		skb_fill_page_desc(skb, i, page, 0, PAGE_SIZE);
 
 		mapping[i + 1] = ib_dma_map_page(priv->ca, skb_shinfo(skb)->frags[i].page,
-						 0, PAGE_SIZE, DMA_TO_DEVICE);
+						 0, PAGE_SIZE, DMA_FROM_DEVICE);
 		if (unlikely(ib_dma_mapping_error(priv->ca, mapping[i + 1])))
 			goto partial_error;
 	}
@@ -452,7 +452,7 @@
 			   skb->len, tx->mtu);
 		++priv->stats.tx_dropped;
 		++priv->stats.tx_errors;
-		ipoib_cm_skb_too_long(dev, skb, tx->mtu - INFINIBAND_ALEN);
+		ipoib_cm_skb_too_long(dev, skb, tx->mtu - IPOIB_ENCAP_LEN);
 		return;
 	}
 
@@ -1095,7 +1095,7 @@
 		/* List if sorted by LRU, start from tail,
 		 * stop when we see a recently used entry */
 		p = list_entry(priv->cm.passive_ids.prev, typeof(*p), list);
-		if (time_after_eq(jiffies, p->jiffies + IPOIB_CM_RX_TIMEOUT))
+		if (time_before_eq(jiffies, p->jiffies + IPOIB_CM_RX_TIMEOUT))
 			break;
 		list_del_init(&p->list);
 		spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index f2aa923..ba0ee5c 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -328,9 +328,9 @@
 	struct ipoib_tx_buf *tx_req;
 	u64 addr;
 
-	if (unlikely(skb->len > priv->mcast_mtu + INFINIBAND_ALEN)) {
+	if (unlikely(skb->len > priv->mcast_mtu + IPOIB_ENCAP_LEN)) {
 		ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n",
-			   skb->len, priv->mcast_mtu + INFINIBAND_ALEN);
+			   skb->len, priv->mcast_mtu + IPOIB_ENCAP_LEN);
 		++priv->stats.tx_dropped;
 		++priv->stats.tx_errors;
 		ipoib_cm_skb_too_long(dev, skb, priv->mcast_mtu);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index f9dbc6f..f2a40ae 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -380,7 +380,7 @@
 	struct net_device *dev = path->dev;
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	struct ipoib_ah *ah = NULL;
-	struct ipoib_neigh *neigh;
+	struct ipoib_neigh *neigh, *tn;
 	struct sk_buff_head skqueue;
 	struct sk_buff *skb;
 	unsigned long flags;
@@ -418,7 +418,7 @@
 		while ((skb = __skb_dequeue(&path->queue)))
 			__skb_queue_tail(&skqueue, skb);
 
-		list_for_each_entry(neigh, &path->neigh_list, list) {
+		list_for_each_entry_safe(neigh, tn, &path->neigh_list, list) {
 			kref_get(&path->ah->ref);
 			neigh->ah = path->ah;
 			memcpy(&neigh->dgid.raw, &path->pathrec.dgid.raw,
@@ -814,7 +814,7 @@
 	queue_work(ipoib_workqueue, &priv->restart_task);
 }
 
-static void ipoib_neigh_destructor(struct neighbour *n)
+static void ipoib_neigh_cleanup(struct neighbour *n)
 {
 	struct ipoib_neigh *neigh;
 	struct ipoib_dev_priv *priv = netdev_priv(n->dev);
@@ -822,7 +822,7 @@
 	struct ipoib_ah *ah = NULL;
 
 	ipoib_dbg(priv,
-		  "neigh_destructor for %06x " IPOIB_GID_FMT "\n",
+		  "neigh_cleanup for %06x " IPOIB_GID_FMT "\n",
 		  IPOIB_QPN(n->ha),
 		  IPOIB_GID_RAW_ARG(n->ha + 4));
 
@@ -874,7 +874,7 @@
 
 static int ipoib_neigh_setup_dev(struct net_device *dev, struct neigh_parms *parms)
 {
-	parms->neigh_destructor = ipoib_neigh_destructor;
+	parms->neigh_cleanup = ipoib_neigh_cleanup;
 
 	return 0;
 }
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index bb2e3d5..54fbead 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -407,6 +407,10 @@
 			queue_delayed_work(ipoib_workqueue,
 					   &priv->mcast_task, 0);
 		mutex_unlock(&mcast_mutex);
+
+		if (mcast == priv->broadcast)
+			netif_carrier_on(dev);
+
 		return 0;
 	}
 
@@ -594,7 +598,6 @@
 	ipoib_dbg_mcast(priv, "successfully joined all multicast groups\n");
 
 	clear_bit(IPOIB_MCAST_RUN, &priv->flags);
-	netif_carrier_on(dev);
 }
 
 int ipoib_mcast_start_thread(struct net_device *dev)
@@ -641,6 +644,9 @@
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	int ret = 0;
 
+	if (test_and_clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags))
+		ib_sa_free_multicast(mcast->mc);
+
 	if (test_and_clear_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags)) {
 		ipoib_dbg_mcast(priv, "leaving MGID " IPOIB_GID_FMT "\n",
 				IPOIB_GID_ARG(mcast->mcmember.mgid));
@@ -652,9 +658,6 @@
 			ipoib_warn(priv, "ipoib_mcast_detach failed (result = %d)\n", ret);
 	}
 
-	if (test_and_clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags))
-		ib_sa_free_multicast(mcast->mc);
-
 	return 0;
 }
 
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
index 3cb551b..7f3ec20 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
@@ -259,12 +259,13 @@
 	struct ipoib_dev_priv *priv =
 		container_of(handler, struct ipoib_dev_priv, event_handler);
 
-	if (record->event == IB_EVENT_PORT_ERR    ||
-	    record->event == IB_EVENT_PKEY_CHANGE ||
-	    record->event == IB_EVENT_PORT_ACTIVE ||
-	    record->event == IB_EVENT_LID_CHANGE  ||
-	    record->event == IB_EVENT_SM_CHANGE   ||
-	    record->event == IB_EVENT_CLIENT_REREGISTER) {
+	if ((record->event == IB_EVENT_PORT_ERR    ||
+	     record->event == IB_EVENT_PKEY_CHANGE ||
+	     record->event == IB_EVENT_PORT_ACTIVE ||
+	     record->event == IB_EVENT_LID_CHANGE  ||
+	     record->event == IB_EVENT_SM_CHANGE   ||
+	     record->event == IB_EVENT_CLIENT_REREGISTER) &&
+	    record->element.port_num == priv->port) {
 		ipoib_dbg(priv, "Port state change event\n");
 		queue_work(ipoib_workqueue, &priv->flush_task);
 	}
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
index cae8c96..8960196 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -245,7 +245,6 @@
 	wait_queue_head_t	     wait;          /* waitq for conn/disconn  */
 	atomic_t                     post_recv_buf_count; /* posted rx count   */
 	atomic_t                     post_send_buf_count; /* posted tx count   */
-	struct work_struct           comperror_work; /* conn term sleepable ctx*/
 	char 			     name[ISER_OBJECT_NAME_SIZE];
 	struct iser_page_vec         *page_vec;     /* represents SG to fmr maps*
 						     * maps serialized as tx is*/
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
index 89e3728..278fcbc 100644
--- a/drivers/infiniband/ulp/iser/iser_initiator.c
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -658,6 +658,7 @@
 {
 	int deferred;
 	int is_rdma_aligned = 1;
+	struct iser_regd_buf *regd;
 
 	/* if we were reading, copy back to unaligned sglist,
 	 * anyway dma_unmap and free the copy
@@ -672,20 +673,20 @@
 	}
 
 	if (iser_ctask->dir[ISER_DIR_IN]) {
-		deferred = iser_regd_buff_release
-			(&iser_ctask->rdma_regd[ISER_DIR_IN]);
+		regd = &iser_ctask->rdma_regd[ISER_DIR_IN];
+		deferred = iser_regd_buff_release(regd);
 		if (deferred) {
-			iser_err("References remain for BUF-IN rdma reg\n");
-			BUG();
+			iser_err("%d references remain for BUF-IN rdma reg\n",
+				 atomic_read(&regd->ref_count));
 		}
 	}
 
 	if (iser_ctask->dir[ISER_DIR_OUT]) {
-		deferred = iser_regd_buff_release
-			(&iser_ctask->rdma_regd[ISER_DIR_OUT]);
+		regd = &iser_ctask->rdma_regd[ISER_DIR_OUT];
+		deferred = iser_regd_buff_release(regd);
 		if (deferred) {
-			iser_err("References remain for BUF-OUT rdma reg\n");
-			BUG();
+			iser_err("%d references remain for BUF-OUT rdma reg\n",
+				 atomic_read(&regd->ref_count));
 		}
 	}
 
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 693b770..1fc9674 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -48,7 +48,6 @@
 
 static void iser_cq_tasklet_fn(unsigned long data);
 static void iser_cq_callback(struct ib_cq *cq, void *cq_context);
-static void iser_comp_error_worker(struct work_struct *work);
 
 static void iser_cq_event_callback(struct ib_event *cause, void *context)
 {
@@ -480,7 +479,6 @@
 	init_waitqueue_head(&ib_conn->wait);
 	atomic_set(&ib_conn->post_recv_buf_count, 0);
 	atomic_set(&ib_conn->post_send_buf_count, 0);
-	INIT_WORK(&ib_conn->comperror_work, iser_comp_error_worker);
 	INIT_LIST_HEAD(&ib_conn->conn_list);
 	spin_lock_init(&ib_conn->lock);
 
@@ -753,26 +751,6 @@
 	return ret_val;
 }
 
-static void iser_comp_error_worker(struct work_struct *work)
-{
-	struct iser_conn *ib_conn =
-		container_of(work, struct iser_conn, comperror_work);
-
-	/* getting here when the state is UP means that the conn is being *
-	 * terminated asynchronously from the iSCSI layer's perspective.  */
-	if (iser_conn_state_comp_exch(ib_conn, ISER_CONN_UP,
-				      ISER_CONN_TERMINATING))
-		iscsi_conn_failure(ib_conn->iser_conn->iscsi_conn,
-					ISCSI_ERR_CONN_FAILED);
-
-	/* complete the termination process if disconnect event was delivered *
-	 * note there are no more non completed posts to the QP               */
-	if (ib_conn->disc_evt_flag) {
-		ib_conn->state = ISER_CONN_DOWN;
-		wake_up_interruptible(&ib_conn->wait);
-	}
-}
-
 static void iser_handle_comp_error(struct iser_desc *desc)
 {
 	struct iser_dto  *dto     = &desc->dto;
@@ -791,8 +769,22 @@
 	}
 
 	if (atomic_read(&ib_conn->post_recv_buf_count) == 0 &&
-	    atomic_read(&ib_conn->post_send_buf_count) == 0)
-		schedule_work(&ib_conn->comperror_work);
+	    atomic_read(&ib_conn->post_send_buf_count) == 0) {
+		/* getting here when the state is UP means that the conn is *
+		 * being terminated asynchronously from the iSCSI layer's   *
+		 * perspective.                                             */
+		if (iser_conn_state_comp_exch(ib_conn, ISER_CONN_UP,
+		    ISER_CONN_TERMINATING))
+			iscsi_conn_failure(ib_conn->iser_conn->iscsi_conn,
+					   ISCSI_ERR_CONN_FAILED);
+
+		/* complete the termination process if disconnect event was delivered *
+		 * note there are no more non completed posts to the QP               */
+		if (ib_conn->disc_evt_flag) {
+			ib_conn->state = ISER_CONN_DOWN;
+			wake_up_interruptible(&ib_conn->wait);
+		}
+	}
 }
 
 static void iser_cq_tasklet_fn(unsigned long data)
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index ec195a3..db9cca3 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -553,7 +553,8 @@
  */
 
 	param = 0x5a;
-	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0x5a) {
+	retval = i8042_command(&param, I8042_CMD_AUX_LOOP);
+	if (retval || param != 0x5a) {
 
 /*
  * External connection test - filters out AT-soldered PS/2 i8042's
@@ -567,7 +568,12 @@
 		    (param && param != 0xfa && param != 0xff))
 			return -1;
 
-		aux_loop_broken = 1;
+/*
+ * If AUX_LOOP completed without error but returned unexpected data
+ * mark it as broken
+ */
+		if (!retval)
+			aux_loop_broken = 1;
 	}
 
 /*
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index c7db4032..e8606c4 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -553,6 +553,7 @@
 }
 
 static struct device_driver ucb1400_ts_driver = {
+	.name		= "ucb1400_ts",
 	.owner		= THIS_MODULE,
 	.bus		= &ac97_bus_type,
 	.probe		= ucb1400_ts_probe,
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 63e51dd..00e3160 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -54,7 +54,7 @@
 #define USB_SX353_PRODUCT_ID    0x0022
 
 /* table of devices that work with this driver */
-static struct usb_device_id gigaset_table [] = {
+static const struct usb_device_id gigaset_table [] = {
 	{ USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3070_PRODUCT_ID) },
 	{ USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3075_PRODUCT_ID) },
 	{ USB_DEVICE(USB_GIGA_VENDOR_ID, USB_SX303_PRODUCT_ID) },
@@ -2305,7 +2305,7 @@
 	gigaset_unassign(cs);
 }
 
-static struct gigaset_ops gigops = {
+static const struct gigaset_ops gigops = {
 	gigaset_write_cmd,
 	gigaset_write_room,
 	gigaset_chars_in_buffer,
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index b460a73..6df336b 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -944,8 +944,8 @@
 struct cardstate *gigaset_get_cs_by_id(int id)
 {
 	unsigned long flags;
-	static struct cardstate *ret = NULL;
-	static struct cardstate *cs;
+	struct cardstate *ret = NULL;
+	struct cardstate *cs;
 	struct gigaset_driver *drv;
 	unsigned i;
 
@@ -999,7 +999,7 @@
 static struct cardstate *gigaset_get_cs_by_minor(unsigned minor)
 {
 	unsigned long flags;
-	static struct cardstate *ret = NULL;
+	struct cardstate *ret = NULL;
 	struct gigaset_driver *drv;
 	unsigned index;
 
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index 4661e2c..cec1ef3 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -409,7 +409,7 @@
 };
 #endif
 
-static struct resp_type_t resp_type[]=
+static const struct resp_type_t resp_type[] =
 {
 	/*{"",		RSP_EMPTY,	RT_NOTHING},*/
 	{"OK",		RSP_OK,		RT_NOTHING},
@@ -511,7 +511,7 @@
 	unsigned char *argv[MAX_REC_PARAMS + 1];
 	int params;
 	int i, j;
-	struct resp_type_t *rt;
+	const struct resp_type_t *rt;
 	int curarg;
 	unsigned long flags;
 	unsigned next, tail, head;
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c
index 8c0eb52..e0505f2 100644
--- a/drivers/isdn/gigaset/isocdata.c
+++ b/drivers/isdn/gigaset/isocdata.c
@@ -274,7 +274,7 @@
  *        bit 12..10 = number of trailing '1' bits in result
  *        bit 14..13 = number of bits added by stuffing
  */
-static u16 stufftab[5 * 256] = {
+static const u16 stufftab[5 * 256] = {
 // previous 1s = 0:
  0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
  0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x201f,
@@ -629,7 +629,7 @@
  *		     (replacing 8 by 7 to make it fit; the algorithm won't care)
  *        bit 7 set if there are 5 or more "interior" consecutive '1' bits
  */
-static unsigned char bitcounts[256] = {
+static const unsigned char bitcounts[256] = {
   0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
   0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05,
   0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c
index c8b7db6..ea44302 100644
--- a/drivers/isdn/gigaset/ser-gigaset.c
+++ b/drivers/isdn/gigaset/ser-gigaset.c
@@ -459,7 +459,7 @@
 	return -EINVAL;
 }
 
-static struct gigaset_ops ops = {
+static const struct gigaset_ops ops = {
 	gigaset_write_cmd,
 	gigaset_write_room,
 	gigaset_chars_in_buffer,
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
index 04f2ad7..2baef34 100644
--- a/drivers/isdn/gigaset/usb-gigaset.c
+++ b/drivers/isdn/gigaset/usb-gigaset.c
@@ -50,7 +50,7 @@
 #define USB_M105_PRODUCT_ID	0x0009
 
 /* table of devices that work with this driver */
-static struct usb_device_id gigaset_table [] = {
+static const struct usb_device_id gigaset_table [] = {
 	{ USB_DEVICE(USB_M105_VENDOR_ID, USB_M105_PRODUCT_ID) },
 	{ }					/* Terminating entry */
 };
@@ -860,7 +860,7 @@
 	gigaset_unassign(cs);
 }
 
-static struct gigaset_ops ops = {
+static const struct gigaset_ops ops = {
 	gigaset_write_cmd,
 	gigaset_write_room,
 	gigaset_chars_in_buffer,
diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c
index 9df9e35..c547a66 100644
--- a/drivers/isdn/hisax/isar.c
+++ b/drivers/isdn/hisax/isar.c
@@ -440,7 +440,7 @@
 {
 	struct BCState *bcs = container_of(work, struct BCState, tqueue);
 
-	BChannel_bh(bcs);
+	BChannel_bh(work);
 	if (test_and_clear_bit(B_LL_NOCARRIER, &bcs->event))
 		ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_NOCARR);
 	if (test_and_clear_bit(B_LL_CONNECT, &bcs->event))
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index a163bca..dc7a8c7 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -2464,7 +2464,7 @@
 
 	r = kvm_arch_ops->hardware_setup();
 	if (r < 0)
-	    return r;
+		goto out;
 
 	on_each_cpu(kvm_arch_ops->hardware_enable, NULL, 0, 1);
 	r = register_cpu_notifier(&kvm_cpu_notifier);
@@ -2500,6 +2500,8 @@
 out_free_1:
 	on_each_cpu(kvm_arch_ops->hardware_disable, NULL, 0, 1);
 	kvm_arch_ops->hardware_unsetup();
+out:
+	kvm_arch_ops = NULL;
 	return r;
 }
 
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c
index a1a9336..e85b4c7 100644
--- a/drivers/kvm/mmu.c
+++ b/drivers/kvm/mmu.c
@@ -131,7 +131,7 @@
 	(((address) >> PT32_LEVEL_SHIFT(level)) & ((1 << PT32_LEVEL_BITS) - 1))
 
 
-#define PT64_BASE_ADDR_MASK (((1ULL << 52) - 1) & PAGE_MASK)
+#define PT64_BASE_ADDR_MASK (((1ULL << 52) - 1) & ~(u64)(PAGE_SIZE-1))
 #define PT64_DIR_BASE_ADDR_MASK \
 	(PT64_BASE_ADDR_MASK & ~((1ULL << (PAGE_SHIFT + PT64_LEVEL_BITS)) - 1))
 
@@ -406,8 +406,8 @@
 			spte = desc->shadow_ptes[0];
 		}
 		BUG_ON(!spte);
-		BUG_ON((*spte & PT64_BASE_ADDR_MASK) !=
-		       page_to_pfn(page) << PAGE_SHIFT);
+		BUG_ON((*spte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT
+		       != page_to_pfn(page));
 		BUG_ON(!(*spte & PT_PRESENT_MASK));
 		BUG_ON(!(*spte & PT_WRITABLE_MASK));
 		rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte);
@@ -1093,22 +1093,40 @@
 	return r;
 }
 
+static void mmu_pre_write_zap_pte(struct kvm_vcpu *vcpu,
+				  struct kvm_mmu_page *page,
+				  u64 *spte)
+{
+	u64 pte;
+	struct kvm_mmu_page *child;
+
+	pte = *spte;
+	if (is_present_pte(pte)) {
+		if (page->role.level == PT_PAGE_TABLE_LEVEL)
+			rmap_remove(vcpu, spte);
+		else {
+			child = page_header(pte & PT64_BASE_ADDR_MASK);
+			mmu_page_remove_parent_pte(vcpu, child, spte);
+		}
+	}
+	*spte = 0;
+}
+
 void kvm_mmu_pre_write(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes)
 {
 	gfn_t gfn = gpa >> PAGE_SHIFT;
 	struct kvm_mmu_page *page;
-	struct kvm_mmu_page *child;
 	struct hlist_node *node, *n;
 	struct hlist_head *bucket;
 	unsigned index;
 	u64 *spte;
-	u64 pte;
 	unsigned offset = offset_in_page(gpa);
 	unsigned pte_size;
 	unsigned page_offset;
 	unsigned misaligned;
 	int level;
 	int flooded = 0;
+	int npte;
 
 	pgprintk("%s: gpa %llx bytes %d\n", __FUNCTION__, gpa, bytes);
 	if (gfn == vcpu->last_pt_write_gfn) {
@@ -1144,22 +1162,26 @@
 		}
 		page_offset = offset;
 		level = page->role.level;
+		npte = 1;
 		if (page->role.glevels == PT32_ROOT_LEVEL) {
-			page_offset <<= 1;          /* 32->64 */
+			page_offset <<= 1;	/* 32->64 */
+			/*
+			 * A 32-bit pde maps 4MB while the shadow pdes map
+			 * only 2MB.  So we need to double the offset again
+			 * and zap two pdes instead of one.
+			 */
+			if (level == PT32_ROOT_LEVEL) {
+				page_offset <<= 1;
+				npte = 2;
+			}
 			page_offset &= ~PAGE_MASK;
 		}
 		spte = __va(page->page_hpa);
 		spte += page_offset / sizeof(*spte);
-		pte = *spte;
-		if (is_present_pte(pte)) {
-			if (level == PT_PAGE_TABLE_LEVEL)
-				rmap_remove(vcpu, spte);
-			else {
-				child = page_header(pte & PT64_BASE_ADDR_MASK);
-				mmu_page_remove_parent_pte(vcpu, child, spte);
-			}
+		while (npte--) {
+			mmu_pre_write_zap_pte(vcpu, page, spte);
+			++spte;
 		}
-		*spte = 0;
 	}
 }
 
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index c07178e..fbbf9d6 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -371,10 +371,10 @@
 		data = vmcs_read32(GUEST_SYSENTER_CS);
 		break;
 	case MSR_IA32_SYSENTER_EIP:
-		data = vmcs_read32(GUEST_SYSENTER_EIP);
+		data = vmcs_readl(GUEST_SYSENTER_EIP);
 		break;
 	case MSR_IA32_SYSENTER_ESP:
-		data = vmcs_read32(GUEST_SYSENTER_ESP);
+		data = vmcs_readl(GUEST_SYSENTER_ESP);
 		break;
 	default:
 		msr = find_msr_entry(vcpu, msr_index);
@@ -412,10 +412,10 @@
 		vmcs_write32(GUEST_SYSENTER_CS, data);
 		break;
 	case MSR_IA32_SYSENTER_EIP:
-		vmcs_write32(GUEST_SYSENTER_EIP, data);
+		vmcs_writel(GUEST_SYSENTER_EIP, data);
 		break;
 	case MSR_IA32_SYSENTER_ESP:
-		vmcs_write32(GUEST_SYSENTER_ESP, data);
+		vmcs_writel(GUEST_SYSENTER_ESP, data);
 		break;
 	case MSR_IA32_TIME_STAMP_COUNTER:
 		guest_write_tsc(data);
@@ -618,7 +618,7 @@
 {
 	struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
 
-	if (vmcs_readl(sf->base) == save->base) {
+	if (vmcs_readl(sf->base) == save->base && (save->base & AR_S_MASK)) {
 		vmcs_write16(sf->selector, save->selector);
 		vmcs_writel(sf->base, save->base);
 		vmcs_write32(sf->limit, save->limit);
@@ -1888,6 +1888,27 @@
 		[cr2]"i"(offsetof(struct kvm_vcpu, cr2))
 	      : "cc", "memory" );
 
+	/*
+	 * Reload segment selectors ASAP. (it's needed for a functional
+	 * kernel: x86 relies on having __KERNEL_PDA in %fs and x86_64
+	 * relies on having 0 in %gs for the CPU PDA to work.)
+	 */
+	if (fs_gs_ldt_reload_needed) {
+		load_ldt(ldt_sel);
+		load_fs(fs_sel);
+		/*
+		 * If we have to reload gs, we must take care to
+		 * preserve our gs base.
+		 */
+		local_irq_disable();
+		load_gs(gs_sel);
+#ifdef CONFIG_X86_64
+		wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE));
+#endif
+		local_irq_enable();
+
+		reload_tss();
+	}
 	++kvm_stat.exits;
 
 	save_msrs(vcpu->guest_msrs, NR_BAD_MSRS);
@@ -1905,22 +1926,6 @@
 		kvm_run->exit_reason = vmcs_read32(VM_INSTRUCTION_ERROR);
 		r = 0;
 	} else {
-		if (fs_gs_ldt_reload_needed) {
-			load_ldt(ldt_sel);
-			load_fs(fs_sel);
-			/*
-			 * If we have to reload gs, we must take care to
-			 * preserve our gs base.
-			 */
-			local_irq_disable();
-			load_gs(gs_sel);
-#ifdef CONFIG_X86_64
-			wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE));
-#endif
-			local_irq_enable();
-
-			reload_tss();
-		}
 		/*
 		 * Profile KVM exit RIPs:
 		 */
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index c625ddb..d5ecd2d 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -188,7 +188,7 @@
 	for (i=0; i < cnt-1 ; i++) {
 		sector_t sz = 0;
 		int j;
-		for (j=i; i<cnt-1 && sz < min_spacing ; j++)
+		for (j = i; j < cnt - 1 && sz < min_spacing; j++)
 			sz += conf->disks[j].size;
 		if (sz >= min_spacing && sz < conf->hash_spacing)
 			conf->hash_spacing = sz;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 6c06e82..509171c 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1318,6 +1318,7 @@
 	char b[BDEVNAME_SIZE];
 	struct kobject *ko;
 	char *s;
+	int err;
 
 	if (rdev->mddev) {
 		MD_BUG();
@@ -1352,20 +1353,35 @@
 	while ( (s=strchr(rdev->kobj.k_name, '/')) != NULL)
 		*s = '!';
 			
-	list_add(&rdev->same_set, &mddev->disks);
 	rdev->mddev = mddev;
 	printk(KERN_INFO "md: bind<%s>\n", b);
 
 	rdev->kobj.parent = &mddev->kobj;
-	kobject_add(&rdev->kobj);
+	if ((err = kobject_add(&rdev->kobj)))
+		goto fail;
 
 	if (rdev->bdev->bd_part)
 		ko = &rdev->bdev->bd_part->kobj;
 	else
 		ko = &rdev->bdev->bd_disk->kobj;
-	sysfs_create_link(&rdev->kobj, ko, "block");
+	if ((err = sysfs_create_link(&rdev->kobj, ko, "block"))) {
+		kobject_del(&rdev->kobj);
+		goto fail;
+	}
+	list_add(&rdev->same_set, &mddev->disks);
 	bd_claim_by_disk(rdev->bdev, rdev, mddev->gendisk);
 	return 0;
+
+ fail:
+	printk(KERN_WARNING "md: failed to register dev-%s for %s\n",
+	       b, mdname(mddev));
+	return err;
+}
+
+static void delayed_delete(struct work_struct *ws)
+{
+	mdk_rdev_t *rdev = container_of(ws, mdk_rdev_t, del_work);
+	kobject_del(&rdev->kobj);
 }
 
 static void unbind_rdev_from_array(mdk_rdev_t * rdev)
@@ -1380,7 +1396,12 @@
 	printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b));
 	rdev->mddev = NULL;
 	sysfs_remove_link(&rdev->kobj, "block");
-	kobject_del(&rdev->kobj);
+
+	/* We need to delay this, otherwise we can deadlock when
+	 * writing to 'remove' to "dev/state"
+	 */
+	INIT_WORK(&rdev->del_work, delayed_delete);
+	schedule_work(&rdev->del_work);
 }
 
 /*
@@ -2966,7 +2987,9 @@
 	mddev->kobj.k_name = NULL;
 	snprintf(mddev->kobj.name, KOBJ_NAME_LEN, "%s", "md");
 	mddev->kobj.ktype = &md_ktype;
-	kobject_register(&mddev->kobj);
+	if (kobject_register(&mddev->kobj))
+		printk(KERN_WARNING "md: cannot register %s/md - name in use\n",
+		       disk->disk_name);
 	return NULL;
 }
 
@@ -3144,9 +3167,12 @@
 		bitmap_destroy(mddev);
 		return err;
 	}
-	if (mddev->pers->sync_request)
-		sysfs_create_group(&mddev->kobj, &md_redundancy_group);
-	else if (mddev->ro == 2) /* auto-readonly not meaningful */
+	if (mddev->pers->sync_request) {
+		if (sysfs_create_group(&mddev->kobj, &md_redundancy_group))
+			printk(KERN_WARNING
+			       "md: cannot register extra attributes for %s\n",
+			       mdname(mddev));
+	} else if (mddev->ro == 2) /* auto-readonly not meaningful */
 		mddev->ro = 0;
 
  	atomic_set(&mddev->writes_pending,0);
@@ -3160,7 +3186,9 @@
 		if (rdev->raid_disk >= 0) {
 			char nm[20];
 			sprintf(nm, "rd%d", rdev->raid_disk);
-			sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
+			if (sysfs_create_link(&mddev->kobj, &rdev->kobj, nm))
+				printk("md: cannot register %s for %s\n",
+				       nm, mdname(mddev));
 		}
 	
 	set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
@@ -3325,6 +3353,7 @@
 			mddev->queue->merge_bvec_fn = NULL;
 			mddev->queue->unplug_fn = NULL;
 			mddev->queue->issue_flush_fn = NULL;
+			mddev->queue->backing_dev_info.congested_fn = NULL;
 			if (mddev->pers->sync_request)
 				sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
 
@@ -3371,6 +3400,9 @@
 				sysfs_remove_link(&mddev->kobj, nm);
 			}
 
+		/* make sure all delayed_delete calls have finished */
+		flush_scheduled_work();
+
 		export_array(mddev);
 
 		mddev->array_size = 0;
@@ -5385,8 +5417,12 @@
 				if (mddev->pers->hot_add_disk(mddev,rdev)) {
 					char nm[20];
 					sprintf(nm, "rd%d", rdev->raid_disk);
-					sysfs_create_link(&mddev->kobj,
-							  &rdev->kobj, nm);
+					if (sysfs_create_link(&mddev->kobj,
+							      &rdev->kobj, nm))
+						printk(KERN_WARNING
+						       "md: cannot register "
+						       "%s for %s\n",
+						       nm, mdname(mddev));
 					spares++;
 					md_new_event(mddev);
 				} else
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 54a1ad5..8d59914 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3642,12 +3642,15 @@
 	}
 
 	/* Ok, everything is just fine now */
-	sysfs_create_group(&mddev->kobj, &raid5_attrs_group);
+	if (sysfs_create_group(&mddev->kobj, &raid5_attrs_group))
+		printk(KERN_WARNING
+		       "raid5: failed to create sysfs attributes for %s\n",
+		       mdname(mddev));
 
 	mddev->queue->unplug_fn = raid5_unplug_device;
 	mddev->queue->issue_flush_fn = raid5_issue_flush;
-	mddev->queue->backing_dev_info.congested_fn = raid5_congested;
 	mddev->queue->backing_dev_info.congested_data = mddev;
+	mddev->queue->backing_dev_info.congested_fn = raid5_congested;
 
 	mddev->array_size =  mddev->size * (conf->previous_raid_disks -
 					    conf->max_degraded);
@@ -3678,6 +3681,7 @@
 	mddev->thread = NULL;
 	shrink_stripes(conf);
 	kfree(conf->stripe_hashtbl);
+	mddev->queue->backing_dev_info.congested_fn = NULL;
 	blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
 	sysfs_remove_group(&mddev->kobj, &raid5_attrs_group);
 	kfree(conf->disks);
@@ -3950,7 +3954,12 @@
 				added_devices++;
 				rdev->recovery_offset = 0;
 				sprintf(nm, "rd%d", rdev->raid_disk);
-				sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
+				if (sysfs_create_link(&mddev->kobj,
+						      &rdev->kobj, nm))
+					printk(KERN_WARNING
+					       "raid5: failed to create "
+					       " link %s for %s\n",
+					       nm, mdname(mddev));
 			} else
 				break;
 		}
@@ -4104,6 +4113,10 @@
 	.spare_active	= raid5_spare_active,
 	.sync_request	= sync_request,
 	.resize		= raid5_resize,
+#ifdef CONFIG_MD_RAID5_RESHAPE
+	.check_reshape	= raid5_check_reshape,
+	.start_reshape  = raid5_start_reshape,
+#endif
 	.quiesce	= raid5_quiesce,
 };
 
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c
index cbf7c05..fcb1941 100644
--- a/drivers/media/common/ir-functions.c
+++ b/drivers/media/common/ir-functions.c
@@ -310,13 +310,15 @@
 		    tv.tv_usec - ir->base_time.tv_usec;
 	}
 
-	/* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */
+	/* signal we're ready to start a new code */
+	ir->active = 0;
+
+	/* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */
 	if (gap < 28000) {
 		dprintk(1, "ir-common: spurious timer_end\n");
 		return;
 	}
 
-	ir->active = 0;
 	if (ir->last_bit < 20) {
 		/* ignore spurious codes (caused by light/other remotes) */
 		dprintk(1, "ir-common: short code: %x\n", ir->code);
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index fc77de4..a5c0e1a 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -180,8 +180,7 @@
 	struct dvb_device *dvbdev = file->private_data;
 	struct dmxdev *dmxdev = dvbdev->priv;
 
-	if (mutex_lock_interruptible(&dmxdev->mutex))
-		return -ERESTARTSYS;
+	mutex_lock(&dmxdev->mutex);
 
 	if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
 		dmxdev->demux->disconnect_frontend(dmxdev->demux);
@@ -673,13 +672,8 @@
 static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev,
 				  struct dmxdev_filter *dmxdevfilter)
 {
-	if (mutex_lock_interruptible(&dmxdev->mutex))
-		return -ERESTARTSYS;
-
-	if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
-		mutex_unlock(&dmxdev->mutex);
-		return -ERESTARTSYS;
-	}
+	mutex_lock(&dmxdev->mutex);
+	mutex_lock(&dmxdevfilter->mutex);
 
 	dvb_dmxdev_filter_stop(dmxdevfilter);
 	dvb_dmxdev_filter_reset(dmxdevfilter);
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index fcff5ea..6d8d1c3d 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -673,8 +673,7 @@
 	struct dvb_demux *demux = feed->demux;
 	int ret;
 
-	if (mutex_lock_interruptible(&demux->mutex))
-		return -ERESTARTSYS;
+	mutex_lock(&demux->mutex);
 
 	if (feed->state < DMX_STATE_GO) {
 		mutex_unlock(&demux->mutex);
@@ -748,8 +747,7 @@
 	struct dvb_demux *demux = (struct dvb_demux *)dmx;
 	struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
 
-	if (mutex_lock_interruptible(&demux->mutex))
-		return -ERESTARTSYS;
+	mutex_lock(&demux->mutex);
 
 	if (feed->state == DMX_STATE_FREE) {
 		mutex_unlock(&demux->mutex);
@@ -916,8 +914,7 @@
 	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
 	int ret;
 
-	if (mutex_lock_interruptible(&dvbdmx->mutex))
-		return -ERESTARTSYS;
+	mutex_lock(&dvbdmx->mutex);
 
 	if (!dvbdmx->stop_feed) {
 		mutex_unlock(&dvbdmx->mutex);
@@ -942,8 +939,7 @@
 	struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
 	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
 
-	if (mutex_lock_interruptible(&dvbdmx->mutex))
-		return -ERESTARTSYS;
+	mutex_lock(&dvbdmx->mutex);
 
 	if (dvbdmxfilter->feed != dvbdmxfeed) {
 		mutex_unlock(&dvbdmx->mutex);
@@ -1016,8 +1012,7 @@
 	struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed;
 	struct dvb_demux *dvbdmx = (struct dvb_demux *)demux;
 
-	if (mutex_lock_interruptible(&dvbdmx->mutex))
-		return -ERESTARTSYS;
+	mutex_lock(&dvbdmx->mutex);
 
 	if (dvbdmxfeed->state == DMX_STATE_FREE) {
 		mutex_unlock(&dvbdmx->mutex);
@@ -1126,8 +1121,7 @@
 	if (demux->frontend)
 		return -EINVAL;
 
-	if (mutex_lock_interruptible(&dvbdemux->mutex))
-		return -ERESTARTSYS;
+	mutex_lock(&dvbdemux->mutex);
 
 	demux->frontend = frontend;
 	mutex_unlock(&dvbdemux->mutex);
@@ -1138,8 +1132,7 @@
 {
 	struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
 
-	if (mutex_lock_interruptible(&dvbdemux->mutex))
-		return -ERESTARTSYS;
+	mutex_lock(&dvbdemux->mutex);
 
 	demux->frontend = NULL;
 	mutex_unlock(&dvbdemux->mutex);
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 490337b..14a372a 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -203,8 +203,7 @@
 
 	int id;
 
-	if (mutex_lock_interruptible(&dvbdev_register_lock))
-		return -ERESTARTSYS;
+	mutex_lock(&dvbdev_register_lock);
 
 	if ((id = dvbdev_get_free_id (adap, type)) < 0){
 		mutex_unlock(&dvbdev_register_lock);
@@ -294,8 +293,7 @@
 {
 	int num;
 
-	if (mutex_lock_interruptible(&dvbdev_register_lock))
-		return -ERESTARTSYS;
+	mutex_lock(&dvbdev_register_lock);
 
 	if ((num = dvbdev_get_free_adapter_num ()) < 0) {
 		mutex_unlock(&dvbdev_register_lock);
@@ -323,8 +321,7 @@
 
 int dvb_unregister_adapter(struct dvb_adapter *adap)
 {
-	if (mutex_lock_interruptible(&dvbdev_register_lock))
-		return -ERESTARTSYS;
+	mutex_lock(&dvbdev_register_lock);
 	list_del (&adap->list_head);
 	mutex_unlock(&dvbdev_register_lock);
 	return 0;
diff --git a/drivers/media/dvb/frontends/isl6421.c b/drivers/media/dvb/frontends/isl6421.c
index ef31936..c967148 100644
--- a/drivers/media/dvb/frontends/isl6421.c
+++ b/drivers/media/dvb/frontends/isl6421.c
@@ -122,6 +122,7 @@
 	/* detect if it is present or not */
 	if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) {
 		kfree(isl6421);
+		fe->sec_priv = NULL;
 		return NULL;
 	}
 
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c
index 87c286e..b809f83 100644
--- a/drivers/media/dvb/frontends/nxt200x.c
+++ b/drivers/media/dvb/frontends/nxt200x.c
@@ -562,7 +562,7 @@
 
 			/* set input */
 			if (state->config->set_pll_input)
-				state->config->set_pll_input(buf, 1);
+				state->config->set_pll_input(buf+1, 1);
 			break;
 		case VSB_8:
 			/* Set non-punctured clock for VSB */
@@ -571,7 +571,7 @@
 
 			/* set input */
 			if (state->config->set_pll_input)
-				state->config->set_pll_input(buf, 0);
+				state->config->set_pll_input(buf+1, 0);
 			break;
 		default:
 			return -EINVAL;
diff --git a/drivers/media/dvb/frontends/tda10086.c b/drivers/media/dvb/frontends/tda10086.c
index 4c27a2d9..ccc429c 100644
--- a/drivers/media/dvb/frontends/tda10086.c
+++ b/drivers/media/dvb/frontends/tda10086.c
@@ -212,7 +212,7 @@
 	for(i=0; i< cmd->msg_len; i++) {
 		tda10086_write_byte(state, 0x48+i, cmd->msg[i]);
 	}
-	tda10086_write_byte(state, 0x36, 0x08 | ((cmd->msg_len + 1) << 4));
+	tda10086_write_byte(state, 0x36, 0x08 | ((cmd->msg_len - 1) << 4));
 
 	tda10086_diseqc_wait(state);
 
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
index ffda71d..058df5c 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -149,6 +149,15 @@
 	writel(val, &pluto->io_mem[reg]);
 }
 
+static void pluto_write_tscr(struct pluto *pluto, u32 val)
+{
+	/* set the number of packets */
+	val &= ~TSCR_ADEF;
+	val |= TS_DMA_PACKETS / 2;
+
+	pluto_writereg(pluto, REG_TSCR, val);
+}
+
 static void pluto_setsda(void *data, int state)
 {
 	struct pluto *pluto = data;
@@ -213,11 +222,11 @@
 
 	if (val & TSCR_RSTN) {
 		val &= ~TSCR_RSTN;
-		pluto_writereg(pluto, REG_TSCR, val);
+		pluto_write_tscr(pluto, val);
 	}
 	if (reenable) {
 		val |= TSCR_RSTN;
-		pluto_writereg(pluto, REG_TSCR, val);
+		pluto_write_tscr(pluto, val);
 	}
 }
 
@@ -339,7 +348,7 @@
 	}
 
 	/* ACK the interrupt */
-	pluto_writereg(pluto, REG_TSCR, tscr | TSCR_IACK);
+	pluto_write_tscr(pluto, tscr | TSCR_IACK);
 
 	return IRQ_HANDLED;
 }
@@ -348,9 +357,6 @@
 {
 	u32 val = pluto_readreg(pluto, REG_TSCR);
 
-	/* set the number of packets */
-	val &= ~TSCR_ADEF;
-	val |= TS_DMA_PACKETS / 2;
 	/* disable AFUL and LOCK interrupts */
 	val |= (TSCR_MSKA | TSCR_MSKL);
 	/* enable DMA and OVERFLOW interrupts */
@@ -358,7 +364,7 @@
 	/* clear pending interrupts */
 	val |= TSCR_IACK;
 
-	pluto_writereg(pluto, REG_TSCR, val);
+	pluto_write_tscr(pluto, val);
 }
 
 static void pluto_disable_irqs(struct pluto *pluto)
@@ -370,7 +376,7 @@
 	/* clear pending interrupts */
 	val |= TSCR_IACK;
 
-	pluto_writereg(pluto, REG_TSCR, val);
+	pluto_write_tscr(pluto, val);
 }
 
 static int __devinit pluto_hw_init(struct pluto *pluto)
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 920b63f..af66a5d 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -3,7 +3,7 @@
 #
 
 menu "Radio Adapters"
-	depends on VIDEO_DEV!=n
+	depends on VIDEO_DEV
 
 config RADIO_CADET
 	tristate "ADS Cadet AM/FM Tuner"
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index 2fb9fe6..ba1af3c 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -780,18 +780,16 @@
 	return 0;
 }
 
-static int msp_suspend(struct device * dev, pm_message_t state)
+static int msp_suspend(struct i2c_client *client, pm_message_t state)
 {
-	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
 
 	v4l_dbg(1, msp_debug, client, "suspend\n");
 	msp_reset(client);
 	return 0;
 }
 
-static int msp_resume(struct device * dev)
+static int msp_resume(struct i2c_client *client)
 {
-	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
 
 	v4l_dbg(1, msp_debug, client, "resume\n");
 	msp_wake_thread(client);
@@ -825,7 +823,7 @@
 	if (msp_reset(client) == -1) {
 		v4l_dbg(1, msp_debug, client, "msp3400 not found\n");
 		kfree(client);
-		return -1;
+		return 0;
 	}
 
 	state = kmalloc(sizeof(*state), GFP_KERNEL);
@@ -859,7 +857,7 @@
 		v4l_dbg(1, msp_debug, client, "not an msp3400 (cannot read chip version)\n");
 		kfree(state);
 		kfree(client);
-		return -1;
+		return 0;
 	}
 
 	msp_set_audio(client);
@@ -996,11 +994,11 @@
 	.id             = I2C_DRIVERID_MSP3400,
 	.attach_adapter = msp_probe,
 	.detach_client  = msp_detach,
+	.suspend = msp_suspend,
+	.resume  = msp_resume,
 	.command        = msp_command,
 	.driver = {
 		.name    = "msp3400",
-		.suspend = msp_suspend,
-		.resume  = msp_resume,
 	},
 };
 
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 1ff5138e..9916cf3 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -1248,10 +1248,10 @@
 	ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/
 	LOCK_TAKE(hdw->ctl_lock); do {
 		hdw->cmd_buffer[0] = FX2CMD_FWPOST1;
-		ret |= pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0);
+		ret |= pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
 		hdw->cmd_buffer[0] = FX2CMD_MEMSEL;
 		hdw->cmd_buffer[1] = 0;
-		ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,0,0);
+		ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,NULL,0);
 	} while (0); LOCK_GIVE(hdw->ctl_lock);
 
 	if (ret) {
@@ -1320,7 +1320,7 @@
 	LOCK_TAKE(hdw->ctl_lock); do {
 		hdw->cmd_buffer[0] = FX2CMD_MEMSEL;
 		hdw->cmd_buffer[1] = 0;
-		ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,0,0);
+		ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,NULL,0);
 	} while (0); LOCK_GIVE(hdw->ctl_lock);
 
 	if (ret) {
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 5313d34..25d3830 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -808,11 +808,11 @@
 {
 	if (vp->dev_video) {
 		pvr2_v4l2_dev_destroy(vp->dev_video);
-		vp->dev_video = 0;
+		vp->dev_video = NULL;
 	}
 	if (vp->dev_radio) {
 		pvr2_v4l2_dev_destroy(vp->dev_radio);
-		vp->dev_radio = 0;
+		vp->dev_radio = NULL;
 	}
 
 	pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp);
@@ -1138,7 +1138,7 @@
 {
 	int mindevnum;
 	int unit_number;
-	int *nr_ptr = 0;
+	int *nr_ptr = NULL;
 	dip->v4lp = vp;
 
 
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 7735b67..4d5bbd85 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -961,7 +961,7 @@
 			reg |= 0x10;
 		} else if (std == V4L2_STD_NTSC_M_JP) {
 			reg |= 0x40;
-		} else if (std == V4L2_STD_SECAM) {
+		} else if (std & V4L2_STD_SECAM) {
 			reg |= 0x50;
 		}
 		saa711x_write(client, R_0E_CHROMA_CNTL_1, reg);
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 7be73e3..15dbc6b 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -804,9 +804,8 @@
 	return 0;
 }
 
-static int tuner_suspend(struct device *dev, pm_message_t state)
+static int tuner_suspend(struct i2c_client *c, pm_message_t state)
 {
-	struct i2c_client *c = container_of (dev, struct i2c_client, dev);
 	struct tuner *t = i2c_get_clientdata (c);
 
 	tuner_dbg ("suspend\n");
@@ -814,9 +813,8 @@
 	return 0;
 }
 
-static int tuner_resume(struct device *dev)
+static int tuner_resume(struct i2c_client *c)
 {
-	struct i2c_client *c = container_of (dev, struct i2c_client, dev);
 	struct tuner *t = i2c_get_clientdata (c);
 
 	tuner_dbg ("resume\n");
@@ -837,10 +835,10 @@
 	.attach_adapter = tuner_probe,
 	.detach_client = tuner_detach,
 	.command = tuner_command,
+	.suspend = tuner_suspend,
+	.resume  = tuner_resume,
 	.driver = {
 		.name    = "tuner",
-		.suspend = tuner_suspend,
-		.resume  = tuner_resume,
 	},
 };
 static struct i2c_client client_template = {
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 404c014..1d2d03f 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -815,7 +815,7 @@
 static int
 mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
 {
-	MPT_SCSI_HOST	*hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
+	MPT_SCSI_HOST	*hd;
 	struct mptsas_target_reset_event *target_reset_list, *n;
 	int rc;
 
@@ -827,7 +827,10 @@
 	if (reset_phase != MPT_IOC_POST_RESET)
 		goto out;
 
-	if (!hd || !hd->ioc)
+	if (!ioc->sh || !ioc->sh->hostdata)
+		goto out;
+	hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
+	if (!hd->ioc)
 		goto out;
 
 	if (list_empty(&hd->target_reset_list))
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index da9859f..b17c4b2 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -390,13 +390,6 @@
 		return BLKPREP_KILL;
 	}
 
-	/* request is already processed by us, so return */
-	if (blk_special_request(req)) {
-		osm_debug("REQ_SPECIAL already set!\n");
-		req->cmd_flags |= REQ_DONTPREP;
-		return BLKPREP_OK;
-	}
-
 	/* connect the i2o_block_request to the request */
 	if (!req->special) {
 		ireq = i2o_block_request_alloc();
@@ -408,11 +401,8 @@
 		ireq->i2o_blk_dev = i2o_blk_dev;
 		req->special = ireq;
 		ireq->req = req;
-	} else
-		ireq = req->special;
-
+	}
 	/* do not come back here */
-	req->cmd_type = REQ_TYPE_SPECIAL;
 	req->cmd_flags |= REQ_DONTPREP;
 
 	return BLKPREP_OK;
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index c707c8e..b0b4458 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -319,7 +319,7 @@
 
 	mode &= 3;		/* get current power mode */
 
-	if (unit > ARRAY_SIZE(sm->unit_power)) {
+	if (unit >= ARRAY_SIZE(sm->unit_power)) {
 		dev_err(dev, "%s: bad unit %d\n", __FUNCTION__, unit);
 		goto already;
 	}
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c
index 295e931..4b23212 100644
--- a/drivers/misc/asus-laptop.c
+++ b/drivers/misc/asus-laptop.c
@@ -211,7 +211,7 @@
 				     enum led_brightness value);	\
 	static void object##_led_update(struct work_struct *ignored);	\
 	static int object##_led_wk;					\
-	DECLARE_WORK(object##_led_work, object##_led_update);		\
+	static DECLARE_WORK(object##_led_work, object##_led_update);	\
 	static struct led_classdev object##_led = {			\
 		.name           = "asus:" ledname,			\
 		.brightness_set = object##_led_set,			\
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
index 2ebe240..ac708bc 100644
--- a/drivers/misc/sony-laptop.c
+++ b/drivers/misc/sony-laptop.c
@@ -453,7 +453,7 @@
 static int sony_acpi_add(struct acpi_device *device)
 {
 	acpi_status status;
-	int result;
+	int result = 0;
 	acpi_handle handle;
 
 	sony_acpi_acpi_device = device;
diff --git a/drivers/mmc/imxmmc.c b/drivers/mmc/imxmmc.c
index b060d4b..0de5c9e 100644
--- a/drivers/mmc/imxmmc.c
+++ b/drivers/mmc/imxmmc.c
@@ -569,10 +569,12 @@
 
 	if(host->dma_dir == DMA_FROM_DEVICE) {
 		imxmci_busy_wait_for_status(host, &stat,
-				STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE,
+				STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE |
+				STATUS_TIME_OUT_READ,
 				50, "imxmci_cpu_driven_data read");
 
 		while((stat & (STATUS_APPL_BUFF_FF |  STATUS_DATA_TRANS_DONE)) &&
+		      !(stat & STATUS_TIME_OUT_READ) &&
 		      (host->data_cnt < 512)) {
 
 			udelay(20);	/* required for clocks < 8MHz*/
@@ -602,6 +604,12 @@
 		if(host->dma_size & 0x1ff)
 			stat &= ~STATUS_CRC_READ_ERR;
 
+		if(stat & STATUS_TIME_OUT_READ) {
+			dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data read timeout STATUS = 0x%x\n",
+				stat);
+			trans_done = -1;
+		}
+
 	} else {
 		imxmci_busy_wait_for_status(host, &stat,
 				STATUS_APPL_BUFF_FE,
@@ -709,6 +717,9 @@
 		 */
 		stat |= host->status_reg;
 
+		if(test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events))
+			stat &= ~STATUS_CRC_READ_ERR;
+
 		if(test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) {
 			imxmci_busy_wait_for_status(host, &stat,
 					STATUS_END_CMD_RESP | STATUS_ERR_MASK,
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index e3acd39..1f64458 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -359,6 +359,8 @@
 		cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
 		cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
 		cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
+		cfi->chips[i].ref_point_counter = 0;
+		init_waitqueue_head(&(cfi->chips[i].wq));
 	}
 
 	map->fldrv = &cfi_amdstd_chipdrv;
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
index 69d49e0..b344ff8 100644
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -158,6 +158,8 @@
 		cfi->chips[i].word_write_time = 128;
 		cfi->chips[i].buffer_write_time = 128;
 		cfi->chips[i].erase_time = 1024;
+		cfi->chips[i].ref_point_counter = 0;
+		init_waitqueue_head(&(cfi->chips[i].wq));
 	}
 
 	return cfi_staa_setup(map);
diff --git a/drivers/mtd/maps/dilnetpc.c b/drivers/mtd/maps/dilnetpc.c
index b1104fe..1c3b34a 100644
--- a/drivers/mtd/maps/dilnetpc.c
+++ b/drivers/mtd/maps/dilnetpc.c
@@ -402,8 +402,8 @@
 			++higlvl_partition_info[i].name;
 	}
 
-	printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%lx\n",
-		is_dnp ? "DNPC" : "ADNP", dnpc_map.size, dnpc_map.phys);
+	printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%llx\n",
+		is_dnp ? "DNPC" : "ADNP", dnpc_map.size, (unsigned long long)dnpc_map.phys);
 
 	dnpc_map.virt = ioremap_nocache(dnpc_map.phys, dnpc_map.size);
 
diff --git a/drivers/mtd/maps/esb2rom.c b/drivers/mtd/maps/esb2rom.c
index 0bc013f..aa64a47 100644
--- a/drivers/mtd/maps/esb2rom.c
+++ b/drivers/mtd/maps/esb2rom.c
@@ -30,7 +30,7 @@
 
 #define ROM_PROBE_STEP_SIZE (64*1024) /* 64KiB */
 
-#define BIOS_CNTL	0xDC
+#define BIOS_CNTL		0xDC
 #define BIOS_LOCK_ENABLE	0x02
 #define BIOS_WRITE_ENABLE	0x01
 
@@ -145,7 +145,7 @@
 }
 
 static int __devinit esb2rom_init_one(struct pci_dev *pdev,
-				const struct pci_device_id *ent)
+				      const struct pci_device_id *ent)
 {
 	static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
 	struct esb2rom_window *window = &esb2rom_window;
@@ -185,7 +185,7 @@
 	/* Find a region continuous to the end of the ROM window  */
 	window->phys = 0;
 	pci_read_config_word(pdev, FWH_DEC_EN1, &word);
-	printk(KERN_DEBUG "pci_read_config_byte : %x\n", word);
+	printk(KERN_DEBUG "pci_read_config_word : %x\n", word);
 
 	if ((word & FWH_8MiB) == FWH_8MiB)
 		window->phys = 0xff400000;
@@ -212,6 +212,11 @@
 	else if ((word & FWH_0_5MiB) == FWH_0_5MiB)
 		window->phys = 0xfff80000;
 
+	if (window->phys == 0) {
+		printk(KERN_ERR MOD_NAME ": Rom window is closed\n");
+		goto out;
+	}
+
 	/* reserved  0x0020 and 0x0010 */
 	window->phys -= 0x400000UL;
 	window->size = (0xffffffffUL - window->phys) + 1UL;
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 880580c..41844ea 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -727,6 +727,7 @@
 	concat->mtd.erasesize = subdev[0]->erasesize;
 	concat->mtd.writesize = subdev[0]->writesize;
 	concat->mtd.oobsize = subdev[0]->oobsize;
+	concat->mtd.oobavail = subdev[0]->oobavail;
 	if (subdev[0]->writev)
 		concat->mtd.writev = concat_writev;
 	if (subdev[0]->read_oob)
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 633def3..1af9890 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -200,6 +200,11 @@
 		return -EINVAL;
 	instr->addr += part->offset;
 	ret = part->master->erase(part->master, instr);
+	if (ret) {
+		if (instr->fail_addr != 0xffffffff)
+			instr->fail_addr -= part->offset;
+		instr->addr -= part->offset;
+	}
 	return ret;
 }
 
@@ -338,6 +343,7 @@
 		slave->mtd.size = parts[i].size;
 		slave->mtd.writesize = master->writesize;
 		slave->mtd.oobsize = master->oobsize;
+		slave->mtd.oobavail = master->oobavail;
 		slave->mtd.subpage_sft = master->subpage_sft;
 
 		slave->mtd.name = parts[i].name;
@@ -559,4 +565,3 @@
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
 MODULE_DESCRIPTION("Generic support for partitioning of MTD devices");
-
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index 12608c1..595208f 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -114,7 +114,7 @@
 static int show_firmware_partition = 0;
 module_param(show_firmware_partition, int, 0);
 
-#ifdef MTD_NAND_DISKONCHIP_BBTWRITE
+#ifdef CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE
 static int inftl_bbt_write = 1;
 #else
 static int inftl_bbt_write = 0;
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index acaf97b..6af37b8 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2524,6 +2524,7 @@
 	for (i = 0; chip->ecc.layout->oobfree[i].length; i++)
 		chip->ecc.layout->oobavail +=
 			chip->ecc.layout->oobfree[i].length;
+	mtd->oobavail = chip->ecc.layout->oobavail;
 
 	/*
 	 * Set the number of read / write steps for one page depending on ECC
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 7f1cb6e..9e14a26 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -4,6 +4,11 @@
  *  Copyright (C) 2005-2007 Samsung Electronics
  *  Kyungmin Park <kyungmin.park@samsung.com>
  *
+ *  Credits:
+ *	Adrian Hunter <ext-adrian.hunter@nokia.com>:
+ *	auto-placement support, read-while load support, various fixes
+ *	Copyright (C) Nokia Corporation, 2007
+ *
  * 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.
@@ -831,7 +836,7 @@
 	int readcol = column;
 	int readend = column + thislen;
 	int lastgap = 0;
-	uint8_t *oob_buf = this->page_buf + mtd->writesize;
+	uint8_t *oob_buf = this->oob_buf;
 
 	for (free = this->ecclayout->oobfree; free->length; ++free) {
 		if (readcol >= lastgap)
@@ -849,7 +854,8 @@
 			int n = ed - st;
 			memcpy(buf, oob_buf + st, n);
 			buf += n;
-		}
+		} else
+			break;
 	}
 	return 0;
 }
@@ -947,9 +953,9 @@
 
 /**
  * onenand_read_oob - [MTD Interface] NAND write data and/or out-of-band
- * @mtd:	MTD device structure
- * @from:	offset to read from
- * @ops:	oob operation description structure
+ * @param mtd:		MTD device structure
+ * @param from:		offset to read from
+ * @param ops:		oob operation description structure
  */
 static int onenand_read_oob(struct mtd_info *mtd, loff_t from,
 			    struct mtd_oob_ops *ops)
@@ -1017,7 +1023,7 @@
  * onenand_bbt_read_oob - [MTD Interface] OneNAND read out-of-band for bbt scan
  * @param mtd		MTD device structure
  * @param from		offset to read from
- * @param @ops		oob operation description structure
+ * @param ops		oob operation description structure
  *
  * OneNAND read out-of-band data from the spare area for bbt scan
  */
@@ -1093,7 +1099,7 @@
 static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to)
 {
 	struct onenand_chip *this = mtd->priv;
-	char *readp = this->page_buf + mtd->writesize;
+	char oobbuf[64];
 	int status, i;
 
 	this->command(mtd, ONENAND_CMD_READOOB, to, mtd->oobsize);
@@ -1102,9 +1108,9 @@
 	if (status)
 		return status;
 
-	this->read_bufferram(mtd, ONENAND_SPARERAM, readp, 0, mtd->oobsize);
-	for(i = 0; i < mtd->oobsize; i++)
-		if (buf[i] != 0xFF && buf[i] != readp[i])
+	this->read_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
+	for (i = 0; i < mtd->oobsize; i++)
+		if (buf[i] != 0xFF && buf[i] != oobbuf[i])
 			return -EBADMSG;
 
 	return 0;
@@ -1290,7 +1296,8 @@
 			int n = ed - st;
 			memcpy(oob_buf + st, buf, n);
 			buf += n;
-		}
+		} else
+			break;
 	}
 	return 0;
 }
@@ -1312,6 +1319,7 @@
 	struct onenand_chip *this = mtd->priv;
 	int column, ret = 0, oobsize;
 	int written = 0;
+	u_char *oobbuf;
 
 	DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
 
@@ -1331,7 +1339,7 @@
 	}
 
 	/* For compatibility with NAND: Do not allow write past end of page */
-	if (column + len > oobsize) {
+	if (unlikely(column + len > oobsize)) {
 		printk(KERN_ERR "onenand_write_oob: "
 		      "Attempt to write past end of page\n");
 		return -EINVAL;
@@ -1348,6 +1356,8 @@
 	/* Grab the lock and see if the device is available */
 	onenand_get_device(mtd, FL_WRITING);
 
+	oobbuf = this->oob_buf;
+
 	/* Loop until all data write */
 	while (written < len) {
 		int thislen = min_t(int, oobsize, len - written);
@@ -1358,12 +1368,12 @@
 
 		/* We send data to spare ram with oobsize
 		 * to prevent byte access */
-		memset(this->page_buf, 0xff, mtd->oobsize);
+		memset(oobbuf, 0xff, mtd->oobsize);
 		if (mode == MTD_OOB_AUTO)
-			onenand_fill_auto_oob(mtd, this->page_buf, buf, column, thislen);
+			onenand_fill_auto_oob(mtd, oobbuf, buf, column, thislen);
 		else
-			memcpy(this->page_buf + column, buf, thislen);
-		this->write_bufferram(mtd, ONENAND_SPARERAM, this->page_buf, 0, mtd->oobsize);
+			memcpy(oobbuf + column, buf, thislen);
+		this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
 
 		this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
 
@@ -1375,7 +1385,7 @@
 			break;
 		}
 
-		ret = onenand_verify_oob(mtd, this->page_buf, to);
+		ret = onenand_verify_oob(mtd, oobbuf, to);
 		if (ret) {
 			printk(KERN_ERR "onenand_write_oob: verify failed %d\n", ret);
 			break;
@@ -1400,9 +1410,9 @@
 
 /**
  * onenand_write_oob - [MTD Interface] NAND write data and/or out-of-band
- * @mtd:	MTD device structure
- * @from:	offset to read from
- * @ops:	oob operation description structure
+ * @param mtd:		MTD device structure
+ * @param to:		offset to write
+ * @param ops:		oob operation description structure
  */
 static int onenand_write_oob(struct mtd_info *mtd, loff_t to,
 			     struct mtd_oob_ops *ops)
@@ -1616,6 +1626,7 @@
  * @param mtd		MTD device structure
  * @param ofs		offset relative to mtd start
  * @param len		number of bytes to lock or unlock
+ * @param cmd		lock or unlock command
  *
  * Lock or unlock one or more blocks
  */
@@ -2117,10 +2128,11 @@
 }
 
 /**
- * onenand_print_device_info - Print device ID
+ * onenand_print_device_info - Print device & version ID
  * @param device        device ID
+ * @param version	version ID
  *
- * Print device ID
+ * Print device & version ID
  */
 static void onenand_print_device_info(int device, int version)
 {
@@ -2320,15 +2332,25 @@
 
 	/* Allocate buffers, if necessary */
 	if (!this->page_buf) {
-		size_t len;
-		len = mtd->writesize + mtd->oobsize;
-		this->page_buf = kmalloc(len, GFP_KERNEL);
+		this->page_buf = kzalloc(mtd->writesize, GFP_KERNEL);
 		if (!this->page_buf) {
 			printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n");
 			return -ENOMEM;
 		}
 		this->options |= ONENAND_PAGEBUF_ALLOC;
 	}
+	if (!this->oob_buf) {
+		this->oob_buf = kzalloc(mtd->oobsize, GFP_KERNEL);
+		if (!this->oob_buf) {
+			printk(KERN_ERR "onenand_scan(): Can't allocate oob_buf\n");
+			if (this->options & ONENAND_PAGEBUF_ALLOC) {
+				this->options &= ~ONENAND_PAGEBUF_ALLOC;
+				kfree(this->page_buf);
+			}
+			return -ENOMEM;
+		}
+		this->options |= ONENAND_OOBBUF_ALLOC;
+	}
 
 	this->state = FL_READY;
 	init_waitqueue_head(&this->wq);
@@ -2367,6 +2389,7 @@
 	for (i = 0; this->ecclayout->oobfree[i].length; i++)
 		this->ecclayout->oobavail +=
 			this->ecclayout->oobfree[i].length;
+	mtd->oobavail = this->ecclayout->oobavail;
 
 	mtd->ecclayout = this->ecclayout;
 
@@ -2424,9 +2447,11 @@
 		kfree(bbm->bbt);
 		kfree(this->bbm);
 	}
-	/* Buffer allocated by onenand_scan */
+	/* Buffers allocated by onenand_scan */
 	if (this->options & ONENAND_PAGEBUF_ALLOC)
 		kfree(this->page_buf);
+	if (this->options & ONENAND_OOBBUF_ALLOC)
+		kfree(this->oob_buf);
 }
 
 EXPORT_SYMBOL_GPL(onenand_scan);
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 7299577..b406ecf 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -858,19 +858,7 @@
 };
 MODULE_DEVICE_TABLE(eisa, vortex_eisa_ids);
 
-static int vortex_eisa_probe(struct device *device);
-static int vortex_eisa_remove(struct device *device);
-
-static struct eisa_driver vortex_eisa_driver = {
-	.id_table = vortex_eisa_ids,
-	.driver   = {
-		.name    = "3c59x",
-		.probe   = vortex_eisa_probe,
-		.remove  = vortex_eisa_remove
-	}
-};
-
-static int vortex_eisa_probe(struct device *device)
+static int __init vortex_eisa_probe(struct device *device)
 {
 	void __iomem *ioaddr;
 	struct eisa_device *edev;
@@ -893,7 +881,7 @@
 	return 0;
 }
 
-static int vortex_eisa_remove(struct device *device)
+static int __devexit vortex_eisa_remove(struct device *device)
 {
 	struct eisa_device *edev;
 	struct net_device *dev;
@@ -918,7 +906,17 @@
 	free_netdev(dev);
 	return 0;
 }
-#endif
+
+static struct eisa_driver vortex_eisa_driver = {
+	.id_table = vortex_eisa_ids,
+	.driver   = {
+		.name    = "3c59x",
+		.probe   = vortex_eisa_probe,
+		.remove  = __devexit_p(vortex_eisa_remove)
+	}
+};
+
+#endif /* CONFIG_EISA */
 
 /* returns count found (>= 0), or negative on error */
 static int __init vortex_eisa_init(void)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index dae0aa4..753695b 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2373,22 +2373,23 @@
 	  when the driver is receiving lots of packets from the card.
 
 config CHELSIO_T3
-        tristate "Chelsio Communications T3 10Gb Ethernet support"
-        depends on PCI
-        help
-          This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
-          adapters.
+	tristate "Chelsio Communications T3 10Gb Ethernet support"
+	depends on PCI
+	select FW_LOADER
+	help
+	  This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
+	  adapters.
 
-          For general information about Chelsio and our products, visit
-          our website at <http://www.chelsio.com>.
+	  For general information about Chelsio and our products, visit
+	  our website at <http://www.chelsio.com>.
 
-          For customer support, please visit our customer support page at
-          <http://www.chelsio.com/support.htm>.
+	  For customer support, please visit our customer support page at
+	  <http://www.chelsio.com/support.htm>.
 
-          Please send feedback to <linux-bugs@chelsio.com>.
+	  Please send feedback to <linux-bugs@chelsio.com>.
 
-          To compile this driver as a module, choose M here: the module
-          will be called cxgb3.
+	  To compile this driver as a module, choose M here: the module
+	  will be called cxgb3.
 
 config EHEA
 	tristate "eHEA Ethernet support"
diff --git a/drivers/net/atl1/atl1_hw.c b/drivers/net/atl1/atl1_hw.c
index 314dbaa..69482e0 100644
--- a/drivers/net/atl1/atl1_hw.c
+++ b/drivers/net/atl1/atl1_hw.c
@@ -334,7 +334,6 @@
 	int i;
 
 	crc32 = ether_crc_le(6, mc_addr);
-	crc32 = ~crc32;
 	for (i = 0; i < 32; i++)
 		value |= (((crc32 >> i) & 1) << (31 - i));
 
diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c
index 88d4f70..8606eac 100644
--- a/drivers/net/atl1/atl1_main.c
+++ b/drivers/net/atl1/atl1_main.c
@@ -1328,7 +1328,7 @@
 
 	if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
 		cso = skb->h.raw - skb->data;
-		css = (skb->h.raw + skb->csum) - skb->data;
+		css = (skb->h.raw + skb->csum_offset) - skb->data;
 		if (unlikely(cso & 0x1)) {
 			printk(KERN_DEBUG "%s: payload offset != even number\n",
 				atl1_driver_name);
@@ -1562,7 +1562,7 @@
 	/* mss will be nonzero if we're doing segment offload (TSO/GSO) */
 	mss = skb_shinfo(skb)->gso_size;
 	if (mss) {
-		if (skb->protocol == ntohs(ETH_P_IP)) {
+		if (skb->protocol == htons(ETH_P_IP)) {
 			proto_hdr_len = ((skb->h.raw - skb->data) +
 					 (skb->h.th->doff << 2));
 			if (unlikely(proto_hdr_len > len)) {
@@ -2320,6 +2320,16 @@
 		return;
 
 	adapter = netdev_priv(netdev);
+
+	/* Some atl1 boards lack persistent storage for their MAC, and get it
+	 * from the BIOS during POST.  If we've been messing with the MAC
+	 * address, we need to save the permanent one.
+	 */
+	if (memcmp(adapter->hw.mac_addr, adapter->hw.perm_mac_addr, ETH_ALEN)) {
+		memcpy(adapter->hw.mac_addr, adapter->hw.perm_mac_addr, ETH_ALEN);
+		atl1_set_mac_addr(&adapter->hw);
+	}
+
 	iowrite16(0, adapter->hw.hw_addr + REG_GPHY_ENABLE);
 	unregister_netdev(netdev);
 	pci_iounmap(pdev, adapter->hw.hw_addr);
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index aaada57..d742bfe 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1709,7 +1709,7 @@
 		bw32(bp, B44_RXCONFIG, val);
 	} else {
 		unsigned char zero[6] = {0, 0, 0, 0, 0, 0};
-		int i = 0;
+		int i = 1;
 
 		__b44_set_mac_addr(bp);
 
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index c12e5ea..0b7aded 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -54,8 +54,8 @@
 
 #define DRV_MODULE_NAME		"bnx2"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"1.5.5"
-#define DRV_MODULE_RELDATE	"February 1, 2007"
+#define DRV_MODULE_VERSION	"1.5.7"
+#define DRV_MODULE_RELDATE	"March 29, 2007"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -2033,8 +2033,8 @@
 	    (sblk->status_tx_quick_consumer_index0 != bp->hw_tx_cons))
 		return 1;
 
-	if (((sblk->status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) != 0) !=
-	    bp->link_up)
+	if ((sblk->status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) !=
+	    (sblk->status_attn_bits_ack & STATUS_ATTN_BITS_LINK_STATE))
 		return 1;
 
 	return 0;
@@ -3099,20 +3099,18 @@
 
 	if ((align_start = (offset32 & 3))) {
 		offset32 &= ~3;
-		len32 += (4 - align_start);
+		len32 += align_start;
+		if (len32 < 4)
+			len32 = 4;
 		if ((rc = bnx2_nvram_read(bp, offset32, start, 4)))
 			return rc;
 	}
 
 	if (len32 & 3) {
-	       	if ((len32 > 4) || !align_start) {
-			align_end = 4 - (len32 & 3);
-			len32 += align_end;
-			if ((rc = bnx2_nvram_read(bp, offset32 + len32 - 4,
-				end, 4))) {
-				return rc;
-			}
-		}
+		align_end = 4 - (len32 & 3);
+		len32 += align_end;
+		if ((rc = bnx2_nvram_read(bp, offset32 + len32 - 4, end, 4)))
+			return rc;
 	}
 
 	if (align_start || align_end) {
@@ -3187,17 +3185,17 @@
 		if ((rc = bnx2_enable_nvram_write(bp)) != 0)
 			goto nvram_write_end;
 
-		/* Erase the page */
-		if ((rc = bnx2_nvram_erase_page(bp, page_start)) != 0)
-			goto nvram_write_end;
-
-		/* Re-enable the write again for the actual write */
-		bnx2_enable_nvram_write(bp);
-
 		/* Loop to write back the buffer data from page_start to
 		 * data_start */
 		i = 0;
 		if (bp->flash_info->buffered == 0) {
+			/* Erase the page */
+			if ((rc = bnx2_nvram_erase_page(bp, page_start)) != 0)
+				goto nvram_write_end;
+
+			/* Re-enable the write again for the actual write */
+			bnx2_enable_nvram_write(bp);
+
 			for (addr = page_start; addr < data_start;
 				addr += 4, i += 4) {
 
diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h
index e23deeb..8d13796 100644
--- a/drivers/net/cxgb3/common.h
+++ b/drivers/net/cxgb3/common.h
@@ -112,8 +112,7 @@
 };
 
 enum {
-	SUPPORTED_OFFLOAD = 1 << 24,
-	SUPPORTED_IRQ = 1 << 25
+	SUPPORTED_IRQ      = 1 << 24
 };
 
 enum {				/* adapter interrupt-maintained statistics */
@@ -260,6 +259,10 @@
 	unsigned long serdes_signal_loss;
 	unsigned long xaui_pcs_ctc_err;
 	unsigned long xaui_pcs_align_change;
+
+	unsigned long num_toggled; /* # times toggled TxEn due to stuck TX */
+	unsigned long num_resets;  /* # times reset due to stuck TX */
+
 };
 
 struct tp_mib_stats {
@@ -354,6 +357,9 @@
 	MC5_MODE_72_BIT = 2
 };
 
+/* MC5 min active region size */
+enum { MC5_MIN_TIDS = 16 };
+
 struct vpd_params {
 	unsigned int cclk;
 	unsigned int mclk;
@@ -398,6 +404,13 @@
 	unsigned int stats_update_period;	/* MAC stats accumulation period */
 	unsigned int linkpoll_period;	/* link poll period in 0.1s */
 	unsigned int rev;	/* chip revision */
+	unsigned int offload;
+};
+
+enum {					    /* chip revisions */
+	T3_REV_A  = 0,
+	T3_REV_B  = 2,
+	T3_REV_B2 = 3,
 };
 
 struct trace_params {
@@ -465,6 +478,13 @@
 	struct adapter *adapter;
 	unsigned int offset;
 	unsigned int nucast;	/* # of address filters for unicast MACs */
+	unsigned int tx_tcnt;
+	unsigned int tx_xcnt;
+	u64 tx_mcnt;
+	unsigned int rx_xcnt;
+	u64 rx_mcnt;
+	unsigned int toggle_cnt;
+	unsigned int txen;
 	struct mac_stats stats;
 };
 
@@ -588,7 +608,7 @@
 
 static inline int is_offload(const struct adapter *adap)
 {
-	return adapter_info(adap)->caps & SUPPORTED_OFFLOAD;
+	return adap->params.offload;
 }
 
 static inline unsigned int core_ticks_per_usec(const struct adapter *adap)
@@ -666,6 +686,7 @@
 int t3_mac_set_num_ucast(struct cmac *mac, int n);
 const struct mac_stats *t3_mac_update_stats(struct cmac *mac);
 int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc);
+int t3b2_mac_watchdog_task(struct cmac *mac);
 
 void t3_mc5_prep(struct adapter *adapter, struct mc5 *mc5, int mode);
 int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters,
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 7ff834e..67b4b21 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -42,6 +42,7 @@
 #include <linux/workqueue.h>
 #include <linux/proc_fs.h>
 #include <linux/rtnetlink.h>
+#include <linux/firmware.h>
 #include <asm/uaccess.h>
 
 #include "common.h"
@@ -184,16 +185,24 @@
 			int speed, int duplex, int pause)
 {
 	struct net_device *dev = adapter->port[port_id];
+	struct port_info *pi = netdev_priv(dev);
+	struct cmac *mac = &pi->mac;
 
 	/* Skip changes from disabled ports. */
 	if (!netif_running(dev))
 		return;
 
 	if (link_stat != netif_carrier_ok(dev)) {
-		if (link_stat)
+		if (link_stat) {
+			t3_mac_enable(mac, MAC_DIRECTION_RX);
 			netif_carrier_on(dev);
-		else
+		} else {
 			netif_carrier_off(dev);
+			pi->phy.ops->power_down(&pi->phy, 1);
+			t3_mac_disable(mac, MAC_DIRECTION_RX);
+			t3_link_start(&pi->phy, mac, &pi->link_config);
+		}
+
 		link_report(dev);
 	}
 }
@@ -406,7 +415,7 @@
 static int setup_sge_qsets(struct adapter *adap)
 {
 	int i, j, err, irq_idx = 0, qset_idx = 0, dummy_dev_idx = 0;
-	unsigned int ntxq = is_offload(adap) ? SGE_TXQ_PER_SET : 1;
+	unsigned int ntxq = SGE_TXQ_PER_SET;
 
 	if (adap->params.rev > 0 && !(adap->flags & USING_MSI))
 		irq_idx = -1;
@@ -484,12 +493,14 @@
 static ssize_t set_nfilters(struct net_device *dev, unsigned int val)
 {
 	struct adapter *adap = dev->priv;
+	int min_tids = is_offload(adap) ? MC5_MIN_TIDS : 0;
 
 	if (adap->flags & FULL_INIT_DONE)
 		return -EBUSY;
 	if (val && adap->params.rev == 0)
 		return -EINVAL;
-	if (val > t3_mc5_size(&adap->mc5) - adap->params.mc5.nservers)
+	if (val > t3_mc5_size(&adap->mc5) - adap->params.mc5.nservers -
+	    min_tids)
 		return -EINVAL;
 	adap->params.mc5.nfilters = val;
 	return 0;
@@ -507,7 +518,8 @@
 
 	if (adap->flags & FULL_INIT_DONE)
 		return -EBUSY;
-	if (val > t3_mc5_size(&adap->mc5) - adap->params.mc5.nfilters)
+	if (val > t3_mc5_size(&adap->mc5) - adap->params.mc5.nfilters -
+	    MC5_MIN_TIDS)
 		return -EINVAL;
 	adap->params.mc5.nservers = val;
 	return 0;
@@ -707,6 +719,28 @@
 	}
 }
 
+#define FW_FNAME "t3fw-%d.%d.%d.bin"
+
+static int upgrade_fw(struct adapter *adap)
+{
+	int ret;
+	char buf[64];
+	const struct firmware *fw;
+	struct device *dev = &adap->pdev->dev;
+
+	snprintf(buf, sizeof(buf), FW_FNAME, FW_VERSION_MAJOR,
+		 FW_VERSION_MINOR, FW_VERSION_MICRO);
+	ret = request_firmware(&fw, buf, dev);
+	if (ret < 0) {
+		dev_err(dev, "could not upgrade firmware: unable to load %s\n",
+			buf);
+		return ret;
+	}
+	ret = t3_load_fw(adap, fw->data, fw->size);
+	release_firmware(fw);
+	return ret;
+}
+
 /**
  *	cxgb_up - enable the adapter
  *	@adapter: adapter being enabled
@@ -723,6 +757,8 @@
 
 	if (!(adap->flags & FULL_INIT_DONE)) {
 		err = t3_check_fw_version(adap);
+		if (err == -EINVAL)
+			err = upgrade_fw(adap);
 		if (err)
 			goto out;
 
@@ -734,6 +770,8 @@
 		if (err)
 			goto out;
 
+		t3_write_reg(adap, A_ULPRX_TDDP_PSZ, V_HPZ0(PAGE_SHIFT - 12));
+		
 		err = setup_sge_qsets(adap);
 		if (err)
 			goto out;
@@ -894,7 +932,7 @@
 		return err;
 
 	set_bit(pi->port_id, &adapter->open_device_map);
-	if (!ofld_disable) {
+	if (is_offload(adapter) && !ofld_disable) {
 		err = offload_open(dev);
 		if (err)
 			printk(KERN_WARNING
@@ -1031,7 +1069,11 @@
 	"VLANinsertions     ",
 	"TxCsumOffload      ",
 	"RxCsumGood         ",
-	"RxDrops            "
+	"RxDrops            ",
+
+	"CheckTXEnToggled   ",
+	"CheckResets        ",
+
 };
 
 static int get_stats_count(struct net_device *dev)
@@ -1145,6 +1187,9 @@
 	*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_TX_CSUM);
 	*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_RX_CSUM_GOOD);
 	*data++ = s->rx_cong_drops;
+
+	*data++ = s->num_toggled;
+	*data++ = s->num_resets;
 }
 
 static inline void reg_block_dump(struct adapter *ap, void *buf,
@@ -1362,23 +1407,27 @@
 
 static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
 {
-	struct adapter *adapter = dev->priv;
+	const struct adapter *adapter = dev->priv;
+	const struct port_info *pi = netdev_priv(dev);
+	const struct qset_params *q = &adapter->params.sge.qset[pi->first_qset];
 
 	e->rx_max_pending = MAX_RX_BUFFERS;
 	e->rx_mini_max_pending = 0;
 	e->rx_jumbo_max_pending = MAX_RX_JUMBO_BUFFERS;
 	e->tx_max_pending = MAX_TXQ_ENTRIES;
 
-	e->rx_pending = adapter->params.sge.qset[0].fl_size;
-	e->rx_mini_pending = adapter->params.sge.qset[0].rspq_size;
-	e->rx_jumbo_pending = adapter->params.sge.qset[0].jumbo_size;
-	e->tx_pending = adapter->params.sge.qset[0].txq_size[0];
+	e->rx_pending = q->fl_size;
+	e->rx_mini_pending = q->rspq_size;
+	e->rx_jumbo_pending = q->jumbo_size;
+	e->tx_pending = q->txq_size[0];
 }
 
 static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
 {
 	int i;
+	struct qset_params *q;
 	struct adapter *adapter = dev->priv;
+	const struct port_info *pi = netdev_priv(dev);
 
 	if (e->rx_pending > MAX_RX_BUFFERS ||
 	    e->rx_jumbo_pending > MAX_RX_JUMBO_BUFFERS ||
@@ -1393,9 +1442,8 @@
 	if (adapter->flags & FULL_INIT_DONE)
 		return -EBUSY;
 
-	for (i = 0; i < SGE_QSETS; ++i) {
-		struct qset_params *q = &adapter->params.sge.qset[i];
-
+	q = &adapter->params.sge.qset[pi->first_qset];
+	for (i = 0; i < pi->nqsets; ++i, ++q) {
 		q->rspq_size = e->rx_mini_pending;
 		q->fl_size = e->rx_pending;
 		q->jumbo_size = e->rx_jumbo_pending;
@@ -2067,6 +2115,42 @@
 	}
 }
 
+static void check_t3b2_mac(struct adapter *adapter)
+{
+	int i;
+
+	if (!rtnl_trylock())	/* synchronize with ifdown */
+		return;
+
+	for_each_port(adapter, i) {
+		struct net_device *dev = adapter->port[i];
+		struct port_info *p = netdev_priv(dev);
+		int status;
+
+		if (!netif_running(dev))
+			continue;
+
+		status = 0;
+		if (netif_running(dev) && netif_carrier_ok(dev))
+			status = t3b2_mac_watchdog_task(&p->mac);
+		if (status == 1)
+			p->mac.stats.num_toggled++;
+		else if (status == 2) {
+			struct cmac *mac = &p->mac;
+
+			t3_mac_set_mtu(mac, dev->mtu);
+			t3_mac_set_address(mac, 0, dev->dev_addr);
+			cxgb_set_rxmode(dev);
+			t3_link_start(&p->phy, mac, &p->link_config);
+			t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
+			t3_port_intr_enable(adapter, p->port_id);
+			p->mac.stats.num_resets++;
+		}
+	}
+	rtnl_unlock();
+}
+
+
 static void t3_adap_check_task(struct work_struct *work)
 {
 	struct adapter *adapter = container_of(work, struct adapter,
@@ -2087,6 +2171,9 @@
 		adapter->check_task_cnt = 0;
 	}
 
+	if (p->rev == T3_REV_B2)
+		check_t3b2_mac(adapter);
+
 	/* Schedule the next check update if any port is active. */
 	spin_lock(&adapter->work_lock);
 	if (adapter->open_device_map & PORT_MASK)
@@ -2195,9 +2282,9 @@
 
 		if (!test_bit(i, &adap->registered_device_map))
 			continue;
-		printk(KERN_INFO "%s: %s %s RNIC (rev %d) %s%s\n",
+		printk(KERN_INFO "%s: %s %s %sNIC (rev %d) %s%s\n",
 		       dev->name, ai->desc, pi->port_type->desc,
-		       adap->params.rev, buf,
+		       is_offload(adap) ? "R" : "", adap->params.rev, buf,
 		       (adap->flags & USING_MSIX) ? " MSI-X" :
 		       (adap->flags & USING_MSI) ? " MSI" : "");
 		if (adap->name == dev->name && adap->params.vpd.mclk)
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index f6ed033..4864924 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -553,7 +553,9 @@
 	struct tid_info *t = &(T3C_DATA(tdev))->tid_maps;
 
 	spin_lock_bh(&t->atid_lock);
-	if (t->afree) {
+	if (t->afree &&
+	    t->atids_in_use + atomic_read(&t->tids_in_use) + MC5_MIN_TIDS <=
+	    t->ntids) {
 		union active_open_entry *p = t->afree;
 
 		atid = (p - t->atid_tab) + t->atid_base;
@@ -741,17 +743,6 @@
 	}
 }
 
-static int do_set_tcb_rpl(struct t3cdev *dev, struct sk_buff *skb)
-{
-	struct cpl_set_tcb_rpl *rpl = cplhdr(skb);
-
-	if (rpl->status != CPL_ERR_NONE)
-		printk(KERN_ERR
-		       "Unexpected SET_TCB_RPL status %u for tid %u\n",
-		       rpl->status, GET_TID(rpl));
-	return CPL_RET_BUF_DONE;
-}
-
 static int do_trace(struct t3cdev *dev, struct sk_buff *skb)
 {
 	struct cpl_trace_pkt *p = cplhdr(skb);
@@ -1213,7 +1204,8 @@
 	t3_register_cpl_handler(CPL_CLOSE_CON_RPL, do_hwtid_rpl);
 	t3_register_cpl_handler(CPL_ABORT_REQ_RSS, do_abort_req_rss);
 	t3_register_cpl_handler(CPL_ACT_ESTABLISH, do_act_establish);
-	t3_register_cpl_handler(CPL_SET_TCB_RPL, do_set_tcb_rpl);
+	t3_register_cpl_handler(CPL_SET_TCB_RPL, do_hwtid_rpl);
+	t3_register_cpl_handler(CPL_GET_TCB_RPL, do_hwtid_rpl);
 	t3_register_cpl_handler(CPL_RDMA_TERMINATE, do_term);
 	t3_register_cpl_handler(CPL_RDMA_EC_STATUS, do_hwtid_rpl);
 	t3_register_cpl_handler(CPL_TRACE_PKT, do_trace);
diff --git a/drivers/net/cxgb3/mc5.c b/drivers/net/cxgb3/mc5.c
index 644d62e..84c1ffa 100644
--- a/drivers/net/cxgb3/mc5.c
+++ b/drivers/net/cxgb3/mc5.c
@@ -328,6 +328,9 @@
 	unsigned int tcam_size = mc5->tcam_size;
 	struct adapter *adap = mc5->adapter;
 
+	if (!tcam_size)
+		return 0;
+
 	if (nroutes > MAX_ROUTES || nroutes + nservers + nfilters > tcam_size)
 		return -EINVAL;
 
diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h
index b56c5f5..e5a5534 100644
--- a/drivers/net/cxgb3/regs.h
+++ b/drivers/net/cxgb3/regs.h
@@ -1206,6 +1206,14 @@
 
 #define A_TP_RX_TRC_KEY0 0x120
 
+#define A_TP_TX_DROP_CNT_CH0 0x12d
+
+#define S_TXDROPCNTCH0RCVD    0
+#define M_TXDROPCNTCH0RCVD    0xffff
+#define V_TXDROPCNTCH0RCVD(x) ((x) << S_TXDROPCNTCH0RCVD)
+#define G_TXDROPCNTCH0RCVD(x) (((x) >> S_TXDROPCNTCH0RCVD) & \
+			       M_TXDROPCNTCH0RCVD)
+
 #define A_ULPRX_CTL 0x500
 
 #define S_ROUND_ROBIN    4
@@ -1226,9 +1234,15 @@
 
 #define A_ULPRX_ISCSI_TAGMASK 0x514
 
+#define S_HPZ0    0
+#define M_HPZ0    0xf
+#define V_HPZ0(x) ((x) << S_HPZ0)
+#define G_HPZ0(x) (((x) >> S_HPZ0) & M_HPZ0)
+
 #define A_ULPRX_TDDP_LLIMIT 0x51c
 
 #define A_ULPRX_TDDP_ULIMIT 0x520
+#define A_ULPRX_TDDP_PSZ 0x528
 
 #define A_ULPRX_STAG_LLIMIT 0x52c
 
@@ -1834,6 +1848,8 @@
 #define V_TXPAUSEEN(x) ((x) << S_TXPAUSEEN)
 #define F_TXPAUSEEN    V_TXPAUSEEN(1U)
 
+#define A_XGM_TX_PAUSE_QUANTA 0x808
+
 #define A_XGM_RX_CTRL 0x80c
 
 #define S_RXEN    0
@@ -1920,11 +1936,20 @@
 
 #define A_XGM_TXFIFO_CFG 0x888
 
+#define S_TXIPG    13
+#define M_TXIPG    0xff
+#define V_TXIPG(x) ((x) << S_TXIPG)
+#define G_TXIPG(x) (((x) >> S_TXIPG) & M_TXIPG)
+
 #define S_TXFIFOTHRESH    4
 #define M_TXFIFOTHRESH    0x1ff
 
 #define V_TXFIFOTHRESH(x) ((x) << S_TXFIFOTHRESH)
 
+#define S_ENDROPPKT    21
+#define V_ENDROPPKT(x) ((x) << S_ENDROPPKT)
+#define F_ENDROPPKT    V_ENDROPPKT(1U)
+
 #define A_XGM_SERDES_CTRL 0x890
 #define A_XGM_SERDES_CTRL0 0x8e0
 
@@ -2190,6 +2215,13 @@
 
 #define A_XGM_RX_MAX_PKT_SIZE_ERR_CNT 0x9a4
 
+#define A_XGM_TX_SPI4_SOP_EOP_CNT 0x9a8
+
+#define S_TXSPI4SOPCNT    16
+#define M_TXSPI4SOPCNT    0xffff
+#define V_TXSPI4SOPCNT(x) ((x) << S_TXSPI4SOPCNT)
+#define G_TXSPI4SOPCNT(x) (((x) >> S_TXSPI4SOPCNT) & M_TXSPI4SOPCNT)
+
 #define A_XGM_RX_SPI4_SOP_EOP_CNT 0x9ac
 
 #define XGMAC0_1_BASE_ADDR 0xa00
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index c237834..027ab2c 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -2631,7 +2631,7 @@
 	q->txq[TXQ_ETH].stop_thres = nports *
 	    flits_to_desc(sgl_len(MAX_SKB_FRAGS + 1) + 3);
 
-	if (ntxq == 1) {
+	if (!is_offload(adapter)) {
 #ifdef USE_RX_PAGE
 		q->fl[0].buf_size = RX_PAGE_SIZE;
 #else
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index eaa7a2e..d83f075 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -438,23 +438,23 @@
 	{2, 0, 0, 0,
 	 F_GPIO2_OEN | F_GPIO4_OEN |
 	 F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5,
-	 SUPPORTED_OFFLOAD,
+	 0,
 	 &mi1_mdio_ops, "Chelsio PE9000"},
 	{2, 0, 0, 0,
 	 F_GPIO2_OEN | F_GPIO4_OEN |
 	 F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5,
-	 SUPPORTED_OFFLOAD,
+	 0,
 	 &mi1_mdio_ops, "Chelsio T302"},
 	{1, 0, 0, 0,
 	 F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO10_OEN |
 	 F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, 0,
-	 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_OFFLOAD,
+	 SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
 	 &mi1_mdio_ext_ops, "Chelsio T310"},
 	{2, 0, 0, 0,
 	 F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO5_OEN | F_GPIO6_OEN |
 	 F_GPIO7_OEN | F_GPIO10_OEN | F_GPIO11_OEN | F_GPIO1_OUT_VAL |
 	 F_GPIO5_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, 0,
-	 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_OFFLOAD,
+	 SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
 	 &mi1_mdio_ext_ops, "Chelsio T320"},
 };
 
@@ -681,7 +681,8 @@
 	SF_ERASE_SECTOR = 0xd8,	/* erase sector */
 
 	FW_FLASH_BOOT_ADDR = 0x70000,	/* start address of FW in flash */
-	FW_VERS_ADDR = 0x77ffc	/* flash address holding FW version */
+	FW_VERS_ADDR = 0x77ffc,    /* flash address holding FW version */
+	FW_MIN_SIZE = 8            /* at least version and csum */
 };
 
 /**
@@ -935,7 +936,7 @@
 	const u32 *p = (const u32 *)fw_data;
 	int ret, addr, fw_sector = FW_FLASH_BOOT_ADDR >> 16;
 
-	if (size & 3)
+	if ((size & 3) || size < FW_MIN_SIZE)
 		return -EINVAL;
 	if (size > FW_VERS_ADDR + 8 - FW_FLASH_BOOT_ADDR)
 		return -EFBIG;
@@ -2899,6 +2900,9 @@
 	struct adapter *adapter = mc7->adapter;
 	const struct mc7_timing_params *p = &mc7_timings[mem_type];
 
+	if (!mc7->size)
+		return 0;
+
 	val = t3_read_reg(adapter, mc7->offset + A_MC7_CFG);
 	slow = val & F_SLOW;
 	width = G_WIDTH(val);
@@ -3099,8 +3103,10 @@
 	do {			/* wait for uP to initialize */
 		msleep(20);
 	} while (t3_read_reg(adapter, A_CIM_HOST_ACC_DATA) && --attempts);
-	if (!attempts)
+	if (!attempts) {
+		CH_ERR(adapter, "uP initialization timed out\n");
 		goto out_err;
+	}
 
 	err = 0;
 out_err:
@@ -3200,7 +3206,7 @@
 	mc7->name = name;
 	mc7->offset = base_addr - MC7_PMRX_BASE_ADDR;
 	cfg = t3_read_reg(adapter, mc7->offset + A_MC7_CFG);
-	mc7->size = mc7_calc_size(cfg);
+	mc7->size = mc7->size = G_DEN(cfg) == M_DEN ? 0 : mc7_calc_size(cfg);
 	mc7->width = G_WIDTH(cfg);
 }
 
@@ -3227,6 +3233,7 @@
 		     V_I2C_CLKDIV(adapter->params.vpd.cclk / 80 - 1));
 	t3_write_reg(adapter, A_T3DBG_GPIO_EN,
 		     ai->gpio_out | F_GPIO0_OEN | F_GPIO0_OUT_VAL);
+	t3_write_reg(adapter, A_MC5_DB_SERVER_INDEX, 0);
 
 	if (adapter->params.rev == 0 || !uses_xaui(adapter))
 		val |= F_ENRGMII;
@@ -3243,15 +3250,17 @@
 }
 
 /*
- * Reset the adapter.  PCIe cards lose their config space during reset, PCI-X
+ * Reset the adapter. 
+ * Older PCIe cards lose their config space during reset, PCI-X
  * ones don't.
  */
 int t3_reset_adapter(struct adapter *adapter)
 {
-	int i;
+	int i, save_and_restore_pcie = 
+	    adapter->params.rev < T3_REV_B2 && is_pcie(adapter);
 	uint16_t devid = 0;
 
-	if (is_pcie(adapter))
+	if (save_and_restore_pcie)
 		pci_save_state(adapter->pdev);
 	t3_write_reg(adapter, A_PL_RST, F_CRSTWRM | F_CRSTWRMMODE);
 
@@ -3269,7 +3278,7 @@
 	if (devid != 0x1425)
 		return -1;
 
-	if (is_pcie(adapter))
+	if (save_and_restore_pcie)
 		pci_restore_state(adapter->pdev);
 	return 0;
 }
@@ -3323,7 +3332,13 @@
 		p->tx_num_pgs = pm_num_pages(p->chan_tx_size, p->tx_pg_size);
 		p->ntimer_qs = p->cm_size >= (128 << 20) ||
 		    adapter->params.rev > 0 ? 12 : 6;
+	}
 
+	adapter->params.offload = t3_mc7_size(&adapter->pmrx) &&
+				  t3_mc7_size(&adapter->pmtx) &&
+				  t3_mc7_size(&adapter->cm);
+
+	if (is_offload(adapter)) {
 		adapter->params.mc5.nservers = DEFAULT_NSERVERS;
 		adapter->params.mc5.nfilters = adapter->params.rev > 0 ?
 		    DEFAULT_NFILTERS : 0;
diff --git a/drivers/net/cxgb3/version.h b/drivers/net/cxgb3/version.h
index 82278f8..042e27e 100644
--- a/drivers/net/cxgb3/version.h
+++ b/drivers/net/cxgb3/version.h
@@ -36,6 +36,9 @@
 #define DRV_NAME "cxgb3"
 /* Driver version */
 #define DRV_VERSION "1.0-ko"
+
+/* Firmware version */
 #define FW_VERSION_MAJOR 3
-#define FW_VERSION_MINOR 2
+#define FW_VERSION_MINOR 3
+#define FW_VERSION_MICRO 0
 #endif				/* __CHELSIO_VERSION_H */
diff --git a/drivers/net/cxgb3/xgmac.c b/drivers/net/cxgb3/xgmac.c
index 907a272..a506792 100644
--- a/drivers/net/cxgb3/xgmac.c
+++ b/drivers/net/cxgb3/xgmac.c
@@ -124,9 +124,6 @@
 			xaui_serdes_reset(mac);
 	}
 
-	if (adap->params.rev > 0)
-		t3_write_reg(adap, A_XGM_PAUSE_TIMER + oft, 0xf000);
-
 	val = F_MAC_RESET_;
 	if (is_10G(adap))
 		val |= F_PCS_RESET_;
@@ -145,6 +142,58 @@
 	return 0;
 }
 
+int t3b2_mac_reset(struct cmac *mac)
+{
+	struct adapter *adap = mac->adapter;
+	unsigned int oft = mac->offset;
+	u32 val;
+
+	if (!macidx(mac)) 
+		t3_set_reg_field(adap, A_MPS_CFG, F_PORT0ACTIVE, 0);
+	else
+		t3_set_reg_field(adap, A_MPS_CFG, F_PORT1ACTIVE, 0);
+
+	t3_write_reg(adap, A_XGM_RESET_CTRL + oft, F_MAC_RESET_);
+	t3_read_reg(adap, A_XGM_RESET_CTRL + oft);    /* flush */
+
+	msleep(10);
+
+	/* Check for xgm Rx fifo empty */
+	if (t3_wait_op_done(adap, A_XGM_RX_MAX_PKT_SIZE_ERR_CNT + oft,
+			    0x80000000, 1, 5, 2)) {
+		CH_ERR(adap, "MAC %d Rx fifo drain failed\n",
+		       macidx(mac));
+		return -1;
+	}
+
+	t3_write_reg(adap, A_XGM_RESET_CTRL + oft, 0);
+	t3_read_reg(adap, A_XGM_RESET_CTRL + oft);    /* flush */
+
+	val = F_MAC_RESET_;
+	if (is_10G(adap))
+		val |= F_PCS_RESET_;
+	else if (uses_xaui(adap))
+		val |= F_PCS_RESET_ | F_XG2G_RESET_;
+	else
+		val |= F_RGMII_RESET_ | F_XG2G_RESET_;
+	t3_write_reg(adap, A_XGM_RESET_CTRL + oft, val);
+	t3_read_reg(adap, A_XGM_RESET_CTRL + oft);  /* flush */
+	if ((val & F_PCS_RESET_) && adap->params.rev) {
+		msleep(1);
+		t3b_pcs_reset(mac);
+	}
+	t3_write_reg(adap, A_XGM_RX_CFG + oft, 
+		     F_DISPAUSEFRAMES | F_EN1536BFRAMES |
+		     F_RMFCS | F_ENJUMBO | F_ENHASHMCAST);
+
+	if (!macidx(mac)) 
+		t3_set_reg_field(adap, A_MPS_CFG, 0, F_PORT0ACTIVE);
+	else
+		t3_set_reg_field(adap, A_MPS_CFG, 0, F_PORT1ACTIVE);
+
+	return 0;
+}
+
 /*
  * Set the exact match register 'idx' to recognize the given Ethernet address.
  */
@@ -251,9 +300,11 @@
 	 * Adjust the PAUSE frame watermarks.  We always set the LWM, and the
 	 * HWM only if flow-control is enabled.
 	 */
-	hwm = max(MAC_RXFIFO_SIZE - 3 * mtu, MAC_RXFIFO_SIZE / 2U);
-	hwm = min(hwm, 3 * MAC_RXFIFO_SIZE / 4 + 1024);
-	lwm = hwm - 1024;
+	hwm = max_t(unsigned int, MAC_RXFIFO_SIZE - 3 * mtu, 
+		    MAC_RXFIFO_SIZE * 38 / 100);
+	hwm = min(hwm, MAC_RXFIFO_SIZE - 8192);
+	lwm = min(3 * (int)mtu, MAC_RXFIFO_SIZE / 4);
+
 	v = t3_read_reg(adap, A_XGM_RXFIFO_CFG + mac->offset);
 	v &= ~V_RXFIFOPAUSELWM(M_RXFIFOPAUSELWM);
 	v |= V_RXFIFOPAUSELWM(lwm / 8);
@@ -270,7 +321,15 @@
 	thres = mtu > thres ? (mtu - thres + 7) / 8 : 0;
 	thres = max(thres, 8U);	/* need at least 8 */
 	t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + mac->offset,
-			 V_TXFIFOTHRESH(M_TXFIFOTHRESH), V_TXFIFOTHRESH(thres));
+			 V_TXFIFOTHRESH(M_TXFIFOTHRESH) | V_TXIPG(M_TXIPG),
+			 V_TXFIFOTHRESH(thres) | V_TXIPG(1));
+
+	if (adap->params.rev > 0)
+		t3_write_reg(adap, A_XGM_PAUSE_TIMER + mac->offset,
+			     (hwm - lwm) * 4 / 8);
+	t3_write_reg(adap, A_XGM_TX_PAUSE_QUANTA + mac->offset,
+		     MAC_RXFIFO_SIZE * 4 * 8 / 512);
+
 	return 0;
 }
 
@@ -298,12 +357,6 @@
 				 V_PORTSPEED(M_PORTSPEED), val);
 	}
 
-	val = t3_read_reg(adap, A_XGM_RXFIFO_CFG + oft);
-	val &= ~V_RXFIFOPAUSEHWM(M_RXFIFOPAUSEHWM);
-	if (fc & PAUSE_TX)
-		val |= V_RXFIFOPAUSEHWM(G_RXFIFOPAUSELWM(val) + 128);	/* +1KB */
-	t3_write_reg(adap, A_XGM_RXFIFO_CFG + oft, val);
-
 	t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN,
 			 (fc & PAUSE_RX) ? F_TXPAUSEEN : 0);
 	return 0;
@@ -314,13 +367,28 @@
 	int idx = macidx(mac);
 	struct adapter *adap = mac->adapter;
 	unsigned int oft = mac->offset;
-
+	struct mac_stats *s = &mac->stats;
+	
 	if (which & MAC_DIRECTION_TX) {
 		t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN);
 		t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
-		t3_write_reg(adap, A_TP_PIO_DATA, 0xbf000001);
+		t3_write_reg(adap, A_TP_PIO_DATA, 0xc0ede401);
 		t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_MODE);
 		t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx);
+
+		t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CNT_CH0 + idx);
+		mac->tx_mcnt = s->tx_frames;
+		mac->tx_tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap,
+							A_TP_PIO_DATA)));
+		mac->tx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
+						A_XGM_TX_SPI4_SOP_EOP_CNT +
+						oft)));
+		mac->rx_mcnt = s->rx_frames;
+		mac->rx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
+						A_XGM_RX_SPI4_SOP_EOP_CNT +
+						oft)));
+		mac->txen = F_TXEN;
+		mac->toggle_cnt = 0;
 	}
 	if (which & MAC_DIRECTION_RX)
 		t3_write_reg(adap, A_XGM_RX_CTRL + oft, F_RXEN);
@@ -331,19 +399,102 @@
 {
 	int idx = macidx(mac);
 	struct adapter *adap = mac->adapter;
+	int val;
 
 	if (which & MAC_DIRECTION_TX) {
 		t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0);
 		t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
 		t3_write_reg(adap, A_TP_PIO_DATA, 0xc000001f);
 		t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_MODE);
-		t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 0);
+		t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx);
+		mac->txen = 0;
 	}
-	if (which & MAC_DIRECTION_RX)
+	if (which & MAC_DIRECTION_RX) {
+		t3_set_reg_field(mac->adapter, A_XGM_RESET_CTRL + mac->offset,
+				 F_PCS_RESET_, 0);
+		msleep(100);
 		t3_write_reg(adap, A_XGM_RX_CTRL + mac->offset, 0);
+		val = F_MAC_RESET_;
+		if (is_10G(adap))
+			val |= F_PCS_RESET_;
+		else if (uses_xaui(adap))
+			val |= F_PCS_RESET_ | F_XG2G_RESET_;
+		else
+			val |= F_RGMII_RESET_ | F_XG2G_RESET_;
+		t3_write_reg(mac->adapter, A_XGM_RESET_CTRL + mac->offset, val);
+	}
 	return 0;
 }
 
+int t3b2_mac_watchdog_task(struct cmac *mac)
+{
+	struct adapter *adap = mac->adapter;
+	struct mac_stats *s = &mac->stats;
+	unsigned int tx_tcnt, tx_xcnt;
+	unsigned int tx_mcnt = s->tx_frames;
+	unsigned int rx_mcnt = s->rx_frames;
+	unsigned int rx_xcnt;
+	int status;
+
+	if (tx_mcnt == mac->tx_mcnt) {
+		tx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
+						A_XGM_TX_SPI4_SOP_EOP_CNT +
+					       	mac->offset)));
+		if (tx_xcnt == 0) {
+			t3_write_reg(adap, A_TP_PIO_ADDR,
+				     A_TP_TX_DROP_CNT_CH0 + macidx(mac));
+			tx_tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap,
+						      A_TP_PIO_DATA)));
+		} else {
+			mac->toggle_cnt = 0;
+			return 0;
+		}
+	} else {
+		mac->toggle_cnt = 0;
+		return 0;
+	}
+
+	if (((tx_tcnt != mac->tx_tcnt) &&
+	     (tx_xcnt == 0) && (mac->tx_xcnt == 0)) ||
+	    ((mac->tx_mcnt == tx_mcnt) &&
+	     (tx_xcnt != 0) && (mac->tx_xcnt != 0))) {
+		if (mac->toggle_cnt > 4)
+			status = 2;
+		else 
+			status = 1;
+	} else {
+		mac->toggle_cnt = 0;
+		return 0;
+	}
+
+	if (rx_mcnt != mac->rx_mcnt)
+		rx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
+						A_XGM_RX_SPI4_SOP_EOP_CNT +
+						mac->offset)));
+	else 
+		return 0;
+
+	if (mac->rx_mcnt != s->rx_frames && rx_xcnt == 0 && mac->rx_xcnt == 0) 
+		status = 2;
+	
+	mac->tx_tcnt = tx_tcnt;
+	mac->tx_xcnt = tx_xcnt;
+	mac->tx_mcnt = s->tx_frames;
+	mac->rx_xcnt = rx_xcnt;
+	mac->rx_mcnt = s->rx_frames;
+	if (status == 1) {
+		t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0);
+		t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset);  /* flush */
+		t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, mac->txen);
+		t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset);  /* flush */
+		mac->toggle_cnt++;
+	} else if (status == 2) {
+		t3b2_mac_reset(mac);
+		mac->toggle_cnt = 0;
+	}
+	return status;
+}
+
 /*
  * This function is called periodically to accumulate the current values of the
  * RMON counters into the port statistics.  Since the packet counters are only
@@ -373,7 +524,11 @@
 	RMON_UPDATE(mac, rx_symbol_errs, RX_SYM_CODE_ERR_FRAMES);
 
 	RMON_UPDATE(mac, rx_too_long, RX_OVERSIZE_FRAMES);
-	mac->stats.rx_too_long += RMON_READ(mac, A_XGM_RX_MAX_PKT_SIZE_ERR_CNT);
+
+	v = RMON_READ(mac, A_XGM_RX_MAX_PKT_SIZE_ERR_CNT);
+	if (mac->adapter->params.rev == T3_REV_B2)
+		v &= 0x7fffffff;
+	mac->stats.rx_too_long += v;
 
 	RMON_UPDATE(mac, rx_frames_64, RX_64B_FRAMES);
 	RMON_UPDATE(mac, rx_frames_65_127, RX_65_127B_FRAMES);
diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c
index c8c41f0..714ea11 100644
--- a/drivers/net/ewrk3.c
+++ b/drivers/net/ewrk3.c
@@ -414,10 +414,9 @@
 	icr &= 0x70;
 	outb(icr, EWRK3_ICR);	/* Disable all the IRQs */
 
-	if (nicsr == (CSR_TXD | CSR_RXD))
+	if (nicsr != (CSR_TXD | CSR_RXD))
 		return -ENXIO;
 
-
 	/* Check that the EEPROM is alive and well and not living on Pluto... */
 	for (chksum = 0, i = 0; i < EEPROM_MAX; i += 2) {
 		union {
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 46e1697..d04214e 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -2050,9 +2050,10 @@
 		nv_drain_tx(dev);
 		nv_init_tx(dev);
 		setup_hw_rings(dev, NV_SETUP_TX_RING);
-		netif_wake_queue(dev);
 	}
 
+	netif_wake_queue(dev);
+
 	/* 4) restart tx engine */
 	nv_start_tx(dev);
 	spin_unlock_irq(&np->lock);
@@ -3536,7 +3537,10 @@
 	pci_push(base);
 
 	if (!using_multi_irqs(dev)) {
-		nv_nic_irq(0, dev);
+		if (np->desc_ver == DESC_VER_3)
+			nv_nic_irq_optimized(0, dev);
+		else
+			nv_nic_irq(0, dev);
 		if (np->msi_flags & NV_MSI_X_ENABLED)
 			enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
 		else
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index ca2b21f..07b4c0d 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -96,17 +96,24 @@
 		skb->tc_verd = SET_TC_NCLS(skb->tc_verd);
 		stats->tx_packets++;
 		stats->tx_bytes +=skb->len;
+
+		skb->dev = __dev_get_by_index(skb->iif);
+		if (!skb->dev) {
+			dev_kfree_skb(skb);
+			stats->tx_dropped++;
+			break;
+		}
+		skb->iif = _dev->ifindex;
+
 		if (from & AT_EGRESS) {
 			dp->st_rx_frm_egr++;
 			dev_queue_xmit(skb);
 		} else if (from & AT_INGRESS) {
-
 			dp->st_rx_frm_ing++;
+			skb_pull(skb, skb->dev->hard_header_len);
 			netif_rx(skb);
-		} else {
-			dev_kfree_skb(skb);
-			stats->tx_dropped++;
-		}
+		} else
+			BUG();
 	}
 
 	if (netif_tx_trylock(_dev)) {
@@ -157,26 +164,10 @@
 	stats->rx_packets++;
 	stats->rx_bytes+=skb->len;
 
-	if (!from || !skb->input_dev) {
-dropped:
+	if (!(from & (AT_INGRESS|AT_EGRESS)) || !skb->iif) {
 		dev_kfree_skb(skb);
 		stats->rx_dropped++;
 		return ret;
-	} else {
-		/*
-		 * note we could be going
-		 * ingress -> egress or
-		 * egress -> ingress
-		*/
-		skb->dev = skb->input_dev;
-		skb->input_dev = dev;
-		if (from & AT_INGRESS) {
-			skb_pull(skb, skb->dev->hard_header_len);
-		} else {
-			if (!(from & AT_EGRESS)) {
-				goto dropped;
-			}
-		}
 	}
 
 	if (skb_queue_len(&dp->rq) >= dev->tx_queue_len) {
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 340ee99..1d510bd 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -1057,6 +1057,8 @@
 
 		if (ret < 0)
 			break;
+
+		mdelay(10);
 	}
 
 	kfree(patch_block);
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 9137e23..2272156 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -321,15 +321,22 @@
 		pxa_irda_set_speed(si, si->newspeed);
 		si->newspeed = 0;
 	} else {
+		int i = 64;
+
 		ICCR0 = 0;
 		pxa_irda_fir_dma_rx_start(si);
+		while ((ICSR1 & ICSR1_RNE) && i--)
+			(void)ICDR;
 		ICCR0 = ICCR0_ITR | ICCR0_RXE;
+
+		if (i < 0)
+			printk(KERN_ERR "pxa_ir: cannot clear Rx FIFO!\n");
 	}
 	netif_wake_queue(dev);
 }
 
 /* EIF(Error in FIFO/End in Frame) handler for FIR */
-static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev)
+static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev, int icsr0)
 {
 	unsigned int len, stat, data;
 
@@ -350,7 +357,7 @@
 			}
 			if (stat & ICSR1_ROR) {
 				printk(KERN_DEBUG "pxa_ir: fir receive overrun\n");
-				si->stats.rx_frame_errors++;
+				si->stats.rx_over_errors++;
 			}
 		} else	{
 			si->dma_rx_buff[len++] = data;
@@ -362,7 +369,15 @@
 
 	if (stat & ICSR1_EOF) {
 		/* end of frame. */
-		struct sk_buff *skb = alloc_skb(len+1,GFP_ATOMIC);
+		struct sk_buff *skb;
+
+		if (icsr0 & ICSR0_FRE) {
+			printk(KERN_ERR "pxa_ir: dropping erroneous frame\n");
+			si->stats.rx_dropped++;
+			return;
+		}
+
+		skb = alloc_skb(len+1,GFP_ATOMIC);
 		if (!skb)  {
 			printk(KERN_ERR "pxa_ir: fir out of memory for receive skb\n");
 			si->stats.rx_dropped++;
@@ -392,7 +407,7 @@
 {
 	struct net_device *dev = dev_id;
 	struct pxa_irda *si = netdev_priv(dev);
-	int icsr0;
+	int icsr0, i = 64;
 
 	/* stop RX DMA */
 	DCSR(si->rxdma) &= ~DCSR_RUN;
@@ -412,13 +427,18 @@
 
 	if (icsr0 & ICSR0_EIF) {
 		/* An error in FIFO occured, or there is a end of frame */
-		pxa_irda_fir_irq_eif(si, dev);
+		pxa_irda_fir_irq_eif(si, dev, icsr0);
 	}
 
 	ICCR0 = 0;
 	pxa_irda_fir_dma_rx_start(si);
+	while ((ICSR1 & ICSR1_RNE) && i--)
+		(void)ICDR;
 	ICCR0 = ICCR0_ITR | ICCR0_RXE;
 
+	if (i < 0)
+		printk(KERN_ERR "pxa_ir: cannot clear Rx FIFO!\n");
+
 	return IRQ_HANDLED;
 }
 
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 9ba21e0..8015a7c 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -787,6 +787,12 @@
 	unsigned int size;
 	int err;
 
+	/* Clear any pending ethernet port interrupts */
+	mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
+	mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
+	/* wait for previous write to complete */
+	mv_read (MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num));
+
 	err = request_irq(dev->irq, mv643xx_eth_int_handler,
 			IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, dev);
 	if (err) {
@@ -875,10 +881,6 @@
 
 	mv643xx_eth_rx_refill_descs(dev);	/* Fill RX ring with skb's */
 
-	/* Clear any pending ethernet port interrupts */
-	mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
-	mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
-
 	eth_port_start(dev);
 
 	/* Interrupt Coalescing */
@@ -1377,7 +1379,7 @@
 
 	spin_lock_init(&mp->lock);
 
-	port_num = pd->port_number;
+	port_num = mp->port_num = pd->port_number;
 
 	/* set default config values */
 	eth_port_uc_addr_get(dev, dev->dev_addr);
@@ -1409,8 +1411,6 @@
 	duplex = pd->duplex;
 	speed = pd->speed;
 
-	mp->port_num = port_num;
-
 	/* Hook up MII support for ethtool */
 	mp->mii.dev = dev;
 	mp->mii.mdio_read = mv643xx_mdio_read;
@@ -1514,9 +1514,23 @@
 	return 0;
 }
 
+static void mv643xx_eth_shutdown(struct platform_device *pdev)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+	struct mv643xx_private *mp = netdev_priv(dev);
+	unsigned int port_num = mp->port_num;
+
+	/* Mask all interrupts on ethernet port */
+	mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), 0);
+	mv_read (MV643XX_ETH_INTERRUPT_MASK_REG(port_num));
+
+	eth_port_reset(port_num);
+}
+
 static struct platform_driver mv643xx_eth_driver = {
 	.probe = mv643xx_eth_probe,
 	.remove = mv643xx_eth_remove,
+	.shutdown = mv643xx_eth_shutdown,
 	.driver = {
 		.name = MV643XX_ETH_NAME,
 	},
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index b05dc6e..f8efe0e 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -71,7 +71,7 @@
 #include "myri10ge_mcp.h"
 #include "myri10ge_mcp_gen_header.h"
 
-#define MYRI10GE_VERSION_STR "1.2.0"
+#define MYRI10GE_VERSION_STR "1.3.0-1.233"
 
 MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
 MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -181,6 +181,7 @@
 	int intr_coal_delay;
 	__be32 __iomem *intr_coal_delay_ptr;
 	int mtrr;
+	int wc_enabled;
 	int wake_queue;
 	int stop_queue;
 	int down_cnt;
@@ -233,7 +234,7 @@
 module_param(myri10ge_msi, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(myri10ge_msi, "Enable Message Signalled Interrupts\n");
 
-static int myri10ge_intr_coal_delay = 25;
+static int myri10ge_intr_coal_delay = 75;
 module_param(myri10ge_intr_coal_delay, int, S_IRUGO);
 MODULE_PARM_DESC(myri10ge_intr_coal_delay, "Interrupt coalescing delay\n");
 
@@ -278,7 +279,7 @@
 module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed\n");
 
-static int myri10ge_wcfifo = 1;
+static int myri10ge_wcfifo = 0;
 module_param(myri10ge_wcfifo, int, S_IRUGO);
 MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n");
 
@@ -717,6 +718,8 @@
 	int status;
 	size_t bytes;
 	u32 len;
+	struct page *dmatest_page;
+	dma_addr_t dmatest_bus;
 
 	/* try to send a reset command to the card to see if it
 	 * is alive */
@@ -726,6 +729,11 @@
 		dev_err(&mgp->pdev->dev, "failed reset\n");
 		return -ENXIO;
 	}
+	dmatest_page = alloc_page(GFP_KERNEL);
+	if (!dmatest_page)
+		return -ENOMEM;
+	dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE,
+				   DMA_BIDIRECTIONAL);
 
 	/* Now exchange information about interrupts  */
 
@@ -764,8 +772,8 @@
 
 	len = mgp->tx.boundary;
 
-	cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus);
-	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus);
+	cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
+	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
 	cmd.data2 = len * 0x10000;
 	status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
 	if (status == 0)
@@ -774,8 +782,8 @@
 	else
 		dev_warn(&mgp->pdev->dev, "DMA read benchmark failed: %d\n",
 			 status);
-	cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus);
-	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus);
+	cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
+	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
 	cmd.data2 = len * 0x1;
 	status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
 	if (status == 0)
@@ -785,8 +793,8 @@
 		dev_warn(&mgp->pdev->dev, "DMA write benchmark failed: %d\n",
 			 status);
 
-	cmd.data0 = MYRI10GE_LOWPART_TO_U32(mgp->rx_done.bus);
-	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(mgp->rx_done.bus);
+	cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
+	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
 	cmd.data2 = len * 0x10001;
 	status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
 	if (status == 0)
@@ -796,6 +804,9 @@
 		dev_warn(&mgp->pdev->dev,
 			 "DMA read/write benchmark failed: %d\n", status);
 
+	pci_unmap_page(mgp->pdev, dmatest_bus, PAGE_SIZE, DMA_BIDIRECTIONAL);
+	put_page(dmatest_page);
+
 	memset(mgp->rx_done.entry, 0, bytes);
 
 	/* reset mcp/driver shared state back to 0 */
@@ -889,9 +900,7 @@
 	/* try to refill entire ring */
 	while (rx->fill_cnt != (rx->cnt + rx->mask + 1)) {
 		idx = rx->fill_cnt & rx->mask;
-
-		if ((bytes < MYRI10GE_ALLOC_SIZE / 2) &&
-		    (rx->page_offset + bytes <= MYRI10GE_ALLOC_SIZE)) {
+		if (rx->page_offset + bytes <= MYRI10GE_ALLOC_SIZE) {
 			/* we can use part of previous page */
 			get_page(rx->page);
 		} else {
@@ -922,6 +931,13 @@
 
 		/* start next packet on a cacheline boundary */
 		rx->page_offset += SKB_DATA_ALIGN(bytes);
+
+#if MYRI10GE_ALLOC_SIZE > 4096
+		/* don't cross a 4KB boundary */
+		if ((rx->page_offset >> 12) !=
+		    ((rx->page_offset + bytes - 1) >> 12))
+			rx->page_offset = (rx->page_offset + 4096) & ~4095;
+#endif
 		rx->fill_cnt++;
 
 		/* copy 8 descriptors to the firmware at a time */
@@ -1375,7 +1391,7 @@
 		data[i] = ((unsigned long *)&mgp->stats)[i];
 
 	data[i++] = (unsigned int)mgp->tx.boundary;
-	data[i++] = (unsigned int)(mgp->mtrr >= 0);
+	data[i++] = (unsigned int)mgp->wc_enabled;
 	data[i++] = (unsigned int)mgp->pdev->irq;
 	data[i++] = (unsigned int)mgp->msi_enabled;
 	data[i++] = (unsigned int)mgp->read_dma;
@@ -1456,6 +1472,8 @@
 	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_RING_SIZE, &cmd, 0);
 	tx_ring_size = cmd.data0;
 	status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_RX_RING_SIZE, &cmd, 0);
+	if (status != 0)
+		return status;
 	rx_ring_size = cmd.data0;
 
 	tx_ring_entries = tx_ring_size / sizeof(struct mcp_kreq_ether_send);
@@ -1463,6 +1481,8 @@
 	mgp->tx.mask = tx_ring_entries - 1;
 	mgp->rx_small.mask = mgp->rx_big.mask = rx_ring_entries - 1;
 
+	status = -ENOMEM;
+
 	/* allocate the host shadow rings */
 
 	bytes = 8 + (MYRI10GE_MAX_SEND_DESC_TSO + 4)
@@ -1735,7 +1755,7 @@
 		goto abort_with_irq;
 	}
 
-	if (myri10ge_wcfifo && mgp->mtrr >= 0) {
+	if (myri10ge_wcfifo && mgp->wc_enabled) {
 		mgp->tx.wc_fifo = (u8 __iomem *) mgp->sram + MXGEFW_ETH_SEND_4;
 		mgp->rx_small.wc_fifo =
 		    (u8 __iomem *) mgp->sram + MXGEFW_ETH_RECV_SMALL;
@@ -1992,10 +2012,9 @@
 	mss = 0;
 	max_segments = MXGEFW_MAX_SEND_DESC;
 
-	if (skb->len > (dev->mtu + ETH_HLEN)) {
+	if (skb_is_gso(skb)) {
 		mss = skb_shinfo(skb)->gso_size;
-		if (mss != 0)
-			max_segments = MYRI10GE_MAX_SEND_DESC_TSO;
+		max_segments = MYRI10GE_MAX_SEND_DESC_TSO;
 	}
 
 	if ((unlikely(avail < max_segments))) {
@@ -2468,6 +2487,12 @@
 
 #define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7
 #define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa
+#define PCI_DEVICE_ID_INTEL_6300ESB_PCIEE1 0x3510
+#define PCI_DEVICE_ID_INTEL_6300ESB_PCIEE4 0x351b
+#define PCI_DEVICE_ID_INTEL_E3000_PCIE	0x2779
+#define PCI_DEVICE_ID_INTEL_E3010_PCIE	0x277a
+#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST 0x140
+#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST 0x142
 
 static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
 {
@@ -2499,6 +2524,24 @@
 			   ((bridge->vendor == PCI_VENDOR_ID_SERVERWORKS
 			     && bridge->device ==
 			     PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE)
+			    /* ServerWorks HT2100 */
+			    || (bridge->vendor == PCI_VENDOR_ID_SERVERWORKS
+				&& bridge->device >=
+				PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST
+				&& bridge->device <=
+				PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST)
+			    /* All Intel E3000/E3010 PCIE ports */
+			    || (bridge->vendor == PCI_VENDOR_ID_INTEL
+				&& (bridge->device ==
+				    PCI_DEVICE_ID_INTEL_E3000_PCIE
+				    || bridge->device ==
+				    PCI_DEVICE_ID_INTEL_E3010_PCIE))
+			    /* All Intel 6310/6311/6321ESB PCIE ports */
+			    || (bridge->vendor == PCI_VENDOR_ID_INTEL
+				&& bridge->device >=
+				PCI_DEVICE_ID_INTEL_6300ESB_PCIEE1
+				&& bridge->device <=
+				PCI_DEVICE_ID_INTEL_6300ESB_PCIEE4)
 			    /* All Intel E5000 PCIE ports */
 			    || (bridge->vendor == PCI_VENDOR_ID_INTEL
 				&& bridge->device >=
@@ -2510,6 +2553,12 @@
 				 bridge->vendor, bridge->device);
 			mgp->tx.boundary = 4096;
 			mgp->fw_name = myri10ge_fw_aligned;
+		} else if (bridge &&
+			   bridge->vendor == PCI_VENDOR_ID_SGI &&
+			   bridge->device == 0x4002 /* TIOCE pcie-port */ ) {
+			/* this pcie bridge does not support 4K rdma request */
+			mgp->tx.boundary = 2048;
+			mgp->fw_name = myri10ge_fw_aligned;
 		}
 	} else {
 		if (myri10ge_force_firmware == 1) {
@@ -2830,9 +2879,12 @@
 	mgp->board_span = pci_resource_len(pdev, 0);
 	mgp->iomem_base = pci_resource_start(pdev, 0);
 	mgp->mtrr = -1;
+	mgp->wc_enabled = 0;
 #ifdef CONFIG_MTRR
 	mgp->mtrr = mtrr_add(mgp->iomem_base, mgp->board_span,
 			     MTRR_TYPE_WRCOMB, 1);
+	if (mgp->mtrr >= 0)
+		mgp->wc_enabled = 1;
 #endif
 	/* Hack.  need to get rid of these magic numbers */
 	mgp->sram_size =
@@ -2927,7 +2979,7 @@
 	dev_info(dev, "%s IRQ %d, tx bndry %d, fw %s, WC %s\n",
 		 (mgp->msi_enabled ? "MSI" : "xPIC"),
 		 netdev->irq, mgp->tx.boundary, mgp->fw_name,
-		 (mgp->mtrr >= 0 ? "Enabled" : "Disabled"));
+		 (mgp->wc_enabled ? "Enabled" : "Disabled"));
 
 	return 0;
 
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index c6172a77a..349b96a 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -1712,7 +1712,7 @@
 
 	/* Enable interrupts by setting the interrupt mask. */
 	writel(DEFAULT_INTR, ioaddr + IntrMask);
-	writel(1, ioaddr + IntrEnable);
+	natsemi_irq_enable(dev);
 
 	writel(RxOn | TxOn, ioaddr + ChipCmd);
 	writel(StatsClear, ioaddr + StatsCtrl); /* Clear Stats */
@@ -2119,28 +2119,35 @@
 	struct netdev_private *np = netdev_priv(dev);
 	void __iomem * ioaddr = ns_ioaddr(dev);
 
-	if (np->hands_off)
+	/* Reading IntrStatus automatically acknowledges so don't do
+	 * that while interrupts are disabled, (for example, while a
+	 * poll is scheduled).  */
+	if (np->hands_off || !readl(ioaddr + IntrEnable))
 		return IRQ_NONE;
 
-	/* Reading automatically acknowledges. */
 	np->intr_status = readl(ioaddr + IntrStatus);
 
+	if (!np->intr_status)
+		return IRQ_NONE;
+
 	if (netif_msg_intr(np))
 		printk(KERN_DEBUG
 		       "%s: Interrupt, status %#08x, mask %#08x.\n",
 		       dev->name, np->intr_status,
 		       readl(ioaddr + IntrMask));
 
-	if (!np->intr_status)
-		return IRQ_NONE;
-
 	prefetch(&np->rx_skbuff[np->cur_rx % RX_RING_SIZE]);
 
 	if (netif_rx_schedule_prep(dev)) {
 		/* Disable interrupts and register for poll */
 		natsemi_irq_disable(dev);
 		__netif_rx_schedule(dev);
-	}
+	} else
+		printk(KERN_WARNING
+	       	       "%s: Ignoring interrupt, status %#08x, mask %#08x.\n",
+		       dev->name, np->intr_status,
+		       readl(ioaddr + IntrMask));
+
 	return IRQ_HANDLED;
 }
 
@@ -2156,6 +2163,20 @@
 	int work_done = 0;
 
 	do {
+		if (netif_msg_intr(np))
+			printk(KERN_DEBUG
+			       "%s: Poll, status %#08x, mask %#08x.\n",
+			       dev->name, np->intr_status,
+			       readl(ioaddr + IntrMask));
+
+		/* netdev_rx() may read IntrStatus again if the RX state
+		 * machine falls over so do it first. */
+		if (np->intr_status &
+		    (IntrRxDone | IntrRxIntr | RxStatusFIFOOver |
+		     IntrRxErr | IntrRxOverrun)) {
+			netdev_rx(dev, &work_done, work_to_do);
+		}
+
 		if (np->intr_status &
 		    (IntrTxDone | IntrTxIntr | IntrTxIdle | IntrTxErr)) {
 			spin_lock(&np->lock);
@@ -2167,12 +2188,6 @@
 		if (np->intr_status & IntrAbnormalSummary)
 			netdev_error(dev, np->intr_status);
 
-		if (np->intr_status &
-		    (IntrRxDone | IntrRxIntr | RxStatusFIFOOver |
-		     IntrRxErr | IntrRxOverrun)) {
-			netdev_rx(dev, &work_done, work_to_do);
-		}
-
 		*budget -= work_done;
 		dev->quota -= work_done;
 
@@ -2399,19 +2414,8 @@
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void natsemi_poll_controller(struct net_device *dev)
 {
-	struct netdev_private *np = netdev_priv(dev);
-
 	disable_irq(dev->irq);
-
-	/*
-	 * A real interrupt might have already reached us at this point
-	 * but NAPI might still haven't called us back.  As the interrupt
-	 * status register is cleared by reading, we should prevent an
-	 * interrupt loss in this case...
-	 */
-	if (!np->intr_status)
-		intr_handler(dev->irq, dev);
-
+	intr_handler(dev->irq, dev);
 	enable_irq(dev->irq);
 }
 #endif
@@ -3071,7 +3075,7 @@
 		 * Could be used to send a netlink message.
 		 */
 		writel(WOLPkt | LinkChange, ioaddr + IntrMask);
-		writel(1, ioaddr + IntrEnable);
+		natsemi_irq_enable(dev);
 	}
 }
 
@@ -3202,7 +3206,7 @@
 		disable_irq(dev->irq);
 		spin_lock_irq(&np->lock);
 
-		writel(0, ioaddr + IntrEnable);
+		natsemi_irq_disable(dev);
 		np->hands_off = 1;
 		natsemi_stop_rxtx(dev);
 		netif_stop_queue(dev);
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 81742e4..dd8ce35 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -232,6 +232,7 @@
 #define MPORT_SINGLE_FUNCTION_MODE 0x1111
 
 extern unsigned long long netxen_dma_mask;
+extern unsigned long last_schedule_time;
 
 /*
  * NetXen host-peg signal message structure
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index 986ef98..ee1b5a2 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -462,6 +462,7 @@
 		}
 		printk(KERN_INFO "%s: flash unlocked. \n", 
 			netxen_nic_driver_name);
+		last_schedule_time = jiffies;
 		ret = netxen_flash_erase_secondary(adapter);
 		if (ret != FLASH_SUCCESS) {
 			printk(KERN_ERR "%s: Flash erase failed.\n", 
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index a2877f3..6537574 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -228,7 +228,7 @@
 			    &adapter->ctx_desc_pdev);
 
 	printk("ctx_desc_phys_addr: 0x%llx\n",
-	       (u64) adapter->ctx_desc_phys_addr);
+	       (unsigned long long) adapter->ctx_desc_phys_addr);
 	if (addr == NULL) {
 		DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
 		err = -ENOMEM;
@@ -247,7 +247,8 @@
 			    adapter->max_tx_desc_count,
 			    (dma_addr_t *) & hw->cmd_desc_phys_addr,
 			    &adapter->ahw.cmd_desc_pdev);
-	printk("cmd_desc_phys_addr: 0x%llx\n", (u64) hw->cmd_desc_phys_addr);
+	printk("cmd_desc_phys_addr: 0x%llx\n",
+	       (unsigned long long) hw->cmd_desc_phys_addr);
 
 	if (addr == NULL) {
 		DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
@@ -821,7 +822,10 @@
 {
 	struct netxen_adapter *adapter = port->adapter;
 	new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE;
-	netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu);
+	if (port->portnum == 0)
+	    netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu);
+	else if (port->portnum == 1)
+	    netxen_nic_write_w0(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE, new_mtu);
 	return 0;
 }
 
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 586d32b..eff965d 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -42,6 +42,8 @@
 	u32 data;
 };
 
+unsigned long last_schedule_time;
+
 #define NETXEN_MAX_CRB_XFORM 60
 static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM];
 #define NETXEN_ADDR_ERROR (0xffffffff)
@@ -404,9 +406,14 @@
 static inline int
 do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
 {
+	if (jiffies > (last_schedule_time + (8 * HZ))) {
+		last_schedule_time = jiffies;
+		schedule();
+	}
+
 	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
 	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
-	udelay(70);		/* prevent bursting on CRB */
+	udelay(100);		/* prevent bursting on CRB */
 	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
 	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb);
 	if (netxen_wait_rom_done(adapter)) {
@@ -415,7 +422,7 @@
 	}
 	/* reset abyte_cnt and dummy_byte_cnt */
 	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
-	udelay(70);		/* prevent bursting on CRB */
+	udelay(100);		/* prevent bursting on CRB */
 	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
 
 	*valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA);
@@ -431,6 +438,7 @@
 
 	for (addridx = addr; addridx < (addr + size); addridx += 4) {
 		ret = do_rom_fast_read(adapter, addridx, (int *)bytes);
+		*(int *)bytes = cpu_to_le32(*(int *)bytes);
 		if (ret != 0)
 			break;
 		bytes += 4;
@@ -490,7 +498,7 @@
 		int timeout = 0;
 		int data;
 
-		data = *(u32*)bytes;
+		data = le32_to_cpu((*(u32*)bytes));
 
 		ret = do_rom_fast_write(adapter, addridx, data);
 		if (ret < 0)
diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c
index 00ca0fd..6ca4e4f 100644
--- a/drivers/net/pci-skeleton.c
+++ b/drivers/net/pci-skeleton.c
@@ -710,8 +710,8 @@
 		tp->chipset,
 		rtl_chip_info[tp->chipset].name);
 
-	i = register_netdev (dev);
-	if (i)
+	rc = register_netdev (dev);
+	if (rc)
 		goto err_out_unmap;
 
 	DPRINTK ("EXIT, returning 0\n");
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
index a956a51..1060154 100644
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -138,7 +138,7 @@
 
 ======================================================================*/
 
-static int ibmtr_attach(struct pcmcia_device *link)
+static int __devinit ibmtr_attach(struct pcmcia_device *link)
 {
     ibmtr_dev_t *info;
     struct net_device *dev;
@@ -217,7 +217,7 @@
 #define CS_CHECK(fn, ret) \
 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 
-static int ibmtr_config(struct pcmcia_device *link)
+static int __devinit ibmtr_config(struct pcmcia_device *link)
 {
     ibmtr_dev_t *info = link->priv;
     struct net_device *dev = info->dev;
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 11b575f..ef58e41 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -2544,6 +2544,9 @@
 	ppp->active_filter = NULL;
 #endif /* CONFIG_PPP_FILTER */
 
+	if (ppp->xmit_pending)
+		kfree_skb(ppp->xmit_pending);
+
 	kfree(ppp);
 }
 
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index d3f65da..a8246eb 100755
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -1691,6 +1691,27 @@
 /*
  * Caller holds hw_lock.
  */
+static void ql_update_small_bufq_prod_index(struct ql3_adapter *qdev)
+{
+	struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers;
+	if (qdev->small_buf_release_cnt >= 16) {
+		while (qdev->small_buf_release_cnt >= 16) {
+			qdev->small_buf_q_producer_index++;
+
+			if (qdev->small_buf_q_producer_index ==
+			    NUM_SBUFQ_ENTRIES)
+				qdev->small_buf_q_producer_index = 0;
+			qdev->small_buf_release_cnt -= 8;
+		}
+		wmb();
+		writel(qdev->small_buf_q_producer_index,
+			&port_regs->CommonRegs.rxSmallQProducerIndex);
+	}
+}
+
+/*
+ * Caller holds hw_lock.
+ */
 static void ql_update_lrg_bufq_prod_index(struct ql3_adapter *qdev)
 {
 	struct bufq_addr_element *lrg_buf_q_ele;
@@ -1732,13 +1753,10 @@
 				lrg_buf_q_ele = qdev->lrg_buf_q_virt_addr;
 			}
 		}
-
+		wmb();
 		qdev->lrg_buf_next_free = lrg_buf_q_ele;
-
-		ql_write_common_reg(qdev,
-				    &port_regs->CommonRegs.
-				    rxLargeQProducerIndex,
-				    qdev->lrg_buf_q_producer_index);
+		writel(qdev->lrg_buf_q_producer_index,
+			&port_regs->CommonRegs.rxLargeQProducerIndex);
 	}
 }
 
@@ -1915,17 +1933,18 @@
 		u16 checksum = le16_to_cpu(ib_ip_rsp_ptr->checksum);
 		if (checksum & 
 			(IB_IP_IOCB_RSP_3032_ICE | 
-			 IB_IP_IOCB_RSP_3032_CE | 
-			 IB_IP_IOCB_RSP_3032_NUC)) {
+			 IB_IP_IOCB_RSP_3032_CE)) { 
 			printk(KERN_ERR
 			       "%s: Bad checksum for this %s packet, checksum = %x.\n",
 			       __func__,
 			       ((checksum & 
 				IB_IP_IOCB_RSP_3032_TCP) ? "TCP" :
 				"UDP"),checksum);
-		} else if (checksum & IB_IP_IOCB_RSP_3032_TCP) {
+		} else if ((checksum & IB_IP_IOCB_RSP_3032_TCP) ||
+				(checksum & IB_IP_IOCB_RSP_3032_UDP &&
+				!(checksum & IB_IP_IOCB_RSP_3032_NUC))) {
 			skb2->ip_summed = CHECKSUM_UNNECESSARY;
-		} 
+		}
 	}
 	skb2->dev = qdev->ndev;
 	skb2->protocol = eth_type_trans(skb2, qdev->ndev);
@@ -1944,16 +1963,12 @@
 static int ql_tx_rx_clean(struct ql3_adapter *qdev,
 			  int *tx_cleaned, int *rx_cleaned, int work_to_do)
 {
-	struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers;
 	struct net_rsp_iocb *net_rsp;
 	struct net_device *ndev = qdev->ndev;
-	unsigned long hw_flags;
 	int work_done = 0;
 
-	u32 rsp_producer_index = le32_to_cpu(*(qdev->prsp_producer_index));
-
 	/* While there are entries in the completion queue. */
-	while ((rsp_producer_index !=
+	while ((le32_to_cpu(*(qdev->prsp_producer_index)) !=
 		qdev->rsp_consumer_index) && (work_done < work_to_do)) {
 
 		net_rsp = qdev->rsp_current;
@@ -2009,33 +2024,7 @@
 		work_done = *tx_cleaned + *rx_cleaned;
 	}
 
-	if(work_done) {
-		spin_lock_irqsave(&qdev->hw_lock, hw_flags);
-
-		ql_update_lrg_bufq_prod_index(qdev);
-
-		if (qdev->small_buf_release_cnt >= 16) {
-			while (qdev->small_buf_release_cnt >= 16) {
-				qdev->small_buf_q_producer_index++;
-
-				if (qdev->small_buf_q_producer_index ==
-				    NUM_SBUFQ_ENTRIES)
-					qdev->small_buf_q_producer_index = 0;
-				qdev->small_buf_release_cnt -= 8;
-			}
-
-			wmb();
-			ql_write_common_reg(qdev,
-					    &port_regs->CommonRegs.
-					    rxSmallQProducerIndex,
-					    qdev->small_buf_q_producer_index);
-
-		}
-
-		spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
-	}
-
-	return *tx_cleaned + *rx_cleaned;
+	return work_done;
 }
 
 static int ql_poll(struct net_device *ndev, int *budget)
@@ -2059,9 +2048,10 @@
 		netif_rx_complete(ndev);
 
 		spin_lock_irqsave(&qdev->hw_lock, hw_flags);
-		ql_write_common_reg(qdev,
-				    &port_regs->CommonRegs.rspQConsumerIndex,
-				    qdev->rsp_consumer_index);
+		ql_update_small_bufq_prod_index(qdev);
+		ql_update_lrg_bufq_prod_index(qdev);
+		writel(qdev->rsp_consumer_index,
+			    &port_regs->CommonRegs.rspQConsumerIndex);
 		spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
 
 		ql_enable_interrupts(qdev);
@@ -2217,12 +2207,7 @@
 	int seg_cnt, seg = 0;
 	int frag_cnt = (int)skb_shinfo(skb)->nr_frags;
 
-	seg_cnt = tx_cb->seg_count = ql_get_seg_count(qdev,
-						      (skb_shinfo(skb)->nr_frags));
-	if(seg_cnt == -1) {
-		printk(KERN_ERR PFX"%s: invalid segment count!\n",__func__);
-		return NETDEV_TX_BUSY;
-	}
+	seg_cnt = tx_cb->seg_count;
 	/*
 	 * Map the skb buffer first.
 	 */
@@ -2278,7 +2263,7 @@
 				pci_unmap_addr_set(&tx_cb->map[seg], mapaddr,
 						   map);
 				pci_unmap_len_set(&tx_cb->map[seg], maplen,
-						  len);
+						  sizeof(struct oal));
 				oal_entry = (struct oal_entry *)oal;
 				oal++;
 				seg++;
@@ -2380,6 +2365,7 @@
 	}
 	
 	mac_iocb_ptr = tx_cb->queue_entry;
+	memset((void *)mac_iocb_ptr, 0, sizeof(struct ob_mac_iocb_req));
 	mac_iocb_ptr->opcode = qdev->mac_ob_opcode;
 	mac_iocb_ptr->flags = OB_MAC_IOCB_REQ_X;
 	mac_iocb_ptr->flags |= qdev->mb_bit_mask;
@@ -3054,15 +3040,6 @@
 			goto out;
 		}
 
-		if (qdev->mac_index)
-			ql_write_page0_reg(qdev,
-					   &port_regs->mac1MaxFrameLengthReg,
-					   qdev->max_frame_size);
-		else
-			ql_write_page0_reg(qdev,
-					   &port_regs->mac0MaxFrameLengthReg,
-					   qdev->max_frame_size);
-
 		value = qdev->nvram_data.tcpMaxWindowSize;
 		ql_write_page0_reg(qdev, &port_regs->tcpMaxWindow, value);
 
@@ -3082,6 +3059,14 @@
 		ql_sem_unlock(qdev, QL_FLASH_SEM_MASK);
 	}
 
+	if (qdev->mac_index)
+		ql_write_page0_reg(qdev,
+				   &port_regs->mac1MaxFrameLengthReg,
+				   qdev->max_frame_size);
+	else
+		ql_write_page0_reg(qdev,
+					   &port_regs->mac0MaxFrameLengthReg,
+					   qdev->max_frame_size);
 
 	if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK,
 			(QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) *
@@ -3152,7 +3137,8 @@
 	if (qdev->device_id == QL3032_DEVICE_ID) {
 		value =
 		    (QL3032_PORT_CONTROL_EF | QL3032_PORT_CONTROL_KIE |
-		     QL3032_PORT_CONTROL_EIv6 | QL3032_PORT_CONTROL_EIv4);
+		     QL3032_PORT_CONTROL_EIv6 | QL3032_PORT_CONTROL_EIv4 |
+			QL3032_PORT_CONTROL_ET);
 		ql_write_page0_reg(qdev, &port_regs->functionControl,
 				   ((value << 16) | value));
 	} else {
diff --git a/drivers/net/qla3xxx.h b/drivers/net/qla3xxx.h
index 34cd658..0203f88 100755
--- a/drivers/net/qla3xxx.h
+++ b/drivers/net/qla3xxx.h
@@ -1014,8 +1014,7 @@
 
 /* Transmit and Receive Buffers */
 #define NUM_LBUFQ_ENTRIES   	128
-#define JUMBO_NUM_LBUFQ_ENTRIES   	\
-(NUM_LBUFQ_ENTRIES/(JUMBO_MTU_SIZE/NORMAL_MTU_SIZE))
+#define JUMBO_NUM_LBUFQ_ENTRIES 32
 #define NUM_SBUFQ_ENTRIES   	64
 #define QL_SMALL_BUFFER_SIZE    32
 #define QL_ADDR_ELE_PER_BUFQ_ENTRY \
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 15d954e50..6a77b8a 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -66,6 +66,7 @@
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
 
+#include <asm/system.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 
@@ -486,6 +487,7 @@
 				void __iomem *);
 static int rtl8169_change_mtu(struct net_device *dev, int new_mtu);
 static void rtl8169_down(struct net_device *dev);
+static void rtl8169_rx_clear(struct rtl8169_private *tp);
 
 #ifdef CONFIG_R8169_NAPI
 static int rtl8169_poll(struct net_device *dev, int *budget);
@@ -572,8 +574,8 @@
 {
 	unsigned int val;
 
-	mdio_write(ioaddr, MII_BMCR, BMCR_RESET);
-	val = mdio_read(ioaddr, MII_BMCR);
+	val = mdio_read(ioaddr, MII_BMCR) | BMCR_RESET;
+	mdio_write(ioaddr, MII_BMCR, val & 0xffff);
 }
 
 static void rtl8169_check_link_status(struct net_device *dev,
@@ -1368,11 +1370,7 @@
 	    (tp->phy_version >= RTL_GIGA_PHY_VER_H))
 		return;
 
-	init_timer(timer);
-	timer->expires = jiffies + RTL8169_PHY_TIMEOUT;
-	timer->data = (unsigned long)(dev);
-	timer->function = rtl8169_phy_timer;
-	add_timer(timer);
+	mod_timer(timer, jiffies + RTL8169_PHY_TIMEOUT);
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -1685,6 +1683,10 @@
 	tp->mmio_addr = ioaddr;
 	tp->align = rtl_cfg_info[ent->driver_data].align;
 
+	init_timer(&tp->timer);
+	tp->timer.data = (unsigned long) dev;
+	tp->timer.function = rtl8169_phy_timer;
+
 	spin_lock_init(&tp->lock);
 
 	rc = register_netdev(dev);
@@ -1751,17 +1753,11 @@
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 	struct pci_dev *pdev = tp->pci_dev;
-	int retval;
+	int retval = -ENOMEM;
+
 
 	rtl8169_set_rxbufsize(tp, dev);
 
-	retval =
-	    request_irq(dev->irq, rtl8169_interrupt, IRQF_SHARED, dev->name, dev);
-	if (retval < 0)
-		goto out;
-
-	retval = -ENOMEM;
-
 	/*
 	 * Rx and Tx desscriptors needs 256 bytes alignment.
 	 * pci_alloc_consistent provides more.
@@ -1769,19 +1765,26 @@
 	tp->TxDescArray = pci_alloc_consistent(pdev, R8169_TX_RING_BYTES,
 					       &tp->TxPhyAddr);
 	if (!tp->TxDescArray)
-		goto err_free_irq;
+		goto out;
 
 	tp->RxDescArray = pci_alloc_consistent(pdev, R8169_RX_RING_BYTES,
 					       &tp->RxPhyAddr);
 	if (!tp->RxDescArray)
-		goto err_free_tx;
+		goto err_free_tx_0;
 
 	retval = rtl8169_init_ring(dev);
 	if (retval < 0)
-		goto err_free_rx;
+		goto err_free_rx_1;
 
 	INIT_DELAYED_WORK(&tp->task, NULL);
 
+	smp_mb();
+
+	retval = request_irq(dev->irq, rtl8169_interrupt, IRQF_SHARED,
+			     dev->name, dev);
+	if (retval < 0)
+		goto err_release_ring_2;
+
 	rtl8169_hw_start(dev);
 
 	rtl8169_request_timer(dev);
@@ -1790,14 +1793,14 @@
 out:
 	return retval;
 
-err_free_rx:
+err_release_ring_2:
+	rtl8169_rx_clear(tp);
+err_free_rx_1:
 	pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray,
 			    tp->RxPhyAddr);
-err_free_tx:
+err_free_tx_0:
 	pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray,
 			    tp->TxPhyAddr);
-err_free_irq:
-	free_irq(dev->irq, dev);
 	goto out;
 }
 
@@ -2887,7 +2890,7 @@
 	void __iomem *ioaddr = tp->mmio_addr;
 
 	if (!netif_running(dev))
-		goto out;
+		goto out_pci_suspend;
 
 	netif_device_detach(dev);
 	netif_stop_queue(dev);
@@ -2901,10 +2904,11 @@
 
 	spin_unlock_irq(&tp->lock);
 
+out_pci_suspend:
 	pci_save_state(pdev);
 	pci_enable_wake(pdev, pci_choose_state(pdev, state), tp->wol_enabled);
 	pci_set_power_state(pdev, pci_choose_state(pdev, state));
-out:
+
 	return 0;
 }
 
@@ -2912,15 +2916,15 @@
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 
+	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
+	pci_enable_wake(pdev, PCI_D0, 0);
+
 	if (!netif_running(dev))
 		goto out;
 
 	netif_device_attach(dev);
 
-	pci_set_power_state(pdev, PCI_D0);
-	pci_restore_state(pdev);
-	pci_enable_wake(pdev, PCI_D0, 0);
-
 	rtl8169_schedule_work(dev, rtl8169_reset_task);
 out:
 	return 0;
diff --git a/drivers/net/saa9730.c b/drivers/net/saa9730.c
index b269513..143958f 100644
--- a/drivers/net/saa9730.c
+++ b/drivers/net/saa9730.c
@@ -64,37 +64,37 @@
 
 static void evm_saa9730_enable_lan_int(struct lan_saa9730_private *lp)
 {
-	outl(readl(&lp->evm_saa9730_regs->InterruptBlock1) | EVM_LAN_INT,
-	     &lp->evm_saa9730_regs->InterruptBlock1);
-	outl(readl(&lp->evm_saa9730_regs->InterruptStatus1) | EVM_LAN_INT,
-	     &lp->evm_saa9730_regs->InterruptStatus1);
-	outl(readl(&lp->evm_saa9730_regs->InterruptEnable1) | EVM_LAN_INT |
-	     EVM_MASTER_EN, &lp->evm_saa9730_regs->InterruptEnable1);
+	writel(readl(&lp->evm_saa9730_regs->InterruptBlock1) | EVM_LAN_INT,
+	       &lp->evm_saa9730_regs->InterruptBlock1);
+	writel(readl(&lp->evm_saa9730_regs->InterruptStatus1) | EVM_LAN_INT,
+	       &lp->evm_saa9730_regs->InterruptStatus1);
+	writel(readl(&lp->evm_saa9730_regs->InterruptEnable1) | EVM_LAN_INT |
+	       EVM_MASTER_EN, &lp->evm_saa9730_regs->InterruptEnable1);
 }
 
 static void evm_saa9730_disable_lan_int(struct lan_saa9730_private *lp)
 {
-	outl(readl(&lp->evm_saa9730_regs->InterruptBlock1) & ~EVM_LAN_INT,
-	     &lp->evm_saa9730_regs->InterruptBlock1);
-	outl(readl(&lp->evm_saa9730_regs->InterruptEnable1) & ~EVM_LAN_INT,
-	     &lp->evm_saa9730_regs->InterruptEnable1);
+	writel(readl(&lp->evm_saa9730_regs->InterruptBlock1) & ~EVM_LAN_INT,
+	       &lp->evm_saa9730_regs->InterruptBlock1);
+	writel(readl(&lp->evm_saa9730_regs->InterruptEnable1) & ~EVM_LAN_INT,
+	       &lp->evm_saa9730_regs->InterruptEnable1);
 }
 
 static void evm_saa9730_clear_lan_int(struct lan_saa9730_private *lp)
 {
-	outl(EVM_LAN_INT, &lp->evm_saa9730_regs->InterruptStatus1);
+	writel(EVM_LAN_INT, &lp->evm_saa9730_regs->InterruptStatus1);
 }
 
 static void evm_saa9730_block_lan_int(struct lan_saa9730_private *lp)
 {
-	outl(readl(&lp->evm_saa9730_regs->InterruptBlock1) & ~EVM_LAN_INT,
-	     &lp->evm_saa9730_regs->InterruptBlock1);
+	writel(readl(&lp->evm_saa9730_regs->InterruptBlock1) & ~EVM_LAN_INT,
+	       &lp->evm_saa9730_regs->InterruptBlock1);
 }
 
 static void evm_saa9730_unblock_lan_int(struct lan_saa9730_private *lp)
 {
-	outl(readl(&lp->evm_saa9730_regs->InterruptBlock1) | EVM_LAN_INT,
-	     &lp->evm_saa9730_regs->InterruptBlock1);
+	writel(readl(&lp->evm_saa9730_regs->InterruptBlock1) | EVM_LAN_INT,
+	       &lp->evm_saa9730_regs->InterruptBlock1);
 }
 
 static void __attribute_used__ show_saa9730_regs(struct lan_saa9730_private *lp)
@@ -147,7 +147,7 @@
 	printk("lp->lan_saa9730_regs->RxStatus = %x\n",
 	       readl(&lp->lan_saa9730_regs->RxStatus));
 	for (i = 0; i < LAN_SAA9730_CAM_DWORDS; i++) {
-		outl(i, &lp->lan_saa9730_regs->CamAddress);
+		writel(i, &lp->lan_saa9730_regs->CamAddress);
 		printk("lp->lan_saa9730_regs->CamData = %x\n",
 		       readl(&lp->lan_saa9730_regs->CamData));
 	}
@@ -288,28 +288,27 @@
 	 * Set rx buffer A and rx buffer B to point to the first two buffer
 	 * spaces.
 	 */
-	outl(lp->dma_addr + rxoffset,
-	     &lp->lan_saa9730_regs->RxBuffA);
-	outl(lp->dma_addr + rxoffset +
-	     LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_RCV_Q_SIZE,
-	     &lp->lan_saa9730_regs->RxBuffB);
+	writel(lp->dma_addr + rxoffset, &lp->lan_saa9730_regs->RxBuffA);
+	writel(lp->dma_addr + rxoffset +
+	       LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_RCV_Q_SIZE,
+	       &lp->lan_saa9730_regs->RxBuffB);
 
 	/*
 	 * Set txm_buf_a and txm_buf_b to point to the first two buffer
 	 * space
 	 */
-	outl(lp->dma_addr + txoffset,
-	     &lp->lan_saa9730_regs->TxBuffA);
-	outl(lp->dma_addr + txoffset +
-	     LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_TXM_Q_SIZE,
-	     &lp->lan_saa9730_regs->TxBuffB);
+	writel(lp->dma_addr + txoffset,
+	       &lp->lan_saa9730_regs->TxBuffA);
+	writel(lp->dma_addr + txoffset +
+	       LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_TXM_Q_SIZE,
+	       &lp->lan_saa9730_regs->TxBuffB);
 
 	/* Set packet number */
-	outl((lp->DmaRcvPackets << PK_COUNT_RX_A_SHF) |
-	     (lp->DmaRcvPackets << PK_COUNT_RX_B_SHF) |
-	     (lp->DmaTxmPackets << PK_COUNT_TX_A_SHF) |
-	     (lp->DmaTxmPackets << PK_COUNT_TX_B_SHF),
-	     &lp->lan_saa9730_regs->PacketCount);
+	writel((lp->DmaRcvPackets << PK_COUNT_RX_A_SHF) |
+	       (lp->DmaRcvPackets << PK_COUNT_RX_B_SHF) |
+	       (lp->DmaTxmPackets << PK_COUNT_TX_A_SHF) |
+	       (lp->DmaTxmPackets << PK_COUNT_TX_B_SHF),
+	       &lp->lan_saa9730_regs->PacketCount);
 
 	return 0;
 
@@ -326,10 +325,10 @@
 
 	for (i = 0; i < LAN_SAA9730_CAM_DWORDS; i++) {
 		/* First set address to where data is written */
-		outl(i, &lp->lan_saa9730_regs->CamAddress);
-		outl((NetworkAddress[0] << 24) | (NetworkAddress[1] << 16)
-		     | (NetworkAddress[2] << 8) | NetworkAddress[3],
-		     &lp->lan_saa9730_regs->CamData);
+		writel(i, &lp->lan_saa9730_regs->CamAddress);
+		writel((NetworkAddress[0] << 24) | (NetworkAddress[1] << 16) |
+		       (NetworkAddress[2] << 8) | NetworkAddress[3],
+		       &lp->lan_saa9730_regs->CamData);
 		NetworkAddress += 4;
 	}
 	return 0;
@@ -365,8 +364,8 @@
 	}
 
 	/* Now set the control and address register. */
-	outl(MD_CA_BUSY | PHY_STATUS | PHY_ADDRESS << MD_CA_PHY_SHF,
-	     &lp->lan_saa9730_regs->StationMgmtCtl);
+	writel(MD_CA_BUSY | PHY_STATUS | PHY_ADDRESS << MD_CA_PHY_SHF,
+	       &lp->lan_saa9730_regs->StationMgmtCtl);
 
 	/* check link status, spin here till station is not busy */
 	i = 0;
@@ -391,23 +390,23 @@
 		/* Link is down, reset the PHY first. */
 
 		/* set PHY address = 'CONTROL' */
-		outl(PHY_ADDRESS << MD_CA_PHY_SHF | MD_CA_WR | PHY_CONTROL,
-		     &lp->lan_saa9730_regs->StationMgmtCtl);
+		writel(PHY_ADDRESS << MD_CA_PHY_SHF | MD_CA_WR | PHY_CONTROL,
+		       &lp->lan_saa9730_regs->StationMgmtCtl);
 
 		/* Wait for 1 ms. */
 		mdelay(1);
 
 		/* set 'CONTROL' = force reset and renegotiate */
-		outl(PHY_CONTROL_RESET | PHY_CONTROL_AUTO_NEG |
-		     PHY_CONTROL_RESTART_AUTO_NEG,
-		     &lp->lan_saa9730_regs->StationMgmtData);
+		writel(PHY_CONTROL_RESET | PHY_CONTROL_AUTO_NEG |
+		       PHY_CONTROL_RESTART_AUTO_NEG,
+		       &lp->lan_saa9730_regs->StationMgmtData);
 
 		/* Wait for 50 ms. */
 		mdelay(50);
 
 		/* set 'BUSY' to start operation */
-		outl(MD_CA_BUSY | PHY_ADDRESS << MD_CA_PHY_SHF | MD_CA_WR |
-		     PHY_CONTROL, &lp->lan_saa9730_regs->StationMgmtCtl);
+		writel(MD_CA_BUSY | PHY_ADDRESS << MD_CA_PHY_SHF | MD_CA_WR |
+		       PHY_CONTROL, &lp->lan_saa9730_regs->StationMgmtCtl);
 
 		/* await completion */
 		i = 0;
@@ -427,9 +426,9 @@
 
 		for (l = 0; l < 2; l++) {
 			/* set PHY address = 'STATUS' */
-			outl(MD_CA_BUSY | PHY_ADDRESS << MD_CA_PHY_SHF |
-			     PHY_STATUS,
-			     &lp->lan_saa9730_regs->StationMgmtCtl);
+			writel(MD_CA_BUSY | PHY_ADDRESS << MD_CA_PHY_SHF |
+			       PHY_STATUS,
+			       &lp->lan_saa9730_regs->StationMgmtCtl);
 
 			/* await completion */
 			i = 0;
@@ -462,35 +461,35 @@
 static int lan_saa9730_control_init(struct lan_saa9730_private *lp)
 {
 	/* Initialize DMA control register. */
-	outl((LANMB_ANY << DMA_CTL_MAX_XFER_SHF) |
-	     (LANEND_LITTLE << DMA_CTL_ENDIAN_SHF) |
-	     (LAN_SAA9730_RCV_Q_INT_THRESHOLD << DMA_CTL_RX_INT_COUNT_SHF)
-	     | DMA_CTL_RX_INT_TO_EN | DMA_CTL_RX_INT_EN |
-	     DMA_CTL_MAC_RX_INT_EN | DMA_CTL_MAC_TX_INT_EN,
-	     &lp->lan_saa9730_regs->LanDmaCtl);
+	writel((LANMB_ANY << DMA_CTL_MAX_XFER_SHF) |
+	       (LANEND_LITTLE << DMA_CTL_ENDIAN_SHF) |
+	       (LAN_SAA9730_RCV_Q_INT_THRESHOLD << DMA_CTL_RX_INT_COUNT_SHF)
+	       | DMA_CTL_RX_INT_TO_EN | DMA_CTL_RX_INT_EN |
+	       DMA_CTL_MAC_RX_INT_EN | DMA_CTL_MAC_TX_INT_EN,
+	       &lp->lan_saa9730_regs->LanDmaCtl);
 
 	/* Initial MAC control register. */
-	outl((MACCM_MII << MAC_CONTROL_CONN_SHF) | MAC_CONTROL_FULL_DUP,
-	     &lp->lan_saa9730_regs->MacCtl);
+	writel((MACCM_MII << MAC_CONTROL_CONN_SHF) | MAC_CONTROL_FULL_DUP,
+	       &lp->lan_saa9730_regs->MacCtl);
 
 	/* Initialize CAM control register. */
-	outl(CAM_CONTROL_COMP_EN | CAM_CONTROL_BROAD_ACC,
-	     &lp->lan_saa9730_regs->CamCtl);
+	writel(CAM_CONTROL_COMP_EN | CAM_CONTROL_BROAD_ACC,
+	       &lp->lan_saa9730_regs->CamCtl);
 
 	/*
 	 * Initialize CAM enable register, only turn on first entry, should
 	 * contain own addr.
 	 */
-	outl(0x0001, &lp->lan_saa9730_regs->CamEnable);
+	writel(0x0001, &lp->lan_saa9730_regs->CamEnable);
 
 	/* Initialize Tx control register */
-	outl(TX_CTL_EN_COMP, &lp->lan_saa9730_regs->TxCtl);
+	writel(TX_CTL_EN_COMP, &lp->lan_saa9730_regs->TxCtl);
 
 	/* Initialize Rcv control register */
-	outl(RX_CTL_STRIP_CRC, &lp->lan_saa9730_regs->RxCtl);
+	writel(RX_CTL_STRIP_CRC, &lp->lan_saa9730_regs->RxCtl);
 
 	/* Reset DMA engine */
-	outl(DMA_TEST_SW_RESET, &lp->lan_saa9730_regs->DmaTest);
+	writel(DMA_TEST_SW_RESET, &lp->lan_saa9730_regs->DmaTest);
 
 	return 0;
 }
@@ -500,14 +499,14 @@
 	int i;
 
 	/* Stop DMA first */
-	outl(readl(&lp->lan_saa9730_regs->LanDmaCtl) &
-	     ~(DMA_CTL_EN_TX_DMA | DMA_CTL_EN_RX_DMA),
-	     &lp->lan_saa9730_regs->LanDmaCtl);
+	writel(readl(&lp->lan_saa9730_regs->LanDmaCtl) &
+	       ~(DMA_CTL_EN_TX_DMA | DMA_CTL_EN_RX_DMA),
+	       &lp->lan_saa9730_regs->LanDmaCtl);
 
 	/* Set the SW Reset bits in DMA and MAC control registers */
-	outl(DMA_TEST_SW_RESET, &lp->lan_saa9730_regs->DmaTest);
-	outl(readl(&lp->lan_saa9730_regs->MacCtl) | MAC_CONTROL_RESET,
-	     &lp->lan_saa9730_regs->MacCtl);
+	writel(DMA_TEST_SW_RESET, &lp->lan_saa9730_regs->DmaTest);
+	writel(readl(&lp->lan_saa9730_regs->MacCtl) | MAC_CONTROL_RESET,
+	       &lp->lan_saa9730_regs->MacCtl);
 
 	/*
 	 * Wait for MAC reset to have finished. The reset bit is auto cleared
@@ -532,8 +531,8 @@
 	/* Stop lan controller. */
 	lan_saa9730_stop(lp);
 
-	outl(LAN_SAA9730_DEFAULT_TIME_OUT_CNT,
-	     &lp->lan_saa9730_regs->Timeout);
+	writel(LAN_SAA9730_DEFAULT_TIME_OUT_CNT,
+	       &lp->lan_saa9730_regs->Timeout);
 
 	return 0;
 }
@@ -552,19 +551,19 @@
 	lp->PendingTxmPacketIndex = 0;
 	lp->PendingTxmBufferIndex = 0;
 
-	outl(readl(&lp->lan_saa9730_regs->LanDmaCtl) | DMA_CTL_EN_TX_DMA |
-	     DMA_CTL_EN_RX_DMA, &lp->lan_saa9730_regs->LanDmaCtl);
+	writel(readl(&lp->lan_saa9730_regs->LanDmaCtl) | DMA_CTL_EN_TX_DMA |
+	       DMA_CTL_EN_RX_DMA, &lp->lan_saa9730_regs->LanDmaCtl);
 
 	/* For Tx, turn on MAC then DMA */
-	outl(readl(&lp->lan_saa9730_regs->TxCtl) | TX_CTL_TX_EN,
-	     &lp->lan_saa9730_regs->TxCtl);
+	writel(readl(&lp->lan_saa9730_regs->TxCtl) | TX_CTL_TX_EN,
+	       &lp->lan_saa9730_regs->TxCtl);
 
 	/* For Rx, turn on DMA then MAC */
-	outl(readl(&lp->lan_saa9730_regs->RxCtl) | RX_CTL_RX_EN,
-	     &lp->lan_saa9730_regs->RxCtl);
+	writel(readl(&lp->lan_saa9730_regs->RxCtl) | RX_CTL_RX_EN,
+	       &lp->lan_saa9730_regs->RxCtl);
 
 	/* Set Ok2Use to let hardware own the buffers.	*/
-	outl(OK2USE_RX_A | OK2USE_RX_B, &lp->lan_saa9730_regs->Ok2Use);
+	writel(OK2USE_RX_A | OK2USE_RX_B, &lp->lan_saa9730_regs->Ok2Use);
 
 	return 0;
 }
@@ -587,7 +586,7 @@
 		printk("lan_saa9730_tx interrupt\n");
 
 	/* Clear interrupt. */
-	outl(DMA_STATUS_MAC_TX_INT, &lp->lan_saa9730_regs->DmaStatus);
+	writel(DMA_STATUS_MAC_TX_INT, &lp->lan_saa9730_regs->DmaStatus);
 
 	while (1) {
 		pPacket = lp->TxmBuffer[lp->PendingTxmBufferIndex]
@@ -660,8 +659,8 @@
 		printk("lan_saa9730_rx interrupt\n");
 
 	/* Clear receive interrupts. */
-	outl(DMA_STATUS_MAC_RX_INT | DMA_STATUS_RX_INT |
-	     DMA_STATUS_RX_TO_INT, &lp->lan_saa9730_regs->DmaStatus);
+	writel(DMA_STATUS_MAC_RX_INT | DMA_STATUS_RX_INT |
+	       DMA_STATUS_RX_TO_INT, &lp->lan_saa9730_regs->DmaStatus);
 
 	/* Address next packet */
 	BufferIndex = lp->NextRcvBufferIndex;
@@ -725,8 +724,8 @@
 		*pPacket = cpu_to_le32(RXSF_READY << RX_STAT_CTL_OWNER_SHF);
 
 		/* Make sure A or B is available to hardware as appropriate. */
-		outl(BufferIndex ? OK2USE_RX_B : OK2USE_RX_A,
-		     &lp->lan_saa9730_regs->Ok2Use);
+		writel(BufferIndex ? OK2USE_RX_B : OK2USE_RX_A,
+		       &lp->lan_saa9730_regs->Ok2Use);
 
 		/* Go to next packet in sequence. */
 		lp->NextRcvPacketIndex++;
@@ -844,8 +843,8 @@
 			    (len << TX_STAT_CTL_LENGTH_SHF));
 
 	/* Make sure A or B is available to hardware as appropriate. */
-	outl(BufferIndex ? OK2USE_TX_B : OK2USE_TX_A,
-	     &lp->lan_saa9730_regs->Ok2Use);
+	writel(BufferIndex ? OK2USE_TX_B : OK2USE_TX_A,
+	       &lp->lan_saa9730_regs->Ok2Use);
 
 	return 0;
 }
@@ -938,15 +937,15 @@
 
 	if (dev->flags & IFF_PROMISC) {
 		/* accept all packets */
-		outl(CAM_CONTROL_COMP_EN | CAM_CONTROL_STATION_ACC |
-		     CAM_CONTROL_GROUP_ACC | CAM_CONTROL_BROAD_ACC,
-		     &lp->lan_saa9730_regs->CamCtl);
+		writel(CAM_CONTROL_COMP_EN | CAM_CONTROL_STATION_ACC |
+		       CAM_CONTROL_GROUP_ACC | CAM_CONTROL_BROAD_ACC,
+		       &lp->lan_saa9730_regs->CamCtl);
 	} else {
 		if (dev->flags & IFF_ALLMULTI) {
 			/* accept all multicast packets */
-			outl(CAM_CONTROL_COMP_EN | CAM_CONTROL_GROUP_ACC |
-			     CAM_CONTROL_BROAD_ACC,
-			     &lp->lan_saa9730_regs->CamCtl);
+			writel(CAM_CONTROL_COMP_EN | CAM_CONTROL_GROUP_ACC |
+			       CAM_CONTROL_BROAD_ACC,
+			       &lp->lan_saa9730_regs->CamCtl);
 		} else {
 			/*
 			 * Will handle the multicast stuff later. -carstenl
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 1eae16b..103c317 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -243,7 +243,7 @@
 	 * Controller-specific things
 	 */
 
-	volatile void __iomem *sbm_base;          /* MAC's base address */
+	void __iomem		*sbm_base;          /* MAC's base address */
 	sbmac_state_t    sbm_state;         /* current state */
 
 	volatile void __iomem	*sbm_macenable;	/* MAC Enable Register */
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c
index 4a926f2..c32c21a 100644
--- a/drivers/net/sc92031.c
+++ b/drivers/net/sc92031.c
@@ -964,7 +964,7 @@
 		goto out;
 	}
 
-	spin_lock_bh(&priv->lock);
+	spin_lock(&priv->lock);
 
 	if (unlikely(!netif_carrier_ok(dev))) {
 		err = -ENOLINK;
@@ -1005,7 +1005,7 @@
 		netif_stop_queue(dev);
 
 out_unlock:
-	spin_unlock_bh(&priv->lock);
+	spin_unlock(&priv->lock);
 
 out:
 	dev_kfree_skb(skb);
@@ -1042,12 +1042,12 @@
 	priv->pm_config = 0;
 
 	/* Interrupts already disabled by sc92031_stop or sc92031_probe */
-	spin_lock(&priv->lock);
+	spin_lock_bh(&priv->lock);
 
 	_sc92031_reset(dev);
 	mmiowb();
 
-	spin_unlock(&priv->lock);
+	spin_unlock_bh(&priv->lock);
 	sc92031_enable_interrupts(dev);
 
 	if (netif_carrier_ok(dev))
@@ -1077,13 +1077,13 @@
 	/* Disable interrupts, stop Tx and Rx. */
 	sc92031_disable_interrupts(dev);
 
-	spin_lock(&priv->lock);
+	spin_lock_bh(&priv->lock);
 
 	_sc92031_disable_tx_rx(dev);
 	_sc92031_tx_clear(dev);
 	mmiowb();
 
-	spin_unlock(&priv->lock);
+	spin_unlock_bh(&priv->lock);
 
 	free_irq(pdev->irq, dev);
 	pci_free_consistent(pdev, TX_BUF_TOT_LEN, priv->tx_bufs,
@@ -1539,13 +1539,13 @@
 	/* Disable interrupts, stop Tx and Rx. */
 	sc92031_disable_interrupts(dev);
 
-	spin_lock(&priv->lock);
+	spin_lock_bh(&priv->lock);
 
 	_sc92031_disable_tx_rx(dev);
 	_sc92031_tx_clear(dev);
 	mmiowb();
 
-	spin_unlock(&priv->lock);
+	spin_unlock_bh(&priv->lock);
 
 out:
 	pci_set_power_state(pdev, pci_choose_state(pdev, state));
@@ -1565,12 +1565,12 @@
 		goto out;
 
 	/* Interrupts already disabled by sc92031_suspend */
-	spin_lock(&priv->lock);
+	spin_lock_bh(&priv->lock);
 
 	_sc92031_reset(dev);
 	mmiowb();
 
-	spin_unlock(&priv->lock);
+	spin_unlock_bh(&priv->lock);
 	sc92031_enable_interrupts(dev);
 
 	netif_device_attach(dev);
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index b08508b..34463ce 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -324,6 +324,7 @@
 	u32 feature;
 } mii_chip_table[] = {
 	{ "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, F_PHY_BCM5461 },
+	{ "Broadcom PHY AC131",   { 0x0143, 0xbc70 }, LAN, 0 },
 	{ "Agere PHY ET1101B",    { 0x0282, 0xf010 }, LAN, 0 },
 	{ "Marvell PHY 88E1111",  { 0x0141, 0x0cc0 }, LAN, F_PHY_88E1111 },
 	{ "Realtek PHY RTL8201",  { 0x0000, 0x8200 }, LAN, 0 },
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index eea75a4..d476a3c 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -105,7 +105,8 @@
 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 irqmask[] = { IS_R1_F|IS_XA1_F, IS_R2_F|IS_XA2_F };
+static const u32 napimask[] = { IS_R1_F|IS_XA1_F, IS_R2_F|IS_XA2_F };
+static const u32 portmask[] = { IS_PORT_1, IS_PORT_2 };
 
 static int skge_get_regs_len(struct net_device *dev)
 {
@@ -162,27 +163,46 @@
 {
 	struct skge_hw *hw = skge->hw;
 	int port = skge->port;
-	enum pause_control save_mode;
-	u32 ctrl;
+	u16 ctrl;
 
-	/* Bring hardware out of reset */
 	skge_write16(hw, B0_CTST, CS_RST_CLR);
 	skge_write16(hw, SK_REG(port, GMAC_LINK_CTRL), GMLC_RST_CLR);
 
-	skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
-	skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
+	/* Turn on Vaux */
+	skge_write8(hw, B0_POWER_CTRL,
+		    PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_ON | PC_VCC_OFF);
+
+	/* WA code for COMA mode -- clear PHY reset */
+	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
+	    hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
+		u32 reg = skge_read32(hw, B2_GP_IO);
+		reg |= GP_DIR_9;
+		reg &= ~GP_IO_9;
+		skge_write32(hw, B2_GP_IO, reg);
+	}
+
+	skge_write32(hw, SK_REG(port, GPHY_CTRL),
+		     GPC_DIS_SLEEP |
+		     GPC_HWCFG_M_3 | GPC_HWCFG_M_2 | GPC_HWCFG_M_1 | GPC_HWCFG_M_0 |
+		     GPC_ANEG_1 | GPC_RST_SET);
+
+	skge_write32(hw, SK_REG(port, GPHY_CTRL),
+		     GPC_DIS_SLEEP |
+		     GPC_HWCFG_M_3 | GPC_HWCFG_M_2 | GPC_HWCFG_M_1 | GPC_HWCFG_M_0 |
+		     GPC_ANEG_1 | GPC_RST_CLR);
+
+	skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
 
 	/* Force to 10/100 skge_reset will re-enable on resume	 */
-	save_mode = skge->flow_control;
-	skge->flow_control = FLOW_MODE_SYMMETRIC;
+	gm_phy_write(hw, port, PHY_MARV_AUNE_ADV,
+		     PHY_AN_100FULL | PHY_AN_100HALF |
+		     PHY_AN_10FULL | PHY_AN_10HALF| PHY_AN_CSMA);
+	/* no 1000 HD/FD */
+	gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, 0);
+	gm_phy_write(hw, port, PHY_MARV_CTRL,
+		     PHY_CT_RESET | PHY_CT_SPS_LSB | PHY_CT_ANE |
+		     PHY_CT_RE_CFG | PHY_CT_DUP_MD);
 
-	ctrl = skge->advertising;
-	skge->advertising &= ~(ADVERTISED_1000baseT_Half|ADVERTISED_1000baseT_Full);
-
-	skge_phy_reset(skge);
-
-	skge->flow_control = save_mode;
-	skge->advertising = ctrl;
 
 	/* Set GMAC to no flow control and auto update for speed/duplex */
 	gma_write16(hw, port, GM_GP_CTRL,
@@ -226,12 +246,10 @@
 	struct skge_port *skge = netdev_priv(dev);
 	struct skge_hw *hw = skge->hw;
 
-	if (wol->wolopts & wol_supported(hw))
+	if (wol->wolopts & ~wol_supported(hw))
 		return -EOPNOTSUPP;
 
 	skge->wol = wol->wolopts;
-	if (!netif_running(dev))
-		skge_wol_init(skge);
 	return 0;
 }
 
@@ -671,7 +689,7 @@
 	struct skge_hw *hw = skge->hw;
 	int port = skge->port;
 
-	mutex_lock(&hw->phy_mutex);
+	spin_lock_bh(&hw->phy_lock);
 	if (hw->chip_id == CHIP_ID_GENESIS) {
 		switch (mode) {
 		case LED_MODE_OFF:
@@ -742,7 +760,7 @@
 				     PHY_M_LED_MO_RX(MO_LED_ON));
 		}
 	}
-	mutex_unlock(&hw->phy_mutex);
+	spin_unlock_bh(&hw->phy_lock);
 }
 
 /* blink LED's for finding board */
@@ -1316,7 +1334,7 @@
 	xm_phy_write(hw, port, PHY_XMAC_CTRL, ctrl);
 
 	/* Poll PHY for status changes */
-	schedule_delayed_work(&skge->link_thread, LINK_HZ);
+	mod_timer(&skge->link_timer, jiffies + LINK_HZ);
 }
 
 static void xm_check_link(struct net_device *dev)
@@ -1391,10 +1409,9 @@
  * Since internal PHY is wired to a level triggered pin, can't
  * get an interrupt when carrier is detected.
  */
-static void xm_link_timer(struct work_struct *work)
+static void xm_link_timer(unsigned long arg)
 {
-	struct skge_port *skge =
-		container_of(work, struct skge_port, link_thread.work);
+	struct skge_port *skge = (struct skge_port *) arg;
 	struct net_device *dev = skge->netdev;
  	struct skge_hw *hw = skge->hw;
 	int port = skge->port;
@@ -1414,13 +1431,13 @@
 			goto nochange;
 	}
 
-	mutex_lock(&hw->phy_mutex);
+	spin_lock(&hw->phy_lock);
 	xm_check_link(dev);
-	mutex_unlock(&hw->phy_mutex);
+	spin_unlock(&hw->phy_lock);
 
 nochange:
 	if (netif_running(dev))
-		schedule_delayed_work(&skge->link_thread, LINK_HZ);
+		mod_timer(&skge->link_timer, jiffies + LINK_HZ);
 }
 
 static void genesis_mac_init(struct skge_hw *hw, int port)
@@ -2323,7 +2340,7 @@
 	netif_stop_queue(skge->netdev);
 	netif_carrier_off(skge->netdev);
 
-	mutex_lock(&hw->phy_mutex);
+	spin_lock_bh(&hw->phy_lock);
 	if (hw->chip_id == CHIP_ID_GENESIS) {
 		genesis_reset(hw, port);
 		genesis_mac_init(hw, port);
@@ -2331,7 +2348,7 @@
 		yukon_reset(hw, port);
 		yukon_init(hw, port);
 	}
-	mutex_unlock(&hw->phy_mutex);
+	spin_unlock_bh(&hw->phy_lock);
 
 	dev->set_multicast_list(dev);
 }
@@ -2354,12 +2371,12 @@
 		/* fallthru */
 	case SIOCGMIIREG: {
 		u16 val = 0;
-		mutex_lock(&hw->phy_mutex);
+		spin_lock_bh(&hw->phy_lock);
 		if (hw->chip_id == CHIP_ID_GENESIS)
 			err = __xm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val);
 		else
 			err = __gm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val);
-		mutex_unlock(&hw->phy_mutex);
+		spin_unlock_bh(&hw->phy_lock);
 		data->val_out = val;
 		break;
 	}
@@ -2368,14 +2385,14 @@
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
 
-		mutex_lock(&hw->phy_mutex);
+		spin_lock_bh(&hw->phy_lock);
 		if (hw->chip_id == CHIP_ID_GENESIS)
 			err = xm_phy_write(hw, skge->port, data->reg_num & 0x1f,
 				   data->val_in);
 		else
 			err = gm_phy_write(hw, skge->port, data->reg_num & 0x1f,
 				   data->val_in);
-		mutex_unlock(&hw->phy_mutex);
+		spin_unlock_bh(&hw->phy_lock);
 		break;
 	}
 	return err;
@@ -2481,12 +2498,12 @@
 		goto free_rx_ring;
 
 	/* Initialize MAC */
-	mutex_lock(&hw->phy_mutex);
+	spin_lock_bh(&hw->phy_lock);
 	if (hw->chip_id == CHIP_ID_GENESIS)
 		genesis_mac_init(hw, port);
 	else
 		yukon_mac_init(hw, port);
-	mutex_unlock(&hw->phy_mutex);
+	spin_unlock_bh(&hw->phy_lock);
 
 	/* Configure RAMbuffers */
 	chunk = hw->ram_size / ((hw->ports + 1)*2);
@@ -2504,6 +2521,11 @@
 	skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F);
 	skge_led(skge, LED_MODE_ON);
 
+	spin_lock_irq(&hw->hw_lock);
+	hw->intr_mask |= portmask[port];
+	skge_write32(hw, B0_IMSK, hw->intr_mask);
+	spin_unlock_irq(&hw->hw_lock);
+
 	netif_poll_enable(dev);
 	return 0;
 
@@ -2530,8 +2552,17 @@
 		printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
 
 	netif_stop_queue(dev);
+
 	if (hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC)
-		cancel_delayed_work(&skge->link_thread);
+		del_timer_sync(&skge->link_timer);
+
+	netif_poll_disable(dev);
+	netif_carrier_off(dev);
+
+	spin_lock_irq(&hw->hw_lock);
+	hw->intr_mask &= ~portmask[port];
+	skge_write32(hw, B0_IMSK, hw->intr_mask);
+	spin_unlock_irq(&hw->hw_lock);
 
 	skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF);
 	if (hw->chip_id == CHIP_ID_GENESIS)
@@ -2575,8 +2606,10 @@
 
 	skge_led(skge, LED_MODE_OFF);
 
-	netif_poll_disable(dev);
+	netif_tx_lock_bh(dev);
 	skge_tx_clean(dev);
+	netif_tx_unlock_bh(dev);
+
 	skge_rx_clean(skge);
 
 	kfree(skge->rx_ring.start);
@@ -2721,7 +2754,6 @@
 	struct skge_port *skge = netdev_priv(dev);
 	struct skge_element *e;
 
-	netif_tx_lock_bh(dev);
 	for (e = skge->tx_ring.to_clean; e != skge->tx_ring.to_use; e = e->next) {
 		struct skge_tx_desc *td = e->desc;
 		skge_tx_free(skge, e, td->control);
@@ -2730,7 +2762,6 @@
 
 	skge->tx_ring.to_clean = e;
 	netif_wake_queue(dev);
-	netif_tx_unlock_bh(dev);
 }
 
 static void skge_tx_timeout(struct net_device *dev)
@@ -3049,7 +3080,7 @@
 
 	spin_lock_irqsave(&hw->hw_lock, flags);
 	__netif_rx_complete(dev);
-	hw->intr_mask |= irqmask[skge->port];
+	hw->intr_mask |= napimask[skge->port];
   	skge_write32(hw, B0_IMSK, hw->intr_mask);
 	skge_read32(hw, B0_IMSK);
 	spin_unlock_irqrestore(&hw->hw_lock, flags);
@@ -3160,28 +3191,29 @@
 }
 
 /*
- * Interrupt from PHY are handled in work queue
+ * Interrupt from PHY are handled in tasklet (softirq)
  * because accessing phy registers requires spin wait which might
  * cause excess interrupt latency.
  */
-static void skge_extirq(struct work_struct *work)
+static void skge_extirq(unsigned long arg)
 {
-	struct skge_hw *hw = container_of(work, struct skge_hw, phy_work);
+	struct skge_hw *hw = (struct skge_hw *) arg;
 	int port;
 
-	mutex_lock(&hw->phy_mutex);
 	for (port = 0; port < hw->ports; port++) {
 		struct net_device *dev = hw->dev[port];
-		struct skge_port *skge = netdev_priv(dev);
 
 		if (netif_running(dev)) {
+			struct skge_port *skge = netdev_priv(dev);
+
+			spin_lock(&hw->phy_lock);
 			if (hw->chip_id != CHIP_ID_GENESIS)
 				yukon_phy_intr(skge);
 			else if (hw->phy_type == SK_PHY_BCOM)
 				bcom_phy_intr(skge);
+			spin_unlock(&hw->phy_lock);
 		}
 	}
-	mutex_unlock(&hw->phy_mutex);
 
 	spin_lock_irq(&hw->hw_lock);
 	hw->intr_mask |= IS_EXT_REG;
@@ -3206,7 +3238,7 @@
 	status &= hw->intr_mask;
 	if (status & IS_EXT_REG) {
 		hw->intr_mask &= ~IS_EXT_REG;
-		schedule_work(&hw->phy_work);
+		tasklet_schedule(&hw->phy_task);
 	}
 
 	if (status & (IS_XA1_F|IS_R1_F)) {
@@ -3275,24 +3307,35 @@
 	struct skge_hw *hw = skge->hw;
 	unsigned port = skge->port;
 	const struct sockaddr *addr = p;
+	u16 ctrl;
 
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 
-	mutex_lock(&hw->phy_mutex);
 	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
-	memcpy_toio(hw->regs + B2_MAC_1 + port*8,
-		    dev->dev_addr, ETH_ALEN);
-	memcpy_toio(hw->regs + B2_MAC_2 + port*8,
-		    dev->dev_addr, ETH_ALEN);
 
-	if (hw->chip_id == CHIP_ID_GENESIS)
-		xm_outaddr(hw, port, XM_SA, dev->dev_addr);
-	else {
-		gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr);
-		gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr);
+	if (!netif_running(dev)) {
+		memcpy_toio(hw->regs + B2_MAC_1 + port*8, dev->dev_addr, ETH_ALEN);
+		memcpy_toio(hw->regs + B2_MAC_2 + port*8, dev->dev_addr, ETH_ALEN);
+	} else {
+		/* disable Rx */
+		spin_lock_bh(&hw->phy_lock);
+		ctrl = gma_read16(hw, port, GM_GP_CTRL);
+		gma_write16(hw, port, GM_GP_CTRL, ctrl & ~GM_GPCR_RX_ENA);
+
+		memcpy_toio(hw->regs + B2_MAC_1 + port*8, dev->dev_addr, ETH_ALEN);
+		memcpy_toio(hw->regs + B2_MAC_2 + port*8, dev->dev_addr, ETH_ALEN);
+
+		if (hw->chip_id == CHIP_ID_GENESIS)
+			xm_outaddr(hw, port, XM_SA, dev->dev_addr);
+		else {
+			gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr);
+			gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr);
+		}
+
+		gma_write16(hw, port, GM_GP_CTRL, ctrl);
+		spin_unlock_bh(&hw->phy_lock);
 	}
-	mutex_unlock(&hw->phy_mutex);
 
 	return 0;
 }
@@ -3407,10 +3450,9 @@
 	else
 		hw->ram_size = t8 * 4096;
 
-	hw->intr_mask = IS_HW_ERR | IS_PORT_1;
-	if (hw->ports > 1)
-		hw->intr_mask |= IS_PORT_2;
+	hw->intr_mask = IS_HW_ERR;
 
+	/* Use PHY IRQ for all but fiber based Genesis board */
 	if (!(hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC))
 		hw->intr_mask |= IS_EXT_REG;
 
@@ -3478,14 +3520,12 @@
 
 	skge_write32(hw, B0_IMSK, hw->intr_mask);
 
-	mutex_lock(&hw->phy_mutex);
 	for (i = 0; i < hw->ports; i++) {
 		if (hw->chip_id == CHIP_ID_GENESIS)
 			genesis_reset(hw, i);
 		else
 			yukon_reset(hw, i);
 	}
-	mutex_unlock(&hw->phy_mutex);
 
 	return 0;
 }
@@ -3533,6 +3573,7 @@
 	skge->netdev = dev;
 	skge->hw = hw;
 	skge->msg_enable = netif_msg_init(debug, default_msg);
+
 	skge->tx_ring.count = DEFAULT_TX_RING_SIZE;
 	skge->rx_ring.count = DEFAULT_RX_RING_SIZE;
 
@@ -3549,7 +3590,7 @@
 	skge->port = port;
 
 	/* Only used for Genesis XMAC */
-	INIT_DELAYED_WORK(&skge->link_thread, xm_link_timer);
+	setup_timer(&skge->link_timer, xm_link_timer, (unsigned long) skge);
 
 	if (hw->chip_id != CHIP_ID_GENESIS) {
 		dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
@@ -3631,9 +3672,9 @@
 	}
 
 	hw->pdev = pdev;
-	mutex_init(&hw->phy_mutex);
-	INIT_WORK(&hw->phy_work, skge_extirq);
 	spin_lock_init(&hw->hw_lock);
+	spin_lock_init(&hw->phy_lock);
+	tasklet_init(&hw->phy_task, &skge_extirq, (unsigned long) hw);
 
 	hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000);
 	if (!hw->regs) {
@@ -3719,6 +3760,8 @@
 	dev0 = hw->dev[0];
 	unregister_netdev(dev0);
 
+	tasklet_disable(&hw->phy_task);
+
 	spin_lock_irq(&hw->hw_lock);
 	hw->intr_mask = 0;
 	skge_write32(hw, B0_IMSK, 0);
@@ -3741,21 +3784,6 @@
 }
 
 #ifdef CONFIG_PM
-static int vaux_avail(struct pci_dev *pdev)
-{
-	int pm_cap;
-
-	pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
-	if (pm_cap) {
-		u16 ctl;
-		pci_read_config_word(pdev, pm_cap + PCI_PM_PMC, &ctl);
-		if (ctl & PCI_PM_CAP_AUX_POWER)
-			return 1;
-	}
-	return 0;
-}
-
-
 static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct skge_hw *hw  = pci_get_drvdata(pdev);
@@ -3777,10 +3805,6 @@
 		wol |= skge->wol;
 	}
 
-	if (wol && vaux_avail(pdev))
-		skge_write8(hw, B0_POWER_CTRL,
-			    PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_ON | PC_VCC_OFF);
-
 	skge_write32(hw, B0_IMSK, 0);
 	pci_enable_wake(pdev, pci_choose_state(pdev, state), wol);
 	pci_set_power_state(pdev, pci_choose_state(pdev, state));
@@ -3826,6 +3850,28 @@
 }
 #endif
 
+static void skge_shutdown(struct pci_dev *pdev)
+{
+	struct skge_hw *hw  = pci_get_drvdata(pdev);
+	int i, wol = 0;
+
+	for (i = 0; i < hw->ports; i++) {
+		struct net_device *dev = hw->dev[i];
+		struct skge_port *skge = netdev_priv(dev);
+
+		if (skge->wol)
+			skge_wol_init(skge);
+		wol |= skge->wol;
+	}
+
+	pci_enable_wake(pdev, PCI_D3hot, wol);
+	pci_enable_wake(pdev, PCI_D3cold, wol);
+
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, PCI_D3hot);
+
+}
+
 static struct pci_driver skge_driver = {
 	.name =         DRV_NAME,
 	.id_table =     skge_id_table,
@@ -3835,6 +3881,7 @@
 	.suspend = 	skge_suspend,
 	.resume = 	skge_resume,
 #endif
+	.shutdown =	skge_shutdown,
 };
 
 static int __init skge_init_module(void)
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index e9354df..86467ae 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -2424,8 +2424,8 @@
 	u32	     	     ram_size;
 	u32	     	     ram_offset;
 	u16		     phy_addr;
-	struct work_struct   phy_work;
-	struct mutex	     phy_mutex;
+	spinlock_t	     phy_lock;
+	struct tasklet_struct phy_task;
 };
 
 enum pause_control {
@@ -2457,7 +2457,7 @@
 
 	struct net_device_stats net_stats;
 
-	struct delayed_work  link_thread;
+	struct timer_list    link_timer;
 	enum pause_control   flow_control;
 	enum pause_status    flow_status;
 	u8		     rx_csum;
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 5383997..4a009b7 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -510,9 +510,9 @@
 		ledover &= ~PHY_M_LED_MO_RX;
 	}
 
-	if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == CHIP_REV_YU_EC_A1) {
+	if (hw->chip_id == CHIP_ID_YUKON_EC_U &&
+	    hw->chip_rev == CHIP_REV_YU_EC_U_A1) {
 		/* apply fixes in PHY AFE */
-		pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 255);
 
 		/* increase differential signal amplitude in 10BASE-T */
@@ -524,7 +524,7 @@
 		gm_phy_write(hw, port, 0x17, 0x2002);
 
 		/* set page register to 0 */
-		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
 	} else if (hw->chip_id != CHIP_ID_YUKON_EX) {
 		gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
 
@@ -1561,6 +1561,7 @@
 
 	/* Stop more packets from being queued */
 	netif_stop_queue(dev);
+	netif_carrier_off(dev);
 
 	/* Disable port IRQ */
 	imask = sky2_read32(hw, B0_IMSK);
@@ -2165,9 +2166,27 @@
 			/* fall through */
 #endif
 		case OP_RXCHKS:
-			skb = sky2->rx_ring[sky2->rx_next].skb;
-			skb->ip_summed = CHECKSUM_COMPLETE;
-			skb->csum = status & 0xffff;
+			if (!sky2->rx_csum)
+				break;
+
+			/* Both checksum counters are programmed to start at
+			 * the same offset, so unless there is a problem they
+			 * should match. This failure is an early indication that
+			 * hardware receive checksumming won't work.
+			 */
+			if (likely(status >> 16 == (status & 0xffff))) {
+				skb = sky2->rx_ring[sky2->rx_next].skb;
+				skb->ip_summed = CHECKSUM_COMPLETE;
+				skb->csum = status & 0xffff;
+			} else {
+				printk(KERN_NOTICE PFX "%s: hardware receive "
+				       "checksum problem (status = %#x)\n",
+				       dev->name, status);
+				sky2->rx_csum = 0;
+				sky2_write32(sky2->hw,
+					     Q_ADDR(rxqaddr[le->link], Q_CSR),
+					     BMU_DIS_RX_CHKSUM);
+			}
 			break;
 
 		case OP_TXINDEXLE:
@@ -3751,6 +3770,11 @@
 		goto out;
 
 	pci_enable_wake(pdev, PCI_D0, 0);
+
+	/* Re-enable all clocks */
+	if (hw->chip_id == CHIP_ID_YUKON_EX || hw->chip_id == CHIP_ID_YUKON_EC_U)
+		sky2_pci_write32(hw, PCI_DEV_REG3, 0);
+
 	sky2_reset(hw);
 
 	sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c
index c62e85d..7bee45b 100644
--- a/drivers/net/sun3lance.c
+++ b/drivers/net/sun3lance.c
@@ -336,13 +336,27 @@
 
 	/* XXX - leak? */
 	MEM = dvma_malloc_align(sizeof(struct lance_memory), 0x10000);
+	if (MEM == NULL) {
+#ifdef CONFIG_SUN3
+		iounmap((void __iomem *)ioaddr);
+#endif
+		printk(KERN_WARNING "SUN3 Lance couldn't allocate DVMA memory\n");
+		return 0;
+	}
 
 	lp->iobase = (volatile unsigned short *)ioaddr;
 	dev->base_addr = (unsigned long)ioaddr; /* informational only */
 
 	REGA(CSR0) = CSR0_STOP;
 
-	request_irq(LANCE_IRQ, lance_interrupt, IRQF_DISABLED, "SUN3 Lance", dev);
+	if (request_irq(LANCE_IRQ, lance_interrupt, IRQF_DISABLED, "SUN3 Lance", dev) < 0) {
+#ifdef CONFIG_SUN3
+		iounmap((void __iomem *)ioaddr);
+#endif
+		dvma_free((void *)MEM);
+		printk(KERN_WARNING "SUN3 Lance unable to allocate IRQ\n");
+		return 0;
+	}
 	dev->irq = (unsigned short)LANCE_IRQ;
 
 
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 616be8d..08ea61d 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -2530,6 +2530,35 @@
 	return &gp->net_stats;
 }
 
+static int gem_set_mac_address(struct net_device *dev, void *addr)
+{
+	struct sockaddr *macaddr = (struct sockaddr *) addr;
+	struct gem *gp = dev->priv;
+	unsigned char *e = &dev->dev_addr[0];
+
+	if (!is_valid_ether_addr(macaddr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	if (!netif_running(dev) || !netif_device_present(dev)) {
+		/* We'll just catch it later when the
+		 * device is up'd or resumed.
+		 */
+		memcpy(dev->dev_addr, macaddr->sa_data, dev->addr_len);
+		return 0;
+	}
+
+	mutex_lock(&gp->pm_mutex);
+	memcpy(dev->dev_addr, macaddr->sa_data, dev->addr_len);
+	if (gp->running) {
+		writel((e[4] << 8) | e[5], gp->regs + MAC_ADDR0);
+		writel((e[2] << 8) | e[3], gp->regs + MAC_ADDR1);
+		writel((e[0] << 8) | e[1], gp->regs + MAC_ADDR2);
+	}
+	mutex_unlock(&gp->pm_mutex);
+
+	return 0;
+}
+
 static void gem_set_multicast(struct net_device *dev)
 {
 	struct gem *gp = dev->priv;
@@ -3122,6 +3151,7 @@
 	dev->change_mtu = gem_change_mtu;
 	dev->irq = pdev->irq;
 	dev->dma = 0;
+	dev->set_mac_address = gem_set_mac_address;
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	dev->poll_controller = gem_poll_controller;
 #endif
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 8c8f9f4..256969e 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -64,8 +64,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"3.74"
-#define DRV_MODULE_RELDATE	"February 20, 2007"
+#define DRV_MODULE_VERSION	"3.75"
+#define DRV_MODULE_RELDATE	"March 23, 2007"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -3568,32 +3568,34 @@
 	 * Reading the PCI State register will confirm whether the
 	 * interrupt is ours and will flush the status block.
 	 */
-	if ((sblk->status & SD_STATUS_UPDATED) ||
-	    !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
-		/*
-		 * Writing any value to intr-mbox-0 clears PCI INTA# and
-		 * chip-internal interrupt pending events.
-		 * Writing non-zero to intr-mbox-0 additional tells the
-		 * NIC to stop sending us irqs, engaging "in-intr-handler"
-		 * event coalescing.
-		 */
-		tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
-			     0x00000001);
-		if (tg3_irq_sync(tp))
+	if (unlikely(!(sblk->status & SD_STATUS_UPDATED))) {
+		if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) ||
+		    (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
+			handled = 0;
 			goto out;
-		sblk->status &= ~SD_STATUS_UPDATED;
-		if (likely(tg3_has_work(tp))) {
-			prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
-			netif_rx_schedule(dev);		/* schedule NAPI poll */
-		} else {
-			/* No work, shared interrupt perhaps?  re-enable
-			 * interrupts, and flush that PCI write
-			 */
-			tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
-			     	0x00000000);
 		}
-	} else {	/* shared interrupt */
-		handled = 0;
+	}
+
+	/*
+	 * Writing any value to intr-mbox-0 clears PCI INTA# and
+	 * chip-internal interrupt pending events.
+	 * Writing non-zero to intr-mbox-0 additional tells the
+	 * NIC to stop sending us irqs, engaging "in-intr-handler"
+	 * event coalescing.
+	 */
+	tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+	if (tg3_irq_sync(tp))
+		goto out;
+	sblk->status &= ~SD_STATUS_UPDATED;
+	if (likely(tg3_has_work(tp))) {
+		prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+		netif_rx_schedule(dev);		/* schedule NAPI poll */
+	} else {
+		/* No work, shared interrupt perhaps?  re-enable
+		 * interrupts, and flush that PCI write
+		 */
+		tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
+			       0x00000000);
 	}
 out:
 	return IRQ_RETVAL(handled);
@@ -3611,31 +3613,33 @@
 	 * Reading the PCI State register will confirm whether the
 	 * interrupt is ours and will flush the status block.
 	 */
-	if ((sblk->status_tag != tp->last_tag) ||
-	    !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
-		/*
-		 * writing any value to intr-mbox-0 clears PCI INTA# and
-		 * chip-internal interrupt pending events.
-		 * writing non-zero to intr-mbox-0 additional tells the
-		 * NIC to stop sending us irqs, engaging "in-intr-handler"
-		 * event coalescing.
-		 */
-		tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
-			     0x00000001);
-		if (tg3_irq_sync(tp))
+	if (unlikely(sblk->status_tag == tp->last_tag)) {
+		if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) ||
+		    (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
+			handled = 0;
 			goto out;
-		if (netif_rx_schedule_prep(dev)) {
-			prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
-			/* Update last_tag to mark that this status has been
-			 * seen. Because interrupt may be shared, we may be
-			 * racing with tg3_poll(), so only update last_tag
-			 * if tg3_poll() is not scheduled.
-			 */
-			tp->last_tag = sblk->status_tag;
-			__netif_rx_schedule(dev);
 		}
-	} else {	/* shared interrupt */
-		handled = 0;
+	}
+
+	/*
+	 * writing any value to intr-mbox-0 clears PCI INTA# and
+	 * chip-internal interrupt pending events.
+	 * writing non-zero to intr-mbox-0 additional tells the
+	 * NIC to stop sending us irqs, engaging "in-intr-handler"
+	 * event coalescing.
+	 */
+	tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+	if (tg3_irq_sync(tp))
+		goto out;
+	if (netif_rx_schedule_prep(dev)) {
+		prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+		/* Update last_tag to mark that this status has been
+		 * seen. Because interrupt may be shared, we may be
+		 * racing with tg3_poll(), so only update last_tag
+		 * if tg3_poll() is not scheduled.
+		 */
+		tp->last_tag = sblk->status_tag;
+		__netif_rx_schedule(dev);
 	}
 out:
 	return IRQ_RETVAL(handled);
@@ -4823,6 +4827,21 @@
 	if (write_op == tg3_write_flush_reg32)
 		tp->write32 = tg3_write32;
 
+	/* Prevent the irq handler from reading or writing PCI registers
+	 * during chip reset when the memory enable bit in the PCI command
+	 * register may be cleared.  The chip does not generate interrupt
+	 * at this time, but the irq handler may still be called due to irq
+	 * sharing or irqpoll.
+	 */
+	tp->tg3_flags |= TG3_FLAG_CHIP_RESETTING;
+	if (tp->hw_status) {
+		tp->hw_status->status = 0;
+		tp->hw_status->status_tag = 0;
+	}
+	tp->last_tag = 0;
+	smp_mb();
+	synchronize_irq(tp->pdev->irq);
+
 	/* do the reset */
 	val = GRC_MISC_CFG_CORECLK_RESET;
 
@@ -4904,6 +4923,8 @@
 
 	pci_restore_state(tp->pdev);
 
+	tp->tg3_flags &= ~TG3_FLAG_CHIP_RESETTING;
+
 	/* Make sure PCI-X relaxed ordering bit is clear. */
 	pci_read_config_dword(tp->pdev, TG3PCI_X_CAPS, &val);
 	val &= ~PCIX_CAPS_RELAXED_ORDERING;
@@ -6321,8 +6342,6 @@
 		      RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB |
 		      RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
 		      RDMAC_MODE_LNGREAD_ENAB);
-	if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE)
-		rdmac_mode |= RDMAC_MODE_SPLIT_ENABLE;
 
 	/* If statement applies to 5705 and 5750 PCI devices only */
 	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
@@ -6495,9 +6514,6 @@
 		} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
 			val &= ~(PCIX_CAPS_SPLIT_MASK | PCIX_CAPS_BURST_MASK);
 			val |= (PCIX_CAPS_MAX_BURST_CPIOB << PCIX_CAPS_BURST_SHIFT);
-			if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE)
-				val |= (tp->split_mode_max_reqs <<
-					PCIX_CAPS_SPLIT_SHIFT);
 		}
 		tw32(TG3PCI_X_CAPS, val);
 	}
@@ -10863,14 +10879,6 @@
 	grc_misc_cfg = tr32(GRC_MISC_CFG);
 	grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK;
 
-	/* Broadcom's driver says that CIOBE multisplit has a bug */
-#if 0
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
-	    grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5704CIOBE) {
-		tp->tg3_flags |= TG3_FLAG_SPLIT_MODE;
-		tp->split_mode_max_reqs = SPLIT_MODE_5704_MAX_REQ;
-	}
-#endif
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
 	    (grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788 ||
 	     grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M))
@@ -11968,14 +11976,12 @@
 		       i == 5 ? '\n' : ':');
 
 	printk(KERN_INFO "%s: RXcsums[%d] LinkChgREG[%d] "
-	       "MIirq[%d] ASF[%d] Split[%d] WireSpeed[%d] "
-	       "TSOcap[%d] \n",
+	       "MIirq[%d] ASF[%d] WireSpeed[%d] TSOcap[%d]\n",
 	       dev->name,
 	       (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0,
 	       (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0,
 	       (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) != 0,
 	       (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0,
-	       (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) != 0,
 	       (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0,
 	       (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0);
 	printk(KERN_INFO "%s: dma_rwctrl[%08x] dma_mask[%d-bit]\n",
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 086892d..d515ed2 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2223,7 +2223,7 @@
 #define TG3_FLAG_40BIT_DMA_BUG		0x08000000
 #define TG3_FLAG_BROKEN_CHECKSUMS	0x10000000
 #define TG3_FLAG_GOT_SERDES_FLOWCTL	0x20000000
-#define TG3_FLAG_SPLIT_MODE		0x40000000
+#define TG3_FLAG_CHIP_RESETTING		0x40000000
 #define TG3_FLAG_INIT_COMPLETE		0x80000000
 	u32				tg3_flags2;
 #define TG3_FLG2_RESTART_TIMER		0x00000001
@@ -2262,9 +2262,6 @@
 #define TG3_FLG2_NO_FWARE_REPORTED	0x40000000
 #define TG3_FLG2_PHY_ADJUST_TRIM	0x80000000
 
-	u32				split_mode_max_reqs;
-#define SPLIT_MODE_5704_MAX_REQ		3
-
 	struct timer_list		timer;
 	u16				timer_counter;
 	u16				timer_multiplier;
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
index 0d97e10..01d5531 100644
--- a/drivers/net/tokenring/ibmtr.c
+++ b/drivers/net/tokenring/ibmtr.c
@@ -186,7 +186,6 @@
 #define TRC_INITV 0x02		/*  verbose init trace points     */
 static unsigned char ibmtr_debug_trace = 0;
 
-static int 	ibmtr_probe(struct net_device *dev);
 static int	ibmtr_probe1(struct net_device *dev, int ioaddr);
 static unsigned char get_sram_size(struct tok_info *adapt_info);
 static int 	trdev_init(struct net_device *dev);
@@ -335,17 +334,6 @@
 #endif		
 }
 
-int ibmtr_probe_card(struct net_device *dev)
-{
-	int err = ibmtr_probe(dev);
-	if (!err) {
-		err = register_netdev(dev);
-		if (err)
-			ibmtr_cleanup_card(dev);
-	}
-	return err;
-}
-
 /****************************************************************************
  *	ibmtr_probe():  Routine specified in the network device structure
  *	to probe for an IBM Token Ring Adapter.  Routine outline:
@@ -358,7 +346,7 @@
  *	which references it.
  ****************************************************************************/
 
-static int ibmtr_probe(struct net_device *dev)
+static int __devinit ibmtr_probe(struct net_device *dev)
 {
 	int i;
 	int base_addr = dev->base_addr;
@@ -378,6 +366,17 @@
 	return -ENODEV;
 }
 
+int __devinit ibmtr_probe_card(struct net_device *dev)
+{
+	int err = ibmtr_probe(dev);
+	if (!err) {
+		err = register_netdev(dev);
+		if (err)
+			ibmtr_cleanup_card(dev);
+	}
+	return err;
+}
+
 /*****************************************************************************/
 
 static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr)
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
index 24a29c9..9aeac76 100644
--- a/drivers/net/tulip/dmfe.c
+++ b/drivers/net/tulip/dmfe.c
@@ -190,13 +190,13 @@
 
 /* Structure/enum declaration ------------------------------- */
 struct tx_desc {
-        u32 tdes0, tdes1, tdes2, tdes3; /* Data for the card */
+        __le32 tdes0, tdes1, tdes2, tdes3; /* Data for the card */
         char *tx_buf_ptr;               /* Data for us */
         struct tx_desc *next_tx_desc;
 } __attribute__(( aligned(32) ));
 
 struct rx_desc {
-	u32 rdes0, rdes1, rdes2, rdes3; /* Data for the card */
+	__le32 rdes0, rdes1, rdes2, rdes3; /* Data for the card */
 	struct sk_buff *rx_skb_ptr;	/* Data for us */
 	struct rx_desc *next_rx_desc;
 } __attribute__(( aligned(32) ));
@@ -458,7 +458,7 @@
 
 	/* read 64 word srom data */
 	for (i = 0; i < 64; i++)
-		((u16 *) db->srom)[i] =
+		((__le16 *) db->srom)[i] =
 			cpu_to_le16(read_srom_word(db->ioaddr, i));
 
 	/* Set Node address */
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index dab88b9..639e1e6 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -3607,7 +3607,6 @@
 	if (bd == ugeth->confBd[txQ]) {
 		if (!netif_queue_stopped(dev))
 			netif_stop_queue(dev);
-		return NETDEV_TX_BUSY;
 	}
 
 	ugeth->txBd[txQ] = bd;
@@ -3623,7 +3622,7 @@
 
 	spin_unlock_irq(&ugeth->lock);
 
-	return NETDEV_TX_OK;
+	return 0;
 }
 
 static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit)
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index ebbda1d..f3a972e 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -30,8 +30,8 @@
 */
 
 #define DRV_NAME	"via-rhine"
-#define DRV_VERSION	"1.4.2"
-#define DRV_RELDATE	"Sept-11-2006"
+#define DRV_VERSION	"1.4.3"
+#define DRV_RELDATE	"2007-03-06"
 
 
 /* A few user-configurable values.
@@ -105,6 +105,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
+#include <linux/dmi.h>
 
 /* These identify the driver base version and may not be removed. */
 static char version[] __devinitdata =
@@ -1995,6 +1996,23 @@
 	.shutdown =	rhine_shutdown,
 };
 
+static struct dmi_system_id __initdata rhine_dmi_table[] = {
+	{
+		.ident = "EPIA-M",
+		.matches = {
+			DMI_MATCH(DMI_BIOS_VENDOR, "Award Software International, Inc."),
+			DMI_MATCH(DMI_BIOS_VERSION, "6.00 PG"),
+		},
+	},
+	{
+		.ident = "KV7",
+		.matches = {
+			DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"),
+			DMI_MATCH(DMI_BIOS_VERSION, "6.00 PG"),
+		},
+	},
+	{ NULL }
+};
 
 static int __init rhine_init(void)
 {
@@ -2002,6 +2020,16 @@
 #ifdef MODULE
 	printk(version);
 #endif
+	if (dmi_check_system(rhine_dmi_table)) {
+		/* these BIOSes fail at PXE boot if chip is in D3 */
+		avoid_D3 = 1;
+		printk(KERN_WARNING "%s: Broken BIOS detected, avoid_D3 "
+				    "enabled.\n",
+		       DRV_NAME);
+	}
+	else if (avoid_D3)
+		printk(KERN_INFO "%s: avoid_D3 set.\n", DRV_NAME);
+
 	return pci_register_driver(&rhine_driver);
 }
 
diff --git a/drivers/net/wan/lmc/lmc_media.h b/drivers/net/wan/lmc/lmc_media.h
deleted file mode 100644
index ddcc004..0000000
--- a/drivers/net/wan/lmc/lmc_media.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef _LMC_MEDIA_H_
-#define _LMC_MEDIA_H_
-
-lmc_media_t lmc_ds3_media = {
-  lmc_ds3_init,			/* special media init stuff */
-  lmc_ds3_default,		/* reset to default state */
-  lmc_ds3_set_status,		/* reset status to state provided */
-  lmc_dummy_set_1,		/* set clock source */
-  lmc_dummy_set2_1,		/* set line speed */
-  lmc_ds3_set_100ft,		/* set cable length */
-  lmc_ds3_set_scram,		/* set scrambler */
-  lmc_ds3_get_link_status,	/* get link status */
-  lmc_dummy_set_1,		/* set link status */
-  lmc_ds3_set_crc_length,	/* set CRC length */
-  lmc_dummy_set_1,		/* set T1 or E1 circuit type */
-  lmc_ds3_watchdog
-};
-
-lmc_media_t lmc_hssi_media = {
-  lmc_hssi_init,		/* special media init stuff */
-  lmc_hssi_default,		/* reset to default state */
-  lmc_hssi_set_status,		/* reset status to state provided */
-  lmc_hssi_set_clock,		/* set clock source */
-  lmc_dummy_set2_1,		/* set line speed */
-  lmc_dummy_set_1,		/* set cable length */
-  lmc_dummy_set_1,		/* set scrambler */
-  lmc_hssi_get_link_status,	/* get link status */
-  lmc_hssi_set_link_status,	/* set link status */
-  lmc_hssi_set_crc_length,	/* set CRC length */
-  lmc_dummy_set_1,		/* set T1 or E1 circuit type */
-  lmc_hssi_watchdog
-};
-
-lmc_media_t lmc_ssi_media = { lmc_ssi_init,	/* special media init stuff */
-  lmc_ssi_default,		/* reset to default state */
-  lmc_ssi_set_status,		/* reset status to state provided */
-  lmc_ssi_set_clock,		/* set clock source */
-  lmc_ssi_set_speed,		/* set line speed */
-  lmc_dummy_set_1,		/* set cable length */
-  lmc_dummy_set_1,		/* set scrambler */
-  lmc_ssi_get_link_status,	/* get link status */
-  lmc_ssi_set_link_status,	/* set link status */
-  lmc_ssi_set_crc_length,	/* set CRC length */
-  lmc_dummy_set_1,		/* set T1 or E1 circuit type */
-  lmc_ssi_watchdog
-};
-
-lmc_media_t lmc_t1_media = {
-  lmc_t1_init,			/* special media init stuff */
-  lmc_t1_default,		/* reset to default state */
-  lmc_t1_set_status,		/* reset status to state provided */
-  lmc_t1_set_clock,		/* set clock source */
-  lmc_dummy_set2_1,		/* set line speed */
-  lmc_dummy_set_1,		/* set cable length */
-  lmc_dummy_set_1,		/* set scrambler */
-  lmc_t1_get_link_status,	/* get link status */
-  lmc_dummy_set_1,		/* set link status */
-  lmc_t1_set_crc_length,	/* set CRC length */
-  lmc_t1_set_circuit_type,	/* set T1 or E1 circuit type */
-  lmc_t1_watchdog
-};
-
-
-#endif
-
diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c
index 8dbcf83..8b4540b 100644
--- a/drivers/net/wan/z85230.c
+++ b/drivers/net/wan/z85230.c
@@ -407,7 +407,7 @@
 	while(c->txcount) {
 		/* FIFO full ? */
 		if(!(read_zsreg(c, R0)&4))
-			break;
+			return;
 		c->txcount--;
 		/*
 		 *	Shovel out the byte
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index a8c2bfe..2ada76a 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -2852,7 +2852,7 @@
 	if (rc) {
 		airo_print_err(dev->name, "register interrupt %d failed, rc %d",
 				irq, rc);
-		goto err_out_unlink;
+		goto err_out_nets;
 	}
 	if (!is_pcmcia) {
 		if (!request_region( dev->base_addr, 64, dev->name )) {
@@ -2935,6 +2935,8 @@
 	        release_region( dev->base_addr, 64 );
 err_out_irq:
 	free_irq(dev->irq, dev);
+err_out_nets:
+	airo_networks_free(ai);
 err_out_unlink:
 	del_airo_dev(dev);
 err_out_thr:
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index e594af4..a38e7ee 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -946,6 +946,7 @@
 	u8 channel;
 	struct bcm43xx_phyinfo *phy;
 	const char *iso_country;
+	u8 max_bg_channel;
 
 	geo = kzalloc(sizeof(*geo), GFP_KERNEL);
 	if (!geo)
@@ -967,6 +968,23 @@
 	}
 	iso_country = bcm43xx_locale_iso(bcm->sprom.locale);
 
+/* set the maximum channel based on locale set in sprom or witle locale option */
+	switch (bcm->sprom.locale) {
+	case BCM43xx_LOCALE_THAILAND:
+	case BCM43xx_LOCALE_ISRAEL:
+	case BCM43xx_LOCALE_JORDAN:
+	case BCM43xx_LOCALE_USA_CANADA_ANZ:
+	case BCM43xx_LOCALE_USA_LOW:
+		max_bg_channel = 11;
+		break;
+	case BCM43xx_LOCALE_JAPAN:
+	case BCM43xx_LOCALE_JAPAN_HIGH:
+		max_bg_channel = 14;
+		break;
+	default:
+		max_bg_channel = 13;
+	}
+
  	if (have_a) {
 		for (i = 0, channel = IEEE80211_52GHZ_MIN_CHANNEL;
 		      channel <= IEEE80211_52GHZ_MAX_CHANNEL; channel++) {
@@ -978,7 +996,7 @@
 	}
 	if (have_bg) {
 		for (i = 0, channel = IEEE80211_24GHZ_MIN_CHANNEL;
-		      channel <= IEEE80211_24GHZ_MAX_CHANNEL; channel++) {
+		      channel <= max_bg_channel; channel++) {
 			chan = &geo->bg[i++];
 			chan->freq = bcm43xx_channel_to_freq_bg(channel);
 			chan->channel = channel;
@@ -1858,9 +1876,6 @@
 
 	spin_lock(&bcm->irq_lock);
 
-	assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
-	assert(bcm->current_core->id == BCM43xx_COREID_80211);
-
 	reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
 	if (reason == 0xffffffff) {
 		/* irq not for us (shared irq) */
@@ -1871,6 +1886,9 @@
 	if (!reason)
 		goto out;
 
+	assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
+	assert(bcm->current_core->id == BCM43xx_COREID_80211);
+
 	bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA0_REASON)
 			     & 0x0001DC00;
 	bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
index 3a5c9c2..72529a4 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
@@ -757,7 +757,7 @@
 	if (radio->version == 0x2050)
 		bcm43xx_phy_write(bcm, 0x0038, 0x0667);
 
-	if (phy->type == BCM43xx_PHYTYPE_G) {
+	if (phy->connected) {
 		if (radio->version == 0x2050) {
 			bcm43xx_radio_write16(bcm, 0x007A,
 					      bcm43xx_radio_read16(bcm, 0x007A)
@@ -859,6 +859,11 @@
 		bcm43xx_radio_write16(bcm, 0x005D, 0x0088);
 		bcm43xx_radio_write16(bcm, 0x005E, 0x0088);
 		bcm43xx_radio_write16(bcm, 0x007D, 0x0088);
+		bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
+				    BCM43xx_UCODEFLAGS_OFFSET,
+				    (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
+				    BCM43xx_UCODEFLAGS_OFFSET)
+				    | 0x00000200));
 	}
 	if (radio->revision == 8) {
 		bcm43xx_radio_write16(bcm, 0x0051, 0x0000);
@@ -941,7 +946,8 @@
 	bcm43xx_phy_write(bcm, 0x0038, 0x0668);
 	bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF);
 	if (radio->revision <= 5)
-		bcm43xx_phy_write(bcm, 0x005D, bcm43xx_phy_read(bcm, 0x005D) | 0x0003);
+		bcm43xx_phy_write(bcm, 0x005D, (bcm43xx_phy_read(bcm, 0x005D)
+			          & 0xFF80) | 0x0003);
 	if (radio->revision <= 2)
 		bcm43xx_radio_write16(bcm, 0x005D, 0x000D);
 	
@@ -958,7 +964,7 @@
 		bcm43xx_phy_write(bcm, 0x0016, 0x0410);
 		bcm43xx_phy_write(bcm, 0x0017, 0x0820);
 		bcm43xx_phy_write(bcm, 0x0062, 0x0007);
-		(void) bcm43xx_radio_calibrationvalue(bcm);
+		bcm43xx_radio_init2050(bcm);
 		bcm43xx_phy_lo_g_measure(bcm);
 		if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {
 			bcm43xx_calc_nrssi_slope(bcm);
@@ -972,7 +978,7 @@
 {
 	struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
 	struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
-	u16 backup_phy[15];
+	u16 backup_phy[15] = {0};
 	u16 backup_radio[3];
 	u16 backup_bband;
 	u16 i;
@@ -983,8 +989,10 @@
 	backup_phy[1] = bcm43xx_phy_read(bcm, 0x0001);
 	backup_phy[2] = bcm43xx_phy_read(bcm, 0x0811);
 	backup_phy[3] = bcm43xx_phy_read(bcm, 0x0812);
-	backup_phy[4] = bcm43xx_phy_read(bcm, 0x0814);
-	backup_phy[5] = bcm43xx_phy_read(bcm, 0x0815);
+	if (phy->rev != 1) {
+		backup_phy[4] = bcm43xx_phy_read(bcm, 0x0814);
+		backup_phy[5] = bcm43xx_phy_read(bcm, 0x0815);
+	}
 	backup_phy[6] = bcm43xx_phy_read(bcm, 0x005A);
 	backup_phy[7] = bcm43xx_phy_read(bcm, 0x0059);
 	backup_phy[8] = bcm43xx_phy_read(bcm, 0x0058);
@@ -1012,14 +1020,16 @@
 			  bcm43xx_phy_read(bcm, 0x0811) | 0x0001);
 	bcm43xx_phy_write(bcm, 0x0812,
 			  bcm43xx_phy_read(bcm, 0x0812) & 0xFFFE);
-	bcm43xx_phy_write(bcm, 0x0814,
-			  bcm43xx_phy_read(bcm, 0x0814) | 0x0001);
-	bcm43xx_phy_write(bcm, 0x0815,
-			  bcm43xx_phy_read(bcm, 0x0815) & 0xFFFE);
-	bcm43xx_phy_write(bcm, 0x0814,
-			  bcm43xx_phy_read(bcm, 0x0814) | 0x0002);
-	bcm43xx_phy_write(bcm, 0x0815,
-			  bcm43xx_phy_read(bcm, 0x0815) & 0xFFFD);
+	if (phy->rev != 1) {
+		bcm43xx_phy_write(bcm, 0x0814,
+				  bcm43xx_phy_read(bcm, 0x0814) | 0x0001);
+		bcm43xx_phy_write(bcm, 0x0815,
+				  bcm43xx_phy_read(bcm, 0x0815) & 0xFFFE);
+		bcm43xx_phy_write(bcm, 0x0814,
+				  bcm43xx_phy_read(bcm, 0x0814) | 0x0002);
+		bcm43xx_phy_write(bcm, 0x0815,
+				  bcm43xx_phy_read(bcm, 0x0815) & 0xFFFD);
+	}
 	bcm43xx_phy_write(bcm, 0x0811,
 			  bcm43xx_phy_read(bcm, 0x0811) | 0x000C);
 	bcm43xx_phy_write(bcm, 0x0812,
@@ -1042,10 +1052,12 @@
 				  bcm43xx_phy_read(bcm, 0x000A)
 				  | 0x2000);
 	}
-	bcm43xx_phy_write(bcm, 0x0814,
-			  bcm43xx_phy_read(bcm, 0x0814) | 0x0004);
-	bcm43xx_phy_write(bcm, 0x0815,
-			  bcm43xx_phy_read(bcm, 0x0815) & 0xFFFB);
+	if (phy->rev != 1) {
+		bcm43xx_phy_write(bcm, 0x0814,
+				  bcm43xx_phy_read(bcm, 0x0814) | 0x0004);
+		bcm43xx_phy_write(bcm, 0x0815,
+				  bcm43xx_phy_read(bcm, 0x0815) & 0xFFFB);
+	}
 	bcm43xx_phy_write(bcm, 0x0003,
 			  (bcm43xx_phy_read(bcm, 0x0003)
 			   & 0xFF9F) | 0x0040);
@@ -1132,8 +1144,10 @@
 		}
 	}
 
-	bcm43xx_phy_write(bcm, 0x0814, backup_phy[4]);
-	bcm43xx_phy_write(bcm, 0x0815, backup_phy[5]);
+	if (phy->rev != 1) {
+		bcm43xx_phy_write(bcm, 0x0814, backup_phy[4]);
+		bcm43xx_phy_write(bcm, 0x0815, backup_phy[5]);
+	}
 	bcm43xx_phy_write(bcm, 0x005A, backup_phy[6]);
 	bcm43xx_phy_write(bcm, 0x0059, backup_phy[7]);
 	bcm43xx_phy_write(bcm, 0x0058, backup_phy[8]);
@@ -1182,24 +1196,23 @@
 		bcm43xx_phy_write(bcm, 0x0811, 0x0000);
 		bcm43xx_phy_write(bcm, 0x0015, 0x00C0);
 	}
-	if (phy->rev >= 3) {
+	if (phy->rev > 5) {
 		bcm43xx_phy_write(bcm, 0x0811, 0x0400);
 		bcm43xx_phy_write(bcm, 0x0015, 0x00C0);
 	}
-	if (phy->connected) {
+	if (phy->rev >= 2 && phy->connected) {
 		tmp = bcm43xx_phy_read(bcm, 0x0400) & 0xFF;
-		if (tmp < 6) {
+		if (tmp ==3 || tmp == 5) {
 			bcm43xx_phy_write(bcm, 0x04C2, 0x1816);
 			bcm43xx_phy_write(bcm, 0x04C3, 0x8006);
-			if (tmp != 3) {
+			if (tmp == 5) {
 				bcm43xx_phy_write(bcm, 0x04CC,
 						  (bcm43xx_phy_read(bcm, 0x04CC)
 						   & 0x00FF) | 0x1F00);
 			}
 		}
-	}
-	if (phy->rev < 3 && phy->connected)
 		bcm43xx_phy_write(bcm, 0x047E, 0x0078);
+	}
 	if (radio->revision == 8) {
 		bcm43xx_phy_write(bcm, 0x0801, bcm43xx_phy_read(bcm, 0x0801) | 0x0080);
 		bcm43xx_phy_write(bcm, 0x043E, bcm43xx_phy_read(bcm, 0x043E) | 0x0004);
@@ -1226,7 +1239,7 @@
 		if (phy->rev >= 6) {
 			bcm43xx_phy_write(bcm, 0x0036,
 					  (bcm43xx_phy_read(bcm, 0x0036)
-					   & 0xF000) | (radio->txctl2 << 12));
+					   & 0x0FFF) | (radio->txctl2 << 12));
 		}
 		if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL)
 			bcm43xx_phy_write(bcm, 0x002E, 0x8075);
@@ -1237,7 +1250,7 @@
 		else
 			bcm43xx_phy_write(bcm, 0x002F, 0x0202);
 	}
-	if (phy->connected) {
+	if (phy->connected || phy->rev >= 2) {
 		bcm43xx_phy_lo_adjust(bcm, 0);
 		bcm43xx_phy_write(bcm, 0x080F, 0x8078);
 	}
@@ -1251,7 +1264,7 @@
 		 */
 		bcm43xx_nrssi_hw_update(bcm, 0xFFFF);
 		bcm43xx_calc_nrssi_threshold(bcm);
-	} else if (phy->connected) {
+	} else if (phy->connected || phy->rev >= 2) {
 		if (radio->nrssi[0] == -1000) {
 			assert(radio->nrssi[1] == -1000);
 			bcm43xx_calc_nrssi_slope(bcm);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
index 32beb91..4025dd0 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
@@ -458,7 +458,7 @@
 		bcm43xx_phy_write(bcm, 0x005A, 0x0480);
 		bcm43xx_phy_write(bcm, 0x0059, 0x0810);
 		bcm43xx_phy_write(bcm, 0x0058, 0x000D);
-		if (phy->rev == 0) {
+		if (phy->analog == 0) {
 			bcm43xx_phy_write(bcm, 0x0003, 0x0122);
 		} else {
 			bcm43xx_phy_write(bcm, 0x000A,
@@ -570,9 +570,9 @@
 		nrssi0 = (s16)bcm43xx_phy_read(bcm, 0x0027);
 		bcm43xx_radio_write16(bcm, 0x007A,
 				      bcm43xx_radio_read16(bcm, 0x007A) & 0x007F);
-		if (phy->rev >= 2) {
+		if (phy->analog >= 2) {
 			bcm43xx_write16(bcm, 0x03E6, 0x0040);
-		} else if (phy->rev == 0) {
+		} else if (phy->analog == 0) {
 			bcm43xx_write16(bcm, 0x03E6, 0x0122);
 		} else {
 			bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT,
@@ -596,7 +596,7 @@
 		bcm43xx_phy_write(bcm, 0x0015, backup[5]);
 		bcm43xx_phy_write(bcm, 0x002A, backup[6]);
 		bcm43xx_synth_pu_workaround(bcm, radio->channel);
-		if (phy->rev != 0)
+		if (phy->analog != 0)
 			bcm43xx_write16(bcm, 0x03F4, backup[13]);
 
 		bcm43xx_phy_write(bcm, 0x0020, backup[7]);
@@ -692,7 +692,7 @@
 
 		bcm43xx_radio_write16(bcm, 0x007A,
 				      bcm43xx_radio_read16(bcm, 0x007A) & 0x007F);
-		if (phy->rev >= 2) {
+		if (phy->analog >= 2) {
 			bcm43xx_phy_write(bcm, 0x0003,
 					  (bcm43xx_phy_read(bcm, 0x0003)
 					   & 0xFF9F) | 0x0040);
@@ -882,10 +882,10 @@
 {
 	u32 *stackptr = &(_stackptr[*stackidx]);
 
-	assert((offset & 0xF000) == 0x0000);
-	assert((id & 0xF0) == 0x00);
+	assert((offset & 0xE000) == 0x0000);
+	assert((id & 0xF8) == 0x00);
 	*stackptr = offset;
-	*stackptr |= ((u32)id) << 12;
+	*stackptr |= ((u32)id) << 13;
 	*stackptr |= ((u32)value) << 16;
 	(*stackidx)++;
 	assert(*stackidx < BCM43xx_INTERFSTACK_SIZE);
@@ -896,12 +896,12 @@
 {
 	size_t i;
 
-	assert((offset & 0xF000) == 0x0000);
-	assert((id & 0xF0) == 0x00);
+	assert((offset & 0xE000) == 0x0000);
+	assert((id & 0xF8) == 0x00);
 	for (i = 0; i < BCM43xx_INTERFSTACK_SIZE; i++, stackptr++) {
-		if ((*stackptr & 0x00000FFF) != offset)
+		if ((*stackptr & 0x00001FFF) != offset)
 			continue;
-		if (((*stackptr & 0x0000F000) >> 12) != id)
+		if (((*stackptr & 0x00007000) >> 13) != id)
 			continue;
 		return ((*stackptr & 0xFFFF0000) >> 16);
 	}
@@ -1579,7 +1579,7 @@
 	
 	for (i = 0; i < 5; i++) {
 		for (j = 0; j < 5; j++) {
-			if (tmp == (data_high[i] << 4 | data_low[j])) {
+			if (tmp == (data_high[i] | data_low[j])) {
 				bcm43xx_phy_write(bcm, 0x0069, (i - j) << 8 | 0x00C0);
 				return;
 			}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
index 7b665e2..d6d9413 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
@@ -105,18 +105,24 @@
 	struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
 	unsigned long flags;
 	u8 channel;
+	s8 expon;
 	int freq;
 	int err = -EINVAL;
 
 	mutex_lock(&bcm->mutex);
 	spin_lock_irqsave(&bcm->irq_lock, flags);
 
-	if ((data->freq.m >= 0) && (data->freq.m <= 1000)) {
+	if ((data->freq.e == 0) &&
+	    (data->freq.m >= 0) && (data->freq.m <= 1000)) {
 		channel = data->freq.m;
 		freq = bcm43xx_channel_to_freq(bcm, channel);
 	} else {
-		channel = bcm43xx_freq_to_channel(bcm, data->freq.m);
 		freq = data->freq.m;
+		expon = 6 - data->freq.e;
+		while (--expon >= 0)    /* scale down the frequency to MHz */
+			freq /= 10;
+		assert(freq > 1000);
+		channel = bcm43xx_freq_to_channel(bcm, freq);
 	}
 	if (!ieee80211_is_valid_channel(bcm->ieee, channel))
 		goto out_unlock;
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index 9c64f89..87ee3ee 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -337,6 +337,7 @@
 	chip->patch_cr157 = (value >> 13) & 0x1;
 	chip->patch_6m_band_edge = (value >> 21) & 0x1;
 	chip->new_phy_layout = (value >> 31) & 0x1;
+	chip->al2230s_bit = (value >> 7) & 0x1;
 	chip->link_led = ((value >> 4) & 1) ? LED1 : LED2;
 	chip->supports_tx_led = 1;
 	if (value & (1 << 24)) { /* LED scenario */
@@ -591,16 +592,16 @@
 	return r;
 }
 
-/* CR157 can be optionally patched by the EEPROM */
+/* CR157 can be optionally patched by the EEPROM for original ZD1211 */
 static int patch_cr157(struct zd_chip *chip)
 {
 	int r;
-	u32 value;
+	u16 value;
 
 	if (!chip->patch_cr157)
 		return 0;
 
-	r = zd_ioread32_locked(chip, &value, E2P_PHY_REG);
+	r = zd_ioread16_locked(chip, &value, E2P_PHY_REG);
 	if (r)
 		return r;
 
@@ -790,11 +791,6 @@
 		goto out;
 
 	r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
-	if (r)
-		goto unlock;
-
-	r = patch_cr157(chip);
-unlock:
 	t = zd_chip_unlock_phy_regs(chip);
 	if (t && !r)
 		r = t;
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index b07569e..e57ed75 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -641,8 +641,8 @@
  * also only 11 channels. */
 #define E2P_ALLOWED_CHANNEL	E2P_DATA(0x18)
 
-#define E2P_PHY_REG		E2P_DATA(0x1a)
 #define E2P_DEVICE_VER		E2P_DATA(0x20)
+#define E2P_PHY_REG		E2P_DATA(0x25)
 #define E2P_36M_CAL_VALUE1	E2P_DATA(0x28)
 #define E2P_36M_CAL_VALUE2      E2P_DATA(0x2a)
 #define E2P_36M_CAL_VALUE3      E2P_DATA(0x2c)
@@ -711,7 +711,7 @@
 	u16 link_led;
 	unsigned int pa_type:4,
 		patch_cck_gain:1, patch_cr157:1, patch_6m_band_edge:1,
-		new_phy_layout:1,
+		new_phy_layout:1, al2230s_bit:1,
 		is_zd1211b:1, supports_tx_led:1;
 };
 
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
index 25323a1..5235a78 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
@@ -358,6 +358,12 @@
 {
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 
+	if (chip->al2230s_bit) {
+		dev_err(zd_chip_dev(chip), "AL2230S devices are not yet "
+			"supported by this driver.\n");
+		return -ENODEV;
+	}
+
 	rf->switch_radio_off = al2230_switch_radio_off;
 	if (chip->is_zd1211b) {
 		rf->init_hw = zd1211b_al2230_init_hw;
diff --git a/drivers/oprofile/event_buffer.c b/drivers/oprofile/event_buffer.c
index 00e937e..e7fbac5 100644
--- a/drivers/oprofile/event_buffer.c
+++ b/drivers/oprofile/event_buffer.c
@@ -70,11 +70,12 @@
 int alloc_event_buffer(void)
 {
 	int err = -ENOMEM;
+	unsigned long flags;
 
-	spin_lock(&oprofilefs_lock);
+	spin_lock_irqsave(&oprofilefs_lock, flags);
 	buffer_size = fs_buffer_size;
 	buffer_watershed = fs_buffer_watershed;
-	spin_unlock(&oprofilefs_lock);
+	spin_unlock_irqrestore(&oprofilefs_lock, flags);
  
 	if (buffer_watershed >= buffer_size)
 		return -EINVAL;
diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c
index 6e67b42..8543cb2 100644
--- a/drivers/oprofile/oprofilefs.c
+++ b/drivers/oprofile/oprofilefs.c
@@ -65,6 +65,7 @@
 int oprofilefs_ulong_from_user(unsigned long * val, char const __user * buf, size_t count)
 {
 	char tmpbuf[TMPBUFSIZE];
+	unsigned long flags;
 
 	if (!count)
 		return 0;
@@ -77,9 +78,9 @@
 	if (copy_from_user(tmpbuf, buf, count))
 		return -EFAULT;
 
-	spin_lock(&oprofilefs_lock);
+	spin_lock_irqsave(&oprofilefs_lock, flags);
 	*val = simple_strtoul(tmpbuf, NULL, 0);
-	spin_unlock(&oprofilefs_lock);
+	spin_unlock_irqrestore(&oprofilefs_lock, flags);
 	return 0;
 }
 
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 01869b1..435c195 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -94,12 +94,14 @@
 		int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
 			PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
 		writel(flag, entry->mask_base + offset);
+		readl(entry->mask_base + offset);
 		break;
 	}
 	default:
 		BUG();
 		break;
 	}
+	entry->msi_attrib.masked = !!flag;
 }
 
 void read_msi_msg(unsigned int irq, struct msi_msg *msg)
@@ -179,6 +181,7 @@
 	default:
 		BUG();
 	}
+	entry->msg = *msg;
 }
 
 void mask_msi_irq(unsigned int irq)
@@ -225,164 +228,60 @@
 }
 
 #ifdef CONFIG_PM
-static int __pci_save_msi_state(struct pci_dev *dev)
-{
-	int pos, i = 0;
-	u16 control;
-	struct pci_cap_saved_state *save_state;
-	u32 *cap;
-
-	if (!dev->msi_enabled)
-		return 0;
-
-	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
-	if (pos <= 0)
-		return 0;
-
-	save_state = kzalloc(sizeof(struct pci_cap_saved_state) + sizeof(u32) * 5,
-		GFP_KERNEL);
-	if (!save_state) {
-		printk(KERN_ERR "Out of memory in pci_save_msi_state\n");
-		return -ENOMEM;
-	}
-	cap = &save_state->data[0];
-
-	pci_read_config_dword(dev, pos, &cap[i++]);
-	control = cap[0] >> 16;
-	pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, &cap[i++]);
-	if (control & PCI_MSI_FLAGS_64BIT) {
-		pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, &cap[i++]);
-		pci_read_config_dword(dev, pos + PCI_MSI_DATA_64, &cap[i++]);
-	} else
-		pci_read_config_dword(dev, pos + PCI_MSI_DATA_32, &cap[i++]);
-	if (control & PCI_MSI_FLAGS_MASKBIT)
-		pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT, &cap[i++]);
-	save_state->cap_nr = PCI_CAP_ID_MSI;
-	pci_add_saved_cap(dev, save_state);
-	return 0;
-}
-
 static void __pci_restore_msi_state(struct pci_dev *dev)
 {
-	int i = 0, pos;
+	int pos;
 	u16 control;
-	struct pci_cap_saved_state *save_state;
-	u32 *cap;
+	struct msi_desc *entry;
 
 	if (!dev->msi_enabled)
 		return;
 
-	save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSI);
-	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
-	if (!save_state || pos <= 0)
-		return;
-	cap = &save_state->data[0];
+	entry = get_irq_msi(dev->irq);
+	pos = entry->msi_attrib.pos;
 
 	pci_intx(dev, 0);		/* disable intx */
-	control = cap[i++] >> 16;
 	msi_set_enable(dev, 0);
-	pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, cap[i++]);
-	if (control & PCI_MSI_FLAGS_64BIT) {
-		pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, cap[i++]);
-		pci_write_config_dword(dev, pos + PCI_MSI_DATA_64, cap[i++]);
-	} else
-		pci_write_config_dword(dev, pos + PCI_MSI_DATA_32, cap[i++]);
-	if (control & PCI_MSI_FLAGS_MASKBIT)
-		pci_write_config_dword(dev, pos + PCI_MSI_MASK_BIT, cap[i++]);
+	write_msi_msg(dev->irq, &entry->msg);
+	if (entry->msi_attrib.maskbit)
+		msi_set_mask_bit(dev->irq, entry->msi_attrib.masked);
+
+	pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
+	control &= ~(PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE);
+	if (entry->msi_attrib.maskbit || !entry->msi_attrib.masked)
+		control |= PCI_MSI_FLAGS_ENABLE;
 	pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control);
-	pci_remove_saved_cap(save_state);
-	kfree(save_state);
-}
-
-static int __pci_save_msix_state(struct pci_dev *dev)
-{
-	int pos;
-	int irq, head, tail = 0;
-	u16 control;
-	struct pci_cap_saved_state *save_state;
-
-	if (!dev->msix_enabled)
-		return 0;
-
-	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
-	if (pos <= 0)
-		return 0;
-
-	/* save the capability */
-	pci_read_config_word(dev, msi_control_reg(pos), &control);
-	save_state = kzalloc(sizeof(struct pci_cap_saved_state) + sizeof(u16),
-		GFP_KERNEL);
-	if (!save_state) {
-		printk(KERN_ERR "Out of memory in pci_save_msix_state\n");
-		return -ENOMEM;
-	}
-	*((u16 *)&save_state->data[0]) = control;
-
-	/* save the table */
-	irq = head = dev->first_msi_irq;
-	while (head != tail) {
-		struct msi_desc *entry;
-
-		entry = get_irq_msi(irq);
-		read_msi_msg(irq, &entry->msg_save);
-
-		tail = entry->link.tail;
-		irq = tail;
-	}
-
-	save_state->cap_nr = PCI_CAP_ID_MSIX;
-	pci_add_saved_cap(dev, save_state);
-	return 0;
-}
-
-int pci_save_msi_state(struct pci_dev *dev)
-{
-	int rc;
-
-	rc = __pci_save_msi_state(dev);
-	if (rc)
-		return rc;
-
-	rc = __pci_save_msix_state(dev);
-
-	return rc;
 }
 
 static void __pci_restore_msix_state(struct pci_dev *dev)
 {
-	u16 save;
 	int pos;
 	int irq, head, tail = 0;
 	struct msi_desc *entry;
-	struct pci_cap_saved_state *save_state;
+	u16 control;
 
 	if (!dev->msix_enabled)
 		return;
 
-	save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSIX);
-	if (!save_state)
-		return;
-	save = *((u16 *)&save_state->data[0]);
-	pci_remove_saved_cap(save_state);
-	kfree(save_state);
-
-	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
-	if (pos <= 0)
-		return;
-
 	/* route the table */
 	pci_intx(dev, 0);		/* disable intx */
 	msix_set_enable(dev, 0);
 	irq = head = dev->first_msi_irq;
+	entry = get_irq_msi(irq);
+	pos = entry->msi_attrib.pos;
 	while (head != tail) {
 		entry = get_irq_msi(irq);
-		write_msi_msg(irq, &entry->msg_save);
+		write_msi_msg(irq, &entry->msg);
+		msi_set_mask_bit(irq, entry->msi_attrib.masked);
 
 		tail = entry->link.tail;
 		irq = tail;
 	}
 
-	pci_write_config_word(dev, msi_control_reg(pos), save);
+	pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control);
+	control &= ~PCI_MSIX_FLAGS_MASKALL;
+	control |= PCI_MSIX_FLAGS_ENABLE;
+	pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
 }
 
 void pci_restore_msi_state(struct pci_dev *dev)
@@ -420,6 +319,7 @@
 	entry->msi_attrib.is_64 = is_64bit_address(control);
 	entry->msi_attrib.entry_nr = 0;
 	entry->msi_attrib.maskbit = is_mask_bit_support(control);
+	entry->msi_attrib.masked = 1;
 	entry->msi_attrib.default_irq = dev->irq;	/* Save IOAPIC IRQ */
 	entry->msi_attrib.pos = pos;
 	if (is_mask_bit_support(control)) {
@@ -507,6 +407,7 @@
 		entry->msi_attrib.is_64 = 1;
 		entry->msi_attrib.entry_nr = j;
 		entry->msi_attrib.maskbit = 1;
+		entry->msi_attrib.masked = 1;
 		entry->msi_attrib.default_irq = dev->irq;
 		entry->msi_attrib.pos = pos;
 		entry->dev = dev;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index df49530..d3eab05 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -551,7 +551,9 @@
 	if (pos <= 0)
 		return 0;
 
-	save_state = kzalloc(sizeof(*save_state) + sizeof(u16) * 4, GFP_KERNEL);
+	save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
+	if (!save_state)
+		save_state = kzalloc(sizeof(*save_state) + sizeof(u16) * 4, GFP_KERNEL);
 	if (!save_state) {
 		dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n");
 		return -ENOMEM;
@@ -582,8 +584,6 @@
 	pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]);
 	pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]);
 	pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]);
-	pci_remove_saved_cap(save_state);
-	kfree(save_state);
 }
 
 
@@ -597,7 +597,9 @@
 	if (pos <= 0)
 		return 0;
 
-	save_state = kzalloc(sizeof(*save_state) + sizeof(u16), GFP_KERNEL);
+	save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
+	if (!save_state)
+		save_state = kzalloc(sizeof(*save_state) + sizeof(u16), GFP_KERNEL);
 	if (!save_state) {
 		dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n");
 		return -ENOMEM;
@@ -622,8 +624,6 @@
 	cap = (u16 *)&save_state->data[0];
 
 	pci_write_config_word(dev, pos + PCI_X_CMD, cap[i++]);
-	pci_remove_saved_cap(save_state);
-	kfree(save_state);
 }
 
 
@@ -638,8 +638,6 @@
 	/* XXX: 100% dword access ok here? */
 	for (i = 0; i < 16; i++)
 		pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]);
-	if ((i = pci_save_msi_state(dev)) != 0)
-		return i;
 	if ((i = pci_save_pcie_state(dev)) != 0)
 		return i;
 	if ((i = pci_save_pcix_state(dev)) != 0)
@@ -757,7 +755,8 @@
  * when a device is enabled using managed PCI device enable interface.
  */
 struct pci_devres {
-	unsigned int disable:1;
+	unsigned int enabled:1;
+	unsigned int pinned:1;
 	unsigned int orig_intx:1;
 	unsigned int restore_intx:1;
 	u32 region_mask;
@@ -781,7 +780,7 @@
 	if (this->restore_intx)
 		pci_intx(dev, this->orig_intx);
 
-	if (this->disable)
+	if (this->enabled && !this->pinned)
 		pci_disable_device(dev);
 }
 
@@ -820,12 +819,12 @@
 	dr = get_pci_dr(pdev);
 	if (unlikely(!dr))
 		return -ENOMEM;
-	WARN_ON(!!dr->disable);
+	WARN_ON(!!dr->enabled);
 
 	rc = pci_enable_device(pdev);
 	if (!rc) {
 		pdev->is_managed = 1;
-		dr->disable = 1;
+		dr->enabled = 1;
 	}
 	return rc;
 }
@@ -843,9 +842,9 @@
 	struct pci_devres *dr;
 
 	dr = find_pci_dr(pdev);
-	WARN_ON(!dr || !dr->disable);
+	WARN_ON(!dr || !dr->enabled);
 	if (dr)
-		dr->disable = 0;
+		dr->pinned = 1;
 }
 
 /**
@@ -876,7 +875,7 @@
 
 	dr = find_pci_dr(dev);
 	if (dr)
-		dr->disable = 0;
+		dr->enabled = 0;
 
 	if (atomic_sub_return(1, &dev->enable_cnt) != 0)
 		return;
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index ae7a975..62ea04c 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -52,10 +52,8 @@
 #endif
 
 #if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM)
-int pci_save_msi_state(struct pci_dev *dev);
 void pci_restore_msi_state(struct pci_dev *dev);
 #else
-static inline int pci_save_msi_state(struct pci_dev *dev) { return 0; }
 static inline void pci_restore_msi_state(struct pci_dev *dev) {}
 #endif
 
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index b164de0..db6ad8e 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -66,7 +66,7 @@
 	.resume = aer_error_resume,
 };
 
-static struct pcie_port_service_driver aerdrv = {
+static struct pcie_port_service_driver aerdriver = {
 	.name		= "aer",
 	.id_table	= &aer_id[0],
 
@@ -328,7 +328,7 @@
  **/
 static int __init aer_service_init(void)
 {
-	return pcie_port_service_register(&aerdrv);
+	return pcie_port_service_register(&aerdriver);
 }
 
 /**
@@ -338,7 +338,7 @@
  **/
 static void __exit aer_service_exit(void)
 {
-	pcie_port_service_unregister(&aerdrv);
+	pcie_port_service_unregister(&aerdriver);
 }
 
 module_init(aer_service_init);
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index f17e7ed..df38364 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -93,7 +93,7 @@
         if (!dev->irq && dev->pin) {
 		printk(KERN_WARNING 
 		"%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n", 
-		__FUNCTION__, dev->device, dev->vendor);
+		__FUNCTION__, dev->vendor, dev->device);
 	}
 	if (pcie_port_device_register(dev)) {
 		pci_disable_device(dev);
@@ -276,7 +276,7 @@
 		.resume = pcie_portdrv_err_resume,
 };
 
-static struct pci_driver pcie_portdrv = {
+static struct pci_driver pcie_portdriver = {
 	.name		= (char *)device_name,
 	.id_table	= &port_pci_ids[0],
 
@@ -298,7 +298,7 @@
 		printk(KERN_WARNING "PCIE: bus_register error: %d\n", retval);
 		goto out;
 	}
-	retval = pci_register_driver(&pcie_portdrv);
+	retval = pci_register_driver(&pcie_portdriver);
 	if (retval)
 		pcie_port_bus_unregister();
  out:
@@ -307,7 +307,7 @@
 
 static void __exit pcie_portdrv_exit(void) 
 {
-	pci_unregister_driver(&pcie_portdrv);
+	pci_unregister_driver(&pcie_portdriver);
 	pcie_port_bus_unregister();
 }
 
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 7f94fc0..65d6f23 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -963,6 +963,13 @@
  * bridge. Unfortunately, this device has no subvendor/subdevice ID. So it 
  * becomes necessary to do this tweak in two steps -- I've chosen the Host
  * bridge as trigger.
+ *
+ * Note that we used to unhide the SMBus that way on Toshiba laptops
+ * (Satellite A40 and Tecra M2) but then found that the thermal management
+ * was done by SMM code, which could cause unsynchronized concurrent
+ * accesses to the SMBus registers, with potentially bad effects. Thus you
+ * should be very careful when adding new entries: if SMM is accessing the
+ * Intel SMBus, this is a very good reason to leave it hidden.
  */
 static int asus_hides_smbus;
 
@@ -1040,17 +1047,6 @@
 			case 0x099c: /* HP Compaq nx6110 */
 				asus_hides_smbus = 1;
 			}
-	} else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_TOSHIBA)) {
-		if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB)
-			switch(dev->subsystem_device) {
-			case 0x0001: /* Toshiba Satellite A40 */
-				asus_hides_smbus = 1;
-			}
-		else if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
-			switch(dev->subsystem_device) {
-			case 0x0001: /* Toshiba Tecra M2 */
-				asus_hides_smbus = 1;
-			}
        } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG)) {
                if (dev->device ==  PCI_DEVICE_ID_INTEL_82855PM_HB)
                        switch(dev->subsystem_device) {
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index ff98ead..2dd8681 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -15,7 +15,7 @@
 
 DECLARE_RWSEM(pci_bus_sem);
 
-static struct pci_bus * __devinit
+static struct pci_bus *
 pci_do_find_bus(struct pci_bus* bus, unsigned char busnr)
 {
 	struct pci_bus* child;
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
index 551bde5..b693367 100644
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -372,7 +372,7 @@
 		skt->socket.resource_ops = &pccard_static_ops;
 		skt->socket.ops = &au1x00_pcmcia_operations;
 		skt->socket.owner = ops->owner;
-		skt->socket.dev.dev = dev;
+		skt->socket.dev.parent = dev;
 
 		init_timer(&skt->poll_timer);
 		skt->poll_timer.function = au1x00_pcmcia_poll_event;
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index d77f751..2df216b0 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -202,15 +202,14 @@
  * "what chipselect is used".  Boards could want more.
  */
 
-static int __devinit omap_cf_probe(struct device *dev)
+static int __init omap_cf_probe(struct platform_device *pdev)
 {
 	unsigned		seg;
 	struct omap_cf_socket	*cf;
-	struct platform_device	*pdev = to_platform_device(dev);
 	int			irq;
 	int			status;
 
-	seg = (int) dev->platform_data;
+	seg = (int) pdev->dev.platform_data;
 	if (seg == 0 || seg > 3)
 		return -ENODEV;
 
@@ -227,7 +226,7 @@
 	cf->timer.data = (unsigned long) cf;
 
 	cf->pdev = pdev;
-	dev_set_drvdata(dev, cf);
+	platform_set_drvdata(pdev, cf);
 
 	/* this primarily just shuts up irq handling noise */
 	status = request_irq(irq, omap_cf_irq, IRQF_SHARED,
@@ -291,7 +290,7 @@
 		omap_cf_present() ? "present" : "(not present)");
 
 	cf->socket.owner = THIS_MODULE;
-	cf->socket.dev.parent = dev;
+	cf->socket.dev.parent = &pdev->dev;
 	cf->socket.ops = &omap_cf_ops;
 	cf->socket.resource_ops = &pccard_static_ops;
 	cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP
@@ -318,9 +317,9 @@
 	return status;
 }
 
-static int __devexit omap_cf_remove(struct device *dev)
+static int __exit omap_cf_remove(struct platform_device *pdev)
 {
-	struct omap_cf_socket *cf = dev_get_drvdata(dev);
+	struct omap_cf_socket *cf = platform_get_drvdata(pdev);
 
 	cf->active = 0;
 	pcmcia_unregister_socket(&cf->socket);
@@ -332,26 +331,36 @@
 	return 0;
 }
 
-static struct device_driver omap_cf_driver = {
-	.name		= (char *) driver_name,
-	.bus		= &platform_bus_type,
-	.probe		= omap_cf_probe,
-	.remove		= __devexit_p(omap_cf_remove),
-	.suspend	= pcmcia_socket_dev_suspend,
-	.resume		= pcmcia_socket_dev_resume,
+static int omap_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
+{
+	return pcmcia_socket_dev_suspend(&pdev->dev, mesg);
+}
+
+static int omap_cf_resume(struct platform_device *pdev)
+{
+	return pcmcia_socket_dev_resume(&pdev->dev);
+}
+
+static struct platform_driver omap_cf_driver = {
+	.driver = {
+		.name	= (char *) driver_name,
+	},
+	.remove		= __exit_p(omap_cf_remove),
+	.suspend	= omap_cf_suspend,
+	.resume		= omap_cf_resume,
 };
 
 static int __init omap_cf_init(void)
 {
 	if (cpu_is_omap16xx())
-		return driver_register(&omap_cf_driver);
+		return platform_driver_probe(&omap_cf_driver, omap_cf_probe);
 	return -ENODEV;
 }
 
 static void __exit omap_cf_exit(void)
 {
 	if (cpu_is_omap16xx())
-		driver_unregister(&omap_cf_driver);
+		platform_driver_unregister(&omap_cf_driver);
 }
 
 module_init(omap_cf_init);
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index 5026b34..57e6ab1 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -451,7 +451,7 @@
 		return -EINVAL;
 
 	if(!pnp_can_configure(dev)) {
-		pnp_info("Device %s does not support resource configuration.", dev->dev.bus_id);
+		pnp_dbg("Device %s does not support resource configuration.", dev->dev.bus_id);
 		return -ENODEV;
 	}
 
@@ -482,7 +482,7 @@
 int pnp_start_dev(struct pnp_dev *dev)
 {
 	if (!pnp_can_write(dev)) {
-		pnp_info("Device %s does not support activation.", dev->dev.bus_id);
+		pnp_dbg("Device %s does not support activation.", dev->dev.bus_id);
 		return -EINVAL;
 	}
 
@@ -506,7 +506,7 @@
 int pnp_stop_dev(struct pnp_dev *dev)
 {
 	if (!pnp_can_disable(dev)) {
-		pnp_info("Device %s does not support disabling.", dev->dev.bus_id);
+		pnp_dbg("Device %s does not support disabling.", dev->dev.bus_id);
 		return -EINVAL;
 	}
 	if (dev->protocol->disable(dev)<0) {
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 7a53554..118ac97 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -89,6 +89,7 @@
 		return;
 
 	res->irq_resource[i].flags = IORESOURCE_IRQ;  // Also clears _UNSET flag
+	res->irq_resource[i].flags |= irq_flags(triggering, polarity);
 	irq = acpi_register_gsi(gsi, triggering, polarity);
 	if (irq < 0) {
 		res->irq_resource[i].flags |= IORESOURCE_DISABLED;
@@ -103,8 +104,52 @@
 	pcibios_penalize_isa_irq(irq, 1);
 }
 
+static int dma_flags(int type, int bus_master, int transfer)
+{
+	int flags = 0;
+
+	if (bus_master)
+		flags |= IORESOURCE_DMA_MASTER;
+	switch (type) {
+	case ACPI_COMPATIBILITY:
+		flags |= IORESOURCE_DMA_COMPATIBLE;
+		break;
+	case ACPI_TYPE_A:
+		flags |= IORESOURCE_DMA_TYPEA;
+		break;
+	case ACPI_TYPE_B:
+		flags |= IORESOURCE_DMA_TYPEB;
+		break;
+	case ACPI_TYPE_F:
+		flags |= IORESOURCE_DMA_TYPEF;
+		break;
+	default:
+		/* Set a default value ? */
+		flags |= IORESOURCE_DMA_COMPATIBLE;
+		pnp_err("Invalid DMA type");
+	}
+	switch (transfer) {
+	case ACPI_TRANSFER_8:
+		flags |= IORESOURCE_DMA_8BIT;
+		break;
+	case ACPI_TRANSFER_8_16:
+		flags |= IORESOURCE_DMA_8AND16BIT;
+		break;
+	case ACPI_TRANSFER_16:
+		flags |= IORESOURCE_DMA_16BIT;
+		break;
+	default:
+		/* Set a default value ? */
+		flags |= IORESOURCE_DMA_8AND16BIT;
+		pnp_err("Invalid DMA transfer type");
+	}
+
+	return flags;
+}
+
 static void
-pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, u32 dma)
+pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, u32 dma,
+	int type, int bus_master, int transfer)
 {
 	int i = 0;
 	while (i < PNP_MAX_DMA &&
@@ -112,6 +157,7 @@
 		i++;
 	if (i < PNP_MAX_DMA) {
 		res->dma_resource[i].flags = IORESOURCE_DMA;  // Also clears _UNSET flag
+		res->dma_resource[i].flags |= dma_flags(type, bus_master, transfer);
 		if (dma == -1) {
 			res->dma_resource[i].flags |= IORESOURCE_DISABLED;
 			return;
@@ -123,7 +169,7 @@
 
 static void
 pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res,
-	u64 io, u64 len)
+	u64 io, u64 len, int io_decode)
 {
 	int i = 0;
 	while (!(res->port_resource[i].flags & IORESOURCE_UNSET) &&
@@ -131,6 +177,8 @@
 		i++;
 	if (i < PNP_MAX_PORT) {
 		res->port_resource[i].flags = IORESOURCE_IO;  // Also clears _UNSET flag
+		if (io_decode == ACPI_DECODE_16)
+			res->port_resource[i].flags |= PNP_PORT_FLAG_16BITADDR;
 		if (len <= 0 || (io + len -1) >= 0x10003) {
 			res->port_resource[i].flags |= IORESOURCE_DISABLED;
 			return;
@@ -142,7 +190,7 @@
 
 static void
 pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res,
-	u64 mem, u64 len)
+	u64 mem, u64 len, int write_protect)
 {
 	int i = 0;
 	while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) &&
@@ -154,6 +202,9 @@
 			res->mem_resource[i].flags |= IORESOURCE_DISABLED;
 			return;
 		}
+		if(write_protect == ACPI_READ_WRITE_MEMORY)
+			res->mem_resource[i].flags |= IORESOURCE_MEM_WRITEABLE;
+
 		res->mem_resource[i].start = mem;
 		res->mem_resource[i].end = mem + len - 1;
 	}
@@ -178,10 +229,11 @@
 
 	if (p->resource_type == ACPI_MEMORY_RANGE)
 		pnpacpi_parse_allocated_memresource(res_table,
-				p->minimum, p->address_length);
+				p->minimum, p->address_length, p->info.mem.write_protect);
 	else if (p->resource_type == ACPI_IO_RANGE)
 		pnpacpi_parse_allocated_ioresource(res_table,
-				p->minimum, p->address_length);
+				p->minimum, p->address_length,
+				p->granularity == 0xfff ? ACPI_DECODE_10 : ACPI_DECODE_16);
 }
 
 static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
@@ -208,13 +260,17 @@
 	case ACPI_RESOURCE_TYPE_DMA:
 		if (res->data.dma.channel_count > 0)
 			pnpacpi_parse_allocated_dmaresource(res_table,
-					res->data.dma.channels[0]);
+					res->data.dma.channels[0],
+					res->data.dma.type,
+					res->data.dma.bus_master,
+					res->data.dma.transfer);
 		break;
 
 	case ACPI_RESOURCE_TYPE_IO:
 		pnpacpi_parse_allocated_ioresource(res_table,
 				res->data.io.minimum,
-				res->data.io.address_length);
+				res->data.io.address_length,
+				res->data.io.io_decode);
 		break;
 
 	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -224,7 +280,8 @@
 	case ACPI_RESOURCE_TYPE_FIXED_IO:
 		pnpacpi_parse_allocated_ioresource(res_table,
 				res->data.fixed_io.address,
-				res->data.fixed_io.address_length);
+				res->data.fixed_io.address_length,
+				ACPI_DECODE_10);
 		break;
 
 	case ACPI_RESOURCE_TYPE_VENDOR:
@@ -236,17 +293,20 @@
 	case ACPI_RESOURCE_TYPE_MEMORY24:
 		pnpacpi_parse_allocated_memresource(res_table,
 				res->data.memory24.minimum,
-				res->data.memory24.address_length);
+				res->data.memory24.address_length,
+				res->data.memory24.write_protect);
 		break;
 	case ACPI_RESOURCE_TYPE_MEMORY32:
 		pnpacpi_parse_allocated_memresource(res_table,
 				res->data.memory32.minimum,
-				res->data.memory32.address_length);
+				res->data.memory32.address_length,
+				res->data.memory32.write_protect);
 		break;
 	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
 		pnpacpi_parse_allocated_memresource(res_table,
 				res->data.fixed_memory32.address,
-				res->data.fixed_memory32.address_length);
+				res->data.fixed_memory32.address_length,
+				res->data.fixed_memory32.write_protect);
 		break;
 	case ACPI_RESOURCE_TYPE_ADDRESS16:
 	case ACPI_RESOURCE_TYPE_ADDRESS32:
@@ -304,42 +364,8 @@
 
 	for(i = 0; i < p->channel_count; i++)
 		dma->map |= 1 << p->channels[i];
-	dma->flags = 0;
-	if (p->bus_master)
-		dma->flags |= IORESOURCE_DMA_MASTER;
-	switch (p->type) {
-	case ACPI_COMPATIBILITY:
-		dma->flags |= IORESOURCE_DMA_COMPATIBLE;
-		break;
-	case ACPI_TYPE_A:
-		dma->flags |= IORESOURCE_DMA_TYPEA;
-		break;
-	case ACPI_TYPE_B:
-		dma->flags |= IORESOURCE_DMA_TYPEB;
-		break;
-	case ACPI_TYPE_F:
-		dma->flags |= IORESOURCE_DMA_TYPEF;
-		break;
-	default:
-		/* Set a default value ? */
-		dma->flags |= IORESOURCE_DMA_COMPATIBLE;
-		pnp_err("Invalid DMA type");
-	}
-	switch (p->transfer) {
-	case ACPI_TRANSFER_8:
-		dma->flags |= IORESOURCE_DMA_8BIT;
-		break;
-	case ACPI_TRANSFER_8_16:
-		dma->flags |= IORESOURCE_DMA_8AND16BIT;
-		break;
-	case ACPI_TRANSFER_16:
-		dma->flags |= IORESOURCE_DMA_16BIT;
-		break;
-	default:
-		/* Set a default value ? */
-		dma->flags |= IORESOURCE_DMA_8AND16BIT;
-		pnp_err("Invalid DMA transfer type");
-	}
+
+	dma->flags = dma_flags(p->type, p->bus_master, p->transfer);
 
 	pnp_register_dma_resource(option, dma);
 	return;
diff --git a/drivers/pnp/system.c b/drivers/pnp/system.c
index 2065e74..a8a9554 100644
--- a/drivers/pnp/system.c
+++ b/drivers/pnp/system.c
@@ -22,7 +22,7 @@
 	{	"",			0	}
 };
 
-static void reserve_range(char *pnpid, int start, int end, int port)
+static void reserve_range(const char *pnpid, resource_size_t start, resource_size_t end, int port)
 {
 	struct resource *res;
 	char *regionid;
@@ -32,9 +32,9 @@
 		return;
 	snprintf(regionid, 16, "pnp %s", pnpid);
 	if (port)
-		res = request_region(start,end-start+1,regionid);
+		res = request_region(start, end-start+1, regionid);
 	else
-		res = request_mem_region(start,end-start+1,regionid);
+		res = request_mem_region(start, end-start+1, regionid);
 	if (res == NULL)
 		kfree(regionid);
 	else
@@ -45,12 +45,13 @@
 	 * have double reservations.
 	 */
 	printk(KERN_INFO
-		"pnp: %s: %s range 0x%x-0x%x %s reserved\n",
-		pnpid, port ? "ioport" : "iomem", start, end,
+		"pnp: %s: %s range 0x%llx-0x%llx %s reserved\n",
+		pnpid, port ? "ioport" : "iomem",
+                (unsigned long long)start, (unsigned long long)end,
 		NULL != res ? "has been" : "could not be");
 }
 
-static void reserve_resources_of_dev(struct pnp_dev *dev)
+static void reserve_resources_of_dev(const struct pnp_dev *dev)
 {
 	int i;
 
diff --git a/drivers/ps3/ps3av_cmd.c b/drivers/ps3/ps3av_cmd.c
index 21c97c8..bc70e81 100644
--- a/drivers/ps3/ps3av_cmd.c
+++ b/drivers/ps3/ps3av_cmd.c
@@ -485,12 +485,12 @@
 
 static const u32 ps3av_ns_table[][5] = {
 					/*   D1,    D2,    D3,    D4,    D5 */
-	[PS3AV_CMD_AUDIO_FS_44K-BASE]	{  6272,  6272, 17836, 17836,  8918 },
-	[PS3AV_CMD_AUDIO_FS_48K-BASE]	{  6144,  6144, 11648, 11648,  5824 },
-	[PS3AV_CMD_AUDIO_FS_88K-BASE]	{ 12544, 12544, 35672, 35672, 17836 },
-	[PS3AV_CMD_AUDIO_FS_96K-BASE]	{ 12288, 12288, 23296, 23296, 11648 },
-	[PS3AV_CMD_AUDIO_FS_176K-BASE]	{ 25088, 25088, 71344, 71344, 35672 },
-	[PS3AV_CMD_AUDIO_FS_192K-BASE]	{ 24576, 24576, 46592, 46592, 23296 }
+	[PS3AV_CMD_AUDIO_FS_44K-BASE] =	{  6272,  6272, 17836, 17836,  8918 },
+	[PS3AV_CMD_AUDIO_FS_48K-BASE] =	{  6144,  6144, 11648, 11648,  5824 },
+	[PS3AV_CMD_AUDIO_FS_88K-BASE] =	{ 12544, 12544, 35672, 35672, 17836 },
+	[PS3AV_CMD_AUDIO_FS_96K-BASE] =	{ 12288, 12288, 23296, 23296, 11648 },
+	[PS3AV_CMD_AUDIO_FS_176K-BASE] =	{ 25088, 25088, 71344, 71344, 35672 },
+	[PS3AV_CMD_AUDIO_FS_192K-BASE] =	{ 24576, 24576, 46592, 46592, 23296 }
 };
 
 static void ps3av_cnv_ns(u8 *ns, u32 fs, u32 video_vid)
@@ -543,9 +543,10 @@
 
 #undef BASE
 
-static u8 ps3av_cnv_enable(u32 source, u8 *enable)
+static u8 ps3av_cnv_enable(u32 source, const u8 *enable)
 {
-	u8 *p, ret = 0;
+	const u8 *p;
+	u8 ret = 0;
 
 	if (source == PS3AV_CMD_AUDIO_SOURCE_SPDIF) {
 		ret = 0x03;
@@ -559,9 +560,10 @@
 	return ret;
 }
 
-static u8 ps3av_cnv_fifomap(u8 *map)
+static u8 ps3av_cnv_fifomap(const u8 *map)
 {
-	u8 *p, ret = 0;
+	const u8 *p;
+	u8 ret = 0;
 
 	p = map;
 	ret = p[0] + (p[1] << 2) + (p[2] << 4) + (p[3] << 6);
@@ -615,7 +617,7 @@
 	info->pb5.lsv = mode->audio_downmix_level;
 }
 
-static void ps3av_cnv_chstat(u8 *chstat, u8 *cs_info)
+static void ps3av_cnv_chstat(u8 *chstat, const u8 *cs_info)
 {
 	memcpy(chstat, cs_info, 5);
 }
diff --git a/drivers/ps3/vuart.c b/drivers/ps3/vuart.c
index 1adf186..6c12744 100644
--- a/drivers/ps3/vuart.c
+++ b/drivers/ps3/vuart.c
@@ -952,7 +952,7 @@
 	kfree(dev->priv);
 	dev->priv = NULL;
 fail_alloc:
-	vuart_bus_priv.devices[port_number] = 0;
+	vuart_bus_priv.devices[port_number] = NULL;
 fail_match:
 	up(&vuart_bus_priv.probe_mutex);
 	dev_dbg(&dev->core, "%s:%d failed\n", __func__, __LINE__);
@@ -978,7 +978,7 @@
 		dev_dbg(&dev->core, "%s:%d: %s no remove method\n", __func__,
 			__LINE__, dev->core.bus_id);
 
-	vuart_bus_priv.devices[dev->priv->port_number] = 0;
+	vuart_bus_priv.devices[dev->priv->port_number] = NULL;
 
 	if (--vuart_bus_priv.use_count == 0) {
 		BUG();
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 85bf795..7c0d609 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -59,6 +59,19 @@
 
 static const char driver_name[] = "rtc_cmos";
 
+/* The RTC_INTR register may have e.g. RTC_PF set even if RTC_PIE is clear;
+ * always mask it against the irq enable bits in RTC_CONTROL.  Bit values
+ * are the same: PF==PIE, AF=AIE, UF=UIE; so RTC_IRQMASK works with both.
+ */
+#define	RTC_IRQMASK	(RTC_PF | RTC_AF | RTC_UF)
+
+static inline int is_intr(u8 rtc_intr)
+{
+	if (!(rtc_intr & RTC_IRQF))
+		return 0;
+	return rtc_intr & RTC_IRQMASK;
+}
+
 /*----------------------------------------------------------------*/
 
 static int cmos_read_time(struct device *dev, struct rtc_time *t)
@@ -188,7 +201,8 @@
 	rtc_control &= ~RTC_AIE;
 	CMOS_WRITE(rtc_control, RTC_CONTROL);
 	rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
-	if (rtc_intr)
+	rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
+	if (is_intr(rtc_intr))
 		rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr);
 
 	/* update alarm */
@@ -207,7 +221,8 @@
 		rtc_control |= RTC_AIE;
 		CMOS_WRITE(rtc_control, RTC_CONTROL);
 		rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
-		if (rtc_intr)
+		rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
+		if (is_intr(rtc_intr))
 			rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr);
 	}
 
@@ -287,7 +302,8 @@
 	}
 	CMOS_WRITE(rtc_control, RTC_CONTROL);
 	rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
-	if (rtc_intr)
+	rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
+	if (is_intr(rtc_intr))
 		rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr);
 	spin_unlock_irqrestore(&rtc_lock, flags);
 	return 0;
@@ -353,12 +369,10 @@
 
 	spin_lock(&rtc_lock);
 	irqstat = CMOS_READ(RTC_INTR_FLAGS);
+	irqstat &= (CMOS_READ(RTC_CONTROL) & RTC_IRQMASK) | RTC_IRQF;
 	spin_unlock(&rtc_lock);
 
-	if (irqstat) {
-		/* NOTE: irqstat may have e.g. RTC_PF set
-		 * even when RTC_PIE is clear...
-		 */
+	if (is_intr(irqstat)) {
 		rtc_update_irq(p, 1, irqstat);
 		return IRQ_HANDLED;
 	} else
@@ -525,25 +539,26 @@
 {
 	struct cmos_rtc	*cmos = dev_get_drvdata(dev);
 	int		do_wake = device_may_wakeup(dev);
-	unsigned char	tmp, irqstat;
+	unsigned char	tmp;
 
 	/* only the alarm might be a wakeup event source */
 	spin_lock_irq(&rtc_lock);
 	cmos->suspend_ctrl = tmp = CMOS_READ(RTC_CONTROL);
 	if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) {
+		unsigned char	irqstat;
+
 		if (do_wake)
 			tmp &= ~(RTC_PIE|RTC_UIE);
 		else
 			tmp &= ~(RTC_PIE|RTC_AIE|RTC_UIE);
 		CMOS_WRITE(tmp, RTC_CONTROL);
 		irqstat = CMOS_READ(RTC_INTR_FLAGS);
-	} else
-		irqstat = 0;
+		irqstat &= (tmp & RTC_IRQMASK) | RTC_IRQF;
+		if (is_intr(irqstat))
+			rtc_update_irq(&cmos->rtc->class_dev, 1, irqstat);
+	}
 	spin_unlock_irq(&rtc_lock);
 
-	if (irqstat)
-		rtc_update_irq(&cmos->rtc->class_dev, 1, irqstat);
-
 	/* ACPI HOOK:  enable ACPI_EVENT_RTC when (tmp & RTC_AIE)
 	 * ... it'd be best if we could do that under rtc_lock.
 	 */
@@ -573,9 +588,10 @@
 		spin_lock_irq(&rtc_lock);
 		CMOS_WRITE(tmp, RTC_CONTROL);
 		tmp = CMOS_READ(RTC_INTR_FLAGS);
-		spin_unlock_irq(&rtc_lock);
-		if (tmp)
+		tmp &= (cmos->suspend_ctrl & RTC_IRQMASK) | RTC_IRQF;
+		if (is_intr(tmp))
 			rtc_update_irq(&cmos->rtc->class_dev, 1, tmp);
+		spin_unlock_irq(&rtc_lock);
 	}
 
 	pr_debug("%s: resume, ctrl %02x\n",
@@ -594,7 +610,7 @@
 /*----------------------------------------------------------------*/
 
 /* The "CMOS" RTC normally lives on the platform_bus.  On ACPI systems,
- * the device node may alternatively be created as a PNP device.
+ * the device node will always be created as a PNPACPI device.
  */
 
 #ifdef	CONFIG_PNPACPI
@@ -673,7 +689,7 @@
 /*----------------------------------------------------------------*/
 
 /* Platform setup should have set up an RTC device, when PNPACPI is
- * unavailable ... this is the normal case, common even on PCs.
+ * unavailable ... this could happen even on (older) PCs.
  */
 
 static int __init cmos_platform_probe(struct platform_device *pdev)
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index ab782bb..e810e4a 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -65,7 +65,7 @@
  * resulting condition code and DIAG return code. */
 static inline int dia250(void *iob, int cmd)
 {
-	register unsigned long reg0 asm ("0") = (unsigned long) iob;
+	register unsigned long reg2 asm ("2") = (unsigned long) iob;
 	typedef union {
 		struct dasd_diag_init_io init_io;
 		struct dasd_diag_rw_io rw_io;
@@ -74,15 +74,15 @@
 
 	rc = 3;
 	asm volatile(
-		"	diag	0,%2,0x250\n"
+		"	diag	2,%2,0x250\n"
 		"0:	ipm	%0\n"
 		"	srl	%0,28\n"
-		"	or	%0,1\n"
+		"	or	%0,3\n"
 		"1:\n"
 		EX_TABLE(0b,1b)
 		: "+d" (rc), "=m" (*(addr_type *) iob)
-		: "d" (cmd), "d" (reg0), "m" (*(addr_type *) iob)
-		: "1", "cc");
+		: "d" (cmd), "d" (reg2), "m" (*(addr_type *) iob)
+		: "3", "cc");
 	return rc;
 }
 
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index d48e3ca..5aeb68e 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -71,19 +71,31 @@
  * Provide an 'ungroup' attribute so the user can remove group devices no
  * longer needed or accidentially created. Saves memory :)
  */
+static void ccwgroup_ungroup_callback(struct device *dev)
+{
+	struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
+
+	__ccwgroup_remove_symlinks(gdev);
+	device_unregister(dev);
+}
+
 static ssize_t
 ccwgroup_ungroup_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct ccwgroup_device *gdev;
+	int rc;
 
 	gdev = to_ccwgroupdev(dev);
 
 	if (gdev->state != CCWGROUP_OFFLINE)
 		return -EINVAL;
 
-	__ccwgroup_remove_symlinks(gdev);
-	device_unregister(dev);
-
+	/* Note that we cannot unregister the device from one of its
+	 * attribute methods, so we have to use this roundabout approach.
+	 */
+	rc = device_schedule_callback(dev, ccwgroup_ungroup_callback);
+	if (rc)
+		count = rc;
 	return count;
 }
 
diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c
index 6b1caea..aa96e67 100644
--- a/drivers/s390/cio/device_status.c
+++ b/drivers/s390/cio/device_status.c
@@ -221,6 +221,14 @@
 
 	cdev_irb = &cdev->private->irb;
 
+	/*
+	 * If the clear function had been performed, all formerly pending
+	 * status at the subchannel has been cleared and we must not pass
+	 * intermediate accumulated status to the device driver.
+	 */
+	if (irb->scsw.fctl & SCSW_FCTL_CLEAR_FUNC)
+		memset(&cdev->private->irb, 0, sizeof(struct irb));
+
 	/* Copy bits which are valid only for the start function. */
 	if (irb->scsw.fctl & SCSW_FCTL_START_FUNC) {
 		/* Copy key. */
@@ -263,7 +271,11 @@
 		cdev_irb->scsw.cpa = irb->scsw.cpa;
 	/* Accumulate device status, but not the device busy flag. */
 	cdev_irb->scsw.dstat &= ~DEV_STAT_BUSY;
-	cdev_irb->scsw.dstat |= irb->scsw.dstat;
+	/* dstat is not always valid. */
+	if (irb->scsw.stctl &
+	    (SCSW_STCTL_PRIM_STATUS | SCSW_STCTL_SEC_STATUS
+	     | SCSW_STCTL_INTER_STATUS | SCSW_STCTL_ALERT_STATUS))
+		cdev_irb->scsw.dstat |= irb->scsw.dstat;
 	/* Accumulate subchannel status. */
 	cdev_irb->scsw.cstat |= irb->scsw.cstat;
 	/* Copy residual count if it is valid. */
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index 5b1e3ff..05fac07 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -210,9 +210,11 @@
 		goto again;
 	}
 	if (rc < 0) {
-                QDIO_DBF_TEXT3(1,trace,"sqberr");
-                sprintf(dbf_text,"%2x,%2x,%d,%d",tmp_cnt,*cnt,ccq,q_no);
-                QDIO_DBF_TEXT3(1,trace,dbf_text);
+		QDIO_DBF_TEXT3(1,trace,"sqberr");
+		sprintf(dbf_text,"%2x,%2x",tmp_cnt,*cnt);
+		QDIO_DBF_TEXT3(1,trace,dbf_text);
+		sprintf(dbf_text,"%d,%d",ccq,q_no);
+		QDIO_DBF_TEXT3(1,trace,dbf_text);
 		q->handler(q->cdev,QDIO_STATUS_ACTIVATE_CHECK_CONDITION|
 				QDIO_STATUS_LOOK_FOR_ERROR,
 				0, 0, 0, -1, -1, q->int_parm);
@@ -1250,7 +1252,6 @@
 	if (!no_used) {
 		QDIO_DBF_TEXT4(0,trace,"inqisdnA");
 		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
-		QDIO_DBF_TEXT4(0,trace,dbf_text);
 		return 1;
 	}
 	if (irq->is_qebsm) {
@@ -3371,10 +3372,15 @@
 			unsigned int count, struct qdio_buffer *buffers)
 {
 	struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr;
+	int tmp = 0;
+
 	qidx &= (QDIO_MAX_BUFFERS_PER_Q - 1);
 	if (irq->is_qebsm) {
-		while (count)
-			set_slsb(q, &qidx, SLSB_CU_INPUT_EMPTY, &count);
+		while (count) {
+			tmp = set_slsb(q, &qidx, SLSB_CU_INPUT_EMPTY, &count);
+			if (!tmp)
+				return;
+		}
 		return;
 	}
 	for (;;) {
@@ -3390,11 +3396,15 @@
 			 unsigned int count, struct qdio_buffer *buffers)
 {
 	struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr;
+	int tmp = 0;
 
 	qidx &= (QDIO_MAX_BUFFERS_PER_Q - 1);
 	if (irq->is_qebsm) {
-		while (count)
-			set_slsb(q, &qidx, SLSB_CU_OUTPUT_PRIMED, &count);
+		while (count) {
+			tmp = set_slsb(q, &qidx, SLSB_CU_OUTPUT_PRIMED, &count);
+			if (!tmp)
+				return;
+		}
 		return;
 	}
 
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index c7d1355..bf37cdf 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -65,6 +65,8 @@
 MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 1 (on).");
 
 static struct device *ap_root_device = NULL;
+static DEFINE_SPINLOCK(ap_device_lock);
+static LIST_HEAD(ap_device_list);
 
 /**
  * Workqueue & timer for bus rescan.
@@ -457,6 +459,9 @@
 	int rc;
 
 	ap_dev->drv = ap_drv;
+	spin_lock_bh(&ap_device_lock);
+	list_add(&ap_dev->list, &ap_device_list);
+	spin_unlock_bh(&ap_device_lock);
 	rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
 	return rc;
 }
@@ -497,6 +502,12 @@
 	ap_flush_queue(ap_dev);
 	if (ap_drv->remove)
 		ap_drv->remove(ap_dev);
+	spin_lock_bh(&ap_device_lock);
+	list_del_init(&ap_dev->list);
+	spin_unlock_bh(&ap_device_lock);
+	spin_lock_bh(&ap_dev->lock);
+	atomic_sub(ap_dev->queue_count, &ap_poll_requests);
+	spin_unlock_bh(&ap_dev->lock);
 	return 0;
 }
 
@@ -749,10 +760,16 @@
 				      (void *)(unsigned long)qid,
 				      __ap_scan_bus);
 		rc = ap_query_queue(qid, &queue_depth, &device_type);
-		if (dev && rc) {
-			put_device(dev);
-			device_unregister(dev);
-			continue;
+		if (dev) {
+			ap_dev = to_ap_dev(dev);
+			spin_lock_bh(&ap_dev->lock);
+			if (rc || ap_dev->unregistered) {
+				spin_unlock_bh(&ap_dev->lock);
+				put_device(dev);
+				device_unregister(dev);
+				continue;
+			} else
+				spin_unlock_bh(&ap_dev->lock);
 		}
 		if (dev) {
 			put_device(dev);
@@ -772,6 +789,7 @@
 		spin_lock_init(&ap_dev->lock);
 		INIT_LIST_HEAD(&ap_dev->pendingq);
 		INIT_LIST_HEAD(&ap_dev->requestq);
+		INIT_LIST_HEAD(&ap_dev->list);
 		if (device_type == 0)
 			ap_probe_device_type(ap_dev);
 		else
@@ -852,6 +870,7 @@
 	case AP_RESPONSE_NO_PENDING_REPLY:
 		if (status.queue_empty) {
 			/* The card shouldn't forget requests but who knows. */
+			atomic_sub(ap_dev->queue_count, &ap_poll_requests);
 			ap_dev->queue_count = 0;
 			list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
 			ap_dev->requestq_count += ap_dev->pendingq_count;
@@ -985,7 +1004,7 @@
 			ap_dev->unregistered = 1;
 	} else {
 		ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
-		rc = 0;
+		rc = -ENODEV;
 	}
 	spin_unlock_bh(&ap_dev->lock);
 	if (rc == -ENODEV)
@@ -1033,31 +1052,29 @@
  * polling until bit 2^0 of the control flags is not set. If bit 2^1
  * of the control flags has been set arm the poll timer.
  */
-static int __ap_poll_all(struct device *dev, void *data)
+static int __ap_poll_all(struct ap_device *ap_dev, unsigned long *flags)
 {
-	struct ap_device *ap_dev = to_ap_dev(dev);
-	int rc;
-
 	spin_lock(&ap_dev->lock);
 	if (!ap_dev->unregistered) {
-		rc = ap_poll_queue(to_ap_dev(dev), (unsigned long *) data);
-		if (rc)
+		if (ap_poll_queue(ap_dev, flags))
 			ap_dev->unregistered = 1;
-	} else
-		rc = 0;
+	}
 	spin_unlock(&ap_dev->lock);
-	if (rc)
-		device_unregister(&ap_dev->device);
 	return 0;
 }
 
 static void ap_poll_all(unsigned long dummy)
 {
 	unsigned long flags;
+	struct ap_device *ap_dev;
 
 	do {
 		flags = 0;
-		bus_for_each_dev(&ap_bus_type, NULL, &flags, __ap_poll_all);
+		spin_lock(&ap_device_lock);
+		list_for_each_entry(ap_dev, &ap_device_list, list) {
+			__ap_poll_all(ap_dev, &flags);
+		}
+		spin_unlock(&ap_device_lock);
 	} while (flags & 1);
 	if (flags & 2)
 		ap_schedule_poll_timer();
@@ -1075,6 +1092,7 @@
 	DECLARE_WAITQUEUE(wait, current);
 	unsigned long flags;
 	int requests;
+	struct ap_device *ap_dev;
 
 	set_user_nice(current, 19);
 	while (1) {
@@ -1092,10 +1110,12 @@
 		set_current_state(TASK_RUNNING);
 		remove_wait_queue(&ap_poll_wait, &wait);
 
-		local_bh_disable();
 		flags = 0;
-		bus_for_each_dev(&ap_bus_type, NULL, &flags, __ap_poll_all);
-		local_bh_enable();
+		spin_lock_bh(&ap_device_lock);
+		list_for_each_entry(ap_dev, &ap_device_list, list) {
+			__ap_poll_all(ap_dev, &flags);
+		}
+		spin_unlock_bh(&ap_device_lock);
 	}
 	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&ap_poll_wait, &wait);
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
index 83b69c0..008559e 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -106,6 +106,7 @@
 	struct device device;
 	struct ap_driver *drv;		/* Pointer to AP device driver. */
 	spinlock_t lock;		/* Per device lock. */
+	struct list_head list;		/* private list of all AP devices. */
 
 	ap_qid_t qid;			/* AP queue id. */
 	int queue_depth;		/* AP queue depth.*/
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 9976139..e3625a4 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -298,14 +298,14 @@
 		get_device(&zdev->ap_dev->device);
 		zdev->request_count++;
 		__zcrypt_decrease_preference(zdev);
-		spin_unlock_bh(&zcrypt_device_lock);
 		if (try_module_get(zdev->ap_dev->drv->driver.owner)) {
+			spin_unlock_bh(&zcrypt_device_lock);
 			rc = zdev->ops->rsa_modexpo(zdev, mex);
+			spin_lock_bh(&zcrypt_device_lock);
 			module_put(zdev->ap_dev->drv->driver.owner);
 		}
 		else
 			rc = -EAGAIN;
-		spin_lock_bh(&zcrypt_device_lock);
 		zdev->request_count--;
 		__zcrypt_increase_preference(zdev);
 		put_device(&zdev->ap_dev->device);
@@ -373,14 +373,14 @@
 		get_device(&zdev->ap_dev->device);
 		zdev->request_count++;
 		__zcrypt_decrease_preference(zdev);
-		spin_unlock_bh(&zcrypt_device_lock);
 		if (try_module_get(zdev->ap_dev->drv->driver.owner)) {
+			spin_unlock_bh(&zcrypt_device_lock);
 			rc = zdev->ops->rsa_modexpo_crt(zdev, crt);
+			spin_lock_bh(&zcrypt_device_lock);
 			module_put(zdev->ap_dev->drv->driver.owner);
 		}
 		else
 			rc = -EAGAIN;
-		spin_lock_bh(&zcrypt_device_lock);
 		zdev->request_count--;
 		__zcrypt_increase_preference(zdev);
 		put_device(&zdev->ap_dev->device);
@@ -408,14 +408,14 @@
 		get_device(&zdev->ap_dev->device);
 		zdev->request_count++;
 		__zcrypt_decrease_preference(zdev);
-		spin_unlock_bh(&zcrypt_device_lock);
 		if (try_module_get(zdev->ap_dev->drv->driver.owner)) {
+			spin_unlock_bh(&zcrypt_device_lock);
 			rc = zdev->ops->send_cprb(zdev, xcRB);
+			spin_lock_bh(&zcrypt_device_lock);
 			module_put(zdev->ap_dev->drv->driver.owner);
 		}
 		else
 			rc = -EAGAIN;
-		spin_lock_bh(&zcrypt_device_lock);
 		zdev->request_count--;
 		__zcrypt_increase_preference(zdev);
 		put_device(&zdev->ap_dev->device);
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index e95c281..84b108d 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -873,7 +873,7 @@
 }
 
 static inline struct sk_buff *
-qeth_pskb_unshare(struct sk_buff *skb, int pri)
+qeth_pskb_unshare(struct sk_buff *skb, gfp_t pri)
 {
         struct sk_buff *nskb;
         if (!skb_cloned(skb))
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 8c81cec..60446b8 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -3091,6 +3091,7 @@
             cmdp->u.raw64.direction  = 
                 gdth_direction_tab[scp->cmnd[0]]==DOU ? GDTH_DATA_OUT:GDTH_DATA_IN;
             memcpy(cmdp->u.raw64.cmd,scp->cmnd,16);
+            cmdp->u.raw64.sg_ranz    = 0;
         } else {
             cmdp->u.raw.reserved   = 0;
             cmdp->u.raw.mdisc_time = 0;
@@ -3107,6 +3108,7 @@
             cmdp->u.raw.direction  = 
                 gdth_direction_tab[scp->cmnd[0]]==DOU ? GDTH_DATA_OUT:GDTH_DATA_IN;
             memcpy(cmdp->u.raw.cmd,scp->cmnd,12);
+            cmdp->u.raw.sg_ranz    = 0;
         }
 
         if (scp->use_sg) {
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 9d014e5..057fd7e0 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -1817,10 +1817,9 @@
 	struct lpfc_sli *psli = &phba->sli;
 	struct lpfc_sli_ring  *pring;
 
-	if (state == pci_channel_io_perm_failure) {
-		lpfc_pci_remove_one(pdev);
+	if (state == pci_channel_io_perm_failure)
 		return PCI_ERS_RESULT_DISCONNECT;
-	}
+
 	pci_disable_device(pdev);
 	/*
 	 * There may be I/Os dropped by the firmware.
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index b8edcf5..918bb60 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -716,7 +716,7 @@
 	 */
 	if (copy_sense) {
 		if (!SCSI_SENSE_VALID(scmd)) {
-			memcpy(scmd->sense_buffer, scmd->request_buffer,
+			memcpy(scmd->sense_buffer, page_address(sgl.page),
 			       sizeof(scmd->sense_buffer));
 		}
 		__free_page(sgl.page);
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index c275dca..939de0d 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -452,10 +452,22 @@
 }
 static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field);
 
+static void sdev_store_delete_callback(struct device *dev)
+{
+	scsi_remove_device(to_scsi_device(dev));
+}
+
 static ssize_t sdev_store_delete(struct device *dev, struct device_attribute *attr, const char *buf,
 				 size_t count)
 {
-	scsi_remove_device(to_scsi_device(dev));
+	int rc;
+
+	/* An attribute cannot be unregistered by one of its own methods,
+	 * so we have to use this roundabout approach.
+	 */
+	rc = device_schedule_callback(dev, sdev_store_delete_callback);
+	if (rc)
+		count = rc;
 	return count;
 };
 static DEVICE_ATTR(delete, S_IWUSR, NULL, sdev_store_delete);
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index cde5db4..301c8c0 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -340,6 +340,9 @@
 	{       "FUJ02B8",              0 },
 	{       "FUJ02B9",              0 },
 	{       "FUJ02BC",              0 },
+	/* Fujitsu Wacom Tablet PC devices */
+	{	"FUJ02E5",		0	},
+	{	"FUJ02E6",		0	},
 	/* Rockwell's (PORALiNK) 33600 INT PNP */
 	{	"WCI0003",		0	},
 	/* Unkown PnP modems */
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index c53b696..46c40bb 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -17,6 +17,9 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  */
+#if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
 
 #undef DEBUG
 
@@ -49,11 +52,6 @@
 #endif
 
 #include <asm/sci.h>
-
-#if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-#define SUPPORT_SYSRQ
-#endif
-
 #include "sh-sci.h"
 
 struct sci_port {
@@ -645,6 +643,9 @@
 	struct tty_struct *tty = port->info->tty;
 	struct sci_port *s = &sci_ports[port->line];
 
+	if (uart_handle_break(port))
+		return 0;
+
 	if (!s->break_flag && status & SCxSR_BRK(port)) {
 #if defined(CONFIG_CPU_SH3)
 		/* Debounce break */
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c
index 253ceb8..a27e9e9 100644
--- a/drivers/serial/sn_console.c
+++ b/drivers/serial/sn_console.c
@@ -636,25 +636,6 @@
 }
 
 /**
- * sn_sal_connect_interrupt - Request interrupt, handled by sn_sal_interrupt
- * @port: Our sn_cons_port (which contains the uart port)
- *
- * returns the console irq if interrupt is successfully registered, else 0
- *
- */
-static int sn_sal_connect_interrupt(struct sn_cons_port *port)
-{
-	if (request_irq(SGI_UART_VECTOR, sn_sal_interrupt,
-			IRQF_DISABLED | IRQF_SHARED,
-			"SAL console driver", port) >= 0) {
-		return SGI_UART_VECTOR;
-	}
-
-	printk(KERN_INFO "sn_console: console proceeding in polled mode\n");
-	return 0;
-}
-
-/**
  * sn_sal_timer_poll - this function handles polled console mode
  * @data: A pointer to our sn_cons_port (which contains the uart port)
  *
@@ -746,30 +727,31 @@
  * mode.  We were previously in asynch/polling mode (using init_timer).
  *
  * We attempt to switch to interrupt mode here by calling
- * sn_sal_connect_interrupt.  If that works out, we enable receive interrupts.
+ * request_irq.  If that works out, we enable receive interrupts.
  */
 static void __init sn_sal_switch_to_interrupts(struct sn_cons_port *port)
 {
-	int irq;
 	unsigned long flags;
 
-	if (!port)
-		return;
+	if (port) {
+		DPRINTF("sn_console: switching to interrupt driven console\n");
 
-	DPRINTF("sn_console: switching to interrupt driven console\n");
+		if (request_irq(SGI_UART_VECTOR, sn_sal_interrupt,
+				IRQF_DISABLED | IRQF_SHARED,
+				"SAL console driver", port) >= 0) {
+			spin_lock_irqsave(&port->sc_port.lock, flags);
+			port->sc_port.irq = SGI_UART_VECTOR;
+			port->sc_ops = &intr_ops;
 
-	spin_lock_irqsave(&port->sc_port.lock, flags);
-
-	irq = sn_sal_connect_interrupt(port);
-
-	if (irq) {
-		port->sc_port.irq = irq;
-		port->sc_ops = &intr_ops;
-
-		/* turn on receive interrupts */
-		ia64_sn_console_intr_enable(SAL_CONSOLE_INTR_RECV);
+			/* turn on receive interrupts */
+			ia64_sn_console_intr_enable(SAL_CONSOLE_INTR_RECV);
+			spin_unlock_irqrestore(&port->sc_port.lock, flags);
+		}
+		else {
+			printk(KERN_INFO
+			    "sn_console: console proceeding in polled mode\n");
+		}
 	}
-	spin_unlock_irqrestore(&port->sc_port.lock, flags);
 }
 
 /*
diff --git a/drivers/spi/at25.c b/drivers/spi/at25.c
index 48e4f48..8efa07e 100644
--- a/drivers/spi/at25.c
+++ b/drivers/spi/at25.c
@@ -291,7 +291,7 @@
 	 */
 	sr = spi_w8r8(spi, AT25_RDSR);
 	if (sr < 0 || sr & AT25_SR_nRDY) {
-		dev_dbg(&at25->spi->dev, "rdsr --> %d (%02x)\n", sr, sr);
+		dev_dbg(&spi->dev, "rdsr --> %d (%02x)\n", sr, sr);
 		err = -ENXIO;
 		goto fail;
 	}
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index 6fa260d..66e7bc9 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -425,7 +425,7 @@
 		if (ret)
 			return ret;
 		spi->controller_state = (void *)npcs_pin;
-		gpio_direction_output(npcs_pin);
+		gpio_direction_output(npcs_pin, !(spi->mode & SPI_CS_HIGH));
 	}
 
 	dev_dbg(&spi->dev,
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 2328128..6657331 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -189,8 +189,8 @@
  * this is exported so that for example a USB or parport based adapter
  * driver could add devices (which it would learn about out-of-band).
  */
-struct spi_device *__init_or_module
-spi_new_device(struct spi_master *master, struct spi_board_info *chip)
+struct spi_device *spi_new_device(struct spi_master *master,
+				  struct spi_board_info *chip)
 {
 	struct spi_device	*proxy;
 	struct device		*dev = master->cdev.dev;
@@ -352,8 +352,7 @@
  * the master's methods before calling spi_register_master(); and (after errors
  * adding the device) calling spi_master_put() to prevent a memory leak.
  */
-struct spi_master * __init_or_module
-spi_alloc_master(struct device *dev, unsigned size)
+struct spi_master *spi_alloc_master(struct device *dev, unsigned size)
 {
 	struct spi_master	*master;
 
@@ -392,8 +391,7 @@
  * After a successful return, the caller is responsible for calling
  * spi_unregister_master().
  */
-int __init_or_module
-spi_register_master(struct spi_master *master)
+int spi_register_master(struct spi_master *master)
 {
 	static atomic_t		dyn_bus_id = ATOMIC_INIT((1<<16) - 1);
 	struct device		*dev = master->cdev.dev;
diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c
index 24a330d..88425e1 100644
--- a/drivers/spi/spi_bitbang.c
+++ b/drivers/spi/spi_bitbang.c
@@ -302,10 +302,6 @@
 		setup_transfer = NULL;
 
 		list_for_each_entry (t, &m->transfers, transfer_list) {
-			if (bitbang->shutdown) {
-				status = -ESHUTDOWN;
-				break;
-			}
 
 			/* override or restore speed and wordsize */
 			if (t->speed_hz || t->bits_per_word) {
@@ -410,8 +406,6 @@
 	m->status = -EINPROGRESS;
 
 	bitbang = spi_master_get_devdata(spi->master);
-	if (bitbang->shutdown)
-		return -ESHUTDOWN;
 
 	spin_lock_irqsave(&bitbang->lock, flags);
 	if (!spi->max_speed_hz)
@@ -507,28 +501,12 @@
  */
 int spi_bitbang_stop(struct spi_bitbang *bitbang)
 {
-	unsigned	limit = 500;
+	spi_unregister_master(bitbang->master);
 
-	spin_lock_irq(&bitbang->lock);
-	bitbang->shutdown = 0;
-	while (!list_empty(&bitbang->queue) && limit--) {
-		spin_unlock_irq(&bitbang->lock);
-
-		dev_dbg(bitbang->master->cdev.dev, "wait for queue\n");
-		msleep(10);
-
-		spin_lock_irq(&bitbang->lock);
-	}
-	spin_unlock_irq(&bitbang->lock);
-	if (!list_empty(&bitbang->queue)) {
-		dev_err(bitbang->master->cdev.dev, "queue didn't empty\n");
-		return -EBUSY;
-	}
+	WARN_ON(!list_empty(&bitbang->queue));
 
 	destroy_workqueue(bitbang->workqueue);
 
-	spi_unregister_master(bitbang->master);
-
 	return 0;
 }
 EXPORT_SYMBOL_GPL(spi_bitbang_stop);
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c
index 651379c..220abce 100644
--- a/drivers/spi/spi_s3c24xx.c
+++ b/drivers/spi/spi_s3c24xx.c
@@ -41,7 +41,7 @@
 	int			 len;
 	int			 count;
 
-	int			(*set_cs)(struct s3c2410_spi_info *spi,
+	void			(*set_cs)(struct s3c2410_spi_info *spi,
 					  int cs, int pol);
 
 	/* data buffers */
diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c
index 3d72aa5..3524e3fc 100644
--- a/drivers/tc/zs.c
+++ b/drivers/tc/zs.c
@@ -70,7 +70,6 @@
 #include <asm/dec/machtype.h>
 #include <asm/dec/serial.h>
 #include <asm/dec/system.h>
-#include <asm/dec/tc.h>
 
 #ifdef CONFIG_KGDB
 #include <asm/kgdb.h>
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index d38a25f..31ae661 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -332,9 +332,9 @@
 	if (!ACM_READY(acm))
 		return;
 
-	spin_lock(&acm->throttle_lock);
+	spin_lock_irqsave(&acm->throttle_lock, flags);
 	throttled = acm->throttle;
-	spin_unlock(&acm->throttle_lock);
+	spin_unlock_irqrestore(&acm->throttle_lock, flags);
 	if (throttled)
 		return;
 
@@ -352,9 +352,9 @@
 	dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size);
 
 	tty_buffer_request_room(tty, buf->size);
-	spin_lock(&acm->throttle_lock);
+	spin_lock_irqsave(&acm->throttle_lock, flags);
 	throttled = acm->throttle;
-	spin_unlock(&acm->throttle_lock);
+	spin_unlock_irqrestore(&acm->throttle_lock, flags);
 	if (!throttled)
 		tty_insert_flip_string(tty, buf->base, buf->size);
 	tty_flip_buffer_push(tty);
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 63e50a1..6584cf0 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -202,6 +202,7 @@
 
 #define USBLP_QUIRK_BIDIR	0x1	/* reports bidir but requires unidirectional mode (no INs/reads) */
 #define USBLP_QUIRK_USB_INIT	0x2	/* needs vendor USB init string */
+#define USBLP_QUIRK_BAD_CLASS	0x4	/* descriptor uses vendor-specific Class or SubClass */
 
 static const struct quirk_printer_struct quirk_printers[] = {
 	{ 0x03f0, 0x0004, USBLP_QUIRK_BIDIR }, /* HP DeskJet 895C */
@@ -218,6 +219,7 @@
 	{ 0x0409, 0xf0be, USBLP_QUIRK_BIDIR }, /* NEC Picty920 (HP OEM) */
 	{ 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
 	{ 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
+	{ 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
 	{ 0, 0 }
 };
 
@@ -1048,7 +1050,8 @@
 		ifd = &if_alt->altsetting[i];
 
 		if (ifd->desc.bInterfaceClass != 7 || ifd->desc.bInterfaceSubClass != 1)
-			continue;
+			if (!(usblp->quirks & USBLP_QUIRK_BAD_CLASS))
+				continue;
 
 		if (ifd->desc.bInterfaceProtocol < USBLP_FIRST_PROTOCOL ||
 		    ifd->desc.bInterfaceProtocol > USBLP_LAST_PROTOCOL)
@@ -1232,6 +1235,7 @@
 	{ USB_INTERFACE_INFO(7, 1, 1) },
 	{ USB_INTERFACE_INFO(7, 1, 2) },
 	{ USB_INTERFACE_INFO(7, 1, 3) },
+	{ USB_DEVICE(0x04b8, 0x0202) },	/* Seiko Epson Receipt Printer M129C */
 	{ }						/* Terminating entry */
 };
 
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 274f14f..36e7a84 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -912,7 +912,7 @@
 	struct async *as;
 	struct usb_ctrlrequest *dr = NULL;
 	unsigned int u, totlen, isofrmlen;
-	int ret, interval = 0, ifnum = -1;
+	int ret, ifnum = -1;
 
 	if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP|USBDEVFS_URB_SHORT_NOT_OK|
 			   URB_NO_FSBR|URB_ZERO_PACKET))
@@ -992,7 +992,6 @@
 		if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
 				!= USB_ENDPOINT_XFER_ISOC)
 			return -EINVAL;
-		interval = 1 << min (15, ep->desc.bInterval - 1);
 		isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * uurb->number_of_packets;
 		if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL)))
 			return -ENOMEM;
@@ -1021,10 +1020,6 @@
 		if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
 				!= USB_ENDPOINT_XFER_INT)
 			return -EINVAL;
-		if (ps->dev->speed == USB_SPEED_HIGH)
-			interval = 1 << min (15, ep->desc.bInterval - 1);
-		else
-			interval = ep->desc.bInterval;
 		if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
 			return -EINVAL;
 		if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length))
@@ -1053,7 +1048,11 @@
 	as->urb->setup_packet = (unsigned char*)dr;
 	as->urb->start_frame = uurb->start_frame;
 	as->urb->number_of_packets = uurb->number_of_packets;
-	as->urb->interval = interval;
+	if (uurb->type == USBDEVFS_URB_TYPE_ISO ||
+			ps->dev->speed == USB_SPEED_HIGH)
+		as->urb->interval = 1 << min(15, ep->desc.bInterval - 1);
+	else
+		as->urb->interval = ep->desc.bInterval;
         as->urb->context = as;
         as->urb->complete = async_completed;
 	for (totlen = u = 0; u < uurb->number_of_packets; u++) {
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 4140074..b89a98e 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1281,12 +1281,6 @@
 {
 	int err;
 
-	/* Lock ourself into memory in order to keep a probe sequence
-	 * sleeping in a new thread from allowing us to be unloaded.
-	 */
-	if (!try_module_get(THIS_MODULE))
-		return -EINVAL;
-
 	/* Determine quirks */
 	usb_detect_quirks(udev);
 
@@ -1390,7 +1384,6 @@
 		usb_autoresume_device(udev->parent);
 
 exit:
-	module_put(THIS_MODULE);
 	return err;
 
 fail:
@@ -2443,7 +2436,7 @@
 
 	if (portchange & USB_PORT_STAT_C_CONNECTION) {
 		status = hub_port_debounce(hub, port1);
-		if (status < 0) {
+		if (status < 0 && printk_ratelimit()) {
 			dev_err (hub_dev,
 				"connect-debounce failed, port %d disabled\n",
 				port1);
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 2f17468..217a3d6 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -221,10 +221,15 @@
 
 	if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
 			USB_ENDPOINT_XFER_INT) {
+		int interval;
+
+		if (usb_dev->speed == USB_SPEED_HIGH)
+			interval = 1 << min(15, ep->desc.bInterval - 1);
+		else
+			interval = ep->desc.bInterval;
 		pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30);
 		usb_fill_int_urb(urb, usb_dev, pipe, data, len,
-				usb_api_blocking_completion, NULL,
-				ep->desc.bInterval);
+				usb_api_blocking_completion, NULL, interval);
 	} else
 		usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
 				usb_api_blocking_completion, NULL);
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 0e5c646..f08ec85 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -30,7 +30,8 @@
 static const struct usb_device_id usb_quirk_list[] = {
 	/* HP 5300/5370C scanner */
 	{ USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 },
-
+	/* Seiko Epson Corp - Perfection 1670 */
+	{ USB_DEVICE(0x04b8, 0x011f), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
 	/* Elsa MicroLink 56k (V.250) */
 	{ USB_DEVICE(0x05cc, 0x2267), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
 
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index a467780..2a6e316 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -1835,7 +1835,7 @@
 #define	at91udc_resume	NULL
 #endif
 
-static struct platform_driver at91_udc = {
+static struct platform_driver at91_udc_driver = {
 	.remove		= __exit_p(at91udc_remove),
 	.shutdown	= at91udc_shutdown,
 	.suspend	= at91udc_suspend,
@@ -1848,13 +1848,13 @@
 
 static int __init udc_init_module(void)
 {
-	return platform_driver_probe(&at91_udc, at91udc_probe);
+	return platform_driver_probe(&at91_udc_driver, at91udc_probe);
 }
 module_init(udc_init_module);
 
 static void __exit udc_exit_module(void)
 {
-	platform_driver_unregister(&at91_udc);
+	platform_driver_unregister(&at91_udc_driver);
 }
 module_exit(udc_exit_module);
 
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index 7b3a326..65c91d3 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -297,27 +297,6 @@
 
 /*-------------------------------------------------------------------------*/
 
-#undef USE_KMALLOC
-
-/* many common platforms have dma-coherent caches, which means that it's
- * safe to use kmalloc() memory for all i/o buffers without using any
- * cache flushing calls.  (unless you're trying to share cache lines
- * between dma and non-dma activities, which is a slow idea in any case.)
- *
- * other platforms need more care, with 2.6 having a moderately general
- * solution except for the common "buffer is smaller than a page" case.
- */
-#if	defined(CONFIG_X86)
-#define USE_KMALLOC
-
-#elif	defined(CONFIG_MIPS) && !defined(CONFIG_DMA_NONCOHERENT)
-#define USE_KMALLOC
-
-#elif	defined(CONFIG_PPC) && !defined(CONFIG_NOT_COHERENT_CACHE)
-#define USE_KMALLOC
-
-#endif
-
 /* allocating buffers this way eliminates dma mapping overhead, which
  * on some platforms will mean eliminating a per-io buffer copy.  with
  * some kinds of system caches, further tweaks may still be needed.
@@ -334,11 +313,6 @@
 		return NULL;
 	*dma = DMA_ADDR_INVALID;
 
-#if	defined(USE_KMALLOC)
-	retval = kmalloc(bytes, gfp_flags);
-	if (retval)
-		*dma = virt_to_phys(retval);
-#else
 	if (ep->dma) {
 		/* the main problem with this call is that it wastes memory
 		 * on typical 1/N page allocations: it allocates 1-N pages.
@@ -348,7 +322,6 @@
 				bytes, dma, gfp_flags);
 	} else
 		retval = kmalloc(bytes, gfp_flags);
-#endif
 	return retval;
 }
 
@@ -356,7 +329,6 @@
 goku_free_buffer(struct usb_ep *_ep, void *buf, dma_addr_t dma, unsigned bytes)
 {
 	/* free memory into the right allocator */
-#ifndef	USE_KMALLOC
 	if (dma != DMA_ADDR_INVALID) {
 		struct goku_ep	*ep;
 
@@ -365,7 +337,6 @@
 			return;
 		dma_free_coherent(&ep->dev->pdev->dev, bytes, buf, dma);
 	} else
-#endif
 		kfree (buf);
 }
 
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 8f9a2b6..b394e63 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -296,6 +296,15 @@
 
 /*-------------------------------------------------------------------------*/
 
+/*
+ * dma-coherent memory allocation (for dma-capable endpoints)
+ *
+ * NOTE: the dma_*_coherent() API calls suck.  Most implementations are
+ * (a) page-oriented, so small buffers lose big; and (b) asymmetric with
+ * respect to calls with irqs disabled:  alloc is safe, free is not.
+ * We currently work around (b), but not (a).
+ */
+
 static void *
 omap_alloc_buffer(
 	struct usb_ep	*_ep,
@@ -307,6 +316,9 @@
 	void		*retval;
 	struct omap_ep	*ep;
 
+	if (!_ep)
+		return NULL;
+
 	ep = container_of(_ep, struct omap_ep, ep);
 	if (use_dma && ep->has_dma) {
 		static int	warned;
@@ -326,6 +338,35 @@
 	return retval;
 }
 
+static DEFINE_SPINLOCK(buflock);
+static LIST_HEAD(buffers);
+
+struct free_record {
+	struct list_head	list;
+	struct device		*dev;
+	unsigned		bytes;
+	dma_addr_t		dma;
+};
+
+static void do_free(unsigned long ignored)
+{
+	spin_lock_irq(&buflock);
+	while (!list_empty(&buffers)) {
+		struct free_record	*buf;
+
+		buf = list_entry(buffers.next, struct free_record, list);
+		list_del(&buf->list);
+		spin_unlock_irq(&buflock);
+
+		dma_free_coherent(buf->dev, buf->bytes, buf, buf->dma);
+
+		spin_lock_irq(&buflock);
+	}
+	spin_unlock_irq(&buflock);
+}
+
+static DECLARE_TASKLET(deferred_free, do_free, 0);
+
 static void omap_free_buffer(
 	struct usb_ep	*_ep,
 	void		*buf,
@@ -333,13 +374,29 @@
 	unsigned	bytes
 )
 {
-	struct omap_ep	*ep;
+	if (!_ep) {
+		WARN_ON(1);
+		return;
+	}
 
-	ep = container_of(_ep, struct omap_ep, ep);
-	if (use_dma && _ep && ep->has_dma)
-		dma_free_coherent(ep->udc->gadget.dev.parent, bytes, buf, dma);
-	else
-		kfree (buf);
+	/* free memory into the right allocator */
+	if (dma != DMA_ADDR_INVALID) {
+		struct omap_ep		*ep;
+		struct free_record	*rec = buf;
+		unsigned long		flags;
+
+		ep = container_of(_ep, struct omap_ep, ep);
+
+		rec->dev = ep->udc->gadget.dev.parent;
+		rec->bytes = bytes;
+		rec->dma = dma;
+
+		spin_lock_irqsave(&buflock, flags);
+		list_add_tail(&rec->list, &buffers);
+		tasklet_schedule(&deferred_free);
+		spin_unlock_irqrestore(&buflock, flags);
+	} else
+		kfree(buf);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1691,12 +1748,38 @@
 			udc->ep0_pending = 0;
 			break;
 		case USB_REQ_GET_STATUS:
+			/* USB_ENDPOINT_HALT status? */
+			if (u.r.bRequestType != (USB_DIR_IN|USB_RECIP_ENDPOINT))
+				goto intf_status;
+
+			/* ep0 never stalls */
+			if (!(w_index & 0xf))
+				goto zero_status;
+
+			/* only active endpoints count */
+			ep = &udc->ep[w_index & 0xf];
+			if (w_index & USB_DIR_IN)
+				ep += 16;
+			if (!ep->desc)
+				goto do_stall;
+
+			/* iso never stalls */
+			if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC)
+				goto zero_status;
+
+			/* FIXME don't assume non-halted endpoints!! */
+			ERR("%s status, can't report\n", ep->ep.name);
+			goto do_stall;
+
+intf_status:
 			/* return interface status.  if we were pedantic,
 			 * we'd detect non-existent interfaces, and stall.
 			 */
 			if (u.r.bRequestType
 					!= (USB_DIR_IN|USB_RECIP_INTERFACE))
 				goto delegate;
+
+zero_status:
 			/* return two zero bytes */
 			UDC_EP_NUM_REG = UDC_EP_SEL|UDC_EP_DIR;
 			UDC_DATA_REG = 0;
@@ -2068,7 +2151,7 @@
 
 /*-------------------------------------------------------------------------*/
 
-static inline int machine_needs_vbus_session(void)
+static inline int machine_without_vbus_sense(void)
 {
 	return (machine_is_omap_innovator()
 		|| machine_is_omap_osk()
@@ -2156,7 +2239,7 @@
 	/* boards that don't have VBUS sensing can't autogate 48MHz;
 	 * can't enter deep sleep while a gadget driver is active.
 	 */
-	if (machine_needs_vbus_session())
+	if (machine_without_vbus_sense())
 		omap_vbus_session(&udc->gadget, 1);
 
 done:
@@ -2179,7 +2262,7 @@
 	if (udc->dc_clk != NULL)
 		omap_udc_enable_clock(1);
 
-	if (machine_needs_vbus_session())
+	if (machine_without_vbus_sense())
 		omap_vbus_session(&udc->gadget, 0);
 
 	if (udc->transceiver)
@@ -2822,7 +2905,7 @@
 		hmc = HMC_1510;
 		type = "(unknown)";
 
-		if (machine_is_omap_innovator() || machine_is_sx1()) {
+		if (machine_without_vbus_sense()) {
 			/* just set up software VBUS detect, and then
 			 * later rig it so we always report VBUS.
 			 * FIXME without really sensing VBUS, we can't
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index a740564..c7458f7 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -669,6 +669,7 @@
 			 */
 			ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
 			ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
+			mod_timer(&hcd->rh_timer, ehci->reset_done[i]);
 		}
 	}
 
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 9af529d..1813b7ca 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -653,8 +653,7 @@
 	if (status & ~0xffff)	/* only if wPortChange is interesting */
 #endif
 		dbg_port (ehci, "GetStatus", wIndex + 1, temp);
-		// we "know" this alignment is good, caller used kmalloc()...
-		*((__le32 *) buf) = cpu_to_le32 (status);
+		put_unaligned(cpu_to_le32 (status), (__le32 *) buf);
 		break;
 	case SetHubFeature:
 		switch (wValue) {
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
index 8d24d3d..1497371 100644
--- a/drivers/usb/host/uhci-debug.c
+++ b/drivers/usb/host/uhci-debug.c
@@ -145,7 +145,8 @@
 	return out - buf;
 }
 
-static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space)
+static int uhci_show_qh(struct uhci_hcd *uhci,
+		struct uhci_qh *qh, char *buf, int len, int space)
 {
 	char *out = buf;
 	int i, nurbs;
@@ -190,6 +191,9 @@
 
 	if (list_empty(&qh->queue)) {
 		out += sprintf(out, "%*s  queue is empty\n", space, "");
+		if (qh == uhci->skel_async_qh)
+			out += uhci_show_td(uhci->term_td, out,
+					len - (out - buf), 0);
 	} else {
 		struct urb_priv *urbp = list_entry(qh->queue.next,
 				struct urb_priv, node);
@@ -343,6 +347,7 @@
 	struct list_head *tmp, *head;
 	int nframes, nerrs;
 	__le32 link;
+	__le32 fsbr_link;
 
 	static const char * const qh_names[] = {
 		"unlink", "iso", "int128", "int64", "int32", "int16",
@@ -424,21 +429,22 @@
 
 	out += sprintf(out, "Skeleton QHs\n");
 
+	fsbr_link = 0;
 	for (i = 0; i < UHCI_NUM_SKELQH; ++i) {
 		int cnt = 0;
-		__le32 fsbr_link = 0;
 
 		qh = uhci->skelqh[i];
 		out += sprintf(out, "- skel_%s_qh\n", qh_names[i]); \
-		out += uhci_show_qh(qh, out, len - (out - buf), 4);
+		out += uhci_show_qh(uhci, qh, out, len - (out - buf), 4);
 
 		/* Last QH is the Terminating QH, it's different */
 		if (i == SKEL_TERM) {
 			if (qh_element(qh) != LINK_TO_TD(uhci->term_td))
 				out += sprintf(out, "    skel_term_qh element is not set to term_td!\n");
-			if (link == LINK_TO_QH(uhci->skel_term_qh))
-				goto check_qh_link;
-			continue;
+			link = fsbr_link;
+			if (!link)
+				link = LINK_TO_QH(uhci->skel_term_qh);
+			goto check_qh_link;
 		}
 
 		head = &qh->node;
@@ -448,7 +454,7 @@
 			qh = list_entry(tmp, struct uhci_qh, node);
 			tmp = tmp->next;
 			if (++cnt <= 10)
-				out += uhci_show_qh(qh, out,
+				out += uhci_show_qh(uhci, qh, out,
 						len - (out - buf), 4);
 			if (!fsbr_link && qh->skel >= SKEL_FSBR)
 				fsbr_link = LINK_TO_QH(qh);
@@ -463,8 +469,6 @@
 			link = LINK_TO_QH(uhci->skel_async_qh);
 		else if (!uhci->fsbr_is_on)
 			;
-		else if (fsbr_link)
-			link = fsbr_link;
 		else
 			link = LINK_TO_QH(uhci->skel_term_qh);
 check_qh_link:
@@ -573,8 +577,8 @@
 static inline void lprintk(char *buf)
 {}
 
-static inline int uhci_show_qh(struct uhci_qh *qh, char *buf,
-		int len, int space)
+static inline int uhci_show_qh(struct uhci_hcd *uhci,
+		struct uhci_qh *qh, char *buf, int len, int space)
 {
 	return 0;
 }
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 44da433..d22da26 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -632,7 +632,8 @@
 	 */
 	for (i = SKEL_ISO + 1; i < SKEL_ASYNC; ++i)
 		uhci->skelqh[i]->link = LINK_TO_QH(uhci->skel_async_qh);
-	uhci->skel_async_qh->link = uhci->skel_term_qh->link = UHCI_PTR_TERM;
+	uhci->skel_async_qh->link = UHCI_PTR_TERM;
+	uhci->skel_term_qh->link = LINK_TO_QH(uhci->skel_term_qh);
 
 	/* This dummy TD is to work around a bug in Intel PIIX controllers */
 	uhci_fill_td(uhci->term_td, 0, uhci_explen(0) |
diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c
index bacc25c..8e4427a 100644
--- a/drivers/usb/host/uhci-hub.c
+++ b/drivers/usb/host/uhci-hub.c
@@ -33,6 +33,9 @@
 /* status change bits:  nonzero writes will clear */
 #define RWC_BITS	(USBPORTSC_OCC | USBPORTSC_PEC | USBPORTSC_CSC)
 
+/* suspend/resume bits: port suspended or port resuming */
+#define SUSPEND_BITS	(USBPORTSC_SUSP | USBPORTSC_RD)
+
 /* A port that either is connected or has a changed-bit set will prevent
  * us from AUTO_STOPPING.
  */
@@ -96,8 +99,8 @@
 	int status;
 	int i;
 
-	if (inw(port_addr) & (USBPORTSC_SUSP | USBPORTSC_RD)) {
-		CLR_RH_PORTSTAT(USBPORTSC_SUSP | USBPORTSC_RD);
+	if (inw(port_addr) & SUSPEND_BITS) {
+		CLR_RH_PORTSTAT(SUSPEND_BITS);
 		if (test_bit(port, &uhci->resuming_ports))
 			set_bit(port, &uhci->port_c_suspend);
 
@@ -107,7 +110,7 @@
 		 * Experiments show that some controllers take longer, so
 		 * we'll poll for completion. */
 		for (i = 0; i < 10; ++i) {
-			if (!(inw(port_addr) & USBPORTSC_RD))
+			if (!(inw(port_addr) & SUSPEND_BITS))
 				break;
 			udelay(1);
 		}
@@ -289,7 +292,7 @@
 			wPortStatus |= USB_PORT_STAT_CONNECTION;
 		if (status & USBPORTSC_PE) {
 			wPortStatus |= USB_PORT_STAT_ENABLE;
-			if (status & (USBPORTSC_SUSP | USBPORTSC_RD))
+			if (status & SUSPEND_BITS)
 				wPortStatus |= USB_PORT_STAT_SUSPEND;
 		}
 		if (status & USBPORTSC_OC)
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index f4ebdb3..19a0cc0 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -45,43 +45,27 @@
  */
 static void uhci_fsbr_on(struct uhci_hcd *uhci)
 {
-	struct uhci_qh *fsbr_qh, *lqh, *tqh;
+	struct uhci_qh *lqh;
 
+	/* The terminating skeleton QH always points back to the first
+	 * FSBR QH.  Make the last async QH point to the terminating
+	 * skeleton QH. */
 	uhci->fsbr_is_on = 1;
 	lqh = list_entry(uhci->skel_async_qh->node.prev,
 			struct uhci_qh, node);
-
-	/* Find the first FSBR QH.  Linear search through the list is
-	 * acceptable because normally FSBR gets turned on as soon as
-	 * one QH needs it. */
-	fsbr_qh = NULL;
-	list_for_each_entry_reverse(tqh, &uhci->skel_async_qh->node, node) {
-		if (tqh->skel < SKEL_FSBR)
-			break;
-		fsbr_qh = tqh;
-	}
-
-	/* No FSBR QH means we must insert the terminating skeleton QH */
-	if (!fsbr_qh) {
-		uhci->skel_term_qh->link = LINK_TO_QH(uhci->skel_term_qh);
-		wmb();
-		lqh->link = uhci->skel_term_qh->link;
-
-	/* Otherwise loop the last QH to the first FSBR QH */
-	} else
-		lqh->link = LINK_TO_QH(fsbr_qh);
+	lqh->link = LINK_TO_QH(uhci->skel_term_qh);
 }
 
 static void uhci_fsbr_off(struct uhci_hcd *uhci)
 {
 	struct uhci_qh *lqh;
 
+	/* Remove the link from the last async QH to the terminating
+	 * skeleton QH. */
 	uhci->fsbr_is_on = 0;
 	lqh = list_entry(uhci->skel_async_qh->node.prev,
 			struct uhci_qh, node);
-
-	/* End the async list normally and unlink the terminating QH */
-	lqh->link = uhci->skel_term_qh->link = UHCI_PTR_TERM;
+	lqh->link = UHCI_PTR_TERM;
 }
 
 static void uhci_add_fsbr(struct uhci_hcd *uhci, struct urb *urb)
@@ -464,9 +448,8 @@
  */
 static void link_async(struct uhci_hcd *uhci, struct uhci_qh *qh)
 {
-	struct uhci_qh *pqh, *lqh;
+	struct uhci_qh *pqh;
 	__le32 link_to_new_qh;
-	__le32 *extra_link = &link_to_new_qh;
 
 	/* Find the predecessor QH for our new one and insert it in the list.
 	 * The list of QHs is expected to be short, so linear search won't
@@ -476,31 +459,17 @@
 			break;
 	}
 	list_add(&qh->node, &pqh->node);
-	qh->link = pqh->link;
-
-	link_to_new_qh = LINK_TO_QH(qh);
-
-	/* If this is now the first FSBR QH, take special action */
-	if (uhci->fsbr_is_on && pqh->skel < SKEL_FSBR &&
-			qh->skel >= SKEL_FSBR) {
-		lqh = list_entry(uhci->skel_async_qh->node.prev,
-				struct uhci_qh, node);
-
-		/* If the new QH is also the last one, we must unlink
-		 * the terminating skeleton QH and make the new QH point
-		 * back to itself. */
-		if (qh == lqh) {
-			qh->link = link_to_new_qh;
-			extra_link = &uhci->skel_term_qh->link;
-
-		/* Otherwise the last QH must point to the new QH */
-		} else
-			extra_link = &lqh->link;
-	}
 
 	/* Link it into the schedule */
+	qh->link = pqh->link;
 	wmb();
-	*extra_link = pqh->link = link_to_new_qh;
+	link_to_new_qh = LINK_TO_QH(qh);
+	pqh->link = link_to_new_qh;
+
+	/* If this is now the first FSBR QH, link the terminating skeleton
+	 * QH to it. */
+	if (pqh->skel < SKEL_FSBR && qh->skel >= SKEL_FSBR)
+		uhci->skel_term_qh->link = link_to_new_qh;
 }
 
 /*
@@ -561,31 +530,16 @@
  */
 static void unlink_async(struct uhci_hcd *uhci, struct uhci_qh *qh)
 {
-	struct uhci_qh *pqh, *lqh;
+	struct uhci_qh *pqh;
 	__le32 link_to_next_qh = qh->link;
 
 	pqh = list_entry(qh->node.prev, struct uhci_qh, node);
-
-	/* If this is the first FSBQ QH, take special action */
-	if (uhci->fsbr_is_on && pqh->skel < SKEL_FSBR &&
-			qh->skel >= SKEL_FSBR) {
-		lqh = list_entry(uhci->skel_async_qh->node.prev,
-				struct uhci_qh, node);
-
-		/* If this QH is also the last one, we must link in
-		 * the terminating skeleton QH. */
-		if (qh == lqh) {
-			link_to_next_qh = LINK_TO_QH(uhci->skel_term_qh);
-			uhci->skel_term_qh->link = link_to_next_qh;
-			wmb();
-			qh->link = link_to_next_qh;
-
-		/* Otherwise the last QH must point to the new first FSBR QH */
-		} else
-			lqh->link = link_to_next_qh;
-	}
-
 	pqh->link = link_to_next_qh;
+
+	/* If this was the old first FSBR QH, link the terminating skeleton
+	 * QH to the next (new first FSBR) QH. */
+	if (pqh->skel < SKEL_FSBR && qh->skel >= SKEL_FSBR)
+		uhci->skel_term_qh->link = link_to_next_qh;
 	mb();
 }
 
@@ -1217,7 +1171,7 @@
 
 				if (debug > 1 && errbuf) {
 					/* Print the chain for debugging */
-					uhci_show_qh(urbp->qh, errbuf,
+					uhci_show_qh(uhci, urbp->qh, errbuf,
 							ERRBUF_LEN, 0);
 					lprintk(errbuf);
 				}
diff --git a/drivers/usb/misc/berry_charge.c b/drivers/usb/misc/berry_charge.c
index 60893c6..b15f2fd 100644
--- a/drivers/usb/misc/berry_charge.c
+++ b/drivers/usb/misc/berry_charge.c
@@ -69,7 +69,7 @@
 		return retval;
 	}
 
-	dbg(&udev->dev, "Sending first magic command\n");
+	dbg(&udev->dev, "Sending second magic command\n");
 	retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 				 0xa2, 0x40, 0, 1, dummy_buffer, 0, 100);
 	if (retval != 0) {
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c
index 0c1d66d..bc3327e 100644
--- a/drivers/usb/misc/ftdi-elan.c
+++ b/drivers/usb/misc/ftdi-elan.c
@@ -2905,17 +2905,31 @@
 {
         int result;
         printk(KERN_INFO "driver %s built at %s on %s\n", ftdi_elan_driver.name,
-                 __TIME__, __DATE__);
+	       __TIME__, __DATE__);
         init_MUTEX(&ftdi_module_lock);
         INIT_LIST_HEAD(&ftdi_static_list);
         status_queue = create_singlethread_workqueue("ftdi-status-control");
+	if (!status_queue)
+		goto err1;
         command_queue = create_singlethread_workqueue("ftdi-command-engine");
+	if (!command_queue)
+		goto err2;
         respond_queue = create_singlethread_workqueue("ftdi-respond-engine");
+	if (!respond_queue)
+		goto err3;
         result = usb_register(&ftdi_elan_driver);
         if (result)
                 printk(KERN_ERR "usb_register failed. Error number %d\n",
-                        result);
+		       result);
         return result;
+
+ err3:
+	destroy_workqueue(command_queue);
+ err2:
+	destroy_workqueue(status_queue);
+ err1:
+	printk(KERN_ERR "%s couldn't create workqueue\n", ftdi_elan_driver.name);
+	return -ENOMEM;
 }
 
 static void __exit ftdi_elan_exit(void)
diff --git a/drivers/usb/net/dm9601.c b/drivers/usb/net/dm9601.c
index 4a932e1..5130cc7 100644
--- a/drivers/usb/net/dm9601.c
+++ b/drivers/usb/net/dm9601.c
@@ -571,9 +571,21 @@
 
 static const struct usb_device_id products[] = {
 	{
+	 USB_DEVICE(0x07aa, 0x9601),	/* Corega FEther USB-TXC */
+	 .driver_info = (unsigned long)&dm9601_info,
+	 },
+	{
 	 USB_DEVICE(0x0a46, 0x9601),	/* Davicom USB-100 */
 	 .driver_info = (unsigned long)&dm9601_info,
 	 },
+	{
+	 USB_DEVICE(0x0a46, 0x6688),	/* ZT6688 USB NIC */
+	 .driver_info = (unsigned long)&dm9601_info,
+	 },
+	{
+	 USB_DEVICE(0x0a46, 0x0268),	/* ShanTou ST268 USB NIC */
+	 .driver_info = (unsigned long)&dm9601_info,
+	 },
 	{},			// END
 };
 
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c
index 18816bf..39a4983 100644
--- a/drivers/usb/serial/airprime.c
+++ b/drivers/usb/serial/airprime.c
@@ -18,11 +18,6 @@
 
 static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */
-	{ USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */
-	{ USB_DEVICE(0x1410, 0x1130) }, /* Novatel Wireless S720 CDMA/EV-DO */
-	{ USB_DEVICE(0x1410, 0x2110) }, /* Novatel Wireless U720 CDMA/EV-DO */
-	{ USB_DEVICE(0x1410, 0x1430) },	/* Novatel Merlin XU870 HSDPA/3G */
-	{ USB_DEVICE(0x1410, 0x1100) }, /* ExpressCard34 Qualcomm 3G CDMA */
 	{ USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */
 	{ },
 };
@@ -44,8 +39,43 @@
 	int outstanding_urbs;
 	int throttled;
 	struct urb *read_urbp[NUM_READ_URBS];
+
+	/* Settings for the port */
+	int rts_state;	/* Handshaking pins (outputs) */
+	int dtr_state;
+	int cts_state;	/* Handshaking pins (inputs) */
+	int dsr_state;
+	int dcd_state;
+	int ri_state;
 };
 
+static int airprime_send_setup(struct usb_serial_port *port)
+{
+	struct usb_serial *serial = port->serial;
+	struct airprime_private *priv;
+
+	dbg("%s", __FUNCTION__);
+
+	if (port->number != 0)
+		return 0;
+
+	priv = usb_get_serial_port_data(port);
+
+	if (port->tty) {
+		int val = 0;
+		if (priv->dtr_state)
+			val |= 0x01;
+		if (priv->rts_state)
+			val |= 0x02;
+
+		return usb_control_msg(serial->dev,
+				usb_rcvctrlpipe(serial->dev, 0),
+				0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT);
+	}
+
+	return 0;
+}
+
 static void airprime_read_bulk_callback(struct urb *urb)
 {
 	struct usb_serial_port *port = urb->context;
@@ -118,6 +148,10 @@
 		usb_set_serial_port_data(port, priv);
 	}
 
+	/* Set some sane defaults */
+	priv->rts_state = 1;
+	priv->dtr_state = 1;
+
 	for (i = 0; i < NUM_READ_URBS; ++i) {
 		buffer = kmalloc(buffer_size, GFP_KERNEL);
 		if (!buffer) {
@@ -151,6 +185,9 @@
 		/* remember this urb so we can kill it when the port is closed */
 		priv->read_urbp[i] = urb;
 	}
+
+	airprime_send_setup(port);
+
 	goto out;
 
  errout:
@@ -176,6 +213,11 @@
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
+	priv->rts_state = 0;
+	priv->dtr_state = 0;
+
+	airprime_send_setup(port);
+
 	for (i = 0; i < NUM_READ_URBS; ++i) {
 		usb_kill_urb (priv->read_urbp[i]);
 		kfree (priv->read_urbp[i]->transfer_buffer);
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index db623e7..d7d0ba9 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -63,6 +63,8 @@
 	{ USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */
 	{ USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */
 	{ USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */
+	{ USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
+	{ USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
 	{ USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
 	{ USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
 	{ USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index c525b42..8ff9d54 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -315,6 +315,7 @@
 	{ USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_232RL_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
@@ -420,6 +421,14 @@
 	{ USB_DEVICE(FTDI_VID, FTDI_ELV_ALC8500_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_PYRAMID_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1000PC_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_IBS_US485_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_IBS_PICPRO_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_IBS_PCMCIA_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_IBS_PK1_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_IBS_RS232MON_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_IBS_APP70_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) },
 	/*
 	 * These will probably use user-space drivers.  Uncomment them if
 	 * you need them or use the user-specified vendor/product module
@@ -459,6 +468,7 @@
 	{ USB_DEVICE(FALCOM_VID, FALCOM_TWIST_PID) },
 	{ USB_DEVICE(FALCOM_VID, FALCOM_SAMBA_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_SUUNTO_SPORTS_PID) },
+	{ USB_DEVICE(TTI_VID, TTI_QL355P_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) },
 	{ USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
 	{ USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) },
@@ -533,6 +543,7 @@
 	[FT8U232AM] = "FT8U232AM",
 	[FT232BM] = "FT232BM",
 	[FT2232C] = "FT2232C",
+	[FT232RL] = "FT232RL",
 };
 
 
@@ -588,6 +599,8 @@
 static int  ftdi_sio_probe	(struct usb_serial *serial, const struct usb_device_id *id);
 static int  ftdi_sio_attach		(struct usb_serial *serial);
 static void ftdi_shutdown		(struct usb_serial *serial);
+static int  ftdi_sio_port_probe	(struct usb_serial_port *port);
+static int  ftdi_sio_port_remove	(struct usb_serial_port *port);
 static int  ftdi_open			(struct usb_serial_port *port, struct file *filp);
 static void ftdi_close			(struct usb_serial_port *port, struct file *filp);
 static int  ftdi_write			(struct usb_serial_port *port, const unsigned char *buf, int count);
@@ -622,6 +635,8 @@
 	.num_bulk_out =		1,
 	.num_ports =		1,
 	.probe =		ftdi_sio_probe,
+	.port_probe =		ftdi_sio_port_probe,
+	.port_remove =		ftdi_sio_port_remove,
 	.open =			ftdi_open,
 	.close =		ftdi_close,
 	.throttle =		ftdi_throttle,
@@ -864,6 +879,7 @@
 		break;
 	case FT232BM: /* FT232BM chip */
 	case FT2232C: /* FT2232C chip */
+	case FT232RL:
 		if (baud <= 3000000) {
 			div_value = ftdi_232bm_baud_to_divisor(baud);
 		} else {
@@ -1006,9 +1022,12 @@
 		/* (It might be a BM because of the iSerialNumber bug,
 		 * but it will still work as an AM device.) */
 		priv->chip_type = FT8U232AM;
-	} else {
+	} else if (version < 0x600) {
 		/* Assume its an FT232BM (or FT245BM) */
 		priv->chip_type = FT232BM;
+	} else {
+		/* Assume its an FT232R  */
+		priv->chip_type = FT232RL;
 	}
 	info("Detected %s", ftdi_chip_name[priv->chip_type]);
 }
@@ -1024,11 +1043,10 @@
 {
 	struct usb_serial_port *port = to_usb_serial_port(dev);
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
-	struct usb_device *udev;
+	struct usb_device *udev = port->serial->dev;
 	unsigned short latency = 0;
 	int rv = 0;
 
-	udev = to_usb_device(dev);
 
 	dbg("%s",__FUNCTION__);
 
@@ -1052,13 +1070,11 @@
 {
 	struct usb_serial_port *port = to_usb_serial_port(dev);
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
-	struct usb_device *udev;
+	struct usb_device *udev = port->serial->dev;
 	char buf[1];
 	int v = simple_strtoul(valbuf, NULL, 10);
 	int rv = 0;
 
-	udev = to_usb_device(dev);
-
 	dbg("%s: setting latency timer = %i", __FUNCTION__, v);
 
 	rv = usb_control_msg(udev,
@@ -1083,13 +1099,11 @@
 {
 	struct usb_serial_port *port = to_usb_serial_port(dev);
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
-	struct usb_device *udev;
+	struct usb_device *udev = port->serial->dev;
 	char buf[1];
 	int v = simple_strtoul(valbuf, NULL, 10);
 	int rv = 0;
 
-	udev = to_usb_device(dev);
-
 	dbg("%s: setting event char = %i", __FUNCTION__, v);
 
 	rv = usb_control_msg(udev,
@@ -1110,46 +1124,38 @@
 static DEVICE_ATTR(latency_timer, S_IWUSR | S_IRUGO, show_latency_timer, store_latency_timer);
 static DEVICE_ATTR(event_char, S_IWUSR, NULL, store_event_char);
 
-static int create_sysfs_attrs(struct usb_serial *serial)
+static int create_sysfs_attrs(struct usb_serial_port *port)
 {
-	struct ftdi_private *priv;
-	struct usb_device *udev;
+	struct ftdi_private *priv = usb_get_serial_port_data(port);
 	int retval = 0;
 
 	dbg("%s",__FUNCTION__);
 
-	priv = usb_get_serial_port_data(serial->port[0]);
-	udev = serial->dev;
-
 	/* XXX I've no idea if the original SIO supports the event_char
 	 * sysfs parameter, so I'm playing it safe.  */
 	if (priv->chip_type != SIO) {
 		dbg("sysfs attributes for %s", ftdi_chip_name[priv->chip_type]);
-		retval = device_create_file(&udev->dev, &dev_attr_event_char);
+		retval = device_create_file(&port->dev, &dev_attr_event_char);
 		if ((!retval) &&
 		    (priv->chip_type == FT232BM || priv->chip_type == FT2232C)) {
-			retval = device_create_file(&udev->dev,
+			retval = device_create_file(&port->dev,
 						    &dev_attr_latency_timer);
 		}
 	}
 	return retval;
 }
 
-static void remove_sysfs_attrs(struct usb_serial *serial)
+static void remove_sysfs_attrs(struct usb_serial_port *port)
 {
-	struct ftdi_private *priv;
-	struct usb_device *udev;
+	struct ftdi_private *priv = usb_get_serial_port_data(port);
 
 	dbg("%s",__FUNCTION__);
 
-	priv = usb_get_serial_port_data(serial->port[0]);
-	udev = serial->dev;
-
 	/* XXX see create_sysfs_attrs */
 	if (priv->chip_type != SIO) {
-		device_remove_file(&udev->dev, &dev_attr_event_char);
+		device_remove_file(&port->dev, &dev_attr_event_char);
 		if (priv->chip_type == FT232BM || priv->chip_type == FT2232C) {
-			device_remove_file(&udev->dev, &dev_attr_latency_timer);
+			device_remove_file(&port->dev, &dev_attr_latency_timer);
 		}
 	}
 
@@ -1169,13 +1175,9 @@
 	return (0);
 }
 
-/* attach subroutine */
-static int ftdi_sio_attach (struct usb_serial *serial)
+static int ftdi_sio_port_probe(struct usb_serial_port *port)
 {
-	struct usb_serial_port *port = serial->port[0];
 	struct ftdi_private *priv;
-	struct ftdi_sio_quirk *quirk;
-	int retval;
 
 	dbg("%s",__FUNCTION__);
 
@@ -1215,19 +1217,21 @@
 	kfree(port->bulk_out_buffer);
 	port->bulk_out_buffer = NULL;
 
-	usb_set_serial_port_data(serial->port[0], priv);
+	usb_set_serial_port_data(port, priv);
 
-	ftdi_determine_type (serial->port[0]);
-	retval = create_sysfs_attrs(serial);
-	if (retval)
-		dev_err(&serial->dev->dev, "Error creating sysfs files, "
-			"continuing\n");
+	ftdi_determine_type (port);
+	create_sysfs_attrs(port);
+	return 0;
+}
 
+/* attach subroutine */
+static int ftdi_sio_attach (struct usb_serial *serial)
+{
 	/* Check for device requiring special set up. */
-	quirk = (struct ftdi_sio_quirk *)usb_get_serial_data(serial);
-	if (quirk && quirk->setup) {
+	struct ftdi_sio_quirk *quirk = usb_get_serial_data(serial);
+
+	if (quirk && quirk->setup)
 		quirk->setup(serial);
-	}
 
 	return 0;
 } /* ftdi_sio_attach */
@@ -1271,17 +1275,18 @@
  *      calls __serial_close for each open of the port
  *      shutdown is called then (ie ftdi_shutdown)
  */
-
-
 static void ftdi_shutdown (struct usb_serial *serial)
-{ /* ftdi_shutdown */
+{
+	dbg("%s", __FUNCTION__);
+}
 
-	struct usb_serial_port *port = serial->port[0];
+static int ftdi_sio_port_remove(struct usb_serial_port *port)
+{
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
 
 	dbg("%s", __FUNCTION__);
 
-	remove_sysfs_attrs(serial);
+	remove_sysfs_attrs(port);
 
 	/* all open ports are closed at this point
          *    (by usbserial.c:__serial_close, which calls ftdi_close)
@@ -1291,8 +1296,9 @@
 		usb_set_serial_port_data(port, NULL);
 		kfree(priv);
 	}
-} /* ftdi_shutdown */
 
+	return 0;
+}
 
 static int  ftdi_open (struct usb_serial_port *port, struct file *filp)
 { /* ftdi_open */
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 1bdda93..513cfe1 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -27,6 +27,7 @@
 #define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */
 #define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */
 #define FTDI_8U2232C_PID 0x6010 /* Dual channel device */
+#define FTDI_232RL_PID  0xFBFA  /* Product ID for FT232RL */
 #define FTDI_RELAIS_PID	0xFA10  /* Relais device from Rudolf Gugler */
 #define FTDI_NF_RIC_VID	0x0DCD	/* Vendor Id */
 #define FTDI_NF_RIC_PID	0x0001	/* Product Id */
@@ -339,6 +340,12 @@
 #define FTDI_SUUNTO_SPORTS_PID	0xF680	/* Suunto Sports instrument */
 
 /*
+ * TTi (Thurlby Thandar Instruments)
+ */
+#define TTI_VID			0x103E	/* Vendor Id */
+#define TTI_QL355P_PID		0x03E8	/* TTi QL355P power supply */
+
+/*
  * Definitions for B&B Electronics products.
  */
 #define BANDB_VID		0x0856	/* B&B Electronics Vendor ID */
@@ -497,6 +504,19 @@
 #define TELLDUS_VID			0x1781	/* Vendor ID */
 #define TELLDUS_TELLSTICK_PID		0x0C30	/* RF control dongle 433 MHz using FT232RL */
 
+/*
+ * IBS elektronik product ids
+ * Submitted by Thomas Schleusener
+ */
+#define FTDI_IBS_US485_PID	0xff38  /* IBS US485 (USB<-->RS422/485 interface) */
+#define FTDI_IBS_PICPRO_PID	0xff39  /* IBS PIC-Programmer */
+#define FTDI_IBS_PCMCIA_PID	0xff3a  /* IBS Card reader for PCMCIA SRAM-cards */
+#define FTDI_IBS_PK1_PID	0xff3b  /* IBS PK1 - Particel counter */
+#define FTDI_IBS_RS232MON_PID	0xff3c  /* IBS RS232 - Monitor */
+#define FTDI_IBS_APP70_PID	0xff3d  /* APP 70 (dust monitoring system) */
+#define FTDI_IBS_PEDO_PID	0xff3e  /* IBS PEDO-Modem (RF modem 868.35 MHz) */
+#define FTDI_IBS_PROD_PID	0xff3f  /* future device */
+
 /* Commands */
 #define FTDI_SIO_RESET 		0 /* Reset the port */
 #define FTDI_SIO_MODEM_CTRL 	1 /* Set the modem control register */
@@ -620,6 +640,7 @@
 	FT8U232AM = 2,
 	FT232BM = 3,
 	FT2232C = 4,
+	FT232RL = 5,
 } ftdi_chip_type_t;
 
 typedef enum {
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 53baeec..4f8282a 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -20,13 +20,14 @@
 #include <linux/usb/serial.h>
 #include <asm/uaccess.h>
 
-static int generic_probe(struct usb_interface *interface,
-			 const struct usb_device_id *id);
-
 
 static int debug;
 
 #ifdef CONFIG_USB_SERIAL_GENERIC
+
+static int generic_probe(struct usb_interface *interface,
+			 const struct usb_device_id *id);
+
 static __u16 vendor  = 0x05f9;
 static __u16 product = 0xffff;
 
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index a408184..d16e2e1 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -247,6 +247,8 @@
 	{ USB_DEVICE(0x04AD, 0x0301) }, /* USB Sync 0301 */
 	{ USB_DEVICE(0x04AD, 0x0302) }, /* USB Sync 0302 */
 	{ USB_DEVICE(0x04AD, 0x0303) }, /* USB Sync 0303 */
+	{ USB_DEVICE(0x04AD, 0x0306) }, /* GPS Pocket PC USB Sync */
+	{ USB_DEVICE(0x04B7, 0x0531) }, /* MyGuide 7000 XL USB Sync */
 	{ USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */
 	{ USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */
 	{ USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index 2d588fb..19bf403 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -1628,6 +1628,7 @@
 	.chars_in_buffer	= mos7720_chars_in_buffer,
 	.break_ctl		= mos7720_break,
 	.read_bulk_callback	= mos7720_bulk_in_callback,
+	.read_int_callback	= mos7720_interrupt_callback,
 };
 
 static int __init moschip7720_init(void)
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index db92a7f..e178e6f 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -109,7 +109,6 @@
 #define HUAWEI_PRODUCT_E220			0x1003
 
 #define NOVATELWIRELESS_VENDOR_ID		0x1410
-#define NOVATELWIRELESS_PRODUCT_U740		0x1400
 
 #define ANYDATA_VENDOR_ID			0x16d5
 #define ANYDATA_PRODUCT_ID			0x6501
@@ -152,7 +151,19 @@
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_NETWORK) },
 	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
 	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
-	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
+	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1100) }, /* Novatel Merlin XS620/S640 */
+	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1110) }, /* Novatel Merlin S620 */
+	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1120) }, /* Novatel Merlin EX720 */
+	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1130) }, /* Novatel Merlin S720 */
+	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1400) }, /* Novatel U730 */
+	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1410) }, /* Novatel U740 */
+	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1420) }, /* Novatel EU870 */
+	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1430) }, /* Novatel Merlin XU870 HSDPA/3G */
+	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1430) }, /* Novatel XU870 */
+	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2100) }, /* Novatel EV620 CDMA/EV-DO */
+	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */
+	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */
+	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */
 	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
 	{ } /* Terminating entry */
 };
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 6bf22a2..7639022 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -99,9 +99,12 @@
 			continue;
 
 		*minor = i;
+		j = 0;
 		dbg("%s - minor base = %d", __FUNCTION__, *minor);
-		for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i)
+		for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i) {
 			serial_table[i] = serial;
+			serial->port[j++]->number = i;
+		}
 		spin_unlock(&table_lock);
 		return serial;
 	}
@@ -826,7 +829,6 @@
 			num_ports = type->num_ports;
 	}
 
-	serial->minor = minor;
 	serial->num_ports = num_ports;
 	serial->num_bulk_in = num_bulk_in;
 	serial->num_bulk_out = num_bulk_out;
@@ -847,7 +849,6 @@
 		port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL);
 		if (!port)
 			goto probe_error;
-		port->number = i + serial->minor;
 		port->serial = serial;
 		spin_lock_init(&port->lock);
 		mutex_init(&port->mutex);
@@ -980,6 +981,7 @@
 		dev_err(&interface->dev, "No more free serial devices\n");
 		goto probe_error;
 	}
+	serial->minor = minor;
 
 	/* register all of the individual ports with the driver core */
 	for (i = 0; i < num_ports; ++i) {
@@ -1034,9 +1036,6 @@
 		kfree(port->interrupt_out_buffer);
 	}
 
-	/* return the minor range that this device had */
-	return_serial (serial);
-
 	/* free up any memory that we allocated */
 	for (i = 0; i < serial->num_port_pointers; ++i)
 		kfree(serial->port[i]);
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 9644a8e..4a9d0d5 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -146,6 +146,13 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
+/* Reported by Andrew Nayenko <relan@bk.ru> */
+UNUSUAL_DEV(  0x0421, 0x0019, 0x0592, 0x0592,
+		"Nokia",
+		"Nokia 6288",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_MAX_SECTORS_64 ),
+
 /* Reported by Mario Rettig <mariorettig@web.de> */
 UNUSUAL_DEV(  0x0421, 0x042e, 0x0100, 0x0100,
 		"Nokia",
@@ -320,6 +327,13 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY),
 
+/* Reported by Emil Larsson <emil@swip.net> */
+UNUSUAL_DEV(  0x04b0, 0x0411, 0x0100, 0x0100,
+		"NIKON",
+		"NIKON DSC D80",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_FIX_CAPACITY),
+
 /* BENQ DC5330
  * Reported by Manuel Fombuena <mfombuena@ya.com> and
  * Frank Copeland <fjc@thingy.apana.org.au> */
@@ -1395,16 +1409,6 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
-/* Reported by Thomas Baechler <thomas@archlinux.org>
- * Fixes I/O errors with Teac HD-35PU devices
- */
-
-UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201,
-               "Super Top",
-               "USB 2.0  IDE DEVICE",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_IGNORE_RESIDUE),
-
 /* patch submitted by Davide Perini <perini.davide@dpsoftware.org>
  * and Renato Perini <rperini@email.it>
  */
@@ -1414,6 +1418,16 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY | US_FL_IGNORE_RESIDUE ),
 
+/*
+ * Patch by Pete Zaitcev <zaitcev@redhat.com>
+ * Report by Mark Patton. Red Hat bz#208928.
+ */
+UNUSUAL_DEV(  0x22b8, 0x4810, 0x0001, 0x0001,
+		"Motorola",
+		"RAZR V3i",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_FIX_CAPACITY),
+
 /* Reported by Radovan Garabik <garabik@kassiopeia.juls.savba.sk> */
 UNUSUAL_DEV(  0x2735, 0x100b, 0x0000, 0x9999,
 		"MPIO",
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 35d2abd..5af684b 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1320,7 +1320,7 @@
 
 config FB_AU1200
 	bool "Au1200 LCD Driver"
-	depends on FB && MIPS && SOC_AU1200
+	depends on (FB = y) && MIPS && SOC_AU1200
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
@@ -1470,7 +1470,7 @@
 
 config FB_68328
 	bool "Motorola 68328 native frame buffer support"
-	depends on FB && (M68328 || M68EZ328 || M68VZ328)
+	depends on (FB = y) && (M68328 || M68EZ328 || M68VZ328)
  	select FB_CFB_FILLRECT
  	select FB_CFB_COPYAREA
  	select FB_CFB_IMAGEBLIT
@@ -1616,7 +1616,7 @@
 
 config FB_PS3
 	bool "PS3 GPU framebuffer driver"
-	depends on FB && PS3_PS3AV
+	depends on (FB = y) && PS3_PS3AV
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c
index d131247..6b488b8 100644
--- a/drivers/video/backlight/locomolcd.c
+++ b/drivers/video/backlight/locomolcd.c
@@ -199,8 +199,8 @@
 {
 	unsigned long flags;
 
-	locomobl_data.brightness = 0;
-	locomobl_data.power = 0;
+	locomolcd_bl_device->props.brightness = 0;
+	locomolcd_bl_device->props.power = 0;
 	locomolcd_set_intensity(locomolcd_bl_device);
 
 	backlight_device_unregister(locomolcd_bl_device);
diff --git a/drivers/video/backlight/progear_bl.c b/drivers/video/backlight/progear_bl.c
index 7022693..836ab4d 100644
--- a/drivers/video/backlight/progear_bl.c
+++ b/drivers/video/backlight/progear_bl.c
@@ -65,13 +65,13 @@
 	u8 temp;
 	struct backlight_device *progear_backlight_device;
 
-	pmu_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, 0);
+	pmu_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, NULL);
 	if (!pmu_dev) {
 		printk("ALI M7101 PMU not found.\n");
 		return -ENODEV;
 	}
 
-	sb_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, 0);
+	sb_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
 	if (!sb_dev) {
 		printk("ALI 1533 SB not found.\n");
 		pci_dev_put(pmu_dev);
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index 9bb6257..b0b2e40 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -186,8 +186,7 @@
  *  Initialisation
  */
 
-static void
-bw2_init_fix(struct fb_info *info, int linebytes)
+static void __devinit bw2_init_fix(struct fb_info *info, int linebytes)
 {
 	strlcpy(info->fix.id, "bwtwo", sizeof(info->fix.id));
 
@@ -199,43 +198,44 @@
 	info->fix.accel = FB_ACCEL_SUN_BWTWO;
 }
 
-static u8 bw2regs_1600[] __initdata = {
+static u8 bw2regs_1600[] __devinitdata = {
 	0x14, 0x8b,	0x15, 0x28,	0x16, 0x03,	0x17, 0x13,
 	0x18, 0x7b,	0x19, 0x05,	0x1a, 0x34,	0x1b, 0x2e,
 	0x1c, 0x00,	0x1d, 0x0a,	0x1e, 0xff,	0x1f, 0x01,
 	0x10, 0x21,	0
 };
 
-static u8 bw2regs_ecl[] __initdata = {
+static u8 bw2regs_ecl[] __devinitdata = {
 	0x14, 0x65,	0x15, 0x1e,	0x16, 0x04,	0x17, 0x0c,
 	0x18, 0x5e,	0x19, 0x03,	0x1a, 0xa7,	0x1b, 0x23,
 	0x1c, 0x00,	0x1d, 0x08,	0x1e, 0xff,	0x1f, 0x01,
 	0x10, 0x20,	0
 };
 
-static u8 bw2regs_analog[] __initdata = {
+static u8 bw2regs_analog[] __devinitdata = {
 	0x14, 0xbb,	0x15, 0x2b,	0x16, 0x03,	0x17, 0x13,
 	0x18, 0xb0,	0x19, 0x03,	0x1a, 0xa6,	0x1b, 0x22,
 	0x1c, 0x01,	0x1d, 0x05,	0x1e, 0xff,	0x1f, 0x01,
 	0x10, 0x20,	0
 };
 
-static u8 bw2regs_76hz[] __initdata = {
+static u8 bw2regs_76hz[] __devinitdata = {
 	0x14, 0xb7,	0x15, 0x27,	0x16, 0x03,	0x17, 0x0f,
 	0x18, 0xae,	0x19, 0x03,	0x1a, 0xae,	0x1b, 0x2a,
 	0x1c, 0x01,	0x1d, 0x09,	0x1e, 0xff,	0x1f, 0x01,
 	0x10, 0x24,	0
 };
 
-static u8 bw2regs_66hz[] __initdata = {
+static u8 bw2regs_66hz[] __devinitdata = {
 	0x14, 0xbb,	0x15, 0x2b,	0x16, 0x04,	0x17, 0x14,
 	0x18, 0xae,	0x19, 0x03,	0x1a, 0xa8,	0x1b, 0x24,
 	0x1c, 0x01,	0x1d, 0x05,	0x1e, 0xff,	0x1f, 0x01,
 	0x10, 0x20,	0
 };
 
-static void bw2_do_default_mode(struct bw2_par *par, struct fb_info *info,
-				int *linebytes)
+static void __devinit bw2_do_default_mode(struct bw2_par *par,
+					  struct fb_info *info,
+					  int *linebytes)
 {
 	u8 status, mon;
 	u8 *p;
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index ec6a51a..b071bb6 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -354,7 +354,8 @@
  *  Initialisation
  */
 
-static void cg14_init_fix(struct fb_info *info, int linebytes, struct device_node *dp)
+static void __devinit cg14_init_fix(struct fb_info *info, int linebytes,
+				    struct device_node *dp)
 {
 	const char *name = dp->name;
 
@@ -368,7 +369,7 @@
 	info->fix.accel = FB_ACCEL_SUN_CG14;
 }
 
-static struct sbus_mmap_map __cg14_mmap_map[CG14_MMAP_ENTRIES] __initdata = {
+static struct sbus_mmap_map __cg14_mmap_map[CG14_MMAP_ENTRIES] __devinitdata = {
 	{
 		.voff	= CG14_REGS,
 		.poff	= 0x80000000,
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index ada6f7e..767c850 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -186,8 +186,7 @@
  *      @blank_mode: the blank mode we want.
  *      @info: frame buffer structure that represents a single frame buffer
  */
-static int
-cg3_blank(int blank, struct fb_info *info)
+static int cg3_blank(int blank, struct fb_info *info)
 {
 	struct cg3_par *par = (struct cg3_par *) info->par;
 	struct cg3_regs __iomem *regs = par->regs;
@@ -251,8 +250,8 @@
  *  Initialisation
  */
 
-static void
-cg3_init_fix(struct fb_info *info, int linebytes, struct device_node *dp)
+static void __devinit cg3_init_fix(struct fb_info *info, int linebytes,
+				   struct device_node *dp)
 {
 	strlcpy(info->fix.id, dp->name, sizeof(info->fix.id));
 
@@ -264,8 +263,8 @@
 	info->fix.accel = FB_ACCEL_SUN_CGTHREE;
 }
 
-static void cg3_rdi_maybe_fixup_var(struct fb_var_screeninfo *var,
-				    struct device_node *dp)
+static void __devinit cg3_rdi_maybe_fixup_var(struct fb_var_screeninfo *var,
+					      struct device_node *dp)
 {
 	char *params;
 	char *p;
@@ -287,36 +286,36 @@
 	}
 }
 
-static u8 cg3regvals_66hz[] __initdata = {	/* 1152 x 900, 66 Hz */
+static u8 cg3regvals_66hz[] __devinitdata = {	/* 1152 x 900, 66 Hz */
 	0x14, 0xbb,	0x15, 0x2b,	0x16, 0x04,	0x17, 0x14,
 	0x18, 0xae,	0x19, 0x03,	0x1a, 0xa8,	0x1b, 0x24,
 	0x1c, 0x01,	0x1d, 0x05,	0x1e, 0xff,	0x1f, 0x01,
 	0x10, 0x20,	0
 };
 
-static u8 cg3regvals_76hz[] __initdata = {	/* 1152 x 900, 76 Hz */
+static u8 cg3regvals_76hz[] __devinitdata = {	/* 1152 x 900, 76 Hz */
 	0x14, 0xb7,	0x15, 0x27,	0x16, 0x03,	0x17, 0x0f,
 	0x18, 0xae,	0x19, 0x03,	0x1a, 0xae,	0x1b, 0x2a,
 	0x1c, 0x01,	0x1d, 0x09,	0x1e, 0xff,	0x1f, 0x01,
 	0x10, 0x24,	0
 };
 
-static u8 cg3regvals_rdi[] __initdata = {	/* 640 x 480, cgRDI */
+static u8 cg3regvals_rdi[] __devinitdata = {	/* 640 x 480, cgRDI */
 	0x14, 0x70,	0x15, 0x20,	0x16, 0x08,	0x17, 0x10,
 	0x18, 0x06,	0x19, 0x02,	0x1a, 0x31,	0x1b, 0x51,
 	0x1c, 0x06,	0x1d, 0x0c,	0x1e, 0xff,	0x1f, 0x01,
 	0x10, 0x22,	0
 };
 
-static u8 *cg3_regvals[] __initdata = {
+static u8 *cg3_regvals[] __devinitdata = {
 	cg3regvals_66hz, cg3regvals_76hz, cg3regvals_rdi
 };
 
-static u_char cg3_dacvals[] __initdata = {
+static u_char cg3_dacvals[] __devinitdata = {
 	4, 0xff,	5, 0x00,	6, 0x70,	7, 0x00,	0
 };
 
-static void cg3_do_default_mode(struct cg3_par *par)
+static void __devinit cg3_do_default_mode(struct cg3_par *par)
 {
 	enum cg3_type type;
 	u8 *p;
@@ -433,7 +432,8 @@
 	return 0;
 }
 
-static int __devinit cg3_probe(struct of_device *dev, const struct of_device_id *match)
+static int __devinit cg3_probe(struct of_device *dev,
+			       const struct of_device_id *match)
 {
 	struct of_device *op = to_of_device(&dev->dev);
 
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 15854ae..1d4e835 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -336,14 +336,30 @@
 	u32	value2;
 };
 
+#define FFB_DAC_UCTRL	0x1001 /* User Control */
+#define  FFB_DAC_UCTRL_MANREV	0x00000f00 /* 4-bit Manufacturing Revision */
+#define  FFB_DAC_UCTRL_MANREV_SHIFT 8
+#define FFB_DAC_TGEN	0x6000 /* Timing Generator */
+#define  FFB_DAC_TGEN_VIDE	0x00000001 /* Video Enable */
+#define FFB_DAC_DID	0x8000 /* Device Identification */
+#define  FFB_DAC_DID_PNUM	0x0ffff000 /* Device Part Number */
+#define  FFB_DAC_DID_PNUM_SHIFT 12
+#define  FFB_DAC_DID_REV	0xf0000000 /* Device Revision */
+#define  FFB_DAC_DID_REV_SHIFT 28
+
+#define FFB_DAC_CUR_CTRL	0x100
+#define  FFB_DAC_CUR_CTRL_P0	0x00000001
+#define  FFB_DAC_CUR_CTRL_P1	0x00000002
+
 struct ffb_par {
 	spinlock_t		lock;
 	struct ffb_fbc __iomem	*fbc;
 	struct ffb_dac __iomem	*dac;
 
 	u32			flags;
-#define FFB_FLAG_AFB		0x00000001
-#define FFB_FLAG_BLANKED	0x00000002
+#define FFB_FLAG_AFB		0x00000001 /* AFB m3 or m6 */
+#define FFB_FLAG_BLANKED	0x00000002 /* screen is blanked */
+#define FFB_FLAG_INVCURSOR	0x00000004 /* DAC has inverted cursor logic */
 
 	u32			fg_cache __attribute__((aligned (8)));
 	u32			bg_cache;
@@ -354,7 +370,6 @@
 	unsigned long		physbase;
 	unsigned long		fbsize;
 
-	int			dac_rev;
 	int			board_type;
 };
 
@@ -426,11 +441,12 @@
 	FFBWait(par);
 
 	/* Disable cursor.  */
-	upa_writel(0x100, &dac->type2);
-	if (par->dac_rev <= 2)
+	upa_writel(FFB_DAC_CUR_CTRL, &dac->type2);
+	if (par->flags & FFB_FLAG_INVCURSOR)
 		upa_writel(0, &dac->value2);
 	else
-		upa_writel(3, &dac->value2);
+		upa_writel((FFB_DAC_CUR_CTRL_P0 |
+			    FFB_DAC_CUR_CTRL_P1), &dac->value2);
 
 	spin_unlock_irqrestore(&par->lock, flags);
 }
@@ -664,18 +680,18 @@
 	struct ffb_par *par = (struct ffb_par *) info->par;
 	struct ffb_dac __iomem *dac = par->dac;
 	unsigned long flags;
-	u32 tmp;
+	u32 val;
+	int i;
 
 	spin_lock_irqsave(&par->lock, flags);
 
 	FFBWait(par);
 
+	upa_writel(FFB_DAC_TGEN, &dac->type);
+	val = upa_readl(&dac->value);
 	switch (blank) {
 	case FB_BLANK_UNBLANK: /* Unblanking */
-		upa_writel(0x6000, &dac->type);
-		tmp = (upa_readl(&dac->value) | 0x1);
-		upa_writel(0x6000, &dac->type);
-		upa_writel(tmp, &dac->value);
+		val |= FFB_DAC_TGEN_VIDE;
 		par->flags &= ~FFB_FLAG_BLANKED;
 		break;
 
@@ -683,13 +699,16 @@
 	case FB_BLANK_VSYNC_SUSPEND: /* VESA blank (vsync off) */
 	case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */
 	case FB_BLANK_POWERDOWN: /* Poweroff */
-		upa_writel(0x6000, &dac->type);
-		tmp = (upa_readl(&dac->value) & ~0x1);
-		upa_writel(0x6000, &dac->type);
-		upa_writel(tmp, &dac->value);
+		val &= ~FFB_DAC_TGEN_VIDE;
 		par->flags |= FFB_FLAG_BLANKED;
 		break;
 	}
+	upa_writel(FFB_DAC_TGEN, &dac->type);
+	upa_writel(val, &dac->value);
+	for (i = 0; i < 10; i++) {
+		upa_writel(FFB_DAC_TGEN, &dac->type);
+		upa_readl(&dac->value);
+	}
 
 	spin_unlock_irqrestore(&par->lock, flags);
 
@@ -894,6 +913,7 @@
 	struct ffb_dac __iomem *dac;
 	struct all_info *all;
 	int err;
+	u32 dac_pnum, dac_rev, dac_mrev;
 
 	all = kzalloc(sizeof(*all), GFP_KERNEL);
 	if (!all)
@@ -948,17 +968,31 @@
 	if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0)
 		upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr);
 
-	ffb_switch_from_graph(&all->par);
-
 	dac = all->par.dac;
-	upa_writel(0x8000, &dac->type);
-	all->par.dac_rev = upa_readl(&dac->value) >> 0x1c;
+	upa_writel(FFB_DAC_DID, &dac->type);
+	dac_pnum = upa_readl(&dac->value);
+	dac_rev = (dac_pnum & FFB_DAC_DID_REV) >> FFB_DAC_DID_REV_SHIFT;
+	dac_pnum = (dac_pnum & FFB_DAC_DID_PNUM) >> FFB_DAC_DID_PNUM_SHIFT;
+
+	upa_writel(FFB_DAC_UCTRL, &dac->type);
+	dac_mrev = upa_readl(&dac->value);
+	dac_mrev = (dac_mrev & FFB_DAC_UCTRL_MANREV) >>
+		FFB_DAC_UCTRL_MANREV_SHIFT;
 
 	/* Elite3D has different DAC revision numbering, and no DAC revisions
-	 * have the reversed meaning of cursor enable.
+	 * have the reversed meaning of cursor enable.  Otherwise, Pacifica 1
+	 * ramdacs with manufacturing revision less than 3 have inverted
+	 * cursor logic.  We identify Pacifica 1 as not Pacifica 2, the
+	 * latter having a part number value of 0x236e.
 	 */
-	if (all->par.flags & FFB_FLAG_AFB)
-		all->par.dac_rev = 10;
+	if ((all->par.flags & FFB_FLAG_AFB) || dac_pnum == 0x236e) {
+		all->par.flags &= ~FFB_FLAG_INVCURSOR;
+	} else {
+		if (dac_mrev < 3)
+			all->par.flags |= FFB_FLAG_INVCURSOR;
+	}
+
+	ffb_switch_from_graph(&all->par);
 
 	/* Unblank it just to be sure.  When there are multiple
 	 * FFB/AFB cards in the system, or it is not the OBP
@@ -993,10 +1027,12 @@
 
 	dev_set_drvdata(&op->dev, all);
 
-	printk("%s: %s at %016lx, type %d, DAC revision %d\n",
+	printk("%s: %s at %016lx, type %d, "
+	       "DAC pnum[%x] rev[%d] manuf_rev[%d]\n",
 	       dp->full_name,
 	       ((all->par.flags & FFB_FLAG_AFB) ? "AFB" : "FFB"),
-	       all->par.physbase, all->par.board_type, all->par.dac_rev);
+	       all->par.physbase, all->par.board_type,
+	       dac_pnum, dac_rev, dac_mrev);
 
 	return 0;
 }
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 1d1c7c6..d7ece8d 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -285,8 +285,6 @@
 #define MAX_LEVEL 0x534
 #define LEVEL_STEP ((MAX_LEVEL - MIN_LEVEL) / FB_BACKLIGHT_MAX)
 
-static struct backlight_properties riva_bl_data;
-
 static int riva_bl_get_level_brightness(struct riva_par *par,
 		int level)
 {
@@ -372,7 +370,7 @@
 		FB_BACKLIGHT_MAX);
 
 	bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
-	bd->props.brightness = riva_bl_data.max_brightness;
+	bd->props.brightness = bd->props.max_brightness;
 	bd->props.power = FB_BLANK_UNBLANK;
 	backlight_update_status(bd);
 
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index 98919a6..3091b20 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -1000,11 +1000,12 @@
 static void __devexit s3_pci_remove(struct pci_dev *dev)
 {
 	struct fb_info *info = pci_get_drvdata(dev);
-	struct s3fb_info *par = info->par;
 
 	if (info) {
 
 #ifdef CONFIG_MTRR
+		struct s3fb_info *par = info->par;
+
 		if (par->mtrr_reg >= 0) {
 			mtrr_del(par->mtrr_reg, 0, 0);
 			par->mtrr_reg = -1;
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 4afa305..0166ec2 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -384,6 +384,19 @@
 	BCI_SEND(0);
 	BCI_SEND(BCI_CMD_SETREG | (1 << 16) | BCI_GBD2);
 	BCI_SEND(GlobalBitmapDescriptor);
+
+	/*
+	 * I don't know why, sending this twice fixes the intial black screen,
+	 * prevents X from crashing at least in Toshiba laptops with SavageIX.
+	 * --Tony
+	 */
+	par->bci_ptr = 0;
+	par->SavageWaitFifo(par, 4);
+
+	BCI_SEND(BCI_CMD_SETREG | (1 << 16) | BCI_GBD1);
+	BCI_SEND(0);
+	BCI_SEND(BCI_CMD_SETREG | (1 << 16) | BCI_GBD2);
+	BCI_SEND(GlobalBitmapDescriptor);
 }
 
 static void savagefb_set_clip(struct fb_info *info)
@@ -496,7 +509,7 @@
 #ifdef SAVAGEFB_DEBUG
 /* This function is used to debug, it prints out the contents of s3 regs */
 
-static void SavagePrintRegs(void)
+static void SavagePrintRegs(struct savagefb_par *par)
 {
 	unsigned char i;
 	int vgaCRIndex = 0x3d4;
@@ -1525,7 +1538,7 @@
 	savagefb_set_fix(info);
 	savagefb_set_clip(info);
 
-	SavagePrintRegs();
+	SavagePrintRegs(par);
 	return 0;
 }
 
@@ -2155,7 +2168,6 @@
 	int video_len;
 
 	DBG("savagefb_probe");
-	SavagePrintRegs();
 
 	info = framebuffer_alloc(sizeof(struct savagefb_par), &dev->dev);
 	if (!info)
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index 59cd1e7..62fa550 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -257,6 +257,7 @@
 	r_dprintk("sst_dac_write(%#x, %#x)\n", reg, val);
 	reg &= 0x07;
 	__sst_write(vbase, DAC_DATA,(((u32)reg << 8)) | (u32)val);
+	__sst_wait_idle(vbase);
 }
 
 /* indexed access to ti/att dacs */
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
index 8ada4c5..6a82d39 100644
--- a/fs/9p/v9fs_vfs.h
+++ b/fs/9p/v9fs_vfs.h
@@ -40,7 +40,6 @@
 extern struct file_system_type v9fs_fs_type;
 extern const struct address_space_operations v9fs_addr_operations;
 extern const struct file_operations v9fs_file_operations;
-extern const struct file_operations v9fs_cached_file_operations;
 extern const struct file_operations v9fs_dir_operations;
 extern struct dentry_operations v9fs_dentry_operations;
 extern struct dentry_operations v9fs_cached_dentry_operations;
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 653dfa5..c7b6772 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -42,6 +42,8 @@
 #include "v9fs_vfs.h"
 #include "fid.h"
 
+static const struct file_operations v9fs_cached_file_operations;
+
 /**
  * v9fs_file_open - open a file (or directory)
  * @inode: inode to be opened
@@ -245,7 +247,7 @@
 	return total;
 }
 
-const struct file_operations v9fs_cached_file_operations = {
+static const struct file_operations v9fs_cached_file_operations = {
 	.llseek = generic_file_llseek,
 	.read = do_sync_read,
 	.aio_read = generic_file_aio_read,
diff --git a/fs/aio.c b/fs/aio.c
index 0b4ee0a..e4598d6 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -136,7 +136,6 @@
 				  0);
 	if (IS_ERR((void *)info->mmap_base)) {
 		up_write(&ctx->mm->mmap_sem);
-		printk("mmap err: %ld\n", -info->mmap_base);
 		info->mmap_size = 0;
 		aio_free_ring(ctx);
 		return -EAGAIN;
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 51db118..9cc4f0a 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -507,7 +507,7 @@
 #define INTERPRETER_ELF 2
 
 #ifndef STACK_RND_MASK
-#define STACK_RND_MASK 0x7ff		/* with 4K pages 8MB of VA */
+#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12))	/* 8MB of VA */
 #endif
 
 static unsigned long randomize_stack_top(unsigned long stack_top)
@@ -1704,7 +1704,10 @@
 				DUMP_SEEK(PAGE_SIZE);
 			} else {
 				if (page == ZERO_PAGE(addr)) {
-					DUMP_SEEK(PAGE_SIZE);
+					if (!dump_seek(file, PAGE_SIZE)) {
+						page_cache_release(page);
+						goto end_coredump;
+					}
 				} else {
 					void *kaddr;
 					flush_cache_page(vma, addr,
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 5810aa1..f3ddca4 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -179,6 +179,8 @@
 	int executable_stack;
 	int retval, i;
 
+	kdebug("____ LOAD %d ____", current->pid);
+
 	memset(&exec_params, 0, sizeof(exec_params));
 	memset(&interp_params, 0, sizeof(interp_params));
 
@@ -941,8 +943,11 @@
 
 		if (mm) {
 			if (phdr->p_flags & PF_X) {
-				mm->start_code = seg->addr;
-				mm->end_code = seg->addr + phdr->p_memsz;
+				if (!mm->start_code) {
+					mm->start_code = seg->addr;
+					mm->end_code = seg->addr +
+						phdr->p_memsz;
+				}
 			} else if (!mm->start_data) {
 				mm->start_data = seg->addr;
 #ifndef CONFIG_MMU
@@ -1123,8 +1128,10 @@
 
 		if (mm) {
 			if (phdr->p_flags & PF_X) {
-				mm->start_code = maddr;
-				mm->end_code = maddr + phdr->p_memsz;
+				if (!mm->start_code) {
+					mm->start_code = maddr;
+					mm->end_code = maddr + phdr->p_memsz;
+				}
 			} else if (!mm->start_data) {
 				mm->start_data = maddr;
 				mm->end_data = maddr + phdr->p_memsz;
@@ -1473,8 +1480,8 @@
 				DUMP_SEEK(file->f_pos + PAGE_SIZE);
 			}
 			else if (page == ZERO_PAGE(addr)) {
-				DUMP_SEEK(file->f_pos + PAGE_SIZE);
 				page_cache_release(page);
+				DUMP_SEEK(file->f_pos + PAGE_SIZE);
 			}
 			else {
 				void *kaddr;
diff --git a/fs/char_dev.c b/fs/char_dev.c
index 78ced72..164a45c 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -109,8 +109,6 @@
 	/* temporary */
 	if (major == 0) {
 		for (i = ARRAY_SIZE(chrdevs)-1; i > 0; i--) {
-			if (is_lanana_major(i))
-				continue;
 			if (chrdevs[i] == NULL)
 				break;
 		}
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 6247628..5d1f487 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -4,6 +4,12 @@
 Fix hang (in i_size_read) when simultaneous size update of same remote file
 on smp system corrupts sequence number. Do not reread unnecessarily partial page
 (which we are about to overwrite anyway) when writing out file opened rw.
+When DOS attribute of file on non-Unix server's file changes on the server side
+from read-only back to read-write, reflect this change in default file mode
+(we had been leaving a file's mode read-only until the inode were reloaded).
+Allow setting of attribute back to ATTR_NORMAL (removing readonly dos attribute
+when archive dos attribute not set and we are changing mode back to writeable
+on server which does not support the Unix Extensions).
 
 Version 1.47
 ------------
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index 0efdf35..4d8948e 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -220,7 +220,7 @@
  */
 #define CIFS_NO_HANDLE        0xFFFF
 
-#define NO_CHANGE_64          0xFFFFFFFFFFFFFFFFULL
+#define NO_CHANGE_64          cpu_to_le64(0xFFFFFFFFFFFFFFFFULL)
 #define NO_CHANGE_32          0xFFFFFFFFUL
 
 /* IPC$ in ASCII */
@@ -1887,7 +1887,13 @@
 						      calls including posix open
 						      and posix unlink */ 
 #ifdef CONFIG_CIFS_POSIX
-#define CIFS_UNIX_CAP_MASK              0x0000003b
+/* Can not set pathnames cap yet until we send new posix create SMB since
+   otherwise server can treat such handles opened with older ntcreatex
+   (by a new client which knows how to send posix path ops)
+   as non-posix handles (can affect write behavior with byte range locks.
+   We can add back in POSIX_PATH_OPS cap when Posix Create/Mkdir finished */
+/* #define CIFS_UNIX_CAP_MASK              0x0000003b */
+#define CIFS_UNIX_CAP_MASK              0x0000001b 
 #else 
 #define CIFS_UNIX_CAP_MASK              0x00000013
 #endif /* CONFIG_CIFS_POSIX */
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 86b9dbb..f414526 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -494,6 +494,12 @@
 			   mode e.g. 555 */
 			if (cifsInfo->cifsAttrs & ATTR_READONLY)
 				inode->i_mode &= ~(S_IWUGO);
+			else if ((inode->i_mode & S_IWUGO) == 0)
+				/* the ATTR_READONLY flag may have been	*/
+				/* changed on server -- set any w bits	*/
+				/* allowed by mnt_file_mode		*/
+				inode->i_mode |= (S_IWUGO &
+						  cifs_sb->mnt_file_mode);
 		/* BB add code here -
 		   validate if device or weird share or device type? */
 		}
@@ -1190,6 +1196,7 @@
 	struct cifsFileInfo *open_file = NULL;
 	FILE_BASIC_INFO time_buf;
 	int set_time = FALSE;
+	int set_dosattr = FALSE;
 	__u64 mode = 0xFFFFFFFFFFFFFFFFULL;
 	__u64 uid = 0xFFFFFFFFFFFFFFFFULL;
 	__u64 gid = 0xFFFFFFFFFFFFFFFFULL;
@@ -1326,15 +1333,23 @@
 	else if (attrs->ia_valid & ATTR_MODE) {
 		rc = 0;
 		if ((mode & S_IWUGO) == 0) /* not writeable */ {
-			if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0)
+			if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
+				set_dosattr = TRUE;
 				time_buf.Attributes =
 					cpu_to_le32(cifsInode->cifsAttrs |
 						    ATTR_READONLY);
+			}
 		} else if ((mode & S_IWUGO) == S_IWUGO) {
-			if (cifsInode->cifsAttrs & ATTR_READONLY)
+			if (cifsInode->cifsAttrs & ATTR_READONLY) {
+				set_dosattr = TRUE;
 				time_buf.Attributes =
 					cpu_to_le32(cifsInode->cifsAttrs &
 						    (~ATTR_READONLY));
+				/* Windows ignores set to zero */
+				if(time_buf.Attributes == 0)
+					time_buf.Attributes |= 
+						cpu_to_le32(ATTR_NORMAL);
+			}
 		}
 		/* BB to be implemented -
 		   via Windows security descriptors or streams */
@@ -1372,7 +1387,7 @@
 	} else
 		time_buf.ChangeTime = 0;
 
-	if (set_time || time_buf.Attributes) {
+	if (set_time || set_dosattr) {
 		time_buf.CreationTime = 0;	/* do not change */
 		/* In the future we should experiment - try setting timestamps
 		   via Handle (SetFileInfo) instead of by path */
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 44cfb52..2a374d52 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -219,6 +219,10 @@
 		tmp_inode->i_mode |= S_IFREG;
 		if (attr & ATTR_READONLY)
 			tmp_inode->i_mode &= ~(S_IWUGO);
+		else if ((tmp_inode->i_mode & S_IWUGO) == 0)
+			/* the ATTR_READONLY flag may have been changed on   */
+		   	/* server -- set any w bits allowed by mnt_file_mode */
+			tmp_inode->i_mode |= (S_IWUGO & cifs_sb->mnt_file_mode);
 	} /* could add code here - to validate if device or weird share type? */
 
 	/* can not fill in nlink here as in qpathinfo version and Unx search */
diff --git a/fs/compat.c b/fs/compat.c
index 0ec70e3..040a8be 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -48,6 +48,7 @@
 #include <linux/highmem.h>
 #include <linux/poll.h>
 #include <linux/mm.h>
+#include <linux/eventpoll.h>
 
 #include <net/sock.h>		/* siocdevprivate_ioctl */
 
@@ -2235,3 +2236,102 @@
 	return sys_ni_syscall();
 }
 #endif
+
+#ifdef CONFIG_EPOLL
+
+#ifdef CONFIG_HAS_COMPAT_EPOLL_EVENT
+asmlinkage long compat_sys_epoll_ctl(int epfd, int op, int fd,
+			struct compat_epoll_event __user *event)
+{
+	long err = 0;
+	struct compat_epoll_event user;
+	struct epoll_event __user *kernel = NULL;
+
+	if (event) {
+		if (copy_from_user(&user, event, sizeof(user)))
+			return -EFAULT;
+		kernel = compat_alloc_user_space(sizeof(struct epoll_event));
+		err |= __put_user(user.events, &kernel->events);
+		err |= __put_user(user.data, &kernel->data);
+	}
+
+	return err ? err : sys_epoll_ctl(epfd, op, fd, kernel);
+}
+
+
+asmlinkage long compat_sys_epoll_wait(int epfd,
+			struct compat_epoll_event __user *events,
+			int maxevents, int timeout)
+{
+	long i, ret, err = 0;
+	struct epoll_event __user *kbuf;
+	struct epoll_event ev;
+
+	if ((maxevents <= 0) ||
+			(maxevents > (INT_MAX / sizeof(struct epoll_event))))
+		return -EINVAL;
+	kbuf = compat_alloc_user_space(sizeof(struct epoll_event) * maxevents);
+	ret = sys_epoll_wait(epfd, kbuf, maxevents, timeout);
+	for (i = 0; i < ret; i++) {
+		err |= __get_user(ev.events, &kbuf[i].events);
+		err |= __get_user(ev.data, &kbuf[i].data);
+		err |= __put_user(ev.events, &events->events);
+		err |= __put_user_unaligned(ev.data, &events->data);
+		events++;
+	}
+
+	return err ? -EFAULT: ret;
+}
+#endif	/* CONFIG_HAS_COMPAT_EPOLL_EVENT */
+
+#ifdef TIF_RESTORE_SIGMASK
+asmlinkage long compat_sys_epoll_pwait(int epfd,
+			struct compat_epoll_event __user *events,
+			int maxevents, int timeout,
+			const compat_sigset_t __user *sigmask,
+			compat_size_t sigsetsize)
+{
+	long err;
+	compat_sigset_t csigmask;
+	sigset_t ksigmask, sigsaved;
+
+	/*
+	 * If the caller wants a certain signal mask to be set during the wait,
+	 * we apply it here.
+	 */
+	if (sigmask) {
+		if (sigsetsize != sizeof(compat_sigset_t))
+			return -EINVAL;
+		if (copy_from_user(&csigmask, sigmask, sizeof(csigmask)))
+			return -EFAULT;
+		sigset_from_compat(&ksigmask, &csigmask);
+		sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
+		sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
+	}
+
+#ifdef CONFIG_HAS_COMPAT_EPOLL_EVENT
+	err = compat_sys_epoll_wait(epfd, events, maxevents, timeout);
+#else
+	err = sys_epoll_wait(epfd, events, maxevents, timeout);
+#endif
+
+	/*
+	 * If we changed the signal mask, we need to restore the original one.
+	 * In case we've got a signal while waiting, we do not restore the
+	 * signal mask yet, and we allow do_signal() to deliver the signal on
+	 * the way back to userspace, before the signal mask is restored.
+	 */
+	if (sigmask) {
+		if (err == -EINTR) {
+			memcpy(&current->saved_sigmask, &sigsaved,
+			       sizeof(sigsaved));
+			set_thread_flag(TIF_RESTORE_SIGMASK);
+		} else
+			sigprocmask(SIG_SETMASK, &sigsaved, NULL);
+	}
+
+	return err;
+}
+#endif /* TIF_RESTORE_SIGMASK */
+
+#endif /* CONFIG_EPOLL */
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index c81c958..8b1c5d8 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -2553,11 +2553,15 @@
 HANDLE_IOCTL(I2C_SMBUS, do_i2c_smbus_ioctl)
 /* wireless */
 HANDLE_IOCTL(SIOCGIWRANGE, do_wireless_ioctl)
+HANDLE_IOCTL(SIOCGIWPRIV, do_wireless_ioctl)
+HANDLE_IOCTL(SIOCGIWSTATS, do_wireless_ioctl)
 HANDLE_IOCTL(SIOCSIWSPY, do_wireless_ioctl)
 HANDLE_IOCTL(SIOCGIWSPY, do_wireless_ioctl)
 HANDLE_IOCTL(SIOCSIWTHRSPY, do_wireless_ioctl)
 HANDLE_IOCTL(SIOCGIWTHRSPY, do_wireless_ioctl)
+HANDLE_IOCTL(SIOCSIWMLME, do_wireless_ioctl)
 HANDLE_IOCTL(SIOCGIWAPLIST, do_wireless_ioctl)
+HANDLE_IOCTL(SIOCSIWSCAN, do_wireless_ioctl)
 HANDLE_IOCTL(SIOCGIWSCAN, do_wireless_ioctl)
 HANDLE_IOCTL(SIOCSIWESSID, do_wireless_ioctl)
 HANDLE_IOCTL(SIOCGIWESSID, do_wireless_ioctl)
@@ -2565,6 +2569,11 @@
 HANDLE_IOCTL(SIOCGIWNICKN, do_wireless_ioctl)
 HANDLE_IOCTL(SIOCSIWENCODE, do_wireless_ioctl)
 HANDLE_IOCTL(SIOCGIWENCODE, do_wireless_ioctl)
+HANDLE_IOCTL(SIOCSIWGENIE, do_wireless_ioctl)
+HANDLE_IOCTL(SIOCGIWGENIE, do_wireless_ioctl)
+HANDLE_IOCTL(SIOCSIWENCODEEXT, do_wireless_ioctl)
+HANDLE_IOCTL(SIOCGIWENCODEEXT, do_wireless_ioctl)
+HANDLE_IOCTL(SIOCSIWPMKSA, do_wireless_ioctl)
 HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl)
 HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl)
 HANDLE_IOCTL(RTC_IRQP_READ32, rtc_ioctl)
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index 34750d5..5e6e37e 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -1141,25 +1141,22 @@
 
 	err = -ENOMEM;
 	dentry = d_alloc(configfs_sb->s_root, &name);
-	if (!dentry)
-		goto out_release;
+	if (dentry) {
+		d_add(dentry, NULL);
 
-	d_add(dentry, NULL);
-
-	err = configfs_attach_group(sd->s_element, &group->cg_item,
-				    dentry);
-	if (!err)
-		dentry = NULL;
-	else
-		d_delete(dentry);
+		err = configfs_attach_group(sd->s_element, &group->cg_item,
+					    dentry);
+		if (err) {
+			d_delete(dentry);
+			dput(dentry);
+		}
+	}
 
 	mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex);
 
-	if (dentry) {
-	    dput(dentry);
-out_release:
-	    unlink_group(group);
-	    configfs_release_fs();
+	if (err) {
+		unlink_group(group);
+		configfs_release_fs();
 	}
 
 	return err;
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index 40db61d..3870150 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -22,6 +22,7 @@
 #include "lockspace.h"
 #include "lock.h"
 #include "lvb_table.h"
+#include "user.h"
 
 static const char *name_prefix="dlm";
 static struct miscdevice ctl_device;
diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c
index 329efcd..cb20b96 100644
--- a/fs/ecryptfs/dentry.c
+++ b/fs/ecryptfs/dentry.c
@@ -78,18 +78,13 @@
  */
 static void ecryptfs_d_release(struct dentry *dentry)
 {
-	struct dentry *lower_dentry;
-
-	lower_dentry = ecryptfs_dentry_to_lower(dentry);
-	if (ecryptfs_dentry_to_private(dentry))
+	if (ecryptfs_dentry_to_private(dentry)) {
+		if (ecryptfs_dentry_to_lower(dentry)) {
+			mntput(ecryptfs_dentry_to_lower_mnt(dentry));
+			dput(ecryptfs_dentry_to_lower(dentry));
+		}
 		kmem_cache_free(ecryptfs_dentry_info_cache,
 				ecryptfs_dentry_to_private(dentry));
-	if (lower_dentry) {
-		struct vfsmount *lower_mnt =
-			ecryptfs_dentry_to_lower_mnt(dentry);
-
-		mntput(lower_mnt);
-		dput(lower_dentry);
 	}
 	return;
 }
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index e62f3fc..1548be2 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -38,7 +38,7 @@
 	struct dentry *dir;
 
 	dir = dget(dentry->d_parent);
-	mutex_lock(&(dir->d_inode->i_mutex));
+	mutex_lock_nested(&(dir->d_inode->i_mutex), I_MUTEX_PARENT);
 	return dir;
 }
 
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 8a824f4..a5b150f 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1148,102 +1148,37 @@
 	return ext3_journal_get_write_access(handle, bh);
 }
 
-/*
- * The idea of this helper function is following:
- * if prepare_write has allocated some blocks, but not all of them, the
- * transaction must include the content of the newly allocated blocks.
- * This content is expected to be set to zeroes by block_prepare_write().
- * 2006/10/14  SAW
- */
-static int ext3_prepare_failure(struct file *file, struct page *page,
-				unsigned from, unsigned to)
-{
-	struct address_space *mapping;
-	struct buffer_head *bh, *head, *next;
-	unsigned block_start, block_end;
-	unsigned blocksize;
-	int ret;
-	handle_t *handle = ext3_journal_current_handle();
-
-	mapping = page->mapping;
-	if (ext3_should_writeback_data(mapping->host)) {
-		/* optimization: no constraints about data */
-skip:
-		return ext3_journal_stop(handle);
-	}
-
-	head = page_buffers(page);
-	blocksize = head->b_size;
-	for (	bh = head, block_start = 0;
-		bh != head || !block_start;
-	    	block_start = block_end, bh = next)
-	{
-		next = bh->b_this_page;
-		block_end = block_start + blocksize;
-		if (block_end <= from)
-			continue;
-		if (block_start >= to) {
-			block_start = to;
-			break;
-		}
-		if (!buffer_mapped(bh))
-		/* prepare_write failed on this bh */
-			break;
-		if (ext3_should_journal_data(mapping->host)) {
-			ret = do_journal_get_write_access(handle, bh);
-			if (ret) {
-				ext3_journal_stop(handle);
-				return ret;
-			}
-		}
-	/*
-	 * block_start here becomes the first block where the current iteration
-	 * of prepare_write failed.
-	 */
-	}
-	if (block_start <= from)
-		goto skip;
-
-	/* commit allocated and zeroed buffers */
-	return mapping->a_ops->commit_write(file, page, from, block_start);
-}
-
 static int ext3_prepare_write(struct file *file, struct page *page,
 			      unsigned from, unsigned to)
 {
 	struct inode *inode = page->mapping->host;
-	int ret, ret2;
-	int needed_blocks = ext3_writepage_trans_blocks(inode);
+	int ret, needed_blocks = ext3_writepage_trans_blocks(inode);
 	handle_t *handle;
 	int retries = 0;
 
 retry:
 	handle = ext3_journal_start(inode, needed_blocks);
-	if (IS_ERR(handle))
-		return PTR_ERR(handle);
+	if (IS_ERR(handle)) {
+		ret = PTR_ERR(handle);
+		goto out;
+	}
 	if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode))
 		ret = nobh_prepare_write(page, from, to, ext3_get_block);
 	else
 		ret = block_prepare_write(page, from, to, ext3_get_block);
 	if (ret)
-		goto failure;
+		goto prepare_write_failed;
 
 	if (ext3_should_journal_data(inode)) {
 		ret = walk_page_buffers(handle, page_buffers(page),
 				from, to, NULL, do_journal_get_write_access);
-		if (ret)
-			/* fatal error, just put the handle and return */
-			journal_stop(handle);
 	}
-	return ret;
-
-failure:
-	ret2 = ext3_prepare_failure(file, page, from, to);
-	if (ret2 < 0)
-		return ret2;
+prepare_write_failed:
+	if (ret)
+		ext3_journal_stop(handle);
 	if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries))
 		goto retry;
-	/* retry number exceeded, or other error like -EDQUOT */
+out:
 	return ret;
 }
 
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index 12f7dda..f58cbb2 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -495,7 +495,8 @@
 		BHDR(bh)->h_refcount = cpu_to_le32(
 				le32_to_cpu(BHDR(bh)->h_refcount) - 1);
 		error = ext3_journal_dirty_metadata(handle, bh);
-		handle->h_sync = 1;
+		if (IS_SYNC(inode))
+			handle->h_sync = 1;
 		DQUOT_FREE_BLOCK(inode, 1);
 		ea_bdebug(bh, "refcount now=%d; releasing",
 			  le32_to_cpu(BHDR(bh)->h_refcount));
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index fbff4b9..810b6d6 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1147,102 +1147,37 @@
 	return ext4_journal_get_write_access(handle, bh);
 }
 
-/*
- * The idea of this helper function is following:
- * if prepare_write has allocated some blocks, but not all of them, the
- * transaction must include the content of the newly allocated blocks.
- * This content is expected to be set to zeroes by block_prepare_write().
- * 2006/10/14  SAW
- */
-static int ext4_prepare_failure(struct file *file, struct page *page,
-				unsigned from, unsigned to)
-{
-	struct address_space *mapping;
-	struct buffer_head *bh, *head, *next;
-	unsigned block_start, block_end;
-	unsigned blocksize;
-	int ret;
-	handle_t *handle = ext4_journal_current_handle();
-
-	mapping = page->mapping;
-	if (ext4_should_writeback_data(mapping->host)) {
-		/* optimization: no constraints about data */
-skip:
-		return ext4_journal_stop(handle);
-	}
-
-	head = page_buffers(page);
-	blocksize = head->b_size;
-	for (	bh = head, block_start = 0;
-		bh != head || !block_start;
-	    	block_start = block_end, bh = next)
-	{
-		next = bh->b_this_page;
-		block_end = block_start + blocksize;
-		if (block_end <= from)
-			continue;
-		if (block_start >= to) {
-			block_start = to;
-			break;
-		}
-		if (!buffer_mapped(bh))
-		/* prepare_write failed on this bh */
-			break;
-		if (ext4_should_journal_data(mapping->host)) {
-			ret = do_journal_get_write_access(handle, bh);
-			if (ret) {
-				ext4_journal_stop(handle);
-				return ret;
-			}
-		}
-	/*
-	 * block_start here becomes the first block where the current iteration
-	 * of prepare_write failed.
-	 */
-	}
-	if (block_start <= from)
-		goto skip;
-
-	/* commit allocated and zeroed buffers */
-	return mapping->a_ops->commit_write(file, page, from, block_start);
-}
-
 static int ext4_prepare_write(struct file *file, struct page *page,
 			      unsigned from, unsigned to)
 {
 	struct inode *inode = page->mapping->host;
-	int ret, ret2;
-	int needed_blocks = ext4_writepage_trans_blocks(inode);
+	int ret, needed_blocks = ext4_writepage_trans_blocks(inode);
 	handle_t *handle;
 	int retries = 0;
 
 retry:
 	handle = ext4_journal_start(inode, needed_blocks);
-	if (IS_ERR(handle))
-		return PTR_ERR(handle);
+	if (IS_ERR(handle)) {
+		ret = PTR_ERR(handle);
+		goto out;
+	}
 	if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode))
 		ret = nobh_prepare_write(page, from, to, ext4_get_block);
 	else
 		ret = block_prepare_write(page, from, to, ext4_get_block);
 	if (ret)
-		goto failure;
+		goto prepare_write_failed;
 
 	if (ext4_should_journal_data(inode)) {
 		ret = walk_page_buffers(handle, page_buffers(page),
 				from, to, NULL, do_journal_get_write_access);
-		if (ret)
-			/* fatal error, just put the handle and return */
-			ext4_journal_stop(handle);
 	}
-	return ret;
-
-failure:
-	ret2 = ext4_prepare_failure(file, page, from, to);
-	if (ret2 < 0)
-		return ret2;
+prepare_write_failed:
+	if (ret)
+		ext4_journal_stop(handle);
 	if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
 		goto retry;
-	/* retry number exceeded, or other error like -EDQUOT */
+out:
 	return ret;
 }
 
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 406bf61..8890eba 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -195,7 +195,7 @@
 	.d_revalidate	= fuse_dentry_revalidate,
 };
 
-static int valid_mode(int m)
+int fuse_valid_type(int m)
 {
 	return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
 		S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
@@ -248,7 +248,8 @@
 	fuse_put_request(fc, req);
 	/* Zero nodeid is same as -ENOENT, but with valid timeout */
 	if (!err && outarg.nodeid &&
-	    (invalid_nodeid(outarg.nodeid) || !valid_mode(outarg.attr.mode)))
+	    (invalid_nodeid(outarg.nodeid) ||
+	     !fuse_valid_type(outarg.attr.mode)))
 		err = -EIO;
 	if (!err && outarg.nodeid) {
 		inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index b98b20d..68ae87c 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -552,3 +552,8 @@
  * Remove connection from control filesystem
  */
 void fuse_ctl_remove_conn(struct fuse_conn *fc);
+
+/**
+ * Is file type valid?
+ */
+int fuse_valid_type(int m);
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 5ab8e50..608db81 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -330,6 +330,8 @@
 		case OPT_ROOTMODE:
 			if (match_octal(&args[0], &value))
 				return 0;
+			if (!fuse_valid_type(value))
+				return 0;
 			d->rootmode = value;
 			d->rootmode_present = 1;
 			break;
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 6618c11..12accb0 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -20,6 +20,7 @@
 #include <linux/list.h>
 #include <linux/lm_interface.h>
 #include <linux/wait.h>
+#include <linux/module.h>
 #include <linux/rwsem.h>
 #include <asm/uaccess.h>
 
@@ -953,9 +954,6 @@
 		spin_unlock(&gl->gl_spin);
 	}
 
-	if (glops->go_drop_bh)
-		glops->go_drop_bh(gl);
-
 	spin_lock(&gl->gl_spin);
 	gl->gl_req_gh = NULL;
 	gl->gl_req_bh = NULL;
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 46af553..39c8ae2 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -245,7 +245,6 @@
 
 	if (ip && S_ISREG(ip->i_inode.i_mode)) {
 		truncate_inode_pages(ip->i_inode.i_mapping, 0);
-		gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), !ip->i_inode.i_mapping->nrpages);
 		clear_bit(GIF_PAGED, &ip->i_flags);
 	}
 }
@@ -459,6 +458,8 @@
 };
 
 const struct gfs2_glock_operations gfs2_rgrp_glops = {
+	.go_xmote_th = meta_go_sync,
+	.go_drop_th = meta_go_sync,
 	.go_inval = meta_go_inval,
 	.go_demote_ok = rgrp_go_demote_ok,
 	.go_lock = rgrp_go_lock,
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 12c80fd..49f0dbf 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -104,7 +104,6 @@
 	void (*go_xmote_th) (struct gfs2_glock *gl);
 	void (*go_xmote_bh) (struct gfs2_glock *gl);
 	void (*go_drop_th) (struct gfs2_glock *gl);
-	void (*go_drop_bh) (struct gfs2_glock *gl);
 	void (*go_inval) (struct gfs2_glock *gl, int flags);
 	int (*go_demote_ok) (struct gfs2_glock *gl);
 	int (*go_lock) (struct gfs2_holder *gh);
@@ -416,7 +415,6 @@
 	unsigned int gt_stall_secs; /* Detects trouble! */
 	unsigned int gt_complain_secs;
 	unsigned int gt_reclaim_limit; /* Max num of glocks in reclaim list */
-	unsigned int gt_entries_per_readdir;
 	unsigned int gt_statfs_quantum;
 	unsigned int gt_statfs_slow;
 };
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 0d6831a..df0b8b3 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -43,7 +43,8 @@
 	struct gfs2_inode *ip = GFS2_I(inode);
 	struct gfs2_inum_host *inum = opaque;
 
-	if (ip->i_num.no_addr == inum->no_addr)
+	if (ip->i_num.no_addr == inum->no_addr &&
+	    inode->i_private != NULL)
 		return 1;
 
 	return 0;
@@ -61,13 +62,13 @@
 
 struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum)
 {
-	return ilookup5(sb, (unsigned long)inum->no_formal_ino,
+	return ilookup5(sb, (unsigned long)inum->no_addr,
 			iget_test, inum);
 }
 
 static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum_host *inum)
 {
-	return iget5_locked(sb, (unsigned long)inum->no_formal_ino,
+	return iget5_locked(sb, (unsigned long)inum->no_addr,
 		     iget_test, iget_set, inum);
 }
 
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 56e3359..b3b7e84 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -266,9 +266,11 @@
 out:
 	return error;
 out_unlock:
-	if (error == GLR_TRYFAILED)
-		error = AOP_TRUNCATED_PAGE;
 	unlock_page(page);
+	if (error == GLR_TRYFAILED) {
+		error = AOP_TRUNCATED_PAGE;
+		yield();
+	}
 	if (do_unlock)
 		gfs2_holder_uninit(&gh);
 	goto out;
@@ -364,6 +366,7 @@
 		if (error == GLR_TRYFAILED) {
 			unlock_page(page);
 			error = AOP_TRUNCATED_PAGE;
+			yield();
 		}
 		goto out_uninit;
 	}
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c
index 1de05b6..aad9183 100644
--- a/fs/gfs2/ops_export.c
+++ b/fs/gfs2/ops_export.c
@@ -38,14 +38,11 @@
 	struct gfs2_fh_obj fh_obj;
 	struct gfs2_inum_host *this, parent;
 
-	if (fh_type != fh_len)
-		return NULL;
-
 	this 		= &fh_obj.this;
 	fh_obj.imode 	= DT_UNKNOWN;
 	memset(&parent, 0, sizeof(struct gfs2_inum));
 
-	switch (fh_type) {
+	switch (fh_len) {
 	case GFS2_LARGE_FH_SIZE:
 		parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32;
 		parent.no_formal_ino |= be32_to_cpu(fh[5]);
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index ee80b8a..ee54cb6 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -840,7 +840,7 @@
 	}
 
 	printk(KERN_WARNING "GFS2: Unrecognized block device or "
-	       "mount point %s", dev_name);
+	       "mount point %s\n", dev_name);
 
 free_nd:
 	path_release(&nd);
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index d0db881..c186857 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -279,7 +279,7 @@
 		(bh->b_data + sizeof(struct gfs2_meta_header) +
 		 offset * sizeof(struct gfs2_quota_change));
 
-	mutex_lock(&sdp->sd_quota_mutex);
+	mutex_unlock(&sdp->sd_quota_mutex);
 
 	return 0;
 
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 70f424f..4fdda97 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -76,7 +76,6 @@
 	gt->gt_stall_secs = 600;
 	gt->gt_complain_secs = 10;
 	gt->gt_reclaim_limit = 5000;
-	gt->gt_entries_per_readdir = 32;
 	gt->gt_statfs_quantum = 30;
 	gt->gt_statfs_slow = 0;
 }
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index e965eb1..fd301a9 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -20,7 +20,6 @@
 #include "hostfs.h"
 #include "kern_util.h"
 #include "kern.h"
-#include "user_util.h"
 #include "init.h"
 
 struct hostfs_inode_info {
@@ -47,7 +46,7 @@
 };
 
 /* Changed in hostfs_args before the kernel starts running */
-static char *root_ino = "/";
+static char *root_ino = "";
 static int append = 0;
 
 #define HOSTFS_SUPER_MAGIC 0x00c0ffee
@@ -939,7 +938,7 @@
 static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
 {
 	struct inode *root_inode;
-	char *name, *data = d;
+	char *host_root_path, *req_root = d;
 	int err;
 
 	sb->s_blocksize = 1024;
@@ -947,15 +946,17 @@
 	sb->s_magic = HOSTFS_SUPER_MAGIC;
 	sb->s_op = &hostfs_sbops;
 
-	if((data == NULL) || (*data == '\0'))
-		data = root_ino;
+	/* NULL is printed as <NULL> by sprintf: avoid that. */
+	if (req_root == NULL)
+		req_root = "";
 
 	err = -ENOMEM;
-	name = kmalloc(strlen(data) + 1, GFP_KERNEL);
-	if(name == NULL)
+	host_root_path = kmalloc(strlen(root_ino) + 1
+				 + strlen(req_root) + 1, GFP_KERNEL);
+	if(host_root_path == NULL)
 		goto out;
 
-	strcpy(name, data);
+	sprintf(host_root_path, "%s/%s", root_ino, req_root);
 
 	root_inode = iget(sb, 0);
 	if(root_inode == NULL)
@@ -965,7 +966,10 @@
 	if(err)
 		goto out_put;
 
-	HOSTFS_I(root_inode)->host_filename = name;
+	HOSTFS_I(root_inode)->host_filename = host_root_path;
+	/* Avoid that in the error path, iput(root_inode) frees again
+	 * host_root_path through hostfs_destroy_inode! */
+	host_root_path = NULL;
 
 	err = -ENOMEM;
 	sb->s_root = d_alloc_root(root_inode);
@@ -977,7 +981,7 @@
                 /* No iput in this case because the dput does that for us */
                 dput(sb->s_root);
                 sb->s_root = NULL;
-		goto out_free;
+		goto out;
         }
 
 	return(0);
@@ -985,7 +989,7 @@
  out_put:
         iput(root_inode);
  out_free:
-	kfree(name);
+	kfree(host_root_path);
  out:
 	return(err);
 }
diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c
index 6eb3dae..888f236 100644
--- a/fs/jffs2/background.c
+++ b/fs/jffs2/background.c
@@ -99,7 +99,13 @@
 		if (try_to_freeze())
 			continue;
 
-		cond_resched();
+		/* This thread is purely an optimisation. But if it runs when
+		   other things could be running, it actually makes things a
+		   lot worse. Use yield() and put it at the back of the runqueue
+		   every time. Especially during boot, pulling an inode in
+		   with read_inode() is much preferable to having the GC thread
+		   get there first. */
+		yield();
 
 		/* Put_super will send a SIGKILL and then wait on the sem.
 		 */
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index 58a0b91..717a48c 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -373,7 +373,14 @@
 static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, struct jffs2_unknown_node *un)
 {
 	/* We don't mark unknown nodes as REF_UNCHECKED */
-	BUG_ON(ref_flags(ref) == REF_UNCHECKED);
+	if (ref_flags(ref) == REF_UNCHECKED) {
+		JFFS2_ERROR("REF_UNCHECKED but unknown node at %#08x\n",
+			    ref_offset(ref));
+		JFFS2_ERROR("Node is {%04x,%04x,%08x,%08x}. Please report this error.\n",
+                            je16_to_cpu(un->magic), je16_to_cpu(un->nodetype),
+                            je32_to_cpu(un->totlen), je32_to_cpu(un->hdr_crc));
+		return 1;
+	}
 
 	un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype));
 
@@ -576,6 +583,13 @@
 			jffs2_mark_node_obsolete(c, ref);
 			goto cont;
 		}
+		/* Due to poor choice of crc32 seed, an all-zero node will have a correct CRC */
+		if (!je32_to_cpu(node->u.hdr_crc) && !je16_to_cpu(node->u.nodetype) &&
+		    !je16_to_cpu(node->u.magic) && !je32_to_cpu(node->u.totlen)) {
+			JFFS2_NOTICE("All zero node header at %#08x.\n", ref_offset(ref));
+			jffs2_mark_node_obsolete(c, ref);
+			goto cont;
+		}
 
 		switch (je16_to_cpu(node->u.nodetype)) {
 
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index 31c1475..7fb45bd4 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -734,6 +734,15 @@
 			ofs += 4;
 			continue;
 		}
+		/* Due to poor choice of crc32 seed, an all-zero node will have a correct CRC */
+		if (!je32_to_cpu(node->hdr_crc) && !je16_to_cpu(node->nodetype) &&
+		    !je16_to_cpu(node->magic) && !je32_to_cpu(node->totlen)) {
+			noisy_printk(&noise, "jffs2_scan_eraseblock(): All zero node header at 0x%08x.\n", ofs);
+			if ((err = jffs2_scan_dirty_space(c, jeb, 4)))
+				return err;
+			ofs += 4;
+			continue;
+		}
 
 		if (ofs + je32_to_cpu(node->totlen) >
 		    jeb->offset + c->sector_size) {
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index de718e3..4fac6dd 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -238,7 +238,10 @@
 	jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
 
 	spin_lock(&c->erase_completion_lock);
-	jffs2_block_refile(c, jeb, REFILE_NOTEMPTY);
+	if (c->wbuf_ofs % c->mtd->erasesize)
+		jffs2_block_refile(c, jeb, REFILE_NOTEMPTY);
+	else
+		jffs2_block_refile(c, jeb, REFILE_ANYWAY);
 	spin_unlock(&c->erase_completion_lock);
 
 	BUG_ON(!ref_obsolete(jeb->last_node));
@@ -1087,7 +1090,7 @@
 	if (!c->mtd->block_markbad)
 		return 1; // What else can we do?
 
-	D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Marking bad block at %08x\n", bad_offset));
+	printk(KERN_WARNING "JFFS2: marking eraseblock at %08x\n as bad", bad_offset);
 	ret = c->mtd->block_markbad(c->mtd, bad_offset);
 
 	if (ret) {
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index af53c02..93d046c 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -429,7 +429,8 @@
 	int err;
 
 	/* Flush out writes to the server in order to update c/mtime */
-	nfs_sync_mapping_range(inode->i_mapping, 0, 0, FLUSH_NOCOMMIT);
+	if (S_ISREG(inode->i_mode))
+		nfs_sync_mapping_range(inode->i_mapping, 0, 0, FLUSH_NOCOMMIT);
 
 	/*
 	 * We may force a getattr if the user cares about atime.
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index bb516a2..f1eae44 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -151,10 +151,10 @@
 	if (ret < 0)
 		goto error_0;
 
-#ifdef CONFIG_NFS_V4
 	ret = nfs_register_sysctl();
 	if (ret < 0)
 		goto error_1;
+#ifdef CONFIG_NFS_V4
 	ret = register_filesystem(&nfs4_fs_type);
 	if (ret < 0)
 		goto error_2;
@@ -165,9 +165,9 @@
 #ifdef CONFIG_NFS_V4
 error_2:
 	nfs_unregister_sysctl();
+#endif
 error_1:
 	unregister_filesystem(&nfs_fs_type);
-#endif
 error_0:
 	return ret;
 }
diff --git a/fs/nfs/sysctl.c b/fs/nfs/sysctl.c
index fcdcafb..b62481da 100644
--- a/fs/nfs/sysctl.c
+++ b/fs/nfs/sysctl.c
@@ -50,6 +50,14 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 		.strategy	= &sysctl_jiffies,
 	},
+	{
+		.ctl_name	= CTL_UNNUMBERED,
+		.procname	= "nfs_congestion_kb",
+		.data		= &nfs_congestion_kb,
+		.maxlen		= sizeof(nfs_congestion_kb),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
 	{ .ctl_name = 0 }
 };
 
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index febdade..2867e6b 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -12,6 +12,7 @@
 #include <linux/pagemap.h>
 #include <linux/file.h>
 #include <linux/writeback.h>
+#include <linux/swap.h>
 
 #include <linux/sunrpc/clnt.h>
 #include <linux/nfs_fs.h>
@@ -38,7 +39,6 @@
 					    struct page *,
 					    unsigned int, unsigned int);
 static void nfs_mark_request_dirty(struct nfs_page *req);
-static int nfs_wait_on_write_congestion(struct address_space *, int);
 static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how);
 static const struct rpc_call_ops nfs_write_partial_ops;
 static const struct rpc_call_ops nfs_write_full_ops;
@@ -48,8 +48,6 @@
 static mempool_t *nfs_wdata_mempool;
 static mempool_t *nfs_commit_mempool;
 
-static DECLARE_WAIT_QUEUE_HEAD(nfs_write_congestion);
-
 struct nfs_write_data *nfs_commit_alloc(void)
 {
 	struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, GFP_NOFS);
@@ -211,6 +209,40 @@
 }
 
 /*
+ * NFS congestion control
+ */
+
+int nfs_congestion_kb;
+
+#define NFS_CONGESTION_ON_THRESH 	(nfs_congestion_kb >> (PAGE_SHIFT-10))
+#define NFS_CONGESTION_OFF_THRESH	\
+	(NFS_CONGESTION_ON_THRESH - (NFS_CONGESTION_ON_THRESH >> 2))
+
+static void nfs_set_page_writeback(struct page *page)
+{
+	if (!test_set_page_writeback(page)) {
+		struct inode *inode = page->mapping->host;
+		struct nfs_server *nfss = NFS_SERVER(inode);
+
+		if (atomic_inc_return(&nfss->writeback) >
+				NFS_CONGESTION_ON_THRESH)
+			set_bdi_congested(&nfss->backing_dev_info, WRITE);
+	}
+}
+
+static void nfs_end_page_writeback(struct page *page)
+{
+	struct inode *inode = page->mapping->host;
+	struct nfs_server *nfss = NFS_SERVER(inode);
+
+	end_page_writeback(page);
+	if (atomic_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH) {
+		clear_bdi_congested(&nfss->backing_dev_info, WRITE);
+		congestion_end(WRITE);
+	}
+}
+
+/*
  * Find an associated nfs write request, and prepare to flush it out
  * Returns 1 if there was no write request, or if the request was
  * already tagged by nfs_set_page_dirty.Returns 0 if the request
@@ -247,7 +279,7 @@
 	spin_unlock(req_lock);
 	if (test_and_set_bit(PG_FLUSHING, &req->wb_flags) == 0) {
 		nfs_mark_request_dirty(req);
-		set_page_writeback(page);
+		nfs_set_page_writeback(page);
 	}
 	ret = test_bit(PG_NEED_FLUSH, &req->wb_flags);
 	nfs_unlock_request(req);
@@ -302,13 +334,8 @@
 	return err; 
 }
 
-/*
- * Note: causes nfs_update_request() to block on the assumption
- * 	 that the writeback is generated due to memory pressure.
- */
 int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
 {
-	struct backing_dev_info *bdi = mapping->backing_dev_info;
 	struct inode *inode = mapping->host;
 	int err;
 
@@ -317,20 +344,12 @@
 	err = generic_writepages(mapping, wbc);
 	if (err)
 		return err;
-	while (test_and_set_bit(BDI_write_congested, &bdi->state) != 0) {
-		if (wbc->nonblocking)
-			return 0;
-		nfs_wait_on_write_congestion(mapping, 0);
-	}
 	err = nfs_flush_mapping(mapping, wbc, wb_priority(wbc));
 	if (err < 0)
 		goto out;
 	nfs_add_stats(inode, NFSIOS_WRITEPAGES, err);
 	err = 0;
 out:
-	clear_bit(BDI_write_congested, &bdi->state);
-	wake_up_all(&nfs_write_congestion);
-	congestion_end(WRITE);
 	return err;
 }
 
@@ -360,7 +379,7 @@
 }
 
 /*
- * Insert a write request into an inode
+ * Remove a write request from an inode
  */
 static void nfs_inode_remove_request(struct nfs_page *req)
 {
@@ -531,10 +550,10 @@
 }
 #endif
 
-static int nfs_wait_on_write_congestion(struct address_space *mapping, int intr)
+static int nfs_wait_on_write_congestion(struct address_space *mapping)
 {
+	struct inode *inode = mapping->host;
 	struct backing_dev_info *bdi = mapping->backing_dev_info;
-	DEFINE_WAIT(wait);
 	int ret = 0;
 
 	might_sleep();
@@ -542,31 +561,23 @@
 	if (!bdi_write_congested(bdi))
 		return 0;
 
-	nfs_inc_stats(mapping->host, NFSIOS_CONGESTIONWAIT);
+	nfs_inc_stats(inode, NFSIOS_CONGESTIONWAIT);
 
-	if (intr) {
-		struct rpc_clnt *clnt = NFS_CLIENT(mapping->host);
+	do {
+		struct rpc_clnt *clnt = NFS_CLIENT(inode);
 		sigset_t oldset;
 
 		rpc_clnt_sigmask(clnt, &oldset);
-		prepare_to_wait(&nfs_write_congestion, &wait, TASK_INTERRUPTIBLE);
-		if (bdi_write_congested(bdi)) {
-			if (signalled())
-				ret = -ERESTARTSYS;
-			else
-				schedule();
-		}
+		ret = congestion_wait_interruptible(WRITE, HZ/10);
 		rpc_clnt_sigunmask(clnt, &oldset);
-	} else {
-		prepare_to_wait(&nfs_write_congestion, &wait, TASK_UNINTERRUPTIBLE);
-		if (bdi_write_congested(bdi))
-			schedule();
-	}
-	finish_wait(&nfs_write_congestion, &wait);
+		if (ret == -ERESTARTSYS)
+			break;
+		ret = 0;
+	} while (bdi_write_congested(bdi));
+
 	return ret;
 }
 
-
 /*
  * Try to update any existing write request, or create one if there is none.
  * In order to match, the request's credentials must match those of
@@ -577,14 +588,15 @@
 static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,
 		struct page *page, unsigned int offset, unsigned int bytes)
 {
-	struct inode *inode = page->mapping->host;
+	struct address_space *mapping = page->mapping;
+	struct inode *inode = mapping->host;
 	struct nfs_inode *nfsi = NFS_I(inode);
 	struct nfs_page		*req, *new = NULL;
 	unsigned long		rqend, end;
 
 	end = offset + bytes;
 
-	if (nfs_wait_on_write_congestion(page->mapping, NFS_SERVER(inode)->flags & NFS_MOUNT_INTR))
+	if (nfs_wait_on_write_congestion(mapping))
 		return ERR_PTR(-ERESTARTSYS);
 	for (;;) {
 		/* Loop over all inode entries and see if we find
@@ -727,7 +739,7 @@
 
 static void nfs_writepage_release(struct nfs_page *req)
 {
-	end_page_writeback(req->wb_page);
+	nfs_end_page_writeback(req->wb_page);
 
 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
 	if (!PageError(req->wb_page)) {
@@ -1042,12 +1054,12 @@
 		if (task->tk_status < 0) {
 			nfs_set_pageerror(page);
 			req->wb_context->error = task->tk_status;
-			end_page_writeback(page);
+			nfs_end_page_writeback(page);
 			nfs_inode_remove_request(req);
 			dprintk(", error = %d\n", task->tk_status);
 			goto next;
 		}
-		end_page_writeback(page);
+		nfs_end_page_writeback(page);
 
 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
 		if (data->args.stable != NFS_UNSTABLE || data->verf.committed == NFS_FILE_SYNC) {
@@ -1514,6 +1526,26 @@
 	if (nfs_commit_mempool == NULL)
 		return -ENOMEM;
 
+	/*
+	 * NFS congestion size, scale with available memory.
+	 *
+	 *  64MB:    8192k
+	 * 128MB:   11585k
+	 * 256MB:   16384k
+	 * 512MB:   23170k
+	 *   1GB:   32768k
+	 *   2GB:   46340k
+	 *   4GB:   65536k
+	 *   8GB:   92681k
+	 *  16GB:  131072k
+	 *
+	 * This allows larger machines to have larger/more transfers.
+	 * Limit the default to 256M
+	 */
+	nfs_congestion_kb = (16*int_sqrt(totalram_pages)) << (PAGE_SHIFT-10);
+	if (nfs_congestion_kb > 256*1024)
+		nfs_congestion_kb = 256*1024;
+
 	return 0;
 }
 
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 6f67798..7e4bb0a 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -859,8 +859,8 @@
 #define NFS3_ENTRY_BAGGAGE	(2 + 1 + 2 + 1)
 #define NFS3_ENTRYPLUS_BAGGAGE	(1 + 21 + 1 + (NFS3_FHSIZE >> 2))
 static int
-encode_entry(struct readdir_cd *ccd, const char *name,
-	     int namlen, off_t offset, ino_t ino, unsigned int d_type, int plus)
+encode_entry(struct readdir_cd *ccd, const char *name, int namlen,
+	     loff_t offset, ino_t ino, unsigned int d_type, int plus)
 {
 	struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres,
 		       					common);
@@ -880,7 +880,7 @@
 			*cd->offset1 = htonl(offset64 & 0xffffffff);
 			cd->offset1 = NULL;
 		} else {
-			xdr_encode_hyper(cd->offset, (u64) offset);
+			xdr_encode_hyper(cd->offset, offset64);
 		}
 	}
 
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
index 832673b..673a53c 100644
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -228,7 +228,7 @@
 	struct posix_acl_summary pas;
 	unsigned short deny;
 	int eflag = ((flags & NFS4_ACL_TYPE_DEFAULT) ?
-					NFS4_INHERITANCE_FLAGS : 0);
+		NFS4_INHERITANCE_FLAGS | NFS4_ACE_INHERIT_ONLY_ACE : 0);
 
 	BUG_ON(pacl->a_count < 3);
 	summarize_posix_acl(pacl, &pas);
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 9e40679..af36070 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -750,9 +750,8 @@
 		status = nfserr_clid_inuse;
 		if (!cmp_creds(&conf->cl_cred, &rqstp->rq_cred)
 				|| conf->cl_addr != sin->sin_addr.s_addr) {
-			printk("NFSD: setclientid: string in use by client"
-			"(clientid %08x/%08x)\n",
-			conf->cl_clientid.cl_boot, conf->cl_clientid.cl_id);
+			dprintk("NFSD: setclientid: string in use by client"
+				"at %u.%u.%u.%u\n", NIPQUAD(conf->cl_addr));
 			goto out;
 		}
 	}
@@ -3261,7 +3260,6 @@
 		unhash_delegation(dp);
 	}
 
-	cancel_delayed_work(&laundromat_work);
 	nfsd4_shutdown_recdir();
 	nfs4_init = 0;
 }
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index c2660cb..8d995bc 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -17,7 +17,6 @@
 #include <linux/stat.h>
 #include <linux/dcache.h>
 #include <linux/mount.h>
-#include <asm/pgtable.h>
 
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/svc.h>
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 93628b0..875c114 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -614,6 +614,27 @@
 	ocfs2_rw_unlock(inode, 0);
 }
 
+/*
+ * ocfs2_invalidatepage() and ocfs2_releasepage() are shamelessly stolen
+ * from ext3.  PageChecked() bits have been removed as OCFS2 does not
+ * do journalled data.
+ */
+static void ocfs2_invalidatepage(struct page *page, unsigned long offset)
+{
+	journal_t *journal = OCFS2_SB(page->mapping->host->i_sb)->journal->j_journal;
+
+	journal_invalidatepage(journal, page, offset);
+}
+
+static int ocfs2_releasepage(struct page *page, gfp_t wait)
+{
+	journal_t *journal = OCFS2_SB(page->mapping->host->i_sb)->journal->j_journal;
+
+	if (!page_has_buffers(page))
+		return 0;
+	return journal_try_to_free_buffers(journal, page, wait);
+}
+
 static ssize_t ocfs2_direct_IO(int rw,
 			       struct kiocb *iocb,
 			       const struct iovec *iov,
@@ -661,5 +682,8 @@
 	.commit_write	= ocfs2_commit_write,
 	.bmap		= ocfs2_bmap,
 	.sync_page	= block_sync_page,
-	.direct_IO	= ocfs2_direct_IO
+	.direct_IO	= ocfs2_direct_IO,
+	.invalidatepage	= ocfs2_invalidatepage,
+	.releasepage	= ocfs2_releasepage,
+	.migratepage	= buffer_migrate_page,
 };
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 5a9779b..eba282d 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -1234,6 +1234,7 @@
 				     const char *page,
 				     size_t count)
 {
+	struct task_struct *hb_task;
 	long fd;
 	int sectsize;
 	char *p = (char *)page;
@@ -1319,20 +1320,28 @@
 	 */
 	atomic_set(&reg->hr_steady_iterations, O2HB_LIVE_THRESHOLD + 1);
 
-	reg->hr_task = kthread_run(o2hb_thread, reg, "o2hb-%s",
-				   reg->hr_item.ci_name);
-	if (IS_ERR(reg->hr_task)) {
-		ret = PTR_ERR(reg->hr_task);
+	hb_task = kthread_run(o2hb_thread, reg, "o2hb-%s",
+			      reg->hr_item.ci_name);
+	if (IS_ERR(hb_task)) {
+		ret = PTR_ERR(hb_task);
 		mlog_errno(ret);
-		reg->hr_task = NULL;
 		goto out;
 	}
 
+	spin_lock(&o2hb_live_lock);
+	reg->hr_task = hb_task;
+	spin_unlock(&o2hb_live_lock);
+
 	ret = wait_event_interruptible(o2hb_steady_queue,
 				atomic_read(&reg->hr_steady_iterations) == 0);
 	if (ret) {
-		kthread_stop(reg->hr_task);
+		spin_lock(&o2hb_live_lock);
+		hb_task = reg->hr_task;
 		reg->hr_task = NULL;
+		spin_unlock(&o2hb_live_lock);
+
+		if (hb_task)
+			kthread_stop(hb_task);
 		goto out;
 	}
 
@@ -1354,10 +1363,17 @@
 static ssize_t o2hb_region_pid_read(struct o2hb_region *reg,
                                       char *page)
 {
-	if (!reg->hr_task)
+	pid_t pid = 0;
+
+	spin_lock(&o2hb_live_lock);
+	if (reg->hr_task)
+		pid = reg->hr_task->pid;
+	spin_unlock(&o2hb_live_lock);
+
+	if (!pid)
 		return 0;
 
-	return sprintf(page, "%u\n", reg->hr_task->pid);
+	return sprintf(page, "%u\n", pid);
 }
 
 struct o2hb_region_attribute {
@@ -1495,13 +1511,17 @@
 static void o2hb_heartbeat_group_drop_item(struct config_group *group,
 					   struct config_item *item)
 {
+	struct task_struct *hb_task;
 	struct o2hb_region *reg = to_o2hb_region(item);
 
 	/* stop the thread when the user removes the region dir */
-	if (reg->hr_task) {
-		kthread_stop(reg->hr_task);
-		reg->hr_task = NULL;
-	}
+	spin_lock(&o2hb_live_lock);
+	hb_task = reg->hr_task;
+	reg->hr_task = NULL;
+	spin_unlock(&o2hb_live_lock);
+
+	if (hb_task)
+		kthread_stop(hb_task);
 
 	config_item_put(item);
 }
@@ -1682,7 +1702,7 @@
 }
 EXPORT_SYMBOL_GPL(o2hb_register_callback);
 
-int o2hb_unregister_callback(struct o2hb_callback_func *hc)
+void o2hb_unregister_callback(struct o2hb_callback_func *hc)
 {
 	BUG_ON(hc->hc_magic != O2HB_CB_MAGIC);
 
@@ -1690,15 +1710,13 @@
 	     __builtin_return_address(0), hc);
 
 	if (list_empty(&hc->hc_item))
-		return 0;
+		return;
 
 	down_write(&o2hb_callback_sem);
 
 	list_del_init(&hc->hc_item);
 
 	up_write(&o2hb_callback_sem);
-
-	return 0;
 }
 EXPORT_SYMBOL_GPL(o2hb_unregister_callback);
 
diff --git a/fs/ocfs2/cluster/heartbeat.h b/fs/ocfs2/cluster/heartbeat.h
index cac6223..cc6d40b 100644
--- a/fs/ocfs2/cluster/heartbeat.h
+++ b/fs/ocfs2/cluster/heartbeat.h
@@ -70,7 +70,7 @@
 			 void *data,
 			 int priority);
 int o2hb_register_callback(struct o2hb_callback_func *hc);
-int o2hb_unregister_callback(struct o2hb_callback_func *hc);
+void o2hb_unregister_callback(struct o2hb_callback_func *hc);
 void o2hb_fill_node_map(unsigned long *map,
 			unsigned bytes);
 void o2hb_init(void);
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
index 1718215..69caf3e 100644
--- a/fs/ocfs2/cluster/tcp.c
+++ b/fs/ocfs2/cluster/tcp.c
@@ -1638,17 +1638,8 @@
 
 void o2net_unregister_hb_callbacks(void)
 {
-	int ret;
-
-	ret = o2hb_unregister_callback(&o2net_hb_up);
-	if (ret < 0)
-		mlog(ML_ERROR, "Status return %d unregistering heartbeat up "
-		     "callback!\n", ret);
-
-	ret = o2hb_unregister_callback(&o2net_hb_down);
-	if (ret < 0)
-		mlog(ML_ERROR, "Status return %d unregistering heartbeat down "
-		     "callback!\n", ret);
+	o2hb_unregister_callback(&o2net_hb_up);
+	o2hb_unregister_callback(&o2net_hb_down);
 }
 
 int o2net_register_hb_callbacks(void)
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
index 6087c47..c558442 100644
--- a/fs/ocfs2/dlm/dlmdomain.c
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -138,8 +138,10 @@
 
 void __dlm_unhash_lockres(struct dlm_lock_resource *lockres)
 {
-	hlist_del_init(&lockres->hash_node);
-	dlm_lockres_put(lockres);
+	if (!hlist_unhashed(&lockres->hash_node)) {
+		hlist_del_init(&lockres->hash_node);
+		dlm_lockres_put(lockres);
+	}
 }
 
 void __dlm_insert_lockres(struct dlm_ctxt *dlm,
@@ -655,6 +657,8 @@
 		dlm_kick_thread(dlm, NULL);
 
 		while (dlm_migrate_all_locks(dlm)) {
+			/* Give dlm_thread time to purge the lockres' */
+			msleep(500);
 			mlog(0, "%s: more migration to do\n", dlm->name);
 		}
 		dlm_mark_domain_leaving(dlm);
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index 77e4e61..6edffca 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -2424,6 +2424,57 @@
 	dlm_lockres_put(res);
 }
 
+/* Checks whether the lockres can be migrated. Returns 0 if yes, < 0
+ * if not. If 0, numlocks is set to the number of locks in the lockres.
+ */
+static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm,
+				      struct dlm_lock_resource *res,
+				      int *numlocks)
+{
+	int ret;
+	int i;
+	int count = 0;
+	struct list_head *queue, *iter;
+	struct dlm_lock *lock;
+
+	assert_spin_locked(&res->spinlock);
+
+	ret = -EINVAL;
+	if (res->owner == DLM_LOCK_RES_OWNER_UNKNOWN) {
+		mlog(0, "cannot migrate lockres with unknown owner!\n");
+		goto leave;
+	}
+
+	if (res->owner != dlm->node_num) {
+		mlog(0, "cannot migrate lockres this node doesn't own!\n");
+		goto leave;
+	}
+
+	ret = 0;
+	queue = &res->granted;
+	for (i = 0; i < 3; i++) {
+		list_for_each(iter, queue) {
+			lock = list_entry(iter, struct dlm_lock, list);
+			++count;
+			if (lock->ml.node == dlm->node_num) {
+				mlog(0, "found a lock owned by this node still "
+				     "on the %s queue!  will not migrate this "
+				     "lockres\n", (i == 0 ? "granted" :
+						   (i == 1 ? "converting" :
+						    "blocked")));
+				ret = -ENOTEMPTY;
+				goto leave;
+			}
+		}
+		queue++;
+	}
+
+	*numlocks = count;
+	mlog(0, "migrateable lockres having %d locks\n", *numlocks);
+
+leave:
+	return ret;
+}
 
 /*
  * DLM_MIGRATE_LOCKRES
@@ -2437,14 +2488,12 @@
 	struct dlm_master_list_entry *mle = NULL;
 	struct dlm_master_list_entry *oldmle = NULL;
  	struct dlm_migratable_lockres *mres = NULL;
-	int ret = -EINVAL;
+	int ret = 0;
 	const char *name;
 	unsigned int namelen;
 	int mle_added = 0;
-	struct list_head *queue, *iter;
-	int i;
-	struct dlm_lock *lock;
-	int empty = 1, wake = 0;
+	int numlocks;
+	int wake = 0;
 
 	if (!dlm_grab(dlm))
 		return -EINVAL;
@@ -2458,42 +2507,16 @@
 	 * ensure this lockres is a proper candidate for migration
 	 */
 	spin_lock(&res->spinlock);
-	if (res->owner == DLM_LOCK_RES_OWNER_UNKNOWN) {
-		mlog(0, "cannot migrate lockres with unknown owner!\n");
+	ret = dlm_is_lockres_migrateable(dlm, res, &numlocks);
+	if (ret < 0) {
 		spin_unlock(&res->spinlock);
 		goto leave;
 	}
-	if (res->owner != dlm->node_num) {
-		mlog(0, "cannot migrate lockres this node doesn't own!\n");
-		spin_unlock(&res->spinlock);
-		goto leave;
-	}
-	mlog(0, "checking queues...\n");
-	queue = &res->granted;
-	for (i=0; i<3; i++) {
-		list_for_each(iter, queue) {
-			lock = list_entry (iter, struct dlm_lock, list);
-			empty = 0;
-			if (lock->ml.node == dlm->node_num) {
-				mlog(0, "found a lock owned by this node "
-				     "still on the %s queue!  will not "
-				     "migrate this lockres\n",
-				     i==0 ? "granted" :
-				     (i==1 ? "converting" : "blocked"));
-				spin_unlock(&res->spinlock);
-				ret = -ENOTEMPTY;
-				goto leave;
-			}
-		}
-		queue++;
-	}
-	mlog(0, "all locks on this lockres are nonlocal.  continuing\n");
 	spin_unlock(&res->spinlock);
 
 	/* no work to do */
-	if (empty) {
+	if (numlocks == 0) {
 		mlog(0, "no locks were found on this lockres! done!\n");
-		ret = 0;
 		goto leave;
 	}
 
@@ -2729,16 +2752,27 @@
 {
 	int ret;
 	int lock_dropped = 0;
+	int numlocks;
 
+	spin_lock(&res->spinlock);
 	if (res->owner != dlm->node_num) {
 		if (!__dlm_lockres_unused(res)) {
 			mlog(ML_ERROR, "%s:%.*s: this node is not master, "
 			     "trying to free this but locks remain\n",
 			     dlm->name, res->lockname.len, res->lockname.name);
 		}
+		spin_unlock(&res->spinlock);
 		goto leave;
 	}
 
+	/* No need to migrate a lockres having no locks */
+	ret = dlm_is_lockres_migrateable(dlm, res, &numlocks);
+	if (ret >= 0 && numlocks == 0) {
+		spin_unlock(&res->spinlock);
+		goto leave;
+	}
+	spin_unlock(&res->spinlock);
+
 	/* Wheee! Migrate lockres here! Will sleep so drop spinlock. */
 	spin_unlock(&dlm->spinlock);
 	lock_dropped = 1;
diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c
index 8ffa091..2b264c6 100644
--- a/fs/ocfs2/dlm/dlmthread.c
+++ b/fs/ocfs2/dlm/dlmthread.c
@@ -256,18 +256,14 @@
 			break;
 		}
 
-		mlog(0, "removing lockres %.*s:%p from purgelist\n",
-		     lockres->lockname.len, lockres->lockname.name, lockres);
-		list_del_init(&lockres->purge);
-		dlm_lockres_put(lockres);
-		dlm->purge_count--;
+		dlm_lockres_get(lockres);
 
 		/* This may drop and reacquire the dlm spinlock if it
 		 * has to do migration. */
-		mlog(0, "calling dlm_purge_lockres!\n");
 		if (dlm_purge_lockres(dlm, lockres))
 			BUG();
-		mlog(0, "DONE calling dlm_purge_lockres!\n");
+
+		dlm_lockres_put(lockres);
 
 		/* Avoid adding any scheduling latencies */
 		cond_resched_lock(&dlm->spinlock);
diff --git a/fs/ocfs2/heartbeat.c b/fs/ocfs2/heartbeat.c
index 8fc52d6..b25ef63 100644
--- a/fs/ocfs2/heartbeat.c
+++ b/fs/ocfs2/heartbeat.c
@@ -164,8 +164,10 @@
 	}
 
 	status = o2hb_register_callback(&osb->osb_hb_up);
-	if (status < 0)
+	if (status < 0) {
 		mlog_errno(status);
+		o2hb_unregister_callback(&osb->osb_hb_down);
+	}
 
 bail:
 	return status;
@@ -173,18 +175,11 @@
 
 void ocfs2_clear_hb_callbacks(struct ocfs2_super *osb)
 {
-	int status;
-
 	if (ocfs2_mount_local(osb))
 		return;
 
-	status = o2hb_unregister_callback(&osb->osb_hb_down);
-	if (status < 0)
-		mlog_errno(status);
-
-	status = o2hb_unregister_callback(&osb->osb_hb_up);
-	if (status < 0)
-		mlog_errno(status);
+	o2hb_unregister_callback(&osb->osb_hb_down);
+	o2hb_unregister_callback(&osb->osb_hb_up);
 }
 
 void ocfs2_stop_heartbeat(struct ocfs2_super *osb)
diff --git a/fs/partitions/Kconfig b/fs/partitions/Kconfig
index 74552c6..6e8bb66 100644
--- a/fs/partitions/Kconfig
+++ b/fs/partitions/Kconfig
@@ -235,5 +235,4 @@
 	select CRC32
 	help
 	  Say Y here if you would like to use hard disks under Linux which
-	  were partitioned using EFI GPT.  Presently only useful on the
-	  IA-64 platform.
+	  were partitioned using EFI GPT.
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 22d38ff..8a7d003 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -180,7 +180,7 @@
 	}
 	if (res > 0)
 		return state;
-	if (!err)
+	if (err)
 	/* The partition is unrecognized. So report I/O errors if there were any */
 		res = err;
 	if (!res)
@@ -541,7 +541,7 @@
 	if (!get_capacity(disk) || !(state = check_partition(disk, bdev)))
 		return 0;
 	if (IS_ERR(state))	/* I/O error reading the partition table */
-		return PTR_ERR(state);
+		return -EIO;
 	for (p = 1; p < state->limit; p++) {
 		sector_t size = state->parts[p].size;
 		sector_t from = state->parts[p].from;
diff --git a/fs/proc/Makefile b/fs/proc/Makefile
index a6b3a8f..bce38e3 100644
--- a/fs/proc/Makefile
+++ b/fs/proc/Makefile
@@ -8,8 +8,9 @@
 proc-$(CONFIG_MMU)	:= mmu.o task_mmu.o
 
 proc-y       += inode.o root.o base.o generic.o array.o \
-		proc_tty.o proc_misc.o proc_sysctl.o
+		proc_tty.o proc_misc.o
 
+proc-$(CONFIG_PROC_SYSCTL)	+= proc_sysctl.o
 proc-$(CONFIG_PROC_KCORE)	+= kcore.o
 proc-$(CONFIG_PROC_VMCORE)	+= vmcore.o
 proc-$(CONFIG_PROC_DEVICETREE)	+= proc_devtree.o
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 01f7769..989af5e 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1558,29 +1558,20 @@
 				  size_t count, loff_t *ppos)
 {
 	struct inode * inode = file->f_path.dentry->d_inode;
-	unsigned long page;
+	char *p = NULL;
 	ssize_t length;
 	struct task_struct *task = get_proc_task(inode);
 
-	length = -ESRCH;
 	if (!task)
-		goto out_no_task;
-
-	if (count > PAGE_SIZE)
-		count = PAGE_SIZE;
-	length = -ENOMEM;
-	if (!(page = __get_free_page(GFP_KERNEL)))
-		goto out;
+		return -ESRCH;
 
 	length = security_getprocattr(task,
 				      (char*)file->f_path.dentry->d_name.name,
-				      (void*)page, count);
-	if (length >= 0)
-		length = simple_read_from_buffer(buf, count, ppos, (char *)page, length);
-	free_page(page);
-out:
+				      &p);
 	put_task_struct(task);
-out_no_task:
+	if (length > 0)
+		length = simple_read_from_buffer(buf, count, ppos, p, length);
+	kfree(p);
 	return length;
 }
 
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index c932aa6..f771889 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -11,7 +11,11 @@
 
 #include <linux/proc_fs.h>
 
+#ifdef CONFIG_PROC_SYSCTL
 extern int proc_sys_init(void);
+#else
+static inline void proc_sys_init(void) { }
+#endif
 
 struct vmalloc_info {
 	unsigned long	used;
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 5834a744..41f1703 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -79,9 +79,7 @@
 	proc_device_tree_init();
 #endif
 	proc_bus = proc_mkdir("bus", NULL);
-#ifdef CONFIG_SYSCTL
 	proc_sys_init();
-#endif
 }
 
 static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat
diff --git a/fs/smbfs/request.c b/fs/smbfs/request.c
index 42261db..723f7c6 100644
--- a/fs/smbfs/request.c
+++ b/fs/smbfs/request.c
@@ -181,6 +181,7 @@
 	req->rq_errno = 0;
 	req->rq_fragment = 0;
 	kfree(req->rq_trans2buffer);
+	req->rq_trans2buffer = NULL;
 
 	return 0;
 }
diff --git a/fs/splice.c b/fs/splice.c
index 2fca6eb..5428b0f 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -576,76 +576,21 @@
 	if (this_len + offset > PAGE_CACHE_SIZE)
 		this_len = PAGE_CACHE_SIZE - offset;
 
-	/*
-	 * Reuse buf page, if SPLICE_F_MOVE is set and we are doing a full
-	 * page.
-	 */
-	if ((sd->flags & SPLICE_F_MOVE) && this_len == PAGE_CACHE_SIZE) {
-		/*
-		 * If steal succeeds, buf->page is now pruned from the
-		 * pagecache and we can reuse it. The page will also be
-		 * locked on successful return.
-		 */
-		if (buf->ops->steal(pipe, buf))
-			goto find_page;
-
-		page = buf->page;
-		if (add_to_page_cache(page, mapping, index, GFP_KERNEL)) {
-			unlock_page(page);
-			goto find_page;
-		}
-
-		page_cache_get(page);
-
-		if (!(buf->flags & PIPE_BUF_FLAG_LRU))
-			lru_cache_add(page);
-	} else {
 find_page:
-		page = find_lock_page(mapping, index);
-		if (!page) {
-			ret = -ENOMEM;
-			page = page_cache_alloc_cold(mapping);
-			if (unlikely(!page))
-				goto out_ret;
-
-			/*
-			 * This will also lock the page
-			 */
-			ret = add_to_page_cache_lru(page, mapping, index,
-						    GFP_KERNEL);
-			if (unlikely(ret))
-				goto out;
-		}
+	page = find_lock_page(mapping, index);
+	if (!page) {
+		ret = -ENOMEM;
+		page = page_cache_alloc_cold(mapping);
+		if (unlikely(!page))
+			goto out_ret;
 
 		/*
-		 * We get here with the page locked. If the page is also
-		 * uptodate, we don't need to do more. If it isn't, we
-		 * may need to bring it in if we are not going to overwrite
-		 * the full page.
+		 * This will also lock the page
 		 */
-		if (!PageUptodate(page)) {
-			if (this_len < PAGE_CACHE_SIZE) {
-				ret = mapping->a_ops->readpage(file, page);
-				if (unlikely(ret))
-					goto out;
-
-				lock_page(page);
-
-				if (!PageUptodate(page)) {
-					/*
-					 * Page got invalidated, repeat.
-					 */
-					if (!page->mapping) {
-						unlock_page(page);
-						page_cache_release(page);
-						goto find_page;
-					}
-					ret = -EIO;
-					goto out;
-				}
-			} else
-				SetPageUptodate(page);
-		}
+		ret = add_to_page_cache_lru(page, mapping, index,
+					    GFP_KERNEL);
+		if (unlikely(ret))
+			goto out;
 	}
 
 	ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len);
@@ -682,18 +627,25 @@
 	}
 
 	ret = mapping->a_ops->commit_write(file, page, offset, offset+this_len);
-	if (!ret) {
+	if (ret) {
+		if (ret == AOP_TRUNCATED_PAGE) {
+			page_cache_release(page);
+			goto find_page;
+		}
+		if (ret < 0)
+			goto out;
 		/*
-		 * Return the number of bytes written and mark page as
-		 * accessed, we are now done!
+		 * Partial write has happened, so 'ret' already initialized by
+		 * number of bytes written, Where is nothing we have to do here.
 		 */
+	} else
 		ret = this_len;
-		mark_page_accessed(page);
-		balance_dirty_pages_ratelimited(mapping);
-	} else if (ret == AOP_TRUNCATED_PAGE) {
-		page_cache_release(page);
-		goto find_page;
-	}
+	/*
+	 * Return the number of bytes written and mark page as
+	 * accessed, we are now done!
+	 */
+	mark_page_accessed(page);
+	balance_dirty_pages_ratelimited(mapping);
 out:
 	page_cache_release(page);
 	unlock_page(page);
@@ -706,9 +658,9 @@
  * key here is the 'actor' worker passed in that actually moves the data
  * to the wanted destination. See pipe_to_file/pipe_to_sendpage above.
  */
-static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
-				  struct file *out, loff_t *ppos, size_t len,
-				  unsigned int flags, splice_actor *actor)
+ssize_t __splice_from_pipe(struct pipe_inode_info *pipe,
+			   struct file *out, loff_t *ppos, size_t len,
+			   unsigned int flags, splice_actor *actor)
 {
 	int ret, do_wakeup, err;
 	struct splice_desc sd;
@@ -802,6 +754,7 @@
 
 	return ret;
 }
+EXPORT_SYMBOL(__splice_from_pipe);
 
 ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
 			 loff_t *ppos, size_t len, unsigned int flags,
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 8d4d839..fc46333 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -168,12 +168,12 @@
 	ssize_t retval = 0;
 
 	down(&buffer->sem);
-	if (buffer->orphaned) {
-		retval = -ENODEV;
-		goto out;
-	}
 	if (buffer->needs_read_fill) {
-		if ((retval = fill_read_buffer(file->f_path.dentry,buffer)))
+		if (buffer->orphaned)
+			retval = -ENODEV;
+		else
+			retval = fill_read_buffer(file->f_path.dentry,buffer);
+		if (retval)
 			goto out;
 	}
 	pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n",
@@ -629,6 +629,60 @@
 }
 EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group);
 
+struct sysfs_schedule_callback_struct {
+	struct kobject 		*kobj;
+	void			(*func)(void *);
+	void			*data;
+	struct work_struct	work;
+};
+
+static void sysfs_schedule_callback_work(struct work_struct *work)
+{
+	struct sysfs_schedule_callback_struct *ss = container_of(work,
+			struct sysfs_schedule_callback_struct, work);
+
+	(ss->func)(ss->data);
+	kobject_put(ss->kobj);
+	kfree(ss);
+}
+
+/**
+ * sysfs_schedule_callback - helper to schedule a callback for a kobject
+ * @kobj: object we're acting for.
+ * @func: callback function to invoke later.
+ * @data: argument to pass to @func.
+ *
+ * sysfs attribute methods must not unregister themselves or their parent
+ * kobject (which would amount to the same thing).  Attempts to do so will
+ * deadlock, since unregistration is mutually exclusive with driver
+ * callbacks.
+ *
+ * Instead methods can call this routine, which will attempt to allocate
+ * and schedule a workqueue request to call back @func with @data as its
+ * argument in the workqueue's process context.  @kobj will be pinned
+ * until @func returns.
+ *
+ * Returns 0 if the request was submitted, -ENOMEM if storage could not
+ * be allocated.
+ */
+int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
+		void *data)
+{
+	struct sysfs_schedule_callback_struct *ss;
+
+	ss = kmalloc(sizeof(*ss), GFP_KERNEL);
+	if (!ss)
+		return -ENOMEM;
+	kobject_get(kobj);
+	ss->kobj = kobj;
+	ss->func = func;
+	ss->data = data;
+	INIT_WORK(&ss->work, sysfs_schedule_callback_work);
+	schedule_work(&ss->work);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(sysfs_schedule_callback);
+
 
 EXPORT_SYMBOL_GPL(sysfs_create_file);
 EXPORT_SYMBOL_GPL(sysfs_remove_file);
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index ccb7d72..4de5c6b 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -222,13 +222,17 @@
 
 static inline void orphan_all_buffers(struct inode *node)
 {
-	struct sysfs_buffer_collection *set = node->i_private;
+	struct sysfs_buffer_collection *set;
 	struct sysfs_buffer *buf;
 
 	mutex_lock_nested(&node->i_mutex, I_MUTEX_CHILD);
-	if (node->i_private) {
-		list_for_each_entry(buf, &set->associates, associates)
+	set = node->i_private;
+	if (set) {
+		list_for_each_entry(buf, &set->associates, associates) {
+			down(&buf->sem);
 			buf->orphaned = 1;
+			up(&buf->sem);
+		}
 	}
 	mutex_unlock(&node->i_mutex);
 }
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index bcc4408..841ac25 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -244,62 +244,87 @@
  * We can come here from ufs_writepage or ufs_prepare_write,
  * locked_page is argument of these functions, so we already lock it.
  */
-static void ufs_change_blocknr(struct inode *inode, unsigned int beg,
-			       unsigned int count, unsigned int oldb,
-			       unsigned int newb, struct page *locked_page)
+static void ufs_change_blocknr(struct inode *inode, sector_t beg,
+			       unsigned int count, sector_t oldb,
+			       sector_t newb, struct page *locked_page)
 {
-	const unsigned mask = (1 << (PAGE_CACHE_SHIFT - inode->i_blkbits)) - 1;
+	const unsigned blks_per_page =
+		1 << (PAGE_CACHE_SHIFT - inode->i_blkbits);
+	const unsigned mask = blks_per_page - 1;
 	struct address_space * const mapping = inode->i_mapping;
-	pgoff_t index, cur_index;
-	unsigned end, pos, j;
+	pgoff_t index, cur_index, last_index;
+	unsigned pos, j, lblock;
+	sector_t end, i;
 	struct page *page;
 	struct buffer_head *head, *bh;
 
-	UFSD("ENTER, ino %lu, count %u, oldb %u, newb %u\n",
-	      inode->i_ino, count, oldb, newb);
+	UFSD("ENTER, ino %lu, count %u, oldb %llu, newb %llu\n",
+	      inode->i_ino, count,
+	     (unsigned long long)oldb, (unsigned long long)newb);
 
 	BUG_ON(!locked_page);
 	BUG_ON(!PageLocked(locked_page));
 
 	cur_index = locked_page->index;
-
-	for (end = count + beg; beg < end; beg = (beg | mask) + 1) {
-		index = beg >> (PAGE_CACHE_SHIFT - inode->i_blkbits);
+	end = count + beg;
+	last_index = end >> (PAGE_CACHE_SHIFT - inode->i_blkbits);
+	for (i = beg; i < end; i = (i | mask) + 1) {
+		index = i >> (PAGE_CACHE_SHIFT - inode->i_blkbits);
 
 		if (likely(cur_index != index)) {
 			page = ufs_get_locked_page(mapping, index);
-			if (!page || IS_ERR(page)) /* it was truncated or EIO */
+			if (!page)/* it was truncated */
 				continue;
+			if (IS_ERR(page)) {/* or EIO */
+				ufs_error(inode->i_sb, __FUNCTION__,
+					  "read of page %llu failed\n",
+					  (unsigned long long)index);
+				continue;
+			}
 		} else
 			page = locked_page;
 
 		head = page_buffers(page);
 		bh = head;
-		pos = beg & mask;
+		pos = i & mask;
 		for (j = 0; j < pos; ++j)
 			bh = bh->b_this_page;
-		j = 0;
+
+
+		if (unlikely(index == last_index))
+			lblock = end & mask;
+		else
+			lblock = blks_per_page;
+
 		do {
-			if (buffer_mapped(bh)) {
-				pos = bh->b_blocknr - oldb;
-				if (pos < count) {
-					UFSD(" change from %llu to %llu\n",
-					     (unsigned long long)pos + oldb,
-					     (unsigned long long)pos + newb);
-					bh->b_blocknr = newb + pos;
-					unmap_underlying_metadata(bh->b_bdev,
-								  bh->b_blocknr);
-					mark_buffer_dirty(bh);
-					++j;
+			if (j >= lblock)
+				break;
+			pos = (i - beg) + j;
+
+			if (!buffer_mapped(bh))
+					map_bh(bh, inode->i_sb, oldb + pos);
+			if (!buffer_uptodate(bh)) {
+				ll_rw_block(READ, 1, &bh);
+				wait_on_buffer(bh);
+				if (!buffer_uptodate(bh)) {
+					ufs_error(inode->i_sb, __FUNCTION__,
+						  "read of block failed\n");
+					break;
 				}
 			}
 
+			UFSD(" change from %llu to %llu, pos %u\n",
+			     (unsigned long long)pos + oldb,
+			     (unsigned long long)pos + newb, pos);
+
+			bh->b_blocknr = newb + pos;
+			unmap_underlying_metadata(bh->b_bdev,
+						  bh->b_blocknr);
+			mark_buffer_dirty(bh);
+			++j;
 			bh = bh->b_this_page;
 		} while (bh != head);
 
-		if (j)
-			set_page_dirty(page);
-
 		if (likely(cur_index != index))
 			ufs_put_locked_page(page);
  	}
@@ -457,8 +482,9 @@
 	if (result) {
 		ufs_clear_frags(inode, result + oldcount, newcount - oldcount,
 				locked_page != NULL);
-		ufs_change_blocknr(inode, fragment - oldcount, oldcount, tmp,
-				   result, locked_page);
+		ufs_change_blocknr(inode, fragment - oldcount, oldcount,
+				   uspi->s_sbbase + tmp,
+				   uspi->s_sbbase + result, locked_page);
 		ufs_cpu_to_data_ptr(sb, p, result);
 		*err = 0;
 		UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count);
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c
index b868878..c28a8b6 100644
--- a/fs/ufs/ialloc.c
+++ b/fs/ufs/ialloc.c
@@ -343,9 +343,8 @@
 		lock_buffer(bh);
 		ufs2_inode = (struct ufs2_inode *)bh->b_data;
 		ufs2_inode += ufs_inotofsbo(inode->i_ino);
-		ufs2_inode->ui_birthtime.tv_sec =
-			cpu_to_fs32(sb, CURRENT_TIME_SEC.tv_sec);
-		ufs2_inode->ui_birthtime.tv_usec = 0;
+		ufs2_inode->ui_birthtime = cpu_to_fs64(sb, CURRENT_TIME.tv_sec);
+		ufs2_inode->ui_birthnsec = cpu_to_fs32(sb, CURRENT_TIME.tv_nsec);
 		mark_buffer_dirty(bh);
 		unlock_buffer(bh);
 		if (sb->s_flags & MS_SYNCHRONOUS)
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index fb34ad0..013d7af 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -212,7 +212,7 @@
 			brelse (result);
 			goto repeat;
 		} else {
-			*phys = tmp + blockoff;
+			*phys = uspi->s_sbbase + tmp + blockoff;
 			return NULL;
 		}
 	}
@@ -282,9 +282,9 @@
 	}
 
 	if (!phys) {
-		result = sb_getblk(sb, tmp + blockoff);
+		result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff);
 	} else {
-		*phys = tmp + blockoff;
+		*phys = uspi->s_sbbase + tmp + blockoff;
 		result = NULL;
 		*err = 0;
 		*new = 1;
@@ -368,7 +368,7 @@
 			brelse (result);
 			goto repeat;
 		} else {
-			*phys = tmp + blockoff;
+			*phys = uspi->s_sbbase + tmp + blockoff;
 			goto out;
 		}
 	}
@@ -389,9 +389,9 @@
 
 
 	if (!phys) {
-		result = sb_getblk(sb, tmp + blockoff);
+		result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff);
 	} else {
-		*phys = tmp + blockoff;
+		*phys = uspi->s_sbbase + tmp + blockoff;
 		*new = 1;
 	}
 
@@ -668,12 +668,12 @@
 	inode->i_gid = fs32_to_cpu(sb, ufs2_inode->ui_gid);
 
 	inode->i_size = fs64_to_cpu(sb, ufs2_inode->ui_size);
-	inode->i_atime.tv_sec = fs32_to_cpu(sb, ufs2_inode->ui_atime.tv_sec);
-	inode->i_ctime.tv_sec = fs32_to_cpu(sb, ufs2_inode->ui_ctime.tv_sec);
-	inode->i_mtime.tv_sec = fs32_to_cpu(sb, ufs2_inode->ui_mtime.tv_sec);
-	inode->i_mtime.tv_nsec = 0;
-	inode->i_atime.tv_nsec = 0;
-	inode->i_ctime.tv_nsec = 0;
+	inode->i_atime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_atime);
+	inode->i_ctime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_ctime);
+	inode->i_mtime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_mtime);
+	inode->i_atime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_atimensec);
+	inode->i_ctime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_ctimensec);
+	inode->i_mtime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_mtimensec);
 	inode->i_blocks = fs64_to_cpu(sb, ufs2_inode->ui_blocks);
 	inode->i_generation = fs32_to_cpu(sb, ufs2_inode->ui_gen);
 	ufsi->i_flags = fs32_to_cpu(sb, ufs2_inode->ui_flags);
@@ -803,12 +803,12 @@
 	ufs_inode->ui_gid = cpu_to_fs32(sb, inode->i_gid);
 
 	ufs_inode->ui_size = cpu_to_fs64(sb, inode->i_size);
-	ufs_inode->ui_atime.tv_sec = cpu_to_fs32(sb, inode->i_atime.tv_sec);
-	ufs_inode->ui_atime.tv_usec = 0;
-	ufs_inode->ui_ctime.tv_sec = cpu_to_fs32(sb, inode->i_ctime.tv_sec);
-	ufs_inode->ui_ctime.tv_usec = 0;
-	ufs_inode->ui_mtime.tv_sec = cpu_to_fs32(sb, inode->i_mtime.tv_sec);
-	ufs_inode->ui_mtime.tv_usec = 0;
+	ufs_inode->ui_atime = cpu_to_fs64(sb, inode->i_atime.tv_sec);
+	ufs_inode->ui_atimensec = cpu_to_fs32(sb, inode->i_atime.tv_nsec);
+	ufs_inode->ui_ctime = cpu_to_fs64(sb, inode->i_ctime.tv_sec);
+	ufs_inode->ui_ctimensec = cpu_to_fs32(sb, inode->i_ctime.tv_nsec);
+	ufs_inode->ui_mtime = cpu_to_fs64(sb, inode->i_mtime.tv_sec);
+	ufs_inode->ui_mtimensec = cpu_to_fs32(sb, inode->i_mtime.tv_nsec);
 
 	ufs_inode->ui_blocks = cpu_to_fs64(sb, inode->i_blocks);
 	ufs_inode->ui_flags = cpu_to_fs32(sb, ufsi->i_flags);
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c
index 749581f..79c54c8 100644
--- a/fs/ufs/truncate.c
+++ b/fs/ufs/truncate.c
@@ -74,7 +74,7 @@
 	unsigned i, tmp;
 	int retry;
 	
-	UFSD("ENTER\n");
+	UFSD("ENTER: ino %lu\n", inode->i_ino);
 
 	sb = inode->i_sb;
 	uspi = UFS_SB(sb)->s_uspi;
@@ -96,8 +96,8 @@
 		block2 = ufs_fragstoblks (frag3);
 	}
 
-	UFSD("frag1 %llu, frag2 %llu, block1 %llu, block2 %llu, frag3 %llu,"
-	     " frag4 %llu\n",
+	UFSD("ino %lu, frag1 %llu, frag2 %llu, block1 %llu, block2 %llu,"
+	     " frag3 %llu, frag4 %llu\n", inode->i_ino,
 	     (unsigned long long)frag1, (unsigned long long)frag2,
 	     (unsigned long long)block1, (unsigned long long)block2,
 	     (unsigned long long)frag3, (unsigned long long)frag4);
@@ -163,7 +163,7 @@
 	mark_inode_dirty(inode);
  next3:
 
-	UFSD("EXIT\n");
+	UFSD("EXIT: ino %lu\n", inode->i_ino);
 	return retry;
 }
 
@@ -248,7 +248,7 @@
 	}
 	ubh_brelse (ind_ubh);
 	
-	UFSD("EXIT\n");
+	UFSD("EXIT: ino %lu\n", inode->i_ino);
 	
 	return retry;
 }
@@ -262,7 +262,7 @@
 	void *dind;
 	int retry = 0;
 	
-	UFSD("ENTER\n");
+	UFSD("ENTER: ino %lu\n", inode->i_ino);
 	
 	sb = inode->i_sb;
 	uspi = UFS_SB(sb)->s_uspi;
@@ -312,7 +312,7 @@
 	}
 	ubh_brelse (dind_bh);
 	
-	UFSD("EXIT\n");
+	UFSD("EXIT: ino %lu\n", inode->i_ino);
 	
 	return retry;
 }
@@ -327,7 +327,7 @@
 	void *tind, *p;
 	int retry;
 	
-	UFSD("ENTER\n");
+	UFSD("ENTER: ino %lu\n", inode->i_ino);
 
 	retry = 0;
 	
@@ -348,7 +348,7 @@
 	}
 
 	for (i = tindirect_block ; i < uspi->s_apb ; i++) {
-		tind = ubh_get_addr32 (tind_bh, i);
+		tind = ubh_get_data_ptr(uspi, tind_bh, i);
 		retry |= ufs_trunc_dindirect(inode, UFS_NDADDR + 
 			uspi->s_apb + ((i + 1) << uspi->s_2apbshift), tind);
 		ubh_mark_buffer_dirty(tind_bh);
@@ -372,19 +372,21 @@
 	}
 	ubh_brelse (tind_bh);
 	
-	UFSD("EXIT\n");
+	UFSD("EXIT: ino %lu\n", inode->i_ino);
 	return retry;
 }
 
 static int ufs_alloc_lastblock(struct inode *inode)
 {
 	int err = 0;
+	struct super_block *sb = inode->i_sb;
 	struct address_space *mapping = inode->i_mapping;
-	struct ufs_sb_private_info *uspi = UFS_SB(inode->i_sb)->s_uspi;
+	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
 	unsigned i, end;
 	sector_t lastfrag;
 	struct page *lastpage;
 	struct buffer_head *bh;
+	u64 phys64;
 
 	lastfrag = (i_size_read(inode) + uspi->s_fsize - 1) >> uspi->s_fshift;
 
@@ -424,6 +426,20 @@
 	       set_page_dirty(lastpage);
        }
 
+       if (lastfrag >= UFS_IND_FRAGMENT) {
+	       end = uspi->s_fpb - ufs_fragnum(lastfrag) - 1;
+	       phys64 = bh->b_blocknr + 1;
+	       for (i = 0; i < end; ++i) {
+		       bh = sb_getblk(sb, i + phys64);
+		       lock_buffer(bh);
+		       memset(bh->b_data, 0, sb->s_blocksize);
+		       set_buffer_uptodate(bh);
+		       mark_buffer_dirty(bh);
+		       unlock_buffer(bh);
+		       sync_dirty_buffer(bh);
+		       brelse(bh);
+	       }
+       }
 out_unlock:
        ufs_put_locked_page(lastpage);
 out:
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index e2bea6a..69e9e80 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -1829,11 +1829,11 @@
 	if (!xfs_buf_zone)
 		goto out_free_trace_buf;
 
-	xfslogd_workqueue = create_freezeable_workqueue("xfslogd");
+	xfslogd_workqueue = create_workqueue("xfslogd");
 	if (!xfslogd_workqueue)
 		goto out_free_buf_zone;
 
-	xfsdatad_workqueue = create_freezeable_workqueue("xfsdatad");
+	xfsdatad_workqueue = create_workqueue("xfsdatad");
 	if (!xfsdatad_workqueue)
 		goto out_destroy_xfslogd_workqueue;
 
diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h
index 73967c8..4409830 100644
--- a/include/acpi/acinterp.h
+++ b/include/acpi/acinterp.h
@@ -446,14 +446,10 @@
 /*
  * exutils - interpreter/scanner utilities
  */
-void acpi_ex_enter_interpreter(void);
+acpi_status acpi_ex_enter_interpreter(void);
 
 void acpi_ex_exit_interpreter(void);
 
-void acpi_ex_reacquire_interpreter(void);
-
-void acpi_ex_relinquish_interpreter(void);
-
 void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc);
 
 u8 acpi_ex_acquire_global_lock(u32 rule);
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index 72a6e2c..56bf492 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -344,7 +344,7 @@
 
 /* 64-bit integers */
 
-typedef u64 acpi_integer;
+typedef unsigned long long              acpi_integer;
 #define ACPI_INTEGER_MAX                ACPI_UINT64_MAX
 #define ACPI_INTEGER_BIT_SIZE           64
 #define ACPI_MAX_DECIMAL_DIGITS         20	/* 2^64 = 18,446,744,073,709,551,616 */
diff --git a/include/asm-arm/arch-at91/gpio.h b/include/asm-arm/arch-at91/gpio.h
index 98ad211..0a241e2 100644
--- a/include/asm-arm/arch-at91/gpio.h
+++ b/include/asm-arm/arch-at91/gpio.h
@@ -223,7 +223,7 @@
 }
 
 extern int gpio_direction_input(unsigned gpio);
-extern int gpio_direction_output(unsigned gpio);
+extern int gpio_direction_output(unsigned gpio, int value);
 
 static inline int gpio_get_value(unsigned gpio)
 {
diff --git a/include/asm-arm/arch-ixp4xx/io.h b/include/asm-arm/arch-ixp4xx/io.h
index b7b5414..a41ba22 100644
--- a/include/asm-arm/arch-ixp4xx/io.h
+++ b/include/asm-arm/arch-ixp4xx/io.h
@@ -238,23 +238,6 @@
 #define memcpy_fromio(a,c,l)		_memcpy_fromio((a),(c),(l))
 #define memcpy_toio(c,a,l)		_memcpy_toio((c),(a),(l))
 
-static inline int
-check_signature(const unsigned char __iomem *bus_addr, const unsigned char *signature,
-		int length)
-{
-	int retval = 0;
-	do {
-		if (readb(bus_addr) != *signature)
-			goto out;
-		bus_addr++;
-		signature++;
-		length--;
-	} while (length);
-	retval = 1;
-out:
-	return retval;
-}
-
 #endif
 
 #ifndef CONFIG_PCI
diff --git a/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
index 9444958..ed35e5c 100644
--- a/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
+++ b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
@@ -144,9 +144,9 @@
 #define IXP4XX_INTC_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x3000)
 #define IXP4XX_GPIO_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x4000)
 #define IXP4XX_TIMER_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x5000)
-#define IXP4XX_NPEA_BASE_VIRT   	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x6000)
-#define IXP4XX_NPEB_BASE_VIRT   	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x7000)
-#define IXP4XX_NPEC_BASE_VIRT   	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x8000)
+#define IXP4XX_NPEA_BASE_VIRT   	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x6000)
+#define IXP4XX_NPEB_BASE_VIRT   	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x7000)
+#define IXP4XX_NPEC_BASE_VIRT   	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x8000)
 #define IXP4XX_EthB_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x9000)
 #define IXP4XX_EthC_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0xA000)
 #define IXP4XX_USB_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0xB000)
diff --git a/include/asm-arm/arch-lh7a40x/entry-macro.S b/include/asm-arm/arch-lh7a40x/entry-macro.S
index 5027006..ffe3972 100644
--- a/include/asm-arm/arch-lh7a40x/entry-macro.S
+++ b/include/asm-arm/arch-lh7a40x/entry-macro.S
@@ -86,6 +86,12 @@
 		.macro	disable_fiq
 		.endm
 
+		.macro  get_irqnr_preamble, base, tmp
+		.endm
+
+		.macro  arch_ret_to_user, tmp1, tmp2
+		.endm
+
 		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
 		mov	\irqnr, #0
 		mov	\base, #io_p2v(0x80000000)	@ APB registers
@@ -105,6 +111,12 @@
 		.macro	disable_fiq
 		.endm
 
+		.macro  get_irqnr_preamble, base, tmp
+		.endm
+
+		.macro  arch_ret_to_user, tmp1, tmp2
+		.endm
+
 		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
 		mov	\irqnr, #0			@ VIC1 irq base
 		mov	\base, #io_p2v(0x80000000)	@ APB registers
diff --git a/include/asm-arm/arch-ns9xxx/clock.h b/include/asm-arm/arch-ns9xxx/clock.h
index 4371a48..a7c5ab3 100644
--- a/include/asm-arm/arch-ns9xxx/clock.h
+++ b/include/asm-arm/arch-ns9xxx/clock.h
@@ -11,6 +11,7 @@
 #ifndef __ASM_ARCH_CLOCK_H
 #define __ASM_ARCH_CLOCK_H
 
+static inline u32 ns9xxx_systemclock(void) __attribute__((const));
 static inline u32 ns9xxx_systemclock(void)
 {
 	/*
@@ -19,17 +20,20 @@
 	return 353894400;
 }
 
-static inline const u32 ns9xxx_cpuclock(void)
+static inline u32 ns9xxx_cpuclock(void) __attribute__((const));
+static inline u32 ns9xxx_cpuclock(void)
 {
 	return ns9xxx_systemclock() / 2;
 }
 
-static inline const u32 ns9xxx_ahbclock(void)
+static inline u32 ns9xxx_ahbclock(void) __attribute__((const));
+static inline u32 ns9xxx_ahbclock(void)
 {
 	return ns9xxx_systemclock() / 4;
 }
 
-static inline const u32 ns9xxx_bbusclock(void)
+static inline u32 ns9xxx_bbusclock(void) __attribute__((const));
+static inline u32 ns9xxx_bbusclock(void)
 {
 	return ns9xxx_systemclock() / 8;
 }
diff --git a/include/asm-arm/arch-omap/gpio.h b/include/asm-arm/arch-omap/gpio.h
index 3762a6a..590917e 100644
--- a/include/asm-arm/arch-omap/gpio.h
+++ b/include/asm-arm/arch-omap/gpio.h
@@ -113,8 +113,9 @@
 	return __gpio_set_direction(gpio, 1);
 }
 
-static inline int gpio_direction_output(unsigned gpio)
+static inline int gpio_direction_output(unsigned gpio, int value)
 {
+	omap_set_gpio_dataout(gpio, value);
 	return __gpio_set_direction(gpio, 0);
 }
 
diff --git a/include/asm-arm/arch-pxa/gpio.h b/include/asm-arm/arch-pxa/gpio.h
index 3d348a3..aeba2434 100644
--- a/include/asm-arm/arch-pxa/gpio.h
+++ b/include/asm-arm/arch-pxa/gpio.h
@@ -43,9 +43,9 @@
 	return pxa_gpio_mode(gpio | GPIO_IN);
 }
 
-static inline int gpio_direction_output(unsigned gpio)
+static inline int gpio_direction_output(unsigned gpio, int value)
 {
-	return pxa_gpio_mode(gpio | GPIO_OUT);
+	return pxa_gpio_mode(gpio | GPIO_OUT | (value ? 0 : GPIO_DFLT_LOW));
 }
 
 static inline int __gpio_get_value(unsigned gpio)
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index aec835b..139c9d9 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -1476,7 +1476,7 @@
 #define GPIO112_MMCCMD_MD	(112 | GPIO_ALT_FN_1_OUT)
 #define GPIO113_I2S_SYSCLK_MD	(113 | GPIO_ALT_FN_1_OUT)
 #define GPIO113_AC97_RESET_N_MD	(113 | GPIO_ALT_FN_2_OUT)
-#define GPIO117_I2CSCL_MD	(117 | GPIO_ALT_FN_1_OUT)
+#define GPIO117_I2CSCL_MD	(117 | GPIO_ALT_FN_1_IN)
 #define GPIO118_I2CSDA_MD	(118 | GPIO_ALT_FN_1_IN)
 
 /*
diff --git a/include/asm-arm/arch-s3c2410/gpio.h b/include/asm-arm/arch-s3c2410/gpio.h
index d47ae45..7583895 100644
--- a/include/asm-arm/arch-s3c2410/gpio.h
+++ b/include/asm-arm/arch-s3c2410/gpio.h
@@ -44,9 +44,11 @@
 	return 0;
 }
 
-static inline int gpio_direction_output(unsigned gpio)
+static inline int gpio_direction_output(unsigned gpio, int value)
 {
 	s3c2410_gpio_cfgpin(gpio, S3C2410_GPIO_OUTPUT);
+	/* REVISIT can we write the value first, to avoid glitching? */
+	s3c2410_gpio_setpin(gpio, value);
 	return 0;
 }
 
diff --git a/include/asm-arm/arch-sa1100/gpio.h b/include/asm-arm/arch-sa1100/gpio.h
index da7575b..e7a9d26 100644
--- a/include/asm-arm/arch-sa1100/gpio.h
+++ b/include/asm-arm/arch-sa1100/gpio.h
@@ -38,7 +38,7 @@
 }
 
 extern int gpio_direction_input(unsigned gpio);
-extern int gpio_direction_output(unsigned gpio);
+extern int gpio_direction_output(unsigned gpio, int value);
 
 
 static inline int gpio_get_value(unsigned gpio)
diff --git a/include/asm-arm/atomic.h b/include/asm-arm/atomic.h
index ea88aa6..f266c27 100644
--- a/include/asm-arm/atomic.h
+++ b/include/asm-arm/atomic.h
@@ -103,9 +103,9 @@
 	unsigned long tmp, tmp2;
 
 	__asm__ __volatile__("@ atomic_clear_mask\n"
-"1:	ldrex	%0, %2\n"
+"1:	ldrex	%0, [%2]\n"
 "	bic	%0, %0, %3\n"
-"	strex	%1, %0, %2\n"
+"	strex	%1, %0, [%2]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
 	: "=&r" (tmp), "=&r" (tmp2)
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
index f06d8a4..69134c7 100644
--- a/include/asm-arm/system.h
+++ b/include/asm-arm/system.h
@@ -3,6 +3,7 @@
 
 #ifdef __KERNEL__
 
+#include <asm/memory.h>
 
 #define CPU_ARCH_UNKNOWN	0
 #define CPU_ARCH_ARMv3		1
@@ -154,7 +155,7 @@
 #define vectors_high()	(0)
 #endif
 
-#if __LINUX_ARM_ARCH__ >= 6
+#if defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ >= 6
 #define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
 				    : : "r" (0) : "memory")
 #define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
@@ -168,22 +169,23 @@
 #define dmb() __asm__ __volatile__ ("" : : : "memory")
 #endif
 
-#define mb()			barrier()
-#define rmb()			barrier()
-#define wmb()			barrier()
-#define read_barrier_depends()	do { } while(0)
-
-#ifdef CONFIG_SMP
-#define smp_mb()		dmb()
-#define smp_rmb()		dmb()
-#define smp_wmb()		dmb()
-#define smp_read_barrier_depends()	read_barrier_depends()
+#ifndef CONFIG_SMP
+#define mb()	do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
+#define rmb()	do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
+#define wmb()	do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
+#define smp_mb()	barrier()
+#define smp_rmb()	barrier()
+#define smp_wmb()	barrier()
 #else
-#define smp_mb()		barrier()
-#define smp_rmb()		barrier()
-#define smp_wmb()		barrier()
-#define smp_read_barrier_depends()	read_barrier_depends()
-#endif /* CONFIG_SMP */
+#define mb()		dmb()
+#define rmb()		dmb()
+#define wmb()		dmb()
+#define smp_mb()	dmb()
+#define smp_rmb()	dmb()
+#define smp_wmb()	dmb()
+#endif
+#define read_barrier_depends()		do { } while(0)
+#define smp_read_barrier_depends()	do { } while(0)
 
 #define set_mb(var, value)	do { var = value; smp_mb(); } while (0)
 #define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
index 0991b7b..c025ab4 100644
--- a/include/asm-arm/unistd.h
+++ b/include/asm-arm/unistd.h
@@ -372,7 +372,7 @@
 #define __NR_move_pages			(__NR_SYSCALL_BASE+344)
 #define __NR_getcpu			(__NR_SYSCALL_BASE+345)
 					/* 346 for epoll_pwait */
-#define __NR_sys_kexec_load		(__NR_SYSCALL_BASE+347)
+#define __NR_kexec_load			(__NR_SYSCALL_BASE+347)
 
 /*
  * The following SWIs are ARM private.
diff --git a/include/asm-avr32/Kbuild b/include/asm-avr32/Kbuild
index 8770e73..3136628 100644
--- a/include/asm-avr32/Kbuild
+++ b/include/asm-avr32/Kbuild
@@ -1,3 +1,3 @@
 include include/asm-generic/Kbuild.asm
 
-headers-y	+= cachectl.h
+header-y	+= cachectl.h
diff --git a/include/asm-avr32/arch-at32ap/gpio.h b/include/asm-avr32/arch-at32ap/gpio.h
index fcb756b..80a21aa 100644
--- a/include/asm-avr32/arch-at32ap/gpio.h
+++ b/include/asm-avr32/arch-at32ap/gpio.h
@@ -10,7 +10,7 @@
 void gpio_free(unsigned int gpio);
 
 int gpio_direction_input(unsigned int gpio);
-int gpio_direction_output(unsigned int gpio);
+int gpio_direction_output(unsigned int gpio, int value);
 int gpio_get_value(unsigned int gpio);
 void gpio_set_value(unsigned int gpio, int value);
 
diff --git a/include/asm-avr32/dma-mapping.h b/include/asm-avr32/dma-mapping.h
index 115813e..21bb60b 100644
--- a/include/asm-avr32/dma-mapping.h
+++ b/include/asm-avr32/dma-mapping.h
@@ -274,6 +274,24 @@
 	dma_cache_sync(dev, bus_to_virt(dma_handle), size, direction);
 }
 
+static inline void
+dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
+			      unsigned long offset, size_t size,
+			      enum dma_data_direction direction)
+{
+	/* just sync everything, that's all the pci API can do */
+	dma_sync_single_for_cpu(dev, dma_handle, offset+size, direction);
+}
+
+static inline void
+dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
+				 unsigned long offset, size_t size,
+				 enum dma_data_direction direction)
+{
+	/* just sync everything, that's all the pci API can do */
+	dma_sync_single_for_device(dev, dma_handle, offset+size, direction);
+}
+
 /**
  * dma_sync_sg_for_cpu
  * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index 00c2343..6d7e279 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -180,6 +180,7 @@
 #ifndef __HAVE_ARCH_ENTER_LAZY_MMU_MODE
 #define arch_enter_lazy_mmu_mode()	do {} while (0)
 #define arch_leave_lazy_mmu_mode()	do {} while (0)
+#define arch_flush_lazy_mmu_mode()	do {} while (0)
 #endif
 
 /*
@@ -193,6 +194,7 @@
 #ifndef __HAVE_ARCH_ENTER_LAZY_CPU_MODE
 #define arch_enter_lazy_cpu_mode()	do {} while (0)
 #define arch_leave_lazy_cpu_mode()	do {} while (0)
+#define arch_flush_lazy_cpu_mode()	do {} while (0)
 #endif
 
 /*
diff --git a/include/asm-i386/apic.h b/include/asm-i386/apic.h
index cc6b165..a19810a 100644
--- a/include/asm-i386/apic.h
+++ b/include/asm-i386/apic.h
@@ -117,6 +117,7 @@
 #define ARCH_APICTIMER_STOPS_ON_C3	1
 
 extern int timer_over_8254;
+extern int local_apic_timer_c2_ok;
 
 #else /* !CONFIG_X86_LOCAL_APIC */
 static inline void lapic_shutdown(void) { }
diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h
index 3f92b94..d1b8e4a 100644
--- a/include/asm-i386/cpufeature.h
+++ b/include/asm-i386/cpufeature.h
@@ -75,6 +75,7 @@
 #define X86_FEATURE_ARCH_PERFMON (3*32+11) /* Intel Architectural PerfMon */
 #define X86_FEATURE_PEBS	(3*32+12)  /* Precise-Event Based Sampling */
 #define X86_FEATURE_BTS		(3*32+13)  /* Branch Trace Store */
+#define X86_FEATURE_LAPIC_TIMER_BROKEN (3*32+ 14) /* lapic timer broken in C1 */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3	(4*32+ 0) /* Streaming SIMD Extensions-3 */
diff --git a/include/asm-i386/elf.h b/include/asm-i386/elf.h
index 8d33c9b..952b3ee 100644
--- a/include/asm-i386/elf.h
+++ b/include/asm-i386/elf.h
@@ -88,16 +88,16 @@
 	pr_reg[4] = regs->edi;				\
 	pr_reg[5] = regs->ebp;				\
 	pr_reg[6] = regs->eax;				\
-	pr_reg[7] = regs->xds;				\
-	pr_reg[8] = regs->xes;				\
-	pr_reg[9] = regs->xfs;				\
+	pr_reg[7] = regs->xds & 0xffff;			\
+	pr_reg[8] = regs->xes & 0xffff;			\
+	pr_reg[9] = regs->xfs & 0xffff;			\
 	savesegment(gs,pr_reg[10]);			\
 	pr_reg[11] = regs->orig_eax;			\
 	pr_reg[12] = regs->eip;				\
-	pr_reg[13] = regs->xcs;				\
+	pr_reg[13] = regs->xcs & 0xffff;		\
 	pr_reg[14] = regs->eflags;			\
 	pr_reg[15] = regs->esp;				\
-	pr_reg[16] = regs->xss;
+	pr_reg[16] = regs->xss & 0xffff;
 
 /* This yields a mask that user programs can use to figure out what
    instruction set this CPU supports.  This could be done in user space,
diff --git a/include/asm-i386/msr.h b/include/asm-i386/msr.h
index ec3b680..2ad3f30 100644
--- a/include/asm-i386/msr.h
+++ b/include/asm-i386/msr.h
@@ -275,6 +275,8 @@
 #define MSR_K7_FID_VID_CTL		0xC0010041
 #define MSR_K7_FID_VID_STATUS		0xC0010042
 
+#define MSR_K8_ENABLE_C1E		0xC0010055
+
 /* extended feature register */
 #define MSR_EFER 			0xc0000080
 
diff --git a/include/asm-i386/nmi.h b/include/asm-i386/nmi.h
index 64544cb..b04333e 100644
--- a/include/asm-i386/nmi.h
+++ b/include/asm-i386/nmi.h
@@ -33,7 +33,7 @@
 
 extern atomic_t nmi_active;
 extern unsigned int nmi_watchdog;
-#define NMI_DEFAULT     0
+#define NMI_DEFAULT     -1
 #define NMI_NONE	0
 #define NMI_IO_APIC	1
 #define NMI_LOCAL_APIC	2
diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h
index f8319ca..e63f1e44 100644
--- a/include/asm-i386/paravirt.h
+++ b/include/asm-i386/paravirt.h
@@ -130,7 +130,7 @@
 	void (*flush_tlb_kernel)(void);
 	void (*flush_tlb_single)(u32 addr);
 
-	void (fastcall *map_pt_hook)(int type, pte_t *va, u32 pfn);
+	void (*map_pt_hook)(int type, pte_t *va, u32 pfn);
 
 	void (*alloc_pt)(u32 pfn);
 	void (*alloc_pd)(u32 pfn);
@@ -421,14 +421,17 @@
 #define PARAVIRT_LAZY_NONE 0
 #define PARAVIRT_LAZY_MMU  1
 #define PARAVIRT_LAZY_CPU  2
+#define PARAVIRT_LAZY_FLUSH 3
 
 #define  __HAVE_ARCH_ENTER_LAZY_CPU_MODE
 #define arch_enter_lazy_cpu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_CPU)
 #define arch_leave_lazy_cpu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_NONE)
+#define arch_flush_lazy_cpu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_FLUSH)
 
 #define  __HAVE_ARCH_ENTER_LAZY_MMU_MODE
 #define arch_enter_lazy_mmu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_MMU)
 #define arch_leave_lazy_mmu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_NONE)
+#define arch_flush_lazy_mmu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_FLUSH)
 
 /* These all sit in the .parainstructions section to tell us what to patch. */
 struct paravirt_patch {
diff --git a/include/asm-i386/sync_bitops.h b/include/asm-i386/sync_bitops.h
index c94d51c..7d72351 100644
--- a/include/asm-i386/sync_bitops.h
+++ b/include/asm-i386/sync_bitops.h
@@ -130,7 +130,7 @@
 	return oldbit;
 }
 
-static __always_inline int sync_const_test_bit(int nr, const volatile unsigned long *addr)
+static __always_inline int sync_constant_test_bit(int nr, const volatile unsigned long *addr)
 {
 	return ((1UL << (nr & 31)) &
 		(((const volatile unsigned int *)addr)[nr >> 5])) != 0;
diff --git a/include/asm-i386/termbits.h b/include/asm-i386/termbits.h
index 12baf1d..2e623769 100644
--- a/include/asm-i386/termbits.h
+++ b/include/asm-i386/termbits.h
@@ -144,7 +144,7 @@
 #define  B3000000 0010015
 #define  B3500000 0010016
 #define  B4000000 0010017
-#define CIBAUD	  002003600000	/* input baud rate (not used) */
+#define CIBAUD	  002003600000
 #define CMSPAR	  010000000000		/* mark or space (stick) parity */
 #define CRTSCTS	  020000000000		/* flow control */
 
diff --git a/include/asm-i386/vmi_time.h b/include/asm-i386/vmi_time.h
index 94d0a12..c3a1fcf 100644
--- a/include/asm-i386/vmi_time.h
+++ b/include/asm-i386/vmi_time.h
@@ -54,7 +54,7 @@
 
 #ifdef CONFIG_X86_LOCAL_APIC
 extern void __init vmi_timer_setup_boot_alarm(void);
-extern void __init vmi_timer_setup_secondary_alarm(void);
+extern void __devinit vmi_timer_setup_secondary_alarm(void);
 extern void apic_vmi_timer_interrupt(void);
 #endif
 
diff --git a/include/asm-ia64/kexec.h b/include/asm-ia64/kexec.h
index f2ad469..41299ddf 100644
--- a/include/asm-ia64/kexec.h
+++ b/include/asm-ia64/kexec.h
@@ -22,7 +22,6 @@
         } while(0)
 
 extern struct kimage *ia64_kimage;
-DECLARE_PER_CPU(u64, ia64_mca_pal_base);
 extern const unsigned int relocate_new_kernel_size;
 extern void relocate_new_kernel(unsigned long, unsigned long,
 		struct ia64_boot_param *, unsigned long);
diff --git a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h
index 3c96ac1..ca33eb1 100644
--- a/include/asm-ia64/machvec.h
+++ b/include/asm-ia64/machvec.h
@@ -168,6 +168,7 @@
 #  define platform_setup_msi_irq	ia64_mv.setup_msi_irq
 #  define platform_teardown_msi_irq	ia64_mv.teardown_msi_irq
 #  define platform_pci_fixup_bus	ia64_mv.pci_fixup_bus
+#  define platform_kernel_launch_event	ia64_mv.kernel_launch_event
 # endif
 
 /* __attribute__((__aligned__(16))) is required to make size of the
@@ -269,6 +270,7 @@
 	platform_setup_msi_irq,			\
 	platform_teardown_msi_irq,		\
 	platform_pci_fixup_bus,			\
+	platform_kernel_launch_event            \
 }
 
 extern struct ia64_machine_vector ia64_mv;
diff --git a/include/asm-ia64/mca.h b/include/asm-ia64/mca.h
index ee97f7c..41098f4 100644
--- a/include/asm-ia64/mca.h
+++ b/include/asm-ia64/mca.h
@@ -156,6 +156,8 @@
 	int *monarch_cpu;
 };
 
+DECLARE_PER_CPU(u64, ia64_mca_pal_base);
+
 #else	/* __ASSEMBLY__ */
 
 #define IA64_MCA_CORRECTED	0x0	/* Error has been corrected by OS_MCA */
diff --git a/include/asm-ia64/meminit.h b/include/asm-ia64/meminit.h
index 21ec5f3..3a62878 100644
--- a/include/asm-ia64/meminit.h
+++ b/include/asm-ia64/meminit.h
@@ -36,6 +36,7 @@
 extern void find_initrd (void);
 extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg);
 extern void efi_memmap_init(unsigned long *, unsigned long *);
+extern int find_max_min_low_pfn (unsigned long , unsigned long, void *);
 
 extern unsigned long vmcore_find_descriptor_size(unsigned long address);
 extern int reserve_elfcorehdr(unsigned long *start, unsigned long *end);
diff --git a/include/asm-ia64/pal.h b/include/asm-ia64/pal.h
index e43021a..67656ce 100644
--- a/include/asm-ia64/pal.h
+++ b/include/asm-ia64/pal.h
@@ -371,6 +371,7 @@
 							 * dependent
 							 */
 
+#define PAL_TLB_CHECK_OP_PURGE			8
 
 typedef struct pal_process_state_info_s {
 	u64		reserved1	: 2,
diff --git a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h
index 5160233..5a5d1c2 100644
--- a/include/asm-ia64/pci.h
+++ b/include/asm-ia64/pci.h
@@ -9,6 +9,7 @@
 
 #include <asm/io.h>
 #include <asm/scatterlist.h>
+#include <asm/hw_irq.h>
 
 /*
  * Can be used to override the logic in pci_scan_bus for skipping already-configured bus
@@ -170,7 +171,7 @@
 #define HAVE_ARCH_PCI_GET_LEGACY_IDE_IRQ
 static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 {
-	return channel ? 15 : 14;
+	return channel ? isa_irq_to_vector(15) : isa_irq_to_vector(14);
 }
 
 #endif /* _ASM_IA64_PCI_H */
diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h
index 5830d36..4f4ee1c 100644
--- a/include/asm-ia64/processor.h
+++ b/include/asm-ia64/processor.h
@@ -210,7 +210,7 @@
 	unsigned int a, b;
 };
 
-#define desc_empty(desc)		(!((desc)->a + (desc)->b))
+#define desc_empty(desc)		(!((desc)->a | (desc)->b))
 #define desc_equal(desc1, desc2)	(((desc1)->a == (desc2)->a) && ((desc1)->b == (desc2)->b))
 
 #define GDT_ENTRY_TLS_ENTRIES	3
diff --git a/include/asm-ia64/sal.h b/include/asm-ia64/sal.h
index d000689..46cadf5 100644
--- a/include/asm-ia64/sal.h
+++ b/include/asm-ia64/sal.h
@@ -847,12 +847,13 @@
  */
 struct sal_to_os_boot {
 	u64 rr[8];		/* Region Registers */
-	u64	br[6];		/* br0: return addr into SAL boot rendez routine */
+	u64 br[6];		/* br0:
+				 * return addr into SAL boot rendez routine */
 	u64 gr1;		/* SAL:GP */
 	u64 gr12;		/* SAL:SP */
 	u64 gr13;		/* SAL: Task Pointer */
 	u64 fpsr;
-	u64	pfs;
+	u64 pfs;
 	u64 rnat;
 	u64 unat;
 	u64 bspstore;
diff --git a/include/asm-ia64/sn/pcibr_provider.h b/include/asm-ia64/sn/pcibr_provider.h
index 17cb6cc..da205b7 100644
--- a/include/asm-ia64/sn/pcibr_provider.h
+++ b/include/asm-ia64/sn/pcibr_provider.h
@@ -21,6 +21,7 @@
 #define IS_PCI_BRIDGE_ASIC(asic) (asic == PCIIO_ASIC_TYPE_PIC || \
                 asic == PCIIO_ASIC_TYPE_TIOCP)
 #define IS_PIC_SOFT(ps)     (ps->pbi_bridge_type == PCIBR_BRIDGETYPE_PIC)
+#define IS_TIOCP_SOFT(ps)   (ps->pbi_bridge_type == PCIBR_BRIDGETYPE_TIOCP)
 
 
 /*
@@ -53,8 +54,8 @@
  * Bridge PMU Address Transaltion Entry Attibutes
  */
 #define PCI32_ATE_V                     (0x1 << 0)
-#define PCI32_ATE_CO                    (0x1 << 1)
-#define PCI32_ATE_PREC                  (0x1 << 2)
+#define PCI32_ATE_CO                    (0x1 << 1)	/* PIC ASIC ONLY */
+#define PCI32_ATE_PIO                   (0x1 << 1)	/* TIOCP ASIC ONLY */
 #define PCI32_ATE_MSI                   (0x1 << 2)
 #define PCI32_ATE_PREF                  (0x1 << 3)
 #define PCI32_ATE_BAR                   (0x1 << 4)
diff --git a/include/asm-ia64/unwind.h b/include/asm-ia64/unwind.h
index 5df0276..1af3875 100644
--- a/include/asm-ia64/unwind.h
+++ b/include/asm-ia64/unwind.h
@@ -81,7 +81,7 @@
 	struct unw_ireg {
 		unsigned long *loc;
 		struct unw_ireg_nat {
-			long type : 3;			/* enum unw_nat_type */
+			unsigned long type : 3;		/* enum unw_nat_type */
 			signed long off : 61;		/* NaT word is at loc+nat.off */
 		} nat;
 	} r4, r5, r6, r7;
diff --git a/include/asm-m32r/dma-mapping.h b/include/asm-m32r/dma-mapping.h
index a7fa030..f9b58eb 100644
--- a/include/asm-m32r/dma-mapping.h
+++ b/include/asm-m32r/dma-mapping.h
@@ -1,23 +1,6 @@
 #ifndef _ASM_M32R_DMA_MAPPING_H
 #define _ASM_M32R_DMA_MAPPING_H
 
-/*
- * NOTE: Do not include <asm-generic/dma-mapping.h>
- * Because it requires PCI stuffs, but current M32R don't provide these.
- */
-
-static inline void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
-		   gfp_t flag)
-{
-	return (void *)NULL;
-}
-
-static inline void
-dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
-		    dma_addr_t dma_handle)
-{
-	return;
-}
+#include <asm-generic/dma-mapping-broken.h>
 
 #endif /* _ASM_M32R_DMA_MAPPING_H */
diff --git a/include/asm-m68k/dma-mapping.h b/include/asm-m68k/dma-mapping.h
index 00259ed..a26cdeb 100644
--- a/include/asm-m68k/dma-mapping.h
+++ b/include/asm-m68k/dma-mapping.h
@@ -32,7 +32,7 @@
 			      void *, dma_addr_t);
 
 static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
-					  dma_addr_t *handle, int flag)
+					  dma_addr_t *handle, gfp_t flag)
 {
 	return dma_alloc_coherent(dev, size, handle, flag);
 }
diff --git a/include/asm-m68k/mc146818rtc.h b/include/asm-m68k/mc146818rtc.h
index 11fe12d..9f70a01 100644
--- a/include/asm-m68k/mc146818rtc.h
+++ b/include/asm-m68k/mc146818rtc.h
@@ -11,6 +11,7 @@
 #include <asm/atarihw.h>
 
 #define RTC_PORT(x)	(TT_RTC_BAS + 2*(x))
+#define RTC_ALWAYS_BCD	0
 
 #define CMOS_READ(addr) ({ \
 atari_outb_p((addr),RTC_PORT(0)); \
diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h
index 8578869..1ac50b6 100644
--- a/include/asm-mips/atomic.h
+++ b/include/asm-mips/atomic.h
@@ -79,9 +79,9 @@
 	} else {
 		unsigned long flags;
 
-		local_irq_save(flags);
+		raw_local_irq_save(flags);
 		v->counter += i;
-		local_irq_restore(flags);
+		raw_local_irq_restore(flags);
 	}
 }
 
@@ -124,9 +124,9 @@
 	} else {
 		unsigned long flags;
 
-		local_irq_save(flags);
+		raw_local_irq_save(flags);
 		v->counter -= i;
-		local_irq_restore(flags);
+		raw_local_irq_restore(flags);
 	}
 }
 
@@ -173,11 +173,11 @@
 	} else {
 		unsigned long flags;
 
-		local_irq_save(flags);
+		raw_local_irq_save(flags);
 		result = v->counter;
 		result += i;
 		v->counter = result;
-		local_irq_restore(flags);
+		raw_local_irq_restore(flags);
 	}
 
 	smp_mb();
@@ -225,11 +225,11 @@
 	} else {
 		unsigned long flags;
 
-		local_irq_save(flags);
+		raw_local_irq_save(flags);
 		result = v->counter;
 		result -= i;
 		v->counter = result;
-		local_irq_restore(flags);
+		raw_local_irq_restore(flags);
 	}
 
 	smp_mb();
@@ -293,12 +293,12 @@
 	} else {
 		unsigned long flags;
 
-		local_irq_save(flags);
+		raw_local_irq_save(flags);
 		result = v->counter;
 		result -= i;
 		if (result >= 0)
 			v->counter = result;
-		local_irq_restore(flags);
+		raw_local_irq_restore(flags);
 	}
 
 	smp_mb();
@@ -454,9 +454,9 @@
 	} else {
 		unsigned long flags;
 
-		local_irq_save(flags);
+		raw_local_irq_save(flags);
 		v->counter += i;
-		local_irq_restore(flags);
+		raw_local_irq_restore(flags);
 	}
 }
 
@@ -499,9 +499,9 @@
 	} else {
 		unsigned long flags;
 
-		local_irq_save(flags);
+		raw_local_irq_save(flags);
 		v->counter -= i;
-		local_irq_restore(flags);
+		raw_local_irq_restore(flags);
 	}
 }
 
@@ -548,11 +548,11 @@
 	} else {
 		unsigned long flags;
 
-		local_irq_save(flags);
+		raw_local_irq_save(flags);
 		result = v->counter;
 		result += i;
 		v->counter = result;
-		local_irq_restore(flags);
+		raw_local_irq_restore(flags);
 	}
 
 	smp_mb();
@@ -600,11 +600,11 @@
 	} else {
 		unsigned long flags;
 
-		local_irq_save(flags);
+		raw_local_irq_save(flags);
 		result = v->counter;
 		result -= i;
 		v->counter = result;
-		local_irq_restore(flags);
+		raw_local_irq_restore(flags);
 	}
 
 	smp_mb();
@@ -668,12 +668,12 @@
 	} else {
 		unsigned long flags;
 
-		local_irq_save(flags);
+		raw_local_irq_save(flags);
 		result = v->counter;
 		result -= i;
 		if (result >= 0)
 			v->counter = result;
-		local_irq_restore(flags);
+		raw_local_irq_restore(flags);
 	}
 
 	smp_mb();
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
index 8959da2..d995413 100644
--- a/include/asm-mips/bitops.h
+++ b/include/asm-mips/bitops.h
@@ -100,9 +100,9 @@
 
 		a += nr >> SZLONG_LOG;
 		mask = 1UL << bit;
-		local_irq_save(flags);
+		raw_local_irq_save(flags);
 		*a |= mask;
-		local_irq_restore(flags);
+		raw_local_irq_restore(flags);
 	}
 }
 
@@ -165,9 +165,9 @@
 
 		a += nr >> SZLONG_LOG;
 		mask = 1UL << bit;
-		local_irq_save(flags);
+		raw_local_irq_save(flags);
 		*a &= ~mask;
-		local_irq_restore(flags);
+		raw_local_irq_restore(flags);
 	}
 }
 
@@ -220,9 +220,9 @@
 
 		a += nr >> SZLONG_LOG;
 		mask = 1UL << bit;
-		local_irq_save(flags);
+		raw_local_irq_save(flags);
 		*a ^= mask;
-		local_irq_restore(flags);
+		raw_local_irq_restore(flags);
 	}
 }
 
@@ -287,10 +287,10 @@
 
 		a += nr >> SZLONG_LOG;
 		mask = 1UL << bit;
-		local_irq_save(flags);
+		raw_local_irq_save(flags);
 		retval = (mask & *a) != 0;
 		*a |= mask;
-		local_irq_restore(flags);
+		raw_local_irq_restore(flags);
 
 		return retval;
 	}
@@ -381,10 +381,10 @@
 
 		a += nr >> SZLONG_LOG;
 		mask = 1UL << bit;
-		local_irq_save(flags);
+		raw_local_irq_save(flags);
 		retval = (mask & *a) != 0;
 		*a &= ~mask;
-		local_irq_restore(flags);
+		raw_local_irq_restore(flags);
 
 		return retval;
 	}
@@ -452,10 +452,10 @@
 
 		a += nr >> SZLONG_LOG;
 		mask = 1UL << bit;
-		local_irq_save(flags);
+		raw_local_irq_save(flags);
 		retval = (mask & *a) != 0;
 		*a ^= mask;
-		local_irq_restore(flags);
+		raw_local_irq_restore(flags);
 
 		return retval;
 	}
diff --git a/include/asm-mips/cacheflush.h b/include/asm-mips/cacheflush.h
index 0ddada3..28d907d 100644
--- a/include/asm-mips/cacheflush.h
+++ b/include/asm-mips/cacheflush.h
@@ -48,6 +48,15 @@
 #define flush_dcache_mmap_lock(mapping)		do { } while (0)
 #define flush_dcache_mmap_unlock(mapping)	do { } while (0)
 
+#define ARCH_HAS_FLUSH_ANON_PAGE
+extern void __flush_anon_page(struct page *, unsigned long);
+static inline void flush_anon_page(struct vm_area_struct *vma,
+	struct page *page, unsigned long vmaddr)
+{
+	if (cpu_has_dc_aliases && PageAnon(page))
+		__flush_anon_page(page, vmaddr);
+}
+
 static inline void flush_icache_page(struct vm_area_struct *vma,
 	struct page *page)
 {
@@ -86,4 +95,7 @@
 /* Run kernel code uncached, useful for cache probing functions. */
 unsigned long __init run_uncached(void *func);
 
+extern void *kmap_coherent(struct page *page, unsigned long addr);
+extern void kunmap_coherent(struct page *page);
+
 #endif /* _ASM_CACHEFLUSH_H */
diff --git a/include/asm-mips/cpu-features.h b/include/asm-mips/cpu-features.h
index eadca26..5e4bed1 100644
--- a/include/asm-mips/cpu-features.h
+++ b/include/asm-mips/cpu-features.h
@@ -40,6 +40,9 @@
 #endif
 #ifndef cpu_has_fpu
 #define cpu_has_fpu		(current_cpu_data.options & MIPS_CPU_FPU)
+#define raw_cpu_has_fpu		(raw_current_cpu_data.options & MIPS_CPU_FPU)
+#else
+#define raw_cpu_has_fpu		cpu_has_fpu
 #endif
 #ifndef cpu_has_32fpr
 #define cpu_has_32fpr		(cpu_data[0].options & MIPS_CPU_32FPR)
diff --git a/include/asm-mips/cpu-info.h b/include/asm-mips/cpu-info.h
index 610d0cd..22fe845 100644
--- a/include/asm-mips/cpu-info.h
+++ b/include/asm-mips/cpu-info.h
@@ -87,6 +87,7 @@
 
 extern struct cpuinfo_mips cpu_data[];
 #define current_cpu_data cpu_data[smp_processor_id()]
+#define raw_current_cpu_data cpu_data[raw_smp_processor_id()]
 
 extern void cpu_probe(void);
 extern void cpu_report(void);
diff --git a/include/asm-mips/delay.h b/include/asm-mips/delay.h
index ea77050..223d156 100644
--- a/include/asm-mips/delay.h
+++ b/include/asm-mips/delay.h
@@ -79,7 +79,7 @@
 	__delay(usecs);
 }
 
-#define __udelay_val cpu_data[smp_processor_id()].udelay_val
+#define __udelay_val cpu_data[raw_smp_processor_id()].udelay_val
 
 #define udelay(usecs) __udelay((usecs),__udelay_val)
 
diff --git a/include/asm-mips/dma.h b/include/asm-mips/dma.h
index e06ef07..833437d 100644
--- a/include/asm-mips/dma.h
+++ b/include/asm-mips/dma.h
@@ -74,7 +74,7 @@
  *
  */
 
-#ifndef GENERIC_ISA_DMA_SUPPORT_BROKEN
+#ifndef CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN
 #define MAX_DMA_CHANNELS	8
 #endif
 
diff --git a/include/asm-mips/fpu.h b/include/asm-mips/fpu.h
index efef843..4e12d1f 100644
--- a/include/asm-mips/fpu.h
+++ b/include/asm-mips/fpu.h
@@ -27,11 +27,11 @@
 struct sigcontext;
 struct sigcontext32;
 
-extern asmlinkage int (*save_fp_context)(struct sigcontext *sc);
-extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc);
+extern asmlinkage int (*save_fp_context)(struct sigcontext __user *sc);
+extern asmlinkage int (*restore_fp_context)(struct sigcontext __user *sc);
 
-extern asmlinkage int (*save_fp_context32)(struct sigcontext32 *sc);
-extern asmlinkage int (*restore_fp_context32)(struct sigcontext32 *sc);
+extern asmlinkage int (*save_fp_context32)(struct sigcontext32 __user *sc);
+extern asmlinkage int (*restore_fp_context32)(struct sigcontext32 __user *sc);
 
 extern void fpu_emulator_init_fpu(void);
 extern void _init_fpu(void);
@@ -68,6 +68,8 @@
 	/* We don't care about the c0 hazard here  */			\
 } while (0)
 
+#define __fpu_enabled()	(read_c0_status() & ST0_CU1)
+
 #define enable_fpu()							\
 do {									\
 	if (cpu_has_fpu)						\
@@ -93,31 +95,47 @@
 	return cpu_has_fpu && __is_fpu_owner();
 }
 
-static inline void own_fpu(void)
+static inline void __own_fpu(void)
 {
-	if (cpu_has_fpu) {
-		__enable_fpu();
-		KSTK_STATUS(current) |= ST0_CU1;
-		set_thread_flag(TIF_USEDFPU);
-	}
+	__enable_fpu();
+	KSTK_STATUS(current) |= ST0_CU1;
+	set_thread_flag(TIF_USEDFPU);
 }
 
-static inline void lose_fpu(void)
+static inline void own_fpu(int restore)
 {
-	if (cpu_has_fpu) {
+	preempt_disable();
+	if (cpu_has_fpu && !__is_fpu_owner()) {
+		__own_fpu();
+		if (restore)
+			_restore_fp(current);
+	}
+	preempt_enable();
+}
+
+static inline void lose_fpu(int save)
+{
+	preempt_disable();
+	if (is_fpu_owner()) {
+		if (save)
+			_save_fp(current);
 		KSTK_STATUS(current) &= ~ST0_CU1;
 		clear_thread_flag(TIF_USEDFPU);
 		__disable_fpu();
 	}
+	preempt_enable();
 }
 
 static inline void init_fpu(void)
 {
+	preempt_disable();
 	if (cpu_has_fpu) {
+		__own_fpu();
 		_init_fpu();
 	} else {
 		fpu_emulator_init_fpu();
 	}
+	preempt_enable();
 }
 
 static inline void save_fp(struct task_struct *tsk)
@@ -144,4 +162,18 @@
 	return tsk->thread.fpu.fpr;
 }
 
+static inline void enable_fp_in_kernel(void)
+{
+	set_thread_flag(TIF_ALLOW_FP_IN_KERNEL);
+	/* make sure CU1 and FPU ownership are consistent */
+	if (!__is_fpu_owner() && __fpu_enabled())
+		__disable_fpu();
+}
+
+static inline void disable_fp_in_kernel(void)
+{
+	BUG_ON(!__is_fpu_owner() && __fpu_enabled());
+	clear_thread_flag(TIF_ALLOW_FP_IN_KERNEL);
+}
+
 #endif /* _ASM_FPU_H */
diff --git a/include/asm-mips/hazards.h b/include/asm-mips/hazards.h
index 5007315..e50c77e 100644
--- a/include/asm-mips/hazards.h
+++ b/include/asm-mips/hazards.h
@@ -52,6 +52,7 @@
 	 _ehb
 	)
 ASMMACRO(irq_enable_hazard,
+	 _ehb
 	)
 ASMMACRO(irq_disable_hazard,
 	_ehb
diff --git a/include/asm-mips/irqflags.h b/include/asm-mips/irqflags.h
index af3b07d..e459fa0 100644
--- a/include/asm-mips/irqflags.h
+++ b/include/asm-mips/irqflags.h
@@ -13,29 +13,9 @@
 
 #ifndef __ASSEMBLY__
 
+#include <linux/compiler.h>
 #include <asm/hazards.h>
 
-/*
- * CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY does prompt replay of deferred IPIs,
- * at the cost of branch and call overhead on each local_irq_restore()
- */
-
-#ifdef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY
-
-extern void smtc_ipi_replay(void);
-
-#define irq_restore_epilog(flags)				\
-do {								\
-	if (!(flags & 0x0400))					\
-		smtc_ipi_replay();				\
-} while (0)
-
-#else
-
-#define irq_restore_epilog(ignore) do { } while (0)
-
-#endif /* CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY */
-
 __asm__ (
 	"	.macro	raw_local_irq_enable				\n"
 	"	.set	push						\n"
@@ -205,17 +185,28 @@
 	"	.set	pop						\n"
 	"	.endm							\n");
 
-#define raw_local_irq_restore(flags)					\
-do {									\
-	unsigned long __tmp1;						\
-									\
-	__asm__ __volatile__(						\
-		"raw_local_irq_restore\t%0"				\
-		: "=r" (__tmp1)						\
-		: "0" (flags)						\
-		: "memory");						\
-	irq_restore_epilog(flags);					\
-} while(0)
+extern void smtc_ipi_replay(void);
+
+static inline void raw_local_irq_restore(unsigned long flags)
+{
+	unsigned long __tmp1;
+
+#ifdef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY
+	/*
+	 * CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY does prompt replay of deferred
+	 * IPIs, at the cost of branch and call overhead on each
+	 * local_irq_restore()
+	 */
+	if (unlikely(!(flags & 0x0400)))
+		smtc_ipi_replay();
+#endif
+
+	__asm__ __volatile__(
+		"raw_local_irq_restore\t%0"
+		: "=r" (__tmp1)
+		: "0" (flags)
+		: "memory");
+}
 
 static inline int raw_irqs_disabled_flags(unsigned long flags)
 {
diff --git a/include/asm-mips/mach-au1x00/au1xxx_ide.h b/include/asm-mips/mach-au1x00/au1xxx_ide.h
index e9fa252..8fcae21 100644
--- a/include/asm-mips/mach-au1x00/au1xxx_ide.h
+++ b/include/asm-mips/mach-au1x00/au1xxx_ide.h
@@ -141,40 +141,6 @@
 static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif);
 int __init auide_probe(void);
 
-#ifdef CONFIG_PM
-        int au1200ide_pm_callback( au1xxx_power_dev_t *dev,
-                                   au1xxx_request_t request, void *data);
-        static int au1xxxide_pm_standby( au1xxx_power_dev_t *dev );
-        static int au1xxxide_pm_sleep( au1xxx_power_dev_t *dev );
-        static int au1xxxide_pm_resume( au1xxx_power_dev_t *dev );
-        static int au1xxxide_pm_getstatus( au1xxx_power_dev_t *dev );
-        static int au1xxxide_pm_access( au1xxx_power_dev_t *dev );
-        static int au1xxxide_pm_idle( au1xxx_power_dev_t *dev );
-        static int au1xxxide_pm_cleanup( au1xxx_power_dev_t *dev );
-#endif
-
-
-/*
- * Multi-Word DMA + DbDMA functions
- */
-#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-        static int auide_build_sglist(ide_drive_t *drive,  struct request *rq);
-        static int auide_build_dmatable(ide_drive_t *drive);
-        static int auide_dma_end(ide_drive_t *drive);
-        ide_startstop_t auide_dma_intr (ide_drive_t *drive);
-        static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command);
-        static int auide_dma_setup(ide_drive_t *drive);
-        static int auide_dma_check(ide_drive_t *drive);
-        static int auide_dma_test_irq(ide_drive_t *drive);
-        static int auide_dma_host_off(ide_drive_t *drive);
-        static int auide_dma_host_on(ide_drive_t *drive);
-        static int auide_dma_lostirq(ide_drive_t *drive);
-        static int auide_dma_on(ide_drive_t *drive);
-        static void auide_ddma_tx_callback(int irq, void *param);
-        static void auide_ddma_rx_callback(int irq, void *param);
-        static int auide_dma_off_quietly(ide_drive_t *drive);
-#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
-
 /*******************************************************************************
 * PIO Mode timing calculation :                                                *
 *                                                                              *
diff --git a/include/asm-mips/mach-ip27/dma-coherence.h b/include/asm-mips/mach-ip27/dma-coherence.h
index 659816e..3fdbbf6 100644
--- a/include/asm-mips/mach-ip27/dma-coherence.h
+++ b/include/asm-mips/mach-ip27/dma-coherence.h
@@ -18,7 +18,8 @@
 
 struct device;
 
-static dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
+static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
+	size_t size)
 {
 	dma_addr_t pa = dev_to_baddr(dev, virt_to_phys(addr));
 
@@ -37,7 +38,7 @@
 	return dma_addr & (0xffUL << 56);
 }
 
-static void plat_unmap_dma_mem(dma_addr_t dma_addr)
+static inline void plat_unmap_dma_mem(dma_addr_t dma_addr)
 {
 }
 
diff --git a/include/asm-mips/mach-ip32/dma-coherence.h b/include/asm-mips/mach-ip32/dma-coherence.h
index 950be17..c3f9a6a 100644
--- a/include/asm-mips/mach-ip32/dma-coherence.h
+++ b/include/asm-mips/mach-ip32/dma-coherence.h
@@ -26,7 +26,8 @@
 
 #define RAM_OFFSET_MASK 0x3fffffffUL
 
-static dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
+static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
+	size_t size)
 {
 	dma_addr_t pa = virt_to_phys(addr) & RAM_OFFSET_MASK;
 
@@ -59,7 +60,7 @@
 	return addr;
 }
 
-static void plat_unmap_dma_mem(dma_addr_t dma_addr)
+static inline void plat_unmap_dma_mem(dma_addr_t dma_addr)
 {
 }
 
diff --git a/include/asm-mips/marvell.h b/include/asm-mips/marvell.h
index df94955..b6144ba 100644
--- a/include/asm-mips/marvell.h
+++ b/include/asm-mips/marvell.h
@@ -54,5 +54,6 @@
 };
 
 extern void ll_mv64340_irq(void);
+extern void mv64340_irq_init(unsigned int base);
 
 #endif	/* __ASM_MIPS_MARVELL_H */
diff --git a/include/asm-mips/pgtable-64.h b/include/asm-mips/pgtable-64.h
index a5b1871..49f5a1a 100644
--- a/include/asm-mips/pgtable-64.h
+++ b/include/asm-mips/pgtable-64.h
@@ -199,7 +199,7 @@
 {
 	return pud_val(pud);
 }
-#define pud_phys(pud)		(pud_val(pud) - PAGE_OFFSET)
+#define pud_phys(pud)		virt_to_phys((void *)pud_val(pud))
 #define pud_page(pud)		(pfn_to_page(pud_phys(pud) >> PAGE_SHIFT))
 
 /* Find an entry in the second-level page table.. */
diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h
index 3fcfd79..0d3295f 100644
--- a/include/asm-mips/pgtable.h
+++ b/include/asm-mips/pgtable.h
@@ -75,7 +75,7 @@
  * Conversion functions: convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
  */
-#define pmd_phys(pmd)		(pmd_val(pmd) - PAGE_OFFSET)
+#define pmd_phys(pmd)		virt_to_phys((void *)pmd_val(pmd))
 #define pmd_page(pmd)		(pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT))
 #define pmd_page_vaddr(pmd)	pmd_val(pmd)
 
diff --git a/include/asm-mips/rtlx.h b/include/asm-mips/rtlx.h
index 59162f7..65778c8 100644
--- a/include/asm-mips/rtlx.h
+++ b/include/asm-mips/rtlx.h
@@ -23,8 +23,8 @@
 
 extern int rtlx_open(int index, int can_sleep);
 extern int rtlx_release(int index);
-extern ssize_t rtlx_read(int index, void *buff, size_t count, int user);
-extern ssize_t rtlx_write(int index, void *buffer, size_t count, int user);
+extern ssize_t rtlx_read(int index, void __user *buff, size_t count);
+extern ssize_t rtlx_write(int index, const void __user *buffer, size_t count);
 extern unsigned int rtlx_read_poll(int index, int can_sleep);
 extern unsigned int rtlx_write_poll(int index);
 
diff --git a/include/asm-mips/sgiarcs.h b/include/asm-mips/sgiarcs.h
index ddb859d..439bce7 100644
--- a/include/asm-mips/sgiarcs.h
+++ b/include/asm-mips/sgiarcs.h
@@ -459,7 +459,7 @@
 	register signed int __a2 __asm__("$5") = (int) (long) (a2);	\
 	register signed int __a3 __asm__("$6") = (int) (long) (a3);	\
 	register signed int __a4 __asm__("$7") = (int) (long) (a4);	\
-	register signed int __a5 = (a5);				\
+	register signed int __a5 = (int) (long) (a5);			\
 	long __vec = (long) romvec->dest;				\
 	__asm__ __volatile__(						\
 	"dsubu\t$29, 32\n\t"						\
diff --git a/include/asm-mips/sibyte/sb1250.h b/include/asm-mips/sibyte/sb1250.h
index dfb29e1..494aa65 100644
--- a/include/asm-mips/sibyte/sb1250.h
+++ b/include/asm-mips/sibyte/sb1250.h
@@ -67,6 +67,6 @@
 
 #endif
 
-#define IOADDR(a) ((volatile void __iomem *)(IO_BASE + (a)))
+#define IOADDR(a) ((void __iomem *)(IO_BASE + (a)))
 
 #endif
diff --git a/include/asm-mips/sibyte/trace_prof.h b/include/asm-mips/sibyte/trace_prof.h
deleted file mode 100644
index 5577920..0000000
--- a/include/asm-mips/sibyte/trace_prof.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2001 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#ifndef __ASM_SIBYTE_TRACE_PROF_H
-#define __ASM_SIBYTE_TRACE_PROF_H
-
-#undef DBG
-#if SBPROF_TB_DEBUG
-#define DBG(a) a
-#else
-#define DBG(a)
-#endif
-
-#define SBPROF_TB_MAJOR 240
-#define DEVNAME "bcm1250_tbprof"
-
-typedef u_int64_t tb_sample_t[6*256];
-
-struct sbprof_tb {
-	int          open;
-	tb_sample_t *sbprof_tbbuf;
-	int          next_tb_sample;
-
-	volatile int tb_enable;
-	volatile int tb_armed;
-
-	wait_queue_head_t tb_sync;
-	wait_queue_head_t tb_read;
-};
-
-#define MAX_SAMPLE_BYTES (24*1024*1024)
-#define MAX_TBSAMPLE_BYTES (12*1024*1024)
-
-#define MAX_SAMPLES (MAX_SAMPLE_BYTES/sizeof(u_int32_t))
-#define TB_SAMPLE_SIZE (sizeof(tb_sample_t))
-#define MAX_TB_SAMPLES (MAX_TBSAMPLE_BYTES/TB_SAMPLE_SIZE)
-
-/* IOCTLs */
-#define SBPROF_ZBSTART		_IOW('s', 0, int)
-#define SBPROF_ZBSTOP		_IOW('s', 1, int)
-#define SBPROF_ZBWAITFULL	_IOW('s', 2, int)
-
-/***************************************************************************
- * Routines for gathering ZBbus profiles using trace buffer
- ***************************************************************************/
-
-/* Requires: Already called zclk_timer_init with a value that won't
-	     saturate 40 bits.  No subsequent use of SCD performance counters
-	     or trace buffer.
-   Effect:   Starts gathering random ZBbus profiles using trace buffer. */
-extern int sbprof_zbprof_start(struct file *filp);
-
-/* Effect: Stops collection of ZBbus profiles */
-extern int sbprof_zbprof_stop(void);
-
-
-/***************************************************************************
- * Routines for using 40-bit SCD cycle counter
- *
- * Client responsible for either handling interrupts or making sure
- * the cycles counter never saturates, e.g., by doing
- * zclk_timer_init(0) at least every 2^40 - 1 ZCLKs.
- ***************************************************************************/
-
-/* Configures SCD counter 0 to count ZCLKs starting from val;
-   Configures SCD counters1,2,3 to count nothing.
-   Must not be called while gathering ZBbus profiles.
-
-unsigned long long val; */
-#define zclk_timer_init(val) \
-  __asm__ __volatile__ (".set push;" \
-			".set mips64;" \
-			"la   $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \
-			"sd   %0, 0x10($8);"   /* write val to counter0 */ \
-			"sd   %1, 0($8);"      /* config counter0 for zclks*/ \
-			".set pop" \
-			: /* no outputs */ \
-						     /* enable, counter0 */ \
-			: /* inputs */ "r"(val), "r" ((1ULL << 33) | 1ULL) \
-			: /* modifies */ "$8" )
-
-
-/* Reads SCD counter 0 and puts result in value
-   unsigned long long val; */
-#define zclk_get(val) \
-  __asm__ __volatile__ (".set push;" \
-			".set mips64;" \
-			"la   $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \
-			"ld   %0, 0x10($8);"   /* write val to counter0 */ \
-			".set pop" \
-			: /* outputs */ "=r"(val) \
-			: /* inputs */ \
-			: /* modifies */ "$8" )
-
-#endif /* __ASM_SIBYTE_TRACE_PROF_H */
diff --git a/include/asm-mips/smtc_ipi.h b/include/asm-mips/smtc_ipi.h
index 360ea6d..a52a4a7 100644
--- a/include/asm-mips/smtc_ipi.h
+++ b/include/asm-mips/smtc_ipi.h
@@ -65,12 +65,10 @@
 	spin_unlock_irqrestore(&q->lock, flags);
 }
 
-static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q)
+static inline struct smtc_ipi *__smtc_ipi_dq(struct smtc_ipi_q *q)
 {
 	struct smtc_ipi *p;
-	long flags;
 
-	spin_lock_irqsave(&q->lock, flags);
 	if (q->head == NULL)
 		p = NULL;
 	else {
@@ -81,7 +79,19 @@
 		if (q->head == NULL)
 			q->tail = NULL;
 	}
+
+	return p;
+}
+
+static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q)
+{
+	unsigned long flags;
+	struct smtc_ipi *p;
+
+	spin_lock_irqsave(&q->lock, flags);
+	p = __smtc_ipi_dq(q);
 	spin_unlock_irqrestore(&q->lock, flags);
+
 	return p;
 }
 
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index 597a374..2908870 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -121,10 +121,10 @@
 	} else {
 		unsigned long flags;
 
-		local_irq_save(flags);
+		raw_local_irq_save(flags);
 		retval = *m;
 		*m = val;
-		local_irq_restore(flags);	/* implies memory barrier  */
+		raw_local_irq_restore(flags);	/* implies memory barrier  */
 	}
 
 	smp_mb();
@@ -169,10 +169,10 @@
 	} else {
 		unsigned long flags;
 
-		local_irq_save(flags);
+		raw_local_irq_save(flags);
 		retval = *m;
 		*m = val;
-		local_irq_restore(flags);	/* implies memory barrier  */
+		raw_local_irq_restore(flags);	/* implies memory barrier  */
 	}
 
 	smp_mb();
@@ -250,11 +250,11 @@
 	} else {
 		unsigned long flags;
 
-		local_irq_save(flags);
+		raw_local_irq_save(flags);
 		retval = *m;
 		if (retval == old)
 			*m = new;
-		local_irq_restore(flags);	/* implies memory barrier  */
+		raw_local_irq_restore(flags);	/* implies memory barrier  */
 	}
 
 	smp_mb();
@@ -304,11 +304,11 @@
 	} else {
 		unsigned long flags;
 
-		local_irq_save(flags);
+		raw_local_irq_save(flags);
 		retval = *m;
 		if (retval == old)
 			*m = new;
-		local_irq_restore(flags);	/* implies memory barrier  */
+		raw_local_irq_restore(flags);	/* implies memory barrier  */
 	}
 
 	smp_mb();
diff --git a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h
index fbcda82..6cf05f4 100644
--- a/include/asm-mips/thread_info.h
+++ b/include/asm-mips/thread_info.h
@@ -119,6 +119,7 @@
 #define TIF_POLLING_NRFLAG	17	/* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE		18
 #define TIF_FREEZE		19
+#define TIF_ALLOW_FP_IN_KERNEL	20
 #define TIF_SYSCALL_TRACE	31	/* syscall trace active */
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
diff --git a/include/asm-powerpc/floppy.h b/include/asm-powerpc/floppy.h
index a0f14ee..afa700d 100644
--- a/include/asm-powerpc/floppy.h
+++ b/include/asm-powerpc/floppy.h
@@ -178,7 +178,7 @@
 	._dma_setup = vdma_dma_setup
 };
 
-static int fd_request_dma()
+static int fd_request_dma(void)
 {
 	if (can_use_virtual_dma & 1) {
 		fd_ops = &virt_dma_ops;
diff --git a/include/asm-powerpc/hvcall.h b/include/asm-powerpc/hvcall.h
index 6097780..62efd9d 100644
--- a/include/asm-powerpc/hvcall.h
+++ b/include/asm-powerpc/hvcall.h
@@ -237,6 +237,20 @@
 long plpar_hcall(unsigned long opcode, unsigned long *retbuf, ...);
 
 /**
+ * plpar_hcall_raw: - Make a hypervisor call without calculating hcall stats
+ * @opcode: The hypervisor call to make.
+ * @retbuf: Buffer to store up to 4 return arguments in.
+ *
+ * This call supports up to 6 arguments and 4 return arguments. Use
+ * PLPAR_HCALL_BUFSIZE to size the return argument buffer.
+ *
+ * Used when phyp interface needs to be called in real mode. Similar to
+ * plpar_hcall, but plpar_hcall_raw works in real mode and does not
+ * calculate hypervisor call statistics.
+ */
+long plpar_hcall_raw(unsigned long opcode, unsigned long *retbuf, ...);
+
+/**
  * plpar_hcall9: - Make a pseries hypervisor call with up to 9 return arguments
  * @opcode: The hypervisor call to make.
  * @retbuf: Buffer to store up to 9 return arguments in.
diff --git a/include/asm-powerpc/immap_qe.h b/include/asm-powerpc/immap_qe.h
index 9fdd049..1020b7f 100644
--- a/include/asm-powerpc/immap_qe.h
+++ b/include/asm-powerpc/immap_qe.h
@@ -258,8 +258,9 @@
 	u8	uccs;		/* UCCx status register */
 	u8	res3[0x24];
 	__be16	utpt;
+	u8	res4[0x52];
 	u8	guemr;		/* UCC general extended mode register */
-	u8	res4[0x200 - 0x091];
+	u8	res5[0x200 - 0x091];
 } __attribute__ ((packed));
 
 /* QE UCC Fast */
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h
index 0f9f2dd2..31d5054 100644
--- a/include/asm-powerpc/spu.h
+++ b/include/asm-powerpc/spu.h
@@ -165,6 +165,13 @@
 int spu_irq_class_1_bottom(struct spu *spu);
 void spu_irq_setaffinity(struct spu *spu, int cpu);
 
+extern void spu_invalidate_slbs(struct spu *spu);
+extern void spu_associate_mm(struct spu *spu, struct mm_struct *mm);
+
+/* Calls from the memory management to the SPU */
+struct mm_struct;
+extern void spu_flush_all_slbs(struct mm_struct *mm);
+
 /* system callbacks from the SPU */
 struct spu_syscall_block {
 	u64 nr_ret;
diff --git a/include/asm-powerpc/spu_csa.h b/include/asm-powerpc/spu_csa.h
index bdbf906..8aad061 100644
--- a/include/asm-powerpc/spu_csa.h
+++ b/include/asm-powerpc/spu_csa.h
@@ -221,8 +221,6 @@
  * @spu_chnlcnt_RW: Array of saved channel counts.
  * @spu_chnldata_RW: Array of saved channel data.
  * @suspend_time: Time stamp when decrementer disabled.
- * @slb_esid_RW: Array of saved SLB esid entries.
- * @slb_vsid_RW: Array of saved SLB vsid entries.
  *
  * Structure representing the whole of the SPU
  * context save area (CSA).  This struct contains
@@ -245,8 +243,6 @@
 	u32 spu_mailbox_data[4];
 	u32 pu_mailbox_data[1];
 	unsigned long suspend_time;
-	u64 slb_esid_RW[8];
-	u64 slb_vsid_RW[8];
 	spinlock_t register_lock;
 };
 
diff --git a/include/asm-powerpc/systbl.h b/include/asm-powerpc/systbl.h
index 418e5c7..8d853c5 100644
--- a/include/asm-powerpc/systbl.h
+++ b/include/asm-powerpc/systbl.h
@@ -304,5 +304,6 @@
 SYSCALL_SPU(faccessat)
 COMPAT_SYS_SPU(get_robust_list)
 COMPAT_SYS_SPU(set_robust_list)
-COMPAT_SYS(move_pages)
+COMPAT_SYS_SPU(move_pages)
 SYSCALL_SPU(getcpu)
+COMPAT_SYS(epoll_pwait)
diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h
index bcc21bf..2baedbe 100644
--- a/include/asm-powerpc/unistd.h
+++ b/include/asm-powerpc/unistd.h
@@ -325,10 +325,11 @@
 #define __NR_set_robust_list	300
 #define __NR_move_pages		301
 #define __NR_getcpu		302
+#define __NR_epoll_pwait	303
 
 #ifdef __KERNEL__
 
-#define __NR_syscalls		303
+#define __NR_syscalls		304
 
 #define __NR__exit __NR_exit
 #define NR_syscalls	__NR_syscalls
diff --git a/include/asm-s390/checksum.h b/include/asm-s390/checksum.h
index 0a3cd7e..d5a8e7c 100644
--- a/include/asm-s390/checksum.h
+++ b/include/asm-s390/checksum.h
@@ -121,50 +121,21 @@
                    unsigned short len, unsigned short proto,
                    __wsum sum)
 {
-#ifndef __s390x__
-	asm volatile(
-		"	alr	%0,%1\n" /* sum += saddr */
-		"	brc	12,0f\n"
-		"	ahi	%0,1\n"  /* add carry */
-		"0:"
-		: "+&d" (sum) : "d" (saddr) : "cc");
-	asm volatile(
-		"	alr	%0,%1\n" /* sum += daddr */
-		"	brc	12,1f\n"
-		"	ahi	%0,1\n"  /* add carry */
-		"1:"
-		: "+&d" (sum) : "d" (daddr) : "cc");
-	asm volatile(
-		"	alr	%0,%1\n" /* sum += len + proto */
-		"	brc	12,2f\n"
-		"	ahi	%0,1\n"  /* add carry */
-		"2:"
-		: "+&d" (sum)
-		: "d" (len + proto)
-		: "cc");
-#else /* __s390x__ */
-	asm volatile(
-		"	lgfr	%0,%0\n"
-		"	algr	%0,%1\n"  /* sum += saddr */
-		"	brc	12,0f\n"
-		"	aghi	%0,1\n"   /* add carry */
-		"0:	algr	%0,%2\n"  /* sum += daddr */
-		"	brc	12,1f\n"
-		"	aghi	%0,1\n"   /* add carry */
-		"1:	algfr	%0,%3\n"  /* sum += len + proto */
-		"	brc	12,2f\n"
-		"	aghi	%0,1\n"   /* add carry */
-		"2:	srlg	0,%0,32\n"
-		"	alr	%0,0\n"   /* fold to 32 bits */
-		"	brc	12,3f\n"
-		"	ahi	%0,1\n"   /* add carry */
-		"3:	llgfr	%0,%0"
-		: "+&d" (sum)
-		: "d" (saddr), "d" (daddr),
-		  "d" (len + proto)
-		: "cc", "0");
-#endif /* __s390x__ */
-	return sum;
+	__u32 csum = (__force __u32)sum;
+
+	csum += (__force __u32)saddr;
+	if (csum < (__force __u32)saddr)
+		csum++;
+
+	csum += (__force __u32)daddr;
+	if (csum < (__force __u32)daddr)
+		csum++;
+
+	csum += len + proto;
+	if (csum < len + proto)
+		csum++;
+
+	return (__force __wsum)csum;
 }
 
 /*
diff --git a/include/asm-s390/ipl.h b/include/asm-s390/ipl.h
index 660f782..0eb6408 100644
--- a/include/asm-s390/ipl.h
+++ b/include/asm-s390/ipl.h
@@ -14,9 +14,13 @@
 #define IPL_PARM_BLK_FCP_LEN (sizeof(struct ipl_list_hdr) + \
 			      sizeof(struct ipl_block_fcp))
 
+#define IPL_PARM_BLK0_FCP_LEN (sizeof(struct ipl_block_fcp) + 8)
+
 #define IPL_PARM_BLK_CCW_LEN (sizeof(struct ipl_list_hdr) + \
 			      sizeof(struct ipl_block_ccw))
 
+#define IPL_PARM_BLK0_CCW_LEN (sizeof(struct ipl_block_ccw) + 8)
+
 #define IPL_MAX_SUPPORTED_VERSION (0)
 
 #define IPL_PARMBLOCK_START	((struct ipl_parameter_block *) \
@@ -58,6 +62,7 @@
 	u8  vm_flags;
 	u8  reserved3[3];
 	u32 vm_parm_len;
+	u8  reserved4[80];
 } __attribute__((packed));
 
 struct ipl_parameter_block {
diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h
index fb6fef9..5c6f00d 100644
--- a/include/asm-s390/unistd.h
+++ b/include/asm-s390/unistd.h
@@ -250,8 +250,9 @@
 /* Number 310 is reserved for new sys_move_pages */
 #define __NR_getcpu		311
 #define __NR_epoll_pwait	312
+#define __NR_utimes		313
 
-#define NR_syscalls 313
+#define NR_syscalls 314
 
 /* 
  * There are some system calls that are not present on 64 bit, some
diff --git a/include/asm-sh/cache.h b/include/asm-sh/cache.h
index e3a180c..9a3cb6b 100644
--- a/include/asm-sh/cache.h
+++ b/include/asm-sh/cache.h
@@ -21,6 +21,7 @@
 
 #define L1_CACHE_ALIGN(x)	(((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
 
+#ifndef __ASSEMBLY__
 struct cache_info {
 	unsigned int ways;		/* Number of cache ways */
 	unsigned int sets;		/* Number of cache sets */
@@ -47,6 +48,6 @@
 
 	unsigned long flags;
 };
-
+#endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 #endif /* __ASM_SH_CACHE_H */
diff --git a/include/asm-sh/cacheflush.h b/include/asm-sh/cacheflush.h
index 22f1263..07f62ec 100644
--- a/include/asm-sh/cacheflush.h
+++ b/include/asm-sh/cacheflush.h
@@ -30,8 +30,5 @@
 
 #define HAVE_ARCH_UNMAPPED_AREA
 
-/* Page flag for lazy dcache write-back for the aliasing UP caches */
-#define PG_dcache_dirty	PG_arch_1
-
 #endif /* __KERNEL__ */
 #endif /* __ASM_SH_CACHEFLUSH_H */
diff --git a/include/asm-sh/cpu-sh3/cacheflush.h b/include/asm-sh/cpu-sh3/cacheflush.h
index 6fabbba..f70d8ef7 100644
--- a/include/asm-sh/cpu-sh3/cacheflush.h
+++ b/include/asm-sh/cpu-sh3/cacheflush.h
@@ -36,6 +36,8 @@
  /* 32KB cache, 4kb PAGE sizes need to check bit 12 */
 #define CACHE_ALIAS 0x00001000
 
+#define PG_mapped	PG_arch_1
+
 void flush_cache_all(void);
 void flush_cache_mm(struct mm_struct *mm);
 #define flush_cache_dup_mm(mm) flush_cache_mm(mm)
diff --git a/include/asm-sh/cpu-sh4/cacheflush.h b/include/asm-sh/cpu-sh4/cacheflush.h
index b3746a9..5fd5c89 100644
--- a/include/asm-sh/cpu-sh4/cacheflush.h
+++ b/include/asm-sh/cpu-sh4/cacheflush.h
@@ -39,4 +39,6 @@
 /* Initialization of P3 area for copy_user_page */
 void p3_cache_init(void);
 
+#define PG_mapped	PG_arch_1
+
 #endif /* __ASM_CPU_SH4_CACHEFLUSH_H */
diff --git a/include/asm-sh/hp6xx.h b/include/asm-sh/hp6xx.h
index f35134c..53ca564 100644
--- a/include/asm-sh/hp6xx.h
+++ b/include/asm-sh/hp6xx.h
@@ -10,9 +10,9 @@
  *
  */
 
-#define HP680_BTN_IRQ		IRQ0_IRQ
-#define HP680_TS_IRQ		IRQ3_IRQ
-#define HP680_HD64461_IRQ	IRQ4_IRQ
+#define HP680_BTN_IRQ		32            /* IRQ0_IRQ */
+#define HP680_TS_IRQ		35            /* IRQ3_IRQ */
+#define HP680_HD64461_IRQ	36            /* IRQ4_IRQ */
 
 #define DAC_LCD_BRIGHTNESS	0
 #define DAC_SPEAKER_VOLUME	1
diff --git a/include/asm-sh/ioctls.h b/include/asm-sh/ioctls.h
index 9d84a2d..35805df 100644
--- a/include/asm-sh/ioctls.h
+++ b/include/asm-sh/ioctls.h
@@ -16,17 +16,17 @@
 #define TCSETSW		0x5403
 #define TCSETSF		0x5404
 
-#define TCGETA		_IOR('t', 23, struct termio)
-#define TCSETA		_IOW('t', 24, struct termio)
-#define TCSETAW		_IOW('t', 25, struct termio)
-#define TCSETAF		_IOW('t', 28, struct termio)
+#define TCGETA		0x80127417	/* _IOR('t', 23, struct termio) */
+#define TCSETA		0x40127418	/* _IOW('t', 24, struct termio) */
+#define TCSETAW		0x40127419	/* _IOW('t', 25, struct termio) */
+#define TCSETAF		0x4012741C	/* _IOW('t', 28, struct termio) */
 
 #define TCSBRK		_IO('t', 29)
 #define TCXONC		_IO('t', 30)
 #define TCFLSH		_IO('t', 31)
 
-#define TIOCSWINSZ	_IOW('t', 103, struct winsize)
-#define TIOCGWINSZ	_IOR('t', 104, struct winsize)
+#define TIOCSWINSZ	0x40087467	/* _IOW('t', 103, struct winsize) */
+#define TIOCGWINSZ	0x80087468	/* _IOR('t', 104, struct winsize) */
 #define	TIOCSTART	_IO('t', 110)		/* start output, like ^Q */
 #define	TIOCSTOP	_IO('t', 111)		/* stop output, like ^S */
 #define TIOCOUTQ        _IOR('t', 115, int)     /* output queue size */
@@ -59,8 +59,8 @@
 #define TIOCSSOFTCAR	_IOW('T', 26, unsigned int) /* 0x541A */
 #define TIOCLINUX	_IOW('T', 28, char) /* 0x541C */
 #define TIOCCONS	_IO('T', 29) /* 0x541D */
-#define TIOCGSERIAL	_IOR('T', 30, struct serial_struct) /* 0x541E */
-#define TIOCSSERIAL	_IOW('T', 31, struct serial_struct) /* 0x541F */
+#define TIOCGSERIAL	0x803C541E	/* _IOR('T', 30, struct serial_struct) 0x541E */
+#define TIOCSSERIAL	0x403C541F	/* _IOW('T', 31, struct serial_struct) 0x541F */
 #define TIOCPKT		_IOW('T', 32, int) /* 0x5420 */
 # define TIOCPKT_DATA		 0
 # define TIOCPKT_FLUSHREAD	 1
@@ -86,12 +86,12 @@
 #define TIOCSERSWILD	_IOW('T', 85,  int) /* 0x5455 */
 #define TIOCGLCKTRMIOS	0x5456
 #define TIOCSLCKTRMIOS	0x5457
-#define TIOCSERGSTRUCT	_IOR('T', 88, struct async_struct) /* 0x5458 */ /* For debugging only */
+#define TIOCSERGSTRUCT	0x80d85458	/* _IOR('T', 88, struct async_struct) 0x5458 */ /* For debugging only */
 #define TIOCSERGETLSR   _IOR('T', 89, unsigned int) /* 0x5459 */ /* Get line status register */
   /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 # define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
-#define TIOCSERGETMULTI _IOR('T', 90, struct serial_multiport_struct) /* 0x545A */ /* Get multiport config  */
-#define TIOCSERSETMULTI _IOW('T', 91, struct serial_multiport_struct) /* 0x545B */ /* Set multiport config */
+#define TIOCSERGETMULTI 0x80A8545A	/* _IOR('T', 90, struct serial_multiport_struct) 0x545A */ /* Get multiport config */
+#define TIOCSERSETMULTI 0x40A8545B	/* _IOW('T', 91, struct serial_multiport_struct) 0x545B */ /* Set multiport config */
 
 #define TIOCMIWAIT	_IO('T', 92) /* 0x545C */	/* wait for a change on serial input line(s) */
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
diff --git a/include/asm-sh/irq.h b/include/asm-sh/irq.h
index 8ccf7ae..afe188f 100644
--- a/include/asm-sh/irq.h
+++ b/include/asm-sh/irq.h
@@ -94,8 +94,13 @@
 /*
  * Convert back and forth between INTEVT and IRQ values.
  */
+#ifdef CONFIG_CPU_HAS_INTEVT
 #define evt2irq(evt)		(((evt) >> 5) - 16)
 #define irq2evt(irq)		(((irq) + 16) << 5)
+#else
+#define evt2irq(evt)		(evt)
+#define irq2evt(irq)		(irq)
+#endif
 
 /*
  * Simple Mask Register Support
diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h
index 9214c01..184d7fc 100644
--- a/include/asm-sh/pgtable.h
+++ b/include/asm-sh/pgtable.h
@@ -583,6 +583,11 @@
 extern unsigned int kobjsize(const void *objp);
 #endif /* !CONFIG_MMU */
 
+#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+extern pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
+#endif
+
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 extern void paging_init(void);
 
diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h
index b1e42e7..4a6a19f 100644
--- a/include/asm-sh/system.h
+++ b/include/asm-sh/system.h
@@ -7,6 +7,7 @@
  */
 
 #include <linux/irqflags.h>
+#include <linux/compiler.h>
 #include <asm/types.h>
 
 /*
diff --git a/include/asm-sh/thread_info.h b/include/asm-sh/thread_info.h
index 279e70a..31d55e3 100644
--- a/include/asm-sh/thread_info.h
+++ b/include/asm-sh/thread_info.h
@@ -111,6 +111,7 @@
 #define TIF_SIGPENDING		2	/* signal pending */
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_RESTORE_SIGMASK	4	/* restore signal mask in do_signal() */
+#define TIF_SINGLESTEP		5	/* singlestepping active */
 #define TIF_USEDFPU		16	/* FPU was used by this task this quantum (SMP) */
 #define TIF_POLLING_NRFLAG	17	/* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE		18
@@ -121,6 +122,7 @@
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 #define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
+#define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
 #define _TIF_USEDFPU		(1<<TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 #define _TIF_FREEZE		(1<<TIF_FREEZE)
diff --git a/include/asm-sh/unistd.h b/include/asm-sh/unistd.h
index 17f527b..49be50a 100644
--- a/include/asm-sh/unistd.h
+++ b/include/asm-sh/unistd.h
@@ -233,6 +233,7 @@
 #define __NR_fcntl64		221
 /* 223 is unused */
 #define __NR_gettid		224
+#define __NR_readahead		225
 #define __NR_setxattr		226
 #define __NR_lsetxattr		227
 #define __NR_fsetxattr		228
diff --git a/include/asm-sparc/a.out.h b/include/asm-sparc/a.out.h
index e4e83eb..9090060 100644
--- a/include/asm-sparc/a.out.h
+++ b/include/asm-sparc/a.out.h
@@ -80,7 +80,7 @@
         unsigned long   r_address;  /* relocation addr */
         unsigned int    r_index:24; /* segment index or symbol index */
         unsigned int    r_extern:1; /* if F, r_index==SEG#; if T, SYM idx */
-        int             r_pad:2;    /* <unused> */
+        unsigned int    r_pad:2;    /* <unused> */
         enum reloc_type r_type:5;   /* type of relocation to perform */
         long            r_addend;   /* addend for relocation value */
 };
diff --git a/include/asm-sparc/dma-mapping.h b/include/asm-sparc/dma-mapping.h
index 6db83dc..f3a641e 100644
--- a/include/asm-sparc/dma-mapping.h
+++ b/include/asm-sparc/dma-mapping.h
@@ -5,20 +5,7 @@
 #ifdef CONFIG_PCI
 #include <asm-generic/dma-mapping.h>
 #else
-
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
-			 dma_addr_t *dma_handle, gfp_t flag)
-{
-	BUG();
-	return NULL;
-}
-
-static inline void dma_free_coherent(struct device *dev, size_t size,
-		       void *vaddr, dma_addr_t dma_handle)
-{
-	BUG();
-}
-
+#include <asm-generic/dma-mapping-broken.h>
 #endif /* PCI */
 
 #endif /* _ASM_SPARC_DMA_MAPPING_H */
diff --git a/include/asm-sparc/mostek.h b/include/asm-sparc/mostek.h
index bd92a78..958d051 100644
--- a/include/asm-sparc/mostek.h
+++ b/include/asm-sparc/mostek.h
@@ -87,7 +87,7 @@
 #define	MSTK_DOW_MASK	0x07
 #define	MSTK_DOM_MASK	0x3f
 #define	MSTK_MONTH_MASK	0x1f
-#define	MSTK_YEAR_MASK	0xff
+#define	MSTK_YEAR_MASK	0xffU
 
 /* Binary coded decimal conversion macros. */
 #define MSTK_REGVAL_TO_DECIMAL(x)  (((x) & 0x0F) + 0x0A * ((x) >> 0x04))
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h
index d5b2f80..e43ed1d 100644
--- a/include/asm-sparc/unistd.h
+++ b/include/asm-sparc/unistd.h
@@ -319,16 +319,17 @@
 #define __NR_set_robust_list	300
 #define __NR_get_robust_list	301
 #define __NR_migrate_pages	302
+#define __NR_mbind		303
+#define __NR_get_mempolicy	304
+#define __NR_set_mempolicy	305
+#define __NR_kexec_load		306
+#define __NR_move_pages		307
+#define __NR_getcpu		308
+#define __NR_epoll_pwait	309
 
-#define NR_SYSCALLS		303
+#define NR_SYSCALLS		310
 
 #ifdef __KERNEL__
-/* WARNING: You MAY NOT add syscall numbers larger than 302, since
- *          all of the syscall tables in the Sparc kernel are
- *          sized to have 302 entries (starting at zero).  Therefore
- *          find a free slot in the 0-302 range.
- */
-
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_STAT64
@@ -345,7 +346,6 @@
 #define __ARCH_WANT_SYS_GETPGRP
 #define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
-#define __ARCH_WANT_SYS_OLD_GETRLIMIT
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/include/asm-sparc64/a.out.h b/include/asm-sparc64/a.out.h
index 35cb5c9..eb3b8e9 100644
--- a/include/asm-sparc64/a.out.h
+++ b/include/asm-sparc64/a.out.h
@@ -86,7 +86,7 @@
         unsigned int    r_address;  /* relocation addr */
         unsigned int    r_index:24; /* segment index or symbol index */
         unsigned int    r_extern:1; /* if F, r_index==SEG#; if T, SYM idx */
-        int             r_pad:2;    /* <unused> */
+        unsigned int    r_pad:2;    /* <unused> */
         enum reloc_type r_type:5;   /* type of relocation to perform */
         int             r_addend;   /* addend for relocation value */
 };
diff --git a/include/asm-sparc64/mostek.h b/include/asm-sparc64/mostek.h
index 09b5aba..d14dd89 100644
--- a/include/asm-sparc64/mostek.h
+++ b/include/asm-sparc64/mostek.h
@@ -89,7 +89,7 @@
 #define	MSTK_DOW_MASK	0x07
 #define	MSTK_DOM_MASK	0x3f
 #define	MSTK_MONTH_MASK	0x1f
-#define	MSTK_YEAR_MASK	0xff
+#define	MSTK_YEAR_MASK	0xffU
 
 /* Binary coded decimal conversion macros. */
 #define MSTK_REGVAL_TO_DECIMAL(x)  (((x) & 0x0F) + 0x0A * ((x) >> 0x04))
diff --git a/include/asm-sparc64/parport.h b/include/asm-sparc64/parport.h
index be9509c..284dfd0 100644
--- a/include/asm-sparc64/parport.h
+++ b/include/asm-sparc64/parport.h
@@ -19,6 +19,17 @@
  */
 #define HAS_DMA
 
+static DEFINE_SPINLOCK(dma_spin_lock);
+
+#define claim_dma_lock() \
+({	unsigned long flags; \
+	spin_lock_irqsave(&dma_spin_lock, flags); \
+	flags; \
+})
+
+#define release_dma_lock(__flags) \
+	spin_unlock_irqrestore(&dma_spin_lock, __flags);
+
 static struct sparc_ebus_info {
 	struct ebus_dma_info info;
 	unsigned int addr;
diff --git a/include/asm-sparc64/tsb.h b/include/asm-sparc64/tsb.h
index e82612c..ab55ffc 100644
--- a/include/asm-sparc64/tsb.h
+++ b/include/asm-sparc64/tsb.h
@@ -264,6 +264,7 @@
 	be,a,pt		%xcc, OK_LABEL; \
 	 mov		REG4, REG1;
 
+#ifndef CONFIG_DEBUG_PAGEALLOC
 	/* This version uses a trick, the TAG is already (VADDR >> 22) so
 	 * we can make use of that for the index computation.
 	 */
@@ -277,5 +278,6 @@
 	cmp		REG3, TAG; \
 	be,a,pt		%xcc, OK_LABEL; \
 	 mov		REG4, REG1;
+#endif
 
 #endif /* !(_SPARC64_TSB_H) */
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h
index 4704753..e2dcb87 100644
--- a/include/asm-sparc64/unistd.h
+++ b/include/asm-sparc64/unistd.h
@@ -321,17 +321,17 @@
 #define __NR_set_robust_list	300
 #define __NR_get_robust_list	301
 #define __NR_migrate_pages	302
+#define __NR_mbind		303
+#define __NR_get_mempolicy	304
+#define __NR_set_mempolicy	305
+#define __NR_kexec_load		306
+#define __NR_move_pages		307
+#define __NR_getcpu		308
+#define __NR_epoll_pwait	309
 
-#define NR_SYSCALLS		303
+#define NR_SYSCALLS		310
 
 #ifdef __KERNEL__
-
-/* WARNING: You MAY NOT add syscall numbers larger than 302, since
- *          all of the syscall tables in the Sparc kernel are
- *          sized to have 302 entries (starting at zero).  Therefore
- *          find a free slot in the 0-302 range.
- */
-
 /* sysconf options, for SunOS compatibility */
 #define   _SC_ARG_MAX             1
 #define   _SC_CHILD_MAX           2
@@ -359,7 +359,6 @@
 #define __ARCH_WANT_SYS_GETPGRP
 #define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
-#define __ARCH_WANT_SYS_OLD_GETRLIMIT
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/include/asm-um/common.lds.S b/include/asm-um/common.lds.S
index f045451..f5de80c 100644
--- a/include/asm-um/common.lds.S
+++ b/include/asm-um/common.lds.S
@@ -15,6 +15,7 @@
   PROVIDE (_unprotected_end = .);
 
   . = ALIGN(4096);
+  .note : { *(.note.*) }
   __start___ex_table = .;
   __ex_table : { *(__ex_table) }
   __stop___ex_table = .;
diff --git a/include/asm-um/delay.h b/include/asm-um/delay.h
index 0985bda6..c71e32b 100644
--- a/include/asm-um/delay.h
+++ b/include/asm-um/delay.h
@@ -1,9 +1,20 @@
 #ifndef __UM_DELAY_H
 #define __UM_DELAY_H
 
-#include "asm/arch/delay.h"
-#include "asm/archparam.h"
-
 #define MILLION 1000000
 
+/* Undefined on purpose */
+extern void __bad_udelay(void);
+
+extern void __udelay(unsigned long usecs);
+extern void __delay(unsigned long loops);
+
+#define udelay(n) ((__builtin_constant_p(n) && (n) > 20000) ? \
+	__bad_udelay() : __udelay(n))
+
+/* It appears that ndelay is not used at all for UML, and has never been
+ * implemented. */
+extern void __unimplemented_ndelay(void);
+#define ndelay(n) __unimplemented_ndelay()
+
 #endif
diff --git a/include/asm-um/pgtable-2level.h b/include/asm-um/pgtable-2level.h
index 6050e0e..172a75f 100644
--- a/include/asm-um/pgtable-2level.h
+++ b/include/asm-um/pgtable-2level.h
@@ -45,12 +45,12 @@
 	((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
 
 /*
- * Bits 0 through 3 are taken
+ * Bits 0 through 4 are taken
  */
-#define PTE_FILE_MAX_BITS	28
+#define PTE_FILE_MAX_BITS	27
 
-#define pte_to_pgoff(pte) (pte_val(pte) >> 4)
+#define pte_to_pgoff(pte) (pte_val(pte) >> 5)
 
-#define pgoff_to_pte(off) ((pte_t) { ((off) << 4) + _PAGE_FILE })
+#define pgoff_to_pte(off) ((pte_t) { ((off) << 5) + _PAGE_FILE })
 
 #endif
diff --git a/include/asm-x86_64/apic.h b/include/asm-x86_64/apic.h
index e81d0f2..7cfb39c 100644
--- a/include/asm-x86_64/apic.h
+++ b/include/asm-x86_64/apic.h
@@ -102,5 +102,6 @@
 #define ARCH_APICTIMER_STOPS_ON_C3	1
 
 extern unsigned boot_cpu_id;
+extern int local_apic_timer_c2_ok;
 
 #endif /* __ASM_APIC_H */
diff --git a/include/asm-x86_64/hw_irq.h b/include/asm-x86_64/hw_irq.h
index 2e4b7a5..6153ae5 100644
--- a/include/asm-x86_64/hw_irq.h
+++ b/include/asm-x86_64/hw_irq.h
@@ -38,7 +38,7 @@
 #define IRQ_MOVE_CLEANUP_VECTOR	FIRST_EXTERNAL_VECTOR
  
 /*
- * Vectors 0x20-0x2f are used for ISA interrupts.
+ * Vectors 0x30-0x3f are used for ISA interrupts.
  */
 #define IRQ0_VECTOR		FIRST_EXTERNAL_VECTOR + 0x10
 #define IRQ1_VECTOR		IRQ0_VECTOR + 1
diff --git a/include/asm-x86_64/nmi.h b/include/asm-x86_64/nmi.h
index ceb3d8d..72375e7 100644
--- a/include/asm-x86_64/nmi.h
+++ b/include/asm-x86_64/nmi.h
@@ -64,7 +64,7 @@
 
 extern atomic_t nmi_active;
 extern unsigned int nmi_watchdog;
-#define NMI_DEFAULT	0
+#define NMI_DEFAULT	-1
 #define NMI_NONE	0
 #define NMI_IO_APIC	1
 #define NMI_LOCAL_APIC	2
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
index f54f3ab..b6e65a6 100644
--- a/include/asm-x86_64/proto.h
+++ b/include/asm-x86_64/proto.h
@@ -99,7 +99,7 @@
 extern int iommu_detected;
 #ifdef CONFIG_IOMMU
 extern void gart_iommu_init(void);
-extern void gart_parse_options(char *);
+extern void __init gart_parse_options(char *);
 extern void iommu_hole_init(void);
 extern int fallback_aper_order;
 extern int fallback_aper_force;
diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h
index e17b9ec4..de592a4 100644
--- a/include/asm-x86_64/smp.h
+++ b/include/asm-x86_64/smp.h
@@ -7,6 +7,7 @@
 #include <linux/threads.h>
 #include <linux/cpumask.h>
 #include <linux/bitops.h>
+#include <linux/init.h>
 extern int disable_apic;
 
 #include <asm/fixmap.h>
@@ -68,7 +69,7 @@
 extern void __cpu_die(unsigned int cpu);
 extern void prefill_possible_map(void);
 extern unsigned num_processors;
-extern unsigned disabled_cpus;
+extern unsigned __cpuinitdata disabled_cpus;
 
 #define NO_PROC_ID		0xFF		/* No processor magic marker */
 
diff --git a/include/asm-x86_64/uaccess.h b/include/asm-x86_64/uaccess.h
index 1981f70..9df30b9 100644
--- a/include/asm-x86_64/uaccess.h
+++ b/include/asm-x86_64/uaccess.h
@@ -373,12 +373,12 @@
 static inline int __copy_from_user_nocache(void *dst, const void __user *src, unsigned size)
 {
 	might_sleep();
-	return __copy_user_nocache(dst, (__force void *)src, size, 1);
+	return __copy_user_nocache(dst, src, size, 1);
 }
 
 static inline int __copy_from_user_inatomic_nocache(void *dst, const void __user *src, unsigned size)
 {
-	return __copy_user_nocache(dst, (__force void *)src, size, 0);
+	return __copy_user_nocache(dst, src, size, 0);
 }
 
 #endif /* __X86_64_UACCESS_H */
diff --git a/include/linux/ata.h b/include/linux/ata.h
index c331da2..6caeb98 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -40,6 +40,7 @@
 	ATA_MAX_DEVICES		= 2,	/* per bus/port */
 	ATA_MAX_PRD		= 256,	/* we could make these 256/256 */
 	ATA_SECT_SIZE		= 512,
+	ATA_MAX_SECTORS_128	= 128,
 	ATA_MAX_SECTORS		= 256,
 	ATA_MAX_SECTORS_LBA48	= 65535,/* TODO: 65536? */
 
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index 7011d625..f2542c2 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -93,6 +93,7 @@
 void clear_bdi_congested(struct backing_dev_info *bdi, int rw);
 void set_bdi_congested(struct backing_dev_info *bdi, int rw);
 long congestion_wait(int rw, long timeout);
+long congestion_wait_interruptible(int rw, long timeout);
 void congestion_end(int rw);
 
 #define bdi_cap_writeback_dirty(bdi) \
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
index 2275f27..81c07cd 100644
--- a/include/linux/bootmem.h
+++ b/include/linux/bootmem.h
@@ -108,7 +108,7 @@
 #endif /* CONFIG_HAVE_ARCH_ALLOC_REMAP */
 
 extern unsigned long __meminitdata nr_kernel_pages;
-extern unsigned long nr_all_pages;
+extern unsigned long __meminitdata nr_all_pages;
 
 extern void *alloc_large_system_hash(const char *tablename,
 				     unsigned long bucketsize,
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 80b17f4..ccd863d 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -234,5 +234,24 @@
 		compat_ulong_t maxnode, const compat_ulong_t __user *old_nodes,
 		const compat_ulong_t __user *new_nodes);
 
+/*
+ * epoll (fs/eventpoll.c) compat bits follow ...
+ */
+#ifndef CONFIG_HAS_COMPAT_EPOLL_EVENT
+struct epoll_event;
+#define compat_epoll_event	epoll_event
+#else
+asmlinkage long compat_sys_epoll_ctl(int epfd, int op, int fd,
+			struct compat_epoll_event __user *event);
+asmlinkage long compat_sys_epoll_wait(int epfd,
+			struct compat_epoll_event __user *events,
+			int maxevents, int timeout);
+#endif
+asmlinkage long compat_sys_epoll_pwait(int epfd,
+			struct compat_epoll_event __user *events,
+			int maxevents, int timeout,
+			const compat_sigset_t __user *sigmask,
+			compat_size_t sigsetsize);
+
 #endif /* CONFIG_COMPAT */
 #endif /* _LINUX_COMPAT_H */
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index aca6698..3b6949b 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -15,8 +15,8 @@
 # define __acquire(x)	__context__(x,1)
 # define __release(x)	__context__(x,-1)
 # define __cond_lock(x,c)	((c) ? ({ __acquire(x); 1; }) : 0)
-extern void __chk_user_ptr(void __user *);
-extern void __chk_io_ptr(void __iomem *);
+extern void __chk_user_ptr(const void __user *);
+extern void __chk_io_ptr(const void __iomem *);
 #else
 # define __user
 # define __kernel
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 769ddc6..c22b0df 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -127,9 +127,13 @@
 #endif		/* CONFIG_HOTPLUG_CPU */
 
 #ifdef CONFIG_SUSPEND_SMP
+extern int suspend_cpu_hotplug;
+
 extern int disable_nonboot_cpus(void);
 extern void enable_nonboot_cpus(void);
 #else
+#define suspend_cpu_hotplug	0
+
 static inline int disable_nonboot_cpus(void) { return 0; }
 static inline void enable_nonboot_cpus(void) {}
 #endif
diff --git a/include/linux/device.h b/include/linux/device.h
index 39a3199..5cf30e9 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -128,6 +128,7 @@
 
 	struct module		* owner;
 	const char 		* mod_name;	/* used for built-in modules */
+	struct module_kobject	* mkobj;
 
 	int	(*probe)	(struct device * dev);
 	int	(*remove)	(struct device * dev);
@@ -353,6 +354,8 @@
 					       struct bin_attribute *attr);
 extern void device_remove_bin_file(struct device *dev,
 				   struct bin_attribute *attr);
+extern int device_schedule_callback(struct device *dev,
+		void (*func)(struct device *));
 
 /* device resource management */
 typedef void (*dr_release_t)(struct device *dev, void *res);
diff --git a/include/linux/eventpoll.h b/include/linux/eventpoll.h
index 84cfa8b..d2a96cb 100644
--- a/include/linux/eventpoll.h
+++ b/include/linux/eventpoll.h
@@ -31,12 +31,19 @@
 /* 
  * On x86-64 make the 64bit structure have the same alignment as the
  * 32bit structure. This makes 32bit emulation easier.
+ *
+ * UML/x86_64 needs the same packing as x86_64 - UML + UML_X86 +
+ * 64_BIT adds up to UML/x86_64.
  */
 #ifdef __x86_64__
 #define EPOLL_PACKED __attribute__((packed))
 #else
+#if defined(CONFIG_UML) && defined(CONFIG_UML_X86) && defined(CONFIG_64BIT)
+#define EPOLL_PACKED __attribute__((packed))
+#else
 #define EPOLL_PACKED
 #endif
+#endif
 
 struct epoll_event {
 	__u32 events;
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 5bdbc74..17c29dc 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -206,6 +206,7 @@
 struct clock_event_device;
 
 extern void clock_was_set(void);
+extern void hres_timers_resume(void);
 extern void hrtimer_interrupt(struct clock_event_device *dev);
 
 /*
@@ -236,6 +237,8 @@
  */
 static inline void clock_was_set(void) { }
 
+static inline void hres_timers_resume(void) { }
+
 /*
  * In non high resolution mode the time reference is taken from
  * the base softirq time variable.
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 34f2676..d3bbc71 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -615,6 +615,7 @@
         u8	init_speed;	/* transfer rate set at boot */
         u8	pio_speed;      /* unused by core, used by some drivers for fallback from DMA */
         u8	current_speed;	/* current transfer rate set */
+	u8	desired_speed;	/* desired transfer rate set */
         u8	dn;		/* now wide spread use */
         u8	wcache;		/* status of write cache */
 	u8	acoustic;	/* acoustic management */
@@ -860,6 +861,8 @@
 	int (*expiry)(ide_drive_t *);
 		/* ide_system_bus_speed */
 	int pio_clock;
+	int req_gen;
+	int req_gen_timer;
 
 	unsigned char cmd_buf[4];
 } ide_hwgroup_t;
diff --git a/include/linux/ipc.h b/include/linux/ipc.h
index 636094c..6da6772 100644
--- a/include/linux/ipc.h
+++ b/include/linux/ipc.h
@@ -92,19 +92,16 @@
 
 #ifdef CONFIG_SYSVIPC
 #define INIT_IPC_NS(ns)		.ns		= &init_ipc_ns,
+extern int copy_ipcs(unsigned long flags, struct task_struct *tsk);
 #else
 #define INIT_IPC_NS(ns)
+static inline int copy_ipcs(unsigned long flags, struct task_struct *tsk)
+{ return 0; }
 #endif
 
 #ifdef CONFIG_IPC_NS
 extern void free_ipc_ns(struct kref *kref);
-extern int copy_ipcs(unsigned long flags, struct task_struct *tsk);
 extern int unshare_ipcs(unsigned long flags, struct ipc_namespace **ns);
-#else
-static inline int copy_ipcs(unsigned long flags, struct task_struct *tsk)
-{
-	return 0;
-}
 #endif
 
 static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)
diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h
index 06c58c4..506ad20 100644
--- a/include/linux/kbd_kern.h
+++ b/include/linux/kbd_kern.h
@@ -75,7 +75,7 @@
 
 extern void (*kbd_ledfunc)(unsigned int led);
 
-extern void set_console(int nr);
+extern int set_console(int nr);
 extern void schedule_console_callback(void);
 
 static inline void set_leds(void)
diff --git a/include/linux/kdev_t.h b/include/linux/kdev_t.h
index 4c2c373..2dacab8 100644
--- a/include/linux/kdev_t.h
+++ b/include/linux/kdev_t.h
@@ -87,8 +87,6 @@
 	return dev & 0x3ffff;
 }
 
-bool is_lanana_major(unsigned int major);
-
 #else /* __KERNEL__ */
 
 /*
diff --git a/include/linux/ktime.h b/include/linux/ktime.h
index c68c7ac..248305b 100644
--- a/include/linux/ktime.h
+++ b/include/linux/ktime.h
@@ -57,7 +57,11 @@
 } ktime_t;
 
 #define KTIME_MAX			((s64)~((u64)1 << 63))
-#define KTIME_SEC_MAX			(KTIME_MAX / NSEC_PER_SEC)
+#if (BITS_PER_LONG == 64)
+# define KTIME_SEC_MAX			(KTIME_MAX / NSEC_PER_SEC)
+#else
+# define KTIME_SEC_MAX			LONG_MAX
+#endif
 
 /*
  * ktime_t definitions when using the 64-bit scalar representation:
diff --git a/include/linux/libata.h b/include/linux/libata.h
index e3f32f3..0cfbcb6 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -311,15 +311,17 @@
 	ATA_HORKAGE_DIAGNOSTIC	= (1 << 0),	/* Failed boot diag */
 	ATA_HORKAGE_NODMA	= (1 << 1),	/* DMA problems */
 	ATA_HORKAGE_NONCQ	= (1 << 2),	/* Don't use NCQ */
+	ATA_HORKAGE_MAX_SEC_128	= (1 << 3),	/* Limit max sects to 128 */
+	ATA_HORKAGE_DMA_RW_ONLY	= (1 << 4),	/* ATAPI DMA for RW only */
 };
 
 enum hsm_task_states {
 	HSM_ST_IDLE,		/* no command on going */
+	HSM_ST_FIRST,		/* (waiting the device to)
+				   write CDB or first data block */
 	HSM_ST,			/* (waiting the device to) transfer data */
 	HSM_ST_LAST,		/* (waiting the device to) complete command */
 	HSM_ST_ERR,		/* error */
-	HSM_ST_FIRST,		/* (waiting the device to)
-				   write CDB or first data block */
 };
 
 enum ata_completion_errors {
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 06fe93a..14c937d 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -245,7 +245,7 @@
 
 # define INIT_LOCKDEP				.lockdep_recursion = 0,
 
-#define lockdep_depth(tsk)	((tsk)->lockdep_depth)
+#define lockdep_depth(tsk)	(debug_locks ? (tsk)->lockdep_depth : 0)
 
 #else /* !LOCKDEP */
 
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 74c8a2e..e38fe682 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -17,7 +17,7 @@
 	struct {
 		__u8	type	: 5; 	/* {0: unused, 5h:MSI, 11h:MSI-X} */
 		__u8	maskbit	: 1; 	/* mask-pending bit supported ?   */
-		__u8	unused	: 1;
+		__u8	masked	: 1;
 		__u8	is_64	: 1;	/* Address size: 0=32bit 1=64bit  */
 		__u8	pos;	 	/* Location of the msi capability */
 		__u16	entry_nr;    	/* specific enabled entry 	  */
@@ -32,10 +32,8 @@
 	void __iomem *mask_base;
 	struct pci_dev *dev;
 
-#ifdef CONFIG_PM
-	/* PM save area for MSIX address/data */
-	struct msi_msg msg_save;
-#endif
+	/* Last set MSI message */
+	struct msi_msg msg;
 };
 
 /*
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 6a8570b..3d956c3a 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -121,6 +121,7 @@
 	u_int32_t writesize;
 
 	u_int32_t oobsize;   // Amount of OOB data per block (e.g. 16)
+	u_int32_t oobavail;  // Available OOB bytes per block
 
 	// Kernel-only stuff starts here.
 	char *name;
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index d8af8a9..a56d24a 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -82,7 +82,8 @@
  * @wq:			[INTERN] wait queue to sleep on if a OneNAND
  *			operation is in progress
  * @state:		[INTERN] the current state of the OneNAND device
- * @page_buf:		data buffer
+ * @page_buf:		[INTERN] page main data buffer
+ * @oob_buf:		[INTERN] page oob data buffer
  * @subpagesize:	[INTERN] holds the subpagesize
  * @ecclayout:		[REPLACEABLE] the default ecc placement scheme
  * @bbm:		[REPLACEABLE] pointer to Bad Block Management
@@ -122,6 +123,7 @@
 	wait_queue_head_t	wq;
 	onenand_state_t		state;
 	unsigned char		*page_buf;
+	unsigned char		*oob_buf;
 
 	int			subpagesize;
 	struct nand_ecclayout	*ecclayout;
@@ -156,6 +158,7 @@
 #define ONENAND_HAS_CONT_LOCK		(0x0001)
 #define ONENAND_HAS_UNLOCK_ALL		(0x0002)
 #define ONENAND_PAGEBUF_ALLOC		(0x1000)
+#define ONENAND_OOBBUF_ALLOC		(0x2000)
 
 /*
  * OneNAND Flash Manufacturer ID Codes
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 47aaa2c..e9ae0c6 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -415,6 +415,7 @@
 /*
  * linux/fs/nfs/write.c
  */
+extern int  nfs_congestion_kb;
 extern int  nfs_writepage(struct page *page, struct writeback_control *wbc);
 extern int  nfs_writepages(struct address_space *, struct writeback_control *);
 extern int  nfs_flush_incompatible(struct file *file, struct page *page);
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 95796e6..c95d5e6 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -82,6 +82,7 @@
 	struct rpc_clnt *	client_acl;	/* ACL RPC client handle */
 	struct nfs_iostats *	io_stats;	/* I/O statistics */
 	struct backing_dev_info	backing_dev_info;
+	atomic_t		writeback;	/* number of writeback pages */
 	int			flags;		/* various flags */
 	unsigned int		caps;		/* server capabilities */
 	unsigned int		rsize;		/* read size */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 78417e4..481ea06 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -209,11 +209,6 @@
 	hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space);
 }
 
-static inline void pci_remove_saved_cap(struct pci_cap_saved_state *cap)
-{
-	hlist_del(&cap->next);
-}
-
 /*
  *  For PCI devices, the region numbers are assigned this way:
  *
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index f09cce2..495d368 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -296,6 +296,7 @@
 #define PCI_MSIX_FLAGS		2
 #define  PCI_MSIX_FLAGS_QSIZE	0x7FF
 #define  PCI_MSIX_FLAGS_ENABLE	(1 << 15)
+#define  PCI_MSIX_FLAGS_MASKALL	(1 << 14)
 #define PCI_MSIX_FLAGS_BIRMASK	(7 << 0)
 #define PCI_MSIX_FLAGS_BITMASK	(1 << 0)
 
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index 2e19478..8bcbc54 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -99,4 +99,8 @@
 				loff_t *, size_t, unsigned int,
 				splice_actor *);
 
+extern ssize_t __splice_from_pipe(struct pipe_inode_info *, struct file *,
+				  loff_t *, size_t, unsigned int,
+				  splice_actor *);
+
 #endif
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index 8245c28..de72c49 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -104,6 +104,7 @@
 					   * for reporting to userspace and storing
 					   * in superblock.
 					   */
+	struct work_struct del_work;	/* used for delayed sysfs removal */
 };
 
 struct mddev_s
diff --git a/include/linux/security.h b/include/linux/security.h
index 7f88d97..47e82c1 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1324,7 +1324,7 @@
 
 	void (*d_instantiate) (struct dentry *dentry, struct inode *inode);
 
- 	int (*getprocattr)(struct task_struct *p, char *name, void *value, size_t size);
+ 	int (*getprocattr)(struct task_struct *p, char *name, char **value);
  	int (*setprocattr)(struct task_struct *p, char *name, void *value, size_t size);
 	int (*secid_to_secctx)(u32 secid, char **secdata, u32 *seclen);
 	void (*release_secctx)(char *secdata, u32 seclen);
@@ -2092,9 +2092,9 @@
 	security_ops->d_instantiate (dentry, inode);
 }
 
-static inline int security_getprocattr(struct task_struct *p, char *name, void *value, size_t size)
+static inline int security_getprocattr(struct task_struct *p, char *name, char **value)
 {
-	return security_ops->getprocattr(p, name, value, size);
+	return security_ops->getprocattr(p, name, value);
 }
 
 static inline int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size)
@@ -2749,7 +2749,7 @@
 static inline void security_d_instantiate (struct dentry *dentry, struct inode *inode)
 { }
 
-static inline int security_getprocattr(struct task_struct *p, char *name, void *value, size_t size)
+static inline int security_getprocattr(struct task_struct *p, char *name, char **value)
 {
 	return -EINVAL;
 }
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 4ff3940..82f43ad 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -188,7 +188,7 @@
  *	@sk: Socket we are owned by
  *	@tstamp: Time we arrived
  *	@dev: Device we arrived on/are leaving by
- *	@input_dev: Device we arrived on
+ *	@iif: ifindex of device we arrived on
  *	@h: Transport layer header
  *	@nh: Network layer header
  *	@mac: Link layer header
@@ -235,7 +235,8 @@
 	struct sock		*sk;
 	struct skb_timeval	tstamp;
 	struct net_device	*dev;
-	struct net_device	*input_dev;
+	int			iif;
+	/* 4 byte hole on 64 bit*/
 
 	union {
 		struct tcphdr	*th;
diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h
index 2e8c048..9dbca62 100644
--- a/include/linux/spi/spi_bitbang.h
+++ b/include/linux/spi/spi_bitbang.h
@@ -25,7 +25,6 @@
 	spinlock_t		lock;
 	struct list_head	queue;
 	u8			busy;
-	u8			shutdown;
 	u8			use_dma;
 
 	struct spi_master	*master;
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 523405e..fea9a6b 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -11,6 +11,7 @@
 #define _SYSFS_H_
 
 #include <linux/compiler.h>
+#include <linux/errno.h>
 #include <linux/list.h>
 #include <asm/atomic.h>
 
@@ -78,6 +79,9 @@
 
 #ifdef CONFIG_SYSFS
 
+extern int sysfs_schedule_callback(struct kobject *kobj,
+		void (*func)(void *), void *data);
+
 extern int __must_check
 sysfs_create_dir(struct kobject *, struct dentry *);
 
@@ -132,6 +136,12 @@
 
 #else /* CONFIG_SYSFS */
 
+static inline int sysfs_schedule_callback(struct kobject *kobj,
+		void (*func)(void *), void *data)
+{
+	return -ENOSYS;
+}
+
 static inline int sysfs_create_dir(struct kobject * k, struct dentry *shadow)
 {
 	return 0;
diff --git a/include/linux/ufs_fs.h b/include/linux/ufs_fs.h
index dc2e9fe..daeba22 100644
--- a/include/linux/ufs_fs.h
+++ b/include/linux/ufs_fs.h
@@ -649,10 +649,10 @@
 	__fs32     ui_blksize;     /*  12: Inode blocksize. */
 	__fs64     ui_size;        /*  16: File byte count. */
 	__fs64     ui_blocks;      /*  24: Bytes actually held. */
-	struct ufs_timeval   ui_atime;       /*  32: Last access time. */
-	struct ufs_timeval   ui_mtime;       /*  40: Last modified time. */
-	struct ufs_timeval   ui_ctime;       /*  48: Last inode change time. */
-	struct ufs_timeval   ui_birthtime;   /*  56: Inode creation time. */
+	__fs64   ui_atime;       /*  32: Last access time. */
+	__fs64   ui_mtime;       /*  40: Last modified time. */
+	__fs64   ui_ctime;       /*  48: Last inode change time. */
+	__fs64   ui_birthtime;   /*  56: Inode creation time. */
 	__fs32     ui_mtimensec;   /*  64: Last modified time. */
 	__fs32     ui_atimensec;   /*  68: Last access time. */
 	__fs32     ui_ctimensec;   /*  72: Last inode change time. */
diff --git a/include/linux/utsname.h b/include/linux/utsname.h
index a4555fe..e10267d 100644
--- a/include/linux/utsname.h
+++ b/include/linux/utsname.h
@@ -70,6 +70,8 @@
 
 static inline int copy_utsname(int flags, struct task_struct *tsk)
 {
+	if (flags & CLONE_NEWUTS)
+		return -EINVAL;
 	return 0;
 }
 static inline void put_uts_ns(struct uts_namespace *ns)
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index 37a1a41..e0db669 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -83,6 +83,7 @@
 #define CON_BUF_SIZE (CONFIG_BASE_SMALL ? 256 : PAGE_SIZE)
 extern char con_buf[CON_BUF_SIZE];
 extern struct semaphore con_buf_sem;
+extern char vt_dont_switch;
 
 struct vt_spawn_console {
 	spinlock_t lock;
diff --git a/include/linux/wireless.h b/include/linux/wireless.h
index 447c52b..48759b2 100644
--- a/include/linux/wireless.h
+++ b/include/linux/wireless.h
@@ -1,10 +1,10 @@
 /*
  * This file define a set of standard wireless extensions
  *
- * Version :	21	14.3.06
+ * Version :	22	16.3.07
  *
  * Authors :	Jean Tourrilhes - HPL - <jt@hpl.hp.com>
- * Copyright (c) 1997-2006 Jean Tourrilhes, All Rights Reserved.
+ * Copyright (c) 1997-2007 Jean Tourrilhes, All Rights Reserved.
  */
 
 #ifndef _LINUX_WIRELESS_H
@@ -85,7 +85,7 @@
  * (there is some stuff that will be added in the future...)
  * I just plan to increment with each new version.
  */
-#define WIRELESS_EXT	21
+#define WIRELESS_EXT	22
 
 /*
  * Changes :
@@ -221,6 +221,10 @@
  *	- Add IW_RETRY_SHORT/IW_RETRY_LONG retry modifiers
  *	- Power/Retry relative values no longer * 100000
  *	- Add explicit flag to tell stats are in 802.11k RCPI : IW_QUAL_RCPI
+ *
+ * V21 to V22
+ * ----------
+ *	- Prevent leaking of kernel space in stream on 64 bits.
  */
 
 /**************************** CONSTANTS ****************************/
@@ -1085,4 +1089,15 @@
 #define IW_EV_POINT_LEN	(IW_EV_LCP_LEN + sizeof(struct iw_point) - \
 			 IW_EV_POINT_OFF)
 
+/* Size of the Event prefix when packed in stream */
+#define IW_EV_LCP_PK_LEN	(4)
+/* Size of the various events when packed in stream */
+#define IW_EV_CHAR_PK_LEN	(IW_EV_LCP_PK_LEN + IFNAMSIZ)
+#define IW_EV_UINT_PK_LEN	(IW_EV_LCP_PK_LEN + sizeof(__u32))
+#define IW_EV_FREQ_PK_LEN	(IW_EV_LCP_PK_LEN + sizeof(struct iw_freq))
+#define IW_EV_PARAM_PK_LEN	(IW_EV_LCP_PK_LEN + sizeof(struct iw_param))
+#define IW_EV_ADDR_PK_LEN	(IW_EV_LCP_PK_LEN + sizeof(struct sockaddr))
+#define IW_EV_QUAL_PK_LEN	(IW_EV_LCP_PK_LEN + sizeof(struct iw_quality))
+#define IW_EV_POINT_PK_LEN	(IW_EV_LCP_LEN + 4)
+
 #endif	/* _LINUX_WIRELESS_H */
diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h
index 83fe2e3..50e33b0 100644
--- a/include/media/saa7146_vv.h
+++ b/include/media/saa7146_vv.h
@@ -239,7 +239,8 @@
 #define SAA7146_HPS_SYNC_PORT_B		0x01
 
 /* some memory sizes */
-#define SAA7146_CLIPPING_MEM	(14*PAGE_SIZE)
+/* max. 16 clipping rectangles */
+#define SAA7146_CLIPPING_MEM	(16 * 4 * sizeof(u32))
 
 /* some defines for the various clipping-modes */
 #define SAA7146_CLIPPING_RECT		0x4
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h
index bc3c264..d585ea9 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -34,6 +34,7 @@
 	int			family;
 	struct list_head	list;
 	int			rule_size;
+	int			addr_size;
 
 	int			(*action)(struct fib_rule *,
 					  struct flowi *, int,
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 9eda572..cf355a3 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -58,6 +58,7 @@
 	__u16			fn_bit;		/* bit key */
 	__u16			fn_flags;
 	__u32			fn_sernum;
+	struct rt6_info		*rr_ptr;
 };
 
 #ifndef CONFIG_IPV6_SUBTREES
diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h
index 10559e9..8a83018 100644
--- a/include/net/iw_handler.h
+++ b/include/net/iw_handler.h
@@ -1,10 +1,10 @@
 /*
  * This file define the new driver API for Wireless Extensions
  *
- * Version :	7	18.3.05
+ * Version :	8	16.3.07
  *
  * Authors :	Jean Tourrilhes - HPL - <jt@hpl.hp.com>
- * Copyright (c) 2001-2006 Jean Tourrilhes, All Rights Reserved.
+ * Copyright (c) 2001-2007 Jean Tourrilhes, All Rights Reserved.
  */
 
 #ifndef _IW_HANDLER_H
@@ -207,7 +207,7 @@
  * will be needed...
  * I just plan to increment with each new version.
  */
-#define IW_HANDLER_VERSION	7
+#define IW_HANDLER_VERSION	8
 
 /*
  * Changes :
@@ -239,6 +239,10 @@
  *	- Remove (struct iw_point *)->pointer from events and streams
  *	- Remove spy_offset from struct iw_handler_def
  *	- Add "check" version of event macros for ieee802.11 stack
+ *
+ * V7 to V8
+ * ----------
+ *	- Prevent leaking of kernel space in stream on 64 bits.
  */
 
 /**************************** CONSTANTS ****************************/
@@ -500,7 +504,11 @@
 	/* Check if it's possible */
 	if(likely((stream + event_len) < ends)) {
 		iwe->len = event_len;
-		memcpy(stream, (char *) iwe, event_len);
+		/* Beware of alignement issues on 64 bits */
+		memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
+		memcpy(stream + IW_EV_LCP_LEN,
+		       ((char *) iwe) + IW_EV_LCP_LEN,
+		       event_len - IW_EV_LCP_LEN);
 		stream += event_len;
 	}
 	return stream;
@@ -521,10 +529,10 @@
 	/* Check if it's possible */
 	if(likely((stream + event_len) < ends)) {
 		iwe->len = event_len;
-		memcpy(stream, (char *) iwe, IW_EV_LCP_LEN);
+		memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
 		memcpy(stream + IW_EV_LCP_LEN,
 		       ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
-		       IW_EV_POINT_LEN - IW_EV_LCP_LEN);
+		       IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
 		memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
 		stream += event_len;
 	}
@@ -574,7 +582,11 @@
 	/* Check if it's possible, set error if not */
 	if(likely((stream + event_len) < ends)) {
 		iwe->len = event_len;
-		memcpy(stream, (char *) iwe, event_len);
+		/* Beware of alignement issues on 64 bits */
+		memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
+		memcpy(stream + IW_EV_LCP_LEN,
+		       ((char *) iwe) + IW_EV_LCP_LEN,
+		       event_len - IW_EV_LCP_LEN);
 		stream += event_len;
 	} else
 		*perr = -E2BIG;
@@ -598,10 +610,10 @@
 	/* Check if it's possible */
 	if(likely((stream + event_len) < ends)) {
 		iwe->len = event_len;
-		memcpy(stream, (char *) iwe, IW_EV_LCP_LEN);
+		memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
 		memcpy(stream + IW_EV_LCP_LEN,
 		       ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
-		       IW_EV_POINT_LEN - IW_EV_LCP_LEN);
+		       IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
 		memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
 		stream += event_len;
 	} else
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index 3725b93..ad7fe11 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -36,7 +36,7 @@
 	struct net_device *dev;
 	struct neigh_parms *next;
 	int	(*neigh_setup)(struct neighbour *);
-	void	(*neigh_destructor)(struct neighbour *);
+	void	(*neigh_cleanup)(struct neighbour *);
 	struct neigh_table *tbl;
 
 	void	*sysctl_table;
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index b902d24..02647fe 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -352,10 +352,13 @@
 static inline int
 tcf_match_indev(struct sk_buff *skb, char *indev)
 {
+	struct net_device *dev;
+
 	if (indev[0]) {
-		if  (!skb->input_dev)
+		if  (!skb->iif)
 			return 0;
-		if (strcmp(indev, skb->input_dev->name))
+		dev = __dev_get_by_index(skb->iif);
+		if (!dev || strcmp(indev, dev->name))
 			return 0;
 	}
 
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 31a8e88..f431acf 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1002,6 +1002,7 @@
 void sctp_transport_raise_cwnd(struct sctp_transport *, __u32, __u32);
 void sctp_transport_lower_cwnd(struct sctp_transport *, sctp_lower_cwnd_t);
 unsigned long sctp_transport_timeout(struct sctp_transport *);
+void sctp_transport_reset(struct sctp_transport *);
 
 
 /* This is the structure we use to queue packets as they come into
diff --git a/include/net/sctp/ulpqueue.h b/include/net/sctp/ulpqueue.h
index a43c878..ab26ab3 100644
--- a/include/net/sctp/ulpqueue.h
+++ b/include/net/sctp/ulpqueue.h
@@ -59,6 +59,7 @@
 /* Prototypes. */
 struct sctp_ulpq *sctp_ulpq_init(struct sctp_ulpq *,
 				 struct sctp_association *);
+void sctp_ulpq_flush(struct sctp_ulpq *ulpq);
 void sctp_ulpq_free(struct sctp_ulpq *);
 
 /* Add a new DATA chunk for processing. */
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 92a1fc4..5a00aa8 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -988,8 +988,9 @@
 int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
 struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
 					  struct xfrm_selector *sel,
-					  struct xfrm_sec_ctx *ctx, int delete);
-struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete);
+					  struct xfrm_sec_ctx *ctx, int delete,
+					  int *err);
+struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete, int *err);
 void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
 u32 xfrm_get_acqseq(void);
 void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi);
diff --git a/include/sound/version.h b/include/sound/version.h
index 5f72750..42a18cc 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by alsa/ksync script.  */
 #define CONFIG_SND_VERSION "1.0.14rc3"
-#define CONFIG_SND_DATE " (Tue Mar 06 13:10:00 2007 UTC)"
+#define CONFIG_SND_DATE " (Wed Mar 14 07:25:50 2007 UTC)"
diff --git a/ipc/util.c b/ipc/util.c
index 08a6479..0b65238 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -144,6 +144,13 @@
 	shm_exit_ns(ns);
 	kfree(ns);
 }
+#else
+int copy_ipcs(unsigned long flags, struct task_struct *tsk)
+{
+	if (flags & CLONE_NEWIPC)
+		return -EINVAL;
+	return 0;
+}
 #endif
 
 /**
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 3599558..628c7ac 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -739,28 +739,26 @@
 void audit_log_task_context(struct audit_buffer *ab)
 {
 	char *ctx = NULL;
-	ssize_t len = 0;
+	unsigned len;
+	int error;
+	u32 sid;
 
-	len = security_getprocattr(current, "current", NULL, 0);
-	if (len < 0) {
-		if (len != -EINVAL)
+	selinux_get_task_sid(current, &sid);
+	if (!sid)
+		return;
+
+	error = selinux_sid_to_string(sid, &ctx, &len);
+	if (error) {
+		if (error != -EINVAL)
 			goto error_path;
 		return;
 	}
 
-	ctx = kmalloc(len, GFP_KERNEL);
-	if (!ctx)
-		goto error_path;
-
-	len = security_getprocattr(current, "current", ctx, len);
-	if (len < 0 )
-		goto error_path;
-
 	audit_log_format(ab, " subj=%s", ctx);
+	kfree(ctx);
 	return;
 
 error_path:
-	kfree(ctx);
 	audit_panic("error in audit_log_task_context");
 	return;
 }
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 3d4206a..36e7084 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -254,6 +254,12 @@
 }
 
 #ifdef CONFIG_SUSPEND_SMP
+/* Needed to prevent the microcode driver from requesting firmware in its CPU
+ * hotplug notifier during the suspend/resume.
+ */
+int suspend_cpu_hotplug;
+EXPORT_SYMBOL(suspend_cpu_hotplug);
+
 static cpumask_t frozen_cpus;
 
 int disable_nonboot_cpus(void)
@@ -261,16 +267,8 @@
 	int cpu, first_cpu, error = 0;
 
 	mutex_lock(&cpu_add_remove_lock);
-	first_cpu = first_cpu(cpu_present_map);
-	if (!cpu_online(first_cpu)) {
-		error = _cpu_up(first_cpu);
-		if (error) {
-			printk(KERN_ERR "Could not bring CPU%d up.\n",
-				first_cpu);
-			goto out;
-		}
-	}
-
+	suspend_cpu_hotplug = 1;
+	first_cpu = first_cpu(cpu_online_map);
 	/* We take down all of the non-boot CPUs in one shot to avoid races
 	 * with the userspace trying to use the CPU hotplug at the same time
 	 */
@@ -296,7 +294,7 @@
 	} else {
 		printk(KERN_ERR "Non-boot CPUs are not disabled\n");
 	}
-out:
+	suspend_cpu_hotplug = 0;
 	mutex_unlock(&cpu_add_remove_lock);
 	return error;
 }
@@ -308,20 +306,22 @@
 	/* Allow everyone to use the CPU hotplug again */
 	mutex_lock(&cpu_add_remove_lock);
 	cpu_hotplug_disabled = 0;
-	mutex_unlock(&cpu_add_remove_lock);
 	if (cpus_empty(frozen_cpus))
-		return;
+		goto out;
 
+	suspend_cpu_hotplug = 1;
 	printk("Enabling non-boot CPUs ...\n");
 	for_each_cpu_mask(cpu, frozen_cpus) {
-		error = cpu_up(cpu);
+		error = _cpu_up(cpu);
 		if (!error) {
 			printk("CPU%d is up\n", cpu);
 			continue;
 		}
-		printk(KERN_WARNING "Error taking CPU%d up: %d\n",
-			cpu, error);
+		printk(KERN_WARNING "Error taking CPU%d up: %d\n", cpu, error);
 	}
 	cpus_clear(frozen_cpus);
+	suspend_cpu_hotplug = 0;
+out:
+	mutex_unlock(&cpu_add_remove_lock);
 }
 #endif
diff --git a/kernel/exit.c b/kernel/exit.c
index f132349..b55ed4c 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -790,7 +790,7 @@
 	
 	pgrp = task_pgrp(tsk);
 	if ((task_pgrp(t) != pgrp) &&
-	    (task_session(t) != task_session(tsk)) &&
+	    (task_session(t) == task_session(tsk)) &&
 	    will_become_orphaned_pgrp(pgrp, tsk) &&
 	    has_stopped_jobs(pgrp)) {
 		__kill_pgrp_info(SIGHUP, SEND_SIG_PRIV, pgrp);
diff --git a/kernel/fork.c b/kernel/fork.c
index d154cc7..6af959c 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -933,8 +933,8 @@
 
 static inline void rt_mutex_init_task(struct task_struct *p)
 {
-#ifdef CONFIG_RT_MUTEXES
 	spin_lock_init(&p->pi_lock);
+#ifdef CONFIG_RT_MUTEXES
 	plist_head_init(&p->pi_waiters, &p->pi_lock);
 	p->pi_blocked_on = NULL;
 #endif
diff --git a/kernel/futex.c b/kernel/futex.c
index e749e7d..5a270b5 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -565,6 +565,7 @@
 	if (!pi_state)
 		return -EINVAL;
 
+	spin_lock(&pi_state->pi_mutex.wait_lock);
 	new_owner = rt_mutex_next_owner(&pi_state->pi_mutex);
 
 	/*
@@ -604,6 +605,7 @@
 	pi_state->owner = new_owner;
 	spin_unlock_irq(&new_owner->pi_lock);
 
+	spin_unlock(&pi_state->pi_mutex.wait_lock);
 	rt_mutex_unlock(&pi_state->pi_mutex);
 
 	return 0;
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index ec4cb9f..b74860a 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -135,7 +135,7 @@
 static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base)
 {
 	ktime_t xtim, tomono;
-	struct timespec xts;
+	struct timespec xts, tom;
 	unsigned long seq;
 
 	do {
@@ -145,10 +145,11 @@
 #else
 		xts = xtime;
 #endif
+		tom = wall_to_monotonic;
 	} while (read_seqretry(&xtime_lock, seq));
 
 	xtim = timespec_to_ktime(xts);
-	tomono = timespec_to_ktime(wall_to_monotonic);
+	tomono = timespec_to_ktime(tom);
 	base->clock_base[CLOCK_REALTIME].softirq_time = xtim;
 	base->clock_base[CLOCK_MONOTONIC].softirq_time =
 		ktime_add(xtim, tomono);
@@ -458,6 +459,18 @@
 }
 
 /*
+ * During resume we might have to reprogram the high resolution timer
+ * interrupt (on the local CPU):
+ */
+void hres_timers_resume(void)
+{
+	WARN_ON_ONCE(num_online_cpus() > 1);
+
+	/* Retrigger the CPU local events: */
+	retrigger_next_event(NULL);
+}
+
+/*
  * Check, whether the timer is on the callback pending list
  */
 static inline int hrtimer_cb_pending(const struct hrtimer *timer)
@@ -644,6 +657,12 @@
 		orun++;
 	}
 	timer->expires = ktime_add(timer->expires, interval);
+	/*
+	 * Make sure, that the result did not wrap with a very large
+	 * interval.
+	 */
+	if (timer->expires.tv64 < 0)
+		timer->expires = ktime_set(KTIME_SEC_MAX, 0);
 
 	return orun;
 }
@@ -807,7 +826,12 @@
 
 	timer_stats_hrtimer_set_start_info(timer);
 
-	enqueue_hrtimer(timer, new_base, base == new_base);
+	/*
+	 * Only allow reprogramming if the new base is on this CPU.
+	 * (it might still be on another CPU if the timer was pending)
+	 */
+	enqueue_hrtimer(timer, new_base,
+			new_base->cpu_base == &__get_cpu_var(hrtimer_bases));
 
 	unlock_hrtimer_base(timer, &flags);
 
diff --git a/kernel/irq/devres.c b/kernel/irq/devres.c
index 85a430d..d8ee241 100644
--- a/kernel/irq/devres.c
+++ b/kernel/irq/devres.c
@@ -54,7 +54,7 @@
 
 	rc = request_irq(irq, handler, irqflags, devname, dev_id);
 	if (rc) {
-		kfree(dr);
+		devres_free(dr);
 		return rc;
 	}
 
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 8dc24c92..7065a68 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -2742,6 +2742,10 @@
 	int count = 10;
 	int unlock = 1;
 
+	if (unlikely(!debug_locks)) {
+		printk("INFO: lockdep is turned off.\n");
+		return;
+	}
 	printk("\nShowing all locks held in the system:\n");
 
 	/*
@@ -2785,6 +2789,10 @@
 
 void debug_show_held_locks(struct task_struct *task)
 {
+	if (unlikely(!debug_locks)) {
+		printk("INFO: lockdep is turned off.\n");
+		return;
+	}
 	lockdep_print_held_locks(task);
 }
 
diff --git a/kernel/module.c b/kernel/module.c
index f77e893..dcdb32b 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2384,8 +2384,13 @@
 
 		/* Lookup built-in module entry in /sys/modules */
 		mkobj = kset_find_obj(&module_subsys.kset, drv->mod_name);
-		if (mkobj)
+		if (mkobj) {
 			mk = container_of(mkobj, struct module_kobject, kobj);
+			/* remember our module structure */
+			drv->mkobj = mk;
+			/* kset_find_obj took a reference */
+			kobject_put(mkobj);
+		}
 	}
 
 	if (!mk)
@@ -2405,26 +2410,25 @@
 
 void module_remove_driver(struct device_driver *drv)
 {
+	struct module_kobject *mk = NULL;
 	char *driver_name;
 
 	if (!drv)
 		return;
 
 	sysfs_remove_link(&drv->kobj, "module");
-	if (drv->owner && drv->owner->mkobj.drivers_dir) {
+
+	if (drv->owner)
+		mk = &drv->owner->mkobj;
+	else if (drv->mkobj)
+		mk = drv->mkobj;
+	if (mk && mk->drivers_dir) {
 		driver_name = make_driver_name(drv);
 		if (driver_name) {
-			sysfs_remove_link(drv->owner->mkobj.drivers_dir,
-					  driver_name);
+			sysfs_remove_link(mk->drivers_dir, driver_name);
 			kfree(driver_name);
 		}
 	}
-	/*
-	 * Undo the additional reference we added in module_add_driver()
-	 * via kset_find_obj()
-	 */
-	if (drv->mod_name)
-		kobject_put(&drv->kobj);
 }
 EXPORT_SYMBOL(module_remove_driver);
 #endif
diff --git a/kernel/power/console.c b/kernel/power/console.c
index 623786d..89bcf49 100644
--- a/kernel/power/console.c
+++ b/kernel/power/console.c
@@ -27,7 +27,15 @@
 		return 1;
 	}
 
-	set_console(SUSPEND_CONSOLE);
+	if (set_console(SUSPEND_CONSOLE)) {
+		/*
+		 * We're unable to switch to the SUSPEND_CONSOLE.
+		 * Let the calling function know so it can decide
+		 * what to do.
+		 */
+		release_console_sem();
+		return 1;
+	}
 	release_console_sem();
 
 	if (vt_waitactive(SUSPEND_CONSOLE)) {
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 406b20a..aec19b0 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -240,12 +240,6 @@
 		goto Done;
 	}
 
-	error = platform_prepare();
-	if (error) {
-		swsusp_free();
-		goto Thaw;
-	}
-
 	pr_debug("PM: Reading swsusp image.\n");
 
 	error = swsusp_read();
@@ -268,7 +262,6 @@
 	enable_nonboot_cpus();
  Free:
 	swsusp_free();
-	platform_finish();
 	device_resume();
 	resume_console();
  Thaw:
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index 7fb8343..1753708 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -229,13 +229,13 @@
 		size += highmem_size;
 		for_each_zone (zone)
 			if (populated_zone(zone)) {
+				tmp += snapshot_additional_pages(zone);
 				if (is_highmem(zone)) {
 					highmem_size -=
 					zone_page_state(zone, NR_FREE_PAGES);
 				} else {
 					tmp -= zone_page_state(zone, NR_FREE_PAGES);
 					tmp += zone->lowmem_reserve[ZONE_NORMAL];
-					tmp += snapshot_additional_pages(zone);
 				}
 			}
 
diff --git a/kernel/power/user.c b/kernel/power/user.c
index dd09efe..7cf6713 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -368,9 +368,12 @@
 		if (error) {
 			printk(KERN_ERR "Failed to suspend some devices.\n");
 		} else {
-			/* Enter S3, system is already frozen */
-			suspend_enter(PM_SUSPEND_MEM);
-
+			error = disable_nonboot_cpus();
+			if (!error) {
+				/* Enter S3, system is already frozen */
+				suspend_enter(PM_SUSPEND_MEM);
+				enable_nonboot_cpus();
+			}
 			/* Wake up devices */
 			device_resume();
 		}
diff --git a/kernel/sched.c b/kernel/sched.c
index a4ca632..b9a6837 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4687,32 +4687,10 @@
 	return retval;
 }
 
-static inline struct task_struct *eldest_child(struct task_struct *p)
-{
-	if (list_empty(&p->children))
-		return NULL;
-	return list_entry(p->children.next,struct task_struct,sibling);
-}
-
-static inline struct task_struct *older_sibling(struct task_struct *p)
-{
-	if (p->sibling.prev==&p->parent->children)
-		return NULL;
-	return list_entry(p->sibling.prev,struct task_struct,sibling);
-}
-
-static inline struct task_struct *younger_sibling(struct task_struct *p)
-{
-	if (p->sibling.next==&p->parent->children)
-		return NULL;
-	return list_entry(p->sibling.next,struct task_struct,sibling);
-}
-
 static const char stat_nam[] = "RSDTtZX";
 
 static void show_task(struct task_struct *p)
 {
-	struct task_struct *relative;
 	unsigned long free = 0;
 	unsigned state;
 
@@ -4738,19 +4716,7 @@
 		free = (unsigned long)n - (unsigned long)end_of_stack(p);
 	}
 #endif
-	printk("%5lu %5d %6d ", free, p->pid, p->parent->pid);
-	if ((relative = eldest_child(p)))
-		printk("%5d ", relative->pid);
-	else
-		printk("      ");
-	if ((relative = younger_sibling(p)))
-		printk("%7d", relative->pid);
-	else
-		printk("       ");
-	if ((relative = older_sibling(p)))
-		printk(" %5d", relative->pid);
-	else
-		printk("      ");
+	printk("%5lu %5d %6d", free, p->pid, p->parent->pid);
 	if (!p->mm)
 		printk(" (L-TLB)\n");
 	else
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 34b2301..1b255df 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -846,7 +846,8 @@
 		.extra2		= &one_hundred,
 	},
 #endif
-#ifdef CONFIG_X86_32
+#if defined(CONFIG_X86_32) || \
+   (defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL))
 	{
 		.ctl_name	= VM_VDSO_ENABLED,
 		.procname	= "vdso_enabled",
diff --git a/kernel/time.c b/kernel/time.c
index c6c80ea5..2f47888 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -635,6 +635,7 @@
 		(((u64)usec * USEC_CONVERSION + USEC_ROUND) >>
 		 (USEC_JIFFIE_SC - SEC_JIFFIE_SC))) >> SEC_JIFFIE_SC;
 }
+EXPORT_SYMBOL(timeval_to_jiffies);
 
 void jiffies_to_timeval(const unsigned long jiffies, struct timeval *value)
 {
@@ -649,6 +650,7 @@
 	tv_usec /= NSEC_PER_USEC;
 	value->tv_usec = tv_usec;
 }
+EXPORT_SYMBOL(jiffies_to_timeval);
 
 /*
  * Convert jiffies/jiffies_64 to clock_t and back.
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 67932ea..76212b2 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -274,72 +274,3 @@
 }
 EXPORT_SYMBOL_GPL(clockevents_notify);
 
-#ifdef CONFIG_SYSFS
-
-/**
- * clockevents_show_registered - sysfs interface for listing clockevents
- * @dev:	unused
- * @buf:	char buffer to be filled with clock events list
- *
- * Provides sysfs interface for listing registered clock event devices
- */
-static ssize_t clockevents_show_registered(struct sys_device *dev, char *buf)
-{
-	struct list_head *tmp;
-	char *p = buf;
-	int cpu;
-
-	spin_lock(&clockevents_lock);
-
-	list_for_each(tmp, &clockevent_devices) {
-		struct clock_event_device *ce;
-
-		ce = list_entry(tmp, struct clock_event_device, list);
-		p += sprintf(p, "%-20s F:%04x M:%d", ce->name,
-			     ce->features, ce->mode);
-		p += sprintf(p, " C:");
-		if (!cpus_equal(ce->cpumask, cpu_possible_map)) {
-			for_each_cpu_mask(cpu, ce->cpumask)
-				p += sprintf(p, " %d", cpu);
-		} else {
-			/*
-			 * FIXME: Add the cpu which is handling this sucker
-			 */
-		}
-		p += sprintf(p, "\n");
-	}
-
-	spin_unlock(&clockevents_lock);
-
-	return p - buf;
-}
-
-/*
- * Sysfs setup bits:
- */
-static SYSDEV_ATTR(registered, 0600,
-		   clockevents_show_registered, NULL);
-
-static struct sysdev_class clockevents_sysclass = {
-	set_kset_name("clockevents"),
-};
-
-static struct sys_device clockevents_sys_device = {
-	.id	= 0,
-	.cls	= &clockevents_sysclass,
-};
-
-static int __init clockevents_sysfs_init(void)
-{
-	int error = sysdev_class_register(&clockevents_sysclass);
-
-	if (!error)
-		error = sysdev_register(&clockevents_sys_device);
-	if (!error)
-		error = sysdev_create_file(
-				&clockevents_sys_device,
-				&attr_registered);
-	return error;
-}
-device_initcall(clockevents_sysfs_init);
-#endif
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index 5b0e46b..fe5c7db 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -151,7 +151,8 @@
 			watchdog_timer.expires = jiffies + WATCHDOG_INTERVAL;
 			add_timer(&watchdog_timer);
 		}
-	} else if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) {
+	} else {
+		if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS)
 			cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES;
 
 		if (!watchdog || cs->rating > watchdog->rating) {
diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c
index 3be8da8..4c256fd 100644
--- a/kernel/time/jiffies.c
+++ b/kernel/time/jiffies.c
@@ -69,4 +69,4 @@
 	return clocksource_register(&clocksource_jiffies);
 }
 
-module_init(init_jiffies_clocksource);
+core_initcall(init_jiffies_clocksource);
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index eb12509..cb25649 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -32,7 +32,7 @@
 /* TIME_ERROR prevents overwriting the CMOS clock */
 static int time_state = TIME_OK;	/* clock synchronization status	*/
 int time_status = STA_UNSYNC;		/* clock status bits		*/
-static long time_offset;		/* time adjustment (ns)		*/
+static s64 time_offset;		/* time adjustment (ns)		*/
 static long time_constant = 2;		/* pll time constant		*/
 long time_maxerror = NTP_PHASE_LIMIT;	/* maximum error (us)		*/
 long time_esterror = NTP_PHASE_LIMIT;	/* estimated error (us)		*/
@@ -196,7 +196,7 @@
  */
 int do_adjtimex(struct timex *txc)
 {
-	long ltemp, mtemp, save_adjust;
+	long mtemp, save_adjust, rem;
 	s64 freq_adj, temp64;
 	int result;
 
@@ -277,14 +277,14 @@
 		    time_adjust = txc->offset;
 		}
 		else if (time_status & STA_PLL) {
-		    ltemp = txc->offset * NSEC_PER_USEC;
+		    time_offset = txc->offset * NSEC_PER_USEC;
 
 		    /*
 		     * Scale the phase adjustment and
 		     * clamp to the operating range.
 		     */
-		    time_offset = min(ltemp, MAXPHASE * NSEC_PER_USEC);
-		    time_offset = max(time_offset, -MAXPHASE * NSEC_PER_USEC);
+		    time_offset = min(time_offset, (s64)MAXPHASE * NSEC_PER_USEC);
+		    time_offset = max(time_offset, (s64)-MAXPHASE * NSEC_PER_USEC);
 
 		    /*
 		     * Select whether the frequency is to be controlled
@@ -297,11 +297,11 @@
 		    mtemp = xtime.tv_sec - time_reftime;
 		    time_reftime = xtime.tv_sec;
 
-		    freq_adj = (s64)time_offset * mtemp;
+		    freq_adj = time_offset * mtemp;
 		    freq_adj = shift_right(freq_adj, time_constant * 2 +
 					   (SHIFT_PLL + 2) * 2 - SHIFT_NSEC);
 		    if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) {
-			temp64 = (s64)time_offset << (SHIFT_NSEC - SHIFT_FLL);
+			temp64 = time_offset << (SHIFT_NSEC - SHIFT_FLL);
 			if (time_offset < 0) {
 			    temp64 = -temp64;
 			    do_div(temp64, mtemp);
@@ -314,8 +314,10 @@
 		    freq_adj += time_freq;
 		    freq_adj = min(freq_adj, (s64)MAXFREQ_NSEC);
 		    time_freq = max(freq_adj, (s64)-MAXFREQ_NSEC);
-		    time_offset = (time_offset / NTP_INTERVAL_FREQ)
-		    			<< SHIFT_UPDATE;
+		    time_offset = div_long_long_rem_signed(time_offset,
+							   NTP_INTERVAL_FREQ,
+							   &rem);
+		    time_offset <<= SHIFT_UPDATE;
 		} /* STA_PLL */
 	    } /* txc->modes & ADJ_OFFSET */
 	    if (txc->modes & ADJ_TICK)
@@ -328,12 +330,12 @@
 		result = TIME_ERROR;
 
 	if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
-	    txc->offset	   = save_adjust;
+		txc->offset = save_adjust;
 	else
-	    txc->offset    = shift_right(time_offset, SHIFT_UPDATE)
-	    			* NTP_INTERVAL_FREQ / 1000;
-	txc->freq	   = (time_freq / NSEC_PER_USEC)
-				<< (SHIFT_USEC - SHIFT_NSEC);
+		txc->offset = ((long)shift_right(time_offset, SHIFT_UPDATE)) *
+	    			NTP_INTERVAL_FREQ / 1000;
+	txc->freq	   = (time_freq / NSEC_PER_USEC) <<
+				(SHIFT_USEC - SHIFT_NSEC);
 	txc->maxerror	   = time_maxerror;
 	txc->esterror	   = time_esterror;
 	txc->status	   = time_status;
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index 5567745..eadfce2 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -307,12 +307,19 @@
 	spin_lock_irqsave(&tick_broadcast_lock, flags);
 
 	bc = tick_broadcast_device.evtdev;
-	if (bc) {
-		if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC &&
-		    !cpus_empty(tick_broadcast_mask))
-			tick_broadcast_start_periodic(bc);
 
-		broadcast = cpu_isset(smp_processor_id(), tick_broadcast_mask);
+	if (bc) {
+		switch (tick_broadcast_device.mode) {
+		case TICKDEV_MODE_PERIODIC:
+			if(!cpus_empty(tick_broadcast_mask))
+				tick_broadcast_start_periodic(bc);
+			broadcast = cpu_isset(smp_processor_id(),
+					      tick_broadcast_mask);
+			break;
+		case TICKDEV_MODE_ONESHOT:
+			broadcast = tick_resume_broadcast_oneshot(bc);
+			break;
+		}
 	}
 	spin_unlock_irqrestore(&tick_broadcast_lock, flags);
 
@@ -347,6 +354,16 @@
 	}
 }
 
+int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
+{
+	clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
+
+	if(!cpus_empty(tick_broadcast_oneshot_mask))
+		tick_broadcast_set_event(ktime_get(), 1);
+
+	return cpu_isset(smp_processor_id(), tick_broadcast_oneshot_mask);
+}
+
 /*
  * Reprogram the broadcast device:
  *
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index 43ba1bd..bfda3f7 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -298,18 +298,17 @@
 	spin_unlock_irqrestore(&tick_device_lock, flags);
 }
 
-static void tick_suspend_periodic(void)
+static void tick_suspend(void)
 {
 	struct tick_device *td = &__get_cpu_var(tick_cpu_device);
 	unsigned long flags;
 
 	spin_lock_irqsave(&tick_device_lock, flags);
-	if (td->mode == TICKDEV_MODE_PERIODIC)
-		clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_SHUTDOWN);
+	clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_SHUTDOWN);
 	spin_unlock_irqrestore(&tick_device_lock, flags);
 }
 
-static void tick_resume_periodic(void)
+static void tick_resume(void)
 {
 	struct tick_device *td = &__get_cpu_var(tick_cpu_device);
 	unsigned long flags;
@@ -317,6 +316,8 @@
 	spin_lock_irqsave(&tick_device_lock, flags);
 	if (td->mode == TICKDEV_MODE_PERIODIC)
 		tick_setup_periodic(td->evtdev, 0);
+	else
+		tick_resume_oneshot();
 	spin_unlock_irqrestore(&tick_device_lock, flags);
 }
 
@@ -348,13 +349,13 @@
 		break;
 
 	case CLOCK_EVT_NOTIFY_SUSPEND:
-		tick_suspend_periodic();
+		tick_suspend();
 		tick_suspend_broadcast();
 		break;
 
 	case CLOCK_EVT_NOTIFY_RESUME:
 		if (!tick_resume_broadcast())
-			tick_resume_periodic();
+			tick_resume();
 		break;
 
 	default:
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index 75890ef..c9d203b 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -19,12 +19,13 @@
 extern int tick_program_event(ktime_t expires, int force);
 extern void tick_oneshot_notify(void);
 extern int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *));
-
+extern void tick_resume_oneshot(void);
 # ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
 extern void tick_broadcast_setup_oneshot(struct clock_event_device *bc);
 extern void tick_broadcast_oneshot_control(unsigned long reason);
 extern void tick_broadcast_switch_to_oneshot(void);
 extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup);
+extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc);
 # else /* BROADCAST */
 static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
 {
@@ -43,6 +44,10 @@
 {
 	BUG();
 }
+static inline void tick_resume_oneshot(void)
+{
+	BUG();
+}
 static inline int tick_program_event(ktime_t expires, int force)
 {
 	return 0;
@@ -54,6 +59,10 @@
 }
 static inline void tick_broadcast_oneshot_control(unsigned long reason) { }
 static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
+static inline int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
+{
+	return 0;
+}
 #endif /* !TICK_ONESHOT */
 
 /*
diff --git a/kernel/time/tick-oneshot.c b/kernel/time/tick-oneshot.c
index 2e8b7ff..f6997ab 100644
--- a/kernel/time/tick-oneshot.c
+++ b/kernel/time/tick-oneshot.c
@@ -41,6 +41,18 @@
 }
 
 /**
+ * tick_resume_onshot - resume oneshot mode
+ */
+void tick_resume_oneshot(void)
+{
+	struct tick_device *td = &__get_cpu_var(tick_cpu_device);
+	struct clock_event_device *dev = td->evtdev;
+
+	clockevents_set_mode(dev, CLOCK_EVT_MODE_ONESHOT);
+	tick_program_event(ktime_get(), 1);
+}
+
+/**
  * tick_setup_oneshot - setup the event device for oneshot mode (hres or nohz)
  */
 void tick_setup_oneshot(struct clock_event_device *newdev,
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
index f82c635..59df5e8 100644
--- a/kernel/time/timer_list.c
+++ b/kernel/time/timer_list.c
@@ -194,9 +194,9 @@
 		return;
 	}
 	SEQ_printf(m, "%s\n", dev->name);
-	SEQ_printf(m, " max_delta_ns:   %ld\n", dev->max_delta_ns);
-	SEQ_printf(m, " min_delta_ns:   %ld\n", dev->min_delta_ns);
-	SEQ_printf(m, " mult:           %ld\n", dev->mult);
+	SEQ_printf(m, " max_delta_ns:   %lu\n", dev->max_delta_ns);
+	SEQ_printf(m, " min_delta_ns:   %lu\n", dev->min_delta_ns);
+	SEQ_printf(m, " mult:           %lu\n", dev->mult);
 	SEQ_printf(m, " shift:          %d\n", dev->shift);
 	SEQ_printf(m, " mode:           %d\n", dev->mode);
 	SEQ_printf(m, " next_event:     %Ld nsecs\n",
diff --git a/kernel/timer.c b/kernel/timer.c
index 797cccb..dd6c2c1 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -695,15 +695,28 @@
 {
 	ktime_t hr_delta = hrtimer_get_next_event();
 	struct timespec tsdelta;
+	unsigned long delta;
 
 	if (hr_delta.tv64 == KTIME_MAX)
 		return expires;
 
-	if (hr_delta.tv64 <= TICK_NSEC)
-		return now;
+	/*
+	 * Expired timer available, let it expire in the next tick
+	 */
+	if (hr_delta.tv64 <= 0)
+		return now + 1;
 
 	tsdelta = ktime_to_timespec(hr_delta);
-	now += timespec_to_jiffies(&tsdelta);
+	delta = timespec_to_jiffies(&tsdelta);
+	/*
+	 * Take rounding errors in to account and make sure, that it
+	 * expires in the next tick. Otherwise we go into an endless
+	 * ping pong due to tick_nohz_stop_sched_tick() retriggering
+	 * the timer softirq
+	 */
+	if (delta < 1)
+		delta = 1;
+	now += delta;
 	if (time_before(now, expires))
 		return now;
 	return expires;
@@ -1003,7 +1016,7 @@
 	clockevents_notify(CLOCK_EVT_NOTIFY_RESUME, NULL);
 
 	/* Resume hrtimers */
-	clock_was_set();
+	hres_timers_resume();
 
 	return 0;
 }
diff --git a/lib/kobject.c b/lib/kobject.c
index f4f6176..057921c 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -385,9 +385,11 @@
 		goto out;
 	old_parent = kobj->parent;
 	kobj->parent = new_parent;
+	new_parent = NULL;
 	kobject_put(old_parent);
 	kobject_uevent_env(kobj, KOBJ_MOVE, envp);
 out:
+	kobject_put(new_parent);
 	kobject_put(kobj);
 	kfree(devpath_string);
 	kfree(devpath);
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index f50a281..e5de378 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -55,6 +55,22 @@
 }
 EXPORT_SYMBOL(congestion_wait);
 
+long congestion_wait_interruptible(int rw, long timeout)
+{
+	long ret;
+	DEFINE_WAIT(wait);
+	wait_queue_head_t *wqh = &congestion_wqh[rw];
+
+	prepare_to_wait(wqh, &wait, TASK_INTERRUPTIBLE);
+	if (signal_pending(current))
+		ret = -ERESTARTSYS;
+	else
+		ret = io_schedule_timeout(timeout);
+	finish_wait(wqh, &wait);
+	return ret;
+}
+EXPORT_SYMBOL(congestion_wait_interruptible);
+
 /**
  * congestion_end - wake up sleepers on a congested backing_dev_info
  * @rw: READ or WRITE
diff --git a/mm/bounce.c b/mm/bounce.c
index 643efbe..ad401fc 100644
--- a/mm/bounce.c
+++ b/mm/bounce.c
@@ -204,7 +204,7 @@
 		/*
 		 * is destination page below bounce pfn?
 		 */
-		if (page_to_pfn(page) < q->bounce_pfn)
+		if (page_to_pfn(page) <= q->bounce_pfn)
 			continue;
 
 		/*
diff --git a/mm/filemap.c b/mm/filemap.c
index d1060b8..5dfc093 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2379,7 +2379,8 @@
 	struct file *file = iocb->ki_filp;
 	struct address_space *mapping = file->f_mapping;
 	ssize_t retval;
-	size_t write_len = 0;
+	size_t write_len;
+	pgoff_t end = 0; /* silence gcc */
 
 	/*
 	 * If it's a write, unmap all mmappings of the file up-front.  This
@@ -2388,23 +2389,46 @@
 	 */
 	if (rw == WRITE) {
 		write_len = iov_length(iov, nr_segs);
+		end = (offset + write_len - 1) >> PAGE_CACHE_SHIFT;
 	       	if (mapping_mapped(mapping))
 			unmap_mapping_range(mapping, offset, write_len, 0);
 	}
 
 	retval = filemap_write_and_wait(mapping);
-	if (retval == 0) {
-		retval = mapping->a_ops->direct_IO(rw, iocb, iov,
-						offset, nr_segs);
-		if (rw == WRITE && mapping->nrpages) {
-			pgoff_t end = (offset + write_len - 1)
-						>> PAGE_CACHE_SHIFT;
-			int err = invalidate_inode_pages2_range(mapping,
+	if (retval)
+		goto out;
+
+	/*
+	 * After a write we want buffered reads to be sure to go to disk to get
+	 * the new data.  We invalidate clean cached page from the region we're
+	 * about to write.  We do this *before* the write so that we can return
+	 * -EIO without clobbering -EIOCBQUEUED from ->direct_IO().
+	 */
+	if (rw == WRITE && mapping->nrpages) {
+		retval = invalidate_inode_pages2_range(mapping,
 					offset >> PAGE_CACHE_SHIFT, end);
-			if (err)
-				retval = err;
-		}
+		if (retval)
+			goto out;
 	}
+
+	retval = mapping->a_ops->direct_IO(rw, iocb, iov, offset, nr_segs);
+	if (retval)
+		goto out;
+
+	/*
+	 * Finally, try again to invalidate clean pages which might have been
+	 * faulted in by get_user_pages() if the source of the write was an
+	 * mmap()ed region of the file we're writing.  That's a pretty crazy
+	 * thing to do, so we don't support it 100%.  If this invalidation
+	 * fails and we have -EIOCBQUEUED we ignore the failure.
+	 */
+	if (rw == WRITE && mapping->nrpages) {
+		int err = invalidate_inode_pages2_range(mapping,
+					      offset >> PAGE_CACHE_SHIFT, end);
+		if (err && retval >= 0)
+			retval = err;
+	}
+out:
 	return retval;
 }
 
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
index 9dd9fbb..cbb3358 100644
--- a/mm/filemap_xip.c
+++ b/mm/filemap_xip.c
@@ -17,6 +17,29 @@
 #include "filemap.h"
 
 /*
+ * We do use our own empty page to avoid interference with other users
+ * of ZERO_PAGE(), such as /dev/zero
+ */
+static struct page *__xip_sparse_page;
+
+static struct page *xip_sparse_page(void)
+{
+	if (!__xip_sparse_page) {
+		unsigned long zeroes = get_zeroed_page(GFP_HIGHUSER);
+		if (zeroes) {
+			static DEFINE_SPINLOCK(xip_alloc_lock);
+			spin_lock(&xip_alloc_lock);
+			if (!__xip_sparse_page)
+				__xip_sparse_page = virt_to_page(zeroes);
+			else
+				free_page(zeroes);
+			spin_unlock(&xip_alloc_lock);
+		}
+	}
+	return __xip_sparse_page;
+}
+
+/*
  * This is a file read routine for execute in place files, and uses
  * the mapping->a_ops->get_xip_page() function for the actual low-level
  * stuff.
@@ -162,7 +185,7 @@
  * xip_write
  *
  * This function walks all vmas of the address_space and unmaps the
- * ZERO_PAGE when found at pgoff. Should it go in rmap.c?
+ * __xip_sparse_page when found at pgoff.
  */
 static void
 __xip_unmap (struct address_space * mapping,
@@ -177,13 +200,16 @@
 	spinlock_t *ptl;
 	struct page *page;
 
+	page = __xip_sparse_page;
+	if (!page)
+		return;
+
 	spin_lock(&mapping->i_mmap_lock);
 	vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
 		mm = vma->vm_mm;
 		address = vma->vm_start +
 			((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
 		BUG_ON(address < vma->vm_start || address >= vma->vm_end);
-		page = ZERO_PAGE(0);
 		pte = page_check_address(page, mm, address, &ptl);
 		if (pte) {
 			/* Nuke the page table entry. */
@@ -222,16 +248,14 @@
 		+ area->vm_pgoff;
 
 	size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-	if (pgoff >= size) {
-		return NULL;
-	}
+	if (pgoff >= size)
+		return NOPAGE_SIGBUS;
 
 	page = mapping->a_ops->get_xip_page(mapping, pgoff*(PAGE_SIZE/512), 0);
-	if (!IS_ERR(page)) {
+	if (!IS_ERR(page))
 		goto out;
-	}
 	if (PTR_ERR(page) != -ENODATA)
-		return NULL;
+		return NOPAGE_SIGBUS;
 
 	/* sparse block */
 	if ((area->vm_flags & (VM_WRITE | VM_MAYWRITE)) &&
@@ -241,12 +265,14 @@
 		page = mapping->a_ops->get_xip_page (mapping,
 			pgoff*(PAGE_SIZE/512), 1);
 		if (IS_ERR(page))
-			return NULL;
+			return NOPAGE_SIGBUS;
 		/* unmap page at pgoff from all other vmas */
 		__xip_unmap(mapping, pgoff);
 	} else {
-		/* not shared and writable, use ZERO_PAGE() */
-		page = ZERO_PAGE(0);
+		/* not shared and writable, use xip_sparse_page() */
+		page = xip_sparse_page();
+		if (!page)
+			return NOPAGE_OOM;
 	}
 
 out:
diff --git a/mm/madvise.c b/mm/madvise.c
index 4e19615..603c525 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -155,10 +155,14 @@
  * Other filesystems return -ENOSYS.
  */
 static long madvise_remove(struct vm_area_struct *vma,
+				struct vm_area_struct **prev,
 				unsigned long start, unsigned long end)
 {
 	struct address_space *mapping;
-        loff_t offset, endoff;
+	loff_t offset, endoff;
+	int error;
+
+	*prev = NULL;	/* tell sys_madvise we drop mmap_sem */
 
 	if (vma->vm_flags & (VM_LOCKED|VM_NONLINEAR|VM_HUGETLB))
 		return -EINVAL;
@@ -177,7 +181,12 @@
 			+ ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
 	endoff = (loff_t)(end - vma->vm_start - 1)
 			+ ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
-	return  vmtruncate_range(mapping->host, offset, endoff);
+
+	/* vmtruncate_range needs to take i_mutex and i_alloc_sem */
+	up_write(&current->mm->mmap_sem);
+	error = vmtruncate_range(mapping->host, offset, endoff);
+	down_write(&current->mm->mmap_sem);
+	return error;
 }
 
 static long
@@ -199,7 +208,7 @@
 		error = madvise_behavior(vma, prev, start, end, behavior);
 		break;
 	case MADV_REMOVE:
-		error = madvise_remove(vma, start, end);
+		error = madvise_remove(vma, prev, start, end);
 		break;
 
 	case MADV_WILLNEED:
@@ -312,12 +321,15 @@
 		if (error)
 			goto out;
 		start = tmp;
-		if (start < prev->vm_end)
+		if (prev && start < prev->vm_end)
 			start = prev->vm_end;
 		error = unmapped_error;
 		if (start >= end)
 			goto out;
-		vma = prev->vm_next;
+		if (prev)
+			vma = prev->vm_next;
+		else	/* madvise_remove dropped mmap_sem */
+			vma = find_vma(current->mm, start);
 	}
 out:
 	up_write(&current->mm->mmap_sem);
diff --git a/mm/nommu.c b/mm/nommu.c
index 23fb033..cbbc137 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -826,6 +826,11 @@
 		unsigned long pglen = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
 		unsigned long vmpglen;
 
+		/* suppress VMA sharing for shared regions */
+		if (vm_flags & VM_SHARED &&
+		    capabilities & BDI_CAP_MAP_DIRECT)
+			goto dont_share_VMAs;
+
 		for (rb = rb_first(&nommu_vma_tree); rb; rb = rb_next(rb)) {
 			vma = rb_entry(rb, struct vm_area_struct, vm_rb);
 
@@ -859,6 +864,7 @@
 			goto shared;
 		}
 
+	dont_share_VMAs:
 		vma = NULL;
 
 		/* obtain the address at which to make a shared mapping
@@ -1193,6 +1199,28 @@
 EXPORT_SYMBOL(unmap_mapping_range);
 
 /*
+ * ask for an unmapped area at which to create a mapping on a file
+ */
+unsigned long get_unmapped_area(struct file *file, unsigned long addr,
+				unsigned long len, unsigned long pgoff,
+				unsigned long flags)
+{
+	unsigned long (*get_area)(struct file *, unsigned long, unsigned long,
+				  unsigned long, unsigned long);
+
+	get_area = current->mm->get_unmapped_area;
+	if (file && file->f_op && file->f_op->get_unmapped_area)
+		get_area = file->f_op->get_unmapped_area;
+
+	if (!get_area)
+		return -ENOSYS;
+
+	return get_area(file, addr, len, pgoff, flags);
+}
+
+EXPORT_SYMBOL(get_unmapped_area);
+
+/*
  * Check that a process has enough memory to allocate a new virtual
  * mapping. 0 means there is enough memory for the allocation to
  * succeed and -ENOMEM implies there is not.
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index b278b8d..2f39169 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -320,7 +320,7 @@
 	 * Don't kill the process if any threads are set to OOM_DISABLE
 	 */
 	do_each_thread(g, q) {
-		if (q->mm == mm && p->oomkilladj == OOM_DISABLE)
+		if (q->mm == mm && q->oomkilladj == OOM_DISABLE)
 			return 1;
 	} while_each_thread(g, q);
 
diff --git a/mm/rmap.c b/mm/rmap.c
index 22ed3f7..b82146e 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -498,9 +498,9 @@
 		struct address_space *mapping = page_mapping(page);
 		if (mapping)
 			ret = page_mkclean_file(mapping, page);
+		if (page_test_and_clear_dirty(page))
+			ret = 1;
 	}
-	if (page_test_and_clear_dirty(page))
-		ret = 1;
 
 	return ret;
 }
diff --git a/mm/shmem.c b/mm/shmem.c
index b8c429a..b2a35eb 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -402,26 +402,38 @@
 /*
  * shmem_free_swp - free some swap entries in a directory
  *
- * @dir:   pointer to the directory
- * @edir:  pointer after last entry of the directory
+ * @dir:        pointer to the directory
+ * @edir:       pointer after last entry of the directory
+ * @punch_lock: pointer to spinlock when needed for the holepunch case
  */
-static int shmem_free_swp(swp_entry_t *dir, swp_entry_t *edir)
+static int shmem_free_swp(swp_entry_t *dir, swp_entry_t *edir,
+						spinlock_t *punch_lock)
 {
+	spinlock_t *punch_unlock = NULL;
 	swp_entry_t *ptr;
 	int freed = 0;
 
 	for (ptr = dir; ptr < edir; ptr++) {
 		if (ptr->val) {
+			if (unlikely(punch_lock)) {
+				punch_unlock = punch_lock;
+				punch_lock = NULL;
+				spin_lock(punch_unlock);
+				if (!ptr->val)
+					continue;
+			}
 			free_swap_and_cache(*ptr);
 			*ptr = (swp_entry_t){0};
 			freed++;
 		}
 	}
+	if (punch_unlock)
+		spin_unlock(punch_unlock);
 	return freed;
 }
 
-static int shmem_map_and_free_swp(struct page *subdir,
-		int offset, int limit, struct page ***dir)
+static int shmem_map_and_free_swp(struct page *subdir, int offset,
+		int limit, struct page ***dir, spinlock_t *punch_lock)
 {
 	swp_entry_t *ptr;
 	int freed = 0;
@@ -431,7 +443,8 @@
 		int size = limit - offset;
 		if (size > LATENCY_LIMIT)
 			size = LATENCY_LIMIT;
-		freed += shmem_free_swp(ptr+offset, ptr+offset+size);
+		freed += shmem_free_swp(ptr+offset, ptr+offset+size,
+							punch_lock);
 		if (need_resched()) {
 			shmem_swp_unmap(ptr);
 			if (*dir) {
@@ -481,7 +494,10 @@
 	long nr_swaps_freed = 0;
 	int offset;
 	int freed;
-	int punch_hole = 0;
+	int punch_hole;
+	spinlock_t *needs_lock;
+	spinlock_t *punch_lock;
+	unsigned long upper_limit;
 
 	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
 	idx = (start + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
@@ -492,11 +508,20 @@
 	info->flags |= SHMEM_TRUNCATE;
 	if (likely(end == (loff_t) -1)) {
 		limit = info->next_index;
+		upper_limit = SHMEM_MAX_INDEX;
 		info->next_index = idx;
+		needs_lock = NULL;
+		punch_hole = 0;
 	} else {
-		limit = (end + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-		if (limit > info->next_index)
-			limit = info->next_index;
+		if (end + 1 >= inode->i_size) {	/* we may free a little more */
+			limit = (inode->i_size + PAGE_CACHE_SIZE - 1) >>
+							PAGE_CACHE_SHIFT;
+			upper_limit = SHMEM_MAX_INDEX;
+		} else {
+			limit = (end + 1) >> PAGE_CACHE_SHIFT;
+			upper_limit = limit;
+		}
+		needs_lock = &info->lock;
 		punch_hole = 1;
 	}
 
@@ -513,17 +538,30 @@
 		size = limit;
 		if (size > SHMEM_NR_DIRECT)
 			size = SHMEM_NR_DIRECT;
-		nr_swaps_freed = shmem_free_swp(ptr+idx, ptr+size);
+		nr_swaps_freed = shmem_free_swp(ptr+idx, ptr+size, needs_lock);
 	}
 
 	/*
 	 * If there are no indirect blocks or we are punching a hole
 	 * below indirect blocks, nothing to be done.
 	 */
-	if (!topdir || (punch_hole && (limit <= SHMEM_NR_DIRECT)))
+	if (!topdir || limit <= SHMEM_NR_DIRECT)
 		goto done2;
 
-	BUG_ON(limit <= SHMEM_NR_DIRECT);
+	/*
+	 * The truncation case has already dropped info->lock, and we're safe
+	 * because i_size and next_index have already been lowered, preventing
+	 * access beyond.  But in the punch_hole case, we still need to take
+	 * the lock when updating the swap directory, because there might be
+	 * racing accesses by shmem_getpage(SGP_CACHE), shmem_unuse_inode or
+	 * shmem_writepage.  However, whenever we find we can remove a whole
+	 * directory page (not at the misaligned start or end of the range),
+	 * we first NULLify its pointer in the level above, and then have no
+	 * need to take the lock when updating its contents: needs_lock and
+	 * punch_lock (either pointing to info->lock or NULL) manage this.
+	 */
+
+	upper_limit -= SHMEM_NR_DIRECT;
 	limit -= SHMEM_NR_DIRECT;
 	idx = (idx > SHMEM_NR_DIRECT)? (idx - SHMEM_NR_DIRECT): 0;
 	offset = idx % ENTRIES_PER_PAGE;
@@ -543,8 +581,14 @@
 		if (*dir) {
 			diroff = ((idx - ENTRIES_PER_PAGEPAGE/2) %
 				ENTRIES_PER_PAGEPAGE) / ENTRIES_PER_PAGE;
-			if (!diroff && !offset) {
-				*dir = NULL;
+			if (!diroff && !offset && upper_limit >= stage) {
+				if (needs_lock) {
+					spin_lock(needs_lock);
+					*dir = NULL;
+					spin_unlock(needs_lock);
+					needs_lock = NULL;
+				} else
+					*dir = NULL;
 				nr_pages_to_free++;
 				list_add(&middir->lru, &pages_to_free);
 			}
@@ -570,39 +614,55 @@
 			}
 			stage = idx + ENTRIES_PER_PAGEPAGE;
 			middir = *dir;
-			*dir = NULL;
-			nr_pages_to_free++;
-			list_add(&middir->lru, &pages_to_free);
+			if (punch_hole)
+				needs_lock = &info->lock;
+			if (upper_limit >= stage) {
+				if (needs_lock) {
+					spin_lock(needs_lock);
+					*dir = NULL;
+					spin_unlock(needs_lock);
+					needs_lock = NULL;
+				} else
+					*dir = NULL;
+				nr_pages_to_free++;
+				list_add(&middir->lru, &pages_to_free);
+			}
 			shmem_dir_unmap(dir);
 			cond_resched();
 			dir = shmem_dir_map(middir);
 			diroff = 0;
 		}
+		punch_lock = needs_lock;
 		subdir = dir[diroff];
-		if (subdir && page_private(subdir)) {
+		if (subdir && !offset && upper_limit-idx >= ENTRIES_PER_PAGE) {
+			if (needs_lock) {
+				spin_lock(needs_lock);
+				dir[diroff] = NULL;
+				spin_unlock(needs_lock);
+				punch_lock = NULL;
+			} else
+				dir[diroff] = NULL;
+			nr_pages_to_free++;
+			list_add(&subdir->lru, &pages_to_free);
+		}
+		if (subdir && page_private(subdir) /* has swap entries */) {
 			size = limit - idx;
 			if (size > ENTRIES_PER_PAGE)
 				size = ENTRIES_PER_PAGE;
 			freed = shmem_map_and_free_swp(subdir,
-						offset, size, &dir);
+					offset, size, &dir, punch_lock);
 			if (!dir)
 				dir = shmem_dir_map(middir);
 			nr_swaps_freed += freed;
-			if (offset)
+			if (offset || punch_lock) {
 				spin_lock(&info->lock);
-			set_page_private(subdir, page_private(subdir) - freed);
-			if (offset)
+				set_page_private(subdir,
+					page_private(subdir) - freed);
 				spin_unlock(&info->lock);
-			if (!punch_hole)
-				BUG_ON(page_private(subdir) > offset);
+			} else
+				BUG_ON(page_private(subdir) != freed);
 		}
-		if (offset)
-			offset = 0;
-		else if (subdir && !page_private(subdir)) {
-			dir[diroff] = NULL;
-			nr_pages_to_free++;
-			list_add(&subdir->lru, &pages_to_free);
-		}
+		offset = 0;
 	}
 done1:
 	shmem_dir_unmap(dir);
@@ -614,8 +674,16 @@
 		 * generic_delete_inode did it, before we lowered next_index.
 		 * Also, though shmem_getpage checks i_size before adding to
 		 * cache, no recheck after: so fix the narrow window there too.
+		 *
+		 * Recalling truncate_inode_pages_range and unmap_mapping_range
+		 * every time for punch_hole (which never got a chance to clear
+		 * SHMEM_PAGEIN at the start of vmtruncate_range) is expensive,
+		 * yet hardly ever necessary: try to optimize them out later.
 		 */
 		truncate_inode_pages_range(inode->i_mapping, start, end);
+		if (punch_hole)
+			unmap_mapping_range(inode->i_mapping, start,
+							end - start, 1);
 	}
 
 	spin_lock(&info->lock);
diff --git a/mm/slab.c b/mm/slab.c
index 57f7aa4..4cbac24 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1802,8 +1802,8 @@
 			/* Print header */
 			if (lines == 0) {
 				printk(KERN_ERR
-					"Slab corruption: start=%p, len=%d\n",
-					realobj, size);
+					"Slab corruption: %s start=%p, len=%d\n",
+					cachep->name, realobj, size);
 				print_objinfo(cachep, objp, 0);
 			}
 			/* Hexdump the affected line */
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 113c175..c8b7dc2 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1417,10 +1417,13 @@
 	/*
 	 * Size check to see if ddp->deh_len was crap
 	 * (Otherwise we'll detonate most spectacularly
-	 * in the middle of recvmsg()).
+	 * in the middle of atalk_checksum() or recvmsg()).
 	 */
-	if (skb->len < sizeof(*ddp))
+	if (skb->len < sizeof(*ddp) || skb->len < (len_hops & 1023)) {
+		pr_debug("AppleTalk: dropping corrupted frame (deh_len=%u, "
+			 "skb->len=%u)\n", len_hops & 1023, skb->len);
 		goto freeit;
+	}
 
 	/*
 	 * Any checksums. Note we don't do htons() on this == is assumed to be
diff --git a/net/atm/clip.c b/net/atm/clip.c
index ebb5d0c..8c38258 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -261,14 +261,6 @@
 	spin_unlock_irqrestore(&PRIV(dev)->xoff_lock, flags);
 }
 
-static void clip_neigh_destroy(struct neighbour *neigh)
-{
-	DPRINTK("clip_neigh_destroy (neigh %p)\n", neigh);
-	if (NEIGH2ENTRY(neigh)->vccs)
-		printk(KERN_CRIT "clip_neigh_destroy: vccs != NULL !!!\n");
-	NEIGH2ENTRY(neigh)->vccs = (void *) NEIGHBOR_DEAD;
-}
-
 static void clip_neigh_solicit(struct neighbour *neigh, struct sk_buff *skb)
 {
 	DPRINTK("clip_neigh_solicit (neigh %p, skb %p)\n", neigh, skb);
@@ -342,7 +334,6 @@
 	/* parameters are copied from ARP ... */
 	.parms = {
 		.tbl 			= &clip_tbl,
-		.neigh_destructor	= clip_neigh_destroy,
 		.base_reachable_time 	= 30 * HZ,
 		.retrans_time 		= 1 * HZ,
 		.gc_staletime 		= 60 * HZ,
diff --git a/net/ax25/Kconfig b/net/ax25/Kconfig
index a8993a0..43dd86f 100644
--- a/net/ax25/Kconfig
+++ b/net/ax25/Kconfig
@@ -1,30 +1,27 @@
 #
 # Amateur Radio protocols and AX.25 device configuration
 #
-# 19971130	Now in an own category to make correct compilation of the
-#		AX.25 stuff easier...
-#		Joerg Reuter DL1BKE <jreuter@yaina.de>
-# 19980129	Moved to net/ax25/Config.in, sourcing device drivers.
 
 menuconfig HAMRADIO
 	depends on NET
 	bool "Amateur Radio support"
 	help
 	  If you want to connect your Linux box to an amateur radio, answer Y
-	  here. You want to read <http://www.tapr.org/tapr/html/pkthome.html> and
-	  the AX25-HOWTO, available from <http://www.tldp.org/docs.html#howto>.
+	  here. You want to read <http://www.tapr.org/tapr/html/pkthome.html>
+	  and more specifically about AX.25 on Linux
+	  <http://www.linux-ax25.org/>.
 
 	  Note that the answer to this question won't directly affect the
 	  kernel: saying N will just cause the configurator to skip all
 	  the questions about amateur radio.
 
 comment "Packet Radio protocols"
-	depends on HAMRADIO && NET
+	depends on HAMRADIO
 
 config AX25
 	tristate "Amateur Radio AX.25 Level 2 protocol"
-	depends on HAMRADIO && NET
-	---help---
+	depends on HAMRADIO
+	help
 	  This is the protocol used for computer communication over amateur
 	  radio. It is either used by itself for point-to-point links, or to
 	  carry other protocols such as tcp/ip. To use it, you need a device
@@ -52,6 +49,7 @@
 
 config AX25_DAMA_SLAVE
 	bool "AX.25 DAMA Slave support"
+	default y
 	depends on AX25
 	help
 	  DAMA is a mechanism to prevent collisions when doing AX.25
@@ -59,23 +57,38 @@
 	  from clients (called "slaves") and redistributes it to other slaves.
 	  If you say Y here, your Linux box will act as a DAMA slave; this is
 	  transparent in that you don't have to do any special DAMA
-	  configuration. (Linux cannot yet act as a DAMA server.) If unsure,
-	  say N.
+	  configuration. Linux cannot yet act as a DAMA server.  This option
+	  only compiles DAMA slave support into the kernel.  It still needs to
+	  be enabled at runtime.  For more about DAMA see
+	  <http://www.linux-ax25.org>.  If unsure, say Y.
 
-#	 bool '    AX.25 DAMA Master support' CONFIG_AX25_DAMA_MASTER
+# placeholder until implemented
+config AX25_DAMA_MASTER
+	bool 'AX.25 DAMA Master support'
+	depends on AX25_DAMA_SLAVE && BROKEN
+	help
+	  DAMA is a mechanism to prevent collisions when doing AX.25
+	  networking. A DAMA server (called "master") accepts incoming traffic
+	  from clients (called "slaves") and redistributes it to other slaves.
+	  If you say Y here, your Linux box will act as a DAMA master; this is
+	  transparent in that you don't have to do any special DAMA
+	  configuration. Linux cannot yet act as a DAMA server.  This option
+	  only compiles DAMA slave support into the kernel.  It still needs to
+	  be explicitly enabled, so if unsure, say Y.
+
 config NETROM
 	tristate "Amateur Radio NET/ROM protocol"
 	depends on AX25
-	---help---
+	help
 	  NET/ROM is a network layer protocol on top of AX.25 useful for
 	  routing.
 
 	  A comprehensive listing of all the software for Linux amateur radio
 	  users as well as information about how to configure an AX.25 port is
-	  contained in the AX25-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>. You also might want to
-	  check out the file <file:Documentation/networking/ax25.txt>. More
-	  information about digital amateur radio in general is on the WWW at
+	  contained in the Linux Ham Wiki, available from
+	  <http://www.linux-ax25.org>. You also might want to check out the
+	  file <file:Documentation/networking/ax25.txt>. More information about
+	  digital amateur radio in general is on the WWW at
 	  <http://www.tapr.org/tapr/html/pkthome.html>.
 
 	  To compile this driver as a module, choose M here: the
@@ -84,27 +97,25 @@
 config ROSE
 	tristate "Amateur Radio X.25 PLP (Rose)"
 	depends on AX25
-	---help---
+	help
 	  The Packet Layer Protocol (PLP) is a way to route packets over X.25
 	  connections in general and amateur radio AX.25 connections in
 	  particular, essentially an alternative to NET/ROM.
 
 	  A comprehensive listing of all the software for Linux amateur radio
 	  users as well as information about how to configure an AX.25 port is
-	  contained in the AX25-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.  You also might want to
-	  check out the file <file:Documentation/networking/ax25.txt>. More
-	  information about digital amateur radio in general is on the WWW at
+	  contained in the Linux Ham Wiki, available from
+	  <http://www.linux-ax25.org>.  You also might want to check out the
+	  file <file:Documentation/networking/ax25.txt>. More information about
+	  digital amateur radio in general is on the WWW at
 	  <http://www.tapr.org/tapr/html/pkthome.html>.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called rose.
 
-
 menu "AX.25 network device drivers"
-	depends on HAMRADIO && NET && AX25!=n
+	depends on HAMRADIO && AX25
 
 source "drivers/net/hamradio/Kconfig"
 
 endmenu
-
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index f928d2b..71f5cfb 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -656,7 +656,7 @@
 		/* Detach sockets from device */
 		read_lock(&hci_sk_list.lock);
 		sk_for_each(sk, node, &hci_sk_list.head) {
-			bh_lock_sock(sk);
+			lock_sock(sk);
 			if (hci_pi(sk)->hdev == hdev) {
 				hci_pi(sk)->hdev = NULL;
 				sk->sk_err = EPIPE;
@@ -665,7 +665,7 @@
 
 				hci_dev_put(hdev);
 			}
-			bh_unlock_sock(sk);
+			release_sock(sk);
 		}
 		read_unlock(&hci_sk_list.lock);
 	}
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 4c914df..d342e89 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -319,7 +319,7 @@
 	return 0;
 }
 
-static int inline hidp_send_ctrl_message(struct hidp_session *session,
+static inline int hidp_send_ctrl_message(struct hidp_session *session,
 			unsigned char hdr, unsigned char *data, int size)
 {
 	int err;
@@ -679,6 +679,27 @@
 {
 }
 
+static const struct {
+	__u16 idVendor;
+	__u16 idProduct;
+	unsigned quirks;
+} hidp_blacklist[] = {
+	/* Apple wireless Mighty Mouse */
+	{ 0x05ac, 0x030c, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL },
+
+	{ }	/* Terminating entry */
+};
+
+static void hidp_setup_quirks(struct hid_device *hid)
+{
+	unsigned int n;
+
+	for (n = 0; hidp_blacklist[n].idVendor; n++)
+		if (hidp_blacklist[n].idVendor == le16_to_cpu(hid->vendor) &&
+				hidp_blacklist[n].idProduct == le16_to_cpu(hid->product))
+			hid->quirks = hidp_blacklist[n].quirks;
+}
+
 static inline void hidp_setup_hid(struct hidp_session *session, struct hidp_connadd_req *req)
 {
 	struct hid_device *hid = session->hid;
@@ -708,6 +729,8 @@
 
 	hid->hidinput_input_event = hidp_hidinput_event;
 
+	hidp_setup_quirks(hid);
+
 	list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list)
 		hidp_send_report(session, report);
 
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index def2e40..8d566c1 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -197,8 +197,8 @@
 
 	rcu_read_lock();
 	fdb = __br_fdb_get(br, addr);
-	if (fdb)
-		atomic_inc(&fdb->use_count);
+	if (fdb && !atomic_inc_not_zero(&fdb->use_count))
+		fdb = NULL;
 	rcu_read_unlock();
 	return fdb;
 }
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 6845a25..f3a2e29 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -428,6 +428,10 @@
 	spin_lock_bh(&br->lock);
 	br_stp_recalculate_bridge_id(br);
 	br_features_recompute(br);
+
+	if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) &&
+	    (br->dev->flags & IFF_UP))
+		br_stp_enable_port(p);
 	spin_unlock_bh(&br->lock);
 
 	dev_set_mtu(br->dev, br_min_mtu(br));
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 7712d76..5439a3c 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -61,7 +61,7 @@
 #define brnf_filter_vlan_tagged 1
 #endif
 
-static __be16 inline vlan_proto(const struct sk_buff *skb)
+static inline __be16 vlan_proto(const struct sk_buff *skb)
 {
 	return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
 }
diff --git a/net/core/dev.c b/net/core/dev.c
index cf71614..4dc93cc 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -751,13 +751,10 @@
 	else
 		strlcpy(dev->name, newname, IFNAMSIZ);
 
-	err = device_rename(&dev->dev, dev->name);
-	if (!err) {
-		hlist_del(&dev->name_hlist);
-		hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name));
-		raw_notifier_call_chain(&netdev_chain,
-				NETDEV_CHANGENAME, dev);
-	}
+	device_rename(&dev->dev, dev->name);
+	hlist_del(&dev->name_hlist);
+	hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name));
+	raw_notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev);
 
 	return err;
 }
@@ -1741,8 +1738,8 @@
 	if (dev->qdisc_ingress) {
 		__u32 ttl = (__u32) G_TC_RTTL(skb->tc_verd);
 		if (MAX_RED_LOOP < ttl++) {
-			printk(KERN_WARNING "Redir loop detected Dropping packet (%s->%s)\n",
-				skb->input_dev->name, skb->dev->name);
+			printk(KERN_WARNING "Redir loop detected Dropping packet (%d->%d)\n",
+				skb->iif, skb->dev->ifindex);
 			return TC_ACT_SHOT;
 		}
 
@@ -1750,10 +1747,10 @@
 
 		skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_INGRESS);
 
-		spin_lock(&dev->ingress_lock);
+		spin_lock(&dev->queue_lock);
 		if ((q = dev->qdisc_ingress) != NULL)
 			result = q->enqueue(skb, q);
-		spin_unlock(&dev->ingress_lock);
+		spin_unlock(&dev->queue_lock);
 
 	}
 
@@ -1775,8 +1772,8 @@
 	if (!skb->tstamp.off_sec)
 		net_timestamp(skb);
 
-	if (!skb->input_dev)
-		skb->input_dev = skb->dev;
+	if (!skb->iif)
+		skb->iif = skb->dev->ifindex;
 
 	orig_dev = skb_bond(skb);
 
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 215f1bff..7174ced 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -143,7 +143,7 @@
 		}
 	}
 
-	err = -ENETUNREACH;
+	err = -ESRCH;
 out:
 	rcu_read_unlock();
 
@@ -152,6 +152,28 @@
 
 EXPORT_SYMBOL_GPL(fib_rules_lookup);
 
+static int validate_rulemsg(struct fib_rule_hdr *frh, struct nlattr **tb,
+			    struct fib_rules_ops *ops)
+{
+	int err = -EINVAL;
+
+	if (frh->src_len)
+		if (tb[FRA_SRC] == NULL ||
+		    frh->src_len > (ops->addr_size * 8) ||
+		    nla_len(tb[FRA_SRC]) != ops->addr_size)
+			goto errout;
+
+	if (frh->dst_len)
+		if (tb[FRA_DST] == NULL ||
+		    frh->dst_len > (ops->addr_size * 8) ||
+		    nla_len(tb[FRA_DST]) != ops->addr_size)
+			goto errout;
+
+	err = 0;
+errout:
+	return err;
+}
+
 int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
 {
 	struct fib_rule_hdr *frh = nlmsg_data(nlh);
@@ -173,6 +195,10 @@
 	if (err < 0)
 		goto errout;
 
+	err = validate_rulemsg(frh, tb, ops);
+	if (err < 0)
+		goto errout;
+
 	rule = kzalloc(ops->rule_size, GFP_KERNEL);
 	if (rule == NULL) {
 		err = -ENOMEM;
@@ -260,6 +286,10 @@
 	if (err < 0)
 		goto errout;
 
+	err = validate_rulemsg(frh, tb, ops);
+	if (err < 0)
+		goto errout;
+
 	list_for_each_entry(rule, ops->rules_list, list) {
 		if (frh->action && (frh->action != rule->action))
 			continue;
@@ -374,7 +404,7 @@
 		return -EAFNOSUPPORT;
 
 	rcu_read_lock();
-	list_for_each_entry(rule, ops->rules_list, list) {
+	list_for_each_entry_rcu(rule, ops->rules_list, list) {
 		if (idx < cb->args[0])
 			goto skip;
 
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 3183142..cfc6001 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -140,6 +140,8 @@
 				n->dead = 1;
 				shrunk	= 1;
 				write_unlock(&n->lock);
+				if (n->parms->neigh_cleanup)
+					n->parms->neigh_cleanup(n);
 				neigh_release(n);
 				continue;
 			}
@@ -211,6 +213,8 @@
 				NEIGH_PRINTK2("neigh %p is stray.\n", n);
 			}
 			write_unlock(&n->lock);
+			if (n->parms->neigh_cleanup)
+				n->parms->neigh_cleanup(n);
 			neigh_release(n);
 		}
 	}
@@ -582,9 +586,6 @@
 			kfree(hh);
 	}
 
-	if (neigh->parms->neigh_destructor)
-		(neigh->parms->neigh_destructor)(neigh);
-
 	skb_queue_purge(&neigh->arp_queue);
 
 	dev_put(neigh->dev);
@@ -675,6 +676,8 @@
 			*np = n->next;
 			n->dead = 1;
 			write_unlock(&n->lock);
+			if (n->parms->neigh_cleanup)
+				n->parms->neigh_cleanup(n);
 			neigh_release(n);
 			continue;
 		}
@@ -2088,8 +2091,11 @@
 			} else
 				np = &n->next;
 			write_unlock(&n->lock);
-			if (release)
+			if (release) {
+				if (n->parms->neigh_cleanup)
+					n->parms->neigh_cleanup(n);
 				neigh_release(n);
+			}
 		}
 	}
 }
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 6055074..33ea8ea 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -621,7 +621,8 @@
 		if (err < 0)
 			goto errout;
 
-		iw += IW_EV_POINT_OFF;
+		/* Payload is at an offset in buffer */
+		iw = iw_buf + IW_EV_POINT_OFF;
 	}
 #endif	/* CONFIG_NET_WIRELESS_RTNETLINK */
 
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 820761f..87573ae 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -463,6 +463,7 @@
 	memcpy(n->cb, skb->cb, sizeof(skb->cb));
 	C(len);
 	C(data_len);
+	C(mac_len);
 	C(csum);
 	C(local_df);
 	n->cloned = 1;
@@ -495,7 +496,7 @@
 	n->tc_verd = SET_TC_VERD(skb->tc_verd,0);
 	n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd);
 	n->tc_verd = CLR_TC_MUNGED(n->tc_verd);
-	C(input_dev);
+	C(iif);
 #endif
 	skb_copy_secmark(n, skb);
 #endif
diff --git a/net/core/sock.c b/net/core/sock.c
index 8d65d64..27c4f62 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -808,7 +808,7 @@
  *
  * (We also register the sk_lock with the lock validator.)
  */
-static void inline sock_lock_init(struct sock *sk)
+static inline void sock_lock_init(struct sock *sk)
 {
 	sock_lock_init_class_and_name(sk,
 			af_family_slock_key_strings[sk->sk_family],
diff --git a/net/core/wireless.c b/net/core/wireless.c
index 9936ab1..b07fe27 100644
--- a/net/core/wireless.c
+++ b/net/core/wireless.c
@@ -2,7 +2,7 @@
  * This file implement the Wireless Extensions APIs.
  *
  * Authors :	Jean Tourrilhes - HPL - <jt@hpl.hp.com>
- * Copyright (c) 1997-2006 Jean Tourrilhes, All Rights Reserved.
+ * Copyright (c) 1997-2007 Jean Tourrilhes, All Rights Reserved.
  *
  * (As all part of the Linux kernel, this file is GPL)
  */
@@ -76,6 +76,9 @@
  *	o Change length in ESSID and NICK to strlen() instead of strlen()+1
  *	o Make standard_ioctl_num and standard_event_num unsigned
  *	o Remove (struct net_device *)->get_wireless_stats()
+ *
+ * v10 - 16.3.07 - Jean II
+ *	o Prevent leaking of kernel space in stream on 64 bits.
  */
 
 /***************************** INCLUDES *****************************/
@@ -427,6 +430,21 @@
 	IW_EV_QUAL_LEN,			/* IW_HEADER_TYPE_QUAL */
 };
 
+/* Size (in bytes) of various events, as packed */
+static const int event_type_pk_size[] = {
+	IW_EV_LCP_PK_LEN,		/* IW_HEADER_TYPE_NULL */
+	0,
+	IW_EV_CHAR_PK_LEN,		/* IW_HEADER_TYPE_CHAR */
+	0,
+	IW_EV_UINT_PK_LEN,		/* IW_HEADER_TYPE_UINT */
+	IW_EV_FREQ_PK_LEN,		/* IW_HEADER_TYPE_FREQ */
+	IW_EV_ADDR_PK_LEN,		/* IW_HEADER_TYPE_ADDR */
+	0,
+	IW_EV_POINT_PK_LEN,		/* Without variable payload */
+	IW_EV_PARAM_PK_LEN,		/* IW_HEADER_TYPE_PARAM */
+	IW_EV_QUAL_PK_LEN,		/* IW_HEADER_TYPE_QUAL */
+};
+
 /************************ COMMON SUBROUTINES ************************/
 /*
  * Stuff that may be used in various place or doesn't fit in one
@@ -1217,7 +1235,7 @@
 		memcpy(buffer + IW_EV_POINT_OFF, request, request_len);
 		/* Use our own copy of wrqu */
 		wrqu = (union iwreq_data *) (buffer + IW_EV_POINT_OFF
-					     + IW_EV_LCP_LEN);
+					     + IW_EV_LCP_PK_LEN);
 
 		/* No extra arguments. Trivial to handle */
 		ret = handler(dev, &info, wrqu, NULL);
@@ -1229,8 +1247,8 @@
 
 		/* Get a temp copy of wrqu (skip pointer) */
 		memcpy(((char *) &wrqu_point) + IW_EV_POINT_OFF,
-		       ((char *) request) + IW_EV_LCP_LEN,
-		       IW_EV_POINT_LEN - IW_EV_LCP_LEN);
+		       ((char *) request) + IW_EV_LCP_PK_LEN,
+		       IW_EV_POINT_LEN - IW_EV_LCP_PK_LEN);
 
 		/* Calculate space needed by arguments. Always allocate
 		 * for max space. Easier, and won't last long... */
@@ -1240,7 +1258,7 @@
 		   (wrqu_point.data.length > descr->max_tokens))
 			extra_size = (wrqu_point.data.length
 				      * descr->token_size);
-		buffer_size = extra_size + IW_EV_POINT_LEN + IW_EV_POINT_OFF;
+		buffer_size = extra_size + IW_EV_POINT_PK_LEN + IW_EV_POINT_OFF;
 #ifdef WE_RTNETLINK_DEBUG
 		printk(KERN_DEBUG "%s (WE.r) : Malloc %d bytes (%d bytes)\n",
 		       dev->name, extra_size, buffer_size);
@@ -1254,15 +1272,15 @@
 
 		/* Put wrqu in the right place (just before extra).
 		 * Leave space for IWE header and dummy pointer...
-		 * Note that IW_EV_LCP_LEN==4 bytes, so it's still aligned...
+		 * Note that IW_EV_LCP_PK_LEN==4 bytes, so it's still aligned.
 		 */
-		memcpy(buffer + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
+		memcpy(buffer + IW_EV_LCP_PK_LEN + IW_EV_POINT_OFF,
 		       ((char *) &wrqu_point) + IW_EV_POINT_OFF,
-		       IW_EV_POINT_LEN - IW_EV_LCP_LEN);
-		wrqu = (union iwreq_data *) (buffer + IW_EV_LCP_LEN);
+		       IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
+		wrqu = (union iwreq_data *) (buffer + IW_EV_LCP_PK_LEN);
 
 		/* Extra comes logically after that. Offset +12 bytes. */
-		extra = buffer + IW_EV_POINT_OFF + IW_EV_POINT_LEN;
+		extra = buffer + IW_EV_POINT_OFF + IW_EV_POINT_PK_LEN;
 
 		/* Call the handler */
 		ret = handler(dev, &info, wrqu, extra);
@@ -1270,11 +1288,11 @@
 		/* Calculate real returned length */
 		extra_size = (wrqu->data.length * descr->token_size);
 		/* Re-adjust reply size */
-		request->len = extra_size + IW_EV_POINT_LEN;
+		request->len = extra_size + IW_EV_POINT_PK_LEN;
 
 		/* Put the iwe header where it should, i.e. scrap the
 		 * dummy pointer. */
-		memcpy(buffer + IW_EV_POINT_OFF, request, IW_EV_LCP_LEN);
+		memcpy(buffer + IW_EV_POINT_OFF, request, IW_EV_LCP_PK_LEN);
 
 #ifdef WE_RTNETLINK_DEBUG
 		printk(KERN_DEBUG "%s (WE.r) : Reply 0x%04X, hdr_len %d, tokens %d, extra_size %d, buffer_size %d\n", dev->name, cmd, hdr_len, wrqu->data.length, extra_size, buffer_size);
@@ -1331,10 +1349,10 @@
 #endif	/* WE_RTNETLINK_DEBUG */
 
 	/* Extract fixed header from request. This is properly aligned. */
-	wrqu = &request->u;
+	wrqu = (union iwreq_data *) (((char *) request) + IW_EV_LCP_PK_LEN);
 
 	/* Check if wrqu is complete */
-	hdr_len = event_type_size[descr->header_type];
+	hdr_len = event_type_pk_size[descr->header_type];
 	if(request_len < hdr_len) {
 #ifdef WE_RTNETLINK_DEBUG
 		printk(KERN_DEBUG
@@ -1359,7 +1377,7 @@
 
 		/* Put wrqu in the right place (skip pointer) */
 		memcpy(((char *) &wrqu_point) + IW_EV_POINT_OFF,
-		       wrqu, IW_EV_POINT_LEN - IW_EV_LCP_LEN);
+		       wrqu, IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
 		/* Don't forget about the event code... */
 		wrqu = &wrqu_point;
 
@@ -1483,7 +1501,7 @@
 		hdr_len = extra_size;
 		extra_size = 0;
 	} else {
-		hdr_len = IW_EV_POINT_LEN;
+		hdr_len = IW_EV_POINT_PK_LEN;
 	}
 
 	/* Check if wrqu is complete */
@@ -1514,7 +1532,7 @@
 		memcpy(buffer + IW_EV_POINT_OFF, request, request_len);
 		/* Use our own copy of wrqu */
 		wrqu = (union iwreq_data *) (buffer + IW_EV_POINT_OFF
-					     + IW_EV_LCP_LEN);
+					     + IW_EV_LCP_PK_LEN);
 
 		/* No extra arguments. Trivial to handle */
 		ret = handler(dev, &info, wrqu, (char *) wrqu);
@@ -1523,7 +1541,7 @@
 		char *	extra;
 
 		/* Buffer for full reply */
-		buffer_size = extra_size + IW_EV_POINT_LEN + IW_EV_POINT_OFF;
+		buffer_size = extra_size + IW_EV_POINT_PK_LEN + IW_EV_POINT_OFF;
 
 #ifdef WE_RTNETLINK_DEBUG
 		printk(KERN_DEBUG "%s (WE.r) : Malloc %d bytes (%d bytes)\n",
@@ -1538,15 +1556,15 @@
 
 		/* Put wrqu in the right place (just before extra).
 		 * Leave space for IWE header and dummy pointer...
-		 * Note that IW_EV_LCP_LEN==4 bytes, so it's still aligned...
+		 * Note that IW_EV_LCP_PK_LEN==4 bytes, so it's still aligned.
 		 */
-		memcpy(buffer + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
-		       ((char *) request) + IW_EV_LCP_LEN,
-		       IW_EV_POINT_LEN - IW_EV_LCP_LEN);
-		wrqu = (union iwreq_data *) (buffer + IW_EV_LCP_LEN);
+		memcpy(buffer + IW_EV_LCP_PK_LEN + IW_EV_POINT_OFF,
+		       ((char *) request) + IW_EV_LCP_PK_LEN,
+		       IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
+		wrqu = (union iwreq_data *) (buffer + IW_EV_LCP_PK_LEN);
 
 		/* Extra comes logically after that. Offset +12 bytes. */
-		extra = buffer + IW_EV_POINT_OFF + IW_EV_POINT_LEN;
+		extra = buffer + IW_EV_POINT_OFF + IW_EV_POINT_PK_LEN;
 
 		/* Call the handler */
 		ret = handler(dev, &info, wrqu, extra);
@@ -1556,11 +1574,11 @@
 		if (!(descr->get_args & IW_PRIV_SIZE_FIXED))
 			extra_size = adjust_priv_size(descr->get_args, wrqu);
 		/* Re-adjust reply size */
-		request->len = extra_size + IW_EV_POINT_LEN;
+		request->len = extra_size + IW_EV_POINT_PK_LEN;
 
 		/* Put the iwe header where it should, i.e. scrap the
 		 * dummy pointer. */
-		memcpy(buffer + IW_EV_POINT_OFF, request, IW_EV_LCP_LEN);
+		memcpy(buffer + IW_EV_POINT_OFF, request, IW_EV_LCP_PK_LEN);
 
 #ifdef WE_RTNETLINK_DEBUG
 		printk(KERN_DEBUG "%s (WE.r) : Reply 0x%04X, hdr_len %d, tokens %d, extra_size %d, buffer_size %d\n", dev->name, cmd, hdr_len, wrqu->data.length, extra_size, buffer_size);
@@ -1641,14 +1659,14 @@
 	/* Does it fits in wrqu ? */
 	if((descr->set_args & IW_PRIV_SIZE_FIXED) &&
 	   (extra_size <= IFNAMSIZ)) {
-		hdr_len = IW_EV_LCP_LEN + extra_size;
+		hdr_len = IW_EV_LCP_PK_LEN + extra_size;
 		extra_size = 0;
 	} else {
-		hdr_len = IW_EV_POINT_LEN;
+		hdr_len = IW_EV_POINT_PK_LEN;
 	}
 
 	/* Extract fixed header from request. This is properly aligned. */
-	wrqu = &request->u;
+	wrqu = (union iwreq_data *) (((char *) request) + IW_EV_LCP_PK_LEN);
 
 	/* Check if wrqu is complete */
 	if(request_len < hdr_len) {
@@ -1675,7 +1693,7 @@
 
 		/* Put wrqu in the right place (skip pointer) */
 		memcpy(((char *) &wrqu_point) + IW_EV_POINT_OFF,
-		       wrqu, IW_EV_POINT_LEN - IW_EV_LCP_LEN);
+		       wrqu, IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
 
 		/* Does it fits within bounds ? */
 		if(wrqu_point.data.length > (descr->set_args &
@@ -1738,7 +1756,7 @@
 	iw_handler		handler;
 
 	/* Check length */
-	if(len < IW_EV_LCP_LEN) {
+	if(len < IW_EV_LCP_PK_LEN) {
 		printk(KERN_DEBUG "%s (WE.r) : RtNetlink request too short (%d)\n",
 		       dev->name, len);
 		return -EINVAL;
@@ -1822,7 +1840,7 @@
 	iw_handler		handler;
 
 	/* Check length */
-	if(len < IW_EV_LCP_LEN) {
+	if(len < IW_EV_LCP_PK_LEN) {
 		printk(KERN_DEBUG "%s (WE.r) : RtNetlink request too short (%d)\n",
 		       dev->name, len);
 		return -EINVAL;
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 5361a4d..746f79d 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -545,12 +545,7 @@
 		/* set idle flag */
 		hctx->ccid3hctx_idle = 1;
 		break;
-	case TFRC_SSTATE_NO_SENT:
-		/*
-		 * XXX when implementing bidirectional rx/tx check this again
-		 */
-		DCCP_WARN("Illegal ACK received - no packet sent\n");
-		/* fall through */
+	case TFRC_SSTATE_NO_SENT:	/* fall through */
 	case TFRC_SSTATE_TERM:		/* ignore feedback when closing */
 		break;
 	}
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 287099f..78b043c 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -248,18 +248,8 @@
 			    DCCP_ACKVEC_STATE_RECEIVED))
 		goto discard;
 
-	/*
-	 * Deliver to the CCID module in charge.
-	 * FIXME: Currently DCCP operates one-directional only, i.e. a listening
-	 *        server is not at the same time a connecting client. There is
-	 *        not much sense in delivering to both rx/tx sides at the moment
-	 *        (only one is active at a time); when moving to bidirectional
-	 *        service, this needs to be revised.
-	 */
-	if (dccp_sk(sk)->dccps_role == DCCP_ROLE_CLIENT)
-		ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
-	else	/* listening or connected server */
-		ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
+	ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
+	ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
 
 	return __dccp_rcv_established(sk, skb, dh, len);
 discard:
@@ -494,11 +484,8 @@
 				    DCCP_ACKVEC_STATE_RECEIVED))
 			goto discard;
 
-		/* XXX see the comments in dccp_rcv_established about this */
-		if (dccp_sk(sk)->dccps_role == DCCP_ROLE_CLIENT)
-			ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
-		else
-			ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
+		ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
+		ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
 	}
 
 	/*
diff --git a/net/dccp/output.c b/net/dccp/output.c
index 3282f2f..aa21cc4 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -213,19 +213,6 @@
 	goto out;
 }
 
-static void dccp_write_xmit_timer(unsigned long data) {
-	struct sock *sk = (struct sock *)data;
-	struct dccp_sock *dp = dccp_sk(sk);
-
-	bh_lock_sock(sk);
-	if (sock_owned_by_user(sk))
-		sk_reset_timer(sk, &dp->dccps_xmit_timer, jiffies+1);
-	else
-		dccp_write_xmit(sk, 0);
-	bh_unlock_sock(sk);
-	sock_put(sk);
-}
-
 void dccp_write_xmit(struct sock *sk, int block)
 {
 	struct dccp_sock *dp = dccp_sk(sk);
@@ -434,9 +421,6 @@
 	dp->dccps_gar = dp->dccps_iss;
 
 	icsk->icsk_retransmits = 0;
-	init_timer(&dp->dccps_xmit_timer);
-	dp->dccps_xmit_timer.data = (unsigned long)sk;
-	dp->dccps_xmit_timer.function = dccp_write_xmit_timer;
 }
 
 int dccp_connect(struct sock *sk)
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index cf28c53..6607b7b 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -575,7 +575,7 @@
 	if (get_user(len, optlen))
 		return -EFAULT;
 
-	if (len < sizeof(int))
+	if (len < (int)sizeof(int))
 		return -EINVAL;
 
 	dp = dccp_sk(sk);
@@ -589,9 +589,11 @@
 					       (__be32 __user *)optval, optlen);
 	case DCCP_SOCKOPT_SEND_CSCOV:
 		val = dp->dccps_pcslen;
+		len = sizeof(val);
 		break;
 	case DCCP_SOCKOPT_RECV_CSCOV:
 		val = dp->dccps_pcrlen;
+		len = sizeof(val);
 		break;
 	case 128 ... 191:
 		return ccid_hc_rx_getsockopt(dp->dccps_hc_rx_ccid, sk, optname,
diff --git a/net/dccp/timer.c b/net/dccp/timer.c
index 41ea0f6..0197a41 100644
--- a/net/dccp/timer.c
+++ b/net/dccp/timer.c
@@ -261,8 +261,33 @@
 	sock_put(sk);
 }
 
+/* Transmit-delay timer: used by the CCIDs to delay actual send time */
+static void dccp_write_xmit_timer(unsigned long data)
+{
+	struct sock *sk = (struct sock *)data;
+	struct dccp_sock *dp = dccp_sk(sk);
+
+	bh_lock_sock(sk);
+	if (sock_owned_by_user(sk))
+		sk_reset_timer(sk, &dp->dccps_xmit_timer, jiffies+1);
+	else
+		dccp_write_xmit(sk, 0);
+	bh_unlock_sock(sk);
+	sock_put(sk);
+}
+
+static void dccp_init_write_xmit_timer(struct sock *sk)
+{
+	struct dccp_sock *dp = dccp_sk(sk);
+
+	init_timer(&dp->dccps_xmit_timer);
+	dp->dccps_xmit_timer.data = (unsigned long)sk;
+	dp->dccps_xmit_timer.function = dccp_write_xmit_timer;
+}
+
 void dccp_init_xmit_timers(struct sock *sk)
 {
+	dccp_init_write_xmit_timer(sk);
 	inet_csk_init_xmit_timers(sk, &dccp_write_timer, &dccp_delack_timer,
 				  &dccp_keepalive_timer);
 }
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c
index 3cbfddc..82d58a9 100644
--- a/net/decnet/dn_fib.c
+++ b/net/decnet/dn_fib.c
@@ -63,7 +63,7 @@
 {
 	int error;
 	u8 scope;
-} dn_fib_props[RTA_MAX+1] = {
+} dn_fib_props[RTN_MAX+1] = {
 	[RTN_UNSPEC] =      { .error = 0,       .scope = RT_SCOPE_NOWHERE },
 	[RTN_UNICAST] =     { .error = 0,       .scope = RT_SCOPE_UNIVERSE },
 	[RTN_LOCAL] =       { .error = 0,       .scope = RT_SCOPE_HOST },
@@ -276,6 +276,9 @@
 	struct dn_fib_info *ofi;
 	int nhs = 1;
 
+	if (r->rtm_type > RTN_MAX)
+		goto err_inval;
+
 	if (dn_fib_props[r->rtm_type].scope > r->rtm_scope)
 		goto err_inval;
 
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index b6c98ac..5e86dd5 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -109,8 +109,6 @@
 
 static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = {
 	FRA_GENERIC_POLICY,
-	[FRA_SRC]	= { .type = NLA_U16 },
-	[FRA_DST]	= { .type = NLA_U16 },
 };
 
 static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
@@ -133,7 +131,7 @@
 	int err = -EINVAL;
 	struct dn_fib_rule *r = (struct dn_fib_rule *)rule;
 
-	if (frh->src_len > 16 || frh->dst_len > 16 || frh->tos)
+	if (frh->tos)
 		goto  errout;
 
 	if (rule->table == RT_TABLE_UNSPEC) {
@@ -150,10 +148,10 @@
 		}
 	}
 
-	if (tb[FRA_SRC])
+	if (frh->src_len)
 		r->src = nla_get_le16(tb[FRA_SRC]);
 
-	if (tb[FRA_DST])
+	if (frh->dst_len)
 		r->dst = nla_get_le16(tb[FRA_DST]);
 
 	r->src_len = frh->src_len;
@@ -176,10 +174,10 @@
 	if (frh->dst_len && (r->dst_len != frh->dst_len))
 		return 0;
 
-	if (tb[FRA_SRC] && (r->src != nla_get_le16(tb[FRA_SRC])))
+	if (frh->src_len && (r->src != nla_get_le16(tb[FRA_SRC])))
 		return 0;
 
-	if (tb[FRA_DST] && (r->dst != nla_get_le16(tb[FRA_DST])))
+	if (frh->dst_len && (r->dst != nla_get_le16(tb[FRA_DST])))
 		return 0;
 
 	return 1;
@@ -249,6 +247,7 @@
 static struct fib_rules_ops dn_fib_rules_ops = {
 	.family		= AF_DECnet,
 	.rule_size	= sizeof(struct dn_fib_rule),
+	.addr_size	= sizeof(u16),
 	.action		= dn_fib_rule_action,
 	.match		= dn_fib_rule_match,
 	.configure	= dn_fib_rule_configure,
diff --git a/net/ieee80211/Kconfig b/net/ieee80211/Kconfig
index a64be6c..6ef766e 100644
--- a/net/ieee80211/Kconfig
+++ b/net/ieee80211/Kconfig
@@ -38,7 +38,7 @@
 	Include software based cipher suites in support of IEEE
 	802.11's WEP.  This is needed for WEP as well as 802.1x.
 
-	This can be compiled as a modules and it will be called
+	This can be compiled as a module and it will be called
 	"ieee80211_crypt_wep".
 
 config IEEE80211_CRYPT_CCMP
@@ -51,7 +51,7 @@
 	(aka TGi, WPA, WPA2, WPA-PSK, etc.) for use with CCMP enabled
 	networks.
 
-	This can be compiled as a modules and it will be called
+	This can be compiled as a module and it will be called
 	"ieee80211_crypt_ccmp".
 
 config IEEE80211_CRYPT_TKIP
@@ -66,7 +66,7 @@
 	(aka TGi, WPA, WPA2, WPA-PSK, etc.) for use with TKIP enabled
 	networks.
 
-	This can be compiled as a modules and it will be called
+	This can be compiled as a module and it will be called
 	"ieee80211_crypt_tkip".
 
 source "net/ieee80211/softmac/Kconfig"
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index c976dd7..2ce5b69 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -1933,6 +1933,11 @@
 						 &cipso_ptr[6],
 						 secattr);
 		break;
+	case CIPSO_V4_TAG_RANGE:
+		ret_val = cipso_v4_parsetag_rng(doi_def,
+						&cipso_ptr[6],
+						secattr);
+		break;
 	}
 
 skbuff_getattr_return:
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index e10794d..98a00d0 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -502,8 +502,10 @@
 		goto errout;
 
 	ifm = nlmsg_data(nlh);
-	if (ifm->ifa_prefixlen > 32 || tb[IFA_LOCAL] == NULL)
+	if (ifm->ifa_prefixlen > 32 || tb[IFA_LOCAL] == NULL) {
+		err = -EINVAL;
 		goto errout;
+	}
 
 	dev = __dev_get_by_index(ifm->ifa_index);
 	if (dev == NULL) {
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 1fba643..fc920f6 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -493,6 +493,11 @@
 	cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
 	cfg->fc_nlinfo.nlh = nlh;
 
+	if (cfg->fc_type > RTN_MAX) {
+		err = -EINVAL;
+		goto errout;
+	}
+
 	nlmsg_for_each_attr(attr, nlh, sizeof(struct rtmsg), remaining) {
 		switch (attr->nla_type) {
 		case RTA_DST:
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index b837c33..c660c07 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -171,8 +171,6 @@
 
 static struct nla_policy fib4_rule_policy[FRA_MAX+1] __read_mostly = {
 	FRA_GENERIC_POLICY,
-	[FRA_SRC]	= { .type = NLA_U32 },
-	[FRA_DST]	= { .type = NLA_U32 },
 	[FRA_FLOW]	= { .type = NLA_U32 },
 };
 
@@ -183,8 +181,7 @@
 	int err = -EINVAL;
 	struct fib4_rule *rule4 = (struct fib4_rule *) rule;
 
-	if (frh->src_len > 32 || frh->dst_len > 32 ||
-	    (frh->tos & ~IPTOS_TOS_MASK))
+	if (frh->tos & ~IPTOS_TOS_MASK)
 		goto errout;
 
 	if (rule->table == RT_TABLE_UNSPEC) {
@@ -201,10 +198,10 @@
 		}
 	}
 
-	if (tb[FRA_SRC])
+	if (frh->src_len)
 		rule4->src = nla_get_be32(tb[FRA_SRC]);
 
-	if (tb[FRA_DST])
+	if (frh->dst_len)
 		rule4->dst = nla_get_be32(tb[FRA_DST]);
 
 #ifdef CONFIG_NET_CLS_ROUTE
@@ -242,10 +239,10 @@
 		return 0;
 #endif
 
-	if (tb[FRA_SRC] && (rule4->src != nla_get_be32(tb[FRA_SRC])))
+	if (frh->src_len && (rule4->src != nla_get_be32(tb[FRA_SRC])))
 		return 0;
 
-	if (tb[FRA_DST] && (rule4->dst != nla_get_be32(tb[FRA_DST])))
+	if (frh->dst_len && (rule4->dst != nla_get_be32(tb[FRA_DST])))
 		return 0;
 
 	return 1;
@@ -309,6 +306,7 @@
 static struct fib_rules_ops fib4_rules_ops = {
 	.family		= AF_INET,
 	.rule_size	= sizeof(struct fib4_rule),
+	.addr_size	= sizeof(u32),
 	.action		= fib4_rule_action,
 	.match		= fib4_rule_match,
 	.configure	= fib4_rule_configure,
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 2f1fdae..3dad12e 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -89,7 +89,7 @@
 {
 	int	error;
 	u8	scope;
-} fib_props[RTA_MAX + 1] = {
+} fib_props[RTN_MAX + 1] = {
 	{
 		.error	= 0,
 		.scope	= RT_SCOPE_NOWHERE,
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 72b3036..214c347 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1123,6 +1123,9 @@
 	return fa_head;
 }
 
+/*
+ * Caller must hold RTNL.
+ */
 static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
 {
 	struct trie *t = (struct trie *) tb->tb_data;
@@ -1527,7 +1530,6 @@
 	t->revision++;
 	t->size--;
 
-	preempt_disable();
 	tp = NODE_PARENT(n);
 	tnode_free((struct tnode *) n);
 
@@ -1537,11 +1539,13 @@
 		rcu_assign_pointer(t->trie, trie_rebalance(t, tp));
 	} else
 		rcu_assign_pointer(t->trie, NULL);
-	preempt_enable();
 
 	return 1;
 }
 
+/*
+ * Caller must hold RTNL.
+ */
 static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg)
 {
 	struct trie *t = (struct trie *) tb->tb_data;
@@ -1720,6 +1724,9 @@
 	return NULL; /* Ready. Root of trie */
 }
 
+/*
+ * Caller must hold RTNL.
+ */
 static int fn_trie_flush(struct fib_table *tb)
 {
 	struct trie *t = (struct trie *) tb->tb_data;
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 1c6a084..8cedb2a 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1255,9 +1255,9 @@
  */
 void ip_mc_rejoin_group(struct ip_mc_list *im)
 {
+#ifdef CONFIG_IP_MULTICAST
 	struct in_device *in_dev = im->interface;
 
-#ifdef CONFIG_IP_MULTICAST
 	if (im->multiaddr == IGMP_ALL_HOSTS)
 		return;
 
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index adf25f9..6bcfdf6 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -253,14 +253,17 @@
 		enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 
 		if (ct->tuplehash[dir].tuple.dst.ip !=
-		    ct->tuplehash[!dir].tuple.src.ip
-#ifdef CONFIG_XFRM
-		    || ct->tuplehash[dir].tuple.dst.u.all !=
-		       ct->tuplehash[!dir].tuple.src.u.all
-#endif
-		    )
+		    ct->tuplehash[!dir].tuple.src.ip) {
 			if (ip_route_me_harder(pskb, RTN_UNSPEC))
 				ret = NF_DROP;
+		}
+#ifdef CONFIG_XFRM
+		else if (ct->tuplehash[dir].tuple.dst.u.all !=
+			 ct->tuplehash[!dir].tuple.src.u.all)
+			if (ip_xfrm_me_harder(pskb))
+				ret = NF_DROP;
+#endif
+
 	}
 	return ret;
 }
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index e965b33..42b0802 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -411,12 +411,10 @@
 				       "has invalid config pointer!\n");
 				return 0;
 			}
-			clusterip_config_entry_get(cipinfo->config);
 		} else {
 			/* Case B: This is a new rule referring to an existing
 			 * clusterip config. */
 			cipinfo->config = config;
-			clusterip_config_entry_get(cipinfo->config);
 		}
 	} else {
 		/* Case C: This is a completely new clusterip config */
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
index e4d3ef1..15aa3db 100644
--- a/net/ipv4/netfilter/nf_nat_standalone.c
+++ b/net/ipv4/netfilter/nf_nat_standalone.c
@@ -245,14 +245,16 @@
 		enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 
 		if (ct->tuplehash[dir].tuple.dst.u3.ip !=
-		    ct->tuplehash[!dir].tuple.src.u3.ip
-#ifdef CONFIG_XFRM
-		    || ct->tuplehash[dir].tuple.dst.u.all !=
-		       ct->tuplehash[!dir].tuple.src.u.all
-#endif
-		    )
+		    ct->tuplehash[!dir].tuple.src.u3.ip) {
 			if (ip_route_me_harder(pskb, RTN_UNSPEC))
 				ret = NF_DROP;
+		}
+#ifdef CONFIG_XFRM
+		else if (ct->tuplehash[dir].tuple.dst.u.all !=
+			 ct->tuplehash[!dir].tuple.src.u.all)
+			if (ip_xfrm_me_harder(pskb))
+				ret = NF_DROP;
+#endif
 	}
 	return ret;
 }
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 74c4d10..3834b10 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2458,11 +2458,18 @@
 		sysctl_max_syn_backlog = 128;
 	}
 
-	/* Allow no more than 3/4 kernel memory (usually less) allocated to TCP */
-	sysctl_tcp_mem[0] = (1536 / sizeof (struct inet_bind_hashbucket)) << order;
-	sysctl_tcp_mem[1] = sysctl_tcp_mem[0] * 4 / 3;
+	/* Set the pressure threshold to be a fraction of global memory that
+	 * is up to 1/2 at 256 MB, decreasing toward zero with the amount of
+	 * memory, with a floor of 128 pages.
+	 */
+	limit = min(nr_all_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT);
+	limit = (limit * (nr_all_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11);
+	limit = max(limit, 128UL);
+	sysctl_tcp_mem[0] = limit / 4 * 3;
+	sysctl_tcp_mem[1] = limit;
 	sysctl_tcp_mem[2] = sysctl_tcp_mem[0] * 2;
 
+	/* Set per-socket limits to no more than 1/128 the pressure threshold */
 	limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7);
 	max_share = min(4UL*1024*1024, limit);
 
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index dc15113..3c24881 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -943,7 +943,8 @@
 		if (tp->packets_out > tp->snd_cwnd_used)
 			tp->snd_cwnd_used = tp->packets_out;
 
-		if ((s32)(tcp_time_stamp - tp->snd_cwnd_stamp) >= inet_csk(sk)->icsk_rto)
+		if (sysctl_tcp_slow_start_after_idle &&
+		    (s32)(tcp_time_stamp - tp->snd_cwnd_stamp) >= inet_csk(sk)->icsk_rto)
 			tcp_cwnd_application_limited(sk);
 	}
 }
@@ -1607,6 +1608,9 @@
 		 */
 		if (window <= free_space - mss || window > free_space)
 			window = (free_space/mss)*mss;
+		else if (mss == full_space &&
+		         free_space > window + full_space/2)
+			window = free_space;
 	}
 
 	return window;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index ce6c460..fc620a7 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1215,6 +1215,7 @@
 
 		if (ulen < sizeof(*uh) || pskb_trim_rcsum(skb, ulen))
 			goto short_packet;
+		uh = skb->h.uh;
 
 		udp4_csum_init(skb, uh);
 
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index 89cf59e..f68dfd8a 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -42,10 +42,9 @@
 
 	skb->nh.raw = skb_push(skb, x->props.header_len + hdrlen);
 	top_iph = skb->nh.iph;
-	hdrlen = iph->ihl * 4 - optlen;
-	skb->h.raw += hdrlen;
+	skb->h.raw += sizeof(*iph) - hdrlen;
 
-	memmove(top_iph, iph, hdrlen);
+	memmove(top_iph, iph, sizeof(*iph));
 	if (unlikely(optlen)) {
 		struct ip_beet_phdr *ph;
 
@@ -55,6 +54,8 @@
 		ph->padlen = 4 - (optlen & 4);
 		ph->hdrlen = (optlen + ph->padlen + sizeof(*ph)) / 8;
 		ph->nexthdr = top_iph->protocol;
+		if (ph->padlen)
+			memset(ph + 1, IPOPT_NOP, ph->padlen);
 
 		top_iph->protocol = IPPROTO_BEETPH;
 		top_iph->ihl = sizeof(struct iphdr) / 4;
@@ -77,29 +78,32 @@
 	protocol = iph->protocol;
 
 	if (unlikely(iph->protocol == IPPROTO_BEETPH)) {
-		struct ip_beet_phdr *ph = (struct ip_beet_phdr*)(iph + 1);
+		struct ip_beet_phdr *ph;
 
 		if (!pskb_may_pull(skb, sizeof(*ph)))
 			goto out;
+		ph = (struct ip_beet_phdr *)(skb->h.ipiph + 1);
 
-		phlen = ph->hdrlen * 8;
-		optlen = phlen - ph->padlen - sizeof(*ph);
+		phlen = sizeof(*ph) + ph->padlen;
+		optlen = ph->hdrlen * 8 - phlen;
 		if (optlen < 0 || optlen & 3 || optlen > 250)
 			goto out;
 
-		if (!pskb_may_pull(skb, phlen))
+		if (!pskb_may_pull(skb, phlen + optlen))
 			goto out;
+		skb->len -= phlen + optlen;
 
 		ph_nexthdr = ph->nexthdr;
 	}
 
-	skb_push(skb, sizeof(*iph) - phlen + optlen);
-	memmove(skb->data, skb->nh.raw, sizeof(*iph));
-	skb->nh.raw = skb->data;
+	skb->nh.raw = skb->data + (phlen - sizeof(*iph));
+	memmove(skb->nh.raw, iph, sizeof(*iph));
+	skb->h.raw = skb->data + (phlen + optlen);
+	skb->data = skb->h.raw;
 
 	iph = skb->nh.iph;
 	iph->ihl = (sizeof(*iph) + optlen) / 4;
-	iph->tot_len = htons(skb->len);
+	iph->tot_len = htons(skb->len + iph->ihl * 4);
 	iph->daddr = x->sel.daddr.a4;
 	iph->saddr = x->sel.saddr.a4;
 	if (ph_nexthdr)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index e16f1bb..7552663 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -342,10 +342,9 @@
 	}
 #endif
 
-	if (netif_carrier_ok(dev))
+	if (netif_running(dev) && netif_carrier_ok(dev))
 		ndev->if_flags |= IF_READY;
 
-
 	ipv6_mc_init_dev(ndev);
 	ndev->tstamp = jiffies;
 #ifdef CONFIG_SYSCTL
@@ -808,7 +807,7 @@
 #define IPV6_SADDR_SCORE_LABEL		0x0020
 #define IPV6_SADDR_SCORE_PRIVACY	0x0040
 
-static int inline ipv6_saddr_preferred(int type)
+static inline int ipv6_saddr_preferred(int type)
 {
 	if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4|
 		    IPV6_ADDR_LOOPBACK|IPV6_ADDR_RESERVED))
@@ -817,7 +816,7 @@
 }
 
 /* static matching label */
-static int inline ipv6_saddr_label(const struct in6_addr *addr, int type)
+static inline int ipv6_saddr_label(const struct in6_addr *addr, int type)
 {
  /*
   * 	prefix (longest match)	label
@@ -3322,7 +3321,7 @@
 		rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err);
 }
 
-static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
+static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
 				__s32 *array, int bytes)
 {
 	BUG_ON(bytes < (DEVCONF_MAX * 4));
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index 0862809..ea3035b 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -131,8 +131,6 @@
 
 static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = {
 	FRA_GENERIC_POLICY,
-	[FRA_SRC]	= { .len = sizeof(struct in6_addr) },
-	[FRA_DST]	= { .len = sizeof(struct in6_addr) },
 };
 
 static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
@@ -142,9 +140,6 @@
 	int err = -EINVAL;
 	struct fib6_rule *rule6 = (struct fib6_rule *) rule;
 
-	if (frh->src_len > 128 || frh->dst_len > 128)
-		goto errout;
-
 	if (rule->action == FR_ACT_TO_TBL) {
 		if (rule->table == RT6_TABLE_UNSPEC)
 			goto errout;
@@ -155,11 +150,11 @@
 		}
 	}
 
-	if (tb[FRA_SRC])
+	if (frh->src_len)
 		nla_memcpy(&rule6->src.addr, tb[FRA_SRC],
 			   sizeof(struct in6_addr));
 
-	if (tb[FRA_DST])
+	if (frh->dst_len)
 		nla_memcpy(&rule6->dst.addr, tb[FRA_DST],
 			   sizeof(struct in6_addr));
 
@@ -186,11 +181,11 @@
 	if (frh->tos && (rule6->tclass != frh->tos))
 		return 0;
 
-	if (tb[FRA_SRC] &&
+	if (frh->src_len &&
 	    nla_memcmp(tb[FRA_SRC], &rule6->src.addr, sizeof(struct in6_addr)))
 		return 0;
 
-	if (tb[FRA_DST] &&
+	if (frh->dst_len &&
 	    nla_memcmp(tb[FRA_DST], &rule6->dst.addr, sizeof(struct in6_addr)))
 		return 0;
 
@@ -240,6 +235,7 @@
 static struct fib_rules_ops fib6_rules_ops = {
 	.family			= AF_INET6,
 	.rule_size		= sizeof(struct fib6_rule),
+	.addr_size		= sizeof(struct in6_addr),
 	.action			= fib6_rule_action,
 	.match			= fib6_rule_match,
 	.configure		= fib6_rule_configure,
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index f4d7be7..268f476 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -658,6 +658,10 @@
 		ins = &iter->u.dst.rt6_next;
 	}
 
+	/* Reset round-robin state, if necessary */
+	if (ins == &fn->leaf)
+		fn->rr_ptr = NULL;
+
 	/*
 	 *	insert node
 	 */
@@ -1109,6 +1113,10 @@
 	rt6_stats.fib_rt_entries--;
 	rt6_stats.fib_discarded_routes++;
 
+	/* Reset round-robin state, if necessary */
+	if (fn->rr_ptr == rt)
+		fn->rr_ptr = NULL;
+
 	/* Adjust walkers */
 	read_lock(&fib6_walker_lock);
 	FOR_WALKERS(w) {
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 11bfc7c..61e7a6c 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -108,8 +108,10 @@
 
 	/* pkt_len may be zero if Jumbo payload option is present */
 	if (pkt_len || hdr->nexthdr != NEXTHDR_HOP) {
-		if (pkt_len + sizeof(struct ipv6hdr) > skb->len)
-			goto truncated;
+		if (pkt_len + sizeof(struct ipv6hdr) > skb->len) {
+			IP6_INC_STATS_BH(idev, IPSTATS_MIB_INTRUNCATEDPKTS);
+			goto drop;
+		}
 		if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr))) {
 			IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS);
 			goto drop;
@@ -128,8 +130,6 @@
 	rcu_read_unlock();
 
 	return NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish);
-truncated:
-	IP6_INC_STATS_BH(idev, IPSTATS_MIB_INTRUNCATEDPKTS);
 err:
 	IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS);
 drop:
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 286c867..f5f9582 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -413,7 +413,7 @@
 		}
 
 		/* routing header option needs extra check */
-		if (optname == IPV6_RTHDR && opt->srcrt) {
+		if (optname == IPV6_RTHDR && opt && opt->srcrt) {
 			struct ipv6_rt_hdr *rthdr = opt->srcrt;
 			switch (rthdr->type) {
 			case IPV6_SRCRT_TYPE_0:
@@ -795,12 +795,16 @@
 EXPORT_SYMBOL(compat_ipv6_setsockopt);
 #endif
 
-static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_opt_hdr *hdr,
+static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_txoptions *opt,
 				  char __user *optval, int len)
 {
-	if (!hdr)
+	struct ipv6_opt_hdr *hdr;
+
+	if (!opt || !opt->hopopt)
 		return 0;
-	len = min_t(int, len, ipv6_optlen(hdr));
+	hdr = opt->hopopt;
+
+	len = min_t(unsigned int, len, ipv6_optlen(hdr));
 	if (copy_to_user(optval, hdr, ipv6_optlen(hdr)))
 		return -EFAULT;
 	return len;
@@ -940,7 +944,7 @@
 	{
 
 		lock_sock(sk);
-		len = ipv6_getsockopt_sticky(sk, np->opt->hopopt,
+		len = ipv6_getsockopt_sticky(sk, np->opt,
 					     optval, len);
 		release_sock(sk);
 		return put_user(len, optlen);
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 6f19c4a..d110245 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -257,6 +257,7 @@
 		}
 		nf_conntrack_get(reasm->nfct);
 		(*pskb)->nfct = reasm->nfct;
+		(*pskb)->nfctinfo = reasm->nfctinfo;
 		return NF_ACCEPT;
 	}
 
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 306d5d8..203e069 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -687,9 +687,9 @@
 	int err;
 
 	/* Rough check on arithmetic overflow,
-	   better check is made in ip6_build_xmit
+	   better check is made in ip6_append_data().
 	 */
-	if (len < 0)
+	if (len > INT_MAX)
 		return -EMSGSIZE;
 
 	/* Mirror BSD error message compatibility */
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 0e1f4b2..ad9b285 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -308,27 +308,18 @@
 /*
  * Default Router Selection (RFC 2461 6.3.6)
  */
-static int inline rt6_check_dev(struct rt6_info *rt, int oif)
+static inline int rt6_check_dev(struct rt6_info *rt, int oif)
 {
 	struct net_device *dev = rt->rt6i_dev;
-	int ret = 0;
-
-	if (!oif)
+	if (!oif || dev->ifindex == oif)
 		return 2;
-	if (dev->flags & IFF_LOOPBACK) {
-		if (!WARN_ON(rt->rt6i_idev == NULL) &&
-		    rt->rt6i_idev->dev->ifindex == oif)
-			ret = 1;
-		else
-			return 0;
-	}
-	if (dev->ifindex == oif)
-		return 2;
-
-	return ret;
+	if ((dev->flags & IFF_LOOPBACK) &&
+	    rt->rt6i_idev && rt->rt6i_idev->dev->ifindex == oif)
+		return 1;
+	return 0;
 }
 
-static int inline rt6_check_neigh(struct rt6_info *rt)
+static inline int rt6_check_neigh(struct rt6_info *rt)
 {
 	struct neighbour *neigh = rt->rt6i_nexthop;
 	int m = 0;
@@ -363,55 +354,76 @@
 	return m;
 }
 
-static struct rt6_info *rt6_select(struct rt6_info **head, int oif,
-				   int strict)
+static struct rt6_info *find_match(struct rt6_info *rt, int oif, int strict,
+				   int *mpri, struct rt6_info *match)
 {
-	struct rt6_info *match = NULL, *last = NULL;
-	struct rt6_info *rt, *rt0 = *head;
-	u32 metric;
+	int m;
+
+	if (rt6_check_expired(rt))
+		goto out;
+
+	m = rt6_score_route(rt, oif, strict);
+	if (m < 0)
+		goto out;
+
+	if (m > *mpri) {
+		if (strict & RT6_LOOKUP_F_REACHABLE)
+			rt6_probe(match);
+		*mpri = m;
+		match = rt;
+	} else if (strict & RT6_LOOKUP_F_REACHABLE) {
+		rt6_probe(rt);
+	}
+
+out:
+	return match;
+}
+
+static struct rt6_info *find_rr_leaf(struct fib6_node *fn,
+				     struct rt6_info *rr_head,
+				     u32 metric, int oif, int strict)
+{
+	struct rt6_info *rt, *match;
 	int mpri = -1;
 
-	RT6_TRACE("%s(head=%p(*head=%p), oif=%d)\n",
-		  __FUNCTION__, head, head ? *head : NULL, oif);
+	match = NULL;
+	for (rt = rr_head; rt && rt->rt6i_metric == metric;
+	     rt = rt->u.dst.rt6_next)
+		match = find_match(rt, oif, strict, &mpri, match);
+	for (rt = fn->leaf; rt && rt != rr_head && rt->rt6i_metric == metric;
+	     rt = rt->u.dst.rt6_next)
+		match = find_match(rt, oif, strict, &mpri, match);
 
-	for (rt = rt0, metric = rt0->rt6i_metric;
-	     rt && rt->rt6i_metric == metric && (!last || rt != rt0);
-	     rt = rt->u.dst.rt6_next) {
-		int m;
+	return match;
+}
 
-		if (rt6_check_expired(rt))
-			continue;
+static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict)
+{
+	struct rt6_info *match, *rt0;
 
-		last = rt;
+	RT6_TRACE("%s(fn->leaf=%p, oif=%d)\n",
+		  __FUNCTION__, fn->leaf, oif);
 
-		m = rt6_score_route(rt, oif, strict);
-		if (m < 0)
-			continue;
+	rt0 = fn->rr_ptr;
+	if (!rt0)
+		fn->rr_ptr = rt0 = fn->leaf;
 
-		if (m > mpri) {
-			if (strict & RT6_LOOKUP_F_REACHABLE)
-				rt6_probe(match);
-			match = rt;
-			mpri = m;
-		} else if (strict & RT6_LOOKUP_F_REACHABLE) {
-			rt6_probe(rt);
-		}
-	}
+	match = find_rr_leaf(fn, rt0, rt0->rt6i_metric, oif, strict);
 
 	if (!match &&
-	    (strict & RT6_LOOKUP_F_REACHABLE) &&
-	    last && last != rt0) {
+	    (strict & RT6_LOOKUP_F_REACHABLE)) {
+		struct rt6_info *next = rt0->u.dst.rt6_next;
+
 		/* no entries matched; do round-robin */
-		static DEFINE_SPINLOCK(lock);
-		spin_lock(&lock);
-		*head = rt0->u.dst.rt6_next;
-		rt0->u.dst.rt6_next = last->u.dst.rt6_next;
-		last->u.dst.rt6_next = rt0;
-		spin_unlock(&lock);
+		if (!next || next->rt6i_metric != rt0->rt6i_metric)
+			next = fn->leaf;
+
+		if (next != rt0)
+			fn->rr_ptr = next;
 	}
 
-	RT6_TRACE("%s() => %p, score=%d\n",
-		  __FUNCTION__, match, mpri);
+	RT6_TRACE("%s() => %p\n",
+		  __FUNCTION__, match);
 
 	return (match ? match : &ip6_null_entry);
 }
@@ -657,7 +669,7 @@
 	fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
 
 restart:
-	rt = rt6_select(&fn->leaf, fl->iif, strict | reachable);
+	rt = rt6_select(fn, fl->iif, strict | reachable);
 	BACKTRACK(&fl->fl6_src);
 	if (rt == &ip6_null_entry ||
 	    rt->rt6i_flags & RTF_CACHE)
@@ -752,7 +764,7 @@
 	fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
 
 restart:
-	rt = rt6_select(&fn->leaf, fl->oif, strict | reachable);
+	rt = rt6_select(fn, fl->oif, strict | reachable);
 	BACKTRACK(&fl->fl6_src);
 	if (rt == &ip6_null_entry ||
 	    rt->rt6i_flags & RTF_CACHE)
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index f57a9ba..92f9992 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1453,6 +1453,7 @@
 	   First: no IPv4 options.
 	 */
 	newinet->opt = NULL;
+	newnp->ipv6_fl_list = NULL;
 
 	/* Clone RX bits */
 	newnp->rxopt.all = np->rxopt.all;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 0ad4719..f590db5 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -615,7 +615,7 @@
 		return udp_sendmsg(iocb, sk, msg, len);
 
 	/* Rough check on arithmetic overflow,
-	   better check is made in ip6_build_xmit
+	   better check is made in ip6_append_data().
 	   */
 	if (len > INT_MAX - sizeof(struct udphdr))
 		return -EMSGSIZE;
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index ee4b84a..93c4223 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -58,7 +58,7 @@
 static struct hlist_head xfrm6_tunnel_spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE];
 static struct hlist_head xfrm6_tunnel_spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE];
 
-static unsigned inline xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
+static inline unsigned xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
 {
 	unsigned h;
 
@@ -70,7 +70,7 @@
 	return h;
 }
 
-static unsigned inline xfrm6_tunnel_spi_hash_byspi(u32 spi)
+static inline unsigned xfrm6_tunnel_spi_hash_byspi(u32 spi)
 {
 	return spi % XFRM6_TUNNEL_SPI_BYSPI_HSIZE;
 }
diff --git a/net/irda/irnet/irnet.h b/net/irda/irnet/irnet.h
index 873ae18..bc2e15c 100644
--- a/net/irda/irnet/irnet.h
+++ b/net/irda/irnet/irnet.h
@@ -419,7 +419,7 @@
   u32			raccm;		/* to please pppd - dummy) */
   unsigned int		flags;		/* PPP flags (compression, ...) */
   unsigned int		rbits;		/* Unused receive flags ??? */
-
+  struct work_struct disconnect_work;   /* Process context disconnection */
   /* ------------------------ IrTTP part ------------------------ */
   /* We create a pseudo "socket" over the IrDA tranport */
   unsigned long		ttp_open;	/* Set when IrTTP is ready */
diff --git a/net/irda/irnet/irnet_irda.c b/net/irda/irnet/irnet_irda.c
index c378e66..a4f1439 100644
--- a/net/irda/irnet/irnet_irda.c
+++ b/net/irda/irnet/irnet_irda.c
@@ -10,6 +10,27 @@
 
 #include "irnet_irda.h"		/* Private header */
 
+/*
+ * PPP disconnect work: we need to make sure we're in
+ * process context when calling ppp_unregister_channel().
+ */
+static void irnet_ppp_disconnect(struct work_struct *work)
+{
+	irnet_socket * self =
+		container_of(work, irnet_socket, disconnect_work);
+
+	if (self == NULL)
+		return;
+	/*
+	 * If we were connected, cleanup & close the PPP
+	 * channel, which will kill pppd (hangup) and the rest.
+	 */
+	if (self->ppp_open && !self->ttp_open && !self->ttp_connect) {
+		ppp_unregister_channel(&self->chan);
+		self->ppp_open = 0;
+	}
+}
+
 /************************* CONTROL CHANNEL *************************/
 /*
  * When ppp is not active, /dev/irnet act as a control channel.
@@ -499,6 +520,8 @@
 #endif /* DISCOVERY_NOMASK */
   self->tx_flow = FLOW_START;	/* Flow control from IrTTP */
 
+  INIT_WORK(&self->disconnect_work, irnet_ppp_disconnect);
+
   DEXIT(IRDA_SOCK_TRACE, "\n");
   return(0);
 }
@@ -1134,15 +1157,8 @@
     {
       if(test_open)
 	{
-#ifdef MISSING_PPP_API
-	  /* ppp_unregister_channel() wants a user context, which we
-	   * are guaranteed to NOT have here. What are we supposed
-	   * to do here ? Jean II */
-	  /* If we were connected, cleanup & close the PPP channel,
-	   * which will kill pppd (hangup) and the rest */
-	  ppp_unregister_channel(&self->chan);
-	  self->ppp_open = 0;
-#endif
+	  /* ppp_unregister_channel() wants a user context. */
+	  schedule_work(&self->disconnect_work);
 	}
       else
 	{
diff --git a/net/irda/irttp.c b/net/irda/irttp.c
index a7486b3..da3f2bc 100644
--- a/net/irda/irttp.c
+++ b/net/irda/irttp.c
@@ -1455,6 +1455,7 @@
 
 	/* Not everything should be copied */
 	new->notify.instance = instance;
+	spin_lock_init(&new->lock);
 	init_timer(&new->todo_timer);
 
 	skb_queue_head_init(&new->rx_queue);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 1c58204..a4e7e2d 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1467,9 +1467,6 @@
 
 	err = xfrm_state_delete(x);
 
-	xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
-		       AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
-
 	if (err < 0)
 		goto out;
 
@@ -1478,6 +1475,8 @@
 	c.event = XFRM_MSG_DELSA;
 	km_state_notify(x, &c);
 out:
+	xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
+		       AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
 	xfrm_state_put(x);
 
 	return err;
@@ -2294,14 +2293,12 @@
 	}
 
 	xp = xfrm_policy_bysel_ctx(XFRM_POLICY_TYPE_MAIN, pol->sadb_x_policy_dir-1,
-				   &sel, tmp.security, 1);
+				   &sel, tmp.security, 1, &err);
 	security_xfrm_policy_free(&tmp);
 
 	if (xp == NULL)
 		return -ENOENT;
 
-	err = security_xfrm_policy_delete(xp);
-
 	xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
 		       AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL);
 
@@ -2539,7 +2536,7 @@
 static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
 {
 	unsigned int dir;
-	int err;
+	int err = 0, delete;
 	struct sadb_x_policy *pol;
 	struct xfrm_policy *xp;
 	struct km_event c;
@@ -2551,16 +2548,20 @@
 	if (dir >= XFRM_POLICY_MAX)
 		return -EINVAL;
 
+	delete = (hdr->sadb_msg_type == SADB_X_SPDDELETE2);
 	xp = xfrm_policy_byid(XFRM_POLICY_TYPE_MAIN, dir, pol->sadb_x_policy_id,
-			      hdr->sadb_msg_type == SADB_X_SPDDELETE2);
+			      delete, &err);
 	if (xp == NULL)
 		return -ENOENT;
 
-	err = 0;
+	if (delete) {
+		xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
+			       AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL);
 
-	c.seq = hdr->sadb_msg_seq;
-	c.pid = hdr->sadb_msg_pid;
-	if (hdr->sadb_msg_type == SADB_X_SPDDELETE2) {
+		if (err)
+			goto out;
+		c.seq = hdr->sadb_msg_seq;
+		c.pid = hdr->sadb_msg_pid;
 		c.data.byid = 1;
 		c.event = XFRM_MSG_DELPOLICY;
 		km_policy_notify(xp, dir, &c);
@@ -2568,6 +2569,7 @@
 		err = key_pol_get_resp(sk, xp, hdr, dir);
 	}
 
+out:
 	xfrm_pol_put(xp);
 	return err;
 }
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 253fce3..54698af 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -275,6 +275,7 @@
 	tristate 'Connection tracking netlink interface (EXPERIMENTAL)'
 	depends on EXPERIMENTAL && NF_CONNTRACK && NETFILTER_NETLINK
 	depends on NF_CONNTRACK!=y || NETFILTER_NETLINK!=m
+	depends on NF_NAT=n || NF_NAT
 	help
 	  This option enables support for a netlink-based userspace interface
 
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 91a0972..5cb30eb 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -486,7 +486,7 @@
 			 * for physical device (when called from ipv4) */
 			NFA_PUT(inst->skb, NFULA_IFINDEX_OUTDEV,
 				sizeof(tmp_uint), &tmp_uint);
-			if (skb->nf_bridge) {
+			if (skb->nf_bridge && skb->nf_bridge->physoutdev) {
 				tmp_uint =
 				    htonl(skb->nf_bridge->physoutdev->ifindex);
 				NFA_PUT(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
@@ -615,7 +615,7 @@
 
 	plen = 0;
 	if (prefix)
-		plen = strlen(prefix);
+		plen = strlen(prefix) + 1;
 
 	/* all macros expand to constant values at compile time */
 	/* FIXME: do we want to make the size calculation conditional based on
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 8c34f1c..f92d531 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -700,23 +700,7 @@
 	unsigned char cause, diagnostic;
 	struct net_device *dev;
 	ax25_uid_assoc *user;
-	int n;
-
-	if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
-		sock->state = SS_CONNECTED;
-		return 0;	/* Connect completed during a ERESTARTSYS event */
-	}
-
-	if (sk->sk_state == TCP_CLOSE && sock->state == SS_CONNECTING) {
-		sock->state = SS_UNCONNECTED;
-		return -ECONNREFUSED;
-	}
-
-	if (sk->sk_state == TCP_ESTABLISHED)
-		return -EISCONN;	/* No reconnect on a seqpacket socket */
-
-	sk->sk_state   = TCP_CLOSE;
-	sock->state = SS_UNCONNECTED;
+	int n, err = 0;
 
 	if (addr_len != sizeof(struct sockaddr_rose) && addr_len != sizeof(struct full_sockaddr_rose))
 		return -EINVAL;
@@ -734,24 +718,53 @@
 	if ((rose->source_ndigis + addr->srose_ndigis) > ROSE_MAX_DIGIS)
 		return -EINVAL;
 
+	lock_sock(sk);
+
+	if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
+		/* Connect completed during a ERESTARTSYS event */
+		sock->state = SS_CONNECTED;
+		goto out_release;
+	}
+
+	if (sk->sk_state == TCP_CLOSE && sock->state == SS_CONNECTING) {
+		sock->state = SS_UNCONNECTED;
+		err = -ECONNREFUSED;
+		goto out_release;
+	}
+
+	if (sk->sk_state == TCP_ESTABLISHED) {
+		/* No reconnect on a seqpacket socket */
+		err = -EISCONN;
+		goto out_release;
+	}
+
+	sk->sk_state   = TCP_CLOSE;
+	sock->state = SS_UNCONNECTED;
+
 	rose->neighbour = rose_get_neigh(&addr->srose_addr, &cause,
 					 &diagnostic);
 	if (!rose->neighbour)
 		return -ENETUNREACH;
 
 	rose->lci = rose_new_lci(rose->neighbour);
-	if (!rose->lci)
-		return -ENETUNREACH;
+	if (!rose->lci) {
+		err = -ENETUNREACH;
+		goto out_release;
+	}
 
 	if (sock_flag(sk, SOCK_ZAPPED)) {	/* Must bind first - autobinding in this may or may not work */
 		sock_reset_flag(sk, SOCK_ZAPPED);
 
-		if ((dev = rose_dev_first()) == NULL)
-			return -ENETUNREACH;
+		if ((dev = rose_dev_first()) == NULL) {
+			err = -ENETUNREACH;
+			goto out_release;
+		}
 
 		user = ax25_findbyuid(current->euid);
-		if (!user)
-			return -EINVAL;
+		if (!user) {
+			err = -EINVAL;
+			goto out_release;
+		}
 
 		memcpy(&rose->source_addr, dev->dev_addr, ROSE_ADDR_LEN);
 		rose->source_call = user->call;
@@ -789,8 +802,10 @@
 	rose_start_t1timer(sk);
 
 	/* Now the loop */
-	if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK))
-		return -EINPROGRESS;
+	if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) {
+		err = -EINPROGRESS;
+		goto out_release;
+	}
 
 	/*
 	 * A Connect Ack with Choke or timeout or failed routing will go to
@@ -805,8 +820,10 @@
 			set_current_state(TASK_INTERRUPTIBLE);
 			if (sk->sk_state != TCP_SYN_SENT)
 				break;
+			release_sock(sk);
 			if (!signal_pending(tsk)) {
 				schedule();
+				lock_sock(sk);
 				continue;
 			}
 			current->state = TASK_RUNNING;
@@ -822,14 +839,19 @@
 		rose->neighbour = rose_get_neigh(&addr->srose_addr, &cause, &diagnostic);
 		if (rose->neighbour)
 			goto rose_try_next_neigh;
-	/* No more neighbour */
+
+		/* No more neighbours */
 		sock->state = SS_UNCONNECTED;
-		return sock_error(sk);	/* Always set at this point */
+		err = sock_error(sk);	/* Always set at this point */
+		goto out_release;
 	}
 
 	sock->state = SS_CONNECTED;
 
-	return 0;
+out_release:
+	release_sock(sk);
+
+	return err;
 }
 
 static int rose_accept(struct socket *sock, struct socket *newsock, int flags)
@@ -877,6 +899,8 @@
 			lock_sock(sk);
 			continue;
 		}
+		current->state = TASK_RUNNING;
+		remove_wait_queue(sk->sk_sleep, &wait);
 		return -ERESTARTSYS;
 	}
 	current->state = TASK_RUNNING;
diff --git a/net/sched/Makefile b/net/sched/Makefile
index ff2d6e5..020767a 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -17,7 +17,6 @@
 obj-$(CONFIG_NET_SCH_FIFO)	+= sch_fifo.o
 obj-$(CONFIG_NET_SCH_CBQ)	+= sch_cbq.o
 obj-$(CONFIG_NET_SCH_HTB)	+= sch_htb.o
-obj-$(CONFIG_NET_SCH_HPFQ)	+= sch_hpfq.o
 obj-$(CONFIG_NET_SCH_HFSC)	+= sch_hfsc.o
 obj-$(CONFIG_NET_SCH_RED)	+= sch_red.o
 obj-$(CONFIG_NET_SCH_GRED)	+= sch_gred.o
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index 68f26cb..3e93683 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -198,7 +198,7 @@
 		skb2->tc_verd = SET_TC_FROM(skb2->tc_verd, at);
 
 	skb2->dev = dev;
-	skb2->input_dev = skb->dev;
+	skb2->iif = skb->dev->ifindex;
 	dev_queue_xmit(skb2);
 	spin_unlock(&m->tcf_lock);
 	return m->tcf_action;
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index fad08e5..4a91f08 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -81,6 +81,13 @@
 
 static int basic_init(struct tcf_proto *tp)
 {
+	struct basic_head *head;
+
+	head = kzalloc(sizeof(*head), GFP_KERNEL);
+	if (head == NULL)
+		return -ENOBUFS;
+	INIT_LIST_HEAD(&head->flist);
+	tp->root = head;
 	return 0;
 }
 
@@ -102,6 +109,7 @@
 		list_del(&f->link);
 		basic_delete_filter(tp, f);
 	}
+	kfree(head);
 }
 
 static int basic_delete(struct tcf_proto *tp, unsigned long arg)
@@ -176,15 +184,6 @@
 	}
 
 	err = -ENOBUFS;
-	if (head == NULL) {
-		head = kzalloc(sizeof(*head), GFP_KERNEL);
-		if (head == NULL)
-			goto errout;
-
-		INIT_LIST_HEAD(&head->flist);
-		tp->root = head;
-	}
-
 	f = kzalloc(sizeof(*f), GFP_KERNEL);
 	if (f == NULL)
 		goto errout;
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index e85df07..abc47cc 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -93,7 +93,7 @@
 	spin_unlock_bh(&dev->queue_lock);
 }
 
-static void __inline__
+static inline void
 route4_set_fastmap(struct route4_head *head, u32 id, int iif,
 		   struct route4_filter *f)
 {
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index 040e2d2..7563fdc 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -245,9 +245,9 @@
 	}
 
 	if (tb[TCA_TCINDEX_SHIFT-1]) {
-		if (RTA_PAYLOAD(tb[TCA_TCINDEX_SHIFT-1]) < sizeof(u16))
+		if (RTA_PAYLOAD(tb[TCA_TCINDEX_SHIFT-1]) < sizeof(int))
 			goto errout;
-		cp.shift = *(u16 *) RTA_DATA(tb[TCA_TCINDEX_SHIFT-1]);
+		cp.shift = *(int *) RTA_DATA(tb[TCA_TCINDEX_SHIFT-1]);
 	}
 
 	err = -EBUSY;
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 396deb7..407c6fb 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1184,10 +1184,12 @@
 
 	sch_tree_lock(sch);
 
-	list_del(&cl->hlist);
 	list_del(&cl->siblings);
 	hfsc_adjust_levels(cl->cl_parent);
+
 	hfsc_purge_queue(sch, cl);
+	list_del(&cl->hlist);
+
 	if (--cl->refcnt == 0)
 		hfsc_destroy_class(sch, cl);
 
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 97cbb9a..3c3294d 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1380,15 +1380,15 @@
 
 	sch_tree_lock(sch);
 
-	/* delete from hash and active; remainder in destroy_class */
-	hlist_del_init(&cl->hlist);
-
 	if (!cl->level) {
 		qlen = cl->un.leaf.q->q.qlen;
 		qdisc_reset(cl->un.leaf.q);
 		qdisc_tree_decrease_qlen(cl->un.leaf.q, qlen);
 	}
 
+	/* delete from hash and active; remainder in destroy_class */
+	hlist_del_init(&cl->hlist);
+
 	if (cl->prio_activity)
 		htb_deactivate(q, cl);
 
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index fa82b73..78d2ddb 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1046,6 +1046,9 @@
 		trans = list_entry(pos, struct sctp_transport, transports);
 		if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr))
 			sctp_assoc_del_peer(asoc, &trans->ipaddr);
+
+		if (asoc->state >= SCTP_STATE_ESTABLISHED)
+			sctp_transport_reset(trans);
 	}
 
 	/* If the case is A (association restart), use
@@ -1063,6 +1066,18 @@
 		 */
 		sctp_ssnmap_clear(asoc->ssnmap);
 
+		/* Flush the ULP reassembly and ordered queue.
+		 * Any data there will now be stale and will
+		 * cause problems.
+		 */
+		sctp_ulpq_flush(&asoc->ulpq);
+
+		/* reset the overall association error count so
+		 * that the restarted association doesn't get torn
+		 * down on the next retransmission timer.
+		 */
+		asoc->overall_error_count = 0;
+
 	} else {
 		/* Add any peer addresses from the new association. */
 		list_for_each(pos, &new->peer.transport_addr_list) {
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 63fe109..0b9c49b 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -360,7 +360,7 @@
 		return;
 	}
 
-	read_lock(&in6_dev->lock);
+	read_lock_bh(&in6_dev->lock);
 	for (ifp = in6_dev->addr_list; ifp; ifp = ifp->if_next) {
 		/* Add the address to the local list.  */
 		addr = t_new(struct sctp_sockaddr_entry, GFP_ATOMIC);
@@ -374,7 +374,7 @@
 		}
 	}
 
-	read_unlock(&in6_dev->lock);
+	read_unlock_bh(&in6_dev->lock);
 	rcu_read_unlock();
 }
 
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 70c39ea..e9097cf 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -4342,8 +4342,24 @@
 					void *arg,
 					sctp_cmd_seq_t *commands)
 {
-	return sctp_sf_heartbeat(ep, asoc, type, (struct sctp_transport *)arg,
-				 commands);
+	if (SCTP_DISPOSITION_NOMEM == sctp_sf_heartbeat(ep, asoc, type,
+				      (struct sctp_transport *)arg, commands))
+		return SCTP_DISPOSITION_NOMEM;
+
+	/*
+	 * RFC 2960 (bis), section 8.3
+	 *
+	 *    D) Request an on-demand HEARTBEAT on a specific destination
+	 *    transport address of a given association.
+	 *
+	 *    The endpoint should increment the respective error  counter of
+	 *    the destination transport address each time a HEARTBEAT is sent
+	 *    to that address and not acknowledged within one RTO.
+	 *
+	 */
+	sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_RESET,
+			SCTP_TRANSPORT(arg));
+	return SCTP_DISPOSITION_CONSUME;
 }
 
 /*
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index a596f53..4d8c2ab 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -526,3 +526,35 @@
 	timeout += jiffies;
 	return timeout;
 }
+
+/* Reset transport variables to their initial values */
+void sctp_transport_reset(struct sctp_transport *t)
+{
+	struct sctp_association *asoc = t->asoc;
+
+	/* RFC 2960 (bis), Section 5.2.4
+	 * All the congestion control parameters (e.g., cwnd, ssthresh)
+	 * related to this peer MUST be reset to their initial values
+	 * (see Section 6.2.1)
+	 */
+	t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380));
+	t->ssthresh = asoc->peer.i.a_rwnd;
+	t->rto = asoc->rto_initial;
+	t->rtt = 0;
+	t->srtt = 0;
+	t->rttvar = 0;
+
+	/* Reset these additional varibles so that we have a clean
+	 * slate.
+	 */
+	t->partial_bytes_acked = 0;
+	t->flight_size = 0;
+	t->error_count = 0;
+	t->rto_pending = 0;
+
+	/* Initialize the state information for SFR-CACC */
+	t->cacc.changeover_active = 0;
+	t->cacc.cycling_changeover = 0;
+	t->cacc.next_tsn_at_change = 0;
+	t->cacc.cacc_saw_newack = 0;
+}
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
index f4759a9..bfb197e 100644
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -73,7 +73,7 @@
 
 
 /* Flush the reassembly and ordering queues.  */
-static void sctp_ulpq_flush(struct sctp_ulpq *ulpq)
+void sctp_ulpq_flush(struct sctp_ulpq *ulpq)
 {
 	struct sk_buff *skb;
 	struct sctp_ulpevent *event;
diff --git a/net/socket.c b/net/socket.c
index 9566e57..ea8f81a 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1381,7 +1381,7 @@
 
 	err = sock_attach_fd(newsock, newfile);
 	if (err < 0)
-		goto out_fd;
+		goto out_fd_simple;
 
 	err = security_socket_accept(sock, newsock);
 	if (err)
@@ -1414,6 +1414,11 @@
 	fput_light(sock->file, fput_needed);
 out:
 	return err;
+out_fd_simple:
+	sock_release(newsock);
+	put_filp(newfile);
+	put_unused_fd(newfd);
+	goto out_put;
 out_fd:
 	fput(newfile);
 	put_unused_fd(newfd);
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index f6e1eb1..593f62f 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -779,8 +779,8 @@
 	}
 
 	clear_bit(SK_DATA, &svsk->sk_flags);
-	while ((err == kernel_recvmsg(svsk->sk_sock, &msg, NULL,
-				      0, 0, MSG_PEEK | MSG_DONTWAIT)) < 0 ||
+	while ((err = kernel_recvmsg(svsk->sk_sock, &msg, NULL,
+				     0, 0, MSG_PEEK | MSG_DONTWAIT)) < 0 ||
 	       (skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err)) == NULL) {
 		if (err == -EAGAIN) {
 			svc_sock_received(svsk);
diff --git a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c
deleted file mode 100644
index 41d7e32..0000000
--- a/net/wanrouter/af_wanpipe.c
+++ /dev/null
@@ -1,2600 +0,0 @@
-/*****************************************************************************
-* af_wanpipe.c	WANPIPE(tm) Secure Socket Layer.
-*
-* Author:	Nenad Corbic	<ncorbic@sangoma.com>
-*
-* Copyright:	(c) 2000 Sangoma Technologies Inc.
-*
-*		This program is free software; you can redistribute it and/or
-*		modify it under the terms of the GNU General Public License
-*		as published by the Free Software Foundation; either version
-*		2 of the License, or (at your option) any later version.
-* ============================================================================
-* Due Credit:
-*               Wanpipe socket layer is based on Packet and
-*               the X25 socket layers. The above sockets were
-*               used for the specific use of Sangoma Technologies
-*               API programs.
-*               Packet socket Authors: Ross Biro, Fred N. van Kempen and
-*                                      Alan Cox.
-*               X25 socket Author: Jonathan Naylor.
-* ============================================================================
-* Mar 15, 2002  Arnaldo C. Melo  o Use wp_sk()->num, as it isnt anymore in sock
-* Apr 25, 2000  Nenad Corbic     o Added the ability to send zero length packets.
-* Mar 13, 2000  Nenad Corbic	 o Added a tx buffer check via ioctl call.
-* Mar 06, 2000  Nenad Corbic     o Fixed the corrupt sock lcn problem.
-*                                  Server and client application can run
-*                                  simultaneously without conflicts.
-* Feb 29, 2000  Nenad Corbic     o Added support for PVC protocols, such as
-*                                  CHDLC, Frame Relay and HDLC API.
-* Jan 17, 2000 	Nenad Corbic	 o Initial version, based on AF_PACKET socket.
-*			           X25API support only.
-*
-******************************************************************************/
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/capability.h>
-#include <linux/fcntl.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/poll.h>
-#include <linux/wireless.h>
-#include <linux/kmod.h>
-#include <net/ip.h>
-#include <net/protocol.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <linux/errno.h>
-#include <linux/timer.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/if_wanpipe.h>
-#include <linux/pkt_sched.h>
-#include <linux/tcp_states.h>
-#include <linux/if_wanpipe_common.h>
-
-#ifdef CONFIG_INET
-#include <net/inet_common.h>
-#endif
-
-#define SLOW_BACKOFF 0.1*HZ
-#define FAST_BACKOFF 0.01*HZ
-
-//#define PRINT_DEBUG
-#ifdef PRINT_DEBUG
-	#define DBG_PRINTK(format, a...) printk(format, ## a)
-#else
-	#define DBG_PRINTK(format, a...)
-#endif
-
-
-/* SECURE SOCKET IMPLEMENTATION
- *
- *   TRANSMIT:
- *
- *      When the user sends a packet via send() system call
- *      the wanpipe_sendmsg() function is executed.
- *
- *      Each packet is enqueud into sk->sk_write_queue transmit
- *      queue. When the packet is enqueued, a delayed transmit
- *      timer is triggerd which acts as a Bottom Half hander.
- *
- *      wanpipe_delay_transmit() function (BH), dequeues packets
- *      from the sk->sk_write_queue transmit queue and sends it
- *      to the deriver via dev->hard_start_xmit(skb, dev) function.
- *      Note, this function is actual a function pointer of if_send()
- *      routine in the wanpipe driver.
- *
- *      X25API GUARANTEED DELIVERY:
- *
- *         In order to provide 100% guaranteed packet delivery,
- *         an atomic 'packet_sent' counter is implemented.  Counter
- *         is incremented for each packet enqueued
- *         into sk->sk_write_queue.  Counter is decremented each
- *         time wanpipe_delayed_transmit() function successfuly
- *         passes the packet to the driver. Before each send(), a poll
- *         routine checks the sock resources The maximum value of
- *         packet sent counter is 1, thus if one packet is queued, the
- *         application will block until that packet is passed to the
- *         driver.
- *
- *   RECEIVE:
- *
- *      Wanpipe device drivers call the socket bottom half
- *      function, wanpipe_rcv() to queue the incoming packets
- *      into an AF_WANPIPE socket queue.  Based on wanpipe_rcv()
- *      return code, the driver knows whether the packet was
- *      successfully queued.  If the socket queue is full,
- *      protocol flow control is used by the driver, if any,
- *      to slow down the traffic until the sock queue is free.
- *
- *      Every time a packet arrives into a socket queue the
- *      socket wakes up processes which are waiting to receive
- *      data.
- *
- *      If the socket queue is full, the driver sets a block
- *      bit which signals the socket to kick the wanpipe driver
- *      bottom half hander when the socket queue is partialy
- *      empty. wanpipe_recvmsg() function performs this action.
- *
- *      In case of x25api, packets will never be dropped, since
- *      flow control is available.
- *
- *      In case of streaming protocols like CHDLC, packets will
- *      be dropped but the statistics will be generated.
- */
-
-
-/* The code below is used to test memory leaks. It prints out
- * a message every time kmalloc and kfree system calls get executed.
- * If the calls match there is no leak :)
- */
-
-/***********FOR DEBUGGING PURPOSES*********************************************
-#define KMEM_SAFETYZONE 8
-
-static void * dbg_kmalloc(unsigned int size, int prio, int line) {
-	void * v = kmalloc(size,prio);
-	printk(KERN_INFO "line %d  kmalloc(%d,%d) = %p\n",line,size,prio,v);
-	return v;
-}
-static void dbg_kfree(void * v, int line) {
-	printk(KERN_INFO "line %d  kfree(%p)\n",line,v);
-	kfree(v);
-}
-
-#define kmalloc(x,y) dbg_kmalloc(x,y,__LINE__)
-#define kfree(x) dbg_kfree(x,__LINE__)
-******************************************************************************/
-
-
-/* List of all wanpipe sockets. */
-HLIST_HEAD(wanpipe_sklist);
-static DEFINE_RWLOCK(wanpipe_sklist_lock);
-
-atomic_t wanpipe_socks_nr;
-static unsigned long wanpipe_tx_critical;
-
-#if 0
-/* Private wanpipe socket structures. */
-struct wanpipe_opt
-{
-	void   *mbox;		/* Mail box  */
-	void   *card; 		/* Card bouded to */
-	struct net_device *dev;	/* Bounded device */
-	unsigned short lcn;	/* Binded LCN */
-	unsigned char  svc;	/* 0=pvc, 1=svc */
-	unsigned char  timer;   /* flag for delayed transmit*/
-	struct timer_list tx_timer;
-	unsigned poll_cnt;
-	unsigned char force;	/* Used to force sock release */
-	atomic_t packet_sent;
-};
-#endif
-
-static int sk_count;
-extern const struct proto_ops wanpipe_ops;
-static unsigned long find_free_critical;
-
-static void wanpipe_unlink_driver(struct sock *sk);
-static void wanpipe_link_driver(struct net_device *dev, struct sock *sk);
-static void wanpipe_wakeup_driver(struct sock *sk);
-static int execute_command(struct sock *, unsigned char, unsigned int);
-static int check_dev(struct net_device *dev, sdla_t *card);
-struct net_device *wanpipe_find_free_dev(sdla_t *card);
-static void wanpipe_unlink_card (struct sock *);
-static int wanpipe_link_card (struct sock *);
-static struct sock *wanpipe_make_new(struct sock *);
-static struct sock *wanpipe_alloc_socket(void);
-static inline int get_atomic_device(struct net_device *dev);
-static int wanpipe_exec_cmd(struct sock *, int, unsigned int);
-static int get_ioctl_cmd (struct sock *, void *);
-static int set_ioctl_cmd (struct sock *, void *);
-static void release_device(struct net_device *dev);
-static void wanpipe_kill_sock_timer (unsigned long data);
-static void wanpipe_kill_sock_irq (struct sock *);
-static void wanpipe_kill_sock_accept (struct sock *);
-static int wanpipe_do_bind(struct sock *sk, struct net_device *dev,
-			   int protocol);
-struct sock * get_newsk_from_skb (struct sk_buff *);
-static int wanpipe_debug (struct sock *, void *);
-static void wanpipe_delayed_transmit (unsigned long data);
-static void release_driver(struct sock *);
-static void start_cleanup_timer (struct sock *);
-static void check_write_queue(struct sock *);
-static int check_driver_busy (struct sock *);
-
-/*============================================================
- * wanpipe_rcv
- *
- *	Wanpipe socket bottom half handler.  This function
- *      is called by the WANPIPE device drivers to queue a
- *      incoming packet into the socket receive queue.
- *      Once the packet is queued, all processes waiting to
- *      read are woken up.
- *
- *      During socket bind, this function is bounded into
- *      WANPIPE driver private.
- *===========================================================*/
-
-static int wanpipe_rcv(struct sk_buff *skb, struct net_device *dev,
-		       struct sock *sk)
-{
-	struct wan_sockaddr_ll *sll = (struct wan_sockaddr_ll*)skb->cb;
-	wanpipe_common_t *chan = dev->priv;
-	/*
-	 *	When we registered the protocol we saved the socket in the data
-	 *	field for just this event.
-	 */
-
-	skb->dev = dev;
-
-	sll->sll_family = AF_WANPIPE;
-	sll->sll_hatype = dev->type;
-	sll->sll_protocol = skb->protocol;
-	sll->sll_pkttype = skb->pkt_type;
-	sll->sll_ifindex = dev->ifindex;
-	sll->sll_halen = 0;
-
-	if (dev->hard_header_parse)
-		sll->sll_halen = dev->hard_header_parse(skb, sll->sll_addr);
-
-	/*
-	 * WAN_PACKET_DATA : Data which should be passed up the receive queue.
-	 * WAN_PACKET_ASYC : Asynchronous data like place call, which should
-	 *                   be passed up the listening sock.
-	 * WAN_PACKET_ERR  : Asynchronous data like clear call or restart
-	 *                   which should go into an error queue.
-	 */
-	switch (skb->pkt_type){
-
-		case WAN_PACKET_DATA:
-			if (sock_queue_rcv_skb(sk,skb)<0){
-				return -ENOMEM;
-			}
-			break;
-		case WAN_PACKET_CMD:
-			sk->sk_state = chan->state;
-			/* Bug fix: update Mar6.
-			 * Do not set the sock lcn number here, since
-			 * cmd is not guaranteed to be executed on the
-			 * board, thus Lcn could be wrong */
-			sk->sk_data_ready(sk, skb->len);
-			kfree_skb(skb);
-			break;
-		case WAN_PACKET_ERR:
-			sk->sk_state = chan->state;
-			if (sock_queue_err_skb(sk,skb)<0){
-				return -ENOMEM;
-			}
-			break;
-		default:
-			printk(KERN_INFO "wansock: BH Illegal Packet Type Dropping\n");
-			kfree_skb(skb);
-			break;
-	}
-
-//??????????????????????
-//	if (sk->sk_state == WANSOCK_DISCONNECTED){
-//		if (sk->sk_zapped) {
-//			//printk(KERN_INFO "wansock: Disconnected, killing early\n");
-//			wanpipe_unlink_driver(sk);
-//			sk->sk_bound_dev_if = 0;
-//		}
-//	}
-
-	return 0;
-}
-
-/*============================================================
- * wanpipe_listen_rcv
- *
- *	Wanpipe LISTEN socket bottom half handler.  This function
- *      is called by the WANPIPE device drivers to queue an
- *      incoming call into the socket listening queue.
- *      Once the packet is queued, the waiting accept() process
- *      is woken up.
- *
- *      During socket bind, this function is bounded into
- *      WANPIPE driver private.
- *
- *      IMPORTANT NOTE:
- *          The accept call() is waiting for an skb packet
- *          which contains a pointer to a device structure.
- *
- *          When we do a bind to a device structre, we
- *          bind a newly created socket into "chan->sk".  Thus,
- *          when accept receives the skb packet, it will know
- *          from which dev it came form, and in turn it will know
- *          the address of the new sock.
- *
- *  	NOTE: This function gets called from driver ISR.
- *===========================================================*/
-
-static int wanpipe_listen_rcv (struct sk_buff *skb,  struct sock *sk)
-{
-	wanpipe_opt *wp = wp_sk(sk), *newwp;
-	struct wan_sockaddr_ll *sll = (struct wan_sockaddr_ll*)skb->cb;
-	struct sock *newsk;
-	struct net_device *dev;
-	sdla_t *card;
-	mbox_cmd_t *mbox_ptr;
-	wanpipe_common_t *chan;
-
-	/* Find a free device, if none found, all svc's are busy
-	 */
-
-	card = (sdla_t*)wp->card;
-	if (!card){
-		printk(KERN_INFO "wansock: LISTEN ERROR, No Card\n");
-		return -ENODEV;
-	}
-
-	dev = wanpipe_find_free_dev(card);
-	if (!dev){
-		printk(KERN_INFO "wansock: LISTEN ERROR, No Free Device\n");
-		return -ENODEV;
-	}
-
-	chan=dev->priv;
-	chan->state = WANSOCK_CONNECTING;
-
-	/* Allocate a new sock, which accept will bind
-	 * and pass up to the user
-	 */
-	if ((newsk = wanpipe_make_new(sk)) == NULL){
-		release_device(dev);
-		return -ENOMEM;
-	}
-
-
-	/* Initialize the new sock structure
-	 */
-	newsk->sk_bound_dev_if = dev->ifindex;
-	newwp = wp_sk(newsk);
-	newwp->card = wp->card;
-
-	/* Insert the sock into the main wanpipe
-	 * sock list.
-	 */
-	atomic_inc(&wanpipe_socks_nr);
-
-	/* Allocate and fill in the new Mail Box. Then
-	 * bind the mail box to the sock. It will be
-	 * used by the ioctl call to read call information
-	 * and to execute commands.
-	 */
-	if ((mbox_ptr = kzalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL) {
-		wanpipe_kill_sock_irq (newsk);
-		release_device(dev);
-		return -ENOMEM;
-	}
-	memcpy(mbox_ptr,skb->data,skb->len);
-
-	/* Register the lcn on which incoming call came
-	 * from. Thus, if we have to clear it, we know
-	 * which lcn to clear
-	 */
-
-	newwp->lcn = mbox_ptr->cmd.lcn;
-	newwp->mbox = (void *)mbox_ptr;
-
-	DBG_PRINTK(KERN_INFO "NEWSOCK : Device %s, bind to lcn %i\n",
-			dev->name,mbox_ptr->cmd.lcn);
-
-	chan->lcn = mbox_ptr->cmd.lcn;
-	card->u.x.svc_to_dev_map[(chan->lcn%MAX_X25_LCN)] = dev;
-
-	sock_reset_flag(newsk, SOCK_ZAPPED);
-	newwp->num = htons(X25_PROT);
-
-	if (wanpipe_do_bind(newsk, dev, newwp->num)) {
-		wanpipe_kill_sock_irq (newsk);
-		release_device(dev);
-		return -EINVAL;
-	}
-	newsk->sk_state = WANSOCK_CONNECTING;
-
-
-	/* Fill in the standard sock address info */
-
-	sll->sll_family = AF_WANPIPE;
-	sll->sll_hatype = dev->type;
-	sll->sll_protocol = skb->protocol;
-	sll->sll_pkttype = skb->pkt_type;
-	sll->sll_ifindex = dev->ifindex;
-	sll->sll_halen = 0;
-
-	skb->dev = dev;
-	sk->sk_ack_backlog++;
-
-	/* We must do this manually, since the sock_queue_rcv_skb()
-	 * function sets the skb->dev to NULL.  However, we use
-	 * the dev field in the accept function.*/
-	if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
-	    (unsigned)sk->sk_rcvbuf) {
-
-		wanpipe_unlink_driver(newsk);
-		wanpipe_kill_sock_irq (newsk);
-		--sk->sk_ack_backlog;
-		return -ENOMEM;
-	}
-
-	skb_set_owner_r(skb, sk);
-	skb_queue_tail(&sk->sk_receive_queue, skb);
-	sk->sk_data_ready(sk, skb->len);
-
-	return 0;
-}
-
-
-
-/*============================================================
- * wanpipe_make_new
- *
- *	Create a new sock, and allocate a wanpipe private
- *      structure to it. Also, copy the important data
- *      from the original sock to the new sock.
- *
- *      This function is used by wanpipe_listen_rcv() listen
- *      bottom half handler.  A copy of the listening sock
- *      is created using this function.
- *
- *===========================================================*/
-
-static struct sock *wanpipe_make_new(struct sock *osk)
-{
-	struct sock *sk;
-
-	if (osk->sk_type != SOCK_RAW)
-		return NULL;
-
-	if ((sk = wanpipe_alloc_socket()) == NULL)
-		return NULL;
-
-	sk->sk_type	= osk->sk_type;
-	sk->sk_socket	= osk->sk_socket;
-	sk->sk_priority	= osk->sk_priority;
-	sk->sk_protocol	= osk->sk_protocol;
-	wp_sk(sk)->num	= wp_sk(osk)->num;
-	sk->sk_rcvbuf	= osk->sk_rcvbuf;
-	sk->sk_sndbuf	= osk->sk_sndbuf;
-	sk->sk_state	= WANSOCK_CONNECTING;
-	sk->sk_sleep	= osk->sk_sleep;
-
-	if (sock_flag(osk, SOCK_DBG))
-		sock_set_flag(sk, SOCK_DBG);
-
-	return sk;
-}
-
-/*
- * FIXME: wanpipe_opt has to include a sock in its definition and stop using
- * sk_protinfo, but this code is not even compilable now, so lets leave it for
- * later.
- */
-static struct proto wanpipe_proto = {
-	.name	  = "WANPIPE",
-	.owner	  = THIS_MODULE,
-	.obj_size = sizeof(struct sock),
-};
-
-/*============================================================
- * wanpipe_make_new
- *
- *	Allocate memory for the a new sock, and sock
- *      private data.
- *
- *	Increment the module use count.
- *
- *      This function is used by wanpipe_create() and
- *      wanpipe_make_new() functions.
- *
- *===========================================================*/
-
-static struct sock *wanpipe_alloc_socket(void)
-{
-	struct sock *sk;
-	struct wanpipe_opt *wan_opt;
-
-	if ((sk = sk_alloc(PF_WANPIPE, GFP_ATOMIC, &wanpipe_proto, 1)) == NULL)
-		return NULL;
-
-	if ((wan_opt = kzalloc(sizeof(struct wanpipe_opt), GFP_ATOMIC)) == NULL) {
-		sk_free(sk);
-		return NULL;
-	}
-
-	wp_sk(sk) = wan_opt;
-
-	/* Use timer to send data to the driver. This will act
-	 * as a BH handler for sendmsg functions */
-	init_timer(&wan_opt->tx_timer);
-	wan_opt->tx_timer.data	   = (unsigned long)sk;
-	wan_opt->tx_timer.function = wanpipe_delayed_transmit;
-
-	sock_init_data(NULL, sk);
-	return sk;
-}
-
-
-/*============================================================
- * wanpipe_sendmsg
- *
- *	This function implements a sendto() system call,
- *      for AF_WANPIPE socket family.
- *      During socket bind() sk->sk_bound_dev_if is initialized
- *      to a correct network device. This number is used
- *      to find a network device to which the packet should
- *      be passed to.
- *
- *      Each packet is queued into sk->sk_write_queue and
- *      delayed transmit bottom half handler is marked for
- *      execution.
- *
- *      A socket must be in WANSOCK_CONNECTED state before
- *      a packet is queued into sk->sk_write_queue.
- *===========================================================*/
-
-static int wanpipe_sendmsg(struct kiocb *iocb, struct socket *sock,
-			   struct msghdr *msg, int len)
-{
-	wanpipe_opt *wp;
-	struct sock *sk = sock->sk;
-	struct wan_sockaddr_ll *saddr=(struct wan_sockaddr_ll *)msg->msg_name;
-	struct sk_buff *skb;
-	struct net_device *dev;
-	unsigned short proto;
-	unsigned char *addr;
-	int ifindex, err, reserve = 0;
-
-
-	if (!sock_flag(sk, SOCK_ZAPPED))
-		return -ENETDOWN;
-
-	if (sk->sk_state != WANSOCK_CONNECTED)
-		return -ENOTCONN;
-
-	if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
-		return(-EINVAL);
-
-	/* it was <=, now one can send
-	 * zero length packets */
-	if (len < sizeof(x25api_hdr_t))
-		return -EINVAL;
-
-	wp = wp_sk(sk);
-
-	if (saddr == NULL) {
-		ifindex	= sk->sk_bound_dev_if;
-		proto	= wp->num;
-		addr	= NULL;
-
-	}else{
-		if (msg->msg_namelen < sizeof(struct wan_sockaddr_ll)){
-			return -EINVAL;
-		}
-
-		ifindex = sk->sk_bound_dev_if;
-		proto	= saddr->sll_protocol;
-		addr	= saddr->sll_addr;
-	}
-
-	dev = dev_get_by_index(ifindex);
-	if (dev == NULL){
-		printk(KERN_INFO "wansock: Send failed, dev index: %i\n",ifindex);
-		return -ENXIO;
-	}
-	dev_put(dev);
-
-	if (sock->type == SOCK_RAW)
-		reserve = dev->hard_header_len;
-
-	if (len > dev->mtu+reserve){
-		return -EMSGSIZE;
-	}
-
-	skb = sock_alloc_send_skb(sk, len + LL_RESERVED_SPACE(dev),
-				msg->msg_flags & MSG_DONTWAIT, &err);
-
-	if (skb==NULL){
-		goto out_unlock;
-	}
-
-	skb_reserve(skb, LL_RESERVED_SPACE(dev));
-	skb->nh.raw = skb->data;
-
-	/* Returns -EFAULT on error */
-	err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
-	if (err){
-		goto out_free;
-	}
-
-	if (dev->hard_header) {
-		int res;
-		err = -EINVAL;
-		res = dev->hard_header(skb, dev, ntohs(proto), addr, NULL, len);
-		if (res<0){
-			goto out_free;
-		}
-	}
-
-	skb->protocol = proto;
-	skb->dev = dev;
-	skb->priority = sk->sk_priority;
-	skb->pkt_type = WAN_PACKET_DATA;
-
-	err = -ENETDOWN;
-	if (!(dev->flags & IFF_UP))
-		goto out_free;
-
-	if (atomic_read(&sk->sk_wmem_alloc) + skb->truesize >
-	    (unsigned int)sk->sk_sndbuf){
-		kfree_skb(skb);
-		return -ENOBUFS;
-	}
-
-	skb_queue_tail(&sk->sk_write_queue,skb);
-	atomic_inc(&wp->packet_sent);
-
-	if (!(test_and_set_bit(0, &wp->timer)))
-		mod_timer(&wp->tx_timer, jiffies + 1);
-
-	return(len);
-
-out_free:
-	kfree_skb(skb);
-out_unlock:
-	return err;
-}
-
-/*============================================================
- * wanpipe_delayed_tarnsmit
- *
- *	Transmit bottom half handler. It dequeues packets
- *      from sk->sk_write_queue and passes them to the
- *      driver.  If the driver is busy, the packet is
- *      re-enqueued.
- *
- *      Packet Sent counter is decremented on successful
- *      transmission.
- *===========================================================*/
-
-
-static void wanpipe_delayed_transmit (unsigned long data)
-{
-	struct sock *sk=(struct sock *)data;
-	struct sk_buff *skb;
-	wanpipe_opt *wp = wp_sk(sk);
-	struct net_device *dev = wp->dev;
-	sdla_t *card = (sdla_t*)wp->card;
-
-	if (!card || !dev){
-		clear_bit(0, &wp->timer);
-		DBG_PRINTK(KERN_INFO "wansock: Transmit delay, no dev or card\n");
-		return;
-	}
-
-	if (sk->sk_state != WANSOCK_CONNECTED || !sock_flag(sk, SOCK_ZAPPED)) {
-		clear_bit(0, &wp->timer);
-		DBG_PRINTK(KERN_INFO "wansock: Tx Timer, State not CONNECTED\n");
-		return;
-	}
-
-	/* If driver is executing command, we must offload
-	 * the board by not sending data. Otherwise a
-	 * pending command will never get a free buffer
-	 * to execute */
-	if (atomic_read(&card->u.x.command_busy)){
-		wp->tx_timer.expires = jiffies + SLOW_BACKOFF;
-		add_timer(&wp->tx_timer);
-		DBG_PRINTK(KERN_INFO "wansock: Tx Timer, command bys BACKOFF\n");
-		return;
-	}
-
-
-	if (test_and_set_bit(0,&wanpipe_tx_critical)){
-		printk(KERN_INFO "WanSock: Tx timer critical %s\n",dev->name);
-		wp->tx_timer.expires = jiffies + SLOW_BACKOFF;
-		add_timer(&wp->tx_timer);
-		return;
-	}
-
-	/* Check for a packet in the fifo and send */
-	if ((skb = skb_dequeue(&sk->sk_write_queue)) != NULL){
-
-		if (dev->hard_start_xmit(skb, dev) != 0){
-
-			/* Driver failed to transmit, re-enqueue
-			 * the packet and retry again later */
-			skb_queue_head(&sk->sk_write_queue,skb);
-			clear_bit(0,&wanpipe_tx_critical);
-			return;
-		}else{
-
-			/* Packet Sent successful. Check for more packets
-			 * if more packets, re-trigger the transmit routine
-			 * other wise exit
-			 */
-			atomic_dec(&wp->packet_sent);
-
-			if (skb_peek(&sk->sk_write_queue) == NULL) {
-				/* If there is nothing to send, kick
-				 * the poll routine, which will trigger
-				 * the application to send more data */
-				sk->sk_data_ready(sk, 0);
-				clear_bit(0, &wp->timer);
-			}else{
-				/* Reschedule as fast as possible */
-				wp->tx_timer.expires = jiffies + 1;
-				add_timer(&wp->tx_timer);
-			}
-		}
-	}
-	clear_bit(0,&wanpipe_tx_critical);
-}
-
-/*============================================================
- * execute_command
- *
- *	Execute x25api commands.  The atomic variable
- *      chan->command is used to indicate to the driver that
- *      command is pending for execution.  The acutal command
- *      structure is placed into a sock mbox structure
- *      (wp_sk(sk)->mbox).
- *
- *      The sock private structure, mbox is
- *      used as shared memory between sock and the driver.
- *      Driver uses the sock mbox to execute the command
- *      and return the result.
- *
- *      For all command except PLACE CALL, the function
- *      waits for the result.  PLACE CALL can be ether
- *      blocking or nonblocking. The user sets this option
- *      via ioctl call.
- *===========================================================*/
-
-
-static int execute_command(struct sock *sk,  unsigned char cmd, unsigned int flags)
-{
-	wanpipe_opt *wp = wp_sk(sk);
-	struct net_device *dev;
-	wanpipe_common_t *chan=NULL;
-	int err=0;
-	DECLARE_WAITQUEUE(wait, current);
-
-	dev = dev_get_by_index(sk->sk_bound_dev_if);
-	if (dev == NULL){
-		printk(KERN_INFO "wansock: Exec failed no dev %i\n",
-			sk->sk_bound_dev_if);
-		return -ENODEV;
-	}
-	dev_put(dev);
-
-	if ((chan=dev->priv) == NULL){
-		printk(KERN_INFO "wansock: Exec cmd failed no priv area\n");
-		return -ENODEV;
-	}
-
-	if (atomic_read(&chan->command)){
-		printk(KERN_INFO "wansock: ERROR: Command already running %x, %s\n",
-			atomic_read(&chan->command),dev->name);
-		return -EINVAL;
-	}
-
-	if (!wp->mbox) {
-		printk(KERN_INFO "wansock: In execute without MBOX\n");
-		return -EINVAL;
-	}
-
-	((mbox_cmd_t*)wp->mbox)->cmd.command = cmd;
-	((mbox_cmd_t*)wp->mbox)->cmd.lcn     = wp->lcn;
-	((mbox_cmd_t*)wp->mbox)->cmd.result  = 0x7F;
-
-
-	if (flags & O_NONBLOCK){
-		cmd |= 0x80;
-		atomic_set(&chan->command, cmd);
-	}else{
-		atomic_set(&chan->command, cmd);
-	}
-
-	add_wait_queue(sk->sk_sleep,&wait);
-	current->state = TASK_INTERRUPTIBLE;
-	for (;;){
-		if (((mbox_cmd_t*)wp->mbox)->cmd.result != 0x7F) {
-			err = 0;
-			break;
-		}
-		if (signal_pending(current)) {
-			err = -ERESTARTSYS;
-			break;
-		}
-		schedule();
-	}
-	current->state = TASK_RUNNING;
-	remove_wait_queue(sk->sk_sleep,&wait);
-
-	return err;
-}
-
-/*============================================================
- * wanpipe_destroy_timer
- *
- *	Used by wanpipe_release, to delay release of
- *      the socket.
- *===========================================================*/
-
-static void wanpipe_destroy_timer(unsigned long data)
-{
-	struct sock *sk=(struct sock *)data;
-	wanpipe_opt *wp = wp_sk(sk);
-
-	if ((!atomic_read(&sk->sk_wmem_alloc) &&
-	     !atomic_read(&sk->sk_rmem_alloc)) ||
-	    (++wp->force == 5)) {
-
-		if (atomic_read(&sk->sk_wmem_alloc) ||
-		    atomic_read(&sk->sk_rmem_alloc))
-			printk(KERN_INFO "wansock: Warning, Packet Discarded due to sock shutdown!\n");
-
-		kfree(wp);
-		wp_sk(sk) = NULL;
-
-		if (atomic_read(&sk->sk_refcnt) != 1) {
-			atomic_set(&sk->sk_refcnt, 1);
-			DBG_PRINTK(KERN_INFO "wansock: Error, wrong reference count: %i ! :delay.\n",
-					atomic_read(&sk->sk_refcnt));
-		}
-		sock_put(sk);
-		atomic_dec(&wanpipe_socks_nr);
-		return;
-	}
-
-	sk->sk_timer.expires = jiffies + 5 * HZ;
-	add_timer(&sk->sk_timer);
-	printk(KERN_INFO "wansock: packet sk destroy delayed\n");
-}
-
-/*============================================================
- * wanpipe_unlink_driver
- *
- * 	When the socket is released, this function is
- *      used to remove links that bind the sock and the
- *      driver together.
- *===========================================================*/
-static void wanpipe_unlink_driver (struct sock *sk)
-{
-	struct net_device *dev;
-	wanpipe_common_t *chan=NULL;
-
-	sock_reset_flag(sk, SOCK_ZAPPED);
-	sk->sk_state = WANSOCK_DISCONNECTED;
-	wp_sk(sk)->dev = NULL;
-
-	dev = dev_get_by_index(sk->sk_bound_dev_if);
-	if (!dev){
-		printk(KERN_INFO "wansock: No dev on release\n");
-		return;
-	}
-	dev_put(dev);
-
-	if ((chan = dev->priv) == NULL){
-		printk(KERN_INFO "wansock: No Priv Area on release\n");
-		return;
-	}
-
-	set_bit(0,&chan->common_critical);
-	chan->sk=NULL;
-	chan->func=NULL;
-	chan->mbox=NULL;
-	chan->tx_timer=NULL;
-	clear_bit(0,&chan->common_critical);
-	release_device(dev);
-
-	return;
-}
-
-/*============================================================
- * wanpipe_link_driver
- *
- * 	Upon successful bind(), sock is linked to a driver
- *      by binding in the wanpipe_rcv() bottom half handler
- *      to the driver function pointer, as well as sock and
- *      sock mailbox addresses.  This way driver can pass
- *      data up the socket.
- *===========================================================*/
-
-static void wanpipe_link_driver(struct net_device *dev, struct sock *sk)
-{
-	wanpipe_opt *wp = wp_sk(sk);
-	wanpipe_common_t *chan = dev->priv;
-	if (!chan)
-		return;
-	set_bit(0,&chan->common_critical);
-	chan->sk=sk;
-	chan->func=wanpipe_rcv;
-	chan->mbox = wp->mbox;
-	chan->tx_timer = &wp->tx_timer;
-	wp->dev = dev;
-	sock_set_flag(sk, SOCK_ZAPPED);
-	clear_bit(0,&chan->common_critical);
-}
-
-
-/*============================================================
- * release_device
- *
- *   	During sock release, clear a critical bit, which
- *      marks the device a being taken.
- *===========================================================*/
-
-
-static void release_device(struct net_device *dev)
-{
-	wanpipe_common_t *chan=dev->priv;
-	clear_bit(0,(void*)&chan->rw_bind);
-}
-
-/*============================================================
- * wanpipe_release
- *
- *	Close a PACKET socket. This is fairly simple. We
- *      immediately go to 'closed' state and remove our
- *      protocol entry in the device list.
- *===========================================================*/
-
-static int wanpipe_release(struct socket *sock)
-{
-	wanpipe_opt *wp;
-	struct sock *sk = sock->sk;
-
-	if (!sk)
-		return 0;
-
-	wp = wp_sk(sk);
-	check_write_queue(sk);
-
-	/* Kill the tx timer, if we don't kill it now, the timer
-	 * will run after we kill the sock.  Timer code will
-	 * try to access the sock which has been killed and cause
-	 * kernel panic */
-
-	del_timer(&wp->tx_timer);
-
-	/*
-	 *	Unhook packet receive handler.
-	 */
-
-	if (wp->num == htons(X25_PROT) &&
-	    sk->sk_state != WANSOCK_DISCONNECTED && sock_flag(sk, SOCK_ZAPPED)) {
-		struct net_device *dev = dev_get_by_index(sk->sk_bound_dev_if);
-		wanpipe_common_t *chan;
-		if (dev){
-			chan=dev->priv;
-			atomic_set(&chan->disconnect,1);
-			DBG_PRINTK(KERN_INFO "wansock: Sending Clear Indication %i\n",
-					sk->sk_state);
-			dev_put(dev);
-		}
-	}
-
-	set_bit(1,&wanpipe_tx_critical);
-	write_lock(&wanpipe_sklist_lock);
-	sk_del_node_init(sk);
-	write_unlock(&wanpipe_sklist_lock);
-	clear_bit(1,&wanpipe_tx_critical);
-
-
-
-	release_driver(sk);
-
-
-	/*
-	 *	Now the socket is dead. No more input will appear.
-	 */
-
-	sk->sk_state_change(sk);	/* It is useless. Just for sanity. */
-
-	sock->sk = NULL;
-	sk->sk_socket = NULL;
-	sock_set_flag(sk, SOCK_DEAD);
-
-	/* Purge queues */
-	skb_queue_purge(&sk->sk_receive_queue);
-	skb_queue_purge(&sk->sk_write_queue);
-	skb_queue_purge(&sk->sk_error_queue);
-
-	if (atomic_read(&sk->sk_rmem_alloc) ||
-	    atomic_read(&sk->sk_wmem_alloc)) {
-		del_timer(&sk->sk_timer);
-		printk(KERN_INFO "wansock: Killing in Timer R %i , W %i\n",
-			atomic_read(&sk->sk_rmem_alloc),
-			atomic_read(&sk->sk_wmem_alloc));
-		sk->sk_timer.data	= (unsigned long)sk;
-		sk->sk_timer.expires	= jiffies + HZ;
-		sk->sk_timer.function	= wanpipe_destroy_timer;
-		add_timer(&sk->sk_timer);
-		return 0;
-	}
-
-	kfree(wp);
-	wp_sk(sk) = NULL;
-
-	if (atomic_read(&sk->sk_refcnt) != 1) {
-		DBG_PRINTK(KERN_INFO "wansock: Error, wrong reference count: %i !:release.\n",
-					atomic_read(&sk->sk_refcnt));
-		atomic_set(&sk->sk_refcnt, 1);
-	}
-	sock_put(sk);
-	atomic_dec(&wanpipe_socks_nr);
-	return 0;
-}
-
-/*============================================================
- * check_write_queue
- *
- *  	During sock shutdown, if the sock state is
- *      WANSOCK_CONNECTED and there is transmit data
- *      pending. Wait until data is released
- *      before proceeding.
- *===========================================================*/
-
-static void check_write_queue(struct sock *sk)
-{
-
-	if (sk->sk_state != WANSOCK_CONNECTED)
-		return;
-
-	if (!atomic_read(&sk->sk_wmem_alloc))
-		return;
-
-	printk(KERN_INFO "wansock: MAJOR ERROR, Data lost on sock release !!!\n");
-
-}
-
-/*============================================================
- * release_driver
- *
- *	This function is called during sock shutdown, to
- *      release any resources and links that bind the sock
- *      to the driver.  It also changes the state of the
- *      sock to WANSOCK_DISCONNECTED
- *===========================================================*/
-
-static void release_driver(struct sock *sk)
-{
-	wanpipe_opt *wp;
-	struct sk_buff *skb=NULL;
-	struct sock *deadsk=NULL;
-
-	if (sk->sk_state == WANSOCK_LISTEN ||
-	    sk->sk_state == WANSOCK_BIND_LISTEN) {
-		while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
-			if ((deadsk = get_newsk_from_skb(skb))){
-				DBG_PRINTK (KERN_INFO "wansock: RELEASE: FOUND DEAD SOCK\n");
-				sock_set_flag(deadsk, SOCK_DEAD);
-				start_cleanup_timer(deadsk);
-			}
-			kfree_skb(skb);
-		}
-		if (sock_flag(sk, SOCK_ZAPPED))
-			wanpipe_unlink_card(sk);
-	}else{
-		if (sock_flag(sk, SOCK_ZAPPED))
-			wanpipe_unlink_driver(sk);
-	}
-	sk->sk_state	    = WANSOCK_DISCONNECTED;
-	sk->sk_bound_dev_if = 0;
-	sock_reset_flag(sk, SOCK_ZAPPED);
-	wp = wp_sk(sk);
-
-	if (wp) {
-		kfree(wp->mbox);
-		wp->mbox = NULL;
-	}
-}
-
-/*============================================================
- *  start_cleanup_timer
- *
- *  	If new incoming call's are pending but the socket
- *      is being released, start the timer which will
- *      envoke the kill routines for pending socks.
- *===========================================================*/
-
-
-static void start_cleanup_timer (struct sock *sk)
-{
-	del_timer(&sk->sk_timer);
-	sk->sk_timer.data	= (unsigned long)sk;
-	sk->sk_timer.expires	= jiffies + HZ;
-	sk->sk_timer.function	= wanpipe_kill_sock_timer;
-	add_timer(&sk->sk_timer);
-}
-
-
-/*============================================================
- *  wanpipe_kill_sock
- *
- *	This is a function which performs actual killing
- *      of the sock.  It releases socket resources,
- *      and unlinks the sock from the driver.
- *===========================================================*/
-
-static void wanpipe_kill_sock_timer (unsigned long data)
-{
-
-	struct sock *sk = (struct sock *)data;
-	struct sock **skp;
-
-	if (!sk)
-		return;
-
-	/* This function can be called from interrupt. We must use
-	 * appropriate locks */
-
-	if (test_bit(1,&wanpipe_tx_critical)){
-		sk->sk_timer.expires = jiffies + 10;
-		add_timer(&sk->sk_timer);
-		return;
-	}
-
-	write_lock(&wanpipe_sklist_lock);
-	sk_del_node_init(sk);
-	write_unlock(&wanpipe_sklist_lock);
-
-
-	if (wp_sk(sk)->num == htons(X25_PROT) &&
-	    sk->sk_state != WANSOCK_DISCONNECTED) {
-		struct net_device *dev = dev_get_by_index(sk->sk_bound_dev_if);
-		wanpipe_common_t *chan;
-		if (dev){
-			chan=dev->priv;
-			atomic_set(&chan->disconnect,1);
-			dev_put(dev);
-		}
-	}
-
-	release_driver(sk);
-
-	sk->sk_socket = NULL;
-
-	/* Purge queues */
-	skb_queue_purge(&sk->sk_receive_queue);
-	skb_queue_purge(&sk->sk_write_queue);
-	skb_queue_purge(&sk->sk_error_queue);
-
-	if (atomic_read(&sk->sk_rmem_alloc) ||
-	    atomic_read(&sk->sk_wmem_alloc)) {
-		del_timer(&sk->sk_timer);
-		printk(KERN_INFO "wansock: Killing SOCK in Timer\n");
-		sk->sk_timer.data	= (unsigned long)sk;
-		sk->sk_timer.expires	= jiffies + HZ;
-		sk->sk_timer.function	= wanpipe_destroy_timer;
-		add_timer(&sk->sk_timer);
-		return;
-	}
-
-	kfree(wp_sk(sk));
-	wp_sk(sk) = NULL;
-
-	if (atomic_read(&sk->sk_refcnt) != 1) {
-		atomic_set(&sk->sk_refcnt, 1);
-		DBG_PRINTK(KERN_INFO "wansock: Error, wrong reference count: %i ! :timer.\n",
-					atomic_read(&sk->sk_refcnt));
-	}
-	sock_put(sk);
-	atomic_dec(&wanpipe_socks_nr);
-	return;
-}
-
-static void wanpipe_kill_sock_accept (struct sock *sk)
-{
-
-	struct sock **skp;
-
-	if (!sk)
-		return;
-
-	/* This function can be called from interrupt. We must use
-	 * appropriate locks */
-
-	write_lock(&wanpipe_sklist_lock);
-	sk_del_node_init(sk);
-	write_unlock(&wanpipe_sklist_lock);
-
-	sk->sk_socket = NULL;
-
-
-	kfree(wp_sk(sk));
-	wp_sk(sk) = NULL;
-
-	if (atomic_read(&sk->sk_refcnt) != 1) {
-		atomic_set(&sk->sk_refcnt, 1);
-		DBG_PRINTK(KERN_INFO "wansock: Error, wrong reference count: %i ! :timer.\n",
-					atomic_read(&sk->sk_refcnt));
-	}
-	sock_put(sk);
-	atomic_dec(&wanpipe_socks_nr);
-	return;
-}
-
-
-static void wanpipe_kill_sock_irq (struct sock *sk)
-{
-
-	if (!sk)
-		return;
-
-	sk->sk_socket = NULL;
-
-	kfree(wp_sk(sk));
-	wp_sk(sk) = NULL;
-
-	if (atomic_read(&sk->sk_refcnt) != 1) {
-		atomic_set(&sk->sk_refcnt, 1);
-		DBG_PRINTK(KERN_INFO "wansock: Error, wrong reference count: %i !:listen.\n",
-					atomic_read(&sk->sk_refcnt));
-	}
-	sock_put(sk);
-	atomic_dec(&wanpipe_socks_nr);
-}
-
-
-/*============================================================
- *  wanpipe_do_bind
- *
- * 	Bottom half of the binding system call.
- *      Once the wanpipe_bind() function checks  the
- *      legality of the call, this function binds the
- *      sock to the driver.
- *===========================================================*/
-
-static int wanpipe_do_bind(struct sock *sk, struct net_device *dev,
-			   int protocol)
-{
-	wanpipe_opt *wp = wp_sk(sk);
-	wanpipe_common_t *chan=NULL;
-	int err=0;
-
-	if (sock_flag(sk, SOCK_ZAPPED)) {
-		err = -EALREADY;
-		goto bind_unlock_exit;
-	}
-
-	wp->num = protocol;
-
-	if (protocol == 0){
-		release_device(dev);
-		err = -EINVAL;
-		goto bind_unlock_exit;
-	}
-
-	if (dev) {
-		if (dev->flags&IFF_UP) {
-			chan=dev->priv;
-			sk->sk_state = chan->state;
-
-			if (wp->num == htons(X25_PROT) &&
-			    sk->sk_state != WANSOCK_DISCONNECTED &&
-			    sk->sk_state != WANSOCK_CONNECTING) {
-				DBG_PRINTK(KERN_INFO
-					"wansock: Binding to Device not DISCONNECTED %i\n",
-						sk->sk_state);
-				release_device(dev);
-				err = -EAGAIN;
-				goto bind_unlock_exit;
-			}
-
-			wanpipe_link_driver(dev,sk);
-			sk->sk_bound_dev_if = dev->ifindex;
-
-			/* X25 Specific option */
-			if (wp->num == htons(X25_PROT))
-				wp_sk(sk)->svc = chan->svc;
-
-		} else {
-			sk->sk_err = ENETDOWN;
-			sk->sk_error_report(sk);
-			release_device(dev);
-			err = -EINVAL;
-		}
-	} else {
-		err = -ENODEV;
-	}
-bind_unlock_exit:
-	/* FIXME where is this lock */
-
-	return err;
-}
-
-/*============================================================
- *  wanpipe_bind
- *
- *      BIND() System call, which is bound to the AF_WANPIPE
- *      operations structure.  It checks for correct wanpipe
- *      card name, and cross references interface names with
- *      the card names.  Thus, interface name must belong to
- *      the actual card.
- *===========================================================*/
-
-
-static int wanpipe_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
-{
-	struct wan_sockaddr_ll *sll = (struct wan_sockaddr_ll*)uaddr;
-	struct sock *sk=sock->sk;
-	wanpipe_opt *wp = wp_sk(sk);
-	struct net_device *dev = NULL;
-	sdla_t *card=NULL;
-	char name[15];
-
-	/*
-	 *	Check legality
-	 */
-
-	if (addr_len < sizeof(struct wan_sockaddr_ll)){
-		printk(KERN_INFO "wansock: Address length error\n");
-		return -EINVAL;
-	}
-	if (sll->sll_family != AF_WANPIPE){
-		printk(KERN_INFO "wansock: Illegal family name specified.\n");
-		return -EINVAL;
-	}
-
-	card = wanpipe_find_card (sll->sll_card);
-	if (!card){
-		printk(KERN_INFO "wansock: Wanpipe card not found: %s\n",sll->sll_card);
-		return -ENODEV;
-	}else{
-		wp_sk(sk)->card = (void *)card;
-	}
-
-	if (!strcmp(sll->sll_device,"svc_listen")){
-
-		/* Bind a sock to a card structure for listening
-		 */
-		int err=0;
-
-		/* This is x25 specific area if protocol doesn't
-		 * match, return error */
-		if (sll->sll_protocol != htons(X25_PROT))
-			return -EINVAL;
-
-		err= wanpipe_link_card (sk);
-		if (err < 0)
-			return err;
-
-		if (sll->sll_protocol)
-			wp->num = sll->sll_protocol;
-		sk->sk_state = WANSOCK_BIND_LISTEN;
-		return 0;
-
-	}else if (!strcmp(sll->sll_device,"svc_connect")){
-
-		/* This is x25 specific area if protocol doesn't
-		 * match, return error */
-		if (sll->sll_protocol != htons(X25_PROT))
-			return -EINVAL;
-
-		/* Find a free device
-		 */
-		dev = wanpipe_find_free_dev(card);
-		if (dev == NULL){
-			DBG_PRINTK(KERN_INFO "wansock: No free network devices for card %s\n",
-				card->devname);
-			return -EINVAL;
-		}
-	}else{
-		/* Bind a socket to a interface name
-		 * This is used by PVC mostly
-		 */
-		strlcpy(name,sll->sll_device,sizeof(name));
-		dev = dev_get_by_name(name);
-		if (dev == NULL){
-			printk(KERN_INFO "wansock: Failed to get Dev from name: %s,\n",
-					name);
-			return -ENODEV;
-		}
-
-		dev_put(dev);
-
-		if (check_dev(dev, card)){
-			printk(KERN_INFO "wansock: Device %s, doesn't belong to card %s\n",
-				dev->name, card->devname);
-			return -EINVAL;
-		}
-		if (get_atomic_device (dev))
-			return -EINVAL;
-	}
-
-	return wanpipe_do_bind(sk, dev, sll->sll_protocol ? : wp->num);
-}
-
-/*============================================================
- * get_atomic_device
- *
- *	Sets a bit atomically which indicates that
- *      the interface is taken. This avoids race conditions.
- *===========================================================*/
-
-
-static inline int get_atomic_device(struct net_device *dev)
-{
-	wanpipe_common_t *chan = dev->priv;
-	if (!test_and_set_bit(0,(void *)&chan->rw_bind)){
-		return 0;
-	}
-	return 1;
-}
-
-/*============================================================
- * check_dev
- *
- *  	Check that device name belongs to a particular card.
- *===========================================================*/
-
-static int check_dev(struct net_device *dev, sdla_t *card)
-{
-	struct net_device* tmp_dev;
-
-	for (tmp_dev = card->wandev.dev; tmp_dev;
-	     tmp_dev = *((struct net_device **)tmp_dev->priv)) {
-		if (tmp_dev->ifindex == dev->ifindex){
-			return 0;
-		}
-	}
-	return 1;
-}
-
-/*============================================================
- *  wanpipe_find_free_dev
- *
- *	Find a free network interface. If found set atomic
- *      bit indicating that the interface is taken.
- *      X25API Specific.
- *===========================================================*/
-
-struct net_device *wanpipe_find_free_dev(sdla_t *card)
-{
-	struct net_device* dev;
-	volatile wanpipe_common_t *chan;
-
-	if (test_and_set_bit(0,&find_free_critical)){
-		printk(KERN_INFO "CRITICAL in Find Free\n");
-	}
-
-	for (dev = card->wandev.dev; dev;
-	     dev = *((struct net_device **)dev->priv)) {
-		chan = dev->priv;
-		if (!chan)
-			continue;
-		if (chan->usedby == API && chan->svc){
-			if (!get_atomic_device (dev)){
-				if (chan->state != WANSOCK_DISCONNECTED){
-					release_device(dev);
-				}else{
-					clear_bit(0,&find_free_critical);
-					return dev;
-				}
-			}
-		}
-	}
-	clear_bit(0,&find_free_critical);
-	return NULL;
-}
-
-/*============================================================
- *  wanpipe_create
- *
- * 	SOCKET() System call.  It allocates a sock structure
- *      and adds the socket to the wanpipe_sk_list.
- *      Crates AF_WANPIPE socket.
- *===========================================================*/
-
-static int wanpipe_create(struct socket *sock, int protocol)
-{
-	struct sock *sk;
-
-	//FIXME: This checks for root user, SECURITY ?
-	//if (!capable(CAP_NET_RAW))
-	//	return -EPERM;
-
-	if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
-		return -ESOCKTNOSUPPORT;
-
-	sock->state = SS_UNCONNECTED;
-
-	if ((sk = wanpipe_alloc_socket()) == NULL)
-		return -ENOBUFS;
-
-	sk->sk_reuse = 1;
-	sock->ops = &wanpipe_ops;
-	sock_init_data(sock,sk);
-
-	sock_reset_flag(sk, SOCK_ZAPPED);
-	sk->sk_family	    = PF_WANPIPE;
-	wp_sk(sk)->num	    = protocol;
-	sk->sk_state	    = WANSOCK_DISCONNECTED;
-	sk->sk_ack_backlog  = 0;
-	sk->sk_bound_dev_if = 0;
-
-	atomic_inc(&wanpipe_socks_nr);
-
-	/* We must disable interrupts because the ISR
-	 * can also change the list */
-	set_bit(1,&wanpipe_tx_critical);
-	write_lock(&wanpipe_sklist_lock);
-	sk_add_node(sk, &wanpipe_sklist);
-	write_unlock(&wanpipe_sklist_lock);
-	clear_bit(1,&wanpipe_tx_critical);
-
-	return(0);
-}
-
-
-/*============================================================
- *  wanpipe_recvmsg
- *
- *	Pull a packet from our receive queue and hand it
- *      to the user. If necessary we block.
- *===========================================================*/
-
-static int wanpipe_recvmsg(struct kiocb *iocb, struct socket *sock,
-			   struct msghdr *msg, int len, int flags)
-{
-	struct sock *sk = sock->sk;
-	struct sk_buff *skb;
-	int copied, err=-ENOBUFS;
-
-
-	/*
-	 *	If the address length field is there to be filled in, we fill
-	 *	it in now.
-	 */
-
-	msg->msg_namelen = sizeof(struct wan_sockaddr_ll);
-
-	/*
-	 *	Call the generic datagram receiver. This handles all sorts
-	 *	of horrible races and re-entrancy so we can forget about it
-	 *	in the protocol layers.
-	 *
-	 *	Now it will return ENETDOWN, if device have just gone down,
-	 *	but then it will block.
-	 */
-
-	if (flags & MSG_OOB){
-		skb = skb_dequeue(&sk->sk_error_queue);
-	}else{
-		skb=skb_recv_datagram(sk,flags,1,&err);
-	}
-	/*
-	 *	An error occurred so return it. Because skb_recv_datagram()
-	 *	handles the blocking we don't see and worry about blocking
-	 *	retries.
-	 */
-
-	if(skb==NULL)
-		goto out;
-
-	/*
-	 *	You lose any data beyond the buffer you gave. If it worries a
-	 *	user program they can ask the device for its MTU anyway.
-	 */
-
-	copied = skb->len;
-	if (copied > len)
-	{
-		copied=len;
-		msg->msg_flags|=MSG_TRUNC;
-	}
-
-	wanpipe_wakeup_driver(sk);
-
-	/* We can't use skb_copy_datagram here */
-	err = memcpy_toiovec(msg->msg_iov, skb->data, copied);
-	if (err)
-		goto out_free;
-
-	sock_recv_timestamp(msg, sk, skb);
-
-	if (msg->msg_name)
-		memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
-
-	/*
-	 *	Free or return the buffer as appropriate. Again this
-	 *	hides all the races and re-entrancy issues from us.
-	 */
-	err = (flags&MSG_TRUNC) ? skb->len : copied;
-
-out_free:
-	skb_free_datagram(sk, skb);
-out:
-	return err;
-}
-
-
-/*============================================================
- *  wanpipe_wakeup_driver
- *
- * 	If socket receive buffer is full and driver cannot
- *      pass data up the sock, it sets a packet_block flag.
- *      This function check that flag and if sock receive
- *      queue has room it kicks the driver BH handler.
- *
- * 	This way, driver doesn't have to poll the sock
- *      receive queue.
- *===========================================================*/
-
-static void wanpipe_wakeup_driver(struct sock *sk)
-{
-	struct net_device *dev = NULL;
-	wanpipe_common_t *chan=NULL;
-
-	dev = dev_get_by_index(sk->sk_bound_dev_if);
-	if (!dev)
-		return;
-
-	dev_put(dev);
-
-	if ((chan = dev->priv) == NULL)
-		return;
-
-	if (atomic_read(&chan->receive_block)){
-		if (atomic_read(&sk->sk_rmem_alloc) <
-		    ((unsigned)sk->sk_rcvbuf * 0.9)) {
-			printk(KERN_INFO "wansock: Queuing task for wanpipe\n");
-			atomic_set(&chan->receive_block,0);
-			wanpipe_queue_tq(&chan->wanpipe_task);
-			wanpipe_mark_bh();
-		}
-	}
-}
-
-/*============================================================
- *  wanpipe_getname
- *
- * 	I don't know what to do with this yet.
- *      User can use this function to get sock address
- *      information. Not very useful for Sangoma's purposes.
- *===========================================================*/
-
-
-static int wanpipe_getname(struct socket *sock, struct sockaddr *uaddr,
-			  int *uaddr_len, int peer)
-{
-	struct net_device *dev;
-	struct sock *sk = sock->sk;
-	struct wan_sockaddr_ll *sll = (struct wan_sockaddr_ll*)uaddr;
-
-	sll->sll_family = AF_WANPIPE;
-	sll->sll_ifindex = sk->sk_bound_dev_if;
-	sll->sll_protocol = wp_sk(sk)->num;
-	dev = dev_get_by_index(sk->sk_bound_dev_if);
-	if (dev) {
-		sll->sll_hatype = dev->type;
-		sll->sll_halen = dev->addr_len;
-		memcpy(sll->sll_addr, dev->dev_addr, dev->addr_len);
-	} else {
-		sll->sll_hatype = 0;	/* Bad: we have no ARPHRD_UNSPEC */
-		sll->sll_halen = 0;
-	}
-	*uaddr_len = sizeof(*sll);
-
-	dev_put(dev);
-
-	return 0;
-}
-
-/*============================================================
- *  wanpipe_notifier
- *
- *	If driver turns off network interface, this function
- *      will be envoked. Currently I treate it as a
- *      call disconnect. More thought should go into this
- *      function.
- *
- * FIXME: More thought should go into this function.
- *
- *===========================================================*/
-
-static int wanpipe_notifier(struct notifier_block *this, unsigned long msg, void *data)
-{
-	struct sock *sk;
-	hlist_node *node;
-	struct net_device *dev = (struct net_device *)data;
-
-	sk_for_each(sk, node, &wanpipe_sklist) {
-		struct wanpipe_opt *po = wp_sk(sk);
-
-		if (!po)
-			continue;
-		if (dev == NULL)
-			continue;
-
-		switch (msg) {
-		case NETDEV_DOWN:
-		case NETDEV_UNREGISTER:
-			if (dev->ifindex == sk->sk_bound_dev_if) {
-				printk(KERN_INFO "wansock: Device down %s\n",dev->name);
-				if (sock_flag(sk, SOCK_ZAPPED)) {
-					wanpipe_unlink_driver(sk);
-					sk->sk_err = ENETDOWN;
-					sk->sk_error_report(sk);
-				}
-
-				if (msg == NETDEV_UNREGISTER) {
-					printk(KERN_INFO "wansock: Unregistering Device: %s\n",
-							  dev->name);
-					wanpipe_unlink_driver(sk);
-					sk->sk_bound_dev_if = 0;
-				}
-			}
-			break;
-		case NETDEV_UP:
-			if (dev->ifindex == sk->sk_bound_dev_if &&
-			    po->num && !sock_flag(sk, SOCK_ZAPPED)) {
-				printk(KERN_INFO "wansock: Registering Device: %s\n",
-						dev->name);
-				wanpipe_link_driver(dev,sk);
-			}
-			break;
-		}
-	}
-	return NOTIFY_DONE;
-}
-
-/*============================================================
- *  wanpipe_ioctl
- *
- * 	Execute a user commands, and set socket options.
- *
- * FIXME: More thought should go into this function.
- *
- *===========================================================*/
-
-static int wanpipe_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-{
-	struct sock *sk = sock->sk;
-	int err;
-
-	switch(cmd)
-	{
-		case SIOCGSTAMP:
-			return sock_get_timestamp(sk, (struct timeval __user *)arg);
-
-		case SIOC_WANPIPE_CHECK_TX:
-
-			return atomic_read(&sk->sk_wmem_alloc);
-
-		case SIOC_WANPIPE_SOCK_STATE:
-
-			if (sk->sk_state == WANSOCK_CONNECTED)
-				return 0;
-
-			return 1;
-
-
-		case SIOC_WANPIPE_GET_CALL_DATA:
-
-			return get_ioctl_cmd (sk,(void*)arg);
-
-		case SIOC_WANPIPE_SET_CALL_DATA:
-
-			return set_ioctl_cmd (sk,(void*)arg);
-
-		case SIOC_WANPIPE_ACCEPT_CALL:
-		case SIOC_WANPIPE_CLEAR_CALL:
-		case SIOC_WANPIPE_RESET_CALL:
-
-			if ((err=set_ioctl_cmd(sk,(void*)arg)) < 0)
-				return err;
-
-			err=wanpipe_exec_cmd(sk,cmd,0);
-			get_ioctl_cmd(sk,(void*)arg);
-			return err;
-
-		case SIOC_WANPIPE_DEBUG:
-
-			return wanpipe_debug(sk,(void*)arg);
-
-		case SIOC_WANPIPE_SET_NONBLOCK:
-
-			if (sk->sk_state != WANSOCK_DISCONNECTED)
-				return -EINVAL;
-
-			sock->file->f_flags |= O_NONBLOCK;
-			return 0;
-
-#ifdef CONFIG_INET
-		case SIOCADDRT:
-		case SIOCDELRT:
-		case SIOCDARP:
-		case SIOCGARP:
-		case SIOCSARP:
-		case SIOCDRARP:
-		case SIOCGRARP:
-		case SIOCSRARP:
-		case SIOCGIFADDR:
-		case SIOCSIFADDR:
-		case SIOCGIFBRDADDR:
-		case SIOCSIFBRDADDR:
-		case SIOCGIFNETMASK:
-		case SIOCSIFNETMASK:
-		case SIOCGIFDSTADDR:
-		case SIOCSIFDSTADDR:
-		case SIOCSIFFLAGS:
-			return inet_dgram_ops.ioctl(sock, cmd, arg);
-#endif
-
-		default:
-			return -ENOIOCTLCMD;
-	}
-	/*NOTREACHED*/
-}
-
-/*============================================================
- *  wanpipe_debug
- *
- *	This function will pass up information about all
- *      active sockets.
- *
- * FIXME: More thought should go into this function.
- *
- *===========================================================*/
-
-static int wanpipe_debug (struct sock *origsk, void *arg)
-{
-	struct sock *sk;
-	struct hlist_node *node;
-	struct net_device *dev = NULL;
-	wanpipe_common_t *chan=NULL;
-	int cnt=0, err=0;
-	wan_debug_t *dbg_data = (wan_debug_t *)arg;
-
-	sk_for_each(sk, node, &wanpipe_sklist) {
-		wanpipe_opt *wp = wp_sk(sk);
-
-		if (sk == origsk){
-			continue;
-		}
-
-		if ((err=put_user(1, &dbg_data->debug[cnt].free)))
-			return err;
-		if ((err = put_user(sk->sk_state,
-				    &dbg_data->debug[cnt].state_sk)))
-			return err;
-		if ((err = put_user(sk->sk_rcvbuf,
-				    &dbg_data->debug[cnt].rcvbuf)))
-			return err;
-		if ((err = put_user(atomic_read(&sk->sk_rmem_alloc),
-				    &dbg_data->debug[cnt].rmem)))
-			return err;
-		if ((err = put_user(atomic_read(&sk->sk_wmem_alloc),
-				    &dbg_data->debug[cnt].wmem)))
-			return err;
-		if ((err = put_user(sk->sk_sndbuf,
-				    &dbg_data->debug[cnt].sndbuf)))
-			return err;
-		if ((err=put_user(sk_count, &dbg_data->debug[cnt].sk_count)))
-			return err;
-		if ((err=put_user(wp->poll_cnt, &dbg_data->debug[cnt].poll_cnt)))
-			return err;
-		if ((err = put_user(sk->sk_bound_dev_if,
-				    &dbg_data->debug[cnt].bound)))
-			return err;
-
-		if (sk->sk_bound_dev_if) {
-			dev = dev_get_by_index(sk->sk_bound_dev_if);
-			if (!dev)
-				continue;
-
-			chan=dev->priv;
-			dev_put(dev);
-
-			if ((err=put_user(chan->state, &dbg_data->debug[cnt].d_state)))
-				return err;
-			if ((err=put_user(chan->svc, &dbg_data->debug[cnt].svc)))
-				return err;
-
-			if ((err=put_user(atomic_read(&chan->command),
-						&dbg_data->debug[cnt].command)))
-				return err;
-
-
-			if (wp){
-				sdla_t *card = (sdla_t*)wp->card;
-
-				if (card){
-					if ((err=put_user(atomic_read(&card->u.x.command_busy),
-								&dbg_data->debug[cnt].cmd_busy)))
-						return err;
-				}
-
-				if ((err=put_user(wp->lcn,
-						  &dbg_data->debug[cnt].lcn)))
-					return err;
-
-				if (wp->mbox) {
-					if ((err=put_user(1, &dbg_data->debug[cnt].mbox)))
-						return err;
-				}
-			}
-
-			if ((err=put_user(atomic_read(&chan->receive_block),
-								&dbg_data->debug[cnt].rblock)))
-				return err;
-
-			if (copy_to_user(dbg_data->debug[cnt].name, dev->name, strlen(dev->name)))
-				return -EFAULT;
-		}
-
-		if (++cnt == MAX_NUM_DEBUG)
-			break;
-	}
-	return 0;
-}
-
-/*============================================================
- *  get_ioctl_cmd
- *
- *	Pass up the contents of socket MBOX to the user.
- *===========================================================*/
-
-static int get_ioctl_cmd (struct sock *sk, void *arg)
-{
-	x25api_t *usr_data = (x25api_t *)arg;
-	mbox_cmd_t *mbox_ptr;
-	int err;
-
-	if (usr_data == NULL)
-		return -EINVAL;
-
-	if (!wp_sk(sk)->mbox) {
-		return -EINVAL;
-	}
-
-	mbox_ptr = (mbox_cmd_t *)wp_sk(sk)->mbox;
-
-	if ((err=put_user(mbox_ptr->cmd.qdm, &usr_data->hdr.qdm)))
-		return err;
-	if ((err=put_user(mbox_ptr->cmd.cause, &usr_data->hdr.cause)))
-		return err;
-	if ((err=put_user(mbox_ptr->cmd.diagn, &usr_data->hdr.diagn)))
-		return err;
-	if ((err=put_user(mbox_ptr->cmd.length, &usr_data->hdr.length)))
-		return err;
-	if ((err=put_user(mbox_ptr->cmd.result, &usr_data->hdr.result)))
-		return err;
-	if ((err=put_user(mbox_ptr->cmd.lcn, &usr_data->hdr.lcn)))
-		return err;
-
-	if (mbox_ptr->cmd.length > 0){
-		if (mbox_ptr->cmd.length > X25_MAX_DATA)
-			return -EINVAL;
-
-		if (copy_to_user(usr_data->data, mbox_ptr->data, mbox_ptr->cmd.length)){
-			printk(KERN_INFO "wansock: Copy failed !!!\n");
-			return -EFAULT;
-		}
-	}
-	return 0;
-}
-
-/*============================================================
- *  set_ioctl_cmd
- *
- *	Before command can be execute, socket MBOX must
- *      be created, and initialized with user data.
- *===========================================================*/
-
-static int set_ioctl_cmd (struct sock *sk, void *arg)
-{
-	x25api_t *usr_data = (x25api_t *)arg;
-	mbox_cmd_t *mbox_ptr;
-	int err;
-
-	if (!wp_sk(sk)->mbox) {
-		void *mbox_ptr;
-		struct net_device *dev = dev_get_by_index(sk->sk_bound_dev_if);
-		if (!dev)
-			return -ENODEV;
-
-		dev_put(dev);
-
-		if ((mbox_ptr = kzalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL)
-			return -ENOMEM;
-
-		wp_sk(sk)->mbox = mbox_ptr;
-
-		wanpipe_link_driver(dev,sk);
-	}
-
-	mbox_ptr = (mbox_cmd_t*)wp_sk(sk)->mbox;
-	memset(mbox_ptr, 0, sizeof(mbox_cmd_t));
-
-	if (usr_data == NULL){
-		return 0;
-	}
-	if ((err=get_user(mbox_ptr->cmd.qdm, &usr_data->hdr.qdm)))
-		return err;
-	if ((err=get_user(mbox_ptr->cmd.cause, &usr_data->hdr.cause)))
-		return err;
-	if ((err=get_user(mbox_ptr->cmd.diagn, &usr_data->hdr.diagn)))
-		return err;
-	if ((err=get_user(mbox_ptr->cmd.length, &usr_data->hdr.length)))
-		return err;
-	if ((err=get_user(mbox_ptr->cmd.result, &usr_data->hdr.result)))
-		return err;
-
-	if (mbox_ptr->cmd.length > 0){
-		if (mbox_ptr->cmd.length > X25_MAX_DATA)
-			return -EINVAL;
-
-		if (copy_from_user(mbox_ptr->data, usr_data->data, mbox_ptr->cmd.length)){
-			printk(KERN_INFO "Copy failed\n");
-			return -EFAULT;
-		}
-	}
-	return 0;
-}
-
-
-/*======================================================================
- * wanpipe_poll
- *
- *	Datagram poll: Again totally generic. This also handles
- *	sequenced packet sockets providing the socket receive queue
- *	is only ever holding data ready to receive.
- *
- *	Note: when you _don't_ use this routine for this protocol,
- *	and you use a different write policy from sock_writeable()
- *	then please supply your own write_space callback.
- *=====================================================================*/
-
-unsigned int wanpipe_poll(struct file * file, struct socket *sock, poll_table *wait)
-{
-	struct sock *sk = sock->sk;
-	unsigned int mask;
-
-	++wp_sk(sk)->poll_cnt;
-
-	poll_wait(file, sk->sk_sleep, wait);
-	mask = 0;
-
-	/* exceptional events? */
-	if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) {
-		mask |= POLLPRI;
-		return mask;
-	}
-	if (sk->sk_shutdown & RCV_SHUTDOWN)
-		mask |= POLLHUP;
-
-	/* readable? */
-	if (!skb_queue_empty(&sk->sk_receive_queue)) {
-		mask |= POLLIN | POLLRDNORM;
-	}
-
-	/* connection hasn't started yet */
-	if (sk->sk_state == WANSOCK_CONNECTING) {
-		return mask;
-	}
-
-	if (sk->sk_state == WANSOCK_DISCONNECTED) {
-		mask = POLLPRI;
-		return mask;
-	}
-
-	/* This check blocks the user process if there is
-	 * a packet already queued in the socket write queue.
-	 * This option is only for X25API protocol, for other
-	 * protocol like chdlc enable streaming mode,
-	 * where multiple packets can be pending in the socket
-	 * transmit queue */
-
-	if (wp_sk(sk)->num == htons(X25_PROT)) {
-		if (atomic_read(&wp_sk(sk)->packet_sent))
-			return mask;
-	}
-
-	/* writable? */
-	if (sock_writeable(sk)){
-		mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
-	}else{
-		set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
-	}
-
-	return mask;
-}
-
-/*======================================================================
- * wanpipe_listen
- *
- *	X25API Specific function. Set a socket into LISTENING  MODE.
- *=====================================================================*/
-
-
-static int wanpipe_listen(struct socket *sock, int backlog)
-{
-	struct sock *sk = sock->sk;
-
-	/* This is x25 specific area if protocol doesn't
-	 * match, return error */
-	if (wp_sk(sk)->num != htons(X25_PROT))
-		return -EINVAL;
-
-	if (sk->sk_state == WANSOCK_BIND_LISTEN) {
-
-		sk->sk_max_ack_backlog = backlog;
-		sk->sk_state           = WANSOCK_LISTEN;
-		return 0;
-	}else{
-		printk(KERN_INFO "wansock: Listening sock was not binded\n");
-	}
-
-	return -EINVAL;
-}
-
-/*======================================================================
- * wanpipe_link_card
- *
- *	Connects the listening socket to the driver
- *=====================================================================*/
-
-static int wanpipe_link_card (struct sock *sk)
-{
-	sdla_t *card = (sdla_t*)wp_sk(sk)->card;
-
-	if (!card)
-		return -ENOMEM;
-
-	if ((card->sk != NULL) || (card->func != NULL)){
-		printk(KERN_INFO "wansock: Listening queue is already established\n");
-		return -EINVAL;
-	}
-
-	card->sk=sk;
-	card->func=wanpipe_listen_rcv;
-	sock_set_flag(sk, SOCK_ZAPPED);
-
-	return 0;
-}
-
-/*======================================================================
- * wanpipe_listen
- *
- *	X25API Specific function. Disconnect listening socket from
- *      the driver.
- *=====================================================================*/
-
-static void wanpipe_unlink_card (struct sock *sk)
-{
-	sdla_t *card = (sdla_t*)wp_sk(sk)->card;
-
-	if (card){
-		card->sk=NULL;
-		card->func=NULL;
-	}
-}
-
-/*======================================================================
- * wanpipe_exec_cmd
- *
- *	Ioctl function calls this function to execute user command.
- *      Connect() sytem call also calls this function to execute
- *      place call.  This function blocks until command is executed.
- *=====================================================================*/
-
-static int wanpipe_exec_cmd(struct sock *sk, int cmd, unsigned int flags)
-{
-	int err = -EINVAL;
-	wanpipe_opt *wp = wp_sk(sk);
-	mbox_cmd_t *mbox_ptr = (mbox_cmd_t*)wp->mbox;
-
-	if (!mbox_ptr){
-		printk(KERN_INFO "NO MBOX PTR !!!!!\n");
-		return -EINVAL;
-	}
-
-	/* This is x25 specific area if protocol doesn't
-	 * match, return error */
-	if (wp->num != htons(X25_PROT))
-		return -EINVAL;
-
-
-	switch (cmd){
-
-		case SIOC_WANPIPE_ACCEPT_CALL:
-
-			if (sk->sk_state != WANSOCK_CONNECTING) {
-				err = -EHOSTDOWN;
-				break;
-			}
-
-			err = execute_command(sk,X25_ACCEPT_CALL,0);
-			if (err < 0)
-				break;
-
-			/* Update. Mar6 2000.
-			 * Do not set the sock lcn number here, since
-			 * it is done in wanpipe_listen_rcv().
-			 */
-			if (sk->sk_state == WANSOCK_CONNECTED) {
-				wp->lcn = ((mbox_cmd_t*)wp->mbox)->cmd.lcn;
-				DBG_PRINTK(KERN_INFO "\nwansock: Accept OK %i\n",
-					wp->lcn);
-				err = 0;
-
-			}else{
-				DBG_PRINTK (KERN_INFO "\nwansock: Accept Failed %i\n",
-					wp->lcn);
-				wp->lcn = 0;
-				err = -ECONNREFUSED;
-			}
-			break;
-
-		case SIOC_WANPIPE_CLEAR_CALL:
-
-			if (sk->sk_state == WANSOCK_DISCONNECTED) {
-				err = -EINVAL;
-				break;
-			}
-
-
-			/* Check if data buffers are pending for transmission,
-			 * if so, check whether user wants to wait until data
-			 * is transmitted, or clear a call and drop packets */
-
-			if (atomic_read(&sk->sk_wmem_alloc) ||
-			    check_driver_busy(sk)) {
-				mbox_cmd_t *mbox = wp->mbox;
-				if (mbox->cmd.qdm & 0x80){
-					mbox->cmd.result = 0x35;
-					err = -EAGAIN;
-					break;
-				}
-			}
-
-			sk->sk_state = WANSOCK_DISCONNECTING;
-
-			err = execute_command(sk,X25_CLEAR_CALL,0);
-			if (err < 0)
-				break;
-
-			err = -ECONNREFUSED;
-			if (sk->sk_state == WANSOCK_DISCONNECTED) {
-				DBG_PRINTK(KERN_INFO "\nwansock: CLEAR OK %i\n",
-					   wp->lcn);
-				wp->lcn = 0;
-				err = 0;
-			}
-			break;
-
-		case SIOC_WANPIPE_RESET_CALL:
-
-			if (sk->sk_state != WANSOCK_CONNECTED) {
-				err = -EINVAL;
-				break;
-			}
-
-
-			/* Check if data buffers are pending for transmission,
-			 * if so, check whether user wants to wait until data
-			 * is transmitted, or reset a call and drop packets */
-
-			if (atomic_read(&sk->sk_wmem_alloc) ||
-			    check_driver_busy(sk)) {
-				mbox_cmd_t *mbox = wp->mbox;
-				if (mbox->cmd.qdm & 0x80){
-					mbox->cmd.result = 0x35;
-					err = -EAGAIN;
-					break;
-				}
-			}
-
-
-			err = execute_command(sk, X25_RESET,0);
-			if (err < 0)
-				break;
-
-			err = mbox_ptr->cmd.result;
-			break;
-
-
-		case X25_PLACE_CALL:
-
-			err=execute_command(sk,X25_PLACE_CALL,flags);
-			if (err < 0)
-				break;
-
-			if (sk->sk_state == WANSOCK_CONNECTED) {
-
-				wp->lcn = ((mbox_cmd_t*)wp->mbox)->cmd.lcn;
-
-				DBG_PRINTK(KERN_INFO "\nwansock: PLACE CALL OK %i\n",
-					wp->lcn);
-				err = 0;
-
-			} else if (sk->sk_state == WANSOCK_CONNECTING &&
-				   (flags & O_NONBLOCK)) {
-				wp->lcn = ((mbox_cmd_t*)wp->mbox)->cmd.lcn;
-				DBG_PRINTK(KERN_INFO "\nwansock: Place Call OK: Waiting %i\n",
-					wp->lcn);
-
-				err = 0;
-
-			}else{
-				DBG_PRINTK(KERN_INFO "\nwansock: Place call Failed\n");
-				err = -ECONNREFUSED;
-			}
-
-			break;
-
-		default:
-			return -EINVAL;
-	}
-
-	return err;
-}
-
-static int check_driver_busy (struct sock *sk)
-{
-	struct net_device *dev = dev_get_by_index(sk->sk_bound_dev_if);
-	wanpipe_common_t *chan;
-
-	if (!dev)
-		return 0;
-
-	dev_put(dev);
-
-	if ((chan=dev->priv) == NULL)
-		return 0;
-
-	return atomic_read(&chan->driver_busy);
-}
-
-
-/*======================================================================
- * wanpipe_accept
- *
- *	ACCEPT() System call.	X25API Specific function.
- *	For each incoming call, create a new socket and
- *      return it to the user.
- *=====================================================================*/
-
-static int wanpipe_accept(struct socket *sock, struct socket *newsock, int flags)
-{
-	struct sock *sk;
-	struct sock *newsk;
-	struct sk_buff *skb;
-	DECLARE_WAITQUEUE(wait, current);
-	int err=0;
-
-	if (newsock->sk != NULL){
-		wanpipe_kill_sock_accept(newsock->sk);
-		newsock->sk=NULL;
-	}
-
-	if ((sk = sock->sk) == NULL)
-		return -EINVAL;
-
-	if (sk->sk_type != SOCK_RAW)
-		return -EOPNOTSUPP;
-
-	if (sk->sk_state != WANSOCK_LISTEN)
-		return -EINVAL;
-
-	if (wp_sk(sk)->num != htons(X25_PROT))
-		return -EINVAL;
-
-	add_wait_queue(sk->sk_sleep,&wait);
-	current->state = TASK_INTERRUPTIBLE;
-	for (;;){
-		skb = skb_dequeue(&sk->sk_receive_queue);
-		if (skb){
-			err=0;
-			break;
-		}
-		if (signal_pending(current)) {
-			err = -ERESTARTSYS;
-			break;
-		}
-		schedule();
-	}
-	current->state = TASK_RUNNING;
-	remove_wait_queue(sk->sk_sleep,&wait);
-
-	if (err != 0)
-		return err;
-
-	newsk = get_newsk_from_skb(skb);
-	if (!newsk){
-		return -EINVAL;
-	}
-
-	set_bit(1,&wanpipe_tx_critical);
-	write_lock(&wanpipe_sklist_lock);
-	sk_add_node(newsk, &wanpipe_sklist);
-	write_unlock(&wanpipe_sklist_lock);
-	clear_bit(1,&wanpipe_tx_critical);
-
-	newsk->sk_socket = newsock;
-	newsk->sk_sleep = &newsock->wait;
-
-	/* Now attach up the new socket */
-	sk->sk_ack_backlog--;
-	newsock->sk = newsk;
-
-	kfree_skb(skb);
-
-	DBG_PRINTK(KERN_INFO "\nwansock: ACCEPT Got LCN %i\n",
-		   wp_sk(newsk)->lcn);
-	return 0;
-}
-
-/*======================================================================
- *  get_newsk_from_skb
- *
- *	Accept() uses this function to get the address of the new
- *      socket structure.
- *=====================================================================*/
-
-struct sock * get_newsk_from_skb (struct sk_buff *skb)
-{
-	struct net_device *dev = skb->dev;
-	wanpipe_common_t *chan;
-
-	if (!dev){
-		return NULL;
-	}
-
-	if ((chan = dev->priv) == NULL){
-		return NULL;
-	}
-
-	if (!chan->sk){
-		return NULL;
-	}
-	return (struct sock *)chan->sk;
-}
-
-/*======================================================================
- *  wanpipe_connect
- *
- *  	CONNECT() System Call. X25API specific function
- * 	Check the state of the sock, and execute PLACE_CALL command.
- *      Connect can ether block or return without waiting for connection,
- *      if specified by user.
- *=====================================================================*/
-
-static int wanpipe_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags)
-{
-	struct sock *sk = sock->sk;
-	struct wan_sockaddr_ll *addr = (struct wan_sockaddr_ll*)uaddr;
-	struct net_device *dev;
-	int err;
-
-	if (wp_sk(sk)->num != htons(X25_PROT))
-		return -EINVAL;
-
-	if (sk->sk_state == WANSOCK_CONNECTED)
-		return -EISCONN;	/* No reconnect on a seqpacket socket */
-
-	if (sk->sk_state != WAN_DISCONNECTED) {
-		printk(KERN_INFO "wansock: Trying to connect on channel NON DISCONNECT\n");
-		return -ECONNREFUSED;
-	}
-
-	sk->sk_state = WANSOCK_DISCONNECTED;
-	sock->state  = SS_UNCONNECTED;
-
-	if (addr_len != sizeof(struct wan_sockaddr_ll))
-		return -EINVAL;
-
-	if (addr->sll_family != AF_WANPIPE)
-		return -EINVAL;
-
-	if ((dev = dev_get_by_index(sk->sk_bound_dev_if)) == NULL)
-		return -ENETUNREACH;
-
-	dev_put(dev);
-
-	if (!sock_flag(sk, SOCK_ZAPPED)) /* Must bind first - autobinding does not work */
-		return -EINVAL;
-
-	sock->state   = SS_CONNECTING;
-	sk->sk_state  = WANSOCK_CONNECTING;
-
-	if (!wp_sk(sk)->mbox) {
-		if (wp_sk (sk)->svc)
-			return -EINVAL;
-		else {
-			int err;
-			if ((err=set_ioctl_cmd(sk,NULL)) < 0)
-				return err;
-		}
-	}
-
-	if ((err=wanpipe_exec_cmd(sk, X25_PLACE_CALL,flags)) != 0){
-		sock->state = SS_UNCONNECTED;
-		sk->sk_state = WANSOCK_CONNECTED;
-		return err;
-	}
-
-	if (sk->sk_state != WANSOCK_CONNECTED && (flags & O_NONBLOCK)) {
-		return 0;
-	}
-
-	if (sk->sk_state != WANSOCK_CONNECTED) {
-		sock->state = SS_UNCONNECTED;
-		return -ECONNREFUSED;
-	}
-
-	sock->state = SS_CONNECTED;
-	return 0;
-}
-
-const struct proto_ops wanpipe_ops = {
-	.family = 	PF_WANPIPE,
-	.owner =	THIS_MODULE,
-	.release = 	wanpipe_release,
-	.bind = 	wanpipe_bind,
-	.connect = 	wanpipe_connect,
-	.socketpair = 	sock_no_socketpair,
-	.accept = 	wanpipe_accept,
-	.getname = 	wanpipe_getname,
-	.poll = 	wanpipe_poll,
-	.ioctl = 	wanpipe_ioctl,
-	.listen = 	wanpipe_listen,
-	.shutdown = 	sock_no_shutdown,
-	.setsockopt = 	sock_no_setsockopt,
-	.getsockopt = 	sock_no_getsockopt,
-	.sendmsg = 	wanpipe_sendmsg,
-	.recvmsg = 	wanpipe_recvmsg
-};
-
-static struct net_proto_family wanpipe_family_ops = {
-	.family = PF_WANPIPE,
-	.create = wanpipe_create,
-	.owner	= THIS_MODULE,
-};
-
-struct notifier_block wanpipe_netdev_notifier = {
-	.notifier_call = wanpipe_notifier,
-};
-
-
-#ifdef MODULE
-void cleanup_module(void)
-{
-	printk(KERN_INFO "wansock: Cleaning up \n");
-	unregister_netdevice_notifier(&wanpipe_netdev_notifier);
-	sock_unregister(PF_WANPIPE);
-	proto_unregister(&wanpipe_proto);
-}
-
-int init_module(void)
-{
-	int rc;
-
-	printk(KERN_INFO "wansock: Registering Socket \n");
-
-	rc = proto_register(&wanpipe_proto, 0);
-	if (rc != 0)
-		goto out;
-
-	sock_register(&wanpipe_family_ops);
-	register_netdevice_notifier(&wanpipe_netdev_notifier);
-out:
-	return rc;
-}
-#endif
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_NETPROTO(PF_WANPIPE);
diff --git a/net/x25/x25_forward.c b/net/x25/x25_forward.c
index d339e0c..8738ec7 100644
--- a/net/x25/x25_forward.c
+++ b/net/x25/x25_forward.c
@@ -26,64 +26,66 @@
 	short same_lci = 0;
 	int rc = 0;
 
-	if ((rt = x25_get_route(dest_addr)) != NULL) {
+	if ((rt = x25_get_route(dest_addr)) == NULL)
+		goto out_no_route;
 
-		if ((neigh_new = x25_get_neigh(rt->dev)) == NULL) {
-			/* This shouldnt happen, if it occurs somehow
-			 * do something sensible
-			 */
-			goto out_put_route;
-		}
-
-		/* Avoid a loop. This is the normal exit path for a
-		 * system with only one x.25 iface and default route
+	if ((neigh_new = x25_get_neigh(rt->dev)) == NULL) {
+		/* This shouldnt happen, if it occurs somehow
+		 * do something sensible
 		 */
-		if (rt->dev == from->dev) {
-			goto out_put_nb;
-		}
-
-		/* Remote end sending a call request on an already
-		 * established LCI? It shouldnt happen, just in case..
-		 */
-		read_lock_bh(&x25_forward_list_lock);
-		list_for_each(entry, &x25_forward_list) {
-			x25_frwd = list_entry(entry, struct x25_forward, node);
-			if (x25_frwd->lci == lci) {
-				printk(KERN_WARNING "X.25: call request for lci which is already registered!, transmitting but not registering new pair\n");
-				same_lci = 1;
-			}
-		}
-		read_unlock_bh(&x25_forward_list_lock);
-
-		/* Save the forwarding details for future traffic */
-		if (!same_lci){
-			if ((new_frwd = kmalloc(sizeof(struct x25_forward),
-							GFP_ATOMIC)) == NULL){
-				rc = -ENOMEM;
-				goto out_put_nb;
-			}
-			new_frwd->lci = lci;
-			new_frwd->dev1 = rt->dev;
-			new_frwd->dev2 = from->dev;
-			write_lock_bh(&x25_forward_list_lock);
-			list_add(&new_frwd->node, &x25_forward_list);
-			write_unlock_bh(&x25_forward_list_lock);
-		}
-
-		/* Forward the call request */
-		if ( (skbn = skb_clone(skb, GFP_ATOMIC)) == NULL){
-			goto out_put_nb;
-		}
-		x25_transmit_link(skbn, neigh_new);
-		rc = 1;
+		goto out_put_route;
 	}
 
+	/* Avoid a loop. This is the normal exit path for a
+	 * system with only one x.25 iface and default route
+	 */
+	if (rt->dev == from->dev) {
+		goto out_put_nb;
+	}
+
+	/* Remote end sending a call request on an already
+	 * established LCI? It shouldnt happen, just in case..
+	 */
+	read_lock_bh(&x25_forward_list_lock);
+	list_for_each(entry, &x25_forward_list) {
+		x25_frwd = list_entry(entry, struct x25_forward, node);
+		if (x25_frwd->lci == lci) {
+			printk(KERN_WARNING "X.25: call request for lci which is already registered!, transmitting but not registering new pair\n");
+			same_lci = 1;
+		}
+	}
+	read_unlock_bh(&x25_forward_list_lock);
+
+	/* Save the forwarding details for future traffic */
+	if (!same_lci){
+		if ((new_frwd = kmalloc(sizeof(struct x25_forward),
+						GFP_ATOMIC)) == NULL){
+			rc = -ENOMEM;
+			goto out_put_nb;
+		}
+		new_frwd->lci = lci;
+		new_frwd->dev1 = rt->dev;
+		new_frwd->dev2 = from->dev;
+		write_lock_bh(&x25_forward_list_lock);
+		list_add(&new_frwd->node, &x25_forward_list);
+		write_unlock_bh(&x25_forward_list_lock);
+	}
+
+	/* Forward the call request */
+	if ( (skbn = skb_clone(skb, GFP_ATOMIC)) == NULL){
+		goto out_put_nb;
+	}
+	x25_transmit_link(skbn, neigh_new);
+	rc = 1;
+
 
 out_put_nb:
 	x25_neigh_put(neigh_new);
 
 out_put_route:
 	x25_route_put(rt);
+
+out_no_route:
 	return rc;
 }
 
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 946b715..785c3e3 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -735,12 +735,14 @@
 
 struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
 					  struct xfrm_selector *sel,
-					  struct xfrm_sec_ctx *ctx, int delete)
+					  struct xfrm_sec_ctx *ctx, int delete,
+					  int *err)
 {
 	struct xfrm_policy *pol, *ret;
 	struct hlist_head *chain;
 	struct hlist_node *entry;
 
+	*err = 0;
 	write_lock_bh(&xfrm_policy_lock);
 	chain = policy_hash_bysel(sel, sel->family, dir);
 	ret = NULL;
@@ -750,6 +752,11 @@
 		    xfrm_sec_ctx_match(ctx, pol->security)) {
 			xfrm_pol_hold(pol);
 			if (delete) {
+				*err = security_xfrm_policy_delete(pol);
+				if (*err) {
+					write_unlock_bh(&xfrm_policy_lock);
+					return pol;
+				}
 				hlist_del(&pol->bydst);
 				hlist_del(&pol->byidx);
 				xfrm_policy_count[dir]--;
@@ -768,12 +775,14 @@
 }
 EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
 
-struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete)
+struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete,
+				     int *err)
 {
 	struct xfrm_policy *pol, *ret;
 	struct hlist_head *chain;
 	struct hlist_node *entry;
 
+	*err = 0;
 	write_lock_bh(&xfrm_policy_lock);
 	chain = xfrm_policy_byidx + idx_hash(id);
 	ret = NULL;
@@ -781,6 +790,11 @@
 		if (pol->type == type && pol->index == id) {
 			xfrm_pol_hold(pol);
 			if (delete) {
+				*err = security_xfrm_policy_delete(pol);
+				if (*err) {
+					write_unlock_bh(&xfrm_policy_lock);
+					return pol;
+				}
 				hlist_del(&pol->bydst);
 				hlist_del(&pol->byidx);
 				xfrm_policy_count[dir]--;
@@ -2075,7 +2089,7 @@
 					sizeof(struct in6_addr));
 			}
 			audit_log_format(audit_buf,
-					 " src=" NIP6_FMT "dst=" NIP6_FMT,
+					 " src=" NIP6_FMT " dst=" NIP6_FMT,
 					 NIP6(saddr6), NIP6(daddr6));
 		}
 		break;
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index a35f9e4..e3a0bcf 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -704,7 +704,8 @@
 		    x->props.mode   != mode ||
 		    x->props.family != family ||
 		    x->km.state     != XFRM_STATE_ACQ ||
-		    x->id.spi       != 0)
+		    x->id.spi       != 0 ||
+		    x->id.proto	    != proto)
 			continue;
 
 		switch (family) {
@@ -801,7 +802,8 @@
 
 	if (use_spi && x->km.seq) {
 		x1 = __xfrm_find_acq_byseq(x->km.seq);
-		if (x1 && xfrm_addr_cmp(&x1->id.daddr, &x->id.daddr, family)) {
+		if (x1 && ((x1->id.proto != x->id.proto) ||
+		    xfrm_addr_cmp(&x1->id.daddr, &x->id.daddr, family))) {
 			xfrm_state_put(x1);
 			x1 = NULL;
 		}
@@ -1369,7 +1371,8 @@
 		return 0;
 
 	diff = x->replay.seq - seq;
-	if (diff >= x->props.replay_window) {
+	if (diff >= min_t(unsigned int, x->props.replay_window,
+			  sizeof(x->replay.bitmap) * 8)) {
 		x->stats.replay_window++;
 		return -EINVAL;
 	}
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 956cfe0..e81e2fb 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -530,9 +530,6 @@
 
 	err = xfrm_state_delete(x);
 
-	xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
-		       AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
-
 	if (err < 0)
 		goto out;
 
@@ -542,6 +539,8 @@
 	km_state_notify(x, &c);
 
 out:
+	xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
+		       AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
 	xfrm_state_put(x);
 	return err;
 }
@@ -1254,7 +1253,7 @@
 		return err;
 
 	if (p->index)
-		xp = xfrm_policy_byid(type, p->dir, p->index, delete);
+		xp = xfrm_policy_byid(type, p->dir, p->index, delete, &err);
 	else {
 		struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1];
 		struct xfrm_policy tmp;
@@ -1270,7 +1269,8 @@
 			if ((err = security_xfrm_policy_alloc(&tmp, uctx)))
 				return err;
 		}
-		xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, delete);
+		xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security,
+					   delete, &err);
 		security_xfrm_policy_free(&tmp);
 	}
 	if (xp == NULL)
@@ -1288,8 +1288,6 @@
 					      MSG_DONTWAIT);
 		}
 	} else {
-		err = security_xfrm_policy_delete(xp);
-
 		xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
 			       AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL);
 
@@ -1303,9 +1301,8 @@
 		km_policy_notify(xp, p->dir, &c);
 	}
 
-	xfrm_pol_put(xp);
-
 out:
+	xfrm_pol_put(xp);
 	return err;
 }
 
@@ -1502,7 +1499,7 @@
 		return err;
 
 	if (p->index)
-		xp = xfrm_policy_byid(type, p->dir, p->index, 0);
+		xp = xfrm_policy_byid(type, p->dir, p->index, 0, &err);
 	else {
 		struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1];
 		struct xfrm_policy tmp;
@@ -1518,13 +1515,14 @@
 			if ((err = security_xfrm_policy_alloc(&tmp, uctx)))
 				return err;
 		}
-		xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, 0);
+		xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security,
+					   0, &err);
 		security_xfrm_policy_free(&tmp);
 	}
 
 	if (xp == NULL)
-		return err;
-											read_lock(&xp->lock);
+		return -ENOENT;
+	read_lock(&xp->lock);
 	if (xp->dead) {
 		read_unlock(&xp->lock);
 		goto out;
@@ -2027,7 +2025,7 @@
 	return -1;
 }
 
-static int inline xfrm_sa_len(struct xfrm_state *x)
+static inline int xfrm_sa_len(struct xfrm_state *x)
 {
 	int l = 0;
 	if (x->aalg)
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
index 668a11a..6bc7e7c 100644
--- a/scripts/basic/fixdep.c
+++ b/scripts/basic/fixdep.c
@@ -28,9 +28,11 @@
  * the dependency on linux/autoconf.h by a dependency on every config
  * option which is mentioned in any of the listed prequisites.
  *
- * To be exact, split-include populates a tree in include/config/,
- * e.g. include/config/his/driver.h, which contains the #define/#undef
- * for the CONFIG_HIS_DRIVER option.
+ * kconfig populates a tree in include/config/ with an empty file
+ * for each config symbol and when the configuration is updated
+ * the files representing changed config options are touched
+ * which then let make pick up the changes and the files that use
+ * the config symbols are rebuilt.
  *
  * So if the user changes his CONFIG_HIS_DRIVER option, only the objects
  * which depend on "include/linux/config/his/driver.h" will be rebuilt,
@@ -245,6 +247,8 @@
 		continue;
 
 	found:
+		if (!memcmp(q - 7, "_MODULE", 7))
+			q -= 7;
 		use_config(p+7, q-p-7);
 	}
 }
diff --git a/security/dummy.c b/security/dummy.c
index 558795b..8ffd764 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -907,7 +907,7 @@
 	return;
 }
 
-static int dummy_getprocattr(struct task_struct *p, char *name, void *value, size_t size)
+static int dummy_getprocattr(struct task_struct *p, char *name, char **value)
 {
 	return -EINVAL;
 }
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 19a385e..d41e24d 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4468,11 +4468,12 @@
 }
 
 static int selinux_getprocattr(struct task_struct *p,
-			       char *name, void *value, size_t size)
+			       char *name, char **value)
 {
 	struct task_security_struct *tsec;
 	u32 sid;
 	int error;
+	unsigned len;
 
 	if (current != p) {
 		error = task_has_perm(current, p, PROCESS__GETATTR);
@@ -4500,7 +4501,10 @@
 	if (!sid)
 		return 0;
 
-	return selinux_getsecurity(sid, value, size);
+	error = security_sid_to_context(sid, value, &len);
+	if (error)
+		return error;
+	return len;
 }
 
 static int selinux_setprocattr(struct task_struct *p,
diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c
index a0ec886..f4056a9 100644
--- a/sound/oss/dmasound/dmasound_core.c
+++ b/sound/oss/dmasound/dmasound_core.c
@@ -1346,22 +1346,34 @@
 	.ioctl		= sq_ioctl,
 	.open		= sq_open,
 	.release	= sq_release,
-#ifdef HAS_RECORD
-	.read		= NULL	/* default to no read for compat mode */
-#endif
 };
 
+#ifdef HAS_RECORD
+static const struct file_operations sq_fops_record =
+{
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.write		= sq_write,
+	.poll		= sq_poll,
+	.ioctl		= sq_ioctl,
+	.open		= sq_open,
+	.release	= sq_release,
+	.read		= sq_read,
+};
+#endif
+
 static int sq_init(void)
 {
+	const struct file_operations *fops = &sq_fops;
 #ifndef MODULE
 	int sq_unit;
 #endif
 
 #ifdef HAS_RECORD
 	if (dmasound.mach.record)
-		sq_fops.read = sq_read ;
+		fops = &sq_fops_record;
 #endif
-	sq_unit = register_sound_dsp(&sq_fops, -1);
+	sq_unit = register_sound_dsp(fops, -1);
 	if (sq_unit < 0) {
 		printk(KERN_ERR "dmasound_core: couldn't register fops\n") ;
 		return sq_unit ;
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 37fabf7..b188a4d 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -1962,9 +1962,11 @@
 static void ad1888_update_jacks(struct snd_ac97 *ac97)
 {
 	unsigned short val = 0;
-	if (! is_shared_linein(ac97))
+	/* clear LODIS if shared jack is to be used for Surround out */
+	if (is_shared_linein(ac97))
 		val |= (1 << 12);
-	if (! is_shared_micin(ac97))
+	/* clear CLDIS if shared jack is to be used for C/LFE out */
+	if (is_shared_micin(ac97))
 		val |= (1 << 11);
 	/* shared Line-In */
 	snd_ac97_update_bits(ac97, AC97_AD_MISC, (1 << 11) | (1 << 12), val);
@@ -2136,8 +2138,9 @@
 static void ad1985_update_jacks(struct snd_ac97 *ac97)
 {
 	ad1888_update_jacks(ac97);
+	/* clear OMS if shared jack is to be used for C/LFE out */
 	snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 1 << 9,
-			     is_shared_micin(ac97) ? 0 : 1 << 9);
+			     is_shared_micin(ac97) ? 1 << 9 : 0);
 }
 
 static int patch_ad1985_specific(struct snd_ac97 *ac97)
@@ -2418,9 +2421,9 @@
 	unsigned short ser_val;
 
 	/* disable SURROUND and CENTER/LFE if not surround mode */
-	if (! is_surround_on(ac97))
+	if (!is_surround_on(ac97))
 		misc_val |= AC97_AD1986_SODIS;
-	if (! is_clfe_on(ac97))
+	if (!is_clfe_on(ac97))
 		misc_val |= AC97_AD1986_CLDIS;
 
 	/* select line input (default=LINE_IN, SURROUND or MIC_1/2) */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index b9a8e23..1672cac 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -199,7 +199,6 @@
 
 /* STATESTS int mask: SD2,SD1,SD0 */
 #define STATESTS_INT_MASK	0x07
-#define AZX_MAX_CODECS		3
 
 /* SD_CTL bits */
 #define SD_CTL_STREAM_RESET	0x01	/* stream reset bit */
@@ -966,6 +965,16 @@
  * Codec initialization
  */
 
+static unsigned int azx_max_codecs[] __devinitdata = {
+	[AZX_DRIVER_ICH] = 3,
+	[AZX_DRIVER_ATI] = 4,
+	[AZX_DRIVER_ATIHDMI] = 4,
+	[AZX_DRIVER_VIA] = 3,		/* FIXME: correct? */
+	[AZX_DRIVER_SIS] = 3,		/* FIXME: correct? */
+	[AZX_DRIVER_ULI] = 3,		/* FIXME: correct? */
+	[AZX_DRIVER_NVIDIA] = 3,	/* FIXME: correct? */
+};
+
 static int __devinit azx_codec_create(struct azx *chip, const char *model)
 {
 	struct hda_bus_template bus_temp;
@@ -982,7 +991,7 @@
 		return err;
 
 	codecs = 0;
-	for (c = 0; c < AZX_MAX_CODECS; c++) {
+	for (c = 0; c < azx_max_codecs[chip->driver_type]; c++) {
 		if ((chip->codec_mask & (1 << c)) & probe_mask) {
 			err = snd_hda_codec_new(chip->bus, c, NULL);
 			if (err < 0)
@@ -1078,6 +1087,10 @@
 	runtime->hw.rates = hinfo->rates;
 	snd_pcm_limit_hw_rates(runtime);
 	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
+				   128);
+	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
+				   128);
 	if ((err = hinfo->ops.open(hinfo, apcm->codec, substream)) < 0) {
 		azx_release_device(azx_dev);
 		mutex_unlock(&chip->open_mutex);
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 00ace59..f94f1f22 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -833,12 +833,14 @@
 	SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK),
 	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK),
 	SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK),
+	SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK),
 	SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
 	SND_PCI_QUIRK(0x144d, 0xc023, "Samsung X60", AD1986A_LAPTOP_EAPD),
 	SND_PCI_QUIRK(0x144d, 0xc024, "Samsung R65", AD1986A_LAPTOP_EAPD),
 	SND_PCI_QUIRK(0x144d, 0xc026, "Samsung X11", AD1986A_LAPTOP_EAPD),
 	SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK),
 	SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA),
+	SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP),
 	SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK),
 	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_EAPD),
 	SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP),
@@ -1205,7 +1207,7 @@
 /*
  * Patch for HP nx6320
  *
- * nx6320 uses EAPD in the reserve way - EAPD-on means the internal
+ * nx6320 uses EAPD in the reverse way - EAPD-on means the internal
  * speaker output enabled _and_ mute-LED off.
  */
 
@@ -1373,6 +1375,21 @@
 	return 0;
 }
 
+/* configuration for Toshiba Laptops */
+static struct hda_verb ad1981_toshiba_init_verbs[] = {
+	{0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */
+	/* pin sensing on HP and Mic jacks */
+	{0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
+	{0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
+	{}
+};
+
+static struct snd_kcontrol_new ad1981_toshiba_mixers[] = {
+	HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT),
+	{ }
+};
+
 /* configuration for Lenovo Thinkpad T60 */
 static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
 	HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT),
@@ -1418,6 +1435,7 @@
 	AD1981_BASIC,
 	AD1981_HP,
 	AD1981_THINKPAD,
+	AD1981_TOSHIBA,
 	AD1981_MODELS
 };
 
@@ -1425,6 +1443,7 @@
 	[AD1981_HP]		= "hp",
 	[AD1981_THINKPAD]	= "thinkpad",
 	[AD1981_BASIC]		= "basic",
+	[AD1981_TOSHIBA]	= "toshiba"
 };
 
 static struct snd_pci_quirk ad1981_cfg_tbl[] = {
@@ -1435,6 +1454,7 @@
 	/* Lenovo Thinkpad T60/X60/Z6xx */
 	SND_PCI_QUIRK(0x17aa, 0, "Lenovo Thinkpad", AD1981_THINKPAD),
 	SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
+	SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA),
 	{}
 };
 
@@ -1485,8 +1505,17 @@
 		spec->mixers[0] = ad1981_thinkpad_mixers;
 		spec->input_mux = &ad1981_thinkpad_capture_source;
 		break;
+	case AD1981_TOSHIBA:
+		spec->mixers[0] = ad1981_hp_mixers;
+		spec->mixers[1] = ad1981_toshiba_mixers;
+		spec->num_init_verbs = 2;
+		spec->init_verbs[1] = ad1981_toshiba_init_verbs;
+		spec->multiout.dig_out_nid = 0;
+		spec->input_mux = &ad1981_hp_capture_source;
+		codec->patch_ops.init = ad1981_hp_init;
+		codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
+		break;
 	}
-
 	return 0;
 }
 
@@ -2607,6 +2636,12 @@
 	[AD1988_AUTO]		= "auto",
 };
 
+static struct snd_pci_quirk ad1988_cfg_tbl[] = {
+	SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
+	SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
+	{}
+};
+
 static int patch_ad1988(struct hda_codec *codec)
 {
 	struct ad198x_spec *spec;
@@ -2623,7 +2658,7 @@
 		snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
 
 	board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST,
-						  ad1988_models, NULL);
+						  ad1988_models, ad1988_cfg_tbl);
 	if (board_config < 0) {
 		printk(KERN_INFO "hda_codec: Unknown model for AD1988, trying auto-probe from BIOS...\n");
 		board_config = AD1988_AUTO;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 84d005e..fba3cb1 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4186,6 +4186,8 @@
 static struct snd_pci_quirk alc260_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
 	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
+	SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
+	SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
 	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
 	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
 	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 4c7b039..c94291b 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -60,7 +60,8 @@
 	STAC_D945GTP5,
 	STAC_MACMINI,
 	STAC_MACBOOK,
-	STAC_MACBOOK_PRO,
+	STAC_MACBOOK_PRO_V1,
+	STAC_MACBOOK_PRO_V2,
 	STAC_922X_MODELS
 };
 
@@ -529,7 +530,13 @@
 	0x400000fc, 0x400000fb,
 };
 
-static unsigned int macbook_pro_pin_configs[10] = {
+static unsigned int macbook_pro_v1_pin_configs[10] = {
+	0x0321e230, 0x03a1e020, 0x9017e110, 0x01014010,
+	0x01a19021, 0x0381e021, 0x1345e240, 0x13c5e22e,
+	0x02a19320, 0x400000fb
+};
+
+static unsigned int macbook_pro_v2_pin_configs[10] = {
 	0x0221401f, 0x90a70120, 0x01813024, 0x01014010,
 	0x400000fd, 0x01016011, 0x1345e240, 0x13c5e22e,
 	0x400000fc, 0x400000fb,
@@ -541,7 +548,8 @@
 	[STAC_D945GTP5] = d945gtp5_pin_configs,
 	[STAC_MACMINI] = d945gtp5_pin_configs,
 	[STAC_MACBOOK] = macbook_pin_configs,
-	[STAC_MACBOOK_PRO] = macbook_pro_pin_configs,
+	[STAC_MACBOOK_PRO_V1] = macbook_pro_v1_pin_configs,
+	[STAC_MACBOOK_PRO_V2] = macbook_pro_v2_pin_configs,
 };
 
 static const char *stac922x_models[STAC_922X_MODELS] = {
@@ -550,7 +558,8 @@
 	[STAC_D945GTP3]	= "3stack",
 	[STAC_MACMINI]	= "macmini",
 	[STAC_MACBOOK]	= "macbook",
-	[STAC_MACBOOK_PRO]	= "macbook-pro",
+	[STAC_MACBOOK_PRO_V1]	= "macbook-pro-v1",
+	[STAC_MACBOOK_PRO_V2]	= "macbook-pro",
 };
 
 static struct snd_pci_quirk stac922x_cfg_tbl[] = {
@@ -1600,6 +1609,11 @@
 		for (i = 0; i < cfg->hp_outs; i++)
 			enable_pin_detect(codec, cfg->hp_pins[i],
 					  STAC_HP_EVENT);
+		/* force to enable the first line-out; the others are set up
+		 * in unsol_event
+		 */
+		stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
+					 AC_PINCTL_OUT_EN);
 		stac92xx_auto_init_hp_out(codec);
 		/* fake event to set up pins */
 		codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
@@ -1889,9 +1903,13 @@
 		/* Intel Macs have all same PCI SSID, so we need to check
 		 * codec SSID to distinguish the exact models
 		 */
+		printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id);
 		switch (codec->subsystem_id) {
-		case 0x106b1e00:
-			spec->board_config = STAC_MACBOOK_PRO;
+		case 0x106b0200: /* MacBook Pro first generation */
+			spec->board_config = STAC_MACBOOK_PRO_V1;
+			break;
+		case 0x106b1e00: /* MacBook Pro second generation */
+			spec->board_config = STAC_MACBOOK_PRO_V2;
 			break;
 		}
 	}
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index a289abf..7cf2dcb 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -725,10 +725,11 @@
 static inline void snd_intel8x0_update(struct intel8x0 *chip, struct ichdev *ichdev)
 {
 	unsigned long port = ichdev->reg_offset;
+	unsigned long flags;
 	int status, civ, i, step;
 	int ack = 0;
 
-	spin_lock(&chip->reg_lock);
+	spin_lock_irqsave(&chip->reg_lock, flags);
 	status = igetbyte(chip, port + ichdev->roff_sr);
 	civ = igetbyte(chip, port + ICH_REG_OFF_CIV);
 	if (!(status & ICH_BCIS)) {
@@ -768,7 +769,7 @@
 			ack = 1;
 		}
 	}
-	spin_unlock(&chip->reg_lock);
+	spin_unlock_irqrestore(&chip->reg_lock, flags);
 	if (ack && ichdev->substream) {
 		snd_pcm_period_elapsed(ichdev->substream);
 	}
@@ -2470,7 +2471,10 @@
 	}
 	pci_disable_device(pci);
 	pci_save_state(pci);
-	pci_set_power_state(pci, pci_choose_state(pci, state));
+	/* The call below may disable built-in speaker on some laptops
+	 * after S2RAM.  So, don't touch it.
+	 */
+	/* pci_set_power_state(pci, pci_choose_state(pci, state)); */
 	return 0;
 }
 
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index ec821a5..dccaa4b 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -10,6 +10,8 @@
 
 config SND_SOC
 	tristate "SoC audio support"
+	depends on SND
+	select SND_PCM
 	---help---
 
 	  If you want SoC support, you should say Y here and also to the
diff --git a/sound/soc/at91/Kconfig b/sound/soc/at91/Kconfig
index 5bcf08b..a5b2558 100644
--- a/sound/soc/at91/Kconfig
+++ b/sound/soc/at91/Kconfig
@@ -2,8 +2,7 @@
 
 config SND_AT91_SOC
 	tristate "SoC Audio for the Atmel AT91 System-on-Chip"
-	depends on ARCH_AT91 && SND
-	select SND_PCM
+	depends on ARCH_AT91 && SND_SOC
 	help
 	  Say Y or M if you want to add support for codecs attached to
 	  the AT91 SSC interface. You will also need
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 579e1c8..b9ab3b8 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -2,8 +2,7 @@
 
 config SND_PXA2XX_SOC
 	tristate "SoC Audio for the Intel PXA2xx chip"
-	depends on ARCH_PXA && SND
-	select SND_PCM
+	depends on ARCH_PXA && SND_SOC
 	help
 	  Say Y or M if you want to add support for codecs attached to
 	  the PXA2xx AC97, I2S or SSP interface. You will also need