[kernel] r10228 - in dists/trunk/linux-2.6/debian/patches: bugfix/all series

Maximilian Attems maks at alioth.debian.org
Mon Jan 28 09:31:16 UTC 2008


Author: maks
Date: Mon Jan 28 09:31:14 2008
New Revision: 10228

Log:
update to patch-2.6.24-git4

disable some more conflicting arm patches
(arm merge hasn't happened yet)


Added:
   dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.24-git4
      - copied, changed from r10226, /dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.24-git3
Removed:
   dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.24-git3
Modified:
   dists/trunk/linux-2.6/debian/patches/series/1~experimental.1

Copied: dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.24-git4 (from r10226, /dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.24-git3)
==============================================================================
--- /dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.24-git3	(original)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/all/patch-2.6.24-git4	Mon Jan 28 09:31:14 2008
@@ -952,10 +952,55 @@
  	 Jamie Honan,
  	 Michael Hunold,
 diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
-index 20c4c8b..9b8291f 100644
+index 20c4c8b..2537066 100644
 --- a/Documentation/feature-removal-schedule.txt
 +++ b/Documentation/feature-removal-schedule.txt
-@@ -295,16 +295,6 @@ Who:  linuxppc-dev at ozlabs.org
+@@ -191,15 +191,6 @@ Who:	Kay Sievers <kay.sievers at suse.de>
+ 
+ ---------------------------
+ 
+-What:	i2c_adapter.list
+-When:	July 2007
+-Why:	Superfluous, this list duplicates the one maintained by the driver
+-	core.
+-Who:	Jean Delvare <khali at linux-fr.org>,
+-	David Brownell <dbrownell at users.sourceforge.net>
+-
+----------------------------
+-
+ What:	ACPI procfs interface
+ When:	July 2008
+ Why:	ACPI sysfs conversion should be finished by January 2008.
+@@ -225,14 +216,6 @@ Who:	Len Brown <len.brown at intel.com>
+ 
+ ---------------------------
+ 
+-What:	i2c-ixp2000, i2c-ixp4xx and scx200_i2c drivers
+-When:	September 2007
+-Why:	Obsolete. The new i2c-gpio driver replaces all hardware-specific
+-	I2C-over-GPIO drivers.
+-Who:	Jean Delvare <khali at linux-fr.org>
+-
+----------------------------
+-
+ What:	'time' kernel boot parameter
+ When:	January 2008
+ Why:	replaced by 'printk.time=<value>' so that printk timestamps can be
+@@ -266,13 +249,6 @@ Who:  Tejun Heo <htejun at gmail.com>
+ 
+ ---------------------------
+ 
+-What:	Legacy RTC drivers (under drivers/i2c/chips)
+-When:	November 2007
+-Why:	Obsolete. We have a RTC subsystem with better drivers.
+-Who:	Jean Delvare <khali at linux-fr.org>
+-
+----------------------------
+-
+ What:	iptables SAME target
+ When:	1.1. 2008
+ Files:	net/ipv4/netfilter/ipt_SAME.c, include/linux/netfilter_ipv4/ipt_SAME.h
+@@ -295,16 +271,6 @@ Who:  linuxppc-dev at ozlabs.org
  
  ---------------------------
  
@@ -972,6 +1017,17 @@
  What:   sk98lin network driver
  When:   Feburary 2008
  Why:    In kernel tree version of driver is unmaintained. Sk98lin driver
+@@ -333,3 +299,10 @@ Why:	This driver has been marked obsolete for many years.
+ Who:	Stephen Hemminger <shemminger at linux-foundation.org>
+ 
+ ---------------------------
++
++What:	i2c-i810, i2c-prosavage and i2c-savage4
++When:	May 2008
++Why:	These drivers are superseded by i810fb, intelfb and savagefb.
++Who:	Jean Delvare <khali at linux-fr.org>
++
++---------------------------
 diff --git a/Documentation/filesystems/ocfs2.txt b/Documentation/filesystems/ocfs2.txt
 index ed55238..c318a8b 100644
 --- a/Documentation/filesystems/ocfs2.txt
@@ -1003,6 +1059,170 @@
 +			large, the fs will silently revert it to the default.
 +			Localalloc is not enabled for local mounts.
 +localflocks		This disables cluster aware flock.
+diff --git a/Documentation/i2c/busses/i2c-i801 b/Documentation/i2c/busses/i2c-i801
+index fde4420..3bd9583 100644
+--- a/Documentation/i2c/busses/i2c-i801
++++ b/Documentation/i2c/busses/i2c-i801
+@@ -17,9 +17,8 @@ Supported adapters:
+    Datasheets: Publicly available at the Intel website
+ 
+ Authors: 
+-	Frodo Looijaard <frodol at dds.nl>, 
+-	Philip Edelbrock <phil at netroedge.com>, 
+ 	Mark Studebaker <mdsxyz123 at yahoo.com>
++	Jean Delvare <khali at linux-fr.org>
+ 
+ 
+ Module Parameters
+@@ -62,7 +61,7 @@ Not supported.
+ I2C Block Read Support
+ ----------------------
+ 
+-Not supported at the moment.
++I2C block read is supported on the 82801EB (ICH5) and later chips.
+ 
+ 
+ SMBus 2.0 Support
+diff --git a/Documentation/i2c/busses/i2c-viapro b/Documentation/i2c/busses/i2c-viapro
+index 06b4be3..1405fb6 100644
+--- a/Documentation/i2c/busses/i2c-viapro
++++ b/Documentation/i2c/busses/i2c-viapro
+@@ -10,7 +10,7 @@ Supported adapters:
+   * VIA Technologies, Inc. VT8231, VT8233, VT8233A
+     Datasheet: available on request from VIA
+ 
+-  * VIA Technologies, Inc. VT8235, VT8237R, VT8237A, VT8251
++  * VIA Technologies, Inc. VT8235, VT8237R, VT8237A, VT8237S, VT8251
+     Datasheet: available on request and under NDA from VIA
+ 
+   * VIA Technologies, Inc. CX700
+@@ -46,6 +46,7 @@ Your lspci -n listing must show one of these :
+  device 1106:3177   (VT8235)
+  device 1106:3227   (VT8237R)
+  device 1106:3337   (VT8237A)
++ device 1106:3372   (VT8237S)
+  device 1106:3287   (VT8251)
+  device 1106:8324   (CX700)
+ 
+diff --git a/Documentation/i2c/chips/pcf8575 b/Documentation/i2c/chips/pcf8575
+new file mode 100644
+index 0000000..25f5698
+--- /dev/null
++++ b/Documentation/i2c/chips/pcf8575
+@@ -0,0 +1,72 @@
++About the PCF8575 chip and the pcf8575 kernel driver
++====================================================
++
++The PCF8575 chip is produced by the following manufacturers:
++
++  * Philips NXP
++    http://www.nxp.com/#/pip/cb=[type=product,path=50807/41735/41850,final=PCF8575_3]|pip=[pip=PCF8575_3][0]
++
++  * Texas Instruments
++    http://focus.ti.com/docs/prod/folders/print/pcf8575.html
++
++
++Some vendors sell small PCB's with the PCF8575 mounted on it. You can connect
++such a board to a Linux host via e.g. an USB to I2C interface. Examples of
++PCB boards with a PCF8575:
++
++  * SFE Breakout Board for PCF8575 I2C Expander by RobotShop
++    http://www.robotshop.ca/home/products/robot-parts/electronics/adapters-converters/sfe-pcf8575-i2c-expander-board.html
++
++  * Breakout Board for PCF8575 I2C Expander by Spark Fun Electronics
++    http://www.sparkfun.com/commerce/product_info.php?products_id=8130
++
++
++Description
++-----------
++The PCF8575 chip is a 16-bit I/O expander for the I2C bus. Up to eight of
++these chips can be connected to the same I2C bus. You can find this
++chip on some custom designed hardware, but you won't find it on PC
++motherboards.
++
++The PCF8575 chip consists of a 16-bit quasi-bidirectional port and an I2C-bus
++interface. Each of the sixteen I/O's can be independently used as an input or
++an output. To set up an I/O pin as an input, you have to write a 1 to the
++corresponding output.
++
++For more information please see the datasheet.
++
++
++Detection
++---------
++
++There is no method known to detect whether a chip on a given I2C address is
++a PCF8575 or whether it is any other I2C device. So there are two alternatives
++to let the driver find the installed PCF8575 devices:
++- Load this driver after any other I2C driver for I2C devices with addresses
++  in the range 0x20 .. 0x27.
++- Pass the I2C bus and address of the installed PCF8575 devices explicitly to
++  the driver at load time via the probe=... or force=... parameters.
++
++/sys interface
++--------------
++
++For each address on which a PCF8575 chip was found or forced the following
++files will be created under /sys:
++* /sys/bus/i2c/devices/<bus>-<address>/read
++* /sys/bus/i2c/devices/<bus>-<address>/write
++where bus is the I2C bus number (0, 1, ...) and address is the four-digit
++hexadecimal representation of the 7-bit I2C address of the PCF8575
++(0020 .. 0027).
++
++The read file is read-only. Reading it will trigger an I2C read and will hence
++report the current input state for the pins configured as inputs, and the
++current output value for the pins configured as outputs.
++
++The write file is read-write. Writing a value to it will configure all pins
++as output for which the corresponding bit is zero. Reading the write file will
++return the value last written, or -EAGAIN if no value has yet been written to
++the write file.
++
++On module initialization the configuration of the chip is not changed -- the
++chip is left in the state it was already configured in through either power-up
++or through previous I2C write actions.
+diff --git a/Documentation/i2c/i2c-stub b/Documentation/i2c/i2c-stub
+index 89e69ad..0d8be1c 100644
+--- a/Documentation/i2c/i2c-stub
++++ b/Documentation/i2c/i2c-stub
+@@ -25,6 +25,9 @@ The typical use-case is like this:
+ 	3. load the target sensors chip driver module
+ 	4. observe its behavior in the kernel log
+ 
++There's a script named i2c-stub-from-dump in the i2c-tools package which
++can load register values automatically from a chip dump.
++
+ PARAMETERS:
+ 
+ int chip_addr[10]:
+@@ -32,9 +35,6 @@ int chip_addr[10]:
+ 
+ CAVEATS:
+ 
+-There are independent arrays for byte/data and word/data commands.  Depending
+-on if/how a target driver mixes them, you'll need to be careful.
+-
+ If your target driver polls some byte or word waiting for it to change, the
+ stub could lock it up.  Use i2cset to unlock it.
+ 
+diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients
+index 2c17003..bfb0a55 100644
+--- a/Documentation/i2c/writing-clients
++++ b/Documentation/i2c/writing-clients
+@@ -267,9 +267,9 @@ insmod parameter of the form force_<kind>.
+ Fortunately, as a module writer, you just have to define the `normal_i2c' 
+ parameter. The complete declaration could look like this:
+ 
+-  /* Scan 0x37, and 0x48 to 0x4f */
+-  static unsigned short normal_i2c[] = { 0x37, 0x48, 0x49, 0x4a, 0x4b, 0x4c,
+-                                         0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
++  /* Scan 0x4c to 0x4f */
++  static const unsigned short normal_i2c[] = { 0x4c, 0x4d, 0x4e, 0x4f,
++                                               I2C_CLIENT_END };
+ 
+   /* Magic definition of all other variables and things */
+   I2C_CLIENT_INSMOD;
 diff --git a/Documentation/ide.txt b/Documentation/ide.txt
 index 1d50f23..94e2e3b 100644
 --- a/Documentation/ide.txt
@@ -5084,10 +5304,35 @@
 +参考Satyam Sharma,Johannes Stezenbach,Jesper Juhl,Heikki Orsila,
 +H. Peter Anvin,Philipp Hahn和Stefan Richter的意见改善了本档。
 diff --git a/MAINTAINERS b/MAINTAINERS
-index 2340cfb..59db481 100644
+index 2340cfb..2937122 100644
 --- a/MAINTAINERS
 +++ b/MAINTAINERS
-@@ -2141,6 +2141,15 @@ L:	isdn4linux at listserv.isdn4linux.de
+@@ -758,22 +758,20 @@ S:	Supported
+ 
+ BLACKFIN RTC DRIVER
+ P:	Mike Frysinger
+-M:	michael.frysinger at analog.com
+ M:	vapier.adi at gmail.com
+ L:	uclinux-dist-devel at blackfin.uclinux.org (subscribers-only)
+ W:	http://blackfin.uclinux.org
+ S:	Supported
+ 
+ BLACKFIN SERIAL DRIVER
+-P:	Aubrey Li
+-M:	aubrey.li at analog.com
++P:	Sonic Zhang
++M:	sonic.zhang at analog.com
+ L:	uclinux-dist-devel at blackfin.uclinux.org (subscribers-only)
+ W:	http://blackfin.uclinux.org
+ S:	Supported
+ 
+ BLACKFIN WATCHDOG DRIVER
+ P:	Mike Frysinger
+-M:	michael.frysinger at analog.com
+ M:	vapier.adi at gmail.com
+ L:	uclinux-dist-devel at blackfin.uclinux.org (subscribers-only)
+ W:	http://blackfin.uclinux.org
+@@ -2141,6 +2139,15 @@ L:	isdn4linux at listserv.isdn4linux.de
  W:	http://www.melware.de
  S:	Maintained
  
@@ -5103,7 +5348,7 @@
  JOURNALLING FLASH FILE SYSTEM V2 (JFFS2)
  P:	David Woodhouse
  M:	dwmw2 at infradead.org
-@@ -3260,8 +3269,10 @@ W:	http://www.ibm.com/developerworks/linux/linux390/
+@@ -3260,8 +3267,10 @@ W:	http://www.ibm.com/developerworks/linux/linux390/
  S:	Supported
  
  S390 ZFCP DRIVER
@@ -5169,6 +5414,310 @@
  	.suspend	= irq_suspend,
  	.resume		= irq_resume,
  };
+diff --git a/arch/arm/mach-ixp4xx/avila-setup.c b/arch/arm/mach-ixp4xx/avila-setup.c
+index d59b8dc..e38f45f 100644
+--- a/arch/arm/mach-ixp4xx/avila-setup.c
++++ b/arch/arm/mach-ixp4xx/avila-setup.c
+@@ -18,6 +18,7 @@
+ #include <linux/tty.h>
+ #include <linux/serial_8250.h>
+ #include <linux/slab.h>
++#include <linux/i2c-gpio.h>
+ 
+ #include <asm/types.h>
+ #include <asm/setup.h>
+@@ -47,18 +48,17 @@ static struct platform_device avila_flash = {
+ 	.resource	= &avila_flash_resource,
+ };
+ 
+-static struct ixp4xx_i2c_pins avila_i2c_gpio_pins = {
++static struct i2c_gpio_platform_data avila_i2c_gpio_data = {
+ 	.sda_pin	= AVILA_SDA_PIN,
+ 	.scl_pin	= AVILA_SCL_PIN,
+ };
+ 
+-static struct platform_device avila_i2c_controller = {
+-	.name		= "IXP4XX-I2C",
++static struct platform_device avila_i2c_gpio = {
++	.name		= "i2c-gpio",
+ 	.id		= 0,
+-	.dev		= {
+-		.platform_data = &avila_i2c_gpio_pins,
++	.dev	 = {
++		.platform_data	= &avila_i2c_gpio_data,
+ 	},
+-	.num_resources	= 0
+ };
+ 
+ static struct resource avila_uart_resources[] = {
+@@ -133,7 +133,7 @@ static struct platform_device avila_pata = {
+ };
+ 
+ static struct platform_device *avila_devices[] __initdata = {
+-	&avila_i2c_controller,
++	&avila_i2c_gpio,
+ 	&avila_flash,
+ 	&avila_uart
+ };
+diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c
+index 1e75e10..c473d40 100644
+--- a/arch/arm/mach-ixp4xx/dsmg600-setup.c
++++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c
+@@ -14,6 +14,7 @@
+ #include <linux/kernel.h>
+ #include <linux/serial.h>
+ #include <linux/serial_8250.h>
++#include <linux/i2c-gpio.h>
+ 
+ #include <asm/mach-types.h>
+ #include <asm/mach/arch.h>
+@@ -37,15 +38,17 @@ static struct platform_device dsmg600_flash = {
+ 	.resource		= &dsmg600_flash_resource,
+ };
+ 
+-static struct ixp4xx_i2c_pins dsmg600_i2c_gpio_pins = {
++static struct i2c_gpio_platform_data dsmg600_i2c_gpio_data = {
+ 	.sda_pin		= DSMG600_SDA_PIN,
+ 	.scl_pin		= DSMG600_SCL_PIN,
+ };
+ 
+-static struct platform_device dsmg600_i2c_controller = {
+-	.name			= "IXP4XX-I2C",
++static struct platform_device dsmg600_i2c_gpio = {
++	.name			= "i2c-gpio",
+ 	.id			= 0,
+-	.dev.platform_data	= &dsmg600_i2c_gpio_pins,
++	.dev	 = {
++		.platform_data	= &dsmg600_i2c_gpio_data,
++	},
+ };
+ 
+ #ifdef CONFIG_LEDS_CLASS
+@@ -116,7 +119,7 @@ static struct platform_device dsmg600_uart = {
+ };
+ 
+ static struct platform_device *dsmg600_devices[] __initdata = {
+-	&dsmg600_i2c_controller,
++	&dsmg600_i2c_gpio,
+ 	&dsmg600_flash,
+ };
+ 
+diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
+index d5008d8..e89070d 100644
+--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c
++++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
+@@ -15,6 +15,7 @@
+ #include <linux/tty.h>
+ #include <linux/serial_8250.h>
+ #include <linux/slab.h>
++#include <linux/i2c-gpio.h>
+ #include <linux/io.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/nand.h>
+@@ -120,18 +121,17 @@ static struct platform_device ixdp425_flash_nand = {
+ };
+ #endif	/* CONFIG_MTD_NAND_PLATFORM */
+ 
+-static struct ixp4xx_i2c_pins ixdp425_i2c_gpio_pins = {
++static struct i2c_gpio_platform_data ixdp425_i2c_gpio_data = {
+ 	.sda_pin	= IXDP425_SDA_PIN,
+ 	.scl_pin	= IXDP425_SCL_PIN,
+ };
+ 
+-static struct platform_device ixdp425_i2c_controller = {
+-	.name		= "IXP4XX-I2C",
++static struct platform_device ixdp425_i2c_gpio = {
++	.name		= "i2c-gpio",
+ 	.id		= 0,
+-	.dev		= {
+-		.platform_data = &ixdp425_i2c_gpio_pins,
++	.dev	 = {
++		.platform_data	= &ixdp425_i2c_gpio_data,
+ 	},
+-	.num_resources	= 0
+ };
+ 
+ static struct resource ixdp425_uart_resources[] = {
+@@ -178,7 +178,7 @@ static struct platform_device ixdp425_uart = {
+ };
+ 
+ static struct platform_device *ixdp425_devices[] __initdata = {
+-	&ixdp425_i2c_controller,
++	&ixdp425_i2c_gpio,
+ 	&ixdp425_flash,
+ #if defined(CONFIG_MTD_NAND_PLATFORM) || \
+     defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
+diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c
+index 78a1741..54d884f 100644
+--- a/arch/arm/mach-ixp4xx/nas100d-setup.c
++++ b/arch/arm/mach-ixp4xx/nas100d-setup.c
+@@ -16,6 +16,7 @@
+ #include <linux/serial.h>
+ #include <linux/serial_8250.h>
+ #include <linux/leds.h>
++#include <linux/i2c-gpio.h>
+ 
+ #include <asm/mach-types.h>
+ #include <asm/mach/arch.h>
+@@ -68,16 +69,17 @@ static struct platform_device nas100d_leds = {
+ };
+ #endif
+ 
+-static struct ixp4xx_i2c_pins nas100d_i2c_gpio_pins = {
++static struct i2c_gpio_platform_data nas100d_i2c_gpio_data = {
+ 	.sda_pin		= NAS100D_SDA_PIN,
+ 	.scl_pin		= NAS100D_SCL_PIN,
+ };
+ 
+-static struct platform_device nas100d_i2c_controller = {
+-	.name			= "IXP4XX-I2C",
++static struct platform_device nas100d_i2c_gpio = {
++	.name			= "i2c-gpio",
+ 	.id			= 0,
+-	.dev.platform_data	= &nas100d_i2c_gpio_pins,
+-	.num_resources		= 0,
++	.dev	 = {
++		.platform_data	= &nas100d_i2c_gpio_data,
++	},
+ };
+ 
+ static struct resource nas100d_uart_resources[] = {
+@@ -124,7 +126,7 @@ static struct platform_device nas100d_uart = {
+ };
+ 
+ static struct platform_device *nas100d_devices[] __initdata = {
+-	&nas100d_i2c_controller,
++	&nas100d_i2c_gpio,
+ 	&nas100d_flash,
+ #ifdef CONFIG_LEDS_IXP4XX
+ 	&nas100d_leds,
+diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c
+index 9bf8ccb..77277d2 100644
+--- a/arch/arm/mach-ixp4xx/nslu2-setup.c
++++ b/arch/arm/mach-ixp4xx/nslu2-setup.c
+@@ -18,6 +18,7 @@
+ #include <linux/serial.h>
+ #include <linux/serial_8250.h>
+ #include <linux/leds.h>
++#include <linux/i2c-gpio.h>
+ 
+ #include <asm/mach-types.h>
+ #include <asm/mach/arch.h>
+@@ -41,7 +42,7 @@ static struct platform_device nslu2_flash = {
+ 	.resource		= &nslu2_flash_resource,
+ };
+ 
+-static struct ixp4xx_i2c_pins nslu2_i2c_gpio_pins = {
++static struct i2c_gpio_platform_data nslu2_i2c_gpio_data = {
+ 	.sda_pin		= NSLU2_SDA_PIN,
+ 	.scl_pin		= NSLU2_SCL_PIN,
+ };
+@@ -82,11 +83,12 @@ static struct platform_device nslu2_leds = {
+ };
+ #endif
+ 
+-static struct platform_device nslu2_i2c_controller = {
+-	.name			= "IXP4XX-I2C",
++static struct platform_device nslu2_i2c_gpio = {
++	.name			= "i2c-gpio",
+ 	.id			= 0,
+-	.dev.platform_data	= &nslu2_i2c_gpio_pins,
+-	.num_resources		= 0,
++	.dev	 = {
++		.platform_data	= &nslu2_i2c_gpio_data,
++	},
+ };
+ 
+ static struct platform_device nslu2_beeper = {
+@@ -139,7 +141,7 @@ static struct platform_device nslu2_uart = {
+ };
+ 
+ static struct platform_device *nslu2_devices[] __initdata = {
+-	&nslu2_i2c_controller,
++	&nslu2_i2c_gpio,
+ 	&nslu2_flash,
+ 	&nslu2_beeper,
+ #ifdef CONFIG_LEDS_IXP4XX
+diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
+index 1306812..9393824 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/i2c/tps65010.h>
+ 
+ #include <asm/hardware.h>
+ #include <asm/gpio.h>
+@@ -36,7 +37,6 @@
+ #include <asm/mach/flash.h>
+ #include <asm/mach/map.h>
+ 
+-#include <asm/arch/tps65010.h>
+ #include <asm/arch/mux.h>
+ #include <asm/arch/tc.h>
+ #include <asm/arch/irda.h>
+diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
+index 4f84ae2..978cdab 100644
+--- a/arch/arm/mach-omap1/board-h3.c
++++ b/arch/arm/mach-omap1/board-h3.c
+@@ -26,6 +26,7 @@
+ #include <linux/mtd/nand.h>
+ #include <linux/mtd/partitions.h>
+ #include <linux/input.h>
++#include <linux/i2c/tps65010.h>
+ 
+ #include <asm/setup.h>
+ #include <asm/page.h>
+@@ -37,7 +38,6 @@
+ #include <asm/mach/flash.h>
+ #include <asm/mach/map.h>
+ 
+-#include <asm/arch/tps65010.h>
+ #include <asm/arch/gpioexpander.h>
+ #include <asm/arch/irqs.h>
+ #include <asm/arch/mux.h>
+diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
+index 5db182d..5b575e6 100644
+--- a/arch/arm/mach-omap1/board-osk.c
++++ b/arch/arm/mach-omap1/board-osk.c
+@@ -37,6 +37,8 @@
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
+ 
++#include <linux/i2c/tps65010.h>
++
+ #include <asm/hardware.h>
+ #include <asm/gpio.h>
+ 
+@@ -46,7 +48,6 @@
+ #include <asm/mach/flash.h>
+ 
+ #include <asm/arch/usb.h>
+-#include <asm/arch/tps65010.h>
+ #include <asm/arch/mux.h>
+ #include <asm/arch/tc.h>
+ #include <asm/arch/common.h>
+diff --git a/arch/arm/mach-omap1/leds-osk.c b/arch/arm/mach-omap1/leds-osk.c
+index 86de303..6939d5e 100644
+--- a/arch/arm/mach-omap1/leds-osk.c
++++ b/arch/arm/mach-omap1/leds-osk.c
+@@ -5,13 +5,13 @@
+  */
+ #include <linux/init.h>
+ #include <linux/workqueue.h>
++#include <linux/i2c/tps65010.h>
+ 
+ #include <asm/hardware.h>
+ #include <asm/leds.h>
+ #include <asm/system.h>
+ 
+ #include <asm/arch/gpio.h>
+-#include <asm/arch/tps65010.h>
+ 
+ #include "leds.h"
+ 
 diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
 index 3bf01e2..d9805e3 100644
 --- a/arch/arm/mach-omap1/pm.c
@@ -5223,6 +5772,19 @@
  
  	if (cpu_is_omap16xx()) {
  		/* configure LOW_PWR pin */
+diff --git a/arch/arm/mach-pxa/akita-ioexp.c b/arch/arm/mach-pxa/akita-ioexp.c
+index 12d2fe0..254892a 100644
+--- a/arch/arm/mach-pxa/akita-ioexp.c
++++ b/arch/arm/mach-pxa/akita-ioexp.c
+@@ -29,7 +29,7 @@
+ #define MAX7310_TIMEOUT  0x04
+ 
+ /* Addresses to scan */
+-static unsigned short normal_i2c[] = { 0x18, I2C_CLIENT_END };
++static const unsigned short normal_i2c[] = { 0x18, I2C_CLIENT_END };
+ 
+ /* I2C Magic */
+ I2C_CLIENT_INSMOD;
 diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c
 index 177664c..a163492 100644
 --- a/arch/arm/mach-pxa/cm-x270.c
@@ -5275,6 +5837,30 @@
  	.resume = mainstone_irq_resume,
  };
  
+diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
+index 8e126e6..57efebd 100644
+--- a/arch/arm/mach-pxa/pxa27x.c
++++ b/arch/arm/mach-pxa/pxa27x.c
+@@ -24,6 +24,7 @@
+ #include <asm/arch/ohci.h>
+ #include <asm/arch/pm.h>
+ #include <asm/arch/dma.h>
++#include <asm/arch/i2c.h>
+ 
+ #include "generic.h"
+ #include "devices.h"
+@@ -423,6 +424,11 @@ struct platform_device pxa27x_device_i2c_power = {
+ 	.num_resources	= ARRAY_SIZE(i2c_power_resources),
+ };
+ 
++void __init pxa_set_i2c_power_info(struct i2c_pxa_platform_data *info)
++{
++	pxa27x_device_i2c_power.dev.platform_data = info;
++}
++
+ static struct platform_device *devices[] __initdata = {
+ 	&pxa_device_mci,
+ 	&pxa_device_udc,
 diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
 index e580303..0e79919 100644
 --- a/arch/arm/mach-s3c2410/s3c2410.c
@@ -14483,5069 +15069,13560 @@
 +{
 +
 +}
-diff --git a/arch/cris/arch-v32/drivers/iop_fw_load.c b/arch/cris/arch-v32/drivers/iop_fw_load.c
-index 11f9895..f4bdc1d 100644
---- a/arch/cris/arch-v32/drivers/iop_fw_load.c
-+++ b/arch/cris/arch-v32/drivers/iop_fw_load.c
-@@ -20,6 +20,9 @@
+diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
+index 25232ba..fc7ca86 100644
+--- a/arch/blackfin/Kconfig
++++ b/arch/blackfin/Kconfig
+@@ -85,11 +85,26 @@ config BF522
+ 	help
+ 	  BF522 Processor Support.
  
- #define IOP_TIMEOUT 100
++config BF523
++	bool "BF523"
++	help
++	  BF523 Processor Support.
++
++config BF524
++	bool "BF524"
++	help
++	  BF524 Processor Support.
++
+ config BF525
+ 	bool "BF525"
+ 	help
+ 	  BF525 Processor Support.
  
-+#error "This driver is broken with regard to its driver core usage."
-+#error "Please contact <greg at kroah.com> for details on how to fix it properly."
++config BF526
++	bool "BF526"
++	help
++	  BF526 Processor Support.
 +
- static struct device iop_spu_device[2] = {
- 	{ .bus_id =     "iop-spu0", },
- 	{ .bus_id =     "iop-spu1", },
-@@ -192,6 +195,13 @@ int iop_start_mpu(unsigned int start_addr)
+ config BF527
+ 	bool "BF527"
+ 	help
+@@ -198,7 +213,7 @@ endchoice
  
- static int __init iop_fw_load_init(void)
- {
-+#if 0
-+	/*
-+	 * static struct devices can not be added directly to sysfs by ignoring
-+	 * the driver model infrastructure.  To fix this properly, please use
-+	 * the platform_bus to register these devices to be able to properly
-+	 * use the firmware infrastructure.
-+	 */
- 	device_initialize(&iop_spu_device[0]);
- 	kobject_set_name(&iop_spu_device[0].kobj, "iop-spu0");
- 	kobject_add(&iop_spu_device[0].kobj);
-@@ -201,6 +211,7 @@ static int __init iop_fw_load_init(void)
- 	device_initialize(&iop_mpu_device);
- 	kobject_set_name(&iop_mpu_device.kobj, "iop-mpu");
- 	kobject_add(&iop_mpu_device.kobj);
-+#endif
- 	return 0;
- }
+ config BF52x
+ 	bool
+-	depends on (BF522 || BF525 || BF527)
++	depends on (BF522 || BF523 || BF524 || BF525 || BF526 || BF527)
+ 	default y
  
-diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
-index 4ac2b1f..86028c6 100644
---- a/arch/ia64/kernel/setup.c
-+++ b/arch/ia64/kernel/setup.c
-@@ -71,8 +71,6 @@ unsigned long __per_cpu_offset[NR_CPUS];
- EXPORT_SYMBOL(__per_cpu_offset);
- #endif
+ config BF53x
+@@ -253,11 +268,6 @@ config MEM_MT48LC32M16A2TG_75
+ 	depends on (BFIN527_EZKIT)
+ 	default y
  
--extern void ia64_setup_printk_clock(void);
--
- DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info);
- DEFINE_PER_CPU(unsigned long, local_per_cpu_offset);
- unsigned long ia64_cycles_per_usec;
-@@ -507,8 +505,6 @@ setup_arch (char **cmdline_p)
- 	/* process SAL system table: */
- 	ia64_sal_init(__va(efi.sal_systab));
+-config BFIN_SHARED_FLASH_ENET
+-	bool
+-	depends on (BFIN533_STAMP)
+-	default y
+-
+ source "arch/blackfin/mach-bf527/Kconfig"
+ source "arch/blackfin/mach-bf533/Kconfig"
+ source "arch/blackfin/mach-bf561/Kconfig"
+@@ -317,7 +327,7 @@ config VCO_MULT
+ 	range 1 64
+ 	default "22" if BFIN533_EZKIT
+ 	default "45" if BFIN533_STAMP
+-	default "20" if (BFIN537_STAMP || BFIN527_EZKIT)
++	default "20" if (BFIN537_STAMP || BFIN527_EZKIT || BFIN548_EZKIT)
+ 	default "22" if BFIN533_BLUETECHNIX_CM
+ 	default "20" if BFIN537_BLUETECHNIX_CM
+ 	default "20" if BFIN561_BLUETECHNIX_CM
+@@ -354,7 +364,7 @@ config SCLK_DIV
+ 	range 1 15
+ 	default 5 if BFIN533_EZKIT
+ 	default 5 if BFIN533_STAMP
+-	default 4 if (BFIN537_STAMP || BFIN527_EZKIT)
++	default 4 if (BFIN537_STAMP || BFIN527_EZKIT || BFIN548_EZKIT)
+ 	default 5 if BFIN533_BLUETECHNIX_CM
+ 	default 4 if BFIN537_BLUETECHNIX_CM
+ 	default 4 if BFIN561_BLUETECHNIX_CM
+@@ -371,7 +381,10 @@ config SCLK_DIV
+ config MAX_VCO_HZ
+ 	int
+ 	default 600000000 if BF522
++	default 400000000 if BF523
++	default 400000000 if BF524
+ 	default 600000000 if BF525
++	default 400000000 if BF526
+ 	default 600000000 if BF527
+ 	default 400000000 if BF531
+ 	default 400000000 if BF532
+@@ -383,6 +396,8 @@ config MAX_VCO_HZ
+ 	default 533333333 if BF539
+ 	default 600000000 if BF542
+ 	default 533333333 if BF544
++	default 600000000 if BF547
++	default 600000000 if BF548
+ 	default 533333333 if BF549
+ 	default 600000000 if BF561
+ 
+@@ -409,6 +424,7 @@ config MEM_SIZE
+ 	default  32 if BFIN533_EZKIT
+ 	default  64 if BFIN527_EZKIT
+ 	default  64 if BFIN537_STAMP
++	default  64 if BFIN548_EZKIT
+ 	default  64 if BFIN561_EZKIT
+ 	default 128 if BFIN533_STAMP
+ 	default  64 if PNAV10
+@@ -416,6 +432,7 @@ config MEM_SIZE
+ 
+ config MEM_ADD_WIDTH
+ 	int "SDRAM Memory Address Width"
++	depends on (!BF54x)
+ 	default  9 if BFIN533_EZKIT
+ 	default  9 if BFIN561_EZKIT
+ 	default  9 if H8606_HVSISTEMAS
+@@ -424,6 +441,19 @@ config MEM_ADD_WIDTH
+ 	default 11 if BFIN533_STAMP
+ 	default 10 if PNAV10
  
--	ia64_setup_printk_clock();
++
++choice
++	prompt "DDR SDRAM Chip Type"
++	depends on BFIN548_EZKIT
++	default MEM_MT46V32M16_5B
++
++config MEM_MT46V32M16_6T
++        bool "MT46V32M16_6T"
++
++config MEM_MT46V32M16_5B
++        bool "MT46V32M16_5B"
++endchoice
++
+ config ENET_FLASH_PIN
+ 	int "PF port/pin used for flash and ethernet sharing"
+ 	depends on (BFIN533_STAMP)
+@@ -448,40 +478,6 @@ config BOOT_LOAD
+ 	  memory region is used to capture NULL pointer references as well
+ 	  as some core kernel functions.
+ 
+-comment "LED Status Indicators"
+-	depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM)
+-
+-config BFIN_ALIVE_LED
+-	bool "Enable Board Alive"
+-	depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM)
+-	default n
+-	help
+-	  Blink the LEDs you select when the kernel is running.  Helps detect
+-	  a hung kernel.
 -
- #ifdef CONFIG_SMP
- 	cpu_physical_id(0) = hard_smp_processor_id();
- #endif
-diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
-index 2bb8421..3ab0427 100644
---- a/arch/ia64/kernel/time.c
-+++ b/arch/ia64/kernel/time.c
-@@ -344,33 +344,6 @@ udelay (unsigned long usecs)
- }
- EXPORT_SYMBOL(udelay);
- 
--static unsigned long long ia64_itc_printk_clock(void)
--{
--	if (ia64_get_kr(IA64_KR_PER_CPU_DATA))
--		return sched_clock();
--	return 0;
--}
+-config BFIN_ALIVE_LED_NUM
+-	int "LED"
+-	depends on BFIN_ALIVE_LED
+-	range 1 3 if BFIN533_STAMP
+-	default "3" if BFIN533_STAMP
+-	help
+-	  Select the LED (marked on the board) for you to blink.
 -
--static unsigned long long ia64_default_printk_clock(void)
--{
--	return (unsigned long long)(jiffies_64 - INITIAL_JIFFIES) *
--		(1000000000/HZ);
--}
+-config BFIN_IDLE_LED
+-	bool "Enable System Load/Idle LED"
+-	depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM)
+-	default n
+-	help
+-	  Blinks the LED you select when to determine kernel load.
 -
--unsigned long long (*ia64_printk_clock)(void) = &ia64_default_printk_clock;
+-config BFIN_IDLE_LED_NUM
+-	int "LED"
+-	depends on BFIN_IDLE_LED
+-	range 1 3 if BFIN533_STAMP
+-	default "2" if BFIN533_STAMP
+-	help
+-	  Select the LED (marked on the board) for you to blink.
 -
--unsigned long long printk_clock(void)
--{
--	return ia64_printk_clock();
--}
+ choice
+ 	prompt "Blackfin Exception Scratch Register"
+ 	default BFIN_SCRATCH_REG_RETN
+@@ -528,41 +524,6 @@ config BFIN_SCRATCH_REG_CYCLES
+ 
+ endchoice
+ 
+-#
+-# Sorry - but you need to put the hex address here -
+-#
 -
--void __init
--ia64_setup_printk_clock(void)
--{
--	if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT))
--		ia64_printk_clock = ia64_itc_printk_clock;
--}
+-# Flag Data register
+-config BFIN_ALIVE_LED_PORT
+-	hex
+-	default 0xFFC00700 if (BFIN533_STAMP)
+-
+-# Peripheral Flag Direction Register
+-config BFIN_ALIVE_LED_DPORT
+-	hex
+-	default 0xFFC00730 if (BFIN533_STAMP)
+-
+-config BFIN_ALIVE_LED_PIN
+-	hex
+-	default 0x04 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 1)
+-	default 0x08 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 2)
+-	default 0x10 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 3)
+-
+-config BFIN_IDLE_LED_PORT
+-	hex
+-	default 0xFFC00700 if (BFIN533_STAMP)
+-
+-# Peripheral Flag Direction Register
+-config BFIN_IDLE_LED_DPORT
+-	hex
+-	default 0xFFC00730 if (BFIN533_STAMP)
+-
+-config BFIN_IDLE_LED_PIN
+-	hex
+-	default 0x04 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 1)
+-	default 0x08 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 2)
+-	default 0x10 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 3)
 -
- /* IA64 doesn't cache the timezone */
- void update_vsyscall_tz(void)
- {
-diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
-index 14261fe..a2484fc 100644
---- a/arch/ia64/kernel/topology.c
-+++ b/arch/ia64/kernel/topology.c
-@@ -354,27 +354,27 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
- 	if (unlikely(retval < 0))
- 		return retval;
+ endmenu
  
--	all_cpu_cache_info[cpu].kobj.parent = &sys_dev->kobj;
--	kobject_set_name(&all_cpu_cache_info[cpu].kobj, "%s", "cache");
--	all_cpu_cache_info[cpu].kobj.ktype = &cache_ktype_percpu_entry;
--	retval = kobject_register(&all_cpu_cache_info[cpu].kobj);
-+	retval = kobject_init_and_add(&all_cpu_cache_info[cpu].kobj,
-+				      &cache_ktype_percpu_entry, &sys_dev->kobj,
-+				      "%s", "cache");
  
- 	for (i = 0; i < all_cpu_cache_info[cpu].num_cache_leaves; i++) {
- 		this_object = LEAF_KOBJECT_PTR(cpu,i);
--		this_object->kobj.parent = &all_cpu_cache_info[cpu].kobj;
--		kobject_set_name(&(this_object->kobj), "index%1lu", i);
--		this_object->kobj.ktype = &cache_ktype;
--		retval = kobject_register(&(this_object->kobj));
-+		retval = kobject_init_and_add(&(this_object->kobj),
-+					      &cache_ktype,
-+					      &all_cpu_cache_info[cpu].kobj,
-+					      "index%1lu", i);
- 		if (unlikely(retval)) {
- 			for (j = 0; j < i; j++) {
--				kobject_unregister(
--					&(LEAF_KOBJECT_PTR(cpu,j)->kobj));
-+				kobject_put(&(LEAF_KOBJECT_PTR(cpu,j)->kobj));
- 			}
--			kobject_unregister(&all_cpu_cache_info[cpu].kobj);
-+			kobject_put(&all_cpu_cache_info[cpu].kobj);
- 			cpu_cache_sysfs_exit(cpu);
- 			break;
- 		}
-+		kobject_uevent(&(this_object->kobj), KOBJ_ADD);
- 	}
-+	kobject_uevent(&all_cpu_cache_info[cpu].kobj, KOBJ_ADD);
- 	return retval;
- }
+@@ -799,6 +760,15 @@ config L1_MAX_PIECE
+ 	  Set the max memory pieces for the L1 SRAM allocation algorithm.
+ 	  Min value is 16. Max value is 1024.
  
-@@ -385,10 +385,10 @@ static int __cpuinit cache_remove_dev(struct sys_device * sys_dev)
- 	unsigned long i;
++
++config MPU
++	bool "Enable the memory protection unit (EXPERIMENTAL)"
++	default n
++	help
++	  Use the processor's MPU to protect applications from accessing
++	  memory they do not own.  This comes at a performance penalty
++	  and is recommended only for debugging.
++
+ comment "Asynchonous Memory Configuration"
+ 
+ menu "EBIU_AMGCTL Global Control"
+@@ -808,7 +778,6 @@ config C_AMCKEN
+ 
+ config C_CDPRIO
+ 	bool "DMA has priority over core for ext. accesses"
+-	depends on !BF54x
+ 	default n
+ 
+ config C_B0PEN
+@@ -949,8 +918,10 @@ endchoice
+ config PM_WAKEUP_SIC_IWR
+ 	hex "Wakeup Events (SIC_IWR)"
+ 	depends on PM_WAKEUP_GPIO_BY_SIC_IWR
+-	default 0x80000000 if (BF537 || BF536 || BF534)
+-	default 0x100000 if (BF533 || BF532 || BF531)
++	default 0x8 if (BF537 || BF536 || BF534)
++	default 0x80 if (BF533 || BF532 || BF531)
++	default 0x80 if (BF54x)
++	default 0x80 if (BF52x)
+ 
+ config PM_WAKEUP_GPIO_NUMBER
+ 	int "Wakeup GPIO number"
+diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile
+index c47e000..0edc402 100644
+--- a/arch/blackfin/Makefile
++++ b/arch/blackfin/Makefile
+@@ -21,7 +21,10 @@ KBUILD_DEFCONFIG := BF537-STAMP_defconfig
+ 
+ # setup the machine name and the machine dependent settings
+ machine-$(CONFIG_BF522) := bf527
++machine-$(CONFIG_BF523) := bf527
++machine-$(CONFIG_BF524) := bf527
+ machine-$(CONFIG_BF525) := bf527
++machine-$(CONFIG_BF526) := bf527
+ machine-$(CONFIG_BF527) := bf527
+ machine-$(CONFIG_BF531) := bf533
+ machine-$(CONFIG_BF532) := bf533
+@@ -39,7 +42,10 @@ MACHINE := $(machine-y)
+ export MACHINE
+ 
+ cpu-$(CONFIG_BF522) := bf522
++cpu-$(CONFIG_BF523) := bf523
++cpu-$(CONFIG_BF524) := bf524
+ cpu-$(CONFIG_BF525) := bf525
++cpu-$(CONFIG_BF526) := bf526
+ cpu-$(CONFIG_BF527) := bf527
+ cpu-$(CONFIG_BF531) := bf531
+ cpu-$(CONFIG_BF532) := bf532
+@@ -76,6 +82,12 @@ core-y   += arch/$(ARCH)/mach-$(MACHINE)/
+ core-y   += arch/$(ARCH)/mach-$(MACHINE)/boards/
+ endif
  
- 	for (i = 0; i < all_cpu_cache_info[cpu].num_cache_leaves; i++)
--		kobject_unregister(&(LEAF_KOBJECT_PTR(cpu,i)->kobj));
-+		kobject_put(&(LEAF_KOBJECT_PTR(cpu,i)->kobj));
++ifeq ($(CONFIG_MPU),y)
++core-y	+= arch/$(ARCH)/kernel/cplb-mpu/
++else
++core-y	+= arch/$(ARCH)/kernel/cplb-nompu/
++endif
++
+ libs-y   += arch/$(ARCH)/lib/
  
- 	if (all_cpu_cache_info[cpu].kobj.parent) {
--		kobject_unregister(&all_cpu_cache_info[cpu].kobj);
-+		kobject_put(&all_cpu_cache_info[cpu].kobj);
- 		memset(&all_cpu_cache_info[cpu].kobj,
- 			0,
- 			sizeof(struct kobject));
-diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
-index 1f38a3a..bb1d249 100644
---- a/arch/ia64/sn/kernel/setup.c
-+++ b/arch/ia64/sn/kernel/setup.c
-@@ -64,7 +64,6 @@ extern void sn_timer_init(void);
- extern unsigned long last_time_offset;
- extern void (*ia64_mark_idle) (int);
- extern void snidle(int);
--extern unsigned long long (*ia64_printk_clock)(void);
+ drivers-$(CONFIG_OPROFILE) += arch/$(ARCH)/oprofile/
+diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig
+index fa6eb4e..d59ee15 100644
+--- a/arch/blackfin/configs/BF527-EZKIT_defconfig
++++ b/arch/blackfin/configs/BF527-EZKIT_defconfig
+@@ -1,6 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.22.12
++# Linux kernel version: 2.6.22.14
++# Thu Nov 29 17:32:47 2007
+ #
+ # CONFIG_MMU is not set
+ # CONFIG_FPU is not set
+@@ -153,8 +154,8 @@ CONFIG_BFIN527_EZKIT=y
+ CONFIG_BF527_SPORT0_PORTG=y
+ CONFIG_BF527_SPORT0_TSCLK_PG10=y
+ # CONFIG_BF527_SPORT0_TSCLK_PG14 is not set
+-# CONFIG_BF527_UART1_PORTF is not set
+-CONFIG_BF527_UART1_PORTG=y
++CONFIG_BF527_UART1_PORTF=y
++# CONFIG_BF527_UART1_PORTG is not set
+ # CONFIG_BF527_NAND_D_PORTF is not set
+ CONFIG_BF527_NAND_D_PORTH=y
+ 
+@@ -232,7 +233,7 @@ CONFIG_CLKIN_HZ=25000000
+ # CONFIG_BFIN_KERNEL_CLOCK is not set
+ CONFIG_MAX_VCO_HZ=600000000
+ CONFIG_MIN_VCO_HZ=50000000
+-CONFIG_MAX_SCLK_HZ=133000000
++CONFIG_MAX_SCLK_HZ=133333333
+ CONFIG_MIN_SCLK_HZ=27000000
  
- unsigned long sn_rtc_cycles_per_second;
- EXPORT_SYMBOL(sn_rtc_cycles_per_second);
-@@ -360,14 +359,6 @@ sn_scan_pcdp(void)
+ #
+@@ -626,8 +627,8 @@ CONFIG_BFIN_MAC_RMII=y
+ # CONFIG_SMSC911X is not set
+ # CONFIG_DM9000 is not set
+ CONFIG_NETDEV_1000=y
+-CONFIG_NETDEV_10000=y
+ # CONFIG_AX88180 is not set
++CONFIG_NETDEV_10000=y
  
- static unsigned long sn2_rtc_initial;
+ #
+ # Wireless LAN
+@@ -1183,7 +1184,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
+ #
+ # CONFIG_PRINTK_TIME is not set
+ CONFIG_ENABLE_MUST_CHECK=y
+-CONFIG_MAGIC_SYSRQ=y
++# CONFIG_MAGIC_SYSRQ is not set
+ # CONFIG_UNUSED_SYMBOLS is not set
+ CONFIG_DEBUG_FS=y
+ # CONFIG_HEADERS_CHECK is not set
+@@ -1208,7 +1209,7 @@ CONFIG_ACCESS_CHECK=y
+ # CONFIG_KEYS is not set
+ CONFIG_SECURITY=y
+ # CONFIG_SECURITY_NETWORK is not set
+-CONFIG_SECURITY_CAPABILITIES=y
++CONFIG_SECURITY_CAPABILITIES=m
  
--static unsigned long long ia64_sn2_printk_clock(void)
--{
--	unsigned long rtc_now = rtc_time();
--
--	return (rtc_now - sn2_rtc_initial) *
--		(1000000000 / sn_rtc_cycles_per_second);
--}
--
- /**
-  * sn_setup - SN platform setup routine
-  * @cmdline_p: kernel command line
-@@ -468,8 +459,6 @@ void __init sn_setup(char **cmdline_p)
+ #
+ # Cryptographic options
+@@ -1219,7 +1220,7 @@ CONFIG_SECURITY_CAPABILITIES=y
+ # Library routines
+ #
+ CONFIG_BITREVERSE=y
+-# CONFIG_CRC_CCITT is not set
++CONFIG_CRC_CCITT=m
+ # CONFIG_CRC16 is not set
+ # CONFIG_CRC_ITU_T is not set
+ CONFIG_CRC32=y
+diff --git a/arch/blackfin/configs/BF533-EZKIT_defconfig b/arch/blackfin/configs/BF533-EZKIT_defconfig
+index 4fdb493..811711f 100644
+--- a/arch/blackfin/configs/BF533-EZKIT_defconfig
++++ b/arch/blackfin/configs/BF533-EZKIT_defconfig
+@@ -1,6 +1,6 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.22.12
++# Linux kernel version: 2.6.22.16
+ #
+ # CONFIG_MMU is not set
+ # CONFIG_FPU is not set
+@@ -115,7 +115,10 @@ CONFIG_PREEMPT_VOLUNTARY=y
+ # Processor and Board Settings
+ #
+ # CONFIG_BF522 is not set
++# CONFIG_BF523 is not set
++# CONFIG_BF524 is not set
+ # CONFIG_BF525 is not set
++# CONFIG_BF526 is not set
+ # CONFIG_BF527 is not set
+ # CONFIG_BF531 is not set
+ # CONFIG_BF532 is not set
+@@ -194,7 +197,7 @@ CONFIG_CLKIN_HZ=27000000
+ # CONFIG_BFIN_KERNEL_CLOCK is not set
+ CONFIG_MAX_VCO_HZ=750000000
+ CONFIG_MIN_VCO_HZ=50000000
+-CONFIG_MAX_SCLK_HZ=133000000
++CONFIG_MAX_SCLK_HZ=133333333
+ CONFIG_MIN_SCLK_HZ=27000000
  
- 	platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR;
+ #
+@@ -267,6 +270,7 @@ CONFIG_BFIN_DCACHE=y
+ # CONFIG_BFIN_WB is not set
+ CONFIG_BFIN_WT=y
+ CONFIG_L1_MAX_PIECE=16
++# CONFIG_MPU is not set
  
--	ia64_printk_clock = ia64_sn2_printk_clock;
+ #
+ # Asynchonous Memory Configuration
+@@ -321,7 +325,7 @@ CONFIG_PM=y
+ CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y
+ # CONFIG_PM_WAKEUP_BY_GPIO is not set
+ # CONFIG_PM_WAKEUP_GPIO_API is not set
+-CONFIG_PM_WAKEUP_SIC_IWR=0x100000
++CONFIG_PM_WAKEUP_SIC_IWR=0x80
+ 
+ #
+ # CPU Frequency scaling
+@@ -510,7 +514,6 @@ CONFIG_MTD_CFI_I2=y
+ # CONFIG_MTD_CFI_INTELEXT is not set
+ # CONFIG_MTD_CFI_AMDSTD is not set
+ # CONFIG_MTD_CFI_STAA is not set
+-CONFIG_MTD_MW320D=m
+ CONFIG_MTD_RAM=y
+ CONFIG_MTD_ROM=m
+ # CONFIG_MTD_ABSENT is not set
+@@ -520,9 +523,6 @@ CONFIG_MTD_ROM=m
+ #
+ CONFIG_MTD_COMPLEX_MAPPINGS=y
+ # CONFIG_MTD_PHYSMAP is not set
+-CONFIG_MTD_BF5xx=m
+-CONFIG_BFIN_FLASH_SIZE=0x400000
+-CONFIG_EBIU_FLASH_BASE=0x20000000
+ # CONFIG_MTD_UCLINUX is not set
+ # CONFIG_MTD_PLATRAM is not set
+ 
+@@ -610,8 +610,8 @@ CONFIG_SMC91X=y
+ # CONFIG_SMSC911X is not set
+ # CONFIG_DM9000 is not set
+ CONFIG_NETDEV_1000=y
+-CONFIG_NETDEV_10000=y
+ # CONFIG_AX88180 is not set
++CONFIG_NETDEV_10000=y
+ 
+ #
+ # Wireless LAN
+@@ -680,7 +680,6 @@ CONFIG_INPUT_EVDEV=m
+ CONFIG_BFIN_SPORT=y
+ # CONFIG_BFIN_TIMER_LATENCY is not set
+ # CONFIG_AD5304 is not set
+-# CONFIG_BF5xx_FBDMA is not set
+ # CONFIG_VT is not set
+ # CONFIG_SERIAL_NONSTANDARD is not set
+ 
+diff --git a/arch/blackfin/configs/BF533-STAMP_defconfig b/arch/blackfin/configs/BF533-STAMP_defconfig
+index b04e8e5..9b7123c 100644
+--- a/arch/blackfin/configs/BF533-STAMP_defconfig
++++ b/arch/blackfin/configs/BF533-STAMP_defconfig
+@@ -1,6 +1,6 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.22.12
++# Linux kernel version: 2.6.22.16
+ #
+ # CONFIG_MMU is not set
+ # CONFIG_FPU is not set
+@@ -115,7 +115,10 @@ CONFIG_PREEMPT_VOLUNTARY=y
+ # Processor and Board Settings
+ #
+ # CONFIG_BF522 is not set
++# CONFIG_BF523 is not set
++# CONFIG_BF524 is not set
+ # CONFIG_BF525 is not set
++# CONFIG_BF526 is not set
+ # CONFIG_BF527 is not set
+ # CONFIG_BF531 is not set
+ # CONFIG_BF532 is not set
+@@ -140,7 +143,6 @@ CONFIG_BF_REV_0_3=y
+ CONFIG_BF53x=y
+ CONFIG_BFIN_SINGLE_CORE=y
+ CONFIG_MEM_MT48LC64M4A2FB_7E=y
+-CONFIG_BFIN_SHARED_FLASH_ENET=y
+ # CONFIG_BFIN533_EZKIT is not set
+ CONFIG_BFIN533_STAMP=y
+ # CONFIG_BFIN533_BLUETECHNIX_CM is not set
+@@ -195,7 +197,7 @@ CONFIG_CLKIN_HZ=11059200
+ # CONFIG_BFIN_KERNEL_CLOCK is not set
+ CONFIG_MAX_VCO_HZ=750000000
+ CONFIG_MIN_VCO_HZ=50000000
+-CONFIG_MAX_SCLK_HZ=133000000
++CONFIG_MAX_SCLK_HZ=133333333
+ CONFIG_MIN_SCLK_HZ=27000000
+ 
+ #
+@@ -215,18 +217,10 @@ CONFIG_MEM_ADD_WIDTH=11
+ CONFIG_ENET_FLASH_PIN=0
+ CONFIG_BOOT_LOAD=0x1000
+ 
+-#
+-# LED Status Indicators
+-#
+-# CONFIG_BFIN_ALIVE_LED is not set
+-# CONFIG_BFIN_IDLE_LED is not set
++
+ CONFIG_BFIN_SCRATCH_REG_RETN=y
+ # CONFIG_BFIN_SCRATCH_REG_RETE is not set
+ # CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
+-CONFIG_BFIN_ALIVE_LED_PORT=0xFFC00700
+-CONFIG_BFIN_ALIVE_LED_DPORT=0xFFC00730
+-CONFIG_BFIN_IDLE_LED_PORT=0xFFC00700
+-CONFIG_BFIN_IDLE_LED_DPORT=0xFFC00730
+ 
+ #
+ # Blackfin Kernel Optimizations
+@@ -279,6 +273,7 @@ CONFIG_BFIN_DCACHE=y
+ # CONFIG_BFIN_WB is not set
+ CONFIG_BFIN_WT=y
+ CONFIG_L1_MAX_PIECE=16
++# CONFIG_MPU is not set
+ 
+ #
+ # Asynchonous Memory Configuration
+@@ -333,7 +328,7 @@ CONFIG_PM=y
+ CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y
+ # CONFIG_PM_WAKEUP_BY_GPIO is not set
+ # CONFIG_PM_WAKEUP_GPIO_API is not set
+-CONFIG_PM_WAKEUP_SIC_IWR=0x100000
++CONFIG_PM_WAKEUP_SIC_IWR=0x80
+ 
+ #
+ # CPU Frequency scaling
+@@ -522,7 +517,6 @@ CONFIG_MTD_CFI_I2=y
+ # CONFIG_MTD_CFI_INTELEXT is not set
+ # CONFIG_MTD_CFI_AMDSTD is not set
+ # CONFIG_MTD_CFI_STAA is not set
+-CONFIG_MTD_MW320D=m
+ CONFIG_MTD_RAM=y
+ CONFIG_MTD_ROM=m
+ # CONFIG_MTD_ABSENT is not set
+@@ -532,17 +526,6 @@ CONFIG_MTD_ROM=m
+ #
+ CONFIG_MTD_COMPLEX_MAPPINGS=y
+ # CONFIG_MTD_PHYSMAP is not set
+-CONFIG_MTD_BF5xx=m
+-CONFIG_BFIN_FLASH_SIZE=0x400000
+-CONFIG_EBIU_FLASH_BASE=0x20000000
 -
- 	printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF);
+-#
+-# FLASH_EBIU_AMBCTL Control
+-#
+-CONFIG_BFIN_FLASH_BANK_0=0x7BB0
+-CONFIG_BFIN_FLASH_BANK_1=0x7BB0
+-CONFIG_BFIN_FLASH_BANK_2=0x7BB0
+-CONFIG_BFIN_FLASH_BANK_3=0x7BB0
+ # CONFIG_MTD_UCLINUX is not set
+ # CONFIG_MTD_PLATRAM is not set
+ 
+@@ -630,8 +613,8 @@ CONFIG_SMC91X=y
+ # CONFIG_SMSC911X is not set
+ # CONFIG_DM9000 is not set
+ CONFIG_NETDEV_1000=y
+-CONFIG_NETDEV_10000=y
+ # CONFIG_AX88180 is not set
++CONFIG_NETDEV_10000=y
  
- 	/*
-diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
-index 4710135..197d797 100644
---- a/arch/mips/kernel/i8259.c
-+++ b/arch/mips/kernel/i8259.c
-@@ -238,7 +238,7 @@ static int i8259A_shutdown(struct sys_device *dev)
- }
+ #
+ # Wireless LAN
+@@ -687,7 +670,6 @@ CONFIG_INPUT_MISC=y
+ # CONFIG_INPUT_POWERMATE is not set
+ # CONFIG_INPUT_YEALINK is not set
+ # CONFIG_INPUT_UINPUT is not set
+-# CONFIG_BF53X_PFBUTTONS is not set
+ CONFIG_TWI_KEYPAD=m
+ CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=39
+ 
+@@ -711,8 +693,6 @@ CONFIG_BFIN_SPORT=y
+ CONFIG_TWI_LCD=m
+ CONFIG_TWI_LCD_SLAVE_ADDR=34
+ # CONFIG_AD5304 is not set
+-# CONFIG_BF5xx_TEA5764 is not set
+-# CONFIG_BF5xx_FBDMA is not set
+ # CONFIG_VT is not set
+ # CONFIG_SERIAL_NONSTANDARD is not set
  
- static struct sysdev_class i8259_sysdev_class = {
--	set_kset_name("i8259"),
-+	.name = "i8259",
- 	.resume = i8259A_resume,
- 	.shutdown = i8259A_shutdown,
- };
-diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c
-index 892665b..bb4f00c 100644
---- a/arch/mips/kernel/mips-mt-fpaff.c
-+++ b/arch/mips/kernel/mips-mt-fpaff.c
-@@ -58,13 +58,13 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
- 	if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask)))
- 		return -EFAULT;
+@@ -778,7 +758,6 @@ CONFIG_I2C_ALGOBIT=m
+ #
+ # I2C Hardware Bus support
+ #
+-# CONFIG_I2C_BLACKFIN_GPIO is not set
+ # CONFIG_I2C_GPIO is not set
+ # CONFIG_I2C_OCORES is not set
+ # CONFIG_I2C_PARPORT_LIGHT is not set
+diff --git a/arch/blackfin/configs/BF537-STAMP_defconfig b/arch/blackfin/configs/BF537-STAMP_defconfig
+index f812b66..b37ccc6 100644
+--- a/arch/blackfin/configs/BF537-STAMP_defconfig
++++ b/arch/blackfin/configs/BF537-STAMP_defconfig
+@@ -1,6 +1,6 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.22.12
++# Linux kernel version: 2.6.22.16
+ #
+ # CONFIG_MMU is not set
+ # CONFIG_FPU is not set
+@@ -115,7 +115,10 @@ CONFIG_PREEMPT_VOLUNTARY=y
+ # Processor and Board Settings
+ #
+ # CONFIG_BF522 is not set
++# CONFIG_BF523 is not set
++# CONFIG_BF524 is not set
+ # CONFIG_BF525 is not set
++# CONFIG_BF526 is not set
+ # CONFIG_BF527 is not set
+ # CONFIG_BF531 is not set
+ # CONFIG_BF532 is not set
+@@ -170,6 +173,7 @@ CONFIG_IRQ_WATCH=13
+ CONFIG_BFIN537_STAMP=y
+ # CONFIG_BFIN537_BLUETECHNIX_CM is not set
+ # CONFIG_PNAV10 is not set
++# CONFIG_CAMSIG_MINOTAUR is not set
+ # CONFIG_GENERIC_BF537_BOARD is not set
  
--	lock_cpu_hotplug();
-+	get_online_cpus();
- 	read_lock(&tasklist_lock);
+ #
+@@ -201,7 +205,7 @@ CONFIG_CLKIN_HZ=25000000
+ # CONFIG_BFIN_KERNEL_CLOCK is not set
+ CONFIG_MAX_VCO_HZ=600000000
+ CONFIG_MIN_VCO_HZ=50000000
+-CONFIG_MAX_SCLK_HZ=133000000
++CONFIG_MAX_SCLK_HZ=133333333
+ CONFIG_MIN_SCLK_HZ=27000000
  
- 	p = find_process_by_pid(pid);
- 	if (!p) {
- 		read_unlock(&tasklist_lock);
--		unlock_cpu_hotplug();
-+		put_online_cpus();
- 		return -ESRCH;
- 	}
+ #
+@@ -274,6 +278,7 @@ CONFIG_BFIN_DCACHE=y
+ # CONFIG_BFIN_WB is not set
+ CONFIG_BFIN_WT=y
+ CONFIG_L1_MAX_PIECE=16
++# CONFIG_MPU is not set
  
-@@ -106,7 +106,7 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
+ #
+ # Asynchonous Memory Configuration
+@@ -328,7 +333,7 @@ CONFIG_PM=y
+ CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y
+ # CONFIG_PM_WAKEUP_BY_GPIO is not set
+ # CONFIG_PM_WAKEUP_GPIO_API is not set
+-CONFIG_PM_WAKEUP_SIC_IWR=0x80000000
++CONFIG_PM_WAKEUP_SIC_IWR=0x8
  
- out_unlock:
- 	put_task_struct(p);
--	unlock_cpu_hotplug();
-+	put_online_cpus();
- 	return retval;
- }
+ #
+ # CPU Frequency scaling
+@@ -483,7 +488,7 @@ CONFIG_MTD=y
+ # CONFIG_MTD_CONCAT is not set
+ CONFIG_MTD_PARTITIONS=y
+ # CONFIG_MTD_REDBOOT_PARTS is not set
+-# CONFIG_MTD_CMDLINE_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
  
-@@ -125,7 +125,7 @@ asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len,
- 	if (len < real_len)
- 		return -EINVAL;
+ #
+ # User Modules And Translation Layers
+@@ -500,8 +505,8 @@ CONFIG_MTD_BLOCK=y
+ #
+ # RAM/ROM/Flash chip drivers
+ #
+-# CONFIG_MTD_CFI is not set
+-CONFIG_MTD_JEDECPROBE=m
++CONFIG_MTD_CFI=m
++# CONFIG_MTD_JEDECPROBE is not set
+ CONFIG_MTD_GEN_PROBE=m
+ # CONFIG_MTD_CFI_ADV_OPTIONS is not set
+ CONFIG_MTD_MAP_BANK_WIDTH_1=y
+@@ -515,9 +520,9 @@ CONFIG_MTD_CFI_I2=y
+ # CONFIG_MTD_CFI_I4 is not set
+ # CONFIG_MTD_CFI_I8 is not set
+ # CONFIG_MTD_CFI_INTELEXT is not set
+-# CONFIG_MTD_CFI_AMDSTD is not set
++CONFIG_MTD_CFI_AMDSTD=m
+ # CONFIG_MTD_CFI_STAA is not set
+-CONFIG_MTD_MW320D=m
++CONFIG_MTD_CFI_UTIL=m
+ CONFIG_MTD_RAM=y
+ CONFIG_MTD_ROM=m
+ # CONFIG_MTD_ABSENT is not set
+@@ -525,11 +530,11 @@ CONFIG_MTD_ROM=m
+ #
+ # Mapping drivers for chip access
+ #
+-CONFIG_MTD_COMPLEX_MAPPINGS=y
+-# CONFIG_MTD_PHYSMAP is not set
+-CONFIG_MTD_BF5xx=m
+-CONFIG_BFIN_FLASH_SIZE=0x400000
+-CONFIG_EBIU_FLASH_BASE=0x20000000
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++CONFIG_MTD_PHYSMAP=m
++CONFIG_MTD_PHYSMAP_START=0x20000000
++CONFIG_MTD_PHYSMAP_LEN=0x0
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+ # CONFIG_MTD_UCLINUX is not set
+ # CONFIG_MTD_PLATRAM is not set
  
--	lock_cpu_hotplug();
-+	get_online_cpus();
- 	read_lock(&tasklist_lock);
+@@ -647,8 +652,8 @@ CONFIG_BFIN_RX_DESC_NUM=20
+ # CONFIG_SMSC911X is not set
+ # CONFIG_DM9000 is not set
+ CONFIG_NETDEV_1000=y
+-CONFIG_NETDEV_10000=y
+ # CONFIG_AX88180 is not set
++CONFIG_NETDEV_10000=y
  
- 	retval = -ESRCH;
-@@ -140,7 +140,7 @@ asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len,
+ #
+ # Wireless LAN
+@@ -704,7 +709,6 @@ CONFIG_INPUT_MISC=y
+ # CONFIG_INPUT_POWERMATE is not set
+ # CONFIG_INPUT_YEALINK is not set
+ # CONFIG_INPUT_UINPUT is not set
+-# CONFIG_BF53X_PFBUTTONS is not set
+ CONFIG_TWI_KEYPAD=m
+ CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=72
+ 
+@@ -728,8 +732,6 @@ CONFIG_BFIN_SPORT=y
+ CONFIG_TWI_LCD=m
+ CONFIG_TWI_LCD_SLAVE_ADDR=34
+ # CONFIG_AD5304 is not set
+-# CONFIG_BF5xx_TEA5764 is not set
+-# CONFIG_BF5xx_FBDMA is not set
+ # CONFIG_VT is not set
+ # CONFIG_SERIAL_NONSTANDARD is not set
  
- out_unlock:
- 	read_unlock(&tasklist_lock);
--	unlock_cpu_hotplug();
-+	put_online_cpus();
- 	if (retval)
- 		return retval;
- 	if (copy_to_user(user_mask_ptr, &mask, real_len))
-diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
-index c83c3e3..a088622 100644
---- a/arch/powerpc/platforms/cell/spu_base.c
-+++ b/arch/powerpc/platforms/cell/spu_base.c
-@@ -459,7 +459,7 @@ static int spu_shutdown(struct sys_device *sysdev)
- }
+@@ -802,7 +804,6 @@ CONFIG_I2C_CHARDEV=m
+ #
+ # I2C Hardware Bus support
+ #
+-# CONFIG_I2C_BLACKFIN_GPIO is not set
+ CONFIG_I2C_BLACKFIN_TWI=m
+ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50
+ # CONFIG_I2C_GPIO is not set
+@@ -957,6 +958,7 @@ CONFIG_LQ035_SLAVE_ADDR=0x58
+ # CONFIG_FB_BFIN_LANDSCAPE is not set
+ # CONFIG_FB_BFIN_BGR is not set
+ # CONFIG_FB_BFIN_T350MCQB is not set
++# CONFIG_FB_HITACHI_TX09 is not set
+ # CONFIG_FB_S1D13XXX is not set
+ # CONFIG_FB_VIRTUAL is not set
+ # CONFIG_LOGO is not set
+@@ -1008,12 +1010,22 @@ CONFIG_SND_BFIN_AD73311_SE=4
+ #
+ # System on Chip audio support
+ #
+-# CONFIG_SND_SOC is not set
++CONFIG_SND_SOC_AC97_BUS=y
++CONFIG_SND_SOC=m
++CONFIG_SND_BF5XX_SOC=m
++CONFIG_SND_BF5XX_SOC_AC97=m
++# CONFIG_SND_BF5XX_SOC_WM8750 is not set
++# CONFIG_SND_BF5XX_SOC_WM8731 is not set
++CONFIG_SND_BF5XX_SOC_BF5xx=m
++CONFIG_SND_BF5XX_SPORT_NUM=0
++# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
++CONFIG_SND_SOC_AD1980=m
  
- static struct sysdev_class spu_sysdev_class = {
--	set_kset_name("spu"),
-+	.name = "spu",
- 	.shutdown = spu_shutdown,
- };
+ #
+ # Open Sound System
+ #
+ # CONFIG_SOUND_PRIME is not set
++CONFIG_AC97_BUS=m
  
-diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
-index 999f5e1..84c0d4e 100644
---- a/arch/powerpc/platforms/powermac/pic.c
-+++ b/arch/powerpc/platforms/powermac/pic.c
-@@ -663,7 +663,7 @@ static int pmacpic_resume(struct sys_device *sysdev)
- #endif /* CONFIG_PM && CONFIG_PPC32 */
+ #
+ # HID Devices
+diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig
+index 48367cc..fd70216 100644
+--- a/arch/blackfin/configs/BF548-EZKIT_defconfig
++++ b/arch/blackfin/configs/BF548-EZKIT_defconfig
+@@ -1,6 +1,6 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.22.12
++# Linux kernel version: 2.6.22.16
+ #
+ # CONFIG_MMU is not set
+ # CONFIG_FPU is not set
+@@ -115,7 +115,10 @@ CONFIG_PREEMPT_VOLUNTARY=y
+ # Processor and Board Settings
+ #
+ # CONFIG_BF522 is not set
++# CONFIG_BF523 is not set
++# CONFIG_BF524 is not set
+ # CONFIG_BF525 is not set
++# CONFIG_BF526 is not set
+ # CONFIG_BF527 is not set
+ # CONFIG_BF531 is not set
+ # CONFIG_BF532 is not set
+@@ -126,8 +129,8 @@ CONFIG_PREEMPT_VOLUNTARY=y
+ # CONFIG_BF542 is not set
+ # CONFIG_BF544 is not set
+ # CONFIG_BF547 is not set
+-# CONFIG_BF548 is not set
+-CONFIG_BF549=y
++CONFIG_BF548=y
++# CONFIG_BF549 is not set
+ # CONFIG_BF561 is not set
+ CONFIG_BF_REV_0_0=y
+ # CONFIG_BF_REV_0_1 is not set
+@@ -265,9 +268,9 @@ CONFIG_PINT3_ASSIGN=0x02020303
+ #
+ CONFIG_CLKIN_HZ=25000000
+ # CONFIG_BFIN_KERNEL_CLOCK is not set
+-CONFIG_MAX_VCO_HZ=533000000
++CONFIG_MAX_VCO_HZ=600000000
+ CONFIG_MIN_VCO_HZ=50000000
+-CONFIG_MAX_SCLK_HZ=133000000
++CONFIG_MAX_SCLK_HZ=133333333
+ CONFIG_MIN_SCLK_HZ=27000000
  
- static struct sysdev_class pmacpic_sysclass = {
--	set_kset_name("pmac_pic"),
-+	.name = "pmac_pic",
- };
+ #
+@@ -283,7 +286,8 @@ CONFIG_HZ=250
+ # Memory Setup
+ #
+ CONFIG_MEM_SIZE=64
+-CONFIG_MEM_ADD_WIDTH=10
++# CONFIG_MEM_MT46V32M16_6T is not set
++CONFIG_MEM_MT46V32M16_5B=y
+ CONFIG_BOOT_LOAD=0x1000
+ CONFIG_BFIN_SCRATCH_REG_RETN=y
+ # CONFIG_BFIN_SCRATCH_REG_RETE is not set
+@@ -340,6 +344,7 @@ CONFIG_BFIN_DCACHE=y
+ # CONFIG_BFIN_WB is not set
+ CONFIG_BFIN_WT=y
+ CONFIG_L1_MAX_PIECE=16
++# CONFIG_MPU is not set
  
- static struct sys_device device_pmacpic = {
-diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
-index 412e6b4..c4ad54e 100644
---- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
-+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
-@@ -153,7 +153,7 @@ static int pseries_add_processor(struct device_node *np)
- 	for (i = 0; i < nthreads; i++)
- 		cpu_set(i, tmp);
+ #
+ # Asynchonous Memory Configuration
+@@ -349,6 +354,7 @@ CONFIG_L1_MAX_PIECE=16
+ # EBIU_AMGCTL Global Control
+ #
+ CONFIG_C_AMCKEN=y
++# CONFIG_C_CDPRIO is not set
+ # CONFIG_C_AMBEN is not set
+ # CONFIG_C_AMBEN_B0 is not set
+ # CONFIG_C_AMBEN_B0_B1 is not set
+@@ -362,9 +368,9 @@ CONFIG_BANK_0=0x7BB0
+ CONFIG_BANK_1=0x5554
+ CONFIG_BANK_2=0x7BB0
+ CONFIG_BANK_3=0x99B3
+-CONFIG_EBUI_MBSCTLVAL=0x0
+-CONFIG_EBUI_MODEVAL=0x1
+-CONFIG_EBUI_FCTLVAL=0x6
++CONFIG_EBIU_MBSCTLVAL=0x0
++CONFIG_EBIU_MODEVAL=0x1
++CONFIG_EBIU_FCTLVAL=0x6
  
--	lock_cpu_hotplug();
-+	cpu_maps_update_begin();
+ #
+ # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+@@ -537,7 +543,6 @@ CONFIG_MTD_CFI_I2=y
+ CONFIG_MTD_CFI_INTELEXT=y
+ # CONFIG_MTD_CFI_AMDSTD is not set
+ # CONFIG_MTD_CFI_STAA is not set
+-# CONFIG_MTD_MW320D is not set
+ CONFIG_MTD_CFI_UTIL=y
+ CONFIG_MTD_RAM=y
+ # CONFIG_MTD_ROM is not set
+@@ -549,9 +554,8 @@ CONFIG_MTD_RAM=y
+ CONFIG_MTD_COMPLEX_MAPPINGS=y
+ CONFIG_MTD_PHYSMAP=y
+ CONFIG_MTD_PHYSMAP_START=0x20000000
+-CONFIG_MTD_PHYSMAP_LEN=0x400000
++CONFIG_MTD_PHYSMAP_LEN=0
+ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+-# CONFIG_MTD_BF5xx is not set
+ # CONFIG_MTD_UCLINUX is not set
+ # CONFIG_MTD_PLATRAM is not set
+ 
+@@ -690,8 +694,8 @@ CONFIG_MII=y
+ CONFIG_SMSC911X=y
+ # CONFIG_DM9000 is not set
+ CONFIG_NETDEV_1000=y
+-CONFIG_NETDEV_10000=y
+ # CONFIG_AX88180 is not set
++CONFIG_NETDEV_10000=y
  
- 	BUG_ON(!cpus_subset(cpu_present_map, cpu_possible_map));
+ #
+ # Wireless LAN
+@@ -719,7 +723,7 @@ CONFIG_NETDEV_10000=y
+ #
+ # Input device support
+ #
+-CONFIG_INPUT=m
++CONFIG_INPUT=y
+ # CONFIG_INPUT_FF_MEMLESS is not set
+ # CONFIG_INPUT_POLLDEV is not set
+ 
+@@ -745,7 +749,8 @@ CONFIG_INPUT_KEYBOARD=y
+ # CONFIG_KEYBOARD_NEWTON is not set
+ # CONFIG_KEYBOARD_STOWAWAY is not set
+ # CONFIG_KEYBOARD_GPIO is not set
+-CONFIG_KEYBOARD_BFIN=m
++CONFIG_KEYBOARD_BFIN=y
++# CONFIG_KEYBOARD_OPENCORES is not set
+ # CONFIG_INPUT_MOUSE is not set
+ # CONFIG_INPUT_JOYSTICK is not set
+ # CONFIG_INPUT_TABLET is not set
+@@ -768,7 +773,6 @@ CONFIG_INPUT_MISC=y
+ # CONFIG_INPUT_POWERMATE is not set
+ # CONFIG_INPUT_YEALINK is not set
+ # CONFIG_INPUT_UINPUT is not set
+-# CONFIG_BF53X_PFBUTTONS is not set
+ # CONFIG_TWI_KEYPAD is not set
  
-@@ -190,7 +190,7 @@ static int pseries_add_processor(struct device_node *np)
- 	}
- 	err = 0;
- out_unlock:
--	unlock_cpu_hotplug();
-+	cpu_maps_update_done();
- 	return err;
- }
+ #
+@@ -786,13 +790,16 @@ CONFIG_INPUT_MISC=y
+ # CONFIG_BF5xx_PPIFCD is not set
+ # CONFIG_BFIN_SIMPLE_TIMER is not set
+ # CONFIG_BF5xx_PPI is not set
++CONFIG_BFIN_OTP=y
++# CONFIG_BFIN_OTP_WRITE_ENABLE is not set
+ # CONFIG_BFIN_SPORT is not set
+ # CONFIG_BFIN_TIMER_LATENCY is not set
+ # CONFIG_TWI_LCD is not set
+ # CONFIG_AD5304 is not set
+-# CONFIG_BF5xx_TEA5764 is not set
+-# CONFIG_BF5xx_FBDMA is not set
+-# CONFIG_VT is not set
++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
  
-@@ -211,7 +211,7 @@ static void pseries_remove_processor(struct device_node *np)
+ #
+@@ -858,7 +865,6 @@ CONFIG_I2C_CHARDEV=y
+ #
+ # I2C Hardware Bus support
+ #
+-# CONFIG_I2C_BLACKFIN_GPIO is not set
+ CONFIG_I2C_BLACKFIN_TWI=y
+ CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50
+ # CONFIG_I2C_GPIO is not set
+@@ -976,12 +982,12 @@ CONFIG_DAB=y
+ #
+ # CONFIG_DISPLAY_SUPPORT is not set
+ # CONFIG_VGASTATE is not set
+-CONFIG_FB=m
++CONFIG_FB=y
+ CONFIG_FIRMWARE_EDID=y
+ # CONFIG_FB_DDC is not set
+-CONFIG_FB_CFB_FILLRECT=m
+-CONFIG_FB_CFB_COPYAREA=m
+-CONFIG_FB_CFB_IMAGEBLIT=m
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
+ # CONFIG_FB_SYS_FILLRECT is not set
+ # CONFIG_FB_SYS_COPYAREA is not set
+ # CONFIG_FB_SYS_IMAGEBLIT is not set
+@@ -998,11 +1004,34 @@ CONFIG_FB_DEFERRED_IO=y
+ #
+ # CONFIG_FB_BFIN_7171 is not set
+ # CONFIG_FB_BFIN_7393 is not set
+-CONFIG_FB_BF54X_LQ043=m
++CONFIG_FB_BF54X_LQ043=y
+ # CONFIG_FB_BFIN_T350MCQB is not set
+ # CONFIG_FB_S1D13XXX is not set
+ # CONFIG_FB_VIRTUAL is not set
+-# CONFIG_LOGO is not set
++
++#
++# Console display driver support
++#
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
++CONFIG_FONTS=y
++# CONFIG_FONT_8x8 is not set
++# CONFIG_FONT_8x16 is not set
++CONFIG_FONT_6x11=y
++# CONFIG_FONT_7x14 is not set
++# CONFIG_FONT_PEARL_8x8 is not set
++# CONFIG_FONT_ACORN_8x8 is not set
++# CONFIG_FONT_MINI_4x6 is not set
++# CONFIG_FONT_SUN8x16 is not set
++# CONFIG_FONT_SUN12x22 is not set
++# CONFIG_FONT_10x18 is not set
++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_BLACKFIN_VGA16 is not set
++CONFIG_LOGO_BLACKFIN_CLUT224=y
  
- 	nthreads = len / sizeof(u32);
+ #
+ # Sound
+@@ -1051,7 +1080,8 @@ CONFIG_SND_BF5XX_SOC_BF548_EZKIT=y
+ # CONFIG_SND_BF5XX_SOC_WM8750 is not set
+ # CONFIG_SND_BF5XX_SOC_WM8731 is not set
+ CONFIG_SND_BF5XX_SPORT_NUM=0
+-# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
++CONFIG_SND_BF5XX_HAVE_COLD_RESET=y
++CONFIG_SND_BF5XX_RESET_GPIO_NUM=19
+ CONFIG_SND_SOC_AD1980=y
  
--	lock_cpu_hotplug();
-+	cpu_maps_update_begin();
- 	for (i = 0; i < nthreads; i++) {
- 		for_each_present_cpu(cpu) {
- 			if (get_hard_smp_processor_id(cpu) != intserv[i])
-@@ -225,7 +225,7 @@ static void pseries_remove_processor(struct device_node *np)
- 			printk(KERN_WARNING "Could not find cpu to remove "
- 			       "with physical id 0x%x\n", intserv[i]);
- 	}
--	unlock_cpu_hotplug();
-+	cpu_maps_update_done();
+ #
+@@ -1403,7 +1433,7 @@ CONFIG_NLS_UTF8=m
+ #
+ # CONFIG_PRINTK_TIME is not set
+ CONFIG_ENABLE_MUST_CHECK=y
+-CONFIG_MAGIC_SYSRQ=y
++# CONFIG_MAGIC_SYSRQ is not set
+ # CONFIG_UNUSED_SYMBOLS is not set
+ CONFIG_DEBUG_FS=y
+ # CONFIG_HEADERS_CHECK is not set
+@@ -1428,7 +1458,7 @@ CONFIG_ACCESS_CHECK=y
+ # CONFIG_KEYS is not set
+ CONFIG_SECURITY=y
+ # CONFIG_SECURITY_NETWORK is not set
+-CONFIG_SECURITY_CAPABILITIES=y
++CONFIG_SECURITY_CAPABILITIES=m
+ 
+ #
+ # Cryptographic options
+@@ -1439,7 +1469,7 @@ CONFIG_SECURITY_CAPABILITIES=y
+ # Library routines
+ #
+ CONFIG_BITREVERSE=y
+-# CONFIG_CRC_CCITT is not set
++CONFIG_CRC_CCITT=m
+ # CONFIG_CRC16 is not set
+ # CONFIG_CRC_ITU_T is not set
+ CONFIG_CRC32=y
+diff --git a/arch/blackfin/configs/BF561-EZKIT_defconfig b/arch/blackfin/configs/BF561-EZKIT_defconfig
+index e9f100b..8546994 100644
+--- a/arch/blackfin/configs/BF561-EZKIT_defconfig
++++ b/arch/blackfin/configs/BF561-EZKIT_defconfig
+@@ -1,6 +1,6 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.22.12
++# Linux kernel version: 2.6.22.16
+ #
+ # CONFIG_MMU is not set
+ # CONFIG_FPU is not set
+@@ -115,7 +115,10 @@ CONFIG_PREEMPT_VOLUNTARY=y
+ # Processor and Board Settings
+ #
+ # CONFIG_BF522 is not set
++# CONFIG_BF523 is not set
++# CONFIG_BF524 is not set
+ # CONFIG_BF525 is not set
++# CONFIG_BF526 is not set
+ # CONFIG_BF527 is not set
+ # CONFIG_BF531 is not set
+ # CONFIG_BF532 is not set
+@@ -238,7 +241,7 @@ CONFIG_CLKIN_HZ=30000000
+ # CONFIG_BFIN_KERNEL_CLOCK is not set
+ CONFIG_MAX_VCO_HZ=600000000
+ CONFIG_MIN_VCO_HZ=50000000
+-CONFIG_MAX_SCLK_HZ=133000000
++CONFIG_MAX_SCLK_HZ=133333333
+ CONFIG_MIN_SCLK_HZ=27000000
+ 
+ #
+@@ -311,6 +314,7 @@ CONFIG_BFIN_DCACHE=y
+ # CONFIG_BFIN_WB is not set
+ CONFIG_BFIN_WT=y
+ CONFIG_L1_MAX_PIECE=16
++# CONFIG_MPU is not set
+ 
+ #
+ # Asynchonous Memory Configuration
+@@ -512,7 +516,7 @@ CONFIG_MTD=y
+ # CONFIG_MTD_CONCAT is not set
+ CONFIG_MTD_PARTITIONS=y
+ # CONFIG_MTD_REDBOOT_PARTS is not set
+-# CONFIG_MTD_CMDLINE_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
+ 
+ #
+ # User Modules And Translation Layers
+@@ -529,8 +533,8 @@ CONFIG_MTD_BLOCK=y
+ #
+ # RAM/ROM/Flash chip drivers
+ #
+-# CONFIG_MTD_CFI is not set
+-CONFIG_MTD_JEDECPROBE=m
++CONFIG_MTD_CFI=m
++# CONFIG_MTD_JEDECPROBE is not set
+ CONFIG_MTD_GEN_PROBE=m
+ # CONFIG_MTD_CFI_ADV_OPTIONS is not set
+ CONFIG_MTD_MAP_BANK_WIDTH_1=y
+@@ -544,9 +548,9 @@ CONFIG_MTD_CFI_I2=y
+ # CONFIG_MTD_CFI_I4 is not set
+ # CONFIG_MTD_CFI_I8 is not set
+ # CONFIG_MTD_CFI_INTELEXT is not set
+-# CONFIG_MTD_CFI_AMDSTD is not set
++CONFIG_MTD_CFI_AMDSTD=m
+ # CONFIG_MTD_CFI_STAA is not set
+-CONFIG_MTD_MW320D=m
++CONFIG_MTD_CFI_UTIL=m
+ CONFIG_MTD_RAM=y
+ CONFIG_MTD_ROM=m
+ # CONFIG_MTD_ABSENT is not set
+@@ -554,12 +558,11 @@ CONFIG_MTD_ROM=m
+ #
+ # Mapping drivers for chip access
+ #
+-CONFIG_MTD_COMPLEX_MAPPINGS=y
+-# CONFIG_MTD_PHYSMAP is not set
+-# CONFIG_MTD_EZKIT561 is not set
+-CONFIG_MTD_BF5xx=m
+-CONFIG_BFIN_FLASH_SIZE=0x0400000
+-CONFIG_EBIU_FLASH_BASE=0x20000000
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++CONFIG_MTD_PHYSMAP=m
++CONFIG_MTD_PHYSMAP_START=0x20000000
++CONFIG_MTD_PHYSMAP_LEN=0x0
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+ # CONFIG_MTD_UCLINUX is not set
+ # CONFIG_MTD_PLATRAM is not set
+ 
+@@ -647,8 +650,8 @@ CONFIG_SMC91X=y
+ # CONFIG_SMSC911X is not set
+ # CONFIG_DM9000 is not set
+ CONFIG_NETDEV_1000=y
+-CONFIG_NETDEV_10000=y
+ # CONFIG_AX88180 is not set
++CONFIG_NETDEV_10000=y
+ 
+ #
+ # Wireless LAN
+@@ -717,7 +720,6 @@ CONFIG_INPUT_EVDEV=m
+ # CONFIG_BFIN_SPORT is not set
+ # CONFIG_BFIN_TIMER_LATENCY is not set
+ # CONFIG_AD5304 is not set
+-# CONFIG_BF5xx_FBDMA is not set
+ # CONFIG_VT is not set
+ # CONFIG_SERIAL_NONSTANDARD is not set
+ 
+diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile
+index 8a4cfb2..318b9b6 100644
+--- a/arch/blackfin/kernel/Makefile
++++ b/arch/blackfin/kernel/Makefile
+@@ -7,7 +7,7 @@ extra-y := init_task.o vmlinux.lds
+ obj-y := \
+ 	entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \
+ 	sys_bfin.o time.o traps.o irqchip.o dma-mapping.o flat.o \
+-	fixed_code.o cplbinit.o cacheinit.o reboot.o bfin_gpio.o
++	fixed_code.o reboot.o bfin_gpio.o
+ 
+ obj-$(CONFIG_BFIN_GPTIMERS)          += gptimers.o
+ obj-$(CONFIG_MODULES)                += module.o
+diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
+index b544460..fa9debe 100644
+--- a/arch/blackfin/kernel/bfin_dma_5xx.c
++++ b/arch/blackfin/kernel/bfin_dma_5xx.c
+@@ -339,13 +339,13 @@ EXPORT_SYMBOL(set_dma_config);
+ 
+ unsigned short
+ set_bfin_dma_config(char direction, char flow_mode,
+-		    char intr_mode, char dma_mode, char width)
++		    char intr_mode, char dma_mode, char width, char syncmode)
+ {
+ 	unsigned short config;
+ 
+ 	config =
+ 	    ((direction << 1) | (width << 2) | (dma_mode << 4) |
+-	     (intr_mode << 6) | (flow_mode << 12) | RESTART);
++	     (intr_mode << 6) | (flow_mode << 12) | (syncmode << 5));
+ 	return config;
+ }
+ EXPORT_SYMBOL(set_bfin_dma_config);
+diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
+index ce85d4b..6bbe0a2 100644
+--- a/arch/blackfin/kernel/bfin_gpio.c
++++ b/arch/blackfin/kernel/bfin_gpio.c
+@@ -7,7 +7,7 @@
+  * Description:  GPIO Abstraction Layer
+  *
+  * Modified:
+- *               Copyright 2007 Analog Devices Inc.
++ *               Copyright 2008 Analog Devices Inc.
+  *
+  * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+  *
+@@ -83,6 +83,7 @@
+ #include <linux/delay.h>
+ #include <linux/module.h>
+ #include <linux/err.h>
++#include <linux/proc_fs.h>
+ #include <asm/blackfin.h>
+ #include <asm/gpio.h>
+ #include <asm/portmux.h>
+@@ -136,7 +137,6 @@ static unsigned short *port_fer[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
+ 	(unsigned short *) PORTG_FER,
+ 	(unsigned short *) PORTH_FER,
+ };
+-
+ #endif
+ 
+ #ifdef BF527_FAMILY
+@@ -178,15 +178,13 @@ static struct gpio_port_t *gpio_array[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
+ #endif
+ 
+ static unsigned short reserved_gpio_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
+-static unsigned short reserved_peri_map[gpio_bank(MAX_BLACKFIN_GPIOS + 16)];
++static unsigned short reserved_peri_map[gpio_bank(MAX_RESOURCES)];
+ 
+-#define MAX_RESOURCES 		256
+ #define RESOURCE_LABEL_SIZE 	16
+ 
+-struct str_ident {
++static struct str_ident {
+ 	char name[RESOURCE_LABEL_SIZE];
+-} *str_ident;
+-
++} str_ident[MAX_RESOURCES];
+ 
+ #ifdef CONFIG_PM
+ static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
+@@ -212,7 +210,7 @@ static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INT
+ #endif /* CONFIG_PM */
+ 
+ #if defined(BF548_FAMILY)
+-inline int check_gpio(unsigned short gpio)
++inline int check_gpio(unsigned gpio)
+ {
+ 	if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15
+ 	    || gpio == GPIO_PH14 || gpio == GPIO_PH15
+@@ -222,7 +220,7 @@ inline int check_gpio(unsigned short gpio)
+ 	return 0;
+ }
+ #else
+-inline int check_gpio(unsigned short gpio)
++inline int check_gpio(unsigned gpio)
+ {
+ 	if (gpio >= MAX_BLACKFIN_GPIOS)
+ 		return -EINVAL;
+@@ -230,9 +228,13 @@ inline int check_gpio(unsigned short gpio)
  }
+ #endif
  
- static int pseries_smp_notifier(struct notifier_block *nb,
-diff --git a/arch/powerpc/platforms/pseries/power.c b/arch/powerpc/platforms/pseries/power.c
-index 73e6902..e95fc15 100644
---- a/arch/powerpc/platforms/pseries/power.c
-+++ b/arch/powerpc/platforms/pseries/power.c
-@@ -28,13 +28,15 @@
+-static void set_label(unsigned short ident, const char *label)
++void gpio_error(unsigned gpio)
+ {
++	printk(KERN_ERR "bfin-gpio: GPIO %d wasn't requested!\n", gpio);
++}
  
- unsigned long rtas_poweron_auto; /* default and normal state is 0 */
++static void set_label(unsigned short ident, const char *label)
++{
+ 	if (label && str_ident) {
+ 		strncpy(str_ident[ident].name, label,
+ 			 RESOURCE_LABEL_SIZE);
+@@ -250,6 +252,11 @@ static char *get_label(unsigned short ident)
  
--static ssize_t auto_poweron_show(struct kset *kset, char *buf)
-+static ssize_t auto_poweron_show(struct kobject *kobj,
-+				 struct kobj_attribute *attr, char *buf)
+ static int cmp_label(unsigned short ident, const char *label)
  {
-         return sprintf(buf, "%lu\n", rtas_poweron_auto);
++	if (label == NULL) {
++		dump_stack();
++		printk(KERN_ERR "Please provide none-null label\n");
++	}
++
+ 	if (label && str_ident)
+ 		return strncmp(str_ident[ident].name,
+ 				 label, strlen(label));
+@@ -258,7 +265,7 @@ static int cmp_label(unsigned short ident, const char *label)
  }
  
--static ssize_t
--auto_poweron_store(struct kset *kset, const char *buf, size_t n)
-+static ssize_t auto_poweron_store(struct kobject *kobj,
-+				  struct kobj_attribute *attr,
-+				  const char *buf, size_t n)
+ #if defined(BF527_FAMILY) || defined(BF537_FAMILY)
+-static void port_setup(unsigned short gpio, unsigned short usage)
++static void port_setup(unsigned gpio, unsigned short usage)
  {
- 	int ret;
- 	unsigned long ups_restart;
-@@ -47,17 +49,11 @@ auto_poweron_store(struct kset *kset, const char *buf, size_t n)
- 	return -EINVAL;
+ 	if (!check_gpio(gpio)) {
+ 		if (usage == GPIO_USAGE)
+@@ -269,7 +276,7 @@ static void port_setup(unsigned short gpio, unsigned short usage)
+ 	}
  }
+ #elif defined(BF548_FAMILY)
+-static void port_setup(unsigned short gpio, unsigned short usage)
++static void port_setup(unsigned gpio, unsigned short usage)
+ {
+ 	if (usage == GPIO_USAGE)
+ 		gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
+@@ -390,7 +397,7 @@ inline void portmux_setup(unsigned short portno, unsigned short function)
+ #endif
  
--static struct subsys_attribute auto_poweron_attr = {
--        .attr   = {
--                .name = __stringify(auto_poweron),
--                .mode = 0644,
--        },
--        .show   = auto_poweron_show,
--        .store  = auto_poweron_store,
--};
-+static struct kobj_attribute auto_poweron_attr =
-+	__ATTR(auto_poweron, 0644, auto_poweron_show, auto_poweron_store);
+ #ifndef BF548_FAMILY
+-static void default_gpio(unsigned short gpio)
++static void default_gpio(unsigned gpio)
+ {
+ 	unsigned short bank, bitmask;
+ 	unsigned long flags;
+@@ -410,7 +417,6 @@ static void default_gpio(unsigned short gpio)
+ 	gpio_bankb[bank]->edge &= ~bitmask;
+ 	AWA_DUMMY_READ(edge);
+ 	local_irq_restore(flags);
+-
+ }
+ #else
+ # define default_gpio(...)  do { } while (0)
+@@ -418,12 +424,6 @@ static void default_gpio(unsigned short gpio)
  
- #ifndef CONFIG_PM
--decl_subsys(power,NULL,NULL);
-+struct kobject *power_kobj;
+ static int __init bfin_gpio_init(void)
+ {
+-	str_ident = kcalloc(MAX_RESOURCES,
+-				 sizeof(struct str_ident), GFP_KERNEL);
+-	if (str_ident == NULL)
+-		return -ENOMEM;
+-
+-	memset(str_ident, 0, MAX_RESOURCES * sizeof(struct str_ident));
  
- static struct attribute *g[] = {
-         &auto_poweron_attr.attr,
-@@ -70,18 +66,16 @@ static struct attribute_group attr_group = {
+ 	printk(KERN_INFO "Blackfin GPIO Controller\n");
  
- static int __init pm_init(void)
+@@ -454,10 +454,9 @@ arch_initcall(bfin_gpio_init);
+ /* Set a specific bit */
+ 
+ #define SET_GPIO(name) \
+-void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
++void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
+ { \
+ 	unsigned long flags; \
+-	BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); \
+ 	local_irq_save(flags); \
+ 	if (arg) \
+ 		gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \
+@@ -477,10 +476,9 @@ SET_GPIO(both)
+ 
+ #if ANOMALY_05000311 || ANOMALY_05000323
+ #define SET_GPIO_SC(name) \
+-void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
++void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
+ { \
+ 	unsigned long flags; \
+-	BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); \
+ 	local_irq_save(flags); \
+ 	if (arg) \
+ 		gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \
+@@ -492,9 +490,8 @@ void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
+ EXPORT_SYMBOL(set_gpio_ ## name);
+ #else
+ #define SET_GPIO_SC(name) \
+-void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
++void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
+ { \
+-	BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); \
+ 	if (arg) \
+ 		gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \
+ 	else \
+@@ -508,19 +505,17 @@ SET_GPIO_SC(maskb)
+ SET_GPIO_SC(data)
+ 
+ #if ANOMALY_05000311 || ANOMALY_05000323
+-void set_gpio_toggle(unsigned short gpio)
++void set_gpio_toggle(unsigned gpio)
  {
--        int error = subsystem_register(&power_subsys);
--        if (!error)
--                error = sysfs_create_group(&power_subsys.kobj, &attr_group);
--        return error;
-+	power_kobj = kobject_create_and_add("power", NULL);
-+	if (!power_kobj)
-+		return -ENOMEM;
-+	return sysfs_create_group(power_kobj, &attr_group);
+ 	unsigned long flags;
+-	BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+ 	local_irq_save(flags);
+ 	gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
+ 	AWA_DUMMY_READ(toggle);
+ 	local_irq_restore(flags);
  }
- core_initcall(pm_init);
  #else
--extern struct kset power_subsys;
--
- static int __init apo_pm_init(void)
+-void set_gpio_toggle(unsigned short gpio)
++void set_gpio_toggle(unsigned gpio)
  {
--	return (subsys_create_file(&power_subsys, &auto_poweron_attr));
-+	return (sysfs_create_file(power_kobj, &auto_poweron_attr));
+-	BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+ 	gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
  }
- __initcall(apo_pm_init);
  #endif
-diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c
-index 73401c8..e3078ce 100644
---- a/arch/powerpc/platforms/pseries/rtasd.c
-+++ b/arch/powerpc/platforms/pseries/rtasd.c
-@@ -382,7 +382,7 @@ static void do_event_scan_all_cpus(long delay)
- {
- 	int cpu;
+@@ -531,7 +526,7 @@ EXPORT_SYMBOL(set_gpio_toggle);
  
--	lock_cpu_hotplug();
-+	get_online_cpus();
- 	cpu = first_cpu(cpu_online_map);
- 	for (;;) {
- 		set_cpus_allowed(current, cpumask_of_cpu(cpu));
-@@ -390,15 +390,15 @@ static void do_event_scan_all_cpus(long delay)
- 		set_cpus_allowed(current, CPU_MASK_ALL);
+ #if ANOMALY_05000311 || ANOMALY_05000323
+ #define SET_GPIO_P(name) \
+-void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \
++void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \
+ { \
+ 	unsigned long flags; \
+ 	local_irq_save(flags); \
+@@ -542,7 +537,7 @@ void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \
+ EXPORT_SYMBOL(set_gpiop_ ## name);
+ #else
+ #define SET_GPIO_P(name) \
+-void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \
++void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \
+ { \
+ 	gpio_bankb[gpio_bank(gpio)]->name = arg; \
+ } \
+@@ -558,11 +553,10 @@ SET_GPIO_P(both)
+ SET_GPIO_P(maska)
+ SET_GPIO_P(maskb)
  
- 		/* Drop hotplug lock, and sleep for the specified delay */
--		unlock_cpu_hotplug();
-+		put_online_cpus();
- 		msleep_interruptible(delay);
--		lock_cpu_hotplug();
-+		get_online_cpus();
+-
+ /* Get a specific bit */
+ #if ANOMALY_05000311 || ANOMALY_05000323
+ #define GET_GPIO(name) \
+-unsigned short get_gpio_ ## name(unsigned short gpio) \
++unsigned short get_gpio_ ## name(unsigned gpio) \
+ { \
+ 	unsigned long flags; \
+ 	unsigned short ret; \
+@@ -575,7 +569,7 @@ unsigned short get_gpio_ ## name(unsigned short gpio) \
+ EXPORT_SYMBOL(get_gpio_ ## name);
+ #else
+ #define GET_GPIO(name) \
+-unsigned short get_gpio_ ## name(unsigned short gpio) \
++unsigned short get_gpio_ ## name(unsigned gpio) \
+ { \
+ 	return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \
+ } \
+@@ -595,7 +589,7 @@ GET_GPIO(maskb)
+ 
+ #if ANOMALY_05000311 || ANOMALY_05000323
+ #define GET_GPIO_P(name) \
+-unsigned short get_gpiop_ ## name(unsigned short gpio) \
++unsigned short get_gpiop_ ## name(unsigned gpio) \
+ { \
+ 	unsigned long flags; \
+ 	unsigned short ret; \
+@@ -608,7 +602,7 @@ unsigned short get_gpiop_ ## name(unsigned short gpio) \
+ EXPORT_SYMBOL(get_gpiop_ ## name);
+ #else
+ #define GET_GPIO_P(name) \
+-unsigned short get_gpiop_ ## name(unsigned short gpio) \
++unsigned short get_gpiop_ ## name(unsigned gpio) \
+ { \
+ 	return (gpio_bankb[gpio_bank(gpio)]->name);\
+ } \
+@@ -645,7 +639,7 @@ GET_GPIO_P(maskb)
+ *************************************************************
+ * MODIFICATION HISTORY :
+ **************************************************************/
+-int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type)
++int gpio_pm_wakeup_request(unsigned gpio, unsigned char type)
+ {
+ 	unsigned long flags;
  
- 		cpu = next_cpu(cpu, cpu_online_map);
- 		if (cpu == NR_CPUS)
- 			break;
- 	}
--	unlock_cpu_hotplug();
-+	put_online_cpus();
+@@ -653,7 +647,6 @@ int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type)
+ 		return -EINVAL;
+ 
+ 	local_irq_save(flags);
+-
+ 	wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio);
+ 	wakeup_flags_map[gpio] = type;
+ 	local_irq_restore(flags);
+@@ -662,7 +655,7 @@ int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type)
  }
+ EXPORT_SYMBOL(gpio_pm_wakeup_request);
  
- static int rtasd(void *unused)
-diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
-index 05a56e5..e898ff4 100644
---- a/arch/powerpc/sysdev/ipic.c
-+++ b/arch/powerpc/sysdev/ipic.c
-@@ -725,7 +725,7 @@ unsigned int ipic_get_irq(void)
+-void gpio_pm_wakeup_free(unsigned short gpio)
++void gpio_pm_wakeup_free(unsigned gpio)
+ {
+ 	unsigned long flags;
+ 
+@@ -677,7 +670,7 @@ void gpio_pm_wakeup_free(unsigned short gpio)
  }
+ EXPORT_SYMBOL(gpio_pm_wakeup_free);
  
- static struct sysdev_class ipic_sysclass = {
--	set_kset_name("ipic"),
-+	.name = "ipic",
- };
+-static int bfin_gpio_wakeup_type(unsigned short gpio, unsigned char type)
++static int bfin_gpio_wakeup_type(unsigned gpio, unsigned char type)
+ {
+ 	port_setup(gpio, GPIO_USAGE);
+ 	set_gpio_dir(gpio, 0);
+@@ -784,6 +777,14 @@ void gpio_pm_restore(void)
+ }
  
- static struct sys_device device_ipic = {
-diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
-index e479388..212a94f 100644
---- a/arch/powerpc/sysdev/mpic.c
-+++ b/arch/powerpc/sysdev/mpic.c
-@@ -1584,7 +1584,7 @@ static struct sysdev_class mpic_sysclass = {
- 	.resume = mpic_resume,
- 	.suspend = mpic_suspend,
  #endif
--	set_kset_name("mpic"),
-+	.name = "mpic",
- };
++#else /* BF548_FAMILY */
++
++unsigned short get_gpio_dir(unsigned gpio)
++{
++	return (0x01 & (gpio_array[gpio_bank(gpio)]->port_dir_clear >> gpio_sub_n(gpio)));
++}
++EXPORT_SYMBOL(get_gpio_dir);
++
+ #endif /* BF548_FAMILY */
  
- static int mpic_init_sys(void)
-diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
-index e1c0fd6..f59444d 100644
---- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
-+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
-@@ -483,7 +483,7 @@ int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high)
- }
+ /***********************************************************
+@@ -1028,7 +1029,7 @@ EXPORT_SYMBOL(peripheral_free_list);
+ * MODIFICATION HISTORY :
+ **************************************************************/
  
- static struct sysdev_class qe_ic_sysclass = {
--	set_kset_name("qe_ic"),
-+	.name = "qe_ic",
- };
+-int gpio_request(unsigned short gpio, const char *label)
++int gpio_request(unsigned gpio, const char *label)
+ {
+ 	unsigned long flags;
  
- static struct sys_device device_qe_ic = {
-diff --git a/arch/ppc/syslib/ipic.c b/arch/ppc/syslib/ipic.c
-index 9192777..4f163e2 100644
---- a/arch/ppc/syslib/ipic.c
-+++ b/arch/ppc/syslib/ipic.c
-@@ -614,7 +614,7 @@ int ipic_get_irq(void)
+@@ -1075,7 +1076,7 @@ int gpio_request(unsigned short gpio, const char *label)
  }
+ EXPORT_SYMBOL(gpio_request);
  
- static struct sysdev_class ipic_sysclass = {
--	set_kset_name("ipic"),
-+	.name = "ipic",
- };
+-void gpio_free(unsigned short gpio)
++void gpio_free(unsigned gpio)
+ {
+ 	unsigned long flags;
  
- static struct sys_device device_ipic = {
-diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c
-index 18ec947..da36522 100644
---- a/arch/ppc/syslib/open_pic.c
-+++ b/arch/ppc/syslib/open_pic.c
-@@ -1043,7 +1043,7 @@ int openpic_resume(struct sys_device *sysdev)
- #endif /* CONFIG_PM */
+@@ -1085,7 +1086,7 @@ void gpio_free(unsigned short gpio)
+ 	local_irq_save(flags);
  
- static struct sysdev_class openpic_sysclass = {
--	set_kset_name("openpic"),
-+	.name = "openpic",
- };
+ 	if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
+-		printk(KERN_ERR "bfin-gpio: GPIO %d wasn't reserved!\n", gpio);
++		gpio_error(gpio);
+ 		dump_stack();
+ 		local_irq_restore(flags);
+ 		return;
+@@ -1101,44 +1102,55 @@ void gpio_free(unsigned short gpio)
+ }
+ EXPORT_SYMBOL(gpio_free);
  
- static struct sys_device device_openpic = {
-diff --git a/arch/ppc/syslib/open_pic2.c b/arch/ppc/syslib/open_pic2.c
-index d585207..449075a 100644
---- a/arch/ppc/syslib/open_pic2.c
-+++ b/arch/ppc/syslib/open_pic2.c
-@@ -666,7 +666,7 @@ int openpic2_resume(struct sys_device *sysdev)
++
+ #ifdef BF548_FAMILY
+-void gpio_direction_input(unsigned short gpio)
++int gpio_direction_input(unsigned gpio)
+ {
+ 	unsigned long flags;
  
- /* HACK ALERT */
- static struct sysdev_class openpic2_sysclass = {
--	set_kset_name("openpic2"),
-+	.name = "openpic2",
- };
+-	BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
++	if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
++		gpio_error(gpio);
++		return -EINVAL;
++	}
  
- static struct sys_device device_openpic2 = {
-diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
-index 1330061..6ef54d2 100644
---- a/arch/s390/Kconfig
-+++ b/arch/s390/Kconfig
-@@ -276,9 +276,6 @@ source "kernel/Kconfig.preempt"
+ 	local_irq_save(flags);
+ 	gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio);
+ 	gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio);
+ 	local_irq_restore(flags);
++
++	return 0;
+ }
+ EXPORT_SYMBOL(gpio_direction_input);
  
- source "mm/Kconfig"
+-void gpio_direction_output(unsigned short gpio)
++int gpio_direction_output(unsigned gpio, int value)
+ {
+ 	unsigned long flags;
  
--config HOLES_IN_ZONE
--	def_bool y
--
- comment "I/O subsystem configuration"
+-	BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
++	if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
++		gpio_error(gpio);
++		return -EINVAL;
++	}
  
- config MACHCHK_WARNING
-diff --git a/arch/s390/crypto/Kconfig b/arch/s390/crypto/Kconfig
-deleted file mode 100644
-index d1defbb..0000000
---- a/arch/s390/crypto/Kconfig
-+++ /dev/null
-@@ -1,60 +0,0 @@
--config CRYPTO_SHA1_S390
--	tristate "SHA1 digest algorithm"
--	depends on S390
--	select CRYPTO_ALGAPI
--	help
--	  This is the s390 hardware accelerated implementation of the
--	  SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
--
--config CRYPTO_SHA256_S390
--	tristate "SHA256 digest algorithm"
--	depends on S390
--	select CRYPTO_ALGAPI
--	help
--	  This is the s390 hardware accelerated implementation of the
--	  SHA256 secure hash standard (DFIPS 180-2).
--
--	  This version of SHA implements a 256 bit hash with 128 bits of
--	  security against collision attacks.
--
--config CRYPTO_DES_S390
--	tristate "DES and Triple DES cipher algorithms"
--	depends on S390
--	select CRYPTO_ALGAPI
--	select CRYPTO_BLKCIPHER
--	help
--	  This us the s390 hardware accelerated implementation of the
--	  DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
--
--config CRYPTO_AES_S390
--	tristate "AES cipher algorithms"
--	depends on S390
--	select CRYPTO_ALGAPI
--	select CRYPTO_BLKCIPHER
--	help
--	  This is the s390 hardware accelerated implementation of the
--	  AES cipher algorithms (FIPS-197). AES uses the Rijndael
--	  algorithm.
--
--	  Rijndael appears to be consistently a very good performer in
--	  both hardware and software across a wide range of computing
--	  environments regardless of its use in feedback or non-feedback
--	  modes. Its key setup time is excellent, and its key agility is
--	  good. Rijndael's very low memory requirements make it very well
--	  suited for restricted-space environments, in which it also
--	  demonstrates excellent performance. Rijndael's operations are
--	  among the easiest to defend against power and timing attacks.
--
--	  On s390 the System z9-109 currently only supports the key size
--	  of 128 bit.
+ 	local_irq_save(flags);
+ 	gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio);
++	gpio_set_value(gpio, value);
+ 	gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio);
+ 	local_irq_restore(flags);
++
++	return 0;
+ }
+ EXPORT_SYMBOL(gpio_direction_output);
+ 
+-void gpio_set_value(unsigned short gpio, unsigned short arg)
++void gpio_set_value(unsigned gpio, int arg)
+ {
+ 	if (arg)
+ 		gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio);
+ 	else
+ 		gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio);
 -
--config S390_PRNG
--	tristate "Pseudo random number generator device driver"
--	depends on S390
--	default "m"
--	help
--	  Select this option if you want to use the s390 pseudo random number
--	  generator. The PRNG is part of the cryptographic processor functions
--	  and uses triple-DES to generate secure random numbers like the
--	  ANSI X9.17 standard. The PRNG is usable via the char device
--	  /dev/prandom.
-diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c
-index 5126696..a3f67f8 100644
---- a/arch/s390/crypto/aes_s390.c
-+++ b/arch/s390/crypto/aes_s390.c
-@@ -6,6 +6,7 @@
-  * s390 Version:
-  *   Copyright IBM Corp. 2005,2007
-  *   Author(s): Jan Glauber (jang at de.ibm.com)
-+ *		Sebastian Siewior (sebastian at breakpoint.cc> SW-Fallback
-  *
-  * Derived from "crypto/aes_generic.c"
-  *
-@@ -16,17 +17,13 @@
-  *
-  */
+ }
+ EXPORT_SYMBOL(gpio_set_value);
  
-+#include <crypto/aes.h>
- #include <crypto/algapi.h>
-+#include <linux/err.h>
- #include <linux/module.h>
- #include <linux/init.h>
- #include "crypt_s390.h"
+-unsigned short gpio_get_value(unsigned short gpio)
++int gpio_get_value(unsigned gpio)
+ {
+ 	return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio)));
+ }
+@@ -1146,31 +1158,47 @@ EXPORT_SYMBOL(gpio_get_value);
  
--#define AES_MIN_KEY_SIZE	16
--#define AES_MAX_KEY_SIZE	32
--
--/* data block size for all key lengths */
--#define AES_BLOCK_SIZE		16
--
- #define AES_KEYLEN_128		1
- #define AES_KEYLEN_192		2
- #define AES_KEYLEN_256		4
-@@ -39,45 +36,89 @@ struct s390_aes_ctx {
- 	long enc;
- 	long dec;
- 	int key_len;
-+	union {
-+		struct crypto_blkcipher *blk;
-+		struct crypto_cipher *cip;
-+	} fallback;
- };
+ #else
  
--static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
--		       unsigned int key_len)
-+/*
-+ * Check if the key_len is supported by the HW.
-+ * Returns 0 if it is, a positive number if it is not and software fallback is
-+ * required or a negative number in case the key size is not valid
-+ */
-+static int need_fallback(unsigned int key_len)
+-void gpio_direction_input(unsigned short gpio)
++int gpio_direction_input(unsigned gpio)
  {
--	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
--	u32 *flags = &tfm->crt_flags;
--
- 	switch (key_len) {
- 	case 16:
- 		if (!(keylen_flag & AES_KEYLEN_128))
--			goto fail;
-+			return 1;
- 		break;
- 	case 24:
- 		if (!(keylen_flag & AES_KEYLEN_192))
--			goto fail;
--
-+			return 1;
- 		break;
- 	case 32:
- 		if (!(keylen_flag & AES_KEYLEN_256))
--			goto fail;
-+			return 1;
- 		break;
- 	default:
--		goto fail;
-+		return -1;
- 		break;
- 	}
-+	return 0;
-+}
-+
-+static int setkey_fallback_cip(struct crypto_tfm *tfm, const u8 *in_key,
-+		unsigned int key_len)
-+{
-+	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
-+	int ret;
-+
-+	sctx->fallback.blk->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
-+	sctx->fallback.blk->base.crt_flags |= (tfm->crt_flags &
-+			CRYPTO_TFM_REQ_MASK);
-+
-+	ret = crypto_cipher_setkey(sctx->fallback.cip, in_key, key_len);
-+	if (ret) {
-+		tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
-+		tfm->crt_flags |= (sctx->fallback.blk->base.crt_flags &
-+				CRYPTO_TFM_RES_MASK);
-+	}
-+	return ret;
-+}
-+
-+static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
-+		       unsigned int key_len)
-+{
-+	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
-+	u32 *flags = &tfm->crt_flags;
-+	int ret;
-+
-+	ret = need_fallback(key_len);
-+	if (ret < 0) {
-+		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ 	unsigned long flags;
+ 
+-	BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
++	if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
++		gpio_error(gpio);
 +		return -EINVAL;
 +	}
  
- 	sctx->key_len = key_len;
--	memcpy(sctx->key, in_key, key_len);
--	return 0;
--fail:
--	*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
--	return -EINVAL;
-+	if (!ret) {
-+		memcpy(sctx->key, in_key, key_len);
-+		return 0;
-+	}
+ 	local_irq_save(flags);
+ 	gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
+ 	gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio);
+ 	AWA_DUMMY_READ(inen);
+ 	local_irq_restore(flags);
 +
-+	return setkey_fallback_cip(tfm, in_key, key_len);
++	return 0;
  }
+ EXPORT_SYMBOL(gpio_direction_input);
  
- static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
+-void gpio_direction_output(unsigned short gpio)
++int gpio_direction_output(unsigned gpio, int value)
  {
- 	const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
+ 	unsigned long flags;
  
-+	if (unlikely(need_fallback(sctx->key_len))) {
-+		crypto_cipher_encrypt_one(sctx->fallback.cip, out, in);
-+		return;
+-	BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
++	if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
++		gpio_error(gpio);
++		return -EINVAL;
 +	}
-+
- 	switch (sctx->key_len) {
- 	case 16:
- 		crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in,
-@@ -98,6 +139,11 @@ static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
- {
- 	const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
  
-+	if (unlikely(need_fallback(sctx->key_len))) {
-+		crypto_cipher_decrypt_one(sctx->fallback.cip, out, in);
-+		return;
-+	}
+ 	local_irq_save(flags);
+ 	gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
 +
- 	switch (sctx->key_len) {
- 	case 16:
- 		crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in,
-@@ -114,6 +160,29 @@ static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
- 	}
++	if (value)
++		gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
++	else
++		gpio_bankb[gpio_bank(gpio)]->data_clear = gpio_bit(gpio);
++
+ 	gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio);
+ 	AWA_DUMMY_READ(dir);
+ 	local_irq_restore(flags);
++
++	return 0;
  }
+ EXPORT_SYMBOL(gpio_direction_output);
  
-+static int fallback_init_cip(struct crypto_tfm *tfm)
+@@ -1190,7 +1218,40 @@ void bfin_gpio_reset_spi0_ssel1(void)
+ 
+ 	port_setup(gpio, GPIO_USAGE);
+ 	gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
++	AWA_DUMMY_READ(data_set);
+ 	udelay(1);
+ }
+ 
+ #endif /*BF548_FAMILY */
++
++#if defined(CONFIG_PROC_FS)
++static int gpio_proc_read(char *buf, char **start, off_t offset,
++			  int len, int *unused_i, void *unused_v)
++{
++	int c, outlen = 0;
++
++	for (c = 0; c < MAX_RESOURCES; c++) {
++		if (!check_gpio(c) && (reserved_gpio_map[gpio_bank(c)] & gpio_bit(c)))
++			len = sprintf(buf, "GPIO_%d: %s \t\tGPIO %s\n", c,
++				 get_label(c), get_gpio_dir(c) ? "OUTPUT" : "INPUT");
++		else if (reserved_peri_map[gpio_bank(c)] & gpio_bit(c))
++			len = sprintf(buf, "GPIO_%d: %s \t\tPeripheral\n", c, get_label(c));
++		else
++			continue;
++		buf += len;
++		outlen += len;
++	}
++	return outlen;
++}
++
++static __init int gpio_register_proc(void)
 +{
-+	const char *name = tfm->__crt_alg->cra_name;
-+	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
++	struct proc_dir_entry *proc_gpio;
 +
-+	sctx->fallback.cip = crypto_alloc_cipher(name, 0,
-+			CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK);
++	proc_gpio = create_proc_entry("gpio", S_IRUGO, NULL);
++	if (proc_gpio)
++		proc_gpio->read_proc = gpio_proc_read;
++	return proc_gpio != NULL;
++}
++__initcall(gpio_register_proc);
++#endif
+diff --git a/arch/blackfin/kernel/cacheinit.c b/arch/blackfin/kernel/cacheinit.c
+deleted file mode 100644
+index 62cbba7..0000000
+--- a/arch/blackfin/kernel/cacheinit.c
++++ /dev/null
+@@ -1,67 +0,0 @@
+-/*
+- *               Copyright 2004-2007 Analog Devices Inc.
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, see the file COPYING, or write
+- * to the Free Software Foundation, Inc.,
+- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+- */
+-
+-#include <linux/cpu.h>
+-
+-#include <asm/cacheflush.h>
+-#include <asm/blackfin.h>
+-#include <asm/cplb.h>
+-#include <asm/cplbinit.h>
+-
+-#if defined(CONFIG_BFIN_ICACHE)
+-void bfin_icache_init(void)
+-{
+-	unsigned long *table = icplb_table;
+-	unsigned long ctrl;
+-	int i;
+-
+-	for (i = 0; i < MAX_CPLBS; i++) {
+-		unsigned long addr = *table++;
+-		unsigned long data = *table++;
+-		if (addr == (unsigned long)-1)
+-			break;
+-		bfin_write32(ICPLB_ADDR0 + i * 4, addr);
+-		bfin_write32(ICPLB_DATA0 + i * 4, data);
+-	}
+-	ctrl = bfin_read_IMEM_CONTROL();
+-	ctrl |= IMC | ENICPLB;
+-	bfin_write_IMEM_CONTROL(ctrl);
+-}
+-#endif
+-
+-#if defined(CONFIG_BFIN_DCACHE)
+-void bfin_dcache_init(void)
+-{
+-	unsigned long *table = dcplb_table;
+-	unsigned long ctrl;
+-	int i;
+-
+-	for (i = 0; i < MAX_CPLBS; i++) {
+-		unsigned long addr = *table++;
+-		unsigned long data = *table++;
+-		if (addr == (unsigned long)-1)
+-			break;
+-		bfin_write32(DCPLB_ADDR0 + i * 4, addr);
+-		bfin_write32(DCPLB_DATA0 + i * 4, data);
+-	}
+-	ctrl = bfin_read_DMEM_CONTROL();
+-	ctrl |= DMEM_CNTR;
+-	bfin_write_DMEM_CONTROL(ctrl);
+-}
+-#endif
+diff --git a/arch/blackfin/kernel/cplb-mpu/Makefile b/arch/blackfin/kernel/cplb-mpu/Makefile
+new file mode 100644
+index 0000000..286b693
+--- /dev/null
++++ b/arch/blackfin/kernel/cplb-mpu/Makefile
+@@ -0,0 +1,8 @@
++#
++# arch/blackfin/kernel/cplb-nompu/Makefile
++#
 +
-+	if (IS_ERR(sctx->fallback.cip)) {
-+		printk(KERN_ERR "Error allocating fallback algo %s\n", name);
-+		return PTR_ERR(sctx->fallback.blk);
++obj-y := cplbinit.o cacheinit.o cplbmgr.o
++
++obj-$(CONFIG_CPLB_INFO) += cplbinfo.o
++
+diff --git a/arch/blackfin/kernel/cplb-mpu/cacheinit.c b/arch/blackfin/kernel/cplb-mpu/cacheinit.c
+new file mode 100644
+index 0000000..9eecfa4
+--- /dev/null
++++ b/arch/blackfin/kernel/cplb-mpu/cacheinit.c
+@@ -0,0 +1,62 @@
++/*
++ *               Copyright 2004-2007 Analog Devices Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, see the file COPYING, or write
++ * to the Free Software Foundation, Inc.,
++ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++ */
++
++#include <linux/cpu.h>
++
++#include <asm/cacheflush.h>
++#include <asm/blackfin.h>
++#include <asm/cplb.h>
++#include <asm/cplbinit.h>
++
++#if defined(CONFIG_BFIN_ICACHE)
++void bfin_icache_init(void)
++{
++	unsigned long ctrl;
++	int i;
++
++	SSYNC();
++	for (i = 0; i < MAX_CPLBS; i++) {
++		bfin_write32(ICPLB_ADDR0 + i * 4, icplb_tbl[i].addr);
++		bfin_write32(ICPLB_DATA0 + i * 4, icplb_tbl[i].data);
 +	}
++	ctrl = bfin_read_IMEM_CONTROL();
++	ctrl |= IMC | ENICPLB;
++	bfin_write_IMEM_CONTROL(ctrl);
++	SSYNC();
++}
++#endif
 +
-+	return 0;
++#if defined(CONFIG_BFIN_DCACHE)
++void bfin_dcache_init(void)
++{
++	unsigned long ctrl;
++	int i;
++
++	SSYNC();
++	for (i = 0; i < MAX_CPLBS; i++) {
++		bfin_write32(DCPLB_ADDR0 + i * 4, dcplb_tbl[i].addr);
++		bfin_write32(DCPLB_DATA0 + i * 4, dcplb_tbl[i].data);
++	}
++
++	ctrl = bfin_read_DMEM_CONTROL();
++	ctrl |= DMEM_CNTR;
++	bfin_write_DMEM_CONTROL(ctrl);
++	SSYNC();
++}
++#endif
+diff --git a/arch/blackfin/kernel/cplb-mpu/cplbinfo.c b/arch/blackfin/kernel/cplb-mpu/cplbinfo.c
+new file mode 100644
+index 0000000..bd07229
+--- /dev/null
++++ b/arch/blackfin/kernel/cplb-mpu/cplbinfo.c
+@@ -0,0 +1,144 @@
++/*
++ * File:         arch/blackfin/mach-common/cplbinfo.c
++ * Based on:
++ * Author:       Sonic Zhang <sonic.zhang at analog.com>
++ *
++ * Created:      Jan. 2005
++ * Description:  Display CPLB status
++ *
++ * Modified:
++ *               Copyright 2004-2006 Analog Devices Inc.
++ *
++ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, see the file COPYING, or write
++ * to the Free Software Foundation, Inc.,
++ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/proc_fs.h>
++#include <linux/uaccess.h>
++
++#include <asm/current.h>
++#include <asm/system.h>
++#include <asm/cplb.h>
++#include <asm/cplbinit.h>
++#include <asm/blackfin.h>
++
++#define CPLB_I 1
++#define CPLB_D 2
++
++#define SYNC_SYS    SSYNC()
++#define SYNC_CORE   CSYNC()
++
++#define CPLB_BIT_PAGESIZE 0x30000
++
++static char page_size_string_table[][4] = { "1K", "4K", "1M", "4M" };
++
++static char *cplb_print_entry(char *buf, struct cplb_entry *tbl, int switched)
++{
++	int i;
++	buf += sprintf(buf, "Index\tAddress\t\tData\tSize\tU/RD\tU/WR\tS/WR\tSwitch\n");
++	for (i = 0; i < MAX_CPLBS; i++) {
++		unsigned long data = tbl[i].data;
++		unsigned long addr = tbl[i].addr;
++		if (!(data & CPLB_VALID))
++			continue;
++
++		buf +=
++		    sprintf(buf,
++			    "%d\t0x%08lx\t%06lx\t%s\t%c\t%c\t%c\t%c\n",
++			    i, addr, data,
++			    page_size_string_table[(data & 0x30000) >> 16],
++			    (data & CPLB_USER_RD) ? 'Y' : 'N',
++			    (data & CPLB_USER_WR) ? 'Y' : 'N',
++			    (data & CPLB_SUPV_WR) ? 'Y' : 'N',
++			    i < switched ? 'N' : 'Y');
++	}
++	buf += sprintf(buf, "\n");
++
++	return buf;
 +}
 +
-+static void fallback_exit_cip(struct crypto_tfm *tfm)
++int cplbinfo_proc_output(char *buf)
 +{
-+	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
++	char *p;
 +
-+	crypto_free_cipher(sctx->fallback.cip);
-+	sctx->fallback.cip = NULL;
++	p = buf;
++
++	p += sprintf(p, "------------------ CPLB Information ------------------\n\n");
++
++	if (bfin_read_IMEM_CONTROL() & ENICPLB) {
++		p += sprintf(p, "Instruction CPLB entry:\n");
++		p = cplb_print_entry(p, icplb_tbl, first_switched_icplb);
++	} else
++		p += sprintf(p, "Instruction CPLB is disabled.\n\n");
++
++	if (1 || bfin_read_DMEM_CONTROL() & ENDCPLB) {
++		p += sprintf(p, "Data CPLB entry:\n");
++		p = cplb_print_entry(p, dcplb_tbl, first_switched_dcplb);
++	} else
++		p += sprintf(p, "Data CPLB is disabled.\n");
++
++	p += sprintf(p, "ICPLB miss: %d\nICPLB supervisor miss: %d\n",
++		     nr_icplb_miss, nr_icplb_supv_miss);
++	p += sprintf(p, "DCPLB miss: %d\nDCPLB protection fault:%d\n",
++		     nr_dcplb_miss, nr_dcplb_prot);
++	p += sprintf(p, "CPLB flushes: %d\n",
++		     nr_cplb_flush);
++
++	return p - buf;
 +}
- 
- static struct crypto_alg aes_alg = {
- 	.cra_name		=	"aes",
-@@ -125,6 +194,8 @@ static struct crypto_alg aes_alg = {
- 	.cra_ctxsize		=	sizeof(struct s390_aes_ctx),
- 	.cra_module		=	THIS_MODULE,
- 	.cra_list		=	LIST_HEAD_INIT(aes_alg.cra_list),
-+	.cra_init               =       fallback_init_cip,
-+	.cra_exit               =       fallback_exit_cip,
- 	.cra_u			=	{
- 		.cipher = {
- 			.cia_min_keysize	=	AES_MIN_KEY_SIZE,
-@@ -136,10 +207,70 @@ static struct crypto_alg aes_alg = {
- 	}
- };
- 
-+static int setkey_fallback_blk(struct crypto_tfm *tfm, const u8 *key,
-+		unsigned int len)
++
++static int cplbinfo_read_proc(char *page, char **start, off_t off,
++			      int count, int *eof, void *data)
 +{
-+	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
-+	unsigned int ret;
++	int len;
 +
-+	sctx->fallback.blk->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
-+	sctx->fallback.blk->base.crt_flags |= (tfm->crt_flags &
-+			CRYPTO_TFM_REQ_MASK);
++	len = cplbinfo_proc_output(page);
++	if (len <= off + count)
++		*eof = 1;
++	*start = page + off;
++	len -= off;
++	if (len > count)
++		len = count;
++	if (len < 0)
++		len = 0;
++	return len;
++}
 +
-+	ret = crypto_blkcipher_setkey(sctx->fallback.blk, key, len);
-+	if (ret) {
-+		tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
-+		tfm->crt_flags |= (sctx->fallback.blk->base.crt_flags &
-+				CRYPTO_TFM_RES_MASK);
++static int __init cplbinfo_init(void)
++{
++	struct proc_dir_entry *entry;
++
++	entry = create_proc_entry("cplbinfo", 0, NULL);
++	if (!entry)
++		return -ENOMEM;
++
++	entry->read_proc = cplbinfo_read_proc;
++	entry->data = NULL;
++
++	return 0;
++}
++
++static void __exit cplbinfo_exit(void)
++{
++	remove_proc_entry("cplbinfo", NULL);
++}
++
++module_init(cplbinfo_init);
++module_exit(cplbinfo_exit);
+diff --git a/arch/blackfin/kernel/cplb-mpu/cplbinit.c b/arch/blackfin/kernel/cplb-mpu/cplbinit.c
+new file mode 100644
+index 0000000..e2e2b50
+--- /dev/null
++++ b/arch/blackfin/kernel/cplb-mpu/cplbinit.c
+@@ -0,0 +1,91 @@
++/*
++ * Blackfin CPLB initialization
++ *
++ *               Copyright 2004-2007 Analog Devices Inc.
++ *
++ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, see the file COPYING, or write
++ * to the Free Software Foundation, Inc.,
++ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++ */
++#include <linux/module.h>
++
++#include <asm/blackfin.h>
++#include <asm/cplb.h>
++#include <asm/cplbinit.h>
++
++struct cplb_entry icplb_tbl[MAX_CPLBS];
++struct cplb_entry dcplb_tbl[MAX_CPLBS];
++
++int first_switched_icplb, first_switched_dcplb;
++int first_mask_dcplb;
++
++void __init generate_cpl_tables(void)
++{
++	int i_d, i_i;
++	unsigned long addr;
++	unsigned long d_data, i_data;
++	unsigned long d_cache = 0, i_cache = 0;
++
++#ifdef CONFIG_BFIN_ICACHE
++	i_cache = CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND;
++#endif
++
++#ifdef CONFIG_BFIN_DCACHE
++	d_cache = CPLB_L1_CHBL;
++#ifdef CONFIG_BLKFIN_WT
++	d_cache |= CPLB_L1_AOW | CPLB_WT;
++#endif
++#endif
++	i_d = i_i = 0;
++
++	/* Set up the zero page.  */
++	dcplb_tbl[i_d].addr = 0;
++	dcplb_tbl[i_d++].data = SDRAM_OOPS | PAGE_SIZE_1KB;
++
++#if 0
++	icplb_tbl[i_i].addr = 0;
++	icplb_tbl[i_i++].data = i_cache | CPLB_USER_RD | PAGE_SIZE_4KB;
++#endif
++
++	/* Cover kernel memory with 4M pages.  */
++	addr = 0;
++	d_data = d_cache | CPLB_SUPV_WR | CPLB_VALID | PAGE_SIZE_4MB | CPLB_DIRTY;
++	i_data = i_cache | CPLB_VALID | CPLB_PORTPRIO | PAGE_SIZE_4MB;
++
++	for (; addr < memory_start; addr += 4 * 1024 * 1024) {
++		dcplb_tbl[i_d].addr = addr;
++		dcplb_tbl[i_d++].data = d_data;
++		icplb_tbl[i_i].addr = addr;
++		icplb_tbl[i_i++].data = i_data | (addr == 0 ? CPLB_USER_RD : 0);
 +	}
-+	return ret;
++
++	/* Cover L1 memory.  One 4M area for code and data each is enough.  */
++#if L1_DATA_A_LENGTH > 0 || L1_DATA_B_LENGTH > 0
++	dcplb_tbl[i_d].addr = L1_DATA_A_START;
++	dcplb_tbl[i_d++].data = L1_DMEMORY | PAGE_SIZE_4MB;
++#endif
++	icplb_tbl[i_i].addr = L1_CODE_START;
++	icplb_tbl[i_i++].data = L1_IMEMORY | PAGE_SIZE_4MB;
++
++	first_mask_dcplb = i_d;
++	first_switched_dcplb = i_d + (1 << page_mask_order);
++	first_switched_icplb = i_i;
++
++	while (i_d < MAX_CPLBS)
++		dcplb_tbl[i_d++].data = 0;
++	while (i_i < MAX_CPLBS)
++		icplb_tbl[i_i++].data = 0;
++}
+diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
+new file mode 100644
+index 0000000..c426a22
+--- /dev/null
++++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
+@@ -0,0 +1,338 @@
++/*
++ *               Blackfin CPLB exception handling.
++ *               Copyright 2004-2007 Analog Devices Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, see the file COPYING, or write
++ * to the Free Software Foundation, Inc.,
++ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++ */
++#include <linux/module.h>
++#include <linux/mm.h>
++
++#include <asm/blackfin.h>
++#include <asm/cplbinit.h>
++#include <asm/mmu_context.h>
++
++#ifdef CONFIG_BFIN_ICACHE
++
++#define FAULT_RW	(1 << 16)
++#define FAULT_USERSUPV	(1 << 17)
++
++int page_mask_nelts;
++int page_mask_order;
++unsigned long *current_rwx_mask;
++
++int nr_dcplb_miss, nr_icplb_miss, nr_icplb_supv_miss, nr_dcplb_prot;
++int nr_cplb_flush;
++
++static inline void disable_dcplb(void)
++{
++	unsigned long ctrl;
++	SSYNC();
++	ctrl = bfin_read_DMEM_CONTROL();
++	ctrl &= ~ENDCPLB;
++	bfin_write_DMEM_CONTROL(ctrl);
++	SSYNC();
 +}
 +
-+static int fallback_blk_dec(struct blkcipher_desc *desc,
-+		struct scatterlist *dst, struct scatterlist *src,
-+		unsigned int nbytes)
++static inline void enable_dcplb(void)
 +{
-+	unsigned int ret;
-+	struct crypto_blkcipher *tfm;
-+	struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
++	unsigned long ctrl;
++	SSYNC();
++	ctrl = bfin_read_DMEM_CONTROL();
++	ctrl |= ENDCPLB;
++	bfin_write_DMEM_CONTROL(ctrl);
++	SSYNC();
++}
 +
-+	tfm = desc->tfm;
-+	desc->tfm = sctx->fallback.blk;
++static inline void disable_icplb(void)
++{
++	unsigned long ctrl;
++	SSYNC();
++	ctrl = bfin_read_IMEM_CONTROL();
++	ctrl &= ~ENICPLB;
++	bfin_write_IMEM_CONTROL(ctrl);
++	SSYNC();
++}
 +
-+	ret = crypto_blkcipher_decrypt_iv(desc, dst, src, nbytes);
++static inline void enable_icplb(void)
++{
++	unsigned long ctrl;
++	SSYNC();
++	ctrl = bfin_read_IMEM_CONTROL();
++	ctrl |= ENICPLB;
++	bfin_write_IMEM_CONTROL(ctrl);
++	SSYNC();
++}
 +
-+	desc->tfm = tfm;
-+	return ret;
++/*
++ * Given the contents of the status register, return the index of the
++ * CPLB that caused the fault.
++ */
++static inline int faulting_cplb_index(int status)
++{
++	int signbits = __builtin_bfin_norm_fr1x32(status & 0xFFFF);
++	return 30 - signbits;
 +}
 +
-+static int fallback_blk_enc(struct blkcipher_desc *desc,
-+		struct scatterlist *dst, struct scatterlist *src,
-+		unsigned int nbytes)
++/*
++ * Given the contents of the status register and the DCPLB_DATA contents,
++ * return true if a write access should be permitted.
++ */
++static inline int write_permitted(int status, unsigned long data)
 +{
-+	unsigned int ret;
-+	struct crypto_blkcipher *tfm;
-+	struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
++	if (status & FAULT_USERSUPV)
++		return !!(data & CPLB_SUPV_WR);
++	else
++		return !!(data & CPLB_USER_WR);
++}
 +
-+	tfm = desc->tfm;
-+	desc->tfm = sctx->fallback.blk;
++/* Counters to implement round-robin replacement.  */
++static int icplb_rr_index, dcplb_rr_index;
 +
-+	ret = crypto_blkcipher_encrypt_iv(desc, dst, src, nbytes);
++/*
++ * Find an ICPLB entry to be evicted and return its index.
++ */
++static int evict_one_icplb(void)
++{
++	int i;
++	for (i = first_switched_icplb; i < MAX_CPLBS; i++)
++		if ((icplb_tbl[i].data & CPLB_VALID) == 0)
++			return i;
++	i = first_switched_icplb + icplb_rr_index;
++	if (i >= MAX_CPLBS) {
++		i -= MAX_CPLBS - first_switched_icplb;
++		icplb_rr_index -= MAX_CPLBS - first_switched_icplb;
++	}
++	icplb_rr_index++;
++	return i;
++}
 +
-+	desc->tfm = tfm;
-+	return ret;
++static int evict_one_dcplb(void)
++{
++	int i;
++	for (i = first_switched_dcplb; i < MAX_CPLBS; i++)
++		if ((dcplb_tbl[i].data & CPLB_VALID) == 0)
++			return i;
++	i = first_switched_dcplb + dcplb_rr_index;
++	if (i >= MAX_CPLBS) {
++		i -= MAX_CPLBS - first_switched_dcplb;
++		dcplb_rr_index -= MAX_CPLBS - first_switched_dcplb;
++	}
++	dcplb_rr_index++;
++	return i;
 +}
 +
- static int ecb_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
- 			   unsigned int key_len)
- {
- 	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
-+	int ret;
++static noinline int dcplb_miss(void)
++{
++	unsigned long addr = bfin_read_DCPLB_FAULT_ADDR();
++	int status = bfin_read_DCPLB_STATUS();
++	unsigned long *mask;
++	int idx;
++	unsigned long d_data;
 +
-+	ret = need_fallback(key_len);
-+	if (ret > 0) {
-+		sctx->key_len = key_len;
-+		return setkey_fallback_blk(tfm, in_key, key_len);
++	nr_dcplb_miss++;
++	if (addr >= _ramend)
++		return CPLB_PROT_VIOL;
++
++	d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB;
++#ifdef CONFIG_BFIN_DCACHE
++	d_data |= CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND;
++#ifdef CONFIG_BLKFIN_WT
++	d_data |= CPLB_L1_AOW | CPLB_WT;
++#endif
++#endif
++	mask = current_rwx_mask;
++	if (mask) {
++		int page = addr >> PAGE_SHIFT;
++		int offs = page >> 5;
++		int bit = 1 << (page & 31);
++
++		if (mask[offs] & bit)
++			d_data |= CPLB_USER_RD;
++
++		mask += page_mask_nelts;
++		if (mask[offs] & bit)
++			d_data |= CPLB_USER_WR;
 +	}
- 
- 	switch (key_len) {
- 	case 16:
-@@ -188,6 +319,9 @@ static int ecb_aes_encrypt(struct blkcipher_desc *desc,
- 	struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
- 	struct blkcipher_walk walk;
- 
-+	if (unlikely(need_fallback(sctx->key_len)))
-+		return fallback_blk_enc(desc, dst, src, nbytes);
 +
- 	blkcipher_walk_init(&walk, dst, src, nbytes);
- 	return ecb_aes_crypt(desc, sctx->enc, sctx->key, &walk);
- }
-@@ -199,10 +333,37 @@ static int ecb_aes_decrypt(struct blkcipher_desc *desc,
- 	struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
- 	struct blkcipher_walk walk;
- 
-+	if (unlikely(need_fallback(sctx->key_len)))
-+		return fallback_blk_dec(desc, dst, src, nbytes);
++	idx = evict_one_dcplb();
 +
- 	blkcipher_walk_init(&walk, dst, src, nbytes);
- 	return ecb_aes_crypt(desc, sctx->dec, sctx->key, &walk);
- }
- 
-+static int fallback_init_blk(struct crypto_tfm *tfm)
++	addr &= PAGE_MASK;
++	dcplb_tbl[idx].addr = addr;
++	dcplb_tbl[idx].data = d_data;
++
++	disable_dcplb();
++	bfin_write32(DCPLB_DATA0 + idx * 4, d_data);
++	bfin_write32(DCPLB_ADDR0 + idx * 4, addr);
++	enable_dcplb();
++
++	return 0;
++}
++
++static noinline int icplb_miss(void)
 +{
-+	const char *name = tfm->__crt_alg->cra_name;
-+	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
++	unsigned long addr = bfin_read_ICPLB_FAULT_ADDR();
++	int status = bfin_read_ICPLB_STATUS();
++	int idx;
++	unsigned long i_data;
 +
-+	sctx->fallback.blk = crypto_alloc_blkcipher(name, 0,
-+			CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK);
++	nr_icplb_miss++;
++	if (status & FAULT_USERSUPV)
++		nr_icplb_supv_miss++;
 +
-+	if (IS_ERR(sctx->fallback.blk)) {
-+		printk(KERN_ERR "Error allocating fallback algo %s\n", name);
-+		return PTR_ERR(sctx->fallback.blk);
++	if (addr >= _ramend)
++		return CPLB_PROT_VIOL;
++
++	/*
++	 * First, try to find a CPLB that matches this address.  If we
++	 * find one, then the fact that we're in the miss handler means
++	 * that the instruction crosses a page boundary.
++	 */
++	for (idx = first_switched_icplb; idx < MAX_CPLBS; idx++) {
++		if (icplb_tbl[idx].data & CPLB_VALID) {
++			unsigned long this_addr = icplb_tbl[idx].addr;
++			if (this_addr <= addr && this_addr + PAGE_SIZE > addr) {
++				addr += PAGE_SIZE;
++				break;
++			}
++		}
 +	}
 +
++	i_data = CPLB_VALID | CPLB_PORTPRIO | PAGE_SIZE_4KB;
++#ifdef CONFIG_BFIN_ICACHE
++	i_data |= CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND;
++#endif
++
++	/*
++	 * Two cases to distinguish - a supervisor access must necessarily
++	 * be for a module page; we grant it unconditionally (could do better
++	 * here in the future).  Otherwise, check the x bitmap of the current
++	 * process.
++	 */
++	if (!(status & FAULT_USERSUPV)) {
++		unsigned long *mask = current_rwx_mask;
++
++		if (mask) {
++			int page = addr >> PAGE_SHIFT;
++			int offs = page >> 5;
++			int bit = 1 << (page & 31);
++
++			mask += 2 * page_mask_nelts;
++			if (mask[offs] & bit)
++				i_data |= CPLB_USER_RD;
++		}
++	}
++
++	idx = evict_one_icplb();
++	addr &= PAGE_MASK;
++	icplb_tbl[idx].addr = addr;
++	icplb_tbl[idx].data = i_data;
++
++	disable_icplb();
++	bfin_write32(ICPLB_DATA0 + idx * 4, i_data);
++	bfin_write32(ICPLB_ADDR0 + idx * 4, addr);
++	enable_icplb();
++
 +	return 0;
 +}
 +
-+static void fallback_exit_blk(struct crypto_tfm *tfm)
++static noinline int dcplb_protection_fault(void)
 +{
-+	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
++	unsigned long addr = bfin_read_DCPLB_FAULT_ADDR();
++	int status = bfin_read_DCPLB_STATUS();
 +
-+	crypto_free_blkcipher(sctx->fallback.blk);
-+	sctx->fallback.blk = NULL;
++	nr_dcplb_prot++;
++
++	if (status & FAULT_RW) {
++		int idx = faulting_cplb_index(status);
++		unsigned long data = dcplb_tbl[idx].data;
++		if (!(data & CPLB_WT) && !(data & CPLB_DIRTY) &&
++		    write_permitted(status, data)) {
++			data |= CPLB_DIRTY;
++			dcplb_tbl[idx].data = data;
++			bfin_write32(DCPLB_DATA0 + idx * 4, data);
++			return 0;
++		}
++	}
++	return CPLB_PROT_VIOL;
 +}
 +
- static struct crypto_alg ecb_aes_alg = {
- 	.cra_name		=	"ecb(aes)",
- 	.cra_driver_name	=	"ecb-aes-s390",
-@@ -214,6 +375,8 @@ static struct crypto_alg ecb_aes_alg = {
- 	.cra_type		=	&crypto_blkcipher_type,
- 	.cra_module		=	THIS_MODULE,
- 	.cra_list		=	LIST_HEAD_INIT(ecb_aes_alg.cra_list),
-+	.cra_init		=	fallback_init_blk,
-+	.cra_exit		=	fallback_exit_blk,
- 	.cra_u			=	{
- 		.blkcipher = {
- 			.min_keysize		=	AES_MIN_KEY_SIZE,
-@@ -229,6 +392,13 @@ static int cbc_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
- 			   unsigned int key_len)
- {
- 	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
-+	int ret;
++int cplb_hdr(int seqstat, struct pt_regs *regs)
++{
++	int cause = seqstat & 0x3f;
++	switch (cause) {
++	case 0x23:
++		return dcplb_protection_fault();
++	case 0x2C:
++		return icplb_miss();
++	case 0x26:
++		return dcplb_miss();
++	default:
++	    return 1;
++		panic_cplb_error(seqstat, regs);
++	}
++}
 +
-+	ret = need_fallback(key_len);
-+	if (ret > 0) {
-+		sctx->key_len = key_len;
-+		return setkey_fallback_blk(tfm, in_key, key_len);
++void flush_switched_cplbs(void)
++{
++	int i;
++
++	nr_cplb_flush++;
++
++	disable_icplb();
++	for (i = first_switched_icplb; i < MAX_CPLBS; i++) {
++		icplb_tbl[i].data = 0;
++		bfin_write32(ICPLB_DATA0 + i * 4, 0);
 +	}
- 
- 	switch (key_len) {
- 	case 16:
-@@ -283,6 +453,9 @@ static int cbc_aes_encrypt(struct blkcipher_desc *desc,
- 	struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
- 	struct blkcipher_walk walk;
- 
-+	if (unlikely(need_fallback(sctx->key_len)))
-+		return fallback_blk_enc(desc, dst, src, nbytes);
++	enable_icplb();
 +
- 	blkcipher_walk_init(&walk, dst, src, nbytes);
- 	return cbc_aes_crypt(desc, sctx->enc, sctx->iv, &walk);
- }
-@@ -294,6 +467,9 @@ static int cbc_aes_decrypt(struct blkcipher_desc *desc,
- 	struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
- 	struct blkcipher_walk walk;
- 
-+	if (unlikely(need_fallback(sctx->key_len)))
-+		return fallback_blk_dec(desc, dst, src, nbytes);
++	disable_dcplb();
++	for (i = first_mask_dcplb; i < MAX_CPLBS; i++) {
++		dcplb_tbl[i].data = 0;
++		bfin_write32(DCPLB_DATA0 + i * 4, 0);
++	}
++	enable_dcplb();
++}
 +
- 	blkcipher_walk_init(&walk, dst, src, nbytes);
- 	return cbc_aes_crypt(desc, sctx->dec, sctx->iv, &walk);
- }
-@@ -309,6 +485,8 @@ static struct crypto_alg cbc_aes_alg = {
- 	.cra_type		=	&crypto_blkcipher_type,
- 	.cra_module		=	THIS_MODULE,
- 	.cra_list		=	LIST_HEAD_INIT(cbc_aes_alg.cra_list),
-+	.cra_init		=	fallback_init_blk,
-+	.cra_exit		=	fallback_exit_blk,
- 	.cra_u			=	{
- 		.blkcipher = {
- 			.min_keysize		=	AES_MIN_KEY_SIZE,
-@@ -336,14 +514,10 @@ static int __init aes_init(void)
- 		return -EOPNOTSUPP;
- 
- 	/* z9 109 and z9 BC/EC only support 128 bit key length */
--	if (keylen_flag == AES_KEYLEN_128) {
--		aes_alg.cra_u.cipher.cia_max_keysize = AES_MIN_KEY_SIZE;
--		ecb_aes_alg.cra_u.blkcipher.max_keysize = AES_MIN_KEY_SIZE;
--		cbc_aes_alg.cra_u.blkcipher.max_keysize = AES_MIN_KEY_SIZE;
-+	if (keylen_flag == AES_KEYLEN_128)
- 		printk(KERN_INFO
--		       "aes_s390: hardware acceleration only available for"
-+		       "aes_s390: hardware acceleration only available for "
- 		       "128 bit keys\n");
--	}
- 
- 	ret = crypto_register_alg(&aes_alg);
- 	if (ret)
-@@ -382,4 +556,3 @@ MODULE_ALIAS("aes");
- 
- MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
- MODULE_LICENSE("GPL");
--
-diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c
-index 8eb3a1a..0cfefdd 100644
---- a/arch/s390/crypto/prng.c
-+++ b/arch/s390/crypto/prng.c
-@@ -90,7 +90,7 @@ static ssize_t prng_read(struct file *file, char __user *ubuf, size_t nbytes,
- 	int ret = 0;
- 	int tmp;
- 
--	/* nbytes can be arbitrary long, we spilt it into chunks */
-+	/* nbytes can be arbitrary length, we split it into chunks */
- 	while (nbytes) {
- 		/* same as in extract_entropy_user in random.c */
- 		if (need_resched()) {
-@@ -146,7 +146,7 @@ static ssize_t prng_read(struct file *file, char __user *ubuf, size_t nbytes,
- 	return ret;
- }
- 
--static struct file_operations prng_fops = {
-+static const struct file_operations prng_fops = {
- 	.owner		= THIS_MODULE,
- 	.open		= &prng_open,
- 	.release	= NULL,
-diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
-index 5245717..4b010ff 100644
---- a/arch/s390/hypfs/inode.c
-+++ b/arch/s390/hypfs/inode.c
-@@ -490,7 +490,7 @@ static struct super_operations hypfs_s_ops = {
- 	.show_options	= hypfs_show_options,
- };
- 
--static decl_subsys(s390, NULL, NULL);
-+static struct kobject *s390_kobj;
- 
- static int __init hypfs_init(void)
- {
-@@ -506,17 +506,18 @@ static int __init hypfs_init(void)
- 			goto fail_diag;
- 		}
- 	}
--	kobj_set_kset_s(&s390_subsys, hypervisor_subsys);
--	rc = subsystem_register(&s390_subsys);
--	if (rc)
-+	s390_kobj = kobject_create_and_add("s390", hypervisor_kobj);
-+	if (!s390_kobj) {
-+		rc = -ENOMEM;;
- 		goto fail_sysfs;
++void set_mask_dcplbs(unsigned long *masks)
++{
++	int i;
++	unsigned long addr = (unsigned long)masks;
++	unsigned long d_data;
++	current_rwx_mask = masks;
++
++	if (!masks)
++		return;
++
++	d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB;
++#ifdef CONFIG_BFIN_DCACHE
++	d_data |= CPLB_L1_CHBL;
++#ifdef CONFIG_BLKFIN_WT
++	d_data |= CPLB_L1_AOW | CPLB_WT;
++#endif
++#endif
++
++	disable_dcplb();
++	for (i = first_mask_dcplb; i < first_switched_dcplb; i++) {
++		dcplb_tbl[i].addr = addr;
++		dcplb_tbl[i].data = d_data;
++		bfin_write32(DCPLB_DATA0 + i * 4, d_data);
++		bfin_write32(DCPLB_ADDR0 + i * 4, addr);
++		addr += PAGE_SIZE;
 +	}
- 	rc = register_filesystem(&hypfs_type);
- 	if (rc)
- 		goto fail_filesystem;
- 	return 0;
- 
- fail_filesystem:
--	subsystem_unregister(&s390_subsys);
-+	kobject_put(s390_kobj);
- fail_sysfs:
- 	if (!MACHINE_IS_VM)
- 		hypfs_diag_exit();
-@@ -530,7 +531,7 @@ static void __exit hypfs_exit(void)
- 	if (!MACHINE_IS_VM)
- 		hypfs_diag_exit();
- 	unregister_filesystem(&hypfs_type);
--	subsystem_unregister(&s390_subsys);
-+	kobject_put(s390_kobj);
- }
- 
- module_init(hypfs_init)
-diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
-index 56cb710..b3b650a 100644
---- a/arch/s390/kernel/Makefile
-+++ b/arch/s390/kernel/Makefile
-@@ -31,7 +31,3 @@ S390_KEXEC_OBJS := machine_kexec.o crash.o
- S390_KEXEC_OBJS += $(if $(CONFIG_64BIT),relocate_kernel64.o,relocate_kernel.o)
- obj-$(CONFIG_KEXEC) += $(S390_KEXEC_OBJS)
- 
--#
--# This is just to get the dependencies...
--#
--binfmt_elf32.o:	$(TOPDIR)/fs/binfmt_elf.c
-diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
-index 1b3af7d..9f7b73b 100644
---- a/arch/s390/kernel/early.c
-+++ b/arch/s390/kernel/early.c
-@@ -276,7 +276,7 @@ void __init startup_init(void)
- 	create_kernel_nss();
- 	sort_main_extable();
- 	setup_lowcore_early();
--	sclp_readinfo_early();
-+	sclp_read_info_early();
- 	sclp_facilities_detect();
- 	memsize = sclp_memory_detect();
- #ifndef CONFIG_64BIT
-diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
-index a87b197..79dccd2 100644
---- a/arch/s390/kernel/head64.S
-+++ b/arch/s390/kernel/head64.S
-@@ -157,7 +157,7 @@ startup_continue:
- 	.long	0xb2b10000		# store facility list
- 	tm	0xc8,0x08		# check bit for clearing-by-ASCE
- 	bno	0f-.LPG1(%r13)
--	lhi	%r1,2094
-+	lhi	%r1,2048
- 	lhi	%r2,0
- 	.long	0xb98e2001
- 	oi	7(%r12),0x80		# set IDTE flag
-diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
-index ce0856d..db28cca 100644
---- a/arch/s390/kernel/ipl.c
-+++ b/arch/s390/kernel/ipl.c
-@@ -2,7 +2,7 @@
-  *  arch/s390/kernel/ipl.c
-  *    ipl/reipl/dump support for Linux on s390.
-  *
-- *    Copyright (C) IBM Corp. 2005,2006
-+ *    Copyright IBM Corp. 2005,2007
-  *    Author(s): Michael Holzheu <holzheu at de.ibm.com>
-  *		 Heiko Carstens <heiko.carstens at de.ibm.com>
-  *		 Volker Sameske <sameske at de.ibm.com>
-@@ -31,6 +31,43 @@
- #define IPL_FCP_DUMP_STR	"fcp_dump"
- #define IPL_NSS_STR		"nss"
- 
-+#define DUMP_CCW_STR		"ccw"
-+#define DUMP_FCP_STR		"fcp"
-+#define DUMP_NONE_STR		"none"
++	enable_dcplb();
++}
++
++#endif
+diff --git a/arch/blackfin/kernel/cplb-nompu/Makefile b/arch/blackfin/kernel/cplb-nompu/Makefile
+new file mode 100644
+index 0000000..d36ea9b
+--- /dev/null
++++ b/arch/blackfin/kernel/cplb-nompu/Makefile
+@@ -0,0 +1,8 @@
++#
++# arch/blackfin/kernel/cplb-nompu/Makefile
++#
++
++obj-y := cplbinit.o cacheinit.o cplbhdlr.o cplbmgr.o
++
++obj-$(CONFIG_CPLB_INFO) += cplbinfo.o
 +
+diff --git a/arch/blackfin/kernel/cplb-nompu/cacheinit.c b/arch/blackfin/kernel/cplb-nompu/cacheinit.c
+new file mode 100644
+index 0000000..8a18399
+--- /dev/null
++++ b/arch/blackfin/kernel/cplb-nompu/cacheinit.c
+@@ -0,0 +1,69 @@
 +/*
-+ * Four shutdown trigger types are supported:
-+ * - panic
-+ * - halt
-+ * - power off
-+ * - reipl
++ *               Copyright 2004-2007 Analog Devices Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, see the file COPYING, or write
++ * to the Free Software Foundation, Inc.,
++ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 + */
-+#define ON_PANIC_STR		"on_panic"
-+#define ON_HALT_STR		"on_halt"
-+#define ON_POFF_STR		"on_poff"
-+#define ON_REIPL_STR		"on_reboot"
 +
-+struct shutdown_action;
-+struct shutdown_trigger {
-+	char *name;
-+	struct shutdown_action *action;
-+};
++#include <linux/cpu.h>
++
++#include <asm/cacheflush.h>
++#include <asm/blackfin.h>
++#include <asm/cplb.h>
++#include <asm/cplbinit.h>
++
++#if defined(CONFIG_BFIN_ICACHE)
++void bfin_icache_init(void)
++{
++	unsigned long *table = icplb_table;
++	unsigned long ctrl;
++	int i;
++
++	for (i = 0; i < MAX_CPLBS; i++) {
++		unsigned long addr = *table++;
++		unsigned long data = *table++;
++		if (addr == (unsigned long)-1)
++			break;
++		bfin_write32(ICPLB_ADDR0 + i * 4, addr);
++		bfin_write32(ICPLB_DATA0 + i * 4, data);
++	}
++	ctrl = bfin_read_IMEM_CONTROL();
++	ctrl |= IMC | ENICPLB;
++	bfin_write_IMEM_CONTROL(ctrl);
++	SSYNC();
++}
++#endif
++
++#if defined(CONFIG_BFIN_DCACHE)
++void bfin_dcache_init(void)
++{
++	unsigned long *table = dcplb_table;
++	unsigned long ctrl;
++	int i;
 +
++	for (i = 0; i < MAX_CPLBS; i++) {
++		unsigned long addr = *table++;
++		unsigned long data = *table++;
++		if (addr == (unsigned long)-1)
++			break;
++		bfin_write32(DCPLB_ADDR0 + i * 4, addr);
++		bfin_write32(DCPLB_DATA0 + i * 4, data);
++	}
++	ctrl = bfin_read_DMEM_CONTROL();
++	ctrl |= DMEM_CNTR;
++	bfin_write_DMEM_CONTROL(ctrl);
++	SSYNC();
++}
++#endif
+diff --git a/arch/blackfin/kernel/cplb-nompu/cplbhdlr.S b/arch/blackfin/kernel/cplb-nompu/cplbhdlr.S
+new file mode 100644
+index 0000000..2788532
+--- /dev/null
++++ b/arch/blackfin/kernel/cplb-nompu/cplbhdlr.S
+@@ -0,0 +1,130 @@
 +/*
-+ * Five shutdown action types are supported:
++ * File:         arch/blackfin/mach-common/cplbhdlr.S
++ * Based on:
++ * Author:       LG Soft India
++ *
++ * Created:      ?
++ * Description:  CPLB exception handler
++ *
++ * Modified:
++ *               Copyright 2004-2006 Analog Devices Inc.
++ *
++ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, see the file COPYING, or write
++ * to the Free Software Foundation, Inc.,
++ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 + */
-+#define SHUTDOWN_ACTION_IPL_STR		"ipl"
-+#define SHUTDOWN_ACTION_REIPL_STR	"reipl"
-+#define SHUTDOWN_ACTION_DUMP_STR	"dump"
-+#define SHUTDOWN_ACTION_VMCMD_STR	"vmcmd"
-+#define SHUTDOWN_ACTION_STOP_STR	"stop"
 +
-+struct shutdown_action {
-+	char *name;
-+	void (*fn) (struct shutdown_trigger *trigger);
-+	int (*init) (void);
++#include <linux/linkage.h>
++#include <asm/cplb.h>
++#include <asm/entry.h>
++
++#ifdef CONFIG_EXCPT_IRQ_SYSC_L1
++.section .l1.text
++#else
++.text
++#endif
++
++.type _cplb_mgr, STT_FUNC;
++.type _panic_cplb_error, STT_FUNC;
++
++.align 2
++
++ENTRY(__cplb_hdr)
++	R2 = SEQSTAT;
++
++	/* Mask the contents of SEQSTAT and leave only EXCAUSE in R2 */
++	R2 <<= 26;
++	R2 >>= 26;
++
++	R1 = 0x23; /* Data access CPLB protection violation */
++	CC = R2 == R1;
++	IF !CC JUMP .Lnot_data_write;
++	R0 = 2;		/* is a write to data space*/
++	JUMP .Lis_icplb_miss;
++
++.Lnot_data_write:
++	R1 = 0x2C; /* CPLB miss on an instruction fetch */
++	CC = R2 == R1;
++	R0 = 0;		/* is_data_miss == False*/
++	IF CC JUMP .Lis_icplb_miss;
++
++	R1 = 0x26;
++	CC = R2 == R1;
++	IF !CC JUMP .Lunknown;
++
++	R0 = 1;		/* is_data_miss == True*/
++
++.Lis_icplb_miss:
++
++#if defined(CONFIG_BFIN_ICACHE) || defined(CONFIG_BFIN_DCACHE)
++# if defined(CONFIG_BFIN_ICACHE) && !defined(CONFIG_BFIN_DCACHE)
++	R1 = CPLB_ENABLE_ICACHE;
++# endif
++# if !defined(CONFIG_BFIN_ICACHE) && defined(CONFIG_BFIN_DCACHE)
++	R1 = CPLB_ENABLE_DCACHE;
++# endif
++# if defined(CONFIG_BFIN_ICACHE) && defined(CONFIG_BFIN_DCACHE)
++	R1 = CPLB_ENABLE_DCACHE | CPLB_ENABLE_ICACHE;
++# endif
++#else
++	R1 = 0;
++#endif
++
++	[--SP] = RETS;
++	CALL _cplb_mgr;
++	RETS = [SP++];
++	CC = R0 == 0;
++	IF !CC JUMP .Lnot_replaced;
++	RTS;
++
++/*
++ * Diagnostic exception handlers
++ */
++.Lunknown:
++	R0 = CPLB_UNKNOWN_ERR;
++	JUMP .Lcplb_error;
++
++.Lnot_replaced:
++	CC = R0 == CPLB_NO_UNLOCKED;
++	IF !CC JUMP .Lnext_check;
++	R0 = CPLB_NO_UNLOCKED;
++	JUMP .Lcplb_error;
++
++.Lnext_check:
++	CC = R0 == CPLB_NO_ADDR_MATCH;
++	IF !CC JUMP .Lnext_check2;
++	R0 = CPLB_NO_ADDR_MATCH;
++	JUMP .Lcplb_error;
++
++.Lnext_check2:
++	CC = R0 == CPLB_PROT_VIOL;
++	IF !CC JUMP .Lstrange_return_from_cplb_mgr;
++	R0 = CPLB_PROT_VIOL;
++	JUMP .Lcplb_error;
++
++.Lstrange_return_from_cplb_mgr:
++	IDLE;
++	CSYNC;
++	JUMP .Lstrange_return_from_cplb_mgr;
++
++.Lcplb_error:
++	R1 = sp;
++	SP += -12;
++	call _panic_cplb_error;
++	SP += 12;
++	JUMP _handle_bad_cplb;
++
++ENDPROC(__cplb_hdr)
+diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinfo.c b/arch/blackfin/kernel/cplb-nompu/cplbinfo.c
+new file mode 100644
+index 0000000..a4f0b42
+--- /dev/null
++++ b/arch/blackfin/kernel/cplb-nompu/cplbinfo.c
+@@ -0,0 +1,208 @@
++/*
++ * File:         arch/blackfin/mach-common/cplbinfo.c
++ * Based on:
++ * Author:       Sonic Zhang <sonic.zhang at analog.com>
++ *
++ * Created:      Jan. 2005
++ * Description:  Display CPLB status
++ *
++ * Modified:
++ *               Copyright 2004-2006 Analog Devices Inc.
++ *
++ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, see the file COPYING, or write
++ * to the Free Software Foundation, Inc.,
++ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/proc_fs.h>
++#include <linux/uaccess.h>
++
++#include <asm/current.h>
++#include <asm/system.h>
++#include <asm/cplb.h>
++#include <asm/blackfin.h>
++
++#define CPLB_I 1
++#define CPLB_D 2
++
++#define SYNC_SYS    SSYNC()
++#define SYNC_CORE   CSYNC()
++
++#define CPLB_BIT_PAGESIZE 0x30000
++
++static int page_size_table[4] = {
++	0x00000400,		/* 1K */
++	0x00001000,		/* 4K */
++	0x00100000,		/* 1M */
++	0x00400000		/* 4M */
 +};
 +
- static char *ipl_type_str(enum ipl_type type)
- {
- 	switch (type) {
-@@ -54,10 +91,6 @@ enum dump_type {
- 	DUMP_TYPE_FCP	= 4,
- };
- 
--#define DUMP_NONE_STR	 "none"
--#define DUMP_CCW_STR	 "ccw"
--#define DUMP_FCP_STR	 "fcp"
--
- static char *dump_type_str(enum dump_type type)
- {
- 	switch (type) {
-@@ -99,30 +132,6 @@ enum dump_method {
- 	DUMP_METHOD_FCP_DIAG,
- };
- 
--enum shutdown_action {
--	SHUTDOWN_REIPL,
--	SHUTDOWN_DUMP,
--	SHUTDOWN_STOP,
--};
--
--#define SHUTDOWN_REIPL_STR "reipl"
--#define SHUTDOWN_DUMP_STR  "dump"
--#define SHUTDOWN_STOP_STR  "stop"
--
--static char *shutdown_action_str(enum shutdown_action action)
--{
--	switch (action) {
--	case SHUTDOWN_REIPL:
--		return SHUTDOWN_REIPL_STR;
--	case SHUTDOWN_DUMP:
--		return SHUTDOWN_DUMP_STR;
--	case SHUTDOWN_STOP:
--		return SHUTDOWN_STOP_STR;
--	default:
--		return NULL;
--	}
--}
--
- static int diag308_set_works = 0;
- 
- static int reipl_capabilities = IPL_TYPE_UNKNOWN;
-@@ -140,8 +149,6 @@ static enum dump_method dump_method = DUMP_METHOD_NONE;
- static struct ipl_parameter_block *dump_block_fcp;
- static struct ipl_parameter_block *dump_block_ccw;
- 
--static enum shutdown_action on_panic_action = SHUTDOWN_STOP;
--
- static struct sclp_ipl_info sclp_ipl_info;
- 
- int diag308(unsigned long subcode, void *addr)
-@@ -162,22 +169,25 @@ EXPORT_SYMBOL_GPL(diag308);
- /* SYSFS */
- 
- #define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value)		\
--static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset,	\
-+static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj,	\
-+		struct kobj_attribute *attr,				\
- 		char *page)						\
- {									\
- 	return sprintf(page, _format, _value);				\
- }									\
--static struct subsys_attribute sys_##_prefix##_##_name##_attr =		\
-+static struct kobj_attribute sys_##_prefix##_##_name##_attr =		\
- 	__ATTR(_name, S_IRUGO, sys_##_prefix##_##_name##_show, NULL);
- 
- #define DEFINE_IPL_ATTR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)	\
--static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset,	\
-+static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj,	\
-+		struct kobj_attribute *attr,				\
- 		char *page)						\
- {									\
- 	return sprintf(page, _fmt_out,					\
- 			(unsigned long long) _value);			\
- }									\
--static ssize_t sys_##_prefix##_##_name##_store(struct kset *kset,	\
-+static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj,	\
-+		struct kobj_attribute *attr,				\
- 		const char *buf, size_t len)				\
- {									\
- 	unsigned long long value;					\
-@@ -186,25 +196,27 @@ static ssize_t sys_##_prefix##_##_name##_store(struct kset *kset,	\
- 	_value = value;							\
- 	return len;							\
- }									\
--static struct subsys_attribute sys_##_prefix##_##_name##_attr =		\
-+static struct kobj_attribute sys_##_prefix##_##_name##_attr =		\
- 	__ATTR(_name,(S_IRUGO | S_IWUSR),				\
- 			sys_##_prefix##_##_name##_show,			\
- 			sys_##_prefix##_##_name##_store);
- 
- #define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\
--static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset,	\
-+static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj,	\
-+		struct kobj_attribute *attr,				\
- 		char *page)						\
- {									\
- 	return sprintf(page, _fmt_out, _value);				\
- }									\
--static ssize_t sys_##_prefix##_##_name##_store(struct kset *kset,	\
-+static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj,	\
-+		struct kobj_attribute *attr,				\
- 		const char *buf, size_t len)				\
- {									\
--	if (sscanf(buf, _fmt_in, _value) != 1)				\
--		return -EINVAL;						\
-+	strncpy(_value, buf, sizeof(_value) - 1);			\
-+	strstrip(_value);						\
- 	return len;							\
- }									\
--static struct subsys_attribute sys_##_prefix##_##_name##_attr =		\
-+static struct kobj_attribute sys_##_prefix##_##_name##_attr =		\
- 	__ATTR(_name,(S_IRUGO | S_IWUSR),				\
- 			sys_##_prefix##_##_name##_show,			\
- 			sys_##_prefix##_##_name##_store);
-@@ -240,44 +252,19 @@ static __init enum ipl_type get_ipl_type(void)
- 	return IPL_TYPE_FCP;
- }
- 
--void __init setup_ipl_info(void)
--{
--	ipl_info.type = get_ipl_type();
--	switch (ipl_info.type) {
--	case IPL_TYPE_CCW:
--		ipl_info.data.ccw.dev_id.devno = ipl_devno;
--		ipl_info.data.ccw.dev_id.ssid = 0;
--		break;
--	case IPL_TYPE_FCP:
--	case IPL_TYPE_FCP_DUMP:
--		ipl_info.data.fcp.dev_id.devno =
--			IPL_PARMBLOCK_START->ipl_info.fcp.devno;
--		ipl_info.data.fcp.dev_id.ssid = 0;
--		ipl_info.data.fcp.wwpn = IPL_PARMBLOCK_START->ipl_info.fcp.wwpn;
--		ipl_info.data.fcp.lun = IPL_PARMBLOCK_START->ipl_info.fcp.lun;
--		break;
--	case IPL_TYPE_NSS:
--		strncpy(ipl_info.data.nss.name, kernel_nss_name,
--			sizeof(ipl_info.data.nss.name));
--		break;
--	case IPL_TYPE_UNKNOWN:
--	default:
--		/* We have no info to copy */
--		break;
--	}
--}
--
- struct ipl_info ipl_info;
- EXPORT_SYMBOL_GPL(ipl_info);
- 
--static ssize_t ipl_type_show(struct kset *kset, char *page)
-+static ssize_t ipl_type_show(struct kobject *kobj, struct kobj_attribute *attr,
-+			     char *page)
- {
- 	return sprintf(page, "%s\n", ipl_type_str(ipl_info.type));
- }
- 
--static struct subsys_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type);
-+static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type);
- 
--static ssize_t sys_ipl_device_show(struct kset *kset, char *page)
-+static ssize_t sys_ipl_device_show(struct kobject *kobj,
-+				   struct kobj_attribute *attr, char *page)
- {
- 	struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
- 
-@@ -292,7 +279,7 @@ static ssize_t sys_ipl_device_show(struct kset *kset, char *page)
- 	}
- }
- 
--static struct subsys_attribute sys_ipl_device_attr =
-+static struct kobj_attribute sys_ipl_device_attr =
- 	__ATTR(device, S_IRUGO, sys_ipl_device_show, NULL);
- 
- static ssize_t ipl_parameter_read(struct kobject *kobj, struct bin_attribute *attr,
-@@ -367,7 +354,8 @@ static struct attribute_group ipl_fcp_attr_group = {
- 
- /* CCW ipl device attributes */
- 
--static ssize_t ipl_ccw_loadparm_show(struct kset *kset, char *page)
-+static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj,
-+				     struct kobj_attribute *attr, char *page)
- {
- 	char loadparm[LOADPARM_LEN + 1] = {};
- 
-@@ -379,7 +367,7 @@ static ssize_t ipl_ccw_loadparm_show(struct kset *kset, char *page)
- 	return sprintf(page, "%s\n", loadparm);
- }
- 
--static struct subsys_attribute sys_ipl_ccw_loadparm_attr =
-+static struct kobj_attribute sys_ipl_ccw_loadparm_attr =
- 	__ATTR(loadparm, 0444, ipl_ccw_loadparm_show, NULL);
- 
- static struct attribute *ipl_ccw_attrs[] = {
-@@ -418,10 +406,76 @@ static struct attribute_group ipl_unknown_attr_group = {
- 	.attrs = ipl_unknown_attrs,
- };
- 
--static decl_subsys(ipl, NULL, NULL);
-+static struct kset *ipl_kset;
++static char page_size_string_table[][4] = { "1K", "4K", "1M", "4M" };
 +
-+static int __init ipl_register_fcp_files(void)
++static int cplb_find_entry(unsigned long *cplb_addr,
++			   unsigned long *cplb_data, unsigned long addr,
++			   unsigned long data)
 +{
-+	int rc;
++	int ii;
 +
-+	rc = sysfs_create_group(&ipl_kset->kobj, &ipl_fcp_attr_group);
-+	if (rc)
-+		goto out;
-+	rc = sysfs_create_bin_file(&ipl_kset->kobj, &ipl_parameter_attr);
-+	if (rc)
-+		goto out_ipl_parm;
-+	rc = sysfs_create_bin_file(&ipl_kset->kobj, &ipl_scp_data_attr);
-+	if (!rc)
-+		goto out;
++	for (ii = 0; ii < 16; ii++)
++		if (addr >= cplb_addr[ii] && addr < cplb_addr[ii] +
++		    page_size_table[(cplb_data[ii] & CPLB_BIT_PAGESIZE) >> 16]
++			&& (cplb_data[ii] == data))
++			return ii;
 +
-+	sysfs_remove_bin_file(&ipl_kset->kobj, &ipl_parameter_attr);
++	return -1;
++}
 +
-+out_ipl_parm:
-+	sysfs_remove_group(&ipl_kset->kobj, &ipl_fcp_attr_group);
-+out:
-+	return rc;
++static char *cplb_print_entry(char *buf, int type)
++{
++	unsigned long *p_addr = dpdt_table;
++	unsigned long *p_data = dpdt_table + 1;
++	unsigned long *p_icount = dpdt_swapcount_table;
++	unsigned long *p_ocount = dpdt_swapcount_table + 1;
++	unsigned long *cplb_addr = (unsigned long *)DCPLB_ADDR0;
++	unsigned long *cplb_data = (unsigned long *)DCPLB_DATA0;
++	int entry = 0, used_cplb = 0;
++
++	if (type == CPLB_I) {
++		buf += sprintf(buf, "Instruction CPLB entry:\n");
++		p_addr = ipdt_table;
++		p_data = ipdt_table + 1;
++		p_icount = ipdt_swapcount_table;
++		p_ocount = ipdt_swapcount_table + 1;
++		cplb_addr = (unsigned long *)ICPLB_ADDR0;
++		cplb_data = (unsigned long *)ICPLB_DATA0;
++	} else
++		buf += sprintf(buf, "Data CPLB entry:\n");
++
++	buf += sprintf(buf, "Address\t\tData\tSize\tValid\tLocked\tSwapin\tiCount\toCount\n");
++
++	while (*p_addr != 0xffffffff) {
++		entry = cplb_find_entry(cplb_addr, cplb_data, *p_addr, *p_data);
++		if (entry >= 0)
++			used_cplb |= 1 << entry;
++
++		buf +=
++		    sprintf(buf,
++			    "0x%08lx\t0x%05lx\t%s\t%c\t%c\t%2d\t%ld\t%ld\n",
++			    *p_addr, *p_data,
++			    page_size_string_table[(*p_data & 0x30000) >> 16],
++			    (*p_data & CPLB_VALID) ? 'Y' : 'N',
++			    (*p_data & CPLB_LOCK) ? 'Y' : 'N', entry, *p_icount,
++			    *p_ocount);
++
++		p_addr += 2;
++		p_data += 2;
++		p_icount += 2;
++		p_ocount += 2;
++	}
++
++	if (used_cplb != 0xffff) {
++		buf += sprintf(buf, "Unused/mismatched CPLBs:\n");
++
++		for (entry = 0; entry < 16; entry++)
++			if (0 == ((1 << entry) & used_cplb)) {
++				int flags = cplb_data[entry];
++				buf +=
++				    sprintf(buf,
++					    "%2d: 0x%08lx\t0x%05x\t%s\t%c\t%c\n",
++					    entry, cplb_addr[entry], flags,
++					    page_size_string_table[(flags &
++								    0x30000) >>
++								   16],
++					    (flags & CPLB_VALID) ? 'Y' : 'N',
++					    (flags & CPLB_LOCK) ? 'Y' : 'N');
++			}
++	}
++
++	buf += sprintf(buf, "\n");
++
++	return buf;
 +}
 +
-+static void ipl_run(struct shutdown_trigger *trigger)
++static int cplbinfo_proc_output(char *buf)
 +{
-+	diag308(DIAG308_IPL, NULL);
-+	if (MACHINE_IS_VM)
-+		__cpcmd("IPL", NULL, 0, NULL);
-+	else if (ipl_info.type == IPL_TYPE_CCW)
-+		reipl_ccw_dev(&ipl_info.data.ccw.dev_id);
++	char *p;
++
++	p = buf;
++
++	p += sprintf(p, "------------------ CPLB Information ------------------\n\n");
++
++	if (bfin_read_IMEM_CONTROL() & ENICPLB)
++		p = cplb_print_entry(p, CPLB_I);
++	else
++		p += sprintf(p, "Instruction CPLB is disabled.\n\n");
++
++	if (bfin_read_DMEM_CONTROL() & ENDCPLB)
++		p = cplb_print_entry(p, CPLB_D);
++	else
++		p += sprintf(p, "Data CPLB is disabled.\n");
++
++	return p - buf;
 +}
 +
-+static int ipl_init(void)
++static int cplbinfo_read_proc(char *page, char **start, off_t off,
++			      int count, int *eof, void *data)
 +{
-+	int rc;
++	int len;
 +
-+	ipl_kset = kset_create_and_add("ipl", NULL, firmware_kobj);
-+	if (!ipl_kset) {
-+		rc = -ENOMEM;
-+		goto out;
-+	}
-+	switch (ipl_info.type) {
-+	case IPL_TYPE_CCW:
-+		rc = sysfs_create_group(&ipl_kset->kobj, &ipl_ccw_attr_group);
-+		break;
-+	case IPL_TYPE_FCP:
-+	case IPL_TYPE_FCP_DUMP:
-+		rc = ipl_register_fcp_files();
-+		break;
-+	case IPL_TYPE_NSS:
-+		rc = sysfs_create_group(&ipl_kset->kobj, &ipl_nss_attr_group);
-+		break;
-+	default:
-+		rc = sysfs_create_group(&ipl_kset->kobj,
-+					&ipl_unknown_attr_group);
-+		break;
-+	}
-+out:
-+	if (rc)
-+		panic("ipl_init failed: rc = %i\n", rc);
++	len = cplbinfo_proc_output(page);
++	if (len <= off + count)
++		*eof = 1;
++	*start = page + off;
++	len -= off;
++	if (len > count)
++		len = count;
++	if (len < 0)
++		len = 0;
++	return len;
++}
 +
-+	return 0;
++static int cplbinfo_write_proc(struct file *file, const char __user *buffer,
++			       unsigned long count, void *data)
++{
++	printk(KERN_INFO "Reset the CPLB swap in/out counts.\n");
++	memset(ipdt_swapcount_table, 0, MAX_SWITCH_I_CPLBS * sizeof(unsigned long));
++	memset(dpdt_swapcount_table, 0, MAX_SWITCH_D_CPLBS * sizeof(unsigned long));
++
++	return count;
 +}
 +
-+static struct shutdown_action ipl_action = {SHUTDOWN_ACTION_IPL_STR, ipl_run,
-+					    ipl_init};
- 
- /*
-- * reipl section
-+ * reipl shutdown action: Reboot Linux on shutdown.
-  */
- 
- /* FCP reipl device attributes */
-@@ -465,7 +519,8 @@ static void reipl_get_ascii_loadparm(char *loadparm)
- 	strstrip(loadparm);
- }
- 
--static ssize_t reipl_ccw_loadparm_show(struct kset *kset, char *page)
-+static ssize_t reipl_ccw_loadparm_show(struct kobject *kobj,
-+				       struct kobj_attribute *attr, char *page)
- {
- 	char buf[LOADPARM_LEN + 1];
- 
-@@ -473,7 +528,8 @@ static ssize_t reipl_ccw_loadparm_show(struct kset *kset, char *page)
- 	return sprintf(page, "%s\n", buf);
- }
- 
--static ssize_t reipl_ccw_loadparm_store(struct kset *kset,
-+static ssize_t reipl_ccw_loadparm_store(struct kobject *kobj,
-+					struct kobj_attribute *attr,
- 					const char *buf, size_t len)
- {
- 	int i, lp_len;
-@@ -500,7 +556,7 @@ static ssize_t reipl_ccw_loadparm_store(struct kset *kset,
- 	return len;
- }
- 
--static struct subsys_attribute sys_reipl_ccw_loadparm_attr =
-+static struct kobj_attribute sys_reipl_ccw_loadparm_attr =
- 	__ATTR(loadparm, 0644, reipl_ccw_loadparm_show,
- 	       reipl_ccw_loadparm_store);
- 
-@@ -539,7 +595,9 @@ static int reipl_set_type(enum ipl_type type)
- 
- 	switch(type) {
- 	case IPL_TYPE_CCW:
--		if (MACHINE_IS_VM)
-+		if (diag308_set_works)
-+			reipl_method = REIPL_METHOD_CCW_DIAG;
-+		else if (MACHINE_IS_VM)
- 			reipl_method = REIPL_METHOD_CCW_VM;
- 		else
- 			reipl_method = REIPL_METHOD_CCW_CIO;
-@@ -568,13 +626,15 @@ static int reipl_set_type(enum ipl_type type)
- 	return 0;
- }
- 
--static ssize_t reipl_type_show(struct kset *kset, char *page)
-+static ssize_t reipl_type_show(struct kobject *kobj,
-+			       struct kobj_attribute *attr, char *page)
- {
- 	return sprintf(page, "%s\n", ipl_type_str(reipl_type));
- }
- 
--static ssize_t reipl_type_store(struct kset *kset, const char *buf,
--				size_t len)
-+static ssize_t reipl_type_store(struct kobject *kobj,
-+				struct kobj_attribute *attr,
-+				const char *buf, size_t len)
- {
- 	int rc = -EINVAL;
- 
-@@ -587,140 +647,12 @@ static ssize_t reipl_type_store(struct kset *kset, const char *buf,
- 	return (rc != 0) ? rc : len;
- }
- 
--static struct subsys_attribute reipl_type_attr =
--		__ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store);
--
--static decl_subsys(reipl, NULL, NULL);
--
--/*
-- * dump section
-- */
--
--/* FCP dump device attributes */
--
--DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%016llx\n",
--		   dump_block_fcp->ipl_info.fcp.wwpn);
--DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%016llx\n",
--		   dump_block_fcp->ipl_info.fcp.lun);
--DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n",
--		   dump_block_fcp->ipl_info.fcp.bootprog);
--DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n",
--		   dump_block_fcp->ipl_info.fcp.br_lba);
--DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
--		   dump_block_fcp->ipl_info.fcp.devno);
--
--static struct attribute *dump_fcp_attrs[] = {
--	&sys_dump_fcp_device_attr.attr,
--	&sys_dump_fcp_wwpn_attr.attr,
--	&sys_dump_fcp_lun_attr.attr,
--	&sys_dump_fcp_bootprog_attr.attr,
--	&sys_dump_fcp_br_lba_attr.attr,
--	NULL,
--};
--
--static struct attribute_group dump_fcp_attr_group = {
--	.name  = IPL_FCP_STR,
--	.attrs = dump_fcp_attrs,
--};
--
--/* CCW dump device attributes */
--
--DEFINE_IPL_ATTR_RW(dump_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
--		   dump_block_ccw->ipl_info.ccw.devno);
--
--static struct attribute *dump_ccw_attrs[] = {
--	&sys_dump_ccw_device_attr.attr,
--	NULL,
--};
--
--static struct attribute_group dump_ccw_attr_group = {
--	.name  = IPL_CCW_STR,
--	.attrs = dump_ccw_attrs,
--};
--
--/* dump type */
--
--static int dump_set_type(enum dump_type type)
--{
--	if (!(dump_capabilities & type))
--		return -EINVAL;
--	switch(type) {
--	case DUMP_TYPE_CCW:
--		if (MACHINE_IS_VM)
--			dump_method = DUMP_METHOD_CCW_VM;
--		else if (diag308_set_works)
--			dump_method = DUMP_METHOD_CCW_DIAG;
--		else
--			dump_method = DUMP_METHOD_CCW_CIO;
--		break;
--	case DUMP_TYPE_FCP:
--		dump_method = DUMP_METHOD_FCP_DIAG;
--		break;
--	default:
--		dump_method = DUMP_METHOD_NONE;
--	}
--	dump_type = type;
--	return 0;
--}
--
--static ssize_t dump_type_show(struct kset *kset, char *page)
--{
--	return sprintf(page, "%s\n", dump_type_str(dump_type));
--}
--
--static ssize_t dump_type_store(struct kset *kset, const char *buf,
--			       size_t len)
--{
--	int rc = -EINVAL;
--
--	if (strncmp(buf, DUMP_NONE_STR, strlen(DUMP_NONE_STR)) == 0)
--		rc = dump_set_type(DUMP_TYPE_NONE);
--	else if (strncmp(buf, DUMP_CCW_STR, strlen(DUMP_CCW_STR)) == 0)
--		rc = dump_set_type(DUMP_TYPE_CCW);
--	else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0)
--		rc = dump_set_type(DUMP_TYPE_FCP);
--	return (rc != 0) ? rc : len;
--}
--
--static struct subsys_attribute dump_type_attr =
--		__ATTR(dump_type, 0644, dump_type_show, dump_type_store);
--
--static decl_subsys(dump, NULL, NULL);
--
--/*
-- * Shutdown actions section
-- */
--
--static decl_subsys(shutdown_actions, NULL, NULL);
--
--/* on panic */
--
--static ssize_t on_panic_show(struct kset *kset, char *page)
--{
--	return sprintf(page, "%s\n", shutdown_action_str(on_panic_action));
--}
--
--static ssize_t on_panic_store(struct kset *kset, const char *buf,
--			      size_t len)
--{
--	if (strncmp(buf, SHUTDOWN_REIPL_STR, strlen(SHUTDOWN_REIPL_STR)) == 0)
--		on_panic_action = SHUTDOWN_REIPL;
--	else if (strncmp(buf, SHUTDOWN_DUMP_STR,
--			 strlen(SHUTDOWN_DUMP_STR)) == 0)
--		on_panic_action = SHUTDOWN_DUMP;
--	else if (strncmp(buf, SHUTDOWN_STOP_STR,
--			 strlen(SHUTDOWN_STOP_STR)) == 0)
--		on_panic_action = SHUTDOWN_STOP;
--	else
--		return -EINVAL;
--
--	return len;
--}
-+static struct kobj_attribute reipl_type_attr =
-+	__ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store);
- 
--static struct subsys_attribute on_panic_attr =
--		__ATTR(on_panic, 0644, on_panic_show, on_panic_store);
-+static struct kset *reipl_kset;
- 
--void do_reipl(void)
-+void reipl_run(struct shutdown_trigger *trigger)
- {
- 	struct ccw_dev_id devid;
- 	static char buf[100];
-@@ -729,8 +661,6 @@ void do_reipl(void)
- 	switch (reipl_method) {
- 	case REIPL_METHOD_CCW_CIO:
- 		devid.devno = reipl_block_ccw->ipl_info.ccw.devno;
--		if (ipl_info.type == IPL_TYPE_CCW && devid.devno == ipl_devno)
--			diag308(DIAG308_IPL, NULL);
- 		devid.ssid  = 0;
- 		reipl_ccw_dev(&devid);
- 		break;
-@@ -771,98 +701,6 @@ void do_reipl(void)
- 	default:
- 		break;
- 	}
--	signal_processor(smp_processor_id(), sigp_stop_and_store_status);
--}
--
--static void do_dump(void)
--{
--	struct ccw_dev_id devid;
--	static char buf[100];
--
--	switch (dump_method) {
--	case DUMP_METHOD_CCW_CIO:
--		smp_send_stop();
--		devid.devno = dump_block_ccw->ipl_info.ccw.devno;
--		devid.ssid  = 0;
--		reipl_ccw_dev(&devid);
--		break;
--	case DUMP_METHOD_CCW_VM:
--		smp_send_stop();
--		sprintf(buf, "STORE STATUS");
--		__cpcmd(buf, NULL, 0, NULL);
--		sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno);
--		__cpcmd(buf, NULL, 0, NULL);
--		break;
--	case DUMP_METHOD_CCW_DIAG:
--		diag308(DIAG308_SET, dump_block_ccw);
--		diag308(DIAG308_DUMP, NULL);
--		break;
--	case DUMP_METHOD_FCP_DIAG:
--		diag308(DIAG308_SET, dump_block_fcp);
--		diag308(DIAG308_DUMP, NULL);
--		break;
--	case DUMP_METHOD_NONE:
--	default:
--		return;
--	}
--	printk(KERN_EMERG "Dump failed!\n");
--}
--
--/* init functions */
--
--static int __init ipl_register_fcp_files(void)
--{
--	int rc;
--
--	rc = sysfs_create_group(&ipl_subsys.kobj,
--				&ipl_fcp_attr_group);
--	if (rc)
--		goto out;
--	rc = sysfs_create_bin_file(&ipl_subsys.kobj,
--				   &ipl_parameter_attr);
--	if (rc)
--		goto out_ipl_parm;
--	rc = sysfs_create_bin_file(&ipl_subsys.kobj,
--				   &ipl_scp_data_attr);
--	if (!rc)
--		goto out;
--
--	sysfs_remove_bin_file(&ipl_subsys.kobj, &ipl_parameter_attr);
--
--out_ipl_parm:
--	sysfs_remove_group(&ipl_subsys.kobj, &ipl_fcp_attr_group);
--out:
--	return rc;
--}
--
--static int __init ipl_init(void)
--{
--	int rc;
--
--	rc = firmware_register(&ipl_subsys);
--	if (rc)
--		return rc;
--	switch (ipl_info.type) {
--	case IPL_TYPE_CCW:
--		rc = sysfs_create_group(&ipl_subsys.kobj,
--					&ipl_ccw_attr_group);
--		break;
--	case IPL_TYPE_FCP:
--	case IPL_TYPE_FCP_DUMP:
--		rc = ipl_register_fcp_files();
--		break;
--	case IPL_TYPE_NSS:
--		rc = sysfs_create_group(&ipl_subsys.kobj,
--					&ipl_nss_attr_group);
--		break;
--	default:
--		rc = sysfs_create_group(&ipl_subsys.kobj,
--					&ipl_unknown_attr_group);
--		break;
--	}
--	if (rc)
--		firmware_unregister(&ipl_subsys);
--	return rc;
- }
- 
- static void __init reipl_probe(void)
-@@ -883,7 +721,7 @@ static int __init reipl_nss_init(void)
- 
- 	if (!MACHINE_IS_VM)
- 		return 0;
--	rc = sysfs_create_group(&reipl_subsys.kobj, &reipl_nss_attr_group);
-+	rc = sysfs_create_group(&reipl_kset->kobj, &reipl_nss_attr_group);
- 	if (rc)
- 		return rc;
- 	strncpy(reipl_nss_name, kernel_nss_name, NSS_NAME_SIZE + 1);
-@@ -898,7 +736,7 @@ static int __init reipl_ccw_init(void)
- 	reipl_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
- 	if (!reipl_block_ccw)
- 		return -ENOMEM;
--	rc = sysfs_create_group(&reipl_subsys.kobj, &reipl_ccw_attr_group);
-+	rc = sysfs_create_group(&reipl_kset->kobj, &reipl_ccw_attr_group);
- 	if (rc) {
- 		free_page((unsigned long)reipl_block_ccw);
- 		return rc;
-@@ -907,6 +745,7 @@ static int __init reipl_ccw_init(void)
- 	reipl_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION;
- 	reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN;
- 	reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
-+	reipl_block_ccw->hdr.flags = DIAG308_FLAGS_LP_VALID;
- 	/* check if read scp info worked and set loadparm */
- 	if (sclp_ipl_info.is_valid)
- 		memcpy(reipl_block_ccw->ipl_info.ccw.load_param,
-@@ -915,8 +754,7 @@ static int __init reipl_ccw_init(void)
- 		/* read scp info failed: set empty loadparm (EBCDIC blanks) */
- 		memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40,
- 		       LOADPARM_LEN);
--	/* FIXME: check for diag308_set_works when enabling diag ccw reipl */
--	if (!MACHINE_IS_VM)
-+	if (!MACHINE_IS_VM && !diag308_set_works)
- 		sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO;
- 	if (ipl_info.type == IPL_TYPE_CCW)
- 		reipl_block_ccw->ipl_info.ccw.devno = ipl_devno;
-@@ -936,7 +774,7 @@ static int __init reipl_fcp_init(void)
- 	reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
- 	if (!reipl_block_fcp)
- 		return -ENOMEM;
--	rc = sysfs_create_group(&reipl_subsys.kobj, &reipl_fcp_attr_group);
-+	rc = sysfs_create_group(&reipl_kset->kobj, &reipl_fcp_attr_group);
- 	if (rc) {
- 		free_page((unsigned long)reipl_block_fcp);
- 		return rc;
-@@ -954,16 +792,16 @@ static int __init reipl_fcp_init(void)
- 	return 0;
- }
- 
--static int __init reipl_init(void)
-+static int reipl_init(void)
- {
- 	int rc;
- 
--	rc = firmware_register(&reipl_subsys);
--	if (rc)
--		return rc;
--	rc = subsys_create_file(&reipl_subsys, &reipl_type_attr);
-+	reipl_kset = kset_create_and_add("reipl", NULL, firmware_kobj);
-+	if (!reipl_kset)
++static int __init cplbinfo_init(void)
++{
++	struct proc_dir_entry *entry;
++
++	entry = create_proc_entry("cplbinfo", 0, NULL);
++	if (!entry)
 +		return -ENOMEM;
-+	rc = sysfs_create_file(&reipl_kset->kobj, &reipl_type_attr.attr);
- 	if (rc) {
--		firmware_unregister(&reipl_subsys);
-+		kset_unregister(reipl_kset);
- 		return rc;
- 	}
- 	rc = reipl_ccw_init();
-@@ -981,6 +819,140 @@ static int __init reipl_init(void)
- 	return 0;
- }
- 
-+static struct shutdown_action reipl_action = {SHUTDOWN_ACTION_REIPL_STR,
-+					      reipl_run, reipl_init};
 +
++	entry->read_proc = cplbinfo_read_proc;
++	entry->write_proc = cplbinfo_write_proc;
++	entry->data = NULL;
++
++	return 0;
++}
++
++static void __exit cplbinfo_exit(void)
++{
++	remove_proc_entry("cplbinfo", NULL);
++}
++
++module_init(cplbinfo_init);
++module_exit(cplbinfo_exit);
+diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
+new file mode 100644
+index 0000000..6320bc4
+--- /dev/null
++++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
+@@ -0,0 +1,437 @@
 +/*
-+ * dump shutdown action: Dump Linux on shutdown.
++ * Blackfin CPLB initialization
++ *
++ *               Copyright 2004-2007 Analog Devices Inc.
++ *
++ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, see the file COPYING, or write
++ * to the Free Software Foundation, Inc.,
++ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 + */
++#include <linux/module.h>
 +
-+/* FCP dump device attributes */
-+
-+DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%016llx\n",
-+		   dump_block_fcp->ipl_info.fcp.wwpn);
-+DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%016llx\n",
-+		   dump_block_fcp->ipl_info.fcp.lun);
-+DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n",
-+		   dump_block_fcp->ipl_info.fcp.bootprog);
-+DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n",
-+		   dump_block_fcp->ipl_info.fcp.br_lba);
-+DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
-+		   dump_block_fcp->ipl_info.fcp.devno);
++#include <asm/blackfin.h>
++#include <asm/cplb.h>
++#include <asm/cplbinit.h>
 +
-+static struct attribute *dump_fcp_attrs[] = {
-+	&sys_dump_fcp_device_attr.attr,
-+	&sys_dump_fcp_wwpn_attr.attr,
-+	&sys_dump_fcp_lun_attr.attr,
-+	&sys_dump_fcp_bootprog_attr.attr,
-+	&sys_dump_fcp_br_lba_attr.attr,
-+	NULL,
-+};
++u_long icplb_table[MAX_CPLBS + 1];
++u_long dcplb_table[MAX_CPLBS + 1];
 +
-+static struct attribute_group dump_fcp_attr_group = {
-+	.name  = IPL_FCP_STR,
-+	.attrs = dump_fcp_attrs,
-+};
++#ifdef CONFIG_CPLB_SWITCH_TAB_L1
++# define PDT_ATTR __attribute__((l1_data))
++#else
++# define PDT_ATTR
++#endif
 +
-+/* CCW dump device attributes */
++u_long ipdt_table[MAX_SWITCH_I_CPLBS + 1] PDT_ATTR;
++u_long dpdt_table[MAX_SWITCH_D_CPLBS + 1] PDT_ATTR;
 +
-+DEFINE_IPL_ATTR_RW(dump_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
-+		   dump_block_ccw->ipl_info.ccw.devno);
++#ifdef CONFIG_CPLB_INFO
++u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS] PDT_ATTR;
++u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS] PDT_ATTR;
++#endif
 +
-+static struct attribute *dump_ccw_attrs[] = {
-+	&sys_dump_ccw_device_attr.attr,
-+	NULL,
++struct s_cplb {
++	struct cplb_tab init_i;
++	struct cplb_tab init_d;
++	struct cplb_tab switch_i;
++	struct cplb_tab switch_d;
 +};
 +
-+static struct attribute_group dump_ccw_attr_group = {
-+	.name  = IPL_CCW_STR,
-+	.attrs = dump_ccw_attrs,
++#if defined(CONFIG_BFIN_DCACHE) || defined(CONFIG_BFIN_ICACHE)
++static struct cplb_desc cplb_data[] = {
++	{
++		.start = 0,
++		.end = SIZE_1K,
++		.psize = SIZE_1K,
++		.attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,
++		.i_conf = SDRAM_OOPS,
++		.d_conf = SDRAM_OOPS,
++#if defined(CONFIG_DEBUG_HUNT_FOR_ZERO)
++		.valid = 1,
++#else
++		.valid = 0,
++#endif
++		.name = "Zero Pointer Guard Page",
++	},
++	{
++		.start = L1_CODE_START,
++		.end = L1_CODE_START + L1_CODE_LENGTH,
++		.psize = SIZE_4M,
++		.attr = INITIAL_T | SWITCH_T | I_CPLB,
++		.i_conf = L1_IMEMORY,
++		.d_conf = 0,
++		.valid = 1,
++		.name = "L1 I-Memory",
++	},
++	{
++		.start = L1_DATA_A_START,
++		.end = L1_DATA_B_START + L1_DATA_B_LENGTH,
++		.psize = SIZE_4M,
++		.attr = INITIAL_T | SWITCH_T | D_CPLB,
++		.i_conf = 0,
++		.d_conf = L1_DMEMORY,
++#if ((L1_DATA_A_LENGTH > 0) || (L1_DATA_B_LENGTH > 0))
++		.valid = 1,
++#else
++		.valid = 0,
++#endif
++		.name = "L1 D-Memory",
++	},
++	{
++		.start = 0,
++		.end = 0,  /* dynamic */
++		.psize = 0,
++		.attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,
++		.i_conf = SDRAM_IGENERIC,
++		.d_conf = SDRAM_DGENERIC,
++		.valid = 1,
++		.name = "Kernel Memory",
++	},
++	{
++		.start = 0, /* dynamic */
++		.end = 0, /* dynamic */
++		.psize = 0,
++		.attr = INITIAL_T | SWITCH_T | D_CPLB,
++		.i_conf = SDRAM_IGENERIC,
++		.d_conf = SDRAM_DNON_CHBL,
++		.valid = 1,
++		.name = "uClinux MTD Memory",
++	},
++	{
++		.start = 0, /* dynamic */
++		.end = 0,   /* dynamic */
++		.psize = SIZE_1M,
++		.attr = INITIAL_T | SWITCH_T | D_CPLB,
++		.d_conf = SDRAM_DNON_CHBL,
++		.valid = 1,
++		.name = "Uncached DMA Zone",
++	},
++	{
++		.start = 0, /* dynamic */
++		.end = 0, /* dynamic */
++		.psize = 0,
++		.attr = SWITCH_T | D_CPLB,
++		.i_conf = 0, /* dynamic */
++		.d_conf = 0, /* dynamic */
++		.valid = 1,
++		.name = "Reserved Memory",
++	},
++	{
++		.start = ASYNC_BANK0_BASE,
++		.end = ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE,
++		.psize = 0,
++		.attr = SWITCH_T | D_CPLB,
++		.d_conf = SDRAM_EBIU,
++		.valid = 1,
++		.name = "Asynchronous Memory Banks",
++	},
++	{
++#ifdef L2_START
++		.start = L2_START,
++		.end = L2_START + L2_LENGTH,
++		.psize = SIZE_1M,
++		.attr = SWITCH_T | I_CPLB | D_CPLB,
++		.i_conf = L2_MEMORY,
++		.d_conf = L2_MEMORY,
++		.valid = 1,
++#else
++		.valid = 0,
++#endif
++		.name = "L2 Memory",
++	},
++	{
++		.start = BOOT_ROM_START,
++		.end = BOOT_ROM_START + BOOT_ROM_LENGTH,
++		.psize = SIZE_1M,
++		.attr = SWITCH_T | I_CPLB | D_CPLB,
++		.i_conf = SDRAM_IGENERIC,
++		.d_conf = SDRAM_DGENERIC,
++		.valid = 1,
++		.name = "On-Chip BootROM",
++	},
 +};
 +
-+/* dump type */
++static u16 __init lock_kernel_check(u32 start, u32 end)
++{
++	if ((end   <= (u32) _end && end   >= (u32)_stext) ||
++	    (start <= (u32) _end && start >= (u32)_stext))
++		return IN_KERNEL;
++	return 0;
++}
 +
-+static int dump_set_type(enum dump_type type)
++static unsigned short __init
++fill_cplbtab(struct cplb_tab *table,
++	     unsigned long start, unsigned long end,
++	     unsigned long block_size, unsigned long cplb_data)
 +{
-+	if (!(dump_capabilities & type))
-+		return -EINVAL;
-+	switch (type) {
-+	case DUMP_TYPE_CCW:
-+		if (diag308_set_works)
-+			dump_method = DUMP_METHOD_CCW_DIAG;
-+		else if (MACHINE_IS_VM)
-+			dump_method = DUMP_METHOD_CCW_VM;
-+		else
-+			dump_method = DUMP_METHOD_CCW_CIO;
++	int i;
++
++	switch (block_size) {
++	case SIZE_4M:
++		i = 3;
 +		break;
-+	case DUMP_TYPE_FCP:
-+		dump_method = DUMP_METHOD_FCP_DIAG;
++	case SIZE_1M:
++		i = 2;
++		break;
++	case SIZE_4K:
++		i = 1;
 +		break;
++	case SIZE_1K:
 +	default:
-+		dump_method = DUMP_METHOD_NONE;
++		i = 0;
++		break;
++	}
++
++	cplb_data = (cplb_data & ~(3 << 16)) | (i << 16);
++
++	while ((start < end) && (table->pos < table->size)) {
++
++		table->tab[table->pos++] = start;
++
++		if (lock_kernel_check(start, start + block_size) == IN_KERNEL)
++			table->tab[table->pos++] =
++			    cplb_data | CPLB_LOCK | CPLB_DIRTY;
++		else
++			table->tab[table->pos++] = cplb_data;
++
++		start += block_size;
 +	}
-+	dump_type = type;
 +	return 0;
 +}
 +
-+static ssize_t dump_type_show(struct kobject *kobj,
-+			      struct kobj_attribute *attr, char *page)
++static unsigned short __init
++close_cplbtab(struct cplb_tab *table)
 +{
-+	return sprintf(page, "%s\n", dump_type_str(dump_type));
++
++	while (table->pos < table->size) {
++
++		table->tab[table->pos++] = 0;
++		table->tab[table->pos++] = 0; /* !CPLB_VALID */
++	}
++	return 0;
 +}
 +
-+static ssize_t dump_type_store(struct kobject *kobj,
-+			       struct kobj_attribute *attr,
-+			       const char *buf, size_t len)
++/* helper function */
++static void __fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
 +{
-+	int rc = -EINVAL;
++	if (cplb_data[i].psize) {
++		fill_cplbtab(t,
++				cplb_data[i].start,
++				cplb_data[i].end,
++				cplb_data[i].psize,
++				cplb_data[i].i_conf);
++	} else {
++#if defined(CONFIG_BFIN_ICACHE)
++		if (ANOMALY_05000263 && i == SDRAM_KERN) {
++			fill_cplbtab(t,
++					cplb_data[i].start,
++					cplb_data[i].end,
++					SIZE_4M,
++					cplb_data[i].i_conf);
++		} else
++#endif
++		{
++			fill_cplbtab(t,
++					cplb_data[i].start,
++					a_start,
++					SIZE_1M,
++					cplb_data[i].i_conf);
++			fill_cplbtab(t,
++					a_start,
++					a_end,
++					SIZE_4M,
++					cplb_data[i].i_conf);
++			fill_cplbtab(t, a_end,
++					cplb_data[i].end,
++					SIZE_1M,
++					cplb_data[i].i_conf);
++		}
++	}
++}
 +
-+	if (strncmp(buf, DUMP_NONE_STR, strlen(DUMP_NONE_STR)) == 0)
-+		rc = dump_set_type(DUMP_TYPE_NONE);
-+	else if (strncmp(buf, DUMP_CCW_STR, strlen(DUMP_CCW_STR)) == 0)
-+		rc = dump_set_type(DUMP_TYPE_CCW);
-+	else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0)
-+		rc = dump_set_type(DUMP_TYPE_FCP);
-+	return (rc != 0) ? rc : len;
++static void __fill_data_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
++{
++	if (cplb_data[i].psize) {
++		fill_cplbtab(t,
++				cplb_data[i].start,
++				cplb_data[i].end,
++				cplb_data[i].psize,
++				cplb_data[i].d_conf);
++	} else {
++		fill_cplbtab(t,
++				cplb_data[i].start,
++				a_start, SIZE_1M,
++				cplb_data[i].d_conf);
++		fill_cplbtab(t, a_start,
++				a_end, SIZE_4M,
++				cplb_data[i].d_conf);
++		fill_cplbtab(t, a_end,
++				cplb_data[i].end,
++				SIZE_1M,
++				cplb_data[i].d_conf);
++	}
 +}
 +
-+static struct kobj_attribute dump_type_attr =
-+	__ATTR(dump_type, 0644, dump_type_show, dump_type_store);
++void __init generate_cpl_tables(void)
++{
 +
-+static struct kset *dump_kset;
++	u16 i, j, process;
++	u32 a_start, a_end, as, ae, as_1m;
 +
-+static void dump_run(struct shutdown_trigger *trigger)
-+{
-+	struct ccw_dev_id devid;
-+	static char buf[100];
++	struct cplb_tab *t_i = NULL;
++	struct cplb_tab *t_d = NULL;
++	struct s_cplb cplb;
 +
-+	switch (dump_method) {
-+	case DUMP_METHOD_CCW_CIO:
-+		smp_send_stop();
-+		devid.devno = dump_block_ccw->ipl_info.ccw.devno;
-+		devid.ssid  = 0;
-+		reipl_ccw_dev(&devid);
-+		break;
-+	case DUMP_METHOD_CCW_VM:
-+		smp_send_stop();
-+		sprintf(buf, "STORE STATUS");
-+		__cpcmd(buf, NULL, 0, NULL);
-+		sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno);
-+		__cpcmd(buf, NULL, 0, NULL);
-+		break;
-+	case DUMP_METHOD_CCW_DIAG:
-+		diag308(DIAG308_SET, dump_block_ccw);
-+		diag308(DIAG308_DUMP, NULL);
-+		break;
-+	case DUMP_METHOD_FCP_DIAG:
-+		diag308(DIAG308_SET, dump_block_fcp);
-+		diag308(DIAG308_DUMP, NULL);
-+		break;
-+	case DUMP_METHOD_NONE:
-+	default:
-+		return;
-+	}
-+	printk(KERN_EMERG "Dump failed!\n");
-+}
++	cplb.init_i.size = MAX_CPLBS;
++	cplb.init_d.size = MAX_CPLBS;
++	cplb.switch_i.size = MAX_SWITCH_I_CPLBS;
++	cplb.switch_d.size = MAX_SWITCH_D_CPLBS;
 +
- static int __init dump_ccw_init(void)
- {
- 	int rc;
-@@ -988,7 +960,7 @@ static int __init dump_ccw_init(void)
- 	dump_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
- 	if (!dump_block_ccw)
- 		return -ENOMEM;
--	rc = sysfs_create_group(&dump_subsys.kobj, &dump_ccw_attr_group);
-+	rc = sysfs_create_group(&dump_kset->kobj, &dump_ccw_attr_group);
- 	if (rc) {
- 		free_page((unsigned long)dump_block_ccw);
- 		return rc;
-@@ -1012,7 +984,7 @@ static int __init dump_fcp_init(void)
- 	dump_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
- 	if (!dump_block_fcp)
- 		return -ENOMEM;
--	rc = sysfs_create_group(&dump_subsys.kobj, &dump_fcp_attr_group);
-+	rc = sysfs_create_group(&dump_kset->kobj, &dump_fcp_attr_group);
- 	if (rc) {
- 		free_page((unsigned long)dump_block_fcp);
- 		return rc;
-@@ -1026,33 +998,16 @@ static int __init dump_fcp_init(void)
- 	return 0;
- }
- 
--#define SHUTDOWN_ON_PANIC_PRIO 0
--
--static int shutdown_on_panic_notify(struct notifier_block *self,
--				    unsigned long event, void *data)
--{
--	if (on_panic_action == SHUTDOWN_DUMP)
--		do_dump();
--	else if (on_panic_action == SHUTDOWN_REIPL)
--		do_reipl();
--	return NOTIFY_OK;
--}
--
--static struct notifier_block shutdown_on_panic_nb = {
--	.notifier_call = shutdown_on_panic_notify,
--	.priority = SHUTDOWN_ON_PANIC_PRIO
--};
--
--static int __init dump_init(void)
-+static int dump_init(void)
- {
- 	int rc;
- 
--	rc = firmware_register(&dump_subsys);
--	if (rc)
--		return rc;
--	rc = subsys_create_file(&dump_subsys, &dump_type_attr);
-+	dump_kset = kset_create_and_add("dump", NULL, firmware_kobj);
-+	if (!dump_kset)
-+		return -ENOMEM;
-+	rc = sysfs_create_file(&dump_kset->kobj, &dump_type_attr.attr);
- 	if (rc) {
--		firmware_unregister(&dump_subsys);
-+		kset_unregister(dump_kset);
- 		return rc;
- 	}
- 	rc = dump_ccw_init();
-@@ -1065,46 +1020,381 @@ static int __init dump_init(void)
- 	return 0;
- }
- 
--static int __init shutdown_actions_init(void)
-+static struct shutdown_action dump_action = {SHUTDOWN_ACTION_DUMP_STR,
-+					     dump_run, dump_init};
++	cplb.init_i.pos = 0;
++	cplb.init_d.pos = 0;
++	cplb.switch_i.pos = 0;
++	cplb.switch_d.pos = 0;
 +
-+/*
-+ * vmcmd shutdown action: Trigger vm command on shutdown.
-+ */
++	cplb.init_i.tab = icplb_table;
++	cplb.init_d.tab = dcplb_table;
++	cplb.switch_i.tab = ipdt_table;
++	cplb.switch_d.tab = dpdt_table;
 +
-+static char vmcmd_on_reboot[128];
-+static char vmcmd_on_panic[128];
-+static char vmcmd_on_halt[128];
-+static char vmcmd_on_poff[128];
++	cplb_data[SDRAM_KERN].end = memory_end;
 +
-+DEFINE_IPL_ATTR_STR_RW(vmcmd, on_reboot, "%s\n", "%s\n", vmcmd_on_reboot);
-+DEFINE_IPL_ATTR_STR_RW(vmcmd, on_panic, "%s\n", "%s\n", vmcmd_on_panic);
-+DEFINE_IPL_ATTR_STR_RW(vmcmd, on_halt, "%s\n", "%s\n", vmcmd_on_halt);
-+DEFINE_IPL_ATTR_STR_RW(vmcmd, on_poff, "%s\n", "%s\n", vmcmd_on_poff);
++#ifdef CONFIG_MTD_UCLINUX
++	cplb_data[SDRAM_RAM_MTD].start = memory_mtd_start;
++	cplb_data[SDRAM_RAM_MTD].end = memory_mtd_start + mtd_size;
++	cplb_data[SDRAM_RAM_MTD].valid = mtd_size > 0;
++# if defined(CONFIG_ROMFS_FS)
++	cplb_data[SDRAM_RAM_MTD].attr |= I_CPLB;
 +
-+static struct attribute *vmcmd_attrs[] = {
-+	&sys_vmcmd_on_reboot_attr.attr,
-+	&sys_vmcmd_on_panic_attr.attr,
-+	&sys_vmcmd_on_halt_attr.attr,
-+	&sys_vmcmd_on_poff_attr.attr,
-+	NULL,
-+};
++	/*
++	 * The ROMFS_FS size is often not multiple of 1MB.
++	 * This can cause multiple CPLB sets covering the same memory area.
++	 * This will then cause multiple CPLB hit exceptions.
++	 * Workaround: We ensure a contiguous memory area by extending the kernel
++	 * memory section over the mtd section.
++	 * For ROMFS_FS memory must be covered with ICPLBs anyways.
++	 * So there is no difference between kernel and mtd memory setup.
++	 */
 +
-+static struct attribute_group vmcmd_attr_group = {
-+	.attrs = vmcmd_attrs,
-+};
++	cplb_data[SDRAM_KERN].end = memory_mtd_start + mtd_size;;
++	cplb_data[SDRAM_RAM_MTD].valid = 0;
 +
-+static struct kset *vmcmd_kset;
++# endif
++#else
++	cplb_data[SDRAM_RAM_MTD].valid = 0;
++#endif
 +
-+static void vmcmd_run(struct shutdown_trigger *trigger)
-+{
-+	char *cmd, *next_cmd;
++	cplb_data[SDRAM_DMAZ].start = _ramend - DMA_UNCACHED_REGION;
++	cplb_data[SDRAM_DMAZ].end = _ramend;
 +
-+	if (strcmp(trigger->name, ON_REIPL_STR) == 0)
-+		cmd = vmcmd_on_reboot;
-+	else if (strcmp(trigger->name, ON_PANIC_STR) == 0)
-+		cmd = vmcmd_on_panic;
-+	else if (strcmp(trigger->name, ON_HALT_STR) == 0)
-+		cmd = vmcmd_on_halt;
-+	else if (strcmp(trigger->name, ON_POFF_STR) == 0)
-+		cmd = vmcmd_on_poff;
++	cplb_data[RES_MEM].start = _ramend;
++	cplb_data[RES_MEM].end = physical_mem_end;
++
++	if (reserved_mem_dcache_on)
++		cplb_data[RES_MEM].d_conf = SDRAM_DGENERIC;
 +	else
-+		return;
++		cplb_data[RES_MEM].d_conf = SDRAM_DNON_CHBL;
 +
-+	if (strlen(cmd) == 0)
-+		return;
-+	do {
-+		next_cmd = strchr(cmd, '\n');
-+		if (next_cmd) {
-+			next_cmd[0] = 0;
-+			next_cmd += 1;
-+		}
-+		__cpcmd(cmd, NULL, 0, NULL);
-+		cmd = next_cmd;
-+	} while (cmd != NULL);
-+}
++	if (reserved_mem_icache_on)
++		cplb_data[RES_MEM].i_conf = SDRAM_IGENERIC;
++	else
++		cplb_data[RES_MEM].i_conf = SDRAM_INON_CHBL;
 +
-+static int vmcmd_init(void)
- {
--	int rc;
-+	if (!MACHINE_IS_VM)
-+		return -ENOTSUPP;
-+	vmcmd_kset = kset_create_and_add("vmcmd", NULL, firmware_kobj);
-+	if (!vmcmd_kset)
-+		return -ENOMEM;
-+	return sysfs_create_group(&vmcmd_kset->kobj, &vmcmd_attr_group);
-+}
- 
--	rc = firmware_register(&shutdown_actions_subsys);
--	if (rc)
--		return rc;
--	rc = subsys_create_file(&shutdown_actions_subsys, &on_panic_attr);
--	if (rc) {
--		firmware_unregister(&shutdown_actions_subsys);
--		return rc;
-+static struct shutdown_action vmcmd_action = {SHUTDOWN_ACTION_VMCMD_STR,
-+					      vmcmd_run, vmcmd_init};
++	for (i = ZERO_P; i < ARRAY_SIZE(cplb_data); ++i) {
++		if (!cplb_data[i].valid)
++			continue;
 +
-+/*
-+ * stop shutdown action: Stop Linux on shutdown.
-+ */
++		as_1m = cplb_data[i].start % SIZE_1M;
 +
-+static void stop_run(struct shutdown_trigger *trigger)
-+{
-+	if (strcmp(trigger->name, ON_PANIC_STR) == 0)
-+		disabled_wait((unsigned long) __builtin_return_address(0));
-+	else {
-+		signal_processor(smp_processor_id(), sigp_stop);
-+		for (;;);
- 	}
--	atomic_notifier_chain_register(&panic_notifier_list,
--				       &shutdown_on_panic_nb);
--	return 0;
- }
- 
--static int __init s390_ipl_init(void)
-+static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR,
-+					     stop_run, NULL};
++		/* We need to make sure all sections are properly 1M aligned
++		 * However between Kernel Memory and the Kernel mtd section, depending on the
++		 * rootfs size, there can be overlapping memory areas.
++		 */
 +
-+/* action list */
++		if (as_1m && i != L1I_MEM && i != L1D_MEM) {
++#ifdef CONFIG_MTD_UCLINUX
++			if (i == SDRAM_RAM_MTD) {
++				if ((cplb_data[SDRAM_KERN].end + 1) > cplb_data[SDRAM_RAM_MTD].start)
++					cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M)) + SIZE_1M;
++				else
++					cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M));
++			} else
++#endif
++				printk(KERN_WARNING "Unaligned Start of %s at 0x%X\n",
++				       cplb_data[i].name, cplb_data[i].start);
++		}
 +
-+static struct shutdown_action *shutdown_actions_list[] = {
-+	&ipl_action, &reipl_action, &dump_action, &vmcmd_action, &stop_action};
-+#define SHUTDOWN_ACTIONS_COUNT (sizeof(shutdown_actions_list) / sizeof(void *))
++		as = cplb_data[i].start % SIZE_4M;
++		ae = cplb_data[i].end % SIZE_4M;
 +
-+/*
-+ * Trigger section
-+ */
++		if (as)
++			a_start = cplb_data[i].start + (SIZE_4M - (as));
++		else
++			a_start = cplb_data[i].start;
 +
-+static struct kset *shutdown_actions_kset;
++		a_end = cplb_data[i].end - ae;
 +
-+static int set_trigger(const char *buf, struct shutdown_trigger *trigger,
-+		       size_t len)
- {
--	int rc;
-+	int i;
-+	for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
-+		if (!shutdown_actions_list[i])
-+			continue;
-+		if (strncmp(buf, shutdown_actions_list[i]->name,
-+			    strlen(shutdown_actions_list[i]->name)) == 0) {
-+			trigger->action = shutdown_actions_list[i];
-+			return len;
++		for (j = INITIAL_T; j <= SWITCH_T; j++) {
++
++			switch (j) {
++			case INITIAL_T:
++				if (cplb_data[i].attr & INITIAL_T) {
++					t_i = &cplb.init_i;
++					t_d = &cplb.init_d;
++					process = 1;
++				} else
++					process = 0;
++				break;
++			case SWITCH_T:
++				if (cplb_data[i].attr & SWITCH_T) {
++					t_i = &cplb.switch_i;
++					t_d = &cplb.switch_d;
++					process = 1;
++				} else
++					process = 0;
++				break;
++			default:
++					process = 0;
++				break;
++			}
++
++			if (!process)
++				continue;
++			if (cplb_data[i].attr & I_CPLB)
++				__fill_code_cplbtab(t_i, i, a_start, a_end);
++
++			if (cplb_data[i].attr & D_CPLB)
++				__fill_data_cplbtab(t_d, i, a_start, a_end);
 +		}
 +	}
-+	return -EINVAL;
-+}
- 
--	sclp_get_ipl_info(&sclp_ipl_info);
-+/* on reipl */
 +
-+static struct shutdown_trigger on_reboot_trigger = {ON_REIPL_STR,
-+						    &reipl_action};
++/* close tables */
 +
-+static ssize_t on_reboot_show(struct kobject *kobj,
-+			      struct kobj_attribute *attr, char *page)
-+{
-+	return sprintf(page, "%s\n", on_reboot_trigger.action->name);
-+}
++	close_cplbtab(&cplb.init_i);
++	close_cplbtab(&cplb.init_d);
++
++	cplb.init_i.tab[cplb.init_i.pos] = -1;
++	cplb.init_d.tab[cplb.init_d.pos] = -1;
++	cplb.switch_i.tab[cplb.switch_i.pos] = -1;
++	cplb.switch_d.tab[cplb.switch_d.pos] = -1;
 +
-+static ssize_t on_reboot_store(struct kobject *kobj,
-+			       struct kobj_attribute *attr,
-+			       const char *buf, size_t len)
-+{
-+	return set_trigger(buf, &on_reboot_trigger, len);
 +}
 +
-+static struct kobj_attribute on_reboot_attr =
-+	__ATTR(on_reboot, 0644, on_reboot_show, on_reboot_store);
++#endif
 +
-+static void do_machine_restart(char *__unused)
-+{
-+	smp_send_stop();
-+	on_reboot_trigger.action->fn(&on_reboot_trigger);
-+	reipl_run(NULL);
-+}
-+void (*_machine_restart)(char *command) = do_machine_restart;
+diff --git a/arch/blackfin/kernel/cplb-nompu/cplbmgr.S b/arch/blackfin/kernel/cplb-nompu/cplbmgr.S
+new file mode 100644
+index 0000000..f5cf3ac
+--- /dev/null
++++ b/arch/blackfin/kernel/cplb-nompu/cplbmgr.S
+@@ -0,0 +1,646 @@
++/*
++ * File:         arch/blackfin/mach-common/cplbmgtr.S
++ * Based on:
++ * Author:       LG Soft India
++ *
++ * Created:      ?
++ * Description:  CPLB replacement routine for CPLB mismatch
++ *
++ * Modified:
++ *               Copyright 2004-2006 Analog Devices Inc.
++ *
++ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, see the file COPYING, or write
++ * to the Free Software Foundation, Inc.,
++ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++ */
 +
-+/* on panic */
++/* Usage: int _cplb_mgr(is_data_miss,int enable_cache)
++ * is_data_miss==2 => Mark as Dirty, write to the clean data page
++ * is_data_miss==1 => Replace a data CPLB.
++ * is_data_miss==0 => Replace an instruction CPLB.
++ *
++ * Returns:
++ * CPLB_RELOADED	=> Successfully updated CPLB table.
++ * CPLB_NO_UNLOCKED	=> All CPLBs are locked, so cannot be evicted.
++ *			   This indicates that the CPLBs in the configuration
++ *			   tablei are badly configured, as this should never
++ *			   occur.
++ * CPLB_NO_ADDR_MATCH	=> The address being accessed, that triggered the
++ *			   exception, is not covered by any of the CPLBs in
++ *			   the configuration table. The application is
++ *			   presumably misbehaving.
++ * CPLB_PROT_VIOL	=> The address being accessed, that triggered the
++ *			   exception, was not a first-write to a clean Write
++ *			   Back Data page, and so presumably is a genuine
++ *			   violation of the page's protection attributes.
++ *			   The application is misbehaving.
++ */
++
++#include <linux/linkage.h>
++#include <asm/blackfin.h>
++#include <asm/cplb.h>
 +
-+static struct shutdown_trigger on_panic_trigger = {ON_PANIC_STR, &stop_action};
++#ifdef CONFIG_EXCPT_IRQ_SYSC_L1
++.section .l1.text
++#else
++.text
++#endif
 +
-+static ssize_t on_panic_show(struct kobject *kobj,
-+			     struct kobj_attribute *attr, char *page)
-+{
-+	return sprintf(page, "%s\n", on_panic_trigger.action->name);
-+}
++.align 2;
++ENTRY(_cplb_mgr)
 +
-+static ssize_t on_panic_store(struct kobject *kobj,
-+			      struct kobj_attribute *attr,
-+			      const char *buf, size_t len)
-+{
-+	return set_trigger(buf, &on_panic_trigger, len);
-+}
++	[--SP]=( R7:4,P5:3 );
 +
-+static struct kobj_attribute on_panic_attr =
-+	__ATTR(on_panic, 0644, on_panic_show, on_panic_store);
++	CC = R0 == 2;
++	IF CC JUMP .Ldcplb_write;
 +
-+static void do_panic(void)
-+{
-+	on_panic_trigger.action->fn(&on_panic_trigger);
-+	stop_run(&on_panic_trigger);
-+}
++	CC = R0 == 0;
++	IF !CC JUMP .Ldcplb_miss_compare;
 +
-+/* on halt */
++	/* ICPLB Miss Exception. We need to choose one of the
++	* currently-installed CPLBs, and replace it with one
++	* from the configuration table.
++	*/
 +
-+static struct shutdown_trigger on_halt_trigger = {ON_HALT_STR, &stop_action};
++	/* A multi-word instruction can cross a page boundary. This means the
++	 * first part of the instruction can be in a valid page, but the
++	 * second part is not, and hence generates the instruction miss.
++	 * However, the fault address is for the start of the instruction,
++	 * not the part that's in the bad page. Therefore, we have to check
++	 * whether the fault address applies to a page that is already present
++	 * in the table.
++	 */
++
++	P4.L = LO(ICPLB_FAULT_ADDR);
++	P4.H = HI(ICPLB_FAULT_ADDR);
++
++	P1 = 16;
++	P5.L = _page_size_table;
++	P5.H = _page_size_table;
++
++	P0.L = LO(ICPLB_DATA0);
++	P0.H = HI(ICPLB_DATA0);
++	R4 = [P4];		/* Get faulting address*/
++	R6 = 64;		/* Advance past the fault address, which*/
++	R6 = R6 + R4;		/* we'll use if we find a match*/
++	R3 = ((16 << 8) | 2);	/* Extract mask, two bits at posn 16 */
++
++	R5 = 0;
++.Lisearch:
++
++	R1 = [P0-0x100];	/* Address for this CPLB */
++
++	R0 = [P0++];		/* Info for this CPLB*/
++	CC = BITTST(R0,0);	/* Is the CPLB valid?*/
++	IF !CC JUMP .Lnomatch;	/* Skip it, if not.*/
++	CC = R4 < R1(IU);	/* If fault address less than page start*/
++	IF CC JUMP .Lnomatch;	/* then skip this one.*/
++	R2 = EXTRACT(R0,R3.L) (Z);	/* Get page size*/
++	P1 = R2;
++	P1 = P5 + (P1<<2);	/* index into page-size table*/
++	R2 = [P1];		/* Get the page size*/
++	R1 = R1 + R2;		/* and add to page start, to get page end*/
++	CC = R4 < R1(IU);	/* and see whether fault addr is in page.*/
++	IF !CC R4 = R6;		/* If so, advance the address and finish loop.*/
++	IF !CC JUMP .Lisearch_done;
++.Lnomatch:
++	/* Go around again*/
++	R5 += 1;
++	CC = BITTST(R5, 4);	/* i.e CC = R5 >= 16*/
++	IF !CC JUMP .Lisearch;
++
++.Lisearch_done:
++	I0 = R4;		/* Fault address we'll search for*/
++
++	/* set up pointers */
++	P0.L = LO(ICPLB_DATA0);
++	P0.H = HI(ICPLB_DATA0);
++
++	/* The replacement procedure for ICPLBs */
++
++	P4.L = LO(IMEM_CONTROL);
++	P4.H = HI(IMEM_CONTROL);
++
++	/* Turn off CPLBs while we work, necessary according to HRM before
++	 * modifying CPLB descriptors
++	 */
++	R5 = [P4];		/* Control Register*/
++	BITCLR(R5,ENICPLB_P);
++	CLI R1;
++	SSYNC;		/* SSYNC required before writing to IMEM_CONTROL. */
++	.align 8;
++	[P4] = R5;
++	SSYNC;
++	STI R1;
++
++	R1 = -1;		/* end point comparison */
++	R3 = 16;		/* counter */
++
++	/* Search through CPLBs for first non-locked entry */
++	/* Overwrite it by moving everyone else up by 1 */
++.Licheck_lock:
++	R0 = [P0++];
++	R3 = R3 + R1;
++	CC = R3 == R1;
++	IF CC JUMP .Lall_locked;
++	CC = BITTST(R0, 0);		/* an invalid entry is good */
++	IF !CC JUMP .Lifound_victim;
++	CC = BITTST(R0,1);		/* but a locked entry isn't */
++	IF CC JUMP .Licheck_lock;
++
++.Lifound_victim:
++#ifdef CONFIG_CPLB_INFO
++	R7 = [P0 - 0x104];
++	P2.L = _ipdt_table;
++	P2.H = _ipdt_table;
++	P3.L = _ipdt_swapcount_table;
++	P3.H = _ipdt_swapcount_table;
++	P3 += -4;
++.Licount:
++	R2 = [P2];	/* address from config table */
++	P2 += 8;
++	P3 += 8;
++	CC = R2==-1;
++	IF CC JUMP .Licount_done;
++	CC = R7==R2;
++	IF !CC JUMP .Licount;
++	R7 = [P3];
++	R7 += 1;
++	[P3] = R7;
++	CSYNC;
++.Licount_done:
++#endif
++	LC0=R3;
++	LSETUP(.Lis_move,.Lie_move) LC0;
++.Lis_move:
++	R0 = [P0];
++	[P0 - 4] = R0;
++	R0 = [P0 - 0x100];
++	[P0-0x104] = R0;
++.Lie_move:
++	P0+=4;
++
++	/* Clear ICPLB_DATA15, in case we don't find a replacement
++	 * otherwise, we would have a duplicate entry, and will crash
++	 */
++	R0 = 0;
++	[P0 - 4] = R0;
++
++	/* We've made space in the ICPLB table, so that ICPLB15
++	 * is now free to be overwritten. Next, we have to determine
++	 * which CPLB we need to install, from the configuration
++	 * table. This is a matter of getting the start-of-page
++	 * addresses and page-lengths from the config table, and
++	 * determining whether the fault address falls within that
++	 * range.
++ 	 */
++
++	P2.L = _ipdt_table;
++	P2.H = _ipdt_table;
++#ifdef	CONFIG_CPLB_INFO
++	P3.L = _ipdt_swapcount_table;
++	P3.H = _ipdt_swapcount_table;
++	P3 += -8;
++#endif
++	P0.L = _page_size_table;
++	P0.H = _page_size_table;
++
++	/* Retrieve our fault address (which may have been advanced
++	 * because the faulting instruction crossed a page boundary).
++	 */
++
++	R0 = I0;
++
++	/* An extraction pattern, to get the page-size bits from
++	 * the CPLB data entry. Bits 16-17, so two bits at posn 16.
++	 */
++
++	R1 = ((16<<8)|2);
++.Linext:	R4 = [P2++];	/* address from config table */
++	R2 = [P2++];	/* data from config table */
++#ifdef	CONFIG_CPLB_INFO
++	P3 += 8;
++#endif
++
++	CC = R4 == -1;	/* End of config table*/
++	IF CC JUMP .Lno_page_in_table;
++
++	/* See if failed address > start address */
++	CC = R4 <= R0(IU);
++	IF !CC JUMP .Linext;
++
++	/* extract page size (17:16)*/
++	R3 = EXTRACT(R2, R1.L) (Z);
++
++	/* add page size to addr to get range */
++
++	P5 = R3;
++	P5 = P0 + (P5 << 2);	/* scaled, for int access*/
++	R3 = [P5];
++	R3 = R3 + R4;
++
++	/* See if failed address < (start address + page size) */
++	CC = R0 < R3(IU);
++	IF !CC JUMP .Linext;
++
++	/* We've found a CPLB in the config table that covers
++	 * the faulting address, so install this CPLB into the
++	 * last entry of the table.
++	 */
++
++	P1.L = LO(ICPLB_DATA15);		/* ICPLB_DATA15 */
++	P1.H = HI(ICPLB_DATA15);
++	[P1] = R2;
++	[P1-0x100] = R4;
++#ifdef	CONFIG_CPLB_INFO
++	R3 = [P3];
++	R3 += 1;
++	[P3] = R3;
++#endif
++
++	/* P4 points to IMEM_CONTROL, and R5 contains its old
++	 * value, after we disabled ICPLBS. Re-enable them.
++	 */
++
++	BITSET(R5,ENICPLB_P);
++	CLI R2;
++	SSYNC;		/* SSYNC required before writing to IMEM_CONTROL. */
++	.align 8;
++	[P4] = R5;
++	SSYNC;
++	STI R2;
++
++	( R7:4,P5:3 ) = [SP++];
++	R0 = CPLB_RELOADED;
++	RTS;
++
++/* FAILED CASES*/
++.Lno_page_in_table:
++	R0 = CPLB_NO_ADDR_MATCH;
++	JUMP .Lfail_ret;
++
++.Lall_locked:
++	R0 = CPLB_NO_UNLOCKED;
++	JUMP .Lfail_ret;
++
++.Lprot_violation:
++	R0 = CPLB_PROT_VIOL;
++
++.Lfail_ret:
++	/* Make sure we turn protection/cache back on, even in the failing case */
++	BITSET(R5,ENICPLB_P);
++	CLI R2;
++	SSYNC;          /* SSYNC required before writing to IMEM_CONTROL. */
++	.align 8;
++	[P4] = R5;
++	SSYNC;
++	STI R2;
++
++	( R7:4,P5:3 ) = [SP++];
++	RTS;
++
++.Ldcplb_write:
++
++	/* if a DCPLB is marked as write-back (CPLB_WT==0), and
++	 * it is clean (CPLB_DIRTY==0), then a write to the
++	 * CPLB's page triggers a protection violation. We have to
++	 * mark the CPLB as dirty, to indicate that there are
++	 * pending writes associated with the CPLB.
++	 */
++
++	P4.L = LO(DCPLB_STATUS);
++	P4.H = HI(DCPLB_STATUS);
++	P3.L = LO(DCPLB_DATA0);
++	P3.H = HI(DCPLB_DATA0);
++	R5 = [P4];
++
++	/* A protection violation can be caused by more than just writes
++	 * to a clean WB page, so we have to ensure that:
++	 * - It's a write
++	 * - to a clean WB page
++	 * - and is allowed in the mode the access occurred.
++	 */
++
++	CC = BITTST(R5, 16);	/* ensure it was a write*/
++	IF !CC JUMP .Lprot_violation;
++
++	/* to check the rest, we have to retrieve the DCPLB.*/
++
++	/* The low half of DCPLB_STATUS is a bit mask*/
++
++	R2 = R5.L (Z);	/* indicating which CPLB triggered the event.*/
++	R3 = 30;	/* so we can use this to determine the offset*/
++	R2.L = SIGNBITS R2;
++	R2 = R2.L (Z);	/* into the DCPLB table.*/
++	R3 = R3 - R2;
++	P4 = R3;
++	P3 = P3 + (P4<<2);
++	R3 = [P3];	/* Retrieve the CPLB*/
++
++	/* Now we can check whether it's a clean WB page*/
++
++	CC = BITTST(R3, 14);	/* 0==WB, 1==WT*/
++	IF CC JUMP .Lprot_violation;
++	CC = BITTST(R3, 7);	/* 0 == clean, 1 == dirty*/
++	IF CC JUMP .Lprot_violation;
++
++	/* Check whether the write is allowed in the mode that was active.*/
++
++	R2 = 1<<3;		/* checking write in user mode*/
++	CC = BITTST(R5, 17);	/* 0==was user, 1==was super*/
++	R5 = CC;
++	R2 <<= R5;		/* if was super, check write in super mode*/
++	R2 = R3 & R2;
++	CC = R2 == 0;
++	IF CC JUMP .Lprot_violation;
++
++	/* It's a genuine write-to-clean-page.*/
++
++	BITSET(R3, 7);		/* mark as dirty*/
++	[P3] = R3;		/* and write back.*/
++	NOP;
++	CSYNC;
++	( R7:4,P5:3 ) = [SP++];
++	R0 = CPLB_RELOADED;
++	RTS;
++
++.Ldcplb_miss_compare:
++
++	/* Data CPLB Miss event. We need to choose a CPLB to
++	 * evict, and then locate a new CPLB to install from the
++	 * config table, that covers the faulting address.
++	 */
++
++	P1.L = LO(DCPLB_DATA15);
++	P1.H = HI(DCPLB_DATA15);
++
++	P4.L = LO(DCPLB_FAULT_ADDR);
++	P4.H = HI(DCPLB_FAULT_ADDR);
++	R4 = [P4];
++	I0 = R4;
++
++	/* The replacement procedure for DCPLBs*/
++
++	R6 = R1;	/* Save for later*/
++
++	/* Turn off CPLBs while we work.*/
++	P4.L = LO(DMEM_CONTROL);
++	P4.H = HI(DMEM_CONTROL);
++	R5 = [P4];
++	BITCLR(R5,ENDCPLB_P);
++	CLI R0;
++	SSYNC;		/* SSYNC required before writing to DMEM_CONTROL. */
++	.align 8;
++	[P4] = R5;
++	SSYNC;
++	STI R0;
++
++	/* Start looking for a CPLB to evict. Our order of preference
++	 * is: invalid CPLBs, clean CPLBs, dirty CPLBs. Locked CPLBs
++	 * are no good.
++	 */
++
++	I1.L = LO(DCPLB_DATA0);
++	I1.H = HI(DCPLB_DATA0);
++	P1 = 2;
++	P2 = 16;
++	I2.L = _dcplb_preference;
++	I2.H = _dcplb_preference;
++	LSETUP(.Lsdsearch1, .Ledsearch1) LC0 = P1;
++.Lsdsearch1:
++	R0 = [I2++];		/* Get the bits we're interested in*/
++	P0 = I1;		/* Go back to start of table*/
++	LSETUP (.Lsdsearch2, .Ledsearch2) LC1 = P2;
++.Lsdsearch2:
++	R1 = [P0++];		/* Fetch each installed CPLB in turn*/
++	R2 = R1 & R0;		/* and test for interesting bits.*/
++	CC = R2 == 0;		/* If none are set, it'll do.*/
++	IF !CC JUMP .Lskip_stack_check;
++
++	R2 = [P0 - 0x104]; 	/* R2 - PageStart */
++	P3.L = _page_size_table; /* retrieve end address */
++	P3.H = _page_size_table; /* retrieve end address */
++	R3 = 0x1002;		/* 16th - position, 2 bits -length */
++#if ANOMALY_05000209
++	nop;			/* Anomaly 05000209 */
++#endif
++	R7 = EXTRACT(R1,R3.l);
++	R7 = R7 << 2;		/* Page size index offset */
++	P5 = R7;
++	P3 = P3 + P5;
++	R7 = [P3];		/* page size in bytes */
++
++	R7 = R2 + R7;		/* R7 - PageEnd */
++	R4 = SP; 		/* Test SP is in range */
++
++	CC = R7 < R4;		/* if PageEnd < SP */
++	IF CC JUMP .Ldfound_victim;
++	R3 = 0x284;		/* stack length from start of trap till
++				 * the point.
++				 * 20 stack locations for future modifications
++				 */
++	R4 = R4 + R3;
++	CC = R4 < R2;		/* if SP + stacklen < PageStart */
++	IF CC JUMP .Ldfound_victim;
++.Lskip_stack_check:
 +
-+static ssize_t on_halt_show(struct kobject *kobj,
-+			    struct kobj_attribute *attr, char *page)
-+{
-+	return sprintf(page, "%s\n", on_halt_trigger.action->name);
-+}
++.Ledsearch2: NOP;
++.Ledsearch1: NOP;
 +
-+static ssize_t on_halt_store(struct kobject *kobj,
-+			     struct kobj_attribute *attr,
-+			     const char *buf, size_t len)
-+{
-+	return set_trigger(buf, &on_halt_trigger, len);
-+}
++	/* If we got here, we didn't find a DCPLB we considered
++	 * replacable, which means all of them were locked.
++	 */
 +
-+static struct kobj_attribute on_halt_attr =
-+	__ATTR(on_halt, 0644, on_halt_show, on_halt_store);
++	JUMP .Lall_locked;
++.Ldfound_victim:
 +
++#ifdef CONFIG_CPLB_INFO
++	R7 = [P0 - 0x104];
++	P2.L = _dpdt_table;
++	P2.H = _dpdt_table;
++	P3.L = _dpdt_swapcount_table;
++	P3.H = _dpdt_swapcount_table;
++	P3 += -4;
++.Ldicount:
++	R2 = [P2];
++	P2 += 8;
++	P3 += 8;
++	CC = R2==-1;
++	IF CC JUMP .Ldicount_done;
++	CC = R7==R2;
++	IF !CC JUMP .Ldicount;
++	R7 = [P3];
++	R7 += 1;
++	[P3] = R7;
++.Ldicount_done:
++#endif
 +
-+static void do_machine_halt(void)
-+{
-+	smp_send_stop();
-+	on_halt_trigger.action->fn(&on_halt_trigger);
-+	stop_run(&on_halt_trigger);
-+}
-+void (*_machine_halt)(void) = do_machine_halt;
++	/* Clean down the hardware loops*/
++	R2 = 0;
++	LC1 = R2;
++	LC0 = R2;
 +
-+/* on power off */
++	/* There's a suitable victim in [P0-4] (because we've
++	 * advanced already).
++	 */
 +
-+static struct shutdown_trigger on_poff_trigger = {ON_POFF_STR, &stop_action};
++.LDdoverwrite:
 +
-+static ssize_t on_poff_show(struct kobject *kobj,
-+			    struct kobj_attribute *attr, char *page)
-+{
-+	return sprintf(page, "%s\n", on_poff_trigger.action->name);
-+}
++	/* [P0-4] is a suitable victim CPLB, so we want to
++	 * overwrite it by moving all the following CPLBs
++	 * one space closer to the start.
++	 */
 +
-+static ssize_t on_poff_store(struct kobject *kobj,
-+			     struct kobj_attribute *attr,
-+			     const char *buf, size_t len)
-+{
-+	return set_trigger(buf, &on_poff_trigger, len);
-+}
++	R1.L = LO(DCPLB_DATA16);		/* DCPLB_DATA15 + 4 */
++	R1.H = HI(DCPLB_DATA16);
++	R0 = P0;
 +
-+static struct kobj_attribute on_poff_attr =
-+	__ATTR(on_poff, 0644, on_poff_show, on_poff_store);
++	/* If the victim happens to be in DCPLB15,
++	 * we don't need to move anything.
++	 */
 +
++	CC = R1 == R0;
++	IF CC JUMP .Lde_moved;
++	R1 = R1 - R0;
++	R1 >>= 2;
++	P1 = R1;
++	LSETUP(.Lds_move, .Lde_move) LC0=P1;
++.Lds_move:
++	R0 = [P0++];	/* move data */
++	[P0 - 8] = R0;
++	R0 = [P0-0x104]	/* move address */
++.Lde_move:
++	 [P0-0x108] = R0;
 +
-+static void do_machine_power_off(void)
-+{
-+	smp_send_stop();
-+	on_poff_trigger.action->fn(&on_poff_trigger);
-+	stop_run(&on_poff_trigger);
-+}
-+void (*_machine_power_off)(void) = do_machine_power_off;
++.Lde_moved:
++	NOP;
 +
-+static void __init shutdown_triggers_init(void)
-+{
-+	shutdown_actions_kset = kset_create_and_add("shutdown_actions", NULL,
-+						    firmware_kobj);
-+	if (!shutdown_actions_kset)
-+		goto fail;
-+	if (sysfs_create_file(&shutdown_actions_kset->kobj,
-+			      &on_reboot_attr.attr))
-+		goto fail;
-+	if (sysfs_create_file(&shutdown_actions_kset->kobj,
-+			      &on_panic_attr.attr))
-+		goto fail;
-+	if (sysfs_create_file(&shutdown_actions_kset->kobj,
-+			      &on_halt_attr.attr))
-+		goto fail;
-+	if (sysfs_create_file(&shutdown_actions_kset->kobj,
-+			      &on_poff_attr.attr))
-+		goto fail;
++	/* Clear DCPLB_DATA15, in case we don't find a replacement
++	 * otherwise, we would have a duplicate entry, and will crash
++	 */
++	R0 = 0;
++	[P0 - 0x4] = R0;
 +
-+	return;
-+fail:
-+	panic("shutdown_triggers_init failed\n");
-+}
++	/* We've now made space in DCPLB15 for the new CPLB to be
++	 * installed. The next stage is to locate a CPLB in the
++	 * config table that covers the faulting address.
++	 */
 +
-+static void __init shutdown_actions_init(void)
-+{
-+	int i;
++	R0 = I0;		/* Our faulting address */
 +
-+	for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
-+		if (!shutdown_actions_list[i]->init)
-+			continue;
-+		if (shutdown_actions_list[i]->init())
-+			shutdown_actions_list[i] = NULL;
-+	}
-+}
++	P2.L = _dpdt_table;
++	P2.H = _dpdt_table;
++#ifdef	CONFIG_CPLB_INFO
++	P3.L = _dpdt_swapcount_table;
++	P3.H = _dpdt_swapcount_table;
++	P3 += -8;
++#endif
 +
-+static int __init s390_ipl_init(void)
-+{
- 	reipl_probe();
--	rc = ipl_init();
--	if (rc)
--		return rc;
--	rc = reipl_init();
--	if (rc)
--		return rc;
--	rc = dump_init();
--	if (rc)
--		return rc;
--	rc = shutdown_actions_init();
--	if (rc)
--		return rc;
-+	sclp_get_ipl_info(&sclp_ipl_info);
-+	shutdown_actions_init();
-+	shutdown_triggers_init();
- 	return 0;
- }
- 
- __initcall(s390_ipl_init);
- 
-+static void __init strncpy_skip_quote(char *dst, char *src, int n)
-+{
-+	int sx, dx;
++	P1.L = _page_size_table;
++	P1.H = _page_size_table;
 +
-+	dx = 0;
-+	for (sx = 0; src[sx] != 0; sx++) {
-+		if (src[sx] == '"')
-+			continue;
-+		dst[dx++] = src[sx];
-+		if (dx >= n)
-+			break;
-+	}
-+}
++	/* An extraction pattern, to retrieve bits 17:16.*/
 +
-+static int __init vmcmd_on_reboot_setup(char *str)
-+{
-+	if (!MACHINE_IS_VM)
-+		return 1;
-+	strncpy_skip_quote(vmcmd_on_reboot, str, 127);
-+	vmcmd_on_reboot[127] = 0;
-+	on_reboot_trigger.action = &vmcmd_action;
-+	return 1;
-+}
-+__setup("vmreboot=", vmcmd_on_reboot_setup);
++	R1 = (16<<8)|2;
++.Ldnext:	R4 = [P2++];	/* address */
++	R2 = [P2++];	/* data */
++#ifdef	CONFIG_CPLB_INFO
++	P3 += 8;
++#endif
 +
-+static int __init vmcmd_on_panic_setup(char *str)
-+{
-+	if (!MACHINE_IS_VM)
-+		return 1;
-+	strncpy_skip_quote(vmcmd_on_panic, str, 127);
-+	vmcmd_on_panic[127] = 0;
-+	on_panic_trigger.action = &vmcmd_action;
-+	return 1;
-+}
-+__setup("vmpanic=", vmcmd_on_panic_setup);
++	CC = R4 == -1;
++	IF CC JUMP .Lno_page_in_table;
 +
-+static int __init vmcmd_on_halt_setup(char *str)
-+{
-+	if (!MACHINE_IS_VM)
-+		return 1;
-+	strncpy_skip_quote(vmcmd_on_halt, str, 127);
-+	vmcmd_on_halt[127] = 0;
-+	on_halt_trigger.action = &vmcmd_action;
-+	return 1;
-+}
-+__setup("vmhalt=", vmcmd_on_halt_setup);
++	/* See if failed address > start address */
++	CC = R4 <= R0(IU);
++	IF !CC JUMP .Ldnext;
 +
-+static int __init vmcmd_on_poff_setup(char *str)
-+{
-+	if (!MACHINE_IS_VM)
-+		return 1;
-+	strncpy_skip_quote(vmcmd_on_poff, str, 127);
-+	vmcmd_on_poff[127] = 0;
-+	on_poff_trigger.action = &vmcmd_action;
-+	return 1;
-+}
-+__setup("vmpoff=", vmcmd_on_poff_setup);
++	/* extract page size (17:16)*/
++	R3 = EXTRACT(R2, R1.L) (Z);
 +
-+static int on_panic_notify(struct notifier_block *self,
-+			   unsigned long event, void *data)
-+{
-+	do_panic();
-+	return NOTIFY_OK;
-+}
++	/* add page size to addr to get range */
 +
-+static struct notifier_block on_panic_nb = {
-+	.notifier_call = on_panic_notify,
-+	.priority = 0,
-+};
++	P5 = R3;
++	P5 = P1 + (P5 << 2);
++	R3 = [P5];
++	R3 = R3 + R4;
 +
-+void __init setup_ipl(void)
-+{
-+	ipl_info.type = get_ipl_type();
-+	switch (ipl_info.type) {
-+	case IPL_TYPE_CCW:
-+		ipl_info.data.ccw.dev_id.devno = ipl_devno;
-+		ipl_info.data.ccw.dev_id.ssid = 0;
-+		break;
-+	case IPL_TYPE_FCP:
-+	case IPL_TYPE_FCP_DUMP:
-+		ipl_info.data.fcp.dev_id.devno =
-+			IPL_PARMBLOCK_START->ipl_info.fcp.devno;
-+		ipl_info.data.fcp.dev_id.ssid = 0;
-+		ipl_info.data.fcp.wwpn = IPL_PARMBLOCK_START->ipl_info.fcp.wwpn;
-+		ipl_info.data.fcp.lun = IPL_PARMBLOCK_START->ipl_info.fcp.lun;
-+		break;
-+	case IPL_TYPE_NSS:
-+		strncpy(ipl_info.data.nss.name, kernel_nss_name,
-+			sizeof(ipl_info.data.nss.name));
-+		break;
-+	case IPL_TYPE_UNKNOWN:
-+	default:
-+		/* We have no info to copy */
-+		break;
-+	}
-+	atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb);
-+}
++	/* See if failed address < (start address + page size) */
++	CC = R0 < R3(IU);
++	IF !CC JUMP .Ldnext;
 +
- void __init ipl_save_parameters(void)
- {
- 	struct cio_iplinfo iplinfo;
-@@ -1185,3 +1475,4 @@ void s390_reset_system(void)
- 
- 	do_reset_calls();
- }
++	/* We've found the CPLB that should be installed, so
++	 * write it into CPLB15, masking off any caching bits
++	 * if necessary.
++	 */
 +
-diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
-index 29f7884..0e7aca0 100644
---- a/arch/s390/kernel/process.c
-+++ b/arch/s390/kernel/process.c
-@@ -36,7 +36,7 @@
- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/notifier.h>
++	P1.L = LO(DCPLB_DATA15);
++	P1.H = HI(DCPLB_DATA15);
++
++	/* If the DCPLB has cache bits set, but caching hasn't
++	 * been enabled, then we want to mask off the cache-in-L1
++	 * bit before installing. Moreover, if caching is off, we
++	 * also want to ensure that the DCPLB has WT mode set, rather
++	 * than WB, since WB pages still trigger first-write exceptions
++	 * even when not caching is off, and the page isn't marked as
++	 * cachable. Finally, we could mark the page as clean, not dirty,
++	 * but we choose to leave that decision to the user; if the user
++	 * chooses to have a CPLB pre-defined as dirty, then they always
++	 * pay the cost of flushing during eviction, but don't pay the
++	 * cost of first-write exceptions to mark the page as dirty.
++	 */
++
++#ifdef CONFIG_BFIN_WT
++	BITSET(R6, 14);		/* Set WT*/
++#endif
++
++	[P1] = R2;
++	[P1-0x100] = R4;
++#ifdef	CONFIG_CPLB_INFO
++	R3 = [P3];
++	R3 += 1;
++	[P3] = R3;
++#endif
++
++	/* We've installed the CPLB, so re-enable CPLBs. P4
++	 * points to DMEM_CONTROL, and R5 is the value we
++	 * last wrote to it, when we were disabling CPLBs.
++	 */
++
++	BITSET(R5,ENDCPLB_P);
++	CLI R2;
++	.align 8;
++	[P4] = R5;
++	SSYNC;
++	STI R2;
++
++	( R7:4,P5:3 ) = [SP++];
++	R0 = CPLB_RELOADED;
++	RTS;
++ENDPROC(_cplb_mgr)
++
++.data
++.align 4;
++_page_size_table:
++.byte4	0x00000400;	/* 1K */
++.byte4	0x00001000;	/* 4K */
++.byte4	0x00100000;	/* 1M */
++.byte4	0x00400000;	/* 4M */
++
++.align 4;
++_dcplb_preference:
++.byte4	0x00000001;	/* valid bit */
++.byte4	0x00000002;	/* lock bit */
+diff --git a/arch/blackfin/kernel/cplbinit.c b/arch/blackfin/kernel/cplbinit.c
+deleted file mode 100644
+index 6320bc4..0000000
+--- a/arch/blackfin/kernel/cplbinit.c
++++ /dev/null
+@@ -1,437 +0,0 @@
+-/*
+- * Blackfin CPLB initialization
+- *
+- *               Copyright 2004-2007 Analog Devices Inc.
+- *
+- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, see the file COPYING, or write
+- * to the Free Software Foundation, Inc.,
+- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+- */
+-#include <linux/module.h>
 -
-+#include <linux/utsname.h>
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
- #include <asm/system.h>
-@@ -182,13 +182,15 @@ void cpu_idle(void)
- 
- void show_regs(struct pt_regs *regs)
- {
--	struct task_struct *tsk = current;
+-#include <asm/blackfin.h>
+-#include <asm/cplb.h>
+-#include <asm/cplbinit.h>
 -
--        printk("CPU:    %d    %s\n", task_thread_info(tsk)->cpu, print_tainted());
--        printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
--	       current->comm, task_pid_nr(current), (void *) tsk,
--	       (void *) tsk->thread.ksp);
+-u_long icplb_table[MAX_CPLBS + 1];
+-u_long dcplb_table[MAX_CPLBS + 1];
 -
-+	print_modules();
-+	printk("CPU: %d %s %s %.*s\n",
-+	       task_thread_info(current)->cpu, print_tainted(),
-+	       init_utsname()->release,
-+	       (int)strcspn(init_utsname()->version, " "),
-+	       init_utsname()->version);
-+	printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
-+	       current->comm, current->pid, current,
-+	       (void *) current->thread.ksp);
- 	show_registers(regs);
- 	/* Show stack backtrace if pt_regs is from kernel mode */
- 	if (!(regs->psw.mask & PSW_MASK_PSTATE))
-diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
-index 1d81bf9..6e036ba 100644
---- a/arch/s390/kernel/ptrace.c
-+++ b/arch/s390/kernel/ptrace.c
-@@ -86,13 +86,13 @@ FixPerRegisters(struct task_struct *task)
- 		per_info->control_regs.bits.storage_alt_space_ctl = 0;
- }
- 
--static void set_single_step(struct task_struct *task)
-+void user_enable_single_step(struct task_struct *task)
- {
- 	task->thread.per_info.single_step = 1;
- 	FixPerRegisters(task);
- }
- 
--static void clear_single_step(struct task_struct *task)
-+void user_disable_single_step(struct task_struct *task)
- {
- 	task->thread.per_info.single_step = 0;
- 	FixPerRegisters(task);
-@@ -107,7 +107,7 @@ void
- ptrace_disable(struct task_struct *child)
- {
- 	/* make sure the single step bit is not set. */
--	clear_single_step(child);
-+	user_disable_single_step(child);
- }
- 
- #ifndef CONFIG_64BIT
-@@ -651,7 +651,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
- 			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- 		child->exit_code = data;
- 		/* make sure the single step bit is not set. */
--		clear_single_step(child);
-+		user_disable_single_step(child);
- 		wake_up_process(child);
- 		return 0;
- 
-@@ -665,7 +665,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
- 			return 0;
- 		child->exit_code = SIGKILL;
- 		/* make sure the single step bit is not set. */
--		clear_single_step(child);
-+		user_disable_single_step(child);
- 		wake_up_process(child);
- 		return 0;
- 
-@@ -675,10 +675,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
- 			return -EIO;
- 		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- 		child->exit_code = data;
--		if (data)
--			set_tsk_thread_flag(child, TIF_SINGLE_STEP);
--		else
--			set_single_step(child);
-+		user_enable_single_step(child);
- 		/* give it a chance to run. */
- 		wake_up_process(child);
- 		return 0;
-diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
-index 577aa7d..766c783 100644
---- a/arch/s390/kernel/setup.c
-+++ b/arch/s390/kernel/setup.c
-@@ -126,75 +126,6 @@ void __cpuinit cpu_init(void)
- }
- 
- /*
-- * VM halt and poweroff setup routines
-- */
--char vmhalt_cmd[128] = "";
--char vmpoff_cmd[128] = "";
--static char vmpanic_cmd[128] = "";
+-#ifdef CONFIG_CPLB_SWITCH_TAB_L1
+-# define PDT_ATTR __attribute__((l1_data))
+-#else
+-# define PDT_ATTR
+-#endif
 -
--static void strncpy_skip_quote(char *dst, char *src, int n)
--{
--        int sx, dx;
+-u_long ipdt_table[MAX_SWITCH_I_CPLBS + 1] PDT_ATTR;
+-u_long dpdt_table[MAX_SWITCH_D_CPLBS + 1] PDT_ATTR;
 -
--        dx = 0;
--        for (sx = 0; src[sx] != 0; sx++) {
--                if (src[sx] == '"') continue;
--                dst[dx++] = src[sx];
--                if (dx >= n) break;
--        }
--}
+-#ifdef CONFIG_CPLB_INFO
+-u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS] PDT_ATTR;
+-u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS] PDT_ATTR;
+-#endif
 -
--static int __init vmhalt_setup(char *str)
+-struct s_cplb {
+-	struct cplb_tab init_i;
+-	struct cplb_tab init_d;
+-	struct cplb_tab switch_i;
+-	struct cplb_tab switch_d;
+-};
+-
+-#if defined(CONFIG_BFIN_DCACHE) || defined(CONFIG_BFIN_ICACHE)
+-static struct cplb_desc cplb_data[] = {
+-	{
+-		.start = 0,
+-		.end = SIZE_1K,
+-		.psize = SIZE_1K,
+-		.attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,
+-		.i_conf = SDRAM_OOPS,
+-		.d_conf = SDRAM_OOPS,
+-#if defined(CONFIG_DEBUG_HUNT_FOR_ZERO)
+-		.valid = 1,
+-#else
+-		.valid = 0,
+-#endif
+-		.name = "Zero Pointer Guard Page",
+-	},
+-	{
+-		.start = L1_CODE_START,
+-		.end = L1_CODE_START + L1_CODE_LENGTH,
+-		.psize = SIZE_4M,
+-		.attr = INITIAL_T | SWITCH_T | I_CPLB,
+-		.i_conf = L1_IMEMORY,
+-		.d_conf = 0,
+-		.valid = 1,
+-		.name = "L1 I-Memory",
+-	},
+-	{
+-		.start = L1_DATA_A_START,
+-		.end = L1_DATA_B_START + L1_DATA_B_LENGTH,
+-		.psize = SIZE_4M,
+-		.attr = INITIAL_T | SWITCH_T | D_CPLB,
+-		.i_conf = 0,
+-		.d_conf = L1_DMEMORY,
+-#if ((L1_DATA_A_LENGTH > 0) || (L1_DATA_B_LENGTH > 0))
+-		.valid = 1,
+-#else
+-		.valid = 0,
+-#endif
+-		.name = "L1 D-Memory",
+-	},
+-	{
+-		.start = 0,
+-		.end = 0,  /* dynamic */
+-		.psize = 0,
+-		.attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,
+-		.i_conf = SDRAM_IGENERIC,
+-		.d_conf = SDRAM_DGENERIC,
+-		.valid = 1,
+-		.name = "Kernel Memory",
+-	},
+-	{
+-		.start = 0, /* dynamic */
+-		.end = 0, /* dynamic */
+-		.psize = 0,
+-		.attr = INITIAL_T | SWITCH_T | D_CPLB,
+-		.i_conf = SDRAM_IGENERIC,
+-		.d_conf = SDRAM_DNON_CHBL,
+-		.valid = 1,
+-		.name = "uClinux MTD Memory",
+-	},
+-	{
+-		.start = 0, /* dynamic */
+-		.end = 0,   /* dynamic */
+-		.psize = SIZE_1M,
+-		.attr = INITIAL_T | SWITCH_T | D_CPLB,
+-		.d_conf = SDRAM_DNON_CHBL,
+-		.valid = 1,
+-		.name = "Uncached DMA Zone",
+-	},
+-	{
+-		.start = 0, /* dynamic */
+-		.end = 0, /* dynamic */
+-		.psize = 0,
+-		.attr = SWITCH_T | D_CPLB,
+-		.i_conf = 0, /* dynamic */
+-		.d_conf = 0, /* dynamic */
+-		.valid = 1,
+-		.name = "Reserved Memory",
+-	},
+-	{
+-		.start = ASYNC_BANK0_BASE,
+-		.end = ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE,
+-		.psize = 0,
+-		.attr = SWITCH_T | D_CPLB,
+-		.d_conf = SDRAM_EBIU,
+-		.valid = 1,
+-		.name = "Asynchronous Memory Banks",
+-	},
+-	{
+-#ifdef L2_START
+-		.start = L2_START,
+-		.end = L2_START + L2_LENGTH,
+-		.psize = SIZE_1M,
+-		.attr = SWITCH_T | I_CPLB | D_CPLB,
+-		.i_conf = L2_MEMORY,
+-		.d_conf = L2_MEMORY,
+-		.valid = 1,
+-#else
+-		.valid = 0,
+-#endif
+-		.name = "L2 Memory",
+-	},
+-	{
+-		.start = BOOT_ROM_START,
+-		.end = BOOT_ROM_START + BOOT_ROM_LENGTH,
+-		.psize = SIZE_1M,
+-		.attr = SWITCH_T | I_CPLB | D_CPLB,
+-		.i_conf = SDRAM_IGENERIC,
+-		.d_conf = SDRAM_DGENERIC,
+-		.valid = 1,
+-		.name = "On-Chip BootROM",
+-	},
+-};
+-
+-static u16 __init lock_kernel_check(u32 start, u32 end)
 -{
--        strncpy_skip_quote(vmhalt_cmd, str, 127);
--        vmhalt_cmd[127] = 0;
--        return 1;
+-	if ((end   <= (u32) _end && end   >= (u32)_stext) ||
+-	    (start <= (u32) _end && start >= (u32)_stext))
+-		return IN_KERNEL;
+-	return 0;
 -}
 -
--__setup("vmhalt=", vmhalt_setup);
--
--static int __init vmpoff_setup(char *str)
+-static unsigned short __init
+-fill_cplbtab(struct cplb_tab *table,
+-	     unsigned long start, unsigned long end,
+-	     unsigned long block_size, unsigned long cplb_data)
 -{
--        strncpy_skip_quote(vmpoff_cmd, str, 127);
--        vmpoff_cmd[127] = 0;
--        return 1;
+-	int i;
+-
+-	switch (block_size) {
+-	case SIZE_4M:
+-		i = 3;
+-		break;
+-	case SIZE_1M:
+-		i = 2;
+-		break;
+-	case SIZE_4K:
+-		i = 1;
+-		break;
+-	case SIZE_1K:
+-	default:
+-		i = 0;
+-		break;
+-	}
+-
+-	cplb_data = (cplb_data & ~(3 << 16)) | (i << 16);
+-
+-	while ((start < end) && (table->pos < table->size)) {
+-
+-		table->tab[table->pos++] = start;
+-
+-		if (lock_kernel_check(start, start + block_size) == IN_KERNEL)
+-			table->tab[table->pos++] =
+-			    cplb_data | CPLB_LOCK | CPLB_DIRTY;
+-		else
+-			table->tab[table->pos++] = cplb_data;
+-
+-		start += block_size;
+-	}
+-	return 0;
 -}
 -
--__setup("vmpoff=", vmpoff_setup);
+-static unsigned short __init
+-close_cplbtab(struct cplb_tab *table)
+-{
 -
--static int vmpanic_notify(struct notifier_block *self, unsigned long event,
--			  void *data)
+-	while (table->pos < table->size) {
+-
+-		table->tab[table->pos++] = 0;
+-		table->tab[table->pos++] = 0; /* !CPLB_VALID */
+-	}
+-	return 0;
+-}
+-
+-/* helper function */
+-static void __fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
 -{
--	if (MACHINE_IS_VM && strlen(vmpanic_cmd) > 0)
--		cpcmd(vmpanic_cmd, NULL, 0, NULL);
+-	if (cplb_data[i].psize) {
+-		fill_cplbtab(t,
+-				cplb_data[i].start,
+-				cplb_data[i].end,
+-				cplb_data[i].psize,
+-				cplb_data[i].i_conf);
+-	} else {
+-#if defined(CONFIG_BFIN_ICACHE)
+-		if (ANOMALY_05000263 && i == SDRAM_KERN) {
+-			fill_cplbtab(t,
+-					cplb_data[i].start,
+-					cplb_data[i].end,
+-					SIZE_4M,
+-					cplb_data[i].i_conf);
+-		} else
+-#endif
+-		{
+-			fill_cplbtab(t,
+-					cplb_data[i].start,
+-					a_start,
+-					SIZE_1M,
+-					cplb_data[i].i_conf);
+-			fill_cplbtab(t,
+-					a_start,
+-					a_end,
+-					SIZE_4M,
+-					cplb_data[i].i_conf);
+-			fill_cplbtab(t, a_end,
+-					cplb_data[i].end,
+-					SIZE_1M,
+-					cplb_data[i].i_conf);
+-		}
+-	}
+-}
 -
--	return NOTIFY_OK;
+-static void __fill_data_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
+-{
+-	if (cplb_data[i].psize) {
+-		fill_cplbtab(t,
+-				cplb_data[i].start,
+-				cplb_data[i].end,
+-				cplb_data[i].psize,
+-				cplb_data[i].d_conf);
+-	} else {
+-		fill_cplbtab(t,
+-				cplb_data[i].start,
+-				a_start, SIZE_1M,
+-				cplb_data[i].d_conf);
+-		fill_cplbtab(t, a_start,
+-				a_end, SIZE_4M,
+-				cplb_data[i].d_conf);
+-		fill_cplbtab(t, a_end,
+-				cplb_data[i].end,
+-				SIZE_1M,
+-				cplb_data[i].d_conf);
+-	}
 -}
 -
--#define PANIC_PRI_VMPANIC	0
+-void __init generate_cpl_tables(void)
+-{
+-
+-	u16 i, j, process;
+-	u32 a_start, a_end, as, ae, as_1m;
+-
+-	struct cplb_tab *t_i = NULL;
+-	struct cplb_tab *t_d = NULL;
+-	struct s_cplb cplb;
+-
+-	cplb.init_i.size = MAX_CPLBS;
+-	cplb.init_d.size = MAX_CPLBS;
+-	cplb.switch_i.size = MAX_SWITCH_I_CPLBS;
+-	cplb.switch_d.size = MAX_SWITCH_D_CPLBS;
+-
+-	cplb.init_i.pos = 0;
+-	cplb.init_d.pos = 0;
+-	cplb.switch_i.pos = 0;
+-	cplb.switch_d.pos = 0;
+-
+-	cplb.init_i.tab = icplb_table;
+-	cplb.init_d.tab = dcplb_table;
+-	cplb.switch_i.tab = ipdt_table;
+-	cplb.switch_d.tab = dpdt_table;
+-
+-	cplb_data[SDRAM_KERN].end = memory_end;
+-
+-#ifdef CONFIG_MTD_UCLINUX
+-	cplb_data[SDRAM_RAM_MTD].start = memory_mtd_start;
+-	cplb_data[SDRAM_RAM_MTD].end = memory_mtd_start + mtd_size;
+-	cplb_data[SDRAM_RAM_MTD].valid = mtd_size > 0;
+-# if defined(CONFIG_ROMFS_FS)
+-	cplb_data[SDRAM_RAM_MTD].attr |= I_CPLB;
 -
--static struct notifier_block vmpanic_nb = {
--	.notifier_call = vmpanic_notify,
--	.priority = PANIC_PRI_VMPANIC
--};
+-	/*
+-	 * The ROMFS_FS size is often not multiple of 1MB.
+-	 * This can cause multiple CPLB sets covering the same memory area.
+-	 * This will then cause multiple CPLB hit exceptions.
+-	 * Workaround: We ensure a contiguous memory area by extending the kernel
+-	 * memory section over the mtd section.
+-	 * For ROMFS_FS memory must be covered with ICPLBs anyways.
+-	 * So there is no difference between kernel and mtd memory setup.
+-	 */
 -
--static int __init vmpanic_setup(char *str)
--{
--	static int register_done __initdata = 0;
+-	cplb_data[SDRAM_KERN].end = memory_mtd_start + mtd_size;;
+-	cplb_data[SDRAM_RAM_MTD].valid = 0;
 -
--	strncpy_skip_quote(vmpanic_cmd, str, 127);
--	vmpanic_cmd[127] = 0;
--	if (!register_done) {
--		register_done = 1;
--		atomic_notifier_chain_register(&panic_notifier_list,
--					       &vmpanic_nb);
+-# endif
+-#else
+-	cplb_data[SDRAM_RAM_MTD].valid = 0;
+-#endif
+-
+-	cplb_data[SDRAM_DMAZ].start = _ramend - DMA_UNCACHED_REGION;
+-	cplb_data[SDRAM_DMAZ].end = _ramend;
+-
+-	cplb_data[RES_MEM].start = _ramend;
+-	cplb_data[RES_MEM].end = physical_mem_end;
+-
+-	if (reserved_mem_dcache_on)
+-		cplb_data[RES_MEM].d_conf = SDRAM_DGENERIC;
+-	else
+-		cplb_data[RES_MEM].d_conf = SDRAM_DNON_CHBL;
+-
+-	if (reserved_mem_icache_on)
+-		cplb_data[RES_MEM].i_conf = SDRAM_IGENERIC;
+-	else
+-		cplb_data[RES_MEM].i_conf = SDRAM_INON_CHBL;
+-
+-	for (i = ZERO_P; i < ARRAY_SIZE(cplb_data); ++i) {
+-		if (!cplb_data[i].valid)
+-			continue;
+-
+-		as_1m = cplb_data[i].start % SIZE_1M;
+-
+-		/* We need to make sure all sections are properly 1M aligned
+-		 * However between Kernel Memory and the Kernel mtd section, depending on the
+-		 * rootfs size, there can be overlapping memory areas.
+-		 */
+-
+-		if (as_1m && i != L1I_MEM && i != L1D_MEM) {
+-#ifdef CONFIG_MTD_UCLINUX
+-			if (i == SDRAM_RAM_MTD) {
+-				if ((cplb_data[SDRAM_KERN].end + 1) > cplb_data[SDRAM_RAM_MTD].start)
+-					cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M)) + SIZE_1M;
+-				else
+-					cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M));
+-			} else
+-#endif
+-				printk(KERN_WARNING "Unaligned Start of %s at 0x%X\n",
+-				       cplb_data[i].name, cplb_data[i].start);
+-		}
+-
+-		as = cplb_data[i].start % SIZE_4M;
+-		ae = cplb_data[i].end % SIZE_4M;
+-
+-		if (as)
+-			a_start = cplb_data[i].start + (SIZE_4M - (as));
+-		else
+-			a_start = cplb_data[i].start;
+-
+-		a_end = cplb_data[i].end - ae;
+-
+-		for (j = INITIAL_T; j <= SWITCH_T; j++) {
+-
+-			switch (j) {
+-			case INITIAL_T:
+-				if (cplb_data[i].attr & INITIAL_T) {
+-					t_i = &cplb.init_i;
+-					t_d = &cplb.init_d;
+-					process = 1;
+-				} else
+-					process = 0;
+-				break;
+-			case SWITCH_T:
+-				if (cplb_data[i].attr & SWITCH_T) {
+-					t_i = &cplb.switch_i;
+-					t_d = &cplb.switch_d;
+-					process = 1;
+-				} else
+-					process = 0;
+-				break;
+-			default:
+-					process = 0;
+-				break;
+-			}
+-
+-			if (!process)
+-				continue;
+-			if (cplb_data[i].attr & I_CPLB)
+-				__fill_code_cplbtab(t_i, i, a_start, a_end);
+-
+-			if (cplb_data[i].attr & D_CPLB)
+-				__fill_data_cplbtab(t_d, i, a_start, a_end);
+-		}
 -	}
--	return 1;
+-
+-/* close tables */
+-
+-	close_cplbtab(&cplb.init_i);
+-	close_cplbtab(&cplb.init_d);
+-
+-	cplb.init_i.tab[cplb.init_i.pos] = -1;
+-	cplb.init_d.tab[cplb.init_d.pos] = -1;
+-	cplb.switch_i.tab[cplb.switch_i.pos] = -1;
+-	cplb.switch_d.tab[cplb.switch_d.pos] = -1;
+-
 -}
 -
--__setup("vmpanic=", vmpanic_setup);
+-#endif
 -
--/*
-  * condev= and conmode= setup parameter.
-  */
+diff --git a/arch/blackfin/kernel/early_printk.c b/arch/blackfin/kernel/early_printk.c
+index 724f4a5..60f67f9 100644
+--- a/arch/blackfin/kernel/early_printk.c
++++ b/arch/blackfin/kernel/early_printk.c
+@@ -187,7 +187,7 @@ asmlinkage void __init init_early_exception_vectors(void)
+ 	bfin_write_EVT15(early_trap);
+ 	CSYNC();
  
-@@ -308,38 +239,6 @@ static void __init setup_zfcpdump(unsigned int console_devno)
- static inline void setup_zfcpdump(unsigned int console_devno) {}
- #endif /* CONFIG_ZFCPDUMP */
+-	/* Set all the return from interupt, exception, NMI to a known place
++	/* Set all the return from interrupt, exception, NMI to a known place
+ 	 * so if we do a RETI, RETX or RETN by mistake - we go somewhere known
+ 	 * Note - don't change RETS - we are in a subroutine, or
+ 	 * RETE - since it might screw up if emulator is attached
+@@ -205,7 +205,7 @@ asmlinkage void __init early_trap_c(struct pt_regs *fp, void *retaddr)
+ 	if (likely(early_console == NULL))
+ 		setup_early_printk(DEFAULT_EARLY_PORT);
  
--#ifdef CONFIG_SMP
--void (*_machine_restart)(char *command) = machine_restart_smp;
--void (*_machine_halt)(void) = machine_halt_smp;
--void (*_machine_power_off)(void) = machine_power_off_smp;
--#else
--/*
-- * Reboot, halt and power_off routines for non SMP.
+-	dump_bfin_mem((void *)fp->retx);
++	dump_bfin_mem(fp);
+ 	show_regs(fp);
+ 	dump_bfin_trace_buffer();
+ 
+diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
+index 5bf1512..023dc80 100644
+--- a/arch/blackfin/kernel/process.c
++++ b/arch/blackfin/kernel/process.c
+@@ -39,9 +39,6 @@
+ #include <asm/blackfin.h>
+ #include <asm/fixed_code.h>
+ 
+-#define	LED_ON	0
+-#define	LED_OFF	1
+-
+ asmlinkage void ret_from_fork(void);
+ 
+ /* Points to the SDRAM backup memory for the stack that is currently in
+@@ -70,32 +67,6 @@ void (*pm_power_off)(void) = NULL;
+ EXPORT_SYMBOL(pm_power_off);
+ 
+ /*
+- * We are using a different LED from the one used to indicate timer interrupt.
 - */
--static void do_machine_restart_nonsmp(char * __unused)
+-#if defined(CONFIG_BFIN_IDLE_LED)
+-static inline void leds_switch(int flag)
 -{
--	do_reipl();
--}
+-	unsigned short tmp = 0;
 -
--static void do_machine_halt_nonsmp(void)
--{
--        if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0)
--		__cpcmd(vmhalt_cmd, NULL, 0, NULL);
--        signal_processor(smp_processor_id(), sigp_stop_and_store_status);
--}
+-	tmp = bfin_read_CONFIG_BFIN_IDLE_LED_PORT();
+-	SSYNC();
 -
--static void do_machine_power_off_nonsmp(void)
+-	if (flag == LED_ON)
+-		tmp &= ~CONFIG_BFIN_IDLE_LED_PIN;	/* light on */
+-	else
+-		tmp |= CONFIG_BFIN_IDLE_LED_PIN;	/* light off */
+-
+-	bfin_write_CONFIG_BFIN_IDLE_LED_PORT(tmp);
+-	SSYNC();
+-
+-}
+-#else
+-static inline void leds_switch(int flag)
 -{
--        if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0)
--		__cpcmd(vmpoff_cmd, NULL, 0, NULL);
--        signal_processor(smp_processor_id(), sigp_stop_and_store_status);
 -}
--
--void (*_machine_restart)(char *command) = do_machine_restart_nonsmp;
--void (*_machine_halt)(void) = do_machine_halt_nonsmp;
--void (*_machine_power_off)(void) = do_machine_power_off_nonsmp;
 -#endif
 -
-  /*
-  * Reboot, halt and power_off stubs. They just call _machine_restart,
-  * _machine_halt or _machine_power_off. 
-@@ -559,7 +458,9 @@ setup_resources(void)
- 	data_resource.start = (unsigned long) &_etext;
- 	data_resource.end = (unsigned long) &_edata - 1;
- 
--	for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) {
-+	for (i = 0; i < MEMORY_CHUNKS; i++) {
-+		if (!memory_chunk[i].size)
-+			continue;
- 		res = alloc_bootmem_low(sizeof(struct resource));
- 		res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
- 		switch (memory_chunk[i].type) {
-@@ -617,7 +518,7 @@ EXPORT_SYMBOL_GPL(real_memory_size);
- static void __init setup_memory_end(void)
+-/*
+  * The idle loop on BFIN
+  */
+ #ifdef CONFIG_IDLE_L1
+@@ -106,12 +77,10 @@ void cpu_idle(void)__attribute__((l1_text));
+ void default_idle(void)
  {
- 	unsigned long memory_size;
--	unsigned long max_mem, max_phys;
-+	unsigned long max_mem;
- 	int i;
+ 	while (!need_resched()) {
+-		leds_switch(LED_OFF);
+ 		local_irq_disable();
+ 		if (likely(!need_resched()))
+ 			idle_with_irq_disabled();
+ 		local_irq_enable();
+-		leds_switch(LED_ON);
+ 	}
+ }
  
- #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE)
-@@ -625,10 +526,31 @@ static void __init setup_memory_end(void)
- 		memory_end = ZFCPDUMP_HSA_SIZE;
+@@ -327,6 +296,7 @@ void finish_atomic_sections (struct pt_regs *regs)
+ }
+ 
+ #if defined(CONFIG_ACCESS_CHECK)
++/* Return 1 if access to memory range is OK, 0 otherwise */
+ int _access_ok(unsigned long addr, unsigned long size)
+ {
+ 	if (size == 0)
+diff --git a/arch/blackfin/kernel/reboot.c b/arch/blackfin/kernel/reboot.c
+index ae28aac..483f93d 100644
+--- a/arch/blackfin/kernel/reboot.c
++++ b/arch/blackfin/kernel/reboot.c
+@@ -19,6 +19,11 @@
+ #define SYSCR_VAL 	0x10
  #endif
- 	memory_size = 0;
--	max_phys = VMALLOC_END_INIT - VMALLOC_MIN_SIZE;
- 	memory_end &= PAGE_MASK;
  
--	max_mem = memory_end ? min(max_phys, memory_end) : max_phys;
-+	max_mem = memory_end ? min(VMALLOC_START, memory_end) : VMALLOC_START;
-+	memory_end = min(max_mem, memory_end);
++/*
++ * Delay min 5 SCLK cycles using worst case CCLK/SCLK ratio (15)
++ */
++#define SWRST_DELAY	(5 * 15)
 +
-+	/*
-+	 * Make sure all chunks are MAX_ORDER aligned so we don't need the
-+	 * extra checks that HOLES_IN_ZONE would require.
-+	 */
-+	for (i = 0; i < MEMORY_CHUNKS; i++) {
-+		unsigned long start, end;
-+		struct mem_chunk *chunk;
-+		unsigned long align;
+ /* A system soft reset makes external memory unusable
+  * so force this function into L1.
+  */
+@@ -34,7 +39,13 @@ void bfin_reset(void)
+ 	while (1) {
+ 		/* initiate system soft reset with magic 0x7 */
+ 		bfin_write_SWRST(0x7);
+-		asm("ssync;");
 +
-+		chunk = &memory_chunk[i];
-+		align = 1UL << (MAX_ORDER + PAGE_SHIFT - 1);
-+		start = (chunk->addr + align - 1) & ~(align - 1);
-+		end = (chunk->addr + chunk->size) & ~(align - 1);
-+		if (start >= end)
-+			memset(chunk, 0, sizeof(*chunk));
-+		else {
-+			chunk->addr = start;
-+			chunk->size = end - start;
-+		}
-+	}
++		/* Wait for System reset to actually reset, needs to be 5 SCLKs, */
++		/* Assume CCLK / SCLK ratio is worst case (15), and use 5*15     */
++
++		asm("LSETUP(.Lfoo,.Lfoo) LC0 = %0\n .Lfoo: NOP;\n"
++		 : : "a" (SWRST_DELAY) : "LC0", "LT0", "LB0");
++
+ 		/* clear system soft reset */
+ 		bfin_write_SWRST(0);
+ 		asm("ssync;");
+diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
+index d282201..462cae8 100644
+--- a/arch/blackfin/kernel/setup.c
++++ b/arch/blackfin/kernel/setup.c
+@@ -238,7 +238,13 @@ void __init setup_arch(char **cmdline_p)
+ 	memory_end = _ramend - DMA_UNCACHED_REGION;
  
- 	for (i = 0; i < MEMORY_CHUNKS; i++) {
- 		struct mem_chunk *chunk = &memory_chunk[i];
-@@ -890,7 +812,7 @@ setup_arch(char **cmdline_p)
+ 	_ramstart = (unsigned long)__bss_stop;
++	_rambase = (unsigned long)_stext;
++#ifdef CONFIG_MPU
++	/* Round up to multiple of 4MB.  */
++	memory_start = (_ramstart + 0x3fffff) & ~0x3fffff;
++#else
+ 	memory_start = PAGE_ALIGN(_ramstart);
++#endif
  
- 	parse_early_param();
+ #if defined(CONFIG_MTD_UCLINUX)
+ 	/* generic memory mapped MTD driver */
+@@ -307,6 +313,11 @@ void __init setup_arch(char **cmdline_p)
+ 	printk(KERN_NOTICE "Warning: limiting memory to %liMB due to hardware anomaly 05000263\n", memory_end >> 20);
+ #endif				/* ANOMALY_05000263 */
+ 
++#ifdef CONFIG_MPU
++	page_mask_nelts = ((_ramend >> PAGE_SHIFT) + 31) / 32;
++	page_mask_order = get_order(3 * page_mask_nelts * sizeof(long));
++#endif
++
+ #if !defined(CONFIG_MTD_UCLINUX)
+ 	memory_end -= SIZE_4K; /*In case there is no valid CPLB behind memory_end make sure we don't get to close*/
+ #endif
+@@ -315,8 +326,6 @@ void __init setup_arch(char **cmdline_p)
+ 	init_mm.end_data = (unsigned long)_edata;
+ 	init_mm.brk = (unsigned long)0;
+ 
+-	init_leds();
+-
+ 	_bfin_swrst = bfin_read_SWRST();
+ 
+ 	if (_bfin_swrst & RESET_DOUBLE)
+diff --git a/arch/blackfin/kernel/time.c b/arch/blackfin/kernel/time.c
+index beef057..5bd64e3 100644
+--- a/arch/blackfin/kernel/time.c
++++ b/arch/blackfin/kernel/time.c
+@@ -42,75 +42,6 @@
+ static void time_sched_init(irqreturn_t(*timer_routine)
+ 			(int, void *));
+ static unsigned long gettimeoffset(void);
+-static inline void do_leds(void);
+-
+-#if (defined(CONFIG_BFIN_ALIVE_LED) || defined(CONFIG_BFIN_IDLE_LED))
+-void __init init_leds(void)
+-{
+-	unsigned int tmp = 0;
+-
+-#if defined(CONFIG_BFIN_ALIVE_LED)
+-	/* config pins as output. */
+-	tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_DPORT();
+-	SSYNC();
+-	bfin_write_CONFIG_BFIN_ALIVE_LED_DPORT(tmp | CONFIG_BFIN_ALIVE_LED_PIN);
+-	SSYNC();
+-
+-	/*      First set led be off */
+-	tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_PORT();
+-	SSYNC();
+-	bfin_write_CONFIG_BFIN_ALIVE_LED_PORT(tmp | CONFIG_BFIN_ALIVE_LED_PIN);	/* light off */
+-	SSYNC();
+-#endif
+-
+-#if defined(CONFIG_BFIN_IDLE_LED)
+-	/* config pins as output. */
+-	tmp = bfin_read_CONFIG_BFIN_IDLE_LED_DPORT();
+-	SSYNC();
+-	bfin_write_CONFIG_BFIN_IDLE_LED_DPORT(tmp | CONFIG_BFIN_IDLE_LED_PIN);
+-	SSYNC();
+-
+-	/*      First set led be off */
+-	tmp = bfin_read_CONFIG_BFIN_IDLE_LED_PORT();
+-	SSYNC();
+-	bfin_write_CONFIG_BFIN_IDLE_LED_PORT(tmp | CONFIG_BFIN_IDLE_LED_PIN);	/* light off */
+-	SSYNC();
+-#endif
+-}
+-#else
+-void __init init_leds(void)
+-{
+-}
+-#endif
+-
+-#if defined(CONFIG_BFIN_ALIVE_LED)
+-static inline void do_leds(void)
+-{
+-	static unsigned int count = 50;
+-	static int flag;
+-	unsigned short tmp = 0;
+-
+-	if (--count == 0) {
+-		count = 50;
+-		flag = ~flag;
+-	}
+-	tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_PORT();
+-	SSYNC();
+-
+-	if (flag)
+-		tmp &= ~CONFIG_BFIN_ALIVE_LED_PIN;	/* light on */
+-	else
+-		tmp |= CONFIG_BFIN_ALIVE_LED_PIN;	/* light off */
+-
+-	bfin_write_CONFIG_BFIN_ALIVE_LED_PORT(tmp);
+-	SSYNC();
+-
+-}
+-#else
+-static inline void do_leds(void)
+-{
+-}
+-#endif
  
--	setup_ipl_info();
-+	setup_ipl();
- 	setup_memory_end();
- 	setup_addressing_mode();
- 	setup_memory();
-@@ -899,7 +821,6 @@ setup_arch(char **cmdline_p)
+ static struct irqaction bfin_timer_irq = {
+ 	.name = "BFIN Timer Tick",
+@@ -205,7 +136,6 @@ irqreturn_t timer_interrupt(int irq, void *dummy)
+ 	write_seqlock(&xtime_lock);
  
-         cpu_init();
-         __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr;
--	smp_setup_cpu_possible_map();
+ 	do_timer(1);
+-	do_leds();
  
- 	/*
- 	 * Setup capabilities (ELF_HWCAP & ELF_PLATFORM).
-@@ -920,7 +841,7 @@ setup_arch(char **cmdline_p)
+ #ifndef CONFIG_SMP
+ 	update_process_times(user_mode(get_irq_regs()));
+diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
+index 21a55ef..66b5f3e 100644
+--- a/arch/blackfin/kernel/traps.c
++++ b/arch/blackfin/kernel/traps.c
+@@ -36,8 +36,10 @@
+ #include <asm/cacheflush.h>
+ #include <asm/blackfin.h>
+ #include <asm/irq_handler.h>
++#include <linux/irq.h>
+ #include <asm/trace.h>
+ #include <asm/fixed_code.h>
++#include <asm/dma.h>
+ 
+ #ifdef CONFIG_KGDB
+ # include <linux/debugger.h>
+@@ -170,7 +172,7 @@ asmlinkage void double_fault_c(struct pt_regs *fp)
+ 	oops_in_progress = 1;
+ 	printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n");
+ 	dump_bfin_process(fp);
+-	dump_bfin_mem((void *)fp->retx);
++	dump_bfin_mem(fp);
+ 	show_regs(fp);
+ 	panic("Double Fault - unrecoverable event\n");
+ 
+@@ -195,9 +197,13 @@ asmlinkage void trap_c(struct pt_regs *fp)
+ 	 * we will kernel panic, so the system reboots.
+ 	 * If KGDB is enabled, don't set this for kernel breakpoints
+ 	*/
+-	if ((bfin_read_IPEND() & 0xFFC0)
++
++	/* TODO: check to see if we are in some sort of deferred HWERR
++	 * that we should be able to recover from, not kernel panic
++	 */
++	if ((bfin_read_IPEND() & 0xFFC0) && (trapnr != VEC_STEP)
+ #ifdef CONFIG_KGDB
+-		&& trapnr != VEC_EXCPT02
++		&& (trapnr != VEC_EXCPT02)
+ #endif
+ 	){
+ 		console_verbose();
+@@ -433,6 +439,36 @@ asmlinkage void trap_c(struct pt_regs *fp)
+ 	/* 0x3D - Reserved, Caught by default */
+ 	/* 0x3E - Reserved, Caught by default */
+ 	/* 0x3F - Reserved, Caught by default */
++	case VEC_HWERR:
++		info.si_code = BUS_ADRALN;
++		sig = SIGBUS;
++		switch (fp->seqstat & SEQSTAT_HWERRCAUSE) {
++		/* System MMR Error */
++		case (SEQSTAT_HWERRCAUSE_SYSTEM_MMR):
++			info.si_code = BUS_ADRALN;
++			sig = SIGBUS;
++			printk(KERN_NOTICE HWC_x2(KERN_NOTICE));
++			break;
++		/* External Memory Addressing Error */
++		case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR):
++			info.si_code = BUS_ADRERR;
++			sig = SIGBUS;
++			printk(KERN_NOTICE HWC_x3(KERN_NOTICE));
++			break;
++		/* Performance Monitor Overflow */
++		case (SEQSTAT_HWERRCAUSE_PERF_FLOW):
++			printk(KERN_NOTICE HWC_x12(KERN_NOTICE));
++			break;
++		/* RAISE 5 instruction */
++		case (SEQSTAT_HWERRCAUSE_RAISE_5):
++			printk(KERN_NOTICE HWC_x18(KERN_NOTICE));
++			break;
++		default:        /* Reserved */
++			printk(KERN_NOTICE HWC_default(KERN_NOTICE));
++			break;
++		}
++		CHK_DEBUGGER_TRAP();
++		break;
+ 	default:
+ 		info.si_code = TRAP_ILLTRAP;
+ 		sig = SIGTRAP;
+@@ -447,7 +483,7 @@ asmlinkage void trap_c(struct pt_regs *fp)
+ 	if (sig != SIGTRAP) {
+ 		unsigned long stack;
+ 		dump_bfin_process(fp);
+-		dump_bfin_mem((void *)fp->retx);
++		dump_bfin_mem(fp);
+ 		show_regs(fp);
+ 
+ 		/* Print out the trace buffer if it makes sense */
+@@ -461,6 +497,7 @@ asmlinkage void trap_c(struct pt_regs *fp)
+ 			dump_bfin_trace_buffer();
+ 		show_stack(current, &stack);
+ 		if (oops_in_progress) {
++			print_modules();
+ #ifndef CONFIG_ACCESS_CHECK
+ 			printk(KERN_EMERG "Please turn on "
+ 			       "CONFIG_ACCESS_CHECK\n");
+@@ -474,13 +511,6 @@ asmlinkage void trap_c(struct pt_regs *fp)
+ 	info.si_addr = (void *)fp->pc;
+ 	force_sig_info(sig, &info, current);
+ 
+-	/* Ensure that bad return addresses don't end up in an infinite
+-	 * loop, due to speculative loads/reads. This needs to be done after
+-	 * the signal has been sent.
+-	 */
+-	if (trapnr == VEC_CPLB_I_M && sig != SIGTRAP)
+-		fp->pc = SAFE_USER_INSTRUCTION;
+-
+ 	trace_buffer_restore(j);
+ 	return;
+ }
+@@ -616,8 +646,10 @@ void dump_bfin_process(struct pt_regs *fp)
+ 	if (oops_in_progress)
+ 		printk(KERN_EMERG "Kernel OOPS in progress\n");
+ 
+-	if (context & 0x0020)
+-		printk(KERN_NOTICE "Deferred excecption or HW Error context\n");
++	if (context & 0x0020 && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR)
++		printk(KERN_NOTICE "HW Error context\n");
++	else if (context & 0x0020)
++		printk(KERN_NOTICE "Defered Exception context\n");
+ 	else if (context & 0x3FC0)
+ 		printk(KERN_NOTICE "Interrupt context\n");
+ 	else if (context & 0x4000)
+@@ -645,59 +677,124 @@ void dump_bfin_process(struct pt_regs *fp)
+ 		     "No Valid process in current context\n");
+ }
+ 
+-void dump_bfin_mem(void *retaddr)
++void dump_bfin_mem(struct pt_regs *fp)
+ {
++	unsigned short *addr, *erraddr, val = 0, err = 0;
++	char sti = 0, buf[6];
+ 
+-	if (retaddr >= (void *)FIXED_CODE_START  && retaddr < (void *)physical_mem_end
+-#if L1_CODE_LENGTH != 0
+-	    /* FIXME: Copy the code out of L1 Instruction SRAM through dma
+-	       memcpy.  */
+-	    && !(retaddr >= (void *)L1_CODE_START
+-	         && retaddr < (void *)(L1_CODE_START + L1_CODE_LENGTH))
+-#endif
+-	) {
+-		int i = ((unsigned int)retaddr & 0xFFFFFFF0) - 32;
+-		unsigned short x = 0;
+-		printk(KERN_NOTICE "return address: [0x%p]; contents of:", retaddr);
+-		for (; i < ((unsigned int)retaddr & 0xFFFFFFF0) + 32; i += 2) {
+-			if (!(i & 0xF))
+-				printk("\n" KERN_NOTICE "0x%08x: ", i);
+-
+-			if (get_user(x, (unsigned short *)i))
+-				break;
++	if (unlikely((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR))
++		erraddr = (void *)fp->pc;
++	else
++		erraddr = (void *)fp->retx;
++
++	printk(KERN_NOTICE "return address: [0x%p]; contents of:", erraddr);
++
++	for (addr = (unsigned short *)((unsigned long)erraddr & ~0xF) - 0x10;
++	     addr < (unsigned short *)((unsigned long)erraddr & ~0xF) + 0x10;
++	     addr++) {
++		if (!((unsigned long)addr & 0xF))
++			printk("\n" KERN_NOTICE "0x%p: ", addr);
++
++		if (get_user(val, addr)) {
++			if (addr >= (unsigned short *)L1_CODE_START &&
++			    addr < (unsigned short *)(L1_CODE_START + L1_CODE_LENGTH)) {
++				dma_memcpy(&val, addr, sizeof(val));
++				sprintf(buf, "%04x", val);
++			} else if (addr >= (unsigned short *)FIXED_CODE_START &&
++				addr <= (unsigned short *)memory_start) {
++				val = bfin_read16(addr);
++				sprintf(buf, "%04x", val);
++			} else {
++				val = 0;
++				sprintf(buf, "????");
++			}
++		} else
++			sprintf(buf, "%04x", val);
++
++		if (addr == erraddr) {
++			printk("[%s]", buf);
++			err = val;
++		} else
++			printk(" %s ", buf);
++
++		/* Do any previous instructions turn on interrupts? */
++		if (addr <= erraddr &&				/* in the past */
++		    ((val >= 0x0040 && val <= 0x0047) ||	/* STI instruction */
++		      val == 0x017b))				/* [SP++] = RETI */
++			sti = 1;
++	}
++
++	printk("\n");
++
++	/* Hardware error interrupts can be deferred */
++	if (unlikely(sti && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR &&
++	    oops_in_progress)){
++		printk(KERN_NOTICE "Looks like this was a deferred error - sorry\n");
+ #ifndef CONFIG_DEBUG_HWERR
+-			/* If one of the last few instructions was a STI
+-			 * it is likely that the error occured awhile ago
+-			 * and we just noticed. This only happens in kernel
+-			 * context, which should mean an oops is happening
+-			 */
+-			if (oops_in_progress && x >= 0x0040 && x <= 0x0047 && i <= 0)
+-				panic("\n\nWARNING : You should reconfigure"
+-					" the kernel to turn on\n"
+-					" 'Hardware error interrupt"
+-					" debugging'\n"
+-					" The rest of this error"
+-					" is meanless\n");
+-#endif
+-			if (i == (unsigned int)retaddr)
+-				printk("[%04x]", x);
+-			else
+-				printk(" %04x ", x);
++		printk(KERN_NOTICE "The remaining message may be meaningless\n"
++			KERN_NOTICE "You should enable CONFIG_DEBUG_HWERR to get a"
++			 " better idea where it came from\n");
++#else
++		/* If we are handling only one peripheral interrupt
++		 * and current mm and pid are valid, and the last error
++		 * was in that user space process's text area
++		 * print it out - because that is where the problem exists
++		 */
++		if ((!(((fp)->ipend & ~0x30) & (((fp)->ipend & ~0x30) - 1))) &&
++		     (current->pid && current->mm)) {
++			/* And the last RETI points to the current userspace context */
++			if ((fp + 1)->pc >= current->mm->start_code &&
++			    (fp + 1)->pc <= current->mm->end_code) {
++				printk(KERN_NOTICE "It might be better to look around here : \n");
++				printk(KERN_NOTICE "-------------------------------------------\n");
++				show_regs(fp + 1);
++				printk(KERN_NOTICE "-------------------------------------------\n");
++			}
+ 		}
+-		printk("\n");
+-	} else
+-		printk("\n" KERN_NOTICE
+-			"Cannot look at the [PC] <%p> for it is"
+-			" in unreadable memory - sorry\n", retaddr);
++#endif
++	}
+ }
  
- void __cpuinit print_cpu_info(struct cpuinfo_S390 *cpuinfo)
- {
--   printk("cpu %d "
-+   printk(KERN_INFO "cpu %d "
- #ifdef CONFIG_SMP
-            "phys_idx=%d "
- #endif
-@@ -996,7 +917,7 @@ static void *c_next(struct seq_file *m, void *v, loff_t *pos)
- static void c_stop(struct seq_file *m, void *v)
+ void show_regs(struct pt_regs *fp)
  {
- }
--struct seq_operations cpuinfo_op = {
-+const struct seq_operations cpuinfo_op = {
- 	.start	= c_start,
- 	.next	= c_next,
- 	.stop	= c_stop,
-diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
-index d264671..4449bf3 100644
---- a/arch/s390/kernel/signal.c
-+++ b/arch/s390/kernel/signal.c
-@@ -471,6 +471,7 @@ void do_signal(struct pt_regs *regs)
+ 	char buf [150];
++	struct irqaction *action;
++	unsigned int i;
++	unsigned long flags;
  
- 	if (signr > 0) {
- 		/* Whee!  Actually deliver the signal.  */
-+		int ret;
- #ifdef CONFIG_COMPAT
- 		if (test_thread_flag(TIF_31BIT)) {
- 			extern int handle_signal32(unsigned long sig,
-@@ -478,15 +479,12 @@ void do_signal(struct pt_regs *regs)
- 						   siginfo_t *info,
- 						   sigset_t *oldset,
- 						   struct pt_regs *regs);
--			if (handle_signal32(
--				    signr, &ka, &info, oldset, regs) == 0) {
--				if (test_thread_flag(TIF_RESTORE_SIGMASK))
--					clear_thread_flag(TIF_RESTORE_SIGMASK);
--			}
--			return;
-+			ret = handle_signal32(signr, &ka, &info, oldset, regs);
- 	        }
-+		else
- #endif
--		if (handle_signal(signr, &ka, &info, oldset, regs) == 0) {
-+			ret = handle_signal(signr, &ka, &info, oldset, regs);
-+		if (!ret) {
- 			/*
- 			 * A signal was successfully delivered; the saved
- 			 * sigmask will have been stored in the signal frame,
-@@ -495,6 +493,14 @@ void do_signal(struct pt_regs *regs)
- 			 */
- 			if (test_thread_flag(TIF_RESTORE_SIGMASK))
- 				clear_thread_flag(TIF_RESTORE_SIGMASK);
+-	printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\n");
++	printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted());
+ 	printk(KERN_NOTICE " SEQSTAT: %08lx  IPEND: %04lx  SYSCFG: %04lx\n",
+ 		(long)fp->seqstat, fp->ipend, fp->syscfg);
++	printk(KERN_NOTICE "  HWERRCAUSE: 0x%lx\n",
++		(fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14);
++	printk(KERN_NOTICE "  EXCAUSE   : 0x%lx\n",
++		fp->seqstat & SEQSTAT_EXCAUSE);
++	for (i = 6; i <= 15 ; i++) {
++		if (fp->ipend & (1 << i)) {
++			decode_address(buf, bfin_read32(EVT0 + 4*i));
++			printk(KERN_NOTICE "  physical IVG%i asserted : %s\n", i, buf);
++		}
++	}
 +
-+			/*
-+			 * If we would have taken a single-step trap
-+			 * for a normal instruction, act like we took
-+			 * one for the handler setup.
-+			 */
-+			if (current->thread.per_info.single_step)
-+				set_thread_flag(TIF_SINGLE_STEP);
- 		}
- 		return;
- 	}
-diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
-index 264ea90..aa37fa1 100644
---- a/arch/s390/kernel/smp.c
-+++ b/arch/s390/kernel/smp.c
-@@ -42,6 +42,7 @@
- #include <asm/tlbflush.h>
- #include <asm/timer.h>
- #include <asm/lowcore.h>
-+#include <asm/sclp.h>
- #include <asm/cpu.h>
++	/* if no interrupts are going off, don't print this out */
++	if (fp->ipend & ~0x3F) {
++		for (i = 0; i < (NR_IRQS - 1); i++) {
++			spin_lock_irqsave(&irq_desc[i].lock, flags);
++			action = irq_desc[i].action;
++			if (!action)
++				goto unlock;
++
++			decode_address(buf, (unsigned int)action->handler);
++			printk(KERN_NOTICE "  logical irq %3d mapped  : %s", i, buf);
++			for (action = action->next; action; action = action->next) {
++				decode_address(buf, (unsigned int)action->handler);
++				printk(", %s", buf);
++			}
++			printk("\n");
++unlock:
++			spin_unlock_irqrestore(&irq_desc[i].lock, flags);
++		}
++	}
  
- /*
-@@ -53,11 +54,27 @@ EXPORT_SYMBOL(lowcore_ptr);
- cpumask_t cpu_online_map = CPU_MASK_NONE;
- EXPORT_SYMBOL(cpu_online_map);
+ 	decode_address(buf, fp->rete);
+ 	printk(KERN_NOTICE " RETE: %s\n", buf);
+@@ -708,9 +805,10 @@ void show_regs(struct pt_regs *fp)
+ 	decode_address(buf, fp->rets);
+ 	printk(KERN_NOTICE " RETS: %s\n", buf);
+ 	decode_address(buf, fp->pc);
+-	printk(KERN_NOTICE " PC: %s\n", buf);
++	printk(KERN_NOTICE " PC  : %s\n", buf);
+ 
+-	if ((long)fp->seqstat & SEQSTAT_EXCAUSE) {
++	if (((long)fp->seqstat &  SEQSTAT_EXCAUSE) &&
++	    (((long)fp->seqstat & SEQSTAT_EXCAUSE) != VEC_HWERR)) {
+ 		decode_address(buf, bfin_read_DCPLB_FAULT_ADDR());
+ 		printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf);
+ 		decode_address(buf, bfin_read_ICPLB_FAULT_ADDR());
+@@ -824,7 +922,7 @@ void panic_cplb_error(int cplb_panic, struct pt_regs *fp)
+ 	printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void *)bfin_read_DCPLB_FAULT_ADDR());
+ 	printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void *)bfin_read_ICPLB_FAULT_ADDR());
+ 	dump_bfin_process(fp);
+-	dump_bfin_mem((void *)fp->retx);
++	dump_bfin_mem(fp);
+ 	show_regs(fp);
+ 	dump_stack();
+ 	panic("Unrecoverable event\n");
+diff --git a/arch/blackfin/lib/memcpy.S b/arch/blackfin/lib/memcpy.S
+index 2e63364..e654a18 100644
+--- a/arch/blackfin/lib/memcpy.S
++++ b/arch/blackfin/lib/memcpy.S
+@@ -70,8 +70,8 @@ ENTRY(_memcpy)
+ 	/* Check for aligned data.*/
+ 
+ 	R3 = R1 | R0;
+-	R0 = 0x3;
+-	R3 = R3 & R0;
++	R1 = 0x3;
++	R3 = R3 & R1;
+ 	CC = R3;	/* low bits set on either address? */
+ 	IF CC JUMP .Lnot_aligned;
+ 
+@@ -83,7 +83,6 @@ ENTRY(_memcpy)
+ 	/* less than eight bytes... */
+ 	P2 = R2;
+ 	LSETUP(.Lthree_start, .Lthree_end) LC0=P2;
+-	R0 = R1;	/* setup src address for return */
+ .Lthree_start:
+ 	R3 = B[P1++] (X);
+ .Lthree_end:
+@@ -95,7 +94,6 @@ ENTRY(_memcpy)
+ 	/* There's at least eight bytes to copy. */
+ 	P2 += -1;	/* because we unroll one iteration */
+ 	LSETUP(.Lword_loops, .Lword_loope) LC0=P2;
+-	R0 = R1;
+ 	I1 = P1;
+ 	R3 = [I1++];
+ #if ANOMALY_05000202
+@@ -120,7 +118,6 @@ ENTRY(_memcpy)
+ .Lnot_aligned:
+ 	/* From here, we're copying byte-by-byte. */
+ 	LSETUP (.Lbyte_start, .Lbyte_end) LC0=P2;
+-	R0 = R1;	/* Save src address for return */
+ .Lbyte_start:
+ 	R1 = B[P1++] (X);
+ .Lbyte_end:
+@@ -135,7 +132,6 @@ ENTRY(_memcpy)
+ 	 * Don't bother to work out alignment for
+ 	 * the reverse case.
+ 	 */
+-	R0 = R1;	/* save src for later. */
+ 	P0 = P0 + P2;
+ 	P0 += -1;
+ 	P1 = P1 + P2;
+diff --git a/arch/blackfin/mach-bf527/Kconfig b/arch/blackfin/mach-bf527/Kconfig
+index 5c73683..3cde4be 100644
+--- a/arch/blackfin/mach-bf527/Kconfig
++++ b/arch/blackfin/mach-bf527/Kconfig
+@@ -43,7 +43,7 @@ endchoice
  
--cpumask_t cpu_possible_map = CPU_MASK_NONE;
-+cpumask_t cpu_possible_map = CPU_MASK_ALL;
- EXPORT_SYMBOL(cpu_possible_map);
+ choice
+ 	prompt "UART1"
+-	default BF527_UART1_PORTG
++	default BF527_UART1_PORTF
+ 	help
+ 	  Select PORT used for UART1. See Hardware Reference Manual
  
- static struct task_struct *current_set[NR_CPUS];
+diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
+index 003e2ac..f8c411a 100644
+--- a/arch/blackfin/mach-bf527/boards/ezkit.c
++++ b/arch/blackfin/mach-bf527/boards/ezkit.c
+@@ -8,7 +8,7 @@
+  *
+  * Modified:
+  *               Copyright 2005 National ICT Australia (NICTA)
+- *               Copyright 2004-2007 Analog Devices Inc.
++ *               Copyright 2004-2008 Analog Devices Inc.
+  *
+  * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+  *
+@@ -41,6 +41,7 @@
+ #include <linux/irq.h>
+ #include <linux/interrupt.h>
+ #include <linux/usb/sl811.h>
++#include <linux/usb/musb.h>
+ #include <asm/cplb.h>
+ #include <asm/dma.h>
+ #include <asm/bfin5xx_spi.h>
+@@ -105,6 +106,69 @@ void __exit bfin_isp1761_exit(void)
+ arch_initcall(bfin_isp1761_init);
+ #endif
  
-+static u8 smp_cpu_type;
-+static int smp_use_sigp_detection;
++#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
++static struct resource musb_resources[] = {
++	[0] = {
++		.start	= 0xffc03800,
++		.end	= 0xffc03cff,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {	/* general IRQ */
++		.start	= IRQ_USB_INT0,
++		.end	= IRQ_USB_INT0,
++		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
++	},
++	[2] = {	/* DMA IRQ */
++		.start	= IRQ_USB_DMA,
++		.end	= IRQ_USB_DMA,
++		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
++	},
++};
 +
-+enum s390_cpu_state {
-+	CPU_STATE_STANDBY,
-+	CPU_STATE_CONFIGURED,
++static struct musb_hdrc_platform_data musb_plat = {
++#if defined(CONFIG_USB_MUSB_OTG)
++	.mode		= MUSB_OTG,
++#elif defined(CONFIG_USB_MUSB_HDRC_HCD)
++	.mode		= MUSB_HOST,
++#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
++	.mode		= MUSB_PERIPHERAL,
++#endif
++	.multipoint	= 0,
 +};
 +
-+#ifdef CONFIG_HOTPLUG_CPU
-+static DEFINE_MUTEX(smp_cpu_state_mutex);
++static u64 musb_dmamask = ~(u32)0;
++
++static struct platform_device musb_device = {
++	.name		= "musb_hdrc",
++	.id		= 0,
++	.dev = {
++		.dma_mask		= &musb_dmamask,
++		.coherent_dma_mask	= 0xffffffff,
++		.platform_data		= &musb_plat,
++	},
++	.num_resources	= ARRAY_SIZE(musb_resources),
++	.resource	= musb_resources,
++};
 +#endif
-+static int smp_cpu_state[NR_CPUS];
 +
-+static DEFINE_PER_CPU(struct cpu, cpu_devices);
-+DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
++#if defined(CONFIG_FB_BFIN_T350MCQB) || defined(CONFIG_FB_BFIN_T350MCQB_MODULE)
 +
- static void smp_ext_bitcall(int, ec_bit_sig);
- 
- /*
-@@ -193,6 +210,33 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
- }
- EXPORT_SYMBOL(smp_call_function_single);
- 
-+/**
-+ * smp_call_function_mask(): Run a function on a set of other CPUs.
-+ * @mask: The set of cpus to run on.  Must not include the current cpu.
-+ * @func: The function to run. This must be fast and non-blocking.
-+ * @info: An arbitrary pointer to pass to the function.
-+ * @wait: If true, wait (atomically) until function has completed on other CPUs.
-+ *
-+ * Returns 0 on success, else a negative status code.
-+ *
-+ * If @wait is true, then returns once @func has returned; otherwise
-+ * it returns just before the target cpu calls @func.
-+ *
-+ * You must not call this function with disabled interrupts or from a
-+ * hardware interrupt handler or from a bottom half handler.
-+ */
-+int
-+smp_call_function_mask(cpumask_t mask,
-+			void (*func)(void *), void *info,
-+			int wait)
-+{
-+	preempt_disable();
-+	__smp_call_function_map(func, info, 0, wait, mask);
-+	preempt_enable();
-+	return 0;
-+}
-+EXPORT_SYMBOL(smp_call_function_mask);
++static struct resource bf52x_t350mcqb_resources[] = {
++	{
++		.start = IRQ_PPI_ERROR,
++		.end = IRQ_PPI_ERROR,
++		.flags = IORESOURCE_IRQ,
++	},
++};
 +
- void smp_send_stop(void)
++static struct platform_device bf52x_t350mcqb_device = {
++	.name		= "bfin-t350mcqb",
++	.id		= -1,
++	.num_resources 	= ARRAY_SIZE(bf52x_t350mcqb_resources),
++	.resource 	= bf52x_t350mcqb_resources,
++};
++#endif
++
+ #if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
+ static struct mtd_partition partition_info[] = {
+ 	{
+@@ -253,12 +317,7 @@ static struct resource sl811_hcd_resources[] = {
+ void sl811_port_power(struct device *dev, int is_on)
  {
- 	int cpu, rc;
-@@ -217,33 +261,6 @@ void smp_send_stop(void)
- }
- 
- /*
-- * Reboot, halt and power_off routines for SMP.
-- */
--void machine_restart_smp(char *__unused)
--{
--	smp_send_stop();
--	do_reipl();
--}
--
--void machine_halt_smp(void)
--{
--	smp_send_stop();
--	if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0)
--		__cpcmd(vmhalt_cmd, NULL, 0, NULL);
--	signal_processor(smp_processor_id(), sigp_stop_and_store_status);
--	for (;;);
--}
--
--void machine_power_off_smp(void)
--{
--	smp_send_stop();
--	if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0)
--		__cpcmd(vmpoff_cmd, NULL, 0, NULL);
--	signal_processor(smp_processor_id(), sigp_stop_and_store_status);
--	for (;;);
--}
+ 	gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
+-	gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS);
 -
--/*
-  * This is the main routine where commands issued by other
-  * cpus are handled.
-  */
-@@ -355,6 +372,13 @@ void smp_ctl_clear_bit(int cr, int bit)
+-	if (is_on)
+-		gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 1);
+-	else
+-		gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 0);
++	gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on);
  }
- EXPORT_SYMBOL(smp_ctl_clear_bit);
+ #endif
  
-+/*
-+ * In early ipl state a temp. logically cpu number is needed, so the sigp
-+ * functions can be used to sense other cpus. Since NR_CPUS is >= 2 on
-+ * CONFIG_SMP and the ipl cpu is logical cpu 0, it must be 1.
-+ */
-+#define CPU_INIT_NO	1
-+
- #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE)
+@@ -718,6 +777,28 @@ static struct platform_device bfin_pata_device = {
+ };
+ #endif
  
- /*
-@@ -375,9 +399,10 @@ static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
- 		       "kernel was compiled with NR_CPUS=%i\n", cpu, NR_CPUS);
- 		return;
- 	}
--	zfcpdump_save_areas[cpu] = alloc_bootmem(sizeof(union save_area));
--	__cpu_logical_map[1] = (__u16) phy_cpu;
--	while (signal_processor(1, sigp_stop_and_store_status) == sigp_busy)
-+	zfcpdump_save_areas[cpu] = kmalloc(sizeof(union save_area), GFP_KERNEL);
-+	__cpu_logical_map[CPU_INIT_NO] = (__u16) phy_cpu;
-+	while (signal_processor(CPU_INIT_NO, sigp_stop_and_store_status) ==
-+	       sigp_busy)
- 		cpu_relax();
- 	memcpy(zfcpdump_save_areas[cpu],
- 	       (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
-@@ -397,32 +422,155 @@ static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { }
++#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
++#include <linux/input.h>
++#include <linux/gpio_keys.h>
++
++static struct gpio_keys_button bfin_gpio_keys_table[] = {
++	{BTN_0, GPIO_PG0, 1, "gpio-keys: BTN0"},
++	{BTN_1, GPIO_PG13, 1, "gpio-keys: BTN1"},
++};
++
++static struct gpio_keys_platform_data bfin_gpio_keys_data = {
++	.buttons        = bfin_gpio_keys_table,
++	.nbuttons       = ARRAY_SIZE(bfin_gpio_keys_table),
++};
++
++static struct platform_device bfin_device_gpiokeys = {
++	.name      = "gpio-keys",
++	.dev = {
++		.platform_data = &bfin_gpio_keys_data,
++	},
++};
++#endif
++
+ static struct platform_device *stamp_devices[] __initdata = {
+ #if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
+ 	&bf5xx_nand_device,
+@@ -739,6 +820,10 @@ static struct platform_device *stamp_devices[] __initdata = {
+ 	&isp1362_hcd_device,
+ #endif
  
- #endif /* CONFIG_ZFCPDUMP || CONFIG_ZFCPDUMP_MODULE */
++#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
++	&musb_device,
++#endif
++
+ #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ 	&smc91x_device,
+ #endif
+@@ -763,6 +848,10 @@ static struct platform_device *stamp_devices[] __initdata = {
+ 	&bfin_fb_device,
+ #endif
  
--/*
-- * Lets check how many CPUs we have.
-- */
--static unsigned int __init smp_count_cpus(void)
-+static int cpu_stopped(int cpu)
- {
--	unsigned int cpu, num_cpus;
--	__u16 boot_cpu_addr;
-+	__u32 status;
++#if defined(CONFIG_FB_BFIN_T350MCQB) || defined(CONFIG_FB_BFIN_T350MCQB_MODULE)
++	&bf52x_t350mcqb_device,
++#endif
++
+ #if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+ 	&bfin_fb_adv7393_device,
+ #endif
+@@ -783,6 +872,10 @@ static struct platform_device *stamp_devices[] __initdata = {
+ #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+ 	&bfin_pata_device,
+ #endif
++
++#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
++	&bfin_device_gpiokeys,
++#endif
+ };
  
--	/*
--	 * cpu 0 is the boot cpu. See smp_prepare_boot_cpu.
--	 */
-+	/* Check for stopped state */
-+	if (signal_processor_ps(&status, 0, cpu, sigp_sense) ==
-+	    sigp_status_stored) {
-+		if (status & 0x40)
-+			return 1;
-+	}
-+	return 0;
-+}
+ static int __init stamp_init(void)
+diff --git a/arch/blackfin/mach-bf533/boards/H8606.c b/arch/blackfin/mach-bf533/boards/H8606.c
+index 6bcf404..a72c7a6 100644
+--- a/arch/blackfin/mach-bf533/boards/H8606.c
++++ b/arch/blackfin/mach-bf533/boards/H8606.c
+@@ -40,6 +40,7 @@
+ #endif
+ #include <linux/pata_platform.h>
+ #include <linux/irq.h>
 +
-+static int cpu_known(int cpu_id)
-+{
-+	int cpu;
+ #include <asm/dma.h>
+ #include <asm/bfin5xx_spi.h>
+ #include <asm/reboot.h>
+@@ -303,7 +304,77 @@ static struct platform_device bfin_uart_device = {
+ };
+ #endif
+ 
+-static struct platform_device *stamp_devices[] __initdata = {
++#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
 +
-+	for_each_present_cpu(cpu) {
-+		if (__cpu_logical_map[cpu] == cpu_id)
-+			return 1;
-+	}
-+	return 0;
-+}
++#include <linux/serial_8250.h>
++#include <linux/serial.h>
 +
-+static int smp_rescan_cpus_sigp(cpumask_t avail)
-+{
-+	int cpu_id, logical_cpu;
++/*
++ * Configuration for two 16550 UARTS in FPGA at addresses 0x20200000 and 0x202000010.
++ * running at half system clock, both with interrupt output or-ed to PF8. Change to
++ * suit different FPGA configuration, or to suit real 16550 UARTS connected to the bus
++ */
 +
-+	logical_cpu = first_cpu(avail);
-+	if (logical_cpu == NR_CPUS)
-+		return 0;
-+	for (cpu_id = 0; cpu_id <= 65535; cpu_id++) {
-+		if (cpu_known(cpu_id))
-+			continue;
-+		__cpu_logical_map[logical_cpu] = cpu_id;
-+		if (!cpu_stopped(logical_cpu))
-+			continue;
-+		cpu_set(logical_cpu, cpu_present_map);
-+		smp_cpu_state[logical_cpu] = CPU_STATE_CONFIGURED;
-+		logical_cpu = next_cpu(logical_cpu, avail);
-+		if (logical_cpu == NR_CPUS)
-+			break;
++static struct plat_serial8250_port serial8250_platform_data [] = {
++	{
++		.membase = 0x20200000,
++		.mapbase = 0x20200000,
++		.irq = IRQ_PF8,
++		.flags = UPF_BOOT_AUTOCONF | UART_CONFIG_TYPE,
++		.iotype = UPIO_MEM,
++		.regshift = 1,
++		.uartclk = 66666667,
++	}, {
++		.membase = 0x20200010,
++		.mapbase = 0x20200010,
++		.irq = IRQ_PF8,
++		.flags = UPF_BOOT_AUTOCONF | UART_CONFIG_TYPE,
++		.iotype = UPIO_MEM,
++		.regshift = 1,
++		.uartclk = 66666667,
++	}, {
 +	}
-+	return 0;
-+}
++};
 +
-+static int smp_rescan_cpus_sclp(cpumask_t avail)
-+{
-+	struct sclp_cpu_info *info;
-+	int cpu_id, logical_cpu, cpu;
-+	int rc;
++static struct platform_device serial8250_device = {
++	.id		= PLAT8250_DEV_PLATFORM,
++	.name		= "serial8250",
++	.dev		= {
++		.platform_data = serial8250_platform_data,
++	},
++};
 +
-+	logical_cpu = first_cpu(avail);
-+	if (logical_cpu == NR_CPUS)
-+		return 0;
-+	info = kmalloc(sizeof(*info), GFP_KERNEL);
-+	if (!info)
-+		return -ENOMEM;
-+	rc = sclp_get_cpu_info(info);
-+	if (rc)
-+		goto out;
-+	for (cpu = 0; cpu < info->combined; cpu++) {
-+		if (info->has_cpu_type && info->cpu[cpu].type != smp_cpu_type)
-+			continue;
-+		cpu_id = info->cpu[cpu].address;
-+		if (cpu_known(cpu_id))
-+			continue;
-+		__cpu_logical_map[logical_cpu] = cpu_id;
-+		cpu_set(logical_cpu, cpu_present_map);
-+		if (cpu >= info->configured)
-+			smp_cpu_state[logical_cpu] = CPU_STATE_STANDBY;
-+		else
-+			smp_cpu_state[logical_cpu] = CPU_STATE_CONFIGURED;
-+		logical_cpu = next_cpu(logical_cpu, avail);
-+		if (logical_cpu == NR_CPUS)
-+			break;
-+	}
-+out:
-+	kfree(info);
-+	return rc;
-+}
++#endif
 +
-+static int smp_rescan_cpus(void)
-+{
-+	cpumask_t avail;
++#if defined(CONFIG_KEYBOARD_OPENCORES) || defined(CONFIG_KEYBOARD_OPENCORES_MODULE)
 +
-+	cpus_xor(avail, cpu_possible_map, cpu_present_map);
-+	if (smp_use_sigp_detection)
-+		return smp_rescan_cpus_sigp(avail);
-+	else
-+		return smp_rescan_cpus_sclp(avail);
-+}
++/*
++ * Configuration for one OpenCores keyboard controller in FPGA at address 0x20200030,
++ * interrupt output wired to PF9. Change to suit different FPGA configuration
++ */
 +
-+static void __init smp_detect_cpus(void)
-+{
-+	unsigned int cpu, c_cpus, s_cpus;
-+	struct sclp_cpu_info *info;
-+	u16 boot_cpu_addr, cpu_addr;
++static struct resource opencores_kbd_resources[] = {
++	[0] = {
++		.start	= 0x20200030,
++		.end	= 0x20300030 + 2,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.start	= IRQ_PF9,
++		.end	= IRQ_PF9,
++		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
++	},
++};
 +
-+	c_cpus = 1;
-+	s_cpus = 0;
- 	boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
--	current_thread_info()->cpu = 0;
--	num_cpus = 1;
--	for (cpu = 0; cpu <= 65535; cpu++) {
--		if ((__u16) cpu == boot_cpu_addr)
-+	info = kmalloc(sizeof(*info), GFP_KERNEL);
-+	if (!info)
-+		panic("smp_detect_cpus failed to allocate memory\n");
-+	/* Use sigp detection algorithm if sclp doesn't work. */
-+	if (sclp_get_cpu_info(info)) {
-+		smp_use_sigp_detection = 1;
-+		for (cpu = 0; cpu <= 65535; cpu++) {
-+			if (cpu == boot_cpu_addr)
-+				continue;
-+			__cpu_logical_map[CPU_INIT_NO] = cpu;
-+			if (!cpu_stopped(CPU_INIT_NO))
-+				continue;
-+			smp_get_save_area(c_cpus, cpu);
-+			c_cpus++;
-+		}
-+		goto out;
-+	}
++static struct platform_device opencores_kbd_device = {
++	.id		= -1,
++	.name		= "opencores-kbd",
++	.resource	= opencores_kbd_resources,
++	.num_resources	= ARRAY_SIZE(opencores_kbd_resources),
++};
++#endif
 +
-+	if (info->has_cpu_type) {
-+		for (cpu = 0; cpu < info->combined; cpu++) {
-+			if (info->cpu[cpu].address == boot_cpu_addr) {
-+				smp_cpu_type = info->cpu[cpu].type;
-+				break;
-+			}
-+		}
-+	}
++static struct platform_device *h8606_devices[] __initdata = {
+ #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ 	&rtc_device,
+ #endif
+@@ -327,13 +398,21 @@ static struct platform_device *stamp_devices[] __initdata = {
+ #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ 	&bfin_uart_device,
+ #endif
 +
-+	for (cpu = 0; cpu < info->combined; cpu++) {
-+		if (info->has_cpu_type && info->cpu[cpu].type != smp_cpu_type)
-+			continue;
-+		cpu_addr = info->cpu[cpu].address;
-+		if (cpu_addr == boot_cpu_addr)
- 			continue;
--		__cpu_logical_map[1] = (__u16) cpu;
--		if (signal_processor(1, sigp_sense) == sigp_not_operational)
-+		__cpu_logical_map[CPU_INIT_NO] = cpu_addr;
-+		if (!cpu_stopped(CPU_INIT_NO)) {
-+			s_cpus++;
- 			continue;
--		smp_get_save_area(num_cpus, cpu);
--		num_cpus++;
-+		}
-+		smp_get_save_area(c_cpus, cpu_addr);
-+		c_cpus++;
- 	}
--	printk("Detected %d CPU's\n", (int) num_cpus);
--	printk("Boot cpu address %2X\n", boot_cpu_addr);
--	return num_cpus;
-+out:
-+	kfree(info);
-+	printk(KERN_INFO "CPUs: %d configured, %d standby\n", c_cpus, s_cpus);
-+	get_online_cpus();
-+	smp_rescan_cpus();
-+	put_online_cpus();
- }
- 
- /*
-@@ -453,8 +601,6 @@ int __cpuinit start_secondary(void *cpuvoid)
- 	return 0;
- }
++#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
++	&serial8250_device,
++#endif
++
++#if defined(CONFIG_KEYBOARD_OPENCORES) || defined(CONFIG_KEYBOARD_OPENCORES_MODULE)
++	&opencores_kbd_device,
++#endif
+ };
  
--DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
--
- static void __init smp_create_idle(unsigned int cpu)
+ static int __init H8606_init(void)
  {
- 	struct task_struct *p;
-@@ -470,37 +616,82 @@ static void __init smp_create_idle(unsigned int cpu)
- 	spin_lock_init(&(&per_cpu(s390_idle, cpu))->lock);
- }
+ 	printk(KERN_INFO "HV Sistemas H8606 board support by http://www.hvsistemas.com\n");
+ 	printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+-	platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
++	platform_add_devices(h8606_devices, ARRAY_SIZE(h8606_devices));
+ #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ 	spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+ #endif
+diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c
+index be85203..c37dd45 100644
+--- a/arch/blackfin/mach-bf533/boards/ezkit.c
++++ b/arch/blackfin/mach-bf533/boards/ezkit.c
+@@ -256,6 +256,50 @@ static struct platform_device bfin_pata_device = {
+ };
+ #endif
  
--static int cpu_stopped(int cpu)
-+static int __cpuinit smp_alloc_lowcore(int cpu)
- {
--	__u32 status;
-+	unsigned long async_stack, panic_stack;
-+	struct _lowcore *lowcore;
-+	int lc_order;
++#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
++#include <linux/input.h>
++#include <linux/gpio_keys.h>
 +
-+	lc_order = sizeof(long) == 8 ? 1 : 0;
-+	lowcore = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, lc_order);
-+	if (!lowcore)
-+		return -ENOMEM;
-+	async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER);
-+	if (!async_stack)
-+		goto out_async_stack;
-+	panic_stack = __get_free_page(GFP_KERNEL);
-+	if (!panic_stack)
-+		goto out_panic_stack;
++static struct gpio_keys_button bfin_gpio_keys_table[] = {
++	{BTN_0, GPIO_PF7, 1, "gpio-keys: BTN0"},
++	{BTN_1, GPIO_PF8, 1, "gpio-keys: BTN1"},
++	{BTN_2, GPIO_PF9, 1, "gpio-keys: BTN2"},
++	{BTN_3, GPIO_PF10, 1, "gpio-keys: BTN3"},
++};
 +
-+	*lowcore = S390_lowcore;
-+	lowcore->async_stack = async_stack + ASYNC_SIZE;
-+	lowcore->panic_stack = panic_stack + PAGE_SIZE;
- 
--	/* Check for stopped state */
--	if (signal_processor_ps(&status, 0, cpu, sigp_sense) ==
--	    sigp_status_stored) {
--		if (status & 0x40)
--			return 1;
-+#ifndef CONFIG_64BIT
-+	if (MACHINE_HAS_IEEE) {
-+		unsigned long save_area;
++static struct gpio_keys_platform_data bfin_gpio_keys_data = {
++	.buttons        = bfin_gpio_keys_table,
++	.nbuttons       = ARRAY_SIZE(bfin_gpio_keys_table),
++};
 +
-+		save_area = get_zeroed_page(GFP_KERNEL);
-+		if (!save_area)
-+			goto out_save_area;
-+		lowcore->extended_save_area_addr = (u32) save_area;
- 	}
++static struct platform_device bfin_device_gpiokeys = {
++	.name      = "gpio-keys",
++	.dev = {
++		.platform_data = &bfin_gpio_keys_data,
++	},
++};
 +#endif
-+	lowcore_ptr[cpu] = lowcore;
- 	return 0;
 +
-+#ifndef CONFIG_64BIT
-+out_save_area:
-+	free_page(panic_stack);
++#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
++#include <linux/i2c-gpio.h>
++
++static struct i2c_gpio_platform_data i2c_gpio_data = {
++	.sda_pin		= 1,
++	.scl_pin		= 0,
++	.sda_is_open_drain	= 0,
++	.scl_is_open_drain	= 0,
++	.udelay			= 40,
++};
++
++static struct platform_device i2c_gpio_device = {
++	.name		= "i2c-gpio",
++	.id		= 0,
++	.dev		= {
++		.platform_data	= &i2c_gpio_data,
++	},
++};
 +#endif
-+out_panic_stack:
-+	free_pages(async_stack, ASYNC_ORDER);
-+out_async_stack:
-+	free_pages((unsigned long) lowcore, lc_order);
-+	return -ENOMEM;
- }
- 
--/* Upping and downing of CPUs */
-+#ifdef CONFIG_HOTPLUG_CPU
-+static void smp_free_lowcore(int cpu)
-+{
-+	struct _lowcore *lowcore;
-+	int lc_order;
 +
-+	lc_order = sizeof(long) == 8 ? 1 : 0;
-+	lowcore = lowcore_ptr[cpu];
-+#ifndef CONFIG_64BIT
-+	if (MACHINE_HAS_IEEE)
-+		free_page((unsigned long) lowcore->extended_save_area_addr);
+ static struct platform_device *ezkit_devices[] __initdata = {
+ #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ 	&smc91x_device,
+@@ -280,6 +324,14 @@ static struct platform_device *ezkit_devices[] __initdata = {
+ #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+ 	&bfin_pata_device,
+ #endif
++
++#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
++	&bfin_device_gpiokeys,
 +#endif
-+	free_page(lowcore->panic_stack - PAGE_SIZE);
-+	free_pages(lowcore->async_stack - ASYNC_SIZE, ASYNC_ORDER);
-+	free_pages((unsigned long) lowcore, lc_order);
-+	lowcore_ptr[cpu] = NULL;
-+}
-+#endif /* CONFIG_HOTPLUG_CPU */
++
++#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
++	&i2c_gpio_device,
++#endif
+ };
  
--int __cpu_up(unsigned int cpu)
-+/* Upping and downing of CPUs */
-+int __cpuinit __cpu_up(unsigned int cpu)
- {
- 	struct task_struct *idle;
- 	struct _lowcore *cpu_lowcore;
- 	struct stack_frame *sf;
- 	sigp_ccode ccode;
--	int curr_cpu;
+ static int __init ezkit_init(void)
+diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
+index 8fde8d8..ac52b04 100644
+--- a/arch/blackfin/mach-bf533/boards/stamp.c
++++ b/arch/blackfin/mach-bf533/boards/stamp.c
+@@ -32,6 +32,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
++#include <linux/mtd/physmap.h>
+ #include <linux/spi/spi.h>
+ #include <linux/spi/flash.h>
+ #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+@@ -108,6 +109,50 @@ static struct platform_device net2272_bfin_device = {
+ };
+ #endif
  
--	for (curr_cpu = 0; curr_cpu <= 65535; curr_cpu++) {
--		__cpu_logical_map[cpu] = (__u16) curr_cpu;
--		if (cpu_stopped(cpu))
--			break;
--	}
--
--	if (!cpu_stopped(cpu))
--		return -ENODEV;
-+	if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED)
-+		return -EIO;
-+	if (smp_alloc_lowcore(cpu))
-+		return -ENOMEM;
++static struct mtd_partition stamp_partitions[] = {
++	{
++		.name   = "Bootloader",
++		.size   = 0x20000,
++		.offset = 0,
++	}, {
++		.name   = "Kernel",
++		.size   = 0xE0000,
++		.offset = MTDPART_OFS_APPEND,
++	}, {
++		.name   = "RootFS",
++		.size   = MTDPART_SIZ_FULL,
++		.offset = MTDPART_OFS_APPEND,
++	}
++};
++
++static struct physmap_flash_data stamp_flash_data = {
++	.width    = 2,
++	.parts    = stamp_partitions,
++	.nr_parts = ARRAY_SIZE(stamp_partitions),
++};
++
++static struct resource stamp_flash_resource[] = {
++	{
++		.name  = "cfi_probe",
++		.start = 0x20000000,
++		.end   = 0x203fffff,
++		.flags = IORESOURCE_MEM,
++	}, {
++		.start = CONFIG_ENET_FLASH_PIN,
++		.flags = IORESOURCE_IRQ,
++	}
++};
++
++static struct platform_device stamp_flash_device = {
++	.name          = "BF5xx-Flash",
++	.id            = 0,
++	.dev = {
++		.platform_data = &stamp_flash_data,
++	},
++	.num_resources = ARRAY_SIZE(stamp_flash_resource),
++	.resource      = stamp_flash_resource,
++};
++
+ #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ /* all SPI peripherals info goes here */
  
- 	ccode = signal_processor_p((__u32)(unsigned long)(lowcore_ptr[cpu]),
- 				   cpu, sigp_set_prefix);
-@@ -515,6 +706,7 @@ int __cpu_up(unsigned int cpu)
- 	cpu_lowcore = lowcore_ptr[cpu];
- 	cpu_lowcore->kernel_stack = (unsigned long)
- 		task_stack_page(idle) + THREAD_SIZE;
-+	cpu_lowcore->thread_info = (unsigned long) task_thread_info(idle);
- 	sf = (struct stack_frame *) (cpu_lowcore->kernel_stack
- 				     - sizeof(struct pt_regs)
- 				     - sizeof(struct stack_frame));
-@@ -528,6 +720,8 @@ int __cpu_up(unsigned int cpu)
- 	cpu_lowcore->percpu_offset = __per_cpu_offset[cpu];
- 	cpu_lowcore->current_task = (unsigned long) idle;
- 	cpu_lowcore->cpu_data.cpu_nr = cpu;
-+	cpu_lowcore->softirq_pending = 0;
-+	cpu_lowcore->ext_call_fast = 0;
- 	eieio();
+@@ -373,6 +418,49 @@ static struct platform_device bfin_pata_device = {
+ };
+ #endif
  
- 	while (signal_processor(cpu, sigp_restart) == sigp_busy)
-@@ -538,44 +732,20 @@ int __cpu_up(unsigned int cpu)
- 	return 0;
- }
++#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
++#include <linux/input.h>
++#include <linux/gpio_keys.h>
++
++static struct gpio_keys_button bfin_gpio_keys_table[] = {
++	{BTN_0, GPIO_PF5, 1, "gpio-keys: BTN0"},
++	{BTN_1, GPIO_PF6, 1, "gpio-keys: BTN1"},
++	{BTN_2, GPIO_PF8, 1, "gpio-keys: BTN2"},
++};
++
++static struct gpio_keys_platform_data bfin_gpio_keys_data = {
++	.buttons        = bfin_gpio_keys_table,
++	.nbuttons       = ARRAY_SIZE(bfin_gpio_keys_table),
++};
++
++static struct platform_device bfin_device_gpiokeys = {
++	.name      = "gpio-keys",
++	.dev = {
++		.platform_data = &bfin_gpio_keys_data,
++	},
++};
++#endif
++
++#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
++#include <linux/i2c-gpio.h>
++
++static struct i2c_gpio_platform_data i2c_gpio_data = {
++	.sda_pin		= 2,
++	.scl_pin		= 3,
++	.sda_is_open_drain	= 0,
++	.scl_is_open_drain	= 0,
++	.udelay			= 40,
++};
++
++static struct platform_device i2c_gpio_device = {
++	.name		= "i2c-gpio",
++	.id		= 0,
++	.dev		= {
++		.platform_data	= &i2c_gpio_data,
++	},
++};
++#endif
++
+ static struct platform_device *stamp_devices[] __initdata = {
+ #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ 	&rtc_device,
+@@ -406,6 +494,15 @@ static struct platform_device *stamp_devices[] __initdata = {
+ #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+ 	&bfin_pata_device,
+ #endif
++
++#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
++	&bfin_device_gpiokeys,
++#endif
++
++#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
++	&i2c_gpio_device,
++#endif
++	&stamp_flash_device,
+ };
  
--static unsigned int __initdata additional_cpus;
--static unsigned int __initdata possible_cpus;
--
--void __init smp_setup_cpu_possible_map(void)
-+static int __init setup_possible_cpus(char *s)
- {
--	unsigned int phy_cpus, pos_cpus, cpu;
--
--	phy_cpus = smp_count_cpus();
--	pos_cpus = min(phy_cpus + additional_cpus, (unsigned int) NR_CPUS);
--
--	if (possible_cpus)
--		pos_cpus = min(possible_cpus, (unsigned int) NR_CPUS);
-+	int pcpus, cpu;
+ static int __init stamp_init(void)
+@@ -418,12 +515,10 @@ static int __init stamp_init(void)
+ 		return ret;
  
--	for (cpu = 0; cpu < pos_cpus; cpu++)
-+	pcpus = simple_strtoul(s, NULL, 0);
-+	cpu_possible_map = cpumask_of_cpu(0);
-+	for (cpu = 1; cpu < pcpus && cpu < NR_CPUS; cpu++)
- 		cpu_set(cpu, cpu_possible_map);
--
--	phy_cpus = min(phy_cpus, pos_cpus);
--
--	for (cpu = 0; cpu < phy_cpus; cpu++)
--		cpu_set(cpu, cpu_present_map);
--}
--
--#ifdef CONFIG_HOTPLUG_CPU
--
--static int __init setup_additional_cpus(char *s)
--{
--	additional_cpus = simple_strtoul(s, NULL, 0);
--	return 0;
--}
--early_param("additional_cpus", setup_additional_cpus);
--
--static int __init setup_possible_cpus(char *s)
--{
--	possible_cpus = simple_strtoul(s, NULL, 0);
- 	return 0;
- }
- early_param("possible_cpus", setup_possible_cpus);
+ #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+-# if defined(CONFIG_BFIN_SHARED_FLASH_ENET)
+ 	/* setup BF533_STAMP CPLD to route AMS3 to Ethernet MAC */
+ 	bfin_write_FIO_DIR(bfin_read_FIO_DIR() | (1 << CONFIG_ENET_FLASH_PIN));
+ 	bfin_write_FIO_FLAG_S(1 << CONFIG_ENET_FLASH_PIN);
+ 	SSYNC();
+-# endif
+ #endif
+ 
+ #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+@@ -440,10 +535,8 @@ arch_initcall(stamp_init);
+ 
+ void native_machine_restart(char *cmd)
+ {
+-#if defined(CONFIG_BFIN_SHARED_FLASH_ENET)
+-# define BIT_TO_SET (1 << CONFIG_ENET_FLASH_PIN)
++#define BIT_TO_SET (1 << CONFIG_ENET_FLASH_PIN)
+ 	bfin_write_FIO_INEN(~BIT_TO_SET);
+ 	bfin_write_FIO_DIR(BIT_TO_SET);
+ 	bfin_write_FIO_FLAG_C(BIT_TO_SET);
+-#endif
+ }
+diff --git a/arch/blackfin/mach-bf537/boards/Kconfig b/arch/blackfin/mach-bf537/boards/Kconfig
+index 96a1519..7e789db 100644
+--- a/arch/blackfin/mach-bf537/boards/Kconfig
++++ b/arch/blackfin/mach-bf537/boards/Kconfig
+@@ -21,6 +21,12 @@ config PNAV10
+ 	help
+ 	  PNAV board support.
  
-+#ifdef CONFIG_HOTPLUG_CPU
++config CAMSIG_MINOTAUR
++	bool "Cambridge Signal Processing LTD Minotaur"
++	depends on (BF537)
++	help
++	  Board supply package for CSP Minotaur
 +
- int __cpu_disable(void)
- {
- 	struct ec_creg_mask_parms cr_parms;
-@@ -612,7 +782,8 @@ void __cpu_die(unsigned int cpu)
- 	/* Wait until target cpu is down */
- 	while (!smp_cpu_not_running(cpu))
- 		cpu_relax();
--	printk("Processor %d spun down\n", cpu);
-+	smp_free_lowcore(cpu);
-+	printk(KERN_INFO "Processor %d spun down\n", cpu);
- }
- 
- void cpu_die(void)
-@@ -625,49 +796,19 @@ void cpu_die(void)
+ config GENERIC_BF537_BOARD
+ 	bool "Generic"
+ 	help
+diff --git a/arch/blackfin/mach-bf537/boards/Makefile b/arch/blackfin/mach-bf537/boards/Makefile
+index 94a8517..87e450f 100644
+--- a/arch/blackfin/mach-bf537/boards/Makefile
++++ b/arch/blackfin/mach-bf537/boards/Makefile
+@@ -6,3 +6,4 @@ obj-$(CONFIG_GENERIC_BF537_BOARD)      += generic_board.o
+ obj-$(CONFIG_BFIN537_STAMP)            += stamp.o led.o
+ obj-$(CONFIG_BFIN537_BLUETECHNIX_CM)   += cm_bf537.o
+ obj-$(CONFIG_PNAV10)                   += pnav10.o
++obj-$(CONFIG_CAMSIG_MINOTAUR)          += minotaur.o
+diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537.c b/arch/blackfin/mach-bf537/boards/cm_bf537.c
+index c0fb06d..8703b67 100644
+--- a/arch/blackfin/mach-bf537/boards/cm_bf537.c
++++ b/arch/blackfin/mach-bf537/boards/cm_bf537.c
+@@ -29,6 +29,7 @@
+  */
  
- #endif /* CONFIG_HOTPLUG_CPU */
+ #include <linux/device.h>
++#include <linux/etherdevice.h>
+ #include <linux/platform_device.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
+@@ -216,6 +217,12 @@ static struct platform_device rtc_device = {
+ };
+ #endif
  
--/*
-- *	Cycle through the processors and setup structures.
-- */
--
- void __init smp_prepare_cpus(unsigned int max_cpus)
- {
--	unsigned long stack;
- 	unsigned int cpu;
--	int i;
++#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
++static struct platform_device hitachi_fb_device = {
++	.name = "hitachi-tx09",
++};
++#endif
 +
-+	smp_detect_cpus();
+ #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ static struct resource smc91x_resources[] = {
+ 	{
+@@ -374,6 +381,10 @@ static struct platform_device bfin_pata_device = {
+ #endif
  
- 	/* request the 0x1201 emergency signal external interrupt */
- 	if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0)
- 		panic("Couldn't request external interrupt 0x1201");
- 	memset(lowcore_ptr, 0, sizeof(lowcore_ptr));
--	/*
--	 *  Initialize prefix pages and stacks for all possible cpus
--	 */
- 	print_cpu_info(&S390_lowcore.cpu_data);
-+	smp_alloc_lowcore(smp_processor_id());
+ static struct platform_device *cm_bf537_devices[] __initdata = {
++#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
++	&hitachi_fb_device,
++#endif
++
+ #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ 	&rtc_device,
+ #endif
+diff --git a/arch/blackfin/mach-bf537/boards/generic_board.c b/arch/blackfin/mach-bf537/boards/generic_board.c
+index 09f4bfb..3e52f3f 100644
+--- a/arch/blackfin/mach-bf537/boards/generic_board.c
++++ b/arch/blackfin/mach-bf537/boards/generic_board.c
+@@ -8,7 +8,7 @@
+  *
+  * Modified:
+  *               Copyright 2005 National ICT Australia (NICTA)
+- *               Copyright 2004-2007 Analog Devices Inc.
++ *               Copyright 2004-2008 Analog Devices Inc.
+  *
+  * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+  *
+@@ -29,6 +29,7 @@
+  */
  
--	for_each_possible_cpu(i) {
--		lowcore_ptr[i] = (struct _lowcore *)
--			__get_free_pages(GFP_KERNEL | GFP_DMA,
--					 sizeof(void*) == 8 ? 1 : 0);
--		stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER);
--		if (!lowcore_ptr[i] || !stack)
--			panic("smp_boot_cpus failed to allocate memory\n");
--
--		*(lowcore_ptr[i]) = S390_lowcore;
--		lowcore_ptr[i]->async_stack = stack + ASYNC_SIZE;
--		stack = __get_free_pages(GFP_KERNEL, 0);
--		if (!stack)
--			panic("smp_boot_cpus failed to allocate memory\n");
--		lowcore_ptr[i]->panic_stack = stack + PAGE_SIZE;
--#ifndef CONFIG_64BIT
--		if (MACHINE_HAS_IEEE) {
--			lowcore_ptr[i]->extended_save_area_addr =
--				(__u32) __get_free_pages(GFP_KERNEL, 0);
--			if (!lowcore_ptr[i]->extended_save_area_addr)
--				panic("smp_boot_cpus failed to "
--				      "allocate memory\n");
--		}
--#endif
--	}
- #ifndef CONFIG_64BIT
- 	if (MACHINE_HAS_IEEE)
- 		ctl_set_bit(14, 29); /* enable extended save area */
-@@ -683,15 +824,17 @@ void __init smp_prepare_boot_cpu(void)
- {
- 	BUG_ON(smp_processor_id() != 0);
+ #include <linux/device.h>
++#include <linux/etherdevice.h>
+ #include <linux/platform_device.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
+@@ -204,12 +205,8 @@ static struct resource sl811_hcd_resources[] = {
+ void sl811_port_power(struct device *dev, int is_on)
+ {
+ 	gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
+-	gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS);
++	gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on);
  
-+	current_thread_info()->cpu = 0;
-+	cpu_set(0, cpu_present_map);
- 	cpu_set(0, cpu_online_map);
- 	S390_lowcore.percpu_offset = __per_cpu_offset[0];
- 	current_set[0] = current;
-+	smp_cpu_state[0] = CPU_STATE_CONFIGURED;
- 	spin_lock_init(&(&__get_cpu_var(s390_idle))->lock);
+-	if (is_on)
+-		gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 1);
+-	else
+-		gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 0);
  }
+ #endif
  
- void __init smp_cpus_done(unsigned int max_cpus)
- {
--	cpu_present_map = cpu_possible_map;
+@@ -733,9 +730,11 @@ void native_machine_restart(char *cmd)
+ 		bfin_gpio_reset_spi0_ssel1();
  }
  
- /*
-@@ -705,7 +848,79 @@ int setup_profiling_timer(unsigned int multiplier)
- 	return 0;
++#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+ void bfin_get_ether_addr(char *addr)
+ {
+ 	random_ether_addr(addr);
+ 	printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__);
  }
- 
--static DEFINE_PER_CPU(struct cpu, cpu_devices);
-+#ifdef CONFIG_HOTPLUG_CPU
-+static ssize_t cpu_configure_show(struct sys_device *dev, char *buf)
-+{
-+	ssize_t count;
+ EXPORT_SYMBOL(bfin_get_ether_addr);
++#endif
+diff --git a/arch/blackfin/mach-bf537/boards/minotaur.c b/arch/blackfin/mach-bf537/boards/minotaur.c
+new file mode 100644
+index 0000000..b8bbba8
+--- /dev/null
++++ b/arch/blackfin/mach-bf537/boards/minotaur.c
+@@ -0,0 +1,317 @@
++/*
++ */
 +
-+	mutex_lock(&smp_cpu_state_mutex);
-+	count = sprintf(buf, "%d\n", smp_cpu_state[dev->id]);
-+	mutex_unlock(&smp_cpu_state_mutex);
-+	return count;
-+}
++#include <linux/device.h>
++#include <linux/platform_device.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++#include <linux/spi/spi.h>
++#include <linux/spi/flash.h>
++#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
++#include <linux/usb_isp1362.h>
++#endif
++#include <linux/pata_platform.h>
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/usb_sl811.h>
++#include <asm/dma.h>
++#include <asm/bfin5xx_spi.h>
++#include <asm/reboot.h>
++#include <linux/spi/ad7877.h>
 +
-+static ssize_t cpu_configure_store(struct sys_device *dev, const char *buf,
-+				   size_t count)
-+{
-+	int cpu = dev->id;
-+	int val, rc;
-+	char delim;
++/*
++ * Name the Board for the /proc/cpuinfo
++ */
++char *bfin_board_name = "CamSig Minotaur BF537";
 +
-+	if (sscanf(buf, "%d %c", &val, &delim) != 1)
-+		return -EINVAL;
-+	if (val != 0 && val != 1)
-+		return -EINVAL;
++#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
++static struct resource bfin_pcmcia_cf_resources[] = {
++	{
++		.start = 0x20310000, /* IO PORT */
++		.end = 0x20312000,
++		.flags = IORESOURCE_MEM,
++	}, {
++		.start = 0x20311000, /* Attribute Memory */
++		.end = 0x20311FFF,
++		.flags = IORESOURCE_MEM,
++	}, {
++		.start = IRQ_PF4,
++		.end = IRQ_PF4,
++		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
++	}, {
++		.start = IRQ_PF6, /* Card Detect PF6 */
++		.end = IRQ_PF6,
++		.flags = IORESOURCE_IRQ,
++	},
++};
 +
-+	mutex_lock(&smp_cpu_state_mutex);
-+	get_online_cpus();
-+	rc = -EBUSY;
-+	if (cpu_online(cpu))
-+		goto out;
-+	rc = 0;
-+	switch (val) {
-+	case 0:
-+		if (smp_cpu_state[cpu] == CPU_STATE_CONFIGURED) {
-+			rc = sclp_cpu_deconfigure(__cpu_logical_map[cpu]);
-+			if (!rc)
-+				smp_cpu_state[cpu] = CPU_STATE_STANDBY;
-+		}
-+		break;
-+	case 1:
-+		if (smp_cpu_state[cpu] == CPU_STATE_STANDBY) {
-+			rc = sclp_cpu_configure(__cpu_logical_map[cpu]);
-+			if (!rc)
-+				smp_cpu_state[cpu] = CPU_STATE_CONFIGURED;
-+		}
-+		break;
-+	default:
-+		break;
++static struct platform_device bfin_pcmcia_cf_device = {
++	.name = "bfin_cf_pcmcia",
++	.id = -1,
++	.num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources),
++	.resource = bfin_pcmcia_cf_resources,
++};
++#endif
++
++#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
++static struct platform_device rtc_device = {
++	.name = "rtc-bfin",
++	.id   = -1,
++};
++#endif
++
++#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
++static struct platform_device bfin_mac_device = {
++	.name = "bfin_mac",
++};
++#endif
++
++#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
++static struct resource net2272_bfin_resources[] = {
++	{
++		.start = 0x20300000,
++		.end = 0x20300000 + 0x100,
++		.flags = IORESOURCE_MEM,
++	}, {
++		.start = IRQ_PF7,
++		.end = IRQ_PF7,
++		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
++	},
++};
++
++static struct platform_device net2272_bfin_device = {
++	.name = "net2272",
++	.id = -1,
++	.num_resources = ARRAY_SIZE(net2272_bfin_resources),
++	.resource = net2272_bfin_resources,
++};
++#endif
++
++#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
++/* all SPI peripherals info goes here */
++
++#if defined(CONFIG_MTD_M25P80) \
++	|| defined(CONFIG_MTD_M25P80_MODULE)
++
++/* Partition sizes */
++#define FLASH_SIZE       0x00400000
++#define PSIZE_UBOOT      0x00030000
++#define PSIZE_INITRAMFS  0x00240000
++
++static struct mtd_partition bfin_spi_flash_partitions[] = {
++	{
++		.name       = "uboot",
++		.size       = PSIZE_UBOOT,
++		.offset     = 0x000000,
++		.mask_flags = MTD_CAP_ROM
++	}, {
++		.name       = "initramfs",
++		.size       = PSIZE_INITRAMFS,
++		.offset     = PSIZE_UBOOT
++	}, {
++		.name       = "opt",
++		.size       = FLASH_SIZE - (PSIZE_UBOOT + PSIZE_INITRAMFS),
++		.offset     = PSIZE_UBOOT + PSIZE_INITRAMFS,
 +	}
-+out:
-+	put_online_cpus();
-+	mutex_unlock(&smp_cpu_state_mutex);
-+	return rc ? rc : count;
-+}
-+static SYSDEV_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store);
-+#endif /* CONFIG_HOTPLUG_CPU */
++};
 +
-+static ssize_t show_cpu_address(struct sys_device *dev, char *buf)
-+{
-+	return sprintf(buf, "%d\n", __cpu_logical_map[dev->id]);
-+}
-+static SYSDEV_ATTR(address, 0444, show_cpu_address, NULL);
++static struct flash_platform_data bfin_spi_flash_data = {
++	.name = "m25p80",
++	.parts = bfin_spi_flash_partitions,
++	.nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
++	.type = "m25p64",
++};
 +
++/* SPI flash chip (m25p64) */
++static struct bfin5xx_spi_chip spi_flash_chip_info = {
++	.enable_dma = 0,         /* use dma transfer with this chip*/
++	.bits_per_word = 8,
++};
++#endif
 +
-+static struct attribute *cpu_common_attrs[] = {
-+#ifdef CONFIG_HOTPLUG_CPU
-+	&attr_configure.attr,
++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
++static struct bfin5xx_spi_chip spi_mmc_chip_info = {
++	.enable_dma = 1,
++	.bits_per_word = 8,
++};
++#endif
++
++static struct spi_board_info bfin_spi_board_info[] __initdata = {
++#if defined(CONFIG_MTD_M25P80) \
++	|| defined(CONFIG_MTD_M25P80_MODULE)
++	{
++		/* the modalias must be the same as spi device driver name */
++		.modalias = "m25p80", /* Name of spi_driver for this device */
++		.max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
++		.bus_num = 0, /* Framework bus number */
++		.chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
++		.platform_data = &bfin_spi_flash_data,
++		.controller_data = &spi_flash_chip_info,
++		.mode = SPI_MODE_3,
++	},
++#endif
++
++#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
++	{
++		.modalias = "spi_mmc_dummy",
++		.max_speed_hz = 5000000,     /* max spi clock (SCK) speed in HZ */
++		.bus_num = 0,
++		.chip_select = 0,
++		.platform_data = NULL,
++		.controller_data = &spi_mmc_chip_info,
++		.mode = SPI_MODE_3,
++	},
++	{
++		.modalias = "spi_mmc",
++		.max_speed_hz = 5000000,     /* max spi clock (SCK) speed in HZ */
++		.bus_num = 0,
++		.chip_select = CONFIG_SPI_MMC_CS_CHAN,
++		.platform_data = NULL,
++		.controller_data = &spi_mmc_chip_info,
++		.mode = SPI_MODE_3,
++	},
 +#endif
-+	&attr_address.attr,
-+	NULL,
 +};
 +
-+static struct attribute_group cpu_common_attr_group = {
-+	.attrs = cpu_common_attrs,
++/* SPI controller data */
++static struct bfin5xx_spi_master bfin_spi0_info = {
++	.num_chipselect = 8,
++	.enable_dma = 1,  /* master has the ability to do dma transfer */
 +};
- 
- static ssize_t show_capability(struct sys_device *dev, char *buf)
- {
-@@ -750,15 +965,15 @@ static ssize_t show_idle_time(struct sys_device *dev, char *buf)
- }
- static SYSDEV_ATTR(idle_time_us, 0444, show_idle_time, NULL);
- 
--static struct attribute *cpu_attrs[] = {
-+static struct attribute *cpu_online_attrs[] = {
- 	&attr_capability.attr,
- 	&attr_idle_count.attr,
- 	&attr_idle_time_us.attr,
- 	NULL,
- };
- 
--static struct attribute_group cpu_attr_group = {
--	.attrs = cpu_attrs,
-+static struct attribute_group cpu_online_attr_group = {
-+	.attrs = cpu_online_attrs,
- };
- 
- static int __cpuinit smp_cpu_notify(struct notifier_block *self,
-@@ -778,12 +993,12 @@ static int __cpuinit smp_cpu_notify(struct notifier_block *self,
- 		idle->idle_time = 0;
- 		idle->idle_count = 0;
- 		spin_unlock_irq(&idle->lock);
--		if (sysfs_create_group(&s->kobj, &cpu_attr_group))
-+		if (sysfs_create_group(&s->kobj, &cpu_online_attr_group))
- 			return NOTIFY_BAD;
- 		break;
- 	case CPU_DEAD:
- 	case CPU_DEAD_FROZEN:
--		sysfs_remove_group(&s->kobj, &cpu_attr_group);
-+		sysfs_remove_group(&s->kobj, &cpu_online_attr_group);
- 		break;
- 	}
- 	return NOTIFY_OK;
-@@ -793,6 +1008,62 @@ static struct notifier_block __cpuinitdata smp_cpu_nb = {
- 	.notifier_call = smp_cpu_notify,
- };
- 
-+static int smp_add_present_cpu(int cpu)
-+{
-+	struct cpu *c = &per_cpu(cpu_devices, cpu);
-+	struct sys_device *s = &c->sysdev;
-+	int rc;
 +
-+	c->hotpluggable = 1;
-+	rc = register_cpu(c, cpu);
-+	if (rc)
-+		goto out;
-+	rc = sysfs_create_group(&s->kobj, &cpu_common_attr_group);
-+	if (rc)
-+		goto out_cpu;
-+	if (!cpu_online(cpu))
-+		goto out;
-+	rc = sysfs_create_group(&s->kobj, &cpu_online_attr_group);
-+	if (!rc)
-+		return 0;
-+	sysfs_remove_group(&s->kobj, &cpu_common_attr_group);
-+out_cpu:
-+#ifdef CONFIG_HOTPLUG_CPU
-+	unregister_cpu(c);
++/* SPI (0) */
++static struct resource bfin_spi0_resource[] = {
++	[0] = {
++		.start = SPI0_REGBASE,
++		.end   = SPI0_REGBASE + 0xFF,
++		.flags = IORESOURCE_MEM,
++		},
++	[1] = {
++		.start = CH_SPI,
++		.end   = CH_SPI,
++		.flags = IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device bfin_spi0_device = {
++	.name = "bfin-spi",
++	.id = 0, /* Bus number */
++	.num_resources = ARRAY_SIZE(bfin_spi0_resource),
++	.resource = bfin_spi0_resource,
++	.dev = {
++		.platform_data = &bfin_spi0_info, /* Passed to driver */
++	},
++};
++#endif  /* spi master and devices */
++
++#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
++static struct resource bfin_uart_resources[] = {
++	{
++		.start = 0xFFC00400,
++		.end = 0xFFC004FF,
++		.flags = IORESOURCE_MEM,
++	}, {
++		.start = 0xFFC02000,
++		.end = 0xFFC020FF,
++		.flags = IORESOURCE_MEM,
++	},
++};
++
++static struct platform_device bfin_uart_device = {
++	.name = "bfin-uart",
++	.id = 1,
++	.num_resources = ARRAY_SIZE(bfin_uart_resources),
++	.resource = bfin_uart_resources,
++};
 +#endif
-+out:
-+	return rc;
-+}
 +
-+#ifdef CONFIG_HOTPLUG_CPU
-+static ssize_t rescan_store(struct sys_device *dev, const char *buf,
-+			    size_t count)
-+{
-+	cpumask_t newcpus;
-+	int cpu;
-+	int rc;
++#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
++static struct resource bfin_twi0_resource[] = {
++	[0] = {
++		.start = TWI0_REGBASE,
++		.end   = TWI0_REGBASE + 0xFF,
++		.flags = IORESOURCE_MEM,
++	},
++	[1] = {
++		.start = IRQ_TWI,
++		.end   = IRQ_TWI,
++		.flags = IORESOURCE_IRQ,
++	},
++};
 +
-+	mutex_lock(&smp_cpu_state_mutex);
-+	get_online_cpus();
-+	newcpus = cpu_present_map;
-+	rc = smp_rescan_cpus();
-+	if (rc)
-+		goto out;
-+	cpus_andnot(newcpus, cpu_present_map, newcpus);
-+	for_each_cpu_mask(cpu, newcpus) {
-+		rc = smp_add_present_cpu(cpu);
-+		if (rc)
-+			cpu_clear(cpu, cpu_present_map);
-+	}
-+	rc = 0;
-+out:
-+	put_online_cpus();
-+	mutex_unlock(&smp_cpu_state_mutex);
-+	return rc ? rc : count;
-+}
-+static SYSDEV_ATTR(rescan, 0200, NULL, rescan_store);
-+#endif /* CONFIG_HOTPLUG_CPU */
++static struct platform_device i2c_bfin_twi_device = {
++	.name = "i2c-bfin-twi",
++	.id = 0,
++	.num_resources = ARRAY_SIZE(bfin_twi0_resource),
++	.resource = bfin_twi0_resource,
++};
++#endif
 +
- static int __init topology_init(void)
- {
- 	int cpu;
-@@ -800,16 +1071,14 @@ static int __init topology_init(void)
- 
- 	register_cpu_notifier(&smp_cpu_nb);
- 
--	for_each_possible_cpu(cpu) {
--		struct cpu *c = &per_cpu(cpu_devices, cpu);
--		struct sys_device *s = &c->sysdev;
--
--		c->hotpluggable = 1;
--		register_cpu(c, cpu);
--		if (!cpu_online(cpu))
--			continue;
--		s = &c->sysdev;
--		rc = sysfs_create_group(&s->kobj, &cpu_attr_group);
-+#ifdef CONFIG_HOTPLUG_CPU
-+	rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
-+			       &attr_rescan.attr);
-+	if (rc)
-+		return rc;
++#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
++static struct platform_device bfin_sport0_uart_device = {
++	.name = "bfin-sport-uart",
++	.id = 0,
++};
++
++static struct platform_device bfin_sport1_uart_device = {
++	.name = "bfin-sport-uart",
++	.id = 1,
++};
 +#endif
-+	for_each_present_cpu(cpu) {
-+		rc = smp_add_present_cpu(cpu);
- 		if (rc)
- 			return rc;
- 	}
-diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
-index 22b800c..3bbac12 100644
---- a/arch/s390/kernel/time.c
-+++ b/arch/s390/kernel/time.c
-@@ -1145,7 +1145,7 @@ static void etr_work_fn(struct work_struct *work)
-  * Sysfs interface functions
-  */
- static struct sysdev_class etr_sysclass = {
--	set_kset_name("etr")
-+	.name	= "etr",
- };
- 
- static struct sys_device etr_port0_dev = {
-diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
-index 8ed16a8..52b8342 100644
---- a/arch/s390/kernel/traps.c
-+++ b/arch/s390/kernel/traps.c
-@@ -31,6 +31,7 @@
- #include <linux/reboot.h>
- #include <linux/kprobes.h>
- #include <linux/bug.h>
-+#include <linux/utsname.h>
- #include <asm/system.h>
- #include <asm/uaccess.h>
- #include <asm/io.h>
-@@ -168,9 +169,16 @@ void show_stack(struct task_struct *task, unsigned long *sp)
-  */
- void dump_stack(void)
- {
-+	printk("CPU: %d %s %s %.*s\n",
-+	       task_thread_info(current)->cpu, print_tainted(),
-+	       init_utsname()->release,
-+	       (int)strcspn(init_utsname()->version, " "),
-+	       init_utsname()->version);
-+	printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
-+	       current->comm, current->pid, current,
-+	       (void *) current->thread.ksp);
- 	show_stack(NULL, NULL);
- }
--
- EXPORT_SYMBOL(dump_stack);
- 
- static inline int mask_bits(struct pt_regs *regs, unsigned long bits)
-@@ -258,8 +266,14 @@ void die(const char * str, struct pt_regs * regs, long err)
- 	console_verbose();
- 	spin_lock_irq(&die_lock);
- 	bust_spinlocks(1);
--	printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
--	print_modules();
-+	printk("%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter);
-+#ifdef CONFIG_PREEMPT
-+	printk("PREEMPT ");
++
++static struct platform_device *minotaur_devices[] __initdata = {
++#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
++	&bfin_pcmcia_cf_device,
 +#endif
-+#ifdef CONFIG_SMP
-+	printk("SMP");
++
++#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
++	&rtc_device,
 +#endif
-+	printk("\n");
- 	notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV);
- 	show_regs(regs);
- 	bust_spinlocks(0);
-diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
-index 849120e..9361591 100644
---- a/arch/s390/kernel/vmlinux.lds.S
-+++ b/arch/s390/kernel/vmlinux.lds.S
-@@ -17,6 +17,12 @@ ENTRY(_start)
- jiffies = jiffies_64;
- #endif
- 
-+PHDRS {
-+	text PT_LOAD FLAGS(5);	/* R_E */
-+	data PT_LOAD FLAGS(7);	/* RWE */
-+	note PT_NOTE FLAGS(0);	/* ___ */
++
++#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
++	&bfin_mac_device,
++#endif
++
++#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
++	&net2272_bfin_device,
++#endif
++
++#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
++	&bfin_spi0_device,
++#endif
++
++#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
++	&bfin_uart_device,
++#endif
++
++#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
++	&i2c_bfin_twi_device,
++#endif
++
++#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
++	&bfin_sport0_uart_device,
++	&bfin_sport1_uart_device,
++#endif
++
++};
++
++static int __init minotaur_init(void)
++{
++	printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
++	platform_add_devices(minotaur_devices, ARRAY_SIZE(minotaur_devices));
++#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
++	spi_register_board_info(bfin_spi_board_info,
++				ARRAY_SIZE(bfin_spi_board_info));
++#endif
++
++	return 0;
 +}
 +
- SECTIONS
- {
- 	. = 0x00000000;
-@@ -33,6 +39,9 @@ SECTIONS
- 
- 	_etext = .;		/* End of text section */
- 
-+	NOTES :text :note
-+	BUG_TABLE :text
++arch_initcall(minotaur_init);
 +
- 	RODATA
++void native_machine_restart(char *cmd)
++{
++	/* workaround reboot hang when booting from SPI */
++	if ((bfin_read_SYSCR() & 0x7) == 0x3)
++		bfin_gpio_reset_spi0_ssel1();
++}
+diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c
+index fd5f4a6..509a8a2 100644
+--- a/arch/blackfin/mach-bf537/boards/pnav10.c
++++ b/arch/blackfin/mach-bf537/boards/pnav10.c
+@@ -8,7 +8,7 @@
+  *
+  * Modified:
+  *               Copyright 2005 National ICT Australia (NICTA)
+- *               Copyright 2004-2006 Analog Devices Inc.
++ *               Copyright 2004-2008 Analog Devices Inc.
+  *
+  * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+  *
+@@ -29,6 +29,7 @@
+  */
  
- #ifdef CONFIG_SHARED_KERNEL
-@@ -49,9 +58,6 @@ SECTIONS
- 		__stop___ex_table = .;
- 	}
+ #include <linux/device.h>
++#include <linux/etherdevice.h>
+ #include <linux/platform_device.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
+@@ -133,12 +134,8 @@ static struct resource sl811_hcd_resources[] = {
+ void sl811_port_power(struct device *dev, int is_on)
+ {
+ 	gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
+-	gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS);
++	gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on);
  
--	NOTES
--	BUG_TABLE
--
- 	.data : {		/* Data */
- 		DATA_DATA
- 		CONSTRUCTORS
-diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c
-index 8d76403..e41f400 100644
---- a/arch/s390/lib/spinlock.c
-+++ b/arch/s390/lib/spinlock.c
-@@ -39,7 +39,7 @@ static inline void _raw_yield_cpu(int cpu)
- 		_raw_yield();
+-	if (is_on)
+-		gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 1);
+-	else
+-		gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 0);
  }
+ #endif
  
--void _raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc)
-+void _raw_spin_lock_wait(raw_spinlock_t *lp)
- {
- 	int count = spin_retry;
- 	unsigned int cpu = ~smp_processor_id();
-@@ -53,15 +53,36 @@ void _raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc)
- 		}
- 		if (__raw_spin_is_locked(lp))
- 			continue;
--		if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) {
--			lp->owner_pc = pc;
-+		if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0)
- 			return;
--		}
- 	}
- }
- EXPORT_SYMBOL(_raw_spin_lock_wait);
+diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
+index 07b0dc2..7725415 100644
+--- a/arch/blackfin/mach-bf537/boards/stamp.c
++++ b/arch/blackfin/mach-bf537/boards/stamp.c
+@@ -32,6 +32,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
++#include <linux/mtd/physmap.h>
+ #include <linux/spi/spi.h>
+ #include <linux/spi/flash.h>
+ #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+@@ -103,6 +104,30 @@ void __exit bfin_isp1761_exit(void)
+ arch_initcall(bfin_isp1761_init);
+ #endif
  
--int _raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc)
-+void _raw_spin_lock_wait_flags(raw_spinlock_t *lp, unsigned long flags)
-+{
-+	int count = spin_retry;
-+	unsigned int cpu = ~smp_processor_id();
++#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
++#include <linux/input.h>
++#include <linux/gpio_keys.h>
 +
-+	local_irq_restore(flags);
-+	while (1) {
-+		if (count-- <= 0) {
-+			unsigned int owner = lp->owner_cpu;
-+			if (owner != 0)
-+				_raw_yield_cpu(~owner);
-+			count = spin_retry;
-+		}
-+		if (__raw_spin_is_locked(lp))
-+			continue;
-+		local_irq_disable();
-+		if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0)
-+			return;
-+		local_irq_restore(flags);
-+	}
-+}
-+EXPORT_SYMBOL(_raw_spin_lock_wait_flags);
++static struct gpio_keys_button bfin_gpio_keys_table[] = {
++	{BTN_0, GPIO_PF2, 1, "gpio-keys: BTN0"},
++	{BTN_1, GPIO_PF3, 1, "gpio-keys: BTN1"},
++	{BTN_2, GPIO_PF4, 1, "gpio-keys: BTN2"},
++	{BTN_3, GPIO_PF5, 1, "gpio-keys: BTN3"},
++};
 +
-+int _raw_spin_trylock_retry(raw_spinlock_t *lp)
++static struct gpio_keys_platform_data bfin_gpio_keys_data = {
++	.buttons        = bfin_gpio_keys_table,
++	.nbuttons       = ARRAY_SIZE(bfin_gpio_keys_table),
++};
++
++static struct platform_device bfin_device_gpiokeys = {
++	.name      = "gpio-keys",
++	.dev = {
++		.platform_data = &bfin_gpio_keys_data,
++	},
++};
++#endif
++
+ #if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
+ static struct resource bfin_pcmcia_cf_resources[] = {
+ 	{
+@@ -226,12 +251,7 @@ static struct resource sl811_hcd_resources[] = {
+ void sl811_port_power(struct device *dev, int is_on)
  {
- 	unsigned int cpu = ~smp_processor_id();
- 	int count;
-@@ -69,10 +90,8 @@ int _raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc)
- 	for (count = spin_retry; count > 0; count--) {
- 		if (__raw_spin_is_locked(lp))
- 			continue;
--		if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) {
--			lp->owner_pc = pc;
-+		if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0)
- 			return 1;
--		}
- 	}
- 	return 0;
- }
-diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c
-index 394980b..880b0eb 100644
---- a/arch/s390/mm/extmem.c
-+++ b/arch/s390/mm/extmem.c
-@@ -83,7 +83,7 @@ struct dcss_segment {
- };
- 
- static DEFINE_MUTEX(dcss_lock);
--static struct list_head dcss_list = LIST_HEAD_INIT(dcss_list);
-+static LIST_HEAD(dcss_list);
- static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC",
- 					"EW/EN-MIXED" };
- 
-diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
-index fb9c5a8..79d13a1 100644
---- a/arch/s390/mm/vmem.c
-+++ b/arch/s390/mm/vmem.c
-@@ -15,10 +15,6 @@
- #include <asm/setup.h>
- #include <asm/tlbflush.h>
- 
--unsigned long vmalloc_end;
--EXPORT_SYMBOL(vmalloc_end);
+ 	gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
+-	gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS);
 -
--static struct page *vmem_map;
- static DEFINE_MUTEX(vmem_mutex);
- 
- struct memory_segment {
-@@ -188,8 +184,8 @@ static int vmem_add_mem_map(unsigned long start, unsigned long size)
- 	pte_t  pte;
- 	int ret = -ENOMEM;
- 
--	map_start = vmem_map + PFN_DOWN(start);
--	map_end	= vmem_map + PFN_DOWN(start + size);
-+	map_start = VMEM_MAP + PFN_DOWN(start);
-+	map_end	= VMEM_MAP + PFN_DOWN(start + size);
- 
- 	start_addr = (unsigned long) map_start & PAGE_MASK;
- 	end_addr = PFN_ALIGN((unsigned long) map_end);
-@@ -240,10 +236,10 @@ static int vmem_add_mem(unsigned long start, unsigned long size)
- {
- 	int ret;
- 
--	ret = vmem_add_range(start, size);
-+	ret = vmem_add_mem_map(start, size);
- 	if (ret)
- 		return ret;
--	return vmem_add_mem_map(start, size);
-+	return vmem_add_range(start, size);
+-	if (is_on)
+-		gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 1);
+-	else
+-		gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 0);
++	gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS, is_on);
  }
+ #endif
  
- /*
-@@ -254,7 +250,7 @@ static int insert_memory_segment(struct memory_segment *seg)
- {
- 	struct memory_segment *tmp;
+@@ -320,6 +340,49 @@ static struct platform_device net2272_bfin_device = {
+ };
+ #endif
  
--	if (PFN_DOWN(seg->start + seg->size) > max_pfn ||
-+	if (seg->start + seg->size >= VMALLOC_START ||
- 	    seg->start + seg->size < seg->start)
- 		return -ERANGE;
++static struct mtd_partition stamp_partitions[] = {
++	{
++		.name       = "Bootloader",
++		.size       = 0x20000,
++		.offset     = 0,
++	}, {
++		.name       = "Kernel",
++		.size       = 0xE0000,
++		.offset     = MTDPART_OFS_APPEND,
++	}, {
++		.name       = "RootFS",
++		.size       = 0x400000 - 0x20000 - 0xE0000 - 0x10000,
++		.offset     = MTDPART_OFS_APPEND,
++	}, {
++		.name       = "MAC Address",
++		.size       = MTDPART_SIZ_FULL,
++		.offset     = 0x3F0000,
++		.mask_flags = MTD_WRITEABLE,
++	}
++};
++
++static struct physmap_flash_data stamp_flash_data = {
++	.width      = 2,
++	.parts      = stamp_partitions,
++	.nr_parts   = ARRAY_SIZE(stamp_partitions),
++};
++
++static struct resource stamp_flash_resource = {
++	.start = 0x20000000,
++	.end   = 0x203fffff,
++	.flags = IORESOURCE_MEM,
++};
++
++static struct platform_device stamp_flash_device = {
++	.name          = "physmap-flash",
++	.id            = 0,
++	.dev = {
++		.platform_data = &stamp_flash_data,
++	},
++	.num_resources = 1,
++	.resource      = &stamp_flash_resource,
++};
++
+ #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ /* all SPI peripherals info goes here */
  
-@@ -357,17 +353,15 @@ out:
+@@ -738,6 +801,11 @@ static struct platform_device *stamp_devices[] __initdata = {
+ #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+ 	&bfin_pata_device,
+ #endif
++
++#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
++	&bfin_device_gpiokeys,
++#endif
++	&stamp_flash_device,
+ };
  
- /*
-  * map whole physical memory to virtual memory (identity mapping)
-+ * we reserve enough space in the vmalloc area for vmemmap to hotplug
-+ * additional memory segments.
-  */
- void __init vmem_map_init(void)
- {
--	unsigned long map_size;
- 	int i;
+ static int __init stamp_init(void)
+diff --git a/arch/blackfin/mach-bf548/Kconfig b/arch/blackfin/mach-bf548/Kconfig
+index d8bd3b4..1bfcd8f 100644
+--- a/arch/blackfin/mach-bf548/Kconfig
++++ b/arch/blackfin/mach-bf548/Kconfig
+@@ -7,7 +7,7 @@ menu "BF548 Specific Configuration"
+ config DEB_DMA_URGENT
+ 	bool "DMA has priority over core for ext. accesses"
+ 	depends on BF54x
+-	default n
++	default y
+ 	help
+ 	  Treat any DEB1, DEB2 and DEB3 request as Urgent
  
--	map_size = ALIGN(max_low_pfn, MAX_ORDER_NR_PAGES) * sizeof(struct page);
--	vmalloc_end = PFN_ALIGN(VMALLOC_END_INIT) - PFN_ALIGN(map_size);
--	vmem_map = (struct page *) vmalloc_end;
--	NODE_DATA(0)->node_mem_map = vmem_map;
+diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
+index d37d665..14860f0 100644
+--- a/arch/blackfin/mach-bf548/boards/ezkit.c
++++ b/arch/blackfin/mach-bf548/boards/ezkit.c
+@@ -32,6 +32,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
++#include <linux/mtd/physmap.h>
+ #include <linux/spi/spi.h>
+ #include <linux/spi/flash.h>
+ #include <linux/irq.h>
+@@ -206,23 +207,6 @@ static struct platform_device smsc911x_device = {
+ };
+ #endif
+ 
+-#if defined(CONFIG_USB_BF54x_HCD) || defined(CONFIG_USB_BF54x_HCD_MODULE)
+-static struct resource bf54x_hcd_resources[] = {
+-	{
+-		.start = 0xFFC03C00,
+-		.end = 0xFFC040FF,
+-		.flags = IORESOURCE_MEM,
+-	},
+-};
 -
-+	BUILD_BUG_ON((unsigned long)VMEM_MAP + VMEM_MAP_SIZE > VMEM_MAP_MAX);
-+	NODE_DATA(0)->node_mem_map = VMEM_MAP;
- 	for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++)
- 		vmem_add_mem(memory_chunk[i].addr, memory_chunk[i].size);
- }
-@@ -382,7 +376,7 @@ static int __init vmem_convert_memory_chunk(void)
- 	int i;
+-static struct platform_device bf54x_hcd = {
+-	.name = "bf54x-hcd",
+-	.id = 0,
+-	.num_resources = ARRAY_SIZE(bf54x_hcd_resources),
+-	.resource = bf54x_hcd_resources,
+-};
+-#endif
+-
+ #if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
+ static struct resource musb_resources[] = {
+ 	[0] = {
+@@ -243,14 +227,14 @@ static struct resource musb_resources[] = {
+ };
  
- 	mutex_lock(&vmem_mutex);
--	for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) {
-+	for (i = 0; i < MEMORY_CHUNKS; i++) {
- 		if (!memory_chunk[i].size)
- 			continue;
- 		seg = kzalloc(sizeof(*seg), GFP_KERNEL);
-diff --git a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c
-index eebcd47..51b57c0 100644
---- a/arch/sh/drivers/dma/dma-sysfs.c
-+++ b/arch/sh/drivers/dma/dma-sysfs.c
-@@ -19,7 +19,7 @@
- #include <asm/dma.h>
+ static struct musb_hdrc_platform_data musb_plat = {
+-#ifdef CONFIG_USB_MUSB_OTG
++#if defined(CONFIG_USB_MUSB_OTG)
+ 	.mode		= MUSB_OTG,
+-#elif CONFIG_USB_MUSB_HDRC_HCD
++#elif defined(CONFIG_USB_MUSB_HDRC_HCD)
+ 	.mode		= MUSB_HOST,
+-#elif CONFIG_USB_GADGET_MUSB_HDRC
++#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
+ 	.mode		= MUSB_PERIPHERAL,
+ #endif
+-	.multipoint	= 1,
++	.multipoint	= 0,
+ };
  
- static struct sysdev_class dma_sysclass = {
--	set_kset_name("dma"),
-+	.name = "dma",
+ static u64 musb_dmamask = ~(u32)0;
+@@ -344,6 +328,44 @@ static struct platform_device bf54x_sdh_device = {
  };
- EXPORT_SYMBOL(dma_sysclass);
+ #endif
  
-diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c
-index b22a78c..3008c00 100644
---- a/arch/sh/kernel/cpu/sh4/sq.c
-+++ b/arch/sh/kernel/cpu/sh4/sq.c
-@@ -341,17 +341,18 @@ static int __devinit sq_sysdev_add(struct sys_device *sysdev)
- {
- 	unsigned int cpu = sysdev->id;
- 	struct kobject *kobj;
-+	int error;
++static struct mtd_partition ezkit_partitions[] = {
++	{
++		.name       = "Bootloader",
++		.size       = 0x20000,
++		.offset     = 0,
++	}, {
++		.name       = "Kernel",
++		.size       = 0xE0000,
++		.offset     = MTDPART_OFS_APPEND,
++	}, {
++		.name       = "RootFS",
++		.size       = MTDPART_SIZ_FULL,
++		.offset     = MTDPART_OFS_APPEND,
++	}
++};
++
++static struct physmap_flash_data ezkit_flash_data = {
++	.width      = 2,
++	.parts      = ezkit_partitions,
++	.nr_parts   = ARRAY_SIZE(ezkit_partitions),
++};
++
++static struct resource ezkit_flash_resource = {
++	.start = 0x20000000,
++	.end   = 0x20ffffff,
++	.flags = IORESOURCE_MEM,
++};
++
++static struct platform_device ezkit_flash_device = {
++	.name          = "physmap-flash",
++	.id            = 0,
++	.dev = {
++		.platform_data = &ezkit_flash_data,
++	},
++	.num_resources = 1,
++	.resource      = &ezkit_flash_resource,
++};
++
+ #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ /* all SPI peripherals info goes here */
+ #if defined(CONFIG_MTD_M25P80) \
+@@ -531,6 +553,29 @@ static struct platform_device i2c_bfin_twi1_device = {
+ #endif
+ #endif
  
- 	sq_kobject[cpu] = kzalloc(sizeof(struct kobject), GFP_KERNEL);
- 	if (unlikely(!sq_kobject[cpu]))
- 		return -ENOMEM;
++#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
++#include <linux/gpio_keys.h>
++
++static struct gpio_keys_button bfin_gpio_keys_table[] = {
++	{BTN_0, GPIO_PB8, 1, "gpio-keys: BTN0"},
++	{BTN_1, GPIO_PB9, 1, "gpio-keys: BTN1"},
++	{BTN_2, GPIO_PB10, 1, "gpio-keys: BTN2"},
++	{BTN_3, GPIO_PB11, 1, "gpio-keys: BTN3"},
++};
++
++static struct gpio_keys_platform_data bfin_gpio_keys_data = {
++	.buttons        = bfin_gpio_keys_table,
++	.nbuttons       = ARRAY_SIZE(bfin_gpio_keys_table),
++};
++
++static struct platform_device bfin_device_gpiokeys = {
++	.name      = "gpio-keys",
++	.dev = {
++		.platform_data = &bfin_gpio_keys_data,
++	},
++};
++#endif
++
+ static struct platform_device *ezkit_devices[] __initdata = {
+ #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ 	&rtc_device,
+@@ -548,10 +593,6 @@ static struct platform_device *ezkit_devices[] __initdata = {
+ 	&smsc911x_device,
+ #endif
  
- 	kobj = sq_kobject[cpu];
--	kobj->parent = &sysdev->kobj;
--	kobject_set_name(kobj, "%s", "sq");
--	kobj->ktype = &ktype_percpu_entry;
+-#if defined(CONFIG_USB_BF54x_HCD) || defined(CONFIG_USB_BF54x_HCD_MODULE)
+-	&bf54x_hcd,
+-#endif
 -
--	return kobject_register(kobj);
-+	error = kobject_init_and_add(kobj, &ktype_percpu_entry, &sysdev->kobj,
-+				     "%s", "sq");
-+	if (!error)
-+		kobject_uevent(kobj, KOBJ_ADD);
-+	return error;
- }
+ #if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
+ 	&musb_device,
+ #endif
+@@ -583,6 +624,11 @@ static struct platform_device *ezkit_devices[] __initdata = {
+ 	&i2c_bfin_twi1_device,
+ #endif
+ #endif
++
++#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
++	&bfin_device_gpiokeys,
++#endif
++	&ezkit_flash_device,
+ };
  
- static int __devexit sq_sysdev_remove(struct sys_device *sysdev)
-@@ -359,7 +360,7 @@ static int __devexit sq_sysdev_remove(struct sys_device *sysdev)
- 	unsigned int cpu = sysdev->id;
- 	struct kobject *kobj = sq_kobject[cpu];
+ static int __init stamp_init(void)
+diff --git a/arch/blackfin/mach-bf548/head.S b/arch/blackfin/mach-bf548/head.S
+index 74b34c7..74fe258 100644
+--- a/arch/blackfin/mach-bf548/head.S
++++ b/arch/blackfin/mach-bf548/head.S
+@@ -298,8 +298,8 @@ ENTRY(_start_dma_code)
+ 	w[p0] = r0.l;
+ 	ssync;
  
--	kobject_unregister(kobj);
-+	kobject_put(kobj);
- 	return 0;
- }
+-	p0.h = hi(SIC_IWR);
+-	p0.l = lo(SIC_IWR);
++	p0.h = hi(SIC_IWR0);
++	p0.l = lo(SIC_IWR0);
+ 	r0.l = 0x1;
+ 	r0.h = 0x0;
+ 	[p0] = r0;
+@@ -324,12 +324,25 @@ ENTRY(_start_dma_code)
+ 	w[p0] = r0.l;
+ 	ssync;
  
-diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
-index a3a67d1..2bc04bf 100644
---- a/arch/sh/kernel/time.c
-+++ b/arch/sh/kernel/time.c
-@@ -174,7 +174,7 @@ int timer_resume(struct sys_device *dev)
- #endif
++#if defined(CONFIG_BF54x)
++	P2.H = hi(EBIU_RSTCTL);
++	P2.L = lo(EBIU_RSTCTL);
++	R0 = [P2];
++	BITSET (R0, 3);
++#else
+ 	P2.H = hi(EBIU_SDGCTL);
+ 	P2.L = lo(EBIU_SDGCTL);
+ 	R0 = [P2];
+ 	BITSET (R0, 24);
++#endif
+ 	[P2] = R0;
+ 	SSYNC;
++#if defined(CONFIG_BF54x)
++.LSRR_MODE:
++	R0 = [P2];
++	CC = BITTST(R0, 4);
++	if !CC JUMP .LSRR_MODE;
++#endif
+ 
+ 	r0 = CONFIG_VCO_MULT & 63;       /* Load the VCO multiplier         */
+ 	r0 = r0 << 9;                    /* Shift it over,                  */
+@@ -361,6 +374,39 @@ ENTRY(_start_dma_code)
+ 	w[p0] = r0.l;
+ 	ssync;
+ 
++#if defined(CONFIG_BF54x)
++	P2.H = hi(EBIU_RSTCTL);
++	P2.L = lo(EBIU_RSTCTL);
++	R0 = [P2];
++	CC = BITTST(R0, 0);
++	if CC jump .Lskipddrrst;
++	BITSET (R0, 0);
++.Lskipddrrst:
++	BITCLR (R0, 3);
++	[P2] = R0;
++	SSYNC;
++
++	p0.l = lo(EBIU_DDRCTL0);
++	p0.h = hi(EBIU_DDRCTL0);
++	r0.l = lo(mem_DDRCTL0);
++	r0.h = hi(mem_DDRCTL0);
++	[p0] = r0;
++	ssync;
++
++	p0.l = lo(EBIU_DDRCTL1);
++	p0.h = hi(EBIU_DDRCTL1);
++	r0.l = lo(mem_DDRCTL1);
++	r0.h = hi(mem_DDRCTL1);
++	[p0] = r0;
++	ssync;
++
++	p0.l = lo(EBIU_DDRCTL2);
++	p0.h = hi(EBIU_DDRCTL2);
++	r0.l = lo(mem_DDRCTL2);
++	r0.h = hi(mem_DDRCTL2);
++	[p0] = r0;
++	ssync;
++#else
+ 	p0.l = lo(EBIU_SDRRC);
+ 	p0.h = hi(EBIU_SDRRC);
+ 	r0 = mem_SDRRC;
+@@ -394,9 +440,10 @@ ENTRY(_start_dma_code)
+ 	R1 = R1 | R0;
+ 	[P2] = R1;
+ 	SSYNC;
++#endif
+ 
+-	p0.h = hi(SIC_IWR);
+-	p0.l = lo(SIC_IWR);
++	p0.h = hi(SIC_IWR0);
++	p0.l = lo(SIC_IWR0);
+ 	r0.l = lo(IWR_ENABLE_ALL);
+ 	r0.h = hi(IWR_ENABLE_ALL);
+ 	[p0] = r0;
+diff --git a/arch/blackfin/mach-bf548/ints-priority.c b/arch/blackfin/mach-bf548/ints-priority.c
+index cb0ebac..2665653 100644
+--- a/arch/blackfin/mach-bf548/ints-priority.c
++++ b/arch/blackfin/mach-bf548/ints-priority.c
+@@ -4,7 +4,7 @@
+  * Author:       Michael Hennerich
+  *
+  * Created:
+- * Description:  Set up the interupt priorities
++ * Description:  Set up the interrupt priorities
+  *
+  * Modified:
+  *               Copyright 2004-2006 Analog Devices Inc.
+@@ -58,7 +58,7 @@ void program_IAR(void)
+ 			    ((CONFIG_IRQ_PINT1 - 7) << IRQ_PINT1_POS) |
+ 			    ((CONFIG_IRQ_MDMAS0 - 7) << IRQ_MDMAS0_POS) |
+ 			    ((CONFIG_IRQ_MDMAS1 - 7) << IRQ_MDMAS1_POS) |
+-			    ((CONFIG_IRQ_WATCHDOG - 7) << IRQ_WATCHDOG_POS));
++			    ((CONFIG_IRQ_WATCHDOG - 7) << IRQ_WATCH_POS));
  
- static struct sysdev_class timer_sysclass = {
--	set_kset_name("timer"),
-+	.name	 = "timer",
- 	.suspend = timer_suspend,
- 	.resume	 = timer_resume,
- };
-diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
-index 46bb609..3874c2d 100644
---- a/arch/x86/crypto/Makefile
-+++ b/arch/x86/crypto/Makefile
-@@ -4,12 +4,16 @@
+ 	bfin_write_SIC_IAR3(((CONFIG_IRQ_DMAC1_ERR - 7) << IRQ_DMAC1_ERR_POS) |
+ 			    ((CONFIG_IRQ_SPORT2_ERR - 7) << IRQ_SPORT2_ERR_POS) |
+diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c
+index c19cd29..3a79a90 100644
+--- a/arch/blackfin/mach-bf561/boards/cm_bf561.c
++++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c
+@@ -198,6 +198,13 @@ static struct platform_device bfin_spi0_device = {
+ #endif  /* spi master and devices */
  
- obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o
- obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o
-+obj-$(CONFIG_CRYPTO_SALSA20_586) += salsa20-i586.o
  
- obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o
- obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o
-+obj-$(CONFIG_CRYPTO_SALSA20_X86_64) += salsa20-x86_64.o
++#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
++static struct platform_device hitachi_fb_device = {
++	.name = "hitachi-tx09",
++};
++#endif
++
++
+ #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
  
--aes-i586-y := aes-i586-asm_32.o aes_32.o
--twofish-i586-y := twofish-i586-asm_32.o twofish_32.o
-+aes-i586-y := aes-i586-asm_32.o aes_glue.o
-+twofish-i586-y := twofish-i586-asm_32.o twofish_glue.o
-+salsa20-i586-y := salsa20-i586-asm_32.o salsa20_glue.o
+ static struct resource smc91x_resources[] = {
+@@ -315,6 +322,10 @@ static struct platform_device bfin_pata_device = {
  
--aes-x86_64-y := aes-x86_64-asm_64.o aes_64.o
--twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_64.o
-+aes-x86_64-y := aes-x86_64-asm_64.o aes_glue.o
-+twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_glue.o
-+salsa20-x86_64-y := salsa20-x86_64-asm_64.o salsa20_glue.o
-diff --git a/arch/x86/crypto/aes-i586-asm_32.S b/arch/x86/crypto/aes-i586-asm_32.S
-index f942f0c..1093bed 100644
---- a/arch/x86/crypto/aes-i586-asm_32.S
-+++ b/arch/x86/crypto/aes-i586-asm_32.S
-@@ -46,9 +46,9 @@
- #define in_blk 16
+ static struct platform_device *cm_bf561_devices[] __initdata = {
  
- /* offsets in crypto_tfm structure */
--#define ekey (crypto_tfm_ctx_offset + 0)
--#define nrnd (crypto_tfm_ctx_offset + 256)
--#define dkey (crypto_tfm_ctx_offset + 260)
-+#define klen (crypto_tfm_ctx_offset + 0)
-+#define ekey (crypto_tfm_ctx_offset + 4)
-+#define dkey (crypto_tfm_ctx_offset + 244)
++#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
++	&hitachi_fb_device,
++#endif
++
+ #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ 	&bfin_uart_device,
+ #endif
+diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c
+index 4ff8f6e..7601c3b 100644
+--- a/arch/blackfin/mach-bf561/boards/ezkit.c
++++ b/arch/blackfin/mach-bf561/boards/ezkit.c
+@@ -29,6 +29,9 @@
  
- // register mapping for encrypt and decrypt subroutines
+ #include <linux/device.h>
+ #include <linux/platform_device.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++#include <linux/mtd/physmap.h>
+ #include <linux/spi/spi.h>
+ #include <linux/irq.h>
+ #include <linux/interrupt.h>
+@@ -155,6 +158,44 @@ static struct platform_device bfin_uart_device = {
+ };
+ #endif
  
-@@ -221,8 +221,8 @@
++static struct mtd_partition ezkit_partitions[] = {
++	{
++		.name       = "Bootloader",
++		.size       = 0x20000,
++		.offset     = 0,
++	}, {
++		.name       = "Kernel",
++		.size       = 0xE0000,
++		.offset     = MTDPART_OFS_APPEND,
++	}, {
++		.name       = "RootFS",
++		.size       = MTDPART_SIZ_FULL,
++		.offset     = MTDPART_OFS_APPEND,
++	}
++};
++
++static struct physmap_flash_data ezkit_flash_data = {
++	.width      = 2,
++	.parts      = ezkit_partitions,
++	.nr_parts   = ARRAY_SIZE(ezkit_partitions),
++};
++
++static struct resource ezkit_flash_resource = {
++	.start = 0x20000000,
++	.end   = 0x207fffff,
++	.flags = IORESOURCE_MEM,
++};
++
++static struct platform_device ezkit_flash_device = {
++	.name          = "physmap-flash",
++	.id            = 0,
++	.dev = {
++		.platform_data = &ezkit_flash_data,
++	},
++	.num_resources = 1,
++	.resource      = &ezkit_flash_resource,
++};
++
+ #ifdef CONFIG_SPI_BFIN
+ #if defined(CONFIG_SND_BLACKFIN_AD1836) \
+ 	|| defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+@@ -246,6 +287,50 @@ static struct platform_device bfin_pata_device = {
+ };
+ #endif
  
- .global  aes_enc_blk
++#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
++#include <linux/input.h>
++#include <linux/gpio_keys.h>
++
++static struct gpio_keys_button bfin_gpio_keys_table[] = {
++	{BTN_0, GPIO_PF5, 1, "gpio-keys: BTN0"},
++	{BTN_1, GPIO_PF6, 1, "gpio-keys: BTN1"},
++	{BTN_2, GPIO_PF7, 1, "gpio-keys: BTN2"},
++	{BTN_3, GPIO_PF8, 1, "gpio-keys: BTN3"},
++};
++
++static struct gpio_keys_platform_data bfin_gpio_keys_data = {
++	.buttons        = bfin_gpio_keys_table,
++	.nbuttons       = ARRAY_SIZE(bfin_gpio_keys_table),
++};
++
++static struct platform_device bfin_device_gpiokeys = {
++	.name      = "gpio-keys",
++	.dev = {
++		.platform_data = &bfin_gpio_keys_data,
++	},
++};
++#endif
++
++#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
++#include <linux/i2c-gpio.h>
++
++static struct i2c_gpio_platform_data i2c_gpio_data = {
++	.sda_pin		= 1,
++	.scl_pin		= 0,
++	.sda_is_open_drain	= 0,
++	.scl_is_open_drain	= 0,
++	.udelay			= 40,
++};
++
++static struct platform_device i2c_gpio_device = {
++	.name		= "i2c-gpio",
++	.id		= 0,
++	.dev		= {
++		.platform_data	= &i2c_gpio_data,
++	},
++};
++#endif
++
+ static struct platform_device *ezkit_devices[] __initdata = {
+ #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ 	&smc91x_device,
+@@ -258,12 +343,23 @@ static struct platform_device *ezkit_devices[] __initdata = {
+ #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ 	&bfin_spi0_device,
+ #endif
++
+ #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ 	&bfin_uart_device,
+ #endif
++
+ #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+ 	&bfin_pata_device,
+ #endif
++
++#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
++	&bfin_device_gpiokeys,
++#endif
++
++#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
++	&i2c_gpio_device,
++#endif
++	&ezkit_flash_device,
+ };
  
--.extern  ft_tab
--.extern  fl_tab
-+.extern  crypto_ft_tab
-+.extern  crypto_fl_tab
+ static int __init ezkit_init(void)
+diff --git a/arch/blackfin/mach-bf561/coreb.c b/arch/blackfin/mach-bf561/coreb.c
+index 5d1d21b..1b44e9e 100644
+--- a/arch/blackfin/mach-bf561/coreb.c
++++ b/arch/blackfin/mach-bf561/coreb.c
+@@ -33,7 +33,9 @@
+ #include <linux/ioport.h>
+ #include <linux/module.h>
+ #include <linux/uaccess.h>
++#include <linux/fs.h>
+ #include <asm/dma.h>
++#include <asm/cacheflush.h>
  
- .align 4
+ #define MODULE_VER		"v0.1"
  
-@@ -236,7 +236,7 @@ aes_enc_blk:
- 1:	push    %ebx
- 	mov     in_blk+4(%esp),%r2
- 	push    %esi
--	mov     nrnd(%ebp),%r3   // number of rounds
-+	mov     klen(%ebp),%r3   // key size
- 	push    %edi
- #if ekey != 0
- 	lea     ekey(%ebp),%ebp  // key pointer
-@@ -255,26 +255,26 @@ aes_enc_blk:
+@@ -90,11 +92,12 @@ static ssize_t coreb_write(struct file *file, const char *buf, size_t count,
  
- 	sub     $8,%esp		// space for register saves on stack
- 	add     $16,%ebp	// increment to next round key
--	cmp     $12,%r3
-+	cmp     $24,%r3
- 	jb      4f		// 10 rounds for 128-bit key
- 	lea     32(%ebp),%ebp
- 	je      3f		// 12 rounds for 192-bit key
- 	lea     32(%ebp),%ebp
+ 		coreb_dma_done = 0;
  
--2:	fwd_rnd1( -64(%ebp) ,ft_tab)	// 14 rounds for 256-bit key
--	fwd_rnd2( -48(%ebp) ,ft_tab)
--3:	fwd_rnd1( -32(%ebp) ,ft_tab)	// 12 rounds for 192-bit key
--	fwd_rnd2( -16(%ebp) ,ft_tab)
--4:	fwd_rnd1(    (%ebp) ,ft_tab)	// 10 rounds for 128-bit key
--	fwd_rnd2( +16(%ebp) ,ft_tab)
--	fwd_rnd1( +32(%ebp) ,ft_tab)
--	fwd_rnd2( +48(%ebp) ,ft_tab)
--	fwd_rnd1( +64(%ebp) ,ft_tab)
--	fwd_rnd2( +80(%ebp) ,ft_tab)
--	fwd_rnd1( +96(%ebp) ,ft_tab)
--	fwd_rnd2(+112(%ebp) ,ft_tab)
--	fwd_rnd1(+128(%ebp) ,ft_tab)
--	fwd_rnd2(+144(%ebp) ,fl_tab)	// last round uses a different table
-+2:	fwd_rnd1( -64(%ebp), crypto_ft_tab)	// 14 rounds for 256-bit key
-+	fwd_rnd2( -48(%ebp), crypto_ft_tab)
-+3:	fwd_rnd1( -32(%ebp), crypto_ft_tab)	// 12 rounds for 192-bit key
-+	fwd_rnd2( -16(%ebp), crypto_ft_tab)
-+4:	fwd_rnd1(    (%ebp), crypto_ft_tab)	// 10 rounds for 128-bit key
-+	fwd_rnd2( +16(%ebp), crypto_ft_tab)
-+	fwd_rnd1( +32(%ebp), crypto_ft_tab)
-+	fwd_rnd2( +48(%ebp), crypto_ft_tab)
-+	fwd_rnd1( +64(%ebp), crypto_ft_tab)
-+	fwd_rnd2( +80(%ebp), crypto_ft_tab)
-+	fwd_rnd1( +96(%ebp), crypto_ft_tab)
-+	fwd_rnd2(+112(%ebp), crypto_ft_tab)
-+	fwd_rnd1(+128(%ebp), crypto_ft_tab)
-+	fwd_rnd2(+144(%ebp), crypto_fl_tab)	// last round uses a different table
- 
- // move final values to the output array.  CAUTION: the 
- // order of these assigns rely on the register mappings
-@@ -297,8 +297,8 @@ aes_enc_blk:
- 
- .global  aes_dec_blk
- 
--.extern  it_tab
--.extern  il_tab
-+.extern  crypto_it_tab
-+.extern  crypto_il_tab
- 
- .align 4
- 
-@@ -312,14 +312,11 @@ aes_dec_blk:
- 1:	push    %ebx
- 	mov     in_blk+4(%esp),%r2
- 	push    %esi
--	mov     nrnd(%ebp),%r3   // number of rounds
-+	mov     klen(%ebp),%r3   // key size
- 	push    %edi
- #if dkey != 0
- 	lea     dkey(%ebp),%ebp  // key pointer
- #endif
--	mov     %r3,%r0
--	shl     $4,%r0
--	add     %r0,%ebp
- 	
- // input four columns and xor in first round key
- 
-@@ -333,27 +330,27 @@ aes_dec_blk:
- 	xor     12(%ebp),%r5
- 
- 	sub     $8,%esp		// space for register saves on stack
--	sub     $16,%ebp	// increment to next round key
--	cmp     $12,%r3
-+	add     $16,%ebp	// increment to next round key
-+	cmp     $24,%r3
- 	jb      4f		// 10 rounds for 128-bit key
--	lea     -32(%ebp),%ebp
-+	lea     32(%ebp),%ebp
- 	je      3f		// 12 rounds for 192-bit key
--	lea     -32(%ebp),%ebp
--
--2:	inv_rnd1( +64(%ebp), it_tab)	// 14 rounds for 256-bit key
--	inv_rnd2( +48(%ebp), it_tab)
--3:	inv_rnd1( +32(%ebp), it_tab)	// 12 rounds for 192-bit key
--	inv_rnd2( +16(%ebp), it_tab)
--4:	inv_rnd1(    (%ebp), it_tab)	// 10 rounds for 128-bit key
--	inv_rnd2( -16(%ebp), it_tab)
--	inv_rnd1( -32(%ebp), it_tab)
--	inv_rnd2( -48(%ebp), it_tab)
--	inv_rnd1( -64(%ebp), it_tab)
--	inv_rnd2( -80(%ebp), it_tab)
--	inv_rnd1( -96(%ebp), it_tab)
--	inv_rnd2(-112(%ebp), it_tab)
--	inv_rnd1(-128(%ebp), it_tab)
--	inv_rnd2(-144(%ebp), il_tab)	// last round uses a different table
-+	lea     32(%ebp),%ebp
-+
-+2:	inv_rnd1( -64(%ebp), crypto_it_tab)	// 14 rounds for 256-bit key
-+	inv_rnd2( -48(%ebp), crypto_it_tab)
-+3:	inv_rnd1( -32(%ebp), crypto_it_tab)	// 12 rounds for 192-bit key
-+	inv_rnd2( -16(%ebp), crypto_it_tab)
-+4:	inv_rnd1(    (%ebp), crypto_it_tab)	// 10 rounds for 128-bit key
-+	inv_rnd2( +16(%ebp), crypto_it_tab)
-+	inv_rnd1( +32(%ebp), crypto_it_tab)
-+	inv_rnd2( +48(%ebp), crypto_it_tab)
-+	inv_rnd1( +64(%ebp), crypto_it_tab)
-+	inv_rnd2( +80(%ebp), crypto_it_tab)
-+	inv_rnd1( +96(%ebp), crypto_it_tab)
-+	inv_rnd2(+112(%ebp), crypto_it_tab)
-+	inv_rnd1(+128(%ebp), crypto_it_tab)
-+	inv_rnd2(+144(%ebp), crypto_il_tab)	// last round uses a different table
- 
- // move final values to the output array.  CAUTION: the 
- // order of these assigns rely on the register mappings
-diff --git a/arch/x86/crypto/aes-x86_64-asm_64.S b/arch/x86/crypto/aes-x86_64-asm_64.S
-index 26b40de..a120f52 100644
---- a/arch/x86/crypto/aes-x86_64-asm_64.S
-+++ b/arch/x86/crypto/aes-x86_64-asm_64.S
-@@ -8,10 +8,10 @@
-  * including this sentence is retained in full.
-  */
- 
--.extern aes_ft_tab
--.extern aes_it_tab
--.extern aes_fl_tab
--.extern aes_il_tab
-+.extern crypto_ft_tab
-+.extern crypto_it_tab
-+.extern crypto_fl_tab
-+.extern crypto_il_tab
- 
- .text
- 
-@@ -56,13 +56,13 @@
- 	.align	8;			\
- FUNC:	movq	r1,r2;			\
- 	movq	r3,r4;			\
--	leaq	BASE+KEY+52(r8),r9;	\
-+	leaq	BASE+KEY+48+4(r8),r9;	\
- 	movq	r10,r11;		\
- 	movl	(r7),r5 ## E;		\
- 	movl	4(r7),r1 ## E;		\
- 	movl	8(r7),r6 ## E;		\
- 	movl	12(r7),r7 ## E;		\
--	movl	BASE(r8),r10 ## E;	\
-+	movl	BASE+0(r8),r10 ## E;	\
- 	xorl	-48(r9),r5 ## E;	\
- 	xorl	-44(r9),r1 ## E;	\
- 	xorl	-40(r9),r6 ## E;	\
-@@ -154,37 +154,37 @@ FUNC:	movq	r1,r2;			\
- /* void aes_enc_blk(stuct crypto_tfm *tfm, u8 *out, const u8 *in) */
- 
- 	entry(aes_enc_blk,0,enc128,enc192)
--	encrypt_round(aes_ft_tab,-96)
--	encrypt_round(aes_ft_tab,-80)
--enc192:	encrypt_round(aes_ft_tab,-64)
--	encrypt_round(aes_ft_tab,-48)
--enc128:	encrypt_round(aes_ft_tab,-32)
--	encrypt_round(aes_ft_tab,-16)
--	encrypt_round(aes_ft_tab,  0)
--	encrypt_round(aes_ft_tab, 16)
--	encrypt_round(aes_ft_tab, 32)
--	encrypt_round(aes_ft_tab, 48)
--	encrypt_round(aes_ft_tab, 64)
--	encrypt_round(aes_ft_tab, 80)
--	encrypt_round(aes_ft_tab, 96)
--	encrypt_final(aes_fl_tab,112)
-+	encrypt_round(crypto_ft_tab,-96)
-+	encrypt_round(crypto_ft_tab,-80)
-+enc192:	encrypt_round(crypto_ft_tab,-64)
-+	encrypt_round(crypto_ft_tab,-48)
-+enc128:	encrypt_round(crypto_ft_tab,-32)
-+	encrypt_round(crypto_ft_tab,-16)
-+	encrypt_round(crypto_ft_tab,  0)
-+	encrypt_round(crypto_ft_tab, 16)
-+	encrypt_round(crypto_ft_tab, 32)
-+	encrypt_round(crypto_ft_tab, 48)
-+	encrypt_round(crypto_ft_tab, 64)
-+	encrypt_round(crypto_ft_tab, 80)
-+	encrypt_round(crypto_ft_tab, 96)
-+	encrypt_final(crypto_fl_tab,112)
- 	return
- 
- /* void aes_dec_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in) */
++		flush_dcache_range((unsigned long)buf, (unsigned long)(buf+len));
+ 		/* Source Channel */
+ 		set_dma_start_addr(CH_MEM_STREAM2_SRC, (unsigned long)buf);
+ 		set_dma_x_count(CH_MEM_STREAM2_SRC, len);
+ 		set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char));
+-		set_dma_config(CH_MEM_STREAM2_SRC, RESTART);
++		set_dma_config(CH_MEM_STREAM2_SRC, 0);
+ 		/* Destination Channel */
+ 		set_dma_start_addr(CH_MEM_STREAM2_DEST, coreb_base + p);
+ 		set_dma_x_count(CH_MEM_STREAM2_DEST, len);
+@@ -135,11 +138,12 @@ static ssize_t coreb_read(struct file *file, char *buf, size_t count,
+ 
+ 		coreb_dma_done = 0;
+ 
++		invalidate_dcache_range((unsigned long)buf, (unsigned long)(buf+len));
+ 		/* Source Channel */
+ 		set_dma_start_addr(CH_MEM_STREAM2_SRC, coreb_base + p);
+ 		set_dma_x_count(CH_MEM_STREAM2_SRC, len);
+ 		set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char));
+-		set_dma_config(CH_MEM_STREAM2_SRC, RESTART);
++		set_dma_config(CH_MEM_STREAM2_SRC, 0);
+ 		/* Destination Channel */
+ 		set_dma_start_addr(CH_MEM_STREAM2_DEST, (unsigned long)buf);
+ 		set_dma_x_count(CH_MEM_STREAM2_DEST, len);
+@@ -266,7 +270,7 @@ static int coreb_ioctl(struct inode *inode, struct file *file,
+ 		coreb_status |= COREB_IS_RUNNING;
+ 		bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~0x0020);
+ 		SSYNC();
+-		spin_lock_irq(&coreb_lock);
++		spin_unlock_irq(&coreb_lock);
+ 		break;
+ #if defined(CONFIG_BF561_COREB_RESET)
+ 	case CMD_COREB_STOP:
+@@ -275,7 +279,7 @@ static int coreb_ioctl(struct inode *inode, struct file *file,
+ 		bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() | 0x0020);
+ 		bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080);
+ 		coreb_status &= ~COREB_IS_RUNNING;
+-		spin_lock_irq(&coreb_lock);
++		spin_unlock_irq(&coreb_lock);
+ 		break;
+ 	case CMD_COREB_RESET:
+ 		printk(KERN_INFO "Resetting Core B\n");
+diff --git a/arch/blackfin/mach-common/Makefile b/arch/blackfin/mach-common/Makefile
+index 4d7733d..8636d42 100644
+--- a/arch/blackfin/mach-common/Makefile
++++ b/arch/blackfin/mach-common/Makefile
+@@ -3,10 +3,9 @@
+ #
  
- 	entry(aes_dec_blk,240,dec128,dec192)
--	decrypt_round(aes_it_tab,-96)
--	decrypt_round(aes_it_tab,-80)
--dec192:	decrypt_round(aes_it_tab,-64)
--	decrypt_round(aes_it_tab,-48)
--dec128:	decrypt_round(aes_it_tab,-32)
--	decrypt_round(aes_it_tab,-16)
--	decrypt_round(aes_it_tab,  0)
--	decrypt_round(aes_it_tab, 16)
--	decrypt_round(aes_it_tab, 32)
--	decrypt_round(aes_it_tab, 48)
--	decrypt_round(aes_it_tab, 64)
--	decrypt_round(aes_it_tab, 80)
--	decrypt_round(aes_it_tab, 96)
--	decrypt_final(aes_il_tab,112)
-+	decrypt_round(crypto_it_tab,-96)
-+	decrypt_round(crypto_it_tab,-80)
-+dec192:	decrypt_round(crypto_it_tab,-64)
-+	decrypt_round(crypto_it_tab,-48)
-+dec128:	decrypt_round(crypto_it_tab,-32)
-+	decrypt_round(crypto_it_tab,-16)
-+	decrypt_round(crypto_it_tab,  0)
-+	decrypt_round(crypto_it_tab, 16)
-+	decrypt_round(crypto_it_tab, 32)
-+	decrypt_round(crypto_it_tab, 48)
-+	decrypt_round(crypto_it_tab, 64)
-+	decrypt_round(crypto_it_tab, 80)
-+	decrypt_round(crypto_it_tab, 96)
-+	decrypt_final(crypto_il_tab,112)
- 	return
-diff --git a/arch/x86/crypto/aes_32.c b/arch/x86/crypto/aes_32.c
+ obj-y := \
+-	cache.o cacheinit.o cplbhdlr.o cplbmgr.o entry.o \
++	cache.o cacheinit.o entry.o \
+ 	interrupt.o lock.o irqpanic.o arch_checks.o
+ 
+-obj-$(CONFIG_CPLB_INFO)          += cplbinfo.o
+ obj-$(CONFIG_BFIN_SINGLE_CORE)   += ints-priority-sc.o
+ obj-$(CONFIG_BFIN_DUAL_CORE)     += ints-priority-dc.o
+ obj-$(CONFIG_PM)                 += pm.o dpmc.o
+diff --git a/arch/blackfin/mach-common/cplbhdlr.S b/arch/blackfin/mach-common/cplbhdlr.S
 deleted file mode 100644
-index 49aad93..0000000
---- a/arch/x86/crypto/aes_32.c
+index 2788532..0000000
+--- a/arch/blackfin/mach-common/cplbhdlr.S
 +++ /dev/null
-@@ -1,515 +0,0 @@
--/* 
-- * 
-- * Glue Code for optimized 586 assembler version of AES
-- *
-- * Copyright (c) 2002, Dr Brian Gladman <>, Worcester, UK.
-- * All rights reserved.
-- *
-- * LICENSE TERMS
-- *
-- * The free distribution and use of this software in both source and binary
-- * form is allowed (with or without changes) provided that:
-- *
-- *   1. distributions of this source code include the above copyright
-- *      notice, this list of conditions and the following disclaimer;
-- *
-- *   2. distributions in binary form include the above copyright
-- *      notice, this list of conditions and the following disclaimer
-- *      in the documentation and/or other associated materials;
+@@ -1,130 +0,0 @@
+-/*
+- * File:         arch/blackfin/mach-common/cplbhdlr.S
+- * Based on:
+- * Author:       LG Soft India
 - *
-- *   3. the copyright holder's name is not used to endorse products
-- *      built using this software without specific written permission.
+- * Created:      ?
+- * Description:  CPLB exception handler
 - *
-- * ALTERNATIVELY, provided that this notice is retained in full, this product
-- * may be distributed under the terms of the GNU General Public License (GPL),
-- * in which case the provisions of the GPL apply INSTEAD OF those given above.
+- * Modified:
+- *               Copyright 2004-2006 Analog Devices Inc.
 - *
-- * DISCLAIMER
+- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
 - *
-- * This software is provided 'as is' with no explicit or implied warranties
-- * in respect of its properties, including, but not limited to, correctness
-- * and/or fitness for purpose.
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
 - *
-- * Copyright (c) 2003, Adam J. Richter <adam at yggdrasil.com> (conversion to
-- * 2.5 API).
-- * Copyright (c) 2003, 2004 Fruhwirth Clemens <clemens at endorphin.org>
-- * Copyright (c) 2004 Red Hat, Inc., James Morris <jmorris at redhat.com>
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
 - *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, see the file COPYING, or write
+- * to the Free Software Foundation, Inc.,
+- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 - */
 -
--#include <asm/byteorder.h>
--#include <linux/kernel.h>
--#include <linux/module.h>
--#include <linux/init.h>
--#include <linux/types.h>
--#include <linux/crypto.h>
 -#include <linux/linkage.h>
+-#include <asm/cplb.h>
+-#include <asm/entry.h>
 -
--asmlinkage void aes_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
--asmlinkage void aes_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
--
--#define AES_MIN_KEY_SIZE	16
--#define AES_MAX_KEY_SIZE	32
--#define AES_BLOCK_SIZE		16
--#define AES_KS_LENGTH		4 * AES_BLOCK_SIZE
--#define RC_LENGTH		29
--
--struct aes_ctx {
--	u32 ekey[AES_KS_LENGTH];
--	u32 rounds;
--	u32 dkey[AES_KS_LENGTH];
--};
--
--#define WPOLY 0x011b
--#define bytes2word(b0, b1, b2, b3)  \
--	(((u32)(b3) << 24) | ((u32)(b2) << 16) | ((u32)(b1) << 8) | (b0))
--
--/* define the finite field multiplies required for Rijndael */
--#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
--#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
--#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
--#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
--#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
--#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
--#define fi(x) ((x) ?   pow[255 - log[x]]: 0)
--
--static inline u32 upr(u32 x, int n)
--{
--	return (x << 8 * n) | (x >> (32 - 8 * n));
--}
--
--static inline u8 bval(u32 x, int n)
--{
--	return x >> 8 * n;
--}
--
--/* The forward and inverse affine transformations used in the S-box */
--#define fwd_affine(x) \
--	(w = (u32)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(u8)(w^(w>>8)))
--
--#define inv_affine(x) \
--	(w = (u32)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(u8)(w^(w>>8)))
+-#ifdef CONFIG_EXCPT_IRQ_SYSC_L1
+-.section .l1.text
+-#else
+-.text
+-#endif
 -
--static u32 rcon_tab[RC_LENGTH];
+-.type _cplb_mgr, STT_FUNC;
+-.type _panic_cplb_error, STT_FUNC;
 -
--u32 ft_tab[4][256];
--u32 fl_tab[4][256];
--static u32 im_tab[4][256];
--u32 il_tab[4][256];
--u32 it_tab[4][256];
+-.align 2
 -
--static void gen_tabs(void)
--{
--	u32 i, w;
--	u8 pow[512], log[256];
+-ENTRY(__cplb_hdr)
+-	R2 = SEQSTAT;
+-
+-	/* Mask the contents of SEQSTAT and leave only EXCAUSE in R2 */
+-	R2 <<= 26;
+-	R2 >>= 26;
+-
+-	R1 = 0x23; /* Data access CPLB protection violation */
+-	CC = R2 == R1;
+-	IF !CC JUMP .Lnot_data_write;
+-	R0 = 2;		/* is a write to data space*/
+-	JUMP .Lis_icplb_miss;
+-
+-.Lnot_data_write:
+-	R1 = 0x2C; /* CPLB miss on an instruction fetch */
+-	CC = R2 == R1;
+-	R0 = 0;		/* is_data_miss == False*/
+-	IF CC JUMP .Lis_icplb_miss;
+-
+-	R1 = 0x26;
+-	CC = R2 == R1;
+-	IF !CC JUMP .Lunknown;
+-
+-	R0 = 1;		/* is_data_miss == True*/
+-
+-.Lis_icplb_miss:
+-
+-#if defined(CONFIG_BFIN_ICACHE) || defined(CONFIG_BFIN_DCACHE)
+-# if defined(CONFIG_BFIN_ICACHE) && !defined(CONFIG_BFIN_DCACHE)
+-	R1 = CPLB_ENABLE_ICACHE;
+-# endif
+-# if !defined(CONFIG_BFIN_ICACHE) && defined(CONFIG_BFIN_DCACHE)
+-	R1 = CPLB_ENABLE_DCACHE;
+-# endif
+-# if defined(CONFIG_BFIN_ICACHE) && defined(CONFIG_BFIN_DCACHE)
+-	R1 = CPLB_ENABLE_DCACHE | CPLB_ENABLE_ICACHE;
+-# endif
+-#else
+-	R1 = 0;
+-#endif
 -
--	/*
--	 * log and power tables for GF(2^8) finite field with
--	 * WPOLY as modular polynomial - the simplest primitive
--	 * root is 0x03, used here to generate the tables.
--	 */
--	i = 0; w = 1; 
--	
--	do {
--		pow[i] = (u8)w;
--		pow[i + 255] = (u8)w;
--		log[w] = (u8)i++;
--		w ^=  (w << 1) ^ (w & 0x80 ? WPOLY : 0);
--	} while (w != 1);
--	
--	for(i = 0, w = 1; i < RC_LENGTH; ++i) {
--		rcon_tab[i] = bytes2word(w, 0, 0, 0);
--		w = f2(w);
--	}
+-	[--SP] = RETS;
+-	CALL _cplb_mgr;
+-	RETS = [SP++];
+-	CC = R0 == 0;
+-	IF !CC JUMP .Lnot_replaced;
+-	RTS;
+-
+-/*
+- * Diagnostic exception handlers
+- */
+-.Lunknown:
+-	R0 = CPLB_UNKNOWN_ERR;
+-	JUMP .Lcplb_error;
+-
+-.Lnot_replaced:
+-	CC = R0 == CPLB_NO_UNLOCKED;
+-	IF !CC JUMP .Lnext_check;
+-	R0 = CPLB_NO_UNLOCKED;
+-	JUMP .Lcplb_error;
+-
+-.Lnext_check:
+-	CC = R0 == CPLB_NO_ADDR_MATCH;
+-	IF !CC JUMP .Lnext_check2;
+-	R0 = CPLB_NO_ADDR_MATCH;
+-	JUMP .Lcplb_error;
+-
+-.Lnext_check2:
+-	CC = R0 == CPLB_PROT_VIOL;
+-	IF !CC JUMP .Lstrange_return_from_cplb_mgr;
+-	R0 = CPLB_PROT_VIOL;
+-	JUMP .Lcplb_error;
+-
+-.Lstrange_return_from_cplb_mgr:
+-	IDLE;
+-	CSYNC;
+-	JUMP .Lstrange_return_from_cplb_mgr;
+-
+-.Lcplb_error:
+-	R1 = sp;
+-	SP += -12;
+-	call _panic_cplb_error;
+-	SP += 12;
+-	JUMP _handle_bad_cplb;
 -
--	for(i = 0; i < 256; ++i) {
--		u8 b;
--		
--		b = fwd_affine(fi((u8)i));
--		w = bytes2word(f2(b), b, b, f3(b));
+-ENDPROC(__cplb_hdr)
+diff --git a/arch/blackfin/mach-common/cplbinfo.c b/arch/blackfin/mach-common/cplbinfo.c
+deleted file mode 100644
+index a4f0b42..0000000
+--- a/arch/blackfin/mach-common/cplbinfo.c
++++ /dev/null
+@@ -1,208 +0,0 @@
+-/*
+- * File:         arch/blackfin/mach-common/cplbinfo.c
+- * Based on:
+- * Author:       Sonic Zhang <sonic.zhang at analog.com>
+- *
+- * Created:      Jan. 2005
+- * Description:  Display CPLB status
+- *
+- * Modified:
+- *               Copyright 2004-2006 Analog Devices Inc.
+- *
+- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, see the file COPYING, or write
+- * to the Free Software Foundation, Inc.,
+- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+- */
 -
--		/* tables for a normal encryption round */
--		ft_tab[0][i] = w;
--		ft_tab[1][i] = upr(w, 1);
--		ft_tab[2][i] = upr(w, 2);
--		ft_tab[3][i] = upr(w, 3);
--		w = bytes2word(b, 0, 0, 0);
--		
--		/*
--		 * tables for last encryption round
--		 * (may also be used in the key schedule)
--		 */
--		fl_tab[0][i] = w;
--		fl_tab[1][i] = upr(w, 1);
--		fl_tab[2][i] = upr(w, 2);
--		fl_tab[3][i] = upr(w, 3);
--		
--		b = fi(inv_affine((u8)i));
--		w = bytes2word(fe(b), f9(b), fd(b), fb(b));
+-#include <linux/module.h>
+-#include <linux/kernel.h>
+-#include <linux/init.h>
+-#include <linux/proc_fs.h>
+-#include <linux/uaccess.h>
 -
--		/* tables for the inverse mix column operation  */
--		im_tab[0][b] = w;
--		im_tab[1][b] = upr(w, 1);
--		im_tab[2][b] = upr(w, 2);
--		im_tab[3][b] = upr(w, 3);
+-#include <asm/current.h>
+-#include <asm/system.h>
+-#include <asm/cplb.h>
+-#include <asm/blackfin.h>
 -
--		/* tables for a normal decryption round */
--		it_tab[0][i] = w;
--		it_tab[1][i] = upr(w,1);
--		it_tab[2][i] = upr(w,2);
--		it_tab[3][i] = upr(w,3);
+-#define CPLB_I 1
+-#define CPLB_D 2
 -
--		w = bytes2word(b, 0, 0, 0);
--		
--		/* tables for last decryption round */
--		il_tab[0][i] = w;
--		il_tab[1][i] = upr(w,1);
--		il_tab[2][i] = upr(w,2);
--		il_tab[3][i] = upr(w,3);
--    }
--}
+-#define SYNC_SYS    SSYNC()
+-#define SYNC_CORE   CSYNC()
 -
--#define four_tables(x,tab,vf,rf,c)		\
--(	tab[0][bval(vf(x,0,c),rf(0,c))]	^	\
--	tab[1][bval(vf(x,1,c),rf(1,c))] ^	\
--	tab[2][bval(vf(x,2,c),rf(2,c))] ^	\
--	tab[3][bval(vf(x,3,c),rf(3,c))]		\
--)
+-#define CPLB_BIT_PAGESIZE 0x30000
 -
--#define vf1(x,r,c)  (x)
--#define rf1(r,c)    (r)
--#define rf2(r,c)    ((r-c)&3)
+-static int page_size_table[4] = {
+-	0x00000400,		/* 1K */
+-	0x00001000,		/* 4K */
+-	0x00100000,		/* 1M */
+-	0x00400000		/* 4M */
+-};
 -
--#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
--#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
+-static char page_size_string_table[][4] = { "1K", "4K", "1M", "4M" };
 -
--#define ff(x) inv_mcol(x)
+-static int cplb_find_entry(unsigned long *cplb_addr,
+-			   unsigned long *cplb_data, unsigned long addr,
+-			   unsigned long data)
+-{
+-	int ii;
 -
--#define ke4(k,i)							\
--{									\
--	k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i];		\
--	k[4*(i)+5] = ss[1] ^= ss[0];					\
--	k[4*(i)+6] = ss[2] ^= ss[1];					\
--	k[4*(i)+7] = ss[3] ^= ss[2];					\
--}
+-	for (ii = 0; ii < 16; ii++)
+-		if (addr >= cplb_addr[ii] && addr < cplb_addr[ii] +
+-		    page_size_table[(cplb_data[ii] & CPLB_BIT_PAGESIZE) >> 16]
+-			&& (cplb_data[ii] == data))
+-			return ii;
 -
--#define kel4(k,i)							\
--{									\
--	k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i];		\
--	k[4*(i)+5] = ss[1] ^= ss[0];					\
--	k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2];	\
+-	return -1;
 -}
 -
--#define ke6(k,i)							\
--{									\
--	k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i];		\
--	k[6*(i)+ 7] = ss[1] ^= ss[0];					\
--	k[6*(i)+ 8] = ss[2] ^= ss[1];					\
--	k[6*(i)+ 9] = ss[3] ^= ss[2];					\
--	k[6*(i)+10] = ss[4] ^= ss[3];					\
--	k[6*(i)+11] = ss[5] ^= ss[4];					\
--}
+-static char *cplb_print_entry(char *buf, int type)
+-{
+-	unsigned long *p_addr = dpdt_table;
+-	unsigned long *p_data = dpdt_table + 1;
+-	unsigned long *p_icount = dpdt_swapcount_table;
+-	unsigned long *p_ocount = dpdt_swapcount_table + 1;
+-	unsigned long *cplb_addr = (unsigned long *)DCPLB_ADDR0;
+-	unsigned long *cplb_data = (unsigned long *)DCPLB_DATA0;
+-	int entry = 0, used_cplb = 0;
+-
+-	if (type == CPLB_I) {
+-		buf += sprintf(buf, "Instruction CPLB entry:\n");
+-		p_addr = ipdt_table;
+-		p_data = ipdt_table + 1;
+-		p_icount = ipdt_swapcount_table;
+-		p_ocount = ipdt_swapcount_table + 1;
+-		cplb_addr = (unsigned long *)ICPLB_ADDR0;
+-		cplb_data = (unsigned long *)ICPLB_DATA0;
+-	} else
+-		buf += sprintf(buf, "Data CPLB entry:\n");
 -
--#define kel6(k,i)							\
--{									\
--	k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i];		\
--	k[6*(i)+ 7] = ss[1] ^= ss[0];					\
--	k[6*(i)+ 8] = ss[2] ^= ss[1];					\
--	k[6*(i)+ 9] = ss[3] ^= ss[2];					\
--}
+-	buf += sprintf(buf, "Address\t\tData\tSize\tValid\tLocked\tSwapin\tiCount\toCount\n");
 -
--#define ke8(k,i)							\
--{									\
--	k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i];		\
--	k[8*(i)+ 9] = ss[1] ^= ss[0];					\
--	k[8*(i)+10] = ss[2] ^= ss[1];					\
--	k[8*(i)+11] = ss[3] ^= ss[2];					\
--	k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0);				\
--	k[8*(i)+13] = ss[5] ^= ss[4];					\
--	k[8*(i)+14] = ss[6] ^= ss[5];					\
--	k[8*(i)+15] = ss[7] ^= ss[6];					\
--}
+-	while (*p_addr != 0xffffffff) {
+-		entry = cplb_find_entry(cplb_addr, cplb_data, *p_addr, *p_data);
+-		if (entry >= 0)
+-			used_cplb |= 1 << entry;
+-
+-		buf +=
+-		    sprintf(buf,
+-			    "0x%08lx\t0x%05lx\t%s\t%c\t%c\t%2d\t%ld\t%ld\n",
+-			    *p_addr, *p_data,
+-			    page_size_string_table[(*p_data & 0x30000) >> 16],
+-			    (*p_data & CPLB_VALID) ? 'Y' : 'N',
+-			    (*p_data & CPLB_LOCK) ? 'Y' : 'N', entry, *p_icount,
+-			    *p_ocount);
+-
+-		p_addr += 2;
+-		p_data += 2;
+-		p_icount += 2;
+-		p_ocount += 2;
+-	}
+-
+-	if (used_cplb != 0xffff) {
+-		buf += sprintf(buf, "Unused/mismatched CPLBs:\n");
+-
+-		for (entry = 0; entry < 16; entry++)
+-			if (0 == ((1 << entry) & used_cplb)) {
+-				int flags = cplb_data[entry];
+-				buf +=
+-				    sprintf(buf,
+-					    "%2d: 0x%08lx\t0x%05x\t%s\t%c\t%c\n",
+-					    entry, cplb_addr[entry], flags,
+-					    page_size_string_table[(flags &
+-								    0x30000) >>
+-								   16],
+-					    (flags & CPLB_VALID) ? 'Y' : 'N',
+-					    (flags & CPLB_LOCK) ? 'Y' : 'N');
+-			}
+-	}
 -
--#define kel8(k,i)							\
--{									\
--	k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i];		\
--	k[8*(i)+ 9] = ss[1] ^= ss[0];					\
--	k[8*(i)+10] = ss[2] ^= ss[1];					\
--	k[8*(i)+11] = ss[3] ^= ss[2];					\
--}
+-	buf += sprintf(buf, "\n");
 -
--#define kdf4(k,i)							\
--{									\
--	ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3];				\
--	ss[1] = ss[1] ^ ss[3];						\
--	ss[2] = ss[2] ^ ss[3];						\
--	ss[3] = ss[3];							\
--	ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i];			\
--	ss[i % 4] ^= ss[4];						\
--	ss[4] ^= k[4*(i)];						\
--	k[4*(i)+4] = ff(ss[4]);						\
--	ss[4] ^= k[4*(i)+1];						\
--	k[4*(i)+5] = ff(ss[4]);						\
--	ss[4] ^= k[4*(i)+2];						\
--	k[4*(i)+6] = ff(ss[4]);						\
--	ss[4] ^= k[4*(i)+3];						\
--	k[4*(i)+7] = ff(ss[4]);						\
+-	return buf;
 -}
 -
--#define kd4(k,i)							\
--{									\
--	ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i];			\
--	ss[i % 4] ^= ss[4];						\
--	ss[4] = ff(ss[4]);						\
--	k[4*(i)+4] = ss[4] ^= k[4*(i)];					\
--	k[4*(i)+5] = ss[4] ^= k[4*(i)+1];				\
--	k[4*(i)+6] = ss[4] ^= k[4*(i)+2];				\
--	k[4*(i)+7] = ss[4] ^= k[4*(i)+3];				\
--}
+-static int cplbinfo_proc_output(char *buf)
+-{
+-	char *p;
 -
--#define kdl4(k,i)							\
--{									\
--	ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i];			\
--	ss[i % 4] ^= ss[4];						\
--	k[4*(i)+4] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3];			\
--	k[4*(i)+5] = ss[1] ^ ss[3];					\
--	k[4*(i)+6] = ss[0];						\
--	k[4*(i)+7] = ss[1];						\
--}
+-	p = buf;
 -
--#define kdf6(k,i)							\
--{									\
--	ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i];				\
--	k[6*(i)+ 6] = ff(ss[0]);					\
--	ss[1] ^= ss[0];							\
--	k[6*(i)+ 7] = ff(ss[1]);					\
--	ss[2] ^= ss[1];							\
--	k[6*(i)+ 8] = ff(ss[2]);					\
--	ss[3] ^= ss[2];							\
--	k[6*(i)+ 9] = ff(ss[3]);					\
--	ss[4] ^= ss[3];							\
--	k[6*(i)+10] = ff(ss[4]);					\
--	ss[5] ^= ss[4];							\
--	k[6*(i)+11] = ff(ss[5]);					\
--}
+-	p += sprintf(p, "------------------ CPLB Information ------------------\n\n");
 -
--#define kd6(k,i)							\
--{									\
--	ss[6] = ls_box(ss[5],3) ^ rcon_tab[i];				\
--	ss[0] ^= ss[6]; ss[6] = ff(ss[6]);				\
--	k[6*(i)+ 6] = ss[6] ^= k[6*(i)];				\
--	ss[1] ^= ss[0];							\
--	k[6*(i)+ 7] = ss[6] ^= k[6*(i)+ 1];				\
--	ss[2] ^= ss[1];							\
--	k[6*(i)+ 8] = ss[6] ^= k[6*(i)+ 2];				\
--	ss[3] ^= ss[2];							\
--	k[6*(i)+ 9] = ss[6] ^= k[6*(i)+ 3];				\
--	ss[4] ^= ss[3];							\
--	k[6*(i)+10] = ss[6] ^= k[6*(i)+ 4];				\
--	ss[5] ^= ss[4];							\
--	k[6*(i)+11] = ss[6] ^= k[6*(i)+ 5];				\
--}
+-	if (bfin_read_IMEM_CONTROL() & ENICPLB)
+-		p = cplb_print_entry(p, CPLB_I);
+-	else
+-		p += sprintf(p, "Instruction CPLB is disabled.\n\n");
 -
--#define kdl6(k,i)							\
--{									\
--	ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i];				\
--	k[6*(i)+ 6] = ss[0];						\
--	ss[1] ^= ss[0];							\
--	k[6*(i)+ 7] = ss[1];						\
--	ss[2] ^= ss[1];							\
--	k[6*(i)+ 8] = ss[2];						\
--	ss[3] ^= ss[2];							\
--	k[6*(i)+ 9] = ss[3];						\
--}
+-	if (bfin_read_DMEM_CONTROL() & ENDCPLB)
+-		p = cplb_print_entry(p, CPLB_D);
+-	else
+-		p += sprintf(p, "Data CPLB is disabled.\n");
 -
--#define kdf8(k,i)							\
--{									\
--	ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i];				\
--	k[8*(i)+ 8] = ff(ss[0]);					\
--	ss[1] ^= ss[0];							\
--	k[8*(i)+ 9] = ff(ss[1]);					\
--	ss[2] ^= ss[1];							\
--	k[8*(i)+10] = ff(ss[2]);					\
--	ss[3] ^= ss[2];							\
--	k[8*(i)+11] = ff(ss[3]);					\
--	ss[4] ^= ls_box(ss[3],0);					\
--	k[8*(i)+12] = ff(ss[4]);					\
--	ss[5] ^= ss[4];							\
--	k[8*(i)+13] = ff(ss[5]);					\
--	ss[6] ^= ss[5];							\
--	k[8*(i)+14] = ff(ss[6]);					\
--	ss[7] ^= ss[6];							\
--	k[8*(i)+15] = ff(ss[7]);					\
+-	return p - buf;
 -}
 -
--#define kd8(k,i)							\
--{									\
--	u32 __g = ls_box(ss[7],3) ^ rcon_tab[i];			\
--	ss[0] ^= __g;							\
--	__g = ff(__g);							\
--	k[8*(i)+ 8] = __g ^= k[8*(i)];					\
--	ss[1] ^= ss[0];							\
--	k[8*(i)+ 9] = __g ^= k[8*(i)+ 1];				\
--	ss[2] ^= ss[1];							\
--	k[8*(i)+10] = __g ^= k[8*(i)+ 2];				\
--	ss[3] ^= ss[2];							\
--	k[8*(i)+11] = __g ^= k[8*(i)+ 3];				\
--	__g = ls_box(ss[3],0);						\
--	ss[4] ^= __g;							\
--	__g = ff(__g);							\
--	k[8*(i)+12] = __g ^= k[8*(i)+ 4];				\
--	ss[5] ^= ss[4];							\
--	k[8*(i)+13] = __g ^= k[8*(i)+ 5];				\
--	ss[6] ^= ss[5];							\
--	k[8*(i)+14] = __g ^= k[8*(i)+ 6];				\
--	ss[7] ^= ss[6];							\
--	k[8*(i)+15] = __g ^= k[8*(i)+ 7];				\
--}
+-static int cplbinfo_read_proc(char *page, char **start, off_t off,
+-			      int count, int *eof, void *data)
+-{
+-	int len;
 -
--#define kdl8(k,i)							\
--{									\
--	ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i];				\
--	k[8*(i)+ 8] = ss[0];						\
--	ss[1] ^= ss[0];							\
--	k[8*(i)+ 9] = ss[1];						\
--	ss[2] ^= ss[1];							\
--	k[8*(i)+10] = ss[2];						\
--	ss[3] ^= ss[2];							\
--	k[8*(i)+11] = ss[3];						\
+-	len = cplbinfo_proc_output(page);
+-	if (len <= off + count)
+-		*eof = 1;
+-	*start = page + off;
+-	len -= off;
+-	if (len > count)
+-		len = count;
+-	if (len < 0)
+-		len = 0;
+-	return len;
 -}
 -
--static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
--		       unsigned int key_len)
+-static int cplbinfo_write_proc(struct file *file, const char __user *buffer,
+-			       unsigned long count, void *data)
 -{
--	int i;
--	u32 ss[8];
--	struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
--	const __le32 *key = (const __le32 *)in_key;
--	u32 *flags = &tfm->crt_flags;
--
--	/* encryption schedule */
--	
--	ctx->ekey[0] = ss[0] = le32_to_cpu(key[0]);
--	ctx->ekey[1] = ss[1] = le32_to_cpu(key[1]);
--	ctx->ekey[2] = ss[2] = le32_to_cpu(key[2]);
--	ctx->ekey[3] = ss[3] = le32_to_cpu(key[3]);
--
--	switch(key_len) {
--	case 16:
--		for (i = 0; i < 9; i++)
--			ke4(ctx->ekey, i);
--		kel4(ctx->ekey, 9);
--		ctx->rounds = 10;
--		break;
--		
--	case 24:
--		ctx->ekey[4] = ss[4] = le32_to_cpu(key[4]);
--		ctx->ekey[5] = ss[5] = le32_to_cpu(key[5]);
--		for (i = 0; i < 7; i++)
--			ke6(ctx->ekey, i);
--		kel6(ctx->ekey, 7); 
--		ctx->rounds = 12;
--		break;
--
--	case 32:
--		ctx->ekey[4] = ss[4] = le32_to_cpu(key[4]);
--		ctx->ekey[5] = ss[5] = le32_to_cpu(key[5]);
--		ctx->ekey[6] = ss[6] = le32_to_cpu(key[6]);
--		ctx->ekey[7] = ss[7] = le32_to_cpu(key[7]);
--		for (i = 0; i < 6; i++)
--			ke8(ctx->ekey, i);
--		kel8(ctx->ekey, 6);
--		ctx->rounds = 14;
--		break;
--
--	default:
--		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
--		return -EINVAL;
--	}
--	
--	/* decryption schedule */
--	
--	ctx->dkey[0] = ss[0] = le32_to_cpu(key[0]);
--	ctx->dkey[1] = ss[1] = le32_to_cpu(key[1]);
--	ctx->dkey[2] = ss[2] = le32_to_cpu(key[2]);
--	ctx->dkey[3] = ss[3] = le32_to_cpu(key[3]);
--
--	switch (key_len) {
--	case 16:
--		kdf4(ctx->dkey, 0);
--		for (i = 1; i < 9; i++)
--			kd4(ctx->dkey, i);
--		kdl4(ctx->dkey, 9);
--		break;
--		
--	case 24:
--		ctx->dkey[4] = ff(ss[4] = le32_to_cpu(key[4]));
--		ctx->dkey[5] = ff(ss[5] = le32_to_cpu(key[5]));
--		kdf6(ctx->dkey, 0);
--		for (i = 1; i < 7; i++)
--			kd6(ctx->dkey, i);
--		kdl6(ctx->dkey, 7);
--		break;
+-	printk(KERN_INFO "Reset the CPLB swap in/out counts.\n");
+-	memset(ipdt_swapcount_table, 0, MAX_SWITCH_I_CPLBS * sizeof(unsigned long));
+-	memset(dpdt_swapcount_table, 0, MAX_SWITCH_D_CPLBS * sizeof(unsigned long));
 -
--	case 32:
--		ctx->dkey[4] = ff(ss[4] = le32_to_cpu(key[4]));
--		ctx->dkey[5] = ff(ss[5] = le32_to_cpu(key[5]));
--		ctx->dkey[6] = ff(ss[6] = le32_to_cpu(key[6]));
--		ctx->dkey[7] = ff(ss[7] = le32_to_cpu(key[7]));
--		kdf8(ctx->dkey, 0);
--		for (i = 1; i < 6; i++)
--			kd8(ctx->dkey, i);
--		kdl8(ctx->dkey, 6);
--		break;
--	}
--	return 0;
+-	return count;
 -}
 -
--static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+-static int __init cplbinfo_init(void)
 -{
--	aes_enc_blk(tfm, dst, src);
--}
+-	struct proc_dir_entry *entry;
 -
--static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
--{
--	aes_dec_blk(tfm, dst, src);
--}
+-	entry = create_proc_entry("cplbinfo", 0, NULL);
+-	if (!entry)
+-		return -ENOMEM;
 -
--static struct crypto_alg aes_alg = {
--	.cra_name		=	"aes",
--	.cra_driver_name	=	"aes-i586",
--	.cra_priority		=	200,
--	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
--	.cra_blocksize		=	AES_BLOCK_SIZE,
--	.cra_ctxsize		=	sizeof(struct aes_ctx),
--	.cra_module		=	THIS_MODULE,
--	.cra_list		=	LIST_HEAD_INIT(aes_alg.cra_list),
--	.cra_u			=	{
--		.cipher = {
--			.cia_min_keysize	=	AES_MIN_KEY_SIZE,
--			.cia_max_keysize	=	AES_MAX_KEY_SIZE,
--			.cia_setkey	   	= 	aes_set_key,
--			.cia_encrypt	 	=	aes_encrypt,
--			.cia_decrypt	  	=	aes_decrypt
--		}
--	}
--};
+-	entry->read_proc = cplbinfo_read_proc;
+-	entry->write_proc = cplbinfo_write_proc;
+-	entry->data = NULL;
 -
--static int __init aes_init(void)
--{
--	gen_tabs();
--	return crypto_register_alg(&aes_alg);
+-	return 0;
 -}
 -
--static void __exit aes_fini(void)
+-static void __exit cplbinfo_exit(void)
 -{
--	crypto_unregister_alg(&aes_alg);
+-	remove_proc_entry("cplbinfo", NULL);
 -}
 -
--module_init(aes_init);
--module_exit(aes_fini);
--
--MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm, i586 asm optimized");
--MODULE_LICENSE("Dual BSD/GPL");
--MODULE_AUTHOR("Fruhwirth Clemens, James Morris, Brian Gladman, Adam Richter");
--MODULE_ALIAS("aes");
-diff --git a/arch/x86/crypto/aes_64.c b/arch/x86/crypto/aes_64.c
+-module_init(cplbinfo_init);
+-module_exit(cplbinfo_exit);
+diff --git a/arch/blackfin/mach-common/cplbmgr.S b/arch/blackfin/mach-common/cplbmgr.S
 deleted file mode 100644
-index 5cdb13e..0000000
---- a/arch/x86/crypto/aes_64.c
+index 6f909cb..0000000
+--- a/arch/blackfin/mach-common/cplbmgr.S
 +++ /dev/null
-@@ -1,336 +0,0 @@
+@@ -1,619 +0,0 @@
 -/*
-- * Cryptographic API.
+- * File:         arch/blackfin/mach-common/cplbmgtr.S
+- * Based on:
+- * Author:       LG Soft India
 - *
-- * AES Cipher Algorithm.
+- * Created:      ?
+- * Description:  CPLB replacement routine for CPLB mismatch
 - *
-- * Based on Brian Gladman's code.
+- * Modified:
+- *               Copyright 2004-2006 Analog Devices Inc.
 - *
-- * Linux developers:
-- *  Alexander Kjeldaas <astor at fast.no>
-- *  Herbert Valerio Riedel <hvr at hvrlab.org>
-- *  Kyle McMartin <kyle at debian.org>
-- *  Adam J. Richter <adam at yggdrasil.com> (conversion to 2.5 API).
-- *  Andreas Steinmetz <ast at domdv.de> (adapted to x86_64 assembler)
+- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
 - *
 - * This program is free software; you can redistribute it and/or modify
 - * it under the terms of the GNU General Public License as published by
 - * the Free Software Foundation; either version 2 of the License, or
 - * (at your option) any later version.
 - *
-- * ---------------------------------------------------------------------------
-- * Copyright (c) 2002, Dr Brian Gladman <brg at gladman.me.uk>, Worcester, UK.
-- * All rights reserved.
-- *
-- * LICENSE TERMS
-- *
-- * The free distribution and use of this software in both source and binary
-- * form is allowed (with or without changes) provided that:
-- *
-- *   1. distributions of this source code include the above copyright
-- *      notice, this list of conditions and the following disclaimer;
-- *
-- *   2. distributions in binary form include the above copyright
-- *      notice, this list of conditions and the following disclaimer
-- *      in the documentation and/or other associated materials;
-- *
-- *   3. the copyright holder's name is not used to endorse products
-- *      built using this software without specific written permission.
-- *
-- * ALTERNATIVELY, provided that this notice is retained in full, this product
-- * may be distributed under the terms of the GNU General Public License (GPL),
-- * in which case the provisions of the GPL apply INSTEAD OF those given above.
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
 - *
-- * DISCLAIMER
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, see the file COPYING, or write
+- * to the Free Software Foundation, Inc.,
+- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+- */
+-
+-/* Usage: int _cplb_mgr(is_data_miss,int enable_cache)
+- * is_data_miss==2 => Mark as Dirty, write to the clean data page
+- * is_data_miss==1 => Replace a data CPLB.
+- * is_data_miss==0 => Replace an instruction CPLB.
 - *
-- * This software is provided 'as is' with no explicit or implied warranties
-- * in respect of its properties, including, but not limited to, correctness
-- * and/or fitness for purpose.
-- * ---------------------------------------------------------------------------
+- * Returns:
+- * CPLB_RELOADED	=> Successfully updated CPLB table.
+- * CPLB_NO_UNLOCKED	=> All CPLBs are locked, so cannot be evicted.
+- *			   This indicates that the CPLBs in the configuration
+- *			   tablei are badly configured, as this should never
+- *			   occur.
+- * CPLB_NO_ADDR_MATCH	=> The address being accessed, that triggered the
+- *			   exception, is not covered by any of the CPLBs in
+- *			   the configuration table. The application is
+- *			   presumably misbehaving.
+- * CPLB_PROT_VIOL	=> The address being accessed, that triggered the
+- *			   exception, was not a first-write to a clean Write
+- *			   Back Data page, and so presumably is a genuine
+- *			   violation of the page's protection attributes.
+- *			   The application is misbehaving.
 - */
 -
--/* Some changes from the Gladman version:
--    s/RIJNDAEL(e_key)/E_KEY/g
--    s/RIJNDAEL(d_key)/D_KEY/g
--*/
+-#include <linux/linkage.h>
+-#include <asm/blackfin.h>
+-#include <asm/cplb.h>
 -
--#include <asm/byteorder.h>
--#include <linux/bitops.h>
--#include <linux/crypto.h>
--#include <linux/errno.h>
--#include <linux/init.h>
--#include <linux/module.h>
--#include <linux/types.h>
+-#ifdef CONFIG_EXCPT_IRQ_SYSC_L1
+-.section .l1.text
+-#else
+-.text
+-#endif
 -
--#define AES_MIN_KEY_SIZE	16
--#define AES_MAX_KEY_SIZE	32
+-.align 2;
+-ENTRY(_cplb_mgr)
 -
--#define AES_BLOCK_SIZE		16
+-	[--SP]=( R7:4,P5:3 );
 -
--/*
-- * #define byte(x, nr) ((unsigned char)((x) >> (nr*8)))
-- */
--static inline u8 byte(const u32 x, const unsigned n)
--{
--	return x >> (n << 3);
--}
+-	CC = R0 == 2;
+-	IF CC JUMP .Ldcplb_write;
+-
+-	CC = R0 == 0;
+-	IF !CC JUMP .Ldcplb_miss_compare;
+-
+-	/* ICPLB Miss Exception. We need to choose one of the
+-	* currently-installed CPLBs, and replace it with one
+-	* from the configuration table.
+-	*/
+-
+-	P4.L = LO(ICPLB_FAULT_ADDR);
+-	P4.H = HI(ICPLB_FAULT_ADDR);
+-
+-	P1 = 16;
+-	P5.L = _page_size_table;
+-	P5.H = _page_size_table;
+-
+-	P0.L = LO(ICPLB_DATA0);
+-	P0.H = HI(ICPLB_DATA0);
+-	R4 = [P4];		/* Get faulting address*/
+-	R6 = 64;		/* Advance past the fault address, which*/
+-	R6 = R6 + R4;		/* we'll use if we find a match*/
+-	R3 = ((16 << 8) | 2);	/* Extract mask, bits 16 and 17.*/
+-
+-	R5 = 0;
+-.Lisearch:
+-
+-	R1 = [P0-0x100];	/* Address for this CPLB */
+-
+-	R0 = [P0++];		/* Info for this CPLB*/
+-	CC = BITTST(R0,0);	/* Is the CPLB valid?*/
+-	IF !CC JUMP .Lnomatch;	/* Skip it, if not.*/
+-	CC = R4 < R1(IU);	/* If fault address less than page start*/
+-	IF CC JUMP .Lnomatch;	/* then skip this one.*/
+-	R2 = EXTRACT(R0,R3.L) (Z);	/* Get page size*/
+-	P1 = R2;
+-	P1 = P5 + (P1<<2);	/* index into page-size table*/
+-	R2 = [P1];		/* Get the page size*/
+-	R1 = R1 + R2;		/* and add to page start, to get page end*/
+-	CC = R4 < R1(IU);	/* and see whether fault addr is in page.*/
+-	IF !CC R4 = R6;		/* If so, advance the address and finish loop.*/
+-	IF !CC JUMP .Lisearch_done;
+-.Lnomatch:
+-	/* Go around again*/
+-	R5 += 1;
+-	CC = BITTST(R5, 4);	/* i.e CC = R5 >= 16*/
+-	IF !CC JUMP .Lisearch;
+-
+-.Lisearch_done:
+-	I0 = R4;		/* Fault address we'll search for*/
+-
+-	/* set up pointers */
+-	P0.L = LO(ICPLB_DATA0);
+-	P0.H = HI(ICPLB_DATA0);
+-
+-	/* The replacement procedure for ICPLBs */
+-
+-	P4.L = LO(IMEM_CONTROL);
+-	P4.H = HI(IMEM_CONTROL);
+-
+-	/* disable cplbs */
+-	R5 = [P4];		/* Control Register*/
+-	BITCLR(R5,ENICPLB_P);
+-	CLI R1;
+-	SSYNC;		/* SSYNC required before writing to IMEM_CONTROL. */
+-	.align 8;
+-	[P4] = R5;
+-	SSYNC;
+-	STI R1;
+-
+-	R1 = -1;		/* end point comparison */
+-	R3 = 16;		/* counter */
+-
+-	/* Search through CPLBs for first non-locked entry */
+-	/* Overwrite it by moving everyone else up by 1 */
+-.Licheck_lock:
+-	R0 = [P0++];
+-	R3 = R3 + R1;
+-	CC = R3 == R1;
+-	IF CC JUMP .Lall_locked;
+-	CC = BITTST(R0, 0);		/* an invalid entry is good */
+-	IF !CC JUMP .Lifound_victim;
+-	CC = BITTST(R0,1);		/* but a locked entry isn't */
+-	IF CC JUMP .Licheck_lock;
+-
+-.Lifound_victim:
+-#ifdef CONFIG_CPLB_INFO
+-	R7 = [P0 - 0x104];
+-	P2.L = _ipdt_table;
+-	P2.H = _ipdt_table;
+-	P3.L = _ipdt_swapcount_table;
+-	P3.H = _ipdt_swapcount_table;
+-	P3 += -4;
+-.Licount:
+-	R2 = [P2];	/* address from config table */
+-	P2 += 8;
+-	P3 += 8;
+-	CC = R2==-1;
+-	IF CC JUMP .Licount_done;
+-	CC = R7==R2;
+-	IF !CC JUMP .Licount;
+-	R7 = [P3];
+-	R7 += 1;
+-	[P3] = R7;
+-	CSYNC;
+-.Licount_done:
+-#endif
+-	LC0=R3;
+-	LSETUP(.Lis_move,.Lie_move) LC0;
+-.Lis_move:
+-	R0 = [P0];
+-	[P0 - 4] = R0;
+-	R0 = [P0 - 0x100];
+-	[P0-0x104] = R0;
+-.Lie_move:P0+=4;
+-
+-	/* We've made space in the ICPLB table, so that ICPLB15
+-	 * is now free to be overwritten. Next, we have to determine
+-	 * which CPLB we need to install, from the configuration
+-	 * table. This is a matter of getting the start-of-page
+-	 * addresses and page-lengths from the config table, and
+-	 * determining whether the fault address falls within that
+-	 * range.
+- 	 */
+-
+-	P2.L = _ipdt_table;
+-	P2.H = _ipdt_table;
+-#ifdef	CONFIG_CPLB_INFO
+-	P3.L = _ipdt_swapcount_table;
+-	P3.H = _ipdt_swapcount_table;
+-	P3 += -8;
+-#endif
+-	P0.L = _page_size_table;
+-	P0.H = _page_size_table;
 -
--struct aes_ctx
--{
--	u32 key_length;
--	u32 buf[120];
--};
+-	/* Retrieve our fault address (which may have been advanced
+-	 * because the faulting instruction crossed a page boundary).
+-	 */
 -
--#define E_KEY (&ctx->buf[0])
--#define D_KEY (&ctx->buf[60])
+-	R0 = I0;
 -
--static u8 pow_tab[256] __initdata;
--static u8 log_tab[256] __initdata;
--static u8 sbx_tab[256] __initdata;
--static u8 isb_tab[256] __initdata;
--static u32 rco_tab[10];
--u32 aes_ft_tab[4][256];
--u32 aes_it_tab[4][256];
+-	/* An extraction pattern, to get the page-size bits from
+-	 * the CPLB data entry. Bits 16-17, so two bits at posn 16.
+-	 */
 -
--u32 aes_fl_tab[4][256];
--u32 aes_il_tab[4][256];
+-	R1 = ((16<<8)|2);
+-.Linext:	R4 = [P2++];	/* address from config table */
+-	R2 = [P2++];	/* data from config table */
+-#ifdef	CONFIG_CPLB_INFO
+-	P3 += 8;
+-#endif
 -
--static inline u8 f_mult(u8 a, u8 b)
--{
--	u8 aa = log_tab[a], cc = aa + log_tab[b];
+-	CC = R4 == -1;	/* End of config table*/
+-	IF CC JUMP .Lno_page_in_table;
 -
--	return pow_tab[cc + (cc < aa ? 1 : 0)];
--}
+-	/* See if failed address > start address */
+-	CC = R4 <= R0(IU);
+-	IF !CC JUMP .Linext;
 -
--#define ff_mult(a, b) (a && b ? f_mult(a, b) : 0)
+-	/* extract page size (17:16)*/
+-	R3 = EXTRACT(R2, R1.L) (Z);
 -
--#define ls_box(x)				\
--	(aes_fl_tab[0][byte(x, 0)] ^		\
--	 aes_fl_tab[1][byte(x, 1)] ^		\
--	 aes_fl_tab[2][byte(x, 2)] ^		\
--	 aes_fl_tab[3][byte(x, 3)])
+-	/* add page size to addr to get range */
 -
--static void __init gen_tabs(void)
--{
--	u32 i, t;
--	u8 p, q;
+-	P5 = R3;
+-	P5 = P0 + (P5 << 2);	/* scaled, for int access*/
+-	R3 = [P5];
+-	R3 = R3 + R4;
 -
--	/* log and power tables for GF(2**8) finite field with
--	   0x011b as modular polynomial - the simplest primitive
--	   root is 0x03, used here to generate the tables */
+-	/* See if failed address < (start address + page size) */
+-	CC = R0 < R3(IU);
+-	IF !CC JUMP .Linext;
 -
--	for (i = 0, p = 1; i < 256; ++i) {
--		pow_tab[i] = (u8)p;
--		log_tab[p] = (u8)i;
+-	/* We've found a CPLB in the config table that covers
+-	 * the faulting address, so install this CPLB into the
+-	 * last entry of the table.
+-	 */
 -
--		p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0);
--	}
+-	P1.L = LO(ICPLB_DATA15);		/* ICPLB_DATA15 */
+-	P1.H = HI(ICPLB_DATA15);
+-	[P1] = R2;
+-	[P1-0x100] = R4;
+-#ifdef	CONFIG_CPLB_INFO
+-	R3 = [P3];
+-	R3 += 1;
+-	[P3] = R3;
+-#endif
 -
--	log_tab[1] = 0;
+-	/* P4 points to IMEM_CONTROL, and R5 contains its old
+-	 * value, after we disabled ICPLBS. Re-enable them.
+-	 */
 -
--	for (i = 0, p = 1; i < 10; ++i) {
--		rco_tab[i] = p;
+-	BITSET(R5,ENICPLB_P);
+-	CLI R2;
+-	SSYNC;		/* SSYNC required before writing to IMEM_CONTROL. */
+-	.align 8;
+-	[P4] = R5;
+-	SSYNC;
+-	STI R2;
+-
+-	( R7:4,P5:3 ) = [SP++];
+-	R0 = CPLB_RELOADED;
+-	RTS;
+-
+-/* FAILED CASES*/
+-.Lno_page_in_table:
+-	R0 = CPLB_NO_ADDR_MATCH;
+-	JUMP .Lfail_ret;
+-
+-.Lall_locked:
+-	R0 = CPLB_NO_UNLOCKED;
+-	JUMP .Lfail_ret;
+-
+-.Lprot_violation:
+-	R0 = CPLB_PROT_VIOL;
+-
+-.Lfail_ret:
+-	/* Make sure we turn protection/cache back on, even in the failing case */
+-	BITSET(R5,ENICPLB_P);
+-	CLI R2;
+-	SSYNC;          /* SSYNC required before writing to IMEM_CONTROL. */
+-	.align 8;
+-	[P4] = R5;
+-	SSYNC;
+-	STI R2;
+-
+-	( R7:4,P5:3 ) = [SP++];
+-	RTS;
+-
+-.Ldcplb_write:
+-
+-	/* if a DCPLB is marked as write-back (CPLB_WT==0), and
+-	 * it is clean (CPLB_DIRTY==0), then a write to the
+-	 * CPLB's page triggers a protection violation. We have to
+-	 * mark the CPLB as dirty, to indicate that there are
+-	 * pending writes associated with the CPLB.
+-	 */
 -
--		p = (p << 1) ^ (p & 0x80 ? 0x01b : 0);
--	}
+-	P4.L = LO(DCPLB_STATUS);
+-	P4.H = HI(DCPLB_STATUS);
+-	P3.L = LO(DCPLB_DATA0);
+-	P3.H = HI(DCPLB_DATA0);
+-	R5 = [P4];
+-
+-	/* A protection violation can be caused by more than just writes
+-	 * to a clean WB page, so we have to ensure that:
+-	 * - It's a write
+-	 * - to a clean WB page
+-	 * - and is allowed in the mode the access occurred.
+-	 */
 -
--	for (i = 0; i < 256; ++i) {
--		p = (i ? pow_tab[255 - log_tab[i]] : 0);
--		q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2));
--		p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2));
--		sbx_tab[i] = p;
--		isb_tab[p] = (u8)i;
--	}
+-	CC = BITTST(R5, 16);	/* ensure it was a write*/
+-	IF !CC JUMP .Lprot_violation;
 -
--	for (i = 0; i < 256; ++i) {
--		p = sbx_tab[i];
+-	/* to check the rest, we have to retrieve the DCPLB.*/
 -
--		t = p;
--		aes_fl_tab[0][i] = t;
--		aes_fl_tab[1][i] = rol32(t, 8);
--		aes_fl_tab[2][i] = rol32(t, 16);
--		aes_fl_tab[3][i] = rol32(t, 24);
+-	/* The low half of DCPLB_STATUS is a bit mask*/
 -
--		t = ((u32)ff_mult(2, p)) |
--		    ((u32)p << 8) |
--		    ((u32)p << 16) | ((u32)ff_mult(3, p) << 24);
+-	R2 = R5.L (Z);	/* indicating which CPLB triggered the event.*/
+-	R3 = 30;	/* so we can use this to determine the offset*/
+-	R2.L = SIGNBITS R2;
+-	R2 = R2.L (Z);	/* into the DCPLB table.*/
+-	R3 = R3 - R2;
+-	P4 = R3;
+-	P3 = P3 + (P4<<2);
+-	R3 = [P3];	/* Retrieve the CPLB*/
+-
+-	/* Now we can check whether it's a clean WB page*/
+-
+-	CC = BITTST(R3, 14);	/* 0==WB, 1==WT*/
+-	IF CC JUMP .Lprot_violation;
+-	CC = BITTST(R3, 7);	/* 0 == clean, 1 == dirty*/
+-	IF CC JUMP .Lprot_violation;
+-
+-	/* Check whether the write is allowed in the mode that was active.*/
+-
+-	R2 = 1<<3;		/* checking write in user mode*/
+-	CC = BITTST(R5, 17);	/* 0==was user, 1==was super*/
+-	R5 = CC;
+-	R2 <<= R5;		/* if was super, check write in super mode*/
+-	R2 = R3 & R2;
+-	CC = R2 == 0;
+-	IF CC JUMP .Lprot_violation;
+-
+-	/* It's a genuine write-to-clean-page.*/
+-
+-	BITSET(R3, 7);		/* mark as dirty*/
+-	[P3] = R3;		/* and write back.*/
+-	NOP;
+-	CSYNC;
+-	( R7:4,P5:3 ) = [SP++];
+-	R0 = CPLB_RELOADED;
+-	RTS;
+-
+-.Ldcplb_miss_compare:
+-
+-	/* Data CPLB Miss event. We need to choose a CPLB to
+-	 * evict, and then locate a new CPLB to install from the
+-	 * config table, that covers the faulting address.
+-	 */
 -
--		aes_ft_tab[0][i] = t;
--		aes_ft_tab[1][i] = rol32(t, 8);
--		aes_ft_tab[2][i] = rol32(t, 16);
--		aes_ft_tab[3][i] = rol32(t, 24);
+-	P1.L = LO(DCPLB_DATA15);
+-	P1.H = HI(DCPLB_DATA15);
 -
--		p = isb_tab[i];
+-	P4.L = LO(DCPLB_FAULT_ADDR);
+-	P4.H = HI(DCPLB_FAULT_ADDR);
+-	R4 = [P4];
+-	I0 = R4;
+-
+-	/* The replacement procedure for DCPLBs*/
+-
+-	R6 = R1;	/* Save for later*/
+-
+-	/* Turn off CPLBs while we work.*/
+-	P4.L = LO(DMEM_CONTROL);
+-	P4.H = HI(DMEM_CONTROL);
+-	R5 = [P4];
+-	BITCLR(R5,ENDCPLB_P);
+-	CLI R0;
+-	SSYNC;		/* SSYNC required before writing to DMEM_CONTROL. */
+-	.align 8;
+-	[P4] = R5;
+-	SSYNC;
+-	STI R0;
+-
+-	/* Start looking for a CPLB to evict. Our order of preference
+-	 * is: invalid CPLBs, clean CPLBs, dirty CPLBs. Locked CPLBs
+-	 * are no good.
+-	 */
 -
--		t = p;
--		aes_il_tab[0][i] = t;
--		aes_il_tab[1][i] = rol32(t, 8);
--		aes_il_tab[2][i] = rol32(t, 16);
--		aes_il_tab[3][i] = rol32(t, 24);
+-	I1.L = LO(DCPLB_DATA0);
+-	I1.H = HI(DCPLB_DATA0);
+-	P1 = 2;
+-	P2 = 16;
+-	I2.L = _dcplb_preference;
+-	I2.H = _dcplb_preference;
+-	LSETUP(.Lsdsearch1, .Ledsearch1) LC0 = P1;
+-.Lsdsearch1:
+-	R0 = [I2++];		/* Get the bits we're interested in*/
+-	P0 = I1;		/* Go back to start of table*/
+-	LSETUP (.Lsdsearch2, .Ledsearch2) LC1 = P2;
+-.Lsdsearch2:
+-	R1 = [P0++];		/* Fetch each installed CPLB in turn*/
+-	R2 = R1 & R0;		/* and test for interesting bits.*/
+-	CC = R2 == 0;		/* If none are set, it'll do.*/
+-	IF !CC JUMP .Lskip_stack_check;
+-
+-	R2 = [P0 - 0x104]; 	/* R2 - PageStart */
+-	P3.L = _page_size_table; /* retrieve end address */
+-	P3.H = _page_size_table; /* retrieve end address */
+-	R3 = 0x1002;		/* 16th - position, 2 bits -length */
+-#if ANOMALY_05000209
+-	nop;			/* Anomaly 05000209 */
+-#endif
+-	R7 = EXTRACT(R1,R3.l);
+-	R7 = R7 << 2;		/* Page size index offset */
+-	P5 = R7;
+-	P3 = P3 + P5;
+-	R7 = [P3];		/* page size in bytes */
+-
+-	R7 = R2 + R7;		/* R7 - PageEnd */
+-	R4 = SP; 		/* Test SP is in range */
+-
+-	CC = R7 < R4;		/* if PageEnd < SP */
+-	IF CC JUMP .Ldfound_victim;
+-	R3 = 0x284;		/* stack length from start of trap till
+-				 * the point.
+-				 * 20 stack locations for future modifications
+-				 */
+-	R4 = R4 + R3;
+-	CC = R4 < R2;		/* if SP + stacklen < PageStart */
+-	IF CC JUMP .Ldfound_victim;
+-.Lskip_stack_check:
 -
--		t = ((u32)ff_mult(14, p)) |
--		    ((u32)ff_mult(9, p) << 8) |
--		    ((u32)ff_mult(13, p) << 16) |
--		    ((u32)ff_mult(11, p) << 24);
+-.Ledsearch2: NOP;
+-.Ledsearch1: NOP;
 -
--		aes_it_tab[0][i] = t;
--		aes_it_tab[1][i] = rol32(t, 8);
--		aes_it_tab[2][i] = rol32(t, 16);
--		aes_it_tab[3][i] = rol32(t, 24);
--	}
--}
+-	/* If we got here, we didn't find a DCPLB we considered
+-	 * replacable, which means all of them were locked.
+-	 */
 -
--#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
+-	JUMP .Lall_locked;
+-.Ldfound_victim:
 -
--#define imix_col(y, x)			\
--	u    = star_x(x);		\
--	v    = star_x(u);		\
--	w    = star_x(v);		\
--	t    = w ^ (x);			\
--	(y)  = u ^ v ^ w;		\
--	(y) ^= ror32(u ^ t,  8) ^	\
--	       ror32(v ^ t, 16) ^	\
--	       ror32(t, 24)
+-#ifdef CONFIG_CPLB_INFO
+-	R7 = [P0 - 0x104];
+-	P2.L = _dpdt_table;
+-	P2.H = _dpdt_table;
+-	P3.L = _dpdt_swapcount_table;
+-	P3.H = _dpdt_swapcount_table;
+-	P3 += -4;
+-.Ldicount:
+-	R2 = [P2];
+-	P2 += 8;
+-	P3 += 8;
+-	CC = R2==-1;
+-	IF CC JUMP .Ldicount_done;
+-	CC = R7==R2;
+-	IF !CC JUMP .Ldicount;
+-	R7 = [P3];
+-	R7 += 1;
+-	[P3] = R7;
+-.Ldicount_done:
+-#endif
+-
+-	/* Clean down the hardware loops*/
+-	R2 = 0;
+-	LC1 = R2;
+-	LC0 = R2;
 -
--/* initialise the key schedule from the user supplied key */
+-	/* There's a suitable victim in [P0-4] (because we've
+-	 * advanced already).
+-	 */
 -
--#define loop4(i)					\
--{							\
--	t = ror32(t,  8); t = ls_box(t) ^ rco_tab[i];	\
--	t ^= E_KEY[4 * i];     E_KEY[4 * i + 4] = t;	\
--	t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t;	\
--	t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t;	\
--	t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t;	\
--}
+-.LDdoverwrite:
 -
--#define loop6(i)					\
--{							\
--	t = ror32(t,  8); t = ls_box(t) ^ rco_tab[i];	\
--	t ^= E_KEY[6 * i];     E_KEY[6 * i + 6] = t;	\
--	t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t;	\
--	t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t;	\
--	t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t;	\
--	t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t;	\
--	t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t;	\
--}
+-	/* [P0-4] is a suitable victim CPLB, so we want to
+-	 * overwrite it by moving all the following CPLBs
+-	 * one space closer to the start.
+-	 */
 -
--#define loop8(i)					\
--{							\
--	t = ror32(t,  8); ; t = ls_box(t) ^ rco_tab[i];	\
--	t ^= E_KEY[8 * i];     E_KEY[8 * i + 8] = t;	\
--	t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t;	\
--	t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t;	\
--	t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t;	\
--	t  = E_KEY[8 * i + 4] ^ ls_box(t);		\
--	E_KEY[8 * i + 12] = t;				\
--	t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t;	\
--	t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t;	\
--	t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t;	\
--}
+-	R1.L = LO(DCPLB_DATA16);		/* DCPLB_DATA15 + 4 */
+-	R1.H = HI(DCPLB_DATA16);
+-	R0 = P0;
 -
--static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
--		       unsigned int key_len)
--{
--	struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
--	const __le32 *key = (const __le32 *)in_key;
--	u32 *flags = &tfm->crt_flags;
--	u32 i, j, t, u, v, w;
+-	/* If the victim happens to be in DCPLB15,
+-	 * we don't need to move anything.
+-	 */
 -
--	if (key_len % 8) {
--		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
--		return -EINVAL;
--	}
+-	CC = R1 == R0;
+-	IF CC JUMP .Lde_moved;
+-	R1 = R1 - R0;
+-	R1 >>= 2;
+-	P1 = R1;
+-	LSETUP(.Lds_move, .Lde_move) LC0=P1;
+-.Lds_move:
+-	R0 = [P0++];	/* move data */
+-	[P0 - 8] = R0;
+-	R0 = [P0-0x104]	/* move address */
+-.Lde_move: [P0-0x108] = R0;
+-
+-	/* We've now made space in DCPLB15 for the new CPLB to be
+-	 * installed. The next stage is to locate a CPLB in the
+-	 * config table that covers the faulting address.
+-	 */
 -
--	ctx->key_length = key_len;
+-.Lde_moved:NOP;
+-	R0 = I0;		/* Our faulting address */
 -
--	D_KEY[key_len + 24] = E_KEY[0] = le32_to_cpu(key[0]);
--	D_KEY[key_len + 25] = E_KEY[1] = le32_to_cpu(key[1]);
--	D_KEY[key_len + 26] = E_KEY[2] = le32_to_cpu(key[2]);
--	D_KEY[key_len + 27] = E_KEY[3] = le32_to_cpu(key[3]);
+-	P2.L = _dpdt_table;
+-	P2.H = _dpdt_table;
+-#ifdef	CONFIG_CPLB_INFO
+-	P3.L = _dpdt_swapcount_table;
+-	P3.H = _dpdt_swapcount_table;
+-	P3 += -8;
+-#endif
 -
--	switch (key_len) {
--	case 16:
--		t = E_KEY[3];
--		for (i = 0; i < 10; ++i)
--			loop4(i);
--		break;
+-	P1.L = _page_size_table;
+-	P1.H = _page_size_table;
 -
--	case 24:
--		E_KEY[4] = le32_to_cpu(key[4]);
--		t = E_KEY[5] = le32_to_cpu(key[5]);
--		for (i = 0; i < 8; ++i)
--			loop6 (i);
--		break;
+-	/* An extraction pattern, to retrieve bits 17:16.*/
 -
--	case 32:
--		E_KEY[4] = le32_to_cpu(key[4]);
--		E_KEY[5] = le32_to_cpu(key[5]);
--		E_KEY[6] = le32_to_cpu(key[6]);
--		t = E_KEY[7] = le32_to_cpu(key[7]);
--		for (i = 0; i < 7; ++i)
--			loop8(i);
--		break;
--	}
+-	R1 = (16<<8)|2;
+-.Ldnext:	R4 = [P2++];	/* address */
+-	R2 = [P2++];	/* data */
+-#ifdef	CONFIG_CPLB_INFO
+-	P3 += 8;
+-#endif
 -
--	D_KEY[0] = E_KEY[key_len + 24];
--	D_KEY[1] = E_KEY[key_len + 25];
--	D_KEY[2] = E_KEY[key_len + 26];
--	D_KEY[3] = E_KEY[key_len + 27];
+-	CC = R4 == -1;
+-	IF CC JUMP .Lno_page_in_table;
 -
--	for (i = 4; i < key_len + 24; ++i) {
--		j = key_len + 24 - (i & ~3) + (i & 3);
--		imix_col(D_KEY[j], E_KEY[i]);
--	}
+-	/* See if failed address > start address */
+-	CC = R4 <= R0(IU);
+-	IF !CC JUMP .Ldnext;
 -
--	return 0;
--}
+-	/* extract page size (17:16)*/
+-	R3 = EXTRACT(R2, R1.L) (Z);
 -
--asmlinkage void aes_enc_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in);
--asmlinkage void aes_dec_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in);
+-	/* add page size to addr to get range */
 -
--static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
--{
--	aes_enc_blk(tfm, dst, src);
--}
+-	P5 = R3;
+-	P5 = P1 + (P5 << 2);
+-	R3 = [P5];
+-	R3 = R3 + R4;
 -
--static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
--{
--	aes_dec_blk(tfm, dst, src);
--}
+-	/* See if failed address < (start address + page size) */
+-	CC = R0 < R3(IU);
+-	IF !CC JUMP .Ldnext;
 -
--static struct crypto_alg aes_alg = {
--	.cra_name		=	"aes",
--	.cra_driver_name	=	"aes-x86_64",
--	.cra_priority		=	200,
--	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
--	.cra_blocksize		=	AES_BLOCK_SIZE,
--	.cra_ctxsize		=	sizeof(struct aes_ctx),
--	.cra_module		=	THIS_MODULE,
--	.cra_list		=	LIST_HEAD_INIT(aes_alg.cra_list),
--	.cra_u			=	{
--		.cipher = {
--			.cia_min_keysize	=	AES_MIN_KEY_SIZE,
--			.cia_max_keysize	=	AES_MAX_KEY_SIZE,
--			.cia_setkey	   	= 	aes_set_key,
--			.cia_encrypt	 	=	aes_encrypt,
--			.cia_decrypt	  	=	aes_decrypt
--		}
--	}
--};
+-	/* We've found the CPLB that should be installed, so
+-	 * write it into CPLB15, masking off any caching bits
+-	 * if necessary.
+-	 */
 -
--static int __init aes_init(void)
--{
--	gen_tabs();
--	return crypto_register_alg(&aes_alg);
--}
+-	P1.L = LO(DCPLB_DATA15);
+-	P1.H = HI(DCPLB_DATA15);
 -
--static void __exit aes_fini(void)
--{
--	crypto_unregister_alg(&aes_alg);
--}
+-	/* If the DCPLB has cache bits set, but caching hasn't
+-	 * been enabled, then we want to mask off the cache-in-L1
+-	 * bit before installing. Moreover, if caching is off, we
+-	 * also want to ensure that the DCPLB has WT mode set, rather
+-	 * than WB, since WB pages still trigger first-write exceptions
+-	 * even when not caching is off, and the page isn't marked as
+-	 * cachable. Finally, we could mark the page as clean, not dirty,
+-	 * but we choose to leave that decision to the user; if the user
+-	 * chooses to have a CPLB pre-defined as dirty, then they always
+-	 * pay the cost of flushing during eviction, but don't pay the
+-	 * cost of first-write exceptions to mark the page as dirty.
+-	 */
 -
--module_init(aes_init);
--module_exit(aes_fini);
+-#ifdef CONFIG_BFIN_WT
+-	BITSET(R6, 14);		/* Set WT*/
+-#endif
 -
--MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
--MODULE_LICENSE("GPL");
--MODULE_ALIAS("aes");
-diff --git a/arch/x86/crypto/aes_glue.c b/arch/x86/crypto/aes_glue.c
-new file mode 100644
-index 0000000..71f4578
---- /dev/null
-+++ b/arch/x86/crypto/aes_glue.c
-@@ -0,0 +1,57 @@
-+/*
-+ * Glue Code for the asm optimized version of the AES Cipher Algorithm
-+ *
-+ */
+-	[P1] = R2;
+-	[P1-0x100] = R4;
+-#ifdef	CONFIG_CPLB_INFO
+-	R3 = [P3];
+-	R3 += 1;
+-	[P3] = R3;
+-#endif
+-
+-	/* We've installed the CPLB, so re-enable CPLBs. P4
+-	 * points to DMEM_CONTROL, and R5 is the value we
+-	 * last wrote to it, when we were disabling CPLBs.
+-	 */
+-
+-	BITSET(R5,ENDCPLB_P);
+-	CLI R2;
+-	.align 8;
+-	[P4] = R5;
+-	SSYNC;
+-	STI R2;
+-
+-	( R7:4,P5:3 ) = [SP++];
+-	R0 = CPLB_RELOADED;
+-	RTS;
+-ENDPROC(_cplb_mgr)
+-
+-.data
+-.align 4;
+-_page_size_table:
+-.byte4	0x00000400;	/* 1K */
+-.byte4	0x00001000;	/* 4K */
+-.byte4	0x00100000;	/* 1M */
+-.byte4	0x00400000;	/* 4M */
+-
+-.align 4;
+-_dcplb_preference:
+-.byte4	0x00000001;	/* valid bit */
+-.byte4	0x00000002;	/* lock bit */
+diff --git a/arch/blackfin/mach-common/dpmc.S b/arch/blackfin/mach-common/dpmc.S
+index 39fbc28..b82c096 100644
+--- a/arch/blackfin/mach-common/dpmc.S
++++ b/arch/blackfin/mach-common/dpmc.S
+@@ -38,6 +38,9 @@ ENTRY(_unmask_wdog_wakeup_evt)
+ #if defined(CONFIG_BF561)
+ 	P0.H = hi(SICA_IWR1);
+ 	P0.L = lo(SICA_IWR1);
++#elif defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
++	P0.h = HI(SIC_IWR0);
++	P0.l = LO(SIC_IWR0);
+ #else
+ 	P0.h = HI(SIC_IWR);
+ 	P0.l = LO(SIC_IWR);
+@@ -172,7 +175,7 @@ ENTRY(_sleep_mode)
+ 	call _set_sic_iwr;
+ 
+ 	R0 = 0xFFFF (Z);
+-	call _set_rtc_istat
++	call _set_rtc_istat;
+ 
+ 	P0.H = hi(PLL_CTL);
+ 	P0.L = lo(PLL_CTL);
+@@ -210,7 +213,7 @@ ENTRY(_hibernate_mode)
+ 	call _set_sic_iwr;
+ 
+ 	R0 = 0xFFFF (Z);
+-	call _set_rtc_istat
++	call _set_rtc_istat;
+ 
+ 	P0.H = hi(VR_CTL);
+ 	P0.L = lo(VR_CTL);
+@@ -236,7 +239,7 @@ ENTRY(_deep_sleep)
+ 
+ 	call _set_sic_iwr;
+ 
+-	call _set_sdram_srfs;
++	call _set_dram_srfs;
+ 
+ 	/* Clear all the interrupts,bits sticky */
+ 	R0 = 0xFFFF (Z);
+@@ -253,7 +256,7 @@ ENTRY(_deep_sleep)
+ 	SSYNC;
+ 	IDLE;
+ 
+-	call _unset_sdram_srfs;
++	call _unset_dram_srfs;
+ 
+ 	call _test_pll_locked;
+ 
+@@ -285,23 +288,22 @@ ENTRY(_sleep_deeper)
+ 	P3 = R0;
+ 	R0 = IWR_ENABLE(0);
+ 	call _set_sic_iwr;
+-	call _set_sdram_srfs;
++	call _set_dram_srfs;	/* Set SDRAM Self Refresh */
+ 
+ 	/* Clear all the interrupts,bits sticky */
+ 	R0 = 0xFFFF (Z);
+-	call _set_rtc_istat
+-
++	call _set_rtc_istat;
+ 	P0.H = hi(PLL_DIV);
+ 	P0.L = lo(PLL_DIV);
+ 	R6 = W[P0](z);
+ 	R0.L = 0xF;
+-	W[P0] = R0.l;
++	W[P0] = R0.l;		/* Set Max VCO to SCLK divider */
+ 
+ 	P0.H = hi(PLL_CTL);
+ 	P0.L = lo(PLL_CTL);
+ 	R5 = W[P0](z);
+ 	R0.L = (CONFIG_MIN_VCO_HZ/CONFIG_CLKIN_HZ) << 9;
+-	W[P0] = R0.l;
++	W[P0] = R0.l;		/* Set Min CLKIN to VCO multiplier */
+ 
+ 	SSYNC;
+ 	IDLE;
+@@ -317,29 +319,28 @@ ENTRY(_sleep_deeper)
+ 	R1 = R1|R2;
+ 
+ 	R2 = DEPOSIT(R7, R1);
+-	W[P0] = R2;
++	W[P0] = R2;		/* Set Min Core Voltage */
+ 
+ 	SSYNC;
+ 	IDLE;
+ 
+ 	call _test_pll_locked;
+ 
++	R0 = P3;
++	call _set_sic_iwr;	/* Set Awake from IDLE */
++
+ 	P0.H = hi(PLL_CTL);
+ 	P0.L = lo(PLL_CTL);
+ 	R0 = W[P0](z);
+ 	BITSET (R0, 3);
+-	W[P0] = R0.L;
+-
+-	R0 = P3;
+-	call _set_sic_iwr;
+-
++	W[P0] = R0.L;		/* Turn CCLK OFF */
+ 	SSYNC;
+ 	IDLE;
+ 
+ 	call _test_pll_locked;
+ 
+ 	R0 = IWR_ENABLE(0);
+-	call _set_sic_iwr;
++	call _set_sic_iwr;	/* Set Awake from IDLE PLL */
+ 
+ 	P0.H = hi(VR_CTL);
+ 	P0.L = lo(VR_CTL);
+@@ -352,15 +353,15 @@ ENTRY(_sleep_deeper)
+ 
+ 	P0.H = hi(PLL_DIV);
+ 	P0.L = lo(PLL_DIV);
+-	W[P0]= R6;
++	W[P0]= R6;		/* Restore CCLK and SCLK divider */
+ 
+ 	P0.H = hi(PLL_CTL);
+ 	P0.L = lo(PLL_CTL);
+-	w[p0] = R5;
++	w[p0] = R5;		/* Restore VCO multiplier */
+ 	IDLE;
+ 	call _test_pll_locked;
+ 
+-	call _unset_sdram_srfs;
++	call _unset_dram_srfs;	/* SDRAM Self Refresh Off */
+ 
+ 	STI R4;
+ 
+@@ -368,25 +369,47 @@ ENTRY(_sleep_deeper)
+ 	( R7:0, P5:0 ) = [SP++];
+ 	RTS;
+ 
+-ENTRY(_set_sdram_srfs)
+-	/*  set the sdram to self refresh mode */
++ENTRY(_set_dram_srfs)
++	/*  set the dram to self refresh mode */
++#if defined(CONFIG_BF54x)
++	P0.H = hi(EBIU_RSTCTL);
++	P0.L = lo(EBIU_RSTCTL);
++	R2 = [P0];
++	R3.H = hi(SRREQ);
++	R3.L = lo(SRREQ);
++#else
+ 	P0.H = hi(EBIU_SDGCTL);
+ 	P0.L = lo(EBIU_SDGCTL);
+ 	R2 = [P0];
+ 	R3.H = hi(SRFS);
+ 	R3.L = lo(SRFS);
++#endif
+ 	R2 = R2|R3;
+ 	[P0] = R2;
+ 	ssync;
++#if defined(CONFIG_BF54x)
++.LSRR_MODE:
++	R2 = [P0];
++	CC = BITTST(R2, 4);
++	if !CC JUMP .LSRR_MODE;
++#endif
+ 	RTS;
+ 
+-ENTRY(_unset_sdram_srfs)
+-	/*  set the sdram out of self refresh mode */
++ENTRY(_unset_dram_srfs)
++	/*  set the dram out of self refresh mode */
++#if defined(CONFIG_BF54x)
++	P0.H = hi(EBIU_RSTCTL);
++	P0.L = lo(EBIU_RSTCTL);
++	R2 = [P0];
++	R3.H = hi(SRREQ);
++	R3.L = lo(SRREQ);
++#else
+ 	P0.H = hi(EBIU_SDGCTL);
+ 	P0.L = lo(EBIU_SDGCTL);
+ 	R2 = [P0];
+ 	R3.H = hi(SRFS);
+ 	R3.L = lo(SRFS);
++#endif
+ 	R3 = ~R3;
+ 	R2 = R2&R3;
+ 	[P0] = R2;
+@@ -394,8 +417,13 @@ ENTRY(_unset_sdram_srfs)
+ 	RTS;
+ 
+ ENTRY(_set_sic_iwr)
++#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
++	P0.H = hi(SIC_IWR0);
++	P0.L = lo(SIC_IWR0);
++#else
+ 	P0.H = hi(SIC_IWR);
+ 	P0.L = lo(SIC_IWR);
++#endif
+ 	[P0] = R0;
+ 	SSYNC;
+ 	RTS;
+diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
+index dc9d3ee..56ff51b 100644
+--- a/arch/blackfin/mach-common/entry.S
++++ b/arch/blackfin/mach-common/entry.S
+@@ -95,6 +95,9 @@ ENTRY(_ex_workaround_261)
+ 	R6 = 0x26;	/* Data CPLB Miss */
+ 	cc = R6 == R7;
+ 	if cc jump _ex_dcplb_miss (BP);
++	R6 = 0x23;	/* Data CPLB Miss */
++	cc = R6 == R7;
++	if cc jump _ex_dcplb_viol (BP);
+ 	/* Handle 0x23 Data CPLB Protection Violation
+ 	 * and Data CPLB Multiple Hits - Linux Trap Zero
+ 	 */
+@@ -102,17 +105,33 @@ ENTRY(_ex_workaround_261)
+ ENDPROC(_ex_workaround_261)
+ 
+ #else
++#ifdef CONFIG_MPU
++#define _ex_dviol _ex_dcplb_viol
++#else
+ #define _ex_dviol _ex_trap_c
++#endif
+ #define _ex_dmiss _ex_dcplb_miss
+ #define _ex_dmult _ex_trap_c
+ #endif
+ 
 +
-+#include <crypto/aes.h>
++ENTRY(_ex_dcplb_viol)
+ ENTRY(_ex_dcplb_miss)
+ ENTRY(_ex_icplb_miss)
+ 	(R7:6,P5:4) = [sp++];
+ 	ASTAT = [sp++];
+ 	SAVE_ALL_SYS
++#ifdef CONFIG_MPU
++	R0 = SEQSTAT;
++	R1 = SP;
++	sp += -12;
++	call _cplb_hdr;
++	sp += 12;
++	CC = R0 == 0;
++	IF !CC JUMP _handle_bad_cplb;
++#else
+ 	call __cplb_hdr;
++#endif
+ 	DEBUG_START_HWTRACE(p5, r7)
+ 	RESTORE_ALL_SYS
+ 	SP = EX_SCRATCH_REG;
+@@ -329,7 +348,7 @@ ENTRY(_exception_to_level5)
+ 	R7 = R7 + R6;
+ 	P5 = R7;
+ 	R1 = [P5];
+-	[SP + 8] = r1;
++	[SP + PT_SEQSTAT] = r1;
+ 
+ 	r0 = sp; 	/* stack frame pt_regs pointer argument ==> r0 */
+ 	SP += -12;
+@@ -633,9 +652,7 @@ ENTRY(_ret_from_exception)
+ 	[sp + PT_IPEND] = r0;
+ 
+ 1:
+-	r1 = 0x37(Z);
+-	r2 = ~r1;
+-	r2.h = 0;
++	r2 = LO(~0x37) (Z);
+ 	r0 = r2 & r0;
+ 	cc = r0 == 0;
+ 	if !cc jump 4f;	/* if not return to user mode, get out */
+@@ -1364,6 +1381,7 @@ ENTRY(_sys_call_table)
+ 	.long _sys_set_robust_list
+ 	.long _sys_get_robust_list	/* 355 */
+ 	.long _sys_fallocate
++	.long _sys_semtimedop
+ 	.rept NR_syscalls-(.-_sys_call_table)/4
+ 	.long _sys_ni_syscall
+ 	.endr
+diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S
+index 4de3764..7f752c8 100644
+--- a/arch/blackfin/mach-common/interrupt.S
++++ b/arch/blackfin/mach-common/interrupt.S
+@@ -34,9 +34,13 @@
+ #include <asm/entry.h>
+ #include <asm/asm-offsets.h>
+ #include <asm/trace.h>
++#include <asm/traps.h>
++#include <asm/thread_info.h>
+ 
+ #include <asm/mach-common/context.S>
+ 
++.extern _ret_from_exception
 +
-+asmlinkage void aes_enc_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in);
-+asmlinkage void aes_dec_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in);
+ #ifdef CONFIG_I_ENTRY_L1
+ .section .l1.text
+ #else
+@@ -117,8 +121,8 @@ __common_int_entry:
+ 
+ #if ANOMALY_05000283 || ANOMALY_05000315
+ 	cc = r7 == r7;
+-	p5.h = 0xffc0;
+-	p5.l = 0x0014;
++	p5.h = HI(CHIPID);
++	p5.l = LO(CHIPID);
+ 	if cc jump 1f;
+ 	r7.l = W[p5];
+ 1:
+@@ -134,26 +138,22 @@ __common_int_entry:
+ 
+ /* interrupt routine for ivhw - 5 */
+ ENTRY(_evt_ivhw)
+-	SAVE_CONTEXT
++	SAVE_ALL_SYS
+ #ifdef CONFIG_FRAME_POINTER
+ 	fp = 0;
+ #endif
++
+ #if ANOMALY_05000283
+ 	cc = r7 == r7;
+-	p5.h = 0xffc0;
+-	p5.l = 0x0014;
++	p5.h = HI(CHIPID);
++	p5.l = LO(CHIPID);
+ 	if cc jump 1f;
+ 	r7.l = W[p5];
+ 1:
+ #endif
+ 
+-	trace_buffer_stop(p0, r0);
+-
+-	r0 = IRQ_HWERR;
+-	r1 = sp;
+-
+ #ifdef CONFIG_HARDWARE_PM
+-	r7 = SEQSTAT;
++	r7 = [sp + PT_SEQSTAT];
+ 	r7 = r7 >>> 0xe;
+ 	r6 = 0x1F;
+ 	r7 = r7 & r6;
+@@ -161,11 +161,29 @@ ENTRY(_evt_ivhw)
+ 	cc = r7 == r5;
+ 	if cc jump .Lcall_do_ovf; /* deal with performance counter overflow */
+ #endif
+-
++	# We are going to dump something out, so make sure we print IPEND properly
++	p2.l = lo(IPEND);
++	p2.h = hi(IPEND);
++	r0 = [p2];
++	[sp + PT_IPEND] = r0;
++
++	/* set the EXCAUSE to HWERR for trap_c */
++	r0 = [sp + PT_SEQSTAT];
++	R1.L = LO(VEC_HWERR);
++	R1.H = HI(VEC_HWERR);
++	R0 = R0 | R1;
++	[sp + PT_SEQSTAT] = R0;
++
++	r0 = sp;        /* stack frame pt_regs pointer argument ==> r0 */
+ 	SP += -12;
+-	call _irq_panic;
++	call _trap_c;
+ 	SP += 12;
++
++	call _ret_from_exception;
++.Lcommon_restore_all_sys:
++	RESTORE_ALL_SYS
+ 	rti;
++
+ #ifdef CONFIG_HARDWARE_PM
+ .Lcall_do_ovf:
+ 
+@@ -173,9 +191,11 @@ ENTRY(_evt_ivhw)
+ 	call _pm_overflow;
+ 	SP += 12;
+ 
+-	jump .Lcommon_restore_context;
++	jump .Lcommon_restore_all_sys;
+ #endif
+ 
++ENDPROC(_evt_ivhw)
++
+ /* Interrupt routine for evt2 (NMI).
+  * We don't actually use this, so just return.
+  * For inner circle type details, please see:
+diff --git a/arch/blackfin/mach-common/ints-priority-dc.c b/arch/blackfin/mach-common/ints-priority-dc.c
+index 4882f0e..8d18d6b 100644
+--- a/arch/blackfin/mach-common/ints-priority-dc.c
++++ b/arch/blackfin/mach-common/ints-priority-dc.c
+@@ -222,11 +222,12 @@ static void bf561_gpio_unmask_irq(unsigned int irq)
+ static unsigned int bf561_gpio_irq_startup(unsigned int irq)
+ {
+ 	unsigned int ret;
++	char buf[8];
+ 	u16 gpionr = irq - IRQ_PF0;
+ 
+ 	if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
+-
+-		ret = gpio_request(gpionr, "IRQ");
++		snprintf(buf, sizeof buf, "IRQ %d", irq);
++		ret = gpio_request(gpionr, buf);
+ 		if (ret)
+ 			return ret;
+ 
+@@ -250,6 +251,7 @@ static int bf561_gpio_irq_type(unsigned int irq, unsigned int type)
+ {
+ 
+ 	unsigned int ret;
++	char buf[8];
+ 	u16 gpionr = irq - IRQ_PF0;
+ 
+ 
+@@ -265,8 +267,8 @@ static int bf561_gpio_irq_type(unsigned int irq, unsigned int type)
+ 			    IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
+ 
+ 		if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
+-
+-			ret = gpio_request(gpionr, "IRQ");
++			snprintf(buf, sizeof buf, "IRQ %d", irq);
++			ret = gpio_request(gpionr, buf);
+ 			if (ret)
+ 				return ret;
+ 
+diff --git a/arch/blackfin/mach-common/ints-priority-sc.c b/arch/blackfin/mach-common/ints-priority-sc.c
+index 147f073..dec42ac 100644
+--- a/arch/blackfin/mach-common/ints-priority-sc.c
++++ b/arch/blackfin/mach-common/ints-priority-sc.c
+@@ -313,6 +313,7 @@ static void bfin_demux_error_irq(unsigned int int_err_irq,
+ static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
+ static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)];
+ 
 +
-+static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
-+{
-+	aes_enc_blk(tfm, dst, src);
+ static void bfin_gpio_ack_irq(unsigned int irq)
+ {
+ 	u16 gpionr = irq - IRQ_PF0;
+@@ -352,9 +353,11 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq)
+ {
+ 	unsigned int ret;
+ 	u16 gpionr = irq - IRQ_PF0;
++	char buf[8];
+ 
+ 	if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
+-		ret = gpio_request(gpionr, "IRQ");
++		snprintf(buf, sizeof buf, "IRQ %d", irq);
++		ret = gpio_request(gpionr, buf);
+ 		if (ret)
+ 			return ret;
+ 	}
+@@ -376,6 +379,7 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
+ {
+ 
+ 	unsigned int ret;
++	char buf[8];
+ 	u16 gpionr = irq - IRQ_PF0;
+ 
+ 	if (type == IRQ_TYPE_PROBE) {
+@@ -388,7 +392,8 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
+ 	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
+ 		    IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
+ 		if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
+-			ret = gpio_request(gpionr, "IRQ");
++			snprintf(buf, sizeof buf, "IRQ %d", irq);
++			ret = gpio_request(gpionr, buf);
+ 			if (ret)
+ 				return ret;
+ 		}
+@@ -478,6 +483,10 @@ static void bfin_demux_gpio_irq(unsigned int intb_irq,
+ static unsigned char irq2pint_lut[NR_PINTS];
+ static unsigned char pint2irq_lut[NR_PINT_SYS_IRQS * NR_PINT_BITS];
+ 
++static unsigned int gpio_both_edge_triggered[NR_PINT_SYS_IRQS];
++static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
++
++
+ struct pin_int_t {
+ 	unsigned int mask_set;
+ 	unsigned int mask_clear;
+@@ -544,13 +553,20 @@ void init_pint_lut(void)
+ 
+ }
+ 
+-static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)];
+-
+ static void bfin_gpio_ack_irq(unsigned int irq)
+ {
+ 	u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
++	u32 pintbit = PINT_BIT(pint_val);
++	u8 bank = PINT_2_BANK(pint_val);
++
++	if (unlikely(gpio_both_edge_triggered[bank] & pintbit)) {
++		if (pint[bank]->invert_set & pintbit)
++			pint[bank]->invert_clear = pintbit;
++		else
++			pint[bank]->invert_set = pintbit;
++	}
++	pint[bank]->request = pintbit;
+ 
+-	pint[PINT_2_BANK(pint_val)]->request = PINT_BIT(pint_val);
+ 	SSYNC();
+ }
+ 
+@@ -560,6 +576,13 @@ static void bfin_gpio_mask_ack_irq(unsigned int irq)
+ 	u32 pintbit = PINT_BIT(pint_val);
+ 	u8 bank = PINT_2_BANK(pint_val);
+ 
++	if (unlikely(gpio_both_edge_triggered[bank] & pintbit)) {
++		if (pint[bank]->invert_set & pintbit)
++			pint[bank]->invert_clear = pintbit;
++		else
++			pint[bank]->invert_set = pintbit;
++	}
++
+ 	pint[bank]->request = pintbit;
+ 	pint[bank]->mask_clear = pintbit;
+ 	SSYNC();
+@@ -587,7 +610,8 @@ static void bfin_gpio_unmask_irq(unsigned int irq)
+ static unsigned int bfin_gpio_irq_startup(unsigned int irq)
+ {
+ 	unsigned int ret;
+-	u16 gpionr = irq - IRQ_PA0;
++	char buf[8];
++	u16 gpionr = irq_to_gpio(irq);
+ 	u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
+ 
+ 	if (pint_val == IRQ_NOT_AVAIL) {
+@@ -598,7 +622,8 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq)
+ 	}
+ 
+ 	if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
+-		ret = gpio_request(gpionr, "IRQ");
++		snprintf(buf, sizeof buf, "IRQ %d", irq);
++		ret = gpio_request(gpionr, buf);
+ 		if (ret)
+ 			return ret;
+ 	}
+@@ -611,16 +636,19 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq)
+ 
+ static void bfin_gpio_irq_shutdown(unsigned int irq)
+ {
++	u16 gpionr = irq_to_gpio(irq);
++
+ 	bfin_gpio_mask_irq(irq);
+-	gpio_free(irq - IRQ_PA0);
+-	gpio_enabled[gpio_bank(irq - IRQ_PA0)] &= ~gpio_bit(irq - IRQ_PA0);
++	gpio_free(gpionr);
++	gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr);
+ }
+ 
+ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
+ {
+ 
+ 	unsigned int ret;
+-	u16 gpionr = irq - IRQ_PA0;
++	char buf[8];
++	u16 gpionr = irq_to_gpio(irq);
+ 	u8 pint_val = irq2pint_lut[irq - SYS_IRQS];
+ 	u32 pintbit = PINT_BIT(pint_val);
+ 	u8 bank = PINT_2_BANK(pint_val);
+@@ -638,7 +666,8 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
+ 	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
+ 		    IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
+ 		if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
+-			ret = gpio_request(gpionr, "IRQ");
++			snprintf(buf, sizeof buf, "IRQ %d", irq);
++			ret = gpio_request(gpionr, buf);
+ 			if (ret)
+ 				return ret;
+ 		}
+@@ -651,28 +680,33 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
+ 
+ 	gpio_direction_input(gpionr);
+ 
+-	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
+-		pint[bank]->edge_set = pintbit;
+-	} else {
+-		pint[bank]->edge_clear = pintbit;
+-	}
+-
+ 	if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)))
+ 		pint[bank]->invert_set = pintbit;	/* low or falling edge denoted by one */
+ 	else
+-		pint[bank]->invert_set = pintbit;	/* high or rising edge denoted by zero */
++		pint[bank]->invert_clear = pintbit;	/* high or rising edge denoted by zero */
+ 
+-	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+-		pint[bank]->invert_set = pintbit;
+-	else
+-		pint[bank]->invert_set = pintbit;
++	if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
++	    == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
+ 
+-	SSYNC();
++		gpio_both_edge_triggered[bank] |= pintbit;
+ 
+-	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
++		if (gpio_get_value(gpionr))
++			pint[bank]->invert_set = pintbit;
++		else
++			pint[bank]->invert_clear = pintbit;
++	} else {
++		gpio_both_edge_triggered[bank] &= ~pintbit;
++	}
++
++	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
++		pint[bank]->edge_set = pintbit;
+ 		set_irq_handler(irq, handle_edge_irq);
+-	else
++	} else {
++		pint[bank]->edge_clear = pintbit;
+ 		set_irq_handler(irq, handle_level_irq);
++	}
++
++	SSYNC();
+ 
+ 	return 0;
+ }
+diff --git a/arch/blackfin/mach-common/irqpanic.c b/arch/blackfin/mach-common/irqpanic.c
+index b22959b..606ded9 100644
+--- a/arch/blackfin/mach-common/irqpanic.c
++++ b/arch/blackfin/mach-common/irqpanic.c
+@@ -46,9 +46,6 @@ void irq_panic(int reason, struct pt_regs *regs) __attribute__ ((l1_text));
+  */
+ asmlinkage void irq_panic(int reason, struct pt_regs *regs)
+ {
+-	int sig = 0;
+-	siginfo_t info;
+-
+ #ifdef CONFIG_DEBUG_ICACHE_CHECK
+ 	unsigned int cmd, tag, ca, cache_hi, cache_lo, *pa;
+ 	unsigned short i, j, die;
+@@ -136,53 +133,6 @@ asmlinkage void irq_panic(int reason, struct pt_regs *regs)
+ 	}
+ #endif
+ 
+-	printk(KERN_EMERG "\n");
+-	printk(KERN_EMERG "Exception: IRQ 0x%x entered\n", reason);
+-	printk(KERN_EMERG " code=[0x%08lx],   stack frame=0x%08lx,  "
+-	    " bad PC=0x%08lx\n",
+-	    (unsigned long)regs->seqstat,
+-	    (unsigned long)regs,
+-	    (unsigned long)regs->pc);
+-	if (reason == 0x5) {
+-		printk(KERN_EMERG "----------- HARDWARE ERROR -----------\n");
+-
+-		/* There is only need to check for Hardware Errors, since other
+-		 * EXCEPTIONS are handled in TRAPS.c (MH)
+-		 */
+-		switch (regs->seqstat & SEQSTAT_HWERRCAUSE) {
+-		case (SEQSTAT_HWERRCAUSE_SYSTEM_MMR):	/* System MMR Error */
+-			info.si_code = BUS_ADRALN;
+-			sig = SIGBUS;
+-			printk(KERN_EMERG HWC_x2(KERN_EMERG));
+-			break;
+-		case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR):	/* External Memory Addressing Error */
+-			info.si_code = BUS_ADRERR;
+-			sig = SIGBUS;
+-			printk(KERN_EMERG HWC_x3(KERN_EMERG));
+-			break;
+-		case (SEQSTAT_HWERRCAUSE_PERF_FLOW):	/* Performance Monitor Overflow */
+-			printk(KERN_EMERG HWC_x12(KERN_EMERG));
+-			break;
+-		case (SEQSTAT_HWERRCAUSE_RAISE_5):	/* RAISE 5 instruction */
+-			printk(KERN_EMERG HWC_x18(KERN_EMERG));
+-			break;
+-		default:	/* Reserved */
+-			printk(KERN_EMERG HWC_default(KERN_EMERG));
+-			break;
+-		}
+-	}
+-
+-	regs->ipend = bfin_read_IPEND();
+-	dump_bfin_process(regs);
+-	dump_bfin_mem((void *)regs->pc);
+-	show_regs(regs);
+-	if (0 == (info.si_signo = sig) || 0 == user_mode(regs))	/* in kernelspace */
+-		panic("Unhandled IRQ or exceptions!\n");
+-	else {			/* in userspace */
+-		info.si_errno = 0;
+-		info.si_addr = (void *)regs->pc;
+-		force_sig_info(sig, &info, current);
+-	}
+ }
+ 
+ #ifdef CONFIG_HARDWARE_PM
+diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
+index dac51fb..81930f7 100644
+--- a/arch/blackfin/mach-common/pm.c
++++ b/arch/blackfin/mach-common/pm.c
+@@ -77,7 +77,15 @@ void bfin_pm_suspend_standby_enter(void)
+ 
+ 		gpio_pm_restore();
+ 
++#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
++		bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
++		bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
++# ifdef CONFIG_BF54x
++		bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
++# endif
++#else
+ 		bfin_write_SIC_IWR(IWR_ENABLE_ALL);
++#endif
+ 
+ 		local_irq_restore(flags);
+ 	}
+@@ -85,7 +93,15 @@ void bfin_pm_suspend_standby_enter(void)
+ 
+ #if defined(CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR)
+ 	sleep_deeper(CONFIG_PM_WAKEUP_SIC_IWR);
++# if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
++	bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
++	bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
++#  ifdef CONFIG_BF54x
++	bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
++#  endif
++# else
+ 	bfin_write_SIC_IWR(IWR_ENABLE_ALL);
++# endif
+ #endif				/* CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR */
+ }
+ 
+diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c
+index e97ea8f..eb1a12a 100644
+--- a/arch/blackfin/mm/init.c
++++ b/arch/blackfin/mm/init.c
+@@ -128,8 +128,8 @@ void __init paging_init(void)
+ void __init mem_init(void)
+ {
+ 	unsigned int codek = 0, datak = 0, initk = 0;
++	unsigned int reservedpages = 0, freepages = 0;
+ 	unsigned long tmp;
+-	unsigned int len = _ramend - _rambase;
+ 	unsigned long start_mem = memory_start;
+ 	unsigned long end_mem = memory_end;
+ 
+@@ -138,19 +138,36 @@ void __init mem_init(void)
+ 
+ 	start_mem = PAGE_ALIGN(start_mem);
+ 	max_mapnr = num_physpages = MAP_NR(high_memory);
+-	printk(KERN_INFO "Physical pages: %lx\n", num_physpages);
++	printk(KERN_INFO "Kernel managed physical pages: %lu\n",
++		num_physpages);
+ 
+ 	/* This will put all memory onto the freelists. */
+ 	totalram_pages = free_all_bootmem();
+ 
++	reservedpages = 0;
++	for (tmp = 0; tmp < max_mapnr; tmp++)
++		if (PageReserved(pfn_to_page(tmp)))
++			reservedpages++;
++	freepages =  max_mapnr - reservedpages;
++
++	/* do not count in kernel image between _rambase and _ramstart */
++	reservedpages -= (_ramstart - _rambase) >> PAGE_SHIFT;
++#if (defined(CONFIG_BFIN_ICACHE) && ANOMALY_05000263)
++	reservedpages += (_ramend - memory_end - DMA_UNCACHED_REGION) >>
++				PAGE_SHIFT;
++#endif
++
+ 	codek = (_etext - _stext) >> 10;
+-	datak = (__bss_stop - __bss_start) >> 10;
+ 	initk = (__init_end - __init_begin) >> 10;
++	datak = ((_ramstart - _rambase) >> 10) - codek - initk;
+ 
+-	tmp = nr_free_pages() << PAGE_SHIFT;
+ 	printk(KERN_INFO
+-	     "Memory available: %luk/%uk RAM, (%uk init code, %uk kernel code, %uk data, %uk dma)\n",
+-	     tmp >> 10, len >> 10, initk, codek, datak, DMA_UNCACHED_REGION >> 10);
++	     "Memory available: %luk/%luk RAM, "
++		"(%uk init code, %uk kernel code, "
++		"%uk data, %uk dma, %uk reserved)\n",
++		(unsigned long) freepages << (PAGE_SHIFT-10), _ramend >> 10,
++		initk, codek, datak, DMA_UNCACHED_REGION >> 10,
++		(reservedpages << (PAGE_SHIFT-10)));
+ 
+ 	/* Initialize the blackfin L1 Memory. */
+ 	l1sram_init();
+@@ -184,13 +201,15 @@ static __init void free_init_pages(const char *what, unsigned long begin, unsign
+ #ifdef CONFIG_BLK_DEV_INITRD
+ void __init free_initrd_mem(unsigned long start, unsigned long end)
+ {
++#ifndef CONFIG_MPU
+ 	free_init_pages("initrd memory", start, end);
++#endif
+ }
+ #endif
+ 
+ void __init free_initmem(void)
+ {
+-#ifdef CONFIG_RAMKERNEL
++#if defined CONFIG_RAMKERNEL && !defined CONFIG_MPU
+ 	free_init_pages("unused kernel memory",
+ 			(unsigned long)(&__init_begin),
+ 			(unsigned long)(&__init_end));
+diff --git a/arch/cris/arch-v32/drivers/iop_fw_load.c b/arch/cris/arch-v32/drivers/iop_fw_load.c
+index 11f9895..f4bdc1d 100644
+--- a/arch/cris/arch-v32/drivers/iop_fw_load.c
++++ b/arch/cris/arch-v32/drivers/iop_fw_load.c
+@@ -20,6 +20,9 @@
+ 
+ #define IOP_TIMEOUT 100
+ 
++#error "This driver is broken with regard to its driver core usage."
++#error "Please contact <greg at kroah.com> for details on how to fix it properly."
++
+ static struct device iop_spu_device[2] = {
+ 	{ .bus_id =     "iop-spu0", },
+ 	{ .bus_id =     "iop-spu1", },
+@@ -192,6 +195,13 @@ int iop_start_mpu(unsigned int start_addr)
+ 
+ static int __init iop_fw_load_init(void)
+ {
++#if 0
++	/*
++	 * static struct devices can not be added directly to sysfs by ignoring
++	 * the driver model infrastructure.  To fix this properly, please use
++	 * the platform_bus to register these devices to be able to properly
++	 * use the firmware infrastructure.
++	 */
+ 	device_initialize(&iop_spu_device[0]);
+ 	kobject_set_name(&iop_spu_device[0].kobj, "iop-spu0");
+ 	kobject_add(&iop_spu_device[0].kobj);
+@@ -201,6 +211,7 @@ static int __init iop_fw_load_init(void)
+ 	device_initialize(&iop_mpu_device);
+ 	kobject_set_name(&iop_mpu_device.kobj, "iop-mpu");
+ 	kobject_add(&iop_mpu_device.kobj);
++#endif
+ 	return 0;
+ }
+ 
+diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
+index 4ac2b1f..86028c6 100644
+--- a/arch/ia64/kernel/setup.c
++++ b/arch/ia64/kernel/setup.c
+@@ -71,8 +71,6 @@ unsigned long __per_cpu_offset[NR_CPUS];
+ EXPORT_SYMBOL(__per_cpu_offset);
+ #endif
+ 
+-extern void ia64_setup_printk_clock(void);
+-
+ DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info);
+ DEFINE_PER_CPU(unsigned long, local_per_cpu_offset);
+ unsigned long ia64_cycles_per_usec;
+@@ -507,8 +505,6 @@ setup_arch (char **cmdline_p)
+ 	/* process SAL system table: */
+ 	ia64_sal_init(__va(efi.sal_systab));
+ 
+-	ia64_setup_printk_clock();
+-
+ #ifdef CONFIG_SMP
+ 	cpu_physical_id(0) = hard_smp_processor_id();
+ #endif
+diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
+index 2bb8421..3ab0427 100644
+--- a/arch/ia64/kernel/time.c
++++ b/arch/ia64/kernel/time.c
+@@ -344,33 +344,6 @@ udelay (unsigned long usecs)
+ }
+ EXPORT_SYMBOL(udelay);
+ 
+-static unsigned long long ia64_itc_printk_clock(void)
+-{
+-	if (ia64_get_kr(IA64_KR_PER_CPU_DATA))
+-		return sched_clock();
+-	return 0;
+-}
+-
+-static unsigned long long ia64_default_printk_clock(void)
+-{
+-	return (unsigned long long)(jiffies_64 - INITIAL_JIFFIES) *
+-		(1000000000/HZ);
+-}
+-
+-unsigned long long (*ia64_printk_clock)(void) = &ia64_default_printk_clock;
+-
+-unsigned long long printk_clock(void)
+-{
+-	return ia64_printk_clock();
+-}
+-
+-void __init
+-ia64_setup_printk_clock(void)
+-{
+-	if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT))
+-		ia64_printk_clock = ia64_itc_printk_clock;
+-}
+-
+ /* IA64 doesn't cache the timezone */
+ void update_vsyscall_tz(void)
+ {
+diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
+index 14261fe..a2484fc 100644
+--- a/arch/ia64/kernel/topology.c
++++ b/arch/ia64/kernel/topology.c
+@@ -354,27 +354,27 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
+ 	if (unlikely(retval < 0))
+ 		return retval;
+ 
+-	all_cpu_cache_info[cpu].kobj.parent = &sys_dev->kobj;
+-	kobject_set_name(&all_cpu_cache_info[cpu].kobj, "%s", "cache");
+-	all_cpu_cache_info[cpu].kobj.ktype = &cache_ktype_percpu_entry;
+-	retval = kobject_register(&all_cpu_cache_info[cpu].kobj);
++	retval = kobject_init_and_add(&all_cpu_cache_info[cpu].kobj,
++				      &cache_ktype_percpu_entry, &sys_dev->kobj,
++				      "%s", "cache");
+ 
+ 	for (i = 0; i < all_cpu_cache_info[cpu].num_cache_leaves; i++) {
+ 		this_object = LEAF_KOBJECT_PTR(cpu,i);
+-		this_object->kobj.parent = &all_cpu_cache_info[cpu].kobj;
+-		kobject_set_name(&(this_object->kobj), "index%1lu", i);
+-		this_object->kobj.ktype = &cache_ktype;
+-		retval = kobject_register(&(this_object->kobj));
++		retval = kobject_init_and_add(&(this_object->kobj),
++					      &cache_ktype,
++					      &all_cpu_cache_info[cpu].kobj,
++					      "index%1lu", i);
+ 		if (unlikely(retval)) {
+ 			for (j = 0; j < i; j++) {
+-				kobject_unregister(
+-					&(LEAF_KOBJECT_PTR(cpu,j)->kobj));
++				kobject_put(&(LEAF_KOBJECT_PTR(cpu,j)->kobj));
+ 			}
+-			kobject_unregister(&all_cpu_cache_info[cpu].kobj);
++			kobject_put(&all_cpu_cache_info[cpu].kobj);
+ 			cpu_cache_sysfs_exit(cpu);
+ 			break;
+ 		}
++		kobject_uevent(&(this_object->kobj), KOBJ_ADD);
+ 	}
++	kobject_uevent(&all_cpu_cache_info[cpu].kobj, KOBJ_ADD);
+ 	return retval;
+ }
+ 
+@@ -385,10 +385,10 @@ static int __cpuinit cache_remove_dev(struct sys_device * sys_dev)
+ 	unsigned long i;
+ 
+ 	for (i = 0; i < all_cpu_cache_info[cpu].num_cache_leaves; i++)
+-		kobject_unregister(&(LEAF_KOBJECT_PTR(cpu,i)->kobj));
++		kobject_put(&(LEAF_KOBJECT_PTR(cpu,i)->kobj));
+ 
+ 	if (all_cpu_cache_info[cpu].kobj.parent) {
+-		kobject_unregister(&all_cpu_cache_info[cpu].kobj);
++		kobject_put(&all_cpu_cache_info[cpu].kobj);
+ 		memset(&all_cpu_cache_info[cpu].kobj,
+ 			0,
+ 			sizeof(struct kobject));
+diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
+index 1f38a3a..bb1d249 100644
+--- a/arch/ia64/sn/kernel/setup.c
++++ b/arch/ia64/sn/kernel/setup.c
+@@ -64,7 +64,6 @@ extern void sn_timer_init(void);
+ extern unsigned long last_time_offset;
+ extern void (*ia64_mark_idle) (int);
+ extern void snidle(int);
+-extern unsigned long long (*ia64_printk_clock)(void);
+ 
+ unsigned long sn_rtc_cycles_per_second;
+ EXPORT_SYMBOL(sn_rtc_cycles_per_second);
+@@ -360,14 +359,6 @@ sn_scan_pcdp(void)
+ 
+ static unsigned long sn2_rtc_initial;
+ 
+-static unsigned long long ia64_sn2_printk_clock(void)
+-{
+-	unsigned long rtc_now = rtc_time();
+-
+-	return (rtc_now - sn2_rtc_initial) *
+-		(1000000000 / sn_rtc_cycles_per_second);
+-}
+-
+ /**
+  * sn_setup - SN platform setup routine
+  * @cmdline_p: kernel command line
+@@ -468,8 +459,6 @@ void __init sn_setup(char **cmdline_p)
+ 
+ 	platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR;
+ 
+-	ia64_printk_clock = ia64_sn2_printk_clock;
+-
+ 	printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF);
+ 
+ 	/*
+diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c
+index d51e18f..841904c 100644
+--- a/arch/mips/au1000/common/platform.c
++++ b/arch/mips/au1000/common/platform.c
+@@ -270,6 +270,24 @@ static struct platform_device smc91x_device = {
+ 
+ #endif
+ 
++/* All Alchemy demoboards with I2C have this #define in their headers */
++#ifdef SMBUS_PSC_BASE
++static struct resource pbdb_smbus_resources[] = {
++	{
++		.start	= SMBUS_PSC_BASE,
++		.end	= SMBUS_PSC_BASE + 0x24 - 1,
++		.flags	= IORESOURCE_MEM,
++	},
++};
++
++static struct platform_device pbdb_smbus_device = {
++	.name		= "au1xpsc_smbus",
++	.id		= 0,	/* bus number */
++	.num_resources	= ARRAY_SIZE(pbdb_smbus_resources),
++	.resource	= pbdb_smbus_resources,
++};
++#endif
++
+ static struct platform_device *au1xxx_platform_devices[] __initdata = {
+ 	&au1xxx_usb_ohci_device,
+ 	&au1x00_pcmcia_device,
+@@ -287,6 +305,9 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = {
+ #ifdef CONFIG_MIPS_DB1200
+ 	&smc91x_device,
+ #endif
++#ifdef SMBUS_PSC_BASE
++	&pbdb_smbus_device,
++#endif
+ };
+ 
+ int __init au1xxx_platform_init(void)
+diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
+index 4710135..197d797 100644
+--- a/arch/mips/kernel/i8259.c
++++ b/arch/mips/kernel/i8259.c
+@@ -238,7 +238,7 @@ static int i8259A_shutdown(struct sys_device *dev)
+ }
+ 
+ static struct sysdev_class i8259_sysdev_class = {
+-	set_kset_name("i8259"),
++	.name = "i8259",
+ 	.resume = i8259A_resume,
+ 	.shutdown = i8259A_shutdown,
+ };
+diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c
+index 892665b..bb4f00c 100644
+--- a/arch/mips/kernel/mips-mt-fpaff.c
++++ b/arch/mips/kernel/mips-mt-fpaff.c
+@@ -58,13 +58,13 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
+ 	if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask)))
+ 		return -EFAULT;
+ 
+-	lock_cpu_hotplug();
++	get_online_cpus();
+ 	read_lock(&tasklist_lock);
+ 
+ 	p = find_process_by_pid(pid);
+ 	if (!p) {
+ 		read_unlock(&tasklist_lock);
+-		unlock_cpu_hotplug();
++		put_online_cpus();
+ 		return -ESRCH;
+ 	}
+ 
+@@ -106,7 +106,7 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
+ 
+ out_unlock:
+ 	put_task_struct(p);
+-	unlock_cpu_hotplug();
++	put_online_cpus();
+ 	return retval;
+ }
+ 
+@@ -125,7 +125,7 @@ asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len,
+ 	if (len < real_len)
+ 		return -EINVAL;
+ 
+-	lock_cpu_hotplug();
++	get_online_cpus();
+ 	read_lock(&tasklist_lock);
+ 
+ 	retval = -ESRCH;
+@@ -140,7 +140,7 @@ asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len,
+ 
+ out_unlock:
+ 	read_unlock(&tasklist_lock);
+-	unlock_cpu_hotplug();
++	put_online_cpus();
+ 	if (retval)
+ 		return retval;
+ 	if (copy_to_user(user_mask_ptr, &mask, real_len))
+diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
+index c83c3e3..a088622 100644
+--- a/arch/powerpc/platforms/cell/spu_base.c
++++ b/arch/powerpc/platforms/cell/spu_base.c
+@@ -459,7 +459,7 @@ static int spu_shutdown(struct sys_device *sysdev)
+ }
+ 
+ static struct sysdev_class spu_sysdev_class = {
+-	set_kset_name("spu"),
++	.name = "spu",
+ 	.shutdown = spu_shutdown,
+ };
+ 
+diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
+index 999f5e1..84c0d4e 100644
+--- a/arch/powerpc/platforms/powermac/pic.c
++++ b/arch/powerpc/platforms/powermac/pic.c
+@@ -663,7 +663,7 @@ static int pmacpic_resume(struct sys_device *sysdev)
+ #endif /* CONFIG_PM && CONFIG_PPC32 */
+ 
+ static struct sysdev_class pmacpic_sysclass = {
+-	set_kset_name("pmac_pic"),
++	.name = "pmac_pic",
+ };
+ 
+ static struct sys_device device_pmacpic = {
+diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
+index 412e6b4..c4ad54e 100644
+--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
++++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
+@@ -153,7 +153,7 @@ static int pseries_add_processor(struct device_node *np)
+ 	for (i = 0; i < nthreads; i++)
+ 		cpu_set(i, tmp);
+ 
+-	lock_cpu_hotplug();
++	cpu_maps_update_begin();
+ 
+ 	BUG_ON(!cpus_subset(cpu_present_map, cpu_possible_map));
+ 
+@@ -190,7 +190,7 @@ static int pseries_add_processor(struct device_node *np)
+ 	}
+ 	err = 0;
+ out_unlock:
+-	unlock_cpu_hotplug();
++	cpu_maps_update_done();
+ 	return err;
+ }
+ 
+@@ -211,7 +211,7 @@ static void pseries_remove_processor(struct device_node *np)
+ 
+ 	nthreads = len / sizeof(u32);
+ 
+-	lock_cpu_hotplug();
++	cpu_maps_update_begin();
+ 	for (i = 0; i < nthreads; i++) {
+ 		for_each_present_cpu(cpu) {
+ 			if (get_hard_smp_processor_id(cpu) != intserv[i])
+@@ -225,7 +225,7 @@ static void pseries_remove_processor(struct device_node *np)
+ 			printk(KERN_WARNING "Could not find cpu to remove "
+ 			       "with physical id 0x%x\n", intserv[i]);
+ 	}
+-	unlock_cpu_hotplug();
++	cpu_maps_update_done();
+ }
+ 
+ static int pseries_smp_notifier(struct notifier_block *nb,
+diff --git a/arch/powerpc/platforms/pseries/power.c b/arch/powerpc/platforms/pseries/power.c
+index 73e6902..e95fc15 100644
+--- a/arch/powerpc/platforms/pseries/power.c
++++ b/arch/powerpc/platforms/pseries/power.c
+@@ -28,13 +28,15 @@
+ 
+ unsigned long rtas_poweron_auto; /* default and normal state is 0 */
+ 
+-static ssize_t auto_poweron_show(struct kset *kset, char *buf)
++static ssize_t auto_poweron_show(struct kobject *kobj,
++				 struct kobj_attribute *attr, char *buf)
+ {
+         return sprintf(buf, "%lu\n", rtas_poweron_auto);
+ }
+ 
+-static ssize_t
+-auto_poweron_store(struct kset *kset, const char *buf, size_t n)
++static ssize_t auto_poweron_store(struct kobject *kobj,
++				  struct kobj_attribute *attr,
++				  const char *buf, size_t n)
+ {
+ 	int ret;
+ 	unsigned long ups_restart;
+@@ -47,17 +49,11 @@ auto_poweron_store(struct kset *kset, const char *buf, size_t n)
+ 	return -EINVAL;
+ }
+ 
+-static struct subsys_attribute auto_poweron_attr = {
+-        .attr   = {
+-                .name = __stringify(auto_poweron),
+-                .mode = 0644,
+-        },
+-        .show   = auto_poweron_show,
+-        .store  = auto_poweron_store,
+-};
++static struct kobj_attribute auto_poweron_attr =
++	__ATTR(auto_poweron, 0644, auto_poweron_show, auto_poweron_store);
+ 
+ #ifndef CONFIG_PM
+-decl_subsys(power,NULL,NULL);
++struct kobject *power_kobj;
+ 
+ static struct attribute *g[] = {
+         &auto_poweron_attr.attr,
+@@ -70,18 +66,16 @@ static struct attribute_group attr_group = {
+ 
+ static int __init pm_init(void)
+ {
+-        int error = subsystem_register(&power_subsys);
+-        if (!error)
+-                error = sysfs_create_group(&power_subsys.kobj, &attr_group);
+-        return error;
++	power_kobj = kobject_create_and_add("power", NULL);
++	if (!power_kobj)
++		return -ENOMEM;
++	return sysfs_create_group(power_kobj, &attr_group);
+ }
+ core_initcall(pm_init);
+ #else
+-extern struct kset power_subsys;
+-
+ static int __init apo_pm_init(void)
+ {
+-	return (subsys_create_file(&power_subsys, &auto_poweron_attr));
++	return (sysfs_create_file(power_kobj, &auto_poweron_attr));
+ }
+ __initcall(apo_pm_init);
+ #endif
+diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c
+index 73401c8..e3078ce 100644
+--- a/arch/powerpc/platforms/pseries/rtasd.c
++++ b/arch/powerpc/platforms/pseries/rtasd.c
+@@ -382,7 +382,7 @@ static void do_event_scan_all_cpus(long delay)
+ {
+ 	int cpu;
+ 
+-	lock_cpu_hotplug();
++	get_online_cpus();
+ 	cpu = first_cpu(cpu_online_map);
+ 	for (;;) {
+ 		set_cpus_allowed(current, cpumask_of_cpu(cpu));
+@@ -390,15 +390,15 @@ static void do_event_scan_all_cpus(long delay)
+ 		set_cpus_allowed(current, CPU_MASK_ALL);
+ 
+ 		/* Drop hotplug lock, and sleep for the specified delay */
+-		unlock_cpu_hotplug();
++		put_online_cpus();
+ 		msleep_interruptible(delay);
+-		lock_cpu_hotplug();
++		get_online_cpus();
+ 
+ 		cpu = next_cpu(cpu, cpu_online_map);
+ 		if (cpu == NR_CPUS)
+ 			break;
+ 	}
+-	unlock_cpu_hotplug();
++	put_online_cpus();
+ }
+ 
+ static int rtasd(void *unused)
+diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
+index 05a56e5..e898ff4 100644
+--- a/arch/powerpc/sysdev/ipic.c
++++ b/arch/powerpc/sysdev/ipic.c
+@@ -725,7 +725,7 @@ unsigned int ipic_get_irq(void)
+ }
+ 
+ static struct sysdev_class ipic_sysclass = {
+-	set_kset_name("ipic"),
++	.name = "ipic",
+ };
+ 
+ static struct sys_device device_ipic = {
+diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
+index e479388..212a94f 100644
+--- a/arch/powerpc/sysdev/mpic.c
++++ b/arch/powerpc/sysdev/mpic.c
+@@ -1584,7 +1584,7 @@ static struct sysdev_class mpic_sysclass = {
+ 	.resume = mpic_resume,
+ 	.suspend = mpic_suspend,
+ #endif
+-	set_kset_name("mpic"),
++	.name = "mpic",
+ };
+ 
+ static int mpic_init_sys(void)
+diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
+index e1c0fd6..f59444d 100644
+--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
++++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
+@@ -483,7 +483,7 @@ int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high)
+ }
+ 
+ static struct sysdev_class qe_ic_sysclass = {
+-	set_kset_name("qe_ic"),
++	.name = "qe_ic",
+ };
+ 
+ static struct sys_device device_qe_ic = {
+diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c
+index b84f8df..cb0a749 100644
+--- a/arch/ppc/platforms/83xx/mpc834x_sys.c
++++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
+@@ -224,26 +224,6 @@ mpc834x_sys_init_IRQ(void)
+ 	ipic_set_default_priority();
+ }
+ 
+-#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
+-extern ulong	ds1374_get_rtc_time(void);
+-extern int	ds1374_set_rtc_time(ulong);
+-
+-static int __init
+-mpc834x_rtc_hookup(void)
+-{
+-	struct timespec	tv;
+-
+-	ppc_md.get_rtc_time = ds1374_get_rtc_time;
+-	ppc_md.set_rtc_time = ds1374_set_rtc_time;
+-
+-	tv.tv_nsec = 0;
+-	tv.tv_sec = (ppc_md.get_rtc_time)();
+-	do_settimeofday(&tv);
+-
+-	return 0;
+-}
+-late_initcall(mpc834x_rtc_hookup);
+-#endif
+ static __inline__ void
+ mpc834x_sys_set_bat(void)
+ {
+diff --git a/arch/ppc/platforms/85xx/tqm85xx.c b/arch/ppc/platforms/85xx/tqm85xx.c
+index 4ee2bd1..27ce389 100644
+--- a/arch/ppc/platforms/85xx/tqm85xx.c
++++ b/arch/ppc/platforms/85xx/tqm85xx.c
+@@ -258,27 +258,6 @@ int tqm85xx_show_cpuinfo(struct seq_file *m)
+ 	return 0;
+ }
+ 
+-#if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_DS1337)
+-extern ulong ds1337_get_rtc_time(void);
+-extern int ds1337_set_rtc_time(unsigned long nowtime);
+-
+-static int __init
+-tqm85xx_rtc_hookup(void)
+-{
+-	struct timespec	tv;
+-
+-        ppc_md.set_rtc_time = ds1337_set_rtc_time;
+-        ppc_md.get_rtc_time = ds1337_get_rtc_time;
+-
+-	tv.tv_nsec = 0;
+-	tv.tv_sec = (ppc_md.get_rtc_time)();
+-	do_settimeofday(&tv);
+-
+-	return 0;
+-}
+-late_initcall(tqm85xx_rtc_hookup);
+-#endif
+-
+ #ifdef CONFIG_PCI
+ /*
+  * interrupt routing
+diff --git a/arch/ppc/platforms/katana.c b/arch/ppc/platforms/katana.c
+index 52f63e6..fe6e88c 100644
+--- a/arch/ppc/platforms/katana.c
++++ b/arch/ppc/platforms/katana.c
+@@ -838,27 +838,6 @@ katana_find_end_of_memory(void)
+ 	return bdp->bi_memsize;
+ }
+ 
+-#if defined(CONFIG_I2C_MV64XXX) && defined(CONFIG_SENSORS_M41T00)
+-extern ulong	m41t00_get_rtc_time(void);
+-extern int	m41t00_set_rtc_time(ulong);
+-
+-static int __init
+-katana_rtc_hookup(void)
+-{
+-	struct timespec	tv;
+-
+-	ppc_md.get_rtc_time = m41t00_get_rtc_time;
+-	ppc_md.set_rtc_time = m41t00_set_rtc_time;
+-
+-	tv.tv_nsec = 0;
+-	tv.tv_sec = (ppc_md.get_rtc_time)();
+-	do_settimeofday(&tv);
+-
+-	return 0;
+-}
+-late_initcall(katana_rtc_hookup);
+-#endif
+-
+ #if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE)
+ static void __init
+ katana_map_io(void)
+diff --git a/arch/ppc/syslib/ipic.c b/arch/ppc/syslib/ipic.c
+index 9192777..4f163e2 100644
+--- a/arch/ppc/syslib/ipic.c
++++ b/arch/ppc/syslib/ipic.c
+@@ -614,7 +614,7 @@ int ipic_get_irq(void)
+ }
+ 
+ static struct sysdev_class ipic_sysclass = {
+-	set_kset_name("ipic"),
++	.name = "ipic",
+ };
+ 
+ static struct sys_device device_ipic = {
+diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c
+index 18ec947..da36522 100644
+--- a/arch/ppc/syslib/open_pic.c
++++ b/arch/ppc/syslib/open_pic.c
+@@ -1043,7 +1043,7 @@ int openpic_resume(struct sys_device *sysdev)
+ #endif /* CONFIG_PM */
+ 
+ static struct sysdev_class openpic_sysclass = {
+-	set_kset_name("openpic"),
++	.name = "openpic",
+ };
+ 
+ static struct sys_device device_openpic = {
+diff --git a/arch/ppc/syslib/open_pic2.c b/arch/ppc/syslib/open_pic2.c
+index d585207..449075a 100644
+--- a/arch/ppc/syslib/open_pic2.c
++++ b/arch/ppc/syslib/open_pic2.c
+@@ -666,7 +666,7 @@ int openpic2_resume(struct sys_device *sysdev)
+ 
+ /* HACK ALERT */
+ static struct sysdev_class openpic2_sysclass = {
+-	set_kset_name("openpic2"),
++	.name = "openpic2",
+ };
+ 
+ static struct sys_device device_openpic2 = {
+diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
+index 1330061..6ef54d2 100644
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -276,9 +276,6 @@ source "kernel/Kconfig.preempt"
+ 
+ source "mm/Kconfig"
+ 
+-config HOLES_IN_ZONE
+-	def_bool y
+-
+ comment "I/O subsystem configuration"
+ 
+ config MACHCHK_WARNING
+diff --git a/arch/s390/crypto/Kconfig b/arch/s390/crypto/Kconfig
+deleted file mode 100644
+index d1defbb..0000000
+--- a/arch/s390/crypto/Kconfig
++++ /dev/null
+@@ -1,60 +0,0 @@
+-config CRYPTO_SHA1_S390
+-	tristate "SHA1 digest algorithm"
+-	depends on S390
+-	select CRYPTO_ALGAPI
+-	help
+-	  This is the s390 hardware accelerated implementation of the
+-	  SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
+-
+-config CRYPTO_SHA256_S390
+-	tristate "SHA256 digest algorithm"
+-	depends on S390
+-	select CRYPTO_ALGAPI
+-	help
+-	  This is the s390 hardware accelerated implementation of the
+-	  SHA256 secure hash standard (DFIPS 180-2).
+-
+-	  This version of SHA implements a 256 bit hash with 128 bits of
+-	  security against collision attacks.
+-
+-config CRYPTO_DES_S390
+-	tristate "DES and Triple DES cipher algorithms"
+-	depends on S390
+-	select CRYPTO_ALGAPI
+-	select CRYPTO_BLKCIPHER
+-	help
+-	  This us the s390 hardware accelerated implementation of the
+-	  DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
+-
+-config CRYPTO_AES_S390
+-	tristate "AES cipher algorithms"
+-	depends on S390
+-	select CRYPTO_ALGAPI
+-	select CRYPTO_BLKCIPHER
+-	help
+-	  This is the s390 hardware accelerated implementation of the
+-	  AES cipher algorithms (FIPS-197). AES uses the Rijndael
+-	  algorithm.
+-
+-	  Rijndael appears to be consistently a very good performer in
+-	  both hardware and software across a wide range of computing
+-	  environments regardless of its use in feedback or non-feedback
+-	  modes. Its key setup time is excellent, and its key agility is
+-	  good. Rijndael's very low memory requirements make it very well
+-	  suited for restricted-space environments, in which it also
+-	  demonstrates excellent performance. Rijndael's operations are
+-	  among the easiest to defend against power and timing attacks.
+-
+-	  On s390 the System z9-109 currently only supports the key size
+-	  of 128 bit.
+-
+-config S390_PRNG
+-	tristate "Pseudo random number generator device driver"
+-	depends on S390
+-	default "m"
+-	help
+-	  Select this option if you want to use the s390 pseudo random number
+-	  generator. The PRNG is part of the cryptographic processor functions
+-	  and uses triple-DES to generate secure random numbers like the
+-	  ANSI X9.17 standard. The PRNG is usable via the char device
+-	  /dev/prandom.
+diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c
+index 5126696..a3f67f8 100644
+--- a/arch/s390/crypto/aes_s390.c
++++ b/arch/s390/crypto/aes_s390.c
+@@ -6,6 +6,7 @@
+  * s390 Version:
+  *   Copyright IBM Corp. 2005,2007
+  *   Author(s): Jan Glauber (jang at de.ibm.com)
++ *		Sebastian Siewior (sebastian at breakpoint.cc> SW-Fallback
+  *
+  * Derived from "crypto/aes_generic.c"
+  *
+@@ -16,17 +17,13 @@
+  *
+  */
+ 
++#include <crypto/aes.h>
+ #include <crypto/algapi.h>
++#include <linux/err.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include "crypt_s390.h"
+ 
+-#define AES_MIN_KEY_SIZE	16
+-#define AES_MAX_KEY_SIZE	32
+-
+-/* data block size for all key lengths */
+-#define AES_BLOCK_SIZE		16
+-
+ #define AES_KEYLEN_128		1
+ #define AES_KEYLEN_192		2
+ #define AES_KEYLEN_256		4
+@@ -39,45 +36,89 @@ struct s390_aes_ctx {
+ 	long enc;
+ 	long dec;
+ 	int key_len;
++	union {
++		struct crypto_blkcipher *blk;
++		struct crypto_cipher *cip;
++	} fallback;
+ };
+ 
+-static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+-		       unsigned int key_len)
++/*
++ * Check if the key_len is supported by the HW.
++ * Returns 0 if it is, a positive number if it is not and software fallback is
++ * required or a negative number in case the key size is not valid
++ */
++static int need_fallback(unsigned int key_len)
+ {
+-	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
+-	u32 *flags = &tfm->crt_flags;
+-
+ 	switch (key_len) {
+ 	case 16:
+ 		if (!(keylen_flag & AES_KEYLEN_128))
+-			goto fail;
++			return 1;
+ 		break;
+ 	case 24:
+ 		if (!(keylen_flag & AES_KEYLEN_192))
+-			goto fail;
+-
++			return 1;
+ 		break;
+ 	case 32:
+ 		if (!(keylen_flag & AES_KEYLEN_256))
+-			goto fail;
++			return 1;
+ 		break;
+ 	default:
+-		goto fail;
++		return -1;
+ 		break;
+ 	}
++	return 0;
 +}
 +
-+static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
++static int setkey_fallback_cip(struct crypto_tfm *tfm, const u8 *in_key,
++		unsigned int key_len)
 +{
-+	aes_dec_blk(tfm, dst, src);
++	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
++	int ret;
++
++	sctx->fallback.blk->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
++	sctx->fallback.blk->base.crt_flags |= (tfm->crt_flags &
++			CRYPTO_TFM_REQ_MASK);
++
++	ret = crypto_cipher_setkey(sctx->fallback.cip, in_key, key_len);
++	if (ret) {
++		tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
++		tfm->crt_flags |= (sctx->fallback.blk->base.crt_flags &
++				CRYPTO_TFM_RES_MASK);
++	}
++	return ret;
 +}
 +
-+static struct crypto_alg aes_alg = {
-+	.cra_name		= "aes",
-+	.cra_driver_name	= "aes-asm",
-+	.cra_priority		= 200,
-+	.cra_flags		= CRYPTO_ALG_TYPE_CIPHER,
-+	.cra_blocksize		= AES_BLOCK_SIZE,
-+	.cra_ctxsize		= sizeof(struct crypto_aes_ctx),
-+	.cra_module		= THIS_MODULE,
-+	.cra_list		= LIST_HEAD_INIT(aes_alg.cra_list),
-+	.cra_u	= {
-+		.cipher	= {
-+			.cia_min_keysize	= AES_MIN_KEY_SIZE,
-+			.cia_max_keysize	= AES_MAX_KEY_SIZE,
-+			.cia_setkey		= crypto_aes_set_key,
-+			.cia_encrypt		= aes_encrypt,
-+			.cia_decrypt		= aes_decrypt
-+		}
++static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
++		       unsigned int key_len)
++{
++	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
++	u32 *flags = &tfm->crt_flags;
++	int ret;
++
++	ret = need_fallback(key_len);
++	if (ret < 0) {
++		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
++		return -EINVAL;
++	}
+ 
+ 	sctx->key_len = key_len;
+-	memcpy(sctx->key, in_key, key_len);
+-	return 0;
+-fail:
+-	*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+-	return -EINVAL;
++	if (!ret) {
++		memcpy(sctx->key, in_key, key_len);
++		return 0;
 +	}
-+};
 +
-+static int __init aes_init(void)
++	return setkey_fallback_cip(tfm, in_key, key_len);
+ }
+ 
+ static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
+ {
+ 	const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
+ 
++	if (unlikely(need_fallback(sctx->key_len))) {
++		crypto_cipher_encrypt_one(sctx->fallback.cip, out, in);
++		return;
++	}
++
+ 	switch (sctx->key_len) {
+ 	case 16:
+ 		crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in,
+@@ -98,6 +139,11 @@ static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
+ {
+ 	const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
+ 
++	if (unlikely(need_fallback(sctx->key_len))) {
++		crypto_cipher_decrypt_one(sctx->fallback.cip, out, in);
++		return;
++	}
++
+ 	switch (sctx->key_len) {
+ 	case 16:
+ 		crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in,
+@@ -114,6 +160,29 @@ static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
+ 	}
+ }
+ 
++static int fallback_init_cip(struct crypto_tfm *tfm)
 +{
-+	return crypto_register_alg(&aes_alg);
++	const char *name = tfm->__crt_alg->cra_name;
++	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
++
++	sctx->fallback.cip = crypto_alloc_cipher(name, 0,
++			CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK);
++
++	if (IS_ERR(sctx->fallback.cip)) {
++		printk(KERN_ERR "Error allocating fallback algo %s\n", name);
++		return PTR_ERR(sctx->fallback.blk);
++	}
++
++	return 0;
 +}
 +
-+static void __exit aes_fini(void)
++static void fallback_exit_cip(struct crypto_tfm *tfm)
 +{
-+	crypto_unregister_alg(&aes_alg);
++	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
++
++	crypto_free_cipher(sctx->fallback.cip);
++	sctx->fallback.cip = NULL;
 +}
+ 
+ static struct crypto_alg aes_alg = {
+ 	.cra_name		=	"aes",
+@@ -125,6 +194,8 @@ static struct crypto_alg aes_alg = {
+ 	.cra_ctxsize		=	sizeof(struct s390_aes_ctx),
+ 	.cra_module		=	THIS_MODULE,
+ 	.cra_list		=	LIST_HEAD_INIT(aes_alg.cra_list),
++	.cra_init               =       fallback_init_cip,
++	.cra_exit               =       fallback_exit_cip,
+ 	.cra_u			=	{
+ 		.cipher = {
+ 			.cia_min_keysize	=	AES_MIN_KEY_SIZE,
+@@ -136,10 +207,70 @@ static struct crypto_alg aes_alg = {
+ 	}
+ };
+ 
++static int setkey_fallback_blk(struct crypto_tfm *tfm, const u8 *key,
++		unsigned int len)
++{
++	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
++	unsigned int ret;
 +
-+module_init(aes_init);
-+module_exit(aes_fini);
++	sctx->fallback.blk->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
++	sctx->fallback.blk->base.crt_flags |= (tfm->crt_flags &
++			CRYPTO_TFM_REQ_MASK);
 +
-+MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm, asm optimized");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("aes");
-+MODULE_ALIAS("aes-asm");
-diff --git a/arch/x86/crypto/salsa20-i586-asm_32.S b/arch/x86/crypto/salsa20-i586-asm_32.S
-new file mode 100644
-index 0000000..72eb306
---- /dev/null
-+++ b/arch/x86/crypto/salsa20-i586-asm_32.S
-@@ -0,0 +1,1114 @@
-+# salsa20_pm.s version 20051229
-+# D. J. Bernstein
-+# Public domain.
++	ret = crypto_blkcipher_setkey(sctx->fallback.blk, key, len);
++	if (ret) {
++		tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
++		tfm->crt_flags |= (sctx->fallback.blk->base.crt_flags &
++				CRYPTO_TFM_RES_MASK);
++	}
++	return ret;
++}
 +
-+# enter ECRYPT_encrypt_bytes
-+.text
-+.p2align 5
-+.globl ECRYPT_encrypt_bytes
-+ECRYPT_encrypt_bytes:
-+	mov	%esp,%eax
-+	and	$31,%eax
-+	add	$256,%eax
-+	sub	%eax,%esp
-+	# eax_stack = eax
-+	movl	%eax,80(%esp)
-+	# ebx_stack = ebx
-+	movl	%ebx,84(%esp)
-+	# esi_stack = esi
-+	movl	%esi,88(%esp)
-+	# edi_stack = edi
-+	movl	%edi,92(%esp)
-+	# ebp_stack = ebp
-+	movl	%ebp,96(%esp)
-+	# x = arg1
-+	movl	4(%esp,%eax),%edx
-+	# m = arg2
-+	movl	8(%esp,%eax),%esi
++static int fallback_blk_dec(struct blkcipher_desc *desc,
++		struct scatterlist *dst, struct scatterlist *src,
++		unsigned int nbytes)
++{
++	unsigned int ret;
++	struct crypto_blkcipher *tfm;
++	struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
++
++	tfm = desc->tfm;
++	desc->tfm = sctx->fallback.blk;
++
++	ret = crypto_blkcipher_decrypt_iv(desc, dst, src, nbytes);
++
++	desc->tfm = tfm;
++	return ret;
++}
++
++static int fallback_blk_enc(struct blkcipher_desc *desc,
++		struct scatterlist *dst, struct scatterlist *src,
++		unsigned int nbytes)
++{
++	unsigned int ret;
++	struct crypto_blkcipher *tfm;
++	struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
++
++	tfm = desc->tfm;
++	desc->tfm = sctx->fallback.blk;
++
++	ret = crypto_blkcipher_encrypt_iv(desc, dst, src, nbytes);
++
++	desc->tfm = tfm;
++	return ret;
++}
++
+ static int ecb_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+ 			   unsigned int key_len)
+ {
+ 	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
++	int ret;
++
++	ret = need_fallback(key_len);
++	if (ret > 0) {
++		sctx->key_len = key_len;
++		return setkey_fallback_blk(tfm, in_key, key_len);
++	}
+ 
+ 	switch (key_len) {
+ 	case 16:
+@@ -188,6 +319,9 @@ static int ecb_aes_encrypt(struct blkcipher_desc *desc,
+ 	struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+ 	struct blkcipher_walk walk;
+ 
++	if (unlikely(need_fallback(sctx->key_len)))
++		return fallback_blk_enc(desc, dst, src, nbytes);
++
+ 	blkcipher_walk_init(&walk, dst, src, nbytes);
+ 	return ecb_aes_crypt(desc, sctx->enc, sctx->key, &walk);
+ }
+@@ -199,10 +333,37 @@ static int ecb_aes_decrypt(struct blkcipher_desc *desc,
+ 	struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+ 	struct blkcipher_walk walk;
+ 
++	if (unlikely(need_fallback(sctx->key_len)))
++		return fallback_blk_dec(desc, dst, src, nbytes);
++
+ 	blkcipher_walk_init(&walk, dst, src, nbytes);
+ 	return ecb_aes_crypt(desc, sctx->dec, sctx->key, &walk);
+ }
+ 
++static int fallback_init_blk(struct crypto_tfm *tfm)
++{
++	const char *name = tfm->__crt_alg->cra_name;
++	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
++
++	sctx->fallback.blk = crypto_alloc_blkcipher(name, 0,
++			CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK);
++
++	if (IS_ERR(sctx->fallback.blk)) {
++		printk(KERN_ERR "Error allocating fallback algo %s\n", name);
++		return PTR_ERR(sctx->fallback.blk);
++	}
++
++	return 0;
++}
++
++static void fallback_exit_blk(struct crypto_tfm *tfm)
++{
++	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
++
++	crypto_free_blkcipher(sctx->fallback.blk);
++	sctx->fallback.blk = NULL;
++}
++
+ static struct crypto_alg ecb_aes_alg = {
+ 	.cra_name		=	"ecb(aes)",
+ 	.cra_driver_name	=	"ecb-aes-s390",
+@@ -214,6 +375,8 @@ static struct crypto_alg ecb_aes_alg = {
+ 	.cra_type		=	&crypto_blkcipher_type,
+ 	.cra_module		=	THIS_MODULE,
+ 	.cra_list		=	LIST_HEAD_INIT(ecb_aes_alg.cra_list),
++	.cra_init		=	fallback_init_blk,
++	.cra_exit		=	fallback_exit_blk,
+ 	.cra_u			=	{
+ 		.blkcipher = {
+ 			.min_keysize		=	AES_MIN_KEY_SIZE,
+@@ -229,6 +392,13 @@ static int cbc_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+ 			   unsigned int key_len)
+ {
+ 	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
++	int ret;
++
++	ret = need_fallback(key_len);
++	if (ret > 0) {
++		sctx->key_len = key_len;
++		return setkey_fallback_blk(tfm, in_key, key_len);
++	}
+ 
+ 	switch (key_len) {
+ 	case 16:
+@@ -283,6 +453,9 @@ static int cbc_aes_encrypt(struct blkcipher_desc *desc,
+ 	struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+ 	struct blkcipher_walk walk;
+ 
++	if (unlikely(need_fallback(sctx->key_len)))
++		return fallback_blk_enc(desc, dst, src, nbytes);
++
+ 	blkcipher_walk_init(&walk, dst, src, nbytes);
+ 	return cbc_aes_crypt(desc, sctx->enc, sctx->iv, &walk);
+ }
+@@ -294,6 +467,9 @@ static int cbc_aes_decrypt(struct blkcipher_desc *desc,
+ 	struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+ 	struct blkcipher_walk walk;
+ 
++	if (unlikely(need_fallback(sctx->key_len)))
++		return fallback_blk_dec(desc, dst, src, nbytes);
++
+ 	blkcipher_walk_init(&walk, dst, src, nbytes);
+ 	return cbc_aes_crypt(desc, sctx->dec, sctx->iv, &walk);
+ }
+@@ -309,6 +485,8 @@ static struct crypto_alg cbc_aes_alg = {
+ 	.cra_type		=	&crypto_blkcipher_type,
+ 	.cra_module		=	THIS_MODULE,
+ 	.cra_list		=	LIST_HEAD_INIT(cbc_aes_alg.cra_list),
++	.cra_init		=	fallback_init_blk,
++	.cra_exit		=	fallback_exit_blk,
+ 	.cra_u			=	{
+ 		.blkcipher = {
+ 			.min_keysize		=	AES_MIN_KEY_SIZE,
+@@ -336,14 +514,10 @@ static int __init aes_init(void)
+ 		return -EOPNOTSUPP;
+ 
+ 	/* z9 109 and z9 BC/EC only support 128 bit key length */
+-	if (keylen_flag == AES_KEYLEN_128) {
+-		aes_alg.cra_u.cipher.cia_max_keysize = AES_MIN_KEY_SIZE;
+-		ecb_aes_alg.cra_u.blkcipher.max_keysize = AES_MIN_KEY_SIZE;
+-		cbc_aes_alg.cra_u.blkcipher.max_keysize = AES_MIN_KEY_SIZE;
++	if (keylen_flag == AES_KEYLEN_128)
+ 		printk(KERN_INFO
+-		       "aes_s390: hardware acceleration only available for"
++		       "aes_s390: hardware acceleration only available for "
+ 		       "128 bit keys\n");
+-	}
+ 
+ 	ret = crypto_register_alg(&aes_alg);
+ 	if (ret)
+@@ -382,4 +556,3 @@ MODULE_ALIAS("aes");
+ 
+ MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
+ MODULE_LICENSE("GPL");
+-
+diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c
+index 8eb3a1a..0cfefdd 100644
+--- a/arch/s390/crypto/prng.c
++++ b/arch/s390/crypto/prng.c
+@@ -90,7 +90,7 @@ static ssize_t prng_read(struct file *file, char __user *ubuf, size_t nbytes,
+ 	int ret = 0;
+ 	int tmp;
+ 
+-	/* nbytes can be arbitrary long, we spilt it into chunks */
++	/* nbytes can be arbitrary length, we split it into chunks */
+ 	while (nbytes) {
+ 		/* same as in extract_entropy_user in random.c */
+ 		if (need_resched()) {
+@@ -146,7 +146,7 @@ static ssize_t prng_read(struct file *file, char __user *ubuf, size_t nbytes,
+ 	return ret;
+ }
+ 
+-static struct file_operations prng_fops = {
++static const struct file_operations prng_fops = {
+ 	.owner		= THIS_MODULE,
+ 	.open		= &prng_open,
+ 	.release	= NULL,
+diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
+index 5245717..4b010ff 100644
+--- a/arch/s390/hypfs/inode.c
++++ b/arch/s390/hypfs/inode.c
+@@ -490,7 +490,7 @@ static struct super_operations hypfs_s_ops = {
+ 	.show_options	= hypfs_show_options,
+ };
+ 
+-static decl_subsys(s390, NULL, NULL);
++static struct kobject *s390_kobj;
+ 
+ static int __init hypfs_init(void)
+ {
+@@ -506,17 +506,18 @@ static int __init hypfs_init(void)
+ 			goto fail_diag;
+ 		}
+ 	}
+-	kobj_set_kset_s(&s390_subsys, hypervisor_subsys);
+-	rc = subsystem_register(&s390_subsys);
+-	if (rc)
++	s390_kobj = kobject_create_and_add("s390", hypervisor_kobj);
++	if (!s390_kobj) {
++		rc = -ENOMEM;;
+ 		goto fail_sysfs;
++	}
+ 	rc = register_filesystem(&hypfs_type);
+ 	if (rc)
+ 		goto fail_filesystem;
+ 	return 0;
+ 
+ fail_filesystem:
+-	subsystem_unregister(&s390_subsys);
++	kobject_put(s390_kobj);
+ fail_sysfs:
+ 	if (!MACHINE_IS_VM)
+ 		hypfs_diag_exit();
+@@ -530,7 +531,7 @@ static void __exit hypfs_exit(void)
+ 	if (!MACHINE_IS_VM)
+ 		hypfs_diag_exit();
+ 	unregister_filesystem(&hypfs_type);
+-	subsystem_unregister(&s390_subsys);
++	kobject_put(s390_kobj);
+ }
+ 
+ module_init(hypfs_init)
+diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
+index 56cb710..b3b650a 100644
+--- a/arch/s390/kernel/Makefile
++++ b/arch/s390/kernel/Makefile
+@@ -31,7 +31,3 @@ S390_KEXEC_OBJS := machine_kexec.o crash.o
+ S390_KEXEC_OBJS += $(if $(CONFIG_64BIT),relocate_kernel64.o,relocate_kernel.o)
+ obj-$(CONFIG_KEXEC) += $(S390_KEXEC_OBJS)
+ 
+-#
+-# This is just to get the dependencies...
+-#
+-binfmt_elf32.o:	$(TOPDIR)/fs/binfmt_elf.c
+diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
+index 1b3af7d..9f7b73b 100644
+--- a/arch/s390/kernel/early.c
++++ b/arch/s390/kernel/early.c
+@@ -276,7 +276,7 @@ void __init startup_init(void)
+ 	create_kernel_nss();
+ 	sort_main_extable();
+ 	setup_lowcore_early();
+-	sclp_readinfo_early();
++	sclp_read_info_early();
+ 	sclp_facilities_detect();
+ 	memsize = sclp_memory_detect();
+ #ifndef CONFIG_64BIT
+diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
+index a87b197..79dccd2 100644
+--- a/arch/s390/kernel/head64.S
++++ b/arch/s390/kernel/head64.S
+@@ -157,7 +157,7 @@ startup_continue:
+ 	.long	0xb2b10000		# store facility list
+ 	tm	0xc8,0x08		# check bit for clearing-by-ASCE
+ 	bno	0f-.LPG1(%r13)
+-	lhi	%r1,2094
++	lhi	%r1,2048
+ 	lhi	%r2,0
+ 	.long	0xb98e2001
+ 	oi	7(%r12),0x80		# set IDTE flag
+diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
+index ce0856d..db28cca 100644
+--- a/arch/s390/kernel/ipl.c
++++ b/arch/s390/kernel/ipl.c
+@@ -2,7 +2,7 @@
+  *  arch/s390/kernel/ipl.c
+  *    ipl/reipl/dump support for Linux on s390.
+  *
+- *    Copyright (C) IBM Corp. 2005,2006
++ *    Copyright IBM Corp. 2005,2007
+  *    Author(s): Michael Holzheu <holzheu at de.ibm.com>
+  *		 Heiko Carstens <heiko.carstens at de.ibm.com>
+  *		 Volker Sameske <sameske at de.ibm.com>
+@@ -31,6 +31,43 @@
+ #define IPL_FCP_DUMP_STR	"fcp_dump"
+ #define IPL_NSS_STR		"nss"
+ 
++#define DUMP_CCW_STR		"ccw"
++#define DUMP_FCP_STR		"fcp"
++#define DUMP_NONE_STR		"none"
++
++/*
++ * Four shutdown trigger types are supported:
++ * - panic
++ * - halt
++ * - power off
++ * - reipl
++ */
++#define ON_PANIC_STR		"on_panic"
++#define ON_HALT_STR		"on_halt"
++#define ON_POFF_STR		"on_poff"
++#define ON_REIPL_STR		"on_reboot"
++
++struct shutdown_action;
++struct shutdown_trigger {
++	char *name;
++	struct shutdown_action *action;
++};
++
++/*
++ * Five shutdown action types are supported:
++ */
++#define SHUTDOWN_ACTION_IPL_STR		"ipl"
++#define SHUTDOWN_ACTION_REIPL_STR	"reipl"
++#define SHUTDOWN_ACTION_DUMP_STR	"dump"
++#define SHUTDOWN_ACTION_VMCMD_STR	"vmcmd"
++#define SHUTDOWN_ACTION_STOP_STR	"stop"
++
++struct shutdown_action {
++	char *name;
++	void (*fn) (struct shutdown_trigger *trigger);
++	int (*init) (void);
++};
++
+ static char *ipl_type_str(enum ipl_type type)
+ {
+ 	switch (type) {
+@@ -54,10 +91,6 @@ enum dump_type {
+ 	DUMP_TYPE_FCP	= 4,
+ };
+ 
+-#define DUMP_NONE_STR	 "none"
+-#define DUMP_CCW_STR	 "ccw"
+-#define DUMP_FCP_STR	 "fcp"
+-
+ static char *dump_type_str(enum dump_type type)
+ {
+ 	switch (type) {
+@@ -99,30 +132,6 @@ enum dump_method {
+ 	DUMP_METHOD_FCP_DIAG,
+ };
+ 
+-enum shutdown_action {
+-	SHUTDOWN_REIPL,
+-	SHUTDOWN_DUMP,
+-	SHUTDOWN_STOP,
+-};
+-
+-#define SHUTDOWN_REIPL_STR "reipl"
+-#define SHUTDOWN_DUMP_STR  "dump"
+-#define SHUTDOWN_STOP_STR  "stop"
+-
+-static char *shutdown_action_str(enum shutdown_action action)
+-{
+-	switch (action) {
+-	case SHUTDOWN_REIPL:
+-		return SHUTDOWN_REIPL_STR;
+-	case SHUTDOWN_DUMP:
+-		return SHUTDOWN_DUMP_STR;
+-	case SHUTDOWN_STOP:
+-		return SHUTDOWN_STOP_STR;
+-	default:
+-		return NULL;
+-	}
+-}
+-
+ static int diag308_set_works = 0;
+ 
+ static int reipl_capabilities = IPL_TYPE_UNKNOWN;
+@@ -140,8 +149,6 @@ static enum dump_method dump_method = DUMP_METHOD_NONE;
+ static struct ipl_parameter_block *dump_block_fcp;
+ static struct ipl_parameter_block *dump_block_ccw;
+ 
+-static enum shutdown_action on_panic_action = SHUTDOWN_STOP;
+-
+ static struct sclp_ipl_info sclp_ipl_info;
+ 
+ int diag308(unsigned long subcode, void *addr)
+@@ -162,22 +169,25 @@ EXPORT_SYMBOL_GPL(diag308);
+ /* SYSFS */
+ 
+ #define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value)		\
+-static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset,	\
++static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj,	\
++		struct kobj_attribute *attr,				\
+ 		char *page)						\
+ {									\
+ 	return sprintf(page, _format, _value);				\
+ }									\
+-static struct subsys_attribute sys_##_prefix##_##_name##_attr =		\
++static struct kobj_attribute sys_##_prefix##_##_name##_attr =		\
+ 	__ATTR(_name, S_IRUGO, sys_##_prefix##_##_name##_show, NULL);
+ 
+ #define DEFINE_IPL_ATTR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)	\
+-static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset,	\
++static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj,	\
++		struct kobj_attribute *attr,				\
+ 		char *page)						\
+ {									\
+ 	return sprintf(page, _fmt_out,					\
+ 			(unsigned long long) _value);			\
+ }									\
+-static ssize_t sys_##_prefix##_##_name##_store(struct kset *kset,	\
++static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj,	\
++		struct kobj_attribute *attr,				\
+ 		const char *buf, size_t len)				\
+ {									\
+ 	unsigned long long value;					\
+@@ -186,25 +196,27 @@ static ssize_t sys_##_prefix##_##_name##_store(struct kset *kset,	\
+ 	_value = value;							\
+ 	return len;							\
+ }									\
+-static struct subsys_attribute sys_##_prefix##_##_name##_attr =		\
++static struct kobj_attribute sys_##_prefix##_##_name##_attr =		\
+ 	__ATTR(_name,(S_IRUGO | S_IWUSR),				\
+ 			sys_##_prefix##_##_name##_show,			\
+ 			sys_##_prefix##_##_name##_store);
+ 
+ #define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\
+-static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset,	\
++static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj,	\
++		struct kobj_attribute *attr,				\
+ 		char *page)						\
+ {									\
+ 	return sprintf(page, _fmt_out, _value);				\
+ }									\
+-static ssize_t sys_##_prefix##_##_name##_store(struct kset *kset,	\
++static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj,	\
++		struct kobj_attribute *attr,				\
+ 		const char *buf, size_t len)				\
+ {									\
+-	if (sscanf(buf, _fmt_in, _value) != 1)				\
+-		return -EINVAL;						\
++	strncpy(_value, buf, sizeof(_value) - 1);			\
++	strstrip(_value);						\
+ 	return len;							\
+ }									\
+-static struct subsys_attribute sys_##_prefix##_##_name##_attr =		\
++static struct kobj_attribute sys_##_prefix##_##_name##_attr =		\
+ 	__ATTR(_name,(S_IRUGO | S_IWUSR),				\
+ 			sys_##_prefix##_##_name##_show,			\
+ 			sys_##_prefix##_##_name##_store);
+@@ -240,44 +252,19 @@ static __init enum ipl_type get_ipl_type(void)
+ 	return IPL_TYPE_FCP;
+ }
+ 
+-void __init setup_ipl_info(void)
+-{
+-	ipl_info.type = get_ipl_type();
+-	switch (ipl_info.type) {
+-	case IPL_TYPE_CCW:
+-		ipl_info.data.ccw.dev_id.devno = ipl_devno;
+-		ipl_info.data.ccw.dev_id.ssid = 0;
+-		break;
+-	case IPL_TYPE_FCP:
+-	case IPL_TYPE_FCP_DUMP:
+-		ipl_info.data.fcp.dev_id.devno =
+-			IPL_PARMBLOCK_START->ipl_info.fcp.devno;
+-		ipl_info.data.fcp.dev_id.ssid = 0;
+-		ipl_info.data.fcp.wwpn = IPL_PARMBLOCK_START->ipl_info.fcp.wwpn;
+-		ipl_info.data.fcp.lun = IPL_PARMBLOCK_START->ipl_info.fcp.lun;
+-		break;
+-	case IPL_TYPE_NSS:
+-		strncpy(ipl_info.data.nss.name, kernel_nss_name,
+-			sizeof(ipl_info.data.nss.name));
+-		break;
+-	case IPL_TYPE_UNKNOWN:
+-	default:
+-		/* We have no info to copy */
+-		break;
+-	}
+-}
+-
+ struct ipl_info ipl_info;
+ EXPORT_SYMBOL_GPL(ipl_info);
+ 
+-static ssize_t ipl_type_show(struct kset *kset, char *page)
++static ssize_t ipl_type_show(struct kobject *kobj, struct kobj_attribute *attr,
++			     char *page)
+ {
+ 	return sprintf(page, "%s\n", ipl_type_str(ipl_info.type));
+ }
+ 
+-static struct subsys_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type);
++static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type);
+ 
+-static ssize_t sys_ipl_device_show(struct kset *kset, char *page)
++static ssize_t sys_ipl_device_show(struct kobject *kobj,
++				   struct kobj_attribute *attr, char *page)
+ {
+ 	struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
+ 
+@@ -292,7 +279,7 @@ static ssize_t sys_ipl_device_show(struct kset *kset, char *page)
+ 	}
+ }
+ 
+-static struct subsys_attribute sys_ipl_device_attr =
++static struct kobj_attribute sys_ipl_device_attr =
+ 	__ATTR(device, S_IRUGO, sys_ipl_device_show, NULL);
+ 
+ static ssize_t ipl_parameter_read(struct kobject *kobj, struct bin_attribute *attr,
+@@ -367,7 +354,8 @@ static struct attribute_group ipl_fcp_attr_group = {
+ 
+ /* CCW ipl device attributes */
+ 
+-static ssize_t ipl_ccw_loadparm_show(struct kset *kset, char *page)
++static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj,
++				     struct kobj_attribute *attr, char *page)
+ {
+ 	char loadparm[LOADPARM_LEN + 1] = {};
+ 
+@@ -379,7 +367,7 @@ static ssize_t ipl_ccw_loadparm_show(struct kset *kset, char *page)
+ 	return sprintf(page, "%s\n", loadparm);
+ }
+ 
+-static struct subsys_attribute sys_ipl_ccw_loadparm_attr =
++static struct kobj_attribute sys_ipl_ccw_loadparm_attr =
+ 	__ATTR(loadparm, 0444, ipl_ccw_loadparm_show, NULL);
+ 
+ static struct attribute *ipl_ccw_attrs[] = {
+@@ -418,10 +406,76 @@ static struct attribute_group ipl_unknown_attr_group = {
+ 	.attrs = ipl_unknown_attrs,
+ };
+ 
+-static decl_subsys(ipl, NULL, NULL);
++static struct kset *ipl_kset;
++
++static int __init ipl_register_fcp_files(void)
++{
++	int rc;
++
++	rc = sysfs_create_group(&ipl_kset->kobj, &ipl_fcp_attr_group);
++	if (rc)
++		goto out;
++	rc = sysfs_create_bin_file(&ipl_kset->kobj, &ipl_parameter_attr);
++	if (rc)
++		goto out_ipl_parm;
++	rc = sysfs_create_bin_file(&ipl_kset->kobj, &ipl_scp_data_attr);
++	if (!rc)
++		goto out;
++
++	sysfs_remove_bin_file(&ipl_kset->kobj, &ipl_parameter_attr);
++
++out_ipl_parm:
++	sysfs_remove_group(&ipl_kset->kobj, &ipl_fcp_attr_group);
++out:
++	return rc;
++}
++
++static void ipl_run(struct shutdown_trigger *trigger)
++{
++	diag308(DIAG308_IPL, NULL);
++	if (MACHINE_IS_VM)
++		__cpcmd("IPL", NULL, 0, NULL);
++	else if (ipl_info.type == IPL_TYPE_CCW)
++		reipl_ccw_dev(&ipl_info.data.ccw.dev_id);
++}
++
++static int ipl_init(void)
++{
++	int rc;
++
++	ipl_kset = kset_create_and_add("ipl", NULL, firmware_kobj);
++	if (!ipl_kset) {
++		rc = -ENOMEM;
++		goto out;
++	}
++	switch (ipl_info.type) {
++	case IPL_TYPE_CCW:
++		rc = sysfs_create_group(&ipl_kset->kobj, &ipl_ccw_attr_group);
++		break;
++	case IPL_TYPE_FCP:
++	case IPL_TYPE_FCP_DUMP:
++		rc = ipl_register_fcp_files();
++		break;
++	case IPL_TYPE_NSS:
++		rc = sysfs_create_group(&ipl_kset->kobj, &ipl_nss_attr_group);
++		break;
++	default:
++		rc = sysfs_create_group(&ipl_kset->kobj,
++					&ipl_unknown_attr_group);
++		break;
++	}
++out:
++	if (rc)
++		panic("ipl_init failed: rc = %i\n", rc);
++
++	return 0;
++}
++
++static struct shutdown_action ipl_action = {SHUTDOWN_ACTION_IPL_STR, ipl_run,
++					    ipl_init};
+ 
+ /*
+- * reipl section
++ * reipl shutdown action: Reboot Linux on shutdown.
+  */
+ 
+ /* FCP reipl device attributes */
+@@ -465,7 +519,8 @@ static void reipl_get_ascii_loadparm(char *loadparm)
+ 	strstrip(loadparm);
+ }
+ 
+-static ssize_t reipl_ccw_loadparm_show(struct kset *kset, char *page)
++static ssize_t reipl_ccw_loadparm_show(struct kobject *kobj,
++				       struct kobj_attribute *attr, char *page)
+ {
+ 	char buf[LOADPARM_LEN + 1];
+ 
+@@ -473,7 +528,8 @@ static ssize_t reipl_ccw_loadparm_show(struct kset *kset, char *page)
+ 	return sprintf(page, "%s\n", buf);
+ }
+ 
+-static ssize_t reipl_ccw_loadparm_store(struct kset *kset,
++static ssize_t reipl_ccw_loadparm_store(struct kobject *kobj,
++					struct kobj_attribute *attr,
+ 					const char *buf, size_t len)
+ {
+ 	int i, lp_len;
+@@ -500,7 +556,7 @@ static ssize_t reipl_ccw_loadparm_store(struct kset *kset,
+ 	return len;
+ }
+ 
+-static struct subsys_attribute sys_reipl_ccw_loadparm_attr =
++static struct kobj_attribute sys_reipl_ccw_loadparm_attr =
+ 	__ATTR(loadparm, 0644, reipl_ccw_loadparm_show,
+ 	       reipl_ccw_loadparm_store);
+ 
+@@ -539,7 +595,9 @@ static int reipl_set_type(enum ipl_type type)
+ 
+ 	switch(type) {
+ 	case IPL_TYPE_CCW:
+-		if (MACHINE_IS_VM)
++		if (diag308_set_works)
++			reipl_method = REIPL_METHOD_CCW_DIAG;
++		else if (MACHINE_IS_VM)
+ 			reipl_method = REIPL_METHOD_CCW_VM;
+ 		else
+ 			reipl_method = REIPL_METHOD_CCW_CIO;
+@@ -568,13 +626,15 @@ static int reipl_set_type(enum ipl_type type)
+ 	return 0;
+ }
+ 
+-static ssize_t reipl_type_show(struct kset *kset, char *page)
++static ssize_t reipl_type_show(struct kobject *kobj,
++			       struct kobj_attribute *attr, char *page)
+ {
+ 	return sprintf(page, "%s\n", ipl_type_str(reipl_type));
+ }
+ 
+-static ssize_t reipl_type_store(struct kset *kset, const char *buf,
+-				size_t len)
++static ssize_t reipl_type_store(struct kobject *kobj,
++				struct kobj_attribute *attr,
++				const char *buf, size_t len)
+ {
+ 	int rc = -EINVAL;
+ 
+@@ -587,140 +647,12 @@ static ssize_t reipl_type_store(struct kset *kset, const char *buf,
+ 	return (rc != 0) ? rc : len;
+ }
+ 
+-static struct subsys_attribute reipl_type_attr =
+-		__ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store);
+-
+-static decl_subsys(reipl, NULL, NULL);
+-
+-/*
+- * dump section
+- */
+-
+-/* FCP dump device attributes */
+-
+-DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%016llx\n",
+-		   dump_block_fcp->ipl_info.fcp.wwpn);
+-DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%016llx\n",
+-		   dump_block_fcp->ipl_info.fcp.lun);
+-DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n",
+-		   dump_block_fcp->ipl_info.fcp.bootprog);
+-DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n",
+-		   dump_block_fcp->ipl_info.fcp.br_lba);
+-DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
+-		   dump_block_fcp->ipl_info.fcp.devno);
+-
+-static struct attribute *dump_fcp_attrs[] = {
+-	&sys_dump_fcp_device_attr.attr,
+-	&sys_dump_fcp_wwpn_attr.attr,
+-	&sys_dump_fcp_lun_attr.attr,
+-	&sys_dump_fcp_bootprog_attr.attr,
+-	&sys_dump_fcp_br_lba_attr.attr,
+-	NULL,
+-};
+-
+-static struct attribute_group dump_fcp_attr_group = {
+-	.name  = IPL_FCP_STR,
+-	.attrs = dump_fcp_attrs,
+-};
+-
+-/* CCW dump device attributes */
+-
+-DEFINE_IPL_ATTR_RW(dump_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
+-		   dump_block_ccw->ipl_info.ccw.devno);
+-
+-static struct attribute *dump_ccw_attrs[] = {
+-	&sys_dump_ccw_device_attr.attr,
+-	NULL,
+-};
+-
+-static struct attribute_group dump_ccw_attr_group = {
+-	.name  = IPL_CCW_STR,
+-	.attrs = dump_ccw_attrs,
+-};
+-
+-/* dump type */
+-
+-static int dump_set_type(enum dump_type type)
+-{
+-	if (!(dump_capabilities & type))
+-		return -EINVAL;
+-	switch(type) {
+-	case DUMP_TYPE_CCW:
+-		if (MACHINE_IS_VM)
+-			dump_method = DUMP_METHOD_CCW_VM;
+-		else if (diag308_set_works)
+-			dump_method = DUMP_METHOD_CCW_DIAG;
+-		else
+-			dump_method = DUMP_METHOD_CCW_CIO;
+-		break;
+-	case DUMP_TYPE_FCP:
+-		dump_method = DUMP_METHOD_FCP_DIAG;
+-		break;
+-	default:
+-		dump_method = DUMP_METHOD_NONE;
+-	}
+-	dump_type = type;
+-	return 0;
+-}
+-
+-static ssize_t dump_type_show(struct kset *kset, char *page)
+-{
+-	return sprintf(page, "%s\n", dump_type_str(dump_type));
+-}
+-
+-static ssize_t dump_type_store(struct kset *kset, const char *buf,
+-			       size_t len)
+-{
+-	int rc = -EINVAL;
+-
+-	if (strncmp(buf, DUMP_NONE_STR, strlen(DUMP_NONE_STR)) == 0)
+-		rc = dump_set_type(DUMP_TYPE_NONE);
+-	else if (strncmp(buf, DUMP_CCW_STR, strlen(DUMP_CCW_STR)) == 0)
+-		rc = dump_set_type(DUMP_TYPE_CCW);
+-	else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0)
+-		rc = dump_set_type(DUMP_TYPE_FCP);
+-	return (rc != 0) ? rc : len;
+-}
+-
+-static struct subsys_attribute dump_type_attr =
+-		__ATTR(dump_type, 0644, dump_type_show, dump_type_store);
+-
+-static decl_subsys(dump, NULL, NULL);
+-
+-/*
+- * Shutdown actions section
+- */
+-
+-static decl_subsys(shutdown_actions, NULL, NULL);
+-
+-/* on panic */
+-
+-static ssize_t on_panic_show(struct kset *kset, char *page)
+-{
+-	return sprintf(page, "%s\n", shutdown_action_str(on_panic_action));
+-}
+-
+-static ssize_t on_panic_store(struct kset *kset, const char *buf,
+-			      size_t len)
+-{
+-	if (strncmp(buf, SHUTDOWN_REIPL_STR, strlen(SHUTDOWN_REIPL_STR)) == 0)
+-		on_panic_action = SHUTDOWN_REIPL;
+-	else if (strncmp(buf, SHUTDOWN_DUMP_STR,
+-			 strlen(SHUTDOWN_DUMP_STR)) == 0)
+-		on_panic_action = SHUTDOWN_DUMP;
+-	else if (strncmp(buf, SHUTDOWN_STOP_STR,
+-			 strlen(SHUTDOWN_STOP_STR)) == 0)
+-		on_panic_action = SHUTDOWN_STOP;
+-	else
+-		return -EINVAL;
+-
+-	return len;
+-}
++static struct kobj_attribute reipl_type_attr =
++	__ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store);
+ 
+-static struct subsys_attribute on_panic_attr =
+-		__ATTR(on_panic, 0644, on_panic_show, on_panic_store);
++static struct kset *reipl_kset;
+ 
+-void do_reipl(void)
++void reipl_run(struct shutdown_trigger *trigger)
+ {
+ 	struct ccw_dev_id devid;
+ 	static char buf[100];
+@@ -729,8 +661,6 @@ void do_reipl(void)
+ 	switch (reipl_method) {
+ 	case REIPL_METHOD_CCW_CIO:
+ 		devid.devno = reipl_block_ccw->ipl_info.ccw.devno;
+-		if (ipl_info.type == IPL_TYPE_CCW && devid.devno == ipl_devno)
+-			diag308(DIAG308_IPL, NULL);
+ 		devid.ssid  = 0;
+ 		reipl_ccw_dev(&devid);
+ 		break;
+@@ -771,98 +701,6 @@ void do_reipl(void)
+ 	default:
+ 		break;
+ 	}
+-	signal_processor(smp_processor_id(), sigp_stop_and_store_status);
+-}
+-
+-static void do_dump(void)
+-{
+-	struct ccw_dev_id devid;
+-	static char buf[100];
+-
+-	switch (dump_method) {
+-	case DUMP_METHOD_CCW_CIO:
+-		smp_send_stop();
+-		devid.devno = dump_block_ccw->ipl_info.ccw.devno;
+-		devid.ssid  = 0;
+-		reipl_ccw_dev(&devid);
+-		break;
+-	case DUMP_METHOD_CCW_VM:
+-		smp_send_stop();
+-		sprintf(buf, "STORE STATUS");
+-		__cpcmd(buf, NULL, 0, NULL);
+-		sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno);
+-		__cpcmd(buf, NULL, 0, NULL);
+-		break;
+-	case DUMP_METHOD_CCW_DIAG:
+-		diag308(DIAG308_SET, dump_block_ccw);
+-		diag308(DIAG308_DUMP, NULL);
+-		break;
+-	case DUMP_METHOD_FCP_DIAG:
+-		diag308(DIAG308_SET, dump_block_fcp);
+-		diag308(DIAG308_DUMP, NULL);
+-		break;
+-	case DUMP_METHOD_NONE:
+-	default:
+-		return;
+-	}
+-	printk(KERN_EMERG "Dump failed!\n");
+-}
+-
+-/* init functions */
+-
+-static int __init ipl_register_fcp_files(void)
+-{
+-	int rc;
+-
+-	rc = sysfs_create_group(&ipl_subsys.kobj,
+-				&ipl_fcp_attr_group);
+-	if (rc)
+-		goto out;
+-	rc = sysfs_create_bin_file(&ipl_subsys.kobj,
+-				   &ipl_parameter_attr);
+-	if (rc)
+-		goto out_ipl_parm;
+-	rc = sysfs_create_bin_file(&ipl_subsys.kobj,
+-				   &ipl_scp_data_attr);
+-	if (!rc)
+-		goto out;
+-
+-	sysfs_remove_bin_file(&ipl_subsys.kobj, &ipl_parameter_attr);
+-
+-out_ipl_parm:
+-	sysfs_remove_group(&ipl_subsys.kobj, &ipl_fcp_attr_group);
+-out:
+-	return rc;
+-}
+-
+-static int __init ipl_init(void)
+-{
+-	int rc;
+-
+-	rc = firmware_register(&ipl_subsys);
+-	if (rc)
+-		return rc;
+-	switch (ipl_info.type) {
+-	case IPL_TYPE_CCW:
+-		rc = sysfs_create_group(&ipl_subsys.kobj,
+-					&ipl_ccw_attr_group);
+-		break;
+-	case IPL_TYPE_FCP:
+-	case IPL_TYPE_FCP_DUMP:
+-		rc = ipl_register_fcp_files();
+-		break;
+-	case IPL_TYPE_NSS:
+-		rc = sysfs_create_group(&ipl_subsys.kobj,
+-					&ipl_nss_attr_group);
+-		break;
+-	default:
+-		rc = sysfs_create_group(&ipl_subsys.kobj,
+-					&ipl_unknown_attr_group);
+-		break;
+-	}
+-	if (rc)
+-		firmware_unregister(&ipl_subsys);
+-	return rc;
+ }
+ 
+ static void __init reipl_probe(void)
+@@ -883,7 +721,7 @@ static int __init reipl_nss_init(void)
+ 
+ 	if (!MACHINE_IS_VM)
+ 		return 0;
+-	rc = sysfs_create_group(&reipl_subsys.kobj, &reipl_nss_attr_group);
++	rc = sysfs_create_group(&reipl_kset->kobj, &reipl_nss_attr_group);
+ 	if (rc)
+ 		return rc;
+ 	strncpy(reipl_nss_name, kernel_nss_name, NSS_NAME_SIZE + 1);
+@@ -898,7 +736,7 @@ static int __init reipl_ccw_init(void)
+ 	reipl_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
+ 	if (!reipl_block_ccw)
+ 		return -ENOMEM;
+-	rc = sysfs_create_group(&reipl_subsys.kobj, &reipl_ccw_attr_group);
++	rc = sysfs_create_group(&reipl_kset->kobj, &reipl_ccw_attr_group);
+ 	if (rc) {
+ 		free_page((unsigned long)reipl_block_ccw);
+ 		return rc;
+@@ -907,6 +745,7 @@ static int __init reipl_ccw_init(void)
+ 	reipl_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION;
+ 	reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN;
+ 	reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
++	reipl_block_ccw->hdr.flags = DIAG308_FLAGS_LP_VALID;
+ 	/* check if read scp info worked and set loadparm */
+ 	if (sclp_ipl_info.is_valid)
+ 		memcpy(reipl_block_ccw->ipl_info.ccw.load_param,
+@@ -915,8 +754,7 @@ static int __init reipl_ccw_init(void)
+ 		/* read scp info failed: set empty loadparm (EBCDIC blanks) */
+ 		memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40,
+ 		       LOADPARM_LEN);
+-	/* FIXME: check for diag308_set_works when enabling diag ccw reipl */
+-	if (!MACHINE_IS_VM)
++	if (!MACHINE_IS_VM && !diag308_set_works)
+ 		sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO;
+ 	if (ipl_info.type == IPL_TYPE_CCW)
+ 		reipl_block_ccw->ipl_info.ccw.devno = ipl_devno;
+@@ -936,7 +774,7 @@ static int __init reipl_fcp_init(void)
+ 	reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
+ 	if (!reipl_block_fcp)
+ 		return -ENOMEM;
+-	rc = sysfs_create_group(&reipl_subsys.kobj, &reipl_fcp_attr_group);
++	rc = sysfs_create_group(&reipl_kset->kobj, &reipl_fcp_attr_group);
+ 	if (rc) {
+ 		free_page((unsigned long)reipl_block_fcp);
+ 		return rc;
+@@ -954,16 +792,16 @@ static int __init reipl_fcp_init(void)
+ 	return 0;
+ }
+ 
+-static int __init reipl_init(void)
++static int reipl_init(void)
+ {
+ 	int rc;
+ 
+-	rc = firmware_register(&reipl_subsys);
+-	if (rc)
+-		return rc;
+-	rc = subsys_create_file(&reipl_subsys, &reipl_type_attr);
++	reipl_kset = kset_create_and_add("reipl", NULL, firmware_kobj);
++	if (!reipl_kset)
++		return -ENOMEM;
++	rc = sysfs_create_file(&reipl_kset->kobj, &reipl_type_attr.attr);
+ 	if (rc) {
+-		firmware_unregister(&reipl_subsys);
++		kset_unregister(reipl_kset);
+ 		return rc;
+ 	}
+ 	rc = reipl_ccw_init();
+@@ -981,6 +819,140 @@ static int __init reipl_init(void)
+ 	return 0;
+ }
+ 
++static struct shutdown_action reipl_action = {SHUTDOWN_ACTION_REIPL_STR,
++					      reipl_run, reipl_init};
++
++/*
++ * dump shutdown action: Dump Linux on shutdown.
++ */
++
++/* FCP dump device attributes */
++
++DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%016llx\n",
++		   dump_block_fcp->ipl_info.fcp.wwpn);
++DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%016llx\n",
++		   dump_block_fcp->ipl_info.fcp.lun);
++DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n",
++		   dump_block_fcp->ipl_info.fcp.bootprog);
++DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n",
++		   dump_block_fcp->ipl_info.fcp.br_lba);
++DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
++		   dump_block_fcp->ipl_info.fcp.devno);
++
++static struct attribute *dump_fcp_attrs[] = {
++	&sys_dump_fcp_device_attr.attr,
++	&sys_dump_fcp_wwpn_attr.attr,
++	&sys_dump_fcp_lun_attr.attr,
++	&sys_dump_fcp_bootprog_attr.attr,
++	&sys_dump_fcp_br_lba_attr.attr,
++	NULL,
++};
++
++static struct attribute_group dump_fcp_attr_group = {
++	.name  = IPL_FCP_STR,
++	.attrs = dump_fcp_attrs,
++};
++
++/* CCW dump device attributes */
++
++DEFINE_IPL_ATTR_RW(dump_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
++		   dump_block_ccw->ipl_info.ccw.devno);
++
++static struct attribute *dump_ccw_attrs[] = {
++	&sys_dump_ccw_device_attr.attr,
++	NULL,
++};
++
++static struct attribute_group dump_ccw_attr_group = {
++	.name  = IPL_CCW_STR,
++	.attrs = dump_ccw_attrs,
++};
++
++/* dump type */
++
++static int dump_set_type(enum dump_type type)
++{
++	if (!(dump_capabilities & type))
++		return -EINVAL;
++	switch (type) {
++	case DUMP_TYPE_CCW:
++		if (diag308_set_works)
++			dump_method = DUMP_METHOD_CCW_DIAG;
++		else if (MACHINE_IS_VM)
++			dump_method = DUMP_METHOD_CCW_VM;
++		else
++			dump_method = DUMP_METHOD_CCW_CIO;
++		break;
++	case DUMP_TYPE_FCP:
++		dump_method = DUMP_METHOD_FCP_DIAG;
++		break;
++	default:
++		dump_method = DUMP_METHOD_NONE;
++	}
++	dump_type = type;
++	return 0;
++}
++
++static ssize_t dump_type_show(struct kobject *kobj,
++			      struct kobj_attribute *attr, char *page)
++{
++	return sprintf(page, "%s\n", dump_type_str(dump_type));
++}
++
++static ssize_t dump_type_store(struct kobject *kobj,
++			       struct kobj_attribute *attr,
++			       const char *buf, size_t len)
++{
++	int rc = -EINVAL;
++
++	if (strncmp(buf, DUMP_NONE_STR, strlen(DUMP_NONE_STR)) == 0)
++		rc = dump_set_type(DUMP_TYPE_NONE);
++	else if (strncmp(buf, DUMP_CCW_STR, strlen(DUMP_CCW_STR)) == 0)
++		rc = dump_set_type(DUMP_TYPE_CCW);
++	else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0)
++		rc = dump_set_type(DUMP_TYPE_FCP);
++	return (rc != 0) ? rc : len;
++}
++
++static struct kobj_attribute dump_type_attr =
++	__ATTR(dump_type, 0644, dump_type_show, dump_type_store);
++
++static struct kset *dump_kset;
++
++static void dump_run(struct shutdown_trigger *trigger)
++{
++	struct ccw_dev_id devid;
++	static char buf[100];
++
++	switch (dump_method) {
++	case DUMP_METHOD_CCW_CIO:
++		smp_send_stop();
++		devid.devno = dump_block_ccw->ipl_info.ccw.devno;
++		devid.ssid  = 0;
++		reipl_ccw_dev(&devid);
++		break;
++	case DUMP_METHOD_CCW_VM:
++		smp_send_stop();
++		sprintf(buf, "STORE STATUS");
++		__cpcmd(buf, NULL, 0, NULL);
++		sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno);
++		__cpcmd(buf, NULL, 0, NULL);
++		break;
++	case DUMP_METHOD_CCW_DIAG:
++		diag308(DIAG308_SET, dump_block_ccw);
++		diag308(DIAG308_DUMP, NULL);
++		break;
++	case DUMP_METHOD_FCP_DIAG:
++		diag308(DIAG308_SET, dump_block_fcp);
++		diag308(DIAG308_DUMP, NULL);
++		break;
++	case DUMP_METHOD_NONE:
++	default:
++		return;
++	}
++	printk(KERN_EMERG "Dump failed!\n");
++}
++
+ static int __init dump_ccw_init(void)
+ {
+ 	int rc;
+@@ -988,7 +960,7 @@ static int __init dump_ccw_init(void)
+ 	dump_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
+ 	if (!dump_block_ccw)
+ 		return -ENOMEM;
+-	rc = sysfs_create_group(&dump_subsys.kobj, &dump_ccw_attr_group);
++	rc = sysfs_create_group(&dump_kset->kobj, &dump_ccw_attr_group);
+ 	if (rc) {
+ 		free_page((unsigned long)dump_block_ccw);
+ 		return rc;
+@@ -1012,7 +984,7 @@ static int __init dump_fcp_init(void)
+ 	dump_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
+ 	if (!dump_block_fcp)
+ 		return -ENOMEM;
+-	rc = sysfs_create_group(&dump_subsys.kobj, &dump_fcp_attr_group);
++	rc = sysfs_create_group(&dump_kset->kobj, &dump_fcp_attr_group);
+ 	if (rc) {
+ 		free_page((unsigned long)dump_block_fcp);
+ 		return rc;
+@@ -1026,33 +998,16 @@ static int __init dump_fcp_init(void)
+ 	return 0;
+ }
+ 
+-#define SHUTDOWN_ON_PANIC_PRIO 0
+-
+-static int shutdown_on_panic_notify(struct notifier_block *self,
+-				    unsigned long event, void *data)
+-{
+-	if (on_panic_action == SHUTDOWN_DUMP)
+-		do_dump();
+-	else if (on_panic_action == SHUTDOWN_REIPL)
+-		do_reipl();
+-	return NOTIFY_OK;
+-}
+-
+-static struct notifier_block shutdown_on_panic_nb = {
+-	.notifier_call = shutdown_on_panic_notify,
+-	.priority = SHUTDOWN_ON_PANIC_PRIO
+-};
+-
+-static int __init dump_init(void)
++static int dump_init(void)
+ {
+ 	int rc;
+ 
+-	rc = firmware_register(&dump_subsys);
+-	if (rc)
+-		return rc;
+-	rc = subsys_create_file(&dump_subsys, &dump_type_attr);
++	dump_kset = kset_create_and_add("dump", NULL, firmware_kobj);
++	if (!dump_kset)
++		return -ENOMEM;
++	rc = sysfs_create_file(&dump_kset->kobj, &dump_type_attr.attr);
+ 	if (rc) {
+-		firmware_unregister(&dump_subsys);
++		kset_unregister(dump_kset);
+ 		return rc;
+ 	}
+ 	rc = dump_ccw_init();
+@@ -1065,46 +1020,381 @@ static int __init dump_init(void)
+ 	return 0;
+ }
+ 
+-static int __init shutdown_actions_init(void)
++static struct shutdown_action dump_action = {SHUTDOWN_ACTION_DUMP_STR,
++					     dump_run, dump_init};
++
++/*
++ * vmcmd shutdown action: Trigger vm command on shutdown.
++ */
++
++static char vmcmd_on_reboot[128];
++static char vmcmd_on_panic[128];
++static char vmcmd_on_halt[128];
++static char vmcmd_on_poff[128];
++
++DEFINE_IPL_ATTR_STR_RW(vmcmd, on_reboot, "%s\n", "%s\n", vmcmd_on_reboot);
++DEFINE_IPL_ATTR_STR_RW(vmcmd, on_panic, "%s\n", "%s\n", vmcmd_on_panic);
++DEFINE_IPL_ATTR_STR_RW(vmcmd, on_halt, "%s\n", "%s\n", vmcmd_on_halt);
++DEFINE_IPL_ATTR_STR_RW(vmcmd, on_poff, "%s\n", "%s\n", vmcmd_on_poff);
++
++static struct attribute *vmcmd_attrs[] = {
++	&sys_vmcmd_on_reboot_attr.attr,
++	&sys_vmcmd_on_panic_attr.attr,
++	&sys_vmcmd_on_halt_attr.attr,
++	&sys_vmcmd_on_poff_attr.attr,
++	NULL,
++};
++
++static struct attribute_group vmcmd_attr_group = {
++	.attrs = vmcmd_attrs,
++};
++
++static struct kset *vmcmd_kset;
++
++static void vmcmd_run(struct shutdown_trigger *trigger)
++{
++	char *cmd, *next_cmd;
++
++	if (strcmp(trigger->name, ON_REIPL_STR) == 0)
++		cmd = vmcmd_on_reboot;
++	else if (strcmp(trigger->name, ON_PANIC_STR) == 0)
++		cmd = vmcmd_on_panic;
++	else if (strcmp(trigger->name, ON_HALT_STR) == 0)
++		cmd = vmcmd_on_halt;
++	else if (strcmp(trigger->name, ON_POFF_STR) == 0)
++		cmd = vmcmd_on_poff;
++	else
++		return;
++
++	if (strlen(cmd) == 0)
++		return;
++	do {
++		next_cmd = strchr(cmd, '\n');
++		if (next_cmd) {
++			next_cmd[0] = 0;
++			next_cmd += 1;
++		}
++		__cpcmd(cmd, NULL, 0, NULL);
++		cmd = next_cmd;
++	} while (cmd != NULL);
++}
++
++static int vmcmd_init(void)
+ {
+-	int rc;
++	if (!MACHINE_IS_VM)
++		return -ENOTSUPP;
++	vmcmd_kset = kset_create_and_add("vmcmd", NULL, firmware_kobj);
++	if (!vmcmd_kset)
++		return -ENOMEM;
++	return sysfs_create_group(&vmcmd_kset->kobj, &vmcmd_attr_group);
++}
+ 
+-	rc = firmware_register(&shutdown_actions_subsys);
+-	if (rc)
+-		return rc;
+-	rc = subsys_create_file(&shutdown_actions_subsys, &on_panic_attr);
+-	if (rc) {
+-		firmware_unregister(&shutdown_actions_subsys);
+-		return rc;
++static struct shutdown_action vmcmd_action = {SHUTDOWN_ACTION_VMCMD_STR,
++					      vmcmd_run, vmcmd_init};
++
++/*
++ * stop shutdown action: Stop Linux on shutdown.
++ */
++
++static void stop_run(struct shutdown_trigger *trigger)
++{
++	if (strcmp(trigger->name, ON_PANIC_STR) == 0)
++		disabled_wait((unsigned long) __builtin_return_address(0));
++	else {
++		signal_processor(smp_processor_id(), sigp_stop);
++		for (;;);
+ 	}
+-	atomic_notifier_chain_register(&panic_notifier_list,
+-				       &shutdown_on_panic_nb);
+-	return 0;
+ }
+ 
+-static int __init s390_ipl_init(void)
++static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR,
++					     stop_run, NULL};
++
++/* action list */
++
++static struct shutdown_action *shutdown_actions_list[] = {
++	&ipl_action, &reipl_action, &dump_action, &vmcmd_action, &stop_action};
++#define SHUTDOWN_ACTIONS_COUNT (sizeof(shutdown_actions_list) / sizeof(void *))
++
++/*
++ * Trigger section
++ */
++
++static struct kset *shutdown_actions_kset;
++
++static int set_trigger(const char *buf, struct shutdown_trigger *trigger,
++		       size_t len)
+ {
+-	int rc;
++	int i;
++	for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
++		if (!shutdown_actions_list[i])
++			continue;
++		if (strncmp(buf, shutdown_actions_list[i]->name,
++			    strlen(shutdown_actions_list[i]->name)) == 0) {
++			trigger->action = shutdown_actions_list[i];
++			return len;
++		}
++	}
++	return -EINVAL;
++}
+ 
+-	sclp_get_ipl_info(&sclp_ipl_info);
++/* on reipl */
++
++static struct shutdown_trigger on_reboot_trigger = {ON_REIPL_STR,
++						    &reipl_action};
++
++static ssize_t on_reboot_show(struct kobject *kobj,
++			      struct kobj_attribute *attr, char *page)
++{
++	return sprintf(page, "%s\n", on_reboot_trigger.action->name);
++}
++
++static ssize_t on_reboot_store(struct kobject *kobj,
++			       struct kobj_attribute *attr,
++			       const char *buf, size_t len)
++{
++	return set_trigger(buf, &on_reboot_trigger, len);
++}
++
++static struct kobj_attribute on_reboot_attr =
++	__ATTR(on_reboot, 0644, on_reboot_show, on_reboot_store);
++
++static void do_machine_restart(char *__unused)
++{
++	smp_send_stop();
++	on_reboot_trigger.action->fn(&on_reboot_trigger);
++	reipl_run(NULL);
++}
++void (*_machine_restart)(char *command) = do_machine_restart;
++
++/* on panic */
++
++static struct shutdown_trigger on_panic_trigger = {ON_PANIC_STR, &stop_action};
++
++static ssize_t on_panic_show(struct kobject *kobj,
++			     struct kobj_attribute *attr, char *page)
++{
++	return sprintf(page, "%s\n", on_panic_trigger.action->name);
++}
++
++static ssize_t on_panic_store(struct kobject *kobj,
++			      struct kobj_attribute *attr,
++			      const char *buf, size_t len)
++{
++	return set_trigger(buf, &on_panic_trigger, len);
++}
++
++static struct kobj_attribute on_panic_attr =
++	__ATTR(on_panic, 0644, on_panic_show, on_panic_store);
++
++static void do_panic(void)
++{
++	on_panic_trigger.action->fn(&on_panic_trigger);
++	stop_run(&on_panic_trigger);
++}
++
++/* on halt */
++
++static struct shutdown_trigger on_halt_trigger = {ON_HALT_STR, &stop_action};
++
++static ssize_t on_halt_show(struct kobject *kobj,
++			    struct kobj_attribute *attr, char *page)
++{
++	return sprintf(page, "%s\n", on_halt_trigger.action->name);
++}
++
++static ssize_t on_halt_store(struct kobject *kobj,
++			     struct kobj_attribute *attr,
++			     const char *buf, size_t len)
++{
++	return set_trigger(buf, &on_halt_trigger, len);
++}
++
++static struct kobj_attribute on_halt_attr =
++	__ATTR(on_halt, 0644, on_halt_show, on_halt_store);
++
++
++static void do_machine_halt(void)
++{
++	smp_send_stop();
++	on_halt_trigger.action->fn(&on_halt_trigger);
++	stop_run(&on_halt_trigger);
++}
++void (*_machine_halt)(void) = do_machine_halt;
++
++/* on power off */
++
++static struct shutdown_trigger on_poff_trigger = {ON_POFF_STR, &stop_action};
++
++static ssize_t on_poff_show(struct kobject *kobj,
++			    struct kobj_attribute *attr, char *page)
++{
++	return sprintf(page, "%s\n", on_poff_trigger.action->name);
++}
++
++static ssize_t on_poff_store(struct kobject *kobj,
++			     struct kobj_attribute *attr,
++			     const char *buf, size_t len)
++{
++	return set_trigger(buf, &on_poff_trigger, len);
++}
++
++static struct kobj_attribute on_poff_attr =
++	__ATTR(on_poff, 0644, on_poff_show, on_poff_store);
++
++
++static void do_machine_power_off(void)
++{
++	smp_send_stop();
++	on_poff_trigger.action->fn(&on_poff_trigger);
++	stop_run(&on_poff_trigger);
++}
++void (*_machine_power_off)(void) = do_machine_power_off;
++
++static void __init shutdown_triggers_init(void)
++{
++	shutdown_actions_kset = kset_create_and_add("shutdown_actions", NULL,
++						    firmware_kobj);
++	if (!shutdown_actions_kset)
++		goto fail;
++	if (sysfs_create_file(&shutdown_actions_kset->kobj,
++			      &on_reboot_attr.attr))
++		goto fail;
++	if (sysfs_create_file(&shutdown_actions_kset->kobj,
++			      &on_panic_attr.attr))
++		goto fail;
++	if (sysfs_create_file(&shutdown_actions_kset->kobj,
++			      &on_halt_attr.attr))
++		goto fail;
++	if (sysfs_create_file(&shutdown_actions_kset->kobj,
++			      &on_poff_attr.attr))
++		goto fail;
++
++	return;
++fail:
++	panic("shutdown_triggers_init failed\n");
++}
++
++static void __init shutdown_actions_init(void)
++{
++	int i;
++
++	for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
++		if (!shutdown_actions_list[i]->init)
++			continue;
++		if (shutdown_actions_list[i]->init())
++			shutdown_actions_list[i] = NULL;
++	}
++}
++
++static int __init s390_ipl_init(void)
++{
+ 	reipl_probe();
+-	rc = ipl_init();
+-	if (rc)
+-		return rc;
+-	rc = reipl_init();
+-	if (rc)
+-		return rc;
+-	rc = dump_init();
+-	if (rc)
+-		return rc;
+-	rc = shutdown_actions_init();
+-	if (rc)
+-		return rc;
++	sclp_get_ipl_info(&sclp_ipl_info);
++	shutdown_actions_init();
++	shutdown_triggers_init();
+ 	return 0;
+ }
+ 
+ __initcall(s390_ipl_init);
+ 
++static void __init strncpy_skip_quote(char *dst, char *src, int n)
++{
++	int sx, dx;
++
++	dx = 0;
++	for (sx = 0; src[sx] != 0; sx++) {
++		if (src[sx] == '"')
++			continue;
++		dst[dx++] = src[sx];
++		if (dx >= n)
++			break;
++	}
++}
++
++static int __init vmcmd_on_reboot_setup(char *str)
++{
++	if (!MACHINE_IS_VM)
++		return 1;
++	strncpy_skip_quote(vmcmd_on_reboot, str, 127);
++	vmcmd_on_reboot[127] = 0;
++	on_reboot_trigger.action = &vmcmd_action;
++	return 1;
++}
++__setup("vmreboot=", vmcmd_on_reboot_setup);
++
++static int __init vmcmd_on_panic_setup(char *str)
++{
++	if (!MACHINE_IS_VM)
++		return 1;
++	strncpy_skip_quote(vmcmd_on_panic, str, 127);
++	vmcmd_on_panic[127] = 0;
++	on_panic_trigger.action = &vmcmd_action;
++	return 1;
++}
++__setup("vmpanic=", vmcmd_on_panic_setup);
++
++static int __init vmcmd_on_halt_setup(char *str)
++{
++	if (!MACHINE_IS_VM)
++		return 1;
++	strncpy_skip_quote(vmcmd_on_halt, str, 127);
++	vmcmd_on_halt[127] = 0;
++	on_halt_trigger.action = &vmcmd_action;
++	return 1;
++}
++__setup("vmhalt=", vmcmd_on_halt_setup);
++
++static int __init vmcmd_on_poff_setup(char *str)
++{
++	if (!MACHINE_IS_VM)
++		return 1;
++	strncpy_skip_quote(vmcmd_on_poff, str, 127);
++	vmcmd_on_poff[127] = 0;
++	on_poff_trigger.action = &vmcmd_action;
++	return 1;
++}
++__setup("vmpoff=", vmcmd_on_poff_setup);
++
++static int on_panic_notify(struct notifier_block *self,
++			   unsigned long event, void *data)
++{
++	do_panic();
++	return NOTIFY_OK;
++}
++
++static struct notifier_block on_panic_nb = {
++	.notifier_call = on_panic_notify,
++	.priority = 0,
++};
++
++void __init setup_ipl(void)
++{
++	ipl_info.type = get_ipl_type();
++	switch (ipl_info.type) {
++	case IPL_TYPE_CCW:
++		ipl_info.data.ccw.dev_id.devno = ipl_devno;
++		ipl_info.data.ccw.dev_id.ssid = 0;
++		break;
++	case IPL_TYPE_FCP:
++	case IPL_TYPE_FCP_DUMP:
++		ipl_info.data.fcp.dev_id.devno =
++			IPL_PARMBLOCK_START->ipl_info.fcp.devno;
++		ipl_info.data.fcp.dev_id.ssid = 0;
++		ipl_info.data.fcp.wwpn = IPL_PARMBLOCK_START->ipl_info.fcp.wwpn;
++		ipl_info.data.fcp.lun = IPL_PARMBLOCK_START->ipl_info.fcp.lun;
++		break;
++	case IPL_TYPE_NSS:
++		strncpy(ipl_info.data.nss.name, kernel_nss_name,
++			sizeof(ipl_info.data.nss.name));
++		break;
++	case IPL_TYPE_UNKNOWN:
++	default:
++		/* We have no info to copy */
++		break;
++	}
++	atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb);
++}
++
+ void __init ipl_save_parameters(void)
+ {
+ 	struct cio_iplinfo iplinfo;
+@@ -1185,3 +1475,4 @@ void s390_reset_system(void)
+ 
+ 	do_reset_calls();
+ }
++
+diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
+index 29f7884..0e7aca0 100644
+--- a/arch/s390/kernel/process.c
++++ b/arch/s390/kernel/process.c
+@@ -36,7 +36,7 @@
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/notifier.h>
+-
++#include <linux/utsname.h>
+ #include <asm/uaccess.h>
+ #include <asm/pgtable.h>
+ #include <asm/system.h>
+@@ -182,13 +182,15 @@ void cpu_idle(void)
+ 
+ void show_regs(struct pt_regs *regs)
+ {
+-	struct task_struct *tsk = current;
+-
+-        printk("CPU:    %d    %s\n", task_thread_info(tsk)->cpu, print_tainted());
+-        printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
+-	       current->comm, task_pid_nr(current), (void *) tsk,
+-	       (void *) tsk->thread.ksp);
+-
++	print_modules();
++	printk("CPU: %d %s %s %.*s\n",
++	       task_thread_info(current)->cpu, print_tainted(),
++	       init_utsname()->release,
++	       (int)strcspn(init_utsname()->version, " "),
++	       init_utsname()->version);
++	printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
++	       current->comm, current->pid, current,
++	       (void *) current->thread.ksp);
+ 	show_registers(regs);
+ 	/* Show stack backtrace if pt_regs is from kernel mode */
+ 	if (!(regs->psw.mask & PSW_MASK_PSTATE))
+diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
+index 1d81bf9..6e036ba 100644
+--- a/arch/s390/kernel/ptrace.c
++++ b/arch/s390/kernel/ptrace.c
+@@ -86,13 +86,13 @@ FixPerRegisters(struct task_struct *task)
+ 		per_info->control_regs.bits.storage_alt_space_ctl = 0;
+ }
+ 
+-static void set_single_step(struct task_struct *task)
++void user_enable_single_step(struct task_struct *task)
+ {
+ 	task->thread.per_info.single_step = 1;
+ 	FixPerRegisters(task);
+ }
+ 
+-static void clear_single_step(struct task_struct *task)
++void user_disable_single_step(struct task_struct *task)
+ {
+ 	task->thread.per_info.single_step = 0;
+ 	FixPerRegisters(task);
+@@ -107,7 +107,7 @@ void
+ ptrace_disable(struct task_struct *child)
+ {
+ 	/* make sure the single step bit is not set. */
+-	clear_single_step(child);
++	user_disable_single_step(child);
+ }
+ 
+ #ifndef CONFIG_64BIT
+@@ -651,7 +651,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
+ 			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ 		child->exit_code = data;
+ 		/* make sure the single step bit is not set. */
+-		clear_single_step(child);
++		user_disable_single_step(child);
+ 		wake_up_process(child);
+ 		return 0;
+ 
+@@ -665,7 +665,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
+ 			return 0;
+ 		child->exit_code = SIGKILL;
+ 		/* make sure the single step bit is not set. */
+-		clear_single_step(child);
++		user_disable_single_step(child);
+ 		wake_up_process(child);
+ 		return 0;
+ 
+@@ -675,10 +675,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
+ 			return -EIO;
+ 		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ 		child->exit_code = data;
+-		if (data)
+-			set_tsk_thread_flag(child, TIF_SINGLE_STEP);
+-		else
+-			set_single_step(child);
++		user_enable_single_step(child);
+ 		/* give it a chance to run. */
+ 		wake_up_process(child);
+ 		return 0;
+diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
+index 577aa7d..766c783 100644
+--- a/arch/s390/kernel/setup.c
++++ b/arch/s390/kernel/setup.c
+@@ -126,75 +126,6 @@ void __cpuinit cpu_init(void)
+ }
+ 
+ /*
+- * VM halt and poweroff setup routines
+- */
+-char vmhalt_cmd[128] = "";
+-char vmpoff_cmd[128] = "";
+-static char vmpanic_cmd[128] = "";
+-
+-static void strncpy_skip_quote(char *dst, char *src, int n)
+-{
+-        int sx, dx;
+-
+-        dx = 0;
+-        for (sx = 0; src[sx] != 0; sx++) {
+-                if (src[sx] == '"') continue;
+-                dst[dx++] = src[sx];
+-                if (dx >= n) break;
+-        }
+-}
+-
+-static int __init vmhalt_setup(char *str)
+-{
+-        strncpy_skip_quote(vmhalt_cmd, str, 127);
+-        vmhalt_cmd[127] = 0;
+-        return 1;
+-}
+-
+-__setup("vmhalt=", vmhalt_setup);
+-
+-static int __init vmpoff_setup(char *str)
+-{
+-        strncpy_skip_quote(vmpoff_cmd, str, 127);
+-        vmpoff_cmd[127] = 0;
+-        return 1;
+-}
+-
+-__setup("vmpoff=", vmpoff_setup);
+-
+-static int vmpanic_notify(struct notifier_block *self, unsigned long event,
+-			  void *data)
+-{
+-	if (MACHINE_IS_VM && strlen(vmpanic_cmd) > 0)
+-		cpcmd(vmpanic_cmd, NULL, 0, NULL);
+-
+-	return NOTIFY_OK;
+-}
+-
+-#define PANIC_PRI_VMPANIC	0
+-
+-static struct notifier_block vmpanic_nb = {
+-	.notifier_call = vmpanic_notify,
+-	.priority = PANIC_PRI_VMPANIC
+-};
+-
+-static int __init vmpanic_setup(char *str)
+-{
+-	static int register_done __initdata = 0;
+-
+-	strncpy_skip_quote(vmpanic_cmd, str, 127);
+-	vmpanic_cmd[127] = 0;
+-	if (!register_done) {
+-		register_done = 1;
+-		atomic_notifier_chain_register(&panic_notifier_list,
+-					       &vmpanic_nb);
+-	}
+-	return 1;
+-}
+-
+-__setup("vmpanic=", vmpanic_setup);
+-
+-/*
+  * condev= and conmode= setup parameter.
+  */
+ 
+@@ -308,38 +239,6 @@ static void __init setup_zfcpdump(unsigned int console_devno)
+ static inline void setup_zfcpdump(unsigned int console_devno) {}
+ #endif /* CONFIG_ZFCPDUMP */
+ 
+-#ifdef CONFIG_SMP
+-void (*_machine_restart)(char *command) = machine_restart_smp;
+-void (*_machine_halt)(void) = machine_halt_smp;
+-void (*_machine_power_off)(void) = machine_power_off_smp;
+-#else
+-/*
+- * Reboot, halt and power_off routines for non SMP.
+- */
+-static void do_machine_restart_nonsmp(char * __unused)
+-{
+-	do_reipl();
+-}
+-
+-static void do_machine_halt_nonsmp(void)
+-{
+-        if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0)
+-		__cpcmd(vmhalt_cmd, NULL, 0, NULL);
+-        signal_processor(smp_processor_id(), sigp_stop_and_store_status);
+-}
+-
+-static void do_machine_power_off_nonsmp(void)
+-{
+-        if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0)
+-		__cpcmd(vmpoff_cmd, NULL, 0, NULL);
+-        signal_processor(smp_processor_id(), sigp_stop_and_store_status);
+-}
+-
+-void (*_machine_restart)(char *command) = do_machine_restart_nonsmp;
+-void (*_machine_halt)(void) = do_machine_halt_nonsmp;
+-void (*_machine_power_off)(void) = do_machine_power_off_nonsmp;
+-#endif
+-
+  /*
+  * Reboot, halt and power_off stubs. They just call _machine_restart,
+  * _machine_halt or _machine_power_off. 
+@@ -559,7 +458,9 @@ setup_resources(void)
+ 	data_resource.start = (unsigned long) &_etext;
+ 	data_resource.end = (unsigned long) &_edata - 1;
+ 
+-	for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) {
++	for (i = 0; i < MEMORY_CHUNKS; i++) {
++		if (!memory_chunk[i].size)
++			continue;
+ 		res = alloc_bootmem_low(sizeof(struct resource));
+ 		res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
+ 		switch (memory_chunk[i].type) {
+@@ -617,7 +518,7 @@ EXPORT_SYMBOL_GPL(real_memory_size);
+ static void __init setup_memory_end(void)
+ {
+ 	unsigned long memory_size;
+-	unsigned long max_mem, max_phys;
++	unsigned long max_mem;
+ 	int i;
+ 
+ #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE)
+@@ -625,10 +526,31 @@ static void __init setup_memory_end(void)
+ 		memory_end = ZFCPDUMP_HSA_SIZE;
+ #endif
+ 	memory_size = 0;
+-	max_phys = VMALLOC_END_INIT - VMALLOC_MIN_SIZE;
+ 	memory_end &= PAGE_MASK;
+ 
+-	max_mem = memory_end ? min(max_phys, memory_end) : max_phys;
++	max_mem = memory_end ? min(VMALLOC_START, memory_end) : VMALLOC_START;
++	memory_end = min(max_mem, memory_end);
++
++	/*
++	 * Make sure all chunks are MAX_ORDER aligned so we don't need the
++	 * extra checks that HOLES_IN_ZONE would require.
++	 */
++	for (i = 0; i < MEMORY_CHUNKS; i++) {
++		unsigned long start, end;
++		struct mem_chunk *chunk;
++		unsigned long align;
++
++		chunk = &memory_chunk[i];
++		align = 1UL << (MAX_ORDER + PAGE_SHIFT - 1);
++		start = (chunk->addr + align - 1) & ~(align - 1);
++		end = (chunk->addr + chunk->size) & ~(align - 1);
++		if (start >= end)
++			memset(chunk, 0, sizeof(*chunk));
++		else {
++			chunk->addr = start;
++			chunk->size = end - start;
++		}
++	}
+ 
+ 	for (i = 0; i < MEMORY_CHUNKS; i++) {
+ 		struct mem_chunk *chunk = &memory_chunk[i];
+@@ -890,7 +812,7 @@ setup_arch(char **cmdline_p)
+ 
+ 	parse_early_param();
+ 
+-	setup_ipl_info();
++	setup_ipl();
+ 	setup_memory_end();
+ 	setup_addressing_mode();
+ 	setup_memory();
+@@ -899,7 +821,6 @@ setup_arch(char **cmdline_p)
+ 
+         cpu_init();
+         __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr;
+-	smp_setup_cpu_possible_map();
+ 
+ 	/*
+ 	 * Setup capabilities (ELF_HWCAP & ELF_PLATFORM).
+@@ -920,7 +841,7 @@ setup_arch(char **cmdline_p)
+ 
+ void __cpuinit print_cpu_info(struct cpuinfo_S390 *cpuinfo)
+ {
+-   printk("cpu %d "
++   printk(KERN_INFO "cpu %d "
+ #ifdef CONFIG_SMP
+            "phys_idx=%d "
+ #endif
+@@ -996,7 +917,7 @@ static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+ static void c_stop(struct seq_file *m, void *v)
+ {
+ }
+-struct seq_operations cpuinfo_op = {
++const struct seq_operations cpuinfo_op = {
+ 	.start	= c_start,
+ 	.next	= c_next,
+ 	.stop	= c_stop,
+diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
+index d264671..4449bf3 100644
+--- a/arch/s390/kernel/signal.c
++++ b/arch/s390/kernel/signal.c
+@@ -471,6 +471,7 @@ void do_signal(struct pt_regs *regs)
+ 
+ 	if (signr > 0) {
+ 		/* Whee!  Actually deliver the signal.  */
++		int ret;
+ #ifdef CONFIG_COMPAT
+ 		if (test_thread_flag(TIF_31BIT)) {
+ 			extern int handle_signal32(unsigned long sig,
+@@ -478,15 +479,12 @@ void do_signal(struct pt_regs *regs)
+ 						   siginfo_t *info,
+ 						   sigset_t *oldset,
+ 						   struct pt_regs *regs);
+-			if (handle_signal32(
+-				    signr, &ka, &info, oldset, regs) == 0) {
+-				if (test_thread_flag(TIF_RESTORE_SIGMASK))
+-					clear_thread_flag(TIF_RESTORE_SIGMASK);
+-			}
+-			return;
++			ret = handle_signal32(signr, &ka, &info, oldset, regs);
+ 	        }
++		else
+ #endif
+-		if (handle_signal(signr, &ka, &info, oldset, regs) == 0) {
++			ret = handle_signal(signr, &ka, &info, oldset, regs);
++		if (!ret) {
+ 			/*
+ 			 * A signal was successfully delivered; the saved
+ 			 * sigmask will have been stored in the signal frame,
+@@ -495,6 +493,14 @@ void do_signal(struct pt_regs *regs)
+ 			 */
+ 			if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ 				clear_thread_flag(TIF_RESTORE_SIGMASK);
++
++			/*
++			 * If we would have taken a single-step trap
++			 * for a normal instruction, act like we took
++			 * one for the handler setup.
++			 */
++			if (current->thread.per_info.single_step)
++				set_thread_flag(TIF_SINGLE_STEP);
+ 		}
+ 		return;
+ 	}
+diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
+index 264ea90..aa37fa1 100644
+--- a/arch/s390/kernel/smp.c
++++ b/arch/s390/kernel/smp.c
+@@ -42,6 +42,7 @@
+ #include <asm/tlbflush.h>
+ #include <asm/timer.h>
+ #include <asm/lowcore.h>
++#include <asm/sclp.h>
+ #include <asm/cpu.h>
+ 
+ /*
+@@ -53,11 +54,27 @@ EXPORT_SYMBOL(lowcore_ptr);
+ cpumask_t cpu_online_map = CPU_MASK_NONE;
+ EXPORT_SYMBOL(cpu_online_map);
+ 
+-cpumask_t cpu_possible_map = CPU_MASK_NONE;
++cpumask_t cpu_possible_map = CPU_MASK_ALL;
+ EXPORT_SYMBOL(cpu_possible_map);
+ 
+ static struct task_struct *current_set[NR_CPUS];
+ 
++static u8 smp_cpu_type;
++static int smp_use_sigp_detection;
++
++enum s390_cpu_state {
++	CPU_STATE_STANDBY,
++	CPU_STATE_CONFIGURED,
++};
++
++#ifdef CONFIG_HOTPLUG_CPU
++static DEFINE_MUTEX(smp_cpu_state_mutex);
++#endif
++static int smp_cpu_state[NR_CPUS];
++
++static DEFINE_PER_CPU(struct cpu, cpu_devices);
++DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
++
+ static void smp_ext_bitcall(int, ec_bit_sig);
+ 
+ /*
+@@ -193,6 +210,33 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
+ }
+ EXPORT_SYMBOL(smp_call_function_single);
+ 
++/**
++ * smp_call_function_mask(): Run a function on a set of other CPUs.
++ * @mask: The set of cpus to run on.  Must not include the current cpu.
++ * @func: The function to run. This must be fast and non-blocking.
++ * @info: An arbitrary pointer to pass to the function.
++ * @wait: If true, wait (atomically) until function has completed on other CPUs.
++ *
++ * Returns 0 on success, else a negative status code.
++ *
++ * If @wait is true, then returns once @func has returned; otherwise
++ * it returns just before the target cpu calls @func.
++ *
++ * You must not call this function with disabled interrupts or from a
++ * hardware interrupt handler or from a bottom half handler.
++ */
++int
++smp_call_function_mask(cpumask_t mask,
++			void (*func)(void *), void *info,
++			int wait)
++{
++	preempt_disable();
++	__smp_call_function_map(func, info, 0, wait, mask);
++	preempt_enable();
++	return 0;
++}
++EXPORT_SYMBOL(smp_call_function_mask);
++
+ void smp_send_stop(void)
+ {
+ 	int cpu, rc;
+@@ -217,33 +261,6 @@ void smp_send_stop(void)
+ }
+ 
+ /*
+- * Reboot, halt and power_off routines for SMP.
+- */
+-void machine_restart_smp(char *__unused)
+-{
+-	smp_send_stop();
+-	do_reipl();
+-}
+-
+-void machine_halt_smp(void)
+-{
+-	smp_send_stop();
+-	if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0)
+-		__cpcmd(vmhalt_cmd, NULL, 0, NULL);
+-	signal_processor(smp_processor_id(), sigp_stop_and_store_status);
+-	for (;;);
+-}
+-
+-void machine_power_off_smp(void)
+-{
+-	smp_send_stop();
+-	if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0)
+-		__cpcmd(vmpoff_cmd, NULL, 0, NULL);
+-	signal_processor(smp_processor_id(), sigp_stop_and_store_status);
+-	for (;;);
+-}
+-
+-/*
+  * This is the main routine where commands issued by other
+  * cpus are handled.
+  */
+@@ -355,6 +372,13 @@ void smp_ctl_clear_bit(int cr, int bit)
+ }
+ EXPORT_SYMBOL(smp_ctl_clear_bit);
+ 
++/*
++ * In early ipl state a temp. logically cpu number is needed, so the sigp
++ * functions can be used to sense other cpus. Since NR_CPUS is >= 2 on
++ * CONFIG_SMP and the ipl cpu is logical cpu 0, it must be 1.
++ */
++#define CPU_INIT_NO	1
++
+ #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE)
+ 
+ /*
+@@ -375,9 +399,10 @@ static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
+ 		       "kernel was compiled with NR_CPUS=%i\n", cpu, NR_CPUS);
+ 		return;
+ 	}
+-	zfcpdump_save_areas[cpu] = alloc_bootmem(sizeof(union save_area));
+-	__cpu_logical_map[1] = (__u16) phy_cpu;
+-	while (signal_processor(1, sigp_stop_and_store_status) == sigp_busy)
++	zfcpdump_save_areas[cpu] = kmalloc(sizeof(union save_area), GFP_KERNEL);
++	__cpu_logical_map[CPU_INIT_NO] = (__u16) phy_cpu;
++	while (signal_processor(CPU_INIT_NO, sigp_stop_and_store_status) ==
++	       sigp_busy)
+ 		cpu_relax();
+ 	memcpy(zfcpdump_save_areas[cpu],
+ 	       (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
+@@ -397,32 +422,155 @@ static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { }
+ 
+ #endif /* CONFIG_ZFCPDUMP || CONFIG_ZFCPDUMP_MODULE */
+ 
+-/*
+- * Lets check how many CPUs we have.
+- */
+-static unsigned int __init smp_count_cpus(void)
++static int cpu_stopped(int cpu)
+ {
+-	unsigned int cpu, num_cpus;
+-	__u16 boot_cpu_addr;
++	__u32 status;
+ 
+-	/*
+-	 * cpu 0 is the boot cpu. See smp_prepare_boot_cpu.
+-	 */
++	/* Check for stopped state */
++	if (signal_processor_ps(&status, 0, cpu, sigp_sense) ==
++	    sigp_status_stored) {
++		if (status & 0x40)
++			return 1;
++	}
++	return 0;
++}
++
++static int cpu_known(int cpu_id)
++{
++	int cpu;
++
++	for_each_present_cpu(cpu) {
++		if (__cpu_logical_map[cpu] == cpu_id)
++			return 1;
++	}
++	return 0;
++}
++
++static int smp_rescan_cpus_sigp(cpumask_t avail)
++{
++	int cpu_id, logical_cpu;
++
++	logical_cpu = first_cpu(avail);
++	if (logical_cpu == NR_CPUS)
++		return 0;
++	for (cpu_id = 0; cpu_id <= 65535; cpu_id++) {
++		if (cpu_known(cpu_id))
++			continue;
++		__cpu_logical_map[logical_cpu] = cpu_id;
++		if (!cpu_stopped(logical_cpu))
++			continue;
++		cpu_set(logical_cpu, cpu_present_map);
++		smp_cpu_state[logical_cpu] = CPU_STATE_CONFIGURED;
++		logical_cpu = next_cpu(logical_cpu, avail);
++		if (logical_cpu == NR_CPUS)
++			break;
++	}
++	return 0;
++}
++
++static int smp_rescan_cpus_sclp(cpumask_t avail)
++{
++	struct sclp_cpu_info *info;
++	int cpu_id, logical_cpu, cpu;
++	int rc;
++
++	logical_cpu = first_cpu(avail);
++	if (logical_cpu == NR_CPUS)
++		return 0;
++	info = kmalloc(sizeof(*info), GFP_KERNEL);
++	if (!info)
++		return -ENOMEM;
++	rc = sclp_get_cpu_info(info);
++	if (rc)
++		goto out;
++	for (cpu = 0; cpu < info->combined; cpu++) {
++		if (info->has_cpu_type && info->cpu[cpu].type != smp_cpu_type)
++			continue;
++		cpu_id = info->cpu[cpu].address;
++		if (cpu_known(cpu_id))
++			continue;
++		__cpu_logical_map[logical_cpu] = cpu_id;
++		cpu_set(logical_cpu, cpu_present_map);
++		if (cpu >= info->configured)
++			smp_cpu_state[logical_cpu] = CPU_STATE_STANDBY;
++		else
++			smp_cpu_state[logical_cpu] = CPU_STATE_CONFIGURED;
++		logical_cpu = next_cpu(logical_cpu, avail);
++		if (logical_cpu == NR_CPUS)
++			break;
++	}
++out:
++	kfree(info);
++	return rc;
++}
++
++static int smp_rescan_cpus(void)
++{
++	cpumask_t avail;
++
++	cpus_xor(avail, cpu_possible_map, cpu_present_map);
++	if (smp_use_sigp_detection)
++		return smp_rescan_cpus_sigp(avail);
++	else
++		return smp_rescan_cpus_sclp(avail);
++}
++
++static void __init smp_detect_cpus(void)
++{
++	unsigned int cpu, c_cpus, s_cpus;
++	struct sclp_cpu_info *info;
++	u16 boot_cpu_addr, cpu_addr;
++
++	c_cpus = 1;
++	s_cpus = 0;
+ 	boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
+-	current_thread_info()->cpu = 0;
+-	num_cpus = 1;
+-	for (cpu = 0; cpu <= 65535; cpu++) {
+-		if ((__u16) cpu == boot_cpu_addr)
++	info = kmalloc(sizeof(*info), GFP_KERNEL);
++	if (!info)
++		panic("smp_detect_cpus failed to allocate memory\n");
++	/* Use sigp detection algorithm if sclp doesn't work. */
++	if (sclp_get_cpu_info(info)) {
++		smp_use_sigp_detection = 1;
++		for (cpu = 0; cpu <= 65535; cpu++) {
++			if (cpu == boot_cpu_addr)
++				continue;
++			__cpu_logical_map[CPU_INIT_NO] = cpu;
++			if (!cpu_stopped(CPU_INIT_NO))
++				continue;
++			smp_get_save_area(c_cpus, cpu);
++			c_cpus++;
++		}
++		goto out;
++	}
++
++	if (info->has_cpu_type) {
++		for (cpu = 0; cpu < info->combined; cpu++) {
++			if (info->cpu[cpu].address == boot_cpu_addr) {
++				smp_cpu_type = info->cpu[cpu].type;
++				break;
++			}
++		}
++	}
++
++	for (cpu = 0; cpu < info->combined; cpu++) {
++		if (info->has_cpu_type && info->cpu[cpu].type != smp_cpu_type)
++			continue;
++		cpu_addr = info->cpu[cpu].address;
++		if (cpu_addr == boot_cpu_addr)
+ 			continue;
+-		__cpu_logical_map[1] = (__u16) cpu;
+-		if (signal_processor(1, sigp_sense) == sigp_not_operational)
++		__cpu_logical_map[CPU_INIT_NO] = cpu_addr;
++		if (!cpu_stopped(CPU_INIT_NO)) {
++			s_cpus++;
+ 			continue;
+-		smp_get_save_area(num_cpus, cpu);
+-		num_cpus++;
++		}
++		smp_get_save_area(c_cpus, cpu_addr);
++		c_cpus++;
+ 	}
+-	printk("Detected %d CPU's\n", (int) num_cpus);
+-	printk("Boot cpu address %2X\n", boot_cpu_addr);
+-	return num_cpus;
++out:
++	kfree(info);
++	printk(KERN_INFO "CPUs: %d configured, %d standby\n", c_cpus, s_cpus);
++	get_online_cpus();
++	smp_rescan_cpus();
++	put_online_cpus();
+ }
+ 
+ /*
+@@ -453,8 +601,6 @@ int __cpuinit start_secondary(void *cpuvoid)
+ 	return 0;
+ }
+ 
+-DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
+-
+ static void __init smp_create_idle(unsigned int cpu)
+ {
+ 	struct task_struct *p;
+@@ -470,37 +616,82 @@ static void __init smp_create_idle(unsigned int cpu)
+ 	spin_lock_init(&(&per_cpu(s390_idle, cpu))->lock);
+ }
+ 
+-static int cpu_stopped(int cpu)
++static int __cpuinit smp_alloc_lowcore(int cpu)
+ {
+-	__u32 status;
++	unsigned long async_stack, panic_stack;
++	struct _lowcore *lowcore;
++	int lc_order;
++
++	lc_order = sizeof(long) == 8 ? 1 : 0;
++	lowcore = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, lc_order);
++	if (!lowcore)
++		return -ENOMEM;
++	async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER);
++	if (!async_stack)
++		goto out_async_stack;
++	panic_stack = __get_free_page(GFP_KERNEL);
++	if (!panic_stack)
++		goto out_panic_stack;
++
++	*lowcore = S390_lowcore;
++	lowcore->async_stack = async_stack + ASYNC_SIZE;
++	lowcore->panic_stack = panic_stack + PAGE_SIZE;
+ 
+-	/* Check for stopped state */
+-	if (signal_processor_ps(&status, 0, cpu, sigp_sense) ==
+-	    sigp_status_stored) {
+-		if (status & 0x40)
+-			return 1;
++#ifndef CONFIG_64BIT
++	if (MACHINE_HAS_IEEE) {
++		unsigned long save_area;
++
++		save_area = get_zeroed_page(GFP_KERNEL);
++		if (!save_area)
++			goto out_save_area;
++		lowcore->extended_save_area_addr = (u32) save_area;
+ 	}
++#endif
++	lowcore_ptr[cpu] = lowcore;
+ 	return 0;
++
++#ifndef CONFIG_64BIT
++out_save_area:
++	free_page(panic_stack);
++#endif
++out_panic_stack:
++	free_pages(async_stack, ASYNC_ORDER);
++out_async_stack:
++	free_pages((unsigned long) lowcore, lc_order);
++	return -ENOMEM;
+ }
+ 
+-/* Upping and downing of CPUs */
++#ifdef CONFIG_HOTPLUG_CPU
++static void smp_free_lowcore(int cpu)
++{
++	struct _lowcore *lowcore;
++	int lc_order;
++
++	lc_order = sizeof(long) == 8 ? 1 : 0;
++	lowcore = lowcore_ptr[cpu];
++#ifndef CONFIG_64BIT
++	if (MACHINE_HAS_IEEE)
++		free_page((unsigned long) lowcore->extended_save_area_addr);
++#endif
++	free_page(lowcore->panic_stack - PAGE_SIZE);
++	free_pages(lowcore->async_stack - ASYNC_SIZE, ASYNC_ORDER);
++	free_pages((unsigned long) lowcore, lc_order);
++	lowcore_ptr[cpu] = NULL;
++}
++#endif /* CONFIG_HOTPLUG_CPU */
+ 
+-int __cpu_up(unsigned int cpu)
++/* Upping and downing of CPUs */
++int __cpuinit __cpu_up(unsigned int cpu)
+ {
+ 	struct task_struct *idle;
+ 	struct _lowcore *cpu_lowcore;
+ 	struct stack_frame *sf;
+ 	sigp_ccode ccode;
+-	int curr_cpu;
+ 
+-	for (curr_cpu = 0; curr_cpu <= 65535; curr_cpu++) {
+-		__cpu_logical_map[cpu] = (__u16) curr_cpu;
+-		if (cpu_stopped(cpu))
+-			break;
+-	}
+-
+-	if (!cpu_stopped(cpu))
+-		return -ENODEV;
++	if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED)
++		return -EIO;
++	if (smp_alloc_lowcore(cpu))
++		return -ENOMEM;
+ 
+ 	ccode = signal_processor_p((__u32)(unsigned long)(lowcore_ptr[cpu]),
+ 				   cpu, sigp_set_prefix);
+@@ -515,6 +706,7 @@ int __cpu_up(unsigned int cpu)
+ 	cpu_lowcore = lowcore_ptr[cpu];
+ 	cpu_lowcore->kernel_stack = (unsigned long)
+ 		task_stack_page(idle) + THREAD_SIZE;
++	cpu_lowcore->thread_info = (unsigned long) task_thread_info(idle);
+ 	sf = (struct stack_frame *) (cpu_lowcore->kernel_stack
+ 				     - sizeof(struct pt_regs)
+ 				     - sizeof(struct stack_frame));
+@@ -528,6 +720,8 @@ int __cpu_up(unsigned int cpu)
+ 	cpu_lowcore->percpu_offset = __per_cpu_offset[cpu];
+ 	cpu_lowcore->current_task = (unsigned long) idle;
+ 	cpu_lowcore->cpu_data.cpu_nr = cpu;
++	cpu_lowcore->softirq_pending = 0;
++	cpu_lowcore->ext_call_fast = 0;
+ 	eieio();
+ 
+ 	while (signal_processor(cpu, sigp_restart) == sigp_busy)
+@@ -538,44 +732,20 @@ int __cpu_up(unsigned int cpu)
+ 	return 0;
+ }
+ 
+-static unsigned int __initdata additional_cpus;
+-static unsigned int __initdata possible_cpus;
+-
+-void __init smp_setup_cpu_possible_map(void)
++static int __init setup_possible_cpus(char *s)
+ {
+-	unsigned int phy_cpus, pos_cpus, cpu;
+-
+-	phy_cpus = smp_count_cpus();
+-	pos_cpus = min(phy_cpus + additional_cpus, (unsigned int) NR_CPUS);
+-
+-	if (possible_cpus)
+-		pos_cpus = min(possible_cpus, (unsigned int) NR_CPUS);
++	int pcpus, cpu;
+ 
+-	for (cpu = 0; cpu < pos_cpus; cpu++)
++	pcpus = simple_strtoul(s, NULL, 0);
++	cpu_possible_map = cpumask_of_cpu(0);
++	for (cpu = 1; cpu < pcpus && cpu < NR_CPUS; cpu++)
+ 		cpu_set(cpu, cpu_possible_map);
+-
+-	phy_cpus = min(phy_cpus, pos_cpus);
+-
+-	for (cpu = 0; cpu < phy_cpus; cpu++)
+-		cpu_set(cpu, cpu_present_map);
+-}
+-
+-#ifdef CONFIG_HOTPLUG_CPU
+-
+-static int __init setup_additional_cpus(char *s)
+-{
+-	additional_cpus = simple_strtoul(s, NULL, 0);
+-	return 0;
+-}
+-early_param("additional_cpus", setup_additional_cpus);
+-
+-static int __init setup_possible_cpus(char *s)
+-{
+-	possible_cpus = simple_strtoul(s, NULL, 0);
+ 	return 0;
+ }
+ early_param("possible_cpus", setup_possible_cpus);
+ 
++#ifdef CONFIG_HOTPLUG_CPU
++
+ int __cpu_disable(void)
+ {
+ 	struct ec_creg_mask_parms cr_parms;
+@@ -612,7 +782,8 @@ void __cpu_die(unsigned int cpu)
+ 	/* Wait until target cpu is down */
+ 	while (!smp_cpu_not_running(cpu))
+ 		cpu_relax();
+-	printk("Processor %d spun down\n", cpu);
++	smp_free_lowcore(cpu);
++	printk(KERN_INFO "Processor %d spun down\n", cpu);
+ }
+ 
+ void cpu_die(void)
+@@ -625,49 +796,19 @@ void cpu_die(void)
+ 
+ #endif /* CONFIG_HOTPLUG_CPU */
+ 
+-/*
+- *	Cycle through the processors and setup structures.
+- */
+-
+ void __init smp_prepare_cpus(unsigned int max_cpus)
+ {
+-	unsigned long stack;
+ 	unsigned int cpu;
+-	int i;
++
++	smp_detect_cpus();
+ 
+ 	/* request the 0x1201 emergency signal external interrupt */
+ 	if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0)
+ 		panic("Couldn't request external interrupt 0x1201");
+ 	memset(lowcore_ptr, 0, sizeof(lowcore_ptr));
+-	/*
+-	 *  Initialize prefix pages and stacks for all possible cpus
+-	 */
+ 	print_cpu_info(&S390_lowcore.cpu_data);
++	smp_alloc_lowcore(smp_processor_id());
+ 
+-	for_each_possible_cpu(i) {
+-		lowcore_ptr[i] = (struct _lowcore *)
+-			__get_free_pages(GFP_KERNEL | GFP_DMA,
+-					 sizeof(void*) == 8 ? 1 : 0);
+-		stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER);
+-		if (!lowcore_ptr[i] || !stack)
+-			panic("smp_boot_cpus failed to allocate memory\n");
+-
+-		*(lowcore_ptr[i]) = S390_lowcore;
+-		lowcore_ptr[i]->async_stack = stack + ASYNC_SIZE;
+-		stack = __get_free_pages(GFP_KERNEL, 0);
+-		if (!stack)
+-			panic("smp_boot_cpus failed to allocate memory\n");
+-		lowcore_ptr[i]->panic_stack = stack + PAGE_SIZE;
+-#ifndef CONFIG_64BIT
+-		if (MACHINE_HAS_IEEE) {
+-			lowcore_ptr[i]->extended_save_area_addr =
+-				(__u32) __get_free_pages(GFP_KERNEL, 0);
+-			if (!lowcore_ptr[i]->extended_save_area_addr)
+-				panic("smp_boot_cpus failed to "
+-				      "allocate memory\n");
+-		}
+-#endif
+-	}
+ #ifndef CONFIG_64BIT
+ 	if (MACHINE_HAS_IEEE)
+ 		ctl_set_bit(14, 29); /* enable extended save area */
+@@ -683,15 +824,17 @@ void __init smp_prepare_boot_cpu(void)
+ {
+ 	BUG_ON(smp_processor_id() != 0);
+ 
++	current_thread_info()->cpu = 0;
++	cpu_set(0, cpu_present_map);
+ 	cpu_set(0, cpu_online_map);
+ 	S390_lowcore.percpu_offset = __per_cpu_offset[0];
+ 	current_set[0] = current;
++	smp_cpu_state[0] = CPU_STATE_CONFIGURED;
+ 	spin_lock_init(&(&__get_cpu_var(s390_idle))->lock);
+ }
+ 
+ void __init smp_cpus_done(unsigned int max_cpus)
+ {
+-	cpu_present_map = cpu_possible_map;
+ }
+ 
+ /*
+@@ -705,7 +848,79 @@ int setup_profiling_timer(unsigned int multiplier)
+ 	return 0;
+ }
+ 
+-static DEFINE_PER_CPU(struct cpu, cpu_devices);
++#ifdef CONFIG_HOTPLUG_CPU
++static ssize_t cpu_configure_show(struct sys_device *dev, char *buf)
++{
++	ssize_t count;
++
++	mutex_lock(&smp_cpu_state_mutex);
++	count = sprintf(buf, "%d\n", smp_cpu_state[dev->id]);
++	mutex_unlock(&smp_cpu_state_mutex);
++	return count;
++}
++
++static ssize_t cpu_configure_store(struct sys_device *dev, const char *buf,
++				   size_t count)
++{
++	int cpu = dev->id;
++	int val, rc;
++	char delim;
++
++	if (sscanf(buf, "%d %c", &val, &delim) != 1)
++		return -EINVAL;
++	if (val != 0 && val != 1)
++		return -EINVAL;
++
++	mutex_lock(&smp_cpu_state_mutex);
++	get_online_cpus();
++	rc = -EBUSY;
++	if (cpu_online(cpu))
++		goto out;
++	rc = 0;
++	switch (val) {
++	case 0:
++		if (smp_cpu_state[cpu] == CPU_STATE_CONFIGURED) {
++			rc = sclp_cpu_deconfigure(__cpu_logical_map[cpu]);
++			if (!rc)
++				smp_cpu_state[cpu] = CPU_STATE_STANDBY;
++		}
++		break;
++	case 1:
++		if (smp_cpu_state[cpu] == CPU_STATE_STANDBY) {
++			rc = sclp_cpu_configure(__cpu_logical_map[cpu]);
++			if (!rc)
++				smp_cpu_state[cpu] = CPU_STATE_CONFIGURED;
++		}
++		break;
++	default:
++		break;
++	}
++out:
++	put_online_cpus();
++	mutex_unlock(&smp_cpu_state_mutex);
++	return rc ? rc : count;
++}
++static SYSDEV_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store);
++#endif /* CONFIG_HOTPLUG_CPU */
++
++static ssize_t show_cpu_address(struct sys_device *dev, char *buf)
++{
++	return sprintf(buf, "%d\n", __cpu_logical_map[dev->id]);
++}
++static SYSDEV_ATTR(address, 0444, show_cpu_address, NULL);
++
++
++static struct attribute *cpu_common_attrs[] = {
++#ifdef CONFIG_HOTPLUG_CPU
++	&attr_configure.attr,
++#endif
++	&attr_address.attr,
++	NULL,
++};
++
++static struct attribute_group cpu_common_attr_group = {
++	.attrs = cpu_common_attrs,
++};
+ 
+ static ssize_t show_capability(struct sys_device *dev, char *buf)
+ {
+@@ -750,15 +965,15 @@ static ssize_t show_idle_time(struct sys_device *dev, char *buf)
+ }
+ static SYSDEV_ATTR(idle_time_us, 0444, show_idle_time, NULL);
+ 
+-static struct attribute *cpu_attrs[] = {
++static struct attribute *cpu_online_attrs[] = {
+ 	&attr_capability.attr,
+ 	&attr_idle_count.attr,
+ 	&attr_idle_time_us.attr,
+ 	NULL,
+ };
+ 
+-static struct attribute_group cpu_attr_group = {
+-	.attrs = cpu_attrs,
++static struct attribute_group cpu_online_attr_group = {
++	.attrs = cpu_online_attrs,
+ };
+ 
+ static int __cpuinit smp_cpu_notify(struct notifier_block *self,
+@@ -778,12 +993,12 @@ static int __cpuinit smp_cpu_notify(struct notifier_block *self,
+ 		idle->idle_time = 0;
+ 		idle->idle_count = 0;
+ 		spin_unlock_irq(&idle->lock);
+-		if (sysfs_create_group(&s->kobj, &cpu_attr_group))
++		if (sysfs_create_group(&s->kobj, &cpu_online_attr_group))
+ 			return NOTIFY_BAD;
+ 		break;
+ 	case CPU_DEAD:
+ 	case CPU_DEAD_FROZEN:
+-		sysfs_remove_group(&s->kobj, &cpu_attr_group);
++		sysfs_remove_group(&s->kobj, &cpu_online_attr_group);
+ 		break;
+ 	}
+ 	return NOTIFY_OK;
+@@ -793,6 +1008,62 @@ static struct notifier_block __cpuinitdata smp_cpu_nb = {
+ 	.notifier_call = smp_cpu_notify,
+ };
+ 
++static int smp_add_present_cpu(int cpu)
++{
++	struct cpu *c = &per_cpu(cpu_devices, cpu);
++	struct sys_device *s = &c->sysdev;
++	int rc;
++
++	c->hotpluggable = 1;
++	rc = register_cpu(c, cpu);
++	if (rc)
++		goto out;
++	rc = sysfs_create_group(&s->kobj, &cpu_common_attr_group);
++	if (rc)
++		goto out_cpu;
++	if (!cpu_online(cpu))
++		goto out;
++	rc = sysfs_create_group(&s->kobj, &cpu_online_attr_group);
++	if (!rc)
++		return 0;
++	sysfs_remove_group(&s->kobj, &cpu_common_attr_group);
++out_cpu:
++#ifdef CONFIG_HOTPLUG_CPU
++	unregister_cpu(c);
++#endif
++out:
++	return rc;
++}
++
++#ifdef CONFIG_HOTPLUG_CPU
++static ssize_t rescan_store(struct sys_device *dev, const char *buf,
++			    size_t count)
++{
++	cpumask_t newcpus;
++	int cpu;
++	int rc;
++
++	mutex_lock(&smp_cpu_state_mutex);
++	get_online_cpus();
++	newcpus = cpu_present_map;
++	rc = smp_rescan_cpus();
++	if (rc)
++		goto out;
++	cpus_andnot(newcpus, cpu_present_map, newcpus);
++	for_each_cpu_mask(cpu, newcpus) {
++		rc = smp_add_present_cpu(cpu);
++		if (rc)
++			cpu_clear(cpu, cpu_present_map);
++	}
++	rc = 0;
++out:
++	put_online_cpus();
++	mutex_unlock(&smp_cpu_state_mutex);
++	return rc ? rc : count;
++}
++static SYSDEV_ATTR(rescan, 0200, NULL, rescan_store);
++#endif /* CONFIG_HOTPLUG_CPU */
++
+ static int __init topology_init(void)
+ {
+ 	int cpu;
+@@ -800,16 +1071,14 @@ static int __init topology_init(void)
+ 
+ 	register_cpu_notifier(&smp_cpu_nb);
+ 
+-	for_each_possible_cpu(cpu) {
+-		struct cpu *c = &per_cpu(cpu_devices, cpu);
+-		struct sys_device *s = &c->sysdev;
+-
+-		c->hotpluggable = 1;
+-		register_cpu(c, cpu);
+-		if (!cpu_online(cpu))
+-			continue;
+-		s = &c->sysdev;
+-		rc = sysfs_create_group(&s->kobj, &cpu_attr_group);
++#ifdef CONFIG_HOTPLUG_CPU
++	rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
++			       &attr_rescan.attr);
++	if (rc)
++		return rc;
++#endif
++	for_each_present_cpu(cpu) {
++		rc = smp_add_present_cpu(cpu);
+ 		if (rc)
+ 			return rc;
+ 	}
+diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
+index 22b800c..3bbac12 100644
+--- a/arch/s390/kernel/time.c
++++ b/arch/s390/kernel/time.c
+@@ -1145,7 +1145,7 @@ static void etr_work_fn(struct work_struct *work)
+  * Sysfs interface functions
+  */
+ static struct sysdev_class etr_sysclass = {
+-	set_kset_name("etr")
++	.name	= "etr",
+ };
+ 
+ static struct sys_device etr_port0_dev = {
+diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
+index 8ed16a8..52b8342 100644
+--- a/arch/s390/kernel/traps.c
++++ b/arch/s390/kernel/traps.c
+@@ -31,6 +31,7 @@
+ #include <linux/reboot.h>
+ #include <linux/kprobes.h>
+ #include <linux/bug.h>
++#include <linux/utsname.h>
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+@@ -168,9 +169,16 @@ void show_stack(struct task_struct *task, unsigned long *sp)
+  */
+ void dump_stack(void)
+ {
++	printk("CPU: %d %s %s %.*s\n",
++	       task_thread_info(current)->cpu, print_tainted(),
++	       init_utsname()->release,
++	       (int)strcspn(init_utsname()->version, " "),
++	       init_utsname()->version);
++	printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
++	       current->comm, current->pid, current,
++	       (void *) current->thread.ksp);
+ 	show_stack(NULL, NULL);
+ }
+-
+ EXPORT_SYMBOL(dump_stack);
+ 
+ static inline int mask_bits(struct pt_regs *regs, unsigned long bits)
+@@ -258,8 +266,14 @@ void die(const char * str, struct pt_regs * regs, long err)
+ 	console_verbose();
+ 	spin_lock_irq(&die_lock);
+ 	bust_spinlocks(1);
+-	printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
+-	print_modules();
++	printk("%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter);
++#ifdef CONFIG_PREEMPT
++	printk("PREEMPT ");
++#endif
++#ifdef CONFIG_SMP
++	printk("SMP");
++#endif
++	printk("\n");
+ 	notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV);
+ 	show_regs(regs);
+ 	bust_spinlocks(0);
+diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
+index 849120e..9361591 100644
+--- a/arch/s390/kernel/vmlinux.lds.S
++++ b/arch/s390/kernel/vmlinux.lds.S
+@@ -17,6 +17,12 @@ ENTRY(_start)
+ jiffies = jiffies_64;
+ #endif
+ 
++PHDRS {
++	text PT_LOAD FLAGS(5);	/* R_E */
++	data PT_LOAD FLAGS(7);	/* RWE */
++	note PT_NOTE FLAGS(0);	/* ___ */
++}
++
+ SECTIONS
+ {
+ 	. = 0x00000000;
+@@ -33,6 +39,9 @@ SECTIONS
+ 
+ 	_etext = .;		/* End of text section */
+ 
++	NOTES :text :note
++	BUG_TABLE :text
++
+ 	RODATA
+ 
+ #ifdef CONFIG_SHARED_KERNEL
+@@ -49,9 +58,6 @@ SECTIONS
+ 		__stop___ex_table = .;
+ 	}
+ 
+-	NOTES
+-	BUG_TABLE
+-
+ 	.data : {		/* Data */
+ 		DATA_DATA
+ 		CONSTRUCTORS
+diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c
+index 8d76403..e41f400 100644
+--- a/arch/s390/lib/spinlock.c
++++ b/arch/s390/lib/spinlock.c
+@@ -39,7 +39,7 @@ static inline void _raw_yield_cpu(int cpu)
+ 		_raw_yield();
+ }
+ 
+-void _raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc)
++void _raw_spin_lock_wait(raw_spinlock_t *lp)
+ {
+ 	int count = spin_retry;
+ 	unsigned int cpu = ~smp_processor_id();
+@@ -53,15 +53,36 @@ void _raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc)
+ 		}
+ 		if (__raw_spin_is_locked(lp))
+ 			continue;
+-		if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) {
+-			lp->owner_pc = pc;
++		if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0)
+ 			return;
+-		}
+ 	}
+ }
+ EXPORT_SYMBOL(_raw_spin_lock_wait);
+ 
+-int _raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc)
++void _raw_spin_lock_wait_flags(raw_spinlock_t *lp, unsigned long flags)
++{
++	int count = spin_retry;
++	unsigned int cpu = ~smp_processor_id();
++
++	local_irq_restore(flags);
++	while (1) {
++		if (count-- <= 0) {
++			unsigned int owner = lp->owner_cpu;
++			if (owner != 0)
++				_raw_yield_cpu(~owner);
++			count = spin_retry;
++		}
++		if (__raw_spin_is_locked(lp))
++			continue;
++		local_irq_disable();
++		if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0)
++			return;
++		local_irq_restore(flags);
++	}
++}
++EXPORT_SYMBOL(_raw_spin_lock_wait_flags);
++
++int _raw_spin_trylock_retry(raw_spinlock_t *lp)
+ {
+ 	unsigned int cpu = ~smp_processor_id();
+ 	int count;
+@@ -69,10 +90,8 @@ int _raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc)
+ 	for (count = spin_retry; count > 0; count--) {
+ 		if (__raw_spin_is_locked(lp))
+ 			continue;
+-		if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) {
+-			lp->owner_pc = pc;
++		if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0)
+ 			return 1;
+-		}
+ 	}
+ 	return 0;
+ }
+diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c
+index 394980b..880b0eb 100644
+--- a/arch/s390/mm/extmem.c
++++ b/arch/s390/mm/extmem.c
+@@ -83,7 +83,7 @@ struct dcss_segment {
+ };
+ 
+ static DEFINE_MUTEX(dcss_lock);
+-static struct list_head dcss_list = LIST_HEAD_INIT(dcss_list);
++static LIST_HEAD(dcss_list);
+ static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC",
+ 					"EW/EN-MIXED" };
+ 
+diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
+index fb9c5a8..79d13a1 100644
+--- a/arch/s390/mm/vmem.c
++++ b/arch/s390/mm/vmem.c
+@@ -15,10 +15,6 @@
+ #include <asm/setup.h>
+ #include <asm/tlbflush.h>
+ 
+-unsigned long vmalloc_end;
+-EXPORT_SYMBOL(vmalloc_end);
+-
+-static struct page *vmem_map;
+ static DEFINE_MUTEX(vmem_mutex);
+ 
+ struct memory_segment {
+@@ -188,8 +184,8 @@ static int vmem_add_mem_map(unsigned long start, unsigned long size)
+ 	pte_t  pte;
+ 	int ret = -ENOMEM;
+ 
+-	map_start = vmem_map + PFN_DOWN(start);
+-	map_end	= vmem_map + PFN_DOWN(start + size);
++	map_start = VMEM_MAP + PFN_DOWN(start);
++	map_end	= VMEM_MAP + PFN_DOWN(start + size);
+ 
+ 	start_addr = (unsigned long) map_start & PAGE_MASK;
+ 	end_addr = PFN_ALIGN((unsigned long) map_end);
+@@ -240,10 +236,10 @@ static int vmem_add_mem(unsigned long start, unsigned long size)
+ {
+ 	int ret;
+ 
+-	ret = vmem_add_range(start, size);
++	ret = vmem_add_mem_map(start, size);
+ 	if (ret)
+ 		return ret;
+-	return vmem_add_mem_map(start, size);
++	return vmem_add_range(start, size);
+ }
+ 
+ /*
+@@ -254,7 +250,7 @@ static int insert_memory_segment(struct memory_segment *seg)
+ {
+ 	struct memory_segment *tmp;
+ 
+-	if (PFN_DOWN(seg->start + seg->size) > max_pfn ||
++	if (seg->start + seg->size >= VMALLOC_START ||
+ 	    seg->start + seg->size < seg->start)
+ 		return -ERANGE;
+ 
+@@ -357,17 +353,15 @@ out:
+ 
+ /*
+  * map whole physical memory to virtual memory (identity mapping)
++ * we reserve enough space in the vmalloc area for vmemmap to hotplug
++ * additional memory segments.
+  */
+ void __init vmem_map_init(void)
+ {
+-	unsigned long map_size;
+ 	int i;
+ 
+-	map_size = ALIGN(max_low_pfn, MAX_ORDER_NR_PAGES) * sizeof(struct page);
+-	vmalloc_end = PFN_ALIGN(VMALLOC_END_INIT) - PFN_ALIGN(map_size);
+-	vmem_map = (struct page *) vmalloc_end;
+-	NODE_DATA(0)->node_mem_map = vmem_map;
+-
++	BUILD_BUG_ON((unsigned long)VMEM_MAP + VMEM_MAP_SIZE > VMEM_MAP_MAX);
++	NODE_DATA(0)->node_mem_map = VMEM_MAP;
+ 	for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++)
+ 		vmem_add_mem(memory_chunk[i].addr, memory_chunk[i].size);
+ }
+@@ -382,7 +376,7 @@ static int __init vmem_convert_memory_chunk(void)
+ 	int i;
+ 
+ 	mutex_lock(&vmem_mutex);
+-	for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) {
++	for (i = 0; i < MEMORY_CHUNKS; i++) {
+ 		if (!memory_chunk[i].size)
+ 			continue;
+ 		seg = kzalloc(sizeof(*seg), GFP_KERNEL);
+diff --git a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c
+index eebcd47..51b57c0 100644
+--- a/arch/sh/drivers/dma/dma-sysfs.c
++++ b/arch/sh/drivers/dma/dma-sysfs.c
+@@ -19,7 +19,7 @@
+ #include <asm/dma.h>
+ 
+ static struct sysdev_class dma_sysclass = {
+-	set_kset_name("dma"),
++	.name = "dma",
+ };
+ EXPORT_SYMBOL(dma_sysclass);
+ 
+diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c
+index b22a78c..3008c00 100644
+--- a/arch/sh/kernel/cpu/sh4/sq.c
++++ b/arch/sh/kernel/cpu/sh4/sq.c
+@@ -341,17 +341,18 @@ static int __devinit sq_sysdev_add(struct sys_device *sysdev)
+ {
+ 	unsigned int cpu = sysdev->id;
+ 	struct kobject *kobj;
++	int error;
+ 
+ 	sq_kobject[cpu] = kzalloc(sizeof(struct kobject), GFP_KERNEL);
+ 	if (unlikely(!sq_kobject[cpu]))
+ 		return -ENOMEM;
+ 
+ 	kobj = sq_kobject[cpu];
+-	kobj->parent = &sysdev->kobj;
+-	kobject_set_name(kobj, "%s", "sq");
+-	kobj->ktype = &ktype_percpu_entry;
+-
+-	return kobject_register(kobj);
++	error = kobject_init_and_add(kobj, &ktype_percpu_entry, &sysdev->kobj,
++				     "%s", "sq");
++	if (!error)
++		kobject_uevent(kobj, KOBJ_ADD);
++	return error;
+ }
+ 
+ static int __devexit sq_sysdev_remove(struct sys_device *sysdev)
+@@ -359,7 +360,7 @@ static int __devexit sq_sysdev_remove(struct sys_device *sysdev)
+ 	unsigned int cpu = sysdev->id;
+ 	struct kobject *kobj = sq_kobject[cpu];
+ 
+-	kobject_unregister(kobj);
++	kobject_put(kobj);
+ 	return 0;
+ }
+ 
+diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
+index a3a67d1..2bc04bf 100644
+--- a/arch/sh/kernel/time.c
++++ b/arch/sh/kernel/time.c
+@@ -174,7 +174,7 @@ int timer_resume(struct sys_device *dev)
+ #endif
+ 
+ static struct sysdev_class timer_sysclass = {
+-	set_kset_name("timer"),
++	.name	 = "timer",
+ 	.suspend = timer_suspend,
+ 	.resume	 = timer_resume,
+ };
+diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
+index 46bb609..3874c2d 100644
+--- a/arch/x86/crypto/Makefile
++++ b/arch/x86/crypto/Makefile
+@@ -4,12 +4,16 @@
+ 
+ obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o
+ obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o
++obj-$(CONFIG_CRYPTO_SALSA20_586) += salsa20-i586.o
+ 
+ obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o
+ obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o
++obj-$(CONFIG_CRYPTO_SALSA20_X86_64) += salsa20-x86_64.o
+ 
+-aes-i586-y := aes-i586-asm_32.o aes_32.o
+-twofish-i586-y := twofish-i586-asm_32.o twofish_32.o
++aes-i586-y := aes-i586-asm_32.o aes_glue.o
++twofish-i586-y := twofish-i586-asm_32.o twofish_glue.o
++salsa20-i586-y := salsa20-i586-asm_32.o salsa20_glue.o
+ 
+-aes-x86_64-y := aes-x86_64-asm_64.o aes_64.o
+-twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_64.o
++aes-x86_64-y := aes-x86_64-asm_64.o aes_glue.o
++twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_glue.o
++salsa20-x86_64-y := salsa20-x86_64-asm_64.o salsa20_glue.o
+diff --git a/arch/x86/crypto/aes-i586-asm_32.S b/arch/x86/crypto/aes-i586-asm_32.S
+index f942f0c..1093bed 100644
+--- a/arch/x86/crypto/aes-i586-asm_32.S
++++ b/arch/x86/crypto/aes-i586-asm_32.S
+@@ -46,9 +46,9 @@
+ #define in_blk 16
+ 
+ /* offsets in crypto_tfm structure */
+-#define ekey (crypto_tfm_ctx_offset + 0)
+-#define nrnd (crypto_tfm_ctx_offset + 256)
+-#define dkey (crypto_tfm_ctx_offset + 260)
++#define klen (crypto_tfm_ctx_offset + 0)
++#define ekey (crypto_tfm_ctx_offset + 4)
++#define dkey (crypto_tfm_ctx_offset + 244)
+ 
+ // register mapping for encrypt and decrypt subroutines
+ 
+@@ -221,8 +221,8 @@
+ 
+ .global  aes_enc_blk
+ 
+-.extern  ft_tab
+-.extern  fl_tab
++.extern  crypto_ft_tab
++.extern  crypto_fl_tab
+ 
+ .align 4
+ 
+@@ -236,7 +236,7 @@ aes_enc_blk:
+ 1:	push    %ebx
+ 	mov     in_blk+4(%esp),%r2
+ 	push    %esi
+-	mov     nrnd(%ebp),%r3   // number of rounds
++	mov     klen(%ebp),%r3   // key size
+ 	push    %edi
+ #if ekey != 0
+ 	lea     ekey(%ebp),%ebp  // key pointer
+@@ -255,26 +255,26 @@ aes_enc_blk:
+ 
+ 	sub     $8,%esp		// space for register saves on stack
+ 	add     $16,%ebp	// increment to next round key
+-	cmp     $12,%r3
++	cmp     $24,%r3
+ 	jb      4f		// 10 rounds for 128-bit key
+ 	lea     32(%ebp),%ebp
+ 	je      3f		// 12 rounds for 192-bit key
+ 	lea     32(%ebp),%ebp
+ 
+-2:	fwd_rnd1( -64(%ebp) ,ft_tab)	// 14 rounds for 256-bit key
+-	fwd_rnd2( -48(%ebp) ,ft_tab)
+-3:	fwd_rnd1( -32(%ebp) ,ft_tab)	// 12 rounds for 192-bit key
+-	fwd_rnd2( -16(%ebp) ,ft_tab)
+-4:	fwd_rnd1(    (%ebp) ,ft_tab)	// 10 rounds for 128-bit key
+-	fwd_rnd2( +16(%ebp) ,ft_tab)
+-	fwd_rnd1( +32(%ebp) ,ft_tab)
+-	fwd_rnd2( +48(%ebp) ,ft_tab)
+-	fwd_rnd1( +64(%ebp) ,ft_tab)
+-	fwd_rnd2( +80(%ebp) ,ft_tab)
+-	fwd_rnd1( +96(%ebp) ,ft_tab)
+-	fwd_rnd2(+112(%ebp) ,ft_tab)
+-	fwd_rnd1(+128(%ebp) ,ft_tab)
+-	fwd_rnd2(+144(%ebp) ,fl_tab)	// last round uses a different table
++2:	fwd_rnd1( -64(%ebp), crypto_ft_tab)	// 14 rounds for 256-bit key
++	fwd_rnd2( -48(%ebp), crypto_ft_tab)
++3:	fwd_rnd1( -32(%ebp), crypto_ft_tab)	// 12 rounds for 192-bit key
++	fwd_rnd2( -16(%ebp), crypto_ft_tab)
++4:	fwd_rnd1(    (%ebp), crypto_ft_tab)	// 10 rounds for 128-bit key
++	fwd_rnd2( +16(%ebp), crypto_ft_tab)
++	fwd_rnd1( +32(%ebp), crypto_ft_tab)
++	fwd_rnd2( +48(%ebp), crypto_ft_tab)
++	fwd_rnd1( +64(%ebp), crypto_ft_tab)
++	fwd_rnd2( +80(%ebp), crypto_ft_tab)
++	fwd_rnd1( +96(%ebp), crypto_ft_tab)
++	fwd_rnd2(+112(%ebp), crypto_ft_tab)
++	fwd_rnd1(+128(%ebp), crypto_ft_tab)
++	fwd_rnd2(+144(%ebp), crypto_fl_tab)	// last round uses a different table
+ 
+ // move final values to the output array.  CAUTION: the 
+ // order of these assigns rely on the register mappings
+@@ -297,8 +297,8 @@ aes_enc_blk:
+ 
+ .global  aes_dec_blk
+ 
+-.extern  it_tab
+-.extern  il_tab
++.extern  crypto_it_tab
++.extern  crypto_il_tab
+ 
+ .align 4
+ 
+@@ -312,14 +312,11 @@ aes_dec_blk:
+ 1:	push    %ebx
+ 	mov     in_blk+4(%esp),%r2
+ 	push    %esi
+-	mov     nrnd(%ebp),%r3   // number of rounds
++	mov     klen(%ebp),%r3   // key size
+ 	push    %edi
+ #if dkey != 0
+ 	lea     dkey(%ebp),%ebp  // key pointer
+ #endif
+-	mov     %r3,%r0
+-	shl     $4,%r0
+-	add     %r0,%ebp
+ 	
+ // input four columns and xor in first round key
+ 
+@@ -333,27 +330,27 @@ aes_dec_blk:
+ 	xor     12(%ebp),%r5
+ 
+ 	sub     $8,%esp		// space for register saves on stack
+-	sub     $16,%ebp	// increment to next round key
+-	cmp     $12,%r3
++	add     $16,%ebp	// increment to next round key
++	cmp     $24,%r3
+ 	jb      4f		// 10 rounds for 128-bit key
+-	lea     -32(%ebp),%ebp
++	lea     32(%ebp),%ebp
+ 	je      3f		// 12 rounds for 192-bit key
+-	lea     -32(%ebp),%ebp
+-
+-2:	inv_rnd1( +64(%ebp), it_tab)	// 14 rounds for 256-bit key
+-	inv_rnd2( +48(%ebp), it_tab)
+-3:	inv_rnd1( +32(%ebp), it_tab)	// 12 rounds for 192-bit key
+-	inv_rnd2( +16(%ebp), it_tab)
+-4:	inv_rnd1(    (%ebp), it_tab)	// 10 rounds for 128-bit key
+-	inv_rnd2( -16(%ebp), it_tab)
+-	inv_rnd1( -32(%ebp), it_tab)
+-	inv_rnd2( -48(%ebp), it_tab)
+-	inv_rnd1( -64(%ebp), it_tab)
+-	inv_rnd2( -80(%ebp), it_tab)
+-	inv_rnd1( -96(%ebp), it_tab)
+-	inv_rnd2(-112(%ebp), it_tab)
+-	inv_rnd1(-128(%ebp), it_tab)
+-	inv_rnd2(-144(%ebp), il_tab)	// last round uses a different table
++	lea     32(%ebp),%ebp
++
++2:	inv_rnd1( -64(%ebp), crypto_it_tab)	// 14 rounds for 256-bit key
++	inv_rnd2( -48(%ebp), crypto_it_tab)
++3:	inv_rnd1( -32(%ebp), crypto_it_tab)	// 12 rounds for 192-bit key
++	inv_rnd2( -16(%ebp), crypto_it_tab)
++4:	inv_rnd1(    (%ebp), crypto_it_tab)	// 10 rounds for 128-bit key
++	inv_rnd2( +16(%ebp), crypto_it_tab)
++	inv_rnd1( +32(%ebp), crypto_it_tab)
++	inv_rnd2( +48(%ebp), crypto_it_tab)
++	inv_rnd1( +64(%ebp), crypto_it_tab)
++	inv_rnd2( +80(%ebp), crypto_it_tab)
++	inv_rnd1( +96(%ebp), crypto_it_tab)
++	inv_rnd2(+112(%ebp), crypto_it_tab)
++	inv_rnd1(+128(%ebp), crypto_it_tab)
++	inv_rnd2(+144(%ebp), crypto_il_tab)	// last round uses a different table
+ 
+ // move final values to the output array.  CAUTION: the 
+ // order of these assigns rely on the register mappings
+diff --git a/arch/x86/crypto/aes-x86_64-asm_64.S b/arch/x86/crypto/aes-x86_64-asm_64.S
+index 26b40de..a120f52 100644
+--- a/arch/x86/crypto/aes-x86_64-asm_64.S
++++ b/arch/x86/crypto/aes-x86_64-asm_64.S
+@@ -8,10 +8,10 @@
+  * including this sentence is retained in full.
+  */
+ 
+-.extern aes_ft_tab
+-.extern aes_it_tab
+-.extern aes_fl_tab
+-.extern aes_il_tab
++.extern crypto_ft_tab
++.extern crypto_it_tab
++.extern crypto_fl_tab
++.extern crypto_il_tab
+ 
+ .text
+ 
+@@ -56,13 +56,13 @@
+ 	.align	8;			\
+ FUNC:	movq	r1,r2;			\
+ 	movq	r3,r4;			\
+-	leaq	BASE+KEY+52(r8),r9;	\
++	leaq	BASE+KEY+48+4(r8),r9;	\
+ 	movq	r10,r11;		\
+ 	movl	(r7),r5 ## E;		\
+ 	movl	4(r7),r1 ## E;		\
+ 	movl	8(r7),r6 ## E;		\
+ 	movl	12(r7),r7 ## E;		\
+-	movl	BASE(r8),r10 ## E;	\
++	movl	BASE+0(r8),r10 ## E;	\
+ 	xorl	-48(r9),r5 ## E;	\
+ 	xorl	-44(r9),r1 ## E;	\
+ 	xorl	-40(r9),r6 ## E;	\
+@@ -154,37 +154,37 @@ FUNC:	movq	r1,r2;			\
+ /* void aes_enc_blk(stuct crypto_tfm *tfm, u8 *out, const u8 *in) */
+ 
+ 	entry(aes_enc_blk,0,enc128,enc192)
+-	encrypt_round(aes_ft_tab,-96)
+-	encrypt_round(aes_ft_tab,-80)
+-enc192:	encrypt_round(aes_ft_tab,-64)
+-	encrypt_round(aes_ft_tab,-48)
+-enc128:	encrypt_round(aes_ft_tab,-32)
+-	encrypt_round(aes_ft_tab,-16)
+-	encrypt_round(aes_ft_tab,  0)
+-	encrypt_round(aes_ft_tab, 16)
+-	encrypt_round(aes_ft_tab, 32)
+-	encrypt_round(aes_ft_tab, 48)
+-	encrypt_round(aes_ft_tab, 64)
+-	encrypt_round(aes_ft_tab, 80)
+-	encrypt_round(aes_ft_tab, 96)
+-	encrypt_final(aes_fl_tab,112)
++	encrypt_round(crypto_ft_tab,-96)
++	encrypt_round(crypto_ft_tab,-80)
++enc192:	encrypt_round(crypto_ft_tab,-64)
++	encrypt_round(crypto_ft_tab,-48)
++enc128:	encrypt_round(crypto_ft_tab,-32)
++	encrypt_round(crypto_ft_tab,-16)
++	encrypt_round(crypto_ft_tab,  0)
++	encrypt_round(crypto_ft_tab, 16)
++	encrypt_round(crypto_ft_tab, 32)
++	encrypt_round(crypto_ft_tab, 48)
++	encrypt_round(crypto_ft_tab, 64)
++	encrypt_round(crypto_ft_tab, 80)
++	encrypt_round(crypto_ft_tab, 96)
++	encrypt_final(crypto_fl_tab,112)
+ 	return
+ 
+ /* void aes_dec_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in) */
+ 
+ 	entry(aes_dec_blk,240,dec128,dec192)
+-	decrypt_round(aes_it_tab,-96)
+-	decrypt_round(aes_it_tab,-80)
+-dec192:	decrypt_round(aes_it_tab,-64)
+-	decrypt_round(aes_it_tab,-48)
+-dec128:	decrypt_round(aes_it_tab,-32)
+-	decrypt_round(aes_it_tab,-16)
+-	decrypt_round(aes_it_tab,  0)
+-	decrypt_round(aes_it_tab, 16)
+-	decrypt_round(aes_it_tab, 32)
+-	decrypt_round(aes_it_tab, 48)
+-	decrypt_round(aes_it_tab, 64)
+-	decrypt_round(aes_it_tab, 80)
+-	decrypt_round(aes_it_tab, 96)
+-	decrypt_final(aes_il_tab,112)
++	decrypt_round(crypto_it_tab,-96)
++	decrypt_round(crypto_it_tab,-80)
++dec192:	decrypt_round(crypto_it_tab,-64)
++	decrypt_round(crypto_it_tab,-48)
++dec128:	decrypt_round(crypto_it_tab,-32)
++	decrypt_round(crypto_it_tab,-16)
++	decrypt_round(crypto_it_tab,  0)
++	decrypt_round(crypto_it_tab, 16)
++	decrypt_round(crypto_it_tab, 32)
++	decrypt_round(crypto_it_tab, 48)
++	decrypt_round(crypto_it_tab, 64)
++	decrypt_round(crypto_it_tab, 80)
++	decrypt_round(crypto_it_tab, 96)
++	decrypt_final(crypto_il_tab,112)
+ 	return
+diff --git a/arch/x86/crypto/aes_32.c b/arch/x86/crypto/aes_32.c
+deleted file mode 100644
+index 49aad93..0000000
+--- a/arch/x86/crypto/aes_32.c
++++ /dev/null
+@@ -1,515 +0,0 @@
+-/* 
+- * 
+- * Glue Code for optimized 586 assembler version of AES
+- *
+- * Copyright (c) 2002, Dr Brian Gladman <>, Worcester, UK.
+- * All rights reserved.
+- *
+- * LICENSE TERMS
+- *
+- * The free distribution and use of this software in both source and binary
+- * form is allowed (with or without changes) provided that:
+- *
+- *   1. distributions of this source code include the above copyright
+- *      notice, this list of conditions and the following disclaimer;
+- *
+- *   2. distributions in binary form include the above copyright
+- *      notice, this list of conditions and the following disclaimer
+- *      in the documentation and/or other associated materials;
+- *
+- *   3. the copyright holder's name is not used to endorse products
+- *      built using this software without specific written permission.
+- *
+- * ALTERNATIVELY, provided that this notice is retained in full, this product
+- * may be distributed under the terms of the GNU General Public License (GPL),
+- * in which case the provisions of the GPL apply INSTEAD OF those given above.
+- *
+- * DISCLAIMER
+- *
+- * This software is provided 'as is' with no explicit or implied warranties
+- * in respect of its properties, including, but not limited to, correctness
+- * and/or fitness for purpose.
+- *
+- * Copyright (c) 2003, Adam J. Richter <adam at yggdrasil.com> (conversion to
+- * 2.5 API).
+- * Copyright (c) 2003, 2004 Fruhwirth Clemens <clemens at endorphin.org>
+- * Copyright (c) 2004 Red Hat, Inc., James Morris <jmorris at redhat.com>
+- *
+- */
+-
+-#include <asm/byteorder.h>
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <linux/init.h>
+-#include <linux/types.h>
+-#include <linux/crypto.h>
+-#include <linux/linkage.h>
+-
+-asmlinkage void aes_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
+-asmlinkage void aes_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
+-
+-#define AES_MIN_KEY_SIZE	16
+-#define AES_MAX_KEY_SIZE	32
+-#define AES_BLOCK_SIZE		16
+-#define AES_KS_LENGTH		4 * AES_BLOCK_SIZE
+-#define RC_LENGTH		29
+-
+-struct aes_ctx {
+-	u32 ekey[AES_KS_LENGTH];
+-	u32 rounds;
+-	u32 dkey[AES_KS_LENGTH];
+-};
+-
+-#define WPOLY 0x011b
+-#define bytes2word(b0, b1, b2, b3)  \
+-	(((u32)(b3) << 24) | ((u32)(b2) << 16) | ((u32)(b1) << 8) | (b0))
+-
+-/* define the finite field multiplies required for Rijndael */
+-#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
+-#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
+-#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
+-#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
+-#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
+-#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
+-#define fi(x) ((x) ?   pow[255 - log[x]]: 0)
+-
+-static inline u32 upr(u32 x, int n)
+-{
+-	return (x << 8 * n) | (x >> (32 - 8 * n));
+-}
+-
+-static inline u8 bval(u32 x, int n)
+-{
+-	return x >> 8 * n;
+-}
+-
+-/* The forward and inverse affine transformations used in the S-box */
+-#define fwd_affine(x) \
+-	(w = (u32)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(u8)(w^(w>>8)))
+-
+-#define inv_affine(x) \
+-	(w = (u32)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(u8)(w^(w>>8)))
+-
+-static u32 rcon_tab[RC_LENGTH];
+-
+-u32 ft_tab[4][256];
+-u32 fl_tab[4][256];
+-static u32 im_tab[4][256];
+-u32 il_tab[4][256];
+-u32 it_tab[4][256];
+-
+-static void gen_tabs(void)
+-{
+-	u32 i, w;
+-	u8 pow[512], log[256];
+-
+-	/*
+-	 * log and power tables for GF(2^8) finite field with
+-	 * WPOLY as modular polynomial - the simplest primitive
+-	 * root is 0x03, used here to generate the tables.
+-	 */
+-	i = 0; w = 1; 
+-	
+-	do {
+-		pow[i] = (u8)w;
+-		pow[i + 255] = (u8)w;
+-		log[w] = (u8)i++;
+-		w ^=  (w << 1) ^ (w & 0x80 ? WPOLY : 0);
+-	} while (w != 1);
+-	
+-	for(i = 0, w = 1; i < RC_LENGTH; ++i) {
+-		rcon_tab[i] = bytes2word(w, 0, 0, 0);
+-		w = f2(w);
+-	}
+-
+-	for(i = 0; i < 256; ++i) {
+-		u8 b;
+-		
+-		b = fwd_affine(fi((u8)i));
+-		w = bytes2word(f2(b), b, b, f3(b));
+-
+-		/* tables for a normal encryption round */
+-		ft_tab[0][i] = w;
+-		ft_tab[1][i] = upr(w, 1);
+-		ft_tab[2][i] = upr(w, 2);
+-		ft_tab[3][i] = upr(w, 3);
+-		w = bytes2word(b, 0, 0, 0);
+-		
+-		/*
+-		 * tables for last encryption round
+-		 * (may also be used in the key schedule)
+-		 */
+-		fl_tab[0][i] = w;
+-		fl_tab[1][i] = upr(w, 1);
+-		fl_tab[2][i] = upr(w, 2);
+-		fl_tab[3][i] = upr(w, 3);
+-		
+-		b = fi(inv_affine((u8)i));
+-		w = bytes2word(fe(b), f9(b), fd(b), fb(b));
+-
+-		/* tables for the inverse mix column operation  */
+-		im_tab[0][b] = w;
+-		im_tab[1][b] = upr(w, 1);
+-		im_tab[2][b] = upr(w, 2);
+-		im_tab[3][b] = upr(w, 3);
+-
+-		/* tables for a normal decryption round */
+-		it_tab[0][i] = w;
+-		it_tab[1][i] = upr(w,1);
+-		it_tab[2][i] = upr(w,2);
+-		it_tab[3][i] = upr(w,3);
+-
+-		w = bytes2word(b, 0, 0, 0);
+-		
+-		/* tables for last decryption round */
+-		il_tab[0][i] = w;
+-		il_tab[1][i] = upr(w,1);
+-		il_tab[2][i] = upr(w,2);
+-		il_tab[3][i] = upr(w,3);
+-    }
+-}
+-
+-#define four_tables(x,tab,vf,rf,c)		\
+-(	tab[0][bval(vf(x,0,c),rf(0,c))]	^	\
+-	tab[1][bval(vf(x,1,c),rf(1,c))] ^	\
+-	tab[2][bval(vf(x,2,c),rf(2,c))] ^	\
+-	tab[3][bval(vf(x,3,c),rf(3,c))]		\
+-)
+-
+-#define vf1(x,r,c)  (x)
+-#define rf1(r,c)    (r)
+-#define rf2(r,c)    ((r-c)&3)
+-
+-#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
+-#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
+-
+-#define ff(x) inv_mcol(x)
+-
+-#define ke4(k,i)							\
+-{									\
+-	k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i];		\
+-	k[4*(i)+5] = ss[1] ^= ss[0];					\
+-	k[4*(i)+6] = ss[2] ^= ss[1];					\
+-	k[4*(i)+7] = ss[3] ^= ss[2];					\
+-}
+-
+-#define kel4(k,i)							\
+-{									\
+-	k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i];		\
+-	k[4*(i)+5] = ss[1] ^= ss[0];					\
+-	k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2];	\
+-}
+-
+-#define ke6(k,i)							\
+-{									\
+-	k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i];		\
+-	k[6*(i)+ 7] = ss[1] ^= ss[0];					\
+-	k[6*(i)+ 8] = ss[2] ^= ss[1];					\
+-	k[6*(i)+ 9] = ss[3] ^= ss[2];					\
+-	k[6*(i)+10] = ss[4] ^= ss[3];					\
+-	k[6*(i)+11] = ss[5] ^= ss[4];					\
+-}
+-
+-#define kel6(k,i)							\
+-{									\
+-	k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i];		\
+-	k[6*(i)+ 7] = ss[1] ^= ss[0];					\
+-	k[6*(i)+ 8] = ss[2] ^= ss[1];					\
+-	k[6*(i)+ 9] = ss[3] ^= ss[2];					\
+-}
+-
+-#define ke8(k,i)							\
+-{									\
+-	k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i];		\
+-	k[8*(i)+ 9] = ss[1] ^= ss[0];					\
+-	k[8*(i)+10] = ss[2] ^= ss[1];					\
+-	k[8*(i)+11] = ss[3] ^= ss[2];					\
+-	k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0);				\
+-	k[8*(i)+13] = ss[5] ^= ss[4];					\
+-	k[8*(i)+14] = ss[6] ^= ss[5];					\
+-	k[8*(i)+15] = ss[7] ^= ss[6];					\
+-}
+-
+-#define kel8(k,i)							\
+-{									\
+-	k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i];		\
+-	k[8*(i)+ 9] = ss[1] ^= ss[0];					\
+-	k[8*(i)+10] = ss[2] ^= ss[1];					\
+-	k[8*(i)+11] = ss[3] ^= ss[2];					\
+-}
+-
+-#define kdf4(k,i)							\
+-{									\
+-	ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3];				\
+-	ss[1] = ss[1] ^ ss[3];						\
+-	ss[2] = ss[2] ^ ss[3];						\
+-	ss[3] = ss[3];							\
+-	ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i];			\
+-	ss[i % 4] ^= ss[4];						\
+-	ss[4] ^= k[4*(i)];						\
+-	k[4*(i)+4] = ff(ss[4]);						\
+-	ss[4] ^= k[4*(i)+1];						\
+-	k[4*(i)+5] = ff(ss[4]);						\
+-	ss[4] ^= k[4*(i)+2];						\
+-	k[4*(i)+6] = ff(ss[4]);						\
+-	ss[4] ^= k[4*(i)+3];						\
+-	k[4*(i)+7] = ff(ss[4]);						\
+-}
+-
+-#define kd4(k,i)							\
+-{									\
+-	ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i];			\
+-	ss[i % 4] ^= ss[4];						\
+-	ss[4] = ff(ss[4]);						\
+-	k[4*(i)+4] = ss[4] ^= k[4*(i)];					\
+-	k[4*(i)+5] = ss[4] ^= k[4*(i)+1];				\
+-	k[4*(i)+6] = ss[4] ^= k[4*(i)+2];				\
+-	k[4*(i)+7] = ss[4] ^= k[4*(i)+3];				\
+-}
+-
+-#define kdl4(k,i)							\
+-{									\
+-	ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i];			\
+-	ss[i % 4] ^= ss[4];						\
+-	k[4*(i)+4] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3];			\
+-	k[4*(i)+5] = ss[1] ^ ss[3];					\
+-	k[4*(i)+6] = ss[0];						\
+-	k[4*(i)+7] = ss[1];						\
+-}
+-
+-#define kdf6(k,i)							\
+-{									\
+-	ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i];				\
+-	k[6*(i)+ 6] = ff(ss[0]);					\
+-	ss[1] ^= ss[0];							\
+-	k[6*(i)+ 7] = ff(ss[1]);					\
+-	ss[2] ^= ss[1];							\
+-	k[6*(i)+ 8] = ff(ss[2]);					\
+-	ss[3] ^= ss[2];							\
+-	k[6*(i)+ 9] = ff(ss[3]);					\
+-	ss[4] ^= ss[3];							\
+-	k[6*(i)+10] = ff(ss[4]);					\
+-	ss[5] ^= ss[4];							\
+-	k[6*(i)+11] = ff(ss[5]);					\
+-}
+-
+-#define kd6(k,i)							\
+-{									\
+-	ss[6] = ls_box(ss[5],3) ^ rcon_tab[i];				\
+-	ss[0] ^= ss[6]; ss[6] = ff(ss[6]);				\
+-	k[6*(i)+ 6] = ss[6] ^= k[6*(i)];				\
+-	ss[1] ^= ss[0];							\
+-	k[6*(i)+ 7] = ss[6] ^= k[6*(i)+ 1];				\
+-	ss[2] ^= ss[1];							\
+-	k[6*(i)+ 8] = ss[6] ^= k[6*(i)+ 2];				\
+-	ss[3] ^= ss[2];							\
+-	k[6*(i)+ 9] = ss[6] ^= k[6*(i)+ 3];				\
+-	ss[4] ^= ss[3];							\
+-	k[6*(i)+10] = ss[6] ^= k[6*(i)+ 4];				\
+-	ss[5] ^= ss[4];							\
+-	k[6*(i)+11] = ss[6] ^= k[6*(i)+ 5];				\
+-}
+-
+-#define kdl6(k,i)							\
+-{									\
+-	ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i];				\
+-	k[6*(i)+ 6] = ss[0];						\
+-	ss[1] ^= ss[0];							\
+-	k[6*(i)+ 7] = ss[1];						\
+-	ss[2] ^= ss[1];							\
+-	k[6*(i)+ 8] = ss[2];						\
+-	ss[3] ^= ss[2];							\
+-	k[6*(i)+ 9] = ss[3];						\
+-}
+-
+-#define kdf8(k,i)							\
+-{									\
+-	ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i];				\
+-	k[8*(i)+ 8] = ff(ss[0]);					\
+-	ss[1] ^= ss[0];							\
+-	k[8*(i)+ 9] = ff(ss[1]);					\
+-	ss[2] ^= ss[1];							\
+-	k[8*(i)+10] = ff(ss[2]);					\
+-	ss[3] ^= ss[2];							\
+-	k[8*(i)+11] = ff(ss[3]);					\
+-	ss[4] ^= ls_box(ss[3],0);					\
+-	k[8*(i)+12] = ff(ss[4]);					\
+-	ss[5] ^= ss[4];							\
+-	k[8*(i)+13] = ff(ss[5]);					\
+-	ss[6] ^= ss[5];							\
+-	k[8*(i)+14] = ff(ss[6]);					\
+-	ss[7] ^= ss[6];							\
+-	k[8*(i)+15] = ff(ss[7]);					\
+-}
+-
+-#define kd8(k,i)							\
+-{									\
+-	u32 __g = ls_box(ss[7],3) ^ rcon_tab[i];			\
+-	ss[0] ^= __g;							\
+-	__g = ff(__g);							\
+-	k[8*(i)+ 8] = __g ^= k[8*(i)];					\
+-	ss[1] ^= ss[0];							\
+-	k[8*(i)+ 9] = __g ^= k[8*(i)+ 1];				\
+-	ss[2] ^= ss[1];							\
+-	k[8*(i)+10] = __g ^= k[8*(i)+ 2];				\
+-	ss[3] ^= ss[2];							\
+-	k[8*(i)+11] = __g ^= k[8*(i)+ 3];				\
+-	__g = ls_box(ss[3],0);						\
+-	ss[4] ^= __g;							\
+-	__g = ff(__g);							\
+-	k[8*(i)+12] = __g ^= k[8*(i)+ 4];				\
+-	ss[5] ^= ss[4];							\
+-	k[8*(i)+13] = __g ^= k[8*(i)+ 5];				\
+-	ss[6] ^= ss[5];							\
+-	k[8*(i)+14] = __g ^= k[8*(i)+ 6];				\
+-	ss[7] ^= ss[6];							\
+-	k[8*(i)+15] = __g ^= k[8*(i)+ 7];				\
+-}
+-
+-#define kdl8(k,i)							\
+-{									\
+-	ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i];				\
+-	k[8*(i)+ 8] = ss[0];						\
+-	ss[1] ^= ss[0];							\
+-	k[8*(i)+ 9] = ss[1];						\
+-	ss[2] ^= ss[1];							\
+-	k[8*(i)+10] = ss[2];						\
+-	ss[3] ^= ss[2];							\
+-	k[8*(i)+11] = ss[3];						\
+-}
+-
+-static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+-		       unsigned int key_len)
+-{
+-	int i;
+-	u32 ss[8];
+-	struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
+-	const __le32 *key = (const __le32 *)in_key;
+-	u32 *flags = &tfm->crt_flags;
+-
+-	/* encryption schedule */
+-	
+-	ctx->ekey[0] = ss[0] = le32_to_cpu(key[0]);
+-	ctx->ekey[1] = ss[1] = le32_to_cpu(key[1]);
+-	ctx->ekey[2] = ss[2] = le32_to_cpu(key[2]);
+-	ctx->ekey[3] = ss[3] = le32_to_cpu(key[3]);
+-
+-	switch(key_len) {
+-	case 16:
+-		for (i = 0; i < 9; i++)
+-			ke4(ctx->ekey, i);
+-		kel4(ctx->ekey, 9);
+-		ctx->rounds = 10;
+-		break;
+-		
+-	case 24:
+-		ctx->ekey[4] = ss[4] = le32_to_cpu(key[4]);
+-		ctx->ekey[5] = ss[5] = le32_to_cpu(key[5]);
+-		for (i = 0; i < 7; i++)
+-			ke6(ctx->ekey, i);
+-		kel6(ctx->ekey, 7); 
+-		ctx->rounds = 12;
+-		break;
+-
+-	case 32:
+-		ctx->ekey[4] = ss[4] = le32_to_cpu(key[4]);
+-		ctx->ekey[5] = ss[5] = le32_to_cpu(key[5]);
+-		ctx->ekey[6] = ss[6] = le32_to_cpu(key[6]);
+-		ctx->ekey[7] = ss[7] = le32_to_cpu(key[7]);
+-		for (i = 0; i < 6; i++)
+-			ke8(ctx->ekey, i);
+-		kel8(ctx->ekey, 6);
+-		ctx->rounds = 14;
+-		break;
+-
+-	default:
+-		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+-		return -EINVAL;
+-	}
+-	
+-	/* decryption schedule */
+-	
+-	ctx->dkey[0] = ss[0] = le32_to_cpu(key[0]);
+-	ctx->dkey[1] = ss[1] = le32_to_cpu(key[1]);
+-	ctx->dkey[2] = ss[2] = le32_to_cpu(key[2]);
+-	ctx->dkey[3] = ss[3] = le32_to_cpu(key[3]);
+-
+-	switch (key_len) {
+-	case 16:
+-		kdf4(ctx->dkey, 0);
+-		for (i = 1; i < 9; i++)
+-			kd4(ctx->dkey, i);
+-		kdl4(ctx->dkey, 9);
+-		break;
+-		
+-	case 24:
+-		ctx->dkey[4] = ff(ss[4] = le32_to_cpu(key[4]));
+-		ctx->dkey[5] = ff(ss[5] = le32_to_cpu(key[5]));
+-		kdf6(ctx->dkey, 0);
+-		for (i = 1; i < 7; i++)
+-			kd6(ctx->dkey, i);
+-		kdl6(ctx->dkey, 7);
+-		break;
+-
+-	case 32:
+-		ctx->dkey[4] = ff(ss[4] = le32_to_cpu(key[4]));
+-		ctx->dkey[5] = ff(ss[5] = le32_to_cpu(key[5]));
+-		ctx->dkey[6] = ff(ss[6] = le32_to_cpu(key[6]));
+-		ctx->dkey[7] = ff(ss[7] = le32_to_cpu(key[7]));
+-		kdf8(ctx->dkey, 0);
+-		for (i = 1; i < 6; i++)
+-			kd8(ctx->dkey, i);
+-		kdl8(ctx->dkey, 6);
+-		break;
+-	}
+-	return 0;
+-}
+-
+-static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+-{
+-	aes_enc_blk(tfm, dst, src);
+-}
+-
+-static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+-{
+-	aes_dec_blk(tfm, dst, src);
+-}
+-
+-static struct crypto_alg aes_alg = {
+-	.cra_name		=	"aes",
+-	.cra_driver_name	=	"aes-i586",
+-	.cra_priority		=	200,
+-	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
+-	.cra_blocksize		=	AES_BLOCK_SIZE,
+-	.cra_ctxsize		=	sizeof(struct aes_ctx),
+-	.cra_module		=	THIS_MODULE,
+-	.cra_list		=	LIST_HEAD_INIT(aes_alg.cra_list),
+-	.cra_u			=	{
+-		.cipher = {
+-			.cia_min_keysize	=	AES_MIN_KEY_SIZE,
+-			.cia_max_keysize	=	AES_MAX_KEY_SIZE,
+-			.cia_setkey	   	= 	aes_set_key,
+-			.cia_encrypt	 	=	aes_encrypt,
+-			.cia_decrypt	  	=	aes_decrypt
+-		}
+-	}
+-};
+-
+-static int __init aes_init(void)
+-{
+-	gen_tabs();
+-	return crypto_register_alg(&aes_alg);
+-}
+-
+-static void __exit aes_fini(void)
+-{
+-	crypto_unregister_alg(&aes_alg);
+-}
+-
+-module_init(aes_init);
+-module_exit(aes_fini);
+-
+-MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm, i586 asm optimized");
+-MODULE_LICENSE("Dual BSD/GPL");
+-MODULE_AUTHOR("Fruhwirth Clemens, James Morris, Brian Gladman, Adam Richter");
+-MODULE_ALIAS("aes");
+diff --git a/arch/x86/crypto/aes_64.c b/arch/x86/crypto/aes_64.c
+deleted file mode 100644
+index 5cdb13e..0000000
+--- a/arch/x86/crypto/aes_64.c
++++ /dev/null
+@@ -1,336 +0,0 @@
+-/*
+- * Cryptographic API.
+- *
+- * AES Cipher Algorithm.
+- *
+- * Based on Brian Gladman's code.
+- *
+- * Linux developers:
+- *  Alexander Kjeldaas <astor at fast.no>
+- *  Herbert Valerio Riedel <hvr at hvrlab.org>
+- *  Kyle McMartin <kyle at debian.org>
+- *  Adam J. Richter <adam at yggdrasil.com> (conversion to 2.5 API).
+- *  Andreas Steinmetz <ast at domdv.de> (adapted to x86_64 assembler)
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * ---------------------------------------------------------------------------
+- * Copyright (c) 2002, Dr Brian Gladman <brg at gladman.me.uk>, Worcester, UK.
+- * All rights reserved.
+- *
+- * LICENSE TERMS
+- *
+- * The free distribution and use of this software in both source and binary
+- * form is allowed (with or without changes) provided that:
+- *
+- *   1. distributions of this source code include the above copyright
+- *      notice, this list of conditions and the following disclaimer;
+- *
+- *   2. distributions in binary form include the above copyright
+- *      notice, this list of conditions and the following disclaimer
+- *      in the documentation and/or other associated materials;
+- *
+- *   3. the copyright holder's name is not used to endorse products
+- *      built using this software without specific written permission.
+- *
+- * ALTERNATIVELY, provided that this notice is retained in full, this product
+- * may be distributed under the terms of the GNU General Public License (GPL),
+- * in which case the provisions of the GPL apply INSTEAD OF those given above.
+- *
+- * DISCLAIMER
+- *
+- * This software is provided 'as is' with no explicit or implied warranties
+- * in respect of its properties, including, but not limited to, correctness
+- * and/or fitness for purpose.
+- * ---------------------------------------------------------------------------
+- */
+-
+-/* Some changes from the Gladman version:
+-    s/RIJNDAEL(e_key)/E_KEY/g
+-    s/RIJNDAEL(d_key)/D_KEY/g
+-*/
+-
+-#include <asm/byteorder.h>
+-#include <linux/bitops.h>
+-#include <linux/crypto.h>
+-#include <linux/errno.h>
+-#include <linux/init.h>
+-#include <linux/module.h>
+-#include <linux/types.h>
+-
+-#define AES_MIN_KEY_SIZE	16
+-#define AES_MAX_KEY_SIZE	32
+-
+-#define AES_BLOCK_SIZE		16
+-
+-/*
+- * #define byte(x, nr) ((unsigned char)((x) >> (nr*8)))
+- */
+-static inline u8 byte(const u32 x, const unsigned n)
+-{
+-	return x >> (n << 3);
+-}
+-
+-struct aes_ctx
+-{
+-	u32 key_length;
+-	u32 buf[120];
+-};
+-
+-#define E_KEY (&ctx->buf[0])
+-#define D_KEY (&ctx->buf[60])
+-
+-static u8 pow_tab[256] __initdata;
+-static u8 log_tab[256] __initdata;
+-static u8 sbx_tab[256] __initdata;
+-static u8 isb_tab[256] __initdata;
+-static u32 rco_tab[10];
+-u32 aes_ft_tab[4][256];
+-u32 aes_it_tab[4][256];
+-
+-u32 aes_fl_tab[4][256];
+-u32 aes_il_tab[4][256];
+-
+-static inline u8 f_mult(u8 a, u8 b)
+-{
+-	u8 aa = log_tab[a], cc = aa + log_tab[b];
+-
+-	return pow_tab[cc + (cc < aa ? 1 : 0)];
+-}
+-
+-#define ff_mult(a, b) (a && b ? f_mult(a, b) : 0)
+-
+-#define ls_box(x)				\
+-	(aes_fl_tab[0][byte(x, 0)] ^		\
+-	 aes_fl_tab[1][byte(x, 1)] ^		\
+-	 aes_fl_tab[2][byte(x, 2)] ^		\
+-	 aes_fl_tab[3][byte(x, 3)])
+-
+-static void __init gen_tabs(void)
+-{
+-	u32 i, t;
+-	u8 p, q;
+-
+-	/* log and power tables for GF(2**8) finite field with
+-	   0x011b as modular polynomial - the simplest primitive
+-	   root is 0x03, used here to generate the tables */
+-
+-	for (i = 0, p = 1; i < 256; ++i) {
+-		pow_tab[i] = (u8)p;
+-		log_tab[p] = (u8)i;
+-
+-		p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0);
+-	}
+-
+-	log_tab[1] = 0;
+-
+-	for (i = 0, p = 1; i < 10; ++i) {
+-		rco_tab[i] = p;
+-
+-		p = (p << 1) ^ (p & 0x80 ? 0x01b : 0);
+-	}
+-
+-	for (i = 0; i < 256; ++i) {
+-		p = (i ? pow_tab[255 - log_tab[i]] : 0);
+-		q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2));
+-		p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2));
+-		sbx_tab[i] = p;
+-		isb_tab[p] = (u8)i;
+-	}
+-
+-	for (i = 0; i < 256; ++i) {
+-		p = sbx_tab[i];
+-
+-		t = p;
+-		aes_fl_tab[0][i] = t;
+-		aes_fl_tab[1][i] = rol32(t, 8);
+-		aes_fl_tab[2][i] = rol32(t, 16);
+-		aes_fl_tab[3][i] = rol32(t, 24);
+-
+-		t = ((u32)ff_mult(2, p)) |
+-		    ((u32)p << 8) |
+-		    ((u32)p << 16) | ((u32)ff_mult(3, p) << 24);
+-
+-		aes_ft_tab[0][i] = t;
+-		aes_ft_tab[1][i] = rol32(t, 8);
+-		aes_ft_tab[2][i] = rol32(t, 16);
+-		aes_ft_tab[3][i] = rol32(t, 24);
+-
+-		p = isb_tab[i];
+-
+-		t = p;
+-		aes_il_tab[0][i] = t;
+-		aes_il_tab[1][i] = rol32(t, 8);
+-		aes_il_tab[2][i] = rol32(t, 16);
+-		aes_il_tab[3][i] = rol32(t, 24);
+-
+-		t = ((u32)ff_mult(14, p)) |
+-		    ((u32)ff_mult(9, p) << 8) |
+-		    ((u32)ff_mult(13, p) << 16) |
+-		    ((u32)ff_mult(11, p) << 24);
+-
+-		aes_it_tab[0][i] = t;
+-		aes_it_tab[1][i] = rol32(t, 8);
+-		aes_it_tab[2][i] = rol32(t, 16);
+-		aes_it_tab[3][i] = rol32(t, 24);
+-	}
+-}
+-
+-#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
+-
+-#define imix_col(y, x)			\
+-	u    = star_x(x);		\
+-	v    = star_x(u);		\
+-	w    = star_x(v);		\
+-	t    = w ^ (x);			\
+-	(y)  = u ^ v ^ w;		\
+-	(y) ^= ror32(u ^ t,  8) ^	\
+-	       ror32(v ^ t, 16) ^	\
+-	       ror32(t, 24)
+-
+-/* initialise the key schedule from the user supplied key */
+-
+-#define loop4(i)					\
+-{							\
+-	t = ror32(t,  8); t = ls_box(t) ^ rco_tab[i];	\
+-	t ^= E_KEY[4 * i];     E_KEY[4 * i + 4] = t;	\
+-	t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t;	\
+-	t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t;	\
+-	t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t;	\
+-}
+-
+-#define loop6(i)					\
+-{							\
+-	t = ror32(t,  8); t = ls_box(t) ^ rco_tab[i];	\
+-	t ^= E_KEY[6 * i];     E_KEY[6 * i + 6] = t;	\
+-	t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t;	\
+-	t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t;	\
+-	t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t;	\
+-	t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t;	\
+-	t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t;	\
+-}
+-
+-#define loop8(i)					\
+-{							\
+-	t = ror32(t,  8); ; t = ls_box(t) ^ rco_tab[i];	\
+-	t ^= E_KEY[8 * i];     E_KEY[8 * i + 8] = t;	\
+-	t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t;	\
+-	t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t;	\
+-	t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t;	\
+-	t  = E_KEY[8 * i + 4] ^ ls_box(t);		\
+-	E_KEY[8 * i + 12] = t;				\
+-	t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t;	\
+-	t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t;	\
+-	t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t;	\
+-}
+-
+-static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+-		       unsigned int key_len)
+-{
+-	struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
+-	const __le32 *key = (const __le32 *)in_key;
+-	u32 *flags = &tfm->crt_flags;
+-	u32 i, j, t, u, v, w;
+-
+-	if (key_len % 8) {
+-		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+-		return -EINVAL;
+-	}
+-
+-	ctx->key_length = key_len;
+-
+-	D_KEY[key_len + 24] = E_KEY[0] = le32_to_cpu(key[0]);
+-	D_KEY[key_len + 25] = E_KEY[1] = le32_to_cpu(key[1]);
+-	D_KEY[key_len + 26] = E_KEY[2] = le32_to_cpu(key[2]);
+-	D_KEY[key_len + 27] = E_KEY[3] = le32_to_cpu(key[3]);
+-
+-	switch (key_len) {
+-	case 16:
+-		t = E_KEY[3];
+-		for (i = 0; i < 10; ++i)
+-			loop4(i);
+-		break;
+-
+-	case 24:
+-		E_KEY[4] = le32_to_cpu(key[4]);
+-		t = E_KEY[5] = le32_to_cpu(key[5]);
+-		for (i = 0; i < 8; ++i)
+-			loop6 (i);
+-		break;
+-
+-	case 32:
+-		E_KEY[4] = le32_to_cpu(key[4]);
+-		E_KEY[5] = le32_to_cpu(key[5]);
+-		E_KEY[6] = le32_to_cpu(key[6]);
+-		t = E_KEY[7] = le32_to_cpu(key[7]);
+-		for (i = 0; i < 7; ++i)
+-			loop8(i);
+-		break;
+-	}
+-
+-	D_KEY[0] = E_KEY[key_len + 24];
+-	D_KEY[1] = E_KEY[key_len + 25];
+-	D_KEY[2] = E_KEY[key_len + 26];
+-	D_KEY[3] = E_KEY[key_len + 27];
+-
+-	for (i = 4; i < key_len + 24; ++i) {
+-		j = key_len + 24 - (i & ~3) + (i & 3);
+-		imix_col(D_KEY[j], E_KEY[i]);
+-	}
+-
+-	return 0;
+-}
+-
+-asmlinkage void aes_enc_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in);
+-asmlinkage void aes_dec_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in);
+-
+-static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+-{
+-	aes_enc_blk(tfm, dst, src);
+-}
+-
+-static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+-{
+-	aes_dec_blk(tfm, dst, src);
+-}
+-
+-static struct crypto_alg aes_alg = {
+-	.cra_name		=	"aes",
+-	.cra_driver_name	=	"aes-x86_64",
+-	.cra_priority		=	200,
+-	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
+-	.cra_blocksize		=	AES_BLOCK_SIZE,
+-	.cra_ctxsize		=	sizeof(struct aes_ctx),
+-	.cra_module		=	THIS_MODULE,
+-	.cra_list		=	LIST_HEAD_INIT(aes_alg.cra_list),
+-	.cra_u			=	{
+-		.cipher = {
+-			.cia_min_keysize	=	AES_MIN_KEY_SIZE,
+-			.cia_max_keysize	=	AES_MAX_KEY_SIZE,
+-			.cia_setkey	   	= 	aes_set_key,
+-			.cia_encrypt	 	=	aes_encrypt,
+-			.cia_decrypt	  	=	aes_decrypt
+-		}
+-	}
+-};
+-
+-static int __init aes_init(void)
+-{
+-	gen_tabs();
+-	return crypto_register_alg(&aes_alg);
+-}
+-
+-static void __exit aes_fini(void)
+-{
+-	crypto_unregister_alg(&aes_alg);
+-}
+-
+-module_init(aes_init);
+-module_exit(aes_fini);
+-
+-MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
+-MODULE_LICENSE("GPL");
+-MODULE_ALIAS("aes");
+diff --git a/arch/x86/crypto/aes_glue.c b/arch/x86/crypto/aes_glue.c
+new file mode 100644
+index 0000000..71f4578
+--- /dev/null
++++ b/arch/x86/crypto/aes_glue.c
+@@ -0,0 +1,57 @@
++/*
++ * Glue Code for the asm optimized version of the AES Cipher Algorithm
++ *
++ */
++
++#include <crypto/aes.h>
++
++asmlinkage void aes_enc_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in);
++asmlinkage void aes_dec_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in);
++
++static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
++{
++	aes_enc_blk(tfm, dst, src);
++}
++
++static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
++{
++	aes_dec_blk(tfm, dst, src);
++}
++
++static struct crypto_alg aes_alg = {
++	.cra_name		= "aes",
++	.cra_driver_name	= "aes-asm",
++	.cra_priority		= 200,
++	.cra_flags		= CRYPTO_ALG_TYPE_CIPHER,
++	.cra_blocksize		= AES_BLOCK_SIZE,
++	.cra_ctxsize		= sizeof(struct crypto_aes_ctx),
++	.cra_module		= THIS_MODULE,
++	.cra_list		= LIST_HEAD_INIT(aes_alg.cra_list),
++	.cra_u	= {
++		.cipher	= {
++			.cia_min_keysize	= AES_MIN_KEY_SIZE,
++			.cia_max_keysize	= AES_MAX_KEY_SIZE,
++			.cia_setkey		= crypto_aes_set_key,
++			.cia_encrypt		= aes_encrypt,
++			.cia_decrypt		= aes_decrypt
++		}
++	}
++};
++
++static int __init aes_init(void)
++{
++	return crypto_register_alg(&aes_alg);
++}
++
++static void __exit aes_fini(void)
++{
++	crypto_unregister_alg(&aes_alg);
++}
++
++module_init(aes_init);
++module_exit(aes_fini);
++
++MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm, asm optimized");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("aes");
++MODULE_ALIAS("aes-asm");
+diff --git a/arch/x86/crypto/salsa20-i586-asm_32.S b/arch/x86/crypto/salsa20-i586-asm_32.S
+new file mode 100644
+index 0000000..72eb306
+--- /dev/null
++++ b/arch/x86/crypto/salsa20-i586-asm_32.S
+@@ -0,0 +1,1114 @@
++# salsa20_pm.s version 20051229
++# D. J. Bernstein
++# Public domain.
++
++# enter ECRYPT_encrypt_bytes
++.text
++.p2align 5
++.globl ECRYPT_encrypt_bytes
++ECRYPT_encrypt_bytes:
++	mov	%esp,%eax
++	and	$31,%eax
++	add	$256,%eax
++	sub	%eax,%esp
++	# eax_stack = eax
++	movl	%eax,80(%esp)
++	# ebx_stack = ebx
++	movl	%ebx,84(%esp)
++	# esi_stack = esi
++	movl	%esi,88(%esp)
++	# edi_stack = edi
++	movl	%edi,92(%esp)
++	# ebp_stack = ebp
++	movl	%ebp,96(%esp)
++	# x = arg1
++	movl	4(%esp,%eax),%edx
++	# m = arg2
++	movl	8(%esp,%eax),%esi
 +	# out = arg3
 +	movl	12(%esp,%eax),%edi
 +	# bytes = arg4
@@ -54415,1780 +63492,6881 @@
 +	tasklet_schedule(&dev->tasklet);
 +	hifn_clear_rings(dev);
 +
-+	return IRQ_HANDLED;
-+}
++	return IRQ_HANDLED;
++}
++
++static void hifn_flush(struct hifn_device *dev)
++{
++	unsigned long flags;
++	struct crypto_async_request *async_req;
++	struct hifn_context *ctx;
++	struct ablkcipher_request *req;
++	struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt;
++	int i;
++
++	spin_lock_irqsave(&dev->lock, flags);
++	for (i=0; i<HIFN_D_RES_RSIZE; ++i) {
++		struct hifn_desc *d = &dma->resr[i];
++
++		if (dev->sa[i]) {
++			hifn_process_ready(dev->sa[i],
++				(d->l & __cpu_to_le32(HIFN_D_VALID))?-ENODEV:0);
++		}
++	}
++
++	while ((async_req = crypto_dequeue_request(&dev->queue))) {
++		ctx = crypto_tfm_ctx(async_req->tfm);
++		req = container_of(async_req, struct ablkcipher_request, base);
++
++		hifn_process_ready(req, -ENODEV);
++	}
++	spin_unlock_irqrestore(&dev->lock, flags);
++}
++
++static int hifn_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
++		unsigned int len)
++{
++	struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
++	struct hifn_context *ctx = crypto_tfm_ctx(tfm);
++	struct hifn_device *dev = ctx->dev;
++
++	if (len > HIFN_MAX_CRYPT_KEY_LENGTH) {
++		crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
++		return -1;
++	}
++
++	if (len == HIFN_DES_KEY_LENGTH) {
++		u32 tmp[DES_EXPKEY_WORDS];
++		int ret = des_ekey(tmp, key);
++		
++		if (unlikely(ret == 0) && (tfm->crt_flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
++			tfm->crt_flags |= CRYPTO_TFM_RES_WEAK_KEY;
++			return -EINVAL;
++		}
++	}
++
++	dev->flags &= ~HIFN_FLAG_OLD_KEY;
++
++	memcpy(ctx->key, key, len);
++	ctx->keysize = len;
++
++	return 0;
++}
++
++static int hifn_handle_req(struct ablkcipher_request *req)
++{
++	struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm);
++	struct hifn_device *dev = ctx->dev;
++	int err = -EAGAIN;
++
++	if (dev->started + DIV_ROUND_UP(req->nbytes, PAGE_SIZE) <= HIFN_QUEUE_LENGTH)
++		err = hifn_setup_session(req);
++
++	if (err == -EAGAIN) {
++		unsigned long flags;
++
++		spin_lock_irqsave(&dev->lock, flags);
++		err = ablkcipher_enqueue_request(&dev->queue, req);
++		spin_unlock_irqrestore(&dev->lock, flags);
++	}
++
++	return err;
++}
++
++static int hifn_setup_crypto_req(struct ablkcipher_request *req, u8 op,
++		u8 type, u8 mode)
++{
++	struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm);
++	unsigned ivsize;
++
++	ivsize = crypto_ablkcipher_ivsize(crypto_ablkcipher_reqtfm(req));
++
++	if (req->info && mode != ACRYPTO_MODE_ECB) {
++		if (type == ACRYPTO_TYPE_AES_128)
++			ivsize = HIFN_AES_IV_LENGTH;
++		else if (type == ACRYPTO_TYPE_DES)
++			ivsize = HIFN_DES_KEY_LENGTH;
++		else if (type == ACRYPTO_TYPE_3DES)
++			ivsize = HIFN_3DES_KEY_LENGTH;
++	}
++
++	if (ctx->keysize != 16 && type == ACRYPTO_TYPE_AES_128) {
++		if (ctx->keysize == 24)
++			type = ACRYPTO_TYPE_AES_192;
++		else if (ctx->keysize == 32)
++			type = ACRYPTO_TYPE_AES_256;
++	}
++
++	ctx->op = op;
++	ctx->mode = mode;
++	ctx->type = type;
++	ctx->iv = req->info;
++	ctx->ivsize = ivsize;
++
++	/*
++	 * HEAVY TODO: needs to kick Herbert XU to write documentation.
++	 * HEAVY TODO: needs to kick Herbert XU to write documentation.
++	 * HEAVY TODO: needs to kick Herbert XU to write documentation.
++	 */
++
++	return hifn_handle_req(req);
++}
++
++static int hifn_process_queue(struct hifn_device *dev)
++{
++	struct crypto_async_request *async_req;
++	struct hifn_context *ctx;
++	struct ablkcipher_request *req;
++	unsigned long flags;
++	int err = 0;
++
++	while (dev->started < HIFN_QUEUE_LENGTH) {
++		spin_lock_irqsave(&dev->lock, flags);
++		async_req = crypto_dequeue_request(&dev->queue);
++		spin_unlock_irqrestore(&dev->lock, flags);
++
++		if (!async_req)
++			break;
++
++		ctx = crypto_tfm_ctx(async_req->tfm);
++		req = container_of(async_req, struct ablkcipher_request, base);
++
++		err = hifn_handle_req(req);
++		if (err)
++			break;
++	}
++
++	return err;
++}
++
++static int hifn_setup_crypto(struct ablkcipher_request *req, u8 op,
++		u8 type, u8 mode)
++{
++	int err;
++	struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm);
++	struct hifn_device *dev = ctx->dev;
++
++	err = hifn_setup_crypto_req(req, op, type, mode);
++	if (err)
++		return err;
++
++	if (dev->started < HIFN_QUEUE_LENGTH &&	dev->queue.qlen)
++		err = hifn_process_queue(dev);
++
++	return err;
++}
++
++/*
++ * AES ecryption functions.
++ */
++static inline int hifn_encrypt_aes_ecb(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
++			ACRYPTO_TYPE_AES_128, ACRYPTO_MODE_ECB);
++}
++static inline int hifn_encrypt_aes_cbc(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
++			ACRYPTO_TYPE_AES_128, ACRYPTO_MODE_CBC);
++}
++static inline int hifn_encrypt_aes_cfb(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
++			ACRYPTO_TYPE_AES_128, ACRYPTO_MODE_CFB);
++}
++static inline int hifn_encrypt_aes_ofb(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
++			ACRYPTO_TYPE_AES_128, ACRYPTO_MODE_OFB);
++}
++
++/*
++ * AES decryption functions.
++ */
++static inline int hifn_decrypt_aes_ecb(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
++			ACRYPTO_TYPE_AES_128, ACRYPTO_MODE_ECB);
++}
++static inline int hifn_decrypt_aes_cbc(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
++			ACRYPTO_TYPE_AES_128, ACRYPTO_MODE_CBC);
++}
++static inline int hifn_decrypt_aes_cfb(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
++			ACRYPTO_TYPE_AES_128, ACRYPTO_MODE_CFB);
++}
++static inline int hifn_decrypt_aes_ofb(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
++			ACRYPTO_TYPE_AES_128, ACRYPTO_MODE_OFB);
++}
++
++/*
++ * DES ecryption functions.
++ */
++static inline int hifn_encrypt_des_ecb(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
++			ACRYPTO_TYPE_DES, ACRYPTO_MODE_ECB);
++}
++static inline int hifn_encrypt_des_cbc(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
++			ACRYPTO_TYPE_DES, ACRYPTO_MODE_CBC);
++}
++static inline int hifn_encrypt_des_cfb(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
++			ACRYPTO_TYPE_DES, ACRYPTO_MODE_CFB);
++}
++static inline int hifn_encrypt_des_ofb(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
++			ACRYPTO_TYPE_DES, ACRYPTO_MODE_OFB);
++}
++
++/*
++ * DES decryption functions.
++ */
++static inline int hifn_decrypt_des_ecb(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
++			ACRYPTO_TYPE_DES, ACRYPTO_MODE_ECB);
++}
++static inline int hifn_decrypt_des_cbc(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
++			ACRYPTO_TYPE_DES, ACRYPTO_MODE_CBC);
++}
++static inline int hifn_decrypt_des_cfb(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
++			ACRYPTO_TYPE_DES, ACRYPTO_MODE_CFB);
++}
++static inline int hifn_decrypt_des_ofb(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
++			ACRYPTO_TYPE_DES, ACRYPTO_MODE_OFB);
++}
++
++/*
++ * 3DES ecryption functions.
++ */
++static inline int hifn_encrypt_3des_ecb(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
++			ACRYPTO_TYPE_3DES, ACRYPTO_MODE_ECB);
++}
++static inline int hifn_encrypt_3des_cbc(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
++			ACRYPTO_TYPE_3DES, ACRYPTO_MODE_CBC);
++}
++static inline int hifn_encrypt_3des_cfb(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
++			ACRYPTO_TYPE_3DES, ACRYPTO_MODE_CFB);
++}
++static inline int hifn_encrypt_3des_ofb(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
++			ACRYPTO_TYPE_3DES, ACRYPTO_MODE_OFB);
++}
++
++/*
++ * 3DES decryption functions.
++ */
++static inline int hifn_decrypt_3des_ecb(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
++			ACRYPTO_TYPE_3DES, ACRYPTO_MODE_ECB);
++}
++static inline int hifn_decrypt_3des_cbc(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
++			ACRYPTO_TYPE_3DES, ACRYPTO_MODE_CBC);
++}
++static inline int hifn_decrypt_3des_cfb(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
++			ACRYPTO_TYPE_3DES, ACRYPTO_MODE_CFB);
++}
++static inline int hifn_decrypt_3des_ofb(struct ablkcipher_request *req)
++{
++	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
++			ACRYPTO_TYPE_3DES, ACRYPTO_MODE_OFB);
++}
++
++struct hifn_alg_template
++{
++	char name[CRYPTO_MAX_ALG_NAME];
++	char drv_name[CRYPTO_MAX_ALG_NAME];
++	unsigned int bsize;
++	struct ablkcipher_alg ablkcipher;
++};
++
++static struct hifn_alg_template hifn_alg_templates[] = {
++	/*
++	 * 3DES ECB, CBC, CFB and OFB modes.
++	 */
++	{
++		.name = "cfb(des3_ede)", .drv_name = "hifn-3des", .bsize = 8,
++		.ablkcipher = {
++			.min_keysize	=	HIFN_3DES_KEY_LENGTH,
++			.max_keysize	=	HIFN_3DES_KEY_LENGTH,
++			.setkey		=	hifn_setkey,
++			.encrypt	=	hifn_encrypt_3des_cfb,
++			.decrypt	=	hifn_decrypt_3des_cfb,
++		},
++	},
++	{
++		.name = "ofb(des3_ede)", .drv_name = "hifn-3des", .bsize = 8,
++		.ablkcipher = {
++			.min_keysize	=	HIFN_3DES_KEY_LENGTH,
++			.max_keysize	=	HIFN_3DES_KEY_LENGTH,
++			.setkey		=	hifn_setkey,
++			.encrypt	=	hifn_encrypt_3des_ofb,
++			.decrypt	=	hifn_decrypt_3des_ofb,
++		},
++	},
++	{
++		.name = "cbc(des3_ede)", .drv_name = "hifn-3des", .bsize = 8,
++		.ablkcipher = {
++			.min_keysize	=	HIFN_3DES_KEY_LENGTH,
++			.max_keysize	=	HIFN_3DES_KEY_LENGTH,
++			.setkey		=	hifn_setkey,
++			.encrypt	=	hifn_encrypt_3des_cbc,
++			.decrypt	=	hifn_decrypt_3des_cbc,
++		},
++	},
++	{
++		.name = "ecb(des3_ede)", .drv_name = "hifn-3des", .bsize = 8,
++		.ablkcipher = {
++			.min_keysize	=	HIFN_3DES_KEY_LENGTH,
++			.max_keysize	=	HIFN_3DES_KEY_LENGTH,
++			.setkey		=	hifn_setkey,
++			.encrypt	=	hifn_encrypt_3des_ecb,
++			.decrypt	=	hifn_decrypt_3des_ecb,
++		},
++	},
++
++	/*
++	 * DES ECB, CBC, CFB and OFB modes.
++	 */
++	{
++		.name = "cfb(des)", .drv_name = "hifn-des", .bsize = 8,
++		.ablkcipher = {
++			.min_keysize	=	HIFN_DES_KEY_LENGTH,
++			.max_keysize	=	HIFN_DES_KEY_LENGTH,
++			.setkey		=	hifn_setkey,
++			.encrypt	=	hifn_encrypt_des_cfb,
++			.decrypt	=	hifn_decrypt_des_cfb,
++		},
++	},
++	{
++		.name = "ofb(des)", .drv_name = "hifn-des", .bsize = 8,
++		.ablkcipher = {
++			.min_keysize	=	HIFN_DES_KEY_LENGTH,
++			.max_keysize	=	HIFN_DES_KEY_LENGTH,
++			.setkey		=	hifn_setkey,
++			.encrypt	=	hifn_encrypt_des_ofb,
++			.decrypt	=	hifn_decrypt_des_ofb,
++		},
++	},
++	{
++		.name = "cbc(des)", .drv_name = "hifn-des", .bsize = 8,
++		.ablkcipher = {
++			.min_keysize	=	HIFN_DES_KEY_LENGTH,
++			.max_keysize	=	HIFN_DES_KEY_LENGTH,
++			.setkey		=	hifn_setkey,
++			.encrypt	=	hifn_encrypt_des_cbc,
++			.decrypt	=	hifn_decrypt_des_cbc,
++		},
++	},
++	{
++		.name = "ecb(des)", .drv_name = "hifn-des", .bsize = 8,
++		.ablkcipher = {
++			.min_keysize	=	HIFN_DES_KEY_LENGTH,
++			.max_keysize	=	HIFN_DES_KEY_LENGTH,
++			.setkey		=	hifn_setkey,
++			.encrypt	=	hifn_encrypt_des_ecb,
++			.decrypt	=	hifn_decrypt_des_ecb,
++		},
++	},
++
++	/*
++	 * AES ECB, CBC, CFB and OFB modes.
++	 */
++	{
++		.name = "ecb(aes)", .drv_name = "hifn-aes", .bsize = 16,
++		.ablkcipher = {
++			.min_keysize	=	AES_MIN_KEY_SIZE,
++			.max_keysize	=	AES_MAX_KEY_SIZE,
++			.setkey		=	hifn_setkey,
++			.encrypt	=	hifn_encrypt_aes_ecb,
++			.decrypt	=	hifn_decrypt_aes_ecb,
++		},
++	},
++	{
++		.name = "cbc(aes)", .drv_name = "hifn-aes", .bsize = 16,
++		.ablkcipher = {
++			.min_keysize	=	AES_MIN_KEY_SIZE,
++			.max_keysize	=	AES_MAX_KEY_SIZE,
++			.setkey		=	hifn_setkey,
++			.encrypt	=	hifn_encrypt_aes_cbc,
++			.decrypt	=	hifn_decrypt_aes_cbc,
++		},
++	},
++	{
++		.name = "cfb(aes)", .drv_name = "hifn-aes", .bsize = 16,
++		.ablkcipher = {
++			.min_keysize	=	AES_MIN_KEY_SIZE,
++			.max_keysize	=	AES_MAX_KEY_SIZE,
++			.setkey		=	hifn_setkey,
++			.encrypt	=	hifn_encrypt_aes_cfb,
++			.decrypt	=	hifn_decrypt_aes_cfb,
++		},
++	},
++	{
++		.name = "ofb(aes)", .drv_name = "hifn-aes", .bsize = 16,
++		.ablkcipher = {
++			.min_keysize	=	AES_MIN_KEY_SIZE,
++			.max_keysize	=	AES_MAX_KEY_SIZE,
++			.setkey		=	hifn_setkey,
++			.encrypt	=	hifn_encrypt_aes_ofb,
++			.decrypt	=	hifn_decrypt_aes_ofb,
++		},
++	},
++};
++
++static int hifn_cra_init(struct crypto_tfm *tfm)
++{
++	struct crypto_alg *alg = tfm->__crt_alg;
++	struct hifn_crypto_alg *ha = crypto_alg_to_hifn(alg);
++	struct hifn_context *ctx = crypto_tfm_ctx(tfm);
++
++	ctx->dev = ha->dev;
++
++	return 0;
++}
++
++static int hifn_alg_alloc(struct hifn_device *dev, struct hifn_alg_template *t)
++{
++	struct hifn_crypto_alg *alg;
++	int err;
++
++	alg = kzalloc(sizeof(struct hifn_crypto_alg), GFP_KERNEL);
++	if (!alg)
++		return -ENOMEM;
++
++	snprintf(alg->alg.cra_name, CRYPTO_MAX_ALG_NAME, "%s", t->name);
++	snprintf(alg->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", t->drv_name);
++
++	alg->alg.cra_priority = 300;
++	alg->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC;
++	alg->alg.cra_blocksize = t->bsize;
++	alg->alg.cra_ctxsize = sizeof(struct hifn_context);
++	alg->alg.cra_alignmask = 15;
++	if (t->bsize == 8)
++		alg->alg.cra_alignmask = 3;
++	alg->alg.cra_type = &crypto_ablkcipher_type;
++	alg->alg.cra_module = THIS_MODULE;
++	alg->alg.cra_u.ablkcipher = t->ablkcipher;
++	alg->alg.cra_init = hifn_cra_init;
++
++	alg->dev = dev;
++
++	list_add_tail(&alg->entry, &dev->alg_list);
++
++	err = crypto_register_alg(&alg->alg);
++	if (err) {
++		list_del(&alg->entry);
++		kfree(alg);
++	}
++
++	return err;
++}
++
++static void hifn_unregister_alg(struct hifn_device *dev)
++{
++	struct hifn_crypto_alg *a, *n;
++
++	list_for_each_entry_safe(a, n, &dev->alg_list, entry) {
++		list_del(&a->entry);
++		crypto_unregister_alg(&a->alg);
++		kfree(a);
++	}
++}
++
++static int hifn_register_alg(struct hifn_device *dev)
++{
++	int i, err;
++
++	for (i=0; i<ARRAY_SIZE(hifn_alg_templates); ++i) {
++		err = hifn_alg_alloc(dev, &hifn_alg_templates[i]);
++		if (err)
++			goto err_out_exit;
++	}
++
++	return 0;
++
++err_out_exit:
++	hifn_unregister_alg(dev);
++	return err;
++}
++
++static void hifn_tasklet_callback(unsigned long data)
++{
++	struct hifn_device *dev = (struct hifn_device *)data;
++
++	/*
++	 * This is ok to call this without lock being held,
++	 * althogh it modifies some parameters used in parallel,
++	 * (like dev->success), but they are used in process
++	 * context or update is atomic (like setting dev->sa[i] to NULL).
++	 */
++	hifn_check_for_completion(dev, 0);
++}
++
++static int hifn_probe(struct pci_dev *pdev, const struct pci_device_id *id)
++{
++	int err, i;
++	struct hifn_device *dev;
++	char name[8];
++
++	err = pci_enable_device(pdev);
++	if (err)
++		return err;
++	pci_set_master(pdev);
++
++	err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
++	if (err)
++		goto err_out_disable_pci_device;
++
++	snprintf(name, sizeof(name), "hifn%d",
++			atomic_inc_return(&hifn_dev_number)-1);
++
++	err = pci_request_regions(pdev, name);
++	if (err)
++		goto err_out_disable_pci_device;
++
++	if (pci_resource_len(pdev, 0) < HIFN_BAR0_SIZE ||
++	    pci_resource_len(pdev, 1) < HIFN_BAR1_SIZE ||
++	    pci_resource_len(pdev, 2) < HIFN_BAR2_SIZE) {
++		dprintk("%s: Broken hardware - I/O regions are too small.\n",
++				pci_name(pdev));
++		err = -ENODEV;
++		goto err_out_free_regions;
++	}
++
++	dev = kzalloc(sizeof(struct hifn_device) + sizeof(struct crypto_alg),
++			GFP_KERNEL);
++	if (!dev) {
++		err = -ENOMEM;
++		goto err_out_free_regions;
++	}
++
++	INIT_LIST_HEAD(&dev->alg_list);
++
++	snprintf(dev->name, sizeof(dev->name), "%s", name);
++	spin_lock_init(&dev->lock);
++
++	for (i=0; i<3; ++i) {
++		unsigned long addr, size;
++
++		addr = pci_resource_start(pdev, i);
++		size = pci_resource_len(pdev, i);
++
++		dev->bar[i] = ioremap_nocache(addr, size);
++		if (!dev->bar[i])
++			goto err_out_unmap_bars;
++	}
++
++	dev->result_mem = __get_free_pages(GFP_KERNEL, HIFN_MAX_RESULT_ORDER);
++	if (!dev->result_mem) {
++		dprintk("Failed to allocate %d pages for result_mem.\n",
++				HIFN_MAX_RESULT_ORDER);
++		goto err_out_unmap_bars;
++	}
++	memset((void *)dev->result_mem, 0, PAGE_SIZE*(1<<HIFN_MAX_RESULT_ORDER));
++
++	dev->dst = pci_map_single(pdev, (void *)dev->result_mem,
++			PAGE_SIZE << HIFN_MAX_RESULT_ORDER, PCI_DMA_FROMDEVICE);
++
++	dev->desc_virt = pci_alloc_consistent(pdev, sizeof(struct hifn_dma),
++			&dev->desc_dma);
++	if (!dev->desc_virt) {
++		dprintk("Failed to allocate descriptor rings.\n");
++		goto err_out_free_result_pages;
++	}
++	memset(dev->desc_virt, 0, sizeof(struct hifn_dma));
++
++	dev->pdev = pdev;
++	dev->irq = pdev->irq;
++
++	for (i=0; i<HIFN_D_RES_RSIZE; ++i)
++		dev->sa[i] = NULL;
++
++	pci_set_drvdata(pdev, dev);
++
++	tasklet_init(&dev->tasklet, hifn_tasklet_callback, (unsigned long)dev);
++
++	crypto_init_queue(&dev->queue, 1);
++
++	err = request_irq(dev->irq, hifn_interrupt, IRQF_SHARED, dev->name, dev);
++	if (err) {
++		dprintk("Failed to request IRQ%d: err: %d.\n", dev->irq, err);
++		dev->irq = 0;
++		goto err_out_free_desc;
++	}
++
++	err = hifn_start_device(dev);
++	if (err)
++		goto err_out_free_irq;
++
++	err = hifn_test(dev, 1, 0);
++	if (err)
++		goto err_out_stop_device;
++
++	err = hifn_register_rng(dev);
++	if (err)
++		goto err_out_stop_device;
++
++	err = hifn_register_alg(dev);
++	if (err)
++		goto err_out_unregister_rng;
++
++	INIT_DELAYED_WORK(&dev->work, hifn_work);
++	schedule_delayed_work(&dev->work, HZ);
++
++	dprintk("HIFN crypto accelerator card at %s has been "
++			"successfully registered as %s.\n",
++			pci_name(pdev), dev->name);
++
++	return 0;
++
++err_out_unregister_rng:
++	hifn_unregister_rng(dev);
++err_out_stop_device:
++	hifn_reset_dma(dev, 1);
++	hifn_stop_device(dev);
++err_out_free_irq:
++	free_irq(dev->irq, dev->name);
++	tasklet_kill(&dev->tasklet);
++err_out_free_desc:
++	pci_free_consistent(pdev, sizeof(struct hifn_dma),
++			dev->desc_virt, dev->desc_dma);
++
++err_out_free_result_pages:
++	pci_unmap_single(pdev, dev->dst, PAGE_SIZE << HIFN_MAX_RESULT_ORDER,
++			PCI_DMA_FROMDEVICE);
++	free_pages(dev->result_mem, HIFN_MAX_RESULT_ORDER);
++
++err_out_unmap_bars:
++	for (i=0; i<3; ++i)
++		if (dev->bar[i])
++			iounmap(dev->bar[i]);
++
++err_out_free_regions:
++	pci_release_regions(pdev);
++
++err_out_disable_pci_device:
++	pci_disable_device(pdev);
++
++	return err;
++}
++
++static void hifn_remove(struct pci_dev *pdev)
++{
++	int i;
++	struct hifn_device *dev;
++
++	dev = pci_get_drvdata(pdev);
++
++	if (dev) {
++		cancel_delayed_work(&dev->work);
++		flush_scheduled_work();
++
++		hifn_unregister_rng(dev);
++		hifn_unregister_alg(dev);
++		hifn_reset_dma(dev, 1);
++		hifn_stop_device(dev);
++
++		free_irq(dev->irq, dev->name);
++		tasklet_kill(&dev->tasklet);
++
++		hifn_flush(dev);
++
++		pci_free_consistent(pdev, sizeof(struct hifn_dma),
++				dev->desc_virt, dev->desc_dma);
++		pci_unmap_single(pdev, dev->dst,
++				PAGE_SIZE << HIFN_MAX_RESULT_ORDER,
++				PCI_DMA_FROMDEVICE);
++		free_pages(dev->result_mem, HIFN_MAX_RESULT_ORDER);
++		for (i=0; i<3; ++i)
++			if (dev->bar[i])
++				iounmap(dev->bar[i]);
++
++		kfree(dev);
++	}
++
++	pci_release_regions(pdev);
++	pci_disable_device(pdev);
++}
++
++static struct pci_device_id hifn_pci_tbl[] = {
++	{ PCI_DEVICE(PCI_VENDOR_ID_HIFN, PCI_DEVICE_ID_HIFN_7955) },
++	{ PCI_DEVICE(PCI_VENDOR_ID_HIFN, PCI_DEVICE_ID_HIFN_7956) },
++	{ 0 }
++};
++MODULE_DEVICE_TABLE(pci, hifn_pci_tbl);
++
++static struct pci_driver hifn_pci_driver = {
++	.name     = "hifn795x",
++	.id_table = hifn_pci_tbl,
++	.probe    = hifn_probe,
++	.remove   = __devexit_p(hifn_remove),
++};
++
++static int __devinit hifn_init(void)
++{
++	unsigned int freq;
++	int err;
++
++	if (strncmp(hifn_pll_ref, "ext", 3) &&
++	    strncmp(hifn_pll_ref, "pci", 3)) {
++		printk(KERN_ERR "hifn795x: invalid hifn_pll_ref clock, "
++				"must be pci or ext");
++		return -EINVAL;
++	}
++
++	/*
++	 * For the 7955/7956 the reference clock frequency must be in the
++	 * range of 20MHz-100MHz. For the 7954 the upper bound is 66.67MHz,
++	 * but this chip is currently not supported.
++	 */
++	if (hifn_pll_ref[3] != '\0') {
++		freq = simple_strtoul(hifn_pll_ref + 3, NULL, 10);
++		if (freq < 20 || freq > 100) {
++			printk(KERN_ERR "hifn795x: invalid hifn_pll_ref "
++					"frequency, must be in the range "
++					"of 20-100");
++			return -EINVAL;
++		}
++	}
++
++	err = pci_register_driver(&hifn_pci_driver);
++	if (err < 0) {
++		dprintk("Failed to register PCI driver for %s device.\n",
++				hifn_pci_driver.name);
++		return -ENODEV;
++	}
++
++	printk(KERN_INFO "Driver for HIFN 795x crypto accelerator chip "
++			"has been successfully registered.\n");
++
++	return 0;
++}
++
++static void __devexit hifn_fini(void)
++{
++	pci_unregister_driver(&hifn_pci_driver);
++
++	printk(KERN_INFO "Driver for HIFN 795x crypto accelerator chip "
++			"has been successfully unregistered.\n");
++}
++
++module_init(hifn_init);
++module_exit(hifn_fini);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Evgeniy Polyakov <johnpol at 2ka.mipt.ru>");
++MODULE_DESCRIPTION("Driver for HIFN 795x crypto accelerator chip.");
+diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
+index 5f7e718..2f3ad3f 100644
+--- a/drivers/crypto/padlock-aes.c
++++ b/drivers/crypto/padlock-aes.c
+@@ -44,6 +44,7 @@
+  */
+ 
+ #include <crypto/algapi.h>
++#include <crypto/aes.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/types.h>
+@@ -53,9 +54,6 @@
+ #include <asm/byteorder.h>
+ #include "padlock.h"
+ 
+-#define AES_MIN_KEY_SIZE	16	/* in uint8_t units */
+-#define AES_MAX_KEY_SIZE	32	/* ditto */
+-#define AES_BLOCK_SIZE		16	/* ditto */
+ #define AES_EXTENDED_KEY_SIZE	64	/* in uint32_t units */
+ #define AES_EXTENDED_KEY_SIZE_B	(AES_EXTENDED_KEY_SIZE * sizeof(uint32_t))
+ 
+@@ -419,6 +417,11 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+ /* ====== Encryption/decryption routines ====== */
+ 
+ /* These are the real call to PadLock. */
++static inline void padlock_reset_key(void)
++{
++	asm volatile ("pushfl; popfl");
++}
++
+ static inline void padlock_xcrypt(const u8 *input, u8 *output, void *key,
+ 				  void *control_word)
+ {
+@@ -439,8 +442,6 @@ static void aes_crypt_copy(const u8 *in, u8 *out, u32 *key, struct cword *cword)
+ static inline void aes_crypt(const u8 *in, u8 *out, u32 *key,
+ 			     struct cword *cword)
+ {
+-	asm volatile ("pushfl; popfl");
+-
+ 	/* padlock_xcrypt requires at least two blocks of data. */
+ 	if (unlikely(!(((unsigned long)in ^ (PAGE_SIZE - AES_BLOCK_SIZE)) &
+ 		       (PAGE_SIZE - 1)))) {
+@@ -459,7 +460,6 @@ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key,
+ 		return;
+ 	}
+ 
+-	asm volatile ("pushfl; popfl");		/* enforce key reload. */
+ 	asm volatile ("test $1, %%cl;"
+ 		      "je 1f;"
+ 		      "lea -1(%%ecx), %%eax;"
+@@ -476,8 +476,6 @@ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key,
+ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
+ 				     u8 *iv, void *control_word, u32 count)
+ {
+-	/* Enforce key reload. */
+-	asm volatile ("pushfl; popfl");
+ 	/* rep xcryptcbc */
+ 	asm volatile (".byte 0xf3,0x0f,0xa7,0xd0"
+ 		      : "+S" (input), "+D" (output), "+a" (iv)
+@@ -488,12 +486,14 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
+ static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
+ {
+ 	struct aes_ctx *ctx = aes_ctx(tfm);
++	padlock_reset_key();
+ 	aes_crypt(in, out, ctx->E, &ctx->cword.encrypt);
+ }
+ 
+ static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
+ {
+ 	struct aes_ctx *ctx = aes_ctx(tfm);
++	padlock_reset_key();
+ 	aes_crypt(in, out, ctx->D, &ctx->cword.decrypt);
+ }
+ 
+@@ -526,6 +526,8 @@ static int ecb_aes_encrypt(struct blkcipher_desc *desc,
+ 	struct blkcipher_walk walk;
+ 	int err;
+ 
++	padlock_reset_key();
++
+ 	blkcipher_walk_init(&walk, dst, src, nbytes);
+ 	err = blkcipher_walk_virt(desc, &walk);
+ 
+@@ -548,6 +550,8 @@ static int ecb_aes_decrypt(struct blkcipher_desc *desc,
+ 	struct blkcipher_walk walk;
+ 	int err;
+ 
++	padlock_reset_key();
 +
-+static void hifn_flush(struct hifn_device *dev)
-+{
-+	unsigned long flags;
-+	struct crypto_async_request *async_req;
-+	struct hifn_context *ctx;
-+	struct ablkcipher_request *req;
-+	struct hifn_dma *dma = (struct hifn_dma *)dev->desc_virt;
-+	int i;
+ 	blkcipher_walk_init(&walk, dst, src, nbytes);
+ 	err = blkcipher_walk_virt(desc, &walk);
+ 
+@@ -592,6 +596,8 @@ static int cbc_aes_encrypt(struct blkcipher_desc *desc,
+ 	struct blkcipher_walk walk;
+ 	int err;
+ 
++	padlock_reset_key();
 +
-+	spin_lock_irqsave(&dev->lock, flags);
-+	for (i=0; i<HIFN_D_RES_RSIZE; ++i) {
-+		struct hifn_desc *d = &dma->resr[i];
+ 	blkcipher_walk_init(&walk, dst, src, nbytes);
+ 	err = blkcipher_walk_virt(desc, &walk);
+ 
+@@ -616,6 +622,8 @@ static int cbc_aes_decrypt(struct blkcipher_desc *desc,
+ 	struct blkcipher_walk walk;
+ 	int err;
+ 
++	padlock_reset_key();
 +
-+		if (dev->sa[i]) {
-+			hifn_process_ready(dev->sa[i],
-+				(d->l & __cpu_to_le32(HIFN_D_VALID))?-ENODEV:0);
-+		}
-+	}
+ 	blkcipher_walk_init(&walk, dst, src, nbytes);
+ 	err = blkcipher_walk_virt(desc, &walk);
+ 
+diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
+index d59b2f4..bcf52df 100644
+--- a/drivers/dma/dmaengine.c
++++ b/drivers/dma/dmaengine.c
+@@ -41,12 +41,12 @@
+  * the definition of dma_event_callback in dmaengine.h.
+  *
+  * Each device has a kref, which is initialized to 1 when the device is
+- * registered. A kref_get is done for each class_device registered.  When the
+- * class_device is released, the coresponding kref_put is done in the release
++ * registered. A kref_get is done for each device registered.  When the
++ * device is released, the coresponding kref_put is done in the release
+  * method. Every time one of the device's channels is allocated to a client,
+  * a kref_get occurs.  When the channel is freed, the coresponding kref_put
+  * happens. The device's release function does a completion, so
+- * unregister_device does a remove event, class_device_unregister, a kref_put
++ * unregister_device does a remove event, device_unregister, a kref_put
+  * for the first reference, then waits on the completion for all other
+  * references to finish.
+  *
+@@ -77,9 +77,9 @@ static LIST_HEAD(dma_client_list);
+ 
+ /* --- sysfs implementation --- */
+ 
+-static ssize_t show_memcpy_count(struct class_device *cd, char *buf)
++static ssize_t show_memcpy_count(struct device *dev, struct device_attribute *attr, char *buf)
+ {
+-	struct dma_chan *chan = container_of(cd, struct dma_chan, class_dev);
++	struct dma_chan *chan = to_dma_chan(dev);
+ 	unsigned long count = 0;
+ 	int i;
+ 
+@@ -89,9 +89,10 @@ static ssize_t show_memcpy_count(struct class_device *cd, char *buf)
+ 	return sprintf(buf, "%lu\n", count);
+ }
+ 
+-static ssize_t show_bytes_transferred(struct class_device *cd, char *buf)
++static ssize_t show_bytes_transferred(struct device *dev, struct device_attribute *attr,
++				      char *buf)
+ {
+-	struct dma_chan *chan = container_of(cd, struct dma_chan, class_dev);
++	struct dma_chan *chan = to_dma_chan(dev);
+ 	unsigned long count = 0;
+ 	int i;
+ 
+@@ -101,9 +102,9 @@ static ssize_t show_bytes_transferred(struct class_device *cd, char *buf)
+ 	return sprintf(buf, "%lu\n", count);
+ }
+ 
+-static ssize_t show_in_use(struct class_device *cd, char *buf)
++static ssize_t show_in_use(struct device *dev, struct device_attribute *attr, char *buf)
+ {
+-	struct dma_chan *chan = container_of(cd, struct dma_chan, class_dev);
++	struct dma_chan *chan = to_dma_chan(dev);
+ 	int in_use = 0;
+ 
+ 	if (unlikely(chan->slow_ref) &&
+@@ -119,7 +120,7 @@ static ssize_t show_in_use(struct class_device *cd, char *buf)
+ 	return sprintf(buf, "%d\n", in_use);
+ }
+ 
+-static struct class_device_attribute dma_class_attrs[] = {
++static struct device_attribute dma_attrs[] = {
+ 	__ATTR(memcpy_count, S_IRUGO, show_memcpy_count, NULL),
+ 	__ATTR(bytes_transferred, S_IRUGO, show_bytes_transferred, NULL),
+ 	__ATTR(in_use, S_IRUGO, show_in_use, NULL),
+@@ -128,16 +129,16 @@ static struct class_device_attribute dma_class_attrs[] = {
+ 
+ static void dma_async_device_cleanup(struct kref *kref);
+ 
+-static void dma_class_dev_release(struct class_device *cd)
++static void dma_dev_release(struct device *dev)
+ {
+-	struct dma_chan *chan = container_of(cd, struct dma_chan, class_dev);
++	struct dma_chan *chan = to_dma_chan(dev);
+ 	kref_put(&chan->device->refcount, dma_async_device_cleanup);
+ }
+ 
+ static struct class dma_devclass = {
+-	.name            = "dma",
+-	.class_dev_attrs = dma_class_attrs,
+-	.release = dma_class_dev_release,
++	.name		= "dma",
++	.dev_attrs	= dma_attrs,
++	.dev_release	= dma_dev_release,
+ };
+ 
+ /* --- client and device registration --- */
+@@ -377,12 +378,12 @@ int dma_async_device_register(struct dma_device *device)
+ 			continue;
+ 
+ 		chan->chan_id = chancnt++;
+-		chan->class_dev.class = &dma_devclass;
+-		chan->class_dev.dev = NULL;
+-		snprintf(chan->class_dev.class_id, BUS_ID_SIZE, "dma%dchan%d",
++		chan->dev.class = &dma_devclass;
++		chan->dev.parent = NULL;
++		snprintf(chan->dev.bus_id, BUS_ID_SIZE, "dma%dchan%d",
+ 		         device->dev_id, chan->chan_id);
+ 
+-		rc = class_device_register(&chan->class_dev);
++		rc = device_register(&chan->dev);
+ 		if (rc) {
+ 			chancnt--;
+ 			free_percpu(chan->local);
+@@ -411,7 +412,7 @@ err_out:
+ 		if (chan->local == NULL)
+ 			continue;
+ 		kref_put(&device->refcount, dma_async_device_cleanup);
+-		class_device_unregister(&chan->class_dev);
++		device_unregister(&chan->dev);
+ 		chancnt--;
+ 		free_percpu(chan->local);
+ 	}
+@@ -445,7 +446,7 @@ void dma_async_device_unregister(struct dma_device *device)
+ 
+ 	list_for_each_entry(chan, &device->channels, device_node) {
+ 		dma_clients_notify_removed(chan);
+-		class_device_unregister(&chan->class_dev);
++		device_unregister(&chan->dev);
+ 		dma_chan_release(chan);
+ 	}
+ 
+diff --git a/drivers/edac/edac_device_sysfs.c b/drivers/edac/edac_device_sysfs.c
+index 70b837f..5376457 100644
+--- a/drivers/edac/edac_device_sysfs.c
++++ b/drivers/edac/edac_device_sysfs.c
+@@ -246,16 +246,6 @@ int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev)
+ 
+ 	/* Init the devices's kobject */
+ 	memset(&edac_dev->kobj, 0, sizeof(struct kobject));
+-	edac_dev->kobj.ktype = &ktype_device_ctrl;
+-
+-	/* set this new device under the edac_class kobject */
+-	edac_dev->kobj.parent = &edac_class->kset.kobj;
+-
+-	/* generate sysfs "..../edac/<name>"   */
+-	debugf4("%s() set name of kobject to: %s\n", __func__, edac_dev->name);
+-	err = kobject_set_name(&edac_dev->kobj, "%s", edac_dev->name);
+-	if (err)
+-		goto err_out;
+ 
+ 	/* Record which module 'owns' this control structure
+ 	 * and bump the ref count of the module
+@@ -268,12 +258,15 @@ int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev)
+ 	}
+ 
+ 	/* register */
+-	err = kobject_register(&edac_dev->kobj);
++	err = kobject_init_and_add(&edac_dev->kobj, &ktype_device_ctrl,
++				   &edac_class->kset.kobj,
++				   "%s", edac_dev->name);
+ 	if (err) {
+ 		debugf1("%s()Failed to register '.../edac/%s'\n",
+ 			__func__, edac_dev->name);
+ 		goto err_kobj_reg;
+ 	}
++	kobject_uevent(&edac_dev->kobj, KOBJ_ADD);
+ 
+ 	/* At this point, to 'free' the control struct,
+ 	 * edac_device_unregister_sysfs_main_kobj() must be used
+@@ -310,7 +303,7 @@ void edac_device_unregister_sysfs_main_kobj(
+ 	 *   a) module_put() this module
+ 	 *   b) 'kfree' the memory
+ 	 */
+-	kobject_unregister(&edac_dev->kobj);
++	kobject_put(&edac_dev->kobj);
+ }
+ 
+ /* edac_dev -> instance information */
+@@ -533,12 +526,6 @@ static int edac_device_create_block(struct edac_device_ctl_info *edac_dev,
+ 
+ 	/* init this block's kobject */
+ 	memset(&block->kobj, 0, sizeof(struct kobject));
+-	block->kobj.parent = &instance->kobj;
+-	block->kobj.ktype = &ktype_block_ctrl;
+-
+-	err = kobject_set_name(&block->kobj, "%s", block->name);
+-	if (err)
+-		return err;
+ 
+ 	/* bump the main kobject's reference count for this controller
+ 	 * and this instance is dependant on the main
+@@ -550,7 +537,9 @@ static int edac_device_create_block(struct edac_device_ctl_info *edac_dev,
+ 	}
+ 
+ 	/* Add this block's kobject */
+-	err = kobject_register(&block->kobj);
++	err = kobject_init_and_add(&block->kobj, &ktype_block_ctrl,
++				   &instance->kobj,
++				   "%s", block->name);
+ 	if (err) {
+ 		debugf1("%s() Failed to register instance '%s'\n",
+ 			__func__, block->name);
+@@ -579,12 +568,13 @@ static int edac_device_create_block(struct edac_device_ctl_info *edac_dev,
+ 				goto err_on_attrib;
+ 		}
+ 	}
++	kobject_uevent(&block->kobj, KOBJ_ADD);
+ 
+ 	return 0;
+ 
+ 	/* Error unwind stack */
+ err_on_attrib:
+-	kobject_unregister(&block->kobj);
++	kobject_put(&block->kobj);
+ 
+ err_out:
+ 	return err;
+@@ -615,7 +605,7 @@ static void edac_device_delete_block(struct edac_device_ctl_info *edac_dev,
+ 	/* unregister this block's kobject, SEE:
+ 	 *	edac_device_ctrl_block_release() callback operation
+ 	 */
+-	kobject_unregister(&block->kobj);
++	kobject_put(&block->kobj);
+ }
+ 
+ /* instance ctor/dtor code */
+@@ -637,15 +627,8 @@ static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev,
+ 	/* Init the instance's kobject */
+ 	memset(&instance->kobj, 0, sizeof(struct kobject));
+ 
+-	/* set this new device under the edac_device main kobject */
+-	instance->kobj.parent = &edac_dev->kobj;
+-	instance->kobj.ktype = &ktype_instance_ctrl;
+ 	instance->ctl = edac_dev;
+ 
+-	err = kobject_set_name(&instance->kobj, "%s", instance->name);
+-	if (err)
+-		goto err_out;
+-
+ 	/* bump the main kobject's reference count for this controller
+ 	 * and this instance is dependant on the main
+ 	 */
+@@ -655,8 +638,9 @@ static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev,
+ 		goto err_out;
+ 	}
+ 
+-	/* Formally register this instance's kobject */
+-	err = kobject_register(&instance->kobj);
++	/* Formally register this instance's kobject under the edac_device */
++	err = kobject_init_and_add(&instance->kobj, &ktype_instance_ctrl,
++				   &edac_dev->kobj, "%s", instance->name);
+ 	if (err != 0) {
+ 		debugf2("%s() Failed to register instance '%s'\n",
+ 			__func__, instance->name);
+@@ -679,6 +663,7 @@ static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev,
+ 			goto err_release_instance_kobj;
+ 		}
+ 	}
++	kobject_uevent(&instance->kobj, KOBJ_ADD);
+ 
+ 	debugf4("%s() Registered instance %d '%s' kobject\n",
+ 		__func__, idx, instance->name);
+@@ -687,7 +672,7 @@ static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev,
+ 
+ 	/* error unwind stack */
+ err_release_instance_kobj:
+-	kobject_unregister(&instance->kobj);
++	kobject_put(&instance->kobj);
+ 
+ err_out:
+ 	return err;
+@@ -712,7 +697,7 @@ static void edac_device_delete_instance(struct edac_device_ctl_info *edac_dev,
+ 	/* unregister this instance's kobject, SEE:
+ 	 *	edac_device_ctrl_instance_release() for callback operation
+ 	 */
+-	kobject_unregister(&instance->kobj);
++	kobject_put(&instance->kobj);
+ }
+ 
+ /*
+diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
+index 3706b2b..9aac880 100644
+--- a/drivers/edac/edac_mc_sysfs.c
++++ b/drivers/edac/edac_mc_sysfs.c
+@@ -380,13 +380,6 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci,
+ 	/* generate ..../edac/mc/mc<id>/csrow<index>   */
+ 	memset(&csrow->kobj, 0, sizeof(csrow->kobj));
+ 	csrow->mci = mci;	/* include container up link */
+-	csrow->kobj.parent = kobj_mci;
+-	csrow->kobj.ktype = &ktype_csrow;
+-
+-	/* name this instance of csrow<id> */
+-	err = kobject_set_name(&csrow->kobj, "csrow%d", index);
+-	if (err)
+-		goto err_out;
+ 
+ 	/* bump the mci instance's kobject's ref count */
+ 	kobj = kobject_get(&mci->edac_mci_kobj);
+@@ -396,12 +389,13 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci,
+ 	}
+ 
+ 	/* Instanstiate the csrow object */
+-	err = kobject_register(&csrow->kobj);
++	err = kobject_init_and_add(&csrow->kobj, &ktype_csrow, kobj_mci,
++				   "csrow%d", index);
+ 	if (err)
+ 		goto err_release_top_kobj;
+ 
+ 	/* At this point, to release a csrow kobj, one must
+-	 * call the kobject_unregister and allow that tear down
++	 * call the kobject_put and allow that tear down
+ 	 * to work the releasing
+ 	 */
+ 
+@@ -412,11 +406,11 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci,
+ 		err = edac_create_channel_files(&csrow->kobj, chan);
+ 		if (err) {
+ 			/* special case the unregister here */
+-			kobject_unregister(&csrow->kobj);
++			kobject_put(&csrow->kobj);
+ 			goto err_out;
+ 		}
+ 	}
+-
++	kobject_uevent(&csrow->kobj, KOBJ_ADD);
+ 	return 0;
+ 
+ 	/* error unwind stack */
+@@ -744,7 +738,6 @@ static struct kobj_type ktype_mc_set_attribs = {
+  */
+ static struct kset mc_kset = {
+ 	.kobj = {.ktype = &ktype_mc_set_attribs },
+-	.ktype = &ktype_mci,
+ };
+ 
+ 
+@@ -765,14 +758,6 @@ int edac_mc_register_sysfs_main_kobj(struct mem_ctl_info *mci)
+ 	/* Init the mci's kobject */
+ 	memset(kobj_mci, 0, sizeof(*kobj_mci));
+ 
+-	/* this instance become part of the mc_kset */
+-	kobj_mci->kset = &mc_kset;
+-
+-	/* set the name of the mc<id> object */
+-	err = kobject_set_name(kobj_mci, "mc%d", mci->mc_idx);
+-	if (err)
+-		goto fail_out;
+-
+ 	/* Record which module 'owns' this control structure
+ 	 * and bump the ref count of the module
+ 	 */
+@@ -784,13 +769,18 @@ int edac_mc_register_sysfs_main_kobj(struct mem_ctl_info *mci)
+ 		goto fail_out;
+ 	}
+ 
++	/* this instance become part of the mc_kset */
++	kobj_mci->kset = &mc_kset;
 +
-+	while ((async_req = crypto_dequeue_request(&dev->queue))) {
-+		ctx = crypto_tfm_ctx(async_req->tfm);
-+		req = container_of(async_req, struct ablkcipher_request, base);
+ 	/* register the mc<id> kobject to the mc_kset */
+-	err = kobject_register(kobj_mci);
++	err = kobject_init_and_add(kobj_mci, &ktype_mci, NULL,
++				   "mc%d", mci->mc_idx);
+ 	if (err) {
+ 		debugf1("%s()Failed to register '.../edac/mc%d'\n",
+ 			__func__, mci->mc_idx);
+ 		goto kobj_reg_fail;
+ 	}
++	kobject_uevent(kobj_mci, KOBJ_ADD);
+ 
+ 	/* At this point, to 'free' the control struct,
+ 	 * edac_mc_unregister_sysfs_main_kobj() must be used
+@@ -818,7 +808,7 @@ fail_out:
+ void edac_mc_unregister_sysfs_main_kobj(struct mem_ctl_info *mci)
+ {
+ 	/* delete the kobj from the mc_kset */
+-	kobject_unregister(&mci->edac_mci_kobj);
++	kobject_put(&mci->edac_mci_kobj);
+ }
+ 
+ #define EDAC_DEVICE_SYMLINK	"device"
+@@ -933,7 +923,7 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
+ fail1:
+ 	for (i--; i >= 0; i--) {
+ 		if (csrow->nr_pages > 0) {
+-			kobject_unregister(&mci->csrows[i].kobj);
++			kobject_put(&mci->csrows[i].kobj);
+ 		}
+ 	}
+ 
+@@ -960,7 +950,7 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
+ 	for (i = 0; i < mci->nr_csrows; i++) {
+ 		if (mci->csrows[i].nr_pages > 0) {
+ 			debugf0("%s()  unreg csrow-%d\n", __func__, i);
+-			kobject_unregister(&mci->csrows[i].kobj);
++			kobject_put(&mci->csrows[i].kobj);
+ 		}
+ 	}
+ 
+@@ -977,7 +967,7 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
+ 	debugf0("%s()  unregister this mci kobj\n", __func__);
+ 
+ 	/* unregister this instance's kobject */
+-	kobject_unregister(&mci->edac_mci_kobj);
++	kobject_put(&mci->edac_mci_kobj);
+ }
+ 
+ 
+diff --git a/drivers/edac/edac_module.c b/drivers/edac/edac_module.c
+index e0c4a40..7e1374a 100644
+--- a/drivers/edac/edac_module.c
++++ b/drivers/edac/edac_module.c
+@@ -31,7 +31,7 @@ struct workqueue_struct *edac_workqueue;
+  *	need to export to other files in this modules
+  */
+ static struct sysdev_class edac_class = {
+-	set_kset_name("edac"),
++	.name = "edac",
+ };
+ static int edac_class_valid;
+ 
+diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c
+index 69f5ddd..5b075da 100644
+--- a/drivers/edac/edac_pci_sysfs.c
++++ b/drivers/edac/edac_pci_sysfs.c
+@@ -162,14 +162,6 @@ static int edac_pci_create_instance_kobj(struct edac_pci_ctl_info *pci, int idx)
+ 
+ 	debugf0("%s()\n", __func__);
+ 
+-	/* Set the parent and the instance's ktype */
+-	pci->kobj.parent = &edac_pci_top_main_kobj;
+-	pci->kobj.ktype = &ktype_pci_instance;
+-
+-	err = kobject_set_name(&pci->kobj, "pci%d", idx);
+-	if (err)
+-		return err;
+-
+ 	/* First bump the ref count on the top main kobj, which will
+ 	 * track the number of PCI instances we have, and thus nest
+ 	 * properly on keeping the module loaded
+@@ -181,7 +173,8 @@ static int edac_pci_create_instance_kobj(struct edac_pci_ctl_info *pci, int idx)
+ 	}
+ 
+ 	/* And now register this new kobject under the main kobj */
+-	err = kobject_register(&pci->kobj);
++	err = kobject_init_and_add(&pci->kobj, &ktype_pci_instance,
++				   &edac_pci_top_main_kobj, "pci%d", idx);
+ 	if (err != 0) {
+ 		debugf2("%s() failed to register instance pci%d\n",
+ 			__func__, idx);
+@@ -189,6 +182,7 @@ static int edac_pci_create_instance_kobj(struct edac_pci_ctl_info *pci, int idx)
+ 		goto error_out;
+ 	}
+ 
++	kobject_uevent(&pci->kobj, KOBJ_ADD);
+ 	debugf1("%s() Register instance 'pci%d' kobject\n", __func__, idx);
+ 
+ 	return 0;
+@@ -211,7 +205,7 @@ void edac_pci_unregister_sysfs_instance_kobj(struct edac_pci_ctl_info *pci)
+ 	 * function release the main reference count and then
+ 	 * kfree the memory
+ 	 */
+-	kobject_unregister(&pci->kobj);
++	kobject_put(&pci->kobj);
+ }
+ 
+ /***************************** EDAC PCI sysfs root **********************/
+@@ -364,14 +358,6 @@ int edac_pci_main_kobj_setup(void)
+ 		goto decrement_count_fail;
+ 	}
+ 
+-	/* Need the kobject hook ups, and name setting */
+-	edac_pci_top_main_kobj.ktype = &ktype_edac_pci_main_kobj;
+-	edac_pci_top_main_kobj.parent = &edac_class->kset.kobj;
+-
+-	err = kobject_set_name(&edac_pci_top_main_kobj, "pci");
+-	if (err)
+-		goto decrement_count_fail;
+-
+ 	/* Bump the reference count on this module to ensure the
+ 	 * modules isn't unloaded until we deconstruct the top
+ 	 * level main kobj for EDAC PCI
+@@ -383,23 +369,24 @@ int edac_pci_main_kobj_setup(void)
+ 	}
+ 
+ 	/* Instanstiate the pci object */
+-	/* FIXME: maybe new sysdev_create_subdir() */
+-	err = kobject_register(&edac_pci_top_main_kobj);
++	err = kobject_init_and_add(&edac_pci_top_main_kobj, &ktype_edac_pci_main_kobj,
++				   &edac_class->kset.kobj, "pci");
+ 	if (err) {
+ 		debugf1("Failed to register '.../edac/pci'\n");
+-		goto kobject_register_fail;
++		goto kobject_init_and_add_fail;
+ 	}
+ 
+ 	/* At this point, to 'release' the top level kobject
+ 	 * for EDAC PCI, then edac_pci_main_kobj_teardown()
+ 	 * must be used, for resources to be cleaned up properly
+ 	 */
++	kobject_uevent(&edac_pci_top_main_kobj, KOBJ_ADD);
+ 	debugf1("Registered '.../edac/pci' kobject\n");
+ 
+ 	return 0;
+ 
+ 	/* Error unwind statck */
+-kobject_register_fail:
++kobject_init_and_add_fail:
+ 	module_put(THIS_MODULE);
+ 
+ decrement_count_fail:
+@@ -424,9 +411,9 @@ static void edac_pci_main_kobj_teardown(void)
+ 	 * main kobj
+ 	 */
+ 	if (atomic_dec_return(&edac_pci_sysfs_refcount) == 0) {
+-		debugf0("%s() called kobject_unregister on main kobj\n",
++		debugf0("%s() called kobject_put on main kobj\n",
+ 			__func__);
+-		kobject_unregister(&edac_pci_top_main_kobj);
++		kobject_put(&edac_pci_top_main_kobj);
+ 	}
+ }
+ 
+diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
+index 624ff3e..c2169d2 100644
+--- a/drivers/firewire/fw-sbp2.c
++++ b/drivers/firewire/fw-sbp2.c
+@@ -1238,6 +1238,12 @@ static int sbp2_scsi_slave_alloc(struct scsi_device *sdev)
+ 
+ 	sdev->allow_restart = 1;
+ 
++	/*
++	 * Update the dma alignment (minimum alignment requirements for
++	 * start and end of DMA transfers) to be a sector
++	 */
++	blk_queue_update_dma_alignment(sdev->request_queue, 511);
 +
-+		hifn_process_ready(req, -ENODEV);
+ 	if (lu->tgt->workarounds & SBP2_WORKAROUND_INQUIRY_36)
+ 		sdev->inquiry_len = 36;
+ 
+diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c
+index 6942e06..d168223 100644
+--- a/drivers/firmware/edd.c
++++ b/drivers/firmware/edd.c
+@@ -631,7 +631,7 @@ static struct kobj_type edd_ktype = {
+ 	.default_attrs	= def_attrs,
+ };
+ 
+-static decl_subsys(edd, &edd_ktype, NULL);
++static struct kset *edd_kset;
+ 
+ 
+ /**
+@@ -693,7 +693,7 @@ edd_create_symlink_to_pcidev(struct edd_device *edev)
+ static inline void
+ edd_device_unregister(struct edd_device *edev)
+ {
+-	kobject_unregister(&edev->kobj);
++	kobject_put(&edev->kobj);
+ }
+ 
+ static void edd_populate_dir(struct edd_device * edev)
+@@ -721,12 +721,13 @@ edd_device_register(struct edd_device *edev, int i)
+ 	if (!edev)
+ 		return 1;
+ 	edd_dev_set_info(edev, i);
+-	kobject_set_name(&edev->kobj, "int13_dev%02x",
+-			 0x80 + i);
+-	kobj_set_kset_s(edev,edd_subsys);
+-	error = kobject_register(&edev->kobj);
+-	if (!error)
++	edev->kobj.kset = edd_kset;
++	error = kobject_init_and_add(&edev->kobj, &edd_ktype, NULL,
++				     "int13_dev%02x", 0x80 + i);
++	if (!error) {
+ 		edd_populate_dir(edev);
++		kobject_uevent(&edev->kobj, KOBJ_ADD);
 +	}
-+	spin_unlock_irqrestore(&dev->lock, flags);
-+}
+ 	return error;
+ }
+ 
+@@ -755,9 +756,9 @@ edd_init(void)
+ 		return 1;
+ 	}
+ 
+-	rc = firmware_register(&edd_subsys);
+-	if (rc)
+-		return rc;
++	edd_kset = kset_create_and_add("edd", NULL, firmware_kobj);
++	if (!edd_kset)
++		return -ENOMEM;
+ 
+ 	for (i = 0; i < edd_num_devices() && !rc; i++) {
+ 		edev = kzalloc(sizeof (*edev), GFP_KERNEL);
+@@ -773,7 +774,7 @@ edd_init(void)
+ 	}
+ 
+ 	if (rc)
+-		firmware_unregister(&edd_subsys);
++		kset_unregister(edd_kset);
+ 	return rc;
+ }
+ 
+@@ -787,7 +788,7 @@ edd_exit(void)
+ 		if ((edev = edd_devices[i]))
+ 			edd_device_unregister(edev);
+ 	}
+-	firmware_unregister(&edd_subsys);
++	kset_unregister(edd_kset);
+ }
+ 
+ late_initcall(edd_init);
+diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
+index 858a7b9..f4f709d 100644
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -129,13 +129,6 @@ struct efivar_attribute {
+ };
+ 
+ 
+-#define EFI_ATTR(_name, _mode, _show, _store) \
+-struct subsys_attribute efi_attr_##_name = { \
+-	.attr = {.name = __stringify(_name), .mode = _mode}, \
+-	.show = _show, \
+-	.store = _store, \
+-};
+-
+ #define EFIVAR_ATTR(_name, _mode, _show, _store) \
+ struct efivar_attribute efivar_attr_##_name = { \
+ 	.attr = {.name = __stringify(_name), .mode = _mode}, \
+@@ -143,13 +136,6 @@ struct efivar_attribute efivar_attr_##_name = { \
+ 	.store = _store, \
+ };
+ 
+-#define VAR_SUBSYS_ATTR(_name, _mode, _show, _store) \
+-struct subsys_attribute var_subsys_attr_##_name = { \
+-	.attr = {.name = __stringify(_name), .mode = _mode}, \
+-	.show = _show, \
+-	.store = _store, \
+-};
+-
+ #define to_efivar_attr(_attr) container_of(_attr, struct efivar_attribute, attr)
+ #define to_efivar_entry(obj)  container_of(obj, struct efivar_entry, kobj)
+ 
+@@ -408,21 +394,16 @@ static struct kobj_type efivar_ktype = {
+ 	.default_attrs = def_attrs,
+ };
+ 
+-static ssize_t
+-dummy(struct kset *kset, char *buf)
+-{
+-	return -ENODEV;
+-}
+-
+ static inline void
+ efivar_unregister(struct efivar_entry *var)
+ {
+-	kobject_unregister(&var->kobj);
++	kobject_put(&var->kobj);
+ }
+ 
+ 
+-static ssize_t
+-efivar_create(struct kset *kset, const char *buf, size_t count)
++static ssize_t efivar_create(struct kobject *kobj,
++			     struct bin_attribute *bin_attr,
++			     char *buf, loff_t pos, size_t count)
+ {
+ 	struct efi_variable *new_var = (struct efi_variable *)buf;
+ 	struct efivar_entry *search_efivar, *n;
+@@ -479,8 +460,9 @@ efivar_create(struct kset *kset, const char *buf, size_t count)
+ 	return count;
+ }
+ 
+-static ssize_t
+-efivar_delete(struct kset *kset, const char *buf, size_t count)
++static ssize_t efivar_delete(struct kobject *kobj,
++			     struct bin_attribute *bin_attr,
++			     char *buf, loff_t pos, size_t count)
+ {
+ 	struct efi_variable *del_var = (struct efi_variable *)buf;
+ 	struct efivar_entry *search_efivar, *n;
+@@ -537,25 +519,26 @@ efivar_delete(struct kset *kset, const char *buf, size_t count)
+ 	return count;
+ }
+ 
+-static VAR_SUBSYS_ATTR(new_var, 0200, dummy, efivar_create);
+-static VAR_SUBSYS_ATTR(del_var, 0200, dummy, efivar_delete);
++static struct bin_attribute var_subsys_attr_new_var = {
++	.attr = {.name = "new_var", .mode = 0200},
++	.write = efivar_create,
++};
+ 
+-static struct subsys_attribute *var_subsys_attrs[] = {
+-	&var_subsys_attr_new_var,
+-	&var_subsys_attr_del_var,
+-	NULL,
++static struct bin_attribute var_subsys_attr_del_var = {
++	.attr = {.name = "del_var", .mode = 0200},
++	.write = efivar_delete,
+ };
+ 
+ /*
+  * Let's not leave out systab information that snuck into
+  * the efivars driver
+  */
+-static ssize_t
+-systab_read(struct kset *kset, char *buf)
++static ssize_t systab_show(struct kobject *kobj,
++			   struct kobj_attribute *attr, char *buf)
+ {
+ 	char *str = buf;
+ 
+-	if (!kset || !buf)
++	if (!kobj || !buf)
+ 		return -EINVAL;
+ 
+ 	if (efi.mps != EFI_INVALID_TABLE_ADDR)
+@@ -576,15 +559,21 @@ systab_read(struct kset *kset, char *buf)
+ 	return str - buf;
+ }
+ 
+-static EFI_ATTR(systab, 0400, systab_read, NULL);
++static struct kobj_attribute efi_attr_systab =
++			__ATTR(systab, 0400, systab_show, NULL);
+ 
+-static struct subsys_attribute *efi_subsys_attrs[] = {
+-	&efi_attr_systab,
++static struct attribute *efi_subsys_attrs[] = {
++	&efi_attr_systab.attr,
+ 	NULL,	/* maybe more in the future? */
+ };
+ 
+-static decl_subsys(vars, &efivar_ktype, NULL);
+-static decl_subsys(efi, NULL, NULL);
++static struct attribute_group efi_subsys_attr_group = {
++	.attrs = efi_subsys_attrs,
++};
 +
-+static int hifn_setkey(struct crypto_ablkcipher *cipher, const u8 *key,
-+		unsigned int len)
-+{
-+	struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
-+	struct hifn_context *ctx = crypto_tfm_ctx(tfm);
-+	struct hifn_device *dev = ctx->dev;
 +
-+	if (len > HIFN_MAX_CRYPT_KEY_LENGTH) {
-+		crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
-+		return -1;
++static struct kset *vars_kset;
++static struct kobject *efi_kobj;
+ 
+ /*
+  * efivar_create_sysfs_entry()
+@@ -628,15 +617,16 @@ efivar_create_sysfs_entry(unsigned long variable_name_size,
+ 	*(short_name + strlen(short_name)) = '-';
+ 	efi_guid_unparse(vendor_guid, short_name + strlen(short_name));
+ 
+-	kobject_set_name(&new_efivar->kobj, "%s", short_name);
+-	kobj_set_kset_s(new_efivar, vars_subsys);
+-	i = kobject_register(&new_efivar->kobj);
++	new_efivar->kobj.kset = vars_kset;
++	i = kobject_init_and_add(&new_efivar->kobj, &efivar_ktype, NULL,
++				 "%s", short_name);
+ 	if (i) {
+ 		kfree(short_name);
+ 		kfree(new_efivar);
+ 		return 1;
+ 	}
+ 
++	kobject_uevent(&new_efivar->kobj, KOBJ_ADD);
+ 	kfree(short_name);
+ 	short_name = NULL;
+ 
+@@ -660,9 +650,8 @@ efivars_init(void)
+ 	efi_status_t status = EFI_NOT_FOUND;
+ 	efi_guid_t vendor_guid;
+ 	efi_char16_t *variable_name;
+-	struct subsys_attribute *attr;
+ 	unsigned long variable_name_size = 1024;
+-	int i, error = 0;
++	int error = 0;
+ 
+ 	if (!efi_enabled)
+ 		return -ENODEV;
+@@ -676,23 +665,18 @@ efivars_init(void)
+ 	printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,
+ 	       EFIVARS_DATE);
+ 
+-	/*
+-	 * For now we'll register the efi subsys within this driver
+-	 */
+-
+-	error = firmware_register(&efi_subsys);
+-
+-	if (error) {
+-		printk(KERN_ERR "efivars: Firmware registration failed with error %d.\n", error);
++	/* For now we'll register the efi directory at /sys/firmware/efi */
++	efi_kobj = kobject_create_and_add("efi", firmware_kobj);
++	if (!efi_kobj) {
++		printk(KERN_ERR "efivars: Firmware registration failed.\n");
++		error = -ENOMEM;
+ 		goto out_free;
+ 	}
+ 
+-	kobj_set_kset_s(&vars_subsys, efi_subsys);
+-
+-	error = subsystem_register(&vars_subsys);
+-
+-	if (error) {
+-		printk(KERN_ERR "efivars: Subsystem registration failed with error %d.\n", error);
++	vars_kset = kset_create_and_add("vars", NULL, efi_kobj);
++	if (!vars_kset) {
++		printk(KERN_ERR "efivars: Subsystem registration failed.\n");
++		error = -ENOMEM;
+ 		goto out_firmware_unregister;
+ 	}
+ 
+@@ -727,28 +711,28 @@ efivars_init(void)
+ 	 * Now add attributes to allow creation of new vars
+ 	 * and deletion of existing ones...
+ 	 */
+-
+-	for (i = 0; (attr = var_subsys_attrs[i]) && !error; i++) {
+-		if (attr->show && attr->store)
+-			error = subsys_create_file(&vars_subsys, attr);
+-	}
++	error = sysfs_create_bin_file(&vars_kset->kobj,
++				      &var_subsys_attr_new_var);
++	if (error)
++		printk(KERN_ERR "efivars: unable to create new_var sysfs file"
++			" due to error %d\n", error);
++	error = sysfs_create_bin_file(&vars_kset->kobj,
++				      &var_subsys_attr_del_var);
++	if (error)
++		printk(KERN_ERR "efivars: unable to create del_var sysfs file"
++			" due to error %d\n", error);
+ 
+ 	/* Don't forget the systab entry */
+-
+-	for (i = 0; (attr = efi_subsys_attrs[i]) && !error; i++) {
+-		if (attr->show)
+-			error = subsys_create_file(&efi_subsys, attr);
+-	}
+-
++	error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
+ 	if (error)
+ 		printk(KERN_ERR "efivars: Sysfs attribute export failed with error %d.\n", error);
+ 	else
+ 		goto out_free;
+ 
+-	subsystem_unregister(&vars_subsys);
++	kset_unregister(vars_kset);
+ 
+ out_firmware_unregister:
+-	firmware_unregister(&efi_subsys);
++	kobject_put(efi_kobj);
+ 
+ out_free:
+ 	kfree(variable_name);
+@@ -768,8 +752,8 @@ efivars_exit(void)
+ 		efivar_unregister(entry);
+ 	}
+ 
+-	subsystem_unregister(&vars_subsys);
+-	firmware_unregister(&efi_subsys);
++	kset_unregister(vars_kset);
++	kobject_put(efi_kobj);
+ }
+ 
+ module_init(efivars_init);
+diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c
+index a37cb6b..3581282 100644
+--- a/drivers/i2c/algos/i2c-algo-bit.c
++++ b/drivers/i2c/algos/i2c-algo-bit.c
+@@ -1,7 +1,7 @@
+-/* ------------------------------------------------------------------------- */
+-/* i2c-algo-bit.c i2c driver algorithms for bit-shift adapters		     */
+-/* ------------------------------------------------------------------------- */
+-/*   Copyright (C) 1995-2000 Simon G. Vogl
++/* -------------------------------------------------------------------------
++ * i2c-algo-bit.c i2c driver algorithms for bit-shift adapters
++ * -------------------------------------------------------------------------
++ *   Copyright (C) 1995-2000 Simon G. Vogl
+ 
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+@@ -15,8 +15,8 @@
+ 
+     You should have received a copy of the GNU General Public License
+     along with this program; if not, write to the Free Software
+-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.		     */
+-/* ------------------------------------------------------------------------- */
++    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ * ------------------------------------------------------------------------- */
+ 
+ /* With some changes from Frodo Looijaard <frodol at dds.nl>, Kyösti Mälkki
+    <kmalkki at cc.hut.fi> and Jean Delvare <khali at linux-fr.org> */
+@@ -60,26 +60,26 @@ MODULE_PARM_DESC(i2c_debug,
+ 
+ /* --- setting states on the bus with the right timing: ---------------	*/
+ 
+-#define setsda(adap,val) adap->setsda(adap->data, val)
+-#define setscl(adap,val) adap->setscl(adap->data, val)
+-#define getsda(adap) adap->getsda(adap->data)
+-#define getscl(adap) adap->getscl(adap->data)
++#define setsda(adap, val)	adap->setsda(adap->data, val)
++#define setscl(adap, val)	adap->setscl(adap->data, val)
++#define getsda(adap)		adap->getsda(adap->data)
++#define getscl(adap)		adap->getscl(adap->data)
+ 
+ static inline void sdalo(struct i2c_algo_bit_data *adap)
+ {
+-	setsda(adap,0);
++	setsda(adap, 0);
+ 	udelay((adap->udelay + 1) / 2);
+ }
+ 
+ static inline void sdahi(struct i2c_algo_bit_data *adap)
+ {
+-	setsda(adap,1);
++	setsda(adap, 1);
+ 	udelay((adap->udelay + 1) / 2);
+ }
+ 
+ static inline void scllo(struct i2c_algo_bit_data *adap)
+ {
+-	setscl(adap,0);
++	setscl(adap, 0);
+ 	udelay(adap->udelay / 2);
+ }
+ 
+@@ -91,22 +91,21 @@ static int sclhi(struct i2c_algo_bit_data *adap)
+ {
+ 	unsigned long start;
+ 
+-	setscl(adap,1);
++	setscl(adap, 1);
+ 
+ 	/* Not all adapters have scl sense line... */
+ 	if (!adap->getscl)
+ 		goto done;
+ 
+-	start=jiffies;
+-	while (! getscl(adap) ) {	
+- 		/* the hw knows how to read the clock line,
+- 		 * so we wait until it actually gets high.
+- 		 * This is safer as some chips may hold it low
+- 		 * while they are processing data internally. 
+- 		 */
+-		if (time_after_eq(jiffies, start+adap->timeout)) {
++	start = jiffies;
++	while (!getscl(adap)) {
++		/* This hw knows how to read the clock line, so we wait
++		 * until it actually gets high.  This is safer as some
++		 * chips may hold it low ("clock stretching") while they
++		 * are processing data internally.
++		 */
++		if (time_after_eq(jiffies, start + adap->timeout))
+ 			return -ETIMEDOUT;
+-		}
+ 		cond_resched();
+ 	}
+ #ifdef DEBUG
+@@ -118,11 +117,11 @@ static int sclhi(struct i2c_algo_bit_data *adap)
+ done:
+ 	udelay(adap->udelay);
+ 	return 0;
+-} 
++}
+ 
+ 
+ /* --- other auxiliary functions --------------------------------------	*/
+-static void i2c_start(struct i2c_algo_bit_data *adap) 
++static void i2c_start(struct i2c_algo_bit_data *adap)
+ {
+ 	/* assert: scl, sda are high */
+ 	setsda(adap, 0);
+@@ -130,7 +129,7 @@ static void i2c_start(struct i2c_algo_bit_data *adap)
+ 	scllo(adap);
+ }
+ 
+-static void i2c_repstart(struct i2c_algo_bit_data *adap) 
++static void i2c_repstart(struct i2c_algo_bit_data *adap)
+ {
+ 	/* assert: scl is low */
+ 	sdahi(adap);
+@@ -141,18 +140,18 @@ static void i2c_repstart(struct i2c_algo_bit_data *adap)
+ }
+ 
+ 
+-static void i2c_stop(struct i2c_algo_bit_data *adap) 
++static void i2c_stop(struct i2c_algo_bit_data *adap)
+ {
+ 	/* assert: scl is low */
+ 	sdalo(adap);
+-	sclhi(adap); 
++	sclhi(adap);
+ 	setsda(adap, 1);
+ 	udelay(adap->udelay);
+ }
+ 
+ 
+ 
+-/* send a byte without start cond., look for arbitration, 
++/* send a byte without start cond., look for arbitration,
+    check ackn. from slave */
+ /* returns:
+  * 1 if the device acknowledged
+@@ -167,27 +166,33 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c)
+ 	struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
+ 
+ 	/* assert: scl is low */
+-	for ( i=7 ; i>=0 ; i-- ) {
++	for (i = 7; i >= 0; i--) {
+ 		sb = (c >> i) & 1;
+-		setsda(adap,sb);
++		setsda(adap, sb);
+ 		udelay((adap->udelay + 1) / 2);
+-		if (sclhi(adap)<0) { /* timed out */
++		if (sclhi(adap) < 0) { /* timed out */
+ 			bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, "
+ 				"timeout at bit #%d\n", (int)c, i);
+ 			return -ETIMEDOUT;
+-		};
+-		/* do arbitration here: 
+-		 * if ( sb && ! getsda(adap) ) -> ouch! Get out of here.
++		}
++		/* FIXME do arbitration here:
++		 * if (sb && !getsda(adap)) -> ouch! Get out of here.
++		 *
++		 * Report a unique code, so higher level code can retry
++		 * the whole (combined) message and *NOT* issue STOP.
+ 		 */
+ 		scllo(adap);
+ 	}
+ 	sdahi(adap);
+-	if (sclhi(adap)<0){ /* timeout */
++	if (sclhi(adap) < 0) { /* timeout */
+ 		bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, "
+ 			"timeout at ack\n", (int)c);
+ 		return -ETIMEDOUT;
+-	};
+-	/* read ack: SDA should be pulled down by slave */
 +	}
 +
-+	if (len == HIFN_DES_KEY_LENGTH) {
-+		u32 tmp[DES_EXPKEY_WORDS];
-+		int ret = des_ekey(tmp, key);
-+		
-+		if (unlikely(ret == 0) && (tfm->crt_flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
-+			tfm->crt_flags |= CRYPTO_TFM_RES_WEAK_KEY;
-+			return -EINVAL;
++	/* read ack: SDA should be pulled down by slave, or it may
++	 * NAK (usually to report problems with the data we wrote).
++	 */
+ 	ack = !getsda(adap);    /* ack: sda is pulled low -> success */
+ 	bit_dbg(2, &i2c_adap->dev, "i2c_outb: 0x%02x %s\n", (int)c,
+ 		ack ? "A" : "NA");
+@@ -198,24 +203,24 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c)
+ }
+ 
+ 
+-static int i2c_inb(struct i2c_adapter *i2c_adap) 
++static int i2c_inb(struct i2c_adapter *i2c_adap)
+ {
+ 	/* read byte via i2c port, without start/stop sequence	*/
+ 	/* acknowledge is sent in i2c_read.			*/
+ 	int i;
+-	unsigned char indata=0;
++	unsigned char indata = 0;
+ 	struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
+ 
+ 	/* assert: scl is low */
+ 	sdahi(adap);
+-	for (i=0;i<8;i++) {
+-		if (sclhi(adap)<0) { /* timeout */
++	for (i = 0; i < 8; i++) {
++		if (sclhi(adap) < 0) { /* timeout */
+ 			bit_dbg(1, &i2c_adap->dev, "i2c_inb: timeout at bit "
+ 				"#%d\n", 7 - i);
+ 			return -ETIMEDOUT;
+-		};
 +		}
-+	}
+ 		indata *= 2;
+-		if ( getsda(adap) ) 
++		if (getsda(adap))
+ 			indata |= 0x01;
+ 		setscl(adap, 0);
+ 		udelay(i == 7 ? adap->udelay / 2 : adap->udelay);
+@@ -228,66 +233,67 @@ static int i2c_inb(struct i2c_adapter *i2c_adap)
+  * Sanity check for the adapter hardware - check the reaction of
+  * the bus lines only if it seems to be idle.
+  */
+-static int test_bus(struct i2c_algo_bit_data *adap, char* name) {
+-	int scl,sda;
++static int test_bus(struct i2c_algo_bit_data *adap, char *name)
++{
++	int scl, sda;
+ 
+-	if (adap->getscl==NULL)
++	if (adap->getscl == NULL)
+ 		pr_info("%s: Testing SDA only, SCL is not readable\n", name);
+ 
+-	sda=getsda(adap);
+-	scl=(adap->getscl==NULL?1:getscl(adap));
+-	if (!scl || !sda ) {
++	sda = getsda(adap);
++	scl = (adap->getscl == NULL) ? 1 : getscl(adap);
++	if (!scl || !sda) {
+ 		printk(KERN_WARNING "%s: bus seems to be busy\n", name);
+ 		goto bailout;
+ 	}
+ 
+ 	sdalo(adap);
+-	sda=getsda(adap);
+-	scl=(adap->getscl==NULL?1:getscl(adap));
+-	if ( 0 != sda ) {
++	sda = getsda(adap);
++	scl = (adap->getscl == NULL) ? 1 : getscl(adap);
++	if (sda) {
+ 		printk(KERN_WARNING "%s: SDA stuck high!\n", name);
+ 		goto bailout;
+ 	}
+-	if ( 0 == scl ) {
++	if (!scl) {
+ 		printk(KERN_WARNING "%s: SCL unexpected low "
+ 		       "while pulling SDA low!\n", name);
+ 		goto bailout;
+-	}		
++	}
+ 
+ 	sdahi(adap);
+-	sda=getsda(adap);
+-	scl=(adap->getscl==NULL?1:getscl(adap));
+-	if ( 0 == sda ) {
++	sda = getsda(adap);
++	scl = (adap->getscl == NULL) ? 1 : getscl(adap);
++	if (!sda) {
+ 		printk(KERN_WARNING "%s: SDA stuck low!\n", name);
+ 		goto bailout;
+ 	}
+-	if ( 0 == scl ) {
++	if (!scl) {
+ 		printk(KERN_WARNING "%s: SCL unexpected low "
+ 		       "while pulling SDA high!\n", name);
+ 		goto bailout;
+ 	}
+ 
+ 	scllo(adap);
+-	sda=getsda(adap);
+-	scl=(adap->getscl==NULL?0:getscl(adap));
+-	if ( 0 != scl ) {
++	sda = getsda(adap);
++	scl = (adap->getscl == NULL) ? 0 : getscl(adap);
++	if (scl) {
+ 		printk(KERN_WARNING "%s: SCL stuck high!\n", name);
+ 		goto bailout;
+ 	}
+-	if ( 0 == sda ) {
++	if (!sda) {
+ 		printk(KERN_WARNING "%s: SDA unexpected low "
+ 		       "while pulling SCL low!\n", name);
+ 		goto bailout;
+ 	}
+-	
 +
-+	dev->flags &= ~HIFN_FLAG_OLD_KEY;
+ 	sclhi(adap);
+-	sda=getsda(adap);
+-	scl=(adap->getscl==NULL?1:getscl(adap));
+-	if ( 0 == scl ) {
++	sda = getsda(adap);
++	scl = (adap->getscl == NULL) ? 1 : getscl(adap);
++	if (!scl) {
+ 		printk(KERN_WARNING "%s: SCL stuck low!\n", name);
+ 		goto bailout;
+ 	}
+-	if ( 0 == sda ) {
++	if (!sda) {
+ 		printk(KERN_WARNING "%s: SDA unexpected low "
+ 		       "while pulling SCL high!\n", name);
+ 		goto bailout;
+@@ -314,9 +320,10 @@ static int try_address(struct i2c_adapter *i2c_adap,
+ 		       unsigned char addr, int retries)
+ {
+ 	struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
+-	int i,ret = -1;
+-	for (i=0;i<=retries;i++) {
+-		ret = i2c_outb(i2c_adap,addr);
++	int i, ret = -1;
++
++	for (i = 0; i <= retries; i++) {
++		ret = i2c_outb(i2c_adap, addr);
+ 		if (ret == 1 || i == retries)
+ 			break;
+ 		bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n");
+@@ -338,20 +345,38 @@ static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
+ {
+ 	const unsigned char *temp = msg->buf;
+ 	int count = msg->len;
+-	unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; 
++	unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK;
+ 	int retval;
+-	int wrcount=0;
++	int wrcount = 0;
+ 
+ 	while (count > 0) {
+ 		retval = i2c_outb(i2c_adap, *temp);
+-		if ((retval>0) || (nak_ok && (retval==0)))  { /* ok or ignored NAK */
+-			count--; 
++
++		/* OK/ACK; or ignored NAK */
++		if ((retval > 0) || (nak_ok && (retval == 0))) {
++			count--;
+ 			temp++;
+ 			wrcount++;
+-		} else { /* arbitration or no acknowledge */
+-			dev_err(&i2c_adap->dev, "sendbytes: error - bailout.\n");
+-			return (retval<0)? retval : -EFAULT;
+-			        /* got a better one ?? */
++
++		/* A slave NAKing the master means the slave didn't like
++		 * something about the data it saw.  For example, maybe
++		 * the SMBus PEC was wrong.
++		 */
++		} else if (retval == 0) {
++			dev_err(&i2c_adap->dev, "sendbytes: NAK bailout.\n");
++			return -EIO;
++
++		/* Timeout; or (someday) lost arbitration
++		 *
++		 * FIXME Lost ARB implies retrying the transaction from
++		 * the first message, after the "winning" master issues
++		 * its STOP.  As a rule, upper layer code has no reason
++		 * to know or care about this ... it is *NOT* an error.
++		 */
++		} else {
++			dev_err(&i2c_adap->dev, "sendbytes: error %d\n",
++					retval);
++			return retval;
+ 		}
+ 	}
+ 	return wrcount;
+@@ -376,14 +401,14 @@ static int acknak(struct i2c_adapter *i2c_adap, int is_ack)
+ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
+ {
+ 	int inval;
+-	int rdcount=0;   	/* counts bytes read */
++	int rdcount = 0;	/* counts bytes read */
+ 	unsigned char *temp = msg->buf;
+ 	int count = msg->len;
+ 	const unsigned flags = msg->flags;
+ 
+ 	while (count > 0) {
+ 		inval = i2c_inb(i2c_adap);
+-		if (inval>=0) {
++		if (inval >= 0) {
+ 			*temp = inval;
+ 			rdcount++;
+ 		} else {   /* read timed out */
+@@ -431,7 +456,7 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
+  * returns:
+  *  0 everything went okay, the chip ack'ed, or IGNORE_NAK flag was set
+  * -x an error occurred (like: -EREMOTEIO if the device did not answer, or
+- *	-ETIMEDOUT, for example if the lines are stuck...) 
++ *	-ETIMEDOUT, for example if the lines are stuck...)
+  */
+ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
+ {
+@@ -443,10 +468,10 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
+ 	int ret, retries;
+ 
+ 	retries = nak_ok ? 0 : i2c_adap->retries;
+-	
+-	if ( (flags & I2C_M_TEN)  ) { 
++
++	if (flags & I2C_M_TEN) {
+ 		/* a ten bit address */
+-		addr = 0xf0 | (( msg->addr >> 7) & 0x03);
++		addr = 0xf0 | ((msg->addr >> 7) & 0x03);
+ 		bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr);
+ 		/* try extended address code...*/
+ 		ret = try_address(i2c_adap, addr, retries);
+@@ -456,33 +481,33 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
+ 			return -EREMOTEIO;
+ 		}
+ 		/* the remaining 8 bit address */
+-		ret = i2c_outb(i2c_adap,msg->addr & 0x7f);
++		ret = i2c_outb(i2c_adap, msg->addr & 0x7f);
+ 		if ((ret != 1) && !nak_ok) {
+ 			/* the chip did not ack / xmission error occurred */
+ 			dev_err(&i2c_adap->dev, "died at 2nd address code\n");
+ 			return -EREMOTEIO;
+ 		}
+-		if ( flags & I2C_M_RD ) {
++		if (flags & I2C_M_RD) {
+ 			bit_dbg(3, &i2c_adap->dev, "emitting repeated "
+ 				"start condition\n");
+ 			i2c_repstart(adap);
+ 			/* okay, now switch into reading mode */
+ 			addr |= 0x01;
+ 			ret = try_address(i2c_adap, addr, retries);
+-			if ((ret!=1) && !nak_ok) {
++			if ((ret != 1) && !nak_ok) {
+ 				dev_err(&i2c_adap->dev,
+ 					"died at repeated address code\n");
+ 				return -EREMOTEIO;
+ 			}
+ 		}
+ 	} else {		/* normal 7bit address	*/
+-		addr = ( msg->addr << 1 );
+-		if (flags & I2C_M_RD )
++		addr = msg->addr << 1;
++		if (flags & I2C_M_RD)
+ 			addr |= 1;
+-		if (flags & I2C_M_REV_DIR_ADDR )
++		if (flags & I2C_M_REV_DIR_ADDR)
+ 			addr ^= 1;
+ 		ret = try_address(i2c_adap, addr, retries);
+-		if ((ret!=1) && !nak_ok)
++		if ((ret != 1) && !nak_ok)
+ 			return -EREMOTEIO;
+ 	}
+ 
+@@ -494,15 +519,14 @@ static int bit_xfer(struct i2c_adapter *i2c_adap,
+ {
+ 	struct i2c_msg *pmsg;
+ 	struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
+-	
+-	int i,ret;
++	int i, ret;
+ 	unsigned short nak_ok;
+ 
+ 	bit_dbg(3, &i2c_adap->dev, "emitting start condition\n");
+ 	i2c_start(adap);
+-	for (i=0;i<num;i++) {
++	for (i = 0; i < num; i++) {
+ 		pmsg = &msgs[i];
+-		nak_ok = pmsg->flags & I2C_M_IGNORE_NAK; 
++		nak_ok = pmsg->flags & I2C_M_IGNORE_NAK;
+ 		if (!(pmsg->flags & I2C_M_NOSTART)) {
+ 			if (i) {
+ 				bit_dbg(3, &i2c_adap->dev, "emitting "
+@@ -517,7 +541,7 @@ static int bit_xfer(struct i2c_adapter *i2c_adap,
+ 				goto bailout;
+ 			}
+ 		}
+-		if (pmsg->flags & I2C_M_RD ) {
++		if (pmsg->flags & I2C_M_RD) {
+ 			/* read bytes into buffer*/
+ 			ret = readbytes(i2c_adap, pmsg);
+ 			if (ret >= 1)
+@@ -551,7 +575,7 @@ bailout:
+ 
+ static u32 bit_func(struct i2c_adapter *adap)
+ {
+-	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | 
++	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
+ 	       I2C_FUNC_SMBUS_READ_BLOCK_DATA |
+ 	       I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
+ 	       I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING;
+@@ -565,8 +589,8 @@ static const struct i2c_algorithm i2c_bit_algo = {
+ 	.functionality	= bit_func,
+ };
+ 
+-/* 
+- * registering functions to load algorithms at runtime 
++/*
++ * registering functions to load algorithms at runtime
+  */
+ static int i2c_bit_prepare_bus(struct i2c_adapter *adap)
+ {
+@@ -574,7 +598,7 @@ static int i2c_bit_prepare_bus(struct i2c_adapter *adap)
+ 
+ 	if (bit_test) {
+ 		int ret = test_bus(bit_adap, adap->name);
+-		if (ret<0)
++		if (ret < 0)
+ 			return -ENODEV;
+ 	}
+ 
+diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c
+index ab2e6f3..8907b01 100644
+--- a/drivers/i2c/algos/i2c-algo-pcf.c
++++ b/drivers/i2c/algos/i2c-algo-pcf.c
+@@ -203,35 +203,6 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
+ /* ----- Utility functions
+  */
+ 
+-static inline int try_address(struct i2c_algo_pcf_data *adap,
+-		       unsigned char addr, int retries)
+-{
+-	int i, status, ret = -1;
+-	int wfp;
+-	for (i=0;i<retries;i++) {
+-		i2c_outb(adap, addr);
+-		i2c_start(adap);
+-		status = get_pcf(adap, 1);
+-		if ((wfp = wait_for_pin(adap, &status)) >= 0) {
+-			if ((status & I2C_PCF_LRB) == 0) { 
+-				i2c_stop(adap);
+-				break;	/* success! */
+-			}
+-		}
+-		if (wfp == -EINTR) {
+-			/* arbitration lost */
+-			udelay(adap->udelay);
+-			return -EINTR;
+-		}
+-		i2c_stop(adap);
+-		udelay(adap->udelay);
+-	}
+-	DEB2(if (i) printk(KERN_DEBUG "i2c-algo-pcf.o: needed %d retries for %d\n",i,
+-	                   addr));
+-	return ret;
+-}
+-
+-
+ static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf,
+                          int count, int last)
+ {
+@@ -321,47 +292,19 @@ static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf,
+ }
+ 
+ 
+-static inline int pcf_doAddress(struct i2c_algo_pcf_data *adap,
+-                                struct i2c_msg *msg, int retries) 
++static int pcf_doAddress(struct i2c_algo_pcf_data *adap,
++			 struct i2c_msg *msg)
+ {
+ 	unsigned short flags = msg->flags;
+ 	unsigned char addr;
+-	int ret;
+-	if ( (flags & I2C_M_TEN)  ) { 
+-		/* a ten bit address */
+-		addr = 0xf0 | (( msg->addr >> 7) & 0x03);
+-		DEB2(printk(KERN_DEBUG "addr0: %d\n",addr));
+-		/* try extended address code...*/
+-		ret = try_address(adap, addr, retries);
+-		if (ret!=1) {
+-			printk(KERN_ERR "died at extended address code.\n");
+-			return -EREMOTEIO;
+-		}
+-		/* the remaining 8 bit address */
+-		i2c_outb(adap,msg->addr & 0x7f);
+-/* Status check comes here */
+-		if (ret != 1) {
+-			printk(KERN_ERR "died at 2nd address code.\n");
+-			return -EREMOTEIO;
+-		}
+-		if ( flags & I2C_M_RD ) {
+-			i2c_repstart(adap);
+-			/* okay, now switch into reading mode */
+-			addr |= 0x01;
+-			ret = try_address(adap, addr, retries);
+-			if (ret!=1) {
+-				printk(KERN_ERR "died at extended address code.\n");
+-				return -EREMOTEIO;
+-			}
+-		}
+-	} else {		/* normal 7bit address	*/
+-		addr = ( msg->addr << 1 );
+-		if (flags & I2C_M_RD )
+-			addr |= 1;
+-		if (flags & I2C_M_REV_DIR_ADDR )
+-			addr ^= 1;
+-		i2c_outb(adap, addr);
+-	}
 +
-+	memcpy(ctx->key, key, len);
-+	ctx->keysize = len;
++	addr = msg->addr << 1;
++	if (flags & I2C_M_RD)
++		addr |= 1;
++	if (flags & I2C_M_REV_DIR_ADDR)
++		addr ^= 1;
++	i2c_outb(adap, addr);
 +
-+	return 0;
-+}
+ 	return 0;
+ }
+ 
+@@ -390,7 +333,7 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
+ 		     pmsg->flags & I2C_M_RD ? "read" : "write",
+                      pmsg->len, pmsg->addr, i + 1, num);)
+     
+-		ret = pcf_doAddress(adap, pmsg, i2c_adap->retries);
++		ret = pcf_doAddress(adap, pmsg);
+ 
+ 		/* Send START */
+ 		if (i == 0) {
+@@ -453,7 +396,7 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
+ static u32 pcf_func(struct i2c_adapter *adap)
+ {
+ 	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | 
+-	       I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; 
++	       I2C_FUNC_PROTOCOL_MANGLING;
+ }
+ 
+ /* -----exported algorithm data: -------------------------------------	*/
+@@ -475,9 +418,7 @@ int i2c_pcf_add_bus(struct i2c_adapter *adap)
+ 
+ 	/* register new adapter to i2c module... */
+ 	adap->algo = &pcf_algo;
+-
+-	adap->timeout = 100;		/* default values, should	*/
+-	adap->retries = 3;		/* be replaced by defines	*/
++	adap->timeout = 100;
+ 
+ 	if ((rval = pcf_init_8584(pcf_adap)))
+ 		return rval;
+diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
+index c466c6c..8d12b26 100644
+--- a/drivers/i2c/busses/Kconfig
++++ b/drivers/i2c/busses/Kconfig
+@@ -182,7 +182,8 @@ config I2C_I801
+ 	  will be called i2c-i801.
+ 
+ config I2C_I810
+-	tristate "Intel 810/815"
++	tristate "Intel 810/815 (DEPRECATED)"
++	default n
+ 	depends on PCI
+ 	select I2C_ALGOBIT
+ 	help
+@@ -195,6 +196,8 @@ config I2C_I810
+ 	    i815
+ 	    i845G
+ 
++	  This driver is deprecated in favor of the i810fb and intelfb drivers.
++
+ 	  This driver can also be built as a module.  If so, the module
+ 	  will be called i2c-i810.
+ 
+@@ -259,20 +262,6 @@ config I2C_IOP3XX
+ 	  This driver can also be built as a module.  If so, the module
+ 	  will be called i2c-iop3xx.
+ 
+-config I2C_IXP4XX
+-	tristate "IXP4xx GPIO-Based I2C Interface (DEPRECATED)"
+-	depends on ARCH_IXP4XX
+-	select I2C_ALGOBIT
+-	help
+-	  Say Y here if you have an Intel IXP4xx(420,421,422,425) based 
+-	  system and are using GPIO lines for an I2C bus.
+-
+-	  This support is also available as a module. If so, the module
+-	  will be called i2c-ixp4xx.
+-
+-	  This driver is deprecated and will be dropped soon. Use i2c-gpio
+-	  instead.
+-
+ config I2C_IXP2000
+ 	tristate "IXP2000 GPIO-Based I2C Interface (DEPRECATED)"
+ 	depends on ARCH_IXP2000
+@@ -396,7 +385,8 @@ config I2C_PASEMI
+ 	  Supports the PA Semi PWRficient on-chip SMBus interfaces.
+ 
+ config I2C_PROSAVAGE
+-	tristate "S3/VIA (Pro)Savage"
++	tristate "S3/VIA (Pro)Savage (DEPRECATED)"
++	default n
+ 	depends on PCI
+ 	select I2C_ALGOBIT
+ 	help
+@@ -407,6 +397,8 @@ config I2C_PROSAVAGE
+ 	    S3/VIA KM266/VT8375 aka ProSavage8
+ 	    S3/VIA KM133/VT8365 aka Savage4
+ 
++	  This driver is deprecated in favor of the savagefb driver.
++
+ 	  This support is also available as a module.  If so, the module 
+ 	  will be called i2c-prosavage.
+ 
+@@ -418,13 +410,16 @@ config I2C_S3C2410
+ 	  Samsung S3C2410 based System-on-Chip devices.
+ 
+ config I2C_SAVAGE4
+-	tristate "S3 Savage 4"
+-	depends on PCI && EXPERIMENTAL
++	tristate "S3 Savage 4 (DEPRECATED)"
++	default n
++	depends on PCI
+ 	select I2C_ALGOBIT
+ 	help
+ 	  If you say yes to this option, support will be included for the 
+ 	  S3 Savage 4 I2C interface.
+ 
++	  This driver is deprecated in favor of the savagefb driver.
 +
-+static int hifn_handle_req(struct ablkcipher_request *req)
-+{
-+	struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm);
-+	struct hifn_device *dev = ctx->dev;
-+	int err = -EAGAIN;
+ 	  This driver can also be built as a module.  If so, the module
+ 	  will be called i2c-savage4.
+ 
+@@ -611,7 +606,7 @@ config I2C_VIAPRO
+ 	    VT8231
+ 	    VT8233/A
+ 	    VT8235
+-	    VT8237R/A
++	    VT8237R/A/S
+ 	    VT8251
+ 	    CX700
+ 
+diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
+index 81d43c2..ea7068f 100644
+--- a/drivers/i2c/busses/Makefile
++++ b/drivers/i2c/busses/Makefile
+@@ -20,7 +20,6 @@ obj-$(CONFIG_I2C_I810)		+= i2c-i810.o
+ obj-$(CONFIG_I2C_IBM_IIC)	+= i2c-ibm_iic.o
+ obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
+ obj-$(CONFIG_I2C_IXP2000)	+= i2c-ixp2000.o
+-obj-$(CONFIG_I2C_IXP4XX)	+= i2c-ixp4xx.o
+ obj-$(CONFIG_I2C_POWERMAC)	+= i2c-powermac.o
+ obj-$(CONFIG_I2C_MPC)		+= i2c-mpc.o
+ obj-$(CONFIG_I2C_MV64XXX)	+= i2c-mv64xxx.o
+diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
+index 7490dc1..573abe4 100644
+--- a/drivers/i2c/busses/i2c-amd756.c
++++ b/drivers/i2c/busses/i2c-amd756.c
+@@ -334,6 +334,10 @@ static int __devinit amd756_probe(struct pci_dev *pdev,
+ 	int error;
+ 	u8 temp;
+ 	
++	/* driver_data might come from user-space, so check it */
++	if (id->driver_data > ARRAY_SIZE(chipname))
++		return -EINVAL;
 +
-+	if (dev->started + DIV_ROUND_UP(req->nbytes, PAGE_SIZE) <= HIFN_QUEUE_LENGTH)
-+		err = hifn_setup_session(req);
+ 	if (amd756_ioport) {
+ 		dev_err(&pdev->dev, "Only one device supported "
+ 		       "(you have a strange motherboard, btw)\n");
+@@ -405,6 +409,7 @@ static struct pci_driver amd756_driver = {
+ 	.id_table	= amd756_ids,
+ 	.probe		= amd756_probe,
+ 	.remove		= __devexit_p(amd756_remove),
++	.dynids.use_driver_data = 1,
+ };
+ 
+ static int __init amd756_init(void)
+diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c
+index 2f68416..1953b26 100644
+--- a/drivers/i2c/busses/i2c-au1550.c
++++ b/drivers/i2c/busses/i2c-au1550.c
+@@ -30,14 +30,22 @@
+ #include <linux/delay.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
++#include <linux/platform_device.h>
+ #include <linux/init.h>
+ #include <linux/errno.h>
+ #include <linux/i2c.h>
++#include <linux/slab.h>
+ 
+ #include <asm/mach-au1x00/au1xxx.h>
+ #include <asm/mach-au1x00/au1xxx_psc.h>
+ 
+-#include "i2c-au1550.h"
++struct i2c_au1550_data {
++	u32	psc_base;
++	int	xfer_timeout;
++	int	ack_timeout;
++	struct i2c_adapter adap;
++	struct resource *ioarea;
++};
+ 
+ static int
+ wait_xfer_done(struct i2c_au1550_data *adap)
+@@ -105,7 +113,7 @@ wait_master_done(struct i2c_au1550_data *adap)
+ }
+ 
+ static int
+-do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd)
++do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd, int q)
+ {
+ 	volatile psc_smb_t	*sp;
+ 	u32			stat;
+@@ -134,6 +142,10 @@ do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd)
+ 	if (rd)
+ 		addr |= 1;
+ 
++	/* zero-byte xfers stop immediately */
++	if (q)
++		addr |= PSC_SMBTXRX_STP;
 +
-+	if (err == -EAGAIN) {
-+		unsigned long flags;
+ 	/* Put byte into fifo, start up master.
+ 	*/
+ 	sp->psc_smbtxrx = addr;
+@@ -142,7 +154,7 @@ do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd)
+ 	au_sync();
+ 	if (wait_ack(adap))
+ 		return -EIO;
+-	return 0;
++	return (q) ? wait_master_done(adap) : 0;
+ }
+ 
+ static u32
+@@ -262,7 +274,8 @@ au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
+ 
+ 	for (i = 0; !err && i < num; i++) {
+ 		p = &msgs[i];
+-		err = do_address(adap, p->addr, p->flags & I2C_M_RD);
++		err = do_address(adap, p->addr, p->flags & I2C_M_RD,
++				 (p->len == 0));
+ 		if (err || !p->len)
+ 			continue;
+ 		if (p->flags & I2C_M_RD)
+@@ -294,18 +307,48 @@ static const struct i2c_algorithm au1550_algo = {
+  * Prior to calling us, the 50MHz clock frequency and routing
+  * must have been set up for the PSC indicated by the adapter.
+  */
+-int
+-i2c_au1550_add_bus(struct i2c_adapter *i2c_adap)
++static int __devinit
++i2c_au1550_probe(struct platform_device *pdev)
+ {
+-	struct i2c_au1550_data *adap = i2c_adap->algo_data;
+-	volatile psc_smb_t	*sp;
+-	u32	stat;
++	struct i2c_au1550_data *priv;
++	volatile psc_smb_t *sp;
++	struct resource *r;
++	u32 stat;
++	int ret;
 +
-+		spin_lock_irqsave(&dev->lock, flags);
-+		err = ablkcipher_enqueue_request(&dev->queue, req);
-+		spin_unlock_irqrestore(&dev->lock, flags);
++	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!r) {
++		ret = -ENODEV;
++		goto out;
 +	}
 +
-+	return err;
-+}
-+
-+static int hifn_setup_crypto_req(struct ablkcipher_request *req, u8 op,
-+		u8 type, u8 mode)
-+{
-+	struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm);
-+	unsigned ivsize;
-+
-+	ivsize = crypto_ablkcipher_ivsize(crypto_ablkcipher_reqtfm(req));
-+
-+	if (req->info && mode != ACRYPTO_MODE_ECB) {
-+		if (type == ACRYPTO_TYPE_AES_128)
-+			ivsize = HIFN_AES_IV_LENGTH;
-+		else if (type == ACRYPTO_TYPE_DES)
-+			ivsize = HIFN_DES_KEY_LENGTH;
-+		else if (type == ACRYPTO_TYPE_3DES)
-+			ivsize = HIFN_3DES_KEY_LENGTH;
++	priv = kzalloc(sizeof(struct i2c_au1550_data), GFP_KERNEL);
++	if (!priv) {
++		ret = -ENOMEM;
++		goto out;
 +	}
 +
-+	if (ctx->keysize != 16 && type == ACRYPTO_TYPE_AES_128) {
-+		if (ctx->keysize == 24)
-+			type = ACRYPTO_TYPE_AES_192;
-+		else if (ctx->keysize == 32)
-+			type = ACRYPTO_TYPE_AES_256;
++	priv->ioarea = request_mem_region(r->start, r->end - r->start + 1,
++					  pdev->name);
++	if (!priv->ioarea) {
++		ret = -EBUSY;
++		goto out_mem;
 +	}
-+
-+	ctx->op = op;
-+	ctx->mode = mode;
-+	ctx->type = type;
-+	ctx->iv = req->info;
-+	ctx->ivsize = ivsize;
-+
-+	/*
-+	 * HEAVY TODO: needs to kick Herbert XU to write documentation.
-+	 * HEAVY TODO: needs to kick Herbert XU to write documentation.
-+	 * HEAVY TODO: needs to kick Herbert XU to write documentation.
-+	 */
-+
-+	return hifn_handle_req(req);
-+}
-+
-+static int hifn_process_queue(struct hifn_device *dev)
-+{
-+	struct crypto_async_request *async_req;
-+	struct hifn_context *ctx;
-+	struct ablkcipher_request *req;
-+	unsigned long flags;
-+	int err = 0;
-+
-+	while (dev->started < HIFN_QUEUE_LENGTH) {
-+		spin_lock_irqsave(&dev->lock, flags);
-+		async_req = crypto_dequeue_request(&dev->queue);
-+		spin_unlock_irqrestore(&dev->lock, flags);
-+
-+		if (!async_req)
-+			break;
-+
-+		ctx = crypto_tfm_ctx(async_req->tfm);
-+		req = container_of(async_req, struct ablkcipher_request, base);
-+
-+		err = hifn_handle_req(req);
-+		if (err)
-+			break;
+ 
+-	i2c_adap->algo = &au1550_algo;
++	priv->psc_base = r->start;
++	priv->xfer_timeout = 200;
++	priv->ack_timeout = 200;
++
++	priv->adap.id = I2C_HW_AU1550_PSC;
++	priv->adap.nr = pdev->id;
++	priv->adap.algo = &au1550_algo;
++	priv->adap.algo_data = priv;
++	priv->adap.dev.parent = &pdev->dev;
++	strlcpy(priv->adap.name, "Au1xxx PSC I2C", sizeof(priv->adap.name));
+ 
+ 	/* Now, set up the PSC for SMBus PIO mode.
+ 	*/
+-	sp = (volatile psc_smb_t *)(adap->psc_base);
++	sp = (volatile psc_smb_t *)priv->psc_base;
+ 	sp->psc_ctrl = PSC_CTRL_DISABLE;
+ 	au_sync();
+ 	sp->psc_sel = PSC_SEL_PS_SMBUSMODE;
+@@ -343,87 +386,87 @@ i2c_au1550_add_bus(struct i2c_adapter *i2c_adap)
+ 		au_sync();
+ 	} while ((stat & PSC_SMBSTAT_DR) == 0);
+ 
+-	return i2c_add_adapter(i2c_adap);
+-}
++	ret = i2c_add_numbered_adapter(&priv->adap);
++	if (ret == 0) {
++		platform_set_drvdata(pdev, priv);
++		return 0;
 +	}
-+
-+	return err;
+ 
++	/* disable the PSC */
++	sp->psc_smbcfg = 0;
++	sp->psc_ctrl = PSC_CTRL_DISABLE;
++	au_sync();
+ 
+-int
+-i2c_au1550_del_bus(struct i2c_adapter *adap)
++	release_resource(priv->ioarea);
++	kfree(priv->ioarea);
++out_mem:
++	kfree(priv);
++out:
++	return ret;
 +}
 +
-+static int hifn_setup_crypto(struct ablkcipher_request *req, u8 op,
-+		u8 type, u8 mode)
-+{
-+	int err;
-+	struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm);
-+	struct hifn_device *dev = ctx->dev;
-+
-+	err = hifn_setup_crypto_req(req, op, type, mode);
-+	if (err)
-+		return err;
++static int __devexit
++i2c_au1550_remove(struct platform_device *pdev)
+ {
+-	return i2c_del_adapter(adap);
++	struct i2c_au1550_data *priv = platform_get_drvdata(pdev);
++	volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base;
++
++	platform_set_drvdata(pdev, NULL);
++	i2c_del_adapter(&priv->adap);
++	sp->psc_smbcfg = 0;
++	sp->psc_ctrl = PSC_CTRL_DISABLE;
++	au_sync();
++	release_resource(priv->ioarea);
++	kfree(priv->ioarea);
++	kfree(priv);
++	return 0;
+ }
+ 
+ static int
+-pb1550_reg(struct i2c_client *client)
++i2c_au1550_suspend(struct platform_device *pdev, pm_message_t state)
+ {
++	struct i2c_au1550_data *priv = platform_get_drvdata(pdev);
++	volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base;
 +
-+	if (dev->started < HIFN_QUEUE_LENGTH &&	dev->queue.qlen)
-+		err = hifn_process_queue(dev);
++	sp->psc_ctrl = PSC_CTRL_SUSPEND;
++	au_sync();
+ 	return 0;
+ }
+ 
+ static int
+-pb1550_unreg(struct i2c_client *client)
++i2c_au1550_resume(struct platform_device *pdev)
+ {
++	struct i2c_au1550_data *priv = platform_get_drvdata(pdev);
++	volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base;
 +
-+	return err;
-+}
++	sp->psc_ctrl = PSC_CTRL_ENABLE;
++	au_sync();
++	while (!(sp->psc_smbstat & PSC_SMBSTAT_SR))
++		au_sync();
+ 	return 0;
+ }
+ 
+-static struct i2c_au1550_data pb1550_i2c_info = {
+-	SMBUS_PSC_BASE, 200, 200
+-};
+-
+-static struct i2c_adapter pb1550_board_adapter = {
+-	name:              "pb1550 adapter",
+-	id:                I2C_HW_AU1550_PSC,
+-	algo:              NULL,
+-	algo_data:         &pb1550_i2c_info,
+-	client_register:   pb1550_reg,
+-	client_unregister: pb1550_unreg,
++static struct platform_driver au1xpsc_smbus_driver = {
++	.driver = {
++		.name	= "au1xpsc_smbus",
++		.owner	= THIS_MODULE,
++	},
++	.probe		= i2c_au1550_probe,
++	.remove		= __devexit_p(i2c_au1550_remove),
++	.suspend	= i2c_au1550_suspend,
++	.resume		= i2c_au1550_resume,
+ };
+ 
+-/* BIG hack to support the control interface on the Wolfson WM8731
+- * audio codec on the Pb1550 board.  We get an address and two data
+- * bytes to write, create an i2c message, and send it across the
+- * i2c transfer function.  We do this here because we have access to
+- * the i2c adapter structure.
+- */
+-static struct i2c_msg wm_i2c_msg;  /* We don't want this stuff on the stack */
+-static	u8 i2cbuf[2];
+-
+-int
+-pb1550_wm_codec_write(u8 addr, u8 reg, u8 val)
+-{
+-	wm_i2c_msg.addr = addr;
+-	wm_i2c_msg.flags = 0;
+-	wm_i2c_msg.buf = i2cbuf;
+-	wm_i2c_msg.len = 2;
+-	i2cbuf[0] = reg;
+-	i2cbuf[1] = val;
+-
+-	return pb1550_board_adapter.algo->master_xfer(&pb1550_board_adapter, &wm_i2c_msg, 1);
+-}
+-
+ static int __init
+ i2c_au1550_init(void)
+ {
+-	printk(KERN_INFO "Au1550 I2C: ");
+-
+-	/* This is where we would set up a 50MHz clock source
+-	 * and routing.  On the Pb1550, the SMBus is PSC2, which
+-	 * uses a shared clock with USB.  This has been already
+-	 * configured by Yamon as a 48MHz clock, close enough
+-	 * for our work.
+-	 */
+-        if (i2c_au1550_add_bus(&pb1550_board_adapter) < 0) {
+-		printk("failed to initialize.\n");
+-                return -ENODEV;
+-	}
+-
+-	printk("initialized.\n");
+-	return 0;
++	return platform_driver_register(&au1xpsc_smbus_driver);
+ }
+ 
+ static void __exit
+ i2c_au1550_exit(void)
+ {
+-	i2c_au1550_del_bus(&pb1550_board_adapter);
++	platform_driver_unregister(&au1xpsc_smbus_driver);
+ }
+ 
+ MODULE_AUTHOR("Dan Malek, Embedded Edge, LLC.");
+diff --git a/drivers/i2c/busses/i2c-au1550.h b/drivers/i2c/busses/i2c-au1550.h
+deleted file mode 100644
+index fce15d1..0000000
+--- a/drivers/i2c/busses/i2c-au1550.h
++++ /dev/null
+@@ -1,32 +0,0 @@
+-/*
+- * Copyright (C) 2004 Embedded Edge, LLC <dan at embeddededge.com>
+- * 2.6 port by Matt Porter <mporter at kernel.crashing.org>
+- *
+- *  This program is free software; you can redistribute it and/or modify
+- *  it under the terms of the GNU General Public License as published by
+- *  the Free Software Foundation; either version 2 of the License, or
+- *  (at your option) any later version.
+- *
+- *  This program is distributed in the hope that it will be useful,
+- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- *  GNU General Public License for more details.
+- *
+- *  You should have received a copy of the GNU General Public License
+- *  along with this program; if not, write to the Free Software
+- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+- */
+-
+-#ifndef I2C_AU1550_H
+-#define I2C_AU1550_H
+-
+-struct i2c_au1550_data {
+-	u32	psc_base;
+-	int	xfer_timeout;
+-	int	ack_timeout;
+-};
+-
+-int i2c_au1550_add_bus(struct i2c_adapter *);
+-int i2c_au1550_del_bus(struct i2c_adapter *);
+-
+-#endif /* I2C_AU1550_H */
+diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c
+index 67224a4..7dbdaeb 100644
+--- a/drivers/i2c/busses/i2c-bfin-twi.c
++++ b/drivers/i2c/busses/i2c-bfin-twi.c
+@@ -550,6 +550,7 @@ static int i2c_bfin_twi_probe(struct platform_device *dev)
+ 
+ 	p_adap = &iface->adap;
+ 	p_adap->id = I2C_HW_BLACKFIN;
++	p_adap->nr = dev->id;
+ 	strlcpy(p_adap->name, dev->name, sizeof(p_adap->name));
+ 	p_adap->algo = &bfin_twi_algorithm;
+ 	p_adap->algo_data = iface;
+@@ -576,7 +577,7 @@ static int i2c_bfin_twi_probe(struct platform_device *dev)
+ 	bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA);
+ 	SSYNC();
+ 
+-	rc = i2c_add_adapter(p_adap);
++	rc = i2c_add_numbered_adapter(p_adap);
+ 	if (rc < 0)
+ 		free_irq(iface->irq, iface);
+ 	else
+diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
+index 6767988..cce5a61 100644
+--- a/drivers/i2c/busses/i2c-davinci.c
++++ b/drivers/i2c/busses/i2c-davinci.c
+@@ -510,7 +510,6 @@ static int davinci_i2c_probe(struct platform_device *pdev)
+ 
+ 	/* FIXME */
+ 	adap->timeout = 1;
+-	adap->retries = 1;
+ 
+ 	adap->nr = pdev->id;
+ 	r = i2c_add_numbered_adapter(adap);
+diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
+index ac27e5f..aa91579 100644
+--- a/drivers/i2c/busses/i2c-i801.c
++++ b/drivers/i2c/busses/i2c-i801.c
+@@ -4,6 +4,7 @@
+     Copyright (c) 1998 - 2002  Frodo Looijaard <frodol at dds.nl>,
+     Philip Edelbrock <phil at netroedge.com>, and Mark D. Studebaker
+     <mdsxyz123 at yahoo.com>
++    Copyright (C) 2007         Jean Delvare <khali at linux-fr.org>
+ 
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+@@ -21,25 +22,34 @@
+ */
+ 
+ /*
+-    SUPPORTED DEVICES	PCI ID
+-    82801AA		2413
+-    82801AB		2423
+-    82801BA		2443
+-    82801CA/CAM		2483
+-    82801DB		24C3   (HW PEC supported)
+-    82801EB		24D3   (HW PEC supported)
+-    6300ESB		25A4
+-    ICH6		266A
+-    ICH7		27DA
+-    ESB2		269B
+-    ICH8		283E
+-    ICH9		2930
+-    Tolapai		5032
+-    This driver supports several versions of Intel's I/O Controller Hubs (ICH).
+-    For SMBus support, they are similar to the PIIX4 and are part
+-    of Intel's '810' and other chipsets.
+-    See the file Documentation/i2c/busses/i2c-i801 for details.
+-    I2C Block Read and Process Call are not supported.
++  Supports the following Intel I/O Controller Hubs (ICH):
++
++                                  I/O                     Block   I2C
++                                  region  SMBus   Block   proc.   block
++  Chip name             PCI ID    size    PEC     buffer  call    read
++  ----------------------------------------------------------------------
++  82801AA  (ICH)        0x2413     16      no      no      no      no
++  82801AB  (ICH0)       0x2423     16      no      no      no      no
++  82801BA  (ICH2)       0x2443     16      no      no      no      no
++  82801CA  (ICH3)       0x2483     32     soft     no      no      no
++  82801DB  (ICH4)       0x24c3     32     hard     yes     no      no
++  82801E   (ICH5)       0x24d3     32     hard     yes     yes     yes
++  6300ESB               0x25a4     32     hard     yes     yes     yes
++  82801F   (ICH6)       0x266a     32     hard     yes     yes     yes
++  6310ESB/6320ESB       0x269b     32     hard     yes     yes     yes
++  82801G   (ICH7)       0x27da     32     hard     yes     yes     yes
++  82801H   (ICH8)       0x283e     32     hard     yes     yes     yes
++  82801I   (ICH9)       0x2930     32     hard     yes     yes     yes
++  Tolapai               0x5032     32     hard     yes     ?       ?
++
++  Features supported by this driver:
++  Software PEC                     no
++  Hardware PEC                     yes
++  Block buffer                     yes
++  Block process call transaction   no
++  I2C block read transaction       yes  (doesn't use the block buffer)
 +
-+/*
-+ * AES ecryption functions.
-+ */
-+static inline int hifn_encrypt_aes_ecb(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
-+			ACRYPTO_TYPE_AES_128, ACRYPTO_MODE_ECB);
-+}
-+static inline int hifn_encrypt_aes_cbc(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
-+			ACRYPTO_TYPE_AES_128, ACRYPTO_MODE_CBC);
-+}
-+static inline int hifn_encrypt_aes_cfb(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
-+			ACRYPTO_TYPE_AES_128, ACRYPTO_MODE_CFB);
-+}
-+static inline int hifn_encrypt_aes_ofb(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
-+			ACRYPTO_TYPE_AES_128, ACRYPTO_MODE_OFB);
-+}
++  See the file Documentation/i2c/busses/i2c-i801 for details.
+ */
+ 
+ /* Note: we assume there can only be one I801, with one SMBus interface */
+@@ -62,9 +72,9 @@
+ #define SMBHSTDAT0	(5 + i801_smba)
+ #define SMBHSTDAT1	(6 + i801_smba)
+ #define SMBBLKDAT	(7 + i801_smba)
+-#define SMBPEC		(8 + i801_smba)	/* ICH4 only */
+-#define SMBAUXSTS	(12 + i801_smba)	/* ICH4 only */
+-#define SMBAUXCTL	(13 + i801_smba)	/* ICH4 only */
++#define SMBPEC		(8 + i801_smba)		/* ICH3 and later */
++#define SMBAUXSTS	(12 + i801_smba)	/* ICH4 and later */
++#define SMBAUXCTL	(13 + i801_smba)	/* ICH4 and later */
+ 
+ /* PCI Address Constants */
+ #define SMBBAR		4
+@@ -91,13 +101,13 @@
+ #define I801_BYTE		0x04
+ #define I801_BYTE_DATA		0x08
+ #define I801_WORD_DATA		0x0C
+-#define I801_PROC_CALL		0x10	/* later chips only, unimplemented */
++#define I801_PROC_CALL		0x10	/* unimplemented */
+ #define I801_BLOCK_DATA		0x14
+-#define I801_I2C_BLOCK_DATA	0x18	/* unimplemented */
++#define I801_I2C_BLOCK_DATA	0x18	/* ICH5 and later */
+ #define I801_BLOCK_LAST		0x34
+-#define I801_I2C_BLOCK_LAST	0x38	/* unimplemented */
++#define I801_I2C_BLOCK_LAST	0x38	/* ICH5 and later */
+ #define I801_START		0x40
+-#define I801_PEC_EN		0x80	/* ICH4 only */
++#define I801_PEC_EN		0x80	/* ICH3 and later */
+ 
+ /* I801 Hosts Status register bits */
+ #define SMBHSTSTS_BYTE_DONE	0x80
+@@ -113,7 +123,12 @@ 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;
++
++#define FEATURE_SMBUS_PEC	(1 << 0)
++#define FEATURE_BLOCK_BUFFER	(1 << 1)
++#define FEATURE_BLOCK_PROC	(1 << 2)
++#define FEATURE_I2C_BLOCK_READ	(1 << 3)
++static unsigned int i801_features;
+ 
+ static int i801_transaction(int xact)
+ {
+@@ -242,7 +257,8 @@ static int i801_block_transaction_by_block(union i2c_smbus_data *data,
+ }
+ 
+ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
+-					       char read_write, int hwpec)
++					       char read_write, int command,
++					       int hwpec)
+ {
+ 	int i, len;
+ 	int smbcmd;
+@@ -259,16 +275,24 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
+ 	}
+ 
+ 	for (i = 1; i <= len; i++) {
+-		if (i == len && read_write == I2C_SMBUS_READ)
+-			smbcmd = I801_BLOCK_LAST;
+-		else
+-			smbcmd = I801_BLOCK_DATA;
++		if (i == len && read_write == I2C_SMBUS_READ) {
++			if (command == I2C_SMBUS_I2C_BLOCK_DATA)
++				smbcmd = I801_I2C_BLOCK_LAST;
++			else
++				smbcmd = I801_BLOCK_LAST;
++		} else {
++			if (command == I2C_SMBUS_I2C_BLOCK_DATA
++			 && read_write == I2C_SMBUS_READ)
++				smbcmd = I801_I2C_BLOCK_DATA;
++			else
++				smbcmd = I801_BLOCK_DATA;
++		}
+ 		outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT);
+ 
+ 		dev_dbg(&I801_dev->dev, "Block (pre %d): CNT=%02x, CMD=%02x, "
+-			"ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i,
++			"ADD=%02x, DAT0=%02x, DAT1=%02x, BLKDAT=%02x\n", i,
+ 			inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
+-			inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT));
++			inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1), inb_p(SMBBLKDAT));
+ 
+ 		/* Make sure the SMBus host is ready to start transmitting */
+ 		temp = inb_p(SMBHSTSTS);
+@@ -332,7 +356,8 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
+ 			dev_dbg(&I801_dev->dev, "Error: no response!\n");
+ 		}
+ 
+-		if (i == 1 && read_write == I2C_SMBUS_READ) {
++		if (i == 1 && read_write == I2C_SMBUS_READ
++		 && command != I2C_SMBUS_I2C_BLOCK_DATA) {
+ 			len = inb_p(SMBHSTDAT0);
+ 			if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
+ 				return -1;
+@@ -353,9 +378,9 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
+ 				temp);
+ 		}
+ 		dev_dbg(&I801_dev->dev, "Block (post %d): CNT=%02x, CMD=%02x, "
+-			"ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i,
++			"ADD=%02x, DAT0=%02x, DAT1=%02x, BLKDAT=%02x\n", i,
+ 			inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
+-			inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT));
++			inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1), inb_p(SMBBLKDAT));
+ 
+ 		if (result < 0)
+ 			return result;
+@@ -384,33 +409,38 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
+ 			pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc);
+ 			pci_write_config_byte(I801_dev, SMBHSTCFG,
+ 					      hostc | SMBHSTCFG_I2C_EN);
+-		} else {
++		} else if (!(i801_features & FEATURE_I2C_BLOCK_READ)) {
+ 			dev_err(&I801_dev->dev,
+-				"I2C_SMBUS_I2C_BLOCK_READ not DB!\n");
++				"I2C block read is unsupported!\n");
+ 			return -1;
+ 		}
+ 	}
+ 
+-	if (read_write == I2C_SMBUS_WRITE) {
++	if (read_write == I2C_SMBUS_WRITE
++	 || command == I2C_SMBUS_I2C_BLOCK_DATA) {
+ 		if (data->block[0] < 1)
+ 			data->block[0] = 1;
+ 		if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
+ 			data->block[0] = I2C_SMBUS_BLOCK_MAX;
+ 	} else {
+-		data->block[0] = 32;	/* max for reads */
++		data->block[0] = 32;	/* max for SMBus block reads */
+ 	}
+ 
+-	if (isich4 && i801_set_block_buffer_mode() == 0 )
++	if ((i801_features & FEATURE_BLOCK_BUFFER)
++	 && !(command == I2C_SMBUS_I2C_BLOCK_DATA
++	      && read_write == I2C_SMBUS_READ)
++	 && i801_set_block_buffer_mode() == 0)
+ 		result = i801_block_transaction_by_block(data, read_write,
+ 							 hwpec);
+ 	else
+ 		result = i801_block_transaction_byte_by_byte(data, read_write,
+-							     hwpec);
++							     command, hwpec);
+ 
+ 	if (result == 0 && hwpec)
+ 		i801_wait_hwpec();
+ 
+-	if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
++	if (command == I2C_SMBUS_I2C_BLOCK_DATA
++	 && read_write == I2C_SMBUS_WRITE) {
+ 		/* restore saved configuration register value */
+ 		pci_write_config_byte(I801_dev, SMBHSTCFG, hostc);
+ 	}
+@@ -426,7 +456,7 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
+ 	int block = 0;
+ 	int ret, xact = 0;
+ 
+-	hwpec = isich4 && (flags & I2C_CLIENT_PEC)
++	hwpec = (i801_features & FEATURE_SMBUS_PEC) && (flags & I2C_CLIENT_PEC)
+ 		&& size != I2C_SMBUS_QUICK
+ 		&& size != I2C_SMBUS_I2C_BLOCK_DATA;
+ 
+@@ -462,12 +492,23 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
+ 		xact = I801_WORD_DATA;
+ 		break;
+ 	case I2C_SMBUS_BLOCK_DATA:
+-	case I2C_SMBUS_I2C_BLOCK_DATA:
+ 		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
+ 		       SMBHSTADD);
+ 		outb_p(command, SMBHSTCMD);
+ 		block = 1;
+ 		break;
++	case I2C_SMBUS_I2C_BLOCK_DATA:
++		/* NB: page 240 of ICH5 datasheet shows that the R/#W
++		 * bit should be cleared here, even when reading */
++		outb_p((addr & 0x7f) << 1, SMBHSTADD);
++		if (read_write == I2C_SMBUS_READ) {
++			/* NB: page 240 of ICH5 datasheet also shows
++			 * that DATA1 is the cmd field when reading */
++			outb_p(command, SMBHSTDAT1);
++		} else
++			outb_p(command, SMBHSTCMD);
++		block = 1;
++		break;
+ 	case I2C_SMBUS_PROC_CALL:
+ 	default:
+ 		dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size);
+@@ -487,7 +528,7 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
+ 	/* Some BIOSes don't like it when PEC is enabled at reboot or resume
+ 	   time, so we forcibly disable it after every transaction. Turn off
+ 	   E32B for the same reason. */
+-	if (hwpec)
++	if (hwpec || block)
+ 		outb_p(inb_p(SMBAUXCTL) & ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B),
+ 		       SMBAUXCTL);
+ 
+@@ -514,9 +555,11 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
+ static u32 i801_func(struct i2c_adapter *adapter)
+ {
+ 	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+-	    I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+-	    I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK
+-	     | (isich4 ? I2C_FUNC_SMBUS_PEC : 0);
++	       I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
++	       I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_WRITE_I2C_BLOCK |
++	       ((i801_features & FEATURE_SMBUS_PEC) ? I2C_FUNC_SMBUS_PEC : 0) |
++	       ((i801_features & FEATURE_I2C_BLOCK_READ) ?
++		I2C_FUNC_SMBUS_READ_I2C_BLOCK : 0);
+ }
+ 
+ static const struct i2c_algorithm smbus_algorithm = {
+@@ -556,8 +599,8 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
+ 	int err;
+ 
+ 	I801_dev = dev;
++	i801_features = 0;
+ 	switch (dev->device) {
+-	case PCI_DEVICE_ID_INTEL_82801DB_3:
+ 	case PCI_DEVICE_ID_INTEL_82801EB_3:
+ 	case PCI_DEVICE_ID_INTEL_ESB_4:
+ 	case PCI_DEVICE_ID_INTEL_ICH6_16:
+@@ -565,11 +608,13 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
+ 	case PCI_DEVICE_ID_INTEL_ESB2_17:
+ 	case PCI_DEVICE_ID_INTEL_ICH8_5:
+ 	case PCI_DEVICE_ID_INTEL_ICH9_6:
++		i801_features |= FEATURE_I2C_BLOCK_READ;
++		/* fall through */
++	case PCI_DEVICE_ID_INTEL_82801DB_3:
+ 	case PCI_DEVICE_ID_INTEL_TOLAPAI_1:
+-		isich4 = 1;
++		i801_features |= FEATURE_SMBUS_PEC;
++		i801_features |= FEATURE_BLOCK_BUFFER;
+ 		break;
+-	default:
+-		isich4 = 0;
+ 	}
+ 
+ 	err = pci_enable_device(dev);
+@@ -610,6 +655,11 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
+ 	else
+ 		dev_dbg(&dev->dev, "SMBus using PCI Interrupt\n");
+ 
++	/* Clear special mode bits */
++	if (i801_features & (FEATURE_SMBUS_PEC | FEATURE_BLOCK_BUFFER))
++		outb_p(inb_p(SMBAUXCTL) & ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B),
++		       SMBAUXCTL);
++
+ 	/* set up the sysfs linkage to our parent device */
+ 	i801_adapter.dev.parent = &dev->dev;
+ 
+@@ -678,9 +728,8 @@ static void __exit i2c_i801_exit(void)
+ 	pci_unregister_driver(&i801_driver);
+ }
+ 
+-MODULE_AUTHOR ("Frodo Looijaard <frodol at dds.nl>, "
+-		"Philip Edelbrock <phil at netroedge.com>, "
+-		"and Mark D. Studebaker <mdsxyz123 at yahoo.com>");
++MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123 at yahoo.com>, "
++	      "Jean Delvare <khali at linux-fr.org>");
+ MODULE_DESCRIPTION("I801 SMBus driver");
+ MODULE_LICENSE("GPL");
+ 
+diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
+index 9b43ff7..7c7eb0c 100644
+--- a/drivers/i2c/busses/i2c-ibm_iic.c
++++ b/drivers/i2c/busses/i2c-ibm_iic.c
+@@ -6,7 +6,7 @@
+  * Copyright (c) 2003, 2004 Zultys Technologies.
+  * Eugene Surovegin <eugene.surovegin at zultys.com> or <ebs at ebshome.net>
+  *
+- * Based on original work by 
++ * Based on original work by
+  * 	Ian DaSilva  <idasilva at mvista.com>
+  *      Armin Kuster <akuster at mvista.com>
+  * 	Matt Porter  <mporter at mvista.com>
+@@ -86,8 +86,8 @@ static void dump_iic_regs(const char* header, struct ibm_iic_private* dev)
+ 	       KERN_DEBUG "  sts      = 0x%02x, extsts = 0x%02x\n"
+ 	       KERN_DEBUG "  clkdiv   = 0x%02x, xfrcnt = 0x%02x\n"
+ 	       KERN_DEBUG "  xtcntlss = 0x%02x, directcntl = 0x%02x\n",
+-		in_8(&iic->cntl), in_8(&iic->mdcntl), in_8(&iic->sts), 
+-		in_8(&iic->extsts), in_8(&iic->clkdiv), in_8(&iic->xfrcnt), 
++		in_8(&iic->cntl), in_8(&iic->mdcntl), in_8(&iic->sts),
++		in_8(&iic->extsts), in_8(&iic->clkdiv), in_8(&iic->xfrcnt),
+ 		in_8(&iic->xtcntlss), in_8(&iic->directcntl));
+ }
+ #  define DUMP_REGS(h,dev)	dump_iic_regs((h),(dev))
+@@ -125,7 +125,7 @@ static inline void iic_interrupt_mode(struct ibm_iic_private* dev, int enable)
+ {
+ 	out_8(&dev->vaddr->intmsk, enable ? INTRMSK_EIMTC : 0);
+ }
+- 
 +
-+/*
-+ * AES decryption functions.
-+ */
-+static inline int hifn_decrypt_aes_ecb(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
-+			ACRYPTO_TYPE_AES_128, ACRYPTO_MODE_ECB);
-+}
-+static inline int hifn_decrypt_aes_cbc(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
-+			ACRYPTO_TYPE_AES_128, ACRYPTO_MODE_CBC);
-+}
-+static inline int hifn_decrypt_aes_cfb(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
-+			ACRYPTO_TYPE_AES_128, ACRYPTO_MODE_CFB);
-+}
-+static inline int hifn_decrypt_aes_ofb(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
-+			ACRYPTO_TYPE_AES_128, ACRYPTO_MODE_OFB);
-+}
+ /*
+  * Initialize IIC interface.
+  */
+@@ -134,7 +134,7 @@ static void iic_dev_init(struct ibm_iic_private* dev)
+ 	volatile struct iic_regs __iomem *iic = dev->vaddr;
+ 
+ 	DBG("%d: init\n", dev->idx);
+-	
 +
-+/*
-+ * DES ecryption functions.
-+ */
-+static inline int hifn_encrypt_des_ecb(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
-+			ACRYPTO_TYPE_DES, ACRYPTO_MODE_ECB);
-+}
-+static inline int hifn_encrypt_des_cbc(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
-+			ACRYPTO_TYPE_DES, ACRYPTO_MODE_CBC);
-+}
-+static inline int hifn_encrypt_des_cfb(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
-+			ACRYPTO_TYPE_DES, ACRYPTO_MODE_CFB);
-+}
-+static inline int hifn_encrypt_des_ofb(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
-+			ACRYPTO_TYPE_DES, ACRYPTO_MODE_OFB);
-+}
+ 	/* Clear master address */
+ 	out_8(&iic->lmadr, 0);
+ 	out_8(&iic->hmadr, 0);
+@@ -160,7 +160,7 @@ static void iic_dev_init(struct ibm_iic_private* dev)
+ 
+ 	/* Clear control register */
+ 	out_8(&iic->cntl, 0);
+-	
 +
+ 	/* Enable interrupts if possible */
+ 	iic_interrupt_mode(dev, dev->irq >= 0);
+ 
+@@ -171,7 +171,7 @@ static void iic_dev_init(struct ibm_iic_private* dev)
+ 	DUMP_REGS("iic_init", dev);
+ }
+ 
+-/* 
 +/*
-+ * DES decryption functions.
-+ */
-+static inline int hifn_decrypt_des_ecb(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
-+			ACRYPTO_TYPE_DES, ACRYPTO_MODE_ECB);
-+}
-+static inline int hifn_decrypt_des_cbc(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
-+			ACRYPTO_TYPE_DES, ACRYPTO_MODE_CBC);
-+}
-+static inline int hifn_decrypt_des_cfb(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
-+			ACRYPTO_TYPE_DES, ACRYPTO_MODE_CFB);
-+}
-+static inline int hifn_decrypt_des_ofb(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
-+			ACRYPTO_TYPE_DES, ACRYPTO_MODE_OFB);
-+}
+  * Reset IIC interface
+  */
+ static void iic_dev_reset(struct ibm_iic_private* dev)
+@@ -179,42 +179,42 @@ static void iic_dev_reset(struct ibm_iic_private* dev)
+ 	volatile struct iic_regs __iomem *iic = dev->vaddr;
+ 	int i;
+ 	u8 dc;
+-	
 +
-+/*
-+ * 3DES ecryption functions.
-+ */
-+static inline int hifn_encrypt_3des_ecb(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
-+			ACRYPTO_TYPE_3DES, ACRYPTO_MODE_ECB);
-+}
-+static inline int hifn_encrypt_3des_cbc(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
-+			ACRYPTO_TYPE_3DES, ACRYPTO_MODE_CBC);
-+}
-+static inline int hifn_encrypt_3des_cfb(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
-+			ACRYPTO_TYPE_3DES, ACRYPTO_MODE_CFB);
-+}
-+static inline int hifn_encrypt_3des_ofb(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_ENCRYPT,
-+			ACRYPTO_TYPE_3DES, ACRYPTO_MODE_OFB);
-+}
+ 	DBG("%d: soft reset\n", dev->idx);
+ 	DUMP_REGS("reset", dev);
+-	
 +
-+/*
-+ * 3DES decryption functions.
-+ */
-+static inline int hifn_decrypt_3des_ecb(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
-+			ACRYPTO_TYPE_3DES, ACRYPTO_MODE_ECB);
-+}
-+static inline int hifn_decrypt_3des_cbc(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
-+			ACRYPTO_TYPE_3DES, ACRYPTO_MODE_CBC);
-+}
-+static inline int hifn_decrypt_3des_cfb(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
-+			ACRYPTO_TYPE_3DES, ACRYPTO_MODE_CFB);
-+}
-+static inline int hifn_decrypt_3des_ofb(struct ablkcipher_request *req)
-+{
-+	return hifn_setup_crypto(req, ACRYPTO_OP_DECRYPT,
-+			ACRYPTO_TYPE_3DES, ACRYPTO_MODE_OFB);
-+}
+     	/* Place chip in the reset state */
+ 	out_8(&iic->xtcntlss, XTCNTLSS_SRST);
+-	
 +
-+struct hifn_alg_template
-+{
-+	char name[CRYPTO_MAX_ALG_NAME];
-+	char drv_name[CRYPTO_MAX_ALG_NAME];
-+	unsigned int bsize;
-+	struct ablkcipher_alg ablkcipher;
-+};
+ 	/* Check if bus is free */
+-	dc = in_8(&iic->directcntl);	
++	dc = in_8(&iic->directcntl);
+ 	if (!DIRCTNL_FREE(dc)){
+ 		DBG("%d: trying to regain bus control\n", dev->idx);
+-	
 +
-+static struct hifn_alg_template hifn_alg_templates[] = {
-+	/*
-+	 * 3DES ECB, CBC, CFB and OFB modes.
-+	 */
-+	{
-+		.name = "cfb(des3_ede)", .drv_name = "hifn-3des", .bsize = 8,
-+		.ablkcipher = {
-+			.min_keysize	=	HIFN_3DES_KEY_LENGTH,
-+			.max_keysize	=	HIFN_3DES_KEY_LENGTH,
-+			.setkey		=	hifn_setkey,
-+			.encrypt	=	hifn_encrypt_3des_cfb,
-+			.decrypt	=	hifn_decrypt_3des_cfb,
-+		},
-+	},
-+	{
-+		.name = "ofb(des3_ede)", .drv_name = "hifn-3des", .bsize = 8,
-+		.ablkcipher = {
-+			.min_keysize	=	HIFN_3DES_KEY_LENGTH,
-+			.max_keysize	=	HIFN_3DES_KEY_LENGTH,
-+			.setkey		=	hifn_setkey,
-+			.encrypt	=	hifn_encrypt_3des_ofb,
-+			.decrypt	=	hifn_decrypt_3des_ofb,
-+		},
-+	},
-+	{
-+		.name = "cbc(des3_ede)", .drv_name = "hifn-3des", .bsize = 8,
-+		.ablkcipher = {
-+			.min_keysize	=	HIFN_3DES_KEY_LENGTH,
-+			.max_keysize	=	HIFN_3DES_KEY_LENGTH,
-+			.setkey		=	hifn_setkey,
-+			.encrypt	=	hifn_encrypt_3des_cbc,
-+			.decrypt	=	hifn_decrypt_3des_cbc,
-+		},
-+	},
-+	{
-+		.name = "ecb(des3_ede)", .drv_name = "hifn-3des", .bsize = 8,
-+		.ablkcipher = {
-+			.min_keysize	=	HIFN_3DES_KEY_LENGTH,
-+			.max_keysize	=	HIFN_3DES_KEY_LENGTH,
-+			.setkey		=	hifn_setkey,
-+			.encrypt	=	hifn_encrypt_3des_ecb,
-+			.decrypt	=	hifn_decrypt_3des_ecb,
-+		},
-+	},
+ 		/* Try to set bus free state */
+-		out_8(&iic->directcntl, DIRCNTL_SDAC | DIRCNTL_SCC);	
+-	
++		out_8(&iic->directcntl, DIRCNTL_SDAC | DIRCNTL_SCC);
 +
-+	/*
-+	 * DES ECB, CBC, CFB and OFB modes.
-+	 */
-+	{
-+		.name = "cfb(des)", .drv_name = "hifn-des", .bsize = 8,
-+		.ablkcipher = {
-+			.min_keysize	=	HIFN_DES_KEY_LENGTH,
-+			.max_keysize	=	HIFN_DES_KEY_LENGTH,
-+			.setkey		=	hifn_setkey,
-+			.encrypt	=	hifn_encrypt_des_cfb,
-+			.decrypt	=	hifn_decrypt_des_cfb,
-+		},
-+	},
-+	{
-+		.name = "ofb(des)", .drv_name = "hifn-des", .bsize = 8,
-+		.ablkcipher = {
-+			.min_keysize	=	HIFN_DES_KEY_LENGTH,
-+			.max_keysize	=	HIFN_DES_KEY_LENGTH,
-+			.setkey		=	hifn_setkey,
-+			.encrypt	=	hifn_encrypt_des_ofb,
-+			.decrypt	=	hifn_decrypt_des_ofb,
-+		},
-+	},
-+	{
-+		.name = "cbc(des)", .drv_name = "hifn-des", .bsize = 8,
-+		.ablkcipher = {
-+			.min_keysize	=	HIFN_DES_KEY_LENGTH,
-+			.max_keysize	=	HIFN_DES_KEY_LENGTH,
-+			.setkey		=	hifn_setkey,
-+			.encrypt	=	hifn_encrypt_des_cbc,
-+			.decrypt	=	hifn_decrypt_des_cbc,
-+		},
-+	},
-+	{
-+		.name = "ecb(des)", .drv_name = "hifn-des", .bsize = 8,
-+		.ablkcipher = {
-+			.min_keysize	=	HIFN_DES_KEY_LENGTH,
-+			.max_keysize	=	HIFN_DES_KEY_LENGTH,
-+			.setkey		=	hifn_setkey,
-+			.encrypt	=	hifn_encrypt_des_ecb,
-+			.decrypt	=	hifn_decrypt_des_ecb,
-+		},
-+	},
+ 		/* Wait until we regain bus control */
+ 		for (i = 0; i < 100; ++i){
+ 			dc = in_8(&iic->directcntl);
+ 			if (DIRCTNL_FREE(dc))
+ 				break;
+-			
 +
-+	/*
-+	 * AES ECB, CBC, CFB and OFB modes.
-+	 */
-+	{
-+		.name = "ecb(aes)", .drv_name = "hifn-aes", .bsize = 16,
-+		.ablkcipher = {
-+			.min_keysize	=	AES_MIN_KEY_SIZE,
-+			.max_keysize	=	AES_MAX_KEY_SIZE,
-+			.setkey		=	hifn_setkey,
-+			.encrypt	=	hifn_encrypt_aes_ecb,
-+			.decrypt	=	hifn_decrypt_aes_ecb,
-+		},
-+	},
-+	{
-+		.name = "cbc(aes)", .drv_name = "hifn-aes", .bsize = 16,
-+		.ablkcipher = {
-+			.min_keysize	=	AES_MIN_KEY_SIZE,
-+			.max_keysize	=	AES_MAX_KEY_SIZE,
-+			.setkey		=	hifn_setkey,
-+			.encrypt	=	hifn_encrypt_aes_cbc,
-+			.decrypt	=	hifn_decrypt_aes_cbc,
-+		},
-+	},
-+	{
-+		.name = "cfb(aes)", .drv_name = "hifn-aes", .bsize = 16,
-+		.ablkcipher = {
-+			.min_keysize	=	AES_MIN_KEY_SIZE,
-+			.max_keysize	=	AES_MAX_KEY_SIZE,
-+			.setkey		=	hifn_setkey,
-+			.encrypt	=	hifn_encrypt_aes_cfb,
-+			.decrypt	=	hifn_decrypt_aes_cfb,
-+		},
-+	},
-+	{
-+		.name = "ofb(aes)", .drv_name = "hifn-aes", .bsize = 16,
-+		.ablkcipher = {
-+			.min_keysize	=	AES_MIN_KEY_SIZE,
-+			.max_keysize	=	AES_MAX_KEY_SIZE,
-+			.setkey		=	hifn_setkey,
-+			.encrypt	=	hifn_encrypt_aes_ofb,
-+			.decrypt	=	hifn_decrypt_aes_ofb,
-+		},
-+	},
-+};
+ 			/* Toggle SCL line */
+ 			dc ^= DIRCNTL_SCC;
+ 			out_8(&iic->directcntl, dc);
+ 			udelay(10);
+ 			dc ^= DIRCNTL_SCC;
+ 			out_8(&iic->directcntl, dc);
+-			
 +
-+static int hifn_cra_init(struct crypto_tfm *tfm)
-+{
-+	struct crypto_alg *alg = tfm->__crt_alg;
-+	struct hifn_crypto_alg *ha = crypto_alg_to_hifn(alg);
-+	struct hifn_context *ctx = crypto_tfm_ctx(tfm);
+ 			/* be nice */
+ 			cond_resched();
+ 		}
+ 	}
+-	
 +
-+	ctx->dev = ha->dev;
+ 	/* Remove reset */
+ 	out_8(&iic->xtcntlss, 0);
+-	
 +
-+	return 0;
-+}
+ 	/* Reinitialize interface */
+ 	iic_dev_init(dev);
+ }
+@@ -324,14 +324,14 @@ static irqreturn_t iic_handler(int irq, void *dev_id)
+ {
+ 	struct ibm_iic_private* dev = (struct ibm_iic_private*)dev_id;
+ 	volatile struct iic_regs __iomem *iic = dev->vaddr;
+-	
+-	DBG2("%d: irq handler, STS = 0x%02x, EXTSTS = 0x%02x\n", 
 +
-+static int hifn_alg_alloc(struct hifn_device *dev, struct hifn_alg_template *t)
-+{
-+	struct hifn_crypto_alg *alg;
-+	int err;
++	DBG2("%d: irq handler, STS = 0x%02x, EXTSTS = 0x%02x\n",
+ 	     dev->idx, in_8(&iic->sts), in_8(&iic->extsts));
+-	
 +
-+	alg = kzalloc(sizeof(struct hifn_crypto_alg), GFP_KERNEL);
-+	if (!alg)
-+		return -ENOMEM;
+ 	/* Acknowledge IRQ and wakeup iic_wait_for_tc */
+ 	out_8(&iic->sts, STS_IRQA | STS_SCMP);
+ 	wake_up_interruptible(&dev->wq);
+-	
 +
-+	snprintf(alg->alg.cra_name, CRYPTO_MAX_ALG_NAME, "%s", t->name);
-+	snprintf(alg->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", t->drv_name);
+ 	return IRQ_HANDLED;
+ }
+ 
+@@ -341,19 +341,19 @@ static irqreturn_t iic_handler(int irq, void *dev_id)
+  */
+ static int iic_xfer_result(struct ibm_iic_private* dev)
+ {
+-	volatile struct iic_regs __iomem *iic = dev->vaddr;	
+-	
++	volatile struct iic_regs __iomem *iic = dev->vaddr;
 +
-+	alg->alg.cra_priority = 300;
-+	alg->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC;
-+	alg->alg.cra_blocksize = t->bsize;
-+	alg->alg.cra_ctxsize = sizeof(struct hifn_context);
-+	alg->alg.cra_alignmask = 15;
-+	if (t->bsize == 8)
-+		alg->alg.cra_alignmask = 3;
-+	alg->alg.cra_type = &crypto_ablkcipher_type;
-+	alg->alg.cra_module = THIS_MODULE;
-+	alg->alg.cra_u.ablkcipher = t->ablkcipher;
-+	alg->alg.cra_init = hifn_cra_init;
+ 	if (unlikely(in_8(&iic->sts) & STS_ERR)){
+-		DBG("%d: xfer error, EXTSTS = 0x%02x\n", dev->idx, 
++		DBG("%d: xfer error, EXTSTS = 0x%02x\n", dev->idx,
+ 			in_8(&iic->extsts));
+-				
++
+ 		/* Clear errors and possible pending IRQs */
+-		out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD | 
++		out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD |
+ 			EXTSTS_LA | EXTSTS_ICT | EXTSTS_XFRA);
+-			
 +
-+	alg->dev = dev;
+ 		/* Flush master data buffer */
+ 		out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB);
+-		
 +
-+	list_add_tail(&alg->entry, &dev->alg_list);
+ 		/* Is bus free?
+ 		 * If error happened during combined xfer
+ 		 * IIC interface is usually stuck in some strange
+@@ -376,11 +376,11 @@ static void iic_abort_xfer(struct ibm_iic_private* dev)
+ {
+ 	volatile struct iic_regs __iomem *iic = dev->vaddr;
+ 	unsigned long x;
+-	
 +
-+	err = crypto_register_alg(&alg->alg);
-+	if (err) {
-+		list_del(&alg->entry);
-+		kfree(alg);
-+	}
+ 	DBG("%d: iic_abort_xfer\n", dev->idx);
+-	
 +
-+	return err;
-+}
+ 	out_8(&iic->cntl, CNTL_HMT);
+-	
 +
-+static void hifn_unregister_alg(struct hifn_device *dev)
-+{
-+	struct hifn_crypto_alg *a, *n;
+ 	/*
+ 	 * Wait for the abort command to complete.
+ 	 * It's not worth to be optimized, just poll (timeout >= 1 tick)
+@@ -405,13 +405,13 @@ static void iic_abort_xfer(struct ibm_iic_private* dev)
+  * Returns the number of transferred bytes or error (<0)
+  */
+ static int iic_wait_for_tc(struct ibm_iic_private* dev){
+-	
 +
-+	list_for_each_entry_safe(a, n, &dev->alg_list, entry) {
-+		list_del(&a->entry);
-+		crypto_unregister_alg(&a->alg);
-+		kfree(a);
-+	}
-+}
+ 	volatile struct iic_regs __iomem *iic = dev->vaddr;
+ 	int ret = 0;
+-	
 +
-+static int hifn_register_alg(struct hifn_device *dev)
-+{
-+	int i, err;
+ 	if (dev->irq >= 0){
+ 		/* Interrupt mode */
+-		ret = wait_event_interruptible_timeout(dev->wq, 
++		ret = wait_event_interruptible_timeout(dev->wq,
+ 			!(in_8(&iic->sts) & STS_PT), dev->adap.timeout * HZ);
+ 
+ 		if (unlikely(ret < 0))
+@@ -424,37 +424,37 @@ static int iic_wait_for_tc(struct ibm_iic_private* dev){
+ 	else {
+ 		/* Polling mode */
+ 		unsigned long x = jiffies + dev->adap.timeout * HZ;
+-		
 +
-+	for (i=0; i<ARRAY_SIZE(hifn_alg_templates); ++i) {
-+		err = hifn_alg_alloc(dev, &hifn_alg_templates[i]);
-+		if (err)
-+			goto err_out_exit;
-+	}
+ 		while (in_8(&iic->sts) & STS_PT){
+ 			if (unlikely(time_after(jiffies, x))){
+ 				DBG("%d: poll timeout\n", dev->idx);
+ 				ret = -ETIMEDOUT;
+ 				break;
+ 			}
+-		
 +
-+	return 0;
+ 			if (unlikely(signal_pending(current))){
+ 				DBG("%d: poll interrupted\n", dev->idx);
+ 				ret = -ERESTARTSYS;
+ 				break;
+ 			}
+ 			schedule();
+-		}	
++		}
+ 	}
+-	
 +
-+err_out_exit:
-+	hifn_unregister_alg(dev);
-+	return err;
-+}
+ 	if (unlikely(ret < 0))
+ 		iic_abort_xfer(dev);
+ 	else
+ 		ret = iic_xfer_result(dev);
+-	
 +
-+static void hifn_tasklet_callback(unsigned long data)
-+{
-+	struct hifn_device *dev = (struct hifn_device *)data;
+ 	DBG2("%d: iic_wait_for_tc -> %d\n", dev->idx, ret);
+-	
 +
-+	/*
-+	 * This is ok to call this without lock being held,
-+	 * althogh it modifies some parameters used in parallel,
-+	 * (like dev->success), but they are used in process
-+	 * context or update is atomic (like setting dev->sa[i] to NULL).
-+	 */
-+	hifn_check_for_completion(dev, 0);
-+}
+ 	return ret;
+ }
+ 
+ /*
+  * Low level master transfer routine
+  */
+-static int iic_xfer_bytes(struct ibm_iic_private* dev, struct i2c_msg* pm, 
++static int iic_xfer_bytes(struct ibm_iic_private* dev, struct i2c_msg* pm,
+ 			  int combined_xfer)
+ {
+ 	volatile struct iic_regs __iomem *iic = dev->vaddr;
+@@ -465,48 +465,48 @@ static int iic_xfer_bytes(struct ibm_iic_private* dev, struct i2c_msg* pm,
+ 	u8 cntl = (in_8(&iic->cntl) & CNTL_AMD) | CNTL_PT;
+ 	if (pm->flags & I2C_M_RD)
+ 		cntl |= CNTL_RW;
+-	
 +
-+static int hifn_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-+{
-+	int err, i;
-+	struct hifn_device *dev;
-+	char name[8];
+ 	loops = (len + 3) / 4;
+ 	for (i = 0; i < loops; ++i, len -= 4){
+ 		int count = len > 4 ? 4 : len;
+ 		u8 cmd = cntl | ((count - 1) << CNTL_TCT_SHIFT);
+-		
 +
-+	err = pci_enable_device(pdev);
-+	if (err)
-+		return err;
-+	pci_set_master(pdev);
+ 		if (!(cntl & CNTL_RW))
+ 			for (j = 0; j < count; ++j)
+ 				out_8((void __iomem *)&iic->mdbuf, *buf++);
+-		
 +
-+	err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
-+	if (err)
-+		goto err_out_disable_pci_device;
+ 		if (i < loops - 1)
+ 			cmd |= CNTL_CHT;
+ 		else if (combined_xfer)
+ 			cmd |= CNTL_RPST;
+-		
 +
-+	snprintf(name, sizeof(name), "hifn%d",
-+			atomic_inc_return(&hifn_dev_number)-1);
+ 		DBG2("%d: xfer_bytes, %d, CNTL = 0x%02x\n", dev->idx, count, cmd);
+-		
 +
-+	err = pci_request_regions(pdev, name);
-+	if (err)
-+		goto err_out_disable_pci_device;
+ 		/* Start transfer */
+ 		out_8(&iic->cntl, cmd);
+-		
 +
-+	if (pci_resource_len(pdev, 0) < HIFN_BAR0_SIZE ||
-+	    pci_resource_len(pdev, 1) < HIFN_BAR1_SIZE ||
-+	    pci_resource_len(pdev, 2) < HIFN_BAR2_SIZE) {
-+		dprintk("%s: Broken hardware - I/O regions are too small.\n",
-+				pci_name(pdev));
-+		err = -ENODEV;
-+		goto err_out_free_regions;
-+	}
+ 		/* Wait for completion */
+ 		ret = iic_wait_for_tc(dev);
+ 
+ 		if (unlikely(ret < 0))
+ 			break;
+ 		else if (unlikely(ret != count)){
+-			DBG("%d: xfer_bytes, requested %d, transfered %d\n", 
++			DBG("%d: xfer_bytes, requested %d, transfered %d\n",
+ 				dev->idx, count, ret);
+-			
 +
-+	dev = kzalloc(sizeof(struct hifn_device) + sizeof(struct crypto_alg),
-+			GFP_KERNEL);
-+	if (!dev) {
-+		err = -ENOMEM;
-+		goto err_out_free_regions;
-+	}
+ 			/* If it's not a last part of xfer, abort it */
+ 			if (combined_xfer || (i < loops - 1))
+     				iic_abort_xfer(dev);
+-				
 +
-+	INIT_LIST_HEAD(&dev->alg_list);
+ 			ret = -EREMOTEIO;
+-			break;				
++			break;
+ 		}
+-		
 +
-+	snprintf(dev->name, sizeof(dev->name), "%s", name);
-+	spin_lock_init(&dev->lock);
+ 		if (cntl & CNTL_RW)
+ 			for (j = 0; j < count; ++j)
+ 				*buf++ = in_8((void __iomem *)&iic->mdbuf);
+ 	}
+-	
 +
-+	for (i=0; i<3; ++i) {
-+		unsigned long addr, size;
+ 	return ret > 0 ? 0 : ret;
+ }
+ 
+@@ -517,10 +517,10 @@ static inline void iic_address(struct ibm_iic_private* dev, struct i2c_msg* msg)
+ {
+ 	volatile struct iic_regs __iomem *iic = dev->vaddr;
+ 	u16 addr = msg->addr;
+-	
+-	DBG2("%d: iic_address, 0x%03x (%d-bit)\n", dev->idx, 
 +
-+		addr = pci_resource_start(pdev, i);
-+		size = pci_resource_len(pdev, i);
++	DBG2("%d: iic_address, 0x%03x (%d-bit)\n", dev->idx,
+ 		addr, msg->flags & I2C_M_TEN ? 10 : 7);
+-	
 +
-+		dev->bar[i] = ioremap_nocache(addr, size);
-+		if (!dev->bar[i])
-+			goto err_out_unmap_bars;
-+	}
+ 	if (msg->flags & I2C_M_TEN){
+ 	    out_8(&iic->cntl, CNTL_AMD);
+ 	    out_8(&iic->lmadr, addr);
+@@ -537,15 +537,15 @@ static inline int iic_invalid_address(const struct i2c_msg* p)
+ 	return (p->addr > 0x3ff) || (!(p->flags & I2C_M_TEN) && (p->addr > 0x7f));
+ }
+ 
+-static inline int iic_address_neq(const struct i2c_msg* p1, 
++static inline int iic_address_neq(const struct i2c_msg* p1,
+ 				  const struct i2c_msg* p2)
+ {
+-	return (p1->addr != p2->addr) 
++	return (p1->addr != p2->addr)
+ 		|| ((p1->flags & I2C_M_TEN) != (p2->flags & I2C_M_TEN));
+-} 
++}
+ 
+ /*
+- * Generic master transfer entrypoint. 
++ * Generic master transfer entrypoint.
+  * Returns the number of processed messages or error (<0)
+  */
+ static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+@@ -553,20 +553,20 @@ static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+     	struct ibm_iic_private* dev = (struct ibm_iic_private*)(i2c_get_adapdata(adap));
+ 	volatile struct iic_regs __iomem *iic = dev->vaddr;
+ 	int i, ret = 0;
+-	
 +
-+	dev->result_mem = __get_free_pages(GFP_KERNEL, HIFN_MAX_RESULT_ORDER);
-+	if (!dev->result_mem) {
-+		dprintk("Failed to allocate %d pages for result_mem.\n",
-+				HIFN_MAX_RESULT_ORDER);
-+		goto err_out_unmap_bars;
-+	}
-+	memset((void *)dev->result_mem, 0, PAGE_SIZE*(1<<HIFN_MAX_RESULT_ORDER));
+ 	DBG2("%d: iic_xfer, %d msg(s)\n", dev->idx, num);
+-	
 +
-+	dev->dst = pci_map_single(pdev, (void *)dev->result_mem,
-+			PAGE_SIZE << HIFN_MAX_RESULT_ORDER, PCI_DMA_FROMDEVICE);
+ 	if (!num)
+ 		return 0;
+-	
 +
-+	dev->desc_virt = pci_alloc_consistent(pdev, sizeof(struct hifn_dma),
-+			&dev->desc_dma);
-+	if (!dev->desc_virt) {
-+		dprintk("Failed to allocate descriptor rings.\n");
-+		goto err_out_free_result_pages;
+ 	/* Check the sanity of the passed messages.
+ 	 * Uhh, generic i2c layer is more suitable place for such code...
+ 	 */
+ 	if (unlikely(iic_invalid_address(&msgs[0]))){
+-		DBG("%d: invalid address 0x%03x (%d-bit)\n", dev->idx, 
++		DBG("%d: invalid address 0x%03x (%d-bit)\n", dev->idx,
+ 			msgs[0].addr, msgs[0].flags & I2C_M_TEN ? 10 : 7);
+ 		return -EINVAL;
+-	}		
 +	}
-+	memset(dev->desc_virt, 0, sizeof(struct hifn_dma));
+ 	for (i = 0; i < num; ++i){
+ 		if (unlikely(msgs[i].len <= 0)){
+ 			if (num == 1 && !msgs[0].len){
+@@ -576,7 +576,7 @@ static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+ 				 */
+ 				return iic_smbus_quick(dev, &msgs[0]);
+ 			}
+-			DBG("%d: invalid len %d in msg[%d]\n", dev->idx, 
++			DBG("%d: invalid len %d in msg[%d]\n", dev->idx,
+ 				msgs[i].len, i);
+ 			return -EINVAL;
+ 		}
+@@ -585,34 +585,34 @@ static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+ 			return -EINVAL;
+ 		}
+ 	}
+-	
 +
-+	dev->pdev = pdev;
-+	dev->irq = pdev->irq;
+ 	/* Check bus state */
+ 	if (unlikely((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE)){
+ 		DBG("%d: iic_xfer, bus is not free\n", dev->idx);
+-		
 +
-+	for (i=0; i<HIFN_D_RES_RSIZE; ++i)
-+		dev->sa[i] = NULL;
+ 		/* Usually it means something serious has happend.
+ 		 * We *cannot* have unfinished previous transfer
+ 		 * so it doesn't make any sense to try to stop it.
+-		 * Probably we were not able to recover from the 
++		 * Probably we were not able to recover from the
+ 		 * previous error.
+ 		 * The only *reasonable* thing I can think of here
+ 		 * is soft reset.  --ebs
+ 		 */
+ 		iic_dev_reset(dev);
+-		
 +
-+	pci_set_drvdata(pdev, dev);
+ 		if ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){
+ 			DBG("%d: iic_xfer, bus is still not free\n", dev->idx);
+ 			return -EREMOTEIO;
+ 		}
+-	} 
++	}
+ 	else {
+ 		/* Flush master data buffer (just in case) */
+ 		out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB);
+ 	}
+-	
 +
-+	tasklet_init(&dev->tasklet, hifn_tasklet_callback, (unsigned long)dev);
+ 	/* Load slave address */
+ 	iic_address(dev, &msgs[0]);
+-	
 +
-+	crypto_init_queue(&dev->queue, 1);
+ 	/* Do real transfer */
+     	for (i = 0; i < num && !ret; ++i)
+ 		ret = iic_xfer_bytes(dev, &msgs[i], i < num - 1);
+@@ -648,7 +648,7 @@ static inline u8 iic_clckdiv(unsigned int opb)
+ 
+ 	/* Convert to MHz */
+ 	opb /= 1000000;
+-	
 +
-+	err = request_irq(dev->irq, hifn_interrupt, IRQF_SHARED, dev->name, dev);
-+	if (err) {
-+		dprintk("Failed to request IRQ%d: err: %d.\n", dev->irq, err);
-+		dev->irq = 0;
-+		goto err_out_free_desc;
-+	}
+ 	if (opb < 20 || opb > 150){
+ 		printk(KERN_CRIT "ibm-iic: invalid OPB clock frequency %u MHz\n",
+ 			opb);
+@@ -666,7 +666,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){
+ 	struct i2c_adapter* adap;
+ 	struct ocp_func_iic_data* iic_data = ocp->def->additions;
+ 	int ret;
+-	
 +
-+	err = hifn_start_device(dev);
-+	if (err)
-+		goto err_out_free_irq;
+ 	if (!iic_data)
+ 		printk(KERN_WARNING"ibm-iic%d: missing additional data!\n",
+ 			ocp->def->index);
+@@ -679,7 +679,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){
+ 
+ 	dev->idx = ocp->def->index;
+ 	ocp_set_drvdata(ocp, dev);
+-	
 +
-+	err = hifn_test(dev, 1, 0);
-+	if (err)
-+		goto err_out_stop_device;
+ 	if (!request_mem_region(ocp->def->paddr, sizeof(struct iic_regs),
+ 				"ibm_iic")) {
+ 		ret = -EBUSY;
+@@ -692,7 +692,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){
+ 		ret = -ENXIO;
+ 		goto fail2;
+ 	}
+-	
 +
-+	err = hifn_register_rng(dev);
-+	if (err)
-+		goto err_out_stop_device;
+ 	init_waitqueue_head(&dev->wq);
+ 
+ 	dev->irq = iic_force_poll ? -1 : ocp->def->irq;
+@@ -702,29 +702,29 @@ static int __devinit iic_probe(struct ocp_device *ocp){
+ 		 */
+ 		iic_interrupt_mode(dev, 0);
+ 		if (request_irq(dev->irq, iic_handler, 0, "IBM IIC", dev)){
+-			printk(KERN_ERR "ibm-iic%d: request_irq %d failed\n", 
++			printk(KERN_ERR "ibm-iic%d: request_irq %d failed\n",
+ 				dev->idx, dev->irq);
+-			/* Fallback to the polling mode */	
++			/* Fallback to the polling mode */
+ 			dev->irq = -1;
+ 		}
+ 	}
+-	
 +
-+	err = hifn_register_alg(dev);
-+	if (err)
-+		goto err_out_unregister_rng;
+ 	if (dev->irq < 0)
+-		printk(KERN_WARNING "ibm-iic%d: using polling mode\n", 
++		printk(KERN_WARNING "ibm-iic%d: using polling mode\n",
+ 			dev->idx);
+-		
 +
-+	INIT_DELAYED_WORK(&dev->work, hifn_work);
-+	schedule_delayed_work(&dev->work, HZ);
+ 	/* Board specific settings */
+ 	dev->fast_mode = iic_force_fast ? 1 : (iic_data ? iic_data->fast_mode : 0);
+-	
+-	/* clckdiv is the same for *all* IIC interfaces, 
 +
-+	dprintk("HIFN crypto accelerator card at %s has been "
-+			"successfully registered as %s.\n",
-+			pci_name(pdev), dev->name);
++	/* clckdiv is the same for *all* IIC interfaces,
+ 	 * but I'd rather make a copy than introduce another global. --ebs
+ 	 */
+ 	dev->clckdiv = iic_clckdiv(ocp_sys_info.opb_bus_freq);
+ 	DBG("%d: clckdiv = %d\n", dev->idx, dev->clckdiv);
+-	
 +
-+	return 0;
+ 	/* Initialize IIC interface */
+ 	iic_dev_init(dev);
+-	
 +
-+err_out_unregister_rng:
-+	hifn_unregister_rng(dev);
-+err_out_stop_device:
-+	hifn_reset_dma(dev, 1);
-+	hifn_stop_device(dev);
-+err_out_free_irq:
-+	free_irq(dev->irq, dev->name);
-+	tasklet_kill(&dev->tasklet);
-+err_out_free_desc:
-+	pci_free_consistent(pdev, sizeof(struct hifn_dma),
-+			dev->desc_virt, dev->desc_dma);
+ 	/* Register it with i2c layer */
+ 	adap = &dev->adap;
+ 	adap->dev.parent = &ocp->dev;
+@@ -736,7 +736,6 @@ static int __devinit iic_probe(struct ocp_device *ocp){
+ 	adap->client_register = NULL;
+ 	adap->client_unregister = NULL;
+ 	adap->timeout = 1;
+-	adap->retries = 1;
+ 
+ 	/*
+ 	 * If "dev->idx" is negative we consider it as zero.
+@@ -750,24 +749,24 @@ static int __devinit iic_probe(struct ocp_device *ocp){
+ 			dev->idx);
+ 		goto fail;
+ 	}
+-	
 +
-+err_out_free_result_pages:
-+	pci_unmap_single(pdev, dev->dst, PAGE_SIZE << HIFN_MAX_RESULT_ORDER,
-+			PCI_DMA_FROMDEVICE);
-+	free_pages(dev->result_mem, HIFN_MAX_RESULT_ORDER);
+ 	printk(KERN_INFO "ibm-iic%d: using %s mode\n", dev->idx,
+ 		dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
+ 
+ 	return 0;
+ 
+-fail:	
++fail:
+ 	if (dev->irq >= 0){
+ 		iic_interrupt_mode(dev, 0);
+ 		free_irq(dev->irq, dev);
+-	}	
++	}
+ 
+ 	iounmap(dev->vaddr);
+-fail2:	
++fail2:
+ 	release_mem_region(ocp->def->paddr, sizeof(struct iic_regs));
+ fail1:
+ 	ocp_set_drvdata(ocp, NULL);
+-	kfree(dev);	
++	kfree(dev);
+ 	return ret;
+ }
+ 
+@@ -783,13 +782,13 @@ static void __devexit iic_remove(struct ocp_device *ocp)
+ 			dev->idx);
+ 		/* That's *very* bad, just shutdown IRQ ... */
+ 		if (dev->irq >= 0){
+-		    iic_interrupt_mode(dev, 0);	
++		    iic_interrupt_mode(dev, 0);
+ 		    free_irq(dev->irq, dev);
+ 		    dev->irq = -1;
+ 		}
+ 	} else {
+ 		if (dev->irq >= 0){
+-		    iic_interrupt_mode(dev, 0);	
++		    iic_interrupt_mode(dev, 0);
+ 		    free_irq(dev->irq, dev);
+ 		}
+ 		iounmap(dev->vaddr);
+@@ -798,7 +797,7 @@ static void __devexit iic_remove(struct ocp_device *ocp)
+ 	}
+ }
+ 
+-static struct ocp_device_id ibm_iic_ids[] __devinitdata = 
++static struct ocp_device_id ibm_iic_ids[] __devinitdata =
+ {
+ 	{ .vendor = OCP_VENDOR_IBM, .function = OCP_FUNC_IIC },
+ 	{ .vendor = OCP_VENDOR_INVALID }
+diff --git a/drivers/i2c/busses/i2c-ibm_iic.h b/drivers/i2c/busses/i2c-ibm_iic.h
+index 59d7b43..fdaa482 100644
+--- a/drivers/i2c/busses/i2c-ibm_iic.h
++++ b/drivers/i2c/busses/i2c-ibm_iic.h
+@@ -2,11 +2,11 @@
+  * drivers/i2c/busses/i2c-ibm_iic.h
+  *
+  * Support for the IIC peripheral on IBM PPC 4xx
+- * 
++ *
+  * Copyright (c) 2003 Zultys Technologies.
+  * Eugene Surovegin <eugene.surovegin at zultys.com> or <ebs at ebshome.net>
+  *
+- * Based on original work by 
++ * Based on original work by
+  * 	Ian DaSilva  <idasilva at mvista.com>
+  *      Armin Kuster <akuster at mvista.com>
+  * 	Matt Porter  <mporter at mvista.com>
+@@ -22,7 +22,7 @@
+ #ifndef __I2C_IBM_IIC_H_
+ #define __I2C_IBM_IIC_H_
+ 
+-#include <linux/i2c.h> 
++#include <linux/i2c.h>
+ 
+ struct iic_regs {
+ 	u16 mdbuf;
+@@ -58,7 +58,7 @@ struct ibm_iic_private {
+ #define CNTL_TCT_MASK	0x30
+ #define CNTL_TCT_SHIFT	4
+ #define CNTL_RPST	0x08
+-#define CNTL_CHT	0x04 
++#define CNTL_CHT	0x04
+ #define CNTL_RW		0x02
+ #define CNTL_PT		0x01
+ 
+diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
+index c70146e..ab41400 100644
+--- a/drivers/i2c/busses/i2c-iop3xx.c
++++ b/drivers/i2c/busses/i2c-iop3xx.c
+@@ -490,7 +490,6 @@ iop3xx_i2c_probe(struct platform_device *pdev)
+ 	 * Default values...should these come in from board code?
+ 	 */
+ 	new_adapter->timeout = 100;	
+-	new_adapter->retries = 3;
+ 	new_adapter->algo = &iop3xx_i2c_algo;
+ 
+ 	init_waitqueue_head(&adapter_data->waitq);
+diff --git a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c
+deleted file mode 100644
+index 069ed7f..0000000
+--- a/drivers/i2c/busses/i2c-ixp4xx.c
++++ /dev/null
+@@ -1,178 +0,0 @@
+-/*
+- * drivers/i2c/busses/i2c-ixp4xx.c
+- *
+- * Intel's IXP4xx XScale NPU chipsets (IXP420, 421, 422, 425) do not have
+- * an on board I2C controller but provide 16 GPIO pins that are often
+- * used to create an I2C bus. This driver provides an i2c_adapter 
+- * interface that plugs in under algo_bit and drives the GPIO pins
+- * as instructed by the alogorithm driver.
+- *
+- * Author: Deepak Saxena <dsaxena at plexity.net>
+- *
+- * Copyright (c) 2003-2004 MontaVista Software Inc.
+- *
+- * This file is licensed under the terms of the GNU General Public 
+- * License version 2. This program is licensed "as is" without any 
+- * warranty of any kind, whether express or implied.
+- *
+- * NOTE: Since different platforms will use different GPIO pins for
+- *       I2C, this driver uses an IXP4xx-specific platform_data
+- *       pointer to pass the GPIO numbers to the driver. This 
+- *       allows us to support all the different IXP4xx platforms
+- *       w/o having to put #ifdefs in this driver.
+- *
+- *       See arch/arm/mach-ixp4xx/ixdp425.c for an example of building a 
+- *       device list and filling in the ixp4xx_i2c_pins data structure 
+- *       that is passed as the platform_data to this driver.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/init.h>
+-#include <linux/platform_device.h>
+-#include <linux/module.h>
+-#include <linux/i2c.h>
+-#include <linux/i2c-algo-bit.h>
+-
+-#include <asm/hardware.h>	/* Pick up IXP4xx-specific bits */
+-
+-static inline int ixp4xx_scl_pin(void *data)
+-{
+-	return ((struct ixp4xx_i2c_pins*)data)->scl_pin;
+-}
+-
+-static inline int ixp4xx_sda_pin(void *data)
+-{
+-	return ((struct ixp4xx_i2c_pins*)data)->sda_pin;
+-}
+-
+-static void ixp4xx_bit_setscl(void *data, int val)
+-{
+-	gpio_line_set(ixp4xx_scl_pin(data), 0);
+-	gpio_line_config(ixp4xx_scl_pin(data),
+-		val ? IXP4XX_GPIO_IN : IXP4XX_GPIO_OUT );
+-}
+-
+-static void ixp4xx_bit_setsda(void *data, int val)
+-{
+-	gpio_line_set(ixp4xx_sda_pin(data), 0);
+-	gpio_line_config(ixp4xx_sda_pin(data),
+-		val ? IXP4XX_GPIO_IN : IXP4XX_GPIO_OUT );
+-}
+-
+-static int ixp4xx_bit_getscl(void *data)
+-{
+-	int scl;
+-
+-	gpio_line_config(ixp4xx_scl_pin(data), IXP4XX_GPIO_IN );
+-	gpio_line_get(ixp4xx_scl_pin(data), &scl);
+-
+-	return scl;
+-}	
+-
+-static int ixp4xx_bit_getsda(void *data)
+-{
+-	int sda;
+-
+-	gpio_line_config(ixp4xx_sda_pin(data), IXP4XX_GPIO_IN );
+-	gpio_line_get(ixp4xx_sda_pin(data), &sda);
+-
+-	return sda;
+-}	
+-
+-struct ixp4xx_i2c_data {
+-	struct ixp4xx_i2c_pins *gpio_pins;
+-	struct i2c_adapter adapter;
+-	struct i2c_algo_bit_data algo_data;
+-};
+-
+-static int ixp4xx_i2c_remove(struct platform_device *plat_dev)
+-{
+-	struct ixp4xx_i2c_data *drv_data = platform_get_drvdata(plat_dev);
+-
+-	platform_set_drvdata(plat_dev, NULL);
+-
+-	i2c_del_adapter(&drv_data->adapter);
+-
+-	kfree(drv_data);
+-
+-	return 0;
+-}
+-
+-static int ixp4xx_i2c_probe(struct platform_device *plat_dev)
+-{
+-	int err;
+-	struct ixp4xx_i2c_pins *gpio = plat_dev->dev.platform_data;
+-	struct ixp4xx_i2c_data *drv_data = 
+-		kzalloc(sizeof(struct ixp4xx_i2c_data), GFP_KERNEL);
+-
+-	if(!drv_data)
+-		return -ENOMEM;
+-
+-	drv_data->gpio_pins = gpio;
+-
+-	/*
+-	 * We could make a lot of these structures static, but
+-	 * certain platforms may have multiple GPIO-based I2C
+-	 * buses for various device domains, so we need per-device
+-	 * algo_data->data. 
+-	 */
+-	drv_data->algo_data.data = gpio;
+-	drv_data->algo_data.setsda = ixp4xx_bit_setsda;
+-	drv_data->algo_data.setscl = ixp4xx_bit_setscl;
+-	drv_data->algo_data.getsda = ixp4xx_bit_getsda;
+-	drv_data->algo_data.getscl = ixp4xx_bit_getscl;
+-	drv_data->algo_data.udelay = 10;
+-	drv_data->algo_data.timeout = 100;
+-
+-	drv_data->adapter.id = I2C_HW_B_IXP4XX;
+-	drv_data->adapter.class = I2C_CLASS_HWMON;
+-	strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
+-		sizeof(drv_data->adapter.name));
+-	drv_data->adapter.algo_data = &drv_data->algo_data;
+-
+-	drv_data->adapter.dev.parent = &plat_dev->dev;
+-
+-	gpio_line_config(gpio->scl_pin, IXP4XX_GPIO_IN);
+-	gpio_line_config(gpio->sda_pin, IXP4XX_GPIO_IN);
+-	gpio_line_set(gpio->scl_pin, 0);
+-	gpio_line_set(gpio->sda_pin, 0);
+-
+-	err = i2c_bit_add_bus(&drv_data->adapter);
+-	if (err) {
+-		printk(KERN_ERR "ERROR: Could not install %s\n", plat_dev->dev.bus_id);
+-
+-		kfree(drv_data);
+-		return err;
+-	}
+-
+-	platform_set_drvdata(plat_dev, drv_data);
+-
+-	return 0;
+-}
+-
+-static struct platform_driver ixp4xx_i2c_driver = {
+-	.probe		= ixp4xx_i2c_probe,
+-	.remove		= ixp4xx_i2c_remove,
+-	.driver		= {
+-		.name	= "IXP4XX-I2C",
+-		.owner	= THIS_MODULE,
+-	},
+-};
+-
+-static int __init ixp4xx_i2c_init(void)
+-{
+-	return platform_driver_register(&ixp4xx_i2c_driver);
+-}
+-
+-static void __exit ixp4xx_i2c_exit(void)
+-{
+-	platform_driver_unregister(&ixp4xx_i2c_driver);
+-}
+-
+-module_init(ixp4xx_i2c_init);
+-module_exit(ixp4xx_i2c_exit);
+-
+-MODULE_DESCRIPTION("GPIO-based I2C adapter for IXP4xx systems");
+-MODULE_LICENSE("GPL");
+-MODULE_AUTHOR("Deepak Saxena <dsaxena at plexity.net>");
+-
+diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
+index d8de4ac..bbe787b 100644
+--- a/drivers/i2c/busses/i2c-mpc.c
++++ b/drivers/i2c/busses/i2c-mpc.c
+@@ -180,7 +180,7 @@ static void mpc_i2c_stop(struct mpc_i2c *i2c)
+ static int mpc_write(struct mpc_i2c *i2c, int target,
+ 		     const u8 * data, int length, int restart)
+ {
+-	int i;
++	int i, result;
+ 	unsigned timeout = i2c->adap.timeout;
+ 	u32 flags = restart ? CCR_RSTA : 0;
+ 
+@@ -192,15 +192,17 @@ static int mpc_write(struct mpc_i2c *i2c, int target,
+ 	/* Write target byte */
+ 	writeb((target << 1), i2c->base + MPC_I2C_DR);
+ 
+-	if (i2c_wait(i2c, timeout, 1) < 0)
+-		return -1;
++	result = i2c_wait(i2c, timeout, 1);
++	if (result < 0)
++		return result;
+ 
+ 	for (i = 0; i < length; i++) {
+ 		/* Write data byte */
+ 		writeb(data[i], i2c->base + MPC_I2C_DR);
+ 
+-		if (i2c_wait(i2c, timeout, 1) < 0)
+-			return -1;
++		result = i2c_wait(i2c, timeout, 1);
++		if (result < 0)
++			return result;
+ 	}
+ 
+ 	return 0;
+@@ -210,7 +212,7 @@ static int mpc_read(struct mpc_i2c *i2c, int target,
+ 		    u8 * data, int length, int restart)
+ {
+ 	unsigned timeout = i2c->adap.timeout;
+-	int i;
++	int i, result;
+ 	u32 flags = restart ? CCR_RSTA : 0;
+ 
+ 	/* Start with MEN */
+@@ -221,8 +223,9 @@ static int mpc_read(struct mpc_i2c *i2c, int target,
+ 	/* Write target address byte - this time with the read flag set */
+ 	writeb((target << 1) | 1, i2c->base + MPC_I2C_DR);
+ 
+-	if (i2c_wait(i2c, timeout, 1) < 0)
+-		return -1;
++	result = i2c_wait(i2c, timeout, 1);
++	if (result < 0)
++		return result;
+ 
+ 	if (length) {
+ 		if (length == 1)
+@@ -234,8 +237,9 @@ static int mpc_read(struct mpc_i2c *i2c, int target,
+ 	}
+ 
+ 	for (i = 0; i < length; i++) {
+-		if (i2c_wait(i2c, timeout, 0) < 0)
+-			return -1;
++		result = i2c_wait(i2c, timeout, 0);
++		if (result < 0)
++			return result;
+ 
+ 		/* Generate txack on next to last byte */
+ 		if (i == length - 2)
+@@ -309,7 +313,6 @@ static struct i2c_adapter mpc_ops = {
+ 	.algo = &mpc_algo,
+ 	.class = I2C_CLASS_HWMON,
+ 	.timeout = 1,
+-	.retries = 1
+ };
+ 
+ static int fsl_i2c_probe(struct platform_device *pdev)
+@@ -321,9 +324,9 @@ static int fsl_i2c_probe(struct platform_device *pdev)
+ 
+ 	pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data;
+ 
+-	if (!(i2c = kzalloc(sizeof(*i2c), GFP_KERNEL))) {
++	i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
++	if (!i2c)
+ 		return -ENOMEM;
+-	}
+ 
+ 	i2c->irq = platform_get_irq(pdev, 0);
+ 	if (i2c->irq < 0) {
+diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
+index 1bf590c..3dac920 100644
+--- a/drivers/i2c/busses/i2c-nforce2.c
++++ b/drivers/i2c/busses/i2c-nforce2.c
+@@ -351,6 +351,7 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_
+ 	pci_set_drvdata(dev, smbuses);
+ 
+ 	switch(dev->device) {
++	case PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS:
+ 	case PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS:
+ 	case PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS:
+ 		smbuses[0].blockops = 1;
+diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
+index f2552b1..da66397 100644
+--- a/drivers/i2c/busses/i2c-omap.c
++++ b/drivers/i2c/busses/i2c-omap.c
+@@ -362,8 +362,6 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
+ 
+ 	omap_i2c_enable_clocks(dev);
+ 
+-	/* REVISIT: initialize and use adap->retries. This is an optional
+-	 * feature */
+ 	if ((r = omap_i2c_wait_for_bb(dev)) < 0)
+ 		goto out;
+ 
+diff --git a/drivers/i2c/busses/i2c-pasemi.c b/drivers/i2c/busses/i2c-pasemi.c
+index ca18e0b..1603c81 100644
+--- a/drivers/i2c/busses/i2c-pasemi.c
++++ b/drivers/i2c/busses/i2c-pasemi.c
+@@ -368,6 +368,7 @@ static int __devinit pasemi_smb_probe(struct pci_dev *dev,
+ 	smbus->adapter.class = I2C_CLASS_HWMON;
+ 	smbus->adapter.algo = &smbus_algorithm;
+ 	smbus->adapter.algo_data = smbus;
++	smbus->adapter.nr = PCI_FUNC(dev->devfn);
+ 
+ 	/* set up the sysfs linkage to our parent device */
+ 	smbus->adapter.dev.parent = &dev->dev;
+@@ -375,7 +376,7 @@ static int __devinit pasemi_smb_probe(struct pci_dev *dev,
+ 	reg_write(smbus, REG_CTL, (CTL_MTR | CTL_MRR |
+ 		  (CLK_100K_DIV & CTL_CLK_M)));
+ 
+-	error = i2c_add_adapter(&smbus->adapter);
++	error = i2c_add_numbered_adapter(&smbus->adapter);
+ 	if (error)
+ 		goto out_release_region;
+ 
+diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
+index 167e413..9bbe96c 100644
+--- a/drivers/i2c/busses/i2c-piix4.c
++++ b/drivers/i2c/busses/i2c-piix4.c
+@@ -121,10 +121,6 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
+ {
+ 	unsigned char temp;
+ 
+-	/* match up the function */
+-	if (PCI_FUNC(PIIX4_dev->devfn) != id->driver_data)
+-		return -ENODEV;
+-
+ 	dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev));
+ 
+ 	/* Don't access SMBus on IBM systems which get corrupted eeproms */
+@@ -389,28 +385,21 @@ static struct i2c_adapter piix4_adapter = {
+ };
+ 
+ static struct pci_device_id piix4_ids[] = {
+-	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3),
+-	  .driver_data = 3 },
+-	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_SMBUS),
+-	  .driver_data = 0 },
+-	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_SMBUS),
+-	  .driver_data = 0 },
+-	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS),
+-	  .driver_data = 0 },
+-	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS),
+-	  .driver_data = 0 },
+-	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4),
+-	  .driver_data = 0 },
+-	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5),
+-	  .driver_data = 0 },
+-	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6),
+-	  .driver_data = 0 },
+-	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000SB),
+-	  .driver_data = 0 },
+-	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3),
+-	  .driver_data = 3 },
+-	{ PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3),
+-	  .driver_data = 0 },
++	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3) },
++	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3) },
++	{ PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3) },
++	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_SMBUS) },
++	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_SMBUS) },
++	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS) },
++	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS) },
++	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
++		     PCI_DEVICE_ID_SERVERWORKS_OSB4) },
++	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
++		     PCI_DEVICE_ID_SERVERWORKS_CSB5) },
++	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
++		     PCI_DEVICE_ID_SERVERWORKS_CSB6) },
++	{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
++		     PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
+ 	{ 0, }
+ };
+ 
+diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
+index 6426a61..2598d29 100644
+--- a/drivers/i2c/busses/i2c-pxa.c
++++ b/drivers/i2c/busses/i2c-pxa.c
+@@ -65,6 +65,7 @@ struct pxa_i2c {
+ 	unsigned long		iosize;
+ 
+ 	int			irq;
++	int			use_pio;
+ };
+ 
+ #define _IBMR(i2c)	((i2c)->reg_base + 0)
+@@ -163,6 +164,7 @@ static void i2c_pxa_show_state(struct pxa_i2c *i2c, int lno, const char *fname)
+ #define eedbg(lvl, x...) do { if ((lvl) < 1) { printk(KERN_DEBUG "" x); } } while(0)
+ 
+ static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret);
++static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id);
+ 
+ static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
+ {
+@@ -554,6 +556,71 @@ static inline void i2c_pxa_stop_message(struct pxa_i2c *i2c)
+ 	writel(icr, _ICR(i2c));
+ }
+ 
++static int i2c_pxa_pio_set_master(struct pxa_i2c *i2c)
++{
++	/* make timeout the same as for interrupt based functions */
++	long timeout = 2 * DEF_TIMEOUT;
 +
-+err_out_unmap_bars:
-+	for (i=0; i<3; ++i)
-+		if (dev->bar[i])
-+			iounmap(dev->bar[i]);
++	/*
++	 * Wait for the bus to become free.
++	 */
++	while (timeout-- && readl(_ISR(i2c)) & (ISR_IBB | ISR_UB)) {
++		udelay(1000);
++		show_state(i2c);
++	}
 +
-+err_out_free_regions:
-+	pci_release_regions(pdev);
++	if (timeout <= 0) {
++		show_state(i2c);
++		dev_err(&i2c->adap.dev,
++			"i2c_pxa: timeout waiting for bus free\n");
++		return I2C_RETRY;
++	}
 +
-+err_out_disable_pci_device:
-+	pci_disable_device(pdev);
++	/*
++	 * Set master mode.
++	 */
++	writel(readl(_ICR(i2c)) | ICR_SCLE, _ICR(i2c));
 +
-+	return err;
++	return 0;
 +}
 +
-+static void hifn_remove(struct pci_dev *pdev)
++static int i2c_pxa_do_pio_xfer(struct pxa_i2c *i2c,
++			       struct i2c_msg *msg, int num)
 +{
-+	int i;
-+	struct hifn_device *dev;
-+
-+	dev = pci_get_drvdata(pdev);
-+
-+	if (dev) {
-+		cancel_delayed_work(&dev->work);
-+		flush_scheduled_work();
-+
-+		hifn_unregister_rng(dev);
-+		hifn_unregister_alg(dev);
-+		hifn_reset_dma(dev, 1);
-+		hifn_stop_device(dev);
++	unsigned long timeout = 500000; /* 5 seconds */
++	int ret = 0;
 +
-+		free_irq(dev->irq, dev->name);
-+		tasklet_kill(&dev->tasklet);
++	ret = i2c_pxa_pio_set_master(i2c);
++	if (ret)
++		goto out;
 +
-+		hifn_flush(dev);
++	i2c->msg = msg;
++	i2c->msg_num = num;
++	i2c->msg_idx = 0;
++	i2c->msg_ptr = 0;
++	i2c->irqlogidx = 0;
 +
-+		pci_free_consistent(pdev, sizeof(struct hifn_dma),
-+				dev->desc_virt, dev->desc_dma);
-+		pci_unmap_single(pdev, dev->dst,
-+				PAGE_SIZE << HIFN_MAX_RESULT_ORDER,
-+				PCI_DMA_FROMDEVICE);
-+		free_pages(dev->result_mem, HIFN_MAX_RESULT_ORDER);
-+		for (i=0; i<3; ++i)
-+			if (dev->bar[i])
-+				iounmap(dev->bar[i]);
++	i2c_pxa_start_message(i2c);
 +
-+		kfree(dev);
++	while (timeout-- && i2c->msg_num > 0) {
++		i2c_pxa_handler(0, i2c);
++		udelay(10);
 +	}
 +
-+	pci_release_regions(pdev);
-+	pci_disable_device(pdev);
-+}
-+
-+static struct pci_device_id hifn_pci_tbl[] = {
-+	{ PCI_DEVICE(PCI_VENDOR_ID_HIFN, PCI_DEVICE_ID_HIFN_7955) },
-+	{ PCI_DEVICE(PCI_VENDOR_ID_HIFN, PCI_DEVICE_ID_HIFN_7956) },
-+	{ 0 }
-+};
-+MODULE_DEVICE_TABLE(pci, hifn_pci_tbl);
-+
-+static struct pci_driver hifn_pci_driver = {
-+	.name     = "hifn795x",
-+	.id_table = hifn_pci_tbl,
-+	.probe    = hifn_probe,
-+	.remove   = __devexit_p(hifn_remove),
-+};
-+
-+static int __devinit hifn_init(void)
-+{
-+	unsigned int freq;
-+	int err;
-+
-+	if (strncmp(hifn_pll_ref, "ext", 3) &&
-+	    strncmp(hifn_pll_ref, "pci", 3)) {
-+		printk(KERN_ERR "hifn795x: invalid hifn_pll_ref clock, "
-+				"must be pci or ext");
-+		return -EINVAL;
-+	}
++	i2c_pxa_stop_message(i2c);
 +
 +	/*
-+	 * For the 7955/7956 the reference clock frequency must be in the
-+	 * range of 20MHz-100MHz. For the 7954 the upper bound is 66.67MHz,
-+	 * but this chip is currently not supported.
++	 * We place the return code in i2c->msg_idx.
 +	 */
-+	if (hifn_pll_ref[3] != '\0') {
-+		freq = simple_strtoul(hifn_pll_ref + 3, NULL, 10);
-+		if (freq < 20 || freq > 100) {
-+			printk(KERN_ERR "hifn795x: invalid hifn_pll_ref "
-+					"frequency, must be in the range "
-+					"of 20-100");
-+			return -EINVAL;
-+		}
-+	}
-+
-+	err = pci_register_driver(&hifn_pci_driver);
-+	if (err < 0) {
-+		dprintk("Failed to register PCI driver for %s device.\n",
-+				hifn_pci_driver.name);
-+		return -ENODEV;
-+	}
++	ret = i2c->msg_idx;
 +
-+	printk(KERN_INFO "Driver for HIFN 795x crypto accelerator chip "
-+			"has been successfully registered.\n");
++out:
++	if (timeout == 0)
++		i2c_pxa_scream_blue_murder(i2c, "timeout");
 +
-+	return 0;
++	return ret;
 +}
 +
-+static void __devexit hifn_fini(void)
+ /*
+  * We are protected by the adapter bus mutex.
+  */
+@@ -610,6 +677,35 @@ static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
+ 	return ret;
+ }
+ 
++static int i2c_pxa_pio_xfer(struct i2c_adapter *adap,
++			    struct i2c_msg msgs[], int num)
 +{
-+	pci_unregister_driver(&hifn_pci_driver);
++	struct pxa_i2c *i2c = adap->algo_data;
++	int ret, i;
 +
-+	printk(KERN_INFO "Driver for HIFN 795x crypto accelerator chip "
-+			"has been successfully unregistered.\n");
-+}
++	/* If the I2C controller is disabled we need to reset it
++	  (probably due to a suspend/resume destroying state). We do
++	  this here as we can then avoid worrying about resuming the
++	  controller before its users. */
++	if (!(readl(_ICR(i2c)) & ICR_IUE))
++		i2c_pxa_reset(i2c);
++
++	for (i = adap->retries; i >= 0; i--) {
++		ret = i2c_pxa_do_pio_xfer(i2c, msgs, num);
++		if (ret != I2C_RETRY)
++			goto out;
 +
-+module_init(hifn_init);
-+module_exit(hifn_fini);
++		if (i2c_debug)
++			dev_dbg(&adap->dev, "Retrying transmission\n");
++		udelay(100);
++	}
++	i2c_pxa_scream_blue_murder(i2c, "exhausted retries");
++	ret = -EREMOTEIO;
++ out:
++	i2c_pxa_set_slave(i2c, ret);
++	return ret;
++}
 +
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Evgeniy Polyakov <johnpol at 2ka.mipt.ru>");
-+MODULE_DESCRIPTION("Driver for HIFN 795x crypto accelerator chip.");
-diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
-index 5f7e718..2f3ad3f 100644
---- a/drivers/crypto/padlock-aes.c
-+++ b/drivers/crypto/padlock-aes.c
-@@ -44,6 +44,7 @@
+ /*
+  * i2c_pxa_master_complete - complete the message and wake up.
   */
+@@ -621,7 +717,8 @@ static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret)
+ 	i2c->msg_num = 0;
+ 	if (ret)
+ 		i2c->msg_idx = ret;
+-	wake_up(&i2c->wait);
++	if (!i2c->use_pio)
++		wake_up(&i2c->wait);
+ }
  
- #include <crypto/algapi.h>
-+#include <crypto/aes.h>
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/types.h>
-@@ -53,9 +54,6 @@
- #include <asm/byteorder.h>
- #include "padlock.h"
- 
--#define AES_MIN_KEY_SIZE	16	/* in uint8_t units */
--#define AES_MAX_KEY_SIZE	32	/* ditto */
--#define AES_BLOCK_SIZE		16	/* ditto */
- #define AES_EXTENDED_KEY_SIZE	64	/* in uint32_t units */
- #define AES_EXTENDED_KEY_SIZE_B	(AES_EXTENDED_KEY_SIZE * sizeof(uint32_t))
- 
-@@ -419,6 +417,11 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
- /* ====== Encryption/decryption routines ====== */
+ static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr)
+@@ -840,6 +937,37 @@ static const struct i2c_algorithm i2c_pxa_algorithm = {
+ 	.functionality	= i2c_pxa_functionality,
+ };
  
- /* These are the real call to PadLock. */
-+static inline void padlock_reset_key(void)
++static const struct i2c_algorithm i2c_pxa_pio_algorithm = {
++	.master_xfer	= i2c_pxa_pio_xfer,
++	.functionality	= i2c_pxa_functionality,
++};
++
++static void i2c_pxa_enable(struct platform_device *dev)
 +{
-+	asm volatile ("pushfl; popfl");
++	if (cpu_is_pxa27x()) {
++		switch (dev->id) {
++		case 0:
++			pxa_gpio_mode(GPIO117_I2CSCL_MD);
++			pxa_gpio_mode(GPIO118_I2CSDA_MD);
++			break;
++		case 1:
++			local_irq_disable();
++			PCFR |= PCFR_PI2CEN;
++			local_irq_enable();
++			break;
++		}
++	}
 +}
 +
- static inline void padlock_xcrypt(const u8 *input, u8 *output, void *key,
- 				  void *control_word)
- {
-@@ -439,8 +442,6 @@ static void aes_crypt_copy(const u8 *in, u8 *out, u32 *key, struct cword *cword)
- static inline void aes_crypt(const u8 *in, u8 *out, u32 *key,
- 			     struct cword *cword)
++static void i2c_pxa_disable(struct platform_device *dev)
++{
++	if (cpu_is_pxa27x() && dev->id == 1) {
++		local_irq_disable();
++		PCFR &= ~PCFR_PI2CEN;
++		local_irq_enable();
++	}
++}
++
+ #define res_len(r)		((r)->end - (r)->start + 1)
+ static int i2c_pxa_probe(struct platform_device *dev)
  {
--	asm volatile ("pushfl; popfl");
--
- 	/* padlock_xcrypt requires at least two blocks of data. */
- 	if (unlikely(!(((unsigned long)in ^ (PAGE_SIZE - AES_BLOCK_SIZE)) &
- 		       (PAGE_SIZE - 1)))) {
-@@ -459,7 +460,6 @@ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key,
- 		return;
+@@ -864,7 +992,6 @@ static int i2c_pxa_probe(struct platform_device *dev)
  	}
  
--	asm volatile ("pushfl; popfl");		/* enforce key reload. */
- 	asm volatile ("test $1, %%cl;"
- 		      "je 1f;"
- 		      "lea -1(%%ecx), %%eax;"
-@@ -476,8 +476,6 @@ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key,
- static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
- 				     u8 *iv, void *control_word, u32 count)
- {
--	/* Enforce key reload. */
--	asm volatile ("pushfl; popfl");
- 	/* rep xcryptcbc */
- 	asm volatile (".byte 0xf3,0x0f,0xa7,0xd0"
- 		      : "+S" (input), "+D" (output), "+a" (iv)
-@@ -488,12 +486,14 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
- static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
- {
- 	struct aes_ctx *ctx = aes_ctx(tfm);
-+	padlock_reset_key();
- 	aes_crypt(in, out, ctx->E, &ctx->cword.encrypt);
- }
- 
- static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
- {
- 	struct aes_ctx *ctx = aes_ctx(tfm);
-+	padlock_reset_key();
- 	aes_crypt(in, out, ctx->D, &ctx->cword.decrypt);
- }
- 
-@@ -526,6 +526,8 @@ static int ecb_aes_encrypt(struct blkcipher_desc *desc,
- 	struct blkcipher_walk walk;
- 	int err;
+ 	i2c->adap.owner   = THIS_MODULE;
+-	i2c->adap.algo    = &i2c_pxa_algorithm;
+ 	i2c->adap.retries = 5;
  
-+	padlock_reset_key();
-+
- 	blkcipher_walk_init(&walk, dst, src, nbytes);
- 	err = blkcipher_walk_virt(desc, &walk);
+ 	spin_lock_init(&i2c->lock);
+@@ -899,34 +1026,28 @@ static int i2c_pxa_probe(struct platform_device *dev)
+ #endif
  
-@@ -548,6 +550,8 @@ static int ecb_aes_decrypt(struct blkcipher_desc *desc,
- 	struct blkcipher_walk walk;
- 	int err;
+ 	clk_enable(i2c->clk);
+-#ifdef CONFIG_PXA27x
+-	switch (dev->id) {
+-	case 0:
+-		pxa_gpio_mode(GPIO117_I2CSCL_MD);
+-		pxa_gpio_mode(GPIO118_I2CSDA_MD);
+-		break;
+-	case 1:
+-		local_irq_disable();
+-		PCFR |= PCFR_PI2CEN;
+-		local_irq_enable();
+-	}
+-#endif
++	i2c_pxa_enable(dev);
  
-+	padlock_reset_key();
-+
- 	blkcipher_walk_init(&walk, dst, src, nbytes);
- 	err = blkcipher_walk_virt(desc, &walk);
+-	ret = request_irq(irq, i2c_pxa_handler, IRQF_DISABLED,
+-			  i2c->adap.name, i2c);
+-	if (ret)
+-		goto ereqirq;
++	if (plat) {
++		i2c->adap.class = plat->class;
++		i2c->use_pio = plat->use_pio;
++	}
  
-@@ -592,6 +596,8 @@ static int cbc_aes_encrypt(struct blkcipher_desc *desc,
- 	struct blkcipher_walk walk;
- 	int err;
++	if (i2c->use_pio) {
++		i2c->adap.algo = &i2c_pxa_pio_algorithm;
++	} else {
++		i2c->adap.algo = &i2c_pxa_algorithm;
++		ret = request_irq(irq, i2c_pxa_handler, IRQF_DISABLED,
++				  i2c->adap.name, i2c);
++		if (ret)
++			goto ereqirq;
++	}
  
-+	padlock_reset_key();
-+
- 	blkcipher_walk_init(&walk, dst, src, nbytes);
- 	err = blkcipher_walk_virt(desc, &walk);
+ 	i2c_pxa_reset(i2c);
  
-@@ -616,6 +622,8 @@ static int cbc_aes_decrypt(struct blkcipher_desc *desc,
- 	struct blkcipher_walk walk;
- 	int err;
+ 	i2c->adap.algo_data = i2c;
+ 	i2c->adap.dev.parent = &dev->dev;
  
-+	padlock_reset_key();
-+
- 	blkcipher_walk_init(&walk, dst, src, nbytes);
- 	err = blkcipher_walk_virt(desc, &walk);
+-	if (plat) {
+-		i2c->adap.class = plat->class;
+-	}
+-
+ 	/*
+ 	 * If "dev->id" is negative we consider it as zero.
+ 	 * The reason to do so is to avoid sysfs names that only make
+@@ -952,17 +1073,11 @@ static int i2c_pxa_probe(struct platform_device *dev)
+ 	return 0;
  
-diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
-index d59b2f4..bcf52df 100644
---- a/drivers/dma/dmaengine.c
-+++ b/drivers/dma/dmaengine.c
-@@ -41,12 +41,12 @@
-  * the definition of dma_event_callback in dmaengine.h.
-  *
-  * Each device has a kref, which is initialized to 1 when the device is
-- * registered. A kref_get is done for each class_device registered.  When the
-- * class_device is released, the coresponding kref_put is done in the release
-+ * registered. A kref_get is done for each device registered.  When the
-+ * device is released, the coresponding kref_put is done in the release
-  * method. Every time one of the device's channels is allocated to a client,
-  * a kref_get occurs.  When the channel is freed, the coresponding kref_put
-  * happens. The device's release function does a completion, so
-- * unregister_device does a remove event, class_device_unregister, a kref_put
-+ * unregister_device does a remove event, device_unregister, a kref_put
-  * for the first reference, then waits on the completion for all other
-  * references to finish.
-  *
-@@ -77,9 +77,9 @@ static LIST_HEAD(dma_client_list);
+ eadapt:
+-	free_irq(irq, i2c);
++	if (!i2c->use_pio)
++		free_irq(irq, i2c);
+ ereqirq:
+ 	clk_disable(i2c->clk);
+-
+-#ifdef CONFIG_PXA27x
+-	if (dev->id == 1) {
+-		local_irq_disable();
+-		PCFR &= ~PCFR_PI2CEN;
+-		local_irq_enable();
+-	}
+-#endif
++	i2c_pxa_disable(dev);
+ eremap:
+ 	clk_put(i2c->clk);
+ eclk:
+@@ -979,18 +1094,12 @@ static int i2c_pxa_remove(struct platform_device *dev)
+ 	platform_set_drvdata(dev, NULL);
+ 
+ 	i2c_del_adapter(&i2c->adap);
+-	free_irq(i2c->irq, i2c);
++	if (!i2c->use_pio)
++		free_irq(i2c->irq, i2c);
  
- /* --- sysfs implementation --- */
+ 	clk_disable(i2c->clk);
+ 	clk_put(i2c->clk);
+-
+-#ifdef CONFIG_PXA27x
+-	if (dev->id == 1) {
+-		local_irq_disable();
+-		PCFR &= ~PCFR_PI2CEN;
+-		local_irq_enable();
+-	}
+-#endif
++	i2c_pxa_disable(dev);
  
--static ssize_t show_memcpy_count(struct class_device *cd, char *buf)
-+static ssize_t show_memcpy_count(struct device *dev, struct device_attribute *attr, char *buf)
- {
--	struct dma_chan *chan = container_of(cd, struct dma_chan, class_dev);
-+	struct dma_chan *chan = to_dma_chan(dev);
- 	unsigned long count = 0;
- 	int i;
+ 	release_mem_region(i2c->iobase, i2c->iosize);
+ 	kfree(i2c);
+diff --git a/drivers/i2c/busses/i2c-sibyte.c b/drivers/i2c/busses/i2c-sibyte.c
+index 503a134..8fbbdb4 100644
+--- a/drivers/i2c/busses/i2c-sibyte.c
++++ b/drivers/i2c/busses/i2c-sibyte.c
+@@ -36,14 +36,6 @@ struct i2c_algo_sibyte_data {
+ /* ----- global defines ----------------------------------------------- */
+ #define SMB_CSR(a,r) ((long)(a->reg_base + r))
  
-@@ -89,9 +89,10 @@ static ssize_t show_memcpy_count(struct class_device *cd, char *buf)
- 	return sprintf(buf, "%lu\n", count);
- }
+-/* ----- global variables --------------------------------------------- */
+-
+-/* module parameters:
+- */
+-static int bit_scan;	/* have a look at what's hanging 'round */
+-module_param(bit_scan, int, 0);
+-MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus");
+-
  
--static ssize_t show_bytes_transferred(struct class_device *cd, char *buf)
-+static ssize_t show_bytes_transferred(struct device *dev, struct device_attribute *attr,
-+				      char *buf)
+ static int smbus_xfer(struct i2c_adapter *i2c_adap, u16 addr,
+ 		      unsigned short flags, char read_write,
+@@ -140,9 +132,8 @@ static const struct i2c_algorithm i2c_sibyte_algo = {
+ /*
+  * registering functions to load algorithms at runtime
+  */
+-int i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed)
++int __init i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed)
  {
--	struct dma_chan *chan = container_of(cd, struct dma_chan, class_dev);
-+	struct dma_chan *chan = to_dma_chan(dev);
- 	unsigned long count = 0;
- 	int i;
+-	int i;
+ 	struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data;
  
-@@ -101,9 +102,9 @@ static ssize_t show_bytes_transferred(struct class_device *cd, char *buf)
- 	return sprintf(buf, "%lu\n", count);
+ 	/* register new adapter to i2c module... */
+@@ -152,24 +143,6 @@ int i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed)
+ 	csr_out32(speed, SMB_CSR(adap,R_SMB_FREQ));
+ 	csr_out32(0, SMB_CSR(adap,R_SMB_CONTROL));
+ 
+-	/* scan bus */
+-	if (bit_scan) {
+-		union i2c_smbus_data data;
+-		int rc;
+-		printk(KERN_INFO " i2c-algo-sibyte.o: scanning bus %s.\n",
+-		       i2c_adap->name);
+-		for (i = 0x00; i < 0x7f; i++) {
+-			/* XXXKW is this a realistic probe? */
+-			rc = smbus_xfer(i2c_adap, i, 0, I2C_SMBUS_READ, 0,
+-					I2C_SMBUS_BYTE_DATA, &data);
+-			if (!rc) {
+-				printk("(%02x)",i);
+-			} else
+-				printk(".");
+-		}
+-		printk("\n");
+-	}
+-
+ 	return i2c_add_adapter(i2c_adap);
  }
  
--static ssize_t show_in_use(struct class_device *cd, char *buf)
-+static ssize_t show_in_use(struct device *dev, struct device_attribute *attr, char *buf)
- {
--	struct dma_chan *chan = container_of(cd, struct dma_chan, class_dev);
-+	struct dma_chan *chan = to_dma_chan(dev);
- 	int in_use = 0;
+diff --git a/drivers/i2c/busses/i2c-stub.c b/drivers/i2c/busses/i2c-stub.c
+index 84df29d..c2a9f8c 100644
+--- a/drivers/i2c/busses/i2c-stub.c
++++ b/drivers/i2c/busses/i2c-stub.c
+@@ -1,8 +1,8 @@
+ /*
+-    i2c-stub.c - Part of lm_sensors, Linux kernel modules for hardware
+-              monitoring
++    i2c-stub.c - I2C/SMBus chip emulator
+ 
+     Copyright (c) 2004 Mark M. Hoffman <mhoffman at lightlink.com>
++    Copyright (C) 2007 Jean Delvare <khali at linux-fr.org>
+ 
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+@@ -37,8 +37,8 @@ MODULE_PARM_DESC(chip_addr,
+ 
+ struct stub_chip {
+ 	u8 pointer;
+-	u8 bytes[256];
+-	u16 words[256];
++	u16 words[256];		/* Byte operations use the LSB as per SMBus
++				   specification */
+ };
+ 
+ static struct stub_chip *stub_chips;
+@@ -75,7 +75,7 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags,
+ 					"wrote 0x%02x.\n",
+ 					addr, command);
+ 		} else {
+-			data->byte = chip->bytes[chip->pointer++];
++			data->byte = chip->words[chip->pointer++] & 0xff;
+ 			dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, "
+ 					"read  0x%02x.\n",
+ 					addr, data->byte);
+@@ -86,12 +86,13 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags,
+ 
+ 	case I2C_SMBUS_BYTE_DATA:
+ 		if (read_write == I2C_SMBUS_WRITE) {
+-			chip->bytes[command] = data->byte;
++			chip->words[command] &= 0xff00;
++			chip->words[command] |= data->byte;
+ 			dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, "
+ 					"wrote 0x%02x at 0x%02x.\n",
+ 					addr, data->byte, command);
+ 		} else {
+-			data->byte = chip->bytes[command];
++			data->byte = chip->words[command] & 0xff;
+ 			dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, "
+ 					"read  0x%02x at 0x%02x.\n",
+ 					addr, data->byte, command);
+diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
+index c9ce77f..77b13d0 100644
+--- a/drivers/i2c/busses/i2c-viapro.c
++++ b/drivers/i2c/busses/i2c-viapro.c
+@@ -4,7 +4,7 @@
+     Copyright (c) 1998 - 2002  Frodo Looijaard <frodol at dds.nl>,
+     Philip Edelbrock <phil at netroedge.com>, Kyösti Mälkki <kmalkki at cc.hut.fi>,
+     Mark D. Studebaker <mdsxyz123 at yahoo.com>
+-    Copyright (C) 2005 - 2007  Jean Delvare <khali at linux-fr.org>
++    Copyright (C) 2005 - 2008  Jean Delvare <khali at linux-fr.org>
  
- 	if (unlikely(chan->slow_ref) &&
-@@ -119,7 +120,7 @@ static ssize_t show_in_use(struct class_device *cd, char *buf)
- 	return sprintf(buf, "%d\n", in_use);
- }
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+@@ -35,6 +35,7 @@
+    VT8235             0x3177             yes
+    VT8237R            0x3227             yes
+    VT8237A            0x3337             yes
++   VT8237S            0x3372             yes
+    VT8251             0x3287             yes
+    CX700              0x8324             yes
+ 
+@@ -318,6 +319,10 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
+ 	unsigned char temp;
+ 	int error = -ENODEV;
+ 
++	/* driver_data might come from user-space, so check it */
++	if (id->driver_data & 1 || id->driver_data > 0xff)
++		return -EINVAL;
++
+ 	/* Determine the address of the SMBus areas */
+ 	if (force_addr) {
+ 		vt596_smba = force_addr & 0xfff0;
+@@ -389,6 +394,7 @@ found:
+ 	case PCI_DEVICE_ID_VIA_8251:
+ 	case PCI_DEVICE_ID_VIA_8237:
+ 	case PCI_DEVICE_ID_VIA_8237A:
++	case PCI_DEVICE_ID_VIA_8237S:
+ 	case PCI_DEVICE_ID_VIA_8235:
+ 	case PCI_DEVICE_ID_VIA_8233A:
+ 	case PCI_DEVICE_ID_VIA_8233_0:
+@@ -440,6 +446,8 @@ static struct pci_device_id vt596_ids[] = {
+ 	  .driver_data = SMBBA3 },
+ 	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237A),
+ 	  .driver_data = SMBBA3 },
++	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237S),
++	  .driver_data = SMBBA3 },
+ 	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4),
+ 	  .driver_data = SMBBA1 },
+ 	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8251),
+@@ -455,6 +463,7 @@ static struct pci_driver vt596_driver = {
+ 	.name		= "vt596_smbus",
+ 	.id_table	= vt596_ids,
+ 	.probe		= vt596_probe,
++	.dynids.use_driver_data = 1,
+ };
+ 
+ static int __init i2c_vt596_init(void)
+diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
+index 2e1c24f..bd7082c 100644
+--- a/drivers/i2c/chips/Kconfig
++++ b/drivers/i2c/chips/Kconfig
+@@ -4,32 +4,6 @@
+ 
+ menu "Miscellaneous I2C Chip support"
+ 
+-config SENSORS_DS1337
+-	tristate "Dallas DS1337 and DS1339 Real Time Clock (DEPRECATED)"
+-	depends on EXPERIMENTAL
+-	help
+-	  If you say yes here you get support for Dallas Semiconductor
+-	  DS1337 and DS1339 real-time clock chips.
+-
+-	  This driver can also be built as a module.  If so, the module
+-	  will be called ds1337.
+-
+-	  This driver is deprecated and will be dropped soon. Use
+-	  rtc-ds1307 instead.
+-
+-config SENSORS_DS1374
+-	tristate "Dallas DS1374 Real Time Clock (DEPRECATED)"
+-	depends on EXPERIMENTAL
+-	help
+-	  If you say yes here you get support for Dallas Semiconductor
+-	  DS1374 real-time clock chips.
+-
+-	  This driver can also be built as a module.  If so, the module
+-	  will be called ds1374.
+-
+-	  This driver is deprecated and will be dropped soon. Use
+-	  rtc-ds1374 instead.
+-
+ config DS1682
+ 	tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm"
+ 	depends on EXPERIMENTAL
+@@ -57,7 +31,7 @@ config SENSORS_PCF8574
+ 	default n
+ 	help
+ 	  If you say yes here you get support for Philips PCF8574 and 
+-	  PCF8574A chips.
++	  PCF8574A chips. These chips are 8-bit I/O expanders for the I2C bus.
+ 
+ 	  This driver can also be built as a module.  If so, the module
+ 	  will be called pcf8574.
+@@ -65,6 +39,20 @@ config SENSORS_PCF8574
+ 	  These devices are hard to detect and rarely found on mainstream
+ 	  hardware.  If unsure, say N.
  
--static struct class_device_attribute dma_class_attrs[] = {
-+static struct device_attribute dma_attrs[] = {
- 	__ATTR(memcpy_count, S_IRUGO, show_memcpy_count, NULL),
- 	__ATTR(bytes_transferred, S_IRUGO, show_bytes_transferred, NULL),
- 	__ATTR(in_use, S_IRUGO, show_in_use, NULL),
-@@ -128,16 +129,16 @@ static struct class_device_attribute dma_class_attrs[] = {
++config PCF8575
++	tristate "Philips PCF8575"
++	default n
++	help
++	  If you say yes here you get support for Philips PCF8575 chip.
++	  This chip is a 16-bit I/O expander for the I2C bus.  Several other
++	  chip manufacturers sell equivalent chips, e.g. Texas Instruments.
++
++	  This driver can also be built as a module.  If so, the module
++	  will be called pcf8575.
++
++	  This device is hard to detect and is rarely found on mainstream
++	  hardware.  If unsure, say N.
++
+ config SENSORS_PCA9539
+ 	tristate "Philips PCA9539 16-bit I/O port"
+ 	depends on EXPERIMENTAL
+@@ -100,12 +88,8 @@ config ISP1301_OMAP
+ 	  This driver can also be built as a module.  If so, the module
+ 	  will be called isp1301_omap.
+ 
+-# NOTE:  This isn't really OMAP-specific, except for the current
+-# interface location in  <include/asm-arm/arch-omap/tps65010.h>
+-# and having mostly OMAP-specific board support
+ config TPS65010
+ 	tristate "TPS6501x Power Management chips"
+-	depends on ARCH_OMAP
+ 	default y if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_OSK
+ 	help
+ 	  If you say yes here you get support for the TPS6501x series of
+@@ -116,18 +100,6 @@ config TPS65010
+ 	  This driver can also be built as a module.  If so, the module
+ 	  will be called tps65010.
+ 
+-config SENSORS_M41T00
+-	tristate "ST M41T00 RTC chip (DEPRECATED)"
+-	depends on PPC32
+-	help
+-	  If you say yes here you get support for the ST M41T00 RTC chip.
+-
+-	  This driver can also be built as a module.  If so, the module
+-	  will be called m41t00.
+-
+-	  This driver is deprecated and will be dropped soon. Use
+-	  rtc-ds1307 or rtc-m41t80 instead.
+-
+ config SENSORS_MAX6875
+ 	tristate "Maxim MAX6875 Power supply supervisor"
+ 	depends on EXPERIMENTAL
+diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
+index ca924e1..501f00c 100644
+--- a/drivers/i2c/chips/Makefile
++++ b/drivers/i2c/chips/Makefile
+@@ -2,14 +2,12 @@
+ # Makefile for miscellaneous I2C chip drivers.
+ #
  
- static void dma_async_device_cleanup(struct kref *kref);
+-obj-$(CONFIG_SENSORS_DS1337)	+= ds1337.o
+-obj-$(CONFIG_SENSORS_DS1374)	+= ds1374.o
+ obj-$(CONFIG_DS1682)		+= ds1682.o
+ obj-$(CONFIG_SENSORS_EEPROM)	+= eeprom.o
+ obj-$(CONFIG_SENSORS_MAX6875)	+= max6875.o
+-obj-$(CONFIG_SENSORS_M41T00)	+= m41t00.o
+ obj-$(CONFIG_SENSORS_PCA9539)	+= pca9539.o
+ obj-$(CONFIG_SENSORS_PCF8574)	+= pcf8574.o
++obj-$(CONFIG_PCF8575)		+= pcf8575.o
+ obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
+ obj-$(CONFIG_ISP1301_OMAP)	+= isp1301_omap.o
+ obj-$(CONFIG_TPS65010)		+= tps65010.o
+diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c
+deleted file mode 100644
+index ec17d6b..0000000
+--- a/drivers/i2c/chips/ds1337.c
++++ /dev/null
+@@ -1,410 +0,0 @@
+-/*
+- *  linux/drivers/i2c/chips/ds1337.c
+- *
+- *  Copyright (C) 2005 James Chapman <jchapman at katalix.com>
+- *
+- *	based on linux/drivers/acorn/char/pcf8583.c
+- *  Copyright (C) 2000 Russell King
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License version 2 as
+- * published by the Free Software Foundation.
+- *
+- * Driver for Dallas Semiconductor DS1337 and DS1339 real time clock chip
+- */
+-
+-#include <linux/module.h>
+-#include <linux/init.h>
+-#include <linux/slab.h>
+-#include <linux/i2c.h>
+-#include <linux/string.h>
+-#include <linux/rtc.h>		/* get the user-level API */
+-#include <linux/bcd.h>
+-#include <linux/list.h>
+-
+-/* Device registers */
+-#define DS1337_REG_HOUR		2
+-#define DS1337_REG_DAY		3
+-#define DS1337_REG_DATE		4
+-#define DS1337_REG_MONTH	5
+-#define DS1337_REG_CONTROL	14
+-#define DS1337_REG_STATUS	15
+-
+-/* FIXME - how do we export these interface constants? */
+-#define DS1337_GET_DATE		0
+-#define DS1337_SET_DATE		1
+-
+-/*
+- * Functions declaration
+- */
+-static unsigned short normal_i2c[] = { 0x68, I2C_CLIENT_END };
+-
+-I2C_CLIENT_INSMOD_1(ds1337);
+-
+-static int ds1337_attach_adapter(struct i2c_adapter *adapter);
+-static int ds1337_detect(struct i2c_adapter *adapter, int address, int kind);
+-static void ds1337_init_client(struct i2c_client *client);
+-static int ds1337_detach_client(struct i2c_client *client);
+-static int ds1337_command(struct i2c_client *client, unsigned int cmd,
+-			  void *arg);
+-
+-/*
+- * Driver data (common to all clients)
+- */
+-static struct i2c_driver ds1337_driver = {
+-	.driver = {
+-		.name	= "ds1337",
+-	},
+-	.attach_adapter	= ds1337_attach_adapter,
+-	.detach_client	= ds1337_detach_client,
+-	.command	= ds1337_command,
+-};
+-
+-/*
+- * Client data (each client gets its own)
+- */
+-struct ds1337_data {
+-	struct i2c_client client;
+-	struct list_head list;
+-};
+-
+-/*
+- * Internal variables
+- */
+-static LIST_HEAD(ds1337_clients);
+-
+-static inline int ds1337_read(struct i2c_client *client, u8 reg, u8 *value)
+-{
+-	s32 tmp = i2c_smbus_read_byte_data(client, reg);
+-
+-	if (tmp < 0)
+-		return -EIO;
+-
+-	*value = tmp;
+-
+-	return 0;
+-}
+-
+-/*
+- * Chip access functions
+- */
+-static int ds1337_get_datetime(struct i2c_client *client, struct rtc_time *dt)
+-{
+-	int result;
+-	u8 buf[7];
+-	u8 val;
+-	struct i2c_msg msg[2];
+-	u8 offs = 0;
+-
+-	if (!dt) {
+-		dev_dbg(&client->dev, "%s: EINVAL: dt=NULL\n", __FUNCTION__);
+-		return -EINVAL;
+-	}
+-
+-	msg[0].addr = client->addr;
+-	msg[0].flags = 0;
+-	msg[0].len = 1;
+-	msg[0].buf = &offs;
+-
+-	msg[1].addr = client->addr;
+-	msg[1].flags = I2C_M_RD;
+-	msg[1].len = sizeof(buf);
+-	msg[1].buf = &buf[0];
+-
+-	result = i2c_transfer(client->adapter, msg, 2);
+-
+-	dev_dbg(&client->dev, "%s: [%d] %02x %02x %02x %02x %02x %02x %02x\n",
+-		__FUNCTION__, result, buf[0], buf[1], buf[2], buf[3],
+-		buf[4], buf[5], buf[6]);
+-
+-	if (result == 2) {
+-		dt->tm_sec = BCD2BIN(buf[0]);
+-		dt->tm_min = BCD2BIN(buf[1]);
+-		val = buf[2] & 0x3f;
+-		dt->tm_hour = BCD2BIN(val);
+-		dt->tm_wday = BCD2BIN(buf[3]) - 1;
+-		dt->tm_mday = BCD2BIN(buf[4]);
+-		val = buf[5] & 0x7f;
+-		dt->tm_mon = BCD2BIN(val) - 1;
+-		dt->tm_year = BCD2BIN(buf[6]);
+-		if (buf[5] & 0x80)
+-			dt->tm_year += 100;
+-
+-		dev_dbg(&client->dev, "%s: secs=%d, mins=%d, "
+-			"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
+-			__FUNCTION__, dt->tm_sec, dt->tm_min,
+-			dt->tm_hour, dt->tm_mday,
+-			dt->tm_mon, dt->tm_year, dt->tm_wday);
+-
+-		return 0;
+-	}
+-
+-	dev_err(&client->dev, "error reading data! %d\n", result);
+-	return -EIO;
+-}
+-
+-static int ds1337_set_datetime(struct i2c_client *client, struct rtc_time *dt)
+-{
+-	int result;
+-	u8 buf[8];
+-	u8 val;
+-	struct i2c_msg msg[1];
+-
+-	if (!dt) {
+-		dev_dbg(&client->dev, "%s: EINVAL: dt=NULL\n", __FUNCTION__);
+-		return -EINVAL;
+-	}
+-
+-	dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
+-		"mday=%d, mon=%d, year=%d, wday=%d\n", __FUNCTION__,
+-		dt->tm_sec, dt->tm_min, dt->tm_hour,
+-		dt->tm_mday, dt->tm_mon, dt->tm_year, dt->tm_wday);
+-
+-	buf[0] = 0;		/* reg offset */
+-	buf[1] = BIN2BCD(dt->tm_sec);
+-	buf[2] = BIN2BCD(dt->tm_min);
+-	buf[3] = BIN2BCD(dt->tm_hour);
+-	buf[4] = BIN2BCD(dt->tm_wday + 1);
+-	buf[5] = BIN2BCD(dt->tm_mday);
+-	buf[6] = BIN2BCD(dt->tm_mon + 1);
+-	val = dt->tm_year;
+-	if (val >= 100) {
+-		val -= 100;
+-		buf[6] |= (1 << 7);
+-	}
+-	buf[7] = BIN2BCD(val);
+-
+-	msg[0].addr = client->addr;
+-	msg[0].flags = 0;
+-	msg[0].len = sizeof(buf);
+-	msg[0].buf = &buf[0];
+-
+-	result = i2c_transfer(client->adapter, msg, 1);
+-	if (result == 1)
+-		return 0;
+-
+-	dev_err(&client->dev, "error writing data! %d\n", result);
+-	return -EIO;
+-}
+-
+-static int ds1337_command(struct i2c_client *client, unsigned int cmd,
+-			  void *arg)
+-{
+-	dev_dbg(&client->dev, "%s: cmd=%d\n", __FUNCTION__, cmd);
+-
+-	switch (cmd) {
+-	case DS1337_GET_DATE:
+-		return ds1337_get_datetime(client, arg);
+-
+-	case DS1337_SET_DATE:
+-		return ds1337_set_datetime(client, arg);
+-
+-	default:
+-		return -EINVAL;
+-	}
+-}
+-
+-/*
+- * Public API for access to specific device. Useful for low-level
+- * RTC access from kernel code.
+- */
+-int ds1337_do_command(int bus, int cmd, void *arg)
+-{
+-	struct list_head *walk;
+-	struct list_head *tmp;
+-	struct ds1337_data *data;
+-
+-	list_for_each_safe(walk, tmp, &ds1337_clients) {
+-		data = list_entry(walk, struct ds1337_data, list);
+-		if (data->client.adapter->nr == bus)
+-			return ds1337_command(&data->client, cmd, arg);
+-	}
+-
+-	return -ENODEV;
+-}
+-
+-static int ds1337_attach_adapter(struct i2c_adapter *adapter)
+-{
+-	return i2c_probe(adapter, &addr_data, ds1337_detect);
+-}
+-
+-/*
+- * The following function does more than just detection. If detection
+- * succeeds, it also registers the new chip.
+- */
+-static int ds1337_detect(struct i2c_adapter *adapter, int address, int kind)
+-{
+-	struct i2c_client *new_client;
+-	struct ds1337_data *data;
+-	int err = 0;
+-	const char *name = "";
+-
+-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
+-				     I2C_FUNC_I2C))
+-		goto exit;
+-
+-	if (!(data = kzalloc(sizeof(struct ds1337_data), GFP_KERNEL))) {
+-		err = -ENOMEM;
+-		goto exit;
+-	}
+-	INIT_LIST_HEAD(&data->list);
+-
+-	/* The common I2C client data is placed right before the
+-	 * DS1337-specific data. 
+-	 */
+-	new_client = &data->client;
+-	i2c_set_clientdata(new_client, data);
+-	new_client->addr = address;
+-	new_client->adapter = adapter;
+-	new_client->driver = &ds1337_driver;
+-	new_client->flags = 0;
+-
+-	/*
+-	 * Now we do the remaining detection. A negative kind means that
+-	 * the driver was loaded with no force parameter (default), so we
+-	 * must both detect and identify the chip. A zero kind means that
+-	 * the driver was loaded with the force parameter, the detection
+-	 * step shall be skipped. A positive kind means that the driver
+-	 * was loaded with the force parameter and a given kind of chip is
+-	 * requested, so both the detection and the identification steps
+-	 * are skipped.
+-	 *
+-	 * For detection, we read registers that are most likely to cause
+-	 * detection failure, i.e. those that have more bits with fixed
+-	 * or reserved values.
+-	 */
+-
+-	/* Default to an DS1337 if forced */
+-	if (kind == 0)
+-		kind = ds1337;
+-
+-	if (kind < 0) {		/* detection and identification */
+-		u8 data;
+-
+-		/* Check that status register bits 6-2 are zero */
+-		if ((ds1337_read(new_client, DS1337_REG_STATUS, &data) < 0) ||
+-		    (data & 0x7c))
+-			goto exit_free;
+-
+-		/* Check for a valid day register value */
+-		if ((ds1337_read(new_client, DS1337_REG_DAY, &data) < 0) ||
+-		    (data == 0) || (data & 0xf8))
+-			goto exit_free;
+-
+-		/* Check for a valid date register value */
+-		if ((ds1337_read(new_client, DS1337_REG_DATE, &data) < 0) ||
+-		    (data == 0) || (data & 0xc0) || ((data & 0x0f) > 9) ||
+-		    (data >= 0x32))
+-			goto exit_free;
+-
+-		/* Check for a valid month register value */
+-		if ((ds1337_read(new_client, DS1337_REG_MONTH, &data) < 0) ||
+-		    (data == 0) || (data & 0x60) || ((data & 0x0f) > 9) ||
+-		    ((data >= 0x13) && (data <= 0x19)))
+-			goto exit_free;
+-
+-		/* Check that control register bits 6-5 are zero */
+-		if ((ds1337_read(new_client, DS1337_REG_CONTROL, &data) < 0) ||
+-		    (data & 0x60))
+-			goto exit_free;
+-
+-		kind = ds1337;
+-	}
+-
+-	if (kind == ds1337)
+-		name = "ds1337";
+-
+-	/* We can fill in the remaining client fields */
+-	strlcpy(new_client->name, name, I2C_NAME_SIZE);
+-
+-	/* Tell the I2C layer a new client has arrived */
+-	if ((err = i2c_attach_client(new_client)))
+-		goto exit_free;
+-
+-	/* Initialize the DS1337 chip */
+-	ds1337_init_client(new_client);
+-
+-	/* Add client to local list */
+-	list_add(&data->list, &ds1337_clients);
+-
+-	return 0;
+-
+-exit_free:
+-	kfree(data);
+-exit:
+-	return err;
+-}
+-
+-static void ds1337_init_client(struct i2c_client *client)
+-{
+-	u8 status, control;
+-
+-	/* On some boards, the RTC isn't configured by boot firmware.
+-	 * Handle that case by starting/configuring the RTC now.
+-	 */
+-	status = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS);
+-	control = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
+-
+-	if ((status & 0x80) || (control & 0x80)) {
+-		/* RTC not running */
+-		u8 buf[1+16];	/* First byte is interpreted as address */
+-		struct i2c_msg msg[1];
+-
+-		dev_dbg(&client->dev, "%s: RTC not running!\n", __FUNCTION__);
+-
+-		/* Initialize all, including STATUS and CONTROL to zero */
+-		memset(buf, 0, sizeof(buf));
+-
+-		/* Write valid values in the date/time registers */
+-		buf[1+DS1337_REG_DAY] = 1;
+-		buf[1+DS1337_REG_DATE] = 1;
+-		buf[1+DS1337_REG_MONTH] = 1;
+-
+-		msg[0].addr = client->addr;
+-		msg[0].flags = 0;
+-		msg[0].len = sizeof(buf);
+-		msg[0].buf = &buf[0];
+-
+-		i2c_transfer(client->adapter, msg, 1);
+-	} else {
+-		/* Running: ensure that device is set in 24-hour mode */
+-		s32 val;
+-
+-		val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR);
+-		if ((val >= 0) && (val & (1 << 6)))
+-			i2c_smbus_write_byte_data(client, DS1337_REG_HOUR,
+-						  val & 0x3f);
+-	}
+-}
+-
+-static int ds1337_detach_client(struct i2c_client *client)
+-{
+-	int err;
+-	struct ds1337_data *data = i2c_get_clientdata(client);
+-
+-	if ((err = i2c_detach_client(client)))
+-		return err;
+-
+-	list_del(&data->list);
+-	kfree(data);
+-	return 0;
+-}
+-
+-static int __init ds1337_init(void)
+-{
+-	return i2c_add_driver(&ds1337_driver);
+-}
+-
+-static void __exit ds1337_exit(void)
+-{
+-	i2c_del_driver(&ds1337_driver);
+-}
+-
+-MODULE_AUTHOR("James Chapman <jchapman at katalix.com>");
+-MODULE_DESCRIPTION("DS1337 RTC driver");
+-MODULE_LICENSE("GPL");
+-
+-EXPORT_SYMBOL_GPL(ds1337_do_command);
+-
+-module_init(ds1337_init);
+-module_exit(ds1337_exit);
+diff --git a/drivers/i2c/chips/ds1374.c b/drivers/i2c/chips/ds1374.c
+deleted file mode 100644
+index 8a2ff0c..0000000
+--- a/drivers/i2c/chips/ds1374.c
++++ /dev/null
+@@ -1,267 +0,0 @@
+-/*
+- * drivers/i2c/chips/ds1374.c
+- *
+- * I2C client/driver for the Maxim/Dallas DS1374 Real-Time Clock
+- *
+- * Author: Randy Vinson <rvinson at mvista.com>
+- *
+- * Based on the m41t00.c by Mark Greer <mgreer at mvista.com>
+- *
+- * 2005 (c) MontaVista Software, Inc. This file is licensed under
+- * the terms of the GNU General Public License version 2. This program
+- * is licensed "as is" without any warranty of any kind, whether express
+- * or implied.
+- */
+-/*
+- * This i2c client/driver wedges between the drivers/char/genrtc.c RTC
+- * interface and the SMBus interface of the i2c subsystem.
+- * It would be more efficient to use i2c msgs/i2c_transfer directly but, as
+- * recommened in .../Documentation/i2c/writing-clients section
+- * "Sending and receiving", using SMBus level communication is preferred.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <linux/interrupt.h>
+-#include <linux/i2c.h>
+-#include <linux/rtc.h>
+-#include <linux/bcd.h>
+-#include <linux/mutex.h>
+-#include <linux/workqueue.h>
+-
+-#define DS1374_REG_TOD0		0x00
+-#define DS1374_REG_TOD1		0x01
+-#define DS1374_REG_TOD2		0x02
+-#define DS1374_REG_TOD3		0x03
+-#define DS1374_REG_WDALM0	0x04
+-#define DS1374_REG_WDALM1	0x05
+-#define DS1374_REG_WDALM2	0x06
+-#define DS1374_REG_CR		0x07
+-#define DS1374_REG_SR		0x08
+-#define DS1374_REG_SR_OSF	0x80
+-#define DS1374_REG_TCR		0x09
+-
+-#define	DS1374_DRV_NAME		"ds1374"
+-
+-static DEFINE_MUTEX(ds1374_mutex);
+-
+-static struct i2c_driver ds1374_driver;
+-static struct i2c_client *save_client;
+-
+-static unsigned short ignore[] = { I2C_CLIENT_END };
+-static unsigned short normal_addr[] = { 0x68, I2C_CLIENT_END };
+-
+-static struct i2c_client_address_data addr_data = {
+-	.normal_i2c = normal_addr,
+-	.probe = ignore,
+-	.ignore = ignore,
+-};
+-
+-static ulong ds1374_read_rtc(void)
+-{
+-	ulong time = 0;
+-	int reg = DS1374_REG_WDALM0;
+-
+-	while (reg--) {
+-		s32 tmp;
+-		if ((tmp = i2c_smbus_read_byte_data(save_client, reg)) < 0) {
+-			dev_warn(&save_client->dev,
+-				 "can't read from rtc chip\n");
+-			return 0;
+-		}
+-		time = (time << 8) | (tmp & 0xff);
+-	}
+-	return time;
+-}
+-
+-static void ds1374_write_rtc(ulong time)
+-{
+-	int reg;
+-
+-	for (reg = DS1374_REG_TOD0; reg < DS1374_REG_WDALM0; reg++) {
+-		if (i2c_smbus_write_byte_data(save_client, reg, time & 0xff)
+-		    < 0) {
+-			dev_warn(&save_client->dev,
+-				 "can't write to rtc chip\n");
+-			break;
+-		}
+-		time = time >> 8;
+-	}
+-}
+-
+-static void ds1374_check_rtc_status(void)
+-{
+-	s32 tmp;
+-
+-	tmp = i2c_smbus_read_byte_data(save_client, DS1374_REG_SR);
+-	if (tmp < 0) {
+-		dev_warn(&save_client->dev,
+-			 "can't read status from rtc chip\n");
+-		return;
+-	}
+-	if (tmp & DS1374_REG_SR_OSF) {
+-		dev_warn(&save_client->dev,
+-			 "oscillator discontinuity flagged, time unreliable\n");
+-		tmp &= ~DS1374_REG_SR_OSF;
+-		tmp = i2c_smbus_write_byte_data(save_client, DS1374_REG_SR,
+-						tmp & 0xff);
+-		if (tmp < 0)
+-			dev_warn(&save_client->dev,
+-				 "can't clear discontinuity notification\n");
+-	}
+-}
+-
+-ulong ds1374_get_rtc_time(void)
+-{
+-	ulong t1, t2;
+-	int limit = 10;		/* arbitrary retry limit */
+-
+-	mutex_lock(&ds1374_mutex);
+-
+-	/*
+-	 * Since the reads are being performed one byte at a time using
+-	 * the SMBus vs a 4-byte i2c transfer, there is a chance that a
+-	 * carry will occur during the read. To detect this, 2 reads are
+-	 * performed and compared.
+-	 */
+-	do {
+-		t1 = ds1374_read_rtc();
+-		t2 = ds1374_read_rtc();
+-	} while (t1 != t2 && limit--);
+-
+-	mutex_unlock(&ds1374_mutex);
+-
+-	if (t1 != t2) {
+-		dev_warn(&save_client->dev,
+-			 "can't get consistent time from rtc chip\n");
+-		t1 = 0;
+-	}
+-
+-	return t1;
+-}
+-
+-static ulong new_time;
+-
+-static void ds1374_set_work(struct work_struct *work)
+-{
+-	ulong t1, t2;
+-	int limit = 10;		/* arbitrary retry limit */
+-
+-	t1 = new_time;
+-
+-	mutex_lock(&ds1374_mutex);
+-
+-	/*
+-	 * Since the writes are being performed one byte at a time using
+-	 * the SMBus vs a 4-byte i2c transfer, there is a chance that a
+-	 * carry will occur during the write. To detect this, the write
+-	 * value is read back and compared.
+-	 */
+-	do {
+-		ds1374_write_rtc(t1);
+-		t2 = ds1374_read_rtc();
+-	} while (t1 != t2 && limit--);
+-
+-	mutex_unlock(&ds1374_mutex);
+-
+-	if (t1 != t2)
+-		dev_warn(&save_client->dev,
+-			 "can't confirm time set from rtc chip\n");
+-}
+-
+-static struct workqueue_struct *ds1374_workqueue;
+-
+-static DECLARE_WORK(ds1374_work, ds1374_set_work);
+-
+-int ds1374_set_rtc_time(ulong nowtime)
+-{
+-	new_time = nowtime;
+-
+-	if (in_interrupt())
+-		queue_work(ds1374_workqueue, &ds1374_work);
+-	else
+-		ds1374_set_work(NULL);
+-
+-	return 0;
+-}
+-
+-/*
+- *****************************************************************************
+- *
+- *	Driver Interface
+- *
+- *****************************************************************************
+- */
+-static int ds1374_probe(struct i2c_adapter *adap, int addr, int kind)
+-{
+-	struct i2c_client *client;
+-	int rc;
+-
+-	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+-	if (!client)
+-		return -ENOMEM;
+-
+-	strncpy(client->name, DS1374_DRV_NAME, I2C_NAME_SIZE);
+-	client->addr = addr;
+-	client->adapter = adap;
+-	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);
+-		return rc;
+-	}
+-
+-	save_client = client;
+-
+-	ds1374_check_rtc_status();
+-
+-	return 0;
+-}
+-
+-static int ds1374_attach(struct i2c_adapter *adap)
+-{
+-	return i2c_probe(adap, &addr_data, ds1374_probe);
+-}
+-
+-static int ds1374_detach(struct i2c_client *client)
+-{
+-	int rc;
+-
+-	if ((rc = i2c_detach_client(client)) == 0) {
+-		kfree(i2c_get_clientdata(client));
+-		destroy_workqueue(ds1374_workqueue);
+-	}
+-	return rc;
+-}
+-
+-static struct i2c_driver ds1374_driver = {
+-	.driver = {
+-		.name	= DS1374_DRV_NAME,
+-	},
+-	.id = I2C_DRIVERID_DS1374,
+-	.attach_adapter = ds1374_attach,
+-	.detach_client = ds1374_detach,
+-};
+-
+-static int __init ds1374_init(void)
+-{
+-	return i2c_add_driver(&ds1374_driver);
+-}
+-
+-static void __exit ds1374_exit(void)
+-{
+-	i2c_del_driver(&ds1374_driver);
+-}
+-
+-module_init(ds1374_init);
+-module_exit(ds1374_exit);
+-
+-MODULE_AUTHOR("Randy Vinson <rvinson at mvista.com>");
+-MODULE_DESCRIPTION("Maxim/Dallas DS1374 RTC I2C Client Driver");
+-MODULE_LICENSE("GPL");
+diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c
+index 1a7eeeb..fde297b 100644
+--- a/drivers/i2c/chips/eeprom.c
++++ b/drivers/i2c/chips/eeprom.c
+@@ -35,7 +35,7 @@
+ #include <linux/mutex.h>
  
--static void dma_class_dev_release(struct class_device *cd)
-+static void dma_dev_release(struct device *dev)
- {
--	struct dma_chan *chan = container_of(cd, struct dma_chan, class_dev);
-+	struct dma_chan *chan = to_dma_chan(dev);
- 	kref_put(&chan->device->refcount, dma_async_device_cleanup);
- }
+ /* Addresses to scan */
+-static unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54,
++static const unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54,
+ 					0x55, 0x56, 0x57, I2C_CLIENT_END };
  
- static struct class dma_devclass = {
--	.name            = "dma",
--	.class_dev_attrs = dma_class_attrs,
--	.release = dma_class_dev_release,
-+	.name		= "dma",
-+	.dev_attrs	= dma_attrs,
-+	.dev_release	= dma_dev_release,
- };
+ /* Insmod parameters */
+diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c
+index b767603..2a31601 100644
+--- a/drivers/i2c/chips/isp1301_omap.c
++++ b/drivers/i2c/chips/isp1301_omap.c
+@@ -100,7 +100,7 @@ struct isp1301 {
  
- /* --- client and device registration --- */
-@@ -377,12 +378,12 @@ int dma_async_device_register(struct dma_device *device)
- 			continue;
+ #if	defined(CONFIG_TPS65010) || defined(CONFIG_TPS65010_MODULE)
  
- 		chan->chan_id = chancnt++;
--		chan->class_dev.class = &dma_devclass;
--		chan->class_dev.dev = NULL;
--		snprintf(chan->class_dev.class_id, BUS_ID_SIZE, "dma%dchan%d",
-+		chan->dev.class = &dma_devclass;
-+		chan->dev.parent = NULL;
-+		snprintf(chan->dev.bus_id, BUS_ID_SIZE, "dma%dchan%d",
- 		         device->dev_id, chan->chan_id);
+-#include <asm/arch/tps65010.h>
++#include <linux/i2c/tps65010.h>
  
--		rc = class_device_register(&chan->class_dev);
-+		rc = device_register(&chan->dev);
- 		if (rc) {
- 			chancnt--;
- 			free_percpu(chan->local);
-@@ -411,7 +412,7 @@ err_out:
- 		if (chan->local == NULL)
- 			continue;
- 		kref_put(&device->refcount, dma_async_device_cleanup);
--		class_device_unregister(&chan->class_dev);
-+		device_unregister(&chan->dev);
- 		chancnt--;
- 		free_percpu(chan->local);
- 	}
-@@ -445,7 +446,7 @@ void dma_async_device_unregister(struct dma_device *device)
+ #else
  
- 	list_for_each_entry(chan, &device->channels, device_node) {
- 		dma_clients_notify_removed(chan);
--		class_device_unregister(&chan->class_dev);
-+		device_unregister(&chan->dev);
- 		dma_chan_release(chan);
- 	}
+@@ -259,12 +259,6 @@ static inline const char *state_name(struct isp1301 *isp)
+ 	return state_string(isp->otg.state);
+ }
  
-diff --git a/drivers/edac/edac_device_sysfs.c b/drivers/edac/edac_device_sysfs.c
-index 70b837f..5376457 100644
---- a/drivers/edac/edac_device_sysfs.c
-+++ b/drivers/edac/edac_device_sysfs.c
-@@ -246,16 +246,6 @@ int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev)
+-#ifdef	VERBOSE
+-#define	dev_vdbg			dev_dbg
+-#else
+-#define	dev_vdbg(dev, fmt, arg...)	do{}while(0)
+-#endif
+-
+ /*-------------------------------------------------------------------------*/
  
- 	/* Init the devices's kobject */
- 	memset(&edac_dev->kobj, 0, sizeof(struct kobject));
--	edac_dev->kobj.ktype = &ktype_device_ctrl;
+ /* NOTE:  some of this ISP1301 setup is specific to H2 boards;
+diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c
+deleted file mode 100644
+index 3fcb646..0000000
+--- a/drivers/i2c/chips/m41t00.c
++++ /dev/null
+@@ -1,413 +0,0 @@
+-/*
+- * I2C client/driver for the ST M41T00 family of i2c rtc chips.
+- *
+- * Author: Mark A. Greer <mgreer at mvista.com>
+- *
+- * 2005, 2006 (c) MontaVista Software, Inc. This file is licensed under
+- * the terms of the GNU General Public License version 2. This program
+- * is licensed "as is" without any warranty of any kind, whether express
+- * or implied.
+- */
+-/*
+- * This i2c client/driver wedges between the drivers/char/genrtc.c RTC
+- * interface and the SMBus interface of the i2c subsystem.
+- */
 -
--	/* set this new device under the edac_class kobject */
--	edac_dev->kobj.parent = &edac_class->kset.kobj;
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+-#include <linux/interrupt.h>
+-#include <linux/i2c.h>
+-#include <linux/rtc.h>
+-#include <linux/bcd.h>
+-#include <linux/workqueue.h>
+-#include <linux/platform_device.h>
+-#include <linux/m41t00.h>
+-#include <asm/time.h>
+-#include <asm/rtc.h>
+-
+-static struct i2c_driver m41t00_driver;
+-static struct i2c_client *save_client;
+-
+-static unsigned short ignore[] = { I2C_CLIENT_END };
+-static unsigned short normal_addr[] = { I2C_CLIENT_END, I2C_CLIENT_END };
+-
+-static struct i2c_client_address_data addr_data = {
+-	.normal_i2c	= normal_addr,
+-	.probe		= ignore,
+-	.ignore		= ignore,
+-};
+-
+-struct m41t00_chip_info {
+-	u8	type;
+-	char	*name;
+-	u8	read_limit;
+-	u8	sec;		/* Offsets for chip regs */
+-	u8	min;
+-	u8	hour;
+-	u8	day;
+-	u8	mon;
+-	u8	year;
+-	u8	alarm_mon;
+-	u8	alarm_hour;
+-	u8	sqw;
+-	u8	sqw_freq;
+-};
+-
+-static struct m41t00_chip_info m41t00_chip_info_tbl[] = {
+-	{
+-		.type		= M41T00_TYPE_M41T00,
+-		.name		= "m41t00",
+-		.read_limit	= 5,
+-		.sec		= 0,
+-		.min		= 1,
+-		.hour		= 2,
+-		.day		= 4,
+-		.mon		= 5,
+-		.year		= 6,
+-	},
+-	{
+-		.type		= M41T00_TYPE_M41T81,
+-		.name		= "m41t81",
+-		.read_limit	= 1,
+-		.sec		= 1,
+-		.min		= 2,
+-		.hour		= 3,
+-		.day		= 5,
+-		.mon		= 6,
+-		.year		= 7,
+-		.alarm_mon	= 0xa,
+-		.alarm_hour	= 0xc,
+-		.sqw		= 0x13,
+-	},
+-	{
+-		.type		= M41T00_TYPE_M41T85,
+-		.name		= "m41t85",
+-		.read_limit	= 1,
+-		.sec		= 1,
+-		.min		= 2,
+-		.hour		= 3,
+-		.day		= 5,
+-		.mon		= 6,
+-		.year		= 7,
+-		.alarm_mon	= 0xa,
+-		.alarm_hour	= 0xc,
+-		.sqw		= 0x13,
+-	},
+-};
+-static struct m41t00_chip_info *m41t00_chip;
 -
--	/* generate sysfs "..../edac/<name>"   */
--	debugf4("%s() set name of kobject to: %s\n", __func__, edac_dev->name);
--	err = kobject_set_name(&edac_dev->kobj, "%s", edac_dev->name);
--	if (err)
--		goto err_out;
- 
- 	/* Record which module 'owns' this control structure
- 	 * and bump the ref count of the module
-@@ -268,12 +258,15 @@ int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev)
- 	}
- 
- 	/* register */
--	err = kobject_register(&edac_dev->kobj);
-+	err = kobject_init_and_add(&edac_dev->kobj, &ktype_device_ctrl,
-+				   &edac_class->kset.kobj,
-+				   "%s", edac_dev->name);
- 	if (err) {
- 		debugf1("%s()Failed to register '.../edac/%s'\n",
- 			__func__, edac_dev->name);
- 		goto err_kobj_reg;
- 	}
-+	kobject_uevent(&edac_dev->kobj, KOBJ_ADD);
- 
- 	/* At this point, to 'free' the control struct,
- 	 * edac_device_unregister_sysfs_main_kobj() must be used
-@@ -310,7 +303,7 @@ void edac_device_unregister_sysfs_main_kobj(
- 	 *   a) module_put() this module
- 	 *   b) 'kfree' the memory
- 	 */
--	kobject_unregister(&edac_dev->kobj);
-+	kobject_put(&edac_dev->kobj);
- }
- 
- /* edac_dev -> instance information */
-@@ -533,12 +526,6 @@ static int edac_device_create_block(struct edac_device_ctl_info *edac_dev,
- 
- 	/* init this block's kobject */
- 	memset(&block->kobj, 0, sizeof(struct kobject));
--	block->kobj.parent = &instance->kobj;
--	block->kobj.ktype = &ktype_block_ctrl;
+-ulong
+-m41t00_get_rtc_time(void)
+-{
+-	s32 sec, min, hour, day, mon, year;
+-	s32 sec1, min1, hour1, day1, mon1, year1;
+-	u8 reads = 0;
+-	u8 buf[8], msgbuf[1] = { 0 }; /* offset into rtc's regs */
+-	struct i2c_msg msgs[] = {
+-		{
+-			.addr	= save_client->addr,
+-			.flags	= 0,
+-			.len	= 1,
+-			.buf	= msgbuf,
+-		},
+-		{
+-			.addr	= save_client->addr,
+-			.flags	= I2C_M_RD,
+-			.len	= 8,
+-			.buf	= buf,
+-		},
+-	};
 -
--	err = kobject_set_name(&block->kobj, "%s", block->name);
--	if (err)
--		return err;
- 
- 	/* bump the main kobject's reference count for this controller
- 	 * and this instance is dependant on the main
-@@ -550,7 +537,9 @@ static int edac_device_create_block(struct edac_device_ctl_info *edac_dev,
- 	}
- 
- 	/* Add this block's kobject */
--	err = kobject_register(&block->kobj);
-+	err = kobject_init_and_add(&block->kobj, &ktype_block_ctrl,
-+				   &instance->kobj,
-+				   "%s", block->name);
- 	if (err) {
- 		debugf1("%s() Failed to register instance '%s'\n",
- 			__func__, block->name);
-@@ -579,12 +568,13 @@ static int edac_device_create_block(struct edac_device_ctl_info *edac_dev,
- 				goto err_on_attrib;
- 		}
- 	}
-+	kobject_uevent(&block->kobj, KOBJ_ADD);
- 
- 	return 0;
- 
- 	/* Error unwind stack */
- err_on_attrib:
--	kobject_unregister(&block->kobj);
-+	kobject_put(&block->kobj);
- 
- err_out:
- 	return err;
-@@ -615,7 +605,7 @@ static void edac_device_delete_block(struct edac_device_ctl_info *edac_dev,
- 	/* unregister this block's kobject, SEE:
- 	 *	edac_device_ctrl_block_release() callback operation
- 	 */
--	kobject_unregister(&block->kobj);
-+	kobject_put(&block->kobj);
- }
+-	sec = min = hour = day = mon = year = 0;
+-
+-	do {
+-		if (i2c_transfer(save_client->adapter, msgs, 2) < 0)
+-			goto read_err;
+-
+-		sec1 = sec;
+-		min1 = min;
+-		hour1 = hour;
+-		day1 = day;
+-		mon1 = mon;
+-		year1 = year;
+-
+-		sec = buf[m41t00_chip->sec] & 0x7f;
+-		min = buf[m41t00_chip->min] & 0x7f;
+-		hour = buf[m41t00_chip->hour] & 0x3f;
+-		day = buf[m41t00_chip->day] & 0x3f;
+-		mon = buf[m41t00_chip->mon] & 0x1f;
+-		year = buf[m41t00_chip->year];
+-	} while ((++reads < m41t00_chip->read_limit) && ((sec != sec1)
+-			|| (min != min1) || (hour != hour1) || (day != day1)
+-			|| (mon != mon1) || (year != year1)));
+-
+-	if ((m41t00_chip->read_limit > 1) && ((sec != sec1) || (min != min1)
+-			|| (hour != hour1) || (day != day1) || (mon != mon1)
+-			|| (year != year1)))
+-		goto read_err;
+-
+-	sec = BCD2BIN(sec);
+-	min = BCD2BIN(min);
+-	hour = BCD2BIN(hour);
+-	day = BCD2BIN(day);
+-	mon = BCD2BIN(mon);
+-	year = BCD2BIN(year);
+-
+-	year += 1900;
+-	if (year < 1970)
+-		year += 100;
+-
+-	return mktime(year, mon, day, hour, min, sec);
+-
+-read_err:
+-	dev_err(&save_client->dev, "m41t00_get_rtc_time: Read error\n");
+-	return 0;
+-}
+-EXPORT_SYMBOL_GPL(m41t00_get_rtc_time);
+-
+-static void
+-m41t00_set(void *arg)
+-{
+-	struct rtc_time	tm;
+-	int nowtime = *(int *)arg;
+-	s32 sec, min, hour, day, mon, year;
+-	u8 wbuf[9], *buf = &wbuf[1], msgbuf[1] = { 0 };
+-	struct i2c_msg msgs[] = {
+-		{
+-			.addr	= save_client->addr,
+-			.flags	= 0,
+-			.len	= 1,
+-			.buf	= msgbuf,
+-		},
+-		{
+-			.addr	= save_client->addr,
+-			.flags	= I2C_M_RD,
+-			.len	= 8,
+-			.buf	= buf,
+-		},
+-	};
+-
+-	to_tm(nowtime, &tm);
+-	tm.tm_year = (tm.tm_year - 1900) % 100;
+-
+-	sec = BIN2BCD(tm.tm_sec);
+-	min = BIN2BCD(tm.tm_min);
+-	hour = BIN2BCD(tm.tm_hour);
+-	day = BIN2BCD(tm.tm_mday);
+-	mon = BIN2BCD(tm.tm_mon);
+-	year = BIN2BCD(tm.tm_year);
+-
+-	/* Read reg values into buf[0..7]/wbuf[1..8] */
+-	if (i2c_transfer(save_client->adapter, msgs, 2) < 0) {
+-		dev_err(&save_client->dev, "m41t00_set: Read error\n");
+-		return;
+-	}
+-
+-	wbuf[0] = 0; /* offset into rtc's regs */
+-	buf[m41t00_chip->sec] = (buf[m41t00_chip->sec] & ~0x7f) | (sec & 0x7f);
+-	buf[m41t00_chip->min] = (buf[m41t00_chip->min] & ~0x7f) | (min & 0x7f);
+-	buf[m41t00_chip->hour] = (buf[m41t00_chip->hour] & ~0x3f) | (hour& 0x3f);
+-	buf[m41t00_chip->day] = (buf[m41t00_chip->day] & ~0x3f) | (day & 0x3f);
+-	buf[m41t00_chip->mon] = (buf[m41t00_chip->mon] & ~0x1f) | (mon & 0x1f);
+-	buf[m41t00_chip->year] = year;
+-
+-	if (i2c_master_send(save_client, wbuf, 9) < 0)
+-		dev_err(&save_client->dev, "m41t00_set: Write error\n");
+-}
+-
+-static ulong new_time;
+-/* well, isn't this API just _lovely_? */
+-static void
+-m41t00_barf(struct work_struct *unusable)
+-{
+-	m41t00_set(&new_time);
+-}
+-
+-static struct workqueue_struct *m41t00_wq;
+-static DECLARE_WORK(m41t00_work, m41t00_barf);
+-
+-int
+-m41t00_set_rtc_time(ulong nowtime)
+-{
+-	new_time = nowtime;
+-
+-	if (in_interrupt())
+-		queue_work(m41t00_wq, &m41t00_work);
+-	else
+-		m41t00_set(&new_time);
+-
+-	return 0;
+-}
+-EXPORT_SYMBOL_GPL(m41t00_set_rtc_time);
+-
+-/*
+- *****************************************************************************
+- *
+- *	platform_data Driver Interface
+- *
+- *****************************************************************************
+- */
+-static int __init
+-m41t00_platform_probe(struct platform_device *pdev)
+-{
+-	struct m41t00_platform_data *pdata;
+-	int i;
+-
+-	if (pdev && (pdata = pdev->dev.platform_data)) {
+-		normal_addr[0] = pdata->i2c_addr;
+-
+-		for (i=0; i<ARRAY_SIZE(m41t00_chip_info_tbl); i++)
+-			if (m41t00_chip_info_tbl[i].type == pdata->type) {
+-				m41t00_chip = &m41t00_chip_info_tbl[i];
+-				m41t00_chip->sqw_freq = pdata->sqw_freq;
+-				return 0;
+-			}
+-	}
+-	return -ENODEV;
+-}
+-
+-static int __exit
+-m41t00_platform_remove(struct platform_device *pdev)
+-{
+-	return 0;
+-}
+-
+-static struct platform_driver m41t00_platform_driver = {
+-	.probe  = m41t00_platform_probe,
+-	.remove = m41t00_platform_remove,
+-	.driver = {
+-		.owner = THIS_MODULE,
+-		.name  = M41T00_DRV_NAME,
+-	},
+-};
+-
+-/*
+- *****************************************************************************
+- *
+- *	Driver Interface
+- *
+- *****************************************************************************
+- */
+-static int
+-m41t00_probe(struct i2c_adapter *adap, int addr, int kind)
+-{
+-	struct i2c_client *client;
+-	int rc;
+-
+-	if (!i2c_check_functionality(adap, I2C_FUNC_I2C
+-			| I2C_FUNC_SMBUS_BYTE_DATA))
+-		return 0;
+-
+-	client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+-	if (!client)
+-		return -ENOMEM;
+-
+-	strlcpy(client->name, m41t00_chip->name, I2C_NAME_SIZE);
+-	client->addr = addr;
+-	client->adapter = adap;
+-	client->driver = &m41t00_driver;
+-
+-	if ((rc = i2c_attach_client(client)))
+-		goto attach_err;
+-
+-	if (m41t00_chip->type != M41T00_TYPE_M41T00) {
+-		/* If asked, disable SQW, set SQW frequency & re-enable */
+-		if (m41t00_chip->sqw_freq)
+-			if (((rc = i2c_smbus_read_byte_data(client,
+-					m41t00_chip->alarm_mon)) < 0)
+-			 || ((rc = i2c_smbus_write_byte_data(client,
+-					m41t00_chip->alarm_mon, rc & ~0x40)) <0)
+-			 || ((rc = i2c_smbus_write_byte_data(client,
+-					m41t00_chip->sqw,
+-					m41t00_chip->sqw_freq)) < 0)
+-			 || ((rc = i2c_smbus_write_byte_data(client,
+-					m41t00_chip->alarm_mon, rc | 0x40)) <0))
+-				goto sqw_err;
+-
+-		/* Make sure HT (Halt Update) bit is cleared */
+-		if ((rc = i2c_smbus_read_byte_data(client,
+-				m41t00_chip->alarm_hour)) < 0)
+-			goto ht_err;
+-
+-		if (rc & 0x40)
+-			if ((rc = i2c_smbus_write_byte_data(client,
+-					m41t00_chip->alarm_hour, rc & ~0x40))<0)
+-				goto ht_err;
+-	}
+-
+-	/* Make sure ST (stop) bit is cleared */
+-	if ((rc = i2c_smbus_read_byte_data(client, m41t00_chip->sec)) < 0)
+-		goto st_err;
+-
+-	if (rc & 0x80)
+-		if ((rc = i2c_smbus_write_byte_data(client, m41t00_chip->sec,
+-				rc & ~0x80)) < 0)
+-			goto st_err;
+-
+-	m41t00_wq = create_singlethread_workqueue(m41t00_chip->name);
+-	save_client = client;
+-	return 0;
+-
+-st_err:
+-	dev_err(&client->dev, "m41t00_probe: Can't clear ST bit\n");
+-	goto attach_err;
+-ht_err:
+-	dev_err(&client->dev, "m41t00_probe: Can't clear HT bit\n");
+-	goto attach_err;
+-sqw_err:
+-	dev_err(&client->dev, "m41t00_probe: Can't set SQW Frequency\n");
+-attach_err:
+-	kfree(client);
+-	return rc;
+-}
+-
+-static int
+-m41t00_attach(struct i2c_adapter *adap)
+-{
+-	return i2c_probe(adap, &addr_data, m41t00_probe);
+-}
+-
+-static int
+-m41t00_detach(struct i2c_client *client)
+-{
+-	int rc;
+-
+-	if ((rc = i2c_detach_client(client)) == 0) {
+-		kfree(client);
+-		destroy_workqueue(m41t00_wq);
+-	}
+-	return rc;
+-}
+-
+-static struct i2c_driver m41t00_driver = {
+-	.driver = {
+-		.name	= M41T00_DRV_NAME,
+-	},
+-	.id		= I2C_DRIVERID_STM41T00,
+-	.attach_adapter	= m41t00_attach,
+-	.detach_client	= m41t00_detach,
+-};
+-
+-static int __init
+-m41t00_init(void)
+-{
+-	int rc;
+-
+-	if (!(rc = platform_driver_register(&m41t00_platform_driver)))
+-		rc = i2c_add_driver(&m41t00_driver);
+-	return rc;
+-}
+-
+-static void __exit
+-m41t00_exit(void)
+-{
+-	i2c_del_driver(&m41t00_driver);
+-	platform_driver_unregister(&m41t00_platform_driver);
+-}
+-
+-module_init(m41t00_init);
+-module_exit(m41t00_exit);
+-
+-MODULE_AUTHOR("Mark A. Greer <mgreer at mvista.com>");
+-MODULE_DESCRIPTION("ST Microelectronics M41T00 RTC I2C Client Driver");
+-MODULE_LICENSE("GPL");
+diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c
+index 64692f6..fb7ea56 100644
+--- a/drivers/i2c/chips/max6875.c
++++ b/drivers/i2c/chips/max6875.c
+@@ -34,7 +34,7 @@
+ #include <linux/mutex.h>
  
- /* instance ctor/dtor code */
-@@ -637,15 +627,8 @@ static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev,
- 	/* Init the instance's kobject */
- 	memset(&instance->kobj, 0, sizeof(struct kobject));
+ /* Do not scan - the MAX6875 access method will write to some EEPROM chips */
+-static unsigned short normal_i2c[] = {I2C_CLIENT_END};
++static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
+ 
+ /* Insmod parameters */
+ I2C_CLIENT_INSMOD_1(max6875);
+diff --git a/drivers/i2c/chips/pcf8574.c b/drivers/i2c/chips/pcf8574.c
+index 21c6dd6..b3b830c 100644
+--- a/drivers/i2c/chips/pcf8574.c
++++ b/drivers/i2c/chips/pcf8574.c
+@@ -41,9 +41,11 @@
+ #include <linux/i2c.h>
  
--	/* set this new device under the edac_device main kobject */
--	instance->kobj.parent = &edac_dev->kobj;
--	instance->kobj.ktype = &ktype_instance_ctrl;
- 	instance->ctl = edac_dev;
+ /* Addresses to scan */
+-static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+-					0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+-					I2C_CLIENT_END };
++static const unsigned short normal_i2c[] = {
++	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
++	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
++	I2C_CLIENT_END
++};
  
--	err = kobject_set_name(&instance->kobj, "%s", instance->name);
--	if (err)
--		goto err_out;
--
- 	/* bump the main kobject's reference count for this controller
- 	 * and this instance is dependant on the main
- 	 */
-@@ -655,8 +638,9 @@ static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev,
- 		goto err_out;
- 	}
+ /* Insmod parameters */
+ I2C_CLIENT_INSMOD_2(pcf8574, pcf8574a);
+diff --git a/drivers/i2c/chips/pcf8575.c b/drivers/i2c/chips/pcf8575.c
+new file mode 100644
+index 0000000..3ea08ac
+--- /dev/null
++++ b/drivers/i2c/chips/pcf8575.c
+@@ -0,0 +1,214 @@
++/*
++  pcf8575.c
++
++  About the PCF8575 chip: the PCF8575 is a 16-bit I/O expander for the I2C bus
++  produced by a.o. Philips Semiconductors.
++
++  Copyright (C) 2006 Michael Hennerich, Analog Devices Inc.
++  <hennerich at blackfin.uclinux.org>
++  Based on pcf8574.c.
++
++  Copyright (c) 2007 Bart Van Assche <bart.vanassche at gmail.com>.
++  Ported this driver from ucLinux to the mainstream Linux kernel.
++
++  This program is free software; you can redistribute it and/or modify
++  it under the terms of the GNU General Public License as published by
++  the Free Software Foundation; either version 2 of the License, or
++  (at your option) any later version.
++
++  This program is distributed in the hope that it will be useful,
++  but WITHOUT ANY WARRANTY; without even the implied warranty of
++  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++  GNU General Public License for more details.
++
++  You should have received a copy of the GNU General Public License
++  along with this program; if not, write to the Free Software
++  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++*/
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/i2c.h>
++#include <linux/slab.h>  /* kzalloc() */
++#include <linux/sysfs.h> /* sysfs_create_group() */
++
++/* Addresses to scan */
++static const unsigned short normal_i2c[] = {
++	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
++	I2C_CLIENT_END
++};
++
++/* Insmod parameters */
++I2C_CLIENT_INSMOD;
++
++
++/* Each client has this additional data */
++struct pcf8575_data {
++	struct i2c_client client;
++	int write;		/* last written value, or error code */
++};
++
++static int pcf8575_attach_adapter(struct i2c_adapter *adapter);
++static int pcf8575_detect(struct i2c_adapter *adapter, int address, int kind);
++static int pcf8575_detach_client(struct i2c_client *client);
++
++/* This is the driver that will be inserted */
++static struct i2c_driver pcf8575_driver = {
++	.driver = {
++		.owner	= THIS_MODULE,
++		.name	= "pcf8575",
++	},
++	.attach_adapter	= pcf8575_attach_adapter,
++	.detach_client	= pcf8575_detach_client,
++};
++
++/* following are the sysfs callback functions */
++static ssize_t show_read(struct device *dev, struct device_attribute *attr,
++			 char *buf)
++{
++	struct i2c_client *client = to_i2c_client(dev);
++	u16 val;
++	u8 iopin_state[2];
++
++	i2c_master_recv(client, iopin_state, 2);
++
++	val = iopin_state[0];
++	val |= iopin_state[1] << 8;
++
++	return sprintf(buf, "%u\n", val);
++}
++
++static DEVICE_ATTR(read, S_IRUGO, show_read, NULL);
++
++static ssize_t show_write(struct device *dev, struct device_attribute *attr,
++			  char *buf)
++{
++	struct pcf8575_data *data = dev_get_drvdata(dev);
++	if (data->write < 0)
++		return data->write;
++	return sprintf(buf, "%d\n", data->write);
++}
++
++static ssize_t set_write(struct device *dev, struct device_attribute *attr,
++			 const char *buf, size_t count)
++{
++	struct i2c_client *client = to_i2c_client(dev);
++	struct pcf8575_data *data = i2c_get_clientdata(client);
++	unsigned long val = simple_strtoul(buf, NULL, 10);
++	u8 iopin_state[2];
++
++	if (val > 0xffff)
++		return -EINVAL;
++
++	data->write = val;
++
++	iopin_state[0] = val & 0xFF;
++	iopin_state[1] = val >> 8;
++
++	i2c_master_send(client, iopin_state, 2);
++
++	return count;
++}
++
++static DEVICE_ATTR(write, S_IWUSR | S_IRUGO, show_write, set_write);
++
++static struct attribute *pcf8575_attributes[] = {
++	&dev_attr_read.attr,
++	&dev_attr_write.attr,
++	NULL
++};
++
++static const struct attribute_group pcf8575_attr_group = {
++	.attrs = pcf8575_attributes,
++};
++
++/*
++ * Real code
++ */
++
++static int pcf8575_attach_adapter(struct i2c_adapter *adapter)
++{
++	return i2c_probe(adapter, &addr_data, pcf8575_detect);
++}
++
++/* This function is called by i2c_probe */
++static int pcf8575_detect(struct i2c_adapter *adapter, int address, int kind)
++{
++	struct i2c_client *client;
++	struct pcf8575_data *data;
++	int err = 0;
++
++	if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
++		goto exit;
++
++	/* OK. For now, we presume we have a valid client. We now create the
++	   client structure, even though we cannot fill it completely yet. */
++	data = kzalloc(sizeof(struct pcf8575_data), GFP_KERNEL);
++	if (!data) {
++		err = -ENOMEM;
++		goto exit;
++	}
++
++	client = &data->client;
++	i2c_set_clientdata(client, data);
++	client->addr = address;
++	client->adapter = adapter;
++	client->driver = &pcf8575_driver;
++	strlcpy(client->name, "pcf8575", I2C_NAME_SIZE);
++	data->write = -EAGAIN;
++
++	/* This is the place to detect whether the chip at the specified
++	   address really is a PCF8575 chip. However, there is no method known
++	   to detect whether an I2C chip is a PCF8575 or any other I2C chip. */
++
++	/* Tell the I2C layer a new client has arrived */
++	err = i2c_attach_client(client);
++	if (err)
++		goto exit_free;
++
++	/* Register sysfs hooks */
++	err = sysfs_create_group(&client->dev.kobj, &pcf8575_attr_group);
++	if (err)
++		goto exit_detach;
++
++	return 0;
++
++exit_detach:
++	i2c_detach_client(client);
++exit_free:
++	kfree(data);
++exit:
++	return err;
++}
++
++static int pcf8575_detach_client(struct i2c_client *client)
++{
++	int err;
++
++	sysfs_remove_group(&client->dev.kobj, &pcf8575_attr_group);
++
++	err = i2c_detach_client(client);
++	if (err)
++		return err;
++
++	kfree(i2c_get_clientdata(client));
++	return 0;
++}
++
++static int __init pcf8575_init(void)
++{
++	return i2c_add_driver(&pcf8575_driver);
++}
++
++static void __exit pcf8575_exit(void)
++{
++	i2c_del_driver(&pcf8575_driver);
++}
++
++MODULE_AUTHOR("Michael Hennerich <hennerich at blackfin.uclinux.org>, "
++	      "Bart Van Assche <bart.vanassche at gmail.com>");
++MODULE_DESCRIPTION("pcf8575 driver");
++MODULE_LICENSE("GPL");
++
++module_init(pcf8575_init);
++module_exit(pcf8575_exit);
+diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c
+index 4dc3637..865f440 100644
+--- a/drivers/i2c/chips/pcf8591.c
++++ b/drivers/i2c/chips/pcf8591.c
+@@ -27,7 +27,7 @@
+ #include <linux/mutex.h>
  
--	/* Formally register this instance's kobject */
--	err = kobject_register(&instance->kobj);
-+	/* Formally register this instance's kobject under the edac_device */
-+	err = kobject_init_and_add(&instance->kobj, &ktype_instance_ctrl,
-+				   &edac_dev->kobj, "%s", instance->name);
- 	if (err != 0) {
- 		debugf2("%s() Failed to register instance '%s'\n",
- 			__func__, instance->name);
-@@ -679,6 +663,7 @@ static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev,
- 			goto err_release_instance_kobj;
- 		}
- 	}
-+	kobject_uevent(&instance->kobj, KOBJ_ADD);
+ /* Addresses to scan */
+-static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
++static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
+ 					0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
+ 
+ /* Insmod parameters */
+diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c
+index e320994..4154a91 100644
+--- a/drivers/i2c/chips/tps65010.c
++++ b/drivers/i2c/chips/tps65010.c
+@@ -31,7 +31,7 @@
+ #include <linux/seq_file.h>
+ #include <linux/mutex.h>
  
- 	debugf4("%s() Registered instance %d '%s' kobject\n",
- 		__func__, idx, instance->name);
-@@ -687,7 +672,7 @@ static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev,
+-#include <asm/arch/tps65010.h>
++#include <linux/i2c/tps65010.h>
  
- 	/* error unwind stack */
- err_release_instance_kobj:
--	kobject_unregister(&instance->kobj);
-+	kobject_put(&instance->kobj);
+ /*-------------------------------------------------------------------------*/
  
- err_out:
- 	return err;
-@@ -712,7 +697,7 @@ static void edac_device_delete_instance(struct edac_device_ctl_info *edac_dev,
- 	/* unregister this instance's kobject, SEE:
- 	 *	edac_device_ctrl_instance_release() for callback operation
- 	 */
--	kobject_unregister(&instance->kobj);
-+	kobject_put(&instance->kobj);
+diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c
+index 3de4b19..a10fd27 100644
+--- a/drivers/i2c/chips/tsl2550.c
++++ b/drivers/i2c/chips/tsl2550.c
+@@ -432,11 +432,32 @@ static int __devexit tsl2550_remove(struct i2c_client *client)
+ 	return 0;
  }
  
- /*
-diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
-index 3706b2b..9aac880 100644
---- a/drivers/edac/edac_mc_sysfs.c
-+++ b/drivers/edac/edac_mc_sysfs.c
-@@ -380,13 +380,6 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci,
- 	/* generate ..../edac/mc/mc<id>/csrow<index>   */
- 	memset(&csrow->kobj, 0, sizeof(csrow->kobj));
- 	csrow->mci = mci;	/* include container up link */
--	csrow->kobj.parent = kobj_mci;
--	csrow->kobj.ktype = &ktype_csrow;
--
--	/* name this instance of csrow<id> */
--	err = kobject_set_name(&csrow->kobj, "csrow%d", index);
--	if (err)
--		goto err_out;
- 
- 	/* bump the mci instance's kobject's ref count */
- 	kobj = kobject_get(&mci->edac_mci_kobj);
-@@ -396,12 +389,13 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci,
- 	}
++#ifdef CONFIG_PM
++
++static int tsl2550_suspend(struct i2c_client *client, pm_message_t mesg)
++{
++	return tsl2550_set_power_state(client, 0);
++}
++
++static int tsl2550_resume(struct i2c_client *client)
++{
++	return tsl2550_set_power_state(client, 1);
++}
++
++#else
++
++#define tsl2550_suspend		NULL
++#define tsl2550_resume		NULL
++
++#endif /* CONFIG_PM */
++
+ static struct i2c_driver tsl2550_driver = {
+ 	.driver = {
+ 		.name	= TSL2550_DRV_NAME,
+ 		.owner	= THIS_MODULE,
+ 	},
++	.suspend = tsl2550_suspend,
++	.resume	= tsl2550_resume,
+ 	.probe	= tsl2550_probe,
+ 	.remove	= __devexit_p(tsl2550_remove),
+ };
+diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
+index b5e13e4..96da22e 100644
+--- a/drivers/i2c/i2c-core.c
++++ b/drivers/i2c/i2c-core.c
+@@ -33,14 +33,15 @@
+ #include <linux/platform_device.h>
+ #include <linux/mutex.h>
+ #include <linux/completion.h>
++#include <linux/hardirq.h>
++#include <linux/irqflags.h>
+ #include <asm/uaccess.h>
++#include <asm/semaphore.h>
  
- 	/* Instanstiate the csrow object */
--	err = kobject_register(&csrow->kobj);
-+	err = kobject_init_and_add(&csrow->kobj, &ktype_csrow, kobj_mci,
-+				   "csrow%d", index);
- 	if (err)
- 		goto err_release_top_kobj;
+ #include "i2c-core.h"
  
- 	/* At this point, to release a csrow kobj, one must
--	 * call the kobject_unregister and allow that tear down
-+	 * call the kobject_put and allow that tear down
- 	 * to work the releasing
- 	 */
  
-@@ -412,11 +406,11 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci,
- 		err = edac_create_channel_files(&csrow->kobj, chan);
- 		if (err) {
- 			/* special case the unregister here */
--			kobject_unregister(&csrow->kobj);
-+			kobject_put(&csrow->kobj);
- 			goto err_out;
- 		}
- 	}
--
-+	kobject_uevent(&csrow->kobj, KOBJ_ADD);
- 	return 0;
+-static LIST_HEAD(adapters);
+-static LIST_HEAD(drivers);
+-static DEFINE_MUTEX(core_lists);
++static DEFINE_MUTEX(core_lock);
+ static DEFINE_IDR(i2c_adapter_idr);
  
- 	/* error unwind stack */
-@@ -744,7 +738,6 @@ static struct kobj_type ktype_mc_set_attribs = {
-  */
- static struct kset mc_kset = {
- 	.kobj = {.ktype = &ktype_mc_set_attribs },
--	.ktype = &ktype_mci,
+ #define is_newstyle_driver(d) ((d)->probe || (d)->remove)
+@@ -198,6 +199,25 @@ static struct bus_type i2c_bus_type = {
+ 	.resume		= i2c_device_resume,
  };
  
++
++/**
++ * i2c_verify_client - return parameter as i2c_client, or NULL
++ * @dev: device, probably from some driver model iterator
++ *
++ * When traversing the driver model tree, perhaps using driver model
++ * iterators like @device_for_each_child(), you can't assume very much
++ * about the nodes you find.  Use this function to avoid oopses caused
++ * by wrongly treating some non-I2C device as an i2c_client.
++ */
++struct i2c_client *i2c_verify_client(struct device *dev)
++{
++	return (dev->bus == &i2c_bus_type)
++			? to_i2c_client(dev)
++			: NULL;
++}
++EXPORT_SYMBOL(i2c_verify_client);
++
++
+ /**
+  * i2c_new_device - instantiate an i2c device for use with a new style driver
+  * @adap: the adapter managing the device
+@@ -276,6 +296,50 @@ void i2c_unregister_device(struct i2c_client *client)
+ EXPORT_SYMBOL_GPL(i2c_unregister_device);
  
-@@ -765,14 +758,6 @@ int edac_mc_register_sysfs_main_kobj(struct mem_ctl_info *mci)
- 	/* Init the mci's kobject */
- 	memset(kobj_mci, 0, sizeof(*kobj_mci));
- 
--	/* this instance become part of the mc_kset */
--	kobj_mci->kset = &mc_kset;
--
--	/* set the name of the mc<id> object */
--	err = kobject_set_name(kobj_mci, "mc%d", mci->mc_idx);
--	if (err)
--		goto fail_out;
--
- 	/* Record which module 'owns' this control structure
- 	 * and bump the ref count of the module
- 	 */
-@@ -784,13 +769,18 @@ int edac_mc_register_sysfs_main_kobj(struct mem_ctl_info *mci)
- 		goto fail_out;
- 	}
  
-+	/* this instance become part of the mc_kset */
-+	kobj_mci->kset = &mc_kset;
++static int dummy_nop(struct i2c_client *client)
++{
++	return 0;
++}
 +
- 	/* register the mc<id> kobject to the mc_kset */
--	err = kobject_register(kobj_mci);
-+	err = kobject_init_and_add(kobj_mci, &ktype_mci, NULL,
-+				   "mc%d", mci->mc_idx);
- 	if (err) {
- 		debugf1("%s()Failed to register '.../edac/mc%d'\n",
- 			__func__, mci->mc_idx);
- 		goto kobj_reg_fail;
- 	}
-+	kobject_uevent(kobj_mci, KOBJ_ADD);
++static struct i2c_driver dummy_driver = {
++	.driver.name	= "dummy",
++	.probe		= dummy_nop,
++	.remove		= dummy_nop,
++};
++
++/**
++ * i2c_new_dummy - return a new i2c device bound to a dummy driver
++ * @adapter: the adapter managing the device
++ * @address: seven bit address to be used
++ * @type: optional label used for i2c_client.name
++ * Context: can sleep
++ *
++ * This returns an I2C client bound to the "dummy" driver, intended for use
++ * with devices that consume multiple addresses.  Examples of such chips
++ * include various EEPROMS (like 24c04 and 24c08 models).
++ *
++ * These dummy devices have two main uses.  First, most I2C and SMBus calls
++ * except i2c_transfer() need a client handle; the dummy will be that handle.
++ * And second, this prevents the specified address from being bound to a
++ * different driver.
++ *
++ * This returns the new i2c client, which should be saved for later use with
++ * i2c_unregister_device(); or NULL to indicate an error.
++ */
++struct i2c_client *
++i2c_new_dummy(struct i2c_adapter *adapter, u16 address, const char *type)
++{
++	struct i2c_board_info info = {
++		.driver_name	= "dummy",
++		.addr		= address,
++	};
++
++	if (type)
++		strlcpy(info.type, type, sizeof info.type);
++	return i2c_new_device(adapter, &info);
++}
++EXPORT_SYMBOL_GPL(i2c_new_dummy);
++
+ /* ------------------------------------------------------------------------- */
  
- 	/* At this point, to 'free' the control struct,
- 	 * edac_mc_unregister_sysfs_main_kobj() must be used
-@@ -818,7 +808,7 @@ fail_out:
- void edac_mc_unregister_sysfs_main_kobj(struct mem_ctl_info *mci)
- {
- 	/* delete the kobj from the mc_kset */
--	kobject_unregister(&mci->edac_mci_kobj);
-+	kobject_put(&mci->edac_mci_kobj);
+ /* I2C bus adapters -- one roots each I2C or SMBUS segment */
+@@ -320,18 +384,27 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
+ 	mutex_unlock(&__i2c_board_lock);
  }
  
- #define EDAC_DEVICE_SYMLINK	"device"
-@@ -933,7 +923,7 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
- fail1:
- 	for (i--; i >= 0; i--) {
- 		if (csrow->nr_pages > 0) {
--			kobject_unregister(&mci->csrows[i].kobj);
-+			kobject_put(&mci->csrows[i].kobj);
- 		}
- 	}
++static int i2c_do_add_adapter(struct device_driver *d, void *data)
++{
++	struct i2c_driver *driver = to_i2c_driver(d);
++	struct i2c_adapter *adap = data;
++
++	if (driver->attach_adapter) {
++		/* We ignore the return code; if it fails, too bad */
++		driver->attach_adapter(adap);
++	}
++	return 0;
++}
++
+ static int i2c_register_adapter(struct i2c_adapter *adap)
+ {
+-	int res = 0;
+-	struct list_head   *item;
+-	struct i2c_driver  *driver;
++	int res = 0, dummy;
  
-@@ -960,7 +950,7 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
- 	for (i = 0; i < mci->nr_csrows; i++) {
- 		if (mci->csrows[i].nr_pages > 0) {
- 			debugf0("%s()  unreg csrow-%d\n", __func__, i);
--			kobject_unregister(&mci->csrows[i].kobj);
-+			kobject_put(&mci->csrows[i].kobj);
- 		}
- 	}
+ 	mutex_init(&adap->bus_lock);
+ 	mutex_init(&adap->clist_lock);
+ 	INIT_LIST_HEAD(&adap->clients);
  
-@@ -977,7 +967,7 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
- 	debugf0("%s()  unregister this mci kobj\n", __func__);
+-	mutex_lock(&core_lists);
+-	list_add_tail(&adap->list, &adapters);
++	mutex_lock(&core_lock);
  
- 	/* unregister this instance's kobject */
--	kobject_unregister(&mci->edac_mci_kobj);
-+	kobject_put(&mci->edac_mci_kobj);
- }
+ 	/* Add the adapter to the driver core.
+ 	 * If the parent pointer is not set up,
+@@ -356,19 +429,14 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
+ 		i2c_scan_static_board_info(adap);
  
+ 	/* let legacy drivers scan this bus for matching devices */
+-	list_for_each(item,&drivers) {
+-		driver = list_entry(item, struct i2c_driver, list);
+-		if (driver->attach_adapter)
+-			/* We ignore the return code; if it fails, too bad */
+-			driver->attach_adapter(adap);
+-	}
++	dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap,
++				 i2c_do_add_adapter);
  
-diff --git a/drivers/edac/edac_module.c b/drivers/edac/edac_module.c
-index e0c4a40..7e1374a 100644
---- a/drivers/edac/edac_module.c
-+++ b/drivers/edac/edac_module.c
-@@ -31,7 +31,7 @@ struct workqueue_struct *edac_workqueue;
-  *	need to export to other files in this modules
-  */
- static struct sysdev_class edac_class = {
--	set_kset_name("edac"),
-+	.name = "edac",
- };
- static int edac_class_valid;
+ out_unlock:
+-	mutex_unlock(&core_lists);
++	mutex_unlock(&core_lock);
+ 	return res;
  
-diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c
-index 69f5ddd..5b075da 100644
---- a/drivers/edac/edac_pci_sysfs.c
-+++ b/drivers/edac/edac_pci_sysfs.c
-@@ -162,14 +162,6 @@ static int edac_pci_create_instance_kobj(struct edac_pci_ctl_info *pci, int idx)
+ out_list:
+-	list_del(&adap->list);
+ 	idr_remove(&i2c_adapter_idr, adap->nr);
+ 	goto out_unlock;
+ }
+@@ -394,11 +462,11 @@ retry:
+ 	if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0)
+ 		return -ENOMEM;
  
- 	debugf0("%s()\n", __func__);
+-	mutex_lock(&core_lists);
++	mutex_lock(&core_lock);
+ 	/* "above" here means "above or equal to", sigh */
+ 	res = idr_get_new_above(&i2c_adapter_idr, adapter,
+ 				__i2c_first_dynamic_bus_num, &id);
+-	mutex_unlock(&core_lists);
++	mutex_unlock(&core_lock);
+ 
+ 	if (res < 0) {
+ 		if (res == -EAGAIN)
+@@ -443,7 +511,7 @@ retry:
+ 	if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0)
+ 		return -ENOMEM;
  
--	/* Set the parent and the instance's ktype */
--	pci->kobj.parent = &edac_pci_top_main_kobj;
--	pci->kobj.ktype = &ktype_pci_instance;
--
--	err = kobject_set_name(&pci->kobj, "pci%d", idx);
--	if (err)
--		return err;
--
- 	/* First bump the ref count on the top main kobj, which will
- 	 * track the number of PCI instances we have, and thus nest
- 	 * properly on keeping the module loaded
-@@ -181,7 +173,8 @@ static int edac_pci_create_instance_kobj(struct edac_pci_ctl_info *pci, int idx)
+-	mutex_lock(&core_lists);
++	mutex_lock(&core_lock);
+ 	/* "above" here means "above or equal to", sigh;
+ 	 * we need the "equal to" result to force the result
+ 	 */
+@@ -452,7 +520,7 @@ retry:
+ 		status = -EBUSY;
+ 		idr_remove(&i2c_adapter_idr, id);
  	}
+-	mutex_unlock(&core_lists);
++	mutex_unlock(&core_lock);
+ 	if (status == -EAGAIN)
+ 		goto retry;
  
- 	/* And now register this new kobject under the main kobj */
--	err = kobject_register(&pci->kobj);
-+	err = kobject_init_and_add(&pci->kobj, &ktype_pci_instance,
-+				   &edac_pci_top_main_kobj, "pci%d", idx);
- 	if (err != 0) {
- 		debugf2("%s() failed to register instance pci%d\n",
- 			__func__, idx);
-@@ -189,6 +182,7 @@ static int edac_pci_create_instance_kobj(struct edac_pci_ctl_info *pci, int idx)
- 		goto error_out;
- 	}
+@@ -462,6 +530,21 @@ retry:
+ }
+ EXPORT_SYMBOL_GPL(i2c_add_numbered_adapter);
  
-+	kobject_uevent(&pci->kobj, KOBJ_ADD);
- 	debugf1("%s() Register instance 'pci%d' kobject\n", __func__, idx);
++static int i2c_do_del_adapter(struct device_driver *d, void *data)
++{
++	struct i2c_driver *driver = to_i2c_driver(d);
++	struct i2c_adapter *adapter = data;
++	int res;
++
++	if (!driver->detach_adapter)
++		return 0;
++	res = driver->detach_adapter(adapter);
++	if (res)
++		dev_err(&adapter->dev, "detach_adapter failed (%d) "
++			"for driver [%s]\n", res, driver->driver.name);
++	return res;
++}
++
+ /**
+  * i2c_del_adapter - unregister I2C adapter
+  * @adap: the adapter being unregistered
+@@ -473,35 +556,24 @@ EXPORT_SYMBOL_GPL(i2c_add_numbered_adapter);
+ int i2c_del_adapter(struct i2c_adapter *adap)
+ {
+ 	struct list_head  *item, *_n;
+-	struct i2c_adapter *adap_from_list;
+-	struct i2c_driver *driver;
+ 	struct i2c_client *client;
+ 	int res = 0;
  
- 	return 0;
-@@ -211,7 +205,7 @@ void edac_pci_unregister_sysfs_instance_kobj(struct edac_pci_ctl_info *pci)
- 	 * function release the main reference count and then
- 	 * kfree the memory
- 	 */
--	kobject_unregister(&pci->kobj);
-+	kobject_put(&pci->kobj);
- }
+-	mutex_lock(&core_lists);
++	mutex_lock(&core_lock);
  
- /***************************** EDAC PCI sysfs root **********************/
-@@ -364,14 +358,6 @@ int edac_pci_main_kobj_setup(void)
- 		goto decrement_count_fail;
+ 	/* First make sure that this adapter was ever added */
+-	list_for_each_entry(adap_from_list, &adapters, list) {
+-		if (adap_from_list == adap)
+-			break;
+-	}
+-	if (adap_from_list != adap) {
++	if (idr_find(&i2c_adapter_idr, adap->nr) != adap) {
+ 		pr_debug("i2c-core: attempting to delete unregistered "
+ 			 "adapter [%s]\n", adap->name);
+ 		res = -EINVAL;
+ 		goto out_unlock;
  	}
  
--	/* Need the kobject hook ups, and name setting */
--	edac_pci_top_main_kobj.ktype = &ktype_edac_pci_main_kobj;
--	edac_pci_top_main_kobj.parent = &edac_class->kset.kobj;
--
--	err = kobject_set_name(&edac_pci_top_main_kobj, "pci");
--	if (err)
--		goto decrement_count_fail;
--
- 	/* Bump the reference count on this module to ensure the
- 	 * modules isn't unloaded until we deconstruct the top
- 	 * level main kobj for EDAC PCI
-@@ -383,23 +369,24 @@ int edac_pci_main_kobj_setup(void)
- 	}
+-	list_for_each(item,&drivers) {
+-		driver = list_entry(item, struct i2c_driver, list);
+-		if (driver->detach_adapter)
+-			if ((res = driver->detach_adapter(adap))) {
+-				dev_err(&adap->dev, "detach_adapter failed "
+-					"for driver [%s]\n",
+-					driver->driver.name);
+-				goto out_unlock;
+-			}
+-	}
++	/* Tell drivers about this removal */
++	res = bus_for_each_drv(&i2c_bus_type, NULL, adap,
++			       i2c_do_del_adapter);
++	if (res)
++		goto out_unlock;
  
- 	/* Instanstiate the pci object */
--	/* FIXME: maybe new sysdev_create_subdir() */
--	err = kobject_register(&edac_pci_top_main_kobj);
-+	err = kobject_init_and_add(&edac_pci_top_main_kobj, &ktype_edac_pci_main_kobj,
-+				   &edac_class->kset.kobj, "pci");
- 	if (err) {
- 		debugf1("Failed to register '.../edac/pci'\n");
--		goto kobject_register_fail;
-+		goto kobject_init_and_add_fail;
- 	}
+ 	/* detach any active clients. This must be done first, because
+ 	 * it can fail; in which case we give up. */
+@@ -529,7 +601,6 @@ int i2c_del_adapter(struct i2c_adapter *adap)
+ 	/* clean up the sysfs representation */
+ 	init_completion(&adap->dev_released);
+ 	device_unregister(&adap->dev);
+-	list_del(&adap->list);
+ 
+ 	/* wait for sysfs to drop all references */
+ 	wait_for_completion(&adap->dev_released);
+@@ -540,7 +611,7 @@ int i2c_del_adapter(struct i2c_adapter *adap)
+ 	dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
+ 
+  out_unlock:
+-	mutex_unlock(&core_lists);
++	mutex_unlock(&core_lock);
+ 	return res;
+ }
+ EXPORT_SYMBOL(i2c_del_adapter);
+@@ -583,21 +654,23 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
+ 	if (res)
+ 		return res;
  
- 	/* At this point, to 'release' the top level kobject
- 	 * for EDAC PCI, then edac_pci_main_kobj_teardown()
- 	 * must be used, for resources to be cleaned up properly
- 	 */
-+	kobject_uevent(&edac_pci_top_main_kobj, KOBJ_ADD);
- 	debugf1("Registered '.../edac/pci' kobject\n");
+-	mutex_lock(&core_lists);
++	mutex_lock(&core_lock);
  
- 	return 0;
+-	list_add_tail(&driver->list,&drivers);
+ 	pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
  
- 	/* Error unwind statck */
--kobject_register_fail:
-+kobject_init_and_add_fail:
- 	module_put(THIS_MODULE);
+ 	/* legacy drivers scan i2c busses directly */
+ 	if (driver->attach_adapter) {
+ 		struct i2c_adapter *adapter;
  
- decrement_count_fail:
-@@ -424,9 +411,9 @@ static void edac_pci_main_kobj_teardown(void)
- 	 * main kobj
- 	 */
- 	if (atomic_dec_return(&edac_pci_sysfs_refcount) == 0) {
--		debugf0("%s() called kobject_unregister on main kobj\n",
-+		debugf0("%s() called kobject_put on main kobj\n",
- 			__func__);
--		kobject_unregister(&edac_pci_top_main_kobj);
-+		kobject_put(&edac_pci_top_main_kobj);
+-		list_for_each_entry(adapter, &adapters, list) {
++		down(&i2c_adapter_class.sem);
++		list_for_each_entry(adapter, &i2c_adapter_class.devices,
++				    dev.node) {
+ 			driver->attach_adapter(adapter);
+ 		}
++		up(&i2c_adapter_class.sem);
  	}
- }
  
-diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
-index 624ff3e..c2169d2 100644
---- a/drivers/firewire/fw-sbp2.c
-+++ b/drivers/firewire/fw-sbp2.c
-@@ -1238,6 +1238,12 @@ static int sbp2_scsi_slave_alloc(struct scsi_device *sdev)
+-	mutex_unlock(&core_lists);
++	mutex_unlock(&core_lock);
+ 	return 0;
+ }
+ EXPORT_SYMBOL(i2c_register_driver);
+@@ -609,11 +682,11 @@ EXPORT_SYMBOL(i2c_register_driver);
+  */
+ void i2c_del_driver(struct i2c_driver *driver)
+ {
+-	struct list_head   *item1, *item2, *_n;
++	struct list_head   *item2, *_n;
+ 	struct i2c_client  *client;
+ 	struct i2c_adapter *adap;
  
- 	sdev->allow_restart = 1;
+-	mutex_lock(&core_lists);
++	mutex_lock(&core_lock);
  
-+	/*
-+	 * Update the dma alignment (minimum alignment requirements for
-+	 * start and end of DMA transfers) to be a sector
-+	 */
-+	blk_queue_update_dma_alignment(sdev->request_queue, 511);
-+
- 	if (lu->tgt->workarounds & SBP2_WORKAROUND_INQUIRY_36)
- 		sdev->inquiry_len = 36;
+ 	/* new-style driver? */
+ 	if (is_newstyle_driver(driver))
+@@ -623,8 +696,8 @@ void i2c_del_driver(struct i2c_driver *driver)
+ 	 * attached. If so, detach them to be able to kill the driver
+ 	 * afterwards.
+ 	 */
+-	list_for_each(item1,&adapters) {
+-		adap = list_entry(item1, struct i2c_adapter, list);
++	down(&i2c_adapter_class.sem);
++	list_for_each_entry(adap, &i2c_adapter_class.devices, dev.node) {
+ 		if (driver->detach_adapter) {
+ 			if (driver->detach_adapter(adap)) {
+ 				dev_err(&adap->dev, "detach_adapter failed "
+@@ -648,40 +721,31 @@ void i2c_del_driver(struct i2c_driver *driver)
+ 			}
+ 		}
+ 	}
++	up(&i2c_adapter_class.sem);
  
-diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c
-index 6942e06..d168223 100644
---- a/drivers/firmware/edd.c
-+++ b/drivers/firmware/edd.c
-@@ -631,7 +631,7 @@ static struct kobj_type edd_ktype = {
- 	.default_attrs	= def_attrs,
- };
+  unregister:
+ 	driver_unregister(&driver->driver);
+-	list_del(&driver->list);
+ 	pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name);
  
--static decl_subsys(edd, &edd_ktype, NULL);
-+static struct kset *edd_kset;
+-	mutex_unlock(&core_lists);
++	mutex_unlock(&core_lock);
+ }
+ EXPORT_SYMBOL(i2c_del_driver);
  
+ /* ------------------------------------------------------------------------- */
  
- /**
-@@ -693,7 +693,7 @@ edd_create_symlink_to_pcidev(struct edd_device *edev)
- static inline void
- edd_device_unregister(struct edd_device *edev)
+-static int __i2c_check_addr(struct i2c_adapter *adapter, unsigned int addr)
++static int __i2c_check_addr(struct device *dev, void *addrp)
  {
--	kobject_unregister(&edev->kobj);
-+	kobject_put(&edev->kobj);
+-	struct list_head   *item;
+-	struct i2c_client  *client;
++	struct i2c_client	*client = i2c_verify_client(dev);
++	int			addr = *(int *)addrp;
+ 
+-	list_for_each(item,&adapter->clients) {
+-		client = list_entry(item, struct i2c_client, list);
+-		if (client->addr == addr)
+-			return -EBUSY;
+-	}
++	if (client && client->addr == addr)
++		return -EBUSY;
+ 	return 0;
  }
  
- static void edd_populate_dir(struct edd_device * edev)
-@@ -721,12 +721,13 @@ edd_device_register(struct edd_device *edev, int i)
- 	if (!edev)
- 		return 1;
- 	edd_dev_set_info(edev, i);
--	kobject_set_name(&edev->kobj, "int13_dev%02x",
--			 0x80 + i);
--	kobj_set_kset_s(edev,edd_subsys);
--	error = kobject_register(&edev->kobj);
--	if (!error)
-+	edev->kobj.kset = edd_kset;
-+	error = kobject_init_and_add(&edev->kobj, &edd_ktype, NULL,
-+				     "int13_dev%02x", 0x80 + i);
-+	if (!error) {
- 		edd_populate_dir(edev);
-+		kobject_uevent(&edev->kobj, KOBJ_ADD);
-+	}
- 	return error;
+ static int i2c_check_addr(struct i2c_adapter *adapter, int addr)
+ {
+-	int rval;
+-
+-	mutex_lock(&adapter->clist_lock);
+-	rval = __i2c_check_addr(adapter, addr);
+-	mutex_unlock(&adapter->clist_lock);
+-
+-	return rval;
++	return device_for_each_child(&adapter->dev, &addr, __i2c_check_addr);
  }
  
-@@ -755,9 +756,9 @@ edd_init(void)
- 		return 1;
- 	}
- 
--	rc = firmware_register(&edd_subsys);
--	if (rc)
--		return rc;
-+	edd_kset = kset_create_and_add("edd", NULL, firmware_kobj);
-+	if (!edd_kset)
-+		return -ENOMEM;
+ int i2c_attach_client(struct i2c_client *client)
+@@ -689,15 +753,6 @@ int i2c_attach_client(struct i2c_client *client)
+ 	struct i2c_adapter *adapter = client->adapter;
+ 	int res = 0;
  
- 	for (i = 0; i < edd_num_devices() && !rc; i++) {
- 		edev = kzalloc(sizeof (*edev), GFP_KERNEL);
-@@ -773,7 +774,7 @@ edd_init(void)
- 	}
+-	mutex_lock(&adapter->clist_lock);
+-	if (__i2c_check_addr(client->adapter, client->addr)) {
+-		res = -EBUSY;
+-		goto out_unlock;
+-	}
+-	list_add_tail(&client->list,&adapter->clients);
+-
+-	client->usage_count = 0;
+-
+ 	client->dev.parent = &client->adapter->dev;
+ 	client->dev.bus = &i2c_bus_type;
  
- 	if (rc)
--		firmware_unregister(&edd_subsys);
-+		kset_unregister(edd_kset);
- 	return rc;
- }
+@@ -712,13 +767,17 @@ int i2c_attach_client(struct i2c_client *client)
  
-@@ -787,7 +788,7 @@ edd_exit(void)
- 		if ((edev = edd_devices[i]))
- 			edd_device_unregister(edev);
- 	}
--	firmware_unregister(&edd_subsys);
-+	kset_unregister(edd_kset);
- }
+ 	snprintf(&client->dev.bus_id[0], sizeof(client->dev.bus_id),
+ 		"%d-%04x", i2c_adapter_id(adapter), client->addr);
+-	dev_dbg(&adapter->dev, "client [%s] registered with bus id %s\n",
+-		client->name, client->dev.bus_id);
+ 	res = device_register(&client->dev);
+ 	if (res)
+-		goto out_list;
++		goto out_err;
++
++	mutex_lock(&adapter->clist_lock);
++	list_add_tail(&client->list, &adapter->clients);
+ 	mutex_unlock(&adapter->clist_lock);
  
- late_initcall(edd_init);
-diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
-index 858a7b9..f4f709d 100644
---- a/drivers/firmware/efivars.c
-+++ b/drivers/firmware/efivars.c
-@@ -129,13 +129,6 @@ struct efivar_attribute {
- };
++	dev_dbg(&adapter->dev, "client [%s] registered with bus id %s\n",
++		client->name, client->dev.bus_id);
++
+ 	if (adapter->client_register)  {
+ 		if (adapter->client_register(client)) {
+ 			dev_dbg(&adapter->dev, "client_register "
+@@ -729,12 +788,9 @@ int i2c_attach_client(struct i2c_client *client)
  
+ 	return 0;
  
--#define EFI_ATTR(_name, _mode, _show, _store) \
--struct subsys_attribute efi_attr_##_name = { \
--	.attr = {.name = __stringify(_name), .mode = _mode}, \
--	.show = _show, \
--	.store = _store, \
--};
--
- #define EFIVAR_ATTR(_name, _mode, _show, _store) \
- struct efivar_attribute efivar_attr_##_name = { \
- 	.attr = {.name = __stringify(_name), .mode = _mode}, \
-@@ -143,13 +136,6 @@ struct efivar_attribute efivar_attr_##_name = { \
- 	.store = _store, \
- };
+-out_list:
+-	list_del(&client->list);
++out_err:
+ 	dev_err(&adapter->dev, "Failed to attach i2c client %s at 0x%02x "
+ 		"(%d)\n", client->name, client->addr, res);
+-out_unlock:
+-	mutex_unlock(&adapter->clist_lock);
+ 	return res;
+ }
+ EXPORT_SYMBOL(i2c_attach_client);
+@@ -744,12 +800,6 @@ int i2c_detach_client(struct i2c_client *client)
+ 	struct i2c_adapter *adapter = client->adapter;
+ 	int res = 0;
  
--#define VAR_SUBSYS_ATTR(_name, _mode, _show, _store) \
--struct subsys_attribute var_subsys_attr_##_name = { \
--	.attr = {.name = __stringify(_name), .mode = _mode}, \
--	.show = _show, \
--	.store = _store, \
--};
+-	if (client->usage_count > 0) {
+-		dev_warn(&client->dev, "Client [%s] still busy, "
+-			 "can't detach\n", client->name);
+-		return -EBUSY;
+-	}
 -
- #define to_efivar_attr(_attr) container_of(_attr, struct efivar_attribute, attr)
- #define to_efivar_entry(obj)  container_of(obj, struct efivar_entry, kobj)
- 
-@@ -408,21 +394,16 @@ static struct kobj_type efivar_ktype = {
- 	.default_attrs = def_attrs,
- };
+ 	if (adapter->client_unregister)  {
+ 		res = adapter->client_unregister(client);
+ 		if (res) {
+@@ -762,9 +812,10 @@ int i2c_detach_client(struct i2c_client *client)
+ 
+ 	mutex_lock(&adapter->clist_lock);
+ 	list_del(&client->list);
++	mutex_unlock(&adapter->clist_lock);
++
+ 	init_completion(&client->released);
+ 	device_unregister(&client->dev);
+-	mutex_unlock(&adapter->clist_lock);
+ 	wait_for_completion(&client->released);
  
--static ssize_t
--dummy(struct kset *kset, char *buf)
--{
--	return -ENODEV;
--}
--
- static inline void
- efivar_unregister(struct efivar_entry *var)
- {
--	kobject_unregister(&var->kobj);
-+	kobject_put(&var->kobj);
+  out:
+@@ -772,72 +823,58 @@ int i2c_detach_client(struct i2c_client *client)
  }
+ EXPORT_SYMBOL(i2c_detach_client);
  
- 
--static ssize_t
--efivar_create(struct kset *kset, const char *buf, size_t count)
-+static ssize_t efivar_create(struct kobject *kobj,
-+			     struct bin_attribute *bin_attr,
-+			     char *buf, loff_t pos, size_t count)
+-static int i2c_inc_use_client(struct i2c_client *client)
++/**
++ * i2c_use_client - increments the reference count of the i2c client structure
++ * @client: the client being referenced
++ *
++ * Each live reference to a client should be refcounted. The driver model does
++ * that automatically as part of driver binding, so that most drivers don't
++ * need to do this explicitly: they hold a reference until they're unbound
++ * from the device.
++ *
++ * A pointer to the client with the incremented reference counter is returned.
++ */
++struct i2c_client *i2c_use_client(struct i2c_client *client)
  {
- 	struct efi_variable *new_var = (struct efi_variable *)buf;
- 	struct efivar_entry *search_efivar, *n;
-@@ -479,8 +460,9 @@ efivar_create(struct kset *kset, const char *buf, size_t count)
- 	return count;
+-
+-	if (!try_module_get(client->driver->driver.owner))
+-		return -ENODEV;
+-	if (!try_module_get(client->adapter->owner)) {
+-		module_put(client->driver->driver.owner);
+-		return -ENODEV;
+-	}
+-
+-	return 0;
++	get_device(&client->dev);
++	return client;
  }
++EXPORT_SYMBOL(i2c_use_client);
  
--static ssize_t
--efivar_delete(struct kset *kset, const char *buf, size_t count)
-+static ssize_t efivar_delete(struct kobject *kobj,
-+			     struct bin_attribute *bin_attr,
-+			     char *buf, loff_t pos, size_t count)
+-static void i2c_dec_use_client(struct i2c_client *client)
++/**
++ * i2c_release_client - release a use of the i2c client structure
++ * @client: the client being no longer referenced
++ *
++ * Must be called when a user of a client is finished with it.
++ */
++void i2c_release_client(struct i2c_client *client)
  {
- 	struct efi_variable *del_var = (struct efi_variable *)buf;
- 	struct efivar_entry *search_efivar, *n;
-@@ -537,25 +519,26 @@ efivar_delete(struct kset *kset, const char *buf, size_t count)
- 	return count;
+-	module_put(client->driver->driver.owner);
+-	module_put(client->adapter->owner);
++	put_device(&client->dev);
  }
++EXPORT_SYMBOL(i2c_release_client);
  
--static VAR_SUBSYS_ATTR(new_var, 0200, dummy, efivar_create);
--static VAR_SUBSYS_ATTR(del_var, 0200, dummy, efivar_delete);
-+static struct bin_attribute var_subsys_attr_new_var = {
-+	.attr = {.name = "new_var", .mode = 0200},
-+	.write = efivar_create,
+-int i2c_use_client(struct i2c_client *client)
+-{
+-	int ret;
+-
+-	ret = i2c_inc_use_client(client);
+-	if (ret)
+-		return ret;
+-
+-	client->usage_count++;
+-
+-	return 0;
+-}
+-EXPORT_SYMBOL(i2c_use_client);
++struct i2c_cmd_arg {
++	unsigned	cmd;
++	void		*arg;
 +};
  
--static struct subsys_attribute *var_subsys_attrs[] = {
--	&var_subsys_attr_new_var,
--	&var_subsys_attr_del_var,
--	NULL,
-+static struct bin_attribute var_subsys_attr_del_var = {
-+	.attr = {.name = "del_var", .mode = 0200},
-+	.write = efivar_delete,
- };
- 
- /*
-  * Let's not leave out systab information that snuck into
-  * the efivars driver
-  */
--static ssize_t
--systab_read(struct kset *kset, char *buf)
-+static ssize_t systab_show(struct kobject *kobj,
-+			   struct kobj_attribute *attr, char *buf)
- {
- 	char *str = buf;
- 
--	if (!kset || !buf)
-+	if (!kobj || !buf)
- 		return -EINVAL;
+-int i2c_release_client(struct i2c_client *client)
++static int i2c_cmd(struct device *dev, void *_arg)
+ {
+-	if (!client->usage_count) {
+-		pr_debug("i2c-core: %s used one too many times\n",
+-			 __FUNCTION__);
+-		return -EPERM;
+-	}
+-
+-	client->usage_count--;
+-	i2c_dec_use_client(client);
++	struct i2c_client	*client = i2c_verify_client(dev);
++	struct i2c_cmd_arg	*arg = _arg;
  
- 	if (efi.mps != EFI_INVALID_TABLE_ADDR)
-@@ -576,15 +559,21 @@ systab_read(struct kset *kset, char *buf)
- 	return str - buf;
++	if (client && client->driver && client->driver->command)
++		client->driver->command(client, arg->cmd, arg->arg);
+ 	return 0;
  }
+-EXPORT_SYMBOL(i2c_release_client);
  
--static EFI_ATTR(systab, 0400, systab_read, NULL);
-+static struct kobj_attribute efi_attr_systab =
-+			__ATTR(systab, 0400, systab_show, NULL);
+ void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg)
+ {
+-	struct list_head  *item;
+-	struct i2c_client *client;
++	struct i2c_cmd_arg	cmd_arg;
  
--static struct subsys_attribute *efi_subsys_attrs[] = {
--	&efi_attr_systab,
-+static struct attribute *efi_subsys_attrs[] = {
-+	&efi_attr_systab.attr,
- 	NULL,	/* maybe more in the future? */
- };
+-	mutex_lock(&adap->clist_lock);
+-	list_for_each(item,&adap->clients) {
+-		client = list_entry(item, struct i2c_client, list);
+-		if (!try_module_get(client->driver->driver.owner))
+-			continue;
+-		if (NULL != client->driver->command) {
+-			mutex_unlock(&adap->clist_lock);
+-			client->driver->command(client,cmd,arg);
+-			mutex_lock(&adap->clist_lock);
+-		}
+-		module_put(client->driver->driver.owner);
+-       }
+-       mutex_unlock(&adap->clist_lock);
++	cmd_arg.cmd = cmd;
++	cmd_arg.arg = arg;
++	device_for_each_child(&adap->dev, &cmd_arg, i2c_cmd);
+ }
+ EXPORT_SYMBOL(i2c_clients_command);
  
--static decl_subsys(vars, &efivar_ktype, NULL);
--static decl_subsys(efi, NULL, NULL);
-+static struct attribute_group efi_subsys_attr_group = {
-+	.attrs = efi_subsys_attrs,
-+};
-+
+@@ -848,11 +885,24 @@ static int __init i2c_init(void)
+ 	retval = bus_register(&i2c_bus_type);
+ 	if (retval)
+ 		return retval;
+-	return class_register(&i2c_adapter_class);
++	retval = class_register(&i2c_adapter_class);
++	if (retval)
++		goto bus_err;
++	retval = i2c_add_driver(&dummy_driver);
++	if (retval)
++		goto class_err;
++	return 0;
 +
-+static struct kset *vars_kset;
-+static struct kobject *efi_kobj;
- 
- /*
-  * efivar_create_sysfs_entry()
-@@ -628,15 +617,16 @@ efivar_create_sysfs_entry(unsigned long variable_name_size,
- 	*(short_name + strlen(short_name)) = '-';
- 	efi_guid_unparse(vendor_guid, short_name + strlen(short_name));
++class_err:
++	class_unregister(&i2c_adapter_class);
++bus_err:
++	bus_unregister(&i2c_bus_type);
++	return retval;
+ }
  
--	kobject_set_name(&new_efivar->kobj, "%s", short_name);
--	kobj_set_kset_s(new_efivar, vars_subsys);
--	i = kobject_register(&new_efivar->kobj);
-+	new_efivar->kobj.kset = vars_kset;
-+	i = kobject_init_and_add(&new_efivar->kobj, &efivar_ktype, NULL,
-+				 "%s", short_name);
- 	if (i) {
- 		kfree(short_name);
- 		kfree(new_efivar);
- 		return 1;
- 	}
+ static void __exit i2c_exit(void)
+ {
++	i2c_del_driver(&dummy_driver);
+ 	class_unregister(&i2c_adapter_class);
+ 	bus_unregister(&i2c_bus_type);
+ }
+@@ -879,7 +929,15 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
+ 		}
+ #endif
  
-+	kobject_uevent(&new_efivar->kobj, KOBJ_ADD);
- 	kfree(short_name);
- 	short_name = NULL;
+-		mutex_lock_nested(&adap->bus_lock, adap->level);
++		if (in_atomic() || irqs_disabled()) {
++			ret = mutex_trylock(&adap->bus_lock);
++			if (!ret)
++				/* I2C activity is ongoing. */
++				return -EAGAIN;
++		} else {
++			mutex_lock_nested(&adap->bus_lock, adap->level);
++		}
++
+ 		ret = adap->algo->master_xfer(adap,msgs,num);
+ 		mutex_unlock(&adap->bus_lock);
  
-@@ -660,9 +650,8 @@ efivars_init(void)
- 	efi_status_t status = EFI_NOT_FOUND;
- 	efi_guid_t vendor_guid;
- 	efi_char16_t *variable_name;
--	struct subsys_attribute *attr;
- 	unsigned long variable_name_size = 1024;
--	int i, error = 0;
-+	int error = 0;
+@@ -978,7 +1036,7 @@ static int i2c_probe_address(struct i2c_adapter *adapter, int addr, int kind,
+ }
  
- 	if (!efi_enabled)
- 		return -ENODEV;
-@@ -676,23 +665,18 @@ efivars_init(void)
- 	printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,
- 	       EFIVARS_DATE);
+ int i2c_probe(struct i2c_adapter *adapter,
+-	      struct i2c_client_address_data *address_data,
++	      const struct i2c_client_address_data *address_data,
+ 	      int (*found_proc) (struct i2c_adapter *, int, int))
+ {
+ 	int i, err;
+@@ -987,7 +1045,7 @@ int i2c_probe(struct i2c_adapter *adapter,
+ 	/* Force entries are done first, and are not affected by ignore
+ 	   entries */
+ 	if (address_data->forces) {
+-		unsigned short **forces = address_data->forces;
++		const unsigned short * const *forces = address_data->forces;
+ 		int kind;
  
--	/*
--	 * For now we'll register the efi subsys within this driver
--	 */
--
--	error = firmware_register(&efi_subsys);
--
--	if (error) {
--		printk(KERN_ERR "efivars: Firmware registration failed with error %d.\n", error);
-+	/* For now we'll register the efi directory at /sys/firmware/efi */
-+	efi_kobj = kobject_create_and_add("efi", firmware_kobj);
-+	if (!efi_kobj) {
-+		printk(KERN_ERR "efivars: Firmware registration failed.\n");
-+		error = -ENOMEM;
- 		goto out_free;
+ 		for (kind = 0; forces[kind]; kind++) {
+@@ -1085,7 +1143,6 @@ i2c_new_probed_device(struct i2c_adapter *adap,
+ 		return NULL;
  	}
  
--	kobj_set_kset_s(&vars_subsys, efi_subsys);
--
--	error = subsystem_register(&vars_subsys);
--
--	if (error) {
--		printk(KERN_ERR "efivars: Subsystem registration failed with error %d.\n", error);
-+	vars_kset = kset_create_and_add("vars", NULL, efi_kobj);
-+	if (!vars_kset) {
-+		printk(KERN_ERR "efivars: Subsystem registration failed.\n");
-+		error = -ENOMEM;
- 		goto out_firmware_unregister;
+-	mutex_lock(&adap->clist_lock);
+ 	for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) {
+ 		/* Check address validity */
+ 		if (addr_list[i] < 0x03 || addr_list[i] > 0x77) {
+@@ -1095,7 +1152,7 @@ i2c_new_probed_device(struct i2c_adapter *adap,
+ 		}
+ 
+ 		/* Check address availability */
+-		if (__i2c_check_addr(adap, addr_list[i])) {
++		if (i2c_check_addr(adap, addr_list[i])) {
+ 			dev_dbg(&adap->dev, "Address 0x%02x already in "
+ 				"use, not probing\n", addr_list[i]);
+ 			continue;
+@@ -1123,7 +1180,6 @@ i2c_new_probed_device(struct i2c_adapter *adap,
+ 				break;
+ 		}
  	}
+-	mutex_unlock(&adap->clist_lock);
  
-@@ -727,28 +711,28 @@ efivars_init(void)
- 	 * Now add attributes to allow creation of new vars
- 	 * and deletion of existing ones...
- 	 */
--
--	for (i = 0; (attr = var_subsys_attrs[i]) && !error; i++) {
--		if (attr->show && attr->store)
--			error = subsys_create_file(&vars_subsys, attr);
--	}
-+	error = sysfs_create_bin_file(&vars_kset->kobj,
-+				      &var_subsys_attr_new_var);
-+	if (error)
-+		printk(KERN_ERR "efivars: unable to create new_var sysfs file"
-+			" due to error %d\n", error);
-+	error = sysfs_create_bin_file(&vars_kset->kobj,
-+				      &var_subsys_attr_del_var);
-+	if (error)
-+		printk(KERN_ERR "efivars: unable to create del_var sysfs file"
-+			" due to error %d\n", error);
+ 	if (addr_list[i] == I2C_CLIENT_END) {
+ 		dev_dbg(&adap->dev, "Probing failed, no device found\n");
+@@ -1139,12 +1195,12 @@ struct i2c_adapter* i2c_get_adapter(int id)
+ {
+ 	struct i2c_adapter *adapter;
+ 
+-	mutex_lock(&core_lists);
++	mutex_lock(&core_lock);
+ 	adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id);
+ 	if (adapter && !try_module_get(adapter->owner))
+ 		adapter = NULL;
+ 
+-	mutex_unlock(&core_lists);
++	mutex_unlock(&core_lock);
+ 	return adapter;
+ }
+ EXPORT_SYMBOL(i2c_get_adapter);
+diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
+index df540d5..393e679 100644
+--- a/drivers/i2c/i2c-dev.c
++++ b/drivers/i2c/i2c-dev.c
+@@ -182,27 +182,22 @@ static ssize_t i2cdev_write (struct file *file, const char __user *buf, size_t c
+ 	return ret;
+ }
  
- 	/* Don't forget the systab entry */
++static int i2cdev_check(struct device *dev, void *addrp)
++{
++	struct i2c_client *client = i2c_verify_client(dev);
++
++	if (!client || client->addr != *(unsigned int *)addrp)
++		return 0;
++
++	return dev->driver ? -EBUSY : 0;
++}
++
+ /* This address checking function differs from the one in i2c-core
+    in that it considers an address with a registered device, but no
+-   bound driver, as NOT busy. */
++   driver bound to it, as NOT busy. */
+ static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr)
+ {
+-	struct list_head *item;
+-	struct i2c_client *client;
+-	int res = 0;
 -
--	for (i = 0; (attr = efi_subsys_attrs[i]) && !error; i++) {
--		if (attr->show)
--			error = subsys_create_file(&efi_subsys, attr);
+-	mutex_lock(&adapter->clist_lock);
+-	list_for_each(item, &adapter->clients) {
+-		client = list_entry(item, struct i2c_client, list);
+-		if (client->addr == addr) {
+-			if (client->driver)
+-				res = -EBUSY;
+-			break;
+-		}
 -	}
+-	mutex_unlock(&adapter->clist_lock);
 -
-+	error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
- 	if (error)
- 		printk(KERN_ERR "efivars: Sysfs attribute export failed with error %d.\n", error);
- 	else
- 		goto out_free;
- 
--	subsystem_unregister(&vars_subsys);
-+	kset_unregister(vars_kset);
- 
- out_firmware_unregister:
--	firmware_unregister(&efi_subsys);
-+	kobject_put(efi_kobj);
- 
- out_free:
- 	kfree(variable_name);
-@@ -768,8 +752,8 @@ efivars_exit(void)
- 		efivar_unregister(entry);
- 	}
- 
--	subsystem_unregister(&vars_subsys);
--	firmware_unregister(&efi_subsys);
-+	kset_unregister(vars_kset);
-+	kobject_put(efi_kobj);
- }
- 
- module_init(efivars_init);
-diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c
-index b767603..ebfbb29 100644
---- a/drivers/i2c/chips/isp1301_omap.c
-+++ b/drivers/i2c/chips/isp1301_omap.c
-@@ -259,12 +259,6 @@ static inline const char *state_name(struct isp1301 *isp)
- 	return state_string(isp->otg.state);
+-	return res;
++	return device_for_each_child(&adapter->dev, &addr, i2cdev_check);
  }
  
--#ifdef	VERBOSE
--#define	dev_vdbg			dev_dbg
--#else
--#define	dev_vdbg(dev, fmt, arg...)	do{}while(0)
--#endif
--
- /*-------------------------------------------------------------------------*/
- 
- /* NOTE:  some of this ISP1301 setup is specific to H2 boards;
+ static int i2cdev_ioctl(struct inode *inode, struct file *file,
 diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
 index fb06555..64df55e 100644
 --- a/drivers/ide/Kconfig
@@ -74091,6 +88269,32 @@
  				pmu_resume();
  			}
  			if (bay->cd_index == -1) {
+diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
+index 5452da1..b66da74 100644
+--- a/drivers/macintosh/therm_windtunnel.c
++++ b/drivers/macintosh/therm_windtunnel.c
+@@ -47,12 +47,10 @@
+ 
+ #define LOG_TEMP		0			/* continously log temperature */
+ 
+-#define I2C_DRIVERID_G4FAN	0x9001			/* fixme */
+-
+ static int 			do_probe( struct i2c_adapter *adapter, int addr, int kind);
+ 
+ /* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */
+-static unsigned short		normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
++static const unsigned short	normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
+ 						 0x4c, 0x4d, 0x4e, 0x4f,
+ 						 0x2c, 0x2d, 0x2e, 0x2f,
+ 						 I2C_CLIENT_END };
+@@ -357,7 +355,6 @@ static struct i2c_driver g4fan_driver = {
+ 	.driver = {
+ 		.name	= "therm_windtunnel",
+ 	},
+-	.id		= I2C_DRIVERID_G4FAN,
+ 	.attach_adapter = do_attach,
+ 	.detach_client	= do_detach,
+ };
 diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
 index 6123c70..ac420b1 100644
 --- a/drivers/macintosh/via-pmu.c
@@ -96272,6 +110476,47 @@
  /* ----------------------------------------------------------- */
  /* cx88-video.c*/
  extern const u32 cx88_user_ctrls[];
+diff --git a/drivers/media/video/dpc7146.c b/drivers/media/video/dpc7146.c
+index 255dae3..566e479 100644
+--- a/drivers/media/video/dpc7146.c
++++ b/drivers/media/video/dpc7146.c
+@@ -87,11 +87,24 @@ struct dpc
+ 	int cur_input;	/* current input */
+ };
+ 
++static int dpc_check_clients(struct device *dev, void *data)
++{
++	struct dpc* dpc = data;
++	struct i2c_client *client = i2c_verify_client(dev);
++
++	if( !client )
++		return 0;
++
++	if( I2C_SAA7111A == client->addr )
++		dpc->saa7111a = client;
++
++	return 0;
++}
++
+ /* fixme: add vbi stuff here */
+ static int dpc_probe(struct saa7146_dev* dev)
+ {
+ 	struct dpc* dpc = NULL;
+-	struct i2c_client *client;
+ 
+ 	dpc = kzalloc(sizeof(struct dpc), GFP_KERNEL);
+ 	if( NULL == dpc ) {
+@@ -115,9 +128,7 @@ static int dpc_probe(struct saa7146_dev* dev)
+ 	}
+ 
+ 	/* loop through all i2c-devices on the bus and look who is there */
+-	list_for_each_entry(client, &dpc->i2c_adapter.clients, list)
+-		if( I2C_SAA7111A == client->addr )
+-			dpc->saa7111a = client;
++	device_for_each_child(&dpc->i2c_adapter.dev, dpc, dpc_check_clients);
+ 
+ 	/* check if all devices are present */
+ 	if( 0 == dpc->saa7111a ) {
 diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
 index c112780..abbd38c 100644
 --- a/drivers/media/video/em28xx/Kconfig
@@ -105125,6 +119370,18 @@
  		IVTVFB_ERR("Failed to allocate memory for osd_info\n");
  		return -ENOMEM;
  	}
+diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c
+index b6cd21e..4895540 100644
+--- a/drivers/media/video/ks0127.c
++++ b/drivers/media/video/ks0127.c
+@@ -764,7 +764,6 @@ static struct i2c_client ks0127_client_tmpl =
+ 	.addr = 0,
+ 	.adapter = NULL,
+ 	.driver = &i2c_driver_ks0127,
+-	.usage_count = 0
+ };
+ 
+ static int ks0127_found_proc(struct i2c_adapter *adapter, int addr, int kind)
 diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c
 new file mode 100644
 index 0000000..d4bf14c
@@ -106218,6 +120475,67 @@
  
  /* ---------------------------------------------------------------------- */
  
+diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
+index 98ad309..add6d0d 100644
+--- a/drivers/media/video/mxb.c
++++ b/drivers/media/video/mxb.c
+@@ -149,10 +149,33 @@ struct mxb
+ 
+ static struct saa7146_extension extension;
+ 
++static int mxb_check_clients(struct device *dev, void *data)
++{
++	struct mxb* mxb = data;
++	struct i2c_client *client = i2c_verify_client(dev);
++
++	if( !client )
++		return 0;
++
++	if( I2C_ADDR_TEA6420_1 == client->addr )
++		mxb->tea6420_1 = client;
++	if( I2C_ADDR_TEA6420_2 == client->addr )
++		mxb->tea6420_2 = client;
++	if( I2C_TEA6415C_2 == client->addr )
++		mxb->tea6415c = client;
++	if( I2C_ADDR_TDA9840 == client->addr )
++		mxb->tda9840 = client;
++	if( I2C_SAA7111 == client->addr )
++		mxb->saa7111a = client;
++	if( 0x60 == client->addr )
++		mxb->tuner = client;
++
++	return 0;
++}
++
+ static int mxb_probe(struct saa7146_dev* dev)
+ {
+ 	struct mxb* mxb = NULL;
+-	struct i2c_client *client;
+ 	int result;
+ 
+ 	if ((result = request_module("saa7111")) < 0) {
+@@ -195,20 +218,7 @@ static int mxb_probe(struct saa7146_dev* dev)
+ 	}
+ 
+ 	/* loop through all i2c-devices on the bus and look who is there */
+-	list_for_each_entry(client, &mxb->i2c_adapter.clients, list) {
+-		if( I2C_ADDR_TEA6420_1 == client->addr )
+-			mxb->tea6420_1 = client;
+-		if( I2C_ADDR_TEA6420_2 == client->addr )
+-			mxb->tea6420_2 = client;
+-		if( I2C_TEA6415C_2 == client->addr )
+-			mxb->tea6415c = client;
+-		if( I2C_ADDR_TDA9840 == client->addr )
+-			mxb->tda9840 = client;
+-		if( I2C_SAA7111 == client->addr )
+-			mxb->saa7111a = client;
+-		if( 0x60 == client->addr )
+-			mxb->tuner = client;
+-	}
++	device_for_each_child(&mxb->i2c_adapter.dev, mxb, mxb_check_clients);
+ 
+ 	/* check if all devices are present */
+ 	if(    0 == mxb->tea6420_1	|| 0 == mxb->tea6420_2	|| 0 == mxb->tea6415c
 diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig
 index d0c2cd7..6fc1b8b 100644
 --- a/drivers/media/video/pvrusb2/Kconfig
@@ -126818,6 +141136,60 @@
  					p->index,p->name,p->type,p->audioset,
  					p->tuner,
  					(unsigned long long)p->std,
+diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
+index 9a03dc8..5bb7529 100644
+--- a/drivers/media/video/vino.c
++++ b/drivers/media/video/vino.c
+@@ -2589,11 +2589,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs)
+ 	/* First try D1 and then SAA7191 */
+ 	if (vino_drvdata->camera.driver
+ 	    && (vino_drvdata->camera.owner == VINO_NO_CHANNEL)) {
+-		if (i2c_use_client(vino_drvdata->camera.driver)) {
+-			ret = -ENODEV;
+-			goto out;
+-		}
+-
++		i2c_use_client(vino_drvdata->camera.driver);
+ 		vino_drvdata->camera.owner = vcs->channel;
+ 		vcs->input = VINO_INPUT_D1;
+ 		vcs->data_norm = VINO_DATA_NORM_D1;
+@@ -2602,11 +2598,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs)
+ 		int input, data_norm;
+ 		int saa7191_input;
+ 
+-		if (i2c_use_client(vino_drvdata->decoder.driver)) {
+-			ret = -ENODEV;
+-			goto out;
+-		}
+-
++		i2c_use_client(vino_drvdata->decoder.driver);
+ 		input = VINO_INPUT_COMPOSITE;
+ 
+ 		saa7191_input = vino_get_saa7191_input(input);
+@@ -2688,10 +2680,7 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
+ 		}
+ 
+ 		if (vino_drvdata->decoder.owner == VINO_NO_CHANNEL) {
+-			if (i2c_use_client(vino_drvdata->decoder.driver)) {
+-				ret = -ENODEV;
+-				goto out;
+-			}
++			i2c_use_client(vino_drvdata->decoder.driver);
+ 			vino_drvdata->decoder.owner = vcs->channel;
+ 		}
+ 
+@@ -2759,10 +2748,7 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
+ 		}
+ 
+ 		if (vino_drvdata->camera.owner == VINO_NO_CHANNEL) {
+-			if (i2c_use_client(vino_drvdata->camera.driver)) {
+-				ret = -ENODEV;
+-				goto out;
+-			}
++			i2c_use_client(vino_drvdata->camera.driver);
+ 			vino_drvdata->camera.owner = vcs->channel;
+ 		}
+ 
 diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
 index 9b54ff9..1db067c 100644
 --- a/drivers/media/video/vivi.c
@@ -129337,6 +143709,26 @@
  		sock->dev.release = tifm_free_device;
  
  		snprintf(sock->dev.bus_id, BUS_ID_SIZE,
+diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
+index 971e18b..c9dfeb1 100644
+--- a/drivers/mmc/host/omap.c
++++ b/drivers/mmc/host/omap.c
+@@ -25,6 +25,7 @@
+ #include <linux/mmc/card.h>
+ #include <linux/clk.h>
+ #include <linux/scatterlist.h>
++#include <linux/i2c/tps65010.h>
+ 
+ #include <asm/io.h>
+ #include <asm/irq.h>
+@@ -35,7 +36,6 @@
+ #include <asm/arch/dma.h>
+ #include <asm/arch/mux.h>
+ #include <asm/arch/fpga.h>
+-#include <asm/arch/tps65010.h>
+ 
+ #define	OMAP_MMC_REG_CMD	0x00
+ #define	OMAP_MMC_REG_ARGL	0x04
 diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
 index 22ed96c..a0cee86 100644
 --- a/drivers/mtd/mtdchar.c
@@ -130738,6 +145130,84 @@
  
  	return rtc;
  }
+diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c
+index dfef163..e0900ca 100644
+--- a/drivers/rtc/rtc-ds1672.c
++++ b/drivers/rtc/rtc-ds1672.c
+@@ -16,7 +16,7 @@
+ #define DRV_VERSION "0.3"
+ 
+ /* Addresses to scan: none. This chip cannot be detected. */
+-static unsigned short normal_i2c[] = { I2C_CLIENT_END };
++static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
+ 
+ /* Insmod parameters */
+ I2C_CLIENT_INSMOD;
+diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
+index 1c74364..725b0c7 100644
+--- a/drivers/rtc/rtc-isl1208.c
++++ b/drivers/rtc/rtc-isl1208.c
+@@ -61,7 +61,7 @@
+ /* i2c configuration */
+ #define ISL1208_I2C_ADDR 0xde
+ 
+-static unsigned short normal_i2c[] = {
++static const unsigned short normal_i2c[] = {
+ 	ISL1208_I2C_ADDR>>1, I2C_CLIENT_END
+ };
+ I2C_CLIENT_INSMOD; /* defines addr_data */
+diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c
+index a1cd448..7683412 100644
+--- a/drivers/rtc/rtc-max6900.c
++++ b/drivers/rtc/rtc-max6900.c
+@@ -54,7 +54,7 @@
+ 
+ #define MAX6900_I2C_ADDR		0xa0
+ 
+-static unsigned short normal_i2c[] = {
++static const unsigned short normal_i2c[] = {
+ 	MAX6900_I2C_ADDR >> 1,
+ 	I2C_CLIENT_END
+ };
+diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
+index 0242d80..b3317fc 100644
+--- a/drivers/rtc/rtc-pcf8563.c
++++ b/drivers/rtc/rtc-pcf8563.c
+@@ -25,7 +25,7 @@
+  * located at 0x51 will pass the validation routine due to
+  * the way the registers are implemented.
+  */
+-static unsigned short normal_i2c[] = { I2C_CLIENT_END };
++static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
+ 
+ /* Module parameters */
+ I2C_CLIENT_INSMOD;
+diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c
+index 556d0e7..c973ba9 100644
+--- a/drivers/rtc/rtc-pcf8583.c
++++ b/drivers/rtc/rtc-pcf8583.c
+@@ -40,7 +40,7 @@ struct pcf8583 {
+ #define CTRL_ALARM	0x02
+ #define CTRL_TIMER	0x01
+ 
+-static unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END };
++static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END };
+ 
+ /* Module parameters */
+ I2C_CLIENT_INSMOD;
+diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c
+index b3fae35..b90fb18 100644
+--- a/drivers/rtc/rtc-x1205.c
++++ b/drivers/rtc/rtc-x1205.c
+@@ -32,7 +32,7 @@
+  * unknown chips, the user must explicitly set the probe parameter.
+  */
+ 
+-static unsigned short normal_i2c[] = { I2C_CLIENT_END };
++static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
+ 
+ /* Insmod parameters */
+ I2C_CLIENT_INSMOD;
 diff --git a/drivers/s390/block/Makefile b/drivers/s390/block/Makefile
 index be9f22d..0a89e08 100644
 --- a/drivers/s390/block/Makefile
@@ -175526,6 +189996,30 @@
  
  				present++;	/* count it */
  
+diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
+index 6f475b6..ac2a3ef 100644
+--- a/drivers/serial/bfin_5xx.c
++++ b/drivers/serial/bfin_5xx.c
+@@ -442,7 +442,8 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
+ 		set_bfin_dma_config(DIR_READ, DMA_FLOW_STOP,
+ 			INTR_ON_BUF,
+ 			DIMENSION_LINEAR,
+-			DATA_SIZE_8));
++			DATA_SIZE_8,
++			DMA_SYNC_RESTART));
+ 	set_dma_start_addr(uart->tx_dma_channel, (unsigned long)(xmit->buf+xmit->tail));
+ 	set_dma_x_count(uart->tx_dma_channel, uart->tx_count);
+ 	set_dma_x_modify(uart->tx_dma_channel, 1);
+@@ -689,7 +690,8 @@ static int bfin_serial_startup(struct uart_port *port)
+ 	set_dma_config(uart->rx_dma_channel,
+ 		set_bfin_dma_config(DIR_WRITE, DMA_FLOW_AUTO,
+ 				INTR_ON_ROW, DIMENSION_2D,
+-				DATA_SIZE_8));
++				DATA_SIZE_8,
++				DMA_SYNC_RESTART));
+ 	set_dma_x_count(uart->rx_dma_channel, DMA_RX_XCOUNT);
+ 	set_dma_x_modify(uart->rx_dma_channel, 1);
+ 	set_dma_y_count(uart->rx_dma_channel, DMA_RX_YCOUNT);
 diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
 index 9d3105b..9c2df5c 100644
 --- a/drivers/serial/icom.c
@@ -175874,6 +190368,43 @@
  }
  
  static void usb_free_dynids(struct usb_driver *usb_drv)
+diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
+index 5cfa3d1..74e1f4b 100644
+--- a/drivers/usb/host/ohci-omap.c
++++ b/drivers/usb/host/ohci-omap.c
+@@ -47,7 +47,7 @@
+ #endif
+ 
+ #ifdef CONFIG_TPS65010
+-#include <asm/arch/tps65010.h>
++#include <linux/i2c/tps65010.h>
+ #else
+ 
+ #define LOW	0
+diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c
+index ca2a6ab..6c52c66 100644
+--- a/drivers/usb/host/ohci-pnx4008.c
++++ b/drivers/usb/host/ohci-pnx4008.c
+@@ -112,9 +112,9 @@ static int isp1301_detach(struct i2c_client *client);
+ static int isp1301_command(struct i2c_client *client, unsigned int cmd,
+ 			   void *arg);
+ 
+-static unsigned short normal_i2c[] =
++static const unsigned short normal_i2c[] =
+     { ISP1301_I2C_ADDR, ISP1301_I2C_ADDR + 1, I2C_CLIENT_END };
+-static unsigned short dummy_i2c_addrlist[] = { I2C_CLIENT_END };
++static const unsigned short dummy_i2c_addrlist[] = { I2C_CLIENT_END };
+ 
+ static struct i2c_client_address_data addr_data = {
+ 	.normal_i2c = normal_i2c,
+@@ -123,7 +123,6 @@ static struct i2c_client_address_data addr_data = {
+ };
+ 
+ struct i2c_driver isp1301_driver = {
+-	.id = I2C_DRIVERID_I2CDEV,	/* Fake Id */
+ 	.class = I2C_CLASS_HWMON,
+ 	.attach_adapter = isp1301_probe,
+ 	.detach_client = isp1301_detach,
 diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c
 index 88aa59a..f5a4e8d 100644
 --- a/drivers/usb/storage/freecom.c
@@ -176717,6 +191248,30 @@
  
  extern int usb_stor_port_reset(struct us_data *us);
  #endif
+diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c
+index 74d11c3..c8e7427 100644
+--- a/drivers/video/bf54x-lq043fb.c
++++ b/drivers/video/bf54x-lq043fb.c
+@@ -224,7 +224,8 @@ static int config_dma(struct bfin_bf54xfb_info *fbi)
+ 	set_dma_config(CH_EPPI0,
+ 		       set_bfin_dma_config(DIR_READ, DMA_FLOW_AUTO,
+ 					   INTR_DISABLE, DIMENSION_2D,
+-					   DATA_SIZE_32));
++					   DATA_SIZE_32,
++					   DMA_NOSYNC_KEEP_DMA_BUF));
+ 	set_dma_x_count(CH_EPPI0, (LCD_X_RES * LCD_BPP) / DMA_BUS_SIZE);
+ 	set_dma_x_modify(CH_EPPI0, DMA_BUS_SIZE / 8);
+ 	set_dma_y_count(CH_EPPI0, LCD_Y_RES);
+@@ -263,8 +264,7 @@ static int request_ports(struct bfin_bf54xfb_info *fbi)
+ 		}
+ 	}
+ 
+-	gpio_direction_output(disp);
+-	gpio_set_value(disp, 1);
++	gpio_direction_output(disp, 1);
+ 
+ 	return 0;
+ }
 diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
 index b87ed37..2b53d1f 100644
 --- a/drivers/video/console/Kconfig
@@ -176730,6 +191285,47 @@
  	default y
  	help
  	  Saying Y here will allow you to use Linux in text mode through a
+diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c
+index 49cd53e..0cd58f8 100644
+--- a/drivers/video/matrox/matroxfb_maven.c
++++ b/drivers/video/matrox/matroxfb_maven.c
+@@ -1232,7 +1232,7 @@ static int maven_shutdown_client(struct i2c_client* clnt) {
+ 	return 0;
+ }
+ 
+-static unsigned short normal_i2c[] = { MAVEN_I2CID, I2C_CLIENT_END };
++static const unsigned short normal_i2c[] = { MAVEN_I2CID, I2C_CLIENT_END };
+ I2C_CLIENT_INSMOD;
+ 
+ static struct i2c_driver maven_driver;
+diff --git a/drivers/video/omap/lcd_h3.c b/drivers/video/omap/lcd_h3.c
+index c604d93..31e9783 100644
+--- a/drivers/video/omap/lcd_h3.c
++++ b/drivers/video/omap/lcd_h3.c
+@@ -21,9 +21,9 @@
+ 
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
++#include <linux/i2c/tps65010.h>
+ 
+ #include <asm/arch/gpio.h>
+-#include <asm/arch/tps65010.h>
+ #include <asm/arch/omapfb.h>
+ 
+ #define MODULE_NAME	"omapfb-lcd_h3"
+diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c
+index d93eb62..0fd5820 100644
+--- a/drivers/w1/masters/ds2482.c
++++ b/drivers/w1/masters/ds2482.c
+@@ -29,7 +29,7 @@
+  * However, the chip cannot be detected without doing an i2c write,
+  * so use the force module parameter.
+  */
+-static unsigned short normal_i2c[] = {I2C_CLIENT_END};
++static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
+ 
+ /**
+  * Insmod parameters
 diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
 index 52dff40..fbd6112 100644
 --- a/drivers/watchdog/Kconfig
@@ -190608,6 +205204,208 @@
  extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int);
  /*
   * External Functions
+diff --git a/include/asm-arm/arch-ixp4xx/platform.h b/include/asm-arm/arch-ixp4xx/platform.h
+index 2a44d3d..2ce28e3 100644
+--- a/include/asm-arm/arch-ixp4xx/platform.h
++++ b/include/asm-arm/arch-ixp4xx/platform.h
+@@ -76,17 +76,6 @@ extern unsigned long ixp4xx_exp_bus_size;
+ #define IXP4XX_UART_XTAL        	14745600
+ 
+ /*
+- * The IXP4xx chips do not have an I2C unit, so GPIO lines are just
+- * used to 
+- * Used as platform_data to provide GPIO pin information to the ixp42x
+- * I2C driver.
+- */
+-struct ixp4xx_i2c_pins {
+-	unsigned long sda_pin;
+-	unsigned long scl_pin;
+-};
+-
+-/*
+  * This structure provide a means for the board setup code
+  * to give information to th pata_ixp4xx driver. It is
+  * passed as platform_data.
+diff --git a/include/asm-arm/arch-omap/tps65010.h b/include/asm-arm/arch-omap/tps65010.h
+deleted file mode 100644
+index b9aa2b3..0000000
+--- a/include/asm-arm/arch-omap/tps65010.h
++++ /dev/null
+@@ -1,156 +0,0 @@
+-/* linux/include/asm-arm/arch-omap/tps65010.h
+- *
+- * Functions to access TPS65010 power management device.
+- *
+- * Copyright (C) 2004 Dirk Behme <dirk.behme at de.bosch.com>
+- *
+- * This program is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License as published by the
+- * Free Software Foundation; either version 2 of the License, or (at your
+- * option) any later version.
+- *
+- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- *
+- * You should have received a copy of the  GNU General Public License along
+- * with this program; if not, write  to the Free Software Foundation, Inc.,
+- * 675 Mass Ave, Cambridge, MA 02139, USA.
+- */
+-
+-#ifndef __ASM_ARCH_TPS65010_H
+-#define __ASM_ARCH_TPS65010_H
+-
+-/*
+- * ----------------------------------------------------------------------------
+- * Registers, all 8 bits
+- * ----------------------------------------------------------------------------
+- */
+-
+-#define	TPS_CHGSTATUS		0x01
+-#	define	TPS_CHG_USB		(1 << 7)
+-#	define	TPS_CHG_AC		(1 << 6)
+-#	define	TPS_CHG_THERM		(1 << 5)
+-#	define	TPS_CHG_TERM		(1 << 4)
+-#	define	TPS_CHG_TAPER_TMO	(1 << 3)
+-#	define	TPS_CHG_CHG_TMO		(1 << 2)
+-#	define	TPS_CHG_PRECHG_TMO	(1 << 1)
+-#	define	TPS_CHG_TEMP_ERR	(1 << 0)
+-#define	TPS_REGSTATUS		0x02
+-#	define	TPS_REG_ONOFF		(1 << 7)
+-#	define	TPS_REG_COVER		(1 << 6)
+-#	define	TPS_REG_UVLO		(1 << 5)
+-#	define	TPS_REG_NO_CHG		(1 << 4)	/* tps65013 */
+-#	define	TPS_REG_PG_LD02		(1 << 3)
+-#	define	TPS_REG_PG_LD01		(1 << 2)
+-#	define	TPS_REG_PG_MAIN		(1 << 1)
+-#	define	TPS_REG_PG_CORE		(1 << 0)
+-#define	TPS_MASK1		0x03
+-#define	TPS_MASK2		0x04
+-#define	TPS_ACKINT1		0x05
+-#define	TPS_ACKINT2		0x06
+-#define	TPS_CHGCONFIG		0x07
+-#	define	TPS_CHARGE_POR		(1 << 7)	/* 65010/65012 */
+-#	define	TPS65013_AUA		(1 << 7)	/* 65011/65013 */
+-#	define	TPS_CHARGE_RESET	(1 << 6)
+-#	define	TPS_CHARGE_FAST		(1 << 5)
+-#	define	TPS_CHARGE_CURRENT	(3 << 3)
+-#	define	TPS_VBUS_500MA		(1 << 2)
+-#	define	TPS_VBUS_CHARGING	(1 << 1)
+-#	define	TPS_CHARGE_ENABLE	(1 << 0)
+-#define	TPS_LED1_ON		0x08
+-#define	TPS_LED1_PER		0x09
+-#define	TPS_LED2_ON		0x0a
+-#define	TPS_LED2_PER		0x0b
+-#define	TPS_VDCDC1		0x0c
+-#	define	TPS_ENABLE_LP		(1 << 3)
+-#define	TPS_VDCDC2		0x0d
+-#define	TPS_VREGS1		0x0e
+-#	define	TPS_LDO2_ENABLE	(1 << 7)
+-#	define	TPS_LDO2_OFF	(1 << 6)
+-#	define	TPS_VLDO2_3_0V	(3 << 4)
+-#	define	TPS_VLDO2_2_75V	(2 << 4)
+-#	define	TPS_VLDO2_2_5V	(1 << 4)
+-#	define	TPS_VLDO2_1_8V	(0 << 4)
+-#	define	TPS_LDO1_ENABLE	(1 << 3)
+-#	define	TPS_LDO1_OFF	(1 << 2)
+-#	define	TPS_VLDO1_3_0V	(3 << 0)
+-#	define	TPS_VLDO1_2_75V	(2 << 0)
+-#	define	TPS_VLDO1_2_5V	(1 << 0)
+-#	define	TPS_VLDO1_ADJ	(0 << 0)
+-#define	TPS_MASK3		0x0f
+-#define	TPS_DEFGPIO		0x10
+-
+-/*
+- * ----------------------------------------------------------------------------
+- * Macros used by exported functions
+- * ----------------------------------------------------------------------------
+- */
+-
+-#define LED1  1
+-#define LED2  2
+-#define OFF   0
+-#define ON    1
+-#define BLINK 2
+-#define GPIO1 1
+-#define GPIO2 2
+-#define GPIO3 3
+-#define GPIO4 4
+-#define LOW   0
+-#define HIGH  1
+-
+-/*
+- * ----------------------------------------------------------------------------
+- * Exported functions
+- * ----------------------------------------------------------------------------
+- */
+-
+-/* Draw from VBUS:
+- *   0 mA -- DON'T DRAW (might supply power instead)
+- * 100 mA -- usb unit load (slowest charge rate)
+- * 500 mA -- usb high power (fast battery charge)
+- */
+-extern int tps65010_set_vbus_draw(unsigned mA);
+-
+-/* tps65010_set_gpio_out_value parameter:
+- * gpio:  GPIO1, GPIO2, GPIO3 or GPIO4
+- * value: LOW or HIGH
+- */
+-extern int tps65010_set_gpio_out_value(unsigned gpio, unsigned value);
+-
+-/* tps65010_set_led parameter:
+- * led:  LED1 or LED2
+- * mode: ON, OFF or BLINK
+- */
+-extern int tps65010_set_led(unsigned led, unsigned mode);
+-
+-/* tps65010_set_vib parameter:
+- * value: ON or OFF
+- */
+-extern int tps65010_set_vib(unsigned value);
+-
+-/* tps65010_set_low_pwr parameter:
+- * mode: ON or OFF
+- */
+-extern int tps65010_set_low_pwr(unsigned mode);
+-
+-/* tps65010_config_vregs1 parameter:
+- * value to be written to VREGS1 register
+- * Note: The complete register is written, set all bits you need
+- */
+-extern int tps65010_config_vregs1(unsigned value);
+-
+-/* tps65013_set_low_pwr parameter:
+- * mode: ON or OFF
+- */
+-extern int tps65013_set_low_pwr(unsigned mode);
+-
+-#endif /*  __ASM_ARCH_TPS65010_H */
+-
+diff --git a/include/asm-arm/arch-pxa/i2c.h b/include/asm-arm/arch-pxa/i2c.h
+index e404b23..80596b0 100644
+--- a/include/asm-arm/arch-pxa/i2c.h
++++ b/include/asm-arm/arch-pxa/i2c.h
+@@ -65,7 +65,13 @@ struct i2c_pxa_platform_data {
+ 	unsigned int		slave_addr;
+ 	struct i2c_slave_client	*slave;
+ 	unsigned int		class;
++	int			use_pio;
+ };
+ 
+ extern void pxa_set_i2c_info(struct i2c_pxa_platform_data *info);
++
++#ifdef CONFIG_PXA27x
++extern void pxa_set_i2c_power_info(struct i2c_pxa_platform_data *info);
++#endif
++
+ #endif
 diff --git a/include/asm-avr32/arch-at32ap/at32ap7000.h b/include/asm-avr32/arch-at32ap/at32ap7000.h
 deleted file mode 100644
 index 3914d7b..0000000
@@ -190840,6 +205638,1030 @@
  #define TIF_USERSPACE		31      /* true if FS sets userspace */
  
  #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
+diff --git a/include/asm-blackfin/bfin-global.h b/include/asm-blackfin/bfin-global.h
+index 39bdd86..6ae0619 100644
+--- a/include/asm-blackfin/bfin-global.h
++++ b/include/asm-blackfin/bfin-global.h
+@@ -51,7 +51,7 @@ extern unsigned long sclk_to_usecs(unsigned long sclk);
+ extern unsigned long usecs_to_sclk(unsigned long usecs);
+ 
+ extern void dump_bfin_process(struct pt_regs *regs);
+-extern void dump_bfin_mem(void *retaddr);
++extern void dump_bfin_mem(struct pt_regs *regs);
+ extern void dump_bfin_trace_buffer(void);
+ 
+ extern int init_arch_irq(void);
+diff --git a/include/asm-blackfin/cplb-mpu.h b/include/asm-blackfin/cplb-mpu.h
+new file mode 100644
+index 0000000..75c67b9
+--- /dev/null
++++ b/include/asm-blackfin/cplb-mpu.h
+@@ -0,0 +1,61 @@
++/*
++ * File:         include/asm-blackfin/cplbinit.h
++ * Based on:
++ * Author:
++ *
++ * Created:
++ * Description:
++ *
++ * Modified:
++ *               Copyright 2004-2006 Analog Devices Inc.
++ *
++ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, see the file COPYING, or write
++ * to the Free Software Foundation, Inc.,
++ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++ */
++#ifndef __ASM_BFIN_CPLB_MPU_H
++#define __ASM_BFIN_CPLB_MPU_H
++
++struct cplb_entry {
++	unsigned long data, addr;
++};
++
++struct mem_region {
++	unsigned long start, end;
++	unsigned long dcplb_data;
++	unsigned long icplb_data;
++};
++
++extern struct cplb_entry dcplb_tbl[MAX_CPLBS];
++extern struct cplb_entry icplb_tbl[MAX_CPLBS];
++extern int first_switched_icplb;
++extern int first_mask_dcplb;
++extern int first_switched_dcplb;
++
++extern int nr_dcplb_miss, nr_icplb_miss, nr_icplb_supv_miss, nr_dcplb_prot;
++extern int nr_cplb_flush;
++
++extern int page_mask_order;
++extern int page_mask_nelts;
++
++extern unsigned long *current_rwx_mask;
++
++extern void flush_switched_cplbs(void);
++extern void set_mask_dcplbs(unsigned long *);
++
++extern void __noreturn panic_cplb_error(int seqstat, struct pt_regs *);
++
++#endif /* __ASM_BFIN_CPLB_MPU_H */
+diff --git a/include/asm-blackfin/cplb.h b/include/asm-blackfin/cplb.h
+index 06828d7..654375c 100644
+--- a/include/asm-blackfin/cplb.h
++++ b/include/asm-blackfin/cplb.h
+@@ -65,7 +65,11 @@
+ #define SIZE_1M 0x00100000      /* 1M */
+ #define SIZE_4M 0x00400000      /* 4M */
+ 
++#ifdef CONFIG_MPU
++#define MAX_CPLBS 16
++#else
+ #define MAX_CPLBS (16 * 2)
++#endif
+ 
+ #define ASYNC_MEMORY_CPLB_COVERAGE	((ASYNC_BANK0_SIZE + ASYNC_BANK1_SIZE + \
+ 				 ASYNC_BANK2_SIZE + ASYNC_BANK3_SIZE) / SIZE_4M)
+diff --git a/include/asm-blackfin/cplbinit.h b/include/asm-blackfin/cplbinit.h
+index c4d0596..0eb1c1b 100644
+--- a/include/asm-blackfin/cplbinit.h
++++ b/include/asm-blackfin/cplbinit.h
+@@ -33,6 +33,12 @@
+ #include <asm/blackfin.h>
+ #include <asm/cplb.h>
+ 
++#ifdef CONFIG_MPU
++
++#include <asm/cplb-mpu.h>
++
++#else
++
+ #define INITIAL_T 0x1
+ #define SWITCH_T  0x2
+ #define I_CPLB    0x4
+@@ -79,6 +85,8 @@ extern u_long ipdt_swapcount_table[];
+ extern u_long dpdt_swapcount_table[];
+ #endif
+ 
++#endif /* CONFIG_MPU */
++
+ extern unsigned long reserved_mem_dcache_on;
+ extern unsigned long reserved_mem_icache_on;
+ 
+diff --git a/include/asm-blackfin/dma.h b/include/asm-blackfin/dma.h
+index b469505..5abaa2c 100644
+--- a/include/asm-blackfin/dma.h
++++ b/include/asm-blackfin/dma.h
+@@ -76,6 +76,9 @@ enum dma_chan_status {
+ #define INTR_ON_BUF    2
+ #define INTR_ON_ROW    3
+ 
++#define DMA_NOSYNC_KEEP_DMA_BUF	0
++#define DMA_SYNC_RESTART	1
++
+ struct dmasg {
+ 	unsigned long next_desc_addr;
+ 	unsigned long start_addr;
+@@ -157,7 +160,8 @@ void set_dma_y_count(unsigned int channel, unsigned short y_count);
+ void set_dma_y_modify(unsigned int channel, short y_modify);
+ void set_dma_config(unsigned int channel, unsigned short config);
+ unsigned short set_bfin_dma_config(char direction, char flow_mode,
+-				   char intr_mode, char dma_mode, char width);
++				   char intr_mode, char dma_mode, char width,
++				   char syncmode);
+ void set_dma_curr_addr(unsigned int channel, unsigned long addr);
+ 
+ /* get curr status for polling */
+diff --git a/include/asm-blackfin/gpio.h b/include/asm-blackfin/gpio.h
+index 33ce98e..d0426c1 100644
+--- a/include/asm-blackfin/gpio.h
++++ b/include/asm-blackfin/gpio.h
+@@ -7,7 +7,7 @@
+  * Description:
+  *
+  * Modified:
+- *               Copyright 2004-2006 Analog Devices Inc.
++ *               Copyright 2004-2008 Analog Devices Inc.
+  *
+  * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+  *
+@@ -304,39 +304,39 @@
+ **************************************************************/
+ 
+ #ifndef BF548_FAMILY
+-void set_gpio_dir(unsigned short, unsigned short);
+-void set_gpio_inen(unsigned short, unsigned short);
+-void set_gpio_polar(unsigned short, unsigned short);
+-void set_gpio_edge(unsigned short, unsigned short);
+-void set_gpio_both(unsigned short, unsigned short);
+-void set_gpio_data(unsigned short, unsigned short);
+-void set_gpio_maska(unsigned short, unsigned short);
+-void set_gpio_maskb(unsigned short, unsigned short);
+-void set_gpio_toggle(unsigned short);
+-void set_gpiop_dir(unsigned short, unsigned short);
+-void set_gpiop_inen(unsigned short, unsigned short);
+-void set_gpiop_polar(unsigned short, unsigned short);
+-void set_gpiop_edge(unsigned short, unsigned short);
+-void set_gpiop_both(unsigned short, unsigned short);
+-void set_gpiop_data(unsigned short, unsigned short);
+-void set_gpiop_maska(unsigned short, unsigned short);
+-void set_gpiop_maskb(unsigned short, unsigned short);
+-unsigned short get_gpio_dir(unsigned short);
+-unsigned short get_gpio_inen(unsigned short);
+-unsigned short get_gpio_polar(unsigned short);
+-unsigned short get_gpio_edge(unsigned short);
+-unsigned short get_gpio_both(unsigned short);
+-unsigned short get_gpio_maska(unsigned short);
+-unsigned short get_gpio_maskb(unsigned short);
+-unsigned short get_gpio_data(unsigned short);
+-unsigned short get_gpiop_dir(unsigned short);
+-unsigned short get_gpiop_inen(unsigned short);
+-unsigned short get_gpiop_polar(unsigned short);
+-unsigned short get_gpiop_edge(unsigned short);
+-unsigned short get_gpiop_both(unsigned short);
+-unsigned short get_gpiop_maska(unsigned short);
+-unsigned short get_gpiop_maskb(unsigned short);
+-unsigned short get_gpiop_data(unsigned short);
++void set_gpio_dir(unsigned, unsigned short);
++void set_gpio_inen(unsigned, unsigned short);
++void set_gpio_polar(unsigned, unsigned short);
++void set_gpio_edge(unsigned, unsigned short);
++void set_gpio_both(unsigned, unsigned short);
++void set_gpio_data(unsigned, unsigned short);
++void set_gpio_maska(unsigned, unsigned short);
++void set_gpio_maskb(unsigned, unsigned short);
++void set_gpio_toggle(unsigned);
++void set_gpiop_dir(unsigned, unsigned short);
++void set_gpiop_inen(unsigned, unsigned short);
++void set_gpiop_polar(unsigned, unsigned short);
++void set_gpiop_edge(unsigned, unsigned short);
++void set_gpiop_both(unsigned, unsigned short);
++void set_gpiop_data(unsigned, unsigned short);
++void set_gpiop_maska(unsigned, unsigned short);
++void set_gpiop_maskb(unsigned, unsigned short);
++unsigned short get_gpio_dir(unsigned);
++unsigned short get_gpio_inen(unsigned);
++unsigned short get_gpio_polar(unsigned);
++unsigned short get_gpio_edge(unsigned);
++unsigned short get_gpio_both(unsigned);
++unsigned short get_gpio_maska(unsigned);
++unsigned short get_gpio_maskb(unsigned);
++unsigned short get_gpio_data(unsigned);
++unsigned short get_gpiop_dir(unsigned);
++unsigned short get_gpiop_inen(unsigned);
++unsigned short get_gpiop_polar(unsigned);
++unsigned short get_gpiop_edge(unsigned);
++unsigned short get_gpiop_both(unsigned);
++unsigned short get_gpiop_maska(unsigned);
++unsigned short get_gpiop_maskb(unsigned);
++unsigned short get_gpiop_data(unsigned);
+ 
+ struct gpio_port_t {
+ 	unsigned short data;
+@@ -382,8 +382,8 @@ struct gpio_port_t {
+ #define PM_WAKE_LOW	0x8
+ #define PM_WAKE_BOTH_EDGES	(PM_WAKE_RISING | PM_WAKE_FALLING)
+ 
+-int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type);
+-void gpio_pm_wakeup_free(unsigned short gpio);
++int gpio_pm_wakeup_request(unsigned gpio, unsigned char type);
++void gpio_pm_wakeup_free(unsigned gpio);
+ unsigned int gpio_pm_setup(void);
+ void gpio_pm_restore(void);
+ 
+@@ -426,19 +426,19 @@ struct gpio_port_s {
+ * MODIFICATION HISTORY :
+ **************************************************************/
+ 
+-int gpio_request(unsigned short, const char *);
+-void gpio_free(unsigned short);
++int gpio_request(unsigned, const char *);
++void gpio_free(unsigned);
+ 
+-void gpio_set_value(unsigned short gpio, unsigned short arg);
+-unsigned short gpio_get_value(unsigned short gpio);
++void gpio_set_value(unsigned gpio, int arg);
++int gpio_get_value(unsigned gpio);
+ 
+ #ifndef BF548_FAMILY
+ #define gpio_get_value(gpio) 		get_gpio_data(gpio)
+ #define gpio_set_value(gpio, value)	set_gpio_data(gpio, value)
+ #endif
+ 
+-void gpio_direction_input(unsigned short gpio);
+-void gpio_direction_output(unsigned short gpio);
++int gpio_direction_input(unsigned gpio);
++int gpio_direction_output(unsigned gpio, int value);
+ 
+ #include <asm-generic/gpio.h>		/* cansleep wrappers */
+ #include <asm/irq.h>
+diff --git a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h
+index 0b867e6..15dbc21 100644
+--- a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h
++++ b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h
+@@ -146,7 +146,7 @@ static void bfin_serial_hw_init(struct bfin_serial_port *uart)
+ 
+ 	if (uart->rts_pin >= 0) {
+ 		gpio_request(uart->rts_pin, DRIVER_NAME);
+-		gpio_direction_output(uart->rts_pin);
++		gpio_direction_output(uart->rts_pin, 0);
+ 	}
+ #endif
+ }
+diff --git a/include/asm-blackfin/mach-bf527/portmux.h b/include/asm-blackfin/mach-bf527/portmux.h
+index dcf001a..ae4d205 100644
+--- a/include/asm-blackfin/mach-bf527/portmux.h
++++ b/include/asm-blackfin/mach-bf527/portmux.h
+@@ -1,6 +1,8 @@
+ #ifndef _MACH_PORTMUX_H_
+ #define _MACH_PORTMUX_H_
+ 
++#define MAX_RESOURCES 	MAX_BLACKFIN_GPIOS
++
+ #define P_PPI0_D0	(P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(0))
+ #define P_PPI0_D1	(P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(0))
+ #define P_PPI0_D2	(P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(0))
+diff --git a/include/asm-blackfin/mach-bf533/anomaly.h b/include/asm-blackfin/mach-bf533/anomaly.h
+index f36ff5a..98209d4 100644
+--- a/include/asm-blackfin/mach-bf533/anomaly.h
++++ b/include/asm-blackfin/mach-bf533/anomaly.h
+@@ -7,9 +7,7 @@
+  */
+ 
+ /* This file shoule be up to date with:
+- *  - Revision X,  March 23, 2007; ADSP-BF533 Blackfin Processor Anomaly List
+- *  - Revision AB, March 23, 2007; ADSP-BF532 Blackfin Processor Anomaly List
+- *  - Revision W,  March 23, 2007; ADSP-BF531 Blackfin Processor Anomaly List
++ *  - Revision B, 12/10/2007; ADSP-BF531/BF532/BF533 Blackfin Processor Anomaly List
+  */
+ 
+ #ifndef _MACH_ANOMALY_H_
+@@ -17,7 +15,7 @@
+ 
+ /* We do not support 0.1 or 0.2 silicon - sorry */
+ #if __SILICON_REVISION__ < 3
+-# error Kernel will not work on BF533 silicon version 0.0, 0.1, or 0.2
++# error will not work on BF533 silicon version 0.0, 0.1, or 0.2
+ #endif
+ 
+ #if defined(__ADSPBF531__)
+@@ -251,6 +249,12 @@
+ #define ANOMALY_05000192 (__SILICON_REVISION__ < 3)
+ /* Internal Voltage Regulator may not start up */
+ #define ANOMALY_05000206 (__SILICON_REVISION__ < 3)
++/* Serial Port (SPORT) Multichannel Transmit Failure when Channel 0 Is Disabled */
++#define ANOMALY_05000357 (1)
++/* PPI Underflow Error Goes Undetected in ITU-R 656 Mode */
++#define ANOMALY_05000366 (1)
++/* Possible RETS Register Corruption when Subroutine Is under 5 Cycles in Duration */
++#define ANOMALY_05000371 (1)
+ 
+ /* Anomalies that don't exist on this proc */
+ #define ANOMALY_05000266 (0)
+diff --git a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h
+index 69b9f8e..7871d43 100644
+--- a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h
++++ b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h
+@@ -111,7 +111,7 @@ static void bfin_serial_hw_init(struct bfin_serial_port *uart)
+ 	}
+ 	if (uart->rts_pin >= 0) {
+ 		gpio_request(uart->rts_pin, DRIVER_NAME);
+-		gpio_direction_input(uart->rts_pin);
++		gpio_direction_input(uart->rts_pin, 0);
+ 	}
+ #endif
+ }
+diff --git a/include/asm-blackfin/mach-bf533/portmux.h b/include/asm-blackfin/mach-bf533/portmux.h
+index 137f488..685a265 100644
+--- a/include/asm-blackfin/mach-bf533/portmux.h
++++ b/include/asm-blackfin/mach-bf533/portmux.h
+@@ -1,6 +1,8 @@
+ #ifndef _MACH_PORTMUX_H_
+ #define _MACH_PORTMUX_H_
+ 
++#define MAX_RESOURCES 	MAX_BLACKFIN_GPIOS
++
+ #define P_PPI0_CLK	(P_DONTCARE)
+ #define P_PPI0_FS1	(P_DONTCARE)
+ #define P_PPI0_FS2	(P_DONTCARE)
+diff --git a/include/asm-blackfin/mach-bf537/anomaly.h b/include/asm-blackfin/mach-bf537/anomaly.h
+index 2b66ecf..746a794 100644
+--- a/include/asm-blackfin/mach-bf537/anomaly.h
++++ b/include/asm-blackfin/mach-bf537/anomaly.h
+@@ -7,9 +7,7 @@
+  */
+ 
+ /* This file shoule be up to date with:
+- *  - Revision M, March 13, 2007; ADSP-BF537 Blackfin Processor Anomaly List
+- *  - Revision L, March 13, 2007; ADSP-BF536 Blackfin Processor Anomaly List
+- *  - Revision M, March 13, 2007; ADSP-BF534 Blackfin Processor Anomaly List
++ *  - Revision A, 09/04/2007; ADSP-BF534/ADSP-BF536/ADSP-BF537 Blackfin Processor Anomaly List
+  */
+ 
+ #ifndef _MACH_ANOMALY_H_
+@@ -17,7 +15,7 @@
+ 
+ /* We do not support 0.1 silicon - sorry */
+ #if __SILICON_REVISION__ < 2
+-# error Kernel will not work on BF537 silicon version 0.0 or 0.1
++# error will not work on BF537 silicon version 0.0 or 0.1
+ #endif
+ 
+ #if defined(__ADSPBF534__)
+@@ -44,6 +42,8 @@
+ #define ANOMALY_05000122 (1)
+ /* Killed 32-bit MMR write leads to next system MMR access thinking it should be 32-bit */
+ #define ANOMALY_05000157 (__SILICON_REVISION__ < 2)
++/* Turning SPORTs on while External Frame Sync Is Active May Corrupt Data */
++#define ANOMALY_05000167 (1)
+ /* PPI_DELAY not functional in PPI modes with 0 frame syncs */
+ #define ANOMALY_05000180 (1)
+ /* Instruction Cache Is Not Functional */
+@@ -130,6 +130,12 @@
+ #define ANOMALY_05000321 (__SILICON_REVISION__ < 3)
+ /* EMAC RMII mode at 10-Base-T speed: RX frames not received properly */
+ #define ANOMALY_05000322 (1)
++/* Ethernet MAC MDIO Reads Do Not Meet IEEE Specification */
++#define ANOMALY_05000341 (__SILICON_REVISION__ >= 3)
++/* Serial Port (SPORT) Multichannel Transmit Failure when Channel 0 Is Disabled */
++#define ANOMALY_05000357 (1)
++/* DMAs that Go Urgent during Tight Core Writes to External Memory Are Blocked */
++#define ANOMALY_05000359 (1)
+ 
+ /* Anomalies that don't exist on this proc */
+ #define ANOMALY_05000125 (0)
+diff --git a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h
+index 6fb328f..86e45c3 100644
+--- a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h
++++ b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h
+@@ -146,7 +146,7 @@ static void bfin_serial_hw_init(struct bfin_serial_port *uart)
+ 
+ 	if (uart->rts_pin >= 0) {
+ 		gpio_request(uart->rts_pin, DRIVER_NAME);
+-		gpio_direction_output(uart->rts_pin);
++		gpio_direction_output(uart->rts_pin, 0);
+ 	}
+ #endif
+ }
+diff --git a/include/asm-blackfin/mach-bf537/portmux.h b/include/asm-blackfin/mach-bf537/portmux.h
+index 5a3f7d3..78fee6e 100644
+--- a/include/asm-blackfin/mach-bf537/portmux.h
++++ b/include/asm-blackfin/mach-bf537/portmux.h
+@@ -1,6 +1,8 @@
+ #ifndef _MACH_PORTMUX_H_
+ #define _MACH_PORTMUX_H_
+ 
++#define MAX_RESOURCES 	(MAX_BLACKFIN_GPIOS + GPIO_BANKSIZE)	/* We additionally handle PORTJ */
++
+ #define P_UART0_TX	(P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(0))
+ #define P_UART0_RX	(P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(0))
+ #define P_UART1_TX	(P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(0))
+diff --git a/include/asm-blackfin/mach-bf548/anomaly.h b/include/asm-blackfin/mach-bf548/anomaly.h
+index c5b6375..850dc12 100644
+--- a/include/asm-blackfin/mach-bf548/anomaly.h
++++ b/include/asm-blackfin/mach-bf548/anomaly.h
+@@ -7,7 +7,7 @@
+  */
+ 
+ /* This file shoule be up to date with:
+- *  - Revision C, July 16, 2007; ADSP-BF549 Silicon Anomaly List
++ *  - Revision E, 11/28/2007; ADSP-BF542/BF544/BF547/BF548/BF549 Blackfin Processor Anomaly List
+  */
+ 
+ #ifndef _MACH_ANOMALY_H_
+@@ -26,47 +26,59 @@
+ /* Certain Data Cache Writethrough Modes Fail for Vddint <= 0.9V */
+ #define ANOMALY_05000272 (1)
+ /* False Hardware Error Exception when ISR context is not restored */
+-#define ANOMALY_05000281 (1)
++#define ANOMALY_05000281 (__SILICON_REVISION__ < 1)
+ /* SSYNCs After Writes To CAN/DMA MMR Registers Are Not Always Handled Correctly */
+-#define ANOMALY_05000304 (1)
++#define ANOMALY_05000304 (__SILICON_REVISION__ < 1)
+ /* False Hardware Errors Caused by Fetches at the Boundary of Reserved Memory */
+ #define ANOMALY_05000310 (1)
+ /* Errors When SSYNC, CSYNC, or Loads to LT, LB and LC Registers Are Interrupted */
+-#define ANOMALY_05000312 (1)
++#define ANOMALY_05000312 (__SILICON_REVISION__ < 1)
+ /* TWI Slave Boot Mode Is Not Functional */
+-#define ANOMALY_05000324 (1)
++#define ANOMALY_05000324 (__SILICON_REVISION__ < 1)
+ /* External FIFO Boot Mode Is Not Functional */
+-#define ANOMALY_05000325 (1)
++#define ANOMALY_05000325 (__SILICON_REVISION__ < 1)
+ /* Data Lost When Core and DMA Accesses Are Made to the USB FIFO Simultaneously */
+-#define ANOMALY_05000327 (1)
++#define ANOMALY_05000327 (__SILICON_REVISION__ < 1)
+ /* Incorrect Access of OTP_STATUS During otp_write() Function */
+-#define ANOMALY_05000328 (1)
++#define ANOMALY_05000328 (__SILICON_REVISION__ < 1)
+ /* Synchronous Burst Flash Boot Mode Is Not Functional */
+-#define ANOMALY_05000329 (1)
++#define ANOMALY_05000329 (__SILICON_REVISION__ < 1)
+ /* Host DMA Boot Mode Is Not Functional */
+-#define ANOMALY_05000330 (1)
++#define ANOMALY_05000330 (__SILICON_REVISION__ < 1)
+ /* Inadequate Timing Margins on DDR DQS to DQ and DQM Skew */
+-#define ANOMALY_05000334 (1)
++#define ANOMALY_05000334 (__SILICON_REVISION__ < 1)
+ /* Inadequate Rotary Debounce Logic Duration */
+-#define ANOMALY_05000335 (1)
++#define ANOMALY_05000335 (__SILICON_REVISION__ < 1)
+ /* Phantom Interrupt Occurs After First Configuration of Host DMA Port */
+-#define ANOMALY_05000336 (1)
++#define ANOMALY_05000336 (__SILICON_REVISION__ < 1)
+ /* Disallowed Configuration Prevents Subsequent Allowed Configuration on Host DMA Port */
+-#define ANOMALY_05000337 (1)
++#define ANOMALY_05000337 (__SILICON_REVISION__ < 1)
+ /* Slave-Mode SPI0 MISO Failure With CPHA = 0 */
+-#define ANOMALY_05000338 (1)
++#define ANOMALY_05000338 (__SILICON_REVISION__ < 1)
+ /* If Memory Reads Are Enabled on SDH or HOSTDP, Other DMAC1 Peripherals Cannot Read */
+-#define ANOMALY_05000340 (1)
++#define ANOMALY_05000340 (__SILICON_REVISION__ < 1)
+ /* Boot Host Wait (HWAIT) and Boot Host Wait Alternate (HWAITA) Signals Are Swapped */
+-#define ANOMALY_05000344 (1)
++#define ANOMALY_05000344 (__SILICON_REVISION__ < 1)
+ /* USB Calibration Value Is Not Intialized */
+-#define ANOMALY_05000346 (1)
++#define ANOMALY_05000346 (__SILICON_REVISION__ < 1)
+ /* Boot ROM Kernel Incorrectly Alters Reset Value of USB Register */
+-#define ANOMALY_05000347 (1)
++#define ANOMALY_05000347 (__SILICON_REVISION__ < 1)
+ /* Data Lost when Core Reads SDH Data FIFO */
+-#define ANOMALY_05000349 (1)
++#define ANOMALY_05000349 (__SILICON_REVISION__ < 1)
+ /* PLL Status Register Is Inaccurate */
+-#define ANOMALY_05000351 (1)
++#define ANOMALY_05000351 (__SILICON_REVISION__ < 1)
++/* Serial Port (SPORT) Multichannel Transmit Failure when Channel 0 Is Disabled */
++#define ANOMALY_05000357 (1)
++/* External Memory Read Access Hangs Core With PLL Bypass */
++#define ANOMALY_05000360 (1)
++/* DMAs that Go Urgent during Tight Core Writes to External Memory Are Blocked */
++#define ANOMALY_05000365 (1)
++/* Addressing Conflict between Boot ROM and Asynchronous Memory */
++#define ANOMALY_05000369 (1)
++/* Mobile DDR Operation Not Functional */
++#define ANOMALY_05000377 (1)
++/* Security/Authentication Speedpath Causes Authentication To Fail To Initiate */
++#define ANOMALY_05000378 (1)
+ 
+ /* Anomalies that don't exist on this proc */
+ #define ANOMALY_05000125 (0)
+diff --git a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h
+index f21a162..3770aa3 100644
+--- a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h
++++ b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h
+@@ -186,7 +186,7 @@ static void bfin_serial_hw_init(struct bfin_serial_port *uart)
+ 
+ 	if (uart->rts_pin >= 0) {
+ 		gpio_request(uart->rts_pin, DRIVER_NAME);
+-		gpio_direction_output(uart->rts_pin);
++		gpio_direction_output(uart->rts_pin, 0);
+ 	}
+ #endif
+ }
+diff --git a/include/asm-blackfin/mach-bf548/cdefBF54x_base.h b/include/asm-blackfin/mach-bf548/cdefBF54x_base.h
+index aefab3f..19ddcd8 100644
+--- a/include/asm-blackfin/mach-bf548/cdefBF54x_base.h
++++ b/include/asm-blackfin/mach-bf548/cdefBF54x_base.h
+@@ -244,39 +244,6 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
+ #define bfin_read_TWI0_RCV_DATA16()		bfin_read16(TWI0_RCV_DATA16)
+ #define bfin_write_TWI0_RCV_DATA16(val)		bfin_write16(TWI0_RCV_DATA16, val)
+ 
+-#define bfin_read_TWI_CLKDIV()			bfin_read16(TWI0_CLKDIV)
+-#define bfin_write_TWI_CLKDIV(val)		bfin_write16(TWI0_CLKDIV, val)
+-#define bfin_read_TWI_CONTROL()			bfin_read16(TWI0_CONTROL)
+-#define bfin_write_TWI_CONTROL(val)		bfin_write16(TWI0_CONTROL, val)
+-#define bfin_read_TWI_SLAVE_CTRL()		bfin_read16(TWI0_SLAVE_CTRL)
+-#define bfin_write_TWI_SLAVE_CTRL(val)		bfin_write16(TWI0_SLAVE_CTRL, val)
+-#define bfin_read_TWI_SLAVE_STAT()		bfin_read16(TWI0_SLAVE_STAT)
+-#define bfin_write_TWI_SLAVE_STAT(val)		bfin_write16(TWI0_SLAVE_STAT, val)
+-#define bfin_read_TWI_SLAVE_ADDR()		bfin_read16(TWI0_SLAVE_ADDR)
+-#define bfin_write_TWI_SLAVE_ADDR(val)		bfin_write16(TWI0_SLAVE_ADDR, val)
+-#define bfin_read_TWI_MASTER_CTL()		bfin_read16(TWI0_MASTER_CTRL)
+-#define bfin_write_TWI_MASTER_CTL(val)		bfin_write16(TWI0_MASTER_CTRL, val)
+-#define bfin_read_TWI_MASTER_STAT()		bfin_read16(TWI0_MASTER_STAT)
+-#define bfin_write_TWI_MASTER_STAT(val)		bfin_write16(TWI0_MASTER_STAT, val)
+-#define bfin_read_TWI_MASTER_ADDR()		bfin_read16(TWI0_MASTER_ADDR)
+-#define bfin_write_TWI_MASTER_ADDR(val)		bfin_write16(TWI0_MASTER_ADDR, val)
+-#define bfin_read_TWI_INT_STAT()		bfin_read16(TWI0_INT_STAT)
+-#define bfin_write_TWI_INT_STAT(val)		bfin_write16(TWI0_INT_STAT, val)
+-#define bfin_read_TWI_INT_MASK()		bfin_read16(TWI0_INT_MASK)
+-#define bfin_write_TWI_INT_MASK(val)		bfin_write16(TWI0_INT_MASK, val)
+-#define bfin_read_TWI_FIFO_CTL()		bfin_read16(TWI0_FIFO_CTRL)
+-#define bfin_write_TWI_FIFO_CTL(val)		bfin_write16(TWI0_FIFO_CTRL, val)
+-#define bfin_read_TWI_FIFO_STAT()		bfin_read16(TWI0_FIFO_STAT)
+-#define bfin_write_TWI_FIFO_STAT(val)		bfin_write16(TWI0_FIFO_STAT, val)
+-#define bfin_read_TWI_XMT_DATA8()		bfin_read16(TWI0_XMT_DATA8)
+-#define bfin_write_TWI_XMT_DATA8(val)		bfin_write16(TWI0_XMT_DATA8, val)
+-#define bfin_read_TWI_XMT_DATA16()		bfin_read16(TWI0_XMT_DATA16)
+-#define bfin_write_TWI_XMT_DATA16(val)		bfin_write16(TWI0_XMT_DATA16, val)
+-#define bfin_read_TWI_RCV_DATA8()		bfin_read16(TWI0_RCV_DATA8)
+-#define bfin_write_TWI_RCV_DATA8(val)		bfin_write16(TWI0_RCV_DATA8, val)
+-#define bfin_read_TWI_RCV_DATA16()		bfin_read16(TWI0_RCV_DATA16)
+-#define bfin_write_TWI_RCV_DATA16(val)		bfin_write16(TWI0_RCV_DATA16, val)
+-
+ /* SPORT0 is not defined in the shared file because it is not available on the ADSP-BF542 and ADSP-BF544 bfin_read_()rocessors */
+ 
+ /* SPORT1 Registers */
+diff --git a/include/asm-blackfin/mach-bf548/defBF542.h b/include/asm-blackfin/mach-bf548/defBF542.h
+index 32d0713..a7c809f 100644
+--- a/include/asm-blackfin/mach-bf548/defBF542.h
++++ b/include/asm-blackfin/mach-bf548/defBF542.h
+@@ -432,8 +432,8 @@
+ 
+ #define              CMD_CRC_FAIL  0x1        /* CMD CRC Fail */
+ #define              DAT_CRC_FAIL  0x2        /* Data CRC Fail */
+-#define               CMD_TIMEOUT  0x4        /* CMD Time Out */
+-#define               DAT_TIMEOUT  0x8        /* Data Time Out */
++#define               CMD_TIME_OUT  0x4        /* CMD Time Out */
++#define               DAT_TIME_OUT  0x8        /* Data Time Out */
+ #define               TX_UNDERRUN  0x10       /* Transmit Underrun */
+ #define                RX_OVERRUN  0x20       /* Receive Overrun */
+ #define              CMD_RESP_END  0x40       /* CMD Response End */
+diff --git a/include/asm-blackfin/mach-bf548/defBF548.h b/include/asm-blackfin/mach-bf548/defBF548.h
+index ecbca95..e46f568 100644
+--- a/include/asm-blackfin/mach-bf548/defBF548.h
++++ b/include/asm-blackfin/mach-bf548/defBF548.h
+@@ -1095,8 +1095,8 @@
+ 
+ #define              CMD_CRC_FAIL  0x1        /* CMD CRC Fail */
+ #define              DAT_CRC_FAIL  0x2        /* Data CRC Fail */
+-#define               CMD_TIMEOUT  0x4        /* CMD Time Out */
+-#define               DAT_TIMEOUT  0x8        /* Data Time Out */
++#define               CMD_TIME_OUT  0x4        /* CMD Time Out */
++#define               DAT_TIME_OUT  0x8        /* Data Time Out */
+ #define               TX_UNDERRUN  0x10       /* Transmit Underrun */
+ #define                RX_OVERRUN  0x20       /* Receive Overrun */
+ #define              CMD_RESP_END  0x40       /* CMD Response End */
+diff --git a/include/asm-blackfin/mach-bf548/defBF54x_base.h b/include/asm-blackfin/mach-bf548/defBF54x_base.h
+index 319a485..08f90c2 100644
+--- a/include/asm-blackfin/mach-bf548/defBF54x_base.h
++++ b/include/asm-blackfin/mach-bf548/defBF54x_base.h
+@@ -1772,17 +1772,36 @@
+ #define                       TRP  0x3c0000   /* Pre charge-to-active command period */
+ #define                      TRAS  0x3c00000  /* Min Active-to-pre charge time */
+ #define                       TRC  0x3c000000 /* Active-to-active time */
++#define DDR_TRAS(x)		((x<<22)&TRAS)	/* DDR tRAS = (1~15) cycles */
++#define DDR_TRP(x)		((x<<18)&TRP)	/* DDR tRP = (1~15) cycles */
++#define DDR_TRC(x)		((x<<26)&TRC)	/* DDR tRC = (1~15) cycles */
++#define DDR_TRFC(x)		((x<<14)&TRFC)	/* DDR tRFC = (1~15) cycles */
++#define DDR_TREFI(x)		(x&TREFI)	/* DDR tRFC = (1~15) cycles */
+ 
+ /* Bit masks for EBIU_DDRCTL1 */
+ 
+ #define                      TRCD  0xf        /* Active-to-Read/write delay */
+-#define                       MRD  0xf0       /* Mode register set to active */
++#define                      TMRD  0xf0       /* Mode register set to active */
+ #define                       TWR  0x300      /* Write Recovery time */
+ #define               DDRDATWIDTH  0x3000     /* DDR data width */
+ #define                  EXTBANKS  0xc000     /* External banks */
+ #define               DDRDEVWIDTH  0x30000    /* DDR device width */
+ #define                DDRDEVSIZE  0xc0000    /* DDR device size */
+-#define                     TWWTR  0xf0000000 /* Write-to-read delay */
++#define                      TWTR  0xf0000000 /* Write-to-read delay */
++#define DDR_TWTR(x)		((x<<28)&TWTR)	/* DDR tWTR = (1~15) cycles */
++#define DDR_TMRD(x)		((x<<4)&TMRD)	/* DDR tMRD = (1~15) cycles */
++#define DDR_TWR(x)		((x<<8)&TWR)	/* DDR tWR = (1~15) cycles */
++#define DDR_TRCD(x)		(x&TRCD)	/* DDR tRCD = (1~15) cycles */
++#define DDR_DATWIDTH		0x2000		/* DDR data width */
++#define EXTBANK_1		0		/* 1 external bank */
++#define EXTBANK_2		0x4000		/* 2 external banks */
++#define DEVSZ_64		0x40000		/* DDR External Bank Size = 64MB */
++#define DEVSZ_128		0x80000		/* DDR External Bank Size = 128MB */
++#define DEVSZ_256		0xc0000		/* DDR External Bank Size = 256MB */
++#define DEVSZ_512		0		/* DDR External Bank Size = 512MB */
++#define DEVWD_4			0		/* DDR Device Width = 4 Bits    */
++#define DEVWD_8			0x10000		/* DDR Device Width = 8 Bits    */
++#define DEVWD_16		0x20000		/* DDR Device Width = 16 Bits    */
+ 
+ /* Bit masks for EBIU_DDRCTL2 */
+ 
+@@ -1790,6 +1809,10 @@
+ #define                CASLATENCY  0x70       /* CAS latency */
+ #define                  DLLRESET  0x100      /* DLL Reset */
+ #define                      REGE  0x1000     /* Register mode enable */
++#define CL_1_5			0x50		/* DDR CAS Latency = 1.5 cycles */
++#define CL_2			0x20		/* DDR CAS Latency = 2 cycles */
++#define CL_2_5			0x60		/* DDR CAS Latency = 2.5 cycles */
++#define CL_3			0x30		/* DDR CAS Latency = 3 cycles */
+ 
+ /* Bit masks for EBIU_DDRCTL3 */
+ 
+@@ -2257,6 +2280,10 @@
+ 
+ #define                      CSEL  0x30       /* Core Select */
+ #define                      SSEL  0xf        /* System Select */
++#define			CSEL_DIV1	0x0000	/* CCLK = VCO / 1 */
++#define			CSEL_DIV2	0x0010	/* CCLK = VCO / 2 */
++#define			CSEL_DIV4	0x0020	/* CCLK = VCO / 4 */
++#define			CSEL_DIV8	0x0030	/* CCLK = VCO / 8 */
+ 
+ /* Bit masks for PLL_CTL */
+ 
+diff --git a/include/asm-blackfin/mach-bf548/irq.h b/include/asm-blackfin/mach-bf548/irq.h
+index 9fb7bc5..c34507a 100644
+--- a/include/asm-blackfin/mach-bf548/irq.h
++++ b/include/asm-blackfin/mach-bf548/irq.h
+@@ -88,7 +88,7 @@ Events         (highest priority)  EMU         0
+ #define IRQ_PINT1		BFIN_IRQ(20)	/* PINT1 Interrupt */
+ #define IRQ_MDMAS0		BFIN_IRQ(21)	/* MDMA Stream 0 Interrupt */
+ #define IRQ_MDMAS1		BFIN_IRQ(22)	/* MDMA Stream 1 Interrupt */
+-#define IRQ_WATCHDOG		BFIN_IRQ(23)	/* Watchdog Interrupt */
++#define IRQ_WATCH		BFIN_IRQ(23)	/* Watchdog Interrupt */
+ #define IRQ_DMAC1_ERROR		BFIN_IRQ(24)	/* DMAC1 Status (Error) Interrupt */
+ #define IRQ_SPORT2_ERROR	BFIN_IRQ(25)	/* SPORT2 Error Interrupt */
+ #define IRQ_SPORT3_ERROR	BFIN_IRQ(26)	/* SPORT3 Error Interrupt */
+@@ -406,7 +406,7 @@ Events         (highest priority)  EMU         0
+ #define IRQ_PINT1_POS		16
+ #define IRQ_MDMAS0_POS		20
+ #define IRQ_MDMAS1_POS		24
+-#define IRQ_WATCHDOG_POS	28
++#define IRQ_WATCH_POS		28
+ 
+ /* IAR3 BIT FIELDS */
+ #define IRQ_DMAC1_ERR_POS	0
+diff --git a/include/asm-blackfin/mach-bf548/mem_init.h b/include/asm-blackfin/mach-bf548/mem_init.h
+index 0cb279e..befc290 100644
+--- a/include/asm-blackfin/mach-bf548/mem_init.h
++++ b/include/asm-blackfin/mach-bf548/mem_init.h
+@@ -28,8 +28,68 @@
+  * If not, write to the Free Software Foundation,
+  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+  */
++#define MIN_DDR_SCLK(x)	(x*(CONFIG_SCLK_HZ/1000/1000)/1000 + 1)
++
++#if (CONFIG_MEM_MT46V32M16_6T)
++#define DDR_SIZE	DEVSZ_512
++#define DDR_WIDTH	DEVWD_16
++
++#define DDR_tRC		DDR_TRC(MIN_DDR_SCLK(60))
++#define DDR_tRAS	DDR_TRAS(MIN_DDR_SCLK(42))
++#define DDR_tRP		DDR_TRP(MIN_DDR_SCLK(15))
++#define DDR_tRFC	DDR_TRFC(MIN_DDR_SCLK(72))
++#define DDR_tREFI	DDR_TREFI(MIN_DDR_SCLK(7800))
++
++#define DDR_tRCD	DDR_TRCD(MIN_DDR_SCLK(15))
++#define DDR_tWTR	DDR_TWTR(1)
++#define DDR_tMRD	DDR_TMRD(MIN_DDR_SCLK(12))
++#define DDR_tWR		DDR_TWR(MIN_DDR_SCLK(15))
++#endif
++
++#if (CONFIG_MEM_MT46V32M16_5B)
++#define DDR_SIZE	DEVSZ_512
++#define DDR_WIDTH	DEVWD_16
++
++#define DDR_tRC		DDR_TRC(MIN_DDR_SCLK(55))
++#define DDR_tRAS	DDR_TRAS(MIN_DDR_SCLK(40))
++#define DDR_tRP		DDR_TRP(MIN_DDR_SCLK(15))
++#define DDR_tRFC	DDR_TRFC(MIN_DDR_SCLK(70))
++#define DDR_tREFI	DDR_TREFI(MIN_DDR_SCLK(7800))
++
++#define DDR_tRCD	DDR_TRCD(MIN_DDR_SCLK(15))
++#define DDR_tWTR	DDR_TWTR(2)
++#define DDR_tMRD	DDR_TMRD(MIN_DDR_SCLK(10))
++#define DDR_tWR		DDR_TWR(MIN_DDR_SCLK(15))
++#endif
++
++#if (CONFIG_MEM_GENERIC_BOARD)
++#define DDR_SIZE	DEVSZ_512
++#define DDR_WIDTH	DEVWD_16
++
++#define DDR_tRCD	DDR_TRCD(3)
++#define DDR_tWTR	DDR_TWTR(2)
++#define DDR_tWR		DDR_TWR(2)
++#define DDR_tMRD	DDR_TMRD(2)
++#define DDR_tRP		DDR_TRP(3)
++#define DDR_tRAS	DDR_TRAS(7)
++#define DDR_tRC		DDR_TRC(10)
++#define DDR_tRFC	DDR_TRFC(12)
++#define DDR_tREFI	DDR_TREFI(1288)
++#endif
++
++#if (CONFIG_SCLK_HZ <= 133333333)
++#define	DDR_CL		CL_2
++#elif (CONFIG_SCLK_HZ <= 166666666)
++#define	DDR_CL		CL_2_5
++#else
++#define	DDR_CL		CL_3
++#endif
++
++#define mem_DDRCTL0	(DDR_tRP | DDR_tRAS | DDR_tRC | DDR_tRFC | DDR_tREFI)
++#define mem_DDRCTL1	(DDR_DATWIDTH | EXTBANK_1 | DDR_SIZE | DDR_WIDTH | DDR_tWTR \
++			| DDR_tMRD | DDR_tWR | DDR_tRCD)
++#define mem_DDRCTL2	DDR_CL
+ 
+-#if (CONFIG_MEM_MT46V32M16)
+ 
+ #if defined CONFIG_CLKIN_HALF
+ #define CLKIN_HALF       1
+diff --git a/include/asm-blackfin/mach-bf548/portmux.h b/include/asm-blackfin/mach-bf548/portmux.h
+index 6b48512..8177a56 100644
+--- a/include/asm-blackfin/mach-bf548/portmux.h
++++ b/include/asm-blackfin/mach-bf548/portmux.h
+@@ -1,6 +1,8 @@
+ #ifndef _MACH_PORTMUX_H_
+ #define _MACH_PORTMUX_H_
+ 
++#define MAX_RESOURCES 	MAX_BLACKFIN_GPIOS
++
+ #define P_SPORT2_TFS	(P_DEFINED | P_IDENT(GPIO_PA0) | P_FUNCT(0))
+ #define P_SPORT2_DTSEC	(P_DEFINED | P_IDENT(GPIO_PA1) | P_FUNCT(0))
+ #define P_SPORT2_DTPRI	(P_DEFINED | P_IDENT(GPIO_PA2) | P_FUNCT(0))
+diff --git a/include/asm-blackfin/mach-bf561/anomaly.h b/include/asm-blackfin/mach-bf561/anomaly.h
+index bed9564..0c1d461 100644
+--- a/include/asm-blackfin/mach-bf561/anomaly.h
++++ b/include/asm-blackfin/mach-bf561/anomaly.h
+@@ -7,7 +7,7 @@
+  */
+ 
+ /* This file shoule be up to date with:
+- *  - Revision N, March 28, 2007; ADSP-BF561 Silicon Anomaly List
++ *  - Revision O, 11/15/2007; ADSP-BF561 Blackfin Processor Anomaly List
+  */
+ 
+ #ifndef _MACH_ANOMALY_H_
+@@ -15,7 +15,7 @@
+ 
+ /* We do not support 0.1, 0.2, or 0.4 silicon - sorry */
+ #if __SILICON_REVISION__ < 3 || __SILICON_REVISION__ == 4
+-# error Kernel will not work on BF561 silicon version 0.0, 0.1, 0.2, or 0.4
++# error will not work on BF561 silicon version 0.0, 0.1, 0.2, or 0.4
+ #endif
+ 
+ /* Multi-Issue Instruction with dsp32shiftimm in slot1 and P-reg Store in slot 2 Not Supported */
+@@ -208,6 +208,8 @@
+ #define ANOMALY_05000275 (__SILICON_REVISION__ > 2)
+ /* Timing Requirements Change for External Frame Sync PPI Modes with Non-Zero PPI_DELAY */
+ #define ANOMALY_05000276 (__SILICON_REVISION__ < 5)
++/* Writes to an I/O data register one SCLK cycle after an edge is detected may clear interrupt */
++#define ANOMALY_05000277 (__SILICON_REVISION__ < 3)
+ /* Disabling Peripherals with DMA Running May Cause DMA System Instability */
+ #define ANOMALY_05000278 (__SILICON_REVISION__ < 5)
+ /* False Hardware Error Exception When ISR Context Is Not Restored */
+@@ -246,6 +248,18 @@
+ #define ANOMALY_05000332 (__SILICON_REVISION__ < 5)
+ /* Flag Data Register Writes One SCLK Cycle After Edge Is Detected May Clear Interrupt Status */
+ #define ANOMALY_05000333 (__SILICON_REVISION__ < 5)
++/* New Feature: Additional PPI Frame Sync Sampling Options (Not Available on Older Silicon) */
++#define ANOMALY_05000339 (__SILICON_REVISION__ < 5)
++/* Memory DMA FIFO Causes Throughput Degradation on Writes to External Memory */
++#define ANOMALY_05000343 (__SILICON_REVISION__ < 5)
++/* Serial Port (SPORT) Multichannel Transmit Failure when Channel 0 Is Disabled */
++#define ANOMALY_05000357 (1)
++/* Conflicting Column Address Widths Causes SDRAM Errors */
++#define ANOMALY_05000362 (1)
++/* PPI Underflow Error Goes Undetected in ITU-R 656 Mode */
++#define ANOMALY_05000366 (1)
++/* Possible RETS Register Corruption when Subroutine Is under 5 Cycles in Duration */
++#define ANOMALY_05000371 (1)
+ 
+ /* Anomalies that don't exist on this proc */
+ #define ANOMALY_05000158 (0)
+diff --git a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
+index 69b9f8e..7871d43 100644
+--- a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
++++ b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
+@@ -111,7 +111,7 @@ static void bfin_serial_hw_init(struct bfin_serial_port *uart)
+ 	}
+ 	if (uart->rts_pin >= 0) {
+ 		gpio_request(uart->rts_pin, DRIVER_NAME);
+-		gpio_direction_input(uart->rts_pin);
++		gpio_direction_input(uart->rts_pin, 0);
+ 	}
+ #endif
+ }
+diff --git a/include/asm-blackfin/mach-bf561/portmux.h b/include/asm-blackfin/mach-bf561/portmux.h
+index 132ad31..a6ee820 100644
+--- a/include/asm-blackfin/mach-bf561/portmux.h
++++ b/include/asm-blackfin/mach-bf561/portmux.h
+@@ -1,6 +1,8 @@
+ #ifndef _MACH_PORTMUX_H_
+ #define _MACH_PORTMUX_H_
+ 
++#define MAX_RESOURCES 	MAX_BLACKFIN_GPIOS
++
+ #define P_PPI0_CLK	(P_DONTCARE)
+ #define P_PPI0_FS1	(P_DONTCARE)
+ #define P_PPI0_FS2	(P_DONTCARE)
+diff --git a/include/asm-blackfin/mmu.h b/include/asm-blackfin/mmu.h
+index 11d52f1..757e439 100644
+--- a/include/asm-blackfin/mmu.h
++++ b/include/asm-blackfin/mmu.h
+@@ -24,7 +24,9 @@ typedef struct {
+ 	unsigned long	exec_fdpic_loadmap;
+ 	unsigned long	interp_fdpic_loadmap;
+ #endif
+-
++#ifdef CONFIG_MPU
++	unsigned long *page_rwx_mask;
++#endif
+ } mm_context_t;
+ 
+ #endif
+diff --git a/include/asm-blackfin/mmu_context.h b/include/asm-blackfin/mmu_context.h
+index c5c71a6..b5eb675 100644
+--- a/include/asm-blackfin/mmu_context.h
++++ b/include/asm-blackfin/mmu_context.h
+@@ -30,9 +30,12 @@
+ #ifndef __BLACKFIN_MMU_CONTEXT_H__
+ #define __BLACKFIN_MMU_CONTEXT_H__
+ 
++#include <linux/gfp.h>
++#include <linux/sched.h>
+ #include <asm/setup.h>
+ #include <asm/page.h>
+ #include <asm/pgalloc.h>
++#include <asm/cplbinit.h>
+ 
+ extern void *current_l1_stack_save;
+ extern int nr_l1stack_tasks;
+@@ -50,6 +53,12 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+ static inline int
+ init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+ {
++#ifdef CONFIG_MPU
++	unsigned long p = __get_free_pages(GFP_KERNEL, page_mask_order);
++	mm->context.page_rwx_mask = (unsigned long *)p;
++	memset(mm->context.page_rwx_mask, 0,
++	       page_mask_nelts * 3 * sizeof(long));
++#endif
+ 	return 0;
+ }
+ 
+@@ -73,6 +82,11 @@ static inline void destroy_context(struct mm_struct *mm)
+ 		sram_free(tmp->addr);
+ 		kfree(tmp);
+ 	}
++#ifdef CONFIG_MPU
++	if (current_rwx_mask == mm->context.page_rwx_mask)
++		current_rwx_mask = NULL;
++	free_pages((unsigned long)mm->context.page_rwx_mask, page_mask_order);
++#endif
+ }
+ 
+ static inline unsigned long
+@@ -106,9 +120,21 @@ activate_l1stack(struct mm_struct *mm, unsigned long sp_base)
+ 
+ #define deactivate_mm(tsk,mm)	do { } while (0)
+ 
+-static inline void activate_mm(struct mm_struct *prev_mm,
+-			       struct mm_struct *next_mm)
++#define activate_mm(prev, next) switch_mm(prev, next, NULL)
++
++static inline void switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm,
++			     struct task_struct *tsk)
+ {
++	if (prev_mm == next_mm)
++		return;
++#ifdef CONFIG_MPU
++	if (prev_mm->context.page_rwx_mask == current_rwx_mask) {
++		flush_switched_cplbs();
++		set_mask_dcplbs(next_mm->context.page_rwx_mask);
++	}
++#endif
++
++	/* L1 stack switching.  */
+ 	if (!next_mm->context.l1_stack_save)
+ 		return;
+ 	if (next_mm->context.l1_stack_save == current_l1_stack_save)
+@@ -120,10 +146,36 @@ static inline void activate_mm(struct mm_struct *prev_mm,
+ 	memcpy(l1_stack_base, current_l1_stack_save, l1_stack_len);
+ }
+ 
+-static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+-			     struct task_struct *tsk)
++#ifdef CONFIG_MPU
++static inline void protect_page(struct mm_struct *mm, unsigned long addr,
++				unsigned long flags)
++{
++	unsigned long *mask = mm->context.page_rwx_mask;
++	unsigned long page = addr >> 12;
++	unsigned long idx = page >> 5;
++	unsigned long bit = 1 << (page & 31);
++
++	if (flags & VM_MAYREAD)
++		mask[idx] |= bit;
++	else
++		mask[idx] &= ~bit;
++	mask += page_mask_nelts;
++	if (flags & VM_MAYWRITE)
++		mask[idx] |= bit;
++	else
++		mask[idx] &= ~bit;
++	mask += page_mask_nelts;
++	if (flags & VM_MAYEXEC)
++		mask[idx] |= bit;
++	else
++		mask[idx] &= ~bit;
++}
++
++static inline void update_protections(struct mm_struct *mm)
+ {
+-	activate_mm(prev, next);
++	flush_switched_cplbs();
++	set_mask_dcplbs(mm->context.page_rwx_mask);
+ }
++#endif
+ 
+ #endif
+diff --git a/include/asm-blackfin/traps.h b/include/asm-blackfin/traps.h
+index ee1cbf7..f0e5f94 100644
+--- a/include/asm-blackfin/traps.h
++++ b/include/asm-blackfin/traps.h
+@@ -45,6 +45,10 @@
+ #define VEC_CPLB_I_M	(44)
+ #define VEC_CPLB_I_MHIT	(45)
+ #define VEC_ILL_RES	(46)	/* including unvalid supervisor mode insn */
++/* The hardware reserves (63) for future use - we use it to tell our
++ * normal exception handling code we have a hardware error
++ */
++#define VEC_HWERR	(63)
+ 
+ #ifndef __ASSEMBLY__
+ 
+diff --git a/include/asm-blackfin/uaccess.h b/include/asm-blackfin/uaccess.h
+index 2233f8f..22a410b 100644
+--- a/include/asm-blackfin/uaccess.h
++++ b/include/asm-blackfin/uaccess.h
+@@ -31,7 +31,7 @@ static inline void set_fs(mm_segment_t fs)
+ #define VERIFY_READ	0
+ #define VERIFY_WRITE	1
+ 
+-#define access_ok(type,addr,size) _access_ok((unsigned long)(addr),(size))
++#define access_ok(type, addr, size) _access_ok((unsigned long)(addr), (size))
+ 
+ static inline int is_in_rom(unsigned long addr)
+ {
+diff --git a/include/asm-blackfin/unistd.h b/include/asm-blackfin/unistd.h
+index 07ffe8b..e981673 100644
+--- a/include/asm-blackfin/unistd.h
++++ b/include/asm-blackfin/unistd.h
+@@ -369,8 +369,9 @@
+ #define __NR_set_robust_list	354
+ #define __NR_get_robust_list	355
+ #define __NR_fallocate		356
++#define __NR_semtimedop		357
+ 
+-#define __NR_syscall		357
++#define __NR_syscall		358
+ #define NR_syscalls		__NR_syscall
+ 
+ /* Old optional stuff no one actually uses */
 diff --git a/include/asm-cris/arch-v10/ide.h b/include/asm-cris/arch-v10/ide.h
 index 78b301e..ea34e0d 100644
 --- a/include/asm-cris/arch-v10/ide.h
@@ -194130,10 +209952,85 @@
  	unsigned long priv;
  
 diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
-index e18017d..c7a51a1 100644
+index e18017d..f922b06 100644
 --- a/include/linux/i2c-id.h
 +++ b/include/linux/i2c-id.h
-@@ -125,6 +125,8 @@
+@@ -33,23 +33,13 @@
+ 
+ #define I2C_DRIVERID_MSP3400	 1
+ #define I2C_DRIVERID_TUNER	 2
+-#define I2C_DRIVERID_VIDEOTEX	 3	/* please rename		*/
+ #define I2C_DRIVERID_TDA8425	 4	/* stereo sound processor	*/
+ #define I2C_DRIVERID_TEA6420	 5	/* audio matrix switch		*/
+ #define I2C_DRIVERID_TEA6415C	 6	/* video matrix switch		*/
+ #define I2C_DRIVERID_TDA9840	 7	/* stereo sound processor	*/
+ #define I2C_DRIVERID_SAA7111A	 8	/* video input processor	*/
+-#define I2C_DRIVERID_SAA5281	 9	/* videotext decoder		*/
+-#define I2C_DRIVERID_SAA7112	10	/* video decoder, image scaler	*/
+-#define I2C_DRIVERID_SAA7120	11	/* video encoder		*/
+-#define I2C_DRIVERID_SAA7121	12	/* video encoder		*/
+ #define I2C_DRIVERID_SAA7185B	13	/* video encoder		*/
+-#define I2C_DRIVERID_CH7003	14	/* digital pc to tv encoder	*/
+-#define I2C_DRIVERID_PCF8574A	15	/* i2c expander - 8 bit in/out	*/
+-#define I2C_DRIVERID_PCF8582C	16	/* eeprom			*/
+-#define I2C_DRIVERID_AT24Cxx	17	/* eeprom 1/2/4/8/16 K		*/
+ #define I2C_DRIVERID_TEA6300	18	/* audio mixer			*/
+-#define I2C_DRIVERID_BT829	19	/* pc to tv encoder		*/
+ #define I2C_DRIVERID_TDA9850	20	/* audio mixer			*/
+ #define I2C_DRIVERID_TDA9855	21	/* audio mixer			*/
+ #define I2C_DRIVERID_SAA7110	22	/* video decoder		*/
+@@ -60,42 +50,19 @@
+ #define I2C_DRIVERID_TDA7432	27	/* Stereo sound processor	*/
+ #define I2C_DRIVERID_TVMIXER    28      /* Mixer driver for tv cards    */
+ #define I2C_DRIVERID_TVAUDIO    29      /* Generic TV sound driver      */
+-#define I2C_DRIVERID_DPL3518    30      /* Dolby decoder chip           */
+ #define I2C_DRIVERID_TDA9873    31      /* TV sound decoder chip        */
+ #define I2C_DRIVERID_TDA9875    32      /* TV sound decoder chip        */
+ #define I2C_DRIVERID_PIC16C54_PV9 33    /* Audio mux/ir receiver        */
+-
+-#define I2C_DRIVERID_SBATT      34     /* Smart Battery Device		*/
+-#define I2C_DRIVERID_SBS        35     /* SB System Manager		*/
+-#define I2C_DRIVERID_VES1893	36     /* VLSI DVB-S decoder		*/
+-#define I2C_DRIVERID_VES1820	37     /* VLSI DVB-C decoder		*/
+-#define I2C_DRIVERID_SAA7113	38     /* video decoder			*/
+-#define I2C_DRIVERID_TDA8444	39     /* octuple 6-bit DAC             */
+ #define I2C_DRIVERID_BT819	40     /* video decoder			*/
+ #define I2C_DRIVERID_BT856	41     /* video encoder			*/
+ #define I2C_DRIVERID_VPX3220	42     /* video decoder+vbi/vtxt	*/
+-#define I2C_DRIVERID_DRP3510	43     /* ADR decoder (Astra Radio)	*/
+-#define I2C_DRIVERID_SP5055	44     /* Satellite tuner		*/
+-#define I2C_DRIVERID_STV0030	45     /* Multipurpose switch		*/
+-#define I2C_DRIVERID_SAA7108	46     /* video decoder, image scaler   */
+-#define I2C_DRIVERID_DS1307	47     /* DS1307 real time clock	*/
+ #define I2C_DRIVERID_ADV7175	48     /* ADV 7175/7176 video encoder	*/
+ #define I2C_DRIVERID_SAA7114	49	/* video decoder		*/
+-#define I2C_DRIVERID_ZR36120	50     /* Zoran 36120 video encoder	*/
+-#define I2C_DRIVERID_24LC32A	51	/* Microchip 24LC32A 32k EEPROM	*/
+-#define I2C_DRIVERID_STM41T00	52	/* real time clock		*/
+-#define I2C_DRIVERID_UDA1342	53	/* UDA1342 audio codec		*/
+ #define I2C_DRIVERID_ADV7170	54	/* video encoder		*/
+-#define I2C_DRIVERID_MAX1617	56	/* temp sensor			*/
+ #define I2C_DRIVERID_SAA7191	57	/* video decoder		*/
+ #define I2C_DRIVERID_INDYCAM	58	/* SGI IndyCam			*/
+-#define I2C_DRIVERID_BT832	59	/* CMOS camera video processor	*/
+-#define I2C_DRIVERID_TDA9887	60	/* TDA988x IF-PLL demodulator	*/
+ #define I2C_DRIVERID_OVCAMCHIP	61	/* OmniVision CMOS image sens.	*/
+-#define I2C_DRIVERID_TDA7313	62	/* TDA7313 audio processor	*/
+ #define I2C_DRIVERID_MAX6900	63	/* MAX6900 real-time clock	*/
+-#define I2C_DRIVERID_SAA7114H	64	/* video decoder		*/
+-#define I2C_DRIVERID_DS1374	65	/* DS1374 real time clock	*/
+ #define I2C_DRIVERID_TDA9874	66	/* TV sound decoder		*/
+ #define I2C_DRIVERID_SAA6752HS	67	/* MPEG2 encoder		*/
+ #define I2C_DRIVERID_TVEEPROM	68	/* TV EEPROM			*/
+@@ -114,7 +81,6 @@
+ #define I2C_DRIVERID_DS1672	81	/* Dallas/Maxim DS1672 RTC	*/
+ #define I2C_DRIVERID_X1205	82	/* Xicor/Intersil X1205 RTC	*/
+ #define I2C_DRIVERID_PCF8563	83	/* Philips PCF8563 RTC		*/
+-#define I2C_DRIVERID_RS5C372	84	/* Ricoh RS5C372 RTC		*/
+ #define I2C_DRIVERID_BT866	85	/* Conexant bt866 video encoder */
+ #define I2C_DRIVERID_KS0127	86	/* Samsung ks0127 video decoder */
+ #define I2C_DRIVERID_TLV320AIC23B 87	/* TI TLV320AIC23B audio codec  */
+@@ -125,10 +91,10 @@
  #define I2C_DRIVERID_LM4857 	92 	/* LM4857 Audio Amplifier */
  #define I2C_DRIVERID_VP27SMPX	93	/* Panasonic VP27s tuner internal MPX */
  #define I2C_DRIVERID_CS4270	94	/* Cirrus Logic 4270 audio codec */
@@ -194141,7 +210038,528 @@
 +#define I2C_DRIVERID_CS5345	96	/* cs5345 audio processor	*/
  
  #define I2C_DRIVERID_I2CDEV	900
- #define I2C_DRIVERID_ARP        902    /* SMBus ARP Client              */
+-#define I2C_DRIVERID_ARP        902    /* SMBus ARP Client              */
+-#define I2C_DRIVERID_ALERT      903    /* SMBus Alert Responder Client  */
+ 
+ /* IDs --   Use DRIVERIDs 1000-1999 for sensors.
+    These were originally in sensors.h in the lm_sensors package */
+@@ -174,24 +140,16 @@
+ 
+ /* --- Bit algorithm adapters						*/
+ #define I2C_HW_B_LP		0x010000 /* Parallel port Philips style */
+-#define I2C_HW_B_SER		0x010002 /* Serial line interface */
+ #define I2C_HW_B_BT848		0x010005 /* BT848 video boards */
+-#define I2C_HW_B_WNV		0x010006 /* Winnov Videums */
+ #define I2C_HW_B_VIA		0x010007 /* Via vt82c586b */
+ #define I2C_HW_B_HYDRA		0x010008 /* Apple Hydra Mac I/O */
+ #define I2C_HW_B_G400		0x010009 /* Matrox G400 */
+ #define I2C_HW_B_I810		0x01000a /* Intel I810 */
+ #define I2C_HW_B_VOO		0x01000b /* 3dfx Voodoo 3 / Banshee */
+-#define I2C_HW_B_PPORT		0x01000c /* Primitive parallel port adapter */
+-#define I2C_HW_B_SAVG		0x01000d /* Savage 4 */
+ #define I2C_HW_B_SCX200		0x01000e /* Nat'l Semi SCx200 I2C */
+ #define I2C_HW_B_RIVA		0x010010 /* Riva based graphics cards */
+ #define I2C_HW_B_IOC		0x010011 /* IOC bit-wiggling */
+-#define I2C_HW_B_TSUNA		0x010012 /* DEC Tsunami chipset */
+-#define I2C_HW_B_OMAHA		0x010014 /* Omaha I2C interface (ARM) */
+-#define I2C_HW_B_GUIDE		0x010015 /* Guide bit-basher */
+ #define I2C_HW_B_IXP2000	0x010016 /* GPIO on IXP2000 systems */
+-#define I2C_HW_B_IXP4XX		0x010017 /* GPIO on IXP4XX systems */
+ #define I2C_HW_B_S3VIA		0x010018 /* S3Via ProSavage adapter */
+ #define I2C_HW_B_ZR36067	0x010019 /* Zoran-36057/36067 based boards */
+ #define I2C_HW_B_PCILYNX	0x01001a /* TI PCILynx I2C adapter */
+@@ -205,22 +163,11 @@
+ #define I2C_HW_B_CX23885	0x010022 /* conexant 23885 based tv cards (bus1) */
+ 
+ /* --- PCF 8584 based algorithms					*/
+-#define I2C_HW_P_LP		0x020000 /* Parallel port interface */
+-#define I2C_HW_P_ISA		0x020001 /* generic ISA Bus inteface card */
+ #define I2C_HW_P_ELEK		0x020002 /* Elektor ISA Bus inteface card */
+ 
+ /* --- PCA 9564 based algorithms */
+ #define I2C_HW_A_ISA		0x1a0000 /* generic ISA Bus interface card */
+ 
+-/* --- ACPI Embedded controller algorithms                              */
+-#define I2C_HW_ACPI_EC          0x1f0000
+-
+-/* --- MPC824x PowerPC adapters						*/
+-#define I2C_HW_MPC824X		0x100001 /* Motorola 8240 / 8245 */
+-
+-/* --- MPC8xx PowerPC adapters						*/
+-#define I2C_HW_MPC8XX_EPON	0x110000 /* Eponymous MPC8xx I2C adapter */
+-
+ /* --- PowerPC on-chip adapters						*/
+ #define I2C_HW_OCP		0x120000 /* IBM on-chip I2C adapter */
+ 
+@@ -229,7 +176,6 @@
+ 
+ /* --- SGI adapters							*/
+ #define I2C_HW_SGI_VINO		0x160000
+-#define I2C_HW_SGI_MACE		0x160001
+ 
+ /* --- XSCALE on-chip adapters                          */
+ #define I2C_HW_IOP3XX		0x140000
+@@ -253,17 +199,10 @@
+ #define I2C_HW_SMBUS_W9968CF	0x04000d
+ #define I2C_HW_SMBUS_OV511	0x04000e /* OV511(+) USB 1.1 webcam ICs */
+ #define I2C_HW_SMBUS_OV518	0x04000f /* OV518(+) USB 1.1 webcam ICs */
+-#define I2C_HW_SMBUS_OV519	0x040010 /* OV519 USB 1.1 webcam IC */
+ #define I2C_HW_SMBUS_OVFX2	0x040011 /* Cypress/OmniVision FX2 webcam */
+ #define I2C_HW_SMBUS_CAFE	0x040012 /* Marvell 88ALP01 "CAFE" cam  */
+ #define I2C_HW_SMBUS_ALI1563	0x040013
+ 
+-/* --- ISA pseudo-adapter						*/
+-#define I2C_HW_ISA		0x050000
+-
+-/* --- IPMB adapter						*/
+-#define I2C_HW_IPMB		0x0c0000
+-
+ /* --- MCP107 adapter */
+ #define I2C_HW_MPC107		0x0d0000
+ 
+diff --git a/include/linux/i2c.h b/include/linux/i2c.h
+index a100c9f..76014f8 100644
+--- a/include/linux/i2c.h
++++ b/include/linux/i2c.h
+@@ -140,7 +140,6 @@ struct i2c_driver {
+ 	int (*command)(struct i2c_client *client,unsigned int cmd, void *arg);
+ 
+ 	struct device_driver driver;
+-	struct list_head list;
+ };
+ #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
+ 
+@@ -155,12 +154,11 @@ struct i2c_driver {
+  *	generic enough to hide second-sourcing and compatible revisions.
+  * @adapter: manages the bus segment hosting this I2C device
+  * @driver: device's driver, hence pointer to access routines
+- * @usage_count: counts current number of users of this client
+  * @dev: Driver model device node for the slave.
+  * @irq: indicates the IRQ generated by this device (if any)
+  * @driver_name: Identifies new-style driver used with this device; also
+  *	used as the module name for hotplug/coldplug modprobe support.
+- * @list: list of active/busy clients
++ * @list: list of active/busy clients (DEPRECATED)
+  * @released: used to synchronize client releases & detaches and references
+  *
+  * An i2c_client identifies a single device (i.e. chip) connected to an
+@@ -175,16 +173,16 @@ struct i2c_client {
+ 	char name[I2C_NAME_SIZE];
+ 	struct i2c_adapter *adapter;	/* the adapter we sit on	*/
+ 	struct i2c_driver *driver;	/* and our access routines	*/
+-	int usage_count;		/* How many accesses currently  */
+-					/* to the client		*/
+ 	struct device dev;		/* the device structure		*/
+ 	int irq;			/* irq issued by device (or -1) */
+ 	char driver_name[KOBJ_NAME_LEN];
+-	struct list_head list;
++	struct list_head list;		/* DEPRECATED */
+ 	struct completion released;
+ };
+ #define to_i2c_client(d) container_of(d, struct i2c_client, dev)
+ 
++extern struct i2c_client *i2c_verify_client(struct device *dev);
++
+ static inline struct i2c_client *kobj_to_i2c_client(struct kobject *kobj)
+ {
+ 	struct device * const dev = container_of(kobj, struct device, kobj);
+@@ -261,6 +259,12 @@ i2c_new_probed_device(struct i2c_adapter *adap,
+ 		      struct i2c_board_info *info,
+ 		      unsigned short const *addr_list);
+ 
++/* For devices that use several addresses, use i2c_new_dummy() to make
++ * client handles for the extra addresses.
++ */
++extern struct i2c_client *
++i2c_new_dummy(struct i2c_adapter *adap, u16 address, const char *type);
++
+ extern void i2c_unregister_device(struct i2c_client *);
+ 
+ /* Mainboard arch_initcall() code should register all its I2C devices.
+@@ -319,8 +323,7 @@ struct i2c_adapter {
+ 	struct device dev;		/* the adapter device */
+ 
+ 	int nr;
+-	struct list_head clients;
+-	struct list_head list;
++	struct list_head clients;	/* DEPRECATED */
+ 	char name[48];
+ 	struct completion dev_released;
+ };
+@@ -357,10 +360,10 @@ static inline void i2c_set_adapdata (struct i2c_adapter *dev, void *data)
+  * command line
+  */
+ struct i2c_client_address_data {
+-	unsigned short *normal_i2c;
+-	unsigned short *probe;
+-	unsigned short *ignore;
+-	unsigned short **forces;
++	const unsigned short *normal_i2c;
++	const unsigned short *probe;
++	const unsigned short *ignore;
++	const unsigned short * const *forces;
+ };
+ 
+ /* Internal numbers to terminate lists */
+@@ -389,11 +392,8 @@ static inline int i2c_add_driver(struct i2c_driver *driver)
+ extern int i2c_attach_client(struct i2c_client *);
+ extern int i2c_detach_client(struct i2c_client *);
+ 
+-/* Should be used to make sure that client-struct is valid and that it
+-   is okay to access the i2c-client.
+-   returns -ENODEV if client has gone in the meantime */
+-extern int i2c_use_client(struct i2c_client *);
+-extern int i2c_release_client(struct i2c_client *);
++extern struct i2c_client *i2c_use_client(struct i2c_client *client);
++extern void i2c_release_client(struct i2c_client *client);
+ 
+ /* call the i2c_client->command() of all attached clients with
+  * the given arguments */
+@@ -405,7 +405,7 @@ extern void i2c_clients_command(struct i2c_adapter *adap,
+  * specific address (unless a 'force' matched);
+  */
+ extern int i2c_probe(struct i2c_adapter *adapter,
+-		struct i2c_client_address_data *address_data,
++		const struct i2c_client_address_data *address_data,
+ 		int (*found_proc) (struct i2c_adapter *, int, int));
+ 
+ extern struct i2c_adapter* i2c_get_adapter(int id);
+@@ -598,104 +598,93 @@ I2C_CLIENT_MODULE_PARM(probe, "List of adapter,address pairs to scan "	\
+ 		       "additionally");					\
+ I2C_CLIENT_MODULE_PARM(ignore, "List of adapter,address pairs not to "	\
+ 		       "scan");						\
+-static struct i2c_client_address_data addr_data = {			\
++const static struct i2c_client_address_data addr_data = {		\
+ 	.normal_i2c	= normal_i2c,					\
+ 	.probe		= probe,					\
+ 	.ignore		= ignore,					\
+ 	.forces		= forces,					\
+ }
+ 
++#define I2C_CLIENT_FORCE_TEXT \
++	"List of adapter,address pairs to boldly assume to be present"
++
+ /* These are the ones you want to use in your own drivers. Pick the one
+    which matches the number of devices the driver differenciates between. */
+-#define I2C_CLIENT_INSMOD \
+-  I2C_CLIENT_MODULE_PARM(force, \
+-                      "List of adapter,address pairs to boldly assume " \
+-                      "to be present"); \
+-	static unsigned short *forces[] = {				\
+-			force,						\
+-			NULL						\
+-		};							\
++#define I2C_CLIENT_INSMOD						\
++I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT);			\
++static const unsigned short * const forces[] = { force, NULL };		\
+ I2C_CLIENT_INSMOD_COMMON
+ 
+ #define I2C_CLIENT_INSMOD_1(chip1)					\
+ enum chips { any_chip, chip1 };						\
+-I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to "	\
+-		       "boldly assume to be present");			\
++I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT);			\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip1);					\
+-static unsigned short *forces[] = { force, force_##chip1, NULL };	\
++static const unsigned short * const forces[] =	{ force,		\
++	force_##chip1, NULL };						\
+ I2C_CLIENT_INSMOD_COMMON
+ 
+ #define I2C_CLIENT_INSMOD_2(chip1, chip2)				\
+ enum chips { any_chip, chip1, chip2 };					\
+-I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to "	\
+-		       "boldly assume to be present");			\
++I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT);			\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip1);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip2);					\
+-static unsigned short *forces[] = { force, force_##chip1,		\
+-				    force_##chip2, NULL };		\
++static const unsigned short * const forces[] =	{ force,		\
++	force_##chip1, force_##chip2, NULL };				\
+ I2C_CLIENT_INSMOD_COMMON
+ 
+ #define I2C_CLIENT_INSMOD_3(chip1, chip2, chip3)			\
+ enum chips { any_chip, chip1, chip2, chip3 };				\
+-I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to "	\
+-		       "boldly assume to be present");			\
++I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT);			\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip1);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip2);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip3);					\
+-static unsigned short *forces[] = { force, force_##chip1,		\
+-				    force_##chip2, force_##chip3,	\
+-				    NULL };				\
++static const unsigned short * const forces[] =	{ force,		\
++	force_##chip1, force_##chip2, force_##chip3, NULL };		\
+ I2C_CLIENT_INSMOD_COMMON
+ 
+ #define I2C_CLIENT_INSMOD_4(chip1, chip2, chip3, chip4)			\
+ enum chips { any_chip, chip1, chip2, chip3, chip4 };			\
+-I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to "	\
+-		       "boldly assume to be present");			\
++I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT);			\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip1);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip2);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip3);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip4);					\
+-static unsigned short *forces[] = { force, force_##chip1,		\
+-				    force_##chip2, force_##chip3,	\
+-				    force_##chip4, NULL};		\
++static const unsigned short * const forces[] =	{ force,		\
++	force_##chip1, force_##chip2, force_##chip3,			\
++	force_##chip4, NULL};						\
+ I2C_CLIENT_INSMOD_COMMON
+ 
+ #define I2C_CLIENT_INSMOD_5(chip1, chip2, chip3, chip4, chip5)		\
+ enum chips { any_chip, chip1, chip2, chip3, chip4, chip5 };		\
+-I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to "	\
+-		       "boldly assume to be present");			\
++I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT);			\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip1);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip2);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip3);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip4);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip5);					\
+-static unsigned short *forces[] = { force, force_##chip1,		\
+-				    force_##chip2, force_##chip3,	\
+-				    force_##chip4, force_##chip5,	\
+-				    NULL };				\
++static const unsigned short * const forces[] = { force,			\
++	force_##chip1, force_##chip2, force_##chip3,			\
++	force_##chip4, force_##chip5, NULL };				\
+ I2C_CLIENT_INSMOD_COMMON
+ 
+ #define I2C_CLIENT_INSMOD_6(chip1, chip2, chip3, chip4, chip5, chip6)	\
+ enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6 };	\
+-I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to "	\
+-		       "boldly assume to be present");			\
++I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT);			\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip1);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip2);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip3);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip4);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip5);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip6);					\
+-static unsigned short *forces[] = { force, force_##chip1,		\
+-				    force_##chip2, force_##chip3,	\
+-				    force_##chip4, force_##chip5,	\
+-				    force_##chip6, NULL };		\
++static const unsigned short * const forces[] = { force,			\
++	force_##chip1, force_##chip2, force_##chip3,			\
++	force_##chip4, force_##chip5, force_##chip6, NULL };		\
+ I2C_CLIENT_INSMOD_COMMON
+ 
+ #define I2C_CLIENT_INSMOD_7(chip1, chip2, chip3, chip4, chip5, chip6, chip7) \
+ enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6,	\
+ 	     chip7 };							\
+-I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to "	\
+-		       "boldly assume to be present");			\
++I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT);			\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip1);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip2);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip3);					\
+@@ -703,18 +692,16 @@ I2C_CLIENT_MODULE_PARM_FORCE(chip4);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip5);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip6);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip7);					\
+-static unsigned short *forces[] = { force, force_##chip1,		\
+-				    force_##chip2, force_##chip3,	\
+-				    force_##chip4, force_##chip5,	\
+-				    force_##chip6, force_##chip7,	\
+-				    NULL };				\
++static const unsigned short * const forces[] = { force,			\
++	force_##chip1, force_##chip2, force_##chip3,			\
++	force_##chip4, force_##chip5, force_##chip6,			\
++	force_##chip7, NULL };						\
+ I2C_CLIENT_INSMOD_COMMON
+ 
+ #define I2C_CLIENT_INSMOD_8(chip1, chip2, chip3, chip4, chip5, chip6, chip7, chip8) \
+ enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6,	\
+ 	     chip7, chip8 };						\
+-I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to "	\
+-		       "boldly assume to be present");			\
++I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT);			\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip1);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip2);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip3);					\
+@@ -723,11 +710,10 @@ I2C_CLIENT_MODULE_PARM_FORCE(chip5);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip6);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip7);					\
+ I2C_CLIENT_MODULE_PARM_FORCE(chip8);					\
+-static unsigned short *forces[] = { force, force_##chip1,		\
+-				    force_##chip2, force_##chip3,	\
+-				    force_##chip4, force_##chip5,	\
+-				    force_##chip6, force_##chip7,	\
+-				    force_##chip8, NULL };		\
++static const unsigned short * const forces[] = { force,			\
++	force_##chip1, force_##chip2, force_##chip3,			\
++	force_##chip4, force_##chip5, force_##chip6,			\
++	force_##chip7, force_##chip8, NULL };				\
+ I2C_CLIENT_INSMOD_COMMON
+ #endif /* __KERNEL__ */
+ #endif /* _LINUX_I2C_H */
+diff --git a/include/linux/i2c/tps65010.h b/include/linux/i2c/tps65010.h
+new file mode 100644
+index 0000000..7021635
+--- /dev/null
++++ b/include/linux/i2c/tps65010.h
+@@ -0,0 +1,156 @@
++/* linux/i2c/tps65010.h
++ *
++ * Functions to access TPS65010 power management device.
++ *
++ * Copyright (C) 2004 Dirk Behme <dirk.behme at de.bosch.com>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ *
++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * You should have received a copy of the  GNU General Public License along
++ * with this program; if not, write  to the Free Software Foundation, Inc.,
++ * 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifndef __LINUX_I2C_TPS65010_H
++#define __LINUX_I2C_TPS65010_H
++
++/*
++ * ----------------------------------------------------------------------------
++ * Registers, all 8 bits
++ * ----------------------------------------------------------------------------
++ */
++
++#define	TPS_CHGSTATUS		0x01
++#	define	TPS_CHG_USB		(1 << 7)
++#	define	TPS_CHG_AC		(1 << 6)
++#	define	TPS_CHG_THERM		(1 << 5)
++#	define	TPS_CHG_TERM		(1 << 4)
++#	define	TPS_CHG_TAPER_TMO	(1 << 3)
++#	define	TPS_CHG_CHG_TMO		(1 << 2)
++#	define	TPS_CHG_PRECHG_TMO	(1 << 1)
++#	define	TPS_CHG_TEMP_ERR	(1 << 0)
++#define	TPS_REGSTATUS		0x02
++#	define	TPS_REG_ONOFF		(1 << 7)
++#	define	TPS_REG_COVER		(1 << 6)
++#	define	TPS_REG_UVLO		(1 << 5)
++#	define	TPS_REG_NO_CHG		(1 << 4)	/* tps65013 */
++#	define	TPS_REG_PG_LD02		(1 << 3)
++#	define	TPS_REG_PG_LD01		(1 << 2)
++#	define	TPS_REG_PG_MAIN		(1 << 1)
++#	define	TPS_REG_PG_CORE		(1 << 0)
++#define	TPS_MASK1		0x03
++#define	TPS_MASK2		0x04
++#define	TPS_ACKINT1		0x05
++#define	TPS_ACKINT2		0x06
++#define	TPS_CHGCONFIG		0x07
++#	define	TPS_CHARGE_POR		(1 << 7)	/* 65010/65012 */
++#	define	TPS65013_AUA		(1 << 7)	/* 65011/65013 */
++#	define	TPS_CHARGE_RESET	(1 << 6)
++#	define	TPS_CHARGE_FAST		(1 << 5)
++#	define	TPS_CHARGE_CURRENT	(3 << 3)
++#	define	TPS_VBUS_500MA		(1 << 2)
++#	define	TPS_VBUS_CHARGING	(1 << 1)
++#	define	TPS_CHARGE_ENABLE	(1 << 0)
++#define	TPS_LED1_ON		0x08
++#define	TPS_LED1_PER		0x09
++#define	TPS_LED2_ON		0x0a
++#define	TPS_LED2_PER		0x0b
++#define	TPS_VDCDC1		0x0c
++#	define	TPS_ENABLE_LP		(1 << 3)
++#define	TPS_VDCDC2		0x0d
++#define	TPS_VREGS1		0x0e
++#	define	TPS_LDO2_ENABLE	(1 << 7)
++#	define	TPS_LDO2_OFF	(1 << 6)
++#	define	TPS_VLDO2_3_0V	(3 << 4)
++#	define	TPS_VLDO2_2_75V	(2 << 4)
++#	define	TPS_VLDO2_2_5V	(1 << 4)
++#	define	TPS_VLDO2_1_8V	(0 << 4)
++#	define	TPS_LDO1_ENABLE	(1 << 3)
++#	define	TPS_LDO1_OFF	(1 << 2)
++#	define	TPS_VLDO1_3_0V	(3 << 0)
++#	define	TPS_VLDO1_2_75V	(2 << 0)
++#	define	TPS_VLDO1_2_5V	(1 << 0)
++#	define	TPS_VLDO1_ADJ	(0 << 0)
++#define	TPS_MASK3		0x0f
++#define	TPS_DEFGPIO		0x10
++
++/*
++ * ----------------------------------------------------------------------------
++ * Macros used by exported functions
++ * ----------------------------------------------------------------------------
++ */
++
++#define LED1  1
++#define LED2  2
++#define OFF   0
++#define ON    1
++#define BLINK 2
++#define GPIO1 1
++#define GPIO2 2
++#define GPIO3 3
++#define GPIO4 4
++#define LOW   0
++#define HIGH  1
++
++/*
++ * ----------------------------------------------------------------------------
++ * Exported functions
++ * ----------------------------------------------------------------------------
++ */
++
++/* Draw from VBUS:
++ *   0 mA -- DON'T DRAW (might supply power instead)
++ * 100 mA -- usb unit load (slowest charge rate)
++ * 500 mA -- usb high power (fast battery charge)
++ */
++extern int tps65010_set_vbus_draw(unsigned mA);
++
++/* tps65010_set_gpio_out_value parameter:
++ * gpio:  GPIO1, GPIO2, GPIO3 or GPIO4
++ * value: LOW or HIGH
++ */
++extern int tps65010_set_gpio_out_value(unsigned gpio, unsigned value);
++
++/* tps65010_set_led parameter:
++ * led:  LED1 or LED2
++ * mode: ON, OFF or BLINK
++ */
++extern int tps65010_set_led(unsigned led, unsigned mode);
++
++/* tps65010_set_vib parameter:
++ * value: ON or OFF
++ */
++extern int tps65010_set_vib(unsigned value);
++
++/* tps65010_set_low_pwr parameter:
++ * mode: ON or OFF
++ */
++extern int tps65010_set_low_pwr(unsigned mode);
++
++/* tps65010_config_vregs1 parameter:
++ * value to be written to VREGS1 register
++ * Note: The complete register is written, set all bits you need
++ */
++extern int tps65010_config_vregs1(unsigned value);
++
++/* tps65013_set_low_pwr parameter:
++ * mode: ON or OFF
++ */
++extern int tps65013_set_low_pwr(unsigned mode);
++
++#endif /*  __LINUX_I2C_TPS65010_H */
++
 diff --git a/include/linux/ide.h b/include/linux/ide.h
 index 9a6a41e..27cb39d 100644
 --- a/include/linux/ide.h
@@ -195512,6 +211930,62 @@
  static inline unsigned int ac_err_mask(u8 status)
  {
  	if (status & (ATA_BUSY | ATA_DRQ))
+diff --git a/include/linux/m41t00.h b/include/linux/m41t00.h
+deleted file mode 100644
+index b423360..0000000
+--- a/include/linux/m41t00.h
++++ /dev/null
+@@ -1,50 +0,0 @@
+-/*
+- * Definitions for the ST M41T00 family of i2c rtc chips.
+- *
+- * Author: Mark A. Greer <mgreer at mvista.com>
+- *
+- * 2005, 2006 (c) MontaVista Software, Inc. This file is licensed under
+- * the terms of the GNU General Public License version 2. This program
+- * is licensed "as is" without any warranty of any kind, whether express
+- * or implied.
+- */
+-
+-#ifndef _M41T00_H
+-#define _M41T00_H
+-
+-#define	M41T00_DRV_NAME		"m41t00"
+-#define	M41T00_I2C_ADDR		0x68
+-
+-#define	M41T00_TYPE_M41T00	0
+-#define	M41T00_TYPE_M41T81	81
+-#define	M41T00_TYPE_M41T85	85
+-
+-struct m41t00_platform_data {
+-	u8	type;
+-	u8	i2c_addr;
+-	u8	sqw_freq;
+-};
+-
+-/* SQW output disabled, this is default value by power on */
+-#define M41T00_SQW_DISABLE	(0)
+-
+-#define M41T00_SQW_32KHZ	(1<<4)		/* 32.768 KHz */
+-#define M41T00_SQW_8KHZ		(2<<4)		/* 8.192 KHz */
+-#define M41T00_SQW_4KHZ		(3<<4)		/* 4.096 KHz */
+-#define M41T00_SQW_2KHZ		(4<<4)		/* 2.048 KHz */
+-#define M41T00_SQW_1KHZ		(5<<4)		/* 1.024 KHz */
+-#define M41T00_SQW_512HZ	(6<<4)		/* 512 Hz */
+-#define M41T00_SQW_256HZ	(7<<4)		/* 256 Hz */
+-#define M41T00_SQW_128HZ	(8<<4)		/* 128 Hz */
+-#define M41T00_SQW_64HZ		(9<<4)		/* 64 Hz */
+-#define M41T00_SQW_32HZ		(10<<4)		/* 32 Hz */
+-#define M41T00_SQW_16HZ		(11<<4)		/* 16 Hz */
+-#define M41T00_SQW_8HZ		(12<<4)		/* 8 Hz */
+-#define M41T00_SQW_4HZ		(13<<4)		/* 4 Hz */
+-#define M41T00_SQW_2HZ		(14<<4)		/* 2 Hz */
+-#define M41T00_SQW_1HZ		(15<<4)		/* 1 Hz */
+-
+-extern ulong m41t00_get_rtc_time(void);
+-extern int m41t00_set_rtc_time(ulong nowtime);
+-
+-#endif /* _M41T00_H */
 diff --git a/include/linux/mm.h b/include/linux/mm.h
 index 1b7b95c..1897ca2 100644
 --- a/include/linux/mm.h
@@ -197085,7 +213559,7 @@
  #define VIDIOC_INT_S_TUNER_MODE	     _IOW('d', 93, enum v4l2_tuner_type)
 diff --git a/include/media/v4l2-i2c-drv-legacy.h b/include/media/v4l2-i2c-drv-legacy.h
 new file mode 100644
-index 0000000..2418542
+index 0000000..e764557
 --- /dev/null
 +++ b/include/media/v4l2-i2c-drv-legacy.h
 @@ -0,0 +1,140 @@
@@ -197125,7 +213599,7 @@
 +};
 +
 +static struct v4l2_i2c_driver_data v4l2_i2c_data;
-+static struct i2c_client_address_data addr_data;
++static const struct i2c_client_address_data addr_data;
 +static struct i2c_driver v4l2_i2c_driver_legacy;
 +static char v4l2_i2c_drv_name_legacy[32];
 +
@@ -211369,3 +227843,50 @@
  	POLICY_RDLOCK;
  
  	for (genfs = policydb.genfs; genfs; genfs = genfs->next) {
+diff --git a/sound/ppc/keywest.c b/sound/ppc/keywest.c
+index 272ae38..bb7d744 100644
+--- a/sound/ppc/keywest.c
++++ b/sound/ppc/keywest.c
+@@ -34,8 +34,6 @@
+ static struct pmac_keywest *keywest_ctx;
+ 
+ 
+-#define I2C_DRIVERID_KEYWEST	0xFEBA
+-
+ static int keywest_attach_adapter(struct i2c_adapter *adapter);
+ static int keywest_detach_client(struct i2c_client *client);
+ 
+@@ -43,7 +41,6 @@ struct i2c_driver keywest_driver = {
+ 	.driver = {
+ 		.name = "PMac Keywest Audio",
+ 	},
+-	.id = I2C_DRIVERID_KEYWEST,
+ 	.attach_adapter = &keywest_attach_adapter,
+ 	.detach_client = &keywest_detach_client,
+ };
+diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
+index abac628..dab22cc 100644
+--- a/sound/soc/codecs/cs4270.c
++++ b/sound/soc/codecs/cs4270.c
+@@ -234,7 +234,7 @@ static int cs4270_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
+  * lower three bits are determined via the AD2, AD1, and AD0 pins
+  * (respectively).
+  */
+-static unsigned short normal_i2c[] = {
++static const unsigned short normal_i2c[] = {
+ 	0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, I2C_CLIENT_END
+ };
+ I2C_CLIENT_INSMOD;
+diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c
+index d5a8fc2..f1f6b94 100644
+--- a/sound/soc/s3c24xx/neo1973_wm8753.c
++++ b/sound/soc/s3c24xx/neo1973_wm8753.c
+@@ -573,7 +573,7 @@ static struct snd_soc_device neo1973_snd_devdata = {
+ 
+ static struct i2c_client client_template;
+ 
+-static unsigned short normal_i2c[] = { 0x7C, I2C_CLIENT_END };
++static const unsigned short normal_i2c[] = { 0x7C, I2C_CLIENT_END };
+ 
+ /* Magic definition of all other variables and things */
+ I2C_CLIENT_INSMOD;

Modified: dists/trunk/linux-2.6/debian/patches/series/1~experimental.1
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/1~experimental.1	(original)
+++ dists/trunk/linux-2.6/debian/patches/series/1~experimental.1	Mon Jan 28 09:31:14 2008
@@ -17,11 +17,11 @@
 + bugfix/mips/tulip_mwi_fix.patch
 + features/arm/ixp4xx-feature-bits.patch
 + features/arm/ixp4xx-npe-and-qmgr.patch
-+ features/arm/ixp4xx-net-headers.patch
+#+ features/arm/ixp4xx-net-headers.patch
 + features/arm/ixp4xx-net-drivers.patch
-+ features/arm/nas100d-i2c-gpio-driver-support.patch
+#+ features/arm/nas100d-i2c-gpio-driver-support.patch
 + features/arm/nas100d-net-driver-support.patch
-+ features/arm/nslu2-i2c-gpio-driver-support.patch
+#+ features/arm/nslu2-i2c-gpio-driver-support.patch
 + features/arm/nslu2-net-driver-support.patch
 + bugfix/sparc/drivers_net-broken.patch
 + bugfix/ia64/hardcode-arch-script-output.patch
@@ -41,4 +41,4 @@
 + bugfix/all/fw-sbp2-incr-login-orb-reply-timeout.patch
 + bugfix/all/fw-sbp2-skip-unnecessary-logout.patch
 + bugfix/all/fw-sbp2-try-increase-reconnect_hold.patch
-+ bugfix/all/patch-2.6.24-git3
++ bugfix/all/patch-2.6.24-git4



More information about the Kernel-svn-changes mailing list