[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