Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (25 commits)
  [XFRM]: Fix oops in xfrm4_dst_destroy()
  [XFRM_TUNNEL]: Reload header pointer after pskb_may_pull/pskb_expand_head
  [IPV4]: Use random32() in net/ipv4/multipath
  [BRIDGE]: eliminate workqueue for carrier check
  [BRIDGE]: get rid of miscdevice include
  [IPV6]: Fix __ipv6_addr_type() export in correct place.
  [IPV4] devinet: Register inetdev earlier.
  [IPV6] ADDRCONF: Register inet6_dev earlier.
  [IPV6] ADDRCONF: Manage prefix route corresponding to address manually added.
  [IPV6] IP6TUNNEL: Use update_pmtu() of dst on xmit.
  [IPV6] ADDRCONF: Statically link __ipv6_addr_type() for sunrpc subsystem.
  [IPV4]: Correct links in net/ipv4/Kconfig
  [SCTP]: Strike the transport before updating rto.
  [SCTP]: Fix connection hang/slowdown with PR-SCTP
  [TCP]: Fix MD5 signature pool locking.
  [TG3]: TSO workaround fixes.
  [AF_PACKET]: Remove unnecessary casts.
  [IPV6]: Adjust inet6_exit() cleanup sequence against inet6_init()
  [IPSEC]: More fix is needed for __xfrm6_bundle_create().
  [IRDA] net/irda/: proper prototypes
  ...
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index c479d30..03eb5ed 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1758,6 +1758,13 @@
 			Note that genuine overcurrent events won't be
 			reported either.
 
+	usbcore.autosuspend=
+			[USB] The autosuspend time delay (in seconds) used
+			for newly-detected USB devices (default 2).  This
+			is the time required before an idle device will be
+			autosuspended.  Devices for which the delay is set
+			to 0 won't be autosuspended at all.
+
 	usbhid.mousepoll=
 			[USBHID] The interval which mice are to be polled at.
 
diff --git a/Documentation/magic-number.txt b/Documentation/magic-number.txt
index af67fac..0e740c8 100644
--- a/Documentation/magic-number.txt
+++ b/Documentation/magic-number.txt
@@ -65,7 +65,6 @@
 MKISS_DRIVER_MAGIC    0x04bf      mkiss_channel     drivers/net/mkiss.h
 RISCOM8_MAGIC         0x0907      riscom_port       drivers/char/riscom8.h
 SPECIALIX_MAGIC       0x0907      specialix_port    drivers/char/specialix_io8.h
-AURORA_MAGIC          0x0A18      Aurora_port       drivers/sbus/char/aurora.h
 HDLC_MAGIC            0x239e      n_hdlc            drivers/char/n_hdlc.c
 APM_BIOS_MAGIC        0x4101      apm_user          arch/i386/kernel/apm.c
 CYCLADES_MAGIC        0x4359      cyclades_port     include/linux/cyclades.h
diff --git a/MAINTAINERS b/MAINTAINERS
index c268b51..a9c1319 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3392,6 +3392,13 @@
 S:	Maintained
 W:	http://www.kroah.com/linux-usb/
 
+USB DAVICOM DM9601 DRIVER
+P:	Peter Korsgaard
+M:	jacmet@sunsite.dk
+L:	linux-usb-devel@lists.sourceforge.net
+W:	http://www.linux-usb.org/usbnet
+S:	Maintained
+
 USB EHCI DRIVER
 P:	David Brownell
 M:	dbrownell@users.sourceforge.net
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index c6f74f1..58e9788 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -274,6 +274,7 @@
 	select SYS_SUPPORTS_BIG_ENDIAN
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 	select SYS_SUPPORTS_MULTITHREADING if EXPERIMENTAL
+	select SYS_SUPPORTS_SMARTMIPS
 	select GENERIC_HARDIRQS_NO__DO_IRQ
 	help
 	  This enables support for the MIPS Technologies Atlas evaluation
@@ -305,6 +306,7 @@
 	select SYS_SUPPORTS_BIG_ENDIAN
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 	select SYS_SUPPORTS_MULTITHREADING
+	select SYS_SUPPORTS_SMARTMIPS
 	help
 	  This enables support for the MIPS Technologies Malta evaluation
 	  board.
@@ -322,6 +324,7 @@
 	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
 	select SYS_SUPPORTS_BIG_ENDIAN
 	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_SUPPORTS_SMARTMIPS
 	help
 	  This enables support for the MIPS Technologies SEAD evaluation
 	  board.
@@ -1641,6 +1644,18 @@
 config CPU_HAS_LLSC
 	bool
 
+config CPU_HAS_SMARTMIPS
+	depends on SYS_SUPPORTS_SMARTMIPS
+	bool "Support for the SmartMIPS ASE"
+	help
+	  SmartMIPS is a extension of the MIPS32 architecture aimed at
+	  increased security at both hardware and software level for
+	  smartcards.  Enabling this option will allow proper use of the
+	  SmartMIPS instructions by Linux applications.  However a kernel with
+	  this option will not work on a MIPS core without SmartMIPS core.  If
+	  you don't know you probably don't have SmartMIPS and should say N
+	  here.
+
 config CPU_HAS_WB
 	bool
 
@@ -1704,6 +1719,9 @@
 config SYS_SUPPORTS_HIGHMEM
 	bool
 
+config SYS_SUPPORTS_SMARTMIPS
+	bool
+
 config ARCH_FLATMEM_ENABLE
 	def_bool y
 	depends on !NUMA
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index c68b5d3..92bca6a 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -103,6 +103,8 @@
 cflags-$(CONFIG_CPU_BIG_ENDIAN)		+= $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' && echo -EB $(undef-all) $(predef-be))
 cflags-$(CONFIG_CPU_LITTLE_ENDIAN)	+= $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL $(undef-all) $(predef-le))
 
+cflags-$(CONFIG_CPU_HAS_SMARTMIPS)	+= $(call cc-option,-msmartmips)
+
 cflags-$(CONFIG_SB1XXX_CORELIS)	+= $(call cc-option,-mno-sched-prolog) \
 				   -fno-omit-frame-pointer
 
diff --git a/arch/mips/cobalt/mtd.c b/arch/mips/cobalt/mtd.c
index 01d8ec7..2b088ef 100644
--- a/arch/mips/cobalt/mtd.c
+++ b/arch/mips/cobalt/mtd.c
@@ -24,7 +24,7 @@
 
 static struct mtd_partition cobalt_mtd_partitions[] = {
 	{
-		.name	= "Colo",
+		.name	= "firmware",
 		.offset	= 0x0,
 		.size	= 0x80000,
 	},
diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig
index 45874d1..4588949 100644
--- a/arch/mips/configs/atlas_defconfig
+++ b/arch/mips/configs/atlas_defconfig
@@ -139,10 +139,12 @@
 CONFIG_SYS_SUPPORTS_MULTITHREADING=y
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_SMARTMIPS is not set
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_SMARTMIPS=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
index b4cdd3e..aa05e29 100644
--- a/arch/mips/configs/bigsur_defconfig
+++ b/arch/mips/configs/bigsur_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:35 2007
+# Tue Feb 20 21:47:22 2007
 #
 CONFIG_MIPS=y
 
@@ -417,6 +417,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -589,6 +590,7 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 # CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -1025,7 +1027,6 @@
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_KGDB is not set
 # CONFIG_SB1XXX_CORELIS is not set
 # CONFIG_RUNTIME_DEBUG is not set
 
diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig
index b05469e..b2594fa 100644
--- a/arch/mips/configs/capcella_defconfig
+++ b/arch/mips/configs/capcella_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:36 2007
+# Tue Feb 20 21:47:22 2007
 #
 CONFIG_MIPS=y
 
@@ -388,6 +388,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
index f88c40f..9090a7a 100644
--- a/arch/mips/configs/cobalt_defconfig
+++ b/arch/mips/configs/cobalt_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Mon Feb 19 14:51:58 2007
+# Tue Feb 20 21:47:24 2007
 #
 CONFIG_MIPS=y
 
@@ -425,7 +425,7 @@
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0
+CONFIG_MTD_PHYSMAP_LEN=0x0
 CONFIG_MTD_PHYSMAP_BANKWIDTH=0
 # CONFIG_MTD_PLATRAM is not set
 
@@ -449,7 +449,6 @@
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -464,6 +463,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -658,6 +658,7 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=y
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
index 1db19f1..4cb8cf4 100644
--- a/arch/mips/configs/db1000_defconfig
+++ b/arch/mips/configs/db1000_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:39 2007
+# Tue Feb 20 21:47:24 2007
 #
 CONFIG_MIPS=y
 
@@ -548,6 +548,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -1103,6 +1104,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
index 529e6eb..d86dedf 100644
--- a/arch/mips/configs/db1100_defconfig
+++ b/arch/mips/configs/db1100_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:39 2007
+# Tue Feb 20 21:47:24 2007
 #
 CONFIG_MIPS=y
 
@@ -537,6 +537,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -1103,6 +1104,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
index 9e86dcd..c24b600 100644
--- a/arch/mips/configs/db1200_defconfig
+++ b/arch/mips/configs/db1200_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:40 2007
+# Tue Feb 20 21:47:25 2007
 #
 CONFIG_MIPS=y
 
@@ -541,6 +541,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -1185,6 +1186,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="mem=48M"
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
index 9c94461..baad2c5 100644
--- a/arch/mips/configs/db1500_defconfig
+++ b/arch/mips/configs/db1500_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:41 2007
+# Tue Feb 20 21:47:26 2007
 #
 CONFIG_MIPS=y
 
@@ -542,7 +542,6 @@
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -557,6 +556,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -715,6 +715,7 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -1145,6 +1146,7 @@
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1402,6 +1404,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
index 5b18d5d..c29fdab 100644
--- a/arch/mips/configs/db1550_defconfig
+++ b/arch/mips/configs/db1550_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:42 2007
+# Tue Feb 20 21:47:27 2007
 #
 CONFIG_MIPS=y
 
@@ -562,6 +562,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -751,6 +752,7 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -1219,6 +1221,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig
index 1210188..f4b316d 100644
--- a/arch/mips/configs/ddb5477_defconfig
+++ b/arch/mips/configs/ddb5477_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:43 2007
+# Tue Feb 20 21:47:28 2007
 #
 CONFIG_MIPS=y
 
@@ -386,6 +386,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -925,6 +926,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="ip=any"
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig
index 2d71745..9c38e5c 100644
--- a/arch/mips/configs/decstation_defconfig
+++ b/arch/mips/configs/decstation_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:44 2007
+# Tue Feb 20 21:47:28 2007
 #
 CONFIG_MIPS=y
 
@@ -398,6 +398,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig
index 0ee2fbb..922af37 100644
--- a/arch/mips/configs/e55_defconfig
+++ b/arch/mips/configs/e55_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:44 2007
+# Tue Feb 20 21:47:28 2007
 #
 CONFIG_MIPS=y
 
@@ -294,6 +294,7 @@
 # Plug and Play support
 #
 # CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
diff --git a/arch/mips/configs/emma2rh_defconfig b/arch/mips/configs/emma2rh_defconfig
index 218fe6e..c0db8f1 100644
--- a/arch/mips/configs/emma2rh_defconfig
+++ b/arch/mips/configs/emma2rh_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:46 2007
+# Tue Feb 20 21:47:29 2007
 #
 CONFIG_MIPS=y
 
@@ -611,7 +611,6 @@
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -626,6 +625,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -1039,6 +1039,7 @@
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
diff --git a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig
index 5ad4870..ce088b3 100644
--- a/arch/mips/configs/ev64120_defconfig
+++ b/arch/mips/configs/ev64120_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:46 2007
+# Tue Feb 20 21:47:30 2007
 #
 CONFIG_MIPS=y
 
@@ -391,6 +391,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -520,6 +521,7 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -914,6 +916,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs rw nfsroot=192.168.1.1:/mnt/disk2/fs.gal ip=192.168.1.211:192.168.1.1:::gt::"
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig
index 5e179fe..82f204d 100644
--- a/arch/mips/configs/excite_defconfig
+++ b/arch/mips/configs/excite_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:47 2007
+# Tue Feb 20 21:47:31 2007
 #
 CONFIG_MIPS=y
 
@@ -451,6 +451,7 @@
 # CONFIG_MTD_NAND_ECC_SMC is not set
 CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_BASLER_EXCITE is not set
 # CONFIG_MTD_NAND_CAFE is not set
 # CONFIG_MTD_NAND_NANDSIM is not set
 
@@ -467,6 +468,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -638,6 +640,7 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -1008,6 +1011,7 @@
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1277,6 +1281,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig
index 864de21..cb81f13 100644
--- a/arch/mips/configs/ip22_defconfig
+++ b/arch/mips/configs/ip22_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:48 2007
+# Tue Feb 20 21:47:32 2007
 #
 CONFIG_MIPS=y
 
@@ -620,6 +620,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index 7b2f5f8..46f6ac4 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:49 2007
+# Tue Feb 20 21:47:32 2007
 #
 CONFIG_MIPS=y
 
@@ -456,6 +456,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -672,6 +673,7 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -1060,6 +1062,7 @@
 CONFIG_LOG_BUF_SHIFT=15
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index 14398e8..d9e5000 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:50 2007
+# Tue Feb 20 21:47:33 2007
 #
 CONFIG_MIPS=y
 
@@ -396,6 +396,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -600,6 +601,7 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=y
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
diff --git a/arch/mips/configs/jaguar-atx_defconfig b/arch/mips/configs/jaguar-atx_defconfig
index b389787..57ef0c4 100644
--- a/arch/mips/configs/jaguar-atx_defconfig
+++ b/arch/mips/configs/jaguar-atx_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:51 2007
+# Tue Feb 20 21:47:33 2007
 #
 CONFIG_MIPS=y
 
@@ -375,6 +375,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -518,9 +519,6 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_MV643XX_ETH=y
-CONFIG_MV643XX_ETH_0=y
-CONFIG_MV643XX_ETH_1=y
-CONFIG_MV643XX_ETH_2=y
 CONFIG_QLA3XXX=m
 
 #
@@ -833,6 +831,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig
index dacf0a6..21d979f 100644
--- a/arch/mips/configs/jazz_defconfig
+++ b/arch/mips/configs/jazz_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:52 2007
+# Tue Feb 20 21:47:33 2007
 #
 CONFIG_MIPS=y
 
@@ -646,6 +646,7 @@
 # Plug and Play support
 #
 # CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig
index 29ed772..9ebb522 100644
--- a/arch/mips/configs/jmr3927_defconfig
+++ b/arch/mips/configs/jmr3927_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:53 2007
+# Tue Feb 20 21:47:34 2007
 #
 CONFIG_MIPS=y
 
@@ -384,6 +384,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -513,6 +514,7 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=y
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig
index a1437b3..b3f767f 100644
--- a/arch/mips/configs/lasat200_defconfig
+++ b/arch/mips/configs/lasat200_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:54 2007
+# Tue Feb 20 21:47:34 2007
 #
 CONFIG_MIPS=y
 
@@ -454,7 +454,6 @@
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -469,6 +468,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -654,6 +654,7 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
index 8d21bb96..a5f379d 100644
--- a/arch/mips/configs/malta_defconfig
+++ b/arch/mips/configs/malta_defconfig
@@ -145,6 +145,7 @@
 CONFIG_MIPS_MT_FPAFF=y
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_SMARTMIPS is not set
 CONFIG_CPU_MIPSR2_IRQ_VI=y
 CONFIG_CPU_MIPSR2_SRS=y
 CONFIG_CPU_HAS_SYNC=y
@@ -152,6 +153,7 @@
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
 CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_SMARTMIPS=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
index 2acb99b..5ff53e1 100644
--- a/arch/mips/configs/mipssim_defconfig
+++ b/arch/mips/configs/mipssim_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:56 2007
+# Tue Feb 20 21:47:35 2007
 #
 CONFIG_MIPS=y
 
@@ -436,6 +436,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -878,7 +879,6 @@
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_KGDB is not set
 # CONFIG_RUNTIME_DEBUG is not set
 # CONFIG_MIPS_UNCACHED is not set
 
diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig
index d52a5a4..750e644 100644
--- a/arch/mips/configs/mpc30x_defconfig
+++ b/arch/mips/configs/mpc30x_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:56 2007
+# Tue Feb 20 21:47:35 2007
 #
 CONFIG_MIPS=y
 
@@ -405,6 +405,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -531,6 +532,7 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -883,6 +885,7 @@
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig
index 746106b..2febd0a 100644
--- a/arch/mips/configs/ocelot_3_defconfig
+++ b/arch/mips/configs/ocelot_3_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:58 2007
+# Tue Feb 20 21:47:35 2007
 #
 CONFIG_MIPS=y
 
@@ -496,6 +496,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -713,9 +714,6 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_MV643XX_ETH=y
-CONFIG_MV643XX_ETH_0=y
-CONFIG_MV643XX_ETH_1=y
-CONFIG_MV643XX_ETH_2=y
 CONFIG_QLA3XXX=m
 # CONFIG_ATL1 is not set
 
diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig
index 4b32b27..b8f4573 100644
--- a/arch/mips/configs/ocelot_c_defconfig
+++ b/arch/mips/configs/ocelot_c_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:58 2007
+# Tue Feb 20 21:47:36 2007
 #
 CONFIG_MIPS=y
 
@@ -393,6 +393,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -523,6 +524,7 @@
 # CONFIG_BNX2 is not set
 # CONFIG_MV643XX_ETH is not set
 CONFIG_QLA3XXX=y
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig
index 674631b..8ade072 100644
--- a/arch/mips/configs/ocelot_defconfig
+++ b/arch/mips/configs/ocelot_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:59 2007
+# Tue Feb 20 21:47:36 2007
 #
 CONFIG_MIPS=y
 
@@ -390,6 +390,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -854,6 +855,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
diff --git a/arch/mips/configs/ocelot_g_defconfig b/arch/mips/configs/ocelot_g_defconfig
index 2600263..d20a221 100644
--- a/arch/mips/configs/ocelot_g_defconfig
+++ b/arch/mips/configs/ocelot_g_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:00 2007
+# Tue Feb 20 21:47:36 2007
 #
 CONFIG_MIPS=y
 
@@ -392,6 +392,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -522,6 +523,7 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=y
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
index 05a33a2..33fcc81 100644
--- a/arch/mips/configs/pb1100_defconfig
+++ b/arch/mips/configs/pb1100_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:01 2007
+# Tue Feb 20 21:47:37 2007
 #
 CONFIG_MIPS=y
 
@@ -549,6 +549,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -1096,6 +1097,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
index 34a6bee..e07c55d 100644
--- a/arch/mips/configs/pb1500_defconfig
+++ b/arch/mips/configs/pb1500_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:02 2007
+# Tue Feb 20 21:47:37 2007
 #
 CONFIG_MIPS=y
 
@@ -541,7 +541,6 @@
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -556,6 +555,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -745,6 +745,7 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -1213,6 +1214,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
index e3bff46..df210dd 100644
--- a/arch/mips/configs/pb1550_defconfig
+++ b/arch/mips/configs/pb1550_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:03 2007
+# Tue Feb 20 21:47:37 2007
 #
 CONFIG_MIPS=y
 
@@ -542,7 +542,6 @@
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -557,6 +556,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -746,6 +746,7 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -1206,6 +1207,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig
index 009b3f8..106a164 100644
--- a/arch/mips/configs/pnx8550-jbs_defconfig
+++ b/arch/mips/configs/pnx8550-jbs_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:04 2007
+# Tue Feb 20 21:47:38 2007
 #
 CONFIG_MIPS=y
 
@@ -389,6 +389,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -962,6 +963,7 @@
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1229,6 +1231,7 @@
 CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp"
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_KGDB is not set
+CONFIG_SYS_SUPPORTS_KGDB=y
 # CONFIG_RUNTIME_DEBUG is not set
 # CONFIG_MIPS_UNCACHED is not set
 
diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig
index 5bd377b..8caa2cd 100644
--- a/arch/mips/configs/pnx8550-stb810_defconfig
+++ b/arch/mips/configs/pnx8550-stb810_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:04 2007
+# Tue Feb 20 21:47:38 2007
 #
 CONFIG_MIPS=y
 
@@ -386,6 +386,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -952,6 +953,7 @@
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1219,6 +1221,7 @@
 CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp"
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_KGDB is not set
+CONFIG_SYS_SUPPORTS_KGDB=y
 # CONFIG_RUNTIME_DEBUG is not set
 # CONFIG_MIPS_UNCACHED is not set
 
diff --git a/arch/mips/configs/pnx8550-v2pci_defconfig b/arch/mips/configs/pnx8550-v2pci_defconfig
index cc69470..43f1bec 100644
--- a/arch/mips/configs/pnx8550-v2pci_defconfig
+++ b/arch/mips/configs/pnx8550-v2pci_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:06 2007
+# Tue Feb 20 21:47:39 2007
 #
 CONFIG_MIPS=y
 
@@ -474,6 +474,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -987,6 +988,7 @@
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
@@ -1209,6 +1211,7 @@
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1466,6 +1469,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig
index c18c5e7..f68396d 100644
--- a/arch/mips/configs/qemu_defconfig
+++ b/arch/mips/configs/qemu_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:06 2007
+# Tue Feb 20 21:47:39 2007
 #
 CONFIG_MIPS=y
 
@@ -348,6 +348,7 @@
 # Plug and Play support
 #
 # CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig
index 678f232..a6a824f 100644
--- a/arch/mips/configs/rbhma4500_defconfig
+++ b/arch/mips/configs/rbhma4500_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:07 2007
+# Tue Feb 20 21:47:39 2007
 #
 CONFIG_MIPS=y
 
@@ -560,7 +560,6 @@
 # NAND Flash Device Drivers
 #
 # CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
 
 #
 # OneNAND Flash Device Drivers
@@ -576,6 +575,7 @@
 # Plug and Play support
 #
 # CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -1191,6 +1191,7 @@
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1462,6 +1463,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 
 #
 # Security options
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index 0417e86..bee3702 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:09 2007
+# Tue Feb 20 21:47:40 2007
 #
 CONFIG_MIPS=y
 
@@ -661,6 +661,7 @@
 # Plug and Play support
 #
 # CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -1397,6 +1398,7 @@
 CONFIG_USB_RIO500=m
 CONFIG_USB_LEGOTOWER=m
 CONFIG_USB_LCD=m
+# CONFIG_USB_BERRY_CHARGE is not set
 CONFIG_USB_LED=m
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 CONFIG_USB_CYTHERM=m
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
index 533df6f..3c891ed 100644
--- a/arch/mips/configs/sb1250-swarm_defconfig
+++ b/arch/mips/configs/sb1250-swarm_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:09 2007
+# Tue Feb 20 21:47:40 2007
 #
 CONFIG_MIPS=y
 
@@ -424,6 +424,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -581,6 +582,7 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -945,6 +947,7 @@
 CONFIG_LOG_BUF_SHIFT=15
 CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE=""
+CONFIG_SYS_SUPPORTS_KGDB=y
 # CONFIG_SB1XXX_CORELIS is not set
 
 #
diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig
index 38816fe..e31d964 100644
--- a/arch/mips/configs/sead_defconfig
+++ b/arch/mips/configs/sead_defconfig
@@ -129,10 +129,12 @@
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_SMARTMIPS is not set
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_SMARTMIPS=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig
index c2f7c8c..5771c1a 100644
--- a/arch/mips/configs/tb0226_defconfig
+++ b/arch/mips/configs/tb0226_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:11 2007
+# Tue Feb 20 21:47:41 2007
 #
 CONFIG_MIPS=y
 
@@ -396,6 +396,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -920,6 +921,7 @@
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
diff --git a/arch/mips/configs/tb0229_defconfig b/arch/mips/configs/tb0229_defconfig
index 33b7880..a8eb4b1 100644
--- a/arch/mips/configs/tb0229_defconfig
+++ b/arch/mips/configs/tb0229_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:12 2007
+# Tue Feb 20 21:47:41 2007
 #
 CONFIG_MIPS=y
 
@@ -397,6 +397,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -530,6 +531,7 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 CONFIG_QLA3XXX=m
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -819,6 +821,7 @@
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig
index d180586..69b8730 100644
--- a/arch/mips/configs/tb0287_defconfig
+++ b/arch/mips/configs/tb0287_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:13 2007
+# Tue Feb 20 21:47:41 2007
 #
 CONFIG_MIPS=y
 
@@ -409,6 +409,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -675,6 +676,7 @@
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
 # CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -1016,6 +1018,7 @@
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig
index 570f0c1..2abbd68 100644
--- a/arch/mips/configs/workpad_defconfig
+++ b/arch/mips/configs/workpad_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:13 2007
+# Tue Feb 20 21:47:42 2007
 #
 CONFIG_MIPS=y
 
@@ -396,6 +396,7 @@
 # Plug and Play support
 #
 # CONFIG_PNP is not set
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig
index 08f3190..44b6b7c 100644
--- a/arch/mips/configs/wrppmc_defconfig
+++ b/arch/mips/configs/wrppmc_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:14 2007
+# Tue Feb 20 21:47:42 2007
 #
 CONFIG_MIPS=y
 
@@ -400,6 +400,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
index aa69fee..f24e1c6 100644
--- a/arch/mips/configs/yosemite_defconfig
+++ b/arch/mips/configs/yosemite_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:28:15 2007
+# Tue Feb 20 21:47:42 2007
 #
 CONFIG_MIPS=y
 
@@ -381,6 +381,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -841,6 +842,7 @@
 CONFIG_CMDLINE=""
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_KGDB is not set
+CONFIG_SYS_SUPPORTS_KGDB=y
 # CONFIG_RUNTIME_DEBUG is not set
 
 #
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index 6c2a233..8cb8f59 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.20
-# Sun Feb 18 21:27:34 2007
+# Tue Feb 20 21:47:14 2007
 #
 CONFIG_MIPS=y
 
@@ -620,6 +620,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index c0b089d..222de46 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -64,6 +64,9 @@
 	offset("#define PT_R31    ", struct pt_regs, regs[31]);
 	offset("#define PT_LO     ", struct pt_regs, lo);
 	offset("#define PT_HI     ", struct pt_regs, hi);
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+	offset("#define PT_ACX    ", struct pt_regs, acx);
+#endif
 	offset("#define PT_EPC    ", struct pt_regs, cp0_epc);
 	offset("#define PT_BVADDR ", struct pt_regs, cp0_badvaddr);
 	offset("#define PT_STATUS ", struct pt_regs, cp0_status);
@@ -246,6 +249,7 @@
 	text("/* Linux sigcontext offsets. */");
 	offset("#define SC_REGS       ", struct sigcontext, sc_regs);
 	offset("#define SC_FPREGS     ", struct sigcontext, sc_fpregs);
+	offset("#define SC_ACX        ", struct sigcontext, sc_acx);
 	offset("#define SC_MDHI       ", struct sigcontext, sc_mdhi);
 	offset("#define SC_MDLO       ", struct sigcontext, sc_mdlo);
 	offset("#define SC_PC         ", struct sigcontext, sc_pc);
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 258d74f..201ae19 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -236,6 +236,11 @@
 		case MMLO:
 			tmp = regs->lo;
 			break;
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+		case ACX:
+			tmp = regs->acx;
+			break;
+#endif
 		case FPC_CSR:
 			tmp = child->thread.fpu.fcr31;
 			break;
@@ -362,6 +367,11 @@
 		case MMLO:
 			regs->lo = data;
 			break;
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+		case ACX:
+			regs->acx = data;
+			break;
+#endif
 		case FPC_CSR:
 			child->thread.fpu.fcr31 = data;
 			break;
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index adbfb95..f091786 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -89,6 +89,9 @@
 	for (i = 1; i < 32; i++)
 		err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
 
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+	err |= __put_user(regs->acx, &sc->sc_acx);
+#endif
 	err |= __put_user(regs->hi, &sc->sc_mdhi);
 	err |= __put_user(regs->lo, &sc->sc_mdlo);
 	if (cpu_has_dsp) {
@@ -132,6 +135,10 @@
 	current_thread_info()->restart_block.fn = do_no_restart_syscall;
 
 	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
+
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+	err |= __get_user(regs->acx, &sc->sc_acx);
+#endif
 	err |= __get_user(regs->hi, &sc->sc_mdhi);
 	err |= __get_user(regs->lo, &sc->sc_mdlo);
 	if (cpu_has_dsp) {
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 0555fc5..c46e479 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -51,31 +51,14 @@
 EXPORT_SYMBOL(phys_cpu_present_map);
 EXPORT_SYMBOL(cpu_online_map);
 
+/* This happens early in bootup, can't really do it better */
 static void smp_tune_scheduling (void)
 {
 	struct cache_desc *cd = &current_cpu_data.scache;
-	unsigned long cachesize;       /* kB   */
-	unsigned long cpu_khz;
+	unsigned long cachesize = cd->linesz * cd->sets * cd->ways;
 
-	/*
-	 * Crude estimate until we actually meassure ...
-	 */
-	cpu_khz = loops_per_jiffy * 2 * HZ / 1000;
-
-	/*
-	 * Rough estimation for SMP scheduling, this is the number of
-	 * cycles it takes for a fully memory-limited process to flush
-	 * the SMP-local cache.
-	 *
-	 * (For a P5 this pretty much means we will choose another idle
-	 *  CPU almost always at wakeup time (this is due to the small
-	 *  L1 cache), on PIIs it's around 50-100 usecs, depending on
-	 *  the cache size)
-	 */
-	if (!cpu_khz)
-		return;
-
-	cachesize = cd->linesz * cd->sets * cd->ways;
+	if (cachesize > max_cache_size)
+		max_cache_size = cachesize;
 }
 
 extern void __init calibrate_delay(void);
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 2aa208b..18f56a9 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -229,6 +229,9 @@
 			printk("\n");
 	}
 
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+	printk("Acx    : %0*lx\n", field, regs->acx);
+#endif
 	printk("Hi    : %0*lx\n", field, regs->hi);
 	printk("Lo    : %0*lx\n", field, regs->lo);
 
diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c
index fc2c96f..cea7d0e 100644
--- a/arch/mips/mm/ioremap.c
+++ b/arch/mips/mm/ioremap.c
@@ -6,13 +6,98 @@
  * (C) Copyright 1995 1996 Linus Torvalds
  * (C) Copyright 2001, 2002 Ralf Baechle
  */
-#include <linux/mm.h>
 #include <linux/module.h>
 #include <asm/addrspace.h>
 #include <asm/byteorder.h>
 
 #include <linux/vmalloc.h>
-#include <linux/io.h>
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/tlbflush.h>
+
+static inline void remap_area_pte(pte_t * pte, unsigned long address,
+	phys_t size, phys_t phys_addr, unsigned long flags)
+{
+	phys_t end;
+	unsigned long pfn;
+	pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE
+	                           | __WRITEABLE | flags);
+
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end > PMD_SIZE)
+		end = PMD_SIZE;
+	if (address >= end)
+		BUG();
+	pfn = phys_addr >> PAGE_SHIFT;
+	do {
+		if (!pte_none(*pte)) {
+			printk("remap_area_pte: page already exists\n");
+			BUG();
+		}
+		set_pte(pte, pfn_pte(pfn, pgprot));
+		address += PAGE_SIZE;
+		pfn++;
+		pte++;
+	} while (address && (address < end));
+}
+
+static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
+	phys_t size, phys_t phys_addr, unsigned long flags)
+{
+	phys_t end;
+
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+	phys_addr -= address;
+	if (address >= end)
+		BUG();
+	do {
+		pte_t * pte = pte_alloc_kernel(pmd, address);
+		if (!pte)
+			return -ENOMEM;
+		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
+		address = (address + PMD_SIZE) & PMD_MASK;
+		pmd++;
+	} while (address && (address < end));
+	return 0;
+}
+
+static int remap_area_pages(unsigned long address, phys_t phys_addr,
+	phys_t size, unsigned long flags)
+{
+	int error;
+	pgd_t * dir;
+	unsigned long end = address + size;
+
+	phys_addr -= address;
+	dir = pgd_offset(&init_mm, address);
+	flush_cache_all();
+	if (address >= end)
+		BUG();
+	do {
+		pud_t *pud;
+		pmd_t *pmd;
+
+		error = -ENOMEM;
+		pud = pud_alloc(&init_mm, dir, address);
+		if (!pud)
+			break;
+		pmd = pmd_alloc(&init_mm, pud, address);
+		if (!pmd)
+			break;
+		if (remap_area_pmd(pmd, address, end - address,
+					 phys_addr + address, flags))
+			break;
+		error = 0;
+		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+		dir++;
+	} while (address && (address < end));
+	flush_tlb_all();
+	return error;
+}
 
 /*
  * Generic mapping function (not visible outside):
@@ -36,7 +121,6 @@
 	unsigned long offset;
 	phys_t last_addr;
 	void * addr;
-	pgprot_t pgprot;
 
 	phys_addr = fixup_bigphys_addr(phys_addr, size);
 
@@ -68,9 +152,6 @@
 				return NULL;
 	}
 
-	pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE
-			  | __WRITEABLE | flags);
-
 	/*
 	 * Mappings have to be page-aligned
 	 */
@@ -85,8 +166,7 @@
 	if (!area)
 		return NULL;
 	addr = area->addr;
-	if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
-			       phys_addr, pgprot)) {
+	if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
 		vunmap(addr);
 		return NULL;
 	}
diff --git a/arch/mips/momentum/jaguar_atx/platform.c b/arch/mips/momentum/jaguar_atx/platform.c
index c78ba30..3df36ed 100644
--- a/arch/mips/momentum/jaguar_atx/platform.c
+++ b/arch/mips/momentum/jaguar_atx/platform.c
@@ -200,7 +200,7 @@
 	int ret;
 
 	get_mac(mac);
-	eth_mac_add(eth1_mac_addr, mac, 0);
+	eth_mac_add(eth0_mac_addr, mac, 0);
 	eth_mac_add(eth1_mac_addr, mac, 1);
 	eth_mac_add(eth2_mac_addr, mac, 2);
 	ret = platform_add_devices(mv643xx_eth_pd_devs,
diff --git a/arch/mips/momentum/ocelot_3/platform.c b/arch/mips/momentum/ocelot_3/platform.c
index 0ab8d23..024aef2 100644
--- a/arch/mips/momentum/ocelot_3/platform.c
+++ b/arch/mips/momentum/ocelot_3/platform.c
@@ -200,7 +200,7 @@
 	int ret;
 
 	get_mac(mac);
-	eth_mac_add(eth1_mac_addr, mac, 0);
+	eth_mac_add(eth0_mac_addr, mac, 0);
 	eth_mac_add(eth1_mac_addr, mac, 1);
 	eth_mac_add(eth2_mac_addr, mac, 2);
 	ret = platform_add_devices(mv643xx_eth_pd_devs,
diff --git a/arch/mips/momentum/ocelot_c/platform.c b/arch/mips/momentum/ocelot_c/platform.c
index 8e381d4..fac8b24 100644
--- a/arch/mips/momentum/ocelot_c/platform.c
+++ b/arch/mips/momentum/ocelot_c/platform.c
@@ -174,7 +174,7 @@
 	int ret;
 
 	get_mac(mac);
-	eth_mac_add(eth1_mac_addr, mac, 0);
+	eth_mac_add(eth0_mac_addr, mac, 0);
 	eth_mac_add(eth1_mac_addr, mac, 1);
 	ret = platform_add_devices(mv643xx_eth_pd_devs,
 			ARRAY_SIZE(mv643xx_eth_pd_devs));
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 0f44a6a..59eef40 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Sun Feb 11 23:47:40 2007
+# Linux kernel version: 2.6.21-rc1
+# Mon Feb 26 10:45:21 2007
 #
 CONFIG_SPARC=y
 CONFIG_SPARC64=y
@@ -41,6 +41,7 @@
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
@@ -322,6 +323,7 @@
 #
 # Plug and Play support
 #
+# CONFIG_PNPACPI is not set
 
 #
 # Block devices
@@ -787,6 +789,7 @@
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PASEMI is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_I2C_SIS5595 is not set
@@ -833,6 +836,7 @@
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
@@ -874,6 +878,11 @@
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -887,16 +896,22 @@
 #
 # Graphics support
 #
-# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
 CONFIG_FB_DDC=y
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_TILEBLITTING=y
+
+#
+# Frambuffer hardware drivers
+#
 # CONFIG_FB_CIRRUS is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_ASILIANT is not set
@@ -908,9 +923,11 @@
 # CONFIG_FB_MATROX is not set
 CONFIG_FB_RADEON=y
 CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_BACKLIGHT is not set
 # CONFIG_FB_RADEON_DEBUG is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
@@ -947,7 +964,6 @@
 # CONFIG_LOGO_LINUX_VGA16 is not set
 # CONFIG_LOGO_LINUX_CLUT224 is not set
 CONFIG_LOGO_SUN_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -1192,6 +1208,7 @@
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1445,9 +1462,11 @@
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
 CONFIG_LOG_BUF_SHIFT=18
 CONFIG_DETECT_SOFTLOCKUP=y
 CONFIG_SCHEDSTATS=y
+# CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
@@ -1465,6 +1484,7 @@
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_DCFLUSH is not set
 # CONFIG_STACK_DEBUG is not set
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index b5ff3ee..c443db1 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -109,6 +109,7 @@
 	return ent;
 }
 
+#ifdef CONFIG_PCI_MSI
 static void virt_irq_free(unsigned int virt_irq)
 {
 	unsigned int real_irq;
@@ -121,6 +122,7 @@
 
 	__bucket(real_irq)->virt_irq = 0;
 }
+#endif
 
 static unsigned int virt_to_real_irq(unsigned char virt_irq)
 {
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index 6b740eb..6fedfb9 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -668,7 +668,7 @@
 
 void arch_teardown_msi_irq(unsigned int virt_irq)
 {
-	struct msi_desc *entry = get_irq_data(virt_irq);
+	struct msi_desc *entry = get_irq_msi(virt_irq);
 	struct pci_dev *pdev = entry->dev;
 	struct pcidev_cookie *pcp = pdev->sysdata;
 	struct pci_pbm_info *pbm = pcp->pbm;
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 1417e5c..d596812 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -840,48 +840,6 @@
 		class_device_unregister(class_dev);
 }
 
-int class_device_rename(struct class_device *class_dev, char *new_name)
-{
-	int error = 0;
-	char *old_class_name = NULL, *new_class_name = NULL;
-
-	class_dev = class_device_get(class_dev);
-	if (!class_dev)
-		return -EINVAL;
-
-	pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev->class_id,
-		 new_name);
-
-#ifdef CONFIG_SYSFS_DEPRECATED
-	if (class_dev->dev)
-		old_class_name = make_class_name(class_dev->class->name,
-						 &class_dev->kobj);
-#endif
-
-	strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN);
-
-	error = kobject_rename(&class_dev->kobj, new_name);
-
-#ifdef CONFIG_SYSFS_DEPRECATED
-	if (class_dev->dev) {
-		new_class_name = make_class_name(class_dev->class->name,
-						 &class_dev->kobj);
-		if (new_class_name)
-			sysfs_create_link(&class_dev->dev->kobj,
-					  &class_dev->kobj, new_class_name);
-		if (old_class_name)
-			sysfs_remove_link(&class_dev->dev->kobj,
-						old_class_name);
-	}
-#endif
-	class_device_put(class_dev);
-
-	kfree(old_class_name);
-	kfree(new_class_name);
-
-	return error;
-}
-
 struct class_device * class_device_get(struct class_device *class_dev)
 {
 	if (class_dev)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index d04fd33..cf2a398 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -637,12 +637,41 @@
 					     BUS_NOTIFY_DEL_DEVICE, dev);
 	device_remove_groups(dev);
  GroupError:
- 	device_remove_attrs(dev);
+	device_remove_attrs(dev);
  AttrsError:
 	if (dev->devt_attr) {
 		device_remove_file(dev, dev->devt_attr);
 		kfree(dev->devt_attr);
 	}
+
+	if (dev->class) {
+		sysfs_remove_link(&dev->kobj, "subsystem");
+		/* If this is not a "fake" compatible device, remove the
+		 * symlink from the class to the device. */
+		if (dev->kobj.parent != &dev->class->subsys.kset.kobj)
+			sysfs_remove_link(&dev->class->subsys.kset.kobj,
+					  dev->bus_id);
+#ifdef CONFIG_SYSFS_DEPRECATED
+		if (parent) {
+			char *class_name = make_class_name(dev->class->name,
+							   &dev->kobj);
+			if (class_name)
+				sysfs_remove_link(&dev->parent->kobj,
+						  class_name);
+			kfree(class_name);
+			sysfs_remove_link(&dev->kobj, "device");
+		}
+#endif
+
+		down(&dev->class->sem);
+		/* notify any interfaces that the device is now gone */
+		list_for_each_entry(class_intf, &dev->class->interfaces, node)
+			if (class_intf->remove_dev)
+				class_intf->remove_dev(dev, class_intf);
+		/* remove the device from the class list */
+		list_del_init(&dev->node);
+		up(&dev->class->sem);
+	}
  ueventattrError:
 	device_remove_file(dev, &dev->uevent_attr);
  attrError:
diff --git a/drivers/char/agp/Makefile b/drivers/char/agp/Makefile
index a0d04a2..627f542 100644
--- a/drivers/char/agp/Makefile
+++ b/drivers/char/agp/Makefile
@@ -1,7 +1,8 @@
 agpgart-y := backend.o frontend.o generic.o isoch.o
 
+agpgart-$(CONFIG_COMPAT)	+= compat_ioctl.o
+
 obj-$(CONFIG_AGP)		+= agpgart.o
-obj-$(CONFIG_COMPAT)		+= compat_ioctl.o
 obj-$(CONFIG_AGP_ALI)		+= ali-agp.o
 obj-$(CONFIG_AGP_ATI)		+= ati-agp.o
 obj-$(CONFIG_AGP_AMD)		+= amd-k7-agp.o
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index 9bd68d9..fdbca25 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -93,12 +93,12 @@
 
 struct agp_bridge_driver {
 	struct module *owner;
-	void *aperture_sizes;
+	const void *aperture_sizes;
 	int num_aperture_sizes;
 	enum aper_size_type size_type;
 	int cant_use_aperture;
 	int needs_scratch_page;
-	struct gatt_mask *masks;
+	const struct gatt_mask *masks;
 	int (*fetch_size)(void);
 	int (*configure)(void);
 	void (*agp_enable)(struct agp_bridge_data *, u32);
@@ -119,7 +119,7 @@
 
 struct agp_bridge_data {
 	const struct agp_version *version;
-	struct agp_bridge_driver *driver;
+	const struct agp_bridge_driver *driver;
 	struct vm_operations_struct *vm_ops;
 	void *previous_size;
 	void *current_size;
@@ -290,7 +290,7 @@
 
 /* aperture sizes have been standardised since v3 */
 #define AGP_GENERIC_SIZES_ENTRIES 11
-extern struct aper_size_info_16 agp3_generic_sizes[];
+extern const struct aper_size_info_16 agp3_generic_sizes[];
 
 #define virt_to_gart(x) (phys_to_gart(virt_to_phys(x)))
 #define gart_to_virt(x) (phys_to_virt(gart_to_phys(x)))
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
index 98177a9..5b684fd 100644
--- a/drivers/char/agp/ali-agp.c
+++ b/drivers/char/agp/ali-agp.c
@@ -182,7 +182,7 @@
 
 /* Setup function */
 
-static struct aper_size_info_32 ali_generic_sizes[7] =
+static const struct aper_size_info_32 ali_generic_sizes[7] =
 {
 	{256, 65536, 6, 10},
 	{128, 32768, 5, 9},
@@ -193,7 +193,7 @@
 	{4, 1024, 0, 3}
 };
 
-static struct agp_bridge_driver ali_generic_bridge = {
+static const struct agp_bridge_driver ali_generic_bridge = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= ali_generic_sizes,
 	.size_type		= U32_APER_SIZE,
@@ -217,7 +217,7 @@
 	.agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver ali_m1541_bridge = {
+static const struct agp_bridge_driver ali_m1541_bridge = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= ali_generic_sizes,
 	.size_type		= U32_APER_SIZE,
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index 3d8d448..e6c534e 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -344,7 +344,7 @@
 	return 0;
 }
 
-static struct aper_size_info_lvl2 amd_irongate_sizes[7] =
+static const struct aper_size_info_lvl2 amd_irongate_sizes[7] =
 {
 	{2048, 524288, 0x0000000c},
 	{1024, 262144, 0x0000000a},
@@ -355,12 +355,12 @@
 	{32, 8192, 0x00000000}
 };
 
-static struct gatt_mask amd_irongate_masks[] =
+static const struct gatt_mask amd_irongate_masks[] =
 {
 	{.mask = 1, .type = 0}
 };
 
-static struct agp_bridge_driver amd_irongate_driver = {
+static const struct agp_bridge_driver amd_irongate_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= amd_irongate_sizes,
 	.size_type		= LVL2_APER_SIZE,
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 636d984..4857204 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -192,7 +192,7 @@
 }
 
 
-static struct aper_size_info_32 amd_8151_sizes[7] =
+static const struct aper_size_info_32 amd_8151_sizes[7] =
 {
 	{2048, 524288, 9, 0x00000000 },	/* 0 0 0 0 0 0 */
 	{1024, 262144, 8, 0x00000400 },	/* 1 0 0 0 0 0 */
@@ -232,7 +232,7 @@
 }
 
 
-static struct agp_bridge_driver amd_8151_driver = {
+static const struct agp_bridge_driver amd_8151_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= amd_8151_sizes,
 	.size_type		= U32_APER_SIZE,
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index 77c9ad6..780e59e 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -24,7 +24,7 @@
 #define ATI_GART_CACHE_ENTRY_CNTRL	0x10
 
 
-static struct aper_size_info_lvl2 ati_generic_sizes[7] =
+static const struct aper_size_info_lvl2 ati_generic_sizes[7] =
 {
 	{2048, 524288, 0x0000000c},
 	{1024, 262144, 0x0000000a},
@@ -410,7 +410,7 @@
 	return 0;
 }
 
-static struct agp_bridge_driver ati_generic_bridge = {
+static const struct agp_bridge_driver ati_generic_bridge = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= ati_generic_sizes,
 	.size_type		= LVL2_APER_SIZE,
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
index 658cb1a..df8da72 100644
--- a/drivers/char/agp/efficeon-agp.c
+++ b/drivers/char/agp/efficeon-agp.c
@@ -59,7 +59,7 @@
 	unsigned long l1_table[EFFICEON_L1_SIZE];
 } efficeon_private;
 
-static struct gatt_mask efficeon_generic_masks[] =
+static const struct gatt_mask efficeon_generic_masks[] =
 {
 	{.mask = 0x00000001, .type = 0}
 };
@@ -70,7 +70,7 @@
 	return addr | 0x00000001;
 }
 
-static struct aper_size_info_lvl2 efficeon_generic_sizes[4] =
+static const struct aper_size_info_lvl2 efficeon_generic_sizes[4] =
 {
 	{256, 65536, 0},
 	{128, 32768, 32},
@@ -309,7 +309,7 @@
 }
 
 
-static struct agp_bridge_driver efficeon_driver = {
+static const struct agp_bridge_driver efficeon_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= efficeon_generic_sizes,
 	.size_type		= LVL2_APER_SIZE,
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 7923337..f902d71 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -1340,7 +1340,7 @@
 }
 EXPORT_SYMBOL(agp3_generic_cleanup);
 
-struct aper_size_info_16 agp3_generic_sizes[AGP_GENERIC_SIZES_ENTRIES] =
+const struct aper_size_info_16 agp3_generic_sizes[AGP_GENERIC_SIZES_ENTRIES] =
 {
 	{4096, 1048576, 10,0x000},
 	{2048,  524288, 9, 0x800},
diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c
index 847deab..79f7c01 100644
--- a/drivers/char/agp/hp-agp.c
+++ b/drivers/char/agp/hp-agp.c
@@ -419,7 +419,7 @@
 	agp_device_command(command, (mode & AGP8X_MODE) != 0);
 }
 
-struct agp_bridge_driver hp_zx1_driver = {
+struct const agp_bridge_driver hp_zx1_driver = {
 	.owner			= THIS_MODULE,
 	.size_type		= FIXED_APER_SIZE,
 	.configure		= hp_zx1_configure,
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
index 3e76186..1cde376 100644
--- a/drivers/char/agp/i460-agp.c
+++ b/drivers/char/agp/i460-agp.c
@@ -78,7 +78,7 @@
 	} *lp_desc;
 } i460;
 
-static struct aper_size_info_8 i460_sizes[3] =
+static const struct aper_size_info_8 i460_sizes[3] =
 {
 	/*
 	 * The 32GB aperture is only available with a 4M GART page size.  Due to the
@@ -550,7 +550,7 @@
 		| (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xfffff000) >> 12);
 }
 
-struct agp_bridge_driver intel_i460_driver = {
+struct const agp_bridge_driver intel_i460_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= i460_sizes,
 	.size_type		= U8_APER_SIZE,
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 06b0bb6..e542a62 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -63,7 +63,7 @@
 #define INTEL_I7505_AGPCTRL	0x70
 #define INTEL_I7505_MCHCFG	0x50
 
-static struct aper_size_info_fixed intel_i810_sizes[] =
+static const struct aper_size_info_fixed intel_i810_sizes[] =
 {
 	{64, 16384, 4},
 	/* The 32M mode still requires a 64k gatt */
@@ -1365,18 +1365,18 @@
 }
 
 /* Setup function */
-static struct gatt_mask intel_generic_masks[] =
+static const struct gatt_mask intel_generic_masks[] =
 {
 	{.mask = 0x00000017, .type = 0}
 };
 
-static struct aper_size_info_8 intel_815_sizes[2] =
+static const struct aper_size_info_8 intel_815_sizes[2] =
 {
 	{64, 16384, 4, 0},
 	{32, 8192, 3, 8},
 };
 
-static struct aper_size_info_8 intel_8xx_sizes[7] =
+static const struct aper_size_info_8 intel_8xx_sizes[7] =
 {
 	{256, 65536, 6, 0},
 	{128, 32768, 5, 32},
@@ -1387,7 +1387,7 @@
 	{4, 1024, 0, 63}
 };
 
-static struct aper_size_info_16 intel_generic_sizes[7] =
+static const struct aper_size_info_16 intel_generic_sizes[7] =
 {
 	{256, 65536, 6, 0},
 	{128, 32768, 5, 32},
@@ -1398,7 +1398,7 @@
 	{4, 1024, 0, 63}
 };
 
-static struct aper_size_info_8 intel_830mp_sizes[4] =
+static const struct aper_size_info_8 intel_830mp_sizes[4] =
 {
 	{256, 65536, 6, 0},
 	{128, 32768, 5, 32},
@@ -1406,7 +1406,7 @@
 	{32, 8192, 3, 56}
 };
 
-static struct agp_bridge_driver intel_generic_driver = {
+static const struct agp_bridge_driver intel_generic_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= intel_generic_sizes,
 	.size_type		= U16_APER_SIZE,
@@ -1430,7 +1430,7 @@
 	.agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_810_driver = {
+static const struct agp_bridge_driver intel_810_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= intel_i810_sizes,
 	.size_type		= FIXED_APER_SIZE,
@@ -1455,7 +1455,7 @@
 	.agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_815_driver = {
+static const struct agp_bridge_driver intel_815_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= intel_815_sizes,
 	.size_type		= U8_APER_SIZE,
@@ -1479,7 +1479,7 @@
 	.agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_830_driver = {
+static const struct agp_bridge_driver intel_830_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= intel_i830_sizes,
 	.size_type		= FIXED_APER_SIZE,
@@ -1504,7 +1504,7 @@
 	.agp_type_to_mask_type  = intel_i830_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_820_driver = {
+static const struct agp_bridge_driver intel_820_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= intel_8xx_sizes,
 	.size_type		= U8_APER_SIZE,
@@ -1528,7 +1528,7 @@
 	.agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_830mp_driver = {
+static const struct agp_bridge_driver intel_830mp_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= intel_830mp_sizes,
 	.size_type		= U8_APER_SIZE,
@@ -1552,7 +1552,7 @@
 	.agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_840_driver = {
+static const struct agp_bridge_driver intel_840_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= intel_8xx_sizes,
 	.size_type		= U8_APER_SIZE,
@@ -1576,7 +1576,7 @@
 	.agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_845_driver = {
+static const struct agp_bridge_driver intel_845_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= intel_8xx_sizes,
 	.size_type		= U8_APER_SIZE,
@@ -1600,7 +1600,7 @@
 	.agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_850_driver = {
+static const struct agp_bridge_driver intel_850_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= intel_8xx_sizes,
 	.size_type		= U8_APER_SIZE,
@@ -1624,7 +1624,7 @@
 	.agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_860_driver = {
+static const struct agp_bridge_driver intel_860_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= intel_8xx_sizes,
 	.size_type		= U8_APER_SIZE,
@@ -1648,7 +1648,7 @@
 	.agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_915_driver = {
+static const struct agp_bridge_driver intel_915_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= intel_i830_sizes,
 	.size_type		= FIXED_APER_SIZE,
@@ -1673,7 +1673,7 @@
 	.agp_type_to_mask_type  = intel_i830_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_i965_driver = {
+static const struct agp_bridge_driver intel_i965_driver = {
        .owner                  = THIS_MODULE,
        .aperture_sizes         = intel_i830_sizes,
        .size_type              = FIXED_APER_SIZE,
@@ -1698,7 +1698,7 @@
        .agp_type_to_mask_type  = intel_i830_type_to_mask_type,
 };
 
-static struct agp_bridge_driver intel_7505_driver = {
+static const struct agp_bridge_driver intel_7505_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= intel_8xx_sizes,
 	.size_type		= U8_APER_SIZE,
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
index 2563286..0c9dab5 100644
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -272,7 +272,7 @@
 }
 
 
-static struct aper_size_info_8 nvidia_generic_sizes[5] =
+static const struct aper_size_info_8 nvidia_generic_sizes[5] =
 {
 	{512, 131072, 7, 0},
 	{256, 65536, 6, 8},
@@ -283,13 +283,13 @@
 };
 
 
-static struct gatt_mask nvidia_generic_masks[] =
+static const struct gatt_mask nvidia_generic_masks[] =
 {
 	{ .mask = 1, .type = 0}
 };
 
 
-static struct agp_bridge_driver nvidia_driver = {
+static const struct agp_bridge_driver nvidia_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= nvidia_generic_sizes,
 	.size_type		= U8_APER_SIZE,
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c
index b7b4590..36d07e3 100644
--- a/drivers/char/agp/parisc-agp.c
+++ b/drivers/char/agp/parisc-agp.c
@@ -210,7 +210,7 @@
 	agp_device_command(command, (mode & AGP8X_MODE) != 0);
 }
 
-struct agp_bridge_driver parisc_agp_driver = {
+struct const agp_bridge_driver parisc_agp_driver = {
 	.owner			= THIS_MODULE,
 	.size_type		= FIXED_APER_SIZE,
 	.configure		= parisc_agp_configure,
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c
index 92d1dc4..e12773a 100644
--- a/drivers/char/agp/sgi-agp.c
+++ b/drivers/char/agp/sgi-agp.c
@@ -247,7 +247,7 @@
 	return bridge;
 }
 
-struct agp_bridge_driver sgi_tioca_driver = {
+struct const agp_bridge_driver sgi_tioca_driver = {
 	.owner = THIS_MODULE,
 	.size_type = U16_APER_SIZE,
 	.configure = sgi_tioca_configure,
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
index 60342b7..125f428 100644
--- a/drivers/char/agp/sis-agp.c
+++ b/drivers/char/agp/sis-agp.c
@@ -108,7 +108,7 @@
 	}
 }
 
-static struct aper_size_info_8 sis_generic_sizes[7] =
+static const struct aper_size_info_8 sis_generic_sizes[7] =
 {
 	{256, 65536, 6, 99},
 	{128, 32768, 5, 83},
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index 9f5ae77..55212a3 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -385,12 +385,12 @@
 	return 0;
 }
 
-static struct gatt_mask serverworks_masks[] =
+static const struct gatt_mask serverworks_masks[] =
 {
 	{.mask = 1, .type = 0}
 };
 
-static struct aper_size_info_lvl2 serverworks_sizes[7] =
+static const struct aper_size_info_lvl2 serverworks_sizes[7] =
 {
 	{2048, 524288, 0x80000000},
 	{1024, 262144, 0xc0000000},
@@ -423,7 +423,7 @@
 	agp_device_command(command, 0);
 }
 
-static struct agp_bridge_driver sworks_driver = {
+static const struct agp_bridge_driver sworks_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= serverworks_sizes,
 	.size_type		= LVL2_APER_SIZE,
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index 6c45702..292b4ad 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -460,7 +460,7 @@
 
 /* Setup function */
 
-static struct aper_size_info_32 uninorth_sizes[7] =
+static const struct aper_size_info_32 uninorth_sizes[7] =
 {
 #if 0 /* Not sure uninorth supports that high aperture sizes */
 	{256, 65536, 6, 64},
@@ -477,7 +477,7 @@
  * Not sure that u3 supports that high aperture sizes but it
  * would strange if it did not :)
  */
-static struct aper_size_info_32 u3_sizes[8] =
+static const struct aper_size_info_32 u3_sizes[8] =
 {
 	{512, 131072, 7, 128},
 	{256, 65536, 6, 64},
@@ -489,7 +489,7 @@
 	{4, 1024, 0, 1}
 };
 
-struct agp_bridge_driver uninorth_agp_driver = {
+struct const agp_bridge_driver uninorth_agp_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= (void *)uninorth_sizes,
 	.size_type		= U32_APER_SIZE,
@@ -514,7 +514,7 @@
 	.cant_use_aperture	= 1,
 };
 
-struct agp_bridge_driver u3_agp_driver = {
+struct const agp_bridge_driver u3_agp_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= (void *)u3_sizes,
 	.size_type		= U32_APER_SIZE,
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
index 2e7c043..a2bb4ec 100644
--- a/drivers/char/agp/via-agp.c
+++ b/drivers/char/agp/via-agp.c
@@ -89,7 +89,7 @@
 }
 
 
-static struct aper_size_info_8 via_generic_sizes[9] =
+static const struct aper_size_info_8 via_generic_sizes[9] =
 {
 	{256, 65536, 6, 0},
 	{128, 32768, 5, 128},
@@ -170,7 +170,7 @@
 }
 
 
-static struct agp_bridge_driver via_agp3_driver = {
+static const struct agp_bridge_driver via_agp3_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= agp3_generic_sizes,
 	.size_type		= U8_APER_SIZE,
@@ -194,7 +194,7 @@
 	.agp_type_to_mask_type  = agp_generic_type_to_mask_type,
 };
 
-static struct agp_bridge_driver via_driver = {
+static const struct agp_bridge_driver via_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= via_generic_sizes,
 	.size_type		= U8_APER_SIZE,
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 7399ba7..80acd08 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -82,6 +82,18 @@
 	help
 	  This option enables support for the PCEngines WRAP programmable LEDs.
 
+config LEDS_H1940
+	tristate "LED Support for iPAQ H1940 device"
+	depends LEDS_CLASS && ARCH_H1940
+	help
+	  This option enables support for the LEDs on the h1940.
+
+config LEDS_COBALT
+	tristate "LED Support for Cobalt Server front LED"
+	depends on LEDS_CLASS && MIPS_COBALT
+	help
+	  This option enables support for the front LED on Cobalt Server
+
 comment "LED Triggers"
 
 config LEDS_TRIGGERS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 500de3dc..aa2c18e 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -14,6 +14,8 @@
 obj-$(CONFIG_LEDS_AMS_DELTA)		+= leds-ams-delta.o
 obj-$(CONFIG_LEDS_NET48XX)		+= leds-net48xx.o
 obj-$(CONFIG_LEDS_WRAP)			+= leds-wrap.o
+obj-$(CONFIG_LEDS_H1940)		+= leds-h1940.o
+obj-$(CONFIG_LEDS_COBALT)		+= leds-cobalt.o
 
 # LED Triggers
 obj-$(CONFIG_LEDS_TRIGGER_TIMER)	+= ledtrig-timer.o
diff --git a/drivers/leds/leds-cobalt.c b/drivers/leds/leds-cobalt.c
new file mode 100644
index 0000000..d16439c
--- /dev/null
+++ b/drivers/leds/leds-cobalt.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2006 - Florian Fainelli <florian@openwrt.org>
+ *
+ * Control the Cobalt Qube/RaQ front LED
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/leds.h>
+#include <asm/mach-cobalt/cobalt.h>
+
+static void cobalt_led_set(struct led_classdev *led_cdev, enum led_brightness brightness)
+{
+	if (brightness)
+		COBALT_LED_PORT = COBALT_LED_BAR_LEFT | COBALT_LED_BAR_RIGHT;
+	else
+		COBALT_LED_PORT = 0;
+}
+
+static struct led_classdev cobalt_led = {
+       .name = "cobalt-front-led",
+       .brightness_set = cobalt_led_set,
+       .default_trigger = "ide-disk",
+};
+
+static int __init cobalt_led_init(void)
+{
+	return led_classdev_register(NULL, &cobalt_led);
+}
+
+static void __exit cobalt_led_exit(void)
+{
+	led_classdev_unregister(&cobalt_led);
+}
+
+module_init(cobalt_led_init);
+module_exit(cobalt_led_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Front LED support for Cobalt Server");
+MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
diff --git a/drivers/leds/leds-h1940.c b/drivers/leds/leds-h1940.c
new file mode 100644
index 0000000..1d49d2a
--- /dev/null
+++ b/drivers/leds/leds-h1940.c
@@ -0,0 +1,163 @@
+/*
+ * drivers/leds/h1940-leds.c
+ * Copyright (c) Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * H1940 leds driver
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/leds.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/hardware.h>
+#include <asm/arch/h1940-latch.h>
+
+/*
+ * Green led.
+ */
+void h1940_greenled_set(struct led_classdev *led_dev, enum led_brightness value)
+{
+	switch (value) {
+		case LED_HALF:
+			h1940_latch_control(0,H1940_LATCH_LED_FLASH);
+			s3c2410_gpio_setpin(S3C2410_GPA7,1);
+			break;
+		case LED_FULL:
+			h1940_latch_control(0,H1940_LATCH_LED_GREEN);
+			s3c2410_gpio_setpin(S3C2410_GPA7,1);
+			break;
+		default:
+		case LED_OFF:
+			h1940_latch_control(H1940_LATCH_LED_FLASH,0);
+			h1940_latch_control(H1940_LATCH_LED_GREEN,0);
+			s3c2410_gpio_setpin(S3C2410_GPA7,0);
+			break;
+	}
+}
+
+static struct led_classdev h1940_greenled = {
+	.name			= "h1940:green",
+	.brightness_set		= h1940_greenled_set,
+	.default_trigger	= "h1940-charger",
+};
+
+/*
+ * Red led.
+ */
+void h1940_redled_set(struct led_classdev *led_dev, enum led_brightness value)
+{
+	switch (value) {
+		case LED_HALF:
+			h1940_latch_control(0,H1940_LATCH_LED_FLASH);
+			s3c2410_gpio_setpin(S3C2410_GPA1,1);
+			break;
+		case LED_FULL:
+			h1940_latch_control(0,H1940_LATCH_LED_RED);
+			s3c2410_gpio_setpin(S3C2410_GPA1,1);
+			break;
+		default:
+		case LED_OFF:
+			h1940_latch_control(H1940_LATCH_LED_FLASH,0);
+			h1940_latch_control(H1940_LATCH_LED_RED,0);
+			s3c2410_gpio_setpin(S3C2410_GPA1,0);
+			break;
+	}
+}
+
+static struct led_classdev h1940_redled = {
+	.name			= "h1940:red",
+	.brightness_set		= h1940_redled_set,
+	.default_trigger	= "h1940-charger",
+};
+
+/*
+ * Blue led.
+ * (it can only be blue flashing led)
+ */
+void h1940_blueled_set(struct led_classdev *led_dev, enum led_brightness value)
+{
+	if (value) {
+		/* flashing Blue */
+		h1940_latch_control(0,H1940_LATCH_LED_FLASH);
+		s3c2410_gpio_setpin(S3C2410_GPA3,1);
+	} else {
+		h1940_latch_control(H1940_LATCH_LED_FLASH,0);
+		s3c2410_gpio_setpin(S3C2410_GPA3,0);
+	}
+
+}
+
+static struct led_classdev h1940_blueled = {
+	.name			= "h1940:blue",
+	.brightness_set		= h1940_blueled_set,
+	.default_trigger	= "h1940-bluetooth",
+};
+
+static int __init h1940leds_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = led_classdev_register(&pdev->dev, &h1940_greenled);
+	if (ret)
+		goto err_green;
+
+	ret = led_classdev_register(&pdev->dev, &h1940_redled);
+	if (ret)
+		goto err_red;
+
+	ret = led_classdev_register(&pdev->dev, &h1940_blueled);
+	if (ret)
+		goto err_blue;
+
+	return 0;
+
+err_blue:
+	led_classdev_unregister(&h1940_redled);
+err_red:
+	led_classdev_unregister(&h1940_greenled);
+err_green:
+	return ret;
+}
+
+static int h1940leds_remove(struct platform_device *pdev)
+{
+	led_classdev_unregister(&h1940_greenled);
+	led_classdev_unregister(&h1940_redled);
+	led_classdev_unregister(&h1940_blueled);
+	return 0;
+}
+
+
+static struct platform_driver h1940leds_driver = {
+	.driver		= {
+		.name	= "h1940-leds",
+	},
+	.probe		= h1940leds_probe,
+	.remove		= h1940leds_remove,
+};
+
+
+static int __init h1940leds_init(void)
+{
+	return platform_driver_register(&h1940leds_driver);
+}
+
+static void __exit h1940leds_exit(void)
+{
+	platform_driver_unregister(&h1940leds_driver);
+}
+
+module_init(h1940leds_init);
+module_exit(h1940leds_exit);
+
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
+MODULE_DESCRIPTION("LED driver for the iPAQ H1940");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c
index caca0dc..f2e810f 100644
--- a/drivers/pcmcia/hd64465_ss.c
+++ b/drivers/pcmcia/hd64465_ss.c
@@ -907,7 +907,7 @@
 
 	for (i=0; i<HS_MAX_SOCKETS; i++) {
 		unsigned int ret;
-		hs_sockets[i].socket.dev.dev = &hd64465_device.dev;		
+		hs_sockets[i].socket.dev.parent = &hd64465_device.dev;
 		hs_sockets[i].number = i;
 		ret = pcmcia_register_socket(&hs_sockets[i].socket);
 		if (ret && i)
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index e4a9410..91da15b 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -760,7 +760,7 @@
 	/* Set up interrupt handler(s) */
 
 	for (i = 0 ; i < pcc_sockets ; i++) {
-		socket[i].socket.dev.dev = &pcc_device.dev;
+		socket[i].socket.dev.parent = &pcc_device.dev;
 		socket[i].socket.ops = &pcc_operations;
 		socket[i].socket.resource_ops = &pccard_nonstatic_ops;
 		socket[i].socket.owner = THIS_MODULE;
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index d059c91..9721ed7 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -1321,7 +1321,7 @@
 		socket[i].socket.ops = &m8xx_services;
 		socket[i].socket.resource_ops = &pccard_iodyn_ops;
 		socket[i].socket.cb_dev = NULL;
-		socket[i].socket.dev.dev = &m8xx_device.dev;
+		socket[i].socket.dev.parent = &m8xx_device.dev;
 	}
 
 	for (i = 0; i < PCMCIA_SOCKETS_NO; i++)
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index 76f7cbc..d77f751 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -291,7 +291,7 @@
 		omap_cf_present() ? "present" : "(not present)");
 
 	cf->socket.owner = THIS_MODULE;
-	cf->socket.dev.dev = dev;
+	cf->socket.dev.parent = dev;
 	cf->socket.ops = &omap_cf_ops;
 	cf->socket.resource_ops = &pccard_static_ops;
 	cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index 81dfc2c..ce22262 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -232,7 +232,7 @@
 		unsigned long align, struct pcmcia_socket *s)
 {
 	struct resource *res = make_resource(0, num, IORESOURCE_IO,
-					     s->dev.class_id);
+					     s->dev.bus_id);
 	struct pcmcia_align_data data;
 	unsigned long min = base;
 	int ret;
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
index 206e26c..eee2f1c 100644
--- a/drivers/pcmcia/vrc4171_card.c
+++ b/drivers/pcmcia/vrc4171_card.c
@@ -596,7 +596,7 @@
 		}
 
 		sprintf(socket->name, "NEC VRC4171 Card Slot %1c", 'A' + slot);
-		socket->pcmcia_socket.dev.dev = &vrc4171_card_device.dev;
+		socket->pcmcia_socket.dev.parent = &vrc4171_card_device.dev;
 		socket->pcmcia_socket.ops = &vrc4171_pccard_operations;
 		socket->pcmcia_socket.owner = THIS_MODULE;
 
diff --git a/drivers/sbus/char/Kconfig b/drivers/sbus/char/Kconfig
index 3a81529..35a7316 100644
--- a/drivers/sbus/char/Kconfig
+++ b/drivers/sbus/char/Kconfig
@@ -46,13 +46,6 @@
 	  based on the Phillips SAA9051, can handle NTSC and PAL/SECAM and
 	  SVIDEO signals.
 
-config SUN_AURORA
-	tristate "Aurora Multiboard 1600se (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && BROKEN
-	help
-	  The Aurora Multiboard is a multi-port high-speed serial controller.
-	  If you have one of these, say Y.
-
 config TADPOLE_TS102_UCTRL
 	tristate "Tadpole TS102 Microcontroller support (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && SPARC32
diff --git a/drivers/sbus/char/Makefile b/drivers/sbus/char/Makefile
index 3a5ea1d..7ab060e 100644
--- a/drivers/sbus/char/Makefile
+++ b/drivers/sbus/char/Makefile
@@ -19,7 +19,6 @@
 obj-$(CONFIG_SUN_MOSTEK_RTC)		+= rtc.o
 obj-$(CONFIG_SUN_BPP)			+= bpp.o
 obj-$(CONFIG_SUN_VIDEOPIX)		+= vfc.o
-obj-$(CONFIG_SUN_AURORA)		+= aurora.o
 obj-$(CONFIG_TADPOLE_TS102_UCTRL)	+= uctrl.o
 obj-$(CONFIG_SUN_JSFLASH)		+= jsflash.o
 obj-$(CONFIG_BBC_I2C)			+= bbc.o
diff --git a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c
deleted file mode 100644
index a54b4ac..0000000
--- a/drivers/sbus/char/aurora.c
+++ /dev/null
@@ -1,2364 +0,0 @@
-/*	$Id: aurora.c,v 1.19 2002/01/08 16:00:16 davem Exp $
- *	linux/drivers/sbus/char/aurora.c -- Aurora multiport driver
- *
- *	Copyright (c) 1999 by Oliver Aldulea (oli at bv dot ro)
- *
- *	This code is based on the RISCom/8 multiport serial driver written
- *	by Dmitry Gorodchanin (pgmdsg@ibi.com), based on the Linux serial
- *	driver, written by Linus Torvalds, Theodore T'so and others.
- *	The Aurora multiport programming info was obtained mainly from the
- *	Cirrus Logic CD180 documentation (available on the web), and by
- *	doing heavy tests on the board. Many thanks to Eddie C. Dost for the
- *	help on the sbus interface.
- *
- *	This program is free software; you can redistribute it and/or modify
- *	it under the terms of the 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.
- *
- *	Revision 1.0
- *
- *	This is the first public release.
- *
- *	Most of the information you need is in the aurora.h file. Please
- *	read that file before reading this one.
- *
- *	Several parts of the code do not have comments yet.
- * 
- * n.b.  The board can support 115.2 bit rates, but only on a few
- * ports. The total badwidth of one chip (ports 0-7 or 8-15) is equal
- * to OSC_FREQ div 16. In case of my board, each chip can take 6
- * channels of 115.2 kbaud.  This information is not well-tested.
- * 
- * Fixed to use tty_get_baud_rate().
- *   Theodore Ts'o <tytso@mit.edu>, 2001-Oct-12
- */
-
-#include <linux/module.h>
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#ifdef AURORA_INT_DEBUG
-#include <linux/timer.h>
-#endif
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/oplib.h>
-#include <asm/system.h>
-#include <asm/kdebug.h>
-#include <asm/sbus.h>
-#include <asm/uaccess.h>
-
-#include "aurora.h"
-#include "cd180.h"
-
-unsigned char irqs[4] = {
-	0, 0, 0, 0
-};
-
-#ifdef AURORA_INT_DEBUG
-int irqhit=0;
-#endif
-
-static struct tty_driver *aurora_driver;
-static struct Aurora_board aurora_board[AURORA_NBOARD] = {
-	{0,},
-};
-
-static struct Aurora_port aurora_port[AURORA_TNPORTS] =  {
-	{ 0, },
-};
-
-/* no longer used. static struct Aurora_board * IRQ_to_board[16] = { NULL, } ;*/
-static unsigned char * tmp_buf = NULL;
-
-DECLARE_TASK_QUEUE(tq_aurora);
-
-static inline int aurora_paranoia_check(struct Aurora_port const * port,
-				    char *name, const char *routine)
-{
-#ifdef AURORA_PARANOIA_CHECK
-	static const char *badmagic =
-		KERN_DEBUG "aurora: Warning: bad aurora port magic number for device %s in %s\n";
-	static const char *badinfo =
-		KERN_DEBUG "aurora: Warning: null aurora port for device %s in %s\n";
-
-	if (!port) {
-		printk(badinfo, name, routine);
-		return 1;
-	}
-	if (port->magic != AURORA_MAGIC) {
-		printk(badmagic, name, routine);
-		return 1;
-	}
-#endif
-	return 0;
-}
-
-/*
- * 
- *  Service functions for aurora driver.
- * 
- */
-
-/* Get board number from pointer */
-static inline int board_No (struct Aurora_board const * bp)
-{
-	return bp - aurora_board;
-}
-
-/* Get port number from pointer */
-static inline int port_No (struct Aurora_port const * port)
-{
-	return AURORA_PORT(port - aurora_port); 
-}
-
-/* Get pointer to board from pointer to port */
-static inline struct Aurora_board * port_Board(struct Aurora_port const * port)
-{
-	return &aurora_board[AURORA_BOARD(port - aurora_port)];
-}
-
-/* Wait for Channel Command Register ready */
-static inline void aurora_wait_CCR(struct aurora_reg128 * r)
-{
-	unsigned long delay;
-
-#ifdef AURORA_DEBUG
-printk("aurora_wait_CCR\n");
-#endif
-	/* FIXME: need something more descriptive than 100000 :) */
-	for (delay = 100000; delay; delay--) 
-		if (!sbus_readb(&r->r[CD180_CCR]))
-			return;
-	printk(KERN_DEBUG "aurora: Timeout waiting for CCR.\n");
-}
-
-/*
- *  aurora probe functions.
- */
-
-/* Must be called with enabled interrupts */
-static inline void aurora_long_delay(unsigned long delay)
-{
-	unsigned long i;
-
-#ifdef AURORA_DEBUG
-	printk("aurora_long_delay: start\n");
-#endif
-	for (i = jiffies + delay; time_before(jiffies, i); ) ;
-#ifdef AURORA_DEBUG
-	printk("aurora_long_delay: end\n");
-#endif
-}
-
-/* Reset and setup CD180 chip */
-static int aurora_init_CD180(struct Aurora_board * bp, int chip)
-{
-	unsigned long flags;
-	int id;
-	
-#ifdef AURORA_DEBUG
-	printk("aurora_init_CD180: start %d:%d\n",
-	       board_No(bp), chip);
-#endif
-	save_flags(flags); cli();
-	sbus_writeb(0, &bp->r[chip]->r[CD180_CAR]);
-	sbus_writeb(0, &bp->r[chip]->r[CD180_GSVR]);
-
-	/* Wait for CCR ready        */
-	aurora_wait_CCR(bp->r[chip]);
-
-	/* Reset CD180 chip          */
-	sbus_writeb(CCR_HARDRESET, &bp->r[chip]->r[CD180_CCR]);
-	udelay(1);
-	sti();
-	id=1000;
-	while((--id) &&
-	      (sbus_readb(&bp->r[chip]->r[CD180_GSVR])!=0xff))udelay(100);
-	if(!id) {
-		printk(KERN_ERR "aurora%d: Chip %d failed init.\n",
-		       board_No(bp), chip);
-		restore_flags(flags);
-		return(-1);
-	}
-	cli();
-	sbus_writeb((board_No(bp)<<5)|((chip+1)<<3),
-		    &bp->r[chip]->r[CD180_GSVR]); /* Set ID for this chip      */
-	sbus_writeb(0x80|bp->ACK_MINT,
-		    &bp->r[chip]->r[CD180_MSMR]); /* Prio for modem intr       */
-	sbus_writeb(0x80|bp->ACK_TINT,
-		    &bp->r[chip]->r[CD180_TSMR]); /* Prio for transmitter intr */
-	sbus_writeb(0x80|bp->ACK_RINT,
-		    &bp->r[chip]->r[CD180_RSMR]); /* Prio for receiver intr    */
-	/* Setting up prescaler. We need 4 tick per 1 ms */
-	sbus_writeb((bp->oscfreq/(1000000/AURORA_TPS)) >> 8,
-		    &bp->r[chip]->r[CD180_PPRH]);
-	sbus_writeb((bp->oscfreq/(1000000/AURORA_TPS)) & 0xff,
-		    &bp->r[chip]->r[CD180_PPRL]);
-
-	sbus_writeb(SRCR_AUTOPRI|SRCR_GLOBPRI,
-		    &bp->r[chip]->r[CD180_SRCR]);
-
-	id = sbus_readb(&bp->r[chip]->r[CD180_GFRCR]);
-	printk(KERN_INFO "aurora%d: Chip %d id %02x: ",
-	       board_No(bp), chip,id);
-	if(sbus_readb(&bp->r[chip]->r[CD180_SRCR]) & 128) {
-		switch (id) {
-			case 0x82:printk("CL-CD1864 rev A\n");break;
-			case 0x83:printk("CL-CD1865 rev A\n");break;
-			case 0x84:printk("CL-CD1865 rev B\n");break;
-			case 0x85:printk("CL-CD1865 rev C\n");break;
-			default:printk("Unknown.\n");
-		};
-	} else {
-		switch (id) {
-			case 0x81:printk("CL-CD180 rev B\n");break;
-			case 0x82:printk("CL-CD180 rev C\n");break;
-			default:printk("Unknown.\n");
-		};
-	}
-	restore_flags(flags);
-#ifdef AURORA_DEBUG
-	printk("aurora_init_CD180: end\n");
-#endif
-	return 0;
-}
-
-static int valid_irq(unsigned char irq)
-{
-int i;
-for(i=0;i<TYPE_1_IRQS;i++)
-	if (type_1_irq[i]==irq) return 1;
-return 0;
-}
-
-static irqreturn_t aurora_interrupt(int irq, void * dev_id);
-
-/* Main probing routine, also sets irq. */
-static int aurora_probe(void)
-{
-	struct sbus_bus *sbus;
-	struct sbus_dev *sdev;
-	int grrr;
-	char buf[30];
-	int bn = 0;
-	struct Aurora_board *bp;
-
-	for_each_sbus(sbus) {
-		for_each_sbusdev(sdev, sbus) {
-/*			printk("Try: %x %s\n",sdev,sdev->prom_name);*/
-			if (!strcmp(sdev->prom_name, "sio16")) {
-#ifdef AURORA_DEBUG
-				printk(KERN_INFO "aurora: sio16 at %p\n",sdev);
-#endif
-				if((sdev->reg_addrs[0].reg_size!=1) &&
-				   (sdev->reg_addrs[1].reg_size!=128) &&
-				   (sdev->reg_addrs[2].reg_size!=128) &&
-				   (sdev->reg_addrs[3].reg_size!=4)) {
-				   	printk(KERN_ERR "aurora%d: registers' sizes "
-					       "do not match.\n", bn);
-				   	break;
-				}
-				bp = &aurora_board[bn];
-				bp->r0 = (struct aurora_reg1 *)
-					sbus_ioremap(&sdev->resource[0], 0,
-						     sdev->reg_addrs[0].reg_size,
-						     "sio16");
-				if (bp->r0 == NULL) {
-					printk(KERN_ERR "aurora%d: can't map "
-					       "reg_addrs[0]\n", bn);
-					break;
-				}
-#ifdef AURORA_DEBUG
-				printk("Map reg 0: %p\n", bp->r0);
-#endif
-				bp->r[0] = (struct aurora_reg128 *)
-					sbus_ioremap(&sdev->resource[1], 0,
-						     sdev->reg_addrs[1].reg_size,
-						     "sio16");
-				if (bp->r[0] == NULL) {
-					printk(KERN_ERR "aurora%d: can't map "
-					       "reg_addrs[1]\n", bn);
-					break;
-				}
-#ifdef AURORA_DEBUG
-				printk("Map reg 1: %p\n", bp->r[0]);
-#endif
-				bp->r[1] = (struct aurora_reg128 *)
-					sbus_ioremap(&sdev->resource[2], 0,
-						     sdev->reg_addrs[2].reg_size,
-						     "sio16");
-				if (bp->r[1] == NULL) {
-					printk(KERN_ERR "aurora%d: can't map "
-					       "reg_addrs[2]\n", bn);
-					break;
-				}
-#ifdef AURORA_DEBUG
-				printk("Map reg 2: %p\n", bp->r[1]);
-#endif
-				bp->r3 = (struct aurora_reg4 *)
-					sbus_ioremap(&sdev->resource[3], 0,
-						     sdev->reg_addrs[3].reg_size,
-						     "sio16");
-				if (bp->r3 == NULL) {
-					printk(KERN_ERR "aurora%d: can't map "
-					       "reg_addrs[3]\n", bn);
-					break;
-				}
-#ifdef AURORA_DEBUG
-				printk("Map reg 3: %p\n", bp->r3);
-#endif
-				/* Variables setup */
-				bp->flags = 0;
-#ifdef AURORA_DEBUG
-				grrr=prom_getint(sdev->prom_node,"intr");
-				printk("intr pri %d\n", grrr);
-#endif
-				if ((bp->irq=irqs[bn]) && valid_irq(bp->irq) &&
-				    !request_irq(bp->irq|0x30, aurora_interrupt, IRQF_SHARED, "sio16", bp)) {
-					free_irq(bp->irq|0x30, bp);
-				} else
-				if ((bp->irq=prom_getint(sdev->prom_node, "bintr")) && valid_irq(bp->irq) &&
-				    !request_irq(bp->irq|0x30, aurora_interrupt, IRQF_SHARED, "sio16", bp)) {
-					free_irq(bp->irq|0x30, bp);
-				} else
-				if ((bp->irq=prom_getint(sdev->prom_node, "intr")) && valid_irq(bp->irq) &&
-				    !request_irq(bp->irq|0x30, aurora_interrupt, IRQF_SHARED, "sio16", bp)) {
-					free_irq(bp->irq|0x30, bp);
-				} else
-				for(grrr=0;grrr<TYPE_1_IRQS;grrr++) {
-					if ((bp->irq=type_1_irq[grrr])&&!request_irq(bp->irq|0x30, aurora_interrupt, IRQF_SHARED, "sio16", bp)) {
-						free_irq(bp->irq|0x30, bp);
-						break;
-					} else {
-					printk(KERN_ERR "aurora%d: Could not get an irq for this board !!!\n",bn);
-					bp->flags=0xff;
-					}
-				}
-				if(bp->flags==0xff)break;
-				printk(KERN_INFO "aurora%d: irq %d\n",bn,bp->irq&0x0f);
-				buf[0]=0;
-				grrr=prom_getproperty(sdev->prom_node,"dtr_rts",buf,sizeof(buf));
-				if(!strcmp(buf,"swapped")){
-					printk(KERN_INFO "aurora%d: Swapped DTR and RTS\n",bn);
-					bp->DTR=MSVR_RTS;
-					bp->RTS=MSVR_DTR;
-					bp->MSVDTR=CD180_MSVRTS;
-					bp->MSVRTS=CD180_MSVDTR;
-					bp->flags|=AURORA_BOARD_DTR_FLOW_OK;
-					}else{
-					#ifdef AURORA_FORCE_DTR_FLOW
-					printk(KERN_INFO "aurora%d: Forcing swapped DTR-RTS\n",bn);
-					bp->DTR=MSVR_RTS;
-					bp->RTS=MSVR_DTR;
-					bp->MSVDTR=CD180_MSVRTS;
-					bp->MSVRTS=CD180_MSVDTR;
-					bp->flags|=AURORA_BOARD_DTR_FLOW_OK;
-					#else
-					printk(KERN_INFO "aurora%d: Normal DTR and RTS\n",bn);
-					bp->DTR=MSVR_DTR;
-					bp->RTS=MSVR_RTS;
-					bp->MSVDTR=CD180_MSVDTR;
-					bp->MSVRTS=CD180_MSVRTS;
-					#endif
-				}
-				bp->oscfreq=prom_getint(sdev->prom_node,"clk")*100;
-				printk(KERN_INFO "aurora%d: Oscillator: %d Hz\n",bn,bp->oscfreq);
-				grrr=prom_getproperty(sdev->prom_node,"chip",buf,sizeof(buf));
-				printk(KERN_INFO "aurora%d: Chips: %s\n",bn,buf);
-				grrr=prom_getproperty(sdev->prom_node,"manu",buf,sizeof(buf));
-				printk(KERN_INFO "aurora%d: Manufacturer: %s\n",bn,buf);
-				grrr=prom_getproperty(sdev->prom_node,"model",buf,sizeof(buf));
-				printk(KERN_INFO "aurora%d: Model: %s\n",bn,buf);
-				grrr=prom_getproperty(sdev->prom_node,"rev",buf,sizeof(buf));
-				printk(KERN_INFO "aurora%d: Revision: %s\n",bn,buf);
-				grrr=prom_getproperty(sdev->prom_node,"mode",buf,sizeof(buf));
-				printk(KERN_INFO "aurora%d: Mode: %s\n",bn,buf);
-				#ifdef MODULE
-				bp->count=0;
-				#endif
-				bp->flags = AURORA_BOARD_PRESENT;
-				/* hardware ack */
-				bp->ACK_MINT=1;
-				bp->ACK_TINT=2;
-				bp->ACK_RINT=3;
-				bn++;
-			}
-		}
-	}
-	return bn;
-}
-
-static void aurora_release_io_range(struct Aurora_board *bp)
-{
-	sbus_iounmap((unsigned long)bp->r0, 1);
-	sbus_iounmap((unsigned long)bp->r[0], 128);
-	sbus_iounmap((unsigned long)bp->r[1], 128);
-	sbus_iounmap((unsigned long)bp->r3, 4);
-}
-
-static inline void aurora_mark_event(struct Aurora_port * port, int event)
-{
-#ifdef AURORA_DEBUG
-	printk("aurora_mark_event: start\n");
-#endif
-	set_bit(event, &port->event);
-	queue_task(&port->tqueue, &tq_aurora);
-	mark_bh(AURORA_BH);
-#ifdef AURORA_DEBUG
-	printk("aurora_mark_event: end\n");
-#endif
-}
-
-static __inline__ struct Aurora_port * aurora_get_port(struct Aurora_board const * bp,
-						       int chip,
-						       unsigned char const *what)
-{
-	unsigned char channel;
-	struct Aurora_port * port;
-
-	channel = ((chip << 3) |
-		   ((sbus_readb(&bp->r[chip]->r[CD180_GSCR]) & GSCR_CHAN) >> GSCR_CHAN_OFF));
-	port = &aurora_port[board_No(bp) * AURORA_NPORT * AURORA_NCD180 + channel];
-	if (port->flags & ASYNC_INITIALIZED)
-		return port;
-
-	printk(KERN_DEBUG "aurora%d: %s interrupt from invalid port %d\n",
-	       board_No(bp), what, channel);
-	return NULL;
-}
-
-static void aurora_receive_exc(struct Aurora_board const * bp, int chip)
-{
-	struct Aurora_port *port;
-	struct tty_struct *tty;
-	unsigned char status;
-	unsigned char ch;
-	
-	if (!(port = aurora_get_port(bp, chip, "Receive_x")))
-		return;
-
-	tty = port->tty;
-	if (tty->flip.count >= TTY_FLIPBUF_SIZE)  {
-#ifdef AURORA_INTNORM
-		printk("aurora%d: port %d: Working around flip buffer overflow.\n",
-		       board_No(bp), port_No(port));
-#endif
-		return;
-	}
-	
-#ifdef AURORA_REPORT_OVERRUN	
-	status = sbus_readb(&bp->r[chip]->r[CD180_RCSR]);
-	if (status & RCSR_OE)  {
-		port->overrun++;
-#if 1
-		printk("aurora%d: port %d: Overrun. Total %ld overruns.\n",
-		       board_No(bp), port_No(port), port->overrun);
-#endif		
-	}
-	status &= port->mark_mask;
-#else	
-	status = sbus_readb(&bp->r[chip]->r[CD180_RCSR]) & port->mark_mask;
-#endif	
-	ch = sbus_readb(&bp->r[chip]->r[CD180_RDR]);
-	if (!status)
-		return;
-
-	if (status & RCSR_TOUT)  {
-/*		printk("aurora%d: port %d: Receiver timeout. Hardware problems ?\n",
-		       board_No(bp), port_No(port));*/
-		return;
-		
-	} else if (status & RCSR_BREAK)  {
-		printk(KERN_DEBUG "aurora%d: port %d: Handling break...\n",
-		       board_No(bp), port_No(port));
-		*tty->flip.flag_buf_ptr++ = TTY_BREAK;
-		if (port->flags & ASYNC_SAK)
-			do_SAK(tty);
-		
-	} else if (status & RCSR_PE) 
-		*tty->flip.flag_buf_ptr++ = TTY_PARITY;
-	
-	else if (status & RCSR_FE) 
-		*tty->flip.flag_buf_ptr++ = TTY_FRAME;
-	
-        else if (status & RCSR_OE)
-		*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
-	
-	else
-		*tty->flip.flag_buf_ptr++ = 0;
-	
-	*tty->flip.char_buf_ptr++ = ch;
-	tty->flip.count++;
-	queue_task(&tty->flip.tqueue, &tq_timer);
-}
-
-static void aurora_receive(struct Aurora_board const * bp, int chip)
-{
-	struct Aurora_port *port;
-	struct tty_struct *tty;
-	unsigned char count,cnt;
-
-	if (!(port = aurora_get_port(bp, chip, "Receive")))
-		return;
-	
-	tty = port->tty;
-	
-	count = sbus_readb(&bp->r[chip]->r[CD180_RDCR]);
-
-#ifdef AURORA_REPORT_FIFO
-	port->hits[count > 8 ? 9 : count]++;
-#endif
-
-	while (count--)  {
-		if (tty->flip.count >= TTY_FLIPBUF_SIZE)  {
-#ifdef AURORA_INTNORM
-			printk("aurora%d: port %d: Working around flip buffer overflow.\n",
-			       board_No(bp), port_No(port));
-#endif
-			break;
-		}
-		cnt = sbus_readb(&bp->r[chip]->r[CD180_RDR]);
-		*tty->flip.char_buf_ptr++ = cnt;
-		*tty->flip.flag_buf_ptr++ = 0;
-		tty->flip.count++;
-	}
-	queue_task(&tty->flip.tqueue, &tq_timer);
-}
-
-static void aurora_transmit(struct Aurora_board const * bp, int chip)
-{
-	struct Aurora_port *port;
-	struct tty_struct *tty;
-	unsigned char count;
-	
-	if (!(port = aurora_get_port(bp, chip, "Transmit")))
-		return;
-		
-	tty = port->tty;
-	
-	if (port->SRER & SRER_TXEMPTY)  {
-		/* FIFO drained */
-		sbus_writeb(port_No(port) & 7,
-			    &bp->r[chip]->r[CD180_CAR]);
-		udelay(1);
-		port->SRER &= ~SRER_TXEMPTY;
-		sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
-		return;
-	}
-	
-	if ((port->xmit_cnt <= 0 && !port->break_length)
-	    || tty->stopped || tty->hw_stopped)  {
-		sbus_writeb(port_No(port) & 7,
-			    &bp->r[chip]->r[CD180_CAR]);
-		udelay(1);
-		port->SRER &= ~SRER_TXRDY;
-		sbus_writeb(port->SRER,
-			    &bp->r[chip]->r[CD180_SRER]);
-		return;
-	}
-	
-	if (port->break_length)  {
-		if (port->break_length > 0)  {
-			if (port->COR2 & COR2_ETC)  {
-				sbus_writeb(CD180_C_ESC,
-					    &bp->r[chip]->r[CD180_TDR]);
-				sbus_writeb(CD180_C_SBRK,
-					    &bp->r[chip]->r[CD180_TDR]);
-				port->COR2 &= ~COR2_ETC;
-			}
-			count = min(port->break_length, 0xff);
-			sbus_writeb(CD180_C_ESC,
-				    &bp->r[chip]->r[CD180_TDR]);
-			sbus_writeb(CD180_C_DELAY,
-				    &bp->r[chip]->r[CD180_TDR]);
-			sbus_writeb(count,
-				    &bp->r[chip]->r[CD180_TDR]);
-			if (!(port->break_length -= count))
-				port->break_length--;
-		} else  {
-			sbus_writeb(CD180_C_ESC,
-				    &bp->r[chip]->r[CD180_TDR]);
-			sbus_writeb(CD180_C_EBRK,
-				    &bp->r[chip]->r[CD180_TDR]);
-			sbus_writeb(port->COR2,
-				    &bp->r[chip]->r[CD180_COR2]);
-			aurora_wait_CCR(bp->r[chip]);
-			sbus_writeb(CCR_CORCHG2,
-				    &bp->r[chip]->r[CD180_CCR]);
-			port->break_length = 0;
-		}
-		return;
-	}
-	
-	count = CD180_NFIFO;
-	do {
-		u8 byte = port->xmit_buf[port->xmit_tail++];
-
-		sbus_writeb(byte, &bp->r[chip]->r[CD180_TDR]);
-		port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
-		if (--port->xmit_cnt <= 0)
-			break;
-	} while (--count > 0);
-	
-	if (port->xmit_cnt <= 0)  {
-		sbus_writeb(port_No(port) & 7,
-			    &bp->r[chip]->r[CD180_CAR]);
-		udelay(1);
-		port->SRER &= ~SRER_TXRDY;
-		sbus_writeb(port->SRER,
-			    &bp->r[chip]->r[CD180_SRER]);
-	}
-	if (port->xmit_cnt <= port->wakeup_chars)
-		aurora_mark_event(port, RS_EVENT_WRITE_WAKEUP);
-}
-
-static void aurora_check_modem(struct Aurora_board const * bp, int chip)
-{
-	struct Aurora_port *port;
-	struct tty_struct *tty;
-	unsigned char mcr;
-	
-	if (!(port = aurora_get_port(bp, chip, "Modem")))
-		return;
-		
-	tty = port->tty;
-	
-	mcr = sbus_readb(&bp->r[chip]->r[CD180_MCR]);
-	if (mcr & MCR_CDCHG)  {
-		if (sbus_readb(&bp->r[chip]->r[CD180_MSVR]) & MSVR_CD) 
-			wake_up_interruptible(&port->open_wait);
-		else
-			schedule_task(&port->tqueue_hangup);
-	}
-	
-/* We don't have such things yet. My aurora board has DTR and RTS swapped, but that doesn't count in this driver. Let's hope
- * Aurora didn't made any boards with CTS or DSR broken...
- */
-/* #ifdef AURORA_BRAIN_DAMAGED_CTS
-	if (mcr & MCR_CTSCHG)  {
-		if (aurora_in(bp, CD180_MSVR) & MSVR_CTS)  {
-			tty->hw_stopped = 0;
-			port->SRER |= SRER_TXRDY;
-			if (port->xmit_cnt <= port->wakeup_chars)
-				aurora_mark_event(port, RS_EVENT_WRITE_WAKEUP);
-		} else  {
-			tty->hw_stopped = 1;
-			port->SRER &= ~SRER_TXRDY;
-		}
-		sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
-	}
-	if (mcr & MCR_DSRCHG)  {
-		if (aurora_in(bp, CD180_MSVR) & MSVR_DSR)  {
-			tty->hw_stopped = 0;
-			port->SRER |= SRER_TXRDY;
-			if (port->xmit_cnt <= port->wakeup_chars)
-				aurora_mark_event(port, RS_EVENT_WRITE_WAKEUP);
-		} else  {
-			tty->hw_stopped = 1;
-			port->SRER &= ~SRER_TXRDY;
-		}
-		sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
-	}
-#endif AURORA_BRAIN_DAMAGED_CTS */
-	
-	/* Clear change bits */
-	sbus_writeb(0, &bp->r[chip]->r[CD180_MCR]);
-}
-
-/* The main interrupt processing routine */
-static irqreturn_t aurora_interrupt(int irq, void * dev_id)
-{
-	unsigned char status;
-	unsigned char ack,chip/*,chip_id*/;
-	struct Aurora_board * bp = (struct Aurora_board *) dev_id;
-	unsigned long loop = 0;
-
-#ifdef AURORA_INT_DEBUG
-	printk("IRQ%d %d\n",irq,++irqhit);
-#ifdef AURORA_FLOODPRO
-	if (irqhit>=AURORA_FLOODPRO)
-		sbus_writeb(8, &bp->r0->r);
-#endif
-#endif
-	
-/* old	bp = IRQ_to_board[irq&0x0f];*/
-	
-	if (!bp || !(bp->flags & AURORA_BOARD_ACTIVE))
-		return IRQ_NONE;
-
-/*	The while() below takes care of this.
-	status = sbus_readb(&bp->r[0]->r[CD180_SRSR]);
-#ifdef AURORA_INT_DEBUG
-	printk("mumu: %02x\n", status);
-#endif
-	if (!(status&SRSR_ANYINT))
-		return IRQ_NONE; * Nobody has anything to say, so exit *
-*/
-	while ((loop++ < 48) &&
-	       (status = sbus_readb(&bp->r[0]->r[CD180_SRSR]) & SRSR_ANYINT)){
-#ifdef AURORA_INT_DEBUG
-		printk("SRSR: %02x\n", status);
-#endif
-		if (status & SRSR_REXT) {
-			ack = sbus_readb(&bp->r3->r[bp->ACK_RINT]);
-#ifdef AURORA_INT_DEBUG
-			printk("R-ACK %02x\n", ack);
-#endif
-			if ((ack >> 5) == board_No(bp)) {
-				if ((chip=((ack>>3)&3)-1) < AURORA_NCD180) {
-					if ((ack&GSVR_ITMASK)==GSVR_IT_RGD) {
-						aurora_receive(bp,chip);
-						sbus_writeb(0,
-							 &bp->r[chip]->r[CD180_EOSRR]);
-					} else if ((ack & GSVR_ITMASK) == GSVR_IT_REXC) {
-						aurora_receive_exc(bp,chip);
-						sbus_writeb(0,
-							 &bp->r[chip]->r[CD180_EOSRR]);
-					}
-				}
-			}
-		} else if (status & SRSR_TEXT) {
-			ack = sbus_readb(&bp->r3->r[bp->ACK_TINT]);
-#ifdef AURORA_INT_DEBUG
-			printk("T-ACK %02x\n", ack);
-#endif
-			if ((ack >> 5) == board_No(bp)) {
-				if ((chip=((ack>>3)&3)-1) < AURORA_NCD180) {
-					if ((ack&GSVR_ITMASK)==GSVR_IT_TX) {
-						aurora_transmit(bp,chip);
-						sbus_writeb(0,
-							 &bp->r[chip]->r[CD180_EOSRR]);
-					}
-				}
-			}
-		} else if (status & SRSR_MEXT) {
-			ack = sbus_readb(&bp->r3->r[bp->ACK_MINT]);
-#ifdef AURORA_INT_DEBUG
-			printk("M-ACK %02x\n", ack);
-#endif
-			if ((ack >> 5) == board_No(bp)) {
-				if ((chip = ((ack>>3)&3)-1) < AURORA_NCD180) {
-					if ((ack&GSVR_ITMASK)==GSVR_IT_MDM) {
-						aurora_check_modem(bp,chip);
-						sbus_writeb(0,
-							 &bp->r[chip]->r[CD180_EOSRR]);
-					}
-				}
-			}
-		}
-	}
-/* I guess this faster code can be used with CD1865, using AUROPRI and GLOBPRI. */
-#if 0
-	while ((loop++ < 48)&&(status=bp->r[0]->r[CD180_SRSR]&SRSR_ANYINT)){
-#ifdef AURORA_INT_DEBUG
-		printk("SRSR: %02x\n",status);
-#endif
-		ack = sbus_readb(&bp->r3->r[0]);
-#ifdef AURORA_INT_DEBUG
-		printk("ACK: %02x\n",ack);
-#endif
-		if ((ack>>5)==board_No(bp)) {
-			if ((chip=((ack>>3)&3)-1) < AURORA_NCD180) {
-				ack&=GSVR_ITMASK;
-				if (ack==GSVR_IT_RGD) {
-					aurora_receive(bp,chip);
-					sbus_writeb(0,
-						    &bp->r[chip]->r[CD180_EOSRR]);
-				} else if (ack==GSVR_IT_REXC) {
-					aurora_receive_exc(bp,chip);
-					sbus_writeb(0,
-						    &bp->r[chip]->r[CD180_EOSRR]);
-				} else if (ack==GSVR_IT_TX) {
-					aurora_transmit(bp,chip);
-					sbus_writeb(0,
-						    &bp->r[chip]->r[CD180_EOSRR]);
-				} else if (ack==GSVR_IT_MDM) {
-					aurora_check_modem(bp,chip);
-					sbus_writeb(0,
-						    &bp->r[chip]->r[CD180_EOSRR]);
-				}
-			}
-		}
-	}
-#endif
-
-/* This is the old handling routine, used in riscom8 for only one CD180. I keep it here for reference. */
-#if 0
-	for(chip=0;chip<AURORA_NCD180;chip++){
-		chip_id=(board_No(bp)<<5)|((chip+1)<<3);
-		loop=0;
-		while ((loop++ < 1) &&
-		       ((status = sbus_readb(&bp->r[chip]->r[CD180_SRSR])) &
-			(SRSR_TEXT | SRSR_MEXT | SRSR_REXT))) {
-
-			if (status & SRSR_REXT) {
-				ack = sbus_readb(&bp->r3->r[bp->ACK_RINT]);
-				if (ack == (chip_id | GSVR_IT_RGD)) {
-#ifdef AURORA_INTMSG
-					printk("RX ACK\n");
-#endif
-					aurora_receive(bp,chip);
-				} else if (ack == (chip_id | GSVR_IT_REXC)) {
-#ifdef AURORA_INTMSG
-					printk("RXC ACK\n");
-#endif
-					aurora_receive_exc(bp,chip);
-				} else {
-#ifdef AURORA_INTNORM
-					printk("aurora%d-%d: Bad receive ack 0x%02x.\n",
-					       board_No(bp), chip, ack);
-#endif
-				}
-			} else if (status & SRSR_TEXT) {
-				ack = sbus_readb(&bp->r3->r[bp->ACK_TINT]);
-				if (ack == (chip_id | GSVR_IT_TX)){
-#ifdef AURORA_INTMSG
-					printk("TX ACK\n");
-#endif
-					aurora_transmit(bp,chip);
-				} else {
-#ifdef AURORA_INTNORM
-					printk("aurora%d-%d: Bad transmit ack 0x%02x.\n",
-					       board_No(bp), chip, ack);
-#endif
-				}
-			} else  if (status & SRSR_MEXT)  {
-				ack = sbus_readb(&bp->r3->r[bp->ACK_MINT]);
-				if (ack == (chip_id | GSVR_IT_MDM)){
-#ifdef AURORA_INTMSG
-					printk("MDM ACK\n");
-#endif
-					aurora_check_modem(bp,chip);
-				} else {
-#ifdef AURORA_INTNORM
-					printk("aurora%d-%d: Bad modem ack 0x%02x.\n",
-					       board_No(bp), chip, ack);
-#endif
-				}
-			}
-			sbus_writeb(0, &bp->r[chip]->r[CD180_EOSRR]);
-		}
-	}
-#endif
-
-	return IRQ_HANDLED;
-}
-
-#ifdef AURORA_INT_DEBUG
-static void aurora_timer (unsigned long ignored);
-
-static DEFINE_TIMER(aurora_poll_timer, aurora_timer, 0, 0);
-
-static void
-aurora_timer (unsigned long ignored)
-{
-	unsigned long flags;
-	int i;
-
-	save_flags(flags); cli();
-
-	printk("SRSR: %02x,%02x - ",
-	       sbus_readb(&aurora_board[0].r[0]->r[CD180_SRSR]),
-	       sbus_readb(&aurora_board[0].r[1]->r[CD180_SRSR]));
-	for (i = 0; i < 4; i++) {
-		udelay(1);
-		printk("%02x ",
-		       sbus_readb(&aurora_board[0].r3->r[i]));
-	}
-	printk("\n");
-
-	aurora_poll_timer.expires = jiffies + 300;
-	add_timer (&aurora_poll_timer);
-
-	restore_flags(flags);
-}
-#endif
-
-/*
- *  Routines for open & close processing.
- */
-
-/* Called with disabled interrupts */
-static int aurora_setup_board(struct Aurora_board * bp)
-{
-	int error;
-	
-#ifdef AURORA_ALLIRQ
-	int i;
-	for (i = 0; i < AURORA_ALLIRQ; i++) {
-		error = request_irq(allirq[i]|0x30, aurora_interrupt, IRQF_SHARED,
-				    "sio16", bp);
-		if (error)
-			printk(KERN_ERR "IRQ%d request error %d\n",
-			       allirq[i], error);
-	}
-#else
-	error = request_irq(bp->irq|0x30, aurora_interrupt, IRQF_SHARED,
-			    "sio16", bp);
-	if (error) {
-		printk(KERN_ERR "IRQ request error %d\n", error);
-		return error;
-	}
-#endif
-	/* Board reset */
-	sbus_writeb(0, &bp->r0->r);
-	udelay(1);
-	if (bp->flags & AURORA_BOARD_TYPE_2) {
-		/* unknown yet */
-	} else {
-		sbus_writeb((AURORA_CFG_ENABLE_IO | AURORA_CFG_ENABLE_IRQ |
-			     (((bp->irq)&0x0f)>>2)),
-			    &bp->r0->r);
-	}
-	udelay(10000);
-
-	if (aurora_init_CD180(bp,0))error=1;error=0;
-	if (aurora_init_CD180(bp,1))error++;
-	if (error == AURORA_NCD180) {
-		printk(KERN_ERR "Both chips failed initialisation.\n");
-		return -EIO;
-	}
-
-#ifdef AURORA_INT_DEBUG
-	aurora_poll_timer.expires= jiffies + 1;
-	add_timer(&aurora_poll_timer);
-#endif
-#ifdef AURORA_DEBUG
-	printk("aurora_setup_board: end\n");
-#endif
-	return 0;
-}
-
-/* Called with disabled interrupts */
-static void aurora_shutdown_board(struct Aurora_board *bp)
-{
-	int i;
-
-#ifdef AURORA_DEBUG
-	printk("aurora_shutdown_board: start\n");
-#endif
-
-#ifdef AURORA_INT_DEBUG
-	del_timer(&aurora_poll_timer);
-#endif
-
-#ifdef AURORA_ALLIRQ
-	for(i=0;i<AURORA_ALLIRQ;i++){
-		free_irq(allirq[i]|0x30, bp);
-/*		IRQ_to_board[allirq[i]&0xf] = NULL;*/
-	}
-#else
-	free_irq(bp->irq|0x30, bp);
-/*	IRQ_to_board[bp->irq&0xf] = NULL;*/
-#endif	
-	/* Drop all DTR's */
-	for(i=0;i<16;i++){
-		sbus_writeb(i & 7, &bp->r[i>>3]->r[CD180_CAR]);
-		udelay(1);
-		sbus_writeb(0, &bp->r[i>>3]->r[CD180_MSVR]);
-		udelay(1);
-	}
-	/* Board shutdown */
-	sbus_writeb(0, &bp->r0->r);
-
-#ifdef AURORA_DEBUG
-	printk("aurora_shutdown_board: end\n");
-#endif
-}
-
-/* Setting up port characteristics. 
- * Must be called with disabled interrupts
- */
-static void aurora_change_speed(struct Aurora_board *bp, struct Aurora_port *port)
-{
-	struct tty_struct *tty;
-	unsigned long baud;
-	long tmp;
-	unsigned char cor1 = 0, cor3 = 0;
-	unsigned char mcor1 = 0, mcor2 = 0,chip;
-	
-#ifdef AURORA_DEBUG
-	printk("aurora_change_speed: start\n");
-#endif
-	if (!(tty = port->tty) || !tty->termios)
-		return;
-		
-	chip = AURORA_CD180(port_No(port));
-
-	port->SRER  = 0;
-	port->COR2 = 0;
-	port->MSVR = MSVR_RTS|MSVR_DTR;
-	
-	baud = tty_get_baud_rate(tty);
-	
-	/* Select port on the board */
-	sbus_writeb(port_No(port) & 7,
-		    &bp->r[chip]->r[CD180_CAR]);
-	udelay(1);
-	
-	if (!baud)  {
-		/* Drop DTR & exit */
-		port->MSVR &= ~(bp->DTR|bp->RTS);
-		sbus_writeb(port->MSVR,
-			    &bp->r[chip]->r[CD180_MSVR]);
-		return;
-	} else  {
-		/* Set DTR on */
-		port->MSVR |= bp->DTR;
-		sbus_writeb(port->MSVR,
-			    &bp->r[chip]->r[CD180_MSVR]);
-	}
-	
-	/* Now we must calculate some speed dependent things. */
-	
-	/* Set baud rate for port. */
-	tmp = (((bp->oscfreq + baud/2) / baud +
-		CD180_TPC/2) / CD180_TPC);
-
-/*	tmp = (bp->oscfreq/7)/baud;
-	if((tmp%10)>4)tmp=tmp/10+1;else tmp=tmp/10;*/
-/*	printk("Prescaler period: %d\n",tmp);*/
-
-	sbus_writeb((tmp >> 8) & 0xff,
-		    &bp->r[chip]->r[CD180_RBPRH]);
-	sbus_writeb((tmp >> 8) & 0xff,
-		    &bp->r[chip]->r[CD180_TBPRH]);
-	sbus_writeb(tmp & 0xff, &bp->r[chip]->r[CD180_RBPRL]);
-	sbus_writeb(tmp & 0xff, &bp->r[chip]->r[CD180_TBPRL]);
-	
-	baud = (baud + 5) / 10;   /* Estimated CPS */
-	
-	/* Two timer ticks seems enough to wakeup something like SLIP driver */
-	tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO;		
-	port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
-					      SERIAL_XMIT_SIZE - 1 : tmp);
-	
-	/* Receiver timeout will be transmission time for 1.5 chars */
-	tmp = (AURORA_TPS + AURORA_TPS/2 + baud/2) / baud;
-	tmp = (tmp > 0xff) ? 0xff : tmp;
-	sbus_writeb(tmp, &bp->r[chip]->r[CD180_RTPR]);
-	
-	switch (C_CSIZE(tty))  {
-	 case CS5:
-		cor1 |= COR1_5BITS;
-		break;
-	 case CS6:
-		cor1 |= COR1_6BITS;
-		break;
-	 case CS7:
-		cor1 |= COR1_7BITS;
-		break;
-	 case CS8:
-		cor1 |= COR1_8BITS;
-		break;
-	}
-	
-	if (C_CSTOPB(tty)) 
-		cor1 |= COR1_2SB;
-	
-	cor1 |= COR1_IGNORE;
-	if (C_PARENB(tty))  {
-		cor1 |= COR1_NORMPAR;
-		if (C_PARODD(tty)) 
-			cor1 |= COR1_ODDP;
-		if (I_INPCK(tty)) 
-			cor1 &= ~COR1_IGNORE;
-	}
-	/* Set marking of some errors */
-	port->mark_mask = RCSR_OE | RCSR_TOUT;
-	if (I_INPCK(tty)) 
-		port->mark_mask |= RCSR_FE | RCSR_PE;
-	if (I_BRKINT(tty) || I_PARMRK(tty)) 
-		port->mark_mask |= RCSR_BREAK;
-	if (I_IGNPAR(tty)) 
-		port->mark_mask &= ~(RCSR_FE | RCSR_PE);
-	if (I_IGNBRK(tty))  {
-		port->mark_mask &= ~RCSR_BREAK;
-		if (I_IGNPAR(tty)) 
-			/* Real raw mode. Ignore all */
-			port->mark_mask &= ~RCSR_OE;
-	}
-	/* Enable Hardware Flow Control */
-	if (C_CRTSCTS(tty))  {
-/*#ifdef AURORA_BRAIN_DAMAGED_CTS
-		port->SRER |= SRER_DSR | SRER_CTS;
-		mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
-		mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
-		tty->hw_stopped = !(aurora_in(bp, CD180_MSVR) & (MSVR_CTS|MSVR_DSR));
-#else*/
-		port->COR2 |= COR2_CTSAE;
-/*#endif*/
-		if (bp->flags&AURORA_BOARD_DTR_FLOW_OK) {
-			mcor1 |= AURORA_RXTH;
-		}
-	}
-	/* Enable Software Flow Control. FIXME: I'm not sure about this */
-	/* Some people reported that it works, but I still doubt */
-	if (I_IXON(tty))  {
-		port->COR2 |= COR2_TXIBE;
-		cor3 |= (COR3_FCT | COR3_SCDE);
-		if (I_IXANY(tty))
-			port->COR2 |= COR2_IXM;
-		sbus_writeb(START_CHAR(tty),
-			    &bp->r[chip]->r[CD180_SCHR1]);
-		sbus_writeb(STOP_CHAR(tty),
-			    &bp->r[chip]->r[CD180_SCHR2]);
-		sbus_writeb(START_CHAR(tty),
-			    &bp->r[chip]->r[CD180_SCHR3]);
-		sbus_writeb(STOP_CHAR(tty),
-			    &bp->r[chip]->r[CD180_SCHR4]);
-	}
-	if (!C_CLOCAL(tty))  {
-		/* Enable CD check */
-		port->SRER |= SRER_CD;
-		mcor1 |= MCOR1_CDZD;
-		mcor2 |= MCOR2_CDOD;
-	}
-	
-	if (C_CREAD(tty)) 
-		/* Enable receiver */
-		port->SRER |= SRER_RXD;
-	
-	/* Set input FIFO size (1-8 bytes) */
-	cor3 |= AURORA_RXFIFO; 
-	/* Setting up CD180 channel registers */
-	sbus_writeb(cor1, &bp->r[chip]->r[CD180_COR1]);
-	sbus_writeb(port->COR2, &bp->r[chip]->r[CD180_COR2]);
-	sbus_writeb(cor3, &bp->r[chip]->r[CD180_COR3]);
-	/* Make CD180 know about registers change */
-	aurora_wait_CCR(bp->r[chip]);
-	sbus_writeb(CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3,
-		    &bp->r[chip]->r[CD180_CCR]);
-	/* Setting up modem option registers */
-	sbus_writeb(mcor1, &bp->r[chip]->r[CD180_MCOR1]);
-	sbus_writeb(mcor2, &bp->r[chip]->r[CD180_MCOR2]);
-	/* Enable CD180 transmitter & receiver */
-	aurora_wait_CCR(bp->r[chip]);
-	sbus_writeb(CCR_TXEN | CCR_RXEN, &bp->r[chip]->r[CD180_CCR]);
-	/* Enable interrupts */
-	sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
-	/* And finally set RTS on */
-	sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]);
-#ifdef AURORA_DEBUG
-	printk("aurora_change_speed: end\n");
-#endif
-}
-
-/* Must be called with interrupts enabled */
-static int aurora_setup_port(struct Aurora_board *bp, struct Aurora_port *port)
-{
-	unsigned long flags;
-	
-#ifdef AURORA_DEBUG
-	printk("aurora_setup_port: start %d\n",port_No(port));
-#endif
-	if (port->flags & ASYNC_INITIALIZED)
-		return 0;
-		
-	if (!port->xmit_buf) {
-		/* We may sleep in get_zeroed_page() */
-		unsigned long tmp;
-		
-		if (!(tmp = get_zeroed_page(GFP_KERNEL)))
-			return -ENOMEM;
-		    
-		if (port->xmit_buf) {
-			free_page(tmp);
-			return -ERESTARTSYS;
-		}
-		port->xmit_buf = (unsigned char *) tmp;
-	}
-		
-	save_flags(flags); cli();
-		
-	if (port->tty) 
-		clear_bit(TTY_IO_ERROR, &port->tty->flags);
-		
-#ifdef MODULE
-	if ((port->count == 1) && ((++bp->count) == 1))
-			bp->flags |= AURORA_BOARD_ACTIVE;
-#endif
-
-	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
-	aurora_change_speed(bp, port);
-	port->flags |= ASYNC_INITIALIZED;
-		
-	restore_flags(flags);
-#ifdef AURORA_DEBUG
-	printk("aurora_setup_port: end\n");
-#endif
-	return 0;
-}
-
-/* Must be called with interrupts disabled */
-static void aurora_shutdown_port(struct Aurora_board *bp, struct Aurora_port *port)
-{
-	struct tty_struct *tty;
-	unsigned char chip;
-
-#ifdef AURORA_DEBUG
-	printk("aurora_shutdown_port: start\n");
-#endif
-	if (!(port->flags & ASYNC_INITIALIZED)) 
-		return;
-	
-	chip = AURORA_CD180(port_No(port));
-	
-#ifdef AURORA_REPORT_OVERRUN
-	printk("aurora%d: port %d: Total %ld overruns were detected.\n",
-	       board_No(bp), port_No(port), port->overrun);
-#endif	
-#ifdef AURORA_REPORT_FIFO
-	{
-		int i;
-		
-		printk("aurora%d: port %d: FIFO hits [ ",
-		       board_No(bp), port_No(port));
-		for (i = 0; i < 10; i++)  {
-			printk("%ld ", port->hits[i]);
-		}
-		printk("].\n");
-	}
-#endif	
-	if (port->xmit_buf)  {
-		free_page((unsigned long) port->xmit_buf);
-		port->xmit_buf = NULL;
-	}
-
-	if (!(tty = port->tty) || C_HUPCL(tty))  {
-		/* Drop DTR */
-		port->MSVR &= ~(bp->DTR|bp->RTS);
-		sbus_writeb(port->MSVR,
-			    &bp->r[chip]->r[CD180_MSVR]);
-	}
-	
-        /* Select port */
-	sbus_writeb(port_No(port) & 7,
-		    &bp->r[chip]->r[CD180_CAR]);
-	udelay(1);
-
-	/* Reset port */
-	aurora_wait_CCR(bp->r[chip]);
-	sbus_writeb(CCR_SOFTRESET, &bp->r[chip]->r[CD180_CCR]);
-
-	/* Disable all interrupts from this port */
-	port->SRER = 0;
-	sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
-	
-	if (tty)  
-		set_bit(TTY_IO_ERROR, &tty->flags);
-	port->flags &= ~ASYNC_INITIALIZED;
-
-#ifdef MODULE
-	if (--bp->count < 0)  {
-		printk(KERN_DEBUG "aurora%d: aurora_shutdown_port: "
-		       "bad board count: %d\n",
-		       board_No(bp), bp->count);
-		bp->count = 0;
-	}
-	
-	if (!bp->count)
-		bp->flags &= ~AURORA_BOARD_ACTIVE;
-#endif
-
-#ifdef AURORA_DEBUG
-	printk("aurora_shutdown_port: end\n");
-#endif
-}
-
-	
-static int block_til_ready(struct tty_struct *tty, struct file * filp,
-			   struct Aurora_port *port)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	struct Aurora_board *bp = port_Board(port);
-	int    retval;
-	int    do_clocal = 0;
-	int    CD;
-	unsigned char chip;
-	
-#ifdef AURORA_DEBUG
-	printk("block_til_ready: start\n");
-#endif
-	chip = AURORA_CD180(port_No(port));
-
-	/* If the device is in the middle of being closed, then block
-	 * until it's done, and then try again.
-	 */
-	if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
-		interruptible_sleep_on(&port->close_wait);
-		if (port->flags & ASYNC_HUP_NOTIFY)
-			return -EAGAIN;
-		else
-			return -ERESTARTSYS;
-	}
-
-	/* If non-blocking mode is set, or the port is not enabled,
-	 * then make the check up front and then exit.
-	 */
-	if ((filp->f_flags & O_NONBLOCK) ||
-	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		port->flags |= ASYNC_NORMAL_ACTIVE;
-		return 0;
-	}
-
-	if (C_CLOCAL(tty))  
-		do_clocal = 1;
-
-	/* Block waiting for the carrier detect and the line to become
-	 * free (i.e., not in use by the callout).  While we are in
-	 * this loop, info->count is dropped by one, so that
-	 * rs_close() knows when to free things.  We restore it upon
-	 * exit, either normal or abnormal.
-	 */
-	retval = 0;
-	add_wait_queue(&port->open_wait, &wait);
-	cli();
-	if (!tty_hung_up_p(filp))
-		port->count--;
-	sti();
-	port->blocked_open++;
-	while (1) {
-		cli();
-		sbus_writeb(port_No(port) & 7,
-			    &bp->r[chip]->r[CD180_CAR]);
-		udelay(1);
-		CD = sbus_readb(&bp->r[chip]->r[CD180_MSVR]) & MSVR_CD;
-		port->MSVR=bp->RTS;
-
-		/* auto drops DTR */
-		sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]);
-		sti();
-		set_current_state(TASK_INTERRUPTIBLE);
-		if (tty_hung_up_p(filp) ||
-		    !(port->flags & ASYNC_INITIALIZED)) {
-			if (port->flags & ASYNC_HUP_NOTIFY)
-				retval = -EAGAIN;
-			else
-				retval = -ERESTARTSYS;	
-			break;
-		}
-		if (!(port->flags & ASYNC_CLOSING) &&
-		    (do_clocal || CD))
-			break;
-		if (signal_pending(current)) {
-			retval = -ERESTARTSYS;
-			break;
-		}
-		schedule();
-	}
-	current->state = TASK_RUNNING;
-	remove_wait_queue(&port->open_wait, &wait);
-	if (!tty_hung_up_p(filp))
-		port->count++;
-	port->blocked_open--;
-	if (retval)
-		return retval;
-	
-	port->flags |= ASYNC_NORMAL_ACTIVE;
-#ifdef AURORA_DEBUG
-	printk("block_til_ready: end\n");
-#endif
-	return 0;
-}	
-
-static int aurora_open(struct tty_struct * tty, struct file * filp)
-{
-	int board;
-	int error;
-	struct Aurora_port * port;
-	struct Aurora_board * bp;
-	unsigned long flags;
-	
-#ifdef AURORA_DEBUG
-	printk("aurora_open: start\n");
-#endif
-	
-	board = AURORA_BOARD(tty->index);
-	if (board > AURORA_NBOARD ||
-	    !(aurora_board[board].flags & AURORA_BOARD_PRESENT)) {
-#ifdef AURORA_DEBUG
-		printk("aurora_open: error board %d present %d\n",
-		       board, aurora_board[board].flags & AURORA_BOARD_PRESENT);
-#endif
-		return -ENODEV;
-	}
-	
-	bp = &aurora_board[board];
-	port = aurora_port + board * AURORA_NPORT * AURORA_NCD180 + AURORA_PORT(tty->index);
-	if ((aurora_paranoia_check(port, tty->name, "aurora_open")) {
-#ifdef AURORA_DEBUG
-		printk("aurora_open: error paranoia check\n");
-#endif
-		return -ENODEV;
-	}
-	
-	port->count++;
-	tty->driver_data = port;
-	port->tty = tty;
-	
-	if ((error = aurora_setup_port(bp, port))) {
-#ifdef AURORA_DEBUG
-		printk("aurora_open: error aurora_setup_port ret %d\n",error);
-#endif
-		return error;
-	}
-
-	if ((error = block_til_ready(tty, filp, port))) {
-#ifdef AURORA_DEBUG
-		printk("aurora_open: error block_til_ready ret %d\n",error);
-#endif
-		return error;
-	}
-	
-#ifdef AURORA_DEBUG
-	printk("aurora_open: end\n");
-#endif
-	return 0;
-}
-
-static void aurora_close(struct tty_struct * tty, struct file * filp)
-{
-	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-	struct Aurora_board *bp;
-	unsigned long flags;
-	unsigned long timeout;
-	unsigned char chip;
-	
-#ifdef AURORA_DEBUG
-	printk("aurora_close: start\n");
-#endif
-	
-	if (!port || (aurora_paranoia_check(port, tty->name, "close"))
-		return;
-	
-	chip = AURORA_CD180(port_No(port));
-
-	save_flags(flags); cli();
-	if (tty_hung_up_p(filp))  {
-		restore_flags(flags);
-		return;
-	}
-	
-	bp = port_Board(port);
-	if ((tty->count == 1) && (port->count != 1))  {
-		printk(KERN_DEBUG "aurora%d: aurora_close: bad port count; "
-		       "tty->count is 1, port count is %d\n",
-		       board_No(bp), port->count);
-		port->count = 1;
-	}
-	if (--port->count < 0)  {
-		printk(KERN_DEBUG "aurora%d: aurora_close: bad port "
-		       "count for tty%d: %d\n",
-		       board_No(bp), port_No(port), port->count);
-		port->count = 0;
-	}
-	if (port->count)  {
-		restore_flags(flags);
-		return;
-	}
-	port->flags |= ASYNC_CLOSING;
-
-	/* Now we wait for the transmit buffer to clear; and we notify 
-	 * the line discipline to only process XON/XOFF characters.
-	 */
-	tty->closing = 1;
-	if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE){
-#ifdef AURORA_DEBUG
-		printk("aurora_close: waiting to flush...\n");
-#endif
-		tty_wait_until_sent(tty, port->closing_wait);
-	}
-
-	/* At this point we stop accepting input.  To do this, we
-	 * disable the receive line status interrupts, and tell the
-	 * interrupt driver to stop checking the data ready bit in the
-	 * line status register.
-	 */
-	port->SRER &= ~SRER_RXD;
-	if (port->flags & ASYNC_INITIALIZED) {
-		port->SRER &= ~SRER_TXRDY;
-		port->SRER |= SRER_TXEMPTY;
-		sbus_writeb(port_No(port) & 7,
-			    &bp->r[chip]->r[CD180_CAR]);
-		udelay(1);
-		sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
-		/*
-		 * Before we drop DTR, make sure the UART transmitter
-		 * has completely drained; this is especially
-		 * important if there is a transmit FIFO!
-		 */
-		timeout = jiffies+HZ;
-		while(port->SRER & SRER_TXEMPTY)  {
-			msleep_interruptible(jiffies_to_msecs(port->timeout));
-			if (time_after(jiffies, timeout))
-				break;
-		}
-	}
-#ifdef AURORA_DEBUG
-	printk("aurora_close: shutdown_port\n");
-#endif
-	aurora_shutdown_port(bp, port);
-	if (tty->driver->flush_buffer)
-		tty->driver->flush_buffer(tty);
-	tty_ldisc_flush(tty);
-	tty->closing = 0;
-	port->event = 0;
-	port->tty = 0;
-	if (port->blocked_open) {
-		if (port->close_delay) {
-			msleep_interruptible(jiffies_to_msecs(port->close_delay));
-		}
-		wake_up_interruptible(&port->open_wait);
-	}
-	port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
-	wake_up_interruptible(&port->close_wait);
-	restore_flags(flags);
-#ifdef AURORA_DEBUG
-	printk("aurora_close: end\n");
-#endif
-}
-
-static int aurora_write(struct tty_struct * tty, 
-			const unsigned char *buf, int count)
-{
-	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-	struct Aurora_board *bp;
-	int c, total = 0;
-	unsigned long flags;
-	unsigned char chip;
-
-#ifdef AURORA_DEBUG
-	printk("aurora_write: start %d\n",count);
-#endif
-	if ((aurora_paranoia_check(port, tty->name, "aurora_write"))
-		return 0;
-		
-	chip = AURORA_CD180(port_No(port));
-	
-	bp = port_Board(port);
-
-	if (!tty || !port->xmit_buf || !tmp_buf)
-		return 0;
-
-	save_flags(flags);
-	while (1) {
-		cli();
-		c = min(count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
-				   SERIAL_XMIT_SIZE - port->xmit_head));
-		if (c <= 0) {
-			restore_flags(flags);
-			break;
-		}
-		memcpy(port->xmit_buf + port->xmit_head, buf, c);
-		port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
-		port->xmit_cnt += c;
-		restore_flags(flags);
-
-		buf += c;
-		count -= c;
-		total += c;
-	}
-
-	cli();
-	if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
-	    !(port->SRER & SRER_TXRDY)) {
-		port->SRER |= SRER_TXRDY;
-		sbus_writeb(port_No(port) & 7,
-			    &bp->r[chip]->r[CD180_CAR]);
-		udelay(1);
-		sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
-	}
-	restore_flags(flags);
-#ifdef AURORA_DEBUG
-	printk("aurora_write: end %d\n",total);
-#endif
-	return total;
-}
-
-static void aurora_put_char(struct tty_struct * tty, unsigned char ch)
-{
-	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-	unsigned long flags;
-
-#ifdef AURORA_DEBUG
-	printk("aurora_put_char: start %c\n",ch);
-#endif
-	if ((aurora_paranoia_check(port, tty->name, "aurora_put_char"))
-		return;
-
-	if (!tty || !port->xmit_buf)
-		return;
-
-	save_flags(flags); cli();
-	
-	if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
-		restore_flags(flags);
-		return;
-	}
-
-	port->xmit_buf[port->xmit_head++] = ch;
-	port->xmit_head &= SERIAL_XMIT_SIZE - 1;
-	port->xmit_cnt++;
-	restore_flags(flags);
-#ifdef AURORA_DEBUG
-	printk("aurora_put_char: end\n");
-#endif
-}
-
-static void aurora_flush_chars(struct tty_struct * tty)
-{
-	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-	unsigned long flags;
-	unsigned char chip;
-
-/*#ifdef AURORA_DEBUG
-	printk("aurora_flush_chars: start\n");
-#endif*/
-	if ((aurora_paranoia_check(port, tty->name, "aurora_flush_chars"))
-		return;
-		
-	chip = AURORA_CD180(port_No(port));
-	
-	if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
-	    !port->xmit_buf)
-		return;
-
-	save_flags(flags); cli();
-	port->SRER |= SRER_TXRDY;
-	sbus_writeb(port_No(port) & 7,
-		    &port_Board(port)->r[chip]->r[CD180_CAR]);
-	udelay(1);
-	sbus_writeb(port->SRER,
-		    &port_Board(port)->r[chip]->r[CD180_SRER]);
-	restore_flags(flags);
-/*#ifdef AURORA_DEBUG
-	printk("aurora_flush_chars: end\n");
-#endif*/
-}
-
-static int aurora_write_room(struct tty_struct * tty)
-{
-	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-	int	ret;
-
-#ifdef AURORA_DEBUG
-	printk("aurora_write_room: start\n");
-#endif
-	if ((aurora_paranoia_check(port, tty->name, "aurora_write_room"))
-		return 0;
-
-	ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
-	if (ret < 0)
-		ret = 0;
-#ifdef AURORA_DEBUG
-	printk("aurora_write_room: end\n");
-#endif
-	return ret;
-}
-
-static int aurora_chars_in_buffer(struct tty_struct *tty)
-{
-	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-				
-	if ((aurora_paranoia_check(port, tty->name, "aurora_chars_in_buffer"))
-		return 0;
-	
-	return port->xmit_cnt;
-}
-
-static void aurora_flush_buffer(struct tty_struct *tty)
-{
-	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-	unsigned long flags;
-
-#ifdef AURORA_DEBUG
-	printk("aurora_flush_buffer: start\n");
-#endif
-	if ((aurora_paranoia_check(port, tty->name, "aurora_flush_buffer"))
-		return;
-
-	save_flags(flags); cli();
-	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
-	restore_flags(flags);
-	
-	tty_wakeup(tty);
-#ifdef AURORA_DEBUG
-	printk("aurora_flush_buffer: end\n");
-#endif
-}
-
-static int aurora_tiocmget(struct tty_struct *tty, struct file *file)
-{
-	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-	struct Aurora_board * bp;
-	unsigned char status,chip;
-	unsigned int result;
-	unsigned long flags;
-
-#ifdef AURORA_DEBUG
-	printk("aurora_get_modem_info: start\n");
-#endif
-	if ((aurora_paranoia_check(port, tty->name, __FUNCTION__))
-		return -ENODEV;
-
-	chip = AURORA_CD180(port_No(port));
-
-	bp = port_Board(port);
-
-	save_flags(flags); cli();
-
-	sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]);
-	udelay(1);
-
-	status = sbus_readb(&bp->r[chip]->r[CD180_MSVR]);
-	result = 0/*bp->r[chip]->r[AURORA_RI] & (1u << port_No(port)) ? 0 : TIOCM_RNG*/;
-
-	restore_flags(flags);
-
-	result |= ((status & bp->RTS) ? TIOCM_RTS : 0)
-		| ((status & bp->DTR) ? TIOCM_DTR : 0)
-		| ((status & MSVR_CD)  ? TIOCM_CAR : 0)
-		| ((status & MSVR_DSR) ? TIOCM_DSR : 0)
-		| ((status & MSVR_CTS) ? TIOCM_CTS : 0);
-
-#ifdef AURORA_DEBUG
-	printk("aurora_get_modem_info: end\n");
-#endif
-	return result;
-}
-
-static int aurora_tiocmset(struct tty_struct *tty, struct file *file,
-			   unsigned int set, unsigned int clear)
-{
-	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-	unsigned int arg;
-	unsigned long flags;
-	struct Aurora_board *bp = port_Board(port);
-	unsigned char chip;
-
-#ifdef AURORA_DEBUG
-	printk("aurora_set_modem_info: start\n");
-#endif
-	if ((aurora_paranoia_check(port, tty->name, __FUNCTION__))
-		return -ENODEV;
-
-	chip = AURORA_CD180(port_No(port));
-
-	save_flags(flags); cli();
-	if (set & TIOCM_RTS)
-		port->MSVR |= bp->RTS;
-	if (set & TIOCM_DTR)
-		port->MSVR |= bp->DTR;
-	if (clear & TIOCM_RTS)
-		port->MSVR &= ~bp->RTS;
-	if (clear & TIOCM_DTR)
-		port->MSVR &= ~bp->DTR;
-
-	sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]);
-	udelay(1);
-
-	sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]);
-
-	restore_flags(flags);
-#ifdef AURORA_DEBUG
-	printk("aurora_set_modem_info: end\n");
-#endif
-	return 0;
-}
-
-static void aurora_send_break(struct Aurora_port * port, unsigned long length)
-{
-	struct Aurora_board *bp = port_Board(port);
-	unsigned long flags;
-	unsigned char chip;
-	
-#ifdef AURORA_DEBUG
-	printk("aurora_send_break: start\n");
-#endif
-	chip = AURORA_CD180(port_No(port));
-	
-	save_flags(flags); cli();
-
-	port->break_length = AURORA_TPS / HZ * length;
-	port->COR2 |= COR2_ETC;
-	port->SRER  |= SRER_TXRDY;
-	sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]);
-	udelay(1);
-
-	sbus_writeb(port->COR2, &bp->r[chip]->r[CD180_COR2]);
-	sbus_writeb(port->SRER, &bp->r[chip]->r[CD180_SRER]);
-	aurora_wait_CCR(bp->r[chip]);
-
-	sbus_writeb(CCR_CORCHG2, &bp->r[chip]->r[CD180_CCR]);
-	aurora_wait_CCR(bp->r[chip]);
-
-	restore_flags(flags);
-#ifdef AURORA_DEBUG
-	printk("aurora_send_break: end\n");
-#endif
-}
-
-static int aurora_set_serial_info(struct Aurora_port * port,
-				  struct serial_struct * newinfo)
-{
-	struct serial_struct tmp;
-	struct Aurora_board *bp = port_Board(port);
-	int change_speed;
-	unsigned long flags;
-
-#ifdef AURORA_DEBUG
-	printk("aurora_set_serial_info: start\n");
-#endif
-	if (copy_from_user(&tmp, newinfo, sizeof(tmp)))
-		return -EFAULT;
-#if 0	
-	if ((tmp.irq != bp->irq) ||
-	    (tmp.port != bp->base) ||
-	    (tmp.type != PORT_CIRRUS) ||
-	    (tmp.baud_base != (bp->oscfreq + CD180_TPC/2) / CD180_TPC) ||
-	    (tmp.custom_divisor != 0) ||
-	    (tmp.xmit_fifo_size != CD180_NFIFO) ||
-	    (tmp.flags & ~AURORA_LEGAL_FLAGS))
-		return -EINVAL;
-#endif	
-	
-	change_speed = ((port->flags & ASYNC_SPD_MASK) !=
-			(tmp.flags & ASYNC_SPD_MASK));
-	
-	if (!capable(CAP_SYS_ADMIN)) {
-		if ((tmp.close_delay != port->close_delay) ||
-		    (tmp.closing_wait != port->closing_wait) ||
-		    ((tmp.flags & ~ASYNC_USR_MASK) !=
-		     (port->flags & ~ASYNC_USR_MASK)))  
-			return -EPERM;
-		port->flags = ((port->flags & ~ASYNC_USR_MASK) |
-			       (tmp.flags & ASYNC_USR_MASK));
-	} else  {
-		port->flags = ((port->flags & ~ASYNC_FLAGS) |
-			       (tmp.flags & ASYNC_FLAGS));
-		port->close_delay = tmp.close_delay;
-		port->closing_wait = tmp.closing_wait;
-	}
-	if (change_speed)  {
-		save_flags(flags); cli();
-		aurora_change_speed(bp, port);
-		restore_flags(flags);
-	}
-#ifdef AURORA_DEBUG
-	printk("aurora_set_serial_info: end\n");
-#endif
-	return 0;
-}
-
-extern int aurora_get_serial_info(struct Aurora_port * port,
-				  struct serial_struct * retinfo)
-{
-	struct serial_struct tmp;
-	struct Aurora_board *bp = port_Board(port);
-	
-#ifdef AURORA_DEBUG
-	printk("aurora_get_serial_info: start\n");
-#endif
-	if (!access_ok(VERIFY_WRITE, (void *) retinfo, sizeof(tmp)))
-		return -EFAULT;
-	
-	memset(&tmp, 0, sizeof(tmp));
-	tmp.type = PORT_CIRRUS;
-	tmp.line = port - aurora_port;
-	tmp.port = 0;
-	tmp.irq  = bp->irq;
-	tmp.flags = port->flags;
-	tmp.baud_base = (bp->oscfreq + CD180_TPC/2) / CD180_TPC;
-	tmp.close_delay = port->close_delay * HZ/100;
-	tmp.closing_wait = port->closing_wait * HZ/100;
-	tmp.xmit_fifo_size = CD180_NFIFO;
-	copy_to_user(retinfo, &tmp, sizeof(tmp));
-#ifdef AURORA_DEBUG
-printk("aurora_get_serial_info: end\n");
-#endif
-	return 0;
-}
-
-static int aurora_ioctl(struct tty_struct * tty, struct file * filp, 
-		    unsigned int cmd, unsigned long arg)
-		    
-{
-	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-	int retval;
-
-#ifdef AURORA_DEBUG
-	printk("aurora_ioctl: start\n");
-#endif
-	if ((aurora_paranoia_check(port, tty->name, "aurora_ioctl"))
-		return -ENODEV;
-	
-	switch (cmd) {
-	case TCSBRK:	/* SVID version: non-zero arg --> no break */
-		retval = tty_check_change(tty);
-		if (retval)
-			return retval;
-		tty_wait_until_sent(tty, 0);
-		if (!arg)
-			aurora_send_break(port, HZ/4);	/* 1/4 second */
-		return 0;
-	case TCSBRKP:	/* support for POSIX tcsendbreak() */
-		retval = tty_check_change(tty);
-		if (retval)
-			return retval;
-		tty_wait_until_sent(tty, 0);
-		aurora_send_break(port, arg ? arg*(HZ/10) : HZ/4);
-		return 0;
-	case TIOCGSOFTCAR:
-		return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *)arg);
-	case TIOCSSOFTCAR:
-		if (get_user(arg,(unsigned long *)arg))
-			return -EFAULT;
-		tty->termios->c_cflag =
-			((tty->termios->c_cflag & ~CLOCAL) |
-			 (arg ? CLOCAL : 0));
-		return 0;
-	case TIOCGSERIAL:	
-		return aurora_get_serial_info(port, (struct serial_struct *) arg);
-	case TIOCSSERIAL:	
-		return aurora_set_serial_info(port, (struct serial_struct *) arg);
-	default:
-		return -ENOIOCTLCMD;
-	};
-#ifdef AURORA_DEBUG
-	printk("aurora_ioctl: end\n");
-#endif
-	return 0;
-}
-
-static void aurora_throttle(struct tty_struct * tty)
-{
-	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-	struct Aurora_board *bp;
-	unsigned long flags;
-	unsigned char chip;
-
-#ifdef AURORA_DEBUG
-	printk("aurora_throttle: start\n");
-#endif
-	if ((aurora_paranoia_check(port, tty->name, "aurora_throttle"))
-		return;
-	
-	bp = port_Board(port);
-	chip = AURORA_CD180(port_No(port));
-	
-	save_flags(flags); cli();
-	port->MSVR &= ~bp->RTS;
-	sbus_writeb(port_No(port) & 7, &bp->r[chip]->r[CD180_CAR]);
-	udelay(1);
-	if (I_IXOFF(tty))  {
-		aurora_wait_CCR(bp->r[chip]);
-		sbus_writeb(CCR_SSCH2, &bp->r[chip]->r[CD180_CCR]);
-		aurora_wait_CCR(bp->r[chip]);
-	}
-	sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]);
-	restore_flags(flags);
-#ifdef AURORA_DEBUG
-	printk("aurora_throttle: end\n");
-#endif
-}
-
-static void aurora_unthrottle(struct tty_struct * tty)
-{
-	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-	struct Aurora_board *bp;
-	unsigned long flags;
-	unsigned char chip;
-
-#ifdef AURORA_DEBUG
-	printk("aurora_unthrottle: start\n");
-#endif
-	if ((aurora_paranoia_check(port, tty->name, "aurora_unthrottle"))
-		return;
-	
-	bp = port_Board(port);
-	
-	chip = AURORA_CD180(port_No(port));
-	
-	save_flags(flags); cli();
-	port->MSVR |= bp->RTS;
-	sbus_writeb(port_No(port) & 7,
-		    &bp->r[chip]->r[CD180_CAR]);
-	udelay(1);
-	if (I_IXOFF(tty))  {
-		aurora_wait_CCR(bp->r[chip]);
-		sbus_writeb(CCR_SSCH1,
-			    &bp->r[chip]->r[CD180_CCR]);
-		aurora_wait_CCR(bp->r[chip]);
-	}
-	sbus_writeb(port->MSVR, &bp->r[chip]->r[CD180_MSVR]);
-	restore_flags(flags);
-#ifdef AURORA_DEBUG
-	printk("aurora_unthrottle: end\n");
-#endif
-}
-
-static void aurora_stop(struct tty_struct * tty)
-{
-	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-	struct Aurora_board *bp;
-	unsigned long flags;
-	unsigned char chip;
-
-#ifdef AURORA_DEBUG
-	printk("aurora_stop: start\n");
-#endif
-	if ((aurora_paranoia_check(port, tty->name, "aurora_stop"))
-		return;
-	
-	bp = port_Board(port);
-	
-	chip = AURORA_CD180(port_No(port));
-	
-	save_flags(flags); cli();
-	port->SRER &= ~SRER_TXRDY;
-	sbus_writeb(port_No(port) & 7,
-		    &bp->r[chip]->r[CD180_CAR]);
-	udelay(1);
-	sbus_writeb(port->SRER,
-		    &bp->r[chip]->r[CD180_SRER]);
-	restore_flags(flags);
-#ifdef AURORA_DEBUG
-	printk("aurora_stop: end\n");
-#endif
-}
-
-static void aurora_start(struct tty_struct * tty)
-{
-	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-	struct Aurora_board *bp;
-	unsigned long flags;
-	unsigned char chip;
-
-#ifdef AURORA_DEBUG
-	printk("aurora_start: start\n");
-#endif
-	if ((aurora_paranoia_check(port, tty->name, "aurora_start"))
-		return;
-	
-	bp = port_Board(port);
-	
-	chip = AURORA_CD180(port_No(port));
-	
-	save_flags(flags); cli();
-	if (port->xmit_cnt && port->xmit_buf && !(port->SRER & SRER_TXRDY))  {
-		port->SRER |= SRER_TXRDY;
-		sbus_writeb(port_No(port) & 7,
-			    &bp->r[chip]->r[CD180_CAR]);
-		udelay(1);
-		sbus_writeb(port->SRER,
-			    &bp->r[chip]->r[CD180_SRER]);
-	}
-	restore_flags(flags);
-#ifdef AURORA_DEBUG
-	printk("aurora_start: end\n");
-#endif
-}
-
-/*
- * This routine is called from the scheduler tqueue when the interrupt
- * routine has signalled that a hangup has occurred.  The path of
- * hangup processing is:
- *
- * 	serial interrupt routine -> (scheduler tqueue) ->
- * 	do_aurora_hangup() -> tty->hangup() -> aurora_hangup()
- * 
- */
-static void do_aurora_hangup(void *private_)
-{
-	struct Aurora_port	*port = (struct Aurora_port *) private_;
-	struct tty_struct	*tty;
-
-#ifdef AURORA_DEBUG
-	printk("do_aurora_hangup: start\n");
-#endif
-	tty = port->tty;
-	if (tty != NULL) {
-		tty_hangup(tty);	/* FIXME: module removal race - AKPM */
-#ifdef AURORA_DEBUG
-		printk("do_aurora_hangup: end\n");
-#endif
-	}
-}
-
-static void aurora_hangup(struct tty_struct * tty)
-{
-	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-	struct Aurora_board *bp;
-				
-#ifdef AURORA_DEBUG
-	printk("aurora_hangup: start\n");
-#endif
-	if ((aurora_paranoia_check(port, tty->name, "aurora_hangup"))
-		return;
-	
-	bp = port_Board(port);
-	
-	aurora_shutdown_port(bp, port);
-	port->event = 0;
-	port->count = 0;
-	port->flags &= ~ASYNC_NORMAL_ACTIVE;
-	port->tty = 0;
-	wake_up_interruptible(&port->open_wait);
-#ifdef AURORA_DEBUG
-	printk("aurora_hangup: end\n");
-#endif
-}
-
-static void aurora_set_termios(struct tty_struct * tty, struct termios * old_termios)
-{
-	struct Aurora_port *port = (struct Aurora_port *) tty->driver_data;
-	unsigned long flags;
-
-#ifdef AURORA_DEBUG
-	printk("aurora_set_termios: start\n");
-#endif
-	if ((aurora_paranoia_check(port, tty->name, "aurora_set_termios"))
-		return;
-	
-	if (tty->termios->c_cflag == old_termios->c_cflag &&
-	    tty->termios->c_iflag == old_termios->c_iflag)
-		return;
-
-	save_flags(flags); cli();
-	aurora_change_speed(port_Board(port), port);
-	restore_flags(flags);
-
-	if ((old_termios->c_cflag & CRTSCTS) &&
-	    !(tty->termios->c_cflag & CRTSCTS)) {
-		tty->hw_stopped = 0;
-		aurora_start(tty);
-	}
-#ifdef AURORA_DEBUG
-	printk("aurora_set_termios: end\n");
-#endif
-}
-
-static void do_aurora_bh(void)
-{
-	 run_task_queue(&tq_aurora);
-}
-
-static void do_softint(void *private_)
-{
-	struct Aurora_port	*port = (struct Aurora_port *) private_;
-	struct tty_struct	*tty;
-
-#ifdef AURORA_DEBUG
-	printk("do_softint: start\n");
-#endif
-	tty = port->tty;
-	if (tty == NULL)
-		return;
-
-	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
-		tty_wakeup(tty);
-	}
-#ifdef AURORA_DEBUG
-	printk("do_softint: end\n");
-#endif
-}
-
-static const struct tty_operations aurora_ops = {
-	.open  = aurora_open,
-	.close = aurora_close,
-	.write = aurora_write,
-	.put_char = aurora_put_char,
-	.flush_chars = aurora_flush_chars,
-	.write_room = aurora_write_room,
-	.chars_in_buffer = aurora_chars_in_buffer,
-	.flush_buffer = aurora_flush_buffer,
-	.ioctl = aurora_ioctl,
-	.throttle = aurora_throttle,
-	.unthrottle = aurora_unthrottle,
-	.set_termios = aurora_set_termios,
-	.stop = aurora_stop,
-	.start = aurora_start,
-	.hangup = aurora_hangup,
-	.tiocmget = aurora_tiocmget,
-	.tiocmset = aurora_tiocmset,
-};
-
-static int aurora_init_drivers(void)
-{
-	int error;
-	int i;
-
-#ifdef AURORA_DEBUG
-	printk("aurora_init_drivers: start\n");
-#endif
-	tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL);
-	if (tmp_buf == NULL) {
-		printk(KERN_ERR "aurora: Couldn't get free page.\n");
-		return 1;
-	}
-	init_bh(AURORA_BH, do_aurora_bh);
-	aurora_driver = alloc_tty_driver(AURORA_INPORTS);
-	if (!aurora_driver) {
-		printk(KERN_ERR "aurora: Couldn't allocate tty driver.\n");
-		free_page((unsigned long) tmp_buf);
-		return 1;
-	}
-	aurora_driver->owner = THIS_MODULE;
-	aurora_driver->name = "ttyA";
-	aurora_driver->major = AURORA_MAJOR;
-	aurora_driver->type = TTY_DRIVER_TYPE_SERIAL;
-	aurora_driver->subtype = SERIAL_TYPE_NORMAL;
-	aurora_driver->init_termios = tty_std_termios;
-	aurora_driver->init_termios.c_cflag =
-		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-	aurora_driver->flags = TTY_DRIVER_REAL_RAW;
-	tty_set_operations(aurora_driver, &aurora_ops);
-	error = tty_register_driver(aurora_driver);
-	if (error) {
-		put_tty_driver(aurora_driver);
-		free_page((unsigned long) tmp_buf);
-		printk(KERN_ERR "aurora: Couldn't register aurora driver, error = %d\n",
-		       error);
-		return 1;
-	}
-	
-	memset(aurora_port, 0, sizeof(aurora_port));
-	for (i = 0; i < AURORA_TNPORTS; i++)  {
-		aurora_port[i].magic = AURORA_MAGIC;
-		aurora_port[i].tqueue.routine = do_softint;
-		aurora_port[i].tqueue.data = &aurora_port[i];
-		aurora_port[i].tqueue_hangup.routine = do_aurora_hangup;
-		aurora_port[i].tqueue_hangup.data = &aurora_port[i];
-		aurora_port[i].close_delay = 50 * HZ/100;
-		aurora_port[i].closing_wait = 3000 * HZ/100;
-		init_waitqueue_head(&aurora_port[i].open_wait);
-		init_waitqueue_head(&aurora_port[i].close_wait);
-	}
-#ifdef AURORA_DEBUG
-	printk("aurora_init_drivers: end\n");
-#endif
-	return 0;
-}
-
-static void aurora_release_drivers(void)
-{
-#ifdef AURORA_DEBUG
-	printk("aurora_release_drivers: start\n");
-#endif
-	free_page((unsigned long)tmp_buf);
-	tty_unregister_driver(aurora_driver);
-	put_tty_driver(aurora_driver);
-#ifdef AURORA_DEBUG
-	printk("aurora_release_drivers: end\n");
-#endif
-}
-
-/*
- * Called at boot time.
- *
- * You can specify IO base for up to RC_NBOARD cards,
- * using line "riscom8=0xiobase1,0xiobase2,.." at LILO prompt.
- * Note that there will be no probing at default
- * addresses in this case.
- *
- */
-void __init aurora_setup(char *str, int *ints)
-{
-	int i;
-
-	for(i=0;(i<ints[0])&&(i<4);i++) {
-		if (ints[i+1]) irqs[i]=ints[i+1];
-		}
-}
-
-static int __init aurora_real_init(void)
-{
-	int found;
-	int i;
-
-	printk(KERN_INFO "aurora: Driver starting.\n");
-	if(aurora_init_drivers())
-		return -EIO;
-	found = aurora_probe();
-	if(!found) {
-		aurora_release_drivers();
-		printk(KERN_INFO "aurora: No Aurora Multiport boards detected.\n");
-		return -EIO;
-	} else {
-		printk(KERN_INFO "aurora: %d boards found.\n", found);
-	}
-	for (i = 0; i < found; i++) {
-		int ret = aurora_setup_board(&aurora_board[i]);
-
-		if (ret) {
-#ifdef AURORA_DEBUG
-			printk(KERN_ERR "aurora_init: error aurora_setup_board ret %d\n",
-			       ret);
-#endif
-			return ret;
-		}
-	}
-	return 0;
-}
-
-int irq  = 0;
-int irq1 = 0;
-int irq2 = 0;
-int irq3 = 0;
-module_param(irq , int, 0);
-module_param(irq1, int, 0);
-module_param(irq2, int, 0);
-module_param(irq3, int, 0);
-
-static int __init aurora_init(void) 
-{
-	if (irq ) irqs[0]=irq ;
-	if (irq1) irqs[1]=irq1;
-	if (irq2) irqs[2]=irq2;
-	if (irq3) irqs[3]=irq3;
-	return aurora_real_init();
-}
-	
-static void __exit aurora_cleanup(void)
-{
-	int i;
-	
-#ifdef AURORA_DEBUG
-printk("cleanup_module: aurora_release_drivers\n");
-#endif
-
-	aurora_release_drivers();
-	for (i = 0; i < AURORA_NBOARD; i++)
-		if (aurora_board[i].flags & AURORA_BOARD_PRESENT) {
-			aurora_shutdown_board(&aurora_board[i]);
-			aurora_release_io_range(&aurora_board[i]);
-		}
-}
-
-module_init(aurora_init);
-module_exit(aurora_cleanup);
-MODULE_LICENSE("GPL");
diff --git a/drivers/sbus/char/aurora.h b/drivers/sbus/char/aurora.h
deleted file mode 100644
index b8b5476d..0000000
--- a/drivers/sbus/char/aurora.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/*	$Id: aurora.h,v 1.6 2001/06/05 12:23:38 davem Exp $
- *	linux/drivers/sbus/char/aurora.h -- Aurora multiport driver
- *
- *	Copyright (c) 1999 by Oliver Aldulea (oli@bv.ro)
- *
- *	This code is based on the RISCom/8 multiport serial driver written
- *	by Dmitry Gorodchanin (pgmdsg@ibi.com), based on the Linux serial
- *	driver, written by Linus Torvalds, Theodore T'so and others.
- *	The Aurora multiport programming info was obtained mainly from the
- *	Cirrus Logic CD180 documentation (available on the web), and by
- *	doing heavy tests on the board. Many thanks to Eddie C. Dost for the
- *	help on the sbus interface.
- *
- *	This program is free software; you can redistribute it and/or modify
- *	it under the terms of the 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.
- *
- *	Revision 1.0
- *
- *	This is the first public release.
- *
- *	This version needs a lot of feedback. This is the version that works
- *	with _my_ board. My board is model 1600se, revision '@(#)1600se.fth
- *	1.2 3/28/95 1'. The driver might work with your board, but I do not
- *	guarantee it. If you have _any_ type of board, I need to know if the
- *	driver works or not, I need to know exactly your board parameters
- *	(get them with 'cd /proc/openprom/iommu/sbus/sio16/; ls *; cat *')
- *	Also, I need your board revision code, which is written on the board.
- *	Send me the output of my driver too (it outputs through klogd).
- *
- *	If the driver does not work, you can try enabling the debug options
- *	to see what's wrong or what should be done.
- *
- *	I'm sorry about the alignment of the code. It was written in a
- *	128x48 environment.
- *
- *	I must say that I do not like Aurora Technologies' policy. I asked
- *	them to help me do this driver faster, but they ended by something
- *	like "don't call us, we'll call you", and I never heard anything
- *	from them. They told me "knowing the way the board works, I don't
- *	doubt you and others on the net will make the driver."
- *	The truth about this board is that it has nothing intelligent on it.
- *	If you want to say to somebody what kind of board you have, say that
- *	it uses Cirrus Logic processors (CD180). The power of the board is
- *	in those two chips. The rest of the board is the interface to the
- *	sbus and to the peripherals. Still, they did something smart: they
- *	reversed DTR and RTS to make on-board automatic hardware flow
- *	control usable.
- *	Thanks to Aurora Technologies for wasting my time, nerves and money.
- */
-
-#ifndef __LINUX_AURORA_H
-#define __LINUX_AURORA_H
-
-#include <linux/serial.h>
-#include <linux/serialP.h>
-
-#ifdef __KERNEL__
-
-/* This is the number of boards to support. I've only tested this driver with
- * one board, so it might not work.
- */
-#define AURORA_NBOARD 1
-
-/* Useful ? Yes. But you can safely comment the warnings if they annoy you
- * (let me say that again: the warnings in the code, not this define). 
- */
-#define AURORA_PARANOIA_CHECK
-
-/* Well, after many lost nights, I found that the IRQ for this board is
- * selected from four built-in values by writing some bits in the
- * configuration register. This causes a little problem to occur: which
- * IRQ to select ? Which one is the best for the user ? Well, I finally
- * decided for the following algorithm: if the "bintr" value is not acceptable
- * (not within type_1_irq[], then test the "intr" value, if that fails too,
- * try each value from type_1_irq until succeded. Hope it's ok.
- * You can safely reorder the irq's.
- */
-#define TYPE_1_IRQS 4
-unsigned char type_1_irq[TYPE_1_IRQS] = {
-	3, 5, 9, 13
-};
-/* I know something about another method of interrupt setting, but not enough.
- * Also, this is for another type of board, so I first have to learn how to
- * detect it.
-#define TYPE_2_IRQS 3
-unsigned char type_2_irq[TYPE_2_IRQS] = {
-	0, 0, 0 ** could anyone find these for me ? (see AURORA_ALLIRQ below) **
-	};
-unsigned char type_2_mask[TYPE_2_IRQS] = {
-	32, 64, 128
-	};
-*/
-
-/* The following section should only be modified by those who know what
- * they're doing (or don't, but want to help with some feedback). Modifying
- * anything raises a _big_ probability for your system to hang, but the
- * sacrifice worths. (I sacrificed my ext2fs many, many times...)
- */
-
-/* This one tries to dump to console the name of almost every function called,
- * and many other debugging info.
- */
-#undef AURORA_DEBUG
-
-/* These are the most dangerous and useful defines. They do printk() during
- * the interrupt processing routine(s), so if you manage to get "flooded" by
- * irq's, start thinking about the "Power off/on" button...
- */
-#undef AURORA_INTNORM	/* This one enables the "normal" messages, but some
-			 * of them cause flood, so I preffered putting
-			 * them under a define */
-#undef AURORA_INT_DEBUG /* This one is really bad. */
-
-/* Here's something helpful: after n irq's, the board will be disabled. This
- * prevents irq flooding during debug (no need to think about power
- * off/on anymore...)
- */
-#define AURORA_FLOODPRO	10
-
-/* This one helps finding which irq the board calls, in case of a strange/
- * unsupported board. AURORA_INT_DEBUG should be enabled, because I don't
- * think /proc/interrupts or any command will be available in case of an irq
- * flood... "allirq" is the list of all free irq's.
- */
-/*
-#define AURORA_ALLIRQ 6
-int allirq[AURORA_ALLIRQ]={
-	2,3,5,7,9,13
-	};
-*/
-
-/* These must not be modified. These values are assumed during the code for
- * performance optimisations.
- */
-#define AURORA_NCD180 2 /* two chips per board */
-#define AURORA_NPORT 8  /* 8 ports per chip */
-
-/* several utilities */
-#define AURORA_BOARD(line)	(((line) >> 4) & 0x01)
-#define AURORA_CD180(line)	(((line) >> 3) & 0x01)
-#define AURORA_PORT(line)	((line) & 15)
-
-#define AURORA_TNPORTS (AURORA_NBOARD*AURORA_NCD180*AURORA_NPORT)
-
-/* Ticks per sec. Used for setting receiver timeout and break length */
-#define AURORA_TPS		4000
-
-#define AURORA_MAGIC	0x0A18
-
-/* Yeah, after heavy testing I decided it must be 6.
- * Sure, You can change it if needed.
- */
-#define AURORA_RXFIFO		6	/* Max. receiver FIFO size (1-8) */
-
-#define AURORA_RXTH		7
-
-struct aurora_reg1 {
-	__volatile__ unsigned char r;
-};
-
-struct aurora_reg128 {
-	__volatile__ unsigned char r[128];
-};
-	
-struct aurora_reg4 {
-	__volatile__ unsigned char r[4];
-};
-
-struct Aurora_board {
-	unsigned long		flags;
-	struct aurora_reg1	* r0;	/* This is the board configuration
-					 * register (write-only). */
-	struct aurora_reg128	* r[2];	/* These are the registers for the
-					 * two chips. */
-	struct aurora_reg4	* r3;	/* These are used for hardware-based
-					 * acknowledge. Software-based ack is
-					 * not supported by CD180. */
-	unsigned int		oscfreq; /* The on-board oscillator
-					  * frequency, in Hz. */
-	unsigned char		irq;
-#ifdef MODULE
-	signed char		count;	/* counts the use of the board */
-#endif
-	/* Values for the dtr_rts swapped mode. */
-	unsigned char		DTR;
-	unsigned char		RTS;
-	unsigned char		MSVDTR;
-	unsigned char		MSVRTS;
-	/* Values for hardware acknowledge. */
-	unsigned char		ACK_MINT, ACK_TINT, ACK_RINT;
-};
-
-/* Board configuration register */
-#define AURORA_CFG_ENABLE_IO	8
-#define AURORA_CFG_ENABLE_IRQ	4
-
-/* Board flags */
-#define AURORA_BOARD_PRESENT		0x00000001
-#define AURORA_BOARD_ACTIVE		0x00000002
-#define AURORA_BOARD_TYPE_2		0x00000004	/* don't know how to
-							 * detect this yet */
-#define AURORA_BOARD_DTR_FLOW_OK	0x00000008
-
-/* The story goes like this: Cirrus programmed the CD-180 chip to do automatic
- * hardware flow control, and do it using CTS and DTR. CTS is ok, but, if you
- * have a modem and the chip drops DTR, then the modem will drop the carrier
- * (ain't that cute...). Luckily, the guys at Aurora decided to swap DTR and
- * RTS, which makes the flow control usable. I hope that all the boards made
- * by Aurora have these two signals swapped. If your's doesn't but you have a
- * breakout box, you can try to reverse them yourself, then set the following
- * flag.
- */
-#undef AURORA_FORCE_DTR_FLOW
-
-/* In fact, a few more words have to be said about hardware flow control.
- * This driver handles "output" flow control through the on-board facility
- * CTS Auto Enable. For the "input" flow control there are two cases when
- * the flow should be controlled. The first case is when the kernel is so
- * busy that it cannot process IRQ's in time; this flow control can only be
- * activated by the on-board chip, and if the board has RTS and DTR swapped,
- * this facility is usable. The second case is when the application is so
- * busy that it cannot receive bytes from the kernel, and this flow must be
- * activated by software. This second case is not yet implemented in this
- * driver. Unfortunately, I estimate that the second case is the one that
- * occurs the most.
- */
-
-
-struct Aurora_port {
-	int			magic;
-	int			baud_base;
-	int			flags;
-	struct tty_struct 	* tty;
-	int			count;
-	int			blocked_open;
-	long			event;
-	int			timeout;
-	int			close_delay;
-	unsigned char 		* xmit_buf;
-	int			custom_divisor;
-	int			xmit_head;
-	int			xmit_tail;
-	int			xmit_cnt;
-	wait_queue_head_t	open_wait;
-	wait_queue_head_t	close_wait;
-	struct tq_struct	tqueue;
-	struct tq_struct	tqueue_hangup;
-	short			wakeup_chars;
-	short			break_length;
-	unsigned short		closing_wait;
-	unsigned char		mark_mask;
-	unsigned char		SRER;
-	unsigned char		MSVR;
-	unsigned char		COR2;
-#ifdef AURORA_REPORT_OVERRUN
-	unsigned long		overrun;
-#endif	
-#ifdef AURORA_REPORT_FIFO
-	unsigned long		hits[10];
-#endif
-};
-
-#endif
-#endif /*__LINUX_AURORA_H*/
-
diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c
index 22631f8..8410587 100644
--- a/drivers/sbus/char/bbc_i2c.c
+++ b/drivers/sbus/char/bbc_i2c.c
@@ -187,19 +187,20 @@
 	bp->waiting = 1;
 	add_wait_queue(&bp->wq, &wait);
 	while (limit-- > 0) {
-		u8 val;
+		unsigned long val;
 
-		set_current_state(TASK_INTERRUPTIBLE);
-		*status = val = readb(bp->i2c_control_regs + 0);
-		if ((val & I2C_PCF_PIN) == 0) {
+		val = wait_event_interruptible_timeout(
+				bp->wq,
+				(((*status = readb(bp->i2c_control_regs + 0))
+				  & I2C_PCF_PIN) == 0),
+				msecs_to_jiffies(250));
+		if (val > 0) {
 			ret = 0;
 			break;
 		}
-		msleep_interruptible(250);
 	}
 	remove_wait_queue(&bp->wq, &wait);
 	bp->waiting = 0;
-	current->state = TASK_RUNNING;
 
 	return ret;
 }
@@ -340,7 +341,7 @@
 	 */
 	if (bp->waiting &&
 	    !(readb(bp->i2c_control_regs + 0x0) & I2C_PCF_PIN))
-		wake_up(&bp->wq);
+		wake_up_interruptible(&bp->wq);
 
 	return IRQ_HANDLED;
 }
diff --git a/drivers/sbus/char/cd180.h b/drivers/sbus/char/cd180.h
deleted file mode 100644
index 445b86c..0000000
--- a/drivers/sbus/char/cd180.h
+++ /dev/null
@@ -1,240 +0,0 @@
-
-/* Definitions for Cirrus Logic CL-CD180 8-port async mux chip */
-#define CD180_NCH       8       /* Total number of channels                */
-#define CD180_TPC       16      /* Ticks per character                     */
-#define CD180_NFIFO	8	/* TX FIFO size                            */
-
-/* Global registers */
-#define CD180_GFRCR	0x6b	/* Global Firmware Revision Code Register  */
-#define CD180_SRCR	0x66	/* Service Request Configuration Register  */
-#define CD180_PPRH	0x70	/* Prescaler Period Register High	   */
-#define CD180_PPRL	0x71	/* Prescaler Period Register Low	   */
-#define CD180_MSMR	0x61	/* Modem Service Match Register		   */
-#define CD180_TSMR	0x62	/* Transmit Service Match Register	   */
-#define CD180_RSMR	0x63	/* Receive Service Match Register	   */
-#define CD180_GSVR	0x40	/* Global Service Vector Register	   */
-#define CD180_SRSR	0x65	/* Service Request Status Register	   */
-#define CD180_GSCR	0x41	/* Global Service Channel Register	   */
-#define CD180_CAR	0x64	/* Channel Access Register		   */
-
-/* Indexed registers */
-#define CD180_RDCR	0x07	/* Receive Data Count Register		   */
-#define CD180_RDR	0x78	/* Receiver Data Register		   */
-#define CD180_RCSR	0x7a	/* Receiver Character Status Register	   */
-#define CD180_TDR	0x7b	/* Transmit Data Register		   */
-#define CD180_EOSRR	0x7f	/* End of Service Request Register	   */
-
-/* Channel Registers */
-#define CD180_SRER      0x02    /* Service Request Enable Register         */
-#define CD180_CCR       0x01    /* Channel Command Register                */
-#define CD180_COR1      0x03    /* Channel Option Register 1               */
-#define CD180_COR2      0x04    /* Channel Option Register 2               */
-#define CD180_COR3      0x05    /* Channel Option Register 3               */
-#define CD180_CCSR      0x06    /* Channel Control Status Register         */
-#define CD180_RTPR      0x18    /* Receive Timeout Period Register         */
-#define CD180_RBPRH     0x31    /* Receive Bit Rate Period Register High  */
-#define CD180_RBPRL     0x32    /* Receive Bit Rate Period Register Low   */
-#define CD180_TBPRH     0x39    /* Transmit Bit Rate Period Register High */
-#define CD180_TBPRL     0x3a    /* Transmit Bit Rate Period Register Low  */
-#define CD180_SCHR1     0x09    /* Special Character Register 1            */
-#define CD180_SCHR2     0x0a    /* Special Character Register 2            */
-#define CD180_SCHR3     0x0b    /* Special Character Register 3            */
-#define CD180_SCHR4     0x0c    /* Special Character Register 4            */
-#define CD180_MCR       0x12    /* Modem Change Register                   */
-#define CD180_MCOR1     0x10    /* Modem Change Option 1 Register          */
-#define CD180_MCOR2     0x11    /* Modem Change Option 2 Register          */
-#define CD180_MSVR      0x28    /* Modem Signal Value Register             */
-#define CD180_MSVRTS    0x29    /* Modem Signal Value RTS                  */
-#define CD180_MSVDTR    0x2a    /* Modem Signal Value DTR                  */
-
-/* Global Interrupt Vector Register (R/W) */
-
-#define GSVR_ITMASK     0x07     /* Interrupt type mask                     */
-#define  GSVR_IT_MDM     0x01    /* Modem Signal Change Interrupt           */
-#define  GSVR_IT_TX      0x02    /* Transmit Data Interrupt                 */
-#define  GSVR_IT_RGD     0x03    /* Receive Good Data Interrupt             */
-#define  GSVR_IT_REXC    0x07    /* Receive Exception Interrupt             */
-
-
-/* Global Interrupt Channel Register (R/W) */
- 
-#define GSCR_CHAN       0x1c    /* Channel Number Mask                     */
-#define GSCR_CHAN_OFF   2       /* Channel Number Offset                   */
-
-
-/* Channel Address Register (R/W) */
-
-#define CAR_CHAN        0x07    /* Channel Number Mask                     */
-
-
-/* Receive Character Status Register (R/O) */
-
-#define RCSR_TOUT       0x80    /* Rx Timeout                              */
-#define RCSR_SCDET      0x70    /* Special Character Detected Mask         */
-#define  RCSR_NO_SC      0x00   /* No Special Characters Detected          */
-#define  RCSR_SC_1       0x10   /* Special Char 1 (or 1 & 3) Detected      */
-#define  RCSR_SC_2       0x20   /* Special Char 2 (or 2 & 4) Detected      */
-#define  RCSR_SC_3       0x30   /* Special Char 3 Detected                 */
-#define  RCSR_SC_4       0x40   /* Special Char 4 Detected                 */
-#define RCSR_BREAK      0x08    /* Break has been detected                 */
-#define RCSR_PE         0x04    /* Parity Error                            */
-#define RCSR_FE         0x02    /* Frame Error                             */
-#define RCSR_OE         0x01    /* Overrun Error                           */
-
-
-/* Channel Command Register (R/W) (commands in groups can be OR-ed) */
-
-#define CCR_HARDRESET   0x81    /* Reset the chip                          */
-
-#define CCR_SOFTRESET   0x80    /* Soft Channel Reset                      */
-
-#define CCR_CORCHG1     0x42    /* Channel Option Register 1 Changed       */
-#define CCR_CORCHG2     0x44    /* Channel Option Register 2 Changed       */
-#define CCR_CORCHG3     0x48    /* Channel Option Register 3 Changed       */
-
-#define CCR_SSCH1       0x21    /* Send Special Character 1                */
-
-#define CCR_SSCH2       0x22    /* Send Special Character 2                */
-
-#define CCR_SSCH3       0x23    /* Send Special Character 3                */
-
-#define CCR_SSCH4       0x24    /* Send Special Character 4                */
-
-#define CCR_TXEN        0x18    /* Enable Transmitter                      */
-#define CCR_RXEN        0x12    /* Enable Receiver                         */
-
-#define CCR_TXDIS       0x14    /* Disable Transmitter                     */
-#define CCR_RXDIS       0x11    /* Disable Receiver                        */
-
-
-/* Service Request Enable Register (R/W) */
-
-#define SRER_DSR         0x80    /* Enable interrupt on DSR change          */
-#define SRER_CD          0x40    /* Enable interrupt on CD change           */
-#define SRER_CTS         0x20    /* Enable interrupt on CTS change          */
-#define SRER_RXD         0x10    /* Enable interrupt on Receive Data        */
-#define SRER_RXSC        0x08    /* Enable interrupt on Receive Spec. Char  */
-#define SRER_TXRDY       0x04    /* Enable interrupt on TX FIFO empty       */
-#define SRER_TXEMPTY     0x02    /* Enable interrupt on TX completely empty */
-#define SRER_RET         0x01    /* Enable interrupt on RX Exc. Timeout     */
-
-
-/* Channel Option Register 1 (R/W) */
-
-#define COR1_ODDP       0x80    /* Odd Parity                              */
-#define COR1_PARMODE    0x60    /* Parity Mode mask                        */
-#define  COR1_NOPAR      0x00   /* No Parity                               */
-#define  COR1_FORCEPAR   0x20   /* Force Parity                            */
-#define  COR1_NORMPAR    0x40   /* Normal Parity                           */
-#define COR1_IGNORE     0x10    /* Ignore Parity on RX                     */
-#define COR1_STOPBITS   0x0c    /* Number of Stop Bits                     */
-#define  COR1_1SB        0x00   /* 1 Stop Bit                              */
-#define  COR1_15SB       0x04   /* 1.5 Stop Bits                           */
-#define  COR1_2SB        0x08   /* 2 Stop Bits                             */
-#define COR1_CHARLEN    0x03    /* Character Length                        */
-#define  COR1_5BITS      0x00   /* 5 bits                                  */
-#define  COR1_6BITS      0x01   /* 6 bits                                  */
-#define  COR1_7BITS      0x02   /* 7 bits                                  */
-#define  COR1_8BITS      0x03   /* 8 bits                                  */
-
-
-/* Channel Option Register 2 (R/W) */
-
-#define COR2_IXM        0x80    /* Implied XON mode                        */
-#define COR2_TXIBE      0x40    /* Enable In-Band (XON/XOFF) Flow Control  */
-#define COR2_ETC        0x20    /* Embedded Tx Commands Enable             */
-#define COR2_LLM        0x10    /* Local Loopback Mode                     */
-#define COR2_RLM        0x08    /* Remote Loopback Mode                    */
-#define COR2_RTSAO      0x04    /* RTS Automatic Output Enable             */
-#define COR2_CTSAE      0x02    /* CTS Automatic Enable                    */
-#define COR2_DSRAE      0x01    /* DSR Automatic Enable                    */
-
-
-/* Channel Option Register 3 (R/W) */
-
-#define COR3_XONCH      0x80    /* XON is a pair of characters (1 & 3)     */
-#define COR3_XOFFCH     0x40    /* XOFF is a pair of characters (2 & 4)    */
-#define COR3_FCT        0x20    /* Flow-Control Transparency Mode          */
-#define COR3_SCDE       0x10    /* Special Character Detection Enable      */
-#define COR3_RXTH       0x0f    /* RX FIFO Threshold value (1-8)           */
-
-
-/* Channel Control Status Register (R/O) */
-
-#define CCSR_RXEN       0x80    /* Receiver Enabled                        */
-#define CCSR_RXFLOFF    0x40    /* Receive Flow Off (XOFF was sent)        */
-#define CCSR_RXFLON     0x20    /* Receive Flow On (XON was sent)          */
-#define CCSR_TXEN       0x08    /* Transmitter Enabled                     */
-#define CCSR_TXFLOFF    0x04    /* Transmit Flow Off (got XOFF)            */
-#define CCSR_TXFLON     0x02    /* Transmit Flow On (got XON)              */
-
-
-/* Modem Change Option Register 1 (R/W) */
-
-#define MCOR1_DSRZD     0x80    /* Detect 0->1 transition of DSR           */
-#define MCOR1_CDZD      0x40    /* Detect 0->1 transition of CD            */
-#define MCOR1_CTSZD     0x20    /* Detect 0->1 transition of CTS           */
-#define MCOR1_DTRTH     0x0f    /* Auto DTR flow control Threshold (1-8)   */
-#define  MCOR1_NODTRFC   0x0     /* Automatic DTR flow control disabled     */
-
-
-/* Modem Change Option Register 2 (R/W) */
-
-#define MCOR2_DSROD     0x80    /* Detect 1->0 transition of DSR           */
-#define MCOR2_CDOD      0x40    /* Detect 1->0 transition of CD            */
-#define MCOR2_CTSOD     0x20    /* Detect 1->0 transition of CTS           */
-
-
-/* Modem Change Register (R/W) */
-
-#define MCR_DSRCHG      0x80    /* DSR Changed                             */
-#define MCR_CDCHG       0x40    /* CD Changed                              */
-#define MCR_CTSCHG      0x20    /* CTS Changed                             */
-
-
-/* Modem Signal Value Register (R/W) */
-
-#define MSVR_DSR        0x80    /* Current state of DSR input              */
-#define MSVR_CD         0x40    /* Current state of CD input               */
-#define MSVR_CTS        0x20    /* Current state of CTS input              */
-#define MSVR_DTR        0x02    /* Current state of DTR output             */
-#define MSVR_RTS        0x01    /* Current state of RTS output             */
-
-
-/* Service Request Status Register */
-
-#define SRSR_CMASK	0xC0	/* Current Service Context Mask            */
-#define  SRSR_CNONE	0x00	/* Not in a service context		   */
-#define  SRSR_CRX	0x40	/* Rx Context				   */
-#define  SRSR_CTX	0x80	/* Tx Context				   */
-#define  SRSR_CMDM	0xC0	/* Modem Context			   */
-#define SRSR_ANYINT	0x6F	/* Any interrupt flag			   */
-#define SRSR_RINT	0x10	/* Receive Interrupt			   */
-#define SRSR_TINT	0x04	/* Transmit Interrupt			   */
-#define SRSR_MINT	0x01	/* Modem Interrupt			   */
-#define SRSR_REXT	0x20	/* Receive External Interrupt		   */
-#define SRSR_TEXT	0x08	/* Transmit External Interrupt		   */
-#define SRSR_MEXT	0x02	/* Modem External Interrupt		   */
-
-
-/* Service Request Configuration Register */
-
-#define SRCR_PKGTYPE    0x80
-#define SRCR_REGACKEN   0x40
-#define SRCR_DAISYEN    0x20
-#define SRCR_GLOBPRI    0x10
-#define SRCR_UNFAIR     0x08
-#define SRCR_AUTOPRI    0x02
-#define SRCR_PRISEL     0x01
-
-/* Values for register-based Interrupt ACKs */
-#define CD180_ACK_MINT	0x75	/* goes to MSMR				   */
-#define CD180_ACK_TINT	0x76	/* goes to TSMR				   */
-#define CD180_ACK_RINT	0x77	/* goes to RSMR				   */
-
-/* Escape characters */
-
-#define CD180_C_ESC     0x00    /* Escape character                        */
-#define CD180_C_SBRK    0x81    /* Start sending BREAK                     */
-#define CD180_C_DELAY   0x82    /* Delay output                            */
-#define CD180_C_EBRK    0x83    /* Stop sending BREAK                      */
diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c
index 45cf5bc..44d2ef9 100644
--- a/drivers/sbus/char/uctrl.c
+++ b/drivers/sbus/char/uctrl.c
@@ -364,6 +364,7 @@
 	struct linux_prom_irqs tmp_irq[2];
         unsigned int vaddr[2] = { 0, 0 };
 	int tmpnode, uctrlnode = prom_getchild(prom_root_node);
+	int err;
 
 	tmpnode = prom_searchsiblings(uctrlnode, "obio");
 
@@ -389,7 +390,12 @@
 	if(!driver->irq) 
 		driver->irq = tmp_irq[0].pri;
 
-	request_irq(driver->irq, uctrl_interrupt, 0, "uctrl", driver);
+	err = request_irq(driver->irq, uctrl_interrupt, 0, "uctrl", driver);
+	if (err) {
+		printk("%s: unable to register irq %d\n",
+		       __FUNCTION__, driver->irq);
+		return err;
+	}
 
 	if (misc_register(&uctrl_dev)) {
 		printk("%s: unable to get misc minor %d\n",
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index f4440d3..509ace7 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -38,6 +38,8 @@
  *		Fix some spin_locks.
  *		Do not call uart_add_one_port for absent ports.
  *	1.07	Use CONFIG_SERIAL_TXX9_NR_UARTS.  Cleanup.
+ *	1.08	Use platform_device.
+ *		Fix and cleanup suspend/resume/initialization codes.
  */
 
 #if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
@@ -50,7 +52,7 @@
 #include <linux/console.h>
 #include <linux/sysrq.h>
 #include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/pci.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
@@ -60,7 +62,7 @@
 
 #include <asm/io.h>
 
-static char *serial_version = "1.07";
+static char *serial_version = "1.08";
 static char *serial_name = "TX39/49 Serial driver";
 
 #define PASS_LIMIT	256
@@ -94,12 +96,7 @@
 
 struct uart_txx9_port {
 	struct uart_port	port;
-
-	/*
-	 * We provide a per-port pm hook.
-	 */
-	void			(*pm)(struct uart_port *port,
-				      unsigned int state, unsigned int old);
+	/* No additional info for now */
 };
 
 #define TXX9_REGION_SIZE	0x24
@@ -277,6 +274,31 @@
 	/* TXX9-SIO can not control DTR... */
 }
 
+static void serial_txx9_initialize(struct uart_port *port)
+{
+	struct uart_txx9_port *up = (struct uart_txx9_port *)port;
+	unsigned int tmout = 10000;
+
+	sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST);
+	/* TX4925 BUG WORKAROUND.  Accessing SIOC register
+	 * immediately after soft reset causes bus error. */
+	mmiowb();
+	udelay(1);
+	while ((sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST) && --tmout)
+		udelay(1);
+	/* TX Int by FIFO Empty, RX Int by Receiving 1 char. */
+	sio_set(up, TXX9_SIFCR,
+		TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1);
+	/* initial settings */
+	sio_out(up, TXX9_SILCR,
+		TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT |
+		((up->port.flags & UPF_TXX9_USE_SCLK) ?
+		 TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG));
+	sio_quot_set(up, uart_get_divisor(port, 9600));
+	sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */);
+	sio_out(up, TXX9_SIDICR, 0);
+}
+
 static inline void
 receive_chars(struct uart_txx9_port *up, unsigned int *status)
 {
@@ -657,9 +679,8 @@
 serial_txx9_pm(struct uart_port *port, unsigned int state,
 	      unsigned int oldstate)
 {
-	struct uart_txx9_port *up = (struct uart_txx9_port *)port;
-	if (up->pm)
-		up->pm(port, state, oldstate);
+	if (state == 0)
+		serial_txx9_initialize(port);
 }
 
 static int serial_txx9_request_resource(struct uart_txx9_port *up)
@@ -732,7 +753,6 @@
 static void serial_txx9_config_port(struct uart_port *port, int uflags)
 {
 	struct uart_txx9_port *up = (struct uart_txx9_port *)port;
-	unsigned long flags;
 	int ret;
 
 	/*
@@ -749,30 +769,7 @@
 	if (up->port.line == up->port.cons->index)
 		return;
 #endif
-	spin_lock_irqsave(&up->port.lock, flags);
-	/*
-	 * Reset the UART.
-	 */
-	sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST);
-#ifdef CONFIG_CPU_TX49XX
-	/* TX4925 BUG WORKAROUND.  Accessing SIOC register
-	 * immediately after soft reset causes bus error. */
-	iob();
-	udelay(1);
-#endif
-	while (sio_in(up, TXX9_SIFCR) & TXX9_SIFCR_SWRST)
-		;
-	/* TX Int by FIFO Empty, RX Int by Receiving 1 char. */
-	sio_set(up, TXX9_SIFCR,
-		TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1);
-	/* initial settings */
-	sio_out(up, TXX9_SILCR,
-		TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT |
-		((up->port.flags & UPF_TXX9_USE_SCLK) ?
-		 TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG));
-	sio_quot_set(up, uart_get_divisor(port, 9600));
-	sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */);
-	spin_unlock_irqrestore(&up->port.lock, flags);
+	serial_txx9_initialize(port);
 }
 
 static int
@@ -818,7 +815,8 @@
 
 static struct uart_txx9_port serial_txx9_ports[UART_NR];
 
-static void __init serial_txx9_register_ports(struct uart_driver *drv)
+static void __init serial_txx9_register_ports(struct uart_driver *drv,
+					      struct device *dev)
 {
 	int i;
 
@@ -827,6 +825,7 @@
 
 		up->port.line = i;
 		up->port.ops = &serial_txx9_pops;
+		up->port.dev = dev;
 		if (up->port.iobase || up->port.mapbase)
 			uart_add_one_port(drv, &up->port);
 	}
@@ -898,7 +897,7 @@
 	sio_out(up, TXX9_SIDICR, ier);
 }
 
-static int serial_txx9_console_setup(struct console *co, char *options)
+static int __init serial_txx9_console_setup(struct console *co, char *options)
 {
 	struct uart_port *port;
 	struct uart_txx9_port *up;
@@ -919,17 +918,7 @@
 	if (!port->ops)
 		return -ENODEV;
 
-	/*
-	 *	Disable UART interrupts, set DTR and RTS high
-	 *	and set speed.
-	 */
-	sio_out(up, TXX9_SIDICR, 0);
-	/* initial settings */
-	sio_out(up, TXX9_SILCR,
-		TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT |
-		((port->flags & UPF_TXX9_USE_SCLK) ?
-		 TXX9_SILCR_SCS_SCLK_BG : TXX9_SILCR_SCS_IMCLK_BG));
-	sio_out(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */);
+	serial_txx9_initialize(&up->port);
 
 	if (options)
 		uart_parse_options(options, &baud, &parity, &bits, &flow);
@@ -981,31 +970,6 @@
 	return 0;
 }
 
-#ifdef ENABLE_SERIAL_TXX9_PCI
-#ifdef CONFIG_PM
-/**
- *	serial_txx9_suspend_port - suspend one serial port
- *	@line:  serial line number
- *
- *	Suspend one serial port.
- */
-static void serial_txx9_suspend_port(int line)
-{
-	uart_suspend_port(&serial_txx9_reg, &serial_txx9_ports[line].port);
-}
-
-/**
- *	serial_txx9_resume_port - resume one serial port
- *	@line:  serial line number
- *
- *	Resume one serial port.
- */
-static void serial_txx9_resume_port(int line)
-{
-	uart_resume_port(&serial_txx9_reg, &serial_txx9_ports[line].port);
-}
-#endif
-
 static DEFINE_MUTEX(serial_txx9_mutex);
 
 /**
@@ -1028,8 +992,18 @@
 	mutex_lock(&serial_txx9_mutex);
 	for (i = 0; i < UART_NR; i++) {
 		uart = &serial_txx9_ports[i];
-		if (!(uart->port.iobase || uart->port.mapbase))
+		if (uart_match_port(&uart->port, port)) {
+			uart_remove_one_port(&serial_txx9_reg, &uart->port);
 			break;
+		}
+	}
+	if (i == UART_NR) {
+		/* Find unused port */
+		for (i = 0; i < UART_NR; i++) {
+			uart = &serial_txx9_ports[i];
+			if (!(uart->port.iobase || uart->port.mapbase))
+				break;
+		}
 	}
 	if (i < UART_NR) {
 		uart->port.iobase = port->iobase;
@@ -1072,6 +1046,95 @@
 }
 
 /*
+ * Register a set of serial devices attached to a platform device.
+ */
+static int __devinit serial_txx9_probe(struct platform_device *dev)
+{
+	struct uart_port *p = dev->dev.platform_data;
+	struct uart_port port;
+	int ret, i;
+
+	memset(&port, 0, sizeof(struct uart_port));
+	for (i = 0; p && p->uartclk != 0; p++, i++) {
+		port.iobase	= p->iobase;
+		port.membase	= p->membase;
+		port.irq	= p->irq;
+		port.uartclk	= p->uartclk;
+		port.iotype	= p->iotype;
+		port.flags	= p->flags;
+		port.mapbase	= p->mapbase;
+		port.dev	= &dev->dev;
+		ret = serial_txx9_register_port(&port);
+		if (ret < 0) {
+			dev_err(&dev->dev, "unable to register port at index %d "
+				"(IO%x MEM%lx IRQ%d): %d\n", i,
+				p->iobase, p->mapbase, p->irq, ret);
+		}
+	}
+	return 0;
+}
+
+/*
+ * Remove serial ports registered against a platform device.
+ */
+static int __devexit serial_txx9_remove(struct platform_device *dev)
+{
+	int i;
+
+	for (i = 0; i < UART_NR; i++) {
+		struct uart_txx9_port *up = &serial_txx9_ports[i];
+
+		if (up->port.dev == &dev->dev)
+			serial_txx9_unregister_port(i);
+	}
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int serial_txx9_suspend(struct platform_device *dev, pm_message_t state)
+{
+	int i;
+
+	for (i = 0; i < UART_NR; i++) {
+		struct uart_txx9_port *up = &serial_txx9_ports[i];
+
+		if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
+			uart_suspend_port(&serial_txx9_reg, &up->port);
+	}
+
+	return 0;
+}
+
+static int serial_txx9_resume(struct platform_device *dev)
+{
+	int i;
+
+	for (i = 0; i < UART_NR; i++) {
+		struct uart_txx9_port *up = &serial_txx9_ports[i];
+
+		if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
+			uart_resume_port(&serial_txx9_reg, &up->port);
+	}
+
+	return 0;
+}
+#endif
+
+static struct platform_driver serial_txx9_plat_driver = {
+	.probe		= serial_txx9_probe,
+	.remove		= __devexit_p(serial_txx9_remove),
+#ifdef CONFIG_PM
+	.suspend	= serial_txx9_suspend,
+	.resume		= serial_txx9_resume,
+#endif
+	.driver		= {
+		.name	= "serial_txx9",
+		.owner	= THIS_MODULE,
+	},
+};
+
+#ifdef ENABLE_SERIAL_TXX9_PCI
+/*
  * Probe one serial board.  Unfortunately, there is no rhyme nor reason
  * to the arrangement of serial ports on a PCI card.
  */
@@ -1097,20 +1160,22 @@
 	line = serial_txx9_register_port(&port);
 	if (line < 0) {
 		printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), line);
+		pci_disable_device(dev);
+		return line;
 	}
-	pci_set_drvdata(dev, (void *)(long)line);
+	pci_set_drvdata(dev, &serial_txx9_ports[line]);
 
 	return 0;
 }
 
 static void __devexit pciserial_txx9_remove_one(struct pci_dev *dev)
 {
-	int line = (int)(long)pci_get_drvdata(dev);
+	struct uart_txx9_port *up = pci_get_drvdata(dev);
 
 	pci_set_drvdata(dev, NULL);
 
-	if (line) {
-		serial_txx9_unregister_port(line);
+	if (up) {
+		serial_txx9_unregister_port(up->port.line);
 		pci_disable_device(dev);
 	}
 }
@@ -1118,10 +1183,10 @@
 #ifdef CONFIG_PM
 static int pciserial_txx9_suspend_one(struct pci_dev *dev, pm_message_t state)
 {
-	int line = (int)(long)pci_get_drvdata(dev);
+	struct uart_txx9_port *up = pci_get_drvdata(dev);
 
-	if (line)
-		serial_txx9_suspend_port(line);
+	if (up)
+		uart_suspend_port(&serial_txx9_reg, &up->port);
 	pci_save_state(dev);
 	pci_set_power_state(dev, pci_choose_state(dev, state));
 	return 0;
@@ -1129,15 +1194,12 @@
 
 static int pciserial_txx9_resume_one(struct pci_dev *dev)
 {
-	int line = (int)(long)pci_get_drvdata(dev);
+	struct uart_txx9_port *up = pci_get_drvdata(dev);
 
 	pci_set_power_state(dev, PCI_D0);
 	pci_restore_state(dev);
-
-	if (line) {
-		pci_enable_device(dev);
-		serial_txx9_resume_port(line);
-	}
+	if (up)
+		uart_resume_port(&serial_txx9_reg, &up->port);
 	return 0;
 }
 #endif
@@ -1161,6 +1223,8 @@
 MODULE_DEVICE_TABLE(pci, serial_txx9_pci_tbl);
 #endif /* ENABLE_SERIAL_TXX9_PCI */
 
+static struct platform_device *serial_txx9_plat_devs;
+
 static int __init serial_txx9_init(void)
 {
 	int ret;
@@ -1168,13 +1232,39 @@
  	printk(KERN_INFO "%s version %s\n", serial_name, serial_version);
 
 	ret = uart_register_driver(&serial_txx9_reg);
-	if (ret >= 0) {
-		serial_txx9_register_ports(&serial_txx9_reg);
+	if (ret)
+		goto out;
+
+	serial_txx9_plat_devs = platform_device_alloc("serial_txx9", -1);
+	if (!serial_txx9_plat_devs) {
+		ret = -ENOMEM;
+		goto unreg_uart_drv;
+	}
+
+	ret = platform_device_add(serial_txx9_plat_devs);
+	if (ret)
+		goto put_dev;
+
+	serial_txx9_register_ports(&serial_txx9_reg,
+				   &serial_txx9_plat_devs->dev);
+
+	ret = platform_driver_register(&serial_txx9_plat_driver);
+	if (ret)
+		goto del_dev;
 
 #ifdef ENABLE_SERIAL_TXX9_PCI
-		ret = pci_register_driver(&serial_txx9_pci_driver);
+	ret = pci_register_driver(&serial_txx9_pci_driver);
 #endif
-	}
+	if (ret == 0)
+		goto out;
+
+ del_dev:
+	platform_device_del(serial_txx9_plat_devs);
+ put_dev:
+	platform_device_put(serial_txx9_plat_devs);
+ unreg_uart_drv:
+	uart_unregister_driver(&serial_txx9_reg);
+ out:
 	return ret;
 }
 
@@ -1185,6 +1275,8 @@
 #ifdef ENABLE_SERIAL_TXX9_PCI
 	pci_unregister_driver(&serial_txx9_pci_driver);
 #endif
+	platform_driver_unregister(&serial_txx9_plat_driver);
+	platform_device_unregister(serial_txx9_plat_devs);
 	for (i = 0; i < UART_NR; i++) {
 		struct uart_txx9_port *up = &serial_txx9_ports[i];
 		if (up->port.iobase || up->port.mapbase)
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
index 34e9bac..b607870 100644
--- a/drivers/usb/core/Makefile
+++ b/drivers/usb/core/Makefile
@@ -4,7 +4,7 @@
 
 usbcore-objs	:= usb.o hub.o hcd.o urb.o message.o driver.o \
 			config.o file.o buffer.o sysfs.o endpoint.o \
-			devio.o notify.o generic.o
+			devio.o notify.o generic.o quirks.o
 
 ifeq ($(CONFIG_PCI),y)
 	usbcore-objs	+= hcd-pci.o
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 2aded26..9e3e943 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -366,19 +366,8 @@
 EXPORT_SYMBOL(usb_driver_release_interface);
 
 /* returns 0 if no match, 1 if match */
-int usb_match_one_id(struct usb_interface *interface,
-		     const struct usb_device_id *id)
+int usb_match_device(struct usb_device *dev, const struct usb_device_id *id)
 {
-	struct usb_host_interface *intf;
-	struct usb_device *dev;
-
-	/* proc_connectinfo in devio.c may call us with id == NULL. */
-	if (id == NULL)
-		return 0;
-
-	intf = interface->cur_altsetting;
-	dev = interface_to_usbdev(interface);
-
 	if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
 	    id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
 		return 0;
@@ -409,6 +398,26 @@
 	    (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
 		return 0;
 
+	return 1;
+}
+
+/* returns 0 if no match, 1 if match */
+int usb_match_one_id(struct usb_interface *interface,
+		     const struct usb_device_id *id)
+{
+	struct usb_host_interface *intf;
+	struct usb_device *dev;
+
+	/* proc_connectinfo in devio.c may call us with id == NULL. */
+	if (id == NULL)
+		return 0;
+
+	intf = interface->cur_altsetting;
+	dev = interface_to_usbdev(interface);
+
+	if (!usb_match_device(dev, id))
+		return 0;
+
 	/* The interface class, subclass, and protocol should never be
 	 * checked for a match if the device class is Vendor Specific,
 	 * unless the match record specifies the Vendor ID. */
@@ -954,12 +963,16 @@
 	int			i;
 	struct usb_interface	*intf;
 
-	/* For autosuspend, fail fast if anything is in use.
-	 * Also fail if any interfaces require remote wakeup but it
-	 * isn't available. */
+	/* For autosuspend, fail fast if anything is in use or autosuspend
+	 * is disabled.  Also fail if any interfaces require remote wakeup
+	 * but it isn't available.
+	 */
 	udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
 	if (udev->pm_usage_cnt > 0)
 		return -EBUSY;
+	if (!udev->autosuspend_delay)
+		return -EPERM;
+
 	if (udev->actconfig) {
 		for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
 			intf = udev->actconfig->interface[i];
@@ -982,7 +995,7 @@
 
 #define autosuspend_check(udev)		0
 
-#endif
+#endif	/* CONFIG_USB_SUSPEND */
 
 /**
  * usb_suspend_both - suspend a USB device and its interfaces
@@ -1177,7 +1190,7 @@
 			udev->pm_usage_cnt -= inc_usage_cnt;
 	} else if (inc_usage_cnt <= 0 && autosuspend_check(udev) == 0)
 		queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend,
-				USB_AUTOSUSPEND_DELAY);
+				udev->autosuspend_delay);
 	usb_pm_unlock(udev);
 	return status;
 }
@@ -1212,6 +1225,26 @@
 }
 
 /**
+ * usb_try_autosuspend_device - attempt an autosuspend of a USB device and its interfaces
+ * @udev: the usb_device to autosuspend
+ *
+ * This routine should be called when a core subsystem thinks @udev may
+ * be ready to autosuspend.
+ *
+ * @udev's usage counter left unchanged.  If it or any of the usage counters
+ * for an active interface is greater than 0, or autosuspend is not allowed
+ * for any other reason, no autosuspend request will be queued.
+ *
+ * This routine can run only in process context.
+ */
+void usb_try_autosuspend_device(struct usb_device *udev)
+{
+	usb_autopm_do_device(udev, 0);
+	// dev_dbg(&udev->dev, "%s: cnt %d\n",
+	// 		__FUNCTION__, udev->pm_usage_cnt);
+}
+
+/**
  * usb_autoresume_device - immediately autoresume a USB device and its interfaces
  * @udev: the usb_device to autoresume
  *
@@ -1261,7 +1294,7 @@
 				intf->pm_usage_cnt -= inc_usage_cnt;
 		} else if (inc_usage_cnt <= 0 && autosuspend_check(udev) == 0)
 			queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend,
-					USB_AUTOSUSPEND_DELAY);
+					udev->autosuspend_delay);
 	}
 	usb_pm_unlock(udev);
 	return status;
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 50c0db1..4140074 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1287,6 +1287,9 @@
 	if (!try_module_get(THIS_MODULE))
 		return -EINVAL;
 
+	/* Determine quirks */
+	usb_detect_quirks(udev);
+
 	err = usb_get_configuration(udev);
 	if (err < 0) {
 		dev_err(&udev->dev, "can't read configurations, error %d\n",
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 74edaea..2f17468 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -11,6 +11,7 @@
 #include <linux/timer.h>
 #include <linux/ctype.h>
 #include <linux/device.h>
+#include <linux/usb/quirks.h>
 #include <asm/byteorder.h>
 #include <asm/scatterlist.h>
 
@@ -685,7 +686,10 @@
 
 	/* Try to read the string descriptor by asking for the maximum
 	 * possible number of bytes */
-	rc = usb_get_string(dev, langid, index, buf, 255);
+	if (dev->quirks & USB_QUIRK_STRING_FETCH_255)
+		rc = -EIO;
+	else
+		rc = usb_get_string(dev, langid, index, buf, 255);
 
 	/* If that failed try to read the descriptor length, then
 	 * ask for just that many bytes */
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
new file mode 100644
index 0000000..0e5c646
--- /dev/null
+++ b/drivers/usb/core/quirks.c
@@ -0,0 +1,77 @@
+/*
+ * USB device quirk handling logic and table
+ *
+ * Copyright (c) 2007 Oliver Neukum
+ * Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ *
+ */
+
+#include <linux/usb.h>
+#include <linux/usb/quirks.h>
+#include "usb.h"
+
+/* List of quirky USB devices.  Please keep this list ordered by:
+ * 	1) Vendor ID
+ * 	2) Product ID
+ * 	3) Class ID
+ *
+ * as we want specific devices to be overridden first, and only after that, any
+ * class specific quirks.
+ *
+ * Right now the logic aborts if it finds a valid device in the table, we might
+ * want to change that in the future if it turns out that a whole class of
+ * devices is broken...
+ */
+static const struct usb_device_id usb_quirk_list[] = {
+	/* HP 5300/5370C scanner */
+	{ USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 },
+
+	/* Elsa MicroLink 56k (V.250) */
+	{ USB_DEVICE(0x05cc, 0x2267), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+
+	{ }  /* terminating entry must be last */
+};
+
+static void usb_autosuspend_quirk(struct usb_device *udev)
+{
+#ifdef	CONFIG_USB_SUSPEND
+	/* disable autosuspend, but allow the user to re-enable it via sysfs */
+	udev->autosuspend_delay = 0;
+#endif
+}
+
+static const struct usb_device_id *find_id(struct usb_device *udev)
+{
+	const struct usb_device_id *id = usb_quirk_list;
+
+	for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass ||
+			id->driver_info; id++) {
+		if (usb_match_device(udev, id))
+			return id;
+	}
+	return NULL;
+}
+
+/*
+ * Detect any quirks the device has, and do any housekeeping for it if needed.
+ */
+void usb_detect_quirks(struct usb_device *udev)
+{
+	const struct usb_device_id *id = usb_quirk_list;
+
+	id = find_id(udev);
+	if (id)
+		udev->quirks = (u32)(id->driver_info);
+	if (udev->quirks)
+		dev_dbg(&udev->dev, "USB quirks for this device: %x\n",
+				udev->quirks);
+
+	/* do any special quirk handling here if needed */
+	if (udev->quirks & USB_QUIRK_NO_AUTOSUSPEND)
+		usb_autosuspend_quirk(udev);
+}
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 0edfbaf..311d5df 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -148,6 +148,75 @@
 }
 static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL);
 
+static ssize_t
+show_quirks(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct usb_device *udev;
+
+	udev = to_usb_device(dev);
+	return sprintf(buf, "0x%x\n", udev->quirks);
+}
+static DEVICE_ATTR(quirks, S_IRUGO, show_quirks, NULL);
+
+#ifdef	CONFIG_USB_SUSPEND
+
+static ssize_t
+show_autosuspend(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct usb_device *udev = to_usb_device(dev);
+
+	return sprintf(buf, "%u\n", udev->autosuspend_delay / HZ);
+}
+
+static ssize_t
+set_autosuspend(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct usb_device *udev = to_usb_device(dev);
+	unsigned value, old;
+
+	if (sscanf(buf, "%u", &value) != 1 || value >= INT_MAX/HZ)
+		return -EINVAL;
+	value *= HZ;
+
+	old = udev->autosuspend_delay;
+	udev->autosuspend_delay = value;
+	if (value > 0 && old == 0)
+		usb_try_autosuspend_device(udev);
+
+	return count;
+}
+
+static DEVICE_ATTR(autosuspend, S_IRUGO | S_IWUSR,
+		show_autosuspend, set_autosuspend);
+
+static char power_group[] = "power";
+
+static int add_power_attributes(struct device *dev)
+{
+	int rc = 0;
+
+	if (is_usb_device(dev))
+		rc = sysfs_add_file_to_group(&dev->kobj,
+				&dev_attr_autosuspend.attr,
+				power_group);
+	return rc;
+}
+
+static void remove_power_attributes(struct device *dev)
+{
+	sysfs_remove_file_from_group(&dev->kobj,
+			&dev_attr_autosuspend.attr,
+			power_group);
+}
+
+#else
+
+#define add_power_attributes(dev)	0
+#define remove_power_attributes(dev)	do {} while (0)
+
+#endif	/* CONFIG_USB_SUSPEND */
+
 /* Descriptor fields */
 #define usb_descriptor_attr_le16(field, format_string)			\
 static ssize_t								\
@@ -204,6 +273,7 @@
 	&dev_attr_devnum.attr,
 	&dev_attr_version.attr,
 	&dev_attr_maxchild.attr,
+	&dev_attr_quirks.attr,
 	NULL,
 };
 static struct attribute_group dev_attr_grp = {
@@ -219,6 +289,10 @@
 	if (retval)
 		return retval;
 
+	retval = add_power_attributes(dev);
+	if (retval)
+		goto error;
+
 	if (udev->manufacturer) {
 		retval = device_create_file(dev, &dev_attr_manufacturer);
 		if (retval)
@@ -239,10 +313,7 @@
 		goto error;
 	return 0;
 error:
-	usb_remove_ep_files(&udev->ep0);
-	device_remove_file(dev, &dev_attr_manufacturer);
-	device_remove_file(dev, &dev_attr_product);
-	device_remove_file(dev, &dev_attr_serial);
+	usb_remove_sysfs_dev_files(udev);
 	return retval;
 }
 
@@ -251,14 +322,11 @@
 	struct device *dev = &udev->dev;
 
 	usb_remove_ep_files(&udev->ep0);
+	device_remove_file(dev, &dev_attr_manufacturer);
+	device_remove_file(dev, &dev_attr_product);
+	device_remove_file(dev, &dev_attr_serial);
+	remove_power_attributes(dev);
 	sysfs_remove_group(&dev->kobj, &dev_attr_grp);
-
-	if (udev->manufacturer)
-		device_remove_file(dev, &dev_attr_manufacturer);
-	if (udev->product)
-		device_remove_file(dev, &dev_attr_product);
-	if (udev->serial)
-		device_remove_file(dev, &dev_attr_serial);
 }
 
 /* Interface fields */
@@ -362,33 +430,28 @@
 
 int usb_create_sysfs_intf_files(struct usb_interface *intf)
 {
+	struct device *dev = &intf->dev;
 	struct usb_device *udev = interface_to_usbdev(intf);
 	struct usb_host_interface *alt = intf->cur_altsetting;
 	int retval;
 
-	retval = sysfs_create_group(&intf->dev.kobj, &intf_attr_grp);
+	retval = sysfs_create_group(&dev->kobj, &intf_attr_grp);
 	if (retval)
-		goto error;
+		return retval;
 
 	if (alt->string == NULL)
 		alt->string = usb_cache_string(udev, alt->desc.iInterface);
 	if (alt->string)
-		retval = device_create_file(&intf->dev, &dev_attr_interface);
+		retval = device_create_file(dev, &dev_attr_interface);
 	usb_create_intf_ep_files(intf, udev);
 	return 0;
-error:
-	if (alt->string)
-		device_remove_file(&intf->dev, &dev_attr_interface);
-	sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp);
-	usb_remove_intf_ep_files(intf);
-	return retval;
 }
 
 void usb_remove_sysfs_intf_files(struct usb_interface *intf)
 {
-	usb_remove_intf_ep_files(intf);
-	sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp);
+	struct device *dev = &intf->dev;
 
-	if (intf->cur_altsetting->string)
-		device_remove_file(&intf->dev, &dev_attr_interface);
+	usb_remove_intf_ep_files(intf);
+	device_remove_file(dev, &dev_attr_interface);
+	sysfs_remove_group(&dev->kobj, &intf_attr_grp);
 }
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 3db721c..54b42ce 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -22,6 +22,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/string.h>
 #include <linux/bitops.h>
 #include <linux/slab.h>
@@ -50,6 +51,16 @@
 
 struct workqueue_struct *ksuspend_usb_wq;	/* For autosuspend */
 
+#ifdef	CONFIG_USB_SUSPEND
+static int usb_autosuspend_delay = 2;		/* Default delay value,
+						 * in seconds */
+module_param_named(autosuspend, usb_autosuspend_delay, uint, 0644);
+MODULE_PARM_DESC(autosuspend, "default autosuspend delay");
+
+#else
+#define usb_autosuspend_delay		0
+#endif
+
 
 /**
  * usb_ifnum_to_if - get the interface object with a given interface number
@@ -306,6 +317,7 @@
 #ifdef	CONFIG_PM
 	mutex_init(&dev->pm_mutex);
 	INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work);
+	dev->autosuspend_delay = usb_autosuspend_delay * HZ;
 #endif
 	return dev;
 }
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 17830a8..08b5a04 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -13,6 +13,7 @@
 		struct usb_interface *intf);
 extern void usb_release_interface_cache(struct kref *ref);
 extern void usb_disable_device (struct usb_device *dev, int skip_ep0);
+extern void usb_detect_quirks(struct usb_device *udev);
 
 extern int usb_get_device_descriptor(struct usb_device *dev,
 		unsigned int size);
@@ -21,6 +22,8 @@
 
 extern void usb_kick_khubd(struct usb_device *dev);
 extern void usb_resume_root_hub(struct usb_device *dev);
+extern int usb_match_device(struct usb_device *dev,
+			    const struct usb_device_id *id);
 
 extern int  usb_hub_init(void);
 extern void usb_hub_cleanup(void);
@@ -62,14 +65,14 @@
 
 #ifdef CONFIG_USB_SUSPEND
 
-#define USB_AUTOSUSPEND_DELAY	(HZ*2)
-
 extern void usb_autosuspend_device(struct usb_device *udev);
+extern void usb_try_autosuspend_device(struct usb_device *udev);
 extern int usb_autoresume_device(struct usb_device *udev);
 
 #else
 
-#define usb_autosuspend_device(udev)	do {} while (0)
+#define usb_autosuspend_device(udev)		do {} while (0)
+#define usb_try_autosuspend_device(udev)	do {} while (0)
 static inline int usb_autoresume_device(struct usb_device *udev)
 {
 	return 0;
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 34296e7..188c74a 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -553,6 +553,7 @@
 {
 	struct kiocb_priv	*priv = iocb->private;
 	ssize_t			len, total;
+	void			*to_copy;
 	int			i;
 
 	/* we "retry" to get the right mm context for this: */
@@ -560,10 +561,11 @@
 	/* copy stuff into user buffers */
 	total = priv->actual;
 	len = 0;
+	to_copy = priv->buf;
 	for (i=0; i < priv->nr_segs; i++) {
 		ssize_t this = min((ssize_t)(priv->iv[i].iov_len), total);
 
-		if (copy_to_user(priv->iv[i].iov_base, priv->buf, this)) {
+		if (copy_to_user(priv->iv[i].iov_base, to_copy, this)) {
 			if (len == 0)
 				len = -EFAULT;
 			break;
@@ -571,6 +573,7 @@
 
 		total -= this;
 		len += this;
+		to_copy += this;
 		if (total == 0)
 			break;
 	}
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
index 5d6c06b..8d24d3d 100644
--- a/drivers/usb/host/uhci-debug.c
+++ b/drivers/usb/host/uhci-debug.c
@@ -196,7 +196,7 @@
 		struct uhci_td *td = list_entry(urbp->td_list.next,
 				struct uhci_td, list);
 
-		if (cpu_to_le32(td->dma_handle) != (element & ~UHCI_PTR_BITS))
+		if (element != LINK_TO_TD(td))
 			out += sprintf(out, "%*s Element != First TD\n",
 					space, "");
 		i = nurbs = 0;
@@ -220,16 +220,6 @@
 	return out - buf;
 }
 
-static const char * const qh_names[] = {
-  "skel_unlink_qh", "skel_iso_qh",
-  "skel_int128_qh", "skel_int64_qh",
-  "skel_int32_qh", "skel_int16_qh",
-  "skel_int8_qh", "skel_int4_qh",
-  "skel_int2_qh", "skel_int1_qh",
-  "skel_ls_control_qh", "skel_fs_control_qh",
-  "skel_bulk_qh", "skel_term_qh"
-};
-
 static int uhci_show_sc(int port, unsigned short status, char *buf, int len)
 {
 	char *out = buf;
@@ -352,6 +342,12 @@
 	struct uhci_td *td;
 	struct list_head *tmp, *head;
 	int nframes, nerrs;
+	__le32 link;
+
+	static const char * const qh_names[] = {
+		"unlink", "iso", "int128", "int64", "int32", "int16",
+		"int8", "int4", "int2", "async", "term"
+	};
 
 	out += uhci_show_root_hub_state(uhci, out, len - (out - buf));
 	out += sprintf(out, "HC status\n");
@@ -374,7 +370,7 @@
 	nframes = 10;
 	nerrs = 0;
 	for (i = 0; i < UHCI_NUMFRAMES; ++i) {
-		__le32 link, qh_dma;
+		__le32 qh_dma;
 
 		j = 0;
 		td = uhci->frame_cpu[i];
@@ -393,7 +389,7 @@
 		do {
 			td = list_entry(tmp, struct uhci_td, fl_list);
 			tmp = tmp->next;
-			if (cpu_to_le32(td->dma_handle) != link) {
+			if (link != LINK_TO_TD(td)) {
 				if (nframes > 0)
 					out += sprintf(out, "    link does "
 						"not match list entry!\n");
@@ -430,23 +426,21 @@
 
 	for (i = 0; i < UHCI_NUM_SKELQH; ++i) {
 		int cnt = 0;
+		__le32 fsbr_link = 0;
 
 		qh = uhci->skelqh[i];
-		out += sprintf(out, "- %s\n", qh_names[i]); \
+		out += sprintf(out, "- skel_%s_qh\n", qh_names[i]); \
 		out += uhci_show_qh(qh, out, len - (out - buf), 4);
 
 		/* Last QH is the Terminating QH, it's different */
-		if (i == UHCI_NUM_SKELQH - 1) {
-			if (qh->link != UHCI_PTR_TERM)
-				out += sprintf(out, "    bandwidth reclamation on!\n");
-
-			if (qh_element(qh) != cpu_to_le32(uhci->term_td->dma_handle))
+		if (i == SKEL_TERM) {
+			if (qh_element(qh) != LINK_TO_TD(uhci->term_td))
 				out += sprintf(out, "    skel_term_qh element is not set to term_td!\n");
-
+			if (link == LINK_TO_QH(uhci->skel_term_qh))
+				goto check_qh_link;
 			continue;
 		}
 
-		j = (i < 9) ? 9 : i+1;		/* Next skeleton */
 		head = &qh->node;
 		tmp = head->next;
 
@@ -456,15 +450,26 @@
 			if (++cnt <= 10)
 				out += uhci_show_qh(qh, out,
 						len - (out - buf), 4);
+			if (!fsbr_link && qh->skel >= SKEL_FSBR)
+				fsbr_link = LINK_TO_QH(qh);
 		}
 		if ((cnt -= 10) > 0)
 			out += sprintf(out, "    Skipped %d QHs\n", cnt);
 
-		if (i > 1 && i < UHCI_NUM_SKELQH - 1) {
-			if (qh->link !=
-			    (cpu_to_le32(uhci->skelqh[j]->dma_handle) | UHCI_PTR_QH))
-				out += sprintf(out, "    last QH not linked to next skeleton!\n");
-		}
+		link = UHCI_PTR_TERM;
+		if (i <= SKEL_ISO)
+			;
+		else if (i < SKEL_ASYNC)
+			link = LINK_TO_QH(uhci->skel_async_qh);
+		else if (!uhci->fsbr_is_on)
+			;
+		else if (fsbr_link)
+			link = fsbr_link;
+		else
+			link = LINK_TO_QH(uhci->skel_term_qh);
+check_qh_link:
+		if (qh->link != link)
+			out += sprintf(out, "    last QH not linked to next skeleton!\n");
 	}
 
 	return out - buf;
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index ded4df3..44da433 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -13,7 +13,7 @@
  * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface
  *               support from usb-ohci.c by Adam Richter, adam@yggdrasil.com).
  * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c)
- * (C) Copyright 2004-2006 Alan Stern, stern@rowland.harvard.edu
+ * (C) Copyright 2004-2007 Alan Stern, stern@rowland.harvard.edu
  *
  * Intel documents this fairly well, and as far as I know there
  * are no royalties or anything like that, but even so there are
@@ -107,16 +107,16 @@
 	 * interrupt QHs, which will help spread out bandwidth utilization.
 	 *
 	 * ffs (Find First bit Set) does exactly what we need:
-	 * 1,3,5,...  => ffs = 0 => use skel_int2_qh = skelqh[8],
-	 * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[7], etc.
+	 * 1,3,5,...  => ffs = 0 => use period-2 QH = skelqh[8],
+	 * 2,6,10,... => ffs = 1 => use period-4 QH = skelqh[7], etc.
 	 * ffs >= 7 => not on any high-period queue, so use
-	 *	skel_int1_qh = skelqh[9].
+	 *	period-1 QH = skelqh[9].
 	 * Add in UHCI_NUMFRAMES to insure at least one bit is set.
 	 */
 	skelnum = 8 - (int) __ffs(frame | UHCI_NUMFRAMES);
 	if (skelnum <= 1)
 		skelnum = 9;
-	return UHCI_PTR_QH | cpu_to_le32(uhci->skelqh[skelnum]->dma_handle);
+	return LINK_TO_QH(uhci->skelqh[skelnum]);
 }
 
 #include "uhci-debug.c"
@@ -540,16 +540,18 @@
  *
  * The hardware doesn't really know any difference
  * in the queues, but the order does matter for the
- * protocols higher up. The order is:
+ * protocols higher up.  The order in which the queues
+ * are encountered by the hardware is:
  *
- *  - any isochronous events handled before any
+ *  - All isochronous events are handled before any
  *    of the queues. We don't do that here, because
  *    we'll create the actual TD entries on demand.
- *  - The first queue is the interrupt queue.
- *  - The second queue is the control queue, split into low- and full-speed
- *  - The third queue is bulk queue.
- *  - The fourth queue is the bandwidth reclamation queue, which loops back
- *    to the full-speed control queue.
+ *  - The first queue is the high-period interrupt queue.
+ *  - The second queue is the period-1 interrupt and async
+ *    (low-speed control, full-speed control, then bulk) queue.
+ *  - The third queue is the terminating bandwidth reclamation queue,
+ *    which contains no members, loops back to itself, and is present
+ *    only when FSBR is on and there are no full-speed control or bulk QHs.
  */
 static int uhci_start(struct usb_hcd *hcd)
 {
@@ -626,34 +628,18 @@
 	}
 
 	/*
-	 * 8 Interrupt queues; link all higher int queues to int1,
-	 * then link int1 to control and control to bulk
+	 * 8 Interrupt queues; link all higher int queues to int1 = async
 	 */
-	uhci->skel_int128_qh->link =
-			uhci->skel_int64_qh->link =
-			uhci->skel_int32_qh->link =
-			uhci->skel_int16_qh->link =
-			uhci->skel_int8_qh->link =
-			uhci->skel_int4_qh->link =
-			uhci->skel_int2_qh->link = UHCI_PTR_QH |
-			cpu_to_le32(uhci->skel_int1_qh->dma_handle);
-
-	uhci->skel_int1_qh->link = UHCI_PTR_QH |
-			cpu_to_le32(uhci->skel_ls_control_qh->dma_handle);
-	uhci->skel_ls_control_qh->link = UHCI_PTR_QH |
-			cpu_to_le32(uhci->skel_fs_control_qh->dma_handle);
-	uhci->skel_fs_control_qh->link = UHCI_PTR_QH |
-			cpu_to_le32(uhci->skel_bulk_qh->dma_handle);
-	uhci->skel_bulk_qh->link = UHCI_PTR_QH |
-			cpu_to_le32(uhci->skel_term_qh->dma_handle);
+	for (i = SKEL_ISO + 1; i < SKEL_ASYNC; ++i)
+		uhci->skelqh[i]->link = LINK_TO_QH(uhci->skel_async_qh);
+	uhci->skel_async_qh->link = uhci->skel_term_qh->link = UHCI_PTR_TERM;
 
 	/* This dummy TD is to work around a bug in Intel PIIX controllers */
 	uhci_fill_td(uhci->term_td, 0, uhci_explen(0) |
-		(0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0);
-	uhci->term_td->link = cpu_to_le32(uhci->term_td->dma_handle);
-
-	uhci->skel_term_qh->link = UHCI_PTR_TERM;
-	uhci->skel_term_qh->element = cpu_to_le32(uhci->term_td->dma_handle);
+			(0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0);
+	uhci->term_td->link = UHCI_PTR_TERM;
+	uhci->skel_async_qh->element = uhci->skel_term_qh->element =
+			LINK_TO_TD(uhci->term_td);
 
 	/*
 	 * Fill the frame list: make all entries point to the proper
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
index 74469b5..1b3d234 100644
--- a/drivers/usb/host/uhci-hcd.h
+++ b/drivers/usb/host/uhci-hcd.h
@@ -129,11 +129,12 @@
 	__le32 element;			/* Queue element (TD) pointer */
 
 	/* Software fields */
+	dma_addr_t dma_handle;
+
 	struct list_head node;		/* Node in the list of QHs */
 	struct usb_host_endpoint *hep;	/* Endpoint information */
 	struct usb_device *udev;
 	struct list_head queue;		/* Queue of urbps for this QH */
-	struct uhci_qh *skel;		/* Skeleton for this QH */
 	struct uhci_td *dummy_td;	/* Dummy TD to end the queue */
 	struct uhci_td *post_td;	/* Last TD completed */
 
@@ -149,8 +150,7 @@
 
 	int state;			/* QH_STATE_xxx; see above */
 	int type;			/* Queue type (control, bulk, etc) */
-
-	dma_addr_t dma_handle;
+	int skel;			/* Skeleton queue number */
 
 	unsigned int initial_toggle:1;	/* Endpoint's current toggle value */
 	unsigned int needs_fixup:1;	/* Must fix the TD toggle values */
@@ -171,6 +171,8 @@
 	return element;
 }
 
+#define LINK_TO_QH(qh)		(UHCI_PTR_QH | cpu_to_le32((qh)->dma_handle))
+
 
 /*
  *	Transfer Descriptors
@@ -264,6 +266,8 @@
 	return le32_to_cpu(status);
 }
 
+#define LINK_TO_TD(td)		(cpu_to_le32((td)->dma_handle))
+
 
 /*
  *	Skeleton Queue Headers
@@ -272,12 +276,13 @@
 /*
  * The UHCI driver uses QHs with Interrupt, Control and Bulk URBs for
  * automatic queuing. To make it easy to insert entries into the schedule,
- * we have a skeleton of QHs for each predefined Interrupt latency,
- * low-speed control, full-speed control, bulk, and terminating QH
- * (see explanation for the terminating QH below).
+ * we have a skeleton of QHs for each predefined Interrupt latency.
+ * Asynchronous QHs (low-speed control, full-speed control, and bulk)
+ * go onto the period-1 interrupt list, since they all get accessed on
+ * every frame.
  *
- * When we want to add a new QH, we add it to the end of the list for the
- * skeleton QH.  For instance, the schedule list can look like this:
+ * When we want to add a new QH, we add it to the list starting from the
+ * appropriate skeleton QH.  For instance, the schedule can look like this:
  *
  * skel int128 QH
  * dev 1 interrupt QH
@@ -285,50 +290,47 @@
  * skel int64 QH
  * skel int32 QH
  * ...
- * skel int1 QH
- * skel low-speed control QH
- * dev 5 control QH
- * skel full-speed control QH
- * skel bulk QH
+ * skel int1 + async QH
+ * dev 5 low-speed control QH
  * dev 1 bulk QH
  * dev 2 bulk QH
- * skel terminating QH
  *
- * The terminating QH is used for 2 reasons:
- * - To place a terminating TD which is used to workaround a PIIX bug
- *   (see Intel errata for explanation), and
- * - To loop back to the full-speed control queue for full-speed bandwidth
- *   reclamation.
+ * There is a special terminating QH used to keep full-speed bandwidth
+ * reclamation active when no full-speed control or bulk QHs are linked
+ * into the schedule.  It has an inactive TD (to work around a PIIX bug,
+ * see the Intel errata) and it points back to itself.
  *
- * There's a special skeleton QH for Isochronous QHs.  It never appears
- * on the schedule, and Isochronous TDs go on the schedule before the
+ * There's a special skeleton QH for Isochronous QHs which never appears
+ * on the schedule.  Isochronous TDs go on the schedule before the
  * the skeleton QHs.  The hardware accesses them directly rather than
  * through their QH, which is used only for bookkeeping purposes.
  * While the UHCI spec doesn't forbid the use of QHs for Isochronous,
  * it doesn't use them either.  And the spec says that queues never
  * advance on an error completion status, which makes them totally
  * unsuitable for Isochronous transfers.
+ *
+ * There's also a special skeleton QH used for QHs which are in the process
+ * of unlinking and so may still be in use by the hardware.  It too never
+ * appears on the schedule.
  */
 
-#define UHCI_NUM_SKELQH		14
-#define skel_unlink_qh		skelqh[0]
-#define skel_iso_qh		skelqh[1]
-#define skel_int128_qh		skelqh[2]
-#define skel_int64_qh		skelqh[3]
-#define skel_int32_qh		skelqh[4]
-#define skel_int16_qh		skelqh[5]
-#define skel_int8_qh		skelqh[6]
-#define skel_int4_qh		skelqh[7]
-#define skel_int2_qh		skelqh[8]
-#define skel_int1_qh		skelqh[9]
-#define skel_ls_control_qh	skelqh[10]
-#define skel_fs_control_qh	skelqh[11]
-#define skel_bulk_qh		skelqh[12]
-#define skel_term_qh		skelqh[13]
+#define UHCI_NUM_SKELQH		11
+#define SKEL_UNLINK		0
+#define skel_unlink_qh		skelqh[SKEL_UNLINK]
+#define SKEL_ISO		1
+#define skel_iso_qh		skelqh[SKEL_ISO]
+	/* int128, int64, ..., int1 = 2, 3, ..., 9 */
+#define SKEL_INDEX(exponent)	(9 - exponent)
+#define SKEL_ASYNC		9
+#define skel_async_qh		skelqh[SKEL_ASYNC]
+#define SKEL_TERM		10
+#define skel_term_qh		skelqh[SKEL_TERM]
 
-/* Find the skelqh entry corresponding to an interval exponent */
-#define UHCI_SKEL_INDEX(exponent)	(9 - exponent)
-
+/* The following entries refer to sublists of skel_async_qh */
+#define SKEL_LS_CONTROL		20
+#define SKEL_FS_CONTROL		21
+#define SKEL_FSBR		SKEL_FS_CONTROL
+#define SKEL_BULK		22
 
 /*
  *	The UHCI controller and root hub
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index 68e66b3..f4ebdb3 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -13,7 +13,7 @@
  * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface
  *               support from usb-ohci.c by Adam Richter, adam@yggdrasil.com).
  * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c)
- * (C) Copyright 2004-2006 Alan Stern, stern@rowland.harvard.edu
+ * (C) Copyright 2004-2007 Alan Stern, stern@rowland.harvard.edu
  */
 
 
@@ -45,15 +45,43 @@
  */
 static void uhci_fsbr_on(struct uhci_hcd *uhci)
 {
+	struct uhci_qh *fsbr_qh, *lqh, *tqh;
+
 	uhci->fsbr_is_on = 1;
-	uhci->skel_term_qh->link = cpu_to_le32(
-			uhci->skel_fs_control_qh->dma_handle) | UHCI_PTR_QH;
+	lqh = list_entry(uhci->skel_async_qh->node.prev,
+			struct uhci_qh, node);
+
+	/* Find the first FSBR QH.  Linear search through the list is
+	 * acceptable because normally FSBR gets turned on as soon as
+	 * one QH needs it. */
+	fsbr_qh = NULL;
+	list_for_each_entry_reverse(tqh, &uhci->skel_async_qh->node, node) {
+		if (tqh->skel < SKEL_FSBR)
+			break;
+		fsbr_qh = tqh;
+	}
+
+	/* No FSBR QH means we must insert the terminating skeleton QH */
+	if (!fsbr_qh) {
+		uhci->skel_term_qh->link = LINK_TO_QH(uhci->skel_term_qh);
+		wmb();
+		lqh->link = uhci->skel_term_qh->link;
+
+	/* Otherwise loop the last QH to the first FSBR QH */
+	} else
+		lqh->link = LINK_TO_QH(fsbr_qh);
 }
 
 static void uhci_fsbr_off(struct uhci_hcd *uhci)
 {
+	struct uhci_qh *lqh;
+
 	uhci->fsbr_is_on = 0;
-	uhci->skel_term_qh->link = UHCI_PTR_TERM;
+	lqh = list_entry(uhci->skel_async_qh->node.prev,
+			struct uhci_qh, node);
+
+	/* End the async list normally and unlink the terminating QH */
+	lqh->link = uhci->skel_term_qh->link = UHCI_PTR_TERM;
 }
 
 static void uhci_add_fsbr(struct uhci_hcd *uhci, struct urb *urb)
@@ -158,11 +186,11 @@
 
 		td->link = ltd->link;
 		wmb();
-		ltd->link = cpu_to_le32(td->dma_handle);
+		ltd->link = LINK_TO_TD(td);
 	} else {
 		td->link = uhci->frame[framenum];
 		wmb();
-		uhci->frame[framenum] = cpu_to_le32(td->dma_handle);
+		uhci->frame[framenum] = LINK_TO_TD(td);
 		uhci->frame_cpu[framenum] = td;
 	}
 }
@@ -184,7 +212,7 @@
 			struct uhci_td *ntd;
 
 			ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list);
-			uhci->frame[td->frame] = cpu_to_le32(ntd->dma_handle);
+			uhci->frame[td->frame] = LINK_TO_TD(ntd);
 			uhci->frame_cpu[td->frame] = ntd;
 		}
 	} else {
@@ -405,12 +433,81 @@
 }
 
 /*
+ * Link an Isochronous QH into its skeleton's list
+ */
+static inline void link_iso(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+	list_add_tail(&qh->node, &uhci->skel_iso_qh->node);
+
+	/* Isochronous QHs aren't linked by the hardware */
+}
+
+/*
+ * Link a high-period interrupt QH into the schedule at the end of its
+ * skeleton's list
+ */
+static void link_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+	struct uhci_qh *pqh;
+
+	list_add_tail(&qh->node, &uhci->skelqh[qh->skel]->node);
+
+	pqh = list_entry(qh->node.prev, struct uhci_qh, node);
+	qh->link = pqh->link;
+	wmb();
+	pqh->link = LINK_TO_QH(qh);
+}
+
+/*
+ * Link a period-1 interrupt or async QH into the schedule at the
+ * correct spot in the async skeleton's list, and update the FSBR link
+ */
+static void link_async(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+	struct uhci_qh *pqh, *lqh;
+	__le32 link_to_new_qh;
+	__le32 *extra_link = &link_to_new_qh;
+
+	/* Find the predecessor QH for our new one and insert it in the list.
+	 * The list of QHs is expected to be short, so linear search won't
+	 * take too long. */
+	list_for_each_entry_reverse(pqh, &uhci->skel_async_qh->node, node) {
+		if (pqh->skel <= qh->skel)
+			break;
+	}
+	list_add(&qh->node, &pqh->node);
+	qh->link = pqh->link;
+
+	link_to_new_qh = LINK_TO_QH(qh);
+
+	/* If this is now the first FSBR QH, take special action */
+	if (uhci->fsbr_is_on && pqh->skel < SKEL_FSBR &&
+			qh->skel >= SKEL_FSBR) {
+		lqh = list_entry(uhci->skel_async_qh->node.prev,
+				struct uhci_qh, node);
+
+		/* If the new QH is also the last one, we must unlink
+		 * the terminating skeleton QH and make the new QH point
+		 * back to itself. */
+		if (qh == lqh) {
+			qh->link = link_to_new_qh;
+			extra_link = &uhci->skel_term_qh->link;
+
+		/* Otherwise the last QH must point to the new QH */
+		} else
+			extra_link = &lqh->link;
+	}
+
+	/* Link it into the schedule */
+	wmb();
+	*extra_link = pqh->link = link_to_new_qh;
+}
+
+/*
  * Put a QH on the schedule in both hardware and software
  */
 static void uhci_activate_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
 {
-	struct uhci_qh *pqh;
-
 	WARN_ON(list_empty(&qh->queue));
 
 	/* Set the element pointer if it isn't set already.
@@ -421,7 +518,7 @@
 		struct uhci_td *td = list_entry(urbp->td_list.next,
 				struct uhci_td, list);
 
-		qh->element = cpu_to_le32(td->dma_handle);
+		qh->element = LINK_TO_TD(td);
 	}
 
 	/* Treat the queue as if it has just advanced */
@@ -432,18 +529,64 @@
 		return;
 	qh->state = QH_STATE_ACTIVE;
 
-	/* Move the QH from its old list to the end of the appropriate
+	/* Move the QH from its old list to the correct spot in the appropriate
 	 * skeleton's list */
 	if (qh == uhci->next_qh)
 		uhci->next_qh = list_entry(qh->node.next, struct uhci_qh,
 				node);
-	list_move_tail(&qh->node, &qh->skel->node);
+	list_del(&qh->node);
 
-	/* Link it into the schedule */
+	if (qh->skel == SKEL_ISO)
+		link_iso(uhci, qh);
+	else if (qh->skel < SKEL_ASYNC)
+		link_interrupt(uhci, qh);
+	else
+		link_async(uhci, qh);
+}
+
+/*
+ * Unlink a high-period interrupt QH from the schedule
+ */
+static void unlink_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+	struct uhci_qh *pqh;
+
 	pqh = list_entry(qh->node.prev, struct uhci_qh, node);
-	qh->link = pqh->link;
-	wmb();
-	pqh->link = UHCI_PTR_QH | cpu_to_le32(qh->dma_handle);
+	pqh->link = qh->link;
+	mb();
+}
+
+/*
+ * Unlink a period-1 interrupt or async QH from the schedule
+ */
+static void unlink_async(struct uhci_hcd *uhci, struct uhci_qh *qh)
+{
+	struct uhci_qh *pqh, *lqh;
+	__le32 link_to_next_qh = qh->link;
+
+	pqh = list_entry(qh->node.prev, struct uhci_qh, node);
+
+	/* If this is the first FSBQ QH, take special action */
+	if (uhci->fsbr_is_on && pqh->skel < SKEL_FSBR &&
+			qh->skel >= SKEL_FSBR) {
+		lqh = list_entry(uhci->skel_async_qh->node.prev,
+				struct uhci_qh, node);
+
+		/* If this QH is also the last one, we must link in
+		 * the terminating skeleton QH. */
+		if (qh == lqh) {
+			link_to_next_qh = LINK_TO_QH(uhci->skel_term_qh);
+			uhci->skel_term_qh->link = link_to_next_qh;
+			wmb();
+			qh->link = link_to_next_qh;
+
+		/* Otherwise the last QH must point to the new first FSBR QH */
+		} else
+			lqh->link = link_to_next_qh;
+	}
+
+	pqh->link = link_to_next_qh;
+	mb();
 }
 
 /*
@@ -451,17 +594,18 @@
  */
 static void uhci_unlink_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
 {
-	struct uhci_qh *pqh;
-
 	if (qh->state == QH_STATE_UNLINKING)
 		return;
 	WARN_ON(qh->state != QH_STATE_ACTIVE || !qh->udev);
 	qh->state = QH_STATE_UNLINKING;
 
 	/* Unlink the QH from the schedule and record when we did it */
-	pqh = list_entry(qh->node.prev, struct uhci_qh, node);
-	pqh->link = qh->link;
-	mb();
+	if (qh->skel == SKEL_ISO)
+		;
+	else if (qh->skel < SKEL_ASYNC)
+		unlink_interrupt(uhci, qh);
+	else
+		unlink_async(uhci, qh);
 
 	uhci_get_current_frame_number(uhci);
 	qh->unlink_frame = uhci->frame_number;
@@ -697,6 +841,7 @@
 	dma_addr_t data = urb->transfer_dma;
 	__le32 *plink;
 	struct urb_priv *urbp = urb->hcpriv;
+	int skel;
 
 	/* The "pipe" thing contains the destination in bits 8--18 */
 	destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP;
@@ -737,7 +882,7 @@
 		td = uhci_alloc_td(uhci);
 		if (!td)
 			goto nomem;
-		*plink = cpu_to_le32(td->dma_handle);
+		*plink = LINK_TO_TD(td);
 
 		/* Alternate Data0/1 (start with Data1) */
 		destination ^= TD_TOKEN_TOGGLE;
@@ -757,7 +902,7 @@
 	td = uhci_alloc_td(uhci);
 	if (!td)
 		goto nomem;
-	*plink = cpu_to_le32(td->dma_handle);
+	*plink = LINK_TO_TD(td);
 
 	/*
 	 * It's IN if the pipe is an output pipe or we're not expecting
@@ -784,7 +929,7 @@
 	td = uhci_alloc_td(uhci);
 	if (!td)
 		goto nomem;
-	*plink = cpu_to_le32(td->dma_handle);
+	*plink = LINK_TO_TD(td);
 
 	uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
 	wmb();
@@ -797,11 +942,13 @@
 	 * isn't in the CONFIGURED state. */
 	if (urb->dev->speed == USB_SPEED_LOW ||
 			urb->dev->state != USB_STATE_CONFIGURED)
-		qh->skel = uhci->skel_ls_control_qh;
+		skel = SKEL_LS_CONTROL;
 	else {
-		qh->skel = uhci->skel_fs_control_qh;
+		skel = SKEL_FS_CONTROL;
 		uhci_add_fsbr(uhci, urb);
 	}
+	if (qh->state != QH_STATE_ACTIVE)
+		qh->skel = skel;
 
 	urb->actual_length = -8;	/* Account for the SETUP packet */
 	return 0;
@@ -860,7 +1007,7 @@
 			td = uhci_alloc_td(uhci);
 			if (!td)
 				goto nomem;
-			*plink = cpu_to_le32(td->dma_handle);
+			*plink = LINK_TO_TD(td);
 		}
 		uhci_add_td_to_urbp(td, urbp);
 		uhci_fill_td(td, status,
@@ -888,7 +1035,7 @@
 		td = uhci_alloc_td(uhci);
 		if (!td)
 			goto nomem;
-		*plink = cpu_to_le32(td->dma_handle);
+		*plink = LINK_TO_TD(td);
 
 		uhci_add_td_to_urbp(td, urbp);
 		uhci_fill_td(td, status,
@@ -914,7 +1061,7 @@
 	td = uhci_alloc_td(uhci);
 	if (!td)
 		goto nomem;
-	*plink = cpu_to_le32(td->dma_handle);
+	*plink = LINK_TO_TD(td);
 
 	uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0);
 	wmb();
@@ -931,7 +1078,7 @@
 	return -ENOMEM;
 }
 
-static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb,
+static int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb,
 		struct uhci_qh *qh)
 {
 	int ret;
@@ -940,7 +1087,8 @@
 	if (urb->dev->speed == USB_SPEED_LOW)
 		return -EINVAL;
 
-	qh->skel = uhci->skel_bulk_qh;
+	if (qh->state != QH_STATE_ACTIVE)
+		qh->skel = SKEL_BULK;
 	ret = uhci_submit_common(uhci, urb, qh);
 	if (ret == 0)
 		uhci_add_fsbr(uhci, urb);
@@ -968,7 +1116,7 @@
 		if (exponent < 0)
 			return -EINVAL;
 		qh->period = 1 << exponent;
-		qh->skel = uhci->skelqh[UHCI_SKEL_INDEX(exponent)];
+		qh->skel = SKEL_INDEX(exponent);
 
 		/* For now, interrupt phase is fixed by the layout
 		 * of the QH lists. */
@@ -1005,7 +1153,7 @@
 		 * the queue at the status stage transaction, which is
 		 * the last TD. */
 		WARN_ON(list_empty(&urbp->td_list));
-		qh->element = cpu_to_le32(td->dma_handle);
+		qh->element = LINK_TO_TD(td);
 		tmp = td->list.prev;
 		ret = -EINPROGRESS;
 
@@ -1216,7 +1364,7 @@
 		qh->iso_status = 0;
 	}
 
-	qh->skel = uhci->skel_iso_qh;
+	qh->skel = SKEL_ISO;
 	if (!qh->bandwidth_reserved)
 		uhci_reserve_bandwidth(uhci, qh);
 	return 0;
@@ -1566,8 +1714,7 @@
 	if (time_after(jiffies, qh->advance_jiffies + QH_WAIT_TIMEOUT)) {
 
 		/* Detect the Intel bug and work around it */
-		if (qh->post_td && qh_element(qh) ==
-				cpu_to_le32(qh->post_td->dma_handle)) {
+		if (qh->post_td && qh_element(qh) == LINK_TO_TD(qh->post_td)) {
 			qh->element = qh->post_td->link;
 			qh->advance_jiffies = jiffies;
 			ret = 1;
diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c
index 8505824..3749f4a 100644
--- a/drivers/usb/input/usbkbd.c
+++ b/drivers/usb/input/usbkbd.c
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/usb/input.h>
+#include <linux/hid.h>
 
 /*
  * Version Information
@@ -330,7 +331,8 @@
 }
 
 static struct usb_device_id usb_kbd_id_table [] = {
-	{ USB_INTERFACE_INFO(3, 1, 1) },
+	{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
+		USB_INTERFACE_PROTOCOL_KEYBOARD) },
 	{ }						/* Terminating entry */
 };
 
diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c
index 64a33e4..692fd60 100644
--- a/drivers/usb/input/usbmouse.c
+++ b/drivers/usb/input/usbmouse.c
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/usb/input.h>
+#include <linux/hid.h>
 
 /*
  * Version Information
@@ -213,7 +214,8 @@
 }
 
 static struct usb_device_id usb_mouse_id_table [] = {
-	{ USB_INTERFACE_INFO(3, 1, 2) },
+	{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
+		USB_INTERFACE_PROTOCOL_MOUSE) },
 	{ }	/* Terminating entry */
 };
 
diff --git a/drivers/usb/input/wacom_wac.c b/drivers/usb/input/wacom_wac.c
index 4142e36..4f3e9bc 100644
--- a/drivers/usb/input/wacom_wac.c
+++ b/drivers/usb/input/wacom_wac.c
@@ -163,7 +163,7 @@
 	}
 
 	id = STYLUS_DEVICE_ID;
-	if (data[1] & 0x10) { /* in prox */
+	if (data[1] & 0x80) { /* in prox */
 
 		switch ((data[1] >> 5) & 3) {
 
@@ -196,9 +196,6 @@
 					wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
 				break;
 		}
-	}
-
-	if (data[1] & 0x90) {
 		x = wacom_le16_to_cpu(&data[2]);
 		y = wacom_le16_to_cpu(&data[4]);
 		wacom_report_abs(wcombo, ABS_X, x);
@@ -210,19 +207,28 @@
 			wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04);
 		}
 		wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */
-	}
-	else
-		wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
-
-	if (data[1] & 0x10)  /* only report prox-in when in area */
 		wacom_report_key(wcombo, wacom->tool[0], 1);
-	if (!(data[1] & 0x90))  /* report prox-out when physically out */
+	} else if (!(data[1] & 0x90)) {
+		wacom_report_abs(wcombo, ABS_X, 0);
+		wacom_report_abs(wcombo, ABS_Y, 0);
+		if (wacom->tool[0] == BTN_TOOL_MOUSE) {
+			wacom_report_key(wcombo, BTN_LEFT, 0);
+			wacom_report_key(wcombo, BTN_RIGHT, 0);
+			wacom_report_abs(wcombo, ABS_DISTANCE, 0);
+		} else {
+			wacom_report_abs(wcombo, ABS_PRESSURE, 0);
+			wacom_report_key(wcombo, BTN_TOUCH, 0);
+			wacom_report_key(wcombo, BTN_STYLUS, 0);
+			wacom_report_key(wcombo, BTN_STYLUS2, 0);
+		}
+		wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
 		wacom_report_key(wcombo, wacom->tool[0], 0);
-	wacom_input_sync(wcombo);
+	}
 
 	/* send pad data */
 	if (wacom->features->type == WACOM_G4) {
-		if ( (wacom->serial[1] & 0xc0) != (data[7] & 0xf8) ) {
+		if (data[7] & 0xf8) {
+			wacom_input_sync(wcombo); /* sync last event */
 			wacom->id[1] = 1;
 			wacom->serial[1] = (data[7] & 0xf8);
 			wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
@@ -230,10 +236,15 @@
 			rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3);
 			wacom_report_rel(wcombo, REL_WHEEL, rw);
 			wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
+			wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID);
 			wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
 		} else if (wacom->id[1]) {
+			wacom_input_sync(wcombo); /* sync last event */
 			wacom->id[1] = 0;
+			wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
+			wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
 			wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
+			wacom_report_abs(wcombo, ABS_MISC, 0);
 			wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
 		}
 	}
@@ -304,28 +315,35 @@
 			default: /* Unknown tool */
 				wacom->tool[idx] = BTN_TOOL_PEN;
 		}
-		/* only large I3 support Lens Cursor */
-		if(!((wacom->tool[idx] == BTN_TOOL_LENS)
-				 && ((wacom->features->type == INTUOS3)
-				 || (wacom->features->type == INTUOS3S)))) {
-			wacom_report_abs(wcombo, ABS_MISC, wacom->id[idx]); /* report tool id */
-			wacom_report_key(wcombo, wacom->tool[idx], 1);
-			wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
-			return 2;
-		}
 		return 1;
 	}
 
 	/* Exit report */
 	if ((data[1] & 0xfe) == 0x80) {
- 		if(!((wacom->tool[idx] == BTN_TOOL_LENS)
-				 && ((wacom->features->type == INTUOS3)
-				 || (wacom->features->type == INTUOS3S)))) {
-			wacom_report_key(wcombo, wacom->tool[idx], 0);
-			wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
-			wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
-			return 2;
+		wacom_report_abs(wcombo, ABS_X, 0);
+		wacom_report_abs(wcombo, ABS_Y, 0);
+		wacom_report_abs(wcombo, ABS_DISTANCE, 0);
+		if (wacom->tool[idx] >= BTN_TOOL_MOUSE) {
+			wacom_report_key(wcombo, BTN_LEFT, 0);
+			wacom_report_key(wcombo, BTN_MIDDLE, 0);
+			wacom_report_key(wcombo, BTN_RIGHT, 0);
+			wacom_report_key(wcombo, BTN_SIDE, 0);
+			wacom_report_key(wcombo, BTN_EXTRA, 0);
+			wacom_report_abs(wcombo, ABS_THROTTLE, 0);
+			wacom_report_abs(wcombo, ABS_RZ, 0);
+ 		} else {
+			wacom_report_abs(wcombo, ABS_PRESSURE, 0);
+			wacom_report_abs(wcombo, ABS_TILT_X, 0);
+			wacom_report_abs(wcombo, ABS_TILT_Y, 0);
+			wacom_report_key(wcombo, BTN_STYLUS, 0);
+			wacom_report_key(wcombo, BTN_STYLUS2, 0);
+			wacom_report_key(wcombo, BTN_TOUCH, 0);
+			wacom_report_abs(wcombo, ABS_WHEEL, 0);
 		}
+		wacom_report_key(wcombo, wacom->tool[idx], 0);
+		wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
+		wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
+		return 2;
 	}
 	return 0;
 }
@@ -394,6 +412,7 @@
 			wacom_report_key(wcombo, wacom->tool[1], 1);
 		else
 			wacom_report_key(wcombo, wacom->tool[1], 0);
+		wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID);
 		wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xffffffff);
                 return 1;
 	}
@@ -403,6 +422,12 @@
 	if (result)
                 return result-1;
 
+	/* Only large I3 and I1 & I2 support Lense Cursor */
+ 	if((wacom->tool[idx] == BTN_TOOL_LENS)
+			&& ((wacom->features->type == INTUOS3)
+		 	|| (wacom->features->type == INTUOS3S)))
+		return 0;
+
 	/* Cintiq doesn't send data when RDY bit isn't set */
 	if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40))
                  return 0;
@@ -554,11 +579,11 @@
 	{ "Wacom Volito2 4x5",   8,   5104,  3712,  511, 63, GRAPHIRE },
 	{ "Wacom Volito2 2x3",   8,   3248,  2320,  511, 63, GRAPHIRE },
 	{ "Wacom PenPartner2",   8,   3250,  2320,  255, 63, GRAPHIRE },
-	{ "Wacom Intuos 4x5",   10,  12700, 10600, 1023, 63, INTUOS },
-	{ "Wacom Intuos 6x8",   10,  20320, 16240, 1023, 63, INTUOS },
-	{ "Wacom Intuos 9x12",  10,  30480, 24060, 1023, 63, INTUOS },
-	{ "Wacom Intuos 12x12", 10,  30480, 31680, 1023, 63, INTUOS },
-	{ "Wacom Intuos 12x18", 10,  45720, 31680, 1023, 63, INTUOS },
+	{ "Wacom Intuos 4x5",   10,  12700, 10600, 1023, 31, INTUOS },
+	{ "Wacom Intuos 6x8",   10,  20320, 16240, 1023, 31, INTUOS },
+	{ "Wacom Intuos 9x12",  10,  30480, 24060, 1023, 31, INTUOS },
+	{ "Wacom Intuos 12x12", 10,  30480, 31680, 1023, 31, INTUOS },
+	{ "Wacom Intuos 12x18", 10,  45720, 31680, 1023, 31, INTUOS },
 	{ "Wacom PL400",         8,   5408,  4056,  255,  0, PL },
 	{ "Wacom PL500",         8,   6144,  4608,  255,  0, PL },
 	{ "Wacom PL600",         8,   6126,  4604,  255,  0, PL },
@@ -571,11 +596,11 @@
 	{ "Wacom DTF521",        8,   6282,  4762,  511,  0, PL },
 	{ "Wacom DTF720",        8,   6858,  5506,  511,  0, PL },
 	{ "Wacom Cintiq Partner",8,  20480, 15360,  511,  0, PTU },
-	{ "Wacom Intuos2 4x5",   10, 12700, 10600, 1023, 63, INTUOS },
-	{ "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 63, INTUOS },
-	{ "Wacom Intuos2 9x12",  10, 30480, 24060, 1023, 63, INTUOS },
-	{ "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 63, INTUOS },
-	{ "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 63, INTUOS },
+	{ "Wacom Intuos2 4x5",   10, 12700, 10600, 1023, 31, INTUOS },
+	{ "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 31, INTUOS },
+	{ "Wacom Intuos2 9x12",  10, 30480, 24060, 1023, 31, INTUOS },
+	{ "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 31, INTUOS },
+	{ "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 31, INTUOS },
 	{ "Wacom Intuos3 4x5",   10, 25400, 20320, 1023, 63, INTUOS3S },
 	{ "Wacom Intuos3 6x8",   10, 40640, 30480, 1023, 63, INTUOS3 },
 	{ "Wacom Intuos3 9x12",  10, 60960, 45720, 1023, 63, INTUOS3 },
@@ -584,7 +609,7 @@
 	{ "Wacom Intuos3 6x11",  10, 54204, 31750, 1023, 63, INTUOS3 },
 	{ "Wacom Intuos3 4x6",   10, 31496, 19685, 1023, 63, INTUOS3S },
 	{ "Wacom Cintiq 21UX",   10, 87200, 65600, 1023, 63, CINTIQ },
-	{ "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 63, INTUOS },
+	{ "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 31, INTUOS },
 	{ }
 };
 
diff --git a/drivers/usb/input/wacom_wac.h b/drivers/usb/input/wacom_wac.h
index a1d9ce0..a230222 100644
--- a/drivers/usb/input/wacom_wac.h
+++ b/drivers/usb/input/wacom_wac.h
@@ -12,6 +12,7 @@
 #define STYLUS_DEVICE_ID	0x02
 #define CURSOR_DEVICE_ID	0x06
 #define ERASER_DEVICE_ID	0x0A
+#define PAD_DEVICE_ID		0x0F
 
 enum {
 	PENPARTNER = 0,
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index 4907e8b..9c7eb61 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -244,6 +244,20 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called trancevibrator.
 
+config USB_IOWARRIOR
+	tristate "IO Warrior driver support"
+	depends on USB
+	help
+	  Say Y here if you want to support the IO Warrior devices from Code
+	  Mercenaries.  This includes support for the following devices:
+	  	IO Warrior 40
+		IO Warrior 24
+		IO Warrior 56
+		IO Warrior 24 Power Vampire
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called iowarrior.
+
 config USB_TEST
 	tristate "USB testing driver (DEVELOPMENT)"
 	depends on USB && USB_DEVICEFS && EXPERIMENTAL
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
index dac2d5b..b68e6b7 100644
--- a/drivers/usb/misc/Makefile
+++ b/drivers/usb/misc/Makefile
@@ -13,6 +13,7 @@
 obj-$(CONFIG_USB_EMI62)		+= emi62.o
 obj-$(CONFIG_USB_FTDI_ELAN)	+= ftdi-elan.o
 obj-$(CONFIG_USB_IDMOUSE)	+= idmouse.o
+obj-$(CONFIG_USB_IOWARRIOR)	+= iowarrior.o
 obj-$(CONFIG_USB_LCD)		+= usblcd.o
 obj-$(CONFIG_USB_LD)		+= ldusb.o
 obj-$(CONFIG_USB_LED)		+= usbled.o
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
new file mode 100644
index 0000000..d69665c
--- /dev/null
+++ b/drivers/usb/misc/iowarrior.c
@@ -0,0 +1,925 @@
+/*
+ *  Native support for the I/O-Warrior USB devices
+ *
+ *  Copyright (c) 2003-2005  Code Mercenaries GmbH
+ *  written by Christian Lucht <lucht@codemercs.com>
+ *
+ *  based on
+
+ *  usb-skeleton.c by Greg Kroah-Hartman  <greg@kroah.com>
+ *  brlvger.c by Stephane Dalton  <sdalton@videotron.ca>
+ *           and St�hane Doyon   <s.doyon@videotron.ca>
+ *
+ *  Released under the GPLv2.
+ */
+
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/version.h>
+#include <linux/usb/iowarrior.h>
+
+/* Version Information */
+#define DRIVER_VERSION "v0.4.0"
+#define DRIVER_AUTHOR "Christian Lucht <lucht@codemercs.com>"
+#define DRIVER_DESC "USB IO-Warrior driver (Linux 2.6.x)"
+
+#define USB_VENDOR_ID_CODEMERCS		1984
+/* low speed iowarrior */
+#define USB_DEVICE_ID_CODEMERCS_IOW40	0x1500
+#define USB_DEVICE_ID_CODEMERCS_IOW24	0x1501
+#define USB_DEVICE_ID_CODEMERCS_IOWPV1	0x1511
+#define USB_DEVICE_ID_CODEMERCS_IOWPV2	0x1512
+/* full speed iowarrior */
+#define USB_DEVICE_ID_CODEMERCS_IOW56	0x1503
+
+/* Get a minor range for your devices from the usb maintainer */
+#ifdef CONFIG_USB_DYNAMIC_MINORS
+#define IOWARRIOR_MINOR_BASE	0
+#else
+#define IOWARRIOR_MINOR_BASE	208	// SKELETON_MINOR_BASE 192 + 16, not offical yet
+#endif
+
+/* interrupt input queue size */
+#define MAX_INTERRUPT_BUFFER 16
+/*
+   maximum number of urbs that are submitted for writes at the same time,
+   this applies to the IOWarrior56 only!
+   IOWarrior24 and IOWarrior40 use synchronous usb_control_msg calls.
+*/
+#define MAX_WRITES_IN_FLIGHT 4
+
+/* Use our own dbg macro */
+#undef dbg
+#define dbg( format, arg... ) do { if( debug ) printk( KERN_DEBUG __FILE__ ": " format "\n" , ## arg ); } while ( 0 )
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+/* Module parameters */
+static int debug = 0;
+module_param(debug, bool, 0644);
+MODULE_PARM_DESC(debug, "debug=1 enables debugging messages");
+
+static struct usb_driver iowarrior_driver;
+
+/*--------------*/
+/*     data     */
+/*--------------*/
+
+/* Structure to hold all of our device specific stuff */
+struct iowarrior {
+	struct mutex mutex;			/* locks this structure */
+	struct usb_device *udev;		/* save off the usb device pointer */
+	struct usb_interface *interface;	/* the interface for this device */
+	unsigned char minor;			/* the starting minor number for this device */
+	struct usb_endpoint_descriptor *int_out_endpoint;	/* endpoint for reading (needed for IOW56 only) */
+	struct usb_endpoint_descriptor *int_in_endpoint;	/* endpoint for reading */
+	struct urb *int_in_urb;		/* the urb for reading data */
+	unsigned char *int_in_buffer;	/* buffer for data to be read */
+	unsigned char serial_number;	/* to detect lost packages */
+	unsigned char *read_queue;	/* size is MAX_INTERRUPT_BUFFER * packet size */
+	wait_queue_head_t read_wait;
+	wait_queue_head_t write_wait;	/* wait-queue for writing to the device */
+	atomic_t write_busy;		/* number of write-urbs submitted */
+	atomic_t read_idx;
+	atomic_t intr_idx;
+	spinlock_t intr_idx_lock;	/* protects intr_idx */
+	atomic_t overflow_flag;		/* signals an index 'rollover' */
+	int present;			/* this is 1 as long as the device is connected */
+	int opened;			/* this is 1 if the device is currently open */
+	char chip_serial[9];		/* the serial number string of the chip connected */
+	int report_size;		/* number of bytes in a report */
+	u16 product_id;
+};
+
+/*--------------*/
+/*    globals   */
+/*--------------*/
+/* prevent races between open() and disconnect() */
+static DECLARE_MUTEX(disconnect_sem);
+
+/*
+ *  USB spec identifies 5 second timeouts.
+ */
+#define GET_TIMEOUT 5
+#define USB_REQ_GET_REPORT  0x01
+//#if 0
+static int usb_get_report(struct usb_device *dev,
+			  struct usb_host_interface *inter, unsigned char type,
+			  unsigned char id, void *buf, int size)
+{
+	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+			       USB_REQ_GET_REPORT,
+			       USB_DIR_IN | USB_TYPE_CLASS |
+			       USB_RECIP_INTERFACE, (type << 8) + id,
+			       inter->desc.bInterfaceNumber, buf, size,
+			       GET_TIMEOUT);
+}
+//#endif
+
+#define USB_REQ_SET_REPORT 0x09
+
+static int usb_set_report(struct usb_interface *intf, unsigned char type,
+			  unsigned char id, void *buf, int size)
+{
+	return usb_control_msg(interface_to_usbdev(intf),
+			       usb_sndctrlpipe(interface_to_usbdev(intf), 0),
+			       USB_REQ_SET_REPORT,
+			       USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+			       (type << 8) + id,
+			       intf->cur_altsetting->desc.bInterfaceNumber, buf,
+			       size, 1);
+}
+
+/*---------------------*/
+/* driver registration */
+/*---------------------*/
+/* table of devices that work with this driver */
+static struct usb_device_id iowarrior_ids[] = {
+	{USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40)},
+	{USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24)},
+	{USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOWPV1)},
+	{USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOWPV2)},
+	{USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW56)},
+	{}			/* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, iowarrior_ids);
+
+/*
+ * USB callback handler for reading data
+ */
+static void iowarrior_callback(struct urb *urb)
+{
+	struct iowarrior *dev = (struct iowarrior *)urb->context;
+	int intr_idx;
+	int read_idx;
+	int aux_idx;
+	int offset;
+	int status;
+
+	switch (urb->status) {
+	case 0:
+		/* success */
+		break;
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		return;
+	default:
+		goto exit;
+	}
+
+	spin_lock(&dev->intr_idx_lock);
+	intr_idx = atomic_read(&dev->intr_idx);
+	/* aux_idx become previous intr_idx */
+	aux_idx = (intr_idx == 0) ? (MAX_INTERRUPT_BUFFER - 1) : (intr_idx - 1);
+	read_idx = atomic_read(&dev->read_idx);
+
+	/* queue is not empty and it's interface 0 */
+	if ((intr_idx != read_idx)
+	    && (dev->interface->cur_altsetting->desc.bInterfaceNumber == 0)) {
+		/* + 1 for serial number */
+		offset = aux_idx * (dev->report_size + 1);
+		if (!memcmp
+		    (dev->read_queue + offset, urb->transfer_buffer,
+		     dev->report_size)) {
+			/* equal values on interface 0 will be ignored */
+			spin_unlock(&dev->intr_idx_lock);
+			goto exit;
+		}
+	}
+
+	/* aux_idx become next intr_idx */
+	aux_idx = (intr_idx == (MAX_INTERRUPT_BUFFER - 1)) ? 0 : (intr_idx + 1);
+	if (read_idx == aux_idx) {
+		/* queue full, dropping oldest input */
+		read_idx = (++read_idx == MAX_INTERRUPT_BUFFER) ? 0 : read_idx;
+		atomic_set(&dev->read_idx, read_idx);
+		atomic_set(&dev->overflow_flag, 1);
+	}
+
+	/* +1 for serial number */
+	offset = intr_idx * (dev->report_size + 1);
+	memcpy(dev->read_queue + offset, urb->transfer_buffer,
+	       dev->report_size);
+	*(dev->read_queue + offset + (dev->report_size)) = dev->serial_number++;
+
+	atomic_set(&dev->intr_idx, aux_idx);
+	spin_unlock(&dev->intr_idx_lock);
+	/* tell the blocking read about the new data */
+	wake_up_interruptible(&dev->read_wait);
+
+exit:
+	status = usb_submit_urb(urb, GFP_ATOMIC);
+	if (status)
+		dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d",
+			__FUNCTION__, status);
+
+}
+
+/*
+ * USB Callback handler for write-ops
+ */
+static void iowarrior_write_callback(struct urb *urb)
+{
+	struct iowarrior *dev;
+	dev = (struct iowarrior *)urb->context;
+	/* sync/async unlink faults aren't errors */
+	if (urb->status &&
+	    !(urb->status == -ENOENT ||
+	      urb->status == -ECONNRESET || urb->status == -ESHUTDOWN)) {
+		dbg("%s - nonzero write bulk status received: %d",
+		    __func__, urb->status);
+	}
+	/* free up our allocated buffer */
+	usb_buffer_free(urb->dev, urb->transfer_buffer_length,
+			urb->transfer_buffer, urb->transfer_dma);
+	/* tell a waiting writer the interrupt-out-pipe is available again */
+	atomic_dec(&dev->write_busy);
+	wake_up_interruptible(&dev->write_wait);
+}
+
+/**
+ *	iowarrior_delete
+ */
+static inline void iowarrior_delete(struct iowarrior *dev)
+{
+	dbg("%s - minor %d", __func__, dev->minor);
+	kfree(dev->int_in_buffer);
+	usb_free_urb(dev->int_in_urb);
+	kfree(dev->read_queue);
+	kfree(dev);
+}
+
+/*---------------------*/
+/* fops implementation */
+/*---------------------*/
+
+static int read_index(struct iowarrior *dev)
+{
+	int intr_idx, read_idx;
+
+	read_idx = atomic_read(&dev->read_idx);
+	intr_idx = atomic_read(&dev->intr_idx);
+
+	return (read_idx == intr_idx ? -1 : read_idx);
+}
+
+/**
+ *  iowarrior_read
+ */
+static ssize_t iowarrior_read(struct file *file, char __user *buffer,
+			      size_t count, loff_t *ppos)
+{
+	struct iowarrior *dev;
+	int read_idx;
+	int offset;
+
+	dev = (struct iowarrior *)file->private_data;
+
+	/* verify that the device wasn't unplugged */
+	if (dev == NULL || !dev->present)
+		return -ENODEV;
+
+	dbg("%s - minor %d, count = %zd", __func__, dev->minor, count);
+
+	/* read count must be packet size (+ time stamp) */
+	if ((count != dev->report_size)
+	    && (count != (dev->report_size + 1)))
+		return -EINVAL;
+
+	/* repeat until no buffer overrun in callback handler occur */
+	do {
+		atomic_set(&dev->overflow_flag, 0);
+		if ((read_idx = read_index(dev)) == -1) {
+			/* queue emty */
+			if (file->f_flags & O_NONBLOCK)
+				return -EAGAIN;
+			else {
+				//next line will return when there is either new data, or the device is unplugged
+				int r = wait_event_interruptible(dev->read_wait,
+								 (!dev->present
+								  || (read_idx =
+								      read_index
+								      (dev)) !=
+								  -1));
+				if (r) {
+					//we were interrupted by a signal
+					return -ERESTART;
+				}
+				if (!dev->present) {
+					//The device was unplugged
+					return -ENODEV;
+				}
+				if (read_idx == -1) {
+					// Can this happen ???
+					return 0;
+				}
+			}
+		}
+
+		offset = read_idx * (dev->report_size + 1);
+		if (copy_to_user(buffer, dev->read_queue + offset, count)) {
+			return -EFAULT;
+		}
+	} while (atomic_read(&dev->overflow_flag));
+
+	read_idx = ++read_idx == MAX_INTERRUPT_BUFFER ? 0 : read_idx;
+	atomic_set(&dev->read_idx, read_idx);
+	return count;
+}
+
+/*
+ * iowarrior_write
+ */
+static ssize_t iowarrior_write(struct file *file,
+			       const char __user *user_buffer,
+			       size_t count, loff_t *ppos)
+{
+	struct iowarrior *dev;
+	int retval = 0;
+	char *buf = NULL;	/* for IOW24 and IOW56 we need a buffer */
+	struct urb *int_out_urb = NULL;
+
+	dev = (struct iowarrior *)file->private_data;
+
+	mutex_lock(&dev->mutex);
+	/* verify that the device wasn't unplugged */
+	if (dev == NULL || !dev->present) {
+		retval = -ENODEV;
+		goto exit;
+	}
+	dbg("%s - minor %d, count = %zd", __func__, dev->minor, count);
+	/* if count is 0 we're already done */
+	if (count == 0) {
+		retval = 0;
+		goto exit;
+	}
+	/* We only accept full reports */
+	if (count != dev->report_size) {
+		retval = -EINVAL;
+		goto exit;
+	}
+	switch (dev->product_id) {
+	case USB_DEVICE_ID_CODEMERCS_IOW24:
+	case USB_DEVICE_ID_CODEMERCS_IOWPV1:
+	case USB_DEVICE_ID_CODEMERCS_IOWPV2:
+	case USB_DEVICE_ID_CODEMERCS_IOW40:
+		/* IOW24 and IOW40 use a synchronous call */
+		buf = kmalloc(8, GFP_KERNEL);	/* 8 bytes are enough for both products */
+		if (!buf) {
+			retval = -ENOMEM;
+			goto exit;
+		}
+		if (copy_from_user(buf, user_buffer, count)) {
+			retval = -EFAULT;
+			kfree(buf);
+			goto exit;
+		}
+		retval = usb_set_report(dev->interface, 2, 0, buf, count);
+		kfree(buf);
+		goto exit;
+		break;
+	case USB_DEVICE_ID_CODEMERCS_IOW56:
+		/* The IOW56 uses asynchronous IO and more urbs */
+		if (atomic_read(&dev->write_busy) == MAX_WRITES_IN_FLIGHT) {
+			/* Wait until we are below the limit for submitted urbs */
+			if (file->f_flags & O_NONBLOCK) {
+				retval = -EAGAIN;
+				goto exit;
+			} else {
+				retval = wait_event_interruptible(dev->write_wait,
+								  (!dev->present || (atomic_read (&dev-> write_busy) < MAX_WRITES_IN_FLIGHT)));
+				if (retval) {
+					/* we were interrupted by a signal */
+					retval = -ERESTART;
+					goto exit;
+				}
+				if (!dev->present) {
+					/* The device was unplugged */
+					retval = -ENODEV;
+					goto exit;
+				}
+				if (!dev->opened) {
+					/* We were closed while waiting for an URB */
+					retval = -ENODEV;
+					goto exit;
+				}
+			}
+		}
+		atomic_inc(&dev->write_busy);
+		int_out_urb = usb_alloc_urb(0, GFP_KERNEL);
+		if (!int_out_urb) {
+			retval = -ENOMEM;
+			dbg("%s Unable to allocate urb ", __func__);
+			goto error;
+		}
+		buf = usb_buffer_alloc(dev->udev, dev->report_size,
+				       GFP_KERNEL, &int_out_urb->transfer_dma);
+		if (!buf) {
+			retval = -ENOMEM;
+			dbg("%s Unable to allocate buffer ", __func__);
+			goto error;
+		}
+		usb_fill_int_urb(int_out_urb, dev->udev,
+				 usb_sndintpipe(dev->udev,
+						dev->int_out_endpoint->bEndpointAddress),
+				 buf, dev->report_size,
+				 iowarrior_write_callback, dev,
+				 dev->int_out_endpoint->bInterval);
+		int_out_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+		if (copy_from_user(buf, user_buffer, count)) {
+			retval = -EFAULT;
+			goto error;
+		}
+		retval = usb_submit_urb(int_out_urb, GFP_KERNEL);
+		if (retval) {
+			dbg("%s submit error %d for urb nr.%d", __func__,
+			    retval, atomic_read(&dev->write_busy));
+			goto error;
+		}
+		/* submit was ok */
+		retval = count;
+		usb_free_urb(int_out_urb);
+		goto exit;
+		break;
+	default:
+		/* what do we have here ? An unsupported Product-ID ? */
+		dev_err(&dev->interface->dev, "%s - not supported for product=0x%x",
+			__FUNCTION__, dev->product_id);
+		retval = -EFAULT;
+		goto exit;
+		break;
+	}
+error:
+	usb_buffer_free(dev->udev, dev->report_size, buf,
+			int_out_urb->transfer_dma);
+	usb_free_urb(int_out_urb);
+	atomic_dec(&dev->write_busy);
+	wake_up_interruptible(&dev->write_wait);
+exit:
+	mutex_unlock(&dev->mutex);
+	return retval;
+}
+
+/**
+ *	iowarrior_ioctl
+ */
+static int iowarrior_ioctl(struct inode *inode, struct file *file,
+			   unsigned int cmd, unsigned long arg)
+{
+	struct iowarrior *dev = NULL;
+	__u8 *buffer;
+	__u8 __user *user_buffer;
+	int retval;
+	int io_res;		/* checks for bytes read/written and copy_to/from_user results */
+
+	dev = (struct iowarrior *)file->private_data;
+	if (dev == NULL) {
+		return -ENODEV;
+	}
+
+	buffer = kzalloc(dev->report_size, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	/* lock this object */
+	mutex_lock(&dev->mutex);
+
+	/* verify that the device wasn't unplugged */
+	if (!dev->present) {
+		mutex_unlock(&dev->mutex);
+		return -ENODEV;
+	}
+
+	dbg("%s - minor %d, cmd 0x%.4x, arg %ld", __func__, dev->minor, cmd,
+	    arg);
+
+	retval = 0;
+	io_res = 0;
+	switch (cmd) {
+	case IOW_WRITE:
+		if (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW24 ||
+		    dev->product_id == USB_DEVICE_ID_CODEMERCS_IOWPV1 ||
+		    dev->product_id == USB_DEVICE_ID_CODEMERCS_IOWPV2 ||
+		    dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW40) {
+			user_buffer = (__u8 __user *)arg;
+			io_res = copy_from_user(buffer, user_buffer,
+						dev->report_size);
+			if (io_res) {
+				retval = -EFAULT;
+			} else {
+				io_res = usb_set_report(dev->interface, 2, 0,
+							buffer,
+							dev->report_size);
+				if (io_res < 0)
+					retval = io_res;
+			}
+		} else {
+			retval = -EINVAL;
+			dev_err(&dev->interface->dev,
+				"ioctl 'IOW_WRITE' is not supported for product=0x%x.",
+				dev->product_id);
+		}
+		break;
+	case IOW_READ:
+		user_buffer = (__u8 __user *)arg;
+		io_res = usb_get_report(dev->udev,
+					dev->interface->cur_altsetting, 1, 0,
+					buffer, dev->report_size);
+		if (io_res < 0)
+			retval = io_res;
+		else {
+			io_res = copy_to_user(user_buffer, buffer, dev->report_size);
+			if (io_res < 0)
+				retval = -EFAULT;
+		}
+		break;
+	case IOW_GETINFO:
+		{
+			/* Report available information for the device */
+			struct iowarrior_info info;
+			/* needed for power consumption */
+			struct usb_config_descriptor *cfg_descriptor = &dev->udev->actconfig->desc;
+
+			/* directly from the descriptor */
+			info.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
+			info.product = dev->product_id;
+			info.revision = le16_to_cpu(dev->udev->descriptor.bcdDevice);
+
+			/* 0==UNKNOWN, 1==LOW(usb1.1) ,2=FULL(usb1.1), 3=HIGH(usb2.0) */
+			info.speed = le16_to_cpu(dev->udev->speed);
+			info.if_num = dev->interface->cur_altsetting->desc.bInterfaceNumber;
+			info.report_size = dev->report_size;
+
+			/* serial number string has been read earlier 8 chars or empty string */
+			memcpy(info.serial, dev->chip_serial,
+			       sizeof(dev->chip_serial));
+			if (cfg_descriptor == NULL) {
+				info.power = -1;	/* no information available */
+			} else {
+				/* the MaxPower is stored in units of 2mA to make it fit into a byte-value */
+				info.power = cfg_descriptor->bMaxPower * 2;
+			}
+			io_res = copy_to_user((struct iowarrior_info __user *)arg, &info,
+					 sizeof(struct iowarrior_info));
+			if (io_res < 0)
+				retval = -EFAULT;
+			break;
+		}
+	default:
+		/* return that we did not understand this ioctl call */
+		retval = -ENOTTY;
+		break;
+	}
+
+	/* unlock the device */
+	mutex_unlock(&dev->mutex);
+	return retval;
+}
+
+/**
+ *	iowarrior_open
+ */
+static int iowarrior_open(struct inode *inode, struct file *file)
+{
+	struct iowarrior *dev = NULL;
+	struct usb_interface *interface;
+	int subminor;
+	int retval = 0;
+
+	dbg("%s", __func__);
+
+	subminor = iminor(inode);
+
+	/* prevent disconnects */
+	down(&disconnect_sem);
+
+	interface = usb_find_interface(&iowarrior_driver, subminor);
+	if (!interface) {
+		err("%s - error, can't find device for minor %d", __FUNCTION__,
+		    subminor);
+		retval = -ENODEV;
+		goto out;
+	}
+
+	dev = usb_get_intfdata(interface);
+	if (!dev) {
+		retval = -ENODEV;
+		goto out;
+	}
+
+	/* Only one process can open each device, no sharing. */
+	if (dev->opened) {
+		retval = -EBUSY;
+		goto out;
+	}
+
+	/* setup interrupt handler for receiving values */
+	if ((retval = usb_submit_urb(dev->int_in_urb, GFP_KERNEL)) < 0) {
+		dev_err(&interface->dev, "Error %d while submitting URB\n", retval);
+		retval = -EFAULT;
+		goto out;
+	}
+	/* increment our usage count for the driver */
+	++dev->opened;
+	/* save our object in the file's private structure */
+	file->private_data = dev;
+	retval = 0;
+
+out:
+	up(&disconnect_sem);
+	return retval;
+}
+
+/**
+ *	iowarrior_release
+ */
+static int iowarrior_release(struct inode *inode, struct file *file)
+{
+	struct iowarrior *dev;
+	int retval = 0;
+
+	dev = (struct iowarrior *)file->private_data;
+	if (dev == NULL) {
+		return -ENODEV;
+	}
+
+	dbg("%s - minor %d", __func__, dev->minor);
+
+	/* lock our device */
+	mutex_lock(&dev->mutex);
+
+	if (dev->opened <= 0) {
+		retval = -ENODEV;	/* close called more than once */
+		mutex_unlock(&dev->mutex);
+	} else {
+		dev->opened = 0;	/* we're closeing now */
+		retval = 0;
+		if (dev->present) {
+			/*
+			   The device is still connected so we only shutdown
+			   pending read-/write-ops.
+			 */
+			usb_kill_urb(dev->int_in_urb);
+			wake_up_interruptible(&dev->read_wait);
+			wake_up_interruptible(&dev->write_wait);
+			mutex_unlock(&dev->mutex);
+		} else {
+			/* The device was unplugged, cleanup resources */
+			mutex_unlock(&dev->mutex);
+			iowarrior_delete(dev);
+		}
+	}
+	return retval;
+}
+
+static unsigned iowarrior_poll(struct file *file, poll_table * wait)
+{
+	struct iowarrior *dev = file->private_data;
+	unsigned int mask = 0;
+
+	if (!dev->present)
+		return POLLERR | POLLHUP;
+
+	poll_wait(file, &dev->read_wait, wait);
+	poll_wait(file, &dev->write_wait, wait);
+
+	if (!dev->present)
+		return POLLERR | POLLHUP;
+
+	if (read_index(dev) != -1)
+		mask |= POLLIN | POLLRDNORM;
+
+	if (atomic_read(&dev->write_busy) < MAX_WRITES_IN_FLIGHT)
+		mask |= POLLOUT | POLLWRNORM;
+	return mask;
+}
+
+/*
+ * File operations needed when we register this driver.
+ * This assumes that this driver NEEDS file operations,
+ * of course, which means that the driver is expected
+ * to have a node in the /dev directory. If the USB
+ * device were for a network interface then the driver
+ * would use "struct net_driver" instead, and a serial
+ * device would use "struct tty_driver".
+ */
+static struct file_operations iowarrior_fops = {
+	.owner = THIS_MODULE,
+	.write = iowarrior_write,
+	.read = iowarrior_read,
+	.ioctl = iowarrior_ioctl,
+	.open = iowarrior_open,
+	.release = iowarrior_release,
+	.poll = iowarrior_poll,
+};
+
+/*
+ * usb class driver info in order to get a minor number from the usb core,
+ * and to have the device registered with devfs and the driver core
+ */
+static struct usb_class_driver iowarrior_class = {
+	.name = "iowarrior%d",
+	.fops = &iowarrior_fops,
+	.minor_base = IOWARRIOR_MINOR_BASE,
+};
+
+/*---------------------------------*/
+/*  probe and disconnect functions */
+/*---------------------------------*/
+/**
+ *	iowarrior_probe
+ *
+ *	Called by the usb core when a new device is connected that it thinks
+ *	this driver might be interested in.
+ */
+static int iowarrior_probe(struct usb_interface *interface,
+			   const struct usb_device_id *id)
+{
+	struct usb_device *udev = interface_to_usbdev(interface);
+	struct iowarrior *dev = NULL;
+	struct usb_host_interface *iface_desc;
+	struct usb_endpoint_descriptor *endpoint;
+	int i;
+	int retval = -ENOMEM;
+	int idele = 0;
+
+	/* allocate memory for our device state and intialize it */
+	dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL);
+	if (dev == NULL) {
+		dev_err(&interface->dev, "Out of memory");
+		return retval;
+	}
+
+	mutex_init(&dev->mutex);
+
+	atomic_set(&dev->intr_idx, 0);
+	atomic_set(&dev->read_idx, 0);
+	spin_lock_init(&dev->intr_idx_lock);
+	atomic_set(&dev->overflow_flag, 0);
+	init_waitqueue_head(&dev->read_wait);
+	atomic_set(&dev->write_busy, 0);
+	init_waitqueue_head(&dev->write_wait);
+
+	dev->udev = udev;
+	dev->interface = interface;
+
+	iface_desc = interface->cur_altsetting;
+	dev->product_id = le16_to_cpu(udev->descriptor.idProduct);
+
+	/* set up the endpoint information */
+	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+		endpoint = &iface_desc->endpoint[i].desc;
+
+		if (usb_endpoint_is_int_in(endpoint))
+			dev->int_in_endpoint = endpoint;
+		if (usb_endpoint_is_int_out(endpoint))
+			/* this one will match for the IOWarrior56 only */
+			dev->int_out_endpoint = endpoint;
+	}
+	/* we have to check the report_size often, so remember it in the endianess suitable for our machine */
+	dev->report_size = le16_to_cpu(dev->int_in_endpoint->wMaxPacketSize);
+	if ((dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) &&
+	    (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW56))
+		/* IOWarrior56 has wMaxPacketSize different from report size */
+		dev->report_size = 7;
+
+	/* create the urb and buffer for reading */
+	dev->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!dev->int_in_urb) {
+		dev_err(&interface->dev, "Couldn't allocate interrupt_in_urb\n");
+		goto error;
+	}
+	dev->int_in_buffer = kmalloc(dev->report_size, GFP_KERNEL);
+	if (!dev->int_in_buffer) {
+		dev_err(&interface->dev, "Couldn't allocate int_in_buffer\n");
+		goto error;
+	}
+	usb_fill_int_urb(dev->int_in_urb, dev->udev,
+			 usb_rcvintpipe(dev->udev,
+					dev->int_in_endpoint->bEndpointAddress),
+			 dev->int_in_buffer, dev->report_size,
+			 iowarrior_callback, dev,
+			 dev->int_in_endpoint->bInterval);
+	/* create an internal buffer for interrupt data from the device */
+	dev->read_queue =
+	    kmalloc(((dev->report_size + 1) * MAX_INTERRUPT_BUFFER),
+		    GFP_KERNEL);
+	if (!dev->read_queue) {
+		dev_err(&interface->dev, "Couldn't allocate read_queue\n");
+		goto error;
+	}
+	/* Get the serial-number of the chip */
+	memset(dev->chip_serial, 0x00, sizeof(dev->chip_serial));
+	usb_string(udev, udev->descriptor.iSerialNumber, dev->chip_serial,
+		   sizeof(dev->chip_serial));
+	if (strlen(dev->chip_serial) != 8)
+		memset(dev->chip_serial, 0x00, sizeof(dev->chip_serial));
+
+	/* Set the idle timeout to 0, if this is interface 0 */
+	if (dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) {
+		idele = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+					0x0A,
+					USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0,
+					0, NULL, 0, USB_CTRL_SET_TIMEOUT);
+		dbg("idele = %d", idele);
+	}
+	/* allow device read and ioctl */
+	dev->present = 1;
+
+	/* we can register the device now, as it is ready */
+	usb_set_intfdata(interface, dev);
+
+	retval = usb_register_dev(interface, &iowarrior_class);
+	if (retval) {
+		/* something prevented us from registering this driver */
+		dev_err(&interface->dev, "Not able to get a minor for this device.\n");
+		usb_set_intfdata(interface, NULL);
+		goto error;
+	}
+
+	dev->minor = interface->minor;
+
+	/* let the user know what node this device is now attached to */
+	dev_info(&interface->dev, "IOWarrior product=0x%x, serial=%s interface=%d "
+		 "now attached to iowarrior%d\n", dev->product_id, dev->chip_serial,
+		 iface_desc->desc.bInterfaceNumber, dev->minor - IOWARRIOR_MINOR_BASE);
+	return retval;
+
+error:
+	iowarrior_delete(dev);
+	return retval;
+}
+
+/**
+ *	iowarrior_disconnect
+ *
+ *	Called by the usb core when the device is removed from the system.
+ */
+static void iowarrior_disconnect(struct usb_interface *interface)
+{
+	struct iowarrior *dev;
+	int minor;
+
+	/* prevent races with open() */
+	down(&disconnect_sem);
+
+	dev = usb_get_intfdata(interface);
+	usb_set_intfdata(interface, NULL);
+
+	mutex_lock(&dev->mutex);
+
+	minor = dev->minor;
+
+	/* give back our minor */
+	usb_deregister_dev(interface, &iowarrior_class);
+
+	/* prevent device read, write and ioctl */
+	dev->present = 0;
+
+	mutex_unlock(&dev->mutex);
+
+	if (dev->opened) {
+		/* There is a process that holds a filedescriptor to the device ,
+		   so we only shutdown read-/write-ops going on.
+		   Deleting the device is postponed until close() was called.
+		 */
+		usb_kill_urb(dev->int_in_urb);
+		wake_up_interruptible(&dev->read_wait);
+		wake_up_interruptible(&dev->write_wait);
+	} else {
+		/* no process is using the device, cleanup now */
+		iowarrior_delete(dev);
+	}
+	up(&disconnect_sem);
+
+	dev_info(&interface->dev, "I/O-Warror #%d now disconnected\n",
+		 minor - IOWARRIOR_MINOR_BASE);
+}
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver iowarrior_driver = {
+	.name = "iowarrior",
+	.probe = iowarrior_probe,
+	.disconnect = iowarrior_disconnect,
+	.id_table = iowarrior_ids,
+};
+
+static int __init iowarrior_init(void)
+{
+	return usb_register(&iowarrior_driver);
+}
+
+static void __exit iowarrior_exit(void)
+{
+	usb_deregister(&iowarrior_driver);
+}
+
+module_init(iowarrior_init);
+module_exit(iowarrior_exit);
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
index c01dfe6..b2bedd9 100644
--- a/drivers/usb/mon/mon_bin.c
+++ b/drivers/usb/mon/mon_bin.c
@@ -1165,7 +1165,7 @@
 	return rc;
 }
 
-void __exit mon_bin_exit(void)
+void mon_bin_exit(void)
 {
 	cdev_del(&mon_bin_cdev);
 	unregister_chrdev_region(mon_bin_dev0, MON_BIN_MAX_MINOR);
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
index d38a127..494ee3b 100644
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -520,7 +520,7 @@
 	return 0;
 }
 
-void __exit mon_text_exit(void)
+void mon_text_exit(void)
 {
 	debugfs_remove(mon_dir);
 }
diff --git a/drivers/usb/mon/usb_mon.h b/drivers/usb/mon/usb_mon.h
index 4f949ce..efdfd89 100644
--- a/drivers/usb/mon/usb_mon.h
+++ b/drivers/usb/mon/usb_mon.h
@@ -57,9 +57,9 @@
 // void mon_bin_add(struct mon_bus *);
 
 int __init mon_text_init(void);
-void __exit mon_text_exit(void);
+void mon_text_exit(void);
 int __init mon_bin_init(void);
-void __exit mon_bin_exit(void);
+void mon_bin_exit(void);
 
 /*
  * DMA interface.
diff --git a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig
index 0f3d7db..3de564b 100644
--- a/drivers/usb/net/Kconfig
+++ b/drivers/usb/net/Kconfig
@@ -186,6 +186,15 @@
 	  IEEE 802 "local assignment" bit is set in the address, a "usbX"
 	  name is used instead.
 
+config USB_NET_DM9601
+	tristate "Davicom DM9601 based USB 1.1 10/100 ethernet devices"
+	depends on USB_USBNET
+	select CRC32
+	select USB_USBNET_MII
+	help
+	  This option adds support for Davicom DM9601 based USB 1.1
+	  10/100 Ethernet adapters.
+
 config USB_NET_GL620A
 	tristate "GeneSys GL620USB-A based cables"
 	depends on USB_USBNET
diff --git a/drivers/usb/net/Makefile b/drivers/usb/net/Makefile
index 7b51964..595a539 100644
--- a/drivers/usb/net/Makefile
+++ b/drivers/usb/net/Makefile
@@ -8,6 +8,7 @@
 obj-$(CONFIG_USB_RTL8150)	+= rtl8150.o
 obj-$(CONFIG_USB_NET_AX8817X)	+= asix.o
 obj-$(CONFIG_USB_NET_CDCETHER)	+= cdc_ether.o
+obj-$(CONFIG_USB_NET_DM9601)	+= dm9601.o
 obj-$(CONFIG_USB_NET_GL620A)	+= gl620a.o
 obj-$(CONFIG_USB_NET_NET1080)	+= net1080.o
 obj-$(CONFIG_USB_NET_PLUSB)	+= plusb.o
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c
index 7ef2e4b..5808ea0 100644
--- a/drivers/usb/net/asix.c
+++ b/drivers/usb/net/asix.c
@@ -1395,9 +1395,9 @@
 	USB_DEVICE (0x07b8, 0x420a),
 	.driver_info =  (unsigned long) &hawking_uf200_info,
 }, {
-        // Billionton Systems, USB2AR
-        USB_DEVICE (0x08dd, 0x90ff),
-        .driver_info =  (unsigned long) &ax8817x_info,
+	// Billionton Systems, USB2AR
+	USB_DEVICE (0x08dd, 0x90ff),
+	.driver_info =  (unsigned long) &ax8817x_info,
 }, {
 	// ATEN UC210T
 	USB_DEVICE (0x0557, 0x2009),
@@ -1423,9 +1423,13 @@
 	USB_DEVICE (0x1631, 0x6200),
 	.driver_info = (unsigned long) &ax8817x_info,
 }, {
+	// JVC MP-PRX1 Port Replicator
+	USB_DEVICE (0x04f1, 0x3008),
+	.driver_info = (unsigned long) &ax8817x_info,
+}, {
 	// ASIX AX88772 10/100
-        USB_DEVICE (0x0b95, 0x7720),
-        .driver_info = (unsigned long) &ax88772_info,
+	USB_DEVICE (0x0b95, 0x7720),
+	.driver_info = (unsigned long) &ax88772_info,
 }, {
 	// ASIX AX88178 10/100/1000
 	USB_DEVICE (0x0b95, 0x1780),
diff --git a/drivers/usb/net/dm9601.c b/drivers/usb/net/dm9601.c
new file mode 100644
index 0000000..4a932e1
--- /dev/null
+++ b/drivers/usb/net/dm9601.c
@@ -0,0 +1,606 @@
+/*
+ * Davicom DM9601 USB 1.1 10/100Mbps ethernet devices
+ *
+ * Peter Korsgaard <jacmet@sunsite.dk>
+ *
+ * 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.
+ */
+
+//#define DEBUG
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/crc32.h>
+
+#include "usbnet.h"
+
+/* datasheet:
+ http://www.davicom.com.tw/big5/download/Data%20Sheet/DM9601-DS-P01-930914.pdf
+*/
+
+/* control requests */
+#define DM_READ_REGS	0x00
+#define DM_WRITE_REGS	0x01
+#define DM_READ_MEMS	0x02
+#define DM_WRITE_REG	0x03
+#define DM_WRITE_MEMS	0x05
+#define DM_WRITE_MEM	0x07
+
+/* registers */
+#define DM_NET_CTRL	0x00
+#define DM_RX_CTRL	0x05
+#define DM_SHARED_CTRL	0x0b
+#define DM_SHARED_ADDR	0x0c
+#define DM_SHARED_DATA	0x0d	/* low + high */
+#define DM_PHY_ADDR	0x10	/* 6 bytes */
+#define DM_MCAST_ADDR	0x16	/* 8 bytes */
+#define DM_GPR_CTRL	0x1e
+#define DM_GPR_DATA	0x1f
+
+#define DM_MAX_MCAST	64
+#define DM_MCAST_SIZE	8
+#define DM_EEPROM_LEN	256
+#define DM_TX_OVERHEAD	2	/* 2 byte header */
+#define DM_RX_OVERHEAD	7	/* 3 byte header + 4 byte crc tail */
+#define DM_TIMEOUT	1000
+
+
+static int dm_read(struct usbnet *dev, u8 reg, u16 length, void *data)
+{
+	devdbg(dev, "dm_read() reg=0x%02x length=%d", reg, length);
+	return usb_control_msg(dev->udev,
+			       usb_rcvctrlpipe(dev->udev, 0),
+			       DM_READ_REGS,
+			       USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			       0, reg, data, length, USB_CTRL_SET_TIMEOUT);
+}
+
+static int dm_read_reg(struct usbnet *dev, u8 reg, u8 *value)
+{
+	return dm_read(dev, reg, 1, value);
+}
+
+static int dm_write(struct usbnet *dev, u8 reg, u16 length, void *data)
+{
+	devdbg(dev, "dm_write() reg=0x%02x, length=%d", reg, length);
+	return usb_control_msg(dev->udev,
+			       usb_sndctrlpipe(dev->udev, 0),
+			       DM_WRITE_REGS,
+			       USB_DIR_OUT | USB_TYPE_VENDOR |USB_RECIP_DEVICE,
+			       0, reg, data, length, USB_CTRL_SET_TIMEOUT);
+}
+
+static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value)
+{
+	devdbg(dev, "dm_write_reg() reg=0x%02x, value=0x%02x", reg, value);
+	return usb_control_msg(dev->udev,
+			       usb_sndctrlpipe(dev->udev, 0),
+			       DM_WRITE_REG,
+			       USB_DIR_OUT | USB_TYPE_VENDOR |USB_RECIP_DEVICE,
+			       value, reg, 0, 0, USB_CTRL_SET_TIMEOUT);
+}
+
+static void dm_write_async_callback(struct urb *urb)
+{
+	struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
+
+	if (urb->status < 0)
+		printk(KERN_DEBUG "dm_write_async_callback() failed with %d",
+		       urb->status);
+
+	kfree(req);
+	usb_free_urb(urb);
+}
+
+static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)
+{
+	struct usb_ctrlrequest *req;
+	struct urb *urb;
+	int status;
+
+	devdbg(dev, "dm_write_async() reg=0x%02x length=%d", reg, length);
+
+	urb = usb_alloc_urb(0, GFP_ATOMIC);
+	if (!urb) {
+		deverr(dev, "Error allocating URB in dm_write_async!");
+		return;
+	}
+
+	req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
+	if (!req) {
+		deverr(dev, "Failed to allocate memory for control request");
+		usb_free_urb(urb);
+		return;
+	}
+
+	req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
+	req->bRequest = DM_WRITE_REGS;
+	req->wValue = 0;
+	req->wIndex = cpu_to_le16(reg);
+	req->wLength = cpu_to_le16(length);
+
+	usb_fill_control_urb(urb, dev->udev,
+			     usb_sndctrlpipe(dev->udev, 0),
+			     (void *)req, data, length,
+			     dm_write_async_callback, req);
+
+	status = usb_submit_urb(urb, GFP_ATOMIC);
+	if (status < 0) {
+		deverr(dev, "Error submitting the control message: status=%d",
+		       status);
+		kfree(req);
+		usb_free_urb(urb);
+	}
+}
+
+static void dm_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
+{
+	struct usb_ctrlrequest *req;
+	struct urb *urb;
+	int status;
+
+	devdbg(dev, "dm_write_reg_async() reg=0x%02x value=0x%02x",
+	       reg, value);
+
+	urb = usb_alloc_urb(0, GFP_ATOMIC);
+	if (!urb) {
+		deverr(dev, "Error allocating URB in dm_write_async!");
+		return;
+	}
+
+	req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
+	if (!req) {
+		deverr(dev, "Failed to allocate memory for control request");
+		usb_free_urb(urb);
+		return;
+	}
+
+	req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
+	req->bRequest = DM_WRITE_REG;
+	req->wValue = cpu_to_le16(value);
+	req->wIndex = cpu_to_le16(reg);
+	req->wLength = 0;
+
+	usb_fill_control_urb(urb, dev->udev,
+			     usb_sndctrlpipe(dev->udev, 0),
+			     (void *)req, 0, 0, dm_write_async_callback, req);
+
+	status = usb_submit_urb(urb, GFP_ATOMIC);
+	if (status < 0) {
+		deverr(dev, "Error submitting the control message: status=%d",
+		       status);
+		kfree(req);
+		usb_free_urb(urb);
+	}
+}
+
+static int dm_read_shared_word(struct usbnet *dev, int phy, u8 reg, u16 *value)
+{
+	int ret, i;
+
+	mutex_lock(&dev->phy_mutex);
+
+	dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg);
+	dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0xc : 0x4);
+
+	for (i = 0; i < DM_TIMEOUT; i++) {
+		u8 tmp;
+
+		udelay(1);
+		ret = dm_read_reg(dev, DM_SHARED_CTRL, &tmp);
+		if (ret < 0)
+			goto out;
+
+		/* ready */
+		if ((tmp & 1) == 0)
+			break;
+	}
+
+	if (i == DM_TIMEOUT) {
+		deverr(dev, "%s read timed out!", phy ? "phy" : "eeprom");
+		ret = -EIO;
+		goto out;
+	}
+
+	dm_write_reg(dev, DM_SHARED_CTRL, 0x0);
+	ret = dm_read(dev, DM_SHARED_DATA, 2, value);
+
+	devdbg(dev, "read shared %d 0x%02x returned 0x%04x, %d",
+	       phy, reg, *value, ret);
+
+ out:
+	mutex_unlock(&dev->phy_mutex);
+	return ret;
+}
+
+static int dm_write_shared_word(struct usbnet *dev, int phy, u8 reg, u16 value)
+{
+	int ret, i;
+
+	mutex_lock(&dev->phy_mutex);
+
+	ret = dm_write(dev, DM_SHARED_DATA, 2, &value);
+	if (ret < 0)
+		goto out;
+
+	dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg);
+	dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0x1c : 0x14);
+
+	for (i = 0; i < DM_TIMEOUT; i++) {
+		u8 tmp;
+
+		udelay(1);
+		ret = dm_read_reg(dev, DM_SHARED_CTRL, &tmp);
+		if (ret < 0)
+			goto out;
+
+		/* ready */
+		if ((tmp & 1) == 0)
+			break;
+	}
+
+	if (i == DM_TIMEOUT) {
+		deverr(dev, "%s write timed out!", phy ? "phy" : "eeprom");
+		ret = -EIO;
+		goto out;
+	}
+
+	dm_write_reg(dev, DM_SHARED_CTRL, 0x0);
+
+out:
+	mutex_unlock(&dev->phy_mutex);
+	return ret;
+}
+
+static int dm_read_eeprom_word(struct usbnet *dev, u8 offset, void *value)
+{
+	return dm_read_shared_word(dev, 0, offset, value);
+}
+
+
+
+static int dm9601_get_eeprom_len(struct net_device *dev)
+{
+	return DM_EEPROM_LEN;
+}
+
+static int dm9601_get_eeprom(struct net_device *net,
+			     struct ethtool_eeprom *eeprom, u8 * data)
+{
+	struct usbnet *dev = netdev_priv(net);
+	u16 *ebuf = (u16 *) data;
+	int i;
+
+	/* access is 16bit */
+	if ((eeprom->offset % 2) || (eeprom->len % 2))
+		return -EINVAL;
+
+	for (i = 0; i < eeprom->len / 2; i++) {
+		if (dm_read_eeprom_word(dev, eeprom->offset / 2 + i,
+					&ebuf[i]) < 0)
+			return -EINVAL;
+	}
+	return 0;
+}
+
+static int dm9601_mdio_read(struct net_device *netdev, int phy_id, int loc)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+
+	u16 res;
+
+	if (phy_id) {
+		devdbg(dev, "Only internal phy supported");
+		return 0;
+	}
+
+	dm_read_shared_word(dev, 1, loc, &res);
+
+	devdbg(dev,
+	       "dm9601_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x",
+	       phy_id, loc, le16_to_cpu(res));
+
+	return le16_to_cpu(res);
+}
+
+static void dm9601_mdio_write(struct net_device *netdev, int phy_id, int loc,
+			      int val)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+	u16 res = cpu_to_le16(val);
+
+	if (phy_id) {
+		devdbg(dev, "Only internal phy supported");
+		return;
+	}
+
+	devdbg(dev,"dm9601_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x",
+	       phy_id, loc, val);
+
+	dm_write_shared_word(dev, 1, loc, res);
+}
+
+static void dm9601_get_drvinfo(struct net_device *net,
+			       struct ethtool_drvinfo *info)
+{
+	/* Inherit standard device info */
+	usbnet_get_drvinfo(net, info);
+	info->eedump_len = DM_EEPROM_LEN;
+}
+
+static u32 dm9601_get_link(struct net_device *net)
+{
+	struct usbnet *dev = netdev_priv(net);
+
+	return mii_link_ok(&dev->mii);
+}
+
+static int dm9601_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
+{
+	struct usbnet *dev = netdev_priv(net);
+
+	return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
+}
+
+static struct ethtool_ops dm9601_ethtool_ops = {
+	.get_drvinfo	= dm9601_get_drvinfo,
+	.get_link	= dm9601_get_link,
+	.get_msglevel	= usbnet_get_msglevel,
+	.set_msglevel	= usbnet_set_msglevel,
+	.get_eeprom_len	= dm9601_get_eeprom_len,
+	.get_eeprom	= dm9601_get_eeprom,
+	.get_settings	= usbnet_get_settings,
+	.set_settings	= usbnet_set_settings,
+	.nway_reset	= usbnet_nway_reset,
+};
+
+static void dm9601_set_multicast(struct net_device *net)
+{
+	struct usbnet *dev = netdev_priv(net);
+	/* We use the 20 byte dev->data for our 8 byte filter buffer
+	 * to avoid allocating memory that is tricky to free later */
+	u8 *hashes = (u8 *) & dev->data;
+	u8 rx_ctl = 0x01;
+
+	memset(hashes, 0x00, DM_MCAST_SIZE);
+	hashes[DM_MCAST_SIZE - 1] |= 0x80;	/* broadcast address */
+
+	if (net->flags & IFF_PROMISC) {
+		rx_ctl |= 0x02;
+	} else if (net->flags & IFF_ALLMULTI || net->mc_count > DM_MAX_MCAST) {
+		rx_ctl |= 0x04;
+	} else if (net->mc_count) {
+		struct dev_mc_list *mc_list = net->mc_list;
+		int i;
+
+		for (i = 0; i < net->mc_count; i++) {
+			u32 crc = ether_crc(ETH_ALEN, mc_list->dmi_addr) >> 26;
+			hashes[crc >> 3] |= 1 << (crc & 0x7);
+		}
+	}
+
+	dm_write_async(dev, DM_MCAST_ADDR, DM_MCAST_SIZE, hashes);
+	dm_write_reg_async(dev, DM_RX_CTRL, rx_ctl);
+}
+
+static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+	int ret;
+
+	ret = usbnet_get_endpoints(dev, intf);
+	if (ret)
+		goto out;
+
+	dev->net->do_ioctl = dm9601_ioctl;
+	dev->net->set_multicast_list = dm9601_set_multicast;
+	dev->net->ethtool_ops = &dm9601_ethtool_ops;
+	dev->net->hard_header_len += DM_TX_OVERHEAD;
+	dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
+	dev->rx_urb_size = dev->net->mtu + DM_RX_OVERHEAD;
+
+	dev->mii.dev = dev->net;
+	dev->mii.mdio_read = dm9601_mdio_read;
+	dev->mii.mdio_write = dm9601_mdio_write;
+	dev->mii.phy_id_mask = 0x1f;
+	dev->mii.reg_num_mask = 0x1f;
+
+	/* reset */
+	ret = dm_write_reg(dev, DM_NET_CTRL, 1);
+	udelay(20);
+
+	/* read MAC */
+	ret = dm_read(dev, DM_PHY_ADDR, ETH_ALEN, dev->net->dev_addr);
+	if (ret < 0) {
+		printk(KERN_ERR "Error reading MAC address\n");
+		ret = -ENODEV;
+		goto out;
+	}
+
+
+	/* power up phy */
+	dm_write_reg(dev, DM_GPR_CTRL, 1);
+	dm_write_reg(dev, DM_GPR_DATA, 0);
+
+	/* receive broadcast packets */
+	dm9601_set_multicast(dev->net);
+
+	dm9601_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
+	dm9601_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
+			  ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
+	mii_nway_restart(&dev->mii);
+
+out:
+	return ret;
+}
+
+static int dm9601_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+	u8 status;
+	int len;
+
+	/* format:
+	   b0: rx status
+	   b1: packet length (incl crc) low
+	   b2: packet length (incl crc) high
+	   b3..n-4: packet data
+	   bn-3..bn: ethernet crc
+	 */
+
+	if (unlikely(skb->len < DM_RX_OVERHEAD)) {
+		dev_err(&dev->udev->dev, "unexpected tiny rx frame\n");
+		return 0;
+	}
+
+	status = skb->data[0];
+	len = (skb->data[1] | (skb->data[2] << 8)) - 4;
+
+	if (unlikely(status & 0xbf)) {
+		if (status & 0x01) dev->stats.rx_fifo_errors++;
+		if (status & 0x02) dev->stats.rx_crc_errors++;
+		if (status & 0x04) dev->stats.rx_frame_errors++;
+		if (status & 0x20) dev->stats.rx_missed_errors++;
+		if (status & 0x90) dev->stats.rx_length_errors++;
+		return 0;
+	}
+
+	skb_pull(skb, 3);
+	skb_trim(skb, len);
+
+	return 1;
+}
+
+static struct sk_buff *dm9601_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
+				       gfp_t flags)
+{
+	int len;
+
+	/* format:
+	   b0: packet length low
+	   b1: packet length high
+	   b3..n: packet data
+	*/
+
+	if (skb_headroom(skb) < DM_TX_OVERHEAD) {
+		struct sk_buff *skb2;
+
+		skb2 = skb_copy_expand(skb, DM_TX_OVERHEAD, 0, flags);
+		dev_kfree_skb_any(skb);
+		skb = skb2;
+		if (!skb)
+			return NULL;
+	}
+
+	__skb_push(skb, DM_TX_OVERHEAD);
+
+	len = skb->len;
+	/* usbnet adds padding if length is a multiple of packet size
+	   if so, adjust length value in header */
+	if ((len % dev->maxpacket) == 0)
+		len++;
+
+	skb->data[0] = len;
+	skb->data[1] = len >> 8;
+
+	return skb;
+}
+
+static void dm9601_status(struct usbnet *dev, struct urb *urb)
+{
+	int link;
+	u8 *buf;
+
+	/* format:
+	   b0: net status
+	   b1: tx status 1
+	   b2: tx status 2
+	   b3: rx status
+	   b4: rx overflow
+	   b5: rx count
+	   b6: tx count
+	   b7: gpr
+	*/
+
+	if (urb->actual_length < 8)
+		return;
+
+	buf = urb->transfer_buffer;
+
+	link = !!(buf[0] & 0x40);
+	if (netif_carrier_ok(dev->net) != link) {
+		if (link) {
+			netif_carrier_on(dev->net);
+			usbnet_defer_kevent (dev, EVENT_LINK_RESET);
+		}
+		else
+			netif_carrier_off(dev->net);
+		devdbg(dev, "Link Status is: %d", link);
+	}
+}
+
+static int dm9601_link_reset(struct usbnet *dev)
+{
+	struct ethtool_cmd ecmd;
+
+	mii_check_media(&dev->mii, 1, 1);
+	mii_ethtool_gset(&dev->mii, &ecmd);
+
+	devdbg(dev, "link_reset() speed: %d duplex: %d",
+	       ecmd.speed, ecmd.duplex);
+
+	return 0;
+}
+
+static const struct driver_info dm9601_info = {
+	.description	= "Davicom DM9601 USB Ethernet",
+	.flags		= FLAG_ETHER,
+	.bind		= dm9601_bind,
+	.rx_fixup	= dm9601_rx_fixup,
+	.tx_fixup	= dm9601_tx_fixup,
+	.status		= dm9601_status,
+	.link_reset	= dm9601_link_reset,
+	.reset		= dm9601_link_reset,
+};
+
+static const struct usb_device_id products[] = {
+	{
+	 USB_DEVICE(0x0a46, 0x9601),	/* Davicom USB-100 */
+	 .driver_info = (unsigned long)&dm9601_info,
+	 },
+	{},			// END
+};
+
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver dm9601_driver = {
+	.name = "dm9601",
+	.id_table = products,
+	.probe = usbnet_probe,
+	.disconnect = usbnet_disconnect,
+	.suspend = usbnet_suspend,
+	.resume = usbnet_resume,
+};
+
+static int __init dm9601_init(void)
+{
+	return usb_register(&dm9601_driver);
+}
+
+static void __exit dm9601_exit(void)
+{
+	usb_deregister(&dm9601_driver);
+}
+
+module_init(dm9601_init);
+module_exit(dm9601_exit);
+
+MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>");
+MODULE_DESCRIPTION("Davicom DM9601 USB 1.1 ethernet devices");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 4695952..c525b42 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -513,6 +513,7 @@
 	{ USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) },
 	{ USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) },
+	{ USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
 	{ },					/* Optional parameter entry */
 	{ }					/* Terminating entry */
 };
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 7eff1c0..1bdda93 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -491,6 +491,12 @@
 #define FTDI_TACTRIX_OPENPORT_13S_PID	0xCC49	/* OpenPort 1.3 Subaru */
 #define FTDI_TACTRIX_OPENPORT_13U_PID	0xCC4A	/* OpenPort 1.3 Universal */
 
+/*
+ * Telldus Technologies
+ */
+#define TELLDUS_VID			0x1781	/* Vendor ID */
+#define TELLDUS_TELLSTICK_PID		0x0C30	/* RF control dongle 433 MHz using FT232RL */
+
 /* Commands */
 #define FTDI_SIO_RESET 		0 /* Reset the port */
 #define FTDI_SIO_MODEM_CTRL 	1 /* Set the modem control register */
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 9963a8b7..db92a7f 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -67,50 +67,95 @@
 static int  option_send_setup(struct usb_serial_port *port);
 
 /* Vendor and product IDs */
-#define OPTION_VENDOR_ID                0x0AF0
-#define HUAWEI_VENDOR_ID                0x12D1
-#define NOVATELWIRELESS_VENDOR_ID       0x1410
-#define ANYDATA_VENDOR_ID               0x16d5
+#define OPTION_VENDOR_ID			0x0AF0
+#define OPTION_PRODUCT_COLT			0x5000
+#define OPTION_PRODUCT_RICOLA			0x6000
+#define OPTION_PRODUCT_RICOLA_LIGHT		0x6100
+#define OPTION_PRODUCT_RICOLA_QUAD		0x6200
+#define OPTION_PRODUCT_RICOLA_QUAD_LIGHT	0x6300
+#define OPTION_PRODUCT_RICOLA_NDIS		0x6050
+#define OPTION_PRODUCT_RICOLA_NDIS_LIGHT	0x6150
+#define OPTION_PRODUCT_RICOLA_NDIS_QUAD		0x6250
+#define OPTION_PRODUCT_RICOLA_NDIS_QUAD_LIGHT	0x6350
+#define OPTION_PRODUCT_COBRA			0x6500
+#define OPTION_PRODUCT_COBRA_BUS		0x6501
+#define OPTION_PRODUCT_VIPER			0x6600
+#define OPTION_PRODUCT_VIPER_BUS		0x6601
+#define OPTION_PRODUCT_GT_MAX_READY		0x6701
+#define OPTION_PRODUCT_GT_MAX			0x6711
+#define OPTION_PRODUCT_FUJI_MODEM_LIGHT		0x6721
+#define OPTION_PRODUCT_FUJI_MODEM_GT		0x6741
+#define OPTION_PRODUCT_FUJI_MODEM_EX		0x6761
+#define OPTION_PRODUCT_FUJI_NETWORK_LIGHT	0x6731
+#define OPTION_PRODUCT_FUJI_NETWORK_GT		0x6751
+#define OPTION_PRODUCT_FUJI_NETWORK_EX		0x6771
+#define OPTION_PRODUCT_KOI_MODEM		0x6800
+#define OPTION_PRODUCT_KOI_NETWORK		0x6811
+#define OPTION_PRODUCT_SCORPION_MODEM		0x6901
+#define OPTION_PRODUCT_SCORPION_NETWORK		0x6911
+#define OPTION_PRODUCT_ETNA_MODEM		0x7001
+#define OPTION_PRODUCT_ETNA_NETWORK		0x7011
+#define OPTION_PRODUCT_ETNA_MODEM_LITE		0x7021
+#define OPTION_PRODUCT_ETNA_MODEM_GT		0x7041
+#define OPTION_PRODUCT_ETNA_MODEM_EX		0x7061
+#define OPTION_PRODUCT_ETNA_NETWORK_LITE	0x7031
+#define OPTION_PRODUCT_ETNA_NETWORK_GT		0x7051
+#define OPTION_PRODUCT_ETNA_NETWORK_EX		0x7071
+#define OPTION_PRODUCT_ETNA_KOI_MODEM		0x7100
+#define OPTION_PRODUCT_ETNA_KOI_NETWORK		0x7111
 
-#define OPTION_PRODUCT_OLD              0x5000
-#define OPTION_PRODUCT_FUSION           0x6000
-#define OPTION_PRODUCT_FUSION2          0x6300
-#define OPTION_PRODUCT_COBRA            0x6500
-#define OPTION_PRODUCT_COBRA2           0x6600
-#define OPTION_PRODUCT_GTMAX36          0x6701
-#define HUAWEI_PRODUCT_E600             0x1001
-#define HUAWEI_PRODUCT_E220             0x1003
-#define NOVATELWIRELESS_PRODUCT_U740    0x1400
-#define ANYDATA_PRODUCT_ID              0x6501
+#define HUAWEI_VENDOR_ID			0x12D1
+#define HUAWEI_PRODUCT_E600			0x1001
+#define HUAWEI_PRODUCT_E220			0x1003
+
+#define NOVATELWIRELESS_VENDOR_ID		0x1410
+#define NOVATELWIRELESS_PRODUCT_U740		0x1400
+
+#define ANYDATA_VENDOR_ID			0x16d5
+#define ANYDATA_PRODUCT_ID			0x6501
 
 static struct usb_device_id option_ids[] = {
-	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
-	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
-	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_QUAD) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_QUAD_LIGHT) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_NDIS) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_NDIS_LIGHT) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_NDIS_QUAD) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_NDIS_QUAD_LIGHT) },
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) },
-	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
-	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA_BUS) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_VIPER) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_VIPER_BUS) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GT_MAX_READY) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GT_MAX) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_LIGHT) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_GT) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_EX) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_NETWORK_LIGHT) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_NETWORK_GT) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_NETWORK_EX) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_KOI_MODEM) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_KOI_NETWORK) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_SCORPION_MODEM) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_SCORPION_NETWORK) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_LITE) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_GT) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_EX) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_LITE) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_GT) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_EX) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_NETWORK) },
 	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
 	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
 	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
 	{ } /* Terminating entry */
 };
-
-static struct usb_device_id option_ids1[] = {
-	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
-	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
-	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
-	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) },
-	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
-	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) },
-	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
-	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
-	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
-	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
-	{ } /* Terminating entry */
-};
-
 MODULE_DEVICE_TABLE(usb, option_ids);
 
 static struct usb_driver option_driver = {
@@ -132,7 +177,7 @@
 	},
 	.description       = "GSM modem (1-port)",
 	.usb_driver        = &option_driver,
-	.id_table          = option_ids1,
+	.id_table          = option_ids,
 	.num_interrupt_in  = NUM_DONT_CARE,
 	.num_bulk_in       = NUM_DONT_CARE,
 	.num_bulk_out      = NUM_DONT_CARE,
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index 6988a10..03893ac 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -1919,7 +1919,8 @@
 	 * header ?
 	 */
 	if (tlck->type & tlckTRUNCATE) {
-		pxd_t pxd;	/* truncated extent of xad */
+		/* This odd declaration suppresses a bogus gcc warning */
+		pxd_t pxd = pxd;	/* truncated extent of xad */
 		int twm;
 
 		/*
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 98b0910..8d4d839 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -502,6 +502,30 @@
 
 
 /**
+ * sysfs_add_file_to_group - add an attribute file to a pre-existing group.
+ * @kobj: object we're acting for.
+ * @attr: attribute descriptor.
+ * @group: group name.
+ */
+int sysfs_add_file_to_group(struct kobject *kobj,
+		const struct attribute *attr, const char *group)
+{
+	struct dentry *dir;
+	int error;
+
+	dir = lookup_one_len(group, kobj->dentry, strlen(group));
+	if (IS_ERR(dir))
+		error = PTR_ERR(dir);
+	else {
+		error = sysfs_add_file(dir, attr, SYSFS_KOBJ_ATTR);
+		dput(dir);
+	}
+	return error;
+}
+EXPORT_SYMBOL_GPL(sysfs_add_file_to_group);
+
+
+/**
  * sysfs_update_file - update the modified timestamp on an object attribute.
  * @kobj: object we're acting for.
  * @attr: attribute descriptor.
@@ -586,6 +610,26 @@
 }
 
 
+/**
+ * sysfs_remove_file_from_group - remove an attribute file from a group.
+ * @kobj: object we're acting for.
+ * @attr: attribute descriptor.
+ * @group: group name.
+ */
+void sysfs_remove_file_from_group(struct kobject *kobj,
+		const struct attribute *attr, const char *group)
+{
+	struct dentry *dir;
+
+	dir = lookup_one_len(group, kobj->dentry, strlen(group));
+	if (!IS_ERR(dir)) {
+		sysfs_hash_and_remove(dir, attr->name);
+		dput(dir);
+	}
+}
+EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group);
+
+
 EXPORT_SYMBOL_GPL(sysfs_create_file);
 EXPORT_SYMBOL_GPL(sysfs_remove_file);
 EXPORT_SYMBOL_GPL(sysfs_update_file);
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index d976b00..a77c57e 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -1,3 +1,14 @@
+struct sysfs_dirent {
+	atomic_t		s_count;
+	struct list_head	s_sibling;
+	struct list_head	s_children;
+	void 			* s_element;
+	int			s_type;
+	umode_t			s_mode;
+	struct dentry		* s_dentry;
+	struct iattr		* s_iattr;
+	atomic_t		s_event;
+};
 
 extern struct vfsmount * sysfs_mount;
 extern struct kmem_cache *sysfs_dir_cachep;
diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h
index 8a1f2b6..1906938 100644
--- a/include/asm-mips/ptrace.h
+++ b/include/asm-mips/ptrace.h
@@ -21,6 +21,7 @@
 #define FPC_EIR		70
 #define DSP_BASE	71		/* 3 more hi / lo register pairs */
 #define DSP_CONTROL	77
+#define ACX		78
 
 /*
  * This struct defines the way the registers are stored on the stack during a
@@ -39,6 +40,9 @@
 	unsigned long cp0_status;
 	unsigned long hi;
 	unsigned long lo;
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+	unsigned long acx;
+#endif
 	unsigned long cp0_badvaddr;
 	unsigned long cp0_cause;
 	unsigned long cp0_epc;
diff --git a/include/asm-mips/sigcontext.h b/include/asm-mips/sigcontext.h
index 9729474..9ce0607 100644
--- a/include/asm-mips/sigcontext.h
+++ b/include/asm-mips/sigcontext.h
@@ -23,7 +23,7 @@
 	unsigned long long	sc_pc;
 	unsigned long long	sc_regs[32];
 	unsigned long long	sc_fpregs[32];
-	unsigned int		sc_ownedfp;	/* Unused */
+	unsigned int		sc_acx;		/* Was sc_ownedfp */
 	unsigned int		sc_fpc_csr;
 	unsigned int		sc_fpc_eir;	/* Unused */
 	unsigned int		sc_used_math;
@@ -79,7 +79,7 @@
 	__u64		sc_pc;
 	__u64		sc_regs[32];
 	__u64		sc_fpregs[32];
-	__u32		sc_ownedfp;	/* Unused */
+	__u32		sc_acx;		/* Only MIPS32; was sc_ownedfp */
 	__u32		sc_fpc_csr;
 	__u32		sc_fpc_eir;	/* Unused */
 	__u32		sc_used_math;
diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h
index 1fae5dc..7afa1fd 100644
--- a/include/asm-mips/stackframe.h
+++ b/include/asm-mips/stackframe.h
@@ -29,16 +29,25 @@
 		.endm
 
 		.macro	SAVE_TEMP
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+		mflhxu	v1
+		LONG_S	v1, PT_LO(sp)
+		mflhxu	v1
+		LONG_S	v1, PT_HI(sp)
+		mflhxu	v1
+		LONG_S	v1, PT_ACX(sp)
+#else
 		mfhi	v1
+		LONG_S	v1, PT_HI(sp)
+		mflo	v1
+		LONG_S	v1, PT_LO(sp)
+#endif
 #ifdef CONFIG_32BIT
 		LONG_S	$8, PT_R8(sp)
 		LONG_S	$9, PT_R9(sp)
 #endif
-		LONG_S	v1, PT_HI(sp)
-		mflo	v1
 		LONG_S	$10, PT_R10(sp)
 		LONG_S	$11, PT_R11(sp)
-		LONG_S	v1,  PT_LO(sp)
 		LONG_S	$12, PT_R12(sp)
 		LONG_S	$13, PT_R13(sp)
 		LONG_S	$14, PT_R14(sp)
@@ -182,16 +191,25 @@
 		.endm
 
 		.macro	RESTORE_TEMP
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+		LONG_L	$24, PT_ACX(sp)
+		mtlhx	$24
+		LONG_L	$24, PT_HI(sp)
+		mtlhx	$24
 		LONG_L	$24, PT_LO(sp)
+		mtlhx	$24
+#else
+		LONG_L	$24, PT_LO(sp)
+		mtlo	$24
+		LONG_L	$24, PT_HI(sp)
+		mthi	$24
+#endif
 #ifdef CONFIG_32BIT
 		LONG_L	$8, PT_R8(sp)
 		LONG_L	$9, PT_R9(sp)
 #endif
-		mtlo	$24
-		LONG_L	$24, PT_HI(sp)
 		LONG_L	$10, PT_R10(sp)
 		LONG_L	$11, PT_R11(sp)
-		mthi	$24
 		LONG_L	$12, PT_R12(sp)
 		LONG_L	$13, PT_R13(sp)
 		LONG_L	$14, PT_R14(sp)
diff --git a/include/linux/device.h b/include/linux/device.h
index d1a3a27..39a3199 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -294,8 +294,6 @@
 extern int __must_check class_device_add(struct class_device *);
 extern void class_device_del(struct class_device *);
 
-extern int class_device_rename(struct class_device *, char *);
-
 extern struct class_device * class_device_get(struct class_device *);
 extern void class_device_put(struct class_device *);
 
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index cc8e674..10f505c 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -28,10 +28,8 @@
 #ifdef CONFIG_KMOD
 /* modprobe exit status on success, -ve on error.  Return value
  * usually useless though. */
-extern void kmod_sysfs_init(void);
 extern int request_module(const char * name, ...) __attribute__ ((format (printf, 1, 2)));
 #else
-static inline void kmod_sysfs_init(void) {};
 static inline int request_module(const char * name, ...) { return -ENOSYS; }
 #endif
 
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 070394e..21db05a 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -120,15 +120,48 @@
 #define	PM_DISK_TESTPROC	((__force suspend_disk_method_t) 6)
 #define	PM_DISK_MAX		((__force suspend_disk_method_t) 7)
 
+/**
+ * struct pm_ops - Callbacks for managing platform dependent suspend states.
+ * @valid: Callback to determine whether the given state can be entered.
+ * 	If %CONFIG_SOFTWARE_SUSPEND is set then %PM_SUSPEND_DISK is
+ *	always valid and never passed to this call.
+ *	If not assigned, all suspend states are advertised as valid
+ *	in /sys/power/state (but can still be rejected by prepare or enter.)
+ *
+ * @prepare: Prepare the platform for the given suspend state. Can return a
+ *	negative error code if necessary.
+ *
+ * @enter: Enter the given suspend state, must be assigned. Can return a
+ *	negative error code if necessary.
+ *
+ * @finish: Called when the system has left the given state and all devices
+ *	are resumed. The return value is ignored.
+ *
+ * @pm_disk_mode: Set to the disk method that the user should be able to
+ *	configure for suspend-to-disk. Since %PM_DISK_SHUTDOWN,
+ *	%PM_DISK_REBOOT, %PM_DISK_TEST and %PM_DISK_TESTPROC
+ *	are always allowed, currently only %PM_DISK_PLATFORM
+ *	makes sense. If the user then choses %PM_DISK_PLATFORM,
+ *	the @prepare call will be called before suspending to disk
+ *	(if present), the @enter call should be present and will
+ *	be called after all state has been saved and the machine
+ *	is ready to be shut down/suspended/..., and the @finish
+ *	callback is called after state has been restored. All
+ *	these calls are called with %PM_SUSPEND_DISK as the state.
+ */
 struct pm_ops {
-	suspend_disk_method_t pm_disk_mode;
 	int (*valid)(suspend_state_t state);
 	int (*prepare)(suspend_state_t state);
 	int (*enter)(suspend_state_t state);
 	int (*finish)(suspend_state_t state);
+	suspend_disk_method_t pm_disk_mode;
 };
 
-extern void pm_set_ops(struct pm_ops *);
+/**
+ * pm_set_ops - set platform dependent power management ops
+ * @pm_ops: The new power management operations to set.
+ */
+extern void pm_set_ops(struct pm_ops *pm_ops);
 extern struct pm_ops *pm_ops;
 extern int pm_suspend(suspend_state_t state);
 
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 192de3a..21805b5 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -17,6 +17,7 @@
 struct kobject;
 struct module;
 struct nameidata;
+struct dentry;
 
 struct attribute {
 	const char		* name;
@@ -68,18 +69,6 @@
 	ssize_t	(*store)(struct kobject *,struct attribute *,const char *, size_t);
 };
 
-struct sysfs_dirent {
-	atomic_t		s_count;
-	struct list_head	s_sibling;
-	struct list_head	s_children;
-	void 			* s_element;
-	int			s_type;
-	umode_t			s_mode;
-	struct dentry		* s_dentry;
-	struct iattr		* s_iattr;
-	atomic_t		s_event;
-};
-
 #define SYSFS_ROOT		0x0001
 #define SYSFS_DIR		0x0002
 #define SYSFS_KOBJ_ATTR 	0x0004
@@ -126,6 +115,11 @@
 int __must_check sysfs_create_group(struct kobject *,
 					const struct attribute_group *);
 void sysfs_remove_group(struct kobject *, const struct attribute_group *);
+int sysfs_add_file_to_group(struct kobject *kobj,
+		const struct attribute *attr, const char *group);
+void sysfs_remove_file_from_group(struct kobject *kobj,
+		const struct attribute *attr, const char *group);
+
 void sysfs_notify(struct kobject * k, char *dir, char *attr);
 
 
@@ -210,6 +204,18 @@
 	;
 }
 
+static inline int sysfs_add_file_to_group(struct kobject *kobj,
+		const struct attribute *attr, const char *group)
+{
+	return 0;
+}
+
+static inline void sysfs_remove_file_from_group(struct kobject *kobj,
+		const struct attribute *attr, const char *group);
+{
+	;
+}
+
 static inline void sysfs_notify(struct kobject * k, char *dir, char *attr)
 {
 }
diff --git a/include/linux/usb.h b/include/linux/usb.h
index a8e8d1e..87dc75a 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -388,10 +388,14 @@
 	struct usb_device *children[USB_MAXCHILDREN];
 
 	int pm_usage_cnt;		/* usage counter for autosuspend */
+	u32 quirks;			/* quirks of the whole device */
+
 #ifdef CONFIG_PM
 	struct delayed_work autosuspend; /* for delayed autosuspends */
 	struct mutex pm_mutex;		/* protects PM operations */
 
+	unsigned autosuspend_delay;	/* in jiffies */
+
 	unsigned auto_pm:1;		/* autosuspend/resume in progress */
 	unsigned do_remote_wakeup:1;	/* remote wakeup should be enabled */
 #endif
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index 245c725..1122a6c 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -1,8 +1,9 @@
 /*
- * This file holds USB constants and structures that are needed for USB
- * device APIs.  These are used by the USB device model, which is defined
- * in chapter 9 of the USB 2.0 specification.  Linux has several APIs in C
- * that need these:
+ * This file holds USB constants and structures that are needed for
+ * USB device APIs.  These are used by the USB device model, which is
+ * defined in chapter 9 of the USB 2.0 specification and in the
+ * Wireless USB 1.0 (spread around).  Linux has several APIs in C that
+ * need these:
  *
  * - the master/host side Linux-USB kernel driver API;
  * - the "usbfs" user space API; and
@@ -14,6 +15,19 @@
  *
  * There's also "Wireless USB", using low power short range radios for
  * peripheral interconnection but otherwise building on the USB framework.
+ *
+ * Note all descriptors are declared '__attribute__((packed))' so that:
+ *
+ * [a] they never get padded, either internally (USB spec writers
+ *     probably handled that) or externally;
+ *
+ * [b] so that accessing bigger-than-a-bytes fields will never
+ *     generate bus errors on any platform, even when the location of
+ *     its descriptor inside a bundle isn't "naturally aligned", and
+ *
+ * [c] for consistency, removing all doubt even when it appears to
+ *     someone that the two other points are non-issues for that
+ *     particular descriptor type.
  */
 
 #ifndef __LINUX_USB_CH9_H
diff --git a/include/linux/usb/iowarrior.h b/include/linux/usb/iowarrior.h
new file mode 100644
index 0000000..cbbe020
--- /dev/null
+++ b/include/linux/usb/iowarrior.h
@@ -0,0 +1,33 @@
+#ifndef _IOWARRIOR_H_
+#define _IOWARRIOR_H_
+
+#define CODEMERCS_MAGIC_NUMBER	0xC0	/* like COde Mercenaries */
+
+/* Define the ioctl commands for reading and writing data */
+#define IOW_WRITE	_IOW(CODEMERCS_MAGIC_NUMBER, 1, __u8 *)
+#define IOW_READ	_IOW(CODEMERCS_MAGIC_NUMBER, 2, __u8 *)
+
+/*
+   A struct for available device info which is read
+   with the ioctl IOW_GETINFO.
+   To be compatible with 2.4 userspace which didn't have an easy way to get
+   this information.
+*/
+struct iowarrior_info {
+	__u32 vendor;		/* vendor id : supposed to be USB_VENDOR_ID_CODEMERCS in all cases */
+	__u32 product;		/* product id : depends on type of chip (USB_DEVICE_ID_CODEMERCS_XXXXX) */
+	__u8 serial[9];		/* the serial number of our chip (if a serial-number is not available this is empty string) */
+	__u32 revision;		/* revision number of the chip */
+	__u32 speed;		/* USB-speed of the device (0=UNKNOWN, 1=LOW, 2=FULL 3=HIGH) */
+	__u32 power;		/* power consumption of the device in mA */
+	__u32 if_num;		/* the number of the endpoint */
+	__u32 report_size;	/* size of the data-packets on this interface */
+};
+
+/*
+  Get some device-information (product-id , serial-number etc.)
+  in order to identify a chip.
+*/
+#define IOW_GETINFO _IOR(CODEMERCS_MAGIC_NUMBER, 3, struct iowarrior_info)
+
+#endif  /* _IOWARRIOR_H_ */
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h
new file mode 100644
index 0000000..6bac8fa
--- /dev/null
+++ b/include/linux/usb/quirks.h
@@ -0,0 +1,11 @@
+/*
+ * This file holds the definitions of quirks found in USB devices.
+ * Only quirks that affect the whole device, not an interface,
+ * belong here.
+ */
+
+/* device must not be autosuspended */
+#define USB_QUIRK_NO_AUTOSUSPEND	0x00000001
+
+/* string descriptors must not be fetched using a 255-byte read */
+#define USB_QUIRK_STRING_FETCH_255	0x00000002
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 9f923f8..7962761 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -36,8 +36,6 @@
 #include <linux/resource.h>
 #include <asm/uaccess.h>
 
-extern int delete_module(const char *name, unsigned int flags);
-
 extern int max_threads;
 
 static struct workqueue_struct *khelper_wq;
@@ -48,7 +46,6 @@
 	modprobe_path is set via /proc/sys.
 */
 char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe";
-struct module_kobject kmod_mk;
 
 /**
  * request_module - try to load a kernel module
@@ -78,11 +75,6 @@
 	static atomic_t kmod_concurrent = ATOMIC_INIT(0);
 #define MAX_KMOD_CONCURRENT 50	/* Completely arbitrary value - KAO */
 	static int kmod_loop_msg;
-	char modalias[16 + MODULE_NAME_LEN] = "MODALIAS=";
-	char *uevent_envp[2] = {
-		modalias,
-		NULL
-	};
 
 	va_start(args, fmt);
 	ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args);
@@ -90,12 +82,6 @@
 	if (ret >= MODULE_NAME_LEN)
 		return -ENAMETOOLONG;
 
-	strcpy(&modalias[strlen("MODALIAS=")], module_name);
-	kobject_uevent_env(&kmod_mk.kobj, KOBJ_CHANGE, uevent_envp);
-
-	if (modprobe_path[0] == '\0')
-		goto out;
-
 	/* If modprobe needs a service that is in a module, we get a recursive
 	 * loop.  Limit the number of running kmod threads to max_threads/2 or
 	 * MAX_KMOD_CONCURRENT, whichever is the smaller.  A cleaner method
@@ -122,115 +108,9 @@
 
 	ret = call_usermodehelper(modprobe_path, argv, envp, 1);
 	atomic_dec(&kmod_concurrent);
-out:
 	return ret;
 }
 EXPORT_SYMBOL(request_module);
-
-static ssize_t store_mod_request(struct module_attribute *mattr,
-				 struct module *mod,
-			      const char *buffer, size_t count)
-{
-	char name[MODULE_NAME_LEN];
-	int ret;
-
-	if (count < 1 || count+1 > MODULE_NAME_LEN)
-		return -EINVAL;
-	memcpy(name, buffer, count);
-	name[count] = '\0';
-	if (name[count-1] == '\n')
-		name[count-1] = '\0';
-
-	ret = request_module(name);
-	if (ret < 0)
-		return ret;
-	return count;
-}
-
-static struct module_attribute mod_request = {
-	.attr = { .name = "mod_request", .mode = S_IWUSR, .owner = THIS_MODULE },
-	.store = store_mod_request,
-};
-
-#ifdef CONFIG_MODULE_UNLOAD
-static ssize_t store_mod_unload(struct module_attribute *mattr,
-			    struct module *mod,
-			    const char *buffer, size_t count)
-{
-	char name[MODULE_NAME_LEN];
-	int ret;
-
-	if (count < 1 || count+1 > MODULE_NAME_LEN)
-		return -EINVAL;
-	memcpy(name, buffer, count);
-	name[count] = '\0';
-	if (name[count-1] == '\n')
-		name[count-1] = '\0';
-
-	ret = delete_module(name, O_NONBLOCK);
-	if (ret < 0)
-		return ret;
-	return count;
-}
-
-static struct module_attribute mod_unload = {
-	.attr = { .name = "mod_unload", .mode = S_IWUSR, .owner = THIS_MODULE },
-	.store = store_mod_unload,
-};
-#endif
-
-static ssize_t show_mod_request_helper(struct module_attribute *mattr,
-				       struct module *mod,
-				       char *buffer)
-{
-	return sprintf(buffer, "%s\n", modprobe_path);
-}
-
-static ssize_t store_mod_request_helper(struct module_attribute *mattr,
-					struct module *mod,
-					const char *buffer, size_t count)
-{
-	if (count < 1 || count+1 > KMOD_PATH_LEN)
-		return -EINVAL;
-	memcpy(modprobe_path, buffer, count);
-	modprobe_path[count] = '\0';
-	if (modprobe_path[count-1] == '\n')
-		modprobe_path[count-1] = '\0';
-	return count;
-}
-
-static struct module_attribute mod_request_helper = {
-	.attr = {
-		.name = "mod_request_helper",
-		.mode = S_IWUSR | S_IRUGO,
-		.owner = THIS_MODULE
-	},
-	.show = show_mod_request_helper,
-	.store = store_mod_request_helper,
-};
-
-void __init kmod_sysfs_init(void)
-{
-	int ret;
-
-	kmod_mk.mod = THIS_MODULE;
-	kobj_set_kset_s(&kmod_mk, module_subsys);
-	kobject_set_name(&kmod_mk.kobj, "kmod");
-	kobject_init(&kmod_mk.kobj);
-	ret = kobject_add(&kmod_mk.kobj);
-	if (ret < 0)
-		goto out;
-
-	ret = sysfs_create_file(&kmod_mk.kobj, &mod_request_helper.attr);
-	ret = sysfs_create_file(&kmod_mk.kobj, &mod_request.attr);
-#ifdef CONFIG_MODULE_UNLOAD
-	ret = sysfs_create_file(&kmod_mk.kobj, &mod_unload.attr);
-#endif
-
-	kobject_uevent(&kmod_mk.kobj, KOBJ_ADD);
-out:
-	return;
-}
 #endif /* CONFIG_KMOD */
 
 struct subprocess_info {
diff --git a/kernel/module.c b/kernel/module.c
index 8c25b1a..f77e893 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -653,11 +653,20 @@
 	mutex_lock(&module_mutex);
 }
 
-int delete_module(const char *name, unsigned int flags)
+asmlinkage long
+sys_delete_module(const char __user *name_user, unsigned int flags)
 {
 	struct module *mod;
+	char name[MODULE_NAME_LEN];
 	int ret, forced = 0;
 
+	if (!capable(CAP_SYS_MODULE))
+		return -EPERM;
+
+	if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
+		return -EFAULT;
+	name[MODULE_NAME_LEN-1] = '\0';
+
 	if (mutex_lock_interruptible(&module_mutex) != 0)
 		return -EINTR;
 
@@ -718,21 +727,6 @@
 	return ret;
 }
 
-asmlinkage long
-sys_delete_module(const char __user *name_user, unsigned int flags)
-{
-	char name[MODULE_NAME_LEN];
-
-	if (!capable(CAP_SYS_MODULE))
-		return -EPERM;
-
-	if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
-		return -EFAULT;
-	name[MODULE_NAME_LEN-1] = '\0';
-
-	return delete_module(name, flags);
-}
-
 static void print_unload_info(struct seq_file *m, struct module *mod)
 {
 	struct module_use *use;
@@ -2425,6 +2419,12 @@
 			kfree(driver_name);
 		}
 	}
+	/*
+	 * Undo the additional reference we added in module_add_driver()
+	 * via kset_find_obj()
+	 */
+	if (drv->mod_name)
+		kobject_put(&drv->kobj);
 }
 EXPORT_SYMBOL(module_remove_driver);
 #endif
diff --git a/kernel/params.c b/kernel/params.c
index 7a75157..e265b13 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -707,7 +707,6 @@
 	}
 
 	param_sysfs_builtin();
-	kmod_sysfs_init();
 
 	return 0;
 }
diff --git a/kernel/power/main.c b/kernel/power/main.c
index e1c4131..a064dfd 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -167,7 +167,10 @@
 	if (state == PM_SUSPEND_DISK)
 		return 1;
 
-	if (pm_ops && pm_ops->valid && !pm_ops->valid(state))
+	/* all other states need lowlevel support and need to be
+	 * valid to the lowlevel implementation, no valid callback
+	 * implies that all are valid. */
+	if (!pm_ops || (pm_ops->valid && !pm_ops->valid(state)))
 		return 0;
 	return 1;
 }
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index 4500e34..0986a2b 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -77,6 +77,7 @@
 void tick_handle_periodic(struct clock_event_device *dev)
 {
 	int cpu = smp_processor_id();
+	ktime_t next;
 
 	tick_periodic(cpu);
 
@@ -86,12 +87,12 @@
 	 * Setup the next period for devices, which do not have
 	 * periodic mode:
 	 */
+	next = ktime_add(dev->next_event, tick_period);
 	for (;;) {
-		ktime_t next = ktime_add(dev->next_event, tick_period);
-
 		if (!clockevents_program_event(dev, next, ktime_get()))
 			return;
 		tick_periodic(cpu);
+		next = ktime_add(next, tick_period);
 	}
 }
 
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 512a4a9..51556b9 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -21,6 +21,8 @@
 #include <linux/sched.h>
 #include <linux/tick.h>
 
+#include <asm/irq_regs.h>
+
 #include "tick-internal.h"
 
 /*
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b1ac22d..19a385e 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -653,11 +653,11 @@
 	sbsec->initialized = 1;
 
 	if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) {
-		printk(KERN_INFO "SELinux: initialized (dev %s, type %s), unknown behavior\n",
+		printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n",
 		       sb->s_id, sb->s_type->name);
 	}
 	else {
-		printk(KERN_INFO "SELinux: initialized (dev %s, type %s), %s\n",
+		printk(KERN_DEBUG "SELinux: initialized (dev %s, type %s), %s\n",
 		       sb->s_id, sb->s_type->name,
 		       labeling_behaviors[sbsec->behavior-1]);
 	}
@@ -4434,7 +4434,7 @@
 static int selinux_register_security (const char *name, struct security_operations *ops)
 {
 	if (secondary_ops != original_ops) {
-		printk(KERN_INFO "%s:  There is already a secondary security "
+		printk(KERN_ERR "%s:  There is already a secondary security "
 		       "module registered.\n", __FUNCTION__);
 		return -EINVAL;
  	}
@@ -4451,7 +4451,7 @@
 static int selinux_unregister_security (const char *name, struct security_operations *ops)
 {
 	if (ops != secondary_ops) {
-		printk (KERN_INFO "%s:  trying to unregister a security module "
+		printk(KERN_ERR "%s:  trying to unregister a security module "
 		        "that is not registered.\n", __FUNCTION__);
 		return -EINVAL;
 	}
@@ -4889,9 +4889,9 @@
 		panic("SELinux: Unable to register with kernel.\n");
 
 	if (selinux_enforcing) {
-		printk(KERN_INFO "SELinux:  Starting in enforcing mode\n");
+		printk(KERN_DEBUG "SELinux:  Starting in enforcing mode\n");
 	} else {
-		printk(KERN_INFO "SELinux:  Starting in permissive mode\n");
+		printk(KERN_DEBUG "SELinux:  Starting in permissive mode\n");
 	}
 
 #ifdef CONFIG_KEYS
@@ -4907,10 +4907,10 @@
 
 void selinux_complete_init(void)
 {
-	printk(KERN_INFO "SELinux:  Completing initialization.\n");
+	printk(KERN_DEBUG "SELinux:  Completing initialization.\n");
 
 	/* Set up any superblocks initialized prior to the policy load. */
-	printk(KERN_INFO "SELinux:  Setting up existing superblocks.\n");
+	printk(KERN_DEBUG "SELinux:  Setting up existing superblocks.\n");
 	spin_lock(&sb_lock);
 	spin_lock(&sb_security_lock);
 next_sb:
@@ -4968,9 +4968,9 @@
 
 	if (!selinux_enabled)
 		goto out;
-		
-	printk(KERN_INFO "SELinux:  Registering netfilter hooks\n");
-	
+
+	printk(KERN_DEBUG "SELinux:  Registering netfilter hooks\n");
+
 	err = nf_register_hook(&selinux_ipv4_op);
 	if (err)
 		panic("SELinux: nf_register_hook for IPv4: error %d\n", err);
@@ -4992,7 +4992,7 @@
 #ifdef CONFIG_SECURITY_SELINUX_DISABLE
 static void selinux_nf_ip_exit(void)
 {
-	printk(KERN_INFO "SELinux:  Unregistering netfilter hooks\n");
+	printk(KERN_DEBUG "SELinux:  Unregistering netfilter hooks\n");
 
 	nf_unregister_hook(&selinux_ipv4_op);
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index 9142073..3122908 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -277,7 +277,7 @@
 		}
 	}
 
-	printk(KERN_INFO "%s:  %d entries and %d/%d buckets used, longest "
+	printk(KERN_DEBUG "%s:  %d entries and %d/%d buckets used, longest "
 	       "chain length %d\n", tag, h->nel, slots_used, AVTAB_SIZE,
 	       max_chain_len);
 }
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index cd79c63..0ac1021 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -374,7 +374,7 @@
 		struct hashtab_info info;
 
 		hashtab_stat(h, &info);
-		printk(KERN_INFO "%s:  %d entries and %d/%d buckets used, "
+		printk(KERN_DEBUG "%s:  %d entries and %d/%d buckets used, "
 		       "longest chain length %d\n", symtab_name[i], h->nel,
 		       info.slots_used, h->size, info.max_chain_len);
 	}
@@ -391,14 +391,14 @@
 {
 	int i, rc = 0;
 
-	printk(KERN_INFO "security:  %d users, %d roles, %d types, %d bools",
+	printk(KERN_DEBUG "security:  %d users, %d roles, %d types, %d bools",
 	       p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
 	if (selinux_mls_enabled)
 		printk(", %d sens, %d cats", p->p_levels.nprim,
 		       p->p_cats.nprim);
 	printk("\n");
 
-	printk(KERN_INFO "security:  %d classes, %d rules\n",
+	printk(KERN_DEBUG "security:  %d classes, %d rules\n",
 	       p->p_classes.nprim, p->te_avtab.nel);
 
 #ifdef DEBUG_HASHES
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index ca9154d..1e52356 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -609,6 +609,9 @@
 	struct context *context;
 	int rc = 0;
 
+	*scontext = NULL;
+	*scontext_len  = 0;
+
 	if (!ss_initialized) {
 		if (sid <= SECINITSID_NUM) {
 			char *scontextp;
diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c
index d78f9ff..53a54a7 100644
--- a/security/selinux/ss/sidtab.c
+++ b/security/selinux/ss/sidtab.c
@@ -253,7 +253,7 @@
 		}
 	}
 
-	printk(KERN_INFO "%s:  %d entries and %d/%d buckets used, longest "
+	printk(KERN_DEBUG "%s:  %d entries and %d/%d buckets used, longest "
 	       "chain length %d\n", tag, h->nel, slots_used, SIDTAB_SIZE,
 	       max_chain_len);
 }