Pull fix-offsets-h into release branch
diff --git a/Documentation/cciss.txt b/Documentation/cciss.txt
index c8f9a73..68a711f 100644
--- a/Documentation/cciss.txt
+++ b/Documentation/cciss.txt
@@ -17,7 +17,9 @@
 	* SA P600
 	* SA P800
 	* SA E400
-	* SA E300
+	* SA P400i
+	* SA E200
+	* SA E200i
 
 If nodes are not already created in the /dev/cciss directory, run as root:
 
diff --git a/Documentation/dontdiff b/Documentation/dontdiff
index 96bea27..24adfe9 100644
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -55,6 +55,7 @@
 aicasm
 aicdb.h*
 asm
+asm-offsets.*
 asm_offsets.*
 autoconf.h*
 bbootsect
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 784e08c..b67189a 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -17,15 +17,6 @@
 
 ---------------------------
 
-What:	io_remap_page_range() (macro or function)
-When:	September 2005
-Why:	Replaced by io_remap_pfn_range() which allows more memory space
-	addressabilty (by using a pfn) and supports sparc & sparc64
-	iospace as part of the pfn.
-Who:	Randy Dunlap <rddunlap@osdl.org>
-
----------------------------
-
 What:	RAW driver (CONFIG_RAW_DRIVER)
 When:	December 2005
 Why:	declared obsolete since kernel 2.6.3
diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt
index 1f5f7d2..5f08f9c 100644
--- a/Documentation/kdump/kdump.txt
+++ b/Documentation/kdump/kdump.txt
@@ -66,11 +66,11 @@
    c) Enable "/proc/vmcore support" (Optional, in Pseudo filesystems).
 	CONFIG_PROC_VMCORE=y
    d) Disable SMP support and build a UP kernel (Until it is fixed).
-   	CONFIG_SMP=n
+	CONFIG_SMP=n
    e) Enable "Local APIC support on uniprocessors".
-   	CONFIG_X86_UP_APIC=y
+	CONFIG_X86_UP_APIC=y
    f) Enable "IO-APIC support on uniprocessors"
-   	CONFIG_X86_UP_IOAPIC=y
+	CONFIG_X86_UP_IOAPIC=y
 
   Note:   i) Options a) and b) depend upon "Configure standard kernel features
 	     (for small systems)" (under General setup).
@@ -95,6 +95,11 @@
 	    hence have memory less than 4GB.
        iii) Specify "irqpoll" as command line parameter. This reduces driver
             initialization failures in second kernel due to shared interrupts.
+        iv) <root-dev> needs to be specified in a format corresponding to
+            the root device name in the output of mount command.
+         v) If you have built the drivers required to mount root file
+            system as modules in <second-kernel>, then, specify
+            --initrd=<initrd-for-second-kernel>.
 
 5) System reboots into the second kernel when a panic occurs. A module can be
    written to force the panic or "ALT-SysRq-c" can be used initiate a crash
diff --git a/Documentation/oops-tracing.txt b/Documentation/oops-tracing.txt
index da71102..66eaaab 100644
--- a/Documentation/oops-tracing.txt
+++ b/Documentation/oops-tracing.txt
@@ -205,8 +205,8 @@
 Tainted kernels:
 
 Some oops reports contain the string 'Tainted: ' after the program
-counter, this indicates that the kernel has been tainted by some
-mechanism.  The string is followed by a series of position sensitive
+counter. This indicates that the kernel has been tainted by some
+mechanism.  The string is followed by a series of position-sensitive
 characters, each representing a particular tainted value.
 
   1: 'G' if all modules loaded have a GPL or compatible license, 'P' if
@@ -214,16 +214,25 @@
      MODULE_LICENSE or with a MODULE_LICENSE that is not recognised by
      insmod as GPL compatible are assumed to be proprietary.
 
-  2: 'F' if any module was force loaded by insmod -f, ' ' if all
+  2: 'F' if any module was force loaded by "insmod -f", ' ' if all
      modules were loaded normally.
 
   3: 'S' if the oops occurred on an SMP kernel running on hardware that
-      hasn't been certified as safe to run multiprocessor.
-	  Currently this occurs only on various Athlons that are not
-	  SMP capable.
+     hasn't been certified as safe to run multiprocessor.
+     Currently this occurs only on various Athlons that are not
+     SMP capable.
+
+  4: 'R' if a module was force unloaded by "rmmod -f", ' ' if all
+     modules were unloaded normally.
+
+  5: 'M' if any processor has reported a Machine Check Exception,
+     ' ' if no Machine Check Exceptions have occurred.
+
+  6: 'B' if a page-release function has found a bad page reference or
+     some unexpected page flags.
 
 The primary reason for the 'Tainted: ' string is to tell kernel
 debuggers if this is a clean kernel or if anything unusual has
-occurred.  Tainting is permanent, even if an offending module is
-unloading the tainted value remains to indicate that the kernel is not
+occurred.  Tainting is permanent: even if an offending module is
+unloaded, the tainted value remains to indicate that the kernel is not
 trustworthy.
diff --git a/Documentation/pm.txt b/Documentation/pm.txt
index cc63ae1..2ea1149 100644
--- a/Documentation/pm.txt
+++ b/Documentation/pm.txt
@@ -38,6 +38,12 @@
 
 Driver Interface -- OBSOLETE, DO NOT USE!
 ----------------*************************
+
+Note: pm_register(), pm_access(), pm_dev_idle() and friends are
+obsolete. Please do not use them. Instead you should properly hook
+your driver into the driver model, and use its suspend()/resume()
+callbacks to do this kind of stuff.
+
 If you are writing a new driver or maintaining an old driver, it
 should include power management support.  Without power management
 support, a single driver may prevent a system with power management
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index ebfcdf2..13cba95 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -75,7 +75,7 @@
     adsp_map	- PCM device number maps assigned to the 2st OSS device.
 		- Default: 1
     nonblock_open
-		- Don't block opening busy PCM devices.
+		- Don't block opening busy PCM devices.  Default: 1
 
     For example, when dsp_map=2, /dev/dsp will be mapped to PCM #2 of
     the card #0.  Similarly, when adsp_map=0, /dev/adsp will be mapped
@@ -148,6 +148,16 @@
     Module supports up to 8 cards. This module does not support autoprobe
     thus main port must be specified!!! Other ports are optional.
     
+  Module snd-ad1889
+  -----------------
+
+    Module for Analog Devices AD1889 chips.
+
+    ac97_quirk  - AC'97 workaround for strange hardware
+                  See the description of intel8x0 module for details.
+
+    This module supports up to 8 cards.
+
   Module snd-ali5451
   ------------------
 
@@ -189,15 +199,20 @@
   Module snd-atiixp
   -----------------
 
-    Module for ATI IXP 150/200/250 AC97 controllers.
+    Module for ATI IXP 150/200/250/400 AC97 controllers.
 
-    ac97_clock		- AC'97 clock (defalut = 48000)
+    ac97_clock		- AC'97 clock (default = 48000)
     ac97_quirk		- AC'97 workaround for strange hardware
-			  See the description of intel8x0 module for details.
+			  See "AC97 Quirk Option" section below.
     spdif_aclink	- S/PDIF transfer over AC-link (default = 1)
 
     This module supports up to 8 cards and autoprobe.
 
+    ATI IXP has two different methods to control SPDIF output.  One is
+    over AC-link and another is over the "direct" SPDIF output.  The
+    implementation depends on the motherboard, and you'll need to
+    choose the correct one via spdif_aclink module option.
+
   Module snd-atiixp-modem
   -----------------------
 
@@ -230,7 +245,7 @@
     The hardware EQ hardware and SPDIF is only present in the Vortex2 and 
     Advantage.
 
-    Note: Some ALSA mixer applicactions don't handle the SPDIF samplerate 
+    Note: Some ALSA mixer applications don't handle the SPDIF sample rate 
            control correctly. If you have problems regarding this, try
            another ALSA compliant mixer (alsamixer works).
 
@@ -302,7 +317,7 @@
 
     mpu_port	- 0x300,0x310,0x320,0x330, 0 = disable (default)
     fm_port     - 0x388 (default), 0 = disable (default)
-    soft_ac3    - Sofware-conversion of raw SPDIF packets (model 033 only)
+    soft_ac3    - Software-conversion of raw SPDIF packets (model 033 only)
                   (default = 1)
     joystick_port - Joystick port address (0 = disable, 1 = auto-detect)
 
@@ -384,7 +399,7 @@
     Module for PCI sound cards based on CS4610/CS4612/CS4614/CS4615/CS4622/
 				       CS4624/CS4630/CS4280 PCI chips.
 
-    external_amp     - Force to enable external amplifer.
+    external_amp     - Force to enable external amplifier.
     thinkpad         - Force to enable Thinkpad's CLKRUN control.
     mmap_valid       - Support OSS mmap mode (default = 0).
 
@@ -620,7 +635,7 @@
 	       VIA VT8251/VT8237A
 
     model	- force the model name
-    position_fix - Fix DMA pointer (0 = FIFO size, 1 = none, 2 = POSBUF)
+    position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)
 
     Module supports up to 8 cards.
 
@@ -656,6 +671,11 @@
 	  allout	5-jack in back, 2-jack in front, SPDIF out
 	  auto		auto-config reading BIOS (default)
 
+    If the default configuration doesn't work and one of the above
+    matches with your device, report it together with the PCI
+    subsystem ID (output of "lspci -nv") to ALSA BTS or alsa-devel
+    ML (see the section "Links and Addresses").
+
     Note 2: If you get click noises on output, try the module option
 	    position_fix=1 or 2.  position_fix=1 will use the SD_LPIB
 	    register value without FIFO size correction as the current
@@ -783,20 +803,13 @@
 
     ac97_clock	  - AC'97 codec clock base (0 = auto-detect)
     ac97_quirk    - AC'97 workaround for strange hardware
-                    The following strings are accepted:
-                      default = don't override the default setting
-                      disable = disable the quirk
-                      hp_only = use headphone control as master
-                      swap_hp = swap headphone and master controls
-                      swap_surround = swap master and surround controls
-                      ad_sharing = for AD1985, turn on OMS bit and use headphone
-                      alc_jack = for ALC65x, turn on the jack sense mode
-                      inv_eapd = inverted EAPD implementation
-                      mute_led = bind EAPD bit for turning on/off mute LED
-                    For backward compatibility, the corresponding integer
-                    value -1, 0, ... are accepted, too.
+		    See "AC97 Quirk Option" section below.
     buggy_irq     - Enable workaround for buggy interrupts on some
-                    motherboards (default off)
+                    motherboards (default yes on nForce chips,
+		    otherwise off)
+    buggy_semaphore - Enable workaround for hardwares with buggy
+		    semaphores (e.g. on some ASUS laptops)
+		    (default off)
 
     Module supports autoprobe and multiple bus-master chips (max 8).
 
@@ -808,13 +821,6 @@
     motherboard has these devices, use the ns558 or snd-mpu401
     modules, respectively.
 
-    The ac97_quirk option is used to enable/override the workaround
-    for specific devices.  Some hardware have swapped output pins
-    between Master and Headphone, or Surround.  The driver provides
-    the auto-detection of known problematic devices, but some might
-    be unknown or wrongly detected.  In such a case, pass the proper
-    value with this option.
-
     The power-management is supported.
     
   Module snd-intel8x0m
@@ -966,7 +972,7 @@
     with machines with other (most likely CS423x or OPL3SAx) chips,
     even though the device is detected in lspci.  In such a case, try
     other drivers, e.g. snd-cs4232 or snd-opl3sa2.  Some has ISA-PnP
-    but some doesn't have ISA PnP.  You'll need to speicfy isapnp=0
+    but some doesn't have ISA PnP.  You'll need to specify isapnp=0
     and proper hardware parameters in the case without ISA PnP.
 
     Note: some laptops need a workaround for AC97 RESET.  For the
@@ -1302,7 +1308,7 @@
 		  channels
 		  [VIA8233/C, 8235, 8237 only]
     ac97_quirk  - AC'97 workaround for strange hardware
-                  See the description of intel8x0 module for details.
+		  See "AC97 Quirk Option" section below.
 
     Module supports autoprobe and multiple bus-master chips (max 8).
 
@@ -1327,16 +1333,17 @@
 	  "lspci -nv").
 	  If dxs_support=5 does not work, try dxs_support=4; if it
 	  doesn't work too, try dxs_support=1.  (dxs_support=1 is
-	  usually for old motherboards.  The correct implementated
+	  usually for old motherboards.  The correct implemented
 	  board should work with 4 or 5.)  If it still doesn't
 	  work and the default setting is ok, dxs_support=3 is the
 	  right choice.  If the default setting doesn't work at all,
 	  try dxs_support=2 to disable the DXS channels.
 	  In any cases, please let us know the result and the
-	  subsystem vendor/device ids.
+	  subsystem vendor/device ids.  See "Links and Addresses"
+	  below.
 
     Note: for the MPU401 on VIA823x, use snd-mpu401 driver
-	  additonally.  The mpu_port option is for VIA686 chips only.
+	  additionally.  The mpu_port option is for VIA686 chips only.
 
   Module snd-via82xx-modem
   ------------------------
@@ -1398,8 +1405,10 @@
     Module supports up to 8 cards.  The module is compiled only when
     PCMCIA is supported on kernel.
 
-    To activate the driver via the card manager, you'll need to set
-    up /etc/pcmcia/vxpocket.conf.  See the sound/pcmcia/vx/vxpocket.c.
+    With the older 2.6.x kernel, to activate the driver via the card
+    manager, you'll need to set up /etc/pcmcia/vxpocket.conf.  See the
+    sound/pcmcia/vx/vxpocket.c.  2.6.13 or later kernel requires no
+    longer require a config file.
 
     When the driver is compiled as a module and the hotplug firmware
     is supported, the firmware data is loaded via hotplug automatically.
@@ -1411,6 +1420,9 @@
 
     Note: the driver is build only when CONFIG_ISA is set.
     
+    Note2: snd-vxp440 driver is merged to snd-vxpocket driver since
+           ALSA 1.0.10.
+
   Module snd-ymfpci
   -----------------
 
@@ -1436,6 +1448,37 @@
     Note: the driver is build only when CONFIG_ISA is set.
 
 
+AC97 Quirk Option
+=================
+
+The ac97_quirk option is used to enable/override the workaround for
+specific devices on drivers for on-board AC'97 controllers like
+snd-intel8x0.  Some hardware have swapped output pins between Master
+and Headphone, or Surround (thanks to confusion of AC'97
+specifications from version to version :-)
+
+The driver provides the auto-detection of known problematic devices,
+but some might be unknown or wrongly detected.  In such a case, pass
+the proper value with this option.
+
+The following strings are accepted:
+    - default	Don't override the default setting
+    - disable	Disable the quirk
+    - hp_only	Bind Master and Headphone controls as a single control
+    - swap_hp	Swap headphone and master controls
+    - swap_surround  Swap master and surround controls
+    - ad_sharing  For AD1985, turn on OMS bit and use headphone
+    - alc_jack	For ALC65x, turn on the jack sense mode
+    - inv_eapd	Inverted EAPD implementation
+    - mute_led	Bind EAPD bit for turning on/off mute LED
+
+For backward compatibility, the corresponding integer value -1, 0,
+... are  accepted, too.
+
+For example, if "Master" volume control has no effect on your device
+but only "Headphone" does, pass ac97_quirk=hp_only module option.
+
+
 Configuring Non-ISAPNP Cards
 ============================
 
@@ -1553,6 +1596,8 @@
 	  - whole-frag  write only whole fragments (optimization affecting
 			playback only)
 	  - no-silence  do not fill silence ahead to avoid clicks
+	  - buggy-ptr	Returns the whitespace blocks in GETOPTR ioctl
+			instead of filled blocks
 
   Example: echo "x11amp 128 16384" > /proc/asound/card0/pcm0p/oss
            echo "squake 0 0 disable" > /proc/asound/card0/pcm0c/oss
@@ -1589,9 +1634,14 @@
     use.
 
 
-Links
-=====
+Links and Addresses
+===================
 
   ALSA project homepage
        http://www.alsa-project.org
 
+  ALSA Bug Tracking System
+       https://bugtrack.alsa-project.org/bugs/
+
+  ALSA Developers ML
+       mailto:alsa-devel@lists.sourceforge.net
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
index 0475478..24e8552 100644
--- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
@@ -447,7 +447,7 @@
           ....
 
           /* allocate a chip-specific data with zero filled */
-          chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+          chip = kzalloc(sizeof(*chip), GFP_KERNEL);
           if (chip == NULL)
                   return -ENOMEM;
 
@@ -949,7 +949,7 @@
           After allocating a card instance via
           <function>snd_card_new()</function> (with
           <constant>NULL</constant> on the 4th arg), call
-          <function>kcalloc()</function>. 
+          <function>kzalloc()</function>. 
 
           <informalexample>
             <programlisting>
@@ -958,7 +958,7 @@
   mychip_t *chip;
   card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL);
   .....
-  chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+  chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 ]]>
             </programlisting>
           </informalexample>
@@ -1136,7 +1136,7 @@
                   return -ENXIO;
           }
 
-          chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+          chip = kzalloc(sizeof(*chip), GFP_KERNEL);
           if (chip == NULL) {
                   pci_disable_device(pci);
                   return -ENOMEM;
@@ -1292,7 +1292,7 @@
       need to initialize this number as -1 before actual allocation,
       since irq 0 is valid. The port address and its resource pointer
       can be initialized as null by
-      <function>kcalloc()</function> automatically, so you
+      <function>kzalloc()</function> automatically, so you
       don't have to take care of resetting them. 
       </para>
 
diff --git a/MAINTAINERS b/MAINTAINERS
index a67bf7d..d1e0eb4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -370,7 +370,10 @@
 S:	Maintained
 
 AUDIT SUBSYSTEM
-L:	linux-audit@redhat.com (subscribers-only)
+P:	David Woodhouse
+M:	dwmw2@infradead.org
+L:	linux-audit@redhat.com
+W:	http://people.redhat.com/sgrubb/audit/
 S:	Maintained
 
 AX.25 NETWORK LAYER
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 949ec44..2ad4aa2 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -131,7 +131,7 @@
 		.long	sys_wait4
 /* 115 */	.long	sys_swapoff
 		.long	sys_sysinfo
-		.long	sys_ipc
+		.long	sys_ipc_wrapper
 		.long	sys_fsync
 		.long	sys_sigreturn_wrapper
 /* 120 */	.long	sys_clone_wrapper
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index db302c6..81d450a 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -273,6 +273,10 @@
 		str	r5, [sp, #4]
 		b	sys_mbind
 
+sys_ipc_wrapper:
+		str	r5, [sp, #4]		@ push sixth arg
+		b	sys_ipc
+
 /*
  * Note: off_4k (r5) is always units of 4K.  If we can't do the requested
  * offset, we return EINVAL.
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 405a55f..3e5f69b 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -20,40 +20,66 @@
 	select PXA25x
 
 config PXA_SHARPSL
-	bool "SHARP SL-5600 and SL-C7xx Models"
-	select PXA25x
+	bool "SHARP Zaurus SL-5600, SL-C7xx and SL-Cxx00 Models"
 	select SHARP_SCOOP
 	select SHARP_PARAM
 	help
 	  Say Y here if you intend to run this kernel on a
-	  Sharp SL-5600 (Poodle), Sharp SL-C700 (Corgi),
-	  SL-C750 (Shepherd) or a Sharp SL-C760 (Husky)
-	  handheld computer.
+	  Sharp Zaurus SL-5600 (Poodle), SL-C700 (Corgi),
+	  SL-C750 (Shepherd), SL-C760 (Husky), SL-C1000 (Akita),
+	  SL-C3000 (Spitz) or SL-C3100 (Borzoi) handheld computer.
 
 endchoice
 
+if PXA_SHARPSL
+
+choice
+	prompt "Select target Sharp Zaurus device range"
+
+config PXA_SHARPSL_25x
+	bool "Sharp PXA25x models (SL-5600 and SL-C7xx)"
+	select PXA25x
+
+config PXA_SHARPSL_27x
+	bool "Sharp PXA270 models (SL-Cxx00)"
+	select PXA27x
+
+endchoice
+
+endif
+
 endmenu
 
 config MACH_POODLE
 	bool "Enable Sharp SL-5600 (Poodle) Support"
-	depends PXA_SHARPSL
+	depends PXA_SHARPSL_25x
 	select SHARP_LOCOMO
 
 config MACH_CORGI
 	bool "Enable Sharp SL-C700 (Corgi) Support"
-	depends PXA_SHARPSL
+	depends PXA_SHARPSL_25x
 	select PXA_SHARP_C7xx
 
 config MACH_SHEPHERD
 	bool "Enable Sharp SL-C750 (Shepherd) Support"
-	depends PXA_SHARPSL
+	depends PXA_SHARPSL_25x
 	select PXA_SHARP_C7xx
 
 config MACH_HUSKY
 	bool "Enable Sharp SL-C760 (Husky) Support"
-	depends PXA_SHARPSL
+	depends PXA_SHARPSL_25x
 	select PXA_SHARP_C7xx
 
+config MACH_SPITZ
+	bool "Enable Sharp Zaurus SL-3000 (Spitz) Support"
+	depends PXA_SHARPSL_27x
+	select PXA_SHARP_Cxx00
+
+config MACH_BORZOI
+	bool "Enable Sharp Zaurus SL-3100 (Borzoi) Support"
+	depends PXA_SHARPSL_27x
+	select PXA_SHARP_Cxx00
+
 config PXA25x
 	bool
 	help
@@ -74,4 +100,9 @@
 	help
 	  Enable support for all Sharp C7xx models
 
+config PXA_SHARP_Cxx00
+	bool
+	help
+	  Enable common support for Sharp Cxx00 models
+
 endif
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 33dae99..f609a0f 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -12,6 +12,7 @@
 obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
 obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
 obj-$(CONFIG_PXA_SHARP_C7xx)	+= corgi.o corgi_ssp.o corgi_lcd.o ssp.o
+obj-$(CONFIG_PXA_SHARP_Cxx00)	+= spitz.o corgi_ssp.o corgi_lcd.o ssp.o
 obj-$(CONFIG_MACH_POODLE)	+= poodle.o
 
 # Support for blinky lights
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 07b5dd4..426c2bc 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -41,6 +41,7 @@
 #include <asm/hardware/scoop.h>
 
 #include "generic.h"
+#include "sharpsl.h"
 
 
 /*
@@ -94,14 +95,30 @@
 	.id		= -1,
 };
 
+struct corgissp_machinfo corgi_ssp_machinfo = {
+	.port		= 1,
+	.cs_lcdcon	= CORGI_GPIO_LCDCON_CS,
+	.cs_ads7846	= CORGI_GPIO_ADS7846_CS,
+	.cs_max1111	= CORGI_GPIO_MAX1111_CS,
+	.clk_lcdcon	= 76,
+	.clk_ads7846	= 2,
+	.clk_max1111	= 8,
+};
+
 
 /*
  * Corgi Backlight Device
  */
+static struct corgibl_machinfo corgi_bl_machinfo = {
+	.max_intensity = 0x2f,
+	.set_bl_intensity = corgi_bl_set_intensity,
+};
+
 static struct platform_device corgibl_device = {
 	.name		= "corgi-bl",
 	.dev		= {
  		.parent = &corgifb_device.dev,
+		.platform_data	= &corgi_bl_machinfo,
 	},
 	.id		= -1,
 };
@@ -119,12 +136,29 @@
 /*
  * Corgi Touch Screen Device
  */
+static struct resource corgits_resources[] = {
+	[0] = {
+		.start		= CORGI_IRQ_GPIO_TP_INT,
+		.end		= CORGI_IRQ_GPIO_TP_INT,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct corgits_machinfo  corgi_ts_machinfo = {
+	.get_hsync_len   = corgi_get_hsync_len,
+	.put_hsync       = corgi_put_hsync,
+	.wait_hsync      = corgi_wait_hsync,
+};
+
 static struct platform_device corgits_device = {
 	.name		= "corgi-ts",
 	.dev		= {
  		.parent = &corgissp_device.dev,
+		.platform_data	= &corgi_ts_machinfo,
 	},
 	.id		= -1,
+	.num_resources	= ARRAY_SIZE(corgits_resources),
+	.resource	= corgits_resources,
 };
 
 
@@ -225,7 +259,10 @@
 
 static void __init corgi_init(void)
 {
+	corgi_ssp_set_machinfo(&corgi_ssp_machinfo);
+
 	pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT);
+	pxa_gpio_mode(CORGI_GPIO_HSYNC | GPIO_IN);
  	pxa_set_udc_info(&udc_info);
 	pxa_set_mci_info(&corgi_mci_platform_data);
 
diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c
index deac29c..c5efcd0 100644
--- a/arch/arm/mach-pxa/corgi_lcd.c
+++ b/arch/arm/mach-pxa/corgi_lcd.c
@@ -1,10 +1,14 @@
 /*
  * linux/drivers/video/w100fb.c
  *
- * Corgi LCD Specific Code for ATI Imageon w100 (Wallaby)
+ * Corgi/Spitz LCD Specific Code
  *
  * Copyright (C) 2005 Richard Purdie
  *
+ * Connectivity:
+ *   Corgi - LCD to ATI Imageon w100 (Wallaby)
+ *   Spitz - LCD to PXA Framebuffer
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
@@ -14,9 +18,17 @@
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
+#include <linux/module.h>
+#include <asm/mach-types.h>
+#include <asm/arch/akita.h>
 #include <asm/arch/corgi.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/sharpsl.h>
+#include <asm/arch/spitz.h>
+#include <asm/hardware/scoop.h>
 #include <asm/mach/sharpsl_param.h>
-#include <video/w100fb.h>
+#include "generic.h"
 
 /* Register Addresses */
 #define RESCTL_ADRS     0x00
@@ -134,10 +146,10 @@
 }
 
 /* Set Phase Adjuct */
-static void lcdtg_set_phadadj(struct w100fb_par *par)
+static void lcdtg_set_phadadj(int mode)
 {
 	int adj;
-	switch(par->xres) {
+	switch(mode) {
 		case 480:
 		case 640:
 			/* Setting for VGA */
@@ -161,7 +173,7 @@
 
 static int lcd_inited;
 
-static void lcdtg_hw_init(struct w100fb_par *par)
+static void lcdtg_hw_init(int mode)
 {
 	if (!lcd_inited) {
 		int comadj;
@@ -215,7 +227,7 @@
 		corgi_ssp_lcdtg_send(PICTRL_ADRS, 0);
 
 		/* Set Phase Adjuct */
-		lcdtg_set_phadadj(par);
+		lcdtg_set_phadadj(mode);
 
 		/* Initialize for Input Signals from ATI */
 		corgi_ssp_lcdtg_send(POLCTRL_ADRS, POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE
@@ -224,10 +236,10 @@
 
 		lcd_inited=1;
 	} else {
-		lcdtg_set_phadadj(par);
+		lcdtg_set_phadadj(mode);
 	}
 
-	switch(par->xres) {
+	switch(mode) {
 		case 480:
 		case 640:
 			/* Set Lcd Resolution (VGA) */
@@ -242,7 +254,7 @@
 	}
 }
 
-static void lcdtg_suspend(struct w100fb_par *par)
+static void lcdtg_suspend(void)
 {
 	/* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */
 	mdelay(34);
@@ -276,15 +288,30 @@
 	lcd_inited = 0;
 }
 
-static struct w100_tg_info corgi_lcdtg_info = {
-	.change=lcdtg_hw_init,
-	.suspend=lcdtg_suspend,
-	.resume=lcdtg_hw_init,
-};
 
 /*
  * Corgi w100 Frame Buffer Device
  */
+#ifdef CONFIG_PXA_SHARP_C7xx
+
+#include <video/w100fb.h>
+
+static void w100_lcdtg_suspend(struct w100fb_par *par)
+{
+	lcdtg_suspend();
+}
+
+static void w100_lcdtg_init(struct w100fb_par *par)
+{
+	lcdtg_hw_init(par->xres);
+}
+
+
+static struct w100_tg_info corgi_lcdtg_info = {
+	.change  = w100_lcdtg_init,
+	.suspend = w100_lcdtg_suspend,
+	.resume  = w100_lcdtg_init,
+};
 
 static struct w100_mem_info corgi_fb_mem = {
 	.ext_cntl          = 0x00040003,
@@ -394,3 +421,145 @@
 	},
 
 };
+#endif
+
+
+/*
+ * Spitz PXA Frame Buffer Device
+ */
+#ifdef CONFIG_PXA_SHARP_Cxx00
+
+#include <asm/arch/pxafb.h>
+
+void spitz_lcd_power(int on)
+{
+	if (on)
+		lcdtg_hw_init(480);
+	else
+		lcdtg_suspend();
+}
+
+#endif
+
+
+/*
+ * Corgi/Spitz Touchscreen to LCD interface
+ */
+static unsigned long (*get_hsync_time)(struct device *dev);
+
+static void inline sharpsl_wait_sync(int gpio)
+{
+	while((GPLR(gpio) & GPIO_bit(gpio)) == 0);
+	while((GPLR(gpio) & GPIO_bit(gpio)) != 0);
+}
+
+#ifdef CONFIG_PXA_SHARP_C7xx
+unsigned long corgi_get_hsync_len(void)
+{
+	if (!get_hsync_time)
+		get_hsync_time = symbol_get(w100fb_get_hsynclen);
+	if (!get_hsync_time)
+		return 0;
+
+	return get_hsync_time(&corgifb_device.dev);
+}
+
+void corgi_put_hsync(void)
+{
+	if (get_hsync_time)
+		symbol_put(w100fb_get_hsynclen);
+}
+
+void corgi_wait_hsync(void)
+{
+	sharpsl_wait_sync(CORGI_GPIO_HSYNC);
+}
+#endif
+
+#ifdef CONFIG_PXA_SHARP_Cxx00
+unsigned long spitz_get_hsync_len(void)
+{
+	if (!get_hsync_time)
+		get_hsync_time = symbol_get(pxafb_get_hsync_time);
+	if (!get_hsync_time)
+		return 0;
+
+	return pxafb_get_hsync_time(&pxafb_device.dev);
+}
+
+void spitz_put_hsync(void)
+{
+	if (get_hsync_time)
+		symbol_put(pxafb_get_hsync_time);
+}
+
+void spitz_wait_hsync(void)
+{
+	sharpsl_wait_sync(SPITZ_GPIO_HSYNC);
+}
+#endif
+
+/*
+ * Corgi/Spitz Backlight Power
+ */
+#ifdef CONFIG_PXA_SHARP_C7xx
+void corgi_bl_set_intensity(int intensity)
+{
+	if (intensity > 0x10)
+		intensity += 0x10;
+
+	/* Bits 0-4 are accessed via the SSP interface */
+	corgi_ssp_blduty_set(intensity & 0x1f);
+
+	/* Bit 5 is via SCOOP */
+	if (intensity & 0x0020)
+		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
+	else
+		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
+}
+#endif
+
+
+#if defined(CONFIG_MACH_SPITZ) || defined(CONFIG_MACH_BORZOI)
+void spitz_bl_set_intensity(int intensity)
+{
+	if (intensity > 0x10)
+		intensity += 0x10;
+
+	/* Bits 0-4 are accessed via the SSP interface */
+	corgi_ssp_blduty_set(intensity & 0x1f);
+
+	/* Bit 5 is via SCOOP */
+	if (intensity & 0x0020)
+		reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT);
+	else
+		set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_CONT);
+
+	if (intensity)
+		set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON);
+	else
+		reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_BACKLIGHT_ON);
+}
+#endif
+
+#ifdef CONFIG_MACH_AKITA
+void akita_bl_set_intensity(int intensity)
+{
+	if (intensity > 0x10)
+		intensity += 0x10;
+
+	/* Bits 0-4 are accessed via the SSP interface */
+	corgi_ssp_blduty_set(intensity & 0x1f);
+
+	/* Bit 5 is via IO-Expander */
+	if (intensity & 0x0020)
+		akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT);
+	else
+		akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_CONT);
+
+	if (intensity)
+		akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON);
+	else
+		akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_BACKLIGHT_ON);
+}
+#endif
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
index 366a9bd..0ef4282 100644
--- a/arch/arm/mach-pxa/corgi_ssp.c
+++ b/arch/arm/mach-pxa/corgi_ssp.c
@@ -1,7 +1,7 @@
 /*
  *  SSP control code for Sharp Corgi devices
  *
- *  Copyright (c) 2004 Richard Purdie
+ *  Copyright (c) 2004-2005 Richard Purdie
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 as
@@ -17,14 +17,16 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <asm/hardware.h>
+#include <asm/mach-types.h>
 
 #include <asm/arch/ssp.h>
-#include <asm/arch/corgi.h>
 #include <asm/arch/pxa-regs.h>
+#include "sharpsl.h"
 
 static DEFINE_SPINLOCK(corgi_ssp_lock);
 static struct ssp_dev corgi_ssp_dev;
 static struct ssp_state corgi_ssp_state;
+static struct corgissp_machinfo *ssp_machinfo;
 
 /*
  * There are three devices connected to the SSP interface:
@@ -48,12 +50,12 @@
 	unsigned long ret,flag;
 
 	spin_lock_irqsave(&corgi_ssp_lock, flag);
-	GPCR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);
+	GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
 
 	ssp_write_word(&corgi_ssp_dev,data);
 	ret = ssp_read_word(&corgi_ssp_dev);
 
-	GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);
+	GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
 	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
 
 	return ret;
@@ -66,12 +68,12 @@
 void corgi_ssp_ads7846_lock(void)
 {
 	spin_lock(&corgi_ssp_lock);
-	GPCR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);
+	GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
 }
 
 void corgi_ssp_ads7846_unlock(void)
 {
-	GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);
+	GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
 	spin_unlock(&corgi_ssp_lock);
 }
 
@@ -97,23 +99,27 @@
  */
 unsigned long corgi_ssp_dac_put(ulong data)
 {
-	unsigned long flag;
+	unsigned long flag, sscr1 = SSCR1_SPH;
 
 	spin_lock_irqsave(&corgi_ssp_lock, flag);
-	GPCR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS);
+
+	if (machine_is_spitz() || machine_is_akita() || machine_is_borzoi())
+		sscr1 = 0;
 
 	ssp_disable(&corgi_ssp_dev);
-	ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), SSCR1_SPH, 0, SSCR0_SerClkDiv(76));
+	ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), sscr1, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_lcdcon));
 	ssp_enable(&corgi_ssp_dev);
 
+	GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
 	ssp_write_word(&corgi_ssp_dev,data);
 	/* Read null data back from device to prevent SSP overflow */
 	ssp_read_word(&corgi_ssp_dev);
+	GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
 
 	ssp_disable(&corgi_ssp_dev);
-	ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2));
+	ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
 	ssp_enable(&corgi_ssp_dev);
-	GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS);
+
 	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
 
 	return 0;
@@ -141,9 +147,9 @@
 	int voltage,voltage1,voltage2;
 
 	spin_lock_irqsave(&corgi_ssp_lock, flag);
-	GPCR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS);
+	GPCR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
 	ssp_disable(&corgi_ssp_dev);
-	ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(8));
+	ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_max1111));
 	ssp_enable(&corgi_ssp_dev);
 
 	udelay(1);
@@ -161,9 +167,9 @@
 	voltage2=ssp_read_word(&corgi_ssp_dev);
 
 	ssp_disable(&corgi_ssp_dev);
-	ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2));
+	ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
 	ssp_enable(&corgi_ssp_dev);
-	GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS);
+	GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
 	spin_unlock_irqrestore(&corgi_ssp_lock, flag);
 
 	if (voltage1 & 0xc0 || voltage2 & 0x3f)
@@ -179,25 +185,31 @@
 /*
  *  Support Routines
  */
-int __init corgi_ssp_probe(struct device *dev)
+
+void __init corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo)
+{
+	ssp_machinfo = machinfo;
+}
+
+static int __init corgi_ssp_probe(struct device *dev)
 {
 	int ret;
 
 	/* Chip Select - Disable All */
-	GPDR0 |= GPIO_bit(CORGI_GPIO_LCDCON_CS); /* output */
-	GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS);  /* High - Disable LCD Control/Timing Gen */
-	GPDR0 |= GPIO_bit(CORGI_GPIO_MAX1111_CS); /* output */
-	GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS);  /* High - Disable MAX1111*/
-	GPDR0 |= GPIO_bit(CORGI_GPIO_ADS7846_CS);  /* output */
-	GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS);   /* High - Disable ADS7846*/
+	GPDR(ssp_machinfo->cs_lcdcon) |= GPIO_bit(ssp_machinfo->cs_lcdcon); /* output */
+	GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);  /* High - Disable LCD Control/Timing Gen */
+	GPDR(ssp_machinfo->cs_max1111) |= GPIO_bit(ssp_machinfo->cs_max1111); /* output */
+	GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);  /* High - Disable MAX1111*/
+	GPDR(ssp_machinfo->cs_ads7846) |= GPIO_bit(ssp_machinfo->cs_ads7846);  /* output */
+	GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);   /* High - Disable ADS7846*/
 
-	ret=ssp_init(&corgi_ssp_dev,1);
+	ret = ssp_init(&corgi_ssp_dev,ssp_machinfo->port);
 
 	if (ret)
 		printk(KERN_ERR "Unable to register SSP handler!\n");
 	else {
 		ssp_disable(&corgi_ssp_dev);
-		ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(2));
+		ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
 		ssp_enable(&corgi_ssp_dev);
 	}
 
@@ -222,9 +234,9 @@
 static int corgi_ssp_resume(struct device *dev, u32 level)
 {
 	if (level == RESUME_POWER_ON) {
-		GPSR0 = GPIO_bit(CORGI_GPIO_LCDCON_CS);  /* High - Disable LCD Control/Timing Gen */
-		GPSR0 = GPIO_bit(CORGI_GPIO_MAX1111_CS); /* High - Disable MAX1111*/
-		GPSR0 = GPIO_bit(CORGI_GPIO_ADS7846_CS); /* High - Disable ADS7846*/
+		GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);  /* High - Disable LCD Control/Timing Gen */
+		GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
+		GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
 		ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
 		ssp_enable(&corgi_ssp_dev);
 	}
diff --git a/arch/arm/mach-pxa/sharpsl.h b/arch/arm/mach-pxa/sharpsl.h
new file mode 100644
index 0000000..3977a77
--- /dev/null
+++ b/arch/arm/mach-pxa/sharpsl.h
@@ -0,0 +1,34 @@
+/*
+ * SharpSL SSP Driver
+ */
+
+struct corgissp_machinfo {
+	int port;
+	int cs_lcdcon;
+	int cs_ads7846;
+	int cs_max1111;
+	int clk_lcdcon;
+	int clk_ads7846;
+	int clk_max1111;
+};
+
+void corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo);
+
+/*
+ * SharpSL Backlight
+ */
+
+void corgi_bl_set_intensity(int intensity);
+void spitz_bl_set_intensity(int intensity);
+void akita_bl_set_intensity(int intensity);
+
+/*
+ * SharpSL Touchscreen Driver
+ */
+
+unsigned long corgi_get_hsync_len(void);
+unsigned long spitz_get_hsync_len(void);
+void corgi_put_hsync(void);
+void spitz_put_hsync(void);
+void corgi_wait_hsync(void);
+void spitz_wait_hsync(void);
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
new file mode 100644
index 0000000..568afe3d
--- /dev/null
+++ b/arch/arm/mach-pxa/spitz.c
@@ -0,0 +1,380 @@
+/*
+ * Support for Sharp SL-Cxx00 Series of PDAs
+ * Models: SL-C3000 (Spitz), SL-C1000 (Akita) and SL-C3100 (Borzoi)
+ *
+ * Copyright (c) 2005 Richard Purdie
+ *
+ * Based on Sharp's 2.4 kernel patches/lubbock.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/mmc/host.h>
+
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/irq.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/udc.h>
+#include <asm/arch/ohci.h>
+#include <asm/arch/pxafb.h>
+#include <asm/arch/akita.h>
+#include <asm/arch/spitz.h>
+#include <asm/arch/sharpsl.h>
+
+#include <asm/mach/sharpsl_param.h>
+#include <asm/hardware/scoop.h>
+
+#include "generic.h"
+#include "sharpsl.h"
+
+/*
+ * Spitz SCOOP Device #1
+ */
+static struct resource spitz_scoop_resources[] = {
+	[0] = {
+		.start		= 0x10800000,
+		.end		= 0x10800fff,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct scoop_config spitz_scoop_setup = {
+	.io_dir 	= SPITZ_SCP_IO_DIR,
+	.io_out		= SPITZ_SCP_IO_OUT,
+	.suspend_clr = SPITZ_SCP_SUS_CLR,
+	.suspend_set = SPITZ_SCP_SUS_SET,
+};
+
+struct platform_device spitzscoop_device = {
+	.name		= "sharp-scoop",
+	.id		= 0,
+	.dev		= {
+ 		.platform_data	= &spitz_scoop_setup,
+	},
+	.num_resources	= ARRAY_SIZE(spitz_scoop_resources),
+	.resource	= spitz_scoop_resources,
+};
+
+/*
+ * Spitz SCOOP Device #2
+ */
+static struct resource spitz_scoop2_resources[] = {
+	[0] = {
+		.start		= 0x08800040,
+		.end		= 0x08800fff,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct scoop_config spitz_scoop2_setup = {
+	.io_dir 	= SPITZ_SCP2_IO_DIR,
+	.io_out		= SPITZ_SCP2_IO_OUT,
+	.suspend_clr = SPITZ_SCP2_SUS_CLR,
+	.suspend_set = SPITZ_SCP2_SUS_SET,
+};
+
+struct platform_device spitzscoop2_device = {
+	.name		= "sharp-scoop",
+	.id		= 1,
+	.dev		= {
+ 		.platform_data	= &spitz_scoop2_setup,
+	},
+	.num_resources	= ARRAY_SIZE(spitz_scoop2_resources),
+	.resource	= spitz_scoop2_resources,
+};
+
+static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = {
+{
+	.dev        = &spitzscoop_device.dev,
+	.irq        = SPITZ_IRQ_GPIO_CF_IRQ,
+	.cd_irq     = SPITZ_IRQ_GPIO_CF_CD,
+	.cd_irq_str = "PCMCIA0 CD",
+},{
+	.dev        = &spitzscoop2_device.dev,
+	.irq        = SPITZ_IRQ_GPIO_CF2_IRQ,
+	.cd_irq     = -1,
+},
+};
+
+
+/*
+ * Spitz SSP Device
+ *
+ * Set the parent as the scoop device because a lot of SSP devices
+ * also use scoop functions and this makes the power up/down order
+ * work correctly.
+ */
+struct platform_device spitzssp_device = {
+	.name		= "corgi-ssp",
+	.dev		= {
+ 		.parent = &spitzscoop_device.dev,
+	},
+	.id		= -1,
+};
+
+struct corgissp_machinfo spitz_ssp_machinfo = {
+	.port		= 2,
+	.cs_lcdcon	= SPITZ_GPIO_LCDCON_CS,
+	.cs_ads7846	= SPITZ_GPIO_ADS7846_CS,
+	.cs_max1111	= SPITZ_GPIO_MAX1111_CS,
+	.clk_lcdcon	= 520,
+	.clk_ads7846	= 14,
+	.clk_max1111	= 56,
+};
+
+
+/*
+ * Spitz Backlight Device
+ */
+static struct corgibl_machinfo spitz_bl_machinfo = {
+	.max_intensity = 0x2f,
+};
+
+static struct platform_device spitzbl_device = {
+	.name		= "corgi-bl",
+	.dev		= {
+ 		.platform_data	= &spitz_bl_machinfo,
+	},
+	.id		= -1,
+};
+
+
+/*
+ * Spitz Keyboard Device
+ */
+static struct platform_device spitzkbd_device = {
+	.name		= "spitz-keyboard",
+	.id		= -1,
+};
+
+
+/*
+ * Spitz Touch Screen Device
+ */
+static struct resource spitzts_resources[] = {
+	[0] = {
+		.start		= SPITZ_IRQ_GPIO_TP_INT,
+		.end		= SPITZ_IRQ_GPIO_TP_INT,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct corgits_machinfo  spitz_ts_machinfo = {
+	.get_hsync_len   = spitz_get_hsync_len,
+	.put_hsync       = spitz_put_hsync,
+	.wait_hsync      = spitz_wait_hsync,
+};
+
+static struct platform_device spitzts_device = {
+	.name		= "corgi-ts",
+	.dev		= {
+ 		.parent = &spitzssp_device.dev,
+		.platform_data	= &spitz_ts_machinfo,
+	},
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(spitzts_resources),
+	.resource	= spitzts_resources,
+};
+
+
+/*
+ * MMC/SD Device
+ *
+ * The card detect interrupt isn't debounced so we delay it by 250ms
+ * to give the card a chance to fully insert/eject.
+ */
+
+static struct pxamci_platform_data spitz_mci_platform_data;
+
+static int spitz_mci_init(struct device *dev, irqreturn_t (*spitz_detect_int)(int, void *, struct pt_regs *), void *data)
+{
+	int err;
+
+	/* setup GPIO for PXA27x MMC controller	*/
+	pxa_gpio_mode(GPIO32_MMCCLK_MD);
+	pxa_gpio_mode(GPIO112_MMCCMD_MD);
+	pxa_gpio_mode(GPIO92_MMCDAT0_MD);
+	pxa_gpio_mode(GPIO109_MMCDAT1_MD);
+	pxa_gpio_mode(GPIO110_MMCDAT2_MD);
+	pxa_gpio_mode(GPIO111_MMCDAT3_MD);
+	pxa_gpio_mode(SPITZ_GPIO_nSD_DETECT | GPIO_IN);
+	pxa_gpio_mode(SPITZ_GPIO_nSD_WP | GPIO_IN);
+
+	spitz_mci_platform_data.detect_delay = msecs_to_jiffies(250);
+
+	err = request_irq(SPITZ_IRQ_GPIO_nSD_DETECT, spitz_detect_int, SA_INTERRUPT,
+			     "MMC card detect", data);
+	if (err) {
+		printk(KERN_ERR "spitz_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
+		return -1;
+	}
+
+	set_irq_type(SPITZ_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);
+
+	return 0;
+}
+
+/* Power control is shared with one of the CF slots so we have a mess */
+static void spitz_mci_setpower(struct device *dev, unsigned int vdd)
+{
+	struct pxamci_platform_data* p_d = dev->platform_data;
+
+	unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR);
+
+	if (( 1 << vdd) & p_d->ocr_mask) {
+		/* printk(KERN_DEBUG "%s: on\n", __FUNCTION__); */
+		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
+		mdelay(2);
+		write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | 0x04);
+	} else {
+		/* printk(KERN_DEBUG "%s: off\n", __FUNCTION__); */
+		write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr & ~0x04);
+
+		if (!(cpr | 0x02)) {
+			mdelay(1);
+			reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
+		}
+	}
+}
+
+static int spitz_mci_get_ro(struct device *dev)
+{
+	return GPLR(SPITZ_GPIO_nSD_WP) & GPIO_bit(SPITZ_GPIO_nSD_WP);
+}
+
+static void spitz_mci_exit(struct device *dev, void *data)
+{
+	free_irq(SPITZ_IRQ_GPIO_nSD_DETECT, data);
+}
+
+static struct pxamci_platform_data spitz_mci_platform_data = {
+	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init 		= spitz_mci_init,
+	.get_ro		= spitz_mci_get_ro,
+	.setpower 	= spitz_mci_setpower,
+	.exit		= spitz_mci_exit,
+};
+
+
+/*
+ * Spitz PXA Framebuffer
+ */
+static struct pxafb_mach_info spitz_pxafb_info __initdata = {
+        .pixclock       = 19231,
+        .xres           = 480,
+        .yres           = 640,
+        .bpp            = 16,
+        .hsync_len      = 40,
+        .left_margin    = 46,
+        .right_margin   = 125,
+        .vsync_len      = 3,
+        .upper_margin   = 1,
+        .lower_margin   = 0,
+        .sync           = 0,
+        .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act | LCCR0_LDDALT | LCCR0_OUC | LCCR0_CMDIM | LCCR0_RDSTM,
+        .lccr3          = LCCR3_PixRsEdg | LCCR3_OutEnH,
+        .pxafb_lcd_power = spitz_lcd_power,
+};
+
+
+static struct platform_device *devices[] __initdata = {
+	&spitzscoop_device,
+	&spitzssp_device,
+	&spitzkbd_device,
+	&spitzts_device,
+	&spitzbl_device,
+	&spitzbattery_device,
+};
+
+static void __init common_init(void)
+{
+	PMCR = 0x00;
+
+	/* setup sleep mode values */
+	PWER  = 0x00000002;
+	PFER  = 0x00000000;
+	PRER  = 0x00000002;
+	PGSR0 = 0x0158C000;
+	PGSR1 = 0x00FF0080;
+	PGSR2 = 0x0001C004;
+
+	/* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
+	PCFR |= PCFR_OPDE;
+
+	corgi_ssp_set_machinfo(&spitz_ssp_machinfo);
+
+	pxa_gpio_mode(SPITZ_GPIO_HSYNC | GPIO_IN);
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+	pxa_set_mci_info(&spitz_mci_platform_data);
+	pxafb_device.dev.parent = &spitzssp_device.dev;
+	set_pxa_fb_info(&spitz_pxafb_info);
+}
+
+static void __init spitz_init(void)
+{
+	scoop_num = 2;
+	scoop_devs = &spitz_pcmcia_scoop[0];
+	spitz_bl_machinfo.set_bl_intensity = spitz_bl_set_intensity;
+
+	common_init();
+
+	platform_device_register(&spitzscoop2_device);
+}
+
+static void __init fixup_spitz(struct machine_desc *desc,
+		struct tag *tags, char **cmdline, struct meminfo *mi)
+{
+	sharpsl_save_param();
+	mi->nr_banks = 1;
+	mi->bank[0].start = 0xa0000000;
+	mi->bank[0].node = 0;
+	mi->bank[0].size = (64*1024*1024);
+}
+
+#ifdef CONFIG_MACH_SPITZ
+MACHINE_START(SPITZ, "SHARP Spitz")
+	.phys_ram	= 0xa0000000,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.fixup		= fixup_spitz,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa_init_irq,
+	.init_machine	= spitz_init,
+	.timer		= &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_BORZOI
+MACHINE_START(BORZOI, "SHARP Borzoi")
+	.phys_ram	= 0xa0000000,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.fixup		= fixup_spitz,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa_init_irq,
+	.init_machine	= spitz_init,
+	.timer		= &pxa_timer,
+MACHINE_END
+#endif
diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c
index 1cbb9c0..350ea66 100644
--- a/arch/i386/kernel/reboot.c
+++ b/arch/i386/kernel/reboot.c
@@ -11,6 +11,7 @@
 #include <linux/mc146818rtc.h>
 #include <linux/efi.h>
 #include <linux/dmi.h>
+#include <linux/ctype.h>
 #include <asm/uaccess.h>
 #include <asm/apic.h>
 #include <asm/desc.h>
@@ -28,8 +29,6 @@
 
 #ifdef CONFIG_SMP
 static int reboot_cpu = -1;
-/* shamelessly grabbed from lib/vsprintf.c for readability */
-#define is_digit(c)	((c) >= '0' && (c) <= '9')
 #endif
 static int __init reboot_setup(char *str)
 {
@@ -49,9 +48,9 @@
 			break;
 #ifdef CONFIG_SMP
 		case 's': /* "smp" reboot by executing reset on BSP or other CPU*/
-			if (is_digit(*(str+1))) {
+			if (isdigit(*(str+1))) {
 				reboot_cpu = (int) (*(str+1) - '0');
-				if (is_digit(*(str+2))) 
+				if (isdigit(*(str+2)))
 					reboot_cpu = reboot_cpu*10 + (int)(*(str+2) - '0');
 			}
 				/* we will leave sorting out the final value 
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index dc39ca6..9b8c8a1 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -848,9 +848,7 @@
 #ifdef CONFIG_X86_IO_APIC
 		else if (!memcmp(from, "acpi_skip_timer_override", 24))
 			acpi_skip_timer_override = 1;
-#endif
 
-#ifdef CONFIG_X86_LOCAL_APIC
 		if (!memcmp(from, "disable_timer_pin_1", 19))
 			disable_timer_pin_1 = 1;
 		if (!memcmp(from, "enable_timer_pin_1", 18))
@@ -859,7 +857,7 @@
 		/* disable IO-APIC */
 		else if (!memcmp(from, "noapic", 6))
 			disable_ioapic_setup();
-#endif /* CONFIG_X86_LOCAL_APIC */
+#endif /* CONFIG_X86_IO_APIC */
 #endif /* CONFIG_ACPI */
 
 #ifdef CONFIG_X86_LOCAL_APIC
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index c70cd2a..5f0a95d 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -202,7 +202,7 @@
 				goto valid_k7;
 
 		/* If we get here, it's not a certified SMP capable AMD system. */
-		tainted |= TAINT_UNSAFE_SMP;
+		add_taint(TAINT_UNSAFE_SMP);
 	}
 
 valid_k7:
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 09a58cb..431a551 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -807,8 +807,9 @@
 	cwd = get_fpu_cwd(task);
 	swd = get_fpu_swd(task);
 	switch (swd & ~cwd & 0x3f) {
-		case 0x000:
-		default:
+		case 0x000: /* No unmasked exception */
+			return;
+		default:    /* Multiple exceptions */
 			break;
 		case 0x001: /* Invalid Op */
 			/*
diff --git a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c
index 31de70b..a7280d9 100644
--- a/arch/ia64/ia32/binfmt_elf32.c
+++ b/arch/ia64/ia32/binfmt_elf32.c
@@ -216,12 +216,6 @@
 	if (!mpnt)
 		return -ENOMEM;
 
-	if (security_vm_enough_memory((IA32_STACK_TOP - (PAGE_MASK & (unsigned long) bprm->p))
-				      >> PAGE_SHIFT)) {
-		kmem_cache_free(vm_area_cachep, mpnt);
-		return -ENOMEM;
-	}
-
 	memset(mpnt, 0, sizeof(*mpnt));
 
 	down_write(&current->mm->mmap_sem);
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
index 4de1556..7ae4af4 100644
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -581,18 +581,13 @@
 	}
 
 	/*
-	 * Check if we have enough memory..
+	 * Ok, looks good - let it rip.
 	 */
-	if (security_vm_enough_memory((newbrk-oldbrk) >> PAGE_SHIFT)) {
+	if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk) {
 		ret = -ENOMEM;
 		goto out;
 	}
-
-	/*
-	 * Ok, looks good - let it rip.
-	 */
 	mm->brk = brk;
-	do_brk(oldbrk, newbrk-oldbrk);
 	ret = 0;
 
 out:
diff --git a/arch/ppc/kernel/temp.c b/arch/ppc/kernel/temp.c
index fe8bb63..26bd8ea 100644
--- a/arch/ppc/kernel/temp.c
+++ b/arch/ppc/kernel/temp.c
@@ -21,7 +21,6 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 
-#include <asm/segment.h>
 #include <asm/io.h>
 #include <asm/reg.h>
 #include <asm/nvram.h>
diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
index a3c5281..22d7fd1 100644
--- a/arch/ppc/kernel/time.c
+++ b/arch/ppc/kernel/time.c
@@ -58,7 +58,6 @@
 #include <linux/init.h>
 #include <linux/profile.h>
 
-#include <asm/segment.h>
 #include <asm/io.h>
 #include <asm/nvram.h>
 #include <asm/cache.h>
diff --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S
index 9353584..17d2db7 100644
--- a/arch/ppc/kernel/vmlinux.lds.S
+++ b/arch/ppc/kernel/vmlinux.lds.S
@@ -96,6 +96,9 @@
 	*(.init.text)
 	_einittext = .;
   }
+  /* .exit.text is discarded at runtime, not link time,
+     to deal with references from __bug_table */
+  .exit.text : { *(.exit.text) }
   .init.data : {
     *(.init.data);
     __vtop_table_begin = .;
@@ -190,5 +193,6 @@
   /* Sections to be discarded. */
   /DISCARD/ : {
     *(.exitcall.exit)
+    *(.exit.data)
   }
 }
diff --git a/arch/ppc/platforms/chrp_time.c b/arch/ppc/platforms/chrp_time.c
index 4864a7d..6037ce7 100644
--- a/arch/ppc/platforms/chrp_time.c
+++ b/arch/ppc/platforms/chrp_time.c
@@ -22,7 +22,6 @@
 #include <linux/init.h>
 #include <linux/bcd.h>
 
-#include <asm/segment.h>
 #include <asm/io.h>
 #include <asm/nvram.h>
 #include <asm/prom.h>
diff --git a/arch/ppc/syslib/prep_nvram.c b/arch/ppc/syslib/prep_nvram.c
index 2bcf8a1..8599850 100644
--- a/arch/ppc/syslib/prep_nvram.c
+++ b/arch/ppc/syslib/prep_nvram.c
@@ -15,7 +15,6 @@
 #include <linux/ioport.h>
 
 #include <asm/sections.h>
-#include <asm/segment.h>
 #include <asm/io.h>
 #include <asm/machdep.h>
 #include <asm/prep_nvram.h>
diff --git a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c
index 17e35d0..1ff4fa0 100644
--- a/arch/ppc64/kernel/asm-offsets.c
+++ b/arch/ppc64/kernel/asm-offsets.c
@@ -68,6 +68,7 @@
 	DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
 #endif /* CONFIG_ALTIVEC */
 	DEFINE(MM, offsetof(struct task_struct, mm));
+	DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context));
 
 	DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
 	DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_dline_size));
diff --git a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S
index d133a49..e8c0bbf 100644
--- a/arch/ppc64/kernel/entry.S
+++ b/arch/ppc64/kernel/entry.S
@@ -276,12 +276,22 @@
 _GLOBAL(ppc32_rt_sigsuspend)
 	bl	.save_nvgprs
 	bl	.sys32_rt_sigsuspend
-	/* If sigsuspend() returns zero, we are going into a signal handler */
 70:	cmpdi	0,r3,0
-	beq	.ret_from_except
-	/* If it returned -EINTR, we need to return via syscall_exit to set
+	/* If it returned an error, we need to return via syscall_exit to set
 	   the SO bit in cr0 and potentially stop for ptrace. */
-	b	syscall_exit
+	bne	syscall_exit
+	/* If sigsuspend() returns zero, we are going into a signal handler. We
+	   may need to call audit_syscall_exit() to mark the exit from sigsuspend() */
+#ifdef CONFIG_AUDIT
+	ld	r3,PACACURRENT(r13)
+	ld	r4,AUDITCONTEXT(r3)
+	cmpdi	0,r4,0
+	beq	.ret_from_except	/* No audit_context: Leave immediately. */
+	li	r4, 2			/* AUDITSC_FAILURE */
+	li	r5,-4			/* It's always -EINTR */
+	bl	.audit_syscall_exit
+#endif
+	b	.ret_from_except
 
 _GLOBAL(ppc_fork)
 	bl	.save_nvgprs
diff --git a/arch/ppc64/kernel/pSeries_setup.c b/arch/ppc64/kernel/pSeries_setup.c
index bfadccc..3009701 100644
--- a/arch/ppc64/kernel/pSeries_setup.c
+++ b/arch/ppc64/kernel/pSeries_setup.c
@@ -238,8 +238,8 @@
 
 	/* Find and initialize PCI host bridges */
 	init_pci_config_tokens();
-	eeh_init();
 	find_and_init_phbs();
+	eeh_init();
 
 #ifdef CONFIG_DUMMY_CONSOLE
 	conswitchp = &dummy_con;
diff --git a/arch/ppc64/kernel/vdso.c b/arch/ppc64/kernel/vdso.c
index 4777676..efa985f 100644
--- a/arch/ppc64/kernel/vdso.c
+++ b/arch/ppc64/kernel/vdso.c
@@ -224,10 +224,7 @@
 	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
 	if (vma == NULL)
 		return -ENOMEM;
-	if (security_vm_enough_memory(vdso_pages)) {
-		kmem_cache_free(vm_area_cachep, vma);
-		return -ENOMEM;
-	}
+
 	memset(vma, 0, sizeof(*vma));
 
 	/*
@@ -237,8 +234,10 @@
 	 */
 	vdso_base = get_unmapped_area(NULL, vdso_base,
 				      vdso_pages << PAGE_SHIFT, 0, 0);
-	if (vdso_base & ~PAGE_MASK)
+	if (vdso_base & ~PAGE_MASK) {
+		kmem_cache_free(vm_area_cachep, vma);
 		return (int)vdso_base;
+	}
 
 	current->thread.vdso_base = vdso_base;
 
@@ -266,7 +265,11 @@
 	vma->vm_ops = &vdso_vmops;
 
 	down_write(&mm->mmap_sem);
-	insert_vm_struct(mm, vma);
+	if (insert_vm_struct(mm, vma)) {
+		up_write(&mm->mmap_sem);
+		kmem_cache_free(vm_area_cachep, vma);
+		return -ENOMEM;
+	}
 	mm->total_vm += (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
 	up_write(&mm->mmap_sem);
 
diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c
index c8131f3..d9161e3 100644
--- a/arch/x86_64/ia32/ia32_binfmt.c
+++ b/arch/x86_64/ia32/ia32_binfmt.c
@@ -353,11 +353,6 @@
 	mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
 	if (!mpnt) 
 		return -ENOMEM; 
-	
-	if (security_vm_enough_memory((IA32_STACK_TOP - (PAGE_MASK & (unsigned long) bprm->p))>>PAGE_SHIFT)) {
-		kmem_cache_free(vm_area_cachep, mpnt);
-		return -ENOMEM;
-	}
 
 	memset(mpnt, 0, sizeof(*mpnt));
 
diff --git a/arch/x86_64/ia32/syscall32.c b/arch/x86_64/ia32/syscall32.c
index adbc5f8..3a01329 100644
--- a/arch/x86_64/ia32/syscall32.c
+++ b/arch/x86_64/ia32/syscall32.c
@@ -52,17 +52,13 @@
 	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
 	if (!vma)
 		return -ENOMEM;
-	if (security_vm_enough_memory(npages)) {
-		kmem_cache_free(vm_area_cachep, vma);
-		return -ENOMEM;
-	}
 
 	memset(vma, 0, sizeof(struct vm_area_struct));
 	/* Could randomize here */
 	vma->vm_start = VSYSCALL32_BASE;
 	vma->vm_end = VSYSCALL32_END;
 	/* MAYWRITE to allow gdb to COW and set breakpoints */
-	vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYEXEC|VM_MAYWRITE;
+	vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE;
 	vma->vm_flags |= mm->def_flags;
 	vma->vm_page_prot = protection_map[vma->vm_flags & 7];
 	vma->vm_ops = &syscall32_vm_ops;
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
index eb7929e..4e34b0f 100644
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -28,6 +28,7 @@
  * PFN of last memory page.
  */
 unsigned long end_pfn; 
+EXPORT_SYMBOL(end_pfn);
 
 /* 
  * end_pfn only includes RAM, while end_pfn_map includes all e820 entries.
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c
index 969365c..08203b0 100644
--- a/arch/x86_64/kernel/mce.c
+++ b/arch/x86_64/kernel/mce.c
@@ -217,7 +217,7 @@
 			panicm_found = 1;
 		}
 
-		tainted |= TAINT_MACHINE_CHECK;
+		add_taint(TAINT_MACHINE_CHECK);
 	}
 
 	/* Never do anything final in the polling timer */
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index 4388b8a5..39d445e 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -366,7 +366,7 @@
 		| K7_NMI_EVENT;
 
 	wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
-	wrmsr(MSR_K7_PERFCTR0, -(cpu_khz/nmi_hz*1000), -1);
+	wrmsrl(MSR_K7_PERFCTR0, -((u64)cpu_khz * 1000 / nmi_hz));
 	apic_write(APIC_LVTPC, APIC_DM_NMI);
 	evntsel |= K7_EVNTSEL_ENABLE;
 	wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
@@ -407,8 +407,8 @@
 
 	wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0);
 	wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 0);
-	Dprintk("setting P4_IQ_COUNTER0 to 0x%08lx\n", -(cpu_khz/nmi_hz*1000));
-	wrmsr(MSR_P4_IQ_COUNTER0, -(cpu_khz/nmi_hz*1000), -1);
+	Dprintk("setting P4_IQ_COUNTER0 to 0x%08lx\n", -(cpu_khz * 1000UL / nmi_hz));
+	wrmsrl(MSR_P4_IQ_COUNTER0, -((u64)cpu_khz * 1000 / nmi_hz));
 	apic_write(APIC_LVTPC, APIC_DM_NMI);
 	wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0);
 	return 1;
@@ -506,7 +506,7 @@
  			wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0);
  			apic_write(APIC_LVTPC, APIC_DM_NMI);
  		}
-		wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1);
+		wrmsrl(nmi_perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz));
 	}
 }
 
diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c
index 373e7b7..6b2eb6f 100644
--- a/drivers/base/attribute_container.c
+++ b/drivers/base/attribute_container.c
@@ -152,12 +152,13 @@
 
 		if (!cont->match(cont, dev))
 			continue;
-		ic = kmalloc(sizeof(struct internal_container), GFP_KERNEL);
+
+		ic = kzalloc(sizeof(*ic), GFP_KERNEL);
 		if (!ic) {
 			dev_printk(KERN_ERR, dev, "failed to allocate class container\n");
 			continue;
 		}
-		memset(ic, 0, sizeof(struct internal_container));
+
 		ic->cont = cont;
 		class_device_initialize(&ic->classdev);
 		ic->classdev.dev = get_device(dev);
diff --git a/drivers/base/class.c b/drivers/base/class.c
index d164c32..3b112e3 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -189,12 +189,11 @@
 	struct class *cls;
 	int retval;
 
-	cls = kmalloc(sizeof(struct class), GFP_KERNEL);
+	cls = kzalloc(sizeof(*cls), GFP_KERNEL);
 	if (!cls) {
 		retval = -ENOMEM;
 		goto error;
 	}
-	memset(cls, 0x00, sizeof(struct class));
 
 	cls->name = name;
 	cls->owner = owner;
@@ -500,13 +499,13 @@
 	/* add the needed attributes to this device */
 	if (MAJOR(class_dev->devt)) {
 		struct class_device_attribute *attr;
-		attr = kmalloc(sizeof(*attr), GFP_KERNEL);
+		attr = kzalloc(sizeof(*attr), GFP_KERNEL);
 		if (!attr) {
 			error = -ENOMEM;
 			kobject_del(&class_dev->kobj);
 			goto register_done;
 		}
-		memset(attr, sizeof(*attr), 0x00);
+
 		attr->attr.name = "dev";
 		attr->attr.mode = S_IRUGO;
 		attr->attr.owner = parent->owner;
@@ -577,12 +576,11 @@
 	if (cls == NULL || IS_ERR(cls))
 		goto error;
 
-	class_dev = kmalloc(sizeof(struct class_device), GFP_KERNEL);
+	class_dev = kzalloc(sizeof(*class_dev), GFP_KERNEL);
 	if (!class_dev) {
 		retval = -ENOMEM;
 		goto error;
 	}
-	memset(class_dev, 0x00, sizeof(struct class_device));
 
 	class_dev->devt = devt;
 	class_dev->dev = device;
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 5bfa2e9..4acb2c5 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -301,9 +301,9 @@
 			 const char *fw_name, struct device *device)
 {
 	int retval;
-	struct firmware_priv *fw_priv = kmalloc(sizeof (struct firmware_priv),
+	struct firmware_priv *fw_priv = kzalloc(sizeof(*fw_priv),
 						GFP_KERNEL);
-	struct class_device *class_dev = kmalloc(sizeof (struct class_device),
+	struct class_device *class_dev = kzalloc(sizeof(*class_dev),
 						 GFP_KERNEL);
 
 	*class_dev_p = NULL;
@@ -313,8 +313,6 @@
 		retval = -ENOMEM;
 		goto error_kfree;
 	}
-	memset(fw_priv, 0, sizeof (*fw_priv));
-	memset(class_dev, 0, sizeof (*class_dev));
 
 	init_completion(&fw_priv->completion);
 	fw_priv->attr_data = firmware_attr_data_tmpl;
@@ -402,14 +400,13 @@
 	if (!firmware_p)
 		return -EINVAL;
 
-	*firmware_p = firmware = kmalloc(sizeof (struct firmware), GFP_KERNEL);
+	*firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL);
 	if (!firmware) {
 		printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n",
 		       __FUNCTION__);
 		retval = -ENOMEM;
 		goto out;
 	}
-	memset(firmware, 0, sizeof (*firmware));
 
 	retval = fw_setup_class_device(firmware, &class_dev, name, device,
 		hotplug);
diff --git a/drivers/base/map.c b/drivers/base/map.c
index 2f455d8..b449dae 100644
--- a/drivers/base/map.c
+++ b/drivers/base/map.c
@@ -135,7 +135,7 @@
 struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct semaphore *sem)
 {
 	struct kobj_map *p = kmalloc(sizeof(struct kobj_map), GFP_KERNEL);
-	struct probe *base = kmalloc(sizeof(struct probe), GFP_KERNEL);
+	struct probe *base = kzalloc(sizeof(*base), GFP_KERNEL);
 	int i;
 
 	if ((p == NULL) || (base == NULL)) {
@@ -144,7 +144,6 @@
 		return NULL;
 	}
 
-	memset(base, 0, sizeof(struct probe));
 	base->dev = 1;
 	base->range = ~0;
 	base->get = base_probe;
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 3a5f4c9..361e204 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -225,13 +225,12 @@
 	struct platform_object *pobj;
 	int retval;
 
-	pobj = kmalloc(sizeof(struct platform_object) + sizeof(struct resource) * num, GFP_KERNEL);
+	pobj = kzalloc(sizeof(*pobj) + sizeof(struct resource) * num, GFP_KERNEL);
 	if (!pobj) {
 		retval = -ENOMEM;
 		goto error;
 	}
 
-	memset(pobj, 0, sizeof(*pobj));
 	pobj->pdev.name = name;
 	pobj->pdev.id = id;
 	pobj->pdev.dev.release = platform_device_release_simple;
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 28f2c17..c56f995 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -47,14 +47,14 @@
 #include <linux/completion.h>
 
 #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
-#define DRIVER_NAME "HP CISS Driver (v 2.6.6)"
-#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,6)
+#define DRIVER_NAME "HP CISS Driver (v 2.6.8)"
+#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,8)
 
 /* Embedded module documentation macros - see modules.h */
 MODULE_AUTHOR("Hewlett-Packard Company");
-MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.6");
+MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.8");
 MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"
-			" SA6i P600 P800 E400 E300");
+			" SA6i P600 P800 P400 P400i E200 E200i");
 MODULE_LICENSE("GPL");
 
 #include "cciss_cmd.h"
@@ -83,12 +83,22 @@
 		0x0E11, 0x4091, 0, 0, 0},
 	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSA,
 		0x103C, 0x3225, 0, 0, 0},
-	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSB,
+	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC,
 		0x103c, 0x3223, 0, 0, 0},
 	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC,
-		0x103c, 0x3231, 0, 0, 0},
+		0x103c, 0x3234, 0, 0, 0},
 	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC,
-		0x103c, 0x3233, 0, 0, 0},
+		0x103c, 0x3235, 0, 0, 0},
+	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD,
+		0x103c, 0x3211, 0, 0, 0},
+	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD,
+		0x103c, 0x3212, 0, 0, 0},
+	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD,
+		0x103c, 0x3213, 0, 0, 0},
+	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD,
+		0x103c, 0x3214, 0, 0, 0},
+	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD,
+		0x103c, 0x3215, 0, 0, 0},
 	{0,}
 };
 MODULE_DEVICE_TABLE(pci, cciss_pci_device_id);
@@ -111,8 +121,13 @@
 	{ 0x40910E11, "Smart Array 6i", &SA5_access},
 	{ 0x3225103C, "Smart Array P600", &SA5_access},
 	{ 0x3223103C, "Smart Array P800", &SA5_access},
-	{ 0x3231103C, "Smart Array E400", &SA5_access},
-	{ 0x3233103C, "Smart Array E300", &SA5_access},
+	{ 0x3234103C, "Smart Array P400", &SA5_access},
+	{ 0x3235103C, "Smart Array P400i", &SA5_access},
+	{ 0x3211103C, "Smart Array E200i", &SA5_access},
+	{ 0x3212103C, "Smart Array E200", &SA5_access},
+	{ 0x3213103C, "Smart Array E200i", &SA5_access},
+	{ 0x3214103C, "Smart Array E200i", &SA5_access},
+	{ 0x3215103C, "Smart Array E200i", &SA5_access},
 };
 
 /* How long to wait (in millesconds) for board to go into simple mode */
@@ -140,15 +155,26 @@
 
 static int revalidate_allvol(ctlr_info_t *host);
 static int cciss_revalidate(struct gendisk *disk);
-static int deregister_disk(struct gendisk *disk);
-static int register_new_disk(ctlr_info_t *h);
+static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk);
+static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, int clear_all);
 
+static void cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf,
+	int withirq, unsigned int *total_size, unsigned int *block_size);
+static void cciss_geometry_inquiry(int ctlr, int logvol,
+			int withirq, unsigned int total_size,
+			unsigned int block_size, InquiryData_struct *inq_buff,
+			drive_info_struct *drv);
 static void cciss_getgeometry(int cntl_num);
 
 static void start_io( ctlr_info_t *h);
 static int sendcmd( __u8 cmd, int ctlr, void *buff, size_t size,
 	unsigned int use_unit_num, unsigned int log_unit, __u8 page_code,
 	unsigned char *scsi3addr, int cmd_type);
+static int sendcmd_withirq(__u8	cmd, int ctlr, void *buff, size_t size,
+	unsigned int use_unit_num, unsigned int log_unit, __u8	page_code,
+	int cmd_type);
+
+static void fail_all_cmds(unsigned long ctlr);
 
 #ifdef CONFIG_PROC_FS
 static int cciss_proc_get_info(char *buffer, char **start, off_t offset, 
@@ -265,7 +291,7 @@
 	for(i=0; i<=h->highest_lun; i++) {
 
                 drv = &h->drv[i];
-		if (drv->block_size == 0)
+		if (drv->heads == 0)
 			continue;
 
 		vol_sz = drv->nr_blocks;
@@ -363,6 +389,8 @@
                  	return NULL;
 		memset(c, 0, sizeof(CommandList_struct));
 
+		c->cmdindex = -1;
+
 		c->err_info = (ErrorInfo_struct *)pci_alloc_consistent(
 					h->pdev, sizeof(ErrorInfo_struct), 
 					&err_dma_handle);
@@ -393,6 +421,8 @@
 		err_dma_handle = h->errinfo_pool_dhandle 
 					+ i*sizeof(ErrorInfo_struct);
                 h->nr_allocs++;
+
+		c->cmdindex = i;
         }
 
 	c->busaddr = (__u32) cmd_dma_handle;
@@ -453,6 +483,11 @@
 	printk(KERN_DEBUG "cciss_open %s\n", inode->i_bdev->bd_disk->disk_name);
 #endif /* CCISS_DEBUG */ 
 
+	if (host->busy_initializing)
+		return -EBUSY;
+
+	if (host->busy_initializing || drv->busy_configuring)
+		return -EBUSY;
 	/*
 	 * Root is allowed to open raw volume zero even if it's not configured
 	 * so array config can still work. Root is also allowed to open any
@@ -796,10 +831,10 @@
  		return(0);
  	}
 	case CCISS_DEREGDISK:
-		return deregister_disk(disk);
+		return rebuild_lun_table(host, disk);
 
 	case CCISS_REGNEWD:
-		return register_new_disk(host);
+		return rebuild_lun_table(host, NULL);
 
 	case CCISS_PASSTHRU:
 	{
@@ -1143,48 +1178,323 @@
         return 0;
 }
 
-static int deregister_disk(struct gendisk *disk)
+/* This function will check the usage_count of the drive to be updated/added.
+ * If the usage_count is zero then the drive information will be updated and
+ * the disk will be re-registered with the kernel.  If not then it will be
+ * left alone for the next reboot.  The exception to this is disk 0 which
+ * will always be left registered with the kernel since it is also the
+ * controller node.  Any changes to disk 0 will show up on the next
+ * reboot.
+*/
+static void cciss_update_drive_info(int ctlr, int drv_index)
+  {
+	ctlr_info_t *h = hba[ctlr];
+	struct gendisk *disk;
+	ReadCapdata_struct *size_buff = NULL;
+	InquiryData_struct *inq_buff = NULL;
+	unsigned int block_size;
+	unsigned int total_size;
+	unsigned long flags = 0;
+	int ret = 0;
+
+	/* if the disk already exists then deregister it before proceeding*/
+	if (h->drv[drv_index].raid_level != -1){
+		spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+		h->drv[drv_index].busy_configuring = 1;
+		spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+		ret = deregister_disk(h->gendisk[drv_index],
+			&h->drv[drv_index], 0);
+		h->drv[drv_index].busy_configuring = 0;
+	}
+
+	/* If the disk is in use return */
+	if (ret)
+		return;
+
+
+	/* Get information about the disk and modify the driver sturcture */
+	size_buff = kmalloc(sizeof( ReadCapdata_struct), GFP_KERNEL);
+        if (size_buff == NULL)
+		goto mem_msg;
+	inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL);
+	if (inq_buff == NULL)
+		goto mem_msg;
+
+	cciss_read_capacity(ctlr, drv_index, size_buff, 1,
+		&total_size, &block_size);
+	cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size,
+		inq_buff, &h->drv[drv_index]);
+
+	++h->num_luns;
+	disk = h->gendisk[drv_index];
+	set_capacity(disk, h->drv[drv_index].nr_blocks);
+
+
+	/* if it's the controller it's already added */
+	if (drv_index){
+		disk->queue = blk_init_queue(do_cciss_request, &h->lock);
+
+		/* Set up queue information */
+		disk->queue->backing_dev_info.ra_pages = READ_AHEAD;
+		blk_queue_bounce_limit(disk->queue, hba[ctlr]->pdev->dma_mask);
+
+		/* This is a hardware imposed limit. */
+		blk_queue_max_hw_segments(disk->queue, MAXSGENTRIES);
+
+		/* This is a limit in the driver and could be eliminated. */
+		blk_queue_max_phys_segments(disk->queue, MAXSGENTRIES);
+
+		blk_queue_max_sectors(disk->queue, 512);
+
+		disk->queue->queuedata = hba[ctlr];
+
+		blk_queue_hardsect_size(disk->queue,
+			hba[ctlr]->drv[drv_index].block_size);
+
+		h->drv[drv_index].queue = disk->queue;
+		add_disk(disk);
+	}
+
+freeret:
+	kfree(size_buff);
+	kfree(inq_buff);
+	return;
+mem_msg:
+	printk(KERN_ERR "cciss: out of memory\n");
+	goto freeret;
+}
+
+/* This function will find the first index of the controllers drive array
+ * that has a -1 for the raid_level and will return that index.  This is
+ * where new drives will be added.  If the index to be returned is greater
+ * than the highest_lun index for the controller then highest_lun is set
+ * to this new index.  If there are no available indexes then -1 is returned.
+*/
+static int cciss_find_free_drive_index(int ctlr)
 {
-	unsigned long flags;
-	ctlr_info_t *h = get_host(disk);
-	drive_info_struct *drv = get_drv(disk);
+	int i;
+
+	for (i=0; i < CISS_MAX_LUN; i++){
+		if (hba[ctlr]->drv[i].raid_level == -1){
+			if (i > hba[ctlr]->highest_lun)
+				hba[ctlr]->highest_lun = i;
+			return i;
+		}
+	}
+	return -1;
+}
+
+/* This function will add and remove logical drives from the Logical
+ * drive array of the controller and maintain persistancy of ordering
+ * so that mount points are preserved until the next reboot.  This allows
+ * for the removal of logical drives in the middle of the drive array
+ * without a re-ordering of those drives.
+ * INPUT
+ * h		= The controller to perform the operations on
+ * del_disk	= The disk to remove if specified.  If the value given
+ *		  is NULL then no disk is removed.
+*/
+static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk)
+{
 	int ctlr = h->ctlr;
+	int num_luns;
+	ReportLunData_struct *ld_buff = NULL;
+	drive_info_struct *drv = NULL;
+	int return_code;
+	int listlength = 0;
+	int i;
+	int drv_found;
+	int drv_index = 0;
+	__u32 lunid = 0;
+	unsigned long flags;
+
+	/* Set busy_configuring flag for this operation */
+	spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
+	if (h->num_luns >= CISS_MAX_LUN){
+		spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+		return -EINVAL;
+	}
+
+	if (h->busy_configuring){
+		spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+		return -EBUSY;
+	}
+	h->busy_configuring = 1;
+
+	/* if del_disk is NULL then we are being called to add a new disk
+	 * and update the logical drive table.  If it is not NULL then
+	 * we will check if the disk is in use or not.
+	 */
+	if (del_disk != NULL){
+		drv = get_drv(del_disk);
+		drv->busy_configuring = 1;
+		spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+		return_code = deregister_disk(del_disk, drv, 1);
+		drv->busy_configuring = 0;
+		h->busy_configuring = 0;
+		return return_code;
+	} else {
+		spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
+		if (!capable(CAP_SYS_RAWIO))
+			return -EPERM;
+
+		ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL);
+		if (ld_buff == NULL)
+			goto mem_msg;
+
+		return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff,
+				sizeof(ReportLunData_struct), 0, 0, 0,
+				TYPE_CMD);
+
+		if (return_code == IO_OK){
+			listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24;
+			listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16;
+			listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8;
+			listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]);
+		} else{ /* reading number of logical volumes failed */
+			printk(KERN_WARNING "cciss: report logical volume"
+				" command failed\n");
+			listlength = 0;
+			goto freeret;
+		}
+
+		num_luns = listlength / 8;	/* 8 bytes per entry */
+		if (num_luns > CISS_MAX_LUN){
+			num_luns = CISS_MAX_LUN;
+			printk(KERN_WARNING "cciss: more luns configured"
+				" on controller than can be handled by"
+				" this driver.\n");
+		}
+
+		/* Compare controller drive array to drivers drive array.
+	 	* Check for updates in the drive information and any new drives
+	 	* on the controller.
+	 	*/
+		for (i=0; i < num_luns; i++){
+			int j;
+
+			drv_found = 0;
+
+	  		lunid = (0xff &
+				(unsigned int)(ld_buff->LUN[i][3])) << 24;
+        		lunid |= (0xff &
+				(unsigned int)(ld_buff->LUN[i][2])) << 16;
+        		lunid |= (0xff &
+				(unsigned int)(ld_buff->LUN[i][1])) << 8;
+        		lunid |= 0xff &
+				(unsigned int)(ld_buff->LUN[i][0]);
+
+			/* Find if the LUN is already in the drive array
+			 * of the controller.  If so then update its info
+			 * if not is use.  If it does not exist then find
+			 * the first free index and add it.
+			*/
+			for (j=0; j <= h->highest_lun; j++){
+				if (h->drv[j].LunID == lunid){
+					drv_index = j;
+					drv_found = 1;
+				}
+			}
+
+			/* check if the drive was found already in the array */
+			if (!drv_found){
+				drv_index = cciss_find_free_drive_index(ctlr);
+				if (drv_index == -1)
+					goto freeret;
+
+			}
+			h->drv[drv_index].LunID = lunid;
+			cciss_update_drive_info(ctlr, drv_index);
+		} /* end for */
+	} /* end else */
+
+freeret:
+	kfree(ld_buff);
+	h->busy_configuring = 0;
+	/* We return -1 here to tell the ACU that we have registered/updated
+	 * all of the drives that we can and to keep it from calling us
+	 * additional times.
+	*/
+	return -1;
+mem_msg:
+	printk(KERN_ERR "cciss: out of memory\n");
+	goto freeret;
+}
+
+/* This function will deregister the disk and it's queue from the
+ * kernel.  It must be called with the controller lock held and the
+ * drv structures busy_configuring flag set.  It's parameters are:
+ *
+ * disk = This is the disk to be deregistered
+ * drv  = This is the drive_info_struct associated with the disk to be
+ *        deregistered.  It contains information about the disk used
+ *        by the driver.
+ * clear_all = This flag determines whether or not the disk information
+ *             is going to be completely cleared out and the highest_lun
+ *             reset.  Sometimes we want to clear out information about
+ *             the disk in preperation for re-adding it.  In this case
+ *             the highest_lun should be left unchanged and the LunID
+ *             should not be cleared.
+*/
+static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
+			   int clear_all)
+{
+	ctlr_info_t *h = get_host(disk);
 
 	if (!capable(CAP_SYS_RAWIO))
 		return -EPERM;
 
-	spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
 	/* make sure logical volume is NOT is use */
-	if( drv->usage_count > 1) {
-		spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
+	if(clear_all || (h->gendisk[0] == disk)) {
+	if (drv->usage_count > 1)
                 return -EBUSY;
 	}
-	drv->usage_count++;
-	spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
+        else
+        	if( drv->usage_count > 0 )
+                	return -EBUSY;
 
-	/* invalidate the devices and deregister the disk */ 
-	if (disk->flags & GENHD_FL_UP)
+	/* invalidate the devices and deregister the disk.  If it is disk
+	 * zero do not deregister it but just zero out it's values.  This
+	 * allows us to delete disk zero but keep the controller registered.
+	*/
+	if (h->gendisk[0] != disk){
+		if (disk->flags & GENHD_FL_UP){
+			blk_cleanup_queue(disk->queue);
 		del_gendisk(disk);
+			drv->queue = NULL;
+		}
+	}
+
+	--h->num_luns;
+	/* zero out the disk size info */
+	drv->nr_blocks = 0;
+	drv->block_size = 0;
+	drv->heads = 0;
+	drv->sectors = 0;
+	drv->cylinders = 0;
+	drv->raid_level = -1;	/* This can be used as a flag variable to
+				 * indicate that this element of the drive
+				 * array is free.
+				*/
+
+	if (clear_all){
 	/* check to see if it was the last disk */
 	if (drv == h->drv + h->highest_lun) {
 		/* if so, find the new hightest lun */
 		int i, newhighest =-1;
 		for(i=0; i<h->highest_lun; i++) {
 			/* if the disk has size > 0, it is available */
-			if (h->drv[i].nr_blocks)
+				if (h->drv[i].heads)
 				newhighest = i;
 		}
 		h->highest_lun = newhighest;
-				
 	}
-	--h->num_luns;
-	/* zero out the disk size info */ 
-	drv->nr_blocks = 0;
-	drv->block_size = 0;
-	drv->cylinders = 0;
+
 	drv->LunID = 0;
+	}
 	return(0);
 }
+
 static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff,
 	size_t size,
 	unsigned int use_unit_num, /* 0: address the controller,
@@ -1420,8 +1730,10 @@
 		}
 	}	
 	/* unlock the buffers from DMA */
+	buff_dma_handle.val32.lower = c->SG[0].Addr.lower;
+	buff_dma_handle.val32.upper = c->SG[0].Addr.upper;
 	pci_unmap_single( h->pdev, (dma_addr_t) buff_dma_handle.val,
-			size, PCI_DMA_BIDIRECTIONAL);
+			c->SG[0].Len, PCI_DMA_BIDIRECTIONAL);
 	cmd_free(h, c, 0);
         return(return_status);
 
@@ -1495,164 +1807,6 @@
 	return;
 }
 
-static int register_new_disk(ctlr_info_t *h)
-{
-        struct gendisk *disk;
-	int ctlr = h->ctlr;
-        int i;
-	int num_luns;
-	int logvol;
-	int new_lun_found = 0;
-	int new_lun_index = 0;
-	int free_index_found = 0;
-	int free_index = 0;
-	ReportLunData_struct *ld_buff = NULL;
-	ReadCapdata_struct *size_buff = NULL;
-	InquiryData_struct *inq_buff = NULL;
-	int return_code;
-	int listlength = 0;
-	__u32 lunid = 0;
-	unsigned int block_size;
-	unsigned int total_size;
-
-        if (!capable(CAP_SYS_RAWIO))
-                return -EPERM;
-	/* if we have no space in our disk array left to add anything */
-	if(  h->num_luns >= CISS_MAX_LUN)
-		return -EINVAL;
-	
-	ld_buff = kmalloc(sizeof(ReportLunData_struct), GFP_KERNEL);
-	if (ld_buff == NULL)
-		goto mem_msg;
-	memset(ld_buff, 0, sizeof(ReportLunData_struct));
-	size_buff = kmalloc(sizeof( ReadCapdata_struct), GFP_KERNEL);
-        if (size_buff == NULL)
-		goto mem_msg;
-	inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL);
-        if (inq_buff == NULL)
-		goto mem_msg;
-	
-	return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff, 
-			sizeof(ReportLunData_struct), 0, 0, 0, TYPE_CMD);
-
-	if( return_code == IO_OK)
-	{
-		
-		// printk("LUN Data\n--------------------------\n");
-
-		listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24;
-		listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16;
-		listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8;	
-		listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]);
-	} else /* reading number of logical volumes failed */
-	{
-		printk(KERN_WARNING "cciss: report logical volume"
-			" command failed\n");
-		listlength = 0;
-		goto free_err;
-	}
-	num_luns = listlength / 8; // 8 bytes pre entry
-	if (num_luns > CISS_MAX_LUN)
-	{
-		num_luns = CISS_MAX_LUN;
-	}
-#ifdef CCISS_DEBUG
-	printk(KERN_DEBUG "Length = %x %x %x %x = %d\n", ld_buff->LUNListLength[0],
-		ld_buff->LUNListLength[1], ld_buff->LUNListLength[2],
-		ld_buff->LUNListLength[3],  num_luns);
-#endif 
-	for(i=0; i<  num_luns; i++)
-	{
-		int j;
-		int lunID_found = 0;
-
-	  	lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) << 24;
-        	lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2])) << 16;
-        	lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1])) << 8;
-        	lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]);
-		
- 		/* check to see if this is a new lun */ 
-		for(j=0; j <= h->highest_lun; j++)
-		{
-#ifdef CCISS_DEBUG
-			printk("Checking %d %x against %x\n", j,h->drv[j].LunID,
-						lunid);
-#endif /* CCISS_DEBUG */
-			if (h->drv[j].LunID == lunid)
-			{
-				lunID_found = 1;
-				break;
-			}
-			
-		}
-		if( lunID_found == 1)
-			continue;
-		else
-		{	/* It is the new lun we have been looking for */
-#ifdef CCISS_DEBUG
-			printk("new lun found at %d\n", i);
-#endif /* CCISS_DEBUG */
-			new_lun_index = i;
-			new_lun_found = 1;
-			break;	
-		}
-	 }
-	 if (!new_lun_found)
-	 {
-		printk(KERN_WARNING "cciss:  New Logical Volume not found\n");
-		goto free_err;
-	 }
-	 /* Now find the free index 	*/
-	for(i=0; i <CISS_MAX_LUN; i++)
-	{
-#ifdef CCISS_DEBUG
-		printk("Checking Index %d\n", i);
-#endif /* CCISS_DEBUG */
-		if(h->drv[i].LunID == 0)
-		{
-#ifdef CCISS_DEBUG
-			printk("free index found at %d\n", i);
-#endif /* CCISS_DEBUG */
-			free_index_found = 1;
-			free_index = i;
-			break;
-		}
-	}
-	if (!free_index_found)
-	{
-		printk(KERN_WARNING "cciss: unable to find free slot for disk\n");
-		goto free_err;
-         }
-
-	logvol = free_index;
-	h->drv[logvol].LunID = lunid;
-		/* there could be gaps in lun numbers, track hightest */
-	if(h->highest_lun < lunid)
-		h->highest_lun = logvol;
-	cciss_read_capacity(ctlr, logvol, size_buff, 1,
-		&total_size, &block_size);
-	cciss_geometry_inquiry(ctlr, logvol, 1, total_size, block_size,
-			inq_buff, &h->drv[logvol]);
-	h->drv[logvol].usage_count = 0;
-	++h->num_luns;
-	/* setup partitions per disk */
-        disk = h->gendisk[logvol];
-	set_capacity(disk, h->drv[logvol].nr_blocks);
-	/* if it's the controller it's already added */
-	if(logvol)
-		add_disk(disk);
-freeret:
-	kfree(ld_buff);
-	kfree(size_buff);
-	kfree(inq_buff);
-	return (logvol);
-mem_msg:
-	printk(KERN_ERR "cciss: out of memory\n");
-free_err:
-	logvol = -1;
-	goto freeret;
-}
-
 static int cciss_revalidate(struct gendisk *disk)
 {
 	ctlr_info_t *h = get_host(disk);
@@ -1859,8 +2013,10 @@
 		
 cleanup1:	
 	/* unlock the data buffer from DMA */
+	buff_dma_handle.val32.lower = c->SG[0].Addr.lower;
+	buff_dma_handle.val32.upper = c->SG[0].Addr.upper;
 	pci_unmap_single(info_p->pdev, (dma_addr_t) buff_dma_handle.val,
-				size, PCI_DMA_BIDIRECTIONAL);
+				c->SG[0].Len, PCI_DMA_BIDIRECTIONAL);
 	cmd_free(info_p, c, 1);
 	return (status);
 } 
@@ -2111,7 +2267,11 @@
 	/* fill in the request */ 
 	drv = creq->rq_disk->private_data;
 	c->Header.ReplyQueue = 0;  // unused in simple mode
-	c->Header.Tag.lower = c->busaddr;  // use the physical address the cmd block for tag
+	/* got command from pool, so use the command block index instead */
+	/* for direct lookups. */
+	/* The first 2 bits are reserved for controller error reporting. */
+	c->Header.Tag.lower = (c->cmdindex << 3);
+	c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */
 	c->Header.LUN.LogDev.VolId= drv->LunID;
 	c->Header.LUN.LogDev.Mode = 1;
 	c->Request.CDBLen = 10; // 12 byte commands not in FW yet;
@@ -2186,7 +2346,7 @@
 	ctlr_info_t *h = dev_id;
 	CommandList_struct *c;
 	unsigned long flags;
-	__u32 a, a1;
+	__u32 a, a1, a2;
 	int j;
 	int start_queue = h->next_to_run;
 
@@ -2204,10 +2364,21 @@
 		while((a = h->access.command_completed(h)) != FIFO_EMPTY) 
 		{
 			a1 = a;
+			if ((a & 0x04)) {
+				a2 = (a >> 3);
+				if (a2 >= NR_CMDS) {
+					printk(KERN_WARNING "cciss: controller cciss%d failed, stopping.\n", h->ctlr);
+					fail_all_cmds(h->ctlr);
+					return IRQ_HANDLED;
+				}
+
+				c = h->cmd_pool + a2;
+				a = c->busaddr;
+
+			} else {
 			a &= ~3;
-			if ((c = h->cmpQ) == NULL)
-			{  
-				printk(KERN_WARNING "cciss: Completion of %08lx ignored\n", (unsigned long)a1);
+				if ((c = h->cmpQ) == NULL) {
+					printk(KERN_WARNING "cciss: Completion of %08x ignored\n", a1);
 				continue;	
 			} 
 			while(c->busaddr != a) {
@@ -2215,6 +2386,7 @@
 				if (c == h->cmpQ) 
 					break;
 			}
+			}
 			/*
 			 * If we've found the command, take it off the
 			 * completion Q and free it
@@ -2634,12 +2806,16 @@
 #endif /* CCISS_DEBUG */
 
 	hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns-1;
-	for(i=0; i<  hba[cntl_num]->num_luns; i++)
+//	for(i=0; i<  hba[cntl_num]->num_luns; i++)
+	for(i=0; i < CISS_MAX_LUN; i++)
 	{
-
-	  	lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) << 24;
-        	lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2])) << 16;
-        	lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1])) << 8;
+		if (i < hba[cntl_num]->num_luns){
+		  	lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3]))
+				 << 24;
+        		lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2]))
+				 << 16;
+        		lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1]))
+				 << 8;
         	lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]);
 		
 		hba[cntl_num]->drv[i].LunID = lunid;
@@ -2647,13 +2823,18 @@
 
 #ifdef CCISS_DEBUG
 	  	printk(KERN_DEBUG "LUN[%d]:  %x %x %x %x = %x\n", i, 
-		ld_buff->LUN[i][0], ld_buff->LUN[i][1],ld_buff->LUN[i][2], 
-		ld_buff->LUN[i][3], hba[cntl_num]->drv[i].LunID);
+			ld_buff->LUN[i][0], ld_buff->LUN[i][1],
+			ld_buff->LUN[i][2], ld_buff->LUN[i][3],
+			hba[cntl_num]->drv[i].LunID);
 #endif /* CCISS_DEBUG */
 		cciss_read_capacity(cntl_num, i, size_buff, 0,
 			&total_size, &block_size);
-		cciss_geometry_inquiry(cntl_num, i, 0, total_size, block_size,
-			inq_buff, &hba[cntl_num]->drv[i]);
+			cciss_geometry_inquiry(cntl_num, i, 0, total_size,
+				block_size, inq_buff, &hba[cntl_num]->drv[i]);
+		} else {
+			/* initialize raid_level to indicate a free space */
+			hba[cntl_num]->drv[i].raid_level = -1;
+		}
 	}
 	kfree(ld_buff);
 	kfree(size_buff);
@@ -2727,6 +2908,9 @@
 	i = alloc_cciss_hba();
 	if(i < 0)
 		return (-1);
+
+	hba[i]->busy_initializing = 1;
+
 	if (cciss_pci_init(hba[i], pdev) != 0)
 		goto clean1;
 
@@ -2849,6 +3033,7 @@
 		add_disk(disk);
 	}
 
+	hba[i]->busy_initializing = 0;
 	return(1);
 
 clean4:
@@ -2869,6 +3054,7 @@
 clean1:
 	release_io_mem(hba[i]);
 	free_hba(i);
+	hba[i]->busy_initializing = 0;
 	return(-1);
 }
 
@@ -2913,9 +3099,10 @@
 	/* remove it from the disk list */
 	for (j = 0; j < NWD; j++) {
 		struct gendisk *disk = hba[i]->gendisk[j];
-		if (disk->flags & GENHD_FL_UP)
-			blk_cleanup_queue(disk->queue);
+		if (disk->flags & GENHD_FL_UP) {
 			del_gendisk(disk);
+			blk_cleanup_queue(disk->queue);
+		}
 	}
 
 	pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct),
@@ -2964,5 +3151,43 @@
 	remove_proc_entry("cciss", proc_root_driver);
 }
 
+static void fail_all_cmds(unsigned long ctlr)
+{
+	/* If we get here, the board is apparently dead. */
+	ctlr_info_t *h = hba[ctlr];
+	CommandList_struct *c;
+	unsigned long flags;
+
+	printk(KERN_WARNING "cciss%d: controller not responding.\n", h->ctlr);
+	h->alive = 0;	/* the controller apparently died... */
+
+	spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
+
+	pci_disable_device(h->pdev); /* Make sure it is really dead. */
+
+	/* move everything off the request queue onto the completed queue */
+	while( (c = h->reqQ) != NULL ) {
+		removeQ(&(h->reqQ), c);
+		h->Qdepth--;
+		addQ (&(h->cmpQ), c);
+	}
+
+	/* Now, fail everything on the completed queue with a HW error */
+	while( (c = h->cmpQ) != NULL ) {
+		removeQ(&h->cmpQ, c);
+		c->err_info->CommandStatus = CMD_HARDWARE_ERR;
+		if (c->cmd_type == CMD_RWREQ) {
+			complete_command(h, c, 0);
+		} else if (c->cmd_type == CMD_IOCTL_PEND)
+			complete(c->waiting);
+#ifdef CONFIG_CISS_SCSI_TAPE
+			else if (c->cmd_type == CMD_SCSI)
+				complete_scsi_command(c, 0, 0);
+#endif
+	}
+	spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
+	return;
+}
+
 module_init(cciss_init);
 module_exit(cciss_cleanup);
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index 566587d..ef277ba 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -35,7 +35,13 @@
 	int 	heads;
 	int	sectors;
 	int 	cylinders;
-	int	raid_level;
+	int	raid_level; /* set to -1 to indicate that
+			     * the drive is not in use/configured
+			    */
+	int	busy_configuring; /*This is set when the drive is being removed
+				   *to prevent it from being opened or it's queue
+				   *from being started.
+				  */
 } drive_info_struct;
 
 struct ctlr_info 
@@ -83,6 +89,7 @@
 	int			nr_allocs;
 	int			nr_frees; 
 	int			busy_configuring;
+	int			busy_initializing;
 
 	/* This element holds the zero based queue number of the last
 	 * queue to be started.  It is used for fairness.
@@ -94,6 +101,7 @@
 #ifdef CONFIG_CISS_SCSI_TAPE
 	void *scsi_ctlr; /* ptr to structure containing scsi related stuff */
 #endif
+	unsigned char alive;
 };
 
 /*  Defining the diffent access_menthods */
diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h
index a88a888..53fea54 100644
--- a/drivers/block/cciss_cmd.h
+++ b/drivers/block/cciss_cmd.h
@@ -226,6 +226,10 @@
 #define CMD_MSG_DONE	0x04
 #define CMD_MSG_TIMEOUT 0x05
 
+/* This structure needs to be divisible by 8 for new
+ * indexing method.
+ */
+#define PADSIZE (sizeof(long) - 4)
 typedef struct _CommandList_struct {
   CommandListHeader_struct Header;
   RequestBlock_struct      Request;
@@ -236,14 +240,14 @@
   ErrorInfo_struct * 	   err_info; /* pointer to the allocated mem */ 
   int			   ctlr;
   int			   cmd_type; 
+  long			   cmdindex;
   struct _CommandList_struct *prev;
   struct _CommandList_struct *next;
   struct request *	   rq;
   struct completion *waiting;
   int	 retry_count;
-#ifdef CONFIG_CISS_SCSI_TAPE
   void * scsi_cmd;
-#endif
+  char   pad[PADSIZE];
 } CommandList_struct;
 
 //Configuration Table Structure
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index f16e3ca..e183a3e 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -93,6 +93,7 @@
 	CommandList_struct cmd;
 	ErrorInfo_struct Err;
 	__u32 busaddr;
+	__u32 pad;
 };
 
 #pragma pack()
@@ -877,7 +878,7 @@
 
 static int
 cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr, 
-		 InquiryData_struct *buf)
+		 unsigned char *buf, unsigned char bufsize)
 {
 	int rc;
 	CommandList_struct *cp;
@@ -900,11 +901,10 @@
 	cdb[1] = 0;
 	cdb[2] = 0;
 	cdb[3] = 0;
-	cdb[4] = sizeof(*buf) & 0xff;
+	cdb[4] = bufsize;
 	cdb[5] = 0;
 	rc = cciss_scsi_do_simple_cmd(c, cp, scsi3addr, cdb, 
-				6, (unsigned char *) buf, 
-				sizeof(*buf), XFER_READ);
+				6, buf, bufsize, XFER_READ);
 
 	if (rc != 0) return rc; /* something went wrong */
 
@@ -1000,9 +1000,10 @@
 	   that though.  
 
 	 */
-
+#define OBDR_TAPE_INQ_SIZE 49
+#define OBDR_TAPE_SIG "$DR-10"
 	ReportLunData_struct *ld_buff;
-	InquiryData_struct *inq_buff;
+	unsigned char *inq_buff;
 	unsigned char scsi3addr[8];
 	ctlr_info_t *c;
 	__u32 num_luns=0;
@@ -1020,7 +1021,7 @@
 		return;
 	}
 	memset(ld_buff, 0, reportlunsize);
-	inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL);
+	inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
         if (inq_buff == NULL) {
                 printk(KERN_ERR "cciss: out of memory\n");
                 kfree(ld_buff);
@@ -1051,19 +1052,36 @@
 
 		/* for each physical lun, do an inquiry */
 		if (ld_buff->LUN[i][3] & 0xC0) continue;
-		memset(inq_buff, 0, sizeof(InquiryData_struct));
+		memset(inq_buff, 0, OBDR_TAPE_INQ_SIZE);
 		memcpy(&scsi3addr[0], &ld_buff->LUN[i][0], 8);
 
-		if (cciss_scsi_do_inquiry(hba[cntl_num], 
-			scsi3addr, inq_buff) != 0)
-		{
+		if (cciss_scsi_do_inquiry(hba[cntl_num], scsi3addr, inq_buff,
+			(unsigned char) OBDR_TAPE_INQ_SIZE) != 0) {
 			/* Inquiry failed (msg printed already) */
 			devtype = 0; /* so we will skip this device. */
 		} else /* what kind of device is this? */
-			devtype = (inq_buff->data_byte[0] & 0x1f);
+			devtype = (inq_buff[0] & 0x1f);
 
 		switch (devtype)
 		{
+		  case 0x05: /* CD-ROM */ {
+
+			/* We don't *really* support actual CD-ROM devices,
+			 * just this "One Button Disaster Recovery" tape drive
+			 * which temporarily pretends to be a CD-ROM drive.
+			 * So we check that the device is really an OBDR tape
+			 * device by checking for "$DR-10" in bytes 43-48 of
+			 * the inquiry data.
+			 */
+				char obdr_sig[7];
+
+				strncpy(obdr_sig, &inq_buff[43], 6);
+				obdr_sig[6] = '\0';
+				if (strncmp(obdr_sig, OBDR_TAPE_SIG, 6) != 0)
+					/* Not OBDR device, ignore it. */
+					break;
+			}
+			/* fall through . . . */
 		  case 0x01: /* sequential access, (tape) */
 		  case 0x08: /* medium changer */
 			if (ncurrent >= CCISS_MAX_SCSI_DEVS_PER_HBA) {
@@ -1126,6 +1144,7 @@
 
 	int buflen, datalen;
 	ctlr_info_t *ci;
+	int i;
 	int cntl_num;
 
 
@@ -1136,8 +1155,28 @@
 	cntl_num = ci->ctlr;	/* Get our index into the hba[] array */
 
 	if (func == 0) {	/* User is reading from /proc/scsi/ciss*?/?*  */
-		buflen = sprintf(buffer, "hostnum=%d\n", sh->host_no); 	
+		buflen = sprintf(buffer, "cciss%d: SCSI host: %d\n",
+				cntl_num, sh->host_no);
 
+		/* this information is needed by apps to know which cciss
+		   device corresponds to which scsi host number without
+		   having to open a scsi target device node.  The device
+		   information is not a duplicate of /proc/scsi/scsi because
+		   the two may be out of sync due to scsi hotplug, rather
+		   this info is for an app to be able to use to know how to
+		   get them back in sync. */
+
+		for (i=0;i<ccissscsi[cntl_num].ndevices;i++) {
+			struct cciss_scsi_dev_t *sd = &ccissscsi[cntl_num].dev[i];
+			buflen += sprintf(&buffer[buflen], "c%db%dt%dl%d %02d "
+				"0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+				sh->host_no, sd->bus, sd->target, sd->lun,
+				sd->devtype,
+				sd->scsi3addr[0], sd->scsi3addr[1],
+				sd->scsi3addr[2], sd->scsi3addr[3],
+				sd->scsi3addr[4], sd->scsi3addr[5],
+				sd->scsi3addr[6], sd->scsi3addr[7]);
+		}
 		datalen = buflen - offset;
 		if (datalen < 0) { 	/* they're reading past EOF. */
 			datalen = 0;
@@ -1399,7 +1438,7 @@
 
 	CPQ_TAPE_LOCK(ctlr, flags);
 	size = sprintf(buffer + *len, 
-		"       Sequential access devices: %d\n\n",
+		"Sequential access devices: %d\n\n",
 			ccissscsi[ctlr].ndevices);
 	CPQ_TAPE_UNLOCK(ctlr, flags);
 	*pos += size; *len += size;
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 7b83834..7e22a58 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -5,29 +5,41 @@
  * May be copied or modified under the terms of the GNU General Public
  * License.  See linux/COPYING for more information.
  *
- * Packet writing layer for ATAPI and SCSI CD-R, CD-RW, DVD-R, and
- * DVD-RW devices (aka an exercise in block layer masturbation)
- *
- *
- * TODO: (circa order of when I will fix it)
- * - Only able to write on CD-RW media right now.
- * - check host application code on media and set it in write page
- * - interface for UDF <-> packet to negotiate a new location when a write
- *   fails.
- * - handle OPC, especially for -RW media
+ * Packet writing layer for ATAPI and SCSI CD-RW, DVD+RW, DVD-RW and
+ * DVD-RAM devices.
  *
  * Theory of operation:
  *
- * We use a custom make_request_fn function that forwards reads directly to
- * the underlying CD device. Write requests are either attached directly to
- * a live packet_data object, or simply stored sequentially in a list for
- * later processing by the kcdrwd kernel thread. This driver doesn't use
- * any elevator functionally as defined by the elevator_s struct, but the
- * underlying CD device uses a standard elevator.
+ * At the lowest level, there is the standard driver for the CD/DVD device,
+ * typically ide-cd.c or sr.c. This driver can handle read and write requests,
+ * but it doesn't know anything about the special restrictions that apply to
+ * packet writing. One restriction is that write requests must be aligned to
+ * packet boundaries on the physical media, and the size of a write request
+ * must be equal to the packet size. Another restriction is that a
+ * GPCMD_FLUSH_CACHE command has to be issued to the drive before a read
+ * command, if the previous command was a write.
  *
- * This strategy makes it possible to do very late merging of IO requests.
- * A new bio sent to pkt_make_request can be merged with a live packet_data
- * object even if the object is in the data gathering state.
+ * The purpose of the packet writing driver is to hide these restrictions from
+ * higher layers, such as file systems, and present a block device that can be
+ * randomly read and written using 2kB-sized blocks.
+ *
+ * The lowest layer in the packet writing driver is the packet I/O scheduler.
+ * Its data is defined by the struct packet_iosched and includes two bio
+ * queues with pending read and write requests. These queues are processed
+ * by the pkt_iosched_process_queue() function. The write requests in this
+ * queue are already properly aligned and sized. This layer is responsible for
+ * issuing the flush cache commands and scheduling the I/O in a good order.
+ *
+ * The next layer transforms unaligned write requests to aligned writes. This
+ * transformation requires reading missing pieces of data from the underlying
+ * block device, assembling the pieces to full packets and queuing them to the
+ * packet I/O scheduler.
+ *
+ * At the top layer there is a custom make_request_fn function that forwards
+ * read requests directly to the iosched queue and puts write requests in the
+ * unaligned write queue. A kernel thread performs the necessary read
+ * gathering to convert the unaligned writes to aligned writes and then feeds
+ * them to the packet I/O scheduler.
  *
  *************************************************************************/
 
@@ -100,10 +112,9 @@
 		goto no_bio;
 	bio_init(bio);
 
-	bvl = kmalloc(nr_iovecs * sizeof(struct bio_vec), GFP_KERNEL);
+	bvl = kcalloc(nr_iovecs, sizeof(struct bio_vec), GFP_KERNEL);
 	if (!bvl)
 		goto no_bvl;
-	memset(bvl, 0, nr_iovecs * sizeof(struct bio_vec));
 
 	bio->bi_max_vecs = nr_iovecs;
 	bio->bi_io_vec = bvl;
@@ -125,10 +136,9 @@
 	int i;
 	struct packet_data *pkt;
 
-	pkt = kmalloc(sizeof(struct packet_data), GFP_KERNEL);
+	pkt = kzalloc(sizeof(struct packet_data), GFP_KERNEL);
 	if (!pkt)
 		goto no_pkt;
-	memset(pkt, 0, sizeof(struct packet_data));
 
 	pkt->w_bio = pkt_bio_alloc(PACKET_MAX_SIZE);
 	if (!pkt->w_bio)
@@ -659,7 +669,6 @@
 		}
 		offs += CD_FRAMESIZE;
 		if (offs >= PAGE_SIZE) {
-			BUG_ON(offs > PAGE_SIZE);
 			offs = 0;
 			p++;
 		}
@@ -724,12 +733,6 @@
 	atomic_set(&pkt->io_wait, 0);
 	atomic_set(&pkt->io_errors, 0);
 
-	if (pkt->cache_valid) {
-		VPRINTK("pkt_gather_data: zone %llx cached\n",
-			(unsigned long long)pkt->sector);
-		goto out_account;
-	}
-
 	/*
 	 * Figure out which frames we need to read before we can write.
 	 */
@@ -738,6 +741,7 @@
 	for (bio = pkt->orig_bios; bio; bio = bio->bi_next) {
 		int first_frame = (bio->bi_sector - pkt->sector) / (CD_FRAMESIZE >> 9);
 		int num_frames = bio->bi_size / CD_FRAMESIZE;
+		pd->stats.secs_w += num_frames * (CD_FRAMESIZE >> 9);
 		BUG_ON(first_frame < 0);
 		BUG_ON(first_frame + num_frames > pkt->frames);
 		for (f = first_frame; f < first_frame + num_frames; f++)
@@ -745,6 +749,12 @@
 	}
 	spin_unlock(&pkt->lock);
 
+	if (pkt->cache_valid) {
+		VPRINTK("pkt_gather_data: zone %llx cached\n",
+			(unsigned long long)pkt->sector);
+		goto out_account;
+	}
+
 	/*
 	 * Schedule reads for missing parts of the packet.
 	 */
@@ -778,7 +788,6 @@
 		frames_read, (unsigned long long)pkt->sector);
 	pd->stats.pkt_started++;
 	pd->stats.secs_rg += frames_read * (CD_FRAMESIZE >> 9);
-	pd->stats.secs_w += pd->settings.size;
 }
 
 /*
@@ -794,10 +803,11 @@
 			list_del_init(&pkt->list);
 			if (pkt->sector != zone)
 				pkt->cache_valid = 0;
-			break;
+			return pkt;
 		}
 	}
-	return pkt;
+	BUG();
+	return NULL;
 }
 
 static void pkt_put_packet_data(struct pktcdvd_device *pd, struct packet_data *pkt)
@@ -941,12 +951,10 @@
 	}
 
 	pkt = pkt_get_packet_data(pd, zone);
-	BUG_ON(!pkt);
 
 	pd->current_sector = zone + pd->settings.size;
 	pkt->sector = zone;
 	pkt->frames = pd->settings.size >> 2;
-	BUG_ON(pkt->frames > PACKET_MAX_SIZE);
 	pkt->write_size = 0;
 
 	/*
@@ -1636,6 +1644,10 @@
 		printk("pktcdvd: detected zero packet size!\n");
 		pd->settings.size = 128;
 	}
+	if (pd->settings.size > PACKET_MAX_SECTORS) {
+		printk("pktcdvd: packet size is too big\n");
+		return -ENXIO;
+	}
 	pd->settings.fp = ti.fp;
 	pd->offset = (be32_to_cpu(ti.track_start) << 2) & (pd->settings.size - 1);
 
@@ -2198,7 +2210,6 @@
 	 * No matching packet found. Store the bio in the work queue.
 	 */
 	node = mempool_alloc(pd->rb_pool, GFP_NOIO);
-	BUG_ON(!node);
 	node->bio = bio;
 	spin_lock(&pd->lock);
 	BUG_ON(pd->bio_queue_size < 0);
@@ -2406,7 +2417,6 @@
 	struct pktcdvd_device *pd = inode->i_bdev->bd_disk->private_data;
 
 	VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, imajor(inode), iminor(inode));
-	BUG_ON(!pd);
 
 	switch (cmd) {
 	/*
@@ -2477,10 +2487,9 @@
 		return -EBUSY;
 	}
 
-	pd = kmalloc(sizeof(struct pktcdvd_device), GFP_KERNEL);
+	pd = kzalloc(sizeof(struct pktcdvd_device), GFP_KERNEL);
 	if (!pd)
 		return ret;
-	memset(pd, 0, sizeof(struct pktcdvd_device));
 
 	pd->rb_pool = mempool_create(PKT_RB_POOL_SIZE, pkt_rb_alloc, pkt_rb_free, NULL);
 	if (!pd->rb_pool)
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index 67d96b5..57c48bb 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -65,13 +65,15 @@
 #endif
 
 static int ignore = 0;
+static int ignore_csr = 0;
+static int ignore_sniffer = 0;
 static int reset = 0;
 
 #ifdef CONFIG_BT_HCIUSB_SCO
 static int isoc = 2;
 #endif
 
-#define VERSION "2.8"
+#define VERSION "2.9"
 
 static struct usb_driver hci_usb_driver; 
 
@@ -98,6 +100,9 @@
 MODULE_DEVICE_TABLE (usb, bluetooth_ids);
 
 static struct usb_device_id blacklist_ids[] = {
+	/* CSR BlueCore devices */
+	{ USB_DEVICE(0x0a12, 0x0001), .driver_info = HCI_CSR },
+
 	/* Broadcom BCM2033 without firmware */
 	{ USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE },
 
@@ -836,6 +841,12 @@
 	if (ignore || id->driver_info & HCI_IGNORE)
 		return -ENODEV;
 
+	if (ignore_csr && id->driver_info & HCI_CSR)
+		return -ENODEV;
+
+	if (ignore_sniffer && id->driver_info & HCI_SNIFFER)
+		return -ENODEV;
+
 	if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
 		return -ENODEV;
 
@@ -1061,6 +1072,12 @@
 module_param(ignore, bool, 0644);
 MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
 
+module_param(ignore_csr, bool, 0644);
+MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
+
+module_param(ignore_sniffer, bool, 0644);
+MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002");
+
 module_param(reset, bool, 0644);
 MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
 
diff --git a/drivers/bluetooth/hci_usb.h b/drivers/bluetooth/hci_usb.h
index 29936b4..37100a6 100644
--- a/drivers/bluetooth/hci_usb.h
+++ b/drivers/bluetooth/hci_usb.h
@@ -31,9 +31,10 @@
 #define HCI_IGNORE		0x01
 #define HCI_RESET		0x02
 #define HCI_DIGIANSWER		0x04
-#define HCI_SNIFFER		0x08
-#define HCI_BROKEN_ISOC		0x10
+#define HCI_CSR			0x08
+#define HCI_SNIFFER		0x10
 #define HCI_BCM92035		0x20
+#define HCI_BROKEN_ISOC		0x40
 
 #define HCI_MAX_IFACE_NUM	3
 
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 2a36561..a124f8c 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -2053,10 +2053,6 @@
 	state->icount.rx = state->icount.tx = 0;
 	state->icount.frame = state->icount.parity = 0;
 	state->icount.overrun = state->icount.brk = 0;
-	/*
-	if(state->port && check_region(state->port,REGION_LENGTH(state)))
-	  continue;
-	*/
 
 	printk(KERN_INFO "ttyS%d is the amiga builtin serial port\n",
 		       state->line);
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
index fa789ea..344001b 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -84,6 +84,17 @@
 
 	  Not sure? It's safe to say N.
 
+config IXP2000_WATCHDOG
+	tristate "IXP2000 Watchdog"
+	depends on WATCHDOG && ARCH_IXP2000
+	help
+	  Say Y here if to include support for the watchdog timer
+	  in the Intel IXP2000(2400, 2800, 2850) network processors.
+	  This driver can be built as a module by choosing M. The module
+	  will be called ixp2000_wdt.
+
+	  Say N if you are unsure.
+
 config IXP4XX_WATCHDOG
 	tristate "IXP4xx Watchdog"
 	depends on WATCHDOG && ARCH_IXP4XX
@@ -100,17 +111,6 @@
 
 	  Say N if you are unsure.
 
-config IXP2000_WATCHDOG
-	tristate "IXP2000 Watchdog"
-	depends on WATCHDOG && ARCH_IXP2000
-	help
-	  Say Y here if to include support for the watchdog timer
-	  in the Intel IXP2000(2400, 2800, 2850) network processors.
-	  This driver can be built as a module by choosing M. The module
-	  will be called ixp2000_wdt.
-
-	  Say N if you are unsure.
-
 config S3C2410_WATCHDOG
 	tristate "S3C2410 Watchdog"
 	depends on WATCHDOG && ARCH_S3C2410
@@ -233,6 +233,16 @@
 
 	  Most people will say N.
 
+config IBMASR
+        tristate "IBM Automatic Server Restart"
+        depends on WATCHDOG && X86
+        help
+	  This is the driver for the IBM Automatic Server Restart watchdog
+	  timer builtin into some eServer xSeries machines.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ibmasr.
+
 config WAFER_WDT
 	tristate "ICP Wafer 5823 Single Board Computer Watchdog"
 	depends on WATCHDOG && X86
@@ -243,6 +253,16 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called wafer5823wdt.
 
+config I6300ESB_WDT
+	tristate "Intel 6300ESB Timer/Watchdog"
+	depends on WATCHDOG && X86 && PCI
+	---help---
+	  Hardware driver for the watchdog timer built into the Intel
+	  6300ESB controller hub.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called i6300esb.
+
 config I8XX_TCO
 	tristate "Intel i8xx TCO Timer/Watchdog"
 	depends on WATCHDOG && (X86 || IA64) && PCI
@@ -298,6 +318,19 @@
 	  You can compile this driver directly into the kernel, or use
 	  it as a module.  The module will be called sbc60xxwdt.
 
+config SBC8360_WDT
+	tristate "SBC8360 Watchdog Timer"
+	depends on WATCHDOG && X86
+	---help---
+
+	  This is the driver for the hardware watchdog on the SBC8360 Single
+	  Board Computer produced by Axiomtek Co., Ltd. (www.axiomtek.com).
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called sbc8360.ko.
+
+	  Most people will say N.
+
 config CPU5_WDT
 	tristate "SMA CPU5 Watchdog"
 	depends on WATCHDOG && X86
@@ -336,6 +369,19 @@
 
 	  Most people will say N.
 
+config W83977F_WDT
+	tristate "W83977F (PCM-5335) Watchdog Timer"
+	depends on WATCHDOG && X86
+	---help---
+	  This is the driver for the hardware watchdog on the W83977F I/O chip
+	  as used in AAEON's PCM-5335 SBC (and likely others).  This
+	  watchdog simply watches your kernel to make sure it doesn't freeze,
+	  and if it does, it reboots your computer after a certain amount of
+	  time.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called w83977f_wdt.
+
 config MACHZ_WDT
 	tristate "ZF MachZ Watchdog"
 	depends on WATCHDOG && X86
@@ -355,6 +401,10 @@
 	tristate "MPC8xx Watchdog Timer"
 	depends on WATCHDOG && 8xx
 
+config MV64X60_WDT
+	tristate "MV64X60 (Marvell Discovery) Watchdog Timer"
+	depends on WATCHDOG && MV64X60
+
 config BOOKE_WDT
 	tristate "PowerPC Book-E Watchdog Timer"
 	depends on WATCHDOG && (BOOKE || 4xx)
@@ -362,6 +412,17 @@
 	  Please see Documentation/watchdog/watchdog-api.txt for
 	  more information.
 
+# PPC64 Architecture
+
+config WATCHDOG_RTAS
+	tristate "RTAS watchdog"
+	depends on WATCHDOG && PPC_RTAS
+	help
+	  This driver adds watchdog support for the RTAS watchdog.
+
+          To compile this driver as a module, choose M here. The module
+	  will be called wdrtas.
+
 # MIPS Architecture
 
 config INDYDOG
@@ -430,16 +491,6 @@
 	  machines.  The watchdog timeout period is normally one minute but
 	  can be changed with a boot-time parameter.
 
-# ppc64 RTAS watchdog
-config WATCHDOG_RTAS
-	tristate "RTAS watchdog"
-	depends on WATCHDOG && PPC_RTAS
-	help
-	  This driver adds watchdog support for the RTAS watchdog.
-
-          To compile this driver as a module, choose M here. The module
-	  will be called wdrtas.
-
 #
 # ISA-based Watchdog Cards
 #
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
index bc6f5fe..cfd0a39 100644
--- a/drivers/char/watchdog/Makefile
+++ b/drivers/char/watchdog/Makefile
@@ -39,22 +39,27 @@
 obj-$(CONFIG_SC520_WDT) += sc520_wdt.o
 obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o
 obj-$(CONFIG_IB700_WDT) += ib700wdt.o
+obj-$(CONFIG_IBMASR) += ibmasr.o
 obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
+obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o
 obj-$(CONFIG_I8XX_TCO) += i8xx_tco.o
 obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
 obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
 obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
+obj-$(CONFIG_SBC8360_WDT) += sbc8360.o
 obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o
 obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o
 obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o
+obj-$(CONFIG_W83977F_WDT) += w83977f_wdt.o
 obj-$(CONFIG_MACHZ_WDT) += machzwd.o
 
 # PowerPC Architecture
 obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
+obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o
+obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o
 
 # PPC64 Architecture
 obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o
-obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o
 
 # MIPS Architecture
 obj-$(CONFIG_INDYDOG) += indydog.o
diff --git a/drivers/char/watchdog/i6300esb.c b/drivers/char/watchdog/i6300esb.c
new file mode 100644
index 0000000..93785f1
--- /dev/null
+++ b/drivers/char/watchdog/i6300esb.c
@@ -0,0 +1,527 @@
+/*
+ *	i6300esb:	Watchdog timer driver for Intel 6300ESB chipset
+ *
+ *	(c) Copyright 2004 Google Inc.
+ *	(c) Copyright 2005 David Härdeman <david@2gen.com>
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *
+ *      based on i810-tco.c which is in turn based on softdog.c
+ *
+ * 	The timer is implemented in the following I/O controller hubs:
+ * 	(See the intel documentation on http://developer.intel.com.)
+ * 	6300ESB chip : document number 300641-003
+ *
+ *  2004YYZZ Ross Biro
+ *	Initial version 0.01
+ *  2004YYZZ Ross Biro
+ *  	Version 0.02
+ *  20050210 David Härdeman <david@2gen.com>
+ *      Ported driver to kernel 2.6
+ */
+
+/*
+ *      Includes, defines, variables, module parameters, ...
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+/* Module and version information */
+#define ESB_VERSION "0.03"
+#define ESB_MODULE_NAME "i6300ESB timer"
+#define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION
+#define PFX ESB_MODULE_NAME ": "
+
+/* PCI configuration registers */
+#define ESB_CONFIG_REG  0x60            /* Config register                   */
+#define ESB_LOCK_REG    0x68            /* WDT lock register                 */
+
+/* Memory mapped registers */
+#define ESB_TIMER1_REG  BASEADDR + 0x00 /* Timer1 value after each reset     */
+#define ESB_TIMER2_REG  BASEADDR + 0x04 /* Timer2 value after each reset     */
+#define ESB_GINTSR_REG  BASEADDR + 0x08 /* General Interrupt Status Register */
+#define ESB_RELOAD_REG  BASEADDR + 0x0c /* Reload register                   */
+
+/* Lock register bits */
+#define ESB_WDT_FUNC    ( 0x01 << 2 )   /* Watchdog functionality            */
+#define ESB_WDT_ENABLE  ( 0x01 << 1 )   /* Enable WDT                        */
+#define ESB_WDT_LOCK    ( 0x01 << 0 )   /* Lock (nowayout)                   */
+
+/* Config register bits */
+#define ESB_WDT_REBOOT  ( 0x01 << 5 )   /* Enable reboot on timeout          */
+#define ESB_WDT_FREQ    ( 0x01 << 2 )   /* Decrement frequency               */
+#define ESB_WDT_INTTYPE ( 0x11 << 0 )   /* Interrupt type on timer1 timeout  */
+
+/* Reload register bits */
+#define ESB_WDT_RELOAD ( 0x01 << 8 )    /* prevent timeout                   */
+
+/* Magic constants */
+#define ESB_UNLOCK1     0x80            /* Step 1 to unlock reset registers  */
+#define ESB_UNLOCK2     0x86            /* Step 2 to unlock reset registers  */
+
+/* internal variables */
+static void __iomem *BASEADDR;
+static spinlock_t esb_lock; /* Guards the hardware */
+static unsigned long timer_alive;
+static struct pci_dev *esb_pci;
+static unsigned short triggered; /* The status of the watchdog upon boot */
+static char esb_expect_close;
+
+/* module parameters */
+#define WATCHDOG_HEARTBEAT 30   /* 30 sec default heartbeat (1<heartbeat<2*1023) */
+static int heartbeat = WATCHDOG_HEARTBEAT;  /* in seconds */
+module_param(heartbeat, int, 0);
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (1<heartbeat<2046, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+
+/*
+ * Some i6300ESB specific functions
+ */
+
+/*
+ * Prepare for reloading the timer by unlocking the proper registers.
+ * This is performed by first writing 0x80 followed by 0x86 to the
+ * reload register. After this the appropriate registers can be written
+ * to once before they need to be unlocked again.
+ */
+static inline void esb_unlock_registers(void) {
+        writeb(ESB_UNLOCK1, ESB_RELOAD_REG);
+        writeb(ESB_UNLOCK2, ESB_RELOAD_REG);
+}
+
+static void esb_timer_start(void)
+{
+	u8 val;
+
+	/* Enable or Enable + Lock? */
+	val = 0x02 | (nowayout ? 0x01 : 0x00);
+
+        pci_write_config_byte(esb_pci, ESB_LOCK_REG, val);
+}
+
+static int esb_timer_stop(void)
+{
+	u8 val;
+
+	spin_lock(&esb_lock);
+	/* First, reset timers as suggested by the docs */
+	esb_unlock_registers();
+	writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
+	/* Then disable the WDT */
+	pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x0);
+	pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val);
+	spin_unlock(&esb_lock);
+
+	/* Returns 0 if the timer was disabled, non-zero otherwise */
+	return (val & 0x01);
+}
+
+static void esb_timer_keepalive(void)
+{
+	spin_lock(&esb_lock);
+	esb_unlock_registers();
+	writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
+        /* FIXME: Do we need to flush anything here? */
+	spin_unlock(&esb_lock);
+}
+
+static int esb_timer_set_heartbeat(int time)
+{
+	u32 val;
+
+	if (time < 0x1 || time > (2 * 0x03ff))
+		return -EINVAL;
+
+	spin_lock(&esb_lock);
+
+	/* We shift by 9, so if we are passed a value of 1 sec,
+	 * val will be 1 << 9 = 512, then write that to two
+	 * timers => 2 * 512 = 1024 (which is decremented at 1KHz)
+	 */
+	val = time << 9;
+
+	/* Write timer 1 */
+	esb_unlock_registers();
+	writel(val, ESB_TIMER1_REG);
+
+	/* Write timer 2 */
+	esb_unlock_registers();
+        writel(val, ESB_TIMER2_REG);
+
+        /* Reload */
+	esb_unlock_registers();
+	writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
+
+	/* FIXME: Do we need to flush everything out? */
+
+	/* Done */
+	heartbeat = time;
+	spin_unlock(&esb_lock);
+	return 0;
+}
+
+static int esb_timer_read (void)
+{
+       	u32 count;
+
+	/* This isn't documented, and doesn't take into
+         * acount which stage is running, but it looks
+         * like a 20 bit count down, so we might as well report it.
+         */
+        pci_read_config_dword(esb_pci, 0x64, &count);
+        return (int)count;
+}
+
+/*
+ * 	/dev/watchdog handling
+ */
+
+static int esb_open (struct inode *inode, struct file *file)
+{
+        /* /dev/watchdog can only be opened once */
+        if (test_and_set_bit(0, &timer_alive))
+                return -EBUSY;
+
+        /* Reload and activate timer */
+        esb_timer_keepalive ();
+        esb_timer_start ();
+
+	return nonseekable_open(inode, file);
+}
+
+static int esb_release (struct inode *inode, struct file *file)
+{
+        /* Shut off the timer. */
+        if (esb_expect_close == 42) {
+                esb_timer_stop ();
+        } else {
+                printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
+                esb_timer_keepalive ();
+        }
+        clear_bit(0, &timer_alive);
+        esb_expect_close = 0;
+        return 0;
+}
+
+static ssize_t esb_write (struct file *file, const char __user *data,
+			  size_t len, loff_t * ppos)
+{
+	/* See if we got the magic character 'V' and reload the timer */
+        if (len) {
+		if (!nowayout) {
+			size_t i;
+
+			/* note: just in case someone wrote the magic character
+			 * five months ago... */
+			esb_expect_close = 0;
+
+			/* scan to see whether or not we got the magic character */
+			for (i = 0; i != len; i++) {
+				char c;
+				if(get_user(c, data+i))
+					return -EFAULT;
+				if (c == 'V')
+					esb_expect_close = 42;
+			}
+		}
+
+		/* someone wrote to us, we should reload the timer */
+		esb_timer_keepalive ();
+	}
+	return len;
+}
+
+static int esb_ioctl (struct inode *inode, struct file *file,
+		      unsigned int cmd, unsigned long arg)
+{
+	int new_options, retval = -EINVAL;
+	int new_heartbeat;
+	void __user *argp = (void __user *)arg;
+	int __user *p = argp;
+	static struct watchdog_info ident = {
+		.options =              WDIOF_SETTIMEOUT |
+					WDIOF_KEEPALIVEPING |
+					WDIOF_MAGICCLOSE,
+		.firmware_version =     0,
+		.identity =             ESB_MODULE_NAME,
+	};
+
+	switch (cmd) {
+		case WDIOC_GETSUPPORT:
+			return copy_to_user(argp, &ident,
+					    sizeof (ident)) ? -EFAULT : 0;
+
+		case WDIOC_GETSTATUS:
+			return put_user (esb_timer_read(), p);
+
+		case WDIOC_GETBOOTSTATUS:
+			return put_user (triggered, p);
+
+                case WDIOC_KEEPALIVE:
+                        esb_timer_keepalive ();
+                        return 0;
+
+                case WDIOC_SETOPTIONS:
+                {
+                        if (get_user (new_options, p))
+                                return -EFAULT;
+
+                        if (new_options & WDIOS_DISABLECARD) {
+                                esb_timer_stop ();
+                                retval = 0;
+                        }
+
+                        if (new_options & WDIOS_ENABLECARD) {
+                                esb_timer_keepalive ();
+                                esb_timer_start ();
+                                retval = 0;
+                        }
+
+                        return retval;
+                }
+
+                case WDIOC_SETTIMEOUT:
+                {
+                        if (get_user(new_heartbeat, p))
+                                return -EFAULT;
+
+                        if (esb_timer_set_heartbeat(new_heartbeat))
+                            return -EINVAL;
+
+                        esb_timer_keepalive ();
+                        /* Fall */
+                }
+
+                case WDIOC_GETTIMEOUT:
+                        return put_user(heartbeat, p);
+
+                default:
+                        return -ENOIOCTLCMD;
+        }
+}
+
+/*
+ *      Notify system
+ */
+
+static int esb_notify_sys (struct notifier_block *this, unsigned long code, void *unused)
+{
+        if (code==SYS_DOWN || code==SYS_HALT) {
+                /* Turn the WDT off */
+                esb_timer_stop ();
+        }
+
+        return NOTIFY_DONE;
+}
+
+/*
+ *      Kernel Interfaces
+ */
+
+static struct file_operations esb_fops = {
+        .owner =        THIS_MODULE,
+        .llseek =       no_llseek,
+        .write =        esb_write,
+        .ioctl =        esb_ioctl,
+        .open =         esb_open,
+        .release =      esb_release,
+};
+
+static struct miscdevice esb_miscdev = {
+        .minor =        WATCHDOG_MINOR,
+        .name =         "watchdog",
+        .fops =         &esb_fops,
+};
+
+static struct notifier_block esb_notifier = {
+        .notifier_call =        esb_notify_sys,
+};
+
+/*
+ * Data for PCI driver interface
+ *
+ * This data only exists for exporting the supported
+ * PCI ids via MODULE_DEVICE_TABLE.  We do not actually
+ * register a pci_driver, because someone else might one day
+ * want to register another driver on the same PCI id.
+ */
+static struct pci_device_id esb_pci_tbl[] = {
+        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), },
+        { 0, },                 /* End of list */
+};
+MODULE_DEVICE_TABLE (pci, esb_pci_tbl);
+
+/*
+ *      Init & exit routines
+ */
+
+static unsigned char __init esb_getdevice (void)
+{
+	u8 val1;
+	unsigned short val2;
+
+        struct pci_dev *dev = NULL;
+        /*
+         *      Find the PCI device
+         */
+
+        for_each_pci_dev(dev) {
+                if (pci_match_id(esb_pci_tbl, dev)) {
+                        esb_pci = dev;
+                        break;
+                }
+	}
+
+        if (esb_pci) {
+        	if (pci_enable_device(esb_pci)) {
+			printk (KERN_ERR PFX "failed to enable device\n");
+			goto err_devput;
+		}
+
+		if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) {
+			printk (KERN_ERR PFX "failed to request region\n");
+			goto err_disable;
+		}
+
+		BASEADDR = ioremap(pci_resource_start(esb_pci, 0),
+				   pci_resource_len(esb_pci, 0));
+		if (BASEADDR == NULL) {
+                	/* Something's wrong here, BASEADDR has to be set */
+			printk (KERN_ERR PFX "failed to get BASEADDR\n");
+                        goto err_release;
+                }
+
+		/*
+		 * The watchdog has two timers, it can be setup so that the
+		 * expiry of timer1 results in an interrupt and the expiry of
+		 * timer2 results in a reboot. We set it to not generate
+		 * any interrupts as there is not much we can do with it
+		 * right now.
+		 *
+		 * We also enable reboots and set the timer frequency to
+		 * the PCI clock divided by 2^15 (approx 1KHz).
+		 */
+		pci_write_config_word(esb_pci, ESB_CONFIG_REG, 0x0003);
+
+		/* Check that the WDT isn't already locked */
+		pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1);
+		if (val1 & ESB_WDT_LOCK)
+			printk (KERN_WARNING PFX "nowayout already set\n");
+
+		/* Set the timer to watchdog mode and disable it for now */
+		pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00);
+
+		/* Check if the watchdog was previously triggered */
+		esb_unlock_registers();
+		val2 = readw(ESB_RELOAD_REG);
+		triggered = (val2 & (0x01 << 9) >> 9);
+
+		/* Reset trigger flag and timers */
+		esb_unlock_registers();
+		writew((0x11 << 8), ESB_RELOAD_REG);
+
+		/* Done */
+		return 1;
+
+err_release:
+		pci_release_region(esb_pci, 0);
+err_disable:
+		pci_disable_device(esb_pci);
+err_devput:
+		pci_dev_put(esb_pci);
+	}
+	return 0;
+}
+
+static int __init watchdog_init (void)
+{
+        int ret;
+
+        spin_lock_init(&esb_lock);
+
+        /* Check whether or not the hardware watchdog is there */
+        if (!esb_getdevice () || esb_pci == NULL)
+                return -ENODEV;
+
+        /* Check that the heartbeat value is within it's range ; if not reset to the default */
+        if (esb_timer_set_heartbeat (heartbeat)) {
+                esb_timer_set_heartbeat (WATCHDOG_HEARTBEAT);
+                printk(KERN_INFO PFX "heartbeat value must be 1<heartbeat<2046, using %d\n",
+		       heartbeat);
+        }
+
+        ret = register_reboot_notifier(&esb_notifier);
+        if (ret != 0) {
+                printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
+                        ret);
+                goto err_unmap;
+        }
+
+        ret = misc_register(&esb_miscdev);
+        if (ret != 0) {
+                printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
+                        WATCHDOG_MINOR, ret);
+                goto err_notifier;
+        }
+
+        esb_timer_stop ();
+
+        printk (KERN_INFO PFX "initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
+                BASEADDR, heartbeat, nowayout);
+
+        return 0;
+
+err_notifier:
+        unregister_reboot_notifier(&esb_notifier);
+err_unmap:
+	iounmap(BASEADDR);
+/* err_release: */
+	pci_release_region(esb_pci, 0);
+/* err_disable: */
+	pci_disable_device(esb_pci);
+/* err_devput: */
+	pci_dev_put(esb_pci);
+        return ret;
+}
+
+static void __exit watchdog_cleanup (void)
+{
+	/* Stop the timer before we leave */
+	if (!nowayout)
+		esb_timer_stop ();
+
+	/* Deregister */
+	misc_deregister(&esb_miscdev);
+        unregister_reboot_notifier(&esb_notifier);
+	iounmap(BASEADDR);
+	pci_release_region(esb_pci, 0);
+	pci_disable_device(esb_pci);
+	pci_dev_put(esb_pci);
+}
+
+module_init(watchdog_init);
+module_exit(watchdog_cleanup);
+
+MODULE_AUTHOR("Ross Biro and David Härdeman");
+MODULE_DESCRIPTION("Watchdog driver for Intel 6300ESB chipsets");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/ibmasr.c b/drivers/char/watchdog/ibmasr.c
new file mode 100644
index 0000000..294c474
--- /dev/null
+++ b/drivers/char/watchdog/ibmasr.c
@@ -0,0 +1,405 @@
+/*
+ * IBM Automatic Server Restart driver.
+ *
+ * Copyright (c) 2005 Andrey Panin <pazke@donpac.ru>
+ *
+ * Based on driver written by Pete Reynolds.
+ * Copyright (c) IBM Corporation, 1998-2004.
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU Public License, incorporated herein by reference.
+ */
+
+#include <linux/config.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/timer.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/dmi.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+
+enum {
+	ASMTYPE_UNKNOWN,
+	ASMTYPE_TOPAZ,
+	ASMTYPE_JASPER,
+	ASMTYPE_PEARL,
+	ASMTYPE_JUNIPER,
+	ASMTYPE_SPRUCE,
+};
+
+#define PFX "ibmasr: "
+
+#define TOPAZ_ASR_REG_OFFSET	4
+#define TOPAZ_ASR_TOGGLE	0x40
+#define TOPAZ_ASR_DISABLE	0x80
+
+/* PEARL ASR S/W REGISTER SUPERIO PORT ADDRESSES */
+#define PEARL_BASE	0xe04
+#define PEARL_WRITE	0xe06
+#define PEARL_READ	0xe07
+
+#define PEARL_ASR_DISABLE_MASK	0x80	/* bit 7: disable = 1, enable = 0 */
+#define PEARL_ASR_TOGGLE_MASK	0x40	/* bit 6: 0, then 1, then 0 */
+
+/* JASPER OFFSET FROM SIO BASE ADDR TO ASR S/W REGISTERS. */
+#define JASPER_ASR_REG_OFFSET	0x38
+
+#define JASPER_ASR_DISABLE_MASK	0x01	/* bit 0: disable = 1, enable = 0 */
+#define JASPER_ASR_TOGGLE_MASK	0x02	/* bit 1: 0, then 1, then 0 */
+
+#define JUNIPER_BASE_ADDRESS	0x54b	/* Base address of Juniper ASR */
+#define JUNIPER_ASR_DISABLE_MASK 0x01	/* bit 0: disable = 1 enable = 0 */
+#define JUNIPER_ASR_TOGGLE_MASK	0x02	/* bit 1: 0, then 1, then 0 */
+
+#define SPRUCE_BASE_ADDRESS	0x118e	/* Base address of Spruce ASR */
+#define SPRUCE_ASR_DISABLE_MASK	0x01	/* bit 1: disable = 1 enable = 0 */
+#define SPRUCE_ASR_TOGGLE_MASK	0x02	/* bit 0: 0, then 1, then 0 */
+
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+
+static unsigned long asr_is_open;
+static char asr_expect_close;
+
+static unsigned int asr_type, asr_base, asr_length;
+static unsigned int asr_read_addr, asr_write_addr;
+static unsigned char asr_toggle_mask, asr_disable_mask;
+
+static void asr_toggle(void)
+{
+	unsigned char reg = inb(asr_read_addr);
+
+	outb(reg & ~asr_toggle_mask, asr_write_addr);
+	reg = inb(asr_read_addr);
+
+	outb(reg | asr_toggle_mask, asr_write_addr);
+	reg = inb(asr_read_addr);
+
+	outb(reg & ~asr_toggle_mask, asr_write_addr);
+	reg = inb(asr_read_addr);
+}
+
+static void asr_enable(void)
+{
+	unsigned char reg;
+
+	if (asr_type == ASMTYPE_TOPAZ) {
+		/* asr_write_addr == asr_read_addr */
+		reg = inb(asr_read_addr);
+		outb(reg & ~(TOPAZ_ASR_TOGGLE | TOPAZ_ASR_DISABLE),
+		     asr_read_addr);
+	} else {
+		/*
+		 * First make sure the hardware timer is reset by toggling
+		 * ASR hardware timer line.
+		 */
+		asr_toggle();
+
+		reg = inb(asr_read_addr);
+		outb(reg & ~asr_disable_mask, asr_write_addr);
+	}
+	reg = inb(asr_read_addr);
+}
+
+static void asr_disable(void)
+{
+	unsigned char reg = inb(asr_read_addr);
+
+	if (asr_type == ASMTYPE_TOPAZ)
+		/* asr_write_addr == asr_read_addr */
+		outb(reg | TOPAZ_ASR_TOGGLE | TOPAZ_ASR_DISABLE,
+		     asr_read_addr);
+	else {
+		outb(reg | asr_toggle_mask, asr_write_addr);
+		reg = inb(asr_read_addr);
+
+		outb(reg | asr_disable_mask, asr_write_addr);
+	}
+	reg = inb(asr_read_addr);
+}
+
+static int __init asr_get_base_address(void)
+{
+	unsigned char low, high;
+	const char *type = "";
+
+	asr_length = 1;
+
+	switch (asr_type) {
+	case ASMTYPE_TOPAZ:
+		/* SELECT SuperIO CHIP FOR QUERYING (WRITE 0x07 TO BOTH 0x2E and 0x2F) */
+		outb(0x07, 0x2e);
+		outb(0x07, 0x2f);
+
+		/* SELECT AND READ THE HIGH-NIBBLE OF THE GPIO BASE ADDRESS */
+		outb(0x60, 0x2e);
+		high = inb(0x2f);
+
+		/* SELECT AND READ THE LOW-NIBBLE OF THE GPIO BASE ADDRESS */
+		outb(0x61, 0x2e);
+		low = inb(0x2f);
+
+		asr_base = (high << 16) | low;
+		asr_read_addr = asr_write_addr =
+			asr_base + TOPAZ_ASR_REG_OFFSET;
+		asr_length = 5;
+
+		break;
+
+	case ASMTYPE_JASPER:
+		type = "Jaspers ";
+
+		/* FIXME: need to use pci_config_lock here, but it's not exported */
+
+/*		spin_lock_irqsave(&pci_config_lock, flags);*/
+
+		/* Select the SuperIO chip in the PCI I/O port register */
+		outl(0x8000f858, 0xcf8);
+
+		/*
+		 * Read the base address for the SuperIO chip.
+		 * Only the lower 16 bits are valid, but the address is word
+		 * aligned so the last bit must be masked off.
+		 */
+		asr_base = inl(0xcfc) & 0xfffe;
+
+/*		spin_unlock_irqrestore(&pci_config_lock, flags);*/
+
+		asr_read_addr = asr_write_addr =
+			asr_base + JASPER_ASR_REG_OFFSET;
+		asr_toggle_mask = JASPER_ASR_TOGGLE_MASK;
+		asr_disable_mask = JASPER_ASR_DISABLE_MASK;
+		asr_length = JASPER_ASR_REG_OFFSET + 1;
+
+		break;
+
+	case ASMTYPE_PEARL:
+		type = "Pearls ";
+		asr_base = PEARL_BASE;
+		asr_read_addr = PEARL_READ;
+		asr_write_addr = PEARL_WRITE;
+		asr_toggle_mask = PEARL_ASR_TOGGLE_MASK;
+		asr_disable_mask = PEARL_ASR_DISABLE_MASK;
+		asr_length = 4;
+		break;
+
+	case ASMTYPE_JUNIPER:
+		type = "Junipers ";
+		asr_base = JUNIPER_BASE_ADDRESS;
+		asr_read_addr = asr_write_addr = asr_base;
+		asr_toggle_mask = JUNIPER_ASR_TOGGLE_MASK;
+		asr_disable_mask = JUNIPER_ASR_DISABLE_MASK;
+		break;
+
+	case ASMTYPE_SPRUCE:
+		type = "Spruce's ";
+		asr_base = SPRUCE_BASE_ADDRESS;
+		asr_read_addr = asr_write_addr = asr_base;
+		asr_toggle_mask = SPRUCE_ASR_TOGGLE_MASK;
+		asr_disable_mask = SPRUCE_ASR_DISABLE_MASK;
+		break;
+	}
+
+	if (!request_region(asr_base, asr_length, "ibmasr")) {
+		printk(KERN_ERR PFX "address %#x already in use\n",
+			asr_base);
+		return -EBUSY;
+	}
+
+	printk(KERN_INFO PFX "found %sASR @ addr %#x\n", type, asr_base);
+
+	return 0;
+}
+
+
+static ssize_t asr_write(struct file *file, const char __user *buf,
+			 size_t count, loff_t *ppos)
+{
+	if (count) {
+		if (!nowayout) {
+			size_t i;
+
+			/* In case it was set long ago */
+			asr_expect_close = 0;
+
+			for (i = 0; i != count; i++) {
+				char c;
+				if (get_user(c, buf + i))
+					return -EFAULT;
+				if (c == 'V')
+					asr_expect_close = 42;
+			}
+		}
+		asr_toggle();
+	}
+	return count;
+}
+
+static int asr_ioctl(struct inode *inode, struct file *file,
+		     unsigned int cmd, unsigned long arg)
+{
+	static const struct watchdog_info ident = {
+		.options =	WDIOF_KEEPALIVEPING | 
+				WDIOF_MAGICCLOSE,
+		.identity =	"IBM ASR"
+	};
+	void __user *argp = (void __user *)arg;
+	int __user *p = argp;
+	int heartbeat;
+
+	switch (cmd) {
+		case WDIOC_GETSUPPORT:
+			return copy_to_user(argp, &ident, sizeof(ident)) ?
+				-EFAULT : 0;
+
+		case WDIOC_GETSTATUS:
+		case WDIOC_GETBOOTSTATUS:
+			return put_user(0, p);
+
+		case WDIOC_KEEPALIVE:
+			asr_toggle();
+			return 0;
+
+		/*
+		 * The hardware has a fixed timeout value, so no WDIOC_SETTIMEOUT
+		 * and WDIOC_GETTIMEOUT always returns 256.
+		 */
+		case WDIOC_GETTIMEOUT:
+			heartbeat = 256;
+			return put_user(heartbeat, p);
+
+		case WDIOC_SETOPTIONS: {
+			int new_options, retval = -EINVAL;
+
+			if (get_user(new_options, p))
+				return -EFAULT;
+
+			if (new_options & WDIOS_DISABLECARD) {
+				asr_disable();
+				retval = 0;
+			}
+
+			if (new_options & WDIOS_ENABLECARD) {
+				asr_enable();
+				asr_toggle();
+				retval = 0;
+			}
+
+			return retval;
+		}
+	}
+
+	return -ENOIOCTLCMD;
+}
+
+static int asr_open(struct inode *inode, struct file *file)
+{
+	if(test_and_set_bit(0, &asr_is_open))
+		return -EBUSY;
+
+	asr_toggle();
+	asr_enable();
+
+	return nonseekable_open(inode, file);
+}
+
+static int asr_release(struct inode *inode, struct file *file)
+{
+	if (asr_expect_close == 42)
+		asr_disable();
+	else {
+		printk(KERN_CRIT PFX "unexpected close, not stopping watchdog!\n");
+		asr_toggle();
+	}
+	clear_bit(0, &asr_is_open);
+	asr_expect_close = 0;
+	return 0;
+}
+
+static struct file_operations asr_fops = {
+	.owner =	THIS_MODULE,
+	.llseek	=	no_llseek,
+	.write =	asr_write,
+	.ioctl =	asr_ioctl,
+	.open =		asr_open,
+	.release =	asr_release,
+};
+
+static struct miscdevice asr_miscdev = {
+	.minor =	WATCHDOG_MINOR,
+	.name =		"watchdog",
+	.fops =		&asr_fops,
+};
+
+
+struct ibmasr_id {
+	const char *desc;
+	int type;
+};
+
+static struct ibmasr_id __initdata ibmasr_id_table[] = {
+	{ "IBM Automatic Server Restart - eserver xSeries 220", ASMTYPE_TOPAZ },
+	{ "IBM Automatic Server Restart - Machine Type 8673", ASMTYPE_PEARL },
+	{ "IBM Automatic Server Restart - Machine Type 8480", ASMTYPE_JASPER },
+	{ "IBM Automatic Server Restart - Machine Type 8482", ASMTYPE_JUNIPER },
+	{ "IBM Automatic Server Restart - Machine Type 8648", ASMTYPE_SPRUCE },
+	{ NULL }
+};
+
+static int __init ibmasr_init(void)
+{
+	struct ibmasr_id *id;
+	int rc;
+
+	for (id = ibmasr_id_table; id->desc; id++) {
+		if (dmi_find_device(DMI_DEV_TYPE_OTHER, id->desc, NULL)) {
+			asr_type = id->type;
+			break;
+		}
+	}
+
+	if (!asr_type)
+		return -ENODEV;
+
+	rc = misc_register(&asr_miscdev);
+	if (rc < 0) {
+		printk(KERN_ERR PFX "failed to register misc device\n");
+		return rc;
+	}
+
+	rc = asr_get_base_address();
+	if (rc) {
+		misc_deregister(&asr_miscdev);
+		return rc;
+	}
+
+	return 0;
+}
+
+static void __exit ibmasr_exit(void)
+{
+	if (!nowayout)
+		asr_disable();
+
+	misc_deregister(&asr_miscdev);
+
+	release_region(asr_base, asr_length);
+}
+
+module_init(ibmasr_init);
+module_exit(ibmasr_exit);
+
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+
+MODULE_DESCRIPTION("IBM Automatic Server Restart driver");
+MODULE_AUTHOR("Andrey Panin");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/mv64x60_wdt.c b/drivers/char/watchdog/mv64x60_wdt.c
new file mode 100644
index 0000000..1436aea
--- /dev/null
+++ b/drivers/char/watchdog/mv64x60_wdt.c
@@ -0,0 +1,252 @@
+/*
+ * mv64x60_wdt.c - MV64X60 (Marvell Discovery) watchdog userspace interface
+ *
+ * Author: James Chapman <jchapman@katalix.com>
+ *
+ * Platform-specific setup code should configure the dog to generate
+ * interrupt or reset as required.  This code only enables/disables
+ * and services the watchdog.
+ *
+ * Derived from mpc8xx_wdt.c, with the following copyright.
+ * 
+ * 2002 (c) Florian Schirmer <jolt@tuxbox.org> This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/watchdog.h>
+#include <asm/mv64x60.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+/* MV64x60 WDC (config) register access definitions */
+#define MV64x60_WDC_CTL1_MASK	(3 << 24)
+#define MV64x60_WDC_CTL1(val)	((val & 3) << 24)
+#define MV64x60_WDC_CTL2_MASK	(3 << 26)
+#define MV64x60_WDC_CTL2(val)	((val & 3) << 26)
+
+/* Flags bits */
+#define MV64x60_WDOG_FLAG_OPENED	0
+#define MV64x60_WDOG_FLAG_ENABLED	1
+
+static unsigned long wdt_flags;
+static int wdt_status;
+static void __iomem *mv64x60_regs;
+static int mv64x60_wdt_timeout;
+
+static void mv64x60_wdt_reg_write(u32 val)
+{
+	/* Allow write only to CTL1 / CTL2 fields, retaining values in
+	 * other fields.
+	 */
+	u32 data = readl(mv64x60_regs + MV64x60_WDT_WDC);
+	data &= ~(MV64x60_WDC_CTL1_MASK | MV64x60_WDC_CTL2_MASK);
+	data |= val;
+	writel(data, mv64x60_regs + MV64x60_WDT_WDC);
+}
+
+static void mv64x60_wdt_service(void)
+{
+	/* Write 01 followed by 10 to CTL2 */
+	mv64x60_wdt_reg_write(MV64x60_WDC_CTL2(0x01));
+	mv64x60_wdt_reg_write(MV64x60_WDC_CTL2(0x02));
+}
+
+static void mv64x60_wdt_handler_disable(void)
+{
+	if (test_and_clear_bit(MV64x60_WDOG_FLAG_ENABLED, &wdt_flags)) {
+		/* Write 01 followed by 10 to CTL1 */
+		mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x01));
+		mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x02));
+		printk(KERN_NOTICE "mv64x60_wdt: watchdog deactivated\n");
+	}
+}
+
+static void mv64x60_wdt_handler_enable(void)
+{
+	if (!test_and_set_bit(MV64x60_WDOG_FLAG_ENABLED, &wdt_flags)) {
+		/* Write 01 followed by 10 to CTL1 */
+		mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x01));
+		mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x02));
+		printk(KERN_NOTICE "mv64x60_wdt: watchdog activated\n");
+	}
+}
+
+static int mv64x60_wdt_open(struct inode *inode, struct file *file)
+{
+	if (test_and_set_bit(MV64x60_WDOG_FLAG_OPENED, &wdt_flags))
+		return -EBUSY;
+
+	mv64x60_wdt_service();
+	mv64x60_wdt_handler_enable();
+
+	return 0;
+}
+
+static int mv64x60_wdt_release(struct inode *inode, struct file *file)
+{
+	mv64x60_wdt_service();
+
+#if !defined(CONFIG_WATCHDOG_NOWAYOUT)
+	mv64x60_wdt_handler_disable();
+#endif
+
+	clear_bit(MV64x60_WDOG_FLAG_OPENED, &wdt_flags);
+
+	return 0;
+}
+
+static ssize_t mv64x60_wdt_write(struct file *file, const char *data,
+				 size_t len, loff_t * ppos)
+{
+	if (*ppos != file->f_pos)
+		return -ESPIPE;
+
+	if (len)
+		mv64x60_wdt_service();
+
+	return len;
+}
+
+static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file,
+			     unsigned int cmd, unsigned long arg)
+{
+	int timeout;
+	static struct watchdog_info info = {
+		.options = WDIOF_KEEPALIVEPING,
+		.firmware_version = 0,
+		.identity = "MV64x60 watchdog",
+	};
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		if (copy_to_user((void *)arg, &info, sizeof(info)))
+			return -EFAULT;
+		break;
+
+	case WDIOC_GETSTATUS:
+	case WDIOC_GETBOOTSTATUS:
+		if (put_user(wdt_status, (int *)arg))
+			return -EFAULT;
+		wdt_status &= ~WDIOF_KEEPALIVEPING;
+		break;
+
+	case WDIOC_GETTEMP:
+		return -EOPNOTSUPP;
+
+	case WDIOC_SETOPTIONS:
+		return -EOPNOTSUPP;
+
+	case WDIOC_KEEPALIVE:
+		mv64x60_wdt_service();
+		wdt_status |= WDIOF_KEEPALIVEPING;
+		break;
+
+	case WDIOC_SETTIMEOUT:
+		return -EOPNOTSUPP;
+
+	case WDIOC_GETTIMEOUT:
+		timeout = mv64x60_wdt_timeout * HZ;
+		if (put_user(timeout, (int *)arg))
+			return -EFAULT;
+		break;
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+
+	return 0;
+}
+
+static struct file_operations mv64x60_wdt_fops = {
+	.owner = THIS_MODULE,
+	.llseek = no_llseek,
+	.write = mv64x60_wdt_write,
+	.ioctl = mv64x60_wdt_ioctl,
+	.open = mv64x60_wdt_open,
+	.release = mv64x60_wdt_release,
+};
+
+static struct miscdevice mv64x60_wdt_miscdev = {
+	.minor = WATCHDOG_MINOR,
+	.name = "watchdog",
+	.fops = &mv64x60_wdt_fops,
+};
+
+static int __devinit mv64x60_wdt_probe(struct device *dev)
+{
+	struct platform_device *pd = to_platform_device(dev);
+	struct mv64x60_wdt_pdata *pdata = pd->dev.platform_data;
+	int bus_clk = 133;
+
+	mv64x60_wdt_timeout = 10;
+	if (pdata) {
+		mv64x60_wdt_timeout = pdata->timeout;
+		bus_clk = pdata->bus_clk;
+	}
+
+	mv64x60_regs = mv64x60_get_bridge_vbase();
+
+	writel((mv64x60_wdt_timeout * (bus_clk * 1000000)) >> 8,
+	       mv64x60_regs + MV64x60_WDT_WDC);
+
+	return misc_register(&mv64x60_wdt_miscdev);
+}
+
+static int __devexit mv64x60_wdt_remove(struct device *dev)
+{
+	misc_deregister(&mv64x60_wdt_miscdev);
+
+	mv64x60_wdt_service();
+	mv64x60_wdt_handler_disable();
+
+	return 0;
+}
+
+static struct device_driver mv64x60_wdt_driver = {
+	.name = MV64x60_WDT_NAME,
+	.bus = &platform_bus_type,
+	.probe = mv64x60_wdt_probe,
+	.remove = __devexit_p(mv64x60_wdt_remove),
+};
+
+static struct platform_device *mv64x60_wdt_dev;
+
+static int __init mv64x60_wdt_init(void)
+{
+	int ret;
+
+	printk(KERN_INFO "MV64x60 watchdog driver\n");
+
+	mv64x60_wdt_dev = platform_device_register_simple(MV64x60_WDT_NAME,
+							  -1, NULL, 0);
+	if (IS_ERR(mv64x60_wdt_dev)) {
+		ret = PTR_ERR(mv64x60_wdt_dev);
+		goto out;
+	}
+
+	ret = driver_register(&mv64x60_wdt_driver);
+      out:
+	return ret;
+}
+
+static void __exit mv64x60_wdt_exit(void)
+{
+	driver_unregister(&mv64x60_wdt_driver);
+	platform_device_unregister(mv64x60_wdt_dev);
+}
+
+module_init(mv64x60_wdt_init);
+module_exit(mv64x60_wdt_exit);
+
+MODULE_AUTHOR("James Chapman <jchapman@katalix.com>");
+MODULE_DESCRIPTION("MV64x60 watchdog driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c
index 2b13afb..5a80adb 100644
--- a/drivers/char/watchdog/pcwd_pci.c
+++ b/drivers/char/watchdog/pcwd_pci.c
@@ -29,27 +29,29 @@
  *	Includes, defines, variables, module parameters, ...
  */
 
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/miscdevice.h>
-#include <linux/watchdog.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/pci.h>
-#include <linux/ioport.h>
-#include <linux/spinlock.h>
+#include <linux/config.h>	/* For CONFIG_WATCHDOG_NOWAYOUT/... */
+#include <linux/module.h>	/* For module specific items */
+#include <linux/moduleparam.h>	/* For new moduleparam's */
+#include <linux/types.h>	/* For standard types (like size_t) */
+#include <linux/errno.h>	/* For the -ENODEV/... values */
+#include <linux/kernel.h>	/* For printk/panic/... */
+#include <linux/delay.h>	/* For mdelay function */
+#include <linux/miscdevice.h>	/* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */
+#include <linux/watchdog.h>	/* For the watchdog specific items */
+#include <linux/notifier.h>	/* For notifier support */
+#include <linux/reboot.h>	/* For reboot_notifier stuff */
+#include <linux/init.h>		/* For __init/__exit/... */
+#include <linux/fs.h>		/* For file operations */
+#include <linux/pci.h>		/* For pci functions */
+#include <linux/ioport.h>	/* For io-port access */
+#include <linux/spinlock.h>	/* For spin_lock/spin_unlock/... */
 
-#include <asm/uaccess.h>
-#include <asm/io.h>
+#include <asm/uaccess.h>	/* For copy_to_user/put_user/... */
+#include <asm/io.h>		/* For inb/outb/... */
 
 /* Module and version information */
 #define WATCHDOG_VERSION "1.01"
-#define WATCHDOG_DATE "15 Mar 2005"
+#define WATCHDOG_DATE "02 Sep 2005"
 #define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog"
 #define WATCHDOG_NAME "pcwd_pci"
 #define PFX WATCHDOG_NAME ": "
@@ -335,12 +337,14 @@
 				return -EFAULT;
 
 			if (new_options & WDIOS_DISABLECARD) {
-				pcipcwd_stop();
+				if (pcipcwd_stop())
+					return -EIO;
 				retval = 0;
 			}
 
 			if (new_options & WDIOS_ENABLECARD) {
-				pcipcwd_start();
+				if (pcipcwd_start())
+					return -EIO;
 				retval = 0;
 			}
 
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c
index 8b292bf..3625b26 100644
--- a/drivers/char/watchdog/s3c2410_wdt.c
+++ b/drivers/char/watchdog/s3c2410_wdt.c
@@ -464,7 +464,7 @@
 static unsigned long wtcon_save;
 static unsigned long wtdat_save;
 
-static int s3c2410wdt_suspend(struct device *dev, u32 state, u32 level)
+static int s3c2410wdt_suspend(struct device *dev, pm_message_t state, u32 level)
 {
 	if (level == SUSPEND_POWER_DOWN) {
 		/* Save watchdog state, and turn it off. */
diff --git a/drivers/char/watchdog/sbc8360.c b/drivers/char/watchdog/sbc8360.c
new file mode 100644
index 0000000..c6cbf80
--- /dev/null
+++ b/drivers/char/watchdog/sbc8360.c
@@ -0,0 +1,414 @@
+/*
+ *	SBC8360 Watchdog driver
+ *
+ *	(c) Copyright 2005 Webcon, Inc.
+ *
+ *	Based on ib700wdt.c, which is based on advantechwdt.c which is based
+ *      on acquirewdt.c which is based on wdt.c.
+ *
+ *	(c) Copyright 2001 Charles Howes <chowes@vsol.net>
+ *
+ *      Based on advantechwdt.c which is based on acquirewdt.c which
+ *       is based on wdt.c.
+ *
+ *	(c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl>
+ *
+ *	Based on acquirewdt.c which is based on wdt.c.
+ *	Original copyright messages:
+ *
+ *	(c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
+ *				http://www.redhat.com
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *
+ *	Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
+ *	warranty for any of this software. This material is provided
+ *	"AS-IS" and at no charge.
+ *
+ *	(c) Copyright 1995    Alan Cox <alan@redhat.com>
+ *
+ *      14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
+ *           Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
+ *           Added timeout module option to override default
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/notifier.h>
+#include <linux/fs.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/moduleparam.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+static unsigned long sbc8360_is_open;
+static spinlock_t sbc8360_lock;
+static char expect_close;
+
+#define PFX "sbc8360: "
+
+/*
+ *
+ * Watchdog Timer Configuration
+ *
+ * The function of the watchdog timer is to reset the system automatically
+ * and is defined at I/O port 0120H and 0121H.  To enable the watchdog timer
+ * and allow the system to reset, write appropriate values from the table
+ * below to I/O port 0120H and 0121H.  To disable the timer, write a zero
+ * value to I/O port 0121H for the system to stop the watchdog function.
+ *
+ * The following describes how the timer should be programmed (according to
+ * the vendor documentation)
+ *
+ * Enabling Watchdog:
+ * MOV AX,000AH (enable, phase I)
+ * MOV DX,0120H
+ * OUT DX,AX
+ * MOV AX,000BH (enable, phase II)
+ * MOV DX,0120H
+ * OUT DX,AX
+ * MOV AX,000nH (set multiplier n, from 1-4)
+ * MOV DX,0120H
+ * OUT DX,AX
+ * MOV AX,000mH (set base timer m, from 0-F)
+ * MOV DX,0121H
+ * OUT DX,AX
+ *
+ * Reset timer:
+ * MOV AX,000mH (same as set base timer, above)
+ * MOV DX,0121H
+ * OUT DX,AX
+ *
+ * Disabling Watchdog:
+ * MOV AX,0000H (a zero value)
+ * MOV DX,0120H
+ * OUT DX,AX
+ *
+ * Watchdog timeout configuration values:
+ *		N
+ *	M |	1	2	3	4
+ *	--|----------------------------------
+ *	0 |	0.5s	5s	50s	100s
+ *	1 |	1s	10s	100s	200s
+ *	2 |	1.5s	15s	150s	300s
+ *	3 |	2s	20s	200s	400s
+ *	4 |	2.5s	25s	250s	500s
+ *	5 |	3s	30s	300s	600s
+ *	6 |	3.5s	35s	350s	700s
+ *	7 |	4s	40s	400s	800s
+ *	8 |	4.5s	45s	450s	900s
+ *	9 |	5s	50s	500s	1000s
+ *	A |	5.5s	55s	550s	1100s
+ *	B |	6s	60s	600s	1200s
+ *	C |	6.5s	65s	650s	1300s
+ *	D |	7s	70s	700s	1400s
+ *	E |	7.5s	75s	750s	1500s
+ *	F |	8s	80s 	800s 	1600s
+ *
+ * Another way to say the same things is:
+ *  For N=1, Timeout = (M+1) * 0.5s
+ *  For N=2, Timeout = (M+1) * 5s
+ *  For N=3, Timeout = (M+1) * 50s
+ *  For N=4, Timeout = (M+1) * 100s
+ *
+ */
+
+static int wd_times[64][2] = {
+	{0, 1},			/* 0  = 0.5s */
+	{1, 1},			/* 1  = 1s   */
+	{2, 1},			/* 2  = 1.5s */
+	{3, 1},			/* 3  = 2s   */
+	{4, 1},			/* 4  = 2.5s */
+	{5, 1},			/* 5  = 3s   */
+	{6, 1},			/* 6  = 3.5s */
+	{7, 1},			/* 7  = 4s   */
+	{8, 1},			/* 8  = 4.5s */
+	{9, 1},			/* 9  = 5s   */
+	{0xA, 1},		/* 10 = 5.5s */
+	{0xB, 1},		/* 11 = 6s   */
+	{0xC, 1},		/* 12 = 6.5s */
+	{0xD, 1},		/* 13 = 7s   */
+	{0xE, 1},		/* 14 = 7.5s */
+	{0xF, 1},		/* 15 = 8s   */
+	{0, 2},			/* 16 = 5s  */
+	{1, 2},			/* 17 = 10s */
+	{2, 2},			/* 18 = 15s */
+	{3, 2},			/* 19 = 20s */
+	{4, 2},			/* 20 = 25s */
+	{5, 2},			/* 21 = 30s */
+	{6, 2},			/* 22 = 35s */
+	{7, 2},			/* 23 = 40s */
+	{8, 2},			/* 24 = 45s */
+	{9, 2},			/* 25 = 50s */
+	{0xA, 2},		/* 26 = 55s */
+	{0xB, 2},		/* 27 = 60s */
+	{0xC, 2},		/* 28 = 65s */
+	{0xD, 2},		/* 29 = 70s */
+	{0xE, 2},		/* 30 = 75s */
+	{0xF, 2},		/* 31 = 80s */
+	{0, 3},			/* 32 = 50s  */
+	{1, 3},			/* 33 = 100s */
+	{2, 3},			/* 34 = 150s */
+	{3, 3},			/* 35 = 200s */
+	{4, 3},			/* 36 = 250s */
+	{5, 3},			/* 37 = 300s */
+	{6, 3},			/* 38 = 350s */
+	{7, 3},			/* 39 = 400s */
+	{8, 3},			/* 40 = 450s */
+	{9, 3},			/* 41 = 500s */
+	{0xA, 3},		/* 42 = 550s */
+	{0xB, 3},		/* 43 = 600s */
+	{0xC, 3},		/* 44 = 650s */
+	{0xD, 3},		/* 45 = 700s */
+	{0xE, 3},		/* 46 = 750s */
+	{0xF, 3},		/* 47 = 800s */
+	{0, 4},			/* 48 = 100s */
+	{1, 4},			/* 49 = 200s */
+	{2, 4},			/* 50 = 300s */
+	{3, 4},			/* 51 = 400s */
+	{4, 4},			/* 52 = 500s */
+	{5, 4},			/* 53 = 600s */
+	{6, 4},			/* 54 = 700s */
+	{7, 4},			/* 55 = 800s */
+	{8, 4},			/* 56 = 900s */
+	{9, 4},			/* 57 = 1000s */
+	{0xA, 4},		/* 58 = 1100s */
+	{0xB, 4},		/* 59 = 1200s */
+	{0xC, 4},		/* 60 = 1300s */
+	{0xD, 4},		/* 61 = 1400s */
+	{0xE, 4},		/* 62 = 1500s */
+	{0xF, 4}		/* 63 = 1600s */
+};
+
+#define SBC8360_ENABLE 0x120
+#define SBC8360_BASETIME 0x121
+
+static int timeout = 27;
+static int wd_margin = 0xB;
+static int wd_multiplier = 2;
+static int nowayout = WATCHDOG_NOWAYOUT;
+
+module_param(timeout, int, 27);
+MODULE_PARM_DESC(timeout, "Index into timeout table (0-63) (default=27 (60s))");
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout,
+		 "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+
+/*
+ *	Kernel methods.
+ */
+
+/* Activate and pre-configure watchdog */
+static void sbc8360_activate(void)
+{
+	/* Enable the watchdog */
+	outb(0x0A, SBC8360_ENABLE);
+	msleep_interruptible(100);
+	outb(0x0B, SBC8360_ENABLE);
+	msleep_interruptible(100);
+	/* Set timeout multiplier */
+	outb(wd_multiplier, SBC8360_ENABLE);
+	msleep_interruptible(100);
+	/* Nothing happens until first sbc8360_ping() */
+}
+
+/* Kernel pings watchdog */
+static void sbc8360_ping(void)
+{
+	/* Write the base timer register */
+	outb(wd_margin, SBC8360_BASETIME);
+}
+
+/* Userspace pings kernel driver, or requests clean close */
+static ssize_t sbc8360_write(struct file *file, const char __user * buf,
+			     size_t count, loff_t * ppos)
+{
+	if (count) {
+		if (!nowayout) {
+			size_t i;
+
+			/* In case it was set long ago */
+			expect_close = 0;
+
+			for (i = 0; i != count; i++) {
+				char c;
+				if (get_user(c, buf + i))
+					return -EFAULT;
+				if (c == 'V')
+					expect_close = 42;
+			}
+		}
+		sbc8360_ping();
+	}
+	return count;
+}
+
+static int sbc8360_open(struct inode *inode, struct file *file)
+{
+	spin_lock(&sbc8360_lock);
+	if (test_and_set_bit(0, &sbc8360_is_open)) {
+		spin_unlock(&sbc8360_lock);
+		return -EBUSY;
+	}
+	if (nowayout)
+		__module_get(THIS_MODULE);
+
+	/* Activate and ping once to start the countdown */
+	spin_unlock(&sbc8360_lock);
+	sbc8360_activate();
+	sbc8360_ping();
+	return nonseekable_open(inode, file);
+}
+
+static int sbc8360_close(struct inode *inode, struct file *file)
+{
+	spin_lock(&sbc8360_lock);
+	if (expect_close == 42)
+		outb(0, SBC8360_ENABLE);
+	else
+		printk(KERN_CRIT PFX
+		       "SBC8360 device closed unexpectedly.  SBC8360 will not stop!\n");
+
+	clear_bit(0, &sbc8360_is_open);
+	expect_close = 0;
+	spin_unlock(&sbc8360_lock);
+	return 0;
+}
+
+/*
+ *	Notifier for system down
+ */
+
+static int sbc8360_notify_sys(struct notifier_block *this, unsigned long code,
+			      void *unused)
+{
+	if (code == SYS_DOWN || code == SYS_HALT) {
+		/* Disable the SBC8360 Watchdog */
+		outb(0, SBC8360_ENABLE);
+	}
+	return NOTIFY_DONE;
+}
+
+/*
+ *	Kernel Interfaces
+ */
+
+static struct file_operations sbc8360_fops = {
+	.owner = THIS_MODULE,
+	.llseek = no_llseek,
+	.write = sbc8360_write,
+	.open = sbc8360_open,
+	.release = sbc8360_close,
+};
+
+static struct miscdevice sbc8360_miscdev = {
+	.minor = WATCHDOG_MINOR,
+	.name = "watchdog",
+	.fops = &sbc8360_fops,
+};
+
+/*
+ *	The SBC8360 needs to learn about soft shutdowns in order to
+ *	turn the timebomb registers off.
+ */
+
+static struct notifier_block sbc8360_notifier = {
+	.notifier_call = sbc8360_notify_sys,
+};
+
+static int __init sbc8360_init(void)
+{
+	int res;
+	unsigned long int mseconds = 60000;
+
+	spin_lock_init(&sbc8360_lock);
+	res = misc_register(&sbc8360_miscdev);
+	if (res) {
+		printk(KERN_ERR PFX "failed to register misc device\n");
+		goto out_nomisc;
+	}
+
+	if (!request_region(SBC8360_ENABLE, 1, "SBC8360")) {
+		printk(KERN_ERR PFX "ENABLE method I/O %X is not available.\n",
+		       SBC8360_ENABLE);
+		res = -EIO;
+		goto out_noenablereg;
+	}
+	if (!request_region(SBC8360_BASETIME, 1, "SBC8360")) {
+		printk(KERN_ERR PFX
+		       "BASETIME method I/O %X is not available.\n",
+		       SBC8360_BASETIME);
+		res = -EIO;
+		goto out_nobasetimereg;
+	}
+
+	res = register_reboot_notifier(&sbc8360_notifier);
+	if (res) {
+		printk(KERN_ERR PFX "Failed to register reboot notifier.\n");
+		goto out_noreboot;
+	}
+
+	if (timeout < 0 || timeout > 63) {
+		printk(KERN_ERR PFX "Invalid timeout index (must be 0-63).\n");
+		res = -EINVAL;
+		goto out_noreboot;
+	}
+
+	wd_margin = wd_times[timeout][0];
+	wd_multiplier = wd_times[timeout][1];
+
+	if (wd_multiplier == 1)
+		mseconds = (wd_margin + 1) * 500;
+	else if (wd_multiplier == 2)
+		mseconds = (wd_margin + 1) * 5000;
+	else if (wd_multiplier == 3)
+		mseconds = (wd_margin + 1) * 50000;
+	else if (wd_multiplier == 4)
+		mseconds = (wd_margin + 1) * 100000;
+
+	/* My kingdom for the ability to print "0.5 seconds" in the kernel! */
+	printk(KERN_INFO PFX "Timeout set at %ld ms.\n", mseconds);
+
+	return 0;
+
+      out_noreboot:
+	release_region(SBC8360_ENABLE, 1);
+	release_region(SBC8360_BASETIME, 1);
+      out_noenablereg:
+      out_nobasetimereg:
+	misc_deregister(&sbc8360_miscdev);
+      out_nomisc:
+	return res;
+}
+
+static void __exit sbc8360_exit(void)
+{
+	misc_deregister(&sbc8360_miscdev);
+	unregister_reboot_notifier(&sbc8360_notifier);
+	release_region(SBC8360_ENABLE, 1);
+	release_region(SBC8360_BASETIME, 1);
+}
+
+module_init(sbc8360_init);
+module_exit(sbc8360_exit);
+
+MODULE_AUTHOR("Ian E. Morgan <imorgan@webcon.ca>");
+MODULE_DESCRIPTION("SBC8360 watchdog driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+
+/* end of sbc8360.c */
diff --git a/drivers/char/watchdog/w83977f_wdt.c b/drivers/char/watchdog/w83977f_wdt.c
new file mode 100644
index 0000000..a7ff64c
--- /dev/null
+++ b/drivers/char/watchdog/w83977f_wdt.c
@@ -0,0 +1,543 @@
+/*
+ *	W83977F Watchdog Timer Driver for Winbond W83977F I/O Chip
+ *
+ *	(c) Copyright 2005  Jose Goncalves <jose.goncalves@inov.pt>
+ *
+ *      Based on w83877f_wdt.c by Scott Jennings,
+ *           and wdt977.c by Woody Suwalski
+ *
+ *			-----------------------
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/watchdog.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#define WATCHDOG_VERSION  "1.00"
+#define WATCHDOG_NAME     "W83977F WDT"
+#define PFX WATCHDOG_NAME ": "
+#define DRIVER_VERSION    WATCHDOG_NAME " driver, v" WATCHDOG_VERSION "\n"
+
+#define IO_INDEX_PORT     0x3F0
+#define IO_DATA_PORT      (IO_INDEX_PORT+1)
+
+#define UNLOCK_DATA       0x87
+#define LOCK_DATA         0xAA
+#define DEVICE_REGISTER   0x07
+
+#define	DEFAULT_TIMEOUT   45		/* default timeout in seconds */
+
+static	int timeout = DEFAULT_TIMEOUT;
+static	int timeoutW;			/* timeout in watchdog counter units */
+static	unsigned long timer_alive;
+static	int testmode;
+static	char expect_close;
+static	spinlock_t spinlock;
+
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout,"Watchdog timeout in seconds (15..7635), default=" __MODULE_STRING(DEFAULT_TIMEOUT) ")");
+module_param(testmode, int, 0);
+MODULE_PARM_DESC(testmode,"Watchdog testmode (1 = no reboot), default=0");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+
+/*
+ * Start the watchdog
+ */
+
+static int wdt_start(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&spinlock, flags);
+
+	/* Unlock the SuperIO chip */
+	outb_p(UNLOCK_DATA,IO_INDEX_PORT);
+	outb_p(UNLOCK_DATA,IO_INDEX_PORT);
+
+	/*
+	 * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4.
+	 * F2 has the timeout in watchdog counter units.
+	 * F3 is set to enable watchdog LED blink at timeout.
+	 * F4 is used to just clear the TIMEOUT'ed state (bit 0).
+	 */
+	outb_p(DEVICE_REGISTER,IO_INDEX_PORT);
+	outb_p(0x08,IO_DATA_PORT);
+	outb_p(0xF2,IO_INDEX_PORT);
+	outb_p(timeoutW,IO_DATA_PORT);
+	outb_p(0xF3,IO_INDEX_PORT);
+	outb_p(0x08,IO_DATA_PORT);
+	outb_p(0xF4,IO_INDEX_PORT);
+	outb_p(0x00,IO_DATA_PORT);
+
+	/* Set device Aux2 active */
+	outb_p(0x30,IO_INDEX_PORT);
+	outb_p(0x01,IO_DATA_PORT);
+
+	/* 
+	 * Select device Aux1 (dev=7) to set GP16 as the watchdog output
+	 * (in reg E6) and GP13 as the watchdog LED output (in reg E3).
+	 * Map GP16 at pin 119.
+	 * In test mode watch the bit 0 on F4 to indicate "triggered" or
+	 * check watchdog LED on SBC.
+	 */
+	outb_p(DEVICE_REGISTER,IO_INDEX_PORT);
+	outb_p(0x07,IO_DATA_PORT);
+	if (!testmode)
+	{
+		unsigned pin_map;
+
+		outb_p(0xE6,IO_INDEX_PORT);
+		outb_p(0x0A,IO_DATA_PORT);
+		outb_p(0x2C,IO_INDEX_PORT);
+		pin_map = inb_p(IO_DATA_PORT);
+		pin_map |= 0x10;
+		pin_map &= ~(0x20);
+		outb_p(0x2C,IO_INDEX_PORT);
+		outb_p(pin_map,IO_DATA_PORT);
+	}
+	outb_p(0xE3,IO_INDEX_PORT);
+	outb_p(0x08,IO_DATA_PORT);
+
+	/* Set device Aux1 active */
+	outb_p(0x30,IO_INDEX_PORT);
+	outb_p(0x01,IO_DATA_PORT);
+
+	/* Lock the SuperIO chip */
+	outb_p(LOCK_DATA,IO_INDEX_PORT);
+
+	spin_unlock_irqrestore(&spinlock, flags);
+
+	printk(KERN_INFO PFX "activated.\n");
+
+	return 0;
+}
+
+/*
+ * Stop the watchdog
+ */
+
+static int wdt_stop(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&spinlock, flags);
+
+	/* Unlock the SuperIO chip */
+	outb_p(UNLOCK_DATA,IO_INDEX_PORT);
+	outb_p(UNLOCK_DATA,IO_INDEX_PORT);
+
+	/* 
+	 * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4.
+	 * F2 is reset to its default value (watchdog timer disabled).
+	 * F3 is reset to its default state.
+	 * F4 clears the TIMEOUT'ed state (bit 0) - back to default.
+	 */
+	outb_p(DEVICE_REGISTER,IO_INDEX_PORT);
+	outb_p(0x08,IO_DATA_PORT);
+	outb_p(0xF2,IO_INDEX_PORT);
+	outb_p(0xFF,IO_DATA_PORT);
+	outb_p(0xF3,IO_INDEX_PORT);
+	outb_p(0x00,IO_DATA_PORT);
+	outb_p(0xF4,IO_INDEX_PORT);
+	outb_p(0x00,IO_DATA_PORT);
+	outb_p(0xF2,IO_INDEX_PORT);
+	outb_p(0x00,IO_DATA_PORT);
+
+	/*
+	 * Select device Aux1 (dev=7) to set GP16 (in reg E6) and 
+	 * Gp13 (in reg E3) as inputs.
+	 */
+	outb_p(DEVICE_REGISTER,IO_INDEX_PORT);
+	outb_p(0x07,IO_DATA_PORT);
+	if (!testmode)
+	{
+		outb_p(0xE6,IO_INDEX_PORT);
+		outb_p(0x01,IO_DATA_PORT);
+	}
+	outb_p(0xE3,IO_INDEX_PORT);
+	outb_p(0x01,IO_DATA_PORT);
+
+	/* Lock the SuperIO chip */
+	outb_p(LOCK_DATA,IO_INDEX_PORT);
+
+	spin_unlock_irqrestore(&spinlock, flags);
+
+	printk(KERN_INFO PFX "shutdown.\n");
+
+	return 0;
+}
+
+/*
+ * Send a keepalive ping to the watchdog
+ * This is done by simply re-writing the timeout to reg. 0xF2
+ */
+
+static int wdt_keepalive(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&spinlock, flags);
+
+	/* Unlock the SuperIO chip */
+	outb_p(UNLOCK_DATA,IO_INDEX_PORT);
+	outb_p(UNLOCK_DATA,IO_INDEX_PORT);
+
+	/* Select device Aux2 (device=8) to kick watchdog reg F2 */
+	outb_p(DEVICE_REGISTER,IO_INDEX_PORT);
+	outb_p(0x08,IO_DATA_PORT);
+	outb_p(0xF2,IO_INDEX_PORT);
+	outb_p(timeoutW,IO_DATA_PORT);
+
+	/* Lock the SuperIO chip */
+	outb_p(LOCK_DATA,IO_INDEX_PORT);
+
+	spin_unlock_irqrestore(&spinlock, flags);
+
+	return 0;
+}
+
+/*
+ * Set the watchdog timeout value
+ */
+
+static int wdt_set_timeout(int t)
+{
+	int tmrval;
+
+	/*
+	 * Convert seconds to watchdog counter time units, rounding up.
+	 * On PCM-5335 watchdog units are 30 seconds/step with 15 sec startup 
+	 * value. This information is supplied in the PCM-5335 manual and was
+	 * checked by me on a real board. This is a bit strange because W83977f
+	 * datasheet says counter unit is in minutes!
+	 */
+	if (t < 15)
+		return -EINVAL;
+
+	tmrval = ((t + 15) + 29) / 30;
+
+	if (tmrval > 255)
+		return -EINVAL;
+
+	/*
+	 * timeout is the timeout in seconds, 
+	 * timeoutW is the timeout in watchdog counter units.
+	 */
+	timeoutW = tmrval;
+	timeout = (timeoutW * 30) - 15;
+	return 0;
+}
+
+/*
+ * Get the watchdog status
+ */
+
+static int wdt_get_status(int *status)
+{
+	int new_status;
+	unsigned long flags;
+
+	spin_lock_irqsave(&spinlock, flags);
+
+	/* Unlock the SuperIO chip */
+	outb_p(UNLOCK_DATA,IO_INDEX_PORT);
+	outb_p(UNLOCK_DATA,IO_INDEX_PORT);
+
+	/* Select device Aux2 (device=8) to read watchdog reg F4 */
+	outb_p(DEVICE_REGISTER,IO_INDEX_PORT);
+	outb_p(0x08,IO_DATA_PORT);
+	outb_p(0xF4,IO_INDEX_PORT);
+	new_status = inb_p(IO_DATA_PORT);
+
+	/* Lock the SuperIO chip */
+	outb_p(LOCK_DATA,IO_INDEX_PORT);
+
+	spin_unlock_irqrestore(&spinlock, flags);
+
+	*status = 0;
+	if (new_status & 1)
+		*status |= WDIOF_CARDRESET;
+
+	return 0;
+}
+
+
+/*
+ *	/dev/watchdog handling
+ */
+
+static int wdt_open(struct inode *inode, struct file *file)
+{
+	/* If the watchdog is alive we don't need to start it again */
+	if( test_and_set_bit(0, &timer_alive) )
+		return -EBUSY;
+
+	if (nowayout)
+		__module_get(THIS_MODULE);
+
+	wdt_start();
+	return nonseekable_open(inode, file);
+}
+
+static int wdt_release(struct inode *inode, struct file *file)
+{
+	/*
+	 * Shut off the timer.
+	 * Lock it in if it's a module and we set nowayout
+	 */
+	if (expect_close == 42)
+	{
+		wdt_stop();
+		clear_bit(0, &timer_alive);
+	} else {
+		wdt_keepalive();
+		printk(KERN_CRIT PFX "unexpected close, not stopping watchdog!\n");
+	}
+	expect_close = 0;
+	return 0;
+}
+
+/*
+ *      wdt_write:
+ *      @file: file handle to the watchdog
+ *      @buf: buffer to write (unused as data does not matter here
+ *      @count: count of bytes
+ *      @ppos: pointer to the position to write. No seeks allowed
+ *
+ *      A write to a watchdog device is defined as a keepalive signal. Any
+ *      write of data will do, as we we don't define content meaning.
+ */
+
+static ssize_t wdt_write(struct file *file, const char __user *buf,
+			    size_t count, loff_t *ppos)
+{
+	/* See if we got the magic character 'V' and reload the timer */
+	if(count)
+	{
+		if (!nowayout)
+		{
+			size_t ofs;
+
+			/* note: just in case someone wrote the magic character long ago */
+			expect_close = 0;
+
+			/* scan to see whether or not we got the magic character */
+			for(ofs = 0; ofs != count; ofs++)
+			{
+				char c;
+				if (get_user(c, buf + ofs))
+					return -EFAULT;
+				if (c == 'V') {
+					expect_close = 42;
+				}
+			}
+		}
+
+		/* someone wrote to us, we should restart timer */
+		wdt_keepalive();
+	}
+	return count;
+}
+
+/*
+ *      wdt_ioctl:
+ *      @inode: inode of the device
+ *      @file: file handle to the device
+ *      @cmd: watchdog command
+ *      @arg: argument pointer
+ *
+ *      The watchdog API defines a common set of functions for all watchdogs
+ *      according to their available features.
+ */
+
+static struct watchdog_info ident = {
+	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
+	.firmware_version =	1,
+	.identity = WATCHDOG_NAME,
+};
+
+static int wdt_ioctl(struct inode *inode, struct file *file,
+	unsigned int cmd, unsigned long arg)
+{
+	int status;
+	int new_options, retval = -EINVAL;
+	int new_timeout;
+	union {
+		struct watchdog_info __user *ident;
+		int __user *i;
+	} uarg;
+
+	uarg.i = (int __user *)arg;
+
+	switch(cmd)
+	{
+	default:
+		return -ENOIOCTLCMD;
+
+	case WDIOC_GETSUPPORT:
+		return copy_to_user(uarg.ident, &ident, sizeof(ident)) ? -EFAULT : 0;
+
+	case WDIOC_GETSTATUS:
+		wdt_get_status(&status);
+		return put_user(status, uarg.i);
+
+	case WDIOC_GETBOOTSTATUS:
+		return put_user(0, uarg.i);
+
+	case WDIOC_KEEPALIVE:
+		wdt_keepalive();
+		return 0;
+
+	case WDIOC_SETOPTIONS:
+		if (get_user (new_options, uarg.i))
+			return -EFAULT;
+
+		if (new_options & WDIOS_DISABLECARD) {
+			wdt_stop();
+			retval = 0;
+		}
+
+		if (new_options & WDIOS_ENABLECARD) {
+			wdt_start();
+			retval = 0;
+		}
+
+		return retval;
+
+	case WDIOC_SETTIMEOUT:
+		if (get_user(new_timeout, uarg.i))
+			return -EFAULT;
+
+		if (wdt_set_timeout(new_timeout))
+		    return -EINVAL;
+
+		wdt_keepalive();
+		/* Fall */
+
+	case WDIOC_GETTIMEOUT:
+		return put_user(timeout, uarg.i);
+
+	}
+}
+
+static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
+	void *unused)
+{
+	if (code==SYS_DOWN || code==SYS_HALT)
+		wdt_stop();
+	return NOTIFY_DONE;
+}
+
+static struct file_operations wdt_fops=
+{
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.write		= wdt_write,
+	.ioctl		= wdt_ioctl,
+	.open		= wdt_open,
+	.release	= wdt_release,
+};
+
+static struct miscdevice wdt_miscdev=
+{
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &wdt_fops,
+};
+
+static struct notifier_block wdt_notifier = {
+	.notifier_call = wdt_notify_sys,
+};
+
+static int __init w83977f_wdt_init(void)
+{
+	int rc;
+
+        printk(KERN_INFO PFX DRIVER_VERSION);
+
+	spin_lock_init(&spinlock);
+
+	/*
+	 * Check that the timeout value is within it's range ; 
+	 * if not reset to the default
+	 */
+	if (wdt_set_timeout(timeout)) {
+		wdt_set_timeout(DEFAULT_TIMEOUT);
+		printk(KERN_INFO PFX "timeout value must be 15<=timeout<=7635, using %d\n",
+			DEFAULT_TIMEOUT);
+	}
+
+	if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME))
+	{
+		printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
+			IO_INDEX_PORT);
+		rc = -EIO;
+		goto err_out;
+	}
+
+	rc = misc_register(&wdt_miscdev);
+	if (rc)
+	{
+		printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
+			wdt_miscdev.minor, rc);
+		goto err_out_region;
+	}
+
+	rc = register_reboot_notifier(&wdt_notifier);
+	if (rc)
+	{
+		printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
+			rc);
+		goto err_out_miscdev;
+	}
+
+	printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d testmode=%d)\n",
+		timeout, nowayout, testmode);
+
+	return 0;
+
+err_out_miscdev:
+	misc_deregister(&wdt_miscdev);
+err_out_region:
+	release_region(IO_INDEX_PORT,2);
+err_out:
+	return rc;
+}
+
+static void __exit w83977f_wdt_exit(void)
+{
+	wdt_stop();
+	misc_deregister(&wdt_miscdev);
+	unregister_reboot_notifier(&wdt_notifier);
+	release_region(IO_INDEX_PORT,2);
+}
+
+module_init(w83977f_wdt_init);
+module_exit(w83977f_wdt_exit);
+
+MODULE_AUTHOR("Jose Goncalves <jose.goncalves@inov.pt>");
+MODULE_DESCRIPTION("Driver for watchdog timer in W83977F I/O chip");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c
index 37b49c2..eff5896 100644
--- a/drivers/i2c/busses/i2c-keywest.c
+++ b/drivers/i2c/busses/i2c-keywest.c
@@ -611,7 +611,6 @@
 	
 	for (i=0; i<nchan; i++) {
 		struct keywest_chan* chan = &iface->channels[i];
-		u8 addr;
 		
 		sprintf(chan->adapter.name, "%s %d", np->parent->name, i);
 		chan->iface = iface;
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index b443b04..0b0aa4f 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -601,44 +601,15 @@
  */
 u8 eighty_ninty_three (ide_drive_t *drive)
 {
-#if 0
-	if (!HWIF(drive)->udma_four)
+	if(HWIF(drive)->udma_four == 0)
 		return 0;
-
-	if (drive->id->major_rev_num) {
-		int hssbd = 0;
-		int i;
-		/*
-		 * Determine highest Supported SPEC
-		 */
-		for (i=1; i<=15; i++)
-			if (drive->id->major_rev_num & (1<<i))
-				hssbd++;
-
-		switch (hssbd) {
-			case 7:
-			case 6:
-			case 5:
-		/* ATA-4 and older do not support above Ultra 33 */
-			default:
-				return 0;
-		}
-	}
-
-	return ((u8) (
+	if (!(drive->id->hw_config & 0x6000))
+		return 0;
 #ifndef CONFIG_IDEDMA_IVB
-		(drive->id->hw_config & 0x4000) &&
+	if(!(drive->id->hw_config & 0x4000))
+		return 0;
 #endif /* CONFIG_IDEDMA_IVB */
-		 (drive->id->hw_config & 0x6000)) ? 1 : 0);
-
-#else
-
-	return ((u8) ((HWIF(drive)->udma_four) &&
-#ifndef CONFIG_IDEDMA_IVB
-			(drive->id->hw_config & 0x4000) &&
-#endif /* CONFIG_IDEDMA_IVB */
-			(drive->id->hw_config & 0x6000)) ? 1 : 0);
-#endif
+	return 1;
 }
 
 EXPORT_SYMBOL(eighty_ninty_three);
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
index 3de9ab8..3d9c7af 100644
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -608,7 +608,7 @@
 
 #ifdef __i386__
 	if (dev->resource[PCI_ROM_RESOURCE].start) {
-		pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
+		pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
 		printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start);
 	}
 #endif
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c
index bbde462..be334da 100644
--- a/drivers/ide/pci/hpt34x.c
+++ b/drivers/ide/pci/hpt34x.c
@@ -173,7 +173,7 @@
 
 	if (cmd & PCI_COMMAND_MEMORY) {
 		if (pci_resource_start(dev, PCI_ROM_RESOURCE)) {
-			pci_write_config_byte(dev, PCI_ROM_ADDRESS,
+			pci_write_config_dword(dev, PCI_ROM_ADDRESS,
 				dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
 			printk(KERN_INFO "HPT345: ROM enabled at 0x%08lx\n",
 				dev->resource[PCI_ROM_RESOURCE].start);
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index e55dee3..444f775 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -132,6 +132,17 @@
 	  To compile this driver as a module, choose M here: the 
 	  module will be called corgikbd.
 
+config KEYBOARD_SPITZ
+	tristate "Spitz keyboard"
+	depends on PXA_SHARPSL
+	default y
+	help
+	  Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000,
+	  SL-C3000 and Sl-C3100 series of PDAs.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called spitzkbd.
+
 config KEYBOARD_MAPLE
 	tristate "Maple bus keyboard"
 	depends on SH_DREAMCAST && MAPLE
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index b02eece..9ce0b87 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -14,6 +14,7 @@
 obj-$(CONFIG_KEYBOARD_NEWTON)		+= newtonkbd.o
 obj-$(CONFIG_KEYBOARD_98KBD)		+= 98kbd.o
 obj-$(CONFIG_KEYBOARD_CORGI)		+= corgikbd.o
+obj-$(CONFIG_KEYBOARD_SPITZ)		+= spitzkbd.o
 obj-$(CONFIG_KEYBOARD_HIL)		+= hil_kbd.o
 obj-$(CONFIG_KEYBOARD_HIL_OLD)		+= hilkbd.o
 
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c
new file mode 100644
index 0000000..1714045
--- /dev/null
+++ b/drivers/input/keyboard/spitzkbd.c
@@ -0,0 +1,478 @@
+/*
+ *  Keyboard driver for Sharp Spitz, Borzoi and Akita (SL-Cxx00 series)
+ *
+ *  Copyright (c) 2005 Richard Purdie
+ *
+ *  Based on corgikbd.c
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <asm/irq.h>
+
+#include <asm/arch/spitz.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/pxa-regs.h>
+
+#define KB_ROWS			7
+#define KB_COLS			11
+#define KB_ROWMASK(r)		(1 << (r))
+#define SCANCODE(r,c)		(((r)<<4) + (c) + 1)
+#define	NR_SCANCODES		((KB_ROWS<<4) + 1)
+
+#define HINGE_SCAN_INTERVAL	(150) /* ms */
+
+#define SPITZ_KEY_CALENDER	KEY_F1
+#define SPITZ_KEY_ADDRESS	KEY_F2
+#define SPITZ_KEY_FN		KEY_F3
+#define SPITZ_KEY_CANCEL	KEY_F4
+#define SPITZ_KEY_EXOK		KEY_F5
+#define SPITZ_KEY_EXCANCEL	KEY_F6
+#define SPITZ_KEY_EXJOGDOWN	KEY_F7
+#define SPITZ_KEY_EXJOGUP	KEY_F8
+#define SPITZ_KEY_JAP1		KEY_LEFTALT
+#define SPITZ_KEY_JAP2		KEY_RIGHTCTRL
+#define SPITZ_KEY_SYNC		KEY_F9
+#define SPITZ_KEY_MAIL		KEY_F10
+#define SPITZ_KEY_OK		KEY_F11
+#define SPITZ_KEY_MENU		KEY_F12
+
+static unsigned char spitzkbd_keycode[NR_SCANCODES] = {
+	0,                                                                                                                /* 0 */
+	KEY_LEFTCTRL, KEY_1, KEY_3, KEY_5, KEY_6, KEY_7, KEY_9, KEY_0, KEY_BACKSPACE, SPITZ_KEY_EXOK, SPITZ_KEY_EXCANCEL, 0, 0, 0, 0, 0,  /* 1-16 */
+	0, KEY_2, KEY_4, KEY_R, KEY_Y, KEY_8, KEY_I, KEY_O, KEY_P, SPITZ_KEY_EXJOGDOWN, SPITZ_KEY_EXJOGUP, 0, 0, 0, 0, 0, /* 17-32 */
+	KEY_TAB, KEY_Q, KEY_E, KEY_T, KEY_G, KEY_U, KEY_J, KEY_K, 0, 0, 0, 0, 0, 0, 0, 0,                                 /* 33-48 */
+	SPITZ_KEY_CALENDER, KEY_W, KEY_S, KEY_F, KEY_V, KEY_H, KEY_M, KEY_L, 0, 0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0,         /* 49-64 */
+	SPITZ_KEY_ADDRESS, KEY_A, KEY_D, KEY_C, KEY_B, KEY_N, KEY_DOT, 0, KEY_ENTER, KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0,	  /* 65-80 */
+	SPITZ_KEY_MAIL, KEY_Z, KEY_X, KEY_MINUS, KEY_SPACE, KEY_COMMA, 0, KEY_UP, 0, 0, SPITZ_KEY_FN, 0, 0, 0, 0, 0,      /* 81-96 */
+	KEY_SYSRQ, SPITZ_KEY_JAP1, SPITZ_KEY_JAP2, SPITZ_KEY_CANCEL, SPITZ_KEY_OK, SPITZ_KEY_MENU, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0, 0, 0  /* 97-112 */
+};
+
+static int spitz_strobes[] = {
+	SPITZ_GPIO_KEY_STROBE0,
+	SPITZ_GPIO_KEY_STROBE1,
+	SPITZ_GPIO_KEY_STROBE2,
+	SPITZ_GPIO_KEY_STROBE3,
+	SPITZ_GPIO_KEY_STROBE4,
+	SPITZ_GPIO_KEY_STROBE5,
+	SPITZ_GPIO_KEY_STROBE6,
+	SPITZ_GPIO_KEY_STROBE7,
+	SPITZ_GPIO_KEY_STROBE8,
+	SPITZ_GPIO_KEY_STROBE9,
+	SPITZ_GPIO_KEY_STROBE10,
+};
+
+static int spitz_senses[] = {
+	SPITZ_GPIO_KEY_SENSE0,
+	SPITZ_GPIO_KEY_SENSE1,
+	SPITZ_GPIO_KEY_SENSE2,
+	SPITZ_GPIO_KEY_SENSE3,
+	SPITZ_GPIO_KEY_SENSE4,
+	SPITZ_GPIO_KEY_SENSE5,
+	SPITZ_GPIO_KEY_SENSE6,
+};
+
+struct spitzkbd {
+	unsigned char keycode[ARRAY_SIZE(spitzkbd_keycode)];
+	struct input_dev input;
+	char phys[32];
+
+	spinlock_t lock;
+	struct timer_list timer;
+	struct timer_list htimer;
+
+	unsigned int suspended;
+	unsigned long suspend_jiffies;
+};
+
+#define KB_DISCHARGE_DELAY	10
+#define KB_ACTIVATE_DELAY	10
+
+/* Helper functions for reading the keyboard matrix
+ * Note: We should really be using pxa_gpio_mode to alter GPDR but it
+ *       requires a function call per GPIO bit which is excessive
+ *       when we need to access 11 bits at once, multiple times.
+ * These functions must be called within local_irq_save()/local_irq_restore()
+ * or similar.
+ */
+static inline void spitzkbd_discharge_all(void)
+{
+	/* STROBE All HiZ */
+	GPCR0  =  SPITZ_GPIO_G0_STROBE_BIT;
+	GPDR0 &= ~SPITZ_GPIO_G0_STROBE_BIT;
+	GPCR1  =  SPITZ_GPIO_G1_STROBE_BIT;
+	GPDR1 &= ~SPITZ_GPIO_G1_STROBE_BIT;
+	GPCR2  =  SPITZ_GPIO_G2_STROBE_BIT;
+	GPDR2 &= ~SPITZ_GPIO_G2_STROBE_BIT;
+	GPCR3  =  SPITZ_GPIO_G3_STROBE_BIT;
+	GPDR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
+}
+
+static inline void spitzkbd_activate_all(void)
+{
+	/* STROBE ALL -> High */
+	GPSR0  =  SPITZ_GPIO_G0_STROBE_BIT;
+	GPDR0 |=  SPITZ_GPIO_G0_STROBE_BIT;
+	GPSR1  =  SPITZ_GPIO_G1_STROBE_BIT;
+	GPDR1 |=  SPITZ_GPIO_G1_STROBE_BIT;
+	GPSR2  =  SPITZ_GPIO_G2_STROBE_BIT;
+	GPDR2 |=  SPITZ_GPIO_G2_STROBE_BIT;
+	GPSR3  =  SPITZ_GPIO_G3_STROBE_BIT;
+	GPDR3 |=  SPITZ_GPIO_G3_STROBE_BIT;
+
+	udelay(KB_DISCHARGE_DELAY);
+
+	/* Clear any interrupts we may have triggered when altering the GPIO lines */
+	GEDR0 = SPITZ_GPIO_G0_SENSE_BIT;
+	GEDR1 = SPITZ_GPIO_G1_SENSE_BIT;
+	GEDR2 = SPITZ_GPIO_G2_SENSE_BIT;
+	GEDR3 = SPITZ_GPIO_G3_SENSE_BIT;
+}
+
+static inline void spitzkbd_activate_col(int col)
+{
+	int gpio = spitz_strobes[col];
+	GPDR0 &= ~SPITZ_GPIO_G0_STROBE_BIT;
+	GPDR1 &= ~SPITZ_GPIO_G1_STROBE_BIT;
+	GPDR2 &= ~SPITZ_GPIO_G2_STROBE_BIT;
+	GPDR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
+	GPSR(gpio) = GPIO_bit(gpio);
+	GPDR(gpio) |= GPIO_bit(gpio);
+}
+
+static inline void spitzkbd_reset_col(int col)
+{
+	int gpio = spitz_strobes[col];
+	GPDR0 &= ~SPITZ_GPIO_G0_STROBE_BIT;
+	GPDR1 &= ~SPITZ_GPIO_G1_STROBE_BIT;
+	GPDR2 &= ~SPITZ_GPIO_G2_STROBE_BIT;
+	GPDR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
+	GPCR(gpio) = GPIO_bit(gpio);
+	GPDR(gpio) |= GPIO_bit(gpio);
+}
+
+static inline int spitzkbd_get_row_status(int col)
+{
+	return ((GPLR0 >> 12) & 0x01) | ((GPLR0 >> 16) & 0x02)
+		| ((GPLR2 >> 25) & 0x04) | ((GPLR1 << 1) & 0x08)
+		| ((GPLR1 >> 0) & 0x10) | ((GPLR1 >> 1) & 0x60);
+}
+
+/*
+ * The spitz keyboard only generates interrupts when a key is pressed.
+ * When a key is pressed, we enable a timer which then scans the
+ * keyboard to detect when the key is released.
+ */
+
+/* Scan the hardware keyboard and push any changes up through the input layer */
+static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs *regs)
+{
+	unsigned int row, col, rowd;
+	unsigned long flags;
+	unsigned int num_pressed, pwrkey = ((GPLR(SPITZ_GPIO_ON_KEY) & GPIO_bit(SPITZ_GPIO_ON_KEY)) != 0);
+
+	if (spitzkbd_data->suspended)
+		return;
+
+	spin_lock_irqsave(&spitzkbd_data->lock, flags);
+
+	if (regs)
+		input_regs(&spitzkbd_data->input, regs);
+
+	num_pressed = 0;
+	for (col = 0; col < KB_COLS; col++) {
+		/*
+		 * Discharge the output driver capacitatance
+		 * in the keyboard matrix. (Yes it is significant..)
+		 */
+
+		spitzkbd_discharge_all();
+		udelay(KB_DISCHARGE_DELAY);
+
+		spitzkbd_activate_col(col);
+		udelay(KB_ACTIVATE_DELAY);
+
+		rowd = spitzkbd_get_row_status(col);
+		for (row = 0; row < KB_ROWS; row++) {
+			unsigned int scancode, pressed;
+
+			scancode = SCANCODE(row, col);
+			pressed = rowd & KB_ROWMASK(row);
+
+			input_report_key(&spitzkbd_data->input, spitzkbd_data->keycode[scancode], pressed);
+
+			if (pressed)
+				num_pressed++;
+		}
+		spitzkbd_reset_col(col);
+	}
+
+	spitzkbd_activate_all();
+
+	input_report_key(&spitzkbd_data->input, SPITZ_KEY_SYNC, (GPLR(SPITZ_GPIO_SYNC) & GPIO_bit(SPITZ_GPIO_SYNC)) != 0 );
+	input_report_key(&spitzkbd_data->input, KEY_SUSPEND, pwrkey);
+
+	if (pwrkey && time_after(jiffies, spitzkbd_data->suspend_jiffies + msecs_to_jiffies(1000))) {
+		input_event(&spitzkbd_data->input, EV_PWR, KEY_SUSPEND, 1);
+		spitzkbd_data->suspend_jiffies = jiffies;
+	}
+
+	input_sync(&spitzkbd_data->input);
+
+	/* if any keys are pressed, enable the timer */
+	if (num_pressed)
+		mod_timer(&spitzkbd_data->timer, jiffies + msecs_to_jiffies(100));
+
+	spin_unlock_irqrestore(&spitzkbd_data->lock, flags);
+}
+
+/*
+ * spitz keyboard interrupt handler.
+ */
+static irqreturn_t spitzkbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct spitzkbd *spitzkbd_data = dev_id;
+
+	if (!timer_pending(&spitzkbd_data->timer)) {
+		/** wait chattering delay **/
+		udelay(20);
+		spitzkbd_scankeyboard(spitzkbd_data, regs);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * spitz timer checking for released keys
+ */
+static void spitzkbd_timer_callback(unsigned long data)
+{
+	struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data;
+	spitzkbd_scankeyboard(spitzkbd_data, NULL);
+}
+
+/*
+ * The hinge switches generate an interrupt.
+ * We debounce the switches and pass them to the input system.
+ */
+
+static irqreturn_t spitzkbd_hinge_isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct spitzkbd *spitzkbd_data = dev_id;
+
+	if (!timer_pending(&spitzkbd_data->htimer))
+		mod_timer(&spitzkbd_data->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
+
+	return IRQ_HANDLED;
+}
+
+#define HINGE_STABLE_COUNT 2
+static int sharpsl_hinge_state;
+static int hinge_count;
+
+static void spitzkbd_hinge_timer(unsigned long data)
+{
+	struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data;
+	unsigned long state;
+	unsigned long flags;
+
+	state = GPLR(SPITZ_GPIO_SWA) & (GPIO_bit(SPITZ_GPIO_SWA)|GPIO_bit(SPITZ_GPIO_SWB));
+	if (state != sharpsl_hinge_state) {
+		hinge_count = 0;
+		sharpsl_hinge_state = state;
+	} else if (hinge_count < HINGE_STABLE_COUNT) {
+		hinge_count++;
+	}
+
+	if (hinge_count >= HINGE_STABLE_COUNT) {
+		spin_lock_irqsave(&spitzkbd_data->lock, flags);
+
+		input_report_switch(&spitzkbd_data->input, SW_0, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0));
+		input_report_switch(&spitzkbd_data->input, SW_1, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0));
+		input_sync(&spitzkbd_data->input);
+
+		spin_unlock_irqrestore(&spitzkbd_data->lock, flags);
+	} else {
+		mod_timer(&spitzkbd_data->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
+	}
+}
+
+#ifdef CONFIG_PM
+static int spitzkbd_suspend(struct device *dev, pm_message_t state, uint32_t level)
+{
+	if (level == SUSPEND_POWER_DOWN) {
+		int i;
+		struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
+		spitzkbd->suspended = 1;
+
+		/* Set Strobe lines as inputs - *except* strobe line 0 leave this
+		   enabled so we can detect a power button press for resume */
+		for (i = 1; i < SPITZ_KEY_STROBE_NUM; i++)
+			pxa_gpio_mode(spitz_strobes[i] | GPIO_IN);
+	}
+	return 0;
+}
+
+static int spitzkbd_resume(struct device *dev, uint32_t level)
+{
+	if (level == RESUME_POWER_ON) {
+		int i;
+		struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
+
+		for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++)
+			pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH);
+
+		/* Upon resume, ignore the suspend key for a short while */
+		spitzkbd->suspend_jiffies = jiffies;
+		spitzkbd->suspended = 0;
+	}
+	return 0;
+}
+#else
+#define spitzkbd_suspend	NULL
+#define spitzkbd_resume		NULL
+#endif
+
+static int __init spitzkbd_probe(struct device *dev)
+{
+	int i;
+	struct spitzkbd *spitzkbd;
+
+	spitzkbd = kzalloc(sizeof(struct spitzkbd), GFP_KERNEL);
+	if (!spitzkbd)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev,spitzkbd);
+	strcpy(spitzkbd->phys, "spitzkbd/input0");
+
+	spin_lock_init(&spitzkbd->lock);
+
+	/* Init Keyboard rescan timer */
+	init_timer(&spitzkbd->timer);
+	spitzkbd->timer.function = spitzkbd_timer_callback;
+	spitzkbd->timer.data = (unsigned long) spitzkbd;
+
+	/* Init Hinge Timer */
+	init_timer(&spitzkbd->htimer);
+	spitzkbd->htimer.function = spitzkbd_hinge_timer;
+	spitzkbd->htimer.data = (unsigned long) spitzkbd;
+
+	spitzkbd->suspend_jiffies=jiffies;
+
+	init_input_dev(&spitzkbd->input);
+	spitzkbd->input.private = spitzkbd;
+	spitzkbd->input.name = "Spitz Keyboard";
+	spitzkbd->input.dev = dev;
+	spitzkbd->input.phys = spitzkbd->phys;
+	spitzkbd->input.id.bustype = BUS_HOST;
+	spitzkbd->input.id.vendor = 0x0001;
+	spitzkbd->input.id.product = 0x0001;
+	spitzkbd->input.id.version = 0x0100;
+	spitzkbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
+	spitzkbd->input.keycode = spitzkbd->keycode;
+	spitzkbd->input.keycodesize = sizeof(unsigned char);
+	spitzkbd->input.keycodemax = ARRAY_SIZE(spitzkbd_keycode);
+
+	memcpy(spitzkbd->keycode, spitzkbd_keycode, sizeof(spitzkbd->keycode));
+	for (i = 0; i < ARRAY_SIZE(spitzkbd_keycode); i++)
+		set_bit(spitzkbd->keycode[i], spitzkbd->input.keybit);
+	clear_bit(0, spitzkbd->input.keybit);
+	set_bit(SW_0, spitzkbd->input.swbit);
+	set_bit(SW_1, spitzkbd->input.swbit);
+
+	input_register_device(&spitzkbd->input);
+	mod_timer(&spitzkbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
+
+	/* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
+	for (i = 0; i < SPITZ_KEY_SENSE_NUM; i++) {
+		pxa_gpio_mode(spitz_senses[i] | GPIO_IN);
+		if (request_irq(IRQ_GPIO(spitz_senses[i]), spitzkbd_interrupt,
+						SA_INTERRUPT, "Spitzkbd Sense", spitzkbd))
+			printk(KERN_WARNING "spitzkbd: Can't get Sense IRQ: %d!\n", i);
+		else
+			set_irq_type(IRQ_GPIO(spitz_senses[i]),IRQT_RISING);
+	}
+
+	/* Set Strobe lines as outputs - set high */
+	for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++)
+		pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH);
+
+	pxa_gpio_mode(SPITZ_GPIO_SYNC | GPIO_IN);
+	pxa_gpio_mode(SPITZ_GPIO_ON_KEY | GPIO_IN);
+	pxa_gpio_mode(SPITZ_GPIO_SWA | GPIO_IN);
+	pxa_gpio_mode(SPITZ_GPIO_SWB | GPIO_IN);
+
+	request_irq(SPITZ_IRQ_GPIO_SYNC, spitzkbd_interrupt, SA_INTERRUPT, "Spitzkbd Sync", spitzkbd);
+	request_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd_interrupt, SA_INTERRUPT, "Spitzkbd PwrOn", spitzkbd);
+	request_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd_hinge_isr, SA_INTERRUPT, "Spitzkbd SWA", spitzkbd);
+	request_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd_hinge_isr, SA_INTERRUPT, "Spitzkbd SWB", spitzkbd);
+
+	set_irq_type(SPITZ_IRQ_GPIO_SYNC, IRQT_BOTHEDGE);
+	set_irq_type(SPITZ_IRQ_GPIO_ON_KEY, IRQT_BOTHEDGE);
+	set_irq_type(SPITZ_IRQ_GPIO_SWA, IRQT_BOTHEDGE);
+	set_irq_type(SPITZ_IRQ_GPIO_SWB, IRQT_BOTHEDGE);
+
+	printk(KERN_INFO "input: Spitz Keyboard Registered\n");
+
+	return 0;
+}
+
+static int spitzkbd_remove(struct device *dev)
+{
+	int i;
+	struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
+
+	for (i = 0; i < SPITZ_KEY_SENSE_NUM; i++)
+		free_irq(IRQ_GPIO(spitz_senses[i]), spitzkbd);
+
+	free_irq(SPITZ_IRQ_GPIO_SYNC, spitzkbd);
+	free_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd);
+	free_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd);
+	free_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd);
+
+	del_timer_sync(&spitzkbd->htimer);
+	del_timer_sync(&spitzkbd->timer);
+
+	input_unregister_device(&spitzkbd->input);
+
+	kfree(spitzkbd);
+
+	return 0;
+}
+
+static struct device_driver spitzkbd_driver = {
+	.name		= "spitz-keyboard",
+	.bus		= &platform_bus_type,
+	.probe		= spitzkbd_probe,
+	.remove		= spitzkbd_remove,
+	.suspend	= spitzkbd_suspend,
+	.resume		= spitzkbd_resume,
+};
+
+static int __devinit spitzkbd_init(void)
+{
+	return driver_register(&spitzkbd_driver);
+}
+
+static void __exit spitzkbd_exit(void)
+{
+	driver_unregister(&spitzkbd_driver);
+}
+
+module_init(spitzkbd_init);
+module_exit(spitzkbd_exit);
+
+MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
+MODULE_DESCRIPTION("Spitz Keyboard Driver");
+MODULE_LICENSE("GPLv2");
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 0489af5..21d55ed 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -24,17 +24,17 @@
 	  module will be called h3600_ts_input.
 
 config TOUCHSCREEN_CORGI
-	tristate "Corgi touchscreen (for Sharp SL-C7xx)"
+	tristate "SharpSL (Corgi and Spitz series) touchscreen driver"
 	depends on PXA_SHARPSL
 	default y	
 	help
 	  Say Y here to enable the driver for the touchscreen on the 
-	  Sharp SL-C7xx series of PDAs.
+	  Sharp SL-C7xx and SL-Cxx00 series of PDAs.
 
 	  If unsure, say N.
 
 	  To compile this driver as a module, choose M here: the
-	  module will be called ads7846_ts.
+	  module will be called corgi_ts.
 
 config TOUCHSCREEN_GUNZE
 	tristate "Gunze AHL-51S touchscreen"
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c
index 5d19261..4c7fbe5 100644
--- a/drivers/input/touchscreen/corgi_ts.c
+++ b/drivers/input/touchscreen/corgi_ts.c
@@ -1,5 +1,5 @@
 /*
- *  Touchscreen driver for Sharp Corgi models (SL-C7xx)
+ *  Touchscreen driver for Sharp SL-C7xx and SL-Cxx00 models
  *
  *  Copyright (c) 2004-2005 Richard Purdie
  *
@@ -19,7 +19,7 @@
 #include <linux/slab.h>
 #include <asm/irq.h>
 
-#include <asm/arch/corgi.h>
+#include <asm/arch/sharpsl.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/pxa-regs.h>
 
@@ -47,15 +47,20 @@
 	struct ts_event tc;
 	int pendown;
 	int power_mode;
+	int irq_gpio;
+	struct corgits_machinfo *machinfo;
 };
 
-#define STATUS_HSYNC		(GPLR(CORGI_GPIO_HSYNC) & GPIO_bit(CORGI_GPIO_HSYNC))
-
-#define SyncHS()	while((STATUS_HSYNC) == 0); while((STATUS_HSYNC) != 0);
+#ifdef CONFIG_PXA25x
 #define CCNT(a)		asm volatile ("mrc p14, 0, %0, C1, C0, 0" : "=r"(a))
 #define PMNC_GET(x)	asm volatile ("mrc p14, 0, %0, C0, C0, 0" : "=r"(x))
 #define PMNC_SET(x)	asm volatile ("mcr p14, 0, %0, C0, C0, 0" : : "r"(x))
-
+#endif
+#ifdef CONFIG_PXA27x
+#define CCNT(a)		asm volatile ("mrc p14, 0, %0, C1, C1, 0" : "=r"(a))
+#define PMNC_GET(x)	asm volatile ("mrc p14, 0, %0, C0, C1, 0" : "=r"(x))
+#define PMNC_SET(x)	asm volatile ("mcr p14, 0, %0, C0, C1, 0" : : "r"(x))
+#endif
 
 /* ADS7846 Touch Screen Controller bit definitions */
 #define ADSCTRL_PD0		(1u << 0)	/* PD0 */
@@ -66,12 +71,11 @@
 #define ADSCTRL_STS		(1u << 7)	/* Start Bit */
 
 /* External Functions */
-extern unsigned long w100fb_get_hsynclen(struct device *dev);
 extern unsigned int get_clk_frequency_khz(int info);
 
-static unsigned long calc_waittime(void)
+static unsigned long calc_waittime(struct corgi_ts *corgi_ts)
 {
-	unsigned long hsync_len = w100fb_get_hsynclen(&corgifb_device.dev);
+	unsigned long hsync_len = corgi_ts->machinfo->get_hsync_len();
 
 	if (hsync_len)
 		return get_clk_frequency_khz(0)*1000/hsync_len;
@@ -79,7 +83,8 @@
 		return 0;
 }
 
-static int sync_receive_data_send_cmd(int doRecive, int doSend, unsigned int address, unsigned long wait_time)
+static int sync_receive_data_send_cmd(struct corgi_ts *corgi_ts, int doRecive, int doSend,
+		unsigned int address, unsigned long wait_time)
 {
 	unsigned long timer1 = 0, timer2, pmnc = 0;
 	int pos = 0;
@@ -90,7 +95,7 @@
 			PMNC_SET(0x01);
 
 		/* polling HSync */
-		SyncHS();
+		corgi_ts->machinfo->wait_hsync();
 		/* get CCNT */
 		CCNT(timer1);
 	}
@@ -109,7 +114,7 @@
 			CCNT(timer2);
 			if (timer2-timer1 > wait_time) {
 				/* too slow - timeout, try again */
-				SyncHS();
+				corgi_ts->machinfo->wait_hsync();
 				/* get OSCR */
 				CCNT(timer1);
 				/* Wait after HSync */
@@ -133,23 +138,23 @@
 	/* critical section */
 	local_irq_save(flags);
 	corgi_ssp_ads7846_lock();
-	wait_time=calc_waittime();
+	wait_time = calc_waittime(corgi_ts);
 
 	/* Y-axis */
-	sync_receive_data_send_cmd(0, 1, 1u, wait_time);
+	sync_receive_data_send_cmd(corgi_ts, 0, 1, 1u, wait_time);
 
 	/* Y-axis */
-	sync_receive_data_send_cmd(1, 1, 1u, wait_time);
+	sync_receive_data_send_cmd(corgi_ts, 1, 1, 1u, wait_time);
 
 	/* X-axis */
-	y = sync_receive_data_send_cmd(1, 1, 5u, wait_time);
+	y = sync_receive_data_send_cmd(corgi_ts, 1, 1, 5u, wait_time);
 
 	/* Z1 */
-	x = sync_receive_data_send_cmd(1, 1, 3u, wait_time);
+	x = sync_receive_data_send_cmd(corgi_ts, 1, 1, 3u, wait_time);
 
 	/* Z2 */
-	z1 = sync_receive_data_send_cmd(1, 1, 4u, wait_time);
-	z2 = sync_receive_data_send_cmd(1, 0, 4u, wait_time);
+	z1 = sync_receive_data_send_cmd(corgi_ts, 1, 1, 4u, wait_time);
+	z2 = sync_receive_data_send_cmd(corgi_ts, 1, 0, 4u, wait_time);
 
 	/* Power-Down Enable */
 	corgi_ssp_ads7846_put((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
@@ -189,9 +194,9 @@
 
 static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer, struct pt_regs *regs)
 {
-	if ((GPLR(CORGI_GPIO_TP_INT) & GPIO_bit(CORGI_GPIO_TP_INT)) == 0) {
+	if ((GPLR(IRQ_TO_GPIO(corgi_ts->irq_gpio)) & GPIO_bit(IRQ_TO_GPIO(corgi_ts->irq_gpio))) == 0) {
 		/* Disable Interrupt */
-		set_irq_type(CORGI_IRQ_GPIO_TP_INT, IRQT_NOEDGE);
+		set_irq_type(corgi_ts->irq_gpio, IRQT_NOEDGE);
 		if (read_xydata(corgi_ts)) {
 			corgi_ts->pendown = 1;
 			new_data(corgi_ts, regs);
@@ -210,7 +215,7 @@
 		}
 
 		/* Enable Falling Edge */
-		set_irq_type(CORGI_IRQ_GPIO_TP_INT, IRQT_FALLING);
+		set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING);
 		corgi_ts->pendown = 0;
 	}
 }
@@ -254,7 +259,7 @@
 
 		corgi_ssp_ads7846_putget((4u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
 		/* Enable Falling Edge */
-		set_irq_type(CORGI_IRQ_GPIO_TP_INT, IRQT_FALLING);
+		set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING);
 		corgi_ts->power_mode = PWR_MODE_ACTIVE;
 	}
 	return 0;
@@ -267,6 +272,7 @@
 static int __init corgits_probe(struct device *dev)
 {
 	struct corgi_ts *corgi_ts;
+	struct platform_device *pdev = to_platform_device(dev);
 
 	if (!(corgi_ts = kmalloc(sizeof(struct corgi_ts), GFP_KERNEL)))
 		return -ENOMEM;
@@ -275,6 +281,14 @@
 
 	memset(corgi_ts, 0, sizeof(struct corgi_ts));
 
+	corgi_ts->machinfo = dev->platform_data;
+	corgi_ts->irq_gpio = platform_get_irq(pdev, 0);
+
+	if (corgi_ts->irq_gpio < 0) {
+		kfree(corgi_ts);
+		return -ENODEV;
+	}
+
 	init_input_dev(&corgi_ts->input);
 	corgi_ts->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 	corgi_ts->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
@@ -293,8 +307,7 @@
 	corgi_ts->input.id.product = 0x0002;
 	corgi_ts->input.id.version = 0x0100;
 
-	pxa_gpio_mode(CORGI_GPIO_TP_INT | GPIO_IN);
-	pxa_gpio_mode(CORGI_GPIO_HSYNC | GPIO_IN);
+	pxa_gpio_mode(IRQ_TO_GPIO(corgi_ts->irq_gpio) | GPIO_IN);
 
 	/* Initiaize ADS7846 Difference Reference mode */
 	corgi_ssp_ads7846_putget((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
@@ -313,14 +326,14 @@
 	input_register_device(&corgi_ts->input);
 	corgi_ts->power_mode = PWR_MODE_ACTIVE;
 
-	if (request_irq(CORGI_IRQ_GPIO_TP_INT, ts_interrupt, SA_INTERRUPT, "ts", corgi_ts)) {
+	if (request_irq(corgi_ts->irq_gpio, ts_interrupt, SA_INTERRUPT, "ts", corgi_ts)) {
 		input_unregister_device(&corgi_ts->input);
 		kfree(corgi_ts);
 		return -EBUSY;
 	}
 
 	/* Enable Falling Edge */
-	set_irq_type(CORGI_IRQ_GPIO_TP_INT, IRQT_FALLING);
+	set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING);
 
 	printk(KERN_INFO "input: Corgi Touchscreen Registered\n");
 
@@ -331,8 +344,9 @@
 {
 	struct corgi_ts *corgi_ts = dev_get_drvdata(dev);
 
-	free_irq(CORGI_IRQ_GPIO_TP_INT, NULL);
+	free_irq(corgi_ts->irq_gpio, NULL);
 	del_timer_sync(&corgi_ts->timer);
+	corgi_ts->machinfo->put_hsync();
 	input_unregister_device(&corgi_ts->input);
 	kfree(corgi_ts);
 	return 0;
diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c
index 40b0df0..1ebed04 100644
--- a/drivers/isdn/sc/init.c
+++ b/drivers/isdn/sc/init.c
@@ -87,7 +87,7 @@
 			 */
 			for (i = 0 ; i < MAX_IO_REGS - 1 ; i++) {
 				if(!request_region(io[b] + i * 0x400, 1, "sc test")) {
-					pr_debug("check_region for 0x%x failed\n", io[b] + i * 0x400);
+					pr_debug("request_region for 0x%x failed\n", io[b] + i * 0x400);
 					io[b] = 0;
 					break;
 				} else
@@ -181,7 +181,7 @@
 			for (i = SRAM_MIN ; i < SRAM_MAX ; i += SRAM_PAGESIZE) {
 				pr_debug("Checking RAM address 0x%x...\n", i);
 				if(request_region(i, SRAM_PAGESIZE, "sc test")) {
-					pr_debug("  check_region succeeded\n");
+					pr_debug("  request_region succeeded\n");
 					model = identify_board(i, io[b]);
 					release_region(i, SRAM_PAGESIZE);
 					if (model >= 0) {
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index 8b4ad70..877c770 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -29,7 +29,7 @@
 
 #include <linux/module.h>	/* Modules 			*/
 #include <linux/init.h>		/* Initdata			*/
-#include <linux/ioport.h>	/* check_region, request_region	*/
+#include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* udelay			*/
 #include <asm/io.h>		/* outb, outb_p			*/
 #include <asm/uaccess.h>	/* copy to/from user		*/
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index 013c835..5319a9c 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -26,7 +26,7 @@
 
 #include <linux/module.h>	/* Modules 			*/
 #include <linux/init.h>		/* Initdata			*/
-#include <linux/ioport.h>	/* check_region, request_region	*/
+#include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* udelay			*/
 #include <asm/io.h>		/* outb, outb_p			*/
 #include <asm/uaccess.h>	/* copy to/from user		*/
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index 53d399b..022913d 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -29,7 +29,7 @@
 
 #include <linux/module.h>	/* Modules 			*/
 #include <linux/init.h>		/* Initdata			*/
-#include <linux/ioport.h>	/* check_region, request_region	*/
+#include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* udelay			*/
 #include <asm/io.h>		/* outb, outb_p			*/
 #include <asm/uaccess.h>	/* copy to/from user		*/
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 202bfe6..6418f03 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -17,7 +17,7 @@
 
 #include <linux/module.h>	/* Modules 			*/
 #include <linux/init.h>		/* Initdata			*/
-#include <linux/ioport.h>	/* check_region, request_region	*/
+#include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* udelay			*/
 #include <asm/io.h>		/* outb, outb_p			*/
 #include <asm/uaccess.h>	/* copy to/from user		*/
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index c00245d..b2256d6 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -10,7 +10,7 @@
 
 #include <linux/module.h>	/* Modules 			*/
 #include <linux/init.h>		/* Initdata			*/
-#include <linux/ioport.h>	/* check_region, request_region	*/
+#include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* udelay			*/
 #include <asm/io.h>		/* outb, outb_p			*/
 #include <asm/uaccess.h>	/* copy to/from user		*/
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 3a464a0..6f03ce4 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -18,7 +18,7 @@
 #include <linux/kernel.h>	/* __setup			*/
 #include <linux/module.h>	/* Modules 			*/
 #include <linux/init.h>		/* Initdata			*/
-#include <linux/ioport.h>	/* check_region, request_region	*/
+#include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* udelay			*/
 #include <linux/videodev.h>	/* kernel radio structs		*/
 #include <linux/isapnp.h>
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index 0732efd..71971e9 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -14,7 +14,7 @@
 
 #include <linux/module.h>	/* Modules 			*/
 #include <linux/init.h>		/* Initdata			*/
-#include <linux/ioport.h>	/* check_region, request_region	*/
+#include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* udelay			*/
 #include <asm/io.h>		/* outb, outb_p			*/
 #include <asm/uaccess.h>	/* copy to/from user		*/
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index 248d67f..b03573c 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -25,7 +25,7 @@
 
 #include <linux/module.h>	/* Modules 			*/
 #include <linux/init.h>		/* Initdata			*/
-#include <linux/ioport.h>	/* check_region, request_region	*/
+#include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* udelay			*/
 #include <asm/io.h>		/* outb, outb_p			*/
 #include <asm/uaccess.h>	/* copy to/from user		*/
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
index d7da901..f304f3c 100644
--- a/drivers/media/radio/radio-typhoon.c
+++ b/drivers/media/radio/radio-typhoon.c
@@ -31,7 +31,7 @@
 
 #include <linux/module.h>	/* Modules                        */
 #include <linux/init.h>		/* Initdata                       */
-#include <linux/ioport.h>	/* check_region, request_region   */
+#include <linux/ioport.h>	/* request_region		  */
 #include <linux/proc_fs.h>	/* radio card status report	  */
 #include <asm/io.h>		/* outb, outb_p                   */
 #include <asm/uaccess.h>	/* copy to/from user              */
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index 342f92d..4c6d6fb 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -28,7 +28,7 @@
 
 #include <linux/module.h>	/* Modules                        */
 #include <linux/init.h>		/* Initdata                       */
-#include <linux/ioport.h>	/* check_region, request_region   */
+#include <linux/ioport.h>	/* request_region		  */
 #include <linux/delay.h>	/* udelay, msleep                 */
 #include <asm/io.h>		/* outb, outb_p                   */
 #include <asm/uaccess.h>	/* copy to/from user              */
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index c9106b1..4334744 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -221,9 +221,7 @@
 	int err;
 
 	/* Put the analog decoder in standby to keep it quiet */
-	if (core->tda9887_conf) {
-		cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
-	}
+	cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
 
 	dvb_pll_configure(core->pll_desc, buf, params->frequency, 0);
 	dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
@@ -402,6 +400,9 @@
 		dev->dvb.frontend->ops->info.frequency_max = dev->core->pll_desc->max;
 	}
 
+	/* Put the analog decoder in standby to keep it quiet */
+	cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
+
 	/* register everything */
 	return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
 }
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 54fff9c..96f14ab 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1951,7 +1951,7 @@
 	---help---
 	  This driver support the Marvell Yukon or SysKonnect SK-98xx/SK-95xx
 	  and related Gigabit Ethernet adapters. It is a new smaller driver
-	  driver with better performance and more complete ethtool support.
+	  with better performance and more complete ethtool support.
 
 	  It does not support the link failover and network management 
 	  features that "portable" vendor supplied sk98lin driver does.
diff --git a/drivers/net/arcnet/com90io.c b/drivers/net/arcnet/com90io.c
index 52c77cb..1f03027 100644
--- a/drivers/net/arcnet/com90io.c
+++ b/drivers/net/arcnet/com90io.c
@@ -160,7 +160,7 @@
 		return -ENODEV;
 	}
 	if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "com90io probe")) {
-		BUGMSG(D_INIT_REASONS, "IO check_region %x-%x failed.\n",
+		BUGMSG(D_INIT_REASONS, "IO request_region %x-%x failed.\n",
 		       ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
 		return -ENXIO;
 	}
@@ -242,7 +242,7 @@
 		BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
 		return -ENODEV;
 	}
-	/* Reserve the I/O region - guaranteed to work by check_region */
+	/* Reserve the I/O region */
 	if (!request_region(dev->base_addr, ARCNET_TOTAL_SIZE, "arcnet (COM90xx-IO)")) {
 		free_irq(dev->irq, dev);
 		return -EBUSY;
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 25cc20e..fbf1c06 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1387,13 +1387,13 @@
 		ns->collisions += nic->tx_collisions;
 		ns->tx_errors += le32_to_cpu(s->tx_max_collisions) +
 			le32_to_cpu(s->tx_lost_crs);
-		ns->rx_dropped += le32_to_cpu(s->rx_resource_errors);
 		ns->rx_length_errors += le32_to_cpu(s->rx_short_frame_errors) +
 			nic->rx_over_length_errors;
 		ns->rx_crc_errors += le32_to_cpu(s->rx_crc_errors);
 		ns->rx_frame_errors += le32_to_cpu(s->rx_alignment_errors);
 		ns->rx_over_errors += le32_to_cpu(s->rx_overrun_errors);
 		ns->rx_fifo_errors += le32_to_cpu(s->rx_overrun_errors);
+		ns->rx_missed_errors += le32_to_cpu(s->rx_resource_errors);
 		ns->rx_errors += le32_to_cpu(s->rx_crc_errors) +
 			le32_to_cpu(s->rx_alignment_errors) +
 			le32_to_cpu(s->rx_short_frame_errors) +
@@ -1727,12 +1727,10 @@
 
 	if(unlikely(!(rfd_status & cb_ok))) {
 		/* Don't indicate if hardware indicates errors */
-		nic->net_stats.rx_dropped++;
 		dev_kfree_skb_any(skb);
 	} else if(actual_size > ETH_DATA_LEN + VLAN_ETH_HLEN) {
 		/* Don't indicate oversized frames */
 		nic->rx_over_length_errors++;
-		nic->net_stats.rx_dropped++;
 		dev_kfree_skb_any(skb);
 	} else {
 		nic->net_stats.rx_packets++;
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 7c8a0a2..ee687c9 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -2544,7 +2544,6 @@
 		adapter->stats.crcerrs + adapter->stats.algnerrc +
 		adapter->stats.rlec + adapter->stats.mpc + 
 		adapter->stats.cexterr;
-	adapter->net_stats.rx_dropped = adapter->stats.mpc;
 	adapter->net_stats.rx_length_errors = adapter->stats.rlec;
 	adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
 	adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 5c55537..89d6d69 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -1616,8 +1616,6 @@
 	    adapter->stats.icbc +
 	    adapter->stats.ecbc + adapter->stats.mpc;
 
-	adapter->net_stats.rx_dropped = adapter->stats.mpc;
-
 	/* see above
 	 * adapter->net_stats.rx_length_errors = adapter->stats.rlec;
 	 */
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index c829e6a..dd451e0 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -428,7 +428,7 @@
 				DBG_PRINT(INIT_DBG, 
 				"%s: Zero DMA address for TxDL. ", dev->name);
 				DBG_PRINT(INIT_DBG, 
-				"Virtual address %llx\n", (u64)tmp_v);
+				"Virtual address %p\n", tmp_v);
 				tmp_v = pci_alloc_consistent(nic->pdev,
 						     PAGE_SIZE, &tmp_p);
 				if (!tmp_v) {
@@ -657,9 +657,10 @@
 					    mac_control->zerodma_virt_addr,
 					    (dma_addr_t)0);
 			DBG_PRINT(INIT_DBG, 
-			"%s: Freeing TxDL with zero DMA addr. ", dev->name);
-			DBG_PRINT(INIT_DBG, "Virtual address %llx\n",
-			(u64)(mac_control->zerodma_virt_addr));
+			  	"%s: Freeing TxDL with zero DMA addr. ",
+				dev->name);
+			DBG_PRINT(INIT_DBG, "Virtual address %p\n",
+				mac_control->zerodma_virt_addr);
 		}
 		kfree(mac_control->fifos[i].list_info);
 	}
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
index 6ee4771..2e72d79 100644
--- a/drivers/net/sk98lin/skge.c
+++ b/drivers/net/sk98lin/skge.c
@@ -5216,17 +5216,15 @@
 	{ PCI_VENDOR_ID_3COM, 0x80eb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ PCI_VENDOR_ID_SYSKONNECT, 0x4300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ PCI_VENDOR_ID_SYSKONNECT, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-	{ PCI_VENDOR_ID_DLINK, 0x4c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+/* DLink card does not have valid VPD so this driver gags
+ *	{ PCI_VENDOR_ID_DLINK, 0x4c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ */
 	{ PCI_VENDOR_ID_MARVELL, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-#if 0	/* don't handle Yukon2 cards at the moment -- mlindner@syskonnect.de */
-	{ PCI_VENDOR_ID_MARVELL, 0x4360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-	{ PCI_VENDOR_ID_MARVELL, 0x4361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-#endif
 	{ PCI_VENDOR_ID_MARVELL, 0x5005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ PCI_VENDOR_ID_CNET, 0x434e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-	{ PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0015, },
 	{ PCI_VENDOR_ID_LINKSYS, 0x1064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-	{ 0, }
+	{ 0 }
 };
 
 MODULE_DEVICE_TABLE(pci, skge_pci_tbl);
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index d7c9851..0208258 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -42,7 +42,7 @@
 #include "skge.h"
 
 #define DRV_NAME		"skge"
-#define DRV_VERSION		"0.9"
+#define DRV_VERSION		"1.0"
 #define PFX			DRV_NAME " "
 
 #define DEFAULT_TX_RING_SIZE	128
@@ -669,7 +669,7 @@
 				     PHY_M_LED_BLINK_RT(BLINK_84MS) |
 				     PHY_M_LEDC_TX_CTRL |
 				     PHY_M_LEDC_DP_CTRL);
-		
+
 			gm_phy_write(hw, port, PHY_MARV_LED_OVER,
 				     PHY_M_LED_MO_RX(MO_LED_OFF) |
 				     (skge->speed == SPEED_100 ?
@@ -876,7 +876,7 @@
 
 static void skge_link_up(struct skge_port *skge)
 {
-	skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), 
+	skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG),
 		    LED_BLK_OFF|LED_SYNC_OFF|LED_ON);
 
 	netif_carrier_on(skge->netdev);
@@ -987,6 +987,8 @@
 {
 	const u8 zero[8]  = { 0 };
 
+	skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
+
 	/* reset the statistics module */
 	xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT);
 	xm_write16(hw, port, XM_IMSK, 0xffff);	/* disable XMAC IRQs */
@@ -1021,8 +1023,6 @@
 	(void) xm_phy_read(hw, port, PHY_BCOM_STAT);
 	status = xm_phy_read(hw, port, PHY_BCOM_STAT);
 
-	pr_debug("bcom_check_link status=0x%x\n", status);
-
 	if ((status & PHY_ST_LSYNC) == 0) {
 		u16 cmd = xm_read16(hw, port, XM_MMU_CMD);
 		cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
@@ -1106,8 +1106,6 @@
 		{ 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 },
 	};
 
-	pr_debug("bcom_phy_init\n");
-
 	/* read Id from external PHY (all have the same address) */
 	id1 = xm_phy_read(hw, port, PHY_XMAC_ID1);
 
@@ -1340,6 +1338,8 @@
 	int port = skge->port;
 	u32 reg;
 
+	genesis_reset(hw, port);
+
 	/* Clear Tx packet arbiter timeout IRQ */
 	skge_write16(hw, B3_PA_CTRL,
 		     port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2);
@@ -1465,7 +1465,6 @@
 	u16 cmd;
 	u32 mode, msk;
 
-	pr_debug("genesis_link_up\n");
 	cmd = xm_read16(hw, port, XM_MMU_CMD);
 
 	/*
@@ -1578,7 +1577,6 @@
 	struct skge_port *skge = netdev_priv(hw->dev[port]);
 	u16 ctrl, ct1000, adv;
 
-	pr_debug("yukon_init\n");
 	if (skge->autoneg == AUTONEG_ENABLE) {
 		u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
 
@@ -1677,9 +1675,11 @@
 
 	/* WA code for COMA mode -- set PHY reset */
 	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
-	    hw->chip_rev >= CHIP_REV_YU_LITE_A3)
-		skge_write32(hw, B2_GP_IO,
-			     (skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9));
+	    hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
+		reg = skge_read32(hw, B2_GP_IO);
+		reg |= GP_DIR_9 | GP_IO_9;
+		skge_write32(hw, B2_GP_IO, reg);
+	}
 
 	/* hard reset */
 	skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
@@ -1687,10 +1687,12 @@
 
 	/* WA code for COMA mode -- clear PHY reset */
 	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
-	    hw->chip_rev >= CHIP_REV_YU_LITE_A3)
-		skge_write32(hw, B2_GP_IO,
-			     (skge_read32(hw, B2_GP_IO) | GP_DIR_9)
-			     & ~GP_IO_9);
+	    hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
+		reg = skge_read32(hw, B2_GP_IO);
+		reg |= GP_DIR_9;
+		reg &= ~GP_IO_9;
+		skge_write32(hw, B2_GP_IO, reg);
+	}
 
 	/* Set hardware config mode */
 	reg = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
@@ -1729,7 +1731,7 @@
 	}
 
 	gma_write16(hw, port, GM_GP_CTRL, reg);
-	skge_read16(hw, GMAC_IRQ_SRC);
+	skge_read16(hw, SK_REG(port, GMAC_IRQ_SRC));
 
 	yukon_init(hw, port);
 
@@ -1801,20 +1803,26 @@
 	struct skge_hw *hw = skge->hw;
 	int port = skge->port;
 
-	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
-	    hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
-		skge_write32(hw, B2_GP_IO,
-			     skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9);
-	}
+	skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
+	yukon_reset(hw, port);
 
 	gma_write16(hw, port, GM_GP_CTRL,
 			 gma_read16(hw, port, GM_GP_CTRL)
 			 & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA));
 	gma_read16(hw, port, GM_GP_CTRL);
 
+	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
+	    hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
+		u32 io = skge_read32(hw, B2_GP_IO);
+
+		io |= GP_DIR_9 | GP_IO_9;
+		skge_write32(hw, B2_GP_IO, io);
+		skge_read32(hw, B2_GP_IO);
+	}
+
 	/* set GPHY Control reset */
-	skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
-	skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
+	skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
+	skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
 }
 
 static void yukon_get_stats(struct skge_port *skge, u64 *data)
@@ -1873,10 +1881,8 @@
 	int port = skge->port;
 	u16 reg;
 
-	pr_debug("yukon_link_up\n");
-
 	/* Enable Transmit FIFO Underrun */
-	skge_write8(hw, GMAC_IRQ_MSK, GMAC_DEF_MSK);
+	skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK);
 
 	reg = gma_read16(hw, port, GM_GP_CTRL);
 	if (skge->duplex == DUPLEX_FULL || skge->autoneg == AUTONEG_ENABLE)
@@ -1896,7 +1902,6 @@
 	int port = skge->port;
 	u16 ctrl;
 
-	pr_debug("yukon_link_down\n");
 	gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
 
 	ctrl = gma_read16(hw, port, GM_GP_CTRL);
@@ -2112,7 +2117,6 @@
 	skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F);
 	skge_led(skge, LED_MODE_ON);
 
-	pr_debug("skge_up completed\n");
 	return 0;
 
  free_rx_ring:
@@ -2135,15 +2139,20 @@
 
 	netif_stop_queue(dev);
 
+	skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF);
+	if (hw->chip_id == CHIP_ID_GENESIS)
+		genesis_stop(skge);
+	else
+		yukon_stop(skge);
+
+	hw->intr_mask &= ~portirqmask[skge->port];
+	skge_write32(hw, B0_IMSK, hw->intr_mask);
+
 	/* Stop transmitter */
 	skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP);
 	skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
 		     RB_RST_SET|RB_DIS_OP_MD);
 
-	if (hw->chip_id == CHIP_ID_GENESIS)
-		genesis_stop(skge);
-	else
-		yukon_stop(skge);
 
 	/* Disable Force Sync bit and Enable Alloc bit */
 	skge_write8(hw, SK_REG(port, TXA_CTRL),
@@ -2367,8 +2376,6 @@
 	u32 mode;
 	u8 filter[8];
 
-	pr_debug("genesis_set_multicast flags=%x count=%d\n", dev->flags, dev->mc_count);
-
 	mode = xm_read32(hw, port, XM_MODE);
 	mode |= XM_MD_ENA_HASH;
 	if (dev->flags & IFF_PROMISC)
@@ -2530,8 +2537,6 @@
 	unsigned int to_do = min(dev->quota, *budget);
 	unsigned int work_done = 0;
 
-	pr_debug("skge_poll\n");
-
 	for (e = ring->to_clean; work_done < to_do; e = e->next) {
 		struct skge_rx_desc *rd = e->desc;
 		struct sk_buff *skb;
@@ -2672,9 +2677,9 @@
 	if (hw->chip_id == CHIP_ID_GENESIS) {
 		/* clear xmac errors */
 		if (hwstatus & (IS_NO_STAT_M1|IS_NO_TIST_M1))
-			skge_write16(hw, SK_REG(0, RX_MFF_CTRL1), MFF_CLR_INSTAT);
+			skge_write16(hw, RX_MFF_CTRL1, MFF_CLR_INSTAT);
 		if (hwstatus & (IS_NO_STAT_M2|IS_NO_TIST_M2))
-			skge_write16(hw, SK_REG(0, RX_MFF_CTRL2), MFF_CLR_INSTAT);
+			skge_write16(hw, RX_MFF_CTRL2, MFF_CLR_INSTAT);
 	} else {
 		/* Timestamp (unused) overflow */
 		if (hwstatus & IS_IRQ_TIST_OV)
@@ -3000,9 +3005,6 @@
 
 	skge_write32(hw, B0_IMSK, hw->intr_mask);
 
-	if (hw->chip_id != CHIP_ID_GENESIS)
-		skge_write8(hw, GMAC_IRQ_MSK, 0);
-
 	spin_lock_bh(&hw->phy_lock);
 	for (i = 0; i < hw->ports; i++) {
 		if (hw->chip_id == CHIP_ID_GENESIS)
@@ -3230,6 +3232,11 @@
 	dev0 = hw->dev[0];
 	unregister_netdev(dev0);
 
+	skge_write32(hw, B0_IMSK, 0);
+	skge_write16(hw, B0_LED, LED_STAT_OFF);
+	skge_pci_clear(hw);
+	skge_write8(hw, B0_CTST, CS_RST_SET);
+
 	tasklet_kill(&hw->ext_tasklet);
 
 	free_irq(pdev->irq, hw);
@@ -3238,7 +3245,7 @@
 	if (dev1)
 		free_netdev(dev1);
 	free_netdev(dev0);
-	skge_write16(hw, B0_LED, LED_STAT_OFF);
+
 	iounmap(hw->regs);
 	kfree(hw);
 	pci_set_drvdata(pdev, NULL);
@@ -3257,7 +3264,10 @@
 			struct skge_port *skge = netdev_priv(dev);
 			if (netif_running(dev)) {
 				netif_carrier_off(dev);
-				skge_down(dev);
+				if (skge->wol)
+					netif_stop_queue(dev);
+				else
+					skge_down(dev);
 			}
 			netif_device_detach(dev);
 			wol |= skge->wol;
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index f1680be..efbf98c 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -2008,7 +2008,7 @@
 	GM_IS_RX_FF_OR	= 1<<1,	/* Receive FIFO Overrun */
 	GM_IS_RX_COMPL	= 1<<0,	/* Frame Reception Complete */
 
-#define GMAC_DEF_MSK	(GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | GM_IS_TX_FF_UR)
+#define GMAC_DEF_MSK	(GM_IS_RX_FF_OR | GM_IS_TX_FF_UR)
 
 /*	GMAC_LINK_CTRL	16 bit	GMAC Link Control Reg (YUKON only) */
 						/* Bits 15.. 2:	reserved */
diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c
index 26cc4f6..60d1e05 100644
--- a/drivers/net/tulip/xircom_cb.c
+++ b/drivers/net/tulip/xircom_cb.c
@@ -117,7 +117,7 @@
 static int xircom_close(struct net_device *dev);
 static void xircom_up(struct xircom_private *card);
 static struct net_device_stats *xircom_get_stats(struct net_device *dev);
-#if CONFIG_NET_POLL_CONTROLLER
+#ifdef CONFIG_NET_POLL_CONTROLLER
 static void xircom_poll_controller(struct net_device *dev);
 #endif
 
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 2be65d3..06998c2 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -6852,7 +6852,10 @@
 	/* Add frequency */
 	iwe.cmd = SIOCGIWFREQ;
 	iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
-	iwe.u.freq.m = frequency_list[iwe.u.freq.m] * 100000;
+	/* iwe.u.freq.m containt the channel (starting 1), our 
+	 * frequency_list array start at index 0...
+	 */
+	iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000;
 	iwe.u.freq.e = 1;
 	current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
 
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index d1fb1ba..bedd7f9f 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -629,6 +629,7 @@
 	PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90),
 	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584),
 	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9),
+	PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae),
 	PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac),
 	PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab),
 	PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3),
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 992db89..259d247 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -309,17 +309,25 @@
 
 	pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr);
 
-	/* If we're in D3, force entire word to 0.
+	/* If we're (effectively) in D3, force entire word to 0.
 	 * This doesn't affect PME_Status, disables PME_En, and
 	 * sets PowerState to 0.
 	 */
-	if (dev->current_state >= PCI_D3hot) {
-		if (!(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
+	switch (dev->current_state) {
+	case PCI_UNKNOWN: /* Boot-up */
+		if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
+		 && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
 			need_restore = 1;
+		/* Fall-through: force to D0 */
+	case PCI_D3hot:
+	case PCI_D3cold:
+	case PCI_POWER_ERROR:
 		pmcsr = 0;
-	} else {
+		break;
+	default:
 		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
 		pmcsr |= state;
+		break;
 	}
 
 	/* enter specified state */
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index 39ba640..80969f7 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -376,6 +376,7 @@
     socket_t i = iminor(inode);
     struct pcmcia_socket *s;
     user_info_t *user;
+    static int warning_printed = 0;
 
     ds_dbg(0, "ds_open(socket %d)\n", i);
 
@@ -407,6 +408,17 @@
     s->user = user;
     file->private_data = user;
 
+    if (!warning_printed) {
+	    printk(KERN_INFO "pcmcia: Detected deprecated PCMCIA ioctl "
+			"usage.\n");
+	    printk(KERN_INFO "pcmcia: This interface will soon be removed from "
+			"the kernel; please expect breakage unless you upgrade "
+			"to new tools.\n");
+	    printk(KERN_INFO "pcmcia: see http://www.kernel.org/pub/linux/"
+			"utils/kernel/pcmcia/pcmcia.html for details.\n");
+	    warning_printed = 1;
+    }
+
     if (s->pcmcia_state.present)
 	queue_event(user, CS_EVENT_CARD_INSERTION);
     return 0;
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index f0997c3..ba4d78e 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -1045,7 +1045,18 @@
 {
 	struct yenta_socket *socket;
 	int ret;
-	
+
+	/*
+	 * If we failed to assign proper bus numbers for this cardbus
+	 * controller during PCI probe, its subordinate pci_bus is NULL.
+	 * Bail out if so.
+	 */
+	if (!dev->subordinate) {
+		printk(KERN_ERR "Yenta: no bus associated with %s! "
+			"(try 'pci=assign-busses')\n", pci_name(dev));
+		return -ENODEV;
+	}
+
 	socket = kmalloc(sizeof(struct yenta_socket), GFP_KERNEL);
 	if (!socket)
 		return -ENOMEM;
diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
index 96ca863..0db4f57 100644
--- a/drivers/s390/net/ctcmain.c
+++ b/drivers/s390/net/ctcmain.c
@@ -1,5 +1,5 @@
 /*
- * $Id: ctcmain.c,v 1.74 2005/03/24 09:04:17 mschwide Exp $
+ * $Id: ctcmain.c,v 1.78 2005/09/07 12:18:02 pavlic Exp $
  *
  * CTC / ESCON network driver
  *
@@ -37,10 +37,9 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.74 $
+ * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.78 $
  *
  */
-
 #undef DEBUG
 #include <linux/module.h>
 #include <linux/init.h>
@@ -135,7 +134,7 @@
 	"TX down",
 	"Restart",
 };
-
+
 /**
  * Events of the channel statemachine
  */
@@ -249,7 +248,7 @@
 print_banner(void)
 {
 	static int printed = 0;
-	char vbuf[] = "$Revision: 1.74 $";
+	char vbuf[] = "$Revision: 1.78 $";
 	char *version = vbuf;
 
 	if (printed)
@@ -334,7 +333,7 @@
 	"Restarting",
 	"Not operational",
 };
-
+
 #ifdef DEBUG
 /**
  * Dump header and first 16 bytes of an sk_buff for debugging purposes.
@@ -671,7 +670,7 @@
 fsm_action_nop(fsm_instance * fi, int event, void *arg)
 {
 }
-
+
 /**
  * Actions for channel - statemachines.
  *****************************************************************************/
@@ -1514,7 +1513,6 @@
  	fsm_addtimer(&privptr->restart_timer, 1000, DEV_EVENT_RESTART, dev);
 }
 
-
 /**
  * The statemachine for a channel.
  */
@@ -1625,7 +1623,7 @@
 };
 
 static const int CH_FSM_LEN = sizeof (ch_fsm) / sizeof (fsm_node);
-
+
 /**
  * Functions related to setup and device detection.
  *****************************************************************************/
@@ -1976,7 +1974,7 @@
 		fsm_event(ch->fsm, CH_EVENT_IRQ, ch);
 
 }
-
+
 /**
  * Actions for interface - statemachine.
  *****************************************************************************/
@@ -2209,13 +2207,18 @@
 	int rc = 0;
 
 	DBF_TEXT(trace, 5, __FUNCTION__);
+	/* we need to acquire the lock for testing the state
+	 * otherwise we can have an IRQ changing the state to 
+	 * TXIDLE after the test but before acquiring the lock.
+	 */
+	spin_lock_irqsave(&ch->collect_lock, saveflags);
 	if (fsm_getstate(ch->fsm) != CH_STATE_TXIDLE) {
 		int l = skb->len + LL_HEADER_LENGTH;
 
-		spin_lock_irqsave(&ch->collect_lock, saveflags);
-		if (ch->collect_len + l > ch->max_bufsize - 2)
-			rc = -EBUSY;
-		else {
+		if (ch->collect_len + l > ch->max_bufsize - 2) {
+			spin_unlock_irqrestore(&ch->collect_lock, saveflags);
+			return -EBUSY;
+		} else {
 			atomic_inc(&skb->users);
 			header.length = l;
 			header.type = skb->protocol;
@@ -2231,7 +2234,7 @@
 		int ccw_idx;
 		struct sk_buff *nskb;
 		unsigned long hi;
-
+		spin_unlock_irqrestore(&ch->collect_lock, saveflags);
 		/**
 		 * Protect skb against beeing free'd by upper
 		 * layers.
@@ -2256,6 +2259,7 @@
 			if (!nskb) {
 				atomic_dec(&skb->users);
 				skb_pull(skb, LL_HEADER_LENGTH + 2);
+				ctc_clear_busy(ch->netdev);
 				return -ENOMEM;
 			} else {
 				memcpy(skb_put(nskb, skb->len),
@@ -2281,6 +2285,7 @@
 				 */
 				atomic_dec(&skb->users);
 				skb_pull(skb, LL_HEADER_LENGTH + 2);
+				ctc_clear_busy(ch->netdev);
 				return -EBUSY;
 			}
 
@@ -2327,9 +2332,10 @@
 		}
 	}
 
+	ctc_clear_busy(ch->netdev);
 	return rc;
 }
-
+
 /**
  * Interface API for upper network layers
  *****************************************************************************/
@@ -2421,7 +2427,6 @@
 	dev->trans_start = jiffies;
 	if (transmit_skb(privptr->channel[WRITE], skb) != 0)
 		rc = 1;
-	ctc_clear_busy(dev);
 	return rc;
 }
 
@@ -2610,7 +2615,6 @@
 	return count;
 }
 
-
 static void
 ctc_netdev_unregister(struct net_device * dev)
 {
@@ -2685,7 +2689,6 @@
 	return count;
 }
 
-
 static ssize_t
 ctc_type_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
index dbad7f3..24ed589 100644
--- a/drivers/sbus/char/display7seg.c
+++ b/drivers/sbus/char/display7seg.c
@@ -14,7 +14,7 @@
 #include <linux/major.h>
 #include <linux/init.h>
 #include <linux/miscdevice.h>
-#include <linux/ioport.h>		/* request_region, check_region */
+#include <linux/ioport.h>		/* request_region */
 #include <asm/atomic.h>
 #include <asm/ebus.h>			/* EBus device					*/
 #include <asm/oplib.h>			/* OpenProm Library 			*/
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index a63f931..b227e51 100644
--- a/drivers/scsi/sata_sis.c
+++ b/drivers/scsi/sata_sis.c
@@ -161,7 +161,7 @@
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
 	unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg, pdev->device);
-	u32 val, val2;
+	u32 val, val2 = 0;
 	u8 pmr;
 
 	if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
@@ -289,7 +289,7 @@
 	if (ent->device != 0x182) {
 		if ((pmr & SIS_PMR_COMBINED) == 0) {
 			printk(KERN_INFO "sata_sis: Detected SiS 180/181 chipset in SATA mode\n");
-			port2_start=0x64;
+			port2_start = 64;
 		}
 		else {
 			printk(KERN_INFO "sata_sis: Detected SiS 180/181 chipset in combined mode\n");
diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c
index 4382ee6..6bed871 100644
--- a/drivers/tc/zs.c
+++ b/drivers/tc/zs.c
@@ -1683,7 +1683,7 @@
 #ifndef CONFIG_SERIAL_DEC_CONSOLE
 			/*
 			 * We're called early and memory managment isn't up, yet.
-			 * Thus check_region would fail.
+			 * Thus request_region would fail.
 			 */
 			if (!request_region((unsigned long)
 					 zs_channels[n_channels].control,
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 615874e..31ee13e 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -753,7 +753,8 @@
 
 config FB_I810_I2C
 	bool "Enable DDC Support"
-	depends on FB_I810 && I2C && FB_I810_GTF
+	depends on FB_I810 && FB_I810_GTF
+	select I2C
 	select I2C_ALGOBIT
 	help
 
diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c
index 353cb3f..a328176 100644
--- a/drivers/video/backlight/corgi_bl.c
+++ b/drivers/video/backlight/corgi_bl.c
@@ -43,18 +43,10 @@
 			intensity &= CORGI_LIMIT_MASK;
 	}
 
-	/* Skip 0x20 as it will blank the display */
-	if (intensity >= 0x20)
-		intensity++;
-
 	spin_lock_irqsave(&bl_lock, flags);
-	/* Bits 0-4 are accessed via the SSP interface */
-	corgi_ssp_blduty_set(intensity & 0x1f);
-	/* Bit 5 is via SCOOP */
-	if (intensity & 0x0020)
-		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
-	else
-		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
+
+	corgibl_mach_set_intensity(intensity);
+
 	spin_unlock_irqrestore(&bl_lock, flags);
 }
 
@@ -113,8 +105,8 @@
 
 static int corgibl_set_intensity(struct backlight_device *bd, int intensity)
 {
-	if (intensity > CORGI_MAX_INTENSITY)
-		intensity = CORGI_MAX_INTENSITY;
+	if (intensity > corgibl_data.max_brightness)
+		intensity = corgibl_data.max_brightness;
 	corgibl_send_intensity(intensity);
 	current_intensity=intensity;
 	return 0;
@@ -141,7 +133,6 @@
 	.owner		= THIS_MODULE,
 	.get_power      = corgibl_get_power,
 	.set_power      = corgibl_set_power,
-	.max_brightness = CORGI_MAX_INTENSITY,
 	.get_brightness = corgibl_get_intensity,
 	.set_brightness = corgibl_set_intensity,
 };
@@ -150,12 +141,18 @@
 
 static int __init corgibl_probe(struct device *dev)
 {
+	struct corgibl_machinfo *machinfo = dev->platform_data;
+
+	corgibl_data.max_brightness = machinfo->max_intensity;
+	corgibl_mach_set_intensity = machinfo->set_bl_intensity;
+
 	corgi_backlight_device = backlight_device_register ("corgi-bl",
 		NULL, &corgibl_data);
 	if (IS_ERR (corgi_backlight_device))
 		return PTR_ERR (corgi_backlight_device);
 
 	corgibl_set_intensity(NULL, CORGI_DEFAULT_INTENSITY);
+	corgibl_limit_intensity(0);
 
 	printk("Corgi Backlight Driver Initialized.\n");
 	return 0;
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 2e93224..0fc8bb4 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -767,7 +767,7 @@
 	const char *display_desc = "frame buffer device";
 	struct display *p = &fb_display[fg_console];
 	struct vc_data *vc = vc_cons[fg_console].d;
-	struct font_desc *font = NULL;
+	const struct font_desc *font = NULL;
 	struct module *owner;
 	struct fb_info *info = NULL;
 	struct fbcon_ops *ops;
@@ -841,7 +841,7 @@
 						info->var.yres);
 		vc->vc_font.width = font->width;
 		vc->vc_font.height = font->height;
-		vc->vc_font.data = p->fontdata = font->data;
+		vc->vc_font.data = (void *)(p->fontdata = font->data);
 		vc->vc_font.charcount = 256; /* FIXME  Need to support more fonts */
 	}
 
@@ -941,7 +941,7 @@
 	   fb, copy the font from that console */
 	t = &fb_display[svc->vc_num];
 	if (!vc->vc_font.data) {
-		vc->vc_font.data = p->fontdata = t->fontdata;
+		vc->vc_font.data = (void *)(p->fontdata = t->fontdata);
 		vc->vc_font.width = (*default_mode)->vc_font.width;
 		vc->vc_font.height = (*default_mode)->vc_font.height;
 		p->userfont = t->userfont;
@@ -1188,7 +1188,7 @@
 		return;
 	t = &fb_display[svc->vc_num];
 	if (!vc->vc_font.data) {
-		vc->vc_font.data = p->fontdata = t->fontdata;
+		vc->vc_font.data = (void *)(p->fontdata = t->fontdata);
 		vc->vc_font.width = (*default_mode)->vc_font.width;
 		vc->vc_font.height = (*default_mode)->vc_font.height;
 		p->userfont = t->userfont;
@@ -1687,6 +1687,8 @@
 	case SM_DOWN:
 		if (count > vc->vc_rows)	/* Maximum realistic size */
 			count = vc->vc_rows;
+		if (logo_shown >= 0)
+			goto redraw_down;
 		switch (p->scrollmode) {
 		case SCROLL_MOVE:
 			ops->bmove(vc, info, t, 0, t + count, 0,
@@ -2148,7 +2150,7 @@
 }
 
 static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
-			     u8 * data, int userfont)
+			     const u8 * data, int userfont)
 {
 	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
 	struct display *p = &fb_display[vc->vc_num];
@@ -2166,7 +2168,7 @@
 		cnt = FNTCHARCNT(data);
 	else
 		cnt = 256;
-	vc->vc_font.data = p->fontdata = data;
+	vc->vc_font.data = (void *)(p->fontdata = data);
 	if ((p->userfont = userfont))
 		REFCOUNT(data)++;
 	vc->vc_font.width = w;
@@ -2323,7 +2325,7 @@
 		    tmp->vc_font.width == w &&
 		    !memcmp(fb_display[i].fontdata, new_data, size)) {
 			kfree(new_data - FONT_EXTRA_WORDS * sizeof(int));
-			new_data = fb_display[i].fontdata;
+			new_data = (u8 *)fb_display[i].fontdata;
 			break;
 		}
 	}
@@ -2333,7 +2335,7 @@
 static int fbcon_set_def_font(struct vc_data *vc, struct console_font *font, char *name)
 {
 	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
-	struct font_desc *f;
+	const struct font_desc *f;
 
 	if (!name)
 		f = get_default_font(info->var.xres, info->var.yres);
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index 08befaf..0738cd6 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -30,7 +30,7 @@
     /* Filled in by the frame buffer device */
     u_short inverse;                /* != 0 text black on white as default */
     /* Filled in by the low-level console driver */
-    u_char *fontdata;
+    const u_char *fontdata;
     int userfont;                   /* != 0 if fontdata kmalloc()ed */
     u_short scrollmode;             /* Scroll Method */
     short yscroll;                  /* Hardware scrolling */
diff --git a/drivers/video/console/font_10x18.c b/drivers/video/console/font_10x18.c
index ff0af96..e6aa0ea 100644
--- a/drivers/video/console/font_10x18.c
+++ b/drivers/video/console/font_10x18.c
@@ -7,7 +7,7 @@
 
 #define FONTDATAMAX 9216
 
-static unsigned char fontdata_10x18[FONTDATAMAX] = {
+static const unsigned char fontdata_10x18[FONTDATAMAX] = {
 
 	/* 0 0x00 '^@' */
 	0x00, 0x00, /* 0000000000 */
@@ -5132,7 +5132,7 @@
 };
 
 
-struct font_desc font_10x18 = {
+const struct font_desc font_10x18 = {
 	FONT10x18_IDX,
 	"10x18",
 	10,
diff --git a/drivers/video/console/font_6x11.c b/drivers/video/console/font_6x11.c
index c52f129..89976cd 100644
--- a/drivers/video/console/font_6x11.c
+++ b/drivers/video/console/font_6x11.c
@@ -8,7 +8,7 @@
 
 #define FONTDATAMAX (11*256)
 
-static unsigned char fontdata_6x11[FONTDATAMAX] = {
+static const unsigned char fontdata_6x11[FONTDATAMAX] = {
 
 	/* 0 0x00 '^@' */
 	0x00, /* 00000000 */
@@ -3341,7 +3341,7 @@
 };
 
 
-struct font_desc font_vga_6x11 = {
+const struct font_desc font_vga_6x11 = {
 	VGA6x11_IDX,
 	"ProFont6x11",
 	6,
diff --git a/drivers/video/console/font_7x14.c b/drivers/video/console/font_7x14.c
index 1fa7fcf..bbf1166 100644
--- a/drivers/video/console/font_7x14.c
+++ b/drivers/video/console/font_7x14.c
@@ -7,7 +7,7 @@
 
 #define FONTDATAMAX 3584
 
-static unsigned char fontdata_7x14[FONTDATAMAX] = {
+static const unsigned char fontdata_7x14[FONTDATAMAX] = {
 
 	/* 0 0x00 '^@' */
 	0x00, /* 0000000 */
@@ -4108,7 +4108,7 @@
 };
 
 
-struct font_desc font_7x14 = {
+const struct font_desc font_7x14 = {
 	FONT7x14_IDX,
 	"7x14",
 	7,
diff --git a/drivers/video/console/font_8x16.c b/drivers/video/console/font_8x16.c
index e6f8dba..74fe86f 100644
--- a/drivers/video/console/font_8x16.c
+++ b/drivers/video/console/font_8x16.c
@@ -8,7 +8,7 @@
 
 #define FONTDATAMAX 4096
 
-static unsigned char fontdata_8x16[FONTDATAMAX] = {
+static const unsigned char fontdata_8x16[FONTDATAMAX] = {
 
 	/* 0 0x00 '^@' */
 	0x00, /* 00000000 */
@@ -4621,7 +4621,7 @@
 };
 
 
-struct font_desc font_vga_8x16 = {
+const struct font_desc font_vga_8x16 = {
 	VGA8x16_IDX,
 	"VGA8x16",
 	8,
diff --git a/drivers/video/console/font_8x8.c b/drivers/video/console/font_8x8.c
index 57fbe26..26199f8 100644
--- a/drivers/video/console/font_8x8.c
+++ b/drivers/video/console/font_8x8.c
@@ -8,7 +8,7 @@
 
 #define FONTDATAMAX 2048
 
-static unsigned char fontdata_8x8[FONTDATAMAX] = {
+static const unsigned char fontdata_8x8[FONTDATAMAX] = {
 
 	/* 0 0x00 '^@' */
 	0x00, /* 00000000 */
@@ -2573,7 +2573,7 @@
 };
 
 
-struct font_desc font_vga_8x8 = {
+const struct font_desc font_vga_8x8 = {
 	VGA8x8_IDX,
 	"VGA8x8",
 	8,
diff --git a/drivers/video/console/font_acorn_8x8.c b/drivers/video/console/font_acorn_8x8.c
index d565505..2d2e396 100644
--- a/drivers/video/console/font_acorn_8x8.c
+++ b/drivers/video/console/font_acorn_8x8.c
@@ -3,7 +3,7 @@
 #include <linux/config.h>
 #include <linux/font.h>
 
-static unsigned char acorndata_8x8[] = {
+static const unsigned char acorndata_8x8[] = {
 /* 00 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ^@ */
 /* 01 */  0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, /* ^A */
 /* 02 */  0x7e, 0xff, 0xbd, 0xff, 0xc3, 0xe7, 0xff, 0x7e, /* ^B */
@@ -262,7 +262,7 @@
 /* FF */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
 
-struct font_desc font_acorn_8x8 = {
+const struct font_desc font_acorn_8x8 = {
 	ACORN8x8_IDX,
 	"Acorn8x8",
 	8,
diff --git a/drivers/video/console/font_mini_4x6.c b/drivers/video/console/font_mini_4x6.c
index 593b955..d818234 100644
--- a/drivers/video/console/font_mini_4x6.c
+++ b/drivers/video/console/font_mini_4x6.c
@@ -43,7 +43,7 @@
 
 #define FONTDATAMAX 1536
 
-static unsigned char fontdata_mini_4x6[FONTDATAMAX] = {
+static const unsigned char fontdata_mini_4x6[FONTDATAMAX] = {
 
 	/*{*/
 	  	/*   Char 0: ' '  */
@@ -2147,7 +2147,7 @@
 	/*}*/
 };
 
-struct font_desc font_mini_4x6 = {
+const struct font_desc font_mini_4x6 = {
 	MINI4x6_IDX,
 	"MINI4x6",
 	4,
diff --git a/drivers/video/console/font_pearl_8x8.c b/drivers/video/console/font_pearl_8x8.c
index 5fa95f1..e646c88 100644
--- a/drivers/video/console/font_pearl_8x8.c
+++ b/drivers/video/console/font_pearl_8x8.c
@@ -13,7 +13,7 @@
 
 #define FONTDATAMAX 2048
 
-static unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
+static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
 
    /* 0 0x00 '^@' */
    0x00, /* 00000000 */
@@ -2577,7 +2577,7 @@
 
 };
 
-struct font_desc font_pearl_8x8 = {
+const struct font_desc font_pearl_8x8 = {
 	PEARL8x8_IDX,
 	"PEARL8x8",
 	8,
diff --git a/drivers/video/console/font_sun12x22.c b/drivers/video/console/font_sun12x22.c
index c7bd967..ab5eb93 100644
--- a/drivers/video/console/font_sun12x22.c
+++ b/drivers/video/console/font_sun12x22.c
@@ -2,7 +2,7 @@
 
 #define FONTDATAMAX 11264
 
-static unsigned char fontdata_sun12x22[FONTDATAMAX] = {
+static const unsigned char fontdata_sun12x22[FONTDATAMAX] = {
 
 	/* 0 0x00 '^@' */
 	0x00, 0x00, /* 000000000000 */
@@ -6151,7 +6151,7 @@
 };
 
 
-struct font_desc font_sun_12x22 = {
+const struct font_desc font_sun_12x22 = {
 	SUN12x22_IDX,
 	"SUN12x22",
 	12,
diff --git a/drivers/video/console/font_sun8x16.c b/drivers/video/console/font_sun8x16.c
index 2af3ab3..41f910f 100644
--- a/drivers/video/console/font_sun8x16.c
+++ b/drivers/video/console/font_sun8x16.c
@@ -2,7 +2,7 @@
 
 #define FONTDATAMAX 4096
 
-static unsigned char fontdata_sun8x16[FONTDATAMAX] = {
+static const unsigned char fontdata_sun8x16[FONTDATAMAX] = {
 /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 /* */ 0x00,0x00,0x7e,0x81,0xa5,0x81,0x81,0xbd,0x99,0x81,0x81,0x7e,0x00,0x00,0x00,0x00,
 /* */ 0x00,0x00,0x7e,0xff,0xdb,0xff,0xff,0xc3,0xe7,0xff,0xff,0x7e,0x00,0x00,0x00,0x00,
@@ -261,7 +261,7 @@
 /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 };
 
-struct font_desc font_sun_8x16 = {
+const struct font_desc font_sun_8x16 = {
 	SUN8x16_IDX,
 	"SUN8x16",
 	8,
diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c
index e79b297..4fd07d9 100644
--- a/drivers/video/console/fonts.c
+++ b/drivers/video/console/fonts.c
@@ -23,7 +23,7 @@
 
 #define NO_FONTS
 
-static struct font_desc *fonts[] = {
+static const struct font_desc *fonts[] = {
 #ifdef CONFIG_FONT_8x8
 #undef NO_FONTS
     &font_vga_8x8,
@@ -84,7 +84,7 @@
  *
  */
 
-struct font_desc *find_font(char *name)
+const struct font_desc *find_font(const char *name)
 {
    unsigned int i;
 
@@ -108,10 +108,10 @@
  *
  */
 
-struct font_desc *get_default_font(int xres, int yres)
+const struct font_desc *get_default_font(int xres, int yres)
 {
     int i, c, cc;
-    struct font_desc *f, *g;
+    const struct font_desc *f, *g;
 
     g = NULL;
     cc = -10000;
@@ -138,7 +138,6 @@
     return g;
 }
 
-EXPORT_SYMBOL(fonts);
 EXPORT_SYMBOL(find_font);
 EXPORT_SYMBOL(get_default_font);
 
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index 98e00d8..e02da41 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -1285,7 +1285,7 @@
 	vaddr_t vm;
 	unsigned int offs;
 	unsigned int offs2;
-	unsigned char store;
+	unsigned char store, orig;
 	unsigned char bytes[32];
 	unsigned char* tmp;
 
@@ -1298,7 +1298,8 @@
 	if (maxSize > 0x2000000) maxSize = 0x2000000;
 
 	mga_outb(M_EXTVGA_INDEX, 0x03);
-	mga_outb(M_EXTVGA_DATA, mga_inb(M_EXTVGA_DATA) | 0x80);
+	orig = mga_inb(M_EXTVGA_DATA);
+	mga_outb(M_EXTVGA_DATA, orig | 0x80);
 
 	store = mga_readb(vm, 0x1234);
 	tmp = bytes;
@@ -1323,7 +1324,7 @@
 	mga_writeb(vm, 0x1234, store);
 
 	mga_outb(M_EXTVGA_INDEX, 0x03);
-	mga_outb(M_EXTVGA_DATA, mga_inb(M_EXTVGA_DATA) & ~0x80);
+	mga_outb(M_EXTVGA_DATA, orig);
 
 	*realSize = offs - 0x100000;
 #ifdef CONFIG_FB_MATROX_MILLENIUM
@@ -1858,6 +1859,8 @@
 							to yres_virtual * xres_virtual < 2^32 */
 	}
 	matroxfb_init_fix(PMINFO2);
+	ACCESS_FBINFO(fbcon.screen_base) = vaddr_va(ACCESS_FBINFO(video.vbase));
+	matroxfb_update_fix(PMINFO2);
 	/* Normalize values (namely yres_virtual) */
 	matroxfb_check_var(&vesafb_defined, &ACCESS_FBINFO(fbcon));
 	/* And put it into "current" var. Do NOT program hardware yet, or we'll not take over
@@ -2010,11 +2013,11 @@
 	}
 	/* not match... */
 	if (!b->vendor)
-		return -1;
+		return -ENODEV;
 	if (dev > 0) {
 		/* not requested one... */
 		dev--;
-		return -1;
+		return -ENODEV;
 	}
 	pci_read_config_dword(pdev, PCI_COMMAND, &cmd);
 	if (pci_enable_device(pdev)) {
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
index e0dad94..2e11b60 100644
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/pm3fb.c
@@ -67,6 +67,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/ioport.h>
+#include <linux/ctype.h>
 
 #include <video/fbcon.h>
 #include <video/fbcon-mfb.h>
@@ -2594,7 +2595,7 @@
 {
 	char *next;
 
-	if (!(CHAR_IS_NUM(options[0]))) {
+	if (!(isdigit(options[0]))) {
 		(*bn) = 0;
 		return (options);
 	}
diff --git a/fs/exec.c b/fs/exec.c
index 14dd039..a04a575 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -421,11 +421,6 @@
 	if (!mpnt)
 		return -ENOMEM;
 
-	if (security_vm_enough_memory(arg_size >> PAGE_SHIFT)) {
-		kmem_cache_free(vm_area_cachep, mpnt);
-		return -ENOMEM;
-	}
-
 	memset(mpnt, 0, sizeof(*mpnt));
 
 	down_write(&mm->mmap_sem);
@@ -745,8 +740,8 @@
         }
 
 	/*
-	 * Now there are really no other threads at all,
-	 * so it's safe to stop telling them to kill themselves.
+	 * There may be one thread left which is just exiting,
+	 * but it's safe to stop telling the group to kill themselves.
 	 */
 	sig->flags = 0;
 
@@ -785,7 +780,6 @@
 			kmem_cache_free(sighand_cachep, oldsighand);
 	}
 
-	BUG_ON(!thread_group_empty(current));
 	BUG_ON(!thread_group_leader(current));
 	return 0;
 }
diff --git a/fs/file.c b/fs/file.c
index 2127a7b..fd066b2 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -69,13 +69,9 @@
 
 static void __free_fdtable(struct fdtable *fdt)
 {
-	int fdset_size, fdarray_size;
-
-	fdset_size = fdt->max_fdset / 8;
-	fdarray_size = fdt->max_fds * sizeof(struct file *);
-	free_fdset(fdt->open_fds, fdset_size);
-	free_fdset(fdt->close_on_exec, fdset_size);
-	free_fd_array(fdt->fd, fdarray_size);
+	free_fdset(fdt->open_fds, fdt->max_fdset);
+	free_fdset(fdt->close_on_exec, fdt->max_fdset);
+	free_fd_array(fdt->fd, fdt->max_fds);
 	kfree(fdt);
 }
 
diff --git a/fs/namei.c b/fs/namei.c
index 21d85f1..043d587 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1048,7 +1048,7 @@
 out:
 	if (unlikely(current->audit_context
 		     && nd && nd->dentry && nd->dentry->d_inode))
-		audit_inode(name, nd->dentry->d_inode);
+		audit_inode(name, nd->dentry->d_inode, flags);
 	return retval;
 }
 
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index e08edc1..361b400 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -162,7 +162,7 @@
 
 
 static inline int
-nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
+nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, struct nfs4_stateowner **replay_owner)
 {
 	int status;
 	dprintk("NFSD: nfsd4_open filename %.*s op_stateowner %p\n",
@@ -238,8 +238,10 @@
 	 */
 	status = nfsd4_process_open2(rqstp, current_fh, open);
 out:
-	if (open->op_stateowner)
+	if (open->op_stateowner) {
 		nfs4_get_stateowner(open->op_stateowner);
+		*replay_owner = open->op_stateowner;
+	}
 	nfs4_unlock_state();
 	return status;
 }
@@ -809,8 +811,7 @@
 			op->status = nfsd4_access(rqstp, current_fh, &op->u.access);
 			break;
 		case OP_CLOSE:
-			op->status = nfsd4_close(rqstp, current_fh, &op->u.close);
-			replay_owner = op->u.close.cl_stateowner;
+			op->status = nfsd4_close(rqstp, current_fh, &op->u.close, &replay_owner);
 			break;
 		case OP_COMMIT:
 			op->status = nfsd4_commit(rqstp, current_fh, &op->u.commit);
@@ -831,15 +832,13 @@
 			op->status = nfsd4_link(rqstp, current_fh, save_fh, &op->u.link);
 			break;
 		case OP_LOCK:
-			op->status = nfsd4_lock(rqstp, current_fh, &op->u.lock);
-			replay_owner = op->u.lock.lk_stateowner;
+			op->status = nfsd4_lock(rqstp, current_fh, &op->u.lock, &replay_owner);
 			break;
 		case OP_LOCKT:
 			op->status = nfsd4_lockt(rqstp, current_fh, &op->u.lockt);
 			break;
 		case OP_LOCKU:
-			op->status = nfsd4_locku(rqstp, current_fh, &op->u.locku);
-			replay_owner = op->u.locku.lu_stateowner;
+			op->status = nfsd4_locku(rqstp, current_fh, &op->u.locku, &replay_owner);
 			break;
 		case OP_LOOKUP:
 			op->status = nfsd4_lookup(rqstp, current_fh, &op->u.lookup);
@@ -853,16 +852,13 @@
 				op->status = nfs_ok;
 			break;
 		case OP_OPEN:
-			op->status = nfsd4_open(rqstp, current_fh, &op->u.open);
-			replay_owner = op->u.open.op_stateowner;
+			op->status = nfsd4_open(rqstp, current_fh, &op->u.open, &replay_owner);
 			break;
 		case OP_OPEN_CONFIRM:
-			op->status = nfsd4_open_confirm(rqstp, current_fh, &op->u.open_confirm);
-			replay_owner = op->u.open_confirm.oc_stateowner;
+			op->status = nfsd4_open_confirm(rqstp, current_fh, &op->u.open_confirm, &replay_owner);
 			break;
 		case OP_OPEN_DOWNGRADE:
-			op->status = nfsd4_open_downgrade(rqstp, current_fh, &op->u.open_downgrade);
-			replay_owner = op->u.open_downgrade.od_stateowner;
+			op->status = nfsd4_open_downgrade(rqstp, current_fh, &op->u.open_downgrade, &replay_owner);
 			break;
 		case OP_PUTFH:
 			op->status = nfsd4_putfh(rqstp, current_fh, &op->u.putfh);
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index b83f8fb..6bbefd0 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -624,7 +624,7 @@
 	cb->cb_ident = se->se_callback_ident;
 	return;
 out_err:
-	printk(KERN_INFO "NFSD: this client (clientid %08x/%08x) "
+	dprintk(KERN_INFO "NFSD: this client (clientid %08x/%08x) "
 		"will not receive delegations\n",
 		clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
 
@@ -678,13 +678,12 @@
 	int 			status;
 	char                    dname[HEXDIR_LEN];
 	
-	status = nfserr_inval;
 	if (!check_name(clname))
-		goto out;
+		return nfserr_inval;
 
 	status = nfs4_make_rec_clidname(dname, &clname);
 	if (status)
-		goto out;
+		return status;
 
 	/* 
 	 * XXX The Duplicate Request Cache (DRC) has been checked (??)
@@ -2014,7 +2013,7 @@
 {
 	if (stateid->si_boot == boot_time)
 		return 0;
-	printk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n",
+	dprintk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n",
 		stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
 		stateid->si_generation);
 	return 1;
@@ -2275,7 +2274,7 @@
 
 check_replay:
 	if (seqid == sop->so_seqid - 1) {
-		printk("NFSD: preprocess_seqid_op: retransmission?\n");
+		dprintk("NFSD: preprocess_seqid_op: retransmission?\n");
 		/* indicate replay to calling function */
 		return NFSERR_REPLAY_ME;
 	}
@@ -2286,7 +2285,7 @@
 }
 
 int
-nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc)
+nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc, struct nfs4_stateowner **replay_owner)
 {
 	int status;
 	struct nfs4_stateowner *sop;
@@ -2320,8 +2319,10 @@
 
 	nfsd4_create_clid_dir(sop->so_client);
 out:
-	if (oc->oc_stateowner)
+	if (oc->oc_stateowner) {
 		nfs4_get_stateowner(oc->oc_stateowner);
+		*replay_owner = oc->oc_stateowner;
+	}
 	nfs4_unlock_state();
 	return status;
 }
@@ -2352,7 +2353,7 @@
 }
 
 int
-nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od)
+nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od, struct nfs4_stateowner **replay_owner)
 {
 	int status;
 	struct nfs4_stateid *stp;
@@ -2394,8 +2395,10 @@
 	memcpy(&od->od_stateid, &stp->st_stateid, sizeof(stateid_t));
 	status = nfs_ok;
 out:
-	if (od->od_stateowner)
+	if (od->od_stateowner) {
 		nfs4_get_stateowner(od->od_stateowner);
+		*replay_owner = od->od_stateowner;
+	}
 	nfs4_unlock_state();
 	return status;
 }
@@ -2404,7 +2407,7 @@
  * nfs4_unlock_state() called after encode
  */
 int
-nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close)
+nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close, struct nfs4_stateowner **replay_owner)
 {
 	int status;
 	struct nfs4_stateid *stp;
@@ -2430,8 +2433,10 @@
 	/* release_state_owner() calls nfsd_close() if needed */
 	release_state_owner(stp, OPEN_STATE);
 out:
-	if (close->cl_stateowner)
+	if (close->cl_stateowner) {
 		nfs4_get_stateowner(close->cl_stateowner);
+		*replay_owner = close->cl_stateowner;
+	}
 	nfs4_unlock_state();
 	return status;
 }
@@ -2500,8 +2505,7 @@
 			    (local->st_stateid.si_fileid == f_id))
 				return local;
 		}
-	} else
-		printk("NFSD: find_stateid: ERROR: no state flag\n");
+	}
 	return NULL;
 }
 
@@ -2624,7 +2628,9 @@
 	sop->so_is_open_owner = 0;
 	sop->so_id = current_ownerid++;
 	sop->so_client = clp;
-	sop->so_seqid = lock->lk_new_lock_seqid;
+	/* It is the openowner seqid that will be incremented in encode in the
+	 * case of new lockowners; so increment the lock seqid manually: */
+	sop->so_seqid = lock->lk_new_lock_seqid + 1;
 	sop->so_confirmed = 1;
 	rp = &sop->so_replay;
 	rp->rp_status = NFSERR_SERVERFAULT;
@@ -2676,9 +2682,10 @@
  *  LOCK operation 
  */
 int
-nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock)
+nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock, struct nfs4_stateowner **replay_owner)
 {
 	struct nfs4_stateowner *open_sop = NULL;
+	struct nfs4_stateowner *lock_sop = NULL;
 	struct nfs4_stateid *lock_stp;
 	struct file *filp;
 	struct file_lock file_lock;
@@ -2705,19 +2712,19 @@
 		struct nfs4_file *fp;
 		
 		status = nfserr_stale_clientid;
-		if (STALE_CLIENTID(&lock->lk_new_clientid)) {
-			printk("NFSD: nfsd4_lock: clientid is stale!\n");
+		if (STALE_CLIENTID(&lock->lk_new_clientid))
 			goto out;
-		}
 
 		/* validate and update open stateid and open seqid */
 		status = nfs4_preprocess_seqid_op(current_fh, 
 				        lock->lk_new_open_seqid,
 		                        &lock->lk_new_open_stateid,
 		                        CHECK_FH | OPEN_STATE,
-		                        &open_sop, &open_stp, lock);
+		                        &lock->lk_stateowner, &open_stp,
+					lock);
 		if (status)
 			goto out;
+		open_sop = lock->lk_stateowner;
 		/* create lockowner and lock stateid */
 		fp = open_stp->st_file;
 		strhashval = lock_ownerstr_hashval(fp->fi_inode, 
@@ -2727,16 +2734,15 @@
 		 * the same file, or should they just be allowed (and
 		 * create new stateids)? */
 		status = nfserr_resource;
-		if (!(lock->lk_stateowner = alloc_init_lock_stateowner(strhashval, open_sop->so_client, open_stp, lock)))
+		lock_sop = alloc_init_lock_stateowner(strhashval,
+				open_sop->so_client, open_stp, lock);
+		if (lock_sop == NULL)
 			goto out;
-		if ((lock_stp = alloc_init_lock_stateid(lock->lk_stateowner, 
-						fp, open_stp)) == NULL) {
-			release_stateowner(lock->lk_stateowner);
-			lock->lk_stateowner = NULL;
+		lock_stp = alloc_init_lock_stateid(lock_sop, fp, open_stp);
+		if (lock_stp == NULL) {
+			release_stateowner(lock_sop);
 			goto out;
 		}
-		/* bump the open seqid used to create the lock */
-		open_sop->so_seqid++;
 	} else {
 		/* lock (lock owner + lock stateid) already exists */
 		status = nfs4_preprocess_seqid_op(current_fh,
@@ -2746,12 +2752,13 @@
 				       &lock->lk_stateowner, &lock_stp, lock);
 		if (status)
 			goto out;
+		lock_sop = lock->lk_stateowner;
 	}
 	/* lock->lk_stateowner and lock_stp have been created or found */
 	filp = lock_stp->st_vfs_file;
 
 	if ((status = fh_verify(rqstp, current_fh, S_IFREG, MAY_LOCK))) {
-		printk("NFSD: nfsd4_lock: permission denied!\n");
+		dprintk("NFSD: nfsd4_lock: permission denied!\n");
 		goto out;
 	}
 
@@ -2776,7 +2783,7 @@
 			status = nfserr_inval;
 		goto out;
 	}
-	file_lock.fl_owner = (fl_owner_t) lock->lk_stateowner;
+	file_lock.fl_owner = (fl_owner_t)lock_sop;
 	file_lock.fl_pid = current->tgid;
 	file_lock.fl_file = filp;
 	file_lock.fl_flags = FL_POSIX;
@@ -2832,14 +2839,13 @@
 		 * An error encountered after instantiation of the new
 		 * stateid has forced us to destroy it.
 		 */
-		if (!seqid_mutating_err(status))
-			open_sop->so_seqid--;
-
 		release_state_owner(lock_stp, LOCK_STATE);
 	}
 out:
-	if (lock->lk_stateowner)
+	if (lock->lk_stateowner) {
 		nfs4_get_stateowner(lock->lk_stateowner);
+		*replay_owner = lock->lk_stateowner;
+	}
 	nfs4_unlock_state();
 	return status;
 }
@@ -2866,13 +2872,11 @@
 	nfs4_lock_state();
 
 	status = nfserr_stale_clientid;
-	if (STALE_CLIENTID(&lockt->lt_clientid)) {
-		printk("NFSD: nfsd4_lockt: clientid is stale!\n");
+	if (STALE_CLIENTID(&lockt->lt_clientid))
 		goto out;
-	}
 
 	if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) {
-		printk("NFSD: nfsd4_lockt: fh_verify() failed!\n");
+		dprintk("NFSD: nfsd4_lockt: fh_verify() failed!\n");
 		if (status == nfserr_symlink)
 			status = nfserr_inval;
 		goto out;
@@ -2930,7 +2934,7 @@
 }
 
 int
-nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku)
+nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_locku *locku, struct nfs4_stateowner **replay_owner)
 {
 	struct nfs4_stateid *stp;
 	struct file *filp = NULL;
@@ -2976,7 +2980,7 @@
 	if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
 		file_lock.fl_ops->fl_release_private(&file_lock);
 	if (status) {
-		printk("NFSD: nfs4_locku: posix_lock_file failed!\n");
+		dprintk("NFSD: nfs4_locku: posix_lock_file failed!\n");
 		goto out_nfserr;
 	}
 	/*
@@ -2986,8 +2990,10 @@
 	memcpy(&locku->lu_stateid, &stp->st_stateid, sizeof(stateid_t));
 
 out:
-	if (locku->lu_stateowner)
+	if (locku->lu_stateowner) {
 		nfs4_get_stateowner(locku->lu_stateowner);
+		*replay_owner = locku->lu_stateowner;
+	}
 	nfs4_unlock_state();
 	return status;
 
@@ -3036,10 +3042,8 @@
 	/* XXX check for lease expiration */
 
 	status = nfserr_stale_clientid;
-	if (STALE_CLIENTID(clid)) {
-		printk("NFSD: nfsd4_release_lockowner: clientid is stale!\n");
+	if (STALE_CLIENTID(clid))
 		return status;
-	}
 
 	nfs4_lock_state();
 
diff --git a/fs/open.c b/fs/open.c
index 2fac58c..f0d90cf 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -738,52 +738,15 @@
 	return error;
 }
 
-/*
- * Note that while the flag value (low two bits) for sys_open means:
- *	00 - read-only
- *	01 - write-only
- *	10 - read-write
- *	11 - special
- * it is changed into
- *	00 - no permissions needed
- *	01 - read-permission
- *	10 - write-permission
- *	11 - read-write
- * for the internal routines (ie open_namei()/follow_link() etc). 00 is
- * used by symlinks.
- */
-struct file *filp_open(const char * filename, int flags, int mode)
+static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
+					int flags, struct file *f)
 {
-	int namei_flags, error;
-	struct nameidata nd;
-
-	namei_flags = flags;
-	if ((namei_flags+1) & O_ACCMODE)
-		namei_flags++;
-	if (namei_flags & O_TRUNC)
-		namei_flags |= 2;
-
-	error = open_namei(filename, namei_flags, mode, &nd);
-	if (!error)
-		return dentry_open(nd.dentry, nd.mnt, flags);
-
-	return ERR_PTR(error);
-}
-
-EXPORT_SYMBOL(filp_open);
-
-struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
-{
-	struct file * f;
 	struct inode *inode;
 	int error;
 
-	error = -ENFILE;
-	f = get_empty_filp();
-	if (!f)
-		goto cleanup_dentry;
 	f->f_flags = flags;
-	f->f_mode = ((flags+1) & O_ACCMODE) | FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE;
+	f->f_mode = ((flags+1) & O_ACCMODE) | FMODE_LSEEK |
+				FMODE_PREAD | FMODE_PWRITE;
 	inode = dentry->d_inode;
 	if (f->f_mode & FMODE_WRITE) {
 		error = get_write_access(inode);
@@ -828,12 +791,63 @@
 	f->f_vfsmnt = NULL;
 cleanup_file:
 	put_filp(f);
-cleanup_dentry:
 	dput(dentry);
 	mntput(mnt);
 	return ERR_PTR(error);
 }
 
+/*
+ * Note that while the flag value (low two bits) for sys_open means:
+ *	00 - read-only
+ *	01 - write-only
+ *	10 - read-write
+ *	11 - special
+ * it is changed into
+ *	00 - no permissions needed
+ *	01 - read-permission
+ *	10 - write-permission
+ *	11 - read-write
+ * for the internal routines (ie open_namei()/follow_link() etc). 00 is
+ * used by symlinks.
+ */
+struct file *filp_open(const char * filename, int flags, int mode)
+{
+	int namei_flags, error;
+	struct nameidata nd;
+	struct file *f;
+
+	namei_flags = flags;
+	if ((namei_flags+1) & O_ACCMODE)
+		namei_flags++;
+	if (namei_flags & O_TRUNC)
+		namei_flags |= 2;
+
+	error = -ENFILE;
+	f = get_empty_filp();
+	if (f == NULL)
+		return ERR_PTR(error);
+
+	error = open_namei(filename, namei_flags, mode, &nd);
+	if (!error)
+		return __dentry_open(nd.dentry, nd.mnt, flags, f);
+
+	put_filp(f);
+	return ERR_PTR(error);
+}
+EXPORT_SYMBOL(filp_open);
+
+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
+{
+	int error;
+	struct file *f;
+
+	error = -ENFILE;
+	f = get_empty_filp();
+	if (f == NULL)
+		return ERR_PTR(error);
+
+	return __dentry_open(dentry, mnt, flags, f);
+}
 EXPORT_SYMBOL(dentry_open);
 
 /*
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index c9f178f..c20babd 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -667,7 +667,7 @@
 	if (th->t_trans_id) {
 		int err;
 		// update any changes we made to blk count
-		reiserfs_update_sd(th, inode);
+		mark_inode_dirty(inode);
 		err =
 		    journal_end(th, inode->i_sb,
 				JOURNAL_PER_BALANCE_CNT * 3 + 1 +
@@ -855,17 +855,18 @@
 
 		if (th->t_trans_id) {
 			reiserfs_write_lock(inode->i_sb);
-			reiserfs_update_sd(th, inode);	// And update on-disk metadata
+			// this sets the proper flags for O_SYNC to trigger a commit
+			mark_inode_dirty(inode);
 			reiserfs_write_unlock(inode->i_sb);
 		} else
-			inode->i_sb->s_op->dirty_inode(inode);
+			mark_inode_dirty(inode);
 
 		sd_update = 1;
 	}
 	if (th->t_trans_id) {
 		reiserfs_write_lock(inode->i_sb);
 		if (!sd_update)
-			reiserfs_update_sd(th, inode);
+			mark_inode_dirty(inode);
 		status = journal_end(th, th->t_super, th->t_blocks_allocated);
 		if (status)
 			retval = status;
@@ -1320,7 +1321,7 @@
 				return err;
 			}
 			reiserfs_update_inode_transaction(inode);
-			reiserfs_update_sd(&th, inode);
+			mark_inode_dirty(inode);
 			err = journal_end(&th, inode->i_sb, 1);
 			if (err) {
 				reiserfs_write_unlock(inode->i_sb);
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 1a8a1bf..d76ee6c 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -2639,6 +2639,12 @@
 		}
 		reiserfs_update_inode_transaction(inode);
 		inode->i_size = pos;
+		/*
+		 * this will just nest into our transaction.  It's important
+		 * to use mark_inode_dirty so the inode gets pushed around on the
+		 * dirty lists, and so that O_SYNC works as expected
+		 */
+		mark_inode_dirty(inode);
 		reiserfs_update_sd(&myth, inode);
 		update_sd = 1;
 		ret = journal_end(&myth, inode->i_sb, 1);
@@ -2649,21 +2655,13 @@
 	if (th) {
 		reiserfs_write_lock(inode->i_sb);
 		if (!update_sd)
-			reiserfs_update_sd(th, inode);
+			mark_inode_dirty(inode);
 		ret = reiserfs_end_persistent_transaction(th);
 		reiserfs_write_unlock(inode->i_sb);
 		if (ret)
 			goto out;
 	}
 
-	/* we test for O_SYNC here so we can commit the transaction
-	 ** for any packed tails the file might have had
-	 */
-	if (f && (f->f_flags & O_SYNC)) {
-		reiserfs_write_lock(inode->i_sb);
-		ret = reiserfs_commit_for_inode(inode);
-		reiserfs_write_unlock(inode->i_sb);
-	}
       out:
 	return ret;
 
diff --git a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h
index 22b53e3..8393bf3 100644
--- a/include/asm-alpha/pgtable.h
+++ b/include/asm-alpha/pgtable.h
@@ -339,13 +339,6 @@
 #define kern_addr_valid(addr)	(1)
 #endif
 
-#define io_remap_page_range(vma, start, busaddr, size, prot)	\
-({								\
-	void *va = (void __force *)ioremap(busaddr, size);	\
-	unsigned long pfn = virt_to_phys(va) >> PAGE_SHIFT;	\
-	remap_pfn_range(vma, start, pfn, size, prot);		\
-})
-
 #define io_remap_pfn_range(vma, start, pfn, size, prot)	\
 		remap_pfn_range(vma, start, pfn, size, prot)
 
diff --git a/include/asm-arm/arch-pxa/akita.h b/include/asm-arm/arch-pxa/akita.h
new file mode 100644
index 0000000..4a1fbcf
--- /dev/null
+++ b/include/asm-arm/arch-pxa/akita.h
@@ -0,0 +1,30 @@
+/*
+ * Hardware specific definitions for SL-C1000 (Akita)
+ *
+ * Copyright (c) 2005 Richard Purdie
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+/* Akita IO Expander GPIOs */
+
+#define AKITA_IOEXP_RESERVED_7      (1 << 7)
+#define AKITA_IOEXP_IR_ON           (1 << 6)
+#define AKITA_IOEXP_AKIN_PULLUP     (1 << 5)
+#define AKITA_IOEXP_BACKLIGHT_CONT  (1 << 4)
+#define AKITA_IOEXP_BACKLIGHT_ON    (1 << 3)
+#define AKITA_IOEXP_MIC_BIAS        (1 << 2)
+#define AKITA_IOEXP_RESERVED_1      (1 << 1)
+#define AKITA_IOEXP_RESERVED_0      (1 << 0)
+
+/* Direction Bitfield  0=output  1=input */
+#define AKITA_IOEXP_IO_DIR	0
+/* Default Values */
+#define AKITA_IOEXP_IO_OUT	(AKITA_IOEXP_IR_ON | AKITA_IOEXP_AKIN_PULLUP)
+
+void akita_set_ioexp(struct device *dev, unsigned char bitmask);
+void akita_reset_ioexp(struct device *dev, unsigned char bitmask);
+
diff --git a/include/asm-arm/arch-pxa/corgi.h b/include/asm-arm/arch-pxa/corgi.h
index 4b7aa0b..e554caa 100644
--- a/include/asm-arm/arch-pxa/corgi.h
+++ b/include/asm-arm/arch-pxa/corgi.h
@@ -106,17 +106,5 @@
 extern struct platform_device corgissp_device;
 extern struct platform_device corgifb_device;
 
-/*
- * External Functions
- */
-extern unsigned long corgi_ssp_ads7846_putget(unsigned long);
-extern unsigned long corgi_ssp_ads7846_get(void);
-extern void corgi_ssp_ads7846_put(unsigned long data);
-extern void corgi_ssp_ads7846_lock(void);
-extern void corgi_ssp_ads7846_unlock(void);
-extern void corgi_ssp_lcdtg_send (unsigned char adrs, unsigned char data);
-extern void corgi_ssp_blduty_set(int duty);
-extern int corgi_ssp_max1111_get(unsigned long data);
-
 #endif /* __ASM_ARCH_CORGI_H  */
 
diff --git a/include/asm-arm/arch-pxa/sharpsl.h b/include/asm-arm/arch-pxa/sharpsl.h
new file mode 100644
index 0000000..311f2bb
--- /dev/null
+++ b/include/asm-arm/arch-pxa/sharpsl.h
@@ -0,0 +1,32 @@
+/*
+ * SharpSL SSP Driver
+ */
+
+unsigned long corgi_ssp_ads7846_putget(unsigned long);
+unsigned long corgi_ssp_ads7846_get(void);
+void corgi_ssp_ads7846_put(unsigned long data);
+void corgi_ssp_ads7846_lock(void);
+void corgi_ssp_ads7846_unlock(void);
+void corgi_ssp_lcdtg_send (unsigned char adrs, unsigned char data);
+void corgi_ssp_blduty_set(int duty);
+int corgi_ssp_max1111_get(unsigned long data);
+
+/*
+ * SharpSL Touchscreen Driver
+ */
+
+struct corgits_machinfo {
+	unsigned long (*get_hsync_len)(void);
+	void (*put_hsync)(void);
+	void (*wait_hsync)(void);
+};
+
+/*
+ * SharpSL Backlight
+ */
+
+struct corgibl_machinfo {
+	int max_intensity;
+	void (*set_bl_intensity)(int intensity);
+};
+
diff --git a/include/asm-arm/arch-pxa/spitz.h b/include/asm-arm/arch-pxa/spitz.h
new file mode 100644
index 0000000..62e1fe4
--- /dev/null
+++ b/include/asm-arm/arch-pxa/spitz.h
@@ -0,0 +1,158 @@
+/*
+ * Hardware specific definitions for SL-Cx000 series of PDAs
+ *
+ * Copyright (c) 2005 Alexander Wykes
+ * Copyright (c) 2005 Richard Purdie
+ *
+ * Based on Sharp's 2.4 kernel patches
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#ifndef __ASM_ARCH_SPITZ_H
+#define __ASM_ARCH_SPITZ_H  1
+#endif
+
+/* Spitz/Akita GPIOs */
+
+#define SPITZ_GPIO_KEY_INT         (0) /* Key Interrupt */
+#define SPITZ_GPIO_RESET           (1)
+#define SPITZ_GPIO_nSD_DETECT      (9)
+#define SPITZ_GPIO_TP_INT          (11) /* Touch Panel interrupt */
+#define SPITZ_GPIO_AK_INT          (13) /* Remote Control */
+#define SPITZ_GPIO_ADS7846_CS      (14)
+#define SPITZ_GPIO_SYNC            (16)
+#define SPITZ_GPIO_MAX1111_CS      (20)
+#define SPITZ_GPIO_FATAL_BAT       (21)
+#define SPITZ_GPIO_HSYNC           (22)
+#define SPITZ_GPIO_nSD_CLK         (32)
+#define SPITZ_GPIO_USB_DEVICE      (35)
+#define SPITZ_GPIO_USB_HOST        (37)
+#define SPITZ_GPIO_USB_CONNECT     (41)
+#define SPITZ_GPIO_LCDCON_CS       (53)
+#define SPITZ_GPIO_nPCE            (54)
+#define SPITZ_GPIO_nSD_WP          (81)
+#define SPITZ_GPIO_ON_RESET        (89)
+#define SPITZ_GPIO_BAT_COVER       (90)
+#define SPITZ_GPIO_CF_CD           (94)
+#define SPITZ_GPIO_ON_KEY          (95)
+#define SPITZ_GPIO_SWA             (97)
+#define SPITZ_GPIO_SWB             (96)
+#define SPITZ_GPIO_CHRG_FULL       (101)
+#define SPITZ_GPIO_CO              (101)
+#define SPITZ_GPIO_CF_IRQ          (105)
+#define SPITZ_GPIO_AC_IN           (115)
+#define SPITZ_GPIO_HP_IN           (116)
+
+/* Spitz Only GPIOs */
+
+#define SPITZ_GPIO_CF2_IRQ         (106) /* CF slot1 Ready */
+#define SPITZ_GPIO_CF2_CD          (93)
+
+
+/* Spitz/Akita Keyboard Definitions */
+
+#define SPITZ_KEY_STROBE_NUM         (11)
+#define SPITZ_KEY_SENSE_NUM          (7)
+#define SPITZ_GPIO_G0_STROBE_BIT     0x0f800000
+#define SPITZ_GPIO_G1_STROBE_BIT     0x00100000
+#define SPITZ_GPIO_G2_STROBE_BIT     0x01000000
+#define SPITZ_GPIO_G3_STROBE_BIT     0x00041880
+#define SPITZ_GPIO_G0_SENSE_BIT      0x00021000
+#define SPITZ_GPIO_G1_SENSE_BIT      0x000000d4
+#define SPITZ_GPIO_G2_SENSE_BIT      0x08000000
+#define SPITZ_GPIO_G3_SENSE_BIT      0x00000000
+
+#define SPITZ_GPIO_KEY_STROBE0       88
+#define SPITZ_GPIO_KEY_STROBE1       23
+#define SPITZ_GPIO_KEY_STROBE2       24
+#define SPITZ_GPIO_KEY_STROBE3       25
+#define SPITZ_GPIO_KEY_STROBE4       26
+#define SPITZ_GPIO_KEY_STROBE5       27
+#define SPITZ_GPIO_KEY_STROBE6       52
+#define SPITZ_GPIO_KEY_STROBE7       103
+#define SPITZ_GPIO_KEY_STROBE8       107
+#define SPITZ_GPIO_KEY_STROBE9       108
+#define SPITZ_GPIO_KEY_STROBE10      114
+
+#define SPITZ_GPIO_KEY_SENSE0        12
+#define SPITZ_GPIO_KEY_SENSE1        17
+#define SPITZ_GPIO_KEY_SENSE2        91
+#define SPITZ_GPIO_KEY_SENSE3        34
+#define SPITZ_GPIO_KEY_SENSE4        36
+#define SPITZ_GPIO_KEY_SENSE5        38
+#define SPITZ_GPIO_KEY_SENSE6        39
+
+
+/* Spitz Scoop Device (No. 1) GPIOs */
+/* Suspend States in comments */
+#define SPITZ_SCP_LED_GREEN     SCOOP_GPCR_PA11  /* Keep */
+#define SPITZ_SCP_JK_B          SCOOP_GPCR_PA12  /* Keep */
+#define SPITZ_SCP_CHRG_ON       SCOOP_GPCR_PA13  /* Keep */
+#define SPITZ_SCP_MUTE_L        SCOOP_GPCR_PA14  /* Low */
+#define SPITZ_SCP_MUTE_R        SCOOP_GPCR_PA15  /* Low */
+#define SPITZ_SCP_CF_POWER      SCOOP_GPCR_PA16  /* Keep */
+#define SPITZ_SCP_LED_ORANGE    SCOOP_GPCR_PA17  /* Keep */
+#define SPITZ_SCP_JK_A          SCOOP_GPCR_PA18  /* Low */
+#define SPITZ_SCP_ADC_TEMP_ON   SCOOP_GPCR_PA19  /* Low */
+
+#define SPITZ_SCP_IO_DIR      (SPITZ_SCP_LED_GREEN | SPITZ_SCP_JK_B | SPITZ_SCP_CHRG_ON | \
+                               SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R | SPITZ_SCP_LED_ORANGE | \
+                               SPITZ_SCP_CF_POWER | SPITZ_SCP_JK_A | SPITZ_SCP_ADC_TEMP_ON)
+#define SPITZ_SCP_IO_OUT      (SPITZ_SCP_CHRG_ON | SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R)
+#define SPITZ_SCP_SUS_CLR     (SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R | SPITZ_SCP_JK_A | SPITZ_SCP_ADC_TEMP_ON)
+#define SPITZ_SCP_SUS_SET     0
+
+/* Spitz Scoop Device (No. 2) GPIOs */
+/* Suspend States in comments */
+#define SPITZ_SCP2_IR_ON           SCOOP_GPCR_PA11  /* High */
+#define SPITZ_SCP2_AKIN_PULLUP     SCOOP_GPCR_PA12  /* Keep */
+#define SPITZ_SCP2_RESERVED_1      SCOOP_GPCR_PA13  /* High */
+#define SPITZ_SCP2_RESERVED_2      SCOOP_GPCR_PA14  /* Low */
+#define SPITZ_SCP2_RESERVED_3      SCOOP_GPCR_PA15  /* Low */
+#define SPITZ_SCP2_RESERVED_4      SCOOP_GPCR_PA16  /* Low */
+#define SPITZ_SCP2_BACKLIGHT_CONT  SCOOP_GPCR_PA17  /* Low */
+#define SPITZ_SCP2_BACKLIGHT_ON    SCOOP_GPCR_PA18  /* Low */
+#define SPITZ_SCP2_MIC_BIAS        SCOOP_GPCR_PA19  /* Low */
+
+#define SPITZ_SCP2_IO_DIR (SPITZ_SCP2_IR_ON | SPITZ_SCP2_AKIN_PULLUP | SPITZ_SCP2_RESERVED_1 | \
+                           SPITZ_SCP2_RESERVED_2 | SPITZ_SCP2_RESERVED_3 | SPITZ_SCP2_RESERVED_4 | \
+                           SPITZ_SCP2_BACKLIGHT_CONT | SPITZ_SCP2_BACKLIGHT_ON | SPITZ_SCP2_MIC_BIAS)
+
+#define SPITZ_SCP2_IO_OUT   (SPITZ_SCP2_IR_ON | SPITZ_SCP2_AKIN_PULLUP | SPITZ_SCP2_RESERVED_1)
+#define SPITZ_SCP2_SUS_CLR  (SPITZ_SCP2_RESERVED_2 | SPITZ_SCP2_RESERVED_3 | SPITZ_SCP2_RESERVED_4 | \
+                             SPITZ_SCP2_BACKLIGHT_CONT | SPITZ_SCP2_BACKLIGHT_ON | SPITZ_SCP2_MIC_BIAS)
+#define SPITZ_SCP2_SUS_SET  (SPITZ_SCP2_IR_ON | SPITZ_SCP2_RESERVED_1)
+
+
+/* Spitz IRQ Definitions */
+
+#define SPITZ_IRQ_GPIO_KEY_INT        IRQ_GPIO(SPITZ_GPIO_KEY_INT)
+#define SPITZ_IRQ_GPIO_AC_IN          IRQ_GPIO(SPITZ_GPIO_AC_IN)
+#define SPITZ_IRQ_GPIO_AK_INT         IRQ_GPIO(SPITZ_GPIO_AK_INT)
+#define SPITZ_IRQ_GPIO_HP_IN          IRQ_GPIO(SPITZ_GPIO_HP_IN)
+#define SPITZ_IRQ_GPIO_TP_INT         IRQ_GPIO(SPITZ_GPIO_TP_INT)
+#define SPITZ_IRQ_GPIO_SYNC           IRQ_GPIO(SPITZ_GPIO_SYNC)
+#define SPITZ_IRQ_GPIO_ON_KEY         IRQ_GPIO(SPITZ_GPIO_ON_KEY)
+#define SPITZ_IRQ_GPIO_SWA            IRQ_GPIO(SPITZ_GPIO_SWA)
+#define SPITZ_IRQ_GPIO_SWB            IRQ_GPIO(SPITZ_GPIO_SWB)
+#define SPITZ_IRQ_GPIO_BAT_COVER      IRQ_GPIO(SPITZ_GPIO_BAT_COVER)
+#define SPITZ_IRQ_GPIO_FATAL_BAT      IRQ_GPIO(SPITZ_GPIO_FATAL_BAT)
+#define SPITZ_IRQ_GPIO_CO             IRQ_GPIO(SPITZ_GPIO_CO)
+#define SPITZ_IRQ_GPIO_CF_IRQ         IRQ_GPIO(SPITZ_GPIO_CF_IRQ)
+#define SPITZ_IRQ_GPIO_CF_CD          IRQ_GPIO(SPITZ_GPIO_CF_CD)
+#define SPITZ_IRQ_GPIO_CF2_IRQ        IRQ_GPIO(SPITZ_GPIO_CF2_IRQ)
+#define SPITZ_IRQ_GPIO_nSD_INT        IRQ_GPIO(SPITZ_GPIO_nSD_INT)
+#define SPITZ_IRQ_GPIO_nSD_DETECT     IRQ_GPIO(SPITZ_GPIO_nSD_DETECT)
+
+/*
+ * Shared data structures
+ */
+extern struct platform_device spitzscoop_device;
+extern struct platform_device spitzscoop2_device;
+extern struct platform_device spitzssp_device;
+extern struct sharpsl_charger_machinfo spitz_pm_machinfo;
+
+extern void spitz_lcd_power(int on);
diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h
index 478c49b..366bafb 100644
--- a/include/asm-arm/pgtable.h
+++ b/include/asm-arm/pgtable.h
@@ -445,12 +445,9 @@
 #define HAVE_ARCH_UNMAPPED_AREA
 
 /*
- * remap a physical address `phys' of size `size' with page protection `prot'
+ * remap a physical page `pfn' of size `size' with page protection `prot'
  * into virtual address `from'
  */
-#define io_remap_page_range(vma,from,phys,size,prot) \
-		remap_pfn_range(vma, from, (phys) >> PAGE_SHIFT, size, prot)
-
 #define io_remap_pfn_range(vma,from,pfn,size,prot) \
 		remap_pfn_range(vma, from, pfn, size, prot)
 
diff --git a/include/asm-arm26/pgtable.h b/include/asm-arm26/pgtable.h
index 4a0a00d..f602cf5 100644
--- a/include/asm-arm26/pgtable.h
+++ b/include/asm-arm26/pgtable.h
@@ -294,12 +294,9 @@
 #include <asm-generic/pgtable.h>
 
 /*
- * remap a physical address `phys' of size `size' with page protection `prot'
+ * remap a physical page `pfn' of size `size' with page protection `prot'
  * into virtual address `from'
  */
-#define io_remap_page_range(vma,from,phys,size,prot) \
-		remap_pfn_range(vma, from, (phys) >> PAGE_SHIFT, size, prot)
-
 #define io_remap_pfn_range(vma,from,pfn,size,prot) \
 		remap_pfn_range(vma, from, pfn, size, prot)
 
diff --git a/include/asm-frv/pgtable.h b/include/asm-frv/pgtable.h
index d0a9c2f..473fb4b 100644
--- a/include/asm-frv/pgtable.h
+++ b/include/asm-frv/pgtable.h
@@ -500,9 +500,6 @@
 #define PageSkip(page)		(0)
 #define kern_addr_valid(addr)	(1)
 
-#define io_remap_page_range(vma, vaddr, paddr, size, prot)		\
-		remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
-
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
 		remap_pfn_range(vma, vaddr, pfn, size, prot)
 
diff --git a/include/asm-h8300/pgtable.h b/include/asm-h8300/pgtable.h
index 69076eb..f6e296f 100644
--- a/include/asm-h8300/pgtable.h
+++ b/include/asm-h8300/pgtable.h
@@ -52,8 +52,6 @@
  * No page table caches to initialise
  */
 #define pgtable_cache_init()   do { } while (0)
-#define io_remap_page_range(vma, vaddr, paddr, size, prot)		\
-		remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
 
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
 		remap_pfn_range(vma, vaddr, pfn, size, prot)
diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h
index 47bc1ff..d101ac4 100644
--- a/include/asm-i386/pgtable.h
+++ b/include/asm-i386/pgtable.h
@@ -431,9 +431,6 @@
 #define kern_addr_valid(addr)	(1)
 #endif /* CONFIG_FLATMEM */
 
-#define io_remap_page_range(vma, vaddr, paddr, size, prot)		\
-		remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
-
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
 		remap_pfn_range(vma, vaddr, pfn, size, prot)
 
diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
index 2e34c06..3339c7b 100644
--- a/include/asm-ia64/pgtable.h
+++ b/include/asm-ia64/pgtable.h
@@ -443,10 +443,6 @@
 #define pte_to_pgoff(pte)		((pte_val(pte) << 1) >> 3)
 #define pgoff_to_pte(off)		((pte_t) { ((off) << 2) | _PAGE_FILE })
 
-/* XXX is this right? */
-#define io_remap_page_range(vma, vaddr, paddr, size, prot)		\
-		remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
-
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
 		remap_pfn_range(vma, vaddr, pfn, size, prot)
 
diff --git a/include/asm-m32r/pgtable.h b/include/asm-m32r/pgtable.h
index da805e9..388e5ee 100644
--- a/include/asm-m32r/pgtable.h
+++ b/include/asm-m32r/pgtable.h
@@ -378,9 +378,6 @@
 /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
 #define kern_addr_valid(addr)	(1)
 
-#define io_remap_page_range(vma, vaddr, paddr, size, prot)	\
-	remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
-
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)	\
 		remap_pfn_range(vma, vaddr, pfn, size, prot)
 
diff --git a/include/asm-m68k/pgtable.h b/include/asm-m68k/pgtable.h
index 0c87fc8..add129e 100644
--- a/include/asm-m68k/pgtable.h
+++ b/include/asm-m68k/pgtable.h
@@ -141,9 +141,6 @@
 
 #define kern_addr_valid(addr)	(1)
 
-#define io_remap_page_range(vma, vaddr, paddr, size, prot)		\
-		remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
-
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
 		remap_pfn_range(vma, vaddr, pfn, size, prot)
 
diff --git a/include/asm-m68knommu/pgtable.h b/include/asm-m68knommu/pgtable.h
index e2a69ff..0089305 100644
--- a/include/asm-m68knommu/pgtable.h
+++ b/include/asm-m68knommu/pgtable.h
@@ -56,8 +56,6 @@
  * No page table caches to initialise.
  */
 #define pgtable_cache_init()	do { } while (0)
-#define io_remap_page_range(vma, vaddr, paddr, size, prot)		\
-		remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
 
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
 		remap_pfn_range(vma, vaddr, pfn, size, prot)
diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h
index dbe13da..cbd1672 100644
--- a/include/asm-mips/pgtable.h
+++ b/include/asm-mips/pgtable.h
@@ -358,16 +358,6 @@
 extern phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size);
 extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot);
 
-static inline int io_remap_page_range(struct vm_area_struct *vma,
-		unsigned long vaddr,
-		unsigned long paddr,
-		unsigned long size,
-		pgprot_t prot)
-{
-	phys_t phys_addr_high = fixup_bigphys_addr(paddr, size);
-	return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot);
-}
-
 static inline int io_remap_pfn_range(struct vm_area_struct *vma,
 		unsigned long vaddr,
 		unsigned long pfn,
@@ -378,8 +368,6 @@
 	return remap_pfn_range(vma, vaddr, pfn, size, prot);
 }
 #else
-#define io_remap_page_range(vma, vaddr, paddr, size, prot)		\
-		remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
 		remap_pfn_range(vma, vaddr, pfn, size, prot)
 #endif
diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h
index f001bb0..820c6e7 100644
--- a/include/asm-parisc/pgtable.h
+++ b/include/asm-parisc/pgtable.h
@@ -498,9 +498,6 @@
 
 #endif /* !__ASSEMBLY__ */
 
-#define io_remap_page_range(vma, vaddr, paddr, size, prot)		\
-		remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
-
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
 		remap_pfn_range(vma, vaddr, pfn, size, prot)
 
diff --git a/include/asm-ppc/mv64x60.h b/include/asm-ppc/mv64x60.h
index 835930d..75c2ffa 100644
--- a/include/asm-ppc/mv64x60.h
+++ b/include/asm-ppc/mv64x60.h
@@ -119,6 +119,14 @@
 
 #define	MV64x60_64BIT_WIN_COUNT			24
 
+/* Watchdog Platform Device, Driver Data */
+#define	MV64x60_WDT_NAME			"wdt"
+
+struct mv64x60_wdt_pdata {
+	int	timeout;	/* watchdog expiry in seconds, default 10 */
+	int	bus_clk;	/* bus clock in MHz, default 133 */
+};
+
 /*
  * Define a structure that's used to pass in config information to the
  * core routines.
diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h
index 92f30b2..eee601b 100644
--- a/include/asm-ppc/pgtable.h
+++ b/include/asm-ppc/pgtable.h
@@ -812,15 +812,6 @@
 #ifdef CONFIG_PHYS_64BIT
 extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
 			unsigned long paddr, unsigned long size, pgprot_t prot);
-static inline int io_remap_page_range(struct vm_area_struct *vma,
-					unsigned long vaddr,
-					unsigned long paddr,
-					unsigned long size,
-					pgprot_t prot)
-{
-	phys_addr_t paddr64 = fixup_bigphys_addr(paddr, size);
-	return remap_pfn_range(vma, vaddr, paddr64 >> PAGE_SHIFT, size, prot);
-}
 
 static inline int io_remap_pfn_range(struct vm_area_struct *vma,
 					unsigned long vaddr,
@@ -832,8 +823,6 @@
 	return remap_pfn_range(vma, vaddr, paddr64 >> PAGE_SHIFT, size, prot);
 }
 #else
-#define io_remap_page_range(vma, vaddr, paddr, size, prot)		\
-		remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
 		remap_pfn_range(vma, vaddr, pfn, size, prot)
 #endif
diff --git a/include/asm-ppc/segment.h b/include/asm-ppc/segment.h
deleted file mode 100644
index 0f2f742..0000000
--- a/include/asm-ppc/segment.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm/uaccess.h>
diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h
index ecb9095..0f4bcaa 100644
--- a/include/asm-sh/pgtable.h
+++ b/include/asm-sh/pgtable.h
@@ -277,9 +277,6 @@
 
 #define kern_addr_valid(addr)	(1)
 
-#define io_remap_page_range(vma, vaddr, paddr, size, prot)		\
-		remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
-
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
 		remap_pfn_range(vma, vaddr, pfn, size, prot)
 
diff --git a/include/asm-sh64/pgtable.h b/include/asm-sh64/pgtable.h
index 78ac6be..51db430 100644
--- a/include/asm-sh64/pgtable.h
+++ b/include/asm-sh64/pgtable.h
@@ -482,9 +482,6 @@
 #define PageSkip(page)		(0)
 #define kern_addr_valid(addr)	(1)
 
-#define io_remap_page_range(vma, vaddr, paddr, size, prot)		\
-		remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
-
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
 		remap_pfn_range(vma, vaddr, pfn, size, prot)
 
diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h
index 1dc110b..2cb4835 100644
--- a/include/asm-x86_64/pgtable.h
+++ b/include/asm-x86_64/pgtable.h
@@ -421,9 +421,6 @@
 
 extern int kern_addr_valid(unsigned long addr); 
 
-#define io_remap_page_range(vma, vaddr, paddr, size, prot)		\
-		remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
-
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
 		remap_pfn_range(vma, vaddr, pfn, size, prot)
 
diff --git a/include/asm-xtensa/pgtable.h b/include/asm-xtensa/pgtable.h
index 883ebc2..987e3b8 100644
--- a/include/asm-xtensa/pgtable.h
+++ b/include/asm-xtensa/pgtable.h
@@ -441,11 +441,11 @@
 			      unsigned long address, pte_t pte);
 
 /*
- * remap a physical address `phys' of size `size' with page protection `prot'
+ * remap a physical page `pfn' of size `size' with page protection `prot'
  * into virtual address `from'
  */
-#define io_remap_page_range(vma,from,phys,size,prot) \
-                remap_pfn_range(vma, from, (phys) >> PAGE_SHIFT, size, prot)
+#define io_remap_pfn_range(vma,from,pfn,size,prot) \
+                remap_pfn_range(vma, from, pfn, size, prot)
 
 
 /* No page table caches to init */
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 68aba0c..b2a2509 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -51,7 +51,8 @@
 #define AUDIT_WATCH_LIST	1009	/* List all file/dir watches */
 #define AUDIT_SIGNAL_INFO	1010	/* Get info about sender of signal to auditd */
 
-#define AUDIT_FIRST_USER_MSG	1100	/* Userspace messages uninteresting to kernel */
+#define AUDIT_FIRST_USER_MSG	1100	/* Userspace messages mostly uninteresting to kernel */
+#define AUDIT_USER_AVC		1107	/* We filter this differently */
 #define AUDIT_LAST_USER_MSG	1199
  
 #define AUDIT_DAEMON_START      1200    /* Daemon startup record */
@@ -75,10 +76,15 @@
 #define AUDIT_KERNEL		2000	/* Asynchronous audit record. NOT A REQUEST. */
 
 /* Rule flags */
-#define AUDIT_PER_TASK 0x01	/* Apply rule at task creation (not syscall) */
-#define AUDIT_AT_ENTRY 0x02	/* Apply rule at syscall entry */
-#define AUDIT_AT_EXIT  0x04	/* Apply rule at syscall exit */
-#define AUDIT_PREPEND  0x10	/* Prepend to front of list */
+#define AUDIT_FILTER_USER	0x00	/* Apply rule to user-generated messages */
+#define AUDIT_FILTER_TASK	0x01	/* Apply rule at task creation (not syscall) */
+#define AUDIT_FILTER_ENTRY	0x02	/* Apply rule at syscall entry */
+#define AUDIT_FILTER_WATCH	0x03	/* Apply rule to file system watches */
+#define AUDIT_FILTER_EXIT	0x04	/* Apply rule at syscall exit */
+
+#define AUDIT_NR_FILTERS	5
+
+#define AUDIT_FILTER_PREPEND	0x10	/* Prepend to front of list */
 
 /* Rule actions */
 #define AUDIT_NEVER    0	/* Do not build context if rule matches */
@@ -199,6 +205,7 @@
 struct audit_buffer;
 struct audit_context;
 struct inode;
+struct netlink_skb_parms;
 
 #define AUDITSC_INVALID 0
 #define AUDITSC_SUCCESS 1
@@ -215,7 +222,7 @@
 extern void audit_syscall_exit(struct task_struct *task, int failed, long return_code);
 extern void audit_getname(const char *name);
 extern void audit_putname(const char *name);
-extern void audit_inode(const char *name, const struct inode *inode);
+extern void audit_inode(const char *name, const struct inode *inode, unsigned flags);
 
 				/* Private API (for audit.c only) */
 extern int  audit_receive_filter(int type, int pid, int uid, int seq,
@@ -230,6 +237,7 @@
 extern int audit_sockaddr(int len, void *addr);
 extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
 extern void audit_signal_info(int sig, struct task_struct *t);
+extern int audit_filter_user(struct netlink_skb_parms *cb, int type);
 #else
 #define audit_alloc(t) ({ 0; })
 #define audit_free(t) do { ; } while (0)
@@ -237,7 +245,7 @@
 #define audit_syscall_exit(t,f,r) do { ; } while (0)
 #define audit_getname(n) do { ; } while (0)
 #define audit_putname(n) do { ; } while (0)
-#define audit_inode(n,i) do { ; } while (0)
+#define audit_inode(n,i,f) do { ; } while (0)
 #define audit_receive_filter(t,p,u,s,d,l) ({ -EOPNOTSUPP; })
 #define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
 #define audit_get_loginuid(c) ({ -1; })
@@ -246,16 +254,17 @@
 #define audit_sockaddr(len, addr) ({ 0; })
 #define audit_avc_path(dentry, mnt) ({ 0; })
 #define audit_signal_info(s,t) do { ; } while (0)
+#define audit_filter_user(cb,t) ({ 1; })
 #endif
 
 #ifdef CONFIG_AUDIT
 /* These are defined in audit.c */
 				/* Public API */
-extern void		    audit_log(struct audit_context *ctx, int type,
-				      const char *fmt, ...)
-			    __attribute__((format(printf,3,4)));
+extern void		    audit_log(struct audit_context *ctx, int gfp_mask,
+				      int type, const char *fmt, ...)
+				      __attribute__((format(printf,4,5)));
 
-extern struct audit_buffer *audit_log_start(struct audit_context *ctx,int type);
+extern struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask, int type);
 extern void		    audit_log_format(struct audit_buffer *ab,
 					     const char *fmt, ...)
 			    __attribute__((format(printf,2,3)));
@@ -274,9 +283,10 @@
 					     int done, int multi,
 					     void *payload, int size);
 extern void		    audit_log_lost(const char *message);
+extern struct semaphore audit_netlink_sem;
 #else
-#define audit_log(c,t,f,...) do { ; } while (0)
-#define audit_log_start(c,t) ({ NULL; })
+#define audit_log(c,g,t,f,...) do { ; } while (0)
+#define audit_log_start(c,g,t) ({ NULL; })
 #define audit_log_vformat(b,f,a) do { ; } while (0)
 #define audit_log_format(b,f,...) do { ; } while (0)
 #define audit_log_end(b) do { ; } while (0)
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 82e39cd..c698055 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -619,7 +619,7 @@
 	__u32 height;               /* height of each tile in scanlines */
 	__u32 depth;                /* color depth of each tile */
 	__u32 length;               /* number of tiles in the map */
-	__u8  *data;                /* actual tile map: a bitmap array, packed
+	const __u8 *data;           /* actual tile map: a bitmap array, packed
 				       to the nearest byte */
 };
 
diff --git a/include/linux/font.h b/include/linux/font.h
index 8fc80a7..53b129f 100644
--- a/include/linux/font.h
+++ b/include/linux/font.h
@@ -15,9 +15,9 @@
 
 struct font_desc {
     int idx;
-    char *name;
+    const char *name;
     int width, height;
-    void *data;
+    const void *data;
     int pref;
 };
 
@@ -32,7 +32,7 @@
 #define ACORN8x8_IDX	8
 #define	MINI4x6_IDX	9
 
-extern struct font_desc	font_vga_8x8,
+extern const struct font_desc	font_vga_8x8,
 			font_vga_8x16,
 			font_pearl_8x8,
 			font_vga_6x11,
@@ -45,11 +45,11 @@
 
 /* Find a font with a specific name */
 
-extern struct font_desc *find_font(char *name);
+extern const struct font_desc *find_font(const char *name);
 
 /* Get the default font for a specific screen size */
 
-extern struct font_desc *get_default_font(int xres, int yres);
+extern const struct font_desc *get_default_font(int xres, int yres);
 
 /* Max. length for the name of a predefined font */
 #define MAX_FONT_NAME	32
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 687ba8c..4367ce4 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -307,8 +307,8 @@
 	char _f[20-2*sizeof(long)-sizeof(int)];	/* Padding: libc5 uses this.. */
 };
 
-extern void BUILD_BUG(void);
-#define BUILD_BUG_ON(condition) do { if (condition) BUILD_BUG(); } while(0)
+/* Force a compilation error if condition is false */
+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
 
 #ifdef CONFIG_SYSCTL
 extern int randomize_va_space;
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
index 4d24d65..8903688 100644
--- a/include/linux/nfsd/xdr4.h
+++ b/include/linux/nfsd/xdr4.h
@@ -438,17 +438,22 @@
 extern int nfsd4_process_open2(struct svc_rqst *rqstp, 
 		struct svc_fh *current_fh, struct nfsd4_open *open);
 extern int nfsd4_open_confirm(struct svc_rqst *rqstp, 
-		struct svc_fh *current_fh, struct nfsd4_open_confirm *oc);
+		struct svc_fh *current_fh, struct nfsd4_open_confirm *oc,
+		struct nfs4_stateowner **);
 extern  int nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, 
-		struct nfsd4_close *close);
+		struct nfsd4_close *close,
+		struct nfs4_stateowner **replay_owner);
 extern int nfsd4_open_downgrade(struct svc_rqst *rqstp, 
-		struct svc_fh *current_fh, struct nfsd4_open_downgrade *od);
+		struct svc_fh *current_fh, struct nfsd4_open_downgrade *od,
+		struct nfs4_stateowner **replay_owner);
 extern int nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, 
-		struct nfsd4_lock *lock);
+		struct nfsd4_lock *lock,
+		struct nfs4_stateowner **replay_owner);
 extern int nfsd4_lockt(struct svc_rqst *rqstp, struct svc_fh *current_fh, 
 		struct nfsd4_lockt *lockt);
 extern int nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, 
-		struct nfsd4_locku *locku);
+		struct nfsd4_locku *locku,
+		struct nfs4_stateowner **replay_owner);
 extern int
 nfsd4_release_lockowner(struct svc_rqst *rqstp,
 		struct nfsd4_release_lockowner *rlockowner);
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index ee0ab7a5..f6c1a14 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -447,6 +447,10 @@
 #define PCI_DEVICE_ID_CIRRUS_7542	0x1200
 #define PCI_DEVICE_ID_CIRRUS_7543	0x1202
 #define PCI_DEVICE_ID_CIRRUS_7541	0x1204
+#define PCI_DEVICE_ID_CIRRUS_4610	0x6001
+#define PCI_DEVICE_ID_CIRRUS_4612	0x6003
+#define PCI_DEVICE_ID_CIRRUS_4615	0x6004
+#define PCI_DEVICE_ID_CIRRUS_4281	0x6005
 
 #define PCI_VENDOR_ID_IBM		0x1014
 #define PCI_DEVICE_ID_IBM_FIRE_CORAL	0x000a
@@ -682,7 +686,9 @@
 #define PCI_DEVICE_ID_SI_6326		0x6326
 #define PCI_DEVICE_ID_SI_7001		0x7001
 #define PCI_DEVICE_ID_SI_7012		0x7012
+#define PCI_DEVICE_ID_SI_7013		0x7013
 #define PCI_DEVICE_ID_SI_7016		0x7016
+#define PCI_DEVICE_ID_SI_7018		0x7018
 
 #define PCI_VENDOR_ID_HP		0x103c
 #define PCI_DEVICE_ID_HP_VISUALIZE_EG	0x1005
@@ -713,10 +719,12 @@
 #define PCI_DEVICE_ID_HP_DIVA_EVEREST	0x1282
 #define PCI_DEVICE_ID_HP_DIVA_AUX	0x1290
 #define PCI_DEVICE_ID_HP_DIVA_RMP3	0x1301
+#define PCI_DEVICE_ID_HP_CISS		0x3210
 #define PCI_DEVICE_ID_HP_CISSA		0x3220
 #define PCI_DEVICE_ID_HP_CISSB		0x3222
-#define PCI_DEVICE_ID_HP_ZX2_IOC	0x4031
 #define PCI_DEVICE_ID_HP_CISSC		0x3230
+#define PCI_DEVICE_ID_HP_CISSD		0x3238
+#define PCI_DEVICE_ID_HP_ZX2_IOC	0x4031
 
 #define PCI_VENDOR_ID_PCTECH		0x1042
 #define PCI_DEVICE_ID_PCTECH_RZ1000	0x1000
@@ -991,6 +999,7 @@
 #define PCI_DEVICE_ID_BROOKTREE_849A	0x0351
 #define PCI_DEVICE_ID_BROOKTREE_878_1	0x036e
 #define PCI_DEVICE_ID_BROOKTREE_878	0x0878
+#define PCI_DEVICE_ID_BROOKTREE_879	0x0879
 #define PCI_DEVICE_ID_BROOKTREE_8474	0x8474
 
 #define PCI_VENDOR_ID_SIERRA		0x10a8
@@ -1109,6 +1118,9 @@
 #define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2160 0x0004
 #define PCI_DEVICE_ID_NEOMAGIC_MAGICMEDIA_256AV       0x0005
 #define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZVPLUS   0x0083
+#define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005
+#define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006
+#define PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO 0x8016
 
 #define PCI_VENDOR_ID_ASP		0x10cd
 #define PCI_DEVICE_ID_ASP_ABP940	0x1200
@@ -1155,10 +1167,13 @@
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS	0x0064
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE	0x0065
 #define PCI_DEVICE_ID_NVIDIA_NVENET_2		0x0066
+#define PCI_DEVICE_ID_NVIDIA_MCP2_MODEM		0x0069
 #define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO		0x006a
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS	0x0084
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE	0x0085
 #define PCI_DEVICE_ID_NVIDIA_NVENET_4		0x0086
+#define PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM	0x0089
+#define PCI_DEVICE_ID_NVIDIA_CK8_AUDIO		0x008a
 #define PCI_DEVICE_ID_NVIDIA_NVENET_5		0x008c
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA	0x008e
 #define PCI_DEVICE_ID_NVIDIA_ITNT2		0x00A0
@@ -1173,6 +1188,7 @@
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS	0x00d4
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE	0x00d5
 #define PCI_DEVICE_ID_NVIDIA_NVENET_3		0x00d6
+#define PCI_DEVICE_ID_NVIDIA_MCP3_MODEM		0x00d9
 #define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO		0x00da
 #define PCI_DEVICE_ID_NVIDIA_NVENET_7		0x00df
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S		0x00e1
@@ -1180,6 +1196,7 @@
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS	0x00e4
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE	0x00e5
 #define PCI_DEVICE_ID_NVIDIA_NVENET_6		0x00e6
+#define PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO		0x00ea
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2	0x00ee
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR	0x0100
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR	0x0101
@@ -1230,6 +1247,7 @@
 #define PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO		0x01b1
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS	0x01b4
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_IDE		0x01bc
+#define PCI_DEVICE_ID_NVIDIA_MCP1_MODEM		0x01c1
 #define PCI_DEVICE_ID_NVIDIA_NVENET_1		0x01c3
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2		0x01e0
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3		0x0200
@@ -1334,6 +1352,13 @@
 #define PCI_DEVICE_ID_REALTEK_8169	0x8169
 
 #define PCI_VENDOR_ID_XILINX		0x10ee
+#define PCI_DEVICE_ID_RME_DIGI96	0x3fc0
+#define PCI_DEVICE_ID_RME_DIGI96_8	0x3fc1
+#define PCI_DEVICE_ID_RME_DIGI96_8_PRO	0x3fc2
+#define PCI_DEVICE_IDRME__DIGI96_8_PAD_OR_PST 0x3fc3
+#define PCI_DEVICE_ID_XILINX_HAMMERFALL	0x3fc4
+#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5
+#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI 0x3fc6
 #define PCI_DEVICE_ID_TURBOPAM		0x4020
 
 #define PCI_VENDOR_ID_TRUEVISION	0x10fa
@@ -1809,6 +1834,14 @@
 #define PCI_DEVICE_ID_ESS_ESS1968	0x1968
 #define PCI_DEVICE_ID_ESS_AUDIOPCI	0x1969
 #define PCI_DEVICE_ID_ESS_ESS1978	0x1978
+#define PCI_DEVICE_ID_ESS_ALLEGRO_1	0x1988
+#define PCI_DEVICE_ID_ESS_ALLEGRO	0x1989
+#define PCI_DEVICE_ID_ESS_CANYON3D_2LE	0x1990
+#define PCI_DEVICE_ID_ESS_CANYON3D_2	0x1992
+#define PCI_DEVICE_ID_ESS_MAESTRO3	0x1998
+#define PCI_DEVICE_ID_ESS_MAESTRO3_1	0x1999
+#define PCI_DEVICE_ID_ESS_MAESTRO3_HW	0x199a
+#define PCI_DEVICE_ID_ESS_MAESTRO3_2	0x199b
 
 #define PCI_VENDOR_ID_SATSAGEM		0x1267
 #define PCI_DEVICE_ID_SATSAGEM_NICCY	0x1016
@@ -1968,6 +2001,9 @@
 #define PCI_DEVICE_ID_LMC_SSI		0x0005
 #define PCI_DEVICE_ID_LMC_T1		0x0006
 
+#define PCI_VENDOR_ID_MARIAN		0x1382
+#define PCI_DEVICE_ID_MARIAN_PRODIF_PLUS 0x2048
+
 #define PCI_VENDOR_ID_NETGEAR		0x1385
 #define PCI_DEVICE_ID_NETGEAR_GA620	0x620a
 #define PCI_DEVICE_ID_NETGEAR_GA622	0x622a
@@ -2056,6 +2092,10 @@
 #define PCI_VENDOR_ID_TIMEDIA		0x1409
 #define PCI_DEVICE_ID_TIMEDIA_1889	0x7168
 
+#define PCI_VENDOR_ID_ICE		0x1412
+#define PCI_DEVICE_ID_ICE_1712		0x1712
+#define PCI_DEVICE_ID_VT1724		0x1724
+
 #define PCI_VENDOR_ID_OXSEMI		0x1415
 #define PCI_DEVICE_ID_OXSEMI_12PCI840	0x8403
 #define PCI_DEVICE_ID_OXSEMI_16PCI954	0x9501
@@ -2536,6 +2576,7 @@
 #define PCI_DEVICE_ID_INTEL_82443BX_1	0x7191
 #define PCI_DEVICE_ID_INTEL_82443BX_2	0x7192
 #define PCI_DEVICE_ID_INTEL_440MX	0x7195
+#define PCI_DEVICE_ID_INTEL_440MX_6	0x7196
 #define PCI_DEVICE_ID_INTEL_82443MX_0	0x7198
 #define PCI_DEVICE_ID_INTEL_82443MX_1	0x7199
 #define PCI_DEVICE_ID_INTEL_82443MX_2	0x719a
@@ -2642,6 +2683,11 @@
 #define PCI_VENDOR_ID_TTTECH		0x0357
 #define PCI_DEVICE_ID_TTTECH_MC322	0x000A
 
+#define PCI_VENDOR_ID_XILINX_RME	0xea60
+#define PCI_DEVICE_ID_RME_DIGI32	0x9896
+#define PCI_DEVICE_ID_RME_DIGI32_PRO	0x9897
+#define PCI_DEVICE_ID_RME_DIGI32_8	0x9898
+
 #define PCI_VENDOR_ID_ARK		0xedd8
 #define PCI_DEVICE_ID_ARK_STING		0xa091
 #define PCI_DEVICE_ID_ARK_STINGARK	0xa099
diff --git a/include/linux/pktcdvd.h b/include/linux/pktcdvd.h
index 4b32bce..2c177e4 100644
--- a/include/linux/pktcdvd.h
+++ b/include/linux/pktcdvd.h
@@ -166,6 +166,9 @@
 /*
  * 32 buffers of 2048 bytes
  */
+#if (PAGE_SIZE % CD_FRAMESIZE) != 0
+#error "PAGE_SIZE must be a multiple of CD_FRAMESIZE"
+#endif
 #define PACKET_MAX_SIZE		32
 #define PAGES_PER_PACKET	(PACKET_MAX_SIZE * CD_FRAMESIZE / PAGE_SIZE)
 #define PACKET_MAX_SECTORS	(PACKET_MAX_SIZE * CD_FRAMESIZE >> 9)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 38c8654..49e617f 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -121,6 +121,17 @@
 #define set_task_state(tsk, state_value)		\
 	set_mb((tsk)->state, (state_value))
 
+/*
+ * set_current_state() includes a barrier so that the write of current->state
+ * is correctly serialised wrt the caller's subsequent test of whether to
+ * actually sleep:
+ *
+ *	set_current_state(TASK_UNINTERRUPTIBLE);
+ *	if (do_i_need_to_sleep())
+ *		schedule();
+ *
+ * If the caller does not need such serialisation then use __set_current_state()
+ */
 #define __set_current_state(state_value)			\
 	do { current->state = (state_value); } while (0)
 #define set_current_state(state_value)		\
diff --git a/include/linux/security.h b/include/linux/security.h
index 55b02e1..0e43460 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1907,6 +1907,11 @@
 extern int unregister_security	(struct security_operations *ops);
 extern int mod_reg_security	(const char *name, struct security_operations *ops);
 extern int mod_unreg_security	(const char *name, struct security_operations *ops);
+extern struct dentry *securityfs_create_file(const char *name, mode_t mode,
+					     struct dentry *parent, void *data,
+					     struct file_operations *fops);
+extern struct dentry *securityfs_create_dir(const char *name, struct dentry *parent);
+extern void securityfs_remove(struct dentry *dentry);
 
 
 #else /* CONFIG_SECURITY */
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index f623a33..89a0557 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -60,12 +60,17 @@
 	 (field) == V4L2_FIELD_SEQ_BT)
 
 enum v4l2_buf_type {
-	V4L2_BUF_TYPE_VIDEO_CAPTURE  = 1,
-	V4L2_BUF_TYPE_VIDEO_OUTPUT   = 2,
-	V4L2_BUF_TYPE_VIDEO_OVERLAY  = 3,
-	V4L2_BUF_TYPE_VBI_CAPTURE    = 4,
-	V4L2_BUF_TYPE_VBI_OUTPUT     = 5,
-	V4L2_BUF_TYPE_PRIVATE        = 0x80,
+	V4L2_BUF_TYPE_VIDEO_CAPTURE      = 1,
+	V4L2_BUF_TYPE_VIDEO_OUTPUT       = 2,
+	V4L2_BUF_TYPE_VIDEO_OVERLAY      = 3,
+	V4L2_BUF_TYPE_VBI_CAPTURE        = 4,
+	V4L2_BUF_TYPE_VBI_OUTPUT         = 5,
+#if 1
+	/* Experimental Sliced VBI */
+	V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6,
+	V4L2_BUF_TYPE_SLICED_VBI_OUTPUT  = 7,
+#endif
+	V4L2_BUF_TYPE_PRIVATE            = 0x80,
 };
 
 enum v4l2_ctrl_type {
@@ -149,20 +154,24 @@
 };
 
 /* Values for 'capabilities' field */
-#define V4L2_CAP_VIDEO_CAPTURE	0x00000001  /* Is a video capture device */
-#define V4L2_CAP_VIDEO_OUTPUT	0x00000002  /* Is a video output device */
-#define V4L2_CAP_VIDEO_OVERLAY	0x00000004  /* Can do video overlay */
-#define V4L2_CAP_VBI_CAPTURE	0x00000010  /* Is a VBI capture device */
-#define V4L2_CAP_VBI_OUTPUT	0x00000020  /* Is a VBI output device */
-#define V4L2_CAP_RDS_CAPTURE	0x00000100  /* RDS data capture */
+#define V4L2_CAP_VIDEO_CAPTURE	        0x00000001  /* Is a video capture device */
+#define V4L2_CAP_VIDEO_OUTPUT	        0x00000002  /* Is a video output device */
+#define V4L2_CAP_VIDEO_OVERLAY	        0x00000004  /* Can do video overlay */
+#define V4L2_CAP_VBI_CAPTURE	        0x00000010  /* Is a raw VBI capture device */
+#define V4L2_CAP_VBI_OUTPUT	        0x00000020  /* Is a raw VBI output device */
+#if 1
+#define V4L2_CAP_SLICED_VBI_CAPTURE	0x00000040  /* Is a sliced VBI capture device */
+#define V4L2_CAP_SLICED_VBI_OUTPUT	0x00000080  /* Is a sliced VBI output device */
+#endif
+#define V4L2_CAP_RDS_CAPTURE	        0x00000100  /* RDS data capture */
 
-#define V4L2_CAP_TUNER		0x00010000  /* has a tuner */
-#define V4L2_CAP_AUDIO		0x00020000  /* has audio support */
-#define V4L2_CAP_RADIO		0x00040000  /* is a radio device */
+#define V4L2_CAP_TUNER		        0x00010000  /* has a tuner */
+#define V4L2_CAP_AUDIO		        0x00020000  /* has audio support */
+#define V4L2_CAP_RADIO		        0x00040000  /* is a radio device */
 
-#define V4L2_CAP_READWRITE      0x01000000  /* read/write systemcalls */
-#define V4L2_CAP_ASYNCIO        0x02000000  /* async I/O */
-#define V4L2_CAP_STREAMING      0x04000000  /* streaming I/O ioctls */
+#define V4L2_CAP_READWRITE              0x01000000  /* read/write systemcalls */
+#define V4L2_CAP_ASYNCIO                0x02000000  /* async I/O */
+#define V4L2_CAP_STREAMING              0x04000000  /* streaming I/O ioctls */
 
 /*
  *	V I D E O   I M A G E   F O R M A T
@@ -809,6 +818,8 @@
  *	Data services API by Michael Schimek
  */
 
+/* Raw VBI */
+
 struct v4l2_vbi_format
 {
 	__u32	sampling_rate;		/* in 1 Hz */
@@ -825,6 +836,54 @@
 #define V4L2_VBI_UNSYNC		(1<< 0)
 #define V4L2_VBI_INTERLACED	(1<< 1)
 
+#if 1
+/* Sliced VBI
+ *
+ *    This implements is a proposal V4L2 API to allow SLICED VBI
+ * required for some hardware encoders. It should change without
+ * notice in the definitive implementation.
+ */
+
+struct v4l2_sliced_vbi_format
+{
+        __u16   service_set;
+        /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
+           service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
+                                 (equals frame lines 313-336 for 625 line video
+                                  standards, 263-286 for 525 line standards) */
+        __u16   service_lines[2][24];
+        __u32   io_size;
+        __u32   reserved[2];            /* must be zero */
+};
+
+#define V4L2_SLICED_TELETEXT_B          (0x0001)
+#define V4L2_SLICED_VPS                 (0x0400)
+#define V4L2_SLICED_CAPTION_525         (0x1000)
+#define V4L2_SLICED_WSS_625             (0x4000)
+
+#define V4L2_SLICED_VBI_525             (V4L2_SLICED_CAPTION_525)
+#define V4L2_SLICED_VBI_625             (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625)
+
+struct v4l2_sliced_vbi_cap
+{
+        __u16   service_set;
+        /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
+           service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
+                                 (equals frame lines 313-336 for 625 line video
+                                  standards, 263-286 for 525 line standards) */
+        __u16   service_lines[2][24];
+        __u32   reserved[4];    /* must be 0 */
+};
+
+struct v4l2_sliced_vbi_data
+{
+        __u32   id;
+        __u32   field;          /* 0: first field, 1: second field */
+        __u32   line;           /* 1-23 */
+        __u32   reserved;       /* must be 0 */
+        __u8    data[48];
+};
+#endif
 
 /*
  *	A G G R E G A T E   S T R U C T U R E S
@@ -837,10 +896,13 @@
 	enum v4l2_buf_type type;
 	union
 	{
-		struct v4l2_pix_format	pix;  // V4L2_BUF_TYPE_VIDEO_CAPTURE
-		struct v4l2_window	win;  // V4L2_BUF_TYPE_VIDEO_OVERLAY
-		struct v4l2_vbi_format	vbi;  // V4L2_BUF_TYPE_VBI_CAPTURE
-		__u8	raw_data[200];        // user-defined
+		struct v4l2_pix_format	        pix;     // V4L2_BUF_TYPE_VIDEO_CAPTURE
+		struct v4l2_window	        win;     // V4L2_BUF_TYPE_VIDEO_OVERLAY
+		struct v4l2_vbi_format	        vbi;     // V4L2_BUF_TYPE_VBI_CAPTURE
+#if 1
+		struct v4l2_sliced_vbi_format	sliced;  // V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
+#endif
+		__u8	raw_data[200];                   // user-defined
 	} fmt;
 };
 
@@ -916,6 +978,9 @@
 #define VIDIOC_ENUMAUDOUT	_IOWR ('V', 66, struct v4l2_audioout)
 #define VIDIOC_G_PRIORITY       _IOR  ('V', 67, enum v4l2_priority)
 #define VIDIOC_S_PRIORITY       _IOW  ('V', 68, enum v4l2_priority)
+#if 1
+#define VIDIOC_G_SLICED_VBI_CAP _IOR  ('V', 69, struct v4l2_sliced_vbi_cap)
+#endif
 
 /* for compatibility, will go away some day */
 #define VIDIOC_OVERLAY_OLD     	_IOWR ('V', 14, int)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 371e7d3..fa2d12b 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -463,6 +463,17 @@
 	__s8     rssi;
 } __attribute__ ((packed));
 
+#define HCI_EV_EXTENDED_INQUIRY_RESULT	0x2F
+struct extended_inquiry_info {
+	bdaddr_t bdaddr;
+	__u8     pscan_rep_mode;
+	__u8     pscan_period_mode;
+	__u8     dev_class[3];
+	__u16    clock_offset;
+	__s8     rssi;
+	__u8     data[240];
+} __attribute__ ((packed));
+
 #define HCI_EV_CONN_COMPLETE 	0x03
 struct hci_ev_conn_complete {
 	__u8     status;
diff --git a/include/sound/core.h b/include/sound/core.h
index 3dc41fd..26160ad 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -168,6 +168,9 @@
 	wait_queue_head_t shutdown_sleep;
 	struct work_struct free_workq;	/* for free in workqueue */
 	struct device *dev;
+#ifdef CONFIG_SND_GENERIC_DRIVER
+	struct snd_generic_device *generic_dev;
+#endif
 
 #ifdef CONFIG_PM
 	int (*pm_suspend)(snd_card_t *card, pm_message_t state);
@@ -176,9 +179,6 @@
 	unsigned int power_state;	/* power state */
 	struct semaphore power_lock;	/* power lock */
 	wait_queue_head_t power_sleep;
-#ifdef CONFIG_SND_GENERIC_PM
-	struct snd_generic_device *pm_dev;	/* for ISA */
-#endif
 #endif
 
 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
@@ -348,6 +348,8 @@
 #ifndef snd_card_set_dev
 #define snd_card_set_dev(card,devptr) ((card)->dev = (devptr))
 #endif
+/* register a generic device (for ISA, etc) */
+int snd_card_set_generic_dev(snd_card_t *card);
 
 /* device.c */
 
diff --git a/include/sound/cs46xx.h b/include/sound/cs46xx.h
index 9b94510..b0c0e19 100644
--- a/include/sound/cs46xx.h
+++ b/include/sound/cs46xx.h
@@ -29,19 +29,6 @@
 #include "ac97_codec.h"
 #include "cs46xx_dsp_spos.h"
 
-#ifndef PCI_VENDOR_ID_CIRRUS
-#define PCI_VENDOR_ID_CIRRUS            0x1013
-#endif
-#ifndef PCI_DEVICE_ID_CIRRUS_4610
-#define PCI_DEVICE_ID_CIRRUS_4610       0x6001
-#endif
-#ifndef PCI_DEVICE_ID_CIRRUS_4612
-#define PCI_DEVICE_ID_CIRRUS_4612       0x6003
-#endif
-#ifndef PCI_DEVICE_ID_CIRRUS_4615
-#define PCI_DEVICE_ID_CIRRUS_4615       0x6004
-#endif
-
 /*
  *  Direct registers
  */
@@ -1715,7 +1702,6 @@
 	void (*active_ctrl)(cs46xx_t *, int);
   	void (*mixer_init)(cs46xx_t *);
 
-	struct pci_dev *acpi_dev;
 	int acpi_port;
 	snd_kcontrol_t *eapd_switch; /* for amplifier hack */
 	int accept_valid;	/* accept mmap valid (for OSS) */
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 4e3993d..67bf3f1 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -35,13 +35,6 @@
 #include <linux/interrupt.h>
 #include <asm/io.h>
 
-#ifndef PCI_VENDOR_ID_CREATIVE
-#define PCI_VENDOR_ID_CREATIVE		0x1102
-#endif
-#ifndef PCI_DEVICE_ID_CREATIVE_EMU10K1
-#define PCI_DEVICE_ID_CREATIVE_EMU10K1	0x0002
-#endif
-
 /* ------------------- DEFINES -------------------- */
 
 #define EMUPAGESIZE     4096
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index d6361dab..2b23a59 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -903,13 +903,16 @@
 int snd_pcm_format_linear(snd_pcm_format_t format);
 int snd_pcm_format_little_endian(snd_pcm_format_t format);
 int snd_pcm_format_big_endian(snd_pcm_format_t format);
-/*
+#if 0 /* just for DocBook */
+/**
  * snd_pcm_format_cpu_endian - Check the PCM format is CPU-endian
  * @format: the format to check
  *
  * Returns 1 if the given PCM format is CPU-endian, 0 if
  * opposite, or a negative error code if endian not specified.
  */
+int snd_pcm_format_cpu_endian(snd_pcm_format_t format);
+#endif /* DocBook */
 #ifdef SNDRV_LITTLE_ENDIAN
 #define snd_pcm_format_cpu_endian(format) snd_pcm_format_little_endian(format)
 #else
diff --git a/include/sound/pcm_oss.h b/include/sound/pcm_oss.h
index 5187285..0b67c9d 100644
--- a/include/sound/pcm_oss.h
+++ b/include/sound/pcm_oss.h
@@ -32,7 +32,8 @@
 		     block:1,
 		     nonblock:1,
 		     partialfrag:1,
-		     nosilence:1;
+		     nosilence:1,
+		     buggyptr:1;
 	unsigned int periods;
 	unsigned int period_size;
 	snd_pcm_oss_setup_t *next;
diff --git a/include/sound/trident.h b/include/sound/trident.h
index f5254ec..a408d39 100644
--- a/include/sound/trident.h
+++ b/include/sound/trident.h
@@ -33,23 +33,6 @@
 //#include "ainstr_gf1.h"
 #include "ainstr_simple.h"
 
-#ifndef PCI_VENDOR_ID_TRIDENT
-#define PCI_VENDOR_ID_TRIDENT		0x1023
-#endif
-#ifndef PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 
-#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX	0x2000
-#endif
-#ifndef PCI_DEVICE_ID_TRIDENT_4DWAVE_NX 
-#define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX	0x2001
-#endif
-
-#ifndef PCI_VENDOR_ID_SI
-#define PCI_VENDOR_ID_SI		0x1039
-#endif
-#ifndef PCI_DEVICE_ID_SI_7018
-#define PCI_DEVICE_ID_SI_7018		0x7018
-#endif
-
 #define TRIDENT_DEVICE_ID_DX		((PCI_VENDOR_ID_TRIDENT<<16)|PCI_DEVICE_ID_TRIDENT_4DWAVE_DX)
 #define TRIDENT_DEVICE_ID_NX		((PCI_VENDOR_ID_TRIDENT<<16)|PCI_DEVICE_ID_TRIDENT_4DWAVE_NX)
 #define TRIDENT_DEVICE_ID_SI7018	((PCI_VENDOR_ID_SI<<16)|PCI_DEVICE_ID_SI_7018)
diff --git a/include/sound/version.h b/include/sound/version.h
index 8d19bfa..ee32af2 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by configure.  */
 #define CONFIG_SND_VERSION "1.0.10rc1"
-#define CONFIG_SND_DATE " (Tue Aug 30 05:31:08 2005 UTC)"
+#define CONFIG_SND_DATE " (Mon Sep 12 08:13:09 2005 UTC)"
diff --git a/include/sound/ymfpci.h b/include/sound/ymfpci.h
index 9a3c1e6..c3bccbfd 100644
--- a/include/sound/ymfpci.h
+++ b/include/sound/ymfpci.h
@@ -28,28 +28,6 @@
 #include "timer.h"
 #include <linux/gameport.h>
 
-#ifndef PCI_VENDOR_ID_YAMAHA
-#define PCI_VENDOR_ID_YAMAHA            0x1073
-#endif
-#ifndef PCI_DEVICE_ID_YAMAHA_724
-#define PCI_DEVICE_ID_YAMAHA_724	0x0004
-#endif
-#ifndef PCI_DEVICE_ID_YAMAHA_724F
-#define PCI_DEVICE_ID_YAMAHA_724F	0x000d
-#endif
-#ifndef PCI_DEVICE_ID_YAMAHA_740
-#define PCI_DEVICE_ID_YAMAHA_740	0x000a
-#endif
-#ifndef PCI_DEVICE_ID_YAMAHA_740C
-#define PCI_DEVICE_ID_YAMAHA_740C	0x000c
-#endif
-#ifndef PCI_DEVICE_ID_YAMAHA_744
-#define PCI_DEVICE_ID_YAMAHA_744	0x0010
-#endif
-#ifndef PCI_DEVICE_ID_YAMAHA_754
-#define PCI_DEVICE_ID_YAMAHA_754	0x0012
-#endif
-
 /*
  *  Direct registers
  */
diff --git a/include/video/pm3fb.h b/include/video/pm3fb.h
index 8d3cef5..6f4ea80 100644
--- a/include/video/pm3fb.h
+++ b/include/video/pm3fb.h
@@ -1142,9 +1142,6 @@
 /* do we want accelerated console  */
 #define PM3FB_USE_ACCEL 1
 
-/* useful ? */
-#define CHAR_IS_NUM(a)  ((((a) >= '0') && ((a) <= '9')) ? 1 : 0)
-
 /* for driver debugging ONLY */
 /* 0 = assert only, 1 = error, 2 = info, 3+ = verbose */
 /* define PM3FB_MASTER_DEBUG 1 */
diff --git a/include/video/w100fb.h b/include/video/w100fb.h
index e6da2d7..677d403 100644
--- a/include/video/w100fb.h
+++ b/include/video/w100fb.h
@@ -19,6 +19,7 @@
 
 unsigned long w100fb_gpio_read(int port);
 void w100fb_gpio_write(int port, unsigned long value);
+unsigned long w100fb_get_hsynclen(struct device *dev);
 
 /* LCD Specific Routines and Config */
 struct w100_tg_info {
diff --git a/init/initramfs.c b/init/initramfs.c
index 02c5ce6..0c5d9a3 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -466,6 +466,14 @@
 extern char __initramfs_start[], __initramfs_end[];
 #ifdef CONFIG_BLK_DEV_INITRD
 #include <linux/initrd.h>
+
+static void __init free_initrd(void)
+{
+	free_initrd_mem(initrd_start, initrd_end);
+	initrd_start = 0;
+	initrd_end = 0;
+}
+
 #endif
 
 void __init populate_rootfs(void)
@@ -484,7 +492,7 @@
 			printk(" it is\n");
 			unpack_to_rootfs((char *)initrd_start,
 				initrd_end - initrd_start, 0);
-			free_initrd_mem(initrd_start, initrd_end);
+			free_initrd();
 			return;
 		}
 		printk("it isn't (%s); looks like an initrd\n", err);
@@ -493,7 +501,7 @@
 			sys_write(fd, (char *)initrd_start,
 					initrd_end - initrd_start);
 			sys_close(fd);
-			free_initrd_mem(initrd_start, initrd_end);
+			free_initrd();
 		}
 	}
 #endif
diff --git a/kernel/audit.c b/kernel/audit.c
index 7f06997..83096b6 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -79,6 +79,8 @@
 
 /* Number of outstanding audit_buffers allowed. */
 static int	audit_backlog_limit = 64;
+static int	audit_backlog_wait_time = 60 * HZ;
+static int	audit_backlog_wait_overflow = 0;
 
 /* The identity of the user shutting down the audit system. */
 uid_t		audit_sig_uid = -1;
@@ -106,18 +108,12 @@
 static struct sk_buff_head audit_skb_queue;
 static struct task_struct *kauditd_task;
 static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
-
-/* There are three lists of rules -- one to search at task creation
- * time, one to search at syscall entry time, and another to search at
- * syscall exit time. */
-static LIST_HEAD(audit_tsklist);
-static LIST_HEAD(audit_entlist);
-static LIST_HEAD(audit_extlist);
+static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait);
 
 /* The netlink socket is only to be read by 1 CPU, which lets us assume
  * that list additions and deletions never happen simultaneously in
  * auditsc.c */
-static DECLARE_MUTEX(audit_netlink_sem);
+DECLARE_MUTEX(audit_netlink_sem);
 
 /* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting
  * audit records.  Since printk uses a 1024 byte buffer, this buffer
@@ -137,6 +133,7 @@
 	struct list_head     list;
 	struct sk_buff       *skb;	/* formatted skb ready to send */
 	struct audit_context *ctx;	/* NULL or associated context */
+	int		     gfp_mask;
 };
 
 static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
@@ -145,11 +142,6 @@
 	nlh->nlmsg_pid = pid;
 }
 
-struct audit_entry {
-	struct list_head  list;
-	struct audit_rule rule;
-};
-
 static void audit_panic(const char *message)
 {
 	switch (audit_failure)
@@ -233,7 +225,7 @@
 {
 	int old		 = audit_rate_limit;
 	audit_rate_limit = limit;
-	audit_log(NULL, AUDIT_CONFIG_CHANGE, 
+	audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, 
 			"audit_rate_limit=%d old=%d by auid=%u",
 			audit_rate_limit, old, loginuid);
 	return old;
@@ -243,7 +235,7 @@
 {
 	int old		 = audit_backlog_limit;
 	audit_backlog_limit = limit;
-	audit_log(NULL, AUDIT_CONFIG_CHANGE,
+	audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
 			"audit_backlog_limit=%d old=%d by auid=%u",
 			audit_backlog_limit, old, loginuid);
 	return old;
@@ -255,7 +247,7 @@
 	if (state != 0 && state != 1)
 		return -EINVAL;
 	audit_enabled = state;
-	audit_log(NULL, AUDIT_CONFIG_CHANGE,
+	audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
 			"audit_enabled=%d old=%d by auid=%u",
 			audit_enabled, old, loginuid);
 	return old;
@@ -269,7 +261,7 @@
 	    && state != AUDIT_FAIL_PANIC)
 		return -EINVAL;
 	audit_failure = state;
-	audit_log(NULL, AUDIT_CONFIG_CHANGE,
+	audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
 			"audit_failure=%d old=%d by auid=%u",
 			audit_failure, old, loginuid);
 	return old;
@@ -281,6 +273,7 @@
 
 	while (1) {
 		skb = skb_dequeue(&audit_skb_queue);
+		wake_up(&audit_backlog_wait);
 		if (skb) {
 			if (audit_pid) {
 				int err = netlink_unicast(audit_sock, skb, audit_pid, 0);
@@ -290,7 +283,7 @@
 					audit_pid = 0;
 				}
 			} else {
-				printk(KERN_ERR "%s\n", skb->data + NLMSG_SPACE(0));
+				printk(KERN_NOTICE "%s\n", skb->data + NLMSG_SPACE(0));
 				kfree_skb(skb);
 			}
 		} else {
@@ -423,7 +416,7 @@
 		if (status_get->mask & AUDIT_STATUS_PID) {
 			int old   = audit_pid;
 			audit_pid = status_get->pid;
-			audit_log(NULL, AUDIT_CONFIG_CHANGE,
+			audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
 				"audit_pid=%d old=%d by auid=%u",
 				  audit_pid, old, loginuid);
 		}
@@ -435,15 +428,21 @@
 		break;
 	case AUDIT_USER:
 	case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
-		ab = audit_log_start(NULL, msg_type);
-		if (!ab)
-			break;	/* audit_panic has been called */
-		audit_log_format(ab,
-				 "user pid=%d uid=%u auid=%u"
-				 " msg='%.1024s'",
-				 pid, uid, loginuid, (char *)data);
-		audit_set_pid(ab, pid);
-		audit_log_end(ab);
+		if (!audit_enabled && msg_type != AUDIT_USER_AVC)
+			return 0;
+
+		err = audit_filter_user(&NETLINK_CB(skb), msg_type);
+		if (err == 1) {
+			err = 0;
+			ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
+			if (ab) {
+				audit_log_format(ab,
+						 "user pid=%d uid=%u auid=%u msg='%.1024s'",
+						 pid, uid, loginuid, (char *)data);
+				audit_set_pid(ab, pid);
+				audit_log_end(ab);
+			}
+		}
 		break;
 	case AUDIT_ADD:
 	case AUDIT_DEL:
@@ -523,7 +522,7 @@
 	skb_queue_head_init(&audit_skb_queue);
 	audit_initialized = 1;
 	audit_enabled = audit_default;
-	audit_log(NULL, AUDIT_KERNEL, "initialized");
+	audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized");
 	return 0;
 }
 __initcall(audit_init);
@@ -561,7 +560,7 @@
 }
 
 static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx,
-						int gfp_mask, int type)
+						unsigned int __nocast gfp_mask, int type)
 {
 	unsigned long flags;
 	struct audit_buffer *ab = NULL;
@@ -587,6 +586,7 @@
 		goto err;
 
 	ab->ctx = ctx;
+	ab->gfp_mask = gfp_mask;
 	nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0));
 	nlh->nlmsg_type = type;
 	nlh->nlmsg_flags = 0;
@@ -606,26 +606,27 @@
  * (timestamp,serial) tuple is unique for each syscall and is live from
  * syscall entry to syscall exit.
  *
- * Atomic values are only guaranteed to be 24-bit, so we count down.
- *
  * NOTE: Another possibility is to store the formatted records off the
  * audit context (for those records that have a context), and emit them
  * all at syscall exit.  However, this could delay the reporting of
  * significant errors until syscall exit (or never, if the system
  * halts). */
+
 unsigned int audit_serial(void)
 {
-	static atomic_t serial = ATOMIC_INIT(0xffffff);
-	unsigned int a, b;
+	static spinlock_t serial_lock = SPIN_LOCK_UNLOCKED;
+	static unsigned int serial = 0;
 
+	unsigned long flags;
+	unsigned int ret;
+
+	spin_lock_irqsave(&serial_lock, flags);
 	do {
-		a = atomic_read(&serial);
-		if (atomic_dec_and_test(&serial))
-			atomic_set(&serial, 0xffffff);
-		b = atomic_read(&serial);
-	} while (b != a - 1);
+		ret = ++serial;
+	} while (unlikely(!ret));
+	spin_unlock_irqrestore(&serial_lock, flags);
 
-	return 0xffffff - b;
+	return ret;
 }
 
 static inline void audit_get_stamp(struct audit_context *ctx, 
@@ -645,17 +646,43 @@
  * syscall, then the syscall is marked as auditable and an audit record
  * will be written at syscall exit.  If there is no associated task, tsk
  * should be NULL. */
-struct audit_buffer *audit_log_start(struct audit_context *ctx, int type)
+
+struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask,
+				     int type)
 {
 	struct audit_buffer	*ab	= NULL;
 	struct timespec		t;
 	unsigned int		serial;
+	int reserve;
+	unsigned long timeout_start = jiffies;
 
 	if (!audit_initialized)
 		return NULL;
 
-	if (audit_backlog_limit
-	    && skb_queue_len(&audit_skb_queue) > audit_backlog_limit) {
+	if (gfp_mask & __GFP_WAIT)
+		reserve = 0;
+	else
+		reserve = 5; /* Allow atomic callers to go up to five 
+				entries over the normal backlog limit */
+
+	while (audit_backlog_limit
+	       && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) {
+		if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time
+		    && time_before(jiffies, timeout_start + audit_backlog_wait_time)) {
+
+			/* Wait for auditd to drain the queue a little */
+			DECLARE_WAITQUEUE(wait, current);
+			set_current_state(TASK_INTERRUPTIBLE);
+			add_wait_queue(&audit_backlog_wait, &wait);
+
+			if (audit_backlog_limit &&
+			    skb_queue_len(&audit_skb_queue) > audit_backlog_limit)
+				schedule_timeout(timeout_start + audit_backlog_wait_time - jiffies);
+
+			__set_current_state(TASK_RUNNING);
+			remove_wait_queue(&audit_backlog_wait, &wait);
+			continue;
+		}
 		if (audit_rate_check())
 			printk(KERN_WARNING
 			       "audit: audit_backlog=%d > "
@@ -663,10 +690,12 @@
 			       skb_queue_len(&audit_skb_queue),
 			       audit_backlog_limit);
 		audit_log_lost("backlog limit exceeded");
+		audit_backlog_wait_time = audit_backlog_wait_overflow;
+		wake_up(&audit_backlog_wait);
 		return NULL;
 	}
 
-	ab = audit_buffer_alloc(ctx, GFP_ATOMIC, type);
+	ab = audit_buffer_alloc(ctx, gfp_mask, type);
 	if (!ab) {
 		audit_log_lost("out of memory in audit_log_start");
 		return NULL;
@@ -690,7 +719,7 @@
 {
 	struct sk_buff *skb = ab->skb;
 	int ret = pskb_expand_head(skb, skb_headroom(skb), extra,
-				   GFP_ATOMIC);
+				   ab->gfp_mask);
 	if (ret < 0) {
 		audit_log_lost("out of memory in audit_expand");
 		return 0;
@@ -809,7 +838,7 @@
 		audit_log_format(ab, " %s", prefix);
 
 	/* We will allow 11 spaces for ' (deleted)' to be appended */
-	path = kmalloc(PATH_MAX+11, GFP_KERNEL);
+	path = kmalloc(PATH_MAX+11, ab->gfp_mask);
 	if (!path) {
 		audit_log_format(ab, "<no memory>");
 		return;
@@ -841,7 +870,7 @@
 			ab->skb = NULL;
 			wake_up_interruptible(&kauditd_wait);
 		} else {
-			printk("%s\n", ab->skb->data + NLMSG_SPACE(0));
+			printk(KERN_NOTICE "%s\n", ab->skb->data + NLMSG_SPACE(0));
 		}
 	}
 	audit_buffer_free(ab);
@@ -850,12 +879,13 @@
 /* Log an audit record.  This is a convenience function that calls
  * audit_log_start, audit_log_vformat, and audit_log_end.  It may be
  * called in any context. */
-void audit_log(struct audit_context *ctx, int type, const char *fmt, ...)
+void audit_log(struct audit_context *ctx, int gfp_mask, int type, 
+	       const char *fmt, ...)
 {
 	struct audit_buffer *ab;
 	va_list args;
 
-	ab = audit_log_start(ctx, type);
+	ab = audit_log_start(ctx, gfp_mask, type);
 	if (ab) {
 		va_start(args, fmt);
 		audit_log_vformat(ab, fmt, args);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index e75f84e..88696f6 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -39,6 +39,9 @@
 #include <linux/audit.h>
 #include <linux/personality.h>
 #include <linux/time.h>
+#include <linux/kthread.h>
+#include <linux/netlink.h>
+#include <linux/compiler.h>
 #include <asm/unistd.h>
 
 /* 0 = no checking
@@ -95,6 +98,7 @@
 	uid_t		uid;
 	gid_t		gid;
 	dev_t		rdev;
+	unsigned	flags;
 };
 
 struct audit_aux_data {
@@ -167,9 +171,16 @@
 /* There are three lists of rules -- one to search at task creation
  * time, one to search at syscall entry time, and another to search at
  * syscall exit time. */
-static LIST_HEAD(audit_tsklist);
-static LIST_HEAD(audit_entlist);
-static LIST_HEAD(audit_extlist);
+static struct list_head audit_filter_list[AUDIT_NR_FILTERS] = {
+	LIST_HEAD_INIT(audit_filter_list[0]),
+	LIST_HEAD_INIT(audit_filter_list[1]),
+	LIST_HEAD_INIT(audit_filter_list[2]),
+	LIST_HEAD_INIT(audit_filter_list[3]),
+	LIST_HEAD_INIT(audit_filter_list[4]),
+#if AUDIT_NR_FILTERS != 5
+#error Fix audit_filter_list initialiser
+#endif
+};
 
 struct audit_entry {
 	struct list_head  list;
@@ -179,9 +190,36 @@
 
 extern int audit_pid;
 
+/* Copy rule from user-space to kernel-space.  Called from 
+ * audit_add_rule during AUDIT_ADD. */
+static inline int audit_copy_rule(struct audit_rule *d, struct audit_rule *s)
+{
+	int i;
+
+	if (s->action != AUDIT_NEVER
+	    && s->action != AUDIT_POSSIBLE
+	    && s->action != AUDIT_ALWAYS)
+		return -1;
+	if (s->field_count < 0 || s->field_count > AUDIT_MAX_FIELDS)
+		return -1;
+	if ((s->flags & ~AUDIT_FILTER_PREPEND) >= AUDIT_NR_FILTERS)
+		return -1;
+
+	d->flags	= s->flags;
+	d->action	= s->action;
+	d->field_count	= s->field_count;
+	for (i = 0; i < d->field_count; i++) {
+		d->fields[i] = s->fields[i];
+		d->values[i] = s->values[i];
+	}
+	for (i = 0; i < AUDIT_BITMASK_SIZE; i++) d->mask[i] = s->mask[i];
+	return 0;
+}
+
 /* Check to see if two rules are identical.  It is called from
+ * audit_add_rule during AUDIT_ADD and 
  * audit_del_rule during AUDIT_DEL. */
-static int audit_compare_rule(struct audit_rule *a, struct audit_rule *b)
+static inline int audit_compare_rule(struct audit_rule *a, struct audit_rule *b)
 {
 	int i;
 
@@ -210,19 +248,37 @@
 /* Note that audit_add_rule and audit_del_rule are called via
  * audit_receive() in audit.c, and are protected by
  * audit_netlink_sem. */
-static inline int audit_add_rule(struct audit_entry *entry,
-				 struct list_head *list)
+static inline int audit_add_rule(struct audit_rule *rule,
+				  struct list_head *list)
 {
-	if (entry->rule.flags & AUDIT_PREPEND) {
-		entry->rule.flags &= ~AUDIT_PREPEND;
+	struct audit_entry  *entry;
+
+	/* Do not use the _rcu iterator here, since this is the only
+	 * addition routine. */
+	list_for_each_entry(entry, list, list) {
+		if (!audit_compare_rule(rule, &entry->rule)) {
+			return -EEXIST;
+		}
+	}
+
+	if (!(entry = kmalloc(sizeof(*entry), GFP_KERNEL)))
+		return -ENOMEM;
+	if (audit_copy_rule(&entry->rule, rule)) {
+		kfree(entry);
+		return -EINVAL;
+	}
+
+	if (entry->rule.flags & AUDIT_FILTER_PREPEND) {
+		entry->rule.flags &= ~AUDIT_FILTER_PREPEND;
 		list_add_rcu(&entry->list, list);
 	} else {
 		list_add_tail_rcu(&entry->list, list);
 	}
+
 	return 0;
 }
 
-static void audit_free_rule(struct rcu_head *head)
+static inline void audit_free_rule(struct rcu_head *head)
 {
 	struct audit_entry *e = container_of(head, struct audit_entry, rcu);
 	kfree(e);
@@ -245,82 +301,82 @@
 			return 0;
 		}
 	}
-	return -EFAULT;		/* No matching rule */
+	return -ENOENT;		/* No matching rule */
 }
 
-/* Copy rule from user-space to kernel-space.  Called during
- * AUDIT_ADD. */
-static int audit_copy_rule(struct audit_rule *d, struct audit_rule *s)
+static int audit_list_rules(void *_dest)
 {
+	int pid, seq;
+	int *dest = _dest;
+	struct audit_entry *entry;
 	int i;
 
-	if (s->action != AUDIT_NEVER
-	    && s->action != AUDIT_POSSIBLE
-	    && s->action != AUDIT_ALWAYS)
-		return -1;
-	if (s->field_count < 0 || s->field_count > AUDIT_MAX_FIELDS)
-		return -1;
+	pid = dest[0];
+	seq = dest[1];
+	kfree(dest);
 
-	d->flags	= s->flags;
-	d->action	= s->action;
-	d->field_count	= s->field_count;
-	for (i = 0; i < d->field_count; i++) {
-		d->fields[i] = s->fields[i];
-		d->values[i] = s->values[i];
+	down(&audit_netlink_sem);
+
+	/* The *_rcu iterators not needed here because we are
+	   always called with audit_netlink_sem held. */
+	for (i=0; i<AUDIT_NR_FILTERS; i++) {
+		list_for_each_entry(entry, &audit_filter_list[i], list)
+			audit_send_reply(pid, seq, AUDIT_LIST, 0, 1,
+					 &entry->rule, sizeof(entry->rule));
 	}
-	for (i = 0; i < AUDIT_BITMASK_SIZE; i++) d->mask[i] = s->mask[i];
+	audit_send_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0);
+	
+	up(&audit_netlink_sem);
 	return 0;
 }
 
 int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
 							uid_t loginuid)
 {
-	u32		   flags;
-	struct audit_entry *entry;
+	struct task_struct *tsk;
+	int *dest;
 	int		   err = 0;
+	unsigned listnr;
 
 	switch (type) {
 	case AUDIT_LIST:
-		/* The *_rcu iterators not needed here because we are
-		   always called with audit_netlink_sem held. */
-		list_for_each_entry(entry, &audit_tsklist, list)
-			audit_send_reply(pid, seq, AUDIT_LIST, 0, 1,
-					 &entry->rule, sizeof(entry->rule));
-		list_for_each_entry(entry, &audit_entlist, list)
-			audit_send_reply(pid, seq, AUDIT_LIST, 0, 1,
-					 &entry->rule, sizeof(entry->rule));
-		list_for_each_entry(entry, &audit_extlist, list)
-			audit_send_reply(pid, seq, AUDIT_LIST, 0, 1,
-					 &entry->rule, sizeof(entry->rule));
-		audit_send_reply(pid, seq, AUDIT_LIST, 1, 1, NULL, 0);
+		/* We can't just spew out the rules here because we might fill
+		 * the available socket buffer space and deadlock waiting for
+		 * auditctl to read from it... which isn't ever going to
+		 * happen if we're actually running in the context of auditctl
+		 * trying to _send_ the stuff */
+		 
+		dest = kmalloc(2 * sizeof(int), GFP_KERNEL);
+		if (!dest)
+			return -ENOMEM;
+		dest[0] = pid;
+		dest[1] = seq;
+
+		tsk = kthread_run(audit_list_rules, dest, "audit_list_rules");
+		if (IS_ERR(tsk)) {
+			kfree(dest);
+			err = PTR_ERR(tsk);
+		}
 		break;
 	case AUDIT_ADD:
-		if (!(entry = kmalloc(sizeof(*entry), GFP_KERNEL)))
-			return -ENOMEM;
-		if (audit_copy_rule(&entry->rule, data)) {
-			kfree(entry);
+		listnr =((struct audit_rule *)data)->flags & ~AUDIT_FILTER_PREPEND;
+		if (listnr >= AUDIT_NR_FILTERS)
 			return -EINVAL;
-		}
-		flags = entry->rule.flags;
-		if (!err && (flags & AUDIT_PER_TASK))
-			err = audit_add_rule(entry, &audit_tsklist);
-		if (!err && (flags & AUDIT_AT_ENTRY))
-			err = audit_add_rule(entry, &audit_entlist);
-		if (!err && (flags & AUDIT_AT_EXIT))
-			err = audit_add_rule(entry, &audit_extlist);
-		audit_log(NULL, AUDIT_CONFIG_CHANGE, 
-				"auid=%u added an audit rule\n", loginuid);
+
+		err = audit_add_rule(data, &audit_filter_list[listnr]);
+		if (!err)
+			audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
+				  "auid=%u added an audit rule\n", loginuid);
 		break;
 	case AUDIT_DEL:
-		flags =((struct audit_rule *)data)->flags;
-		if (!err && (flags & AUDIT_PER_TASK))
-			err = audit_del_rule(data, &audit_tsklist);
-		if (!err && (flags & AUDIT_AT_ENTRY))
-			err = audit_del_rule(data, &audit_entlist);
-		if (!err && (flags & AUDIT_AT_EXIT))
-			err = audit_del_rule(data, &audit_extlist);
-		audit_log(NULL, AUDIT_CONFIG_CHANGE,
-				"auid=%u removed an audit rule\n", loginuid);
+		listnr =((struct audit_rule *)data)->flags & ~AUDIT_FILTER_PREPEND;
+		if (listnr >= AUDIT_NR_FILTERS)
+			return -EINVAL;
+
+		err = audit_del_rule(data, &audit_filter_list[listnr]);
+		if (!err)
+			audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
+				  "auid=%u removed an audit rule\n", loginuid);
 		break;
 	default:
 		return -EINVAL;
@@ -384,8 +440,12 @@
 				result = (ctx->return_code == value);
 			break;
 		case AUDIT_SUCCESS:
-			if (ctx && ctx->return_valid)
-				result = (ctx->return_valid == AUDITSC_SUCCESS);
+			if (ctx && ctx->return_valid) {
+				if (value)
+					result = (ctx->return_valid == AUDITSC_SUCCESS);
+				else
+					result = (ctx->return_valid == AUDITSC_FAILURE);
+			}
 			break;
 		case AUDIT_DEVMAJOR:
 			if (ctx) {
@@ -454,7 +514,7 @@
 	enum audit_state   state;
 
 	rcu_read_lock();
-	list_for_each_entry_rcu(e, &audit_tsklist, list) {
+	list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) {
 		if (audit_filter_rules(tsk, &e->rule, NULL, &state)) {
 			rcu_read_unlock();
 			return state;
@@ -474,22 +534,86 @@
 					     struct list_head *list)
 {
 	struct audit_entry *e;
-	enum audit_state   state;
-	int		   word = AUDIT_WORD(ctx->major);
-	int		   bit  = AUDIT_BIT(ctx->major);
+	enum audit_state state;
+
+	if (audit_pid && tsk->tgid == audit_pid)
+		return AUDIT_DISABLED;
 
 	rcu_read_lock();
-	list_for_each_entry_rcu(e, list, list) {
-		if ((e->rule.mask[word] & bit) == bit
- 		    && audit_filter_rules(tsk, &e->rule, ctx, &state)) {
-			rcu_read_unlock();
-			return state;
-		}
+	if (!list_empty(list)) {
+		    int word = AUDIT_WORD(ctx->major);
+		    int bit  = AUDIT_BIT(ctx->major);
+
+		    list_for_each_entry_rcu(e, list, list) {
+			    if ((e->rule.mask[word] & bit) == bit
+				&& audit_filter_rules(tsk, &e->rule, ctx, &state)) {
+				    rcu_read_unlock();
+				    return state;
+			    }
+		    }
 	}
 	rcu_read_unlock();
 	return AUDIT_BUILD_CONTEXT;
 }
 
+static int audit_filter_user_rules(struct netlink_skb_parms *cb,
+			      struct audit_rule *rule,
+			      enum audit_state *state)
+{
+	int i;
+
+	for (i = 0; i < rule->field_count; i++) {
+		u32 field  = rule->fields[i] & ~AUDIT_NEGATE;
+		u32 value  = rule->values[i];
+		int result = 0;
+
+		switch (field) {
+		case AUDIT_PID:
+			result = (cb->creds.pid == value);
+			break;
+		case AUDIT_UID:
+			result = (cb->creds.uid == value);
+			break;
+		case AUDIT_GID:
+			result = (cb->creds.gid == value);
+			break;
+		case AUDIT_LOGINUID:
+			result = (cb->loginuid == value);
+			break;
+		}
+
+		if (rule->fields[i] & AUDIT_NEGATE)
+			result = !result;
+		if (!result)
+			return 0;
+	}
+	switch (rule->action) {
+	case AUDIT_NEVER:    *state = AUDIT_DISABLED;	    break;
+	case AUDIT_POSSIBLE: *state = AUDIT_BUILD_CONTEXT;  break;
+	case AUDIT_ALWAYS:   *state = AUDIT_RECORD_CONTEXT; break;
+	}
+	return 1;
+}
+
+int audit_filter_user(struct netlink_skb_parms *cb, int type)
+{
+	struct audit_entry *e;
+	enum audit_state   state;
+	int ret = 1;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) {
+		if (audit_filter_user_rules(cb, &e->rule, &state)) {
+			if (state == AUDIT_DISABLED)
+				ret = 0;
+			break;
+		}
+	}
+	rcu_read_unlock();
+
+	return ret; /* Audit by default */
+}
+
 /* This should be called with task_lock() held. */
 static inline struct audit_context *audit_get_context(struct task_struct *tsk,
 						      int return_valid,
@@ -504,7 +628,7 @@
 
 	if (context->in_syscall && !context->auditable) {
 		enum audit_state state;
-		state = audit_filter_syscall(tsk, context, &audit_extlist);
+		state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_EXIT]);
 		if (state == AUDIT_RECORD_CONTEXT)
 			context->auditable = 1;
 	}
@@ -679,13 +803,13 @@
 	up_read(&mm->mmap_sem);
 }
 
-static void audit_log_exit(struct audit_context *context)
+static void audit_log_exit(struct audit_context *context, unsigned int gfp_mask)
 {
 	int i;
 	struct audit_buffer *ab;
 	struct audit_aux_data *aux;
 
-	ab = audit_log_start(context, AUDIT_SYSCALL);
+	ab = audit_log_start(context, gfp_mask, AUDIT_SYSCALL);
 	if (!ab)
 		return;		/* audit_panic has been called */
 	audit_log_format(ab, "arch=%x syscall=%d",
@@ -717,7 +841,7 @@
 
 	for (aux = context->aux; aux; aux = aux->next) {
 
-		ab = audit_log_start(context, aux->type);
+		ab = audit_log_start(context, GFP_KERNEL, aux->type);
 		if (!ab)
 			continue; /* audit_panic has been called */
 
@@ -754,14 +878,14 @@
 	}
 
 	if (context->pwd && context->pwdmnt) {
-		ab = audit_log_start(context, AUDIT_CWD);
+		ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
 		if (ab) {
 			audit_log_d_path(ab, "cwd=", context->pwd, context->pwdmnt);
 			audit_log_end(ab);
 		}
 	}
 	for (i = 0; i < context->name_count; i++) {
-		ab = audit_log_start(context, AUDIT_PATH);
+		ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH);
 		if (!ab)
 			continue; /* audit_panic has been called */
 
@@ -770,6 +894,8 @@
 			audit_log_format(ab, " name=");
 			audit_log_untrustedstring(ab, context->names[i].name);
 		}
+		audit_log_format(ab, " flags=%x\n", context->names[i].flags);
+			 
 		if (context->names[i].ino != (unsigned long)-1)
 			audit_log_format(ab, " inode=%lu dev=%02x:%02x mode=%#o"
 					     " ouid=%u ogid=%u rdev=%02x:%02x",
@@ -799,9 +925,11 @@
 		return;
 
 	/* Check for system calls that do not go through the exit
-	 * function (e.g., exit_group), then free context block. */
-	if (context->in_syscall && context->auditable && context->pid != audit_pid)
-		audit_log_exit(context);
+	 * function (e.g., exit_group), then free context block. 
+	 * We use GFP_ATOMIC here because we might be doing this 
+	 * in the context of the idle thread */
+	if (context->in_syscall && context->auditable)
+		audit_log_exit(context, GFP_ATOMIC);
 
 	audit_free_context(context);
 }
@@ -876,11 +1004,11 @@
 
 	state = context->state;
 	if (state == AUDIT_SETUP_CONTEXT || state == AUDIT_BUILD_CONTEXT)
-		state = audit_filter_syscall(tsk, context, &audit_entlist);
+		state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_ENTRY]);
 	if (likely(state == AUDIT_DISABLED))
 		return;
 
-	context->serial     = audit_serial();
+	context->serial     = 0;
 	context->ctime      = CURRENT_TIME;
 	context->in_syscall = 1;
 	context->auditable  = !!(state == AUDIT_RECORD_CONTEXT);
@@ -903,10 +1031,10 @@
 	/* Not having a context here is ok, since the parent may have
 	 * called __put_task_struct. */
 	if (likely(!context))
-		return;
+		goto out;
 
-	if (context->in_syscall && context->auditable && context->pid != audit_pid)
-		audit_log_exit(context);
+	if (context->in_syscall && context->auditable)
+		audit_log_exit(context, GFP_KERNEL);
 
 	context->in_syscall = 0;
 	context->auditable  = 0;
@@ -919,9 +1047,9 @@
 	} else {
 		audit_free_names(context);
 		audit_free_aux(context);
-		audit_zero_context(context, context->state);
 		tsk->audit_context = context;
 	}
+ out:
 	put_task_struct(tsk);
 }
 
@@ -996,7 +1124,7 @@
 
 /* Store the inode and device from a lookup.  Called from
  * fs/namei.c:path_lookup(). */
-void audit_inode(const char *name, const struct inode *inode)
+void audit_inode(const char *name, const struct inode *inode, unsigned flags)
 {
 	int idx;
 	struct audit_context *context = current->audit_context;
@@ -1022,17 +1150,20 @@
 		++context->ino_count;
 #endif
 	}
-	context->names[idx].ino  = inode->i_ino;
-	context->names[idx].dev	 = inode->i_sb->s_dev;
-	context->names[idx].mode = inode->i_mode;
-	context->names[idx].uid  = inode->i_uid;
-	context->names[idx].gid  = inode->i_gid;
-	context->names[idx].rdev = inode->i_rdev;
+	context->names[idx].flags = flags;
+	context->names[idx].ino   = inode->i_ino;
+	context->names[idx].dev	  = inode->i_sb->s_dev;
+	context->names[idx].mode  = inode->i_mode;
+	context->names[idx].uid   = inode->i_uid;
+	context->names[idx].gid   = inode->i_gid;
+	context->names[idx].rdev  = inode->i_rdev;
 }
 
 void auditsc_get_stamp(struct audit_context *ctx,
 		       struct timespec *t, unsigned int *serial)
 {
+	if (!ctx->serial)
+		ctx->serial = audit_serial();
 	t->tv_sec  = ctx->ctime.tv_sec;
 	t->tv_nsec = ctx->ctime.tv_nsec;
 	*serial    = ctx->serial;
@@ -1044,7 +1175,7 @@
 	if (task->audit_context) {
 		struct audit_buffer *ab;
 
-		ab = audit_log_start(NULL, AUDIT_LOGIN);
+		ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN);
 		if (ab) {
 			audit_log_format(ab, "login pid=%d uid=%u "
 				"old auid=%u new auid=%u",
@@ -1153,7 +1284,7 @@
 	extern pid_t audit_sig_pid;
 	extern uid_t audit_sig_uid;
 
-	if (unlikely(audit_pid && t->pid == audit_pid)) {
+	if (unlikely(audit_pid && t->tgid == audit_pid)) {
 		if (sig == SIGTERM || sig == SIGHUP) {
 			struct audit_context *ctx = current->audit_context;
 			audit_sig_pid = current->pid;
diff --git a/kernel/module.c b/kernel/module.c
index 4b39d37..ff5c500 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/moduleloader.h>
 #include <linux/init.h>
+#include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/elf.h>
@@ -498,7 +499,7 @@
 {
 	int ret = (flags & O_TRUNC);
 	if (ret)
-		tainted |= TAINT_FORCED_MODULE;
+		add_taint(TAINT_FORCED_MODULE);
 	return ret;
 }
 #else
@@ -897,7 +898,7 @@
 	if (!(tainted & TAINT_FORCED_MODULE)) {
 		printk("%s: no version for \"%s\" found: kernel tainted.\n",
 		       mod->name, symname);
-		tainted |= TAINT_FORCED_MODULE;
+		add_taint(TAINT_FORCED_MODULE);
 	}
 	return 1;
 }
@@ -1352,7 +1353,7 @@
 	if (!mod->license_gplok && !(tainted & TAINT_PROPRIETARY_MODULE)) {
 		printk(KERN_WARNING "%s: module license '%s' taints kernel.\n",
 		       mod->name, license);
-		tainted |= TAINT_PROPRIETARY_MODULE;
+		add_taint(TAINT_PROPRIETARY_MODULE);
 	}
 }
 
@@ -1610,7 +1611,7 @@
 	modmagic = get_modinfo(sechdrs, infoindex, "vermagic");
 	/* This is allowed: modprobe --force will invalidate it. */
 	if (!modmagic) {
-		tainted |= TAINT_FORCED_MODULE;
+		add_taint(TAINT_FORCED_MODULE);
 		printk(KERN_WARNING "%s: no version magic, tainting kernel.\n",
 		       mod->name);
 	} else if (!same_magic(modmagic, vermagic)) {
@@ -1739,7 +1740,7 @@
 	    (mod->num_gpl_syms && !gplcrcindex)) {
 		printk(KERN_WARNING "%s: No versions for exported symbols."
 		       " Tainting kernel.\n", mod->name);
-		tainted |= TAINT_FORCED_MODULE;
+		add_taint(TAINT_FORCED_MODULE);
 	}
 #endif
 
diff --git a/kernel/sched.c b/kernel/sched.c
index 81b3a96..1f31a52 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -294,6 +294,10 @@
 
 static inline void finish_lock_switch(runqueue_t *rq, task_t *prev)
 {
+#ifdef CONFIG_DEBUG_SPINLOCK
+	/* this is a valid case when another task releases the spinlock */
+	rq->lock.owner = current;
+#endif
 	spin_unlock_irq(&rq->lock);
 }
 
@@ -1529,10 +1533,6 @@
 	 *		Manfred Spraul <manfred@colorfullife.com>
 	 */
 	prev_task_flags = prev->flags;
-#ifdef CONFIG_DEBUG_SPINLOCK
-	/* this is a valid case when another task releases the spinlock */
-	rq->lock.owner = current;
-#endif
 	finish_arch_switch(prev);
 	finish_lock_switch(rq, prev);
 	if (mm)
diff --git a/kernel/timer.c b/kernel/timer.c
index f4152fc..3ba10fa 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -1151,19 +1151,22 @@
  out:
 	return timeout < 0 ? 0 : timeout;
 }
-
 EXPORT_SYMBOL(schedule_timeout);
 
+/*
+ * We can use __set_current_state() here because schedule_timeout() calls
+ * schedule() unconditionally.
+ */
 signed long __sched schedule_timeout_interruptible(signed long timeout)
 {
-       set_current_state(TASK_INTERRUPTIBLE);
+       __set_current_state(TASK_INTERRUPTIBLE);
        return schedule_timeout(timeout);
 }
 EXPORT_SYMBOL(schedule_timeout_interruptible);
 
 signed long __sched schedule_timeout_uninterruptible(signed long timeout)
 {
-       set_current_state(TASK_UNINTERRUPTIBLE);
+       __set_current_state(TASK_UNINTERRUPTIBLE);
        return schedule_timeout(timeout);
 }
 EXPORT_SYMBOL(schedule_timeout_uninterruptible);
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index afa06e1..9033f08 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -333,8 +333,13 @@
 		if (prev && prev->vm_end < vma->vm_start)
 			return ERR_PTR(-EFAULT);
 		if ((flags & MPOL_MF_STRICT) && !is_vm_hugetlb_page(vma)) {
+			unsigned long endvma = vma->vm_end;
+			if (endvma > end)
+				endvma = end;
+			if (vma->vm_start > start)
+				start = vma->vm_start;
 			err = check_pgd_range(vma->vm_mm,
-					   vma->vm_start, vma->vm_end, nodes);
+					   start, endvma, nodes);
 			if (err) {
 				first = ERR_PTR(err);
 				break;
diff --git a/mm/mmap.c b/mm/mmap.c
index 12334ae..8b8e05f 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1993,6 +1993,9 @@
 	__vma = find_vma_prepare(mm,vma->vm_start,&prev,&rb_link,&rb_parent);
 	if (__vma && __vma->vm_start < vma->vm_end)
 		return -ENOMEM;
+	if ((vma->vm_flags & VM_ACCOUNT) &&
+	     security_vm_enough_memory(vma_pages(vma)))
+		return -ENOMEM;
 	vma_link(mm, vma, prev, rb_link, rb_parent);
 	return 0;
 }
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index c5823c3..ae29033 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -22,6 +22,7 @@
 #include <linux/pagemap.h>
 #include <linux/bootmem.h>
 #include <linux/compiler.h>
+#include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/suspend.h>
 #include <linux/pagevec.h>
@@ -117,7 +118,7 @@
 	set_page_count(page, 0);
 	reset_page_mapcount(page);
 	page->mapping = NULL;
-	tainted |= TAINT_BAD_PAGE;
+	add_taint(TAINT_BAD_PAGE);
 }
 
 #ifndef CONFIG_HUGETLB_PAGE
diff --git a/mm/slab.c b/mm/slab.c
index 9e876d6..437d338 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -659,7 +659,7 @@
  	* kmem_cache_create(), or __kmalloc(), before
  	* the generic caches are initialized.
  	*/
-	BUG_ON(csizep->cs_cachep == NULL);
+	BUG_ON(malloc_sizes[INDEX_AC].cs_cachep == NULL);
 #endif
 	while (size > csizep->cs_size)
 		csizep++;
diff --git a/mm/vmscan.c b/mm/vmscan.c
index a740778..0ea71e8 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1258,9 +1258,9 @@
 		pgdat->kswapd_max_order = order;
 	if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
 		return;
-	if (!waitqueue_active(&zone->zone_pgdat->kswapd_wait))
+	if (!waitqueue_active(&pgdat->kswapd_wait))
 		return;
-	wake_up_interruptible(&zone->zone_pgdat->kswapd_wait);
+	wake_up_interruptible(&pgdat->kswapd_wait);
 }
 
 #ifdef CONFIG_PM
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index d6da093..b61b4e8 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -558,6 +558,35 @@
 	hci_dev_unlock(hdev);
 }
 
+/* Extended Inquiry Result */
+static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	struct inquiry_data data;
+	struct extended_inquiry_info *info = (struct extended_inquiry_info *) (skb->data + 1);
+	int num_rsp = *((__u8 *) skb->data);
+
+	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
+
+	if (!num_rsp)
+		return;
+
+	hci_dev_lock(hdev);
+
+	for (; num_rsp; num_rsp--) {
+		bacpy(&data.bdaddr, &info->bdaddr);
+		data.pscan_rep_mode     = info->pscan_rep_mode;
+		data.pscan_period_mode  = info->pscan_period_mode;
+		data.pscan_mode         = 0x00;
+		memcpy(data.dev_class, info->dev_class, 3);
+		data.clock_offset       = info->clock_offset;
+		data.rssi               = info->rssi;
+		info++;
+		hci_inquiry_cache_update(hdev, &data);
+	}
+
+	hci_dev_unlock(hdev);
+}
+
 /* Connect Request */
 static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
@@ -940,6 +969,10 @@
 		hci_inquiry_result_with_rssi_evt(hdev, skb);
 		break;
 
+	case HCI_EV_EXTENDED_INQUIRY_RESULT:
+		hci_extended_inquiry_result_evt(hdev, skb);
+		break;
+
 	case HCI_EV_CONN_REQUEST:
 		hci_conn_request_evt(hdev, skb);
 		break;
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 90e19eb..f49e7e9 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -363,6 +363,11 @@
 		goto done;
 	}
 
+	if (sk->sk_type != SOCK_STREAM) {
+		err = -EINVAL;
+		goto done;
+	}
+
 	write_lock_bh(&rfcomm_sk_list.lock);
 
 	if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) {
@@ -393,14 +398,18 @@
 	if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_rc))
 		return -EINVAL;
 
-	if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
-		return -EBADFD;
-
-	if (sk->sk_type != SOCK_STREAM)
-		return -EINVAL;
-
 	lock_sock(sk);
 
+	if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) {
+		err = -EBADFD;
+		goto done;
+	}
+
+	if (sk->sk_type != SOCK_STREAM) {
+		err = -EINVAL;
+		goto done;
+	}
+
 	sk->sk_state = BT_CONNECT;
 	bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr);
 	rfcomm_pi(sk)->channel = sa->rc_channel;
@@ -410,6 +419,7 @@
 		err = bt_sock_wait_state(sk, BT_CONNECTED,
 				sock_sndtimeo(sk, flags & O_NONBLOCK));
 
+done:
 	release_sock(sk);
 	return err;
 }
@@ -428,6 +438,11 @@
 		goto done;
 	}
 
+	if (sk->sk_type != SOCK_STREAM) {
+		err = -EINVAL;
+		goto done;
+	}
+
 	if (!rfcomm_pi(sk)->channel) {
 		bdaddr_t *src = &bt_sk(sk)->src;
 		u8 channel;
@@ -472,6 +487,11 @@
 		goto done;
 	}
 
+	if (sk->sk_type != SOCK_STREAM) {
+		err = -EINVAL;
+		goto done;
+	}
+
 	timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
 
 	BT_DBG("sk %p timeo %ld", sk, timeo);
diff --git a/net/dccp/input.c b/net/dccp/input.c
index c60bc34..c74034c 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -50,7 +50,8 @@
 		return;
 	}
 
-	dccp_set_state(sk, DCCP_CLOSING);
+	if (sk->sk_state != DCCP_CLOSING)
+		dccp_set_state(sk, DCCP_CLOSING);
 	dccp_send_close(sk, 0);
 }
 
@@ -561,6 +562,12 @@
 		return 0;
 	}
 
+	if (unlikely(dh->dccph_type == DCCP_PKT_SYNC)) {
+		dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq,
+			       DCCP_PKT_SYNCACK);
+		goto discard;
+	}
+
 	switch (sk->sk_state) {
 	case DCCP_CLOSED:
 		return 1;
diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c
index 1b79ec3..d77d6b3f 100644
--- a/net/ipv4/netfilter/ip_conntrack_ftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_ftp.c
@@ -29,9 +29,9 @@
 static DEFINE_SPINLOCK(ip_ftp_lock);
 
 #define MAX_PORTS 8
-static int ports[MAX_PORTS];
+static short ports[MAX_PORTS];
 static int ports_c;
-module_param_array(ports, int, &ports_c, 0400);
+module_param_array(ports, short, &ports_c, 0400);
 
 static int loose;
 module_param(loose, int, 0600);
@@ -450,7 +450,7 @@
 }
 
 static struct ip_conntrack_helper ftp[MAX_PORTS];
-static char ftp_names[MAX_PORTS][10];
+static char ftp_names[MAX_PORTS][sizeof("ftp-65535")];
 
 /* Not __exit: called from init() */
 static void fini(void)
diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c
index d7a8a98..1545741 100644
--- a/net/ipv4/netfilter/ip_conntrack_irc.c
+++ b/net/ipv4/netfilter/ip_conntrack_irc.c
@@ -34,7 +34,7 @@
 #include <linux/moduleparam.h>
 
 #define MAX_PORTS 8
-static int ports[MAX_PORTS];
+static short ports[MAX_PORTS];
 static int ports_c;
 static int max_dcc_channels = 8;
 static unsigned int dcc_timeout = 300;
@@ -52,7 +52,7 @@
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 MODULE_DESCRIPTION("IRC (DCC) connection tracking helper");
 MODULE_LICENSE("GPL");
-module_param_array(ports, int, &ports_c, 0400);
+module_param_array(ports, short, &ports_c, 0400);
 MODULE_PARM_DESC(ports, "port numbers of IRC servers");
 module_param(max_dcc_channels, int, 0400);
 MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC session");
@@ -240,7 +240,7 @@
 }
 
 static struct ip_conntrack_helper irc_helpers[MAX_PORTS];
-static char irc_names[MAX_PORTS][10];
+static char irc_names[MAX_PORTS][sizeof("irc-65535")];
 
 static void fini(void);
 
diff --git a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
index bb72466..71ef19d 100644
--- a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
+++ b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
@@ -23,7 +23,6 @@
 #include <linux/inetdevice.h>
 #include <linux/in.h>
 #include <linux/ip.h>
-#include <linux/udp.h>
 #include <net/route.h>
 
 #include <linux/netfilter.h>
@@ -31,6 +30,8 @@
 #include <linux/netfilter_ipv4/ip_conntrack.h>
 #include <linux/netfilter_ipv4/ip_conntrack_helper.h>
 
+#define NMBD_PORT	137
+
 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
 MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper");
 MODULE_LICENSE("GPL");
@@ -44,7 +45,6 @@
 {
 	struct ip_conntrack_expect *exp;
 	struct iphdr *iph = (*pskb)->nh.iph;
-	struct udphdr _uh, *uh;
 	struct rtable *rt = (struct rtable *)(*pskb)->dst;
 	struct in_device *in_dev;
 	u_int32_t mask = 0;
@@ -72,20 +72,15 @@
 	if (mask == 0)
 		goto out;
 
-	uh = skb_header_pointer(*pskb, iph->ihl * 4, sizeof(_uh), &_uh);
-	BUG_ON(uh == NULL);
-
 	exp = ip_conntrack_expect_alloc(ct);
 	if (exp == NULL)
 		goto out;
-	memset(&exp->tuple, 0, sizeof(exp->tuple));
-	exp->tuple.src.ip         = iph->daddr & mask;
-	exp->tuple.dst.ip         = iph->saddr;
-	exp->tuple.dst.u.udp.port = uh->source;
-	exp->tuple.dst.protonum   = IPPROTO_UDP;
 
-	memset(&exp->mask, 0, sizeof(exp->mask));
+	exp->tuple                = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
+	exp->tuple.src.u.udp.port = ntohs(NMBD_PORT);
+
 	exp->mask.src.ip          = mask;
+	exp->mask.src.u.udp.port  = 0xFFFF;
 	exp->mask.dst.ip          = 0xFFFFFFFF;
 	exp->mask.dst.u.udp.port  = 0xFFFF;
 	exp->mask.dst.protonum    = 0xFF;
@@ -107,7 +102,7 @@
 		.src = {
 			.u = {
 				.udp = {
-					.port	= __constant_htons(137),
+					.port	= __constant_htons(NMBD_PORT),
 				}
 			}
 		},
diff --git a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c
index d2b5905..a78736b 100644
--- a/net/ipv4/netfilter/ip_conntrack_tftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_tftp.c
@@ -26,9 +26,9 @@
 MODULE_LICENSE("GPL");
 
 #define MAX_PORTS 8
-static int ports[MAX_PORTS];
+static short ports[MAX_PORTS];
 static int ports_c;
-module_param_array(ports, int, &ports_c, 0400);
+module_param_array(ports, short, &ports_c, 0400);
 MODULE_PARM_DESC(ports, "port numbers of tftp servers");
 
 #if 0
@@ -100,7 +100,7 @@
 }
 
 static struct ip_conntrack_helper tftp[MAX_PORTS];
-static char tftp_names[MAX_PORTS][10];
+static char tftp_names[MAX_PORTS][sizeof("tftp-65535")];
 
 static void fini(void)
 {
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index 2f3e181..275a174 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -90,6 +90,12 @@
 	IP_NF_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED
 	                    || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY));
 
+	/* Source address is 0.0.0.0 - locally generated packet that is
+	 * probably not supposed to be masqueraded.
+	 */
+	if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip == 0)
+		return NF_ACCEPT;
+
 	mr = targinfo;
 	rt = (struct rtable *)(*pskb)->dst;
 	newsrc = inet_select_addr(out, rt->rt_gateway, RT_SCOPE_UNIVERSE);
diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c
index d2e1344..715cb61 100644
--- a/net/ipv4/netfilter/ipt_REDIRECT.c
+++ b/net/ipv4/netfilter/ipt_REDIRECT.c
@@ -88,14 +88,18 @@
 		newdst = htonl(0x7F000001);
 	else {
 		struct in_device *indev;
+		struct in_ifaddr *ifa;
 
-		/* Device might not have an associated in_device. */
-		indev = (struct in_device *)(*pskb)->dev->ip_ptr;
-		if (indev == NULL || indev->ifa_list == NULL)
+		newdst = 0;
+		
+		rcu_read_lock();
+		indev = __in_dev_get((*pskb)->dev);
+		if (indev && (ifa = indev->ifa_list))
+			newdst = ifa->ifa_local;
+		rcu_read_unlock();
+
+		if (!newdst)
 			return NF_DROP;
-
-		/* Grab first address on interface. */
-		newdst = indev->ifa_list->ifa_local;
 	}
 
 	/* Transfer from original range. */
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 51885b5..30ec3ef 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -512,15 +512,14 @@
 static void
 svc_udp_data_ready(struct sock *sk, int count)
 {
-	struct svc_sock	*svsk = (struct svc_sock *)(sk->sk_user_data);
+	struct svc_sock	*svsk = (struct svc_sock *)sk->sk_user_data;
 
-	if (!svsk)
-		goto out;
-	dprintk("svc: socket %p(inet %p), count=%d, busy=%d\n",
-		svsk, sk, count, test_bit(SK_BUSY, &svsk->sk_flags));
-	set_bit(SK_DATA, &svsk->sk_flags);
-	svc_sock_enqueue(svsk);
- out:
+	if (svsk) {
+		dprintk("svc: socket %p(inet %p), count=%d, busy=%d\n",
+			svsk, sk, count, test_bit(SK_BUSY, &svsk->sk_flags));
+		set_bit(SK_DATA, &svsk->sk_flags);
+		svc_sock_enqueue(svsk);
+	}
 	if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
 		wake_up_interruptible(sk->sk_sleep);
 }
@@ -540,7 +539,7 @@
 	}
 
 	if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) {
-		printk(KERN_WARNING "RPC svc_write_space: some sleeping on %p\n",
+		dprintk("RPC svc_write_space: someone sleeping on %p\n",
 		       svsk);
 		wake_up_interruptible(sk->sk_sleep);
 	}
@@ -692,31 +691,29 @@
 static void
 svc_tcp_listen_data_ready(struct sock *sk, int count_unused)
 {
-	struct svc_sock	*svsk;
+	struct svc_sock	*svsk = (struct svc_sock *)sk->sk_user_data;
 
 	dprintk("svc: socket %p TCP (listen) state change %d\n",
-			sk, sk->sk_state);
+		sk, sk->sk_state);
 
-	if  (sk->sk_state != TCP_LISTEN) {
-		/*
-		 * This callback may called twice when a new connection
-		 * is established as a child socket inherits everything
-		 * from a parent LISTEN socket.
-		 * 1) data_ready method of the parent socket will be called
-		 *    when one of child sockets become ESTABLISHED.
-		 * 2) data_ready method of the child socket may be called
-		 *    when it receives data before the socket is accepted.
-		 * In case of 2, we should ignore it silently.
-		 */
-		goto out;
+	/*
+	 * This callback may called twice when a new connection
+	 * is established as a child socket inherits everything
+	 * from a parent LISTEN socket.
+	 * 1) data_ready method of the parent socket will be called
+	 *    when one of child sockets become ESTABLISHED.
+	 * 2) data_ready method of the child socket may be called
+	 *    when it receives data before the socket is accepted.
+	 * In case of 2, we should ignore it silently.
+	 */
+	if (sk->sk_state == TCP_LISTEN) {
+		if (svsk) {
+			set_bit(SK_CONN, &svsk->sk_flags);
+			svc_sock_enqueue(svsk);
+		} else
+			printk("svc: socket %p: no user data\n", sk);
 	}
-	if (!(svsk = (struct svc_sock *) sk->sk_user_data)) {
-		printk("svc: socket %p: no user data\n", sk);
-		goto out;
-	}
-	set_bit(SK_CONN, &svsk->sk_flags);
-	svc_sock_enqueue(svsk);
- out:
+
 	if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
 		wake_up_interruptible_all(sk->sk_sleep);
 }
@@ -727,18 +724,17 @@
 static void
 svc_tcp_state_change(struct sock *sk)
 {
-	struct svc_sock	*svsk;
+	struct svc_sock	*svsk = (struct svc_sock *)sk->sk_user_data;
 
 	dprintk("svc: socket %p TCP (connected) state change %d (svsk %p)\n",
-			sk, sk->sk_state, sk->sk_user_data);
+		sk, sk->sk_state, sk->sk_user_data);
 
-	if (!(svsk = (struct svc_sock *) sk->sk_user_data)) {
+	if (!svsk)
 		printk("svc: socket %p: no user data\n", sk);
-		goto out;
+	else {
+		set_bit(SK_CLOSE, &svsk->sk_flags);
+		svc_sock_enqueue(svsk);
 	}
-	set_bit(SK_CLOSE, &svsk->sk_flags);
-	svc_sock_enqueue(svsk);
- out:
 	if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
 		wake_up_interruptible_all(sk->sk_sleep);
 }
@@ -746,15 +742,14 @@
 static void
 svc_tcp_data_ready(struct sock *sk, int count)
 {
-	struct svc_sock *	svsk;
+	struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data;
 
 	dprintk("svc: socket %p TCP data ready (svsk %p)\n",
-			sk, sk->sk_user_data);
-	if (!(svsk = (struct svc_sock *)(sk->sk_user_data)))
-		goto out;
-	set_bit(SK_DATA, &svsk->sk_flags);
-	svc_sock_enqueue(svsk);
- out:
+		sk, sk->sk_user_data);
+	if (svsk) {
+		set_bit(SK_DATA, &svsk->sk_flags);
+		svc_sock_enqueue(svsk);
+	}
 	if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
 		wake_up_interruptible(sk->sk_sleep);
 }
diff --git a/security/Kconfig b/security/Kconfig
index dcf04a0..64d3f1e 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -35,6 +35,7 @@
 
 config SECURITY
 	bool "Enable different security models"
+	depends on SYSFS
 	help
 	  This allows you to choose different security modules to be
 	  configured into your kernel.
diff --git a/security/Makefile b/security/Makefile
index 197cc2f..8cbbf2f 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -11,7 +11,7 @@
 endif
 
 # Object file lists
-obj-$(CONFIG_SECURITY)			+= security.o dummy.o
+obj-$(CONFIG_SECURITY)			+= security.o dummy.o inode.o
 # Must precede capability.o in order to stack properly.
 obj-$(CONFIG_SECURITY_SELINUX)		+= selinux/built-in.o
 obj-$(CONFIG_SECURITY_CAPABILITIES)	+= commoncap.o capability.o
diff --git a/security/inode.c b/security/inode.c
new file mode 100644
index 0000000..a596450
--- /dev/null
+++ b/security/inode.c
@@ -0,0 +1,347 @@
+/*
+ *  inode.c - securityfs
+ *
+ *  Copyright (C) 2005 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 version
+ *	2 as published by the Free Software Foundation.
+ *
+ *  Based on fs/debugfs/inode.c which had the following copyright notice:
+ *    Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
+ *    Copyright (C) 2004 IBM Inc.
+ */
+
+/* #define DEBUG */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/init.h>
+#include <linux/namei.h>
+#include <linux/security.h>
+
+#define SECURITYFS_MAGIC	0x73636673
+
+static struct vfsmount *mount;
+static int mount_count;
+
+/*
+ * TODO:
+ *   I think I can get rid of these default_file_ops, but not quite sure...
+ */
+static ssize_t default_read_file(struct file *file, char __user *buf,
+				 size_t count, loff_t *ppos)
+{
+	return 0;
+}
+
+static ssize_t default_write_file(struct file *file, const char __user *buf,
+				   size_t count, loff_t *ppos)
+{
+	return count;
+}
+
+static int default_open(struct inode *inode, struct file *file)
+{
+	if (inode->u.generic_ip)
+		file->private_data = inode->u.generic_ip;
+
+	return 0;
+}
+
+static struct file_operations default_file_ops = {
+	.read =		default_read_file,
+	.write =	default_write_file,
+	.open =		default_open,
+};
+
+static struct inode *get_inode(struct super_block *sb, int mode, dev_t dev)
+{
+	struct inode *inode = new_inode(sb);
+
+	if (inode) {
+		inode->i_mode = mode;
+		inode->i_uid = 0;
+		inode->i_gid = 0;
+		inode->i_blksize = PAGE_CACHE_SIZE;
+		inode->i_blocks = 0;
+		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+		switch (mode & S_IFMT) {
+		default:
+			init_special_inode(inode, mode, dev);
+			break;
+		case S_IFREG:
+			inode->i_fop = &default_file_ops;
+			break;
+		case S_IFDIR:
+			inode->i_op = &simple_dir_inode_operations;
+			inode->i_fop = &simple_dir_operations;
+
+			/* directory inodes start off with i_nlink == 2 (for "." entry) */
+			inode->i_nlink++;
+			break;
+		}
+	}
+	return inode;
+}
+
+/* SMP-safe */
+static int mknod(struct inode *dir, struct dentry *dentry,
+			 int mode, dev_t dev)
+{
+	struct inode *inode;
+	int error = -EPERM;
+
+	if (dentry->d_inode)
+		return -EEXIST;
+
+	inode = get_inode(dir->i_sb, mode, dev);
+	if (inode) {
+		d_instantiate(dentry, inode);
+		dget(dentry);
+		error = 0;
+	}
+	return error;
+}
+
+static int mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+	int res;
+
+	mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
+	res = mknod(dir, dentry, mode, 0);
+	if (!res)
+		dir->i_nlink++;
+	return res;
+}
+
+static int create(struct inode *dir, struct dentry *dentry, int mode)
+{
+	mode = (mode & S_IALLUGO) | S_IFREG;
+	return mknod(dir, dentry, mode, 0);
+}
+
+static inline int positive(struct dentry *dentry)
+{
+	return dentry->d_inode && !d_unhashed(dentry);
+}
+
+static int fill_super(struct super_block *sb, void *data, int silent)
+{
+	static struct tree_descr files[] = {{""}};
+
+	return simple_fill_super(sb, SECURITYFS_MAGIC, files);
+}
+
+static struct super_block *get_sb(struct file_system_type *fs_type,
+				        int flags, const char *dev_name,
+					void *data)
+{
+	return get_sb_single(fs_type, flags, data, fill_super);
+}
+
+static struct file_system_type fs_type = {
+	.owner =	THIS_MODULE,
+	.name =		"securityfs",
+	.get_sb =	get_sb,
+	.kill_sb =	kill_litter_super,
+};
+
+static int create_by_name(const char *name, mode_t mode,
+			  struct dentry *parent,
+			  struct dentry **dentry)
+{
+	int error = 0;
+
+	*dentry = NULL;
+
+	/* If the parent is not specified, we create it in the root.
+	 * We need the root dentry to do this, which is in the super
+	 * block. A pointer to that is in the struct vfsmount that we
+	 * have around.
+	 */
+	if (!parent ) {
+		if (mount && mount->mnt_sb) {
+			parent = mount->mnt_sb->s_root;
+		}
+	}
+	if (!parent) {
+		pr_debug("securityfs: Ah! can not find a parent!\n");
+		return -EFAULT;
+	}
+
+	down(&parent->d_inode->i_sem);
+	*dentry = lookup_one_len(name, parent, strlen(name));
+	if (!IS_ERR(dentry)) {
+		if ((mode & S_IFMT) == S_IFDIR)
+			error = mkdir(parent->d_inode, *dentry, mode);
+		else
+			error = create(parent->d_inode, *dentry, mode);
+	} else
+		error = PTR_ERR(dentry);
+	up(&parent->d_inode->i_sem);
+
+	return error;
+}
+
+/**
+ * securityfs_create_file - create a file in the securityfs filesystem
+ *
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have
+ * @parent: a pointer to the parent dentry for this file.  This should be a
+ *          directory dentry if set.  If this paramater is NULL, then the
+ *          file will be created in the root of the securityfs filesystem.
+ * @data: a pointer to something that the caller will want to get to later
+ *        on.  The inode.u.generic_ip pointer will point to this value on
+ *        the open() call.
+ * @fops: a pointer to a struct file_operations that should be used for
+ *        this file.
+ *
+ * This is the basic "create a file" function for securityfs.  It allows for a
+ * wide range of flexibility in createing a file, or a directory (if you
+ * want to create a directory, the securityfs_create_dir() function is
+ * recommended to be used instead.)
+ *
+ * This function will return a pointer to a dentry if it succeeds.  This
+ * pointer must be passed to the securityfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.)  If an error occurs, NULL will be returned.
+ *
+ * If securityfs is not enabled in the kernel, the value -ENODEV will be
+ * returned.  It is not wise to check for this value, but rather, check for
+ * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * code.
+ */
+struct dentry *securityfs_create_file(const char *name, mode_t mode,
+				   struct dentry *parent, void *data,
+				   struct file_operations *fops)
+{
+	struct dentry *dentry = NULL;
+	int error;
+
+	pr_debug("securityfs: creating file '%s'\n",name);
+
+	error = simple_pin_fs("securityfs", &mount, &mount_count);
+	if (error) {
+		dentry = ERR_PTR(error);
+		goto exit;
+	}
+
+	error = create_by_name(name, mode, parent, &dentry);
+	if (error) {
+		dentry = ERR_PTR(error);
+		simple_release_fs(&mount, &mount_count);
+		goto exit;
+	}
+
+	if (dentry->d_inode) {
+		if (fops)
+			dentry->d_inode->i_fop = fops;
+		if (data)
+			dentry->d_inode->u.generic_ip = data;
+	}
+exit:
+	return dentry;
+}
+EXPORT_SYMBOL_GPL(securityfs_create_file);
+
+/**
+ * securityfs_create_dir - create a directory in the securityfs filesystem
+ *
+ * @name: a pointer to a string containing the name of the directory to
+ *        create.
+ * @parent: a pointer to the parent dentry for this file.  This should be a
+ *          directory dentry if set.  If this paramater is NULL, then the
+ *          directory will be created in the root of the securityfs filesystem.
+ *
+ * This function creates a directory in securityfs with the given name.
+ *
+ * This function will return a pointer to a dentry if it succeeds.  This
+ * pointer must be passed to the securityfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.)  If an error occurs, NULL will be returned.
+ *
+ * If securityfs is not enabled in the kernel, the value -ENODEV will be
+ * returned.  It is not wise to check for this value, but rather, check for
+ * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * code.
+ */
+struct dentry *securityfs_create_dir(const char *name, struct dentry *parent)
+{
+	return securityfs_create_file(name,
+				      S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
+				      parent, NULL, NULL);
+}
+EXPORT_SYMBOL_GPL(securityfs_create_dir);
+
+/**
+ * securityfs_remove - removes a file or directory from the securityfs filesystem
+ *
+ * @dentry: a pointer to a the dentry of the file or directory to be
+ *          removed.
+ *
+ * This function removes a file or directory in securityfs that was previously
+ * created with a call to another securityfs function (like
+ * securityfs_create_file() or variants thereof.)
+ *
+ * This function is required to be called in order for the file to be
+ * removed, no automatic cleanup of files will happen when a module is
+ * removed, you are responsible here.
+ */
+void securityfs_remove(struct dentry *dentry)
+{
+	struct dentry *parent;
+
+	if (!dentry)
+		return;
+
+	parent = dentry->d_parent;
+	if (!parent || !parent->d_inode)
+		return;
+
+	down(&parent->d_inode->i_sem);
+	if (positive(dentry)) {
+		if (dentry->d_inode) {
+			if (S_ISDIR(dentry->d_inode->i_mode))
+				simple_rmdir(parent->d_inode, dentry);
+			else
+				simple_unlink(parent->d_inode, dentry);
+			dput(dentry);
+		}
+	}
+	up(&parent->d_inode->i_sem);
+	simple_release_fs(&mount, &mount_count);
+}
+EXPORT_SYMBOL_GPL(securityfs_remove);
+
+static decl_subsys(security, NULL, NULL);
+
+static int __init securityfs_init(void)
+{
+	int retval;
+
+	kset_set_kset_s(&security_subsys, kernel_subsys);
+	retval = subsystem_register(&security_subsys);
+	if (retval)
+		return retval;
+
+	retval = register_filesystem(&fs_type);
+	if (retval)
+		subsystem_unregister(&security_subsys);
+	return retval;
+}
+
+static void __exit securityfs_exit(void)
+{
+	simple_release_fs(&mount, &mount_count);
+	unregister_filesystem(&fs_type);
+	subsystem_unregister(&security_subsys);
+}
+
+core_initcall(securityfs_init);
+module_exit(securityfs_exit);
+MODULE_LICENSE("GPL");
+
diff --git a/security/seclvl.c b/security/seclvl.c
index 96b1f21..dc4e17b 100644
--- a/security/seclvl.c
+++ b/security/seclvl.c
@@ -119,69 +119,6 @@
 	} while (0)
 
 /**
- * kobject stuff
- */
-
-struct subsystem seclvl_subsys;
-
-struct seclvl_obj {
-	char *name;
-	struct list_head slot_list;
-	struct kobject kobj;
-};
-
-/**
- * There is a seclvl_attribute struct for each file in sysfs.
- *
- * In our case, we have one of these structs for "passwd" and another
- * for "seclvl".
- */
-struct seclvl_attribute {
-	struct attribute attr;
-	ssize_t(*show) (struct seclvl_obj *, char *);
-	ssize_t(*store) (struct seclvl_obj *, const char *, size_t);
-};
-
-/**
- * When this function is called, one of the files in sysfs is being
- * written to.  attribute->store is a function pointer to whatever the
- * struct seclvl_attribute store function pointer points to.  It is
- * unique for "passwd" and "seclvl".
- */
-static ssize_t
-seclvl_attr_store(struct kobject *kobj,
-		  struct attribute *attr, const char *buf, size_t len)
-{
-	struct seclvl_obj *obj = container_of(kobj, struct seclvl_obj, kobj);
-	struct seclvl_attribute *attribute =
-	    container_of(attr, struct seclvl_attribute, attr);
-	return attribute->store ? attribute->store(obj, buf, len) : -EIO;
-}
-
-static ssize_t
-seclvl_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
-{
-	struct seclvl_obj *obj = container_of(kobj, struct seclvl_obj, kobj);
-	struct seclvl_attribute *attribute =
-	    container_of(attr, struct seclvl_attribute, attr);
-	return attribute->show ? attribute->show(obj, buf) : -EIO;
-}
-
-/**
- * Callback function pointers for show and store
- */
-static struct sysfs_ops seclvlfs_sysfs_ops = {
-	.show = seclvl_attr_show,
-	.store = seclvl_attr_store,
-};
-
-static struct kobj_type seclvl_ktype = {
-	.sysfs_ops = &seclvlfs_sysfs_ops
-};
-
-decl_subsys(seclvl, &seclvl_ktype, NULL);
-
-/**
  * The actual security level.  Ranges between -1 and 2 inclusive.
  */
 static int seclvl;
@@ -213,97 +150,44 @@
 }
 
 /**
- * Called whenever the user reads the sysfs handle to this kernel
- * object
- */
-static ssize_t seclvl_read_file(struct seclvl_obj *obj, char *buff)
-{
-	return snprintf(buff, PAGE_SIZE, "%d\n", seclvl);
-}
-
-/**
  * security level advancement rules:
  *   Valid levels are -1 through 2, inclusive.
  *   From -1, stuck.  [ in case compiled into kernel ]
  *   From 0 or above, can only increment.
  */
-static int do_seclvl_advance(int newlvl)
+static void do_seclvl_advance(void *data, u64 val)
 {
-	if (newlvl <= seclvl) {
-		seclvl_printk(1, KERN_WARNING, "Cannot advance to seclvl "
-			      "[%d]\n", newlvl);
-		return -EINVAL;
-	}
+	int ret;
+	int newlvl = (int)val;
+
+	ret = seclvl_sanity(newlvl);
+	if (ret)
+		return;
+
 	if (newlvl > 2) {
 		seclvl_printk(1, KERN_WARNING, "Cannot advance to seclvl "
 			      "[%d]\n", newlvl);
-		return -EINVAL;
+		return;
 	}
 	if (seclvl == -1) {
 		seclvl_printk(1, KERN_WARNING, "Not allowed to advance to "
 			      "seclvl [%d]\n", seclvl);
-		return -EPERM;
+		return;
 	}
-	seclvl = newlvl;
-	return 0;
+	seclvl = newlvl;  /* would it be more "correct" to set *data? */
+	return;
 }
 
-/**
- * Called whenever the user writes to the sysfs handle to this kernel
- * object (seclvl/seclvl).  It expects a single-digit number.
- */
-static ssize_t
-seclvl_write_file(struct seclvl_obj *obj, const char *buff, size_t count)
+static u64 seclvl_int_get(void *data)
 {
-	unsigned long val;
-	if (count > 2 || (count == 2 && buff[1] != '\n')) {
-		seclvl_printk(1, KERN_WARNING, "Invalid value passed to "
-			      "seclvl: [%s]\n", buff);
-		return -EINVAL;
-	}
-	val = buff[0] - 48;
-	if (seclvl_sanity(val)) {
-		seclvl_printk(1, KERN_WARNING, "Illegal secure level "
-			      "requested: [%d]\n", (int)val);
-		return -EPERM;
-	}
-	if (do_seclvl_advance(val)) {
-		seclvl_printk(0, KERN_ERR, "Failure advancing security level "
-			      "to %lu\n", val);
-	}
-	return count;
+	return *(int *)data;
 }
 
-/* Generate sysfs_attr_seclvl */
-static struct seclvl_attribute sysfs_attr_seclvl =
-__ATTR(seclvl, (S_IFREG | S_IRUGO | S_IWUSR), seclvl_read_file,
-       seclvl_write_file);
+DEFINE_SIMPLE_ATTRIBUTE(seclvl_file_ops, seclvl_int_get, do_seclvl_advance, "%lld\n");
 
 static unsigned char hashedPassword[SHA1_DIGEST_SIZE];
 
 /**
- * Called whenever the user reads the sysfs passwd handle.
- */
-static ssize_t seclvl_read_passwd(struct seclvl_obj *obj, char *buff)
-{
-	/* So just how good *is* your password? :-) */
-	char tmp[3];
-	int i = 0;
-	buff[0] = '\0';
-	if (hideHash) {
-		/* Security through obscurity */
-		return 0;
-	}
-	while (i < SHA1_DIGEST_SIZE) {
-		snprintf(tmp, 3, "%02x", hashedPassword[i]);
-		strncat(buff, tmp, 2);
-		i++;
-	}
-	strcat(buff, "\n");
-	return ((SHA1_DIGEST_SIZE * 2) + 1);
-}
-
-/**
  * Converts a block of plaintext of into its SHA1 hashed value.
  *
  * It would be nice if crypto had a wrapper to do this for us linear
@@ -347,12 +231,15 @@
  * object.  It hashes the password and compares the hashed results.
  */
 static ssize_t
-seclvl_write_passwd(struct seclvl_obj *obj, const char *buff, size_t count)
+passwd_write_file(struct file * file, const char __user * buf,
+				size_t count, loff_t *ppos)
 {
 	int i;
 	unsigned char tmp[SHA1_DIGEST_SIZE];
+	char *page;
 	int rc;
 	int len;
+
 	if (!*passwd && !*sha1_passwd) {
 		seclvl_printk(0, KERN_ERR, "Attempt to password-unlock the "
 			      "seclvl module, but neither a plain text "
@@ -363,13 +250,26 @@
 			      "maintainer about this event.\n");
 		return -EINVAL;
 	}
-	len = strlen(buff);
+
+	if (count < 0 || count >= PAGE_SIZE)
+		return -ENOMEM;
+	if (*ppos != 0) {
+		return -EINVAL;
+	}
+	page = (char *)get_zeroed_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+	len = -EFAULT;
+	if (copy_from_user(page, buf, count))
+		goto out;
+	
+	len = strlen(page);
 	/* ``echo "secret" > seclvl/passwd'' includes a newline */
-	if (buff[len - 1] == '\n') {
+	if (page[len - 1] == '\n') {
 		len--;
 	}
 	/* Hash the password, then compare the hashed values */
-	if ((rc = plaintext_to_sha1(tmp, buff, len))) {
+	if ((rc = plaintext_to_sha1(tmp, page, len))) {
 		seclvl_printk(0, KERN_ERR, "Error hashing password: rc = "
 			      "[%d]\n", rc);
 		return rc;
@@ -382,13 +282,16 @@
 	seclvl_printk(0, KERN_INFO,
 		      "Password accepted; seclvl reduced to 0.\n");
 	seclvl = 0;
-	return count;
+	len = count;
+
+out:
+	free_page((unsigned long)page);
+	return len;
 }
 
-/* Generate sysfs_attr_passwd */
-static struct seclvl_attribute sysfs_attr_passwd =
-__ATTR(passwd, (S_IFREG | S_IRUGO | S_IWUSR), seclvl_read_passwd,
-       seclvl_write_passwd);
+static struct file_operations passwd_file_ops = {
+	.write = passwd_write_file,
+};
 
 /**
  * Explicitely disallow ptrace'ing the init process.
@@ -647,22 +550,34 @@
 }
 
 /**
- * Sysfs registrations
+ * securityfs registrations
  */
-static int doSysfsRegistrations(void)
+struct dentry *dir_ino, *seclvl_ino, *passwd_ino;
+
+static int seclvlfs_register(void)
 {
-	int rc = 0;
-	if ((rc = subsystem_register(&seclvl_subsys))) {
-		seclvl_printk(0, KERN_WARNING,
-			      "Error [%d] registering seclvl subsystem\n", rc);
-		return rc;
-	}
-	sysfs_create_file(&seclvl_subsys.kset.kobj, &sysfs_attr_seclvl.attr);
+	dir_ino = securityfs_create_dir("seclvl", NULL);
+	if (!dir_ino)
+		return -EFAULT;
+
+	seclvl_ino = securityfs_create_file("seclvl", S_IRUGO | S_IWUSR,
+				dir_ino, &seclvl, &seclvl_file_ops);
+	if (!seclvl_ino)
+		goto out_deldir;
 	if (*passwd || *sha1_passwd) {
-		sysfs_create_file(&seclvl_subsys.kset.kobj,
-				  &sysfs_attr_passwd.attr);
+		passwd_ino = securityfs_create_file("passwd", S_IRUGO | S_IWUSR,
+				dir_ino, NULL, &passwd_file_ops);
+		if (!passwd_ino)
+			goto out_delf;
 	}
 	return 0;
+
+out_deldir:
+	securityfs_remove(dir_ino);
+out_delf:
+	securityfs_remove(seclvl_ino);
+
+	return -EFAULT;
 }
 
 /**
@@ -677,8 +592,6 @@
 		rc = -EINVAL;
 		goto exit;
 	}
-	sysfs_attr_seclvl.attr.owner = THIS_MODULE;
-	sysfs_attr_passwd.attr.owner = THIS_MODULE;
 	if (initlvl < -1 || initlvl > 2) {
 		seclvl_printk(0, KERN_ERR, "Error: bad initial securelevel "
 			      "[%d].\n", initlvl);
@@ -706,7 +619,7 @@
 		}		/* if primary module registered */
 		secondary = 1;
 	}			/* if we registered ourselves with the security framework */
-	if ((rc = doSysfsRegistrations())) {
+	if ((rc = seclvlfs_register())) {
 		seclvl_printk(0, KERN_ERR, "Error registering with sysfs\n");
 		goto exit;
 	}
@@ -724,12 +637,11 @@
  */
 static void __exit seclvl_exit(void)
 {
-	sysfs_remove_file(&seclvl_subsys.kset.kobj, &sysfs_attr_seclvl.attr);
+	securityfs_remove(seclvl_ino);
 	if (*passwd || *sha1_passwd) {
-		sysfs_remove_file(&seclvl_subsys.kset.kobj,
-				  &sysfs_attr_passwd.attr);
+		securityfs_remove(passwd_ino);
 	}
-	subsystem_unregister(&seclvl_subsys);
+	securityfs_remove(dir_ino);
 	if (secondary == 1) {
 		mod_unreg_security(MY_NAME, &seclvl_ops);
 	} else if (unregister_security(&seclvl_ops)) {
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index cf6020f..12e4fb7 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -242,7 +242,7 @@
 	avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node),
 					     0, SLAB_PANIC, NULL, NULL);
 
-	audit_log(current->audit_context, AUDIT_KERNEL, "AVC INITIALIZED\n");
+	audit_log(current->audit_context, GFP_KERNEL, AUDIT_KERNEL, "AVC INITIALIZED\n");
 }
 
 int avc_get_hash_stats(char *page)
@@ -550,7 +550,7 @@
 			return;
 	}
 
-	ab = audit_log_start(current->audit_context, AUDIT_AVC);
+	ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_AVC);
 	if (!ab)
 		return;		/* audit_panic has been called */
 	audit_log_format(ab, "avc:  %s ", denied ? "denied" : "granted");
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index f40c822..6e4937f 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3389,7 +3389,7 @@
 	err = selinux_nlmsg_lookup(isec->sclass, nlh->nlmsg_type, &perm);
 	if (err) {
 		if (err == -EINVAL) {
-			audit_log(current->audit_context, AUDIT_SELINUX_ERR,
+			audit_log(current->audit_context, GFP_KERNEL, AUDIT_SELINUX_ERR,
 				  "SELinux:  unrecognized netlink message"
 				  " type=%hu for sclass=%hu\n",
 				  nlh->nlmsg_type, isec->sclass);
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 92b89dc..aecdded 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -381,7 +381,7 @@
 		goto out;
 	if (context_struct_to_string(tcontext, &t, &tlen) < 0)
 		goto out;
-	audit_log(current->audit_context, AUDIT_SELINUX_ERR,
+	audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
 	          "security_validate_transition:  denied for"
 	          " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s",
 	          o, n, t, policydb.p_class_val_to_name[tclass-1]);
@@ -787,7 +787,7 @@
 		goto out;
 	if (context_struct_to_string(newcontext, &n, &nlen) < 0)
 		goto out;
-	audit_log(current->audit_context, AUDIT_SELINUX_ERR,
+	audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
 		  "security_compute_sid:  invalid context %s"
 		  " for scontext=%s"
 		  " tcontext=%s"
diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig
index 2e4a5e0..0864a7c 100644
--- a/sound/arm/Kconfig
+++ b/sound/arm/Kconfig
@@ -7,6 +7,7 @@
 	tristate "SA11xx UDA1341TS driver (iPaq H3600)"
 	depends on ARCH_SA1100 && SND && L3
 	select SND_PCM
+	select SND_GENERIC_DRIVER
 	help
 	  Say Y here if you have a Compaq iPaq H3x00 handheld computer
 	  and want to use its Philips UDA 1341 audio chip.
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index 9887703..34195b74 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -900,6 +900,8 @@
 	if (ret)
 		goto out;
 
+	snd_card_set_dev(aaci->card, &dev->dev);
+
 	ret = snd_card_register(aaci->card);
 	if (ret == 0) {
 		dev_info(&dev->dev, "%s, fifo %d\n", aaci->card->longname,
diff --git a/sound/arm/sa11xx-uda1341.c b/sound/arm/sa11xx-uda1341.c
index 174bc03..6ee9122 100644
--- a/sound/arm/sa11xx-uda1341.c
+++ b/sound/arm/sa11xx-uda1341.c
@@ -21,7 +21,7 @@
  *                              merged HAL layer (patches from Brian)
  */
 
-/* $Id: sa11xx-uda1341.c,v 1.21 2005/01/28 19:34:04 tiwai Exp $ */
+/* $Id: sa11xx-uda1341.c,v 1.23 2005/09/09 13:22:34 tiwai Exp $ */
 
 /***************************************************************************************************
 *
@@ -918,7 +918,7 @@
 	if (card == NULL)
 		return -ENOMEM;
 
-	sa11xx_uda1341 = kcalloc(1, sizeof(*sa11xx_uda1341), GFP_KERNEL);
+	sa11xx_uda1341 = kzalloc(sizeof(*sa11xx_uda1341), GFP_KERNEL);
 	if (sa11xx_uda1341 == NULL)
 		return -ENOMEM;	
 	spin_lock_init(&chip->s[0].dma_lock);
@@ -946,6 +946,9 @@
 	strcpy(card->shortname, "H3600 UDA1341TS");
 	sprintf(card->longname, "Compaq iPAQ H3600 with Philips UDA1341TS");
         
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto nodev;
+
 	if ((err = snd_card_register(card)) == 0) {
 		printk( KERN_INFO "iPAQ audio support initialized\n" );
 		return 0;
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index d1e800b..48cf45c 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -99,6 +99,18 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-rtctimer.
 
+config SND_SEQ_RTCTIMER_DEFAULT
+	bool "Use RTC as default sequencer timer"
+	depends on SND_RTCTIMER && SND_SEQUENCER
+	default y
+	help
+	  Say Y here to use the RTC timer as the default sequencer
+	  timer.  This is strongly recommended because it ensures
+	  precise MIDI timing even when the system timer runs at less
+	  than 1000 Hz.
+
+	  If in doubt, say Y.
+
 config SND_VERBOSE_PRINTK
 	bool "Verbose printk"
 	depends on SND
@@ -128,6 +140,6 @@
 	  Say Y here to enable extra-verbose log messages printed when
 	  detecting devices.
 
-config SND_GENERIC_PM
+config SND_GENERIC_DRIVER
 	bool
 	depends on SND
diff --git a/sound/core/control.c b/sound/core/control.c
index 227f3cf..736edf3 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -69,7 +69,7 @@
 		err = -EFAULT;
 		goto __error2;
 	}
-	ctl = kcalloc(1, sizeof(*ctl), GFP_KERNEL);
+	ctl = kzalloc(sizeof(*ctl), GFP_KERNEL);
 	if (ctl == NULL) {
 		err = -ENOMEM;
 		goto __error;
@@ -162,7 +162,7 @@
 				goto _found;
 			}
 		}
-		ev = kcalloc(1, sizeof(*ev), GFP_ATOMIC);
+		ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
 		if (ev) {
 			ev->id = *id;
 			ev->mask = mask;
@@ -195,7 +195,7 @@
 	
 	snd_runtime_check(control != NULL, return NULL);
 	snd_runtime_check(control->count > 0, return NULL);
-	kctl = kcalloc(1, sizeof(*kctl) + sizeof(snd_kcontrol_volatile_t) * control->count, GFP_KERNEL);
+	kctl = kzalloc(sizeof(*kctl) + sizeof(snd_kcontrol_volatile_t) * control->count, GFP_KERNEL);
 	if (kctl == NULL)
 		return NULL;
 	*kctl = *control;
@@ -521,7 +521,7 @@
 {
 	snd_ctl_card_info_t *info;
 
-	info = kcalloc(1, sizeof(*info), GFP_KERNEL);
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (! info)
 		return -ENOMEM;
 	down_read(&snd_ioctl_rwsem);
@@ -929,7 +929,7 @@
 		return -EINVAL;
 	}
 	private_size *= info->count;
-	ue = kcalloc(1, sizeof(struct user_element) + private_size, GFP_KERNEL);
+	ue = kzalloc(sizeof(struct user_element) + private_size, GFP_KERNEL);
 	if (ue == NULL)
 		return -ENOMEM;
 	ue->info = *info;
@@ -1185,7 +1185,7 @@
 {
 	snd_kctl_ioctl_t *pn;
 
-	pn = kcalloc(1, sizeof(snd_kctl_ioctl_t), GFP_KERNEL);
+	pn = kzalloc(sizeof(snd_kctl_ioctl_t), GFP_KERNEL);
 	if (pn == NULL)
 		return -ENOMEM;
 	pn->fioctl = fcn;
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index 7fdabea..207c7de 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -92,7 +92,7 @@
 	struct sndrv_ctl_elem_info *data;
 	int err;
 
-	data = kcalloc(1, sizeof(*data), GFP_KERNEL);
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (! data)
 		return -ENOMEM;
 
@@ -271,7 +271,7 @@
 	struct sndrv_ctl_elem_value *data;
 	int err, type, count;
 
-	data = kcalloc(1, sizeof(*data), GFP_KERNEL);
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (data == NULL)
 		return -ENOMEM;
 
@@ -291,7 +291,7 @@
 	struct sndrv_ctl_elem_value *data;
 	int err, type, count;
 
-	data = kcalloc(1, sizeof(*data), GFP_KERNEL);
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (data == NULL)
 		return -ENOMEM;
 
@@ -313,7 +313,7 @@
 	struct sndrv_ctl_elem_info *data;
 	int err;
 
-	data = kcalloc(1, sizeof(*data), GFP_KERNEL);
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (! data)
 		return -ENOMEM;
 
diff --git a/sound/core/device.c b/sound/core/device.c
index ca00ad7..1f509f5 100644
--- a/sound/core/device.c
+++ b/sound/core/device.c
@@ -49,7 +49,7 @@
 	snd_assert(card != NULL, return -ENXIO);
 	snd_assert(device_data != NULL, return -ENXIO);
 	snd_assert(ops != NULL, return -ENXIO);
-	dev = kcalloc(1, sizeof(*dev), GFP_KERNEL);
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (dev == NULL)
 		return -ENOMEM;
 	dev->card = card;
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 997dd41..9383f12 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -359,7 +359,7 @@
 	snd_assert(rhwdep != NULL, return -EINVAL);
 	*rhwdep = NULL;
 	snd_assert(card != NULL, return -ENXIO);
-	hwdep = kcalloc(1, sizeof(*hwdep), GFP_KERNEL);
+	hwdep = kzalloc(sizeof(*hwdep), GFP_KERNEL);
 	if (hwdep == NULL)
 		return -ENOMEM;
 	hwdep->card = card;
diff --git a/sound/core/info.c b/sound/core/info.c
index 7f8bdf7..37024d6 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -295,7 +295,7 @@
 		    	goto __error;
 		}
 	}
-	data = kcalloc(1, sizeof(*data), GFP_KERNEL);
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (data == NULL) {
 		err = -ENOMEM;
 		goto __error;
@@ -304,7 +304,7 @@
 	switch (entry->content) {
 	case SNDRV_INFO_CONTENT_TEXT:
 		if (mode == O_RDONLY || mode == O_RDWR) {
-			buffer = kcalloc(1, sizeof(*buffer), GFP_KERNEL);
+			buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
 			if (buffer == NULL) {
 				kfree(data);
 				err = -ENOMEM;
@@ -323,7 +323,7 @@
 			data->rbuffer = buffer;
 		}
 		if (mode == O_WRONLY || mode == O_RDWR) {
-			buffer = kcalloc(1, sizeof(*buffer), GFP_KERNEL);
+			buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
 			if (buffer == NULL) {
 				if (mode == O_RDWR) {
 					vfree(data->rbuffer->buffer);
@@ -752,7 +752,7 @@
 static snd_info_entry_t *snd_info_create_entry(const char *name)
 {
 	snd_info_entry_t *entry;
-	entry = kcalloc(1, sizeof(*entry), GFP_KERNEL);
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
 	if (entry == NULL)
 		return NULL;
 	entry->name = kstrdup(name, GFP_KERNEL);
diff --git a/sound/core/init.c b/sound/core/init.c
index d72f58f..a570201 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -72,7 +72,7 @@
 
 	if (extra_size < 0)
 		extra_size = 0;
-	card = kcalloc(1, sizeof(*card) + extra_size, GFP_KERNEL);
+	card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL);
 	if (card == NULL)
 		return NULL;
 	if (xid) {
@@ -226,8 +226,10 @@
 	return 0;	
 }
 
-#if defined(CONFIG_PM) && defined(CONFIG_SND_GENERIC_PM)
-static void snd_generic_device_unregister(struct snd_generic_device *dev);
+#ifdef CONFIG_SND_GENERIC_DRIVER
+static void snd_generic_device_unregister(snd_card_t *card);
+#else
+#define snd_generic_device_unregister(x) /*NOP*/
 #endif
 
 /**
@@ -253,14 +255,7 @@
 
 #ifdef CONFIG_PM
 	wake_up(&card->power_sleep);
-#ifdef CONFIG_SND_GENERIC_PM
-	if (card->pm_dev) {
-		snd_generic_device_unregister(card->pm_dev);
-		card->pm_dev = NULL;
-	}
 #endif
-#endif
-
 	/* wait, until all devices are ready for the free operation */
 	wait_event(card->shutdown_sleep, card->files == NULL);
 
@@ -288,6 +283,7 @@
 		snd_printk(KERN_WARNING "unable to free card info\n");
 		/* Not fatal error */
 	}
+	snd_generic_device_unregister(card);
 	while (card->s_f_ops) {
 		s_f_ops = card->s_f_ops;
 		card->s_f_ops = s_f_ops->next;
@@ -665,6 +661,96 @@
 	return 0;
 }
 
+#ifdef CONFIG_SND_GENERIC_DRIVER
+/*
+ * generic device without a proper bus using platform_device
+ * (e.g. ISA)
+ */
+struct snd_generic_device {
+	struct platform_device pdev;
+	snd_card_t *card;
+};
+
+#define get_snd_generic_card(dev)	container_of(to_platform_device(dev), struct snd_generic_device, pdev)->card
+
+#define SND_GENERIC_NAME	"snd_generic"
+
+#ifdef CONFIG_PM
+static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level);
+static int snd_generic_resume(struct device *dev, u32 level);
+#endif
+
+/* initialized in sound.c */
+struct device_driver snd_generic_driver = {
+	.name		= SND_GENERIC_NAME,
+	.bus		= &platform_bus_type,
+#ifdef CONFIG_PM
+	.suspend	= snd_generic_suspend,
+	.resume		= snd_generic_resume,
+#endif
+};
+
+void snd_generic_device_release(struct device *dev)
+{
+}
+
+static int snd_generic_device_register(snd_card_t *card)
+{
+	struct snd_generic_device *dev;
+	int err;
+
+	if (card->generic_dev)
+		return 0; /* already registered */
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (! dev) {
+		snd_printk(KERN_ERR "can't allocate generic_device\n");
+		return -ENOMEM;
+	}
+
+	dev->pdev.name = SND_GENERIC_NAME;
+	dev->pdev.id = card->number;
+	dev->pdev.dev.release = snd_generic_device_release;
+	dev->card = card;
+	if ((err = platform_device_register(&dev->pdev)) < 0) {
+		kfree(dev);
+		return err;
+	}
+	card->generic_dev = dev;
+	return 0;
+}
+
+static void snd_generic_device_unregister(snd_card_t *card)
+{
+	struct snd_generic_device *dev = card->generic_dev;
+	if (dev) {
+		platform_device_unregister(&dev->pdev);
+		kfree(dev);
+		card->generic_dev = NULL;
+	}
+}
+
+/**
+ * snd_card_set_generic_dev - assign the generic device to the card
+ * @card: soundcard structure
+ *
+ * Assigns a generic device to the card.  This function is provided as the
+ * last resort, for devices without any proper bus.  Thus this won't override
+ * the device already assigned to the card.
+ * 
+ * Returns zero if successful, or a negative error code.
+ */
+int snd_card_set_generic_dev(snd_card_t *card)
+{
+	int err;
+	if ((err = snd_generic_device_register(card)) < 0)
+		return err;
+	if (! card->dev)
+		snd_card_set_dev(card, &card->generic_dev->pdev.dev);
+	return 0;
+}
+#endif /* CONFIG_SND_GENERIC_DRIVER */
+
 #ifdef CONFIG_PM
 /**
  *  snd_power_wait - wait until the power-state is changed.
@@ -730,75 +816,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_SND_GENERIC_PM
-/*
- * use platform_device for generic power-management without a proper bus
- * (e.g. ISA)
- */
-struct snd_generic_device {
-	struct platform_device pdev;
-	snd_card_t *card;
-};
-
-#define get_snd_generic_card(dev)	container_of(to_platform_device(dev), struct snd_generic_device, pdev)->card
-
-#define SND_GENERIC_NAME	"snd_generic_pm"
-
-static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level);
-static int snd_generic_resume(struct device *dev, u32 level);
-
-static struct device_driver snd_generic_driver = {
-	.name		= SND_GENERIC_NAME,
-	.bus		= &platform_bus_type,
-	.suspend	= snd_generic_suspend,
-	.resume		= snd_generic_resume,
-};
-
-static int generic_driver_registered;
-
-static void generic_driver_unregister(void)
-{
-	if (generic_driver_registered) {
-		generic_driver_registered--;
-		if (! generic_driver_registered)
-			driver_unregister(&snd_generic_driver);
-	}
-}
-
-static struct snd_generic_device *snd_generic_device_register(snd_card_t *card)
-{
-	struct snd_generic_device *dev;
-
-	if (! generic_driver_registered) {
-		if (driver_register(&snd_generic_driver) < 0)
-			return NULL;
-	}
-	generic_driver_registered++;
-
-	dev = kcalloc(1, sizeof(*dev), GFP_KERNEL);
-	if (! dev) {
-		generic_driver_unregister();
-		return NULL;
-	}
-
-	dev->pdev.name = SND_GENERIC_NAME;
-	dev->pdev.id = card->number;
-	dev->card = card;
-	if (platform_device_register(&dev->pdev) < 0) {
-		kfree(dev);
-		generic_driver_unregister();
-		return NULL;
-	}
-	return dev;
-}
-
-static void snd_generic_device_unregister(struct snd_generic_device *dev)
-{
-	platform_device_unregister(&dev->pdev);
-	kfree(dev);
-	generic_driver_unregister();
-}
-
+#ifdef CONFIG_SND_GENERIC_DRIVER
 /* suspend/resume callbacks for snd_generic platform device */
 static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level)
 {
@@ -846,13 +864,12 @@
 				 int (*resume)(snd_card_t *),
 				 void *private_data)
 {
-	card->pm_dev = snd_generic_device_register(card);
-	if (! card->pm_dev)
-		return -ENOMEM;
-	snd_card_set_pm_callback(card, suspend, resume, private_data);
-	return 0;
+	int err;
+	if ((err = snd_generic_device_register(card)) < 0)
+		return err;
+	return snd_card_set_pm_callback(card, suspend, resume, private_data);
 }
-#endif /* CONFIG_SND_GENERIC_PM */
+#endif /* CONFIG_SND_GENERIC_DRIVER */
 
 #ifdef CONFIG_PCI
 int snd_card_pci_suspend(struct pci_dev *dev, pm_message_t state)
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index 39a54a4..91124dd 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -590,7 +590,7 @@
 
 		alloced = 0;
 		pci = NULL;
-		while ((pci = pci_find_device(vendor, device, pci)) != NULL) {
+		while ((pci = pci_get_device(vendor, device, pci)) != NULL) {
 			if (mask > 0 && mask < 0xffffffff) {
 				if (pci_set_dma_mask(pci, mask) < 0 ||
 				    pci_set_consistent_dma_mask(pci, mask) < 0) {
@@ -604,6 +604,7 @@
 				if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
 							size, &dmab) < 0) {
 					printk(KERN_ERR "snd-page-alloc: cannot allocate buffer pages (size = %d)\n", size);
+					pci_dev_put(pci);
 					return (int)count;
 				}
 				snd_dma_reserve_buf(&dmab, snd_dma_pci_buf_id(pci));
diff --git a/sound/core/memory.c b/sound/core/memory.c
index 291b476..8fa888f 100644
--- a/sound/core/memory.c
+++ b/sound/core/memory.c
@@ -249,7 +249,7 @@
 int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count)
 {
 #if defined(__i386__) || defined(CONFIG_SPARC32)
-	return copy_to_user(dst, (const void*)src, count) ? -EFAULT : 0;
+	return copy_to_user(dst, (const void __force*)src, count) ? -EFAULT : 0;
 #else
 	char buf[256];
 	while (count) {
@@ -280,7 +280,7 @@
 int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count)
 {
 #if defined(__i386__) || defined(CONFIG_SPARC32)
-	return copy_from_user((void*)dst, src, count) ? -EFAULT : 0;
+	return copy_from_user((void __force *)dst, src, count) ? -EFAULT : 0;
 #else
 	char buf[256];
 	while (count) {
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 98fc076..69e1059 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -53,7 +53,7 @@
 	err = snd_card_file_add(card, file);
 	if (err < 0)
 		return err;
-	fmixer = kcalloc(1, sizeof(*fmixer), GFP_KERNEL);
+	fmixer = kzalloc(sizeof(*fmixer), GFP_KERNEL);
 	if (fmixer == NULL) {
 		snd_card_file_remove(card, file);
 		return -ENOMEM;
@@ -517,8 +517,8 @@
 		up_read(&card->controls_rwsem);
 		return;
 	}
-	uinfo = kcalloc(1, sizeof(*uinfo), GFP_KERNEL);
-	uctl = kcalloc(1, sizeof(*uctl), GFP_KERNEL);
+	uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
+	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 	if (uinfo == NULL || uctl == NULL)
 		goto __unalloc;
 	snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
@@ -551,8 +551,8 @@
 		up_read(&card->controls_rwsem);
 		return;
 	}
-	uinfo = kcalloc(1, sizeof(*uinfo), GFP_KERNEL);
-	uctl = kcalloc(1, sizeof(*uctl), GFP_KERNEL);
+	uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
+	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 	if (uinfo == NULL || uctl == NULL)
 		goto __unalloc;
 	snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
@@ -612,8 +612,8 @@
 	down_read(&card->controls_rwsem);
 	if ((kctl = snd_ctl_find_numid(card, numid)) == NULL)
 		return;
-	uinfo = kcalloc(1, sizeof(*uinfo), GFP_KERNEL);
-	uctl = kcalloc(1, sizeof(*uctl), GFP_KERNEL);
+	uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
+	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 	if (uinfo == NULL || uctl == NULL)
 		goto __unalloc;
 	snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
@@ -649,8 +649,8 @@
 		up_read(&fmixer->card->controls_rwsem);
 		return;
 	}
-	uinfo = kcalloc(1, sizeof(*uinfo), GFP_KERNEL);
-	uctl = kcalloc(1, sizeof(*uctl), GFP_KERNEL);
+	uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
+	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 	if (uinfo == NULL || uctl == NULL)
 		goto __unalloc;
 	snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
@@ -768,8 +768,8 @@
 	snd_ctl_elem_value_t *uctl;
 	int err, idx;
 	
-	uinfo = kcalloc(1, sizeof(*uinfo), GFP_KERNEL);
-	uctl = kcalloc(1, sizeof(*uctl), GFP_KERNEL);
+	uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
+	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 	if (uinfo == NULL || uctl == NULL) {
 		err = -ENOMEM;
 		goto __unlock;
@@ -813,8 +813,8 @@
 	int err;
 	unsigned int idx;
 
-	uinfo = kcalloc(1, sizeof(*uinfo), GFP_KERNEL);
-	uctl = kcalloc(1, sizeof(*uctl), GFP_KERNEL);
+	uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
+	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 	if (uinfo == NULL || uctl == NULL) {
 		err = -ENOMEM;
 		goto __unlock;
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index a13bd7b..842c28b 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -850,7 +850,9 @@
 					return xfer > 0 ? xfer : -EAGAIN;
 			}
 		} else {
-			tmp = snd_pcm_oss_write2(substream, (const char *)buf, runtime->oss.period_bytes, 0);
+			tmp = snd_pcm_oss_write2(substream,
+						 (const char __force *)buf,
+						 runtime->oss.period_bytes, 0);
 			if (tmp <= 0)
 				return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
 			runtime->oss.bytes += tmp;
@@ -926,7 +928,8 @@
 			xfer += tmp;
 			runtime->oss.buffer_used -= tmp;
 		} else {
-			tmp = snd_pcm_oss_read2(substream, (char *)buf, runtime->oss.period_bytes, 0);
+			tmp = snd_pcm_oss_read2(substream, (char __force *)buf,
+						runtime->oss.period_bytes, 0);
 			if (tmp <= 0)
 				return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
 			runtime->oss.bytes += tmp;
@@ -1540,7 +1543,11 @@
 	} else {
 		delay = snd_pcm_oss_bytes(substream, delay);
 		if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
-			info.blocks = (runtime->oss.buffer_bytes - delay - fixup) / runtime->oss.period_bytes;
+			snd_pcm_oss_setup_t *setup = substream->oss.setup;
+			if (setup && setup->buggyptr)
+				info.blocks = (runtime->oss.buffer_bytes - delay - fixup) / runtime->oss.period_bytes;
+			else
+				info.blocks = (delay + fixup) / runtime->oss.period_bytes;
 			info.bytes = (runtime->oss.bytes - delay) & INT_MAX;
 		} else {
 			delay += fixup;
@@ -1733,7 +1740,7 @@
 	snd_assert(rpcm_oss_file != NULL, return -EINVAL);
 	*rpcm_oss_file = NULL;
 
-	pcm_oss_file = kcalloc(1, sizeof(*pcm_oss_file), GFP_KERNEL);
+	pcm_oss_file = kzalloc(sizeof(*pcm_oss_file), GFP_KERNEL);
 	if (pcm_oss_file == NULL)
 		return -ENOMEM;
 
@@ -2347,6 +2354,8 @@
 				template.partialfrag = 1;
 			} else if (!strcmp(str, "no-silence")) {
 				template.nosilence = 1;
+			} else if (!strcmp(str, "buggy-ptr")) {
+				template.buggyptr = 1;
 			}
 		} while (*str);
 		if (setup == NULL) {
diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c
index 6430410..fc23373 100644
--- a/sound/core/oss/pcm_plugin.c
+++ b/sound/core/oss/pcm_plugin.c
@@ -171,7 +171,7 @@
 	
 	snd_assert(plug != NULL, return -ENXIO);
 	snd_assert(src_format != NULL && dst_format != NULL, return -ENXIO);
-	plugin = kcalloc(1, sizeof(*plugin) + extra, GFP_KERNEL);
+	plugin = kzalloc(sizeof(*plugin) + extra, GFP_KERNEL);
 	if (plugin == NULL)
 		return -ENOMEM;
 	plugin->name = name;
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 9f4c920..1be470e 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -597,7 +597,7 @@
 	}
 	prev = NULL;
 	for (idx = 0, prev = NULL; idx < substream_count; idx++) {
-		substream = kcalloc(1, sizeof(*substream), GFP_KERNEL);
+		substream = kzalloc(sizeof(*substream), GFP_KERNEL);
 		if (substream == NULL)
 			return -ENOMEM;
 		substream->pcm = pcm;
@@ -657,7 +657,7 @@
 	snd_assert(rpcm != NULL, return -EINVAL);
 	*rpcm = NULL;
 	snd_assert(card != NULL, return -ENXIO);
-	pcm = kcalloc(1, sizeof(*pcm), GFP_KERNEL);
+	pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
 	if (pcm == NULL)
 		return -ENOMEM;
 	pcm->card = card;
@@ -795,7 +795,7 @@
 	if (substream == NULL)
 		return -EAGAIN;
 
-	runtime = kcalloc(1, sizeof(*runtime), GFP_KERNEL);
+	runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
 	if (runtime == NULL)
 		return -ENOMEM;
 
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 0082914..0503980 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -524,6 +524,9 @@
 
 /**
  * snd_interval_div - refine the interval value with division
+ * @a: dividend
+ * @b: divisor
+ * @c: quotient
  *
  * c = a / b
  *
@@ -555,7 +558,11 @@
 
 /**
  * snd_interval_muldivk - refine the interval value
- *
+ * @a: dividend 1
+ * @b: dividend 2
+ * @k: divisor (as integer)
+ * @c: result
+  *
  * c = a * b / k
  *
  * Returns non-zero if the value is changed, zero if not changed.
@@ -582,6 +589,10 @@
 
 /**
  * snd_interval_mulkdiv - refine the interval value
+ * @a: dividend 1
+ * @k: dividend 2 (as integer)
+ * @b: divisor
+ * @c: result
  *
  * c = a * k / b
  *
@@ -618,6 +629,11 @@
 
 /**
  * snd_interval_ratnum - refine the interval value
+ * @i: interval to refine
+ * @rats_count: number of ratnum_t 
+ * @rats: ratnum_t array
+ * @nump: pointer to store the resultant numerator
+ * @denp: pointer to store the resultant denominator
  *
  * Returns non-zero if the value is changed, zero if not changed.
  */
@@ -715,6 +731,11 @@
 
 /**
  * snd_interval_ratden - refine the interval value
+ * @i: interval to refine
+ * @rats_count: number of ratden_t
+ * @rats: ratden_t array
+ * @nump: pointer to store the resultant numerator
+ * @denp: pointer to store the resultant denominator
  *
  * Returns non-zero if the value is changed, zero if not changed.
  */
@@ -936,6 +957,11 @@
 
 /**
  * snd_pcm_hw_constraint_mask
+ * @runtime: PCM runtime instance
+ * @var: hw_params variable to apply the mask
+ * @mask: the bitmap mask
+ *
+ * Apply the constraint of the given bitmap mask to a mask parameter.
  */
 int snd_pcm_hw_constraint_mask(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
 			       u_int32_t mask)
@@ -951,6 +977,11 @@
 
 /**
  * snd_pcm_hw_constraint_mask64
+ * @runtime: PCM runtime instance
+ * @var: hw_params variable to apply the mask
+ * @mask: the 64bit bitmap mask
+ *
+ * Apply the constraint of the given bitmap mask to a mask parameter.
  */
 int snd_pcm_hw_constraint_mask64(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
 				 u_int64_t mask)
@@ -967,6 +998,10 @@
 
 /**
  * snd_pcm_hw_constraint_integer
+ * @runtime: PCM runtime instance
+ * @var: hw_params variable to apply the integer constraint
+ *
+ * Apply the constraint of integer to an interval parameter.
  */
 int snd_pcm_hw_constraint_integer(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var)
 {
@@ -976,6 +1011,12 @@
 
 /**
  * snd_pcm_hw_constraint_minmax
+ * @runtime: PCM runtime instance
+ * @var: hw_params variable to apply the range
+ * @min: the minimal value
+ * @max: the maximal value
+ * 
+ * Apply the min/max range constraint to an interval parameter.
  */
 int snd_pcm_hw_constraint_minmax(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
 				 unsigned int min, unsigned int max)
@@ -999,6 +1040,12 @@
 
 /**
  * snd_pcm_hw_constraint_list
+ * @runtime: PCM runtime instance
+ * @cond: condition bits
+ * @var: hw_params variable to apply the list constraint
+ * @l: list
+ * 
+ * Apply the list of constraints to an interval parameter.
  */
 int snd_pcm_hw_constraint_list(snd_pcm_runtime_t *runtime,
 			       unsigned int cond,
@@ -1027,6 +1074,10 @@
 
 /**
  * snd_pcm_hw_constraint_ratnums
+ * @runtime: PCM runtime instance
+ * @cond: condition bits
+ * @var: hw_params variable to apply the ratnums constraint
+ * @r: ratnums_t constriants
  */
 int snd_pcm_hw_constraint_ratnums(snd_pcm_runtime_t *runtime, 
 				  unsigned int cond,
@@ -1054,6 +1105,10 @@
 
 /**
  * snd_pcm_hw_constraint_ratdens
+ * @runtime: PCM runtime instance
+ * @cond: condition bits
+ * @var: hw_params variable to apply the ratdens constraint
+ * @r: ratdens_t constriants
  */
 int snd_pcm_hw_constraint_ratdens(snd_pcm_runtime_t *runtime, 
 				  unsigned int cond,
@@ -1079,6 +1134,10 @@
 
 /**
  * snd_pcm_hw_constraint_msbits
+ * @runtime: PCM runtime instance
+ * @cond: condition bits
+ * @width: sample bits width
+ * @msbits: msbits width
  */
 int snd_pcm_hw_constraint_msbits(snd_pcm_runtime_t *runtime, 
 				 unsigned int cond,
@@ -1101,6 +1160,10 @@
 
 /**
  * snd_pcm_hw_constraint_step
+ * @runtime: PCM runtime instance
+ * @cond: condition bits
+ * @var: hw_params variable to apply the step constraint
+ * @step: step size
  */
 int snd_pcm_hw_constraint_step(snd_pcm_runtime_t *runtime,
 			       unsigned int cond,
@@ -1126,6 +1189,9 @@
 
 /**
  * snd_pcm_hw_constraint_pow2
+ * @runtime: PCM runtime instance
+ * @cond: condition bits
+ * @var: hw_params variable to apply the power-of-2 constraint
  */
 int snd_pcm_hw_constraint_pow2(snd_pcm_runtime_t *runtime,
 			       unsigned int cond,
@@ -1162,7 +1228,7 @@
 }
 
 #if 0
-/**
+/*
  * snd_pcm_hw_param_any
  */
 int snd_pcm_hw_param_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
@@ -1185,7 +1251,7 @@
 }
 
 #if 0
-/**
+/*
  * snd_pcm_hw_params_any
  *
  * Fill PARAMS with full configuration space boundaries
@@ -1199,6 +1265,9 @@
 
 /**
  * snd_pcm_hw_param_value
+ * @params: the hw_params instance
+ * @var: parameter to retrieve
+ * @dir: pointer to the direction (-1,0,1) or NULL
  *
  * Return the value for field PAR if it's fixed in configuration space 
  *  defined by PARAMS. Return -EINVAL otherwise
@@ -1228,6 +1297,9 @@
 
 /**
  * snd_pcm_hw_param_value_min
+ * @params: the hw_params instance
+ * @var: parameter to retrieve
+ * @dir: pointer to the direction (-1,0,1) or NULL
  *
  * Return the minimum value for field PAR.
  */
@@ -1251,6 +1323,9 @@
 
 /**
  * snd_pcm_hw_param_value_max
+ * @params: the hw_params instance
+ * @var: parameter to retrieve
+ * @dir: pointer to the direction (-1,0,1) or NULL
  *
  * Return the maximum value for field PAR.
  */
@@ -1302,7 +1377,7 @@
 }
 	
 #if 0
-/**
+/*
  * snd_pcm_hw_param_setinteger
  *
  * Inside configuration space defined by PARAMS remove from PAR all 
@@ -1347,6 +1422,10 @@
 
 /**
  * snd_pcm_hw_param_first
+ * @pcm: PCM instance
+ * @params: the hw_params instance
+ * @var: parameter to retrieve
+ * @dir: pointer to the direction (-1,0,1) or NULL
  *
  * Inside configuration space defined by PARAMS remove from PAR all 
  * values > minimum. Reduce configuration space accordingly.
@@ -1388,6 +1467,10 @@
 
 /**
  * snd_pcm_hw_param_last
+ * @pcm: PCM instance
+ * @params: the hw_params instance
+ * @var: parameter to retrieve
+ * @dir: pointer to the direction (-1,0,1) or NULL
  *
  * Inside configuration space defined by PARAMS remove from PAR all 
  * values < maximum. Reduce configuration space accordingly.
@@ -1439,6 +1522,11 @@
 
 /**
  * snd_pcm_hw_param_min
+ * @pcm: PCM instance
+ * @params: the hw_params instance
+ * @var: parameter to retrieve
+ * @val: minimal value
+ * @dir: pointer to the direction (-1,0,1) or NULL
  *
  * Inside configuration space defined by PARAMS remove from PAR all 
  * values < VAL. Reduce configuration space accordingly.
@@ -1494,6 +1582,11 @@
 
 /**
  * snd_pcm_hw_param_max
+ * @pcm: PCM instance
+ * @params: the hw_params instance
+ * @var: parameter to retrieve
+ * @val: maximal value
+ * @dir: pointer to the direction (-1,0,1) or NULL
  *
  * Inside configuration space defined by PARAMS remove from PAR all 
  *  values >= VAL + 1. Reduce configuration space accordingly.
@@ -1565,6 +1658,11 @@
 
 /**
  * snd_pcm_hw_param_set
+ * @pcm: PCM instance
+ * @params: the hw_params instance
+ * @var: parameter to retrieve
+ * @val: value to set
+ * @dir: pointer to the direction (-1,0,1) or NULL
  *
  * Inside configuration space defined by PARAMS remove from PAR all 
  * values != VAL. Reduce configuration space accordingly.
@@ -1599,6 +1697,10 @@
 
 /**
  * snd_pcm_hw_param_mask
+ * @pcm: PCM instance
+ * @params: the hw_params instance
+ * @var: parameter to retrieve
+ * @val: mask to apply
  *
  * Inside configuration space defined by PARAMS remove from PAR all values
  * not contained in MASK. Reduce configuration space accordingly.
@@ -1671,6 +1773,11 @@
 
 /**
  * snd_pcm_hw_param_near
+ * @pcm: PCM instance
+ * @params: the hw_params instance
+ * @var: parameter to retrieve
+ * @best: value to set
+ * @dir: pointer to the direction (-1,0,1) or NULL
  *
  * Inside configuration space defined by PARAMS set PAR to the available value
  * nearest to VAL. Reduce configuration space accordingly.
@@ -1747,6 +1854,8 @@
 
 /**
  * snd_pcm_hw_param_choose
+ * @pcm: PCM instance
+ * @params: the hw_params instance
  *
  * Choose one configuration from configuration space defined by PARAMS
  * The configuration chosen is that obtained fixing in this order:
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index 9a174fb..b3f5344 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -244,7 +244,7 @@
 
 /**
  * snd_pcm_lib_preallocate_pages_for_all - pre-allocation for continous memory type (all substreams)
- * @substream: the pcm substream instance
+ * @pcm: the pcm instance
  * @type: DMA type (SNDRV_DMA_TYPE_*)
  * @data: DMA type dependant data
  * @size: the requested pre-allocation size in bytes
@@ -321,7 +321,7 @@
 	if (substream->dma_buffer.area != NULL && substream->dma_buffer.bytes >= size) {
 		dmab = &substream->dma_buffer; /* use the pre-allocated buffer */
 	} else {
-		dmab = kcalloc(1, sizeof(*dmab), GFP_KERNEL);
+		dmab = kzalloc(sizeof(*dmab), GFP_KERNEL);
 		if (! dmab)
 			return -ENOMEM;
 		dmab->dev = substream->dma_buffer.dev;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 03c1715..67abeba 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -859,6 +859,7 @@
 
 /**
  * snd_pcm_start
+ * @substream: the PCM substream instance
  *
  * Start all linked streams.
  */
@@ -908,6 +909,8 @@
 
 /**
  * snd_pcm_stop
+ * @substream: the PCM substream instance
+ * @state: PCM state after stopping the stream
  *
  * Try to stop all running streams in the substream group.
  * The state of each stream is changed to the given value after that unconditionally.
@@ -919,6 +922,7 @@
 
 /**
  * snd_pcm_drain_done
+ * @substream: the PCM substream
  *
  * Stop the DMA only when the given stream is playback.
  * The state is changed to SETUP.
@@ -1040,6 +1044,7 @@
 
 /**
  * snd_pcm_suspend
+ * @substream: the PCM substream
  *
  * Trigger SUSPEND to all linked streams.
  * After this call, all streams are changed to SUSPENDED state.
@@ -1057,6 +1062,7 @@
 
 /**
  * snd_pcm_suspend_all
+ * @pcm: the PCM instance
  *
  * Trigger SUSPEND to all substreams in the given pcm.
  * After this call, all streams are changed to SUSPENDED state.
@@ -1272,6 +1278,9 @@
 
 /**
  * snd_pcm_prepare
+ * @substream: the PCM substream instance
+ *
+ * Prepare the PCM substream to be triggerable.
  */
 int snd_pcm_prepare(snd_pcm_substream_t *substream)
 {
@@ -1992,7 +2001,7 @@
 	snd_assert(rpcm_file != NULL, return -EINVAL);
 	*rpcm_file = NULL;
 
-	pcm_file = kcalloc(1, sizeof(*pcm_file), GFP_KERNEL);
+	pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL);
 	if (pcm_file == NULL) {
 		return -ENOMEM;
 	}
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index edba411..7c20eaf 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -101,7 +101,7 @@
 {
 	snd_rawmidi_runtime_t *runtime;
 
-	if ((runtime = kcalloc(1, sizeof(*runtime), GFP_KERNEL)) == NULL)
+	if ((runtime = kzalloc(sizeof(*runtime), GFP_KERNEL)) == NULL)
 		return -ENOMEM;
 	spin_lock_init(&runtime->lock);
 	init_waitqueue_head(&runtime->sleep);
@@ -984,7 +984,9 @@
 			spin_lock_irq(&runtime->lock);
 		}
 		spin_unlock_irq(&runtime->lock);
-		count1 = snd_rawmidi_kernel_read1(substream, (unsigned char *)buf, count, 0);
+		count1 = snd_rawmidi_kernel_read1(substream,
+						  (unsigned char __force *)buf,
+						  count, 0);
 		if (count1 < 0)
 			return result > 0 ? result : count1;
 		result += count1;
@@ -1107,7 +1109,7 @@
 /**
  * snd_rawmidi_transmit - copy from the buffer to the device
  * @substream: the rawmidi substream
- * @buf: the buffer pointer
+ * @buffer: the buffer pointer
  * @count: the data size to transfer
  * 
  * Copies data from the buffer to the device and advances the pointer.
@@ -1213,7 +1215,9 @@
 			spin_lock_irq(&runtime->lock);
 		}
 		spin_unlock_irq(&runtime->lock);
-		count1 = snd_rawmidi_kernel_write1(substream, (unsigned char *)buf, count, 0);
+		count1 = snd_rawmidi_kernel_write1(substream,
+						   (unsigned char __force *)buf,
+						   count, 0);
 		if (count1 < 0)
 			return result > 0 ? result : count1;
 		result += count1;
@@ -1370,7 +1374,7 @@
 
 	INIT_LIST_HEAD(&stream->substreams);
 	for (idx = 0; idx < count; idx++) {
-		substream = kcalloc(1, sizeof(*substream), GFP_KERNEL);
+		substream = kzalloc(sizeof(*substream), GFP_KERNEL);
 		if (substream == NULL)
 			return -ENOMEM;
 		substream->stream = direction;
@@ -1413,7 +1417,7 @@
 	snd_assert(rrawmidi != NULL, return -EINVAL);
 	*rrawmidi = NULL;
 	snd_assert(card != NULL, return -ENXIO);
-	rmidi = kcalloc(1, sizeof(*rmidi), GFP_KERNEL);
+	rmidi = kzalloc(sizeof(*rmidi), GFP_KERNEL);
 	if (rmidi == NULL)
 		return -ENOMEM;
 	rmidi->card = card;
diff --git a/sound/core/seq/instr/ainstr_gf1.c b/sound/core/seq/instr/ainstr_gf1.c
index 32e91c6..207c2c5 100644
--- a/sound/core/seq/instr/ainstr_gf1.c
+++ b/sound/core/seq/instr/ainstr_gf1.c
@@ -61,7 +61,7 @@
 		return -EFAULT;
 	*data += sizeof(xp);
 	*len -= sizeof(xp);
-	wp = kcalloc(1, sizeof(*wp), gfp_mask);
+	wp = kzalloc(sizeof(*wp), gfp_mask);
 	if (wp == NULL)
 		return -ENOMEM;
 	wp->share_id[0] = le32_to_cpu(xp.share_id[0]);
diff --git a/sound/core/seq/instr/ainstr_iw.c b/sound/core/seq/instr/ainstr_iw.c
index 2622b86..b3cee09 100644
--- a/sound/core/seq/instr/ainstr_iw.c
+++ b/sound/core/seq/instr/ainstr_iw.c
@@ -92,7 +92,7 @@
 		points_size = (le16_to_cpu(rx.nattack) + le16_to_cpu(rx.nrelease)) * 2 * sizeof(__u16);
 		if (points_size > *len)
 			return -EINVAL;
-		rp = kcalloc(1, sizeof(*rp) + points_size, gfp_mask);
+		rp = kzalloc(sizeof(*rp) + points_size, gfp_mask);
 		if (rp == NULL)
 			return -ENOMEM;
 		rp->nattack = le16_to_cpu(rx.nattack);
@@ -139,7 +139,7 @@
 		return -EFAULT;
 	*data += sizeof(xp);
 	*len -= sizeof(xp);
-	wp = kcalloc(1, sizeof(*wp), gfp_mask);
+	wp = kzalloc(sizeof(*wp), gfp_mask);
 	if (wp == NULL)
 		return -ENOMEM;
 	wp->share_id[0] = le32_to_cpu(xp.share_id[0]);
@@ -273,7 +273,7 @@
 			snd_seq_iwffff_instr_free(ops, ip, atomic);
 			return -EINVAL;
 		}
-		lp = kcalloc(1, sizeof(*lp), gfp_mask);
+		lp = kzalloc(sizeof(*lp), gfp_mask);
 		if (lp == NULL) {
 			snd_seq_iwffff_instr_free(ops, ip, atomic);
 			return -ENOMEM;
diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c
index bac4b4f..1ab1cf8 100644
--- a/sound/core/seq/oss/seq_oss_init.c
+++ b/sound/core/seq/oss/seq_oss_init.c
@@ -193,7 +193,7 @@
 	int i, rc;
 	seq_oss_devinfo_t *dp;
 
-	if ((dp = kcalloc(1, sizeof(*dp), GFP_KERNEL)) == NULL) {
+	if ((dp = kzalloc(sizeof(*dp), GFP_KERNEL)) == NULL) {
 		snd_printk(KERN_ERR "can't malloc device info\n");
 		return -ENOMEM;
 	}
diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c
index 9aece6c..f0e95c8 100644
--- a/sound/core/seq/oss/seq_oss_midi.c
+++ b/sound/core/seq/oss/seq_oss_midi.c
@@ -76,8 +76,8 @@
 	snd_seq_client_info_t *clinfo;
 	snd_seq_port_info_t *pinfo;
 
-	clinfo = kcalloc(1, sizeof(*clinfo), GFP_KERNEL);
-	pinfo = kcalloc(1, sizeof(*pinfo), GFP_KERNEL);
+	clinfo = kzalloc(sizeof(*clinfo), GFP_KERNEL);
+	pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL);
 	if (! clinfo || ! pinfo) {
 		kfree(clinfo);
 		kfree(pinfo);
@@ -172,7 +172,7 @@
 	/*
 	 * allocate midi info record
 	 */
-	if ((mdev = kcalloc(1, sizeof(*mdev), GFP_KERNEL)) == NULL) {
+	if ((mdev = kzalloc(sizeof(*mdev), GFP_KERNEL)) == NULL) {
 		snd_printk(KERN_ERR "can't malloc midi info\n");
 		return -ENOMEM;
 	}
diff --git a/sound/core/seq/oss/seq_oss_readq.c b/sound/core/seq/oss/seq_oss_readq.c
index 0a6f2a6..55571e1 100644
--- a/sound/core/seq/oss/seq_oss_readq.c
+++ b/sound/core/seq/oss/seq_oss_readq.c
@@ -46,7 +46,7 @@
 {
 	seq_oss_readq_t *q;
 
-	if ((q = kcalloc(1, sizeof(*q), GFP_KERNEL)) == NULL) {
+	if ((q = kzalloc(sizeof(*q), GFP_KERNEL)) == NULL) {
 		snd_printk(KERN_ERR "can't malloc read queue\n");
 		return NULL;
 	}
diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c
index 1a7736c..8257fce 100644
--- a/sound/core/seq/oss/seq_oss_synth.c
+++ b/sound/core/seq/oss/seq_oss_synth.c
@@ -103,7 +103,7 @@
 	snd_seq_oss_reg_t *reg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
 	unsigned long flags;
 
-	if ((rec = kcalloc(1, sizeof(*rec), GFP_KERNEL)) == NULL) {
+	if ((rec = kzalloc(sizeof(*rec), GFP_KERNEL)) == NULL) {
 		snd_printk(KERN_ERR "can't malloc synth info\n");
 		return -ENOMEM;
 	}
@@ -499,7 +499,7 @@
 
 	sysex = dp->synths[dev].sysex;
 	if (sysex == NULL) {
-		sysex = kcalloc(1, sizeof(*sysex), GFP_KERNEL);
+		sysex = kzalloc(sizeof(*sysex), GFP_KERNEL);
 		if (sysex == NULL)
 			return -ENOMEM;
 		dp->synths[dev].sysex = sysex;
diff --git a/sound/core/seq/oss/seq_oss_timer.c b/sound/core/seq/oss/seq_oss_timer.c
index 42ca949..64d594b 100644
--- a/sound/core/seq/oss/seq_oss_timer.c
+++ b/sound/core/seq/oss/seq_oss_timer.c
@@ -46,7 +46,7 @@
 {
 	seq_oss_timer_t *rec;
 
-	rec = kcalloc(1, sizeof(*rec), GFP_KERNEL);
+	rec = kzalloc(sizeof(*rec), GFP_KERNEL);
 	if (rec == NULL)
 		return NULL;
 
diff --git a/sound/core/seq/oss/seq_oss_writeq.c b/sound/core/seq/oss/seq_oss_writeq.c
index 87f85f7..b203780 100644
--- a/sound/core/seq/oss/seq_oss_writeq.c
+++ b/sound/core/seq/oss/seq_oss_writeq.c
@@ -38,7 +38,7 @@
 	seq_oss_writeq_t *q;
 	snd_seq_client_pool_t pool;
 
-	if ((q = kcalloc(1, sizeof(*q), GFP_KERNEL)) == NULL)
+	if ((q = kzalloc(sizeof(*q), GFP_KERNEL)) == NULL)
 		return NULL;
 	q->dp = dp;
 	q->maxlen = maxlen;
diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c
index 7449d2a..24644150 100644
--- a/sound/core/seq/seq.c
+++ b/sound/core/seq/seq.c
@@ -43,7 +43,13 @@
 int seq_default_timer_class = SNDRV_TIMER_CLASS_GLOBAL;
 int seq_default_timer_sclass = SNDRV_TIMER_SCLASS_NONE;
 int seq_default_timer_card = -1;
-int seq_default_timer_device = SNDRV_TIMER_GLOBAL_SYSTEM;
+int seq_default_timer_device =
+#ifdef CONFIG_SND_SEQ_RTCTIMER_DEFAULT
+	SNDRV_TIMER_GLOBAL_RTC
+#else
+	SNDRV_TIMER_GLOBAL_SYSTEM
+#endif
+	;
 int seq_default_timer_subdevice = 0;
 int seq_default_timer_resolution = 0;	/* Hz */
 
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index d8f76af..a886db9 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -203,7 +203,7 @@
 	client_t *client;
 
 	/* init client data */
-	client = kcalloc(1, sizeof(*client), GFP_KERNEL);
+	client = kzalloc(sizeof(*client), GFP_KERNEL);
 	if (client == NULL)
 		return NULL;
 	client->pool = snd_seq_pool_new(poolsize);
@@ -413,7 +413,9 @@
 			}
 			count -= sizeof(snd_seq_event_t);
 			buf += sizeof(snd_seq_event_t);
-			err = snd_seq_expand_var_event(&cell->event, count, (char *)buf, 0, sizeof(snd_seq_event_t));
+			err = snd_seq_expand_var_event(&cell->event, count,
+						       (char __force *)buf, 0,
+						       sizeof(snd_seq_event_t));
 			if (err < 0)
 				break;
 			result += err;
@@ -1009,7 +1011,8 @@
 			}
 			/* set user space pointer */
 			event.data.ext.len = extlen | SNDRV_SEQ_EXT_USRPTR;
-			event.data.ext.ptr = (char*)buf + sizeof(snd_seq_event_t);
+			event.data.ext.ptr = (char __force *)buf
+						+ sizeof(snd_seq_event_t);
 			len += extlen; /* increment data length */
 		} else {
 #ifdef CONFIG_COMPAT
diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c
index 4d80f39..252b527 100644
--- a/sound/core/seq/seq_device.c
+++ b/sound/core/seq/seq_device.c
@@ -200,7 +200,7 @@
 	if (ops == NULL)
 		return -ENOMEM;
 
-	dev = kcalloc(1, sizeof(*dev)*2 + argsize, GFP_KERNEL);
+	dev = kzalloc(sizeof(*dev)*2 + argsize, GFP_KERNEL);
 	if (dev == NULL) {
 		unlock_driver(ops);
 		return -ENOMEM;
diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c
index ea945a5..5dd0e6a 100644
--- a/sound/core/seq/seq_dummy.c
+++ b/sound/core/seq/seq_dummy.c
@@ -153,7 +153,7 @@
 	snd_seq_port_callback_t pcb;
 	snd_seq_dummy_port_t *rec;
 
-	if ((rec = kcalloc(1, sizeof(*rec), GFP_KERNEL)) == NULL)
+	if ((rec = kzalloc(sizeof(*rec), GFP_KERNEL)) == NULL)
 		return NULL;
 
 	rec->client = my_client;
diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c
index 3b7647c..4767cfd 100644
--- a/sound/core/seq/seq_fifo.c
+++ b/sound/core/seq/seq_fifo.c
@@ -33,7 +33,7 @@
 {
 	fifo_t *f;
 
-	f = kcalloc(1, sizeof(*f), GFP_KERNEL);
+	f = kzalloc(sizeof(*f), GFP_KERNEL);
 	if (f == NULL) {
 		snd_printd("malloc failed for snd_seq_fifo_new() \n");
 		return NULL;
diff --git a/sound/core/seq/seq_instr.c b/sound/core/seq/seq_instr.c
index 5b40ea2..019d43a 100644
--- a/sound/core/seq/seq_instr.c
+++ b/sound/core/seq/seq_instr.c
@@ -53,7 +53,7 @@
 {
 	snd_seq_kinstr_t *instr;
 	
-	instr = kcalloc(1, sizeof(snd_seq_kinstr_t) + add_len, atomic ? GFP_ATOMIC : GFP_KERNEL);
+	instr = kzalloc(sizeof(snd_seq_kinstr_t) + add_len, atomic ? GFP_ATOMIC : GFP_KERNEL);
 	if (instr == NULL)
 		return NULL;
 	instr->add_len = add_len;
@@ -77,7 +77,7 @@
 {
 	snd_seq_kinstr_list_t *list;
 
-	list = kcalloc(1, sizeof(snd_seq_kinstr_list_t), GFP_KERNEL);
+	list = kzalloc(sizeof(snd_seq_kinstr_list_t), GFP_KERNEL);
 	if (list == NULL)
 		return NULL;
 	spin_lock_init(&list->lock);
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
index 03acb2d..d4d7d32 100644
--- a/sound/core/seq/seq_memory.c
+++ b/sound/core/seq/seq_memory.c
@@ -452,7 +452,7 @@
 	pool_t *pool;
 
 	/* create pool block */
-	pool = kcalloc(1, sizeof(*pool), GFP_KERNEL);
+	pool = kzalloc(sizeof(*pool), GFP_KERNEL);
 	if (pool == NULL) {
 		snd_printd("seq: malloc failed for pool\n");
 		return NULL;
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
index 4374829..b4674ae 100644
--- a/sound/core/seq/seq_midi.c
+++ b/sound/core/seq/seq_midi.c
@@ -322,7 +322,7 @@
 	client = synths[card->number];
 	if (client == NULL) {
 		newclient = 1;
-		client = kcalloc(1, sizeof(*client), GFP_KERNEL);
+		client = kzalloc(sizeof(*client), GFP_KERNEL);
 		if (client == NULL) {
 			up(&register_mutex);
 			kfree(info);
diff --git a/sound/core/seq/seq_midi_event.c b/sound/core/seq/seq_midi_event.c
index 603b637..2dc1aec 100644
--- a/sound/core/seq/seq_midi_event.c
+++ b/sound/core/seq/seq_midi_event.c
@@ -118,7 +118,7 @@
 	snd_midi_event_t *dev;
 
 	*rdev = NULL;
-	dev = kcalloc(1, sizeof(*dev), GFP_KERNEL);
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (dev == NULL)
 		return -ENOMEM;
 	if (bufsize > 0) {
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
index b976951..57ec31d 100644
--- a/sound/core/seq/seq_ports.c
+++ b/sound/core/seq/seq_ports.c
@@ -141,7 +141,7 @@
 	}
 
 	/* create a new port */
-	new_port = kcalloc(1, sizeof(*new_port), GFP_KERNEL);
+	new_port = kzalloc(sizeof(*new_port), GFP_KERNEL);
 	if (! new_port) {
 		snd_printd("malloc failed for registering client port\n");
 		return NULL;	/* failure, out of memory */
@@ -488,7 +488,7 @@
 	unsigned long flags;
 	int exclusive;
 
-	subs = kcalloc(1, sizeof(*subs), GFP_KERNEL);
+	subs = kzalloc(sizeof(*subs), GFP_KERNEL);
 	if (! subs)
 		return -ENOMEM;
 
diff --git a/sound/core/seq/seq_prioq.c b/sound/core/seq/seq_prioq.c
index a519732e..cd641bc 100644
--- a/sound/core/seq/seq_prioq.c
+++ b/sound/core/seq/seq_prioq.c
@@ -59,7 +59,7 @@
 {
 	prioq_t *f;
 
-	f = kcalloc(1, sizeof(*f), GFP_KERNEL);
+	f = kzalloc(sizeof(*f), GFP_KERNEL);
 	if (f == NULL) {
 		snd_printd("oops: malloc failed for snd_seq_prioq_new()\n");
 		return NULL;
diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c
index 98de2e7..5f5c3cb 100644
--- a/sound/core/seq/seq_queue.c
+++ b/sound/core/seq/seq_queue.c
@@ -111,7 +111,7 @@
 {
 	queue_t *q;
 
-	q = kcalloc(1, sizeof(*q), GFP_KERNEL);
+	q = kzalloc(sizeof(*q), GFP_KERNEL);
 	if (q == NULL) {
 		snd_printd("malloc failed for snd_seq_queue_new()\n");
 		return NULL;
diff --git a/sound/core/seq/seq_system.c b/sound/core/seq/seq_system.c
index e8f0a66..0d9eff8 100644
--- a/sound/core/seq/seq_system.c
+++ b/sound/core/seq/seq_system.c
@@ -126,8 +126,8 @@
 	snd_seq_client_info_t *inf;
 	snd_seq_port_info_t *port;
 
-	inf = kcalloc(1, sizeof(*inf), GFP_KERNEL);
-	port = kcalloc(1, sizeof(*port), GFP_KERNEL);
+	inf = kzalloc(sizeof(*inf), GFP_KERNEL);
+	port = kzalloc(sizeof(*port), GFP_KERNEL);
 	if (! inf || ! port) {
 		kfree(inf);
 		kfree(port);
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
index a7f76fc..b57a3c0 100644
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -60,7 +60,7 @@
 {
 	seq_timer_t *tmr;
 	
-	tmr = kcalloc(1, sizeof(*tmr), GFP_KERNEL);
+	tmr = kzalloc(sizeof(*tmr), GFP_KERNEL);
 	if (tmr == NULL) {
 		snd_printd("malloc failed for snd_seq_timer_new() \n");
 		return NULL;
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
index a66484b5..e4f512a 100644
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -205,7 +205,7 @@
 	snd_virmidi_t *vmidi;
 	unsigned long flags;
 
-	vmidi = kcalloc(1, sizeof(*vmidi), GFP_KERNEL);
+	vmidi = kzalloc(sizeof(*vmidi), GFP_KERNEL);
 	if (vmidi == NULL)
 		return -ENOMEM;
 	vmidi->substream = substream;
@@ -233,7 +233,7 @@
 	snd_rawmidi_runtime_t *runtime = substream->runtime;
 	snd_virmidi_t *vmidi;
 
-	vmidi = kcalloc(1, sizeof(*vmidi), GFP_KERNEL);
+	vmidi = kzalloc(sizeof(*vmidi), GFP_KERNEL);
 	if (vmidi == NULL)
 		return -ENOMEM;
 	vmidi->substream = substream;
@@ -508,7 +508,7 @@
 				   &rmidi)) < 0)
 		return err;
 	strcpy(rmidi->name, rmidi->id);
-	rdev = kcalloc(1, sizeof(*rdev), GFP_KERNEL);
+	rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
 	if (rdev == NULL) {
 		snd_device_free(card, rmidi);
 		return -ENOMEM;
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 3271e92..9e76bdd 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -328,6 +328,10 @@
  *  INIT PART
  */
 
+#ifdef CONFIG_SND_GENERIC_DRIVER
+extern struct device_driver snd_generic_driver;
+#endif
+
 static int __init alsa_sound_init(void)
 {
 	short controlnum;
@@ -354,6 +358,9 @@
 		return -ENOMEM;
 	}
 	snd_info_minor_register();
+#ifdef CONFIG_SND_GENERIC_DRIVER
+	driver_register(&snd_generic_driver);
+#endif
 	for (controlnum = 0; controlnum < cards_limit; controlnum++)
 		devfs_mk_cdev(MKDEV(major, controlnum<<5), S_IFCHR | device_mode, "snd/controlC%d", controlnum);
 #ifndef MODULE
@@ -369,6 +376,9 @@
 	for (controlnum = 0; controlnum < cards_limit; controlnum++)
 		devfs_remove("snd/controlC%d", controlnum);
 
+#ifdef CONFIG_SND_GENERIC_DRIVER
+	driver_unregister(&snd_generic_driver);
+#endif
 	snd_info_minor_unregister();
 	snd_info_done();
 	snd_memory_done();
@@ -416,10 +426,13 @@
 EXPORT_SYMBOL(snd_component_add);
 EXPORT_SYMBOL(snd_card_file_add);
 EXPORT_SYMBOL(snd_card_file_remove);
+#ifdef CONFIG_SND_GENERIC_DRIVER
+EXPORT_SYMBOL(snd_card_set_generic_dev);
+#endif
 #ifdef CONFIG_PM
 EXPORT_SYMBOL(snd_power_wait);
 EXPORT_SYMBOL(snd_card_set_pm_callback);
-#if defined(CONFIG_PM) && defined(CONFIG_SND_GENERIC_PM)
+#ifdef CONFIG_SND_GENERIC_DRIVER
 EXPORT_SYMBOL(snd_card_set_generic_pm_callback);
 #endif
 #ifdef CONFIG_PCI
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 4104f6e..22b1046 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -98,7 +98,7 @@
 static snd_timer_instance_t *snd_timer_instance_new(char *owner, snd_timer_t *timer)
 {
 	snd_timer_instance_t *timeri;
-	timeri = kcalloc(1, sizeof(*timeri), GFP_KERNEL);
+	timeri = kzalloc(sizeof(*timeri), GFP_KERNEL);
 	if (timeri == NULL)
 		return NULL;
 	timeri->owner = kstrdup(owner, GFP_KERNEL);
@@ -764,7 +764,7 @@
 	snd_assert(tid != NULL, return -EINVAL);
 	snd_assert(rtimer != NULL, return -EINVAL);
 	*rtimer = NULL;
-	timer = kcalloc(1, sizeof(*timer), GFP_KERNEL);
+	timer = kzalloc(sizeof(*timer), GFP_KERNEL);
 	if (timer == NULL)
 		return -ENOMEM;
 	timer->tmr_class = tid->dev_class;
@@ -1017,7 +1017,7 @@
 		return err;
 	strcpy(timer->name, "system timer");
 	timer->hw = snd_timer_system;
-	priv = kcalloc(1, sizeof(*priv), GFP_KERNEL);
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	if (priv == NULL) {
 		snd_timer_free(timer);
 		return -ENOMEM;
@@ -1202,7 +1202,7 @@
 {
 	snd_timer_user_t *tu;
 	
-	tu = kcalloc(1, sizeof(*tu), GFP_KERNEL);
+	tu = kzalloc(sizeof(*tu), GFP_KERNEL);
 	if (tu == NULL)
 		return -ENOMEM;
 	spin_lock_init(&tu->qlock);
@@ -1513,7 +1513,7 @@
 	t = tu->timeri->timer;
 	snd_assert(t != NULL, return -ENXIO);
 
-	info = kcalloc(1, sizeof(*info), GFP_KERNEL);
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (! info)
 		return -ENOMEM;
 	info->card = t->card ? t->card->number : -1;
diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig
index 3b2bee1..efcb4eb 100644
--- a/sound/drivers/Kconfig
+++ b/sound/drivers/Kconfig
@@ -29,6 +29,7 @@
 	tristate "Dummy (/dev/null) soundcard"
 	depends on SND
 	select SND_PCM
+	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include the dummy driver.  This driver does
 	  nothing, but emulates various mixer controls and PCM devices.
@@ -44,6 +45,7 @@
 	depends on SND_SEQUENCER
 	select SND_TIMER
 	select SND_RAWMIDI
+	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include the virtual MIDI driver.  This driver
 	  allows to connect applications using raw MIDI devices to
@@ -59,6 +61,7 @@
 	depends on SND
 	select SND_TIMER
 	select SND_RAWMIDI
+	select SND_GENERIC_DRIVER
 	help
 	  To use a MOTU MidiTimePiece AV multiport MIDI adapter
 	  connected to the parallel port, say Y here and make sure that
@@ -72,6 +75,7 @@
 	depends on SND
 	select SND_TIMER
 	select SND_RAWMIDI
+	select SND_GENERIC_DRIVER
 	help
 	  To include support for MIDI serial port interfaces, say Y here
 	  and read <file:Documentation/sound/alsa/serial-u16550.txt>.
@@ -88,6 +92,7 @@
 	tristate "Generic MPU-401 UART driver"
 	depends on SND
 	select SND_MPU401_UART
+	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for MIDI ports compatible with
 	  the Roland MPU-401 interface in UART mode.
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index a61640c..64ef7f6 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -337,7 +337,7 @@
 	snd_card_dummy_pcm_t *dpcm;
 	int err;
 
-	dpcm = kcalloc(1, sizeof(*dpcm), GFP_KERNEL);
+	dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
 	if (dpcm == NULL)
 		return -ENOMEM;
 	init_timer(&dpcm->timer);
@@ -368,7 +368,7 @@
 	snd_card_dummy_pcm_t *dpcm;
 	int err;
 
-	dpcm = kcalloc(1, sizeof(*dpcm), GFP_KERNEL);
+	dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
 	if (dpcm == NULL)
 		return -ENOMEM;
 	init_timer(&dpcm->timer);
@@ -600,6 +600,10 @@
 	strcpy(card->driver, "Dummy");
 	strcpy(card->shortname, "Dummy");
 	sprintf(card->longname, "Dummy %i", dev + 1);
+
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto __nodev;
+
 	if ((err = snd_card_register(card)) == 0) {
 		snd_dummy_cards[dev] = card;
 		return 0;
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index cb36ecb..54e2ff9 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -77,20 +77,26 @@
 		strcat(card->longname, "polled");
 	}
 
-	if (snd_mpu401_uart_new(card, 0,
-				MPU401_HW_MPU401,
-				port[dev], 0,
-				irq[dev], irq[dev] >= 0 ? SA_INTERRUPT : 0, NULL) < 0) {
+	if ((err = snd_mpu401_uart_new(card, 0,
+				       MPU401_HW_MPU401,
+				       port[dev], 0,
+				       irq[dev], irq[dev] >= 0 ? SA_INTERRUPT : 0, NULL)) < 0) {
 		printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]);
-		snd_card_free(card);
-		return -ENODEV;
+		goto _err;
 	}
-	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto _err;
+
+	if ((err = snd_card_register(card)) < 0)
+		goto _err;
+
 	*rcard = card;
 	return 0;
+
+ _err:
+	snd_card_free(card);
+	return err;
 }
 
 static int __devinit snd_mpu401_probe(int dev)
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
index 0f83c52..fe3f921 100644
--- a/sound/drivers/mpu401/mpu401_uart.c
+++ b/sound/drivers/mpu401/mpu401_uart.c
@@ -463,7 +463,7 @@
 		*rrawmidi = NULL;
 	if ((err = snd_rawmidi_new(card, "MPU-401U", device, 1, 1, &rmidi)) < 0)
 		return err;
-	mpu = kcalloc(1, sizeof(*mpu), GFP_KERNEL);
+	mpu = kzalloc(sizeof(*mpu), GFP_KERNEL);
 	if (mpu == NULL) {
 		snd_device_free(card, rmidi);
 		return -ENOMEM;
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index 1280a57..3a25c89 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -688,7 +688,7 @@
 
 static mtpav_t *new_mtpav(void)
 {
-	mtpav_t *ncrd = kcalloc(1, sizeof(*ncrd), GFP_KERNEL);
+	mtpav_t *ncrd = kzalloc(sizeof(*ncrd), GFP_KERNEL);
 	if (ncrd != NULL) {
 		spin_lock_init(&ncrd->spinlock);
 
@@ -757,6 +757,9 @@
 	if (err < 0)
 		goto __error;
 
+	if ((err = snd_card_set_generic_dev(mtp_card->card)) < 0)
+		goto __error;
+
 	err = snd_card_register(mtp_card->card);	// don't snd_card_register until AFTER all cards reources done!
 
 	//printk("snd_card_register returned %d\n", err);
diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c
index c313e52..1f84d78 100644
--- a/sound/drivers/opl3/opl3_lib.c
+++ b/sound/drivers/opl3/opl3_lib.c
@@ -354,7 +354,7 @@
 	int err;
 
 	*ropl3 = NULL;
-	opl3 = kcalloc(1, sizeof(*opl3), GFP_KERNEL);
+	opl3 = kzalloc(sizeof(*opl3), GFP_KERNEL);
 	if (opl3 == NULL)
 		return -ENOMEM;
 
diff --git a/sound/drivers/opl3/opl3_oss.c b/sound/drivers/opl3/opl3_oss.c
index 33da334..21a2b40 100644
--- a/sound/drivers/opl3/opl3_oss.c
+++ b/sound/drivers/opl3/opl3_oss.c
@@ -241,7 +241,7 @@
 		}
 
 		size = sizeof(*put) + sizeof(fm_xinstrument_t);
-		put = kcalloc(1, size, GFP_KERNEL);
+		put = kzalloc(size, GFP_KERNEL);
 		if (put == NULL)
 			return -ENOMEM;
 		/* build header */
diff --git a/sound/drivers/opl4/opl4_lib.c b/sound/drivers/opl4/opl4_lib.c
index 8261464..380c2c7 100644
--- a/sound/drivers/opl4/opl4_lib.c
+++ b/sound/drivers/opl4/opl4_lib.c
@@ -204,7 +204,7 @@
 	if (ropl4)
 		*ropl4 = NULL;
 
-	opl4 = kcalloc(1, sizeof(*opl4), GFP_KERNEL);
+	opl4 = kzalloc(sizeof(*opl4), GFP_KERNEL);
 	if (!opl4)
 		return -ENOMEM;
 
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index 986df35..416172e 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -779,7 +779,7 @@
 	int err;
 
 
-	if ((uart = kcalloc(1, sizeof(*uart), GFP_KERNEL)) == NULL)
+	if ((uart = kzalloc(sizeof(*uart), GFP_KERNEL)) == NULL)
 		return -ENOMEM;
 	uart->adaptor = adaptor;
 	uart->card = card;
@@ -928,15 +928,11 @@
 					base[dev],
 					adaptor[dev],
 					droponfull[dev],
-					&uart)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+					&uart)) < 0)
+		goto _err;
 
-	if ((err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi)) < 0)
+		goto _err;
 
 	sprintf(card->longname, "%s at 0x%lx, irq %d speed %d div %d outs %d ins %d adaptor %s droponfull %d",
 		card->shortname,
@@ -949,12 +945,18 @@
 		adaptor_names[uart->adaptor],
 		uart->drop_on_full);
 
-	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto _err;
+
+	if ((err = snd_card_register(card)) < 0)
+		goto _err;
+
 	snd_serial_cards[dev] = card;
 	return 0;
+
+ _err:
+	snd_card_free(card);
+	return err;
 }
 
 static int __init alsa_card_serial_init(void)
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c
index 5937711..af12185 100644
--- a/sound/drivers/virmidi.c
+++ b/sound/drivers/virmidi.c
@@ -116,6 +116,10 @@
 	strcpy(card->driver, "VirMIDI");
 	strcpy(card->shortname, "VirMIDI");
 	sprintf(card->longname, "Virtual MIDI Card %i", dev + 1);
+
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto __nodev;
+
 	if ((err = snd_card_register(card)) == 0) {
 		snd_virmidi_cards[dev] = card;
 		return 0;
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
index c6fa5af..4697b1d 100644
--- a/sound/drivers/vx/vx_core.c
+++ b/sound/drivers/vx/vx_core.c
@@ -782,7 +782,7 @@
 
 	snd_assert(card && hw && ops, return NULL);
 
-	chip = kcalloc(1, sizeof(*chip) + extra_size, GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip) + extra_size, GFP_KERNEL);
 	if (! chip) {
 		snd_printk(KERN_ERR "vx_core: no memory\n");
 		return NULL;
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
index d4becf4..c2312d9 100644
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -473,7 +473,7 @@
 		return err;
 
 	/* initialize the pipe record */
-	pipe = kcalloc(1, sizeof(*pipe), GFP_KERNEL);
+	pipe = kzalloc(sizeof(*pipe), GFP_KERNEL);
 	if (! pipe) {
 		/* release the pipe */
 		vx_init_rmh(&rmh, CMD_FREE_PIPE);
diff --git a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c
index a3fda85..a21f7d5 100644
--- a/sound/i2c/cs8427.c
+++ b/sound/i2c/cs8427.c
@@ -200,7 +200,7 @@
 
 	if ((err = snd_i2c_device_create(bus, "CS8427", CS8427_ADDR | (addr & 7), &device)) < 0)
 		return err;
-	chip = device->private_data = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = device->private_data = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL) {
 	      	snd_i2c_device_free(device);
 		return -ENOMEM;
diff --git a/sound/i2c/i2c.c b/sound/i2c/i2c.c
index e8fa7e1..e4e505b 100644
--- a/sound/i2c/i2c.c
+++ b/sound/i2c/i2c.c
@@ -81,7 +81,7 @@
 	};
 
 	*ri2c = NULL;
-	bus = kcalloc(1, sizeof(*bus), GFP_KERNEL);
+	bus = kzalloc(sizeof(*bus), GFP_KERNEL);
 	if (bus == NULL)
 		return -ENOMEM;
 	init_MUTEX(&bus->lock_mutex);
@@ -108,7 +108,7 @@
 
 	*rdevice = NULL;
 	snd_assert(bus != NULL, return -EINVAL);
-	device = kcalloc(1, sizeof(*device), GFP_KERNEL);
+	device = kzalloc(sizeof(*device), GFP_KERNEL);
 	if (device == NULL)
 		return -ENOMEM;
 	device->addr = addr;
diff --git a/sound/i2c/l3/uda1341.c b/sound/i2c/l3/uda1341.c
index e13122f..103a7dc 100644
--- a/sound/i2c/l3/uda1341.c
+++ b/sound/i2c/l3/uda1341.c
@@ -17,7 +17,7 @@
  * 2002-05-12   Tomas Kasparek  another code cleanup
  */
 
-/* $Id: uda1341.c,v 1.15 2005/01/03 12:05:20 tiwai Exp $ */
+/* $Id: uda1341.c,v 1.16 2005/09/09 13:22:34 tiwai Exp $ */
 
 #include <sound/driver.h>
 #include <linux/module.h>
@@ -670,7 +670,7 @@
 
 	snd_assert(card != NULL, return -EINVAL);
 
-	uda1341 = kcalloc(1, sizeof(*uda1341), GFP_KERNEL);
+	uda1341 = kzalloc(sizeof(*uda1341), GFP_KERNEL);
 	if (uda1341 == NULL)
 		return -ENOMEM;
          
@@ -707,7 +707,7 @@
 {
 	struct uda1341 *uda;
 
-	uda = kcalloc(1, sizeof(*uda), 0, GFP_KERNEL);
+	uda = kzalloc(sizeof(*uda), 0, GFP_KERNEL);
 	if (!uda)
 		return -ENOMEM;
 
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
index 5adde30..af5eadc 100644
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -92,7 +92,7 @@
 		.dev_free =     snd_ak4114_dev_free,
 	};
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL)
 		return -ENOMEM;
 	spin_lock_init(&chip->lock);
diff --git a/sound/i2c/other/ak4117.c b/sound/i2c/other/ak4117.c
index 0419c433..d51b51d 100644
--- a/sound/i2c/other/ak4117.c
+++ b/sound/i2c/other/ak4117.c
@@ -83,7 +83,7 @@
 		.dev_free =     snd_ak4117_dev_free,
 	};
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL)
 		return -ENOMEM;
 	spin_lock_init(&chip->lock);
diff --git a/sound/i2c/tea6330t.c b/sound/i2c/tea6330t.c
index 2da8d7f..fd65da6 100644
--- a/sound/i2c/tea6330t.c
+++ b/sound/i2c/tea6330t.c
@@ -281,7 +281,7 @@
 	u8 default_treble, default_bass;
 	unsigned char bytes[7];
 
-	tea = kcalloc(1, sizeof(*tea), GFP_KERNEL);
+	tea = kzalloc(sizeof(*tea), GFP_KERNEL);
 	if (tea == NULL)
 		return -ENOMEM;
 	if ((err = snd_i2c_device_create(bus, "TEA6330T", TEA6330T_ADDR, &device)) < 0) {
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index 5c39483..5d6c300a 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -6,12 +6,12 @@
 config SND_AD1848_LIB
         tristate
         select SND_PCM
-	select SND_GENERIC_PM
+	select SND_GENERIC_DRIVER
 
 config SND_CS4231_LIB
         tristate
         select SND_PCM
-	select SND_GENERIC_PM
+	select SND_GENERIC_DRIVER
 
 config SND_AD1816A
 	tristate "Analog Devices SoundPort AD1816A"
@@ -97,6 +97,7 @@
 	select SND_OPL3_LIB
 	select SND_MPU401_UART
 	select SND_PCM
+	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for ESS AudioDrive ES688 or
 	  ES1688 chips.
@@ -110,7 +111,7 @@
 	select SND_OPL3_LIB
 	select SND_MPU401_UART
 	select SND_PCM
-	select SND_GENERIC_PM
+	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for ESS AudioDrive ES18xx chips.
 
@@ -126,6 +127,7 @@
 	select SND_RAWMIDI
 	select SND_PCM
 	select SND_GUS_SYNTH
+	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for Gravis UltraSound Classic
 	  soundcards.
@@ -140,6 +142,7 @@
 	select SND_MPU401_UART
 	select SND_PCM
 	select SND_GUS_SYNTH
+	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for Gravis UltraSound Extreme
 	  soundcards.
@@ -153,6 +156,7 @@
 	select SND_RAWMIDI
 	select SND_CS4231_LIB
 	select SND_GUS_SYNTH
+	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for Gravis UltraSound MAX
 	  soundcards.
@@ -166,7 +170,7 @@
 	select SND_RAWMIDI
 	select SND_CS4231_LIB
 	select SND_GUS_SYNTH
-	select ISAPNP
+	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for AMD InterWave based
 	  soundcards (Gravis UltraSound Plug & Play, STB SoundRage32,
@@ -181,7 +185,7 @@
 	select SND_RAWMIDI
 	select SND_CS4231_LIB
 	select SND_GUS_SYNTH
-	select ISAPNP
+	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for AMD InterWave based
 	  soundcards with a TEA6330T bass and treble regulator
@@ -224,6 +228,7 @@
 	select SND_OPL3_LIB
 	select SND_MPU401_UART
 	select SND_PCM
+	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for soundcards based on Opti
 	  82C93x chips.
@@ -237,6 +242,7 @@
 	select SND_OPL3_LIB
 	select SND_RAWMIDI
 	select SND_PCM
+	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for Creative Sound Blaster 1.0/
 	  2.0/Pro (8-bit) or 100% compatible soundcards.
@@ -250,6 +256,7 @@
 	select SND_OPL3_LIB
 	select SND_MPU401_UART
 	select SND_PCM
+	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for Sound Blaster 16 soundcards
 	  (including the Plug and Play version).
@@ -263,6 +270,7 @@
 	select SND_OPL3_LIB
 	select SND_MPU401_UART
 	select SND_PCM
+	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for Sound Blaster AWE soundcards
 	  (including the Plug and Play version).
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c
index ae86036..27a9dcf 100644
--- a/sound/isa/ad1816a/ad1816a_lib.c
+++ b/sound/isa/ad1816a/ad1816a_lib.c
@@ -591,7 +591,7 @@
 
 	*rchip = NULL;
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL)
 		return -ENOMEM;
 	chip->irq = -1;
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c
index 8c39934..3ebcc48 100644
--- a/sound/isa/ad1848/ad1848.c
+++ b/sound/isa/ad1848/ad1848.c
@@ -91,35 +91,36 @@
 				     irq[dev],
 				     dma1[dev],
 				     thinkpad[dev] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT,
-				     &chip)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+				     &chip)) < 0)
+		goto _err;
 
-	if ((err = snd_ad1848_pcm(chip, 0, &pcm)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if ((err = snd_ad1848_mixer(chip)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_ad1848_pcm(chip, 0, &pcm)) < 0)
+		goto _err;
+
+	if ((err = snd_ad1848_mixer(chip)) < 0)
+		goto _err;
+
 	strcpy(card->driver, "AD1848");
 	strcpy(card->shortname, pcm->name);
 
 	sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
 		pcm->name, chip->port, irq[dev], dma1[dev]);
 
-	if (thinkpad[dev]) {
+	if (thinkpad[dev])
 		strcat(card->longname, " [Thinkpad]");
-	}
 
-	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto _err;
+
+	if ((err = snd_card_register(card)) < 0)
+		goto _err;
+
 	snd_ad1848_cards[dev] = card;
 	return 0;
+
+ _err:
+	snd_card_free(card);
+	return err;
 }
 
 static int __init alsa_card_ad1848_init(void)
diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c
index bc642dc..303861c 100644
--- a/sound/isa/ad1848/ad1848_lib.c
+++ b/sound/isa/ad1848/ad1848_lib.c
@@ -890,7 +890,7 @@
 	int err;
 
 	*rchip = NULL;
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL)
 		return -ENOMEM;
 	spin_lock_init(&chip->reg_lock);
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index 1fce8b9..5252206 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -438,33 +438,37 @@
 /*
  */
 
+#ifdef CONFIG_PNP
+#define is_isapnp_selected(dev)		isapnp[dev]
+#else
+#define is_isapnp_selected(dev)		0
+#endif
+
+#define PFX	"cmi8330: "
+
 static int __devinit snd_cmi8330_probe(int dev,
 				       struct pnp_card_link *pcard,
 				       const struct pnp_card_device_id *pid)
 {
 	snd_card_t *card;
 	struct snd_cmi8330 *acard;
-	unsigned long flags;
 	int i, err;
 
-#ifdef CONFIG_PNP
-	if (!isapnp[dev]) {
-#endif
+	if (! is_isapnp_selected(dev)) {
 		if (wssport[dev] == SNDRV_AUTO_PORT) {
-			snd_printk("specify wssport\n");
+			snd_printk(KERN_ERR PFX "specify wssport\n");
 			return -EINVAL;
 		}
 		if (sbport[dev] == SNDRV_AUTO_PORT) {
-			snd_printk("specify sbport\n");
+			snd_printk(KERN_ERR PFX "specify sbport\n");
 			return -EINVAL;
 		}
-#ifdef CONFIG_PNP
 	}
-#endif
+
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE,
 			    sizeof(struct snd_cmi8330));
 	if (card == NULL) {
-		snd_printk("could not get a new card\n");
+		snd_printk(KERN_ERR PFX "could not get a new card\n");
 		return -ENOMEM;
 	}
 	acard = (struct snd_cmi8330 *)card->private_data;
@@ -473,9 +477,8 @@
 #ifdef CONFIG_PNP
 	if (isapnp[dev]) {
 		if ((err = snd_cmi8330_pnp(dev, acard, pcard, pid)) < 0) {
-			snd_printk("PnP detection failed\n");
-			snd_card_free(card);
-			return err;
+			snd_printk(KERN_ERR PFX "PnP detection failed\n");
+			goto _err;
 		}
 		snd_card_set_dev(card, &pcard->card->dev);
 	}
@@ -487,14 +490,13 @@
 				     wssdma[dev],
 				     AD1848_HW_DETECT,
 				     &acard->wss)) < 0) {
-		snd_printk("(AD1848) device busy??\n");
-		snd_card_free(card);
-		return err;
+		snd_printk(KERN_ERR PFX "(AD1848) device busy??\n");
+		goto _err;
 	}
 	if (acard->wss->hardware != AD1848_HW_CMI8330) {
-		snd_printk("(AD1848) not found during probe\n");
-		snd_card_free(card);
-		return -ENODEV;
+		snd_printk(KERN_ERR PFX "(AD1848) not found during probe\n");
+		err = -ENODEV;
+		goto _err;
 	}
 
 	if ((err = snd_sbdsp_create(card, sbport[dev],
@@ -503,32 +505,26 @@
 				    sbdma8[dev],
 				    sbdma16[dev],
 				    SB_HW_AUTO, &acard->sb)) < 0) {
-		snd_printk("(SB16) device busy??\n");
-		snd_card_free(card);
-		return err;
+		snd_printk(KERN_ERR PFX "(SB16) device busy??\n");
+		goto _err;
 	}
 	if (acard->sb->hardware != SB_HW_16) {
-		snd_printk("(SB16) not found during probe\n");
-		snd_card_free(card);
-		return -ENODEV;
+		snd_printk(KERN_ERR PFX "(SB16) not found during probe\n");
+		goto _err;
 	}
 
-	spin_lock_irqsave(&acard->wss->reg_lock, flags);
 	snd_ad1848_out(acard->wss, AD1848_MISC_INFO, 0x40); /* switch on MODE2 */
 	for (i = CMI8330_RMUX3D; i <= CMI8330_CDINGAIN; i++)
 		snd_ad1848_out(acard->wss, i, snd_cmi8330_image[i - CMI8330_RMUX3D]);
-	spin_unlock_irqrestore(&acard->wss->reg_lock, flags);
 
 	if ((err = snd_cmi8330_mixer(card, acard)) < 0) {
-		snd_printk("failed to create mixers\n");
-		snd_card_free(card);
-		return err;
+		snd_printk(KERN_ERR PFX "failed to create mixers\n");
+		goto _err;
 	}
 
 	if ((err = snd_cmi8330_pcm(card, acard)) < 0) {
-		snd_printk("failed to create pcms\n");
-		snd_card_free(card);
-		return err;
+		snd_printk(KERN_ERR PFX "failed to create pcms\n");
+		goto _err;
 	}
 
 	strcpy(card->driver, "CMI8330/C3D");
@@ -539,16 +535,21 @@
 		wssirq[dev],
 		wssdma[dev]);
 
-	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto _err;
+
+	if ((err = snd_card_register(card)) < 0)
+		goto _err;
 
 	if (pcard)
 		pnp_set_card_drvdata(pcard, card);
 	else
 		snd_cmi8330_legacy[dev] = card;
 	return 0;
+
+ _err:
+	snd_card_free(card);
+	return err;
 }
 
 #ifdef CONFIG_PNP
@@ -594,10 +595,8 @@
 	for (dev = 0; dev < SNDRV_CARDS; dev++) {
 		if (!enable[dev])
 			continue;
-#ifdef CONFIG_PNP
-		if (isapnp[dev])
+		if (is_isapnp_selected(dev))
 			continue;
-#endif
 		if (snd_cmi8330_probe(dev, NULL, NULL) >= 0)
 			cards++;
 	}
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c
index 7640837..9be5416 100644
--- a/sound/isa/cs423x/cs4231.c
+++ b/sound/isa/cs423x/cs4231.c
@@ -76,15 +76,15 @@
 	int err;
 
 	if (port[dev] == SNDRV_AUTO_PORT) {
-		snd_printk("specify port\n");
+		snd_printk(KERN_ERR "specify port\n");
 		return -EINVAL;
 	}
 	if (irq[dev] == SNDRV_AUTO_IRQ) {
-		snd_printk("specify irq\n");
+		snd_printk(KERN_ERR "specify irq\n");
 		return -EINVAL;
 	}
 	if (dma1[dev] == SNDRV_AUTO_DMA) {
-		snd_printk("specify dma1\n");
+		snd_printk(KERN_ERR "specify dma1\n");
 		return -EINVAL;
 	}
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
@@ -96,15 +96,11 @@
 				     dma1[dev],
 				     dma2[dev],
 				     CS4231_HW_DETECT,
-				     0, &chip)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+				     0, &chip)) < 0)
+		goto _err;
 
-	if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0)
+		goto _err;
 
 	strcpy(card->driver, "CS4231");
 	strcpy(card->shortname, pcm->name);
@@ -113,14 +109,10 @@
 	if (dma2[dev] >= 0)
 		sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]);
 
-	if ((err = snd_cs4231_mixer(chip)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_cs4231_mixer(chip)) < 0)
+		goto _err;
+	if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0)
+		goto _err;
 
 	if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
 		if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
@@ -130,14 +122,20 @@
 					mpu_irq[dev],
 					mpu_irq[dev] >= 0 ? SA_INTERRUPT : 0,
 					NULL) < 0)
-			printk(KERN_ERR "cs4231: MPU401 not detected\n");
+			printk(KERN_WARNING "cs4231: MPU401 not detected\n");
 	}
-	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto _err;
+
+	if ((err = snd_card_register(card)) < 0)
+		goto _err;
 	snd_cs4231_cards[dev] = card;
 	return 0;
+
+ _err:
+	snd_card_free(card);
+	return err;
 }
 
 static int __init alsa_card_cs4231_init(void)
diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c
index 3199941..3231825 100644
--- a/sound/isa/cs423x/cs4231_lib.c
+++ b/sound/isa/cs423x/cs4231_lib.c
@@ -1480,7 +1480,7 @@
 	cs4231_t *chip;
 
 	*rchip = NULL;
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL)
 		return -ENOMEM;
 	chip->hardware = hardware;
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index 39f4eff..d28315d 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -387,6 +387,12 @@
 	}
 }
 
+#ifdef CONFIG_PNP
+#define is_isapnp_selected(dev)		isapnp[dev]
+#else
+#define is_isapnp_selected(dev)		0
+#endif
+
 static int __devinit snd_card_cs423x_probe(int dev, struct pnp_card_link *pcard,
 					   const struct pnp_card_device_id *pid)
 {
@@ -397,20 +403,16 @@
 	opl3_t *opl3;
 	int err;
 
-#ifdef CONFIG_PNP
-	if (!isapnp[dev]) {
-#endif
+	if (! is_isapnp_selected(dev)) {
 		if (port[dev] == SNDRV_AUTO_PORT) {
-			snd_printk("specify port\n");
+			snd_printk(KERN_ERR "specify port\n");
 			return -EINVAL;
 		}
 		if (cport[dev] == SNDRV_AUTO_PORT) {
-			snd_printk("specify cport\n");
+			snd_printk(KERN_ERR "specify cport\n");
 			return -EINVAL;
 		}
-#ifdef CONFIG_PNP
 	}
-#endif
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE,
 			    sizeof(struct snd_card_cs4236));
 	if (card == NULL)
@@ -421,8 +423,7 @@
 	if (isapnp[dev]) {
 		if ((err = snd_card_cs4236_pnp(dev, acard, pcard, pid))<0) {
 			printk(KERN_ERR "isapnp detection failed and probing for " IDENT " is not supported\n");
-			snd_card_free(card);
-			return -ENXIO;
+			goto _err;
 		}
 		snd_card_set_dev(card, &pcard->card->dev);
 	}
@@ -430,8 +431,8 @@
 	if (sb_port[dev] > 0 && sb_port[dev] != SNDRV_AUTO_PORT)
 		if ((acard->res_sb_port = request_region(sb_port[dev], 16, IDENT " SB")) == NULL) {
 			printk(KERN_ERR IDENT ": unable to register SB port at 0x%lx\n", sb_port[dev]);
-			snd_card_free(card);
-			return -ENOMEM;
+			err = -EBUSY;
+			goto _err;
 		}
 
 #ifdef CS4232
@@ -443,18 +444,14 @@
 				     dma2[dev],
 				     CS4231_HW_DETECT,
 				     0,
-				     &chip)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if ((err = snd_cs4231_mixer(chip)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+				     &chip)) < 0)
+		goto _err;
+
+	if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0)
+		goto _err;
+
+	if ((err = snd_cs4231_mixer(chip)) < 0)
+		goto _err;
 
 #else /* CS4236 */
 	if ((err = snd_cs4236_create(card,
@@ -465,18 +462,14 @@
 				     dma2[dev],
 				     CS4231_HW_DETECT,
 				     0,
-				     &chip)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if ((err = snd_cs4236_pcm(chip, 0, &pcm)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if ((err = snd_cs4236_mixer(chip)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+				     &chip)) < 0)
+		goto _err;
+
+	if ((err = snd_cs4236_pcm(chip, 0, &pcm)) < 0)
+		goto _err;
+
+	if ((err = snd_cs4236_mixer(chip)) < 0)
+		goto _err;
 #endif
 	strcpy(card->driver, pcm->name);
 	strcpy(card->shortname, pcm->name);
@@ -488,21 +481,17 @@
 	if (dma2[dev] >= 0)
 		sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]);
 
-	if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0)
+		goto _err;
 
 	if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
 		if (snd_opl3_create(card,
 				    fm_port[dev], fm_port[dev] + 2,
 				    OPL3_HW_OPL3_CS, 0, &opl3) < 0) {
-			printk(KERN_ERR IDENT ": OPL3 not detected\n");
+			printk(KERN_WARNING IDENT ": OPL3 not detected\n");
 		} else {
-			if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
-				snd_card_free(card);
-				return err;
-			}
+			if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
+				goto _err;
 		}
 	}
 
@@ -513,17 +502,23 @@
 					mpu_port[dev], 0,
 					mpu_irq[dev],
 					mpu_irq[dev] >= 0 ? SA_INTERRUPT : 0, NULL) < 0)
-			printk(KERN_ERR IDENT ": MPU401 not detected\n");
+			printk(KERN_WARNING IDENT ": MPU401 not detected\n");
 	}
-	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto _err;
+
+	if ((err = snd_card_register(card)) < 0)
+		goto _err;
 	if (pcard)
 		pnp_set_card_drvdata(pcard, card);
 	else
 		snd_cs4236_legacy[dev] = card;
 	return 0;
+
+ _err:
+	snd_card_free(card);
+	return err;
 }
 
 #ifdef CONFIG_PNP
@@ -569,10 +564,8 @@
 	for (dev = 0; dev < SNDRV_CARDS; dev++) {
 		if (!enable[dev])
 			continue;
-#ifdef CONFIG_PNP
-		if (isapnp[dev])
+		if (is_isapnp_selected(dev))
 			continue;
-#endif
 		if (snd_card_cs423x_probe(dev, NULL, NULL) >= 0)
 			cards++;
 	}
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index c5eaec0..26a7d33 100644
--- a/sound/isa/es1688/es1688.c
+++ b/sound/isa/es1688/es1688.c
@@ -70,6 +70,7 @@
 
 static snd_card_t *snd_audiodrive_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
 
+#define PFX	"es1688: "
 
 static int __init snd_audiodrive_probe(int dev)
 {
@@ -89,47 +90,41 @@
 	xirq = irq[dev];
 	if (xirq == SNDRV_AUTO_IRQ) {
 		if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
-			snd_card_free(card);
-			snd_printk("unable to find a free IRQ\n");
-			return -EBUSY;
+			snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
+			err = -EBUSY;
+			goto _err;
 		}
 	}
 	xmpu_irq = mpu_irq[dev];
 	xdma = dma8[dev];
 	if (xdma == SNDRV_AUTO_DMA) {
 		if ((xdma = snd_legacy_find_free_dma(possible_dmas)) < 0) {
-			snd_card_free(card);
-			snd_printk("unable to find a free DMA\n");
-			return -EBUSY;
+			snd_printk(KERN_ERR PFX "unable to find a free DMA\n");
+			err = -EBUSY;
+			goto _err;
 		}
 	}
 
 	if ((err = snd_es1688_create(card, port[dev], mpu_port[dev],
 				     xirq, xmpu_irq, xdma,
-				     ES1688_HW_AUTO, &chip)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if ((err = snd_es1688_pcm(chip, 0, &pcm)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if ((err = snd_es1688_mixer(chip)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+				     ES1688_HW_AUTO, &chip)) < 0)
+		goto _err;
+
+	if ((err = snd_es1688_pcm(chip, 0, &pcm)) < 0)
+		goto _err;
+
+	if ((err = snd_es1688_mixer(chip)) < 0)
+		goto _err;
 
 	strcpy(card->driver, "ES1688");
 	strcpy(card->shortname, pcm->name);
 	sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port, xirq, xdma);
 
 	if ((snd_opl3_create(card, chip->port, chip->port + 2, OPL3_HW_OPL3, 0, &opl3)) < 0) {
-		printk(KERN_ERR "es1688: opl3 not detected at 0x%lx\n", chip->port);
+		printk(KERN_WARNING PFX "opl3 not detected at 0x%lx\n", chip->port);
 	} else {
-		if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
-			snd_card_free(card);
-			return err;
-		}
+		if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
+			goto _err;
 	}
 
 	if (xmpu_irq >= 0 && xmpu_irq != SNDRV_AUTO_IRQ && chip->mpu_port > 0) {
@@ -137,18 +132,22 @@
 					       chip->mpu_port, 0,
 					       xmpu_irq,
 					       SA_INTERRUPT,
-					       NULL)) < 0) {
-			snd_card_free(card);
-			return err;
-		}
+					       NULL)) < 0)
+			goto _err;
 	}
-	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto _err;
+
+	if ((err = snd_card_register(card)) < 0)
+		goto _err;
+
 	snd_audiodrive_cards[dev] = card;
 	return 0;
 
+ _err:
+	snd_card_free(card);
+	return err;
 }
 
 static int __init snd_audiodrive_legacy_auto_probe(unsigned long xport)
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index 17f68d0..aac8987 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -649,7 +649,7 @@
 	int err;
 
 	*rchip = NULL;
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL)
 		return -ENOMEM;
 	chip->irq = -1;
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 1d832b2..d0ea19f 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -1686,7 +1686,7 @@
 	int err;
 
 	*rchip = NULL;
-        chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL)
 		return -ENOMEM;
 	spin_lock_init(&chip->reg_lock);
@@ -1988,6 +1988,12 @@
 }
 #endif /* CONFIG_PNP */
 
+#ifdef CONFIG_PNP
+#define is_isapnp_selected(dev)		isapnp[dev]
+#else
+#define is_isapnp_selected(dev)		0
+#endif
+
 static int __devinit snd_audiodrive_probe(int dev, struct pnp_card_link *pcard,
 					  const struct pnp_card_device_id *pid)
 {
@@ -1996,7 +2002,6 @@
 	int xirq, xdma1, xdma2;
 	snd_card_t *card;
 	struct snd_audiodrive *acard;
-	snd_rawmidi_t *rmidi = NULL;
 	es18xx_t *chip;
 	opl3_t *opl3;
 	int err;
@@ -2019,25 +2024,25 @@
 	xirq = irq[dev];
 	if (xirq == SNDRV_AUTO_IRQ) {
 		if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
-			snd_card_free(card);
-			snd_printk("unable to find a free IRQ\n");
-			return -EBUSY;
+			snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
+			err = -EBUSY;
+			goto _err;
 		}
 	}
 	xdma1 = dma1[dev];
         if (xdma1 == SNDRV_AUTO_DMA) {
                 if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
-                        snd_card_free(card);
-                        snd_printk("unable to find a free DMA1\n");
-                        return -EBUSY;
+			snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
+			err = -EBUSY;
+			goto _err;
                 }
         }
 	xdma2 = dma2[dev];
         if (xdma2 == SNDRV_AUTO_DMA) {
                 if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
-                        snd_card_free(card);
-                        snd_printk("unable to find a free DMA2\n");
-                        return -EBUSY;
+			snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
+			err = -EBUSY;
+			goto _err;
                 }
         }
 
@@ -2046,10 +2051,8 @@
 					 mpu_port[dev],
 					 fm_port[dev],
 					 xirq, xdma1, xdma2,
-					 &chip)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+					 &chip)) < 0)
+		goto _err;
 
 	sprintf(card->driver, "ES%x", chip->version);
 	sprintf(card->shortname, "ESS AudioDrive ES%x", chip->version);
@@ -2064,23 +2067,18 @@
 			chip->port,
 			xirq, xdma1);
 
-	if ((err = snd_es18xx_pcm(chip, 0, NULL)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if ((err = snd_es18xx_mixer(chip)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_es18xx_pcm(chip, 0, NULL)) < 0)
+		goto _err;
+
+	if ((err = snd_es18xx_mixer(chip)) < 0)
+		goto _err;
 
 	if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
 		if (snd_opl3_create(card, chip->fm_port, chip->fm_port + 2, OPL3_HW_OPL3, 0, &opl3) < 0) {
-			snd_printk(KERN_ERR PFX "opl3 not detected at 0x%lx\n", chip->fm_port);
+			snd_printk(KERN_WARNING PFX "opl3 not detected at 0x%lx\n", chip->fm_port);
 		} else {
-			if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
-				snd_card_free(card);
-				return err;
-			}
+			if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
+				goto _err;
 		}
 	}
 
@@ -2088,25 +2086,28 @@
 		if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX,
 					       chip->mpu_port, 0,
 					       xirq, 0,
-					       &rmidi)) < 0) {
-			snd_card_free(card);
-			return err;
-		}
-		chip->rmidi = rmidi;
+					       &chip->rmidi)) < 0)
+			goto _err;
 	}
 
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto _err;
+
 	/* Power Management */
 	snd_card_set_isa_pm_callback(card, snd_es18xx_suspend, snd_es18xx_resume, chip);
 
-	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_card_register(card)) < 0)
+		goto _err;
+
 	if (pcard)
 		pnp_set_card_drvdata(pcard, card);
 	else
 		snd_audiodrive_legacy[dev] = card;
 	return 0;
+
+ _err:
+	snd_card_free(card);
+	return err;
 }
 
 static int __devinit snd_audiodrive_probe_legacy_port(unsigned long xport)
@@ -2117,10 +2118,8 @@
 	for ( ; dev < SNDRV_CARDS; dev++) {
 		if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT)
 			continue;
-#ifdef CONFIG_PNP
-		if (isapnp[dev])
+		if (is_isapnp_selected(dev))
 			continue;
-#endif
 		port[dev] = xport;
 		res = snd_audiodrive_probe(dev, NULL, NULL);
 		if (res < 0)
@@ -2177,10 +2176,8 @@
 	for (dev = 0; dev < SNDRV_CARDS; dev++) {
 		if (!enable[dev] || port[dev] == SNDRV_AUTO_PORT)
 			continue;
-#ifdef CONFIG_PNP
-		if (isapnp[dev])
+		if (is_isapnp_selected(dev))
 			continue;
-#endif
 		if (snd_audiodrive_probe(dev, NULL, NULL) >= 0)
 			cards++;
 	}
diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c
index a636d9c..8f2872f 100644
--- a/sound/isa/gus/gus_main.c
+++ b/sound/isa/gus/gus_main.c
@@ -157,7 +157,7 @@
 	};
 
 	*rgus = NULL;
-	gus = kcalloc(1, sizeof(*gus), GFP_KERNEL);
+	gus = kzalloc(sizeof(*gus), GFP_KERNEL);
 	if (gus == NULL)
 		return -ENOMEM;
 	gus->gf1.irq = -1;
diff --git a/sound/isa/gus/gus_mem_proc.c b/sound/isa/gus/gus_mem_proc.c
index 886763f..7f96ac2 100644
--- a/sound/isa/gus/gus_mem_proc.c
+++ b/sound/isa/gus/gus_mem_proc.c
@@ -98,7 +98,7 @@
 
 	for (idx = 0; idx < 4; idx++) {
 		if (gus->gf1.mem_alloc.banks_8[idx].size > 0) {
-			priv = kcalloc(1, sizeof(*priv), GFP_KERNEL);
+			priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 			if (priv == NULL)
 				return -ENOMEM;
 			priv->gus = gus;
@@ -115,7 +115,7 @@
 	}
 	for (idx = 0; idx < 4; idx++) {
 		if (gus->gf1.rom_present & (1 << idx)) {
-			priv = kcalloc(1, sizeof(*priv), GFP_KERNEL);
+			priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 			if (priv == NULL)
 				return -ENOMEM;
 			priv->rom = 1;
diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c
index b75066a..beb0136 100644
--- a/sound/isa/gus/gus_pcm.c
+++ b/sound/isa/gus/gus_pcm.c
@@ -666,7 +666,7 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	int err;
 
-	pcmp = kcalloc(1, sizeof(*pcmp), GFP_KERNEL);
+	pcmp = kzalloc(sizeof(*pcmp), GFP_KERNEL);
 	if (pcmp == NULL)
 		return -ENOMEM;
 	pcmp->gus = gus;
diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c
index a99fa50..39cef38 100644
--- a/sound/isa/gus/gusclassic.c
+++ b/sound/isa/gus/gusclassic.c
@@ -72,40 +72,24 @@
 
 static snd_card_t *snd_gusclassic_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
 
+#define PFX	"gusclassic: "
 
 static int __init snd_gusclassic_detect(snd_gus_card_t * gus)
 {
-	snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0);	/* reset GF1 */
-#ifdef CONFIG_SND_DEBUG_DETECT
-	{
-		unsigned char d;
+	unsigned char d;
 
-		if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
-			snd_printk("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
-			return -ENODEV;
-		}
-	}
-#else
-	if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 0)
+	snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0);	/* reset GF1 */
+	if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
+		snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
 		return -ENODEV;
-#endif
+	}
 	udelay(160);
 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1);	/* release reset */
 	udelay(160);
-#ifdef CONFIG_SND_DEBUG_DETECT
-	{
-		unsigned char d;
-
-		if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
-			snd_printk("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
-			return -ENODEV;
-		}
-	}
-#else
-	if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 1)
+	if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
+		snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
 		return -ENODEV;
-#endif
-
+	}
 	return 0;
 }
 
@@ -137,25 +121,25 @@
 	xirq = irq[dev];
 	if (xirq == SNDRV_AUTO_IRQ) {
 		if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
-			snd_card_free(card);
-			snd_printk("unable to find a free IRQ\n");
-			return -EBUSY;
+			snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
+			err = -EBUSY;
+			goto _err;
 		}
 	}
 	xdma1 = dma1[dev];
 	if (xdma1 == SNDRV_AUTO_DMA) {
 		if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
-			snd_card_free(card);
-			snd_printk("unable to find a free DMA1\n");
-			return -EBUSY;
+			snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
+			err = -EBUSY;
+			goto _err;
 		}
 	}
 	xdma2 = dma2[dev];
 	if (xdma2 == SNDRV_AUTO_DMA) {
 		if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
-			snd_card_free(card);
-			snd_printk("unable to find a free DMA2\n");
-			return -EBUSY;
+			snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
+			err = -EBUSY;
+			goto _err;
 		}
 	}
 
@@ -164,47 +148,48 @@
 				  port[dev],
 				  xirq, xdma1, xdma2,
 			          0, channels[dev], pcm_channels[dev],
-			          0, &gus)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if ((err = snd_gusclassic_detect(gus)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+			          0, &gus)) < 0)
+		goto _err;
+
+	if ((err = snd_gusclassic_detect(gus)) < 0)
+		goto _err;
+
 	snd_gusclassic_init(dev, gus);
-	if ((err = snd_gus_initialize(gus)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_gus_initialize(gus)) < 0)
+		goto _err;
+
 	if (gus->max_flag || gus->ess_flag) {
-		snd_printdd("GUS Classic or ACE soundcard was not detected at 0x%lx\n", gus->gf1.port);
-		snd_card_free(card);
-		return -ENODEV;
+		snd_printk(KERN_ERR PFX "GUS Classic or ACE soundcard was not detected at 0x%lx\n", gus->gf1.port);
+		err = -ENODEV;
+		goto _err;
 	}
-	if ((err = snd_gf1_new_mixer(gus)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if ((err = snd_gf1_pcm_new(gus, 0, 0, NULL)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+
+	if ((err = snd_gf1_new_mixer(gus)) < 0)
+		goto _err;
+
+	if ((err = snd_gf1_pcm_new(gus, 0, 0, NULL)) < 0)
+		goto _err;
+
 	if (!gus->ace_flag) {
-		if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0) {
-			snd_card_free(card);
-			return err;
-		}
+		if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0)
+			goto _err;
 	}
 	sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %d, dma %d", gus->gf1.port, xirq, xdma1);
 	if (dma2 >= 0)
 		sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
-	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto _err;
+
+	if ((err = snd_card_register(card)) < 0)
+		goto _err;
+
 	snd_gusclassic_cards[dev] = card;
 	return 0;
+
+ _err:
+	snd_card_free(card);
+	return err;
 }
 
 static int __init snd_gusclassic_legacy_auto_probe(unsigned long xport)
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c
index bc6fecb..d2e7cb1 100644
--- a/sound/isa/gus/gusextreme.c
+++ b/sound/isa/gus/gusextreme.c
@@ -87,6 +87,7 @@
 
 static snd_card_t *snd_gusextreme_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
 
+#define PFX	"gusextreme: "
 
 static int __init snd_gusextreme_detect(int dev,
 					snd_card_t * card,
@@ -94,6 +95,7 @@
 					es1688_t *es1688)
 {
 	unsigned long flags;
+	unsigned char d;
 
 	/*
 	 * This is main stuff - enable access to GF1 chip...
@@ -123,36 +125,17 @@
 	udelay(100);
 
 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0);	/* reset GF1 */
-#ifdef CONFIG_SND_DEBUG_DETECT
-	{
-		unsigned char d;
-
-		if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
-			snd_printk("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
-			return -EIO;
-		}
-	}
-#else
-	if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 0)
+	if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
+		snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
 		return -EIO;
-#endif
+	}
 	udelay(160);
 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1);	/* release reset */
 	udelay(160);
-#ifdef CONFIG_SND_DEBUG_DETECT
-	{
-		unsigned char d;
-
-		if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
-			snd_printk("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
-			return -EIO;
-		}
-	}
-#else
-	if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 1)
+	if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
+		snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
 		return -EIO;
-#endif
-
+	}
 	return 0;
 }
 
@@ -205,7 +188,7 @@
 	xgf1_irq = gf1_irq[dev];
 	if (xgf1_irq == SNDRV_AUTO_IRQ) {
 		if ((xgf1_irq = snd_legacy_find_free_irq(possible_gf1_irqs)) < 0) {
-			snd_printk("unable to find a free IRQ for GF1\n");
+			snd_printk(KERN_ERR PFX "unable to find a free IRQ for GF1\n");
 			err = -EBUSY;
 			goto out;
 		}
@@ -213,7 +196,7 @@
 	xess_irq = irq[dev];
 	if (xess_irq == SNDRV_AUTO_IRQ) {
 		if ((xess_irq = snd_legacy_find_free_irq(possible_ess_irqs)) < 0) {
-			snd_printk("unable to find a free IRQ for ES1688\n");
+			snd_printk(KERN_ERR PFX "unable to find a free IRQ for ES1688\n");
 			err = -EBUSY;
 			goto out;
 		}
@@ -226,7 +209,7 @@
 	xgf1_dma = dma1[dev];
 	if (xgf1_dma == SNDRV_AUTO_DMA) {
 		if ((xgf1_dma = snd_legacy_find_free_dma(possible_gf1_dmas)) < 0) {
-			snd_printk("unable to find a free DMA for GF1\n");
+			snd_printk(KERN_ERR PFX "unable to find a free DMA for GF1\n");
 			err = -EBUSY;
 			goto out;
 		}
@@ -234,7 +217,7 @@
 	xess_dma = dma8[dev];
 	if (xess_dma == SNDRV_AUTO_DMA) {
 		if ((xess_dma = snd_legacy_find_free_dma(possible_ess_dmas)) < 0) {
-			snd_printk("unable to find a free DMA for ES1688\n");
+			snd_printk(KERN_ERR PFX "unable to find a free DMA for ES1688\n");
 			err = -EBUSY;
 			goto out;
 		}
@@ -264,7 +247,7 @@
 		goto out;
 
 	if (!gus->ess_flag) {
-		snd_printdd("GUS Extreme soundcard was not detected at 0x%lx\n", gus->gf1.port);
+		snd_printk(KERN_ERR PFX "GUS Extreme soundcard was not detected at 0x%lx\n", gus->gf1.port);
 		err = -ENODEV;
 		goto out;
 	}
@@ -287,7 +270,7 @@
 
 	if (snd_opl3_create(card, es1688->port, es1688->port + 2,
 			    OPL3_HW_OPL3, 0, &opl3) < 0) {
-		printk(KERN_ERR "gusextreme: opl3 not detected at 0x%lx\n", es1688->port);
+		printk(KERN_ERR PFX "gusextreme: opl3 not detected at 0x%lx\n", es1688->port);
 	} else {
 		if ((err = snd_opl3_hwdep_new(opl3, 0, 2, NULL)) < 0)
 			goto out;
@@ -303,6 +286,10 @@
 
 	sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, irq %i&%i, dma %i&%i",
 		es1688->port, xgf1_irq, xess_irq, xgf1_dma, xess_dma);
+
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto out;
+
 	if ((err = snd_card_register(card)) < 0)
 		goto out;
 
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c
index 400ff34..0bb44b5 100644
--- a/sound/isa/gus/gusmax.c
+++ b/sound/isa/gus/gusmax.c
@@ -82,39 +82,25 @@
 
 static snd_card_t *snd_gusmax_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
 
+#define PFX	"gusmax: "
 
 static int __init snd_gusmax_detect(snd_gus_card_t * gus)
 {
-	snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0);	/* reset GF1 */
-#ifdef CONFIG_SND_DEBUG_DETECT
-	{
-		unsigned char d;
+	unsigned char d;
 
-		if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
-			snd_printk("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
-			return -ENODEV;
-		}
-	}
-#else
-	if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 0)
+	snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0);	/* reset GF1 */
+	if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
+		snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
 		return -ENODEV;
-#endif
+	}
 	udelay(160);
 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1);	/* release reset */
 	udelay(160);
-#ifdef CONFIG_SND_DEBUG_DETECT
-	{
-		unsigned char d;
-
-		if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
-			snd_printk("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
-			return -ENODEV;
-		}
-	}
-#else
-	if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 1)
+	if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
+		snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
 		return -ENODEV;
-#endif
+	}
+
 	return 0;
 }
 
@@ -239,25 +225,25 @@
 	xirq = irq[dev];
 	if (xirq == SNDRV_AUTO_IRQ) {
 		if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
-			snd_card_free(card);
-			snd_printk("unable to find a free IRQ\n");
-			return -EBUSY;
+			snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
+			err = -EBUSY;
+			goto _err;
 		}
 	}
 	xdma1 = dma1[dev];
 	if (xdma1 == SNDRV_AUTO_DMA) {
 		if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
-			snd_card_free(card);
-			snd_printk("unable to find a free DMA1\n");
-			return -EBUSY;
+			snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
+			err = -EBUSY;
+			goto _err;
 		}
 	}
 	xdma2 = dma2[dev];
 	if (xdma2 == SNDRV_AUTO_DMA) {
 		if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
-			snd_card_free(card);
-			snd_printk("unable to find a free DMA2\n");
-			return -EBUSY;
+			snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
+			err = -EBUSY;
+			goto _err;
 		}
 	}
 
@@ -266,31 +252,28 @@
 				  -xirq, xdma1, xdma2,
 				  0, channels[dev],
 				  pcm_channels[dev],
-				  0, &gus)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if ((err = snd_gusmax_detect(gus)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+				  0, &gus)) < 0)
+		goto _err;
+
+	if ((err = snd_gusmax_detect(gus)) < 0)
+		goto _err;
+
 	maxcard->gus_status_reg = gus->gf1.reg_irqstat;
 	maxcard->pcm_status_reg = gus->gf1.port + 0x10c + 2;
 	snd_gusmax_init(dev, card, gus);
-	if ((err = snd_gus_initialize(gus)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_gus_initialize(gus)) < 0)
+		goto _err;
+
 	if (!gus->max_flag) {
-		printk(KERN_ERR "GUS MAX soundcard was not detected at 0x%lx\n", gus->gf1.port);
-		snd_card_free(card);
-		return -ENODEV;
+		snd_printk(KERN_ERR PFX "GUS MAX soundcard was not detected at 0x%lx\n", gus->gf1.port);
+		err = -ENODEV;
+		goto _err;
 	}
 
 	if (request_irq(xirq, snd_gusmax_interrupt, SA_INTERRUPT, "GUS MAX", (void *)maxcard)) {
-		snd_card_free(card);
-		printk(KERN_ERR "gusmax: unable to grab IRQ %d\n", xirq);
-		return -EBUSY;
+		snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq);
+		err = -EBUSY;
+		goto _err;
 	}
 	maxcard->irq = xirq;
 	
@@ -301,50 +284,46 @@
 				     CS4231_HWSHARE_IRQ |
 				     CS4231_HWSHARE_DMA1 |
 				     CS4231_HWSHARE_DMA2,
-				     &cs4231)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if ((err = snd_cs4231_pcm(cs4231, 0, NULL)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if ((err = snd_cs4231_mixer(cs4231)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if ((err = snd_cs4231_timer(cs4231, 2, NULL)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if (pcm_channels[dev] > 0) {
-		if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0) {
-			snd_card_free(card);
-			return err;
-		}
-	}
-	if ((err = snd_gusmax_mixer(cs4231)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+				     &cs4231)) < 0)
+		goto _err;
 
-	if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0) {
-		snd_card_free(card);
-		return err;
+	if ((err = snd_cs4231_pcm(cs4231, 0, NULL)) < 0)
+		goto _err;
+
+	if ((err = snd_cs4231_mixer(cs4231)) < 0)
+		goto _err;
+
+	if ((err = snd_cs4231_timer(cs4231, 2, NULL)) < 0)
+		goto _err;
+
+	if (pcm_channels[dev] > 0) {
+		if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0)
+			goto _err;
 	}
+	if ((err = snd_gusmax_mixer(cs4231)) < 0)
+		goto _err;
+
+	if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0)
+		goto _err;
 
 	sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %i, dma %i", gus->gf1.port, xirq, xdma1);
 	if (xdma2 >= 0)
 		sprintf(card->longname + strlen(card->longname), "&%i", xdma2);
-	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto _err;
+
+	if ((err = snd_card_register(card)) < 0)
+		goto _err;
 		
 	maxcard->gus = gus;
 	maxcard->cs4231 = cs4231;
 	snd_gusmax_cards[dev] = card;
 	return 0;
+
+ _err:
+	snd_card_free(card);
+	return err;
 }
 
 static int __init snd_gusmax_legacy_auto_probe(unsigned long xport)
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 46e867d..358cba9 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -73,6 +73,12 @@
 static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
 static int effect[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
 
+#ifdef SNDRV_STB
+#define PFX "interwave-stb: "
+#else
+#define PFX "interwave: "
+#endif
+
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for InterWave soundcard.");
 module_param_array(id, charp, NULL, 0444);
@@ -249,38 +255,20 @@
 {
 	unsigned long flags;
 	unsigned char rev1, rev2;
+	int d;
 
 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0);	/* reset GF1 */
-#ifdef CONFIG_SND_DEBUG_DETECT
-	{
-		int d;
-
-		if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
-			snd_printk("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
-			return -ENODEV;
-		}
-	}
-#else
-	if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 0)
+	if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) {
+		snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d);
 		return -ENODEV;
-#endif
+	}
 	udelay(160);
 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1);	/* release reset */
 	udelay(160);
-#ifdef CONFIG_SND_DEBUG_DETECT
-	{
-		int d;
-
-		if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
-			snd_printk("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
-			return -ENODEV;
-		}
-	}
-#else
-	if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 1)
+	if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) {
+		snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
 		return -ENODEV;
-#endif
-
+	}
 	spin_lock_irqsave(&gus->reg_lock, flags);
 	rev1 = snd_gf1_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER);
 	snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, ~rev1);
@@ -686,35 +674,33 @@
 	card->private_free = snd_interwave_free;
 #ifdef CONFIG_PNP
 	if (isapnp[dev]) {
-		if (snd_interwave_pnp(dev, iwcard, pcard, pid)) {
-			snd_card_free(card);
-			return -ENODEV;
-		}
+		if ((err = snd_interwave_pnp(dev, iwcard, pcard, pid)) < 0)
+			goto _err;
 		snd_card_set_dev(card, &pcard->card->dev);
 	}
 #endif
 	xirq = irq[dev];
 	if (xirq == SNDRV_AUTO_IRQ) {
 		if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
-			snd_card_free(card);
-			snd_printk("unable to find a free IRQ\n");
-			return -EBUSY;
+			snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
+			err = -EBUSY;
+			goto _err;
 		}
 	}
 	xdma1 = dma1[dev];
 	if (xdma1 == SNDRV_AUTO_DMA) {
 		if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
-			snd_card_free(card);
-			snd_printk("unable to find a free DMA1\n");
-			return -EBUSY;
+			snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
+			err = -EBUSY;
+			goto _err;
 		}
 	}
 	xdma2 = dma2[dev];
 	if (xdma2 == SNDRV_AUTO_DMA) {
 		if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
-			snd_card_free(card);
-			snd_printk("unable to find a free DMA2\n");
-			return -EBUSY;
+			snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
+			err = -EBUSY;
+			goto _err;
 		}
 	}
 
@@ -722,32 +708,28 @@
 				  port[dev],
 				  -xirq, xdma1, xdma2,
 				  0, 32,
-				  pcm_channels[dev], effect[dev], &gus)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+				  pcm_channels[dev], effect[dev], &gus)) < 0)
+		goto _err;
+
 	if ((err = snd_interwave_detect(iwcard, gus, dev
 #ifdef SNDRV_STB
             , &i2c_bus
 #endif
-	    )) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	    )) < 0)
+		goto _err;
+
 	iwcard->gus_status_reg = gus->gf1.reg_irqstat;
 	iwcard->pcm_status_reg = gus->gf1.port + 0x10c + 2;
 
 	snd_interwave_init(dev, gus);
 	snd_interwave_detect_memory(gus);
-	if ((err = snd_gus_initialize(gus)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_gus_initialize(gus)) < 0)
+		goto _err;
 
 	if (request_irq(xirq, snd_interwave_interrupt, SA_INTERRUPT, "InterWave", (void *)iwcard)) {
-		snd_card_free(card);
-		snd_printk("unable to grab IRQ %d\n", xirq);
-		return -EBUSY;
+		snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq);
+		err = -EBUSY;
+		goto _err;
 	}
 	iwcard->irq = xirq;
 
@@ -758,34 +740,28 @@
 				     CS4231_HWSHARE_IRQ |
 				     CS4231_HWSHARE_DMA1 |
 				     CS4231_HWSHARE_DMA2,
-				     &cs4231)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if ((err = snd_cs4231_pcm(cs4231, 0, &pcm)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+				     &cs4231)) < 0)
+		goto _err;
+
+	if ((err = snd_cs4231_pcm(cs4231, 0, &pcm)) < 0)
+		goto _err;
+
 	sprintf(pcm->name + strlen(pcm->name), " rev %c", gus->revision + 'A');
 	strcat(pcm->name, " (codec)");
-	if ((err = snd_cs4231_timer(cs4231, 2, NULL)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if ((err = snd_cs4231_mixer(cs4231)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+
+	if ((err = snd_cs4231_timer(cs4231, 2, NULL)) < 0)
+		goto _err;
+
+	if ((err = snd_cs4231_mixer(cs4231)) < 0)
+		goto _err;
+
 	if (pcm_channels[dev] > 0) {
-		if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0) {
-			snd_card_free(card);
-			return err;
-		}
+		if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0)
+			goto _err;
 	}
-	if ((err = snd_interwave_mixer(cs4231)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_interwave_mixer(cs4231)) < 0)
+		goto _err;
+
 #ifdef SNDRV_STB
 	{
 		snd_ctl_elem_id_t id1, id2;
@@ -795,28 +771,20 @@
 		strcpy(id1.name, "Master Playback Switch");
 		strcpy(id2.name, id1.name);
 		id2.index = 1;
-		if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
-			snd_card_free(card);
-			return err;
-		}
+		if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+			goto _err;
 		strcpy(id1.name, "Master Playback Volume");
 		strcpy(id2.name, id1.name);
-		if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
-			snd_card_free(card);
-			return err;
-		}
-		if ((err = snd_tea6330t_update_mixer(card, i2c_bus, 0, 1)) < 0) {
-			snd_card_free(card);
-			return err;
-		}
+		if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+			goto _err;
+		if ((err = snd_tea6330t_update_mixer(card, i2c_bus, 0, 1)) < 0)
+			goto _err;
 	}
 #endif
 
 	gus->uart_enable = midi[dev];
-	if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0)
+		goto _err;
 
 #ifndef SNDRV_STB
 	str = "AMD InterWave";
@@ -835,10 +803,11 @@
 	if (xdma2 >= 0)
 		sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
 
-	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto _err;
+
+	if ((err = snd_card_register(card)) < 0)
+		goto _err;
 	
 	iwcard->cs4231 = cs4231;
 	iwcard->gus = gus;
@@ -847,6 +816,10 @@
 	else
 		snd_interwave_legacy[dev++] = card;
 	return 0;
+
+ _err:
+	snd_card_free(card);
+	return err;
 }
 
 static int __devinit snd_interwave_probe_legacy_port(unsigned long xport)
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 75bd6ec..e2d2bab 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -143,6 +143,8 @@
 
 static snd_card_t *snd_opl3sa2_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
 
+#define PFX	"opl3sa2: "
+
 #ifdef CONFIG_PNP
 
 static struct pnp_device_id snd_opl3sa2_pnpbiosids[] = {
@@ -231,7 +233,7 @@
 	card = chip->card;
 	port = chip->port;
 	if ((chip->res_port = request_region(port, 2, "OPL3-SA control")) == NULL) {
-		snd_printk(KERN_ERR "opl3sa2: can't grab port 0x%lx\n", port);
+		snd_printk(KERN_ERR PFX "can't grab port 0x%lx\n", port);
 		return -EBUSY;
 	}
 	// snd_printk("REG 0A = 0x%x\n", snd_opl3sa2_read(chip, 0x0a));
@@ -668,6 +670,12 @@
 	return snd_opl3sa2_free(chip);
 }
 
+#ifdef CONFIG_PNP
+#define is_isapnp_selected(dev)		isapnp[dev]
+#else
+#define is_isapnp_selected(dev)		0
+#endif
+
 static int __devinit snd_opl3sa2_probe(int dev,
 				       struct pnp_dev *pdev,
 				       struct pnp_card_link *pcard,
@@ -683,34 +691,31 @@
 	};
 	int err;
 
-#ifdef CONFIG_PNP
-	if (!isapnp[dev]) {
-#endif
+	if (! is_isapnp_selected(dev)) {
 		if (port[dev] == SNDRV_AUTO_PORT) {
-			snd_printk("specify port\n");
+			snd_printk(KERN_ERR PFX "specify port\n");
 			return -EINVAL;
 		}
 		if (wss_port[dev] == SNDRV_AUTO_PORT) {
-			snd_printk("specify wss_port\n");
+			snd_printk(KERN_ERR PFX "specify wss_port\n");
 			return -EINVAL;
 		}
 		if (fm_port[dev] == SNDRV_AUTO_PORT) {
-			snd_printk("specify fm_port\n");
+			snd_printk(KERN_ERR PFX "specify fm_port\n");
 			return -EINVAL;
 		}
 		if (midi_port[dev] == SNDRV_AUTO_PORT) {
-			snd_printk("specify midi_port\n");
+			snd_printk(KERN_ERR PFX "specify midi_port\n");
 			return -EINVAL;
 		}
-#ifdef CONFIG_PNP
 	}
-#endif
+
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
 	strcpy(card->driver, "OPL3SA2");
 	strcpy(card->shortname, "Yamaha OPL3-SA2");
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL) {
 		err = -ENOMEM;
 		goto __error;
@@ -742,7 +747,7 @@
 	if ((err = snd_opl3sa2_detect(chip)) < 0)
 		goto __error;
 	if (request_irq(xirq, snd_opl3sa2_interrupt, SA_INTERRUPT, "OPL3-SA2", (void *)chip)) {
-		snd_printk(KERN_ERR "opl3sa2: can't grab IRQ %d\n", xirq);
+		snd_printk(KERN_ERR PFX "can't grab IRQ %d\n", xirq);
 		err = -ENODEV;
 		goto __error;
 	}
@@ -795,6 +800,9 @@
 	if (dma2 >= 0)
 		sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
 
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto __error;
+
 	if ((err = snd_card_register(card)) < 0)
 		goto __error;
 
@@ -852,8 +860,10 @@
         int res;
 
         for ( ; dev < SNDRV_CARDS; dev++) {
-                if (!enable[dev] || !isapnp[dev])
-                        continue;
+		if (!enable[dev])
+			continue;
+		if (is_isapnp_selected(dev))
+			continue;
                 res = snd_opl3sa2_probe(dev, NULL, card, id);
                 if (res < 0)
                         return res;
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 411a702..73573cb 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -1038,8 +1038,7 @@
 
 	chip->c_dma_size = size;
 	snd_opti93x_out_mask(chip, OPTi93X_IFACE_CONF,
-		OPTi93X_CAPTURE_ENABLE | OPTi93X_CAPTURE_PIO,
-		(unsigned char)~(OPTi93X_CAPTURE_ENABLE | OPTi93X_CAPTURE_PIO));
+		OPTi93X_CAPTURE_ENABLE | OPTi93X_CAPTURE_PIO, 0);
 
 	snd_dma_program(chip->dma2, runtime->dma_addr, size,
 		DMA_MODE_READ | DMA_AUTOINIT);
@@ -1274,7 +1273,7 @@
 	opti93x_t *codec;
 
 	*rcodec = NULL;
-	codec = kcalloc(1, sizeof(*codec), GFP_KERNEL);
+	codec = kzalloc(sizeof(*codec), GFP_KERNEL);
 	if (codec == NULL)
 		return -ENOMEM;
 	codec->irq = -1;
@@ -1895,8 +1894,8 @@
 	}
 }
 
-static int __devinit snd_card_opti9xx_probe(struct pnp_card_link *pcard,
-					    const struct pnp_card_device_id *pid)
+static int snd_card_opti9xx_probe(struct pnp_card_link *pcard,
+				  const struct pnp_card_device_id *pid)
 {
 	static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
 	static long possible_mpu_ports[] = {0x300, 0x310, 0x320, 0x330, -1};
@@ -1966,6 +1965,10 @@
 			snd_card_free(card);
 			return error;
 		}
+		if ((error = snd_card_set_generic_dev(card)) < 0) {
+			snd_card_free(card);
+			return error;
+		}
 #ifdef CONFIG_PNP
 	}
 #endif	/* CONFIG_PNP */
diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c
index 028af40..5375705 100644
--- a/sound/isa/sb/emu8000.c
+++ b/sound/isa/sb/emu8000.c
@@ -1097,7 +1097,7 @@
 	if (seq_ports <= 0)
 		return 0;
 
-	hw = kcalloc(1, sizeof(*hw), GFP_KERNEL);
+	hw = kzalloc(sizeof(*hw), GFP_KERNEL);
 	if (hw == NULL)
 		return -ENOMEM;
 	spin_lock_init(&hw->reg_lock);
diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c
index db5eb8b..0209790 100644
--- a/sound/isa/sb/emu8000_pcm.c
+++ b/sound/isa/sb/emu8000_pcm.c
@@ -233,7 +233,7 @@
 	emu8k_pcm_t *rec;
 	snd_pcm_runtime_t *runtime = subs->runtime;
 
-	rec = kcalloc(1, sizeof(*rec), GFP_KERNEL);
+	rec = kzalloc(sizeof(*rec), GFP_KERNEL);
 	if (! rec)
 		return -ENOMEM;
 
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index 60e2c53..7888783 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -351,6 +351,12 @@
 	}
 }
 
+#ifdef CONFIG_PNP
+#define is_isapnp_selected(dev)		isapnp[dev]
+#else
+#define is_isapnp_selected(dev)		0
+#endif
+
 static int __init snd_sb16_probe(int dev,
 				 struct pnp_card_link *pcard,
 				 const struct pnp_card_device_id *pid)
@@ -378,10 +384,8 @@
 	card->private_free = snd_sb16_free;
 #ifdef CONFIG_PNP
 	if (isapnp[dev]) {
-		if ((err = snd_card_sb16_pnp(dev, acard, pcard, pid))) {
-			snd_card_free(card);
-			return err;
-		}
+		if ((err = snd_card_sb16_pnp(dev, acard, pcard, pid)))
+			goto _err;
 		snd_card_set_dev(card, &pcard->card->dev);
 	}
 #endif
@@ -389,41 +393,37 @@
 	xirq = irq[dev];
 	xdma8 = dma8[dev];
 	xdma16 = dma16[dev];
-#ifdef CONFIG_PNP
-	if (!isapnp[dev]) {
-#endif
-	if (xirq == SNDRV_AUTO_IRQ) {
-		if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
-			snd_card_free(card);
-			snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
-			return -EBUSY;
+	if (! is_isapnp_selected(dev)) {
+		if (xirq == SNDRV_AUTO_IRQ) {
+			if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
+				snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
+				err = -EBUSY;
+				goto _err;
+			}
 		}
-	}
-	if (xdma8 == SNDRV_AUTO_DMA) {
-		if ((xdma8 = snd_legacy_find_free_dma(possible_dmas8)) < 0) {
-			snd_card_free(card);
-			snd_printk(KERN_ERR PFX "unable to find a free 8-bit DMA\n");
-			return -EBUSY;
+		if (xdma8 == SNDRV_AUTO_DMA) {
+			if ((xdma8 = snd_legacy_find_free_dma(possible_dmas8)) < 0) {
+				snd_printk(KERN_ERR PFX "unable to find a free 8-bit DMA\n");
+				err = -EBUSY;
+				goto _err;
+			}
 		}
-	}
-	if (xdma16 == SNDRV_AUTO_DMA) {
-		if ((xdma16 = snd_legacy_find_free_dma(possible_dmas16)) < 0) {
-			snd_card_free(card);
-			snd_printk(KERN_ERR PFX "unable to find a free 16-bit DMA\n");
-			return -EBUSY;
+		if (xdma16 == SNDRV_AUTO_DMA) {
+			if ((xdma16 = snd_legacy_find_free_dma(possible_dmas16)) < 0) {
+				snd_printk(KERN_ERR PFX "unable to find a free 16-bit DMA\n");
+				err = -EBUSY;
+				goto _err;
+			}
 		}
-	}
-	/* non-PnP FM port address is hardwired with base port address */
-	fm_port[dev] = port[dev];
-	/* block the 0x388 port to avoid PnP conflicts */
-	acard->fm_res = request_region(0x388, 4, "SoundBlaster FM");
+		/* non-PnP FM port address is hardwired with base port address */
+		fm_port[dev] = port[dev];
+		/* block the 0x388 port to avoid PnP conflicts */
+		acard->fm_res = request_region(0x388, 4, "SoundBlaster FM");
 #ifdef SNDRV_SBAWE_EMU8000
-	/* non-PnP AWE port address is hardwired with base port address */
-	awe_port[dev] = port[dev] + 0x400;
+		/* non-PnP AWE port address is hardwired with base port address */
+		awe_port[dev] = port[dev] + 0x400;
 #endif
-#ifdef CONFIG_PNP
 	}
-#endif
 
 	if ((err = snd_sbdsp_create(card,
 				    port[dev],
@@ -432,28 +432,20 @@
 				    xdma8,
 				    xdma16,
 				    SB_HW_AUTO,
-				    &chip)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+				    &chip)) < 0)
+		goto _err;
+
 	if (chip->hardware != SB_HW_16) {
-		snd_card_free(card);
-		snd_printdd("SB 16 chip was not detected at 0x%lx\n", port[dev]);
-		return -ENODEV;
+		snd_printk(KERN_ERR PFX "SB 16 chip was not detected at 0x%lx\n", port[dev]);
+		err = -ENODEV;
+		goto _err;
 	}
 	chip->mpu_port = mpu_port[dev];
-#ifdef CONFIG_PNP
-	if (!isapnp[dev] && (err = snd_sb16dsp_configure(chip)) < 0) {
-#else
-	if ((err = snd_sb16dsp_configure(chip)) < 0) {
-#endif
-		snd_card_free(card);
-		return -ENXIO;
-	}
-	if ((err = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) {
-		snd_card_free(card);
-		return -ENXIO;
-	}
+	if (! is_isapnp_selected(dev) && (err = snd_sb16dsp_configure(chip)) < 0)
+		goto _err;
+
+	if ((err = snd_sb16dsp_pcm(chip, 0, NULL)) < 0)
+		goto _err;
 
 	strcpy(card->driver,
 #ifdef SNDRV_SBAWE_EMU8000
@@ -474,10 +466,8 @@
 	if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) {
 		if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SB,
 					       chip->mpu_port, 0,
-					       xirq, 0, &chip->rmidi)) < 0) {
-			snd_card_free(card);
-			return -ENXIO;
-		}
+					       xirq, 0, &chip->rmidi)) < 0)
+			goto _err;
 		chip->rmidi_callback = snd_mpu401_uart_interrupt;
 	}
 
@@ -499,17 +489,13 @@
 #else
 			int seqdev = 1;
 #endif
-			if ((err = snd_opl3_hwdep_new(opl3, 0, seqdev, &synth)) < 0) {
-				snd_card_free(card);
-				return -ENXIO;
-			}
+			if ((err = snd_opl3_hwdep_new(opl3, 0, seqdev, &synth)) < 0)
+				goto _err;
 		}
 	}
 
-	if ((err = snd_sbmixer_new(chip)) < 0) {
-		snd_card_free(card);
-		return -ENXIO;
-	}
+	if ((err = snd_sbmixer_new(chip)) < 0)
+		goto _err;
 
 #ifdef CONFIG_SND_SB16_CSP
 	/* CSP chip on SB16ASP/AWE32 */
@@ -525,11 +511,11 @@
 #endif
 #ifdef SNDRV_SBAWE_EMU8000
 	if (awe_port[dev] > 0) {
-		if (snd_emu8000_new(card, 1, awe_port[dev],
-				    seq_ports[dev], NULL) < 0) {
+		if ((err = snd_emu8000_new(card, 1, awe_port[dev],
+					   seq_ports[dev], NULL)) < 0) {
 			snd_printk(KERN_ERR PFX "fatal error - EMU-8000 synthesizer not detected at 0x%lx\n", awe_port[dev]);
-			snd_card_free(card);
-			return -ENXIO;
+
+			goto _err;
 		}
 	}
 #endif
@@ -541,15 +527,21 @@
 		(mic_agc[dev] ? 0x00 : 0x01));
 	spin_unlock_irqrestore(&chip->mixer_lock, flags);
 
-	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto _err;
+
+	if ((err = snd_card_register(card)) < 0)
+		goto _err;
+
 	if (pcard)
 		pnp_set_card_drvdata(pcard, card);
 	else
 		snd_sb16_legacy[dev] = card;
 	return 0;
+
+ _err:
+	snd_card_free(card);
+	return err;
 }
 
 static int __init snd_sb16_probe_legacy_port(unsigned long xport)
@@ -560,10 +552,8 @@
 	for ( ; dev < SNDRV_CARDS; dev++) {
 		if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT)
 			continue;
-#ifdef CONFIG_PNP
-		if (isapnp[dev])
+		if (is_isapnp_selected(dev))
 			continue;
-#endif
 		port[dev] = xport;
 		res = snd_sb16_probe(dev, NULL, NULL);
 		if (res < 0)
@@ -621,10 +611,8 @@
 	for (dev = 0; dev < SNDRV_CARDS; dev++) {
 		if (!enable[dev] || port[dev] == SNDRV_AUTO_PORT)
 			continue;
-#ifdef CONFIG_PNP
-		if (isapnp[dev])
+		if (is_isapnp_selected(dev))
 			continue;
-#endif
 		if (!snd_sb16_probe(dev, NULL, NULL)) {
 			cards++;
 			continue;
diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c
index d64790b..7192d4c 100644
--- a/sound/isa/sb/sb16_csp.c
+++ b/sound/isa/sb/sb16_csp.c
@@ -122,7 +122,7 @@
 	if ((err = snd_hwdep_new(chip->card, "SB16-CSP", device, &hw)) < 0)
 		return err;
 
-	if ((p = kcalloc(1, sizeof(*p), GFP_KERNEL)) == NULL) {
+	if ((p = kzalloc(sizeof(*p), GFP_KERNEL)) == NULL) {
 		snd_device_free(chip->card, hw);
 		return -ENOMEM;
 	}
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index e2cbc42..c41ac25 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -107,54 +107,47 @@
 				    dma8[dev],
 				    -1,
 				    SB_HW_AUTO,
-				    &chip)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+				    &chip)) < 0)
+		goto _err;
+
 	if (chip->hardware >= SB_HW_16) {
-		snd_card_free(card);
 		if (chip->hardware == SB_HW_ALS100)
-			snd_printdd("ALS100 chip detected at 0x%lx, try snd-als100 module\n",
+			snd_printk(KERN_WARNING "ALS100 chip detected at 0x%lx, try snd-als100 module\n",
 				    port[dev]);
 		else
-			snd_printdd("SB 16 chip detected at 0x%lx, try snd-sb16 module\n",
-				    port[dev]);
-		return -ENODEV;
+			snd_printk(KERN_WARNING "SB 16 chip detected at 0x%lx, try snd-sb16 module\n",
+				   port[dev]);
+		err = -ENODEV;
+		goto _err;
 	}
 
-	if ((err = snd_sb8dsp_pcm(chip, 0, NULL)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if ((err = snd_sbmixer_new(chip)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_sb8dsp_pcm(chip, 0, NULL)) < 0)
+		goto _err;
+
+	if ((err = snd_sbmixer_new(chip)) < 0)
+		goto _err;
+
 	if (chip->hardware == SB_HW_10 || chip->hardware == SB_HW_20) {
 		if ((err = snd_opl3_create(card, chip->port + 8, 0,
 					   OPL3_HW_AUTO, 1,
 					   &opl3)) < 0) {
-			snd_printk(KERN_ERR "sb8: no OPL device at 0x%lx\n", chip->port + 8);
+			snd_printk(KERN_WARNING "sb8: no OPL device at 0x%lx\n", chip->port + 8);
 		}
 	} else {
 		if ((err = snd_opl3_create(card, chip->port, chip->port + 2,
 					   OPL3_HW_AUTO, 1,
 					   &opl3)) < 0) {
-			snd_printk(KERN_ERR "sb8: no OPL device at 0x%lx-0x%lx\n",
+			snd_printk(KERN_WARNING "sb8: no OPL device at 0x%lx-0x%lx\n",
 				   chip->port, chip->port + 2);
 		}
 	}
 	if (err >= 0) {
-		if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
-			snd_card_free(card);
-			return err;
-		}
+		if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
+			goto _err;
 	}
 
-	if ((err = snd_sb8dsp_midi(chip, 0, NULL)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_sb8dsp_midi(chip, 0, NULL)) < 0)
+		goto _err;
 
 	strcpy(card->driver, chip->hardware == SB_HW_PRO ? "SB Pro" : "SB8");
 	strcpy(card->shortname, chip->name);
@@ -162,12 +155,19 @@
 		chip->name,
 		chip->port,
 		irq[dev], dma8[dev]);
-	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto _err;
+
+	if ((err = snd_card_register(card)) < 0)
+		goto _err;
+
 	snd_sb8_cards[dev] = card;
 	return 0;
+
+ _err:
+	snd_card_free(card);
+	return err;
 }
 
 static int __init snd_card_sb8_legacy_auto_probe(unsigned long xport)
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c
index 5b6bde2..f0f205a 100644
--- a/sound/isa/sb/sb_common.c
+++ b/sound/isa/sb/sb_common.c
@@ -221,7 +221,7 @@
 
 	snd_assert(r_chip != NULL, return -EINVAL);
 	*r_chip = NULL;
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL)
 		return -ENOMEM;
 	spin_lock_init(&chip->reg_lock);
diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c
index 17f585b..52f2294 100644
--- a/sound/isa/sgalaxy.c
+++ b/sound/isa/sgalaxy.c
@@ -67,6 +67,8 @@
 
 static snd_card_t *snd_sgalaxy_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
 
+#define PFX	"sgalaxy: "
+
 /*
 
  */
@@ -135,7 +137,7 @@
 	}
 
 #if 0
-	snd_printdd("sgalaxy - setting up IRQ/DMA for WSS\n");
+	snd_printdd(PFX "setting up IRQ/DMA for WSS\n");
 #endif
 
         /* initialize IRQ for WSS codec */
@@ -160,7 +162,7 @@
 static int __init snd_sgalaxy_detect(int dev, int irq, int dma)
 {
 #if 0
-	snd_printdd("sgalaxy - switching to WSS mode\n");
+	snd_printdd(PFX "switching to WSS mode\n");
 #endif
 
 	/* switch to WSS mode */
@@ -223,11 +225,11 @@
 	ad1848_t *chip;
 
 	if (sbport[dev] == SNDRV_AUTO_PORT) {
-		snd_printk("specify SB port\n");
+		snd_printk(KERN_ERR PFX "specify SB port\n");
 		return -EINVAL;
 	}
 	if (wssport[dev] == SNDRV_AUTO_PORT) {
-		snd_printk("specify WSS port\n");
+		snd_printk(KERN_ERR PFX "specify WSS port\n");
 		return -EINVAL;
 	}
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
@@ -237,46 +239,39 @@
 	xirq = irq[dev];
 	if (xirq == SNDRV_AUTO_IRQ) {
 		if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
-			snd_card_free(card);
-			snd_printk("unable to find a free IRQ\n");
-			return -EBUSY;
+			snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
+			err = -EBUSY;
+			goto _err;
 		}
 	}
 	xdma1 = dma1[dev];
         if (xdma1 == SNDRV_AUTO_DMA) {
 		if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
-			snd_card_free(card);
-			snd_printk("unable to find a free DMA\n");
-			return -EBUSY;
+			snd_printk(KERN_ERR PFX "unable to find a free DMA\n");
+			err = -EBUSY;
+			goto _err;
 		}
 	}
 
-	if ((err = snd_sgalaxy_detect(dev, xirq, xdma1)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_sgalaxy_detect(dev, xirq, xdma1)) < 0)
+		goto _err;
 
 	if ((err = snd_ad1848_create(card, wssport[dev] + 4,
 				     xirq, xdma1,
-				     AD1848_HW_DETECT, &chip)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+				     AD1848_HW_DETECT, &chip)) < 0)
+		goto _err;
 
 	if ((err = snd_ad1848_pcm(chip, 0, NULL)) < 0) {
-		snd_printdd("sgalaxy - error creating new ad1848 PCM device\n");
-		snd_card_free(card);
-		return err;
+		snd_printdd(PFX "error creating new ad1848 PCM device\n");
+		goto _err;
 	}
 	if ((err = snd_ad1848_mixer(chip)) < 0) {
-		snd_printdd("sgalaxy - error creating new ad1848 mixer\n");
-		snd_card_free(card);
-		return err;
+		snd_printdd(PFX "error creating new ad1848 mixer\n");
+		goto _err;
 	}
-	if (snd_sgalaxy_mixer(chip) < 0) {
-		snd_printdd("sgalaxy - the mixer rewrite failed\n");
-		snd_card_free(card);
-		return err;
+	if ((err = snd_sgalaxy_mixer(chip)) < 0) {
+		snd_printdd(PFX "the mixer rewrite failed\n");
+		goto _err;
 	}
 
 	strcpy(card->driver, "Sound Galaxy");
@@ -284,12 +279,18 @@
 	sprintf(card->longname, "Sound Galaxy at 0x%lx, irq %d, dma %d",
 		wssport[dev], xirq, xdma1);
 
-	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto _err;
+
+	if ((err = snd_card_register(card)) < 0)
+		goto _err;
+
 	snd_sgalaxy_cards[dev] = card;
 	return 0;
+
+ _err:
+	snd_card_free(card);
+	return err;
 }
 
 static int __init alsa_card_sgalaxy_init(void)
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index 3959ed6..9f6b58c 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -1262,11 +1262,6 @@
 	 */
 	sscape_write(sscape, GA_INTENA_REG, 0x80);
 
-	if ((err = snd_card_register(card)) < 0) {
-		printk(KERN_ERR "sscape: Failed to register sound card\n");
-		goto _release_card;
-	}
-
 	/*
 	 * Initialize mixer
 	 */
@@ -1396,6 +1391,13 @@
 			if (ret < 0)
 				return ret;
 			snd_card_set_dev(card, &pcard->card->dev);
+
+			if ((ret = snd_card_register(card)) < 0) {
+				printk(KERN_ERR "sscape: Failed to register sound card\n");
+				snd_card_free(card);
+				return ret;
+			}
+
 			pnp_set_card_drvdata(pcard, card);
 			++sscape_cards;
 			++idx;
@@ -1460,6 +1462,16 @@
 		if (ret < 0)
 			return ret;
 
+		if ((ret = snd_card_set_generic_dev(card)) < 0) {
+			snd_card_free(card);
+			return ret;
+		}
+		if ((ret = snd_card_register(card)) < 0) {
+			printk(KERN_ERR "sscape: Failed to register sound card\n");
+			snd_card_free(card);
+			return ret;
+		}
+
 		sscape_card[sscape_cards] = card;
 		params++;
 		sscape_cards++;
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index 79b0220..0a572e0 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -622,6 +622,11 @@
 		 ics2115_port[dev],
 		 ics2115_irq[dev]);
 
+	if ((err = snd_card_set_generic_dev(card)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
 	if ((err = snd_card_register(card)) < 0) {
 		snd_card_free(card);
 		return err;
diff --git a/sound/mips/Kconfig b/sound/mips/Kconfig
index 531f8ba..2433b77 100644
--- a/sound/mips/Kconfig
+++ b/sound/mips/Kconfig
@@ -8,6 +8,7 @@
 	depends on (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) && SND
 	select SND_PCM
 	select SND_AC97_CODEC
+	select SND_GENERIC_DRIVER
 	help
 	  ALSA Sound driver for the Au1x00's AC97 port.
 
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c
index c20522b..3f9684f 100644
--- a/sound/mips/au1x00.c
+++ b/sound/mips/au1x00.c
@@ -667,6 +667,11 @@
 	strcpy(au1000->card->shortname, "Au1000-AC97");
 	sprintf(au1000->card->longname, "AMD Au1000--AC97 ALSA Driver");
 
+	if ((err = snd_card_set_generic_dev(au1000->card)) < 0) {
+		snd_card_free(au1000->card);
+		return err;
+	}
+
 	if ((err = snd_card_register(au1000->card)) < 0) {
 		snd_card_free(au1000->card);
 		return err;
diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c
index d7a8f9f..f560dd8 100644
--- a/sound/parisc/harmony.c
+++ b/sound/parisc/harmony.c
@@ -880,6 +880,8 @@
                 goto free_and_ret;
         }
 
+	snd_card_set_dev(card, &padev->dev);
+
 	*rchip = h;
 
 	return 0;
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 1e458919..a5d593c 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -316,6 +316,18 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-ymfpci.
 
+config SND_AD1889
+	tristate "Analog Devices AD1889"
+	depends on SND
+	select SND_AC97_CODEC
+	help
+	  Say Y here to include support for the integrated AC97 sound
+	  device found in particular on the Hewlett-Packard [BCJ]-xxx0
+	  class PA-RISC workstations, using the AD1819 codec.
+
+	  To compile this as a module, choose M here: the module
+	  will be called snd-ad1889.
+
 config SND_ALS4000
 	tristate "Avance Logic ALS4000"
 	depends on SND && ISA_DMA_API
diff --git a/sound/pci/Makefile b/sound/pci/Makefile
index b40575c..42fabfc 100644
--- a/sound/pci/Makefile
+++ b/sound/pci/Makefile
@@ -3,6 +3,7 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
+snd-ad1889-objs := ad1889.o
 snd-als4000-objs := als4000.o
 snd-atiixp-objs := atiixp.o
 snd-atiixp-modem-objs := atiixp_modem.o
@@ -25,6 +26,7 @@
 snd-via82xx-modem-objs := via82xx_modem.o
 
 # Toplevel Module Dependency
+obj-$(CONFIG_SND_AD1889) += snd-ad1889.o
 obj-$(CONFIG_SND_ALS4000) += snd-als4000.o
 obj-$(CONFIG_SND_ATIIXP) += snd-atiixp.o
 obj-$(CONFIG_SND_ATIIXP_MODEM) += snd-atiixp-modem.o
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 5501f44..e64cb07 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -112,6 +112,7 @@
 { 0x414c4723, 0xffffffff, "ALC650F",		NULL,	NULL }, /* already patched */
 { 0x414c4720, 0xfffffff0, "ALC650",		patch_alc650,	NULL },
 { 0x414c4760, 0xfffffff0, "ALC655",		patch_alc655,	NULL },
+{ 0x414c4781, 0xffffffff, "ALC658D",		NULL,	NULL }, /* already patched */
 { 0x414c4780, 0xfffffff0, "ALC658",		patch_alc655,	NULL },
 { 0x414c4790, 0xfffffff0, "ALC850",		patch_alc850,	NULL },
 { 0x414c4730, 0xffffffff, "ALC101",		NULL,		NULL },
@@ -1796,7 +1797,7 @@
 
 	snd_assert(card != NULL, return -EINVAL);
 	snd_assert(rbus != NULL, return -EINVAL);
-	bus = kcalloc(1, sizeof(*bus), GFP_KERNEL);
+	bus = kzalloc(sizeof(*bus), GFP_KERNEL);
 	if (bus == NULL)
 		return -ENOMEM;
 	bus->card = card;
@@ -1905,7 +1906,7 @@
 	}
 
 	card = bus->card;
-	ac97 = kcalloc(1, sizeof(*ac97), GFP_KERNEL);
+	ac97 = kzalloc(sizeof(*ac97), GFP_KERNEL);
 	if (ac97 == NULL)
 		return -ENOMEM;
 	ac97->private_data = template->private_data;
diff --git a/sound/pci/ac97/ac97_id.h b/sound/pci/ac97/ac97_id.h
index dadf387..6d73514 100644
--- a/sound/pci/ac97/ac97_id.h
+++ b/sound/pci/ac97/ac97_id.h
@@ -52,6 +52,7 @@
 #define AC97_ID_ALC650F		0x414c4723
 #define AC97_ID_ALC655		0x414c4760
 #define AC97_ID_ALC658		0x414c4780
+#define AC97_ID_ALC658D		0x414c4781
 #define AC97_ID_ALC850		0x414c4790
 #define AC97_ID_YMF753		0x594d4803
 #define AC97_ID_VT1616		0x49434551
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index b584172..045ddc7 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -2134,7 +2134,13 @@
 {
 	unsigned int val;
 
-	ac97->spec.dev_flags = (ac97->id == 0x414c4780); /* ALC658 */
+	if (ac97->id == AC97_ID_ALC658) {
+		ac97->spec.dev_flags = 1; /* ALC658 */
+		if ((snd_ac97_read(ac97, AC97_ALC650_REVISION) & 0x3f) == 2) {
+			ac97->id = AC97_ID_ALC658D;
+			ac97->spec.dev_flags = 2;
+		}
+	}
 
 	ac97->build_ops = &patch_alc655_ops;
 
@@ -2143,10 +2149,15 @@
 
 	/* adjust default values */
 	val = snd_ac97_read(ac97, 0x7a); /* misc control */
-	if (ac97->id == 0x414c4780) /* ALC658 */
+	if (ac97->spec.dev_flags) /* ALC658 */
 		val &= ~(1 << 1); /* Pin 47 is spdif input pin */
-	else /* ALC655 */
-		val |= (1 << 1); /* Pin 47 is spdif input pin */
+	else { /* ALC655 */
+		if (ac97->subsystem_vendor == 0x1462 &&
+		    ac97->subsystem_device == 0x0131) /* MSI S270 laptop */
+			val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */
+		else
+			val |= (1 << 1); /* Pin 47 is spdif input pin */
+	}
 	val &= ~(1 << 12); /* vref enable */
 	snd_ac97_write_cache(ac97, 0x7a, val);
 	/* set default: spdif-in enabled,
@@ -2159,6 +2170,11 @@
 	/* full DAC volume */
 	snd_ac97_write_cache(ac97, AC97_ALC650_SURR_DAC_VOL, 0x0808);
 	snd_ac97_write_cache(ac97, AC97_ALC650_LFE_DAC_VOL, 0x0808);
+
+	/* update undocumented bit... */
+	if (ac97->id == AC97_ID_ALC658D)
+		snd_ac97_update_bits(ac97, 0x74, 0x0800, 0x0800);
+
 	return 0;
 }
 
diff --git a/sound/pci/ac97/ak4531_codec.c b/sound/pci/ac97/ak4531_codec.c
index f9ce0fd..4032c57 100644
--- a/sound/pci/ac97/ak4531_codec.c
+++ b/sound/pci/ac97/ak4531_codec.c
@@ -357,7 +357,7 @@
 	snd_assert(rak4531 != NULL, return -EINVAL);
 	*rak4531 = NULL;
 	snd_assert(card != NULL && _ak4531 != NULL, return -EINVAL);
-	ak4531 = kcalloc(1, sizeof(*ak4531), GFP_KERNEL);
+	ak4531 = kzalloc(sizeof(*ak4531), GFP_KERNEL);
 	if (ak4531 == NULL)
 		return -ENOMEM;
 	*ak4531 = *_ak4531;
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
new file mode 100644
index 0000000..d7d99a2
--- /dev/null
+++ b/sound/pci/ad1889.c
@@ -0,0 +1,1090 @@
+/* Analog Devices 1889 audio driver
+ *
+ * This is a driver for the AD1889 PCI audio chipset found
+ * on the HP PA-RISC [BCJ]-xxx0 workstations.
+ *
+ * Copyright (C) 2004-2005, Kyle McMartin <kyle@parisc-linux.org>
+ * Copyright (C) 2005, Thibaut Varene <varenet@parisc-linux.org>
+ *   Based on the OSS AD1889 driver by Randolph Chung <tausq@debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ * TODO:
+ *	Do we need to take care of CCS register?
+ *	Maybe we could use finer grained locking (separate locks for pb/cap)?
+ * Wishlist:
+ *	Control Interface (mixer) support
+ *	Better AC97 support (VSR...)?
+ *	PM support
+ *	MIDI support
+ *	Game Port support
+ *	SG DMA support (this will need *alot* of work)
+ */
+
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/compiler.h>
+#include <linux/delay.h>
+
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/initval.h>
+#include <sound/ac97_codec.h>
+
+#include <asm/io.h>
+
+#include "ad1889.h"
+#include "ac97/ac97_id.h"
+
+#define	AD1889_DRVVER	"$Revision: 1.3 $"
+
+MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>, Thibaut Varene <t-bone@parisc-linux.org>");
+MODULE_DESCRIPTION("Analog Devices AD1889 ALSA sound driver");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("{{Analog Devices,AD1889}}");
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for the AD1889 soundcard.");
+
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+module_param_array(id, charp, NULL, 0444);
+MODULE_PARM_DESC(id, "ID string for the AD1889 soundcard.");
+
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, "Enable AD1889 soundcard.");
+
+static char *ac97_quirk[SNDRV_CARDS];
+module_param_array(ac97_quirk, charp, NULL, 0444);
+MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
+
+#define DEVNAME "ad1889"
+#define PFX	DEVNAME ": "
+
+/* let's use the global sound debug interfaces */
+#define ad1889_debug(fmt, arg...) snd_printd(KERN_DEBUG fmt, ## arg)
+
+/* keep track of some hw registers */
+struct ad1889_register_state {
+	u16 reg;	/* reg setup */
+	u32 addr;	/* dma base address */
+	unsigned long size;	/* DMA buffer size */
+};
+
+struct snd_ad1889 {
+	snd_card_t *card;
+	struct pci_dev *pci;
+
+	int irq;
+	unsigned long bar;
+	void __iomem *iobase;
+
+	ac97_t *ac97;
+	ac97_bus_t *ac97_bus;
+	snd_pcm_t *pcm;
+	snd_info_entry_t *proc;
+
+	snd_pcm_substream_t *psubs;
+	snd_pcm_substream_t *csubs;
+
+	/* playback register state */
+	struct ad1889_register_state wave;
+	struct ad1889_register_state ramc;
+
+	spinlock_t lock;
+};
+
+static inline u16
+ad1889_readw(struct snd_ad1889 *chip, unsigned reg)
+{
+	return readw(chip->iobase + reg);
+}
+
+static inline void
+ad1889_writew(struct snd_ad1889 *chip, unsigned reg, u16 val)
+{
+	writew(val, chip->iobase + reg);
+}
+
+static inline u32
+ad1889_readl(struct snd_ad1889 *chip, unsigned reg)
+{
+	return readl(chip->iobase + reg);
+}
+
+static inline void
+ad1889_writel(struct snd_ad1889 *chip, unsigned reg, u32 val)
+{
+	writel(val, chip->iobase + reg);
+}
+
+static inline void
+ad1889_unmute(struct snd_ad1889 *chip)
+{
+	u16 st;
+	st = ad1889_readw(chip, AD_DS_WADA) & 
+		~(AD_DS_WADA_RWAM | AD_DS_WADA_LWAM);
+	ad1889_writew(chip, AD_DS_WADA, st);
+	ad1889_readw(chip, AD_DS_WADA);
+}
+
+static inline void
+ad1889_mute(struct snd_ad1889 *chip)
+{
+	u16 st;
+	st = ad1889_readw(chip, AD_DS_WADA) | AD_DS_WADA_RWAM | AD_DS_WADA_LWAM;
+	ad1889_writew(chip, AD_DS_WADA, st);
+	ad1889_readw(chip, AD_DS_WADA);
+}
+
+static inline void
+ad1889_load_adc_buffer_address(struct snd_ad1889 *chip, u32 address)
+{
+	ad1889_writel(chip, AD_DMA_ADCBA, address);
+	ad1889_writel(chip, AD_DMA_ADCCA, address);
+}
+
+static inline void
+ad1889_load_adc_buffer_count(struct snd_ad1889 *chip, u32 count)
+{
+	ad1889_writel(chip, AD_DMA_ADCBC, count);
+	ad1889_writel(chip, AD_DMA_ADCCC, count);
+}
+
+static inline void
+ad1889_load_adc_interrupt_count(struct snd_ad1889 *chip, u32 count)
+{
+	ad1889_writel(chip, AD_DMA_ADCIB, count);
+	ad1889_writel(chip, AD_DMA_ADCIC, count);
+}
+
+static inline void
+ad1889_load_wave_buffer_address(struct snd_ad1889 *chip, u32 address)
+{
+	ad1889_writel(chip, AD_DMA_WAVBA, address);
+	ad1889_writel(chip, AD_DMA_WAVCA, address);
+}
+
+static inline void
+ad1889_load_wave_buffer_count(struct snd_ad1889 *chip, u32 count)
+{
+	ad1889_writel(chip, AD_DMA_WAVBC, count);
+	ad1889_writel(chip, AD_DMA_WAVCC, count);
+}
+
+static inline void
+ad1889_load_wave_interrupt_count(struct snd_ad1889 *chip, u32 count)
+{
+	ad1889_writel(chip, AD_DMA_WAVIB, count);
+	ad1889_writel(chip, AD_DMA_WAVIC, count);
+}
+
+static void
+ad1889_channel_reset(struct snd_ad1889 *chip, unsigned int channel)
+{
+	u16 reg;
+	
+	if (channel & AD_CHAN_WAV) {
+		/* Disable wave channel */
+		reg = ad1889_readw(chip, AD_DS_WSMC) & ~AD_DS_WSMC_WAEN;
+		ad1889_writew(chip, AD_DS_WSMC, reg);
+		chip->wave.reg = reg;
+		
+		/* disable IRQs */
+		reg = ad1889_readw(chip, AD_DMA_WAV);
+		reg &= AD_DMA_IM_DIS;
+		reg &= ~AD_DMA_LOOP;
+		ad1889_writew(chip, AD_DMA_WAV, reg);
+
+		/* clear IRQ and address counters and pointers */
+		ad1889_load_wave_buffer_address(chip, 0x0);
+		ad1889_load_wave_buffer_count(chip, 0x0);
+		ad1889_load_wave_interrupt_count(chip, 0x0);
+
+		/* flush */
+		ad1889_readw(chip, AD_DMA_WAV);
+	}
+	
+	if (channel & AD_CHAN_ADC) {
+		/* Disable ADC channel */
+		reg = ad1889_readw(chip, AD_DS_RAMC) & ~AD_DS_RAMC_ADEN;
+		ad1889_writew(chip, AD_DS_RAMC, reg);
+		chip->ramc.reg = reg;
+
+		reg = ad1889_readw(chip, AD_DMA_ADC);
+		reg &= AD_DMA_IM_DIS;
+		reg &= ~AD_DMA_LOOP;
+		ad1889_writew(chip, AD_DMA_ADC, reg);
+	
+		ad1889_load_adc_buffer_address(chip, 0x0);
+		ad1889_load_adc_buffer_count(chip, 0x0);
+		ad1889_load_adc_interrupt_count(chip, 0x0);
+
+		/* flush */
+		ad1889_readw(chip, AD_DMA_ADC);
+	}
+}
+
+static inline u16
+snd_ad1889_ac97_read(ac97_t *ac97, unsigned short reg)
+{
+	struct snd_ad1889 *chip = ac97->private_data;
+	return ad1889_readw(chip, AD_AC97_BASE + reg);
+}
+
+static inline void
+snd_ad1889_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
+{
+	struct snd_ad1889 *chip = ac97->private_data;
+	ad1889_writew(chip, AD_AC97_BASE + reg, val);
+}
+
+static int
+snd_ad1889_ac97_ready(struct snd_ad1889 *chip)
+{
+	int retry = 400; /* average needs 352 msec */
+	
+	while (!(ad1889_readw(chip, AD_AC97_ACIC) & AD_AC97_ACIC_ACRDY) 
+			&& --retry)
+		mdelay(1);
+	if (!retry) {
+		snd_printk(KERN_ERR PFX "[%s] Link is not ready.\n",
+		       __FUNCTION__);
+		return -EIO;
+	}
+	ad1889_debug("[%s] ready after %d ms\n", __FUNCTION__, 400 - retry);
+
+	return 0;
+}
+
+static int 
+snd_ad1889_hw_params(snd_pcm_substream_t *substream,
+			snd_pcm_hw_params_t *hw_params)
+{
+	return snd_pcm_lib_malloc_pages(substream, 
+					params_buffer_bytes(hw_params));
+}
+
+static int
+snd_ad1889_hw_free(snd_pcm_substream_t *substream)
+{
+	return snd_pcm_lib_free_pages(substream);
+}
+
+static snd_pcm_hardware_t snd_ad1889_playback_hw = {
+	.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER,
+	.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	.rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
+	.rate_min = 8000,	/* docs say 7000, but we're lazy */
+	.rate_max = 48000,
+	.channels_min = 1,
+	.channels_max = 2,
+	.buffer_bytes_max = BUFFER_BYTES_MAX,
+	.period_bytes_min = PERIOD_BYTES_MIN,
+	.period_bytes_max = PERIOD_BYTES_MAX,
+	.periods_min = PERIODS_MIN,
+	.periods_max = PERIODS_MAX,
+	/*.fifo_size = 0,*/
+};
+
+static snd_pcm_hardware_t snd_ad1889_capture_hw = {
+	.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER,
+	.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	.rates = SNDRV_PCM_RATE_48000,
+	.rate_min = 48000,	/* docs say we could to VSR, but we're lazy */
+	.rate_max = 48000,
+	.channels_min = 1,
+	.channels_max = 2,
+	.buffer_bytes_max = BUFFER_BYTES_MAX,
+	.period_bytes_min = PERIOD_BYTES_MIN,
+	.period_bytes_max = PERIOD_BYTES_MAX,
+	.periods_min = PERIODS_MIN,
+	.periods_max = PERIODS_MAX,
+	/*.fifo_size = 0,*/
+};
+
+static int
+snd_ad1889_playback_open(snd_pcm_substream_t *ss)
+{
+	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
+	snd_pcm_runtime_t *rt = ss->runtime;
+
+	chip->psubs = ss;
+	rt->hw = snd_ad1889_playback_hw;
+
+	return 0;
+}
+
+static int
+snd_ad1889_capture_open(snd_pcm_substream_t *ss)
+{
+	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
+	snd_pcm_runtime_t *rt = ss->runtime;
+
+	chip->csubs = ss;
+	rt->hw = snd_ad1889_capture_hw;
+
+	return 0;
+}
+
+static int
+snd_ad1889_playback_close(snd_pcm_substream_t *ss)
+{
+	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
+	chip->psubs = NULL;
+	return 0;
+}
+
+static int
+snd_ad1889_capture_close(snd_pcm_substream_t *ss)
+{
+	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
+	chip->csubs = NULL;
+	return 0;
+}
+
+static int
+snd_ad1889_playback_prepare(snd_pcm_substream_t *ss)
+{
+	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
+	snd_pcm_runtime_t *rt = ss->runtime;
+	unsigned int size = snd_pcm_lib_buffer_bytes(ss);
+	unsigned int count = snd_pcm_lib_period_bytes(ss);
+	u16 reg;
+
+	ad1889_channel_reset(chip, AD_CHAN_WAV);
+
+	reg = ad1889_readw(chip, AD_DS_WSMC);
+	
+	/* Mask out 16-bit / Stereo */
+	reg &= ~(AD_DS_WSMC_WA16 | AD_DS_WSMC_WAST);
+
+	if (snd_pcm_format_width(rt->format) == 16)
+		reg |= AD_DS_WSMC_WA16;
+
+	if (rt->channels > 1)
+		reg |= AD_DS_WSMC_WAST;
+
+	/* let's make sure we don't clobber ourselves */
+	spin_lock_irq(&chip->lock);
+	
+	chip->wave.size = size;
+	chip->wave.reg = reg;
+	chip->wave.addr = rt->dma_addr;
+
+	ad1889_writew(chip, AD_DS_WSMC, chip->wave.reg);
+	
+	/* Set sample rates on the codec */
+	ad1889_writew(chip, AD_DS_WAS, rt->rate);
+
+	/* Set up DMA */
+	ad1889_load_wave_buffer_address(chip, chip->wave.addr);
+	ad1889_load_wave_buffer_count(chip, size);
+	ad1889_load_wave_interrupt_count(chip, count);
+
+	/* writes flush */
+	ad1889_readw(chip, AD_DS_WSMC);
+	
+	spin_unlock_irq(&chip->lock);
+	
+	ad1889_debug("prepare playback: addr = 0x%x, count = %u, "
+			"size = %u, reg = 0x%x, rate = %u\n", chip->wave.addr,
+			count, size, reg, rt->rate);
+	return 0;
+}
+
+static int
+snd_ad1889_capture_prepare(snd_pcm_substream_t *ss)
+{
+	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
+	snd_pcm_runtime_t *rt = ss->runtime;
+	unsigned int size = snd_pcm_lib_buffer_bytes(ss);
+	unsigned int count = snd_pcm_lib_period_bytes(ss);
+	u16 reg;
+
+	ad1889_channel_reset(chip, AD_CHAN_ADC);
+	
+	reg = ad1889_readw(chip, AD_DS_RAMC);
+
+	/* Mask out 16-bit / Stereo */
+	reg &= ~(AD_DS_RAMC_AD16 | AD_DS_RAMC_ADST);
+
+	if (snd_pcm_format_width(rt->format) == 16)
+		reg |= AD_DS_RAMC_AD16;
+
+	if (rt->channels > 1)
+		reg |= AD_DS_RAMC_ADST;
+
+	/* let's make sure we don't clobber ourselves */
+	spin_lock_irq(&chip->lock);
+	
+	chip->ramc.size = size;
+	chip->ramc.reg = reg;
+	chip->ramc.addr = rt->dma_addr;
+
+	ad1889_writew(chip, AD_DS_RAMC, chip->ramc.reg);
+
+	/* Set up DMA */
+	ad1889_load_adc_buffer_address(chip, chip->ramc.addr);
+	ad1889_load_adc_buffer_count(chip, size);
+	ad1889_load_adc_interrupt_count(chip, count);
+
+	/* writes flush */
+	ad1889_readw(chip, AD_DS_RAMC);
+	
+	spin_unlock_irq(&chip->lock);
+	
+	ad1889_debug("prepare capture: addr = 0x%x, count = %u, "
+			"size = %u, reg = 0x%x, rate = %u\n", chip->ramc.addr,
+			count, size, reg, rt->rate);
+	return 0;
+}
+
+/* this is called in atomic context with IRQ disabled.
+   Must be as fast as possible and not sleep.
+   DMA should be *triggered* by this call.
+   The WSMC "WAEN" bit triggers DMA Wave On/Off */
+static int
+snd_ad1889_playback_trigger(snd_pcm_substream_t *ss, int cmd)
+{
+	u16 wsmc;
+	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
+	
+	wsmc = ad1889_readw(chip, AD_DS_WSMC);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		/* enable DMA loop & interrupts */
+		ad1889_writew(chip, AD_DMA_WAV, AD_DMA_LOOP | AD_DMA_IM_CNT);
+		wsmc |= AD_DS_WSMC_WAEN;
+		/* 1 to clear CHSS bit */
+		ad1889_writel(chip, AD_DMA_CHSS, AD_DMA_CHSS_WAVS);
+		ad1889_unmute(chip);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		ad1889_mute(chip);
+		wsmc &= ~AD_DS_WSMC_WAEN;
+		break;
+	default:
+		snd_BUG();
+		return -EINVAL;
+	}
+	
+	chip->wave.reg = wsmc;
+	ad1889_writew(chip, AD_DS_WSMC, wsmc);	
+	ad1889_readw(chip, AD_DS_WSMC);	/* flush */
+
+	/* reset the chip when STOP - will disable IRQs */
+	if (cmd == SNDRV_PCM_TRIGGER_STOP)
+		ad1889_channel_reset(chip, AD_CHAN_WAV);
+
+	return 0;
+}
+
+/* this is called in atomic context with IRQ disabled.
+   Must be as fast as possible and not sleep.
+   DMA should be *triggered* by this call.
+   The RAMC "ADEN" bit triggers DMA ADC On/Off */
+static int
+snd_ad1889_capture_trigger(snd_pcm_substream_t *ss, int cmd)
+{
+	u16 ramc;
+	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
+
+	ramc = ad1889_readw(chip, AD_DS_RAMC);
+	
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		/* enable DMA loop & interrupts */
+		ad1889_writew(chip, AD_DMA_ADC, AD_DMA_LOOP | AD_DMA_IM_CNT);
+		ramc |= AD_DS_RAMC_ADEN;
+		/* 1 to clear CHSS bit */
+		ad1889_writel(chip, AD_DMA_CHSS, AD_DMA_CHSS_ADCS);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		ramc &= ~AD_DS_RAMC_ADEN;
+		break;
+	default:
+		return -EINVAL;
+	}
+	
+	chip->ramc.reg = ramc;
+	ad1889_writew(chip, AD_DS_RAMC, ramc);	
+	ad1889_readw(chip, AD_DS_RAMC);	/* flush */
+	
+	/* reset the chip when STOP - will disable IRQs */
+	if (cmd == SNDRV_PCM_TRIGGER_STOP)
+		ad1889_channel_reset(chip, AD_CHAN_ADC);
+		
+	return 0;
+}
+
+/* Called in atomic context with IRQ disabled */
+static snd_pcm_uframes_t
+snd_ad1889_playback_pointer(snd_pcm_substream_t *ss)
+{
+	size_t ptr = 0;
+	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
+
+	if (unlikely(!(chip->wave.reg & AD_DS_WSMC_WAEN)))
+		return 0;
+
+	ptr = ad1889_readl(chip, AD_DMA_WAVCA);
+	ptr -= chip->wave.addr;
+	
+	snd_assert((ptr >= 0) && (ptr < chip->wave.size), return 0);
+	
+	return bytes_to_frames(ss->runtime, ptr);
+}
+
+/* Called in atomic context with IRQ disabled */
+static snd_pcm_uframes_t
+snd_ad1889_capture_pointer(snd_pcm_substream_t *ss)
+{
+	size_t ptr = 0;
+	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
+
+	if (unlikely(!(chip->ramc.reg & AD_DS_RAMC_ADEN)))
+		return 0;
+
+	ptr = ad1889_readl(chip, AD_DMA_ADCCA);
+	ptr -= chip->ramc.addr;
+
+	snd_assert((ptr >= 0) && (ptr < chip->ramc.size), return 0);
+	
+	return bytes_to_frames(ss->runtime, ptr);
+}
+
+static snd_pcm_ops_t snd_ad1889_playback_ops = {
+	.open = snd_ad1889_playback_open,
+	.close = snd_ad1889_playback_close,
+	.ioctl = snd_pcm_lib_ioctl,
+	.hw_params = snd_ad1889_hw_params,
+	.hw_free = snd_ad1889_hw_free,
+	.prepare = snd_ad1889_playback_prepare,
+	.trigger = snd_ad1889_playback_trigger,
+	.pointer = snd_ad1889_playback_pointer, 
+};
+
+static snd_pcm_ops_t snd_ad1889_capture_ops = {
+	.open = snd_ad1889_capture_open,
+	.close = snd_ad1889_capture_close,
+	.ioctl = snd_pcm_lib_ioctl,
+	.hw_params = snd_ad1889_hw_params,
+	.hw_free = snd_ad1889_hw_free,
+	.prepare = snd_ad1889_capture_prepare,
+	.trigger = snd_ad1889_capture_trigger,
+	.pointer = snd_ad1889_capture_pointer, 
+};
+
+static irqreturn_t
+snd_ad1889_interrupt(int irq, 
+		     void *dev_id, 
+		     struct pt_regs *regs)
+{
+	unsigned long st;
+	struct snd_ad1889 *chip = dev_id;
+
+	st = ad1889_readl(chip, AD_DMA_DISR);
+
+	/* clear ISR */
+	ad1889_writel(chip, AD_DMA_DISR, st);
+
+	st &= AD_INTR_MASK;
+
+	if (unlikely(!st))
+		return IRQ_NONE;
+
+	if (st & (AD_DMA_DISR_PMAI|AD_DMA_DISR_PTAI))
+		ad1889_debug("Unexpected master or target abort interrupt!\n");
+
+	if ((st & AD_DMA_DISR_WAVI) && chip->psubs)
+		snd_pcm_period_elapsed(chip->psubs);
+	if ((st & AD_DMA_DISR_ADCI) && chip->csubs)
+		snd_pcm_period_elapsed(chip->csubs);
+
+	return IRQ_HANDLED;
+}
+
+static void 
+snd_ad1889_pcm_free(snd_pcm_t *pcm)
+{
+	struct snd_ad1889 *chip = pcm->private_data;
+	chip->pcm = NULL;
+	snd_pcm_lib_preallocate_free_for_all(pcm);
+}
+
+static int __devinit
+snd_ad1889_pcm_init(struct snd_ad1889 *chip, int device, snd_pcm_t **rpcm)
+{
+	int err;
+	snd_pcm_t *pcm;
+
+	if (rpcm)
+		*rpcm = NULL;
+
+	err = snd_pcm_new(chip->card, chip->card->driver, device, 1, 1, &pcm);
+	if (err < 0)
+		return err;
+
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, 
+			&snd_ad1889_playback_ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+			&snd_ad1889_capture_ops);
+
+	pcm->private_data = chip;
+	pcm->private_free = snd_ad1889_pcm_free;
+	pcm->info_flags = 0;
+	strcpy(pcm->name, chip->card->shortname);
+	
+	chip->pcm = pcm;
+	chip->psubs = NULL;
+	chip->csubs = NULL;
+
+	err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+						snd_dma_pci_data(chip->pci),
+						BUFFER_BYTES_MAX / 2,
+						BUFFER_BYTES_MAX);
+
+	if (err < 0) {
+		snd_printk(KERN_ERR PFX "buffer allocation error: %d\n", err);
+		return err;
+	}
+	
+	if (rpcm)
+		*rpcm = pcm;
+	
+	return 0;
+}
+
+static void
+snd_ad1889_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+{
+	struct snd_ad1889 *chip = entry->private_data;
+	u16 reg;
+	int tmp;
+
+	reg = ad1889_readw(chip, AD_DS_WSMC);
+	snd_iprintf(buffer, "Wave output: %s\n",
+			(reg & AD_DS_WSMC_WAEN) ? "enabled" : "disabled");
+	snd_iprintf(buffer, "Wave Channels: %s\n",
+			(reg & AD_DS_WSMC_WAST) ? "stereo" : "mono");
+	snd_iprintf(buffer, "Wave Quality: %d-bit linear\n",
+			(reg & AD_DS_WSMC_WA16) ? 16 : 8);
+	
+	/* WARQ is at offset 12 */
+	tmp = (reg & AD_DS_WSMC_WARQ) ?
+			(((reg & AD_DS_WSMC_WARQ >> 12) & 0x01) ? 12 : 18) : 4;
+	tmp /= (reg & AD_DS_WSMC_WAST) ? 2 : 1;
+	
+	snd_iprintf(buffer, "Wave FIFO: %d %s words\n\n", tmp,
+			(reg & AD_DS_WSMC_WAST) ? "stereo" : "mono");
+				
+	
+	snd_iprintf(buffer, "Synthesis output: %s\n",
+			reg & AD_DS_WSMC_SYEN ? "enabled" : "disabled");
+	
+	/* SYRQ is at offset 4 */
+	tmp = (reg & AD_DS_WSMC_SYRQ) ?
+			(((reg & AD_DS_WSMC_SYRQ >> 4) & 0x01) ? 12 : 18) : 4;
+	tmp /= (reg & AD_DS_WSMC_WAST) ? 2 : 1;
+	
+	snd_iprintf(buffer, "Synthesis FIFO: %d %s words\n\n", tmp,
+			(reg & AD_DS_WSMC_WAST) ? "stereo" : "mono");
+
+	reg = ad1889_readw(chip, AD_DS_RAMC);
+	snd_iprintf(buffer, "ADC input: %s\n",
+			(reg & AD_DS_RAMC_ADEN) ? "enabled" : "disabled");
+	snd_iprintf(buffer, "ADC Channels: %s\n",
+			(reg & AD_DS_RAMC_ADST) ? "stereo" : "mono");
+	snd_iprintf(buffer, "ADC Quality: %d-bit linear\n",
+			(reg & AD_DS_RAMC_AD16) ? 16 : 8);
+	
+	/* ACRQ is at offset 4 */
+	tmp = (reg & AD_DS_RAMC_ACRQ) ?
+			(((reg & AD_DS_RAMC_ACRQ >> 4) & 0x01) ? 12 : 18) : 4;
+	tmp /= (reg & AD_DS_RAMC_ADST) ? 2 : 1;
+	
+	snd_iprintf(buffer, "ADC FIFO: %d %s words\n\n", tmp,
+			(reg & AD_DS_RAMC_ADST) ? "stereo" : "mono");
+	
+	snd_iprintf(buffer, "Resampler input: %s\n",
+			reg & AD_DS_RAMC_REEN ? "enabled" : "disabled");
+			
+	/* RERQ is at offset 12 */
+	tmp = (reg & AD_DS_RAMC_RERQ) ?
+			(((reg & AD_DS_RAMC_RERQ >> 12) & 0x01) ? 12 : 18) : 4;
+	tmp /= (reg & AD_DS_RAMC_ADST) ? 2 : 1;
+	
+	snd_iprintf(buffer, "Resampler FIFO: %d %s words\n\n", tmp,
+			(reg & AD_DS_WSMC_WAST) ? "stereo" : "mono");
+				
+	
+	/* doc says LSB represents -1.5dB, but the max value (-94.5dB)
+	suggests that LSB is -3dB, which is more coherent with the logarithmic
+	nature of the dB scale */
+	reg = ad1889_readw(chip, AD_DS_WADA);
+	snd_iprintf(buffer, "Left: %s, -%d dB\n",
+			(reg & AD_DS_WADA_LWAM) ? "mute" : "unmute",
+			((reg & AD_DS_WADA_LWAA) >> 8) * 3);
+	reg = ad1889_readw(chip, AD_DS_WADA);
+	snd_iprintf(buffer, "Right: %s, -%d dB\n",
+			(reg & AD_DS_WADA_RWAM) ? "mute" : "unmute",
+			((reg & AD_DS_WADA_RWAA) >> 8) * 3);
+	
+	reg = ad1889_readw(chip, AD_DS_WAS);
+	snd_iprintf(buffer, "Wave samplerate: %u Hz\n", reg);
+	reg = ad1889_readw(chip, AD_DS_RES);
+	snd_iprintf(buffer, "Resampler samplerate: %u Hz\n", reg);
+}
+
+static void __devinit
+snd_ad1889_proc_init(struct snd_ad1889 *chip)
+{
+	snd_info_entry_t *entry;
+
+	if (!snd_card_proc_new(chip->card, chip->card->driver, &entry))
+		snd_info_set_text_ops(entry, chip, 1024, snd_ad1889_proc_read);
+}
+
+static struct ac97_quirk ac97_quirks[] = {
+	{
+		.subvendor = 0x11d4,	/* AD */
+		.subdevice = 0x1889,	/* AD1889 */
+		.codec_id = AC97_ID_AD1819,
+		.name = "AD1889",
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{ } /* terminator */
+};
+
+static void __devinit
+snd_ad1889_ac97_xinit(struct snd_ad1889 *chip)
+{
+	u16 reg;
+
+	reg = ad1889_readw(chip, AD_AC97_ACIC);
+	reg |= AD_AC97_ACIC_ACRD;		/* Reset Disable */
+	ad1889_writew(chip, AD_AC97_ACIC, reg);
+	ad1889_readw(chip, AD_AC97_ACIC);	/* flush posted write */
+	udelay(10);
+	/* Interface Enable */
+	reg |= AD_AC97_ACIC_ACIE;
+	ad1889_writew(chip, AD_AC97_ACIC, reg);
+	
+	snd_ad1889_ac97_ready(chip);
+
+	/* Audio Stream Output | Variable Sample Rate Mode */
+	reg = ad1889_readw(chip, AD_AC97_ACIC);
+	reg |= AD_AC97_ACIC_ASOE | AD_AC97_ACIC_VSRM;
+	ad1889_writew(chip, AD_AC97_ACIC, reg);
+	ad1889_readw(chip, AD_AC97_ACIC); /* flush posted write */
+
+}
+
+static void
+snd_ad1889_ac97_bus_free(ac97_bus_t *bus)
+{
+	struct snd_ad1889 *chip = bus->private_data;
+	chip->ac97_bus = NULL;
+}
+
+static void
+snd_ad1889_ac97_free(ac97_t *ac97)
+{
+	struct snd_ad1889 *chip = ac97->private_data;
+	chip->ac97 = NULL;
+}
+
+static int __devinit
+snd_ad1889_ac97_init(struct snd_ad1889 *chip, const char *quirk_override)
+{
+	int err;
+	ac97_template_t ac97;
+	static ac97_bus_ops_t ops = {
+		.write = snd_ad1889_ac97_write,
+		.read = snd_ad1889_ac97_read,
+	};
+
+	/* doing that here, it works. */
+	snd_ad1889_ac97_xinit(chip);
+
+	err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus);
+	if (err < 0)
+		return err;
+	
+	chip->ac97_bus->private_free = snd_ad1889_ac97_bus_free;
+
+	memset(&ac97, 0, sizeof(ac97));
+	ac97.private_data = chip;
+	ac97.private_free = snd_ad1889_ac97_free;
+	ac97.pci = chip->pci;
+
+	err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97);
+	if (err < 0)
+		return err;
+		
+	snd_ac97_tune_hardware(chip->ac97, ac97_quirks, quirk_override);
+	
+	return 0;
+}
+
+static int
+snd_ad1889_free(struct snd_ad1889 *chip)
+{
+	if (chip->irq < 0)
+		goto skip_hw;
+
+	spin_lock_irq(&chip->lock);
+
+	ad1889_mute(chip);
+
+	/* Turn off interrupt on count and zero DMA registers */
+	ad1889_channel_reset(chip, AD_CHAN_WAV | AD_CHAN_ADC);
+
+	/* clear DISR. If we don't, we'd better jump off the Eiffel Tower */
+	ad1889_writel(chip, AD_DMA_DISR, AD_DMA_DISR_PTAI | AD_DMA_DISR_PMAI);
+	ad1889_readl(chip, AD_DMA_DISR);	/* flush, dammit! */
+
+	spin_unlock_irq(&chip->lock);
+
+	synchronize_irq(chip->irq);
+	
+	if (chip->irq >= 0)
+		free_irq(chip->irq, (void*)chip);
+
+skip_hw:
+	if (chip->iobase)
+		iounmap(chip->iobase);
+
+	pci_release_regions(chip->pci);
+	pci_disable_device(chip->pci);
+
+	kfree(chip);
+	return 0;
+}
+
+static inline int
+snd_ad1889_dev_free(snd_device_t *device) 
+{
+	struct snd_ad1889 *chip = device->device_data;
+	return snd_ad1889_free(chip);
+}
+
+static int __devinit
+snd_ad1889_init(struct snd_ad1889 *chip) 
+{
+	ad1889_writew(chip, AD_DS_CCS, AD_DS_CCS_CLKEN); /* turn on clock */
+	ad1889_readw(chip, AD_DS_CCS);	/* flush posted write */
+
+	mdelay(10);
+
+	/* enable Master and Target abort interrupts */
+	ad1889_writel(chip, AD_DMA_DISR, AD_DMA_DISR_PMAE | AD_DMA_DISR_PTAE);
+
+	return 0;
+}
+
+static int __devinit
+snd_ad1889_create(snd_card_t *card,
+		  struct pci_dev *pci,
+		  struct snd_ad1889 **rchip)
+{
+	int err;
+
+	struct snd_ad1889 *chip;
+	static snd_device_ops_t ops = {
+		.dev_free = snd_ad1889_dev_free,
+	};
+
+	*rchip = NULL;
+
+	if ((err = pci_enable_device(pci)) < 0)
+		return err;
+	
+	/* check PCI availability (32bit DMA) */
+	if (pci_set_dma_mask(pci, 0xffffffff) < 0 ||
+	    pci_set_consistent_dma_mask(pci, 0xffffffff) < 0) {
+		printk(KERN_ERR PFX "error setting 32-bit DMA mask.\n");
+		pci_disable_device(pci);
+		return -ENXIO;
+	}
+
+	/* allocate chip specific data with zero-filled memory */
+	if ((chip = kzalloc(sizeof(*chip), GFP_KERNEL)) == NULL) {
+		pci_disable_device(pci);
+		return -ENOMEM;
+	}
+
+	chip->card = card;
+	card->private_data = chip;
+	chip->pci = pci;
+	chip->irq = -1;
+
+	/* (1) PCI resource allocation */
+	if ((err = pci_request_regions(pci, card->driver)) < 0)
+		goto free_and_ret;
+
+	chip->bar = pci_resource_start(pci, 0);
+	chip->iobase = ioremap_nocache(chip->bar, pci_resource_len(pci, 0));
+	if (chip->iobase == NULL) {
+		printk(KERN_ERR PFX "unable to reserve region.\n");
+		err = -EBUSY;
+		goto free_and_ret;
+	}
+	
+	pci_set_master(pci);
+
+	spin_lock_init(&chip->lock);	/* only now can we call ad1889_free */
+
+	if (request_irq(pci->irq, snd_ad1889_interrupt,
+			SA_INTERRUPT|SA_SHIRQ, card->driver, (void*)chip)) {
+		printk(KERN_ERR PFX "cannot obtain IRQ %d\n", pci->irq);
+		snd_ad1889_free(chip);
+		return -EBUSY;
+	}
+
+	chip->irq = pci->irq;
+	synchronize_irq(chip->irq);
+
+	/* (2) initialization of the chip hardware */
+	if ((err = snd_ad1889_init(chip)) < 0) {
+		snd_ad1889_free(chip);
+		return err;
+	}
+
+	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+		snd_ad1889_free(chip);
+		return err;
+	}
+
+	snd_card_set_dev(card, &pci->dev);
+
+	*rchip = chip;
+
+	return 0;
+
+free_and_ret:
+	if (chip)
+		kfree(chip);
+	pci_disable_device(pci);
+
+	return err;
+}
+
+static int __devinit
+snd_ad1889_probe(struct pci_dev *pci,
+		 const struct pci_device_id *pci_id)
+{
+	int err;
+	static int devno;
+	snd_card_t *card;
+	struct snd_ad1889 *chip;
+
+	/* (1) */
+	if (devno >= SNDRV_CARDS)
+		return -ENODEV;
+	if (!enable[devno]) {
+		devno++;
+		return -ENOENT;
+	}
+
+	/* (2) */
+	card = snd_card_new(index[devno], id[devno], THIS_MODULE, 0);
+	/* XXX REVISIT: we can probably allocate chip in this call */
+	if (card == NULL)
+		return -ENOMEM;
+
+	strcpy(card->driver, "AD1889");
+	strcpy(card->shortname, "Analog Devices AD1889");
+
+	/* (3) */
+	err = snd_ad1889_create(card, pci, &chip);
+	if (err < 0)
+		goto free_and_ret;
+
+	/* (4) */
+	sprintf(card->longname, "%s at 0x%lx irq %i",
+		card->shortname, chip->bar, chip->irq);
+
+	/* (5) */
+	/* register AC97 mixer */
+	err = snd_ad1889_ac97_init(chip, ac97_quirk[devno]);
+	if (err < 0)
+		goto free_and_ret;
+	
+	err = snd_ad1889_pcm_init(chip, 0, NULL);
+	if (err < 0)
+		goto free_and_ret;
+
+	/* register proc interface */
+	snd_ad1889_proc_init(chip);
+
+	/* (6) */
+	err = snd_card_register(card);
+	if (err < 0)
+		goto free_and_ret;
+
+	/* (7) */
+	pci_set_drvdata(pci, card);
+
+	devno++;
+	return 0;
+
+free_and_ret:
+	snd_card_free(card);
+	return err;
+}
+
+static void __devexit
+snd_ad1889_remove(struct pci_dev *pci)
+{
+	snd_card_free(pci_get_drvdata(pci));
+	pci_set_drvdata(pci, NULL);
+}
+
+static struct pci_device_id snd_ad1889_ids[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_ANALOG_DEVICES, PCI_DEVICE_ID_AD1889JS) },
+	{ 0, },
+};
+MODULE_DEVICE_TABLE(pci, snd_ad1889_ids);
+
+static struct pci_driver ad1889_pci = {
+	.name = "AD1889 Audio",
+	.owner = THIS_MODULE,
+	.id_table = snd_ad1889_ids,
+	.probe = snd_ad1889_probe,
+	.remove = __devexit_p(snd_ad1889_remove),
+};
+
+static int __init
+alsa_ad1889_init(void)
+{
+	return pci_register_driver(&ad1889_pci);
+}
+
+static void __exit
+alsa_ad1889_fini(void)
+{
+	pci_unregister_driver(&ad1889_pci);
+}
+
+module_init(alsa_ad1889_init);
+module_exit(alsa_ad1889_fini);
diff --git a/sound/pci/ad1889.h b/sound/pci/ad1889.h
new file mode 100644
index 0000000..5e6dad5
--- /dev/null
+++ b/sound/pci/ad1889.h
@@ -0,0 +1,189 @@
+/* Analog Devices 1889 audio driver
+ * Copyright (C) 2004, Kyle McMartin <kyle@parisc-linux.org>
+ */
+
+#ifndef __AD1889_H__
+#define __AD1889_H__
+
+#define AD_DS_WSMC	0x00 /* wave/synthesis channel mixer control */
+#define  AD_DS_WSMC_SYEN 0x0004 /* synthesis channel enable */
+#define  AD_DS_WSMC_SYRQ 0x0030 /* synth. fifo request point */
+#define  AD_DS_WSMC_WA16 0x0100 /* wave channel 16bit select */
+#define  AD_DS_WSMC_WAST 0x0200 /* wave channel stereo select */
+#define  AD_DS_WSMC_WAEN 0x0400 /* wave channel enable */
+#define  AD_DS_WSMC_WARQ 0x3000 /* wave fifo request point */
+
+#define AD_DS_RAMC	0x02 /* resampler/ADC channel mixer control */
+#define  AD_DS_RAMC_AD16 0x0001 /* ADC channel 16bit select */
+#define  AD_DS_RAMC_ADST 0x0002 /* ADC channel stereo select */
+#define  AD_DS_RAMC_ADEN 0x0004 /* ADC channel enable */
+#define  AD_DS_RAMC_ACRQ 0x0030 /* ADC fifo request point */
+#define  AD_DS_RAMC_REEN 0x0400 /* resampler channel enable */
+#define  AD_DS_RAMC_RERQ 0x3000 /* res. fifo request point */
+
+#define AD_DS_WADA	0x04 /* wave channel mix attenuation */
+#define  AD_DS_WADA_RWAM 0x0080 /* right wave mute */
+#define  AD_DS_WADA_RWAA 0x001f /* right wave attenuation */
+#define  AD_DS_WADA_LWAM 0x8000 /* left wave mute */
+#define  AD_DS_WADA_LWAA 0x3e00 /* left wave attenuation */
+
+#define AD_DS_SYDA	0x06 /* synthesis channel mix attenuation */
+#define  AD_DS_SYDA_RSYM 0x0080 /* right synthesis mute */
+#define  AD_DS_SYDA_RSYA 0x001f /* right synthesis attenuation */
+#define  AD_DS_SYDA_LSYM 0x8000 /* left synthesis mute */
+#define  AD_DS_SYDA_LSYA 0x3e00 /* left synthesis attenuation */
+
+#define AD_DS_WAS	0x08 /* wave channel sample rate */
+#define  AD_DS_WAS_WAS   0xffff /* sample rate mask */
+
+#define AD_DS_RES	0x0a /* resampler channel sample rate */
+#define  AD_DS_RES_RES   0xffff /* sample rate mask */
+
+#define AD_DS_CCS	0x0c /* chip control/status */
+#define  AD_DS_CCS_ADO   0x0001 /* ADC channel overflow */
+#define  AD_DS_CCS_REO   0x0002 /* resampler channel overflow */
+#define  AD_DS_CCS_SYU   0x0004 /* synthesis channel underflow */
+#define  AD_DS_CCS_WAU   0x0008 /* wave channel underflow */
+/* bits 4 -> 7, 9, 11 -> 14 reserved */
+#define  AD_DS_CCS_XTD   0x0100 /* xtd delay control (4096 clock cycles) */
+#define  AD_DS_CCS_PDALL 0x0400 /* power */
+#define  AD_DS_CCS_CLKEN 0x8000 /* clock */
+
+#define AD_DMA_RESBA	0x40 /* RES base address */
+#define AD_DMA_RESCA	0x44 /* RES current address */
+#define AD_DMA_RESBC	0x48 /* RES base count */
+#define AD_DMA_RESCC	0x4c /* RES current count */
+
+#define AD_DMA_ADCBA	0x50 /* ADC base address */
+#define AD_DMA_ADCCA	0x54 /* ADC current address */
+#define AD_DMA_ADCBC	0x58 /* ADC base count */
+#define AD_DMA_ADCCC	0x5c /* ADC current count */
+
+#define AD_DMA_SYNBA	0x60 /* synth base address */
+#define AD_DMA_SYNCA	0x64 /* synth current address */
+#define AD_DMA_SYNBC	0x68 /* synth base count */
+#define AD_DMA_SYNCC	0x6c /* synth current count */
+
+#define AD_DMA_WAVBA	0x70 /* wave base address */
+#define AD_DMA_WAVCA	0x74 /* wave current address */
+#define AD_DMA_WAVBC	0x78 /* wave base count */
+#define AD_DMA_WAVCC	0x7c /* wave current count */
+
+#define AD_DMA_RESIC	0x80 /* RES dma interrupt current byte count */
+#define AD_DMA_RESIB	0x84 /* RES dma interrupt base byte count */
+
+#define AD_DMA_ADCIC	0x88 /* ADC dma interrupt current byte count */
+#define AD_DMA_ADCIB	0x8c /* ADC dma interrupt base byte count */
+
+#define AD_DMA_SYNIC	0x90 /* synth dma interrupt current byte count */
+#define AD_DMA_SYNIB	0x94 /* synth dma interrupt base byte count */
+
+#define AD_DMA_WAVIC	0x98 /* wave dma interrupt current byte count */
+#define AD_DMA_WAVIB	0x9c /* wave dma interrupt base byte count */
+
+#define  AD_DMA_ICC	0xffffff /* current byte count mask */
+#define  AD_DMA_IBC	0xffffff /* base byte count mask */
+/* bits 24 -> 31 reserved */
+
+/* 4 bytes pad */
+#define AD_DMA_ADC	0xa8	/* ADC      dma control and status */
+#define AD_DMA_SYNTH	0xb0	/* Synth    dma control and status */
+#define AD_DMA_WAV	0xb8	/* wave     dma control and status */
+#define AD_DMA_RES	0xa0	/* Resample dma control and status */
+
+#define  AD_DMA_SGDE	0x0001 /* SGD mode enable */
+#define  AD_DMA_LOOP	0x0002 /* loop enable */
+#define  AD_DMA_IM	0x000c /* interrupt mode mask */
+#define  AD_DMA_IM_DIS	(~AD_DMA_IM)	/* disable */
+#define  AD_DMA_IM_CNT	0x0004 /* interrupt on count */
+#define  AD_DMA_IM_SGD	0x0008 /* interrupt on SGD flag */
+#define  AD_DMA_IM_EOL	0x000c /* interrupt on End of Linked List */
+#define  AD_DMA_SGDS	0x0030 /* SGD status */
+#define  AD_DMA_SFLG	0x0040 /* SGD flag */
+#define  AD_DMA_EOL	0x0080 /* SGD end of list */
+/* bits 8 -> 15 reserved */
+
+#define AD_DMA_DISR	0xc0 /* dma interrupt status */
+#define  AD_DMA_DISR_RESI 0x000001 /* resampler channel interrupt */
+#define  AD_DMA_DISR_ADCI 0x000002 /* ADC channel interrupt */
+#define  AD_DMA_DISR_SYNI 0x000004 /* synthesis channel interrupt */
+#define  AD_DMA_DISR_WAVI 0x000008 /* wave channel interrupt */
+/* bits 4, 5 reserved */
+#define  AD_DMA_DISR_SEPS 0x000040 /* serial eeprom status */
+/* bits 7 -> 13 reserved */
+#define  AD_DMA_DISR_PMAI 0x004000 /* pci master abort interrupt */
+#define  AD_DMA_DISR_PTAI 0x008000 /* pci target abort interrupt */
+#define  AD_DMA_DISR_PTAE 0x010000 /* pci target abort interrupt enable */
+#define  AD_DMA_DISR_PMAE 0x020000 /* pci master abort interrupt enable */
+/* bits 19 -> 31 reserved */
+
+/* interrupt mask */
+#define  AD_INTR_MASK     (AD_DMA_DISR_RESI|AD_DMA_DISR_ADCI| \
+                           AD_DMA_DISR_WAVI|AD_DMA_DISR_SYNI| \
+                           AD_DMA_DISR_PMAI|AD_DMA_DISR_PTAI)
+
+#define AD_DMA_CHSS	0xc4 /* dma channel stop status */
+#define  AD_DMA_CHSS_RESS 0x000001 /* resampler channel stopped */
+#define  AD_DMA_CHSS_ADCS 0x000002 /* ADC channel stopped */
+#define  AD_DMA_CHSS_SYNS 0x000004 /* synthesis channel stopped */
+#define  AD_DMA_CHSS_WAVS 0x000008 /* wave channel stopped */
+
+#define AD_GPIO_IPC	0xc8	/* gpio port control */
+#define AD_GPIO_OP	0xca	/* gpio output port status */
+#define AD_GPIO_IP	0xcc	/* gpio  input port status */
+
+#define AD_AC97_BASE	0x100	/* ac97 base register */
+
+#define AD_AC97_RESET   0x100   /* reset */
+
+#define AD_AC97_PWR_CTL	0x126	/* == AC97_POWERDOWN */
+#define  AD_AC97_PWR_ADC 0x0001 /* ADC ready status */
+#define  AD_AC97_PWR_DAC 0x0002 /* DAC ready status */
+#define  AD_AC97_PWR_PR0 0x0100 /* PR0 (ADC) powerdown */
+#define  AD_AC97_PWR_PR1 0x0200 /* PR1 (DAC) powerdown */
+
+#define AD_MISC_CTL     0x176 /* misc control */
+#define  AD_MISC_CTL_DACZ   0x8000 /* set for zero fill, unset for repeat */
+#define  AD_MISC_CTL_ARSR   0x0001 /* set for SR1, unset for SR0 */
+#define  AD_MISC_CTL_ALSR   0x0100
+#define  AD_MISC_CTL_DLSR   0x0400
+#define  AD_MISC_CTL_DRSR   0x0004
+
+#define AD_AC97_SR0     0x178 /* sample rate 0, 0xbb80 == 48K */
+#define  AD_AC97_SR0_48K 0xbb80 /* 48KHz */
+#define AD_AC97_SR1     0x17a /* sample rate 1 */
+
+#define AD_AC97_ACIC	0x180 /* ac97 codec interface control */
+#define  AD_AC97_ACIC_ACIE  0x0001 /* analog codec interface enable */
+#define  AD_AC97_ACIC_ACRD  0x0002 /* analog codec reset disable */
+#define  AD_AC97_ACIC_ASOE  0x0004 /* audio stream output enable */
+#define  AD_AC97_ACIC_VSRM  0x0008 /* variable sample rate mode */
+#define  AD_AC97_ACIC_FSDH  0x0100 /* force SDATA_OUT high */
+#define  AD_AC97_ACIC_FSYH  0x0200 /* force sync high */
+#define  AD_AC97_ACIC_ACRDY 0x8000 /* analog codec ready status */
+/* bits 10 -> 14 reserved */
+
+
+#define AD_DS_MEMSIZE	512
+#define AD_OPL_MEMSIZE	16
+#define AD_MIDI_MEMSIZE	16
+
+#define AD_WAV_STATE	0
+#define AD_ADC_STATE	1
+#define AD_MAX_STATES	2
+
+#define AD_CHAN_WAV	0x0001
+#define AD_CHAN_ADC	0x0002
+#define AD_CHAN_RES	0x0004
+#define AD_CHAN_SYN	0x0008
+
+
+/* The chip would support 4 GB buffers and 16 MB periods,
+ * but let's not overdo it ... */
+#define BUFFER_BYTES_MAX	(256 * 1024)
+#define PERIOD_BYTES_MIN	32
+#define PERIOD_BYTES_MAX	(BUFFER_BYTES_MAX / 2)
+#define PERIODS_MIN		2
+#define PERIODS_MAX		(BUFFER_BYTES_MAX / PERIOD_BYTES_MIN)
+
+#endif /* __AD1889_H__ */
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index 4943299..d683f77 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -78,15 +78,7 @@
  *  Constants definition
  */
 
-#ifndef PCI_VENDOR_ID_ALI
-#define PCI_VENDOR_ID_ALI	0x10b9
-#endif
-
-#ifndef PCI_DEVICE_ID_ALI_5451
-#define PCI_DEVICE_ID_ALI_5451	0x5451
-#endif
-
-#define DEVICE_ID_ALI5451	((PCI_VENDOR_ID_ALI<<16)|PCI_DEVICE_ID_ALI_5451)
+#define DEVICE_ID_ALI5451	((PCI_VENDOR_ID_AL<<16)|PCI_DEVICE_ID_AL_M5451)
 
 
 #define ALI_CHANNELS		32
@@ -326,13 +318,12 @@
 static void ali_read_cfg(unsigned int vendor, unsigned deviceid)
 {
 	unsigned int dwVal;
-	struct pci_dev *pci_dev = NULL;
+	struct pci_dev *pci_dev;
 	int i,j;
 
-
-        pci_dev = pci_find_device(vendor, deviceid, pci_dev);
-        if (pci_dev == NULL)
-                return ;
+	pci_dev = pci_get_device(vendor, deviceid, NULL);
+	if (pci_dev == NULL)
+		return ;
 
 	printk("\nM%x PCI CFG\n", deviceid);
 	printk("    ");
@@ -349,6 +340,7 @@
 		}
 		printk("\n");
 	}
+	pci_dev_put(pci_dev);
  }
 static void ali_read_ac97regs(ali_t *codec, int secondary)
 {
@@ -2116,6 +2108,8 @@
 #ifdef CONFIG_PM
 	kfree(codec->image);
 #endif
+	pci_dev_put(codec->pci_m1533);
+	pci_dev_put(codec->pci_m7101);
 	kfree(codec);
 	return 0;
 }
@@ -2305,7 +2299,7 @@
 	codec->chregs.data.ainten = 0x00;
 
 	/* M1533: southbridge */
-       	pci_dev = pci_find_device(0x10b9, 0x1533, NULL);
+	pci_dev = pci_get_device(0x10b9, 0x1533, NULL);
 	codec->pci_m1533 = pci_dev;
 	if (! codec->pci_m1533) {
 		snd_printk(KERN_ERR "ali5451: cannot find ALi 1533 chip.\n");
@@ -2313,7 +2307,7 @@
 		return -ENODEV;
 	}
 	/* M7101: power management */
-       	pci_dev = pci_find_device(0x10b9, 0x7101, NULL);
+	pci_dev = pci_get_device(0x10b9, 0x7101, NULL);
 	codec->pci_m7101 = pci_dev;
 	if (! codec->pci_m7101 && codec->revision == ALI_5451_V02) {
 		snd_printk(KERN_ERR "ali5451: cannot find ALi 7101 chip.\n");
@@ -2417,6 +2411,7 @@
 
 static struct pci_driver driver = {
 	.name = "ALI 5451",
+	.owner = THIS_MODULE,
 	.id_table = snd_ali_ids,
 	.probe = snd_ali_probe,
 	.remove = __devexit_p(snd_ali_remove),
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index ca28b22..196ec1c 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -770,6 +770,7 @@
 
 static struct pci_driver driver = {
 	.name = "ALS4000",
+	.owner = THIS_MODULE,
 	.id_table = snd_als4000_ids,
 	.probe = snd_card_als4000_probe,
 	.remove = __devexit_p(snd_card_als4000_remove),
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 188df08..241eacf 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1453,6 +1453,7 @@
 			atiixp_dma_t *dma = &chip->dmas[i];
 			if (dma->substream && dma->suspended) {
 				dma->ops->enable_dma(chip, 1);
+				dma->substream->ops->prepare(dma->substream);
 				writel((u32)dma->desc_buf.addr | ATI_REG_LINKPTR_EN,
 				       chip->remap_addr + dma->ops->llp_offset);
 				writel(dma->saved_curptr, chip->remap_addr + dma->ops->dt_cur);
@@ -1530,7 +1531,7 @@
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -1644,6 +1645,7 @@
 
 static struct pci_driver driver = {
 	.name = "ATI IXP AC97 controller",
+	.owner = THIS_MODULE,
 	.id_table = snd_atiixp_ids,
 	.probe = snd_atiixp_probe,
 	.remove = __devexit_p(snd_atiixp_remove),
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 8d20029..8a59598 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -1208,7 +1208,7 @@
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -1318,6 +1318,7 @@
 
 static struct pci_driver driver = {
 	.name = "ATI IXP MC97 controller",
+	.owner = THIS_MODULE,
 	.id_table = snd_atiixp_ids,
 	.probe = snd_atiixp_probe,
 	.remove = __devexit_p(snd_atiixp_remove),
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index f6236c6..04b695d 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -79,19 +79,21 @@
 
 static void __devinit snd_vortex_workaround(struct pci_dev *vortex, int fix)
 {
-	struct pci_dev *via;
+	struct pci_dev *via = NULL;
 
 	/* autodetect if workarounds are required */
 	if (fix == 255) {
 		/* VIA KT133 */
-		via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8365_1, NULL);
+		via = pci_get_device(PCI_VENDOR_ID_VIA,
+			PCI_DEVICE_ID_VIA_8365_1, NULL);
 		/* VIA Apollo */
 		if (via == NULL) {
-			via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C598_1, NULL);
-		}
-		/* AMD Irongate */
-		if (via == NULL) {
-			via = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL);
+			via = pci_get_device(PCI_VENDOR_ID_VIA,
+				PCI_DEVICE_ID_VIA_82C598_1, NULL);
+			/* AMD Irongate */
+			if (via == NULL)
+				via = pci_get_device(PCI_VENDOR_ID_AMD,
+					PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL);
 		}
 		if (via) {
 			printk(KERN_INFO CARD_NAME ": Activating latency workaround...\n");
@@ -101,13 +103,17 @@
 	} else {
 		if (fix & 0x1)
 			vortex_fix_latency(vortex);
-		if ((fix & 0x2) && (via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8365_1, NULL)))
+		if ((fix & 0x2) && (via = pci_get_device(PCI_VENDOR_ID_VIA,
+				PCI_DEVICE_ID_VIA_8365_1, NULL)))
 			vortex_fix_agp_bridge(via);
-		if ((fix & 0x4) && (via = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C598_1, NULL)))
+		if ((fix & 0x4) && (via = pci_get_device(PCI_VENDOR_ID_VIA,
+				PCI_DEVICE_ID_VIA_82C598_1, NULL)))
 			vortex_fix_agp_bridge(via);
-		if ((fix & 0x8) && (via = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL)))
+		if ((fix & 0x8) && (via = pci_get_device(PCI_VENDOR_ID_AMD,
+				PCI_DEVICE_ID_AMD_FE_GATE_7007, NULL)))
 			vortex_fix_agp_bridge(via);
 	}
+	pci_dev_put(via);
 }
 
 // component-destructor
@@ -150,7 +156,7 @@
 	}
 	pci_set_dma_mask(pci, VORTEX_DMA_MASK);
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL)
 		return -ENOMEM;
 
@@ -367,6 +373,7 @@
 // pci_driver definition
 static struct pci_driver driver = {
 	.name = CARD_NAME_SHORT,
+	.owner = THIS_MODULE,
 	.id_table = snd_vortex_ids,
 	.probe = snd_vortex_probe,
 	.remove = __devexit_p(snd_vortex_remove),
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 72bba7b..d5261bd 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1345,7 +1345,7 @@
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -1511,6 +1511,7 @@
 
 static struct pci_driver driver = {
 	.name = "AZF3328",
+	.owner = THIS_MODULE,
 	.id_table = snd_azf3328_ids,
 	.probe = snd_azf3328_probe,
 	.remove = __devexit_p(snd_azf3328_remove),
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index c5557ea..2236c95 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -59,16 +59,6 @@
 MODULE_PARM_DESC(load_all, "Allow to load the non-whitelisted cards");
 
 
-#ifndef PCI_VENDOR_ID_BROOKTREE
-#define PCI_VENDOR_ID_BROOKTREE 0x109e
-#endif
-#ifndef PCI_DEVICE_ID_BROOKTREE_878
-#define PCI_DEVICE_ID_BROOKTREE_878 0x0878
-#endif
-#ifndef PCI_DEVICE_ID_BROOKTREE_879
-#define PCI_DEVICE_ID_BROOKTREE_879 0x0879
-#endif
-
 /* register offsets */
 #define REG_INT_STAT		0x100	/* interrupt status */
 #define REG_INT_MASK		0x104	/* interrupt mask */
@@ -720,7 +710,7 @@
 	if (err < 0)
 		return err;
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (!chip) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -911,6 +901,7 @@
 
 static struct pci_driver driver = {
 	.name = "Bt87x",
+	.owner = THIS_MODULE,
 	.id_table = snd_bt87x_ids,
 	.probe = snd_bt87x_probe,
 	.remove = __devexit_p(snd_bt87x_remove),
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 7e27bfc..ba07960 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -352,7 +352,7 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	int err;
 
-	epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
 
 	if (epcm == NULL)
 		return -ENOMEM;
@@ -419,7 +419,7 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	int err;
 
-	epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
 	if (epcm == NULL) {
                 snd_printk("open_capture_channel: failed epcm alloc\n");
 		return -ENOMEM;
@@ -1144,7 +1144,7 @@
 		return -ENXIO;
 	}
   
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -1390,6 +1390,7 @@
 // pci_driver definition
 static struct pci_driver driver = {
 	.name = "CA0106",
+	.owner = THIS_MODULE,
 	.id_table = snd_ca0106_ids,
 	.probe = snd_ca0106_probe,
 	.remove = __devexit_p(snd_ca0106_remove),
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index b6b8882..c10e4a5 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -482,7 +482,7 @@
 static snd_kcontrol_new_t snd_ca0106_volume_control_analog_front =
 {
         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "Analog Front Volume",
+        .name =         "Analog Front Playback Volume",
         .info =         snd_ca0106_volume_info,
         .get =          snd_ca0106_volume_get_analog_front,
         .put =          snd_ca0106_volume_put_analog_front
@@ -490,7 +490,7 @@
 static snd_kcontrol_new_t snd_ca0106_volume_control_analog_center_lfe =
 {
         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "Analog Center/LFE Volume",
+        .name =         "Analog Center/LFE Playback Volume",
         .info =         snd_ca0106_volume_info,
         .get =          snd_ca0106_volume_get_analog_center_lfe,
         .put =          snd_ca0106_volume_put_analog_center_lfe
@@ -498,7 +498,7 @@
 static snd_kcontrol_new_t snd_ca0106_volume_control_analog_unknown =
 {
         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "Analog Side Volume",
+        .name =         "Analog Side Playback Volume",
         .info =         snd_ca0106_volume_info,
         .get =          snd_ca0106_volume_get_analog_unknown,
         .put =          snd_ca0106_volume_put_analog_unknown
@@ -506,7 +506,7 @@
 static snd_kcontrol_new_t snd_ca0106_volume_control_analog_rear =
 {
         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "Analog Rear Volume",
+        .name =         "Analog Rear Playback Volume",
         .info =         snd_ca0106_volume_info,
         .get =          snd_ca0106_volume_get_analog_rear,
         .put =          snd_ca0106_volume_put_analog_rear
@@ -514,7 +514,7 @@
 static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_front =
 {
         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "SPDIF Front Volume",
+        .name =         "SPDIF Front Playback Volume",
         .info =         snd_ca0106_volume_info,
         .get =          snd_ca0106_volume_get_spdif_front,
         .put =          snd_ca0106_volume_put_spdif_front
@@ -522,7 +522,7 @@
 static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_center_lfe =
 {
         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "SPDIF Center/LFE Volume",
+        .name =         "SPDIF Center/LFE Playback Volume",
         .info =         snd_ca0106_volume_info,
         .get =          snd_ca0106_volume_get_spdif_center_lfe,
         .put =          snd_ca0106_volume_put_spdif_center_lfe
@@ -530,7 +530,7 @@
 static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_unknown =
 {
         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "SPDIF Unknown Volume",
+        .name =         "SPDIF Unknown Playback Volume",
         .info =         snd_ca0106_volume_info,
         .get =          snd_ca0106_volume_get_spdif_unknown,
         .put =          snd_ca0106_volume_put_spdif_unknown
@@ -538,7 +538,7 @@
 static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_rear =
 {
         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "SPDIF Rear Volume",
+        .name =         "SPDIF Rear Playback Volume",
         .info =         snd_ca0106_volume_info,
         .get =          snd_ca0106_volume_get_spdif_rear,
         .put =          snd_ca0106_volume_put_spdif_rear
@@ -547,7 +547,7 @@
 static snd_kcontrol_new_t snd_ca0106_volume_control_feedback =
 {
         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "CAPTURE feedback into PLAYBACK",
+        .name =         "CAPTURE feedback Playback Volume",
         .info =         snd_ca0106_volume_info,
         .get =          snd_ca0106_volume_get_feedback,
         .put =          snd_ca0106_volume_put_feedback
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index b098b51..1eb3315 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -79,13 +79,6 @@
 MODULE_PARM_DESC(joystick_port, "Joystick port address.");
 #endif
 
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8738
-#define PCI_DEVICE_ID_CMEDIA_CM8738	0x0111
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8738B
-#define PCI_DEVICE_ID_CMEDIA_CM8738B	0x0112
-#endif
-
 /*
  * CM8x38 registers definition
  */
@@ -348,25 +341,6 @@
 
 
 /*
- * pci ids
- */
-#ifndef PCI_VENDOR_ID_CMEDIA
-#define PCI_VENDOR_ID_CMEDIA         0x13F6
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8338A
-#define PCI_DEVICE_ID_CMEDIA_CM8338A 0x0100
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8338B
-#define PCI_DEVICE_ID_CMEDIA_CM8338B 0x0101
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8738
-#define PCI_DEVICE_ID_CMEDIA_CM8738  0x0111
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8738B
-#define PCI_DEVICE_ID_CMEDIA_CM8738B 0x0112
-#endif
-
-/*
  * channels for playback / capture
  */
 #define CM_CH_PLAY	0
@@ -2801,7 +2775,7 @@
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
 
-	cm = kcalloc(1, sizeof(*cm), GFP_KERNEL);
+	cm = kzalloc(sizeof(*cm), GFP_KERNEL);
 	if (cm == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -3063,6 +3037,7 @@
 
 static struct pci_driver driver = {
 	.name = "C-Media PCI",
+	.owner = THIS_MODULE,
 	.id_table = snd_cmipci_ids,
 	.probe = snd_cmipci_probe,
 	.remove = __devexit_p(snd_cmipci_remove),
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index c7a370d..dc87e01 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -57,17 +57,6 @@
 MODULE_PARM_DESC(dual_codec, "Secondary Codec ID (0 = disabled).");
 
 /*
- *
- */
-
-#ifndef PCI_VENDOR_ID_CIRRUS
-#define PCI_VENDOR_ID_CIRRUS            0x1013
-#endif
-#ifndef PCI_DEVICE_ID_CIRRUS_4281
-#define PCI_DEVICE_ID_CIRRUS_4281	0x6005
-#endif
-
-/*
  *  Direct registers
  */
 
@@ -1394,7 +1383,7 @@
 	*rchip = NULL;
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -2119,6 +2108,7 @@
 
 static struct pci_driver driver = {
 	.name = "CS4281",
+	.owner = THIS_MODULE,
 	.id_table = snd_cs4281_ids,
 	.probe = snd_cs4281_probe,
 	.remove = __devexit_p(snd_cs4281_remove),
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index b9fff4e..32b4f84 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -163,6 +163,7 @@
 
 static struct pci_driver driver = {
 	.name = "Sound Fusion CS46xx",
+	.owner = THIS_MODULE,
 	.id_table = snd_cs46xx_ids,
 	.probe = snd_card_cs46xx_probe,
 	.remove = __devexit_p(snd_card_cs46xx_remove),
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 4b05215..6e3855b 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -1304,7 +1304,7 @@
 	cs46xx_pcm_t * cpcm;
 	snd_pcm_runtime_t *runtime = substream->runtime;
 
-	cpcm = kcalloc(1, sizeof(*cpcm), GFP_KERNEL);
+	cpcm = kzalloc(sizeof(*cpcm), GFP_KERNEL);
 	if (cpcm == NULL)
 		return -ENOMEM;
 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
@@ -3525,17 +3525,6 @@
 
 
 /*
- * piix4 pci ids
- */
-#ifndef PCI_VENDOR_ID_INTEL
-#define PCI_VENDOR_ID_INTEL 0x8086
-#endif /* PCI_VENDOR_ID_INTEL */
-
-#ifndef PCI_DEVICE_ID_INTEL_82371AB_3
-#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
-#endif /* PCI_DEVICE_ID_INTEL_82371AB_3 */
-
-/*
  *	Handle the CLKRUN on a thinkpad. We must disable CLKRUN support
  *	whenever we need to beat on the chip.
  *
@@ -3548,7 +3537,7 @@
 {
 	u16 control, nval;
 	
-	if (chip->acpi_dev == NULL)
+	if (!chip->acpi_port)
 		return;
 
 	chip->amplifier += change;
@@ -3571,15 +3560,20 @@
  */
 static void clkrun_init(cs46xx_t *chip)
 {
+	struct pci_dev *pdev;
 	u8 pp;
 
-	chip->acpi_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
-	if (chip->acpi_dev == NULL)
+	chip->acpi_port = 0;
+	
+	pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
+		PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
+	if (pdev == NULL)
 		return;		/* Not a thinkpad thats for sure */
 
 	/* Find the control port */		
-	pci_read_config_byte(chip->acpi_dev, 0x41, &pp);
+	pci_read_config_byte(pdev, 0x41, &pp);
 	chip->acpi_port = pp << 8;
+	pci_dev_put(pdev);
 }
 
 
@@ -3780,7 +3774,7 @@
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index fc377c4..b0e00f0 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -223,6 +223,7 @@
 
 static struct pci_driver driver = {
 	.name = "EMU10K1_Audigy",
+	.owner = THIS_MODULE,
 	.id_table = snd_emu10k1_ids,
 	.probe = snd_card_emu10k1_probe,
 	.remove = __devexit_p(snd_card_emu10k1_remove),
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index e69d5b7..e87e842 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -754,12 +754,11 @@
 	 .emu10k1_chip = 1,
 	 .ac97_chip = 1,
 	 .sblive51 = 1} ,
-	/* Tested by alsa bugtrack user "hus" 12th Sept 2005 */
+	/* Tested by alsa bugtrack user "hus" bug #1297 12th Aug 2005 */
 	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102,
-	 .driver = "EMU10K1", .name = "SBLive! Player 5.1 [SB0060]", 
+	 .driver = "EMU10K1", .name = "SBLive! Platinum 5.1 [SB0060]", 
 	 .id = "Live",
 	 .emu10k1_chip = 1,
-	 .ac97_chip = 1,
 	 .sblive51 = 1} ,
 	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102,
 	 .driver = "EMU10K1", .name = "SBLive! Value [CT4850]", 
@@ -865,7 +864,7 @@
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
 
-	emu = kcalloc(1, sizeof(*emu), GFP_KERNEL);
+	emu = kzalloc(sizeof(*emu), GFP_KERNEL);
 	if (emu == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 52c7826..ad15755 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -395,7 +395,7 @@
 	if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
                 return err;
 
-	epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
 	if (epcm == NULL)
 		return -ENOMEM;
 	epcm->emu = chip;
@@ -571,7 +571,7 @@
 	if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
                 return err;
 
-	epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
 	if (epcm == NULL)
 		return -ENOMEM;
 
@@ -920,7 +920,7 @@
 		return -ENXIO;
 	}
   
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -1615,6 +1615,7 @@
 // pci_driver definition
 static struct pci_driver driver = {
 	.name = "EMU10K1X",
+	.owner = THIS_MODULE,
 	.id_table = snd_emu10k1x_ids,
 	.probe = snd_emu10k1x_probe,
 	.remove = __devexit_p(snd_emu10k1x_remove),
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index 637c555..646b5d9 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -470,7 +470,7 @@
 {
 	u_int32_t *code;
 	snd_assert(*ptr < 512, return);
-	code = (u_int32_t *)icode->code + (*ptr) * 2;
+	code = (u_int32_t __force *)icode->code + (*ptr) * 2;
 	set_bit(*ptr, icode->code_valid);
 	code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
 	code[1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
@@ -485,7 +485,7 @@
 {
 	u_int32_t *code;
 	snd_assert(*ptr < 1024, return);
-	code = (u_int32_t *)icode->code + (*ptr) * 2;
+	code = (u_int32_t __force *)icode->code + (*ptr) * 2;
 	set_bit(*ptr, icode->code_valid);
 	code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
 	code[1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
@@ -1036,13 +1036,13 @@
 	spin_lock_init(&emu->fx8010.irq_lock);
 	INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
 
-	if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL ||
+	if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL ||
 	    (icode->gpr_map = (u_int32_t __user *)kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
 	    (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(*controls), GFP_KERNEL)) == NULL) {
 		err = -ENOMEM;
 		goto __err;
 	}
-	gpr_map = (u32 *)icode->gpr_map;
+	gpr_map = (u32 __force *)icode->gpr_map;
 
 	icode->tram_data_map = icode->gpr_map + 512;
 	icode->tram_addr_map = icode->tram_data_map + 256;
@@ -1431,7 +1431,7 @@
  __err:
 	kfree(controls);
 	if (icode != NULL) {
-		kfree((void *)icode->gpr_map);
+		kfree((void __force *)icode->gpr_map);
 		kfree(icode);
 	}
 	return err;
@@ -1503,15 +1503,15 @@
 	spin_lock_init(&emu->fx8010.irq_lock);
 	INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
 
-	if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL)
+	if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL)
 		return -ENOMEM;
 	if ((icode->gpr_map = (u_int32_t __user *)kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
             (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(emu10k1_fx8010_control_gpr_t), GFP_KERNEL)) == NULL ||
-	    (ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL)) == NULL) {
+	    (ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL)) == NULL) {
 		err = -ENOMEM;
 		goto __err;
 	}
-	gpr_map = (u32 *)icode->gpr_map;
+	gpr_map = (u32 __force *)icode->gpr_map;
 
 	icode->tram_data_map = icode->gpr_map + 256;
 	icode->tram_addr_map = icode->tram_data_map + 160;
@@ -2032,7 +2032,7 @@
 	kfree(ipcm);
 	kfree(controls);
 	if (icode != NULL) {
-		kfree((void *)icode->gpr_map);
+		kfree((void __force *)icode->gpr_map);
 		kfree(icode);
 	}
 	return err;
@@ -2217,7 +2217,7 @@
 		kfree(ipcm);
 		return res;
 	case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
-		ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL);
+		ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL);
 		if (ipcm == NULL)
 			return -ENOMEM;
 		if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 9c35f6d..66ba27a 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -1016,7 +1016,7 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	int i;
 
-	epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
 	if (epcm == NULL)
 		return -ENOMEM;
 	epcm->emu = emu;
@@ -1049,7 +1049,7 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	int i, err;
 
-	epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
 	if (epcm == NULL)
 		return -ENOMEM;
 	epcm->emu = emu;
@@ -1094,7 +1094,7 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	emu10k1_pcm_t *epcm;
 
-	epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
 	if (epcm == NULL)
 		return -ENOMEM;
 	epcm->emu = emu;
@@ -1130,7 +1130,7 @@
 	emu10k1_pcm_t *epcm;
 	snd_pcm_runtime_t *runtime = substream->runtime;
 
-	epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
 	if (epcm == NULL)
 		return -ENOMEM;
 	epcm->emu = emu;
@@ -1170,7 +1170,7 @@
 	int nefx = emu->audigy ? 64 : 32;
 	int idx;
 
-	epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
 	if (epcm == NULL)
 		return -ENOMEM;
 	epcm->emu = emu;
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index a169133..d59c7f3 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -178,7 +178,7 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	int err;
 
-	epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
         //snd_printk("epcm kcalloc: %p\n", epcm);
 
 	if (epcm == NULL)
@@ -214,7 +214,7 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	int err;
 
-	epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
 	//snd_printk("epcm kcalloc: %p\n", epcm);
 
 	if (epcm == NULL)
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index f06b95f..bef9a59 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -100,13 +100,6 @@
 #endif
 #endif /* SUPPORT_JOYSTICK */
 
-#ifndef PCI_DEVICE_ID_ENSONIQ_CT5880
-#define PCI_DEVICE_ID_ENSONIQ_CT5880    0x5880
-#endif
-#ifndef PCI_DEVICE_ID_ENSONIQ_ES1371
-#define PCI_DEVICE_ID_ENSONIQ_ES1371	0x1371
-#endif
-
 /* ES1371 chip ID */
 /* This is a little confusing because all ES1371 compatible chips have the
    same DEVICE_ID, the only thing differentiating them is the REV_ID field.
@@ -1950,7 +1943,7 @@
 	*rensoniq = NULL;
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
-	ensoniq = kcalloc(1, sizeof(*ensoniq), GFP_KERNEL);
+	ensoniq = kzalloc(sizeof(*ensoniq), GFP_KERNEL);
 	if (ensoniq == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -2394,6 +2387,7 @@
 
 static struct pci_driver driver = {
 	.name = DRIVER_NAME,
+	.owner = THIS_MODULE,
 	.id_table = snd_audiopci_ids,
 	.probe = snd_audiopci_probe,
 	.remove = __devexit_p(snd_audiopci_remove),
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index b492777..17fa80c 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -76,13 +76,6 @@
 #define SUPPORT_JOYSTICK 1
 #endif
 
-#ifndef PCI_VENDOR_ID_ESS
-#define PCI_VENDOR_ID_ESS		0x125d
-#endif
-#ifndef PCI_DEVICE_ID_ESS_ES1938
-#define PCI_DEVICE_ID_ESS_ES1938	0x1969
-#endif
-
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
@@ -1501,7 +1494,7 @@
                 return -ENXIO;
         }
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -1753,6 +1746,7 @@
 
 static struct pci_driver driver = {
 	.name = "ESS ES1938 (Solo-1)",
+	.owner = THIS_MODULE,
 	.id_table = snd_es1938_ids,
 	.probe = snd_es1938_probe,
 	.remove = __devexit_p(snd_es1938_remove),
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 9d7a287..ecdcada 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -160,25 +160,6 @@
 #endif
 
 
-/* PCI Dev ID's */
-
-#ifndef PCI_VENDOR_ID_ESS
-#define PCI_VENDOR_ID_ESS	0x125D
-#endif
-
-#define PCI_VENDOR_ID_ESS_OLD	0x1285	/* Platform Tech, the people the ESS
-					   was bought form */
-
-#ifndef PCI_DEVICE_ID_ESS_M2E
-#define PCI_DEVICE_ID_ESS_M2E	0x1978
-#endif
-#ifndef PCI_DEVICE_ID_ESS_M2
-#define PCI_DEVICE_ID_ESS_M2	0x1968
-#endif
-#ifndef PCI_DEVICE_ID_ESS_M1
-#define PCI_DEVICE_ID_ESS_M1	0x0100
-#endif
-
 #define NR_APUS			64
 #define NR_APU_REGS		16
 
@@ -1596,7 +1577,7 @@
 	if (apu1 < 0)
 		return apu1;
 
-	es = kcalloc(1, sizeof(*es), GFP_KERNEL);
+	es = kzalloc(sizeof(*es), GFP_KERNEL);
 	if (!es) {
 		snd_es1968_free_apu_pair(chip, apu1);
 		return -ENOMEM;
@@ -1641,7 +1622,7 @@
 		return apu2;
 	}
 	
-	es = kcalloc(1, sizeof(*es), GFP_KERNEL);
+	es = kzalloc(sizeof(*es), GFP_KERNEL);
 	if (!es) {
 		snd_es1968_free_apu_pair(chip, apu1);
 		snd_es1968_free_apu_pair(chip, apu2);
@@ -2588,7 +2569,7 @@
 		return -ENXIO;
 	}
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (! chip) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -2782,6 +2763,7 @@
 
 static struct pci_driver driver = {
 	.name = "ES1968 (ESS Maestro)",
+	.owner = THIS_MODULE,
 	.id_table = snd_es1968_ids,
 	.probe = snd_es1968_probe,
 	.remove = __devexit_p(snd_es1968_remove),
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 36b2f62..e5cfa2a 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -1263,7 +1263,7 @@
 	*rchip = NULL;
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -1462,6 +1462,7 @@
 
 static struct pci_driver driver = {
 	.name = "FM801",
+	.owner = THIS_MODULE,
 	.id_table = snd_fm801_ids,
 	.probe = snd_card_fm801_probe,
 	.remove = __devexit_p(snd_card_fm801_remove),
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 20f7762..3815403 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -288,7 +288,7 @@
 {
 	struct hda_bus_unsolicited *unsol;
 
-	unsol = kcalloc(1, sizeof(*unsol), GFP_KERNEL);
+	unsol = kzalloc(sizeof(*unsol), GFP_KERNEL);
 	if (! unsol) {
 		snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n");
 		return -ENOMEM;
@@ -358,7 +358,7 @@
 	if (busp)
 		*busp = NULL;
 
-	bus = kcalloc(1, sizeof(*bus), GFP_KERNEL);
+	bus = kzalloc(sizeof(*bus), GFP_KERNEL);
 	if (bus == NULL) {
 		snd_printk(KERN_ERR "can't allocate struct hda_bus\n");
 		return -ENOMEM;
@@ -493,7 +493,7 @@
 		return -EBUSY;
 	}
 
-	codec = kcalloc(1, sizeof(*codec), GFP_KERNEL);
+	codec = kzalloc(sizeof(*codec), GFP_KERNEL);
 	if (codec == NULL) {
 		snd_printk(KERN_ERR "can't allocate struct hda_codec\n");
 		return -ENOMEM;
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 63a29a8..bb53bcf 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -505,6 +505,7 @@
 struct hda_pcm {
 	char *name;
 	struct hda_pcm_stream stream[2];
+	unsigned int is_modem;	/* modem codec? */
 };
 
 /* codec information */
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 1229227..5b829a1 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -98,7 +98,7 @@
 	struct hda_gnode *node;
 	int nconns;
 
-	node = kcalloc(1, sizeof(*node), GFP_KERNEL);
+	node = kzalloc(sizeof(*node), GFP_KERNEL);
 	if (node == NULL)
 		return -ENOMEM;
 	node->nid = nid;
@@ -886,7 +886,7 @@
 		return -ENODEV;
 	}
 
-	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL) {
 		printk(KERN_ERR "hda_generic: can't allocate spec\n");
 		return -ENOMEM;
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 15107df..9590ece 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -62,7 +62,7 @@
 module_param_array(model, charp, NULL, 0444);
 MODULE_PARM_DESC(model, "Use the given board model.");
 module_param_array(position_fix, int, NULL, 0444);
-MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = FIFO size, 1 = none, 2 = POSBUF).");
+MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size).");
 
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
@@ -164,7 +164,9 @@
 /* max buffer size - no h/w limit, you can increase as you like */
 #define AZX_MAX_BUF_SIZE	(1024*1024*1024)
 /* max number of PCM devics per card */
-#define AZX_MAX_PCMS		8
+#define AZX_MAX_AUDIO_PCMS	6
+#define AZX_MAX_MODEM_PCMS	2
+#define AZX_MAX_PCMS		(AZX_MAX_AUDIO_PCMS + AZX_MAX_MODEM_PCMS)
 
 /* RIRB int mask: overrun[2], response[0] */
 #define RIRB_INT_RESPONSE	0x01
@@ -211,9 +213,10 @@
 
 /* position fix mode */
 enum {
-	POS_FIX_FIFO,
+	POS_FIX_AUTO,
 	POS_FIX_NONE,
-	POS_FIX_POSBUF
+	POS_FIX_POSBUF,
+	POS_FIX_FIFO,
 };
 
 /* Defines for ATI HD Audio support in SB450 south bridge */
@@ -243,6 +246,7 @@
 	unsigned int fragsize;		/* size of each period in bytes */
 	unsigned int frags;		/* number for period in the play buffer */
 	unsigned int fifo_size;		/* FIFO size */
+	unsigned int last_pos;		/* last updated period position */
 
 	void __iomem *sd_addr;		/* stream descriptor pointer */
 
@@ -256,6 +260,7 @@
 
 	unsigned int opened: 1;
 	unsigned int running: 1;
+	unsigned int period_updating: 1;
 };
 
 /* CORB/RIRB */
@@ -724,11 +729,9 @@
 	/* initialize the codec command I/O */
 	azx_init_cmd_io(chip);
 
-	if (chip->position_fix == POS_FIX_POSBUF) {
-		/* program the position buffer */
-		azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
-		azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr));
-	}
+	/* program the position buffer */
+	azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
+	azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr));
 
 	/* For ATI SB450 azalia HD audio, we need to enable snoop */
 	if (chip->driver_type == AZX_DRIVER_ATI) {
@@ -763,9 +766,11 @@
 		if (status & azx_dev->sd_int_sta_mask) {
 			azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK);
 			if (azx_dev->substream && azx_dev->running) {
+				azx_dev->period_updating = 1;
 				spin_unlock(&chip->reg_lock);
 				snd_pcm_period_elapsed(azx_dev->substream);
 				spin_lock(&chip->reg_lock);
+				azx_dev->period_updating = 0;
 			}
 		}
 	}
@@ -866,11 +871,9 @@
 	/* upper BDL address */
 	azx_sd_writel(azx_dev, SD_BDLPU, upper_32bit(azx_dev->bdl_addr));
 
-	if (chip->position_fix == POS_FIX_POSBUF) {
-		/* enable the position buffer */
-		if (! (azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
-			azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE);
-	}
+	/* enable the position buffer */
+	if (! (azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
+		azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE);
 
 	/* set the interrupt enable bits in the descriptor control register */
 	azx_sd_writel(azx_dev, SD_CTL, azx_sd_readl(azx_dev, SD_CTL) | SD_INT_MASK);
@@ -1078,6 +1081,7 @@
 		azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1;
 	else
 		azx_dev->fifo_size = 0;
+	azx_dev->last_pos = 0;
 
 	return hinfo->ops.prepare(hinfo, apcm->codec, azx_dev->stream_tag,
 				  azx_dev->format_val, substream);
@@ -1133,6 +1137,26 @@
 		pos = azx_sd_readl(azx_dev, SD_LPIB);
 		if (chip->position_fix == POS_FIX_FIFO)
 			pos += azx_dev->fifo_size;
+		else if (chip->position_fix == POS_FIX_AUTO && azx_dev->period_updating) {
+			/* check the validity of DMA position */
+			unsigned int diff = 0;
+			azx_dev->last_pos += azx_dev->fragsize;
+			if (azx_dev->last_pos > pos)
+				diff = azx_dev->last_pos - pos;
+			if (azx_dev->last_pos >= azx_dev->bufsize) {
+				if (pos < azx_dev->fragsize)
+					diff = 0;
+				azx_dev->last_pos = 0;
+			}
+			if (diff > 0 && diff <= azx_dev->fifo_size)
+				pos += azx_dev->fifo_size;
+			else {
+				snd_printdd(KERN_INFO "hda_intel: DMA position fix %d, switching to posbuf\n", diff);
+				chip->position_fix = POS_FIX_POSBUF;
+				pos = *azx_dev->posbuf;
+			}
+			azx_dev->period_updating = 0;
+		}
 	}
 	if (pos >= azx_dev->bufsize)
 		pos = 0;
@@ -1203,12 +1227,33 @@
 	if ((err = snd_hda_build_pcms(chip->bus)) < 0)
 		return err;
 
+	/* create audio PCMs */
 	pcm_dev = 0;
 	list_for_each(p, &chip->bus->codec_list) {
 		codec = list_entry(p, struct hda_codec, list);
 		for (c = 0; c < codec->num_pcms; c++) {
+			if (codec->pcm_info[c].is_modem)
+				continue; /* create later */
+			if (pcm_dev >= AZX_MAX_AUDIO_PCMS) {
+				snd_printk(KERN_ERR SFX "Too many audio PCMs\n");
+				return -EINVAL;
+			}
+			err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev);
+			if (err < 0)
+				return err;
+			pcm_dev++;
+		}
+	}
+
+	/* create modem PCMs */
+	pcm_dev = AZX_MAX_AUDIO_PCMS;
+	list_for_each(p, &chip->bus->codec_list) {
+		codec = list_entry(p, struct hda_codec, list);
+		for (c = 0; c < codec->num_pcms; c++) {
+			if (! codec->pcm_info[c].is_modem)
+				continue; /* already created */
 			if (pcm_dev >= AZX_MAX_PCMS) {
-				snd_printk(KERN_ERR SFX "Too many PCMs\n");
+				snd_printk(KERN_ERR SFX "Too many modem PCMs\n");
 				return -EINVAL;
 			}
 			err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev);
@@ -1244,8 +1289,7 @@
 		azx_dev_t *azx_dev = &chip->azx_dev[i];
 		azx_dev->bdl = (u32 *)(chip->bdl.area + off);
 		azx_dev->bdl_addr = chip->bdl.addr + off;
-		if (chip->position_fix == POS_FIX_POSBUF)
-			azx_dev->posbuf = (volatile u32 *)(chip->posbuf.area + i * 8);
+		azx_dev->posbuf = (volatile u32 *)(chip->posbuf.area + i * 8);
 		/* offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */
 		azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80);
 		/* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */
@@ -1358,7 +1402,7 @@
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	
 	if (NULL == chip) {
 		snd_printk(KERN_ERR SFX "cannot allocate chip\n");
@@ -1437,13 +1481,11 @@
 		snd_printk(KERN_ERR SFX "cannot allocate BDL\n");
 		goto errout;
 	}
-	if (chip->position_fix == POS_FIX_POSBUF) {
-		/* allocate memory for the position buffer */
-		if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
-					       chip->num_streams * 8, &chip->posbuf)) < 0) {
-			snd_printk(KERN_ERR SFX "cannot allocate posbuf\n");
-			goto errout;
-		}
+	/* allocate memory for the position buffer */
+	if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
+				       chip->num_streams * 8, &chip->posbuf)) < 0) {
+		snd_printk(KERN_ERR SFX "cannot allocate posbuf\n");
+		goto errout;
 	}
 	/* allocate CORB/RIRB */
 	if ((err = azx_alloc_cmd_io(chip)) < 0)
@@ -1561,6 +1603,7 @@
 /* pci_driver definition */
 static struct pci_driver driver = {
 	.name = "HDA Intel",
+	.owner = THIS_MODULE,
 	.id_table = azx_ids,
 	.probe = azx_probe,
 	.remove = __devexit_p(azx_remove),
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index de1217b..08f6a6e 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -207,6 +207,8 @@
 	snd_iprintf(buffer, "Vendor Id: 0x%x\n", codec->vendor_id);
 	snd_iprintf(buffer, "Subsystem Id: 0x%x\n", codec->subsystem_id);
 	snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id);
+	if (! codec->afg)
+		return;
 	snd_iprintf(buffer, "Default PCM: ");
 	print_pcm_caps(buffer, codec, codec->afg);
 	snd_iprintf(buffer, "Default Amp-In caps: ");
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index bceb83a..da6874d 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -465,7 +465,7 @@
 {
 	struct ad198x_spec *spec;
 
-	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL)
 		return -ENOMEM;
 
@@ -623,7 +623,7 @@
 {
 	struct ad198x_spec *spec;
 
-	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL)
 		return -ENOMEM;
 
@@ -764,7 +764,7 @@
 {
 	struct ad198x_spec *spec;
 
-	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL)
 		return -ENOMEM;
 
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index 07fb4f5..523c362 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -667,7 +667,7 @@
 {
 	struct cmi_spec *spec;
 
-	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL)
 		return -ENOMEM;
 
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index eeb900a..849b5b5 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1526,6 +1526,7 @@
 	/* Back 3 jack, front 2 jack (Internal add Aux-In) */
 	{ .pci_subvendor = 0x1025, .pci_subdevice = 0xe310, .config = ALC880_3ST },
 	{ .pci_subvendor = 0x104d, .pci_subdevice = 0x81d6, .config = ALC880_3ST }, 
+	{ .pci_subvendor = 0x104d, .pci_subdevice = 0x81a0, .config = ALC880_3ST },
 
 	/* Back 3 jack plus 1 SPDIF out jack, front 2 jack */
 	{ .modelname = "3stack-digout", .config = ALC880_3ST_DIG },
@@ -1581,6 +1582,7 @@
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1973, .config = ALC880_ASUS_DIG },
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x19b3, .config = ALC880_ASUS_DIG },
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1113, .config = ALC880_ASUS_DIG },
+	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1173, .config = ALC880_ASUS_DIG },
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1993, .config = ALC880_ASUS },
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x10c3, .config = ALC880_ASUS_DIG },
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1133, .config = ALC880_ASUS },
@@ -2093,7 +2095,7 @@
 	int board_config;
 	int i, err;
 
-	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL)
 		return -ENOMEM;
 
@@ -2365,7 +2367,7 @@
 	struct alc_spec *spec;
 	int board_config;
 
-	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL)
 		return -ENOMEM;
 
@@ -2615,7 +2617,7 @@
 {
 	struct alc_spec *spec;
 
-	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL)
 		return -ENOMEM;
 
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index b0270d1..d014b7b 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -214,6 +214,7 @@
 	info->name = "Si3054 Modem";
 	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = si3054_pcm;
 	info->stream[SNDRV_PCM_STREAM_CAPTURE]  = si3054_pcm;
+	info->is_modem = 1;
 	return 0;
 }
 
@@ -282,7 +283,7 @@
 
 static int patch_si3054(struct hda_codec *codec)
 {
-	struct si3054_spec *spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+	struct si3054_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL)
 		return -ENOMEM;
 	codec->spec = spec;
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 9d503da..33a8ada 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -919,7 +919,7 @@
 	struct sigmatel_spec *spec;
 	int err;
 
-	spec  = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+	spec  = kzalloc(sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL)
 		return -ENOMEM;
 
@@ -957,7 +957,7 @@
 	struct sigmatel_spec *spec;
 	int err;
 
-	spec  = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+	spec  = kzalloc(sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL)
 		return -ENOMEM;
 
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 4405d96..2e0a316 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -1796,7 +1796,7 @@
 	}
 
 	/* to remeber the register values of CS8415 */
-	ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
+	ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL);
 	if (! ice->akm)
 		return -ENOMEM;
 	ice->akm_codecs = 1;
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index b97f50d..a6d9801 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -100,12 +100,6 @@
 module_param_array(model, charp, NULL, 0444);
 MODULE_PARM_DESC(model, "Use the given board model.");
 
-#ifndef PCI_VENDOR_ID_ICE
-#define PCI_VENDOR_ID_ICE		0x1412
-#endif
-#ifndef PCI_DEVICE_ID_ICE_1712
-#define PCI_DEVICE_ID_ICE_1712		0x1712
-#endif
 
 static struct pci_device_id snd_ice1712_ids[] = {
 	{ PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_ICE_1712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },   /* ICE1712 */
@@ -2535,7 +2529,7 @@
 		return -ENXIO;
 	}
 
-	ice = kcalloc(1, sizeof(*ice), GFP_KERNEL);
+	ice = kzalloc(sizeof(*ice), GFP_KERNEL);
 	if (ice == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -2741,6 +2735,7 @@
 
 static struct pci_driver driver = {
 	.name = "ICE1712",
+	.owner = THIS_MODULE,
 	.id_table = snd_ice1712_ids,
 	.probe = snd_ice1712_probe,
 	.remove = __devexit_p(snd_ice1712_remove),
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index c7af5e5..c3ce8f9 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -83,12 +83,6 @@
 module_param_array(model, charp, NULL, 0444);
 MODULE_PARM_DESC(model, "Use the given board model.");
 
-#ifndef PCI_VENDOR_ID_ICE
-#define PCI_VENDOR_ID_ICE		0x1412
-#endif
-#ifndef PCI_DEVICE_ID_VT1724
-#define PCI_DEVICE_ID_VT1724		0x1724
-#endif
 
 /* Both VT1720 and VT1724 have the same PCI IDs */
 static struct pci_device_id snd_vt1724_ids[] = {
@@ -2130,7 +2124,7 @@
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
 
-	ice = kcalloc(1, sizeof(*ice), GFP_KERNEL);
+	ice = kzalloc(sizeof(*ice), GFP_KERNEL);
 	if (ice == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -2321,6 +2315,7 @@
 
 static struct pci_driver driver = {
 	.name = "ICE1724",
+	.owner = THIS_MODULE,
 	.id_table = snd_vt1724_ids,
 	.probe = snd_vt1724_probe,
 	.remove = __devexit_p(snd_vt1724_remove),
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
index 3fb297b9..2437876 100644
--- a/sound/pci/ice1712/juli.c
+++ b/sound/pci/ice1712/juli.c
@@ -182,7 +182,7 @@
 		ice->num_total_dacs = 2;
 		ice->num_total_adcs = 2;
 
-		ak = ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
+		ak = ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL);
 		if (! ak)
 			return -ENOMEM;
 		ice->akm_codecs = 1;
diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c
index 5bf734b..dcf1e8c 100644
--- a/sound/pci/ice1712/phase.c
+++ b/sound/pci/ice1712/phase.c
@@ -122,7 +122,7 @@
 	}
 
 	// Initialize analog chips
-	ak = ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
+	ak = ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL);
 	if (! ak)
 		return -ENOMEM;
 	ice->akm_codecs = 1;
@@ -386,7 +386,7 @@
 	ice->num_total_adcs = 2;
 
 	// Initialize analog chips
-	ak = ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
+	ak = ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL);
 	if (!ak)
 		return -ENOMEM;
 	ice->akm_codecs = 1;
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
index 25f827d..a5f852b 100644
--- a/sound/pci/ice1712/pontis.c
+++ b/sound/pci/ice1712/pontis.c
@@ -781,7 +781,7 @@
 	ice->num_total_adcs = 2;
 
 	/* to remeber the register values */
-	ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
+	ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL);
 	if (! ice->akm)
 		return -ENOMEM;
 	ice->akm_codecs = 1;
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 7b54841..1a96198 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -69,6 +69,7 @@
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
 static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
 static char *ac97_quirk[SNDRV_CARDS];
+static int buggy_semaphore[SNDRV_CARDS];
 static int buggy_irq[SNDRV_CARDS];
 static int xbox[SNDRV_CARDS];
 
@@ -86,6 +87,8 @@
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
 module_param_array(ac97_quirk, charp, NULL, 0444);
 MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
+module_param_array(buggy_semaphore, bool, NULL, 0444);
+MODULE_PARM_DESC(buggy_semaphore, "Enable workaround for hardwares with problematic codec semaphores.");
 module_param_array(buggy_irq, bool, NULL, 0444);
 MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards.");
 module_param_array(xbox, bool, NULL, 0444);
@@ -94,62 +97,6 @@
 /*
  *  Direct registers
  */
-
-#ifndef PCI_DEVICE_ID_INTEL_82801
-#define PCI_DEVICE_ID_INTEL_82801       0x2415
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_82901
-#define PCI_DEVICE_ID_INTEL_82901       0x2425
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_82801BA
-#define PCI_DEVICE_ID_INTEL_82801BA     0x2445
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_440MX
-#define PCI_DEVICE_ID_INTEL_440MX       0x7195
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ICH3
-#define PCI_DEVICE_ID_INTEL_ICH3	0x2485
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ICH4
-#define PCI_DEVICE_ID_INTEL_ICH4	0x24c5
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ICH5
-#define PCI_DEVICE_ID_INTEL_ICH5	0x24d5
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ESB_5
-#define PCI_DEVICE_ID_INTEL_ESB_5	0x25a6
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ICH6_18
-#define PCI_DEVICE_ID_INTEL_ICH6_18	0x266e
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ICH7_20
-#define PCI_DEVICE_ID_INTEL_ICH7_20	0x27de
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ESB2_14
-#define PCI_DEVICE_ID_INTEL_ESB2_14	0x2698
-#endif
-#ifndef PCI_DEVICE_ID_SI_7012
-#define PCI_DEVICE_ID_SI_7012		0x7012
-#endif
-#ifndef PCI_DEVICE_ID_NVIDIA_MCP_AUDIO
-#define PCI_DEVICE_ID_NVIDIA_MCP_AUDIO	0x01b1
-#endif
-#ifndef PCI_DEVICE_ID_NVIDIA_CK804_AUDIO
-#define PCI_DEVICE_ID_NVIDIA_CK804_AUDIO 0x0059
-#endif
-#ifndef PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO
-#define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO	0x006a
-#endif
-#ifndef PCI_DEVICE_ID_NVIDIA_CK8_AUDIO
-#define PCI_DEVICE_ID_NVIDIA_CK8_AUDIO	0x008a
-#endif
-#ifndef PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO
-#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO	0x00da
-#endif
-#ifndef PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO
-#define PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO	0x00ea
-#endif
-
 enum { DEVICE_INTEL, DEVICE_INTEL_ICH4, DEVICE_SIS, DEVICE_ALI, DEVICE_NFORCE };
 
 #define ICHREG(x) ICH_REG_##x
@@ -423,6 +370,7 @@
 	unsigned fix_nocache: 1; 	/* workaround for 440MX */
 	unsigned buggy_irq: 1;		/* workaround for buggy mobos */
 	unsigned xbox: 1;		/* workaround for Xbox AC'97 detection */
+	unsigned buggy_semaphore: 1;	/* workaround for buggy codec semaphore */
 
 	int spdif_idx;	/* SPDIF BAR index; *_SPBAR or -1 if use PCMOUT */
 	unsigned int sdm_saved;	/* SDM reg value */
@@ -577,6 +525,9 @@
 	if ((igetdword(chip, ICHREG(GLOB_STA)) & codec) == 0)
 		return -EIO;
 
+	if (chip->buggy_semaphore)
+		return 0; /* just ignore ... */
+
 	/* Anyone holding a semaphore for 1 msec should be shot... */
 	time = 100;
       	do {
@@ -1759,6 +1710,12 @@
 		.type = AC97_TUNE_ALC_JACK
 	},
 	{
+		.subvendor = 0x1014,
+		.subdevice = 0x0267,
+		.name = "IBM NetVista A30p",	/* AD1981B */
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
 		.subvendor = 0x1028,
 		.subdevice = 0x00d8,
 		.name = "Dell Precision 530",	/* AD1885 */
@@ -2599,6 +2556,7 @@
 static int __devinit snd_intel8x0_create(snd_card_t * card,
 					 struct pci_dev *pci,
 					 unsigned long device_type,
+					 int buggy_sem,
 					 intel8x0_t ** r_intel8x0)
 {
 	intel8x0_t *chip;
@@ -2646,7 +2604,7 @@
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -2656,6 +2614,7 @@
 	chip->card = card;
 	chip->pci = pci;
 	chip->irq = -1;
+	chip->buggy_semaphore = buggy_sem;
 
 	if (pci->vendor == PCI_VENDOR_ID_INTEL &&
 	    pci->device == PCI_DEVICE_ID_INTEL_440MX)
@@ -2795,19 +2754,19 @@
 	unsigned int id;
 	const char *s;
 } shortnames[] __devinitdata = {
-	{ PCI_DEVICE_ID_INTEL_82801, "Intel 82801AA-ICH" },
-	{ PCI_DEVICE_ID_INTEL_82901, "Intel 82901AB-ICH0" },
-	{ PCI_DEVICE_ID_INTEL_82801BA, "Intel 82801BA-ICH2" },
+	{ PCI_DEVICE_ID_INTEL_82801AA_5, "Intel 82801AA-ICH" },
+	{ PCI_DEVICE_ID_INTEL_82801AB_5, "Intel 82901AB-ICH0" },
+	{ PCI_DEVICE_ID_INTEL_82801BA_4, "Intel 82801BA-ICH2" },
 	{ PCI_DEVICE_ID_INTEL_440MX, "Intel 440MX" },
-	{ PCI_DEVICE_ID_INTEL_ICH3, "Intel 82801CA-ICH3" },
-	{ PCI_DEVICE_ID_INTEL_ICH4, "Intel 82801DB-ICH4" },
-	{ PCI_DEVICE_ID_INTEL_ICH5, "Intel ICH5" },
+	{ PCI_DEVICE_ID_INTEL_82801CA_5, "Intel 82801CA-ICH3" },
+	{ PCI_DEVICE_ID_INTEL_82801DB_5, "Intel 82801DB-ICH4" },
+	{ PCI_DEVICE_ID_INTEL_82801EB_5, "Intel ICH5" },
 	{ PCI_DEVICE_ID_INTEL_ESB_5, "Intel 6300ESB" },
 	{ PCI_DEVICE_ID_INTEL_ICH6_18, "Intel ICH6" },
 	{ PCI_DEVICE_ID_INTEL_ICH7_20, "Intel ICH7" },
 	{ PCI_DEVICE_ID_INTEL_ESB2_14, "Intel ESB2" },
 	{ PCI_DEVICE_ID_SI_7012, "SiS SI7012" },
-	{ PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia nForce" },
+	{ PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO, "NVidia nForce" },
 	{ PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO, "NVidia nForce2" },
 	{ PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO, "NVidia nForce3" },
 	{ PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO, "NVidia CK8S" },
@@ -2860,7 +2819,8 @@
 		}
 	}
 
-	if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data, &chip)) < 0) {
+	if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data,
+				       buggy_semaphore[dev], &chip)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
@@ -2904,6 +2864,7 @@
 
 static struct pci_driver driver = {
 	.name = "Intel ICH",
+	.owner = THIS_MODULE,
 	.id_table = snd_intel8x0_ids,
 	.probe = snd_intel8x0_probe,
 	.remove = __devexit_p(snd_intel8x0_remove),
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index bb758c7..9e2060d 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -73,51 +73,6 @@
 /*
  *  Direct registers
  */
-
-#ifndef PCI_DEVICE_ID_INTEL_82801_6
-#define PCI_DEVICE_ID_INTEL_82801_6     0x2416
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_82901_6
-#define PCI_DEVICE_ID_INTEL_82901_6     0x2426
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_82801BA_6
-#define PCI_DEVICE_ID_INTEL_82801BA_6   0x2446
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_440MX_6
-#define PCI_DEVICE_ID_INTEL_440MX_6     0x7196
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ICH3_6
-#define PCI_DEVICE_ID_INTEL_ICH3_6	0x2486
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ICH4_6
-#define PCI_DEVICE_ID_INTEL_ICH4_6	0x24c6
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ICH5_6
-#define PCI_DEVICE_ID_INTEL_ICH5_6	0x24d6
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ICH6_6
-#define PCI_DEVICE_ID_INTEL_ICH6_6	0x266d
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ICH7_6
-#define PCI_DEVICE_ID_INTEL_ICH7_6	0x27dd
-#endif
-#ifndef PCI_DEVICE_ID_SI_7013
-#define PCI_DEVICE_ID_SI_7013		0x7013
-#endif
-#ifndef PCI_DEVICE_ID_NVIDIA_MCP_MODEM
-#define PCI_DEVICE_ID_NVIDIA_MCP_MODEM	0x01c1
-#endif
-#ifndef PCI_DEVICE_ID_NVIDIA_MCP2_MODEM
-#define PCI_DEVICE_ID_NVIDIA_MCP2_MODEM	0x0069
-#endif
-#ifndef PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM
-#define PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM 0x0089
-#endif
-#ifndef PCI_DEVICE_ID_NVIDIA_MCP3_MODEM
-#define PCI_DEVICE_ID_NVIDIA_MCP3_MODEM	0x00d9
-#endif
-
-
 enum { DEVICE_INTEL, DEVICE_SIS, DEVICE_ALI, DEVICE_NFORCE };
 
 #define ICHREG(x) ICH_REG_##x
@@ -1158,7 +1113,7 @@
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -1283,18 +1238,18 @@
 	unsigned int id;
 	const char *s;
 } shortnames[] __devinitdata = {
-	{ PCI_DEVICE_ID_INTEL_82801_6, "Intel 82801AA-ICH" },
-	{ PCI_DEVICE_ID_INTEL_82901_6, "Intel 82901AB-ICH0" },
+	{ PCI_DEVICE_ID_INTEL_82801AA_6, "Intel 82801AA-ICH" },
+	{ PCI_DEVICE_ID_INTEL_82801AB_6, "Intel 82901AB-ICH0" },
 	{ PCI_DEVICE_ID_INTEL_82801BA_6, "Intel 82801BA-ICH2" },
 	{ PCI_DEVICE_ID_INTEL_440MX_6, "Intel 440MX" },
-	{ PCI_DEVICE_ID_INTEL_ICH3_6, "Intel 82801CA-ICH3" },
-	{ PCI_DEVICE_ID_INTEL_ICH4_6, "Intel 82801DB-ICH4" },
-	{ PCI_DEVICE_ID_INTEL_ICH5_6, "Intel ICH5" },
-	{ PCI_DEVICE_ID_INTEL_ICH6_6, "Intel ICH6" },
-	{ PCI_DEVICE_ID_INTEL_ICH7_6, "Intel ICH7" },
+	{ PCI_DEVICE_ID_INTEL_82801CA_6, "Intel 82801CA-ICH3" },
+	{ PCI_DEVICE_ID_INTEL_82801DB_6, "Intel 82801DB-ICH4" },
+	{ PCI_DEVICE_ID_INTEL_82801EB_6, "Intel ICH5" },
+	{ PCI_DEVICE_ID_INTEL_ICH6_17, "Intel ICH6" },
+	{ PCI_DEVICE_ID_INTEL_ICH7_19, "Intel ICH7" },
 	{ 0x7446, "AMD AMD768" },
 	{ PCI_DEVICE_ID_SI_7013, "SiS SI7013" },
-	{ PCI_DEVICE_ID_NVIDIA_MCP_MODEM, "NVidia nForce" },
+	{ PCI_DEVICE_ID_NVIDIA_MCP1_MODEM, "NVidia nForce" },
 	{ PCI_DEVICE_ID_NVIDIA_MCP2_MODEM, "NVidia nForce2" },
 	{ PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM, "NVidia nForce2s" },
 	{ PCI_DEVICE_ID_NVIDIA_MCP3_MODEM, "NVidia nForce3" },
@@ -1371,6 +1326,7 @@
 
 static struct pci_driver driver = {
 	.name = "Intel ICH Modem",
+	.owner = THIS_MODULE,
 	.id_table = snd_intel8x0m_ids,
 	.probe = snd_intel8x0m_probe,
 	.remove = __devexit_p(snd_intel8x0m_remove),
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index d2aa9c8..09f9cbe 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -2220,7 +2220,7 @@
         if ((err = pci_enable_device(pci)) < 0)
                 return err;
 
-        korg1212 = kcalloc(1, sizeof(*korg1212), GFP_KERNEL);
+        korg1212 = kzalloc(sizeof(*korg1212), GFP_KERNEL);
         if (korg1212 == NULL) {
 		pci_disable_device(pci);
                 return -ENOMEM;
@@ -2534,6 +2534,7 @@
 
 static struct pci_driver driver = {
 	.name = "korg1212",
+	.owner = THIS_MODULE,
 	.id_table = snd_korg1212_ids,
 	.probe = snd_korg1212_probe,
 	.remove = __devexit_p(snd_korg1212_remove),
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 39b5e7d..2693b6f 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -872,35 +872,6 @@
 /*
  * pci ids
  */
-
-#ifndef PCI_VENDOR_ID_ESS
-#define PCI_VENDOR_ID_ESS         0x125D
-#endif
-#ifndef PCI_DEVICE_ID_ESS_ALLEGRO_1
-#define PCI_DEVICE_ID_ESS_ALLEGRO_1	0x1988
-#endif
-#ifndef PCI_DEVICE_ID_ESS_ALLEGRO
-#define PCI_DEVICE_ID_ESS_ALLEGRO	0x1989
-#endif
-#ifndef PCI_DEVICE_ID_ESS_CANYON3D_2LE
-#define PCI_DEVICE_ID_ESS_CANYON3D_2LE	0x1990
-#endif
-#ifndef PCI_DEVICE_ID_ESS_CANYON3D_2
-#define PCI_DEVICE_ID_ESS_CANYON3D_2	0x1992
-#endif
-#ifndef PCI_DEVICE_ID_ESS_MAESTRO3
-#define PCI_DEVICE_ID_ESS_MAESTRO3	0x1998
-#endif
-#ifndef PCI_DEVICE_ID_ESS_MAESTRO3_1
-#define PCI_DEVICE_ID_ESS_MAESTRO3_1	0x1999
-#endif
-#ifndef PCI_DEVICE_ID_ESS_MAESTRO3_HW
-#define PCI_DEVICE_ID_ESS_MAESTRO3_HW	0x199a
-#endif
-#ifndef PCI_DEVICE_ID_ESS_MAESTRO3_2
-#define PCI_DEVICE_ID_ESS_MAESTRO3_2	0x199b
-#endif
-
 static struct pci_device_id snd_m3_ids[] = {
 	{PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO_1, PCI_ANY_ID, PCI_ANY_ID,
 	 PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
@@ -2689,7 +2660,7 @@
 		return -ENXIO;
 	}
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -2890,6 +2861,7 @@
 
 static struct pci_driver driver = {
 	.name = "Maestro3",
+	.owner = THIS_MODULE,
 	.id_table = snd_m3_ids,
 	.probe = snd_m3_probe,
 	.remove = __devexit_p(snd_m3_remove),
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 6c868d9..1a62c7f 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -1004,7 +1004,7 @@
 		.dev_free = snd_mixart_chip_dev_free,
 	};
 
-	mgr->chip[idx] = chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	mgr->chip[idx] = chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (! chip) {
 		snd_printk(KERN_ERR "cannot allocate chip\n");
 		return -ENOMEM;
@@ -1292,7 +1292,7 @@
 
 	/*
 	 */
-	mgr = kcalloc(1, sizeof(*mgr), GFP_KERNEL);
+	mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
 	if (! mgr) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -1424,6 +1424,7 @@
 
 static struct pci_driver driver = {
 	.name = "Digigram miXart",
+	.owner = THIS_MODULE,
 	.id_table = snd_mixart_ids,
 	.probe = snd_mixart_probe,
 	.remove = __devexit_p(snd_mixart_remove),
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 2bbeb10..5c55a3b 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -259,21 +259,6 @@
 /*
  * PCI ids
  */
-
-#ifndef PCI_VENDOR_ID_NEOMAGIC
-#define PCI_VENDOR_ID_NEOMEGIC 0x10c8
-#endif
-#ifndef PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO
-#define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005
-#endif
-#ifndef PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO
-#define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006
-#endif
-#ifndef PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO
-#define PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO 0x8016
-#endif
-
-
 static struct pci_device_id snd_nm256_ids[] = {
 	{PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
@@ -840,7 +825,7 @@
 	runtime->hw = *hw_ptr;
 	runtime->hw.buffer_bytes_max = s->bufsize;
 	runtime->hw.period_bytes_max = s->bufsize / 2;
-	runtime->dma_area = (void*) s->bufptr;
+	runtime->dma_area = (void __force *) s->bufptr;
 	runtime->dma_addr = s->bufptr_addr;
 	runtime->dma_bytes = s->bufsize;
 	runtime->private_data = s;
@@ -1404,7 +1389,7 @@
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -1683,6 +1668,7 @@
 
 static struct pci_driver driver = {
 	.name = "NeoMagic 256",
+	.owner = THIS_MODULE,
 	.id_table = snd_nm256_ids,
 	.probe = snd_nm256_probe,
 	.remove = __devexit_p(snd_nm256_remove),
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index 456be39..3daeecb 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -192,20 +192,6 @@
 #define RME32_PRO_REVISION_WITH_8414 150
 
 
-/* PCI vendor/device ID's */
-#ifndef PCI_VENDOR_ID_XILINX_RME
-# define PCI_VENDOR_ID_XILINX_RME 0xea60
-#endif
-#ifndef PCI_DEVICE_ID_DIGI32
-# define PCI_DEVICE_ID_DIGI32 0x9896
-#endif
-#ifndef PCI_DEVICE_ID_DIGI32_PRO
-# define PCI_DEVICE_ID_DIGI32_PRO 0x9897
-#endif
-#ifndef PCI_DEVICE_ID_DIGI32_8
-# define PCI_DEVICE_ID_DIGI32_8 0x9898
-#endif
-
 typedef struct snd_rme32 {
 	spinlock_t lock;
 	int irq;
@@ -692,7 +678,8 @@
 		if (err < 0)
 			return err;
 	} else {
-		runtime->dma_area = (void *)(rme32->iobase + RME32_IO_DATA_BUFFER);
+		runtime->dma_area = (void __force *)(rme32->iobase +
+						     RME32_IO_DATA_BUFFER);
 		runtime->dma_addr = rme32->port + RME32_IO_DATA_BUFFER;
 		runtime->dma_bytes = RME32_BUFFER_SIZE;
 	}
@@ -746,7 +733,8 @@
 		if (err < 0)
 			return err;
 	} else {
-		runtime->dma_area = (void *)rme32->iobase + RME32_IO_DATA_BUFFER;
+		runtime->dma_area = (void __force *)rme32->iobase +
+					RME32_IO_DATA_BUFFER;
 		runtime->dma_addr = rme32->port + RME32_IO_DATA_BUFFER;
 		runtime->dma_bytes = RME32_BUFFER_SIZE;
 	}
@@ -2024,6 +2012,7 @@
 
 static struct pci_driver driver = {
 	.name =		"RME Digi32",
+	.owner =	THIS_MODULE,
 	.id_table =	snd_rme32_ids,
 	.probe =	snd_rme32_probe,
 	.remove =	__devexit_p(snd_rme32_remove),
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 9645e90..9983b66 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -200,25 +200,6 @@
 #define RME96_AD1852_VOL_BITS 14
 #define RME96_AD1855_VOL_BITS 10
 
-/*
- * PCI vendor/device ids, could in the future be defined in <linux/pci.h>,
- * therefore #ifndef is used.
- */
-#ifndef PCI_VENDOR_ID_XILINX
-#define PCI_VENDOR_ID_XILINX 0x10ee
-#endif
-#ifndef PCI_DEVICE_ID_DIGI96
-#define PCI_DEVICE_ID_DIGI96 0x3fc0
-#endif
-#ifndef PCI_DEVICE_ID_DIGI96_8
-#define PCI_DEVICE_ID_DIGI96_8 0x3fc1
-#endif
-#ifndef PCI_DEVICE_ID_DIGI96_8_PRO
-#define PCI_DEVICE_ID_DIGI96_8_PRO 0x3fc2
-#endif
-#ifndef PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST
-#define PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST 0x3fc3
-#endif
 
 typedef struct snd_rme96 {
 	spinlock_t    lock;
@@ -985,7 +966,8 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	int err, rate, dummy;
 
-	runtime->dma_area = (void *)(rme96->iobase + RME96_IO_PLAY_BUFFER);
+	runtime->dma_area = (void __force *)(rme96->iobase +
+					     RME96_IO_PLAY_BUFFER);
 	runtime->dma_addr = rme96->port + RME96_IO_PLAY_BUFFER;
 	runtime->dma_bytes = RME96_BUFFER_SIZE;
 
@@ -1037,7 +1019,8 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	int err, isadat, rate;
 	
-	runtime->dma_area = (void *)(rme96->iobase + RME96_IO_REC_BUFFER);
+	runtime->dma_area = (void __force *)(rme96->iobase +
+					     RME96_IO_REC_BUFFER);
 	runtime->dma_addr = rme96->port + RME96_IO_REC_BUFFER;
 	runtime->dma_bytes = RME96_BUFFER_SIZE;
 
@@ -2430,6 +2413,7 @@
 
 static struct pci_driver driver = {
 	.name = "RME Digi96",
+	.owner = THIS_MODULE,
 	.id_table = snd_rme96_ids,
 	.probe = snd_rme96_probe,
 	.remove = __devexit_p(snd_rme96_remove),
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 6694866..52525eb 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -370,13 +370,6 @@
 #define UNITY_GAIN                       32768
 #define MINUS_INFINITY_GAIN              0
 
-#ifndef PCI_VENDOR_ID_XILINX
-#define PCI_VENDOR_ID_XILINX		0x10ee
-#endif
-#ifndef PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP
-#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5
-#endif
-
 /* the size of a substream (1 mono data stream) */
 
 #define HDSP_CHANNEL_BUFFER_SAMPLES  (16*1024)
@@ -4899,6 +4892,7 @@
 	}
 	
 	if (!(hdsp->state & HDSP_InitializationComplete)) {
+		strcpy(card->shortname, "Hammerfall DSP");
 		sprintf(card->longname, "%s at 0x%lx, irq %d", hdsp->card_name, 
 			hdsp->port, hdsp->irq);
 	    
@@ -5222,6 +5216,7 @@
 
 static struct pci_driver driver = {
 	.name =     "RME Hammerfall DSP",
+	.owner =    THIS_MODULE,
 	.id_table = snd_hdsp_ids,
 	.probe =    snd_hdsp_probe,
 	.remove = __devexit_p(snd_hdsp_remove),
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 5d786d1..fc3f328 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -301,18 +301,6 @@
 #define UNITY_GAIN          32768	/* = 65536/2 */
 #define MINUS_INFINITY_GAIN 0
 
-/* PCI info */
-#ifndef PCI_VENDOR_ID_XILINX
-#define PCI_VENDOR_ID_XILINX		0x10ee
-#endif
-#ifndef PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP
-#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5
-#endif
-#ifndef PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI
-#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI 0x3fc6
-#endif
-
-
 /* Number of channels for different Speed Modes */
 #define MADI_SS_CHANNELS       64
 #define MADI_DS_CHANNELS       32
@@ -3652,6 +3640,7 @@
 
 static struct pci_driver driver = {
 	.name = "RME Hammerfall DSP MADI",
+	.owner = THIS_MODULE,
 	.id_table = snd_hdspm_ids,
 	.probe = snd_hdspm_probe,
 	.remove = __devexit_p(snd_hdspm_remove),
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index 8ee4d6f..b600f45 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -120,13 +120,6 @@
 
 #define RME9652_REV15_buf_pos(x) ((((x)&0xE0000000)>>26)|((x)&RME9652_buf_pos))
 
-#ifndef PCI_VENDOR_ID_XILINX
-#define PCI_VENDOR_ID_XILINX		0x10ee
-#endif
-#ifndef PCI_DEVICE_ID_XILINX_HAMMERFALL
-#define PCI_DEVICE_ID_XILINX_HAMMERFALL	0x3fc4
-#endif
-
 /* amount of io space we remap for register access. i'm not sure we
    even need this much, but 1K is nice round number :)
 */
@@ -2661,6 +2654,7 @@
 
 static struct pci_driver driver = {
 	.name	  = "RME Digi9652 (Hammerfall)",
+	.owner	  = THIS_MODULE,
 	.id_table = snd_rme9652_ids,
 	.probe	  = snd_rme9652_probe,
 	.remove	  = __devexit_p(snd_rme9652_remove),
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 60ecb2b..1f6c2bf 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -50,13 +50,6 @@
 #define SUPPORT_JOYSTICK 1
 #endif
 
-#ifndef PCI_VENDOR_ID_S3
-#define PCI_VENDOR_ID_S3             0x5333
-#endif
-#ifndef PCI_DEVICE_ID_S3_SONICVIBES
-#define PCI_DEVICE_ID_S3_SONICVIBES  0xca00
-#endif
-
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
@@ -1257,7 +1250,7 @@
                 return -ENXIO;
         }
 
-	sonic = kcalloc(1, sizeof(*sonic), GFP_KERNEL);
+	sonic = kzalloc(sizeof(*sonic), GFP_KERNEL);
 	if (sonic == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -1515,6 +1508,7 @@
 
 static struct pci_driver driver = {
 	.name = "S3 SonicVibes",
+	.owner = THIS_MODULE,
 	.id_table = snd_sonic_ids,
 	.probe = snd_sonic_probe,
 	.remove = __devexit_p(snd_sonic_remove),
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index 940d531..a8ca8e1 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -177,6 +177,7 @@
 
 static struct pci_driver driver = {
 	.name = "Trident4DWaveAudio",
+	.owner = THIS_MODULE,
 	.id_table = snd_trident_ids,
 	.probe = snd_trident_probe,
 	.remove = __devexit_p(snd_trident_remove),
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index f30d9d9..777da9a 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -2960,7 +2960,7 @@
 		.read = snd_trident_codec_read,
 	};
 
-	uctl = kcalloc(1, sizeof(*uctl), GFP_KERNEL);
+	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 	if (!uctl)
 		return -ENOMEM;
 
@@ -3546,7 +3546,7 @@
 		return -ENXIO;
 	}
 	
-	trident = kcalloc(1, sizeof(*trident), GFP_KERNEL);
+	trident = kzalloc(sizeof(*trident), GFP_KERNEL);
 	if (trident == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 56c6e52..6db7de6 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -104,14 +104,6 @@
 MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA, 5 = enable any sample rate)");
 
 
-/* pci ids */
-#ifndef PCI_DEVICE_ID_VIA_82C686_5
-#define PCI_DEVICE_ID_VIA_82C686_5	0x3058
-#endif
-#ifndef PCI_DEVICE_ID_VIA_8233_5
-#define PCI_DEVICE_ID_VIA_8233_5	0x3059
-#endif
-
 /* revision numbers for via686 */
 #define VIA_REV_686_A		0x10
 #define VIA_REV_686_B		0x11
@@ -1935,11 +1927,12 @@
 		 * DXS channels don't work properly with VRA if MC97 is disabled.
 		 */
 		struct pci_dev *pci;
-		pci = pci_find_device(0x1106, 0x3068, NULL); /* MC97 */
+		pci = pci_get_device(0x1106, 0x3068, NULL); /* MC97 */
 		if (pci) {
 			unsigned char data;
 			pci_read_config_byte(pci, 0x44, &data);
 			pci_write_config_byte(pci, 0x44, data | 0x40);
+			pci_dev_put(pci);
 		}
 	}
 
@@ -2065,7 +2058,7 @@
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
 
-	if ((chip = kcalloc(1, sizeof(*chip), GFP_KERNEL)) == NULL) {
+	if ((chip = kzalloc(sizeof(*chip), GFP_KERNEL)) == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
 	}
@@ -2350,6 +2343,7 @@
 
 static struct pci_driver driver = {
 	.name = "VIA 82xx Audio",
+	.owner = THIS_MODULE,
 	.id_table = snd_via82xx_ids,
 	.probe = snd_via82xx_probe,
 	.remove = __devexit_p(snd_via82xx_remove),
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 5872d43..7eac6f6 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -1083,7 +1083,7 @@
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
 
-	if ((chip = kcalloc(1, sizeof(*chip), GFP_KERNEL)) == NULL) {
+	if ((chip = kzalloc(sizeof(*chip), GFP_KERNEL)) == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
 	}
@@ -1207,6 +1207,7 @@
 
 static struct pci_driver driver = {
 	.name = "VIA 82xx Modem",
+	.owner = THIS_MODULE,
 	.id_table = snd_via82xx_modem_ids,
 	.probe = snd_via82xx_probe,
 	.remove = __devexit_p(snd_via82xx_remove),
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index dca6bd2..2a7ad9d 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -252,6 +252,7 @@
 
 static struct pci_driver driver = {
 	.name = "Digigram VX222",
+	.owner = THIS_MODULE,
 	.id_table = snd_vx222_ids,
 	.probe = snd_vx222_probe,
 	.remove = __devexit_p(snd_vx222_remove),
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index 5b5b624..2e69abe 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -352,6 +352,7 @@
 
 static struct pci_driver driver = {
 	.name = "Yamaha DS-XG PCI",
+	.owner = THIS_MODULE,
 	.id_table = snd_ymfpci_ids,
 	.probe = snd_card_ymfpci_probe,
 	.remove = __devexit_p(snd_card_ymfpci_remove),
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 0548364..27fa523 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -839,7 +839,7 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	ymfpci_pcm_t *ypcm;
 
-	ypcm = kcalloc(1, sizeof(*ypcm), GFP_KERNEL);
+	ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL);
 	if (ypcm == NULL)
 		return -ENOMEM;
 	ypcm->chip = chip;
@@ -957,7 +957,7 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	ymfpci_pcm_t *ypcm;
 
-	ypcm = kcalloc(1, sizeof(*ypcm), GFP_KERNEL);
+	ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL);
 	if (ypcm == NULL)
 		return -ENOMEM;
 	ypcm->chip = chip;
@@ -2270,7 +2270,7 @@
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL) {
 		pci_disable_device(pci);
 		return -ENOMEM;
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
index a2132e3..0208c54 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
@@ -151,7 +151,7 @@
 {
 	pdacf_t *chip;
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL)
 		return NULL;
 	chip->card = card;
diff --git a/sound/ppc/Kconfig b/sound/ppc/Kconfig
index 75213bf..206b933 100644
--- a/sound/ppc/Kconfig
+++ b/sound/ppc/Kconfig
@@ -13,11 +13,24 @@
 	tristate "PowerMac (AWACS, DACA, Burgundy, Tumbler, Keywest)"
 	depends on SND && I2C && INPUT && PPC_PMAC
 	select SND_PCM
+	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for the integrated sound device.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-powermac.
 
-endmenu
+config SND_POWERMAC_AUTO_DRC
+	bool "Toggle DRC automatically at headphone/line plug-in"
+	depends on SND_POWERMAC
+	default y
+	help
+	  Say Y here to enable the automatic toggle of DRC (dynamic
+	  range compression) on Tumbler/Snapper.
+	  If this feature is enabled, DRC is turned off when the
+	  headphone/line jack is plugged, and turned on when unplugged.
 
+	  Note that you can turn on/off DRC manually even without this
+	  option.
+
+endmenu
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index c89e82e..e35b48d 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -988,6 +988,7 @@
 		case 0x33:
 		case 0x29:
 		case 0x24:
+		case 0x5c:
 			chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
 			chip->model = PMAC_SNAPPER;
 			chip->can_byte_swap = 0; /* FIXME: check this */
@@ -1159,7 +1160,7 @@
 	snd_runtime_check(chip_return, return -EINVAL);
 	*chip_return = NULL;
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL)
 		return -ENOMEM;
 	chip->card = card;
diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c
index 231f643..a6d8cbf 100644
--- a/sound/ppc/powermac.c
+++ b/sound/ppc/powermac.c
@@ -131,6 +131,9 @@
 	if (enable_beep)
 		snd_pmac_attach_beep(chip);
 
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto __error;
+
 	if ((err = snd_card_register(card)) < 0)
 		goto __error;
 
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index b94437c..65384af 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -948,7 +948,6 @@
 			msleep(10);
 		check_mute(chip, &mix->amp_mute, 1, mix->auto_mute_notify,
 			   chip->speaker_sw_ctl);
-		mix->drc_enable = 0;
 	} else {
 		/* unmute speaker, mute others */
 		check_mute(chip, &mix->amp_mute, 0, mix->auto_mute_notify,
@@ -960,20 +959,21 @@
 		if (mix->line_mute.addr != 0)
 			check_mute(chip, &mix->line_mute, 1, mix->auto_mute_notify,
 				   chip->lineout_sw_ctl);
-		mix->drc_enable = 1;
 	}
-	if (mix->auto_mute_notify) {
+	if (mix->auto_mute_notify)
 		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
 				       &chip->hp_detect_ctl->id);
+
+#ifdef CONFIG_SND_POWERMAC_AUTO_DRC
+	mix->drc_enable = ! (headphone || lineout);
+	if (mix->auto_mute_notify)
 		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
 			       &chip->drc_sw_ctl->id);
-	}
-
-	/* first set the DRC so the speaker do not explode -ReneR */
 	if (chip->model == PMAC_TUMBLER)
 		tumbler_set_drc(mix);
 	else
 		snapper_set_drc(mix);
+#endif
 
 	/* reset the master volume so the correct amplification is applied */
 	tumbler_set_master_volume(mix);
@@ -1370,6 +1370,17 @@
 	if ((err = snd_ctl_add(chip->card, chip->drc_sw_ctl)) < 0)
 		return err;
 
+	/* set initial DRC range to 60% */
+	if (chip->model == PMAC_TUMBLER)
+		mix->drc_range = (TAS3001_DRC_MAX * 6) / 10;
+	else
+		mix->drc_range = (TAS3004_DRC_MAX * 6) / 10;
+	mix->drc_enable = 1; /* will be changed later if AUTO_DRC is set */
+	if (chip->model == PMAC_TUMBLER)
+		tumbler_set_drc(mix);
+	else
+		snapper_set_drc(mix);
+
 #ifdef CONFIG_PM
 	chip->suspend = tumbler_suspend;
 	chip->resume = tumbler_resume;
diff --git a/sound/sparc/Kconfig b/sound/sparc/Kconfig
index 25a8a55..09ab138 100644
--- a/sound/sparc/Kconfig
+++ b/sound/sparc/Kconfig
@@ -7,6 +7,7 @@
 	tristate "Sun AMD7930"
 	depends on SBUS && SND
 	select SND_PCM
+	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for AMD7930 sound device on Sun.
 
@@ -17,6 +18,7 @@
 	tristate "Sun CS4231"
 	depends on SND
 	select SND_PCM
+	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for CS4231 sound device on Sun.
 
@@ -27,6 +29,7 @@
 	tristate "Sun DBRI"
 	depends on SND && SBUS
 	select SND_PCM
+	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for DBRI sound device on Sun.
 
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c
index bd8a850..46d504b 100644
--- a/sound/sparc/amd7930.c
+++ b/sound/sparc/amd7930.c
@@ -967,7 +967,7 @@
 	int err;
 
 	*ramd = NULL;
-	amd = kcalloc(1, sizeof(*amd), GFP_KERNEL);
+	amd = kzalloc(sizeof(*amd), GFP_KERNEL);
 	if (amd == NULL)
 		return -ENOMEM;
 
@@ -1088,6 +1088,9 @@
 	if ((err = snd_amd7930_mixer(amd)) < 0)
 		goto out_err;
 
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto out_err;
+
 	if ((err = snd_card_register(card)) < 0)
 		goto out_err;
 
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index 36f9fe4..2fb27c4 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -1915,6 +1915,9 @@
 	if ((err = snd_cs4231_timer(chip)) < 0)
 		goto out_err;
 
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto out_err;
+
 	if ((err = snd_card_register(card)) < 0)
 		goto out_err;
 
@@ -1966,7 +1969,7 @@
 	int err;
 
 	*rchip = NULL;
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL)
 		return -ENOMEM;
 
@@ -2080,7 +2083,7 @@
 	int err;
 
 	*rchip = NULL;
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL)
 		return -ENOMEM;
 
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 941c7b1..b5c4c15 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -1,6 +1,6 @@
 /*
  * Driver for DBRI sound chip found on Sparcs.
- * Copyright (C) 2004 Martin Habets (mhabets@users.sourceforge.net)
+ * Copyright (C) 2004, 2005 Martin Habets (mhabets@users.sourceforge.net)
  *
  * Based entirely upon drivers/sbus/audio/dbri.c which is:
  * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de)
@@ -43,6 +43,12 @@
  * audio devices. But the SUN HW group decided against it, at least on my
  * LX the speakerbox connector has at least 1 pin missing and 1 wrongly
  * connected.
+ *
+ * I've tried to stick to the following function naming conventions:
+ * snd_*	ALSA stuff
+ * cs4215_*	CS4215 codec specfic stuff
+ * dbri_*	DBRI high-level stuff
+ * other	DBRI low-level stuff
  */
 
 #include <sound/driver.h>
@@ -87,7 +93,7 @@
 #define D_DESC	(1<<5)
 
 static int dbri_debug = 0;
-module_param(dbri_debug, int, 0444);
+module_param(dbri_debug, int, 0644);
 MODULE_PARM_DESC(dbri_debug, "Debug value for Sun DBRI soundcard.");
 
 #ifdef DBRI_DEBUG
@@ -320,7 +326,8 @@
 	void __iomem *regs;	/* dbri HW regs */
 	int dbri_version;	/* 'e' and up is OK */
 	int dbri_irqp;		/* intr queue pointer */
-	int wait_seen;
+	int wait_send;		/* sequence of command buffers send */
+	int wait_ackd;		/* sequence of command buffers acknowledged */
 
 	struct dbri_pipe pipes[DBRI_NO_PIPES];	/* DBRI's 32 data pipes */
 	struct dbri_desc descs[DBRI_NO_DESCS];
@@ -625,16 +632,13 @@
 
 Commands are sent to the DBRI by building a list of them in memory,
 then writing the address of the first list item to DBRI register 8.
-The list is terminated with a WAIT command, which can generate a
-CPU interrupt if required.
+The list is terminated with a WAIT command, which generates a
+CPU interrupt to signal completion.
 
 Since the DBRI can run in parallel with the CPU, several means of
-synchronization present themselves.  The original scheme (Rudolf's)
-was to set a flag when we "cmdlock"ed the DBRI, clear the flag when
-an interrupt signaled completion, and wait on a wait_queue if a routine
-attempted to cmdlock while the flag was set.  The problems arose when
-we tried to cmdlock from inside an interrupt handler, which might
-cause scheduling in an interrupt (if we waited), etc, etc
+synchronization present themselves.  The method implemented here is close
+to the original scheme (Rudolf's), and uses 2 counters (wait_send and
+wait_ackd) to synchronize the command buffer between the CPU and the DBRI.
 
 A more sophisticated scheme might involve a circular command buffer
 or an array of command buffers.  A routine could fill one with
@@ -642,70 +646,75 @@
 completion of the current command buffer, look on the list for
 the next one.
 
-I've decided to implement something much simpler - after each command,
-the CPU waits for the DBRI to finish the command by polling the P bit
-in DBRI register 0.  I've tried to implement this in such a way
-that might make implementing a more sophisticated scheme easier.
-
 Every time a routine wants to write commands to the DBRI, it must
 first call dbri_cmdlock() and get an initial pointer into dbri->dma->cmd
-in return.  After the commands have been writen, dbri_cmdsend() is
-called with the final pointer value.
+in return. dbri_cmdlock() will block if the previous commands have not
+been completed yet. After this the commands can be written to the buffer,
+and dbri_cmdsend() is called with the final pointer value to send them
+to the DBRI.
 
 */
 
+static void dbri_process_interrupt_buffer(snd_dbri_t * dbri);
+
 enum dbri_lock_t { NoGetLock, GetLock };
+#define MAXLOOPS 10
 
 static volatile s32 *dbri_cmdlock(snd_dbri_t * dbri, enum dbri_lock_t get)
 {
+	int maxloops = MAXLOOPS;
+
 #ifndef SMP
 	if ((get == GetLock) && spin_is_locked(&dbri->lock)) {
 		printk(KERN_ERR "DBRI: cmdlock called while in spinlock.");
 	}
 #endif
 
+	/* Delay if previous commands are still being processed */
+	while ((--maxloops) > 0 && (dbri->wait_send != dbri->wait_ackd)) {
+		msleep_interruptible(1);
+		/* If dbri_cmdlock() got called from inside the
+		 * interrupt handler, this will do the processing.
+		 */
+		dbri_process_interrupt_buffer(dbri);
+	}
+	if (maxloops == 0) {
+		printk(KERN_ERR "DBRI: Chip never completed command buffer %d\n",
+			dbri->wait_send);
+	} else {
+		dprintk(D_CMD, "Chip completed command buffer (%d)\n",
+			MAXLOOPS - maxloops - 1);
+	}
+
 	/*if (get == GetLock) spin_lock(&dbri->lock); */
 	return &dbri->dma->cmd[0];
 }
 
-static void dbri_process_interrupt_buffer(snd_dbri_t *);
-
 static void dbri_cmdsend(snd_dbri_t * dbri, volatile s32 * cmd)
 {
-	int MAXLOOPS = 1000000;
-	int maxloops = MAXLOOPS;
 	volatile s32 *ptr;
+	u32	reg;
 
 	for (ptr = &dbri->dma->cmd[0]; ptr < cmd; ptr++) {
 		dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
 	}
 
 	if ((cmd - &dbri->dma->cmd[0]) >= DBRI_NO_CMDS - 1) {
-		printk("DBRI: Command buffer overflow! (bug in driver)\n");
+		printk(KERN_ERR "DBRI: Command buffer overflow! (bug in driver)\n");
 		/* Ignore the last part. */
 		cmd = &dbri->dma->cmd[DBRI_NO_CMDS - 3];
 	}
 
+	dbri->wait_send++;
+	dbri->wait_send &= 0xffff;	/* restrict it to a 16 bit counter. */
 	*(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
-	*(cmd++) = DBRI_CMD(D_WAIT, 1, 0);
-	dbri->wait_seen = 0;
+	*(cmd++) = DBRI_CMD(D_WAIT, 1, dbri->wait_send);
+
+	/* Set command pointer and signal it is valid. */
 	sbus_writel(dbri->dma_dvma, dbri->regs + REG8);
-	while ((--maxloops) > 0 && (sbus_readl(dbri->regs + REG0) & D_P))
-		barrier();
-	if (maxloops == 0) {
-		printk(KERN_ERR "DBRI: Chip never completed command buffer\n");
-		dprintk(D_CMD, "DBRI: Chip never completed command buffer\n");
-	} else {
-		while ((--maxloops) > 0 && (!dbri->wait_seen))
-			dbri_process_interrupt_buffer(dbri);
-		if (maxloops == 0) {
-			printk(KERN_ERR "DBRI: Chip never acked WAIT\n");
-			dprintk(D_CMD, "DBRI: Chip never acked WAIT\n");
-		} else {
-			dprintk(D_CMD, "Chip completed command "
-				"buffer (%d)\n", MAXLOOPS - maxloops);
-		}
-	}
+	reg = sbus_readl(dbri->regs + REG0);
+	reg |= D_P;
+	sbus_writel(reg, dbri->regs + REG0);
 
 	/*spin_unlock(&dbri->lock); */
 }
@@ -757,10 +766,11 @@
 	for (n = 0; n < DBRI_NO_PIPES; n++)
 		dbri->pipes[n].desc = dbri->pipes[n].first_desc = -1;
 
-	/* We should query the openprom to see what burst sizes this
-	 * SBus supports.  For now, just disable all SBus bursts */
+	/* A brute approach - DBRI falls back to working burst size by itself
+	 * On SS20 D_S does not work, so do not try so high. */
 	tmp = sbus_readl(dbri->regs + REG0);
-	tmp &= ~(D_G | D_S | D_E);
+	tmp |= D_G | D_E;
+	tmp &= ~D_S;
 	sbus_writel(tmp, dbri->regs + REG0);
 
 	/*
@@ -805,13 +815,13 @@
 	volatile int *cmd;
 
 	if (pipe < 0 || pipe > 31) {
-		printk("DBRI: reset_pipe called with illegal pipe number\n");
+		printk(KERN_ERR "DBRI: reset_pipe called with illegal pipe number\n");
 		return;
 	}
 
 	sdp = dbri->pipes[pipe].sdp;
 	if (sdp == 0) {
-		printk("DBRI: reset_pipe called on uninitialized pipe\n");
+		printk(KERN_ERR "DBRI: reset_pipe called on uninitialized pipe\n");
 		return;
 	}
 
@@ -834,12 +844,12 @@
 static void setup_pipe(snd_dbri_t * dbri, int pipe, int sdp)
 {
 	if (pipe < 0 || pipe > 31) {
-		printk("DBRI: setup_pipe called with illegal pipe number\n");
+		printk(KERN_ERR "DBRI: setup_pipe called with illegal pipe number\n");
 		return;
 	}
 
 	if ((sdp & 0xf800) != sdp) {
-		printk("DBRI: setup_pipe called with strange SDP value\n");
+		printk(KERN_ERR "DBRI: setup_pipe called with strange SDP value\n");
 		/* sdp &= 0xf800; */
 	}
 
@@ -872,13 +882,13 @@
 	int nextpipe;
 
 	if (pipe < 0 || pipe > 31 || basepipe < 0 || basepipe > 31) {
-		printk
-		    ("DBRI: link_time_slot called with illegal pipe number\n");
+		printk(KERN_ERR 
+		    "DBRI: link_time_slot called with illegal pipe number\n");
 		return;
 	}
 
 	if (dbri->pipes[pipe].sdp == 0 || dbri->pipes[basepipe].sdp == 0) {
-		printk("DBRI: link_time_slot called on uninitialized pipe\n");
+		printk(KERN_ERR "DBRI: link_time_slot called on uninitialized pipe\n");
 		return;
 	}
 
@@ -960,8 +970,8 @@
 	int val;
 
 	if (pipe < 0 || pipe > 31 || prevpipe < 0 || prevpipe > 31) {
-		printk
-		    ("DBRI: unlink_time_slot called with illegal pipe number\n");
+		printk(KERN_ERR 
+		    "DBRI: unlink_time_slot called with illegal pipe number\n");
 		return;
 	}
 
@@ -1001,22 +1011,22 @@
 	volatile s32 *cmd;
 
 	if (pipe < 16 || pipe > 31) {
-		printk("DBRI: xmit_fixed: Illegal pipe number\n");
+		printk(KERN_ERR "DBRI: xmit_fixed: Illegal pipe number\n");
 		return;
 	}
 
 	if (D_SDP_MODE(dbri->pipes[pipe].sdp) == 0) {
-		printk("DBRI: xmit_fixed: Uninitialized pipe %d\n", pipe);
+		printk(KERN_ERR "DBRI: xmit_fixed: Uninitialized pipe %d\n", pipe);
 		return;
 	}
 
 	if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) {
-		printk("DBRI: xmit_fixed: Non-fixed pipe %d\n", pipe);
+		printk(KERN_ERR "DBRI: xmit_fixed: Non-fixed pipe %d\n", pipe);
 		return;
 	}
 
 	if (!(dbri->pipes[pipe].sdp & D_SDP_TO_SER)) {
-		printk("DBRI: xmit_fixed: Called on receive pipe %d\n", pipe);
+		printk(KERN_ERR "DBRI: xmit_fixed: Called on receive pipe %d\n", pipe);
 		return;
 	}
 
@@ -1036,17 +1046,17 @@
 static void recv_fixed(snd_dbri_t * dbri, int pipe, volatile __u32 * ptr)
 {
 	if (pipe < 16 || pipe > 31) {
-		printk("DBRI: recv_fixed called with illegal pipe number\n");
+		printk(KERN_ERR "DBRI: recv_fixed called with illegal pipe number\n");
 		return;
 	}
 
 	if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) {
-		printk("DBRI: recv_fixed called on non-fixed pipe %d\n", pipe);
+		printk(KERN_ERR "DBRI: recv_fixed called on non-fixed pipe %d\n", pipe);
 		return;
 	}
 
 	if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) {
-		printk("DBRI: recv_fixed called on transmit pipe %d\n", pipe);
+		printk(KERN_ERR "DBRI: recv_fixed called on transmit pipe %d\n", pipe);
 		return;
 	}
 
@@ -1075,12 +1085,12 @@
 	int last_desc = -1;
 
 	if (info->pipe < 0 || info->pipe > 15) {
-		printk("DBRI: setup_descs: Illegal pipe number\n");
+		printk(KERN_ERR "DBRI: setup_descs: Illegal pipe number\n");
 		return -2;
 	}
 
 	if (dbri->pipes[info->pipe].sdp == 0) {
-		printk("DBRI: setup_descs: Uninitialized pipe %d\n",
+		printk(KERN_ERR "DBRI: setup_descs: Uninitialized pipe %d\n",
 		       info->pipe);
 		return -2;
 	}
@@ -1090,20 +1100,20 @@
 
 	if (streamno == DBRI_PLAY) {
 		if (!(dbri->pipes[info->pipe].sdp & D_SDP_TO_SER)) {
-			printk("DBRI: setup_descs: Called on receive pipe %d\n",
+			printk(KERN_ERR "DBRI: setup_descs: Called on receive pipe %d\n",
 			       info->pipe);
 			return -2;
 		}
 	} else {
 		if (dbri->pipes[info->pipe].sdp & D_SDP_TO_SER) {
-			printk
-			    ("DBRI: setup_descs: Called on transmit pipe %d\n",
+			printk(KERN_ERR 
+			    "DBRI: setup_descs: Called on transmit pipe %d\n",
 			     info->pipe);
 			return -2;
 		}
 		/* Should be able to queue multiple buffers to receive on a pipe */
 		if (pipe_active(dbri, info->pipe)) {
-			printk("DBRI: recv_on_pipe: Called on active pipe %d\n",
+			printk(KERN_ERR "DBRI: recv_on_pipe: Called on active pipe %d\n",
 			       info->pipe);
 			return -2;
 		}
@@ -1120,7 +1130,7 @@
 				break;
 		}
 		if (desc == DBRI_NO_DESCS) {
-			printk("DBRI: setup_descs: No descriptors\n");
+			printk(KERN_ERR "DBRI: setup_descs: No descriptors\n");
 			return -1;
 		}
 
@@ -1165,7 +1175,7 @@
 	}
 
 	if (first_desc == -1 || last_desc == -1) {
-		printk("DBRI: setup_descs: Not enough descriptors available\n");
+		printk(KERN_ERR "DBRI: setup_descs: Not enough descriptors available\n");
 		return -1;
 	}
 
@@ -1270,7 +1280,7 @@
 		int divisor = 12288 / clockrate;
 
 		if (divisor > 255 || divisor * clockrate != 12288)
-			printk("DBRI: illegal bits_per_frame in setup_chi\n");
+			printk(KERN_ERR "DBRI: illegal bits_per_frame in setup_chi\n");
 
 		*(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(divisor) | D_CHI_FD
 				    | D_CHI_BPF(bits_per_frame));
@@ -1474,7 +1484,6 @@
 	/* Temporarily mute outputs, and wait 1/8000 sec (125 us)
 	 * to make sure this takes.  This avoids clicking noises.
 	 */
-
 	cs4215_setdata(dbri, 1);
 	udelay(125);
 
@@ -1530,8 +1539,8 @@
 	tmp |= D_C;		/* Enable CHI */
 	sbus_writel(tmp, dbri->regs + REG0);
 
-	for (i = 64; ((dbri->mm.status & 0xe4) != 0x20); --i) {
-		udelay(125);
+	for (i = 10; ((dbri->mm.status & 0xe4) != 0x20); --i) {
+		msleep_interruptible(1);
 	}
 	if (i == 0) {
 		dprintk(D_MM, "CS4215 didn't respond to CLB (0x%02x)\n",
@@ -1678,8 +1687,8 @@
 Complicated interrupts are handled by dedicated functions (which
 appear first in this file).  Any pending interrupts can be serviced by
 calling dbri_process_interrupt_buffer(), which works even if the CPU's
-interrupts are disabled.  This function is used by dbri_cmdsend()
-to make sure we're synced up with the chip after each command sequence,
+interrupts are disabled.  This function is used by dbri_cmdlock()
+to make sure we're synced up with the chip before each command sequence,
 even if we're running cli'ed.
 
 */
@@ -1765,11 +1774,13 @@
  * Called by main interrupt handler when DBRI signals transmission complete
  * on a pipe (interrupt triggered by the B bit in a transmit descriptor).
  *
- * Walks through the pipe's list of transmit buffer descriptors, releasing
- * each one's DMA buffer (if present), flagging the descriptor available,
- * and signaling its callback routine (if present), before proceeding
- * to the next one.  Stops when the first descriptor is found without
+ * Walks through the pipe's list of transmit buffer descriptors and marks
+ * them as available. Stops when the first descriptor is found without
  * TBC (Transmit Buffer Complete) set, or we've run through them all.
+ *
+ * The DMA buffers are not released, but re-used. Since the transmit buffer
+ * descriptors are not clobbered, they can be re-submitted as is. This is
+ * done by the xmit_descs() tasklet above since that could take longer.
  */
 
 static void transmission_complete_intr(snd_dbri_t * dbri, int pipe)
@@ -1885,7 +1896,11 @@
 	}
 
 	if (channel == D_INTR_CMD && command == D_WAIT) {
-		dbri->wait_seen++;
+		dbri->wait_ackd = val;
+		if (dbri->wait_send != val) {
+			printk(KERN_ERR "Processing wait command %d when %d was send.\n",
+			       val, dbri->wait_send);
+		}
 		return;
 	}
 
@@ -1994,8 +2009,7 @@
 		 * The only one I've seen is MRR, which will be triggered
 		 * if you let a transmit pipe underrun, then try to CDP it.
 		 *
-		 * If these things persist, we should probably reset
-		 * and re-init the chip.
+		 * If these things persist, we reset the chip.
 		 */
 		if ((++errcnt) % 10 == 0) {
 			dprintk(D_INT, "Interrupt errors exceeded.\n");
@@ -2094,7 +2108,7 @@
 
 	if ((ret = snd_pcm_lib_malloc_pages(substream,
 				params_buffer_bytes(hw_params))) < 0) {
-		snd_printk(KERN_ERR "malloc_pages failed with %d\n", ret);
+		printk(KERN_ERR "malloc_pages failed with %d\n", ret);
 		return ret;
 	}
 
@@ -2455,8 +2469,7 @@
 
 	for (idx = 0; idx < NUM_CS4215_CONTROLS; idx++) {
 		if ((err = snd_ctl_add(card,
-				       snd_ctl_new1(&dbri_controls[idx],
-						    dbri))) < 0)
+				snd_ctl_new1(&dbri_controls[idx], dbri))) < 0)
 			return err;
 	}
 
@@ -2490,8 +2503,6 @@
 	int pipe;
 	snd_iprintf(buffer, "debug=%d\n", dbri_debug);
 
-	snd_iprintf(buffer, "CHI pipe in=%d, out=%d\n",
-		    dbri->chi_in_pipe, dbri->chi_out_pipe);
 	for (pipe = 0; pipe < 32; pipe++) {
 		if (pipe_active(dbri, pipe)) {
 			struct dbri_pipe *pptr = &dbri->pipes[pipe];
@@ -2506,18 +2517,6 @@
 		}
 	}
 }
-
-static void dbri_debug_write(snd_info_entry_t * entry,
-			     snd_info_buffer_t * buffer)
-{
-	char line[80];
-	int i;
-
-	if (snd_info_get_line(buffer, line, 80) == 0) {
-		sscanf(line, "%d\n", &i);
-		dbri_debug = i & 0x3f;
-	}
-}
 #endif
 
 void snd_dbri_proc(snd_dbri_t * dbri)
@@ -2531,9 +2530,7 @@
 #ifdef DBRI_DEBUG
 	err = snd_card_proc_new(dbri->card, "debug", &entry);
 	snd_info_set_text_ops(entry, dbri, 4096, dbri_debug_read);
-	entry->mode = S_IFREG | S_IRUGO | S_IWUSR; /* Writable for root */
-	entry->c.text.write_size = 256;
-	entry->c.text.write = dbri_debug_write;
+	entry->mode = S_IFREG | S_IRUGO;	/* Readable only. */
 #endif
 }
 
@@ -2637,7 +2634,11 @@
 		return -ENOENT;
 	}
 
-	prom_getproperty(prom_node, "intr", (char *)&irq, sizeof(irq));
+	err = prom_getproperty(prom_node, "intr", (char *)&irq, sizeof(irq));
+	if (err < 0) {
+		printk(KERN_ERR "DBRI-%d: Firmware node lacks IRQ property.\n", dev);
+		return -ENODEV;
+	}
 
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE,
 			    sizeof(snd_dbri_t));
@@ -2657,26 +2658,20 @@
 	}
 
 	dbri = (snd_dbri_t *) card->private_data;
-	if ((err = snd_dbri_pcm(dbri)) < 0) {
-		snd_dbri_free(dbri);
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_dbri_pcm(dbri)) < 0)
+		goto _err;
 
-	if ((err = snd_dbri_mixer(dbri)) < 0) {
-		snd_dbri_free(dbri);
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_dbri_mixer(dbri)) < 0)
+		goto _err;
 
 	/* /proc file handling */
 	snd_dbri_proc(dbri);
 
-	if ((err = snd_card_register(card)) < 0) {
-		snd_dbri_free(dbri);
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_card_set_generic_dev(card)) < 0)
+		goto _err;
+
+	if ((err = snd_card_register(card)) < 0)
+		goto _err;
 
 	printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n",
 	       dev, dbri->regs,
@@ -2684,6 +2679,11 @@
 	dev++;
 
 	return 0;
+
+ _err:
+	snd_dbri_free(dbri);
+	snd_card_free(card);
+	return err;
 }
 
 /* Probe for the dbri chip and then attach the driver. */
diff --git a/sound/synth/emux/emux.c b/sound/synth/emux/emux.c
index 60d0b2c..9e2b4c0 100644
--- a/sound/synth/emux/emux.c
+++ b/sound/synth/emux/emux.c
@@ -40,7 +40,7 @@
 	snd_emux_t *emu;
 
 	*remu = NULL;
-	emu = kcalloc(1, sizeof(*emu), GFP_KERNEL);
+	emu = kzalloc(sizeof(*emu), GFP_KERNEL);
 	if (emu == NULL)
 		return -ENOMEM;
 
diff --git a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c
index e41b28d..8ccd33f 100644
--- a/sound/synth/emux/emux_seq.c
+++ b/sound/synth/emux/emux_seq.c
@@ -146,7 +146,7 @@
 	int i, type, cap;
 
 	/* Allocate structures for this channel */
-	if ((p = kcalloc(1, sizeof(*p), GFP_KERNEL)) == NULL) {
+	if ((p = kzalloc(sizeof(*p), GFP_KERNEL)) == NULL) {
 		snd_printk("no memory\n");
 		return NULL;
 	}
diff --git a/sound/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c
index 901a7db..d0925ea 100644
--- a/sound/synth/emux/soundfont.c
+++ b/sound/synth/emux/soundfont.c
@@ -266,7 +266,7 @@
 	}
 
 	/* not found -- create a new one */
-	sf = kcalloc(1, sizeof(*sf), GFP_KERNEL);
+	sf = kzalloc(sizeof(*sf), GFP_KERNEL);
 	if (sf == NULL)
 		return NULL;
 	sf->id = sflist->fonts_size;
@@ -346,7 +346,7 @@
 {
 	snd_sf_zone_t *zp;
 
-	if ((zp = kcalloc(1, sizeof(*zp), GFP_KERNEL)) == NULL)
+	if ((zp = kzalloc(sizeof(*zp), GFP_KERNEL)) == NULL)
 		return NULL;
 	zp->next = sf->zones;
 	sf->zones = zp;
@@ -377,7 +377,7 @@
 {
 	snd_sf_sample_t *sp;
 
-	if ((sp = kcalloc(1, sizeof(*sp), GFP_KERNEL)) == NULL)
+	if ((sp = kzalloc(sizeof(*sp), GFP_KERNEL)) == NULL)
 		return NULL;
 
 	sp->next = sf->samples;
@@ -1362,7 +1362,7 @@
 {
 	snd_sf_list_t *sflist;
 
-	if ((sflist = kcalloc(1, sizeof(*sflist), GFP_KERNEL)) == NULL)
+	if ((sflist = kzalloc(sizeof(*sflist), GFP_KERNEL)) == NULL)
 		return NULL;
 
 	init_MUTEX(&sflist->presets_mutex);
diff --git a/sound/synth/util_mem.c b/sound/synth/util_mem.c
index 8b131a1..5f75bf3 100644
--- a/sound/synth/util_mem.c
+++ b/sound/synth/util_mem.c
@@ -38,7 +38,7 @@
 {
 	snd_util_memhdr_t *hdr;
 
-	hdr = kcalloc(1, sizeof(*hdr), GFP_KERNEL);
+	hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
 	if (hdr == NULL)
 		return NULL;
 	hdr->size = memsize;
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index bfbec58..d5ae2055 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -1439,9 +1439,11 @@
 
 static snd_pcm_hardware_t snd_usb_playback =
 {
-	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
-				 SNDRV_PCM_INFO_MMAP_VALID),
+	.info =			SNDRV_PCM_INFO_MMAP |
+				SNDRV_PCM_INFO_MMAP_VALID |
+				SNDRV_PCM_INFO_BATCH |
+				SNDRV_PCM_INFO_INTERLEAVED |
+				SNDRV_PCM_INFO_BLOCK_TRANSFER,
 	.buffer_bytes_max =	(256*1024),
 	.period_bytes_min =	64,
 	.period_bytes_max =	(128*1024),
@@ -1451,9 +1453,11 @@
 
 static snd_pcm_hardware_t snd_usb_capture =
 {
-	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
-				 SNDRV_PCM_INFO_MMAP_VALID),
+	.info =			SNDRV_PCM_INFO_MMAP |
+				SNDRV_PCM_INFO_MMAP_VALID |
+				SNDRV_PCM_INFO_BATCH |
+				SNDRV_PCM_INFO_INTERLEAVED |
+				SNDRV_PCM_INFO_BLOCK_TRANSFER,
 	.buffer_bytes_max =	(256*1024),
 	.period_bytes_min =	64,
 	.period_bytes_max =	(128*1024),
@@ -3132,7 +3136,7 @@
 		return -ENOMEM;
 	}
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (! chip) {
 		snd_card_free(card);
 		return -ENOMEM;
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 93dedde..e0d0365 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -841,7 +841,7 @@
 	int length;
 
 	rep->in = NULL;
-	ep = kcalloc(1, sizeof(*ep), GFP_KERNEL);
+	ep = kzalloc(sizeof(*ep), GFP_KERNEL);
 	if (!ep)
 		return -ENOMEM;
 	ep->umidi = umidi;
@@ -913,7 +913,7 @@
 	void* buffer;
 
 	rep->out = NULL;
-	ep = kcalloc(1, sizeof(*ep), GFP_KERNEL);
+	ep = kzalloc(sizeof(*ep), GFP_KERNEL);
 	if (!ep)
 		return -ENOMEM;
 	ep->umidi = umidi;
@@ -1537,7 +1537,7 @@
 	int out_ports, in_ports;
 	int i, err;
 
-	umidi = kcalloc(1, sizeof(*umidi), GFP_KERNEL);
+	umidi = kzalloc(sizeof(*umidi), GFP_KERNEL);
 	if (!umidi)
 		return -ENOMEM;
 	umidi->chip = chip;
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index fa7056f..c3c08c9 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -824,7 +824,7 @@
 	if (check_ignored_ctl(state, unitid, control))
 		return;
 
-	cval = kcalloc(1, sizeof(*cval), GFP_KERNEL);
+	cval = kzalloc(sizeof(*cval), GFP_KERNEL);
 	if (! cval) {
 		snd_printk(KERN_ERR "cannot malloc kcontrol\n");
 		return;
@@ -997,7 +997,7 @@
 	if (check_ignored_ctl(state, unitid, 0))
 		return;
 
-	cval = kcalloc(1, sizeof(*cval), GFP_KERNEL);
+	cval = kzalloc(sizeof(*cval), GFP_KERNEL);
 	if (! cval)
 		return;
 
@@ -1244,7 +1244,7 @@
 			continue;
 		if (check_ignored_ctl(state, unitid, valinfo->control))
 			continue;
-		cval = kcalloc(1, sizeof(*cval), GFP_KERNEL);
+		cval = kzalloc(sizeof(*cval), GFP_KERNEL);
 		if (! cval) {
 			snd_printk(KERN_ERR "cannot malloc kcontrol\n");
 			return -ENOMEM;
@@ -1430,7 +1430,7 @@
 	if (check_ignored_ctl(state, unitid, 0))
 		return 0;
 
-	cval = kcalloc(1, sizeof(*cval), GFP_KERNEL);
+	cval = kzalloc(sizeof(*cval), GFP_KERNEL);
 	if (! cval) {
 		snd_printk(KERN_ERR "cannot malloc kcontrol\n");
 		return -ENOMEM;
@@ -1945,7 +1945,7 @@
 
 	strcpy(chip->card->mixername, "USB Mixer");
 
-	mixer = kcalloc(1, sizeof(*mixer), GFP_KERNEL);
+	mixer = kzalloc(sizeof(*mixer), GFP_KERNEL);
 	if (!mixer)
 		return -ENOMEM;
 	mixer->chip = chip;
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index 62dfd28..0f09e0d 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -957,7 +957,7 @@
 
 	for (i = playback_endpoint ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
 	     i <= SNDRV_PCM_STREAM_CAPTURE; ++i) {
-		usX2Y_substream[i] = kcalloc(1, sizeof(snd_usX2Y_substream_t), GFP_KERNEL);
+		usX2Y_substream[i] = kzalloc(sizeof(snd_usX2Y_substream_t), GFP_KERNEL);
 		if (NULL == usX2Y_substream[i]) {
 			snd_printk(KERN_ERR "cannot malloc\n");
 			return -ENOMEM;