Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
diff --git a/Documentation/DocBook/kernel-locking.tmpl b/Documentation/DocBook/kernel-locking.tmpl
index 90dc2de..158ffe9 100644
--- a/Documentation/DocBook/kernel-locking.tmpl
+++ b/Documentation/DocBook/kernel-locking.tmpl
@@ -222,7 +222,7 @@
    <title>Two Main Types of Kernel Locks: Spinlocks and Semaphores</title>
 
    <para>
-     There are two main types of kernel locks.  The fundamental type
+     There are three main types of kernel locks.  The fundamental type
      is the spinlock 
      (<filename class="headerfile">include/asm/spinlock.h</filename>),
      which is a very simple single-holder lock: if you can't get the 
@@ -230,16 +230,22 @@
      very small and fast, and can be used anywhere.
    </para>
    <para>
-     The second type is a semaphore
+     The second type is a mutex
+     (<filename class="headerfile">include/linux/mutex.h</filename>): it
+     is like a spinlock, but you may block holding a mutex.
+     If you can't lock a mutex, your task will suspend itself, and be woken
+     up when the mutex is released.  This means the CPU can do something
+     else while you are waiting.  There are many cases when you simply
+     can't sleep (see <xref linkend="sleeping-things"/>), and so have to
+     use a spinlock instead.
+   </para>
+   <para>
+     The third type is a semaphore
      (<filename class="headerfile">include/asm/semaphore.h</filename>): it
      can have more than one holder at any time (the number decided at
      initialization time), although it is most commonly used as a
-     single-holder lock (a mutex).  If you can't get a semaphore,
-     your task will put itself on the queue, and be woken up when the
-     semaphore is released.  This means the CPU will do something
-     else while you are waiting, but there are many cases when you
-     simply can't sleep (see <xref linkend="sleeping-things"/>), and so
-     have to use a spinlock instead.
+     single-holder lock (a mutex).  If you can't get a semaphore, your
+     task will be suspended and later on woken up - just like for mutexes.
    </para>
    <para>
      Neither type of lock is recursive: see
diff --git a/Documentation/dvb/avermedia.txt b/Documentation/dvb/avermedia.txt
index 2dc260b..068070f 100644
--- a/Documentation/dvb/avermedia.txt
+++ b/Documentation/dvb/avermedia.txt
@@ -150,7 +150,8 @@
 
    The frontend module sp887x.o, requires an external   firmware.
    Please use  the  command "get_dvb_firmware sp887x" to download
-   it. Then copy it to /usr/lib/hotplug/firmware.
+   it. Then copy it to /usr/lib/hotplug/firmware or /lib/firmware/
+   (depending on configuration of firmware hotplug).
 
 Receiving DVB-T in Australia
 
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
index be6eb4c..75c28a1 100644
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -23,7 +23,7 @@
 
 @components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t",
 		"dec2540t", "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
-		"or51211", "or51132_qam", "or51132_vsb");
+		"or51211", "or51132_qam", "or51132_vsb", "bluebird");
 
 # Check args
 syntax() if (scalar(@ARGV) != 1);
@@ -34,7 +34,11 @@
     if ($cid eq $components[$i]) {
 	$outfile = eval($cid);
 	die $@ if $@;
-	print STDERR "Firmware $outfile extracted successfully. Now copy it to either /lib/firmware or /usr/lib/hotplug/firmware/ (depending on your hotplug version).\n";
+	print STDERR <<EOF;
+Firmware $outfile extracted successfully.
+Now copy it to either /usr/lib/hotplug/firmware or /lib/firmware
+(depending on configuration of firmware hotplug).
+EOF
 	exit(0);
     }
 }
@@ -243,7 +247,7 @@
     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
 
     checkstandard();
-    
+
     wgetfile($sourcefile, $url);
     unzip($sourcefile, $tmpdir);
     verify("$tmpdir/SkyNETU.sys", $hash);
@@ -308,6 +312,19 @@
     $fwfile;
 }
 
+sub bluebird {
+	my $url = "http://www.linuxtv.org/download/dvb/firmware/dvb-usb-bluebird-01.fw";
+	my $outfile = "dvb-usb-bluebird-01.fw";
+	my $hash = "658397cb9eba9101af9031302671f49d";
+
+	checkstandard();
+
+	wgetfile($outfile, $url);
+	verify($outfile,$hash);
+
+	$outfile;
+}
+
 # ---------------------------------------------------------------
 # Utilities
 
diff --git a/Documentation/dvb/ttusb-dec.txt b/Documentation/dvb/ttusb-dec.txt
index 5c1e984..b2f271c 100644
--- a/Documentation/dvb/ttusb-dec.txt
+++ b/Documentation/dvb/ttusb-dec.txt
@@ -41,4 +41,5 @@
 For 2.6 kernels the firmware is loaded at the point that the driver module is
 loaded.  See linux/Documentation/dvb/firmware.txt for more information.
 
-Copy the three files downloaded above into the /usr/lib/hotplug/firmware directory.
+Copy the three files downloaded above into the /usr/lib/hotplug/firmware or
+/lib/firmware directory (depending on configuration of firmware hotplug).
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index a4dcf42..944cf10 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -418,7 +418,7 @@
        Dirty: Memory which is waiting to get written back to the disk
    Writeback: Memory which is actively being written back to the disk
       Mapped: files which have been mmaped, such as libraries
-              Slab: in-kernel data structures cache
+        Slab: in-kernel data structures cache
  CommitLimit: Based on the overcommit ratio ('vm.overcommit_ratio'),
               this is the total amount of  memory currently available to
               be allocated on the system. This limit is only adhered to
diff --git a/Documentation/i2o/ioctl b/Documentation/i2o/ioctl
index 3e17497..1e77fac 100644
--- a/Documentation/i2o/ioctl
+++ b/Documentation/i2o/ioctl
@@ -185,7 +185,7 @@
       ENOMEM      Kernel memory allocation error
 
    A return value of 0 does not mean that the value was actually
-   properly retreived.  The user should check the result list
+   properly retrieved.  The user should check the result list
    to determine the specific status of the transaction.
 
 VIII. Downloading Software
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index acb010b..0dc848b 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -998,6 +998,8 @@
 
 	nowb		[ARM]
 
+	nr_uarts=	[SERIAL] maximum number of UARTs to be registered.
+
 	opl3=		[HW,OSS]
 			Format: <io>
 
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index 0541fe1..0ea5a0c 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -411,7 +411,8 @@
 		printk("Couldn't find %s to plant kprobe\n", "do_fork");
 		return -1;
 	}
-	if ((ret = register_kprobe(&kp) < 0)) {
+	ret = register_kprobe(&kp);
+	if (ret < 0) {
 		printk("register_kprobe failed, returned %d\n", ret);
 		return -1;
 	}
diff --git a/Documentation/mutex-design.txt b/Documentation/mutex-design.txt
new file mode 100644
index 0000000..cbf7988
--- /dev/null
+++ b/Documentation/mutex-design.txt
@@ -0,0 +1,135 @@
+Generic Mutex Subsystem
+
+started by Ingo Molnar <mingo@redhat.com>
+
+  "Why on earth do we need a new mutex subsystem, and what's wrong
+   with semaphores?"
+
+firstly, there's nothing wrong with semaphores. But if the simpler
+mutex semantics are sufficient for your code, then there are a couple
+of advantages of mutexes:
+
+ - 'struct mutex' is smaller on most architectures: .e.g on x86,
+   'struct semaphore' is 20 bytes, 'struct mutex' is 16 bytes.
+   A smaller structure size means less RAM footprint, and better
+   CPU-cache utilization.
+
+ - tighter code. On x86 i get the following .text sizes when
+   switching all mutex-alike semaphores in the kernel to the mutex
+   subsystem:
+
+        text    data     bss     dec     hex filename
+     3280380  868188  396860 4545428  455b94 vmlinux-semaphore
+     3255329  865296  396732 4517357  44eded vmlinux-mutex
+
+   that's 25051 bytes of code saved, or a 0.76% win - off the hottest
+   codepaths of the kernel. (The .data savings are 2892 bytes, or 0.33%)
+   Smaller code means better icache footprint, which is one of the
+   major optimization goals in the Linux kernel currently.
+
+ - the mutex subsystem is slightly faster and has better scalability for
+   contended workloads. On an 8-way x86 system, running a mutex-based
+   kernel and testing creat+unlink+close (of separate, per-task files)
+   in /tmp with 16 parallel tasks, the average number of ops/sec is:
+
+    Semaphores:                        Mutexes:
+
+    $ ./test-mutex V 16 10             $ ./test-mutex V 16 10
+    8 CPUs, running 16 tasks.          8 CPUs, running 16 tasks.
+    checking VFS performance.          checking VFS performance.
+    avg loops/sec:      34713          avg loops/sec:      84153
+    CPU utilization:    63%            CPU utilization:    22%
+
+   i.e. in this workload, the mutex based kernel was 2.4 times faster
+   than the semaphore based kernel, _and_ it also had 2.8 times less CPU
+   utilization. (In terms of 'ops per CPU cycle', the semaphore kernel
+   performed 551 ops/sec per 1% of CPU time used, while the mutex kernel
+   performed 3825 ops/sec per 1% of CPU time used - it was 6.9 times
+   more efficient.)
+
+   the scalability difference is visible even on a 2-way P4 HT box:
+
+    Semaphores:                        Mutexes:
+
+    $ ./test-mutex V 16 10             $ ./test-mutex V 16 10
+    4 CPUs, running 16 tasks.          8 CPUs, running 16 tasks.
+    checking VFS performance.          checking VFS performance.
+    avg loops/sec:      127659         avg loops/sec:      181082
+    CPU utilization:    100%           CPU utilization:    34%
+
+   (the straight performance advantage of mutexes is 41%, the per-cycle
+    efficiency of mutexes is 4.1 times better.)
+
+ - there are no fastpath tradeoffs, the mutex fastpath is just as tight
+   as the semaphore fastpath. On x86, the locking fastpath is 2
+   instructions:
+
+    c0377ccb <mutex_lock>:
+    c0377ccb:       f0 ff 08                lock decl (%eax)
+    c0377cce:       78 0e                   js     c0377cde <.text.lock.mutex>
+    c0377cd0:       c3                      ret
+
+   the unlocking fastpath is equally tight:
+
+    c0377cd1 <mutex_unlock>:
+    c0377cd1:       f0 ff 00                lock incl (%eax)
+    c0377cd4:       7e 0f                   jle    c0377ce5 <.text.lock.mutex+0x7>
+    c0377cd6:       c3                      ret
+
+ - 'struct mutex' semantics are well-defined and are enforced if
+   CONFIG_DEBUG_MUTEXES is turned on. Semaphores on the other hand have
+   virtually no debugging code or instrumentation. The mutex subsystem
+   checks and enforces the following rules:
+
+   * - only one task can hold the mutex at a time
+   * - only the owner can unlock the mutex
+   * - multiple unlocks are not permitted
+   * - recursive locking is not permitted
+   * - a mutex object must be initialized via the API
+   * - a mutex object must not be initialized via memset or copying
+   * - task may not exit with mutex held
+   * - memory areas where held locks reside must not be freed
+   * - held mutexes must not be reinitialized
+   * - mutexes may not be used in irq contexts
+
+   furthermore, there are also convenience features in the debugging
+   code:
+
+   * - uses symbolic names of mutexes, whenever they are printed in debug output
+   * - point-of-acquire tracking, symbolic lookup of function names
+   * - list of all locks held in the system, printout of them
+   * - owner tracking
+   * - detects self-recursing locks and prints out all relevant info
+   * - detects multi-task circular deadlocks and prints out all affected
+   *   locks and tasks (and only those tasks)
+
+Disadvantages
+-------------
+
+The stricter mutex API means you cannot use mutexes the same way you
+can use semaphores: e.g. they cannot be used from an interrupt context,
+nor can they be unlocked from a different context that which acquired
+it. [ I'm not aware of any other (e.g. performance) disadvantages from
+using mutexes at the moment, please let me know if you find any. ]
+
+Implementation of mutexes
+-------------------------
+
+'struct mutex' is the new mutex type, defined in include/linux/mutex.h
+and implemented in kernel/mutex.c. It is a counter-based mutex with a
+spinlock and a wait-list. The counter has 3 states: 1 for "unlocked",
+0 for "locked" and negative numbers (usually -1) for "locked, potential
+waiters queued".
+
+the APIs of 'struct mutex' have been streamlined:
+
+ DEFINE_MUTEX(name);
+
+ mutex_init(mutex);
+
+ void mutex_lock(struct mutex *lock);
+ int  mutex_lock_interruptible(struct mutex *lock);
+ int  mutex_trylock(struct mutex *lock);
+ void mutex_unlock(struct mutex *lock);
+ int  mutex_is_locked(struct mutex *lock);
+
diff --git a/Documentation/networking/sk98lin.txt b/Documentation/networking/sk98lin.txt
index 851fc97..f9d979e 100644
--- a/Documentation/networking/sk98lin.txt
+++ b/Documentation/networking/sk98lin.txt
@@ -245,7 +245,7 @@
 This parameters is only relevant if auto-negotiation for this port is 
 not set to "Sense". If auto-negotiation is set to "On", all three values
 are possible. If it is set to "Off", only "Full" and "Half" are allowed.
-This parameter is usefull if your link partner does not support all
+This parameter is useful if your link partner does not support all
 possible combinations.
 
 Flow Control
diff --git a/Documentation/power/swsusp.txt b/Documentation/power/swsusp.txt
index cd0fcd8..08c79d4 100644
--- a/Documentation/power/swsusp.txt
+++ b/Documentation/power/swsusp.txt
@@ -212,7 +212,7 @@
 
 cat `cat /proc/[0-9]*/maps | grep / | sed 's:.* /:/:' | sort -u` > /dev/null
 
-after resume. swapoff -a; swapon -a may also be usefull.
+after resume. swapoff -a; swapon -a may also be useful.
 
 Q: What happens to devices during swsusp? They seem to be resumed
 during system suspend?
@@ -323,7 +323,7 @@
 A: No, it should work okay, as long as your app does not mlock()
 it. Just prepare big enough swap partition.
 
-Q: What information is usefull for debugging suspend-to-disk problems?
+Q: What information is useful for debugging suspend-to-disk problems?
 
 A: Well, last messages on the screen are always useful. If something
 is broken, it is usually some kernel driver, therefore trying with as
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv
index 330246a..74fb085 100644
--- a/Documentation/video4linux/CARDLIST.bttv
+++ b/Documentation/video4linux/CARDLIST.bttv
@@ -141,3 +141,4 @@
 140 -> Osprey 440                                          [0070:ff07]
 141 -> Asound Skyeye PCTV
 142 -> Sabrent TV-FM (bttv version)
+143 -> Hauppauge ImpactVCB (bt878)                         [0070:13eb]
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index a1017d1..34b6e59 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -16,7 +16,7 @@
  15 -> DViCO FusionHDTV DVB-T1                             [18ac:db00]
  16 -> KWorld LTV883RF
  17 -> DViCO FusionHDTV 3 Gold-Q                           [18ac:d810]
- 18 -> Hauppauge Nova-T DVB-T                              [0070:9002]
+ 18 -> Hauppauge Nova-T DVB-T                              [0070:9002,0070:9001]
  19 -> Conexant DVB-T reference design                     [14f1:0187]
  20 -> Provideo PV259                                      [1540:2580]
  21 -> DViCO FusionHDTV DVB-T Plus                         [18ac:db10]
@@ -35,3 +35,11 @@
  34 -> ATI HDTV Wonder                                     [1002:a101]
  35 -> WinFast DTV1000-T                                   [107d:665f]
  36 -> AVerTV 303 (M126)                                   [1461:000a]
+ 37 -> Hauppauge Nova-S-Plus DVB-S                         [0070:9201,0070:9202]
+ 38 -> Hauppauge Nova-SE2 DVB-S                            [0070:9200]
+ 39 -> KWorld DVB-S 100                                    [17de:08b2]
+ 40 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid                [0070:9400,0070:9402]
+ 41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile)  [0070:9800,0070:9802]
+ 42 -> digitalnow DNTV Live! DVB-T Pro                     [1822:0025]
+ 43 -> KWorld/VStream XPert DVB-T with cx22702             [17de:08a1]
+ 44 -> DViCO FusionHDTV DVB-T Dual Digital                 [18ac:db50]
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index efb708e..cb3a59b 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -56,7 +56,7 @@
  55 -> LifeView FlyDVB-T DUO                    [5168:0502,5168:0306]
  56 -> Avermedia AVerTV 307                     [1461:a70a]
  57 -> Avermedia AVerTV GO 007 FM               [1461:f31f]
- 58 -> ADS Tech Instant TV (saa7135)            [1421:0350,1421:0370,1421:1370]
+ 58 -> ADS Tech Instant TV (saa7135)            [1421:0350,1421:0351,1421:0370,1421:1370]
  59 -> Kworld/Tevion V-Stream Xpert TV PVR7134
  60 -> Typhoon DVB-T Duo Digital/Analog Cardbus [4e42:0502]
  61 -> Philips TOUGH DVB-T reference design     [1131:2004]
@@ -81,4 +81,5 @@
  80 -> ASUS Digimatrix TV                       [1043:0210]
  81 -> Philips Tiger reference design           [1131:2018]
  82 -> MSI TV@Anywhere plus                     [1462:6231]
-
+ 83 -> Terratec Cinergy 250 PCI TV              [153b:1160]
+ 84 -> LifeView FlyDVB Trio                     [5168:0319]
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner
index 9d6544e..0bf3d5b 100644
--- a/Documentation/video4linux/CARDLIST.tuner
+++ b/Documentation/video4linux/CARDLIST.tuner
@@ -40,7 +40,7 @@
 tuner=39 - LG NTSC (newer TAPC series)
 tuner=40 - HITACHI V7-J180AT
 tuner=41 - Philips PAL_MK (FI1216 MK)
-tuner=42 - Philips 1236D ATSC/NTSC daul in
+tuner=42 - Philips 1236D ATSC/NTSC dual in
 tuner=43 - Philips NTSC MK3 (FM1236MK3 or FM1236/F)
 tuner=44 - Philips 4 in 1 (ATI TV Wonder Pro/Conexant)
 tuner=45 - Microtune 4049 FM5
@@ -50,7 +50,7 @@
 tuner=49 - Microtune 4042 FI5 ATSC/NTSC dual in
 tuner=50 - TCL 2002N
 tuner=51 - Philips PAL/SECAM_D (FM 1256 I-H3)
-tuner=52 - Thomson DDT 7610 (ATSC/NTSC)
+tuner=52 - Thomson DTT 7610 (ATSC/NTSC)
 tuner=53 - Philips FQ1286
 tuner=54 - tda8290+75
 tuner=55 - TCL 2002MB
@@ -58,7 +58,7 @@
 tuner=57 - Philips FQ1236A MK4
 tuner=58 - Ymec TVision TVF-8531MF/8831MF/8731MF
 tuner=59 - Ymec TVision TVF-5533MF
-tuner=60 - Thomson DDT 7611 (ATSC/NTSC)
+tuner=60 - Thomson DTT 761X (ATSC/NTSC)
 tuner=61 - Tena TNF9533-D/IF/TNF9533-B/DF
 tuner=62 - Philips TEA5767HN FM Radio
 tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner
diff --git a/MAINTAINERS b/MAINTAINERS
index 8024d1b..0742016 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -546,13 +546,6 @@
 T:	git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
 S:	Maintained
 
-BUSLOGIC SCSI DRIVER
-P:	Leonard N. Zubkoff
-M:	Leonard N. Zubkoff <lnz@dandelion.com>
-L:	linux-scsi@vger.kernel.org
-W:	http://www.dandelion.com/Linux/
-S:	Maintained
-
 COMMON INTERNET FILE SYSTEM (CIFS)
 P:	Steve French
 M:	sfrench@samba.org
diff --git a/Makefile b/Makefile
index 599e744..fb497ea 100644
--- a/Makefile
+++ b/Makefile
@@ -251,7 +251,7 @@
 # If it is set to "silent_", nothing wil be printed at all, since
 # the variable $(silent_cmd_cc_o_c) doesn't exist.
 #
-# A simple variant is to prefix commands with $(Q) - that's usefull
+# A simple variant is to prefix commands with $(Q) - that's useful
 # for commands that shall be hidden in non-verbose mode.
 #
 #	$(Q)ln $@ :<
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 7a74e3e..50b9afa 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -99,13 +99,6 @@
 	  Ethernet interface, two PCMCIA sockets, two serial ports and a
 	  parallel port.
 
-config ARCH_CAMELOT
-	bool "Epxa10db"
-	help
-	  This enables support for Altera's Excalibur XA10 development board.
-	  If you would like to build your kernel to run on one of these boards
-	  then you must say 'Y' here. Otherwise say 'N'
-
 config ARCH_FOOTBRIDGE
 	bool "FootBridge"
 	select FOOTBRIDGE
@@ -213,12 +206,16 @@
 	help
 	  This enables support for systems based on the Agilent AAEC-2000
 
+config ARCH_AT91RM9200
+	bool "AT91RM9200"
+	help
+	  Say Y here if you intend to run this kernel on an AT91RM9200-based
+	  board.
+
 endchoice
 
 source "arch/arm/mach-clps711x/Kconfig"
 
-source "arch/arm/mach-epxa10db/Kconfig"
-
 source "arch/arm/mach-footbridge/Kconfig"
 
 source "arch/arm/mach-integrator/Kconfig"
@@ -253,6 +250,8 @@
 
 source "arch/arm/mach-realview/Kconfig"
 
+source "arch/arm/mach-at91rm9200/Kconfig"
+
 # Definitions to make life easier
 config ARCH_ACORN
 	bool
@@ -418,7 +417,8 @@
 		   ARCH_EBSA285 || ARCH_IMX || ARCH_INTEGRATOR || \
 		   ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \
 		   ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
-		   ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE
+		   ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \
+		   ARCH_AT91RM9200
 	help
 	  If you say Y here, the LEDs on your machine will be used
 	  to provide useful information about your current system status.
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index afaf3a1..1fa2a10 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -84,7 +84,6 @@
  machine-$(CONFIG_ARCH_PXA)	   := pxa
  machine-$(CONFIG_ARCH_L7200)	   := l7200
  machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
- machine-$(CONFIG_ARCH_CAMELOT)	   := epxa10db
  textofs-$(CONFIG_ARCH_CLPS711X)   := 0x00028000
  machine-$(CONFIG_ARCH_CLPS711X)   := clps711x
  machine-$(CONFIG_ARCH_IOP3XX)	   := iop3xx
@@ -100,6 +99,7 @@
  machine-$(CONFIG_ARCH_H720X)	   := h720x
  machine-$(CONFIG_ARCH_AAEC2000)   := aaec2000
  machine-$(CONFIG_ARCH_REALVIEW)   := realview
+ machine-$(CONFIG_ARCH_AT91RM9200) := at91rm9200
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
 # This is what happens if you forget the IOCS16 line.
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 6b505ce..35ffe0f 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -21,10 +21,6 @@
 OBJS		+= head-shark.o ofw-shark.o
 endif
 
-ifeq ($(CONFIG_ARCH_CAMELOT),y)
-OBJS		+= head-epxa10db.o
-endif
-
 ifeq ($(CONFIG_ARCH_L7200),y)
 OBJS		+= head-l7200.o
 endif
@@ -50,6 +46,10 @@
 OBJS		+= head-sharpsl.o
 endif
 
+ifeq ($(CONFIG_ARCH_AT91RM9200),y)
+OBJS		+= head-at91rm9200.o
+endif
+
 ifeq ($(CONFIG_DEBUG_ICEDCC),y)
 OBJS            += ice-dcc.o
 endif
diff --git a/arch/arm/boot/compressed/head-at91rm9200.S b/arch/arm/boot/compressed/head-at91rm9200.S
new file mode 100644
index 0000000..2119ea6
--- /dev/null
+++ b/arch/arm/boot/compressed/head-at91rm9200.S
@@ -0,0 +1,57 @@
+/*
+ * linux/arch/arm/boot/compressed/head-at91rm9200.S
+ *
+ *  Copyright (C) 2003 SAN People
+ *
+ * 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 <asm/mach-types.h>
+
+		.section	".start", "ax"
+
+		@ Atmel AT91RM9200-DK : 262
+		mov	r3,	#(MACH_TYPE_AT91RM9200DK & 0xff)
+		orr	r3, r3, #(MACH_TYPE_AT91RM9200DK & 0xff00)
+		cmp	r7, r3
+		beq	99f
+
+		@ Cogent CSB337 : 399
+		mov	r3,	#(MACH_TYPE_CSB337 & 0xff)
+		orr	r3, r3, #(MACH_TYPE_CSB337 & 0xff00)
+		cmp	r7, r3
+		beq	99f
+
+		@ Cogent CSB637 : 648
+		mov	r3,	#(MACH_TYPE_CSB637 & 0xff)
+		orr	r3, r3,	#(MACH_TYPE_CSB637 & 0xff00)
+		cmp	r7, r3
+		beq	99f
+
+		@ Atmel AT91RM9200-EK : 705
+		mov	r3,	#(MACH_TYPE_AT91RM9200EK & 0xff)
+		orr	r3, r3, #(MACH_TYPE_AT91RM9200EK & 0xff00)
+		cmp	r7, r3
+		beq	99f
+
+		@ Conitec Carmeva : 769
+		mov	r3,	#(MACH_TYPE_CARMEVA & 0xff)
+		orr	r3, r3, #(MACH_TYPE_CARMEVA & 0xff00)
+		cmp	r7, r3
+		beq	99f
+
+		@ KwikByte KB920x : 612
+		mov	r3,	#(MACH_TYPE_KB9200 & 0xff)
+		orr	r3, r3, #(MACH_TYPE_KB9200 & 0xff00)
+		cmp	r7, r3
+		beq	99f
+
+		@ Unknown board, use the AT91RM9200DK board
+		@ mov	r7, #MACH_TYPE_AT91RM9200
+		mov	r7,	#(MACH_TYPE_AT91RM9200DK & 0xff)
+		orr	r7, r7, #(MACH_TYPE_AT91RM9200DK & 0xff00)
+
+99:
diff --git a/arch/arm/boot/compressed/head-epxa10db.S b/arch/arm/boot/compressed/head-epxa10db.S
deleted file mode 100644
index 757681f..0000000
--- a/arch/arm/boot/compressed/head-epxa10db.S
+++ /dev/null
@@ -1,5 +0,0 @@
-#include <asm/mach-types.h>
-#include <asm/arch/excalibur.h>
-
-		.section	".start", "ax"
-		mov	r7, #MACH_TYPE_CAMELOT
diff --git a/arch/arm/configs/assabet_defconfig b/arch/arm/configs/assabet_defconfig
index ccbb4c0..089c9d5 100644
--- a/arch/arm/configs/assabet_defconfig
+++ b/arch/arm/configs/assabet_defconfig
@@ -63,7 +63,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/badge4_defconfig b/arch/arm/configs/badge4_defconfig
index 5d92af9..cfe6bd8 100644
--- a/arch/arm/configs/badge4_defconfig
+++ b/arch/arm/configs/badge4_defconfig
@@ -66,7 +66,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/bast_defconfig b/arch/arm/configs/bast_defconfig
index 35e3a99..6886001 100644
--- a/arch/arm/configs/bast_defconfig
+++ b/arch/arm/configs/bast_defconfig
@@ -64,7 +64,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/cerfcube_defconfig b/arch/arm/configs/cerfcube_defconfig
index d8fe0f4..f81a600 100644
--- a/arch/arm/configs/cerfcube_defconfig
+++ b/arch/arm/configs/cerfcube_defconfig
@@ -65,7 +65,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/clps7500_defconfig b/arch/arm/configs/clps7500_defconfig
index 9087583..af9ae53 100644
--- a/arch/arm/configs/clps7500_defconfig
+++ b/arch/arm/configs/clps7500_defconfig
@@ -57,7 +57,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig
index 40dfe07..15468a0 100644
--- a/arch/arm/configs/collie_defconfig
+++ b/arch/arm/configs/collie_defconfig
@@ -71,7 +71,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig
index 0622902..3c3461e 100644
--- a/arch/arm/configs/corgi_defconfig
+++ b/arch/arm/configs/corgi_defconfig
@@ -87,7 +87,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/ebsa110_defconfig b/arch/arm/configs/ebsa110_defconfig
index 6f61929..afcfff6 100644
--- a/arch/arm/configs/ebsa110_defconfig
+++ b/arch/arm/configs/ebsa110_defconfig
@@ -63,7 +63,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 CONFIG_ARCH_EBSA110=y
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/edb7211_defconfig b/arch/arm/configs/edb7211_defconfig
index 78b08ed..6ba7355 100644
--- a/arch/arm/configs/edb7211_defconfig
+++ b/arch/arm/configs/edb7211_defconfig
@@ -57,7 +57,6 @@
 CONFIG_ARCH_CLPS711X=y
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/enp2611_defconfig b/arch/arm/configs/enp2611_defconfig
index fd7c004..9592e39 100644
--- a/arch/arm/configs/enp2611_defconfig
+++ b/arch/arm/configs/enp2611_defconfig
@@ -86,7 +86,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/ep80219_defconfig b/arch/arm/configs/ep80219_defconfig
index 96342af..fbe312e 100644
--- a/arch/arm/configs/ep80219_defconfig
+++ b/arch/arm/configs/ep80219_defconfig
@@ -64,7 +64,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 CONFIG_ARCH_IOP3XX=y
diff --git a/arch/arm/configs/epxa10db_defconfig b/arch/arm/configs/epxa10db_defconfig
deleted file mode 100644
index 9fb8b58..0000000
--- a/arch/arm/configs/epxa10db_defconfig
+++ /dev/null
@@ -1,644 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 22:46:51 2005
-#
-CONFIG_ARM=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-# CONFIG_KMOD is not set
-
-#
-# System Type
-#
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-CONFIG_ARCH_CAMELOT=y
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_H720X is not set
-
-#
-# Epxa10db
-#
-
-#
-# PLD hotswap support
-#
-CONFIG_PLD=y
-# CONFIG_PLD_HOTSWAP is not set
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_ARM922T=y
-CONFIG_CPU_32v4=y
-CONFIG_CPU_ABRT_EV4T=y
-CONFIG_CPU_CACHE_V4WT=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_COPY_V4WB=y
-CONFIG_CPU_TLB_V4WBI=y
-
-#
-# Processor Features
-#
-# CONFIG_ARM_THUMB is not set
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-
-#
-# Bus support
-#
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# Kernel Features
-#
-# CONFIG_PREEMPT is not set
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyUA0,115200 initrd=0x00200000,8M root=/dev/ram0 rw"
-# CONFIG_XIP_KERNEL is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_ARTHUR is not set
-
-#
-# Power management options
-#
-# CONFIG_PM is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# SCSI device support
-#
-# CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-# CONFIG_IP_TCPDIAG is not set
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-# CONFIG_NET_ETHERNET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-CONFIG_PPP=y
-CONFIG_PPP_MULTILINK=y
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=y
-CONFIG_PPP_SYNC_TTY=y
-CONFIG_PPP_DEFLATE=y
-# CONFIG_PPP_BSDCOMP is not set
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_RAW is not set
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_UART00=y
-CONFIG_SERIAL_UART00_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB is not set
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-CONFIG_AUTOFS_FS=y
-CONFIG_AUTOFS4_FS=y
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
-# CONFIG_TMPFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-# CONFIG_NFS_FS is not set
-# CONFIG_NFSD is not set
-CONFIG_SMB_FS=y
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-CONFIG_CRC_CCITT=y
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/arm/configs/footbridge_defconfig b/arch/arm/configs/footbridge_defconfig
index 9737c48..2a612d2 100644
--- a/arch/arm/configs/footbridge_defconfig
+++ b/arch/arm/configs/footbridge_defconfig
@@ -63,7 +63,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 CONFIG_ARCH_FOOTBRIDGE=y
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/fortunet_defconfig b/arch/arm/configs/fortunet_defconfig
index b6f688d..65dc73a 100644
--- a/arch/arm/configs/fortunet_defconfig
+++ b/arch/arm/configs/fortunet_defconfig
@@ -57,7 +57,6 @@
 CONFIG_ARCH_CLPS711X=y
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig
index b9de07d..7a0da0b 100644
--- a/arch/arm/configs/h3600_defconfig
+++ b/arch/arm/configs/h3600_defconfig
@@ -65,7 +65,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/h7201_defconfig b/arch/arm/configs/h7201_defconfig
index 39c13a3..116920a 100644
--- a/arch/arm/configs/h7201_defconfig
+++ b/arch/arm/configs/h7201_defconfig
@@ -60,7 +60,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/h7202_defconfig b/arch/arm/configs/h7202_defconfig
index fbf5c24..9d62ed1 100644
--- a/arch/arm/configs/h7202_defconfig
+++ b/arch/arm/configs/h7202_defconfig
@@ -63,7 +63,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/hackkit_defconfig b/arch/arm/configs/hackkit_defconfig
index fb41a36..a45b575 100644
--- a/arch/arm/configs/hackkit_defconfig
+++ b/arch/arm/configs/hackkit_defconfig
@@ -66,7 +66,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig
index 27ee768..d1ba7fd 100644
--- a/arch/arm/configs/integrator_defconfig
+++ b/arch/arm/configs/integrator_defconfig
@@ -65,7 +65,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 CONFIG_ARCH_INTEGRATOR=y
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/iq31244_defconfig b/arch/arm/configs/iq31244_defconfig
index e71443b..c07628c 100644
--- a/arch/arm/configs/iq31244_defconfig
+++ b/arch/arm/configs/iq31244_defconfig
@@ -65,7 +65,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 CONFIG_ARCH_IOP3XX=y
diff --git a/arch/arm/configs/iq80321_defconfig b/arch/arm/configs/iq80321_defconfig
index ab5ad23..18fa161 100644
--- a/arch/arm/configs/iq80321_defconfig
+++ b/arch/arm/configs/iq80321_defconfig
@@ -64,7 +64,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 CONFIG_ARCH_IOP3XX=y
diff --git a/arch/arm/configs/iq80331_defconfig b/arch/arm/configs/iq80331_defconfig
index bb53613..f50035d 100644
--- a/arch/arm/configs/iq80331_defconfig
+++ b/arch/arm/configs/iq80331_defconfig
@@ -64,7 +64,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 CONFIG_ARCH_IOP3XX=y
diff --git a/arch/arm/configs/iq80332_defconfig b/arch/arm/configs/iq80332_defconfig
index 305f01f..18b3f37 100644
--- a/arch/arm/configs/iq80332_defconfig
+++ b/arch/arm/configs/iq80332_defconfig
@@ -64,7 +64,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 CONFIG_ARCH_IOP3XX=y
diff --git a/arch/arm/configs/ixdp2400_defconfig b/arch/arm/configs/ixdp2400_defconfig
index e6a4d26..d9d6bb8 100644
--- a/arch/arm/configs/ixdp2400_defconfig
+++ b/arch/arm/configs/ixdp2400_defconfig
@@ -86,7 +86,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/ixdp2401_defconfig b/arch/arm/configs/ixdp2401_defconfig
index 5572cf9..2dc9d49 100644
--- a/arch/arm/configs/ixdp2401_defconfig
+++ b/arch/arm/configs/ixdp2401_defconfig
@@ -86,7 +86,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/ixdp2800_defconfig b/arch/arm/configs/ixdp2800_defconfig
index 0fddbde..4248123 100644
--- a/arch/arm/configs/ixdp2800_defconfig
+++ b/arch/arm/configs/ixdp2800_defconfig
@@ -86,7 +86,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/ixdp2801_defconfig b/arch/arm/configs/ixdp2801_defconfig
index 89b9aa0..ea8f4b4 100644
--- a/arch/arm/configs/ixdp2801_defconfig
+++ b/arch/arm/configs/ixdp2801_defconfig
@@ -86,7 +86,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
index 613afab..4975b91 100644
--- a/arch/arm/configs/ixp4xx_defconfig
+++ b/arch/arm/configs/ixp4xx_defconfig
@@ -85,7 +85,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/jornada720_defconfig b/arch/arm/configs/jornada720_defconfig
index b88aeba..ad1048d 100644
--- a/arch/arm/configs/jornada720_defconfig
+++ b/arch/arm/configs/jornada720_defconfig
@@ -63,7 +63,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/lart_defconfig b/arch/arm/configs/lart_defconfig
index 7033829..c3a9328 100644
--- a/arch/arm/configs/lart_defconfig
+++ b/arch/arm/configs/lart_defconfig
@@ -62,7 +62,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/lpd7a400_defconfig b/arch/arm/configs/lpd7a400_defconfig
index d64706d..67eaa26 100644
--- a/arch/arm/configs/lpd7a400_defconfig
+++ b/arch/arm/configs/lpd7a400_defconfig
@@ -60,7 +60,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/lpd7a404_defconfig b/arch/arm/configs/lpd7a404_defconfig
index 87cbedf..208d591 100644
--- a/arch/arm/configs/lpd7a404_defconfig
+++ b/arch/arm/configs/lpd7a404_defconfig
@@ -60,7 +60,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/lubbock_defconfig b/arch/arm/configs/lubbock_defconfig
index 4bc8717..81daadc 100644
--- a/arch/arm/configs/lubbock_defconfig
+++ b/arch/arm/configs/lubbock_defconfig
@@ -63,7 +63,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/lusl7200_defconfig b/arch/arm/configs/lusl7200_defconfig
index 3ca64ca..42f6a77 100644
--- a/arch/arm/configs/lusl7200_defconfig
+++ b/arch/arm/configs/lusl7200_defconfig
@@ -62,7 +62,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/mainstone_defconfig b/arch/arm/configs/mainstone_defconfig
index 153d685..b112bd7 100644
--- a/arch/arm/configs/mainstone_defconfig
+++ b/arch/arm/configs/mainstone_defconfig
@@ -63,7 +63,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/mx1ads_defconfig b/arch/arm/configs/mx1ads_defconfig
index 6517d16..d16f6cd 100644
--- a/arch/arm/configs/mx1ads_defconfig
+++ b/arch/arm/configs/mx1ads_defconfig
@@ -63,7 +63,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/neponset_defconfig b/arch/arm/configs/neponset_defconfig
index 7fb1f7c..3d35255 100644
--- a/arch/arm/configs/neponset_defconfig
+++ b/arch/arm/configs/neponset_defconfig
@@ -65,7 +65,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/netwinder_defconfig b/arch/arm/configs/netwinder_defconfig
index 6e81acf..2cae1ea 100644
--- a/arch/arm/configs/netwinder_defconfig
+++ b/arch/arm/configs/netwinder_defconfig
@@ -58,7 +58,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 CONFIG_ARCH_FOOTBRIDGE=y
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/omap_h2_1610_defconfig b/arch/arm/configs/omap_h2_1610_defconfig
index 529f0f7..ee3ecbd 100644
--- a/arch/arm/configs/omap_h2_1610_defconfig
+++ b/arch/arm/configs/omap_h2_1610_defconfig
@@ -85,7 +85,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/pleb_defconfig b/arch/arm/configs/pleb_defconfig
index 10fec89..24e8bdd 100644
--- a/arch/arm/configs/pleb_defconfig
+++ b/arch/arm/configs/pleb_defconfig
@@ -63,7 +63,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/pxa255-idp_defconfig b/arch/arm/configs/pxa255-idp_defconfig
index 21c3278..b71d31a 100644
--- a/arch/arm/configs/pxa255-idp_defconfig
+++ b/arch/arm/configs/pxa255-idp_defconfig
@@ -63,7 +63,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/realview_defconfig b/arch/arm/configs/realview_defconfig
index 0485b2f..3f1ec4e 100644
--- a/arch/arm/configs/realview_defconfig
+++ b/arch/arm/configs/realview_defconfig
@@ -65,7 +65,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/rpc_defconfig b/arch/arm/configs/rpc_defconfig
index 19184c1..b498afd 100644
--- a/arch/arm/configs/rpc_defconfig
+++ b/arch/arm/configs/rpc_defconfig
@@ -66,7 +66,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
index 3f97590..33f3108 100644
--- a/arch/arm/configs/s3c2410_defconfig
+++ b/arch/arm/configs/s3c2410_defconfig
@@ -85,7 +85,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/shannon_defconfig b/arch/arm/configs/shannon_defconfig
index e3facc4..d052c8f 100644
--- a/arch/arm/configs/shannon_defconfig
+++ b/arch/arm/configs/shannon_defconfig
@@ -62,7 +62,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/shark_defconfig b/arch/arm/configs/shark_defconfig
index 271823f..c48d170 100644
--- a/arch/arm/configs/shark_defconfig
+++ b/arch/arm/configs/shark_defconfig
@@ -66,7 +66,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/simpad_defconfig b/arch/arm/configs/simpad_defconfig
index 5373eeb..2e5a616 100644
--- a/arch/arm/configs/simpad_defconfig
+++ b/arch/arm/configs/simpad_defconfig
@@ -64,7 +64,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/smdk2410_defconfig b/arch/arm/configs/smdk2410_defconfig
index 2c60865..4d123d3 100644
--- a/arch/arm/configs/smdk2410_defconfig
+++ b/arch/arm/configs/smdk2410_defconfig
@@ -58,7 +58,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig
index 9895539..d1ace3a 100644
--- a/arch/arm/configs/spitz_defconfig
+++ b/arch/arm/configs/spitz_defconfig
@@ -87,7 +87,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig
index d72f2c7..2687a22 100644
--- a/arch/arm/configs/versatile_defconfig
+++ b/arch/arm/configs/versatile_defconfig
@@ -64,7 +64,6 @@
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index b5645c4..1d50d2b 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -710,7 +710,8 @@
 		desc->pending = 0;
 		desc->disable_depth = 1;
 
-		if (new->flags & SA_TRIGGER_MASK) {
+		if (new->flags & SA_TRIGGER_MASK &&
+		    desc->chip->set_type) {
 			unsigned int type = new->flags & SA_TRIGGER_MASK;
 			desc->chip->set_type(irq, type);
 		}
diff --git a/arch/arm/mach-at91rm9200/Kconfig b/arch/arm/mach-at91rm9200/Kconfig
new file mode 100644
index 0000000..4b7218f
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/Kconfig
@@ -0,0 +1,54 @@
+if ARCH_AT91RM9200
+
+menu "AT91RM9200 Implementations"
+
+comment "AT91RM9200 Board Type"
+
+config ARCH_AT91RM9200DK
+	bool "Atmel AT91RM9200-DK Development board"
+	depends on ARCH_AT91RM9200
+	help
+	  Select this if you are using Atmel's AT91RM9200-DK Development board
+
+config MACH_AT91RM9200EK
+	bool "Atmel AT91RM9200-EK Evaluation Kit"
+	depends on ARCH_AT91RM9200
+	help
+	  Select this if you are using Atmel's AT91RM9200-EK Evaluation Kit
+
+config MACH_CSB337
+	bool "Cogent CSB337 board"
+	depends on ARCH_AT91RM9200
+	help
+	  Select this if you are using Cogent's CSB337 board
+
+config MACH_CSB637
+	bool "Cogent CSB637 board"
+	depends on ARCH_AT91RM9200
+	help
+	  Select this if you are using Cogent's CSB637 board
+
+config MACH_CARMEVA
+	bool "Conitec's ARM&EVA"
+	depends on ARCH_AT91RM9200
+	help
+	  Select this if you are using Conitec's AT91RM9200-MCU-Module
+
+config MACH_KB9200
+	bool "KwikByte's KB920x"
+	depends on ARCH_AT91RM9200
+	help
+	  Select this if you are using KwikByte's KB920x board
+
+
+comment "AT91RM9200 Feature Selections"
+
+config AT91_PROGRAMMABLE_CLOCKS
+	bool "Programmable Clocks"
+	help
+	  Select this if you need to program one or more of the PCK0..PCK3
+	  programmable clock outputs.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile
new file mode 100644
index 0000000..1f2805ca
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/Makefile
@@ -0,0 +1,27 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y		:= clock.o irq.o time.o gpio.o common.o devices.o
+obj-m		:=
+obj-n		:=
+obj-		:=
+
+# Board-specific support
+#obj-$(CONFIG_ARCH_AT91RM9200DK)	+= board-dk.o
+#obj-$(CONFIG_MACH_AT91RM9200EK)	+= board-ek.o
+#obj-$(CONFIG_MACH_CSB337)	+= board-csb337.o
+#obj-$(CONFIG_MACH_CSB637)	+= board-csb637.o
+#obj-$(CONFIG_MACH_CARMEVA)	+= board-carmeva.o
+#obj-$(CONFIG_MACH_KB9200)	+= board-kb9202.o
+
+# LEDs support
+#led-$(CONFIG_ARCH_AT91RM9200DK)	+= leds.o
+#led-$(CONFIG_MACH_AT91RM9200EK)	+= leds.o
+#led-$(CONFIG_MACH_CSB337)	+= leds.o
+#led-$(CONFIG_MACH_CSB637)	+= leds.o
+#led-$(CONFIG_MACH_KB9200)	+= leds.o
+obj-$(CONFIG_LEDS) += $(led-y)
+
+# VGA support
+#obj-$(CONFIG_FB_S1D13XXX)	+= ics1523.o
diff --git a/arch/arm/mach-at91rm9200/Makefile.boot b/arch/arm/mach-at91rm9200/Makefile.boot
new file mode 100644
index 0000000..e667dcc
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/Makefile.boot
@@ -0,0 +1,9 @@
+# Note: the following conditions must always be true:
+#   ZRELADDR == virt_to_phys(TEXTADDR)
+#   PARAMS_PHYS must be within 4MB of ZRELADDR
+#   INITRD_PHYS must be in RAM
+
+   zreladdr-y	:= 0x20008000
+params_phys-y	:= 0x20000100
+initrd_phys-y	:= 0x20410000
+
diff --git a/arch/arm/mach-at91rm9200/clock.c b/arch/arm/mach-at91rm9200/clock.c
new file mode 100644
index 0000000..ec8195a
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/clock.c
@@ -0,0 +1,620 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/clock.c
+ *
+ * Copyright (C) 2005 David Brownell
+ * Copyright (C) 2005 Ivan Kokshaysky
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+
+#include <asm/semaphore.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/board.h>		/* for master clock global */
+
+#include "generic.h"
+
+#undef	DEBUG
+
+/*
+ * There's a lot more which can be done with clocks, including cpufreq
+ * integration, slow clock mode support (for system suspend), letting
+ * PLLB be used at other rates (on boards that don't need USB), etc.
+ */
+
+struct clk {
+	const char	*name;
+	unsigned long	rate_hz;
+	struct clk	*parent;
+	u32		pmc_mask;
+	void		(*mode)(struct clk *, int);
+	unsigned	id:2;		/* PCK0..3, or 32k/main/a/b */
+	unsigned	primary:1;
+	unsigned	pll:1;
+	unsigned	programmable:1;
+	u16		users;
+};
+
+static spinlock_t	clk_lock;
+static u32		at91_pllb_usb_init;
+
+/*
+ * Four primary clock sources:  two crystal oscillators (32K, main), and
+ * two PLLs.  PLLA usually runs the master clock; and PLLB must run at
+ * 48 MHz (unless no USB function clocks are needed).  The main clock and
+ * both PLLs are turned off to run in "slow clock mode" (system suspend).
+ */
+static struct clk clk32k = {
+	.name		= "clk32k",
+	.rate_hz	= AT91_SLOW_CLOCK,
+	.users		= 1,		/* always on */
+	.id		= 0,
+	.primary	= 1,
+};
+static struct clk main_clk = {
+	.name		= "main",
+	.pmc_mask	= 1 << 0,	/* in PMC_SR */
+	.users		= 1,
+	.id		= 1,
+	.primary	= 1,
+};
+static struct clk plla = {
+	.name		= "plla",
+	.parent		= &main_clk,
+	.pmc_mask	= 1 << 1,	/* in PMC_SR */
+	.id		= 2,
+	.primary	= 1,
+	.pll		= 1,
+};
+
+static void pllb_mode(struct clk *clk, int is_on)
+{
+	u32	value;
+
+	if (is_on) {
+		is_on = AT91_PMC_LOCKB;
+		value = at91_pllb_usb_init;
+	} else
+		value = 0;
+
+	at91_sys_write(AT91_CKGR_PLLBR, value);
+
+	do {
+		cpu_relax();
+	} while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != is_on);
+}
+
+static struct clk pllb = {
+	.name		= "pllb",
+	.parent		= &main_clk,
+	.pmc_mask	= 1 << 2,	/* in PMC_SR */
+	.mode		= pllb_mode,
+	.id		= 3,
+	.primary	= 1,
+	.pll		= 1,
+};
+
+static void pmc_sys_mode(struct clk *clk, int is_on)
+{
+	if (is_on)
+		at91_sys_write(AT91_PMC_SCER, clk->pmc_mask);
+	else
+		at91_sys_write(AT91_PMC_SCDR, clk->pmc_mask);
+}
+
+/* USB function clocks (PLLB must be 48 MHz) */
+static struct clk udpck = {
+	.name		= "udpck",
+	.parent		= &pllb,
+	.pmc_mask	= AT91_PMC_UDP,
+	.mode		= pmc_sys_mode,
+};
+static struct clk uhpck = {
+	.name		= "uhpck",
+	.parent		= &pllb,
+	.pmc_mask	= AT91_PMC_UHP,
+	.mode		= pmc_sys_mode,
+};
+
+#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
+/*
+ * The four programmable clocks can be parented by any primary clock.
+ * You must configure pin multiplexing to bring these signals out.
+ */
+static struct clk pck0 = {
+	.name		= "pck0",
+	.pmc_mask	= AT91_PMC_PCK0,
+	.mode		= pmc_sys_mode,
+	.programmable	= 1,
+	.id		= 0,
+};
+static struct clk pck1 = {
+	.name		= "pck1",
+	.pmc_mask	= AT91_PMC_PCK1,
+	.mode		= pmc_sys_mode,
+	.programmable	= 1,
+	.id		= 1,
+};
+static struct clk pck2 = {
+	.name		= "pck2",
+	.pmc_mask	= AT91_PMC_PCK2,
+	.mode		= pmc_sys_mode,
+	.programmable	= 1,
+	.id		= 2,
+};
+static struct clk pck3 = {
+	.name		= "pck3",
+	.pmc_mask	= AT91_PMC_PCK3,
+	.mode		= pmc_sys_mode,
+	.programmable	= 1,
+	.id		= 3,
+};
+#endif	/* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
+
+
+/*
+ * The master clock is divided from the CPU clock (by 1-4).  It's used for
+ * memory, interfaces to on-chip peripherals, the AIC, and sometimes more
+ * (e.g baud rate generation).  It's sourced from one of the primary clocks.
+ */
+static struct clk mck = {
+	.name		= "mck",
+	.pmc_mask	= 1 << 3,	/* in PMC_SR */
+	.users		= 1,		/* (must be) always on */
+};
+
+static void pmc_periph_mode(struct clk *clk, int is_on)
+{
+	if (is_on)
+		at91_sys_write(AT91_PMC_PCER, clk->pmc_mask);
+	else
+		at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask);
+}
+
+static struct clk udc_clk = {
+	.name		= "udc_clk",
+	.parent		= &mck,
+	.pmc_mask	= 1 << AT91_ID_UDP,
+	.mode		= pmc_periph_mode,
+};
+static struct clk ohci_clk = {
+	.name		= "ohci_clk",
+	.parent		= &mck,
+	.pmc_mask	= 1 << AT91_ID_UHP,
+	.mode		= pmc_periph_mode,
+};
+
+static struct clk *const clock_list[] = {
+	/* four primary clocks -- MUST BE FIRST! */
+	&clk32k,
+	&main_clk,
+	&plla,
+	&pllb,
+
+	/* PLLB children (USB) */
+	&udpck,
+	&uhpck,
+
+#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
+	/* programmable clocks */
+	&pck0,
+	&pck1,
+	&pck2,
+	&pck3,
+#endif	/* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
+
+	/* MCK and peripherals */
+	&mck,
+	// usart0..usart3
+	// mmc
+	&udc_clk,
+	// i2c
+	// spi
+	// ssc0..ssc2
+	// tc0..tc5
+	&ohci_clk,
+	// ether
+};
+
+
+/* clocks are all static for now; no refcounting necessary */
+struct clk *clk_get(struct device *dev, const char *id)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(clock_list); i++) {
+		if (strcmp(id, clock_list[i]->name) == 0)
+			return clock_list[i];
+	}
+
+	return ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
+
+static void __clk_enable(struct clk *clk)
+{
+	if (clk->parent)
+		__clk_enable(clk->parent);
+	if (clk->users++ == 0 && clk->mode)
+		clk->mode(clk, 1);
+}
+
+int clk_enable(struct clk *clk)
+{
+	unsigned long	flags;
+
+	spin_lock_irqsave(&clk_lock, flags);
+	__clk_enable(clk);
+	spin_unlock_irqrestore(&clk_lock, flags);
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+static void __clk_disable(struct clk *clk)
+{
+	BUG_ON(clk->users == 0);
+	if (--clk->users == 0 && clk->mode)
+		clk->mode(clk, 0);
+	if (clk->parent)
+		__clk_disable(clk->parent);
+}
+
+void clk_disable(struct clk *clk)
+{
+	unsigned long	flags;
+
+	spin_lock_irqsave(&clk_lock, flags);
+	__clk_disable(clk);
+	spin_unlock_irqrestore(&clk_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	unsigned long	flags;
+	unsigned long	rate;
+
+	spin_lock_irqsave(&clk_lock, flags);
+	for (;;) {
+		rate = clk->rate_hz;
+		if (rate || !clk->parent)
+			break;
+		clk = clk->parent;
+	}
+	spin_unlock_irqrestore(&clk_lock, flags);
+	return rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/*------------------------------------------------------------------------*/
+
+#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
+
+/*
+ * For now, only the programmable clocks support reparenting (MCK could
+ * do this too, with care) or rate changing (the PLLs could do this too,
+ * ditto MCK but that's more for cpufreq).  Drivers may reparent to get
+ * a better rate match; we don't.
+ */
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long	flags;
+	unsigned	prescale;
+	unsigned long	actual;
+
+	if (!clk->programmable)
+		return -EINVAL;
+	spin_lock_irqsave(&clk_lock, flags);
+
+	actual = clk->parent->rate_hz;
+	for (prescale = 0; prescale < 7; prescale++) {
+		if (actual && actual <= rate)
+			break;
+		actual >>= 1;
+	}
+
+	spin_unlock_irqrestore(&clk_lock, flags);
+	return (prescale < 7) ? actual : -ENOENT;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long	flags;
+	unsigned	prescale;
+	unsigned long	actual;
+
+	if (!clk->programmable)
+		return -EINVAL;
+	if (clk->users)
+		return -EBUSY;
+	spin_lock_irqsave(&clk_lock, flags);
+
+	actual = clk->parent->rate_hz;
+	for (prescale = 0; prescale < 7; prescale++) {
+		if (actual && actual <= rate) {
+			u32	pckr;
+
+			pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
+			pckr &= 0x03;
+			pckr |= prescale << 2;
+			at91_sys_write(AT91_PMC_PCKR(clk->id), pckr);
+			clk->rate_hz = actual;
+			break;
+		}
+		actual >>= 1;
+	}
+
+	spin_unlock_irqrestore(&clk_lock, flags);
+	return (prescale < 7) ? actual : -ENOENT;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+	return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	unsigned long	flags;
+
+	if (clk->users)
+		return -EBUSY;
+	if (!parent->primary || !clk->programmable)
+		return -EINVAL;
+	spin_lock_irqsave(&clk_lock, flags);
+
+	clk->rate_hz = parent->rate_hz;
+	clk->parent = parent;
+	at91_sys_write(AT91_PMC_PCKR(clk->id), parent->id);
+
+	spin_unlock_irqrestore(&clk_lock, flags);
+	return 0;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+#endif	/* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
+
+/*------------------------------------------------------------------------*/
+
+#ifdef CONFIG_DEBUG_FS
+
+static int at91_clk_show(struct seq_file *s, void *unused)
+{
+	u32		scsr, pcsr, sr;
+	unsigned	i;
+
+	seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR));
+	seq_printf(s, "PCSR = %8x\n", pcsr = at91_sys_read(AT91_PMC_PCSR));
+
+	seq_printf(s, "MOR  = %8x\n", at91_sys_read(AT91_CKGR_MOR));
+	seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR));
+	seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR));
+	seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR));
+
+	seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR));
+	for (i = 0; i < 4; i++)
+		seq_printf(s, "PCK%d = %8x\n", i, at91_sys_read(AT91_PMC_PCKR(i)));
+	seq_printf(s, "SR   = %8x\n", sr = at91_sys_read(AT91_PMC_SR));
+
+	seq_printf(s, "\n");
+
+	for (i = 0; i < ARRAY_SIZE(clock_list); i++) {
+		char		*state;
+		struct clk	*clk = clock_list[i];
+
+		if (clk->mode == pmc_sys_mode)
+			state = (scsr & clk->pmc_mask) ? "on" : "off";
+		else if (clk->mode == pmc_periph_mode)
+			state = (pcsr & clk->pmc_mask) ? "on" : "off";
+		else if (clk->pmc_mask)
+			state = (sr & clk->pmc_mask) ? "on" : "off";
+		else if (clk == &clk32k || clk == &main_clk)
+			state = "on";
+		else
+			state = "";
+
+		seq_printf(s, "%-10s users=%d %-3s %9ld Hz %s\n",
+			clk->name, clk->users, state, clk_get_rate(clk),
+			clk->parent ? clk->parent->name : "");
+	}
+	return 0;
+}
+
+static int at91_clk_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, at91_clk_show, NULL);
+}
+
+static struct file_operations at91_clk_operations = {
+	.open		= at91_clk_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __init at91_clk_debugfs_init(void)
+{
+	/* /sys/kernel/debug/at91_clk */
+	(void) debugfs_create_file("at91_clk", S_IFREG | S_IRUGO, NULL, NULL, &at91_clk_operations);
+
+	return 0;
+}
+postcore_initcall(at91_clk_debugfs_init);
+
+#endif
+
+/*------------------------------------------------------------------------*/
+
+static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg)
+{
+	unsigned mul, div;
+
+	div = reg & 0xff;
+	mul = (reg >> 16) & 0x7ff;
+	if (div && mul) {
+		freq /= div;
+		freq *= mul + 1;
+	} else
+		freq = 0;
+	if (pll == &pllb && (reg & (1 << 28)))
+		freq /= 2;
+	return freq;
+}
+
+static unsigned __init at91_pll_calc(unsigned main_freq, unsigned out_freq)
+{
+	unsigned i, div = 0, mul = 0, diff = 1 << 30;
+	unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00;
+
+	/* PLL output max 240 MHz (or 180 MHz per errata) */
+	if (out_freq > 240000000)
+		goto fail;
+
+	for (i = 1; i < 256; i++) {
+		int diff1;
+		unsigned input, mul1;
+
+		/*
+		 * PLL input between 1MHz and 32MHz per spec, but lower
+		 * frequences seem necessary in some cases so allow 100K.
+		 */
+		input = main_freq / i;
+		if (input < 100000)
+			continue;
+		if (input > 32000000)
+			continue;
+
+		mul1 = out_freq / input;
+		if (mul1 > 2048)
+			continue;
+		if (mul1 < 2)
+			goto fail;
+
+		diff1 = out_freq - input * mul1;
+		if (diff1 < 0)
+			diff1 = -diff1;
+		if (diff > diff1) {
+			diff = diff1;
+			div = i;
+			mul = mul1;
+			if (diff == 0)
+				break;
+		}
+	}
+	if (i == 256 && diff > (out_freq >> 5))
+		goto fail;
+	return ret | ((mul - 1) << 16) | div;
+fail:
+	return 0;
+}
+
+int __init at91_clock_init(unsigned long main_clock)
+{
+	unsigned tmp, freq, mckr;
+
+	spin_lock_init(&clk_lock);
+
+	/*
+	 * When the bootloader initialized the main oscillator correctly,
+	 * there's no problem using the cycle counter.  But if it didn't,
+	 * or when using oscillator bypass mode, we must be told the speed
+	 * of the main clock.
+	 */
+	if (!main_clock) {
+		do {
+			tmp = at91_sys_read(AT91_CKGR_MCFR);
+		} while (!(tmp & 0x10000));
+		main_clock = (tmp & 0xffff) * (AT91_SLOW_CLOCK / 16);
+	}
+	main_clk.rate_hz = main_clock;
+
+	/* report if PLLA is more than mildly overclocked */
+	plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR));
+	if (plla.rate_hz > 209000000)
+		pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
+
+	/*
+	 * USB clock init:  choose 48 MHz PLLB value, turn all clocks off,
+	 * disable 48MHz clock during usb peripheral suspend.
+	 *
+	 * REVISIT:  assumes MCK doesn't derive from PLLB!
+	 */
+	at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | 0x10000000;
+	pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init);
+	at91_sys_write(AT91_PMC_PCDR, (1 << AT91_ID_UHP) | (1 << AT91_ID_UDP));
+	at91_sys_write(AT91_PMC_SCDR, AT91_PMC_UHP | AT91_PMC_UDP);
+	at91_sys_write(AT91_CKGR_PLLBR, 0);
+	at91_sys_write(AT91_PMC_SCER, AT91_PMC_MCKUDP);
+
+	/*
+	 * MCK and CPU derive from one of those primary clocks.
+	 * For now, assume this parentage won't change.
+	 */
+	mckr = at91_sys_read(AT91_PMC_MCKR);
+	mck.parent = clock_list[mckr & AT91_PMC_CSS];
+	mck.parent->users++;
+	freq = mck.parent->rate_hz;
+	freq /= (1 << ((mckr >> 2) & 3));		/* prescale */
+	mck.rate_hz = freq / (1 + ((mckr >> 8) & 3));	/* mdiv */
+
+	printk("Clocks: CPU %u MHz, master %u MHz, main %u.%03u MHz\n",
+		freq / 1000000, (unsigned) mck.rate_hz / 1000000,
+		(unsigned) main_clock / 1000000,
+		((unsigned) main_clock % 1000000) / 1000);
+
+	/* FIXME get rid of master_clock global */
+	at91_master_clock = mck.rate_hz;
+
+#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
+	/* establish PCK0..PCK3 parentage */
+	for (tmp = 0; tmp < ARRAY_SIZE(clock_list); tmp++) {
+		struct clk	*clk = clock_list[tmp], *parent;
+		u32		pckr;
+
+		if (!clk->programmable)
+			continue;
+
+		pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
+		parent = clock_list[pckr & 3];
+		clk->parent = parent;
+		clk->rate_hz = parent->rate_hz / (1 << ((pckr >> 2) & 3));
+	}
+#else
+	/* disable unused clocks */
+	at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK0 | AT91_PMC_PCK1 | AT91_PMC_PCK2 | AT91_PMC_PCK3);
+#endif	/* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
+
+	/* FIXME several unused clocks may still be active...  provide
+	 * a CONFIG option to turn off all unused clocks at some point
+	 * before driver init starts.
+	 */
+
+	return 0;
+}
diff --git a/arch/arm/mach-at91rm9200/common.c b/arch/arm/mach-at91rm9200/common.c
new file mode 100644
index 0000000..3848fd2
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/common.c
@@ -0,0 +1,115 @@
+/*
+ * arch/arm/mach-at91rm9200/common.c
+ *
+ *  Copyright (C) 2005 SAN People
+ *
+ * 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/config.h>
+#include <linux/module.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/hardware.h>
+
+static struct map_desc at91rm9200_io_desc[] __initdata = {
+	{
+		.virtual	= AT91_VA_BASE_SYS,
+		.pfn		= __phys_to_pfn(AT91_BASE_SYS),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_SPI,
+		.pfn		= __phys_to_pfn(AT91_BASE_SPI),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_SSC2,
+		.pfn		= __phys_to_pfn(AT91_BASE_SSC2),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_SSC1,
+		.pfn		= __phys_to_pfn(AT91_BASE_SSC1),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_SSC0,
+		.pfn		= __phys_to_pfn(AT91_BASE_SSC0),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_US3,
+		.pfn		= __phys_to_pfn(AT91_BASE_US3),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_US2,
+		.pfn		= __phys_to_pfn(AT91_BASE_US2),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_US1,
+		.pfn		= __phys_to_pfn(AT91_BASE_US1),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_US0,
+		.pfn		= __phys_to_pfn(AT91_BASE_US0),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_EMAC,
+		.pfn		= __phys_to_pfn(AT91_BASE_EMAC),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_TWI,
+		.pfn		= __phys_to_pfn(AT91_BASE_TWI),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_MCI,
+		.pfn		= __phys_to_pfn(AT91_BASE_MCI),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_UDP,
+		.pfn		= __phys_to_pfn(AT91_BASE_UDP),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_TCB1,
+		.pfn		= __phys_to_pfn(AT91_BASE_TCB1),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_VA_BASE_TCB0,
+		.pfn		= __phys_to_pfn(AT91_BASE_TCB0),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	},
+};
+
+void __init at91rm9200_map_io(void)
+{
+	iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc));
+}
+
+
+unsigned long at91_master_clock;
+
+EXPORT_SYMBOL(at91_master_clock);
+
+
+int at91_serial_map[AT91_NR_UART];
+int at91_console_port;
+
+EXPORT_SYMBOL(at91_serial_map);
+EXPORT_SYMBOL(at91_console_port);
diff --git a/arch/arm/mach-at91rm9200/devices.c b/arch/arm/mach-at91rm9200/devices.c
new file mode 100644
index 0000000..8df3e52
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/devices.c
@@ -0,0 +1,291 @@
+/*
+ * arch/arm/mach-at91rm9200/devices.c
+ *
+ *  Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
+ *  Copyright (C) 2005 David Brownell
+ *
+ * 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 <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <linux/config.h>
+#include <linux/platform_device.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/pio.h>
+
+
+/* --------------------------------------------------------------------
+ *  USB Host
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static u64 ohci_dmamask = 0xffffffffUL;
+static struct at91_usbh_data usbh_data;
+
+static struct resource at91rm9200_usbh_resource[] = {
+	[0] = {
+		.start	= AT91_UHP_BASE,
+		.end	= AT91_UHP_BASE + SZ_1M -1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91_ID_UHP,
+		.end	= AT91_ID_UHP,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91rm9200_usbh_device = {
+	.name		= "at91rm9200-ohci",
+	.id		= -1,
+	.dev		= {
+				.dma_mask		= &ohci_dmamask,
+				.coherent_dma_mask	= 0xffffffff,
+				.platform_data		= &usbh_data,
+	},
+	.resource	= at91rm9200_usbh_resource,
+	.num_resources	= ARRAY_SIZE(at91rm9200_usbh_resource),
+};
+
+void __init at91_add_device_usbh(struct at91_usbh_data *data)
+{
+	if (!data)
+		return;
+
+	usbh_data = *data;
+	platform_device_register(&at91rm9200_usbh_device);
+}
+#else
+void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  USB Device (Gadget)
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_USB_GADGET_AT91
+static struct at91_udc_data udc_data;
+
+static struct resource at91_udc_resources[] = {
+	{
+		.start	= AT91_BASE_UDP,
+		.end	= AT91_BASE_UDP + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device at91rm9200_udc_device = {
+	.name		= "at91_udc",
+	.id		= -1,
+	.dev		= {
+				.platform_data		= &udc_data,
+	},
+	.resource	= at91_udc_resources,
+	.num_resources	= ARRAY_SIZE(at91_udc_resources),
+};
+
+void __init at91_add_device_udc(struct at91_udc_data *data)
+{
+	if (!data)
+		return;
+
+	if (data->vbus_pin) {
+		at91_set_gpio_input(data->vbus_pin, 0);
+		at91_set_deglitch(data->vbus_pin, 1);
+	}
+	if (data->pullup_pin)
+		at91_set_gpio_output(data->pullup_pin, 0);
+
+	udc_data = *data;
+	platform_device_register(&at91rm9200_udc_device);
+}
+#else
+void __init at91_add_device_udc(struct at91_udc_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  Ethernet
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_ARM_AT91_ETHER) || defined(CONFIG_ARM_AT91_ETHER_MODULE)
+static u64 eth_dmamask = 0xffffffffUL;
+static struct at91_eth_data eth_data;
+
+static struct platform_device at91rm9200_eth_device = {
+	.name		= "at91_ether",
+	.id		= -1,
+	.dev		= {
+				.dma_mask		= &eth_dmamask,
+				.coherent_dma_mask	= 0xffffffff,
+				.platform_data		= &eth_data,
+	},
+	.num_resources	= 0,
+};
+
+void __init at91_add_device_eth(struct at91_eth_data *data)
+{
+	if (!data)
+		return;
+
+	if (data->phy_irq_pin) {
+		at91_set_gpio_input(data->phy_irq_pin, 0);
+		at91_set_deglitch(data->phy_irq_pin, 1);
+	}
+
+	/* Pins used for MII and RMII */
+	at91_set_A_periph(AT91_PIN_PA16, 0);	/* EMDIO */
+	at91_set_A_periph(AT91_PIN_PA15, 0);	/* EMDC */
+	at91_set_A_periph(AT91_PIN_PA14, 0);	/* ERXER */
+	at91_set_A_periph(AT91_PIN_PA13, 0);	/* ERX1 */
+	at91_set_A_periph(AT91_PIN_PA12, 0);	/* ERX0 */
+	at91_set_A_periph(AT91_PIN_PA11, 0);	/* ECRS_ECRSDV */
+	at91_set_A_periph(AT91_PIN_PA10, 0);	/* ETX1 */
+	at91_set_A_periph(AT91_PIN_PA9, 0);	/* ETX0 */
+	at91_set_A_periph(AT91_PIN_PA8, 0);	/* ETXEN */
+	at91_set_A_periph(AT91_PIN_PA7, 0);	/* ETXCK_EREFCK */
+
+	if (!data->is_rmii) {
+		at91_set_B_periph(AT91_PIN_PB19, 0);	/* ERXCK */
+		at91_set_B_periph(AT91_PIN_PB18, 0);	/* ECOL */
+		at91_set_B_periph(AT91_PIN_PB17, 0);	/* ERXDV */
+		at91_set_B_periph(AT91_PIN_PB16, 0);	/* ERX3 */
+		at91_set_B_periph(AT91_PIN_PB15, 0);	/* ERX2 */
+		at91_set_B_periph(AT91_PIN_PB14, 0);	/* ETXER */
+		at91_set_B_periph(AT91_PIN_PB13, 0);	/* ETX3 */
+		at91_set_B_periph(AT91_PIN_PB12, 0);	/* ETX2 */
+	}
+
+	eth_data = *data;
+	platform_device_register(&at91rm9200_eth_device);
+}
+#else
+void __init at91_add_device_eth(struct at91_eth_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  Compact Flash / PCMCIA
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE)
+static struct at91_cf_data cf_data;
+
+static struct platform_device at91rm9200_cf_device = {
+	.name		= "at91_cf",
+	.id		= -1,
+	.dev		= {
+				.platform_data		= &cf_data,
+	},
+	.num_resources	= 0,
+};
+
+void __init at91_add_device_cf(struct at91_cf_data *data)
+{
+	if (!data)
+		return;
+
+	/* input/irq */
+	if (data->irq_pin) {
+		at91_set_gpio_input(data->irq_pin, 1);
+		at91_set_deglitch(data->irq_pin, 1);
+	}
+	at91_set_gpio_input(data->det_pin, 1);
+	at91_set_deglitch(data->det_pin, 1);
+
+	/* outputs, initially off */
+	if (data->vcc_pin)
+		at91_set_gpio_output(data->vcc_pin, 0);
+	at91_set_gpio_output(data->rst_pin, 0);
+
+	cf_data = *data;
+	platform_device_register(&at91rm9200_cf_device);
+}
+#else
+void __init at91_add_device_cf(struct at91_cf_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  MMC / SD
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MMC_AT91RM9200) || defined(CONFIG_MMC_AT91RM9200_MODULE)
+static u64 mmc_dmamask = 0xffffffffUL;
+static struct at91_mmc_data mmc_data;
+
+static struct resource at91_mmc_resources[] = {
+	{
+		.start	= AT91_BASE_MCI,
+		.end	= AT91_BASE_MCI + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device at91rm9200_mmc_device = {
+	.name		= "at91rm9200_mci",
+	.id		= -1,
+	.dev		= {
+				.dma_mask		= &mmc_dmamask,
+				.coherent_dma_mask	= 0xffffffff,
+				.platform_data		= &mmc_data,
+	},
+	.resource	= at91_mmc_resources,
+	.num_resources	= ARRAY_SIZE(at91_mmc_resources),
+};
+
+void __init at91_add_device_mmc(struct at91_mmc_data *data)
+{
+	if (!data)
+		return;
+
+	/* input/irq */
+	if (data->det_pin) {
+		at91_set_gpio_input(data->det_pin, 1);
+		at91_set_deglitch(data->det_pin, 1);
+	}
+	if (data->wp_pin)
+		at91_set_gpio_input(data->wp_pin, 1);
+
+	/* CLK */
+	at91_set_A_periph(AT91_PIN_PA27, 0);
+
+	if (data->is_b) {
+		/* CMD */
+		at91_set_B_periph(AT91_PIN_PA8, 0);
+
+		/* DAT0, maybe DAT1..DAT3 */
+		at91_set_B_periph(AT91_PIN_PA9, 0);
+		if (data->wire4) {
+			at91_set_B_periph(AT91_PIN_PA10, 0);
+			at91_set_B_periph(AT91_PIN_PA11, 0);
+			at91_set_B_periph(AT91_PIN_PA12, 0);
+		}
+	} else {
+		/* CMD */
+		at91_set_A_periph(AT91_PIN_PA28, 0);
+
+		/* DAT0, maybe DAT1..DAT3 */
+		at91_set_A_periph(AT91_PIN_PA29, 0);
+		if (data->wire4) {
+			at91_set_B_periph(AT91_PIN_PB3, 0);
+			at91_set_B_periph(AT91_PIN_PB4, 0);
+			at91_set_B_periph(AT91_PIN_PB5, 0);
+		}
+	}
+
+	mmc_data = *data;
+	platform_device_register(&at91rm9200_mmc_device);
+}
+#else
+void __init at91_add_device_mmc(struct at91_mmc_data *data) {}
+#endif
+
+/* -------------------------------------------------------------------- */
diff --git a/arch/arm/mach-at91rm9200/generic.h b/arch/arm/mach-at91rm9200/generic.h
new file mode 100644
index 0000000..9bd541e
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/generic.h
@@ -0,0 +1,18 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/generic.h
+ *
+ *  Copyright (C) 2005 David Brownell
+ *
+ * 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.
+ */
+
+void at91_gpio_irq_setup(unsigned banks);
+
+struct sys_timer;
+extern struct sys_timer at91rm9200_timer;
+
+extern void __init at91rm9200_map_io(void);
+
+extern int __init at91_clock_init(unsigned long main_clock);
diff --git a/arch/arm/mach-at91rm9200/gpio.c b/arch/arm/mach-at91rm9200/gpio.c
new file mode 100644
index 0000000..2fd2ef5
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/gpio.c
@@ -0,0 +1,302 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/gpio.c
+ *
+ * Copyright (C) 2005 HP Labs
+ *
+ * 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/errno.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+
+#include <asm/io.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/gpio.h>
+
+static const u32 pio_controller_offset[4] = {
+	AT91_PIOA,
+	AT91_PIOB,
+	AT91_PIOC,
+	AT91_PIOD,
+};
+
+static inline void __iomem *pin_to_controller(unsigned pin)
+{
+	void __iomem *sys_base = (void __iomem *) AT91_VA_BASE_SYS;
+
+	pin -= PIN_BASE;
+	pin /= 32;
+	if (likely(pin < BGA_GPIO_BANKS))
+		return sys_base + pio_controller_offset[pin];
+
+	return NULL;
+}
+
+static inline unsigned pin_to_mask(unsigned pin)
+{
+	pin -= PIN_BASE;
+	return 1 << (pin % 32);
+}
+
+
+/*--------------------------------------------------------------------------*/
+
+/* Not all hardware capabilities are exposed through these calls; they
+ * only encapsulate the most common features and modes.  (So if you
+ * want to change signals in groups, do it directly.)
+ *
+ * Bootloaders will usually handle some of the pin multiplexing setup.
+ * The intent is certainly that by the time Linux is fully booted, all
+ * pins should have been fully initialized.  These setup calls should
+ * only be used by board setup routines, or possibly in driver probe().
+ *
+ * For bootloaders doing all that setup, these calls could be inlined
+ * as NOPs so Linux won't duplicate any setup code
+ */
+
+
+/*
+ * mux the pin to the "A" internal peripheral role.
+ */
+int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup)
+{
+	void __iomem	*pio = pin_to_controller(pin);
+	unsigned	mask = pin_to_mask(pin);
+
+	if (!pio)
+		return -EINVAL;
+
+	__raw_writel(mask, pio + PIO_IDR);
+	__raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
+	__raw_writel(mask, pio + PIO_ASR);
+	__raw_writel(mask, pio + PIO_PDR);
+	return 0;
+}
+EXPORT_SYMBOL(at91_set_A_periph);
+
+
+/*
+ * mux the pin to the "B" internal peripheral role.
+ */
+int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup)
+{
+	void __iomem	*pio = pin_to_controller(pin);
+	unsigned	mask = pin_to_mask(pin);
+
+	if (!pio)
+		return -EINVAL;
+
+	__raw_writel(mask, pio + PIO_IDR);
+	__raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
+	__raw_writel(mask, pio + PIO_BSR);
+	__raw_writel(mask, pio + PIO_PDR);
+	return 0;
+}
+EXPORT_SYMBOL(at91_set_B_periph);
+
+
+/*
+ * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and
+ * configure it for an input.
+ */
+int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup)
+{
+	void __iomem	*pio = pin_to_controller(pin);
+	unsigned	mask = pin_to_mask(pin);
+
+	if (!pio)
+		return -EINVAL;
+
+	__raw_writel(mask, pio + PIO_IDR);
+	__raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
+	__raw_writel(mask, pio + PIO_ODR);
+	__raw_writel(mask, pio + PIO_PER);
+	return 0;
+}
+EXPORT_SYMBOL(at91_set_gpio_input);
+
+
+/*
+ * mux the pin to the gpio controller (instead of "A" or "B" peripheral),
+ * and configure it for an output.
+ */
+int __init_or_module at91_set_gpio_output(unsigned pin, int value)
+{
+	void __iomem	*pio = pin_to_controller(pin);
+	unsigned	mask = pin_to_mask(pin);
+
+	if (!pio)
+		return -EINVAL;
+
+	__raw_writel(mask, pio + PIO_IDR);
+	__raw_writel(mask, pio + PIO_PUDR);
+	__raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR));
+	__raw_writel(mask, pio + PIO_OER);
+	__raw_writel(mask, pio + PIO_PER);
+	return 0;
+}
+EXPORT_SYMBOL(at91_set_gpio_output);
+
+
+/*
+ * enable/disable the glitch filter; mostly used with IRQ handling.
+ */
+int __init_or_module at91_set_deglitch(unsigned pin, int is_on)
+{
+	void __iomem	*pio = pin_to_controller(pin);
+	unsigned	mask = pin_to_mask(pin);
+
+	if (!pio)
+		return -EINVAL;
+	__raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR));
+	return 0;
+}
+EXPORT_SYMBOL(at91_set_deglitch);
+
+/*--------------------------------------------------------------------------*/
+
+
+/*
+ * assuming the pin is muxed as a gpio output, set its value.
+ */
+int at91_set_gpio_value(unsigned pin, int value)
+{
+	void __iomem	*pio = pin_to_controller(pin);
+	unsigned	mask = pin_to_mask(pin);
+
+	if (!pio)
+		return -EINVAL;
+	__raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR));
+	return 0;
+}
+EXPORT_SYMBOL(at91_set_gpio_value);
+
+
+/*
+ * read the pin's value (works even if it's not muxed as a gpio).
+ */
+int at91_get_gpio_value(unsigned pin)
+{
+	void __iomem	*pio = pin_to_controller(pin);
+	unsigned	mask = pin_to_mask(pin);
+	u32		pdsr;
+
+	if (!pio)
+		return -EINVAL;
+	pdsr = __raw_readl(pio + PIO_PDSR);
+	return (pdsr & mask) != 0;
+}
+EXPORT_SYMBOL(at91_get_gpio_value);
+
+/*--------------------------------------------------------------------------*/
+
+
+/* Several AIC controller irqs are dispatched through this GPIO handler.
+ * To use any AT91_PIN_* as an externally triggered IRQ, first call
+ * at91_set_gpio_input() then maybe enable its glitch filter.
+ * Then just request_irq() with the pin ID; it works like any ARM IRQ
+ * handler, though it always triggers on rising and falling edges.
+ *
+ * Alternatively, certain pins may be used directly as IRQ0..IRQ6 after
+ * configuring them with at91_set_a_periph() or at91_set_b_periph().
+ * IRQ0..IRQ6 should be configurable, e.g. level vs edge triggering.
+ */
+
+static void gpio_irq_mask(unsigned pin)
+{
+	void __iomem	*pio = pin_to_controller(pin);
+	unsigned	mask = pin_to_mask(pin);
+
+	if (pio)
+		__raw_writel(mask, pio + PIO_IDR);
+}
+
+static void gpio_irq_unmask(unsigned pin)
+{
+	void __iomem	*pio = pin_to_controller(pin);
+	unsigned	mask = pin_to_mask(pin);
+
+	if (pio)
+		__raw_writel(mask, pio + PIO_IER);
+}
+
+static int gpio_irq_type(unsigned pin, unsigned type)
+{
+	return (type == IRQT_BOTHEDGE) ? 0 : -EINVAL;
+}
+
+static struct irqchip gpio_irqchip = {
+	.mask		= gpio_irq_mask,
+	.unmask		= gpio_irq_unmask,
+	.set_type	= gpio_irq_type,
+};
+
+static void gpio_irq_handler(unsigned irq, struct irqdesc *desc, struct pt_regs *regs)
+{
+	unsigned	pin;
+	struct irqdesc	*gpio;
+	void __iomem	*pio;
+	u32		isr;
+
+	pio = (void __force __iomem *) desc->chipdata;
+
+	/* temporarily mask (level sensitive) parent IRQ */
+	desc->chip->ack(irq);
+	for (;;) {
+		isr = __raw_readl(pio + PIO_ISR) & __raw_readl(pio + PIO_IMR);
+		if (!isr)
+			break;
+
+		pin = (unsigned) desc->data;
+		gpio = &irq_desc[pin];
+
+		while (isr) {
+			if (isr & 1)
+				gpio->handle(pin, gpio, regs);
+			pin++;
+			gpio++;
+			isr >>= 1;
+		}
+	}
+	desc->chip->unmask(irq);
+	/* now it may re-trigger */
+}
+
+/* call this from board-specific init_irq */
+void __init at91_gpio_irq_setup(unsigned banks)
+{
+	unsigned	pioc, pin, id;
+
+	if (banks > 4)
+		banks = 4;
+	for (pioc = 0, pin = PIN_BASE, id = AT91_ID_PIOA;
+			pioc < banks;
+			pioc++, id++) {
+		void __iomem	*controller;
+		unsigned	i;
+
+		controller = (void __iomem *) AT91_VA_BASE_SYS + pio_controller_offset[pioc];
+		__raw_writel(~0, controller + PIO_IDR);
+
+		set_irq_data(id, (void *) pin);
+		set_irq_chipdata(id, (void __force *) controller);
+
+		for (i = 0; i < 32; i++, pin++) {
+			set_irq_chip(pin, &gpio_irqchip);
+			set_irq_handler(pin, do_simple_IRQ);
+			set_irq_flags(pin, IRQF_VALID);
+		}
+
+		set_irq_chained_handler(id, gpio_irq_handler);
+
+		/* enable the PIO peripheral clock */
+		at91_sys_write(AT91_PMC_PCER, 1 << id);
+	}
+	pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, banks);
+}
diff --git a/arch/arm/mach-at91rm9200/irq.c b/arch/arm/mach-at91rm9200/irq.c
new file mode 100644
index 0000000..cb62bc8
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/irq.c
@@ -0,0 +1,170 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/irq.c
+ *
+ *  Copyright (C) 2004 SAN People
+ *  Copyright (C) 2004 ATMEL
+ *  Copyright (C) Rick Bronson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/types.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+
+#include "generic.h"
+
+/*
+ * The default interrupt priority levels (0 = lowest, 7 = highest).
+ */
+static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = {
+	7,	/* Advanced Interrupt Controller */
+	7,	/* System Peripheral */
+	0,	/* Parallel IO Controller A */
+	0,	/* Parallel IO Controller B */
+	0,	/* Parallel IO Controller C */
+	0,	/* Parallel IO Controller D */
+	6,	/* USART 0 */
+	6,	/* USART 1 */
+	6,	/* USART 2 */
+	6,	/* USART 3 */
+	0,	/* Multimedia Card Interface */
+	4,	/* USB Device Port */
+	0,	/* Two-Wire Interface */
+	6,	/* Serial Peripheral Interface */
+	5,	/* Serial Synchronous Controller */
+	5,	/* Serial Synchronous Controller */
+	5,	/* Serial Synchronous Controller */
+	0,	/* Timer Counter 0 */
+	0,	/* Timer Counter 1 */
+	0,	/* Timer Counter 2 */
+	0,	/* Timer Counter 3 */
+	0,	/* Timer Counter 4 */
+	0,	/* Timer Counter 5 */
+	3,	/* USB Host port */
+	3,	/* Ethernet MAC */
+	0,	/* Advanced Interrupt Controller */
+	0,	/* Advanced Interrupt Controller */
+	0,	/* Advanced Interrupt Controller */
+	0,	/* Advanced Interrupt Controller */
+	0,	/* Advanced Interrupt Controller */
+	0,	/* Advanced Interrupt Controller */
+	0	/* Advanced Interrupt Controller */
+};
+
+
+static void at91rm9200_mask_irq(unsigned int irq)
+{
+	/* Disable interrupt on AIC */
+	at91_sys_write(AT91_AIC_IDCR, 1 << irq);
+}
+
+static void at91rm9200_unmask_irq(unsigned int irq)
+{
+	/* Enable interrupt on AIC */
+	at91_sys_write(AT91_AIC_IECR, 1 << irq);
+}
+
+static int at91rm9200_irq_type(unsigned irq, unsigned type)
+{
+	unsigned int smr, srctype;
+
+	/* change triggering only for FIQ and external IRQ0..IRQ6 */
+	if ((irq < AT91_ID_IRQ0) && (irq != AT91_ID_FIQ))
+		return -EINVAL;
+
+	switch (type) {
+	case IRQT_HIGH:
+		srctype = AT91_AIC_SRCTYPE_HIGH;
+		break;
+	case IRQT_RISING:
+		srctype = AT91_AIC_SRCTYPE_RISING;
+		break;
+	case IRQT_LOW:
+		srctype = AT91_AIC_SRCTYPE_LOW;
+		break;
+	case IRQT_FALLING:
+		srctype = AT91_AIC_SRCTYPE_FALLING;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	smr = at91_sys_read(AT91_AIC_SMR(irq)) & ~AT91_AIC_SRCTYPE;
+	at91_sys_write(AT91_AIC_SMR(irq), smr | srctype);
+	return 0;
+}
+
+static struct irqchip at91rm9200_irq_chip = {
+	.ack		= at91rm9200_mask_irq,
+	.mask		= at91rm9200_mask_irq,
+	.unmask		= at91rm9200_unmask_irq,
+	.set_type	= at91rm9200_irq_type,
+};
+
+/*
+ * Initialize the AIC interrupt controller.
+ */
+void __init at91rm9200_init_irq(unsigned int priority[NR_AIC_IRQS])
+{
+	unsigned int i;
+
+	/* No priority list specified for this board -> use defaults */
+	if (priority == NULL)
+		priority = at91rm9200_default_irq_priority;
+
+	/*
+	 * The IVR is used by macro get_irqnr_and_base to read and verify.
+	 * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred.
+	 */
+	for (i = 0; i < NR_AIC_IRQS; i++) {
+		/* Put irq number in Source Vector Register: */
+		at91_sys_write(AT91_AIC_SVR(i), i);
+		/* Store the Source Mode Register as defined in table above */
+		at91_sys_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]);
+
+		set_irq_chip(i, &at91rm9200_irq_chip);
+		set_irq_handler(i, do_level_IRQ);
+		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+
+		/* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */
+		if (i < 8)
+			at91_sys_write(AT91_AIC_EOICR, 0);
+	}
+
+	/*
+	 * Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS
+	 * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU
+	 */
+	at91_sys_write(AT91_AIC_SPU, NR_AIC_IRQS);
+
+	/* No debugging in AIC: Debug (Protect) Control Register */
+	at91_sys_write(AT91_AIC_DCR, 0);
+
+	/* Disable and clear all interrupts initially */
+	at91_sys_write(AT91_AIC_IDCR, 0xFFFFFFFF);
+	at91_sys_write(AT91_AIC_ICCR, 0xFFFFFFFF);
+}
diff --git a/arch/arm/mach-at91rm9200/time.c b/arch/arm/mach-at91rm9200/time.c
new file mode 100644
index 0000000..1b6dd2d
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/time.c
@@ -0,0 +1,127 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/time.c
+ *
+ *  Copyright (C) 2003 SAN People
+ *  Copyright (C) 2003 ATMEL
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach/time.h>
+
+/*
+ * The ST_CRTR is updated asynchronously to the master clock.  It is therefore
+ *  necessary to read it twice (with the same value) to ensure accuracy.
+ */
+static inline unsigned long read_CRTR(void) {
+	unsigned long x1, x2;
+
+	do {
+		x1 = at91_sys_read(AT91_ST_CRTR);
+		x2 = at91_sys_read(AT91_ST_CRTR);
+	} while (x1 != x2);
+
+	return x1;
+}
+
+/*
+ * Returns number of microseconds since last timer interrupt.  Note that interrupts
+ * will have been disabled by do_gettimeofday()
+ *  'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy.
+ *  'tick' is usecs per jiffy (linux/timex.h).
+ */
+static unsigned long at91rm9200_gettimeoffset(void)
+{
+	unsigned long elapsed;
+
+	elapsed = (read_CRTR() - at91_sys_read(AT91_ST_RTAR)) & AT91_ST_ALMV;
+
+	return (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH;
+}
+
+/*
+ * IRQ handler for the timer.
+ */
+static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long rtar;
+
+	if (at91_sys_read(AT91_ST_SR) & AT91_ST_PITS) {	/* This is a shared interrupt */
+		write_seqlock(&xtime_lock);
+
+		do {
+			timer_tick(regs);
+			rtar = (at91_sys_read(AT91_ST_RTAR) + LATCH) & AT91_ST_ALMV;
+			at91_sys_write(AT91_ST_RTAR, rtar);
+		} while (((read_CRTR() - at91_sys_read(AT91_ST_RTAR)) & AT91_ST_ALMV) >= LATCH);
+
+		write_sequnlock(&xtime_lock);
+
+		return IRQ_HANDLED;
+	}
+	else
+		return IRQ_NONE;		/* not handled */
+}
+
+static struct irqaction at91rm9200_timer_irq = {
+	.name		= "at91_tick",
+	.flags		= SA_SHIRQ | SA_INTERRUPT,
+	.handler	= at91rm9200_timer_interrupt
+};
+
+/*
+ * Set up timer interrupt.
+ */
+void __init at91rm9200_timer_init(void)
+{
+	/* Disable all timer interrupts */
+	at91_sys_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS);
+	(void) at91_sys_read(AT91_ST_SR);	/* Clear any pending interrupts */
+
+	/*
+	 * Make IRQs happen for the system timer.
+	 */
+	setup_irq(AT91_ID_SYS, &at91rm9200_timer_irq);
+
+	/* Set initial alarm to 0 */
+	at91_sys_write(AT91_ST_RTAR, 0);
+
+	/* Real time counter incremented every 30.51758 microseconds */
+	at91_sys_write(AT91_ST_RTMR, 1);
+
+	/* Set Period Interval timer */
+	at91_sys_write(AT91_ST_PIMR, LATCH);
+
+	/* Change the kernel's 'tick' value to 10009 usec. (the default is 10000) */
+	tick_usec = (LATCH * 1000000) / CLOCK_TICK_RATE;
+
+	/* Enable Period Interval Timer interrupt */
+	at91_sys_write(AT91_ST_IER, AT91_ST_PITS);
+}
+
+struct sys_timer at91rm9200_timer = {
+	.init		= at91rm9200_timer_init,
+	.offset		= at91rm9200_gettimeoffset,
+};
diff --git a/arch/arm/mach-epxa10db/Kconfig b/arch/arm/mach-epxa10db/Kconfig
deleted file mode 100644
index 55d896d..0000000
--- a/arch/arm/mach-epxa10db/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-if ARCH_CAMELOT
-
-menu "Epxa10db"
-
-comment "PLD hotswap support"
-
-config PLD
-	bool
-	default y
-
-config PLD_HOTSWAP
-	bool "Support for PLD device hotplugging (experimental)"
-	depends on EXPERIMENTAL
-	help
-	  This enables support for the dynamic loading and configuration of
-	  compatible drivers when the contents of the PLD are changed. This
-	  is still experimental and requires configuration tools which are
-	  not yet generally available. Say N here. You must enable the kernel
-	  module loader for this feature to work.
-
-endmenu
-
-endif
diff --git a/arch/arm/mach-epxa10db/Makefile b/arch/arm/mach-epxa10db/Makefile
deleted file mode 100644
index 24fbd7d..0000000
--- a/arch/arm/mach-epxa10db/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-# Object file lists.
-
-obj-y			:= arch.o irq.o mm.o time.o 
-obj-m			:=
-obj-n			:=
-obj-			:=
-
diff --git a/arch/arm/mach-epxa10db/Makefile.boot b/arch/arm/mach-epxa10db/Makefile.boot
deleted file mode 100644
index 28bec7d..0000000
--- a/arch/arm/mach-epxa10db/Makefile.boot
+++ /dev/null
@@ -1,2 +0,0 @@
-   zreladdr-y	:= 0x00008000
-
diff --git a/arch/arm/mach-epxa10db/arch.c b/arch/arm/mach-epxa10db/arch.c
deleted file mode 100644
index 44c5657..0000000
--- a/arch/arm/mach-epxa10db/arch.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *  linux/arch/arm/mach-epxa10db/arch.c
- *
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/serial_8250.h>
-
-#include <asm/hardware.h>
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-
-#include <asm/mach/arch.h>
-
-static struct plat_serial8250_port serial_platform_data[] = {
-	{
-		.iobase		= 0x3f8,
-		.irq		= IRQ_UARTINT0,
-#error FIXME
-		.uartclk	= 0,
-		.regshift	= 0,
-		.iotype		= UPIO_PORT,
-		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
-	},
-	{
-		.iobase		= 0x2f8,
-		.irq		= IRQ_UARTINT1,
-#error FIXME
-		.uartclk	= 0,
-		.regshift	= 0,
-		.iotype		= UPIO_PORT,
-		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
-	},
-	{ },
-};
-
-static struct platform_device serial_device = {
-	.name			= "serial8250",
-	.id			= PLAT8250_DEV_PLATFORM,
-	.dev			= {
-		.platform_data	= serial_platform_data,
-	},
-};
-
-extern void epxa10db_map_io(void);
-extern void epxa10db_init_irq(void);
-extern struct sys_timer epxa10db_timer;
-
-MACHINE_START(CAMELOT, "Altera Epxa10db")
-	/* Maintainer: Altera Corporation */
-	.phys_ram	= 0x00000000,
-	.phys_io	= 0x7fffc000,
-	.io_pg_offst	= ((0xffffc000) >> 18) & 0xfffc,
-	.map_io		= epxa10db_map_io,
-	.init_irq	= epxa10db_init_irq,
-	.timer		= &epxa10db_timer,
-MACHINE_END
-
diff --git a/arch/arm/mach-epxa10db/irq.c b/arch/arm/mach-epxa10db/irq.c
deleted file mode 100644
index 9bf927e..0000000
--- a/arch/arm/mach-epxa10db/irq.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- *  linux/arch/arm/mach-epxa10db/irq.c
- *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/stddef.h>
-#include <linux/timer.h>
-#include <linux/list.h>
-#include <asm/io.h>
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach/irq.h>
-#include <asm/arch/platform.h>
-#include <asm/arch/int_ctrl00.h>
-
-
-static void epxa_mask_irq(unsigned int irq)
-{
-        writel(1 << irq, INT_MC(IO_ADDRESS(EXC_INT_CTRL00_BASE)));
-}
-
-static void epxa_unmask_irq(unsigned int irq)
-{
-        writel(1 << irq, INT_MS(IO_ADDRESS(EXC_INT_CTRL00_BASE)));
-}
- 
-
-static struct irqchip epxa_irq_chip = {
-	.ack		= epxa_mask_irq,
-	.mask		= epxa_mask_irq,
-	.unmask		= epxa_unmask_irq,
-};
-
-static struct resource irq_resource = {
-	.name	= "irq_handler",
-	.start	= IO_ADDRESS(EXC_INT_CTRL00_BASE),
-	.end	= IO_ADDRESS(INT_PRIORITY_FC(EXC_INT_CTRL00_BASE))+4,
-};
-
-void __init epxa10db_init_irq(void)
-{
-	unsigned int i;
-	
-	request_resource(&iomem_resource, &irq_resource);
-
-	/*
-	 * This bit sets up the interrupt controller using 
-	 * the 6 PLD interrupts mode (the default) each 
-	 * irqs is assigned a priority which is the same
-	 * as its interrupt number. This scheme is used because 
-	 * its easy, but you may want to change it depending
-	 * on the contents of your PLD
-	 */
-
-	writel(3,INT_MODE(IO_ADDRESS(EXC_INT_CTRL00_BASE)));
-	for (i = 0; i < NR_IRQS; i++){
-		writel(i+1, INT_PRIORITY_P0(IO_ADDRESS(EXC_INT_CTRL00_BASE)) + (4*i));
-		set_irq_chip(i,&epxa_irq_chip);
-		set_irq_handler(i,do_level_IRQ);
-		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
-	}
-
-	/* Disable all interrupts */
-	writel(-1,INT_MC(IO_ADDRESS(EXC_INT_CTRL00_BASE)));
-
-}
diff --git a/arch/arm/mach-epxa10db/mm.c b/arch/arm/mach-epxa10db/mm.c
deleted file mode 100644
index cfd0d21..0000000
--- a/arch/arm/mach-epxa10db/mm.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- *  linux/arch/arm/mach-epxa10db/mm.c
- *
- *  MM routines for Altera'a Epxa10db board
- *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/sizes.h>
-#include <asm/page.h>
- 
-#include <asm/mach/map.h>
-
-/* Page table mapping for I/O region */
- 
-static struct map_desc epxa10db_io_desc[] __initdata = {
-	{
-		.virtual	= IO_ADDRESS(EXC_REGISTERS_BASE),
-		.pfn		= __phys_to_pfn(EXC_REGISTERS_BASE),
-		.length		= SZ_16K,
-		.type		= MT_DEVICE
-	}, {
-		.virtual	= IO_ADDRESS(EXC_PLD_BLOCK0_BASE),
-		.pfn		= __phys_to_pfn(EXC_PLD_BLOCK0_BASE),
-		.length		= SZ_16K,
-		.type		= MT_DEVICE
-	}, {
-		.virtual	= IO_ADDRESS(EXC_PLD_BLOCK1_BASE),
-		.pfn		=__phys_to_pfn(EXC_PLD_BLOCK1_BASE),
-		.length		= SZ_16K,
-		.type		= MT_DEVICE
-	}, {
-		.virtual	= IO_ADDRESS(EXC_PLD_BLOCK2_BASE),
-		.physical	= __phys_to_pfn(EXC_PLD_BLOCK2_BASE),
-		.length		= SZ_16K,
-		.type		= MT_DEVICE
-	}, {
-		.virtual	= IO_ADDRESS(EXC_PLD_BLOCK3_BASE),
-		.pfn		= __phys_to_pfn(EXC_PLD_BLOCK3_BASE),
-		.length		= SZ_16K,
-		.type		= MT_DEVICE
-	}, {
-		.virtual	= FLASH_VADDR(EXC_EBI_BLOCK0_BASE),
-		.pfn		= __phys_to_pfn(EXC_EBI_BLOCK0_BASE),
-		.length		= SZ_16M,
-		.type		= MT_DEVICE
-	}
-};
-
-void __init epxa10db_map_io(void)
-{
-	iotable_init(epxa10db_io_desc, ARRAY_SIZE(epxa10db_io_desc));
-}
diff --git a/arch/arm/mach-epxa10db/time.c b/arch/arm/mach-epxa10db/time.c
deleted file mode 100644
index 4b1084d..0000000
--- a/arch/arm/mach-epxa10db/time.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- *  linux/arch/arm/mach-epxa10db/time.c
- *
- *  Copyright (C) 2000 Deep Blue Solutions
- *  Copyright (C) 2001 Altera Corporation
- *
- * 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/interrupt.h>
-#include <linux/sched.h>
-
-#include <asm/hardware.h>
-#include <asm/system.h>
-#include <asm/leds.h>
-
-#include <asm/mach/time.h>
-
-#define TIMER00_TYPE (volatile unsigned int*)
-#include <asm/arch/timer00.h>
-
-static int epxa10db_set_rtc(void)
-{
-	return 1;
-}
-
-static int epxa10db_rtc_init(void)
-{
-	set_rtc = epxa10db_set_rtc;
-
-	return 0;
-}
-
-__initcall(epxa10db_rtc_init);
-
-
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t
-epxa10db_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	write_seqlock(&xtime_lock);
-
-	// ...clear the interrupt
-	*TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))|=TIMER0_CR_CI_MSK;
-
-	timer_tick(regs);
-	write_sequnlock(&xtime_lock);
-
-	return IRQ_HANDLED;
-}
-
-static struct irqaction epxa10db_timer_irq = {
-	.name		= "Excalibur Timer Tick",
-	.flags		= SA_INTERRUPT | SA_TIMER,
-	.handler	= epxa10db_timer_interrupt,
-};
-
-/*
- * Set up timer interrupt, and return the current time in seconds.
- */
-static void __init epxa10db_timer_init(void)
-{
-	/* Start the timer */
-	*TIMER0_LIMIT(IO_ADDRESS(EXC_TIMER00_BASE))=(unsigned int)(EXC_AHB2_CLK_FREQUENCY/200);
-	*TIMER0_PRESCALE(IO_ADDRESS(EXC_TIMER00_BASE))=1;
-	*TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))=TIMER0_CR_IE_MSK | TIMER0_CR_S_MSK;
-
-	setup_irq(IRQ_TIMER0, &epxa10db_timer_irq);
-}
-
-struct sys_timer epxa10db_timer = {
-	.init		= epxa10db_timer_init,
-};
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index bd900b7..92ff5dc 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -184,7 +184,7 @@
 	omap_writel(0x00000088, OMAP730_FLASH_ACFG_0);
 
 	/*
-	 * Ethernet support trough the debug board
+	 * Ethernet support through the debug board
 	 * CS1 timings setup
 	 */
 	omap_writel(0x0000fff3, OMAP730_FLASH_CFG_1);
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index 5830ae3..fc09ba9 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -253,100 +253,101 @@
 /* clock definitions */
 
 static struct clk init_clocks[] = {
-	{ .name    = "nand",
-	  .id	   = -1,
-	  .parent  = &clk_h,
-	  .enable  = s3c24xx_clkcon_enable,
-	  .ctrlbit = S3C2410_CLKCON_NAND
-	},
-	{ .name    = "lcd",
-	  .id	   = -1,
-	  .parent  = &clk_h,
-	  .enable  = s3c24xx_clkcon_enable,
-	  .ctrlbit = S3C2410_CLKCON_LCDC
-	},
-	{ .name    = "usb-host",
-	  .id	   = -1,
-	  .parent  = &clk_h,
-	  .enable  = s3c24xx_clkcon_enable,
-	  .ctrlbit = S3C2410_CLKCON_USBH
-	},
-	{ .name    = "usb-device",
-	  .id	   = -1,
-	  .parent  = &clk_h,
-	  .enable  = s3c24xx_clkcon_enable,
-	  .ctrlbit = S3C2410_CLKCON_USBD
-	},
-	{ .name    = "timers",
-	  .id	   = -1,
-	  .parent  = &clk_p,
-	  .enable  = s3c24xx_clkcon_enable,
-	  .ctrlbit = S3C2410_CLKCON_PWMT
-	},
-	{ .name    = "sdi",
-	  .id	   = -1,
-	  .parent  = &clk_p,
-	  .enable  = s3c24xx_clkcon_enable,
-	  .ctrlbit = S3C2410_CLKCON_SDI
-	},
-	{ .name    = "uart",
-	  .id	   = 0,
-	  .parent  = &clk_p,
-	  .enable  = s3c24xx_clkcon_enable,
-	  .ctrlbit = S3C2410_CLKCON_UART0
-	},
-	{ .name    = "uart",
-	  .id	   = 1,
-	  .parent  = &clk_p,
-	  .enable  = s3c24xx_clkcon_enable,
-	  .ctrlbit = S3C2410_CLKCON_UART1
-	},
-	{ .name    = "uart",
-	  .id	   = 2,
-	  .parent  = &clk_p,
-	  .enable  = s3c24xx_clkcon_enable,
-	  .ctrlbit = S3C2410_CLKCON_UART2
-	},
-	{ .name    = "gpio",
-	  .id	   = -1,
-	  .parent  = &clk_p,
-	  .enable  = s3c24xx_clkcon_enable,
-	  .ctrlbit = S3C2410_CLKCON_GPIO
-	},
-	{ .name    = "rtc",
-	  .id	   = -1,
-	  .parent  = &clk_p,
-	  .enable  = s3c24xx_clkcon_enable,
-	  .ctrlbit = S3C2410_CLKCON_RTC
-	},
-	{ .name    = "adc",
-	  .id	   = -1,
-	  .parent  = &clk_p,
-	  .enable  = s3c24xx_clkcon_enable,
-	  .ctrlbit = S3C2410_CLKCON_ADC
-	},
-	{ .name    = "i2c",
-	  .id	   = -1,
-	  .parent  = &clk_p,
-	  .enable  = s3c24xx_clkcon_enable,
-	  .ctrlbit = S3C2410_CLKCON_IIC
-	},
-	{ .name    = "iis",
-	  .id	   = -1,
-	  .parent  = &clk_p,
-	  .enable  = s3c24xx_clkcon_enable,
-	  .ctrlbit = S3C2410_CLKCON_IIS
-	},
-	{ .name    = "spi",
-	  .id	   = -1,
-	  .parent  = &clk_p,
-	  .enable  = s3c24xx_clkcon_enable,
-	  .ctrlbit = S3C2410_CLKCON_SPI
-	},
-	{ .name    = "watchdog",
-	  .id	   = -1,
-	  .parent  = &clk_p,
-	  .ctrlbit = 0
+	{
+		.name		= "nand",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c24xx_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_NAND,
+	}, {
+		.name		= "lcd",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c24xx_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_LCDC,
+	}, {
+		.name		= "usb-host",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c24xx_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_USBH,
+	}, {
+		.name		= "usb-device",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s3c24xx_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_USBD,
+	}, {
+		.name		= "timers",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c24xx_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_PWMT,
+	}, {
+		.name		= "sdi",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c24xx_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_SDI,
+	}, {
+		.name		= "uart",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s3c24xx_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_UART0,
+	}, {
+		.name		= "uart",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s3c24xx_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_UART1,
+	}, {
+		.name		= "uart",
+		.id		= 2,
+		.parent		= &clk_p,
+		.enable		= s3c24xx_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_UART2,
+	}, {
+		.name		= "gpio",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c24xx_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_GPIO,
+	}, {
+		.name		= "rtc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c24xx_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_RTC,
+	}, {
+		.name		= "adc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c24xx_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_ADC,
+	}, {
+		.name		= "i2c",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c24xx_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_IIC,
+	}, {
+		.name		= "iis",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c24xx_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_IIS,
+	}, {
+		.name		= "spi",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s3c24xx_clkcon_enable,
+		.ctrlbit	= S3C2410_CLKCON_SPI,
+	}, {
+		.name		= "watchdog",
+		.id		= -1,
+		.parent		= &clk_p,
+		.ctrlbit	= 0,
 	}
 };
 
@@ -390,16 +391,15 @@
 	clk_p.rate = pclk;
 	clk_f.rate = fclk;
 
-	/* it looks like just setting the register here is not good
-	 * enough, and causes the odd hang at initial boot time, so
-	 * do all of them indivdually.
+	/* We must be careful disabling the clocks we are not intending to
+	 * be using at boot time, as subsytems such as the LCD which do
+	 * their own DMA requests to the bus can cause the system to lockup
+	 * if they where in the middle of requesting bus access.
 	 *
-	 * I think disabling the LCD clock if the LCD is active is
-	 * very dangerous, and therefore the bootloader should be
-	 * careful to not enable the LCD clock if it is not needed.
-	 *
-	 * and of course, this looks neater
-	 */
+	 * Disabling the LCD clock if the LCD is active is very dangerous,
+	 * and therefore the bootloader should be  careful to not enable
+	 * the LCD clock if it is not needed.
+	*/
 
 	s3c24xx_clk_enable(S3C2410_CLKCON_NAND, 0);
 	s3c24xx_clk_enable(S3C2410_CLKCON_USBH, 0);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index e84fdde..3b79d0e 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -62,8 +62,8 @@
 # ARM920T
 config CPU_ARM920T
 	bool "Support ARM920T processor" if !ARCH_S3C2410
-	depends on ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX || ARCH_AAEC2000
-	default y if ARCH_S3C2410
+	depends on ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX || ARCH_AAEC2000 || ARCH_AT91RM9200
+	default y if ARCH_S3C2410 || ARCH_AT91RM9200
 	select CPU_32v4
 	select CPU_ABRT_EV4T
 	select CPU_CACHE_V4WT
@@ -83,8 +83,8 @@
 # ARM922T
 config CPU_ARM922T
 	bool "Support ARM922T processor" if ARCH_INTEGRATOR
-	depends on ARCH_CAMELOT || ARCH_LH7A40X || ARCH_INTEGRATOR
-	default y if ARCH_CAMELOT || ARCH_LH7A40X
+	depends on ARCH_LH7A40X || ARCH_INTEGRATOR
+	default y if ARCH_LH7A40X
 	select CPU_32v4
 	select CPU_ABRT_EV4T
 	select CPU_CACHE_V4WT
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 1090139..de3ce1e 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -86,11 +86,12 @@
 }
 
 static int
-remap_area_pages(unsigned long start, unsigned long phys_addr,
+remap_area_pages(unsigned long start, unsigned long pfn,
 		 unsigned long size, unsigned long flags)
 {
 	unsigned long address = start;
 	unsigned long end = start + size;
+	unsigned long phys_addr = __pfn_to_phys(pfn);
 	int err = 0;
 	pgd_t * dir;
 
@@ -130,36 +131,44 @@
  * mapping.  See include/asm-arm/proc-armv/pgtable.h for more information.
  */
 void __iomem *
+__ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
+	      unsigned long flags)
+{
+	unsigned long addr;
+ 	struct vm_struct * area;
+
+ 	area = get_vm_area(size, VM_IOREMAP);
+ 	if (!area)
+ 		return NULL;
+ 	addr = (unsigned long)area->addr;
+ 	if (remap_area_pages(addr, pfn, size, flags)) {
+ 		vfree(addr);
+ 		return NULL;
+ 	}
+ 	return (void __iomem *) (offset + (char *)addr);
+}
+EXPORT_SYMBOL(__ioremap_pfn);
+
+void __iomem *
 __ioremap(unsigned long phys_addr, size_t size, unsigned long flags)
 {
-	void * addr;
-	struct vm_struct * area;
-	unsigned long offset, last_addr;
+	unsigned long last_addr;
+ 	unsigned long offset = phys_addr & ~PAGE_MASK;
+ 	unsigned long pfn = __phys_to_pfn(phys_addr);
 
-	/* Don't allow wraparound or zero size */
+ 	/*
+ 	 * Don't allow wraparound or zero size
+	 */
 	last_addr = phys_addr + size - 1;
 	if (!size || last_addr < phys_addr)
 		return NULL;
 
 	/*
-	 * Mappings have to be page-aligned
+ 	 * Page align the mapping size
 	 */
-	offset = phys_addr & ~PAGE_MASK;
-	phys_addr &= PAGE_MASK;
 	size = PAGE_ALIGN(last_addr + 1) - phys_addr;
 
-	/*
-	 * Ok, go for it..
-	 */
-	area = get_vm_area(size, VM_IOREMAP);
-	if (!area)
-		return NULL;
-	addr = area->addr;
-	if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
-		vfree(addr);
-		return NULL;
-	}
-	return (void __iomem *) (offset + (char *)addr);
+ 	return __ioremap_pfn(pfn, offset, size, flags);
 }
 EXPORT_SYMBOL(__ioremap);
 
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 4654874..d0f9bb5 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Fri Nov 25 14:43:04 2005
+# Last update: Mon Jan 9 12:56:42 2006
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -910,3 +910,31 @@
 nadia2vb		MACH_NADIA2VB		NADIA2VB		897
 r1000			MACH_R1000		R1000			898
 hw90250			MACH_HW90250		HW90250			899
+omap_2430sdp		MACH_OMAP_2430SDP	OMAP_2430SDP		900
+davinci_evm		MACH_DAVINCI_EVM	DAVINCI_EVM		901
+omap_tornado		MACH_OMAP_TORNADO	OMAP_TORNADO		902
+olocreek		MACH_OLOCREEK		OLOCREEK		903
+palmz72			MACH_PALMZ72		PALMZ72			904
+nxdb500			MACH_NXDB500		NXDB500			905
+apf9328			MACH_APF9328		APF9328			906
+omap_wipoq		MACH_OMAP_WIPOQ		OMAP_WIPOQ		907
+omap_twip		MACH_OMAP_TWIP		OMAP_TWIP		908
+xscale_treo650		MACH_XSCALE_PALMTREO650	XSCALE_PALMTREO650	909
+acumen			MACH_ACUMEN		ACUMEN			910
+xp100			MACH_XP100		XP100			911
+fs2410			MACH_FS2410		FS2410			912
+pxa270_cerf		MACH_PXA270_CERF	PXA270_CERF		913
+sq2ftlpalm		MACH_SQ2FTLPALM		SQ2FTLPALM		914
+bsemserver		MACH_BSEMSERVER		BSEMSERVER		915
+netclient		MACH_NETCLIENT		NETCLIENT		916
+xscale_palmtt5		MACH_XSCALE_PALMTT5	XSCALE_PALMTT5		917
+xscale_palmtc		MACH_OMAP_PALMTC	OMAP_PALMTC		918
+omap_apollon		MACH_OMAP_APOLLON	OMAP_APOLLON		919
+argonlvevb		MACH_ARGONLVEVB		ARGONLVEVB		920
+rea_2d			MACH_REA_2D		REA_2D			921
+eti3e524		MACH_TI3E524		TI3E524			922
+ateb9200		MACH_ATEB9200		ATEB9200		923
+auckland		MACH_AUCKLAND		AUCKLAND		924
+ak3220m			MACH_AK3320M		AK3320M			925
+duramax			MACH_DURAMAX		DURAMAX			926
+n35			MACH_N35		N35			927
diff --git a/arch/i386/crypto/aes-i586-asm.S b/arch/i386/crypto/aes-i586-asm.S
index 7b73c67..911b153 100644
--- a/arch/i386/crypto/aes-i586-asm.S
+++ b/arch/i386/crypto/aes-i586-asm.S
@@ -255,18 +255,17 @@
 	xor     8(%ebp),%r4
 	xor     12(%ebp),%r5
 
-	sub     $8,%esp           // space for register saves on stack
-	add     $16,%ebp          // increment to next round key
-	sub     $10,%r3          
-	je      4f              // 10 rounds for 128-bit key
-	add     $32,%ebp
-	sub     $2,%r3
-	je      3f              // 12 rounds for 128-bit key
-	add     $32,%ebp
+	sub     $8,%esp		// space for register saves on stack
+	add     $16,%ebp	// increment to next round key
+	cmp     $12,%r3
+	jb      4f		// 10 rounds for 128-bit key
+	lea     32(%ebp),%ebp
+	je      3f		// 12 rounds for 192-bit key
+	lea     32(%ebp),%ebp
 
-2:	fwd_rnd1( -64(%ebp) ,ft_tab)	// 14 rounds for 128-bit key
+2:	fwd_rnd1( -64(%ebp) ,ft_tab)	// 14 rounds for 256-bit key
 	fwd_rnd2( -48(%ebp) ,ft_tab)
-3:	fwd_rnd1( -32(%ebp) ,ft_tab)	// 12 rounds for 128-bit key
+3:	fwd_rnd1( -32(%ebp) ,ft_tab)	// 12 rounds for 192-bit key
 	fwd_rnd2( -16(%ebp) ,ft_tab)
 4:	fwd_rnd1(    (%ebp) ,ft_tab)	// 10 rounds for 128-bit key
 	fwd_rnd2( +16(%ebp) ,ft_tab)
@@ -334,18 +333,17 @@
 	xor     8(%ebp),%r4
 	xor     12(%ebp),%r5
 
-	sub     $8,%esp         // space for register saves on stack
-	sub     $16,%ebp        // increment to next round key
-	sub     $10,%r3          
-	je      4f              // 10 rounds for 128-bit key
-	sub     $32,%ebp
-	sub     $2,%r3
-	je      3f              // 12 rounds for 128-bit key
-	sub     $32,%ebp
+	sub     $8,%esp		// space for register saves on stack
+	sub     $16,%ebp	// increment to next round key
+	cmp     $12,%r3
+	jb      4f		// 10 rounds for 128-bit key
+	lea     -32(%ebp),%ebp
+	je      3f		// 12 rounds for 192-bit key
+	lea     -32(%ebp),%ebp
 
-2:	inv_rnd1( +64(%ebp), it_tab)	// 14 rounds for 128-bit key
+2:	inv_rnd1( +64(%ebp), it_tab)	// 14 rounds for 256-bit key
 	inv_rnd2( +48(%ebp), it_tab)
-3:	inv_rnd1( +32(%ebp), it_tab)	// 12 rounds for 128-bit key
+3:	inv_rnd1( +32(%ebp), it_tab)	// 12 rounds for 192-bit key
 	inv_rnd2( +16(%ebp), it_tab)
 4:	inv_rnd1(    (%ebp), it_tab)	// 10 rounds for 128-bit key
 	inv_rnd2( -16(%ebp), it_tab)
diff --git a/arch/i386/crypto/aes.c b/arch/i386/crypto/aes.c
index 88ee85c..a50397b 100644
--- a/arch/i386/crypto/aes.c
+++ b/arch/i386/crypto/aes.c
@@ -36,6 +36,8 @@
  * Copyright (c) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
  *
  */
+
+#include <asm/byteorder.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -59,7 +61,6 @@
 };
 
 #define WPOLY 0x011b
-#define u32_in(x) le32_to_cpup((const __le32 *)(x))
 #define bytes2word(b0, b1, b2, b3)  \
 	(((u32)(b3) << 24) | ((u32)(b2) << 16) | ((u32)(b1) << 8) | (b0))
 
@@ -93,7 +94,6 @@
 
 u32 ft_tab[4][256];
 u32 fl_tab[4][256];
-static u32 ls_tab[4][256];
 static u32 im_tab[4][256];
 u32 il_tab[4][256];
 u32 it_tab[4][256];
@@ -144,15 +144,6 @@
 		fl_tab[2][i] = upr(w, 2);
 		fl_tab[3][i] = upr(w, 3);
 		
-		/*
-		 * table for key schedule if fl_tab above is
-		 * not of the required form
-		 */
-		ls_tab[0][i] = w;
-		ls_tab[1][i] = upr(w, 1);
-		ls_tab[2][i] = upr(w, 2);
-		ls_tab[3][i] = upr(w, 3);
-		
 		b = fi(inv_affine((u8)i));
 		w = bytes2word(fe(b), f9(b), fd(b), fb(b));
 
@@ -393,13 +384,14 @@
 	int i;
 	u32 ss[8];
 	struct aes_ctx *ctx = ctx_arg;
+	const __le32 *key = (const __le32 *)in_key;
 
 	/* encryption schedule */
 	
-	ctx->ekey[0] = ss[0] = u32_in(in_key);
-	ctx->ekey[1] = ss[1] = u32_in(in_key + 4);
-	ctx->ekey[2] = ss[2] = u32_in(in_key + 8);
-	ctx->ekey[3] = ss[3] = u32_in(in_key + 12);
+	ctx->ekey[0] = ss[0] = le32_to_cpu(key[0]);
+	ctx->ekey[1] = ss[1] = le32_to_cpu(key[1]);
+	ctx->ekey[2] = ss[2] = le32_to_cpu(key[2]);
+	ctx->ekey[3] = ss[3] = le32_to_cpu(key[3]);
 
 	switch(key_len) {
 	case 16:
@@ -410,8 +402,8 @@
 		break;
 		
 	case 24:
-		ctx->ekey[4] = ss[4] = u32_in(in_key + 16);
-		ctx->ekey[5] = ss[5] = u32_in(in_key + 20);
+		ctx->ekey[4] = ss[4] = le32_to_cpu(key[4]);
+		ctx->ekey[5] = ss[5] = le32_to_cpu(key[5]);
 		for (i = 0; i < 7; i++)
 			ke6(ctx->ekey, i);
 		kel6(ctx->ekey, 7); 
@@ -419,10 +411,10 @@
 		break;
 
 	case 32:
-		ctx->ekey[4] = ss[4] = u32_in(in_key + 16);
-		ctx->ekey[5] = ss[5] = u32_in(in_key + 20);
-		ctx->ekey[6] = ss[6] = u32_in(in_key + 24);
-		ctx->ekey[7] = ss[7] = u32_in(in_key + 28);
+		ctx->ekey[4] = ss[4] = le32_to_cpu(key[4]);
+		ctx->ekey[5] = ss[5] = le32_to_cpu(key[5]);
+		ctx->ekey[6] = ss[6] = le32_to_cpu(key[6]);
+		ctx->ekey[7] = ss[7] = le32_to_cpu(key[7]);
 		for (i = 0; i < 6; i++)
 			ke8(ctx->ekey, i);
 		kel8(ctx->ekey, 6);
@@ -436,10 +428,10 @@
 	
 	/* decryption schedule */
 	
-	ctx->dkey[0] = ss[0] = u32_in(in_key);
-	ctx->dkey[1] = ss[1] = u32_in(in_key + 4);
-	ctx->dkey[2] = ss[2] = u32_in(in_key + 8);
-	ctx->dkey[3] = ss[3] = u32_in(in_key + 12);
+	ctx->dkey[0] = ss[0] = le32_to_cpu(key[0]);
+	ctx->dkey[1] = ss[1] = le32_to_cpu(key[1]);
+	ctx->dkey[2] = ss[2] = le32_to_cpu(key[2]);
+	ctx->dkey[3] = ss[3] = le32_to_cpu(key[3]);
 
 	switch (key_len) {
 	case 16:
@@ -450,8 +442,8 @@
 		break;
 		
 	case 24:
-		ctx->dkey[4] = ff(ss[4] = u32_in(in_key + 16));
-		ctx->dkey[5] = ff(ss[5] = u32_in(in_key + 20));
+		ctx->dkey[4] = ff(ss[4] = le32_to_cpu(key[4]));
+		ctx->dkey[5] = ff(ss[5] = le32_to_cpu(key[5]));
 		kdf6(ctx->dkey, 0);
 		for (i = 1; i < 7; i++)
 			kd6(ctx->dkey, i);
@@ -459,10 +451,10 @@
 		break;
 
 	case 32:
-		ctx->dkey[4] = ff(ss[4] = u32_in(in_key + 16));
-		ctx->dkey[5] = ff(ss[5] = u32_in(in_key + 20));
-		ctx->dkey[6] = ff(ss[6] = u32_in(in_key + 24));
-		ctx->dkey[7] = ff(ss[7] = u32_in(in_key + 28));
+		ctx->dkey[4] = ff(ss[4] = le32_to_cpu(key[4]));
+		ctx->dkey[5] = ff(ss[5] = le32_to_cpu(key[5]));
+		ctx->dkey[6] = ff(ss[6] = le32_to_cpu(key[6]));
+		ctx->dkey[7] = ff(ss[7] = le32_to_cpu(key[7]));
 		kdf8(ctx->dkey, 0);
 		for (i = 1; i < 6; i++)
 			kd8(ctx->dkey, i);
@@ -484,6 +476,8 @@
 
 static struct crypto_alg aes_alg = {
 	.cra_name		=	"aes",
+	.cra_driver_name	=	"aes-i586",
+	.cra_priority		=	200,
 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize		=	AES_BLOCK_SIZE,
 	.cra_ctxsize		=	sizeof(struct aes_ctx),
diff --git a/arch/i386/kernel/cpu/changelog b/arch/i386/kernel/cpu/changelog
deleted file mode 100644
index cef76b8..0000000
--- a/arch/i386/kernel/cpu/changelog
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *  Enhanced CPU type detection by Mike Jagdis, Patrick St. Jean
- *  and Martin Mares, November 1997.
- *
- *  Force Cyrix 6x86(MX) and M II processors to report MTRR capability
- *  and Cyrix "coma bug" recognition by
- *  Zoltán Böszörményi <zboszor@mail.externet.hu> February 1999.
- * 
- *  Force Centaur C6 processors to report MTRR capability.
- *  Bart Hartgers <bart@etpmod.phys.tue.nl>, May 1999.
- *
- *  Intel Mobile Pentium II detection fix. Sean Gilley, June 1999.
- *
- *  IDT Winchip tweaks, misc clean ups.
- *  Dave Jones <davej@suse.de>, August 1999
- *
- *  Better detection of Centaur/IDT WinChip models.
- *  Bart Hartgers <bart@etpmod.phys.tue.nl>, August 1999.
- *
- *  Cleaned up cache-detection code
- *  Dave Jones <davej@suse.de>, October 1999
- *
- *  Added proper L2 cache detection for Coppermine
- *  Dragan Stancevic <visitor@valinux.com>, October 1999
- *
- *  Added the original array for capability flags but forgot to credit 
- *  myself :) (~1998) Fixed/cleaned up some cpu_model_info and other stuff
- *  Jauder Ho <jauderho@carumba.com>, January 2000
- *
- *  Detection for Celeron coppermine, identify_cpu() overhauled,
- *  and a few other clean ups.
- *  Dave Jones <davej@suse.de>, April 2000
- *
- *  Pentium III FXSR, SSE support
- *  General FPU state handling cleanups
- *  Gareth Hughes <gareth@valinux.com>, May 2000
- *
- *  Added proper Cascades CPU and L2 cache detection for Cascades
- *  and 8-way type cache happy bunch from Intel:^)
- *  Dragan Stancevic <visitor@valinux.com>, May 2000 
- *
- *  Forward port AMD Duron errata T13 from 2.2.17pre
- *  Dave Jones <davej@suse.de>, August 2000
- *
- *  Forward port lots of fixes/improvements from 2.2.18pre
- *  Cyrix III, Pentium IV support.
- *  Dave Jones <davej@suse.de>, October 2000
- *
- *  Massive cleanup of CPU detection and bug handling;
- *  Transmeta CPU detection,
- *  H. Peter Anvin <hpa@zytor.com>, November 2000
- *
- *  VIA C3 Support.
- *  Dave Jones <davej@suse.de>, March 2001
- *
- *  AMD Athlon/Duron/Thunderbird bluesmoke support.
- *  Dave Jones <davej@suse.de>, April 2001.
- *
- *  CacheSize bug workaround updates for AMD, Intel & VIA Cyrix.
- *  Dave Jones <davej@suse.de>, September, October 2001.
- *
- */
-
diff --git a/arch/i386/kernel/cpu/mtrr/changelog b/arch/i386/kernel/cpu/mtrr/changelog
deleted file mode 100644
index af13685..0000000
--- a/arch/i386/kernel/cpu/mtrr/changelog
+++ /dev/null
@@ -1,229 +0,0 @@
-    ChangeLog
-
-    Prehistory Martin Tischhäuser <martin@ikcbarka.fzk.de>
-	       Initial register-setting code (from proform-1.0).
-    19971216   Richard Gooch <rgooch@atnf.csiro.au>
-               Original version for /proc/mtrr interface, SMP-safe.
-  v1.0
-    19971217   Richard Gooch <rgooch@atnf.csiro.au>
-               Bug fix for ioctls()'s.
-	       Added sample code in Documentation/mtrr.txt
-  v1.1
-    19971218   Richard Gooch <rgooch@atnf.csiro.au>
-               Disallow overlapping regions.
-    19971219   Jens Maurer <jmaurer@menuett.rhein-main.de>
-               Register-setting fixups.
-  v1.2
-    19971222   Richard Gooch <rgooch@atnf.csiro.au>
-               Fixups for kernel 2.1.75.
-  v1.3
-    19971229   David Wragg <dpw@doc.ic.ac.uk>
-               Register-setting fixups and conformity with Intel conventions.
-    19971229   Richard Gooch <rgooch@atnf.csiro.au>
-               Cosmetic changes and wrote this ChangeLog ;-)
-    19980106   Richard Gooch <rgooch@atnf.csiro.au>
-               Fixups for kernel 2.1.78.
-  v1.4
-    19980119   David Wragg <dpw@doc.ic.ac.uk>
-               Included passive-release enable code (elsewhere in PCI setup).
-  v1.5
-    19980131   Richard Gooch <rgooch@atnf.csiro.au>
-               Replaced global kernel lock with private spinlock.
-  v1.6
-    19980201   Richard Gooch <rgooch@atnf.csiro.au>
-               Added wait for other CPUs to complete changes.
-  v1.7
-    19980202   Richard Gooch <rgooch@atnf.csiro.au>
-               Bug fix in definition of <set_mtrr> for UP.
-  v1.8
-    19980319   Richard Gooch <rgooch@atnf.csiro.au>
-               Fixups for kernel 2.1.90.
-    19980323   Richard Gooch <rgooch@atnf.csiro.au>
-               Move SMP BIOS fixup before secondary CPUs call <calibrate_delay>
-  v1.9
-    19980325   Richard Gooch <rgooch@atnf.csiro.au>
-               Fixed test for overlapping regions: confused by adjacent regions
-    19980326   Richard Gooch <rgooch@atnf.csiro.au>
-               Added wbinvd in <set_mtrr_prepare>.
-    19980401   Richard Gooch <rgooch@atnf.csiro.au>
-               Bug fix for non-SMP compilation.
-    19980418   David Wragg <dpw@doc.ic.ac.uk>
-               Fixed-MTRR synchronisation for SMP and use atomic operations
-	       instead of spinlocks.
-    19980418   Richard Gooch <rgooch@atnf.csiro.au>
-	       Differentiate different MTRR register classes for BIOS fixup.
-  v1.10
-    19980419   David Wragg <dpw@doc.ic.ac.uk>
-	       Bug fix in variable MTRR synchronisation.
-  v1.11
-    19980419   Richard Gooch <rgooch@atnf.csiro.au>
-	       Fixups for kernel 2.1.97.
-  v1.12
-    19980421   Richard Gooch <rgooch@atnf.csiro.au>
-	       Safer synchronisation across CPUs when changing MTRRs.
-  v1.13
-    19980423   Richard Gooch <rgooch@atnf.csiro.au>
-	       Bugfix for SMP systems without MTRR support.
-  v1.14
-    19980427   Richard Gooch <rgooch@atnf.csiro.au>
-	       Trap calls to <mtrr_add> and <mtrr_del> on non-MTRR machines.
-  v1.15
-    19980427   Richard Gooch <rgooch@atnf.csiro.au>
-	       Use atomic bitops for setting SMP change mask.
-  v1.16
-    19980428   Richard Gooch <rgooch@atnf.csiro.au>
-	       Removed spurious diagnostic message.
-  v1.17
-    19980429   Richard Gooch <rgooch@atnf.csiro.au>
-	       Moved register-setting macros into this file.
-	       Moved setup code from init/main.c to i386-specific areas.
-  v1.18
-    19980502   Richard Gooch <rgooch@atnf.csiro.au>
-	       Moved MTRR detection outside conditionals in <mtrr_init>.
-  v1.19
-    19980502   Richard Gooch <rgooch@atnf.csiro.au>
-	       Documentation improvement: mention Pentium II and AGP.
-  v1.20
-    19980521   Richard Gooch <rgooch@atnf.csiro.au>
-	       Only manipulate interrupt enable flag on local CPU.
-	       Allow enclosed uncachable regions.
-  v1.21
-    19980611   Richard Gooch <rgooch@atnf.csiro.au>
-	       Always define <main_lock>.
-  v1.22
-    19980901   Richard Gooch <rgooch@atnf.csiro.au>
-	       Removed module support in order to tidy up code.
-	       Added sanity check for <mtrr_add>/<mtrr_del> before <mtrr_init>.
-	       Created addition queue for prior to SMP commence.
-  v1.23
-    19980902   Richard Gooch <rgooch@atnf.csiro.au>
-	       Ported patch to kernel 2.1.120-pre3.
-  v1.24
-    19980910   Richard Gooch <rgooch@atnf.csiro.au>
-	       Removed sanity checks and addition queue: Linus prefers an OOPS.
-  v1.25
-    19981001   Richard Gooch <rgooch@atnf.csiro.au>
-	       Fixed harmless compiler warning in include/asm-i386/mtrr.h
-	       Fixed version numbering and history for v1.23 -> v1.24.
-  v1.26
-    19990118   Richard Gooch <rgooch@atnf.csiro.au>
-	       Added devfs support.
-  v1.27
-    19990123   Richard Gooch <rgooch@atnf.csiro.au>
-	       Changed locking to spin with reschedule.
-	       Made use of new <smp_call_function>.
-  v1.28
-    19990201   Zoltán Böszörményi <zboszor@mail.externet.hu>
-	       Extended the driver to be able to use Cyrix style ARRs.
-    19990204   Richard Gooch <rgooch@atnf.csiro.au>
-	       Restructured Cyrix support.
-  v1.29
-    19990204   Zoltán Böszörményi <zboszor@mail.externet.hu>
-	       Refined ARR support: enable MAPEN in set_mtrr_prepare()
-	       and disable MAPEN in set_mtrr_done().
-    19990205   Richard Gooch <rgooch@atnf.csiro.au>
-	       Minor cleanups.
-  v1.30
-    19990208   Zoltán Böszörményi <zboszor@mail.externet.hu>
-               Protect plain 6x86s (and other processors without the
-               Page Global Enable feature) against accessing CR4 in
-               set_mtrr_prepare() and set_mtrr_done().
-    19990210   Richard Gooch <rgooch@atnf.csiro.au>
-	       Turned <set_mtrr_up> and <get_mtrr> into function pointers.
-  v1.31
-    19990212   Zoltán Böszörményi <zboszor@mail.externet.hu>
-               Major rewrite of cyrix_arr_init(): do not touch ARRs,
-               leave them as the BIOS have set them up.
-               Enable usage of all 8 ARRs.
-               Avoid multiplications by 3 everywhere and other
-               code clean ups/speed ups.
-    19990213   Zoltán Böszörményi <zboszor@mail.externet.hu>
-               Set up other Cyrix processors identical to the boot cpu.
-               Since Cyrix don't support Intel APIC, this is l'art pour l'art.
-               Weigh ARRs by size:
-               If size <= 32M is given, set up ARR# we were given.
-               If size >  32M is given, set up ARR7 only if it is free,
-               fail otherwise.
-    19990214   Zoltán Böszörményi <zboszor@mail.externet.hu>
-               Also check for size >= 256K if we are to set up ARR7,
-               mtrr_add() returns the value it gets from set_mtrr()
-    19990218   Zoltán Böszörményi <zboszor@mail.externet.hu>
-               Remove Cyrix "coma bug" workaround from here.
-               Moved to linux/arch/i386/kernel/setup.c and
-               linux/include/asm-i386/bugs.h
-    19990228   Richard Gooch <rgooch@atnf.csiro.au>
-	       Added MTRRIOC_KILL_ENTRY ioctl(2)
-	       Trap for counter underflow in <mtrr_file_del>.
-	       Trap for 4 MiB aligned regions for PPro, stepping <= 7.
-    19990301   Richard Gooch <rgooch@atnf.csiro.au>
-	       Created <get_free_region> hook.
-    19990305   Richard Gooch <rgooch@atnf.csiro.au>
-	       Temporarily disable AMD support now MTRR capability flag is set.
-  v1.32
-    19990308   Zoltán Böszörményi <zboszor@mail.externet.hu>
-	       Adjust my changes (19990212-19990218) to Richard Gooch's
-	       latest changes. (19990228-19990305)
-  v1.33
-    19990309   Richard Gooch <rgooch@atnf.csiro.au>
-	       Fixed typo in <printk> message.
-    19990310   Richard Gooch <rgooch@atnf.csiro.au>
-	       Support K6-II/III based on Alan Cox's <alan@redhat.com> patches.
-  v1.34
-    19990511   Bart Hartgers <bart@etpmod.phys.tue.nl>
-	       Support Centaur C6 MCR's.
-    19990512   Richard Gooch <rgooch@atnf.csiro.au>
-	       Minor cleanups.
-  v1.35
-    19990707   Zoltán Böszörményi <zboszor@mail.externet.hu>
-               Check whether ARR3 is protected in cyrix_get_free_region()
-               and mtrr_del(). The code won't attempt to delete or change it
-               from now on if the BIOS protected ARR3. It silently skips ARR3
-               in cyrix_get_free_region() or returns with an error code from
-               mtrr_del().
-    19990711   Zoltán Böszörményi <zboszor@mail.externet.hu>
-               Reset some bits in the CCRs in cyrix_arr_init() to disable SMM
-               if ARR3 isn't protected. This is needed because if SMM is active
-               and ARR3 isn't protected then deleting and setting ARR3 again
-               may lock up the processor. With SMM entirely disabled, it does
-               not happen.
-    19990812   Zoltán Böszörményi <zboszor@mail.externet.hu>
-               Rearrange switch() statements so the driver accomodates to
-               the fact that the AMD Athlon handles its MTRRs the same way
-               as Intel does.
-    19990814   Zoltán Böszörményi <zboszor@mail.externet.hu>
-	       Double check for Intel in mtrr_add()'s big switch() because
-	       that revision check is only valid for Intel CPUs.
-    19990819   Alan Cox <alan@redhat.com>
-               Tested Zoltan's changes on a pre production Athlon - 100%
-               success.
-    19991008   Manfred Spraul <manfreds@colorfullife.com>
-    	       replaced spin_lock_reschedule() with a normal semaphore.
-  v1.36
-    20000221   Richard Gooch <rgooch@atnf.csiro.au>
-               Compile fix if procfs and devfs not enabled.
-	       Formatting changes.
-  v1.37
-    20001109   H. Peter Anvin <hpa@zytor.com>
-	       Use the new centralized CPU feature detects.
-
-  v1.38
-    20010309   Dave Jones <davej@suse.de>
-	       Add support for Cyrix III.
-
-  v1.39
-    20010312   Dave Jones <davej@suse.de>
-               Ugh, I broke AMD support.
-	       Reworked fix by Troels Walsted Hansen <troels@thule.no>
-
-  v1.40
-    20010327   Dave Jones <davej@suse.de>
-	       Adapted Cyrix III support to include VIA C3.
-
-  v2.0
-    20020306   Patrick Mochel <mochel@osdl.org>
-               Split mtrr.c -> mtrr/*.c
-               Converted to Linux Kernel Coding Style
-               Fixed several minor nits in form
-               Moved some SMP-only functions out, so they can be used
-                for power management in the future.
-               TODO: Fix user interface cruft.
diff --git a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c
index c30a16d..e8a5355 100644
--- a/arch/i386/mm/pageattr.c
+++ b/arch/i386/mm/pageattr.c
@@ -222,6 +222,10 @@
 {
 	if (PageHighMem(page))
 		return;
+	if (!enable)
+		mutex_debug_check_no_locks_freed(page_address(page),
+						 page_address(page+numpages));
+
 	/* the return value is ignored - the calls cannot fail,
 	 * large pages are disabled at boot time.
 	 */
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 06be405..9c89eeb 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -1171,7 +1171,8 @@
 		return -ENODEV;
 	}
 
-	if ((major = register_chrdev(0, module_name, &vpe_fops) < 0)) {
+	major = register_chrdev(0, module_name, &vpe_fops);
+	if (major < 0) {
 		printk("VPE loader: unable to register character device\n");
 		return major;
 	}
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 977ee3a..34ab0da 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -972,7 +972,7 @@
 #endif
 
 #ifdef CONFIG_PPC_RTAS
-	/* To help early debugging via the front panel, we retreive a minimal
+	/* To help early debugging via the front panel, we retrieve a minimal
 	 * set of RTAS infos now if available
 	 */
 	{
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 4283fa3..ae2e2a3 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -632,7 +632,7 @@
 }
 
 /*
- * Call early during boot, before mem init or bootmem, to retreive the RTAS
+ * Call early during boot, before mem init or bootmem, to retrieve the RTAS
  * informations from the device-tree and allocate the RMO buffer for userland
  * accesses.
  */
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 98e9f05..81567e9 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -438,7 +438,7 @@
 
 	/*
 	 * Fill the ppc64_caches & systemcfg structures with informations
-	 * retreived from the device-tree. Need to be called before
+	 * retrieved from the device-tree. Need to be called before
 	 * finish_device_tree() since the later requires some of the
 	 * informations filled up here to properly parse the interrupt
 	 * tree.
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 5bb433c..149351a 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -368,7 +368,7 @@
 	unsigned long mem_size, rnd_mem_size, pteg_count;
 
 	/* If hash size isn't already provided by the platform, we try to
-	 * retreive it from the device-tree. If it's not there neither, we
+	 * retrieve it from the device-tree. If it's not there neither, we
 	 * calculate it now based on the total RAM size
 	 */
 	if (ppc64_pft_size == 0)
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 1f3507c..d2ba358 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -137,7 +137,7 @@
 static void spufs_prune_dir(struct dentry *dir)
 {
 	struct dentry *dentry, *tmp;
-	down(&dir->d_inode->i_sem);
+	mutex_lock(&dir->d_inode->i_mutex);
 	list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) {
 		spin_lock(&dcache_lock);
 		spin_lock(&dentry->d_lock);
@@ -154,7 +154,7 @@
 		}
 	}
 	shrink_dcache_parent(dir);
-	up(&dir->d_inode->i_sem);
+	mutex_unlock(&dir->d_inode->i_mutex);
 }
 
 static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry)
@@ -162,15 +162,15 @@
 	struct spu_context *ctx;
 
 	/* remove all entries */
-	down(&root->i_sem);
+	mutex_lock(&root->i_mutex);
 	spufs_prune_dir(dir_dentry);
-	up(&root->i_sem);
+	mutex_unlock(&root->i_mutex);
 
 	/* We have to give up the mm_struct */
 	ctx = SPUFS_I(dir_dentry->d_inode)->i_ctx;
 	spu_forget(ctx);
 
-	/* XXX Do we need to hold i_sem here ? */
+	/* XXX Do we need to hold i_mutex here ? */
 	return simple_rmdir(root, dir_dentry);
 }
 
@@ -330,7 +330,7 @@
 out_dput:
 	dput(dentry);
 out_dir:
-	up(&nd->dentry->d_inode->i_sem);
+	mutex_unlock(&nd->dentry->d_inode->i_mutex);
 out:
 	return ret;
 }
diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c
index a4b50c4..a415e8d 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_64.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_64.c
@@ -80,7 +80,7 @@
 };
 
 /* Power mode data is an array of the 32 bits PCR values to use for
- * the various frequencies, retreived from the device-tree
+ * the various frequencies, retrieved from the device-tree
  */
 static u32 *g5_pmode_data;
 static int g5_pmode_max;
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 46a6ad6..a3fb337 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,46 +1,67 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11
-# Sun Mar  6 20:47:29 2005
+# Linux kernel version: 2.6.15
+# Mon Jan  9 14:36:29 2006
 #
+CONFIG_SPARC=y
+CONFIG_SPARC64=y
 CONFIG_64BIT=y
 CONFIG_MMU=y
 CONFIG_TIME_INTERPOLATION=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_SPARC64_PAGE_SIZE_8KB=y
+# CONFIG_SPARC64_PAGE_SIZE_64KB is not set
+# CONFIG_SPARC64_PAGE_SIZE_512KB is not set
+# CONFIG_SPARC64_PAGE_SIZE_4MB is not set
+CONFIG_SECCOMP=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
-CONFIG_LOCK_KERNEL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=15
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -52,20 +73,32 @@
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 CONFIG_KMOD=y
-CONFIG_STOP_MACHINE=y
+
+#
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_SYSVIPC_COMPAT=y
 
 #
 # General machine setup
 #
-CONFIG_BBC_I2C=m
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_SMP=y
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
-CONFIG_NR_CPUS=4
 CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=m
 # CONFIG_CPU_FREQ_DEBUG is not set
 CONFIG_CPU_FREQ_STAT=m
 CONFIG_CPU_FREQ_STAT_DETAILS=y
@@ -75,15 +108,22 @@
 CONFIG_CPU_FREQ_GOV_POWERSAVE=m
 CONFIG_CPU_FREQ_GOV_USERSPACE=m
 CONFIG_CPU_FREQ_GOV_ONDEMAND=m
-CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
 CONFIG_US3_FREQ=m
 CONFIG_US2E_FREQ=m
-CONFIG_SPARC64=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HUGETLB_PAGE_SIZE_4MB=y
 # CONFIG_HUGETLB_PAGE_SIZE_512K is not set
 # CONFIG_HUGETLB_PAGE_SIZE_64K is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_SBUS=y
 CONFIG_SBUSCHAR=y
@@ -91,130 +131,142 @@
 CONFIG_SUN_IO=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
-CONFIG_RTC=y
 # CONFIG_PCI_LEGACY_PROC is not set
-# CONFIG_PCI_NAMES is not set
+# CONFIG_PCI_DEBUG is not set
 CONFIG_SUN_OPENPROMFS=m
 CONFIG_SPARC32_COMPAT=y
 CONFIG_COMPAT=y
-CONFIG_UID16=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_AOUT32 is not set
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_MISC=m
-CONFIG_SOLARIS_EMUL=m
 
 #
-# Parallel port support
+# Executable file formats
 #
-CONFIG_PARPORT=m
-CONFIG_PARPORT_PC=m
-CONFIG_PARPORT_PC_FIFO=y
-# CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_SUNBPP is not set
-# CONFIG_PARPORT_OTHER is not set
-CONFIG_PARPORT_1284=y
-CONFIG_PRINTER=m
-CONFIG_ENVCTRL=m
-CONFIG_DISPLAY7SEG=m
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=m
+# CONFIG_SOLARIS_EMUL is not set
 # CONFIG_CMDLINE_BOOL is not set
 
 #
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_ARPD=y
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_DCCP_CCID3=m
+CONFIG_IP_DCCP_TFRC_LIB=m
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
+# CONFIG_IP_DCCP_UNLOAD_HACK is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+CONFIG_VLAN_8021Q=m
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
 # Generic Driver Options
 #
 CONFIG_STANDALONE=y
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
 # CONFIG_DEBUG_DRIVER is not set
 
 #
-# Graphics support
+# Connector - unified userspace <-> kernelspace linker
 #
-CONFIG_FB=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_TILEBLITTING=y
-# CONFIG_FB_CIRRUS is not set
-CONFIG_FB_PM2=y
-# CONFIG_FB_PM2_FIFO_DISCONNECT is not set
-# CONFIG_FB_ASILIANT is not set
-# CONFIG_FB_IMSTT is not set
-# CONFIG_FB_BW2 is not set
-# CONFIG_FB_CG3 is not set
-CONFIG_FB_CG6=y
-# CONFIG_FB_RIVA is not set
-# CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
-# CONFIG_FB_RADEON is not set
-# CONFIG_FB_ATY128 is not set
-CONFIG_FB_ATY=y
-CONFIG_FB_ATY_CT=y
-# CONFIG_FB_ATY_GENERIC_LCD is not set
-# CONFIG_FB_ATY_XL_INIT is not set
-CONFIG_FB_ATY_GX=y
-# CONFIG_FB_SAVAGE is not set
-# CONFIG_FB_SIS is not set
-# CONFIG_FB_NEOMAGIC is not set
-# CONFIG_FB_KYRO is not set
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_VOODOO1 is not set
-# CONFIG_FB_TRIDENT is not set
-CONFIG_FB_SBUS=y
-CONFIG_FB_FFB=y
-# CONFIG_FB_TCX is not set
-# CONFIG_FB_CG14 is not set
-# CONFIG_FB_P9100 is not set
-# CONFIG_FB_LEO is not set
-# CONFIG_FB_PCI is not set
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Console display driver support
-#
-# CONFIG_PROM_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-# CONFIG_FONT_8x8 is not set
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-CONFIG_FONT_SUN8x16=y
-# CONFIG_FONT_SUN12x22 is not set
-
-#
-# Logo configuration
-#
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-# CONFIG_LOGO_LINUX_CLUT224 is not set
-CONFIG_LOGO_SUN_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Serial drivers
-#
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_SUNCORE=y
-CONFIG_SERIAL_SUNZILOG=y
-CONFIG_SERIAL_SUNZILOG_CONSOLE=y
-CONFIG_SERIAL_SUNSU=y
-CONFIG_SERIAL_SUNSU_CONSOLE=y
-CONFIG_SERIAL_SUNSAB=m
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-
-#
-# Misc Linux/SPARC drivers
-#
-CONFIG_SUN_OPENPROMIO=m
-CONFIG_SUN_MOSTEK_RTC=y
-CONFIG_OBP_FLASH=m
-# CONFIG_SUN_BPP is not set
+CONFIG_CONNECTOR=m
 
 #
 # Memory Technology Devices (MTD)
@@ -222,10 +274,18 @@
 # CONFIG_MTD is not set
 
 #
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
 # Block devices
 #
 # CONFIG_BLK_DEV_FD is not set
-# CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -234,22 +294,13 @@
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_SX8=m
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_UB=m
 # CONFIG_BLK_DEV_RAM is not set
 CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 CONFIG_CDROM_PKTCDVD_WCACHE=y
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 CONFIG_ATA_OVER_ETH=m
 
 #
@@ -265,7 +316,7 @@
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 CONFIG_BLK_DEV_IDECD=y
-CONFIG_BLK_DEV_IDETAPE=m
+# CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
@@ -278,7 +329,7 @@
 # CONFIG_IDEPCI_SHARE_IRQ is not set
 # CONFIG_BLK_DEV_OFFBOARD is not set
 # CONFIG_BLK_DEV_GENERIC is not set
-CONFIG_BLK_DEV_OPTI621=m
+# CONFIG_BLK_DEV_OPTI621 is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
@@ -286,27 +337,25 @@
 # CONFIG_BLK_DEV_AEC62XX is not set
 CONFIG_BLK_DEV_ALI15X3=y
 # CONFIG_WDC_ALI15X3 is not set
-CONFIG_BLK_DEV_AMD74XX=m
-CONFIG_BLK_DEV_CMD64X=m
-CONFIG_BLK_DEV_TRIFLEX=m
-CONFIG_BLK_DEV_CY82C693=m
-CONFIG_BLK_DEV_CS5520=m
-CONFIG_BLK_DEV_CS5530=m
-CONFIG_BLK_DEV_HPT34X=m
-# CONFIG_HPT34X_AUTODMA is not set
-CONFIG_BLK_DEV_HPT366=m
-CONFIG_BLK_DEV_SC1200=m
-CONFIG_BLK_DEV_PIIX=m
-CONFIG_BLK_DEV_NS87415=m
-CONFIG_BLK_DEV_PDC202XX_OLD=m
-# CONFIG_PDC202XX_BURST is not set
-CONFIG_BLK_DEV_PDC202XX_NEW=m
-# CONFIG_PDC202XX_FORCE is not set
-CONFIG_BLK_DEV_SVWKS=m
-CONFIG_BLK_DEV_SIIMAGE=m
-CONFIG_BLK_DEV_SLC90E66=m
-CONFIG_BLK_DEV_TRM290=m
-CONFIG_BLK_DEV_VIA82CXXX=m
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
 # CONFIG_IDE_ARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
@@ -316,6 +365,7 @@
 #
 # SCSI device support
 #
+CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_SCSI_PROC_FS=y
 
@@ -323,11 +373,12 @@
 # SCSI support type (disk, tape, CD-ROM)
 #
 CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
 CONFIG_BLK_DEV_SR=m
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -340,89 +391,42 @@
 # SCSI Transport Attributes
 #
 CONFIG_SCSI_SPI_ATTRS=y
-CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=y
 CONFIG_SCSI_ISCSI_ATTRS=m
+# CONFIG_SCSI_SAS_ATTRS is not set
 
 #
 # SCSI low-level drivers
 #
-CONFIG_BLK_DEV_3W_XXXX_RAID=m
-CONFIG_SCSI_3W_9XXX=m
-CONFIG_SCSI_ACARD=m
-CONFIG_SCSI_AACRAID=m
+CONFIG_ISCSI_TCP=m
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
-CONFIG_SCSI_AIC79XX=m
-CONFIG_AIC79XX_CMDS_PER_DEVICE=32
-CONFIG_AIC79XX_RESET_DELAY_MS=15000
-# CONFIG_AIC79XX_BUILD_FIRMWARE is not set
-# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
-# CONFIG_AIC79XX_DEBUG_ENABLE is not set
-CONFIG_AIC79XX_DEBUG_MASK=0
-# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_AIC79XX is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
-CONFIG_SCSI_SATA=y
-CONFIG_SCSI_SATA_AHCI=m
-CONFIG_SCSI_SATA_SVW=m
-CONFIG_SCSI_ATA_PIIX=m
-CONFIG_SCSI_SATA_NV=m
-CONFIG_SCSI_SATA_PROMISE=m
-CONFIG_SCSI_SATA_QSTOR=m
-CONFIG_SCSI_SATA_SX4=m
-CONFIG_SCSI_SATA_SIL=m
-CONFIG_SCSI_SATA_SIS=m
-CONFIG_SCSI_SATA_ULI=m
-CONFIG_SCSI_SATA_VIA=m
-CONFIG_SCSI_SATA_VITESSE=m
-CONFIG_SCSI_DMX3191D=m
-CONFIG_SCSI_EATA_PIO=m
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
-CONFIG_SCSI_IPS=m
-CONFIG_SCSI_INITIO=m
-CONFIG_SCSI_INIA100=m
-CONFIG_SCSI_PPA=m
-CONFIG_SCSI_IMM=m
-# CONFIG_SCSI_IZIP_EPP16 is not set
-# CONFIG_SCSI_IZIP_SLOW_CTR is not set
-CONFIG_SCSI_SYM53C8XX_2=y
-CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
-CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
-CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
-CONFIG_SCSI_QLOGIC_ISP=m
-CONFIG_SCSI_QLOGIC_FC=y
-CONFIG_SCSI_QLOGIC_FC_FIRMWARE=y
+# CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLOGICPTI=m
+# CONFIG_SCSI_QLOGICPTI is not set
 CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-CONFIG_SCSI_DC395x=m
+# CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
-CONFIG_SCSI_DEBUG=m
-CONFIG_SCSI_SUNESP=y
-
-#
-# Fibre Channel support
-#
-CONFIG_FC4=m
-
-#
-# FC4 drivers
-#
-CONFIG_FC4_SOC=m
-CONFIG_FC4_SOCAL=m
-
-#
-# FC4 targets
-#
-CONFIG_SCSI_PLUTO=m
-CONFIG_SCSI_FCAL=m
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SUNESP is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -442,427 +446,34 @@
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+# CONFIG_DM_MULTIPATH is not set
 
 #
 # Fusion MPT device support
 #
-CONFIG_FUSION=m
-CONFIG_FUSION_MAX_SGE=40
-CONFIG_FUSION_CTL=m
-CONFIG_FUSION_LAN=m
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
-CONFIG_IEEE1394=m
+# CONFIG_IEEE1394 is not set
 
 #
-# Subsystem Options
+# I2O device support
 #
-# CONFIG_IEEE1394_VERBOSEDEBUG is not set
-CONFIG_IEEE1394_OUI_DB=y
-CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
-CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_I2O is not set
 
 #
-# Device Drivers
+# Network device support
 #
-CONFIG_IEEE1394_PCILYNX=m
-CONFIG_IEEE1394_OHCI1394=m
-
-#
-# Protocol Drivers
-#
-CONFIG_IEEE1394_VIDEO1394=m
-CONFIG_IEEE1394_SBP2=m
-# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
-CONFIG_IEEE1394_ETH1394=m
-CONFIG_IEEE1394_DV1394=m
-CONFIG_IEEE1394_RAWIO=m
-CONFIG_IEEE1394_CMP=m
-CONFIG_IEEE1394_AMDTP=m
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-CONFIG_ARPD=y
-CONFIG_SYN_COOKIES=y
-CONFIG_INET_AH=y
-CONFIG_INET_ESP=y
-CONFIG_INET_IPCOMP=y
-CONFIG_INET_TUNNEL=y
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-CONFIG_IP_VS=m
-# CONFIG_IP_VS_DEBUG is not set
-CONFIG_IP_VS_TAB_BITS=12
-
-#
-# IPVS transport protocol load balancing support
-#
-CONFIG_IP_VS_PROTO_TCP=y
-CONFIG_IP_VS_PROTO_UDP=y
-CONFIG_IP_VS_PROTO_ESP=y
-CONFIG_IP_VS_PROTO_AH=y
-
-#
-# IPVS scheduler
-#
-CONFIG_IP_VS_RR=m
-CONFIG_IP_VS_WRR=m
-CONFIG_IP_VS_LC=m
-CONFIG_IP_VS_WLC=m
-CONFIG_IP_VS_LBLC=m
-CONFIG_IP_VS_LBLCR=m
-CONFIG_IP_VS_DH=m
-CONFIG_IP_VS_SH=m
-CONFIG_IP_VS_SED=m
-CONFIG_IP_VS_NQ=m
-
-#
-# IPVS application helper
-#
-CONFIG_IP_VS_FTP=m
-CONFIG_IPV6=m
-CONFIG_IPV6_PRIVACY=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_INET6_TUNNEL=m
-CONFIG_IPV6_TUNNEL=m
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_BRIDGE_NETFILTER=y
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_CT_ACCT=y
-CONFIG_IP_NF_CONNTRACK_MARK=y
-CONFIG_IP_NF_CT_PROTO_SCTP=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_RECENT=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_MATCH_PHYSDEV=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_REALM=m
-CONFIG_IP_NF_MATCH_SCTP=m
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=m
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_TARGET_NETMAP=m
-CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
-CONFIG_IP_NF_TARGET_CONNMARK=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-
-#
-# IPv6: Netfilter Configuration
-#
-CONFIG_IP6_NF_QUEUE=m
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
-CONFIG_IP6_NF_MATCH_RT=m
-CONFIG_IP6_NF_MATCH_OPTS=m
-CONFIG_IP6_NF_MATCH_FRAG=m
-CONFIG_IP6_NF_MATCH_HL=m
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
-CONFIG_IP6_NF_MATCH_OWNER=m
-CONFIG_IP6_NF_MATCH_MARK=m
-CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_AHESP=m
-CONFIG_IP6_NF_MATCH_LENGTH=m
-CONFIG_IP6_NF_MATCH_EUI64=m
-CONFIG_IP6_NF_MATCH_PHYSDEV=m
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_LOG=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
-CONFIG_IP6_NF_RAW=m
-
-#
-# DECnet: Netfilter Configuration
-#
-CONFIG_DECNET_NF_GRABULATOR=m
-
-#
-# Bridge: Netfilter Configuration
-#
-CONFIG_BRIDGE_NF_EBTABLES=m
-CONFIG_BRIDGE_EBT_BROUTE=m
-CONFIG_BRIDGE_EBT_T_FILTER=m
-CONFIG_BRIDGE_EBT_T_NAT=m
-CONFIG_BRIDGE_EBT_802_3=m
-CONFIG_BRIDGE_EBT_AMONG=m
-CONFIG_BRIDGE_EBT_ARP=m
-CONFIG_BRIDGE_EBT_IP=m
-CONFIG_BRIDGE_EBT_LIMIT=m
-CONFIG_BRIDGE_EBT_MARK=m
-CONFIG_BRIDGE_EBT_PKTTYPE=m
-CONFIG_BRIDGE_EBT_STP=m
-CONFIG_BRIDGE_EBT_VLAN=m
-CONFIG_BRIDGE_EBT_ARPREPLY=m
-CONFIG_BRIDGE_EBT_DNAT=m
-CONFIG_BRIDGE_EBT_MARK_T=m
-CONFIG_BRIDGE_EBT_REDIRECT=m
-CONFIG_BRIDGE_EBT_SNAT=m
-CONFIG_BRIDGE_EBT_LOG=m
-CONFIG_BRIDGE_EBT_ULOG=m
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-CONFIG_IP_SCTP=m
-# CONFIG_SCTP_DBG_MSG is not set
-# CONFIG_SCTP_DBG_OBJCNT is not set
-# CONFIG_SCTP_HMAC_NONE is not set
-# CONFIG_SCTP_HMAC_SHA1 is not set
-CONFIG_SCTP_HMAC_MD5=y
-CONFIG_ATM=y
-CONFIG_ATM_CLIP=y
-# CONFIG_ATM_CLIP_NO_ICMP is not set
-CONFIG_ATM_LANE=m
-CONFIG_ATM_MPOA=m
-CONFIG_ATM_BR2684=m
-CONFIG_ATM_BR2684_IPFILTER=y
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
-CONFIG_DECNET=m
-CONFIG_DECNET_ROUTER=y
-CONFIG_DECNET_ROUTE_FWMARK=y
-CONFIG_LLC=m
-CONFIG_LLC2=m
-CONFIG_IPX=m
-# CONFIG_IPX_INTERN is not set
-CONFIG_ATALK=m
-# CONFIG_DEV_APPLETALK is not set
-CONFIG_X25=m
-CONFIG_LAPB=m
-CONFIG_NET_DIVERT=y
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-CONFIG_NET_SCHED=y
-# CONFIG_NET_SCH_CLK_JIFFIES is not set
-# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
-CONFIG_NET_SCH_CLK_CPU=y
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_HFSC=m
-CONFIG_NET_SCH_ATM=y
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-CONFIG_NET_SCH_NETEM=m
-CONFIG_NET_SCH_INGRESS=m
-CONFIG_NET_QOS=y
-CONFIG_NET_ESTIMATOR=y
-CONFIG_NET_CLS=y
-CONFIG_NET_CLS_BASIC=m
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_ROUTE=y
-CONFIG_NET_CLS_FW=m
-CONFIG_NET_CLS_U32=m
-CONFIG_CLS_U32_PERF=y
-CONFIG_NET_CLS_IND=y
-CONFIG_CLS_U32_MARK=y
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
-CONFIG_NET_EMATCH=y
-CONFIG_NET_EMATCH_STACK=32
-CONFIG_NET_EMATCH_CMP=m
-CONFIG_NET_EMATCH_NBYTE=m
-CONFIG_NET_EMATCH_U32=m
-CONFIG_NET_EMATCH_META=m
-CONFIG_NET_CLS_ACT=y
-CONFIG_NET_ACT_POLICE=m
-CONFIG_NET_ACT_GACT=m
-CONFIG_GACT_PROB=y
-CONFIG_NET_ACT_MIRRED=m
-CONFIG_NET_ACT_IPT=m
-CONFIG_NET_ACT_PEDIT=m
-
-#
-# Network testing
-#
-CONFIG_NET_PKTGEN=m
-CONFIG_NETPOLL=y
-# CONFIG_NETPOLL_RX is not set
-# CONFIG_NETPOLL_TRAP is not set
-CONFIG_NET_POLL_CONTROLLER=y
-CONFIG_HAMRADIO=y
-
-#
-# Packet Radio protocols
-#
-CONFIG_AX25=m
-CONFIG_AX25_DAMA_SLAVE=y
-CONFIG_NETROM=m
-CONFIG_ROSE=m
-
-#
-# AX.25 network device drivers
-#
-# CONFIG_BPQETHER is not set
-# CONFIG_BAYCOM_SER_FDX is not set
-# CONFIG_BAYCOM_SER_HDX is not set
-# CONFIG_BAYCOM_PAR is not set
-# CONFIG_YAM is not set
-CONFIG_IRDA=m
-
-#
-# IrDA protocols
-#
-CONFIG_IRLAN=m
-CONFIG_IRNET=m
-CONFIG_IRCOMM=m
-CONFIG_IRDA_ULTRA=y
-
-#
-# IrDA options
-#
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-# CONFIG_IRDA_DEBUG is not set
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-# CONFIG_IRTTY_SIR is not set
-
-#
-# Dongle support
-#
-
-#
-# Old SIR device drivers
-#
-
-#
-# Old Serial dongle support
-#
-
-#
-# FIR device drivers
-#
-# CONFIG_USB_IRDA is not set
-CONFIG_SIGMATEL_FIR=m
-# CONFIG_VLSI_FIR is not set
-CONFIG_BT=m
-CONFIG_BT_L2CAP=m
-CONFIG_BT_SCO=m
-CONFIG_BT_RFCOMM=m
-CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_BNEP=m
-CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y
-CONFIG_BT_CMTP=m
-CONFIG_BT_HIDP=m
-
-#
-# Bluetooth device drivers
-#
-CONFIG_BT_HCIUSB=m
-CONFIG_BT_HCIUSB_SCO=y
-CONFIG_BT_HCIUART=m
-CONFIG_BT_HCIUART_H4=y
-CONFIG_BT_HCIUART_BCSP=y
-CONFIG_BT_HCIUART_BCSP_TXCRC=y
-CONFIG_BT_HCIBCM203X=m
-CONFIG_BT_HCIBPA10X=m
-CONFIG_BT_HCIBFUSB=m
-CONFIG_BT_HCIVHCI=m
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
-CONFIG_BONDING=m
-CONFIG_EQUALIZER=m
-CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
 
 #
 # ARCnet devices
@@ -870,86 +481,73 @@
 # CONFIG_ARCNET is not set
 
 #
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=m
-CONFIG_SUNLANCE=y
-CONFIG_HAPPYMEAL=y
-CONFIG_SUNBMAC=m
-CONFIG_SUNQE=m
-CONFIG_SUNGEM=y
-CONFIG_NET_VENDOR_3COM=y
-CONFIG_VORTEX=m
-CONFIG_TYPHOON=m
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+CONFIG_CASSINI=m
+# CONFIG_NET_VENDOR_3COM is not set
 
 #
 # Tulip family network device support
 #
-CONFIG_NET_TULIP=y
-CONFIG_DE2104X=m
-CONFIG_TULIP=m
-# CONFIG_TULIP_MWI is not set
-# CONFIG_TULIP_MMIO is not set
-CONFIG_TULIP_NAPI=y
-CONFIG_TULIP_NAPI_HW_MITIGATION=y
-CONFIG_DE4X5=m
-CONFIG_WINBOND_840=m
-# CONFIG_DM9102 is not set
+# CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_NET_PCI=y
-CONFIG_PCNET32=m
+# CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
-CONFIG_ADAPTEC_STARFIRE=m
-CONFIG_ADAPTEC_STARFIRE_NAPI=y
-CONFIG_B44=m
-CONFIG_FORCEDETH=m
-CONFIG_DGRS=m
-CONFIG_EEPRO100=m
-CONFIG_E100=m
-CONFIG_FEALNX=m
-CONFIG_NATSEMI=m
-CONFIG_NE2K_PCI=m
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
 # CONFIG_8139CP is not set
-CONFIG_8139TOO=m
-# CONFIG_8139TOO_PIO is not set
-# CONFIG_8139TOO_TUNE_TWISTER is not set
-# CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_OLD_RX_RESET is not set
-CONFIG_SIS900=m
-CONFIG_EPIC100=m
-CONFIG_SUNDANCE=m
-CONFIG_SUNDANCE_MMIO=y
-CONFIG_VIA_RHINE=m
-# CONFIG_VIA_RHINE_MMIO is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_VIA_RHINE is not set
 
 #
 # Ethernet (1000 Mbit)
 #
-CONFIG_ACENIC=m
-# CONFIG_ACENIC_OMIT_TIGON_I is not set
-CONFIG_DL2K=m
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
 CONFIG_E1000=m
 CONFIG_E1000_NAPI=y
-CONFIG_MYRI_SBUS=m
-CONFIG_NS83820=m
-CONFIG_HAMACHI=m
-CONFIG_YELLOWFIN=m
-CONFIG_R8169=m
-CONFIG_R8169_NAPI=y
-CONFIG_R8169_VLAN=y
-CONFIG_SK98LIN=m
-CONFIG_VIA_VELOCITY=m
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=m
+CONFIG_BNX2=m
 
 #
 # Ethernet (10000 Mbit)
 #
-CONFIG_IXGB=m
-CONFIG_IXGB_NAPI=y
-CONFIG_S2IO=m
-CONFIG_S2IO_NAPI=y
-CONFIG_2BUFF_MODE=y
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
 
 #
 # Token Ring devices
@@ -959,140 +557,31 @@
 #
 # Wireless LAN (non-hamradio)
 #
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-CONFIG_HERMES=m
-CONFIG_PLX_HERMES=m
-CONFIG_TMD_HERMES=m
-CONFIG_PCI_HERMES=m
-CONFIG_ATMEL=m
-CONFIG_PCI_ATMEL=m
-
-#
-# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
-#
-CONFIG_PRISM54=m
-CONFIG_NET_WIRELESS=y
+# CONFIG_NET_RADIO is not set
 
 #
 # Wan interfaces
 #
 # CONFIG_WAN is not set
-
-#
-# ATM drivers
-#
-CONFIG_ATM_TCP=m
-# CONFIG_ATM_LANAI is not set
-# CONFIG_ATM_ENI is not set
-# CONFIG_ATM_FIRESTREAM is not set
-# CONFIG_ATM_ZATM is not set
-# CONFIG_ATM_IDT77252 is not set
-# CONFIG_ATM_AMBASSADOR is not set
-# CONFIG_ATM_HORIZON is not set
-CONFIG_ATM_FORE200E_MAYBE=m
-CONFIG_ATM_FORE200E_PCA=y
-CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y
-CONFIG_ATM_FORE200E_SBA=y
-CONFIG_ATM_FORE200E_SBA_DEFAULT_FW=y
-CONFIG_ATM_FORE200E_USE_TASKLET=y
-CONFIG_ATM_FORE200E_TX_RETRY=16
-CONFIG_ATM_FORE200E_DEBUG=0
-CONFIG_ATM_FORE200E=m
-CONFIG_ATM_HE=m
-CONFIG_ATM_HE_USE_SUNI=y
-CONFIG_FDDI=y
-# CONFIG_DEFXX is not set
-CONFIG_SKFP=m
-CONFIG_HIPPI=y
-# CONFIG_ROADRUNNER is not set
-CONFIG_PLIP=m
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPPOE=m
-CONFIG_PPPOATM=m
-CONFIG_SLIP=m
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_SMART=y
-# CONFIG_SLIP_MODE_SLIP6 is not set
-CONFIG_NET_FC=y
-CONFIG_SHAPER=m
-CONFIG_NETCONSOLE=m
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
 #
-CONFIG_ISDN=m
-
-#
-# Old ISDN4Linux
-#
-# CONFIG_ISDN_I4L is not set
-
-#
-# CAPI subsystem
-#
-CONFIG_ISDN_CAPI=m
-# CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON is not set
-# CONFIG_ISDN_CAPI_MIDDLEWARE is not set
-CONFIG_ISDN_CAPI_CAPI20=m
-
-#
-# CAPI hardware drivers
-#
-
-#
-# Active AVM cards
-#
-CONFIG_CAPI_AVM=y
-CONFIG_ISDN_DRV_AVMB1_B1PCI=m
-CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
-CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m
-CONFIG_ISDN_DRV_AVMB1_T1PCI=m
-CONFIG_ISDN_DRV_AVMB1_C4=m
-
-#
-# Active Eicon DIVA Server cards
-#
-CONFIG_CAPI_EICON=y
-CONFIG_ISDN_DIVAS=m
-CONFIG_ISDN_DIVAS_BRIPCI=y
-CONFIG_ISDN_DIVAS_PRIPCI=y
-CONFIG_ISDN_DIVAS_DIVACAPI=m
-CONFIG_ISDN_DIVAS_USERIDI=m
-CONFIG_ISDN_DIVAS_MAINT=m
+# CONFIG_ISDN is not set
 
 #
 # Telephony Support
 #
-CONFIG_PHONE=m
-CONFIG_PHONE_IXJ=m
-
-#
-# Unix98 PTY support
-#
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# XFree86 DRI support
-#
-CONFIG_DRM=y
-CONFIG_DRM_TDFX=m
-# CONFIG_DRM_R128 is not set
+# CONFIG_PHONE is not set
 
 #
 # Input device support
@@ -1112,26 +601,6 @@
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-CONFIG_GAMEPORT=m
-CONFIG_SOUND_GAMEPORT=m
-# CONFIG_GAMEPORT_NS558 is not set
-# CONFIG_GAMEPORT_L4 is not set
-# CONFIG_GAMEPORT_EMU10K1 is not set
-# CONFIG_GAMEPORT_VORTEX is not set
-# CONFIG_GAMEPORT_FM801 is not set
-CONFIG_GAMEPORT_CS461X=m
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PARKBD is not set
-CONFIG_SERIO_PCIPS2=m
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SERIO_RAW=m
-
-#
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
@@ -1143,7 +612,7 @@
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 CONFIG_MOUSE_SERIAL=y
-CONFIG_MOUSE_VSXXXAA=m
+# CONFIG_MOUSE_VSXXXAA is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 CONFIG_INPUT_MISC=y
@@ -1151,406 +620,250 @@
 # CONFIG_INPUT_UINPUT is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_PCIPS2=m
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SUNCORE=y
+# CONFIG_SERIAL_SUNZILOG is not set
+CONFIG_SERIAL_SUNSU=y
+CONFIG_SERIAL_SUNSU_CONSOLE=y
+CONFIG_SERIAL_SUNSAB=m
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
 # I2C support
 #
 CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=m
+# CONFIG_I2C_CHARDEV is not set
 
 #
 # I2C Algorithms
 #
 CONFIG_I2C_ALGOBIT=y
-CONFIG_I2C_ALGOPCF=m
-CONFIG_I2C_ALGOPCA=m
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
 
 #
 # I2C Hardware Bus support
 #
-CONFIG_I2C_ALI1535=m
-CONFIG_I2C_ALI1563=m
-CONFIG_I2C_ALI15X3=m
-CONFIG_I2C_AMD756=m
-# CONFIG_I2C_AMD756_S4882 is not set
-CONFIG_I2C_AMD8111=m
-CONFIG_I2C_I801=m
-CONFIG_I2C_I810=m
-CONFIG_I2C_ISA=m
-CONFIG_I2C_NFORCE2=m
-CONFIG_I2C_PARPORT=m
-CONFIG_I2C_PARPORT_LIGHT=m
-CONFIG_I2C_PIIX4=m
-CONFIG_I2C_PROSAVAGE=m
-CONFIG_I2C_SAVAGE4=m
-CONFIG_SCx200_ACB=m
-CONFIG_I2C_SIS5595=m
-CONFIG_I2C_SIS630=m
-CONFIG_I2C_SIS96X=m
-CONFIG_I2C_STUB=m
-CONFIG_I2C_VIA=m
-CONFIG_I2C_VIAPRO=m
-CONFIG_I2C_VOODOO3=m
-CONFIG_I2C_PCA_ISA=m
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
 
 #
-# Hardware Sensors Chip support
+# Miscellaneous I2C Chip support
 #
-CONFIG_I2C_SENSOR=m
-CONFIG_SENSORS_ADM1021=m
-CONFIG_SENSORS_ADM1025=m
-CONFIG_SENSORS_ADM1026=m
-CONFIG_SENSORS_ADM1031=m
-CONFIG_SENSORS_ASB100=m
-CONFIG_SENSORS_DS1621=m
-CONFIG_SENSORS_FSCHER=m
-CONFIG_SENSORS_FSCPOS=m
-CONFIG_SENSORS_GL518SM=m
-CONFIG_SENSORS_GL520SM=m
-CONFIG_SENSORS_IT87=m
-CONFIG_SENSORS_LM63=m
-CONFIG_SENSORS_LM75=m
-CONFIG_SENSORS_LM77=m
-CONFIG_SENSORS_LM78=m
-CONFIG_SENSORS_LM80=m
-CONFIG_SENSORS_LM83=m
-CONFIG_SENSORS_LM85=m
-CONFIG_SENSORS_LM87=m
-CONFIG_SENSORS_LM90=m
-CONFIG_SENSORS_MAX1619=m
-CONFIG_SENSORS_PC87360=m
-CONFIG_SENSORS_SMSC47B397=m
-CONFIG_SENSORS_SIS5595=m
-CONFIG_SENSORS_SMSC47M1=m
-CONFIG_SENSORS_VIA686A=m
-CONFIG_SENSORS_W83781D=m
-CONFIG_SENSORS_W83L785TS=m
-CONFIG_SENSORS_W83627HF=m
-
-#
-# Other I2C Chip support
-#
-CONFIG_SENSORS_EEPROM=m
-CONFIG_SENSORS_PCF8574=m
-CONFIG_SENSORS_PCF8591=m
-CONFIG_SENSORS_RTC8564=m
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_RTC_X1205_I2C is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 
 #
-# File systems
+# Dallas's 1-wire bus
 #
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
-CONFIG_EXT3_FS_POSIX_ACL=y
-CONFIG_EXT3_FS_SECURITY=y
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-# CONFIG_REISERFS_FS is not set
-CONFIG_JFS_FS=m
-CONFIG_JFS_POSIX_ACL=y
-CONFIG_JFS_SECURITY=y
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_STATISTICS is not set
-CONFIG_FS_POSIX_ACL=y
+# CONFIG_W1 is not set
 
 #
-# XFS support
+# Hardware Monitoring support
 #
-CONFIG_XFS_FS=m
-CONFIG_XFS_EXPORT=y
-# CONFIG_XFS_RT is not set
-CONFIG_XFS_QUOTA=y
-CONFIG_XFS_SECURITY=y
-CONFIG_XFS_POSIX_ACL=y
-CONFIG_MINIX_FS=m
-CONFIG_ROMFS_FS=m
-# CONFIG_QUOTA is not set
-CONFIG_QUOTACTL=y
-CONFIG_DNOTIFY=y
-CONFIG_AUTOFS_FS=m
-CONFIG_AUTOFS4_FS=m
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
-# CD-ROM/DVD Filesystems
+# Misc devices
 #
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-# CONFIG_ZISOFS is not set
-CONFIG_UDF_FS=m
-CONFIG_UDF_NLS=y
 
 #
-# DOS/FAT/NT Filesystems
+# Multimedia Capabilities Port drivers
 #
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS_XATTR=y
-# CONFIG_DEVPTS_FS_SECURITY is not set
-CONFIG_TMPFS=y
-CONFIG_TMPFS_XATTR=y
-CONFIG_TMPFS_SECURITY=y
-CONFIG_HUGETLBFS=y
-CONFIG_HUGETLB_PAGE=y
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-CONFIG_ADFS_FS=m
-# CONFIG_ADFS_FS_RW is not set
-CONFIG_AFFS_FS=m
-CONFIG_HFS_FS=m
-CONFIG_HFSPLUS_FS=m
-CONFIG_BEFS_FS=m
-# CONFIG_BEFS_DEBUG is not set
-CONFIG_BFS_FS=m
-CONFIG_EFS_FS=m
-CONFIG_CRAMFS=m
-CONFIG_VXFS_FS=m
-CONFIG_HPFS_FS=m
-CONFIG_QNX4FS_FS=m
-CONFIG_SYSV_FS=m
-CONFIG_UFS_FS=m
-CONFIG_UFS_FS_WRITE=y
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-CONFIG_NFS_V4=y
-CONFIG_NFS_DIRECTIO=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-CONFIG_NFSD_V4=y
-CONFIG_NFSD_TCP=y
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
-CONFIG_SUNRPC=m
-CONFIG_SUNRPC_GSS=m
-CONFIG_RPCSEC_GSS_KRB5=m
-CONFIG_RPCSEC_GSS_SPKM3=m
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-CONFIG_CIFS=m
-# CONFIG_CIFS_STATS is not set
-# CONFIG_CIFS_XATTR is not set
-# CONFIG_CIFS_EXPERIMENTAL is not set
-CONFIG_NCP_FS=m
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
-CONFIG_AFS_FS=m
-CONFIG_RXRPC=m
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_SUN_PARTITION=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
 
 #
 # Multimedia devices
 #
-CONFIG_VIDEO_DEV=y
-
-#
-# Video For Linux
-#
-
-#
-# Video Adapters
-#
-CONFIG_VIDEO_BT848=m
-CONFIG_VIDEO_BWQCAM=m
-CONFIG_VIDEO_CQCAM=m
-CONFIG_VIDEO_W9966=m
-CONFIG_VIDEO_CPIA=m
-CONFIG_VIDEO_CPIA_PP=m
-CONFIG_VIDEO_CPIA_USB=m
-CONFIG_VIDEO_SAA5246A=m
-CONFIG_VIDEO_SAA5249=m
-CONFIG_TUNER_3036=m
-# CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_ZORAN is not set
-# CONFIG_VIDEO_SAA7134 is not set
-CONFIG_VIDEO_MXB=m
-CONFIG_VIDEO_DPC=m
-CONFIG_VIDEO_HEXIUM_ORION=m
-CONFIG_VIDEO_HEXIUM_GEMINI=m
-CONFIG_VIDEO_CX88=m
-CONFIG_VIDEO_OVCAMCHIP=m
-
-#
-# Radio Adapters
-#
-CONFIG_RADIO_GEMTEK_PCI=m
-CONFIG_RADIO_MAXIRADIO=m
-CONFIG_RADIO_MAESTRO=m
+# CONFIG_VIDEO_DEV is not set
 
 #
 # Digital Video Broadcasting Devices
 #
-CONFIG_DVB=y
-CONFIG_DVB_CORE=m
+# CONFIG_DVB is not set
 
 #
-# Supported SAA7146 based PCI Adapters
+# Graphics support
 #
-CONFIG_DVB_AV7110=m
-# CONFIG_DVB_AV7110_OSD is not set
-CONFIG_DVB_BUDGET=m
-CONFIG_DVB_BUDGET_CI=m
-CONFIG_DVB_BUDGET_AV=m
-CONFIG_DVB_BUDGET_PATCH=m
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_SBUS is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON_OLD is not set
+CONFIG_FB_RADEON=y
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_PCI is not set
+# CONFIG_FB_VIRTUAL is not set
 
 #
-# Supported USB Adapters
+# Console display driver support
 #
-# CONFIG_DVB_TTUSB_BUDGET is not set
-CONFIG_DVB_TTUSB_DEC=m
-CONFIG_DVB_DIBUSB=m
-# CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES is not set
-CONFIG_DVB_DIBCOM_DEBUG=y
-CONFIG_DVB_CINERGYT2=m
-# CONFIG_DVB_CINERGYT2_TUNING is not set
+# CONFIG_PROM_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+CONFIG_FONT_SUN8x16=y
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
 
 #
-# Supported FlexCopII (B2C2) Adapters
+# Logo configuration
 #
-CONFIG_DVB_B2C2_SKYSTAR=m
-CONFIG_DVB_B2C2_USB=m
-
-#
-# Supported BT878 Adapters
-#
-CONFIG_DVB_BT8XX=m
-
-#
-# Supported DVB Frontends
-#
-
-#
-# Customise DVB Frontends
-#
-
-#
-# DVB-S (satellite) frontends
-#
-CONFIG_DVB_STV0299=m
-CONFIG_DVB_CX24110=m
-CONFIG_DVB_TDA8083=m
-CONFIG_DVB_TDA80XX=m
-CONFIG_DVB_MT312=m
-CONFIG_DVB_VES1X93=m
-
-#
-# DVB-T (terrestrial) frontends
-#
-CONFIG_DVB_SP8870=m
-CONFIG_DVB_SP887X=m
-CONFIG_DVB_CX22700=m
-CONFIG_DVB_CX22702=m
-CONFIG_DVB_L64781=m
-CONFIG_DVB_TDA1004X=m
-CONFIG_DVB_NXT6000=m
-CONFIG_DVB_MT352=m
-CONFIG_DVB_DIB3000MB=m
-CONFIG_DVB_DIB3000MC=m
-
-#
-# DVB-C (cable) frontends
-#
-CONFIG_DVB_ATMEL_AT76C651=m
-CONFIG_DVB_VES1820=m
-CONFIG_DVB_TDA10021=m
-CONFIG_DVB_STV0297=m
-
-#
-# ATSC (North American/Korean Terresterial DTV) frontends
-#
-CONFIG_DVB_NXT2002=m
-CONFIG_VIDEO_SAA7146=m
-CONFIG_VIDEO_SAA7146_VV=m
-CONFIG_VIDEO_VIDEOBUF=m
-CONFIG_VIDEO_TUNER=m
-CONFIG_VIDEO_BUF=m
-CONFIG_VIDEO_BTCX=m
-CONFIG_VIDEO_IR=m
-CONFIG_VIDEO_TVEEPROM=m
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+CONFIG_LOGO_SUN_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -1563,7 +876,6 @@
 CONFIG_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
-CONFIG_SND_HWDEP=m
 CONFIG_SND_RAWMIDI=m
 CONFIG_SND_SEQUENCER=m
 CONFIG_SND_SEQ_DUMMY=m
@@ -1571,8 +883,9 @@
 CONFIG_SND_MIXER_OSS=m
 CONFIG_SND_PCM_OSS=m
 CONFIG_SND_SEQUENCER_OSS=y
-CONFIG_SND_BIT32_EMUL=m
 # CONFIG_SND_RTCTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
 
@@ -1580,59 +893,58 @@
 # Generic devices
 #
 CONFIG_SND_MPU401_UART=m
-CONFIG_SND_OPL3_LIB=m
-CONFIG_SND_VX_LIB=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
 CONFIG_SND_DUMMY=m
 CONFIG_SND_VIRMIDI=m
-# CONFIG_SND_MTPAV is not set
+CONFIG_SND_MTPAV=m
 # CONFIG_SND_SERIAL_U16550 is not set
 # CONFIG_SND_MPU401 is not set
 
 #
 # PCI devices
 #
-CONFIG_SND_AC97_CODEC=m
+# CONFIG_SND_AD1889 is not set
 CONFIG_SND_ALI5451=m
-CONFIG_SND_ATIIXP=m
-CONFIG_SND_ATIIXP_MODEM=m
-CONFIG_SND_AU8810=m
-CONFIG_SND_AU8820=m
-CONFIG_SND_AU8830=m
-CONFIG_SND_AZT3328=m
-CONFIG_SND_BT87X=m
-# CONFIG_SND_BT87X_OVERCLOCK is not set
-CONFIG_SND_CS46XX=m
-# CONFIG_SND_CS46XX_NEW_DSP is not set
-CONFIG_SND_CS4281=m
-CONFIG_SND_EMU10K1=m
-CONFIG_SND_EMU10K1X=m
-CONFIG_SND_CA0106=m
-CONFIG_SND_KORG1212=m
-CONFIG_SND_MIXART=m
-CONFIG_SND_NM256=m
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_FM801 is not set
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
 # CONFIG_SND_RME32 is not set
 # CONFIG_SND_RME96 is not set
 # CONFIG_SND_RME9652 is not set
-# CONFIG_SND_HDSP is not set
-CONFIG_SND_TRIDENT=m
-CONFIG_SND_YMFPCI=m
-CONFIG_SND_ALS4000=m
-CONFIG_SND_CMIPCI=m
-CONFIG_SND_ENS1370=m
-CONFIG_SND_ENS1371=m
-CONFIG_SND_ES1938=m
-CONFIG_SND_ES1968=m
-CONFIG_SND_MAESTRO3=m
-CONFIG_SND_FM801=m
-CONFIG_SND_FM801_TEA575X=m
-CONFIG_SND_ICE1712=m
-# CONFIG_SND_ICE1724 is not set
-CONFIG_SND_INTEL8X0=m
-CONFIG_SND_INTEL8X0M=m
-CONFIG_SND_SONICVIBES=m
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
 # CONFIG_SND_VIA82XX is not set
-CONFIG_SND_VIA82XX_MODEM=m
-CONFIG_SND_VX222=m
+# CONFIG_SND_VIA82XX_MODEM is not set
+# CONFIG_SND_VX222 is not set
+# CONFIG_SND_YMFPCI is not set
 
 #
 # USB devices
@@ -1642,12 +954,20 @@
 #
 # ALSA Sparc devices
 #
-CONFIG_SND_SUN_AMD7930=m
+# CONFIG_SND_SUN_AMD7930 is not set
 CONFIG_SND_SUN_CS4231=m
+# CONFIG_SND_SUN_DBRI is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
 
 #
 # USB support
 #
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -1658,8 +978,6 @@
 # CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
 
 #
 # USB Host Controller Drivers
@@ -1667,36 +985,29 @@
 CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_UHCI_HCD=m
-CONFIG_USB_SL811_HCD=m
+# CONFIG_USB_SL811_HCD is not set
 
 #
 # USB Device Class drivers
 #
-# CONFIG_USB_AUDIO is not set
+# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
 
 #
-# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
-# CONFIG_USB_MIDI is not set
-CONFIG_USB_ACM=m
-CONFIG_USB_PRINTER=m
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# may also be needed; see USB_STORAGE Help for more information
 #
-CONFIG_USB_STORAGE=m
-# CONFIG_USB_STORAGE_DEBUG is not set
-CONFIG_USB_STORAGE_RW_DETECT=y
-# CONFIG_USB_STORAGE_DATAFAB is not set
-CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_ISD200=y
-CONFIG_USB_STORAGE_DPCM=y
-CONFIG_USB_STORAGE_HP8200e=y
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_LIBUSUAL is not set
 
 #
 # USB Input Devices
@@ -1706,135 +1017,75 @@
 # CONFIG_HID_FF is not set
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
-CONFIG_USB_WACOM=m
-CONFIG_USB_KBTAB=m
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
-CONFIG_USB_MTOUCH=m
-CONFIG_USB_EGALAX=m
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
 # CONFIG_USB_XPAD is not set
-CONFIG_USB_ATI_REMOTE=m
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
 
 #
 # USB Imaging devices
 #
-CONFIG_USB_MDC800=m
-CONFIG_USB_MICROTEK=m
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
 
 #
 # USB Multimedia devices
 #
 # CONFIG_USB_DABUSB is not set
-# CONFIG_USB_VICAM is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_KONICAWC is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_SE401 is not set
-CONFIG_USB_SN9C102=m
-# CONFIG_USB_STV680 is not set
-CONFIG_USB_W9968CF=m
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
 
 #
 # USB Network Adapters
 #
-CONFIG_USB_CATC=m
-CONFIG_USB_KAWETH=m
-CONFIG_USB_PEGASUS=m
-CONFIG_USB_RTL8150=m
-CONFIG_USB_USBNET=m
-
-#
-# USB Host-to-Host Cables
-#
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_BELKIN=y
-CONFIG_USB_GENESYS=y
-CONFIG_USB_NET1080=y
-CONFIG_USB_PL2301=y
-CONFIG_USB_KC2190=y
-
-#
-# Intelligent USB Devices/Gadgets
-#
-CONFIG_USB_ARMLINUX=y
-CONFIG_USB_EPSON2888=y
-CONFIG_USB_ZAURUS=y
-CONFIG_USB_CDCETHER=y
-
-#
-# USB Network Adapters
-#
-CONFIG_USB_AX8817X=y
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_MON is not set
 
 #
 # USB port drivers
 #
-CONFIG_USB_USS720=m
 
 #
 # USB Serial Converter support
 #
-CONFIG_USB_SERIAL=m
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_BELKIN=m
-CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
-CONFIG_USB_SERIAL_CYPRESS_M8=m
-CONFIG_USB_SERIAL_EMPEG=m
-CONFIG_USB_SERIAL_FTDI_SIO=m
-# CONFIG_USB_SERIAL_VISOR is not set
-CONFIG_USB_SERIAL_IPAQ=m
-# CONFIG_USB_SERIAL_IR is not set
-CONFIG_USB_SERIAL_EDGEPORT=m
-# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
-CONFIG_USB_SERIAL_GARMIN=m
-CONFIG_USB_SERIAL_IPW=m
-CONFIG_USB_SERIAL_KEYSPAN_PDA=m
-CONFIG_USB_SERIAL_KEYSPAN=m
-# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set
-CONFIG_USB_SERIAL_KLSI=m
-# CONFIG_USB_SERIAL_KOBIL_SCT is not set
-CONFIG_USB_SERIAL_MCT_U232=m
-CONFIG_USB_SERIAL_PL2303=m
-# CONFIG_USB_SERIAL_SAFE is not set
-CONFIG_USB_SERIAL_TI=m
-CONFIG_USB_SERIAL_CYBERJACK=m
-CONFIG_USB_SERIAL_XIRCOM=m
-CONFIG_USB_SERIAL_OMNINET=m
-CONFIG_USB_EZUSB=y
+# CONFIG_USB_SERIAL is not set
 
 #
 # USB Miscellaneous drivers
 #
-CONFIG_USB_EMI62=m
-CONFIG_USB_EMI26=m
-CONFIG_USB_AUERSWALD=m
-CONFIG_USB_RIO500=m
-CONFIG_USB_LEGOTOWER=m
-CONFIG_USB_LCD=m
-CONFIG_USB_LED=m
-CONFIG_USB_CYTHERM=m
-CONFIG_USB_PHIDGETKIT=m
-CONFIG_USB_PHIDGETSERVO=m
-CONFIG_USB_IDMOUSE=m
-CONFIG_USB_TEST=m
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TEST is not set
 
 #
-# USB ATM/DSL drivers
+# USB DSL modem support
 #
-CONFIG_USB_ATM=m
-CONFIG_USB_SPEEDTOUCH=m
 
 #
 # USB Gadget Support
@@ -1842,50 +1093,185 @@
 # CONFIG_USB_GADGET is not set
 
 #
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
 # InfiniBand support
 #
-CONFIG_INFINIBAND=m
-CONFIG_INFINIBAND_MTHCA=m
-# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
-CONFIG_INFINIBAND_IPOIB=m
-# CONFIG_INFINIBAND_IPOIB_DEBUG is not set
+# CONFIG_INFINIBAND is not set
 
 #
-# Watchdog Cards
+# SN Devices
 #
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
 
 #
-# Watchdog Device Drivers
+# Misc Linux/SPARC drivers
 #
-CONFIG_SOFT_WATCHDOG=m
-CONFIG_WATCHDOG_CP1XXX=m
-CONFIG_WATCHDOG_RIO=m
+CONFIG_SUN_OPENPROMIO=m
+CONFIG_SUN_MOSTEK_RTC=y
+# CONFIG_OBP_FLASH is not set
+# CONFIG_SUN_BPP is not set
+# CONFIG_BBC_I2C is not set
+# CONFIG_ENVCTRL is not set
+# CONFIG_DISPLAY7SEG is not set
 
 #
-# PCI-based Watchdog Cards
+# Fibre Channel support
 #
-CONFIG_PCIPCWATCHDOG=m
-CONFIG_WDTPCI=m
-CONFIG_WDT_501_PCI=y
+# CONFIG_FC4 is not set
 
 #
-# USB-based Watchdog Cards
+# File systems
 #
-CONFIG_USBPCWATCHDOG=m
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
-# Profiling support
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_SUN_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Instrumentation Support
 #
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
 
 #
 # Kernel hacking
 #
+CONFIG_PRINTK_TIME=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_DETECT_SOFTLOCKUP=y
 CONFIG_SCHEDSTATS=y
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -1894,12 +1280,13 @@
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-CONFIG_KPROBES=y
 # CONFIG_DEBUG_DCFLUSH is not set
 # CONFIG_STACK_DEBUG is not set
 # CONFIG_DEBUG_BOOTMEM is not set
-CONFIG_HAVE_DEC_LOCK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 
 #
 # Security options
@@ -1945,6 +1332,7 @@
 # Library routines
 #
 CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
 CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index 11a8484..7100029 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -1657,13 +1657,10 @@
 	/* Check if force_successful_syscall_return()
 	 * was invoked.
 	 */
-	ldub		[%curptr + TI_SYS_NOERROR], %l0
-	brz,pt		%l0, 1f
-	 nop
-	ba,pt		%xcc, 80f
+	ldub            [%curptr + TI_SYS_NOERROR], %l2
+	brnz,a,pn       %l2, 80f
 	 stb		%g0, [%curptr + TI_SYS_NOERROR]
 
-1:
 	cmp		%o0, -ERESTART_RESTARTBLOCK
 	bgeu,pn		%xcc, 1f
 	 andcc		%l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
index 9e8362e..30bcaf5 100644
--- a/arch/sparc64/kernel/power.c
+++ b/arch/sparc64/kernel/power.c
@@ -14,6 +14,7 @@
 #include <linux/signal.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/pm.h>
 
 #include <asm/system.h>
 #include <asm/ebus.h>
@@ -70,6 +71,9 @@
 	machine_halt();
 }
 
+void (*pm_power_off)(void) = machine_power_off;
+EXPORT_SYMBOL(pm_power_off);
+
 #ifdef CONFIG_PCI
 static int powerd(void *__unused)
 {
diff --git a/arch/x86_64/crypto/aes.c b/arch/x86_64/crypto/aes.c
index acfdaa2..fb1b961 100644
--- a/arch/x86_64/crypto/aes.c
+++ b/arch/x86_64/crypto/aes.c
@@ -74,8 +74,6 @@
 	return x >> (n << 3);
 }
 
-#define u32_in(x) le32_to_cpu(*(const __le32 *)(x))
-
 struct aes_ctx
 {
 	u32 key_length;
@@ -234,6 +232,7 @@
 		       u32 *flags)
 {
 	struct aes_ctx *ctx = ctx_arg;
+	const __le32 *key = (const __le32 *)in_key;
 	u32 i, j, t, u, v, w;
 
 	if (key_len != 16 && key_len != 24 && key_len != 32) {
@@ -243,10 +242,10 @@
 
 	ctx->key_length = key_len;
 
-	D_KEY[key_len + 24] = E_KEY[0] = u32_in(in_key);
-	D_KEY[key_len + 25] = E_KEY[1] = u32_in(in_key + 4);
-	D_KEY[key_len + 26] = E_KEY[2] = u32_in(in_key + 8);
-	D_KEY[key_len + 27] = E_KEY[3] = u32_in(in_key + 12);
+	D_KEY[key_len + 24] = E_KEY[0] = le32_to_cpu(key[0]);
+	D_KEY[key_len + 25] = E_KEY[1] = le32_to_cpu(key[1]);
+	D_KEY[key_len + 26] = E_KEY[2] = le32_to_cpu(key[2]);
+	D_KEY[key_len + 27] = E_KEY[3] = le32_to_cpu(key[3]);
 
 	switch (key_len) {
 	case 16:
@@ -256,17 +255,17 @@
 		break;
 
 	case 24:
-		E_KEY[4] = u32_in(in_key + 16);
-		t = E_KEY[5] = u32_in(in_key + 20);
+		E_KEY[4] = le32_to_cpu(key[4]);
+		t = E_KEY[5] = le32_to_cpu(key[5]);
 		for (i = 0; i < 8; ++i)
 			loop6 (i);
 		break;
 
 	case 32:
-		E_KEY[4] = u32_in(in_key + 16);
-		E_KEY[5] = u32_in(in_key + 20);
-		E_KEY[6] = u32_in(in_key + 24);
-		t = E_KEY[7] = u32_in(in_key + 28);
+		E_KEY[4] = le32_to_cpu(key[4]);
+		E_KEY[5] = le32_to_cpu(key[5]);
+		E_KEY[6] = le32_to_cpu(key[6]);
+		t = E_KEY[7] = le32_to_cpu(key[7]);
 		for (i = 0; i < 7; ++i)
 			loop8(i);
 		break;
@@ -290,6 +289,8 @@
 
 static struct crypto_alg aes_alg = {
 	.cra_name		=	"aes",
+	.cra_driver_name	=	"aes-x86_64",
+	.cra_priority		=	200,
 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize		=	AES_BLOCK_SIZE,
 	.cra_ctxsize		=	sizeof(struct aes_ctx),
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
index cb6e38e..937d81f 100644
--- a/arch/xtensa/kernel/time.c
+++ b/arch/xtensa/kernel/time.c
@@ -201,7 +201,7 @@
 	if ((signed long)(get_ccount() - next) > 0)
 		goto again;
 
-	/* Allow platform to do something usefull (Wdog). */
+	/* Allow platform to do something useful (Wdog). */
 
 	platform_heartbeat();
 
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 52e1d41..c442f2e 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -157,7 +157,7 @@
 
 config CRYPTO_AES
 	tristate "AES cipher algorithms"
-	depends on CRYPTO && !(X86 || UML_X86)
+	depends on CRYPTO
 	help
 	  AES cipher algorithms (FIPS-197). AES uses the Rijndael 
 	  algorithm.
diff --git a/crypto/aes.c b/crypto/aes.c
index 5df9288..0a6a5c1 100644
--- a/crypto/aes.c
+++ b/crypto/aes.c
@@ -73,9 +73,6 @@
 	return x >> (n << 3);
 }
 
-#define u32_in(x) le32_to_cpu(*(const u32 *)(x))
-#define u32_out(to, from) (*(u32 *)(to) = cpu_to_le32(from))
-
 struct aes_ctx {
 	int key_length;
 	u32 E[60];
@@ -256,6 +253,7 @@
 aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags)
 {
 	struct aes_ctx *ctx = ctx_arg;
+	const __le32 *key = (const __le32 *)in_key;
 	u32 i, t, u, v, w;
 
 	if (key_len != 16 && key_len != 24 && key_len != 32) {
@@ -265,10 +263,10 @@
 
 	ctx->key_length = key_len;
 
-	E_KEY[0] = u32_in (in_key);
-	E_KEY[1] = u32_in (in_key + 4);
-	E_KEY[2] = u32_in (in_key + 8);
-	E_KEY[3] = u32_in (in_key + 12);
+	E_KEY[0] = le32_to_cpu(key[0]);
+	E_KEY[1] = le32_to_cpu(key[1]);
+	E_KEY[2] = le32_to_cpu(key[2]);
+	E_KEY[3] = le32_to_cpu(key[3]);
 
 	switch (key_len) {
 	case 16:
@@ -278,17 +276,17 @@
 		break;
 
 	case 24:
-		E_KEY[4] = u32_in (in_key + 16);
-		t = E_KEY[5] = u32_in (in_key + 20);
+		E_KEY[4] = le32_to_cpu(key[4]);
+		t = E_KEY[5] = le32_to_cpu(key[5]);
 		for (i = 0; i < 8; ++i)
 			loop6 (i);
 		break;
 
 	case 32:
-		E_KEY[4] = u32_in (in_key + 16);
-		E_KEY[5] = u32_in (in_key + 20);
-		E_KEY[6] = u32_in (in_key + 24);
-		t = E_KEY[7] = u32_in (in_key + 28);
+		E_KEY[4] = le32_to_cpu(key[4]);
+		E_KEY[5] = le32_to_cpu(key[5]);
+		E_KEY[6] = le32_to_cpu(key[6]);
+		t = E_KEY[7] = le32_to_cpu(key[7]);
 		for (i = 0; i < 7; ++i)
 			loop8 (i);
 		break;
@@ -324,13 +322,15 @@
 static void aes_encrypt(void *ctx_arg, u8 *out, const u8 *in)
 {
 	const struct aes_ctx *ctx = ctx_arg;
+	const __le32 *src = (const __le32 *)in;
+	__le32 *dst = (__le32 *)out;
 	u32 b0[4], b1[4];
 	const u32 *kp = E_KEY + 4;
 
-	b0[0] = u32_in (in) ^ E_KEY[0];
-	b0[1] = u32_in (in + 4) ^ E_KEY[1];
-	b0[2] = u32_in (in + 8) ^ E_KEY[2];
-	b0[3] = u32_in (in + 12) ^ E_KEY[3];
+	b0[0] = le32_to_cpu(src[0]) ^ E_KEY[0];
+	b0[1] = le32_to_cpu(src[1]) ^ E_KEY[1];
+	b0[2] = le32_to_cpu(src[2]) ^ E_KEY[2];
+	b0[3] = le32_to_cpu(src[3]) ^ E_KEY[3];
 
 	if (ctx->key_length > 24) {
 		f_nround (b1, b0, kp);
@@ -353,10 +353,10 @@
 	f_nround (b1, b0, kp);
 	f_lround (b0, b1, kp);
 
-	u32_out (out, b0[0]);
-	u32_out (out + 4, b0[1]);
-	u32_out (out + 8, b0[2]);
-	u32_out (out + 12, b0[3]);
+	dst[0] = cpu_to_le32(b0[0]);
+	dst[1] = cpu_to_le32(b0[1]);
+	dst[2] = cpu_to_le32(b0[2]);
+	dst[3] = cpu_to_le32(b0[3]);
 }
 
 /* decrypt a block of text */
@@ -377,14 +377,16 @@
 static void aes_decrypt(void *ctx_arg, u8 *out, const u8 *in)
 {
 	const struct aes_ctx *ctx = ctx_arg;
+	const __le32 *src = (const __le32 *)in;
+	__le32 *dst = (__le32 *)out;
 	u32 b0[4], b1[4];
 	const int key_len = ctx->key_length;
 	const u32 *kp = D_KEY + key_len + 20;
 
-	b0[0] = u32_in (in) ^ E_KEY[key_len + 24];
-	b0[1] = u32_in (in + 4) ^ E_KEY[key_len + 25];
-	b0[2] = u32_in (in + 8) ^ E_KEY[key_len + 26];
-	b0[3] = u32_in (in + 12) ^ E_KEY[key_len + 27];
+	b0[0] = le32_to_cpu(src[0]) ^ E_KEY[key_len + 24];
+	b0[1] = le32_to_cpu(src[1]) ^ E_KEY[key_len + 25];
+	b0[2] = le32_to_cpu(src[2]) ^ E_KEY[key_len + 26];
+	b0[3] = le32_to_cpu(src[3]) ^ E_KEY[key_len + 27];
 
 	if (key_len > 24) {
 		i_nround (b1, b0, kp);
@@ -407,18 +409,21 @@
 	i_nround (b1, b0, kp);
 	i_lround (b0, b1, kp);
 
-	u32_out (out, b0[0]);
-	u32_out (out + 4, b0[1]);
-	u32_out (out + 8, b0[2]);
-	u32_out (out + 12, b0[3]);
+	dst[0] = cpu_to_le32(b0[0]);
+	dst[1] = cpu_to_le32(b0[1]);
+	dst[2] = cpu_to_le32(b0[2]);
+	dst[3] = cpu_to_le32(b0[3]);
 }
 
 
 static struct crypto_alg aes_alg = {
 	.cra_name		=	"aes",
+	.cra_driver_name	=	"aes-generic",
+	.cra_priority		=	100,
 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize		=	AES_BLOCK_SIZE,
 	.cra_ctxsize		=	sizeof(struct aes_ctx),
+	.cra_alignmask		=	3,
 	.cra_module		=	THIS_MODULE,
 	.cra_list		=	LIST_HEAD_INIT(aes_alg.cra_list),
 	.cra_u			=	{
diff --git a/crypto/anubis.c b/crypto/anubis.c
index 3925eb0..2c796bd 100644
--- a/crypto/anubis.c
+++ b/crypto/anubis.c
@@ -32,8 +32,10 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mm.h>
+#include <asm/byteorder.h>
 #include <asm/scatterlist.h>
 #include <linux/crypto.h>
+#include <linux/types.h>
 
 #define ANUBIS_MIN_KEY_SIZE	16
 #define ANUBIS_MAX_KEY_SIZE	40
@@ -461,8 +463,8 @@
 static int anubis_setkey(void *ctx_arg, const u8 *in_key,
 			 unsigned int key_len, u32 *flags)
 {
-
-	int N, R, i, pos, r;
+	const __be32 *key = (const __be32 *)in_key;
+	int N, R, i, r;
 	u32 kappa[ANUBIS_MAX_N];
 	u32 inter[ANUBIS_MAX_N];
 
@@ -483,13 +485,8 @@
 	ctx->R = R = 8 + N;
 
 	/* * map cipher key to initial key state (mu): */
-		for (i = 0, pos = 0; i < N; i++, pos += 4) {
-		kappa[i] =
-			(in_key[pos    ] << 24) ^
-			(in_key[pos + 1] << 16) ^
-			(in_key[pos + 2] <<  8) ^
-			(in_key[pos + 3]      );
-	}
+	for (i = 0; i < N; i++)
+		kappa[i] = be32_to_cpu(key[i]);
 
 	/*
 	 * generate R + 1 round keys:
@@ -578,7 +575,9 @@
 static void anubis_crypt(u32 roundKey[ANUBIS_MAX_ROUNDS + 1][4],
 		u8 *ciphertext, const u8 *plaintext, const int R)
 {
-	int i, pos, r;
+	const __be32 *src = (const __be32 *)plaintext;
+	__be32 *dst = (__be32 *)ciphertext;
+	int i, r;
 	u32 state[4];
 	u32 inter[4];
 
@@ -586,14 +585,8 @@
 	 * map plaintext block to cipher state (mu)
 	 * and add initial round key (sigma[K^0]):
 	 */
-	for (i = 0, pos = 0; i < 4; i++, pos += 4) {
-		state[i] =
-			(plaintext[pos    ] << 24) ^
-			(plaintext[pos + 1] << 16) ^
-			(plaintext[pos + 2] <<  8) ^
-			(plaintext[pos + 3]      ) ^
-			roundKey[0][i];
-	}
+	for (i = 0; i < 4; i++)
+		state[i] = be32_to_cpu(src[i]) ^ roundKey[0][i];
 
 	/*
 	 * R - 1 full rounds:
@@ -663,13 +656,8 @@
 	 * map cipher state to ciphertext block (mu^{-1}):
 	 */
 
-	for (i = 0, pos = 0; i < 4; i++, pos += 4) {
-		u32 w = inter[i];
-		ciphertext[pos    ] = (u8)(w >> 24);
-		ciphertext[pos + 1] = (u8)(w >> 16);
-		ciphertext[pos + 2] = (u8)(w >>  8);
-		ciphertext[pos + 3] = (u8)(w      );
-	}
+	for (i = 0; i < 4; i++)
+		dst[i] = cpu_to_be32(inter[i]);
 }
 
 static void anubis_encrypt(void *ctx_arg, u8 *dst, const u8 *src)
@@ -689,6 +677,7 @@
 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize		=	ANUBIS_BLOCK_SIZE,
 	.cra_ctxsize		=	sizeof (struct anubis_ctx),
+	.cra_alignmask		=	3,
 	.cra_module		=	THIS_MODULE,
 	.cra_list		=	LIST_HEAD_INIT(anubis_alg.cra_list),
 	.cra_u			=	{ .cipher = {
diff --git a/crypto/api.c b/crypto/api.c
index 40ae42e..e26156f 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -3,6 +3,7 @@
  *
  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
  * Copyright (c) 2002 David S. Miller (davem@redhat.com)
+ * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
  *
  * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
  * and Nettle, by Niels Möller.
@@ -18,9 +19,11 @@
 #include <linux/init.h>
 #include <linux/crypto.h>
 #include <linux/errno.h>
+#include <linux/kernel.h>
 #include <linux/kmod.h>
 #include <linux/rwsem.h>
 #include <linux/slab.h>
+#include <linux/string.h>
 #include "internal.h"
 
 LIST_HEAD(crypto_alg_list);
@@ -39,6 +42,7 @@
 static struct crypto_alg *crypto_alg_lookup(const char *name)
 {
 	struct crypto_alg *q, *alg = NULL;
+	int best = -1;
 
 	if (!name)
 		return NULL;
@@ -46,11 +50,23 @@
 	down_read(&crypto_alg_sem);
 	
 	list_for_each_entry(q, &crypto_alg_list, cra_list) {
-		if (!(strcmp(q->cra_name, name))) {
-			if (crypto_alg_get(q))
-				alg = q;
+		int exact, fuzzy;
+
+		exact = !strcmp(q->cra_driver_name, name);
+		fuzzy = !strcmp(q->cra_name, name);
+		if (!exact && !(fuzzy && q->cra_priority > best))
+			continue;
+
+		if (unlikely(!crypto_alg_get(q)))
+			continue;
+
+		best = q->cra_priority;
+		if (alg)
+			crypto_alg_put(alg);
+		alg = q;
+
+		if (exact)
 			break;
-		}
 	}
 	
 	up_read(&crypto_alg_sem);
@@ -207,9 +223,26 @@
 	kfree(tfm);
 }
 
+static inline int crypto_set_driver_name(struct crypto_alg *alg)
+{
+	static const char suffix[] = "-generic";
+	char *driver_name = (char *)alg->cra_driver_name;
+	int len;
+
+	if (*driver_name)
+		return 0;
+
+	len = strlcpy(driver_name, alg->cra_name, CRYPTO_MAX_ALG_NAME);
+	if (len + sizeof(suffix) > CRYPTO_MAX_ALG_NAME)
+		return -ENAMETOOLONG;
+
+	memcpy(driver_name + len, suffix, sizeof(suffix));
+	return 0;
+}
+
 int crypto_register_alg(struct crypto_alg *alg)
 {
-	int ret = 0;
+	int ret;
 	struct crypto_alg *q;
 
 	if (alg->cra_alignmask & (alg->cra_alignmask + 1))
@@ -218,13 +251,20 @@
 	if (alg->cra_alignmask & alg->cra_blocksize)
 		return -EINVAL;
 
-	if (alg->cra_blocksize > PAGE_SIZE)
+	if (alg->cra_blocksize > PAGE_SIZE / 8)
+		return -EINVAL;
+
+	if (alg->cra_priority < 0)
 		return -EINVAL;
 	
+	ret = crypto_set_driver_name(alg);
+	if (unlikely(ret))
+		return ret;
+
 	down_write(&crypto_alg_sem);
 	
 	list_for_each_entry(q, &crypto_alg_list, cra_list) {
-		if (!(strcmp(q->cra_name, alg->cra_name))) {
+		if (!strcmp(q->cra_driver_name, alg->cra_driver_name)) {
 			ret = -EEXIST;
 			goto out;
 		}
diff --git a/crypto/blowfish.c b/crypto/blowfish.c
index a8b29d5..7f710b2 100644
--- a/crypto/blowfish.c
+++ b/crypto/blowfish.c
@@ -19,8 +19,10 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mm.h>
+#include <asm/byteorder.h>
 #include <asm/scatterlist.h>
 #include <linux/crypto.h>
+#include <linux/types.h>
 
 #define BF_BLOCK_SIZE 8
 #define BF_MIN_KEY_SIZE 4
@@ -451,6 +453,7 @@
 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize		=	BF_BLOCK_SIZE,
 	.cra_ctxsize		=	sizeof(struct bf_ctx),
+	.cra_alignmask		=	3,
 	.cra_module		=	THIS_MODULE,
 	.cra_list		=	LIST_HEAD_INIT(alg.cra_list),
 	.cra_u			=	{ .cipher = {
diff --git a/crypto/cast5.c b/crypto/cast5.c
index bc42f42..8834c85 100644
--- a/crypto/cast5.c
+++ b/crypto/cast5.c
@@ -21,11 +21,13 @@
 */
 
 
+#include <asm/byteorder.h>
 #include <linux/init.h>
 #include <linux/crypto.h>
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/types.h>
 
 #define CAST5_BLOCK_SIZE 8
 #define CAST5_MIN_KEY_SIZE 5
@@ -578,6 +580,8 @@
 static void cast5_encrypt(void *ctx, u8 * outbuf, const u8 * inbuf)
 {
 	struct cast5_ctx *c = (struct cast5_ctx *) ctx;
+	const __be32 *src = (const __be32 *)inbuf;
+	__be32 *dst = (__be32 *)outbuf;
 	u32 l, r, t;
 	u32 I;			/* used by the Fx macros */
 	u32 *Km;
@@ -589,8 +593,8 @@
 	/* (L0,R0) <-- (m1...m64).  (Split the plaintext into left and
 	 * right 32-bit halves L0 = m1...m32 and R0 = m33...m64.)
 	 */
-	l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
-	r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
+	l = be32_to_cpu(src[0]);
+	r = be32_to_cpu(src[1]);
 
 	/* (16 rounds) for i from 1 to 16, compute Li and Ri as follows:
 	 *  Li = Ri-1;
@@ -634,19 +638,15 @@
 
 	/* c1...c64 <-- (R16,L16).  (Exchange final blocks L16, R16 and
 	 *  concatenate to form the ciphertext.) */
-	outbuf[0] = (r >> 24) & 0xff;
-	outbuf[1] = (r >> 16) & 0xff;
-	outbuf[2] = (r >> 8) & 0xff;
-	outbuf[3] = r & 0xff;
-	outbuf[4] = (l >> 24) & 0xff;
-	outbuf[5] = (l >> 16) & 0xff;
-	outbuf[6] = (l >> 8) & 0xff;
-	outbuf[7] = l & 0xff;
+	dst[0] = cpu_to_be32(r);
+	dst[1] = cpu_to_be32(l);
 }
 
 static void cast5_decrypt(void *ctx, u8 * outbuf, const u8 * inbuf)
 {
 	struct cast5_ctx *c = (struct cast5_ctx *) ctx;
+	const __be32 *src = (const __be32 *)inbuf;
+	__be32 *dst = (__be32 *)outbuf;
 	u32 l, r, t;
 	u32 I;
 	u32 *Km;
@@ -655,8 +655,8 @@
 	Km = c->Km;
 	Kr = c->Kr;
 
-	l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
-	r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
+	l = be32_to_cpu(src[0]);
+	r = be32_to_cpu(src[1]);
 
 	if (!(c->rr)) {
 		t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
@@ -690,14 +690,8 @@
 		t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]);
 	}
 
-	outbuf[0] = (r >> 24) & 0xff;
-	outbuf[1] = (r >> 16) & 0xff;
-	outbuf[2] = (r >> 8) & 0xff;
-	outbuf[3] = r & 0xff;
-	outbuf[4] = (l >> 24) & 0xff;
-	outbuf[5] = (l >> 16) & 0xff;
-	outbuf[6] = (l >> 8) & 0xff;
-	outbuf[7] = l & 0xff;
+	dst[0] = cpu_to_be32(r);
+	dst[1] = cpu_to_be32(l);
 }
 
 static void key_schedule(u32 * x, u32 * z, u32 * k)
@@ -782,7 +776,7 @@
 	u32 x[4];
 	u32 z[4];
 	u32 k[16];
-	u8 p_key[16];
+	__be32 p_key[4];
 	struct cast5_ctx *c = (struct cast5_ctx *) ctx;
 	
 	if (key_len < 5 || key_len > 16) {
@@ -796,12 +790,10 @@
 	memcpy(p_key, key, key_len);
 
 
-	x[0] = p_key[0] << 24 | p_key[1] << 16 | p_key[2] << 8 | p_key[3];
-	x[1] = p_key[4] << 24 | p_key[5] << 16 | p_key[6] << 8 | p_key[7];
-	x[2] =
-	    p_key[8] << 24 | p_key[9] << 16 | p_key[10] << 8 | p_key[11];
-	x[3] =
-	    p_key[12] << 24 | p_key[13] << 16 | p_key[14] << 8 | p_key[15];
+	x[0] = be32_to_cpu(p_key[0]);
+	x[1] = be32_to_cpu(p_key[1]);
+	x[2] = be32_to_cpu(p_key[2]);
+	x[3] = be32_to_cpu(p_key[3]);
 
 	key_schedule(x, z, k);
 	for (i = 0; i < 16; i++)
@@ -817,6 +809,7 @@
 	.cra_flags 	= CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize 	= CAST5_BLOCK_SIZE,
 	.cra_ctxsize 	= sizeof(struct cast5_ctx),
+	.cra_alignmask	= 3,
 	.cra_module 	= THIS_MODULE,
 	.cra_list 	= LIST_HEAD_INIT(alg.cra_list),
 	.cra_u 		= {
diff --git a/crypto/cast6.c b/crypto/cast6.c
index 3eb0810..9e28740 100644
--- a/crypto/cast6.c
+++ b/crypto/cast6.c
@@ -18,11 +18,13 @@
  */
 
 
+#include <asm/byteorder.h>
 #include <linux/init.h>
 #include <linux/crypto.h>
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/types.h>
 
 #define CAST6_BLOCK_SIZE 16
 #define CAST6_MIN_KEY_SIZE 16
@@ -384,7 +386,7 @@
 {
 	int i;
 	u32 key[8];
-	u8 p_key[32]; /* padded key */
+	__be32 p_key[8]; /* padded key */
 	struct cast6_ctx *c = (struct cast6_ctx *) ctx;
 
 	if (key_len < 16 || key_len > 32 || key_len % 4 != 0) {
@@ -395,14 +397,14 @@
 	memset (p_key, 0, 32);
 	memcpy (p_key, in_key, key_len);
 	
-	key[0] = p_key[0] << 24 | p_key[1] << 16 | p_key[2] << 8 | p_key[3];		/* A */
-	key[1] = p_key[4] << 24 | p_key[5] << 16 | p_key[6] << 8 | p_key[7];		/* B */
-	key[2] = p_key[8] << 24 | p_key[9] << 16 | p_key[10] << 8 | p_key[11];		/* C */
-	key[3] = p_key[12] << 24 | p_key[13] << 16 | p_key[14] << 8 | p_key[15];	/* D */
-	key[4] = p_key[16] << 24 | p_key[17] << 16 | p_key[18] << 8 | p_key[19];	/* E */
-	key[5] = p_key[20] << 24 | p_key[21] << 16 | p_key[22] << 8 | p_key[23];	/* F */
-	key[6] = p_key[24] << 24 | p_key[25] << 16 | p_key[26] << 8 | p_key[27];	/* G */
-	key[7] = p_key[28] << 24 | p_key[29] << 16 | p_key[30] << 8 | p_key[31];	/* H */
+	key[0] = be32_to_cpu(p_key[0]);		/* A */
+	key[1] = be32_to_cpu(p_key[1]);		/* B */
+	key[2] = be32_to_cpu(p_key[2]);		/* C */
+	key[3] = be32_to_cpu(p_key[3]);		/* D */
+	key[4] = be32_to_cpu(p_key[4]);		/* E */
+	key[5] = be32_to_cpu(p_key[5]);		/* F */
+	key[6] = be32_to_cpu(p_key[6]);		/* G */
+	key[7] = be32_to_cpu(p_key[7]);		/* H */
 	
 
 
@@ -444,14 +446,16 @@
 
 static void cast6_encrypt (void * ctx, u8 * outbuf, const u8 * inbuf) {
 	struct cast6_ctx * c = (struct cast6_ctx *)ctx;
+	const __be32 *src = (const __be32 *)inbuf;
+	__be32 *dst = (__be32 *)outbuf;
 	u32 block[4];
 	u32 * Km; 
 	u8 * Kr;
 
-	block[0] = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
-	block[1] = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
-	block[2] = inbuf[8] << 24 | inbuf[9] << 16 | inbuf[10] << 8 | inbuf[11];
-	block[3] = inbuf[12] << 24 | inbuf[13] << 16 | inbuf[14] << 8 | inbuf[15];
+	block[0] = be32_to_cpu(src[0]);
+	block[1] = be32_to_cpu(src[1]);
+	block[2] = be32_to_cpu(src[2]);
+	block[3] = be32_to_cpu(src[3]);
 
 	Km = c->Km[0]; Kr = c->Kr[0]; Q (block, Kr, Km);
 	Km = c->Km[1]; Kr = c->Kr[1]; Q (block, Kr, Km);
@@ -465,35 +469,25 @@
 	Km = c->Km[9]; Kr = c->Kr[9]; QBAR (block, Kr, Km);
 	Km = c->Km[10]; Kr = c->Kr[10]; QBAR (block, Kr, Km);
 	Km = c->Km[11]; Kr = c->Kr[11]; QBAR (block, Kr, Km);
-	
-	outbuf[0] = (block[0] >> 24) & 0xff;
-	outbuf[1] = (block[0] >> 16) & 0xff;
-	outbuf[2] = (block[0] >> 8) & 0xff;
-	outbuf[3] = block[0] & 0xff;
-	outbuf[4] = (block[1] >> 24) & 0xff;
-	outbuf[5] = (block[1] >> 16) & 0xff;
-	outbuf[6] = (block[1] >> 8) & 0xff;
-	outbuf[7] = block[1] & 0xff;
-	outbuf[8] = (block[2] >> 24) & 0xff;
-	outbuf[9] = (block[2] >> 16) & 0xff;
-	outbuf[10] = (block[2] >> 8) & 0xff;
-	outbuf[11] = block[2] & 0xff;
-	outbuf[12] = (block[3] >> 24) & 0xff;
-	outbuf[13] = (block[3] >> 16) & 0xff;
-	outbuf[14] = (block[3] >> 8) & 0xff;
-	outbuf[15] = block[3] & 0xff;	
+
+	dst[0] = cpu_to_be32(block[0]);
+	dst[1] = cpu_to_be32(block[1]);
+	dst[2] = cpu_to_be32(block[2]);
+	dst[3] = cpu_to_be32(block[3]);
 }	
 
 static void cast6_decrypt (void * ctx, u8 * outbuf, const u8 * inbuf) {
 	struct cast6_ctx * c = (struct cast6_ctx *)ctx;
+	const __be32 *src = (const __be32 *)inbuf;
+	__be32 *dst = (__be32 *)outbuf;
 	u32 block[4];
 	u32 * Km; 
 	u8 * Kr;
 
-	block[0] = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
-	block[1] = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
-	block[2] = inbuf[8] << 24 | inbuf[9] << 16 | inbuf[10] << 8 | inbuf[11];
-	block[3] = inbuf[12] << 24 | inbuf[13] << 16 | inbuf[14] << 8 | inbuf[15];
+	block[0] = be32_to_cpu(src[0]);
+	block[1] = be32_to_cpu(src[1]);
+	block[2] = be32_to_cpu(src[2]);
+	block[3] = be32_to_cpu(src[3]);
 
 	Km = c->Km[11]; Kr = c->Kr[11]; Q (block, Kr, Km);
 	Km = c->Km[10]; Kr = c->Kr[10]; Q (block, Kr, Km);
@@ -508,22 +502,10 @@
 	Km = c->Km[1]; Kr = c->Kr[1]; QBAR (block, Kr, Km);
 	Km = c->Km[0]; Kr = c->Kr[0]; QBAR (block, Kr, Km);
 	
-	outbuf[0] = (block[0] >> 24) & 0xff;
-	outbuf[1] = (block[0] >> 16) & 0xff;
-	outbuf[2] = (block[0] >> 8) & 0xff;
-	outbuf[3] = block[0] & 0xff;
-	outbuf[4] = (block[1] >> 24) & 0xff;
-	outbuf[5] = (block[1] >> 16) & 0xff;
-	outbuf[6] = (block[1] >> 8) & 0xff;
-	outbuf[7] = block[1] & 0xff;
-	outbuf[8] = (block[2] >> 24) & 0xff;
-	outbuf[9] = (block[2] >> 16) & 0xff;
-	outbuf[10] = (block[2] >> 8) & 0xff;
-	outbuf[11] = block[2] & 0xff;
-	outbuf[12] = (block[3] >> 24) & 0xff;
-	outbuf[13] = (block[3] >> 16) & 0xff;
-	outbuf[14] = (block[3] >> 8) & 0xff;
-	outbuf[15] = block[3] & 0xff;	
+	dst[0] = cpu_to_be32(block[0]);
+	dst[1] = cpu_to_be32(block[1]);
+	dst[2] = cpu_to_be32(block[2]);
+	dst[3] = cpu_to_be32(block[3]);
 }	
 
 static struct crypto_alg alg = {
@@ -531,6 +513,7 @@
 	.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize = CAST6_BLOCK_SIZE,
 	.cra_ctxsize = sizeof(struct cast6_ctx),
+	.cra_alignmask = 3,
 	.cra_module = THIS_MODULE,
 	.cra_list = LIST_HEAD_INIT(alg.cra_list),
 	.cra_u = {
diff --git a/crypto/cipher.c b/crypto/cipher.c
index dfd4bcf..65bcea0 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -212,9 +212,10 @@
 	struct crypto_tfm *tfm = desc->tfm;
 	void (*xor)(u8 *, const u8 *) = tfm->crt_u.cipher.cit_xor_block;
 	int bsize = crypto_tfm_alg_blocksize(tfm);
+	unsigned long alignmask = crypto_tfm_alg_alignmask(desc->tfm);
 
-	u8 stack[src == dst ? bsize : 0];
-	u8 *buf = stack;
+	u8 stack[src == dst ? bsize + alignmask : 0];
+	u8 *buf = (u8 *)ALIGN((unsigned long)stack, alignmask + 1);
 	u8 **dst_p = src == dst ? &buf : &dst;
 
 	void (*fn)(void *, u8 *, const u8 *) = desc->crfn;
diff --git a/crypto/crc32c.c b/crypto/crc32c.c
index 256956c..9533624 100644
--- a/crypto/crc32c.c
+++ b/crypto/crc32c.c
@@ -16,6 +16,7 @@
 #include <linux/string.h>
 #include <linux/crypto.h>
 #include <linux/crc32c.h>
+#include <linux/types.h>
 #include <asm/byteorder.h>
 
 #define CHKSUM_BLOCK_SIZE	32
diff --git a/crypto/des.c b/crypto/des.c
index a3c863d..7bb5486 100644
--- a/crypto/des.c
+++ b/crypto/des.c
@@ -12,11 +12,13 @@
  *
  */
 
+#include <asm/byteorder.h>
 #include <linux/bitops.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/crypto.h>
+#include <linux/types.h>
 
 #define DES_KEY_SIZE		8
 #define DES_EXPKEY_WORDS	32
@@ -947,6 +949,7 @@
 	.cra_blocksize		=	DES_BLOCK_SIZE,
 	.cra_ctxsize		=	sizeof(struct des_ctx),
 	.cra_module		=	THIS_MODULE,
+	.cra_alignmask		=	3,
 	.cra_list		=	LIST_HEAD_INIT(des_alg.cra_list),
 	.cra_u			=	{ .cipher = {
 	.cia_min_keysize	=	DES_KEY_SIZE,
diff --git a/crypto/internal.h b/crypto/internal.h
index 37aa652..959e602 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -2,6 +2,7 @@
  * Cryptographic API.
  *
  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
  *
  * 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
@@ -16,10 +17,15 @@
 #include <linux/highmem.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/list.h>
 #include <linux/kernel.h>
+#include <linux/rwsem.h>
 #include <linux/slab.h>
 #include <asm/kmap_types.h>
 
+extern struct list_head crypto_alg_list;
+extern struct rw_semaphore crypto_alg_sem;
+
 extern enum km_type crypto_km_types[];
 
 static inline enum km_type crypto_kmap_type(int out)
diff --git a/crypto/khazad.c b/crypto/khazad.c
index 738cb0d..807f2bf 100644
--- a/crypto/khazad.c
+++ b/crypto/khazad.c
@@ -22,8 +22,10 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mm.h>
+#include <asm/byteorder.h>
 #include <asm/scatterlist.h>
 #include <linux/crypto.h>
+#include <linux/types.h>
 
 #define KHAZAD_KEY_SIZE		16
 #define KHAZAD_BLOCK_SIZE	8
@@ -755,8 +757,8 @@
 static int khazad_setkey(void *ctx_arg, const u8 *in_key,
                        unsigned int key_len, u32 *flags)
 {
-
 	struct khazad_ctx *ctx = ctx_arg;
+	const __be64 *key = (const __be64 *)in_key;
 	int r;
 	const u64 *S = T7;
 	u64 K2, K1;
@@ -767,22 +769,8 @@
 		return -EINVAL;
 	}
 
-	K2 = ((u64)in_key[ 0] << 56) ^
-	     ((u64)in_key[ 1] << 48) ^
-	     ((u64)in_key[ 2] << 40) ^
-	     ((u64)in_key[ 3] << 32) ^
-	     ((u64)in_key[ 4] << 24) ^
-	     ((u64)in_key[ 5] << 16) ^
-	     ((u64)in_key[ 6] <<  8) ^
-	     ((u64)in_key[ 7]      );
-	K1 = ((u64)in_key[ 8] << 56) ^
-	     ((u64)in_key[ 9] << 48) ^
-	     ((u64)in_key[10] << 40) ^
-	     ((u64)in_key[11] << 32) ^
-	     ((u64)in_key[12] << 24) ^
-	     ((u64)in_key[13] << 16) ^
-	     ((u64)in_key[14] <<  8) ^
-	     ((u64)in_key[15]      );
+	K2 = be64_to_cpu(key[0]);
+	K1 = be64_to_cpu(key[1]);
 
 	/* setup the encrypt key */
 	for (r = 0; r <= KHAZAD_ROUNDS; r++) {
@@ -820,19 +808,12 @@
 static void khazad_crypt(const u64 roundKey[KHAZAD_ROUNDS + 1],
 		u8 *ciphertext, const u8 *plaintext)
 {
-
+	const __be64 *src = (const __be64 *)plaintext;
+	__be64 *dst = (__be64 *)ciphertext;
 	int r;
 	u64 state;
 
-	state = ((u64)plaintext[0] << 56) ^
-		((u64)plaintext[1] << 48) ^
-		((u64)plaintext[2] << 40) ^
-		((u64)plaintext[3] << 32) ^
-		((u64)plaintext[4] << 24) ^
-		((u64)plaintext[5] << 16) ^
-		((u64)plaintext[6] <<  8) ^
-		((u64)plaintext[7]      ) ^
-		roundKey[0];
+	state = be64_to_cpu(*src) ^ roundKey[0];
 
 	for (r = 1; r < KHAZAD_ROUNDS; r++) {
 		state = T0[(int)(state >> 56)       ] ^
@@ -856,15 +837,7 @@
 		(T7[(int)(state      ) & 0xff] & 0x00000000000000ffULL) ^
 		roundKey[KHAZAD_ROUNDS];
 
-	ciphertext[0] = (u8)(state >> 56);
-	ciphertext[1] = (u8)(state >> 48);
-	ciphertext[2] = (u8)(state >> 40);
-	ciphertext[3] = (u8)(state >> 32);
-	ciphertext[4] = (u8)(state >> 24);
-	ciphertext[5] = (u8)(state >> 16);
-	ciphertext[6] = (u8)(state >>  8);
-	ciphertext[7] = (u8)(state      );
-
+	*dst = cpu_to_be64(state);
 }
 
 static void khazad_encrypt(void *ctx_arg, u8 *dst, const u8 *src)
@@ -884,6 +857,7 @@
 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize		=	KHAZAD_BLOCK_SIZE,
 	.cra_ctxsize		=	sizeof (struct khazad_ctx),
+	.cra_alignmask		=	7,
 	.cra_module		=	THIS_MODULE,
 	.cra_list		=	LIST_HEAD_INIT(khazad_alg.cra_list),
 	.cra_u			=	{ .cipher = {
diff --git a/crypto/md4.c b/crypto/md4.c
index bef6a9e..a2d6df5 100644
--- a/crypto/md4.c
+++ b/crypto/md4.c
@@ -24,6 +24,7 @@
 #include <linux/crypto.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/types.h>
 #include <asm/byteorder.h>
 
 #define MD4_DIGEST_SIZE		16
diff --git a/crypto/md5.c b/crypto/md5.c
index 1ed45f9..7f041ae 100644
--- a/crypto/md5.c
+++ b/crypto/md5.c
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/crypto.h>
+#include <linux/types.h>
 #include <asm/byteorder.h>
 
 #define MD5_DIGEST_SIZE		16
diff --git a/crypto/michael_mic.c b/crypto/michael_mic.c
index a470bcb..4f6ab23 100644
--- a/crypto/michael_mic.c
+++ b/crypto/michael_mic.c
@@ -10,10 +10,12 @@
  * published by the Free Software Foundation.
  */
 
+#include <asm/byteorder.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/crypto.h>
+#include <linux/types.h>
 
 
 struct michael_mic_ctx {
@@ -43,21 +45,6 @@
 } while (0)
 
 
-static inline u32 get_le32(const u8 *p)
-{
-	return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
-}
-
-
-static inline void put_le32(u8 *p, u32 v)
-{
-	p[0] = v;
-	p[1] = v >> 8;
-	p[2] = v >> 16;
-	p[3] = v >> 24;
-}
-
-
 static void michael_init(void *ctx)
 {
 	struct michael_mic_ctx *mctx = ctx;
@@ -68,6 +55,7 @@
 static void michael_update(void *ctx, const u8 *data, unsigned int len)
 {
 	struct michael_mic_ctx *mctx = ctx;
+	const __le32 *src;
 
 	if (mctx->pending_len) {
 		int flen = 4 - mctx->pending_len;
@@ -81,21 +69,23 @@
 		if (mctx->pending_len < 4)
 			return;
 
-		mctx->l ^= get_le32(mctx->pending);
+		src = (const __le32 *)mctx->pending;
+		mctx->l ^= le32_to_cpup(src);
 		michael_block(mctx->l, mctx->r);
 		mctx->pending_len = 0;
 	}
 
+	src = (const __le32 *)data;
+
 	while (len >= 4) {
-		mctx->l ^= get_le32(data);
+		mctx->l ^= le32_to_cpup(src++);
 		michael_block(mctx->l, mctx->r);
-		data += 4;
 		len -= 4;
 	}
 
 	if (len > 0) {
 		mctx->pending_len = len;
-		memcpy(mctx->pending, data, len);
+		memcpy(mctx->pending, src, len);
 	}
 }
 
@@ -104,6 +94,7 @@
 {
 	struct michael_mic_ctx *mctx = ctx;
 	u8 *data = mctx->pending;
+	__le32 *dst = (__le32 *)out;
 
 	/* Last block and padding (0x5a, 4..7 x 0) */
 	switch (mctx->pending_len) {
@@ -125,8 +116,8 @@
 	/* l ^= 0; */
 	michael_block(mctx->l, mctx->r);
 
-	put_le32(out, mctx->l);
-	put_le32(out + 4, mctx->r);
+	dst[0] = cpu_to_le32(mctx->l);
+	dst[1] = cpu_to_le32(mctx->r);
 }
 
 
@@ -134,13 +125,16 @@
 			  u32 *flags)
 {
 	struct michael_mic_ctx *mctx = ctx;
+	const __le32 *data = (const __le32 *)key;
+
 	if (keylen != 8) {
 		if (flags)
 			*flags = CRYPTO_TFM_RES_BAD_KEY_LEN;
 		return -EINVAL;
 	}
-	mctx->l = get_le32(key);
-	mctx->r = get_le32(key + 4);
+
+	mctx->l = le32_to_cpu(data[0]);
+	mctx->r = le32_to_cpu(data[1]);
 	return 0;
 }
 
diff --git a/crypto/proc.c b/crypto/proc.c
index 630ba91..c0a5dd7 100644
--- a/crypto/proc.c
+++ b/crypto/proc.c
@@ -4,6 +4,7 @@
  * Procfs information.
  *
  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
  *
  * 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
@@ -18,9 +19,6 @@
 #include <linux/seq_file.h>
 #include "internal.h"
 
-extern struct list_head crypto_alg_list;
-extern struct rw_semaphore crypto_alg_sem;
-
 static void *c_start(struct seq_file *m, loff_t *pos)
 {
 	struct list_head *v;
@@ -53,7 +51,9 @@
 	struct crypto_alg *alg = (struct crypto_alg *)p;
 	
 	seq_printf(m, "name         : %s\n", alg->cra_name);
+	seq_printf(m, "driver       : %s\n", alg->cra_driver_name);
 	seq_printf(m, "module       : %s\n", module_name(alg->cra_module));
+	seq_printf(m, "priority     : %d\n", alg->cra_priority);
 	
 	switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
 	case CRYPTO_ALG_TYPE_CIPHER:
diff --git a/crypto/serpent.c b/crypto/serpent.c
index 3cf2c50..52ad1a4 100644
--- a/crypto/serpent.c
+++ b/crypto/serpent.c
@@ -20,6 +20,7 @@
 #include <linux/errno.h>
 #include <asm/byteorder.h>
 #include <linux/crypto.h>
+#include <linux/types.h>
 
 /* Key is padded to the maximum of 256 bits before round key generation.
  * Any key length <= 256 bits (32 bytes) is allowed by the algorithm.
@@ -552,6 +553,7 @@
 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize		=	SERPENT_BLOCK_SIZE,
 	.cra_ctxsize		=	sizeof(struct serpent_ctx),
+	.cra_alignmask		=	3,
 	.cra_module		=	THIS_MODULE,
 	.cra_list		=	LIST_HEAD_INIT(serpent_alg.cra_list),
 	.cra_u			=	{ .cipher = {
diff --git a/crypto/sha1.c b/crypto/sha1.c
index 4016f3b..21571ed3 100644
--- a/crypto/sha1.c
+++ b/crypto/sha1.c
@@ -21,6 +21,7 @@
 #include <linux/mm.h>
 #include <linux/crypto.h>
 #include <linux/cryptohash.h>
+#include <linux/types.h>
 #include <asm/scatterlist.h>
 #include <asm/byteorder.h>
 
@@ -48,23 +49,33 @@
 static void sha1_update(void *ctx, const u8 *data, unsigned int len)
 {
 	struct sha1_ctx *sctx = ctx;
-	unsigned int i, j;
-	u32 temp[SHA_WORKSPACE_WORDS];
+	unsigned int partial, done;
+	const u8 *src;
 
-	j = (sctx->count >> 3) & 0x3f;
-	sctx->count += len << 3;
+	partial = sctx->count & 0x3f;
+	sctx->count += len;
+	done = 0;
+	src = data;
 
-	if ((j + len) > 63) {
-		memcpy(&sctx->buffer[j], data, (i = 64-j));
-		sha_transform(sctx->state, sctx->buffer, temp);
-		for ( ; i + 63 < len; i += 64) {
-			sha_transform(sctx->state, &data[i], temp);
+	if ((partial + len) > 63) {
+		u32 temp[SHA_WORKSPACE_WORDS];
+
+		if (partial) {
+			done = -partial;
+			memcpy(sctx->buffer + partial, data, done + 64);
+			src = sctx->buffer;
 		}
-		j = 0;
+
+		do {
+			sha_transform(sctx->state, src, temp);
+			done += 64;
+			src = data + done;
+		} while (done + 63 < len);
+
+		memset(temp, 0, sizeof(temp));
+		partial = 0;
 	}
-	else i = 0;
-	memset(temp, 0, sizeof(temp));
-	memcpy(&sctx->buffer[j], &data[i], len - i);
+	memcpy(sctx->buffer + partial, src, len - done);
 }
 
 
@@ -72,37 +83,24 @@
 static void sha1_final(void* ctx, u8 *out)
 {
 	struct sha1_ctx *sctx = ctx;
-	u32 i, j, index, padlen;
-	u64 t;
-	u8 bits[8] = { 0, };
+	__be32 *dst = (__be32 *)out;
+	u32 i, index, padlen;
+	__be64 bits;
 	static const u8 padding[64] = { 0x80, };
 
-	t = sctx->count;
-	bits[7] = 0xff & t; t>>=8;
-	bits[6] = 0xff & t; t>>=8;
-	bits[5] = 0xff & t; t>>=8;
-	bits[4] = 0xff & t; t>>=8;
-	bits[3] = 0xff & t; t>>=8;
-	bits[2] = 0xff & t; t>>=8;
-	bits[1] = 0xff & t; t>>=8;
-	bits[0] = 0xff & t;
+	bits = cpu_to_be64(sctx->count << 3);
 
 	/* Pad out to 56 mod 64 */
-	index = (sctx->count >> 3) & 0x3f;
+	index = sctx->count & 0x3f;
 	padlen = (index < 56) ? (56 - index) : ((64+56) - index);
 	sha1_update(sctx, padding, padlen);
 
 	/* Append length */
-	sha1_update(sctx, bits, sizeof bits); 
+	sha1_update(sctx, (const u8 *)&bits, sizeof(bits));
 
 	/* Store state in digest */
-	for (i = j = 0; i < 5; i++, j += 4) {
-		u32 t2 = sctx->state[i];
-		out[j+3] = t2 & 0xff; t2>>=8;
-		out[j+2] = t2 & 0xff; t2>>=8;
-		out[j+1] = t2 & 0xff; t2>>=8;
-		out[j  ] = t2 & 0xff;
-	}
+	for (i = 0; i < 5; i++)
+		dst[i] = cpu_to_be32(sctx->state[i]);
 
 	/* Wipe context */
 	memset(sctx, 0, sizeof *sctx);
diff --git a/crypto/sha256.c b/crypto/sha256.c
index c78da50..9d5ef67 100644
--- a/crypto/sha256.c
+++ b/crypto/sha256.c
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/crypto.h>
+#include <linux/types.h>
 #include <asm/scatterlist.h>
 #include <asm/byteorder.h>
 
@@ -279,22 +280,15 @@
 static void sha256_final(void* ctx, u8 *out)
 {
 	struct sha256_ctx *sctx = ctx;
-	u8 bits[8];
-	unsigned int index, pad_len, t;
-	int i, j;
+	__be32 *dst = (__be32 *)out;
+	__be32 bits[2];
+	unsigned int index, pad_len;
+	int i;
 	static const u8 padding[64] = { 0x80, };
 
 	/* Save number of bits */
-	t = sctx->count[0];
-	bits[7] = t; t >>= 8;
-	bits[6] = t; t >>= 8;
-	bits[5] = t; t >>= 8;
-	bits[4] = t;
-	t = sctx->count[1];
-	bits[3] = t; t >>= 8;
-	bits[2] = t; t >>= 8;
-	bits[1] = t; t >>= 8;
-	bits[0] = t;
+	bits[1] = cpu_to_be32(sctx->count[0]);
+	bits[0] = cpu_to_be32(sctx->count[1]);
 
 	/* Pad out to 56 mod 64. */
 	index = (sctx->count[0] >> 3) & 0x3f;
@@ -302,16 +296,11 @@
 	sha256_update(sctx, padding, pad_len);
 
 	/* Append length (before padding) */
-	sha256_update(sctx, bits, 8);
+	sha256_update(sctx, (const u8 *)bits, sizeof(bits));
 
 	/* Store state in digest */
-	for (i = j = 0; i < 8; i++, j += 4) {
-		t = sctx->state[i];
-		out[j+3] = t; t >>= 8;
-		out[j+2] = t; t >>= 8;
-		out[j+1] = t; t >>= 8;
-		out[j  ] = t;
-	}
+	for (i = 0; i < 8; i++)
+		dst[i] = cpu_to_be32(sctx->state[i]);
 
 	/* Zeroize sensitive information. */
 	memset(sctx, 0, sizeof(*sctx));
diff --git a/crypto/sha512.c b/crypto/sha512.c
index c663438..3e6e939 100644
--- a/crypto/sha512.c
+++ b/crypto/sha512.c
@@ -17,6 +17,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/crypto.h>
+#include <linux/types.h>
 
 #include <asm/scatterlist.h>
 #include <asm/byteorder.h>
@@ -235,39 +236,17 @@
 sha512_final(void *ctx, u8 *hash)
 {
         struct sha512_ctx *sctx = ctx;
-	
         static u8 padding[128] = { 0x80, };
-
-        u32 t;
-	u64 t2;
-        u8 bits[128];
+	__be64 *dst = (__be64 *)hash;
+	__be32 bits[4];
 	unsigned int index, pad_len;
-	int i, j;
-
-        index = pad_len = t = i = j = 0;
-        t2 = 0;
+	int i;
 
 	/* Save number of bits */
-	t = sctx->count[0];
-	bits[15] = t; t>>=8;
-	bits[14] = t; t>>=8;
-	bits[13] = t; t>>=8;
-	bits[12] = t; 
-	t = sctx->count[1];
-	bits[11] = t; t>>=8;
-	bits[10] = t; t>>=8;
-	bits[9 ] = t; t>>=8;
-	bits[8 ] = t; 
-	t = sctx->count[2];
-	bits[7 ] = t; t>>=8;
-	bits[6 ] = t; t>>=8;
-	bits[5 ] = t; t>>=8;
-	bits[4 ] = t; 
-	t = sctx->count[3];
-	bits[3 ] = t; t>>=8;
-	bits[2 ] = t; t>>=8;
-	bits[1 ] = t; t>>=8;
-	bits[0 ] = t; 
+	bits[3] = cpu_to_be32(sctx->count[0]);
+	bits[2] = cpu_to_be32(sctx->count[1]);
+	bits[1] = cpu_to_be32(sctx->count[2]);
+	bits[0] = cpu_to_be32(sctx->count[3]);
 
 	/* Pad out to 112 mod 128. */
 	index = (sctx->count[0] >> 3) & 0x7f;
@@ -275,21 +254,12 @@
 	sha512_update(sctx, padding, pad_len);
 
 	/* Append length (before padding) */
-	sha512_update(sctx, bits, 16);
+	sha512_update(sctx, (const u8 *)bits, sizeof(bits));
 
 	/* Store state in digest */
-	for (i = j = 0; i < 8; i++, j += 8) {
-		t2 = sctx->state[i];
-		hash[j+7] = (char)t2 & 0xff; t2>>=8;
-		hash[j+6] = (char)t2 & 0xff; t2>>=8;
-		hash[j+5] = (char)t2 & 0xff; t2>>=8;
-		hash[j+4] = (char)t2 & 0xff; t2>>=8;
-		hash[j+3] = (char)t2 & 0xff; t2>>=8;
-		hash[j+2] = (char)t2 & 0xff; t2>>=8;
-		hash[j+1] = (char)t2 & 0xff; t2>>=8;
-		hash[j  ] = (char)t2 & 0xff;
-	}
-	
+	for (i = 0; i < 8; i++)
+		dst[i] = cpu_to_be64(sctx->state[i]);
+
 	/* Zeroize sensitive information. */
 	memset(sctx, 0, sizeof(struct sha512_ctx));
 }
diff --git a/crypto/tea.c b/crypto/tea.c
index 5924efd..a6a02b3 100644
--- a/crypto/tea.c
+++ b/crypto/tea.c
@@ -22,8 +22,10 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mm.h>
+#include <asm/byteorder.h>
 #include <asm/scatterlist.h>
 #include <linux/crypto.h>
+#include <linux/types.h>
 
 #define TEA_KEY_SIZE		16
 #define TEA_BLOCK_SIZE		8
@@ -35,9 +37,6 @@
 #define XTEA_ROUNDS		32
 #define XTEA_DELTA		0x9e3779b9
 
-#define u32_in(x) le32_to_cpu(*(const __le32 *)(x))
-#define u32_out(to, from) (*(__le32 *)(to) = cpu_to_le32(from))
-
 struct tea_ctx {
 	u32 KEY[4];
 };
@@ -49,8 +48,8 @@
 static int tea_setkey(void *ctx_arg, const u8 *in_key,
                        unsigned int key_len, u32 *flags)
 { 
-
 	struct tea_ctx *ctx = ctx_arg;
+	const __le32 *key = (const __le32 *)in_key;
 	
 	if (key_len != 16)
 	{
@@ -58,10 +57,10 @@
 		return -EINVAL;
 	}
 
-	ctx->KEY[0] = u32_in (in_key);
-	ctx->KEY[1] = u32_in (in_key + 4);
-	ctx->KEY[2] = u32_in (in_key + 8);
-	ctx->KEY[3] = u32_in (in_key + 12);
+	ctx->KEY[0] = le32_to_cpu(key[0]);
+	ctx->KEY[1] = le32_to_cpu(key[1]);
+	ctx->KEY[2] = le32_to_cpu(key[2]);
+	ctx->KEY[3] = le32_to_cpu(key[3]);
 
 	return 0; 
 
@@ -73,9 +72,11 @@
 	u32 k0, k1, k2, k3;
 
 	struct tea_ctx *ctx = ctx_arg;
+	const __le32 *in = (const __le32 *)src;
+	__le32 *out = (__le32 *)dst;
 
-	y = u32_in (src);
-	z = u32_in (src + 4);
+	y = le32_to_cpu(in[0]);
+	z = le32_to_cpu(in[1]);
 
 	k0 = ctx->KEY[0];
 	k1 = ctx->KEY[1];
@@ -90,19 +91,20 @@
 		z += ((y << 4) + k2) ^ (y + sum) ^ ((y >> 5) + k3);
 	}
 	
-	u32_out (dst, y);
-	u32_out (dst + 4, z);
+	out[0] = cpu_to_le32(y);
+	out[1] = cpu_to_le32(z);
 }
 
 static void tea_decrypt(void *ctx_arg, u8 *dst, const u8 *src)
 { 
 	u32 y, z, n, sum;
 	u32 k0, k1, k2, k3;
-
 	struct tea_ctx *ctx = ctx_arg;
+	const __le32 *in = (const __le32 *)src;
+	__le32 *out = (__le32 *)dst;
 
-	y = u32_in (src);
-	z = u32_in (src + 4);
+	y = le32_to_cpu(in[0]);
+	z = le32_to_cpu(in[1]);
 
 	k0 = ctx->KEY[0];
 	k1 = ctx->KEY[1];
@@ -119,16 +121,15 @@
 		sum -= TEA_DELTA;
 	}
 	
-	u32_out (dst, y);
-	u32_out (dst + 4, z);
-
+	out[0] = cpu_to_le32(y);
+	out[1] = cpu_to_le32(z);
 }
 
 static int xtea_setkey(void *ctx_arg, const u8 *in_key,
                        unsigned int key_len, u32 *flags)
 { 
-
 	struct xtea_ctx *ctx = ctx_arg;
+	const __le32 *key = (const __le32 *)in_key;
 	
 	if (key_len != 16)
 	{
@@ -136,10 +137,10 @@
 		return -EINVAL;
 	}
 
-	ctx->KEY[0] = u32_in (in_key);
-	ctx->KEY[1] = u32_in (in_key + 4);
-	ctx->KEY[2] = u32_in (in_key + 8);
-	ctx->KEY[3] = u32_in (in_key + 12);
+	ctx->KEY[0] = le32_to_cpu(key[0]);
+	ctx->KEY[1] = le32_to_cpu(key[1]);
+	ctx->KEY[2] = le32_to_cpu(key[2]);
+	ctx->KEY[3] = le32_to_cpu(key[3]);
 
 	return 0; 
 
@@ -147,14 +148,15 @@
 
 static void xtea_encrypt(void *ctx_arg, u8 *dst, const u8 *src)
 { 
-
 	u32 y, z, sum = 0;
 	u32 limit = XTEA_DELTA * XTEA_ROUNDS;
 
 	struct xtea_ctx *ctx = ctx_arg;
+	const __le32 *in = (const __le32 *)src;
+	__le32 *out = (__le32 *)dst;
 
-	y = u32_in (src);
-	z = u32_in (src + 4);
+	y = le32_to_cpu(in[0]);
+	z = le32_to_cpu(in[1]);
 
 	while (sum != limit) {
 		y += ((z << 4 ^ z >> 5) + z) ^ (sum + ctx->KEY[sum&3]); 
@@ -162,19 +164,19 @@
 		z += ((y << 4 ^ y >> 5) + y) ^ (sum + ctx->KEY[sum>>11 &3]); 
 	}
 	
-	u32_out (dst, y);
-	u32_out (dst + 4, z);
-
+	out[0] = cpu_to_le32(y);
+	out[1] = cpu_to_le32(z);
 }
 
 static void xtea_decrypt(void *ctx_arg, u8 *dst, const u8 *src)
 { 
-
 	u32 y, z, sum;
 	struct tea_ctx *ctx = ctx_arg;
+	const __le32 *in = (const __le32 *)src;
+	__le32 *out = (__le32 *)dst;
 
-	y = u32_in (src);
-	z = u32_in (src + 4);
+	y = le32_to_cpu(in[0]);
+	z = le32_to_cpu(in[1]);
 
 	sum = XTEA_DELTA * XTEA_ROUNDS;
 
@@ -184,22 +186,22 @@
 		y -= ((z << 4 ^ z >> 5) + z) ^ (sum + ctx->KEY[sum & 3]);
 	}
 	
-	u32_out (dst, y);
-	u32_out (dst + 4, z);
-
+	out[0] = cpu_to_le32(y);
+	out[1] = cpu_to_le32(z);
 }
 
 
 static void xeta_encrypt(void *ctx_arg, u8 *dst, const u8 *src)
 { 
-
 	u32 y, z, sum = 0;
 	u32 limit = XTEA_DELTA * XTEA_ROUNDS;
 
 	struct xtea_ctx *ctx = ctx_arg;
+	const __le32 *in = (const __le32 *)src;
+	__le32 *out = (__le32 *)dst;
 
-	y = u32_in (src);
-	z = u32_in (src + 4);
+	y = le32_to_cpu(in[0]);
+	z = le32_to_cpu(in[1]);
 
 	while (sum != limit) {
 		y += (z << 4 ^ z >> 5) + (z ^ sum) + ctx->KEY[sum&3];
@@ -207,19 +209,19 @@
 		z += (y << 4 ^ y >> 5) + (y ^ sum) + ctx->KEY[sum>>11 &3];
 	}
 	
-	u32_out (dst, y);
-	u32_out (dst + 4, z);
-
+	out[0] = cpu_to_le32(y);
+	out[1] = cpu_to_le32(z);
 }
 
 static void xeta_decrypt(void *ctx_arg, u8 *dst, const u8 *src)
 { 
-
 	u32 y, z, sum;
 	struct tea_ctx *ctx = ctx_arg;
+	const __le32 *in = (const __le32 *)src;
+	__le32 *out = (__le32 *)dst;
 
-	y = u32_in (src);
-	z = u32_in (src + 4);
+	y = le32_to_cpu(in[0]);
+	z = le32_to_cpu(in[1]);
 
 	sum = XTEA_DELTA * XTEA_ROUNDS;
 
@@ -229,9 +231,8 @@
 		y -= (z << 4 ^ z >> 5) + (z ^ sum) + ctx->KEY[sum & 3];
 	}
 	
-	u32_out (dst, y);
-	u32_out (dst + 4, z);
-
+	out[0] = cpu_to_le32(y);
+	out[1] = cpu_to_le32(z);
 }
 
 static struct crypto_alg tea_alg = {
@@ -239,6 +240,7 @@
 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize		=	TEA_BLOCK_SIZE,
 	.cra_ctxsize		=	sizeof (struct tea_ctx),
+	.cra_alignmask		=	3,
 	.cra_module		=	THIS_MODULE,
 	.cra_list		=	LIST_HEAD_INIT(tea_alg.cra_list),
 	.cra_u			=	{ .cipher = {
@@ -254,6 +256,7 @@
 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize		=	XTEA_BLOCK_SIZE,
 	.cra_ctxsize		=	sizeof (struct xtea_ctx),
+	.cra_alignmask		=	3,
 	.cra_module		=	THIS_MODULE,
 	.cra_list		=	LIST_HEAD_INIT(xtea_alg.cra_list),
 	.cra_u			=	{ .cipher = {
@@ -269,6 +272,7 @@
 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize		=	XTEA_BLOCK_SIZE,
 	.cra_ctxsize		=	sizeof (struct xtea_ctx),
+	.cra_alignmask		=	3,
 	.cra_module		=	THIS_MODULE,
 	.cra_list		=	LIST_HEAD_INIT(xtea_alg.cra_list),
 	.cra_u			=	{ .cipher = {
diff --git a/crypto/tgr192.c b/crypto/tgr192.c
index f0a45cf..2d8e44f 100644
--- a/crypto/tgr192.c
+++ b/crypto/tgr192.c
@@ -24,8 +24,10 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mm.h>
+#include <asm/byteorder.h>
 #include <asm/scatterlist.h>
 #include <linux/crypto.h>
+#include <linux/types.h>
 
 #define TGR192_DIGEST_SIZE 24
 #define TGR160_DIGEST_SIZE 20
@@ -467,18 +469,10 @@
 	u64 a, b, c, aa, bb, cc;
 	u64 x[8];
 	int i;
-	const u8 *ptr = data;
+	const __le64 *ptr = (const __le64 *)data;
 
-	for (i = 0; i < 8; i++, ptr += 8) {
-		x[i] = (((u64)ptr[7] ) << 56) ^
-		(((u64)ptr[6] & 0xffL) << 48) ^
-		(((u64)ptr[5] & 0xffL) << 40) ^
-		(((u64)ptr[4] & 0xffL) << 32) ^
-		(((u64)ptr[3] & 0xffL) << 24) ^
-		(((u64)ptr[2] & 0xffL) << 16) ^
-		(((u64)ptr[1] & 0xffL) <<  8) ^
-		(((u64)ptr[0] & 0xffL)      );
-	}
+	for (i = 0; i < 8; i++)
+		x[i] = le64_to_cpu(ptr[i]);
 
 	/* save */
 	a = aa = tctx->a;
@@ -558,9 +552,10 @@
 static void tgr192_final(void *ctx, u8 * out)
 {
 	struct tgr192_ctx *tctx = ctx;
+	__be64 *dst = (__be64 *)out;
+	__be64 *be64p;
+	__le32 *le32p;
 	u32 t, msb, lsb;
-	u8 *p;
-	int i, j;
 
 	tgr192_update(tctx, NULL, 0); /* flush */ ;
 
@@ -594,41 +589,16 @@
 		memset(tctx->hash, 0, 56);    /* fill next block with zeroes */
 	}
 	/* append the 64 bit count */
-	tctx->hash[56] = lsb;
-	tctx->hash[57] = lsb >> 8;
-	tctx->hash[58] = lsb >> 16;
-	tctx->hash[59] = lsb >> 24;
-	tctx->hash[60] = msb;
-	tctx->hash[61] = msb >> 8;
-	tctx->hash[62] = msb >> 16;
-	tctx->hash[63] = msb >> 24;
+	le32p = (__le32 *)&tctx->hash[56];
+	le32p[0] = cpu_to_le32(lsb);
+	le32p[1] = cpu_to_le32(msb);
+
 	tgr192_transform(tctx, tctx->hash);
 
-	p = tctx->hash;
-	*p++ = tctx->a >> 56; *p++ = tctx->a >> 48; *p++ = tctx->a >> 40;
-	*p++ = tctx->a >> 32; *p++ = tctx->a >> 24; *p++ = tctx->a >> 16;
-	*p++ = tctx->a >>  8; *p++ = tctx->a;\
-	*p++ = tctx->b >> 56; *p++ = tctx->b >> 48; *p++ = tctx->b >> 40;
-	*p++ = tctx->b >> 32; *p++ = tctx->b >> 24; *p++ = tctx->b >> 16;
-	*p++ = tctx->b >>  8; *p++ = tctx->b;
-	*p++ = tctx->c >> 56; *p++ = tctx->c >> 48; *p++ = tctx->c >> 40;
-	*p++ = tctx->c >> 32; *p++ = tctx->c >> 24; *p++ = tctx->c >> 16;
-	*p++ = tctx->c >>  8; *p++ = tctx->c;
-
-
-	/* unpack the hash */
-	j = 7;
-	for (i = 0; i < 8; i++) {
-		out[j--] = (tctx->a >> 8 * i) & 0xff;
-	}
-	j = 15;
-	for (i = 0; i < 8; i++) {
-		out[j--] = (tctx->b >> 8 * i) & 0xff;
-	}
-	j = 23;
-	for (i = 0; i < 8; i++) {
-		out[j--] = (tctx->c >> 8 * i) & 0xff;
-	}
+	be64p = (__be64 *)tctx->hash;
+	dst[0] = be64p[0] = cpu_to_be64(tctx->a);
+	dst[1] = be64p[1] = cpu_to_be64(tctx->b);
+	dst[2] = be64p[2] = cpu_to_be64(tctx->c);
 }
 
 static void tgr160_final(void *ctx, u8 * out)
diff --git a/crypto/twofish.c b/crypto/twofish.c
index 4efff8c..a26d885 100644
--- a/crypto/twofish.c
+++ b/crypto/twofish.c
@@ -37,6 +37,8 @@
  * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
  * Third Edition.
  */
+
+#include <asm/byteorder.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
@@ -621,13 +623,11 @@
  * whitening subkey number m. */
 
 #define INPACK(n, x, m) \
-   x = in[4 * (n)] ^ (in[4 * (n) + 1] << 8) \
-     ^ (in[4 * (n) + 2] << 16) ^ (in[4 * (n) + 3] << 24) ^ ctx->w[m]
+   x = le32_to_cpu(src[n]) ^ ctx->w[m]
 
 #define OUTUNPACK(n, x, m) \
    x ^= ctx->w[m]; \
-   out[4 * (n)] = x; out[4 * (n) + 1] = x >> 8; \
-   out[4 * (n) + 2] = x >> 16; out[4 * (n) + 3] = x >> 24
+   dst[n] = cpu_to_le32(x)
 
 #define TF_MIN_KEY_SIZE 16
 #define TF_MAX_KEY_SIZE 32
@@ -804,6 +804,8 @@
 static void twofish_encrypt(void *cx, u8 *out, const u8 *in)
 {
 	struct twofish_ctx *ctx = cx;
+	const __le32 *src = (const __le32 *)in;
+	__le32 *dst = (__le32 *)out;
 
 	/* The four 32-bit chunks of the text. */
 	u32 a, b, c, d;
@@ -839,6 +841,8 @@
 static void twofish_decrypt(void *cx, u8 *out, const u8 *in)
 {
 	struct twofish_ctx *ctx = cx;
+	const __le32 *src = (const __le32 *)in;
+	__le32 *dst = (__le32 *)out;
   
 	/* The four 32-bit chunks of the text. */
 	u32 a, b, c, d;
@@ -875,6 +879,7 @@
 	.cra_flags          =   CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize      =   TF_BLOCK_SIZE,
 	.cra_ctxsize        =   sizeof(struct twofish_ctx),
+	.cra_alignmask      =	3,
 	.cra_module         =   THIS_MODULE,
 	.cra_list           =   LIST_HEAD_INIT(alg.cra_list),
 	.cra_u              =   { .cipher = {
diff --git a/crypto/wp512.c b/crypto/wp512.c
index fd6e20e..b226a12 100644
--- a/crypto/wp512.c
+++ b/crypto/wp512.c
@@ -22,8 +22,10 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mm.h>
+#include <asm/byteorder.h>
 #include <asm/scatterlist.h>
 #include <linux/crypto.h>
+#include <linux/types.h>
 
 #define WP512_DIGEST_SIZE 64
 #define WP384_DIGEST_SIZE 48
@@ -778,19 +780,10 @@
 	u64 block[8];    /* mu(buffer) */
 	u64 state[8];    /* the cipher state */
 	u64 L[8];
-	u8 *buffer = wctx->buffer;
+	const __be64 *buffer = (const __be64 *)wctx->buffer;
 
-	for (i = 0; i < 8; i++, buffer += 8) {
-		block[i] =
-		(((u64)buffer[0]        ) << 56) ^
-		(((u64)buffer[1] & 0xffL) << 48) ^
-		(((u64)buffer[2] & 0xffL) << 40) ^
-		(((u64)buffer[3] & 0xffL) << 32) ^
-		(((u64)buffer[4] & 0xffL) << 24) ^
-		(((u64)buffer[5] & 0xffL) << 16) ^
-		(((u64)buffer[6] & 0xffL) <<  8) ^
-		(((u64)buffer[7] & 0xffL)      );
-	}
+	for (i = 0; i < 8; i++)
+		block[i] = be64_to_cpu(buffer[i]);
 
 	state[0] = block[0] ^ (K[0] = wctx->hash[0]);
 	state[1] = block[1] ^ (K[1] = wctx->hash[1]);
@@ -1069,7 +1062,7 @@
    	u8 *bitLength   = wctx->bitLength;
    	int bufferBits  = wctx->bufferBits;
    	int bufferPos   = wctx->bufferPos;
-   	u8 *digest      = out;
+	__be64 *digest  = (__be64 *)out;
 
    	buffer[bufferPos] |= 0x80U >> (bufferBits & 7);
    	bufferPos++;
@@ -1088,17 +1081,8 @@
    	memcpy(&buffer[WP512_BLOCK_SIZE - WP512_LENGTHBYTES],
 		   bitLength, WP512_LENGTHBYTES);
    	wp512_process_buffer(wctx);
-   	for (i = 0; i < WP512_DIGEST_SIZE/8; i++) {
-		digest[0] = (u8)(wctx->hash[i] >> 56);
-		digest[1] = (u8)(wctx->hash[i] >> 48);
-		digest[2] = (u8)(wctx->hash[i] >> 40);
-		digest[3] = (u8)(wctx->hash[i] >> 32);
-		digest[4] = (u8)(wctx->hash[i] >> 24);
-		digest[5] = (u8)(wctx->hash[i] >> 16);
-		digest[6] = (u8)(wctx->hash[i] >>  8);
-		digest[7] = (u8)(wctx->hash[i]      );
-		digest += 8;
-   	}
+	for (i = 0; i < WP512_DIGEST_SIZE/8; i++)
+		digest[i] = cpu_to_be64(wctx->hash[i]);
    	wctx->bufferBits   = bufferBits;
    	wctx->bufferPos    = bufferPos;
 }
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 1bbdd16..889855d 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -15,7 +15,6 @@
 #include <linux/amba/bus.h>
 
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/sizes.h>
 
 #define to_amba_device(d)	container_of(d, struct amba_device, dev)
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index a452b13..8647290 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -215,7 +215,7 @@
 	unsigned offset, bv_offs;
 	int len, ret;
 
-	down(&mapping->host->i_sem);
+	mutex_lock(&mapping->host->i_mutex);
 	index = pos >> PAGE_CACHE_SHIFT;
 	offset = pos & ((pgoff_t)PAGE_CACHE_SIZE - 1);
 	bv_offs = bvec->bv_offset;
@@ -278,7 +278,7 @@
 	}
 	ret = 0;
 out:
-	up(&mapping->host->i_sem);
+	mutex_unlock(&mapping->host->i_mutex);
 	return ret;
 unlock:
 	unlock_page(page);
@@ -527,12 +527,12 @@
 	lo->lo_pending++;
 	loop_add_bio(lo, old_bio);
 	spin_unlock_irq(&lo->lo_lock);
-	up(&lo->lo_bh_mutex);
+	complete(&lo->lo_bh_done);
 	return 0;
 
 out:
 	if (lo->lo_pending == 0)
-		up(&lo->lo_bh_mutex);
+		complete(&lo->lo_bh_done);
 	spin_unlock_irq(&lo->lo_lock);
 	bio_io_error(old_bio, old_bio->bi_size);
 	return 0;
@@ -593,23 +593,20 @@
 	lo->lo_pending = 1;
 
 	/*
-	 * up sem, we are running
+	 * complete it, we are running
 	 */
-	up(&lo->lo_sem);
+	complete(&lo->lo_done);
 
 	for (;;) {
 		int pending;
 
-		/*
-		 * interruptible just to not contribute to load avg
-		 */
-		if (down_interruptible(&lo->lo_bh_mutex))
+		if (wait_for_completion_interruptible(&lo->lo_bh_done))
 			continue;
 
 		spin_lock_irq(&lo->lo_lock);
 
 		/*
-		 * could be upped because of tear-down, not pending work
+		 * could be completed because of tear-down, not pending work
 		 */
 		if (unlikely(!lo->lo_pending)) {
 			spin_unlock_irq(&lo->lo_lock);
@@ -632,7 +629,7 @@
 			break;
 	}
 
-	up(&lo->lo_sem);
+	complete(&lo->lo_done);
 	return 0;
 }
 
@@ -843,7 +840,7 @@
 	set_blocksize(bdev, lo_blocksize);
 
 	kernel_thread(loop_thread, lo, CLONE_KERNEL);
-	down(&lo->lo_sem);
+	wait_for_completion(&lo->lo_done);
 	return 0;
 
  out_putf:
@@ -909,10 +906,10 @@
 	lo->lo_state = Lo_rundown;
 	lo->lo_pending--;
 	if (!lo->lo_pending)
-		up(&lo->lo_bh_mutex);
+		complete(&lo->lo_bh_done);
 	spin_unlock_irq(&lo->lo_lock);
 
-	down(&lo->lo_sem);
+	wait_for_completion(&lo->lo_done);
 
 	lo->lo_backing_file = NULL;
 
@@ -1289,8 +1286,8 @@
 		if (!lo->lo_queue)
 			goto out_mem4;
 		init_MUTEX(&lo->lo_ctl_mutex);
-		init_MUTEX_LOCKED(&lo->lo_sem);
-		init_MUTEX_LOCKED(&lo->lo_bh_mutex);
+		init_completion(&lo->lo_done);
+		init_completion(&lo->lo_bh_done);
 		lo->lo_number = i;
 		spin_lock_init(&lo->lo_lock);
 		disk->major = LOOP_MAJOR;
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
index a7e0975..2ae08b3 100644
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -27,8 +27,8 @@
 #include <linux/time.h>
 #include <linux/hdreg.h>
 #include <linux/dma-mapping.h>
+#include <linux/completion.h>
 #include <asm/io.h>
-#include <asm/semaphore.h>
 #include <asm/uaccess.h>
 
 #if 0
@@ -303,7 +303,7 @@
 
 	struct work_struct		fsm_task;
 
-	struct semaphore		probe_sem;
+	struct completion		probe_comp;
 };
 
 struct carm_response {
@@ -1346,7 +1346,7 @@
 	}
 
 	case HST_PROBE_FINISHED:
-		up(&host->probe_sem);
+		complete(&host->probe_comp);
 		break;
 
 	case HST_ERROR:
@@ -1622,7 +1622,7 @@
 	host->flags = pci_dac ? FL_DAC : 0;
 	spin_lock_init(&host->lock);
 	INIT_WORK(&host->fsm_task, carm_fsm_task, host);
-	init_MUTEX_LOCKED(&host->probe_sem);
+	init_completion(&host->probe_comp);
 
 	for (i = 0; i < ARRAY_SIZE(host->req); i++)
 		host->req[i].tag = i;
@@ -1691,8 +1691,8 @@
 	if (rc)
 		goto err_out_free_irq;
 
-	DPRINTK("waiting for probe_sem\n");
-	down(&host->probe_sem);
+	DPRINTK("waiting for probe_comp\n");
+	wait_for_completion(&host->probe_comp);
 
 	printk(KERN_INFO "%s: pci %s, ports %d, io %lx, irq %u, major %d\n",
 	       host->name, pci_name(pdev), (int) CARM_MAX_PORTS,
diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c
index 01f0351..ce127f7 100644
--- a/drivers/cdrom/cm206.c
+++ b/drivers/cdrom/cm206.c
@@ -32,7 +32,7 @@
  18 mrt 1995: 0.24 Working background read-ahead. (still problems)
  26 mrt 1995: 0.25 Multi-session ioctl added (kernel v1.2).
               Statistics implemented, though separate stats206.h.
-	      Accessible trough ioctl 0x1000 (just a number).
+	      Accessible through ioctl 0x1000 (just a number).
 	      Hard to choose between v1.2 development and 1.1.75.
 	      Bottom-half doesn't work with 1.2...
 	      0.25a: fixed... typo. Still problems...
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 5b2d180..704c3c0 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -741,7 +741,7 @@
 {
 	loff_t ret;
 
-	down(&file->f_dentry->d_inode->i_sem);
+	mutex_lock(&file->f_dentry->d_inode->i_mutex);
 	switch (orig) {
 		case 0:
 			file->f_pos = offset;
@@ -756,7 +756,7 @@
 		default:
 			ret = -EINVAL;
 	}
-	up(&file->f_dentry->d_inode->i_sem);
+	mutex_unlock(&file->f_dentry->d_inode->i_mutex);
 	return ret;
 }
 
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 145275e..5765f67 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -153,6 +153,21 @@
 
 /* END SYNC SYSRQ HANDLERS BLOCK */
 
+#ifdef CONFIG_DEBUG_MUTEXES
+
+static void
+sysrq_handle_showlocks(int key, struct pt_regs *pt_regs, struct tty_struct *tty)
+{
+	mutex_debug_show_all_locks();
+}
+
+static struct sysrq_key_op sysrq_showlocks_op = {
+	.handler	= sysrq_handle_showlocks,
+	.help_msg	= "show-all-locks(D)",
+	.action_msg	= "Show Locks Held",
+};
+
+#endif
 
 /* SHOW SYSRQ HANDLERS BLOCK */
 
@@ -294,7 +309,11 @@
 #else
 /* c */	NULL,
 #endif
+#ifdef CONFIG_DEBUG_MUTEXES
+/* d */ &sysrq_showlocks_op,
+#else
 /* d */ NULL,
+#endif
 /* e */	&sysrq_term_op,
 /* f */	&sysrq_moom_op,
 /* g */	NULL,
diff --git a/drivers/char/watchdog/cpu5wdt.c b/drivers/char/watchdog/cpu5wdt.c
index e75045f..3e8410b 100644
--- a/drivers/char/watchdog/cpu5wdt.c
+++ b/drivers/char/watchdog/cpu5wdt.c
@@ -28,6 +28,7 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/timer.h>
+#include <linux/completion.h>
 #include <linux/jiffies.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -57,7 +58,7 @@
 /* some device data */
 
 static struct {
-	struct semaphore stop;
+	struct completion stop;
 	volatile int running;
 	struct timer_list timer;
 	volatile int queue;
@@ -85,7 +86,7 @@
 	}
 	else {
 		/* ticks doesn't matter anyway */
-		up(&cpu5wdt_device.stop);
+		complete(&cpu5wdt_device.stop);
 	}
 
 }
@@ -239,7 +240,7 @@
 	if ( !val )
 		printk(KERN_INFO PFX "sorry, was my fault\n");
 
-	init_MUTEX_LOCKED(&cpu5wdt_device.stop);
+	init_completion(&cpu5wdt_device.stop);
 	cpu5wdt_device.queue = 0;
 
 	clear_bit(0, &cpu5wdt_device.inuse);
@@ -269,7 +270,7 @@
 {
 	if ( cpu5wdt_device.queue ) {
 		cpu5wdt_device.queue = 0;
-		down(&cpu5wdt_device.stop);
+		wait_for_completion(&cpu5wdt_device.stop);
 	}
 
 	misc_deregister(&cpu5wdt_misc);
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
index 71407c5..64819aa 100644
--- a/drivers/crypto/padlock-aes.c
+++ b/drivers/crypto/padlock-aes.c
@@ -99,9 +99,6 @@
 	return x >> (n << 3);
 }
 
-#define uint32_t_in(x) le32_to_cpu(*(const uint32_t *)(x))
-#define uint32_t_out(to, from) (*(uint32_t *)(to) = cpu_to_le32(from))
-
 #define E_KEY ctx->E
 #define D_KEY ctx->D
 
@@ -294,6 +291,7 @@
 aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t *flags)
 {
 	struct aes_ctx *ctx = aes_ctx(ctx_arg);
+	const __le32 *key = (const __le32 *)in_key;
 	uint32_t i, t, u, v, w;
 	uint32_t P[AES_EXTENDED_KEY_SIZE];
 	uint32_t rounds;
@@ -313,10 +311,10 @@
 	ctx->E = ctx->e_data;
 	ctx->D = ctx->e_data;
 
-	E_KEY[0] = uint32_t_in (in_key);
-	E_KEY[1] = uint32_t_in (in_key + 4);
-	E_KEY[2] = uint32_t_in (in_key + 8);
-	E_KEY[3] = uint32_t_in (in_key + 12);
+	E_KEY[0] = le32_to_cpu(key[0]);
+	E_KEY[1] = le32_to_cpu(key[1]);
+	E_KEY[2] = le32_to_cpu(key[2]);
+	E_KEY[3] = le32_to_cpu(key[3]);
 
 	/* Prepare control words. */
 	memset(&ctx->cword, 0, sizeof(ctx->cword));
@@ -343,17 +341,17 @@
 		break;
 
 	case 24:
-		E_KEY[4] = uint32_t_in (in_key + 16);
-		t = E_KEY[5] = uint32_t_in (in_key + 20);
+		E_KEY[4] = le32_to_cpu(key[4]);
+		t = E_KEY[5] = le32_to_cpu(key[5]);
 		for (i = 0; i < 8; ++i)
 			loop6 (i);
 		break;
 
 	case 32:
-		E_KEY[4] = uint32_t_in (in_key + 16);
-		E_KEY[5] = uint32_t_in (in_key + 20);
-		E_KEY[6] = uint32_t_in (in_key + 24);
-		t = E_KEY[7] = uint32_t_in (in_key + 28);
+		E_KEY[4] = le32_to_cpu(in_key[4]);
+		E_KEY[5] = le32_to_cpu(in_key[5]);
+		E_KEY[6] = le32_to_cpu(in_key[6]);
+		t = E_KEY[7] = le32_to_cpu(in_key[7]);
 		for (i = 0; i < 7; ++i)
 			loop8 (i);
 		break;
@@ -468,6 +466,8 @@
 
 static struct crypto_alg aes_alg = {
 	.cra_name		=	"aes",
+	.cra_driver_name	=	"aes-padlock",
+	.cra_priority		=	300,
 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize		=	AES_BLOCK_SIZE,
 	.cra_ctxsize		=	sizeof(struct aes_ctx),
diff --git a/drivers/crypto/padlock.h b/drivers/crypto/padlock.h
index 3cf2b7a..b78489b 100644
--- a/drivers/crypto/padlock.h
+++ b/drivers/crypto/padlock.h
@@ -17,7 +17,7 @@
 
 /* Control word. */
 struct cword {
-	int __attribute__ ((__packed__))
+	unsigned int __attribute__ ((__packed__))
 		rounds:4,
 		algo:3,
 		keygen:1,
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 1ddaa71..7cb2d86 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -655,7 +655,7 @@
 {
 	ide_hwif_t *hwif = container_of(dev, ide_hwif_t, gendev);
 
-	up(&hwif->gendev_rel_sem);
+	complete(&hwif->gendev_rel_comp);
 }
 
 static void hwif_register (ide_hwif_t *hwif)
@@ -1327,7 +1327,7 @@
 	drive->queue = NULL;
 	spin_unlock_irq(&ide_lock);
 
-	up(&drive->gendev_rel_sem);
+	complete(&drive->gendev_rel_comp);
 }
 
 /*
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index b069b13..ec5a4cb 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -222,7 +222,7 @@
 	hwif->mwdma_mask = 0x80;	/* disable all mwdma */
 	hwif->swdma_mask = 0x80;	/* disable all swdma */
 
-	sema_init(&hwif->gendev_rel_sem, 0);
+	init_completion(&hwif->gendev_rel_comp);
 
 	default_hwif_iops(hwif);
 	default_hwif_transport(hwif);
@@ -245,7 +245,7 @@
 		drive->is_flash			= 0;
 		drive->vdma			= 0;
 		INIT_LIST_HEAD(&drive->list);
-		sema_init(&drive->gendev_rel_sem, 0);
+		init_completion(&drive->gendev_rel_comp);
 	}
 }
 
@@ -602,7 +602,7 @@
 		}
 		spin_unlock_irq(&ide_lock);
 		device_unregister(&drive->gendev);
-		down(&drive->gendev_rel_sem);
+		wait_for_completion(&drive->gendev_rel_comp);
 		spin_lock_irq(&ide_lock);
 	}
 	hwif->present = 0;
@@ -662,7 +662,7 @@
 	/* More messed up locking ... */
 	spin_unlock_irq(&ide_lock);
 	device_unregister(&hwif->gendev);
-	down(&hwif->gendev_rel_sem);
+	wait_for_completion(&hwif->gendev_rel_comp);
 
 	/*
 	 * Remove us from the kernel's knowledge
diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
index 3f0df33..ebd9976 100644
--- a/drivers/input/serio/sa1111ps2.c
+++ b/drivers/input/serio/sa1111ps2.c
@@ -20,7 +20,6 @@
 #include <linux/spinlock.h>
 
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/system.h>
 
 #include <asm/hardware/sa1111.h>
diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c
index 207cae3..0a37ade 100644
--- a/drivers/isdn/capi/capifs.c
+++ b/drivers/isdn/capi/capifs.c
@@ -138,7 +138,7 @@
 {
 	char s[10];
 	struct dentry *root = capifs_root;
-	down(&root->d_inode->i_sem);
+	mutex_lock(&root->d_inode->i_mutex);
 	return lookup_one_len(s, root, sprintf(s, "%d", num));
 }
 
@@ -159,7 +159,7 @@
 	dentry = get_node(number);
 	if (!IS_ERR(dentry) && !dentry->d_inode)
 		d_instantiate(dentry, inode);
-	up(&capifs_root->d_inode->i_sem);
+	mutex_unlock(&capifs_root->d_inode->i_mutex);
 }
 
 void capifs_free_ncci(unsigned int number)
@@ -175,7 +175,7 @@
 		}
 		dput(dentry);
 	}
-	up(&capifs_root->d_inode->i_sem);
+	mutex_unlock(&capifs_root->d_inode->i_mutex);
 }
 
 static int __init capifs_init(void)
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index 8d0958c..4f50ee5 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -630,12 +630,12 @@
 	sprintf(nodename, "/u3@0,f8000000/i2c@f8001000/cpuid@a%d", cpu ? 2 : 0);
 	np = of_find_node_by_path(nodename);
 	if (np == NULL) {
-		printk(KERN_ERR "therm_pm72: Failed to retreive cpuid node from device-tree\n");
+		printk(KERN_ERR "therm_pm72: Failed to retrieve cpuid node from device-tree\n");
 		return -ENODEV;
 	}
 	data = (u8 *)get_property(np, "cpuid", &len);
 	if (data == NULL) {
-		printk(KERN_ERR "therm_pm72: Failed to retreive cpuid property from device-tree\n");
+		printk(KERN_ERR "therm_pm72: Failed to retrieve cpuid property from device-tree\n");
 		of_node_put(np);
 		return -ENODEV;
 	}
diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c
index 80ddf97..eb69a60 100644
--- a/drivers/macintosh/windfarm_pm81.c
+++ b/drivers/macintosh/windfarm_pm81.c
@@ -26,7 +26,7 @@
  *    (typically the drive fan)
  *  - the main control (first control) gets the target value scaled with
  *    the first pair of factors, and is then modified as below
- *  - the value of the target of the CPU Fan control loop is retreived,
+ *  - the value of the target of the CPU Fan control loop is retrieved,
  *    scaled with the second pair of factors, and the max of that and
  *    the scaled target is applied to the main control.
  *
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 0e48151..5c210b0 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -837,9 +837,9 @@
 {
 	set_capacity(md->disk, size);
 
-	down(&md->suspended_bdev->bd_inode->i_sem);
+	mutex_lock(&md->suspended_bdev->bd_inode->i_mutex);
 	i_size_write(md->suspended_bdev->bd_inode, (loff_t)size << SECTOR_SHIFT);
-	up(&md->suspended_bdev->bd_inode->i_sem);
+	mutex_unlock(&md->suspended_bdev->bd_inode->i_mutex);
 }
 
 static int __bind(struct mapped_device *md, struct dm_table *t)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index e423a16..0302723 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -3460,9 +3460,9 @@
 
 		bdev = bdget_disk(mddev->gendisk, 0);
 		if (bdev) {
-			down(&bdev->bd_inode->i_sem);
+			mutex_lock(&bdev->bd_inode->i_mutex);
 			i_size_write(bdev->bd_inode, mddev->array_size << 10);
-			up(&bdev->bd_inode->i_sem);
+			mutex_unlock(&bdev->bd_inode->i_mutex);
 			bdput(bdev);
 		}
 	}
@@ -3486,9 +3486,9 @@
 
 		bdev = bdget_disk(mddev->gendisk, 0);
 		if (bdev) {
-			down(&bdev->bd_inode->i_sem);
+			mutex_lock(&bdev->bd_inode->i_mutex);
 			i_size_write(bdev->bd_inode, mddev->array_size << 10);
-			up(&bdev->bd_inode->i_sem);
+			mutex_unlock(&bdev->bd_inode->i_mutex);
 			bdput(bdev);
 		}
 	}
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index 09ec964..b614612 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -253,7 +253,10 @@
 
 	if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
 		DEB_S(("initializing vbi...\n"));
-		result = saa7146_vbi_uops.open(dev,file);
+		if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
+			result = saa7146_vbi_uops.open(dev,file);
+		if (dev->ext_vv_data->vbi_fops.open)
+			dev->ext_vv_data->vbi_fops.open(inode, file);
 	} else {
 		DEB_S(("initializing video...\n"));
 		result = saa7146_video_uops.open(dev,file);
@@ -289,7 +292,10 @@
 		return -ERESTARTSYS;
 
 	if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
-		saa7146_vbi_uops.release(dev,file);
+		if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
+			saa7146_vbi_uops.release(dev,file);
+		if (dev->ext_vv_data->vbi_fops.release)
+			dev->ext_vv_data->vbi_fops.release(inode, file);
 	} else {
 		saa7146_video_uops.release(dev,file);
 	}
@@ -332,6 +338,7 @@
 		BUG();
 		return 0;
 	}
+
 	return videobuf_mmap_mapper(q,vma);
 }
 
@@ -381,7 +388,10 @@
 		}
 	case V4L2_BUF_TYPE_VBI_CAPTURE: {
 //		DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", file, data, (unsigned long)count));
-		return saa7146_vbi_uops.read(file,data,count,ppos);
+		if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
+			return saa7146_vbi_uops.read(file,data,count,ppos);
+		else
+			return -EINVAL;
 		}
 		break;
 	default:
@@ -390,12 +400,31 @@
 	}
 }
 
+static ssize_t fops_write(struct file *file, const char __user *data, size_t count, loff_t *ppos)
+{
+	struct saa7146_fh *fh = file->private_data;
+
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		return -EINVAL;
+	case V4L2_BUF_TYPE_VBI_CAPTURE:
+		if (fh->dev->ext_vv_data->vbi_fops.write)
+			return fh->dev->ext_vv_data->vbi_fops.write(file, data, count, ppos);
+		else
+			return -EINVAL;
+	default:
+		BUG();
+		return -EINVAL;
+	}
+}
+
 static struct file_operations video_fops =
 {
 	.owner		= THIS_MODULE,
 	.open		= fops_open,
 	.release	= fops_release,
 	.read		= fops_read,
+	.write		= fops_write,
 	.poll		= fops_poll,
 	.mmap		= fops_mmap,
 	.ioctl		= fops_ioctl,
@@ -467,7 +496,8 @@
 	memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM);
 
 	saa7146_video_uops.init(dev,vv);
-	saa7146_vbi_uops.init(dev,vv);
+	if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
+		saa7146_vbi_uops.init(dev,vv);
 
 	dev->vv_data = vv;
 	dev->vv_callback = &vv_callback;
diff --git a/drivers/media/common/saa7146_hlp.c b/drivers/media/common/saa7146_hlp.c
index ec52dff..33bec8a 100644
--- a/drivers/media/common/saa7146_hlp.c
+++ b/drivers/media/common/saa7146_hlp.c
@@ -562,19 +562,26 @@
 
 	int b_depth = vv->ov_fmt->depth;
 	int b_bpl = vv->ov_fb.fmt.bytesperline;
-	u32 base = (u32)vv->ov_fb.base;
+	/* The unsigned long cast is to remove a 64-bit compile warning since
+	   it looks like a 64-bit address is cast to a 32-bit value, even
+	   though the base pointer is really a 32-bit physical address that
+	   goes into a 32-bit DMA register.
+	   FIXME: might not work on some 64-bit platforms, but see the FIXME
+	   in struct v4l2_framebuffer (videodev2.h) for that.
+	 */
+	u32 base = (u32)(unsigned long)vv->ov_fb.base;
 
 	struct	saa7146_video_dma vdma1;
 
 	/* calculate memory offsets for picture, look if we shall top-down-flip */
 	vdma1.pitch	= 2*b_bpl;
 	if ( 0 == vv->vflip ) {
-		vdma1.base_even = (u32)base + (w_y * (vdma1.pitch/2)) + (w_x * (b_depth / 8));
+		vdma1.base_even = base + (w_y * (vdma1.pitch/2)) + (w_x * (b_depth / 8));
 		vdma1.base_odd  = vdma1.base_even + (vdma1.pitch / 2);
 		vdma1.prot_addr = vdma1.base_even + (w_height * (vdma1.pitch / 2));
 	}
 	else {
-		vdma1.base_even = (u32)base + ((w_y+w_height) * (vdma1.pitch/2)) + (w_x * (b_depth / 8));
+		vdma1.base_even = base + ((w_y+w_height) * (vdma1.pitch/2)) + (w_x * (b_depth / 8));
 		vdma1.base_odd  = vdma1.base_even - (vdma1.pitch / 2);
 		vdma1.prot_addr = vdma1.base_odd - (w_height * (vdma1.pitch / 2));
 	}
diff --git a/drivers/media/common/saa7146_vbi.c b/drivers/media/common/saa7146_vbi.c
index 063986e..468d3c9 100644
--- a/drivers/media/common/saa7146_vbi.c
+++ b/drivers/media/common/saa7146_vbi.c
@@ -500,9 +500,9 @@
 }
 
 struct saa7146_use_ops saa7146_vbi_uops = {
-	.init 		= vbi_init,
-	.open 		= vbi_open,
+	.init		= vbi_init,
+	.open		= vbi_open,
 	.release	= vbi_close,
 	.irq_done	= vbi_irq_done,
-	.read 		= vbi_read,
+	.read		= vbi_read,
 };
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index 1d96102..7ebac79 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -151,8 +151,8 @@
 
 	if (V4L2_FIELD_ANY == field) {
 		field = (win->w.height > maxh/2)
-		        ? V4L2_FIELD_INTERLACED
-		        : V4L2_FIELD_TOP;
+			? V4L2_FIELD_INTERLACED
+			: V4L2_FIELD_TOP;
 		}
 	switch (field) {
 	case V4L2_FIELD_TOP:
@@ -1114,10 +1114,6 @@
 		return 0;
 	}
 	case VIDIOC_OVERLAY:
-
-
-
-
 	{
 		int on = *(int *)arg;
 		int err = 0;
@@ -1359,7 +1355,6 @@
 	saa7146_buffer_queue(fh->dev,&vv->video_q,buf);
 }
 
-
 static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
 {
 	struct file *file = q->priv_data;
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 21a9045..0b940e1 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -298,7 +298,7 @@
 }
 
 static int lgdt3303_pll_set(struct dvb_frontend* fe,
-		            struct dvb_frontend_parameters* params)
+			    struct dvb_frontend_parameters* params)
 {
 	struct flexcop_device *fc = fe->dvb->priv;
 	u8 buf[4];
@@ -485,12 +485,16 @@
 /* try to figure out the frontend, each card/box can have on of the following list */
 int flexcop_frontend_init(struct flexcop_device *fc)
 {
+	struct dvb_frontend_ops *ops;
+
 	/* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */
 	if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) {
-		fc->fe->ops->set_voltage = flexcop_set_voltage;
+		ops = fc->fe->ops;
 
-		fc->fe_sleep             = fc->fe->ops->sleep;
-		fc->fe->ops->sleep       = flexcop_sleep;
+		ops->set_voltage = flexcop_set_voltage;
+
+		fc->fe_sleep             = ops->sleep;
+		ops->sleep               = flexcop_sleep;
 
 		fc->dev_type          = FC_SKY;
 		info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address);
@@ -522,15 +526,17 @@
 	} else
 	/* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
 	if ((fc->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) {
-		fc->fe->ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
-		fc->fe->ops->diseqc_send_burst      = flexcop_diseqc_send_burst;
-		fc->fe->ops->set_tone               = flexcop_set_tone;
-		fc->fe->ops->set_voltage            = flexcop_set_voltage;
+		ops = fc->fe->ops;
 
-		fc->fe_sleep                        = fc->fe->ops->sleep;
-		fc->fe->ops->sleep                  = flexcop_sleep;
+		ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
+		ops->diseqc_send_burst      = flexcop_diseqc_send_burst;
+		ops->set_tone               = flexcop_set_tone;
+		ops->set_voltage            = flexcop_set_voltage;
 
-		fc->dev_type                        = FC_SKY_OLD;
+		fc->fe_sleep                = ops->sleep;
+		ops->sleep                  = flexcop_sleep;
+
+		fc->dev_type                = FC_SKY_OLD;
 		info("found the vp310 (aka mt312) at i2c address: 0x%02x",skystar23_samsung_tbdu18132_config.demod_address);
 	}
 
@@ -540,8 +546,9 @@
 	} else {
 		if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
 			err("frontend registration failed!");
-			if (fc->fe->ops->release != NULL)
-				fc->fe->ops->release(fc->fe);
+			ops = fc->fe->ops;
+			if (ops->release != NULL)
+				ops->release(fc->fe);
 			fc->fe = NULL;
 			return -EINVAL;
 		}
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h
index 23cc643..3153f95 100644
--- a/drivers/media/dvb/b2c2/flexcop-reg.h
+++ b/drivers/media/dvb/b2c2/flexcop-reg.h
@@ -39,11 +39,13 @@
 /* FlexCop IBI Registers */
 #if defined(__LITTLE_ENDIAN)
 	#include "flexcop_ibi_value_le.h"
-#elif defined(__BIG_ENDIAN)
+#else
+#if defined(__BIG_ENDIAN)
 	#include "flexcop_ibi_value_be.h"
 #else
 	#error no endian defined
 #endif
+#endif
 
 #define fc_data_Tag_ID_DVB  0x3e
 #define fc_data_Tag_ID_ATSC 0x3f
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 8977c7a..3a2ff1c 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -1341,30 +1341,40 @@
 	return 0;
 }
 
-static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
+static int dst_set_frontend(struct dvb_frontend* fe,
+			    struct dvb_frontend_parameters* p,
+			    unsigned int mode_flags,
+			    int *delay,
+			    fe_status_t *status)
 {
 	struct dst_state *state = fe->demodulator_priv;
 
-	dst_set_freq(state, p->frequency);
-	dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
+	if (p != NULL) {
+		dst_set_freq(state, p->frequency);
+		dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
 
-	if (state->dst_type == DST_TYPE_IS_SAT) {
-		if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
-			dst_set_inversion(state, p->inversion);
-		dst_set_fec(state, p->u.qpsk.fec_inner);
-		dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
-		dst_set_polarization(state);
-		dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate);
+		if (state->dst_type == DST_TYPE_IS_SAT) {
+			if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
+				dst_set_inversion(state, p->inversion);
+			dst_set_fec(state, p->u.qpsk.fec_inner);
+			dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
+			dst_set_polarization(state);
+			dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate);
 
-	} else if (state->dst_type == DST_TYPE_IS_TERR)
-		dst_set_bandwidth(state, p->u.ofdm.bandwidth);
-	else if (state->dst_type == DST_TYPE_IS_CABLE) {
-		dst_set_fec(state, p->u.qam.fec_inner);
-		dst_set_symbolrate(state, p->u.qam.symbol_rate);
-		dst_set_modulation(state, p->u.qam.modulation);
+		} else if (state->dst_type == DST_TYPE_IS_TERR)
+			dst_set_bandwidth(state, p->u.ofdm.bandwidth);
+		else if (state->dst_type == DST_TYPE_IS_CABLE) {
+			dst_set_fec(state, p->u.qam.fec_inner);
+			dst_set_symbolrate(state, p->u.qam.symbol_rate);
+			dst_set_modulation(state, p->u.qam.modulation);
+		}
+		dst_write_tuna(fe);
 	}
-	dst_write_tuna(fe);
 
+	if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
+		dst_read_status(fe, status);
+
+	*delay = HZ/10;
 	return 0;
 }
 
@@ -1445,7 +1455,7 @@
 
 	.release = dst_release,
 	.init = dst_init,
-	.set_frontend = dst_set_frontend,
+	.tune = dst_set_frontend,
 	.get_frontend = dst_get_frontend,
 	.read_status = dst_read_status,
 	.read_signal_strength = dst_read_signal_strength,
@@ -1469,7 +1479,7 @@
 
 	.release = dst_release,
 	.init = dst_init,
-	.set_frontend = dst_set_frontend,
+	.tune = dst_set_frontend,
 	.get_frontend = dst_get_frontend,
 	.read_status = dst_read_status,
 	.read_signal_strength = dst_read_signal_strength,
@@ -1496,7 +1506,7 @@
 
 	.release = dst_release,
 	.init = dst_init,
-	.set_frontend = dst_set_frontend,
+	.tune = dst_set_frontend,
 	.get_frontend = dst_get_frontend,
 	.read_status = dst_read_status,
 	.read_signal_strength = dst_read_signal_strength,
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index 2239651..c650b4b 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -283,16 +283,17 @@
 		hw_buffer->msg[4] = 0x03;
 		hw_buffer->msg[5] = length & 0xff;
 		hw_buffer->msg[6] = 0x00;
+
 		/*
 		 *	Need to compute length for EN50221 section 8.3.2, for the time being
 		 *	assuming 8.3.2 is not applicable
 		 */
 		memcpy(&hw_buffer->msg[7], &p_ca_message->msg[4], length);
 	}
+
 	return 0;
 }
 
-
 static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply)
 {
 	if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) {
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index 77977e9..01b4e0a 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -600,7 +600,6 @@
 	struct dst_state* state = NULL;
 
 	switch(type) {
-#ifdef BTTV_BOARD_DVICO_DVBT_LITE
 	case BTTV_BOARD_DVICO_DVBT_LITE:
 		card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter);
 		if (card->fe != NULL) {
@@ -608,22 +607,15 @@
 			card->fe->ops->info.frequency_max = 862000000;
 		}
 		break;
-#endif
 
-#ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE
 	case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
 		lgdt330x_reset(card);
 		card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter);
 		if (card->fe != NULL)
 			dprintk ("dvb_bt8xx: lgdt330x detected\n");
 		break;
-#endif
 
-#ifdef BTTV_BOARD_TWINHAN_VP3021
-	case BTTV_BOARD_TWINHAN_VP3021:
-#else
 	case BTTV_BOARD_NEBULA_DIGITV:
-#endif
 		/*
 		 * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK);
 		 * this would be a cleaner solution than trying each frontend in turn.
@@ -812,9 +804,7 @@
 		card->irq_err_ignore = 0;
 		break;
 
-#ifdef BTTV_BOARD_DVICO_DVBT_LITE
 	case BTTV_BOARD_DVICO_DVBT_LITE:
-#endif
 		card->gpio_mode = 0x0400C060;
 		card->op_sync_orin = 0;
 		card->irq_err_ignore = 0;
@@ -823,19 +813,13 @@
 		 * DA_APP(parallel) */
 		break;
 
-#ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE
 	case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
-#endif
 		card->gpio_mode = 0x0400c060;
 		card->op_sync_orin = BT878_RISC_SYNC_MASK;
 		card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
 		break;
 
-#ifdef BTTV_BOARD_TWINHAN_VP3021
-	case BTTV_BOARD_TWINHAN_VP3021:
-#else
 	case BTTV_BOARD_NEBULA_DIGITV:
-#endif
 	case BTTV_BOARD_AVDVBT_761:
 		card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5);
 		card->op_sync_orin = 0;
diff --git a/drivers/media/dvb/cinergyT2/Kconfig b/drivers/media/dvb/cinergyT2/Kconfig
index 7cf4c4a..6018fcd 100644
--- a/drivers/media/dvb/cinergyT2/Kconfig
+++ b/drivers/media/dvb/cinergyT2/Kconfig
@@ -21,35 +21,35 @@
 config DVB_CINERGYT2_STREAM_URB_COUNT
 	int "Number of queued USB Request Blocks for Highspeed Stream Transfers"
 	depends on DVB_CINERGYT2_TUNING
-        default "32"
+	default "32"
 	help
 	  USB Request Blocks for Highspeed Stream transfers are scheduled in
 	  a queue for the Host Controller.
 
 	  Usually the default value is a safe choice.
 
-	  You may increase this number if you are using this device in a 
-	  Server Environment with many high-traffic USB Highspeed devices 
+	  You may increase this number if you are using this device in a
+	  Server Environment with many high-traffic USB Highspeed devices
 	  sharing the same USB bus.
 
 
 config DVB_CINERGYT2_STREAM_BUF_SIZE
 	int "Size of URB Stream Buffers for Highspeed Transfers"
 	depends on DVB_CINERGYT2_TUNING
-        default "512"
+	default "512"
 	help
 	  Should be a multiple of native buffer size of 512 bytes.
 	  Default value is a safe choice.
 
-	  You may increase this number if you are using this device in a 
-	  Server Environment with many high-traffic USB Highspeed devices 
+	  You may increase this number if you are using this device in a
+	  Server Environment with many high-traffic USB Highspeed devices
 	  sharing the same USB bus.
 
 
 config DVB_CINERGYT2_QUERY_INTERVAL
 	int "Status update interval [milliseconds]"
 	depends on DVB_CINERGYT2_TUNING
-        default "250"
+	default "250"
 	help
 	  This is the interval for status readouts from the demodulator.
 	  You may try lower values if you need more responsive signal quality
@@ -64,9 +64,9 @@
 config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
 	bool "Register the onboard IR Remote Control Receiver as Input Device"
 	depends on DVB_CINERGYT2_TUNING
-        default "yes"
+	default "yes"
 	help
-	  Enable this option if you want to use the onboard Infrared Remote 
+	  Enable this option if you want to use the onboard Infrared Remote
 	  Control Receiver as Linux-Input device.
 
 	  Right now only the keycode table for the default Remote Control
@@ -77,7 +77,7 @@
 config DVB_CINERGYT2_RC_QUERY_INTERVAL
 	int "Infrared Remote Controller update interval [milliseconds]"
 	depends on DVB_CINERGYT2_TUNING && DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
-        default "50"
+	default "50"
 	help
 	  If you have a very fast-repeating remote control you can try lower
 	  values, for normal consumer receivers the default value should be
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 1d69bf0..c4b4c5b 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -131,6 +131,8 @@
 
 	wait_queue_head_t poll_wq;
 	int pending_fe_events;
+	int disconnect_pending;
+	atomic_t inuse;
 
 	void *streambuf;
 	dma_addr_t streambuf_dmahandle;
@@ -343,7 +345,7 @@
 	struct dvb_demux *demux = dvbdmxfeed->demux;
 	struct cinergyt2 *cinergyt2 = demux->priv;
 
-	if (down_interruptible(&cinergyt2->sem))
+	if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
 		return -ERESTARTSYS;
 
 	if (cinergyt2->streaming == 0)
@@ -359,7 +361,7 @@
 	struct dvb_demux *demux = dvbdmxfeed->demux;
 	struct cinergyt2 *cinergyt2 = demux->priv;
 
-	if (down_interruptible(&cinergyt2->sem))
+	if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
 		return -ERESTARTSYS;
 
 	if (--cinergyt2->streaming == 0)
@@ -479,23 +481,37 @@
 {
 	struct dvb_device *dvbdev = file->private_data;
 	struct cinergyt2 *cinergyt2 = dvbdev->priv;
-	int err;
+	int err = -ERESTARTSYS;
 
-	if ((err = dvb_generic_open(inode, file)))
-		return err;
-
-	if (down_interruptible(&cinergyt2->sem))
+	if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
 		return -ERESTARTSYS;
 
+	if ((err = dvb_generic_open(inode, file))) {
+		up(&cinergyt2->sem);
+		return err;
+	}
+
+
 	if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
 		cinergyt2_sleep(cinergyt2, 0);
 		schedule_delayed_work(&cinergyt2->query_work, HZ/2);
 	}
 
+	atomic_inc(&cinergyt2->inuse);
+
 	up(&cinergyt2->sem);
 	return 0;
 }
 
+static void cinergyt2_unregister(struct cinergyt2 *cinergyt2)
+{
+	dvb_unregister_device(cinergyt2->fedev);
+	dvb_unregister_adapter(&cinergyt2->adapter);
+
+	cinergyt2_free_stream_urbs(cinergyt2);
+	kfree(cinergyt2);
+}
+
 static int cinergyt2_release (struct inode *inode, struct file *file)
 {
 	struct dvb_device *dvbdev = file->private_data;
@@ -504,7 +520,7 @@
 	if (down_interruptible(&cinergyt2->sem))
 		return -ERESTARTSYS;
 
-	if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
+	if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) {
 		cancel_delayed_work(&cinergyt2->query_work);
 		flush_scheduled_work();
 		cinergyt2_sleep(cinergyt2, 1);
@@ -512,6 +528,11 @@
 
 	up(&cinergyt2->sem);
 
+	if (atomic_dec_and_test(&cinergyt2->inuse) && cinergyt2->disconnect_pending) {
+		warn("delayed unregister in release");
+		cinergyt2_unregister(cinergyt2);
+	}
+
 	return dvb_generic_release(inode, file);
 }
 
@@ -519,7 +540,14 @@
 {
 	struct dvb_device *dvbdev = file->private_data;
 	struct cinergyt2 *cinergyt2 = dvbdev->priv;
+
+	if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
+		return -ERESTARTSYS;
+
 	poll_wait(file, &cinergyt2->poll_wq, wait);
+
+	up(&cinergyt2->sem);
+
 	return (POLLIN | POLLRDNORM | POLLPRI);
 }
 
@@ -564,10 +592,15 @@
 				(__u16 __user *) arg);
 
 	case FE_READ_UNCORRECTED_BLOCKS:
-		/* UNC are already converted to host byte order... */
-		return put_user(stat->uncorrected_block_count,
-				(__u32 __user *) arg);
+	{
+		uint32_t unc_count;
 
+		unc_count = stat->uncorrected_block_count;
+		stat->uncorrected_block_count = 0;
+
+		/* UNC are already converted to host byte order... */
+		return put_user(unc_count,(__u32 __user *) arg);
+	}
 	case FE_SET_FRONTEND:
 	{
 		struct dvbt_set_parameters_msg *param = &cinergyt2->param;
@@ -580,7 +613,7 @@
 		if (copy_from_user(&p, (void  __user*) arg, sizeof(p)))
 			return -EFAULT;
 
-		if (down_interruptible(&cinergyt2->sem))
+		if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
 			return -ERESTARTSYS;
 
 		param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
@@ -691,7 +724,7 @@
 	struct cinergyt2_rc_event rc_events[12];
 	int n, len, i;
 
-	if (down_interruptible(&cinergyt2->sem))
+	if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
 		return;
 
 	len = cinergyt2_command(cinergyt2, buf, sizeof(buf),
@@ -786,7 +819,6 @@
 static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2)
 {
 	cancel_delayed_work(&cinergyt2->rc_query_work);
-	flush_scheduled_work();
 	input_unregister_device(cinergyt2->rc_input_dev);
 }
 
@@ -817,7 +849,7 @@
 	uint8_t lock_bits;
 	uint32_t unc;
 
-	if (down_interruptible(&cinergyt2->sem))
+	if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
 		return;
 
 	unc = s->uncorrected_block_count;
@@ -917,28 +949,25 @@
 {
 	struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
 
-	if (down_interruptible(&cinergyt2->sem))
-		return;
+	flush_scheduled_work();
 
 	cinergyt2_unregister_rc(cinergyt2);
 
-	cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx);
-	dvb_net_release(&cinergyt2->dvbnet);
-	dvb_dmxdev_release(&cinergyt2->dmxdev);
-	dvb_dmx_release(&cinergyt2->demux);
-	dvb_unregister_device(cinergyt2->fedev);
-	dvb_unregister_adapter(&cinergyt2->adapter);
+	cancel_delayed_work(&cinergyt2->query_work);
+	wake_up_interruptible(&cinergyt2->poll_wq);
 
-	cinergyt2_free_stream_urbs(cinergyt2);
-	up(&cinergyt2->sem);
-	kfree(cinergyt2);
+	cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx);
+	cinergyt2->disconnect_pending = 1;
+
+	if (!atomic_read(&cinergyt2->inuse))
+		cinergyt2_unregister(cinergyt2);
 }
 
 static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state)
 {
 	struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
 
-	if (down_interruptible(&cinergyt2->sem))
+	if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
 		return -ERESTARTSYS;
 
 	if (state.event > PM_EVENT_ON) {
@@ -961,7 +990,7 @@
 	struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
 	struct dvbt_set_parameters_msg *param = &cinergyt2->param;
 
-	if (down_interruptible(&cinergyt2->sem))
+	if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem))
 		return -ERESTARTSYS;
 
 	if (!cinergyt2->sleeping) {
@@ -1014,4 +1043,3 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Holger Waechtler, Daniel Mack");
-
diff --git a/drivers/media/dvb/dvb-core/Kconfig b/drivers/media/dvb/dvb-core/Kconfig
index a9a7b34..12ee912 100644
--- a/drivers/media/dvb/dvb-core/Kconfig
+++ b/drivers/media/dvb/dvb-core/Kconfig
@@ -5,7 +5,7 @@
 	help
 	  DVB core utility functions for device handling, software fallbacks etc.
 	  Say Y when you have a DVB card and want to use it. Say Y if your want
-	  to build your drivers outside the kernel, but need the DVB core. All 
+	  to build your drivers outside the kernel, but need the DVB core. All
 	  in-kernel drivers will select this automatically if needed.
 	  If unsure say N.
 
diff --git a/drivers/media/dvb/dvb-core/Makefile b/drivers/media/dvb/dvb-core/Makefile
index c6baac2..7adb50c 100644
--- a/drivers/media/dvb/dvb-core/Makefile
+++ b/drivers/media/dvb/dvb-core/Makefile
@@ -3,7 +3,7 @@
 #
 
 dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \
-	        dvb_ca_en50221.o dvb_frontend.o \
+		dvb_ca_en50221.o dvb_frontend.o \
 		dvb_net.o dvb_ringbuffer.o
 
 obj-$(CONFIG_DVB_CORE) += dvb-core.o
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 5956c35..4bb779a 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -1745,9 +1745,7 @@
 
 	for (i = 0; i < ca->slot_count; i++) {
 		dvb_ca_en50221_slot_shutdown(ca, i);
-		if (ca->slot_info[i].rx_buffer.data != NULL) {
-			vfree(ca->slot_info[i].rx_buffer.data);
-		}
+		vfree(ca->slot_info[i].rx_buffer.data);
 	}
 	kfree(ca->slot_info);
 	dvb_unregister_device(ca->dvbdev);
diff --git a/drivers/media/dvb/dvb-core/dvb_filter.c b/drivers/media/dvb/dvb-core/dvb_filter.c
index c49fd0b..772003f 100644
--- a/drivers/media/dvb/dvb-core/dvb_filter.c
+++ b/drivers/media/dvb/dvb-core/dvb_filter.c
@@ -409,16 +409,16 @@
 
 	if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */
 		if (buf[7] & PTS_ONLY)
-		        pts = buf+9;
+			pts = buf+9;
 		else pts = NULL;
 		buf = inbuf + 9 + inbuf[8];
 	} else {        /* mpeg1 */
 		for (buf = inbuf + 6; *buf == 0xff; buf++)
-		        if (buf == inbuf + 6 + 16) {
-		                break;
-		        }
+			if (buf == inbuf + 6 + 16) {
+				break;
+			}
 		if ((*buf & 0xc0) == 0x40)
-		        buf += 2;
+			buf += 2;
 		skip = mpeg1_skip_table [*buf >> 4];
 		if (skip == 5 || skip == 10) pts = buf;
 		else pts = NULL;
@@ -529,9 +529,9 @@
 	pic->picture_header = 0;
 	pic->sequence_header_data
 		= ( INIT_HORIZONTAL_SIZE << 20 )
-		        | ( INIT_VERTICAL_SIZE << 8 )
-		        | ( INIT_ASPECT_RATIO << 4 )
-		        | ( INIT_FRAME_RATE );
+			| ( INIT_VERTICAL_SIZE << 8 )
+			| ( INIT_ASPECT_RATIO << 4 )
+			| ( INIT_FRAME_RATE );
 	pic->mpeg1_flag = 0;
 	pic->vinfo.horizontal_size
 		= INIT_DISP_HORIZONTAL_SIZE;
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 95ea509..4a08c4a 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -92,6 +92,7 @@
 
 struct dvb_frontend_private {
 
+	/* thread/frontend values */
 	struct dvb_device *dvbdev;
 	struct dvb_frontend_parameters parameters;
 	struct dvb_fe_events events;
@@ -100,20 +101,25 @@
 	wait_queue_head_t wait_queue;
 	pid_t thread_pid;
 	unsigned long release_jiffies;
-	int state;
-	int bending;
-	int lnb_drift;
-	int inversion;
-	int auto_step;
-	int auto_sub_step;
-	int started_auto_step;
-	int min_delay;
-	int max_drift;
-	int step_size;
-	int exit;
-	int wakeup;
+	unsigned int exit;
+	unsigned int wakeup;
 	fe_status_t status;
-	fe_sec_tone_mode_t tone;
+	unsigned long tune_mode_flags;
+	unsigned int delay;
+
+	/* swzigzag values */
+	unsigned int state;
+	unsigned int bending;
+	int lnb_drift;
+	unsigned int inversion;
+	unsigned int auto_step;
+	unsigned int auto_sub_step;
+	unsigned int started_auto_step;
+	unsigned int min_delay;
+	unsigned int max_drift;
+	unsigned int step_size;
+	int quality;
+	unsigned int check_wrapped;
 };
 
 
@@ -208,21 +214,21 @@
 		fe->ops->init(fe);
 }
 
-static void update_delay(int *quality, int *delay, int min_delay, int locked)
+static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked)
 {
-	    int q2;
+	int q2;
 
-	    dprintk ("%s\n", __FUNCTION__);
+	dprintk ("%s\n", __FUNCTION__);
 
-	    if (locked)
-		      (*quality) = (*quality * 220 + 36*256) / 256;
-	    else
-		      (*quality) = (*quality * 220 + 0) / 256;
+	if (locked)
+		(fepriv->quality) = (fepriv->quality * 220 + 36*256) / 256;
+	else
+		(fepriv->quality) = (fepriv->quality * 220 + 0) / 256;
 
-	    q2 = *quality - 128;
-	    q2 *= q2;
+	q2 = fepriv->quality - 128;
+	q2 *= q2;
 
-	    *delay = min_delay + q2 * HZ / (128*128);
+	fepriv->delay = fepriv->min_delay + q2 * HZ / (128*128);
 }
 
 /**
@@ -232,7 +238,7 @@
  * @param check_wrapped Checks if an iteration has completed. DO NOT SET ON THE FIRST ATTEMPT
  * @returns Number of complete iterations that have been performed.
  */
-static int dvb_frontend_autotune(struct dvb_frontend *fe, int check_wrapped)
+static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wrapped)
 {
 	int autoinversion;
 	int ready = 0;
@@ -321,6 +327,129 @@
 	return 0;
 }
 
+static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
+{
+	fe_status_t s;
+	struct dvb_frontend_private *fepriv = fe->frontend_priv;
+
+	/* if we've got no parameters, just keep idling */
+	if (fepriv->state & FESTATE_IDLE) {
+		fepriv->delay = 3*HZ;
+		fepriv->quality = 0;
+		return;
+	}
+
+	/* in SCAN mode, we just set the frontend when asked and leave it alone */
+	if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) {
+		if (fepriv->state & FESTATE_RETUNE) {
+			if (fe->ops->set_frontend)
+				fe->ops->set_frontend(fe, &fepriv->parameters);
+			fepriv->state = FESTATE_TUNED;
+		}
+		fepriv->delay = 3*HZ;
+		fepriv->quality = 0;
+		return;
+	}
+
+	/* get the frontend status */
+	if (fepriv->state & FESTATE_RETUNE) {
+		s = 0;
+	} else {
+		if (fe->ops->read_status)
+			fe->ops->read_status(fe, &s);
+		if (s != fepriv->status) {
+			dvb_frontend_add_event(fe, s);
+			fepriv->status = s;
+		}
+	}
+
+	/* if we're not tuned, and we have a lock, move to the TUNED state */
+	if ((fepriv->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) {
+		dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
+		fepriv->state = FESTATE_TUNED;
+
+		/* if we're tuned, then we have determined the correct inversion */
+		if ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) &&
+		    (fepriv->parameters.inversion == INVERSION_AUTO)) {
+			fepriv->parameters.inversion = fepriv->inversion;
+		}
+		return;
+	}
+
+	/* if we are tuned already, check we're still locked */
+	if (fepriv->state & FESTATE_TUNED) {
+		dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
+
+		/* we're tuned, and the lock is still good... */
+		if (s & FE_HAS_LOCK) {
+			return;
+		} else { /* if we _WERE_ tuned, but now don't have a lock */
+			fepriv->state = FESTATE_ZIGZAG_FAST;
+			fepriv->started_auto_step = fepriv->auto_step;
+			fepriv->check_wrapped = 0;
+		}
+	}
+
+	/* don't actually do anything if we're in the LOSTLOCK state,
+	 * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */
+	if ((fepriv->state & FESTATE_LOSTLOCK) &&
+	    (fe->ops->info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) {
+		dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
+		return;
+	}
+
+	/* don't do anything if we're in the DISEQC state, since this
+	 * might be someone with a motorized dish controlled by DISEQC.
+	 * If its actually a re-tune, there will be a SET_FRONTEND soon enough.	*/
+	if (fepriv->state & FESTATE_DISEQC) {
+		dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
+		return;
+	}
+
+	/* if we're in the RETUNE state, set everything up for a brand
+	 * new scan, keeping the current inversion setting, as the next
+	 * tune is _very_ likely to require the same */
+	if (fepriv->state & FESTATE_RETUNE) {
+		fepriv->lnb_drift = 0;
+		fepriv->auto_step = 0;
+		fepriv->auto_sub_step = 0;
+		fepriv->started_auto_step = 0;
+		fepriv->check_wrapped = 0;
+	}
+
+	/* fast zigzag. */
+	if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) {
+		fepriv->delay = fepriv->min_delay;
+
+		/* peform a tune */
+		if (dvb_frontend_swzigzag_autotune(fe, fepriv->check_wrapped)) {
+			/* OK, if we've run out of trials at the fast speed.
+			 * Drop back to slow for the _next_ attempt */
+			fepriv->state = FESTATE_SEARCHING_SLOW;
+			fepriv->started_auto_step = fepriv->auto_step;
+			return;
+		}
+		fepriv->check_wrapped = 1;
+
+		/* if we've just retuned, enter the ZIGZAG_FAST state.
+		 * This ensures we cannot return from an
+		 * FE_SET_FRONTEND ioctl before the first frontend tune
+		 * occurs */
+		if (fepriv->state & FESTATE_RETUNE) {
+			fepriv->state = FESTATE_TUNING_FAST;
+		}
+	}
+
+	/* slow zigzag */
+	if (fepriv->state & FESTATE_SEARCHING_SLOW) {
+		dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
+
+		/* Note: don't bother checking for wrapping; we stay in this
+		 * state until we get a lock */
+		dvb_frontend_swzigzag_autotune(fe, 0);
+	}
+}
+
 static int dvb_frontend_is_exiting(struct dvb_frontend *fe)
 {
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
@@ -330,7 +459,7 @@
 
 	if (fepriv->dvbdev->writers == 1)
 		if (time_after(jiffies, fepriv->release_jiffies +
-					dvb_shutdown_timeout * HZ))
+				  dvb_shutdown_timeout * HZ))
 			return 1;
 
 	return 0;
@@ -355,18 +484,14 @@
 	wake_up_interruptible(&fepriv->wait_queue);
 }
 
-/*
- * FIXME: use linux/kthread.h
- */
 static int dvb_frontend_thread(void *data)
 {
 	struct dvb_frontend *fe = data;
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 	unsigned long timeout;
 	char name [15];
-	int quality = 0, delay = 3*HZ;
 	fe_status_t s;
-	int check_wrapped = 0;
+	struct dvb_frontend_parameters *params;
 
 	dprintk("%s\n", __FUNCTION__);
 
@@ -377,6 +502,9 @@
 	sigfillset(&current->blocked);
 	unlock_kernel();
 
+	fepriv->check_wrapped = 0;
+	fepriv->quality = 0;
+	fepriv->delay = 3*HZ;
 	fepriv->status = 0;
 	dvb_frontend_init(fe);
 	fepriv->wakeup = 0;
@@ -386,7 +514,7 @@
 
 		timeout = wait_event_interruptible_timeout(fepriv->wait_queue,
 							   dvb_frontend_should_wakeup(fe),
-							   delay);
+							   fepriv->delay);
 		if (0 != dvb_frontend_is_exiting(fe)) {
 			/* got signal or quitting */
 			break;
@@ -397,108 +525,22 @@
 		if (down_interruptible(&fepriv->sem))
 			break;
 
-		/* if we've got no parameters, just keep idling */
-		if (fepriv->state & FESTATE_IDLE) {
-			delay = 3*HZ;
-			quality = 0;
-			continue;
-		}
+		/* do an iteration of the tuning loop */
+		if (fe->ops->tune) {
+			/* have we been asked to retune? */
+			params = NULL;
+			if (fepriv->state & FESTATE_RETUNE) {
+				params = &fepriv->parameters;
+				fepriv->state = FESTATE_TUNED;
+			}
 
-		/* get the frontend status */
-		if (fepriv->state & FESTATE_RETUNE) {
-			s = 0;
-		} else {
-			if (fe->ops->read_status)
-				fe->ops->read_status(fe, &s);
+			fe->ops->tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s);
 			if (s != fepriv->status) {
 				dvb_frontend_add_event(fe, s);
 				fepriv->status = s;
 			}
-		}
-		/* if we're not tuned, and we have a lock, move to the TUNED state */
-		if ((fepriv->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) {
-			update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
-			fepriv->state = FESTATE_TUNED;
-
-			/* if we're tuned, then we have determined the correct inversion */
-			if ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) &&
-			    (fepriv->parameters.inversion == INVERSION_AUTO)) {
-				fepriv->parameters.inversion = fepriv->inversion;
-			}
-			continue;
-		}
-
-		/* if we are tuned already, check we're still locked */
-		if (fepriv->state & FESTATE_TUNED) {
-			update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
-
-			/* we're tuned, and the lock is still good... */
-			if (s & FE_HAS_LOCK)
-				continue;
-			else { /* if we _WERE_ tuned, but now don't have a lock */
-				fepriv->state = FESTATE_ZIGZAG_FAST;
-				fepriv->started_auto_step = fepriv->auto_step;
-				check_wrapped = 0;
-			}
-		}
-
-		/* don't actually do anything if we're in the LOSTLOCK state,
-		 * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */
-		if ((fepriv->state & FESTATE_LOSTLOCK) &&
-		    (fe->ops->info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) {
-			update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
-			continue;
-		}
-
-		/* don't do anything if we're in the DISEQC state, since this
-		 * might be someone with a motorized dish controlled by DISEQC.
-		 * If its actually a re-tune, there will be a SET_FRONTEND soon enough.	*/
-		if (fepriv->state & FESTATE_DISEQC) {
-			update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
-			continue;
-		}
-
-		/* if we're in the RETUNE state, set everything up for a brand
-		 * new scan, keeping the current inversion setting, as the next
-		 * tune is _very_ likely to require the same */
-		if (fepriv->state & FESTATE_RETUNE) {
-			fepriv->lnb_drift = 0;
-			fepriv->auto_step = 0;
-			fepriv->auto_sub_step = 0;
-			fepriv->started_auto_step = 0;
-			check_wrapped = 0;
-		}
-
-		/* fast zigzag. */
-		if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) {
-			delay = fepriv->min_delay;
-
-			/* peform a tune */
-			if (dvb_frontend_autotune(fe, check_wrapped)) {
-				/* OK, if we've run out of trials at the fast speed.
-				 * Drop back to slow for the _next_ attempt */
-				fepriv->state = FESTATE_SEARCHING_SLOW;
-				fepriv->started_auto_step = fepriv->auto_step;
-				continue;
-			}
-			check_wrapped = 1;
-
-			/* if we've just retuned, enter the ZIGZAG_FAST state.
-			 * This ensures we cannot return from an
-			 * FE_SET_FRONTEND ioctl before the first frontend tune
-			 * occurs */
-			if (fepriv->state & FESTATE_RETUNE) {
-				fepriv->state = FESTATE_TUNING_FAST;
-			}
-		}
-
-		/* slow zigzag */
-		if (fepriv->state & FESTATE_SEARCHING_SLOW) {
-			update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK);
-
-			/* Note: don't bother checking for wrapping; we stay in this
-			 * state until we get a lock */
-			dvb_frontend_autotune(fe, 0);
+		} else {
+			dvb_frontend_swzigzag(fe);
 		}
 	}
 
@@ -733,7 +775,6 @@
 			err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg);
 			fepriv->state = FESTATE_DISEQC;
 			fepriv->status = 0;
-			fepriv->tone = (fe_sec_tone_mode_t) parg;
 		}
 		break;
 
@@ -747,7 +788,7 @@
 
 	case FE_DISHNETWORK_SEND_LEGACY_CMD:
 		if (fe->ops->dishnetwork_send_legacy_command) {
-			err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg);
+			err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned long) parg);
 			fepriv->state = FESTATE_DISEQC;
 			fepriv->status = 0;
 		} else if (fe->ops->set_voltage) {
@@ -767,13 +808,13 @@
 			 * initialization, so parg is 8 bits and does not
 			 * include the initialization or start bit
 			 */
-			unsigned int cmd = ((unsigned int) parg) << 1;
+			unsigned long cmd = ((unsigned long) parg) << 1;
 			struct timeval nexttime;
 			struct timeval tv[10];
 			int i;
 			u8 last = 1;
 			if (dvb_frontend_debug)
-				printk("%s switch command: 0x%04x\n", __FUNCTION__, cmd);
+				printk("%s switch command: 0x%04lx\n", __FUNCTION__, cmd);
 			do_gettimeofday(&nexttime);
 			if (dvb_frontend_debug)
 				memcpy(&tv[0], &nexttime, sizeof(struct timeval));
@@ -814,7 +855,7 @@
 
 	case FE_ENABLE_HIGH_LNB_VOLTAGE:
 		if (fe->ops->enable_high_lnb_voltage)
-			err = fe->ops->enable_high_lnb_voltage(fe, (int) parg);
+			err = fe->ops->enable_high_lnb_voltage(fe, (long) parg);
 		break;
 
 	case FE_SET_FRONTEND: {
@@ -891,6 +932,10 @@
 			err = fe->ops->get_frontend(fe, (struct dvb_frontend_parameters*) parg);
 		}
 		break;
+
+	case FE_SET_FRONTEND_TUNE_MODE:
+		fepriv->tune_mode_flags = (unsigned long) parg;
+		break;
 	};
 
 	up (&fepriv->sem);
@@ -932,6 +977,9 @@
 
 		/*  empty event queue */
 		fepriv->events.eventr = fepriv->events.eventw = 0;
+
+		/* normal tune mode when opened R/W */
+		fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT;
 	}
 
 	return ret;
@@ -990,7 +1038,6 @@
 	init_MUTEX (&fepriv->events.sem);
 	fe->dvb = dvb;
 	fepriv->inversion = INVERSION_OFF;
-	fepriv->tone = SEC_TONE_OFF;
 
 	printk ("DVB: registering frontend %i (%s)...\n",
 		fe->dvb->num,
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index 1e0840d..70a6d14 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -58,10 +58,19 @@
 	int (*init)(struct dvb_frontend* fe);
 	int (*sleep)(struct dvb_frontend* fe);
 
+	/* if this is set, it overrides the default swzigzag */
+	int (*tune)(struct dvb_frontend* fe,
+		    struct dvb_frontend_parameters* params,
+		    unsigned int mode_flags,
+		    int *delay,
+		    fe_status_t *status);
+
+	/* these two are only used for the swzigzag code */
 	int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
-	int (*get_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
 	int (*get_tune_settings)(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings);
 
+	int (*get_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
+
 	int (*read_status)(struct dvb_frontend* fe, fe_status_t* status);
 	int (*read_ber)(struct dvb_frontend* fe, u32* ber);
 	int (*read_signal_strength)(struct dvb_frontend* fe, u16* strength);
@@ -74,8 +83,9 @@
 	int (*diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd);
 	int (*set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone);
 	int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
-	int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, int arg);
-	int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned int cmd);
+	int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg);
+	int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd);
+	int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable);
 };
 
 #define MAX_EVENT 8
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index 86bba81..6711eb6 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -1222,7 +1222,7 @@
 	return if_num;
 }
 
-static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned int num)
+static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned long num)
 {
 	struct net_device *net = dvbnet->device[num];
 	struct dvb_net_priv *priv;
@@ -1296,9 +1296,9 @@
 
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
-		if ((unsigned int) parg >= DVB_NET_DEVICES_MAX)
+		if ((unsigned long) parg >= DVB_NET_DEVICES_MAX)
 			return -EINVAL;
-		ret = dvb_net_remove_if(dvbnet, (unsigned int) parg);
+		ret = dvb_net_remove_if(dvbnet, (unsigned long) parg);
 		if (!ret)
 			module_put(dvbdev->adapter->module);
 		return ret;
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
index 283c6e9..77ad241 100644
--- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
@@ -112,10 +112,10 @@
 	split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0;
 	if (split > 0) {
 		if (!usermem)
-		        memcpy(buf, rbuf->data+rbuf->pread, split);
+			memcpy(buf, rbuf->data+rbuf->pread, split);
 		else
-		        if (copy_to_user(buf, rbuf->data+rbuf->pread, split))
-		                return -EFAULT;
+			if (copy_to_user(buf, rbuf->data+rbuf->pread, split))
+				return -EFAULT;
 		buf += split;
 		todo -= split;
 		rbuf->pread = 0;
@@ -124,7 +124,7 @@
 		memcpy(buf, rbuf->data+rbuf->pread, todo);
 	else
 		if (copy_to_user(buf, rbuf->data+rbuf->pread, todo))
-		        return -EFAULT;
+			return -EFAULT;
 
 	rbuf->pread = (rbuf->pread + todo) % rbuf->size;
 
@@ -167,7 +167,7 @@
 }
 
 ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
-		                int offset, u8* buf, size_t len, int usermem)
+				int offset, u8* buf, size_t len, int usermem)
 {
 	size_t todo;
 	size_t split;
@@ -183,10 +183,10 @@
 	split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0;
 	if (split > 0) {
 		if (!usermem)
-		        memcpy(buf, rbuf->data+idx, split);
+			memcpy(buf, rbuf->data+idx, split);
 		else
-		        if (copy_to_user(buf, rbuf->data+idx, split))
-		                return -EFAULT;
+			if (copy_to_user(buf, rbuf->data+idx, split))
+				return -EFAULT;
 		buf += split;
 		todo -= split;
 		idx = 0;
@@ -195,7 +195,7 @@
 		memcpy(buf, rbuf->data+idx, todo);
 	else
 		if (copy_to_user(buf, rbuf->data+idx, todo))
-		        return -EFAULT;
+			return -EFAULT;
 
 	return len;
 }
@@ -209,12 +209,12 @@
 	// clean up disposed packets
 	while(dvb_ringbuffer_avail(rbuf) > DVB_RINGBUFFER_PKTHDRSIZE) {
 		if (DVB_RINGBUFFER_PEEK(rbuf, 2) == PKT_DISPOSED) {
-		        pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8;
-		        pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1);
-		        DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE);
+			pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8;
+			pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1);
+			DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE);
 		} else {
-		        // first packet is not disposed, so we stop cleaning now
-		        break;
+			// first packet is not disposed, so we stop cleaning now
+			break;
 		}
 	}
 }
@@ -242,8 +242,8 @@
 		curpktstatus = rbuf->data[(idx + 2) % rbuf->size];
 
 		if (curpktstatus == PKT_READY) {
-		        *pktlen = curpktlen;
-		        return idx;
+			*pktlen = curpktlen;
+			return idx;
 		}
 
 		consumed += curpktlen + DVB_RINGBUFFER_PKTHDRSIZE;
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
index fa476f6..6d25609 100644
--- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
@@ -106,7 +106,7 @@
 ** returns number of bytes transferred or -EFAULT
 */
 extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf,
-		                   size_t len, int usermem);
+				   size_t len, int usermem);
 
 
 /* write routines & macros */
@@ -121,7 +121,7 @@
 ** returns number of bytes transferred or -EFAULT
 */
 extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf,
-		                    size_t len);
+				    size_t len);
 
 
 /**
@@ -133,7 +133,7 @@
  * returns Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL.
  */
 extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf,
-		                        size_t len);
+					size_t len);
 
 /**
  * Read from a packet in the ringbuffer. Note: unlike dvb_ringbuffer_read(), this
@@ -149,7 +149,7 @@
  * returns Number of bytes read, or -EFAULT.
  */
 extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
-		                       int offset, u8* buf, size_t len, int usermem);
+				       int offset, u8* buf, size_t len, int usermem);
 
 /**
  * Dispose of a packet in the ring buffer.
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index a4aee86..06b696e 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -92,10 +92,10 @@
 		old_fops = file->f_op;
 		file->f_op = fops_get(dvbdev->fops);
 		if(file->f_op->open)
-		        err = file->f_op->open(inode,file);
+			err = file->f_op->open(inode,file);
 		if (err) {
-		        fops_put(file->f_op);
-		        file->f_op = fops_get(old_fops);
+			fops_put(file->f_op);
+			file->f_op = fops_get(old_fops);
 		}
 		fops_put(old_fops);
 		return err;
@@ -356,18 +356,18 @@
 	case _IOC_WRITE:
 	case (_IOC_WRITE | _IOC_READ):
 		if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
-		        parg = sbuf;
+			parg = sbuf;
 		} else {
-		        /* too big to allocate from stack */
-		        mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
-		        if (NULL == mbuf)
-		                return -ENOMEM;
-		        parg = mbuf;
+			/* too big to allocate from stack */
+			mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
+			if (NULL == mbuf)
+				return -ENOMEM;
+			parg = mbuf;
 		}
 
 		err = -EFAULT;
 		if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
-		        goto out;
+			goto out;
 		break;
 	}
 
@@ -384,7 +384,7 @@
 	case _IOC_READ:
 	case (_IOC_WRITE | _IOC_READ):
 		if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
-		        err = -EFAULT;
+			err = -EFAULT;
 		break;
 	}
 
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index 0cc6e4a..74ed585 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -97,7 +97,7 @@
 generic_usercopy()  someday... */
 
 extern int dvb_usercopy(struct inode *inode, struct file *file,
-		            unsigned int cmd, unsigned long arg,
+			    unsigned int cmd, unsigned long arg,
 			    int (*func)(struct inode *inode, struct file *file,
 			    unsigned int cmd, void *arg));
 
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 54e2b29..90a69d3 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -37,16 +37,16 @@
 	  DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
 
 	  Devices supported by this driver:
-	    TwinhanDTV USB-Ter (VP7041)
-	    TwinhanDTV Magic Box (VP7041e)
-	    KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0
-	    Hama DVB-T USB1.1-Box
-	    DiBcom USB1.1 reference devices (non-public)
-	    Ultima Electronic/Artec T1 USB TVBOX
-	    Compro Videomate DVB-U2000 - DVB-T USB
-	    Grandtec DVB-T USB
-	    Avermedia AverTV DVBT USB1.1
 	    Artec T1 USB1.1 boxes
+	    Avermedia AverTV DVBT USB1.1
+	    Compro Videomate DVB-U2000 - DVB-T USB
+	    DiBcom USB1.1 reference devices (non-public)
+	    Grandtec DVB-T USB
+	    Hama DVB-T USB1.1-Box
+	    KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0
+	    TwinhanDTV Magic Box (VP7041e)
+	    TwinhanDTV USB-Ter (VP7041)
+	    Ultima Electronic/Artec T1 USB TVBOX
 
 	  The VP7041 seems to be identical to "CTS Portable" (Chinese
 	  Television System).
@@ -54,6 +54,12 @@
 	  Say Y if you own such a device and want to use it. You should build it as
 	  a module.
 
+config DVB_USB_DIBUSB_MB_FAULTY
+	bool "Support faulty USB IDs"
+	depends on DVB_USB_DIBUSB_MB
+	help
+	  Support for faulty USB IDs due to an invalid EEPROM on some Artec devices.
+
 config DVB_USB_DIBUSB_MC
 	tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
 	depends on DVB_USB
@@ -63,8 +69,8 @@
 	  DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
 
 	  Devices supported by this driver:
-	    DiBcom USB2.0 reference devices (non-public)
 	    Artec T1 USB2.0 boxes
+	    DiBcom USB2.0 reference devices (non-public)
 
 	  Say Y if you own such a device and want to use it. You should build it as
 	  a module.
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index d05fab01..358ed15 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -11,10 +11,11 @@
  * design, so it can be reused for the "analogue-only" device (if it will
  * appear at all).
  *
- * TODO: check if the cx25840-driver (from ivtv) can be used for the analogue
- * part
+ * TODO: Use the cx25840-driver for the analogue part
  *
  * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
+ * Copyright (C) 2005 Michael Krufky (mkrufky@m1k.net)
+ * Copyright (C) 2006 Chris Pascoe (c.pascoe@itee.uq.edu.au)
  *
  *	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
@@ -25,6 +26,9 @@
 #include "cxusb.h"
 
 #include "cx22702.h"
+#include "lgdt330x.h"
+#include "mt352.h"
+#include "mt352_priv.h"
 
 /* debug */
 int dvb_usb_cxusb_debug;
@@ -156,6 +160,99 @@
 	return 0;
 }
 
+static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+	struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
+	u8 ircode[4];
+	int i;
+
+	cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4);
+
+	*event = 0;
+	*state = REMOTE_NO_KEY_PRESSED;
+
+	for (i = 0; i < d->props.rc_key_map_size; i++) {
+		if (keymap[i].custom == ircode[2] &&
+		    keymap[i].data == ircode[3]) {
+			*event = keymap[i].event;
+			*state = REMOTE_KEY_PRESSED;
+
+			return 0;
+		}
+	}
+
+	return 0;
+}
+
+struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
+	{ 0xfe, 0x02, KEY_TV },
+	{ 0xfe, 0x0e, KEY_MP3 },
+	{ 0xfe, 0x1a, KEY_DVD },
+	{ 0xfe, 0x1e, KEY_FAVORITES },
+	{ 0xfe, 0x16, KEY_SETUP },
+	{ 0xfe, 0x46, KEY_POWER2 },
+	{ 0xfe, 0x0a, KEY_EPG },
+	{ 0xfe, 0x49, KEY_BACK },
+	{ 0xfe, 0x4d, KEY_MENU },
+	{ 0xfe, 0x51, KEY_UP },
+	{ 0xfe, 0x5b, KEY_LEFT },
+	{ 0xfe, 0x5f, KEY_RIGHT },
+	{ 0xfe, 0x53, KEY_DOWN },
+	{ 0xfe, 0x5e, KEY_OK },
+	{ 0xfe, 0x59, KEY_INFO },
+	{ 0xfe, 0x55, KEY_TAB },
+	{ 0xfe, 0x0f, KEY_PREVIOUSSONG },/* Replay */
+	{ 0xfe, 0x12, KEY_NEXTSONG },	/* Skip */
+	{ 0xfe, 0x42, KEY_ENTER	 },	/* Windows/Start */
+	{ 0xfe, 0x15, KEY_VOLUMEUP },
+	{ 0xfe, 0x05, KEY_VOLUMEDOWN },
+	{ 0xfe, 0x11, KEY_CHANNELUP },
+	{ 0xfe, 0x09, KEY_CHANNELDOWN },
+	{ 0xfe, 0x52, KEY_CAMERA },
+	{ 0xfe, 0x5a, KEY_TUNER },	/* Live */
+	{ 0xfe, 0x19, KEY_OPEN },
+	{ 0xfe, 0x0b, KEY_1 },
+	{ 0xfe, 0x17, KEY_2 },
+	{ 0xfe, 0x1b, KEY_3 },
+	{ 0xfe, 0x07, KEY_4 },
+	{ 0xfe, 0x50, KEY_5 },
+	{ 0xfe, 0x54, KEY_6 },
+	{ 0xfe, 0x48, KEY_7 },
+	{ 0xfe, 0x4c, KEY_8 },
+	{ 0xfe, 0x58, KEY_9 },
+	{ 0xfe, 0x13, KEY_ANGLE },	/* Aspect */
+	{ 0xfe, 0x03, KEY_0 },
+	{ 0xfe, 0x1f, KEY_ZOOM },
+	{ 0xfe, 0x43, KEY_REWIND },
+	{ 0xfe, 0x47, KEY_PLAYPAUSE },
+	{ 0xfe, 0x4f, KEY_FASTFORWARD },
+	{ 0xfe, 0x57, KEY_MUTE },
+	{ 0xfe, 0x0d, KEY_STOP },
+	{ 0xfe, 0x01, KEY_RECORD },
+	{ 0xfe, 0x4e, KEY_POWER },
+};
+
+static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
+{
+	static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x38 };
+	static u8 reset []         = { RESET,      0x80 };
+	static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
+	static u8 agc_cfg []       = { AGC_TARGET, 0x28, 0x20 };
+	static u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
+	static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
+
+	mt352_write(fe, clock_config,   sizeof(clock_config));
+	udelay(200);
+	mt352_write(fe, reset,          sizeof(reset));
+	mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
+
+	mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
+	mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
+	mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
+
+	return 0;
+}
+
 struct cx22702_config cxusb_cx22702_config = {
 	.demod_address = 0x63,
 
@@ -165,17 +262,47 @@
 	.pll_set  = dvb_usb_pll_set_i2c,
 };
 
+struct lgdt330x_config cxusb_lgdt330x_config = {
+	.demod_address = 0x0e,
+	.demod_chip    = LGDT3303,
+	.pll_set       = dvb_usb_pll_set_i2c,
+};
+
+struct mt352_config cxusb_dee1601_config = {
+	.demod_address = 0x0f,
+	.demod_init    = cxusb_dee1601_demod_init,
+	.pll_set       = dvb_usb_pll_set,
+};
+
 /* Callbacks for DVB USB */
-static int cxusb_tuner_attach(struct dvb_usb_device *d)
+static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_device *d)
 {
 	u8 bpll[4] = { 0x0b, 0xdc, 0x9c, 0xa0 };
 	d->pll_addr = 0x61;
-	memcpy(d->pll_init,bpll,4);
+	memcpy(d->pll_init, bpll, 4);
 	d->pll_desc = &dvb_pll_fmd1216me;
 	return 0;
 }
 
-static int cxusb_frontend_attach(struct dvb_usb_device *d)
+static int cxusb_lgh064f_tuner_attach(struct dvb_usb_device *d)
+{
+	u8 bpll[4] = { 0x00, 0x00, 0x18, 0x50 };
+	/* bpll[2] : unset bit 3, set bits 4&5
+	   bpll[3] : 0x50 - digital, 0x20 - analog */
+	d->pll_addr = 0x61;
+	memcpy(d->pll_init, bpll, 4);
+	d->pll_desc = &dvb_pll_tdvs_tua6034;
+	return 0;
+}
+
+static int cxusb_dee1601_tuner_attach(struct dvb_usb_device *d)
+{
+	d->pll_addr = 0x61;
+	d->pll_desc = &dvb_pll_thomson_dtt7579;
+	return 0;
+}
+
+static int cxusb_cx22702_frontend_attach(struct dvb_usb_device *d)
 {
 	u8 b;
 	if (usb_set_interface(d->udev,0,6) < 0)
@@ -189,22 +316,84 @@
 	return -EIO;
 }
 
+static int cxusb_lgdt330x_frontend_attach(struct dvb_usb_device *d)
+{
+	if (usb_set_interface(d->udev,0,7) < 0)
+		err("set interface failed");
+
+	cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0);
+
+	if ((d->fe = lgdt330x_attach(&cxusb_lgdt330x_config, &d->i2c_adap)) != NULL)
+		return 0;
+
+	return -EIO;
+}
+
+static int cxusb_dee1601_frontend_attach(struct dvb_usb_device *d)
+{
+	if (usb_set_interface(d->udev,0,0) < 0)
+		err("set interface failed");
+
+	cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0);
+
+	if ((d->fe = mt352_attach(&cxusb_dee1601_config, &d->i2c_adap)) != NULL)
+		return 0;
+
+	return -EIO;
+}
+
+/*
+ * DViCO bluebird firmware needs the "warm" product ID to be patched into the
+ * firmware file before download.
+ */
+
+#define BLUEBIRD_01_ID_OFFSET 6638
+static int bluebird_patch_dvico_firmware_download(struct usb_device *udev, const struct firmware *fw)
+{
+	if (fw->size < BLUEBIRD_01_ID_OFFSET + 4)
+		return -EINVAL;
+
+	if (fw->data[BLUEBIRD_01_ID_OFFSET] == (USB_VID_DVICO & 0xff) &&
+	    fw->data[BLUEBIRD_01_ID_OFFSET + 1] == USB_VID_DVICO >> 8) {
+
+		/* FIXME: are we allowed to change the fw-data ? */
+		fw->data[BLUEBIRD_01_ID_OFFSET + 2] = udev->descriptor.idProduct + 1;
+		fw->data[BLUEBIRD_01_ID_OFFSET + 3] = udev->descriptor.idProduct >> 8;
+
+		return usb_cypress_load_firmware(udev,fw,CYPRESS_FX2);
+	}
+
+	return -EINVAL;
+}
+
 /* DVB USB Driver stuff */
-static struct dvb_usb_properties cxusb_properties;
+static struct dvb_usb_properties cxusb_medion_properties;
+static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties;
+static struct dvb_usb_properties cxusb_bluebird_dee1601_properties;
 
 static int cxusb_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
 {
-	return dvb_usb_device_init(intf,&cxusb_properties,THIS_MODULE,NULL);
+	if (dvb_usb_device_init(intf,&cxusb_medion_properties,THIS_MODULE,NULL) == 0 ||
+		dvb_usb_device_init(intf,&cxusb_bluebird_lgh064f_properties,THIS_MODULE,NULL) == 0 ||
+		dvb_usb_device_init(intf,&cxusb_bluebird_dee1601_properties,THIS_MODULE,NULL) == 0) {
+		return 0;
+	}
+
+	return -EINVAL;
 }
 
 static struct usb_device_id cxusb_table [] = {
 		{ USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
+		{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
+		{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) },
+		{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DEE1601_COLD) },
+		{ USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DEE1601_WARM) },
 		{}		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE (usb, cxusb_table);
 
-static struct dvb_usb_properties cxusb_properties = {
+static struct dvb_usb_properties cxusb_medion_properties = {
 	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
 	.usb_ctrl = CYPRESS_FX2,
@@ -213,8 +402,8 @@
 
 	.streaming_ctrl   = cxusb_streaming_ctrl,
 	.power_ctrl       = cxusb_power_ctrl,
-	.frontend_attach  = cxusb_frontend_attach,
-	.tuner_attach     = cxusb_tuner_attach,
+	.frontend_attach  = cxusb_cx22702_frontend_attach,
+	.tuner_attach     = cxusb_fmd1216me_tuner_attach,
 
 	.i2c_algo         = &cxusb_i2c_algo,
 
@@ -240,6 +429,91 @@
 	}
 };
 
+static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+	.usb_ctrl          = DEVICE_SPECIFIC,
+	.firmware          = "dvb-usb-bluebird-01.fw",
+	.download_firmware = bluebird_patch_dvico_firmware_download,
+	/* use usb alt setting 0 for EP4 transfer (dvb-t),
+	   use usb alt setting 7 for EP2 transfer (atsc) */
+
+	.size_of_priv     = sizeof(struct cxusb_state),
+
+	.streaming_ctrl   = cxusb_streaming_ctrl,
+	.power_ctrl       = cxusb_power_ctrl,
+	.frontend_attach  = cxusb_lgdt330x_frontend_attach,
+	.tuner_attach     = cxusb_lgh064f_tuner_attach,
+
+	.i2c_algo         = &cxusb_i2c_algo,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+	/* parameter for the MPEG2-data transfer */
+	.urb = {
+		.type = DVB_USB_BULK,
+		.count = 5,
+		.endpoint = 0x02,
+		.u = {
+			.bulk = {
+				.buffersize = 8192,
+			}
+		}
+	},
+
+	.num_device_descs = 1,
+	.devices = {
+		{   "DViCO FusionHDTV5 USB Gold",
+			{ &cxusb_table[1], NULL },
+			{ &cxusb_table[2], NULL },
+		},
+	}
+};
+
+static struct dvb_usb_properties cxusb_bluebird_dee1601_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+	.usb_ctrl          = DEVICE_SPECIFIC,
+	.firmware          = "dvb-usb-bluebird-01.fw",
+	.download_firmware = bluebird_patch_dvico_firmware_download,
+	/* use usb alt setting 0 for EP4 transfer (dvb-t),
+	   use usb alt setting 7 for EP2 transfer (atsc) */
+
+	.size_of_priv     = sizeof(struct cxusb_state),
+
+	.streaming_ctrl   = cxusb_streaming_ctrl,
+	.power_ctrl       = cxusb_power_ctrl,
+	.frontend_attach  = cxusb_dee1601_frontend_attach,
+	.tuner_attach     = cxusb_dee1601_tuner_attach,
+
+	.i2c_algo         = &cxusb_i2c_algo,
+
+	.rc_interval      = 150,
+	.rc_key_map       = dvico_mce_rc_keys,
+	.rc_key_map_size  = ARRAY_SIZE(dvico_mce_rc_keys),
+	.rc_query         = cxusb_rc_query,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+	/* parameter for the MPEG2-data transfer */
+	.urb = {
+		.type = DVB_USB_BULK,
+		.count = 5,
+		.endpoint = 0x04,
+		.u = {
+			.bulk = {
+				.buffersize = 8192,
+			}
+		}
+	},
+
+	.num_device_descs = 1,
+	.devices = {
+		{   "DViCO FusionHDTV DVB-T Dual USB",
+			{ &cxusb_table[3], NULL },
+			{ &cxusb_table[4], NULL },
+		},
+	}
+};
+
 static struct usb_driver cxusb_driver = {
 	.name		= "dvb_usb_cxusb",
 	.probe		= cxusb_probe,
diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h
index 135c2a8..087c994 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.h
+++ b/drivers/media/dvb/dvb-usb/cxusb.h
@@ -21,6 +21,8 @@
 #define CMD_STREAMING_ON  0x36
 #define CMD_STREAMING_OFF 0x37
 
+#define CMD_GET_IR_CODE   0x47
+
 #define CMD_ANALOG        0x50
 #define CMD_DIGITAL       0x51
 
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index 52ac3e5..dd5a131 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -65,11 +65,11 @@
 		d->tuner_pass_ctrl(d->fe,0,msg[0].addr);
 
 	if (b2[0] == 0xfe) {
-		info("this device has the Thomson Cable onboard. Which is default.");
+		info("This device has the Thomson Cable onboard. Which is default.");
 		dibusb_thomson_tuner_attach(d);
 	} else {
 		u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab };
-		info("this device has the Panasonic ENV77H11D5 onboard.");
+		info("This device has the Panasonic ENV77H11D5 onboard.");
 		d->pll_addr = 0x60;
 		memcpy(d->pll_init,bpll,4);
 		d->pll_desc = &dvb_pll_tda665x;
@@ -98,15 +98,15 @@
 
 /* do not change the order of the ID table */
 static struct usb_device_id dibusb_dib3000mb_table [] = {
-/* 00 */	{ USB_DEVICE(USB_VID_WIDEVIEW,		USB_PID_AVERMEDIA_DVBT_USB_COLD)},
-/* 01 */	{ USB_DEVICE(USB_VID_WIDEVIEW,		USB_PID_AVERMEDIA_DVBT_USB_WARM)},
+/* 00 */	{ USB_DEVICE(USB_VID_WIDEVIEW,		USB_PID_AVERMEDIA_DVBT_USB_COLD) },
+/* 01 */	{ USB_DEVICE(USB_VID_WIDEVIEW,		USB_PID_AVERMEDIA_DVBT_USB_WARM) },
 /* 02 */	{ USB_DEVICE(USB_VID_COMPRO,		USB_PID_COMPRO_DVBU2000_COLD) },
 /* 03 */	{ USB_DEVICE(USB_VID_COMPRO,		USB_PID_COMPRO_DVBU2000_WARM) },
 /* 04 */	{ USB_DEVICE(USB_VID_COMPRO_UNK,	USB_PID_COMPRO_DVBU2000_UNK_COLD) },
 /* 05 */	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3000_COLD) },
 /* 06 */	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3000_WARM) },
-/* 07 */	{ USB_DEVICE(USB_VID_EMPIA,			USB_PID_KWORLD_VSTREAM_COLD) },
-/* 08 */	{ USB_DEVICE(USB_VID_EMPIA,			USB_PID_KWORLD_VSTREAM_WARM) },
+/* 07 */	{ USB_DEVICE(USB_VID_EMPIA,		USB_PID_KWORLD_VSTREAM_COLD) },
+/* 08 */	{ USB_DEVICE(USB_VID_EMPIA,		USB_PID_KWORLD_VSTREAM_WARM) },
 /* 09 */	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_GRANDTEC_DVBT_USB_COLD) },
 /* 10 */	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_GRANDTEC_DVBT_USB_WARM) },
 /* 11 */	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_DIBCOM_MOD3000_COLD) },
@@ -117,27 +117,34 @@
 /* 16 */	{ USB_DEVICE(USB_VID_VISIONPLUS,	USB_PID_TWINHAN_VP7041_WARM) },
 /* 17 */	{ USB_DEVICE(USB_VID_TWINHAN,		USB_PID_TWINHAN_VP7041_COLD) },
 /* 18 */	{ USB_DEVICE(USB_VID_TWINHAN,		USB_PID_TWINHAN_VP7041_WARM) },
-/* 19 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
-/* 20 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
-/* 21 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
-/* 22 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
+/* 19 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC,	USB_PID_ULTIMA_TVBOX_COLD) },
+/* 20 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC,	USB_PID_ULTIMA_TVBOX_WARM) },
+/* 21 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC,	USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
+/* 22 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC,	USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
 /* 23 */	{ USB_DEVICE(USB_VID_ADSTECH,		USB_PID_ADSTECH_USB2_COLD) },
 
 /* device ID with default DIBUSB2_0-firmware and with the hacked firmware */
 /* 24 */	{ USB_DEVICE(USB_VID_ADSTECH,		USB_PID_ADSTECH_USB2_WARM) },
-/* 25 */	{ USB_DEVICE(USB_VID_KYE,			USB_PID_KYE_DVB_T_COLD) },
-/* 26 */	{ USB_DEVICE(USB_VID_KYE,			USB_PID_KYE_DVB_T_WARM) },
+/* 25 */	{ USB_DEVICE(USB_VID_KYE,		USB_PID_KYE_DVB_T_COLD) },
+/* 26 */	{ USB_DEVICE(USB_VID_KYE,		USB_PID_KYE_DVB_T_WARM) },
 
 /* 27 */	{ USB_DEVICE(USB_VID_KWORLD,		USB_PID_KWORLD_VSTREAM_COLD) },
 
-/* 28 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC,		USB_PID_ULTIMA_TVBOX_USB2_COLD) },
-/* 29 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC,		USB_PID_ULTIMA_TVBOX_USB2_WARM) },
+/* 28 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC,	USB_PID_ULTIMA_TVBOX_USB2_COLD) },
+/* 29 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC,	USB_PID_ULTIMA_TVBOX_USB2_WARM) },
 
-// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
+/*
+ * XXX: As Artec just 'forgot' to program the EEPROM on some Artec T1 devices
+ *      we don't catch these faulty IDs (namely 'Cypress FX1 USB controller') that
+ *      have been left on the device. If you don't have such a device but an Artec
+ *      device that's supposed to work with this driver but is not detected by it,
+ *      free to enable CONFIG_DVB_USB_DIBUSB_MB_FAULTY via your kernel config.
+ */
 
-#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
+#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
 /* 30 */	{ USB_DEVICE(USB_VID_ANCHOR,		USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
 #endif
+
 			{ }		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table);
@@ -257,7 +264,7 @@
 		}
 	},
 
-#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
+#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
 	.num_device_descs = 2,
 #else
 	.num_device_descs = 1,
@@ -267,11 +274,12 @@
 			{ &dibusb_dib3000mb_table[20], NULL },
 			{ &dibusb_dib3000mb_table[21], NULL },
 		},
-#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
+#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
 		{	"Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
 			{ &dibusb_dib3000mb_table[30], NULL },
 			{ NULL },
 		},
+		{ NULL },
 #endif
 	}
 };
@@ -323,6 +331,7 @@
 			{ &dibusb_dib3000mb_table[27], NULL },
 			{ NULL }
 		},
+		{ NULL },
 	}
 };
 
@@ -369,6 +378,7 @@
 			{ &dibusb_dib3000mb_table[28], NULL },
 			{ &dibusb_dib3000mb_table[29], NULL },
 		},
+		{ NULL },
 	}
 };
 
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
index 450417a..e6c55c9 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -32,7 +32,7 @@
 	sndbuf[1] = vv;
 	sndbuf[2] = wo ? wlen : rlen;
 
-	if (!wo) {
+	if (wo) {
 		memcpy(&sndbuf[3],wbuf,wlen);
 		dvb_usb_generic_write(d,sndbuf,7);
 	} else {
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
index 6e2bac8..130ea7f 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -151,7 +151,7 @@
 		  .cold_ids = { &dtt200u_usb_table[0], NULL },
 		  .warm_ids = { &dtt200u_usb_table[1], NULL },
 		},
-		{ NULL },
+		{ 0 },
 	}
 };
 
@@ -160,7 +160,7 @@
 	.pid_filter_count = 15,
 
 	.usb_ctrl = CYPRESS_FX2,
-	.firmware = "dvb-usb-wt220u-01.fw",
+	.firmware = "dvb-usb-wt220u-02.fw",
 
 	.power_ctrl      = dtt200u_power_ctrl,
 	.streaming_ctrl  = dtt200u_streaming_ctrl,
@@ -192,7 +192,7 @@
 		  .cold_ids = { &dtt200u_usb_table[2], NULL },
 		  .warm_ids = { &dtt200u_usb_table[3], NULL },
 		},
-		{ NULL },
+		{ 0 },
 	}
 };
 
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.h b/drivers/media/dvb/dvb-usb/dtt200u.h
index 6f1f304..005b0a7 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.h
+++ b/drivers/media/dvb/dvb-usb/dtt200u.h
@@ -13,6 +13,7 @@
 #define _DVB_USB_DTT200U_H_
 
 #define DVB_USB_LOG_PREFIX "dtt200u"
+
 #include "dvb-usb.h"
 
 extern int dvb_usb_dtt200u_debug;
@@ -25,15 +26,15 @@
  *  88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal)
  */
 
-#define GET_SPEED            0x00
-#define GET_TUNE_STATUS      0x81
-#define GET_RC_CODE          0x84
-#define GET_CONFIGURATION    0x88
-#define GET_AGC              0x89
-#define GET_SNR              0x8a
-#define GET_VIT_ERR_CNT      0x8c
-#define GET_RS_ERR_CNT       0x8d
-#define GET_RS_UNCOR_BLK_CNT 0x8e
+#define GET_SPEED		0x00
+#define GET_TUNE_STATUS		0x81
+#define GET_RC_CODE		0x84
+#define GET_CONFIGURATION	0x88
+#define GET_AGC			0x89
+#define GET_SNR			0x8a
+#define GET_VIT_ERR_CNT		0x8c
+#define GET_RS_ERR_CNT		0x8d
+#define GET_RS_UNCOR_BLK_CNT	0x8e
 
 /* write
  *  01 - init
@@ -44,12 +45,12 @@
  *  08 - transfer switch
  */
 
-#define SET_INIT         0x01
-#define SET_RF_FREQ      0x02
-#define SET_BANDWIDTH    0x03
-#define SET_PID_FILTER   0x04
-#define RESET_PID_FILTER 0x05
-#define SET_STREAMING    0x08
+#define SET_INIT		0x01
+#define SET_RF_FREQ		0x02
+#define SET_BANDWIDTH		0x03
+#define SET_PID_FILTER		0x04
+#define RESET_PID_FILTER	0x05
+#define SET_STREAMING		0x08
 
 extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d);
 
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
index 7300489..a3460bf 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-common.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
@@ -24,7 +24,7 @@
 #define deb_mem(args...)  dprintk(dvb_usb_debug,0x80,args)
 
 /* commonly used  methods */
-extern int usb_cypress_load_firmware(struct usb_device *, const char *, int);
+extern int dvb_usb_download_firmware(struct usb_device *, struct dvb_usb_properties *);
 
 extern int dvb_usb_urb_submit(struct dvb_usb_device *);
 extern int dvb_usb_urb_kill(struct dvb_usb_device *);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
index 5244e39..8535895 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
@@ -9,7 +9,6 @@
  */
 #include "dvb-usb-common.h"
 
-#include <linux/firmware.h>
 #include <linux/usb.h>
 
 struct usb_cypress_controller {
@@ -19,9 +18,10 @@
 };
 
 static struct usb_cypress_controller cypress[] = {
-	{ .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 },
-	{ .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 },
-	{ .id = CYPRESS_FX2,    .name = "Cypress FX2",    .cpu_cs_register = 0xe600 },
+	{ .id = DEVICE_SPECIFIC, .name = "Device specific", .cpu_cs_register = 0 },
+	{ .id = CYPRESS_AN2135,  .name = "Cypress AN2135",  .cpu_cs_register = 0x7f92 },
+	{ .id = CYPRESS_AN2235,  .name = "Cypress AN2235",  .cpu_cs_register = 0x7f92 },
+	{ .id = CYPRESS_FX2,     .name = "Cypress FX2",     .cpu_cs_register = 0xe600 },
 };
 
 /*
@@ -30,71 +30,117 @@
 static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len)
 {
 	return usb_control_msg(udev, usb_sndctrlpipe(udev,0),
-			0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5*HZ);
+			0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000);
 }
 
-int usb_cypress_load_firmware(struct usb_device *udev, const char *filename, int type)
+int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type)
 {
-	const struct firmware *fw = NULL;
-	u16 addr;
-	u8 *b,*p;
-	int ret = 0,i;
+	struct hexline hx;
+	u8 reset;
+	int ret,pos=0;
 
-	if ((ret = request_firmware(&fw, filename, &udev->dev)) != 0) {
-		err("did not find the firmware file. (%s) "
-			"Please see linux/Documentation/dvb/ for more details on firmware-problems.",
-			filename);
+	/* stop the CPU */
+	reset = 1;
+	if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1)
+		err("could not stop the USB controller CPU.");
+
+	while ((ret = dvb_usb_get_hexline(fw,&hx,&pos)) > 0) {
+		deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx.addr,hx.len,hx.chk);
+		ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len);
+
+		if (ret != hx.len) {
+			err("error while transferring firmware "
+				"(transferred size: %d, block size: %d)",
+				ret,hx.len);
+			ret = -EINVAL;
+			break;
+		}
+	}
+	if (ret < 0) {
+		err("firmware download failed at %d with %d",pos,ret);
 		return ret;
 	}
 
-	info("downloading firmware from file '%s' to the '%s'",filename,cypress[type].name);
-
-	p = kmalloc(fw->size,GFP_KERNEL);
-	if (p != NULL) {
-		u8 reset;
-		/*
-		 * you cannot use the fw->data as buffer for
-		 * usb_control_msg, a new buffer has to be
-		 * created
-		 */
-		memcpy(p,fw->data,fw->size);
-
-		/* stop the CPU */
-		reset = 1;
-		if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1)
-			err("could not stop the USB controller CPU.");
-		for(i = 0; p[i+3] == 0 && i < fw->size; ) {
-			b = (u8 *) &p[i];
-			addr = cpu_to_le16( *((u16 *) &b[1]) );
-
-			deb_fw("writing to address 0x%04x (buffer: 0x%02x%02x)\n",addr,b[1],b[2]);
-
-			ret = usb_cypress_writemem(udev,addr,&b[4],b[0]);
-
-			if (ret != b[0]) {
-				err("error while transferring firmware "
-					"(transferred size: %d, block size: %d)",
-					ret,b[0]);
-				ret = -EINVAL;
-				break;
-			}
-			i += 5 + b[0];
-		}
-		/* length in ret */
-		if (ret > 0)
-			ret = 0;
+	if (ret == 0) {
 		/* restart the CPU */
 		reset = 0;
 		if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) {
 			err("could not restart the USB controller CPU.");
 			ret = -EINVAL;
 		}
-
-		kfree(p);
-	} else {
-		ret = -ENOMEM;
-	}
-	release_firmware(fw);
+	} else
+		ret = -EIO;
 
 	return ret;
 }
+EXPORT_SYMBOL(usb_cypress_load_firmware);
+
+int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_properties *props)
+{
+	int ret;
+	const struct firmware *fw = NULL;
+
+	if ((ret = request_firmware(&fw, props->firmware, &udev->dev)) != 0) {
+		err("did not find the firmware file. (%s) "
+			"Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)",
+			props->firmware,ret);
+		return ret;
+	}
+
+	info("downloading firmware from file '%s'",props->firmware);
+
+	switch (props->usb_ctrl) {
+		case CYPRESS_AN2135:
+		case CYPRESS_AN2235:
+		case CYPRESS_FX2:
+			ret = usb_cypress_load_firmware(udev, fw, props->usb_ctrl);
+			break;
+		case DEVICE_SPECIFIC:
+			if (props->download_firmware)
+				ret = props->download_firmware(udev,fw);
+			else {
+				err("BUG: driver didn't specified a download_firmware-callback, although it claims to have a DEVICE_SPECIFIC one.");
+				ret = -EINVAL;
+			}
+			break;
+		default:
+			ret = -EINVAL;
+			break;
+	}
+
+	release_firmware(fw);
+	return ret;
+}
+
+int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos)
+{
+	u8 *b = (u8 *) &fw->data[*pos];
+	int data_offs = 4;
+	if (*pos >= fw->size)
+		return 0;
+
+	memset(hx,0,sizeof(struct hexline));
+
+	hx->len  = b[0];
+
+	if ((*pos + hx->len + 4) >= fw->size)
+		return -EINVAL;
+
+	hx->addr = le16_to_cpu( *((u16 *) &b[1]) );
+	hx->type = b[3];
+
+	if (hx->type == 0x04) {
+		/* b[4] and b[5] are the Extended linear address record data field */
+		hx->addr |= (b[4] << 24) | (b[5] << 16);
+/*		hx->len -= 2;
+		data_offs += 2; */
+	}
+	memcpy(hx->data,&b[data_offs],hx->len);
+	hx->chk = b[hx->len + data_offs];
+
+	*pos += hx->len + 5;
+
+	return *pos;
+}
+EXPORT_SYMBOL(dvb_usb_get_hexline);
+
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
index da97094..9b25453 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
@@ -52,9 +52,8 @@
 	struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 };
 	int ret = 0;
 
-	/* if there is nothing to initialize */
-	if (d->pll_init[0] == 0x00 && d->pll_init[1] == 0x00 &&
-		d->pll_init[2] == 0x00 && d->pll_init[3] == 0x00)
+	/* if pll_desc is not used */
+	if (d->pll_desc == NULL)
 		return 0;
 
 	if (d->tuner_pass_ctrl)
@@ -80,6 +79,9 @@
 {
 	struct dvb_usb_device *d = fe->dvb->priv;
 
+	if (d->pll_desc == NULL)
+		return 0;
+
 	deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc);
 
 	b[0] = d->pll_addr << 1;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 6be99e5..d229343 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -86,11 +86,15 @@
 #define USB_PID_WINTV_NOVA_T_USB2_COLD		0x9300
 #define USB_PID_WINTV_NOVA_T_USB2_WARM		0x9301
 #define USB_PID_NEBULA_DIGITV				0x0201
-#define USB_PID_DVICO_BLUEBIRD_LGZ201		0xdb00
-#define USB_PID_DVICO_BLUEBIRD_TH7579		0xdb10
 #define USB_PID_DVICO_BLUEBIRD_LGDT			0xd820
-#define USB_PID_DVICO_BLUEBIRD_LGZ201_1		0xdb01
-#define USB_PID_DVICO_BLUEBIRD_TH7579_2		0xdb11
+#define USB_PID_DVICO_BLUEBIRD_LG064F_COLD		0xd500
+#define USB_PID_DVICO_BLUEBIRD_LG064F_WARM		0xd501
+#define USB_PID_DVICO_BLUEBIRD_LGZ201_COLD		0xdb00
+#define USB_PID_DVICO_BLUEBIRD_LGZ201_WARM		0xdb01
+#define USB_PID_DVICO_BLUEBIRD_TH7579_COLD		0xdb10
+#define USB_PID_DVICO_BLUEBIRD_TH7579_WARM		0xdb11
+#define USB_PID_DVICO_BLUEBIRD_DEE1601_COLD		0xdb50
+#define USB_PID_DVICO_BLUEBIRD_DEE1601_WARM		0xdb51
 #define USB_PID_MEDION_MD95700				0x0932
 #define USB_PID_KYE_DVB_T_COLD				0x701e
 #define USB_PID_KYE_DVB_T_WARM				0x701f
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
index dd8e0b9..2e23060 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
@@ -138,6 +138,9 @@
 
 	int ret = -ENOMEM,cold=0;
 
+	if (du != NULL)
+		*du = NULL;
+
 	if ((desc = dvb_usb_find_device(udev,props,&cold)) == NULL) {
 		deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n");
 		return -ENODEV;
@@ -145,39 +148,41 @@
 
 	if (cold) {
 		info("found a '%s' in cold state, will try to load a firmware",desc->name);
-		ret = usb_cypress_load_firmware(udev,props->firmware,props->usb_ctrl);
-	} else {
-		info("found a '%s' in warm state.",desc->name);
-		d = kmalloc(sizeof(struct dvb_usb_device),GFP_KERNEL);
-		if (d == NULL) {
-			err("no memory for 'struct dvb_usb_device'");
+		ret = dvb_usb_download_firmware(udev,props);
+		if (!props->no_reconnect)
 			return ret;
-		}
-		memset(d,0,sizeof(struct dvb_usb_device));
-
-		d->udev = udev;
-		memcpy(&d->props,props,sizeof(struct dvb_usb_properties));
-		d->desc = desc;
-		d->owner = owner;
-
-		if (d->props.size_of_priv > 0) {
-			d->priv = kmalloc(d->props.size_of_priv,GFP_KERNEL);
-			if (d->priv == NULL) {
-				err("no memory for priv in 'struct dvb_usb_device'");
-				kfree(d);
-				return -ENOMEM;
-			}
-			memset(d->priv,0,d->props.size_of_priv);
-		}
-
-		usb_set_intfdata(intf, d);
-
-		if (du != NULL)
-			*du = d;
-
-		ret = dvb_usb_init(d);
 	}
 
+	info("found a '%s' in warm state.",desc->name);
+	d = kmalloc(sizeof(struct dvb_usb_device),GFP_KERNEL);
+	if (d == NULL) {
+		err("no memory for 'struct dvb_usb_device'");
+		return ret;
+	}
+	memset(d,0,sizeof(struct dvb_usb_device));
+
+	d->udev = udev;
+	memcpy(&d->props,props,sizeof(struct dvb_usb_properties));
+	d->desc = desc;
+	d->owner = owner;
+
+	if (d->props.size_of_priv > 0) {
+		d->priv = kmalloc(d->props.size_of_priv,GFP_KERNEL);
+		if (d->priv == NULL) {
+			err("no memory for priv in 'struct dvb_usb_device'");
+			kfree(d);
+			return -ENOMEM;
+		}
+		memset(d->priv,0,d->props.size_of_priv);
+	}
+
+	usb_set_intfdata(intf, d);
+
+	if (du != NULL)
+		*du = d;
+
+	ret = dvb_usb_init(d);
+
 	if (ret == 0)
 		info("%s successfully initialized and connected.",desc->name);
 	else
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index b4a1a98..dd56839 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -10,8 +10,8 @@
 
 #include <linux/config.h>
 #include <linux/input.h>
-#include <linux/module.h>
 #include <linux/usb.h>
+#include <linux/firmware.h>
 
 #include "dvb_frontend.h"
 #include "dvb_demux.h"
@@ -94,7 +94,11 @@
  * @usb_ctrl: which USB device-side controller is in use. Needed for firmware
  *  download.
  * @firmware: name of the firmware file.
- *
+ * @download_firmware: called to download the firmware when the usb_ctrl is
+ *  DEVICE_SPECIFIC.
+ * @no_reconnect: device doesn't do a reconnect after downloading the firmware,
+    so do the warm initialization right after it
+
  * @size_of_priv: how many bytes shall be allocated for the private field
  *  of struct dvb_usb_device.
  *
@@ -142,11 +146,14 @@
 	int caps;
 	int pid_filter_count;
 
-#define CYPRESS_AN2135  0
-#define CYPRESS_AN2235  1
-#define CYPRESS_FX2     2
+#define DEVICE_SPECIFIC 0
+#define CYPRESS_AN2135  1
+#define CYPRESS_AN2235  2
+#define CYPRESS_FX2     3
 	int usb_ctrl;
-	const char *firmware;
+	const char firmware[FIRMWARE_NAME_MAX];
+	int (*download_firmware) (struct usb_device *, const struct firmware *);
+	int no_reconnect;
 
 	int size_of_priv;
 
@@ -326,5 +333,15 @@
 extern int dvb_usb_pll_set(struct dvb_frontend *, struct dvb_frontend_parameters *, u8[]);
 extern int dvb_usb_pll_set_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *);
 
+/* commonly used firmware download types and function */
+struct hexline {
+	u8 len;
+	u32 addr;
+	u8 type;
+	u8 data[255];
+	u8 chk;
+};
+extern int dvb_usb_get_hexline(const struct firmware *, struct hexline *, int *);
+extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type);
 
 #endif
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
index fac48fc..412039d 100644
--- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -129,10 +129,6 @@
 		dibusb_read_eeprom_byte(d,i, &b);
 
 		mac[5 - (i - 136)] = b;
-
-/*		deb_ee("%02x ",b);
-		if ((i+1) % 16 == 0)
-			deb_ee("\n");*/
 	}
 
 	return 0;
@@ -153,7 +149,7 @@
 /* 01 */	{ USB_DEVICE(USB_VID_HAUPPAUGE,     USB_PID_WINTV_NOVA_T_USB2_WARM) },
 			{ }		/* Terminating entry */
 };
-MODULE_DEVICE_TABLE (usb, nova_t_table);
+MODULE_DEVICE_TABLE(usb, nova_t_table);
 
 static struct dvb_usb_properties nova_t_properties = {
 	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
@@ -198,6 +194,7 @@
 			{ &nova_t_table[0], NULL },
 			{ &nova_t_table[1], NULL },
 		},
+		{ NULL },
 	}
 };
 
diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c
index 104b5d0..0885d9f 100644
--- a/drivers/media/dvb/dvb-usb/vp702x-fe.c
+++ b/drivers/media/dvb/dvb-usb/vp702x-fe.c
@@ -190,7 +190,7 @@
 }
 
 static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
-			            struct dvb_diseqc_master_cmd *m)
+				    struct dvb_diseqc_master_cmd *m)
 {
 	struct vp702x_fe_state *st = fe->demodulator_priv;
 	u8 cmd[8],ibuf[10];
diff --git a/drivers/media/dvb/dvb-usb/vp702x.h b/drivers/media/dvb/dvb-usb/vp702x.h
index 4a3e8c7..a808d48 100644
--- a/drivers/media/dvb/dvb-usb/vp702x.h
+++ b/drivers/media/dvb/dvb-usb/vp702x.h
@@ -13,47 +13,47 @@
 /* commands are read and written with USB control messages */
 
 /* consecutive read/write operation */
-#define REQUEST_OUT       0xB2
-#define REQUEST_IN		  0xB3
+#define REQUEST_OUT		0xB2
+#define REQUEST_IN		0xB3
 
 /* the out-buffer of these consecutive operations contain sub-commands when b[0] = 0
  * request: 0xB2; i: 0; v: 0; b[0] = 0, b[1] = subcmd, additional buffer
  * the returning buffer looks as follows
  * request: 0xB3; i: 0; v: 0; b[0] = 0xB3, additional buffer */
 
-#define GET_TUNER_STATUS  0x05
+#define GET_TUNER_STATUS	0x05
 /* additional in buffer:
  * 0   1   2    3              4   5   6               7       8
  * N/A N/A 0x05 signal-quality N/A N/A signal-strength lock==0 N/A */
 
-#define GET_SYSTEM_STRING 0x06
+#define GET_SYSTEM_STRING	0x06
 /* additional in buffer:
  * 0   1   2   3   4   5   6   7   8
  * N/A 'U' 'S' 'B' '7' '0' '2' 'X' N/A */
 
-#define SET_DISEQC_CMD    0x08
+#define SET_DISEQC_CMD		0x08
 /* additional out buffer:
  * 0    1  2  3  4
  * len  X1 X2 X3 X4
  * additional in buffer:
  * 0   1 2
- * N/A 0 0   b[1] == b[2] == 0 -> success otherwise not */
+ * N/A 0 0   b[1] == b[2] == 0 -> success, failure otherwise */
 
-#define SET_LNB_POWER     0x09
+#define SET_LNB_POWER		0x09
 /* additional out buffer:
  * 0    1    2
  * 0x00 0xff 1 = on, 0 = off
  * additional in buffer:
  * 0   1 2
- * N/A 0 0   b[1] == b[2] == 0 -> success otherwise not */
+ * N/A 0 0   b[1] == b[2] == 0 -> success failure otherwise */
 
-#define GET_MAC_ADDRESS   0x0A
+#define GET_MAC_ADDRESS		0x0A
 /* #define GET_MAC_ADDRESS   0x0B */
 /* additional in buffer:
  * 0   1   2            3    4    5    6    7    8
  * N/A N/A 0x0A or 0x0B MAC0 MAC1 MAC2 MAC3 MAC4 MAC5 */
 
-#define SET_PID_FILTER    0x11
+#define SET_PID_FILTER		0x11
 /* additional in buffer:
  * 0        1        ... 14       15       16
  * PID0_MSB PID0_LSB ... PID7_MSB PID7_LSB PID_active (bits) */
@@ -64,39 +64,38 @@
  * freq0 freq1 divstep srate0 srate1 srate2 flag chksum
  */
 
-
 /* one direction requests */
-#define READ_REMOTE_REQ       0xB4
+#define READ_REMOTE_REQ		0xB4
 /* IN  i: 0; v: 0; b[0] == request, b[1] == key */
 
-#define READ_PID_NUMBER_REQ   0xB5
+#define READ_PID_NUMBER_REQ	0xB5
 /* IN  i: 0; v: 0; b[0] == request, b[1] == 0, b[2] = pid number */
 
-#define WRITE_EEPROM_REQ      0xB6
+#define WRITE_EEPROM_REQ	0xB6
 /* OUT i: offset; v: value to write; no extra buffer */
 
-#define READ_EEPROM_REQ       0xB7
+#define READ_EEPROM_REQ		0xB7
 /* IN  i: bufferlen; v: offset; buffer with bufferlen bytes */
 
-#define READ_STATUS           0xB8
+#define READ_STATUS		0xB8
 /* IN  i: 0; v: 0; bufferlen 10 */
 
-#define READ_TUNER_REG_REQ    0xB9
+#define READ_TUNER_REG_REQ	0xB9
 /* IN  i: 0; v: register; b[0] = value */
 
-#define READ_FX2_REG_REQ      0xBA
+#define READ_FX2_REG_REQ	0xBA
 /* IN  i: offset; v: 0; b[0] = value */
 
-#define WRITE_FX2_REG_REQ     0xBB
+#define WRITE_FX2_REG_REQ	0xBB
 /* OUT i: offset; v: value to write; 1 byte extra buffer */
 
-#define SET_TUNER_POWER_REQ   0xBC
+#define SET_TUNER_POWER_REQ	0xBC
 /* IN  i: 0 = power off, 1 = power on */
 
-#define WRITE_TUNER_REG_REQ   0xBD
+#define WRITE_TUNER_REG_REQ	0xBD
 /* IN  i: register, v: value to write, no extra buffer */
 
-#define RESET_TUNER           0xBE
+#define RESET_TUNER		0xBE
 /* IN  i: 0, v: 0, no extra buffer */
 
 extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d);
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
index 3835235..0282049 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -247,7 +247,7 @@
 		  .cold_ids = { &vp7045_usb_table[2], NULL },
 		  .warm_ids = { &vp7045_usb_table[3], NULL },
 		},
-		{ NULL },
+		{ 0 },
 	}
 };
 
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 8e269e1..db3a8b4 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -16,6 +16,12 @@
 	help
 	  A DVB-S tuner module. Say Y when you want to support this frontend.
 
+config DVB_CX24123
+	tristate "Conexant CX24123 based"
+	depends on DVB_CORE
+	help
+	  A DVB-S tuner module. Say Y when you want to support this frontend.
+
 config DVB_TDA8083
 	tristate "Philips TDA8083 based"
 	depends on DVB_CORE
@@ -50,18 +56,19 @@
 	depends on DVB_CORE
 
 config DVB_SP8870
- 	tristate "Spase sp8870 based"
+	tristate "Spase sp8870 based"
 	depends on DVB_CORE
 	select FW_LOADER
 	help
- 	  A DVB-T tuner module. Say Y when you want to support this frontend.
+	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
 	  This driver needs external firmware. Please use the command
 	  "<kerneldir>/Documentation/dvb/get_dvb_firmware sp8870" to
-	  download/extract it, and then copy it to /usr/lib/hotplug/firmware.
+	  download/extract it, and then copy it to /usr/lib/hotplug/firmware
+	  or /lib/firmware (depending on configuration of firmware hotplug).
 
 config DVB_SP887X
- 	tristate "Spase sp887x based"
+	tristate "Spase sp887x based"
 	depends on DVB_CORE
 	select FW_LOADER
 	help
@@ -69,7 +76,8 @@
 
 	  This driver needs external firmware. Please use the command
 	  "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to
-	  download/extract it, and then copy it to /usr/lib/hotplug/firmware.
+	  download/extract it, and then copy it to /usr/lib/hotplug/firmware
+	  or /lib/firmware (depending on configuration of firmware hotplug).
 
 config DVB_CX22700
 	tristate "Conexant CX22700 based"
@@ -78,10 +86,10 @@
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
 config DVB_CX22702
- 	tristate "Conexant cx22702 demodulator (OFDM)"
- 	depends on DVB_CORE
- 	help
- 	  A DVB-T tuner module. Say Y when you want to support this frontend.
+	tristate "Conexant cx22702 demodulator (OFDM)"
+	depends on DVB_CORE
+	help
+	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
 config DVB_L64781
 	tristate "LSI L64781"
@@ -98,8 +106,9 @@
 
 	  This driver needs external firmware. Please use the commands
 	  "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045",
-  	  "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to
-	  download/extract them, and then copy them to /usr/lib/hotplug/firmware.
+	  "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to
+	  download/extract them, and then copy them to /usr/lib/hotplug/firmware
+	  or /lib/firmware (depending on configuration of firmware hotplug).
 
 config DVB_NXT6000
 	tristate "NxtWave Communications NXT6000 based"
@@ -140,13 +149,13 @@
 	tristate "VLSI VES1820 based"
 	depends on DVB_CORE
 	help
- 	  A DVB-C tuner module. Say Y when you want to support this frontend.
+	  A DVB-C tuner module. Say Y when you want to support this frontend.
 
 config DVB_TDA10021
 	tristate "Philips TDA10021 based"
 	depends on DVB_CORE
 	help
- 	  A DVB-C tuner module. Say Y when you want to support this frontend.
+	  A DVB-C tuner module. Say Y when you want to support this frontend.
 
 config DVB_STV0297
 	tristate "ST STV0297 based"
@@ -164,6 +173,11 @@
 	help
 	  An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
 
+	  This driver needs external firmware. Please use the command
+	  "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to
+	  download/extract it, and then copy it to /usr/lib/hotplug/firmware
+	  or /lib/firmware (depending on configuration of firmware hotplug).
+
 config DVB_NXT200X
 	tristate "Nextwave NXT2002/NXT2004 based"
 	depends on DVB_CORE
@@ -172,6 +186,12 @@
 	  An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
 	  to support this frontend.
 
+	  This driver needs external firmware. Please use the commands
+	  "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" and
+	  "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to
+	  download/extract them, and then copy them to /usr/lib/hotplug/firmware
+	  or /lib/firmware (depending on configuration of firmware hotplug).
+
 config DVB_OR51211
 	tristate "or51211 based (pcHDTV HD2000 card)"
 	depends on DVB_CORE
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index a98760f..615ec83 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -32,3 +32,4 @@
 obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
 obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
 obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
+obj-$(CONFIG_DVB_CX24123) += cx24123.o
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c
index 8ceb9a3..3b132ba 100644
--- a/drivers/media/dvb/frontends/bcm3510.c
+++ b/drivers/media/dvb/frontends/bcm3510.c
@@ -255,7 +255,7 @@
 	bcm3510_register_value b;
 	int ret;
 
-	if ((ret < bcm3510_readB(st,0xfa,&b)) < 0)
+	if ((ret = bcm3510_readB(st,0xfa,&b)) < 0)
 		return ret;
 
 	b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b);
@@ -623,13 +623,13 @@
 		err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret);
 		return ret;
 	}
-	deb_info("got firmware: %d\n",fw->size);
+	deb_info("got firmware: %zd\n",fw->size);
 
 	b = fw->data;
 	for (i = 0; i < fw->size;) {
 		addr = le16_to_cpu( *( (u16 *)&b[i] ) );
 		len  = le16_to_cpu( *( (u16 *)&b[i+2] ) );
-		deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04x\n",addr,len,fw->size);
+		deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size);
 		if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) {
 			err("firmware download failed: %d\n",ret);
 			return ret;
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
index 5de0e6d3..0fc899f 100644
--- a/drivers/media/dvb/frontends/cx22702.c
+++ b/drivers/media/dvb/frontends/cx22702.c
@@ -195,6 +195,16 @@
 	return 0;
 }
 
+static int cx22702_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+{
+	struct cx22702_state* state = fe->demodulator_priv;
+	dprintk ("%s(%d)\n", __FUNCTION__, enable);
+	if (enable)
+		return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) & 0xfe);
+	else
+		return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) | 1);
+}
+
 /* Talk to the demod, set the FEC, GUARD, QAM settings etc */
 static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
@@ -202,7 +212,7 @@
 	struct cx22702_state* state = fe->demodulator_priv;
 
 	/* set PLL */
-	cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe);
+	cx22702_i2c_gate_ctrl(fe, 1);
 	if (state->config->pll_set) {
 		state->config->pll_set(fe, p);
 	} else if (state->config->pll_desc) {
@@ -216,7 +226,7 @@
 	} else {
 		BUG();
 	}
-	cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
+	cx22702_i2c_gate_ctrl(fe, 0);
 
 	/* set inversion */
 	cx22702_set_inversion (state, p->inversion);
@@ -349,11 +359,10 @@
 	cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02);
 
 	/* init PLL */
-	if (state->config->pll_init) {
-		cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) & 0xfe);
+	if (state->config->pll_init)
 		state->config->pll_init(fe);
-		cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
-	}
+
+	cx22702_i2c_gate_ctrl(fe, 0);
 
 	return 0;
 }
@@ -531,6 +540,7 @@
 	.read_signal_strength = cx22702_read_signal_strength,
 	.read_snr = cx22702_read_snr,
 	.read_ucblocks = cx22702_read_ucblocks,
+	.i2c_gate_ctrl = cx22702_i2c_gate_ctrl,
 };
 
 module_param(debug, int, 0644);
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
index 0c4db80..d15d32c 100644
--- a/drivers/media/dvb/frontends/cx24110.c
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -27,7 +27,6 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
-#include <linux/jiffies.h>
 
 #include "dvb_frontend.h"
 #include "cx24110.h"
@@ -56,7 +55,7 @@
 
 static struct {u8 reg; u8 data;} cx24110_regdata[]=
 		      /* Comments beginning with @ denote this value should
-		         be the default */
+			 be the default */
 	{{0x09,0x01}, /* SoftResetAll */
 	 {0x09,0x00}, /* release reset */
 	 {0x01,0xe8}, /* MSB of code rate 27.5MS/s */
@@ -67,26 +66,26 @@
 	 {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */
 	 {0x0a,0x00}, /* @ partial chip disables, do not set */
 	 {0x0b,0x01}, /* set output clock in gapped mode, start signal low
-		         active for first byte */
+			 active for first byte */
 	 {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */
 	 {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */
 	 {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1
-		         to avoid starting the BER counter. Reset the
-		         CRC test bit. Finite counting selected */
+			 to avoid starting the BER counter. Reset the
+			 CRC test bit. Finite counting selected */
 	 {0x15,0xff}, /* @ size of the limited time window for RS BER
-		         estimation. It is <value>*256 RS blocks, this
-		         gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */
+			 estimation. It is <value>*256 RS blocks, this
+			 gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */
 	 {0x16,0x00}, /* @ enable all RS output ports */
 	 {0x17,0x04}, /* @ time window allowed for the RS to sync */
 	 {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned
-		         for automatically */
+			 for automatically */
 		      /* leave the current code rate and normalization
-		         registers as they are after reset... */
+			 registers as they are after reset... */
 	 {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting
-		         only once */
+			 only once */
 	 {0x23,0x18}, /* @ size of the limited time window for Viterbi BER
-		         estimation. It is <value>*65536 channel bits, i.e.
-		         approx. 38ms at 27.5MS/s, rate 3/4 */
+			 estimation. It is <value>*65536 channel bits, i.e.
+			 approx. 38ms at 27.5MS/s, rate 3/4 */
 	 {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */
 		      /* leave front-end AGC parameters at default values */
 		      /* leave decimation AGC parameters at default values */
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c
new file mode 100644
index 0000000..d661c6f
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24123.c
@@ -0,0 +1,889 @@
+/*
+    Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
+
+    Copyright (C) 2005 Steven Toth <stoth@hauppauge.com>
+
+    Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+
+#include "dvb_frontend.h"
+#include "cx24123.h"
+
+static int debug;
+#define dprintk(args...) \
+	do { \
+		if (debug) printk (KERN_DEBUG "cx24123: " args); \
+	} while (0)
+
+struct cx24123_state
+{
+	struct i2c_adapter* i2c;
+	struct dvb_frontend_ops ops;
+	const struct cx24123_config* config;
+
+	struct dvb_frontend frontend;
+
+	u32 lastber;
+	u16 snr;
+	u8  lnbreg;
+
+	/* Some PLL specifics for tuning */
+	u32 VCAarg;
+	u32 VGAarg;
+	u32 bandselectarg;
+	u32 pllarg;
+
+	/* The Demod/Tuner can't easily provide these, we cache them */
+	u32 currentfreq;
+	u32 currentsymbolrate;
+};
+
+/* Various tuner defaults need to be established for a given symbol rate Sps */
+static struct
+{
+	u32 symbolrate_low;
+	u32 symbolrate_high;
+	u32 VCAslope;
+	u32 VCAoffset;
+	u32 VGA1offset;
+	u32 VGA2offset;
+	u32 VCAprogdata;
+	u32 VGAprogdata;
+} cx24123_AGC_vals[] =
+{
+	{
+		.symbolrate_low		= 1000000,
+		.symbolrate_high	= 4999999,
+		.VCAslope		= 0x07,
+		.VCAoffset		= 0x0f,
+		.VGA1offset		= 0x1f8,
+		.VGA2offset		= 0x1f8,
+		.VGAprogdata		= (2 << 18) | (0x1f8 << 9) | 0x1f8,
+		.VCAprogdata		= (4 << 18) | (0x07 << 9) | 0x07,
+	},
+	{
+		.symbolrate_low		=  5000000,
+		.symbolrate_high	= 14999999,
+		.VCAslope		= 0x1f,
+		.VCAoffset		= 0x1f,
+		.VGA1offset		= 0x1e0,
+		.VGA2offset		= 0x180,
+		.VGAprogdata		= (2 << 18) | (0x180 << 9) | 0x1e0,
+		.VCAprogdata		= (4 << 18) | (0x07 << 9) | 0x1f,
+	},
+	{
+		.symbolrate_low		= 15000000,
+		.symbolrate_high	= 45000000,
+		.VCAslope		= 0x3f,
+		.VCAoffset		= 0x3f,
+		.VGA1offset		= 0x180,
+		.VGA2offset		= 0x100,
+		.VGAprogdata		= (2 << 18) | (0x100 << 9) | 0x180,
+		.VCAprogdata		= (4 << 18) | (0x07 << 9) | 0x3f,
+	},
+};
+
+/*
+ * Various tuner defaults need to be established for a given frequency kHz.
+ * fixme: The bounds on the bands do not match the doc in real life.
+ * fixme: Some of them have been moved, other might need adjustment.
+ */
+static struct
+{
+	u32 freq_low;
+	u32 freq_high;
+	u32 bandselect;
+	u32 VCOdivider;
+	u32 VCOnumber;
+	u32 progdata;
+} cx24123_bandselect_vals[] =
+{
+	{
+		.freq_low	= 950000,
+		.freq_high	= 1018999,
+		.bandselect	= 0x40,
+		.VCOdivider	= 4,
+		.VCOnumber	= 7,
+		.progdata	= (0 << 18) | (0 << 9) | 0x40,
+	},
+	{
+		.freq_low	= 1019000,
+		.freq_high	= 1074999,
+		.bandselect	= 0x80,
+		.VCOdivider	= 4,
+		.VCOnumber	= 8,
+		.progdata	= (0 << 18) | (0 << 9) | 0x80,
+	},
+	{
+		.freq_low	= 1075000,
+		.freq_high	= 1227999,
+		.bandselect	= 0x01,
+		.VCOdivider	= 2,
+		.VCOnumber	= 1,
+		.progdata	= (0 << 18) | (1 << 9) | 0x01,
+	},
+	{
+		.freq_low	= 1228000,
+		.freq_high	= 1349999,
+		.bandselect	= 0x02,
+		.VCOdivider	= 2,
+		.VCOnumber	= 2,
+		.progdata	= (0 << 18) | (1 << 9) | 0x02,
+	},
+	{
+		.freq_low	= 1350000,
+		.freq_high	= 1481999,
+		.bandselect	= 0x04,
+		.VCOdivider	= 2,
+		.VCOnumber	= 3,
+		.progdata	= (0 << 18) | (1 << 9) | 0x04,
+	},
+	{
+		.freq_low	= 1482000,
+		.freq_high	= 1595999,
+		.bandselect	= 0x08,
+		.VCOdivider	= 2,
+		.VCOnumber	= 4,
+		.progdata	= (0 << 18) | (1 << 9) | 0x08,
+	},
+	{
+		.freq_low	= 1596000,
+		.freq_high	= 1717999,
+		.bandselect	= 0x10,
+		.VCOdivider	= 2,
+		.VCOnumber	= 5,
+		.progdata	= (0 << 18) | (1 << 9) | 0x10,
+	},
+	{
+		.freq_low	= 1718000,
+		.freq_high	= 1855999,
+		.bandselect	= 0x20,
+		.VCOdivider	= 2,
+		.VCOnumber	= 6,
+		.progdata	= (0 << 18) | (1 << 9) | 0x20,
+	},
+	{
+		.freq_low	= 1856000,
+		.freq_high	= 2035999,
+		.bandselect	= 0x40,
+		.VCOdivider	= 2,
+		.VCOnumber	= 7,
+		.progdata	= (0 << 18) | (1 << 9) | 0x40,
+	},
+	{
+		.freq_low	= 2036000,
+		.freq_high	= 2149999,
+		.bandselect	= 0x80,
+		.VCOdivider	= 2,
+		.VCOnumber	= 8,
+		.progdata	= (0 << 18) | (1 << 9) | 0x80,
+	},
+};
+
+static struct {
+	u8 reg;
+	u8 data;
+} cx24123_regdata[] =
+{
+	{0x00, 0x03}, /* Reset system */
+	{0x00, 0x00}, /* Clear reset */
+	{0x01, 0x3b}, /* Apply sensible defaults, from an i2c sniffer */
+	{0x03, 0x07},
+	{0x04, 0x10},
+	{0x05, 0x04},
+	{0x06, 0x31},
+	{0x0d, 0x02},
+	{0x0e, 0x03},
+	{0x0f, 0xfe},
+	{0x10, 0x01},
+	{0x14, 0x01},
+	{0x15, 0x98},
+	{0x16, 0x00},
+	{0x17, 0x01},
+	{0x1b, 0x05},
+	{0x1c, 0x80},
+	{0x1d, 0x00},
+	{0x1e, 0x00},
+	{0x20, 0x41},
+	{0x21, 0x15},
+	{0x27, 0x14},
+	{0x28, 0x46},
+	{0x29, 0x00},
+	{0x2a, 0xb0},
+	{0x2b, 0x73},
+	{0x2c, 0x00},
+	{0x2d, 0x00},
+	{0x2e, 0x00},
+	{0x2f, 0x00},
+	{0x30, 0x00},
+	{0x31, 0x00},
+	{0x32, 0x8c},
+	{0x33, 0x00},
+	{0x34, 0x00},
+	{0x35, 0x03},
+	{0x36, 0x02},
+	{0x37, 0x3a},
+	{0x3a, 0x00},	/* Enable AGC accumulator */
+	{0x44, 0x00},
+	{0x45, 0x00},
+	{0x46, 0x05},
+	{0x56, 0x41},
+	{0x57, 0xff},
+	{0x67, 0x83},
+};
+
+static int cx24123_writereg(struct cx24123_state* state, int reg, int data)
+{
+	u8 buf[] = { reg, data };
+	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
+	int err;
+
+	if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
+		printk("%s: writereg error(err == %i, reg == 0x%02x,"
+			 " data == 0x%02x)\n", __FUNCTION__, err, reg, data);
+		return -EREMOTEIO;
+	}
+
+	return 0;
+}
+
+static int cx24123_writelnbreg(struct cx24123_state* state, int reg, int data)
+{
+	u8 buf[] = { reg, data };
+	/* fixme: put the intersil addr int the config */
+	struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 2 };
+	int err;
+
+	if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
+		printk("%s: writelnbreg error (err == %i, reg == 0x%02x,"
+			 " data == 0x%02x)\n", __FUNCTION__, err, reg, data);
+		return -EREMOTEIO;
+	}
+
+	/* cache the write, no way to read back */
+	state->lnbreg = data;
+
+	return 0;
+}
+
+static int cx24123_readreg(struct cx24123_state* state, u8 reg)
+{
+	int ret;
+	u8 b0[] = { reg };
+	u8 b1[] = { 0 };
+	struct i2c_msg msg[] = {
+		{ .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
+		{ .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 }
+	};
+
+	ret = i2c_transfer(state->i2c, msg, 2);
+
+	if (ret != 2) {
+		printk("%s: reg=0x%x (error=%d)\n", __FUNCTION__, reg, ret);
+		return ret;
+	}
+
+	return b1[0];
+}
+
+static int cx24123_readlnbreg(struct cx24123_state* state, u8 reg)
+{
+	return state->lnbreg;
+}
+
+static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion)
+{
+	switch (inversion) {
+	case INVERSION_OFF:
+		cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) & 0x7f);
+		cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80);
+		break;
+	case INVERSION_ON:
+		cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) | 0x80);
+		cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80);
+		break;
+	case INVERSION_AUTO:
+		cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) & 0x7f);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_inversion_t *inversion)
+{
+	u8 val;
+
+	val = cx24123_readreg(state, 0x1b) >> 7;
+
+	if (val == 0)
+		*inversion = INVERSION_OFF;
+	else
+		*inversion = INVERSION_ON;
+
+	return 0;
+}
+
+static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec)
+{
+	if ( (fec < FEC_NONE) || (fec > FEC_AUTO) )
+		fec = FEC_AUTO;
+
+	/* Hardware has 5/11 and 3/5 but are never unused */
+	switch (fec) {
+	case FEC_NONE:
+		return cx24123_writereg(state, 0x0f, 0x01);
+	case FEC_1_2:
+		return cx24123_writereg(state, 0x0f, 0x02);
+	case FEC_2_3:
+		return cx24123_writereg(state, 0x0f, 0x04);
+	case FEC_3_4:
+		return cx24123_writereg(state, 0x0f, 0x08);
+	case FEC_5_6:
+		return cx24123_writereg(state, 0x0f, 0x20);
+	case FEC_7_8:
+		return cx24123_writereg(state, 0x0f, 0x80);
+	case FEC_AUTO:
+		return cx24123_writereg(state, 0x0f, 0xae);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int cx24123_get_fec(struct cx24123_state* state, fe_code_rate_t *fec)
+{
+	int ret;
+	u8 val;
+
+	ret = cx24123_readreg (state, 0x1b);
+	if (ret < 0)
+		return ret;
+	val = ret & 0x07;
+	switch (val) {
+	case 1:
+		*fec = FEC_1_2;
+		break;
+	case 3:
+		*fec = FEC_2_3;
+		break;
+	case 4:
+		*fec = FEC_3_4;
+		break;
+	case 5:
+		*fec = FEC_4_5;
+		break;
+	case 6:
+		*fec = FEC_5_6;
+		break;
+	case 7:
+		*fec = FEC_7_8;
+		break;
+	case 2:	/* *fec = FEC_3_5; break; */
+	case 0:	/* *fec = FEC_5_11; break; */
+		*fec = FEC_AUTO;
+		break;
+	default:
+		*fec = FEC_NONE; // can't happen
+	}
+
+	return 0;
+}
+
+/* fixme: Symbol rates < 3MSps may not work because of precision loss */
+static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate)
+{
+	u32 val;
+
+	val = (srate / 1185) * 100;
+
+	/* Compensate for scaling up, by removing 17 symbols per 1Msps */
+	val = val - (17 * (srate / 1000000));
+
+	cx24123_writereg(state, 0x08, (val >> 16) & 0xff );
+	cx24123_writereg(state, 0x09, (val >>  8) & 0xff );
+	cx24123_writereg(state, 0x0a, (val      ) & 0xff );
+
+	return 0;
+}
+
+/*
+ * Based on the required frequency and symbolrate, the tuner AGC has to be configured
+ * and the correct band selected. Calculate those values
+ */
+static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+{
+	struct cx24123_state *state = fe->demodulator_priv;
+	u32 ndiv = 0, adiv = 0, vco_div = 0;
+	int i = 0;
+
+	/* Defaults for low freq, low rate */
+	state->VCAarg = cx24123_AGC_vals[0].VCAprogdata;
+	state->VGAarg = cx24123_AGC_vals[0].VGAprogdata;
+	state->bandselectarg = cx24123_bandselect_vals[0].progdata;
+	vco_div = cx24123_bandselect_vals[0].VCOdivider;
+
+	/* For the given symbolerate, determine the VCA and VGA programming bits */
+	for (i = 0; i < sizeof(cx24123_AGC_vals) / sizeof(cx24123_AGC_vals[0]); i++)
+	{
+		if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) &&
+				(cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) {
+			state->VCAarg = cx24123_AGC_vals[i].VCAprogdata;
+			state->VGAarg = cx24123_AGC_vals[i].VGAprogdata;
+		}
+	}
+
+	/* For the given frequency, determine the bandselect programming bits */
+	for (i = 0; i < sizeof(cx24123_bandselect_vals) / sizeof(cx24123_bandselect_vals[0]); i++)
+	{
+		if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) &&
+				(cx24123_bandselect_vals[i].freq_high >= p->frequency) ) {
+			state->bandselectarg = cx24123_bandselect_vals[i].progdata;
+			vco_div = cx24123_bandselect_vals[i].VCOdivider;
+		}
+	}
+
+	/* Determine the N/A dividers for the requested lband freq (in kHz). */
+	/* Note: 10111 (kHz) is the Crystal Freq and divider of 10. */
+	ndiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) / 32) & 0x1ff;
+	adiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) % 32) & 0x1f;
+
+	if (adiv == 0)
+		adiv++;
+
+	/* determine the correct pll frequency values. */
+	/* Command 11, refdiv 11, cpump polarity 1, cpump current 3mA 10. */
+	state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (2 << 14);
+	state->pllarg |= (ndiv << 5) | adiv;
+
+	return 0;
+}
+
+/*
+ * Tuner data is 21 bits long, must be left-aligned in data.
+ * Tuner cx24109 is written through a dedicated 3wire interface on the demod chip.
+ */
+static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_parameters *p, u32 data)
+{
+	struct cx24123_state *state = fe->demodulator_priv;
+	unsigned long timeout;
+
+	/* align the 21 bytes into to bit23 boundary */
+	data = data << 3;
+
+	/* Reset the demod pll word length to 0x15 bits */
+	cx24123_writereg(state, 0x21, 0x15);
+
+	/* write the msb 8 bits, wait for the send to be completed */
+	timeout = jiffies + msecs_to_jiffies(40);
+	cx24123_writereg(state, 0x22, (data >> 16) & 0xff);
+	while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
+		if (time_after(jiffies, timeout)) {
+			printk("%s:  demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__);
+			return -EREMOTEIO;
+		}
+		msleep(10);
+	}
+
+	/* send another 8 bytes, wait for the send to be completed */
+	timeout = jiffies + msecs_to_jiffies(40);
+	cx24123_writereg(state, 0x22, (data>>8) & 0xff );
+	while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
+		if (time_after(jiffies, timeout)) {
+			printk("%s:  demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__);
+			return -EREMOTEIO;
+		}
+		msleep(10);
+	}
+
+	/* send the lower 5 bits of this byte, padded with 3 LBB, wait for the send to be completed */
+	timeout = jiffies + msecs_to_jiffies(40);
+	cx24123_writereg(state, 0x22, (data) & 0xff );
+	while ((cx24123_readreg(state, 0x20) & 0x80)) {
+		if (time_after(jiffies, timeout)) {
+			printk("%s:  demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__);
+			return -EREMOTEIO;
+		}
+		msleep(10);
+	}
+
+	/* Trigger the demod to configure the tuner */
+	cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) | 2);
+	cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) & 0xfd);
+
+	return 0;
+}
+
+static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+{
+	struct cx24123_state *state = fe->demodulator_priv;
+
+	if (cx24123_pll_calculate(fe, p) != 0) {
+		printk("%s: cx24123_pll_calcutate failed\n",__FUNCTION__);
+		return -EINVAL;
+	}
+
+	/* Write the new VCO/VGA */
+	cx24123_pll_writereg(fe, p, state->VCAarg);
+	cx24123_pll_writereg(fe, p, state->VGAarg);
+
+	/* Write the new bandselect and pll args */
+	cx24123_pll_writereg(fe, p, state->bandselectarg);
+	cx24123_pll_writereg(fe, p, state->pllarg);
+
+	return 0;
+}
+
+static int cx24123_initfe(struct dvb_frontend* fe)
+{
+	struct cx24123_state *state = fe->demodulator_priv;
+	int i;
+
+	/* Configure the demod to a good set of defaults */
+	for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++)
+		cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data);
+
+	if (state->config->pll_init)
+		state->config->pll_init(fe);
+
+	/* Configure the LNB for 14V */
+	if (state->config->use_isl6421)
+		cx24123_writelnbreg(state, 0x0, 0x2a);
+
+	return 0;
+}
+
+static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+	struct cx24123_state *state = fe->demodulator_priv;
+	u8 val;
+
+	switch (state->config->use_isl6421) {
+
+	case 1:
+
+		val = cx24123_readlnbreg(state, 0x0);
+
+		switch (voltage) {
+		case SEC_VOLTAGE_13:
+			return cx24123_writelnbreg(state, 0x0, val & 0x32); /* V 13v */
+		case SEC_VOLTAGE_18:
+			return cx24123_writelnbreg(state, 0x0, val | 0x04); /* H 18v */
+		case SEC_VOLTAGE_OFF:
+			return cx24123_writelnbreg(state, 0x0, val & 0x30);
+		default:
+			return -EINVAL;
+		};
+
+	case 0:
+
+		val = cx24123_readreg(state, 0x29);
+
+		switch (voltage) {
+		case SEC_VOLTAGE_13:
+			dprintk("%s: setting voltage 13V\n", __FUNCTION__);
+			if (state->config->enable_lnb_voltage)
+				state->config->enable_lnb_voltage(fe, 1);
+			return cx24123_writereg(state, 0x29, val | 0x80);
+		case SEC_VOLTAGE_18:
+			dprintk("%s: setting voltage 18V\n", __FUNCTION__);
+			if (state->config->enable_lnb_voltage)
+				state->config->enable_lnb_voltage(fe, 1);
+			return cx24123_writereg(state, 0x29, val & 0x7f);
+		case SEC_VOLTAGE_OFF:
+			dprintk("%s: setting voltage off\n", __FUNCTION__);
+			if (state->config->enable_lnb_voltage)
+				state->config->enable_lnb_voltage(fe, 0);
+			return 0;
+		default:
+			return -EINVAL;
+		};
+	}
+
+	return 0;
+}
+
+static int cx24123_send_diseqc_msg(struct dvb_frontend* fe,
+				   struct dvb_diseqc_master_cmd *cmd)
+{
+	/* fixme: Implement diseqc */
+	printk("%s: No support yet\n",__FUNCTION__);
+
+	return -ENOTSUPP;
+}
+
+static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+	struct cx24123_state *state = fe->demodulator_priv;
+
+	int sync = cx24123_readreg(state, 0x14);
+	int lock = cx24123_readreg(state, 0x20);
+
+	*status = 0;
+	if (lock & 0x01)
+		*status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+	if (sync & 0x04)
+		*status |= FE_HAS_VITERBI;
+	if (sync & 0x08)
+		*status |= FE_HAS_CARRIER;
+	if (sync & 0x80)
+		*status |= FE_HAS_SYNC | FE_HAS_LOCK;
+
+	return 0;
+}
+
+/*
+ * Configured to return the measurement of errors in blocks, because no UCBLOCKS value
+ * is available, so this value doubles up to satisfy both measurements
+ */
+static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+	struct cx24123_state *state = fe->demodulator_priv;
+
+	state->lastber =
+		((cx24123_readreg(state, 0x1c) & 0x3f) << 16) |
+		(cx24123_readreg(state, 0x1d) << 8 |
+		cx24123_readreg(state, 0x1e));
+
+	/* Do the signal quality processing here, it's derived from the BER. */
+	/* Scale the BER from a 24bit to a SNR 16 bit where higher = better */
+	if (state->lastber < 5000)
+		state->snr = 655*100;
+	else if ( (state->lastber >=   5000) && (state->lastber <  55000) )
+		state->snr = 655*90;
+	else if ( (state->lastber >=  55000) && (state->lastber < 150000) )
+		state->snr = 655*80;
+	else if ( (state->lastber >= 150000) && (state->lastber < 250000) )
+		state->snr = 655*70;
+	else if ( (state->lastber >= 250000) && (state->lastber < 450000) )
+		state->snr = 655*65;
+	else
+		state->snr = 0;
+
+	*ber = state->lastber;
+
+	return 0;
+}
+
+static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
+{
+	struct cx24123_state *state = fe->demodulator_priv;
+	*signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */
+
+	return 0;
+}
+
+static int cx24123_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+	struct cx24123_state *state = fe->demodulator_priv;
+	*snr = state->snr;
+
+	return 0;
+}
+
+static int cx24123_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+	struct cx24123_state *state = fe->demodulator_priv;
+	*ucblocks = state->lastber;
+
+	return 0;
+}
+
+static int cx24123_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+{
+	struct cx24123_state *state = fe->demodulator_priv;
+
+	if (state->config->set_ts_params)
+		state->config->set_ts_params(fe, 0);
+
+	state->currentfreq=p->frequency;
+	state->currentsymbolrate = p->u.qpsk.symbol_rate;
+
+	cx24123_set_inversion(state, p->inversion);
+	cx24123_set_fec(state, p->u.qpsk.fec_inner);
+	cx24123_set_symbolrate(state, p->u.qpsk.symbol_rate);
+	cx24123_pll_tune(fe, p);
+
+	/* Enable automatic aquisition and reset cycle */
+	cx24123_writereg(state, 0x03, (cx24123_readreg(state, 0x03) | 0x07));
+	cx24123_writereg(state, 0x00, 0x10);
+	cx24123_writereg(state, 0x00, 0);
+
+	return 0;
+}
+
+static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+{
+	struct cx24123_state *state = fe->demodulator_priv;
+
+	if (cx24123_get_inversion(state, &p->inversion) != 0) {
+		printk("%s: Failed to get inversion status\n",__FUNCTION__);
+		return -EREMOTEIO;
+	}
+	if (cx24123_get_fec(state, &p->u.qpsk.fec_inner) != 0) {
+		printk("%s: Failed to get fec status\n",__FUNCTION__);
+		return -EREMOTEIO;
+	}
+	p->frequency = state->currentfreq;
+	p->u.qpsk.symbol_rate = state->currentsymbolrate;
+
+	return 0;
+}
+
+static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+	struct cx24123_state *state = fe->demodulator_priv;
+	u8 val;
+
+	switch (state->config->use_isl6421) {
+	case 1:
+
+		val = cx24123_readlnbreg(state, 0x0);
+
+		switch (tone) {
+		case SEC_TONE_ON:
+			return cx24123_writelnbreg(state, 0x0, val | 0x10);
+		case SEC_TONE_OFF:
+			return cx24123_writelnbreg(state, 0x0, val & 0x2f);
+		default:
+			printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
+			return -EINVAL;
+		}
+
+	case 0:
+
+		val = cx24123_readreg(state, 0x29);
+
+		switch (tone) {
+		case SEC_TONE_ON:
+			dprintk("%s: setting tone on\n", __FUNCTION__);
+			return cx24123_writereg(state, 0x29, val | 0x10);
+		case SEC_TONE_OFF:
+			dprintk("%s: setting tone off\n",__FUNCTION__);
+			return cx24123_writereg(state, 0x29, val & 0xef);
+		default:
+			printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static void cx24123_release(struct dvb_frontend* fe)
+{
+	struct cx24123_state* state = fe->demodulator_priv;
+	dprintk("%s\n",__FUNCTION__);
+	kfree(state);
+}
+
+static struct dvb_frontend_ops cx24123_ops;
+
+struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
+				    struct i2c_adapter* i2c)
+{
+	struct cx24123_state* state = NULL;
+	int ret;
+
+	dprintk("%s\n",__FUNCTION__);
+
+	/* allocate memory for the internal state */
+	state = kmalloc(sizeof(struct cx24123_state), GFP_KERNEL);
+	if (state == NULL) {
+		printk("Unable to kmalloc\n");
+		goto error;
+	}
+
+	/* setup the state */
+	state->config = config;
+	state->i2c = i2c;
+	memcpy(&state->ops, &cx24123_ops, sizeof(struct dvb_frontend_ops));
+	state->lastber = 0;
+	state->snr = 0;
+	state->lnbreg = 0;
+	state->VCAarg = 0;
+	state->VGAarg = 0;
+	state->bandselectarg = 0;
+	state->pllarg = 0;
+	state->currentfreq = 0;
+	state->currentsymbolrate = 0;
+
+	/* check if the demod is there */
+	ret = cx24123_readreg(state, 0x00);
+	if ((ret != 0xd1) && (ret != 0xe1)) {
+		printk("Version != d1 or e1\n");
+		goto error;
+	}
+
+	/* create dvb_frontend */
+	state->frontend.ops = &state->ops;
+	state->frontend.demodulator_priv = state;
+	return &state->frontend;
+
+error:
+	kfree(state);
+
+	return NULL;
+}
+
+static struct dvb_frontend_ops cx24123_ops = {
+
+	.info = {
+		.name = "Conexant CX24123/CX24109",
+		.type = FE_QPSK,
+		.frequency_min = 950000,
+		.frequency_max = 2150000,
+		.frequency_stepsize = 1011, /* kHz for QPSK frontends */
+		.frequency_tolerance = 29500,
+		.symbol_rate_min = 1000000,
+		.symbol_rate_max = 45000000,
+		.caps = FE_CAN_INVERSION_AUTO |
+			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+			FE_CAN_QPSK | FE_CAN_RECOVER
+	},
+
+	.release = cx24123_release,
+
+	.init = cx24123_initfe,
+	.set_frontend = cx24123_set_frontend,
+	.get_frontend = cx24123_get_frontend,
+	.read_status = cx24123_read_status,
+	.read_ber = cx24123_read_ber,
+	.read_signal_strength = cx24123_read_signal_strength,
+	.read_snr = cx24123_read_snr,
+	.read_ucblocks = cx24123_read_ucblocks,
+	.diseqc_send_master_cmd = cx24123_send_diseqc_msg,
+	.set_tone = cx24123_set_tone,
+	.set_voltage = cx24123_set_voltage,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24123/cx24109 hardware");
+MODULE_AUTHOR("Steven Toth");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(cx24123_attach);
diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h
new file mode 100644
index 0000000..0c922b5
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24123.h
@@ -0,0 +1,51 @@
+/*
+    Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
+
+    Copyright (C) 2005 Steven Toth <stoth@hauppauge.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef CX24123_H
+#define CX24123_H
+
+#include <linux/dvb/frontend.h>
+
+struct cx24123_config
+{
+	/* the demodulator's i2c address */
+	u8 demod_address;
+
+	/*
+	   cards like Hauppauge Nova-S Plus/Nova-SE2 use an Intersil ISL6421 chip
+	   for LNB control, while KWorld DVB-S 100 use the LNBDC and LNBTone bits
+	   from register 0x29 of the CX24123 demodulator
+	*/
+	int use_isl6421;
+
+	/* PLL maintenance */
+	int (*pll_init)(struct dvb_frontend* fe);
+	int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
+
+	/* Need to set device param for start_dma */
+	int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
+
+	void (*enable_lnb_voltage)(struct dvb_frontend* fe, int on);
+};
+
+extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
+					   struct i2c_adapter* i2c);
+
+#endif /* CX24123_H */
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index f857b86..a3d57ce 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -107,18 +107,19 @@
 };
 EXPORT_SYMBOL(dvb_pll_microtune_4042);
 
-struct dvb_pll_desc dvb_pll_thomson_dtt7611 = {
-	.name  = "Thomson dtt7611",
-	.min   =  44000000,
-	.max   = 958000000,
+struct dvb_pll_desc dvb_pll_thomson_dtt761x = {
+	/* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */
+	.name  = "Thomson dtt761x",
+	.min   =  57000000,
+	.max   = 863000000,
 	.count = 3,
 	.entries = {
-		{ 157250000, 44000000, 62500, 0x8e, 0x39 },
-		{ 454000000, 44000000, 62500, 0x8e, 0x3a },
+		{ 147000000, 44000000, 62500, 0x8e, 0x39 },
+		{ 417000000, 44000000, 62500, 0x8e, 0x3a },
 		{ 999999999, 44000000, 62500, 0x8e, 0x3c },
 	},
 };
-EXPORT_SYMBOL(dvb_pll_thomson_dtt7611);
+EXPORT_SYMBOL(dvb_pll_thomson_dtt761x);
 
 struct dvb_pll_desc dvb_pll_unknown_1 = {
 	.name  = "unknown 1", /* used by dntv live dvb-t */
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index 497d31d..24d4d2e 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -25,7 +25,7 @@
 extern struct dvb_pll_desc dvb_pll_thomson_dtt7610;
 extern struct dvb_pll_desc dvb_pll_lg_z201;
 extern struct dvb_pll_desc dvb_pll_microtune_4042;
-extern struct dvb_pll_desc dvb_pll_thomson_dtt7611;
+extern struct dvb_pll_desc dvb_pll_thomson_dtt761x;
 extern struct dvb_pll_desc dvb_pll_unknown_1;
 
 extern struct dvb_pll_desc dvb_pll_tua6010xs;
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
index cb53018..9d21464 100644
--- a/drivers/media/dvb/frontends/lgdt330x.c
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -27,6 +27,7 @@
  *   DViCO FusionHDTV 3 Gold-T
  *   DViCO FusionHDTV 5 Gold
  *   DViCO FusionHDTV 5 Lite
+ *   DViCO FusionHDTV 5 USB Gold
  *   Air2PC/AirStar 2 ATSC 3rd generation (HD5000)
  *
  * TODO:
@@ -402,6 +403,8 @@
 		state->config->pll_set(fe, param);
 
 	/* Keep track of the new frequency */
+	/* FIXME this is the wrong way to do this...           */
+	/* The tuner is shared with the video4linux analog API */
 	state->current_frequency = param->frequency;
 
 	lgdt330x_SwReset(state);
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
index 8d67228..ec4e641 100644
--- a/drivers/media/dvb/frontends/mt312.c
+++ b/drivers/media/dvb/frontends/mt312.c
@@ -501,7 +501,8 @@
 	case ID_VP310:
 	// For now we will do this only for the VP310.
 	// It should be better for the mt312 as well, but tunning will be slower. ACCJr 09/29/03
-		if ((ret = mt312_readreg(state, CONFIG, &config_val) < 0))
+		ret = mt312_readreg(state, CONFIG, &config_val);
+		if (ret < 0)
 			return ret;
 		if (p->u.qpsk.symbol_rate >= 30000000) //Note that 30MS/s should use 90MHz
 		{
diff --git a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c
index 52c4160..4f263e6 100644
--- a/drivers/media/dvb/frontends/nxt2002.c
+++ b/drivers/media/dvb/frontends/nxt2002.c
@@ -22,7 +22,8 @@
 /*
  * This driver needs external firmware. Please use the command
  * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to
- * download/extract it, and then copy it to /usr/lib/hotplug/firmware.
+ * download/extract it, and then copy it to /usr/lib/hotplug/firmware
+ * or /lib/firmware (depending on configuration of firmware hotplug).
  */
 #define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
 #define CRC_CCIT_MASK 0x1021
diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c
index a458a3b..a16eeba 100644
--- a/drivers/media/dvb/frontends/nxt6000.c
+++ b/drivers/media/dvb/frontends/nxt6000.c
@@ -574,11 +574,11 @@
 		.symbol_rate_max = 9360000,	/* FIXME */
 		.symbol_rate_tolerance = 4000,
 		.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-		        FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
-		        FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
-		        FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-		        FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
-		        FE_CAN_HIERARCHY_AUTO,
+			FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
+			FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
+			FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+			FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
+			FE_CAN_HIERARCHY_AUTO,
 	},
 
 	.release = nxt6000_release,
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c
index 531f762..7c3aed1 100644
--- a/drivers/media/dvb/frontends/or51211.c
+++ b/drivers/media/dvb/frontends/or51211.c
@@ -25,7 +25,8 @@
 /*
  * This driver needs external firmware. Please use the command
  * "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to
- * download/extract it, and then copy it to /usr/lib/hotplug/firmware.
+ * download/extract it, and then copy it to /usr/lib/hotplug/firmware
+ * or /lib/firmware (depending on configuration of firmware hotplug).
  */
 #define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw"
 
@@ -112,7 +113,7 @@
 	u8 tudata[585];
 	int i;
 
-	dprintk("Firmware is %d bytes\n",fw->size);
+	dprintk("Firmware is %zd bytes\n",fw->size);
 
 	/* Get eprom data */
 	tudata[0] = 17;
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
index 1871509..d694775 100644
--- a/drivers/media/dvb/frontends/s5h1420.c
+++ b/drivers/media/dvb/frontends/s5h1420.c
@@ -521,8 +521,8 @@
 
 		case FEC_3_4:
 			s5h1420_writereg(state, 0x30, 0x04);
-		        s5h1420_writereg(state, 0x31, 0x12 | inversion);
-		        break;
+			s5h1420_writereg(state, 0x31, 0x12 | inversion);
+			break;
 
 		case FEC_5_6:
 			s5h1420_writereg(state, 0x30, 0x08);
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c
index fc06cd6..73829e6 100644
--- a/drivers/media/dvb/frontends/sp8870.c
+++ b/drivers/media/dvb/frontends/sp8870.c
@@ -22,7 +22,8 @@
 /*
  * This driver needs external firmware. Please use the command
  * "<kerneldir>/Documentation/dvb/get_dvb_firmware alps_tdlb7" to
- * download/extract it, and then copy it to /usr/lib/hotplug/firmware.
+ * download/extract it, and then copy it to /usr/lib/hotplug/firmware
+ * or /lib/firmware (depending on configuration of firmware hotplug).
  */
 #define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw"
 
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c
index e3b6657..eb8a602 100644
--- a/drivers/media/dvb/frontends/sp887x.c
+++ b/drivers/media/dvb/frontends/sp887x.c
@@ -5,7 +5,8 @@
 /*
  * This driver needs external firmware. Please use the command
  * "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to
- * download/extract it, and then copy it to /usr/lib/hotplug/firmware.
+ * download/extract it, and then copy it to /usr/lib/hotplug/firmware
+ * or /lib/firmware (depending on configuration of firmware hotplug).
  */
 #define SP887X_DEFAULT_FIRMWARE "dvb-fe-sp887x.fw"
 
@@ -581,7 +582,7 @@
 		.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
 			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
 			FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
-		        FE_CAN_RECOVER
+			FE_CAN_RECOVER
 	},
 
 	.release = sp887x_release,
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index 177d71d..5bcd00f 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -131,6 +131,13 @@
 	return ret == 2 ? 0 : ret;
 }
 
+int stv0299_enable_plli2c (struct dvb_frontend* fe)
+{
+	struct stv0299_state* state = fe->demodulator_priv;
+
+	return stv0299_writeregI(state, 0x05, 0xb5);	/*  enable i2c repeater on stv0299  */
+}
+
 static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec)
 {
 	dprintk ("%s\n", __FUNCTION__);
@@ -387,7 +394,7 @@
 	};
 }
 
-static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
+static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long cmd)
 {
 	struct stv0299_state* state = fe->demodulator_priv;
 	u8 reg0x08;
@@ -407,7 +414,7 @@
 
 	cmd = cmd << 1;
 	if (debug_legacy_dish_switch)
-		printk ("%s switch command: 0x%04x\n",__FUNCTION__, cmd);
+		printk ("%s switch command: 0x%04lx\n",__FUNCTION__, cmd);
 
 	do_gettimeofday (&nexttime);
 	if (debug_legacy_dish_switch)
@@ -717,5 +724,6 @@
 	      "Andreas Oberritter, Andrew de Quincey, Kenneth Aafløy");
 MODULE_LICENSE("GPL");
 
+EXPORT_SYMBOL(stv0299_enable_plli2c);
 EXPORT_SYMBOL(stv0299_writereg);
 EXPORT_SYMBOL(stv0299_attach);
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
index 9af3d71..32c87b4 100644
--- a/drivers/media/dvb/frontends/stv0299.h
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -94,6 +94,7 @@
 };
 
 extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data);
+extern int stv0299_enable_plli2c (struct dvb_frontend* fe);
 
 extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
 					   struct i2c_adapter* i2c);
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
index 425cd19..21255ca 100644
--- a/drivers/media/dvb/frontends/tda10021.c
+++ b/drivers/media/dvb/frontends/tda10021.c
@@ -95,7 +95,7 @@
 	u8 b0 [] = { reg };
 	u8 b1 [] = { 0 };
 	struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
-		                  { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
+				  { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
 	int ret;
 
 	ret = i2c_transfer (state->i2c, msg, 2);
@@ -434,7 +434,7 @@
 		.frequency_max = 858000000,
 		.symbol_rate_min = (XIN/2)/64,     /* SACLK/64 == (XIN/2)/64 */
 		.symbol_rate_max = (XIN/2)/4,      /* SACLK/4 */
-	#if 0
+#if 0
 		.frequency_tolerance = ???,
 		.symbol_rate_tolerance = ???,  /* ppm */  /* == 8% (spec p. 5) */
 	#endif
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index dd02aff..c63e9a5 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -23,7 +23,8 @@
  * This driver needs external firmware. Please use the commands
  * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045",
  * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to
- * download/extract them, and then copy them to /usr/lib/hotplug/firmware.
+ * download/extract them, and then copy them to /usr/lib/hotplug/firmware
+ * or /lib/firmware (depending on configuration of firmware hotplug).
  */
 #define TDA10045_DEFAULT_FIRMWARE "dvb-fe-tda10045.fw"
 #define TDA10046_DEFAULT_FIRMWARE "dvb-fe-tda10046.fw"
@@ -271,32 +272,57 @@
 static int tda10046h_set_bandwidth(struct tda1004x_state *state,
 				   fe_bandwidth_t bandwidth)
 {
-	static u8 bandwidth_6mhz[] = { 0x80, 0x15, 0xfe, 0xab, 0x8e };
-	static u8 bandwidth_7mhz[] = { 0x6e, 0x02, 0x53, 0xc8, 0x25 };
-	static u8 bandwidth_8mhz[] = { 0x60, 0x12, 0xa8, 0xe4, 0xbd };
+	static u8 bandwidth_6mhz_53M[] = { 0x7b, 0x2e, 0x11, 0xf0, 0xd2 };
+	static u8 bandwidth_7mhz_53M[] = { 0x6a, 0x02, 0x6a, 0x43, 0x9f };
+	static u8 bandwidth_8mhz_53M[] = { 0x5c, 0x32, 0xc2, 0x96, 0x6d };
 
+	static u8 bandwidth_6mhz_48M[] = { 0x70, 0x02, 0x49, 0x24, 0x92 };
+	static u8 bandwidth_7mhz_48M[] = { 0x60, 0x02, 0xaa, 0xaa, 0xab };
+	static u8 bandwidth_8mhz_48M[] = { 0x54, 0x03, 0x0c, 0x30, 0xc3 };
+	int tda10046_clk53m;
+
+	if ((state->config->if_freq == TDA10046_FREQ_045) ||
+	    (state->config->if_freq == TDA10046_FREQ_052))
+		tda10046_clk53m = 0;
+	else
+		tda10046_clk53m = 1;
 	switch (bandwidth) {
 	case BANDWIDTH_6_MHZ:
-		tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz, sizeof(bandwidth_6mhz));
+		if (tda10046_clk53m)
+			tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_53M,
+						  sizeof(bandwidth_6mhz_53M));
+		else
+			tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_48M,
+						  sizeof(bandwidth_6mhz_48M));
 		if (state->config->if_freq == TDA10046_FREQ_045) {
-			tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x09);
-			tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x4f);
+			tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a);
+			tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xab);
 		}
 		break;
 
 	case BANDWIDTH_7_MHZ:
-		tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz, sizeof(bandwidth_7mhz));
+		if (tda10046_clk53m)
+			tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_53M,
+						  sizeof(bandwidth_7mhz_53M));
+		else
+			tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_48M,
+						  sizeof(bandwidth_7mhz_48M));
 		if (state->config->if_freq == TDA10046_FREQ_045) {
-			tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a);
-			tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x79);
+			tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c);
+			tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00);
 		}
 		break;
 
 	case BANDWIDTH_8_MHZ:
-		tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz, sizeof(bandwidth_8mhz));
+		if (tda10046_clk53m)
+			tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_53M,
+						  sizeof(bandwidth_8mhz_53M));
+		else
+			tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_48M,
+						  sizeof(bandwidth_8mhz_48M));
 		if (state->config->if_freq == TDA10046_FREQ_045) {
-			tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b);
-			tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3);
+			tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d);
+			tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x55);
 		}
 		break;
 
@@ -418,9 +444,22 @@
 static void tda10046_init_plls(struct dvb_frontend* fe)
 {
 	struct tda1004x_state* state = fe->demodulator_priv;
+	int tda10046_clk53m;
+
+	if ((state->config->if_freq == TDA10046_FREQ_045) ||
+	    (state->config->if_freq == TDA10046_FREQ_052))
+		tda10046_clk53m = 0;
+	else
+		tda10046_clk53m = 1;
 
 	tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0);
-	tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x0a); // PLL M = 10
+	if(tda10046_clk53m) {
+		printk(KERN_INFO "tda1004x: setting up plls for 53MHz sampling clock\n");
+		tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x08); // PLL M = 8
+	} else {
+		printk(KERN_INFO "tda1004x: setting up plls for 48MHz sampling clock\n");
+		tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x03); // PLL M = 3
+	}
 	if (state->config->xtal_freq == TDA10046_XTAL_4M ) {
 		dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__);
 		tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
@@ -428,26 +467,32 @@
 		dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __FUNCTION__);
 		tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3
 	}
-	tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99);
+	if(tda10046_clk53m)
+		tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x67);
+	else
+		tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x72);
+	/* Note clock frequency is handled implicitly */
 	switch (state->config->if_freq) {
-	case TDA10046_FREQ_3617:
-		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
-		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c);
-		break;
-	case TDA10046_FREQ_3613:
-		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
-		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x13);
-		break;
 	case TDA10046_FREQ_045:
-		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b);
-		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3);
+		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c);
+		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00);
 		break;
 	case TDA10046_FREQ_052:
-		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c);
-		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x06);
+		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d);
+		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xc7);
+		break;
+	case TDA10046_FREQ_3617:
+		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7);
+		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x59);
+		break;
+	case TDA10046_FREQ_3613:
+		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7);
+		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x3f);
 		break;
 	}
 	tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz
+	/* let the PLLs settle */
+	msleep(120);
 }
 
 static int tda10046_fwupload(struct dvb_frontend* fe)
@@ -462,13 +507,13 @@
 	/* let the clocks recover from sleep */
 	msleep(5);
 
+	/* The PLLs need to be reprogrammed after sleep */
+	tda10046_init_plls(fe);
+
 	/* don't re-upload unless necessary */
 	if (tda1004x_check_upload_ok(state) == 0)
 		return 0;
 
-	/* set parameters */
-	tda10046_init_plls(fe);
-
 	if (state->config->request_firmware != NULL) {
 		/* request the firmware, this will block until someone uploads it */
 		printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");
@@ -484,7 +529,6 @@
 			return ret;
 	} else {
 		/* boot from firmware eeprom */
-		/* Hac Note: we might need to do some GPIO Magic here */
 		printk(KERN_INFO "tda1004x: booting from eeprom\n");
 		tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
 		msleep(300);
@@ -606,10 +650,9 @@
 
 	// tda setup
 	tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
-	tda1004x_write_byteI(state, TDA1004X_AUTO, 7); // select HP stream
-	tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer
+	tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87);    // 100 ppm crystal, select HP stream
+	tda1004x_write_byteI(state, TDA1004X_CONFC1, 8);      // disable pulse killer
 
-	tda10046_init_plls(fe);
 	switch (state->config->agc_config) {
 	case TDA10046_AGC_DEFAULT:
 		tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup
@@ -626,25 +669,22 @@
 	case TDA10046_AGC_TDA827X:
 		tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02);   // AGC setup
 		tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70);    // AGC Threshold
-		tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x0E); // Gain Renormalize
-		tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
+		tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
+		tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities
 		break;
 	}
+	tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38);
 	tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on
 	tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0);	  // }
 	tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
 	tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0);	  // }
 	tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff);  // }
-	tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 1); // IF gain 2, TUN gain 1
+	tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 0x12); // IF gain 2, TUN gain 1
 	tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits
 	tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
 	tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config
 	tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
 
-	tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0xe1); // tristate setup
-	tda1004x_write_byteI(state, TDA10046H_GPIO_OUT_SEL, 0xcc); // GPIO output config
-	tda1004x_write_byteI(state, TDA10046H_GPIO_SELECT, 8); // GPIO select
-
 	state->initialised = 1;
 	return 0;
 }
@@ -686,9 +726,9 @@
 
 	// Set standard params.. or put them to auto
 	if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) ||
-	    (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) ||
-	    (fe_params->u.ofdm.constellation == QAM_AUTO) ||
-	    (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) {
+		(fe_params->u.ofdm.code_rate_LP == FEC_AUTO) ||
+		(fe_params->u.ofdm.constellation == QAM_AUTO) ||
+		(fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) {
 		tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1);	// enable auto
 		tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0);	// turn off constellation bits
 		tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0);	// turn off hierarchy bits
@@ -851,6 +891,7 @@
 static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params)
 {
 	struct tda1004x_state* state = fe->demodulator_priv;
+
 	dprintk("%s\n", __FUNCTION__);
 
 	// inversion status
@@ -875,16 +916,18 @@
 			break;
 		}
 		break;
-
 	case TDA1004X_DEMOD_TDA10046:
 		switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) {
-		case 0x60:
+		case 0x5c:
+		case 0x54:
 			fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
 			break;
-		case 0x6e:
+		case 0x6a:
+		case 0x60:
 			fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
 			break;
-		case 0x80:
+		case 0x7b:
+		case 0x70:
 			fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
 			break;
 		}
diff --git a/drivers/media/dvb/pluto2/Kconfig b/drivers/media/dvb/pluto2/Kconfig
index f02842b..84f8f9f 100644
--- a/drivers/media/dvb/pluto2/Kconfig
+++ b/drivers/media/dvb/pluto2/Kconfig
@@ -8,7 +8,7 @@
 	  Support for PCI cards based on the Pluto2 FPGA like the Satelco
 	  Easywatch Mobile Terrestrial DVB-T Receiver.
 
-          Since these cards have no MPEG decoder onboard, they transmit
+	  Since these cards have no MPEG decoder onboard, they transmit
 	  only compressed MPEG data over the PCI bus, so you need
 	  an external software decoder to watch TV on your computer.
 
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index fa5034a..5b2aadb 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -18,9 +18,10 @@
 	  This driver only supports the fullfeatured cards with
 	  onboard MPEG2 decoder.
 
-          This driver needs an external firmware. Please use the script
-          "<kerneldir>/Documentation/dvb/get_dvb_firmware av7110" to
-          download/extract it, and then copy it to /usr/lib/hotplug/firmware.
+	  This driver needs an external firmware. Please use the script
+	  "<kerneldir>/Documentation/dvb/get_dvb_firmware av7110" to
+	  download/extract it, and then copy it to /usr/lib/hotplug/firmware
+	  or /lib/firmware (depending on configuration of firmware hotplug).
 
 	  Say Y if you own such a card and want to use it.
 
diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile
index 825ab1c..a690730 100644
--- a/drivers/media/dvb/ttpci/Makefile
+++ b/drivers/media/dvb/ttpci/Makefile
@@ -16,7 +16,7 @@
 hostprogs-y	:= fdump
 
 ifdef CONFIG_DVB_AV7110_FIRMWARE
-$(obj)/av7110.o: $(obj)/fdump $(obj)/av7110_firm.h 
+$(obj)/av7110.o: $(obj)/fdump $(obj)/av7110_firm.h
 
 $(obj)/av7110_firm.h:
 	$(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 7dae91e..8ce4146 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -133,7 +133,13 @@
 	/* remaining inits according to card and frontend type */
 	av7110->analog_tuner_flags = 0;
 	av7110->current_input = 0;
-	if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) {
+	if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000a) {
+		printk("dvb-ttpci: MSP3415 audio DAC @ card %d\n",
+			av7110->dvb_adapter.num);
+		av7110->adac_type = DVB_ADAC_MSP34x5;
+		av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 0); // SPDIF on
+	}
+	else if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) {
 		printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n",
 			av7110->dvb_adapter.num);
 		av7110->adac_type = DVB_ADAC_CRYSTAL;
@@ -156,10 +162,10 @@
 	else {
 		av7110->adac_type = adac;
 		printk("dvb-ttpci: adac type set to %d @ card %d\n",
-			av7110->dvb_adapter.num, av7110->adac_type);
+			av7110->adac_type, av7110->dvb_adapter.num);
 	}
 
-	if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) {
+	if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP34x0) {
 		// switch DVB SCART on
 		ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
 		if (ret < 0)
@@ -190,19 +196,17 @@
 
 	av7110_bootarm(av7110);
 	msleep(100);
+
+	init_av7110_av(av7110);
+
+	/* card-specific recovery */
+	if (av7110->recover)
+		av7110->recover(av7110);
+
 	restart_feeds(av7110);
 	av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config);
 }
 
-static void arm_error(struct av7110 *av7110)
-{
-	dprintk(4, "%p\n",av7110);
-
-	av7110->arm_errors++;
-	av7110->arm_ready = 0;
-	recover_arm(av7110);
-}
-
 static void av7110_arm_sync(struct av7110 *av7110)
 {
 	av7110->arm_rmmod = 1;
@@ -240,26 +244,22 @@
 
 		if (down_interruptible(&av7110->dcomlock))
 			break;
-
 		newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2);
 		up(&av7110->dcomlock);
 
-		if (newloops == av7110->arm_loops) {
+		if (newloops == av7110->arm_loops || av7110->arm_errors > 3) {
 			printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n",
 			       av7110->dvb_adapter.num);
 
-			arm_error(av7110);
-			av7710_set_video_mode(av7110, vidmode);
-
-			init_av7110_av(av7110);
+			recover_arm(av7110);
 
 			if (down_interruptible(&av7110->dcomlock))
 				break;
-
 			newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1;
 			up(&av7110->dcomlock);
 		}
 		av7110->arm_loops = newloops;
+		av7110->arm_errors = 0;
 	}
 
 	av7110->arm_thread = NULL;
@@ -510,10 +510,6 @@
 		iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
 
 		av7110->video_size.h = h_ar & 0xfff;
-		dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",
-			av7110->video_size.w,
-			av7110->video_size.h,
-			av7110->video_size.aspect_ratio);
 
 		event.type = VIDEO_EVENT_SIZE_CHANGED;
 		event.u.size.w = av7110->video_size.w;
@@ -535,6 +531,11 @@
 			event.u.size.aspect_ratio = VIDEO_FORMAT_4_3;
 			av7110->videostate.video_format = VIDEO_FORMAT_4_3;
 		}
+
+		dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",
+			av7110->video_size.w, av7110->video_size.h,
+			av7110->video_size.aspect_ratio);
+
 		dvb_video_add_event(av7110, &event);
 		break;
 	}
@@ -714,6 +715,8 @@
 static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
 			  u16 subpid, u16 pcrpid)
 {
+	u16 aflags = 0;
+
 	dprintk(4, "%p\n", av7110);
 
 	if (vpid == 0x1fff || apid == 0x1fff ||
@@ -725,8 +728,11 @@
 		av7110->pids[DMX_PES_PCR] = 0;
 	}
 
-	return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 5,
-			     pcrpid, vpid, apid, ttpid, subpid);
+	if (av7110->audiostate.bypass_mode)
+		aflags |= 0x8000;
+
+	return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 6,
+			     pcrpid, vpid, apid, ttpid, subpid, aflags);
 }
 
 int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
@@ -1043,7 +1049,7 @@
 	struct dvb_demux *dvbdmx = &av7110->demux;
 	struct dvb_demux_feed *feed;
 	int mode;
-	int i;
+	int i, j;
 
 	dprintk(4, "%p\n", av7110);
 
@@ -1051,10 +1057,21 @@
 	av7110->playing = 0;
 	av7110->rec_mode = 0;
 
-	for (i = 0; i < dvbdmx->filternum; i++) {
+	for (i = 0; i < dvbdmx->feednum; i++) {
 		feed = &dvbdmx->feed[i];
-		if (feed->state == DMX_STATE_GO)
+		if (feed->state == DMX_STATE_GO) {
+			if (feed->type == DMX_TYPE_SEC) {
+				for (j = 0; j < dvbdmx->filternum; j++) {
+					if (dvbdmx->filter[j].type != DMX_TYPE_SEC)
+						continue;
+					if (dvbdmx->filter[j].filter.parent != &feed->feed.sec)
+						continue;
+					if (dvbdmx->filter[j].state == DMX_STATE_GO)
+						dvbdmx->filter[j].state = DMX_STATE_READY;
+				}
+			}
 			av7110_start_feed(feed);
+		}
 	}
 
 	if (mode)
@@ -1483,9 +1500,9 @@
 		if (ret == -ENOENT) {
 			printk(KERN_ERR "dvb-ttpci: could not load firmware,"
 			       " file not found: dvb-ttpci-01.fw\n");
-			printk(KERN_ERR "dvb-ttpci: usually this should be in"
-			       " /usr/lib/hotplug/firmware\n");
-			printk(KERN_ERR "dvb-ttpci: and can be downloaded here"
+			printk(KERN_ERR "dvb-ttpci: usually this should be in "
+			       "/usr/lib/hotplug/firmware or /lib/firmware\n");
+			printk(KERN_ERR "dvb-ttpci: and can be downloaded from"
 			       " http://www.linuxtv.org/download/dvb/firmware/\n");
 		} else
 			printk(KERN_ERR "dvb-ttpci: cannot request firmware"
@@ -2110,8 +2127,10 @@
 	struct av7110* av7110 = fe->dvb->priv;
 
 	int ret = av7110_fe_lock_fix(av7110, 0);
-	if (!ret)
+	if (!ret) {
+		av7110->saved_fe_params = *params;
 		ret = av7110->fe_set_frontend(fe, params);
+	}
 	return ret;
 }
 
@@ -2153,8 +2172,10 @@
 	struct av7110* av7110 = fe->dvb->priv;
 
 	int ret = av7110_fe_lock_fix(av7110, 0);
-	if (!ret)
+	if (!ret) {
+		av7110->saved_master_cmd = *cmd;
 		ret = av7110->fe_diseqc_send_master_cmd(fe, cmd);
+	}
 	return ret;
 }
 
@@ -2163,8 +2184,10 @@
 	struct av7110* av7110 = fe->dvb->priv;
 
 	int ret = av7110_fe_lock_fix(av7110, 0);
-	if (!ret)
+	if (!ret) {
+		av7110->saved_minicmd = minicmd;
 		ret = av7110->fe_diseqc_send_burst(fe, minicmd);
+	}
 	return ret;
 }
 
@@ -2173,8 +2196,10 @@
 	struct av7110* av7110 = fe->dvb->priv;
 
 	int ret = av7110_fe_lock_fix(av7110, 0);
-	if (!ret)
+	if (!ret) {
+		av7110->saved_tone = tone;
 		ret = av7110->fe_set_tone(fe, tone);
+	}
 	return ret;
 }
 
@@ -2183,12 +2208,14 @@
 	struct av7110* av7110 = fe->dvb->priv;
 
 	int ret = av7110_fe_lock_fix(av7110, 0);
-	if (!ret)
+	if (!ret) {
+		av7110->saved_voltage = voltage;
 		ret = av7110->fe_set_voltage(fe, voltage);
+	}
 	return ret;
 }
 
-static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned int cmd)
+static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned long cmd)
 {
 	struct av7110* av7110 = fe->dvb->priv;
 
@@ -2198,6 +2225,23 @@
 	return ret;
 }
 
+static void dvb_s_recover(struct av7110* av7110)
+{
+	av7110_fe_init(av7110->fe);
+
+	av7110_fe_set_voltage(av7110->fe, av7110->saved_voltage);
+	if (av7110->saved_master_cmd.msg_len) {
+		msleep(20);
+		av7110_fe_diseqc_send_master_cmd(av7110->fe, &av7110->saved_master_cmd);
+	}
+	msleep(20);
+	av7110_fe_diseqc_send_burst(av7110->fe, av7110->saved_minicmd);
+	msleep(20);
+	av7110_fe_set_tone(av7110->fe, av7110->saved_tone);
+
+	av7110_fe_set_frontend(av7110->fe, &av7110->saved_fe_params);
+}
+
 static u8 read_pwm(struct av7110* av7110)
 {
 	u8 b = 0xff;
@@ -2235,6 +2279,7 @@
 				av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
 				av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
 				av7110->fe->ops->set_tone = av7110_set_tone;
+				av7110->recover = dvb_s_recover;
 				break;
 			}
 
@@ -2244,15 +2289,17 @@
 				av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
 				av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
 				av7110->fe->ops->set_tone = av7110_set_tone;
+				av7110->recover = dvb_s_recover;
 				break;
 			}
 
 			// Try the grundig 29504-451
-		        av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
+			av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
 			if (av7110->fe) {
 				av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
 				av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
 				av7110->fe->ops->set_tone = av7110_set_tone;
+				av7110->recover = dvb_s_recover;
 				break;
 			}
 
@@ -2274,12 +2321,12 @@
 		case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X
 
 			// ALPS TDLB7
-		        av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap);
+			av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap);
 			break;
 
 		case 0x0002: // Hauppauge/TT DVB-C premium rev2.X
 
-		        av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
+			av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
 			break;
 
 		case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */
@@ -2289,6 +2336,7 @@
 				av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
 				av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
 				av7110->fe->ops->set_tone = av7110_set_tone;
+				av7110->recover = dvb_s_recover;
 			}
 			break;
 
@@ -2314,8 +2362,11 @@
 		case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */
 			/* ALPS BSBE1 */
 			av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap);
-			if (av7110->fe)
+			if (av7110->fe) {
 				av7110->fe->ops->set_voltage = lnbp21_set_voltage;
+				av7110->fe->ops->dishnetwork_send_legacy_command = NULL;
+				av7110->recover = dvb_s_recover;
+			}
 			break;
 		}
 	}
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h
index cce00ef..6ea30df 100644
--- a/drivers/media/dvb/ttpci/av7110.h
+++ b/drivers/media/dvb/ttpci/av7110.h
@@ -98,7 +98,8 @@
 	int adac_type;	       /* audio DAC type */
 #define DVB_ADAC_TI	  0
 #define DVB_ADAC_CRYSTAL  1
-#define DVB_ADAC_MSP	  2
+#define DVB_ADAC_MSP34x0  2
+#define DVB_ADAC_MSP34x5  3
 #define DVB_ADAC_NONE	 -1
 
 
@@ -228,6 +229,9 @@
 	struct dvb_video_events  video_events;
 	video_size_t		 video_size;
 
+	u16			wssMode;
+	u16			wssData;
+
 	u32			ir_config;
 	u32			ir_command;
 	void			(*ir_handler)(struct av7110 *av7110, u32 ircom);
@@ -245,6 +249,15 @@
 
 	struct dvb_frontend* fe;
 	fe_status_t fe_status;
+
+	/* crash recovery */
+	void				(*recover)(struct av7110* av7110);
+	struct dvb_frontend_parameters	saved_fe_params;
+	fe_sec_voltage_t		saved_voltage;
+	fe_sec_tone_mode_t		saved_tone;
+	struct dvb_diseqc_master_cmd	saved_master_cmd;
+	fe_sec_mini_cmd_t		saved_minicmd;
+
 	int (*fe_init)(struct dvb_frontend* fe);
 	int (*fe_read_status)(struct dvb_frontend* fe, fe_status_t* status);
 	int (*fe_diseqc_reset_overload)(struct dvb_frontend* fe);
@@ -252,7 +265,7 @@
 	int (*fe_diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd);
 	int (*fe_set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone);
 	int (*fe_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
-	int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned int cmd);
+	int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd);
 	int (*fe_set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
 };
 
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index 0696a5a..400face 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -309,7 +309,7 @@
 		i2c_writereg(av7110, 0x20, 0x04, volright);
 		return 0;
 
-	case DVB_ADAC_MSP:
+	case DVB_ADAC_MSP34x0:
 		vol  = (volleft > volright) ? volleft : volright;
 		val	= (vol * 0x73 / 255) << 8;
 		if (vol > 0)
@@ -1256,7 +1256,9 @@
 		break;
 
 	case AUDIO_SET_BYPASS_MODE:
-		ret = -EINVAL;
+		if (FW_VERSION(av7110->arm_app) < 0x2621)
+			ret = -EINVAL;
+		av7110->audiostate.bypass_mode = (int)arg;
 		break;
 
 	case AUDIO_CHANNEL_SELECT:
@@ -1295,7 +1297,11 @@
 		break;
 
 	case AUDIO_GET_CAPABILITIES:
-		*(int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2;
+		if (FW_VERSION(av7110->arm_app) < 0x2621)
+			*(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2;
+		else
+			*(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_DTS | AUDIO_CAP_AC3 |
+						AUDIO_CAP_MP1 | AUDIO_CAP_MP2;
 		break;
 
 	case AUDIO_CLEAR_BUFFER:
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
index 87106e8..cb37745 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -230,6 +230,8 @@
 
 	dprintk(4, "%p\n", av7110);
 
+	av7110->arm_ready = 0;
+
 	saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
 
 	/* Disable DEBI and GPIO irq */
@@ -361,6 +363,7 @@
 			break;
 		if (err) {
 			printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__);
+			av7110->arm_errors++;
 			return -ETIMEDOUT;
 		}
 		msleep(1);
@@ -1206,9 +1209,9 @@
 	switch (cap->cmd) {
 	case OSD_CAP_MEMSIZE:
 		if (FW_4M_SDRAM(av7110->arm_app))
-		        cap->val = 1000000;
+			cap->val = 1000000;
 		else
-		        cap->val = 92000;
+			cap->val = 92000;
 		return 0;
 	default:
 		return -EINVAL;
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h
index 2a5e87b..84b8329 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.h
+++ b/drivers/media/dvb/ttpci/av7110_hw.h
@@ -167,7 +167,8 @@
 	LoadVidCode,
 	SetMonitorType,
 	SetPanScanType,
-	SetFreezeMode
+	SetFreezeMode,
+	SetWSSConfig
 };
 
 enum av7110_rec_play_state {
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c
index f5e59fc..9138132 100644
--- a/drivers/media/dvb/ttpci/av7110_ir.c
+++ b/drivers/media/dvb/ttpci/av7110_ir.c
@@ -17,6 +17,8 @@
 static struct av7110 *av_list[4];
 static struct input_dev *input_dev;
 
+static u8 delay_timer_finished;
+
 static u16 key_map [256] = {
 	KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
 	KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO,
@@ -112,13 +114,16 @@
 	if (timer_pending(&keyup_timer)) {
 		del_timer(&keyup_timer);
 		if (keyup_timer.data != keycode || new_toggle != old_toggle) {
+			delay_timer_finished = 0;
 			input_event(input_dev, EV_KEY, keyup_timer.data, !!0);
 			input_event(input_dev, EV_KEY, keycode, !0);
 		} else
-			input_event(input_dev, EV_KEY, keycode, 2);
-
-	} else
+			if (delay_timer_finished)
+				input_event(input_dev, EV_KEY, keycode, 2);
+	} else {
+		delay_timer_finished = 0;
 		input_event(input_dev, EV_KEY, keycode, !0);
+	}
 
 	keyup_timer.expires = jiffies + UP_TIMEOUT;
 	keyup_timer.data = keycode;
@@ -145,7 +150,8 @@
 
 static void input_repeat_key(unsigned long data)
 {
-       /* dummy routine to disable autorepeat in the input driver */
+	/* called by the input driver after rep[REP_DELAY] ms */
+	delay_timer_finished = 1;
 }
 
 
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index b5aea41..94cf38c 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -490,6 +490,58 @@
 		dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
 		break;
 	}
+	case VIDIOC_G_SLICED_VBI_CAP:
+	{
+		struct v4l2_sliced_vbi_cap *cap = arg;
+		dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n");
+		memset(cap, 0, sizeof *cap);
+		if (FW_VERSION(av7110->arm_app) >= 0x2623) {
+			cap->service_set = V4L2_SLICED_WSS_625;
+			cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
+		}
+		break;
+	}
+	case VIDIOC_G_FMT:
+	{
+		struct v4l2_format *f = arg;
+		dprintk(2, "VIDIOC_G_FMT:\n");
+		if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ||
+		    FW_VERSION(av7110->arm_app) < 0x2623)
+			return -EAGAIN; /* handled by core driver */
+		memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
+		if (av7110->wssMode) {
+			f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
+			f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
+			f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data);
+		}
+		break;
+	}
+	case VIDIOC_S_FMT:
+	{
+		struct v4l2_format *f = arg;
+		dprintk(2, "VIDIOC_S_FMT\n");
+		if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ||
+		    FW_VERSION(av7110->arm_app) < 0x2623)
+			return -EAGAIN; /* handled by core driver */
+		if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 &&
+		    f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) {
+			memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
+			/* WSS controlled by firmware */
+			av7110->wssMode = 0;
+			av7110->wssData = 0;
+			return av7110_fw_cmd(av7110, COMTYPE_ENCODER,
+					     SetWSSConfig, 1, 0);
+		} else {
+			memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
+			f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
+			f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
+			f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data);
+			/* WSS controlled by userspace */
+			av7110->wssMode = 1;
+			av7110->wssData = 0;
+		}
+		break;
+	}
 	default:
 		printk("no such ioctl\n");
 		return -ENOIOCTLCMD;
@@ -497,6 +549,46 @@
 	return 0;
 }
 
+static int av7110_vbi_reset(struct inode *inode, struct file *file)
+{
+	struct saa7146_fh *fh = file->private_data;
+	struct saa7146_dev *dev = fh->dev;
+	struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
+
+	dprintk(2, "%s\n", __FUNCTION__);
+	av7110->wssMode = 0;
+	av7110->wssData = 0;
+	if (FW_VERSION(av7110->arm_app) < 0x2623)
+		return 0;
+	else
+		return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0);
+}
+
+static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size_t count, loff_t *ppos)
+{
+	struct saa7146_fh *fh = file->private_data;
+	struct saa7146_dev *dev = fh->dev;
+	struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
+	struct v4l2_sliced_vbi_data d;
+	int rc;
+
+	dprintk(2, "%s\n", __FUNCTION__);
+	if (FW_VERSION(av7110->arm_app) < 0x2623 || !av7110->wssMode || count != sizeof d)
+		return -EINVAL;
+	if (copy_from_user(&d, data, count))
+		return -EFAULT;
+	if ((d.id != 0 && d.id != V4L2_SLICED_WSS_625) || d.field != 0 || d.line != 23)
+		return -EINVAL;
+	if (d.id) {
+		av7110->wssData = ((d.data[1] << 8) & 0x3f00) | d.data[0];
+		rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig,
+				   2, 1, av7110->wssData);
+	} else {
+		av7110->wssData = 0;
+		rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0);
+	}
+	return (rc < 0) ? rc : count;
+}
 
 /****************************************************************************
  * INITIALIZATION
@@ -512,6 +604,9 @@
 	{ VIDIOC_S_TUNER,	SAA7146_EXCLUSIVE },
 	{ VIDIOC_G_AUDIO,	SAA7146_EXCLUSIVE },
 	{ VIDIOC_S_AUDIO,	SAA7146_EXCLUSIVE },
+	{ VIDIOC_G_SLICED_VBI_CAP, SAA7146_EXCLUSIVE },
+	{ VIDIOC_G_FMT,		SAA7146_BEFORE },
+	{ VIDIOC_S_FMT,		SAA7146_BEFORE },
 	{ 0, 0 }
 };
 
@@ -587,7 +682,7 @@
 
 	printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n",
 		av7110->dvb_adapter.num);
-	av7110->adac_type = DVB_ADAC_MSP;
+	av7110->adac_type = DVB_ADAC_MSP34x0;
 	msleep(100); // the probing above resets the msp...
 	msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1);
 	msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2);
@@ -692,12 +787,11 @@
 		saa7146_vv_release(dev);
 		return -ENODEV;
 	}
-	if (av7110->analog_tuner_flags) {
-		if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) {
-			ERR(("cannot register vbi v4l2 device. skipping.\n"));
-		} else {
+	if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) {
+		ERR(("cannot register vbi v4l2 device. skipping.\n"));
+	} else {
+		if (av7110->analog_tuner_flags)
 			av7110->analog_tuner_flags |= ANALOG_TUNER_VBI;
-		}
 	}
 	return 0;
 }
@@ -778,7 +872,7 @@
 static struct saa7146_ext_vv av7110_vv_data_st = {
 	.inputs		= 1,
 	.audios		= 1,
-	.capabilities	= 0,
+	.capabilities	= V4L2_CAP_SLICED_VBI_OUTPUT,
 	.flags		= 0,
 
 	.stds		= &standard[0],
@@ -787,12 +881,16 @@
 
 	.ioctls		= &ioctls[0],
 	.ioctl		= av7110_ioctl,
+
+	.vbi_fops.open	= av7110_vbi_reset,
+	.vbi_fops.release = av7110_vbi_reset,
+	.vbi_fops.write	= av7110_vbi_write,
 };
 
 static struct saa7146_ext_vv av7110_vv_data_c = {
 	.inputs		= 1,
 	.audios		= 1,
-	.capabilities	= V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
+	.capabilities	= V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT,
 	.flags		= SAA7146_USE_PORT_B_FOR_VBI,
 
 	.stds		= &standard[0],
@@ -801,5 +899,9 @@
 
 	.ioctls		= &ioctls[0],
 	.ioctl		= av7110_ioctl,
+
+	.vbi_fops.open	= av7110_vbi_reset,
+	.vbi_fops.release = av7110_vbi_reset,
+	.vbi_fops.write	= av7110_vbi_write,
 };
 
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 9f51bae..f9d0045 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -127,7 +127,7 @@
 	saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
 	udelay(1);
 
-	result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 0);
+	result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1);
 
 	if (result == -ETIMEDOUT)
 		budget_av->slot_status = 0;
@@ -145,7 +145,7 @@
 	saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
 	udelay(1);
 
-	result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 0);
+	result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1);
 
 	if (result == -ETIMEDOUT)
 		budget_av->slot_status = 0;
@@ -192,7 +192,7 @@
 {
 	struct budget_av *budget_av = (struct budget_av *) ca->data;
 	struct saa7146_dev *saa = budget_av->budget.dev;
-	int timeout = 500; // 5 seconds (4.4.6 Ready)
+	int timeout = 50; // 5 seconds (4.4.6 Ready)
 
 	if (slot != 0)
 		return -EINVAL;
@@ -256,19 +256,37 @@
 {
 	struct budget_av *budget_av = (struct budget_av *) ca->data;
 	struct saa7146_dev *saa = budget_av->budget.dev;
+	int cam_present = 0;
 
 	if (slot != 0)
 		return -EINVAL;
 
-	if (!budget_av->slot_status) {
+	if (!budget_av->slot_status)
+	{
+		// first of all test the card detect line
 		saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
 		udelay(1);
 		if (saa7146_read(saa, PSR) & MASK_06)
 		{
+			cam_present = 1;
+		}
+		saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
+
+		// that is unreliable however, so try and read from IO memory
+		if (!cam_present)
+		{
+			saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
+			if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) != -ETIMEDOUT)
+			{
+				cam_present = 1;
+			}
+		}
+
+		// did we find something?
+		if (cam_present) {
 			printk(KERN_INFO "budget-av: cam inserted\n");
 			budget_av->slot_status = 1;
 		}
-		saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
 	} else if (!open) {
 		saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
 		if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT)
@@ -484,6 +502,140 @@
 	return 0;
 }
 
+#define MIN2(a,b) ((a) < (b) ? (a) : (b))
+#define MIN3(a,b,c) MIN2(MIN2(a,b),c)
+
+static int philips_su1278sh2_tua6100_pll_set(struct dvb_frontend *fe,
+					struct i2c_adapter *i2c,
+					struct dvb_frontend_parameters *params)
+{
+	u8 reg0 [2] = { 0x00, 0x00 };
+	u8 reg1 [4] = { 0x01, 0x00, 0x00, 0x00 };
+	u8 reg2 [3] = { 0x02, 0x00, 0x00 };
+	int _fband;
+	int first_ZF;
+	int R, A, N, P, M;
+	struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = NULL,.len = 0 };
+	int freq = params->frequency;
+
+	first_ZF = (freq) / 1000;
+
+	if (abs(MIN2(abs(first_ZF-1190),abs(first_ZF-1790))) <
+		   abs(MIN3(abs(first_ZF-1202),abs(first_ZF-1542),abs(first_ZF-1890))))
+		_fband = 2;
+	else
+		_fband = 3;
+
+	if (_fband == 2) {
+		if (((first_ZF >= 950) && (first_ZF < 1350)) ||
+				    ((first_ZF >= 1430) && (first_ZF < 1950)))
+			reg0[1] = 0x07;
+		else if (((first_ZF >= 1350) && (first_ZF < 1430)) ||
+					 ((first_ZF >= 1950) && (first_ZF < 2150)))
+			reg0[1] = 0x0B;
+	}
+
+	if(_fband == 3) {
+		if (((first_ZF >= 950) && (first_ZF < 1350)) ||
+				    ((first_ZF >= 1455) && (first_ZF < 1950)))
+			reg0[1] = 0x07;
+		else if (((first_ZF >= 1350) && (first_ZF < 1420)) ||
+					 ((first_ZF >= 1950) && (first_ZF < 2150)))
+			reg0[1] = 0x0B;
+		else if ((first_ZF >= 1420) && (first_ZF < 1455))
+			reg0[1] = 0x0F;
+	}
+
+	if (first_ZF > 1525)
+		reg1[1] |= 0x80;
+	else
+		reg1[1] &= 0x7F;
+
+	if (_fband == 2) {
+		if (first_ZF > 1430) { /* 1430MHZ */
+			reg1[1] &= 0xCF; /* N2 */
+			reg2[1] &= 0xCF; /* R2 */
+			reg2[1] |= 0x10;
+		} else {
+			reg1[1] &= 0xCF; /* N2 */
+			reg1[1] |= 0x20;
+			reg2[1] &= 0xCF; /* R2 */
+			reg2[1] |= 0x10;
+		}
+	}
+
+	if (_fband == 3) {
+		if ((first_ZF >= 1455) &&
+				   (first_ZF < 1630)) {
+			reg1[1] &= 0xCF; /* N2 */
+			reg1[1] |= 0x20;
+			reg2[1] &= 0xCF; /* R2 */
+				   } else {
+					   if (first_ZF < 1455) {
+						   reg1[1] &= 0xCF; /* N2 */
+						   reg1[1] |= 0x20;
+						   reg2[1] &= 0xCF; /* R2 */
+						   reg2[1] |= 0x10;
+					   } else {
+						   if (first_ZF >= 1630) {
+							   reg1[1] &= 0xCF; /* N2 */
+							   reg2[1] &= 0xCF; /* R2 */
+							   reg2[1] |= 0x10;
+						   }
+					   }
+				   }
+	}
+
+	/* set ports, enable P0 for symbol rates > 4Ms/s */
+	if (params->u.qpsk.symbol_rate >= 4000000)
+		reg1[1] |= 0x0c;
+	else
+		reg1[1] |= 0x04;
+
+	reg2[1] |= 0x0c;
+
+	R = 64;
+	A = 64;
+	P = 64;	 //32
+
+	M = (freq * R) / 4;		/* in Mhz */
+	N = (M - A * 1000) / (P * 1000);
+
+	reg1[1] |= (N >> 9) & 0x03;
+	reg1[2]	 = (N >> 1) & 0xff;
+	reg1[3]	 = (N << 7) & 0x80;
+
+	reg2[1] |= (R >> 8) & 0x03;
+	reg2[2]	 = R & 0xFF;	/* R */
+
+	reg1[3] |= A & 0x7f;	/* A */
+
+	if (P == 64)
+		reg1[1] |= 0x40; /* Prescaler 64/65 */
+
+	reg0[1] |= 0x03;
+
+	/* already enabled - do not reenable i2c repeater or TX fails */
+	msg.buf = reg0;
+	msg.len = sizeof(reg0);
+	if (i2c_transfer(i2c, &msg, 1) != 1)
+		return -EIO;
+
+	stv0299_enable_plli2c(fe);
+	msg.buf = reg1;
+	msg.len = sizeof(reg1);
+	if (i2c_transfer(i2c, &msg, 1) != 1)
+		return -EIO;
+
+	stv0299_enable_plli2c(fe);
+	msg.buf = reg2;
+	msg.len = sizeof(reg2);
+	if (i2c_transfer(i2c, &msg, 1) != 1)
+		return -EIO;
+
+	return 0;
+}
+
 static u8 typhoon_cinergy1200s_inittab[] = {
 	0x01, 0x15,
 	0x02, 0x30,
@@ -553,6 +705,18 @@
 	.pll_set = philips_su1278_ty_ci_pll_set,
 };
 
+static struct stv0299_config cinergy_1200s_1894_0010_config = {
+	.demod_address = 0x68,
+	.inittab = typhoon_cinergy1200s_inittab,
+	.mclk = 88000000UL,
+	.invert = 1,
+	.skip_reinit = 0,
+	.lock_output = STV0229_LOCKOUTPUT_1,
+	.volt13_op0_op1 = STV0299_VOLT13_OP0,
+	.min_delay_ms = 100,
+	.set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
+	.pll_set = philips_su1278sh2_tua6100_pll_set,
+};
 
 static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
 {
@@ -749,6 +913,15 @@
 	switch (saa->pci->subsystem_device) {
 
 	case SUBID_DVBS_KNC1:
+		if (saa->pci->subsystem_vendor == 0x1894) {
+			fe = stv0299_attach(&cinergy_1200s_1894_0010_config,
+					     &budget_av->budget.i2c_adap);
+		} else {
+			fe = stv0299_attach(&typhoon_config,
+					     &budget_av->budget.i2c_adap);
+		}
+		break;
+
 	case SUBID_DVBS_KNC1_PLUS:
 	case SUBID_DVBS_TYPHOON:
 		fe = stv0299_attach(&typhoon_config,
@@ -1003,6 +1176,7 @@
 static struct pci_device_id pci_tbl[] = {
 	MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56),
 	MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010),
+	MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010),
 	MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
 	MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
 	MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c
index 017fcbc..633e68c 100644
--- a/drivers/media/dvb/ttpci/budget-core.c
+++ b/drivers/media/dvb/ttpci/budget-core.c
@@ -404,9 +404,7 @@
 	tasklet_init(&budget->vpe_tasklet, vpeirq, (unsigned long) budget);
 
 	/* frontend power on */
-	if (bi->type == BUDGET_FS_ACTIVY)
-		saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI);
-	else
+	if (bi->type != BUDGET_FS_ACTIVY)
 		saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
 
 	if (budget_register(budget) == 0) {
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index fafe640..238c77b 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -112,6 +112,7 @@
  *   Routines for the Fujitsu Siemens Activy budget card
  *   22 kHz tone and DiSEqC are handled by the frontend.
  *   Voltage must be set here.
+ *   GPIO 1: LNBP EN, GPIO 2: LNBP VSEL
  */
 static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage)
 {
@@ -121,11 +122,16 @@
 
 	switch (voltage) {
 		case SEC_VOLTAGE_13:
+			saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI);
 			saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO);
 			break;
 		case SEC_VOLTAGE_18:
+			saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI);
 			saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
 			break;
+		case SEC_VOLTAGE_OFF:
+			saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO);
+			break;
 		default:
 			return -EINVAL;
 	}
@@ -206,7 +212,7 @@
 	return 0;
 }
 
-static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, int arg)
+static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, long arg)
 {
 	struct budget* budget = (struct budget*) fe->dvb->priv;
 	u8 buf;
@@ -580,6 +586,7 @@
 		if (budget->dvb_frontend) {
 			budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage;
 			budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
+			budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL;
 			if (lnbp21_init(budget)) {
 				printk("%s: No LNBP21 found!\n", __FUNCTION__);
 				goto error_out;
@@ -624,7 +631,7 @@
 		budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap);
 		if (budget->dvb_frontend) {
 			budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage;
-			break;
+			budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL;
 		}
 		break;
 
@@ -632,7 +639,7 @@
 		budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap);
 		if (budget->dvb_frontend) {
 			budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage;
-			break;
+			budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL;
 		}
 		break;
 
diff --git a/drivers/media/dvb/ttpci/ttpci-eeprom.c b/drivers/media/dvb/ttpci/ttpci-eeprom.c
index 18aa22b..1f31e91 100644
--- a/drivers/media/dvb/ttpci/ttpci-eeprom.c
+++ b/drivers/media/dvb/ttpci/ttpci-eeprom.c
@@ -13,7 +13,7 @@
     Holger Waechtler	Convergence
 
     Copyright (C) 2002-2003 Ralph Metzler <rjkm@metzlerbros.de>
-		            Metzler Brothers Systementwicklung GbR
+			    Metzler Brothers Systementwicklung GbR
 
     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
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig
index c6c1d41..914587d 100644
--- a/drivers/media/dvb/ttusb-budget/Kconfig
+++ b/drivers/media/dvb/ttusb-budget/Kconfig
@@ -10,7 +10,7 @@
 	  Support for external USB adapters designed by Technotrend and
 	  produced by Hauppauge, shipped under the brand name 'Nova-USB'.
 
-          These devices don't have a MPEG decoder built in, so you need
+	  These devices don't have a MPEG decoder built in, so you need
 	  an external software decoder to watch TV.
 
 	  Say Y if you own such a device and want to use it.
diff --git a/drivers/media/dvb/ttusb-dec/Kconfig b/drivers/media/dvb/ttusb-dec/Kconfig
index c334526..8361101 100644
--- a/drivers/media/dvb/ttusb-dec/Kconfig
+++ b/drivers/media/dvb/ttusb-dec/Kconfig
@@ -8,14 +8,15 @@
 	  produced by Hauppauge, shipped under the brand name 'DEC2000-t'
 	  and 'DEC3000-s'.
 
-          Even if these devices have a MPEG decoder built in, they transmit
+	  Even if these devices have a MPEG decoder built in, they transmit
 	  only compressed MPEG data over the USB bus, so you need
 	  an external software decoder to watch TV on your computer.
 
-          This driver needs external firmware. Please use the commands
-          "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2000t",
-          "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2540t",
-          "<kerneldir>/Documentation/dvb/get_dvb_firmware dec3000s",
-          download/extract them, and then copy them to /usr/lib/hotplug/firmware.
+	  This driver needs external firmware. Please use the commands
+	  "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2000t",
+	  "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2540t",
+	  "<kerneldir>/Documentation/dvb/get_dvb_firmware dec3000s",
+	  download/extract them, and then copy them to /usr/lib/hotplug/firmware
+	  or /lib/firmware (depending on configuration of firmware hotplug).
 
 	  Say Y if you own such a device and want to use it.
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 8abc218..d8966d1 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -369,7 +369,7 @@
 
 static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data)
 {
-	struct ttusb_dec *dec = (struct ttusb_dec *)priv;
+	struct ttusb_dec *dec = priv;
 
 	dec->audio_filter->feed->cb.ts(data, 188, NULL, 0,
 				       &dec->audio_filter->feed->feed.ts,
@@ -380,7 +380,7 @@
 
 static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data)
 {
-	struct ttusb_dec *dec = (struct ttusb_dec *)priv;
+	struct ttusb_dec *dec = priv;
 
 	dec->video_filter->feed->cb.ts(data, 188, NULL, 0,
 				       &dec->video_filter->feed->feed.ts,
@@ -965,8 +965,8 @@
 
 	case DMX_TS_PES_TELETEXT:
 		dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid;
-		dprintk("  pes_type: DMX_TS_PES_TELETEXT\n");
-		break;
+		dprintk("  pes_type: DMX_TS_PES_TELETEXT(not supported)\n");
+		return -ENOSYS;
 
 	case DMX_TS_PES_PCR:
 		dprintk("  pes_type: DMX_TS_PES_PCR\n");
@@ -975,8 +975,8 @@
 		break;
 
 	case DMX_TS_PES_OTHER:
-		dprintk("  pes_type: DMX_TS_PES_OTHER\n");
-		break;
+		dprintk("  pes_type: DMX_TS_PES_OTHER(not supported)\n");
+		return -ENOSYS;
 
 	default:
 		dprintk("  pes_type: unknown (%d)\n", dvbdmxfeed->pes_type);
@@ -1182,7 +1182,7 @@
 		     (unsigned long)dec);
 }
 
-static int ttusb_init_rc(struct ttusb_dec *dec)
+static int ttusb_init_rc( struct ttusb_dec *dec)
 {
 	struct input_dev *input_dev;
 	u8 b[] = { 0x00, 0x01 };
@@ -1203,13 +1203,12 @@
 	input_dev->keycode = rc_keys;
 
 	for (i = 0; i < ARRAY_SIZE(rc_keys); i++)
-		set_bit(rc_keys[i], input_dev->keybit);
+		  set_bit(rc_keys[i], input_dev->keybit);
 
 	input_register_device(input_dev);
 
 	if (usb_submit_urb(dec->irq_urb, GFP_KERNEL))
 		printk("%s: usb_submit_urb failed\n",__FUNCTION__);
-
 	/* enable irq pipe */
 	ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL);
 
@@ -1395,6 +1394,7 @@
 			/* We can't trust the USB IDs that some firmwares
 			   give the box */
 			switch (model) {
+			case 0x00070001:
 			case 0x00070008:
 			case 0x0007000c:
 				ttusb_dec_set_model(dec, TTUSB_DEC3000S);
@@ -1588,7 +1588,7 @@
 			   int param_length, const u8 params[],
 			   int *result_length, u8 cmd_result[])
 {
-	struct ttusb_dec* dec = (struct ttusb_dec*) fe->dvb->priv;
+	struct ttusb_dec* dec = fe->dvb->priv;
 	return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result);
 }
 
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
index 725af3a..a5a4617 100644
--- a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
+++ b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
@@ -42,8 +42,39 @@
 
 static int ttusbdecfe_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
-	*status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
-		  FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
+	struct ttusbdecfe_state* state = fe->demodulator_priv;
+	u8 b[] = { 0x00, 0x00, 0x00, 0x00,
+		   0x00, 0x00, 0x00, 0x00 };
+	u8 result[4];
+	int len, ret;
+
+	*status=0;
+
+	ret=state->config->send_command(fe, 0x73, sizeof(b), b, &len, result);
+	if(ret)
+		return ret;
+
+	if(len != 4) {
+		printk(KERN_ERR "%s: unexpected reply\n", __FUNCTION__);
+		return -EIO;
+	}
+
+	switch(result[3]) {
+		case 1:  /* not tuned yet */
+		case 2:  /* no signal/no lock*/
+			break;
+		case 3:	 /* signal found and locked*/
+			*status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
+			FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
+			break;
+		case 4:
+			*status = FE_TIMEDOUT;
+			break;
+		default:
+			pr_info("%s: returned unknown value: %d\n",
+				__FUNCTION__, result[3]);
+			return -EIO;
+	}
 
 	return 0;
 }
@@ -64,6 +95,16 @@
 	return 0;
 }
 
+static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe,
+					struct dvb_frontend_tune_settings* fesettings)
+{
+		fesettings->min_delay_ms = 1500;
+		/* Drift compensation makes no sense for DVB-T */
+		fesettings->step_size = 0;
+		fesettings->max_drift = 0;
+		return 0;
+}
+
 static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
 	struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
@@ -212,6 +253,8 @@
 
 	.set_frontend = ttusbdecfe_dvbt_set_frontend,
 
+	.get_tune_settings = ttusbdecfe_dvbt_get_tune_settings,
+
 	.read_status = ttusbdecfe_read_status,
 };
 
@@ -223,11 +266,11 @@
 		.frequency_min		= 950000,
 		.frequency_max		= 2150000,
 		.frequency_stepsize	= 125,
+		.symbol_rate_min        = 1000000,  /* guessed */
+		.symbol_rate_max        = 45000000, /* guessed */
 		.caps =	FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
 			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-			FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-			FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
-			FE_CAN_HIERARCHY_AUTO,
+			FE_CAN_QPSK
 	},
 
 	.release = ttusbdecfe_release,
diff --git a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c
index c2ebe87..dc292da 100644
--- a/drivers/media/radio/miropcm20-radio.c
+++ b/drivers/media/radio/miropcm20-radio.c
@@ -220,6 +220,7 @@
 	.open           = video_exclusive_open,
 	.release        = video_exclusive_release,
 	.ioctl		= pcm20_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek         = no_llseek,
 };
 
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index 877c770..914deab 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -299,6 +299,7 @@
 	.open           = video_exclusive_open,
 	.release        = video_exclusive_release,
 	.ioctl	        = rt_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek         = no_llseek,
 };
 
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index 5319a9c..523be82 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -256,6 +256,7 @@
 	.open           = video_exclusive_open,
 	.release        = video_exclusive_release,
 	.ioctl		= az_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek         = no_llseek,
 };
 
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index 9b04063..f1b5ac8 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -490,6 +490,7 @@
 	.release       	= cadet_release,
 	.read		= cadet_read,
 	.ioctl		= cadet_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek         = no_llseek,
 };
 
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index 78b2888..69ac8aa 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -301,6 +301,7 @@
 	.open           = video_exclusive_open,
 	.release        = video_exclusive_release,
 	.ioctl		= gemtek_pci_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek         = no_llseek,
 };
 
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 6418f03..47173be 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -233,6 +233,7 @@
 	.open           = video_exclusive_open,
 	.release        = video_exclusive_release,
 	.ioctl		= gemtek_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek         = no_llseek,
 };
 
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
index e5e2021..c30effd 100644
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -72,6 +72,7 @@
 	.open           = video_exclusive_open,
 	.release        = video_exclusive_release,
 	.ioctl		= radio_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek         = no_llseek,
 };
 
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index 7b33d8f..c975ddd 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -80,6 +80,7 @@
 	.open           = video_exclusive_open,
 	.release        = video_exclusive_release,
 	.ioctl	        = radio_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek         = no_llseek,
 };
 static struct video_device maxiradio_radio =
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index b2256d6..28a47c9 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -199,6 +199,7 @@
 	.open           = video_exclusive_open,
 	.release        = video_exclusive_release,
 	.ioctl		= rt_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek         = no_llseek,
 };
 
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 6f03ce4..0229f79 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -225,6 +225,7 @@
 	.open           = video_exclusive_open,
 	.release        = video_exclusive_release,
 	.ioctl		= fmi_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek         = no_llseek,
 };
 
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index 71971e9..099ffb3 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -48,7 +48,7 @@
 static int radio_nr = -1;
 
 /* hw precision is 12.5 kHz
- * It is only usefull to give freq in intervall of 200 (=0.0125Mhz),
+ * It is only useful to give freq in intervall of 200 (=0.0125Mhz),
  * other bits will be truncated
  */
 #define RSF16_ENCODE(x)	((x)/200+856)
@@ -356,6 +356,7 @@
 	.open           = video_exclusive_open,
 	.release        = video_exclusive_release,
 	.ioctl          = fmr2_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek         = no_llseek,
 };
 
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index b03573c..fcfde2e 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -276,6 +276,7 @@
 	.open           = video_exclusive_open,
 	.release        = video_exclusive_release,
 	.ioctl		= tt_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek         = no_llseek,
 };
 
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
index b300bed..5a099a5 100644
--- a/drivers/media/radio/radio-trust.c
+++ b/drivers/media/radio/radio-trust.c
@@ -255,6 +255,7 @@
 	.open           = video_exclusive_open,
 	.release        = video_exclusive_release,
 	.ioctl		= tr_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek         = no_llseek,
 };
 
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
index f304f3c..8ac9a8e 100644
--- a/drivers/media/radio/radio-typhoon.c
+++ b/drivers/media/radio/radio-typhoon.c
@@ -261,6 +261,7 @@
 	.open           = video_exclusive_open,
 	.release        = video_exclusive_release,
 	.ioctl		= typhoon_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek         = no_llseek,
 };
 
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index 4c6d6fb..d590e80 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -313,6 +313,7 @@
 	.open           = video_exclusive_open,
 	.release        = video_exclusive_release,
 	.ioctl		= zol_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek         = no_llseek,
 };
 
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index fc87efc..2fe260f 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -7,6 +7,15 @@
 
 comment "Video Adapters"
 
+config VIDEO_ADV_DEBUG
+	bool "Enable advanced debug functionality"
+	depends on VIDEO_DEV
+	default n
+	---help---
+	  Say Y here to enable advanced debugging functionality on some
+	  V4L devices.
+	  In doubt, say N.
+
 config VIDEO_BT848
 	tristate "BT848 Video For Linux"
 	depends on VIDEO_DEV && PCI && I2C
@@ -342,6 +351,6 @@
 	depends on VIDEO_DEV && I2C && EXPERIMENTAL
 	---help---
 	  Say Y here to compile drivers for SAA7115, SAA7127 and CX25840
-	  video  decoders.
+	  video decoders.
 
 endmenu
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 82060f9..dd24896 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -3,15 +3,19 @@
 #
 
 bttv-objs	:=	bttv-driver.o bttv-cards.o bttv-if.o \
-			bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o
+			bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o \
+			bttv-input.o
 zoran-objs      :=	zr36120.o zr36120_i2c.o zr36120_mem.o
 zr36067-objs	:=	zoran_procfs.o zoran_device.o \
 			zoran_driver.o zoran_card.o
 tuner-objs	:=	tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o
-obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o
+
+msp3400-objs	:=	msp3400-driver.o msp3400-kthreads.o
+
+obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o compat_ioctl32.o
 
 obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \
-	tda7432.o tda9875.o ir-kbd-i2c.o ir-kbd-gpio.o
+	tda7432.o tda9875.o ir-kbd-i2c.o
 obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
 
 obj-$(CONFIG_VIDEO_ZR36120) += zoran.o
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index 881cdcb..7d5a068 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -749,6 +749,7 @@
 	.release	= video_exclusive_release,
 	.read		= ar_read,
 	.ioctl		= ar_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek		= no_llseek,
 };
 
diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c
index 1c3ff5f..dda4aa6 100644
--- a/drivers/media/video/bt832.c
+++ b/drivers/media/video/bt832.c
@@ -30,8 +30,9 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
-
 #include <media/audiochip.h>
+#include <media/v4l2-common.h>
+
 #include "bttv.h"
 #include "bt832.h"
 
@@ -42,9 +43,10 @@
 				       I2C_CLIENT_END };
 I2C_CLIENT_INSMOD;
 
-/* ---------------------------------------------------------------------- */
+int debug    = 0;    /* debug output */
+module_param(debug,            int, 0644);
 
-#define dprintk     if (debug) printk
+/* ---------------------------------------------------------------------- */
 
 static int bt832_detach(struct i2c_client *client);
 
@@ -61,23 +63,26 @@
 	int i,rc;
 	buf[0]=0x80; // start at register 0 with auto-increment
 	if (1 != (rc = i2c_master_send(i2c_client_s,buf,1)))
-		printk("bt832: i2c i/o error: rc == %d (should be 1)\n",rc);
+		v4l_err(i2c_client_s,"i2c i/o error: rc == %d (should be 1)\n",rc);
 
 	for(i=0;i<65;i++)
 		buf[i]=0;
 	if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65)))
-		printk("bt832: i2c i/o error: rc == %d (should be 65)\n",rc);
+		v4l_err(i2c_client_s,"i2c i/o error: rc == %d (should be 65)\n",rc);
 
 	// Note: On READ the first byte is the current index
 	//  (e.g. 0x80, what we just wrote)
 
-	if(1) {
+	if(debug>1) {
 		int i;
-		printk("BT832 hexdump:\n");
+		v4l_dbg(2,i2c_client_s,"hexdump:");
 		for(i=1;i<65;i++) {
 			if(i!=1) {
-			  if(((i-1)%8)==0) printk(" ");
-			  if(((i-1)%16)==0) printk("\n");
+				if(((i-1)%8)==0) printk(" ");
+				if(((i-1)%16)==0) {
+					printk("\n");
+					v4l_dbg(2,i2c_client_s,"hexdump:");
+				}
 			}
 			printk(" %02x",buf[i]);
 		}
@@ -96,56 +101,56 @@
 	bt832_hexdump(i2c_client_s,buf);
 
 	if(buf[0x40] != 0x31) {
-		printk("bt832: this i2c chip is no bt832 (id=%02x). Detaching.\n",buf[0x40]);
+		v4l_err(i2c_client_s,"This i2c chip is no bt832 (id=%02x). Detaching.\n",buf[0x40]);
 		kfree(buf);
 		return 0;
 	}
 
-	printk("Write 0 tp VPSTATUS\n");
+	v4l_err(i2c_client_s,"Write 0 tp VPSTATUS\n");
 	buf[0]=BT832_VP_STATUS; // Reg.52
 	buf[1]= 0x00;
 	if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
-		printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc);
+		v4l_err(i2c_client_s,"i2c i/o error VPS: rc == %d (should be 2)\n",rc);
 
 	bt832_hexdump(i2c_client_s,buf);
 
 
 	// Leave low power mode:
-	printk("Bt832: leave low power mode.\n");
+	v4l_err(i2c_client_s,"leave low power mode.\n");
 	buf[0]=BT832_CAM_SETUP0; //0x39 57
 	buf[1]=0x08;
 	if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
-		printk("bt832: i2c i/o error LLPM: rc == %d (should be 2)\n",rc);
+		v4l_err(i2c_client_s,"i2c i/o error LLPM: rc == %d (should be 2)\n",rc);
 
 	bt832_hexdump(i2c_client_s,buf);
 
-	printk("Write 0 tp VPSTATUS\n");
+	v4l_info(i2c_client_s,"Write 0 tp VPSTATUS\n");
 	buf[0]=BT832_VP_STATUS; // Reg.52
 	buf[1]= 0x00;
 	if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
-		printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc);
+		v4l_err(i2c_client_s,"i2c i/o error VPS: rc == %d (should be 2)\n",rc);
 
 	bt832_hexdump(i2c_client_s,buf);
 
 
 	// Enable Output
-	printk("Enable Output\n");
+	v4l_info(i2c_client_s,"Enable Output\n");
 	buf[0]=BT832_VP_CONTROL1; // Reg.40
 	buf[1]= 0x27 & (~0x01); // Default | !skip
 	if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
-		printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc);
+		v4l_err(i2c_client_s,"i2c i/o error EO: rc == %d (should be 2)\n",rc);
 
 	bt832_hexdump(i2c_client_s,buf);
 
 
 	// for testing (even works when no camera attached)
-	printk("bt832: *** Generate NTSC M Bars *****\n");
+	v4l_info(i2c_client_s,"*** Generate NTSC M Bars *****\n");
 	buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42
 	buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally
 	if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
-		printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc);
+		v4l_info(i2c_client_s,"i2c i/o error MBAR: rc == %d (should be 2)\n",rc);
 
-	printk("Bt832: Camera Present: %s\n",
+	v4l_info(i2c_client_s,"Camera Present: %s\n",
 		(buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no");
 
 	bt832_hexdump(i2c_client_s,buf);
@@ -159,13 +164,9 @@
 {
 	struct bt832 *t;
 
-	printk("bt832_attach\n");
-
 	client_template.adapter = adap;
 	client_template.addr    = addr;
 
-	printk("bt832: chip found @ 0x%x\n", addr<<1);
-
 	if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
 		return -ENOMEM;
 	memset(t,0,sizeof(*t));
@@ -173,6 +174,9 @@
 	i2c_set_clientdata(&t->client, t);
 	i2c_attach_client(&t->client);
 
+	v4l_info(&t->client,"chip found @ 0x%x\n", addr<<1);
+
+
 	if(! bt832_init(&t->client)) {
 		bt832_detach(&t->client);
 		return -1;
@@ -183,13 +187,8 @@
 
 static int bt832_probe(struct i2c_adapter *adap)
 {
-#ifdef I2C_CLASS_TV_ANALOG
 	if (adap->class & I2C_CLASS_TV_ANALOG)
 		return i2c_probe(adap, &addr_data, bt832_attach);
-#else
-	if (adap->id == I2C_HW_B_BT848)
-		return i2c_probe(adap, &addr_data, bt832_attach);
-#endif
 	return 0;
 }
 
@@ -197,7 +196,7 @@
 {
 	struct bt832 *t = i2c_get_clientdata(client);
 
-	printk("bt832: detach.\n");
+	v4l_info(&t->client,"dettach\n");
 	i2c_detach_client(client);
 	kfree(t);
 	return 0;
@@ -208,7 +207,8 @@
 {
 	struct bt832 *t = i2c_get_clientdata(client);
 
-	printk("bt832: command %x\n",cmd);
+	if (debug>1)
+		v4l_i2c_print_ioctl(&t->client,cmd);
 
 	switch (cmd) {
 		case BT832_HEXDUMP: {
@@ -219,7 +219,7 @@
 		}
 		break;
 		case BT832_REATTACH:
-			printk("bt832: re-attach\n");
+			v4l_info(&t->client,"re-attach\n");
 			i2c_del_driver(&driver);
 			i2c_add_driver(&driver);
 		break;
@@ -231,9 +231,9 @@
 
 static struct i2c_driver driver = {
 	.driver = {
-		.name   = "i2c bt832 driver",
+		.name   = "bt832",
 	},
-	.id             = -1, /* FIXME */
+	.id             = 0, /* FIXME */
 	.attach_adapter = bt832_probe,
 	.detach_client  = bt832_detach,
 	.command        = bt832_command,
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index 012be63..1621ab1 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -38,6 +38,7 @@
 #include <asm/io.h>
 
 #include "bttvp.h"
+#include <media/v4l2-common.h>
 
 /* fwd decl */
 static void boot_msp34xx(struct bttv *btv, int pin);
@@ -292,6 +293,9 @@
 	/* likely broken, vendor id doesn't match the other magic views ...
 	 * { 0xa0fca04f, BTTV_BOARD_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */
 
+	/* Duplicate PCI ID, reconfigure for this board during the eeprom read.
+	* { 0x13eb0070, BTTV_BOARD_HAUPPAUGE_IMPACTVCB,  "Hauppauge ImpactVCB" }, */
+
 	/* DVB cards (using pci function .1 for mpeg data xfer) */
 	{ 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
 	{ 0x07611461, BTTV_BOARD_AVDVBT_761,    "AverMedia AverTV DVB-T 761" },
@@ -2136,7 +2140,6 @@
 		.has_remote	= 1,
 		.gpiomask	= 0x1b,
 		.no_gpioirq     = 1,
-		.any_irq		= 1,
 	},
 	[BTTV_BOARD_PV143] = {
 		/* Jorge Boncompte - DTI2 <jorge@dti2.net> */
@@ -2817,6 +2820,22 @@
 		.tuner_addr	= ADDR_UNSET,
 		.has_radio      = 1,
 	},
+	/* ---- card 0x8f ---------------------------------- */
+	[BTTV_BOARD_HAUPPAUGE_IMPACTVCB] = {
+		.name		= "Hauppauge ImpactVCB (bt878)",
+		.video_inputs	= 4,
+		.audio_inputs	= 0,
+		.tuner		= -1,
+		.svhs		= -1,
+		.gpiomask	= 0x0f, /* old: 7 */
+		.muxsel		= { 0, 1, 3, 2}, /* Composite 0-3 */
+		.no_msp34xx	= 1,
+		.no_tda9875     = 1,
+		.no_tda7432     = 1,
+		.tuner_type	= -1,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+	},
 };
 
 static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@@ -3037,26 +3056,33 @@
 		switch (id) {
 		case 1:
 			info = "PAL / mono";
+			btv->tda9887_conf = TDA9887_INTERCARRIER;
 			break;
 		case 2:
 			info = "PAL+SECAM / stereo";
 			btv->has_radio = 1;
+			btv->tda9887_conf = TDA9887_QSS;
 			break;
 		case 3:
 			info = "NTSC / stereo";
 			btv->has_radio = 1;
+			btv->tda9887_conf = TDA9887_QSS;
 			break;
 		case 4:
 			info = "PAL+SECAM / mono";
+			btv->tda9887_conf = TDA9887_QSS;
 			break;
 		case 5:
 			info = "NTSC / mono";
+			btv->tda9887_conf = TDA9887_INTERCARRIER;
 			break;
 		case 6:
 			info = "NTSC / stereo";
+			btv->tda9887_conf = TDA9887_INTERCARRIER;
 			break;
 		case 7:
 			info = "PAL / stereo";
+			btv->tda9887_conf = TDA9887_INTERCARRIER;
 			break;
 		default:
 			info = "oops: unknown card";
@@ -3067,8 +3093,7 @@
 		printk(KERN_INFO
 		       "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n",
 		       btv->c.nr, id, info, btv->has_radio ? "yes" : "no");
-		btv->tuner_type  = 33;
-		btv->pinnacle_id = id;
+		btv->tuner_type = TUNER_MT2032;
 	}
 }
 
@@ -3370,9 +3395,9 @@
 		bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
 	}
 
-	if (btv->pinnacle_id != UNSET) {
-		bttv_call_i2c_clients(btv, AUDC_CONFIG_PINNACLE,
-							&btv->pinnacle_id);
+	if (btv->tda9887_conf) {
+		bttv_call_i2c_clients(btv, TDA9887_SET_CONFIG,
+							&btv->tda9887_conf);
 	}
 
 	btv->svhs = bttv_tvcards[btv->c.type].svhs;
@@ -3387,8 +3412,6 @@
 		btv->has_remote=1;
 	if (!bttv_tvcards[btv->c.type].no_gpioirq)
 		btv->gpioirq=1;
-	if (bttv_tvcards[btv->c.type].any_irq)
-		btv->any_irq = 1;
 	if (bttv_tvcards[btv->c.type].audio_hook)
 		btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook;
 
@@ -3424,7 +3447,7 @@
 
 	/* tuner modules */
 	tda9887 = 0;
-	if (btv->pinnacle_id != UNSET)
+	if (btv->tda9887_conf)
 		tda9887 = 1;
 	if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb &&
 	    bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0)
@@ -3471,6 +3494,21 @@
 	tveeprom_hauppauge_analog(&btv->i2c_client, &tv, eeprom_data);
 	btv->tuner_type = tv.tuner_type;
 	btv->has_radio  = tv.has_radio;
+
+	printk("bttv%d: Hauppauge eeprom indicates model#%d\n",
+		btv->c.nr, tv.model);
+
+	/*
+	 * Some of the 878 boards have duplicate PCI IDs. Switch the board
+	 * type based on model #.
+	 */
+	if(tv.model == 64900) {
+		printk("bttv%d: Switching board type from %s to %s\n",
+			btv->c.nr,
+			bttv_tvcards[btv->c.type].name,
+			bttv_tvcards[BTTV_BOARD_HAUPPAUGE_IMPACTVCB].name);
+		btv->c.type = BTTV_BOARD_HAUPPAUGE_IMPACTVCB;
+	}
 }
 
 static int terratec_active_radio_upgrade(struct bttv *btv)
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index 00bd8ea..0e69703 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -34,13 +34,14 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/kdev_t.h>
+#include "bttvp.h"
+#include <media/v4l2-common.h>
+
 #include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/byteorder.h>
 
-#include "bttvp.h"
-
 #include "rds.h"
 
 
@@ -210,6 +211,9 @@
 		.vdelay         = 0x20,
 		.vbipack        = 255,
 		.sram           = 0,
+		/* ITU-R frame line number of the first VBI line
+		   we can capture, of the first and second field. */
+		.vbistart	= { 7,320 },
 	},{
 		.v4l2_id        = V4L2_STD_NTSC_M,
 		.name           = "NTSC",
@@ -226,6 +230,7 @@
 		.vdelay         = 0x1a,
 		.vbipack        = 144,
 		.sram           = 1,
+		.vbistart	= { 10, 273 },
 	},{
 		.v4l2_id        = V4L2_STD_SECAM,
 		.name           = "SECAM",
@@ -242,6 +247,7 @@
 		.vdelay         = 0x20,
 		.vbipack        = 255,
 		.sram           = 0, /* like PAL, correct? */
+		.vbistart	= { 7, 320 },
 	},{
 		.v4l2_id        = V4L2_STD_PAL_Nc,
 		.name           = "PAL-Nc",
@@ -258,6 +264,7 @@
 		.vdelay         = 0x1a,
 		.vbipack        = 144,
 		.sram           = -1,
+		.vbistart	= { 7, 320 },
 	},{
 		.v4l2_id        = V4L2_STD_PAL_M,
 		.name           = "PAL-M",
@@ -274,6 +281,7 @@
 		.vdelay         = 0x1a,
 		.vbipack        = 144,
 		.sram           = -1,
+		.vbistart	= { 10, 273 },
 	},{
 		.v4l2_id        = V4L2_STD_PAL_N,
 		.name           = "PAL-N",
@@ -290,6 +298,7 @@
 		.vdelay         = 0x20,
 		.vbipack        = 144,
 		.sram           = -1,
+		.vbistart	= { 7, 320},
 	},{
 		.v4l2_id        = V4L2_STD_NTSC_M_JP,
 		.name           = "NTSC-JP",
@@ -306,6 +315,7 @@
 		.vdelay         = 0x16,
 		.vbipack        = 144,
 		.sram           = -1,
+		.vbistart	= {10, 273},
 	},{
 		/* that one hopefully works with the strange timing
 		 * which video recorders produce when playing a NTSC
@@ -326,6 +336,7 @@
 		.vbipack        = 255,
 		.vtotal         = 524,
 		.sram           = -1,
+		.vbistart	= { 10, 273 },
 	}
 };
 static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms);
@@ -1510,14 +1521,6 @@
 	.buf_release  = buffer_release,
 };
 
-static const char *v4l1_ioctls[] = {
-	"?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
-	"CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
-	"SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
-	"GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
-	"SMICROCODE", "GVBIFMT", "SVBIFMT" };
-#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
-
 static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
 {
 	switch (cmd) {
@@ -2206,22 +2209,9 @@
 	unsigned long flags;
 	int retval = 0;
 
-	if (bttv_debug > 1) {
-		switch (_IOC_TYPE(cmd)) {
-		case 'v':
-			printk("bttv%d: ioctl 0x%x (v4l1, VIDIOC%s)\n",
-			       btv->c.nr, cmd, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
-			       v4l1_ioctls[_IOC_NR(cmd)] : "???");
-			break;
-		case 'V':
-			printk("bttv%d: ioctl 0x%x (v4l2, %s)\n",
-			       btv->c.nr, cmd,  v4l2_ioctl_names[_IOC_NR(cmd)]);
-			break;
-		default:
-			printk("bttv%d: ioctl 0x%x (???)\n",
-			       btv->c.nr, cmd);
-		}
-	}
+	if (bttv_debug > 1)
+		v4l_print_ioctl(btv->c.name, cmd);
+
 	if (btv->errors)
 		bttv_reinit_bt848(btv);
 
@@ -2570,10 +2560,10 @@
 		fmt->count[0]         = fmt2.fmt.vbi.count[0];
 		fmt->start[1]         = fmt2.fmt.vbi.start[1];
 		fmt->count[1]         = fmt2.fmt.vbi.count[1];
-		if (fmt2.fmt.vbi.flags & VBI_UNSYNC)
-			fmt->flags   |= V4L2_VBI_UNSYNC;
-		if (fmt2.fmt.vbi.flags & VBI_INTERLACED)
-			fmt->flags   |= V4L2_VBI_INTERLACED;
+		if (fmt2.fmt.vbi.flags & V4L2_VBI_UNSYNC)
+			fmt->flags   |= VBI_UNSYNC;
+		if (fmt2.fmt.vbi.flags & V4L2_VBI_INTERLACED)
+			fmt->flags   |= VBI_INTERLACED;
 		return 0;
 	}
 	case VIDIOCSVBIFMT:
@@ -3120,6 +3110,7 @@
 	.open	  = bttv_open,
 	.release  = bttv_release,
 	.ioctl	  = bttv_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek	  = no_llseek,
 	.read	  = bttv_read,
 	.mmap	  = bttv_mmap,
@@ -3229,6 +3220,7 @@
 	case VIDIOCSFREQ:
 	case VIDIOCGAUDIO:
 	case VIDIOCSAUDIO:
+	case VIDIOC_LOG_STATUS:
 		return bttv_common_ioctls(btv,cmd,arg);
 
 	default:
@@ -3701,8 +3693,8 @@
 
 	btv=(struct bttv *)dev_id;
 
-	if (btv->any_irq)
-		handled = bttv_any_irq(&btv->c);
+	if (btv->custom_irq)
+		handled = btv->custom_irq(btv);
 
 	count=0;
 	while (1) {
@@ -3738,9 +3730,9 @@
 		if (astat&BT848_INT_VSYNC)
 			btv->field_count++;
 
-		if (astat & BT848_INT_GPINT) {
+		if ((astat & BT848_INT_GPINT) && btv->remote) {
 			wake_up(&btv->gpioq);
-			bttv_gpio_irq(&btv->c);
+			bttv_input_irq(btv);
 		}
 
 		if (astat & BT848_INT_I2CDONE) {
@@ -3946,7 +3938,6 @@
 
 	btv->i2c_rc = -1;
 	btv->tuner_type  = UNSET;
-	btv->pinnacle_id = UNSET;
 	btv->new_input   = UNSET;
 	btv->has_radio=radio[btv->c.nr];
 
@@ -4065,11 +4056,11 @@
 	}
 
 	/* add subdevices */
-	if (btv->has_remote)
-		bttv_sub_add_device(&btv->c, "remote");
 	if (bttv_tvcards[btv->c.type].has_dvb)
 		bttv_sub_add_device(&btv->c, "dvb");
 
+	bttv_input_init(btv);
+
 	/* everything is fine */
 	bttv_num++;
 	return 0;
@@ -4104,6 +4095,7 @@
 	/* tell gpio modules we are leaving ... */
 	btv->shutdown=1;
 	wake_up(&btv->gpioq);
+	bttv_input_fini(btv);
 	bttv_sub_del_devices(&btv->c);
 
 	/* unregister i2c_bus + input */
diff --git a/drivers/media/video/bttv-gpio.c b/drivers/media/video/bttv-gpio.c
index 616a5b7..575ce8b 100644
--- a/drivers/media/video/bttv-gpio.c
+++ b/drivers/media/video/bttv-gpio.c
@@ -113,24 +113,6 @@
 	}
 }
 
-int bttv_any_irq(struct bttv_core *core)
-{
-	struct bttv_sub_driver *drv;
-	struct bttv_sub_device *dev;
-	struct list_head *item;
-	int handled = 0;
-
-	list_for_each(item,&core->subs) {
-		dev = list_entry(item,struct bttv_sub_device,list);
-		drv = to_bttv_sub_drv(dev->dev.driver);
-		if (drv && drv->any_irq) {
-			if (drv->any_irq(dev))
-				handled = 1;
-		}
-	}
-	return handled;
-}
-
 /* ----------------------------------------------------------------------- */
 /* external: sub-driver register/unregister                                */
 
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c
index d6418c0..748d630 100644
--- a/drivers/media/video/bttv-i2c.c
+++ b/drivers/media/video/bttv-i2c.c
@@ -28,10 +28,11 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/jiffies.h>
-#include <asm/io.h>
 
 #include "bttvp.h"
+#include <media/v4l2-common.h>
+#include <linux/jiffies.h>
+#include <asm/io.h>
 
 static struct i2c_algo_bit_data bttv_i2c_algo_bit_template;
 static struct i2c_adapter bttv_i2c_adap_sw_template;
@@ -105,10 +106,8 @@
 
 static struct i2c_adapter bttv_i2c_adap_sw_template = {
 	.owner             = THIS_MODULE,
-#ifdef I2C_CLASS_TV_ANALOG
 	.class             = I2C_CLASS_TV_ANALOG,
-#endif
-	.name              = "bt848",
+	.name              = "bttv",
 	.id                = I2C_HW_B_BT848,
 	.client_register   = attach_inform,
 };
@@ -275,10 +274,8 @@
 };
 
 static struct i2c_adapter bttv_i2c_adap_hw_template = {
-	.owner         = THIS_MODULE,
-#ifdef I2C_CLASS_TV_ANALOG
+	.owner             = THIS_MODULE,
 	.class         = I2C_CLASS_TV_ANALOG,
-#endif
 	.name          = "bt878",
 	.id            = I2C_HW_B_BT848 /* FIXME */,
 	.algo          = &bttv_algo,
@@ -441,12 +438,10 @@
 	i2c_set_adapdata(&btv->c.i2c_adap, btv);
 	btv->i2c_client.adapter = &btv->c.i2c_adap;
 
-#ifdef I2C_CLASS_TV_ANALOG
 	if (bttv_tvcards[btv->c.type].no_video)
 		btv->c.i2c_adap.class &= ~I2C_CLASS_TV_ANALOG;
 	if (bttv_tvcards[btv->c.type].has_dvb)
 		btv->c.i2c_adap.class |= I2C_CLASS_TV_DIGITAL;
-#endif
 
 	if (btv->use_i2c_hw) {
 		btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap);
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/bttv-input.c
similarity index 73%
rename from drivers/media/video/ir-kbd-gpio.c
rename to drivers/media/video/bttv-input.c
index de1385e..12197f1 100644
--- a/drivers/media/video/ir-kbd-gpio.c
+++ b/drivers/media/video/bttv-input.c
@@ -24,11 +24,9 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
-#include <linux/pci.h>
-
-#include <media/ir-common.h>
 
 #include "bttv.h"
+#include "bttvp.h"
 
 /* ---------------------------------------------------------------------- */
 
@@ -156,9 +154,6 @@
 
 /* ---------------------------------------------------------------------- */
 
-/* Ricardo Cerqueira <v4l@cerqueira.org> */
-/* Weird matching, since the remote has "uncommon" keys */
-
 static IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE] = {
 
 	[ 30 ] = KEY_POWER,       // power
@@ -279,34 +274,6 @@
 	[0x36] = KEY_PC
 };
 
-struct IR {
-	struct bttv_sub_device  *sub;
-	struct input_dev        *input;
-	struct ir_input_state   ir;
-	char                    name[32];
-	char                    phys[32];
-
-	/* Usual gpio signalling */
-
-	u32                     mask_keycode;
-	u32                     mask_keydown;
-	u32                     mask_keyup;
-	u32                     polling;
-	u32                     last_gpio;
-	struct work_struct      work;
-	struct timer_list       timer;
-
-	/* RC5 gpio */
-	u32 rc5_gpio;
-	struct timer_list timer_end;	/* timer_end for code completion */
-	struct timer_list timer_keyup;	/* timer_end for key release */
-	u32 last_rc5;			/* last good rc5 code */
-	u32 last_bit;			/* last raw bit seen */
-	u32 code;			/* raw code under construction */
-	struct timeval base_time;	/* time of last seen code */
-	int active;			/* building raw code */
-};
-
 static int debug;
 module_param(debug, int, 0644);    /* debug level (0,1,2) */
 static int repeat_delay = 500;
@@ -314,31 +281,17 @@
 static int repeat_period = 33;
 module_param(repeat_period, int, 0644);
 
-#define DEVNAME "ir-kbd-gpio"
-#define dprintk(fmt, arg...)	if (debug) \
-	printk(KERN_DEBUG DEVNAME ": " fmt , ## arg)
-
-static void ir_irq(struct bttv_sub_device *sub);
-static int ir_probe(struct device *dev);
-static int ir_remove(struct device *dev);
-
-static struct bttv_sub_driver driver = {
-	.drv = {
-		.name	= DEVNAME,
-		.probe	= ir_probe,
-		.remove	= ir_remove,
-	},
-	.gpio_irq 	= ir_irq,
-};
+#define DEVNAME "bttv-input"
 
 /* ---------------------------------------------------------------------- */
 
-static void ir_handle_key(struct IR *ir)
+static void ir_handle_key(struct bttv *btv)
 {
+	struct bttv_ir *ir = btv->remote;
 	u32 gpio,data;
 
 	/* read gpio value */
-	gpio = bttv_gpio_read(ir->sub->core);
+	gpio = bttv_gpio_read(&btv->c);
 	if (ir->polling) {
 		if (ir->last_gpio == gpio)
 			return;
@@ -347,56 +300,36 @@
 
 	/* extract data */
 	data = ir_extract_bits(gpio, ir->mask_keycode);
-	dprintk(DEVNAME ": irq gpio=0x%x code=%d | %s%s%s\n",
+	dprintk(KERN_INFO DEVNAME ": irq gpio=0x%x code=%d | %s%s%s\n",
 		gpio, data,
 		ir->polling               ? "poll"  : "irq",
 		(gpio & ir->mask_keydown) ? " down" : "",
 		(gpio & ir->mask_keyup)   ? " up"   : "");
 
-	if (ir->mask_keydown) {
-		/* bit set on keydown */
-		if (gpio & ir->mask_keydown) {
-			ir_input_keydown(ir->input, &ir->ir, data, data);
-		} else {
-			ir_input_nokey(ir->input, &ir->ir);
-		}
-
-	} else if (ir->mask_keyup) {
-		/* bit cleared on keydown */
-		if (0 == (gpio & ir->mask_keyup)) {
-			ir_input_keydown(ir->input, &ir->ir, data, data);
-		} else {
-			ir_input_nokey(ir->input, &ir->ir);
-		}
-
+	if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
+	    (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
+		ir_input_keydown(ir->dev,&ir->ir,data,data);
 	} else {
-		/* can't disturgissh keydown/up :-/ */
-		ir_input_keydown(ir->input, &ir->ir, data, data);
-		ir_input_nokey(ir->input, &ir->ir);
+		ir_input_nokey(ir->dev,&ir->ir);
 	}
+
 }
 
-static void ir_irq(struct bttv_sub_device *sub)
+void bttv_input_irq(struct bttv *btv)
 {
-	struct IR *ir = dev_get_drvdata(&sub->dev);
+	struct bttv_ir *ir = btv->remote;
 
 	if (!ir->polling)
-		ir_handle_key(ir);
+		ir_handle_key(btv);
 }
 
-static void ir_timer(unsigned long data)
+static void bttv_input_timer(unsigned long data)
 {
-	struct IR *ir = (struct IR*)data;
-
-	schedule_work(&ir->work);
-}
-
-static void ir_work(void *data)
-{
-	struct IR *ir = data;
+	struct bttv *btv = (struct bttv*)data;
+	struct bttv_ir *ir = btv->remote;
 	unsigned long timeout;
 
-	ir_handle_key(ir);
+	ir_handle_key(btv);
 	timeout = jiffies + (ir->polling * HZ / 1000);
 	mod_timer(&ir->timer, timeout);
 }
@@ -435,26 +368,26 @@
 			rc5 |= 1;
 			break;
 		case 3:
-			dprintk("bad code: %x\n", org_code);
+			dprintk(KERN_WARNING "bad code: %x\n", org_code);
 			return 0;
 		}
 	}
-	dprintk("code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
+	dprintk(KERN_WARNING "code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
 		"instr=%x\n", rc5, org_code, RC5_START(rc5),
 		RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
 	return rc5;
 }
 
-static int ir_rc5_irq(struct bttv_sub_device *sub)
+static int bttv_rc5_irq(struct bttv *btv)
 {
-	struct IR *ir = dev_get_drvdata(&sub->dev);
+	struct bttv_ir *ir = btv->remote;
 	struct timeval tv;
 	u32 gpio;
 	u32 gap;
 	unsigned long current_jiffies, timeout;
 
 	/* read gpio port */
-	gpio = bttv_gpio_read(ir->sub->core);
+	gpio = bttv_gpio_read(&btv->c);
 
 	/* remote IRQ? */
 	if (!(gpio & 0x20))
@@ -493,14 +426,15 @@
 	}
 
 	/* toggle GPIO pin 4 to reset the irq */
-	bttv_gpio_write(ir->sub->core, gpio & ~(1 << 4));
-	bttv_gpio_write(ir->sub->core, gpio | (1 << 4));
+	bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
+	bttv_gpio_write(&btv->c, gpio | (1 << 4));
 	return 1;
 }
 
-static void ir_rc5_timer_end(unsigned long data)
+
+static void bttv_rc5_timer_end(unsigned long data)
 {
-	struct IR *ir = (struct IR *)data;
+	struct bttv_ir *ir = (struct bttv_ir *)data;
 	struct timeval tv;
 	unsigned long current_jiffies, timeout;
 	u32 gap;
@@ -519,20 +453,20 @@
 
 	/* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */
 	if (gap < 28000) {
-		dprintk("spurious timer_end\n");
+		dprintk(KERN_WARNING "spurious timer_end\n");
 		return;
 	}
 
 	ir->active = 0;
 	if (ir->last_bit < 20) {
 		/* ignore spurious codes (caused by light/other remotes) */
-		dprintk("short code: %x\n", ir->code);
+		dprintk(KERN_WARNING "short code: %x\n", ir->code);
 	} else {
 		u32 rc5 = rc5_decode(ir->code);
 
 		/* two start bits? */
 		if (RC5_START(rc5) != 3) {
-			dprintk("rc5 start bits invalid: %u\n", RC5_START(rc5));
+			dprintk(KERN_WARNING "rc5 start bits invalid: %u\n", RC5_START(rc5));
 
 			/* right address? */
 		} else if (RC5_ADDR(rc5) == 0x0) {
@@ -542,10 +476,10 @@
 			/* Good code, decide if repeat/repress */
 			if (toggle != RC5_TOGGLE(ir->last_rc5) ||
 			    instr != RC5_INSTR(ir->last_rc5)) {
-				dprintk("instruction %x, toggle %x\n", instr,
+				dprintk(KERN_WARNING "instruction %x, toggle %x\n", instr,
 					toggle);
-				ir_input_nokey(ir->input, &ir->ir);
-				ir_input_keydown(ir->input, &ir->ir, instr,
+				ir_input_nokey(ir->dev, &ir->ir);
+				ir_input_keydown(ir->dev, &ir->ir, instr,
 						 instr);
 			}
 
@@ -560,34 +494,37 @@
 	}
 }
 
-static void ir_rc5_timer_keyup(unsigned long data)
+static void bttv_rc5_timer_keyup(unsigned long data)
 {
-	struct IR *ir = (struct IR *)data;
+	struct bttv_ir *ir = (struct bttv_ir *)data;
 
-	dprintk("key released\n");
-	ir_input_nokey(ir->input, &ir->ir);
+	dprintk(KERN_DEBUG "key released\n");
+	ir_input_nokey(ir->dev, &ir->ir);
 }
 
 /* ---------------------------------------------------------------------- */
 
-static int ir_probe(struct device *dev)
+int bttv_input_init(struct bttv *btv)
 {
-	struct bttv_sub_device *sub = to_bttv_sub_dev(dev);
-	struct IR *ir;
-	struct input_dev *input_dev;
+	struct bttv_ir *ir;
 	IR_KEYTAB_TYPE *ir_codes = NULL;
+	struct input_dev *input_dev;
 	int ir_type = IR_TYPE_OTHER;
 
-	ir = kzalloc(sizeof(*ir), GFP_KERNEL);
+	if (!btv->has_remote)
+		return -ENODEV;
+
+	ir = kzalloc(sizeof(*ir),GFP_KERNEL);
 	input_dev = input_allocate_device();
 	if (!ir || !input_dev) {
 		kfree(ir);
 		input_free_device(input_dev);
 		return -ENOMEM;
 	}
+	memset(ir,0,sizeof(*ir));
 
 	/* detect & configure */
-	switch (sub->core->type) {
+	switch (btv->c.type) {
 	case BTTV_BOARD_AVERMEDIA:
 	case BTTV_BOARD_AVPHONE98:
 	case BTTV_BOARD_AVERMEDIA98:
@@ -643,12 +580,12 @@
 		break;
 	case BTTV_BOARD_NEBULA_DIGITV:
 		ir_codes = ir_codes_nebula;
-		driver.any_irq = ir_rc5_irq;
-		driver.gpio_irq = NULL;
+		btv->custom_irq = bttv_rc5_irq;
 		ir->rc5_gpio = 1;
 		break;
 	}
 	if (NULL == ir_codes) {
+		dprintk(KERN_INFO "Ooops: IR config error [card=%d]\n",btv->c.type);
 		kfree(ir);
 		input_free_device(input_dev);
 		return -ENODEV;
@@ -657,109 +594,92 @@
 	if (ir->rc5_gpio) {
 		u32 gpio;
 	    	/* enable remote irq */
-		bttv_gpio_inout(sub->core, (1 << 4), 1 << 4);
-		gpio = bttv_gpio_read(sub->core);
-		bttv_gpio_write(sub->core, gpio & ~(1 << 4));
-		bttv_gpio_write(sub->core, gpio | (1 << 4));
+		bttv_gpio_inout(&btv->c, (1 << 4), 1 << 4);
+		gpio = bttv_gpio_read(&btv->c);
+		bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
+		bttv_gpio_write(&btv->c, gpio | (1 << 4));
 	} else {
 		/* init hardware-specific stuff */
-		bttv_gpio_inout(sub->core, ir->mask_keycode | ir->mask_keydown, 0);
+		bttv_gpio_inout(&btv->c, ir->mask_keycode | ir->mask_keydown, 0);
 	}
 
 	/* init input device */
+	ir->dev = input_dev;
+
 	snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)",
-		 sub->core->type);
+		 btv->c.type);
 	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
-		 pci_name(sub->core->pci));
+		 pci_name(btv->c.pci));
 
 	ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
 	input_dev->name = ir->name;
 	input_dev->phys = ir->phys;
 	input_dev->id.bustype = BUS_PCI;
 	input_dev->id.version = 1;
-	if (sub->core->pci->subsystem_vendor) {
-		input_dev->id.vendor  = sub->core->pci->subsystem_vendor;
-		input_dev->id.product = sub->core->pci->subsystem_device;
+	if (btv->c.pci->subsystem_vendor) {
+		input_dev->id.vendor  = btv->c.pci->subsystem_vendor;
+		input_dev->id.product = btv->c.pci->subsystem_device;
 	} else {
-		input_dev->id.vendor  = sub->core->pci->vendor;
-		input_dev->id.product = sub->core->pci->device;
+		input_dev->id.vendor  = btv->c.pci->vendor;
+		input_dev->id.product = btv->c.pci->device;
 	}
-	input_dev->cdev.dev = &sub->core->pci->dev;
+	input_dev->cdev.dev = &btv->c.pci->dev;
 
-	ir->input = input_dev;
-	ir->sub = sub;
-
+	btv->remote = ir;
 	if (ir->polling) {
-		INIT_WORK(&ir->work, ir_work, ir);
 		init_timer(&ir->timer);
-		ir->timer.function = ir_timer;
-		ir->timer.data     = (unsigned long)ir;
-		schedule_work(&ir->work);
+		ir->timer.function = bttv_input_timer;
+		ir->timer.data     = (unsigned long)btv;
+		ir->timer.expires  = jiffies + HZ;
+		add_timer(&ir->timer);
 	} else if (ir->rc5_gpio) {
 		/* set timer_end for code completion */
 		init_timer(&ir->timer_end);
-		ir->timer_end.function = ir_rc5_timer_end;
+		ir->timer_end.function = bttv_rc5_timer_end;
 		ir->timer_end.data = (unsigned long)ir;
 
 		init_timer(&ir->timer_keyup);
-		ir->timer_keyup.function = ir_rc5_timer_keyup;
+		ir->timer_keyup.function = bttv_rc5_timer_keyup;
 		ir->timer_keyup.data = (unsigned long)ir;
 	}
 
 	/* all done */
-	dev_set_drvdata(dev, ir);
-	input_register_device(ir->input);
+	input_register_device(btv->remote->dev);
+	printk(DEVNAME ": %s detected at %s\n",ir->name,ir->phys);
 
 	/* the remote isn't as bouncy as a keyboard */
-	ir->input->rep[REP_DELAY] = repeat_delay;
-	ir->input->rep[REP_PERIOD] = repeat_period;
+	ir->dev->rep[REP_DELAY] = repeat_delay;
+	ir->dev->rep[REP_PERIOD] = repeat_period;
 
 	return 0;
 }
 
-static int ir_remove(struct device *dev)
+void bttv_input_fini(struct bttv *btv)
 {
-	struct IR *ir = dev_get_drvdata(dev);
+	if (btv->remote == NULL)
+		return;
 
-	if (ir->polling) {
-		del_timer(&ir->timer);
+	if (btv->remote->polling) {
+		del_timer_sync(&btv->remote->timer);
 		flush_scheduled_work();
 	}
 
-	if (ir->rc5_gpio) {
+
+	if (btv->remote->rc5_gpio) {
 		u32 gpio;
 
-		del_timer(&ir->timer_end);
+		del_timer_sync(&btv->remote->timer_end);
 		flush_scheduled_work();
 
-		gpio = bttv_gpio_read(ir->sub->core);
-		bttv_gpio_write(ir->sub->core, gpio & ~(1 << 4));
+		gpio = bttv_gpio_read(&btv->c);
+		bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
 	}
 
-	input_unregister_device(ir->input);
-	kfree(ir);
-	return 0;
+	input_unregister_device(btv->remote->dev);
+	kfree(btv->remote);
+	btv->remote = NULL;
 }
 
-/* ---------------------------------------------------------------------- */
-
-MODULE_AUTHOR("Gerd Knorr, Pavel Machek");
-MODULE_DESCRIPTION("input driver for bt8x8 gpio IR remote controls");
-MODULE_LICENSE("GPL");
-
-static int ir_init(void)
-{
-	return bttv_sub_register(&driver, "remote");
-}
-
-static void ir_fini(void)
-{
-	bttv_sub_unregister(&driver);
-}
-
-module_init(ir_init);
-module_exit(ir_fini);
-
 
 /*
  * Local variables:
diff --git a/drivers/media/video/bttv-vbi.c b/drivers/media/video/bttv-vbi.c
index f4f58c6..72afdd6 100644
--- a/drivers/media/video/bttv-vbi.c
+++ b/drivers/media/video/bttv-vbi.c
@@ -31,6 +31,12 @@
 #include <asm/io.h>
 #include "bttvp.h"
 
+/* Offset from line sync pulse leading edge (0H) in 1 / sampling_rate:
+   bt8x8 /HRESET pulse starts at 0H and has length 64 / fCLKx1 (E|O_VTC
+   HSFMT = 0). VBI_HDELAY (always 0) is an offset from the trailing edge
+   of /HRESET in 1 / fCLKx1, and the sampling_rate tvnorm->Fsc is fCLKx2. */
+#define VBI_OFFSET ((64 + 0) * 2)
+
 #define VBI_DEFLINES 16
 #define VBI_MAXLINES 32
 
@@ -163,40 +169,30 @@
 void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f)
 {
 	const struct bttv_tvnorm *tvnorm;
-	u32 start0,start1;
-	s32 count0,count1,count;
+	s64 count0,count1,count;
 
 	tvnorm = &bttv_tvnorms[fh->btv->tvnorm];
 	f->type = V4L2_BUF_TYPE_VBI_CAPTURE;
 	f->fmt.vbi.sampling_rate    = tvnorm->Fsc;
 	f->fmt.vbi.samples_per_line = 2048;
 	f->fmt.vbi.sample_format    = V4L2_PIX_FMT_GREY;
-	f->fmt.vbi.offset           = 244;
+	f->fmt.vbi.offset           = VBI_OFFSET;
 	f->fmt.vbi.flags            = 0;
-	switch (fh->btv->tvnorm) {
-	case 1: /* NTSC */
-		start0 = 10;
-		start1 = 273;
-		break;
-	case 0: /* PAL */
-	case 2: /* SECAM */
-	default:
-		start0 = 7;
-		start1 = 320;
-	}
 
-	count0 = (f->fmt.vbi.start[0] + f->fmt.vbi.count[0]) - start0;
-	count1 = (f->fmt.vbi.start[1] + f->fmt.vbi.count[1]) - start1;
-	count  = max(count0,count1);
-	if (count > VBI_MAXLINES)
-		count = VBI_MAXLINES;
-	if (count < 1)
-		count = 1;
+	/* s64 to prevent overflow. */
+	count0 = (s64) f->fmt.vbi.start[0] + f->fmt.vbi.count[0]
+		- tvnorm->vbistart[0];
+	count1 = (s64) f->fmt.vbi.start[1] + f->fmt.vbi.count[1]
+		- tvnorm->vbistart[1];
+	count  = clamp (max (count0, count1), 1LL, (s64) VBI_MAXLINES);
 
-	f->fmt.vbi.start[0] = start0;
-	f->fmt.vbi.start[1] = start1;
+	f->fmt.vbi.start[0] = tvnorm->vbistart[0];
+	f->fmt.vbi.start[1] = tvnorm->vbistart[1];
 	f->fmt.vbi.count[0] = count;
 	f->fmt.vbi.count[1] = count;
+
+	f->fmt.vbi.reserved[0] = 0;
+	f->fmt.vbi.reserved[1] = 0;
 }
 
 void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f)
@@ -209,21 +205,12 @@
 	f->fmt.vbi.sampling_rate    = tvnorm->Fsc;
 	f->fmt.vbi.samples_per_line = 2048;
 	f->fmt.vbi.sample_format    = V4L2_PIX_FMT_GREY;
-	f->fmt.vbi.offset           = 244;
+	f->fmt.vbi.offset           = VBI_OFFSET;
+	f->fmt.vbi.start[0]         = tvnorm->vbistart[0];
+	f->fmt.vbi.start[1]         = tvnorm->vbistart[1];
 	f->fmt.vbi.count[0]         = fh->lines;
 	f->fmt.vbi.count[1]         = fh->lines;
 	f->fmt.vbi.flags            = 0;
-	switch (fh->btv->tvnorm) {
-	case 1: /* NTSC */
-		f->fmt.vbi.start[0] = 10;
-		f->fmt.vbi.start[1] = 273;
-		break;
-	case 0: /* PAL */
-	case 2: /* SECAM */
-	default:
-		f->fmt.vbi.start[0] = 7;
-		f->fmt.vbi.start[1] = 319;
-	}
 }
 
 /* ----------------------------------------------------------------------- */
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h
index 93298f0..9feaa6b 100644
--- a/drivers/media/video/bttv.h
+++ b/drivers/media/video/bttv.h
@@ -16,6 +16,8 @@
 
 #include <linux/videodev.h>
 #include <linux/i2c.h>
+#include <media/ir-common.h>
+#include <media/ir-kbd-i2c.h>
 
 /* ---------------------------------------------------------- */
 /* exported by bttv-cards.c                                   */
@@ -163,6 +165,7 @@
 #define BTTV_BOARD_OSPREY440               0x8c
 #define BTTV_BOARD_ASOUND_SKYEYE	   0x8d
 #define BTTV_BOARD_SABRENT_TVFM   	   0x8e
+#define BTTV_BOARD_HAUPPAUGE_IMPACTVCB     0x8f
 
 /* i2c address list */
 #define I2C_TSA5522        0xc2
@@ -210,6 +213,34 @@
 
 struct bttv;
 
+
+struct bttv_ir {
+	struct input_dev        *dev;
+	struct ir_input_state   ir;
+	char                    name[32];
+	char                    phys[32];
+
+	/* Usual gpio signalling */
+
+	u32                     mask_keycode;
+	u32                     mask_keydown;
+	u32                     mask_keyup;
+	u32                     polling;
+	u32                     last_gpio;
+	struct work_struct      work;
+	struct timer_list       timer;
+
+	/* RC5 gpio */
+	u32 rc5_gpio;
+	struct timer_list timer_end;	/* timer_end for code completion */
+	struct timer_list timer_keyup;	/* timer_end for key release */
+	u32 last_rc5;			/* last good rc5 code */
+	u32 last_bit;			/* last raw bit seen */
+	u32 code;			/* raw code under construction */
+	struct timeval base_time;	/* time of last seen code */
+	int active;			/* building raw code */
+};
+
 struct tvcard
 {
 	char *name;
@@ -235,7 +266,6 @@
 	unsigned int has_dvb:1;
 	unsigned int has_remote:1;
 	unsigned int no_gpioirq:1;
-	unsigned int any_irq:1;
 
 	/* other settings */
 	unsigned int pll;
@@ -335,7 +365,6 @@
 	struct device_driver   drv;
 	char                   wanted[BUS_ID_SIZE];
 	void                   (*gpio_irq)(struct bttv_sub_device *sub);
-	int                    (*any_irq)(struct bttv_sub_device *sub);
 };
 #define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv)
 
@@ -363,6 +392,10 @@
 			 unsigned char b2, int both);
 extern void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr);
 
+extern int bttv_input_init(struct bttv *dev);
+extern void bttv_input_fini(struct bttv *dev);
+extern void bttv_input_irq(struct bttv *dev);
+
 #endif /* _BTTV_H_ */
 /*
  * Local variables:
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
index 1e6a563..dd00c20 100644
--- a/drivers/media/video/bttvp.h
+++ b/drivers/media/video/bttvp.h
@@ -73,6 +73,8 @@
 
 #define UNSET (-1U)
 
+#define clamp(x, low, high) min (max (low, x), high)
+
 /* ---------------------------------------------------------- */
 
 struct bttv_tvnorm {
@@ -88,6 +90,9 @@
 	u8    vbipack;
 	u16   vtotal;
 	int   sram;
+	/* ITU-R frame line number of the first VBI line we can
+	   capture, of the first and second field. */
+	u16   vbistart[2];
 };
 extern const struct bttv_tvnorm bttv_tvnorms[];
 
@@ -209,7 +214,6 @@
 int bttv_sub_add_device(struct bttv_core *core, char *name);
 int bttv_sub_del_devices(struct bttv_core *core);
 void bttv_gpio_irq(struct bttv_core *core);
-int bttv_any_irq(struct bttv_core *core);
 
 
 /* ---------------------------------------------------------- */
@@ -270,12 +274,13 @@
 	/* card configuration info */
 	unsigned int cardid;   /* pci subsystem id (bt878 based ones) */
 	unsigned int tuner_type;  /* tuner chip type */
-	unsigned int pinnacle_id;
+	unsigned int tda9887_conf;
 	unsigned int svhs;
 	struct bttv_pll_info pll;
 	int triton1;
 	int gpioirq;
-	int any_irq;
+	int (*custom_irq)(struct bttv *btv);
+
 	int use_i2c_hw;
 
 	/* old gpio interface */
@@ -300,7 +305,7 @@
 
 	/* infrared remote */
 	int has_remote;
-	struct bttv_input *remote;
+	struct bttv_ir *remote;
 
 	/* locking */
 	spinlock_t s_lock;
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
index 0065d0c..6bad93e 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/video/bw-qcam.c
@@ -875,6 +875,7 @@
 	.open           = video_exclusive_open,
 	.release        = video_exclusive_release,
 	.ioctl          = qcam_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.read		= qcam_read,
 	.llseek         = no_llseek,
 };
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
index 75442ec..9976db4 100644
--- a/drivers/media/video/c-qcam.c
+++ b/drivers/media/video/c-qcam.c
@@ -687,6 +687,7 @@
 	.open           = video_exclusive_open,
 	.release        = video_exclusive_release,
 	.ioctl          = qcam_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.read		= qcam_read,
 	.llseek         = no_llseek,
 };
diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c
new file mode 100644
index 0000000..6194b01
--- /dev/null
+++ b/drivers/media/video/compat_ioctl32.c
@@ -0,0 +1,732 @@
+/*
+ * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
+ *	Separated from fs stuff by Arnd Bergmann <arnd@arndb.de>
+ *
+ * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
+ * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
+ * Copyright (C) 2001,2002  Andi Kleen, SuSE Labs
+ * Copyright (C) 2003       Pavel Machek (pavel@suse.cz)
+ * Copyright (C) 2005       Philippe De Muyter (phdm@macqel.be)
+ *
+ * These routines maintain argument size conversion between 32bit and 64bit
+ * ioctls.
+ */
+
+#include <linux/config.h>
+#include <linux/compat.h>
+#include <linux/videodev.h>
+#include <linux/videodev2.h>
+#include <linux/module.h>
+#include <linux/smp_lock.h>
+
+#ifdef CONFIG_COMPAT
+struct video_tuner32 {
+	compat_int_t tuner;
+	char name[32];
+	compat_ulong_t rangelow, rangehigh;
+	u32 flags;	/* It is really u32 in videodev.h */
+	u16 mode, signal;
+};
+
+static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up)
+{
+	if(get_user(kp->tuner, &up->tuner))
+		return -EFAULT;
+	__copy_from_user(kp->name, up->name, 32);
+	__get_user(kp->rangelow, &up->rangelow);
+	__get_user(kp->rangehigh, &up->rangehigh);
+	__get_user(kp->flags, &up->flags);
+	__get_user(kp->mode, &up->mode);
+	__get_user(kp->signal, &up->signal);
+	return 0;
+}
+
+static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up)
+{
+	if(put_user(kp->tuner, &up->tuner))
+		return -EFAULT;
+	__copy_to_user(up->name, kp->name, 32);
+	__put_user(kp->rangelow, &up->rangelow);
+	__put_user(kp->rangehigh, &up->rangehigh);
+	__put_user(kp->flags, &up->flags);
+	__put_user(kp->mode, &up->mode);
+	__put_user(kp->signal, &up->signal);
+	return 0;
+}
+
+struct video_buffer32 {
+	compat_caddr_t base;
+	compat_int_t height, width, depth, bytesperline;
+};
+
+static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up)
+{
+	u32 tmp;
+
+	if (get_user(tmp, &up->base))
+		return -EFAULT;
+
+	/* This is actually a physical address stored
+	 * as a void pointer.
+	 */
+	kp->base = (void *)(unsigned long) tmp;
+
+	__get_user(kp->height, &up->height);
+	__get_user(kp->width, &up->width);
+	__get_user(kp->depth, &up->depth);
+	__get_user(kp->bytesperline, &up->bytesperline);
+	return 0;
+}
+
+static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up)
+{
+	u32 tmp = (u32)((unsigned long)kp->base);
+
+	if(put_user(tmp, &up->base))
+		return -EFAULT;
+	__put_user(kp->height, &up->height);
+	__put_user(kp->width, &up->width);
+	__put_user(kp->depth, &up->depth);
+	__put_user(kp->bytesperline, &up->bytesperline);
+	return 0;
+}
+
+struct video_clip32 {
+	s32 x, y, width, height;	/* Its really s32 in videodev.h */
+	compat_caddr_t next;
+};
+
+struct video_window32 {
+	u32 x, y, width, height, chromakey, flags;
+	compat_caddr_t clips;
+	compat_int_t clipcount;
+};
+
+static int native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int ret = -ENOIOCTLCMD;
+
+	if (file->f_op->unlocked_ioctl)
+		ret = file->f_op->unlocked_ioctl(file, cmd, arg);
+	else if (file->f_op->ioctl) {
+		lock_kernel();
+		ret = file->f_op->ioctl(file->f_dentry->d_inode, file, cmd, arg);
+		unlock_kernel();
+	}
+
+	return ret;
+}
+
+
+/* You get back everything except the clips... */
+static int put_video_window32(struct video_window *kp, struct video_window32 __user *up)
+{
+	if(put_user(kp->x, &up->x))
+		return -EFAULT;
+	__put_user(kp->y, &up->y);
+	__put_user(kp->width, &up->width);
+	__put_user(kp->height, &up->height);
+	__put_user(kp->chromakey, &up->chromakey);
+	__put_user(kp->flags, &up->flags);
+	__put_user(kp->clipcount, &up->clipcount);
+	return 0;
+}
+
+struct v4l2_clip32
+{
+	struct v4l2_rect        c;
+	compat_caddr_t 		next;
+};
+
+struct v4l2_window32
+{
+	struct v4l2_rect        w;
+	enum v4l2_field  	field;
+	__u32			chromakey;
+	compat_caddr_t		clips; /* actually struct v4l2_clip32 * */
+	__u32			clipcount;
+	compat_caddr_t		bitmap;
+};
+
+static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
+{
+	if (copy_from_user(&kp->w, &up->w, sizeof(up->w)))
+		return -EFAULT;
+	__get_user(kp->field, &up->field);
+	__get_user(kp->chromakey, &up->chromakey);
+	__get_user(kp->clipcount, &up->clipcount);
+	if (kp->clipcount > 2048)
+		return -EINVAL;
+	if (kp->clipcount) {
+		struct v4l2_clip32 *uclips = compat_ptr(up->clips);
+		struct v4l2_clip *kclips;
+		int n = kp->clipcount;
+
+		kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip));
+		kp->clips = kclips;
+		while (--n >= 0) {
+			copy_from_user(&kclips->c, &uclips->c, sizeof(uclips->c));
+			kclips->next = n ? kclips + 1 : 0;
+			uclips += 1;
+			kclips += 1;
+		}
+	} else
+		kp->clips = 0;
+	return 0;
+}
+
+static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
+{
+	if (copy_to_user(&up->w, &kp->w, sizeof(up->w)))
+		return -EFAULT;
+	__put_user(kp->field, &up->field);
+	__put_user(kp->chromakey, &up->chromakey);
+	__put_user(kp->clipcount, &up->clipcount);
+	return 0;
+}
+
+static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
+{
+	return copy_from_user(kp, up, sizeof(struct v4l2_pix_format));
+}
+
+static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
+{
+	return copy_to_user(up, kp, sizeof(struct v4l2_pix_format));
+}
+
+static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
+{
+	return copy_from_user(kp, up, sizeof(struct v4l2_vbi_format));
+}
+
+static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
+{
+	return copy_to_user(up, kp, sizeof(struct v4l2_vbi_format));
+}
+
+struct v4l2_format32
+{
+	enum v4l2_buf_type type;
+	union
+	{
+		struct v4l2_pix_format	pix;  // V4L2_BUF_TYPE_VIDEO_CAPTURE
+		struct v4l2_window32	win;  // V4L2_BUF_TYPE_VIDEO_OVERLAY
+		struct v4l2_vbi_format	vbi;  // V4L2_BUF_TYPE_VBI_CAPTURE
+		__u8	raw_data[200];        // user-defined
+	} fmt;
+};
+
+static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+{
+	if(get_user(kp->type, &up->type))
+		return -EFAULT;
+	switch (kp->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
+	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+		return get_v4l2_window32(&kp->fmt.win, &up->fmt.win);
+	case V4L2_BUF_TYPE_VBI_CAPTURE:
+		return get_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);
+	default:
+		printk("compat_ioctl : unexpected VIDIOC_FMT type %d\n",
+								kp->type);
+		return -ENXIO;
+	}
+}
+
+static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+{
+	if(put_user(kp->type, &up->type))
+		return -EFAULT;
+	switch (kp->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
+	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+		return put_v4l2_window32(&kp->fmt.win, &up->fmt.win);
+	case V4L2_BUF_TYPE_VBI_CAPTURE:
+		return put_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);
+	default:
+		return -ENXIO;
+	}
+}
+
+struct v4l2_standard32
+{
+	__u32		     index;
+	__u32		     id[2]; /* __u64 would get the alignment wrong */
+	__u8		     name[24];
+	struct v4l2_fract    frameperiod; /* Frames, not fields */
+	__u32		     framelines;
+	__u32		     reserved[4];
+};
+
+static int get_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
+{
+	/* other fields are not set by the user, nor used by the driver */
+	return get_user(kp->index, &up->index);
+}
+
+static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
+{
+	if(put_user(kp->index, &up->index))
+		return -EFAULT;
+	__copy_to_user(up->id, &kp->id, sizeof(__u64));
+	__copy_to_user(up->name, kp->name, 24);
+	__put_user(kp->frameperiod, &up->frameperiod);
+	__put_user(kp->framelines, &up->framelines);
+	__copy_to_user(up->reserved, kp->reserved, 4 * sizeof(__u32));
+	return 0;
+}
+
+struct v4l2_buffer32
+{
+	__u32			index;
+	enum v4l2_buf_type      type;
+	__u32			bytesused;
+	__u32			flags;
+	enum v4l2_field		field;
+	struct compat_timeval	timestamp;
+	struct v4l2_timecode	timecode;
+	__u32			sequence;
+
+	/* memory location */
+	enum v4l2_memory        memory;
+	union {
+		__u32           offset;
+		compat_long_t   userptr;
+	} m;
+	__u32			length;
+	__u32			input;
+	__u32			reserved;
+};
+
+static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
+{
+
+	if (get_user(kp->index, &up->index))
+		return -EFAULT;
+	__get_user(kp->type, &up->type);
+	__get_user(kp->flags, &up->flags);
+	__get_user(kp->memory, &up->memory);
+	__get_user(kp->input, &up->input);
+	switch(kp->memory) {
+	case V4L2_MEMORY_MMAP:
+		break;
+	case V4L2_MEMORY_USERPTR:
+		{
+		unsigned long tmp = (unsigned long)compat_ptr(up->m.userptr);
+
+		__get_user(kp->length, &up->length);
+		__get_user(kp->m.userptr, &tmp);
+		}
+		break;
+	case V4L2_MEMORY_OVERLAY:
+		__get_user(kp->m.offset, &up->m.offset);
+		break;
+	}
+	return 0;
+}
+
+static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
+{
+	if (put_user(kp->index, &up->index))
+		return -EFAULT;
+	__put_user(kp->type, &up->type);
+	__put_user(kp->flags, &up->flags);
+	__put_user(kp->memory, &up->memory);
+	__put_user(kp->input, &up->input);
+	switch(kp->memory) {
+	case V4L2_MEMORY_MMAP:
+		__put_user(kp->length, &up->length);
+		__put_user(kp->m.offset, &up->m.offset);
+		break;
+	case V4L2_MEMORY_USERPTR:
+		__put_user(kp->length, &up->length);
+		__put_user(kp->m.userptr, &up->m.userptr);
+		break;
+	case V4L2_MEMORY_OVERLAY:
+		__put_user(kp->m.offset, &up->m.offset);
+		break;
+	}
+	__put_user(kp->bytesused, &up->bytesused);
+	__put_user(kp->field, &up->field);
+	__put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec);
+	__put_user(kp->timestamp.tv_usec, &up->timestamp.tv_usec);
+	__copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode));
+	__put_user(kp->sequence, &up->sequence);
+	__put_user(kp->reserved, &up->reserved);
+	return 0;
+}
+
+struct v4l2_framebuffer32
+{
+	__u32			capability;
+	__u32			flags;
+	compat_caddr_t 		base;
+	struct v4l2_pix_format	fmt;
+};
+
+static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up)
+{
+	u32 tmp;
+
+	if (get_user(tmp, &up->base))
+		return -EFAULT;
+	kp->base = compat_ptr(tmp);
+	__get_user(kp->capability, &up->capability);
+	__get_user(kp->flags, &up->flags);
+	get_v4l2_pix_format(&kp->fmt, &up->fmt);
+	return 0;
+}
+
+static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up)
+{
+	u32 tmp = (u32)((unsigned long)kp->base);
+
+	if(put_user(tmp, &up->base))
+		return -EFAULT;
+	__put_user(kp->capability, &up->capability);
+	__put_user(kp->flags, &up->flags);
+	put_v4l2_pix_format(&kp->fmt, &up->fmt);
+	return 0;
+}
+
+struct v4l2_input32 	/* identical layout, but different size */
+{
+	__u32	     index;		/*  Which input */
+	__u8	     name[32];		/*  Label */
+	__u32	     type;		/*  Type of input */
+	__u32	     audioset;		/*  Associated audios (bitfield) */
+	__u32        tuner;             /*  Associated tuner */
+	__u32	     std[2];		/* __u64 would get the padding wrong */
+	__u32	     status;
+	__u32	     reserved[4];
+};
+
+#define VIDIOCGTUNER32		_IOWR('v',4, struct video_tuner32)
+#define VIDIOCSTUNER32		_IOW('v',5, struct video_tuner32)
+#define VIDIOCGWIN32		_IOR('v',9, struct video_window32)
+#define VIDIOCSWIN32		_IOW('v',10, struct video_window32)
+#define VIDIOCGFBUF32		_IOR('v',11, struct video_buffer32)
+#define VIDIOCSFBUF32		_IOW('v',12, struct video_buffer32)
+#define VIDIOCGFREQ32		_IOR('v',14, u32)
+#define VIDIOCSFREQ32		_IOW('v',15, u32)
+
+#define VIDIOC_G_FMT32		_IOWR ('V',  4, struct v4l2_format32)
+#define VIDIOC_S_FMT32		_IOWR ('V',  5, struct v4l2_format32)
+#define VIDIOC_QUERYBUF32	_IOWR ('V',  9, struct v4l2_buffer32)
+#define VIDIOC_G_FBUF32		_IOR  ('V', 10, struct v4l2_framebuffer32)
+#define VIDIOC_S_FBUF32		_IOW  ('V', 11, struct v4l2_framebuffer32)
+/* VIDIOC_OVERLAY is now _IOW, but was _IOWR */
+#define VIDIOC_OVERLAY32	_IOWR ('V', 14, compat_int_t)
+#define VIDIOC_QBUF32		_IOWR ('V', 15, struct v4l2_buffer32)
+#define VIDIOC_DQBUF32		_IOWR ('V', 17, struct v4l2_buffer32)
+#define VIDIOC_STREAMON32	_IOW  ('V', 18, compat_int_t)
+#define VIDIOC_STREAMOFF32	_IOW  ('V', 19, compat_int_t)
+#define VIDIOC_ENUMSTD32	_IOWR ('V', 25, struct v4l2_standard32)
+#define VIDIOC_ENUMINPUT32	_IOWR ('V', 26, struct v4l2_input32)
+/* VIDIOC_S_CTRL is now _IOWR, but was _IOW */
+#define VIDIOC_S_CTRL32		_IOW  ('V', 28, struct v4l2_control)
+#define VIDIOC_G_INPUT32	_IOR  ('V', 38, compat_int_t)
+#define VIDIOC_S_INPUT32	_IOWR ('V', 39, compat_int_t)
+#define VIDIOC_TRY_FMT32      	_IOWR ('V', 64, struct v4l2_format32)
+
+enum {
+	MaxClips = (~0U-sizeof(struct video_window))/sizeof(struct video_clip)
+};
+
+static int do_set_window(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct video_window32 __user *up = compat_ptr(arg);
+	struct video_window __user *vw;
+	struct video_clip __user *p;
+	int nclips;
+	u32 n;
+
+	if (get_user(nclips, &up->clipcount))
+		return -EFAULT;
+
+	/* Peculiar interface... */
+	if (nclips < 0)
+		nclips = VIDEO_CLIPMAP_SIZE;
+
+	if (nclips > MaxClips)
+		return -ENOMEM;
+
+	vw = compat_alloc_user_space(sizeof(struct video_window) +
+				    nclips * sizeof(struct video_clip));
+
+	p = nclips ? (struct video_clip __user *)(vw + 1) : NULL;
+
+	if (get_user(n, &up->x) || put_user(n, &vw->x) ||
+	    get_user(n, &up->y) || put_user(n, &vw->y) ||
+	    get_user(n, &up->width) || put_user(n, &vw->width) ||
+	    get_user(n, &up->height) || put_user(n, &vw->height) ||
+	    get_user(n, &up->chromakey) || put_user(n, &vw->chromakey) ||
+	    get_user(n, &up->flags) || put_user(n, &vw->flags) ||
+	    get_user(n, &up->clipcount) || put_user(n, &vw->clipcount) ||
+	    get_user(n, &up->clips) || put_user(p, &vw->clips))
+		return -EFAULT;
+
+	if (nclips) {
+		struct video_clip32 __user *u = compat_ptr(n);
+		int i;
+		if (!u)
+			return -EINVAL;
+		for (i = 0; i < nclips; i++, u++, p++) {
+			s32 v;
+			if (get_user(v, &u->x) ||
+			    put_user(v, &p->x) ||
+			    get_user(v, &u->y) ||
+			    put_user(v, &p->y) ||
+			    get_user(v, &u->width) ||
+			    put_user(v, &p->width) ||
+			    get_user(v, &u->height) ||
+			    put_user(v, &p->height) ||
+			    put_user(NULL, &p->next))
+				return -EFAULT;
+		}
+	}
+
+	return native_ioctl(file, VIDIOCSWIN, (unsigned long)vw);
+}
+
+static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	union {
+		struct video_tuner vt;
+		struct video_buffer vb;
+		struct video_window vw;
+		struct v4l2_format v2f;
+		struct v4l2_buffer v2b;
+		struct v4l2_framebuffer v2fb;
+		struct v4l2_standard v2s;
+		unsigned long vx;
+	} karg;
+	void __user *up = compat_ptr(arg);
+	int compatible_arg = 1;
+	int err = 0;
+
+	/* First, convert the command. */
+	switch(cmd) {
+	case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break;
+	case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break;
+	case VIDIOCGWIN32: cmd = VIDIOCGWIN; break;
+	case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break;
+	case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break;
+	case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break;
+	case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break;
+	case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break;
+	case VIDIOC_S_FMT32: cmd = VIDIOC_S_FMT; break;
+	case VIDIOC_QUERYBUF32: cmd = VIDIOC_QUERYBUF; break;
+	case VIDIOC_QBUF32: cmd = VIDIOC_QBUF; break;
+	case VIDIOC_DQBUF32: cmd = VIDIOC_DQBUF; break;
+	case VIDIOC_STREAMON32: cmd = VIDIOC_STREAMON; break;
+	case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break;
+	case VIDIOC_G_FBUF32: cmd = VIDIOC_G_FBUF; break;
+	case VIDIOC_S_FBUF32: cmd = VIDIOC_S_FBUF; break;
+	case VIDIOC_OVERLAY32: cmd = VIDIOC_OVERLAY; break;
+	case VIDIOC_ENUMSTD32: cmd = VIDIOC_ENUMSTD; break;
+	case VIDIOC_ENUMINPUT32: cmd = VIDIOC_ENUMINPUT; break;
+	case VIDIOC_S_CTRL32: cmd = VIDIOC_S_CTRL; break;
+	case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break;
+	case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
+	case VIDIOC_TRY_FMT32: cmd = VIDIOC_TRY_FMT; break;
+	};
+
+	switch(cmd) {
+	case VIDIOCSTUNER:
+	case VIDIOCGTUNER:
+		err = get_video_tuner32(&karg.vt, up);
+		compatible_arg = 0;
+
+		break;
+
+	case VIDIOCSFBUF:
+		err = get_video_buffer32(&karg.vb, up);
+		compatible_arg = 0;
+		break;
+
+	case VIDIOCSFREQ:
+	case VIDIOC_S_INPUT:
+	case VIDIOC_OVERLAY:
+	case VIDIOC_STREAMON:
+	case VIDIOC_STREAMOFF:
+		err = get_user(karg.vx, (u32 __user *)up);
+		compatible_arg = 0;
+		break;
+
+	case VIDIOC_S_FBUF:
+		err = get_v4l2_framebuffer32(&karg.v2fb, up);
+		compatible_arg = 0;
+		break;
+
+	case VIDIOC_G_FMT:
+	case VIDIOC_S_FMT:
+	case VIDIOC_TRY_FMT:
+		err = get_v4l2_format32(&karg.v2f, up);
+		compatible_arg = 0;
+		break;
+
+	case VIDIOC_QUERYBUF:
+	case VIDIOC_QBUF:
+	case VIDIOC_DQBUF:
+		err = get_v4l2_buffer32(&karg.v2b, up);
+		compatible_arg = 0;
+		break;
+
+	case VIDIOC_ENUMSTD:
+		err = get_v4l2_standard32(&karg.v2s, up);
+		compatible_arg = 0;
+		break;
+
+	case VIDIOCGWIN:
+	case VIDIOCGFBUF:
+	case VIDIOCGFREQ:
+	case VIDIOC_G_FBUF:
+	case VIDIOC_G_INPUT:
+		compatible_arg = 0;
+	};
+
+	if(err)
+		goto out;
+
+	if(compatible_arg)
+		err = native_ioctl(file, cmd, (unsigned long)up);
+	else {
+		mm_segment_t old_fs = get_fs();
+
+		set_fs(KERNEL_DS);
+		err = native_ioctl(file, cmd, (unsigned long)&karg);
+		set_fs(old_fs);
+	}
+	if(err == 0) {
+		switch(cmd) {
+		case VIDIOCGTUNER:
+			err = put_video_tuner32(&karg.vt, up);
+			break;
+
+		case VIDIOCGWIN:
+			err = put_video_window32(&karg.vw, up);
+			break;
+
+		case VIDIOCGFBUF:
+			err = put_video_buffer32(&karg.vb, up);
+			break;
+
+		case VIDIOC_G_FBUF:
+			err = put_v4l2_framebuffer32(&karg.v2fb, up);
+			break;
+
+		case VIDIOC_G_FMT:
+		case VIDIOC_S_FMT:
+		case VIDIOC_TRY_FMT:
+			err = put_v4l2_format32(&karg.v2f, up);
+			break;
+
+		case VIDIOC_QUERYBUF:
+		case VIDIOC_QBUF:
+		case VIDIOC_DQBUF:
+			err = put_v4l2_buffer32(&karg.v2b, up);
+			break;
+
+		case VIDIOC_ENUMSTD:
+			err = put_v4l2_standard32(&karg.v2s, up);
+			break;
+
+		case VIDIOCGFREQ:
+		case VIDIOC_G_INPUT:
+			err = put_user(((u32)karg.vx), (u32 __user *)up);
+			break;
+		};
+	}
+out:
+	return err;
+}
+
+long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int ret = -ENOIOCTLCMD;
+
+	if (!file->f_op->ioctl)
+		return ret;
+
+	switch (cmd) {
+	case VIDIOCSWIN32:
+		ret = do_set_window(file, cmd, arg);
+		break;
+	case VIDIOCGTUNER32:
+	case VIDIOCSTUNER32:
+	case VIDIOCGWIN32:
+	case VIDIOCGFBUF32:
+	case VIDIOCSFBUF32:
+	case VIDIOCGFREQ32:
+	case VIDIOCSFREQ32:
+	case VIDIOC_QUERYCAP:
+	case VIDIOC_ENUM_FMT:
+	case VIDIOC_G_FMT32:
+	case VIDIOC_S_FMT32:
+	case VIDIOC_REQBUFS:
+	case VIDIOC_QUERYBUF32:
+	case VIDIOC_G_FBUF32:
+	case VIDIOC_S_FBUF32:
+	case VIDIOC_OVERLAY32:
+	case VIDIOC_QBUF32:
+	case VIDIOC_DQBUF32:
+	case VIDIOC_STREAMON32:
+	case VIDIOC_STREAMOFF32:
+	case VIDIOC_G_PARM:
+	case VIDIOC_G_STD:
+	case VIDIOC_S_STD:
+	case VIDIOC_ENUMSTD32:
+	case VIDIOC_ENUMINPUT32:
+	case VIDIOC_G_CTRL:
+	case VIDIOC_S_CTRL32:
+	case VIDIOC_QUERYCTRL:
+	case VIDIOC_G_INPUT32:
+	case VIDIOC_S_INPUT32:
+	case VIDIOC_TRY_FMT32:
+		ret = do_video_ioctl(file, cmd, arg);
+		break;
+
+	/* Little v, the video4linux ioctls (conflict?) */
+	case VIDIOCGCAP:
+	case VIDIOCGCHAN:
+	case VIDIOCSCHAN:
+	case VIDIOCGPICT:
+	case VIDIOCSPICT:
+	case VIDIOCCAPTURE:
+	case VIDIOCKEY:
+	case VIDIOCGAUDIO:
+	case VIDIOCSAUDIO:
+	case VIDIOCSYNC:
+	case VIDIOCMCAPTURE:
+	case VIDIOCGMBUF:
+	case VIDIOCGUNIT:
+	case VIDIOCGCAPTURE:
+	case VIDIOCSCAPTURE:
+
+	/* BTTV specific... */
+	case _IOW('v',  BASE_VIDIOCPRIVATE+0, char [256]):
+	case _IOR('v',  BASE_VIDIOCPRIVATE+1, char [256]):
+	case _IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int):
+	case _IOW('v' , BASE_VIDIOCPRIVATE+3, char [16]): /* struct bttv_pll_info */
+	case _IOR('v' , BASE_VIDIOCPRIVATE+4, int):
+	case _IOR('v' , BASE_VIDIOCPRIVATE+5, int):
+	case _IOR('v' , BASE_VIDIOCPRIVATE+6, int):
+	case _IOR('v' , BASE_VIDIOCPRIVATE+7, int):
+		ret = native_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
+		break;
+	}
+	return ret;
+}
+#else
+long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	return -ENOIOCTLCMD;
+}
+#endif
+EXPORT_SYMBOL_GPL(v4l_compat_ioctl32);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index b7ec9bf..9f59541 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -3807,6 +3807,7 @@
 	.read		= cpia_read,
 	.mmap		= cpia_mmap,
 	.ioctl          = cpia_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek         = no_llseek,
 };
 
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
index 643ead1..b421068 100644
--- a/drivers/media/video/cs53l32a.c
+++ b/drivers/media/video/cs53l32a.c
@@ -27,7 +27,7 @@
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
 #include <linux/videodev.h>
-#include <media/audiochip.h>
+#include <media/v4l2-common.h>
 
 MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC");
 MODULE_AUTHOR("Martin Vaughan");
@@ -39,21 +39,6 @@
 
 MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On");
 
-#define cs53l32a_dbg(fmt, arg...) \
-	do { \
-		if (debug) \
-			printk(KERN_INFO "%s debug %d-%04x: " fmt, \
-			       client->driver->driver.name, \
-			       i2c_adapter_id(client->adapter), client->addr , ## arg); \
-	} while (0)
-
-#define cs53l32a_err(fmt, arg...) do { \
-	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
-		i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-#define cs53l32a_info(fmt, arg...) do { \
-	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
-		i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-
 static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
 
 
@@ -74,50 +59,59 @@
 static int cs53l32a_command(struct i2c_client *client, unsigned int cmd,
 			    void *arg)
 {
-	int *input = arg;
+	struct v4l2_audio *input = arg;
+	struct v4l2_control *ctrl = arg;
 
 	switch (cmd) {
-	case AUDC_SET_INPUT:
-		switch (*input) {
-		case AUDIO_TUNER:
-			cs53l32a_write(client, 0x01, 0x01);
-			break;
-		case AUDIO_EXTERN:
-			cs53l32a_write(client, 0x01, 0x21);
-			break;
-		case AUDIO_MUTE:
-			cs53l32a_write(client, 0x03, 0xF0);
-			break;
-		case AUDIO_UNMUTE:
-			cs53l32a_write(client, 0x03, 0x30);
-			break;
-		default:
-			cs53l32a_err("Invalid input %d.\n", *input);
+	case VIDIOC_S_AUDIO:
+		/* There are 2 physical inputs, but the second input can be
+		   placed in two modes, the first mode bypasses the PGA (gain),
+		   the second goes through the PGA. Hence there are three
+		   possible inputs to choose from. */
+		if (input->index > 2) {
+			v4l_err(client, "Invalid input %d.\n", input->index);
 			return -EINVAL;
 		}
+		cs53l32a_write(client, 0x01, 0x01 + (input->index << 4));
+		break;
+
+	case VIDIOC_G_AUDIO:
+		memset(input, 0, sizeof(*input));
+		input->index = (cs53l32a_read(client, 0x01) >> 4) & 3;
+		break;
+
+	case VIDIOC_G_CTRL:
+		if (ctrl->id == V4L2_CID_AUDIO_MUTE) {
+			ctrl->value = (cs53l32a_read(client, 0x03) & 0xc0) != 0;
+			break;
+		}
+		if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
+			return -EINVAL;
+		ctrl->value = (s8)cs53l32a_read(client, 0x04);
 		break;
 
 	case VIDIOC_S_CTRL:
-		{
-			struct v4l2_control *ctrl = arg;
-
-			if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
-				return -EINVAL;
-			if (ctrl->value > 12 || ctrl->value < -90)
-				return -EINVAL;
-			cs53l32a_write(client, 0x04, (u8) ctrl->value);
-			cs53l32a_write(client, 0x05, (u8) ctrl->value);
+		if (ctrl->id == V4L2_CID_AUDIO_MUTE) {
+			cs53l32a_write(client, 0x03, ctrl->value ? 0xf0 : 0x30);
 			break;
 		}
+		if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
+			return -EINVAL;
+		if (ctrl->value > 12 || ctrl->value < -96)
+			return -EINVAL;
+		cs53l32a_write(client, 0x04, (u8) ctrl->value);
+		cs53l32a_write(client, 0x05, (u8) ctrl->value);
+		break;
 
 	case VIDIOC_LOG_STATUS:
 		{
 			u8 v = cs53l32a_read(client, 0x01);
 			u8 m = cs53l32a_read(client, 0x03);
+			s8 vol = cs53l32a_read(client, 0x04);
 
-			cs53l32a_info("Input: %s%s\n",
-				      v == 0x21 ? "external line in" : "tuner",
+			v4l_info(client, "Input:  %d%s\n", (v >> 4) & 3,
 				      (m & 0xC0) ? " (muted)" : "");
+			v4l_info(client, "Volume: %d dB\n", vol);
 			break;
 		}
 
@@ -157,12 +151,12 @@
 	client->driver = &i2c_driver;
 	snprintf(client->name, sizeof(client->name) - 1, "cs53l32a");
 
-	cs53l32a_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name);
+	v4l_info(client, "chip found @ 0x%x (%s)\n", address << 1, adapter->name);
 
 	for (i = 1; i <= 7; i++) {
 		u8 v = cs53l32a_read(client, i);
 
-		cs53l32a_dbg("Read Reg %d %02x\n", i, v);
+		v4l_dbg(1, client, "Read Reg %d %02x\n", i, v);
 	}
 
 	/* Set cs53l32a internal register for Adaptec 2010/2410 setup */
@@ -180,7 +174,7 @@
 	for (i = 1; i <= 7; i++) {
 		u8 v = cs53l32a_read(client, i);
 
-		cs53l32a_dbg("Read Reg %d %02x\n", i, v);
+		v4l_dbg(1, client, "Read Reg %d %02x\n", i, v);
 	}
 
 	i2c_attach_client(client);
@@ -190,11 +184,7 @@
 
 static int cs53l32a_probe(struct i2c_adapter *adapter)
 {
-#ifdef I2C_CLASS_TV_ANALOG
 	if (adapter->class & I2C_CLASS_TV_ANALOG)
-#else
-	if (adapter->id == I2C_HW_B_BT848)
-#endif
 		return i2c_probe(adapter, &addr_data, cs53l32a_attach);
 	return 0;
 }
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c
index 740908f..cb9a798 100644
--- a/drivers/media/video/cx25840/cx25840-audio.c
+++ b/drivers/media/video/cx25840/cx25840-audio.c
@@ -23,11 +23,13 @@
 
 #include "cx25840.h"
 
-inline static int set_audclk_freq(struct i2c_client *client,
-				 enum v4l2_audio_clock_freq freq)
+static int set_audclk_freq(struct i2c_client *client, u32 freq)
 {
 	struct cx25840_state *state = i2c_get_clientdata(client);
 
+	if (freq != 32000 && freq != 44100 && freq != 48000)
+		return -EINVAL;
+
 	/* assert soft reset */
 	cx25840_and_or(client, 0x810, ~0x1, 0x01);
 
@@ -35,10 +37,9 @@
 	/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
 	cx25840_write(client, 0x127, 0x50);
 
-	switch (state->audio_input) {
-	case AUDIO_TUNER:
+	if (state->aud_input != CX25840_AUDIO_SERIAL) {
 		switch (freq) {
-		case V4L2_AUDCLK_32_KHZ:
+		case 32000:
 			/* VID_PLL and AUX_PLL */
 			cx25840_write4(client, 0x108, 0x0f040610);
 
@@ -51,7 +52,7 @@
 			cx25840_write4(client, 0x90c, 0x7ff70108);
 			break;
 
-		case V4L2_AUDCLK_441_KHZ:
+		case 44100:
 			/* VID_PLL and AUX_PLL */
 			cx25840_write4(client, 0x108, 0x0f040910);
 
@@ -64,7 +65,7 @@
 			cx25840_write4(client, 0x90c, 0x596d0108);
 			break;
 
-		case V4L2_AUDCLK_48_KHZ:
+		case 48000:
 			/* VID_PLL and AUX_PLL */
 			cx25840_write4(client, 0x108, 0x0f040a10);
 
@@ -77,14 +78,9 @@
 			cx25840_write4(client, 0x90c, 0xaa4f0108);
 			break;
 		}
-		break;
-
-	case AUDIO_EXTERN_1:
-	case AUDIO_EXTERN_2:
-	case AUDIO_INTERN:
-	case AUDIO_RADIO:
+	} else {
 		switch (freq) {
-		case V4L2_AUDCLK_32_KHZ:
+		case 32000:
 			/* VID_PLL and AUX_PLL */
 			cx25840_write4(client, 0x108, 0x0f04081e);
 
@@ -103,7 +99,7 @@
 			cx25840_write(client, 0x127, 0x54);
 			break;
 
-		case V4L2_AUDCLK_441_KHZ:
+		case 44100:
 			/* VID_PLL and AUX_PLL */
 			cx25840_write4(client, 0x108, 0x0f040918);
 
@@ -119,7 +115,7 @@
 			cx25840_write4(client, 0x90c, 0x85730108);
 			break;
 
-		case V4L2_AUDCLK_48_KHZ:
+		case 48000:
 			/* VID_PLL and AUX_PLL */
 			cx25840_write4(client, 0x108, 0x0f040a18);
 
@@ -135,7 +131,6 @@
 			cx25840_write4(client, 0x90c, 0x55550108);
 			break;
 		}
-		break;
 	}
 
 	/* deassert soft reset */
@@ -146,51 +141,36 @@
 	return 0;
 }
 
-static int set_input(struct i2c_client *client, int audio_input)
+void cx25840_audio_set_path(struct i2c_client *client)
 {
 	struct cx25840_state *state = i2c_get_clientdata(client);
 
-	cx25840_dbg("set audio input (%d)\n", audio_input);
-
 	/* stop microcontroller */
 	cx25840_and_or(client, 0x803, ~0x10, 0);
 
 	/* Mute everything to prevent the PFFT! */
 	cx25840_write(client, 0x8d3, 0x1f);
 
-	switch (audio_input) {
-	case AUDIO_TUNER:
-		/* Set Path1 to Analog Demod Main Channel */
-		cx25840_write4(client, 0x8d0, 0x7038061f);
-
-		/* When the microcontroller detects the
-		 * audio format, it will unmute the lines */
-		cx25840_and_or(client, 0x803, ~0x10, 0x10);
-		break;
-
-	case AUDIO_EXTERN_1:
-	case AUDIO_EXTERN_2:
-	case AUDIO_INTERN:
-	case AUDIO_RADIO:
+	if (state->aud_input == CX25840_AUDIO_SERIAL) {
 		/* Set Path1 to Serial Audio Input */
 		cx25840_write4(client, 0x8d0, 0x12100101);
 
 		/* The microcontroller should not be started for the
 		 * non-tuner inputs: autodetection is specific for
 		 * TV audio. */
-		break;
+	} else {
+		/* Set Path1 to Analog Demod Main Channel */
+		cx25840_write4(client, 0x8d0, 0x7038061f);
 
-	default:
-		cx25840_dbg("Invalid audio input selection %d\n", audio_input);
-		return -EINVAL;
+		/* When the microcontroller detects the
+		 * audio format, it will unmute the lines */
+		cx25840_and_or(client, 0x803, ~0x10, 0x10);
 	}
 
-	state->audio_input = audio_input;
-
-	return set_audclk_freq(client, state->audclk_freq);
+	set_audclk_freq(client, state->audclk_freq);
 }
 
-inline static int get_volume(struct i2c_client *client)
+static int get_volume(struct i2c_client *client)
 {
 	/* Volume runs +18dB to -96dB in 1/2dB steps
 	 * change to fit the msp3400 -114dB to +12dB range */
@@ -201,7 +181,7 @@
 	return vol << 9;
 }
 
-inline static void set_volume(struct i2c_client *client, int volume)
+static void set_volume(struct i2c_client *client, int volume)
 {
 	/* First convert the volume to msp3400 values (0-127) */
 	int vol = volume >> 9;
@@ -218,7 +198,7 @@
 	cx25840_write(client, 0x8d4, 228 - (vol * 2));
 }
 
-inline static int get_bass(struct i2c_client *client)
+static int get_bass(struct i2c_client *client)
 {
 	/* bass is 49 steps +12dB to -12dB */
 
@@ -228,13 +208,13 @@
 	return bass;
 }
 
-inline static void set_bass(struct i2c_client *client, int bass)
+static void set_bass(struct i2c_client *client, int bass)
 {
 	/* PATH1_EQ_BASS_VOL */
 	cx25840_and_or(client, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff));
 }
 
-inline static int get_treble(struct i2c_client *client)
+static int get_treble(struct i2c_client *client)
 {
 	/* treble is 49 steps +12dB to -12dB */
 
@@ -244,13 +224,13 @@
 	return treble;
 }
 
-inline static void set_treble(struct i2c_client *client, int treble)
+static void set_treble(struct i2c_client *client, int treble)
 {
 	/* PATH1_EQ_TREBLE_VOL */
 	cx25840_and_or(client, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff));
 }
 
-inline static int get_balance(struct i2c_client *client)
+static int get_balance(struct i2c_client *client)
 {
 	/* balance is 7 bit, 0 to -96dB */
 
@@ -264,7 +244,7 @@
 	return balance << 8;
 }
 
-inline static void set_balance(struct i2c_client *client, int balance)
+static void set_balance(struct i2c_client *client, int balance)
 {
 	int bal = balance >> 8;
 	if (bal > 0x80) {
@@ -280,17 +260,17 @@
 	}
 }
 
-inline static int get_mute(struct i2c_client *client)
+static int get_mute(struct i2c_client *client)
 {
 	/* check SRC1_MUTE_EN */
 	return cx25840_read(client, 0x8d3) & 0x2 ? 1 : 0;
 }
 
-inline static void set_mute(struct i2c_client *client, int mute)
+static void set_mute(struct i2c_client *client, int mute)
 {
 	struct cx25840_state *state = i2c_get_clientdata(client);
 
-	if (state->audio_input == AUDIO_TUNER) {
+	if (state->aud_input != CX25840_AUDIO_SERIAL) {
 		/* Must turn off microcontroller in order to mute sound.
 		 * Not sure if this is the best method, but it does work.
 		 * If the microcontroller is running, then it will undo any
@@ -314,10 +294,9 @@
 	struct v4l2_control *ctrl = arg;
 
 	switch (cmd) {
-	case AUDC_SET_INPUT:
-		return set_input(client, *(int *)arg);
 	case VIDIOC_INT_AUDIO_CLOCK_FREQ:
-		return set_audclk_freq(client, *(enum v4l2_audio_clock_freq *)arg);
+		return set_audclk_freq(client, *(u32 *)arg);
+
 	case VIDIOC_G_CTRL:
 		switch (ctrl->id) {
 		case V4L2_CID_AUDIO_VOLUME:
@@ -339,6 +318,7 @@
 			return -EINVAL;
 		}
 		break;
+
 	case VIDIOC_S_CTRL:
 		switch (ctrl->id) {
 		case V4L2_CID_AUDIO_VOLUME:
@@ -360,6 +340,7 @@
 			return -EINVAL;
 		}
 		break;
+
 	default:
 		return -EINVAL;
 	}
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 3b09f46..d45237d 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -43,11 +43,11 @@
 static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
 
 
-int cx25840_debug = 0;
+int debug = 0;
 
-module_param(cx25840_debug, bool, 0644);
+module_param(debug, bool, 0644);
 
-MODULE_PARM_DESC(cx25840_debug, "Debugging messages [0=Off (default) 1=On]");
+MODULE_PARM_DESC(debug, "Debugging messages [0=Off (default) 1=On]");
 
 I2C_CLIENT_INSMOD;
 
@@ -115,13 +115,13 @@
 
 /* ----------------------------------------------------------------------- */
 
-static int set_input(struct i2c_client *, enum cx25840_input);
-static void input_change(struct i2c_client *);
+static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
+						enum cx25840_audio_input aud_input);
 static void log_status(struct i2c_client *client);
 
 /* ----------------------------------------------------------------------- */
 
-static inline void init_dll1(struct i2c_client *client)
+static void init_dll1(struct i2c_client *client)
 {
 	/* This is the Hauppauge sequence used to
 	 * initialize the Delay Lock Loop 1 (ADC DLL). */
@@ -135,7 +135,7 @@
 	cx25840_write(client, 0x15b, 0x10);
 }
 
-static inline void init_dll2(struct i2c_client *client)
+static void init_dll2(struct i2c_client *client)
 {
 	/* This is the Hauppauge sequence used to
 	 * initialize the Delay Lock Loop 2 (ADC DLL). */
@@ -195,10 +195,8 @@
 	/* AC97 shift */
 	cx25840_write(client, 0x8cf, 0x0f);
 
-	/* (re)set video input */
-	set_input(client, state->input);
-	/* (re)set audio input */
-	cx25840_audio(client, AUDC_SET_INPUT, &state->audio_input);
+	/* (re)set input */
+	set_input(client, state->vid_input, state->aud_input);
 
 	/* start microcontroller */
 	cx25840_and_or(client, 0x803, ~0x10, 0x10);
@@ -223,7 +221,7 @@
 		cx25840_write(client, 0x80b, 0x10);
 	} else if (std & V4L2_STD_NTSC) {
 		/* NTSC */
-		if (state->cardtype == CARDTYPE_PVR150_WORKAROUND) {
+		if (state->pvr150_workaround) {
 			/* Certain Hauppauge PVR150 models have a hardware bug
 			   that causes audio to drop out. For these models the
 			   audio standard must be set explicitly.
@@ -259,72 +257,68 @@
 	}
 }
 
-static int set_input(struct i2c_client *client, enum cx25840_input input)
+static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
+						enum cx25840_audio_input aud_input)
 {
 	struct cx25840_state *state = i2c_get_clientdata(client);
+	u8 is_composite = (vid_input >= CX25840_COMPOSITE1 &&
+			   vid_input <= CX25840_COMPOSITE8);
+	u8 reg;
 
-	cx25840_dbg("decoder set input (%d)\n", input);
+	v4l_dbg(1, client, "decoder set video input %d, audio input %d\n",
+			vid_input, aud_input);
 
-	switch (input) {
-	case CX25840_TUNER:
-		cx25840_dbg("now setting Tuner input\n");
+	if (is_composite) {
+		reg = 0xf0 + (vid_input - CX25840_COMPOSITE1);
+	} else {
+		int luma = vid_input & 0xf0;
+		int chroma = vid_input & 0xf00;
 
-		if (state->cardtype == CARDTYPE_PVR150 ||
-		    state->cardtype == CARDTYPE_PVR150_WORKAROUND) {
-			/* CH_SEL_ADC2=1 */
-			cx25840_and_or(client, 0x102, ~0x2, 0x02);
+		if ((vid_input & ~0xff0) ||
+		    luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA4 ||
+		    chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) {
+			v4l_err(client, "0x%04x is not a valid video input!\n", vid_input);
+			return -EINVAL;
 		}
-
-		/* Video Input Control */
-		if (state->cardtype == CARDTYPE_PG600) {
-			cx25840_write(client, 0x103, 0x11);
+		reg = 0xf0 + ((luma - CX25840_SVIDEO_LUMA1) >> 4);
+		if (chroma >= CX25840_SVIDEO_CHROMA7) {
+			reg &= 0x3f;
+			reg |= (chroma - CX25840_SVIDEO_CHROMA7) >> 2;
 		} else {
-			cx25840_write(client, 0x103, 0x46);
+			reg &= 0xcf;
+			reg |= (chroma - CX25840_SVIDEO_CHROMA4) >> 4;
 		}
+	}
 
-		/* INPUT_MODE=0 */
-		cx25840_and_or(client, 0x401, ~0x6, 0x00);
+	switch (aud_input) {
+	case CX25840_AUDIO_SERIAL:
+		/* do nothing, use serial audio input */
 		break;
-
-	case CX25840_COMPOSITE0:
-	case CX25840_COMPOSITE1:
-		cx25840_dbg("now setting Composite input\n");
-
-		/* Video Input Control */
-		if (state->cardtype == CARDTYPE_PG600) {
-			cx25840_write(client, 0x103, 0x00);
-		} else {
-			cx25840_write(client, 0x103, 0x02);
-		}
-
-		/* INPUT_MODE=0 */
-		cx25840_and_or(client, 0x401, ~0x6, 0x00);
-		break;
-
-	case CX25840_SVIDEO0:
-	case CX25840_SVIDEO1:
-		cx25840_dbg("now setting S-Video input\n");
-
-		/* CH_SEL_ADC2=0 */
-		cx25840_and_or(client, 0x102, ~0x2, 0x00);
-
-		/* Video Input Control */
-		if (state->cardtype == CARDTYPE_PG600) {
-			cx25840_write(client, 0x103, 0x02);
-		} else {
-			cx25840_write(client, 0x103, 0x10);
-		}
-
-		/* INPUT_MODE=1 */
-		cx25840_and_or(client, 0x401, ~0x6, 0x02);
-		break;
+	case CX25840_AUDIO4: reg &= ~0x30; break;
+	case CX25840_AUDIO5: reg &= ~0x30; reg |= 0x10; break;
+	case CX25840_AUDIO6: reg &= ~0x30; reg |= 0x20; break;
+	case CX25840_AUDIO7: reg &= ~0xc0; break;
+	case CX25840_AUDIO8: reg &= ~0xc0; reg |= 0x40; break;
 
 	default:
-		cx25840_err("%d is not a valid input!\n", input);
+		v4l_err(client, "0x%04x is not a valid audio input!\n", aud_input);
 		return -EINVAL;
 	}
 
-	state->input = input;
+	cx25840_write(client, 0x103, reg);
+	/* Set INPUT_MODE to Composite (0) or S-Video (1) */
+	cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02);
+	/* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
+	cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
+	/* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
+	if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30)
+		cx25840_and_or(client, 0x102, ~0x4, 4);
+	else
+		cx25840_and_or(client, 0x102, ~0x4, 0);
+
+	state->vid_input = vid_input;
+	state->aud_input = aud_input;
+	cx25840_audio_set_path(client);
 	input_change(client);
 	return 0;
 }
@@ -395,23 +389,14 @@
 	struct cx25840_state *state = i2c_get_clientdata(client);
 
 	switch (ctrl->id) {
-	case CX25840_CID_CARDTYPE:
-		switch (ctrl->value) {
-		case CARDTYPE_PVR150:
-		case CARDTYPE_PVR150_WORKAROUND:
-		case CARDTYPE_PG600:
-			state->cardtype = ctrl->value;
-			break;
-		default:
-			return -ERANGE;
-		}
-
-		set_input(client, state->input);
+	case CX25840_CID_ENABLE_PVR150_WORKAROUND:
+		state->pvr150_workaround = ctrl->value;
+		set_input(client, state->vid_input, state->aud_input);
 		break;
 
 	case V4L2_CID_BRIGHTNESS:
 		if (ctrl->value < 0 || ctrl->value > 255) {
-			cx25840_err("invalid brightness setting %d\n",
+			v4l_err(client, "invalid brightness setting %d\n",
 				    ctrl->value);
 			return -ERANGE;
 		}
@@ -421,7 +406,7 @@
 
 	case V4L2_CID_CONTRAST:
 		if (ctrl->value < 0 || ctrl->value > 127) {
-			cx25840_err("invalid contrast setting %d\n",
+			v4l_err(client, "invalid contrast setting %d\n",
 				    ctrl->value);
 			return -ERANGE;
 		}
@@ -431,7 +416,7 @@
 
 	case V4L2_CID_SATURATION:
 		if (ctrl->value < 0 || ctrl->value > 127) {
-			cx25840_err("invalid saturation setting %d\n",
+			v4l_err(client, "invalid saturation setting %d\n",
 				    ctrl->value);
 			return -ERANGE;
 		}
@@ -442,7 +427,7 @@
 
 	case V4L2_CID_HUE:
 		if (ctrl->value < -127 || ctrl->value > 127) {
-			cx25840_err("invalid hue setting %d\n", ctrl->value);
+			v4l_err(client, "invalid hue setting %d\n", ctrl->value);
 			return -ERANGE;
 		}
 
@@ -455,6 +440,9 @@
 	case V4L2_CID_AUDIO_BALANCE:
 	case V4L2_CID_AUDIO_MUTE:
 		return cx25840_audio(client, VIDIOC_S_CTRL, ctrl);
+
+	default:
+		return -EINVAL;
 	}
 
 	return 0;
@@ -465,11 +453,11 @@
 	struct cx25840_state *state = i2c_get_clientdata(client);
 
 	switch (ctrl->id) {
-	case CX25840_CID_CARDTYPE:
-		ctrl->value = state->cardtype;
+	case CX25840_CID_ENABLE_PVR150_WORKAROUND:
+		ctrl->value = state->pvr150_workaround;
 		break;
 	case V4L2_CID_BRIGHTNESS:
-		ctrl->value = cx25840_read(client, 0x414) + 128;
+		ctrl->value = (s8)cx25840_read(client, 0x414) + 128;
 		break;
 	case V4L2_CID_CONTRAST:
 		ctrl->value = cx25840_read(client, 0x415) >> 1;
@@ -478,7 +466,7 @@
 		ctrl->value = cx25840_read(client, 0x420) >> 1;
 		break;
 	case V4L2_CID_HUE:
-		ctrl->value = cx25840_read(client, 0x422);
+		ctrl->value = (s8)cx25840_read(client, 0x422);
 		break;
 	case V4L2_CID_AUDIO_VOLUME:
 	case V4L2_CID_AUDIO_BASS:
@@ -527,7 +515,7 @@
 
 		if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
 		    (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
-			cx25840_err("%dx%d is not a valid size!\n",
+			v4l_err(client, "%dx%d is not a valid size!\n",
 				    pix->width, pix->height);
 			return -ERANGE;
 		}
@@ -545,7 +533,7 @@
 		else
 			filter = 3;
 
-		cx25840_dbg("decoder set size %dx%d -> scale  %ux%u\n",
+		v4l_dbg(1, client, "decoder set size %dx%d -> scale  %ux%u\n",
 			    pix->width, pix->height, HSC, VSC);
 
 		/* HSCALE=HSC */
@@ -574,17 +562,98 @@
 
 /* ----------------------------------------------------------------------- */
 
+static struct v4l2_queryctrl cx25840_qctrl[] = {
+	{
+		.id            = V4L2_CID_BRIGHTNESS,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+		.name          = "Brightness",
+		.minimum       = 0,
+		.maximum       = 255,
+		.step          = 1,
+		.default_value = 128,
+		.flags         = 0,
+	}, {
+		.id            = V4L2_CID_CONTRAST,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+		.name          = "Contrast",
+		.minimum       = 0,
+		.maximum       = 255,
+		.step          = 1,
+		.default_value = 64,
+		.flags         = 0,
+	}, {
+		.id            = V4L2_CID_SATURATION,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+		.name          = "Saturation",
+		.minimum       = 0,
+		.maximum       = 255,
+		.step          = 1,
+		.default_value = 64,
+		.flags         = 0,
+	}, {
+		.id            = V4L2_CID_HUE,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+		.name          = "Hue",
+		.minimum       = -128,
+		.maximum       = 127,
+		.step          = 1,
+		.default_value = 0,
+		.flags 	       = 0,
+	}, {
+		.id            = V4L2_CID_AUDIO_VOLUME,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+		.name          = "Volume",
+		.minimum       = 0,
+		.maximum       = 65535,
+		.step          = 65535/100,
+		.default_value = 58880,
+		.flags         = 0,
+	}, {
+		.id            = V4L2_CID_AUDIO_BALANCE,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+		.name          = "Balance",
+		.minimum       = 0,
+		.maximum       = 65535,
+		.step          = 65535/100,
+		.default_value = 32768,
+		.flags         = 0,
+	}, {
+		.id            = V4L2_CID_AUDIO_MUTE,
+		.type          = V4L2_CTRL_TYPE_BOOLEAN,
+		.name          = "Mute",
+		.minimum       = 0,
+		.maximum       = 1,
+		.step          = 1,
+		.default_value = 1,
+		.flags         = 0,
+	}, {
+		.id            = V4L2_CID_AUDIO_BASS,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+		.name          = "Bass",
+		.minimum       = 0,
+		.maximum       = 65535,
+		.step          = 65535/100,
+		.default_value = 32768,
+	}, {
+		.id            = V4L2_CID_AUDIO_TREBLE,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+		.name          = "Treble",
+		.minimum       = 0,
+		.maximum       = 65535,
+		.step          = 65535/100,
+		.default_value = 32768,
+	},
+};
+
+/* ----------------------------------------------------------------------- */
+
 static int cx25840_command(struct i2c_client *client, unsigned int cmd,
 			   void *arg)
 {
 	struct cx25840_state *state = i2c_get_clientdata(client);
 	struct v4l2_tuner *vt = arg;
-	int result = 0;
 
 	switch (cmd) {
-	case 0:
-		break;
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	/* ioctls to allow direct access to the
 	 * cx25840 registers for testing */
@@ -615,18 +684,16 @@
 		return cx25840_vbi(client, cmd, arg);
 
 	case VIDIOC_INT_AUDIO_CLOCK_FREQ:
-	case AUDC_SET_INPUT:
-		result = cx25840_audio(client, cmd, arg);
-		break;
+		return cx25840_audio(client, cmd, arg);
 
 	case VIDIOC_STREAMON:
-		cx25840_dbg("enable output\n");
+		v4l_dbg(1, client, "enable output\n");
 		cx25840_write(client, 0x115, 0x8c);
 		cx25840_write(client, 0x116, 0x07);
 		break;
 
 	case VIDIOC_STREAMOFF:
-		cx25840_dbg("disable output\n");
+		v4l_dbg(1, client, "disable output\n");
 		cx25840_write(client, 0x115, 0x00);
 		cx25840_write(client, 0x116, 0x00);
 		break;
@@ -636,28 +703,58 @@
 		break;
 
 	case VIDIOC_G_CTRL:
-		result = get_v4lctrl(client, (struct v4l2_control *)arg);
-		break;
+		return get_v4lctrl(client, (struct v4l2_control *)arg);
 
 	case VIDIOC_S_CTRL:
-		result = set_v4lctrl(client, (struct v4l2_control *)arg);
-		break;
+		return set_v4lctrl(client, (struct v4l2_control *)arg);
+
+	case VIDIOC_QUERYCTRL:
+	{
+		struct v4l2_queryctrl *qc = arg;
+		int i;
+
+		for (i = 0; i < ARRAY_SIZE(cx25840_qctrl); i++)
+			if (qc->id && qc->id == cx25840_qctrl[i].id) {
+				memcpy(qc, &cx25840_qctrl[i], sizeof(*qc));
+				return 0;
+			}
+		return -EINVAL;
+	}
 
 	case VIDIOC_G_STD:
 		*(v4l2_std_id *)arg = cx25840_get_v4lstd(client);
 		break;
 
 	case VIDIOC_S_STD:
-		result = set_v4lstd(client, *(v4l2_std_id *)arg);
+		state->radio = 0;
+		return set_v4lstd(client, *(v4l2_std_id *)arg);
+
+	case AUDC_SET_RADIO:
+		state->radio = 1;
 		break;
 
 	case VIDIOC_G_INPUT:
-		*(int *)arg = state->input;
+		*(int *)arg = state->vid_input;
 		break;
 
 	case VIDIOC_S_INPUT:
-		result = set_input(client, *(int *)arg);
+		return set_input(client, *(enum cx25840_video_input *)arg, state->aud_input);
+
+	case VIDIOC_S_AUDIO:
+	{
+		struct v4l2_audio *input = arg;
+
+		return set_input(client, state->vid_input, input->index);
+	}
+
+	case VIDIOC_G_AUDIO:
+	{
+		struct v4l2_audio *input = arg;
+
+		memset(input, 0, sizeof(*input));
+		input->index = state->aud_input;
 		break;
+	}
 
 	case VIDIOC_S_FREQUENCY:
 		input_change(client);
@@ -670,6 +767,9 @@
 		u8 vpres = cx25840_read(client, 0x80a) & 0x10;
 		int val = 0;
 
+		if (state->radio)
+			break;
+
 		vt->capability |=
 		    V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
 		    V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
@@ -724,12 +824,10 @@
 		break;
 
 	case VIDIOC_G_FMT:
-		result = get_v4lfmt(client, (struct v4l2_format *)arg);
-		break;
+		return get_v4lfmt(client, (struct v4l2_format *)arg);
 
 	case VIDIOC_S_FMT:
-		result = set_v4lfmt(client, (struct v4l2_format *)arg);
-		break;
+		return set_v4lfmt(client, (struct v4l2_format *)arg);
 
 	case VIDIOC_INT_RESET:
 		cx25840_initialize(client, 0);
@@ -741,11 +839,10 @@
 		break;
 
 	default:
-		cx25840_err("invalid ioctl %x\n", cmd);
 		return -EINVAL;
 	}
 
-	return result;
+	return 0;
 }
 
 /* ----------------------------------------------------------------------- */
@@ -775,7 +872,7 @@
 	client->driver = &i2c_driver_cx25840;
 	snprintf(client->name, sizeof(client->name) - 1, "cx25840");
 
-	cx25840_dbg("detecting cx25840 client on address 0x%x\n", address << 1);
+	v4l_dbg(1, client, "detecting cx25840 client on address 0x%x\n", address << 1);
 
 	device_id = cx25840_read(client, 0x101) << 8;
 	device_id |= cx25840_read(client, 0x100);
@@ -783,12 +880,12 @@
 	/* The high byte of the device ID should be
 	 * 0x84 if chip is present */
 	if ((device_id & 0xff00) != 0x8400) {
-		cx25840_dbg("cx25840 not found\n");
+		v4l_dbg(1, client, "cx25840 not found\n");
 		kfree(client);
 		return 0;
 	}
 
-	cx25840_info("cx25%3x-2%x found @ 0x%x (%s)\n",
+	v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n",
 		    (device_id & 0xfff0) >> 4,
 		    (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3,
 		    address << 1, adapter->name);
@@ -801,10 +898,10 @@
 
 	i2c_set_clientdata(client, state);
 	memset(state, 0, sizeof(struct cx25840_state));
-	state->input = CX25840_TUNER;
-	state->audclk_freq = V4L2_AUDCLK_48_KHZ;
-	state->audio_input = AUDIO_TUNER;
-	state->cardtype = CARDTYPE_PVR150;
+	state->vid_input = CX25840_COMPOSITE7;
+	state->aud_input = CX25840_AUDIO8;
+	state->audclk_freq = 48000;
+	state->pvr150_workaround = 0;
 
 	cx25840_initialize(client, 1);
 
@@ -815,11 +912,7 @@
 
 static int cx25840_attach_adapter(struct i2c_adapter *adapter)
 {
-#ifdef I2C_CLASS_TV_ANALOG
 	if (adapter->class & I2C_CLASS_TV_ANALOG)
-#else
-	if (adapter->id == I2C_HW_B_BT848)
-#endif
 		return i2c_probe(adapter, &addr_data, &cx25840_detect_client);
 	return 0;
 }
@@ -846,9 +939,7 @@
 	.driver = {
 		.name = "cx25840",
 	},
-
 	.id = I2C_DRIVERID_CX25840,
-
 	.attach_adapter = cx25840_attach_adapter,
 	.detach_client = cx25840_detach_client,
 	.command = cx25840_command,
@@ -892,11 +983,13 @@
 	u8 pref_mode = cx25840_read(client, 0x809);
 	u8 afc0 = cx25840_read(client, 0x80b);
 	u8 mute_ctl = cx25840_read(client, 0x8d3);
+	int vid_input = state->vid_input;
+	int aud_input = state->aud_input;
 	char *p;
 
-	cx25840_info("Video signal:              %spresent\n",
+	v4l_info(client, "Video signal:              %spresent\n",
 		    (microctrl_vidfmt & 0x10) ? "" : "not ");
-	cx25840_info("Detected format:           %s\n",
+	v4l_info(client, "Detected format:           %s\n",
 		    fmt_strs[gen_stat1 & 0xf]);
 
 	switch (mod_det_stat0) {
@@ -911,7 +1004,7 @@
 	case 0xfe: p = "forced mode"; break;
 	default: p = "not defined";
 	}
-	cx25840_info("Detected audio mode:       %s\n", p);
+	v4l_info(client, "Detected audio mode:       %s\n", p);
 
 	switch (mod_det_stat1) {
 	case 0x00: p = "not defined"; break;
@@ -937,10 +1030,10 @@
 	case 0xff: p = "no detected audio standard"; break;
 	default: p = "not defined";
 	}
-	cx25840_info("Detected audio standard:   %s\n", p);
-	cx25840_info("Audio muted:               %s\n",
+	v4l_info(client, "Detected audio standard:   %s\n", p);
+	v4l_info(client, "Audio muted:               %s\n",
 		    (mute_ctl & 0x2) ? "yes" : "no");
-	cx25840_info("Audio microcontroller:     %s\n",
+	v4l_info(client, "Audio microcontroller:     %s\n",
 		    (download_ctl & 0x10) ? "running" : "stopped");
 
 	switch (audio_config >> 4) {
@@ -962,7 +1055,7 @@
 	case 0x0f: p = "automatic detection"; break;
 	default: p = "undefined";
 	}
-	cx25840_info("Configured audio standard: %s\n", p);
+	v4l_info(client, "Configured audio standard: %s\n", p);
 
 	if ((audio_config >> 4) < 0xF) {
 		switch (audio_config & 0xF) {
@@ -979,7 +1072,7 @@
 		case 0x0a: p = "SAP"; break;
 		default: p = "undefined";
 		}
-		cx25840_info("Configured audio mode:     %s\n", p);
+		v4l_info(client, "Configured audio mode:     %s\n", p);
 	} else {
 		switch (audio_config & 0xF) {
 		case 0x00: p = "BG"; break;
@@ -995,30 +1088,27 @@
 		case 0x0f: p = "automatic standard and mode detection"; break;
 		default: p = "undefined";
 		}
-		cx25840_info("Configured audio system:   %s\n", p);
+		v4l_info(client, "Configured audio system:   %s\n", p);
 	}
 
-	cx25840_info("Specified standard:        %s\n",
+	v4l_info(client, "Specified standard:        %s\n",
 		    vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
 
-	switch (state->input) {
-	case CX25840_COMPOSITE0: p = "Composite 0"; break;
-	case CX25840_COMPOSITE1: p = "Composite 1"; break;
-	case CX25840_SVIDEO0: p = "S-Video 0"; break;
-	case CX25840_SVIDEO1: p = "S-Video 1"; break;
-	case CX25840_TUNER: p = "Tuner"; break;
+	if (vid_input >= CX25840_COMPOSITE1 &&
+	    vid_input <= CX25840_COMPOSITE8) {
+		v4l_info(client, "Specified video input:     Composite %d\n",
+			vid_input - CX25840_COMPOSITE1 + 1);
+	} else {
+		v4l_info(client, "Specified video input:     S-Video (Luma In%d, Chroma In%d)\n",
+			(vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
 	}
-	cx25840_info("Specified input:           %s\n", p);
-	cx25840_info("Specified audio input:     %s\n",
-		    state->audio_input == 0 ? "Tuner" : "External");
+	if (aud_input) {
+		v4l_info(client, "Specified audio input:     Tuner (In%d)\n", aud_input);
+	} else {
+		v4l_info(client, "Specified audio input:     External\n");
+	}
 
-	switch (state->audclk_freq) {
-	case V4L2_AUDCLK_441_KHZ: p = "44.1 kHz"; break;
-	case V4L2_AUDCLK_48_KHZ: p = "48 kHz"; break;
-	case V4L2_AUDCLK_32_KHZ: p = "32 kHz"; break;
-	default: p = "undefined";
-	}
-	cx25840_info("Specified audioclock freq: %s\n", p);
+	v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq);
 
 	switch (pref_mode & 0xf) {
 	case 0: p = "mono/language A"; break;
@@ -1031,7 +1121,7 @@
 	case 7: p = "language AB"; break;
 	default: p = "undefined";
 	}
-	cx25840_info("Preferred audio mode:      %s\n", p);
+	v4l_info(client, "Preferred audio mode:      %s\n", p);
 
 	if ((audio_config & 0xf) == 0xf) {
 		switch ((afc0 >> 3) & 0x3) {
@@ -1040,7 +1130,7 @@
 		case 2: p = "autodetect"; break;
 		default: p = "undefined";
 		}
-		cx25840_info("Selected 65 MHz format:    %s\n", p);
+		v4l_info(client, "Selected 65 MHz format:    %s\n", p);
 
 		switch (afc0 & 0x7) {
 		case 0: p = "chroma"; break;
@@ -1050,6 +1140,6 @@
 		case 4: p = "autodetect"; break;
 		default: p = "undefined";
 		}
-		cx25840_info("Selected 45 MHz format:    %s\n", p);
+		v4l_info(client, "Selected 45 MHz format:    %s\n", p);
 	}
 }
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c
index df9d50a..e1a7823 100644
--- a/drivers/media/video/cx25840/cx25840-firmware.c
+++ b/drivers/media/video/cx25840/cx25840-firmware.c
@@ -15,7 +15,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 #include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
@@ -38,7 +37,7 @@
 MODULE_PARM_DESC(fastfw, "Load firmware fast [0=100MHz 1=333MHz (default)]");
 MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]");
 
-static inline void set_i2c_delay(struct i2c_client *client, int delay)
+static void set_i2c_delay(struct i2c_client *client, int delay)
 {
 	struct i2c_algo_bit_data *algod = client->adapter->algo_data;
 
@@ -52,7 +51,7 @@
 	}
 }
 
-static inline void start_fw_load(struct i2c_client *client)
+static void start_fw_load(struct i2c_client *client)
 {
 	/* DL_ADDR_LB=0 DL_ADDR_HB=0 */
 	cx25840_write(client, 0x800, 0x00);
@@ -66,7 +65,7 @@
 		set_i2c_delay(client, 3);
 }
 
-static inline void end_fw_load(struct i2c_client *client)
+static void end_fw_load(struct i2c_client *client)
 {
 	if (fastfw)
 		set_i2c_delay(client, 10);
@@ -77,38 +76,47 @@
 	cx25840_write(client, 0x803, 0x03);
 }
 
-static inline int check_fw_load(struct i2c_client *client, int size)
+static int check_fw_load(struct i2c_client *client, int size)
 {
 	/* DL_ADDR_HB DL_ADDR_LB */
 	int s = cx25840_read(client, 0x801) << 8;
 	s |= cx25840_read(client, 0x800);
 
 	if (size != s) {
-		cx25840_err("firmware %s load failed\n", firmware);
+		v4l_err(client, "firmware %s load failed\n", firmware);
 		return -EINVAL;
 	}
 
-	cx25840_info("loaded %s firmware (%d bytes)\n", firmware, size);
+	v4l_info(client, "loaded %s firmware (%d bytes)\n", firmware, size);
 	return 0;
 }
 
-static inline int fw_write(struct i2c_client *client, u8 * data, int size)
+static int fw_write(struct i2c_client *client, u8 * data, int size)
 {
-	if (i2c_master_send(client, data, size) < size) {
+	int sent;
+
+	if ((sent = i2c_master_send(client, data, size)) < size) {
 
 		if (fastfw) {
-			cx25840_err("333MHz i2c firmware load failed\n");
+			v4l_err(client, "333MHz i2c firmware load failed\n");
 			fastfw = 0;
 			set_i2c_delay(client, 10);
 
+			if (sent > 2) {
+				u16 dl_addr = cx25840_read(client, 0x801) << 8;
+				dl_addr |= cx25840_read(client, 0x800);
+				dl_addr -= sent - 2;
+				cx25840_write(client, 0x801, dl_addr >> 8);
+				cx25840_write(client, 0x800, dl_addr & 0xff);
+			}
+
 			if (i2c_master_send(client, data, size) < size) {
-				cx25840_err
-				    ("100MHz i2c firmware load failed\n");
+				v4l_err(client, "100MHz i2c firmware load failed\n");
 				return -ENOSYS;
 			}
 
 		} else {
-			cx25840_err("firmware load i2c failure\n");
+			v4l_err(client, "firmware load i2c failure\n");
 			return -ENOSYS;
 		}
 
@@ -124,7 +132,7 @@
 	int size, send, retval;
 
 	if (request_firmware(&fw, firmware, FWDEV(client)) != 0) {
-		cx25840_err("unable to open firmware %s\n", firmware);
+		v4l_err(client, "unable to open firmware %s\n", firmware);
 		return -EINVAL;
 	}
 
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c
index 13ba4e1..04d879d 100644
--- a/drivers/media/video/cx25840/cx25840-vbi.c
+++ b/drivers/media/video/cx25840/cx25840-vbi.c
@@ -22,7 +22,7 @@
 
 #include "cx25840.h"
 
-static inline int odd_parity(u8 c)
+static int odd_parity(u8 c)
 {
 	c ^= (c >> 4);
 	c ^= (c >> 2);
@@ -31,7 +31,7 @@
 	return c & 1;
 }
 
-static inline int decode_vps(u8 * dst, u8 * p)
+static int decode_vps(u8 * dst, u8 * p)
 {
 	static const u8 biphase_tbl[] = {
 		0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
diff --git a/drivers/media/video/cx25840/cx25840.h b/drivers/media/video/cx25840/cx25840.h
index 40aa59f..fd22f30 100644
--- a/drivers/media/video/cx25840/cx25840.h
+++ b/drivers/media/video/cx25840/cx25840.h
@@ -24,48 +24,60 @@
 #include <linux/videodev2.h>
 #include <linux/i2c.h>
 
-extern int cx25840_debug;
-
-#define cx25840_dbg(fmt, arg...) do { if (cx25840_debug) \
-	printk(KERN_INFO "%s debug %d-%04x: " fmt, \
-	       client->driver->driver.name, \
-	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-
-#define cx25840_err(fmt, arg...) do { \
-	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
-	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-
-#define cx25840_info(fmt, arg...) do { \
-	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
-	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-
-#define CX25840_CID_CARDTYPE (V4L2_CID_PRIVATE_BASE+0)
-
-/* The CARDTYPE_PVR150_WORKAROUND cardtype activates a workaround for a
-   hardware bug that is present in PVR150 (and possible PVR500) cards that
-   have certain NTSC tuners (tveeprom model numbers 85, 99 and 112). The
+/* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is
+   present in Hauppauge PVR-150 (and possibly PVR-500) cards that have
+   certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The
    audio autodetect fails on some channels for these models and the workaround
    is to select the audio standard explicitly. Many thanks to Hauppauge for
    providing this information. */
-enum cx25840_cardtype {
-	CARDTYPE_PVR150,
-	CARDTYPE_PG600,
-	CARDTYPE_PVR150_WORKAROUND,
+#define CX25840_CID_ENABLE_PVR150_WORKAROUND (V4L2_CID_PRIVATE_BASE+0)
+
+enum cx25840_video_input {
+	/* Composite video inputs In1-In8 */
+	CX25840_COMPOSITE1 = 1,
+	CX25840_COMPOSITE2,
+	CX25840_COMPOSITE3,
+	CX25840_COMPOSITE4,
+	CX25840_COMPOSITE5,
+	CX25840_COMPOSITE6,
+	CX25840_COMPOSITE7,
+	CX25840_COMPOSITE8,
+
+	/* S-Video inputs consist of one luma input (In1-In4) ORed with one
+	   chroma input (In5-In8) */
+	CX25840_SVIDEO_LUMA1 = 0x10,
+	CX25840_SVIDEO_LUMA2 = 0x20,
+	CX25840_SVIDEO_LUMA3 = 0x30,
+	CX25840_SVIDEO_LUMA4 = 0x40,
+	CX25840_SVIDEO_CHROMA4 = 0x400,
+	CX25840_SVIDEO_CHROMA5 = 0x500,
+	CX25840_SVIDEO_CHROMA6 = 0x600,
+	CX25840_SVIDEO_CHROMA7 = 0x700,
+	CX25840_SVIDEO_CHROMA8 = 0x800,
+
+	/* S-Video aliases for common luma/chroma combinations */
+	CX25840_SVIDEO1 = 0x510,
+	CX25840_SVIDEO2 = 0x620,
+	CX25840_SVIDEO3 = 0x730,
+	CX25840_SVIDEO4 = 0x840,
 };
 
-enum cx25840_input {
-	CX25840_TUNER,
-	CX25840_COMPOSITE0,
-	CX25840_COMPOSITE1,
-	CX25840_SVIDEO0,
-	CX25840_SVIDEO1
+enum cx25840_audio_input {
+	/* Audio inputs: serial or In4-In8 */
+	CX25840_AUDIO_SERIAL,
+	CX25840_AUDIO4 = 4,
+	CX25840_AUDIO5,
+	CX25840_AUDIO6,
+	CX25840_AUDIO7,
+	CX25840_AUDIO8,
 };
 
 struct cx25840_state {
-	enum cx25840_cardtype cardtype;
-	enum cx25840_input input;
-	int audio_input;
-	enum v4l2_audio_clock_freq audclk_freq;
+	int pvr150_workaround;
+	int radio;
+	enum cx25840_video_input vid_input;
+	enum cx25840_audio_input aud_input;
+	u32 audclk_freq;
 };
 
 /* ----------------------------------------------------------------------- */
@@ -84,6 +96,7 @@
 /* ----------------------------------------------------------------------- */
 /* cx25850-audio.c                                                         */
 int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg);
+void cx25840_audio_set_path(struct i2c_client *client);
 
 /* ----------------------------------------------------------------------- */
 /* cx25850-vbi.c                                                           */
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 85ba410..76fcb4e 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -29,6 +29,21 @@
 	  You must also select one or more DVB/ATSC demodulators.
 	  If you are unsure which you need, choose all of them.
 
+config VIDEO_CX88_ALSA
+	tristate "ALSA DMA audio support"
+	depends on VIDEO_CX88 && SND
+	select SND_PCM_OSS
+	---help---
+	  This is a video4linux driver for direct (DMA) audio on
+	  Conexant 2388x based TV cards.
+	  It only works with boards with function 01 enabled.
+	  To check if your board supports, use lspci -n.
+	  If supported, you should see 1471:8801 or 1471:8811
+	  PCI device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called cx88-alsa.
+
 config VIDEO_CX88_DVB_ALL_FRONTENDS
 	bool "Build all supported frontends for cx2388x based TV cards"
 	default y
@@ -38,6 +53,7 @@
 	select DVB_CX22702
 	select DVB_LGDT330X
 	select DVB_NXT200X
+	select DVB_CX24123
 	---help---
 	  This builds cx88-dvb with all currently supported frontend
 	  demodulators.  If you wish to tweak your configuration, and
@@ -89,3 +105,12 @@
 	---help---
 	  This adds ATSC 8VSB and QAM64/256 support for cards based on the
 	  Connexant 2388x chip and the NXT2002/NXT2004 demodulator.
+
+config VIDEO_CX88_DVB_CX24123
+	bool "Conexant CX24123 DVB-S Support"
+	default y
+	depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
+	select DVB_CX24123
+	---help---
+	  This adds DVB-S support for cards based on the
+	  Connexant 2388x chip and the CX24123 demodulator.
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
index 54401b0..e4b2134 100644
--- a/drivers/media/video/cx88/Makefile
+++ b/drivers/media/video/cx88/Makefile
@@ -4,7 +4,7 @@
 cx8802-objs	:= cx88-mpeg.o
 
 obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o cx88-blackbird.o
-obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
+obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o cx88-vp3054-i2c.o
 
 EXTRA_CFLAGS += -I$(src)/..
 EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
@@ -16,5 +16,7 @@
 extra-cflags-$(CONFIG_DVB_LGDT330X)  += -DHAVE_LGDT330X=1
 extra-cflags-$(CONFIG_DVB_MT352)     += -DHAVE_MT352=1
 extra-cflags-$(CONFIG_DVB_NXT200X)   += -DHAVE_NXT200X=1
+extra-cflags-$(CONFIG_DVB_CX24123)   += -DHAVE_CX24123=1
+extra-cflags-$(CONFIG_VIDEO_CX88_DVB)+= -DHAVE_VP3054_I2C=1
 
 EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
new file mode 100644
index 0000000..7695b52
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -0,0 +1,848 @@
+/*
+ *
+ *  Support for audio capture
+ *  PCI function #1 of the cx2388x.
+ *
+ *    (c) 2005,2006 Ricardo Cerqueira <v4l@cerqueira.org>
+ *    (c) 2005 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
+ *    Based on a dummy cx88 module by Gerd Knorr <kraxel@bytesex.org>
+ *    Based on dummy.c by Jaroslav Kysela <perex@suse.cz>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <asm/delay.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/control.h>
+#include <sound/initval.h>
+
+#include "cx88.h"
+#include "cx88-reg.h"
+
+#define dprintk(level,fmt, arg...)	if (debug >= level) \
+	printk(KERN_INFO "%s/1: " fmt, chip->core->name , ## arg)
+
+#define dprintk_core(level,fmt, arg...)	if (debug >= level) \
+	printk(KERN_DEBUG "%s/1: " fmt, chip->core->name , ## arg)
+
+
+/****************************************************************************
+	Data type declarations - Can be moded to a header file later
+ ****************************************************************************/
+
+/* These can be replaced after done */
+#define MIXER_ADDR_LAST MAX_CX88_INPUT
+
+struct cx88_audio_dev {
+	struct cx88_core           *core;
+	struct cx88_dmaqueue       q;
+
+	/* pci i/o */
+	struct pci_dev             *pci;
+	unsigned char              pci_rev,pci_lat;
+
+	/* audio controls */
+	int                        irq;
+
+	snd_card_t                 *card;
+
+	spinlock_t                 reg_lock;
+
+	unsigned int               dma_size;
+	unsigned int               period_size;
+	unsigned int               num_periods;
+
+	struct videobuf_dmabuf dma_risc;
+
+	int                        mixer_volume[MIXER_ADDR_LAST+1][2];
+	int                        capture_source[MIXER_ADDR_LAST+1][2];
+
+	long int read_count;
+	long int read_offset;
+
+	struct cx88_buffer   *buf;
+
+	long opened;
+	snd_pcm_substream_t *substream;
+
+};
+typedef struct cx88_audio_dev snd_cx88_card_t;
+
+
+
+/****************************************************************************
+			Module global static vars
+ ****************************************************************************/
+
+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] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
+static snd_card_t *snd_cx88_cards[SNDRV_CARDS];
+
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled.");
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for cx88x capture interface(s).");
+
+
+/****************************************************************************
+				Module macros
+ ****************************************************************************/
+
+MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards");
+MODULE_AUTHOR("Ricardo Cerqueira");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@brturbo.com.br>");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("{{Conexant,23881},"
+			"{{Conexant,23882},"
+			"{{Conexant,23883}");
+static unsigned int debug = 0;
+module_param(debug,int,0644);
+MODULE_PARM_DESC(debug,"enable debug messages");
+
+/****************************************************************************
+			Module specific funtions
+ ****************************************************************************/
+
+/*
+ * BOARD Specific: Sets audio DMA
+ */
+
+int _cx88_start_audio_dma(snd_cx88_card_t *chip)
+{
+	struct cx88_buffer   *buf = chip->buf;
+	struct cx88_core *core=chip->core;
+	struct sram_channel *audio_ch = &cx88_sram_channels[SRAM_CH25];
+
+
+	dprintk(1, "Starting audio DMA for %i bytes/line and %i (%i) lines at address %08x\n",buf->bpl, chip->num_periods, audio_ch->fifo_size / buf->bpl, audio_ch->fifo_start);
+
+	/* setup fifo + format - out channel */
+	cx88_sram_channel_setup(chip->core, &cx88_sram_channels[SRAM_CH25],
+				buf->bpl, buf->risc.dma);
+
+	/* sets bpl size */
+	cx_write(MO_AUDD_LNGTH, buf->bpl);
+
+	/* reset counter */
+	cx_write(MO_AUDD_GPCNTRL,GP_COUNT_CONTROL_RESET);
+
+	dprintk(1,"Enabling IRQ, setting mask from 0x%x to 0x%x\n",chip->core->pci_irqmask,(chip->core->pci_irqmask | 0x02));
+	/* enable irqs */
+	cx_set(MO_PCI_INTMSK, chip->core->pci_irqmask | 0x02);
+
+
+	/* Enables corresponding bits at AUD_INT_STAT */
+	cx_write(MO_AUD_INTMSK,
+			(1<<16)|
+			(1<<12)|
+			(1<<4)|
+			(1<<0)
+			);
+
+	/* start dma */
+	cx_set(MO_DEV_CNTRL2, (1<<5)); /* Enables Risc Processor */
+	cx_set(MO_AUD_DMACNTRL, 0x11); /* audio downstream FIFO and RISC enable */
+
+	if (debug)
+		cx88_sram_channel_dump(chip->core, &cx88_sram_channels[SRAM_CH25]);
+
+	return 0;
+}
+
+/*
+ * BOARD Specific: Resets audio DMA
+ */
+int _cx88_stop_audio_dma(snd_cx88_card_t *chip)
+{
+	struct cx88_core *core=chip->core;
+	dprintk(1, "Stopping audio DMA\n");
+
+	/* stop dma */
+	cx_clear(MO_AUD_DMACNTRL, 0x11);
+
+	/* disable irqs */
+	cx_clear(MO_PCI_INTMSK, 0x02);
+	cx_clear(MO_AUD_INTMSK,
+			(1<<16)|
+			(1<<12)|
+			(1<<4)|
+			(1<<0)
+			);
+
+	if (debug)
+		cx88_sram_channel_dump(chip->core, &cx88_sram_channels[SRAM_CH25]);
+
+	return 0;
+}
+
+#define MAX_IRQ_LOOP 10
+
+/*
+ * BOARD Specific: IRQ dma bits
+ */
+static char *cx88_aud_irqs[32] = {
+	"dn_risci1", "up_risci1", "rds_dn_risc1", /* 0-2 */
+	NULL,					  /* reserved */
+	"dn_risci2", "up_risci2", "rds_dn_risc2", /* 4-6 */
+	NULL,					  /* reserved */
+	"dnf_of", "upf_uf", "rds_dnf_uf",	  /* 8-10 */
+	NULL,					  /* reserved */
+	"dn_sync", "up_sync", "rds_dn_sync",	  /* 12-14 */
+	NULL,					  /* reserved */
+	"opc_err", "par_err", "rip_err",	  /* 16-18 */
+	"pci_abort", "ber_irq", "mchg_irq"	  /* 19-21 */
+};
+
+/*
+ * BOARD Specific: Threats IRQ audio specific calls
+ */
+static void cx8801_aud_irq(snd_cx88_card_t *chip)
+{
+	struct cx88_core *core = chip->core;
+	u32 status, mask;
+	u32 count;
+
+	status = cx_read(MO_AUD_INTSTAT);
+	mask   = cx_read(MO_AUD_INTMSK);
+	if (0 == (status & mask)) {
+		spin_unlock(&chip->reg_lock);
+		return;
+	}
+	cx_write(MO_AUD_INTSTAT, status);
+	if (debug > 1  ||  (status & mask & ~0xff))
+		cx88_print_irqbits(core->name, "irq aud",
+				   cx88_aud_irqs, status, mask);
+	/* risc op code error */
+	if (status & (1 << 16)) {
+		printk(KERN_WARNING "%s/0: audio risc op code error\n",core->name);
+		cx_clear(MO_AUD_DMACNTRL, 0x11);
+		cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH25]);
+	}
+
+	/* risc1 downstream */
+	if (status & 0x01) {
+		spin_lock(&chip->reg_lock);
+		count = cx_read(MO_AUDD_GPCNT);
+		spin_unlock(&chip->reg_lock);
+		if (chip->read_count == 0)
+			chip->read_count += chip->dma_size;
+	}
+
+	if  (chip->read_count >= chip->period_size) {
+		dprintk(2, "Elapsing period\n");
+		snd_pcm_period_elapsed(chip->substream);
+	}
+
+	dprintk(3,"Leaving audio IRQ handler...\n");
+
+	/* FIXME: Any other status should deserve a special handling? */
+}
+
+/*
+ * BOARD Specific: Handles IRQ calls
+ */
+static irqreturn_t cx8801_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	snd_cx88_card_t *chip = dev_id;
+	struct cx88_core *core = chip->core;
+	u32 status;
+	int loop, handled = 0;
+
+	for (loop = 0; loop < MAX_IRQ_LOOP; loop++) {
+		status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x02);
+		if (0 == status)
+			goto out;
+		dprintk( 3, "cx8801_irq\n" );
+		dprintk( 3, "    loop: %d/%d\n", loop, MAX_IRQ_LOOP );
+		dprintk( 3, "    status: %d\n", status );
+		handled = 1;
+		cx_write(MO_PCI_INTSTAT, status);
+
+		if (status & 0x02)
+		{
+			dprintk( 2, "    ALSA IRQ handling\n" );
+			cx8801_aud_irq(chip);
+		}
+	};
+
+	if (MAX_IRQ_LOOP == loop) {
+		dprintk( 0, "clearing mask\n" );
+		dprintk(1,"%s/0: irq loop -- clearing mask\n",
+		       core->name);
+		cx_clear(MO_PCI_INTMSK,0x02);
+	}
+
+ out:
+	return IRQ_RETVAL(handled);
+}
+
+
+static int dsp_buffer_free(snd_cx88_card_t *chip)
+{
+	BUG_ON(!chip->dma_size);
+
+	dprintk(2,"Freeing buffer\n");
+	videobuf_dma_pci_unmap(chip->pci, &chip->dma_risc);
+	videobuf_dma_free(&chip->dma_risc);
+	btcx_riscmem_free(chip->pci,&chip->buf->risc);
+	kfree(chip->buf);
+
+	chip->dma_size = 0;
+
+       return 0;
+}
+
+/****************************************************************************
+				ALSA PCM Interface
+ ****************************************************************************/
+
+/*
+ * Digital hardware definition
+ */
+static snd_pcm_hardware_t snd_cx88_digital_hw = {
+	.info = SNDRV_PCM_INFO_MMAP |
+		SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		SNDRV_PCM_INFO_MMAP_VALID,
+	.formats = SNDRV_PCM_FMTBIT_S16_LE,
+
+	.rates =		SNDRV_PCM_RATE_48000,
+	.rate_min =		48000,
+	.rate_max =		48000,
+	.channels_min = 1,
+	.channels_max = 2,
+	.buffer_bytes_max = (2*2048),
+	.period_bytes_min = 256,
+	.period_bytes_max = 2048,
+	.periods_min = 2,
+	.periods_max = 16,
+};
+
+/*
+ * audio pcm capture runtime free
+ */
+static void snd_card_cx88_runtime_free(snd_pcm_runtime_t *runtime)
+{
+}
+/*
+ * audio pcm capture open callback
+ */
+static int snd_cx88_pcm_open(snd_pcm_substream_t *substream)
+{
+	snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	int err;
+
+	if (test_and_set_bit(0, &chip->opened))
+		return -EBUSY;
+
+	err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+	if (err < 0)
+		goto _error;
+
+	chip->substream = substream;
+
+	chip->read_count = 0;
+	chip->read_offset = 0;
+
+	runtime->private_free = snd_card_cx88_runtime_free;
+	runtime->hw = snd_cx88_digital_hw;
+
+	return 0;
+_error:
+	dprintk(1,"Error opening PCM!\n");
+	clear_bit(0, &chip->opened);
+	smp_mb__after_clear_bit();
+	return err;
+}
+
+/*
+ * audio close callback
+ */
+static int snd_cx88_close(snd_pcm_substream_t *substream)
+{
+	snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
+
+	clear_bit(0, &chip->opened);
+	smp_mb__after_clear_bit();
+
+	return 0;
+}
+
+/*
+ * hw_params callback
+ */
+static int snd_cx88_hw_params(snd_pcm_substream_t * substream,
+				 snd_pcm_hw_params_t * hw_params)
+{
+	snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
+	struct cx88_buffer *buf;
+
+	if (substream->runtime->dma_area) {
+		dsp_buffer_free(chip);
+		substream->runtime->dma_area = NULL;
+	}
+
+
+	chip->period_size = params_period_bytes(hw_params);
+	chip->num_periods = params_periods(hw_params);
+	chip->dma_size = chip->period_size * params_periods(hw_params);
+
+	BUG_ON(!chip->dma_size);
+
+	dprintk(1,"Setting buffer\n");
+
+	buf = kmalloc(sizeof(*buf),GFP_KERNEL);
+	if (NULL == buf)
+		return -ENOMEM;
+	memset(buf,0,sizeof(*buf));
+
+
+	buf->vb.memory = V4L2_MEMORY_MMAP;
+	buf->vb.width  = chip->period_size;
+	buf->vb.height = chip->num_periods;
+	buf->vb.size   = chip->dma_size;
+	buf->vb.field  = V4L2_FIELD_NONE;
+
+	videobuf_dma_init(&buf->vb.dma);
+	videobuf_dma_init_kernel(&buf->vb.dma,PCI_DMA_FROMDEVICE,
+			(PAGE_ALIGN(buf->vb.size) >> PAGE_SHIFT));
+
+	videobuf_dma_pci_map(chip->pci,&buf->vb.dma);
+
+
+	cx88_risc_databuffer(chip->pci, &buf->risc,
+			buf->vb.dma.sglist,
+			buf->vb.width, buf->vb.height);
+
+	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+	buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+
+	buf->vb.state = STATE_PREPARED;
+
+	buf->bpl = chip->period_size;
+	chip->buf = buf;
+	chip->dma_risc = buf->vb.dma;
+
+	dprintk(1,"Buffer ready at %u\n",chip->dma_risc.nr_pages);
+	substream->runtime->dma_area = chip->dma_risc.vmalloc;
+	return 0;
+}
+
+/*
+ * hw free callback
+ */
+static int snd_cx88_hw_free(snd_pcm_substream_t * substream)
+{
+
+	snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
+
+	if (substream->runtime->dma_area) {
+		dsp_buffer_free(chip);
+		substream->runtime->dma_area = NULL;
+	}
+
+	return 0;
+}
+
+/*
+ * prepare callback
+ */
+static int snd_cx88_prepare(snd_pcm_substream_t *substream)
+{
+	return 0;
+}
+
+
+/*
+ * trigger callback
+ */
+static int snd_cx88_card_trigger(snd_pcm_substream_t *substream, int cmd)
+{
+	snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
+	int err;
+
+	spin_lock(&chip->reg_lock);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		err=_cx88_start_audio_dma(chip);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		err=_cx88_stop_audio_dma(chip);
+		break;
+	default:
+		err=-EINVAL;
+		break;
+	}
+
+	spin_unlock(&chip->reg_lock);
+
+	return err;
+}
+
+/*
+ * pointer callback
+ */
+static snd_pcm_uframes_t snd_cx88_pointer(snd_pcm_substream_t *substream)
+{
+	snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+
+	if (chip->read_count) {
+		chip->read_count -= snd_pcm_lib_period_bytes(substream);
+		chip->read_offset += snd_pcm_lib_period_bytes(substream);
+		if (chip->read_offset == chip->dma_size)
+			chip->read_offset = 0;
+	}
+
+	dprintk(2, "Pointer time, will return %li, read %li\n",chip->read_offset,chip->read_count);
+	return bytes_to_frames(runtime, chip->read_offset);
+
+}
+
+/*
+ * operators
+ */
+static snd_pcm_ops_t snd_cx88_pcm_ops = {
+	.open = snd_cx88_pcm_open,
+	.close = snd_cx88_close,
+	.ioctl = snd_pcm_lib_ioctl,
+	.hw_params = snd_cx88_hw_params,
+	.hw_free = snd_cx88_hw_free,
+	.prepare = snd_cx88_prepare,
+	.trigger = snd_cx88_card_trigger,
+	.pointer = snd_cx88_pointer,
+};
+
+/*
+ * create a PCM device
+ */
+static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name)
+{
+	int err;
+	snd_pcm_t *pcm;
+
+	err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
+	if (err < 0)
+		return err;
+	pcm->private_data = chip;
+	strcpy(pcm->name, name);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx88_pcm_ops);
+
+	return 0;
+}
+
+/****************************************************************************
+				CONTROL INTERFACE
+ ****************************************************************************/
+static int snd_cx88_capture_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
+{
+	info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	info->count = 1;
+	info->value.integer.min = 0;
+	info->value.integer.max = 0x3f;
+
+	return 0;
+}
+
+/* OK - TODO: test it */
+static int snd_cx88_capture_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
+{
+	snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
+	struct cx88_core *core=chip->core;
+
+	value->value.integer.value[0] = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f);
+
+	return 0;
+}
+
+/* OK - TODO: test it */
+static int snd_cx88_capture_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
+{
+	snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
+	struct cx88_core *core=chip->core;
+	int v;
+	u32 old_control;
+
+	spin_lock_irq(&chip->reg_lock);
+	old_control = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f);
+	v = 0x3f - (value->value.integer.value[0] & 0x3f);
+	cx_andor(AUD_VOL_CTL, 0x3f, v);
+	spin_unlock_irq(&chip->reg_lock);
+
+	return v != old_control;
+}
+
+static snd_kcontrol_new_t snd_cx88_capture_volume = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Capture Volume",
+	.info = snd_cx88_capture_volume_info,
+	.get = snd_cx88_capture_volume_get,
+	.put = snd_cx88_capture_volume_put,
+};
+
+
+/****************************************************************************
+			Basic Flow for Sound Devices
+ ****************************************************************************/
+
+/*
+ * PCI ID Table - 14f1:8801 and 14f1:8811 means function 1: Audio
+ * Only boards with eeprom and byte 1 at eeprom=1 have it
+ */
+
+struct pci_device_id cx88_audio_pci_tbl[] = {
+	{0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{0, }
+};
+MODULE_DEVICE_TABLE(pci, cx88_audio_pci_tbl);
+
+/*
+ * Chip-specific destructor
+ */
+
+static int snd_cx88_free(snd_cx88_card_t *chip)
+{
+
+	if (chip->irq >= 0){
+		synchronize_irq(chip->irq);
+		free_irq(chip->irq, chip);
+	}
+
+	cx88_core_put(chip->core,chip->pci);
+
+	pci_disable_device(chip->pci);
+	return 0;
+}
+
+/*
+ * Component Destructor
+ */
+static void snd_cx88_dev_free(snd_card_t * card)
+{
+	snd_cx88_card_t *chip = card->private_data;
+
+	snd_cx88_free(chip);
+}
+
+
+/*
+ * Alsa Constructor - Component probe
+ */
+
+static int devno=0;
+static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci,
+				    snd_cx88_card_t **rchip)
+{
+	snd_cx88_card_t   *chip;
+	struct cx88_core  *core;
+	int               err;
+
+	*rchip = NULL;
+
+	err = pci_enable_device(pci);
+	if (err < 0)
+		return err;
+
+	pci_set_master(pci);
+
+	chip = (snd_cx88_card_t *) card->private_data;
+
+	core = cx88_core_get(pci);
+
+	if (!pci_dma_supported(pci,0xffffffff)) {
+		dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name);
+		err = -EIO;
+		cx88_core_put(core,pci);
+		return err;
+	}
+
+
+	/* pci init */
+	chip->card = card;
+	chip->pci = pci;
+	chip->irq = -1;
+	spin_lock_init(&chip->reg_lock);
+
+	cx88_reset(core);
+	if (NULL == core) {
+		err = -EINVAL;
+		kfree (chip);
+		return err;
+	}
+	chip->core = core;
+
+	/* get irq */
+	err = request_irq(chip->pci->irq, cx8801_irq,
+			  SA_SHIRQ | SA_INTERRUPT, chip->core->name, chip);
+	if (err < 0) {
+		dprintk(0, "%s: can't get IRQ %d\n",
+		       chip->core->name, chip->pci->irq);
+		return err;
+	}
+
+	/* print pci info */
+	pci_read_config_byte(pci, PCI_CLASS_REVISION, &chip->pci_rev);
+	pci_read_config_byte(pci, PCI_LATENCY_TIMER,  &chip->pci_lat);
+
+	dprintk(1,"ALSA %s/%i: found at %s, rev: %d, irq: %d, "
+	       "latency: %d, mmio: 0x%lx\n", core->name, devno,
+	       pci_name(pci), chip->pci_rev, pci->irq,
+	       chip->pci_lat,pci_resource_start(pci,0));
+
+	chip->irq = pci->irq;
+	synchronize_irq(chip->irq);
+
+	snd_card_set_dev(card, &pci->dev);
+
+	*rchip = chip;
+
+	return 0;
+}
+
+static int __devinit cx88_audio_initdev(struct pci_dev *pci,
+				    const struct pci_device_id *pci_id)
+{
+	snd_card_t       *card;
+	snd_cx88_card_t  *chip;
+	int              err;
+
+	if (devno >= SNDRV_CARDS)
+		return (-ENODEV);
+
+	if (!enable[devno]) {
+		++devno;
+		return (-ENOENT);
+	}
+
+	card = snd_card_new(index[devno], id[devno], THIS_MODULE, sizeof(snd_cx88_card_t));
+	if (!card)
+		return (-ENOMEM);
+
+	card->private_free = snd_cx88_dev_free;
+
+	err = snd_cx88_create(card, pci, &chip);
+	if (err < 0)
+		return (err);
+
+	err = snd_cx88_pcm(chip, 0, "CX88 Digital");
+
+	if (err < 0) {
+		snd_card_free(card);
+		return (err);
+	}
+
+	err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_capture_volume, chip));
+	if (err < 0) {
+		snd_card_free(card);
+		return (err);
+	}
+
+	strcpy (card->driver, "CX88x");
+	sprintf(card->shortname, "Conexant CX%x", pci->device);
+	sprintf(card->longname, "%s at %#lx",
+		card->shortname, pci_resource_start(pci, 0));
+	strcpy (card->mixername, "CX88");
+
+	dprintk (0, "%s/%i: ALSA support for cx2388x boards\n",
+	       card->driver,devno);
+
+	err = snd_card_register(card);
+	if (err < 0) {
+		snd_card_free(card);
+		return (err);
+	}
+	snd_cx88_cards[devno] = card;
+
+	pci_set_drvdata(pci,card);
+
+	devno++;
+	return 0;
+}
+/*
+ * ALSA destructor
+ */
+static void __devexit cx88_audio_finidev(struct pci_dev *pci)
+{
+	struct cx88_audio_dev *card = pci_get_drvdata(pci);
+
+	snd_card_free((void *)card);
+
+	pci_set_drvdata(pci, NULL);
+
+	devno--;
+}
+
+/*
+ * PCI driver definition
+ */
+
+static struct pci_driver cx88_audio_pci_driver = {
+	.name     = "cx88_audio",
+	.id_table = cx88_audio_pci_tbl,
+	.probe    = cx88_audio_initdev,
+	.remove   = cx88_audio_finidev,
+	SND_PCI_PM_CALLBACKS
+};
+
+/****************************************************************************
+				LINUX MODULE INIT
+ ****************************************************************************/
+
+/*
+ * module init
+ */
+static int cx88_audio_init(void)
+{
+	printk(KERN_INFO "cx2388x alsa driver version %d.%d.%d loaded\n",
+	       (CX88_VERSION_CODE >> 16) & 0xff,
+	       (CX88_VERSION_CODE >>  8) & 0xff,
+	       CX88_VERSION_CODE & 0xff);
+#ifdef SNAPSHOT
+	printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
+	       SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
+#endif
+	return pci_register_driver(&cx88_audio_pci_driver);
+}
+
+/*
+ * module remove
+ */
+static void cx88_audio_fini(void)
+{
+
+	pci_unregister_driver(&cx88_audio_pci_driver);
+}
+
+module_init(cx88_audio_init);
+module_exit(cx88_audio_fini);
+
+/* ----------------------------------------------------------- */
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 74e57a5..a490621 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -32,10 +32,10 @@
 #include <linux/firmware.h>
 
 #include "cx88.h"
+#include <media/v4l2-common.h>
 
 MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards");
-MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>");
-MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
+MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>, Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
 MODULE_LICENSE("GPL");
 
 static unsigned int mpegbufs = 32;
@@ -1375,7 +1375,7 @@
 	struct cx88_core  *core = dev->core;
 
 	if (debug > 1)
-		cx88_print_ioctl(core->name,cmd);
+		v4l_print_ioctl(core->name,cmd);
 
 	switch (cmd) {
 
@@ -1689,6 +1689,18 @@
 	memcpy(&dev->params,&default_mpeg_params,sizeof(default_mpeg_params));
 	memcpy(&dev->dnr_params,&default_dnr_params,sizeof(default_dnr_params));
 
+	if (core->board == CX88_BOARD_HAUPPAUGE_ROSLYN) {
+
+		if (core->tuner_formats & V4L2_STD_525_60) {
+			dev->height = 480;
+			dev->params.vi_frame_rate = 30;
+		} else {
+			dev->height = 576;
+			dev->params.vi_frame_rate = 25;
+		}
+
+	}
+
 	err = cx8802_init_common(dev);
 	if (0 != err)
 		goto fail_free;
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 951709a..a76d545 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -611,12 +611,12 @@
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
-			.gpio0  = 0xed12,  /* internal decoder */
+			.gpio0  = 0xed1a,
 			.gpio2  = 0x00ff,
 		},{
 			.type   = CX88_VMUX_DEBUG,
 			.vmux   = 0,
-			.gpio0  = 0xff01,  /* mono from tuner chip */
+			.gpio0  = 0xff01,
 		},{
 			.type   = CX88_VMUX_COMPOSITE1,
 			.vmux   = 1,
@@ -708,7 +708,7 @@
 	},
 	[CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = {
 		.name           = "DViCO FusionHDTV 3 Gold-T",
-		.tuner_type     = TUNER_THOMSON_DTT7611,
+		.tuner_type     = TUNER_THOMSON_DTT761X,
 		.radio_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
@@ -897,6 +897,158 @@
 			.gpio3  = 0x0000,
 		}},
 	},
+	[CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1] = {
+		.name		= "Hauppauge Nova-S-Plus DVB-S",
+		.tuner_type	= TUNER_ABSENT,
+		.radio_type	= UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.input		= {{
+			.type	= CX88_VMUX_DVB,
+			.vmux	= 0,
+		},{
+			.type	= CX88_VMUX_COMPOSITE1,
+			.vmux	= 1,
+		},{
+			.type	= CX88_VMUX_SVIDEO,
+			.vmux	= 2,
+		}},
+		.dvb		= 1,
+	},
+	[CX88_BOARD_HAUPPAUGE_NOVASE2_S1] = {
+		.name		= "Hauppauge Nova-SE2 DVB-S",
+		.tuner_type	= TUNER_ABSENT,
+		.radio_type	= UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.input		= {{
+			.type	= CX88_VMUX_DVB,
+			.vmux	= 0,
+		}},
+		.dvb		= 1,
+	},
+	[CX88_BOARD_KWORLD_DVBS_100] = {
+		.name		= "KWorld DVB-S 100",
+		.tuner_type	= TUNER_ABSENT,
+		.radio_type	= UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.input		= {{
+			.type	= CX88_VMUX_DVB,
+			.vmux	= 0,
+		},{
+			.type	= CX88_VMUX_COMPOSITE1,
+			.vmux	= 1,
+		},{
+			.type	= CX88_VMUX_SVIDEO,
+			.vmux	= 2,
+		}},
+		.dvb		= 1,
+	},
+	[CX88_BOARD_HAUPPAUGE_HVR1100] = {
+		.name		= "Hauppauge WinTV-HVR1100 DVB-T/Hybrid",
+		.tuner_type     = TUNER_PHILIPS_FMD1216ME_MK3,
+		.radio_type	= UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.input		= {{
+			.type   = CX88_VMUX_TELEVISION,
+			.vmux   = 0,
+		},{
+			.type	= CX88_VMUX_COMPOSITE1,
+			.vmux	= 1,
+		},{
+			.type	= CX88_VMUX_SVIDEO,
+			.vmux	= 2,
+		}},
+		/* fixme: Add radio support */
+		.dvb		= 1,
+	},
+	[CX88_BOARD_HAUPPAUGE_HVR1100LP] = {
+		.name		= "Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile)",
+		.tuner_type     = TUNER_PHILIPS_FMD1216ME_MK3,
+		.radio_type	= UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.input		= {{
+			.type   = CX88_VMUX_TELEVISION,
+			.vmux   = 0,
+		},{
+			.type	= CX88_VMUX_COMPOSITE1,
+			.vmux	= 1,
+		}},
+		/* fixme: Add radio support */
+		.dvb		= 1,
+	},
+	[CX88_BOARD_DNTV_LIVE_DVB_T_PRO] = {
+		.name           = "digitalnow DNTV Live! DVB-T Pro",
+		.tuner_type     = TUNER_PHILIPS_FMD1216ME_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE |
+				  TDA9887_PORT2_ACTIVE,
+		.input          = {{
+			.type   = CX88_VMUX_TELEVISION,
+			.vmux   = 0,
+			.gpio0  = 0xf80808,
+		},{
+			.type   = CX88_VMUX_COMPOSITE1,
+			.vmux   = 1,
+			.gpio0	= 0xf80808,
+		},{
+			.type   = CX88_VMUX_SVIDEO,
+			.vmux   = 2,
+			.gpio0	= 0xf80808,
+		}},
+		.radio = {
+			 .type  = CX88_RADIO,
+			 .gpio0 = 0xf80808,
+		},
+		.dvb            = 1,
+	},
+	[CX88_BOARD_KWORLD_DVB_T_CX22702] = {
+		/* Kworld V-stream Xpert DVB-T with Thomson tuner */
+		/* DTT 7579 Conexant CX22702-19 Conexant CX2388x  */
+		/* Manenti Marco <marco_manenti@colman.it> */
+		.name           = "KWorld/VStream XPert DVB-T with cx22702",
+		.tuner_type     = TUNER_ABSENT,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.input          = {{
+			.type   = CX88_VMUX_COMPOSITE1,
+			.vmux   = 1,
+			.gpio0  = 0x0700,
+			.gpio2  = 0x0101,
+		},{
+			.type   = CX88_VMUX_SVIDEO,
+			.vmux   = 2,
+			.gpio0  = 0x0700,
+			.gpio2  = 0x0101,
+		}},
+		.dvb            = 1,
+	},
+	[CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL] = {
+		.name           = "DViCO FusionHDTV DVB-T Dual Digital",
+		.tuner_type     = TUNER_ABSENT, /* No analog tuner */
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.input          = {{
+			.type   = CX88_VMUX_COMPOSITE1,
+			.vmux   = 1,
+			.gpio0  = 0x000027df,
+		 },{
+			.type   = CX88_VMUX_SVIDEO,
+			.vmux   = 2,
+			.gpio0  = 0x000027df,
+		}},
+		.dvb            = 1,
+	},
+
 };
 const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
 
@@ -1044,6 +1196,54 @@
 		.subvendor = 0x1461,
 		.subdevice = 0x000a,
 		.card      = CX88_BOARD_AVERTV_303,
+	},{
+		.subvendor = 0x0070,
+		.subdevice = 0x9200,
+		.card      = CX88_BOARD_HAUPPAUGE_NOVASE2_S1,
+	},{
+		.subvendor = 0x0070,
+		.subdevice = 0x9201,
+		.card      = CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1,
+	},{
+		.subvendor = 0x0070,
+		.subdevice = 0x9202,
+		.card      = CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1,
+	},{
+		.subvendor = 0x17de,
+		.subdevice = 0x08b2,
+		.card      = CX88_BOARD_KWORLD_DVBS_100,
+	},{
+		.subvendor = 0x0070,
+		.subdevice = 0x9400,
+		.card      = CX88_BOARD_HAUPPAUGE_HVR1100,
+	},{
+		.subvendor = 0x0070,
+		.subdevice = 0x9402,
+		.card      = CX88_BOARD_HAUPPAUGE_HVR1100,
+	},{
+		.subvendor = 0x0070,
+		.subdevice = 0x9800,
+		.card      = CX88_BOARD_HAUPPAUGE_HVR1100LP,
+	},{
+		.subvendor = 0x0070,
+		.subdevice = 0x9802,
+		.card      = CX88_BOARD_HAUPPAUGE_HVR1100LP,
+	},{
+		.subvendor = 0x0070,
+		.subdevice = 0x9001,
+		.card      = CX88_BOARD_HAUPPAUGE_DVB_T1,
+	},{
+		.subvendor = 0x1822,
+		.subdevice = 0x0025,
+		.card      = CX88_BOARD_DNTV_LIVE_DVB_T_PRO,
+	},{
+		.subvendor = 0x17de,
+		.subdevice = 0x08a1,
+		.card      = CX88_BOARD_KWORLD_DVB_T_CX22702,
+	},{
+		.subvendor = 0x18ac,
+		.subdevice = 0xdb50,
+		.card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL,
 	},
 };
 const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
@@ -1075,20 +1275,19 @@
 	       core->name, core->tuner_type, eeprom_data[0]);
 }
 
-
-/* ----------------------------------------------------------------------- */
-
 static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
 {
 	struct tveeprom tv;
 
 	tveeprom_hauppauge_analog(&core->i2c_client, &tv, eeprom_data);
 	core->tuner_type = tv.tuner_type;
+	core->tuner_formats = tv.tuner_formats;
 	core->has_radio  = tv.has_radio;
 
 	/* Make sure we support the board model */
 	switch (tv.model)
 	{
+	case 28552: /* WinTV-PVR 'Roslyn' (No IR) */
 	case 90002: /* Nova-T-PCI (9002) */
 	case 92001: /* Nova-S-Plus (Video and IR) */
 	case 92002: /* Nova-S-Plus (Video and IR) */
@@ -1096,7 +1295,9 @@
 	case 90500: /* Nova-T-PCI (oem) */
 	case 90501: /* Nova-T-PCI (oem/IR) */
 	case 92000: /* Nova-SE2 (OEM, No Video or IR) */
-
+	case 94009: /* WinTV-HVR1100 (Video and IR Retail) */
+	case 94501: /* WinTV-HVR1100 (Video and IR OEM) */
+	case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */
 		/* known */
 		break;
 	default:
@@ -1211,12 +1412,21 @@
 		if (0 == core->i2c_rc)
 			leadtek_eeprom(core,eeprom);
 		break;
+	case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
+	case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
 	case CX88_BOARD_HAUPPAUGE_DVB_T1:
+	case CX88_BOARD_HAUPPAUGE_HVR1100:
+	case CX88_BOARD_HAUPPAUGE_HVR1100LP:
 		if (0 == core->i2c_rc)
 			hauppauge_eeprom(core,eeprom);
 		break;
+	case CX88_BOARD_KWORLD_DVBS_100:
+		cx_write(MO_GP0_IO, 0x000007f8);
+		cx_write(MO_GP1_IO, 0x00000001);
+		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
+	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
 		/* GPIO0:0 is hooked to mt352 reset pin */
 		cx_set(MO_GP0_IO, 0x00000101);
 		cx_clear(MO_GP0_IO, 0x00000001);
@@ -1232,6 +1442,9 @@
 		cx_clear(MO_GP0_IO, 0x00000007);
 		cx_set(MO_GP2_IO, 0x00000101);
 		break;
+	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
+		cx_write(MO_GP0_IO, 0x00080808);
+		break;
 	case CX88_BOARD_ATI_HDTVWONDER:
 		if (0 == core->i2c_rc) {
 			/* enable tuner */
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index bb6eb54..9975be1 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -34,6 +34,7 @@
 #include <linux/videodev2.h>
 
 #include "cx88.h"
+#include <media/v4l2-common.h>
 
 MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
@@ -76,60 +77,6 @@
 static LIST_HEAD(cx88_devlist);
 static DECLARE_MUTEX(devlist);
 
-/* ------------------------------------------------------------------ */
-/* debug help functions                                               */
-
-static const char *v4l1_ioctls[] = {
-	"0", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
-	"CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
-	"SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
-	"GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
-	"SMICROCODE", "GVBIFMT", "SVBIFMT" };
-#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
-
-static const char *v4l2_ioctls[] = {
-	"QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
-	"G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF",
-	"G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON",
-	"STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD",
-	"ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER",
-	"G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL",
-	"QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43",
-	"44", "45",  "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT",
-	"S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
-	"S_MODULATOR"
-};
-#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
-
-void cx88_print_ioctl(char *name, unsigned int cmd)
-{
-	char *dir;
-
-	switch (_IOC_DIR(cmd)) {
-	case _IOC_NONE:              dir = "--"; break;
-	case _IOC_READ:              dir = "r-"; break;
-	case _IOC_WRITE:             dir = "-w"; break;
-	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
-	default:                     dir = "??"; break;
-	}
-	switch (_IOC_TYPE(cmd)) {
-	case 'v':
-		printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n",
-		       name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
-		       v4l1_ioctls[_IOC_NR(cmd)] : "???");
-		break;
-	case 'V':
-		printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n",
-		       name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
-		       v4l2_ioctls[_IOC_NR(cmd)] : "???");
-		break;
-	default:
-		printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
-		       name, cmd, dir, _IOC_NR(cmd));
-	}
-}
-
-/* ------------------------------------------------------------------ */
 #define NO_SYNC_LINE (-1U)
 
 static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist,
@@ -291,9 +238,9 @@
  *    channel  22    (u video)  -  2.0k
  *    channel  23    (v video)  -  2.0k
  *    channel  24    (vbi)      -  4.0k
- *    channels 25+26 (audio)    -  0.5k
+ *    channels 25+26 (audio)    -  4.0k
  *    channel  28    (mpeg)     -  4.0k
- *    TOTAL                     = 25.5k
+ *    TOTAL                     = 29.0k
  *
  * Every channel has 160 bytes control data (64 bytes instruction
  * queue and 6 CDT entries), which is close to 2k total.
@@ -359,7 +306,7 @@
 		.ctrl_start = 0x180680,
 		.cdt        = 0x180680 + 64,
 		.fifo_start = 0x185400,
-		.fifo_size  = 0x000200,
+		.fifo_size  = 0x001000,
 		.ptr1_reg   = MO_DMA25_PTR1,
 		.ptr2_reg   = MO_DMA25_PTR2,
 		.cnt1_reg   = MO_DMA25_CNT1,
@@ -371,7 +318,7 @@
 		.ctrl_start = 0x180720,
 		.cdt        = 0x180680 + 64,  /* same as audio IN */
 		.fifo_start = 0x185400,       /* same as audio IN */
-		.fifo_size  = 0x000200,       /* same as audio IN */
+		.fifo_size  = 0x001000,       /* same as audio IN */
 		.ptr1_reg   = MO_DMA26_PTR1,
 		.ptr2_reg   = MO_DMA26_PTR2,
 		.cnt1_reg   = MO_DMA26_CNT1,
@@ -382,7 +329,7 @@
 		.cmds_start = 0x180200,
 		.ctrl_start = 0x1807C0,
 		.cdt        = 0x1807C0 + 64,
-		.fifo_start = 0x185600,
+		.fifo_start = 0x186400,
 		.fifo_size  = 0x001000,
 		.ptr1_reg   = MO_DMA28_PTR1,
 		.ptr2_reg   = MO_DMA28_PTR2,
@@ -848,7 +795,6 @@
 
 	/* start dma */
 	cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */
-
 	return 0;
 }
 
@@ -1208,7 +1154,6 @@
 
 /* ------------------------------------------------------------------ */
 
-EXPORT_SYMBOL(cx88_print_ioctl);
 EXPORT_SYMBOL(cx88_print_irqbits);
 
 EXPORT_SYMBOL(cx88_core_irq);
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 99ea955..42c012a 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -3,7 +3,7 @@
  * device driver for Conexant 2388x based TV cards
  * MPEG Transport Stream (DVB) routines
  *
- * (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au>
+ * (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
  * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -31,10 +31,14 @@
 
 #include "cx88.h"
 #include "dvb-pll.h"
+#include <media/v4l2-common.h>
 
 #ifdef HAVE_MT352
 # include "mt352.h"
 # include "mt352_priv.h"
+# ifdef HAVE_VP3054_I2C
+#  include "cx88-vp3054-i2c.h"
+# endif
 #endif
 #ifdef HAVE_CX22702
 # include "cx22702.h"
@@ -48,6 +52,9 @@
 #ifdef HAVE_NXT200X
 # include "nxt200x.h"
 #endif
+#ifdef HAVE_CX24123
+# include "cx24123.h"
+#endif
 
 MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
 MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -125,6 +132,27 @@
 	return 0;
 }
 
+static int dvico_dual_demod_init(struct dvb_frontend *fe)
+{
+	static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x38 };
+	static u8 reset []         = { RESET,      0x80 };
+	static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
+	static u8 agc_cfg []       = { AGC_TARGET, 0x28, 0x20 };
+	static u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
+	static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
+
+	mt352_write(fe, clock_config,   sizeof(clock_config));
+	udelay(200);
+	mt352_write(fe, reset,          sizeof(reset));
+	mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
+
+	mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
+	mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
+	mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
+
+	return 0;
+}
+
 static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
 {
 	static u8 clock_config []  = { 0x89, 0x38, 0x39 };
@@ -172,6 +200,98 @@
 	.demod_init    = dntv_live_dvbt_demod_init,
 	.pll_set       = mt352_pll_set,
 };
+
+static struct mt352_config dvico_fusionhdtv_dual = {
+	.demod_address = 0x0F,
+	.demod_init    = dvico_dual_demod_init,
+	.pll_set       = mt352_pll_set,
+};
+
+#ifdef HAVE_VP3054_I2C
+static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
+{
+	static u8 clock_config []  = { 0x89, 0x38, 0x38 };
+	static u8 reset []         = { 0x50, 0x80 };
+	static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
+	static u8 agc_cfg []       = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF,
+				       0x00, 0xFF, 0x00, 0x40, 0x40 };
+	static u8 dntv_extra[]     = { 0xB5, 0x7A };
+	static u8 capt_range_cfg[] = { 0x75, 0x32 };
+
+	mt352_write(fe, clock_config,   sizeof(clock_config));
+	udelay(2000);
+	mt352_write(fe, reset,          sizeof(reset));
+	mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
+
+	mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
+	udelay(2000);
+	mt352_write(fe, dntv_extra,     sizeof(dntv_extra));
+	mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
+
+	return 0;
+}
+
+static int philips_fmd1216_pll_init(struct dvb_frontend *fe)
+{
+	struct cx8802_dev *dev= fe->dvb->priv;
+
+	/* this message is to set up ATC and ALC */
+	static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 };
+	struct i2c_msg msg =
+		{ .addr = dev->core->pll_addr, .flags = 0,
+		  .buf = fmd1216_init, .len = sizeof(fmd1216_init) };
+	int err;
+
+	if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
+		if (err < 0)
+			return err;
+		else
+			return -EREMOTEIO;
+	}
+
+	return 0;
+}
+
+static int dntv_live_dvbt_pro_pll_set(struct dvb_frontend* fe,
+				      struct dvb_frontend_parameters* params,
+				      u8* pllbuf)
+{
+	struct cx8802_dev *dev= fe->dvb->priv;
+	struct i2c_msg msg =
+		{ .addr = dev->core->pll_addr, .flags = 0,
+		  .buf = pllbuf+1, .len = 4 };
+	int err;
+
+	/* Switch PLL to DVB mode */
+	err = philips_fmd1216_pll_init(fe);
+	if (err)
+		return err;
+
+	/* Tune PLL */
+	pllbuf[0] = dev->core->pll_addr << 1;
+	dvb_pll_configure(dev->core->pll_desc, pllbuf+1,
+			  params->frequency,
+			  params->u.ofdm.bandwidth);
+	if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
+		printk(KERN_WARNING "cx88-dvb: %s error "
+			   "(addr %02x <- %02x, err = %i)\n",
+			   __FUNCTION__, pllbuf[0], pllbuf[1], err);
+		if (err < 0)
+			return err;
+		else
+			return -EREMOTEIO;
+	}
+
+	return 0;
+}
+
+static struct mt352_config dntv_live_dvbt_pro_config = {
+	.demod_address = 0x0f,
+	.no_tuner      = 1,
+	.demod_init    = dntv_live_dvbt_pro_demod_init,
+	.pll_set       = dntv_live_dvbt_pro_pll_set,
+};
+#endif
 #endif
 
 #ifdef HAVE_CX22702
@@ -188,6 +308,12 @@
 	.pll_address   = 0x61,
 	.pll_desc      = &dvb_pll_thomson_dtt759x,
 };
+static struct cx22702_config hauppauge_hvr1100_config = {
+	.demod_address = 0x63,
+	.output_mode   = CX22702_SERIAL_OUTPUT,
+	.pll_address   = 0x61,
+	.pll_desc      = &dvb_pll_fmd1216me,
+};
 #endif
 
 #ifdef HAVE_OR51132
@@ -314,6 +440,40 @@
 };
 #endif
 
+#ifdef HAVE_CX24123
+static int cx24123_set_ts_param(struct dvb_frontend* fe,
+	int is_punctured)
+{
+	struct cx8802_dev *dev= fe->dvb->priv;
+	dev->ts_gen_cntrl = 0x2;
+	return 0;
+}
+
+static void cx24123_enable_lnb_voltage(struct dvb_frontend* fe, int on)
+{
+	struct cx8802_dev *dev= fe->dvb->priv;
+	struct cx88_core *core = dev->core;
+
+	if (on)
+		cx_write(MO_GP0_IO, 0x000006f9);
+	else
+		cx_write(MO_GP0_IO, 0x000006fB);
+}
+
+static struct cx24123_config hauppauge_novas_config = {
+	.demod_address		= 0x55,
+	.use_isl6421		= 1,
+	.set_ts_params		= cx24123_set_ts_param,
+};
+
+static struct cx24123_config kworld_dvbs_100_config = {
+	.demod_address		= 0x15,
+	.use_isl6421		= 0,
+	.set_ts_params		= cx24123_set_ts_param,
+	.enable_lnb_voltage	= cx24123_enable_lnb_voltage,
+};
+#endif
+
 static int dvb_register(struct cx8802_dev *dev)
 {
 	/* init struct videobuf_dvb */
@@ -329,10 +489,16 @@
 		break;
 	case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
 	case CX88_BOARD_CONEXANT_DVB_T1:
+	case CX88_BOARD_KWORLD_DVB_T_CX22702:
 	case CX88_BOARD_WINFAST_DTV1000:
 		dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
 						   &dev->core->i2c_adap);
 		break;
+	case CX88_BOARD_HAUPPAUGE_HVR1100:
+	case CX88_BOARD_HAUPPAUGE_HVR1100LP:
+		dev->dvb.frontend = cx22702_attach(&hauppauge_hvr1100_config,
+						   &dev->core->i2c_adap);
+		break;
 #endif
 #ifdef HAVE_MT352
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
@@ -355,6 +521,24 @@
 		dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config,
 						 &dev->core->i2c_adap);
 		break;
+	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
+#ifdef HAVE_VP3054_I2C
+		dev->core->pll_addr = 0x61;
+		dev->core->pll_desc = &dvb_pll_fmd1216me;
+		dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_pro_config,
+			&((struct vp3054_i2c_state *)dev->card_priv)->adap);
+#else
+		printk("%s: built without vp3054 support\n", dev->core->name);
+#endif
+		break;
+	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
+		/* The tin box says DEE1601, but it seems to be DTT7579
+		 * compatible, with a slightly different MT352 AGC gain. */
+		dev->core->pll_addr = 0x61;
+		dev->core->pll_desc = &dvb_pll_thomson_dtt7579;
+		dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dual,
+						 &dev->core->i2c_adap);
+		break;
 #endif
 #ifdef HAVE_OR51132
 	case CX88_BOARD_PCHDTV_HD3000:
@@ -393,7 +577,7 @@
 		cx_set(MO_GP0_IO, 9);
 		mdelay(200);
 		dev->core->pll_addr = 0x61;
-		dev->core->pll_desc = &dvb_pll_thomson_dtt7611;
+		dev->core->pll_desc = &dvb_pll_thomson_dtt761x;
 		dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold,
 						    &dev->core->i2c_adap);
 		}
@@ -421,6 +605,17 @@
 						 &dev->core->i2c_adap);
 		break;
 #endif
+#ifdef HAVE_CX24123
+	case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
+	case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
+		dev->dvb.frontend = cx24123_attach(&hauppauge_novas_config,
+			&dev->core->i2c_adap);
+		break;
+	case CX88_BOARD_KWORLD_DVBS_100:
+		dev->dvb.frontend = cx24123_attach(&kworld_dvbs_100_config,
+			&dev->core->i2c_adap);
+		break;
+#endif
 	default:
 		printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
 		       dev->core->name);
@@ -473,6 +668,12 @@
 	if (0 != err)
 		goto fail_free;
 
+#ifdef HAVE_VP3054_I2C
+	err = vp3054_i2c_probe(dev);
+	if (0 != err)
+		goto fail_free;
+#endif
+
 	/* dvb stuff */
 	printk("%s/2: cx2388x based dvb card\n", core->name);
 	videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops,
@@ -484,6 +685,9 @@
 	err = dvb_register(dev);
 	if (0 != err)
 		goto fail_fini;
+
+	/* Maintain a reference to cx88-video can query the 8802 device. */
+	core->dvbdev = dev;
 	return 0;
 
  fail_fini:
@@ -499,9 +703,16 @@
 {
 	struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
 
+	/* Destroy any 8802 reference. */
+	dev->core->dvbdev = NULL;
+
 	/* dvb */
 	videobuf_dvb_unregister(&dev->dvb);
 
+#ifdef HAVE_VP3054_I2C
+	vp3054_i2c_remove(dev);
+#endif
+
 	/* common */
 	cx8802_fini_common(dev);
 	cx88_core_put(dev->core,dev->pci);
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 4a8fb16..f720901 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -30,6 +30,7 @@
 #include <asm/io.h>
 
 #include "cx88.h"
+#include <media/v4l2-common.h>
 
 static unsigned int i2c_debug = 0;
 module_param(i2c_debug, int, 0644);
@@ -135,7 +136,17 @@
 {
 	if (0 != core->i2c_rc)
 		return;
-	i2c_clients_command(&core->i2c_adap, cmd, arg);
+
+	if (core->dvbdev) {
+		if (core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl)
+			core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1);
+
+		i2c_clients_command(&core->i2c_adap, cmd, arg);
+
+		if (core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl)
+			core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl(core->dvbdev->dvb.frontend, 0);
+	} else
+		i2c_clients_command(&core->i2c_adap, cmd, arg);
 }
 
 static struct i2c_algo_bit_data cx8800_i2c_algo_template = {
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 461019d..286c85b 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 2003 Pavel Machek
  * Copyright (c) 2004 Gerd Knorr
- * Copyright (c) 2004 Chris Pascoe
+ * Copyright (c) 2004, 2005 Chris Pascoe
  *
  * 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
@@ -29,9 +29,8 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 
-#include <media/ir-common.h>
-
 #include "cx88.h"
+#include <media/ir-common.h>
 
 /* ---------------------------------------------------------------------- */
 
@@ -258,6 +257,114 @@
 
 /* ---------------------------------------------------------------------- */
 
+/* AVERTV STUDIO 303 Remote */
+static IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE] = {
+	[ 0x2a ] = KEY_KP1,
+	[ 0x32 ] = KEY_KP2,
+	[ 0x3a ] = KEY_KP3,
+	[ 0x4a ] = KEY_KP4,
+	[ 0x52 ] = KEY_KP5,
+	[ 0x5a ] = KEY_KP6,
+	[ 0x6a ] = KEY_KP7,
+	[ 0x72 ] = KEY_KP8,
+	[ 0x7a ] = KEY_KP9,
+	[ 0x0e ] = KEY_KP0,
+
+	[ 0x02 ] = KEY_POWER,
+	[ 0x22 ] = KEY_VIDEO,
+	[ 0x42 ] = KEY_AUDIO,
+	[ 0x62 ] = KEY_ZOOM,
+	[ 0x0a ] = KEY_TV,
+	[ 0x12 ] = KEY_CD,
+	[ 0x1a ] = KEY_TEXT,
+
+	[ 0x16 ] = KEY_SUBTITLE,
+	[ 0x1e ] = KEY_REWIND,
+	[ 0x06 ] = KEY_PRINT,
+
+	[ 0x2e ] = KEY_SEARCH,
+	[ 0x36 ] = KEY_SLEEP,
+	[ 0x3e ] = KEY_SHUFFLE,
+	[ 0x26 ] = KEY_MUTE,
+
+	[ 0x4e ] = KEY_RECORD,
+	[ 0x56 ] = KEY_PAUSE,
+	[ 0x5e ] = KEY_STOP,
+	[ 0x46 ] = KEY_PLAY,
+
+	[ 0x6e ] = KEY_RED,
+	[ 0x0b ] = KEY_GREEN,
+	[ 0x66 ] = KEY_YELLOW,
+	[ 0x03 ] = KEY_BLUE,
+
+	[ 0x76 ] = KEY_LEFT,
+	[ 0x7e ] = KEY_RIGHT,
+	[ 0x13 ] = KEY_DOWN,
+	[ 0x1b ] = KEY_UP,
+};
+
+/* ---------------------------------------------------------------------- */
+
+/* DigitalNow DNTV Live! DVB-T Pro Remote */
+static IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE] = {
+	[ 0x16 ] = KEY_POWER,
+	[ 0x5b ] = KEY_HOME,
+
+	[ 0x55 ] = KEY_TV,		/* live tv */
+	[ 0x58 ] = KEY_TUNER,		/* digital Radio */
+	[ 0x5a ] = KEY_RADIO,		/* FM radio */
+	[ 0x59 ] = KEY_DVD,		/* dvd menu */
+	[ 0x03 ] = KEY_1,
+	[ 0x01 ] = KEY_2,
+	[ 0x06 ] = KEY_3,
+	[ 0x09 ] = KEY_4,
+	[ 0x1d ] = KEY_5,
+	[ 0x1f ] = KEY_6,
+	[ 0x0d ] = KEY_7,
+	[ 0x19 ] = KEY_8,
+	[ 0x1b ] = KEY_9,
+	[ 0x0c ] = KEY_CANCEL,
+	[ 0x15 ] = KEY_0,
+	[ 0x4a ] = KEY_CLEAR,
+	[ 0x13 ] = KEY_BACK,
+	[ 0x00 ] = KEY_TAB,
+	[ 0x4b ] = KEY_UP,
+	[ 0x4e ] = KEY_LEFT,
+	[ 0x4f ] = KEY_OK,
+	[ 0x52 ] = KEY_RIGHT,
+	[ 0x51 ] = KEY_DOWN,
+	[ 0x1e ] = KEY_VOLUMEUP,
+	[ 0x0a ] = KEY_VOLUMEDOWN,
+	[ 0x02 ] = KEY_CHANNELDOWN,
+	[ 0x05 ] = KEY_CHANNELUP,
+	[ 0x11 ] = KEY_RECORD,
+	[ 0x14 ] = KEY_PLAY,
+	[ 0x4c ] = KEY_PAUSE,
+	[ 0x1a ] = KEY_STOP,
+	[ 0x40 ] = KEY_REWIND,
+	[ 0x12 ] = KEY_FASTFORWARD,
+	[ 0x41 ] = KEY_PREVIOUSSONG,	/* replay |< */
+	[ 0x42 ] = KEY_NEXTSONG,	/* skip >| */
+	[ 0x54 ] = KEY_CAMERA,		/* capture */
+	[ 0x50 ] = KEY_LANGUAGE,	/* sap */
+	[ 0x47 ] = KEY_TV2,		/* pip */
+	[ 0x4d ] = KEY_SCREEN,
+	[ 0x43 ] = KEY_SUBTITLE,
+	[ 0x10 ] = KEY_MUTE,
+	[ 0x49 ] = KEY_AUDIO,		/* l/r */
+	[ 0x07 ] = KEY_SLEEP,
+	[ 0x08 ] = KEY_VIDEO,		/* a/v */
+	[ 0x0e ] = KEY_PREVIOUS,	/* recall */
+	[ 0x45 ] = KEY_ZOOM,		/* zoom + */
+	[ 0x46 ] = KEY_ANGLE,		/* zoom - */
+	[ 0x56 ] = KEY_RED,
+	[ 0x57 ] = KEY_GREEN,
+	[ 0x5c ] = KEY_YELLOW,
+	[ 0x5d ] = KEY_BLUE,
+};
+
+/* ---------------------------------------------------------------------- */
+
 struct cx88_IR {
 	struct cx88_core *core;
 	struct input_dev *input;
@@ -266,7 +373,7 @@
 	char phys[32];
 
 	/* sample from gpio pin 16 */
-	int sampling;
+	u32 sampling;
 	u32 samples[16];
 	int scount;
 	unsigned long release;
@@ -384,10 +491,13 @@
 	case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
 		ir_codes = ir_codes_cinergy_1400;
 		ir_type = IR_TYPE_PD;
-		ir->sampling = 1;
+		ir->sampling = 0xeb04; /* address */
 		break;
 	case CX88_BOARD_HAUPPAUGE:
 	case CX88_BOARD_HAUPPAUGE_DVB_T1:
+	case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
+	case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
+	case CX88_BOARD_HAUPPAUGE_HVR1100:
 		ir_codes = ir_codes_hauppauge_new;
 		ir_type = IR_TYPE_RC5;
 		ir->sampling = 1;
@@ -427,6 +537,19 @@
 		ir->mask_keyup = 0x40;
 		ir->polling = 1; /* ms */
 		break;
+	case CX88_BOARD_AVERTV_303:
+	case CX88_BOARD_AVERTV_STUDIO_303:
+		ir_codes         = ir_codes_avertv_303;
+		ir->gpio_addr    = MO_GP2_IO;
+		ir->mask_keycode = 0xfb;
+		ir->mask_keydown = 0x02;
+		ir->polling      = 50; /* ms */
+		break;
+	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
+		ir_codes = ir_codes_dntv_live_dvbt_pro;
+		ir_type = IR_TYPE_PD;
+		ir->sampling = 0xff00; /* address */
+		break;
 	}
 
 	if (NULL == ir_codes) {
@@ -484,6 +607,10 @@
 	if (NULL == ir)
 		return 0;
 
+	if (ir->sampling) {
+		cx_write(MO_DDSCFG_IO, 0x0);
+		core->pci_irqmask &= ~(1 << 18);
+	}
 	if (ir->polling) {
 		del_timer(&ir->timer);
 		flush_scheduled_work();
@@ -535,6 +662,7 @@
 	/* decode it */
 	switch (core->board) {
 	case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
+	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
 		ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4);
 
 		if (ircode == 0xffffffff) { /* decoding error */
@@ -550,7 +678,7 @@
 			break;
 		}
 
-		if ((ircode & 0xffff) != 0xeb04) { /* wrong address */
+		if ((ircode & 0xffff) != (ir->sampling & 0xffff)) { /* wrong address */
 			ir_dprintk("pulse distance decoded wrong address\n");
 			break;
 		}
@@ -567,6 +695,8 @@
 		break;
 	case CX88_BOARD_HAUPPAUGE:
 	case CX88_BOARD_HAUPPAUGE_DVB_T1:
+	case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
+	case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
 		ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
 		ir_dprintk("biphase decoded: %x\n", ircode);
 		if ((ircode & 0xfffff000) != 0x3000)
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index 35e6d0c..c79cc1d 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -78,6 +78,11 @@
 		case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
 			cx_write(TS_SOP_STAT, 1<<13);
 			break;
+		case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
+		case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
+			cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */
+			udelay(100);
+			break;
 		default:
 			cx_write(TS_SOP_STAT, 0x00);
 			break;
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index a1b120c..24118e4 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -132,14 +132,22 @@
 {
 	u32 volume;
 
+#ifndef USING_CX88_ALSA
 	/* restart dma; This avoids buzz in NICAM and is good in others  */
 	cx88_stop_audio_dma(core);
+#endif
 	cx_write(AUD_RATE_THRES_DMD, 0x000000C0);
+#ifndef USING_CX88_ALSA
 	cx88_start_audio_dma(core);
+#endif
 
 	if (cx88_boards[core->board].blackbird) {
 		/* sets sound input from external adc */
-		cx_set(AUD_CTL, EN_I2SIN_ENABLE);
+		if (core->board == CX88_BOARD_HAUPPAUGE_ROSLYN)
+			cx_clear(AUD_CTL, EN_I2SIN_ENABLE);
+		else
+			cx_set(AUD_CTL, EN_I2SIN_ENABLE);
+
 		cx_write(AUD_I2SINPUTCNTL, 4);
 		cx_write(AUD_BAUDRATE, 1);
 		/* 'pass-thru mode': this enables the i2s output to the mpeg encoder */
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 24a48f8..9a02515 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -33,6 +33,7 @@
 #include <asm/div64.h>
 
 #include "cx88.h"
+#include <media/v4l2-common.h>
 
 /* Include V4L1 specific functions. Should be removed soon */
 #include <linux/videodev.h>
@@ -240,7 +241,7 @@
 			.minimum       = 0,
 			.maximum       = 0xff,
 			.step          = 1,
-			.default_value = 0,
+			.default_value = 0x3f,
 			.type          = V4L2_CTRL_TYPE_INTEGER,
 		},
 		.off                   = 0,
@@ -271,7 +272,7 @@
 			.minimum       = 0,
 			.maximum       = 0xff,
 			.step          = 1,
-			.default_value = 0,
+			.default_value = 0x7f,
 			.type          = V4L2_CTRL_TYPE_INTEGER,
 		},
 		.off                   = 0,
@@ -285,6 +286,7 @@
 			.name          = "Mute",
 			.minimum       = 0,
 			.maximum       = 1,
+			.default_value = 1,
 			.type          = V4L2_CTRL_TYPE_BOOLEAN,
 		},
 		.reg                   = AUD_VOL_CTL,
@@ -298,7 +300,7 @@
 			.minimum       = 0,
 			.maximum       = 0x3f,
 			.step          = 1,
-			.default_value = 0,
+			.default_value = 0x1f,
 			.type          = V4L2_CTRL_TYPE_INTEGER,
 		},
 		.reg                   = AUD_VOL_CTL,
@@ -917,6 +919,9 @@
 		ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift;
 		break;
 	}
+	printk("get_control id=0x%X reg=0x%02x val=0x%02x (mask 0x%02x)%s\n",
+					ctl->id, c->reg, ctl->value,
+					c->mask, c->sreg ? " [shadowed]" : "");
 	return 0;
 }
 
@@ -925,13 +930,13 @@
 {
 	/* struct cx88_core *core = dev->core; */
 	struct cx88_ctrl *c = NULL;
-	u32 v_sat_value;
-	u32 value;
+	u32 value,mask;
 	int i;
-
-	for (i = 0; i < CX8800_CTLS; i++)
-		if (cx8800_ctls[i].v.id == ctl->id)
+	for (i = 0; i < CX8800_CTLS; i++) {
+		if (cx8800_ctls[i].v.id == ctl->id) {
 			c = &cx8800_ctls[i];
+		}
+	}
 	if (NULL == c)
 		return -EINVAL;
 
@@ -939,6 +944,7 @@
 		ctl->value = c->v.minimum;
 	if (ctl->value > c->v.maximum)
 		ctl->value = c->v.maximum;
+	mask=c->mask;
 	switch (ctl->id) {
 	case V4L2_CID_AUDIO_BALANCE:
 		value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value;
@@ -948,56 +954,44 @@
 		break;
 	case V4L2_CID_SATURATION:
 		/* special v_sat handling */
-		v_sat_value = ctl->value - (0x7f - 0x5a);
-		if (v_sat_value > 0xff)
-			v_sat_value = 0xff;
-		if (v_sat_value < 0x00)
-			v_sat_value = 0x00;
-		cx_andor(MO_UV_SATURATION, 0xff00, v_sat_value << 8);
-		/* fall through to default route for u_sat */
+
+		value = ((ctl->value - c->off) << c->shift) & c->mask;
+
+		if (core->tvnorm->id & V4L2_STD_SECAM) {
+			/* For SECAM, both U and V sat should be equal */
+			value=value<<8|value;
+		} else {
+			/* Keeps U Saturation proportional to V Sat */
+			value=(value*0x5a)/0x7f<<8|value;
+		}
+		mask=0xffff;
+		break;
 	default:
 		value = ((ctl->value - c->off) << c->shift) & c->mask;
 		break;
 	}
-	dprintk(1,"set_control id=0x%X reg=0x%x val=0x%x%s\n",
-		ctl->id, c->reg, value, c->sreg ? " [shadowed]" : "");
+	printk("set_control id=0x%X reg=0x%02x val=0x%02x (mask 0x%02x)%s\n",
+					ctl->id, c->reg, value,
+					mask, c->sreg ? " [shadowed]" : "");
 	if (c->sreg) {
-		cx_sandor(c->sreg, c->reg, c->mask, value);
+		cx_sandor(c->sreg, c->reg, mask, value);
 	} else {
-		cx_andor(c->reg, c->mask, value);
+		cx_andor(c->reg, mask, value);
 	}
 	return 0;
 }
 
-/* static void init_controls(struct cx8800_dev *dev) */
 static void init_controls(struct cx88_core *core)
 {
-	static struct v4l2_control mute = {
-		.id    = V4L2_CID_AUDIO_MUTE,
-		.value = 1,
-	};
-	static struct v4l2_control volume = {
-		.id    = V4L2_CID_AUDIO_VOLUME,
-		.value = 0x3f,
-	};
-	static struct v4l2_control hue = {
-		.id    = V4L2_CID_HUE,
-		.value = 0x80,
-	};
-	static struct v4l2_control contrast = {
-		.id    = V4L2_CID_CONTRAST,
-		.value = 0x80,
-	};
-	static struct v4l2_control brightness = {
-		.id    = V4L2_CID_BRIGHTNESS,
-		.value = 0x80,
-	};
+	struct v4l2_control ctrl;
+	int i;
 
-	set_control(core,&mute);
-	set_control(core,&volume);
-	set_control(core,&hue);
-	set_control(core,&contrast);
-	set_control(core,&brightness);
+	for (i = 0; i < CX8800_CTLS; i++) {
+		ctrl.id=cx8800_ctls[i].v.id;
+		ctrl.value=cx8800_ctls[i].v.default_value
+				+cx8800_ctls[i].off;
+		set_control(core, &ctrl);
+	}
 }
 
 /* ------------------------------------------------------------------ */
@@ -1125,7 +1119,7 @@
 	int err;
 
 	if (video_debug > 1)
-		cx88_print_ioctl(core->name,cmd);
+		v4l_print_ioctl(core->name,cmd);
 	switch (cmd) {
 
 	/* --- capabilities ------------------------------------------ */
@@ -1261,7 +1255,7 @@
 
 	dprintk( 1, "CORE IOCTL: 0x%x\n", cmd );
 	if (video_debug > 1)
-		cx88_print_ioctl(core->name,cmd);
+		v4l_print_ioctl(core->name,cmd);
 
 	switch (cmd) {
 	/* ---------- tv norms ---------- */
@@ -1481,7 +1475,7 @@
 	struct cx88_core  *core = dev->core;
 
 	if (video_debug > 1)
-		cx88_print_ioctl(core->name,cmd);
+		v4l_print_ioctl(core->name,cmd);
 
 	switch (cmd) {
 	case VIDIOC_QUERYCAP:
@@ -1740,6 +1734,7 @@
 	.poll          = video_poll,
 	.mmap	       = video_mmap,
 	.ioctl	       = video_ioctl,
+	.compat_ioctl  = v4l_compat_ioctl32,
 	.llseek        = no_llseek,
 };
 
@@ -1767,6 +1762,7 @@
 	.open          = video_open,
 	.release       = video_release,
 	.ioctl         = radio_ioctl,
+	.compat_ioctl  = v4l_compat_ioctl32,
 	.llseek        = no_llseek,
 };
 
@@ -1928,8 +1924,8 @@
 
 	/* initial device configuration */
 	down(&core->lock);
-	init_controls(core);
 	cx88_set_tvnorm(core,tvnorms);
+	init_controls(core);
 	video_mux(core,0);
 	up(&core->lock);
 
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.c b/drivers/media/video/cx88/cx88-vp3054-i2c.c
new file mode 100644
index 0000000..372cd29
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-vp3054-i2c.c
@@ -0,0 +1,173 @@
+/*
+
+    cx88-vp3054-i2c.c  --  support for the secondary I2C bus of the
+			   DNTV Live! DVB-T Pro (VP-3054), wired as:
+			   GPIO[0] -> SCL, GPIO[1] -> SDA
+
+    (c) 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+
+#include "cx88.h"
+#include "cx88-vp3054-i2c.h"
+
+
+/* ----------------------------------------------------------------------- */
+
+static void vp3054_bit_setscl(void *data, int state)
+{
+	struct cx8802_dev *dev = data;
+	struct cx88_core *core = dev->core;
+	struct vp3054_i2c_state *vp3054_i2c = dev->card_priv;
+
+	if (state) {
+		vp3054_i2c->state |=  0x0001;	/* SCL high */
+		vp3054_i2c->state &= ~0x0100;	/* external pullup */
+	} else {
+		vp3054_i2c->state &= ~0x0001;	/* SCL low */
+		vp3054_i2c->state |=  0x0100;	/* drive pin */
+	}
+	cx_write(MO_GP0_IO, 0x010000 | vp3054_i2c->state);
+	cx_read(MO_GP0_IO);
+}
+
+static void vp3054_bit_setsda(void *data, int state)
+{
+	struct cx8802_dev *dev = data;
+	struct cx88_core *core = dev->core;
+	struct vp3054_i2c_state *vp3054_i2c = dev->card_priv;
+
+	if (state) {
+		vp3054_i2c->state |=  0x0002;	/* SDA high */
+		vp3054_i2c->state &= ~0x0200;	/* tristate pin */
+	} else {
+		vp3054_i2c->state &= ~0x0002;	/* SDA low */
+		vp3054_i2c->state |=  0x0200;	/* drive pin */
+	}
+	cx_write(MO_GP0_IO, 0x020000 | vp3054_i2c->state);
+	cx_read(MO_GP0_IO);
+}
+
+static int vp3054_bit_getscl(void *data)
+{
+	struct cx8802_dev *dev = data;
+	struct cx88_core *core = dev->core;
+	u32 state;
+
+	state = cx_read(MO_GP0_IO);
+	return (state & 0x01) ? 1 : 0;
+}
+
+static int vp3054_bit_getsda(void *data)
+{
+	struct cx8802_dev *dev = data;
+	struct cx88_core *core = dev->core;
+	u32 state;
+
+	state = cx_read(MO_GP0_IO);
+	return (state & 0x02) ? 1 : 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static struct i2c_algo_bit_data vp3054_i2c_algo_template = {
+	.setsda  = vp3054_bit_setsda,
+	.setscl  = vp3054_bit_setscl,
+	.getsda  = vp3054_bit_getsda,
+	.getscl  = vp3054_bit_getscl,
+	.udelay  = 16,
+	.mdelay  = 10,
+	.timeout = 200,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static struct i2c_adapter vp3054_i2c_adap_template = {
+	.name              = "cx2388x",
+	.owner             = THIS_MODULE,
+	.id                = I2C_HW_B_CX2388x,
+};
+
+static struct i2c_client vp3054_i2c_client_template = {
+	.name	= "VP-3054",
+};
+
+int vp3054_i2c_probe(struct cx8802_dev *dev)
+{
+	struct cx88_core *core = dev->core;
+	struct vp3054_i2c_state *vp3054_i2c;
+	int rc;
+
+	if (core->board != CX88_BOARD_DNTV_LIVE_DVB_T_PRO)
+		return 0;
+
+	dev->card_priv = kzalloc(sizeof(*vp3054_i2c), GFP_KERNEL);
+	if (dev->card_priv == NULL)
+		return -ENOMEM;
+	vp3054_i2c = dev->card_priv;
+
+	memcpy(&vp3054_i2c->adap, &vp3054_i2c_adap_template,
+	       sizeof(vp3054_i2c->adap));
+	memcpy(&vp3054_i2c->algo, &vp3054_i2c_algo_template,
+	       sizeof(vp3054_i2c->algo));
+	memcpy(&vp3054_i2c->client, &vp3054_i2c_client_template,
+	       sizeof(vp3054_i2c->client));
+
+	vp3054_i2c->adap.class |= I2C_CLASS_TV_DIGITAL;
+
+	vp3054_i2c->adap.dev.parent = &dev->pci->dev;
+	strlcpy(vp3054_i2c->adap.name, core->name,
+		sizeof(vp3054_i2c->adap.name));
+	vp3054_i2c->algo.data = dev;
+	i2c_set_adapdata(&vp3054_i2c->adap, dev);
+	vp3054_i2c->adap.algo_data = &vp3054_i2c->algo;
+	vp3054_i2c->client.adapter = &vp3054_i2c->adap;
+
+	vp3054_bit_setscl(dev,1);
+	vp3054_bit_setsda(dev,1);
+
+	rc = i2c_bit_add_bus(&vp3054_i2c->adap);
+	if (0 != rc) {
+		printk("%s: vp3054_i2c register FAILED\n", core->name);
+
+		kfree(dev->card_priv);
+		dev->card_priv = NULL;
+	}
+
+	return rc;
+}
+
+void vp3054_i2c_remove(struct cx8802_dev *dev)
+{
+	struct vp3054_i2c_state *vp3054_i2c = dev->card_priv;
+
+	if (vp3054_i2c == NULL ||
+	    dev->core->board != CX88_BOARD_DNTV_LIVE_DVB_T_PRO)
+		return;
+
+	i2c_bit_del_bus(&vp3054_i2c->adap);
+	kfree(vp3054_i2c);
+}
+
+EXPORT_SYMBOL(vp3054_i2c_probe);
+EXPORT_SYMBOL(vp3054_i2c_remove);
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.h b/drivers/media/video/cx88/cx88-vp3054-i2c.h
new file mode 100644
index 0000000..b7a0a04
--- /dev/null
+++ b/drivers/media/video/cx88/cx88-vp3054-i2c.h
@@ -0,0 +1,35 @@
+/*
+
+    cx88-vp3054-i2c.h  --  support for the secondary I2C bus of the
+			   DNTV Live! DVB-T Pro (VP-3054), wired as:
+			   GPIO[0] -> SCL, GPIO[1] -> SDA
+
+    (c) 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+/* ----------------------------------------------------------------------- */
+struct vp3054_i2c_state {
+	struct i2c_adapter         adap;
+	struct i2c_algo_bit_data   algo;
+	struct i2c_client          client;
+	u32                        state;
+};
+
+/* ----------------------------------------------------------------------- */
+int  vp3054_i2c_probe(struct cx8802_dev *dev);
+void vp3054_i2c_remove(struct cx8802_dev *dev);
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 77beafc..e9fd55b 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -179,6 +179,14 @@
 #define CX88_BOARD_ATI_HDTVWONDER          34
 #define CX88_BOARD_WINFAST_DTV1000         35
 #define CX88_BOARD_AVERTV_303              36
+#define CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1  37
+#define CX88_BOARD_HAUPPAUGE_NOVASE2_S1    38
+#define CX88_BOARD_KWORLD_DVBS_100         39
+#define CX88_BOARD_HAUPPAUGE_HVR1100       40
+#define CX88_BOARD_HAUPPAUGE_HVR1100LP     41
+#define CX88_BOARD_DNTV_LIVE_DVB_T_PRO     42
+#define CX88_BOARD_KWORLD_DVB_T_CX22702    43
+#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL 44
 
 enum cx88_itype {
 	CX88_VMUX_COMPOSITE1 = 1,
@@ -280,6 +288,9 @@
 	unsigned int               tda9887_conf;
 	unsigned int               has_radio;
 
+	/* Supported V4L _STD_ tuner formats */
+	unsigned int               tuner_formats;
+
 	/* config info -- dvb */
 	struct dvb_pll_desc        *pll_desc;
 	unsigned int               pll_addr;
@@ -301,6 +312,9 @@
 
 	/* various v4l controls */
 	u32                        freq;
+
+	/* cx88-video needs to access cx8802 for hybrid tuner pll access. */
+	struct cx8802_dev          *dvbdev;
 };
 
 struct cx8800_dev;
@@ -411,6 +425,8 @@
 	struct videobuf_dvb        dvb;
 	void*                      fe_handle;
 	int                        (*fe_release)(void *handle);
+
+	void			   *card_priv;
 	/* for switching modulation types */
 	unsigned char              ts_gen_cntrl;
 
@@ -447,7 +463,6 @@
 
 extern void cx88_print_irqbits(char *name, char *tag, char **strings,
 			       u32 bits, u32 mask);
-extern void cx88_print_ioctl(char *name, unsigned int cmd);
 
 extern int cx88_core_irq(struct cx88_core *core, u32 status);
 extern void cx88_wakeup(struct cx88_core *core,
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 57779e6..58f7b41 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -30,6 +30,7 @@
 #include <media/tuner.h>
 #include <media/audiochip.h>
 #include <media/tveeprom.h>
+#include <media/v4l2-common.h>
 #include "msp3400.h"
 
 #include "em28xx.h"
@@ -261,7 +262,6 @@
 	/* request some modules */
 	if (dev->model == EM2820_BOARD_HAUPPAUGE_WINTV_USB_2) {
 		struct tveeprom tv;
-		struct v4l2_audioout ao;
 #ifdef CONFIG_MODULES
 		request_module("tveeprom");
 		request_module("ir-kbd-i2c");
@@ -274,12 +274,8 @@
 
 		dev->tuner_type= tv.tuner_type;
 		if (tv.audio_processor == AUDIO_CHIP_MSP34XX) {
+			dev->i2s_speed=2048000;
 			dev->has_msp34xx=1;
-			memset (&ao,0,sizeof(ao));
-
-			ao.index=2;
-			ao.mode=V4L2_AUDMODE_32BITS;
-			em28xx_i2c_call_clients(dev, VIDIOC_S_AUDOUT, &ao);
 		} else
 			dev->has_msp34xx=0;
 	}
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 0cfe754..dff3893 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -32,7 +32,7 @@
 
 /* #define ENABLE_DEBUG_ISOC_FRAMES */
 
-static unsigned int core_debug;
+static unsigned int core_debug = 0;
 module_param(core_debug,int,0644);
 MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
 
@@ -41,7 +41,7 @@
 		printk(KERN_INFO "%s %s :"fmt, \
 			 dev->name, __FUNCTION__ , ##arg); } while (0)
 
-static unsigned int reg_debug;
+static unsigned int reg_debug = 0;
 module_param(reg_debug,int,0644);
 MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]");
 
@@ -50,7 +50,7 @@
 		printk(KERN_INFO "%s %s :"fmt, \
 			 dev->name, __FUNCTION__ , ##arg); } while (0)
 
-static unsigned int isoc_debug;
+static unsigned int isoc_debug = 0;
 module_param(isoc_debug,int,0644);
 MODULE_PARM_DESC(isoc_debug,"enable debug messages [isoc transfers]");
 
@@ -63,59 +63,6 @@
 module_param(alt, int, 0644);
 MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
 
-/* ------------------------------------------------------------------ */
-/* debug help functions                                               */
-
-static const char *v4l1_ioctls[] = {
-	"0", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
-	"CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
-	"SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
-	"GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
-	"SMICROCODE", "GVBIFMT", "SVBIFMT" };
-#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
-
-static const char *v4l2_ioctls[] = {
-	"QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
-	"G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF",
-	"G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON",
-	"STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD",
-	"ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER",
-	"G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL",
-	"QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43",
-	"44", "45",  "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT",
-	"S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
-	"S_MODULATOR"
-};
-#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
-
-void em28xx_print_ioctl(char *name, unsigned int cmd)
-{
-	char *dir;
-
-	switch (_IOC_DIR(cmd)) {
-	case _IOC_NONE:              dir = "--"; break;
-	case _IOC_READ:              dir = "r-"; break;
-	case _IOC_WRITE:             dir = "-w"; break;
-	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
-	default:                     dir = "??"; break;
-	}
-	switch (_IOC_TYPE(cmd)) {
-	case 'v':
-		printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n",
-		       name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
-		       v4l1_ioctls[_IOC_NR(cmd)] : "???");
-		break;
-	case 'V':
-		printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n",
-		       name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
-		       v4l2_ioctls[_IOC_NR(cmd)] : "???");
-		break;
-	default:
-		printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
-		       name, cmd, dir, _IOC_NR(cmd));
-	}
-}
-
 
 /*
  * em28xx_request_buffers()
@@ -126,7 +73,7 @@
 	const size_t imagesize = PAGE_ALIGN(dev->frame_size);	/*needs to be page aligned cause the buffers can be mapped individually! */
 	void *buff = NULL;
 	u32 i;
-	em28xx_coredbg("requested %i buffers with size %zd", count, imagesize);
+	em28xx_coredbg("requested %i buffers with size %zi", count, imagesize);
 	if (count > EM28XX_NUM_FRAMES)
 		count = EM28XX_NUM_FRAMES;
 
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index d14bcf4..0591a70 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -28,6 +28,7 @@
 #include <linux/video_decoder.h>
 
 #include "em28xx.h"
+#include <media/v4l2-common.h>
 #include <media/tuner.h>
 
 /* ----------------------------------------------------------- */
@@ -486,9 +487,7 @@
 	.inc_use = inc_use,
 	.dec_use = dec_use,
 #endif
-#ifdef I2C_CLASS_TV_ANALOG
 	.class = I2C_CLASS_TV_ANALOG,
-#endif
 	.name = "em28xx",
 	.id = I2C_HW_B_EM28XX,
 	.algo = &em28xx_algo,
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 3a56120..fdc2559 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -32,6 +32,7 @@
 
 #include "em28xx.h"
 #include <media/tuner.h>
+#include <media/v4l2-common.h>
 
 #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
 		      "Markus Rechberger <mrechberger@gmail.com>, " \
@@ -106,8 +107,32 @@
 #define TVNORMS ARRAY_SIZE(tvnorms)
 
 /* supported controls */
+/* Common to all boards */
 static struct v4l2_queryctrl em28xx_qctrl[] = {
 	{
+		.id = V4L2_CID_AUDIO_VOLUME,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Volume",
+		.minimum = 0x0,
+		.maximum = 0x1f,
+		.step = 0x1,
+		.default_value = 0x1f,
+		.flags = 0,
+	},{
+		.id = V4L2_CID_AUDIO_MUTE,
+		.type = V4L2_CTRL_TYPE_BOOLEAN,
+		.name = "Mute",
+		.minimum = 0,
+		.maximum = 1,
+		.step = 1,
+		.default_value = 1,
+		.flags = 0,
+	}
+};
+
+/* FIXME: These are specific to saa711x - should be moved to its code */
+static struct v4l2_queryctrl saa711x_qctrl[] = {
+	{
 		.id = V4L2_CID_BRIGHTNESS,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "Brightness",
@@ -135,24 +160,6 @@
 		.default_value = 0x10,
 		.flags = 0,
 	},{
-		.id = V4L2_CID_AUDIO_VOLUME,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "Volume",
-		.minimum = 0x0,
-		.maximum = 0x1f,
-		.step = 0x1,
-		.default_value = 0x1f,
-		.flags = 0,
-	},{
-		.id = V4L2_CID_AUDIO_MUTE,
-		.type = V4L2_CTRL_TYPE_BOOLEAN,
-		.name = "Mute",
-		.minimum = 0,
-		.maximum = 1,
-		.step = 1,
-		.default_value = 1,
-		.flags = 0,
-	},{
 		.id = V4L2_CID_RED_BALANCE,
 		.type = V4L2_CTRL_TYPE_INTEGER,
 		.name = "Red chroma balance",
@@ -179,7 +186,7 @@
 		.step = 0x1,
 		.default_value = 0x20,
 		.flags = 0,
-	 }
+	}
 };
 
 static struct usb_driver em28xx_usb_driver;
@@ -280,6 +287,8 @@
 	em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput);
 
 	if (dev->has_msp34xx) {
+		if (dev->i2s_speed)
+			em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, &dev->i2s_speed);
 		em28xx_i2c_call_clients(dev, VIDIOC_S_AUDIO, &dev->ctl_ainput);
 		ainput = EM28XX_AUDIO_SRC_TUNER;
 		em28xx_audio_source(dev, ainput);
@@ -674,7 +683,6 @@
  */
 static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
 {
-	s32 tmp;
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
 		ctrl->value = dev->mute;
@@ -682,6 +690,16 @@
 	case V4L2_CID_AUDIO_VOLUME:
 		ctrl->value = dev->volume;
 		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+/*FIXME: should be moved to saa711x */
+static int saa711x_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
+{
+	s32 tmp;
+	switch (ctrl->id) {
 	case V4L2_CID_BRIGHTNESS:
 		if ((tmp = em28xx_brightness_get(dev)) < 0)
 			return -EIO;
@@ -731,6 +749,15 @@
 	case V4L2_CID_AUDIO_VOLUME:
 		dev->volume = ctrl->value;
 		return em28xx_audio_analog_set(dev);
+	default:
+		return -EINVAL;
+	}
+}
+
+/*FIXME: should be moved to saa711x */
+static int saa711x_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl)
+{
+	switch (ctrl->id) {
 	case V4L2_CID_BRIGHTNESS:
 		return em28xx_brightness_set(dev, ctrl->value);
 	case V4L2_CID_CONTRAST:
@@ -994,14 +1021,34 @@
 	case VIDIOC_QUERYCTRL:
 		{
 			struct v4l2_queryctrl *qc = arg;
-			u8 i, n;
-			n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]);
-			for (i = 0; i < n; i++)
-				if (qc->id && qc->id == em28xx_qctrl[i].id) {
-					memcpy(qc, &(em28xx_qctrl[i]),
+			int i, id=qc->id;
+
+			memset(qc,0,sizeof(*qc));
+			qc->id=id;
+
+			if (!dev->has_msp34xx) {
+				for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
+					if (qc->id && qc->id == em28xx_qctrl[i].id) {
+						memcpy(qc, &(em28xx_qctrl[i]),
+						sizeof(*qc));
+						return 0;
+					}
+				}
+			}
+			if (dev->decoder == EM28XX_TVP5150) {
+				em28xx_i2c_call_clients(dev,cmd,qc);
+				if (qc->type)
+					return 0;
+				else
+					return -EINVAL;
+			}
+			for (i = 0; i < ARRAY_SIZE(saa711x_qctrl); i++) {
+				if (qc->id && qc->id == saa711x_qctrl[i].id) {
+					memcpy(qc, &(saa711x_qctrl[i]),
 					       sizeof(*qc));
 					return 0;
 				}
+			}
 
 			return -EINVAL;
 		}
@@ -1009,29 +1056,64 @@
 	case VIDIOC_G_CTRL:
 		{
 			struct v4l2_control *ctrl = arg;
+			int retval=-EINVAL;
 
+			if (!dev->has_msp34xx)
+				retval=em28xx_get_ctrl(dev, ctrl);
+			if (retval==-EINVAL) {
+				if (dev->decoder == EM28XX_TVP5150) {
+					em28xx_i2c_call_clients(dev,cmd,arg);
+					return 0;
+				}
 
-			return em28xx_get_ctrl(dev, ctrl);
+				return saa711x_get_ctrl(dev, ctrl);
+			} else return retval;
 		}
 
-	case VIDIOC_S_CTRL_OLD:	/* ??? */
 	case VIDIOC_S_CTRL:
 		{
 			struct v4l2_control *ctrl = arg;
-			u8 i, n;
+			u8 i;
 
-
-			n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]);
-			for (i = 0; i < n; i++)
-				if (ctrl->id == em28xx_qctrl[i].id) {
-					if (ctrl->value <
-					    em28xx_qctrl[i].minimum
-					    || ctrl->value >
-					    em28xx_qctrl[i].maximum)
-						return -ERANGE;
-
-					return em28xx_set_ctrl(dev, ctrl);
+			if (!dev->has_msp34xx){
+				for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
+					if (ctrl->id == em28xx_qctrl[i].id) {
+						if (ctrl->value <
+						em28xx_qctrl[i].minimum
+						|| ctrl->value >
+						em28xx_qctrl[i].maximum)
+							return -ERANGE;
+						return em28xx_set_ctrl(dev, ctrl);
+					}
 				}
+			}
+
+			if (dev->decoder == EM28XX_TVP5150) {
+				em28xx_i2c_call_clients(dev,cmd,arg);
+				return 0;
+			} else if (!dev->has_msp34xx) {
+				for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
+					if (ctrl->id == em28xx_qctrl[i].id) {
+						if (ctrl->value <
+						em28xx_qctrl[i].minimum
+						|| ctrl->value >
+						em28xx_qctrl[i].maximum)
+							return -ERANGE;
+						return em28xx_set_ctrl(dev, ctrl);
+					}
+				}
+				for (i = 0; i < ARRAY_SIZE(saa711x_qctrl); i++) {
+					if (ctrl->id == saa711x_qctrl[i].id) {
+						if (ctrl->value <
+						saa711x_qctrl[i].minimum
+						|| ctrl->value >
+						saa711x_qctrl[i].maximum)
+							return -ERANGE;
+						return saa711x_set_ctrl(dev, ctrl);
+					}
+				}
+			}
+
 			return -EINVAL;
 		}
 
@@ -1187,7 +1269,7 @@
 		return -ENODEV;
 
 	if (video_debug > 1)
-		em28xx_print_ioctl(dev->name,cmd);
+		v4l_print_ioctl(dev->name,cmd);
 
 	switch (cmd) {
 
@@ -1564,6 +1646,8 @@
 	.poll = em28xx_v4l2_poll,
 	.mmap = em28xx_v4l2_mmap,
 	.llseek = no_llseek,
+	.compat_ioctl   = v4l_compat_ioctl32,
+
 };
 
 /******************************** usb interface *****************************************/
@@ -1848,9 +1932,12 @@
 	struct em28xx *dev = usb_get_intfdata(interface);
 	usb_set_intfdata(interface, NULL);
 
+/*FIXME: IR should be disconnected */
+
 	if (!dev)
 		return;
 
+
 	down_write(&em28xx_disconnect);
 
 	down(&dev->lock);
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 5c7a41c..33de9d8 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -1,5 +1,5 @@
 /*
-   em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
+   em28xx.h - driver for Empia EM2800/EM2820/2840 USB video capture devices
 
    Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com>
 		      Ludovico Cavedon <cavedon@sssup.it>
@@ -216,6 +216,8 @@
 	unsigned int has_msp34xx:1;
 	unsigned int has_tda9887:1;
 
+	u32 i2s_speed;		/* I2S speed for audio digital stream */
+
 	enum em28xx_decoder decoder;
 
 	int tuner_type;		/* type of the tuner */
@@ -293,8 +295,6 @@
 
 /* Provided by em28xx-core.c */
 
-void em28xx_print_ioctl(char *name, unsigned int cmd);
-
 u32 em28xx_request_buffers(struct em28xx *dev, u32 count);
 void em28xx_queue_unusedframes(struct em28xx *dev);
 void em28xx_release_buffers(struct em28xx *dev);
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 3cc1d6a..58b0e69 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -279,7 +279,7 @@
 
 static struct i2c_driver driver = {
 	.driver = {
-		.name   = "ir remote kbd driver",
+		.name   = "ir-kbd-i2c",
 	},
 	.id             = I2C_DRIVERID_INFRARED,
 	.attach_adapter = ir_probe,
@@ -304,18 +304,20 @@
 	ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL);
 	input_dev = input_allocate_device();
 	if (!ir || !input_dev) {
-		kfree(ir);
 		input_free_device(input_dev);
+		kfree(ir);
 		return -ENOMEM;
 	}
+	memset(ir,0,sizeof(*ir));
 
 	ir->c = client_template;
 	ir->input = input_dev;
 
-	i2c_set_clientdata(&ir->c, ir);
 	ir->c.adapter = adap;
 	ir->c.addr    = addr;
 
+	i2c_set_clientdata(&ir->c, ir);
+
 	switch(addr) {
 	case 0x64:
 		name        = "Pixelview";
@@ -378,13 +380,15 @@
 		 ir->c.dev.bus_id);
 
 	/* init + register input device */
-	ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
-	input_dev->id.bustype	= BUS_I2C;
-	input_dev->name		= ir->c.name;
-	input_dev->phys		= ir->phys;
+	ir_input_init(input_dev,&ir->ir,ir_type,ir->ir_codes);
+	input_dev->id.bustype = BUS_I2C;
+	input_dev->name       = ir->c.name;
+	input_dev->phys       = ir->phys;
 
 	/* register event device */
 	input_register_device(ir->input);
+	printk(DEVNAME ": %s detected at %s [%s]\n",
+	       ir->input->name,ir->input->phys,adap->name);
 
 	/* start polling via eventd */
 	INIT_WORK(&ir->work, ir_work, ir);
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 3f2a882..2869464 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -1754,6 +1754,7 @@
 	.release	= meye_release,
 	.mmap		= meye_mmap,
 	.ioctl		= meye_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.poll		= meye_poll,
 	.llseek		= no_llseek,
 };
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
new file mode 100644
index 0000000..aa8c556
--- /dev/null
+++ b/drivers/media/video/msp3400-driver.c
@@ -0,0 +1,1274 @@
+/*
+ * Programming the mspx4xx sound processor family
+ *
+ * (c) 1997-2001 Gerd Knorr <kraxel@bytesex.org>
+ *
+ * what works and what doesn't:
+ *
+ *  AM-Mono
+ *      Support for Hauppauge cards added (decoding handled by tuner) added by
+ *      Frederic Crozat <fcrozat@mail.dotcom.fr>
+ *
+ *  FM-Mono
+ *      should work. The stereo modes are backward compatible to FM-mono,
+ *      therefore FM-Mono should be allways available.
+ *
+ *  FM-Stereo (B/G, used in germany)
+ *      should work, with autodetect
+ *
+ *  FM-Stereo (satellite)
+ *      should work, no autodetect (i.e. default is mono, but you can
+ *      switch to stereo -- untested)
+ *
+ *  NICAM (B/G, L , used in UK, Scandinavia, Spain and France)
+ *      should work, with autodetect. Support for NICAM was added by
+ *      Pekka Pietikainen <pp@netppl.fi>
+ *
+ * TODO:
+ *   - better SAT support
+ *
+ * 980623  Thomas Sailer (sailer@ife.ee.ethz.ch)
+ *         using soundcore instead of OSS
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/videodev.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+#include <media/audiochip.h>
+#include <linux/kthread.h>
+#include <linux/suspend.h>
+#include "msp3400.h"
+
+/* ---------------------------------------------------------------------- */
+
+MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
+MODULE_AUTHOR("Gerd Knorr");
+MODULE_LICENSE("GPL");
+
+/* module parameters */
+static int opmode   = OPMODE_AUTO;
+int debug    = 0;    /* debug output */
+int once     = 0;    /* no continous stereo monitoring */
+int amsound  = 0;    /* hard-wire AM sound at 6.5 Hz (france),
+			       the autoscan seems work well only with FM... */
+int standard = 1;    /* Override auto detect of audio standard, if needed. */
+int dolby    = 0;
+
+int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual
+					(msp34xxg only) 0x00a0-0x03c0 */
+
+/* read-only */
+module_param(opmode,           int, 0444);
+
+/* read-write */
+module_param(once,             bool, 0644);
+module_param(debug,            int, 0644);
+module_param(stereo_threshold, int, 0644);
+module_param(standard,         int, 0644);
+module_param(amsound,          bool, 0644);
+module_param(dolby,            bool, 0644);
+
+MODULE_PARM_DESC(opmode, "Forces a MSP3400 opmode. 0=Manual, 1=Autodetect, 2=Autodetect and autoselect");
+MODULE_PARM_DESC(once, "No continuous stereo monitoring");
+MODULE_PARM_DESC(debug, "Enable debug messages [0-3]");
+MODULE_PARM_DESC(stereo_threshold, "Sets signal threshold to activate stereo");
+MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Default: Autodetect");
+MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan");
+MODULE_PARM_DESC(dolby, "Activates Dolby processsing");
+
+/* ---------------------------------------------------------------------- */
+
+/* control subaddress */
+#define I2C_MSP_CONTROL 0x00
+/* demodulator unit subaddress */
+#define I2C_MSP_DEM     0x10
+/* DSP unit subaddress */
+#define I2C_MSP_DSP     0x12
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x80 >> 1, 0x88 >> 1, I2C_CLIENT_END };
+I2C_CLIENT_INSMOD;
+
+/* ----------------------------------------------------------------------- */
+/* functions for talking to the MSP3400C Sound processor                   */
+
+int msp_reset(struct i2c_client *client)
+{
+	/* reset and read revision code */
+	static u8 reset_off[3] = { I2C_MSP_CONTROL, 0x80, 0x00 };
+	static u8 reset_on[3]  = { I2C_MSP_CONTROL, 0x00, 0x00 };
+	static u8 write[3]     = { I2C_MSP_DSP + 1, 0x00, 0x1e };
+	u8 read[2];
+	struct i2c_msg reset[2] = {
+		{ client->addr, I2C_M_IGNORE_NAK, 3, reset_off },
+		{ client->addr, I2C_M_IGNORE_NAK, 3, reset_on  },
+	};
+	struct i2c_msg test[2] = {
+		{ client->addr, 0,        3, write },
+		{ client->addr, I2C_M_RD, 2, read  },
+	};
+
+	v4l_dbg(3, client, "msp_reset\n");
+	if (i2c_transfer(client->adapter, &reset[0], 1) != 1 ||
+	    i2c_transfer(client->adapter, &reset[1], 1) != 1 ||
+	    i2c_transfer(client->adapter, test, 2) != 2) {
+		v4l_err(client, "chip reset failed\n");
+		return -1;
+	}
+	return 0;
+}
+
+static int msp_read(struct i2c_client *client, int dev, int addr)
+{
+	int err, retval;
+	u8 write[3];
+	u8 read[2];
+	struct i2c_msg msgs[2] = {
+		{ client->addr, 0,        3, write },
+		{ client->addr, I2C_M_RD, 2, read  }
+	};
+
+	write[0] = dev + 1;
+	write[1] = addr >> 8;
+	write[2] = addr & 0xff;
+
+	for (err = 0; err < 3; err++) {
+		if (i2c_transfer(client->adapter, msgs, 2) == 2)
+			break;
+		v4l_warn(client, "I/O error #%d (read 0x%02x/0x%02x)\n", err,
+		       dev, addr);
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(msecs_to_jiffies(10));
+	}
+	if (err == 3) {
+		v4l_warn(client, "giving up, resetting chip. Sound will go off, sorry folks :-|\n");
+		msp_reset(client);
+		return -1;
+	}
+	retval = read[0] << 8 | read[1];
+	v4l_dbg(3, client, "msp_read(0x%x, 0x%x): 0x%x\n", dev, addr, retval);
+	return retval;
+}
+
+int msp_read_dem(struct i2c_client *client, int addr)
+{
+	return msp_read(client, I2C_MSP_DEM, addr);
+}
+
+int msp_read_dsp(struct i2c_client *client, int addr)
+{
+	return msp_read(client, I2C_MSP_DSP, addr);
+}
+
+static int msp_write(struct i2c_client *client, int dev, int addr, int val)
+{
+	int err;
+	u8 buffer[5];
+
+	buffer[0] = dev;
+	buffer[1] = addr >> 8;
+	buffer[2] = addr &  0xff;
+	buffer[3] = val  >> 8;
+	buffer[4] = val  &  0xff;
+
+	v4l_dbg(3, client, "msp_write(0x%x, 0x%x, 0x%x)\n", dev, addr, val);
+	for (err = 0; err < 3; err++) {
+		if (i2c_master_send(client, buffer, 5) == 5)
+			break;
+		v4l_warn(client, "I/O error #%d (write 0x%02x/0x%02x)\n", err,
+		       dev, addr);
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(msecs_to_jiffies(10));
+	}
+	if (err == 3) {
+		v4l_warn(client, "giving up, resetting chip. Sound will go off, sorry folks :-|\n");
+		msp_reset(client);
+		return -1;
+	}
+	return 0;
+}
+
+int msp_write_dem(struct i2c_client *client, int addr, int val)
+{
+	return msp_write(client, I2C_MSP_DEM, addr, val);
+}
+
+int msp_write_dsp(struct i2c_client *client, int addr, int val)
+{
+	return msp_write(client, I2C_MSP_DSP, addr, val);
+}
+
+/* ----------------------------------------------------------------------- *
+ * bits  9  8  5 - SCART DSP input Select:
+ *       0  0  0 - SCART 1 to DSP input (reset position)
+ *       0  1  0 - MONO to DSP input
+ *       1  0  0 - SCART 2 to DSP input
+ *       1  1  1 - Mute DSP input
+ *
+ * bits 11 10  6 - SCART 1 Output Select:
+ *       0  0  0 - undefined (reset position)
+ *       0  1  0 - SCART 2 Input to SCART 1 Output (for devices with 2 SCARTS)
+ *       1  0  0 - MONO input to SCART 1 Output
+ *       1  1  0 - SCART 1 DA to SCART 1 Output
+ *       0  0  1 - SCART 2 DA to SCART 1 Output
+ *       0  1  1 - SCART 1 Input to SCART 1 Output
+ *       1  1  1 - Mute SCART 1 Output
+ *
+ * bits 13 12  7 - SCART 2 Output Select (for devices with 2 Output SCART):
+ *       0  0  0 - SCART 1 DA to SCART 2 Output (reset position)
+ *       0  1  0 - SCART 1 Input to SCART 2 Output
+ *       1  0  0 - MONO input to SCART 2 Output
+ *       0  0  1 - SCART 2 DA to SCART 2 Output
+ *       0  1  1 - SCART 2 Input to SCART 2 Output
+ *       1  1  0 - Mute SCART 2 Output
+ *
+ * Bits 4 to 0 should be zero.
+ * ----------------------------------------------------------------------- */
+
+static int scarts[3][9] = {
+	/* MASK    IN1     IN2     IN1_DA  IN2_DA  IN3     IN4     MONO    MUTE   */
+	/* SCART DSP Input select */
+	{ 0x0320, 0x0000, 0x0200, -1,     -1,     0x0300, 0x0020, 0x0100, 0x0320 },
+	/* SCART1 Output select */
+	{ 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 },
+	/* SCART2 Output select */
+	{ 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 },
+};
+
+static char *scart_names[] = {
+	"mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute"
+};
+
+void msp_set_scart(struct i2c_client *client, int in, int out)
+{
+	struct msp_state *state = i2c_get_clientdata(client);
+
+	state->in_scart=in;
+
+	if (in >= 1 && in <= 8 && out >= 0 && out <= 2) {
+		if (-1 == scarts[out][in])
+			return;
+
+		state->acb &= ~scarts[out][SCART_MASK];
+		state->acb |=  scarts[out][in];
+	} else
+		state->acb = 0xf60; /* Mute Input and SCART 1 Output */
+
+	v4l_dbg(1, client, "scart switch: %s => %d (ACB=0x%04x)\n",
+						scart_names[in], out, state->acb);
+	msp_write_dsp(client, 0x13, state->acb);
+
+	/* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */
+	msp_write_dem(client, 0x40, state->i2s_mode);
+}
+
+void msp_set_mute(struct i2c_client *client)
+{
+	struct msp_state *state = i2c_get_clientdata(client);
+
+	v4l_dbg(1, client, "mute audio\n");
+	msp_write_dsp(client, 0x0000, 0);
+	msp_write_dsp(client, 0x0007, 1);
+	if (state->has_scart2_out_volume)
+		msp_write_dsp(client, 0x0040, 1);
+	if (state->has_headphones)
+		msp_write_dsp(client, 0x0006, 0);
+}
+
+void msp_set_audio(struct i2c_client *client)
+{
+	struct msp_state *state = i2c_get_clientdata(client);
+	int bal = 0, bass, treble, loudness;
+	int val = 0;
+
+	if (!state->muted)
+		val = (state->volume * 0x7f / 65535) << 8;
+
+	v4l_dbg(1, client, "mute=%s volume=%d\n",
+		state->muted ? "on" : "off", state->volume);
+
+	msp_write_dsp(client, 0x0000, val);
+	msp_write_dsp(client, 0x0007, state->muted ? 0x1 : (val | 0x1));
+	if (state->has_scart2_out_volume)
+		msp_write_dsp(client, 0x0040, state->muted ? 0x1 : (val | 0x1));
+	if (state->has_headphones)
+		msp_write_dsp(client, 0x0006, val);
+	if (!state->has_sound_processing)
+		return;
+
+	if (val)
+		bal = (u8)((state->balance / 256) - 128);
+	bass = ((state->bass - 32768) * 0x60 / 65535) << 8;
+	treble = ((state->treble - 32768) * 0x60 / 65535) << 8;
+	loudness = state->loudness ? ((5 * 4) << 8) : 0;
+
+	v4l_dbg(1, client, "balance=%d bass=%d treble=%d loudness=%d\n",
+		state->balance, state->bass, state->treble, state->loudness);
+
+	msp_write_dsp(client, 0x0001, bal << 8);
+	msp_write_dsp(client, 0x0002, bass);
+	msp_write_dsp(client, 0x0003, treble);
+	msp_write_dsp(client, 0x0004, loudness);
+	if (!state->has_headphones)
+		return;
+	msp_write_dsp(client, 0x0030, bal << 8);
+	msp_write_dsp(client, 0x0031, bass);
+	msp_write_dsp(client, 0x0032, treble);
+	msp_write_dsp(client, 0x0033, loudness);
+}
+
+int msp_modus(struct i2c_client *client)
+{
+	struct msp_state *state = i2c_get_clientdata(client);
+
+	if (state->radio) {
+		v4l_dbg(1, client, "video mode selected to Radio\n");
+		return 0x0003;
+	}
+
+	if (state->v4l2_std & V4L2_STD_PAL) {
+		v4l_dbg(1, client, "video mode selected to PAL\n");
+
+#if 1
+		/* experimental: not sure this works with all chip versions */
+		return 0x7003;
+#else
+		/* previous value, try this if it breaks ... */
+		return 0x1003;
+#endif
+	}
+	if (state->v4l2_std & V4L2_STD_NTSC) {
+		v4l_dbg(1, client, "video mode selected to NTSC\n");
+		return 0x2003;
+	}
+	if (state->v4l2_std & V4L2_STD_SECAM) {
+		v4l_dbg(1, client, "video mode selected to SECAM\n");
+		return 0x0003;
+	}
+	return 0x0003;
+}
+
+/* ------------------------------------------------------------------------ */
+
+
+static void msp_wake_thread(struct i2c_client *client)
+{
+	struct msp_state *state = i2c_get_clientdata(client);
+
+	if (NULL == state->kthread)
+		return;
+	msp_set_mute(client);
+	state->watch_stereo = 0;
+	state->restart = 1;
+	wake_up_interruptible(&state->wq);
+}
+
+int msp_sleep(struct msp_state *state, int timeout)
+{
+	DECLARE_WAITQUEUE(wait, current);
+
+	add_wait_queue(&state->wq, &wait);
+	if (!kthread_should_stop()) {
+		if (timeout < 0) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule();
+		} else {
+			schedule_timeout_interruptible
+						(msecs_to_jiffies(timeout));
+		}
+	}
+
+	remove_wait_queue(&state->wq, &wait);
+	try_to_freeze();
+	return state->restart;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int msp_mode_v4l2_to_v4l1(int rxsubchans)
+{
+	int mode = 0;
+
+	if (rxsubchans & V4L2_TUNER_SUB_STEREO)
+		mode |= VIDEO_SOUND_STEREO;
+	if (rxsubchans & V4L2_TUNER_SUB_LANG2)
+		mode |= VIDEO_SOUND_LANG2;
+	if (rxsubchans & V4L2_TUNER_SUB_LANG1)
+		mode |= VIDEO_SOUND_LANG1;
+	if (mode == 0)
+		mode |= VIDEO_SOUND_MONO;
+	return mode;
+}
+
+static int msp_mode_v4l1_to_v4l2(int mode)
+{
+	if (mode & VIDEO_SOUND_STEREO)
+		return V4L2_TUNER_MODE_STEREO;
+	if (mode & VIDEO_SOUND_LANG2)
+		return V4L2_TUNER_MODE_LANG2;
+	if (mode & VIDEO_SOUND_LANG1)
+		return V4L2_TUNER_MODE_LANG1;
+	return V4L2_TUNER_MODE_MONO;
+}
+
+static void msp_any_detect_stereo(struct i2c_client *client)
+{
+	struct msp_state *state  = i2c_get_clientdata(client);
+
+	switch (state->opmode) {
+	case OPMODE_MANUAL:
+	case OPMODE_AUTODETECT:
+		autodetect_stereo(client);
+		break;
+	case OPMODE_AUTOSELECT:
+		msp34xxg_detect_stereo(client);
+		break;
+	}
+}
+
+static struct v4l2_queryctrl msp_qctrl_std[] = {
+	{
+		.id            = V4L2_CID_AUDIO_VOLUME,
+		.name          = "Volume",
+		.minimum       = 0,
+		.maximum       = 65535,
+		.step          = 65535/100,
+		.default_value = 58880,
+		.flags         = 0,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+	},{
+		.id            = V4L2_CID_AUDIO_MUTE,
+		.name          = "Mute",
+		.minimum       = 0,
+		.maximum       = 1,
+		.step          = 1,
+		.default_value = 1,
+		.flags         = 0,
+		.type          = V4L2_CTRL_TYPE_BOOLEAN,
+	},
+};
+
+static struct v4l2_queryctrl msp_qctrl_sound_processing[] = {
+	{
+		.id            = V4L2_CID_AUDIO_BALANCE,
+		.name          = "Balance",
+		.minimum       = 0,
+		.maximum       = 65535,
+		.step          = 65535/100,
+		.default_value = 32768,
+		.flags         = 0,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+	},{
+		.id            = V4L2_CID_AUDIO_BASS,
+		.name          = "Bass",
+		.minimum       = 0,
+		.maximum       = 65535,
+		.step          = 65535/100,
+		.default_value = 32768,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+	},{
+		.id            = V4L2_CID_AUDIO_TREBLE,
+		.name          = "Treble",
+		.minimum       = 0,
+		.maximum       = 65535,
+		.step          = 65535/100,
+		.default_value = 32768,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+	},{
+		.id            = V4L2_CID_AUDIO_LOUDNESS,
+		.name          = "Loudness",
+		.minimum       = 0,
+		.maximum       = 1,
+		.step          = 1,
+		.default_value = 1,
+		.flags         = 0,
+		.type          = V4L2_CTRL_TYPE_BOOLEAN,
+	},
+};
+
+
+static void msp_any_set_audmode(struct i2c_client *client, int audmode)
+{
+	struct msp_state *state = i2c_get_clientdata(client);
+
+	switch (state->opmode) {
+	case OPMODE_MANUAL:
+	case OPMODE_AUTODETECT:
+		state->watch_stereo = 0;
+		msp3400c_setstereo(client, audmode);
+		break;
+	case OPMODE_AUTOSELECT:
+		msp34xxg_set_audmode(client, audmode);
+		break;
+	}
+}
+
+static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+{
+	struct msp_state *state = i2c_get_clientdata(client);
+
+	switch (ctrl->id) {
+	case V4L2_CID_AUDIO_VOLUME:
+		ctrl->value = state->volume;
+		break;
+
+	case V4L2_CID_AUDIO_MUTE:
+		ctrl->value = state->muted;
+		break;
+
+	case V4L2_CID_AUDIO_BALANCE:
+		if (!state->has_sound_processing)
+			return -EINVAL;
+		ctrl->value = state->balance;
+		break;
+
+	case V4L2_CID_AUDIO_BASS:
+		if (!state->has_sound_processing)
+			return -EINVAL;
+		ctrl->value = state->bass;
+		break;
+
+	case V4L2_CID_AUDIO_TREBLE:
+		if (!state->has_sound_processing)
+			return -EINVAL;
+		ctrl->value = state->treble;
+		break;
+
+	case V4L2_CID_AUDIO_LOUDNESS:
+		if (!state->has_sound_processing)
+			return -EINVAL;
+		ctrl->value = state->loudness;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int msp_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+{
+	struct msp_state *state = i2c_get_clientdata(client);
+
+	switch (ctrl->id) {
+	case V4L2_CID_AUDIO_VOLUME:
+		state->volume = ctrl->value;
+		if (state->volume == 0)
+			state->balance = 32768;
+		break;
+
+	case V4L2_CID_AUDIO_MUTE:
+		if (ctrl->value < 0 || ctrl->value >= 2)
+			return -ERANGE;
+		state->muted = ctrl->value;
+		break;
+
+	case V4L2_CID_AUDIO_BASS:
+		if (!state->has_sound_processing)
+			return -EINVAL;
+		state->bass = ctrl->value;
+		break;
+
+	case V4L2_CID_AUDIO_TREBLE:
+		if (!state->has_sound_processing)
+			return -EINVAL;
+		state->treble = ctrl->value;
+		break;
+
+	case V4L2_CID_AUDIO_LOUDNESS:
+		if (!state->has_sound_processing)
+			return -EINVAL;
+		state->loudness = ctrl->value;
+		break;
+
+	case V4L2_CID_AUDIO_BALANCE:
+		if (!state->has_sound_processing)
+			return -EINVAL;
+		state->balance = ctrl->value;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	msp_set_audio(client);
+	return 0;
+}
+
+static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
+{
+	struct msp_state *state = i2c_get_clientdata(client);
+	u16 *sarg = arg;
+	int scart = 0;
+
+	if (debug >= 2)
+		v4l_i2c_print_ioctl(client, cmd);
+
+	switch (cmd) {
+	case AUDC_SET_INPUT:
+		if (*sarg == state->input)
+			break;
+		state->input = *sarg;
+		switch (*sarg) {
+		case AUDIO_RADIO:
+			/* Hauppauge uses IN2 for the radio */
+			state->mode = MSP_MODE_FM_RADIO;
+			scart       = SCART_IN2;
+			break;
+		case AUDIO_EXTERN_1:
+			/* IN1 is often used for external input ... */
+			state->mode = MSP_MODE_EXTERN;
+			scart       = SCART_IN1;
+			break;
+		case AUDIO_EXTERN_2:
+			/* ... sometimes it is IN2 through ;) */
+			state->mode = MSP_MODE_EXTERN;
+			scart       = SCART_IN2;
+			break;
+		case AUDIO_TUNER:
+			state->mode = -1;
+			break;
+		default:
+			if (*sarg & AUDIO_MUTE)
+				msp_set_scart(client, SCART_MUTE, 0);
+			break;
+		}
+		if (scart) {
+			state->rxsubchans = V4L2_TUNER_SUB_STEREO;
+			state->audmode = V4L2_TUNER_MODE_STEREO;
+			msp_set_scart(client, scart, 0);
+			msp_write_dsp(client, 0x000d, 0x1900);
+			if (state->opmode != OPMODE_AUTOSELECT)
+				msp3400c_setstereo(client, state->audmode);
+		}
+		msp_wake_thread(client);
+		break;
+
+	case AUDC_SET_RADIO:
+		if (state->radio)
+			return 0;
+		state->radio = 1;
+		v4l_dbg(1, client, "switching to radio mode\n");
+		state->watch_stereo = 0;
+		switch (state->opmode) {
+		case OPMODE_MANUAL:
+			/* set msp3400 to FM radio mode */
+			msp3400c_setmode(client, MSP_MODE_FM_RADIO);
+			msp3400c_setcarrier(client, MSP_CARRIER(10.7),
+					    MSP_CARRIER(10.7));
+			msp_set_audio(client);
+			break;
+		case OPMODE_AUTODETECT:
+		case OPMODE_AUTOSELECT:
+			/* the thread will do for us */
+			msp_wake_thread(client);
+			break;
+		}
+		break;
+
+	/* --- v4l ioctls --- */
+	/* take care: bttv does userspace copying, we'll get a
+	   kernel pointer here... */
+	case VIDIOCGAUDIO:
+	{
+		struct video_audio *va = arg;
+
+		va->flags |= VIDEO_AUDIO_VOLUME | VIDEO_AUDIO_MUTABLE;
+		if (state->has_sound_processing)
+			va->flags |= VIDEO_AUDIO_BALANCE |
+				VIDEO_AUDIO_BASS |
+				VIDEO_AUDIO_TREBLE;
+		if (state->muted)
+			va->flags |= VIDEO_AUDIO_MUTE;
+		va->volume = state->volume;
+		va->balance = state->volume ? state->balance : 32768;
+		va->bass = state->bass;
+		va->treble = state->treble;
+
+		if (state->radio)
+			break;
+		if (state->opmode == OPMODE_AUTOSELECT)
+			msp_any_detect_stereo(client);
+		va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans);
+		break;
+	}
+
+	case VIDIOCSAUDIO:
+	{
+		struct video_audio *va = arg;
+
+		state->muted = (va->flags & VIDEO_AUDIO_MUTE);
+		state->volume = va->volume;
+		state->balance = va->balance;
+		state->bass = va->bass;
+		state->treble = va->treble;
+		msp_set_audio(client);
+
+		if (va->mode != 0 && state->radio == 0)
+			msp_any_set_audmode(client, msp_mode_v4l1_to_v4l2(va->mode));
+		break;
+	}
+
+	case VIDIOCSCHAN:
+	{
+		struct video_channel *vc = arg;
+		int update = 0;
+		v4l2_std_id std;
+
+		if (state->radio)
+			update = 1;
+		state->radio = 0;
+		if (vc->norm == VIDEO_MODE_PAL)
+			std = V4L2_STD_PAL;
+		else if (vc->norm == VIDEO_MODE_SECAM)
+			std = V4L2_STD_SECAM;
+		else
+			std = V4L2_STD_NTSC;
+		if (std != state->v4l2_std) {
+			state->v4l2_std = std;
+			update = 1;
+		}
+		if (update)
+			msp_wake_thread(client);
+		break;
+	}
+
+	case VIDIOCSFREQ:
+	case VIDIOC_S_FREQUENCY:
+	{
+		/* new channel -- kick audio carrier scan */
+		msp_wake_thread(client);
+		break;
+	}
+
+	/* msp34xx specific */
+	case MSP_SET_MATRIX:
+	{
+		struct msp_matrix *mspm = arg;
+
+		msp_set_scart(client, mspm->input, mspm->output);
+		break;
+	}
+
+	/* --- v4l2 ioctls --- */
+	case VIDIOC_S_STD:
+	{
+		v4l2_std_id *id = arg;
+		int update = state->radio || state->v4l2_std != *id;
+
+		state->v4l2_std = *id;
+		state->radio = 0;
+		if (update)
+			msp_wake_thread(client);
+		return 0;
+	}
+
+	case VIDIOC_ENUMINPUT:
+	{
+		struct v4l2_input *i = arg;
+
+		if (i->index != 0)
+			return -EINVAL;
+
+		i->type = V4L2_INPUT_TYPE_TUNER;
+		switch (i->index) {
+		case AUDIO_RADIO:
+			strcpy(i->name, "Radio");
+			break;
+		case AUDIO_EXTERN_1:
+			strcpy(i->name, "Extern 1");
+			break;
+		case AUDIO_EXTERN_2:
+			strcpy(i->name, "Extern 2");
+			break;
+		case AUDIO_TUNER:
+			strcpy(i->name, "Television");
+			break;
+		default:
+			return -EINVAL;
+		}
+		return 0;
+	}
+
+	case VIDIOC_G_AUDIO:
+	{
+		struct v4l2_audio *a = arg;
+
+		memset(a, 0, sizeof(*a));
+
+		switch (a->index) {
+		case AUDIO_RADIO:
+			strcpy(a->name, "Radio");
+			break;
+		case AUDIO_EXTERN_1:
+			strcpy(a->name, "Extern 1");
+			break;
+		case AUDIO_EXTERN_2:
+			strcpy(a->name, "Extern 2");
+			break;
+		case AUDIO_TUNER:
+			strcpy(a->name, "Television");
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		msp_any_detect_stereo(client);
+		if (state->audmode == V4L2_TUNER_MODE_STEREO) {
+			a->capability = V4L2_AUDCAP_STEREO;
+		}
+
+		break;
+	}
+
+	case VIDIOC_S_AUDIO:
+	{
+		struct v4l2_audio *sarg = arg;
+
+		switch (sarg->index) {
+		case AUDIO_RADIO:
+			/* Hauppauge uses IN2 for the radio */
+			state->mode = MSP_MODE_FM_RADIO;
+			scart       = SCART_IN2;
+			break;
+		case AUDIO_EXTERN_1:
+			/* IN1 is often used for external input ... */
+			state->mode = MSP_MODE_EXTERN;
+			scart       = SCART_IN1;
+			break;
+		case AUDIO_EXTERN_2:
+			/* ... sometimes it is IN2 through ;) */
+			state->mode = MSP_MODE_EXTERN;
+			scart       = SCART_IN2;
+			break;
+		case AUDIO_TUNER:
+			state->mode = -1;
+			break;
+		}
+		if (scart) {
+			state->rxsubchans = V4L2_TUNER_SUB_STEREO;
+			state->audmode = V4L2_TUNER_MODE_STEREO;
+			msp_set_scart(client, scart, 0);
+			msp_write_dsp(client, 0x000d, 0x1900);
+		}
+		if (sarg->capability == V4L2_AUDCAP_STEREO) {
+			state->audmode = V4L2_TUNER_MODE_STEREO;
+		} else {
+			state->audmode &= ~V4L2_TUNER_MODE_STEREO;
+		}
+		msp_any_set_audmode(client, state->audmode);
+		msp_wake_thread(client);
+		break;
+	}
+
+	case VIDIOC_G_TUNER:
+	{
+		struct v4l2_tuner *vt = arg;
+
+		if (state->radio)
+			break;
+		if (state->opmode == OPMODE_AUTOSELECT)
+			msp_any_detect_stereo(client);
+		vt->audmode    = state->audmode;
+		vt->rxsubchans = state->rxsubchans;
+		vt->capability = V4L2_TUNER_CAP_STEREO |
+			V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
+		break;
+	}
+
+	case VIDIOC_S_TUNER:
+	{
+		struct v4l2_tuner *vt = (struct v4l2_tuner *)arg;
+
+		if (state->radio)
+			break;
+		/* only set audmode */
+		if (vt->audmode != -1 && vt->audmode != 0)
+			msp_any_set_audmode(client, vt->audmode);
+		break;
+	}
+
+	case VIDIOC_G_AUDOUT:
+	{
+		struct v4l2_audioout *a = (struct v4l2_audioout *)arg;
+		int idx = a->index;
+
+		memset(a, 0, sizeof(*a));
+
+		switch (idx) {
+		case 0:
+			strcpy(a->name, "Scart1 Out");
+			break;
+		case 1:
+			strcpy(a->name, "Scart2 Out");
+			break;
+		case 2:
+			strcpy(a->name, "I2S Out");
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+
+	}
+
+	case VIDIOC_S_AUDOUT:
+	{
+		struct v4l2_audioout *a = (struct v4l2_audioout *)arg;
+
+		if (a->index < 0 || a->index > 2)
+			return -EINVAL;
+
+		v4l_dbg(1, client, "Setting audio out on msp34xx to input %i\n", a->index);
+		msp_set_scart(client, state->in_scart, a->index + 1);
+
+		break;
+	}
+
+	case VIDIOC_INT_I2S_CLOCK_FREQ:
+	{
+		u32 *a = (u32 *)arg;
+
+		v4l_dbg(1, client, "Setting I2S speed to %d\n", *a);
+
+		switch (*a) {
+			case 1024000:
+				state->i2s_mode = 0;
+				break;
+			case 2048000:
+				state->i2s_mode = 1;
+				break;
+			default:
+				return -EINVAL;
+		}
+		break;
+	}
+
+	case VIDIOC_QUERYCTRL:
+	{
+		struct v4l2_queryctrl *qc = arg;
+		int i;
+
+		for (i = 0; i < ARRAY_SIZE(msp_qctrl_std); i++)
+			if (qc->id && qc->id == msp_qctrl_std[i].id) {
+				memcpy(qc, &msp_qctrl_std[i], sizeof(*qc));
+				return 0;
+			}
+		if (!state->has_sound_processing)
+			return -EINVAL;
+		for (i = 0; i < ARRAY_SIZE(msp_qctrl_sound_processing); i++)
+			if (qc->id && qc->id == msp_qctrl_sound_processing[i].id) {
+				memcpy(qc, &msp_qctrl_sound_processing[i], sizeof(*qc));
+				return 0;
+			}
+		return -EINVAL;
+	}
+
+	case VIDIOC_G_CTRL:
+		return msp_get_ctrl(client, arg);
+
+	case VIDIOC_S_CTRL:
+		return msp_set_ctrl(client, arg);
+
+	case VIDIOC_LOG_STATUS:
+	{
+		const char *p;
+
+		if (state->opmode == OPMODE_AUTOSELECT)
+			msp_any_detect_stereo(client);
+		v4l_info(client, "%s rev1 = 0x%04x rev2 = 0x%04x\n",
+				client->name, state->rev1, state->rev2);
+		v4l_info(client, "Audio:    volume %d%s\n",
+				state->volume, state->muted ? " (muted)" : "");
+		if (state->has_sound_processing) {
+			v4l_info(client, "Audio:    balance %d bass %d treble %d loudness %s\n",
+					state->balance, state->bass, state->treble,
+					state->loudness ? "on" : "off");
+		}
+		switch (state->mode) {
+		case MSP_MODE_AM_DETECT: p = "AM (for carrier detect)"; break;
+		case MSP_MODE_FM_RADIO: p = "FM Radio"; break;
+		case MSP_MODE_FM_TERRA: p = "Terrestial FM-mono + FM-stereo"; break;
+		case MSP_MODE_FM_SAT: p = "Satellite FM-mono"; break;
+		case MSP_MODE_FM_NICAM1: p = "NICAM/FM (B/G, D/K)"; break;
+		case MSP_MODE_FM_NICAM2: p = "NICAM/FM (I)"; break;
+		case MSP_MODE_AM_NICAM: p = "NICAM/AM (L)"; break;
+		case MSP_MODE_BTSC: p = "BTSC"; break;
+		case MSP_MODE_EXTERN: p = "External input"; break;
+		default: p = "unknown"; break;
+		}
+		if (state->opmode == OPMODE_MANUAL) {
+			v4l_info(client, "Mode:     %s (%s%s)\n", p,
+				(state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
+				(state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
+		} else {
+			v4l_info(client, "Mode:     %s\n", p);
+			v4l_info(client, "Standard: %s (%s%s)\n",
+				msp_standard_std_name(state->std),
+				(state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
+				(state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
+		}
+		v4l_info(client, "ACB:      0x%04x\n", state->acb);
+		break;
+	}
+
+	default:
+		/* nothing */
+		break;
+	}
+	return 0;
+}
+
+static int msp_suspend(struct device * dev, pm_message_t state)
+{
+	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+
+	v4l_dbg(1, client, "suspend\n");
+	msp_reset(client);
+	return 0;
+}
+
+static int msp_resume(struct device * dev)
+{
+	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+
+	v4l_dbg(1, client, "resume\n");
+	msp_wake_thread(client);
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static struct i2c_driver i2c_driver;
+
+static int msp_attach(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *client;
+	struct msp_state *state;
+	int (*thread_func)(void *data) = NULL;
+	int msp_hard;
+	int msp_family;
+	int msp_revision;
+	int msp_product, msp_prod_hi, msp_prod_lo;
+	int msp_rom;
+
+	client = kmalloc(sizeof(*client), GFP_KERNEL);
+	if (client == NULL)
+		return -ENOMEM;
+	memset(client, 0, sizeof(*client));
+	client->addr = address;
+	client->adapter = adapter;
+	client->driver = &i2c_driver;
+	snprintf(client->name, sizeof(client->name) - 1, "msp3400");
+
+	if (msp_reset(client) == -1) {
+		v4l_dbg(1, client, "msp3400 not found\n");
+		kfree(client);
+		return -1;
+	}
+
+	state = kmalloc(sizeof(*state), GFP_KERNEL);
+	if (state == NULL) {
+		kfree(client);
+		return -ENOMEM;
+	}
+	i2c_set_clientdata(client, state);
+
+	memset(state, 0, sizeof(*state));
+	state->v4l2_std = V4L2_STD_NTSC;
+	state->volume = 58880;	/* 0db gain */
+	state->balance = 32768;	/* 0db gain */
+	state->bass = 32768;
+	state->treble = 32768;
+	state->loudness = 0;
+	state->input = -1;
+	state->muted = 0;
+	state->i2s_mode = 0;
+	init_waitqueue_head(&state->wq);
+
+	state->rev1 = msp_read_dsp(client, 0x1e);
+	if (state->rev1 != -1)
+		state->rev2 = msp_read_dsp(client, 0x1f);
+	v4l_dbg(1, client, "rev1=0x%04x, rev2=0x%04x\n", state->rev1, state->rev2);
+	if (state->rev1 == -1 || (state->rev1 == 0 && state->rev2 == 0)) {
+		v4l_dbg(1, client, "not an msp3400 (cannot read chip version)\n");
+		kfree(state);
+		kfree(client);
+		return -1;
+	}
+
+	msp_set_audio(client);
+
+	msp_family = ((state->rev1 >> 4) & 0x0f) + 3;
+	msp_product = (state->rev2 >> 8) & 0xff;
+	msp_prod_hi = msp_product / 10;
+	msp_prod_lo = msp_product % 10;
+	msp_revision = (state->rev1 & 0x0f) + '@';
+	msp_hard = ((state->rev1 >> 8) & 0xff) + '@';
+	msp_rom = state->rev2 & 0x1f;
+	snprintf(client->name, sizeof(client->name), "MSP%d4%02d%c-%c%d",
+			msp_family, msp_product,
+			msp_revision, msp_hard, msp_rom);
+
+	/* Has NICAM support: all mspx41x and mspx45x products have NICAM */
+	state->has_nicam = msp_prod_hi == 1 || msp_prod_hi == 5;
+	/* Has radio support: was added with revision G */
+	state->has_radio = msp_revision >= 'G';
+	/* Has headphones output: not for stripped down products */
+	state->has_headphones = msp_prod_lo < 5;
+	/* Has scart4 input: not in pre D revisions, not in stripped D revs */
+	state->has_scart4 = msp_family >= 4 || (msp_revision >= 'D' && msp_prod_lo < 5);
+	/* Has scart2 and scart3 inputs and scart2 output: not in stripped
+	   down products of the '3' family */
+	state->has_scart23_in_scart2_out = msp_family >= 4 || msp_prod_lo < 5;
+	/* Has scart2 a volume control? Not in pre-D revisions. */
+	state->has_scart2_out_volume = msp_revision > 'C' && state->has_scart23_in_scart2_out;
+	/* Has a configurable i2s out? */
+	state->has_i2s_conf = msp_revision >= 'G' && msp_prod_lo < 7;
+	/* Has subwoofer output: not in pre-D revs and not in stripped down products */
+	state->has_subwoofer = msp_revision >= 'D' && msp_prod_lo < 5;
+	/* Has soundprocessing (bass/treble/balance/loudness/equalizer): not in
+	   stripped down products */
+	state->has_sound_processing = msp_prod_lo < 7;
+	/* Has Virtual Dolby Surround: only in msp34x1 */
+	state->has_virtual_dolby_surround = msp_revision == 'G' && msp_prod_lo == 1;
+	/* Has Virtual Dolby Surround & Dolby Pro Logic: only in msp34x2 */
+	state->has_dolby_pro_logic = msp_revision == 'G' && msp_prod_lo == 2;
+
+	state->opmode = opmode;
+	if (state->opmode == OPMODE_AUTO) {
+		/* MSP revision G and up have both autodetect and autoselect */
+		if (msp_revision >= 'G')
+			state->opmode = OPMODE_AUTOSELECT;
+		/* MSP revision D and up have autodetect */
+		else if (msp_revision >= 'D')
+			state->opmode = OPMODE_AUTODETECT;
+		else
+			state->opmode = OPMODE_MANUAL;
+	}
+
+	/* hello world :-) */
+	v4l_info(client, "%s found @ 0x%x (%s)\n", client->name, address << 1, adapter->name);
+	v4l_info(client, "%s ", client->name);
+	if (state->has_nicam && state->has_radio)
+		printk("supports nicam and radio, ");
+	else if (state->has_nicam)
+		printk("supports nicam, ");
+	else if (state->has_radio)
+		printk("supports radio, ");
+	printk("mode is ");
+
+	/* version-specific initialization */
+	switch (state->opmode) {
+	case OPMODE_MANUAL:
+		printk("manual");
+		thread_func = msp3400c_thread;
+		break;
+	case OPMODE_AUTODETECT:
+		printk("autodetect");
+		thread_func = msp3410d_thread;
+		break;
+	case OPMODE_AUTOSELECT:
+		printk("autodetect and autoselect");
+		thread_func = msp34xxg_thread;
+		break;
+	}
+	printk("\n");
+
+	/* startup control thread if needed */
+	if (thread_func) {
+		state->kthread = kthread_run(thread_func, client, "msp34xx");
+
+		if (state->kthread == NULL)
+			v4l_warn(client, "kernel_thread() failed\n");
+		msp_wake_thread(client);
+	}
+
+	/* done */
+	i2c_attach_client(client);
+
+	return 0;
+}
+
+static int msp_probe(struct i2c_adapter *adapter)
+{
+	if (adapter->class & I2C_CLASS_TV_ANALOG)
+		return i2c_probe(adapter, &addr_data, msp_attach);
+	return 0;
+}
+
+static int msp_detach(struct i2c_client *client)
+{
+	struct msp_state *state = i2c_get_clientdata(client);
+	int err;
+
+	/* shutdown control thread */
+	if (state->kthread) {
+		state->restart = 1;
+		kthread_stop(state->kthread);
+	}
+	msp_reset(client);
+
+	err = i2c_detach_client(client);
+	if (err) {
+		return err;
+	}
+
+	kfree(state);
+	kfree(client);
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* i2c implementation */
+static struct i2c_driver i2c_driver = {
+	.id             = I2C_DRIVERID_MSP3400,
+	.attach_adapter = msp_probe,
+	.detach_client  = msp_detach,
+	.command        = msp_command,
+	.driver = {
+		.name    = "msp3400",
+		.suspend = msp_suspend,
+		.resume  = msp_resume,
+	},
+};
+
+static int __init msp3400_init_module(void)
+{
+	return i2c_add_driver(&i2c_driver);
+}
+
+static void __exit msp3400_cleanup_module(void)
+{
+	i2c_del_driver(&i2c_driver);
+}
+
+module_init(msp3400_init_module);
+module_exit(msp3400_cleanup_module);
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c
new file mode 100644
index 0000000..2b59b68
--- /dev/null
+++ b/drivers/media/video/msp3400-kthreads.c
@@ -0,0 +1,1010 @@
+/*
+ * Programming the mspx4xx sound processor family
+ *
+ * (c) 1997-2001 Gerd Knorr <kraxel@bytesex.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/videodev.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+#include <media/audiochip.h>
+#include <linux/kthread.h>
+#include <linux/suspend.h>
+#include "msp3400.h"
+
+/* this one uses the automatic sound standard detection of newer msp34xx
+   chip versions */
+static struct {
+	int retval;
+	int main, second;
+	char *name;
+} msp_stdlist[] = {
+	{ 0x0000, 0, 0, "could not detect sound standard" },
+	{ 0x0001, 0, 0, "autodetect start" },
+	{ 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72), "4.5/4.72  M Dual FM-Stereo" },
+	{ 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875), "5.5/5.74  B/G Dual FM-Stereo" },
+	{ 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25  D/K1 Dual FM-Stereo" },
+	{ 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74  D/K2 Dual FM-Stereo" },
+	{ 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5  D/K FM-Mono (HDEV3)" },
+	{ 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85  B/G NICAM FM" },
+	{ 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85  L NICAM AM" },
+	{ 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55  I NICAM FM" },
+	{ 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85  D/K NICAM FM" },
+	{ 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85  D/K NICAM FM (HDEV2)" },
+	{ 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5  M BTSC-Stereo" },
+	{ 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5  M BTSC-Mono + SAP" },
+	{ 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5  M EIA-J Japan Stereo" },
+	{ 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7), "10.7  FM-Stereo Radio" },
+	{ 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5  SAT-Mono" },
+	{ 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20), "7.02/7.20  SAT-Stereo" },
+	{ 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2), "7.2  SAT ADR" },
+	{     -1, 0, 0, NULL }, /* EOF */
+};
+
+static struct msp3400c_init_data_dem {
+	int fir1[6];
+	int fir2[6];
+	int cdo1;
+	int cdo2;
+	int ad_cv;
+	int mode_reg;
+	int dsp_src;
+	int dsp_matrix;
+} msp3400c_init_data[] = {
+	{	/* AM (for carrier detect / msp3400) */
+		{75, 19, 36, 35, 39, 40},
+		{75, 19, 36, 35, 39, 40},
+		MSP_CARRIER(5.5), MSP_CARRIER(5.5),
+		0x00d0, 0x0500, 0x0020, 0x3000
+	},{	/* AM (for carrier detect / msp3410) */
+		{-1, -1, -8, 2, 59, 126},
+		{-1, -1, -8, 2, 59, 126},
+		MSP_CARRIER(5.5), MSP_CARRIER(5.5),
+		0x00d0, 0x0100, 0x0020, 0x3000
+	},{	/* FM Radio */
+		{-8, -8, 4, 6, 78, 107},
+		{-8, -8, 4, 6, 78, 107},
+		MSP_CARRIER(10.7), MSP_CARRIER(10.7),
+		0x00d0, 0x0480, 0x0020, 0x3000
+	},{	/* Terrestial FM-mono + FM-stereo */
+		{3, 18, 27, 48, 66, 72},
+		{3, 18, 27, 48, 66, 72},
+		MSP_CARRIER(5.5), MSP_CARRIER(5.5),
+		0x00d0, 0x0480, 0x0030, 0x3000
+	},{	/* Sat FM-mono */
+		{ 1, 9, 14, 24, 33, 37},
+		{ 3, 18, 27, 48, 66, 72},
+		MSP_CARRIER(6.5), MSP_CARRIER(6.5),
+		0x00c6, 0x0480, 0x0000, 0x3000
+	},{	/* NICAM/FM --  B/G (5.5/5.85), D/K (6.5/5.85) */
+		{-2, -8, -10, 10, 50, 86},
+		{3, 18, 27, 48, 66, 72},
+		MSP_CARRIER(5.5), MSP_CARRIER(5.5),
+		0x00d0, 0x0040, 0x0120, 0x3000
+	},{	/* NICAM/FM -- I (6.0/6.552) */
+		{2, 4, -6, -4, 40, 94},
+		{3, 18, 27, 48, 66, 72},
+		MSP_CARRIER(6.0), MSP_CARRIER(6.0),
+		0x00d0, 0x0040, 0x0120, 0x3000
+	},{	/* NICAM/AM -- L (6.5/5.85) */
+		{-2, -8, -10, 10, 50, 86},
+		{-4, -12, -9, 23, 79, 126},
+		MSP_CARRIER(6.5), MSP_CARRIER(6.5),
+		0x00c6, 0x0140, 0x0120, 0x7c03
+	},
+};
+
+struct msp3400c_carrier_detect {
+	int   cdo;
+	char *name;
+};
+
+static struct msp3400c_carrier_detect msp3400c_carrier_detect_main[] = {
+	/* main carrier */
+	{ MSP_CARRIER(4.5),        "4.5   NTSC"                   },
+	{ MSP_CARRIER(5.5),        "5.5   PAL B/G"                },
+	{ MSP_CARRIER(6.0),        "6.0   PAL I"                  },
+	{ MSP_CARRIER(6.5),        "6.5   PAL D/K + SAT + SECAM"  }
+};
+
+static struct msp3400c_carrier_detect msp3400c_carrier_detect_55[] = {
+	/* PAL B/G */
+	{ MSP_CARRIER(5.7421875),  "5.742 PAL B/G FM-stereo"     },
+	{ MSP_CARRIER(5.85),       "5.85  PAL B/G NICAM"         }
+};
+
+static struct msp3400c_carrier_detect msp3400c_carrier_detect_65[] = {
+	/* PAL SAT / SECAM */
+	{ MSP_CARRIER(5.85),       "5.85  PAL D/K + SECAM NICAM" },
+	{ MSP_CARRIER(6.2578125),  "6.25  PAL D/K1 FM-stereo" },
+	{ MSP_CARRIER(6.7421875),  "6.74  PAL D/K2 FM-stereo" },
+	{ MSP_CARRIER(7.02),       "7.02  PAL SAT FM-stereo s/b" },
+	{ MSP_CARRIER(7.20),       "7.20  PAL SAT FM-stereo s"   },
+	{ MSP_CARRIER(7.38),       "7.38  PAL SAT FM-stereo b"   },
+};
+
+/* ------------------------------------------------------------------------ */
+
+const char *msp_standard_std_name(int std)
+{
+	int i;
+
+	for (i = 0; msp_stdlist[i].name != NULL; i++)
+		if (msp_stdlist[i].retval == std)
+			return msp_stdlist[i].name;
+	return "unknown";
+}
+
+void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2)
+{
+	msp_write_dem(client, 0x0093, cdo1 & 0xfff);
+	msp_write_dem(client, 0x009b, cdo1 >> 12);
+	msp_write_dem(client, 0x00a3, cdo2 & 0xfff);
+	msp_write_dem(client, 0x00ab, cdo2 >> 12);
+	msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/
+}
+
+void msp3400c_setmode(struct i2c_client *client, int type)
+{
+	struct msp_state *state = i2c_get_clientdata(client);
+	int i;
+
+	v4l_dbg(1, client, "setmode: %d\n", type);
+	state->mode       = type;
+	state->audmode    = V4L2_TUNER_MODE_MONO;
+	state->rxsubchans = V4L2_TUNER_SUB_MONO;
+
+	msp_write_dem(client, 0x00bb, msp3400c_init_data[type].ad_cv);
+
+	for (i = 5; i >= 0; i--)               /* fir 1 */
+		msp_write_dem(client, 0x0001, msp3400c_init_data[type].fir1[i]);
+
+	msp_write_dem(client, 0x0005, 0x0004); /* fir 2 */
+	msp_write_dem(client, 0x0005, 0x0040);
+	msp_write_dem(client, 0x0005, 0x0000);
+	for (i = 5; i >= 0; i--)
+		msp_write_dem(client, 0x0005, msp3400c_init_data[type].fir2[i]);
+
+	msp_write_dem(client, 0x0083, msp3400c_init_data[type].mode_reg);
+
+	msp3400c_setcarrier(client, msp3400c_init_data[type].cdo1,
+			    msp3400c_init_data[type].cdo2);
+
+	msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/
+
+	if (dolby) {
+		msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */
+		msp_write_dsp(client, 0x0009, 0x0620); /* I2S2 */
+		msp_write_dsp(client, 0x000b, msp3400c_init_data[type].dsp_src);
+	} else {
+		msp_write_dsp(client, 0x0008, msp3400c_init_data[type].dsp_src);
+		msp_write_dsp(client, 0x0009, msp3400c_init_data[type].dsp_src);
+		msp_write_dsp(client, 0x000b, msp3400c_init_data[type].dsp_src);
+	}
+	msp_write_dsp(client, 0x000a, msp3400c_init_data[type].dsp_src);
+	msp_write_dsp(client, 0x000e, msp3400c_init_data[type].dsp_matrix);
+
+	if (state->has_nicam) {
+		/* nicam prescale */
+		msp_write_dsp(client, 0x0010, 0x5a00); /* was: 0x3000 */
+	}
+}
+
+/* turn on/off nicam + stereo */
+void msp3400c_setstereo(struct i2c_client *client, int mode)
+{
+	static char *strmode[] = { "mono", "stereo", "lang2", "lang1" };
+	struct msp_state *state = i2c_get_clientdata(client);
+	int nicam = 0;		/* channel source: FM/AM or nicam */
+	int src = 0;
+
+	if (state->opmode == OPMODE_AUTOSELECT) {
+		/* this method would break everything, let's make sure
+		 * it's never called
+		 */
+		v4l_dbg(1, client, "setstereo called with mode=%d instead of set_source (ignored)\n",
+		     mode);
+		return;
+	}
+
+	/* switch demodulator */
+	switch (state->mode) {
+	case MSP_MODE_FM_TERRA:
+		v4l_dbg(1, client, "FM setstereo: %s\n", strmode[mode]);
+		msp3400c_setcarrier(client, state->second, state->main);
+		switch (mode) {
+		case V4L2_TUNER_MODE_STEREO:
+			msp_write_dsp(client, 0x000e, 0x3001);
+			break;
+		case V4L2_TUNER_MODE_MONO:
+		case V4L2_TUNER_MODE_LANG1:
+		case V4L2_TUNER_MODE_LANG2:
+			msp_write_dsp(client, 0x000e, 0x3000);
+			break;
+		}
+		break;
+	case MSP_MODE_FM_SAT:
+		v4l_dbg(1, client, "SAT setstereo: %s\n", strmode[mode]);
+		switch (mode) {
+		case V4L2_TUNER_MODE_MONO:
+			msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
+			break;
+		case V4L2_TUNER_MODE_STEREO:
+			msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
+			break;
+		case V4L2_TUNER_MODE_LANG1:
+			msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
+			break;
+		case V4L2_TUNER_MODE_LANG2:
+			msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
+			break;
+		}
+		break;
+	case MSP_MODE_FM_NICAM1:
+	case MSP_MODE_FM_NICAM2:
+	case MSP_MODE_AM_NICAM:
+		v4l_dbg(1, client, "NICAM setstereo: %s\n",strmode[mode]);
+		msp3400c_setcarrier(client,state->second,state->main);
+		if (state->nicam_on)
+			nicam=0x0100;
+		break;
+	case MSP_MODE_BTSC:
+		v4l_dbg(1, client, "BTSC setstereo: %s\n",strmode[mode]);
+		nicam=0x0300;
+		break;
+	case MSP_MODE_EXTERN:
+		v4l_dbg(1, client, "extern setstereo: %s\n",strmode[mode]);
+		nicam = 0x0200;
+		break;
+	case MSP_MODE_FM_RADIO:
+		v4l_dbg(1, client, "FM-Radio setstereo: %s\n",strmode[mode]);
+		break;
+	default:
+		v4l_dbg(1, client, "mono setstereo\n");
+		return;
+	}
+
+	/* switch audio */
+	switch (mode) {
+	case V4L2_TUNER_MODE_STEREO:
+		src = 0x0020 | nicam;
+		break;
+	case V4L2_TUNER_MODE_MONO:
+		if (state->mode == MSP_MODE_AM_NICAM) {
+			v4l_dbg(1, client, "switching to AM mono\n");
+			/* AM mono decoding is handled by tuner, not MSP chip */
+			/* SCART switching control register */
+			msp_set_scart(client, SCART_MONO, 0);
+			src = 0x0200;
+			break;
+		}
+	case V4L2_TUNER_MODE_LANG1:
+		src = 0x0000 | nicam;
+		break;
+	case V4L2_TUNER_MODE_LANG2:
+		src = 0x0010 | nicam;
+		break;
+	}
+	v4l_dbg(1, client, "setstereo final source/matrix = 0x%x\n", src);
+
+	if (dolby) {
+		msp_write_dsp(client, 0x0008, 0x0520);
+		msp_write_dsp(client, 0x0009, 0x0620);
+		msp_write_dsp(client, 0x000a, src);
+		msp_write_dsp(client, 0x000b, src);
+	} else {
+		msp_write_dsp(client, 0x0008, src);
+		msp_write_dsp(client, 0x0009, src);
+		msp_write_dsp(client, 0x000a, src);
+		msp_write_dsp(client, 0x000b, src);
+		msp_write_dsp(client, 0x000c, src);
+		if (state->has_scart23_in_scart2_out)
+			msp_write_dsp(client, 0x0041, src);
+	}
+}
+
+static void msp3400c_print_mode(struct i2c_client *client)
+{
+	struct msp_state *state = i2c_get_clientdata(client);
+
+	if (state->main == state->second) {
+		v4l_dbg(1, client, "mono sound carrier: %d.%03d MHz\n",
+		       state->main / 910000, (state->main / 910) % 1000);
+	} else {
+		v4l_dbg(1, client, "main sound carrier: %d.%03d MHz\n",
+		       state->main / 910000, (state->main / 910) % 1000);
+	}
+	if (state->mode == MSP_MODE_FM_NICAM1 || state->mode == MSP_MODE_FM_NICAM2)
+		v4l_dbg(1, client, "NICAM/FM carrier  : %d.%03d MHz\n",
+		       state->second / 910000, (state->second/910) % 1000);
+	if (state->mode == MSP_MODE_AM_NICAM)
+		v4l_dbg(1, client, "NICAM/AM carrier  : %d.%03d MHz\n",
+		       state->second / 910000, (state->second / 910) % 1000);
+	if (state->mode == MSP_MODE_FM_TERRA && state->main != state->second) {
+		v4l_dbg(1, client, "FM-stereo carrier : %d.%03d MHz\n",
+		       state->second / 910000, (state->second / 910) % 1000);
+	}
+}
+
+/* ----------------------------------------------------------------------- */
+
+int autodetect_stereo(struct i2c_client *client)
+{
+	struct msp_state *state = i2c_get_clientdata(client);
+	int val;
+	int rxsubchans = state->rxsubchans;
+	int newnicam   = state->nicam_on;
+	int update = 0;
+
+	switch (state->mode) {
+	case MSP_MODE_FM_TERRA:
+		val = msp_read_dsp(client, 0x18);
+		if (val > 32767)
+			val -= 65536;
+		v4l_dbg(2, client, "stereo detect register: %d\n", val);
+		if (val > 4096) {
+			rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
+		} else if (val < -4096) {
+			rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+		} else {
+			rxsubchans = V4L2_TUNER_SUB_MONO;
+		}
+		newnicam = 0;
+		break;
+	case MSP_MODE_FM_NICAM1:
+	case MSP_MODE_FM_NICAM2:
+	case MSP_MODE_AM_NICAM:
+		val = msp_read_dem(client, 0x23);
+		v4l_dbg(2, client, "nicam sync=%d, mode=%d\n",
+			val & 1, (val & 0x1e) >> 1);
+
+		if (val & 1) {
+			/* nicam synced */
+			switch ((val & 0x1e) >> 1)  {
+			case 0:
+			case 8:
+				rxsubchans = V4L2_TUNER_SUB_STEREO;
+				break;
+			case 1:
+			case 9:
+				rxsubchans = V4L2_TUNER_SUB_MONO
+					| V4L2_TUNER_SUB_LANG1;
+				break;
+			case 2:
+			case 10:
+				rxsubchans = V4L2_TUNER_SUB_MONO
+					| V4L2_TUNER_SUB_LANG1
+					| V4L2_TUNER_SUB_LANG2;
+				break;
+			default:
+				rxsubchans = V4L2_TUNER_SUB_MONO;
+				break;
+			}
+			newnicam = 1;
+		} else {
+			newnicam = 0;
+			rxsubchans = V4L2_TUNER_SUB_MONO;
+		}
+		break;
+	case MSP_MODE_BTSC:
+		val = msp_read_dem(client, 0x200);
+		v4l_dbg(2, client, "status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
+			val,
+			(val & 0x0002) ? "no"     : "yes",
+			(val & 0x0004) ? "no"     : "yes",
+			(val & 0x0040) ? "stereo" : "mono",
+			(val & 0x0080) ? ", nicam 2nd mono" : "",
+			(val & 0x0100) ? ", bilingual/SAP"  : "");
+		rxsubchans = V4L2_TUNER_SUB_MONO;
+		if (val & 0x0040) rxsubchans |= V4L2_TUNER_SUB_STEREO;
+		if (val & 0x0100) rxsubchans |= V4L2_TUNER_SUB_LANG1;
+		break;
+	}
+	if (rxsubchans != state->rxsubchans) {
+		update = 1;
+		v4l_dbg(1, client, "watch: rxsubchans %d => %d\n",
+			state->rxsubchans,rxsubchans);
+		state->rxsubchans = rxsubchans;
+	}
+	if (newnicam != state->nicam_on) {
+		update = 1;
+		v4l_dbg(1, client, "watch: nicam %d => %d\n",
+			state->nicam_on,newnicam);
+		state->nicam_on = newnicam;
+	}
+	return update;
+}
+
+/*
+ * A kernel thread for msp3400 control -- we don't want to block the
+ * in the ioctl while doing the sound carrier & stereo detect
+ */
+/* stereo/multilang monitoring */
+static void watch_stereo(struct i2c_client *client)
+{
+	struct msp_state *state = i2c_get_clientdata(client);
+
+	if (autodetect_stereo(client)) {
+		if (state->rxsubchans & V4L2_TUNER_SUB_STEREO)
+			msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO);
+		else if (state->rxsubchans & V4L2_TUNER_SUB_LANG1)
+			msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1);
+		else
+			msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
+	}
+
+	if (once)
+		state->watch_stereo = 0;
+}
+
+int msp3400c_thread(void *data)
+{
+	struct i2c_client *client = data;
+	struct msp_state *state = i2c_get_clientdata(client);
+	struct msp3400c_carrier_detect *cd;
+	int count, max1,max2,val1,val2, val,this;
+
+
+	v4l_dbg(1, client, "msp3400 daemon started\n");
+	for (;;) {
+		v4l_dbg(2, client, "msp3400 thread: sleep\n");
+		msp_sleep(state, -1);
+		v4l_dbg(2, client, "msp3400 thread: wakeup\n");
+
+	restart:
+		v4l_dbg(1, client, "thread: restart scan\n");
+		state->restart = 0;
+		if (kthread_should_stop())
+			break;
+
+		if (state->radio || MSP_MODE_EXTERN == state->mode) {
+			/* no carrier scan, just unmute */
+			v4l_dbg(1, client, "thread: no carrier scan\n");
+			msp_set_audio(client);
+			continue;
+		}
+
+		/* mute */
+		msp_set_mute(client);
+		msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ );
+		val1 = val2 = 0;
+		max1 = max2 = -1;
+		state->watch_stereo = 0;
+
+		/* some time for the tuner to sync */
+		if (msp_sleep(state,200))
+			goto restart;
+
+		/* carrier detect pass #1 -- main carrier */
+		cd = msp3400c_carrier_detect_main;
+		count = ARRAY_SIZE(msp3400c_carrier_detect_main);
+
+		if (amsound && (state->v4l2_std & V4L2_STD_SECAM)) {
+			/* autodetect doesn't work well with AM ... */
+			max1 = 3;
+			count = 0;
+			v4l_dbg(1, client, "AM sound override\n");
+		}
+
+		for (this = 0; this < count; this++) {
+			msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
+			if (msp_sleep(state,100))
+				goto restart;
+			val = msp_read_dsp(client, 0x1b);
+			if (val > 32767)
+				val -= 65536;
+			if (val1 < val)
+				val1 = val, max1 = this;
+			v4l_dbg(1, client, "carrier1 val: %5d / %s\n", val,cd[this].name);
+		}
+
+		/* carrier detect pass #2 -- second (stereo) carrier */
+		switch (max1) {
+		case 1: /* 5.5 */
+			cd = msp3400c_carrier_detect_55;
+			count = ARRAY_SIZE(msp3400c_carrier_detect_55);
+			break;
+		case 3: /* 6.5 */
+			cd = msp3400c_carrier_detect_65;
+			count = ARRAY_SIZE(msp3400c_carrier_detect_65);
+			break;
+		case 0: /* 4.5 */
+		case 2: /* 6.0 */
+		default:
+			cd = NULL;
+			count = 0;
+			break;
+		}
+
+		if (amsound && (state->v4l2_std & V4L2_STD_SECAM)) {
+			/* autodetect doesn't work well with AM ... */
+			cd = NULL;
+			count = 0;
+			max2 = 0;
+		}
+		for (this = 0; this < count; this++) {
+			msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
+			if (msp_sleep(state,100))
+				goto restart;
+			val = msp_read_dsp(client, 0x1b);
+			if (val > 32767)
+				val -= 65536;
+			if (val2 < val)
+				val2 = val, max2 = this;
+			v4l_dbg(1, client, "carrier2 val: %5d / %s\n", val,cd[this].name);
+		}
+
+		/* program the msp3400 according to the results */
+		state->main   = msp3400c_carrier_detect_main[max1].cdo;
+		switch (max1) {
+		case 1: /* 5.5 */
+			if (max2 == 0) {
+				/* B/G FM-stereo */
+				state->second = msp3400c_carrier_detect_55[max2].cdo;
+				msp3400c_setmode(client, MSP_MODE_FM_TERRA);
+				state->nicam_on = 0;
+				msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
+				state->watch_stereo = 1;
+			} else if (max2 == 1 && state->has_nicam) {
+				/* B/G NICAM */
+				state->second = msp3400c_carrier_detect_55[max2].cdo;
+				msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
+				state->nicam_on = 1;
+				msp3400c_setcarrier(client, state->second, state->main);
+				state->watch_stereo = 1;
+			} else {
+				goto no_second;
+			}
+			break;
+		case 2: /* 6.0 */
+			/* PAL I NICAM */
+			state->second = MSP_CARRIER(6.552);
+			msp3400c_setmode(client, MSP_MODE_FM_NICAM2);
+			state->nicam_on = 1;
+			msp3400c_setcarrier(client, state->second, state->main);
+			state->watch_stereo = 1;
+			break;
+		case 3: /* 6.5 */
+			if (max2 == 1 || max2 == 2) {
+				/* D/K FM-stereo */
+				state->second = msp3400c_carrier_detect_65[max2].cdo;
+				msp3400c_setmode(client, MSP_MODE_FM_TERRA);
+				state->nicam_on = 0;
+				msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
+				state->watch_stereo = 1;
+			} else if (max2 == 0 && (state->v4l2_std & V4L2_STD_SECAM)) {
+				/* L NICAM or AM-mono */
+				state->second = msp3400c_carrier_detect_65[max2].cdo;
+				msp3400c_setmode(client, MSP_MODE_AM_NICAM);
+				state->nicam_on = 0;
+				msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
+				msp3400c_setcarrier(client, state->second, state->main);
+				/* volume prescale for SCART (AM mono input) */
+				msp_write_dsp(client, 0x000d, 0x1900);
+				state->watch_stereo = 1;
+			} else if (max2 == 0 && state->has_nicam) {
+				/* D/K NICAM */
+				state->second = msp3400c_carrier_detect_65[max2].cdo;
+				msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
+				state->nicam_on = 1;
+				msp3400c_setcarrier(client, state->second, state->main);
+				state->watch_stereo = 1;
+			} else {
+				goto no_second;
+			}
+			break;
+		case 0: /* 4.5 */
+		default:
+		no_second:
+			state->second = msp3400c_carrier_detect_main[max1].cdo;
+			msp3400c_setmode(client, MSP_MODE_FM_TERRA);
+			state->nicam_on = 0;
+			msp3400c_setcarrier(client, state->second, state->main);
+			state->rxsubchans = V4L2_TUNER_SUB_MONO;
+			msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
+			break;
+		}
+
+		/* unmute */
+		msp_set_audio(client);
+
+		if (debug)
+			msp3400c_print_mode(client);
+
+		/* monitor tv audio mode */
+		while (state->watch_stereo) {
+			if (msp_sleep(state,5000))
+				goto restart;
+			watch_stereo(client);
+		}
+	}
+	v4l_dbg(1, client, "thread: exit\n");
+	return 0;
+}
+
+
+int msp3410d_thread(void *data)
+{
+	struct i2c_client *client = data;
+	struct msp_state *state = i2c_get_clientdata(client);
+	int val, i, std;
+
+	v4l_dbg(1, client, "msp3410 daemon started\n");
+
+	for (;;) {
+		v4l_dbg(2, client, "msp3410 thread: sleep\n");
+		msp_sleep(state,-1);
+		v4l_dbg(2, client, "msp3410 thread: wakeup\n");
+
+	restart:
+		v4l_dbg(1, client, "thread: restart scan\n");
+		state->restart = 0;
+		if (kthread_should_stop())
+			break;
+
+		if (state->mode == MSP_MODE_EXTERN) {
+			/* no carrier scan needed, just unmute */
+			v4l_dbg(1, client, "thread: no carrier scan\n");
+			msp_set_audio(client);
+			continue;
+		}
+
+		/* put into sane state (and mute) */
+		msp_reset(client);
+
+		/* some time for the tuner to sync */
+		if (msp_sleep(state,200))
+			goto restart;
+
+		/* start autodetect */
+		if (state->radio)
+			std = 0x40;
+		else
+			std = (state->v4l2_std & V4L2_STD_NTSC) ? 0x20 : 1;
+		state->watch_stereo = 0;
+
+		if (debug)
+			v4l_dbg(1, client, "setting standard: %s (0x%04x)\n",
+			       msp_standard_std_name(std), std);
+
+		if (std != 1) {
+			/* programmed some specific mode */
+			val = std;
+		} else {
+			/* triggered autodetect */
+			msp_write_dem(client, 0x20, std);
+			for (;;) {
+				if (msp_sleep(state, 100))
+					goto restart;
+
+				/* check results */
+				val = msp_read_dem(client, 0x7e);
+				if (val < 0x07ff)
+					break;
+				v4l_dbg(1, client, "detection still in progress\n");
+			}
+		}
+		for (i = 0; msp_stdlist[i].name != NULL; i++)
+			if (msp_stdlist[i].retval == val)
+				break;
+		v4l_dbg(1, client, "current standard: %s (0x%04x)\n",
+			msp_standard_std_name(val), val);
+		state->main   = msp_stdlist[i].main;
+		state->second = msp_stdlist[i].second;
+		state->std = val;
+
+		if (amsound && !state->radio && (state->v4l2_std & V4L2_STD_SECAM) &&
+				(val != 0x0009)) {
+			/* autodetection has failed, let backup */
+			v4l_dbg(1, client, "autodetection failed,"
+				" switching to backup standard: %s (0x%04x)\n",
+				msp_stdlist[8].name ? msp_stdlist[8].name : "unknown",val);
+			val = 0x0009;
+			msp_write_dem(client, 0x20, val);
+		}
+
+		/* set various prescales */
+		msp_write_dsp(client, 0x0d, 0x1900); /* scart */
+		msp_write_dsp(client, 0x0e, 0x2403); /* FM */
+		msp_write_dsp(client, 0x10, 0x5a00); /* nicam */
+
+		/* set stereo */
+		switch (val) {
+		case 0x0008: /* B/G NICAM */
+		case 0x000a: /* I NICAM */
+			if (val == 0x0008)
+				state->mode = MSP_MODE_FM_NICAM1;
+			else
+				state->mode = MSP_MODE_FM_NICAM2;
+			/* just turn on stereo */
+			state->rxsubchans = V4L2_TUNER_SUB_STEREO;
+			state->nicam_on = 1;
+			state->watch_stereo = 1;
+			msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
+			break;
+		case 0x0009:
+			state->mode = MSP_MODE_AM_NICAM;
+			state->rxsubchans = V4L2_TUNER_SUB_MONO;
+			state->nicam_on = 1;
+			msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO);
+			state->watch_stereo = 1;
+			break;
+		case 0x0020: /* BTSC */
+			/* just turn on stereo */
+			state->mode = MSP_MODE_BTSC;
+			state->rxsubchans = V4L2_TUNER_SUB_STEREO;
+			state->nicam_on = 0;
+			state->watch_stereo = 1;
+			msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
+			break;
+		case 0x0040: /* FM radio */
+			state->mode = MSP_MODE_FM_RADIO;
+			state->rxsubchans = V4L2_TUNER_SUB_STEREO;
+			state->audmode = V4L2_TUNER_MODE_STEREO;
+			state->nicam_on = 0;
+			state->watch_stereo = 0;
+			/* not needed in theory if we have radio, but
+			   short programming enables carrier mute */
+			msp3400c_setmode(client, MSP_MODE_FM_RADIO);
+			msp3400c_setcarrier(client, MSP_CARRIER(10.7),
+					    MSP_CARRIER(10.7));
+			/* scart routing */
+			msp_set_scart(client,SCART_IN2,0);
+			/* msp34xx does radio decoding */
+			msp_write_dsp(client, 0x08, 0x0020);
+			msp_write_dsp(client, 0x09, 0x0020);
+			msp_write_dsp(client, 0x0b, 0x0020);
+			break;
+		case 0x0003:
+		case 0x0004:
+		case 0x0005:
+			state->mode = MSP_MODE_FM_TERRA;
+			state->rxsubchans = V4L2_TUNER_SUB_MONO;
+			state->audmode = V4L2_TUNER_MODE_MONO;
+			state->nicam_on = 0;
+			state->watch_stereo = 1;
+			break;
+		}
+
+		/* unmute, restore misc registers */
+		msp_set_audio(client);
+		msp_write_dsp(client, 0x13, state->acb);
+		if (state->has_i2s_conf)
+			msp_write_dem(client, 0x40, state->i2s_mode);
+
+		/* monitor tv audio mode */
+		while (state->watch_stereo) {
+			if (msp_sleep(state,5000))
+				goto restart;
+			watch_stereo(client);
+		}
+	}
+	v4l_dbg(1, client, "thread: exit\n");
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* msp34xxG + (autoselect no-thread)                                          */
+/* this one uses both automatic standard detection and automatic sound     */
+/* select which are available in the newer G versions                      */
+/* struct msp: only norm, acb and source are really used in this mode      */
+
+/* set the same 'source' for the loudspeaker, scart and quasi-peak detector
+ * the value for source is the same as bit 15:8 of DSP registers 0x08,
+ * 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B
+ *
+ * this function replaces msp3400c_setstereo
+ */
+static void msp34xxg_set_source(struct i2c_client *client, int source)
+{
+	struct msp_state *state = i2c_get_clientdata(client);
+
+	/* fix matrix mode to stereo and let the msp choose what
+	 * to output according to 'source', as recommended
+	 * for MONO (source==0) downmixing set bit[7:0] to 0x30
+	 */
+	int value = (source & 0x07) << 8 | (source == 0 ? 0x30 : 0x20);
+
+	v4l_dbg(1, client, "set source to %d (0x%x)\n", source, value);
+	/* Loudspeaker Output */
+	msp_write_dsp(client, 0x08, value);
+	/* SCART1 DA Output */
+	msp_write_dsp(client, 0x0a, value);
+	/* Quasi-peak detector */
+	msp_write_dsp(client, 0x0c, value);
+	/*
+	 * set identification threshold. Personally, I
+	 * I set it to a higher value that the default
+	 * of 0x190 to ignore noisy stereo signals.
+	 * this needs tuning. (recommended range 0x00a0-0x03c0)
+	 * 0x7f0 = forced mono mode
+	 */
+	/* a2 threshold for stereo/bilingual */
+	msp_write_dem(client, 0x22, stereo_threshold);
+	state->source = source;
+}
+
+/* (re-)initialize the msp34xxg, according to the current norm in state->norm
+ * return 0 if it worked, -1 if it failed
+ */
+static int msp34xxg_reset(struct i2c_client *client)
+{
+	struct msp_state *state = i2c_get_clientdata(client);
+	int modus, std;
+
+	if (msp_reset(client))
+		return -1;
+
+	/* make sure that input/output is muted (paranoid mode) */
+	/* ACB, mute DSP input, mute SCART 1 */
+	if (msp_write_dsp(client, 0x13, 0x0f20))
+		return -1;
+
+	if (state->has_i2s_conf)
+		msp_write_dem(client, 0x40, state->i2s_mode);
+
+	/* step-by-step initialisation, as described in the manual */
+	modus = msp_modus(client);
+	if (state->radio)
+		std = 0x40;
+	else
+		std = (state->v4l2_std & V4L2_STD_NTSC) ? 0x20 : 1;
+	modus &= ~0x03; /* STATUS_CHANGE = 0 */
+	modus |= 0x01;  /* AUTOMATIC_SOUND_DETECTION = 1 */
+	if (msp_write_dem(client, 0x30, modus))
+		return -1;
+	if (msp_write_dem(client, 0x20, std))
+		return -1;
+
+	/* write the dsps that may have an influence on
+	   standard/audio autodetection right now */
+	msp34xxg_set_source(client, state->source);
+
+	/* AM/FM Prescale [15:8] 75khz deviation */
+	if (msp_write_dsp(client, 0x0e, 0x3000))
+		return -1;
+
+	/* NICAM Prescale 9db gain (as recommended) */
+	if (msp_write_dsp(client, 0x10, 0x5a00))
+		return -1;
+
+	return 0;
+}
+
+int msp34xxg_thread(void *data)
+{
+	struct i2c_client *client = data;
+	struct msp_state *state = i2c_get_clientdata(client);
+	int val, std, i;
+
+	v4l_dbg(1, client, "msp34xxg daemon started\n");
+
+	state->source = 1; /* default */
+	for (;;) {
+		v4l_dbg(2, client, "msp34xxg thread: sleep\n");
+		msp_sleep(state, -1);
+		v4l_dbg(2, client, "msp34xxg thread: wakeup\n");
+
+	restart:
+		v4l_dbg(1, client, "thread: restart scan\n");
+		state->restart = 0;
+		if (kthread_should_stop())
+			break;
+
+		/* setup the chip*/
+		msp34xxg_reset(client);
+		std = standard;
+		if (std != 0x01)
+			goto unmute;
+
+		/* watch autodetect */
+		v4l_dbg(1, client, "triggered autodetect, waiting for result\n");
+		for (i = 0; i < 10; i++) {
+			if (msp_sleep(state, 100))
+				goto restart;
+
+			/* check results */
+			val = msp_read_dem(client, 0x7e);
+			if (val < 0x07ff) {
+				std = val;
+				break;
+			}
+			v4l_dbg(2, client, "detection still in progress\n");
+		}
+		if (std == 1) {
+			v4l_dbg(1, client, "detection still in progress after 10 tries. giving up.\n");
+			continue;
+		}
+
+	unmute:
+		state->std = std;
+		v4l_dbg(1, client, "current standard: %s (0x%04x)\n",
+			msp_standard_std_name(std), std);
+
+		/* unmute: dispatch sound to scart output, set scart volume */
+		msp_set_audio(client);
+
+		/* restore ACB */
+		if (msp_write_dsp(client, 0x13, state->acb))
+			return -1;
+
+		msp_write_dem(client, 0x40, state->i2s_mode);
+	}
+	v4l_dbg(1, client, "thread: exit\n");
+	return 0;
+}
+
+void msp34xxg_detect_stereo(struct i2c_client *client)
+{
+	struct msp_state *state = i2c_get_clientdata(client);
+
+	int status = msp_read_dem(client, 0x0200);
+	int is_bilingual = status & 0x100;
+	int is_stereo = status & 0x40;
+
+	state->rxsubchans = 0;
+	if (is_stereo)
+		state->rxsubchans |= V4L2_TUNER_SUB_STEREO;
+	else
+		state->rxsubchans |= V4L2_TUNER_SUB_MONO;
+	if (is_bilingual) {
+		state->rxsubchans |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+		/* I'm supposed to check whether it's SAP or not
+		 * and set only LANG2/SAP in this case. Yet, the MSP
+		 * does a lot of work to hide this and handle everything
+		 * the same way. I don't want to work around it so unless
+		 * this is a problem, I'll handle SAP just like lang1/lang2.
+		 */
+	}
+	v4l_dbg(1, client, "status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",
+		status, is_stereo, is_bilingual, state->rxsubchans);
+}
+
+void msp34xxg_set_audmode(struct i2c_client *client, int audmode)
+{
+	struct msp_state *state = i2c_get_clientdata(client);
+	int source;
+
+	switch (audmode) {
+	case V4L2_TUNER_MODE_MONO:
+		source = 0; /* mono only */
+		break;
+	case V4L2_TUNER_MODE_STEREO:
+		source = 1; /* stereo or A|B, see comment in msp34xxg_get_v4l2_stereo() */
+		/* problem: that could also mean 2 (scart input) */
+		break;
+	case V4L2_TUNER_MODE_LANG1:
+		source = 3; /* stereo or A */
+		break;
+	case V4L2_TUNER_MODE_LANG2:
+		source = 4; /* stereo or B */
+		break;
+	default:
+		audmode = 0;
+		source  = 1;
+		break;
+	}
+	state->audmode = audmode;
+	msp34xxg_set_source(client, source);
+}
+
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
deleted file mode 100644
index 183253e..0000000
--- a/drivers/media/video/msp3400.c
+++ /dev/null
@@ -1,2229 +0,0 @@
-/*
- * programming the msp34* sound processor family
- *
- * (c) 1997-2001 Gerd Knorr <kraxel@bytesex.org>
- *
- * what works and what doesn't:
- *
- *  AM-Mono
- *      Support for Hauppauge cards added (decoding handled by tuner) added by
- *      Frederic Crozat <fcrozat@mail.dotcom.fr>
- *
- *  FM-Mono
- *      should work. The stereo modes are backward compatible to FM-mono,
- *      therefore FM-Mono should be allways available.
- *
- *  FM-Stereo (B/G, used in germany)
- *      should work, with autodetect
- *
- *  FM-Stereo (satellite)
- *      should work, no autodetect (i.e. default is mono, but you can
- *      switch to stereo -- untested)
- *
- *  NICAM (B/G, L , used in UK, Scandinavia, Spain and France)
- *      should work, with autodetect. Support for NICAM was added by
- *      Pekka Pietikainen <pp@netppl.fi>
- *
- *
- * TODO:
- *   - better SAT support
- *
- *
- * 980623  Thomas Sailer (sailer@ife.ee.ethz.ch)
- *         using soundcore instead of OSS
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/videodev.h>
-#include <linux/init.h>
-#include <linux/smp_lock.h>
-#include <linux/kthread.h>
-#include <linux/suspend.h>
-#include <asm/semaphore.h>
-#include <asm/pgtable.h>
-
-#include <media/audiochip.h>
-#include "msp3400.h"
-
-#define msp3400_dbg(fmt, arg...) \
-	do { \
-		if (debug) \
-			printk(KERN_INFO "%s debug %d-%04x: " fmt, \
-			       client->driver->driver.name, \
-			       i2c_adapter_id(client->adapter), client->addr , ## arg); \
-	} while (0)
-
-/* Medium volume debug. */
-#define msp3400_dbg_mediumvol(fmt, arg...) \
-	do { \
-		if (debug >= 2) \
-			printk(KERN_INFO "%s debug %d-%04x: " fmt, \
-				client->driver->driver.name, \
-				i2c_adapter_id(client->adapter), client->addr , ## arg); \
-	} while (0)
-
-/* High volume debug. Use with care. */
-#define msp3400_dbg_highvol(fmt, arg...) \
-	do { \
-		if (debug >= 16) \
-			printk(KERN_INFO "%s debug %d-%04x: " fmt, \
-				client->driver->driver.name, \
-				i2c_adapter_id(client->adapter), client->addr , ## arg); \
-	} while (0)
-
-#define msp3400_err(fmt, arg...) do { \
-	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
-		i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-#define msp3400_warn(fmt, arg...) do { \
-	printk(KERN_WARNING "%s %d-%04x: " fmt, client->driver->driver.name, \
-		i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-#define msp3400_info(fmt, arg...) do { \
-	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
-		i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-
-#define OPMODE_AUTO    -1
-#define OPMODE_MANUAL   0
-#define OPMODE_SIMPLE   1   /* use short programming (>= msp3410 only) */
-#define OPMODE_SIMPLER  2   /* use shorter programming (>= msp34xxG)   */
-
-/* insmod parameters */
-static int opmode   = OPMODE_AUTO;
-static int debug    = 0;    /* debug output */
-static int once     = 0;    /* no continous stereo monitoring */
-static int amsound  = 0;    /* hard-wire AM sound at 6.5 Hz (france),
-			       the autoscan seems work well only with FM... */
-static int standard = 1;    /* Override auto detect of audio standard, if needed. */
-static int dolby    = 0;
-
-static int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual
-					(msp34xxg only) 0x00a0-0x03c0 */
-#define DFP_COUNT 0x41
-static const int bl_dfp[] = {
-	0x00, 0x01, 0x02, 0x03, 0x06, 0x08, 0x09, 0x0a,
-	0x0b, 0x0d, 0x0e, 0x10
-};
-
-#define IS_MSP34XX_G(msp) ((msp)->opmode==2)
-
-struct msp3400c {
-	int rev1,rev2;
-
-	int opmode;
-	int nicam;
-	int mode;
-	int norm;
-	int stereo;
-	int nicam_on;
-	int acb;
-	int in_scart;
-	int i2s_mode;
-	int main, second;	/* sound carrier */
-	int input;
-	int source;             /* see msp34xxg_set_source */
-
-	/* v4l2 */
-	int audmode;
-	int rxsubchans;
-
-	int muted;
-	int left, right;	/* volume */
-	int bass, treble;
-
-	/* shadow register set */
-	int dfp_regs[DFP_COUNT];
-
-	/* thread */
-	struct task_struct   *kthread;
-	wait_queue_head_t    wq;
-	int                  restart:1;
-	int                  watch_stereo:1;
-};
-
-#define MIN(a,b) (((a)>(b))?(b):(a))
-#define MAX(a,b) (((a)>(b))?(a):(b))
-#define HAVE_NICAM(msp)   (((msp->rev2>>8) & 0xff) != 00)
-#define HAVE_SIMPLE(msp)  ((msp->rev1      & 0xff) >= 'D'-'@')
-#define HAVE_SIMPLER(msp) ((msp->rev1      & 0xff) >= 'G'-'@')
-#define HAVE_RADIO(msp)   ((msp->rev1      & 0xff) >= 'G'-'@')
-
-#define VIDEO_MODE_RADIO 16      /* norm magic for radio mode */
-
-/* ---------------------------------------------------------------------- */
-
-/* read-only */
-module_param(opmode,           int, 0444);
-
-/* read-write */
-module_param(once,             int, 0644);
-module_param(debug,            int, 0644);
-module_param(stereo_threshold, int, 0644);
-module_param(standard,         int, 0644);
-module_param(amsound,          int, 0644);
-module_param(dolby,            int, 0644);
-
-MODULE_PARM_DESC(opmode, "Forces a MSP3400 opmode. 0=Manual, 1=Simple, 2=Simpler");
-MODULE_PARM_DESC(once, "No continuous stereo monitoring");
-MODULE_PARM_DESC(debug, "Enable debug messages");
-MODULE_PARM_DESC(stereo_threshold, "Sets signal threshold to activate stereo");
-MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Default: Autodetect");
-MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan");
-MODULE_PARM_DESC(dolby, "Activates Dolby processsing");
-
-/* ---------------------------------------------------------------------- */
-
-#define I2C_MSP3400C       0x80
-#define I2C_MSP3400C_ALT   0x88
-
-#define I2C_MSP3400C_DEM   0x10
-#define I2C_MSP3400C_DFP   0x12
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = {
-	I2C_MSP3400C      >> 1,
-	I2C_MSP3400C_ALT  >> 1,
-	I2C_CLIENT_END
-};
-I2C_CLIENT_INSMOD;
-
-MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
-MODULE_AUTHOR("Gerd Knorr");
-MODULE_LICENSE("GPL");
-
-/* ----------------------------------------------------------------------- */
-/* functions for talking to the MSP3400C Sound processor                   */
-
-static int msp3400c_reset(struct i2c_client *client)
-{
-	/* reset and read revision code */
-	static char reset_off[3] = { 0x00, 0x80, 0x00 };
-	static char reset_on[3]  = { 0x00, 0x00, 0x00 };
-	static char write[3]     = { I2C_MSP3400C_DFP + 1, 0x00, 0x1e };
-	char read[2];
-	struct i2c_msg reset[2] = {
-		{ client->addr, I2C_M_IGNORE_NAK, 3, reset_off },
-		{ client->addr, I2C_M_IGNORE_NAK, 3, reset_on  },
-	};
-	struct i2c_msg test[2] = {
-		{ client->addr, 0,        3, write },
-		{ client->addr, I2C_M_RD, 2, read  },
-	};
-
-	msp3400_dbg_highvol("msp3400c_reset\n");
-	if ( (1 != i2c_transfer(client->adapter,&reset[0],1)) ||
-	     (1 != i2c_transfer(client->adapter,&reset[1],1)) ||
-	     (2 != i2c_transfer(client->adapter,test,2)) ) {
-		msp3400_err("chip reset failed\n");
-		return -1;
-	}
-	return 0;
-}
-
-static int msp3400c_read(struct i2c_client *client, int dev, int addr)
-{
-	int err,retval;
-
-	unsigned char write[3];
-	unsigned char read[2];
-	struct i2c_msg msgs[2] = {
-		{ client->addr, 0,        3, write },
-		{ client->addr, I2C_M_RD, 2, read  }
-	};
-
-	write[0] = dev+1;
-	write[1] = addr >> 8;
-	write[2] = addr & 0xff;
-
-	for (err = 0; err < 3;) {
-		if (2 == i2c_transfer(client->adapter,msgs,2))
-			break;
-		err++;
-		msp3400_warn("I/O error #%d (read 0x%02x/0x%02x)\n", err,
-		       dev, addr);
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(msecs_to_jiffies(10));
-	}
-	if (3 == err) {
-		msp3400_warn("giving up, resetting chip. Sound will go off, sorry folks :-|\n");
-		msp3400c_reset(client);
-		return -1;
-	}
-	retval = read[0] << 8 | read[1];
-	msp3400_dbg_highvol("msp3400c_read(0x%x, 0x%x): 0x%x\n", dev, addr, retval);
-	return retval;
-}
-
-static int msp3400c_write(struct i2c_client *client, int dev, int addr, int val)
-{
-	int err;
-	unsigned char buffer[5];
-
-	buffer[0] = dev;
-	buffer[1] = addr >> 8;
-	buffer[2] = addr &  0xff;
-	buffer[3] = val  >> 8;
-	buffer[4] = val  &  0xff;
-
-	msp3400_dbg_highvol("msp3400c_write(0x%x, 0x%x, 0x%x)\n", dev, addr, val);
-	for (err = 0; err < 3;) {
-		if (5 == i2c_master_send(client, buffer, 5))
-			break;
-		err++;
-		msp3400_warn("I/O error #%d (write 0x%02x/0x%02x)\n", err,
-		       dev, addr);
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(msecs_to_jiffies(10));
-	}
-	if (3 == err) {
-		msp3400_warn("giving up, reseting chip. Sound will go off, sorry folks :-|\n");
-		msp3400c_reset(client);
-		return -1;
-	}
-	return 0;
-}
-
-/* ------------------------------------------------------------------------ */
-
-/* This macro is allowed for *constants* only, gcc must calculate it
-   at compile time.  Remember -- no floats in kernel mode */
-#define MSP_CARRIER(freq) ((int)((float)(freq/18.432)*(1<<24)))
-
-#define MSP_MODE_AM_DETECT   0
-#define MSP_MODE_FM_RADIO    2
-#define MSP_MODE_FM_TERRA    3
-#define MSP_MODE_FM_SAT      4
-#define MSP_MODE_FM_NICAM1   5
-#define MSP_MODE_FM_NICAM2   6
-#define MSP_MODE_AM_NICAM    7
-#define MSP_MODE_BTSC        8
-#define MSP_MODE_EXTERN      9
-
-static struct MSP_INIT_DATA_DEM {
-	int fir1[6];
-	int fir2[6];
-	int cdo1;
-	int cdo2;
-	int ad_cv;
-	int mode_reg;
-	int dfp_src;
-	int dfp_matrix;
-} msp_init_data[] = {
-	{	/* AM (for carrier detect / msp3400) */
-		{75, 19, 36, 35, 39, 40},
-		{75, 19, 36, 35, 39, 40},
-		MSP_CARRIER(5.5), MSP_CARRIER(5.5),
-		0x00d0, 0x0500, 0x0020, 0x3000
-	},{	/* AM (for carrier detect / msp3410) */
-		{-1, -1, -8, 2, 59, 126},
-		{-1, -1, -8, 2, 59, 126},
-		MSP_CARRIER(5.5), MSP_CARRIER(5.5),
-		0x00d0, 0x0100, 0x0020, 0x3000
-	},{	/* FM Radio */
-		{-8, -8, 4, 6, 78, 107},
-		{-8, -8, 4, 6, 78, 107},
-		MSP_CARRIER(10.7), MSP_CARRIER(10.7),
-		0x00d0, 0x0480, 0x0020, 0x3000
-	},{	/* Terrestial FM-mono + FM-stereo */
-		{3, 18, 27, 48, 66, 72},
-		{3, 18, 27, 48, 66, 72},
-		MSP_CARRIER(5.5), MSP_CARRIER(5.5),
-		0x00d0, 0x0480, 0x0030, 0x3000
-	},{	/* Sat FM-mono */
-		{ 1, 9, 14, 24, 33, 37},
-		{ 3, 18, 27, 48, 66, 72},
-		MSP_CARRIER(6.5), MSP_CARRIER(6.5),
-		0x00c6, 0x0480, 0x0000, 0x3000
-	},{	/* NICAM/FM --  B/G (5.5/5.85), D/K (6.5/5.85) */
-		{-2, -8, -10, 10, 50, 86},
-		{3, 18, 27, 48, 66, 72},
-		MSP_CARRIER(5.5), MSP_CARRIER(5.5),
-		0x00d0, 0x0040, 0x0120, 0x3000
-	},{	/* NICAM/FM -- I (6.0/6.552) */
-		{2, 4, -6, -4, 40, 94},
-		{3, 18, 27, 48, 66, 72},
-		MSP_CARRIER(6.0), MSP_CARRIER(6.0),
-		0x00d0, 0x0040, 0x0120, 0x3000
-	},{	/* NICAM/AM -- L (6.5/5.85) */
-		{-2, -8, -10, 10, 50, 86},
-		{-4, -12, -9, 23, 79, 126},
-		MSP_CARRIER(6.5), MSP_CARRIER(6.5),
-		0x00c6, 0x0140, 0x0120, 0x7c03
-	},
-};
-
-struct CARRIER_DETECT {
-	int   cdo;
-	char *name;
-};
-
-static struct CARRIER_DETECT carrier_detect_main[] = {
-	/* main carrier */
-	{ MSP_CARRIER(4.5),        "4.5   NTSC"                   },
-	{ MSP_CARRIER(5.5),        "5.5   PAL B/G"                },
-	{ MSP_CARRIER(6.0),        "6.0   PAL I"                  },
-	{ MSP_CARRIER(6.5),        "6.5   PAL D/K + SAT + SECAM"  }
-};
-
-static struct CARRIER_DETECT carrier_detect_55[] = {
-	/* PAL B/G */
-	{ MSP_CARRIER(5.7421875),  "5.742 PAL B/G FM-stereo"     },
-	{ MSP_CARRIER(5.85),       "5.85  PAL B/G NICAM"         }
-};
-
-static struct CARRIER_DETECT carrier_detect_65[] = {
-	/* PAL SAT / SECAM */
-	{ MSP_CARRIER(5.85),       "5.85  PAL D/K + SECAM NICAM" },
-	{ MSP_CARRIER(6.2578125),  "6.25  PAL D/K1 FM-stereo" },
-	{ MSP_CARRIER(6.7421875),  "6.74  PAL D/K2 FM-stereo" },
-	{ MSP_CARRIER(7.02),       "7.02  PAL SAT FM-stereo s/b" },
-	{ MSP_CARRIER(7.20),       "7.20  PAL SAT FM-stereo s"   },
-	{ MSP_CARRIER(7.38),       "7.38  PAL SAT FM-stereo b"   },
-};
-
-#define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT))
-
-/* ----------------------------------------------------------------------- *
- * bits  9  8  5 - SCART DSP input Select:
- *       0  0  0 - SCART 1 to DSP input (reset position)
- *       0  1  0 - MONO to DSP input
- *       1  0  0 - SCART 2 to DSP input
- *       1  1  1 - Mute DSP input
- *
- * bits 11 10  6 - SCART 1 Output Select:
- *       0  0  0 - undefined (reset position)
- *       0  1  0 - SCART 2 Input to SCART 1 Output (for devices with 2 SCARTS)
- *       1  0  0 - MONO input to SCART 1 Output
- *       1  1  0 - SCART 1 DA to SCART 1 Output
- *       0  0  1 - SCART 2 DA to SCART 1 Output
- *       0  1  1 - SCART 1 Input to SCART 1 Output
- *       1  1  1 - Mute SCART 1 Output
- *
- * bits 13 12  7 - SCART 2 Output Select (for devices with 2 Output SCART):
- *       0  0  0 - SCART 1 DA to SCART 2 Output (reset position)
- *       0  1  0 - SCART 1 Input to SCART 2 Output
- *       1  0  0 - MONO input to SCART 2 Output
- *       0  0  1 - SCART 2 DA to SCART 2 Output
- *       0  1  1 - SCART 2 Input to SCART 2 Output
- *       1  1  0 - Mute SCART 2 Output
- *
- * Bits 4 to 0 should be zero.
- * ----------------------------------------------------------------------- */
-
-static int scarts[3][9] = {
-	/* MASK    IN1     IN2     IN1_DA  IN2_DA  IN3     IN4     MONO    MUTE   */
-	/* SCART DSP Input select */
-	{ 0x0320, 0x0000, 0x0200, -1,     -1,     0x0300, 0x0020, 0x0100, 0x0320 },
-	/* SCART1 Output select */
-	{ 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 },
-	/* SCART2 Output select */
-	{ 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 },
-};
-
-static char *scart_names[] = {
-	"mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute"
-};
-
-static void msp3400c_set_scart(struct i2c_client *client, int in, int out)
-{
-	struct msp3400c *msp = i2c_get_clientdata(client);
-
-	msp->in_scart=in;
-
-	if (in >= 1 && in <= 8 && out >= 0 && out <= 2) {
-		if (-1 == scarts[out][in])
-			return;
-
-		msp->acb &= ~scarts[out][SCART_MASK];
-		msp->acb |=  scarts[out][in];
-	} else
-		msp->acb = 0xf60; /* Mute Input and SCART 1 Output */
-
-	msp3400_dbg("scart switch: %s => %d (ACB=0x%04x)\n",
-						scart_names[in], out, msp->acb);
-	msp3400c_write(client,I2C_MSP3400C_DFP, 0x13, msp->acb);
-
-	/* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */
-	msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
-}
-
-/* ------------------------------------------------------------------------ */
-
-static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2)
-{
-	msp3400c_write(client,I2C_MSP3400C_DEM, 0x0093, cdo1 & 0xfff);
-	msp3400c_write(client,I2C_MSP3400C_DEM, 0x009b, cdo1 >> 12);
-	msp3400c_write(client,I2C_MSP3400C_DEM, 0x00a3, cdo2 & 0xfff);
-	msp3400c_write(client,I2C_MSP3400C_DEM, 0x00ab, cdo2 >> 12);
-	msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/
-}
-
-static void msp3400c_setvolume(struct i2c_client *client,
-			       int muted, int left, int right)
- {
-	int vol = 0, val = 0, balance = 0;
-
-	if (!muted) {
-		/* 0x7f instead if 0x73 here has sound quality issues,
-		 * probably due to overmodulation + clipping ... */
-		vol = (left > right) ? left : right;
-		val = (vol * 0x73 / 65535) << 8;
-	}
-	if (vol > 0) {
-		balance = ((right - left) * 127) / vol;
-	}
-
-	msp3400_dbg("setvolume: mute=%s %d:%d  v=0x%02x b=0x%02x\n",
-		muted ? "on" : "off", left, right, val >> 8, balance);
-	msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */
-	msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones  */
-	msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007,
-					muted ? 0x1 : (val | 0x1));
-	msp3400c_write(client, I2C_MSP3400C_DFP, 0x0001, balance << 8);
-}
-
-static void msp3400c_setbass(struct i2c_client *client, int bass)
-{
-	int val = ((bass-32768) * 0x60 / 65535) << 8;
-
-	msp3400_dbg("setbass: %d 0x%02x\n", bass, val >> 8);
-	msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */
-}
-
-static void msp3400c_settreble(struct i2c_client *client, int treble)
-{
-	int val = ((treble-32768) * 0x60 / 65535) << 8;
-
-	msp3400_dbg("settreble: %d 0x%02x\n",treble, val>>8);
-	msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */
-}
-
-static void msp3400c_setmode(struct i2c_client *client, int type)
-{
-	struct msp3400c *msp = i2c_get_clientdata(client);
-	int i;
-
-	msp3400_dbg("setmode: %d\n",type);
-	msp->mode       = type;
-	msp->audmode    = V4L2_TUNER_MODE_MONO;
-	msp->rxsubchans = V4L2_TUNER_SUB_MONO;
-
-	msp3400c_write(client,I2C_MSP3400C_DEM, 0x00bb,          /* ad_cv */
-		       msp_init_data[type].ad_cv);
-
-	for (i = 5; i >= 0; i--)                                   /* fir 1 */
-		msp3400c_write(client,I2C_MSP3400C_DEM, 0x0001,
-			       msp_init_data[type].fir1[i]);
-
-	msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0004); /* fir 2 */
-	msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0040);
-	msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0000);
-	for (i = 5; i >= 0; i--)
-		msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005,
-			       msp_init_data[type].fir2[i]);
-
-	msp3400c_write(client,I2C_MSP3400C_DEM, 0x0083,     /* MODE_REG */
-		       msp_init_data[type].mode_reg);
-
-	msp3400c_setcarrier(client, msp_init_data[type].cdo1,
-			    msp_init_data[type].cdo2);
-
-	msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/
-
-	if (dolby) {
-		msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,
-			       0x0520); /* I2S1 */
-		msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,
-			       0x0620); /* I2S2 */
-		msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,
-			       msp_init_data[type].dfp_src);
-	} else {
-		msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,
-			       msp_init_data[type].dfp_src);
-		msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,
-			       msp_init_data[type].dfp_src);
-		msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,
-			       msp_init_data[type].dfp_src);
-	}
-	msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,
-		       msp_init_data[type].dfp_src);
-	msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e,
-		       msp_init_data[type].dfp_matrix);
-
-	if (HAVE_NICAM(msp)) {
-		/* nicam prescale */
-		msp3400c_write(client,I2C_MSP3400C_DFP, 0x0010, 0x5a00); /* was: 0x3000 */
-	}
-}
-
-/* given a bitmask of VIDEO_SOUND_XXX returns the "best" in the bitmask */
-static int best_video_sound(int rxsubchans)
-{
-	if (rxsubchans & V4L2_TUNER_SUB_STEREO)
-		return V4L2_TUNER_MODE_STEREO;
-	if (rxsubchans & V4L2_TUNER_SUB_LANG1)
-		return V4L2_TUNER_MODE_LANG1;
-	if (rxsubchans & V4L2_TUNER_SUB_LANG2)
-		return V4L2_TUNER_MODE_LANG2;
-	return V4L2_TUNER_MODE_MONO;
-}
-
-/* turn on/off nicam + stereo */
-static void msp3400c_setstereo(struct i2c_client *client, int mode)
-{
-	static char *strmode[] = { "0", "mono", "stereo", "3",
-		"lang1", "5", "6", "7", "lang2"
-	};
-	struct msp3400c *msp = i2c_get_clientdata(client);
-	int nicam = 0;		/* channel source: FM/AM or nicam */
-	int src = 0;
-
-	if (IS_MSP34XX_G(msp)) {
-		/* this method would break everything, let's make sure
-		 * it's never called
-		 */
-		msp3400_dbg
-		    ("DEBUG WARNING setstereo called with mode=%d instead of set_source (ignored)\n",
-		     mode);
-		return;
-	}
-
-	/* switch demodulator */
-	switch (msp->mode) {
-	case MSP_MODE_FM_TERRA:
-		msp3400_dbg("FM setstereo: %s\n", strmode[mode]);
-		msp3400c_setcarrier(client,msp->second,msp->main);
-		switch (mode) {
-		case V4L2_TUNER_MODE_STEREO:
-			msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001);
-			break;
-		case V4L2_TUNER_MODE_MONO:
-		case V4L2_TUNER_MODE_LANG1:
-		case V4L2_TUNER_MODE_LANG2:
-			msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3000);
-			break;
-		}
-		break;
-	case MSP_MODE_FM_SAT:
-		msp3400_dbg("SAT setstereo: %s\n", strmode[mode]);
-		switch (mode) {
-		case V4L2_TUNER_MODE_MONO:
-			msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
-			break;
-		case V4L2_TUNER_MODE_STEREO:
-			msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
-			break;
-		case V4L2_TUNER_MODE_LANG1:
-			msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
-			break;
-		case V4L2_TUNER_MODE_LANG2:
-			msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
-			break;
-		}
-		break;
-	case MSP_MODE_FM_NICAM1:
-	case MSP_MODE_FM_NICAM2:
-	case MSP_MODE_AM_NICAM:
-		msp3400_dbg("NICAM setstereo: %s\n",strmode[mode]);
-		msp3400c_setcarrier(client,msp->second,msp->main);
-		if (msp->nicam_on)
-			nicam=0x0100;
-		break;
-	case MSP_MODE_BTSC:
-		msp3400_dbg("BTSC setstereo: %s\n",strmode[mode]);
-		nicam=0x0300;
-		break;
-	case MSP_MODE_EXTERN:
-		msp3400_dbg("extern setstereo: %s\n",strmode[mode]);
-		nicam = 0x0200;
-		break;
-	case MSP_MODE_FM_RADIO:
-		msp3400_dbg("FM-Radio setstereo: %s\n",strmode[mode]);
-		break;
-	default:
-		msp3400_dbg("mono setstereo\n");
-		return;
-	}
-
-	/* switch audio */
-	switch (best_video_sound(mode)) {
-	case V4L2_TUNER_MODE_STEREO:
-		src = 0x0020 | nicam;
-		break;
-	case V4L2_TUNER_MODE_MONO:
-		if (msp->mode == MSP_MODE_AM_NICAM) {
-			msp3400_dbg("switching to AM mono\n");
-			/* AM mono decoding is handled by tuner, not MSP chip */
-			/* SCART switching control register */
-			msp3400c_set_scart(client,SCART_MONO,0);
-			src = 0x0200;
-			break;
-		}
-	case V4L2_TUNER_MODE_LANG1:
-		src = 0x0000 | nicam;
-		break;
-	case V4L2_TUNER_MODE_LANG2:
-		src = 0x0010 | nicam;
-		break;
-	}
-	msp3400_dbg("setstereo final source/matrix = 0x%x\n", src);
-
-	if (dolby) {
-		msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520);
-		msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,0x0620);
-		msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src);
-		msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src);
-	} else {
-		msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,src);
-		msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,src);
-		msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src);
-		msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src);
-	}
-}
-
-static void
-msp3400c_print_mode(struct i2c_client *client)
-{
-	struct msp3400c *msp = i2c_get_clientdata(client);
-
-	if (msp->main == msp->second) {
-		msp3400_dbg("mono sound carrier: %d.%03d MHz\n",
-		       msp->main/910000,(msp->main/910)%1000);
-	} else {
-		msp3400_dbg("main sound carrier: %d.%03d MHz\n",
-		       msp->main/910000,(msp->main/910)%1000);
-	}
-	if (msp->mode == MSP_MODE_FM_NICAM1 || msp->mode == MSP_MODE_FM_NICAM2)
-		msp3400_dbg("NICAM/FM carrier   : %d.%03d MHz\n",
-		       msp->second/910000,(msp->second/910)%1000);
-	if (msp->mode == MSP_MODE_AM_NICAM)
-		msp3400_dbg("NICAM/AM carrier   : %d.%03d MHz\n",
-		       msp->second/910000,(msp->second/910)%1000);
-	if (msp->mode == MSP_MODE_FM_TERRA &&
-	    msp->main != msp->second) {
-		msp3400_dbg("FM-stereo carrier : %d.%03d MHz\n",
-		       msp->second/910000,(msp->second/910)%1000);
-	}
-}
-
-#define MSP3400_MAX 4
-static struct i2c_client *msps[MSP3400_MAX];
-static void msp3400c_restore_dfp(struct i2c_client *client)
-{
-	struct msp3400c *msp = i2c_get_clientdata(client);
-	int i;
-
-	for (i = 0; i < DFP_COUNT; i++) {
-		if (-1 == msp->dfp_regs[i])
-			continue;
-		msp3400c_write(client, I2C_MSP3400C_DFP, i, msp->dfp_regs[i]);
-	}
-}
-
-/* if the dfp_regs is set, set what's in there. Otherwise, set the default value */
-static int msp3400c_write_dfp_with_default(struct i2c_client *client,
-					int addr, int default_value)
-{
-	struct msp3400c *msp = i2c_get_clientdata(client);
-	int value = default_value;
-	if (addr < DFP_COUNT && -1 != msp->dfp_regs[addr])
-		value = msp->dfp_regs[addr];
-	return msp3400c_write(client, I2C_MSP3400C_DFP, addr, value);
-}
-
-/* ----------------------------------------------------------------------- */
-
-struct REGISTER_DUMP {
-	int   addr;
-	char *name;
-};
-
-struct REGISTER_DUMP d1[] = {
-	{0x007e, "autodetect"},
-	{0x0023, "C_AD_BITS "},
-	{0x0038, "ADD_BITS  "},
-	{0x003e, "CIB_BITS  "},
-	{0x0057, "ERROR_RATE"},
-};
-
-static int autodetect_stereo(struct i2c_client *client)
-{
-	struct msp3400c *msp = i2c_get_clientdata(client);
-	int val;
-	int rxsubchans = msp->rxsubchans;
-	int newnicam   = msp->nicam_on;
-	int update = 0;
-
-	switch (msp->mode) {
-	case MSP_MODE_FM_TERRA:
-		val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18);
-		if (val > 32767)
-			val -= 65536;
-		msp3400_dbg("stereo detect register: %d\n",val);
-		if (val > 4096) {
-			rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
-		} else if (val < -4096) {
-			rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
-		} else {
-			rxsubchans = V4L2_TUNER_SUB_MONO;
-		}
-		newnicam = 0;
-		break;
-	case MSP_MODE_FM_NICAM1:
-	case MSP_MODE_FM_NICAM2:
-	case MSP_MODE_AM_NICAM:
-		val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23);
-		msp3400_dbg("nicam sync=%d, mode=%d\n",
-			val & 1, (val & 0x1e) >> 1);
-
-		if (val & 1) {
-			/* nicam synced */
-			switch ((val & 0x1e) >> 1)  {
-			case 0:
-			case 8:
-				rxsubchans = V4L2_TUNER_SUB_STEREO;
-				break;
-			case 1:
-			case 9:
-				rxsubchans = V4L2_TUNER_SUB_MONO
-					| V4L2_TUNER_SUB_LANG1;
-				break;
-			case 2:
-			case 10:
-				rxsubchans = V4L2_TUNER_SUB_MONO
-					| V4L2_TUNER_SUB_LANG1
-					| V4L2_TUNER_SUB_LANG2;
-				break;
-			default:
-				rxsubchans = V4L2_TUNER_SUB_MONO;
-				break;
-			}
-			newnicam=1;
-		} else {
-			newnicam = 0;
-			rxsubchans = V4L2_TUNER_SUB_MONO;
-		}
-		break;
-	case MSP_MODE_BTSC:
-		val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200);
-		msp3400_dbg("status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
-			val,
-			(val & 0x0002) ? "no"     : "yes",
-			(val & 0x0004) ? "no"     : "yes",
-			(val & 0x0040) ? "stereo" : "mono",
-			(val & 0x0080) ? ", nicam 2nd mono" : "",
-			(val & 0x0100) ? ", bilingual/SAP"  : "");
-		rxsubchans = V4L2_TUNER_SUB_MONO;
-		if (val & 0x0040) rxsubchans |= V4L2_TUNER_SUB_STEREO;
-		if (val & 0x0100) rxsubchans |= V4L2_TUNER_SUB_LANG1;
-		break;
-	}
-	if (rxsubchans != msp->rxsubchans) {
-		update = 1;
-		msp3400_dbg("watch: rxsubchans %d => %d\n",
-			msp->rxsubchans,rxsubchans);
-		msp->rxsubchans = rxsubchans;
-	}
-	if (newnicam != msp->nicam_on) {
-		update = 1;
-		msp3400_dbg("watch: nicam %d => %d\n",
-			msp->nicam_on,newnicam);
-		msp->nicam_on = newnicam;
-	}
-	return update;
-}
-
-/*
- * A kernel thread for msp3400 control -- we don't want to block the
- * in the ioctl while doing the sound carrier & stereo detect
- */
-
-static int msp34xx_sleep(struct msp3400c *msp, int timeout)
-{
-	DECLARE_WAITQUEUE(wait, current);
-
-	add_wait_queue(&msp->wq, &wait);
-	if (!kthread_should_stop()) {
-		if (timeout < 0) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule();
-		} else {
-			schedule_timeout_interruptible
-						(msecs_to_jiffies(timeout));
-		}
-	}
-
-	remove_wait_queue(&msp->wq, &wait);
-	try_to_freeze();
-	return msp->restart;
-}
-
-/* stereo/multilang monitoring */
-static void watch_stereo(struct i2c_client *client)
-{
-	struct msp3400c *msp = i2c_get_clientdata(client);
-
-	if (autodetect_stereo(client)) {
-		if (msp->stereo & V4L2_TUNER_MODE_STEREO)
-			msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO);
-		else if (msp->stereo & VIDEO_SOUND_LANG1)
-			msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1);
-		else
-			msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
-	}
-
-	if (once)
-		msp->watch_stereo = 0;
-}
-
-
-static int msp3400c_thread(void *data)
-{
-	struct i2c_client *client = data;
-	struct msp3400c *msp = i2c_get_clientdata(client);
-	struct CARRIER_DETECT *cd;
-	int count, max1,max2,val1,val2, val,this;
-
-
-	msp3400_info("msp3400 daemon started\n");
-	for (;;) {
-		msp3400_dbg_mediumvol("msp3400 thread: sleep\n");
-		msp34xx_sleep(msp,-1);
-		msp3400_dbg_mediumvol("msp3400 thread: wakeup\n");
-
-	restart:
-		msp3400_dbg("thread: restart scan\n");
-		msp->restart = 0;
-		if (kthread_should_stop())
-			break;
-
-		if (VIDEO_MODE_RADIO == msp->norm ||
-		    MSP_MODE_EXTERN  == msp->mode) {
-			/* no carrier scan, just unmute */
-			msp3400_info("thread: no carrier scan\n");
-			msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
-			continue;
-		}
-
-		/* mute */
-		msp3400c_setvolume(client, msp->muted, 0, 0);
-		msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ );
-		val1 = val2 = 0;
-		max1 = max2 = -1;
-		msp->watch_stereo = 0;
-
-		/* some time for the tuner to sync */
-		if (msp34xx_sleep(msp,200))
-			goto restart;
-
-		/* carrier detect pass #1 -- main carrier */
-		cd = carrier_detect_main;
-		count = CARRIER_COUNT(carrier_detect_main);
-
-		if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
-			/* autodetect doesn't work well with AM ... */
-			max1 = 3;
-			count = 0;
-			msp3400_dbg("AM sound override\n");
-		}
-
-		for (this = 0; this < count; this++) {
-			msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
-			if (msp34xx_sleep(msp,100))
-				goto restart;
-			val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b);
-			if (val > 32767)
-				val -= 65536;
-			if (val1 < val)
-				val1 = val, max1 = this;
-			msp3400_dbg("carrier1 val: %5d / %s\n", val,cd[this].name);
-		}
-
-		/* carrier detect pass #2 -- second (stereo) carrier */
-		switch (max1) {
-		case 1: /* 5.5 */
-			cd = carrier_detect_55;
-			count = CARRIER_COUNT(carrier_detect_55);
-			break;
-		case 3: /* 6.5 */
-			cd = carrier_detect_65;
-			count = CARRIER_COUNT(carrier_detect_65);
-			break;
-		case 0: /* 4.5 */
-		case 2: /* 6.0 */
-		default:
-			cd = NULL;
-			count = 0;
-			break;
-		}
-
-		if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
-			/* autodetect doesn't work well with AM ... */
-			cd = NULL;
-			count = 0;
-			max2 = 0;
-		}
-		for (this = 0; this < count; this++) {
-			msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
-			if (msp34xx_sleep(msp,100))
-				goto restart;
-			val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b);
-			if (val > 32767)
-				val -= 65536;
-			if (val2 < val)
-				val2 = val, max2 = this;
-			msp3400_dbg("carrier2 val: %5d / %s\n", val,cd[this].name);
-		}
-
-		/* programm the msp3400 according to the results */
-		msp->main   = carrier_detect_main[max1].cdo;
-		switch (max1) {
-		case 1: /* 5.5 */
-			if (max2 == 0) {
-				/* B/G FM-stereo */
-				msp->second = carrier_detect_55[max2].cdo;
-				msp3400c_setmode(client, MSP_MODE_FM_TERRA);
-				msp->nicam_on = 0;
-				msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
-				msp->watch_stereo = 1;
-			} else if (max2 == 1 && HAVE_NICAM(msp)) {
-				/* B/G NICAM */
-				msp->second = carrier_detect_55[max2].cdo;
-				msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
-				msp->nicam_on = 1;
-				msp3400c_setcarrier(client, msp->second, msp->main);
-				msp->watch_stereo = 1;
-			} else {
-				goto no_second;
-			}
-			break;
-		case 2: /* 6.0 */
-			/* PAL I NICAM */
-			msp->second = MSP_CARRIER(6.552);
-			msp3400c_setmode(client, MSP_MODE_FM_NICAM2);
-			msp->nicam_on = 1;
-			msp3400c_setcarrier(client, msp->second, msp->main);
-			msp->watch_stereo = 1;
-			break;
-		case 3: /* 6.5 */
-			if (max2 == 1 || max2 == 2) {
-				/* D/K FM-stereo */
-				msp->second = carrier_detect_65[max2].cdo;
-				msp3400c_setmode(client, MSP_MODE_FM_TERRA);
-				msp->nicam_on = 0;
-				msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
-				msp->watch_stereo = 1;
-			} else if (max2 == 0 &&
-				   msp->norm == VIDEO_MODE_SECAM) {
-				/* L NICAM or AM-mono */
-				msp->second = carrier_detect_65[max2].cdo;
-				msp3400c_setmode(client, MSP_MODE_AM_NICAM);
-				msp->nicam_on = 0;
-				msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
-				msp3400c_setcarrier(client, msp->second, msp->main);
-				/* volume prescale for SCART (AM mono input) */
-				msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900);
-				msp->watch_stereo = 1;
-			} else if (max2 == 0 && HAVE_NICAM(msp)) {
-				/* D/K NICAM */
-				msp->second = carrier_detect_65[max2].cdo;
-				msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
-				msp->nicam_on = 1;
-				msp3400c_setcarrier(client, msp->second, msp->main);
-				msp->watch_stereo = 1;
-			} else {
-				goto no_second;
-			}
-			break;
-		case 0: /* 4.5 */
-		default:
-		no_second:
-			msp->second = carrier_detect_main[max1].cdo;
-			msp3400c_setmode(client, MSP_MODE_FM_TERRA);
-			msp->nicam_on = 0;
-			msp3400c_setcarrier(client, msp->second, msp->main);
-			msp->rxsubchans = V4L2_TUNER_SUB_MONO;
-			msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
-			break;
-		}
-
-		/* unmute */
-		msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
-		msp3400c_restore_dfp(client);
-
-		if (debug)
-			msp3400c_print_mode(client);
-
-		/* monitor tv audio mode */
-		while (msp->watch_stereo) {
-			if (msp34xx_sleep(msp,5000))
-				goto restart;
-			watch_stereo(client);
-		}
-	}
-	msp3400_dbg("thread: exit\n");
-	return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-/* this one uses the automatic sound standard detection of newer           */
-/* msp34xx chip versions                                                   */
-
-static struct MODES {
-	int retval;
-	int main, second;
-	char *name;
-} modelist[] = {
-	{ 0x0000, 0, 0, "ERROR" },
-	{ 0x0001, 0, 0, "autodetect start" },
-	{ 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72), "4.5/4.72  M Dual FM-Stereo" },
-	{ 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875), "5.5/5.74  B/G Dual FM-Stereo" },
-	{ 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25  D/K1 Dual FM-Stereo" },
-	{ 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74  D/K2 Dual FM-Stereo" },
-	{ 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5  D/K FM-Mono (HDEV3)" },
-	{ 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85  B/G NICAM FM" },
-	{ 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85  L NICAM AM" },
-	{ 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55  I NICAM FM" },
-	{ 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85  D/K NICAM FM" },
-	{ 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85  D/K NICAM FM (HDEV2)" },
-	{ 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5  M BTSC-Stereo" },
-	{ 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5  M BTSC-Mono + SAP" },
-	{ 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5  M EIA-J Japan Stereo" },
-	{ 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7), "10.7  FM-Stereo Radio" },
-	{ 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5  SAT-Mono" },
-	{ 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20), "7.02/7.20  SAT-Stereo" },
-	{ 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2), "7.2  SAT ADR" },
-	{     -1, 0, 0, NULL }, /* EOF */
-};
-
-static inline const char *msp34xx_standard_mode_name(int mode)
-{
-	int i;
-	for (i = 0; modelist[i].name != NULL; i++)
-		if (modelist[i].retval == mode)
-			return modelist[i].name;
-	return "unknown";
-}
-
-static int msp34xx_modus(struct i2c_client *client, int norm)
-{
-	switch (norm) {
-	case VIDEO_MODE_PAL:
-		msp3400_dbg("video mode selected to PAL\n");
-
-#if 1
-		/* experimental: not sure this works with all chip versions */
-		return 0x7003;
-#else
-		/* previous value, try this if it breaks ... */
-		return 0x1003;
-#endif
-	case VIDEO_MODE_NTSC:  /* BTSC */
-		msp3400_dbg("video mode selected to NTSC\n");
-		return 0x2003;
-	case VIDEO_MODE_SECAM:
-		msp3400_dbg("video mode selected to SECAM\n");
-		return 0x0003;
-	case VIDEO_MODE_RADIO:
-		msp3400_dbg("video mode selected to Radio\n");
-		return 0x0003;
-	case VIDEO_MODE_AUTO:
-		msp3400_dbg("video mode selected to Auto\n");
-		return 0x2003;
-	default:
-		return 0x0003;
-	}
-}
-
-static int msp34xx_standard(int norm)
-{
-	switch (norm) {
-	case VIDEO_MODE_PAL:
-		return 1;
-	case VIDEO_MODE_NTSC:  /* BTSC */
-		return 0x0020;
-	case VIDEO_MODE_SECAM:
-		return 1;
-	case VIDEO_MODE_RADIO:
-		return 0x0040;
-	default:
-		return 1;
-	}
-}
-
-static int msp3410d_thread(void *data)
-{
-	struct i2c_client *client = data;
-	struct msp3400c *msp = i2c_get_clientdata(client);
-	int mode,val,i,std;
-
-	msp3400_info("msp3410 daemon started\n");
-
-	for (;;) {
-		msp3400_dbg_mediumvol("msp3410 thread: sleep\n");
-		msp34xx_sleep(msp,-1);
-		msp3400_dbg_mediumvol("msp3410 thread: wakeup\n");
-
-	restart:
-		msp3400_dbg("thread: restart scan\n");
-		msp->restart = 0;
-		if (kthread_should_stop())
-			break;
-
-		if (msp->mode == MSP_MODE_EXTERN) {
-			/* no carrier scan needed, just unmute */
-			msp3400_dbg("thread: no carrier scan\n");
-		msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
-			continue;
-		}
-
-		/* put into sane state (and mute) */
-		msp3400c_reset(client);
-
-		/* some time for the tuner to sync */
-		if (msp34xx_sleep(msp,200))
-			goto restart;
-
-		/* start autodetect */
-		mode = msp34xx_modus(client, msp->norm);
-		std  = msp34xx_standard(msp->norm);
-		msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode);
-		msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std);
-		msp->watch_stereo = 0;
-
-		if (debug)
-			msp3400_dbg("setting mode: %s (0x%04x)\n",
-			       msp34xx_standard_mode_name(std) ,std);
-
-		if (std != 1) {
-			/* programmed some specific mode */
-			val = std;
-		} else {
-			/* triggered autodetect */
-			for (;;) {
-				if (msp34xx_sleep(msp,100))
-					goto restart;
-
-				/* check results */
-				val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e);
-				if (val < 0x07ff)
-					break;
-				msp3400_dbg("detection still in progress\n");
-			}
-		}
-		for (i = 0; modelist[i].name != NULL; i++)
-			if (modelist[i].retval == val)
-				break;
-		msp3400_dbg("current mode: %s (0x%04x)\n",
-			modelist[i].name ? modelist[i].name : "unknown",
-			val);
-		msp->main   = modelist[i].main;
-		msp->second = modelist[i].second;
-
-		if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) {
-			/* autodetection has failed, let backup */
-			msp3400_dbg("autodetection failed,"
-				" switching to backup mode: %s (0x%04x)\n",
-				modelist[8].name ? modelist[8].name : "unknown",val);
-			val = 0x0009;
-			msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, val);
-		}
-
-		/* set various prescales */
-		msp3400c_write(client, I2C_MSP3400C_DFP, 0x0d, 0x1900); /* scart */
-		msp3400c_write(client, I2C_MSP3400C_DFP, 0x0e, 0x2403); /* FM */
-		msp3400c_write(client, I2C_MSP3400C_DFP, 0x10, 0x5a00); /* nicam */
-
-		/* set stereo */
-		switch (val) {
-		case 0x0008: /* B/G NICAM */
-		case 0x000a: /* I NICAM */
-			if (val == 0x0008)
-				msp->mode = MSP_MODE_FM_NICAM1;
-			else
-				msp->mode = MSP_MODE_FM_NICAM2;
-			/* just turn on stereo */
-			msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
-			msp->nicam_on = 1;
-			msp->watch_stereo = 1;
-			msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
-			break;
-		case 0x0009:
-			msp->mode = MSP_MODE_AM_NICAM;
-			msp->rxsubchans = V4L2_TUNER_SUB_MONO;
-			msp->nicam_on = 1;
-			msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO);
-			msp->watch_stereo = 1;
-			break;
-		case 0x0020: /* BTSC */
-			/* just turn on stereo */
-			msp->mode = MSP_MODE_BTSC;
-			msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
-			msp->nicam_on = 0;
-			msp->watch_stereo = 1;
-			msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
-			break;
-		case 0x0040: /* FM radio */
-			msp->mode   = MSP_MODE_FM_RADIO;
-			msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
-			msp->audmode = V4L2_TUNER_MODE_STEREO;
-			msp->nicam_on = 0;
-			msp->watch_stereo = 0;
-			/* not needed in theory if HAVE_RADIO(), but
-			   short programming enables carrier mute */
-			msp3400c_setmode(client,MSP_MODE_FM_RADIO);
-			msp3400c_setcarrier(client, MSP_CARRIER(10.7),
-					    MSP_CARRIER(10.7));
-			/* scart routing */
-			msp3400c_set_scart(client,SCART_IN2,0);
-			/* msp34xx does radio decoding */
-			msp3400c_write(client,I2C_MSP3400C_DFP, 0x08, 0x0020);
-			msp3400c_write(client,I2C_MSP3400C_DFP, 0x09, 0x0020);
-			msp3400c_write(client,I2C_MSP3400C_DFP, 0x0b, 0x0020);
-			break;
-		case 0x0003:
-		case 0x0004:
-		case 0x0005:
-			msp->mode   = MSP_MODE_FM_TERRA;
-			msp->rxsubchans = V4L2_TUNER_SUB_MONO;
-			msp->audmode = V4L2_TUNER_MODE_MONO;
-			msp->nicam_on = 0;
-			msp->watch_stereo = 1;
-			break;
-		}
-
-		/* unmute, restore misc registers */
-		msp3400c_setbass(client, msp->bass);
-		msp3400c_settreble(client, msp->treble);
-		msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
-		msp3400c_write(client, I2C_MSP3400C_DFP, 0x13, msp->acb);
-		msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
-		msp3400c_restore_dfp(client);
-
-		/* monitor tv audio mode */
-		while (msp->watch_stereo) {
-			if (msp34xx_sleep(msp,5000))
-				goto restart;
-			watch_stereo(client);
-		}
-	}
-	msp3400_dbg("thread: exit\n");
-	return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-/* msp34xxG + (simpler no-thread)                                          */
-/* this one uses both automatic standard detection and automatic sound     */
-/* select which are available in the newer G versions                      */
-/* struct msp: only norm, acb and source are really used in this mode      */
-
-static void msp34xxg_set_source(struct i2c_client *client, int source);
-
-/* (re-)initialize the msp34xxg, according to the current norm in msp->norm
- * return 0 if it worked, -1 if it failed
- */
-static int msp34xxg_reset(struct i2c_client *client)
-{
-	struct msp3400c *msp = i2c_get_clientdata(client);
-	int modus,std;
-
-	if (msp3400c_reset(client))
-		return -1;
-
-	/* make sure that input/output is muted (paranoid mode) */
-	if (msp3400c_write(client,
-			   I2C_MSP3400C_DFP,
-			   0x13, /* ACB */
-			   0x0f20 /* mute DSP input, mute SCART 1 */))
-		return -1;
-
-	msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
-
-	/* step-by-step initialisation, as described in the manual */
-	modus = msp34xx_modus(client, msp->norm);
-	std   = msp34xx_standard(msp->norm);
-	modus &= ~0x03; /* STATUS_CHANGE=0 */
-	modus |= 0x01;  /* AUTOMATIC_SOUND_DETECTION=1 */
-	if (msp3400c_write(client,
-			   I2C_MSP3400C_DEM,
-			   0x30/*MODUS*/,
-			   modus))
-		return -1;
-	if (msp3400c_write(client,
-			   I2C_MSP3400C_DEM,
-			   0x20/*standard*/,
-			   std))
-		return -1;
-
-	/* write the dfps that may have an influence on
-	   standard/audio autodetection right now */
-	msp34xxg_set_source(client, msp->source);
-
-	if (msp3400c_write_dfp_with_default(client, 0x0e,	/* AM/FM Prescale */
-					    0x3000
-					    /* default: [15:8] 75khz deviation */
-	    ))
-		return -1;
-
-	if (msp3400c_write_dfp_with_default(client, 0x10,	/* NICAM Prescale */
-					    0x5a00
-					    /* default: 9db gain (as recommended) */
-	    ))
-		return -1;
-
-	return 0;
-}
-
-static int msp34xxg_thread(void *data)
-{
-	struct i2c_client *client = data;
-	struct msp3400c *msp = i2c_get_clientdata(client);
-	int val, std, i;
-
-	msp3400_info("msp34xxg daemon started\n");
-
-	msp->source = 1; /* default */
-	for (;;) {
-		msp3400_dbg_mediumvol("msp34xxg thread: sleep\n");
-		msp34xx_sleep(msp,-1);
-		msp3400_dbg_mediumvol("msp34xxg thread: wakeup\n");
-
-	restart:
-		msp3400_dbg("thread: restart scan\n");
-		msp->restart = 0;
-		if (kthread_should_stop())
-			break;
-
-		/* setup the chip*/
-		msp34xxg_reset(client);
-		std = standard;
-		if (std != 0x01)
-			goto unmute;
-
-		/* watch autodetect */
-		msp3400_dbg("triggered autodetect, waiting for result\n");
-		for (i = 0; i < 10; i++) {
-			if (msp34xx_sleep(msp,100))
-				goto restart;
-
-			/* check results */
-			val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e);
-			if (val < 0x07ff) {
-				std = val;
-				break;
-			}
-			msp3400_dbg("detection still in progress\n");
-		}
-		if (0x01 == std) {
-			msp3400_dbg("detection still in progress after 10 tries. giving up.\n");
-			continue;
-		}
-
-	unmute:
-		msp3400_dbg("current mode: %s (0x%04x)\n",
-			msp34xx_standard_mode_name(std), std);
-
-		/* unmute: dispatch sound to scart output, set scart volume */
-		msp3400_dbg("unmute\n");
-
-		msp3400c_setbass(client, msp->bass);
-		msp3400c_settreble(client, msp->treble);
-		msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
-
-		/* restore ACB */
-		if (msp3400c_write(client,
-				   I2C_MSP3400C_DFP,
-				   0x13, /* ACB */
-				   msp->acb))
-			return -1;
-
-		msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
-	}
-	msp3400_dbg("thread: exit\n");
-	return 0;
-}
-
-/* set the same 'source' for the loudspeaker, scart and quasi-peak detector
- * the value for source is the same as bit 15:8 of DFP registers 0x08,
- * 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B
- *
- * this function replaces msp3400c_setstereo
- */
-static void msp34xxg_set_source(struct i2c_client *client, int source)
-{
-	struct msp3400c *msp = i2c_get_clientdata(client);
-
-	/* fix matrix mode to stereo and let the msp choose what
-	 * to output according to 'source', as recommended
-	 * for MONO (source==0) downmixing set bit[7:0] to 0x30
-	 */
-	int value = (source&0x07)<<8|(source==0 ? 0x30:0x20);
-	msp3400_dbg("set source to %d (0x%x)\n", source, value);
-	msp3400c_write(client,
-		       I2C_MSP3400C_DFP,
-		       0x08, /* Loudspeaker Output */
-		       value);
-	msp3400c_write(client,
-		       I2C_MSP3400C_DFP,
-		       0x0a, /* SCART1 DA Output */
-		       value);
-	msp3400c_write(client,
-		       I2C_MSP3400C_DFP,
-		       0x0c, /* Quasi-peak detector */
-		       value);
-	/*
-	 * set identification threshold. Personally, I
-	 * I set it to a higher value that the default
-	 * of 0x190 to ignore noisy stereo signals.
-	 * this needs tuning. (recommended range 0x00a0-0x03c0)
-	 * 0x7f0 = forced mono mode
-	 */
-	msp3400c_write(client,
-		       I2C_MSP3400C_DEM,
-		       0x22, /* a2 threshold for stereo/bilingual */
-		       stereo_threshold);
-	msp->source=source;
-}
-
-static void msp34xxg_detect_stereo(struct i2c_client *client)
-{
-	struct msp3400c *msp = i2c_get_clientdata(client);
-
-	int status = msp3400c_read(client,
-				   I2C_MSP3400C_DEM,
-				   0x0200 /* STATUS */);
-	int is_bilingual = status&0x100;
-	int is_stereo = status&0x40;
-
-	msp->rxsubchans = 0;
-	if (is_stereo)
-		msp->rxsubchans |= V4L2_TUNER_SUB_STEREO;
-	else
-		msp->rxsubchans |= V4L2_TUNER_SUB_MONO;
-	if (is_bilingual) {
-		msp->rxsubchans |= V4L2_TUNER_SUB_LANG1|V4L2_TUNER_SUB_LANG2;
-		/* I'm supposed to check whether it's SAP or not
-		 * and set only LANG2/SAP in this case. Yet, the MSP
-		 * does a lot of work to hide this and handle everything
-		 * the same way. I don't want to work around it so unless
-		 * this is a problem, I'll handle SAP just like lang1/lang2.
-		 */
-	}
-	msp3400_dbg("status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",
-		status, is_stereo, is_bilingual, msp->rxsubchans);
-}
-
-static void msp34xxg_set_audmode(struct i2c_client *client, int audmode)
-{
-	struct msp3400c *msp = i2c_get_clientdata(client);
-	int source;
-
-	switch (audmode) {
-	case V4L2_TUNER_MODE_MONO:
-		source=0; /* mono only */
-		break;
-	case V4L2_TUNER_MODE_STEREO:
-		source=1; /* stereo or A|B, see comment in msp34xxg_get_v4l2_stereo() */
-		/* problem: that could also mean 2 (scart input) */
-		break;
-	case V4L2_TUNER_MODE_LANG1:
-		source=3; /* stereo or A */
-		break;
-	case V4L2_TUNER_MODE_LANG2:
-		source=4; /* stereo or B */
-		break;
-	default:
-		audmode = 0;
-		source  = 1;
-		break;
-	}
-	msp->audmode = audmode;
-	msp34xxg_set_source(client, source);
-}
-
-
-/* ----------------------------------------------------------------------- */
-
-static int msp_attach(struct i2c_adapter *adap, int addr, int kind);
-static int msp_detach(struct i2c_client *client);
-static int msp_probe(struct i2c_adapter *adap);
-static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg);
-
-static int msp_suspend(struct device * dev, pm_message_t state);
-static int msp_resume(struct device * dev);
-
-static void msp_wake_thread(struct i2c_client *client);
-
-static struct i2c_driver driver = {
-	.id             = I2C_DRIVERID_MSP3400,
-	.attach_adapter = msp_probe,
-	.detach_client  = msp_detach,
-	.command        = msp_command,
-	.driver = {
-		.name    = "i2c msp3400 driver",
-		.suspend = msp_suspend,
-		.resume  = msp_resume,
-	},
-};
-
-static struct i2c_client client_template =
-{
-	.name      = "(unset)",
-	.driver    = &driver,
-};
-
-static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
-{
-	struct msp3400c *msp;
-	struct i2c_client *client = &client_template;
-	int (*thread_func)(void *data) = NULL;
-	int i;
-
-	client_template.adapter = adap;
-	client_template.addr = addr;
-
-	if (-1 == msp3400c_reset(&client_template)) {
-		msp3400_dbg("no chip found\n");
-		return -1;
-	}
-
-	if (NULL == (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL)))
-		return -ENOMEM;
-	memcpy(client,&client_template,sizeof(struct i2c_client));
-	if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) {
-		kfree(client);
-		return -ENOMEM;
-	}
-
-	memset(msp,0,sizeof(struct msp3400c));
-	msp->norm = VIDEO_MODE_NTSC;
-	msp->left = 58880;	/* 0db gain */
-	msp->right = 58880;	/* 0db gain */
-	msp->bass = 32768;
-	msp->treble = 32768;
-	msp->input = -1;
-	msp->muted = 0;
-	msp->i2s_mode = 0;
-	for (i = 0; i < DFP_COUNT; i++)
-		msp->dfp_regs[i] = -1;
-
-	i2c_set_clientdata(client, msp);
-	init_waitqueue_head(&msp->wq);
-
-	if (-1 == msp3400c_reset(client)) {
-		kfree(msp);
-		kfree(client);
-		msp3400_dbg("no chip found\n");
-		return -1;
-	}
-
-	msp->rev1 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1e);
-	if (-1 != msp->rev1)
-		msp->rev2 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1f);
-	if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) {
-		kfree(msp);
-		kfree(client);
-		msp3400_dbg("error while reading chip version\n");
-		return -1;
-	}
-	msp3400_dbg("rev1=0x%04x, rev2=0x%04x\n", msp->rev1, msp->rev2);
-
-	msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
-
-	snprintf(client->name, sizeof(client->name), "MSP%c4%02d%c-%c%d",
-		 ((msp->rev1>>4)&0x0f) + '3',
-		 (msp->rev2>>8)&0xff, (msp->rev1&0x0f)+'@',
-		 ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f);
-
-	msp->opmode = opmode;
-	if (OPMODE_AUTO == msp->opmode) {
-		if (HAVE_SIMPLER(msp))
-			msp->opmode = OPMODE_SIMPLER;
-		else if (HAVE_SIMPLE(msp))
-			msp->opmode = OPMODE_SIMPLE;
-		else
-			msp->opmode = OPMODE_MANUAL;
-	}
-
-	/* hello world :-) */
-	msp3400_info("chip=%s", client->name);
-	if (HAVE_NICAM(msp))
-		printk(" +nicam");
-	if (HAVE_SIMPLE(msp))
-		printk(" +simple");
-	if (HAVE_SIMPLER(msp))
-		printk(" +simpler");
-	if (HAVE_RADIO(msp))
-		printk(" +radio");
-
-	/* version-specific initialization */
-	switch (msp->opmode) {
-	case OPMODE_MANUAL:
-		printk(" mode=manual");
-		thread_func = msp3400c_thread;
-		break;
-	case OPMODE_SIMPLE:
-		printk(" mode=simple");
-		thread_func = msp3410d_thread;
-		break;
-	case OPMODE_SIMPLER:
-		printk(" mode=simpler");
-		thread_func = msp34xxg_thread;
-		break;
-	}
-	printk("\n");
-
-	/* startup control thread if needed */
-	if (thread_func) {
-		msp->kthread = kthread_run(thread_func, client, "msp34xx");
-
-		if (NULL == msp->kthread)
-			msp3400_warn("kernel_thread() failed\n");
-		msp_wake_thread(client);
-	}
-
-	/* done */
-	i2c_attach_client(client);
-
-	/* update our own array */
-	for (i = 0; i < MSP3400_MAX; i++) {
-		if (NULL == msps[i]) {
-			msps[i] = client;
-			break;
-		}
-	}
-
-	return 0;
-}
-
-static int msp_detach(struct i2c_client *client)
-{
-	struct msp3400c *msp  = i2c_get_clientdata(client);
-	int i;
-
-	/* shutdown control thread */
-	if (msp->kthread) {
-		msp->restart = 1;
-		kthread_stop(msp->kthread);
-	}
-	msp3400c_reset(client);
-
-	/* update our own array */
-	for (i = 0; i < MSP3400_MAX; i++) {
-		if (client == msps[i]) {
-			msps[i] = NULL;
-			break;
-		}
-	}
-
-	i2c_detach_client(client);
-
-	kfree(msp);
-	kfree(client);
-	return 0;
-}
-
-static int msp_probe(struct i2c_adapter *adap)
-{
-	if (adap->class & I2C_CLASS_TV_ANALOG)
-		return i2c_probe(adap, &addr_data, msp_attach);
-	return 0;
-}
-
-static void msp_wake_thread(struct i2c_client *client)
-{
-	struct msp3400c *msp  = i2c_get_clientdata(client);
-
-	if (NULL == msp->kthread)
-		return;
-	msp3400c_setvolume(client,msp->muted,0,0);
-	msp->watch_stereo = 0;
-	msp->restart = 1;
-	wake_up_interruptible(&msp->wq);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int mode_v4l2_to_v4l1(int rxsubchans)
-{
-	int mode = 0;
-
-	if (rxsubchans & V4L2_TUNER_SUB_STEREO)
-		mode |= VIDEO_SOUND_STEREO;
-	if (rxsubchans & V4L2_TUNER_SUB_LANG2)
-		mode |= VIDEO_SOUND_LANG2;
-	if (rxsubchans & V4L2_TUNER_SUB_LANG1)
-		mode |= VIDEO_SOUND_LANG1;
-	if (0 == mode)
-		mode |= VIDEO_SOUND_MONO;
-	return mode;
-}
-
-static int mode_v4l1_to_v4l2(int mode)
-{
-	if (mode & VIDEO_SOUND_STEREO)
-		return V4L2_TUNER_MODE_STEREO;
-	if (mode & VIDEO_SOUND_LANG2)
-		return V4L2_TUNER_MODE_LANG2;
-	if (mode & VIDEO_SOUND_LANG1)
-		return V4L2_TUNER_MODE_LANG1;
-	return V4L2_TUNER_MODE_MONO;
-}
-
-static void msp_any_detect_stereo(struct i2c_client *client)
-{
-	struct msp3400c *msp  = i2c_get_clientdata(client);
-
-	switch (msp->opmode) {
-	case OPMODE_MANUAL:
-	case OPMODE_SIMPLE:
-		autodetect_stereo(client);
-		break;
-	case OPMODE_SIMPLER:
-		msp34xxg_detect_stereo(client);
-		break;
-	}
-}
-
-static void msp_any_set_audmode(struct i2c_client *client, int audmode)
-{
-	struct msp3400c *msp  = i2c_get_clientdata(client);
-
-	switch (msp->opmode) {
-	case OPMODE_MANUAL:
-	case OPMODE_SIMPLE:
-		msp->watch_stereo = 0;
-		msp3400c_setstereo(client, audmode);
-		break;
-	case OPMODE_SIMPLER:
-		msp34xxg_set_audmode(client, audmode);
-		break;
-	}
-}
-
-
-static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
-{
-	struct msp3400c *msp  = i2c_get_clientdata(client);
-	__u16           *sarg = arg;
-	int scart = 0;
-
-	switch (cmd) {
-
-	case AUDC_SET_INPUT:
-		msp3400_dbg("AUDC_SET_INPUT(%d)\n",*sarg);
-
-		if (*sarg == msp->input)
-			break;
-		msp->input = *sarg;
-		switch (*sarg) {
-		case AUDIO_RADIO:
-			/* Hauppauge uses IN2 for the radio */
-			msp->mode   = MSP_MODE_FM_RADIO;
-			scart       = SCART_IN2;
-			break;
-		case AUDIO_EXTERN_1:
-			/* IN1 is often used for external input ... */
-			msp->mode   = MSP_MODE_EXTERN;
-			scart       = SCART_IN1;
-			break;
-		case AUDIO_EXTERN_2:
-			/* ... sometimes it is IN2 through ;) */
-			msp->mode   = MSP_MODE_EXTERN;
-			scart       = SCART_IN2;
-			break;
-		case AUDIO_TUNER:
-			msp->mode   = -1;
-			break;
-		default:
-			if (*sarg & AUDIO_MUTE)
-				msp3400c_set_scart(client,SCART_MUTE,0);
-			break;
-		}
-		if (scart) {
-			msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
-			msp->audmode = V4L2_TUNER_MODE_STEREO;
-			msp3400c_set_scart(client,scart,0);
-			msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
-			if (msp->opmode != OPMODE_SIMPLER)
-				msp3400c_setstereo(client, msp->audmode);
-		}
-		msp_wake_thread(client);
-		break;
-
-	case AUDC_SET_RADIO:
-		msp3400_dbg("AUDC_SET_RADIO\n");
-		msp->norm = VIDEO_MODE_RADIO;
-		msp3400_dbg("switching to radio mode\n");
-		msp->watch_stereo = 0;
-		switch (msp->opmode) {
-		case OPMODE_MANUAL:
-			/* set msp3400 to FM radio mode */
-			msp3400c_setmode(client,MSP_MODE_FM_RADIO);
-			msp3400c_setcarrier(client, MSP_CARRIER(10.7),
-					    MSP_CARRIER(10.7));
-			msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
-			break;
-		case OPMODE_SIMPLE:
-		case OPMODE_SIMPLER:
-			/* the thread will do for us */
-			msp_wake_thread(client);
-			break;
-		}
-		break;
-		/* work-in-progress:  hook to control the DFP registers */
-	case MSP_SET_DFPREG:
-	{
-		struct msp_dfpreg *r = arg;
-		int i;
-
-		if (r->reg < 0 || r->reg >= DFP_COUNT)
-			return -EINVAL;
-		for (i = 0; i < sizeof(bl_dfp) / sizeof(int); i++)
-			if (r->reg == bl_dfp[i])
-				return -EINVAL;
-		msp->dfp_regs[r->reg] = r->value;
-		msp3400c_write(client, I2C_MSP3400C_DFP, r->reg, r->value);
-		return 0;
-	}
-	case MSP_GET_DFPREG:
-	{
-		struct msp_dfpreg *r = arg;
-
-		if (r->reg < 0 || r->reg >= DFP_COUNT)
-			return -EINVAL;
-		r->value = msp3400c_read(client, I2C_MSP3400C_DFP, r->reg);
-		return 0;
-	}
-
-	/* --- v4l ioctls --- */
-	/* take care: bttv does userspace copying, we'll get a
-	   kernel pointer here... */
-	case VIDIOCGAUDIO:
-	{
-		struct video_audio *va = arg;
-
-		msp3400_dbg("VIDIOCGAUDIO\n");
-		va->flags |= VIDEO_AUDIO_VOLUME |
-			VIDEO_AUDIO_BASS |
-			VIDEO_AUDIO_TREBLE |
-			VIDEO_AUDIO_MUTABLE;
-		if (msp->muted)
-			va->flags |= VIDEO_AUDIO_MUTE;
-
-		if (msp->muted)
-			va->flags |= VIDEO_AUDIO_MUTE;
-		va->volume = MAX(msp->left, msp->right);
-		va->balance = (32768 * MIN(msp->left, msp->right)) /
-		    (va->volume ? va->volume : 1);
-		va->balance = (msp->left < msp->right) ?
-		    (65535 - va->balance) : va->balance;
-		if (0 == va->volume)
-			va->balance = 32768;
-		va->bass = msp->bass;
-		va->treble = msp->treble;
-
-		msp_any_detect_stereo(client);
-		va->mode = mode_v4l2_to_v4l1(msp->rxsubchans);
-		break;
-	}
-	case VIDIOCSAUDIO:
-	{
-		struct video_audio *va = arg;
-
-		msp3400_dbg("VIDIOCSAUDIO\n");
-		msp->muted = (va->flags & VIDEO_AUDIO_MUTE);
-		msp->left = (MIN(65536 - va->balance, 32768) *
-			     va->volume) / 32768;
-		msp->right = (MIN(va->balance, 32768) * va->volume) / 32768;
-		msp->bass = va->bass;
-		msp->treble = va->treble;
-		msp3400_dbg("VIDIOCSAUDIO setting va->volume to %d\n",
-			va->volume);
-		msp3400_dbg("VIDIOCSAUDIO setting va->balance to %d\n",
-			va->balance);
-		msp3400_dbg("VIDIOCSAUDIO setting va->flags to %d\n",
-			va->flags);
-		msp3400_dbg("VIDIOCSAUDIO setting msp->left to %d\n",
-			msp->left);
-		msp3400_dbg("VIDIOCSAUDIO setting msp->right to %d\n",
-			msp->right);
-		msp3400_dbg("VIDIOCSAUDIO setting msp->bass to %d\n",
-			msp->bass);
-		msp3400_dbg("VIDIOCSAUDIO setting msp->treble to %d\n",
-			msp->treble);
-		msp3400_dbg("VIDIOCSAUDIO setting msp->mode to %d\n",
-			msp->mode);
-		msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
-		msp3400c_setbass(client, msp->bass);
-		msp3400c_settreble(client, msp->treble);
-
-		if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO)
-			msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode));
-		break;
-	}
-
-	case VIDIOCSCHAN:
-	{
-		struct video_channel *vc = arg;
-
-		msp3400_dbg("VIDIOCSCHAN (norm=%d)\n",vc->norm);
-		msp->norm = vc->norm;
-		msp_wake_thread(client);
-		break;
-	}
-
-	case VIDIOCSFREQ:
-	case VIDIOC_S_FREQUENCY:
-	{
-		/* new channel -- kick audio carrier scan */
-		msp3400_dbg("VIDIOCSFREQ\n");
-		msp_wake_thread(client);
-		break;
-	}
-
-	/* msp34xx specific */
-	case MSP_SET_MATRIX:
-	{
-		struct msp_matrix *mspm = arg;
-
-		msp3400_dbg("MSP_SET_MATRIX\n");
-		msp3400c_set_scart(client, mspm->input, mspm->output);
-		break;
-	}
-
-	/* --- v4l2 ioctls --- */
-	case VIDIOC_S_STD:
-	{
-		v4l2_std_id *id = arg;
-
-		/*FIXME: use V4L2 mode flags on msp3400 instead of V4L1*/
-		if (*id & V4L2_STD_PAL) {
-			msp->norm=VIDEO_MODE_PAL;
-		} else if (*id & V4L2_STD_SECAM) {
-			msp->norm=VIDEO_MODE_SECAM;
-		} else {
-			msp->norm=VIDEO_MODE_NTSC;
-		}
-
-		msp_wake_thread(client);
-		return 0;
-	}
-
-	case VIDIOC_ENUMINPUT:
-	{
-		struct v4l2_input *i = arg;
-
-		if (i->index != 0)
-			return -EINVAL;
-
-		i->type = V4L2_INPUT_TYPE_TUNER;
-		switch (i->index) {
-		case AUDIO_RADIO:
-			strcpy(i->name,"Radio");
-			break;
-		case AUDIO_EXTERN_1:
-			strcpy(i->name,"Extern 1");
-			break;
-		case AUDIO_EXTERN_2:
-			strcpy(i->name,"Extern 2");
-			break;
-		case AUDIO_TUNER:
-			strcpy(i->name,"Television");
-			break;
-		default:
-			return -EINVAL;
-		}
-		return 0;
-	}
-
-	case VIDIOC_G_AUDIO:
-	{
-		struct v4l2_audio *a = arg;
-
-		memset(a,0,sizeof(*a));
-
-		switch (a->index) {
-		case AUDIO_RADIO:
-			strcpy(a->name,"Radio");
-			break;
-		case AUDIO_EXTERN_1:
-			strcpy(a->name,"Extern 1");
-			break;
-		case AUDIO_EXTERN_2:
-			strcpy(a->name,"Extern 2");
-			break;
-		case AUDIO_TUNER:
-			strcpy(a->name,"Television");
-			break;
-		default:
-			return -EINVAL;
-		}
-
-		msp_any_detect_stereo(client);
-		if (msp->audmode == V4L2_TUNER_MODE_STEREO) {
-			a->capability=V4L2_AUDCAP_STEREO;
-		}
-
-		break;
-	}
-	case VIDIOC_S_AUDIO:
-	{
-		struct v4l2_audio *sarg = arg;
-
-		switch (sarg->index) {
-		case AUDIO_RADIO:
-			/* Hauppauge uses IN2 for the radio */
-			msp->mode   = MSP_MODE_FM_RADIO;
-			scart       = SCART_IN2;
-			break;
-		case AUDIO_EXTERN_1:
-			/* IN1 is often used for external input ... */
-			msp->mode   = MSP_MODE_EXTERN;
-			scart       = SCART_IN1;
-			break;
-		case AUDIO_EXTERN_2:
-			/* ... sometimes it is IN2 through ;) */
-			msp->mode   = MSP_MODE_EXTERN;
-			scart       = SCART_IN2;
-			break;
-		case AUDIO_TUNER:
-			msp->mode   = -1;
-			break;
-		}
-		if (scart) {
-			msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
-			msp->audmode = V4L2_TUNER_MODE_STEREO;
-			msp3400c_set_scart(client,scart,0);
-			msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
-		}
-		if (sarg->capability==V4L2_AUDCAP_STEREO) {
-			msp->audmode = V4L2_TUNER_MODE_STEREO;
-		} else {
-			msp->audmode &= ~V4L2_TUNER_MODE_STEREO;
-		}
-		msp_any_set_audmode(client, msp->audmode);
-		msp_wake_thread(client);
-		break;
-	}
-	case VIDIOC_G_TUNER:
-	{
-		struct v4l2_tuner *vt = arg;
-
-		msp_any_detect_stereo(client);
-		vt->audmode    = msp->audmode;
-		vt->rxsubchans = msp->rxsubchans;
-		vt->capability = V4L2_TUNER_CAP_STEREO |
-			V4L2_TUNER_CAP_LANG1|
-			V4L2_TUNER_CAP_LANG2;
-		break;
-	}
-	case VIDIOC_S_TUNER:
-	{
-		struct v4l2_tuner *vt=(struct v4l2_tuner *)arg;
-
-		/* only set audmode */
-		if (vt->audmode != -1 && vt->audmode != 0)
-			msp_any_set_audmode(client, vt->audmode);
-		break;
-	}
-
-	case VIDIOC_G_AUDOUT:
-	{
-		struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
-		int idx=a->index;
-
-		memset(a,0,sizeof(*a));
-
-		switch (idx) {
-		case 0:
-			strcpy(a->name,"Scart1 Out");
-			break;
-		case 1:
-			strcpy(a->name,"Scart2 Out");
-			break;
-		case 2:
-			strcpy(a->name,"I2S Out");
-			break;
-		default:
-			return -EINVAL;
-		}
-		break;
-
-	}
-	case VIDIOC_S_AUDOUT:
-	{
-		struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
-
-		if (a->index<0||a->index>2)
-			return -EINVAL;
-
-		if (a->index==2) {
-			if (a->mode == V4L2_AUDMODE_32BITS)
-				msp->i2s_mode=1;
-			else
-				msp->i2s_mode=0;
-		}
-		msp3400_dbg("Setting audio out on msp34xx to input %i, mode %i\n",
-						a->index,msp->i2s_mode);
-		msp3400c_set_scart(client,msp->in_scart,a->index+1);
-
-		break;
-	}
-
-	default:
-		/* nothing */
-		break;
-	}
-	return 0;
-}
-
-static int msp_suspend(struct device * dev, pm_message_t state)
-{
-	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
-
-	msp3400_dbg("msp34xx: suspend\n");
-	msp3400c_reset(client);
-	return 0;
-}
-
-static int msp_resume(struct device * dev)
-{
-	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
-
-	msp3400_dbg("msp34xx: resume\n");
-	msp_wake_thread(client);
-	return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int __init msp3400_init_module(void)
-{
-	return i2c_add_driver(&driver);
-}
-
-static void __exit msp3400_cleanup_module(void)
-{
-	i2c_del_driver(&driver);
-}
-
-module_init(msp3400_init_module);
-module_exit(msp3400_cleanup_module);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/video/msp3400.h b/drivers/media/video/msp3400.h
index 2d9ff40..8a05cf5 100644
--- a/drivers/media/video/msp3400.h
+++ b/drivers/media/video/msp3400.h
@@ -6,22 +6,28 @@
 
 /* ---------------------------------------------------------------------- */
 
-struct msp_dfpreg {
-    int reg;
-    int value;
-};
-
 struct msp_matrix {
   int input;
   int output;
 };
 
-#define MSP_SET_DFPREG     _IOW('m',15,struct msp_dfpreg)
-#define MSP_GET_DFPREG     _IOW('m',16,struct msp_dfpreg)
-
 /* ioctl for MSP_SET_MATRIX will have to be registered */
 #define MSP_SET_MATRIX     _IOW('m',17,struct msp_matrix)
 
+/* This macro is allowed for *constants* only, gcc must calculate it
+   at compile time.  Remember -- no floats in kernel mode */
+#define MSP_CARRIER(freq) ((int)((float)(freq / 18.432) * (1 << 24)))
+
+#define MSP_MODE_AM_DETECT   0
+#define MSP_MODE_FM_RADIO    2
+#define MSP_MODE_FM_TERRA    3
+#define MSP_MODE_FM_SAT      4
+#define MSP_MODE_FM_NICAM1   5
+#define MSP_MODE_FM_NICAM2   6
+#define MSP_MODE_AM_NICAM    7
+#define MSP_MODE_BTSC        8
+#define MSP_MODE_EXTERN      9
+
 #define SCART_MASK    0
 #define SCART_IN1     1
 #define SCART_IN2     2
@@ -36,4 +42,84 @@
 #define SCART1_OUT    1
 #define SCART2_OUT    2
 
+#define OPMODE_AUTO       -1
+#define OPMODE_MANUAL      0
+#define OPMODE_AUTODETECT  1   /* use autodetect (>= msp3410 only) */
+#define OPMODE_AUTOSELECT  2   /* use autodetect & autoselect (>= msp34xxG)   */
+
+/* module parameters */
+extern int debug;
+extern int once;
+extern int amsound;
+extern int standard;
+extern int dolby;
+extern int stereo_threshold;
+
+struct msp_state {
+	int rev1, rev2;
+	u8 has_nicam;
+	u8 has_radio;
+	u8 has_headphones;
+	u8 has_ntsc_jp_d_k3;
+	u8 has_scart4;
+	u8 has_scart23_in_scart2_out;
+	u8 has_scart2_out_volume;
+	u8 has_i2s_conf;
+	u8 has_subwoofer;
+	u8 has_sound_processing;
+	u8 has_virtual_dolby_surround;
+	u8 has_dolby_pro_logic;
+
+	int radio;
+	int opmode;
+	int std;
+	int mode;
+	v4l2_std_id v4l2_std;
+	int nicam_on;
+	int acb;
+	int in_scart;
+	int i2s_mode;
+	int main, second;	/* sound carrier */
+	int input;
+	int source;             /* see msp34xxg_set_source */
+
+	/* v4l2 */
+	int audmode;
+	int rxsubchans;
+
+	int volume, muted;
+	int balance, loudness;
+	int bass, treble;
+
+	/* thread */
+	struct task_struct   *kthread;
+	wait_queue_head_t    wq;
+	int                  restart:1;
+	int                  watch_stereo:1;
+};
+
+/* msp3400-driver.c */
+int msp_write_dem(struct i2c_client *client, int addr, int val);
+int msp_write_dsp(struct i2c_client *client, int addr, int val);
+int msp_read_dem(struct i2c_client *client, int addr);
+int msp_read_dsp(struct i2c_client *client, int addr);
+int msp_reset(struct i2c_client *client);
+void msp_set_scart(struct i2c_client *client, int in, int out);
+void msp_set_mute(struct i2c_client *client);
+void msp_set_audio(struct i2c_client *client);
+int msp_modus(struct i2c_client *client);
+int msp_sleep(struct msp_state *state, int timeout);
+
+/* msp3400-kthreads.c */
+const char *msp_standard_std_name(int std);
+void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2);
+void msp3400c_setmode(struct i2c_client *client, int type);
+void msp3400c_setstereo(struct i2c_client *client, int mode);
+int autodetect_stereo(struct i2c_client *client);
+int msp3400c_thread(void *data);
+int msp3410d_thread(void *data);
+int msp34xxg_thread(void *data);
+void msp34xxg_detect_stereo(struct i2c_client *client);
+void msp34xxg_set_audmode(struct i2c_client *client, int audmode);
+
 #endif /* MSP3400_H */
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c
index 2180018..2c19c95 100644
--- a/drivers/media/video/mt20xx.c
+++ b/drivers/media/video/mt20xx.c
@@ -20,6 +20,9 @@
 static unsigned int radio_antenna = 0;
 module_param(radio_antenna,     int, 0644);
 
+/* from tuner-core.c */
+extern int debug;
+
 /* ---------------------------------------------------------------------- */
 
 #define MT2032 0x04
@@ -401,7 +404,7 @@
 	div2a=(lo2/8)-1;
 	div2b=lo2-(div2a+1)*8;
 
-	if (tuner_debug > 1) {
+	if (debug > 1) {
 		tuner_dbg("lo1 lo2 = %d %d\n", lo1, lo2);
 		tuner_dbg("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n",
 			  num1,num2,div1a,div1b,div2a,div2b);
@@ -417,7 +420,7 @@
 	buf[5]=div2a;
 	if(num2!=0) buf[5]=buf[5]|0x40;
 
-	if (tuner_debug > 1) {
+	if (debug > 1) {
 		int i;
 		tuner_dbg("bufs is: ");
 		for(i=0;i<6;i++)
@@ -494,11 +497,18 @@
 	t->tv_freq    = NULL;
 	t->radio_freq = NULL;
 	t->standby    = NULL;
+	if (t->std & V4L2_STD_525_60) {
+		tuner_dbg("pinnacle ntsc\n");
+		t->radio_if2 = 41300 * 1000;
+	} else {
+		tuner_dbg("pinnacle pal\n");
+		t->radio_if2 = 33300 * 1000;
+	}
 	name = "unknown";
 
 	i2c_master_send(c,buf,1);
 	i2c_master_recv(c,buf,21);
-	if (tuner_debug) {
+	if (debug) {
 		int i;
 		tuner_dbg("MT20xx hexdump:");
 		for(i=0;i<21;i++) {
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index d04793f..91681aa 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -26,6 +26,7 @@
 #include <media/saa7146_vv.h>
 #include <media/tuner.h>
 #include <linux/video_decoder.h>
+#include <media/v4l2-common.h>
 
 #include "mxb.h"
 #include "tea6415c.h"
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index 2504207..9e64486 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -883,6 +883,7 @@
 	.open           = video_exclusive_open,
 	.release        = video_exclusive_release,
 	.ioctl          = pms_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.read           = pms_read,
 	.llseek         = no_llseek,
 };
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
index a51c7bd..73b4f0e 100644
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -702,6 +702,7 @@
 	.open		= saa5249_open,
 	.release       	= saa5249_release,
 	.ioctl          = saa5249_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek         = no_llseek,
 };
 
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
index d60a783..e70b17e 100644
--- a/drivers/media/video/saa6588.c
+++ b/drivers/media/video/saa6588.c
@@ -427,18 +427,8 @@
 
 static int saa6588_probe(struct i2c_adapter *adap)
 {
-#ifdef I2C_CLASS_TV_ANALOG
 	if (adap->class & I2C_CLASS_TV_ANALOG)
 		return i2c_probe(adap, &addr_data, saa6588_attach);
-#else
-	switch (adap->id) {
-	case I2C_HW_B_BT848:
-	case I2C_HW_B_RIVA:
-	case I2C_HW_SAA7134:
-		return i2c_probe(adap, &addr_data, saa6588_attach);
-		break;
-	}
-#endif
 	return 0;
 }
 
@@ -496,7 +486,7 @@
 
 static struct i2c_driver driver = {
 	.driver = {
-		.name = "i2c saa6588 driver",
+		.name = "saa6588",
 	},
 	.id = -1,		/* FIXME */
 	.attach_adapter = saa6588_probe,
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 29e28c7..4a4bc69 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -39,31 +39,18 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
+#include <media/audiochip.h>
+#include <asm/div64.h>
 
 MODULE_DESCRIPTION("Philips SAA7114/SAA7115 video decoder driver");
 MODULE_AUTHOR("Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, Hans Verkuil");
 MODULE_LICENSE("GPL");
 
 static int debug = 0;
-module_param(debug, int, 0644);
+module_param(debug, bool, 0644);
 
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
-#define saa7115_dbg(fmt,arg...) \
-	do { \
-		if (debug) \
-			printk(KERN_INFO "%s debug %d-%04x: " fmt, \
-			       client->driver->driver.name, \
-			       i2c_adapter_id(client->adapter), client->addr , ## arg); \
-	} while (0)
-
-#define saa7115_err(fmt, arg...) do { \
-	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
-	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-#define saa7115_info(fmt, arg...) do { \
-	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
-	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-
 static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END };
 
 
@@ -73,12 +60,13 @@
 	v4l2_std_id std;
 	int input;
 	int enable;
+	int radio;
 	int bright;
 	int contrast;
 	int hue;
 	int sat;
 	enum v4l2_chip_ident ident;
-	enum v4l2_audio_clock_freq audclk_freq;
+	u32 audclk_freq;
 };
 
 /* ----------------------------------------------------------------------- */
@@ -469,80 +457,6 @@
 	0x00, 0x00
 };
 
-/* ============== SAA7715 AUDIO settings ============= */
-
-/* 48.0 kHz */
-static const unsigned char saa7115_cfg_48_audio[] = {
-	0x34, 0xce,
-	0x35, 0xfb,
-	0x36, 0x30,
-	0x00, 0x00
-};
-
-/* 44.1 kHz */
-static const unsigned char saa7115_cfg_441_audio[] = {
-	0x34, 0xf2,
-	0x35, 0x00,
-	0x36, 0x2d,
-	0x00, 0x00
-};
-
-/* 32.0 kHz */
-static const unsigned char saa7115_cfg_32_audio[] = {
-	0x34, 0xdf,
-	0x35, 0xa7,
-	0x36, 0x20,
-	0x00, 0x00
-};
-
-/* 48.0 kHz 60hz */
-static const unsigned char saa7115_cfg_60hz_48_audio[] = {
-	0x30, 0xcd,
-	0x31, 0x20,
-	0x32, 0x03,
-	0x00, 0x00
-};
-
-/* 48.0 kHz 50hz */
-static const unsigned char saa7115_cfg_50hz_48_audio[] = {
-	0x30, 0x00,
-	0x31, 0xc0,
-	0x32, 0x03,
-	0x00, 0x00
-};
-
-/* 44.1 kHz 60hz */
-static const unsigned char saa7115_cfg_60hz_441_audio[] = {
-	0x30, 0xbc,
-	0x31, 0xdf,
-	0x32, 0x02,
-	0x00, 0x00
-};
-
-/* 44.1 kHz 50hz */
-static const unsigned char saa7115_cfg_50hz_441_audio[] = {
-	0x30, 0x00,
-	0x31, 0x72,
-	0x32, 0x03,
-	0x00, 0x00
-};
-
-/* 32.0 kHz 60hz */
-static const unsigned char saa7115_cfg_60hz_32_audio[] = {
-	0x30, 0xde,
-	0x31, 0x15,
-	0x32, 0x02,
-	0x00, 0x00
-};
-
-/* 32.0 kHz 50hz */
-static const unsigned char saa7115_cfg_50hz_32_audio[] = {
-	0x30, 0x00,
-	0x31, 0x80,
-	0x32, 0x02,
-	0x00, 0x00
-};
-
 static int saa7115_odd_parity(u8 c)
 {
 	c ^= (c >> 4);
@@ -627,40 +541,38 @@
 }
 
 
-static int saa7115_set_audio_clock_freq(struct i2c_client *client, enum v4l2_audio_clock_freq freq)
+static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq)
 {
 	struct saa7115_state *state = i2c_get_clientdata(client);
+	u32 acpf;
+	u32 acni;
+	u32 hz;
+	u64 f;
 
-	saa7115_dbg("set audio clock freq: %d\n", freq);
-	switch (freq) {
-		case V4L2_AUDCLK_32_KHZ:
-			saa7115_writeregs(client, saa7115_cfg_32_audio);
-			if (state->std & V4L2_STD_525_60) {
-				saa7115_writeregs(client, saa7115_cfg_60hz_32_audio);
-			} else {
-				saa7115_writeregs(client, saa7115_cfg_50hz_32_audio);
-			}
-			break;
-		case V4L2_AUDCLK_441_KHZ:
-			saa7115_writeregs(client, saa7115_cfg_441_audio);
-			if (state->std & V4L2_STD_525_60) {
-				saa7115_writeregs(client, saa7115_cfg_60hz_441_audio);
-			} else {
-				saa7115_writeregs(client, saa7115_cfg_50hz_441_audio);
-			}
-			break;
-		case V4L2_AUDCLK_48_KHZ:
-			saa7115_writeregs(client, saa7115_cfg_48_audio);
-			if (state->std & V4L2_STD_525_60) {
-				saa7115_writeregs(client, saa7115_cfg_60hz_48_audio);
-			} else {
-				saa7115_writeregs(client, saa7115_cfg_50hz_48_audio);
-			}
-			break;
-		default:
-			saa7115_dbg("invalid audio setting %d\n", freq);
-			return -EINVAL;
-	}
+	v4l_dbg(1, client, "set audio clock freq: %d\n", freq);
+
+	/* sanity check */
+	if (freq < 32000 || freq > 48000)
+		return -EINVAL;
+
+	/* hz is the refresh rate times 100 */
+	hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000;
+	/* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */
+	acpf = (25600 * freq) / hz;
+	/* acni = (256 * freq * 2^23) / crystal_frequency =
+		  (freq * 2^(8+23)) / crystal_frequency =
+		  (freq << 31) / 32.11 MHz */
+	f = freq;
+	f = f << 31;
+	do_div(f, 32110000);
+	acni = f;
+
+	saa7115_write(client, 0x30, acpf & 0xff);
+	saa7115_write(client, 0x31, (acpf >> 8) & 0xff);
+	saa7115_write(client, 0x32, (acpf >> 16) & 0x03);
+	saa7115_write(client, 0x34, acni & 0xff);
+	saa7115_write(client, 0x35, (acni >> 8) & 0xff);
+	saa7115_write(client, 0x36, (acni >> 16) & 0x3f);
 	state->audclk_freq = freq;
 	return 0;
 }
@@ -672,7 +584,7 @@
 	switch (ctrl->id) {
 	case V4L2_CID_BRIGHTNESS:
 		if (ctrl->value < 0 || ctrl->value > 255) {
-			saa7115_err("invalid brightness setting %d\n", ctrl->value);
+			v4l_err(client, "invalid brightness setting %d\n", ctrl->value);
 			return -ERANGE;
 		}
 
@@ -682,7 +594,7 @@
 
 	case V4L2_CID_CONTRAST:
 		if (ctrl->value < 0 || ctrl->value > 127) {
-			saa7115_err("invalid contrast setting %d\n", ctrl->value);
+			v4l_err(client, "invalid contrast setting %d\n", ctrl->value);
 			return -ERANGE;
 		}
 
@@ -692,7 +604,7 @@
 
 	case V4L2_CID_SATURATION:
 		if (ctrl->value < 0 || ctrl->value > 127) {
-			saa7115_err("invalid saturation setting %d\n", ctrl->value);
+			v4l_err(client, "invalid saturation setting %d\n", ctrl->value);
 			return -ERANGE;
 		}
 
@@ -702,13 +614,16 @@
 
 	case V4L2_CID_HUE:
 		if (ctrl->value < -127 || ctrl->value > 127) {
-			saa7115_err("invalid hue setting %d\n", ctrl->value);
+			v4l_err(client, "invalid hue setting %d\n", ctrl->value);
 			return -ERANGE;
 		}
 
 		state->hue = ctrl->value;
 		saa7115_write(client, 0x0d, state->hue);
 		break;
+
+	default:
+		return -EINVAL;
 	}
 
 	return 0;
@@ -743,12 +658,22 @@
 	struct saa7115_state *state = i2c_get_clientdata(client);
 	int taskb = saa7115_read(client, 0x80) & 0x10;
 
+	/* Prevent unnecessary standard changes. During a standard
+	   change the I-Port is temporarily disabled. Any devices
+	   reading from that port can get confused.
+	   Note that VIDIOC_S_STD is also used to switch from
+	   radio to TV mode, so if a VIDIOC_S_STD is broadcast to
+	   all I2C devices then you do not want to have an unwanted
+	   side-effect here. */
+	if (std == state->std)
+		return;
+
 	// This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
 	if (std & V4L2_STD_525_60) {
-		saa7115_dbg("decoder set standard 60 Hz\n");
+		v4l_dbg(1, client, "decoder set standard 60 Hz\n");
 		saa7115_writeregs(client, saa7115_cfg_60hz_video);
 	} else {
-		saa7115_dbg("decoder set standard 50 Hz\n");
+		v4l_dbg(1, client, "decoder set standard 50 Hz\n");
 		saa7115_writeregs(client, saa7115_cfg_50hz_video);
 	}
 
@@ -773,24 +698,17 @@
 static void saa7115_log_status(struct i2c_client *client)
 {
 	struct saa7115_state *state = i2c_get_clientdata(client);
-	char *audfreq = "undefined";
 	int reg1e, reg1f;
 	int signalOk;
 	int vcr;
 
-	switch (state->audclk_freq) {
-		case V4L2_AUDCLK_32_KHZ:  audfreq = "32 kHz"; break;
-		case V4L2_AUDCLK_441_KHZ: audfreq = "44.1 kHz"; break;
-		case V4L2_AUDCLK_48_KHZ:  audfreq = "48 kHz"; break;
-	}
-
-	saa7115_info("Audio frequency: %s\n", audfreq);
+	v4l_info(client, "Audio frequency: %d Hz\n", state->audclk_freq);
 	if (client->name[6] == '4') {
 		/* status for the saa7114 */
 		reg1f = saa7115_read(client, 0x1f);
 		signalOk = (reg1f & 0xc1) == 0x81;
-		saa7115_info("Video signal:    %s\n", signalOk ? "ok" : "bad");
-		saa7115_info("Frequency:       %s\n", (reg1f & 0x20) ? "60Hz" : "50Hz");
+		v4l_info(client, "Video signal:    %s\n", signalOk ? "ok" : "bad");
+		v4l_info(client, "Frequency:       %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
 		return;
 	}
 
@@ -801,21 +719,26 @@
 	signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
 	vcr = !(reg1f & 0x10);
 
-	saa7115_info("Video signal:    %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
-	saa7115_info("Frequency:       %s\n", (reg1f & 0x20) ? "60Hz" : "50Hz");
+	if (state->input >= 6) {
+		v4l_info(client, "Input:           S-Video %d\n", state->input - 6);
+	} else {
+		v4l_info(client, "Input:           Composite %d\n", state->input);
+	}
+	v4l_info(client, "Video signal:    %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
+	v4l_info(client, "Frequency:       %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
 
 	switch (reg1e & 0x03) {
 		case 1:
-			saa7115_info("Detected format: NTSC\n");
+			v4l_info(client, "Detected format: NTSC\n");
 			break;
 		case 2:
-			saa7115_info("Detected format: PAL\n");
+			v4l_info(client, "Detected format: PAL\n");
 			break;
 		case 3:
-			saa7115_info("Detected format: SECAM\n");
+			v4l_info(client, "Detected format: SECAM\n");
 			break;
 		default:
-			saa7115_info("Detected format: BW/No color\n");
+			v4l_info(client, "Detected format: BW/No color\n");
 			break;
 	}
 }
@@ -940,7 +863,7 @@
 
 	pix = &(fmt->fmt.pix);
 
-	saa7115_dbg("decoder set size\n");
+	v4l_dbg(1, client, "decoder set size\n");
 
 	/* FIXME need better bounds checking here */
 	if ((pix->width < 1) || (pix->width > 1440))
@@ -966,7 +889,7 @@
 		HPSC = HPSC ? HPSC : 1;
 		HFSC = (int)((1024 * 720) / (HPSC * pix->width));
 
-		saa7115_dbg("Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
+		v4l_dbg(1, client, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
 		/* FIXME hardcodes to "Task B"
 		 * write H prescaler integer */
 		saa7115_write(client, 0xd0, (u8) (HPSC & 0x3f));
@@ -980,10 +903,10 @@
 		saa7115_write(client, 0xDD, (u8) ((HFSC >> 9) & 0xff));
 	} else {
 		if (is_50hz) {
-			saa7115_dbg("Setting full 50hz width\n");
+			v4l_dbg(1, client, "Setting full 50hz width\n");
 			saa7115_writeregs(client, saa7115_cfg_50hz_fullres_x);
 		} else {
-			saa7115_dbg("Setting full 60hz width\n");
+			v4l_dbg(1, client, "Setting full 60hz width\n");
 			saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
 		}
 	}
@@ -992,7 +915,7 @@
 
 	if (pix->height != Vsrc) {
 		VSCY = (int)((1024 * Vsrc) / pix->height);
-		saa7115_dbg("Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
+		v4l_dbg(1, client, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
 
 		/* Correct Contrast and Luminance */
 		saa7115_write(client, 0xd5, (u8) (64 * 1024 / VSCY));
@@ -1006,10 +929,10 @@
 		saa7115_write(client, 0xe3, (u8) ((VSCY >> 8) & 0xff));
 	} else {
 		if (is_50hz) {
-			saa7115_dbg("Setting full 50Hz height\n");
+			v4l_dbg(1, client, "Setting full 50Hz height\n");
 			saa7115_writeregs(client, saa7115_cfg_50hz_fullres_y);
 		} else {
-			saa7115_dbg("Setting full 60hz height\n");
+			v4l_dbg(1, client, "Setting full 60hz height\n");
 			saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
 		}
 	}
@@ -1089,6 +1012,48 @@
 
 /* ============ SAA7115 AUDIO settings (end) ============= */
 
+static struct v4l2_queryctrl saa7115_qctrl[] = {
+	{
+		.id            = V4L2_CID_BRIGHTNESS,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+		.name          = "Brightness",
+		.minimum       = 0,
+		.maximum       = 255,
+		.step          = 1,
+		.default_value = 128,
+		.flags         = 0,
+	}, {
+		.id            = V4L2_CID_CONTRAST,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+		.name          = "Contrast",
+		.minimum       = 0,
+		.maximum       = 255,
+		.step          = 1,
+		.default_value = 64,
+		.flags         = 0,
+	}, {
+		.id            = V4L2_CID_SATURATION,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+		.name          = "Saturation",
+		.minimum       = 0,
+		.maximum       = 255,
+		.step          = 1,
+		.default_value = 64,
+		.flags         = 0,
+	}, {
+		.id            = V4L2_CID_HUE,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+		.name          = "Hue",
+		.minimum       = -128,
+		.maximum       = 127,
+		.step          = 1,
+		.default_value = 0,
+		.flags 	       = 0,
+	},
+};
+
+/* ----------------------------------------------------------------------- */
+
 static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg)
 {
 	struct saa7115_state *state = i2c_get_clientdata(client);
@@ -1103,16 +1068,18 @@
 		return saa7115_get_v4lfmt(client, (struct v4l2_format *)arg);
 
 	case VIDIOC_INT_AUDIO_CLOCK_FREQ:
-		return saa7115_set_audio_clock_freq(client, *(enum v4l2_audio_clock_freq *)arg);
+		return saa7115_set_audio_clock_freq(client, *(u32 *)arg);
 
 	case VIDIOC_G_TUNER:
 	{
 		struct v4l2_tuner *vt = arg;
 		int status;
 
+		if (state->radio)
+			break;
 		status = saa7115_read(client, 0x1f);
 
-		saa7115_dbg("status: 0x%02x\n", status);
+		v4l_dbg(1, client, "status: 0x%02x\n", status);
 		vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0;
 		break;
 	}
@@ -1127,20 +1094,38 @@
 	case VIDIOC_S_CTRL:
 		return saa7115_set_v4lctrl(client, (struct v4l2_control *)arg);
 
+	case VIDIOC_QUERYCTRL:
+	{
+		struct v4l2_queryctrl *qc = arg;
+		int i;
+
+		for (i = 0; i < ARRAY_SIZE(saa7115_qctrl); i++)
+			if (qc->id && qc->id == saa7115_qctrl[i].id) {
+				memcpy(qc, &saa7115_qctrl[i], sizeof(*qc));
+				return 0;
+			}
+		return -EINVAL;
+	}
+
 	case VIDIOC_G_STD:
 		*(v4l2_std_id *)arg = saa7115_get_v4lstd(client);
 		break;
 
 	case VIDIOC_S_STD:
+		state->radio = 0;
 		saa7115_set_v4lstd(client, *(v4l2_std_id *)arg);
 		break;
 
+	case AUDC_SET_RADIO:
+		state->radio = 1;
+		break;
+
 	case VIDIOC_G_INPUT:
 		*(int *)arg = state->input;
 		break;
 
 	case VIDIOC_S_INPUT:
-		saa7115_dbg("decoder set input %d\n", *iarg);
+		v4l_dbg(1, client, "decoder set input %d\n", *iarg);
 		/* inputs from 0-9 are available */
 		if (*iarg < 0 || *iarg > 9) {
 			return -EINVAL;
@@ -1148,7 +1133,7 @@
 
 		if (state->input == *iarg)
 			break;
-		saa7115_dbg("now setting %s input\n",
+		v4l_dbg(1, client, "now setting %s input\n",
 			*iarg >= 6 ? "S-Video" : "Composite");
 		state->input = *iarg;
 
@@ -1165,7 +1150,7 @@
 
 	case VIDIOC_STREAMON:
 	case VIDIOC_STREAMOFF:
-		saa7115_dbg("%s output\n",
+		v4l_dbg(1, client, "%s output\n",
 			(cmd == VIDIOC_STREAMON) ? "enable" : "disable");
 
 		if (state->enable != (cmd == VIDIOC_STREAMON)) {
@@ -1179,7 +1164,7 @@
 		break;
 
 	case VIDIOC_INT_RESET:
-		saa7115_dbg("decoder RESET\n");
+		v4l_dbg(1, client, "decoder RESET\n");
 		saa7115_writeregs(client, saa7115_cfg_reset_scaler);
 		break;
 
@@ -1273,19 +1258,19 @@
 	client->driver = &i2c_driver_saa7115;
 	snprintf(client->name, sizeof(client->name) - 1, "saa7115");
 
-	saa7115_dbg("detecting saa7115 client on address 0x%x\n", address << 1);
+	v4l_dbg(1, client, "detecting saa7115 client on address 0x%x\n", address << 1);
 
 	saa7115_write(client, 0, 5);
 	chip_id = saa7115_read(client, 0) & 0x0f;
 	if (chip_id != 4 && chip_id != 5) {
-		saa7115_dbg("saa7115 not found\n");
+		v4l_dbg(1, client, "saa7115 not found\n");
 		kfree(client);
 		return 0;
 	}
 	if (chip_id == 4) {
 		snprintf(client->name, sizeof(client->name) - 1, "saa7114");
 	}
-	saa7115_info("saa711%d found @ 0x%x (%s)\n", chip_id, address << 1, adapter->name);
+	v4l_info(client, "saa711%d found @ 0x%x (%s)\n", chip_id, address << 1, adapter->name);
 
 	state = kmalloc(sizeof(struct saa7115_state), GFP_KERNEL);
 	i2c_set_clientdata(client, state);
@@ -1297,14 +1282,15 @@
 	state->std = V4L2_STD_NTSC;
 	state->input = -1;
 	state->enable = 1;
+	state->radio = 0;
 	state->bright = 128;
 	state->contrast = 64;
 	state->hue = 0;
 	state->sat = 64;
 	state->ident = (chip_id == 4) ? V4L2_IDENT_SAA7114 : V4L2_IDENT_SAA7115;
-	state->audclk_freq = V4L2_AUDCLK_48_KHZ;
+	state->audclk_freq = 48000;
 
-	saa7115_dbg("writing init values\n");
+	v4l_dbg(1, client, "writing init values\n");
 
 	/* init to 60hz/48khz */
 	saa7115_writeregs(client, saa7115_init_auto_input);
@@ -1312,13 +1298,12 @@
 	saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
 	saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
 	saa7115_writeregs(client, saa7115_cfg_60hz_video);
-	saa7115_writeregs(client, saa7115_cfg_48_audio);
-	saa7115_writeregs(client, saa7115_cfg_60hz_48_audio);
+	saa7115_set_audio_clock_freq(client, state->audclk_freq);
 	saa7115_writeregs(client, saa7115_cfg_reset_scaler);
 
 	i2c_attach_client(client);
 
-	saa7115_dbg("status: (1E) 0x%02x, (1F) 0x%02x\n",
+	v4l_dbg(1, client, "status: (1E) 0x%02x, (1F) 0x%02x\n",
 		saa7115_read(client, 0x1e), saa7115_read(client, 0x1f));
 
 	return 0;
@@ -1326,11 +1311,7 @@
 
 static int saa7115_probe(struct i2c_adapter *adapter)
 {
-#ifdef I2C_CLASS_TV_ANALOG
 	if (adapter->class & I2C_CLASS_TV_ANALOG)
-#else
-	if (adapter->id == I2C_HW_B_BT848)
-#endif
 		return i2c_probe(adapter, &addr_data, &saa7115_attach);
 	return 0;
 }
diff --git a/drivers/media/video/saa711x.c b/drivers/media/video/saa711x.c
index 8008537..f39a7be 100644
--- a/drivers/media/video/saa711x.c
+++ b/drivers/media/video/saa711x.c
@@ -567,9 +567,7 @@
 	.driver = {
 		.name = "saa711x",
 	},
-
 	.id = I2C_DRIVERID_SAA711X,
-
 	.attach_adapter = saa711x_attach_adapter,
 	.detach_client = saa711x_detach_client,
 	.command = saa711x_command,
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index bca6ed0..2009c1b 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -66,30 +66,6 @@
 MODULE_PARM_DESC(debug, "debug level (0-2)");
 MODULE_PARM_DESC(test_image, "test_image (0-1)");
 
-#define saa7127_dbg(fmt, arg...) \
-	do { \
-		if (debug >= 1) \
-			printk(KERN_INFO "%s debug %d-%04x: " fmt, \
-			       client->driver->driver.name, \
-			       i2c_adapter_id(client->adapter), client->addr , ## arg); \
-	} while (0)
-
-/* High volume debug. Use with care. */
-#define saa7127_dbg_highvol(fmt, arg...) \
-	do { \
-		if (debug == 2) \
-			printk(KERN_INFO "%s debug %d-%04x: " fmt, \
-			       client->driver->driver.name, \
-			       i2c_adapter_id(client->adapter), client->addr , ## arg); \
-	} while (0)
-
-#define saa7127_err(fmt, arg...) do { \
-	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
-	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-#define saa7127_info(fmt, arg...) do { \
-	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
-	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-
 static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
 
 
@@ -336,7 +312,7 @@
 		if (i2c_smbus_write_byte_data(client, reg, val) == 0)
 			return 0;
 	}
-	saa7127_err("I2C Write Problem\n");
+	v4l_err(client, "I2C Write Problem\n");
 	return -1;
 }
 
@@ -362,7 +338,7 @@
 	if (enable && (data->field != 0 || data->line != 16))
 		return -EINVAL;
 	if (state->vps_enable != enable) {
-		saa7127_dbg("Turn VPS Signal %s\n", enable ? "on" : "off");
+		v4l_dbg(1, client, "Turn VPS Signal %s\n", enable ? "on" : "off");
 		saa7127_write(client, 0x54, enable << 7);
 		state->vps_enable = enable;
 	}
@@ -374,7 +350,7 @@
 	state->vps_data[2] = data->data[11];
 	state->vps_data[3] = data->data[12];
 	state->vps_data[4] = data->data[13];
-	saa7127_dbg("Set VPS data %02x %02x %02x %02x %02x\n",
+	v4l_dbg(1, client, "Set VPS data %02x %02x %02x %02x %02x\n",
 		state->vps_data[0], state->vps_data[1],
 		state->vps_data[2], state->vps_data[3],
 		state->vps_data[4]);
@@ -397,7 +373,7 @@
 	if (enable && (data->field != 0 || data->line != 21))
 		return -EINVAL;
 	if (state->cc_enable != enable) {
-		saa7127_dbg("Turn CC %s\n", enable ? "on" : "off");
+		v4l_dbg(1, client, "Turn CC %s\n", enable ? "on" : "off");
 		saa7127_write(client, SAA7127_REG_CLOSED_CAPTION,
 				(state->xds_enable << 7) | (enable << 6) | 0x11);
 		state->cc_enable = enable;
@@ -405,7 +381,7 @@
 	if (!enable)
 		return 0;
 
-	saa7127_dbg_highvol("CC data: %04x\n", cc);
+	v4l_dbg(2, client, "CC data: %04x\n", cc);
 	saa7127_write(client, SAA7127_REG_LINE_21_ODD_0, cc & 0xff);
 	saa7127_write(client, SAA7127_REG_LINE_21_ODD_1, cc >> 8);
 	state->cc_data = cc;
@@ -423,7 +399,7 @@
 	if (enable && (data->field != 1 || data->line != 21))
 		return -EINVAL;
 	if (state->xds_enable != enable) {
-		saa7127_dbg("Turn XDS %s\n", enable ? "on" : "off");
+		v4l_dbg(1, client, "Turn XDS %s\n", enable ? "on" : "off");
 		saa7127_write(client, SAA7127_REG_CLOSED_CAPTION,
 				(enable << 7) | (state->cc_enable << 6) | 0x11);
 		state->xds_enable = enable;
@@ -431,7 +407,7 @@
 	if (!enable)
 		return 0;
 
-	saa7127_dbg_highvol("XDS data: %04x\n", xds);
+	v4l_dbg(2, client, "XDS data: %04x\n", xds);
 	saa7127_write(client, SAA7127_REG_LINE_21_EVEN_0, xds & 0xff);
 	saa7127_write(client, SAA7127_REG_LINE_21_EVEN_1, xds >> 8);
 	state->xds_data = xds;
@@ -448,7 +424,7 @@
 	if (enable && (data->field != 0 || data->line != 23))
 		return -EINVAL;
 	if (state->wss_enable != enable) {
-		saa7127_dbg("Turn WSS %s\n", enable ? "on" : "off");
+		v4l_dbg(1, client, "Turn WSS %s\n", enable ? "on" : "off");
 		saa7127_write(client, 0x27, enable << 7);
 		state->wss_enable = enable;
 	}
@@ -457,7 +433,7 @@
 
 	saa7127_write(client, 0x26, data->data[0]);
 	saa7127_write(client, 0x27, 0x80 | (data->data[1] & 0x3f));
-	saa7127_dbg("WSS mode: %s\n", wss_strs[data->data[0] & 0xf]);
+	v4l_dbg(1, client, "WSS mode: %s\n", wss_strs[data->data[0] & 0xf]);
 	state->wss_mode = (data->data[1] & 0x3f) << 8 | data->data[0];
 	return 0;
 }
@@ -469,11 +445,11 @@
 	struct saa7127_state *state = i2c_get_clientdata(client);
 
 	if (enable) {
-		saa7127_dbg("Enable Video Output\n");
+		v4l_dbg(1, client, "Enable Video Output\n");
 		saa7127_write(client, 0x2d, state->reg_2d);
 		saa7127_write(client, 0x61, state->reg_61);
 	} else {
-		saa7127_dbg("Disable Video Output\n");
+		v4l_dbg(1, client, "Disable Video Output\n");
 		saa7127_write(client, 0x2d, (state->reg_2d & 0xf0));
 		saa7127_write(client, 0x61, (state->reg_61 | 0xc0));
 	}
@@ -489,11 +465,11 @@
 	const struct i2c_reg_value *inittab;
 
 	if (std & V4L2_STD_525_60) {
-		saa7127_dbg("Selecting 60 Hz video Standard\n");
+		v4l_dbg(1, client, "Selecting 60 Hz video Standard\n");
 		inittab = saa7127_init_config_60hz;
 		state->reg_61 = SAA7127_60HZ_DAC_CONTROL;
 	} else {
-		saa7127_dbg("Selecting 50 Hz video Standard\n");
+		v4l_dbg(1, client, "Selecting 50 Hz video Standard\n");
 		inittab = saa7127_init_config_50hz;
 		state->reg_61 = SAA7127_50HZ_DAC_CONTROL;
 	}
@@ -544,7 +520,7 @@
 	default:
 		return -EINVAL;
 	}
-	saa7127_dbg("Selecting %s output type\n", output_strs[output]);
+	v4l_dbg(1, client, "Selecting %s output type\n", output_strs[output]);
 
 	/* Configure Encoder */
 	saa7127_write(client, 0x2d, state->reg_2d);
@@ -561,12 +537,12 @@
 
 	switch (input) {
 	case SAA7127_INPUT_TYPE_NORMAL:	/* avia */
-		saa7127_dbg("Selecting Normal Encoder Input\n");
+		v4l_dbg(1, client, "Selecting Normal Encoder Input\n");
 		state->reg_3a_cb = 0;
 		break;
 
 	case SAA7127_INPUT_TYPE_TEST_IMAGE:	/* color bar */
-		saa7127_dbg("Selecting Color Bar generator\n");
+		v4l_dbg(1, client, "Selecting Color Bar generator\n");
 		state->reg_3a_cb = 0x80;
 		break;
 
@@ -633,14 +609,14 @@
 		break;
 
 	case VIDIOC_LOG_STATUS:
-		saa7127_info("Standard: %s\n", (state->std & V4L2_STD_525_60) ? "60 Hz" : "50 Hz");
-		saa7127_info("Input:    %s\n", state->input_type ?  "color bars" : "normal");
-		saa7127_info("Output:   %s\n", state->video_enable ?
+		v4l_info(client, "Standard: %s\n", (state->std & V4L2_STD_525_60) ? "60 Hz" : "50 Hz");
+		v4l_info(client, "Input:    %s\n", state->input_type ?  "color bars" : "normal");
+		v4l_info(client, "Output:   %s\n", state->video_enable ?
 			output_strs[state->output_type] : "disabled");
-		saa7127_info("WSS:      %s\n", state->wss_enable ?
+		v4l_info(client, "WSS:      %s\n", state->wss_enable ?
 			wss_strs[state->wss_mode] : "disabled");
-		saa7127_info("VPS:      %s\n", state->vps_enable ? "enabled" : "disabled");
-		saa7127_info("CC:       %s\n", state->cc_enable ? "enabled" : "disabled");
+		v4l_info(client, "VPS:      %s\n", state->vps_enable ? "enabled" : "disabled");
+		v4l_info(client, "CC:       %s\n", state->cc_enable ? "enabled" : "disabled");
 		break;
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -723,7 +699,7 @@
 	client->driver = &i2c_driver_saa7127;
 	snprintf(client->name, sizeof(client->name) - 1, "saa7127");
 
-	saa7127_dbg("detecting saa7127 client on address 0x%x\n", address << 1);
+	v4l_dbg(1, client, "detecting saa7127 client on address 0x%x\n", address << 1);
 
 	/* First test register 0: Bits 5-7 are a version ID (should be 0),
 	   and bit 2 should also be 0.
@@ -732,7 +708,7 @@
 	   0x1d after a reset and not expected to ever change. */
 	if ((saa7127_read(client, 0) & 0xe4) != 0 ||
 			(saa7127_read(client, 0x29) & 0x3f) != 0x1d) {
-		saa7127_dbg("saa7127 not found\n");
+		v4l_dbg(1, client, "saa7127 not found\n");
 		kfree(client);
 		return 0;
 	}
@@ -748,7 +724,7 @@
 
 	/* Configure Encoder */
 
-	saa7127_dbg("Configuring encoder\n");
+	v4l_dbg(1, client, "Configuring encoder\n");
 	saa7127_write_inittab(client, saa7127_init_config_common);
 	saa7127_set_std(client, V4L2_STD_NTSC);
 	saa7127_set_output_type(client, SAA7127_OUTPUT_TYPE_BOTH);
@@ -769,12 +745,12 @@
 	read_result = saa7127_read(client, SAA7129_REG_FADE_KEY_COL2);
 	saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, 0xaa);
 	if (saa7127_read(client, SAA7129_REG_FADE_KEY_COL2) == 0xaa) {
-		saa7127_info("saa7129 found @ 0x%x (%s)\n", address << 1, adapter->name);
+		v4l_info(client, "saa7129 found @ 0x%x (%s)\n", address << 1, adapter->name);
 		saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, read_result);
 		saa7127_write_inittab(client, saa7129_init_config_extra);
 		state->ident = V4L2_IDENT_SAA7129;
 	} else {
-		saa7127_info("saa7127 found @ 0x%x (%s)\n", address << 1, adapter->name);
+		v4l_info(client, "saa7127 found @ 0x%x (%s)\n", address << 1, adapter->name);
 		state->ident = V4L2_IDENT_SAA7127;
 	}
 
@@ -787,11 +763,7 @@
 
 static int saa7127_probe(struct i2c_adapter *adapter)
 {
-#ifdef I2C_CLASS_TV_ANALOG
 	if (adapter->class & I2C_CLASS_TV_ANALOG)
-#else
-	if (adapter->id == I2C_HW_B_BT848)
-#endif
 		return i2c_probe(adapter, &addr_data, saa7127_attach);
 	return 0;
 }
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 4615a98..ad73c4a 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -9,7 +9,8 @@
 #include <linux/poll.h>
 #include <linux/i2c.h>
 #include <linux/types.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
 #include <linux/init.h>
 #include <linux/crc32.h>
 
@@ -509,7 +510,6 @@
 {
 	struct saa6752hs_state *h;
 
-	printk("saa6752hs: chip found @ 0x%x\n", addr<<1);
 
 	if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL)))
 		return -ENOMEM;
@@ -525,6 +525,8 @@
 	i2c_set_clientdata(&h->client, h);
 	i2c_attach_client(&h->client);
 
+	v4l_info(&h->client,"saa6752hs: chip found @ 0x%x\n", addr<<1);
+
 	return 0;
 }
 
@@ -598,7 +600,7 @@
 
 static struct i2c_driver driver = {
 	.driver = {
-		.name   = "i2c saa6752hs MPEG encoder",
+		.name   = "saa6752hs",
 	},
 	.id             = I2C_DRIVERID_SAA6752HS,
 	.attach_adapter = saa6752hs_probe,
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index ade05f7..a7a6ab9 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -20,13 +20,13 @@
  *
  */
 
-#include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/wait.h>
 #include <linux/moduleparam.h>
 #include <linux/module.h>
+#include <sound/driver.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 672fb20..77e5be9 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -25,6 +25,7 @@
 
 #include "saa7134-reg.h"
 #include "saa7134.h"
+#include <media/v4l2-common.h>
 
 /* commly used strings */
 static char name_mute[]    = "mute";
@@ -2555,6 +2556,69 @@
 			.amux   = LINE1,
 		},
 	},
+	[SAA7134_BOARD_CINERGY250PCI] = {
+		/* remote-control does not work. The signal about a
+		   key press comes in via gpio, but the key code
+		   doesn't. Neither does it have an i2c remote control
+		   interface. */
+		.name           = "Terratec Cinergy 250 PCI TV",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_TDA8290,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.gpiomask       = 0x80200000,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+		},{
+			.name = name_svideo,  /* NOT tested */
+			.vmux = 8,
+			.amux = LINE1,
+		}},
+		.radio = {
+			.name   = name_radio,
+			.amux   = LINE1,
+			.gpio   = 0x0200000,
+		},
+	},
+	[SAA7134_BOARD_FLYDVB_TRIO] = {
+		/* LifeView LR319 FlyDVB Trio */
+		/* Peter Missel <peter.missel@onlinehome.de> */
+		.name           = "LifeView FlyDVB Trio",
+		.audio_clock    = 0x00200000,
+		.tuner_type     = TUNER_PHILIPS_TDA8290,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.gpiomask	= 0x00200000,
+		.inputs         = {{
+			.name = name_tv,	/* Analog broadcast/cable TV */
+			.vmux = 1,
+			.amux = TV,
+			.gpio = 0x200000,	/* GPIO21=High for TV input */
+			.tv   = 1,
+		},{
+			.name = name_svideo,	/* S-Video signal on S-Video input */
+			.vmux = 8,
+			.amux = LINE2,
+		},{
+			.name = name_comp1,	/* Composite signal on S-Video input */
+			.vmux = 0,
+			.amux = LINE2,
+		},{
+			.name = name_comp2,	/* Composite input */
+			.vmux = 3,
+			.amux = LINE2,
+		}},
+		.radio = {
+			.name = name_radio,
+			.amux = TV,
+			.gpio = 0x000000,	/* GPIO21=Low for FM radio antenna */
+		},
+	},
 };
 
 const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -2895,6 +2959,12 @@
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = 0x1421,
+		.subdevice    = 0x0351,		/* PCI version, new revision */
+		.driver_data  = SAA7134_BOARD_ADS_INSTANT_TV,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x1421,
 		.subdevice    = 0x0370,		/* cardbus version */
 		.driver_data  = SAA7134_BOARD_ADS_INSTANT_TV,
 	},{
@@ -3002,6 +3072,18 @@
 		.subdevice    = 0x6231,
 		.driver_data  = SAA7134_BOARD_MSI_TVATANYWHERE_PLUS,
 	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x153b,
+		.subdevice    = 0x1160,
+		.driver_data  = SAA7134_BOARD_CINERGY250PCI,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,	/* SAA 7131E */
+		.subvendor    = 0x5168,
+		.subdevice    = 0x0319,
+		.driver_data  = SAA7134_BOARD_FLYDVB_TRIO,
+	},{
 		/* --- boards without eeprom + subsystem ID --- */
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -3090,6 +3172,7 @@
 	case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
 /*      case SAA7134_BOARD_SABRENT_SBTTVFM:  */ /* not finished yet */
 	case SAA7134_BOARD_VIDEOMATE_TV_PVR:
+	case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS:
 	case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
 	case SAA7134_BOARD_VIDEOMATE_DVBT_300:
 	case SAA7134_BOARD_VIDEOMATE_DVBT_200:
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 21cb3d6..accbc32 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -95,77 +95,6 @@
 #define dprintk(fmt, arg...)	if (core_debug) \
 	printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg)
 
-/* ------------------------------------------------------------------ */
-/* debug help functions                                               */
-
-static const char *v4l1_ioctls[] = {
-	"0", "GCAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
-	"CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
-	"SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
-	"GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
-	"SMICROCODE", "GVBIFMT", "SVBIFMT" };
-#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
-
-static const char *v4l2_ioctls[] = {
-	"QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
-	"G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF",
-	"G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON",
-	"STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD",
-	"ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER",
-	"G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL",
-	"QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43",
-	"44", "45",  "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT",
-	"S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
-	"S_MODULATOR"
-};
-#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
-
-static const char *osspcm_ioctls[] = {
-	"RESET", "SYNC", "SPEED", "STEREO", "GETBLKSIZE", "SETFMT",
-	"CHANNELS", "?", "POST", "SUBDIVIDE", "SETFRAGMENT", "GETFMTS",
-	"GETOSPACE", "GETISPACE", "NONBLOCK", "GETCAPS", "GET/SETTRIGGER",
-	"GETIPTR", "GETOPTR", "MAPINBUF", "MAPOUTBUF", "SETSYNCRO",
-	"SETDUPLEX", "GETODELAY"
-};
-#define OSSPCM_IOCTLS ARRAY_SIZE(v4l2_ioctls)
-
-void saa7134_print_ioctl(char *name, unsigned int cmd)
-{
-	char *dir;
-
-	switch (_IOC_DIR(cmd)) {
-	case _IOC_NONE:              dir = "--"; break;
-	case _IOC_READ:              dir = "r-"; break;
-	case _IOC_WRITE:             dir = "-w"; break;
-	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
-	default:                     dir = "??"; break;
-	}
-	switch (_IOC_TYPE(cmd)) {
-	case 'v':
-		printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n",
-		       name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
-		       v4l1_ioctls[_IOC_NR(cmd)] : "???");
-		break;
-	case 'V':
-		printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n",
-		       name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
-		       v4l2_ioctls[_IOC_NR(cmd)] : "???");
-		break;
-	case 'P':
-		printk(KERN_DEBUG "%s: ioctl 0x%08x (oss dsp, %s, SNDCTL_DSP_%s)\n",
-		       name, cmd, dir, (_IOC_NR(cmd) < OSSPCM_IOCTLS) ?
-		       osspcm_ioctls[_IOC_NR(cmd)] : "???");
-		break;
-	case 'M':
-		printk(KERN_DEBUG "%s: ioctl 0x%08x (oss mixer, %s, #%d)\n",
-		       name, cmd, dir, _IOC_NR(cmd));
-		break;
-	default:
-		printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
-		       name, cmd, dir, _IOC_NR(cmd));
-	}
-}
-
 void saa7134_track_gpio(struct saa7134_dev *dev, char *msg)
 {
 	unsigned long mode,status;
@@ -211,7 +140,7 @@
 	return NOTIFY_DONE;
 }
 
-static int pending_registered;
+static int pending_registered=0;
 static struct notifier_block pending_notifier = {
 	.notifier_call = pending_call,
 };
@@ -610,11 +539,38 @@
 		    card_has_mpeg(dev))
 			saa7134_irq_ts_done(dev,status);
 
-		if ((report & (SAA7134_IRQ_REPORT_GPIO16 |
-			       SAA7134_IRQ_REPORT_GPIO18)) &&
-		    dev->remote)
-			saa7134_input_irq(dev);
+		if (report & SAA7134_IRQ_REPORT_GPIO16) {
+			switch (dev->has_remote) {
+				case SAA7134_REMOTE_GPIO:
+					if  (dev->remote->mask_keydown & 0x10000) {
+						saa7134_input_irq(dev);
+					}
+					break;
 
+				case SAA7134_REMOTE_I2C:
+					break;			/* FIXME: invoke I2C get_key() */
+
+				default:			/* GPIO16 not used by IR remote */
+					break;
+			}
+		}
+
+		if (report & SAA7134_IRQ_REPORT_GPIO18) {
+			switch (dev->has_remote) {
+				case SAA7134_REMOTE_GPIO:
+					if ((dev->remote->mask_keydown & 0x40000) ||
+					    (dev->remote->mask_keyup & 0x40000)) {
+						saa7134_input_irq(dev);
+					}
+					break;
+
+				case SAA7134_REMOTE_I2C:
+					break;			/* FIXME: invoke I2C get_key() */
+
+				default:			/* GPIO18 not used by IR remote */
+					break;
+			}
+		}
 	}
 
 	if (10 == loop) {
@@ -624,13 +580,16 @@
 			printk(KERN_WARNING "%s/irq: looping -- "
 			       "clearing PE (parity error!) enable bit\n",dev->name);
 			saa_clearl(SAA7134_IRQ2,SAA7134_IRQ2_INTE_PE);
-		} else if (report & (SAA7134_IRQ_REPORT_GPIO16 |
-				     SAA7134_IRQ_REPORT_GPIO18)) {
-			/* disable gpio IRQs */
+		} else if (report & SAA7134_IRQ_REPORT_GPIO16) {
+			/* disable gpio16 IRQ */
 			printk(KERN_WARNING "%s/irq: looping -- "
-			       "clearing GPIO enable bits\n",dev->name);
-			saa_clearl(SAA7134_IRQ2, (SAA7134_IRQ2_INTE_GPIO16 |
-						  SAA7134_IRQ2_INTE_GPIO18));
+			       "clearing GPIO16 enable bit\n",dev->name);
+			saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO16);
+		} else if (report & SAA7134_IRQ_REPORT_GPIO18) {
+			/* disable gpio18 IRQs */
+			printk(KERN_WARNING "%s/irq: looping -- "
+			       "clearing GPIO18 enable bit\n",dev->name);
+			saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18);
 		} else {
 			/* disable all irqs */
 			printk(KERN_WARNING "%s/irq: looping -- "
@@ -711,10 +670,14 @@
 		SAA7134_IRQ2_INTE_PE      |
 		SAA7134_IRQ2_INTE_AR;
 
-	if (dev->has_remote == SAA7134_REMOTE_GPIO)
-		irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18  |
-			      SAA7134_IRQ2_INTE_GPIO18A |
-			      SAA7134_IRQ2_INTE_GPIO16  );
+	if (dev->has_remote == SAA7134_REMOTE_GPIO) {
+		if (dev->remote->mask_keydown & 0x10000)
+			irq2_mask |= SAA7134_IRQ2_INTE_GPIO16;
+		else if (dev->remote->mask_keydown & 0x40000)
+			irq2_mask |= SAA7134_IRQ2_INTE_GPIO18;
+		else if (dev->remote->mask_keyup & 0x40000)
+			irq2_mask |= SAA7134_IRQ2_INTE_GPIO18A;
+	}
 
 	saa_writel(SAA7134_IRQ1, 0);
 	saa_writel(SAA7134_IRQ2, irq2_mask);
@@ -1173,7 +1136,6 @@
 
 /* ----------------------------------------------------------- */
 
-EXPORT_SYMBOL(saa7134_print_ioctl);
 EXPORT_SYMBOL(saa7134_i2c_call_clients);
 EXPORT_SYMBOL(saa7134_devlist);
 EXPORT_SYMBOL(saa7134_boards);
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index e016480..399f995 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -31,6 +31,7 @@
 
 #include "saa7134-reg.h"
 #include "saa7134.h"
+#include <media/v4l2-common.h>
 
 #ifdef HAVE_MT352
 # include "mt352.h"
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 575f3e8..bd4c389 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -29,6 +29,7 @@
 #include "saa7134.h"
 
 #include <media/saa6752hs.h>
+#include <media/v4l2-common.h>
 
 /* ------------------------------------------------------------------ */
 
@@ -163,7 +164,7 @@
 	struct saa7134_dev *dev = file->private_data;
 
 	if (debug > 1)
-		saa7134_print_ioctl(dev->name,cmd);
+		v4l_print_ioctl(dev->name,cmd);
 	switch (cmd) {
 	case VIDIOC_QUERYCAP:
 	{
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index 1792d03..6162550 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -30,6 +30,7 @@
 
 #include "saa7134-reg.h"
 #include "saa7134.h"
+#include <media/v4l2-common.h>
 
 /* ----------------------------------------------------------- */
 
@@ -390,9 +391,7 @@
 
 static struct i2c_adapter saa7134_adap_template = {
 	.owner         = THIS_MODULE,
-#ifdef I2C_CLASS_TV_ANALOG
 	.class         = I2C_CLASS_TV_ANALOG,
-#endif
 	.name          = "saa7134",
 	.id            = I2C_HW_SAA7134,
 	.algo          = &saa7134_algo,
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index ab75ca5..82d28cb 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -56,23 +56,23 @@
 	[   12 ] = KEY_KP8,
 	[   13 ] = KEY_KP9,
 
-	[   14 ] = KEY_TUNER,        // Air/Cable
+	[   14 ] = KEY_MODE,         // Air/Cable
 	[   17 ] = KEY_VIDEO,        // Video
 	[   21 ] = KEY_AUDIO,        // Audio
-	[    0 ] = KEY_POWER,        // Pover
+	[    0 ] = KEY_POWER,        // Power
+	[   24 ] = KEY_TUNER,        // AV Source
 	[    2 ] = KEY_ZOOM,         // Fullscreen
+	[   26 ] = KEY_LANGUAGE,     // Stereo
 	[   27 ] = KEY_MUTE,         // Mute
-	[   20 ] = KEY_VOLUMEUP,
-	[   23 ] = KEY_VOLUMEDOWN,
+	[   20 ] = KEY_VOLUMEUP,     // Volume +
+	[   23 ] = KEY_VOLUMEDOWN,   // Volume -
 	[   18 ] = KEY_CHANNELUP,    // Channel +
 	[   19 ] = KEY_CHANNELDOWN,  // Channel -
-	[    6 ] = KEY_AGAIN,        // Recal
-	[   16 ] = KEY_KPENTER,      // Enter
-
-	[   26 ] = KEY_F22,          // Stereo
-	[   24 ] = KEY_EDIT,         // AV Source
+	[    6 ] = KEY_AGAIN,        // Recall
+	[   16 ] = KEY_ENTER,      // Enter
 };
 
+
 static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
 	[    0 ] = KEY_KP0,
 	[    1 ] = KEY_KP1,
@@ -543,12 +543,22 @@
 	dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
 		gpio, ir->mask_keycode, data);
 
-	if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
-	    (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
-		ir_input_keydown(ir->dev, &ir->ir, data, data);
-	} else {
-		ir_input_nokey(ir->dev, &ir->ir);
+	if (ir->polling) {
+		if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
+		    (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
+			ir_input_keydown(ir->dev, &ir->ir, data, data);
+		} else {
+			ir_input_nokey(ir->dev, &ir->ir);
+		}
 	}
+	else {	/* IRQ driven mode - handle key press and release in one go */
+		if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
+		    (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
+			ir_input_keydown(ir->dev, &ir->ir, data, data);
+			ir_input_nokey(ir->dev, &ir->ir);
+		}
+	}
+
 	return 0;
 }
 
@@ -686,6 +696,7 @@
 		polling	     = 50; // ms
 		break;
 	case SAA7134_BOARD_VIDEOMATE_TV_PVR:
+	case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS:
 	case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
 		ir_codes     = videomate_tv_pvr_codes;
 		mask_keycode = 0x00003F;
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
index 8badd2a..7448e38 100644
--- a/drivers/media/video/saa7134/saa7134-oss.c
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -373,6 +373,42 @@
 	return -EINVAL;
 }
 
+static const char *osspcm_ioctls[] = {
+	"RESET", "SYNC", "SPEED", "STEREO", "GETBLKSIZE", "SETFMT",
+	"CHANNELS", "?", "POST", "SUBDIVIDE", "SETFRAGMENT", "GETFMTS",
+	"GETOSPACE", "GETISPACE", "NONBLOCK", "GETCAPS", "GET/SETTRIGGER",
+	"GETIPTR", "GETOPTR", "MAPINBUF", "MAPOUTBUF", "SETSYNCRO",
+	"SETDUPLEX", "GETODELAY"
+};
+#define OSSPCM_IOCTLS ARRAY_SIZE(osspcm_ioctls)
+
+static void saa7134_oss_print_ioctl(char *name, unsigned int cmd)
+{
+	char *dir;
+
+	switch (_IOC_DIR(cmd)) {
+	case _IOC_NONE:              dir = "--"; break;
+	case _IOC_READ:              dir = "r-"; break;
+	case _IOC_WRITE:             dir = "-w"; break;
+	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
+	default:                     dir = "??"; break;
+	}
+	switch (_IOC_TYPE(cmd)) {
+	case 'P':
+		printk(KERN_DEBUG "%s: ioctl 0x%08x (oss dsp, %s, SNDCTL_DSP_%s)\n",
+		       name, cmd, dir, (_IOC_NR(cmd) < OSSPCM_IOCTLS) ?
+		       osspcm_ioctls[_IOC_NR(cmd)] : "???");
+		break;
+	case 'M':
+		printk(KERN_DEBUG "%s: ioctl 0x%08x (oss mixer, %s, #%d)\n",
+		       name, cmd, dir, _IOC_NR(cmd));
+		break;
+	default:
+		printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
+		       name, cmd, dir, _IOC_NR(cmd));
+	}
+}
+
 static int dsp_ioctl(struct inode *inode, struct file *file,
 		     unsigned int cmd, unsigned long arg)
 {
@@ -382,7 +418,7 @@
 	int val = 0;
 
 	if (debug > 1)
-		saa7134_print_ioctl(dev->name,cmd);
+		saa7134_oss_print_ioctl(dev->name,cmd);
 	switch (cmd) {
 	case OSS_GETVERSION:
 		return put_user(SOUND_VERSION, p);
@@ -678,7 +714,7 @@
 	int __user *p = argp;
 
 	if (debug > 1)
-		saa7134_print_ioctl(dev->name,cmd);
+		saa7134_oss_print_ioctl(dev->name,cmd);
 	switch (cmd) {
 	case OSS_GETVERSION:
 		return put_user(SOUND_VERSION, p);
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 45c852d..adfa8fe 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -29,6 +29,7 @@
 
 #include "saa7134-reg.h"
 #include "saa7134.h"
+#include <media/v4l2-common.h>
 
 /* Include V4L1 specific functions. Should be removed soon */
 #include <linux/videodev.h>
@@ -1689,7 +1690,7 @@
 	int err;
 
 	if (video_debug > 1)
-		saa7134_print_ioctl(dev->name,cmd);
+		v4l_print_ioctl(dev->name,cmd);
 
 	switch (cmd) {
 	case VIDIOC_S_CTRL:
@@ -2142,7 +2143,7 @@
 	struct saa7134_dev *dev = fh->dev;
 
 	if (video_debug > 1)
-		saa7134_print_ioctl(dev->name,cmd);
+		v4l_print_ioctl(dev->name,cmd);
 	switch (cmd) {
 	case VIDIOC_QUERYCAP:
 	{
@@ -2262,6 +2263,7 @@
 	.poll     = video_poll,
 	.mmap	  = video_mmap,
 	.ioctl	  = video_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek   = no_llseek,
 };
 
@@ -2271,6 +2273,7 @@
 	.open	  = video_open,
 	.release  = video_release,
 	.ioctl	  = radio_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek   = no_llseek,
 };
 
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index add49db..e70eae8 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -37,6 +37,9 @@
 #include <media/ir-common.h>
 #include <media/ir-kbd-i2c.h>
 #include <media/video-buf.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
 #include <media/video-buf-dvb.h>
 
 #ifndef TRUE
@@ -47,10 +50,6 @@
 #endif
 #define UNSET (-1U)
 
-#include <sound/driver.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-
 /* ----------------------------------------------------------- */
 /* enums                                                       */
 
@@ -209,6 +208,8 @@
 #define SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV 80
 #define SAA7134_BOARD_PHILIPS_TIGER  81
 #define SAA7134_BOARD_MSI_TVATANYWHERE_PLUS  82
+#define SAA7134_BOARD_CINERGY250PCI 83
+#define SAA7134_BOARD_FLYDVB_TRIO 84
 
 #define SAA7134_MAXBOARDS 8
 #define SAA7134_INPUT_MAX 8
@@ -546,7 +547,6 @@
 
 extern struct list_head  saa7134_devlist;
 
-void saa7134_print_ioctl(char *name, unsigned int cmd);
 void saa7134_track_gpio(struct saa7134_dev *dev, char *msg);
 
 #define SAA7134_PGTABLE_SIZE 4096
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c
index d4497db..6ee54a4 100644
--- a/drivers/media/video/stradis.c
+++ b/drivers/media/video/stradis.c
@@ -1974,6 +1974,7 @@
 	.open		= saa_open,
 	.release	= saa_release,
 	.ioctl		= saa_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.read		= saa_read,
 	.llseek		= no_llseek,
 	.write		= saa_write,
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index 549c992..99261f1 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -50,6 +50,7 @@
 
 #include "bttv.h"
 #include <media/audiochip.h>
+#include <media/v4l2-common.h>
 
 #ifndef VIDEO_AUDIO_BALANCE
 # define VIDEO_AUDIO_BALANCE 32
@@ -90,9 +91,6 @@
 static struct i2c_driver driver;
 static struct i2c_client client_template;
 
-#define dprintk  if (debug) printk
-#define d2printk if (debug > 1) printk
-
 /* The TDA7432 is made by STS-Thompson
  * http://www.st.com
  * http://us.st.com/stonline/books/pdf/docs/4056.pdf
@@ -229,12 +227,12 @@
 static int tda7432_write(struct i2c_client *client, int subaddr, int val)
 {
 	unsigned char buffer[2];
-	d2printk("tda7432: In tda7432_write\n");
-	dprintk("tda7432: Writing %d 0x%x\n", subaddr, val);
+	v4l_dbg(2,client,"In tda7432_write\n");
+	v4l_dbg(1,client,"Writing %d 0x%x\n", subaddr, val);
 	buffer[0] = subaddr;
 	buffer[1] = val;
 	if (2 != i2c_master_send(client,buffer,2)) {
-		printk(KERN_WARNING "tda7432: I/O error, trying (write %d 0x%x)\n",
+		v4l_err(client,"I/O error, trying (write %d 0x%x)\n",
 		       subaddr, val);
 		return -1;
 	}
@@ -247,9 +245,9 @@
 {
 	struct tda7432 *t = i2c_get_clientdata(client);
 	unsigned char buf[16];
-	d2printk("tda7432: In tda7432_set\n");
+	v4l_dbg(2,client,"In tda7432_set\n");
 
-	dprintk(KERN_INFO
+	v4l_dbg(1,client,
 		"tda7432: 7432_set(0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n",
 		t->input,t->volume,t->bass,t->treble,t->lf,t->lr,t->rf,t->rr,t->loud);
 	buf[0]  = TDA7432_IN;
@@ -263,7 +261,7 @@
 	buf[8]  = t->rr;
 	buf[9]  = t->loud;
 	if (10 != i2c_master_send(client,buf,10)) {
-		printk(KERN_WARNING "tda7432: I/O error, trying tda7432_set\n");
+		v4l_err(client,"I/O error, trying tda7432_set\n");
 		return -1;
 	}
 
@@ -273,7 +271,7 @@
 static void do_tda7432_init(struct i2c_client *client)
 {
 	struct tda7432 *t = i2c_get_clientdata(client);
-	d2printk("tda7432: In tda7432_init\n");
+	v4l_dbg(2,client,"In tda7432_init\n");
 
 	t->input  = TDA7432_STEREO_IN |  /* Main (stereo) input   */
 		    TDA7432_BASS_SYM  |  /* Symmetric bass cut    */
@@ -301,7 +299,6 @@
 {
 	struct tda7432 *t;
 	struct i2c_client *client;
-	d2printk("tda7432: In tda7432_attach\n");
 
 	t = kmalloc(sizeof *t,GFP_KERNEL);
 	if (!t)
@@ -315,21 +312,16 @@
 	i2c_set_clientdata(client, t);
 
 	do_tda7432_init(client);
-	printk(KERN_INFO "tda7432: init\n");
-
 	i2c_attach_client(client);
+
+	v4l_info(client, "chip found @ 0x%x (%s)\n", addr << 1, adap->name);
 	return 0;
 }
 
 static int tda7432_probe(struct i2c_adapter *adap)
 {
-#ifdef I2C_CLASS_TV_ANALOG
 	if (adap->class & I2C_CLASS_TV_ANALOG)
 		return i2c_probe(adap, &addr_data, tda7432_attach);
-#else
-	if (adap->id == I2C_HW_B_BT848)
-		return i2c_probe(adap, &addr_data, tda7432_attach);
-#endif
 	return 0;
 }
 
@@ -348,7 +340,9 @@
 			   unsigned int cmd, void *arg)
 {
 	struct tda7432 *t = i2c_get_clientdata(client);
-	d2printk("tda7432: In tda7432_command\n");
+	v4l_dbg(2,client,"In tda7432_command\n");
+	if (debug>1)
+		v4l_i2c_print_ioctl(client,cmd);
 
 	switch (cmd) {
 	/* --- v4l ioctls --- */
@@ -359,7 +353,6 @@
 	case VIDIOCGAUDIO:
 	{
 		struct video_audio *va = arg;
-		dprintk("tda7432: VIDIOCGAUDIO\n");
 
 		va->flags |= VIDEO_AUDIO_VOLUME |
 			VIDEO_AUDIO_BASS |
@@ -414,7 +407,6 @@
 	case VIDIOCSAUDIO:
 	{
 		struct video_audio *va = arg;
-		dprintk("tda7432: VIDEOCSAUDIO\n");
 
 		if(va->flags & VIDEO_AUDIO_VOLUME){
 			if(!maxvol){ /* max +20db */
@@ -490,11 +482,6 @@
 
 	} /* end of VIDEOCSAUDIO case */
 
-	default: /* Not VIDEOCGAUDIO or VIDEOCSAUDIO */
-
-		/* nothing */
-		d2printk("tda7432: Default\n");
-
 	} /* end of (cmd) switch */
 
 	return 0;
@@ -502,7 +489,7 @@
 
 static struct i2c_driver driver = {
 	.driver = {
-		.name    = "i2c tda7432 driver",
+		.name    = "tda7432",
 	},
 	.id              = I2C_DRIVERID_TDA7432,
 	.attach_adapter  = tda7432_probe,
@@ -519,7 +506,7 @@
 static int __init tda7432_init(void)
 {
 	if ( (loudness < 0) || (loudness > 15) ) {
-		printk(KERN_ERR "tda7432: loudness parameter must be between 0 and 15\n");
+		printk(KERN_ERR "loudness parameter must be between 0 and 15\n");
 		return -EINVAL;
 	}
 
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
index 61d94dd..2498b76 100644
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/video/tda8290.c
@@ -398,14 +398,8 @@
 	return 0;
 }
 
-
 /*---------------------------------------------------------------------*/
 
-#define V4L2_STD_MN	(V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC)
-#define V4L2_STD_B	(V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B)
-#define V4L2_STD_GH	(V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H)
-#define V4L2_STD_DK	(V4L2_STD_PAL_DK|V4L2_STD_SECAM_DK)
-
 static void set_audio(struct tuner *t)
 {
 	char* mode;
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 9c3ecf7..299393b 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -257,13 +257,8 @@
 
 static int tda9875_probe(struct i2c_adapter *adap)
 {
-#ifdef I2C_CLASS_TV_ANALOG
 	if (adap->class & I2C_CLASS_TV_ANALOG)
 		return i2c_probe(adap, &addr_data, tda9875_attach);
-#else
-	if (adap->id == I2C_HW_B_BT848)
-		return i2c_probe(adap, &addr_data, tda9875_attach);
-#endif
 	return 0;
 }
 
@@ -373,7 +368,7 @@
 
 static struct i2c_driver driver = {
 	.driver = {
-		.name   = "i2c tda9875 driver",
+		.name   = "tda9875",
 	},
 	.id             = I2C_DRIVERID_TDA9875,
 	.attach_adapter = tda9875_probe,
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index 7165a1b..9cf47dc 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -9,7 +9,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 
-#include <media/audiochip.h>
+#include <media/v4l2-common.h>
 #include <media/tuner.h>
 
 
@@ -57,7 +57,6 @@
 	v4l2_std_id        std;
 	enum tuner_mode    mode;
 	unsigned int       config;
-	unsigned int       pinnacle_id;
 	unsigned int       using_v4l2;
 	unsigned int 	   radio_mode;
 	unsigned char 	   data[4];
@@ -115,6 +114,9 @@
 #define cAudioGain0             0x00    // bit c7
 #define cAudioGain6             0x80    // bit c7
 
+#define cTopMask                0x1f    // bit c0:4
+#define cTopPalSecamDefault	0x14 	// bit c0:4
+#define cTopNtscRadioDefault 	0x10 	// bit c0:4
 
 //// third reg (e)
 #define cAudioIF_4_5             0x00    // bit e0:1
@@ -146,13 +148,15 @@
 
 static struct tvnorm tvnorms[] = {
 	{
-		.std   = V4L2_STD_PAL_BG,
-		.name  = "PAL-BG",
+		.std   = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N,
+		.name  = "PAL-BGHN",
 		.b     = ( cNegativeFmTV  |
 			   cQSS           ),
 		.c     = ( cDeemphasisON  |
-			   cDeemphasis50  ),
-		.e     = ( cAudioIF_5_5   |
+			   cDeemphasis50  |
+			   cTopPalSecamDefault),
+		.e     = ( cGating_36     |
+			   cAudioIF_5_5   |
 			   cVideoIF_38_90 ),
 	},{
 		.std   = V4L2_STD_PAL_I,
@@ -160,8 +164,10 @@
 		.b     = ( cNegativeFmTV  |
 			   cQSS           ),
 		.c     = ( cDeemphasisON  |
-			   cDeemphasis50  ),
-		.e     = ( cAudioIF_6_0   |
+			   cDeemphasis50  |
+			   cTopPalSecamDefault),
+		.e     = ( cGating_36     |
+			   cAudioIF_6_0   |
 			   cVideoIF_38_90 ),
 	},{
 		.std   = V4L2_STD_PAL_DK,
@@ -169,52 +175,80 @@
 		.b     = ( cNegativeFmTV  |
 			   cQSS           ),
 		.c     = ( cDeemphasisON  |
-			   cDeemphasis50  ),
-		.e     = ( cAudioIF_6_5   |
-			   cVideoIF_38_00 ),
+			   cDeemphasis50  |
+			   cTopPalSecamDefault),
+		.e     = ( cGating_36     |
+			   cAudioIF_6_5   |
+			   cVideoIF_38_90 ),
 	},{
-		.std   = V4L2_STD_PAL_M | V4L2_STD_PAL_N,
-		.name  = "PAL-M/N",
+		.std   = V4L2_STD_PAL_M | V4L2_STD_PAL_Nc,
+		.name  = "PAL-M/Nc",
 		.b     = ( cNegativeFmTV  |
 			   cQSS           ),
 		.c     = ( cDeemphasisON  |
-			   cDeemphasis75  ),
-		.e     = ( cAudioIF_4_5   |
+			   cDeemphasis75  |
+			   cTopNtscRadioDefault),
+		.e     = ( cGating_36     |
+			   cAudioIF_4_5   |
 			   cVideoIF_45_75 ),
 	},{
+		.std   = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H,
+		.name  = "SECAM-BGH",
+		.b     = ( cPositiveAmTV  |
+			   cQSS           ),
+		.c     = ( cTopPalSecamDefault),
+		.e     = ( cGating_36	  |
+			   cAudioIF_5_5   |
+			   cVideoIF_38_90 ),
+	},{
 		.std   = V4L2_STD_SECAM_L,
 		.name  = "SECAM-L",
 		.b     = ( cPositiveAmTV  |
 			   cQSS           ),
+		.c     = ( cTopPalSecamDefault),
 		.e     = ( cGating_36	  |
 			   cAudioIF_6_5   |
 			   cVideoIF_38_90 ),
 	},{
+		.std   = V4L2_STD_SECAM_LC,
+		.name  = "SECAM-L'",
+		.b     = ( cOutputPort2Inactive |
+			   cPositiveAmTV  |
+			   cQSS           ),
+		.c     = ( cTopPalSecamDefault),
+		.e     = ( cGating_36	  |
+			   cAudioIF_6_5   |
+			   cVideoIF_33_90 ),
+	},{
 		.std   = V4L2_STD_SECAM_DK,
 		.name  = "SECAM-DK",
 		.b     = ( cNegativeFmTV  |
 			   cQSS           ),
 		.c     = ( cDeemphasisON  |
-			   cDeemphasis50  ),
-		.e     = ( cAudioIF_6_5   |
-			   cVideoIF_38_00 ),
+			   cDeemphasis50  |
+			   cTopPalSecamDefault),
+		.e     = ( cGating_36     |
+			   cAudioIF_6_5   |
+			   cVideoIF_38_90 ),
 	},{
 		.std   = V4L2_STD_NTSC_M,
 		.name  = "NTSC-M",
 		.b     = ( cNegativeFmTV  |
 			   cQSS           ),
 		.c     = ( cDeemphasisON  |
-			   cDeemphasis75  ),
+			   cDeemphasis75  |
+			   cTopNtscRadioDefault),
 		.e     = ( cGating_36     |
 			   cAudioIF_4_5   |
 			   cVideoIF_45_75 ),
 	},{
 		.std   = V4L2_STD_NTSC_M_JP,
-		.name  = "NTSC-JP",
+		.name  = "NTSC-M-JP",
 		.b     = ( cNegativeFmTV  |
 			   cQSS           ),
 		.c     = ( cDeemphasisON  |
-			   cDeemphasis50  ),
+			   cDeemphasis50  |
+			   cTopNtscRadioDefault),
 		.e     = ( cGating_36     |
 			   cAudioIF_4_5   |
 			   cVideoIF_58_75 ),
@@ -226,8 +260,10 @@
 	.b    = ( cFmRadio       |
 		  cQSS           ),
 	.c    = ( cDeemphasisOFF |
-		  cAudioGain6 ),
-	.e    = ( cAudioIF_5_5   |
+		  cAudioGain6    |
+		  cTopNtscRadioDefault),
+	.e    = ( cTunerGainLow  |
+		  cAudioIF_5_5   |
 		  cRadioIF_38_90 ),
 };
 
@@ -236,8 +272,10 @@
 	.b    = ( cFmRadio       |
 		  cQSS           ),
 	.c    = ( cDeemphasisON  |
-		  cDeemphasis50),
-	.e    = ( cAudioIF_5_5   |
+		  cDeemphasis75  |
+		  cTopNtscRadioDefault),
+	.e    = ( cTunerGainLow  |
+		  cAudioIF_5_5   |
 		  cRadioIF_38_90 ),
 };
 
@@ -400,7 +438,8 @@
 static unsigned int port1  = UNSET;
 static unsigned int port2  = UNSET;
 static unsigned int qss    = UNSET;
-static unsigned int adjust = 0x10;
+static unsigned int adjust = UNSET;
+
 module_param(port1, int, 0644);
 module_param(port2, int, 0644);
 module_param(qss, int, 0644);
@@ -428,8 +467,10 @@
 			buf[1] &= ~cQSS;
 	}
 
-	if (adjust >= 0x00 && adjust < 0x20)
+	if (adjust >= 0x00 && adjust < 0x20) {
+		buf[2] &= ~cTopMask;
 		buf[2] |= adjust;
+	}
 	return 0;
 }
 
@@ -465,6 +506,10 @@
 			break;
 		}
 	}
+	if (t->config & TDA9887_TOP_SET) {
+		buf[2] &= ~cTopMask;
+		buf[2] |= (t->config >> 8) & cTopMask;
+	}
 	if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC))
 		buf[1] &= ~cQSS;
 	return 0;
@@ -472,38 +517,13 @@
 
 /* ---------------------------------------------------------------------- */
 
-static int tda9887_set_pinnacle(struct tda9887 *t, char *buf)
-{
-	unsigned int bCarrierMode = UNSET;
+static char pal[] = "--";
+static char secam[] = "--";
+static char ntsc[] = "-";
 
-	if (t->std & V4L2_STD_625_50) {
-		if ((1 == t->pinnacle_id) || (7 == t->pinnacle_id)) {
-			bCarrierMode = cIntercarrier;
-		} else {
-			bCarrierMode = cQSS;
-		}
-	}
-	if (t->std & V4L2_STD_525_60) {
-		if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) {
-			bCarrierMode = cIntercarrier;
-		} else {
-			bCarrierMode = cQSS;
-		}
-	}
-
-	if (bCarrierMode != UNSET) {
-		buf[1] &= ~0x04;
-		buf[1] |= bCarrierMode;
-	}
-	return 0;
-}
-
-/* ---------------------------------------------------------------------- */
-
-static char pal[] = "-";
 module_param_string(pal, pal, sizeof(pal), 0644);
-static char secam[] = "-";
 module_param_string(secam, secam, sizeof(secam), 0644);
+module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
 
 static int tda9887_fixup_std(struct tda9887 *t)
 {
@@ -514,8 +534,17 @@
 		case 'B':
 		case 'g':
 		case 'G':
-			tda9887_dbg("insmod fixup: PAL => PAL-BG\n");
-			t->std = V4L2_STD_PAL_BG;
+		case 'h':
+		case 'H':
+		case 'n':
+		case 'N':
+			if (pal[1] == 'c' || pal[1] == 'C') {
+				tda9887_dbg("insmod fixup: PAL => PAL-Nc\n");
+				t->std = V4L2_STD_PAL_Nc;
+			} else {
+				tda9887_dbg("insmod fixup: PAL => PAL-BGHN\n");
+				t->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N;
+			}
 			break;
 		case 'i':
 		case 'I':
@@ -529,6 +558,11 @@
 			tda9887_dbg("insmod fixup: PAL => PAL-DK\n");
 			t->std = V4L2_STD_PAL_DK;
 			break;
+		case 'm':
+		case 'M':
+			tda9887_dbg("insmod fixup: PAL => PAL-M\n");
+			t->std = V4L2_STD_PAL_M;
+			break;
 		case '-':
 			/* default parameter, do nothing */
 			break;
@@ -539,6 +573,15 @@
 	}
 	if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
 		switch (secam[0]) {
+		case 'b':
+		case 'B':
+		case 'g':
+		case 'G':
+		case 'h':
+		case 'H':
+			tda9887_dbg("insmod fixup: SECAM => SECAM-BGH\n");
+			t->std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;
+			break;
 		case 'd':
 		case 'D':
 		case 'k':
@@ -548,8 +591,13 @@
 			break;
 		case 'l':
 		case 'L':
-			tda9887_dbg("insmod fixup: SECAM => SECAM-L\n");
-			t->std = V4L2_STD_SECAM_L;
+			if (secam[1] == 'c' || secam[1] == 'C') {
+				tda9887_dbg("insmod fixup: SECAM => SECAM-L'\n");
+				t->std = V4L2_STD_SECAM_LC;
+			} else {
+				tda9887_dbg("insmod fixup: SECAM => SECAM-L\n");
+				t->std = V4L2_STD_SECAM_L;
+			}
 			break;
 		case '-':
 			/* default parameter, do nothing */
@@ -559,6 +607,26 @@
 			break;
 		}
 	}
+	if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
+		switch (ntsc[0]) {
+		case 'm':
+		case 'M':
+			tda9887_dbg("insmod fixup: NTSC => NTSC-M\n");
+			t->std = V4L2_STD_NTSC_M;
+			break;
+		case 'j':
+		case 'J':
+			tda9887_dbg("insmod fixup: NTSC => NTSC_M_JP\n");
+			t->std = V4L2_STD_NTSC_M_JP;
+			break;
+		case '-':
+			/* default parameter, do nothing */
+			break;
+		default:
+			tda9887_info("ntsc= argument not recognised\n");
+			break;
+		}
+	}
 	return 0;
 }
 
@@ -581,12 +649,22 @@
 	memset(t->data,0,sizeof(t->data));
 	tda9887_set_tvnorm(t,t->data);
 
+	/* A note on the port settings:
+	   These settings tend to depend on the specifics of the board.
+	   By default they are set to inactive (bit value 1) by this driver,
+	   overwriting any changes made by the tvnorm. This means that it
+	   is the responsibility of the module using the tda9887 to set
+	   these values in case of changes in the tvnorm.
+	   In many cases port 2 should be made active (0) when selecting
+	   SECAM-L, and port 2 should remain inactive (1) for SECAM-L'.
+
+	   For the other standards the tda9887 application note says that
+	   the ports should be set to active (0), but, again, that may
+	   differ depending on the precise hardware configuration.
+	 */
 	t->data[1] |= cOutputPort1Inactive;
 	t->data[1] |= cOutputPort2Inactive;
 
-	if (UNSET != t->pinnacle_id) {
-		tda9887_set_pinnacle(t,t->data);
-	}
 	tda9887_set_config(t,t->data);
 	tda9887_set_insmod(t,t->data);
 
@@ -594,7 +672,6 @@
 		t->data[1] |= cForcedMuteAudioON;
 	}
 
-
 	tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
 		t->data[1],t->data[2],t->data[3]);
 	if (debug > 1)
@@ -625,7 +702,6 @@
 
 	t->client      = client_template;
 	t->std         = 0;
-	t->pinnacle_id = UNSET;
 	t->radio_mode = V4L2_TUNER_MODE_STEREO;
 
 	tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name);
@@ -638,18 +714,8 @@
 
 static int tda9887_probe(struct i2c_adapter *adap)
 {
-#ifdef I2C_CLASS_TV_ANALOG
 	if (adap->class & I2C_CLASS_TV_ANALOG)
 		return i2c_probe(adap, &addr_data, tda9887_attach);
-#else
-	switch (adap->id) {
-	case I2C_HW_B_BT848:
-	case I2C_HW_B_RIVA:
-	case I2C_HW_SAA7134:
-		return i2c_probe(adap, &addr_data, tda9887_attach);
-		break;
-	}
-#endif
 	return 0;
 }
 
@@ -689,14 +755,6 @@
 		tda9887_configure(t);
 		break;
 	}
-	case AUDC_CONFIG_PINNACLE:
-	{
-		int *i = arg;
-
-		t->pinnacle_id = *i;
-		tda9887_configure(t);
-		break;
-	}
 	case TDA9887_SET_CONFIG:
 	{
 		int *i = arg;
@@ -787,7 +845,7 @@
 	}
 	case VIDIOC_LOG_STATUS:
 	{
-		tda9887_info("Data bytes: b=%02x c=%02x e=%02x\n", t->data[1], t->data[2], t->data[3]);
+		tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", t->data[1], t->data[2], t->data[3]);
 		break;
 	}
 	default:
@@ -824,7 +882,7 @@
 	.detach_client  = tda9887_detach,
 	.command        = tda9887_command,
 	.driver = {
-		.name    = "i2c tda9887 driver",
+		.name    = "tda9887",
 		.suspend = tda9887_suspend,
 		.resume  = tda9887_resume,
 	},
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c
index a9375ef..261b7a3 100644
--- a/drivers/media/video/tea5767.c
+++ b/drivers/media/video/tea5767.c
@@ -17,6 +17,9 @@
 
 #define PREFIX "TEA5767 "
 
+/* from tuner-core.c */
+extern int debug;
+
 /*****************************************************************************/
 
 /******************************
@@ -246,7 +249,7 @@
 	if (5 != (rc = i2c_master_send(c, buffer, 5)))
 		tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
 
-	if (tuner_debug) {
+	if (debug) {
 		if (5 != (rc = i2c_master_recv(c, buffer, 5)))
 			tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
 		else
@@ -264,7 +267,7 @@
 	if (5 != (rc = i2c_master_recv(c, buffer, 5)))
 		tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
 
-	return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << (13 - 4));
+	return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << 8);
 }
 
 static int tea5767_stereo(struct i2c_client *c)
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index c13c7b9..57bc585 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -20,10 +20,9 @@
 #include <linux/init.h>
 
 #include <media/tuner.h>
+#include <media/v4l2-common.h>
 #include <media/audiochip.h>
 
-#include "msp3400.h"
-
 #define UNSET (-1U)
 
 /* standard i2c insmod options */
@@ -38,21 +37,30 @@
 
 /* insmod options used at init time => read/only */
 static unsigned int addr = 0;
-module_param(addr, int, 0444);
-
 static unsigned int no_autodetect = 0;
-module_param(no_autodetect, int, 0444);
-
 static unsigned int show_i2c = 0;
-module_param(show_i2c, int, 0444);
 
 /* insmod options used at runtime => read/write */
-unsigned int tuner_debug = 0;
-module_param(tuner_debug, int, 0644);
+static unsigned int tuner_debug = 0;
+int debug = 0;
 
 static unsigned int tv_range[2] = { 44, 958 };
 static unsigned int radio_range[2] = { 65, 108 };
 
+static char pal[] = "--";
+static char secam[] = "--";
+static char ntsc[] = "-";
+
+module_param(addr, int, 0444);
+module_param(no_autodetect, int, 0444);
+module_param(show_i2c, int, 0444);
+/* Note: tuner_debug is deprecated and will be removed in 2.6.17 */
+module_param(tuner_debug, int, 0444);
+module_param(debug, int, 0644);
+
+module_param_string(pal, pal, sizeof(pal), 0644);
+module_param_string(secam, secam, sizeof(secam), 0644);
+module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
 module_param_array(tv_range, int, NULL, 0644);
 module_param_array(radio_range, int, NULL, 0644);
 
@@ -249,11 +257,6 @@
 	return 0;
 }
 
-static char pal[] = "-";
-module_param_string(pal, pal, sizeof(pal), 0644);
-static char secam[] = "--";
-module_param_string(secam, secam, sizeof(secam), 0644);
-
 /* get more precise norm info from insmod option */
 static int tuner_fixup_std(struct tuner *t)
 {
@@ -285,8 +288,13 @@
 			break;
 		case 'N':
 		case 'n':
-			tuner_dbg ("insmod fixup: PAL => PAL-N\n");
-			t->std = V4L2_STD_PAL_N;
+			if (pal[1] == 'c' || pal[1] == 'C') {
+				tuner_dbg("insmod fixup: PAL => PAL-Nc\n");
+				t->std = V4L2_STD_PAL_Nc;
+			} else {
+				tuner_dbg ("insmod fixup: PAL => PAL-N\n");
+				t->std = V4L2_STD_PAL_N;
+			}
 			break;
 		case '-':
 			/* default parameter, do nothing */
@@ -298,6 +306,15 @@
 	}
 	if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
 		switch (secam[0]) {
+		case 'b':
+		case 'B':
+		case 'g':
+		case 'G':
+		case 'h':
+		case 'H':
+			tuner_dbg("insmod fixup: SECAM => SECAM-BGH\n");
+			t->std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;
+			break;
 		case 'd':
 		case 'D':
 		case 'k':
@@ -324,9 +341,60 @@
 		}
 	}
 
+	if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
+		switch (ntsc[0]) {
+		case 'm':
+		case 'M':
+			tuner_dbg("insmod fixup: NTSC => NTSC-M\n");
+			t->std = V4L2_STD_NTSC_M;
+			break;
+		case 'j':
+		case 'J':
+			tuner_dbg("insmod fixup: NTSC => NTSC_M_JP\n");
+			t->std = V4L2_STD_NTSC_M_JP;
+			break;
+		case '-':
+			/* default parameter, do nothing */
+			break;
+		default:
+			tuner_info("ntsc= argument not recognised\n");
+			break;
+		}
+	}
 	return 0;
 }
 
+static void tuner_status(struct i2c_client *client)
+{
+	struct tuner *t = i2c_get_clientdata(client);
+	unsigned long freq, freq_fraction;
+	const char *p;
+
+	switch (t->mode) {
+		case V4L2_TUNER_RADIO: 	    p = "radio"; break;
+		case V4L2_TUNER_ANALOG_TV:  p = "analog TV"; break;
+		case V4L2_TUNER_DIGITAL_TV: p = "digital TV"; break;
+		default: p = "undefined"; break;
+	}
+	if (t->mode == V4L2_TUNER_RADIO) {
+		freq = t->freq / 16000;
+		freq_fraction = (t->freq % 16000) * 100 / 16000;
+	} else {
+		freq = t->freq / 16;
+		freq_fraction = (t->freq % 16) * 100 / 16;
+	}
+	tuner_info("Tuner mode:      %s\n", p);
+	tuner_info("Frequency:       %lu.%02lu MHz\n", freq, freq_fraction);
+	tuner_info("Standard:        0x%08llx\n", t->std);
+	if (t->mode == V4L2_TUNER_RADIO) {
+		if (t->has_signal) {
+			tuner_info("Signal strength: %d\n", t->has_signal(client));
+		}
+		if (t->is_stereo) {
+			tuner_info("Stereo:          %s\n", t->is_stereo(client) ? "yes" : "no");
+		}
+	}
+}
 /* ---------------------------------------------------------------------- */
 
 /* static var Used only in tuner_attach and tuner_probe */
@@ -352,6 +420,11 @@
 	t->radio_if2 = 10700 * 1000;	/* 10.7MHz - FM radio */
 	t->audmode = V4L2_TUNER_MODE_STEREO;
 	t->mode_mask = T_UNINITIALIZED;
+	if (tuner_debug) {
+		debug = tuner_debug;
+		printk(KERN_ERR "tuner: tuner_debug is deprecated and will be removed in 2.6.17.\n");
+		printk(KERN_ERR "tuner: use the debug option instead.\n");
+	}
 
 	if (show_i2c) {
 		unsigned char buffer[16];
@@ -478,7 +551,9 @@
 static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
 {
 	struct tuner *t = i2c_get_clientdata(client);
-	unsigned int *iarg = (int *)arg;
+
+	if (debug>1)
+		v4l_i2c_print_ioctl(&(t->i2c),cmd);
 
 	switch (cmd) {
 	/* --- configuration --- */
@@ -501,18 +576,6 @@
 				t->standby (client);
 			break;
 		}
-	case AUDC_CONFIG_PINNACLE:
-		switch (*iarg) {
-		case 2:
-			tuner_dbg("pinnacle pal\n");
-			t->radio_if2 = 33300 * 1000;
-			break;
-		case 3:
-			tuner_dbg("pinnacle ntsc\n");
-			t->radio_if2 = 41300 * 1000;
-			break;
-		}
-		break;
 	case VIDIOCSAUDIO:
 		if (check_mode(t, "VIDIOCSAUDIO") == EINVAL)
 			return 0;
@@ -523,9 +586,6 @@
 		tuner_dbg("VIDIOCSAUDIO not implemented.\n");
 
 		break;
-	case MSP_SET_MATRIX:
-	case TDA9887_SET_CONFIG:
-		break;
 	/* --- v4l ioctls --- */
 	/* take care: bttv does userspace copying, we'll get a
 	   kernel pointer here... */
@@ -708,10 +768,8 @@
 			}
 			break;
 		}
-	default:
-		tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp='%c',nr=%d,sz=%d)\n",
-					 cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd),
-					_IOC_NR(cmd), _IOC_SIZE(cmd));
+	case VIDIOC_LOG_STATUS:
+		tuner_status(client);
 		break;
 	}
 
@@ -747,10 +805,10 @@
 	.detach_client = tuner_detach,
 	.command = tuner_command,
 	.driver = {
-		   .name = "tuner",
-		   .suspend = tuner_suspend,
-		   .resume = tuner_resume,
-		   },
+		.name    = "tuner",
+		.suspend = tuner_suspend,
+		.resume  = tuner_resume,
+	},
 };
 static struct i2c_client client_template = {
 	.name = "(tuner unset)",
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index e0c9fdb..e5fb743 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -8,6 +8,10 @@
 #include <linux/videodev.h>
 #include <media/tuner.h>
 
+static int offset = 0;
+module_param(offset, int, 0666);
+MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner");
+
 /* ---------------------------------------------------------------------- */
 
 /* tv standard selection for Temic 4046 FM5
@@ -75,24 +79,20 @@
 #define TUNER_PLL_LOCKED   0x40
 #define TUNER_STEREO_MK3   0x04
 
+#define TUNER_MAX_RANGES   3
+
 /* ---------------------------------------------------------------------- */
 
 struct tunertype
 {
 	char *name;
-	unsigned char Vendor;
-	unsigned char Type;
 
-	unsigned short thresh1;  /*  band switch VHF_LO <=> VHF_HI  */
-	unsigned short thresh2;  /*  band switch VHF_HI <=> UHF     */
-	unsigned char VHF_L;
-	unsigned char VHF_H;
-	unsigned char UHF;
+	int count;
+	struct {
+		unsigned short thresh;
+		unsigned char cb;
+	} ranges[TUNER_MAX_RANGES];
 	unsigned char config;
-	unsigned short IFPCoff; /* 622.4=16*38.90 MHz PAL,
-				   732  =16*45.75 NTSCi,
-				   940  =16*58.75 NTSC-Japan
-				   704  =16*44    ATSC */
 };
 
 /*
@@ -102,158 +102,696 @@
  */
 static struct tunertype tuners[] = {
 	/* 0-9 */
-	{ "Temic PAL (4002 FH5)", TEMIC, PAL,
-	  16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623},
-	{ "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I,
-	  16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
-	{ "Philips NTSC (FI1236,FM1236 and compatibles)", Philips, NTSC,
-	  16*157.25,16*451.25,0xA0,0x90,0x30,0x8e,732},
-	{ "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)", Philips, SECAM,
-	  16*168.25,16*447.25,0xA7,0x97,0x37,0x8e,623},
-	{ "NoTuner", NoTuner, NOTUNER,
-	  0,0,0x00,0x00,0x00,0x00,0x00},
-	{ "Philips PAL_BG (FI1216 and compatibles)", Philips, PAL,
-	  16*168.25,16*447.25,0xA0,0x90,0x30,0x8e,623},
-	{ "Temic NTSC (4032 FY5)", TEMIC, NTSC,
-	  16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732},
-	{ "Temic PAL_I (4062 FY5)", TEMIC, PAL_I,
-	  16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623},
-	{ "Temic NTSC (4036 FY5)", TEMIC, NTSC,
-	  16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732},
-	{ "Alps HSBH1", TEMIC, NTSC,
-	  16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
+	[TUNER_TEMIC_PAL] = { /* TEMIC PAL */
+		.name   = "Temic PAL (4002 FH5)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 140.25 /*MHz*/, 0x02, },
+			{ 16 * 463.25 /*MHz*/, 0x04, },
+			{ 16 * 999.99        , 0x01, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_PHILIPS_PAL_I] = { /* Philips PAL_I */
+		.name   = "Philips PAL_I (FI1246 and compatibles)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 140.25 /*MHz*/, 0xa0, },
+			{ 16 * 463.25 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_PHILIPS_NTSC] = { /* Philips NTSC */
+		.name   = "Philips NTSC (FI1236,FM1236 and compatibles)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 157.25 /*MHz*/, 0xa0, },
+			{ 16 * 451.25 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_PHILIPS_SECAM] = { /* Philips SECAM */
+		.name   = "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 168.25 /*MHz*/, 0xa7, },
+			{ 16 * 447.25 /*MHz*/, 0x97, },
+			{ 16 * 999.99        , 0x37, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_ABSENT] = { /* Tuner Absent */
+		.name   = "NoTuner",
+		.count  = 1,
+		.ranges = {
+			{ 0, 0x00, },
+		},
+		.config = 0x00,
+	},
+	[TUNER_PHILIPS_PAL] = { /* Philips PAL */
+		.name   = "Philips PAL_BG (FI1216 and compatibles)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 168.25 /*MHz*/, 0xa0, },
+			{ 16 * 447.25 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_TEMIC_NTSC] = { /* TEMIC NTSC */
+		.name   = "Temic NTSC (4032 FY5)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 157.25 /*MHz*/, 0x02, },
+			{ 16 * 463.25 /*MHz*/, 0x04, },
+			{ 16 * 999.99        , 0x01, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_TEMIC_PAL_I] = { /* TEMIC PAL_I */
+		.name   = "Temic PAL_I (4062 FY5)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 170.00 /*MHz*/, 0x02, },
+			{ 16 * 450.00 /*MHz*/, 0x04, },
+			{ 16 * 999.99        , 0x01, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_TEMIC_4036FY5_NTSC] = { /* TEMIC NTSC */
+		.name   = "Temic NTSC (4036 FY5)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 157.25 /*MHz*/, 0xa0, },
+			{ 16 * 463.25 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_ALPS_TSBH1_NTSC] = { /* TEMIC NTSC */
+		.name   = "Alps HSBH1",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 137.25 /*MHz*/, 0x01, },
+			{ 16 * 385.25 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x08, },
+		},
+		.config = 0x8e,
+	},
 
 	/* 10-19 */
-	{ "Alps TSBE1", TEMIC, PAL,
-	  16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
-	{ "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */
-	  16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632},
-	{ "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
-	  16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622},
-	{ "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
-	  16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608},
-	{ "Temic PAL_BG (4006FH5)", TEMIC, PAL,
-	  16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
-	{ "Alps TSCH6", Alps, NTSC,
-	  16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732},
-	{ "Temic PAL_DK (4016 FY5)", TEMIC, PAL,
-	  16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623},
-	{ "Philips NTSC_M (MK2)", Philips, NTSC,
-	  16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
-	{ "Temic PAL_I (4066 FY5)", TEMIC, PAL_I,
-	  16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
-	{ "Temic PAL* auto (4006 FN5)", TEMIC, PAL,
-	  16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
+	[TUNER_ALPS_TSBE1_PAL] = { /* TEMIC PAL */
+		.name   = "Alps TSBE1",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 137.25 /*MHz*/, 0x01, },
+			{ 16 * 385.25 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x08, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_ALPS_TSBB5_PAL_I] = { /* Alps PAL_I */
+		.name   = "Alps TSBB5",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 133.25 /*MHz*/, 0x01, },
+			{ 16 * 351.25 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x08, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_ALPS_TSBE5_PAL] = { /* Alps PAL */
+		.name   = "Alps TSBE5",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 133.25 /*MHz*/, 0x01, },
+			{ 16 * 351.25 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x08, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_ALPS_TSBC5_PAL] = { /* Alps PAL */
+		.name   = "Alps TSBC5",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 133.25 /*MHz*/, 0x01, },
+			{ 16 * 351.25 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x08, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_TEMIC_4006FH5_PAL] = { /* TEMIC PAL */
+		.name   = "Temic PAL_BG (4006FH5)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 170.00 /*MHz*/, 0xa0, },
+			{ 16 * 450.00 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_ALPS_TSHC6_NTSC] = { /* Alps NTSC */
+		.name   = "Alps TSCH6",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 137.25 /*MHz*/, 0x14, },
+			{ 16 * 385.25 /*MHz*/, 0x12, },
+			{ 16 * 999.99        , 0x11, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_TEMIC_PAL_DK] = { /* TEMIC PAL */
+		.name   = "Temic PAL_DK (4016 FY5)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 168.25 /*MHz*/, 0xa0, },
+			{ 16 * 456.25 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_PHILIPS_NTSC_M] = { /* Philips NTSC */
+		.name   = "Philips NTSC_M (MK2)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 160.00 /*MHz*/, 0xa0, },
+			{ 16 * 454.00 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_TEMIC_4066FY5_PAL_I] = { /* TEMIC PAL_I */
+		.name   = "Temic PAL_I (4066 FY5)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 169.00 /*MHz*/, 0xa0, },
+			{ 16 * 454.00 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_TEMIC_4006FN5_MULTI_PAL] = { /* TEMIC PAL */
+		.name   = "Temic PAL* auto (4006 FN5)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 169.00 /*MHz*/, 0xa0, },
+			{ 16 * 454.00 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
 
 	/* 20-29 */
-	{ "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL,
-	  16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
-	{ "Temic NTSC (4039 FR5)", TEMIC, NTSC,
-	  16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
-	{ "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL,
-	  16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
-	{ "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL,
-	  16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
-	{ "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL,
-	  16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
-	{ "LG PAL_I+FM (TAPC-I001D)", LGINNOTEK, PAL_I,
-	  16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
-	{ "LG PAL_I (TAPC-I701D)", LGINNOTEK, PAL_I,
-	  16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
-	{ "LG NTSC+FM (TPI8NSR01F)", LGINNOTEK, NTSC,
-	  16*210.00,16*497.00,0xa0,0x90,0x30,0x8e,732},
-	{ "LG PAL_BG+FM (TPI8PSB01D)", LGINNOTEK, PAL,
-	  16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
-	{ "LG PAL_BG (TPI8PSB11D)", LGINNOTEK, PAL,
-	  16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
+	[TUNER_TEMIC_4009FR5_PAL] = { /* TEMIC PAL */
+		.name   = "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 141.00 /*MHz*/, 0xa0, },
+			{ 16 * 464.00 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_TEMIC_4039FR5_NTSC] = { /* TEMIC NTSC */
+		.name   = "Temic NTSC (4039 FR5)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 158.00 /*MHz*/, 0xa0, },
+			{ 16 * 453.00 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_TEMIC_4046FM5] = { /* TEMIC PAL */
+		.name   = "Temic PAL/SECAM multi (4046 FM5)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 169.00 /*MHz*/, 0xa0, },
+			{ 16 * 454.00 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_PHILIPS_PAL_DK] = { /* Philips PAL */
+		.name   = "Philips PAL_DK (FI1256 and compatibles)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 170.00 /*MHz*/, 0xa0, },
+			{ 16 * 450.00 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_PHILIPS_FQ1216ME] = { /* Philips PAL */
+		.name   = "Philips PAL/SECAM multi (FQ1216ME)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 170.00 /*MHz*/, 0xa0, },
+			{ 16 * 450.00 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_LG_PAL_I_FM] = { /* LGINNOTEK PAL_I */
+		.name   = "LG PAL_I+FM (TAPC-I001D)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 170.00 /*MHz*/, 0xa0, },
+			{ 16 * 450.00 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_LG_PAL_I] = { /* LGINNOTEK PAL_I */
+		.name   = "LG PAL_I (TAPC-I701D)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 170.00 /*MHz*/, 0xa0, },
+			{ 16 * 450.00 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_LG_NTSC_FM] = { /* LGINNOTEK NTSC */
+		.name   = "LG NTSC+FM (TPI8NSR01F)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 210.00 /*MHz*/, 0xa0, },
+			{ 16 * 497.00 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_LG_PAL_FM] = { /* LGINNOTEK PAL */
+		.name   = "LG PAL_BG+FM (TPI8PSB01D)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 170.00 /*MHz*/, 0xa0, },
+			{ 16 * 450.00 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_LG_PAL] = { /* LGINNOTEK PAL */
+		.name   = "LG PAL_BG (TPI8PSB11D)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 170.00 /*MHz*/, 0xa0, },
+			{ 16 * 450.00 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
 
 	/* 30-39 */
-	{ "Temic PAL* auto + FM (4009 FN5)", TEMIC, PAL,
-	  16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
-	{ "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */
-	  16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 },
-	{ "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */
-	  16*169,16*464,0xA0,0x90,0x30,0x8e,623},
-	{ "MT20xx universal", Microtune, PAL|NTSC,
+	[TUNER_TEMIC_4009FN5_MULTI_PAL_FM] = { /* TEMIC PAL */
+		.name   = "Temic PAL* auto + FM (4009 FN5)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 141.00 /*MHz*/, 0xa0, },
+			{ 16 * 464.00 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_SHARP_2U5JF5540_NTSC] = { /* SHARP NTSC */
+		.name   = "SHARP NTSC_JP (2U5JF5540)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 137.25 /*MHz*/, 0x01, },
+			{ 16 * 317.25 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x08, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_Samsung_PAL_TCPM9091PD27] = { /* Samsung PAL */
+		.name   = "Samsung PAL TCPM9091PD27",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 169 /*MHz*/, 0xa0, },
+			{ 16 * 464 /*MHz*/, 0x90, },
+			{ 16 * 999.99     , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_MT2032] = { /* Microtune PAL|NTSC */
+		.name   = "MT20xx universal",
 	  /* see mt20xx.c for details */ },
-	{ "Temic PAL_BG (4106 FH5)", TEMIC, PAL,
-	  16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
-	{ "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL,
-	  16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623},
-	{ "Temic NTSC (4136 FY5)", TEMIC, NTSC,
-	  16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
-	{ "LG PAL (newer TAPC series)", LGINNOTEK, PAL,
-	  16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623},
-	{ "Philips PAL/SECAM multi (FM1216ME MK3)", Philips, PAL,
-	  16*158.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
-	{ "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC,
-	  16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732},
+	[TUNER_TEMIC_4106FH5] = { /* TEMIC PAL */
+		.name   = "Temic PAL_BG (4106 FH5)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 141.00 /*MHz*/, 0xa0, },
+			{ 16 * 464.00 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_TEMIC_4012FY5] = { /* TEMIC PAL */
+		.name   = "Temic PAL_DK/SECAM_L (4012 FY5)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 140.25 /*MHz*/, 0x02, },
+			{ 16 * 463.25 /*MHz*/, 0x04, },
+			{ 16 * 999.99        , 0x01, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_TEMIC_4136FY5] = { /* TEMIC NTSC */
+		.name   = "Temic NTSC (4136 FY5)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 158.00 /*MHz*/, 0xa0, },
+			{ 16 * 453.00 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_LG_PAL_NEW_TAPC] = { /* LGINNOTEK PAL */
+		.name   = "LG PAL (newer TAPC series)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 170.00 /*MHz*/, 0x01, },
+			{ 16 * 450.00 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x08, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_PHILIPS_FM1216ME_MK3] = { /* Philips PAL */
+		.name   = "Philips PAL/SECAM multi (FM1216ME MK3)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 158.00 /*MHz*/, 0x01, },
+			{ 16 * 442.00 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x04, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_LG_NTSC_NEW_TAPC] = { /* LGINNOTEK NTSC */
+		.name   = "LG NTSC (newer TAPC series)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 170.00 /*MHz*/, 0x01, },
+			{ 16 * 450.00 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x08, },
+		},
+		.config = 0x8e,
+	},
 
 	/* 40-49 */
-	{ "HITACHI V7-J180AT", HITACHI, NTSC,
-	  16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,940 },
-	{ "Philips PAL_MK (FI1216 MK)", Philips, PAL,
-	  16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623},
-	{ "Philips 1236D ATSC/NTSC daul in", Philips, ATSC,
-	  16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732},
-	{ "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC,
-	  16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
-	{ "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC,
-	  16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
-	{ "Microtune 4049 FM5", Microtune, PAL,
-	  16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623},
-	{ "Panasonic VP27s/ENGE4324D", Panasonic, NTSC,
-	  16*160.00,16*454.00,0x01,0x02,0x08,0xce,940},
-	{ "LG NTSC (TAPE series)", LGINNOTEK, NTSC,
-	  16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
-	{ "Tenna TNF 8831 BGFF)", Philips, PAL,
-	  16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
-	{ "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC,
-	  16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732},
+	[TUNER_HITACHI_NTSC] = { /* HITACHI NTSC */
+		.name   = "HITACHI V7-J180AT",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 170.00 /*MHz*/, 0x01, },
+			{ 16 * 450.00 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x08, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_PHILIPS_PAL_MK] = { /* Philips PAL */
+		.name   = "Philips PAL_MK (FI1216 MK)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 140.25 /*MHz*/, 0x01, },
+			{ 16 * 463.25 /*MHz*/, 0xc2, },
+			{ 16 * 999.99        , 0xcf, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_PHILIPS_ATSC] = { /* Philips ATSC */
+		.name   = "Philips 1236D ATSC/NTSC dual in",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 157.25 /*MHz*/, 0xa0, },
+			{ 16 * 454.00 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_PHILIPS_FM1236_MK3] = { /* Philips NTSC */
+		.name   = "Philips NTSC MK3 (FM1236MK3 or FM1236/F)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 160.00 /*MHz*/, 0x01, },
+			{ 16 * 442.00 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x04, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_PHILIPS_4IN1] = { /* Philips NTSC */
+		.name   = "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 160.00 /*MHz*/, 0x01, },
+			{ 16 * 442.00 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x04, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_MICROTUNE_4049FM5] = { /* Microtune PAL */
+		.name   = "Microtune 4049 FM5",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 141.00 /*MHz*/, 0xa0, },
+			{ 16 * 464.00 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_PANASONIC_VP27] = { /* Panasonic NTSC */
+		.name   = "Panasonic VP27s/ENGE4324D",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 160.00 /*MHz*/, 0x01, },
+			{ 16 * 454.00 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x08, },
+		},
+		.config = 0xce,
+	},
+	[TUNER_LG_NTSC_TAPE] = { /* LGINNOTEK NTSC */
+		.name   = "LG NTSC (TAPE series)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 160.00 /*MHz*/, 0x01, },
+			{ 16 * 442.00 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x04, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_TNF_8831BGFF] = { /* Philips PAL */
+		.name   = "Tenna TNF 8831 BGFF)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 161.25 /*MHz*/, 0xa0, },
+			{ 16 * 463.25 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_MICROTUNE_4042FI5] = { /* Microtune NTSC */
+		.name   = "Microtune 4042 FI5 ATSC/NTSC dual in",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 162.00 /*MHz*/, 0xa2, },
+			{ 16 * 457.00 /*MHz*/, 0x94, },
+			{ 16 * 999.99        , 0x31, },
+		},
+		.config = 0x8e,
+	},
 
 	/* 50-59 */
-	{ "TCL 2002N", TCL, NTSC,
-	  16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732},
-	{ "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL,
-	  16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
-	{ "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC,
-	  16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
-	{ "Philips FQ1286", Philips, NTSC,
-	  16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, /* UHF band untested */
-	{ "tda8290+75", Philips, PAL|NTSC,
+	[TUNER_TCL_2002N] = { /* TCL NTSC */
+		.name   = "TCL 2002N",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 172.00 /*MHz*/, 0x01, },
+			{ 16 * 448.00 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x08, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_PHILIPS_FM1256_IH3] = { /* Philips PAL */
+		.name   = "Philips PAL/SECAM_D (FM 1256 I-H3)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 160.00 /*MHz*/, 0x01, },
+			{ 16 * 442.00 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x04, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_THOMSON_DTT7610] = { /* THOMSON ATSC */
+		.name   = "Thomson DTT 7610 (ATSC/NTSC)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 157.25 /*MHz*/, 0x39, },
+			{ 16 * 454.00 /*MHz*/, 0x3a, },
+			{ 16 * 999.99        , 0x3c, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_PHILIPS_FQ1286] = { /* Philips NTSC */
+		.name   = "Philips FQ1286",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 160.00 /*MHz*/, 0x41, },
+			{ 16 * 454.00 /*MHz*/, 0x42, },
+			{ 16 * 999.99        , 0x04, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_PHILIPS_TDA8290] = { /* Philips PAL|NTSC */
+		.name   = "tda8290+75",
 	  /* see tda8290.c for details */ },
-	{ "TCL 2002MB", TCL, PAL,
-	  16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623},
-	{ "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
-	  16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
-	{ "Philips FQ1236A MK4", Philips, NTSC,
-	  16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
-	{ "Ymec TVision TVF-8531MF/8831MF/8731MF", Philips, NTSC,
-	  16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
-	{ "Ymec TVision TVF-5533MF", Philips, NTSC,
-	  16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
+	[TUNER_TCL_2002MB] = { /* TCL PAL */
+		.name   = "TCL 2002MB",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 170.00 /*MHz*/, 0x01, },
+			{ 16 * 450.00 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x08, },
+		},
+		.config = 0xce,
+	},
+	[TUNER_PHILIPS_FQ1216AME_MK4] = { /* Philips PAL */
+		.name   = "Philips PAL/SECAM multi (FQ1216AME MK4)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 160.00 /*MHz*/, 0x01, },
+			{ 16 * 442.00 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x04, },
+		},
+		.config = 0xce,
+	},
+	[TUNER_PHILIPS_FQ1236A_MK4] = { /* Philips NTSC */
+		.name   = "Philips FQ1236A MK4",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 160.00 /*MHz*/, 0x01, },
+			{ 16 * 442.00 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x04, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_YMEC_TVF_8531MF] = { /* Philips NTSC */
+		.name   = "Ymec TVision TVF-8531MF/8831MF/8731MF",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 160.00 /*MHz*/, 0xa0, },
+			{ 16 * 454.00 /*MHz*/, 0x90, },
+			{ 16 * 999.99        , 0x30, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_YMEC_TVF_5533MF] = { /* Philips NTSC */
+		.name   = "Ymec TVision TVF-5533MF",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 160.00 /*MHz*/, 0x01, },
+			{ 16 * 454.00 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x04, },
+		},
+		.config = 0x8e,
+	},
 
 	/* 60-69 */
-	{ "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
-	  16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
-	{ "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL,
-	  16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623},
-	{ "Philips TEA5767HN FM Radio", Philips, RADIO,
+	[TUNER_THOMSON_DTT761X] = { /* THOMSON ATSC */
+		/* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */
+		.name   = "Thomson DTT 761X (ATSC/NTSC)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 145.25 /*MHz*/, 0x39, },
+			{ 16 * 415.25 /*MHz*/, 0x3a, },
+			{ 16 * 999.99        , 0x3c, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_TENA_9533_DI] = { /* Philips PAL */
+		.name   = "Tena TNF9533-D/IF/TNF9533-B/DF",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 160.25 /*MHz*/, 0x01, },
+			{ 16 * 464.25 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x04, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_TEA5767] = { /* Philips RADIO */
+		.name   = "Philips TEA5767HN FM Radio",
 	  /* see tea5767.c for details */},
-	{ "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL,
-	  16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 },
-	{ "LG TDVS-H062F/TUA6034", LGINNOTEK, ATSC,
-	  16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732},
-	{ "Ymec TVF66T5-B/DFF", Philips, PAL,
-	  16*160.25,16*464.25,0x01,0x02,0x08,0x8e,623},
-	{ "LG NTSC (TALN mini series)", LGINNOTEK, NTSC,
-	  16*137.25,16*373.25,0x01,0x02,0x08,0x8e,732 },
-	{ "Philips TD1316 Hybrid Tuner", Philips, PAL,
-	  16*160.00,16*442.00,0xa1,0xa2,0xa4,0xc8,623 },
-	{ "Philips TUV1236D ATSC/NTSC dual in", Philips, ATSC,
-	  16*157.25,16*454.00,0x01,0x02,0x04,0xce,732 },
-	{ "Tena TNF 5335 MF", Philips, NTSC,
-	  16*157.25,16*454.00,0x01,0x02,0x04,0x8e,732 },
+	[TUNER_PHILIPS_FMD1216ME_MK3] = { /* Philips PAL */
+		.name   = "Philips FMD1216ME MK3 Hybrid Tuner",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 160.00 /*MHz*/, 0x51, },
+			{ 16 * 442.00 /*MHz*/, 0x52, },
+			{ 16 * 999.99        , 0x54, },
+		},
+		.config = 0x86,
+	},
+	[TUNER_LG_TDVS_H062F] = { /* LGINNOTEK ATSC */
+		.name   = "LG TDVS-H062F/TUA6034",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 160.00 /*MHz*/, 0x01 },
+			{ 16 * 455.00 /*MHz*/, 0x02 },
+			{ 16 * 999.99        , 0x04 },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */
+		.name   = "Ymec TVF66T5-B/DFF",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 160.25 /*MHz*/, 0x01, },
+			{ 16 * 464.25 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x08, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_LG_NTSC_TALN_MINI] = { /* LGINNOTEK NTSC */
+		.name   = "LG NTSC (TALN mini series)",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 137.25 /*MHz*/, 0x01, },
+			{ 16 * 373.25 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x08, },
+		},
+		.config = 0x8e,
+	},
+	[TUNER_PHILIPS_TD1316] = { /* Philips PAL */
+		.name   = "Philips TD1316 Hybrid Tuner",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 160.00 /*MHz*/, 0xa1, },
+			{ 16 * 442.00 /*MHz*/, 0xa2, },
+			{ 16 * 999.99        , 0xa4, },
+		},
+		.config = 0xc8,
+	},
+	[TUNER_PHILIPS_TUV1236D] = { /* Philips ATSC */
+		.name   = "Philips TUV1236D ATSC/NTSC dual in",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 157.25 /*MHz*/, 0x01, },
+			{ 16 * 454.00 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x04, },
+		},
+		.config = 0xce,
+	},
+	[TUNER_TNF_5335MF] = { /* Philips NTSC */
+		.name   = "Tena TNF 5335 MF",
+		.count  = 3,
+		.ranges = {
+			{ 16 * 157.25 /*MHz*/, 0x01, },
+			{ 16 * 454.00 /*MHz*/, 0x02, },
+			{ 16 * 999.99        , 0x04, },
+		},
+		.config = 0x8e,
+	},
 };
 
 unsigned const int tuner_count = ARRAY_SIZE(tuners);
@@ -305,20 +843,19 @@
 	u16 div;
 	struct tunertype *tun;
 	unsigned char buffer[4];
-	int rc;
+	int rc, IFPCoff, i;
 
 	tun = &tuners[t->type];
-	if (freq < tun->thresh1) {
-		config = tun->VHF_L;
-		tuner_dbg("tv: VHF lowrange\n");
-	} else if (freq < tun->thresh2) {
-		config = tun->VHF_H;
-		tuner_dbg("tv: VHF high range\n");
-	} else {
-		config = tun->UHF;
-		tuner_dbg("tv: UHF range\n");
+	for (i = 0; i < tun->count; i++) {
+		if (freq > tun->ranges[i].thresh)
+			continue;
+		break;
 	}
-
+	config = tun->ranges[i].cb;
+	/*  i == 0 -> VHF_LO  */
+	/*  i == 1 -> VHF_HI  */
+	/*  i == 2 -> UHF     */
+	tuner_dbg("tv: range %d\n",i);
 
 	/* tv norm specific stuff for multi-norm tuners */
 	switch (t->type) {
@@ -420,7 +957,37 @@
 	 * frequency in case (wanted frequency < current frequency).
 	 */
 
-	div=freq + tun->IFPCoff;
+	/* IFPCoff = Video Intermediate Frequency - Vif:
+		940  =16*58.75  NTSC/J (Japan)
+		732  =16*45.75  M/N STD
+		704  =16*44     ATSC (at DVB code)
+		632  =16*39.50  I U.K.
+		622.4=16*38.90  B/G D/K I, L STD
+		592  =16*37.00  D China
+		590  =16.36.875 B Australia
+		543.2=16*33.95  L' STD
+		171.2=16*10.70  FM Radio (at set_radio_freq)
+	*/
+
+	if (t->std == V4L2_STD_NTSC_M_JP) {
+		IFPCoff = 940;
+	} else if ((t->std & V4L2_STD_MN) &&
+		  !(t->std & ~V4L2_STD_MN)) {
+		IFPCoff = 732;
+	} else if (t->std == V4L2_STD_SECAM_LC) {
+		IFPCoff = 543;
+	} else {
+		IFPCoff = 623;
+	}
+
+	div=freq + IFPCoff + offset;
+
+	tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, Offset=%d.%02d MHz, div=%0d\n",
+					freq / 16, freq % 16 * 100 / 16,
+					IFPCoff / 16, IFPCoff % 16 * 100 / 16,
+					offset / 16, offset % 16 * 100 / 16,
+					div);
+
 	if (t->type == TUNER_PHILIPS_SECAM && freq < t->freq) {
 		buffer[0] = tun->config;
 		buffer[1] = config;
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 0292c5a..b582943 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -31,6 +31,7 @@
 #include <linux/smp_lock.h>
 
 #include <media/audiochip.h>
+#include <media/v4l2-common.h>
 
 #include "tvaudio.h"
 
@@ -46,17 +47,6 @@
 
 #define UNSET    (-1U)
 
-#define tvaudio_info(fmt, arg...) do {\
-	printk(KERN_INFO "tvaudio %d-%04x: " fmt, \
-			chip->c.adapter->nr, chip->c.addr , ##arg); } while (0)
-#define tvaudio_warn(fmt, arg...) do {\
-	printk(KERN_WARNING "tvaudio %d-%04x: " fmt, \
-			chip->c.adapter->nr, chip->c.addr , ##arg); } while (0)
-#define tvaudio_dbg(fmt, arg...) do {\
-	if (debug) \
-		printk(KERN_INFO "tvaudio %d-%04x: " fmt, \
-			chip->c.adapter->nr, chip->c.addr , ##arg); } while (0)
-
 /* ---------------------------------------------------------------------- */
 /* our structs                                                            */
 
@@ -131,7 +121,7 @@
 	/* current settings */
 	__u16 left,right,treble,bass,mode;
 	int prevmode;
-	int norm;
+	int radio;
 
 	/* thread */
 	pid_t                tpid;
@@ -142,8 +132,6 @@
 	int                  watch_stereo;
 };
 
-#define VIDEO_MODE_RADIO 16      /* norm magic for radio mode */
-
 /* ---------------------------------------------------------------------- */
 /* i2c addresses                                                          */
 
@@ -171,23 +159,23 @@
 	unsigned char buffer[2];
 
 	if (-1 == subaddr) {
-		tvaudio_dbg("%s: chip_write: 0x%x\n",
+		v4l_dbg(1, &chip->c, "%s: chip_write: 0x%x\n",
 			chip->c.name, val);
 		chip->shadow.bytes[1] = val;
 		buffer[0] = val;
 		if (1 != i2c_master_send(&chip->c,buffer,1)) {
-			tvaudio_warn("%s: I/O error (write 0x%x)\n",
+			v4l_warn(&chip->c, "%s: I/O error (write 0x%x)\n",
 				chip->c.name, val);
 			return -1;
 		}
 	} else {
-		tvaudio_dbg("%s: chip_write: reg%d=0x%x\n",
+		v4l_dbg(1, &chip->c, "%s: chip_write: reg%d=0x%x\n",
 			chip->c.name, subaddr, val);
 		chip->shadow.bytes[subaddr+1] = val;
 		buffer[0] = subaddr;
 		buffer[1] = val;
 		if (2 != i2c_master_send(&chip->c,buffer,2)) {
-			tvaudio_warn("%s: I/O error (write reg%d=0x%x)\n",
+			v4l_warn(&chip->c, "%s: I/O error (write reg%d=0x%x)\n",
 			chip->c.name, subaddr, val);
 			return -1;
 		}
@@ -212,11 +200,11 @@
 	unsigned char buffer;
 
 	if (1 != i2c_master_recv(&chip->c,&buffer,1)) {
-		tvaudio_warn("%s: I/O error (read)\n",
+		v4l_warn(&chip->c, "%s: I/O error (read)\n",
 		chip->c.name);
 		return -1;
 	}
-	tvaudio_dbg("%s: chip_read: 0x%x\n",chip->c.name, buffer);
+	v4l_dbg(1, &chip->c, "%s: chip_read: 0x%x\n",chip->c.name, buffer);
 	return buffer;
 }
 
@@ -231,10 +219,10 @@
 	write[0] = subaddr;
 
 	if (2 != i2c_transfer(chip->c.adapter,msgs,2)) {
-		tvaudio_warn("%s: I/O error (read2)\n", chip->c.name);
+		v4l_warn(&chip->c, "%s: I/O error (read2)\n", chip->c.name);
 		return -1;
 	}
-	tvaudio_dbg("%s: chip_read2: reg%d=0x%x\n",
+	v4l_dbg(1, &chip->c, "%s: chip_read2: reg%d=0x%x\n",
 		chip->c.name, subaddr,read[0]);
 	return read[0];
 }
@@ -247,7 +235,7 @@
 		return 0;
 
 	/* update our shadow register set; print bytes if (debug > 0) */
-	tvaudio_dbg("%s: chip_cmd(%s): reg=%d, data:",
+	v4l_dbg(1, &chip->c, "%s: chip_cmd(%s): reg=%d, data:",
 		chip->c.name, name,cmd->bytes[0]);
 	for (i = 1; i < cmd->count; i++) {
 		if (debug)
@@ -259,7 +247,7 @@
 
 	/* send data to the chip */
 	if (cmd->count != i2c_master_send(&chip->c,cmd->bytes,cmd->count)) {
-		tvaudio_warn("%s: I/O error (%s)\n", chip->c.name, name);
+		v4l_warn(&chip->c, "%s: I/O error (%s)\n", chip->c.name, name);
 		return -1;
 	}
 	return 0;
@@ -286,7 +274,7 @@
 
 	daemonize("%s", chip->c.name);
 	allow_signal(SIGTERM);
-	tvaudio_dbg("%s: thread started\n", chip->c.name);
+	v4l_dbg(1, &chip->c, "%s: thread started\n", chip->c.name);
 
 	for (;;) {
 		add_wait_queue(&chip->wq, &wait);
@@ -298,10 +286,10 @@
 		try_to_freeze();
 		if (chip->done || signal_pending(current))
 			break;
-		tvaudio_dbg("%s: thread wakeup\n", chip->c.name);
+		v4l_dbg(1, &chip->c, "%s: thread wakeup\n", chip->c.name);
 
 		/* don't do anything for radio or if mode != auto */
-		if (chip->norm == VIDEO_MODE_RADIO || chip->mode != 0)
+		if (chip->radio || chip->mode != 0)
 			continue;
 
 		/* have a look what's going on */
@@ -311,7 +299,7 @@
 		mod_timer(&chip->wt, jiffies+2*HZ);
 	}
 
-	tvaudio_dbg("%s: thread exiting\n", chip->c.name);
+	v4l_dbg(1, &chip->c, "%s: thread exiting\n", chip->c.name);
 	complete_and_exit(&chip->texit, 0);
 	return 0;
 }
@@ -324,7 +312,7 @@
 	if (mode == chip->prevmode)
 	return;
 
-	tvaudio_dbg("%s: thread checkmode\n", chip->c.name);
+	v4l_dbg(1, &chip->c, "%s: thread checkmode\n", chip->c.name);
 	chip->prevmode = mode;
 
 	if (mode & VIDEO_SOUND_STEREO)
@@ -371,7 +359,7 @@
 	if (val & TDA9840_ST_STEREO)
 		mode |= VIDEO_SOUND_STEREO;
 
-	tvaudio_dbg ("tda9840_getmode(): raw chip read: %d, return: %d\n",
+	v4l_dbg(1, &chip->c, "tda9840_getmode(): raw chip read: %d, return: %d\n",
 		val, mode);
 	return mode;
 }
@@ -667,7 +655,7 @@
 		mode |= VIDEO_SOUND_STEREO;
 	if (val & TDA9873_DUAL)
 		mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
-	tvaudio_dbg ("tda9873_getmode(): raw chip read: %d, return: %d\n",
+	v4l_dbg(1, &chip->c, "tda9873_getmode(): raw chip read: %d, return: %d\n",
 		val, mode);
 	return mode;
 }
@@ -678,12 +666,12 @@
 	/*	int adj_data = chip->shadow.bytes[TDA9873_AD+1] ; */
 
 	if ((sw_data & TDA9873_INP_MASK) != TDA9873_INTERNAL) {
-		tvaudio_dbg("tda9873_setmode(): external input\n");
+		v4l_dbg(1, &chip->c, "tda9873_setmode(): external input\n");
 		return;
 	}
 
-	tvaudio_dbg("tda9873_setmode(): chip->shadow.bytes[%d] = %d\n", TDA9873_SW+1, chip->shadow.bytes[TDA9873_SW+1]);
-	tvaudio_dbg("tda9873_setmode(): sw_data  = %d\n", sw_data);
+	v4l_dbg(1, &chip->c, "tda9873_setmode(): chip->shadow.bytes[%d] = %d\n", TDA9873_SW+1, chip->shadow.bytes[TDA9873_SW+1]);
+	v4l_dbg(1, &chip->c, "tda9873_setmode(): sw_data  = %d\n", sw_data);
 
 	switch (mode) {
 	case VIDEO_SOUND_MONO:
@@ -704,7 +692,7 @@
 	}
 
 	chip_write(chip, TDA9873_SW, sw_data);
-	tvaudio_dbg("tda9873_setmode(): req. mode %d; chip_write: %d\n",
+	v4l_dbg(1, &chip->c, "tda9873_setmode(): req. mode %d; chip_write: %d\n",
 		mode, sw_data);
 }
 
@@ -843,7 +831,7 @@
 		chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80);
 		chip_write(chip, TDA9874A_AOSR, 0x00); /* or 0x10 */
 	}
-	tvaudio_dbg("tda9874a_setup(): %s [0x%02X].\n",
+	v4l_dbg(1, &chip->c, "tda9874a_setup(): %s [0x%02X].\n",
 		tda9874a_modelist[tda9874a_STD].name,tda9874a_STD);
 	return 1;
 }
@@ -886,7 +874,7 @@
 			mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
 	}
 
-	tvaudio_dbg("tda9874a_getmode(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n",
+	v4l_dbg(1, &chip->c, "tda9874a_getmode(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n",
 		 dsr, nsr, necr, mode);
 	return mode;
 }
@@ -932,7 +920,7 @@
 		chip_write(chip, TDA9874A_AOSR, aosr);
 		chip_write(chip, TDA9874A_MDACOSR, mdacosr);
 
-		tvaudio_dbg("tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n",
+		v4l_dbg(1, &chip->c, "tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n",
 			mode, aosr, mdacosr);
 
 	} else { /* dic == 0x07 */
@@ -967,7 +955,7 @@
 		chip_write(chip, TDA9874A_FMMR, fmmr);
 		chip_write(chip, TDA9874A_AOSR, aosr);
 
-		tvaudio_dbg("tda9874a_setmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n",
+		v4l_dbg(1, &chip->c, "tda9874a_setmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n",
 			mode, fmmr, aosr);
 	}
 }
@@ -981,10 +969,10 @@
 	if(-1 == (sic = chip_read2(chip,TDA9874A_SIC)))
 		return 0;
 
-	tvaudio_dbg("tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic);
+	v4l_dbg(1, &chip->c, "tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic);
 
 	if((dic == 0x11)||(dic == 0x07)) {
-		tvaudio_info("found tda9874%s.\n", (dic == 0x11) ? "a":"h");
+		v4l_info(&chip->c, "found tda9874%s.\n", (dic == 0x11) ? "a":"h");
 		tda9874a_dic = dic;	/* remember device id. */
 		return 1;
 	}
@@ -1196,7 +1184,7 @@
 	}else if (!(val & TA8874Z_B0)){
 		mode |= VIDEO_SOUND_STEREO;
 	}
-	/* tvaudio_dbg ("ta8874z_getmode(): raw chip read: 0x%02x, return: 0x%02x\n", val, mode); */
+	/* v4l_dbg(1, &chip->c, "ta8874z_getmode(): raw chip read: 0x%02x, return: 0x%02x\n", val, mode); */
 	return mode;
 }
 
@@ -1209,7 +1197,7 @@
 {
 	int update = 1;
 	audiocmd *t = NULL;
-	tvaudio_dbg("ta8874z_setmode(): mode: 0x%02x\n", mode);
+	v4l_dbg(1, &chip->c, "ta8874z_setmode(): mode: 0x%02x\n", mode);
 
 	switch(mode){
 	case VIDEO_SOUND_MONO:
@@ -1490,7 +1478,7 @@
 	i2c_set_clientdata(&chip->c, chip);
 
 	/* find description for the chip */
-	tvaudio_dbg("chip found @ 0x%x\n", addr<<1);
+	v4l_dbg(1, &chip->c, "chip found @ 0x%x\n", addr<<1);
 	for (desc = chiplist; desc->name != NULL; desc++) {
 		if (0 == *(desc->insmodopt))
 			continue;
@@ -1502,12 +1490,12 @@
 		break;
 	}
 	if (desc->name == NULL) {
-		tvaudio_dbg("no matching chip description found\n");
+		v4l_dbg(1, &chip->c, "no matching chip description found\n");
 		return -EIO;
 	}
-	tvaudio_info("%s found @ 0x%x (%s)\n", desc->name, addr<<1, adap->name);
+	v4l_info(&chip->c, "%s found @ 0x%x (%s)\n", desc->name, addr<<1, adap->name);
 	if (desc->flags) {
-		tvaudio_dbg("matches:%s%s%s.\n",
+		v4l_dbg(1, &chip->c, "matches:%s%s%s.\n",
 			(desc->flags & CHIP_HAS_VOLUME)     ? " volume"      : "",
 			(desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "",
 			(desc->flags & CHIP_HAS_INPUTSEL)   ? " audiomux"    : "");
@@ -1550,7 +1538,7 @@
 		init_completion(&chip->texit);
 		chip->tpid = kernel_thread(chip_thread,(void *)chip,0);
 		if (chip->tpid < 0)
-			tvaudio_warn("%s: kernel_thread() failed\n",
+			v4l_warn(&chip->c, "%s: kernel_thread() failed\n",
 			       chip->c.name);
 		wake_up_interruptible(&chip->wq);
 	}
@@ -1563,17 +1551,8 @@
 	   because dedicated drivers are used */
 	if ((adap->id == I2C_HW_SAA7146))
 		return 0;
-#ifdef I2C_CLASS_TV_ANALOG
 	if (adap->class & I2C_CLASS_TV_ANALOG)
 		return i2c_probe(adap, &addr_data, chip_attach);
-#else
-	switch (adap->id) {
-	case I2C_HW_B_BT848:
-	case I2C_HW_B_RIVA:
-	case I2C_HW_SAA7134:
-		return i2c_probe(adap, &addr_data, chip_attach);
-	}
-#endif
 	return 0;
 }
 
@@ -1604,7 +1583,7 @@
 	struct CHIPSTATE *chip = i2c_get_clientdata(client);
 	struct CHIPDESC  *desc = chiplist + chip->type;
 
-	tvaudio_dbg("%s: chip_command 0x%x\n", chip->c.name, cmd);
+	v4l_dbg(1, &chip->c, "%s: chip_command 0x%x\n", chip->c.name, cmd);
 
 	switch (cmd) {
 	case AUDC_SET_INPUT:
@@ -1617,7 +1596,7 @@
 		break;
 
 	case AUDC_SET_RADIO:
-		chip->norm = VIDEO_MODE_RADIO;
+		chip->radio = 1;
 		chip->watch_stereo = 0;
 		/* del_timer(&chip->wt); */
 		break;
@@ -1643,7 +1622,7 @@
 			va->bass   = chip->bass;
 			va->treble = chip->treble;
 		}
-		if (chip->norm != VIDEO_MODE_RADIO) {
+		if (!chip->radio) {
 			if (desc->getmode)
 				va->mode = desc->getmode(chip);
 			else
@@ -1678,15 +1657,80 @@
 		}
 		break;
 	}
-	case VIDIOCSCHAN:
-	{
-		struct video_channel *vc = arg;
 
-		chip->norm = vc->norm;
+	case VIDIOC_S_TUNER:
+	{
+		struct v4l2_tuner *vt = arg;
+		int mode = 0;
+
+		switch (vt->audmode) {
+		case V4L2_TUNER_MODE_MONO:
+			mode = VIDEO_SOUND_MONO;
+			break;
+		case V4L2_TUNER_MODE_STEREO:
+			mode = VIDEO_SOUND_STEREO;
+			break;
+		case V4L2_TUNER_MODE_LANG1:
+			mode = VIDEO_SOUND_LANG1;
+			break;
+		case V4L2_TUNER_MODE_LANG2:
+			mode = VIDEO_SOUND_LANG2;
+			break;
+		default:
+			break;
+		}
+
+		if (desc->setmode && mode) {
+			chip->watch_stereo = 0;
+			/* del_timer(&chip->wt); */
+			chip->mode = mode;
+			desc->setmode(chip, mode);
+		}
 		break;
 	}
-	case VIDIOCSFREQ:
+
+	case VIDIOC_G_TUNER:
 	{
+		struct v4l2_tuner *vt = arg;
+		int mode = VIDEO_SOUND_MONO;
+
+		if (chip->radio)
+			break;
+		vt->audmode = 0;
+		vt->rxsubchans = 0;
+		vt->capability = V4L2_TUNER_CAP_STEREO |
+			V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
+
+		if (desc->getmode)
+			mode = desc->getmode(chip);
+
+		if (mode & VIDEO_SOUND_MONO)
+			vt->rxsubchans |= V4L2_TUNER_SUB_MONO;
+		if (mode & VIDEO_SOUND_STEREO)
+			vt->rxsubchans |= V4L2_TUNER_SUB_STEREO;
+		if (mode & VIDEO_SOUND_LANG1)
+			vt->rxsubchans |= V4L2_TUNER_SUB_LANG1 |
+					  V4L2_TUNER_SUB_LANG2;
+
+		mode = chip->mode;
+		if (mode & VIDEO_SOUND_MONO)
+			vt->audmode = V4L2_TUNER_MODE_MONO;
+		if (mode & VIDEO_SOUND_STEREO)
+			vt->audmode = V4L2_TUNER_MODE_STEREO;
+		if (mode & VIDEO_SOUND_LANG1)
+			vt->audmode = V4L2_TUNER_MODE_LANG1;
+		if (mode & VIDEO_SOUND_LANG2)
+			vt->audmode = V4L2_TUNER_MODE_LANG2;
+		break;
+	}
+
+	case VIDIOCSCHAN:
+	case VIDIOC_S_STD:
+		chip->radio = 0;
+		break;
+
+	case VIDIOCSFREQ:
+	case VIDIOC_S_FREQUENCY:
 		chip->mode = 0; /* automatic */
 		if (desc->checkmode) {
 			desc->setmode(chip,VIDEO_SOUND_MONO);
@@ -1695,15 +1739,14 @@
 			mod_timer(&chip->wt, jiffies+2*HZ);
 			/* the thread will call checkmode() later */
 		}
-	}
+		break;
 	}
 	return 0;
 }
 
-
 static struct i2c_driver driver = {
 	.driver = {
-		.name    = "generic i2c audio driver",
+		.name    = "tvaudio",
 	},
 	.id              = I2C_DRIVERID_TVAUDIO,
 	.attach_adapter  = chip_probe,
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 8ac4cb8..fd0acc5 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -40,6 +40,7 @@
 
 #include <media/tuner.h>
 #include <media/tveeprom.h>
+#include <media/v4l2-common.h>
 #include <media/audiochip.h>
 
 MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
@@ -52,21 +53,19 @@
 
 #define STRM(array,i) (i < sizeof(array)/sizeof(char*) ? array[i] : "unknown")
 
-#define tveeprom_info(fmt, arg...) do {\
-	printk(KERN_INFO "tveeprom %d-%04x: " fmt, \
-			c->adapter->nr, c->addr , ##arg); } while (0)
-#define tveeprom_warn(fmt, arg...) do {\
-	printk(KERN_WARNING "tveeprom %d-%04x: " fmt, \
-			c->adapter->nr, c->addr , ##arg); } while (0)
-#define tveeprom_dbg(fmt, arg...) do {\
+#define tveeprom_info(fmt, arg...) \
+	v4l_printk(KERN_INFO, "tveeprom", c->adapter, c->addr, fmt , ## arg)
+#define tveeprom_warn(fmt, arg...) \
+	v4l_printk(KERN_WARNING, "tveeprom", c->adapter, c->addr, fmt , ## arg)
+#define tveeprom_dbg(fmt, arg...) do { \
 	if (debug) \
-		printk(KERN_INFO "tveeprom %d-%04x: " fmt, \
-			c->adapter->nr, c->addr , ##arg); } while (0)
+		v4l_printk(KERN_DEBUG, "tveeprom", c->adapter, c->addr, fmt , ## arg); \
+	} while (0)
 
-
-/* ----------------------------------------------------------------------- */
-/* some hauppauge specific stuff                                           */
-
+/*
+ * The Hauppauge eeprom uses an 8bit field to determine which
+ * tuner formats the tuner supports.
+ */
 static struct HAUPPAUGE_TUNER_FMT
 {
 	int	id;
@@ -74,14 +73,14 @@
 }
 hauppauge_tuner_fmt[] =
 {
-	{ 0x00000000, " unknown1" },
-	{ 0x00000000, " unknown2" },
-	{ 0x00000007, " PAL(B/G)" },
-	{ 0x00001000, " NTSC(M)" },
-	{ 0x00000010, " PAL(I)" },
-	{ 0x00400000, " SECAM(L/L')" },
-	{ 0x00000e00, " PAL(D/K)" },
-	{ 0x03000000, " ATSC/DVB Digital" },
+	{ V4L2_STD_UNKNOWN," UNKNOWN" },
+	{ V4L2_STD_UNKNOWN," FM" },
+	{ V4L2_STD_PAL_BG, " PAL(B/G)" },
+	{ V4L2_STD_NTSC_M, " NTSC(M)" },
+	{ V4L2_STD_PAL_I,  " PAL(I)" },
+	{ V4L2_STD_SECAM_L," SECAM(L/L')" },
+	{ V4L2_STD_PAL_DK, " PAL(D/D1/K)" },
+	{ V4L2_STD_ATSC,   " ATSC/DVB Digital" },
 };
 
 /* This is the full list of possible tuners. Many thanks to Hauppauge for
@@ -387,7 +386,7 @@
 	if ((eeprom_data[0] == 0x1a) && (eeprom_data[1] == 0xeb) &&
 			(eeprom_data[2] == 0x67) && (eeprom_data[3] == 0x95))
 		start=0xa0; /* Generic em28xx offset */
-	else if (((eeprom_data[0] & 0xf0) == 0x10) &&
+	else if (((eeprom_data[0] & 0xe1) == 0x01) &&
 					(eeprom_data[1] == 0x00) &&
 					(eeprom_data[2] == 0x00) &&
 					(eeprom_data[8] == 0x84))
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
index e837f9f..9e86cae 100644
--- a/drivers/media/video/tvmixer.c
+++ b/drivers/media/video/tvmixer.c
@@ -227,13 +227,9 @@
 }
 
 static struct i2c_driver driver = {
-#ifdef I2C_PEC
 	.driver = {
-		.name    = "tv card mixer driver",
+		.name    = "tvmixer",
 	},
-#else
-	.name            = "tv card mixer driver",
-#endif
 	.id              = I2C_DRIVERID_TVMIXER,
 	.detach_adapter  = tvmixer_adapters,
 	.attach_adapter  = tvmixer_adapters,
@@ -267,22 +263,8 @@
 	struct video_audio va;
 	int i,minor;
 
-#ifdef I2C_CLASS_TV_ANALOG
 	if (!(client->adapter->class & I2C_CLASS_TV_ANALOG))
 		return -1;
-#else
-	/* TV card ??? */
-	switch (client->adapter->id) {
-	case I2C_HW_SMBUS_VOODOO3:
-	case I2C_HW_B_BT848:
-	case I2C_HW_B_RIVA:
-		/* ok, have a look ... */
-		break;
-	default:
-		/* ignore that one */
-		return -1;
-	}
-#endif
 
 	/* unregister ?? */
 	for (i = 0; i < DEV_MAX; i++) {
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index a60442e..c35b804 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -9,6 +9,7 @@
 #include <linux/videodev.h>
 #include <linux/delay.h>
 #include <linux/video_decoder.h>
+#include <media/v4l2-common.h>
 
 #include "tvp5150_reg.h"
 
@@ -28,33 +29,38 @@
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
-#define dprintk(num, format, args...) \
+#define tvp5150_info(fmt, arg...) do { \
+	printk(KERN_INFO "%s %d-%04x: " fmt, c->driver->driver.name, \
+	       i2c_adapter_id(c->adapter), c->addr , ## arg); } while (0)
+#define tvp5150_dbg(num, fmt, arg...) \
 	do { \
 		if (debug >= num) \
-			printk(format, ##args); \
-	} while (0)
+			printk(KERN_DEBUG "%s debug %d-%04x: " fmt,\
+				c->driver->driver.name, \
+				i2c_adapter_id(c->adapter), \
+				c->addr , ## arg); } while (0)
 
 /* supported controls */
 static struct v4l2_queryctrl tvp5150_qctrl[] = {
 	{
-	 .id = V4L2_CID_BRIGHTNESS,
-	 .type = V4L2_CTRL_TYPE_INTEGER,
-	 .name = "Brightness",
-	 .minimum = 0,
-	 .maximum = 255,
-	 .step = 1,
-	 .default_value = 0,
-	 .flags = 0,
-	 }, {
-	     .id = V4L2_CID_CONTRAST,
-	     .type = V4L2_CTRL_TYPE_INTEGER,
-	     .name = "Contrast",
-	     .minimum = 0,
-	     .maximum = 255,
-	     .step = 0x1,
-	     .default_value = 0x10,
-	     .flags = 0,
-	     }, {
+		.id = V4L2_CID_BRIGHTNESS,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Brightness",
+		.minimum = 0,
+		.maximum = 255,
+		.step = 1,
+		.default_value = 0,
+		.flags = 0,
+	}, {
+		.id = V4L2_CID_CONTRAST,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Contrast",
+		.minimum = 0,
+		.maximum = 255,
+		.step = 0x1,
+		.default_value = 0x10,
+		.flags = 0,
+	}, {
 		 .id = V4L2_CID_SATURATION,
 		 .type = V4L2_CTRL_TYPE_INTEGER,
 		 .name = "Saturation",
@@ -63,16 +69,16 @@
 		 .step = 0x1,
 		 .default_value = 0x10,
 		 .flags = 0,
-		 }, {
-		     .id = V4L2_CID_HUE,
-		     .type = V4L2_CTRL_TYPE_INTEGER,
-		     .name = "Hue",
-		     .minimum = -128,
-		     .maximum = 127,
-		     .step = 0x1,
-		     .default_value = 0x10,
-		     .flags = 0,
-		     }
+	}, {
+		.id = V4L2_CID_HUE,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Hue",
+		.minimum = -128,
+		.maximum = 127,
+		.step = 0x1,
+		.default_value = 0x10,
+		.flags = 0,
+	}
 };
 
 struct tvp5150 {
@@ -94,12 +100,14 @@
 
 	buffer[0] = addr;
 	if (1 != (rc = i2c_master_send(c, buffer, 1)))
-		dprintk(0, "i2c i/o error: rc == %d (should be 1)\n", rc);
+		tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 1)\n", rc);
 
 	msleep(10);
 
 	if (1 != (rc = i2c_master_recv(c, buffer, 1)))
-		dprintk(0, "i2c i/o error: rc == %d (should be 1)\n", rc);
+		tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 1)\n", rc);
+
+	tvp5150_dbg(2, "tvp5150: read 0x%02x = 0x%02x\n", addr, buffer[0]);
 
 	return (buffer[0]);
 }
@@ -109,13 +117,12 @@
 {
 	unsigned char buffer[2];
 	int rc;
-/*	struct tvp5150 *core = i2c_get_clientdata(c); */
 
 	buffer[0] = addr;
 	buffer[1] = value;
-	dprintk(1, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]);
+	tvp5150_dbg(2, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]);
 	if (2 != (rc = i2c_master_send(c, buffer, 2)))
-		dprintk(0, "i2c i/o error: rc == %d (should be 2)\n", rc);
+		tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 2)\n", rc);
 }
 
 static void dump_reg(struct i2c_client *c)
@@ -437,48 +444,346 @@
 static inline void tvp5150_selmux(struct i2c_client *c,
 				  enum tvp5150_input input)
 {
+	int opmode=0;
+
 	struct tvp5150 *decoder = i2c_get_clientdata(c);
 
 	if (!decoder->enable)
 		input |= TVP5150_BLACK_SCREEN;
 
+	switch (input) {
+	case TVP5150_ANALOG_CH0:
+	case TVP5150_ANALOG_CH1:
+		opmode=0x30;		/* TV Mode */
+		break;
+	default:
+		opmode=0;		/* Auto Mode */
+		break;
+	}
+
+	tvp5150_write(c, TVP5150_OP_MODE_CTL, opmode);
 	tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input);
 };
 
-static inline void tvp5150_reset(struct i2c_client *c)
+struct i2c_reg_value {
+	unsigned char reg;
+	unsigned char value;
+};
+
+/* Default values as sugested at TVP5150AM1 datasheet */
+static const struct i2c_reg_value tvp5150_init_default[] = {
+	{ /* 0x00 */
+		TVP5150_VD_IN_SRC_SEL_1,0x00
+	},
+	{ /* 0x01 */
+		TVP5150_ANAL_CHL_CTL,0x15
+	},
+	{ /* 0x02 */
+		TVP5150_OP_MODE_CTL,0x00
+	},
+	{ /* 0x03 */
+		TVP5150_MISC_CTL,0x01
+	},
+	{ /* 0x06 */
+		TVP5150_COLOR_KIL_THSH_CTL,0x10
+	},
+	{ /* 0x07 */
+		TVP5150_LUMA_PROC_CTL_1,0x60
+	},
+	{ /* 0x08 */
+		TVP5150_LUMA_PROC_CTL_2,0x00
+	},
+	{ /* 0x09 */
+		TVP5150_BRIGHT_CTL,0x80
+	},
+	{ /* 0x0a */
+		TVP5150_SATURATION_CTL,0x80
+	},
+	{ /* 0x0b */
+		TVP5150_HUE_CTL,0x00
+	},
+	{ /* 0x0c */
+		TVP5150_CONTRAST_CTL,0x80
+	},
+	{ /* 0x0d */
+		TVP5150_DATA_RATE_SEL,0x47
+	},
+	{ /* 0x0e */
+		TVP5150_LUMA_PROC_CTL_3,0x00
+	},
+	{ /* 0x0f */
+		TVP5150_CONF_SHARED_PIN,0x08
+	},
+	{ /* 0x11 */
+		TVP5150_ACT_VD_CROP_ST_MSB,0x00
+	},
+	{ /* 0x12 */
+		TVP5150_ACT_VD_CROP_ST_LSB,0x00
+	},
+	{ /* 0x13 */
+		TVP5150_ACT_VD_CROP_STP_MSB,0x00
+	},
+	{ /* 0x14 */
+		TVP5150_ACT_VD_CROP_STP_LSB,0x00
+	},
+	{ /* 0x15 */
+		TVP5150_GENLOCK,0x01
+	},
+	{ /* 0x16 */
+		TVP5150_HORIZ_SYNC_START,0x80
+	},
+	{ /* 0x18 */
+		TVP5150_VERT_BLANKING_START,0x00
+	},
+	{ /* 0x19 */
+		TVP5150_VERT_BLANKING_STOP,0x00
+	},
+	{ /* 0x1a */
+		TVP5150_CHROMA_PROC_CTL_1,0x0c
+	},
+	{ /* 0x1b */
+		TVP5150_CHROMA_PROC_CTL_2,0x14
+	},
+	{ /* 0x1c */
+		TVP5150_INT_RESET_REG_B,0x00
+	},
+	{ /* 0x1d */
+		TVP5150_INT_ENABLE_REG_B,0x00
+	},
+	{ /* 0x1e */
+		TVP5150_INTT_CONFIG_REG_B,0x00
+	},
+	{ /* 0x28 */
+		TVP5150_VIDEO_STD,0x00
+	},
+	{ /* 0x2e */
+		TVP5150_MACROVISION_ON_CTR,0x0f
+	},
+	{ /* 0x2f */
+		TVP5150_MACROVISION_OFF_CTR,0x01
+	},
+	{ /* 0xbb */
+		TVP5150_TELETEXT_FIL_ENA,0x00
+	},
+	{ /* 0xc0 */
+		TVP5150_INT_STATUS_REG_A,0x00
+	},
+	{ /* 0xc1 */
+		TVP5150_INT_ENABLE_REG_A,0x00
+	},
+	{ /* 0xc2 */
+		TVP5150_INT_CONF,0x04
+	},
+	{ /* 0xc8 */
+		TVP5150_FIFO_INT_THRESHOLD,0x80
+	},
+	{ /* 0xc9 */
+		TVP5150_FIFO_RESET,0x00
+	},
+	{ /* 0xca */
+		TVP5150_LINE_NUMBER_INT,0x00
+	},
+	{ /* 0xcb */
+		TVP5150_PIX_ALIGN_REG_LOW,0x4e
+	},
+	{ /* 0xcc */
+		TVP5150_PIX_ALIGN_REG_HIGH,0x00
+	},
+	{ /* 0xcd */
+		TVP5150_FIFO_OUT_CTRL,0x01
+	},
+	{ /* 0xcf */
+		TVP5150_FULL_FIELD_ENA_1,0x00
+	},
+	{ /* 0xd0 */
+		TVP5150_FULL_FIELD_ENA_2,0x00
+	},
+	{ /* 0xfc */
+		TVP5150_FULL_FIELD_MODE_REG,0x7f
+	},
+	{ /* end of data */
+		0xff,0xff
+	}
+};
+
+/* Default values as sugested at TVP5150AM1 datasheet */
+static const struct i2c_reg_value tvp5150_init_enable[] = {
+	{
+		TVP5150_CONF_SHARED_PIN, 2
+	},{	/* Automatic offset and AGC enabled */
+		TVP5150_ANAL_CHL_CTL, 0x15
+	},{	/* Activate YCrCb output 0x9 or 0xd ? */
+		TVP5150_MISC_CTL, 0x6f
+	},{	/* Activates video std autodetection for all standards */
+		TVP5150_AUTOSW_MSK, 0x0
+	},{	/* Default format: 0x47. For 4:2:2: 0x40 */
+		TVP5150_DATA_RATE_SEL, 0x47
+	},{
+		TVP5150_CHROMA_PROC_CTL_1, 0x0c
+	},{
+		TVP5150_CHROMA_PROC_CTL_2, 0x54
+	},{	/* Non documented, but initialized on WinTV USB2 */
+		0x27, 0x20
+	},{
+		0xff,0xff
+	}
+};
+
+struct i2c_vbi_ram_value {
+	u16 reg;
+	unsigned char values[26];
+};
+
+struct i2c_vbi_ram_value vbi_ram_default[] =
+{
+	{0x010, /* WST SECAM 6 */
+		{ 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x26, 0xe6, 0xb4, 0x0e, 0x0, 0x0, 0x0, 0x10, 0x0 }
+	},
+	{0x030, /* WST PAL B 6 */
+		{ 0xaa, 0xaa, 0xff, 0xff , 0x27, 0x2e, 0x20, 0x2b, 0xa6, 0x72, 0x10, 0x0, 0x0, 0x0, 0x10, 0x0 }
+	},
+	{0x050, /* WST PAL C 6 */
+		{ 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x22, 0xa6, 0x98, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 }
+	},
+	{0x070, /* WST NTSC 6 */
+		{ 0xaa, 0xaa, 0xff, 0xff , 0x27, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 }
+	},
+	{0x090, /* NABTS, NTSC 6 */
+		{ 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x22, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x15, 0x0 }
+	},
+	{0x0b0, /* NABTS, NTSC-J 6 */
+		{ 0xaa, 0xaa, 0xff, 0xff , 0xa7, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 }
+	},
+	{0x0d0, /* CC, PAL/SECAM 6 */
+		{ 0xaa, 0x2a, 0xff, 0x3f , 0x04, 0x51, 0x6e, 0x02, 0xa6, 0x7b, 0x09, 0x0, 0x0, 0x0, 0x27, 0x0 }
+	},
+	{0x0f0, /* CC, NTSC 6 */
+		{ 0xaa, 0x2a, 0xff, 0x3f , 0x04, 0x51, 0x6e, 0x02, 0x69, 0x8c, 0x09, 0x0, 0x0, 0x0, 0x27, 0x0 }
+	},
+	{0x110, /* WSS, PAL/SECAM 6 */
+		{ 0x5b, 0x55, 0xc5, 0xff , 0x0, 0x71, 0x6e, 0x42, 0xa6, 0xcd, 0x0f, 0x0, 0x0, 0x0, 0x3a, 0x0 }
+	},
+	{0x130, /* WSS, NTSC C */
+		{ 0x38, 0x00, 0x3f, 0x00 , 0x0, 0x71, 0x6e, 0x43, 0x69, 0x7c, 0x08, 0x0, 0x0, 0x0, 0x39, 0x0 }
+	},
+	{0x150, /* VITC, PAL/SECAM 6 */
+		{ 0x0, 0x0, 0x0, 0x0 , 0x0, 0x8f, 0x6d, 0x49, 0xa6, 0x85, 0x08, 0x0, 0x0, 0x0, 0x4c, 0x0 }
+	},
+	{0x170, /* VITC, NTSC 6 */
+		{ 0x0, 0x0, 0x0, 0x0 , 0x0, 0x8f, 0x6d, 0x49, 0x69, 0x94, 0x08, 0x0, 0x0, 0x0, 0x4c, 0x0 }
+	},
+	{ (u16)-1 }
+};
+
+static int tvp5150_write_inittab(struct i2c_client *c,
+				 const struct i2c_reg_value *regs)
+{
+	while (regs->reg != 0xff) {
+		tvp5150_write(c, regs->reg, regs->value);
+		regs++;
+	}
+	return 0;
+}
+
+static int tvp5150_vdp_init(struct i2c_client *c,
+				 const struct i2c_vbi_ram_value *regs)
+{
+	unsigned int i;
+
+	/* Disable Full Field */
+	tvp5150_write(c, TVP5150_FULL_FIELD_ENA_1, 0);
+
+	/* Before programming, Line mode should be at 0xff */
+	for (i=TVP5150_FULL_FIELD_ENA_2; i<=TVP5150_LINE_MODE_REG_44; i++)
+		tvp5150_write(c, i, 0xff);
+
+	/* Load Ram Table */
+	while (regs->reg != (u16)-1 ) {
+		tvp5150_write(c, TVP5150_CONF_RAM_ADDR_HIGH,regs->reg>>8);
+		tvp5150_write(c, TVP5150_CONF_RAM_ADDR_LOW,regs->reg);
+
+		for (i=0;i<16;i++)
+			tvp5150_write(c, TVP5150_VDP_CONF_RAM_DATA,regs->values[i]);
+
+		regs++;
+	}
+	return 0;
+}
+
+static int tvp5150_set_std(struct i2c_client *c, v4l2_std_id std)
 {
 	struct tvp5150 *decoder = i2c_get_clientdata(c);
+	int fmt=0;
 
-	tvp5150_write(c, TVP5150_CONF_SHARED_PIN, 2);
+	decoder->norm=std;
 
-	/* Automatic offset and AGC enabled */
-	tvp5150_write(c, TVP5150_ANAL_CHL_CTL, 0x15);
+	/* First tests should be against specific std */
 
-	/* Normal Operation */
-//      tvp5150_write(c, TVP5150_OP_MODE_CTL, 0x00);
+	if (std == V4L2_STD_ALL) {
+		fmt=0;	/* Autodetect mode */
+	} else if (std & V4L2_STD_NTSC_443) {
+		fmt=0xa;
+	} else if (std & V4L2_STD_PAL_M) {
+		fmt=0x6;
+	} else if (std & (V4L2_STD_PAL_N| V4L2_STD_PAL_Nc)) {
+		fmt=0x8;
+	} else {
+		/* Then, test against generic ones */
+		if (std & V4L2_STD_NTSC) {
+			fmt=0x2;
+		} else if (std & V4L2_STD_PAL) {
+			fmt=0x4;
+		} else if (std & V4L2_STD_SECAM) {
+			fmt=0xc;
+		}
+	}
 
-	/* Activate YCrCb output 0x9 or 0xd ? */
-	tvp5150_write(c, TVP5150_MISC_CTL, 0x6f);
+	tvp5150_dbg(1,"Set video std register to %d.\n",fmt);
+	tvp5150_write(c, TVP5150_VIDEO_STD, fmt);
 
-	/* Activates video std autodetection for all standards */
-	tvp5150_write(c, TVP5150_AUTOSW_MSK, 0x0);
+	return 0;
+}
 
-	/* Default format: 0x47, 4:2:2: 0x40 */
-	tvp5150_write(c, TVP5150_DATA_RATE_SEL, 0x47);
+static inline void tvp5150_reset(struct i2c_client *c)
+{
+	u8 type, ver_656, msb_id, lsb_id, msb_rom, lsb_rom;
+	struct tvp5150 *decoder = i2c_get_clientdata(c);
 
+	type=tvp5150_read(c,TVP5150_AUTOSW_MSK);
+	msb_id=tvp5150_read(c,TVP5150_MSB_DEV_ID);
+	lsb_id=tvp5150_read(c,TVP5150_LSB_DEV_ID);
+	msb_rom=tvp5150_read(c,TVP5150_ROM_MAJOR_VER);
+	lsb_rom=tvp5150_read(c,TVP5150_ROM_MINOR_VER);
+
+	if (type==0xdc) {
+		ver_656=tvp5150_read(c,TVP5150_REV_SELECT);
+		tvp5150_info("tvp%02x%02xam1 detected 656 version is %d.\n",msb_id, lsb_id,ver_656);
+	} else if (type==0xfc) {
+		tvp5150_info("tvp%02x%02xa detected.\n",msb_id, lsb_id);
+	} else {
+		tvp5150_info("unknown tvp%02x%02x chip detected(%d).\n",msb_id,lsb_id,type);
+	}
+	tvp5150_info("Rom ver is %d.%d\n",msb_rom,lsb_rom);
+
+	/* Initializes TVP5150 to its default values */
+	tvp5150_write_inittab(c, tvp5150_init_default);
+
+	/* Initializes VDP registers */
+	tvp5150_vdp_init(c, vbi_ram_default);
+
+	/* Selects decoder input */
 	tvp5150_selmux(c, decoder->input);
 
-	tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_1, 0x0c);
-	tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_2, 0x54);
+	/* Initializes TVP5150 to stream enabled values */
+	tvp5150_write_inittab(c, tvp5150_init_enable);
 
-	tvp5150_write(c, 0x27, 0x20);	/* ?????????? */
-
-	tvp5150_write(c, TVP5150_VIDEO_STD, 0x0);	/* Auto switch */
-
+	/* Initialize image preferences */
 	tvp5150_write(c, TVP5150_BRIGHT_CTL, decoder->bright >> 8);
 	tvp5150_write(c, TVP5150_CONTRAST_CTL, decoder->contrast >> 8);
 	tvp5150_write(c, TVP5150_SATURATION_CTL, decoder->contrast >> 8);
 	tvp5150_write(c, TVP5150_HUE_CTL, (decoder->hue - 32768) >> 8);
+
+	tvp5150_set_std(c, decoder->norm);
 };
 
 static int tvp5150_get_ctrl(struct i2c_client *c, struct v4l2_control *ctrl)
@@ -498,9 +803,8 @@
 	case V4L2_CID_HUE:
 		ctrl->value = tvp5150_read(c, TVP5150_HUE_CTL);
 		return 0;
-	default:
-		return -EINVAL;
 	}
+	return -EINVAL;
 }
 
 static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl)
@@ -520,28 +824,59 @@
 	case V4L2_CID_HUE:
 		tvp5150_write(c, TVP5150_HUE_CTL, ctrl->value);
 		return 0;
-	default:
-		return -EINVAL;
 	}
+	return -EINVAL;
 }
 
 /****************************************************************************
 			I2C Command
  ****************************************************************************/
-static int tvp5150_command(struct i2c_client *client,
+static int tvp5150_command(struct i2c_client *c,
 			   unsigned int cmd, void *arg)
 {
-	struct tvp5150 *decoder = i2c_get_clientdata(client);
+	struct tvp5150 *decoder = i2c_get_clientdata(c);
 
 	switch (cmd) {
 
 	case 0:
+	case VIDIOC_INT_RESET:
 	case DECODER_INIT:
-		tvp5150_reset(client);
+		tvp5150_reset(c);
+		break;
+	case VIDIOC_S_STD:
+		if (decoder->norm == *(v4l2_std_id *)arg)
+			break;
+		return tvp5150_set_std(c, *(v4l2_std_id *)arg);
+	case VIDIOC_G_STD:
+		*(v4l2_std_id *)arg = decoder->norm;
 		break;
 
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	case VIDIOC_INT_G_REGISTER:
+	{
+		struct v4l2_register *reg = arg;
+
+		if (reg->i2c_id != I2C_DRIVERID_TVP5150)
+			return -EINVAL;
+		reg->val = tvp5150_read(c, reg->reg & 0xff);
+		break;
+	}
+
+	case VIDIOC_INT_S_REGISTER:
+	{
+		struct v4l2_register *reg = arg;
+
+		if (reg->i2c_id != I2C_DRIVERID_TVP5150)
+			return -EINVAL;
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+		tvp5150_write(c, reg->reg & 0xff, reg->val & 0xff);
+		break;
+	}
+#endif
+
 	case DECODER_DUMP:
-		dump_reg(client);
+		dump_reg(c);
 		break;
 
 	case DECODER_GET_CAPABILITIES:
@@ -600,7 +935,7 @@
 			}
 
 			decoder->input = *iarg;
-			tvp5150_selmux(client, decoder->input);
+			tvp5150_selmux(c, decoder->input);
 
 			break;
 		}
@@ -620,19 +955,18 @@
 
 			decoder->enable = (*iarg != 0);
 
-			tvp5150_selmux(client, decoder->input);
+			tvp5150_selmux(c, decoder->input);
 
 			break;
 		}
 	case VIDIOC_QUERYCTRL:
 		{
 			struct v4l2_queryctrl *qc = arg;
-			u8 i, n;
+			int i;
 
-			dprintk(1, KERN_DEBUG "VIDIOC_QUERYCTRL");
+			tvp5150_dbg(1, "VIDIOC_QUERYCTRL called\n");
 
-			n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]);
-			for (i = 0; i < n; i++)
+			for (i = 0; i < ARRAY_SIZE(tvp5150_qctrl); i++)
 				if (qc->id && qc->id == tvp5150_qctrl[i].id) {
 					memcpy(qc, &(tvp5150_qctrl[i]),
 					       sizeof(*qc));
@@ -644,16 +978,14 @@
 	case VIDIOC_G_CTRL:
 		{
 			struct v4l2_control *ctrl = arg;
-			dprintk(1, KERN_DEBUG "VIDIOC_G_CTRL");
+			tvp5150_dbg(1, "VIDIOC_G_CTRL called\n");
 
-			return tvp5150_get_ctrl(client, ctrl);
+			return tvp5150_get_ctrl(c, ctrl);
 		}
-	case VIDIOC_S_CTRL_OLD:	/* ??? */
 	case VIDIOC_S_CTRL:
 		{
 			struct v4l2_control *ctrl = arg;
 			u8 i, n;
-			dprintk(1, KERN_DEBUG "VIDIOC_S_CTRL");
 			n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]);
 			for (i = 0; i < n; i++)
 				if (ctrl->id == tvp5150_qctrl[i].id) {
@@ -662,11 +994,10 @@
 					    || ctrl->value >
 					    tvp5150_qctrl[i].maximum)
 						return -ERANGE;
-					dprintk(1,
-						KERN_DEBUG
-						"VIDIOC_S_CTRL: id=%d, value=%d",
+					tvp5150_dbg(1,
+						"VIDIOC_S_CTRL: id=%d, value=%d\n",
 						ctrl->id, ctrl->value);
-					return tvp5150_set_ctrl(client, ctrl);
+					return tvp5150_set_ctrl(c, ctrl);
 				}
 			return -EINVAL;
 		}
@@ -677,25 +1008,25 @@
 			if (decoder->bright != pic->brightness) {
 				/* We want 0 to 255 we get 0-65535 */
 				decoder->bright = pic->brightness;
-				tvp5150_write(client, TVP5150_BRIGHT_CTL,
+				tvp5150_write(c, TVP5150_BRIGHT_CTL,
 					      decoder->bright >> 8);
 			}
 			if (decoder->contrast != pic->contrast) {
 				/* We want 0 to 255 we get 0-65535 */
 				decoder->contrast = pic->contrast;
-				tvp5150_write(client, TVP5150_CONTRAST_CTL,
+				tvp5150_write(c, TVP5150_CONTRAST_CTL,
 					      decoder->contrast >> 8);
 			}
 			if (decoder->sat != pic->colour) {
 				/* We want 0 to 255 we get 0-65535 */
 				decoder->sat = pic->colour;
-				tvp5150_write(client, TVP5150_SATURATION_CTL,
+				tvp5150_write(c, TVP5150_SATURATION_CTL,
 					      decoder->contrast >> 8);
 			}
 			if (decoder->hue != pic->hue) {
 				/* We want -128 to 127 we get 0-65535 */
 				decoder->hue = pic->hue;
-				tvp5150_write(client, TVP5150_HUE_CTL,
+				tvp5150_write(c, TVP5150_HUE_CTL,
 					      (decoder->hue - 32768) >> 8);
 			}
 			break;
@@ -720,12 +1051,12 @@
 static int tvp5150_detect_client(struct i2c_adapter *adapter,
 				 int address, int kind)
 {
-	struct i2c_client *client;
+	struct i2c_client *c;
 	struct tvp5150 *core;
 	int rv;
 
-	dprintk(1,
-		KERN_INFO
+	if (debug)
+		printk( KERN_INFO
 		"tvp5150.c: detecting tvp5150 client on address 0x%x\n",
 		address << 1);
 
@@ -738,22 +1069,22 @@
 	     I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
 		return 0;
 
-	client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (client == 0)
+	c = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+	if (c == 0)
 		return -ENOMEM;
-	memcpy(client, &client_template, sizeof(struct i2c_client));
+	memcpy(c, &client_template, sizeof(struct i2c_client));
 
 	core = kmalloc(sizeof(struct tvp5150), GFP_KERNEL);
 	if (core == 0) {
-		kfree(client);
+		kfree(c);
 		return -ENOMEM;
 	}
 	memset(core, 0, sizeof(struct tvp5150));
-	i2c_set_clientdata(client, core);
+	i2c_set_clientdata(c, core);
 
-	rv = i2c_attach_client(client);
+	rv = i2c_attach_client(c);
 
-	core->norm = VIDEO_MODE_AUTO;
+	core->norm = V4L2_STD_ALL;
 	core->input = 2;
 	core->enable = 1;
 	core->bright = 32768;
@@ -762,37 +1093,41 @@
 	core->sat = 32768;
 
 	if (rv) {
-		kfree(client);
+		kfree(c);
 		kfree(core);
 		return rv;
 	}
 
 	if (debug > 1)
-		dump_reg(client);
+		dump_reg(c);
 	return 0;
 }
 
 static int tvp5150_attach_adapter(struct i2c_adapter *adapter)
 {
-	dprintk(1,
-		KERN_INFO
+	if (debug)
+		printk( KERN_INFO
 		"tvp5150.c: starting probe for adapter %s (0x%x)\n",
 		adapter->name, adapter->id);
 	return i2c_probe(adapter, &addr_data, &tvp5150_detect_client);
 }
 
-static int tvp5150_detach_client(struct i2c_client *client)
+static int tvp5150_detach_client(struct i2c_client *c)
 {
-	struct tvp5150 *decoder = i2c_get_clientdata(client);
+	struct tvp5150 *decoder = i2c_get_clientdata(c);
 	int err;
 
-	err = i2c_detach_client(client);
+	tvp5150_dbg(1,
+		"tvp5150.c: removing tvp5150 adapter on address 0x%x\n",
+		c->addr << 1);
+
+	err = i2c_detach_client(c);
 	if (err) {
 		return err;
 	}
 
 	kfree(decoder);
-	kfree(client);
+	kfree(c);
 
 	return 0;
 }
@@ -803,9 +1138,7 @@
 	.driver = {
 		.name = "tvp5150",
 	},
-
-	/* FIXME */
-	.id = I2C_DRIVERID_SAA7110,
+	.id = I2C_DRIVERID_TVP5150,
 
 	.attach_adapter = tvp5150_attach_adapter,
 	.detach_client = tvp5150_detach_client,
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index 4134549..2ab5b40 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -951,6 +951,10 @@
 			dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err);
 			break;
 		}
+		if (fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) {
+			err = -EINVAL;
+			break;
+		}
 		memset(fmt, 0, sizeof(*fmt));
 		fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line;
 		fmt->sampling_rate    = fmt2->fmt.vbi.sampling_rate;
@@ -966,6 +970,11 @@
 	{
 		struct vbi_format      *fmt = arg;
 
+		if (VIDEO_PALETTE_RAW != fmt->sample_format) {
+			err = -EINVAL;
+			break;
+		}
+
 		fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
 		memset(fmt2, 0, sizeof(*fmt2));
 
@@ -986,7 +995,7 @@
 
 		if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line ||
 		    fmt2->fmt.vbi.sampling_rate    != fmt->sampling_rate    ||
-		    VIDEO_PALETTE_RAW              != fmt->sample_format    ||
+		    fmt2->fmt.vbi.sample_format    != V4L2_PIX_FMT_GREY     ||
 		    fmt2->fmt.vbi.start[0]         != fmt->start[0]         ||
 		    fmt2->fmt.vbi.count[0]         != fmt->count[0]         ||
 		    fmt2->fmt.vbi.start[1]         != fmt->start[1]         ||
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 62a7d63..5dbd7c1 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -58,6 +58,8 @@
 #include <asm/pgtable.h>
 #include <asm/io.h>
 #include <asm/div64.h>
+#include <linux/video_decoder.h>
+#include <media/v4l2-common.h>
 
 #ifdef CONFIG_KMOD
 #include <linux/kmod.h>
@@ -190,55 +192,174 @@
 	[V4L2_BUF_TYPE_VBI_OUTPUT]    = "vbi-out",
 };
 
-char *v4l2_ioctl_names[256] = {
-	[0 ... 255]                      = "UNKNOWN",
-	[_IOC_NR(VIDIOC_QUERYCAP)]       = "VIDIOC_QUERYCAP",
-	[_IOC_NR(VIDIOC_RESERVED)]       = "VIDIOC_RESERVED",
-	[_IOC_NR(VIDIOC_ENUM_FMT)]       = "VIDIOC_ENUM_FMT",
-	[_IOC_NR(VIDIOC_G_FMT)]          = "VIDIOC_G_FMT",
-	[_IOC_NR(VIDIOC_S_FMT)]          = "VIDIOC_S_FMT",
-	[_IOC_NR(VIDIOC_REQBUFS)]        = "VIDIOC_REQBUFS",
-	[_IOC_NR(VIDIOC_QUERYBUF)]       = "VIDIOC_QUERYBUF",
-	[_IOC_NR(VIDIOC_G_FBUF)]         = "VIDIOC_G_FBUF",
-	[_IOC_NR(VIDIOC_S_FBUF)]         = "VIDIOC_S_FBUF",
-	[_IOC_NR(VIDIOC_OVERLAY)]        = "VIDIOC_OVERLAY",
-	[_IOC_NR(VIDIOC_QBUF)]           = "VIDIOC_QBUF",
-	[_IOC_NR(VIDIOC_DQBUF)]          = "VIDIOC_DQBUF",
-	[_IOC_NR(VIDIOC_STREAMON)]       = "VIDIOC_STREAMON",
-	[_IOC_NR(VIDIOC_STREAMOFF)]      = "VIDIOC_STREAMOFF",
-	[_IOC_NR(VIDIOC_G_PARM)]         = "VIDIOC_G_PARM",
-	[_IOC_NR(VIDIOC_S_PARM)]         = "VIDIOC_S_PARM",
-	[_IOC_NR(VIDIOC_G_STD)]          = "VIDIOC_G_STD",
-	[_IOC_NR(VIDIOC_S_STD)]          = "VIDIOC_S_STD",
-	[_IOC_NR(VIDIOC_ENUMSTD)]        = "VIDIOC_ENUMSTD",
-	[_IOC_NR(VIDIOC_ENUMINPUT)]      = "VIDIOC_ENUMINPUT",
-	[_IOC_NR(VIDIOC_G_CTRL)]         = "VIDIOC_G_CTRL",
-	[_IOC_NR(VIDIOC_S_CTRL)]         = "VIDIOC_S_CTRL",
-	[_IOC_NR(VIDIOC_G_TUNER)]        = "VIDIOC_G_TUNER",
-	[_IOC_NR(VIDIOC_S_TUNER)]        = "VIDIOC_S_TUNER",
-	[_IOC_NR(VIDIOC_G_AUDIO)]        = "VIDIOC_G_AUDIO",
-	[_IOC_NR(VIDIOC_S_AUDIO)]        = "VIDIOC_S_AUDIO",
-	[_IOC_NR(VIDIOC_QUERYCTRL)]      = "VIDIOC_QUERYCTRL",
-	[_IOC_NR(VIDIOC_QUERYMENU)]      = "VIDIOC_QUERYMENU",
-	[_IOC_NR(VIDIOC_G_INPUT)]        = "VIDIOC_G_INPUT",
-	[_IOC_NR(VIDIOC_S_INPUT)]        = "VIDIOC_S_INPUT",
-	[_IOC_NR(VIDIOC_G_OUTPUT)]       = "VIDIOC_G_OUTPUT",
-	[_IOC_NR(VIDIOC_S_OUTPUT)]       = "VIDIOC_S_OUTPUT",
-	[_IOC_NR(VIDIOC_ENUMOUTPUT)]     = "VIDIOC_ENUMOUTPUT",
-	[_IOC_NR(VIDIOC_G_AUDOUT)]       = "VIDIOC_G_AUDOUT",
-	[_IOC_NR(VIDIOC_S_AUDOUT)]       = "VIDIOC_S_AUDOUT",
-	[_IOC_NR(VIDIOC_G_MODULATOR)]    = "VIDIOC_G_MODULATOR",
-	[_IOC_NR(VIDIOC_S_MODULATOR)]    = "VIDIOC_S_MODULATOR",
-	[_IOC_NR(VIDIOC_G_FREQUENCY)]    = "VIDIOC_G_FREQUENCY",
-	[_IOC_NR(VIDIOC_S_FREQUENCY)]    = "VIDIOC_S_FREQUENCY",
-	[_IOC_NR(VIDIOC_CROPCAP)]        = "VIDIOC_CROPCAP",
-	[_IOC_NR(VIDIOC_G_CROP)]         = "VIDIOC_G_CROP",
-	[_IOC_NR(VIDIOC_S_CROP)]         = "VIDIOC_S_CROP",
-	[_IOC_NR(VIDIOC_G_JPEGCOMP)]     = "VIDIOC_G_JPEGCOMP",
-	[_IOC_NR(VIDIOC_S_JPEGCOMP)]     = "VIDIOC_S_JPEGCOMP",
-	[_IOC_NR(VIDIOC_QUERYSTD)]       = "VIDIOC_QUERYSTD",
-	[_IOC_NR(VIDIOC_TRY_FMT)]        = "VIDIOC_TRY_FMT",
+/* ------------------------------------------------------------------ */
+/* debug help functions                                               */
+
+#ifdef HAVE_V4L1
+static const char *v4l1_ioctls[] = {
+	[_IOC_NR(VIDIOCGCAP)]       = "VIDIOCGCAP",
+	[_IOC_NR(VIDIOCGCHAN)]      = "VIDIOCGCHAN",
+	[_IOC_NR(VIDIOCSCHAN)]      = "VIDIOCSCHAN",
+	[_IOC_NR(VIDIOCGTUNER)]     = "VIDIOCGTUNER",
+	[_IOC_NR(VIDIOCSTUNER)]     = "VIDIOCSTUNER",
+	[_IOC_NR(VIDIOCGPICT)]      = "VIDIOCGPICT",
+	[_IOC_NR(VIDIOCSPICT)]      = "VIDIOCSPICT",
+	[_IOC_NR(VIDIOCCAPTURE)]    = "VIDIOCCAPTURE",
+	[_IOC_NR(VIDIOCGWIN)]       = "VIDIOCGWIN",
+	[_IOC_NR(VIDIOCSWIN)]       = "VIDIOCSWIN",
+	[_IOC_NR(VIDIOCGFBUF)]      = "VIDIOCGFBUF",
+	[_IOC_NR(VIDIOCSFBUF)]      = "VIDIOCSFBUF",
+	[_IOC_NR(VIDIOCKEY)]        = "VIDIOCKEY",
+	[_IOC_NR(VIDIOCGFREQ)]      = "VIDIOCGFREQ",
+	[_IOC_NR(VIDIOCSFREQ)]      = "VIDIOCSFREQ",
+	[_IOC_NR(VIDIOCGAUDIO)]     = "VIDIOCGAUDIO",
+	[_IOC_NR(VIDIOCSAUDIO)]     = "VIDIOCSAUDIO",
+	[_IOC_NR(VIDIOCSYNC)]       = "VIDIOCSYNC",
+	[_IOC_NR(VIDIOCMCAPTURE)]   = "VIDIOCMCAPTURE",
+	[_IOC_NR(VIDIOCGMBUF)]      = "VIDIOCGMBUF",
+	[_IOC_NR(VIDIOCGUNIT)]      = "VIDIOCGUNIT",
+	[_IOC_NR(VIDIOCGCAPTURE)]   = "VIDIOCGCAPTURE",
+	[_IOC_NR(VIDIOCSCAPTURE)]   = "VIDIOCSCAPTURE",
+	[_IOC_NR(VIDIOCSPLAYMODE)]  = "VIDIOCSPLAYMODE",
+	[_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE",
+	[_IOC_NR(VIDIOCGPLAYINFO)]  = "VIDIOCGPLAYINFO",
+	[_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE",
+	[_IOC_NR(VIDIOCGVBIFMT)]    = "VIDIOCGVBIFMT",
+	[_IOC_NR(VIDIOCSVBIFMT)]    = "VIDIOCSVBIFMT"
 };
+#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
+#endif
+
+static const char *v4l2_ioctls[] = {
+	[_IOC_NR(VIDIOC_QUERYCAP)]         = "VIDIOC_QUERYCAP",
+	[_IOC_NR(VIDIOC_RESERVED)]         = "VIDIOC_RESERVED",
+	[_IOC_NR(VIDIOC_ENUM_FMT)]         = "VIDIOC_ENUM_FMT",
+	[_IOC_NR(VIDIOC_G_FMT)]            = "VIDIOC_G_FMT",
+	[_IOC_NR(VIDIOC_S_FMT)]            = "VIDIOC_S_FMT",
+	[_IOC_NR(VIDIOC_G_MPEGCOMP)]       = "VIDIOC_G_MPEGCOMP",
+	[_IOC_NR(VIDIOC_S_MPEGCOMP)]       = "VIDIOC_S_MPEGCOMP",
+	[_IOC_NR(VIDIOC_REQBUFS)]          = "VIDIOC_REQBUFS",
+	[_IOC_NR(VIDIOC_QUERYBUF)]         = "VIDIOC_QUERYBUF",
+	[_IOC_NR(VIDIOC_G_FBUF)]           = "VIDIOC_G_FBUF",
+	[_IOC_NR(VIDIOC_S_FBUF)]           = "VIDIOC_S_FBUF",
+	[_IOC_NR(VIDIOC_OVERLAY)]          = "VIDIOC_OVERLAY",
+	[_IOC_NR(VIDIOC_QBUF)]             = "VIDIOC_QBUF",
+	[_IOC_NR(VIDIOC_DQBUF)]            = "VIDIOC_DQBUF",
+	[_IOC_NR(VIDIOC_STREAMON)]         = "VIDIOC_STREAMON",
+	[_IOC_NR(VIDIOC_STREAMOFF)]        = "VIDIOC_STREAMOFF",
+	[_IOC_NR(VIDIOC_G_PARM)]           = "VIDIOC_G_PARM",
+	[_IOC_NR(VIDIOC_S_PARM)]           = "VIDIOC_S_PARM",
+	[_IOC_NR(VIDIOC_G_STD)]            = "VIDIOC_G_STD",
+	[_IOC_NR(VIDIOC_S_STD)]            = "VIDIOC_S_STD",
+	[_IOC_NR(VIDIOC_ENUMSTD)]          = "VIDIOC_ENUMSTD",
+	[_IOC_NR(VIDIOC_ENUMINPUT)]        = "VIDIOC_ENUMINPUT",
+	[_IOC_NR(VIDIOC_G_CTRL)]           = "VIDIOC_G_CTRL",
+	[_IOC_NR(VIDIOC_S_CTRL)]           = "VIDIOC_S_CTRL",
+	[_IOC_NR(VIDIOC_G_TUNER)]          = "VIDIOC_G_TUNER",
+	[_IOC_NR(VIDIOC_S_TUNER)]          = "VIDIOC_S_TUNER",
+	[_IOC_NR(VIDIOC_G_AUDIO)]          = "VIDIOC_G_AUDIO",
+	[_IOC_NR(VIDIOC_S_AUDIO)]          = "VIDIOC_S_AUDIO",
+	[_IOC_NR(VIDIOC_QUERYCTRL)]        = "VIDIOC_QUERYCTRL",
+	[_IOC_NR(VIDIOC_QUERYMENU)]        = "VIDIOC_QUERYMENU",
+	[_IOC_NR(VIDIOC_G_INPUT)]          = "VIDIOC_G_INPUT",
+	[_IOC_NR(VIDIOC_S_INPUT)]          = "VIDIOC_S_INPUT",
+	[_IOC_NR(VIDIOC_G_OUTPUT)]         = "VIDIOC_G_OUTPUT",
+	[_IOC_NR(VIDIOC_S_OUTPUT)]         = "VIDIOC_S_OUTPUT",
+	[_IOC_NR(VIDIOC_ENUMOUTPUT)]       = "VIDIOC_ENUMOUTPUT",
+	[_IOC_NR(VIDIOC_G_AUDOUT)]         = "VIDIOC_G_AUDOUT",
+	[_IOC_NR(VIDIOC_S_AUDOUT)]         = "VIDIOC_S_AUDOUT",
+	[_IOC_NR(VIDIOC_G_MODULATOR)]      = "VIDIOC_G_MODULATOR",
+	[_IOC_NR(VIDIOC_S_MODULATOR)]      = "VIDIOC_S_MODULATOR",
+	[_IOC_NR(VIDIOC_G_FREQUENCY)]      = "VIDIOC_G_FREQUENCY",
+	[_IOC_NR(VIDIOC_S_FREQUENCY)]      = "VIDIOC_S_FREQUENCY",
+	[_IOC_NR(VIDIOC_CROPCAP)]          = "VIDIOC_CROPCAP",
+	[_IOC_NR(VIDIOC_G_CROP)]           = "VIDIOC_G_CROP",
+	[_IOC_NR(VIDIOC_S_CROP)]           = "VIDIOC_S_CROP",
+	[_IOC_NR(VIDIOC_G_JPEGCOMP)]       = "VIDIOC_G_JPEGCOMP",
+	[_IOC_NR(VIDIOC_S_JPEGCOMP)]       = "VIDIOC_S_JPEGCOMP",
+	[_IOC_NR(VIDIOC_QUERYSTD)]         = "VIDIOC_QUERYSTD",
+	[_IOC_NR(VIDIOC_TRY_FMT)]          = "VIDIOC_TRY_FMT",
+	[_IOC_NR(VIDIOC_ENUMAUDIO)]        = "VIDIOC_ENUMAUDIO",
+	[_IOC_NR(VIDIOC_ENUMAUDOUT)]       = "VIDIOC_ENUMAUDOUT",
+	[_IOC_NR(VIDIOC_G_PRIORITY)]       = "VIDIOC_G_PRIORITY",
+	[_IOC_NR(VIDIOC_S_PRIORITY)]       = "VIDIOC_S_PRIORITY",
+#if 1
+	[_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
+#endif
+	[_IOC_NR(VIDIOC_LOG_STATUS)]       = "VIDIOC_LOG_STATUS"
+};
+#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
+
+static const char *v4l2_int_ioctls[] = {
+#ifdef HAVE_VIDEO_DECODER
+	[_IOC_NR(DECODER_GET_CAPABILITIES)]    = "DECODER_GET_CAPABILITIES",
+	[_IOC_NR(DECODER_GET_STATUS)]          = "DECODER_GET_STATUS",
+	[_IOC_NR(DECODER_SET_NORM)]            = "DECODER_SET_NORM",
+	[_IOC_NR(DECODER_SET_INPUT)]           = "DECODER_SET_INPUT",
+	[_IOC_NR(DECODER_SET_OUTPUT)]          = "DECODER_SET_OUTPUT",
+	[_IOC_NR(DECODER_ENABLE_OUTPUT)]       = "DECODER_ENABLE_OUTPUT",
+	[_IOC_NR(DECODER_SET_PICTURE)]         = "DECODER_SET_PICTURE",
+	[_IOC_NR(DECODER_SET_GPIO)]            = "DECODER_SET_GPIO",
+	[_IOC_NR(DECODER_INIT)]                = "DECODER_INIT",
+	[_IOC_NR(DECODER_SET_VBI_BYPASS)]      = "DECODER_SET_VBI_BYPASS",
+	[_IOC_NR(DECODER_DUMP)]                = "DECODER_DUMP",
+#endif
+	[_IOC_NR(AUDC_SET_RADIO)]              = "AUDC_SET_RADIO",
+	[_IOC_NR(AUDC_SET_INPUT)]              = "AUDC_SET_INPUT",
+
+	[_IOC_NR(TUNER_SET_TYPE_ADDR)]         = "TUNER_SET_TYPE_ADDR",
+	[_IOC_NR(TUNER_SET_STANDBY)]           = "TUNER_SET_STANDBY",
+	[_IOC_NR(TDA9887_SET_CONFIG)]          = "TDA9887_SET_CONFIG",
+
+	[_IOC_NR(VIDIOC_INT_S_REGISTER)]       = "VIDIOC_INT_S_REGISTER",
+	[_IOC_NR(VIDIOC_INT_G_REGISTER)]       = "VIDIOC_INT_G_REGISTER",
+	[_IOC_NR(VIDIOC_INT_RESET)]            = "VIDIOC_INT_RESET",
+	[_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ",
+	[_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)]  = "VIDIOC_INT_DECODE_VBI_LINE",
+	[_IOC_NR(VIDIOC_INT_S_VBI_DATA)]       = "VIDIOC_INT_S_VBI_DATA",
+	[_IOC_NR(VIDIOC_INT_G_VBI_DATA)]       = "VIDIOC_INT_G_VBI_DATA",
+	[_IOC_NR(VIDIOC_INT_G_CHIP_IDENT)]     = "VIDIOC_INT_G_CHIP_IDENT",
+	[_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)]   = "VIDIOC_INT_I2S_CLOCK_FREQ"
+};
+#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls)
+
+/* Common ioctl debug function. This function can be used by
+   external ioctl messages as well as internal V4L ioctl */
+void v4l_printk_ioctl(unsigned int cmd)
+{
+	char *dir;
+
+	switch (_IOC_DIR(cmd)) {
+	case _IOC_NONE:              dir = "--"; break;
+	case _IOC_READ:              dir = "r-"; break;
+	case _IOC_WRITE:             dir = "-w"; break;
+	case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
+	default:                     dir = "*ERR*"; break;
+	}
+	switch (_IOC_TYPE(cmd)) {
+	case 'd':
+		printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n",
+		       (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ?
+		       v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
+		break;
+#ifdef HAVE_V4L1
+	case 'v':
+		printk("v4l1 ioctl %s, dir=%s (0x%08x)\n",
+		       (_IOC_NR(cmd) < V4L1_IOCTLS) ?
+		       v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
+		break;
+#endif
+	case 'V':
+		printk("v4l2 ioctl %s, dir=%s (0x%08x)\n",
+		       (_IOC_NR(cmd) < V4L2_IOCTLS) ?
+		       v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd);
+		break;
+
+	default:
+		printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n",
+		       _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd);
+	}
+}
 
 /* ----------------------------------------------------------------- */
 
@@ -253,7 +374,7 @@
 
 EXPORT_SYMBOL(v4l2_field_names);
 EXPORT_SYMBOL(v4l2_type_names);
-EXPORT_SYMBOL(v4l2_ioctl_names);
+EXPORT_SYMBOL(v4l_printk_ioctl);
 
 /*
  * Local variables:
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 6de5b00..9a9902c 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -68,7 +68,8 @@
 {
 	struct video_device *vfd = container_of(cd, struct video_device, class_dev);
 
-#if 1 /* needed until all drivers are fixed */
+#if 1
+	/* needed until all drivers are fixed */
 	if (!vfd->release)
 		return;
 #endif
@@ -338,13 +339,14 @@
 	if (vfd->dev)
 		vfd->class_dev.dev = vfd->dev;
 	vfd->class_dev.class       = &video_class;
-	vfd->class_dev.devt       = MKDEV(VIDEO_MAJOR, vfd->minor);
+	vfd->class_dev.devt        = MKDEV(VIDEO_MAJOR, vfd->minor);
 	strlcpy(vfd->class_dev.class_id, vfd->devfs_name + 4, BUS_ID_SIZE);
 	class_device_register(&vfd->class_dev);
 	class_device_create_file(&vfd->class_dev,
-				 &class_device_attr_name);
+				&class_device_attr_name);
 
-#if 1 /* needed until all drivers are fixed */
+#if 1
+	/* needed until all drivers are fixed */
 	if (!vfd->release)
 		printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
 		       "Please fix your driver for proper sysfs support, see "
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index c318ba3..b7b0aff 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -187,6 +187,7 @@
 	.open           = video_exclusive_open,
 	.release        = video_exclusive_release,
 	.ioctl          = w9966_v4l_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.read           = w9966_v4l_read,
 	.llseek         = no_llseek,
 };
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index bbfd55c..c2e6d2e 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -25,7 +25,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/ioctl.h>
@@ -33,20 +32,12 @@
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
 #include <linux/videodev.h>
-#include <media/audiochip.h>
+#include <media/v4l2-common.h>
 
 MODULE_DESCRIPTION("wm8775 driver");
 MODULE_AUTHOR("Ulf Eklund, Hans Verkuil");
 MODULE_LICENSE("GPL");
 
-#define wm8775_err(fmt, arg...) do { \
-	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
-	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-#define wm8775_info(fmt, arg...) do { \
-	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
-	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-
-
 static unsigned short normal_i2c[] = { 0x36 >> 1, I2C_CLIENT_END };
 
 
@@ -70,7 +61,7 @@
 	int i;
 
 	if (reg < 0 || reg >= TOT_REGS) {
-		wm8775_err("Invalid register R%d\n", reg);
+		v4l_err(client, "Invalid register R%d\n", reg);
 		return -1;
 	}
 
@@ -80,7 +71,7 @@
 			return 0;
 		}
 	}
-	wm8775_err("I2C: cannot write %03x to register R%d\n", val, reg);
+	v4l_err(client, "I2C: cannot write %03x to register R%d\n", val, reg);
 	return -1;
 }
 
@@ -88,38 +79,53 @@
 			  void *arg)
 {
 	struct wm8775_state *state = i2c_get_clientdata(client);
-	int *input = arg;
+	struct v4l2_audio *input = arg;
+	struct v4l2_control *ctrl = arg;
 
 	switch (cmd) {
-	case AUDC_SET_INPUT:
+	case VIDIOC_S_AUDIO:
+		/* There are 4 inputs and one output. Zero or more inputs
+		   are multiplexed together to the output. Hence there are
+		   16 combinations.
+		   If only one input is active (the normal case) then the
+		   input values 1, 2, 4 or 8 should be used. */
+		if (input->index > 15) {
+			v4l_err(client, "Invalid input %d.\n", input->index);
+			return -EINVAL;
+		}
+		state->input = input->index;
+		if (state->muted)
+			break;
 		wm8775_write(client, R21, 0x0c0);
 		wm8775_write(client, R14, 0x1d4);
 		wm8775_write(client, R15, 0x1d4);
+		wm8775_write(client, R21, 0x100 + state->input);
+		break;
 
-		if (*input == AUDIO_RADIO) {
-			wm8775_write(client, R21, 0x108);
-			state->input = 8;
-			state->muted = 0;
-			break;
-		}
-		if (*input == AUDIO_MUTE) {
-			state->muted = 1;
-			break;
-		}
-		if (*input == AUDIO_UNMUTE) {
+	case VIDIOC_G_AUDIO:
+		memset(input, 0, sizeof(*input));
+		input->index = state->input;
+		break;
+
+	case VIDIOC_G_CTRL:
+		if (ctrl->id != V4L2_CID_AUDIO_MUTE)
+			return -EINVAL;
+		ctrl->value = state->muted;
+		break;
+
+	case VIDIOC_S_CTRL:
+		if (ctrl->id != V4L2_CID_AUDIO_MUTE)
+			return -EINVAL;
+		state->muted = ctrl->value;
+		wm8775_write(client, R21, 0x0c0);
+		wm8775_write(client, R14, 0x1d4);
+		wm8775_write(client, R15, 0x1d4);
+		if (!state->muted)
 			wm8775_write(client, R21, 0x100 + state->input);
-			state->muted = 0;
-			break;
-		}
-		/* All other inputs... */
-		wm8775_write(client, R21, 0x102);
-		state->input = 2;
-		state->muted = 0;
 		break;
 
 	case VIDIOC_LOG_STATUS:
-		wm8775_info("Input: %s%s\n",
-			    state->input == 8 ? "radio" : "default",
+		v4l_info(client, "Input: %d%s\n", state->input,
 			    state->muted ? " (muted)" : "");
 		break;
 
@@ -170,7 +176,7 @@
 	client->driver = &i2c_driver;
 	snprintf(client->name, sizeof(client->name) - 1, "wm8775");
 
-	wm8775_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name);
+	v4l_info(client, "chip found @ 0x%x (%s)\n", address << 1, adapter->name);
 
 	state = kmalloc(sizeof(struct wm8775_state), GFP_KERNEL);
 	if (state == NULL) {
@@ -206,11 +212,7 @@
 
 static int wm8775_probe(struct i2c_adapter *adapter)
 {
-#ifdef I2C_CLASS_TV_ANALOG
 	if (adapter->class & I2C_CLASS_TV_ANALOG)
-#else
-	if (adapter->id == I2C_HW_B_BT848)
-#endif
 		return i2c_probe(adapter, &addr_data, wm8775_attach);
 	return 0;
 }
@@ -235,12 +237,10 @@
 	.driver = {
 		.name = "wm8775",
 	},
-
-	.id = I2C_DRIVERID_WM8775,
-
+	.id             = I2C_DRIVERID_WM8775,
 	.attach_adapter = wm8775_probe,
-	.detach_client = wm8775_detach,
-	.command = wm8775_command,
+	.detach_client  = wm8775_detach,
+	.command        = wm8775_command,
 };
 
 
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index 4034f1b..15283f4 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -4678,6 +4678,7 @@
 	.open = zoran_open,
 	.release = zoran_close,
 	.ioctl = zoran_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek = no_llseek,
 	.read = zoran_read,
 	.write = zoran_write,
diff --git a/drivers/media/video/zr36120.c b/drivers/media/video/zr36120.c
index 0728681..d4c633b 100644
--- a/drivers/media/video/zr36120.c
+++ b/drivers/media/video/zr36120.c
@@ -1490,6 +1490,7 @@
 	.write		= zoran_write,
 	.poll		= zoran_poll,
 	.ioctl		= zoran_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.mmap		= zoran_mmap,
 	.minor		= -1,
 };
diff --git a/drivers/message/i2o/README.ioctl b/drivers/message/i2o/README.ioctl
index 73dd084..65c0c47 100644
--- a/drivers/message/i2o/README.ioctl
+++ b/drivers/message/i2o/README.ioctl
@@ -185,7 +185,7 @@
       ENOMEM      Kernel memory allocation error
 
    A return value of 0 does not mean that the value was actually
-   properly retreived.  The user should check the result list 
+   properly retrieved.  The user should check the result list 
    to determine the specific status of the transaction.
 
 VIII. Downloading Software
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 6696f71..bfca5c1 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -495,6 +495,7 @@
 
 		case 2: /* MMC v2.0 - v2.2 */
 		case 3: /* MMC v3.1 - v3.3 */
+		case 4: /* MMC v4 */
 			card->cid.manfid	= UNSTUFF_BITS(resp, 120, 8);
 			card->cid.oemid		= UNSTUFF_BITS(resp, 104, 16);
 			card->cid.prod_name[0]	= UNSTUFF_BITS(resp, 96, 8);
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
index d5f2898..f2c42b1 100644
--- a/drivers/mmc/mmc_block.c
+++ b/drivers/mmc/mmc_block.c
@@ -187,7 +187,13 @@
 			brq.data.flags |= MMC_DATA_WRITE;
 			brq.data.blocks = 1;
 		}
-		brq.mrq.stop = brq.data.blocks > 1 ? &brq.stop : NULL;
+
+		if (brq.data.blocks > 1) {
+			brq.data.flags |= MMC_DATA_MULTI;
+			brq.mrq.stop = &brq.stop;
+		} else {
+			brq.mrq.stop = NULL;
+		}
 
 		brq.data.sg = mq->sg;
 		brq.data.sg_len = blk_rq_map_sg(req->q, req, brq.data.sg);
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index 4f13bd2..f257576 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -90,7 +90,7 @@
  * Basic functions
  */
 
-static inline void wbsd_unlock_config(struct wbsd_host* host)
+static inline void wbsd_unlock_config(struct wbsd_host *host)
 {
 	BUG_ON(host->config == 0);
 
@@ -98,14 +98,14 @@
 	outb(host->unlock_code, host->config);
 }
 
-static inline void wbsd_lock_config(struct wbsd_host* host)
+static inline void wbsd_lock_config(struct wbsd_host *host)
 {
 	BUG_ON(host->config == 0);
 
 	outb(LOCK_CODE, host->config);
 }
 
-static inline void wbsd_write_config(struct wbsd_host* host, u8 reg, u8 value)
+static inline void wbsd_write_config(struct wbsd_host *host, u8 reg, u8 value)
 {
 	BUG_ON(host->config == 0);
 
@@ -113,7 +113,7 @@
 	outb(value, host->config + 1);
 }
 
-static inline u8 wbsd_read_config(struct wbsd_host* host, u8 reg)
+static inline u8 wbsd_read_config(struct wbsd_host *host, u8 reg)
 {
 	BUG_ON(host->config == 0);
 
@@ -121,13 +121,13 @@
 	return inb(host->config + 1);
 }
 
-static inline void wbsd_write_index(struct wbsd_host* host, u8 index, u8 value)
+static inline void wbsd_write_index(struct wbsd_host *host, u8 index, u8 value)
 {
 	outb(index, host->base + WBSD_IDXR);
 	outb(value, host->base + WBSD_DATAR);
 }
 
-static inline u8 wbsd_read_index(struct wbsd_host* host, u8 index)
+static inline u8 wbsd_read_index(struct wbsd_host *host, u8 index)
 {
 	outb(index, host->base + WBSD_IDXR);
 	return inb(host->base + WBSD_DATAR);
@@ -137,7 +137,7 @@
  * Common routines
  */
 
-static void wbsd_init_device(struct wbsd_host* host)
+static void wbsd_init_device(struct wbsd_host *host)
 {
 	u8 setup, ier;
 
@@ -197,7 +197,7 @@
 	inb(host->base + WBSD_ISR);
 }
 
-static void wbsd_reset(struct wbsd_host* host)
+static void wbsd_reset(struct wbsd_host *host)
 {
 	u8 setup;
 
@@ -211,14 +211,13 @@
 	wbsd_write_index(host, WBSD_IDX_SETUP, setup);
 }
 
-static void wbsd_request_end(struct wbsd_host* host, struct mmc_request* mrq)
+static void wbsd_request_end(struct wbsd_host *host, struct mmc_request *mrq)
 {
 	unsigned long dmaflags;
 
 	DBGF("Ending request, cmd (%x)\n", mrq->cmd->opcode);
 
-	if (host->dma >= 0)
-	{
+	if (host->dma >= 0) {
 		/*
 		 * Release ISA DMA controller.
 		 */
@@ -247,7 +246,7 @@
  * Scatter/gather functions
  */
 
-static inline void wbsd_init_sg(struct wbsd_host* host, struct mmc_data* data)
+static inline void wbsd_init_sg(struct wbsd_host *host, struct mmc_data *data)
 {
 	/*
 	 * Get info. about SG list from data structure.
@@ -259,7 +258,7 @@
 	host->remain = host->cur_sg->length;
 }
 
-static inline int wbsd_next_sg(struct wbsd_host* host)
+static inline int wbsd_next_sg(struct wbsd_host *host)
 {
 	/*
 	 * Skip to next SG entry.
@@ -270,33 +269,32 @@
 	/*
 	 * Any entries left?
 	 */
-	if (host->num_sg > 0)
-	  {
-	    host->offset = 0;
-	    host->remain = host->cur_sg->length;
-	  }
+	if (host->num_sg > 0) {
+		host->offset = 0;
+		host->remain = host->cur_sg->length;
+	}
 
 	return host->num_sg;
 }
 
-static inline char* wbsd_kmap_sg(struct wbsd_host* host)
+static inline char *wbsd_kmap_sg(struct wbsd_host *host)
 {
 	host->mapped_sg = kmap_atomic(host->cur_sg->page, KM_BIO_SRC_IRQ) +
 		host->cur_sg->offset;
 	return host->mapped_sg;
 }
 
-static inline void wbsd_kunmap_sg(struct wbsd_host* host)
+static inline void wbsd_kunmap_sg(struct wbsd_host *host)
 {
 	kunmap_atomic(host->mapped_sg, KM_BIO_SRC_IRQ);
 }
 
-static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data)
+static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
 {
 	unsigned int len, i, size;
-	struct scatterlist* sg;
-	char* dmabuf = host->dma_buffer;
-	char* sgbuf;
+	struct scatterlist *sg;
+	char *dmabuf = host->dma_buffer;
+	char *sgbuf;
 
 	size = host->size;
 
@@ -308,8 +306,7 @@
 	 * be the entire list though so make sure that
 	 * we do not transfer too much.
 	 */
-	for (i = 0;i < len;i++)
-	{
+	for (i = 0; i < len; i++) {
 		sgbuf = kmap_atomic(sg[i].page, KM_BIO_SRC_IRQ) + sg[i].offset;
 		if (size < sg[i].length)
 			memcpy(dmabuf, sgbuf, size);
@@ -337,12 +334,12 @@
 	host->size -= size;
 }
 
-static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data)
+static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data)
 {
 	unsigned int len, i, size;
-	struct scatterlist* sg;
-	char* dmabuf = host->dma_buffer;
-	char* sgbuf;
+	struct scatterlist *sg;
+	char *dmabuf = host->dma_buffer;
+	char *sgbuf;
 
 	size = host->size;
 
@@ -354,8 +351,7 @@
 	 * be the entire list though so make sure that
 	 * we do not transfer too much.
 	 */
-	for (i = 0;i < len;i++)
-	{
+	for (i = 0; i < len; i++) {
 		sgbuf = kmap_atomic(sg[i].page, KM_BIO_SRC_IRQ) + sg[i].offset;
 		if (size < sg[i].length)
 			memcpy(sgbuf, dmabuf, size);
@@ -387,46 +383,38 @@
  * Command handling
  */
 
-static inline void wbsd_get_short_reply(struct wbsd_host* host,
-	struct mmc_command* cmd)
+static inline void wbsd_get_short_reply(struct wbsd_host *host,
+					struct mmc_command *cmd)
 {
 	/*
 	 * Correct response type?
 	 */
-	if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_SHORT)
-	{
+	if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_SHORT) {
 		cmd->error = MMC_ERR_INVALID;
 		return;
 	}
 
-	cmd->resp[0] =
-		wbsd_read_index(host, WBSD_IDX_RESP12) << 24;
-	cmd->resp[0] |=
-		wbsd_read_index(host, WBSD_IDX_RESP13) << 16;
-	cmd->resp[0] |=
-		wbsd_read_index(host, WBSD_IDX_RESP14) << 8;
-	cmd->resp[0] |=
-		wbsd_read_index(host, WBSD_IDX_RESP15) << 0;
-	cmd->resp[1] =
-		wbsd_read_index(host, WBSD_IDX_RESP16) << 24;
+	cmd->resp[0]  = wbsd_read_index(host, WBSD_IDX_RESP12) << 24;
+	cmd->resp[0] |= wbsd_read_index(host, WBSD_IDX_RESP13) << 16;
+	cmd->resp[0] |= wbsd_read_index(host, WBSD_IDX_RESP14) << 8;
+	cmd->resp[0] |= wbsd_read_index(host, WBSD_IDX_RESP15) << 0;
+	cmd->resp[1]  = wbsd_read_index(host, WBSD_IDX_RESP16) << 24;
 }
 
-static inline void wbsd_get_long_reply(struct wbsd_host* host,
-	struct mmc_command* cmd)
+static inline void wbsd_get_long_reply(struct wbsd_host *host,
+	struct mmc_command *cmd)
 {
 	int i;
 
 	/*
 	 * Correct response type?
 	 */
-	if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_LONG)
-	{
+	if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_LONG) {
 		cmd->error = MMC_ERR_INVALID;
 		return;
 	}
 
-	for (i = 0;i < 4;i++)
-	{
+	for (i = 0; i < 4; i++) {
 		cmd->resp[i] =
 			wbsd_read_index(host, WBSD_IDX_RESP1 + i * 4) << 24;
 		cmd->resp[i] |=
@@ -438,7 +426,7 @@
 	}
 }
 
-static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
+static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd)
 {
 	int i;
 	u8 status, isr;
@@ -456,7 +444,7 @@
 	 * Send the command (CRC calculated by host).
 	 */
 	outb(cmd->opcode, host->base + WBSD_CMDR);
-	for (i = 3;i >= 0;i--)
+	for (i = 3; i >= 0; i--)
 		outb((cmd->arg >> (i * 8)) & 0xff, host->base + WBSD_CMDR);
 
 	cmd->error = MMC_ERR_NONE;
@@ -471,8 +459,7 @@
 	/*
 	 * Do we expect a reply?
 	 */
-	if ((cmd->flags & MMC_RSP_MASK) != MMC_RSP_NONE)
-	{
+	if ((cmd->flags & MMC_RSP_MASK) != MMC_RSP_NONE) {
 		/*
 		 * Read back status.
 		 */
@@ -488,8 +475,7 @@
 		else if ((cmd->flags & MMC_RSP_CRC) && (isr & WBSD_INT_CRC))
 			cmd->error = MMC_ERR_BADCRC;
 		/* All ok */
-		else
-		{
+		else {
 			if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT)
 				wbsd_get_short_reply(host, cmd);
 			else
@@ -504,10 +490,10 @@
  * Data functions
  */
 
-static void wbsd_empty_fifo(struct wbsd_host* host)
+static void wbsd_empty_fifo(struct wbsd_host *host)
 {
-	struct mmc_data* data = host->mrq->cmd->data;
-	char* buffer;
+	struct mmc_data *data = host->mrq->cmd->data;
+	char *buffer;
 	int i, fsr, fifo;
 
 	/*
@@ -522,8 +508,7 @@
 	 * Drain the fifo. This has a tendency to loop longer
 	 * than the FIFO length (usually one block).
 	 */
-	while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_EMPTY))
-	{
+	while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_EMPTY)) {
 		/*
 		 * The size field in the FSR is broken so we have to
 		 * do some guessing.
@@ -535,8 +520,7 @@
 		else
 			fifo = 1;
 
-		for (i = 0;i < fifo;i++)
-		{
+		for (i = 0; i < fifo; i++) {
 			*buffer = inb(host->base + WBSD_DFR);
 			buffer++;
 			host->offset++;
@@ -547,8 +531,7 @@
 			/*
 			 * Transfer done?
 			 */
-			if (data->bytes_xfered == host->size)
-			{
+			if (data->bytes_xfered == host->size) {
 				wbsd_kunmap_sg(host);
 				return;
 			}
@@ -556,15 +539,13 @@
 			/*
 			 * End of scatter list entry?
 			 */
-			if (host->remain == 0)
-			{
+			if (host->remain == 0) {
 				wbsd_kunmap_sg(host);
 
 				/*
 				 * Get next entry. Check if last.
 				 */
-				if (!wbsd_next_sg(host))
-				{
+				if (!wbsd_next_sg(host)) {
 					/*
 					 * We should never reach this point.
 					 * It means that we're trying to
@@ -594,10 +575,10 @@
 		tasklet_schedule(&host->fifo_tasklet);
 }
 
-static void wbsd_fill_fifo(struct wbsd_host* host)
+static void wbsd_fill_fifo(struct wbsd_host *host)
 {
-	struct mmc_data* data = host->mrq->cmd->data;
-	char* buffer;
+	struct mmc_data *data = host->mrq->cmd->data;
+	char *buffer;
 	int i, fsr, fifo;
 
 	/*
@@ -613,8 +594,7 @@
 	 * Fill the fifo. This has a tendency to loop longer
 	 * than the FIFO length (usually one block).
 	 */
-	while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_FULL))
-	{
+	while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_FULL)) {
 		/*
 		 * The size field in the FSR is broken so we have to
 		 * do some guessing.
@@ -626,8 +606,7 @@
 		else
 			fifo = 15;
 
-		for (i = 16;i > fifo;i--)
-		{
+		for (i = 16; i > fifo; i--) {
 			outb(*buffer, host->base + WBSD_DFR);
 			buffer++;
 			host->offset++;
@@ -638,8 +617,7 @@
 			/*
 			 * Transfer done?
 			 */
-			if (data->bytes_xfered == host->size)
-			{
+			if (data->bytes_xfered == host->size) {
 				wbsd_kunmap_sg(host);
 				return;
 			}
@@ -647,15 +625,13 @@
 			/*
 			 * End of scatter list entry?
 			 */
-			if (host->remain == 0)
-			{
+			if (host->remain == 0) {
 				wbsd_kunmap_sg(host);
 
 				/*
 				 * Get next entry. Check if last.
 				 */
-				if (!wbsd_next_sg(host))
-				{
+				if (!wbsd_next_sg(host)) {
 					/*
 					 * We should never reach this point.
 					 * It means that we're trying to
@@ -684,7 +660,7 @@
 	tasklet_schedule(&host->fifo_tasklet);
 }
 
-static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
+static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data)
 {
 	u16 blksize;
 	u8 setup;
@@ -706,8 +682,10 @@
 	 */
 	if (data->timeout_ns > 127000000)
 		wbsd_write_index(host, WBSD_IDX_TAAC, 127);
-	else
-		wbsd_write_index(host, WBSD_IDX_TAAC, data->timeout_ns/1000000);
+	else {
+		wbsd_write_index(host, WBSD_IDX_TAAC,
+			data->timeout_ns / 1000000);
+	}
 
 	if (data->timeout_clks > 255)
 		wbsd_write_index(host, WBSD_IDX_NSAC, 255);
@@ -722,23 +700,18 @@
 	 * Space for CRC must be included in the size.
 	 * Two bytes are needed for each data line.
 	 */
-	if (host->bus_width == MMC_BUS_WIDTH_1)
-	{
+	if (host->bus_width == MMC_BUS_WIDTH_1) {
 		blksize = (1 << data->blksz_bits) + 2;
 
 		wbsd_write_index(host, WBSD_IDX_PBSMSB, (blksize >> 4) & 0xF0);
 		wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF);
-	}
-	else if (host->bus_width == MMC_BUS_WIDTH_4)
-	{
+	} else if (host->bus_width == MMC_BUS_WIDTH_4) {
 		blksize = (1 << data->blksz_bits) + 2 * 4;
 
-		wbsd_write_index(host, WBSD_IDX_PBSMSB, ((blksize >> 4) & 0xF0)
-			| WBSD_DATA_WIDTH);
+		wbsd_write_index(host, WBSD_IDX_PBSMSB,
+			((blksize >> 4) & 0xF0) | WBSD_DATA_WIDTH);
 		wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF);
-	}
-	else
-	{
+	} else {
 		data->error = MMC_ERR_INVALID;
 		return;
 	}
@@ -755,14 +728,12 @@
 	/*
 	 * DMA transfer?
 	 */
-	if (host->dma >= 0)
-	{
+	if (host->dma >= 0) {
 		/*
 		 * The buffer for DMA is only 64 kB.
 		 */
 		BUG_ON(host->size > 0x10000);
-		if (host->size > 0x10000)
-		{
+		if (host->size > 0x10000) {
 			data->error = MMC_ERR_INVALID;
 			return;
 		}
@@ -794,9 +765,7 @@
 		 * Enable DMA on the host.
 		 */
 		wbsd_write_index(host, WBSD_IDX_DMA, WBSD_DMA_ENABLE);
-	}
-	else
-	{
+	} else {
 		/*
 		 * This flag is used to keep printk
 		 * output to a minimum.
@@ -817,13 +786,10 @@
 		 * Set up FIFO threshold levels (and fill
 		 * buffer if doing a write).
 		 */
-		if (data->flags & MMC_DATA_READ)
-		{
+		if (data->flags & MMC_DATA_READ) {
 			wbsd_write_index(host, WBSD_IDX_FIFOEN,
 				WBSD_FIFOEN_FULL | 8);
-		}
-		else
-		{
+		} else {
 			wbsd_write_index(host, WBSD_IDX_FIFOEN,
 				WBSD_FIFOEN_EMPTY | 8);
 			wbsd_fill_fifo(host);
@@ -833,7 +799,7 @@
 	data->error = MMC_ERR_NONE;
 }
 
-static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
+static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data)
 {
 	unsigned long dmaflags;
 	int count;
@@ -851,16 +817,14 @@
 	 * Wait for the controller to leave data
 	 * transfer state.
 	 */
-	do
-	{
+	do {
 		status = wbsd_read_index(host, WBSD_IDX_STATUS);
 	} while (status & (WBSD_BLOCK_READ | WBSD_BLOCK_WRITE));
 
 	/*
 	 * DMA transfer?
 	 */
-	if (host->dma >= 0)
-	{
+	if (host->dma >= 0) {
 		/*
 		 * Disable DMA on the host.
 		 */
@@ -878,16 +842,13 @@
 		/*
 		 * Any leftover data?
 		 */
-		if (count)
-		{
+		if (count) {
 			printk(KERN_ERR "%s: Incomplete DMA transfer. "
 				"%d bytes left.\n",
 				mmc_hostname(host->mmc), count);
 
 			data->error = MMC_ERR_FAILED;
-		}
-		else
-		{
+		} else {
 			/*
 			 * Transfer data from DMA buffer to
 			 * SG list.
@@ -910,10 +871,10 @@
  *                                                                           *
 \*****************************************************************************/
 
-static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
+static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
-	struct wbsd_host* host = mmc_priv(mmc);
-	struct mmc_command* cmd;
+	struct wbsd_host *host = mmc_priv(mmc);
+	struct mmc_command *cmd;
 
 	/*
 	 * Disable tasklets to avoid a deadlock.
@@ -930,8 +891,7 @@
 	 * If there is no card in the slot then
 	 * timeout immediatly.
 	 */
-	if (!(host->flags & WBSD_FCARD_PRESENT))
-	{
+	if (!(host->flags & WBSD_FCARD_PRESENT)) {
 		cmd->error = MMC_ERR_TIMEOUT;
 		goto done;
 	}
@@ -939,8 +899,7 @@
 	/*
 	 * Does the request include data?
 	 */
-	if (cmd->data)
-	{
+	if (cmd->data) {
 		wbsd_prepare_data(host, cmd->data);
 
 		if (cmd->data->error != MMC_ERR_NONE)
@@ -954,8 +913,7 @@
 	 * will be finished after the data has
 	 * transfered.
 	 */
-	if (cmd->data && (cmd->error == MMC_ERR_NONE))
-	{
+	if (cmd->data && (cmd->error == MMC_ERR_NONE)) {
 		/*
 		 * Dirty fix for hardware bug.
 		 */
@@ -973,14 +931,14 @@
 	spin_unlock_bh(&host->lock);
 }
 
-static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
+static void wbsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
-	struct wbsd_host* host = mmc_priv(mmc);
+	struct wbsd_host *host = mmc_priv(mmc);
 	u8 clk, setup, pwr;
 
 	DBGF("clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n",
-	     ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select,
-	     ios->vdd, ios->bus_width);
+		ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select,
+		ios->vdd, ios->bus_width);
 
 	spin_lock_bh(&host->lock);
 
@@ -1004,8 +962,7 @@
 	 * Only write to the clock register when
 	 * there is an actual change.
 	 */
-	if (clk != host->clk)
-	{
+	if (clk != host->clk) {
 		wbsd_write_index(host, WBSD_IDX_CLK, clk);
 		host->clk = clk;
 	}
@@ -1013,8 +970,7 @@
 	/*
 	 * Power up card.
 	 */
-	if (ios->power_mode != MMC_POWER_OFF)
-	{
+	if (ios->power_mode != MMC_POWER_OFF) {
 		pwr = inb(host->base + WBSD_CSR);
 		pwr &= ~WBSD_POWER_N;
 		outb(pwr, host->base + WBSD_CSR);
@@ -1026,23 +982,19 @@
 	 * that needs to be disabled.
 	 */
 	setup = wbsd_read_index(host, WBSD_IDX_SETUP);
-	if (ios->chip_select == MMC_CS_HIGH)
-	{
+	if (ios->chip_select == MMC_CS_HIGH) {
 		BUG_ON(ios->bus_width != MMC_BUS_WIDTH_1);
 		setup |= WBSD_DAT3_H;
 		host->flags |= WBSD_FIGNORE_DETECT;
-	}
-	else
-	{
-		if (setup & WBSD_DAT3_H)
-		{
+	} else {
+		if (setup & WBSD_DAT3_H) {
 			setup &= ~WBSD_DAT3_H;
 
 			/*
 			 * We cannot resume card detection immediatly
 			 * because of capacitance and delays in the chip.
 			 */
-			mod_timer(&host->ignore_timer, jiffies + HZ/100);
+			mod_timer(&host->ignore_timer, jiffies + HZ / 100);
 		}
 	}
 	wbsd_write_index(host, WBSD_IDX_SETUP, setup);
@@ -1056,9 +1008,9 @@
 	spin_unlock_bh(&host->lock);
 }
 
-static int wbsd_get_ro(struct mmc_host* mmc)
+static int wbsd_get_ro(struct mmc_host *mmc)
 {
-	struct wbsd_host* host = mmc_priv(mmc);
+	struct wbsd_host *host = mmc_priv(mmc);
 	u8 csr;
 
 	spin_lock_bh(&host->lock);
@@ -1096,7 +1048,7 @@
 
 static void wbsd_reset_ignore(unsigned long data)
 {
-	struct wbsd_host *host = (struct wbsd_host*)data;
+	struct wbsd_host *host = (struct wbsd_host *)data;
 
 	BUG_ON(host == NULL);
 
@@ -1119,7 +1071,7 @@
  * Tasklets
  */
 
-static inline struct mmc_data* wbsd_get_data(struct wbsd_host* host)
+static inline struct mmc_data *wbsd_get_data(struct wbsd_host *host)
 {
 	WARN_ON(!host->mrq);
 	if (!host->mrq)
@@ -1138,14 +1090,13 @@
 
 static void wbsd_tasklet_card(unsigned long param)
 {
-	struct wbsd_host* host = (struct wbsd_host*)param;
+	struct wbsd_host *host = (struct wbsd_host *)param;
 	u8 csr;
 	int delay = -1;
 
 	spin_lock(&host->lock);
 
-	if (host->flags & WBSD_FIGNORE_DETECT)
-	{
+	if (host->flags & WBSD_FIGNORE_DETECT) {
 		spin_unlock(&host->lock);
 		return;
 	}
@@ -1153,23 +1104,18 @@
 	csr = inb(host->base + WBSD_CSR);
 	WARN_ON(csr == 0xff);
 
-	if (csr & WBSD_CARDPRESENT)
-	{
-		if (!(host->flags & WBSD_FCARD_PRESENT))
-		{
+	if (csr & WBSD_CARDPRESENT) {
+		if (!(host->flags & WBSD_FCARD_PRESENT)) {
 			DBG("Card inserted\n");
 			host->flags |= WBSD_FCARD_PRESENT;
 
 			delay = 500;
 		}
-	}
-	else if (host->flags & WBSD_FCARD_PRESENT)
-	{
+	} else if (host->flags & WBSD_FCARD_PRESENT) {
 		DBG("Card removed\n");
 		host->flags &= ~WBSD_FCARD_PRESENT;
 
-		if (host->mrq)
-		{
+		if (host->mrq) {
 			printk(KERN_ERR "%s: Card removed during transfer!\n",
 				mmc_hostname(host->mmc));
 			wbsd_reset(host);
@@ -1193,8 +1139,8 @@
 
 static void wbsd_tasklet_fifo(unsigned long param)
 {
-	struct wbsd_host* host = (struct wbsd_host*)param;
-	struct mmc_data* data;
+	struct wbsd_host *host = (struct wbsd_host *)param;
+	struct mmc_data *data;
 
 	spin_lock(&host->lock);
 
@@ -1213,8 +1159,7 @@
 	/*
 	 * Done?
 	 */
-	if (host->size == data->bytes_xfered)
-	{
+	if (host->size == data->bytes_xfered) {
 		wbsd_write_index(host, WBSD_IDX_FIFOEN, 0);
 		tasklet_schedule(&host->finish_tasklet);
 	}
@@ -1225,8 +1170,8 @@
 
 static void wbsd_tasklet_crc(unsigned long param)
 {
-	struct wbsd_host* host = (struct wbsd_host*)param;
-	struct mmc_data* data;
+	struct wbsd_host *host = (struct wbsd_host *)param;
+	struct mmc_data *data;
 
 	spin_lock(&host->lock);
 
@@ -1249,8 +1194,8 @@
 
 static void wbsd_tasklet_timeout(unsigned long param)
 {
-	struct wbsd_host* host = (struct wbsd_host*)param;
-	struct mmc_data* data;
+	struct wbsd_host *host = (struct wbsd_host *)param;
+	struct mmc_data *data;
 
 	spin_lock(&host->lock);
 
@@ -1273,8 +1218,8 @@
 
 static void wbsd_tasklet_finish(unsigned long param)
 {
-	struct wbsd_host* host = (struct wbsd_host*)param;
-	struct mmc_data* data;
+	struct wbsd_host *host = (struct wbsd_host *)param;
+	struct mmc_data *data;
 
 	spin_lock(&host->lock);
 
@@ -1294,14 +1239,13 @@
 
 static void wbsd_tasklet_block(unsigned long param)
 {
-	struct wbsd_host* host = (struct wbsd_host*)param;
-	struct mmc_data* data;
+	struct wbsd_host *host = (struct wbsd_host *)param;
+	struct mmc_data *data;
 
 	spin_lock(&host->lock);
 
 	if ((wbsd_read_index(host, WBSD_IDX_CRCSTATUS) & WBSD_CRC_MASK) !=
-		WBSD_CRC_OK)
-	{
+		WBSD_CRC_OK) {
 		data = wbsd_get_data(host);
 		if (!data)
 			goto end;
@@ -1323,7 +1267,7 @@
 
 static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs)
 {
-	struct wbsd_host* host = dev_id;
+	struct wbsd_host *host = dev_id;
 	int isr;
 
 	isr = inb(host->base + WBSD_ISR);
@@ -1365,10 +1309,10 @@
  * Allocate/free MMC structure.
  */
 
-static int __devinit wbsd_alloc_mmc(struct device* dev)
+static int __devinit wbsd_alloc_mmc(struct device *dev)
 {
-	struct mmc_host* mmc;
-	struct wbsd_host* host;
+	struct mmc_host *mmc;
+	struct wbsd_host *host;
 
 	/*
 	 * Allocate MMC structure.
@@ -1388,7 +1332,7 @@
 	mmc->ops = &wbsd_ops;
 	mmc->f_min = 375000;
 	mmc->f_max = 24000000;
-	mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
+	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
 	mmc->caps = MMC_CAP_4_BIT_DATA;
 
 	spin_lock_init(&host->lock);
@@ -1424,10 +1368,10 @@
 	return 0;
 }
 
-static void __devexit wbsd_free_mmc(struct device* dev)
+static void __devexit wbsd_free_mmc(struct device *dev)
 {
-	struct mmc_host* mmc;
-	struct wbsd_host* host;
+	struct mmc_host *mmc;
+	struct wbsd_host *host;
 
 	mmc = dev_get_drvdata(dev);
 	if (!mmc)
@@ -1447,7 +1391,7 @@
  * Scan for known chip id:s
  */
 
-static int __devinit wbsd_scan(struct wbsd_host* host)
+static int __devinit wbsd_scan(struct wbsd_host *host)
 {
 	int i, j, k;
 	int id;
@@ -1477,16 +1421,14 @@
 			wbsd_lock_config(host);
 
 			for (k = 0; k < ARRAY_SIZE(valid_ids); k++) {
-				if (id == valid_ids[k])
-				{
+				if (id == valid_ids[k]) {
 					host->chip_id = id;
 
 					return 0;
 				}
 			}
 
-			if (id != 0xFFFF)
-			{
+			if (id != 0xFFFF) {
 				DBG("Unknown hardware (id %x) found at %x\n",
 					id, config_ports[i]);
 			}
@@ -1505,7 +1447,7 @@
  * Allocate/free io port ranges
  */
 
-static int __devinit wbsd_request_region(struct wbsd_host* host, int base)
+static int __devinit wbsd_request_region(struct wbsd_host *host, int base)
 {
 	if (io & 0x7)
 		return -EINVAL;
@@ -1518,7 +1460,7 @@
 	return 0;
 }
 
-static void __devexit wbsd_release_regions(struct wbsd_host* host)
+static void __devexit wbsd_release_regions(struct wbsd_host *host)
 {
 	if (host->base)
 		release_region(host->base, 8);
@@ -1535,7 +1477,7 @@
  * Allocate/free DMA port and buffer
  */
 
-static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma)
+static void __devinit wbsd_request_dma(struct wbsd_host *host, int dma)
 {
 	if (dma < 0)
 		return;
@@ -1579,8 +1521,8 @@
 	 */
 	BUG_ON(1);
 
-	dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE,
-		DMA_BIDIRECTIONAL);
+	dma_unmap_single(host->mmc->dev, host->dma_addr,
+		WBSD_DMA_SIZE, DMA_BIDIRECTIONAL);
 	host->dma_addr = (dma_addr_t)NULL;
 
 	kfree(host->dma_buffer);
@@ -1594,11 +1536,12 @@
 		"Falling back on FIFO.\n", dma);
 }
 
-static void __devexit wbsd_release_dma(struct wbsd_host* host)
+static void __devexit wbsd_release_dma(struct wbsd_host *host)
 {
-	if (host->dma_addr)
-		dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE,
-			DMA_BIDIRECTIONAL);
+	if (host->dma_addr) {
+		dma_unmap_single(host->mmc->dev, host->dma_addr,
+			WBSD_DMA_SIZE, DMA_BIDIRECTIONAL);
+	}
 	kfree(host->dma_buffer);
 	if (host->dma >= 0)
 		free_dma(host->dma);
@@ -1612,7 +1555,7 @@
  * Allocate/free IRQ.
  */
 
-static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq)
+static int __devinit wbsd_request_irq(struct wbsd_host *host, int irq)
 {
 	int ret;
 
@@ -1629,17 +1572,23 @@
 	/*
 	 * Set up tasklets.
 	 */
-	tasklet_init(&host->card_tasklet, wbsd_tasklet_card, (unsigned long)host);
-	tasklet_init(&host->fifo_tasklet, wbsd_tasklet_fifo, (unsigned long)host);
-	tasklet_init(&host->crc_tasklet, wbsd_tasklet_crc, (unsigned long)host);
-	tasklet_init(&host->timeout_tasklet, wbsd_tasklet_timeout, (unsigned long)host);
-	tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, (unsigned long)host);
-	tasklet_init(&host->block_tasklet, wbsd_tasklet_block, (unsigned long)host);
+	tasklet_init(&host->card_tasklet, wbsd_tasklet_card,
+			(unsigned long)host);
+	tasklet_init(&host->fifo_tasklet, wbsd_tasklet_fifo,
+			(unsigned long)host);
+	tasklet_init(&host->crc_tasklet, wbsd_tasklet_crc,
+			(unsigned long)host);
+	tasklet_init(&host->timeout_tasklet, wbsd_tasklet_timeout,
+			(unsigned long)host);
+	tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish,
+			(unsigned long)host);
+	tasklet_init(&host->block_tasklet, wbsd_tasklet_block,
+			(unsigned long)host);
 
 	return 0;
 }
 
-static void __devexit wbsd_release_irq(struct wbsd_host* host)
+static void __devexit wbsd_release_irq(struct wbsd_host *host)
 {
 	if (!host->irq)
 		return;
@@ -1660,7 +1609,7 @@
  * Allocate all resources for the host.
  */
 
-static int __devinit wbsd_request_resources(struct wbsd_host* host,
+static int __devinit wbsd_request_resources(struct wbsd_host *host,
 	int base, int irq, int dma)
 {
 	int ret;
@@ -1691,7 +1640,7 @@
  * Release all resources for the host.
  */
 
-static void __devexit wbsd_release_resources(struct wbsd_host* host)
+static void __devexit wbsd_release_resources(struct wbsd_host *host)
 {
 	wbsd_release_dma(host);
 	wbsd_release_irq(host);
@@ -1702,7 +1651,7 @@
  * Configure the resources the chip should use.
  */
 
-static void wbsd_chip_config(struct wbsd_host* host)
+static void wbsd_chip_config(struct wbsd_host *host)
 {
 	wbsd_unlock_config(host);
 
@@ -1746,7 +1695,7 @@
  * Check that configured resources are correct.
  */
 
-static int wbsd_chip_validate(struct wbsd_host* host)
+static int wbsd_chip_validate(struct wbsd_host *host)
 {
 	int base, irq, dma;
 
@@ -1786,7 +1735,7 @@
  * Powers down the SD function
  */
 
-static void wbsd_chip_poweroff(struct wbsd_host* host)
+static void wbsd_chip_poweroff(struct wbsd_host *host)
 {
 	wbsd_unlock_config(host);
 
@@ -1802,11 +1751,11 @@
  *                                                                           *
 \*****************************************************************************/
 
-static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
+static int __devinit wbsd_init(struct device *dev, int base, int irq, int dma,
 	int pnp)
 {
-	struct wbsd_host* host = NULL;
-	struct mmc_host* mmc = NULL;
+	struct wbsd_host *host = NULL;
+	struct mmc_host *mmc = NULL;
 	int ret;
 
 	ret = wbsd_alloc_mmc(dev);
@@ -1820,16 +1769,12 @@
 	 * Scan for hardware.
 	 */
 	ret = wbsd_scan(host);
-	if (ret)
-	{
-		if (pnp && (ret == -ENODEV))
-		{
+	if (ret) {
+		if (pnp && (ret == -ENODEV)) {
 			printk(KERN_WARNING DRIVER_NAME
 				": Unable to confirm device presence. You may "
 				"experience lock-ups.\n");
-		}
-		else
-		{
+		} else {
 			wbsd_free_mmc(dev);
 			return ret;
 		}
@@ -1839,8 +1784,7 @@
 	 * Request resources.
 	 */
 	ret = wbsd_request_resources(host, io, irq, dma);
-	if (ret)
-	{
+	if (ret) {
 		wbsd_release_resources(host);
 		wbsd_free_mmc(dev);
 		return ret;
@@ -1849,18 +1793,15 @@
 	/*
 	 * See if chip needs to be configured.
 	 */
-	if (pnp)
-	{
-		if ((host->config != 0) && !wbsd_chip_validate(host))
-		{
+	if (pnp) {
+		if ((host->config != 0) && !wbsd_chip_validate(host)) {
 			printk(KERN_WARNING DRIVER_NAME
 				": PnP active but chip not configured! "
 				"You probably have a buggy BIOS. "
 				"Configuring chip manually.\n");
 			wbsd_chip_config(host);
 		}
-	}
-	else
+	} else
 		wbsd_chip_config(host);
 
 	/*
@@ -1868,8 +1809,7 @@
 	 * Not tested.
 	 */
 #ifdef CONFIG_PM
-	if (host->config)
-	{
+	if (host->config) {
 		wbsd_unlock_config(host);
 		wbsd_write_config(host, WBSD_CONF_PME, 0xA0);
 		wbsd_lock_config(host);
@@ -1902,10 +1842,10 @@
 	return 0;
 }
 
-static void __devexit wbsd_shutdown(struct device* dev, int pnp)
+static void __devexit wbsd_shutdown(struct device *dev, int pnp)
 {
-	struct mmc_host* mmc = dev_get_drvdata(dev);
-	struct wbsd_host* host;
+	struct mmc_host *mmc = dev_get_drvdata(dev);
+	struct wbsd_host *host;
 
 	if (!mmc)
 		return;
@@ -1929,12 +1869,12 @@
  * Non-PnP
  */
 
-static int __devinit wbsd_probe(struct platform_device* dev)
+static int __devinit wbsd_probe(struct platform_device *dev)
 {
 	return wbsd_init(&dev->dev, io, irq, dma, 0);
 }
 
-static int __devexit wbsd_remove(struct platform_device* dev)
+static int __devexit wbsd_remove(struct platform_device *dev)
 {
 	wbsd_shutdown(&dev->dev, 0);
 
@@ -1948,7 +1888,7 @@
 #ifdef CONFIG_PNP
 
 static int __devinit
-wbsd_pnp_probe(struct pnp_dev * pnpdev, const struct pnp_device_id *dev_id)
+wbsd_pnp_probe(struct pnp_dev *pnpdev, const struct pnp_device_id *dev_id)
 {
 	int io, irq, dma;
 
@@ -1967,7 +1907,7 @@
 	return wbsd_init(&pnpdev->dev, io, irq, dma, 1);
 }
 
-static void __devexit wbsd_pnp_remove(struct pnp_dev * dev)
+static void __devexit wbsd_pnp_remove(struct pnp_dev *dev)
 {
 	wbsd_shutdown(&dev->dev, 1);
 }
@@ -1980,37 +1920,54 @@
 
 #ifdef CONFIG_PM
 
-static int wbsd_suspend(struct platform_device *dev, pm_message_t state)
+static int wbsd_suspend(struct wbsd_host *host, pm_message_t state)
+{
+	BUG_ON(host == NULL);
+
+	return mmc_suspend_host(host->mmc, state);
+}
+
+static int wbsd_resume(struct wbsd_host *host)
+{
+	BUG_ON(host == NULL);
+
+	wbsd_init_device(host);
+
+	return mmc_resume_host(host->mmc);
+}
+
+static int wbsd_platform_suspend(struct platform_device *dev,
+				 pm_message_t state)
 {
 	struct mmc_host *mmc = platform_get_drvdata(dev);
 	struct wbsd_host *host;
 	int ret;
 
-	if (!mmc)
+	if (mmc == NULL)
 		return 0;
 
-	DBG("Suspending...\n");
-
-	ret = mmc_suspend_host(mmc, state);
-	if (!ret)
-		return ret;
+	DBGF("Suspending...\n");
 
 	host = mmc_priv(mmc);
 
+	ret = wbsd_suspend(host, state);
+	if (ret)
+		return ret;
+
 	wbsd_chip_poweroff(host);
 
 	return 0;
 }
 
-static int wbsd_resume(struct platform_device *dev)
+static int wbsd_platform_resume(struct platform_device *dev)
 {
 	struct mmc_host *mmc = platform_get_drvdata(dev);
 	struct wbsd_host *host;
 
-	if (!mmc)
+	if (mmc == NULL)
 		return 0;
 
-	DBG("Resuming...\n");
+	DBGF("Resuming...\n");
 
 	host = mmc_priv(mmc);
 
@@ -2021,15 +1978,68 @@
 	 */
 	mdelay(5);
 
-	wbsd_init_device(host);
-
-	return mmc_resume_host(mmc);
+	return wbsd_resume(host);
 }
 
+#ifdef CONFIG_PNP
+
+static int wbsd_pnp_suspend(struct pnp_dev *pnp_dev, pm_message_t state)
+{
+	struct mmc_host *mmc = dev_get_drvdata(&pnp_dev->dev);
+	struct wbsd_host *host;
+
+	if (mmc == NULL)
+		return 0;
+
+	DBGF("Suspending...\n");
+
+	host = mmc_priv(mmc);
+
+	return wbsd_suspend(host, state);
+}
+
+static int wbsd_pnp_resume(struct pnp_dev *pnp_dev)
+{
+	struct mmc_host *mmc = dev_get_drvdata(&pnp_dev->dev);
+	struct wbsd_host *host;
+
+	if (mmc == NULL)
+		return 0;
+
+	DBGF("Resuming...\n");
+
+	host = mmc_priv(mmc);
+
+	/*
+	 * See if chip needs to be configured.
+	 */
+	if (host->config != 0) {
+		if (!wbsd_chip_validate(host)) {
+			printk(KERN_WARNING DRIVER_NAME
+				": PnP active but chip not configured! "
+				"You probably have a buggy BIOS. "
+				"Configuring chip manually.\n");
+			wbsd_chip_config(host);
+		}
+	}
+
+	/*
+	 * Allow device to initialise itself properly.
+	 */
+	mdelay(5);
+
+	return wbsd_resume(host);
+}
+
+#endif /* CONFIG_PNP */
+
 #else /* CONFIG_PM */
 
-#define wbsd_suspend NULL
-#define wbsd_resume NULL
+#define wbsd_platform_suspend NULL
+#define wbsd_platform_resume NULL
+
+#define wbsd_pnp_suspend NULL
+#define wbsd_pnp_resume NULL
 
 #endif /* CONFIG_PM */
 
@@ -2039,8 +2049,8 @@
 	.probe		= wbsd_probe,
 	.remove		= __devexit_p(wbsd_remove),
 
-	.suspend	= wbsd_suspend,
-	.resume		= wbsd_resume,
+	.suspend	= wbsd_platform_suspend,
+	.resume		= wbsd_platform_resume,
 	.driver		= {
 		.name	= DRIVER_NAME,
 	},
@@ -2053,6 +2063,9 @@
 	.id_table	= pnp_dev_table,
 	.probe		= wbsd_pnp_probe,
 	.remove		= __devexit_p(wbsd_pnp_remove),
+
+	.suspend	= wbsd_pnp_suspend,
+	.resume		= wbsd_pnp_resume,
 };
 
 #endif /* CONFIG_PNP */
@@ -2072,31 +2085,26 @@
 
 #ifdef CONFIG_PNP
 
-	if (!nopnp)
-	{
+	if (!nopnp) {
 		result = pnp_register_driver(&wbsd_pnp_driver);
 		if (result < 0)
 			return result;
 	}
-
 #endif /* CONFIG_PNP */
 
-	if (nopnp)
-	{
+	if (nopnp) {
 		result = platform_driver_register(&wbsd_driver);
 		if (result < 0)
 			return result;
 
 		wbsd_device = platform_device_alloc(DRIVER_NAME, -1);
-		if (!wbsd_device)
-		{
+		if (!wbsd_device) {
 			platform_driver_unregister(&wbsd_driver);
 			return -ENOMEM;
 		}
 
 		result = platform_device_add(wbsd_device);
-		if (result)
-		{
+		if (result) {
 			platform_device_put(wbsd_device);
 			platform_driver_unregister(&wbsd_driver);
 			return result;
@@ -2115,8 +2123,7 @@
 
 #endif /* CONFIG_PNP */
 
-	if (nopnp)
-	{
+	if (nopnp) {
 		platform_device_unregister(wbsd_device);
 
 		platform_driver_unregister(&wbsd_driver);
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index b9b77cf..7abd7fe 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -473,14 +473,6 @@
 	  IXDP425 and Coyote. If you have an IXP2000 based board and
 	  would like to use the flash chips on it, say 'Y'.
 
-config MTD_EPXA10DB
-	tristate "CFI Flash device mapped on Epxa10db"
-	depends on MTD_CFI && MTD_PARTITIONS && ARCH_CAMELOT
-	help
-	  This enables support for the flash devices on the Altera
-	  Excalibur XA10 Development Board. If you are building a kernel
-	  for on of these boards then you should say 'Y' otherwise say 'N'.
-
 config MTD_FORTUNET
 	tristate "CFI Flash device mapped on the FortuNet board"
 	depends on MTD_CFI && MTD_PARTITIONS && SA1100_FORTUNET
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 2f7e254..ab71f17 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -15,7 +15,6 @@
 obj-$(CONFIG_MTD_CSTM_MIPS_IXX)	+= cstm_mips_ixx.o
 obj-$(CONFIG_MTD_DC21285)	+= dc21285.o
 obj-$(CONFIG_MTD_DILNETPC)	+= dilnetpc.o
-obj-$(CONFIG_MTD_EPXA10DB)	+= epxa10db-flash.o
 obj-$(CONFIG_MTD_IQ80310)	+= iq80310.o
 obj-$(CONFIG_MTD_L440GX)	+= l440gx.o
 obj-$(CONFIG_MTD_AMD76XROM)	+= amd76xrom.o
diff --git a/drivers/mtd/maps/epxa10db-flash.c b/drivers/mtd/maps/epxa10db-flash.c
deleted file mode 100644
index 265b079..0000000
--- a/drivers/mtd/maps/epxa10db-flash.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Flash memory access on EPXA based devices
- *
- * (C) 2000 Nicolas Pitre <nico@cam.org>
- *  Copyright (C) 2001 Altera Corporation
- *  Copyright (C) 2001 Red Hat, Inc.
- *
- * $Id: epxa10db-flash.c,v 1.15 2005/11/07 11:14:27 gleixner Exp $
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/io.h>
-#include <asm/hardware.h>
-
-#ifdef CONFIG_EPXA10DB
-#define BOARD_NAME "EPXA10DB"
-#else
-#define BOARD_NAME "EPXA1DB"
-#endif
-
-static int nr_parts = 0;
-static struct mtd_partition *parts;
-
-static struct mtd_info *mymtd;
-
-static int epxa_default_partitions(struct mtd_info *master, struct mtd_partition **pparts);
-
-
-static struct map_info epxa_map = {
-	.name =		"EPXA flash",
-	.size =		FLASH_SIZE,
-	.bankwidth =	2,
-	.phys =		FLASH_START,
-};
-
-static const char *probes[] = { "RedBoot", "afs", NULL };
-
-static int __init epxa_mtd_init(void)
-{
-	int i;
-
-	printk(KERN_NOTICE "%s flash device: 0x%x at 0x%x\n", BOARD_NAME, FLASH_SIZE, FLASH_START);
-
-	epxa_map.virt = ioremap(FLASH_START, FLASH_SIZE);
-	if (!epxa_map.virt) {
-		printk("Failed to ioremap %s flash\n",BOARD_NAME);
-		return -EIO;
-	}
-	simple_map_init(&epxa_map);
-
-	mymtd = do_map_probe("cfi_probe", &epxa_map);
-	if (!mymtd) {
-		iounmap((void *)epxa_map.virt);
-		return -ENXIO;
-	}
-
-	mymtd->owner = THIS_MODULE;
-
-	/* Unlock the flash device. */
-	if(mymtd->unlock){
-		for (i=0; i<mymtd->numeraseregions;i++){
-			int j;
-			for(j=0;j<mymtd->eraseregions[i].numblocks;j++){
-				mymtd->unlock(mymtd,mymtd->eraseregions[i].offset + j * mymtd->eraseregions[i].erasesize,mymtd->eraseregions[i].erasesize);
-			}
-		}
-	}
-
-#ifdef CONFIG_MTD_PARTITIONS
-	nr_parts = parse_mtd_partitions(mymtd, probes, &parts, 0);
-
-	if (nr_parts > 0) {
-		add_mtd_partitions(mymtd, parts, nr_parts);
-		return 0;
-	}
-#endif
-	/* No recognised partitioning schemes found - use defaults */
-	nr_parts = epxa_default_partitions(mymtd, &parts);
-	if (nr_parts > 0) {
-		add_mtd_partitions(mymtd, parts, nr_parts);
-		return 0;
-	}
-
-	/* If all else fails... */
-	add_mtd_device(mymtd);
-	return 0;
-}
-
-static void __exit epxa_mtd_cleanup(void)
-{
-	if (mymtd) {
-		if (nr_parts)
-			del_mtd_partitions(mymtd);
-		else
-			del_mtd_device(mymtd);
-		map_destroy(mymtd);
-	}
-	if (epxa_map.virt) {
-		iounmap((void *)epxa_map.virt);
-		epxa_map.virt = 0;
-	}
-}
-
-
-/*
- * This will do for now, once we decide which bootldr we're finally
- * going to use then we'll remove this function and do it properly
- *
- * Partions are currently (as offsets from base of flash):
- * 0x00000000 - 0x003FFFFF - bootloader (!)
- * 0x00400000 - 0x00FFFFFF - Flashdisk
- */
-
-static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_partition **pparts)
-{
-	struct mtd_partition *parts;
-	int ret, i;
-	int npartitions = 0;
-	char *names;
-	const char *name = "jffs";
-
-	printk("Using default partitions for %s\n",BOARD_NAME);
-	npartitions=1;
-	parts = kmalloc(npartitions*sizeof(*parts)+strlen(name), GFP_KERNEL);
-	memzero(parts,npartitions*sizeof(*parts)+strlen(name));
-	if (!parts) {
-		ret = -ENOMEM;
-		goto out;
-	}
-	i=0;
-	names = (char *)&parts[npartitions];
-	parts[i].name = names;
-	names += strlen(name) + 1;
-	strcpy(parts[i].name, name);
-
-#ifdef CONFIG_EPXA10DB
-	parts[i].size = FLASH_SIZE-0x00400000;
-	parts[i].offset = 0x00400000;
-#else
-	parts[i].size = FLASH_SIZE-0x00180000;
-	parts[i].offset = 0x00180000;
-#endif
-
- out:
-	*pparts = parts;
-	return npartitions;
-}
-
-
-module_init(epxa_mtd_init);
-module_exit(epxa_mtd_cleanup);
-
-MODULE_AUTHOR("Clive Davies");
-MODULE_DESCRIPTION("Altera epxa mtd flash map");
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 733bc25..4959800 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -27,6 +27,19 @@
 # that for each of the symbols.
 if NETDEVICES
 
+config IFB
+	tristate "Intermediate Functional Block support"
+	depends on NET_CLS_ACT
+	---help---
+	  This is an intermidiate driver that allows sharing of
+	  resources.
+	  To compile this driver as a module, choose M here: the module
+	  will be called ifb.  If you want to use more than one ifb
+	  device at a time, you need to compile this driver as a module.
+	  Instead of 'ifb', the devices will then be called 'ifb0',
+	  'ifb1' etc.
+	  Look at the iproute2 documentation directory for usage etc
+
 config DUMMY
 	tristate "Dummy net driver support"
 	---help---
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index b74a7cb..00e72b1 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -125,6 +125,7 @@
 endif
 
 obj-$(CONFIG_DUMMY) += dummy.o
+obj-$(CONFIG_IFB) += ifb.o
 obj-$(CONFIG_DE600) += de600.o
 obj-$(CONFIG_DE620) += de620.o
 obj-$(CONFIG_LANCE) += lance.o
diff --git a/drivers/net/arm/Kconfig b/drivers/net/arm/Kconfig
index 470364d..625184b 100644
--- a/drivers/net/arm/Kconfig
+++ b/drivers/net/arm/Kconfig
@@ -31,16 +31,3 @@
 	help
 	  If you have an Acorn system with one of these network cards, you
 	  should say Y to this option if you wish to use it with Linux.
-
-config ARM_ETHER00
-	tristate "Altera Ether00 support"
-	depends on NET_ETHERNET && ARM && ARCH_CAMELOT
-	help
-	  This is the driver for Altera's ether00 ethernet mac IP core. Say
-	  Y here if you want to build support for this into the kernel. It
-	  is also available as a module (say M here) that can be inserted/
-	  removed from the kernel at the same time as the PLD is configured.
-	  If this driver is running on an epxa10 development board then it
-	  will generate a suitable hw address based on the board serial
-	  number (MTD support is required for this). Otherwise you will
-	  need to set a suitable hw address using ifconfig.
diff --git a/drivers/net/arm/Makefile b/drivers/net/arm/Makefile
index b0d7068..bc263ed 100644
--- a/drivers/net/arm/Makefile
+++ b/drivers/net/arm/Makefile
@@ -4,7 +4,6 @@
 #
 
 obj-$(CONFIG_ARM_AM79C961A)	+= am79c961a.o
-obj-$(CONFIG_ARM_ETHER00)	+= ether00.o
 obj-$(CONFIG_ARM_ETHERH)	+= etherh.o
 obj-$(CONFIG_ARM_ETHER3)	+= ether3.o
 obj-$(CONFIG_ARM_ETHER1)	+= ether1.o
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c
index 877891a..53e3afc 100644
--- a/drivers/net/arm/am79c961a.c
+++ b/drivers/net/arm/am79c961a.c
@@ -668,9 +668,8 @@
 		printk(KERN_INFO "%s", version);
 }
 
-static int __init am79c961_probe(struct device *_dev)
+static int __init am79c961_probe(struct platform_device *pdev)
 {
-	struct platform_device *pdev = to_platform_device(_dev);
 	struct resource *res;
 	struct net_device *dev;
 	struct dev_priv *priv;
@@ -758,15 +757,16 @@
 	return ret;
 }
 
-static struct device_driver am79c961_driver = {
-	.name		= "am79c961",
-	.bus		= &platform_bus_type,
+static struct platform_driver am79c961_driver = {
 	.probe		= am79c961_probe,
+	.driver		= {
+		.name	= "am79c961",
+	},
 };
 
 static int __init am79c961_init(void)
 {
-	return driver_register(&am79c961_driver);
+	return platform_driver_register(&am79c961_driver);
 }
 
 __initcall(am79c961_init);
diff --git a/drivers/net/arm/ether00.c b/drivers/net/arm/ether00.c
deleted file mode 100644
index 4f1f4e3..0000000
--- a/drivers/net/arm/ether00.c
+++ /dev/null
@@ -1,1017 +0,0 @@
-/*
- *  drivers/net/ether00.c
- *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/* includes */
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/sched.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <linux/etherdevice.h>
-#include <linux/module.h>
-#include <linux/tqueue.h>
-#include <linux/mtd/mtd.h>
-#include <linux/pld/pld_hotswap.h>
-#include <asm/arch/excalibur.h>
-#include <asm/arch/hardware.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/sizes.h>
-
-#include <asm/arch/ether00.h>
-#include <asm/arch/tdkphy.h>
-
-
-MODULE_AUTHOR("Clive Davies");
-MODULE_DESCRIPTION("Altera Ether00 IP core driver");
-MODULE_LICENSE("GPL");
-
-#define PKT_BUF_SZ 1540 /* Size of each rx buffer */
-#define ETH_NR 4 /* Number of MACs this driver supports */
-
-#define DEBUG(x)
-
-#define __dma_va(x) (unsigned int)((unsigned int)priv->dma_data+(((unsigned int)(x))&(EXC_SPSRAM_BLOCK0_SIZE-1)))
-#define __dma_pa(x) (unsigned int)(EXC_SPSRAM_BLOCK0_BASE+(((unsigned int)(x))-(unsigned int)priv->dma_data))
-
-#define ETHER00_BASE	0
-#define	ETHER00_TYPE
-#define ETHER00_NAME "ether00"
-#define MAC_REG_SIZE 0x400 /* size of MAC register area */
-
-
-
-/* typedefs */
-
-/* The definition of the driver control structure */
-
-#define RX_NUM_BUFF     10
-#define RX_NUM_FDESC    10
-#define TX_NUM_FDESC    10
-
-struct tx_fda_ent{
-	FDA_DESC  fd;
-	BUF_DESC  bd;
-	BUF_DESC  pad;
-};
-struct rx_fda_ent{
-	FDA_DESC  fd;
-	BUF_DESC  bd;
-	BUF_DESC  pad;
-};
-struct rx_blist_ent{
-	FDA_DESC  fd;
-	BUF_DESC  bd;
-	BUF_DESC  pad;
-};
-struct net_priv
-{
-	struct net_device_stats stats;
-	struct sk_buff* skb;
-	void* dma_data;
-	struct rx_blist_ent*  rx_blist_vp;
-	struct rx_fda_ent* rx_fda_ptr;
-	struct tx_fda_ent* tx_fdalist_vp;
-	struct tq_struct  tq_memupdate;
-	unsigned char   memupdate_scheduled;
-	unsigned char   rx_disabled;
-	unsigned char   queue_stopped;
-	spinlock_t rx_lock;
-};
-
-static const char vendor_id[2]={0x07,0xed};
-
-#ifdef ETHER00_DEBUG
-
-/* Dump (most) registers for debugging puposes */
-
-static void dump_regs(struct net_device *dev){
-	struct net_priv* priv=dev->priv;
-	unsigned int* i;
-
-	printk("\n RX free descriptor area:\n");
-
-	for(i=(unsigned int*)priv->rx_fda_ptr;
-	    i<((unsigned int*)(priv->rx_fda_ptr+RX_NUM_FDESC));){
-		printk("%#8x %#8x %#8x %#8x\n",*i,*(i+1),*(i+2),*(i+3));
-		i+=4;
-	}
-
-	printk("\n RX buffer list:\n");
-
-	for(i=(unsigned int*)priv->rx_blist_vp;
-	    i<((unsigned int*)(priv->rx_blist_vp+RX_NUM_BUFF));){
-		printk("%#8x %#8x %#8x %#8x\n",*i,*(i+1),*(i+2),*(i+3));
-		i+=4;
-	}
-
-	printk("\n TX frame descriptor list:\n");
-
-	for(i=(unsigned int*)priv->tx_fdalist_vp;
-	    i<((unsigned int*)(priv->tx_fdalist_vp+TX_NUM_FDESC));){
-		printk("%#8x %#8x %#8x %#8x\n",*i,*(i+1),*(i+2),*(i+3));
-		i+=4;
-	}
-
-	printk("\ndma ctl=%#x\n",readw(ETHER_DMA_CTL(dev->base_addr)));
-	printk("txfrmptr=%#x\n",readw(ETHER_TXFRMPTR(dev->base_addr)));
-	printk("txthrsh=%#x\n",readw(ETHER_TXTHRSH(dev->base_addr)));
-	printk("txpollctr=%#x\n",readw(ETHER_TXPOLLCTR(dev->base_addr)));
-	printk("blfrmptr=%#x\n",readw(ETHER_BLFRMPTR(dev->base_addr)));
-	printk("rxfragsize=%#x\n",readw(ETHER_RXFRAGSIZE(dev->base_addr)));
-	printk("tx_int_en=%#x\n",readw(ETHER_INT_EN(dev->base_addr)));
-	printk("fda_bas=%#x\n",readw(ETHER_FDA_BAS(dev->base_addr)));
-	printk("fda_lim=%#x\n",readw(ETHER_FDA_LIM(dev->base_addr)));
-	printk("int_src=%#x\n",readw(ETHER_INT_SRC(dev->base_addr)));
-	printk("pausecnt=%#x\n",readw(ETHER_PAUSECNT(dev->base_addr)));
-	printk("rempaucnt=%#x\n",readw(ETHER_REMPAUCNT(dev->base_addr)));
-	printk("txconfrmstat=%#x\n",readw(ETHER_TXCONFRMSTAT(dev->base_addr)));
-	printk("mac_ctl=%#x\n",readw(ETHER_MAC_CTL(dev->base_addr)));
-	printk("arc_ctl=%#x\n",readw(ETHER_ARC_CTL(dev->base_addr)));
-	printk("tx_ctl=%#x\n",readw(ETHER_TX_CTL(dev->base_addr)));
-}
-#endif /* ETHER00_DEBUG */
-
-
-static int ether00_write_phy(struct net_device *dev, short address, short value)
-{
-	volatile int count = 1024;
-	writew(value,ETHER_MD_DATA(dev->base_addr));
-	writew( ETHER_MD_CA_BUSY_MSK |
-		ETHER_MD_CA_WR_MSK |
-		(address & ETHER_MD_CA_ADDR_MSK),
-		ETHER_MD_CA(dev->base_addr));
-
-	/* Wait for the command to complete */
-	while((readw(ETHER_MD_CA(dev->base_addr)) & ETHER_MD_CA_BUSY_MSK)&&count){
-		count--;
-	}
-	if (!count){
-		printk("Write to phy failed, addr=%#x, data=%#x\n",address, value);
-		return -EIO;
-	}
-	return 0;
-}
-
-static int ether00_read_phy(struct net_device *dev, short address)
-{
-	volatile int count = 1024;
-	writew( ETHER_MD_CA_BUSY_MSK |
-		(address & ETHER_MD_CA_ADDR_MSK),
-		ETHER_MD_CA(dev->base_addr));
-
-	/* Wait for the command to complete */
-	while((readw(ETHER_MD_CA(dev->base_addr)) & ETHER_MD_CA_BUSY_MSK)&&count){
-		count--;
-	}
-	if (!count){
-		printk(KERN_WARNING "Read from phy timed out\n");
-		return -EIO;
-	}
-	return readw(ETHER_MD_DATA(dev->base_addr));
-}
-
-static void ether00_phy_int(int irq_num, void* dev_id, struct pt_regs* regs)
-{
-	struct net_device* dev=dev_id;
-	int irq_status;
-
-	irq_status=ether00_read_phy(dev, PHY_IRQ_CONTROL);
-
-	if(irq_status & PHY_IRQ_CONTROL_ANEG_COMP_INT_MSK){
-		/*
-		 * Autonegotiation complete on epxa10db. The mac doesn't
-		 * twig if we're in full duplex so we need to check the
-		 * phy status register and configure the mac accordingly
-		 */
-		if(ether00_read_phy(dev, PHY_STATUS)&(PHY_STATUS_10T_F_MSK|PHY_STATUS_100_X_F_MSK)){
-			int tmp;
-			tmp=readl(ETHER_MAC_CTL(dev->base_addr));
-			writel(tmp|ETHER_MAC_CTL_FULLDUP_MSK,ETHER_MAC_CTL(dev->base_addr));
-		}
-	}
-
-	if(irq_status&PHY_IRQ_CONTROL_LS_CHG_INT_MSK){
-
-		if(ether00_read_phy(dev, PHY_STATUS)& PHY_STATUS_LINK_MSK){
-			/* Link is up */
-			netif_carrier_on(dev);
-			//printk("Carrier on\n");
-		}else{
-			netif_carrier_off(dev);
-			//printk("Carrier off\n");
-
-		}
-	}
-
-}
-
-static void setup_blist_entry(struct sk_buff* skb,struct rx_blist_ent* blist_ent_ptr){
-	/* Make the buffer consistent with the cache as the mac is going to write
-	 * directly into it*/
-	blist_ent_ptr->fd.FDSystem=(unsigned int)skb;
-	blist_ent_ptr->bd.BuffData=(char*)__pa(skb->data);
-	consistent_sync(skb->data,PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
-        /* align IP on 16 Byte (DMA_CTL set to skip 2 bytes) */
-	skb_reserve(skb,2);
-	blist_ent_ptr->bd.BuffLength=PKT_BUF_SZ-2;
-	blist_ent_ptr->fd.FDLength=1;
-	blist_ent_ptr->fd.FDCtl=FDCTL_COWNSFD_MSK;
-	blist_ent_ptr->bd.BDCtl=BDCTL_COWNSBD_MSK;
-}
-
-
-static int ether00_mem_init(struct net_device* dev)
-{
-	struct net_priv* priv=dev->priv;
-	struct tx_fda_ent *tx_fd_ptr,*tx_end_ptr;
-	struct rx_blist_ent* blist_ent_ptr;
-	int i;
-
-	/*
-	 * Grab a block of on chip SRAM to contain the control stuctures for
-	 * the ethernet MAC. This uncached becuase it needs to be accesses by both
-	 * bus masters (cpu + mac). However, it shouldn't matter too much in terms
-	 * of speed as its on chip memory
-	 */
-	priv->dma_data=ioremap_nocache(EXC_SPSRAM_BLOCK0_BASE,EXC_SPSRAM_BLOCK0_SIZE );
-	if (!priv->dma_data)
-		return -ENOMEM;
-
-	priv->rx_fda_ptr=(struct rx_fda_ent*)priv->dma_data;
-	/*
-	 * Now share it out amongst the Frame descriptors and the buffer list
-	 */
-	priv->rx_blist_vp=(struct rx_blist_ent*)((unsigned int)priv->dma_data+RX_NUM_FDESC*sizeof(struct rx_fda_ent));
-
-	/*
-	 *Initalise the FDA list
-	 */
-	/* set ownership to the controller */
-	memset(priv->rx_fda_ptr,0x80,RX_NUM_FDESC*sizeof(struct rx_fda_ent));
-
-	/*
-	 *Initialise the buffer list
-	 */
-	blist_ent_ptr=priv->rx_blist_vp;
-	i=0;
-	while(blist_ent_ptr<(priv->rx_blist_vp+RX_NUM_BUFF)){
-		struct sk_buff *skb;
-		blist_ent_ptr->fd.FDLength=1;
-		skb=dev_alloc_skb(PKT_BUF_SZ);
-		if(skb){
-			setup_blist_entry(skb,blist_ent_ptr);
-			blist_ent_ptr->fd.FDNext=(FDA_DESC*)__dma_pa(blist_ent_ptr+1);
-			blist_ent_ptr->bd.BDStat=i++;
-			blist_ent_ptr++;
-		}
-		else
-		{
-			printk("Failed to initalise buffer list\n");
-		}
-
-	}
-	blist_ent_ptr--;
-	blist_ent_ptr->fd.FDNext=(FDA_DESC*)__dma_pa(priv->rx_blist_vp);
-
-	priv->tx_fdalist_vp=(struct tx_fda_ent*)(priv->rx_blist_vp+RX_NUM_BUFF);
-
-	/* Initialise the buffers to be a circular list. The mac will then go poll
-	 * the list until it finds a frame ready to transmit */
-	tx_end_ptr=priv->tx_fdalist_vp+TX_NUM_FDESC;
-	for(tx_fd_ptr=priv->tx_fdalist_vp;tx_fd_ptr<tx_end_ptr;tx_fd_ptr++){
-		tx_fd_ptr->fd.FDNext=(FDA_DESC*)__dma_pa((tx_fd_ptr+1));
-		tx_fd_ptr->fd.FDCtl=1;
-		tx_fd_ptr->fd.FDStat=0;
-		tx_fd_ptr->fd.FDLength=1;
-
-	}
-	/* Change the last FDNext pointer to make a circular list */
-	tx_fd_ptr--;
-	tx_fd_ptr->fd.FDNext=(FDA_DESC*)__dma_pa(priv->tx_fdalist_vp);
-
-	/* Point the device at the chain of Rx and Tx Buffers */
-	writel((unsigned int)__dma_pa(priv->rx_fda_ptr),ETHER_FDA_BAS(dev->base_addr));
-	writel((RX_NUM_FDESC-1)*sizeof(struct rx_fda_ent),ETHER_FDA_LIM(dev->base_addr));
-	writel((unsigned int)__dma_pa(priv->rx_blist_vp),ETHER_BLFRMPTR(dev->base_addr));
-
-	writel((unsigned int)__dma_pa(priv->tx_fdalist_vp),ETHER_TXFRMPTR(dev->base_addr));
-
-	return 0;
-}
-
-
-void ether00_mem_update(void* dev_id)
-{
-	struct net_device* dev=dev_id;
-	struct net_priv* priv=dev->priv;
-	struct sk_buff* skb;
-	struct tx_fda_ent *fda_ptr=priv->tx_fdalist_vp;
-	struct rx_blist_ent* blist_ent_ptr;
-	unsigned long flags;
-
-	priv->tq_memupdate.sync=0;
-	//priv->tq_memupdate.list=
-	priv->memupdate_scheduled=0;
-
-	/* Transmit interrupt */
-	while(fda_ptr<(priv->tx_fdalist_vp+TX_NUM_FDESC)){
-		if(!(FDCTL_COWNSFD_MSK&fda_ptr->fd.FDCtl) && (ETHER_TX_STAT_COMP_MSK&fda_ptr->fd.FDStat)){
-			priv->stats.tx_packets++;
-			priv->stats.tx_bytes+=fda_ptr->bd.BuffLength;
-			skb=(struct sk_buff*)fda_ptr->fd.FDSystem;
-			//printk("%d:txcln:fda=%#x skb=%#x\n",jiffies,fda_ptr,skb);
-			dev_kfree_skb(skb);
-			fda_ptr->fd.FDSystem=0;
-			fda_ptr->fd.FDStat=0;
-			fda_ptr->fd.FDCtl=0;
-		}
-		fda_ptr++;
-	}
-	/* Fill in any missing buffers from the received queue */
-	spin_lock_irqsave(&priv->rx_lock,flags);
-	blist_ent_ptr=priv->rx_blist_vp;
-	while(blist_ent_ptr<(priv->rx_blist_vp+RX_NUM_BUFF)){
-		/* fd.FDSystem of 0 indicates we failed to allocate the buffer in the ISR */
-		if(!blist_ent_ptr->fd.FDSystem){
-			struct sk_buff *skb;
-			skb=dev_alloc_skb(PKT_BUF_SZ);
-			blist_ent_ptr->fd.FDSystem=(unsigned int)skb;
-			if(skb){
-				setup_blist_entry(skb,blist_ent_ptr);
-			}
-			else
-			{
-				break;
-			}
-		}
-		blist_ent_ptr++;
-	}
-	spin_unlock_irqrestore(&priv->rx_lock,flags);
-	if(priv->queue_stopped){
-		//printk("%d:cln:start q\n",jiffies);
-		netif_start_queue(dev);
-	}
-	if(priv->rx_disabled){
-		//printk("%d:enable_irq\n",jiffies);
-		priv->rx_disabled=0;
-		writel(ETHER_RX_CTL_RXEN_MSK,ETHER_RX_CTL(dev->base_addr));
-
-	}
-}
-
-
-static void ether00_int( int irq_num, void* dev_id, struct pt_regs* regs)
-{
-	struct net_device* dev=dev_id;
-	struct net_priv* priv=dev->priv;
-
-	unsigned int   interruptValue;
-
-	interruptValue=readl(ETHER_INT_SRC(dev->base_addr));
-
-	//printk("INT_SRC=%x\n",interruptValue);
-
-	if(!(readl(ETHER_INT_SRC(dev->base_addr)) & ETHER_INT_SRC_IRQ_MSK))
-	{
-		return;		/* Interrupt wasn't caused by us!! */
-	}
-
-	if(readl(ETHER_INT_SRC(dev->base_addr))&
-	   (ETHER_INT_SRC_INTMACRX_MSK |
-	    ETHER_INT_SRC_FDAEX_MSK |
-	    ETHER_INT_SRC_BLEX_MSK)) {
-		struct rx_blist_ent* blist_ent_ptr;
-		struct rx_fda_ent* fda_ent_ptr;
-		struct sk_buff* skb;
-
-		fda_ent_ptr=priv->rx_fda_ptr;
-		spin_lock(&priv->rx_lock);
-		while(fda_ent_ptr<(priv->rx_fda_ptr+RX_NUM_FDESC)){
-			int result;
-
-			if(!(fda_ent_ptr->fd.FDCtl&FDCTL_COWNSFD_MSK))
-			{
-				/* This frame is ready for processing */
-				/*find the corresponding buffer in the bufferlist */
-				blist_ent_ptr=priv->rx_blist_vp+fda_ent_ptr->bd.BDStat;
-				skb=(struct sk_buff*)blist_ent_ptr->fd.FDSystem;
-
-				/* Pass this skb up the stack */
-				skb->dev=dev;
-				skb_put(skb,fda_ent_ptr->fd.FDLength);
-				skb->protocol=eth_type_trans(skb,dev);
-				skb->ip_summed=CHECKSUM_UNNECESSARY;
-				result=netif_rx(skb);
-				/* Update statistics */
-				priv->stats.rx_packets++;
-				priv->stats.rx_bytes+=fda_ent_ptr->fd.FDLength;
-
-				/* Free the FDA entry */
-				fda_ent_ptr->bd.BDStat=0xff;
-				fda_ent_ptr->fd.FDCtl=FDCTL_COWNSFD_MSK;
-
-				/* Allocate a new skb and point the bd entry to it */
-				blist_ent_ptr->fd.FDSystem=0;
-				skb=dev_alloc_skb(PKT_BUF_SZ);
-				//printk("allocskb=%#x\n",skb);
-				if(skb){
-					setup_blist_entry(skb,blist_ent_ptr);
-
-				}
-				else if(!priv->memupdate_scheduled){
-					int tmp;
-					/* There are no buffers at the moment, so schedule */
-					/* the background task to sort this out */
-					schedule_task(&priv->tq_memupdate);
-					priv->memupdate_scheduled=1;
-					printk(KERN_DEBUG "%s:No buffers",dev->name);
-					/* If this interrupt was due to a lack of buffers then
-					 * we'd better stop the receiver too */
-					if(interruptValue&ETHER_INT_SRC_BLEX_MSK){
-						priv->rx_disabled=1;
-						tmp=readl(ETHER_INT_SRC(dev->base_addr));
-						writel(tmp&~ETHER_RX_CTL_RXEN_MSK,ETHER_RX_CTL(dev->base_addr));
-						printk(KERN_DEBUG "%s:Halting rx",dev->name);
-					}
-
-				}
-
-			}
-			fda_ent_ptr++;
-		}
-		spin_unlock(&priv->rx_lock);
-
-		/* Clear the  interrupts */
-		writel(ETHER_INT_SRC_INTMACRX_MSK | ETHER_INT_SRC_FDAEX_MSK
-		       | ETHER_INT_SRC_BLEX_MSK,ETHER_INT_SRC(dev->base_addr));
-
-	}
-
-	if(readl(ETHER_INT_SRC(dev->base_addr))&ETHER_INT_SRC_INTMACTX_MSK){
-
-		if(!priv->memupdate_scheduled){
-			schedule_task(&priv->tq_memupdate);
-			priv->memupdate_scheduled=1;
-		}
-		/* Clear the interrupt */
-		writel(ETHER_INT_SRC_INTMACTX_MSK,ETHER_INT_SRC(dev->base_addr));
-	}
-
-	if (readl(ETHER_INT_SRC(dev->base_addr)) & (ETHER_INT_SRC_SWINT_MSK|
-						    ETHER_INT_SRC_INTEARNOT_MSK|
-						    ETHER_INT_SRC_INTLINK_MSK|
-						    ETHER_INT_SRC_INTEXBD_MSK|
-						    ETHER_INT_SRC_INTTXCTLCMP_MSK))
-	{
-		/*
-		 *	Not using any of these so they shouldn't happen
-		 *
-		 *	In the cased of INTEXBD - if you allocate more
-		 *      than 28 decsriptors you may need to think about this
-		 */
-		printk("Not using this interrupt\n");
-	}
-
-	if (readl(ETHER_INT_SRC(dev->base_addr)) &
-	    (ETHER_INT_SRC_INTSBUS_MSK |
-	     ETHER_INT_SRC_INTNRABT_MSK
-	     |ETHER_INT_SRC_DMPARERR_MSK))
-	{
-		/*
-		 * Hardware errors, we can either ignore them and hope they go away
-		 *or reset the device, I'll try the first for now to see if they happen
-		 */
-		printk("Hardware error\n");
-	}
-}
-
-static void ether00_setup_ethernet_address(struct net_device* dev)
-{
-	int tmp;
-
-	dev->addr_len=6;
-	writew(0,ETHER_ARC_ADR(dev->base_addr));
-	writel((dev->dev_addr[0]<<24) |
-		(dev->dev_addr[1]<<16) |
-		(dev->dev_addr[2]<<8) |
-		dev->dev_addr[3],
-		ETHER_ARC_DATA(dev->base_addr));
-
-	writew(4,ETHER_ARC_ADR(dev->base_addr));
-	tmp=readl(ETHER_ARC_DATA(dev->base_addr));
-	tmp&=0xffff;
-	tmp|=(dev->dev_addr[4]<<24) | (dev->dev_addr[5]<<16);
-	writel(tmp, ETHER_ARC_DATA(dev->base_addr));
-	/* Enable this entry in the ARC */
-
-	writel(1,ETHER_ARC_ENA(dev->base_addr));
-
-	return;
-}
-
-
-static void ether00_reset(struct net_device *dev)
-{
-	/* reset the controller */
-	writew(ETHER_MAC_CTL_RESET_MSK,ETHER_MAC_CTL(dev->base_addr));
-
-	/*
-	 * Make sure we're not going to send anything
-	 */
-
-	writew(ETHER_TX_CTL_TXHALT_MSK,ETHER_TX_CTL(dev->base_addr));
-
-	/*
-	 * Make sure we're not going to receive anything
-	 */
-	writew(ETHER_RX_CTL_RXHALT_MSK,ETHER_RX_CTL(dev->base_addr));
-
-	/*
-	 * Disable Interrupts for now, and set the burst size to 8 bytes
-	 */
-
-	writel(ETHER_DMA_CTL_INTMASK_MSK |
-	       ((8 << ETHER_DMA_CTL_DMBURST_OFST) & ETHER_DMA_CTL_DMBURST_MSK)
-	       |(2<<ETHER_DMA_CTL_RXALIGN_OFST),
-	       ETHER_DMA_CTL(dev->base_addr));
-
-
-	/*
-	 * Set TxThrsh - start transmitting a packet after 1514
-	 * bytes or when a packet is complete, whichever comes first
-	 */
-	 writew(1514,ETHER_TXTHRSH(dev->base_addr));
-
-	/*
-	 * Set TxPollCtr.  Each cycle is
-	 * 61.44 microseconds with a 33 MHz bus
-	 */
-	 writew(1,ETHER_TXPOLLCTR(dev->base_addr));
-
-	/*
-	 * Set Rx_Ctl - Turn off reception and let RxData turn it
-	 * on later
-	 */
-	 writew(ETHER_RX_CTL_RXHALT_MSK,ETHER_RX_CTL(dev->base_addr));
-
-}
-
-
-static void ether00_set_multicast(struct net_device* dev)
-{
-	int count=dev->mc_count;
-
-	/* Set promiscuous mode if it's asked for. */
-
-	if (dev->flags&IFF_PROMISC){
-
-		writew( ETHER_ARC_CTL_COMPEN_MSK |
-			ETHER_ARC_CTL_BROADACC_MSK |
-			ETHER_ARC_CTL_GROUPACC_MSK |
-			ETHER_ARC_CTL_STATIONACC_MSK,
-			ETHER_ARC_CTL(dev->base_addr));
-		return;
-	}
-
-	/*
-	 * Get all multicast packets if required, or if there are too
-	 * many addresses to fit in hardware
-	 */
-	if (dev->flags & IFF_ALLMULTI){
-		writew( ETHER_ARC_CTL_COMPEN_MSK |
-			ETHER_ARC_CTL_GROUPACC_MSK |
-			ETHER_ARC_CTL_BROADACC_MSK,
-			ETHER_ARC_CTL(dev->base_addr));
-		return;
-	}
-	if (dev->mc_count > (ETHER_ARC_SIZE - 1)){
-
-		printk(KERN_WARNING "Too many multicast addresses for hardware to filter - receiving all multicast packets\n");
-		writew( ETHER_ARC_CTL_COMPEN_MSK |
-			ETHER_ARC_CTL_GROUPACC_MSK |
-			ETHER_ARC_CTL_BROADACC_MSK,
-			ETHER_ARC_CTL(dev->base_addr));
-		return;
-	}
-
-	if(dev->mc_count){
-		struct dev_mc_list *mc_list_ent=dev->mc_list;
-		unsigned int temp,i;
-		DEBUG(printk("mc_count=%d mc_list=%#x\n",dev-> mc_count, dev->mc_list));
-		DEBUG(printk("mc addr=%02#x%02x%02x%02x%02x%02x\n",
-			     mc_list_ent->dmi_addr[5],
-			     mc_list_ent->dmi_addr[4],
-			     mc_list_ent->dmi_addr[3],
-			     mc_list_ent->dmi_addr[2],
-			     mc_list_ent->dmi_addr[1],
-			     mc_list_ent->dmi_addr[0]);)
-
-		/*
-		 * The first 6 bytes are the MAC address, so
-		 * don't change them!
-		 */
-		writew(4,ETHER_ARC_ADR(dev->base_addr));
-		temp=readl(ETHER_ARC_DATA(dev->base_addr));
-		temp&=0xffff0000;
-
-		/* Disable the current multicast stuff */
-		writel(1,ETHER_ARC_ENA(dev->base_addr));
-
-		for(;;){
-			temp|=mc_list_ent->dmi_addr[1] |
-				mc_list_ent->dmi_addr[0]<<8;
-			writel(temp,ETHER_ARC_DATA(dev->base_addr));
-
-			i=readl(ETHER_ARC_ADR(dev->base_addr));
-			writew(i+4,ETHER_ARC_ADR(dev->base_addr));
-
-			temp=mc_list_ent->dmi_addr[5]|
-				mc_list_ent->dmi_addr[4]<<8 |
-				mc_list_ent->dmi_addr[3]<<16 |
-				mc_list_ent->dmi_addr[2]<<24;
-			writel(temp,ETHER_ARC_DATA(dev->base_addr));
-
-			count--;
-			if(!mc_list_ent->next || !count){
-				break;
-			}
-			DEBUG(printk("mc_list_next=%#x\n",mc_list_ent->next);)
-			mc_list_ent=mc_list_ent->next;
-
-
-			i=readl(ETHER_ARC_ADR(dev->base_addr));
-			writel(i+4,ETHER_ARC_ADR(dev->base_addr));
-
-			temp=mc_list_ent->dmi_addr[3]|
-				mc_list_ent->dmi_addr[2]<<8 |
-				mc_list_ent->dmi_addr[1]<<16 |
-				mc_list_ent->dmi_addr[0]<<24;
-			writel(temp,ETHER_ARC_DATA(dev->base_addr));
-
-			i=readl(ETHER_ARC_ADR(dev->base_addr));
-			writel(i+4,ETHER_ARC_ADR(dev->base_addr));
-
-			temp=mc_list_ent->dmi_addr[4]<<16 |
-				mc_list_ent->dmi_addr[5]<<24;
-
-			writel(temp,ETHER_ARC_DATA(dev->base_addr));
-
-			count--;
-			if(!mc_list_ent->next || !count){
-				break;
-			}
-			mc_list_ent=mc_list_ent->next;
-		}
-
-
-		if(count)
-			printk(KERN_WARNING "Multicast list size error\n");
-
-
-		writew( ETHER_ARC_CTL_BROADACC_MSK|
-			ETHER_ARC_CTL_COMPEN_MSK,
-			ETHER_ARC_CTL(dev->base_addr));
-
-	}
-
-	/* enable the active ARC enties */
-	writew((1<<(count+2))-1,ETHER_ARC_ENA(dev->base_addr));
-}
-
-
-static int ether00_open(struct net_device* dev)
-{
-	int result,tmp;
-	struct net_priv* priv;
-
-	if (!is_valid_ether_addr(dev->dev_addr))
-		return -EINVAL;
-
-	/* Install interrupt handlers */
-	result=request_irq(dev->irq,ether00_int,0,"ether00",dev);
-	if(result)
-		goto open_err1;
-
-	result=request_irq(2,ether00_phy_int,0,"ether00_phy",dev);
-	if(result)
-		goto open_err2;
-
-	ether00_reset(dev);
-	result=ether00_mem_init(dev);
-	if(result)
-		goto open_err3;
-
-
-	ether00_setup_ethernet_address(dev);
-
-	ether00_set_multicast(dev);
-
-	result=ether00_write_phy(dev,PHY_CONTROL, PHY_CONTROL_ANEGEN_MSK | PHY_CONTROL_RANEG_MSK);
-	if(result)
-		goto open_err4;
-	result=ether00_write_phy(dev,PHY_IRQ_CONTROL, PHY_IRQ_CONTROL_LS_CHG_IE_MSK |
-				 PHY_IRQ_CONTROL_ANEG_COMP_IE_MSK);
-	if(result)
-		goto open_err4;
-
-	/* Start the device enable interrupts */
-	writew(ETHER_RX_CTL_RXEN_MSK
-//	       | ETHER_RX_CTL_STRIPCRC_MSK
-	       | ETHER_RX_CTL_ENGOOD_MSK
-	       | ETHER_RX_CTL_ENRXPAR_MSK| ETHER_RX_CTL_ENLONGERR_MSK
-	       | ETHER_RX_CTL_ENOVER_MSK| ETHER_RX_CTL_ENCRCERR_MSK,
-	       ETHER_RX_CTL(dev->base_addr));
-
-	writew(ETHER_TX_CTL_TXEN_MSK|
-	       ETHER_TX_CTL_ENEXDEFER_MSK|
-	       ETHER_TX_CTL_ENLCARR_MSK|
-	       ETHER_TX_CTL_ENEXCOLL_MSK|
-	       ETHER_TX_CTL_ENLATECOLL_MSK|
-	       ETHER_TX_CTL_ENTXPAR_MSK|
-	       ETHER_TX_CTL_ENCOMP_MSK,
-	       ETHER_TX_CTL(dev->base_addr));
-
-	tmp=readl(ETHER_DMA_CTL(dev->base_addr));
-	writel(tmp&~ETHER_DMA_CTL_INTMASK_MSK,ETHER_DMA_CTL(dev->base_addr));
-
-	return 0;
-
- open_err4:
-	ether00_reset(dev);
- open_err3:
-	free_irq(2,dev);
- open_err2:
-	free_irq(dev->irq,dev);
- open_err1:
-	return result;
-
-}
-
-
-static int ether00_tx(struct sk_buff* skb, struct net_device* dev)
-{
-	struct net_priv *priv=dev->priv;
-	struct tx_fda_ent *fda_ptr;
-	int i;
-
-
-	/*
-	 *	Find an empty slot in which to stick the frame
-	 */
-	fda_ptr=(struct tx_fda_ent*)__dma_va(readl(ETHER_TXFRMPTR(dev->base_addr)));
-	i=0;
-	while(i<TX_NUM_FDESC){
-		if (fda_ptr->fd.FDStat||(fda_ptr->fd.FDCtl & FDCTL_COWNSFD_MSK)){
-			fda_ptr =(struct tx_fda_ent*) __dma_va((struct tx_fda_ent*)fda_ptr->fd.FDNext);
-		}
-		else {
-			break;
-		}
-		i++;
-	}
-
-	/* Write the skb data from the cache*/
-	consistent_sync(skb->data,skb->len,PCI_DMA_TODEVICE);
-	fda_ptr->bd.BuffData=(char*)__pa(skb->data);
-	fda_ptr->bd.BuffLength=(unsigned short)skb->len;
-	/* Save the pointer to the skb for freeing later */
-	fda_ptr->fd.FDSystem=(unsigned int)skb;
-	fda_ptr->fd.FDStat=0;
-	/* Pass ownership of the buffers to the controller */
-	fda_ptr->fd.FDCtl=1;
-	fda_ptr->fd.FDCtl|=FDCTL_COWNSFD_MSK;
-
-	/* If the next buffer in the list is full, stop the queue */
-	fda_ptr=(struct tx_fda_ent*)__dma_va(fda_ptr->fd.FDNext);
-	if ((fda_ptr->fd.FDStat)||(fda_ptr->fd.FDCtl & FDCTL_COWNSFD_MSK)){
-		netif_stop_queue(dev);
-		priv->queue_stopped=1;
-	}
-
-	return 0;
-}
-
-static struct net_device_stats *ether00_stats(struct net_device* dev)
-{
-	struct net_priv *priv=dev->priv;
-	return &priv->stats;
-}
-
-
-static int ether00_stop(struct net_device* dev)
-{
-	struct net_priv *priv=dev->priv;
-	int tmp;
-
-	/* Stop/disable the device. */
-	tmp=readw(ETHER_RX_CTL(dev->base_addr));
-	tmp&=~(ETHER_RX_CTL_RXEN_MSK | ETHER_RX_CTL_ENGOOD_MSK);
-	tmp|=ETHER_RX_CTL_RXHALT_MSK;
-	writew(tmp,ETHER_RX_CTL(dev->base_addr));
-
-	tmp=readl(ETHER_TX_CTL(dev->base_addr));
-	tmp&=~ETHER_TX_CTL_TXEN_MSK;
-	tmp|=ETHER_TX_CTL_TXHALT_MSK;
-	writel(tmp,ETHER_TX_CTL(dev->base_addr));
-
-	/* Free up system resources */
-	free_irq(dev->irq,dev);
-	free_irq(2,dev);
-	iounmap(priv->dma_data);
-
-	return 0;
-}
-
-
-static void ether00_get_ethernet_address(struct net_device* dev)
-{
-	struct mtd_info *mymtd=NULL;
-	int i;
-	size_t retlen;
-
-	/*
-	 * For the Epxa10 dev board (camelot), the ethernet MAC
-	 * address is of the form  00:aa:aa:00:xx:xx where
-	 * 00:aa:aa is the Altera vendor ID and xx:xx is the
-	 * last 2 bytes of the board serial number, as programmed
-	 * into the OTP area of the flash device on EBI1. If this
-	 * isn't an expa10 dev board, or there's no mtd support to
-	 * read the serial number from flash then we'll force the
-	 * use to set their own mac address using ifconfig.
-	 */
-
-#ifdef CONFIG_ARCH_CAMELOT
-#ifdef CONFIG_MTD
-	/* get the mtd_info structure for the first mtd device*/
-	for(i=0;i<MAX_MTD_DEVICES;i++){
-		mymtd=get_mtd_device(NULL,i);
-		if(!mymtd||!strcmp(mymtd->name,"EPXA10DB flash"))
-			break;
-	}
-
-	if(!mymtd || !mymtd->read_user_prot_reg){
-		printk(KERN_WARNING "%s: Failed to read MAC address from flash\n",dev->name);
-	}else{
-		mymtd->read_user_prot_reg(mymtd,2,1,&retlen,&dev->dev_addr[5]);
-		mymtd->read_user_prot_reg(mymtd,3,1,&retlen,&dev->dev_addr[4]);
-		dev->dev_addr[3]=0;
-		dev->dev_addr[2]=vendor_id[1];
-		dev->dev_addr[1]=vendor_id[0];
-		dev->dev_addr[0]=0;
-	}
-#else
-	printk(KERN_WARNING "%s: MTD support required to read MAC address from EPXA10 dev board\n", dev->name);
-#endif
-#endif
-
-	if (!is_valid_ether_addr(dev->dev_addr))
-		printk("%s: Invalid ethernet MAC address.  Please set using "
-			"ifconfig\n", dev->name);
-
-}
-
-/*
- * Keep a mapping of dev_info addresses -> port lines to use when
- * removing ports dev==NULL indicates unused entry
- */
-
-
-static struct net_device* dev_list[ETH_NR];
-
-static int ether00_add_device(struct pldhs_dev_info* dev_info,void* dev_ps_data)
-{
-	struct net_device *dev;
-	struct net_priv *priv;
-	void *map_addr;
-	int result;
-	int i;
-
-	i=0;
-	while(dev_list[i] && i < ETH_NR)
-		i++;
-
-	if(i==ETH_NR){
-		printk(KERN_WARNING "ether00: Maximum number of ports reached\n");
-		return 0;
-	}
-
-
-	if (!request_mem_region(dev_info->base_addr, MAC_REG_SIZE, "ether00"))
-		return -EBUSY;
-
-	dev = alloc_etherdev(sizeof(struct net_priv));
-	if(!dev) {
-		result = -ENOMEM;
-		goto out_release;
-	}
-	priv = dev->priv;
-
-	priv->tq_memupdate.routine=ether00_mem_update;
-	priv->tq_memupdate.data=(void*) dev;
-
-	spin_lock_init(&priv->rx_lock);
-
-	map_addr=ioremap_nocache(dev_info->base_addr,SZ_4K);
-	if(!map_addr){
-		result = -ENOMEM;
-		out_kfree;
-	}
-
-	dev->open=ether00_open;
-	dev->stop=ether00_stop;
-	dev->set_multicast_list=ether00_set_multicast;
-	dev->hard_start_xmit=ether00_tx;
-	dev->get_stats=ether00_stats;
-
-	ether00_get_ethernet_address(dev);
-
-	SET_MODULE_OWNER(dev);
-
-	dev->base_addr=(unsigned int)map_addr;
-	dev->irq=dev_info->irq;
-	dev->features=NETIF_F_DYNALLOC | NETIF_F_HW_CSUM;
-
-	result=register_netdev(dev);
-	if(result){
-		printk("Ether00: Error %i registering driver\n",result);
-		goto out_unmap;
-	}
-	printk("registered ether00 device at %#x\n",dev_info->base_addr);
-
-	dev_list[i]=dev;
-
-	return result;
-
- out_unmap:
-	iounmap(map_addr);
- out_kfree:
-	free_netdev(dev);
- out_release:
-	release_mem_region(dev_info->base_addr, MAC_REG_SIZE);
-	return result;
-}
-
-
-static int ether00_remove_devices(void)
-{
-	int i;
-
-	for(i=0;i<ETH_NR;i++){
-		if(dev_list[i]){
-			netif_device_detach(dev_list[i]);
-			unregister_netdev(dev_list[i]);
-			iounmap((void*)dev_list[i]->base_addr);
-			release_mem_region(dev_list[i]->base_addr, MAC_REG_SIZE);
-			free_netdev(dev_list[i]);
-			dev_list[i]=0;
-		}
-	}
-	return 0;
-}
-
-static struct pld_hotswap_ops ether00_pldhs_ops={
-	.name = ETHER00_NAME,
-	.add_device = ether00_add_device,
-	.remove_devices = ether00_remove_devices,
-};
-
-
-static void __exit ether00_cleanup_module(void)
-{
-	int result;
-	result=ether00_remove_devices();
-	if(result)
-		printk(KERN_WARNING "ether00: failed to remove all devices\n");
-
-	pldhs_unregister_driver(ETHER00_NAME);
-}
-module_exit(ether00_cleanup_module);
-
-
-static int __init ether00_mod_init(void)
-{
-	printk("mod init\n");
-	return pldhs_register_driver(&ether00_pldhs_ops);
-
-}
-
-module_init(ether00_mod_init);
-
diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c
index 1cc53ab..f1d5b10 100644
--- a/drivers/net/arm/ether3.c
+++ b/drivers/net/arm/ether3.c
@@ -69,7 +69,6 @@
 #include <asm/system.h>
 #include <asm/ecard.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 
 static char version[] __initdata = "ether3 ethernet driver (c) 1995-2000 R.M.King v1.17\n";
 
diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c
index 942a281..6a93b66 100644
--- a/drivers/net/arm/etherh.c
+++ b/drivers/net/arm/etherh.c
@@ -50,7 +50,6 @@
 #include <asm/system.h>
 #include <asm/ecard.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 
 #include "../8390.h"
 
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 41b3d83..f4424cf 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -515,6 +515,7 @@
 			count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
 		}
   	}
+	spin_unlock_bh(&ax->buflock);
 
 	set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
 	actual = ax->tty->driver->write(ax->tty, ax->xbuff, count);
@@ -524,7 +525,6 @@
 	ax->dev->trans_start = jiffies;
 	ax->xleft = count - actual;
 	ax->xhead = ax->xbuff + actual;
-	spin_unlock_bh(&ax->buflock);
 }
 
 /* Encapsulate an AX.25 packet and kick it into a TTY queue. */
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index e92c17f..55c7ed6 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -276,7 +276,7 @@
  * Convert an address in a kernel buffer to a bus/phys/dma address.
  * This work *only* for memory fragments part of lp->page_vaddr,
  * because it was properly DMA allocated via pci_alloc_consistent(),
- * so we just need to "retreive" the original mapping to bus/phys/dma
+ * so we just need to "retrieve" the original mapping to bus/phys/dma
  * address - Jean II */
 static inline dma_addr_t virt_to_whatever(struct net_device *dev, u32 * ptr)
 {
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
new file mode 100644
index 0000000..1b69925
--- /dev/null
+++ b/drivers/net/ifb.c
@@ -0,0 +1,294 @@
+/* drivers/net/ifb.c: 
+
+	The purpose of this driver is to provide a device that allows
+	for sharing of resources:
+
+	1) qdiscs/policies that are per device as opposed to system wide.
+	ifb allows for a device which can be redirected to thus providing
+	an impression of sharing.
+
+	2) Allows for queueing incoming traffic for shaping instead of
+	dropping. 
+	
+	The original concept is based on what is known as the IMQ
+	driver initially written by Martin Devera, later rewritten
+	by Patrick McHardy and then maintained by Andre Correa.
+
+	You need the tc action  mirror or redirect to feed this device
+       	packets.
+
+	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.
+ 
+  	Authors:	Jamal Hadi Salim (2005)
+ 
+*/
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+#include <net/pkt_sched.h> 
+
+#define TX_TIMEOUT  (2*HZ)
+                                                                                
+#define TX_Q_LIMIT    32
+struct ifb_private {
+	struct net_device_stats stats;
+	struct tasklet_struct   ifb_tasklet;
+	int     tasklet_pending;
+	/* mostly debug stats leave in for now */
+	unsigned long   st_task_enter; /* tasklet entered */
+	unsigned long   st_txq_refl_try; /* transmit queue refill attempt */
+	unsigned long   st_rxq_enter; /* receive queue entered */
+	unsigned long   st_rx2tx_tran; /* receive to trasmit transfers */
+	unsigned long   st_rxq_notenter; /*receiveQ not entered, resched */
+	unsigned long   st_rx_frm_egr; /* received from egress path */
+	unsigned long   st_rx_frm_ing; /* received from ingress path */
+	unsigned long   st_rxq_check;
+	unsigned long   st_rxq_rsch;
+	struct sk_buff_head     rq;
+	struct sk_buff_head     tq;
+};
+
+static int numifbs = 1;
+
+static void ri_tasklet(unsigned long dev);
+static int ifb_xmit(struct sk_buff *skb, struct net_device *dev);
+static struct net_device_stats *ifb_get_stats(struct net_device *dev);
+static int ifb_open(struct net_device *dev);
+static int ifb_close(struct net_device *dev);
+
+static void ri_tasklet(unsigned long dev) 
+{
+
+	struct net_device *_dev = (struct net_device *)dev;
+	struct ifb_private *dp = netdev_priv(_dev);
+	struct net_device_stats *stats = &dp->stats;
+	struct sk_buff *skb;
+
+	dp->st_task_enter++;
+	if ((skb = skb_peek(&dp->tq)) == NULL) {
+		dp->st_txq_refl_try++;
+		if (spin_trylock(&_dev->xmit_lock)) {
+			dp->st_rxq_enter++;
+			while ((skb = skb_dequeue(&dp->rq)) != NULL) {
+				skb_queue_tail(&dp->tq, skb);
+				dp->st_rx2tx_tran++;
+			}
+			spin_unlock(&_dev->xmit_lock);
+		} else {
+			/* reschedule */
+			dp->st_rxq_notenter++;
+			goto resched;
+		}
+	}
+
+	while ((skb = skb_dequeue(&dp->tq)) != NULL) {
+		u32 from = G_TC_FROM(skb->tc_verd);
+
+		skb->tc_verd = 0;
+		skb->tc_verd = SET_TC_NCLS(skb->tc_verd);
+		stats->tx_packets++;
+		stats->tx_bytes +=skb->len;
+		if (from & AT_EGRESS) {
+			dp->st_rx_frm_egr++;
+			dev_queue_xmit(skb);
+		} else if (from & AT_INGRESS) {
+
+			dp->st_rx_frm_ing++;
+			netif_rx(skb);
+		} else {
+			dev_kfree_skb(skb);
+			stats->tx_dropped++;
+		}
+	}
+
+	if (spin_trylock(&_dev->xmit_lock)) {
+		dp->st_rxq_check++;
+		if ((skb = skb_peek(&dp->rq)) == NULL) {
+			dp->tasklet_pending = 0;
+			if (netif_queue_stopped(_dev))
+				netif_wake_queue(_dev);
+		} else {
+			dp->st_rxq_rsch++;
+			spin_unlock(&_dev->xmit_lock);
+			goto resched;
+		}
+		spin_unlock(&_dev->xmit_lock);
+	} else {
+resched:
+		dp->tasklet_pending = 1;
+		tasklet_schedule(&dp->ifb_tasklet);
+	}
+
+}
+
+static void __init ifb_setup(struct net_device *dev)
+{
+	/* Initialize the device structure. */
+	dev->get_stats = ifb_get_stats;
+	dev->hard_start_xmit = ifb_xmit;
+	dev->open = &ifb_open;
+	dev->stop = &ifb_close;
+
+	/* Fill in device structure with ethernet-generic values. */
+	ether_setup(dev);
+	dev->tx_queue_len = TX_Q_LIMIT;
+	dev->change_mtu = NULL;
+	dev->flags |= IFF_NOARP;
+	dev->flags &= ~IFF_MULTICAST;
+	SET_MODULE_OWNER(dev);
+	random_ether_addr(dev->dev_addr);
+}
+
+static int ifb_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct ifb_private *dp = netdev_priv(dev);
+	struct net_device_stats *stats = &dp->stats;
+	int ret = 0;
+	u32 from = G_TC_FROM(skb->tc_verd);
+
+	stats->tx_packets++;
+	stats->tx_bytes+=skb->len;
+
+	if (!from || !skb->input_dev) {
+dropped:
+		dev_kfree_skb(skb);
+		stats->rx_dropped++;
+		return ret;
+	} else {
+		/* 
+		 * note we could be going
+		 * ingress -> egress or
+		 * egress -> ingress
+		*/
+		skb->dev = skb->input_dev;
+		skb->input_dev = dev;
+		if (from & AT_INGRESS) {
+			skb_pull(skb, skb->dev->hard_header_len);
+		} else {
+			if (!(from & AT_EGRESS)) {
+				goto dropped;
+			}
+		}
+	}
+
+	if (skb_queue_len(&dp->rq) >= dev->tx_queue_len) {
+		netif_stop_queue(dev);
+	}
+
+	dev->trans_start = jiffies;
+	skb_queue_tail(&dp->rq, skb);
+	if (!dp->tasklet_pending) {
+		dp->tasklet_pending = 1;
+		tasklet_schedule(&dp->ifb_tasklet);
+	}
+
+	return ret;
+}
+
+static struct net_device_stats *ifb_get_stats(struct net_device *dev)
+{
+	struct ifb_private *dp = netdev_priv(dev);
+	struct net_device_stats *stats = &dp->stats;
+
+	pr_debug("tasklets stats %ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld:%ld \n",
+		dp->st_task_enter, dp->st_txq_refl_try, dp->st_rxq_enter, 
+		dp->st_rx2tx_tran dp->st_rxq_notenter, dp->st_rx_frm_egr,
+		dp->st_rx_frm_ing, dp->st_rxq_check, dp->st_rxq_rsch );
+
+	return stats;
+}
+
+static struct net_device **ifbs;
+
+/* Number of ifb devices to be set up by this module. */
+module_param(numifbs, int, 0);
+MODULE_PARM_DESC(numifbs, "Number of ifb devices");
+
+static int ifb_close(struct net_device *dev)
+{
+	struct ifb_private *dp = netdev_priv(dev);
+
+	tasklet_kill(&dp->ifb_tasklet);
+	netif_stop_queue(dev);
+	skb_queue_purge(&dp->rq);
+	skb_queue_purge(&dp->tq);
+	return 0;
+}
+
+static int ifb_open(struct net_device *dev)
+{
+	struct ifb_private *dp = netdev_priv(dev);
+
+	tasklet_init(&dp->ifb_tasklet, ri_tasklet, (unsigned long)dev);
+	skb_queue_head_init(&dp->rq);
+	skb_queue_head_init(&dp->tq);
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+static int __init ifb_init_one(int index)
+{
+	struct net_device *dev_ifb;
+	int err;
+
+	dev_ifb = alloc_netdev(sizeof(struct ifb_private),
+				 "ifb%d", ifb_setup);
+
+	if (!dev_ifb)
+		return -ENOMEM;
+
+	if ((err = register_netdev(dev_ifb))) {
+		free_netdev(dev_ifb);
+		dev_ifb = NULL;
+	} else {
+		ifbs[index] = dev_ifb; 
+	}
+
+	return err;
+}
+
+static void ifb_free_one(int index)
+{
+	unregister_netdev(ifbs[index]);
+	free_netdev(ifbs[index]);
+} 
+
+static int __init ifb_init_module(void)
+{ 
+	int i, err = 0;
+	ifbs = kmalloc(numifbs * sizeof(void *), GFP_KERNEL); 
+	if (!ifbs)
+		return -ENOMEM; 
+	for (i = 0; i < numifbs && !err; i++)
+		err = ifb_init_one(i); 
+	if (err) { 
+		while (--i >= 0)
+			ifb_free_one(i);
+	}
+
+	return err;
+} 
+
+static void __exit ifb_cleanup_module(void)
+{
+	int i;
+
+	for (i = 0; i < numifbs; i++) 
+		ifb_free_one(i); 
+	kfree(ifbs);	
+}
+
+module_init(ifb_init_module);
+module_exit(ifb_cleanup_module);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jamal Hadi Salim");
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index 049c34b..593d8ad 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -1598,7 +1598,7 @@
     switch(cmd) {
       case SIOCGMIIPHY:		/* Get the address of the PHY in use. */
 	data[0] = 0;		/* we have only this address */
-	/* fall trough */
+	/* fall through */
       case SIOCGMIIREG:		/* Read the specified MII register. */
 	data[3] = mii_rd(ioaddr, data[0] & 0x1f, data[1] & 0x1f);
 	break;
diff --git a/drivers/net/sk98lin/skdim.c b/drivers/net/sk98lin/skdim.c
index 0fddf61..07c1b4c 100644
--- a/drivers/net/sk98lin/skdim.c
+++ b/drivers/net/sk98lin/skdim.c
@@ -180,7 +180,7 @@
                 /*
                 ** The number of interrupts per sec is the same as expected.
                 ** Evalulate the descriptor-ratio. If it has changed, a resize 
-                ** in the moderation timer might be usefull
+                ** in the moderation timer might be useful
                 */
                 if (M_DIMINFO.AutoSizing) {
                     ResizeDimTimerDuration(pAC);
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
index 197edd7..a5f2b1e 100644
--- a/drivers/net/sk98lin/skge.c
+++ b/drivers/net/sk98lin/skge.c
@@ -2851,7 +2851,7 @@
  * Description:
  *	This function is called if an ioctl is issued on the device.
  *	There are three subfunction for reading, writing and test-writing
- *	the private MIB data structure (usefull for SysKonnect-internal tools).
+ *	the private MIB data structure (useful for SysKonnect-internal tools).
  *
  * Returns:
  *	0, if everything is ok
diff --git a/drivers/net/sk98lin/skgepnmi.c b/drivers/net/sk98lin/skgepnmi.c
index 58e1a5b..a386172 100644
--- a/drivers/net/sk98lin/skgepnmi.c
+++ b/drivers/net/sk98lin/skgepnmi.c
@@ -611,7 +611,7 @@
  * Description:
  *	Calls a general sub-function for all this stuff. The preset does
  *	the same as a set, but returns just before finally setting the
- *	new value. This is usefull to check if a set might be successfull.
+ *	new value. This is useful to check if a set might be successfull.
  *	If the instance -1 is passed, an array of values is supposed and
  *	all instances of the OID will be set.
  *
@@ -654,7 +654,7 @@
  * Description:
  *	Calls a general sub-function for all this stuff. The preset does
  *	the same as a set, but returns just before finally setting the
- *	new value. This is usefull to check if a set might be successfull.
+ *	new value. This is useful to check if a set might be successfull.
  *	If the instance -1 is passed, an array of values is supposed and
  *	all instances of the OID will be set.
  *
@@ -870,7 +870,7 @@
  * Description:
  *	Calls a general sub-function for all this set stuff. The preset does
  *	the same as a set, but returns just before finally setting the
- *	new value. This is usefull to check if a set might be successfull.
+ *	new value. This is useful to check if a set might be successfull.
  *	The sub-function runs through the IdTable, checks which OIDs are able
  *	to set, and calls the handler function of the OID to perform the
  *	preset. The return value of the function will also be stored in
@@ -6473,7 +6473,7 @@
  *
  * Description:
  *	The COMMON module only tells us if the mode is half or full duplex.
- *	But in the decade of auto sensing it is usefull for the user to
+ *	But in the decade of auto sensing it is useful for the user to
  *	know if the mode was negotiated or forced. Therefore we have a
  *	look to the mode, which was last used by the negotiation process.
  *
diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
index 95bd07b..315be47 100644
--- a/drivers/parisc/led.c
+++ b/drivers/parisc/led.c
@@ -347,7 +347,7 @@
    ** 
    ** led_get_net_activity()
    ** 
-   ** calculate if there was TX- or RX-troughput on the network interfaces
+   ** calculate if there was TX- or RX-throughput on the network interfaces
    ** (analog to dev_get_info() from net/core/dev.c)
    **   
  */
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index d21894c..92a8857 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -25,7 +25,7 @@
 	loff_t new = -1;
 	struct inode *inode = file->f_dentry->d_inode;
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	switch (whence) {
 	case 0:
 		new = off;
@@ -41,7 +41,7 @@
 		new = -EINVAL;
 	else
 		file->f_pos = new;
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	return new;
 }
 
diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c
index 09ed057..dda5a5f 100644
--- a/drivers/scsi/arm/acornscsi.c
+++ b/drivers/scsi/arm/acornscsi.c
@@ -146,7 +146,6 @@
 
 #include <asm/system.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/ecard.h>
 
 #include "../scsi.h"
diff --git a/drivers/scsi/arm/arxescsi.c b/drivers/scsi/arm/arxescsi.c
index 804125e..a289401 100644
--- a/drivers/scsi/arm/arxescsi.c
+++ b/drivers/scsi/arm/arxescsi.c
@@ -33,7 +33,6 @@
 
 #include <asm/dma.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/ecard.h>
 
 #include "../scsi.h"
diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c
index 81e266b..e6c9491 100644
--- a/drivers/scsi/arm/cumana_1.c
+++ b/drivers/scsi/arm/cumana_1.c
@@ -13,7 +13,6 @@
 
 #include <asm/ecard.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/system.h>
 
 #include "../scsi.h"
diff --git a/drivers/scsi/arm/cumana_2.c b/drivers/scsi/arm/cumana_2.c
index 3a7a46b..583d2d8 100644
--- a/drivers/scsi/arm/cumana_2.c
+++ b/drivers/scsi/arm/cumana_2.c
@@ -31,7 +31,6 @@
 #include <asm/dma.h>
 #include <asm/ecard.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/pgtable.h>
 
 #include "../scsi.h"
diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c
index 4d1e8f5..3ffec7e 100644
--- a/drivers/scsi/arm/eesox.c
+++ b/drivers/scsi/arm/eesox.c
@@ -35,7 +35,6 @@
 #include <linux/dma-mapping.h>
 
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/dma.h>
 #include <asm/ecard.h>
 #include <asm/pgtable.h>
diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c
index 3333d7b..3113bdc 100644
--- a/drivers/scsi/arm/powertec.c
+++ b/drivers/scsi/arm/powertec.c
@@ -22,7 +22,6 @@
 #include <asm/dma.h>
 #include <asm/ecard.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/pgtable.h>
 
 #include "../scsi.h"
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 221e96e..78aad95 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -2493,7 +2493,7 @@
 	}
 	if (resp) {
 		if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
-			memset(resp, 0, resSz);
+			memset(page_address(resp), 0, resSz);
 		if (retSzp)
 			*retSzp = resSz;
 	}
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 1891cf5..e845461 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -54,6 +54,8 @@
  */
 static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
 
+static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
+
 /*
  * Debugging.
  */
@@ -2118,7 +2120,7 @@
 		return;
 	first = 0;
 
-	for (i = 0; i < UART_NR; i++) {
+	for (i = 0; i < nr_uarts; i++) {
 		struct uart_8250_port *up = &serial8250_ports[i];
 
 		up->port.line = i;
@@ -2137,7 +2139,7 @@
 	}
 
 	for (i = 0, up = serial8250_ports;
-	     i < ARRAY_SIZE(old_serial_port) && i < UART_NR;
+	     i < ARRAY_SIZE(old_serial_port) && i < nr_uarts;
 	     i++, up++) {
 		up->port.iobase   = old_serial_port[i].port;
 		up->port.irq      = irq_canonicalize(old_serial_port[i].irq);
@@ -2159,7 +2161,7 @@
 
 	serial8250_isa_init_ports();
 
-	for (i = 0; i < UART_NR; i++) {
+	for (i = 0; i < nr_uarts; i++) {
 		struct uart_8250_port *up = &serial8250_ports[i];
 
 		up->port.dev = dev;
@@ -2262,7 +2264,7 @@
 	 * if so, search for the first available port that does have
 	 * console support.
 	 */
-	if (co->index >= UART_NR)
+	if (co->index >= nr_uarts)
 		co->index = 0;
 	port = &serial8250_ports[co->index].port;
 	if (!port->iobase && !port->membase)
@@ -2298,7 +2300,7 @@
 	int line;
 	struct uart_port *port;
 
-	for (line = 0; line < UART_NR; line++) {
+	for (line = 0; line < nr_uarts; line++) {
 		port = &serial8250_ports[line].port;
 		if (uart_match_port(p, port))
 			return line;
@@ -2420,7 +2422,7 @@
 {
 	int i;
 
-	for (i = 0; i < UART_NR; i++) {
+	for (i = 0; i < nr_uarts; i++) {
 		struct uart_8250_port *up = &serial8250_ports[i];
 
 		if (up->port.dev == &dev->dev)
@@ -2487,7 +2489,7 @@
 	/*
 	 * First, find a port entry which matches.
 	 */
-	for (i = 0; i < UART_NR; i++)
+	for (i = 0; i < nr_uarts; i++)
 		if (uart_match_port(&serial8250_ports[i].port, port))
 			return &serial8250_ports[i];
 
@@ -2496,7 +2498,7 @@
 	 * free entry.  We look for one which hasn't been previously
 	 * used (indicated by zero iobase).
 	 */
-	for (i = 0; i < UART_NR; i++)
+	for (i = 0; i < nr_uarts; i++)
 		if (serial8250_ports[i].port.type == PORT_UNKNOWN &&
 		    serial8250_ports[i].port.iobase == 0)
 			return &serial8250_ports[i];
@@ -2505,7 +2507,7 @@
 	 * That also failed.  Last resort is to find any entry which
 	 * doesn't have a real port associated with it.
 	 */
-	for (i = 0; i < UART_NR; i++)
+	for (i = 0; i < nr_uarts; i++)
 		if (serial8250_ports[i].port.type == PORT_UNKNOWN)
 			return &serial8250_ports[i];
 
@@ -2590,8 +2592,11 @@
 {
 	int ret, i;
 
+	if (nr_uarts > UART_NR)
+		nr_uarts = UART_NR;
+
 	printk(KERN_INFO "Serial: 8250/16550 driver $Revision: 1.90 $ "
-		"%d ports, IRQ sharing %sabled\n", (int) UART_NR,
+		"%d ports, IRQ sharing %sabled\n", nr_uarts,
 		share_irqs ? "en" : "dis");
 
 	for (i = 0; i < NR_IRQS; i++)
@@ -2651,6 +2656,9 @@
 MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
 	" (unsafe)");
 
+module_param(nr_uarts, uint, 0644);
+MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")");
+
 #ifdef CONFIG_SERIAL_8250_RSA
 module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
 MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 812bae6..1bae26a 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -95,6 +95,16 @@
 	  PCI enumeration and any ports that may be added at run-time
 	  via hot-plug, or any ISA multi-port serial cards.
 
+config SERIAL_8250_RUNTIME_UARTS
+	int "Number of 8250/16550 serial ports to register at runtime"
+	depends on SERIAL_8250
+	default "4"
+	help
+	  Set this to the maximum number of serial ports you want
+	  the kernel to register at boot time.  This can be overriden
+	  with the module parameter "nr_uarts", or boot-time parameter
+	  8250.nr_uarts
+
 config SERIAL_8250_EXTENDED
 	bool "Extended 8250/16550 serial driver options"
 	depends on SERIAL_8250
@@ -359,29 +369,6 @@
 	  your boot loader (lilo or loadlin) about how to pass options to the
 	  kernel at boot time.)
 
-config SERIAL_UART00
-	bool "Excalibur serial port (uart00) support"
-	depends on ARM && ARCH_CAMELOT
-	select SERIAL_CORE
-	help
-	  Say Y here if you want to use the hard logic uart on Excalibur. This
-	  driver also supports soft logic implementations of this uart core.
-
-config SERIAL_UART00_CONSOLE
-	bool "Support for console on Excalibur serial port"
-	depends on SERIAL_UART00
-	select SERIAL_CORE_CONSOLE
-	help
-	  Say Y here if you want to support a serial console on an Excalibur
-	  hard logic uart or uart00 IP core.
-
-	  Even if you say Y here, the currently visible virtual console
-	  (/dev/tty0) will still be used as the system console by default, but
-	  you can alter that using a kernel command line option such as
-	  "console=ttyS1". (Try "man bootparam" or see the documentation of
-	  your boot loader (lilo or loadlin) about how to pass options to the
-	  kernel at boot time.)
-
 config SERIAL_MPSC
 	bool "Marvell MPSC serial port support"
 	depends on PPC32 && MV64X60
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index d7c7c71..137148b 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -29,7 +29,6 @@
 obj-$(CONFIG_SERIAL_PXA) += pxa.o
 obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
 obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o
-obj-$(CONFIG_SERIAL_UART00) += uart00.o
 obj-$(CONFIG_SERIAL_SUNCORE) += suncore.o
 obj-$(CONFIG_SERIAL_SUNZILOG) += sunzilog.o
 obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 34c576d..9589509 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -1440,6 +1440,7 @@
 		 * modem is ready for us.
 		 */
 		spin_lock_irq(&port->lock);
+		port->ops->enable_ms(port);
 		mctrl = port->ops->get_mctrl(port);
 		spin_unlock_irq(&port->lock);
 		if (mctrl & TIOCM_CAR)
diff --git a/drivers/serial/uart00.c b/drivers/serial/uart00.c
deleted file mode 100644
index 47b504f..0000000
--- a/drivers/serial/uart00.c
+++ /dev/null
@@ -1,782 +0,0 @@
-/*
- *  linux/drivers/serial/uart00.c
- *
- *  Driver for UART00 serial ports
- *
- *  Based on drivers/char/serial_amba.c, by ARM Limited & 
- *                                          Deep Blue Solutions Ltd.
- *  Copyright 2001 Altera Corporation
- *
- *  Update for 2.6.4 by Dirk Behme <dirk.behme@de.bosch.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- *  $Id: uart00.c,v 1.35 2002/07/28 10:03:28 rmk Exp $
- *
- */
-#include <linux/config.h>
-
-#if defined(CONFIG_SERIAL_UART00_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-#define SUPPORT_SYSRQ
-#endif
-
-#include <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/sysrq.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/serial_core.h>
-#include <linux/serial.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/sizes.h>
-
-#include <asm/arch/excalibur.h>
-#define UART00_TYPE (volatile unsigned int*)
-#include <asm/arch/uart00.h>
-#include <asm/arch/int_ctrl00.h>
-
-#define UART_NR		2
-
-#define SERIAL_UART00_NAME	"ttyUA"
-#define SERIAL_UART00_MAJOR	204
-#define SERIAL_UART00_MINOR	16      /* Temporary - will change in future */
-#define SERIAL_UART00_NR	UART_NR
-#define UART_PORT_SIZE 0x50
-
-#define UART00_ISR_PASS_LIMIT	256
-
-/*
- * Access macros for the UART00 UARTs
- */
-#define UART_GET_INT_STATUS(p)	inl(UART_ISR((p)->membase))
-#define UART_PUT_IES(p, c)      outl(c,UART_IES((p)->membase))
-#define UART_GET_IES(p)         inl(UART_IES((p)->membase))
-#define UART_PUT_IEC(p, c)      outl(c,UART_IEC((p)->membase))
-#define UART_GET_IEC(p)         inl(UART_IEC((p)->membase))
-#define UART_PUT_CHAR(p, c)     outl(c,UART_TD((p)->membase))
-#define UART_GET_CHAR(p)        inl(UART_RD((p)->membase))
-#define UART_GET_RSR(p)         inl(UART_RSR((p)->membase))
-#define UART_GET_RDS(p)         inl(UART_RDS((p)->membase))
-#define UART_GET_MSR(p)         inl(UART_MSR((p)->membase))
-#define UART_GET_MCR(p)         inl(UART_MCR((p)->membase))
-#define UART_PUT_MCR(p, c)      outl(c,UART_MCR((p)->membase))
-#define UART_GET_MC(p)          inl(UART_MC((p)->membase))
-#define UART_PUT_MC(p, c)       outl(c,UART_MC((p)->membase))
-#define UART_GET_TSR(p)         inl(UART_TSR((p)->membase))
-#define UART_GET_DIV_HI(p)	inl(UART_DIV_HI((p)->membase))
-#define UART_PUT_DIV_HI(p,c)	outl(c,UART_DIV_HI((p)->membase))
-#define UART_GET_DIV_LO(p)	inl(UART_DIV_LO((p)->membase))
-#define UART_PUT_DIV_LO(p,c)	outl(c,UART_DIV_LO((p)->membase))
-#define UART_RX_DATA(s)		((s) & UART_RSR_RX_LEVEL_MSK)
-#define UART_TX_READY(s)	(((s) & UART_TSR_TX_LEVEL_MSK) < 15)
-//#define UART_TX_EMPTY(p)	((UART_GET_FR(p) & UART00_UARTFR_TMSK) == 0)
-
-static void uart00_stop_tx(struct uart_port *port)
-{
-	UART_PUT_IEC(port, UART_IEC_TIE_MSK);
-}
-
-static void uart00_stop_rx(struct uart_port *port)
-{
-	UART_PUT_IEC(port, UART_IEC_RE_MSK);
-}
-
-static void uart00_enable_ms(struct uart_port *port)
-{
-	UART_PUT_IES(port, UART_IES_ME_MSK);
-}
-
-static void
-uart00_rx_chars(struct uart_port *port, struct pt_regs *regs)
-{
-	struct tty_struct *tty = port->info->tty;
-	unsigned int status, ch, rds, flg, ignored = 0;
-
-	status = UART_GET_RSR(port);
-	while (UART_RX_DATA(status)) {
-		/* 
-		 * We need to read rds before reading the 
-		 * character from the fifo
-		 */
-		rds = UART_GET_RDS(port);
-		ch = UART_GET_CHAR(port);
-		port->icount.rx++;
-
-		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-			goto ignore_char;
-
-		flg = TTY_NORMAL;
-
-		/*
-		 * Note that the error handling code is
-		 * out of the main execution path
-		 */
-		if (rds & (UART_RDS_BI_MSK |UART_RDS_FE_MSK|
-			   UART_RDS_PE_MSK |UART_RDS_PE_MSK))
-			goto handle_error;
-		if (uart_handle_sysrq_char(port, ch, regs))
-			goto ignore_char;
-
-	error_return:
-		tty_insert_flip_char(tty, ch, flg);
-
-	ignore_char:
-		status = UART_GET_RSR(port);
-	}
- out:
-	tty_flip_buffer_push(tty);
-	return;
-
- handle_error:
-	if (rds & UART_RDS_BI_MSK) {
-		status &= ~(UART_RDS_FE_MSK | UART_RDS_PE_MSK);
-		port->icount.brk++;
-		if (uart_handle_break(port))
-			goto ignore_char;
-	} else if (rds & UART_RDS_PE_MSK)
-		port->icount.parity++;
-	else if (rds & UART_RDS_FE_MSK)
-		port->icount.frame++;
-	if (rds & UART_RDS_OE_MSK)
-		port->icount.overrun++;
-
-	if (rds & port->ignore_status_mask) {
-		if (++ignored > 100)
-			goto out;
-		goto ignore_char;
-	}
-	rds &= port->read_status_mask;
-
-	if (rds & UART_RDS_BI_MSK)
-		flg = TTY_BREAK;
-	else if (rds & UART_RDS_PE_MSK)
-		flg = TTY_PARITY;
-	else if (rds & UART_RDS_FE_MSK)
-		flg = TTY_FRAME;
-
-	if (rds & UART_RDS_OE_MSK) {
-		/*
-		 * CHECK: does overrun affect the current character?
-		 * ASSUMPTION: it does not.
-		 */
-		tty_insert_flip_char(tty, ch, flg);
-		ch = 0;
-		flg = TTY_OVERRUN;
-	}
-#ifdef SUPPORT_SYSRQ
-	port->sysrq = 0;
-#endif
-	goto error_return;
-}
-
-static void uart00_tx_chars(struct uart_port *port)
-{
-	struct circ_buf *xmit = &port->info->xmit;
-	int count;
-
-	if (port->x_char) {
-		while ((UART_GET_TSR(port) & UART_TSR_TX_LEVEL_MSK) == 15)
-			barrier();
-		UART_PUT_CHAR(port, port->x_char);
-		port->icount.tx++;
-		port->x_char = 0;
-		return;
-	}
-	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
-		uart00_stop_tx(port);
-		return;
-	}
-
-	count = port->fifosize >> 1;
-	do {
-		while ((UART_GET_TSR(port) & UART_TSR_TX_LEVEL_MSK) == 15)
-			barrier();
-		UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
-		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-		port->icount.tx++;
-		if (uart_circ_empty(xmit))
-			break;
-	} while (--count > 0);
-
-	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-		uart_write_wakeup(port);
-
-	if (uart_circ_empty(xmit))
-		uart00_stop_tx(port);
-}
-
-static void uart00_start_tx(struct uart_port *port)
-{
-	UART_PUT_IES(port, UART_IES_TIE_MSK);
-	uart00_tx_chars(port);
-}
-
-static void uart00_modem_status(struct uart_port *port)
-{
-	unsigned int status;
-
-	status = UART_GET_MSR(port);
-
-	if (!(status & (UART_MSR_DCTS_MSK | UART_MSR_DDSR_MSK | 
-			UART_MSR_TERI_MSK | UART_MSR_DDCD_MSK)))
-		return;
-
-	if (status & UART_MSR_DDCD_MSK)
-		uart_handle_dcd_change(port, status & UART_MSR_DCD_MSK);
-
-	if (status & UART_MSR_DDSR_MSK)
-		port->icount.dsr++;
-
-	if (status & UART_MSR_DCTS_MSK)
-		uart_handle_cts_change(port, status & UART_MSR_CTS_MSK);
-
-	wake_up_interruptible(&port->info->delta_msr_wait);
-}
-
-static irqreturn_t uart00_int(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct uart_port *port = dev_id;
-	unsigned int status, pass_counter = 0;
-
-	status = UART_GET_INT_STATUS(port);
-	do {
-		if (status & UART_ISR_RI_MSK)
-			uart00_rx_chars(port, regs);
-		if (status & UART_ISR_MI_MSK)
-			uart00_modem_status(port);
-		if (status & (UART_ISR_TI_MSK | UART_ISR_TII_MSK))
-			uart00_tx_chars(port);
-		if (pass_counter++ > UART00_ISR_PASS_LIMIT)
-			break;
-
-		status = UART_GET_INT_STATUS(port);
-	} while (status);
-
-	return IRQ_HANDLED;
-}
-
-static unsigned int uart00_tx_empty(struct uart_port *port)
-{
-	return UART_GET_TSR(port) & UART_TSR_TX_LEVEL_MSK? 0 : TIOCSER_TEMT;
-}
-
-static unsigned int uart00_get_mctrl(struct uart_port *port)
-{
-	unsigned int result = 0;
-	unsigned int status;
-
-	status = UART_GET_MSR(port);
-	if (status & UART_MSR_DCD_MSK)
-		result |= TIOCM_CAR;
-	if (status & UART_MSR_DSR_MSK)
-		result |= TIOCM_DSR;
-	if (status & UART_MSR_CTS_MSK)
-		result |= TIOCM_CTS;
-	if (status & UART_MSR_RI_MSK)
-		result |= TIOCM_RI;
-
-	return result;
-}
-
-static void uart00_set_mctrl_null(struct uart_port *port, unsigned int mctrl)
-{
-}
-
-static void uart00_break_ctl(struct uart_port *port, int break_state)
-{
-	unsigned long flags;
-	unsigned int mcr;
-
-	spin_lock_irqsave(&port->lock, flags);
-	mcr = UART_GET_MCR(port);
-	if (break_state == -1)
-		mcr |= UART_MCR_BR_MSK;
-	else
-		mcr &= ~UART_MCR_BR_MSK;
-	UART_PUT_MCR(port, mcr);
-	spin_unlock_irqrestore(&port->lock, flags);
-}
-
-static void
-uart00_set_termios(struct uart_port *port, struct termios *termios,
-		   struct termios *old)
-{
-	unsigned int uart_mc, old_ies, baud, quot;
-	unsigned long flags;
-
-	/*
-	 * We don't support CREAD (yet)
-	 */
-	termios->c_cflag |= CREAD;
-
-	/*
-	 * Ask the core to calculate the divisor for us.
-	 */
-	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 
-	quot = uart_get_divisor(port, baud);
-
-	/* byte size and parity */
-	switch (termios->c_cflag & CSIZE) {
-	case CS5:
-		uart_mc = UART_MC_CLS_CHARLEN_5;
-		break;
-	case CS6:
-		uart_mc = UART_MC_CLS_CHARLEN_6;
-		break;
-	case CS7:
-		uart_mc = UART_MC_CLS_CHARLEN_7;
-		break;
-	default: // CS8
-		uart_mc = UART_MC_CLS_CHARLEN_8;
-		break;
-	}
-	if (termios->c_cflag & CSTOPB)
-		uart_mc|= UART_MC_ST_TWO;
-	if (termios->c_cflag & PARENB) {
-		uart_mc |= UART_MC_PE_MSK;
-		if (!(termios->c_cflag & PARODD))
-			uart_mc |= UART_MC_EP_MSK;
-	}
-
-	spin_lock_irqsave(&port->lock, flags);
-
-	/*
-	 * Update the per-port timeout.
-	 */
-	uart_update_timeout(port, termios->c_cflag, baud);
-
-	port->read_status_mask = UART_RDS_OE_MSK;
-	if (termios->c_iflag & INPCK)
-		port->read_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK;
-	if (termios->c_iflag & (BRKINT | PARMRK))
-		port->read_status_mask |= UART_RDS_BI_MSK;
-
-	/*
-	 * Characters to ignore
-	 */
-	port->ignore_status_mask = 0;
-	if (termios->c_iflag & IGNPAR)
-		port->ignore_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK;
-	if (termios->c_iflag & IGNBRK) {
-		port->ignore_status_mask |= UART_RDS_BI_MSK;
-		/*
-		 * If we're ignoring parity and break indicators,
-		 * ignore overruns to (for real raw support).
-		 */
-		if (termios->c_iflag & IGNPAR)
-			port->ignore_status_mask |= UART_RDS_OE_MSK;
-	}
-
-	/* first, disable everything */
-	old_ies = UART_GET_IES(port); 
-
-	if (UART_ENABLE_MS(port, termios->c_cflag))
-		old_ies |= UART_IES_ME_MSK;
-
-	/* Set baud rate */
-	UART_PUT_DIV_LO(port, (quot & 0xff));
-	UART_PUT_DIV_HI(port, ((quot & 0xf00) >> 8));
-
-	UART_PUT_MC(port, uart_mc);
-	UART_PUT_IES(port, old_ies);
-
-	spin_unlock_irqrestore(&port->lock, flags);
-}
-
-static int uart00_startup(struct uart_port *port)
-{
-	int result;
-
-	/*
-	 * Allocate the IRQ
-	 */
-	result = request_irq(port->irq, uart00_int, 0, "uart00", port);
-	if (result) {
-		printk(KERN_ERR "Request of irq %d failed\n", port->irq);
-		return result;
-	}
-
-	/*
-	 * Finally, enable interrupts. Use the TII interrupt to minimise 
-	 * the number of interrupts generated. If higher performance is 
-	 * needed, consider using the TI interrupt with a suitable FIFO
-	 * threshold
-	 */
-	UART_PUT_IES(port, UART_IES_RE_MSK | UART_IES_TIE_MSK);
-
-	return 0;
-}
-
-static void uart00_shutdown(struct uart_port *port)
-{
-	/*
-	 * disable all interrupts, disable the port
-	 */
-	UART_PUT_IEC(port, 0xff);
-
-	/* disable break condition and fifos */
-	UART_PUT_MCR(port, UART_GET_MCR(port) &~UART_MCR_BR_MSK);
-
-        /*
-	 * Free the interrupt
-	 */
-	free_irq(port->irq, port);
-}
-
-static const char *uart00_type(struct uart_port *port)
-{
-	return port->type == PORT_UART00 ? "Altera UART00" : NULL;
-}
-
-/*
- * Release the memory region(s) being used by 'port'
- */
-static void uart00_release_port(struct uart_port *port)
-{
-	release_mem_region(port->mapbase, UART_PORT_SIZE);
-
-#ifdef CONFIG_ARCH_CAMELOT
-	if (port->membase != (void*)IO_ADDRESS(EXC_UART00_BASE)) {
-		iounmap(port->membase);
-	}
-#endif
-}
-
-/*
- * Request the memory region(s) being used by 'port'
- */
-static int uart00_request_port(struct uart_port *port)
-{
-	return request_mem_region(port->mapbase, UART_PORT_SIZE, "serial_uart00")
-			!= NULL ? 0 : -EBUSY;
-}
-
-/*
- * Configure/autoconfigure the port.
- */
-static void uart00_config_port(struct uart_port *port, int flags)
-{
-
-	/*
-	 * Map the io memory if this is a soft uart
-	 */
-	if (!port->membase)
-		port->membase = ioremap_nocache(port->mapbase,SZ_4K);
-
-	if (!port->membase)
-		printk(KERN_ERR "serial00: cannot map io memory\n");
-	else
-		port->type = PORT_UART00;
-
-}
-
-/*
- * verify the new serial_struct (for TIOCSSERIAL).
- */
-static int uart00_verify_port(struct uart_port *port, struct serial_struct *ser)
-{
-	int ret = 0;
-	if (ser->type != PORT_UNKNOWN && ser->type != PORT_UART00)
-		ret = -EINVAL;
-	if (ser->irq < 0 || ser->irq >= NR_IRQS)
-		ret = -EINVAL;
-	if (ser->baud_base < 9600)
-		ret = -EINVAL;
-	return ret;
-}
-
-static struct uart_ops uart00_pops = {
-	.tx_empty	= uart00_tx_empty,
-	.set_mctrl	= uart00_set_mctrl_null,
-	.get_mctrl	= uart00_get_mctrl,
-	.stop_tx	= uart00_stop_tx,
-	.start_tx	= uart00_start_tx,
-	.stop_rx	= uart00_stop_rx,
-	.enable_ms	= uart00_enable_ms,
-	.break_ctl	= uart00_break_ctl,
-	.startup	= uart00_startup,
-	.shutdown	= uart00_shutdown,
-	.set_termios	= uart00_set_termios,
-	.type		= uart00_type,
-	.release_port	= uart00_release_port,
-	.request_port	= uart00_request_port,
-	.config_port	= uart00_config_port,
-	.verify_port	= uart00_verify_port,
-};
-
-
-#ifdef CONFIG_ARCH_CAMELOT
-static struct uart_port epxa10db_port = {
-	.membase	= (void*)IO_ADDRESS(EXC_UART00_BASE),
-	.mapbase	= EXC_UART00_BASE,
-	.iotype		= SERIAL_IO_MEM,
-	.irq		= IRQ_UART,
-	.uartclk	= EXC_AHB2_CLK_FREQUENCY,
-	.fifosize	= 16,
-	.ops		= &uart00_pops,
-	.flags		= ASYNC_BOOT_AUTOCONF,
-};
-#endif
-
-
-#ifdef CONFIG_SERIAL_UART00_CONSOLE
-static void uart00_console_write(struct console *co, const char *s, unsigned count)
-{
-#ifdef CONFIG_ARCH_CAMELOT
-	struct uart_port *port = &epxa10db_port;
-	unsigned int status, old_ies;
-	int i;
-
-	/*
-	 *	First save the CR then disable the interrupts
-	 */
-	old_ies = UART_GET_IES(port);
-	UART_PUT_IEC(port,0xff);
-
-	/*
-	 *	Now, do each character
-	 */
-	for (i = 0; i < count; i++) {
-		do {
-			status = UART_GET_TSR(port);
-		} while (!UART_TX_READY(status));
-		UART_PUT_CHAR(port, s[i]);
-		if (s[i] == '\n') {
-			do {
-				status = UART_GET_TSR(port);
-			} while (!UART_TX_READY(status));
-			UART_PUT_CHAR(port, '\r');
-		}
-	}
-
-	/*
-	 *	Finally, wait for transmitter to become empty
-	 *	and restore the IES
-	 */
-	do {
-		status = UART_GET_TSR(port);
-	} while (status & UART_TSR_TX_LEVEL_MSK);
-	UART_PUT_IES(port, old_ies);
-#endif
-}
-
-static void __init
-uart00_console_get_options(struct uart_port *port, int *baud,
-			   int *parity, int *bits)
-{
-	unsigned int uart_mc, quot;
-
-	uart_mc = UART_GET_MC(port);
-
-	*parity = 'n';
-	if (uart_mc & UART_MC_PE_MSK) {
-		if (uart_mc & UART_MC_EP_MSK)
-			*parity = 'e';
-		else
-			*parity = 'o';
-	}
-
-	switch (uart_mc & UART_MC_CLS_MSK) {
-	case UART_MC_CLS_CHARLEN_5:
-		*bits = 5;
-		break;
-	case UART_MC_CLS_CHARLEN_6:
-		*bits = 6;
-		break;
-	case UART_MC_CLS_CHARLEN_7:
-		*bits = 7;
-		break;
-	case UART_MC_CLS_CHARLEN_8:
-		*bits = 8;
-		break;
-	}
-	quot = UART_GET_DIV_LO(port) | (UART_GET_DIV_HI(port) << 8);
-	*baud = port->uartclk / (16 *quot );
-}
-
-static int __init uart00_console_setup(struct console *co, char *options)
-{
-	struct uart_port *port;
-	int baud = 115200;
-	int bits = 8;
-	int parity = 'n';
-	int flow = 'n';
-
-#ifdef CONFIG_ARCH_CAMELOT
-	port = &epxa10db_port;             ;
-#else
-	return -ENODEV;
-#endif
-	if (options)
-		uart_parse_options(options, &baud, &parity, &bits, &flow);
-	else
-		uart00_console_get_options(port, &baud, &parity, &bits);
-
-	return uart_set_options(port, co, baud, parity, bits, flow);
-}
-
-extern struct uart_driver uart00_reg;
-static struct console uart00_console = {
-	.name		= SERIAL_UART00_NAME,
-	.write		= uart00_console_write,
-	.device		= uart_console_device,
-	.setup		= uart00_console_setup,
-	.flags		= CON_PRINTBUFFER,
-	.index		= 0,
-	.data		= &uart00_reg,
-};
-
-static int __init uart00_console_init(void)
-{
-	register_console(&uart00_console);
-	return 0;
-}
-console_initcall(uart00_console_init);
-
-#define UART00_CONSOLE	&uart00_console
-#else
-#define UART00_CONSOLE	NULL
-#endif
-
-static struct uart_driver uart00_reg = {
-	.owner			= NULL,
-	.driver_name		= SERIAL_UART00_NAME,
-	.dev_name		= SERIAL_UART00_NAME,
-	.major			= SERIAL_UART00_MAJOR,
-	.minor			= SERIAL_UART00_MINOR,
-	.nr			= UART_NR,
-	.cons			= UART00_CONSOLE,
-};
-
-struct dev_port_entry{
-	unsigned int base_addr;
-	struct uart_port *port;
-};
-
-#ifdef CONFIG_PLD_HOTSWAP
-
-static struct dev_port_entry dev_port_map[UART_NR];
-
-/*
- * Keep a mapping of dev_info addresses -> port lines to use when
- * removing ports dev==NULL indicates unused entry
- */
-
-struct uart00_ps_data{
-	unsigned int clk;
-	unsigned int fifosize;
-};
-
-int uart00_add_device(struct pldhs_dev_info* dev_info, void* dev_ps_data)
-{
-	struct uart00_ps_data* dev_ps=dev_ps_data;
-	struct uart_port * port;
-	int i,result;
-
-	i=0;
-	while(dev_port_map[i].port)
-		i++;
-
-	if(i==UART_NR){
-		printk(KERN_WARNING "uart00: Maximum number of ports reached\n");
-		return 0;
-	}
-
-	port=kmalloc(sizeof(struct uart_port),GFP_KERNEL);
-	if(!port)
-		return -ENOMEM;
-
-	printk("clk=%d fifo=%d\n",dev_ps->clk,dev_ps->fifosize);
-	port->membase=0;
-	port->mapbase=dev_info->base_addr;
-	port->iotype=SERIAL_IO_MEM;
-	port->irq=dev_info->irq;
-	port->uartclk=dev_ps->clk;
-	port->fifosize=dev_ps->fifosize;
-	port->ops=&uart00_pops;
-	port->line=i;
-	port->flags=ASYNC_BOOT_AUTOCONF;
-
-	result=uart_add_one_port(&uart00_reg, port);
-	if(result){
-		printk("uart_add_one_port returned %d\n",result);
-		return result;
-	}
-	dev_port_map[i].base_addr=dev_info->base_addr;
-	dev_port_map[i].port=port;
-	printk("uart00: added device at %x as ttyUA%d\n",dev_port_map[i].base_addr,i);
-	return 0;
-
-}
-
-int uart00_remove_devices(void)
-{
-	int i,result;
-
-
-	result=0;
-	for(i=1;i<UART_NR;i++){
-		if(dev_port_map[i].base_addr){
-			result=uart_remove_one_port(&uart00_reg, dev_port_map[i].port);
-			if(result)
-				return result;
-
-			/* port removed sucessfully, so now tidy up */
-			kfree(dev_port_map[i].port);
-			dev_port_map[i].base_addr=0;
-			dev_port_map[i].port=NULL;
-		}
-	}
-	return 0;
-
-}
-
-struct pld_hotswap_ops uart00_pldhs_ops={
-	.name		= "uart00",
-	.add_device	= uart00_add_device,
-	.remove_devices	= uart00_remove_devices,
-};
-
-#endif
-
-static int __init uart00_init(void)
-{
-	int result;
-
-	printk(KERN_INFO "Serial: UART00 driver $Revision: 1.35 $\n");
-
-	printk(KERN_WARNING "serial_uart00:Using temporary major/minor pairs"
-		" - these WILL change in the future\n");
-
-	result = uart_register_driver(&uart00_reg);
-	if (result)
-		return result;
-#ifdef CONFIG_ARCH_CAMELOT
-	result = uart_add_one_port(&uart00_reg,&epxa10db_port);
-#endif
-	if (result)
-		uart_unregister_driver(&uart00_reg);
-
-#ifdef  CONFIG_PLD_HOTSWAP
-	pldhs_register_driver(&uart00_pldhs_ops);
-#endif
-	return result;
-}
-
-__initcall(uart00_init);
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index 4ddc4530..3cf945c 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -184,13 +184,13 @@
 	bus->d_inode->i_gid = busgid;
 	bus->d_inode->i_mode = S_IFDIR | busmode;
 
-	down(&bus->d_inode->i_sem);
+	mutex_lock(&bus->d_inode->i_mutex);
 
 	list_for_each_entry(dev, &bus->d_subdirs, d_u.d_child)
 		if (dev->d_inode)
 			update_dev(dev);
 
-	up(&bus->d_inode->i_sem);
+	mutex_unlock(&bus->d_inode->i_mutex);
 }
 
 static void update_sb(struct super_block *sb)
@@ -201,7 +201,7 @@
 	if (!root)
 		return;
 
-	down(&root->d_inode->i_sem);
+	mutex_lock(&root->d_inode->i_mutex);
 
 	list_for_each_entry(bus, &root->d_subdirs, d_u.d_child) {
 		if (bus->d_inode) {
@@ -219,7 +219,7 @@
 		}
 	}
 
-	up(&root->d_inode->i_sem);
+	mutex_unlock(&root->d_inode->i_mutex);
 }
 
 static int remount(struct super_block *sb, int *flags, char *data)
@@ -333,10 +333,10 @@
 static int usbfs_unlink (struct inode *dir, struct dentry *dentry)
 {
 	struct inode *inode = dentry->d_inode;
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	dentry->d_inode->i_nlink--;
 	dput(dentry);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	d_delete(dentry);
 	return 0;
 }
@@ -346,7 +346,7 @@
 	int error = -ENOTEMPTY;
 	struct inode * inode = dentry->d_inode;
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	dentry_unhash(dentry);
 	if (usbfs_empty(dentry)) {
 		dentry->d_inode->i_nlink -= 2;
@@ -355,7 +355,7 @@
 		dir->i_nlink--;
 		error = 0;
 	}
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	if (!error)
 		d_delete(dentry);
 	dput(dentry);
@@ -380,7 +380,7 @@
 {
 	loff_t retval = -EINVAL;
 
-	down(&file->f_dentry->d_inode->i_sem);
+	mutex_lock(&file->f_dentry->d_inode->i_mutex);
 	switch(orig) {
 	case 0:
 		if (offset > 0) {
@@ -397,7 +397,7 @@
 	default:
 		break;
 	}
-	up(&file->f_dentry->d_inode->i_sem);
+	mutex_unlock(&file->f_dentry->d_inode->i_mutex);
 	return retval;
 }
 
@@ -480,7 +480,7 @@
 	}
 
 	*dentry = NULL;
-	down(&parent->d_inode->i_sem);
+	mutex_lock(&parent->d_inode->i_mutex);
 	*dentry = lookup_one_len(name, parent, strlen(name));
 	if (!IS_ERR(dentry)) {
 		if ((mode & S_IFMT) == S_IFDIR)
@@ -489,7 +489,7 @@
 			error = usbfs_create (parent->d_inode, *dentry, mode);
 	} else
 		error = PTR_ERR(dentry);
-	up(&parent->d_inode->i_sem);
+	mutex_unlock(&parent->d_inode->i_mutex);
 
 	return error;
 }
@@ -528,7 +528,7 @@
 	if (!parent || !parent->d_inode)
 		return;
 
-	down(&parent->d_inode->i_sem);
+	mutex_lock(&parent->d_inode->i_mutex);
 	if (usbfs_positive(dentry)) {
 		if (dentry->d_inode) {
 			if (S_ISDIR(dentry->d_inode->i_mode))
@@ -538,7 +538,7 @@
 		dput(dentry);
 		}
 	}
-	up(&parent->d_inode->i_sem);
+	mutex_unlock(&parent->d_inode->i_mutex);
 }
 
 /* --------------------------------------------------------------------- */
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 0cea978..de59c58 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -1891,7 +1891,7 @@
 		return -EINVAL;
 
 	inode = filp->f_dentry->d_inode;
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	current->flags |= PF_SYNCWRITE;
 	rc = filemap_fdatawrite(inode->i_mapping);
 	err = filp->f_op->fsync(filp, filp->f_dentry, 1);
@@ -1901,7 +1901,7 @@
 	if (!rc)
 		rc = err;
 	current->flags &= ~PF_SYNCWRITE;
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	VLDBG(curlun, "fdatasync -> %d\n", rc);
 	return rc;
 }
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 5c40980..c6c279d 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -1562,10 +1562,10 @@
 		spin_unlock_irq (&dev->lock);
 
 		/* break link to dcache */
-		down (&parent->i_sem);
+		mutex_lock (&parent->i_mutex);
 		d_delete (dentry);
 		dput (dentry);
-		up (&parent->i_sem);
+		mutex_unlock (&parent->i_mutex);
 
 		/* fds may still be open */
 		goto restart;
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index ed1899d..be3fd9b 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -11,14 +11,14 @@
 	  The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0
 	  "high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware.
 	  If your USB host controller supports USB 2.0, you will likely want to
-	  configure this Host Controller Driver.  At this writing, the primary
-	  implementation of EHCI is a chip from NEC, widely available in add-on
-	  PCI cards, but implementations are in the works from other vendors
-	  including Intel and Philips.  Motherboard support is appearing.
+	  configure this Host Controller Driver.  At the time of this writing, 
+	  the primary implementation of EHCI is a chip from NEC, widely available
+	  in add-on PCI cards, but implementations are in the works from other 
+	  vendors including Intel and Philips.  Motherboard support is appearing.
 
 	  EHCI controllers are packaged with "companion" host controllers (OHCI
 	  or UHCI) to handle USB 1.1 devices connected to root hub ports.  Ports
-	  will connect to EHCI if it the device is high speed, otherwise they
+	  will connect to EHCI if the device is high speed, otherwise they
 	  connect to a companion controller.  If you configure EHCI, you should
 	  probably configure the OHCI (for NEC and some other vendors) USB Host
 	  Controller Driver or UHCI (for Via motherboards) Host Controller
diff --git a/drivers/usb/media/dsbr100.c b/drivers/usb/media/dsbr100.c
index 6a5700e..2564680 100644
--- a/drivers/usb/media/dsbr100.c
+++ b/drivers/usb/media/dsbr100.c
@@ -127,6 +127,7 @@
 	.open =		usb_dsbr100_open,
 	.release =     	usb_dsbr100_close,
 	.ioctl =        usb_dsbr100_ioctl,
+	.compat_ioctl = v4l_compat_ioctl32,
 	.llseek =       no_llseek,
 };
 
diff --git a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c
index 3a0e8ce..8af665b 100644
--- a/drivers/usb/media/ov511.c
+++ b/drivers/usb/media/ov511.c
@@ -4774,6 +4774,7 @@
 	.read =		ov51x_v4l1_read,
 	.mmap =		ov51x_v4l1_mmap,
 	.ioctl =	ov51x_v4l1_ioctl,
+	.compat_ioctl = v4l_compat_ioctl32,
 	.llseek =	no_llseek,
 };
 
diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c
index 09ca612..4f9b0dc 100644
--- a/drivers/usb/media/pwc/pwc-if.c
+++ b/drivers/usb/media/pwc/pwc-if.c
@@ -154,6 +154,7 @@
 	.poll =		pwc_video_poll,
 	.mmap =		pwc_video_mmap,
 	.ioctl =        pwc_video_ioctl,
+	.compat_ioctl = v4l_compat_ioctl32,
 	.llseek =       no_llseek,
 };
 static struct video_device pwc_template = {
diff --git a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c
index b2ae29a..2ba5622 100644
--- a/drivers/usb/media/se401.c
+++ b/drivers/usb/media/se401.c
@@ -1193,6 +1193,7 @@
         .read =         se401_read,
         .mmap =         se401_mmap,
 	.ioctl =        se401_ioctl,
+	.compat_ioctl = v4l_compat_ioctl32,
 	.llseek =       no_llseek,
 };
 static struct video_device se401_template = {
diff --git a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c
index 774038b..b497a6a 100644
--- a/drivers/usb/media/stv680.c
+++ b/drivers/usb/media/stv680.c
@@ -1343,6 +1343,7 @@
 	.read =		stv680_read,
 	.mmap =		stv680_mmap,
 	.ioctl =        stv680_ioctl,
+	.compat_ioctl = v4l_compat_ioctl32,
 	.llseek =       no_llseek,
 };
 static struct video_device stv680_template = {
diff --git a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c
index 4bd1133..63a72e5 100644
--- a/drivers/usb/media/usbvideo.c
+++ b/drivers/usb/media/usbvideo.c
@@ -953,6 +953,7 @@
 	.read =   usbvideo_v4l_read,
 	.mmap =   usbvideo_v4l_mmap,
 	.ioctl =  usbvideo_v4l_ioctl,
+	.compat_ioctl = v4l_compat_ioctl32,
 	.llseek = no_llseek,
 };
 static const struct video_device usbvideo_template = {
diff --git a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c
index 1c73155..5df1440 100644
--- a/drivers/usb/media/vicam.c
+++ b/drivers/usb/media/vicam.c
@@ -1236,6 +1236,7 @@
 	.read		= vicam_read,
 	.mmap		= vicam_mmap,
 	.ioctl		= vicam_ioctl,
+	.compat_ioctl	= v4l_compat_ioctl32,
 	.llseek		= no_llseek,
 };
 
diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c
index 3605a6f..bff9434 100644
--- a/drivers/usb/media/w9968cf.c
+++ b/drivers/usb/media/w9968cf.c
@@ -3490,6 +3490,7 @@
 	.release = w9968cf_release,
 	.read =    w9968cf_read,
 	.ioctl =   w9968cf_ioctl,
+	.compat_ioctl = v4l_compat_ioctl32,
 	.mmap =    w9968cf_mmap,
 	.llseek =  no_llseek,
 };
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index af18355..4e9637e 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -357,7 +357,7 @@
 			} while (retval != 5 && retval != ENODEV);
 
 			if (retval != 5) {
-				err("%s - failed to retreive serial line settings - %d", __FUNCTION__, retval);
+				err("%s - failed to retrieve serial line settings - %d", __FUNCTION__, retval);
 				return retval;
 			} else {
 				spin_lock_irqsave(&priv->lock, flags);
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 8bc8337..4dd6865 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -584,7 +584,7 @@
 	const struct usb_device_id *id;
 	struct usb_serial_driver *t;
 
-	/* List trough know devices and see if the usb id matches */
+	/* Check if the usb id matches a known device */
 	list_for_each(p, &usb_serial_driver_list) {
 		t = list_entry(p, struct usb_serial_driver, driver_list);
 		id = usb_match_id(iface, t->id_table);
diff --git a/drivers/video/aty/radeon_monitor.c b/drivers/video/aty/radeon_monitor.c
index ea7c863..7f9838d 100644
--- a/drivers/video/aty/radeon_monitor.c
+++ b/drivers/video/aty/radeon_monitor.c
@@ -423,7 +423,7 @@
 /*
  * Probe display on both primary and secondary card's connector (if any)
  * by various available techniques (i2c, OF device tree, BIOS, ...) and
- * try to retreive EDID. The algorithm here comes from XFree's radeon
+ * try to retrieve EDID. The algorithm here comes from XFree's radeon
  * driver
  */
 void __devinit radeon_probe_screens(struct radeonfb_info *rinfo,
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index a9300f9..55a3514 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -50,7 +50,6 @@
 #include <linux/init.h>
 
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
diff --git a/drivers/video/logo/Makefile b/drivers/video/logo/Makefile
index d0244c04..4ef5cd1 100644
--- a/drivers/video/logo/Makefile
+++ b/drivers/video/logo/Makefile
@@ -16,7 +16,7 @@
 
 # How to generate logo's
 
-# Use logo-cfiles to retreive list of .c files to be built
+# Use logo-cfiles to retrieve list of .c files to be built
 logo-cfiles = $(notdir $(patsubst %.$(2), %.c, \
               $(wildcard $(srctree)/$(src)/*$(1).$(2))))
 
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index 2ea1354..087e586 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -178,7 +178,6 @@
 
 #include <asm/hardware.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/mach-types.h>
 #include <asm/uaccess.h>
 #include <asm/arch/assabet.h>
@@ -1455,7 +1454,11 @@
 static int __init sa1100fb_probe(struct platform_device *pdev)
 {
 	struct sa1100fb_info *fbi;
-	int ret;
+	int ret, irq;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq <= 0)
+		return -EINVAL;
 
 	if (!request_mem_region(0xb0100000, 0x10000, "LCD"))
 		return -EBUSY;
@@ -1470,7 +1473,7 @@
 	if (ret)
 		goto failed;
 
-	ret = request_irq(IRQ_LCD, sa1100fb_handle_irq, SA_INTERRUPT,
+	ret = request_irq(irq, sa1100fb_handle_irq, SA_INTERRUPT,
 			  "LCD", fbi);
 	if (ret) {
 		printk(KERN_ERR "sa1100fb: request_irq failed: %d\n", ret);
@@ -1492,7 +1495,7 @@
 
 	ret = register_framebuffer(&fbi->fb);
 	if (ret < 0)
-		goto failed;
+		goto err_free_irq;
 
 #ifdef CONFIG_CPU_FREQ
 	fbi->freq_transition.notifier_call = sa1100fb_freq_transition;
@@ -1504,7 +1507,9 @@
 	/* This driver cannot be unloaded at the moment */
 	return 0;
 
-failed:
+ err_free_irq:
+	free_irq(irq, fbi);
+ failed:
 	platform_set_drvdata(pdev, NULL);
 	kfree(fbi);
 	release_mem_region(0xb0100000, 0x10000);
diff --git a/drivers/w1/Kconfig b/drivers/w1/Kconfig
index 9a1e00d..4baf61a 100644
--- a/drivers/w1/Kconfig
+++ b/drivers/w1/Kconfig
@@ -3,7 +3,7 @@
 config W1
 	tristate "Dallas's 1-wire support"
 	---help---
-	  Dallas's 1-wire bus is usefull to connect slow 1-pin devices
+	  Dallas's 1-wire bus is useful to connect slow 1-pin devices
 	  such as iButtons and thermal sensors.
 
 	  If you want W1 support, you should say Y here.
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index d933ef1..a17b288 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -663,7 +663,7 @@
 }
 
 /**
- * v9fs_vfs_getattr - retreive file metadata
+ * v9fs_vfs_getattr - retrieve file metadata
  * @mnt - mount information
  * @dentry - file to get attributes on
  * @stat - metadata structure to populate
diff --git a/fs/affs/inode.c b/fs/affs/inode.c
index 9ebe881..44d439c 100644
--- a/fs/affs/inode.c
+++ b/fs/affs/inode.c
@@ -244,10 +244,10 @@
 	pr_debug("AFFS: put_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
 	affs_free_prealloc(inode);
 	if (atomic_read(&inode->i_count) == 1) {
-		down(&inode->i_sem);
+		mutex_lock(&inode->i_mutex);
 		if (inode->i_size != AFFS_I(inode)->mmu_private)
 			affs_truncate(inode);
-		up(&inode->i_sem);
+		mutex_unlock(&inode->i_mutex);
 	}
 }
 
diff --git a/fs/autofs/root.c b/fs/autofs/root.c
index a1ab1c0..808134a 100644
--- a/fs/autofs/root.c
+++ b/fs/autofs/root.c
@@ -229,9 +229,9 @@
 	dentry->d_flags |= DCACHE_AUTOFS_PENDING;
 	d_add(dentry, NULL);
 
-	up(&dir->i_sem);
+	mutex_unlock(&dir->i_mutex);
 	autofs_revalidate(dentry, nd);
-	down(&dir->i_sem);
+	mutex_lock(&dir->i_mutex);
 
 	/*
 	 * If we are still pending, check if we had to handle
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 2241405..541b19e 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -489,9 +489,9 @@
 	d_add(dentry, NULL);
 
 	if (dentry->d_op && dentry->d_op->d_revalidate) {
-		up(&dir->i_sem);
+		mutex_unlock(&dir->i_mutex);
 		(dentry->d_op->d_revalidate)(dentry, nd);
-		down(&dir->i_sem);
+		mutex_lock(&dir->i_mutex);
 	}
 
 	/*
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 2568eb4..9ccc7d8 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -588,11 +588,11 @@
 		case 2: set_bit(Enabled, &e->flags);
 			break;
 		case 3: root = dget(file->f_vfsmnt->mnt_sb->s_root);
-			down(&root->d_inode->i_sem);
+			mutex_lock(&root->d_inode->i_mutex);
 
 			kill_node(e);
 
-			up(&root->d_inode->i_sem);
+			mutex_unlock(&root->d_inode->i_mutex);
 			dput(root);
 			break;
 		default: return res;
@@ -622,7 +622,7 @@
 		return PTR_ERR(e);
 
 	root = dget(sb->s_root);
-	down(&root->d_inode->i_sem);
+	mutex_lock(&root->d_inode->i_mutex);
 	dentry = lookup_one_len(e->name, root, strlen(e->name));
 	err = PTR_ERR(dentry);
 	if (IS_ERR(dentry))
@@ -658,7 +658,7 @@
 out2:
 	dput(dentry);
 out:
-	up(&root->d_inode->i_sem);
+	mutex_unlock(&root->d_inode->i_mutex);
 	dput(root);
 
 	if (err) {
@@ -703,12 +703,12 @@
 		case 1: enabled = 0; break;
 		case 2: enabled = 1; break;
 		case 3: root = dget(file->f_vfsmnt->mnt_sb->s_root);
-			down(&root->d_inode->i_sem);
+			mutex_lock(&root->d_inode->i_mutex);
 
 			while (!list_empty(&entries))
 				kill_node(list_entry(entries.next, Node, list));
 
-			up(&root->d_inode->i_sem);
+			mutex_unlock(&root->d_inode->i_mutex);
 			dput(root);
 		default: return res;
 	}
diff --git a/fs/block_dev.c b/fs/block_dev.c
index e0df94c..6e50346 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -202,7 +202,7 @@
 	loff_t size;
 	loff_t retval;
 
-	down(&bd_inode->i_sem);
+	mutex_lock(&bd_inode->i_mutex);
 	size = i_size_read(bd_inode);
 
 	switch (origin) {
@@ -219,7 +219,7 @@
 		}
 		retval = offset;
 	}
-	up(&bd_inode->i_sem);
+	mutex_unlock(&bd_inode->i_mutex);
 	return retval;
 }
 	
diff --git a/fs/buffer.c b/fs/buffer.c
index 55f0975a..6466bc8a 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -352,11 +352,11 @@
 	 * We need to protect against concurrent writers,
 	 * which could cause livelocks in fsync_buffers_list
 	 */
-	down(&mapping->host->i_sem);
+	mutex_lock(&mapping->host->i_mutex);
 	err = file->f_op->fsync(file, file->f_dentry, datasync);
 	if (!ret)
 		ret = err;
-	up(&mapping->host->i_sem);
+	mutex_unlock(&mapping->host->i_mutex);
 	err = filemap_fdatawait(mapping);
 	if (!ret)
 		ret = err;
@@ -2338,7 +2338,7 @@
 	__block_commit_write(inode,page,from,to);
 	/*
 	 * No need to use i_size_read() here, the i_size
-	 * cannot change under us because we hold i_sem.
+	 * cannot change under us because we hold i_mutex.
 	 */
 	if (pos > inode->i_size) {
 		i_size_write(inode, pos);
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 2a13a2b..e10213b 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -860,9 +860,9 @@
 				DeleteOplockQEntry(oplock_item);
 				/* can not grab inode sem here since it would
 				deadlock when oplock received on delete 
-				since vfs_unlink holds the i_sem across
+				since vfs_unlink holds the i_mutex across
 				the call */
-				/* down(&inode->i_sem);*/
+				/* mutex_lock(&inode->i_mutex);*/
 				if (S_ISREG(inode->i_mode)) {
 					rc = filemap_fdatawrite(inode->i_mapping);
 					if(CIFS_I(inode)->clientCanCacheRead == 0) {
@@ -871,7 +871,7 @@
 					}
 				} else
 					rc = 0;
-				/* up(&inode->i_sem);*/
+				/* mutex_unlock(&inode->i_mutex);*/
 				if (rc)
 					CIFS_I(inode)->write_behind_rc = rc;
 				cFYI(1,("Oplock flush inode %p rc %d",inode,rc));
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 9558f51..3ebce94 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1040,9 +1040,9 @@
 	}
 
 	/* can not grab this sem since kernel filesys locking documentation
-	   indicates i_sem may be taken by the kernel on lookup and rename
-	   which could deadlock if we grab the i_sem here as well */
-/*	down(&direntry->d_inode->i_sem);*/
+	   indicates i_mutex may be taken by the kernel on lookup and rename
+	   which could deadlock if we grab the i_mutex here as well */
+/*	mutex_lock(&direntry->d_inode->i_mutex);*/
 	/* need to write out dirty pages here  */
 	if (direntry->d_inode->i_mapping) {
 		/* do we need to lock inode until after invalidate completes
@@ -1066,7 +1066,7 @@
 			}
 		}
 	}
-/*	up(&direntry->d_inode->i_sem); */
+/*	mutex_unlock(&direntry->d_inode->i_mutex); */
 	
 	kfree(full_path);
 	FreeXid(xid);
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index 2391766..8f1a517 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -453,7 +453,7 @@
 	coda_vfs_stat.readdir++;
 
 	host_inode = host_file->f_dentry->d_inode;
-	down(&host_inode->i_sem);
+	mutex_lock(&host_inode->i_mutex);
 	host_file->f_pos = coda_file->f_pos;
 
 	if (!host_file->f_op->readdir) {
@@ -475,7 +475,7 @@
 	}
 out:
 	coda_file->f_pos = host_file->f_pos;
-	up(&host_inode->i_sem);
+	mutex_unlock(&host_inode->i_mutex);
 
 	return ret;
 }
diff --git a/fs/coda/file.c b/fs/coda/file.c
index e6bc022..30b4630 100644
--- a/fs/coda/file.c
+++ b/fs/coda/file.c
@@ -77,14 +77,14 @@
 		return -EINVAL;
 
 	host_inode = host_file->f_dentry->d_inode;
-	down(&coda_inode->i_sem);
+	mutex_lock(&coda_inode->i_mutex);
 
 	ret = host_file->f_op->write(host_file, buf, count, ppos);
 
 	coda_inode->i_size = host_inode->i_size;
 	coda_inode->i_blocks = (coda_inode->i_size + 511) >> 9;
 	coda_inode->i_mtime = coda_inode->i_ctime = CURRENT_TIME_SEC;
-	up(&coda_inode->i_sem);
+	mutex_unlock(&coda_inode->i_mutex);
 
 	return ret;
 }
@@ -272,9 +272,9 @@
 	if (host_file->f_op && host_file->f_op->fsync) {
 		host_dentry = host_file->f_dentry;
 		host_inode = host_dentry->d_inode;
-		down(&host_inode->i_sem);
+		mutex_lock(&host_inode->i_mutex);
 		err = host_file->f_op->fsync(host_file, host_dentry, datasync);
-		up(&host_inode->i_sem);
+		mutex_unlock(&host_inode->i_mutex);
 	}
 
 	if ( !err && !datasync ) {
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 43a2508..55d9a3a 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -207,244 +207,6 @@
 	return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg));
 }
 
-struct video_tuner32 {
-	compat_int_t tuner;
-	char name[32];
-	compat_ulong_t rangelow, rangehigh;
-	u32 flags;	/* It is really u32 in videodev.h */
-	u16 mode, signal;
-};
-
-static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up)
-{
-	int i;
-
-	if(get_user(kp->tuner, &up->tuner))
-		return -EFAULT;
-	for(i = 0; i < 32; i++)
-		__get_user(kp->name[i], &up->name[i]);
-	__get_user(kp->rangelow, &up->rangelow);
-	__get_user(kp->rangehigh, &up->rangehigh);
-	__get_user(kp->flags, &up->flags);
-	__get_user(kp->mode, &up->mode);
-	__get_user(kp->signal, &up->signal);
-	return 0;
-}
-
-static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up)
-{
-	int i;
-
-	if(put_user(kp->tuner, &up->tuner))
-		return -EFAULT;
-	for(i = 0; i < 32; i++)
-		__put_user(kp->name[i], &up->name[i]);
-	__put_user(kp->rangelow, &up->rangelow);
-	__put_user(kp->rangehigh, &up->rangehigh);
-	__put_user(kp->flags, &up->flags);
-	__put_user(kp->mode, &up->mode);
-	__put_user(kp->signal, &up->signal);
-	return 0;
-}
-
-struct video_buffer32 {
-	compat_caddr_t base;
-	compat_int_t height, width, depth, bytesperline;
-};
-
-static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up)
-{
-	u32 tmp;
-
-	if (get_user(tmp, &up->base))
-		return -EFAULT;
-
-	/* This is actually a physical address stored
-	 * as a void pointer.
-	 */
-	kp->base = (void *)(unsigned long) tmp;
-
-	__get_user(kp->height, &up->height);
-	__get_user(kp->width, &up->width);
-	__get_user(kp->depth, &up->depth);
-	__get_user(kp->bytesperline, &up->bytesperline);
-	return 0;
-}
-
-static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up)
-{
-	u32 tmp = (u32)((unsigned long)kp->base);
-
-	if(put_user(tmp, &up->base))
-		return -EFAULT;
-	__put_user(kp->height, &up->height);
-	__put_user(kp->width, &up->width);
-	__put_user(kp->depth, &up->depth);
-	__put_user(kp->bytesperline, &up->bytesperline);
-	return 0;
-}
-
-struct video_clip32 {
-	s32 x, y, width, height;	/* Its really s32 in videodev.h */
-	compat_caddr_t next;
-};
-
-struct video_window32 {
-	u32 x, y, width, height, chromakey, flags;
-	compat_caddr_t clips;
-	compat_int_t clipcount;
-};
-
-/* You get back everything except the clips... */
-static int put_video_window32(struct video_window *kp, struct video_window32 __user *up)
-{
-	if(put_user(kp->x, &up->x))
-		return -EFAULT;
-	__put_user(kp->y, &up->y);
-	__put_user(kp->width, &up->width);
-	__put_user(kp->height, &up->height);
-	__put_user(kp->chromakey, &up->chromakey);
-	__put_user(kp->flags, &up->flags);
-	__put_user(kp->clipcount, &up->clipcount);
-	return 0;
-}
-
-#define VIDIOCGTUNER32		_IOWR('v',4, struct video_tuner32)
-#define VIDIOCSTUNER32		_IOW('v',5, struct video_tuner32)
-#define VIDIOCGWIN32		_IOR('v',9, struct video_window32)
-#define VIDIOCSWIN32		_IOW('v',10, struct video_window32)
-#define VIDIOCGFBUF32		_IOR('v',11, struct video_buffer32)
-#define VIDIOCSFBUF32		_IOW('v',12, struct video_buffer32)
-#define VIDIOCGFREQ32		_IOR('v',14, u32)
-#define VIDIOCSFREQ32		_IOW('v',15, u32)
-
-enum {
-	MaxClips = (~0U-sizeof(struct video_window))/sizeof(struct video_clip)
-};
-
-static int do_set_window(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-	struct video_window32 __user *up = compat_ptr(arg);
-	struct video_window __user *vw;
-	struct video_clip __user *p;
-	int nclips;
-	u32 n;
-
-	if (get_user(nclips, &up->clipcount))
-		return -EFAULT;
-
-	/* Peculiar interface... */
-	if (nclips < 0)
-		nclips = VIDEO_CLIPMAP_SIZE;
-
-	if (nclips > MaxClips)
-		return -ENOMEM;
-
-	vw = compat_alloc_user_space(sizeof(struct video_window) +
-				    nclips * sizeof(struct video_clip));
-
-	p = nclips ? (struct video_clip __user *)(vw + 1) : NULL;
-
-	if (get_user(n, &up->x) || put_user(n, &vw->x) ||
-	    get_user(n, &up->y) || put_user(n, &vw->y) ||
-	    get_user(n, &up->width) || put_user(n, &vw->width) ||
-	    get_user(n, &up->height) || put_user(n, &vw->height) ||
-	    get_user(n, &up->chromakey) || put_user(n, &vw->chromakey) ||
-	    get_user(n, &up->flags) || put_user(n, &vw->flags) ||
-	    get_user(n, &up->clipcount) || put_user(n, &vw->clipcount) ||
-	    get_user(n, &up->clips) || put_user(p, &vw->clips))
-		return -EFAULT;
-
-	if (nclips) {
-		struct video_clip32 __user *u = compat_ptr(n);
-		int i;
-		if (!u)
-			return -EINVAL;
-		for (i = 0; i < nclips; i++, u++, p++) {
-			s32 v;
-			if (get_user(v, &u->x) ||
-			    put_user(v, &p->x) ||
-			    get_user(v, &u->y) ||
-			    put_user(v, &p->y) ||
-			    get_user(v, &u->width) ||
-			    put_user(v, &p->width) ||
-			    get_user(v, &u->height) ||
-			    put_user(v, &p->height) ||
-			    put_user(NULL, &p->next))
-				return -EFAULT;
-		}
-	}
-
-	return sys_ioctl(fd, VIDIOCSWIN, (unsigned long)p);
-}
-
-static int do_video_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-	union {
-		struct video_tuner vt;
-		struct video_buffer vb;
-		struct video_window vw;
-		unsigned long vx;
-	} karg;
-	mm_segment_t old_fs = get_fs();
-	void __user *up = compat_ptr(arg);
-	int err = 0;
-
-	/* First, convert the command. */
-	switch(cmd) {
-	case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break;
-	case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break;
-	case VIDIOCGWIN32: cmd = VIDIOCGWIN; break;
-	case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break;
-	case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break;
-	case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break;
-	case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break;
-	};
-
-	switch(cmd) {
-	case VIDIOCSTUNER:
-	case VIDIOCGTUNER:
-		err = get_video_tuner32(&karg.vt, up);
-		break;
-
-	case VIDIOCSFBUF:
-		err = get_video_buffer32(&karg.vb, up);
-		break;
-
-	case VIDIOCSFREQ:
-		err = get_user(karg.vx, (u32 __user *)up);
-		break;
-	};
-	if(err)
-		goto out;
-
-	set_fs(KERNEL_DS);
-	err = sys_ioctl(fd, cmd, (unsigned long)&karg);
-	set_fs(old_fs);
-
-	if(err == 0) {
-		switch(cmd) {
-		case VIDIOCGTUNER:
-			err = put_video_tuner32(&karg.vt, up);
-			break;
-
-		case VIDIOCGWIN:
-			err = put_video_window32(&karg.vw, up);
-			break;
-
-		case VIDIOCGFBUF:
-			err = put_video_buffer32(&karg.vb, up);
-			break;
-
-		case VIDIOCGFREQ:
-			err = put_user(((u32)karg.vx), (u32 __user *)up);
-			break;
-		};
-	}
-out:
-	return err;
-}
-
 struct compat_dmx_event {
 	dmx_event_t	event;
 	compat_time_t	timeStamp;
@@ -3015,14 +2777,6 @@
 #ifdef CONFIG_JBD_DEBUG
 HANDLE_IOCTL(EXT3_IOC32_WAIT_FOR_READONLY, do_ext3_ioctl)
 #endif
-HANDLE_IOCTL(VIDIOCGTUNER32, do_video_ioctl)
-HANDLE_IOCTL(VIDIOCSTUNER32, do_video_ioctl)
-HANDLE_IOCTL(VIDIOCGWIN32, do_video_ioctl)
-HANDLE_IOCTL(VIDIOCSWIN32, do_set_window)
-HANDLE_IOCTL(VIDIOCGFBUF32, do_video_ioctl)
-HANDLE_IOCTL(VIDIOCSFBUF32, do_video_ioctl)
-HANDLE_IOCTL(VIDIOCGFREQ32, do_video_ioctl)
-HANDLE_IOCTL(VIDIOCSFREQ32, do_video_ioctl)
 /* One SMB ioctl needs translations. */
 #define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t)
 HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid)
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index e48b539..b668ec6 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -288,10 +288,10 @@
 
 /*
  * Only subdirectories count here.  Files (CONFIGFS_NOT_PINNED) are
- * attributes and are removed by rmdir().  We recurse, taking i_sem
+ * attributes and are removed by rmdir().  We recurse, taking i_mutex
  * on all children that are candidates for default detach.  If the
  * result is clean, then configfs_detach_group() will handle dropping
- * i_sem.  If there is an error, the caller will clean up the i_sem
+ * i_mutex.  If there is an error, the caller will clean up the i_mutex
  * holders via configfs_detach_rollback().
  */
 static int configfs_detach_prep(struct dentry *dentry)
@@ -309,8 +309,8 @@
 		if (sd->s_type & CONFIGFS_NOT_PINNED)
 			continue;
 		if (sd->s_type & CONFIGFS_USET_DEFAULT) {
-			down(&sd->s_dentry->d_inode->i_sem);
-			/* Mark that we've taken i_sem */
+			mutex_lock(&sd->s_dentry->d_inode->i_mutex);
+			/* Mark that we've taken i_mutex */
 			sd->s_type |= CONFIGFS_USET_DROPPING;
 
 			ret = configfs_detach_prep(sd->s_dentry);
@@ -327,7 +327,7 @@
 }
 
 /*
- * Walk the tree, dropping i_sem wherever CONFIGFS_USET_DROPPING is
+ * Walk the tree, dropping i_mutex wherever CONFIGFS_USET_DROPPING is
  * set.
  */
 static void configfs_detach_rollback(struct dentry *dentry)
@@ -341,7 +341,7 @@
 
 			if (sd->s_type & CONFIGFS_USET_DROPPING) {
 				sd->s_type &= ~CONFIGFS_USET_DROPPING;
-				up(&sd->s_dentry->d_inode->i_sem);
+				mutex_unlock(&sd->s_dentry->d_inode->i_mutex);
 			}
 		}
 	}
@@ -424,11 +424,11 @@
 
 		/*
 		 * From rmdir/unregister, a configfs_detach_prep() pass
-		 * has taken our i_sem for us.  Drop it.
+		 * has taken our i_mutex for us.  Drop it.
 		 * From mkdir/register cleanup, there is no sem held.
 		 */
 		if (sd->s_type & CONFIGFS_USET_DROPPING)
-			up(&child->d_inode->i_sem);
+			mutex_unlock(&child->d_inode->i_mutex);
 
 		d_delete(child);
 		dput(child);
@@ -493,11 +493,11 @@
 		/* FYI, we're faking mkdir here
 		 * I'm not sure we need this semaphore, as we're called
 		 * from our parent's mkdir.  That holds our parent's
-		 * i_sem, so afaik lookup cannot continue through our
+		 * i_mutex, so afaik lookup cannot continue through our
 		 * parent to find us, let alone mess with our tree.
-		 * That said, taking our i_sem is closer to mkdir
+		 * That said, taking our i_mutex is closer to mkdir
 		 * emulation, and shouldn't hurt. */
-		down(&dentry->d_inode->i_sem);
+		mutex_lock(&dentry->d_inode->i_mutex);
 
 		for (i = 0; group->default_groups[i]; i++) {
 			new_group = group->default_groups[i];
@@ -507,7 +507,7 @@
 				break;
 		}
 
-		up(&dentry->d_inode->i_sem);
+		mutex_unlock(&dentry->d_inode->i_mutex);
 	}
 
 	if (ret)
@@ -856,7 +856,7 @@
 	down_write(&configfs_rename_sem);
 	parent = item->parent->dentry;
 
-	down(&parent->d_inode->i_sem);
+	mutex_lock(&parent->d_inode->i_mutex);
 
 	new_dentry = lookup_one_len(new_name, parent, strlen(new_name));
 	if (!IS_ERR(new_dentry)) {
@@ -872,7 +872,7 @@
 			error = -EEXIST;
 		dput(new_dentry);
 	}
-	up(&parent->d_inode->i_sem);
+	mutex_unlock(&parent->d_inode->i_mutex);
 	up_write(&configfs_rename_sem);
 
 	return error;
@@ -884,9 +884,9 @@
 	struct dentry * dentry = file->f_dentry;
 	struct configfs_dirent * parent_sd = dentry->d_fsdata;
 
-	down(&dentry->d_inode->i_sem);
+	mutex_lock(&dentry->d_inode->i_mutex);
 	file->private_data = configfs_new_dirent(parent_sd, NULL);
-	up(&dentry->d_inode->i_sem);
+	mutex_unlock(&dentry->d_inode->i_mutex);
 
 	return file->private_data ? 0 : -ENOMEM;
 
@@ -897,9 +897,9 @@
 	struct dentry * dentry = file->f_dentry;
 	struct configfs_dirent * cursor = file->private_data;
 
-	down(&dentry->d_inode->i_sem);
+	mutex_lock(&dentry->d_inode->i_mutex);
 	list_del_init(&cursor->s_sibling);
-	up(&dentry->d_inode->i_sem);
+	mutex_unlock(&dentry->d_inode->i_mutex);
 
 	release_configfs_dirent(cursor);
 
@@ -975,7 +975,7 @@
 {
 	struct dentry * dentry = file->f_dentry;
 
-	down(&dentry->d_inode->i_sem);
+	mutex_lock(&dentry->d_inode->i_mutex);
 	switch (origin) {
 		case 1:
 			offset += file->f_pos;
@@ -983,7 +983,7 @@
 			if (offset >= 0)
 				break;
 		default:
-			up(&file->f_dentry->d_inode->i_sem);
+			mutex_unlock(&file->f_dentry->d_inode->i_mutex);
 			return -EINVAL;
 	}
 	if (offset != file->f_pos) {
@@ -1007,7 +1007,7 @@
 			list_add_tail(&cursor->s_sibling, p);
 		}
 	}
-	up(&dentry->d_inode->i_sem);
+	mutex_unlock(&dentry->d_inode->i_mutex);
 	return offset;
 }
 
@@ -1037,7 +1037,7 @@
 	sd = configfs_sb->s_root->d_fsdata;
 	link_group(to_config_group(sd->s_element), group);
 
-	down(&configfs_sb->s_root->d_inode->i_sem);
+	mutex_lock(&configfs_sb->s_root->d_inode->i_mutex);
 
 	name.name = group->cg_item.ci_name;
 	name.len = strlen(name.name);
@@ -1057,7 +1057,7 @@
 	else
 		d_delete(dentry);
 
-	up(&configfs_sb->s_root->d_inode->i_sem);
+	mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex);
 
 	if (dentry) {
 	    dput(dentry);
@@ -1079,18 +1079,18 @@
 		return;
 	}
 
-	down(&configfs_sb->s_root->d_inode->i_sem);
-	down(&dentry->d_inode->i_sem);
+	mutex_lock(&configfs_sb->s_root->d_inode->i_mutex);
+	mutex_lock(&dentry->d_inode->i_mutex);
 	if (configfs_detach_prep(dentry)) {
 		printk(KERN_ERR "configfs: Tried to unregister non-empty subsystem!\n");
 	}
 	configfs_detach_group(&group->cg_item);
 	dentry->d_inode->i_flags |= S_DEAD;
-	up(&dentry->d_inode->i_sem);
+	mutex_unlock(&dentry->d_inode->i_mutex);
 
 	d_delete(dentry);
 
-	up(&configfs_sb->s_root->d_inode->i_sem);
+	mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex);
 
 	dput(dentry);
 
diff --git a/fs/configfs/file.c b/fs/configfs/file.c
index af1ffc9..c26cd61 100644
--- a/fs/configfs/file.c
+++ b/fs/configfs/file.c
@@ -336,9 +336,9 @@
 	umode_t mode = (attr->ca_mode & S_IALLUGO) | S_IFREG;
 	int error = 0;
 
-	down(&dir->d_inode->i_sem);
+	mutex_lock(&dir->d_inode->i_mutex);
 	error = configfs_make_dirent(parent_sd, NULL, (void *) attr, mode, type);
-	up(&dir->d_inode->i_sem);
+	mutex_unlock(&dir->d_inode->i_mutex);
 
 	return error;
 }
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c
index 6b274c6..6577c58 100644
--- a/fs/configfs/inode.c
+++ b/fs/configfs/inode.c
@@ -122,7 +122,7 @@
 
 /*
  * Unhashes the dentry corresponding to given configfs_dirent
- * Called with parent inode's i_sem held.
+ * Called with parent inode's i_mutex held.
  */
 void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent)
 {
@@ -145,7 +145,7 @@
 	struct configfs_dirent * sd;
 	struct configfs_dirent * parent_sd = dir->d_fsdata;
 
-	down(&dir->d_inode->i_sem);
+	mutex_lock(&dir->d_inode->i_mutex);
 	list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
 		if (!sd->s_element)
 			continue;
@@ -156,7 +156,7 @@
 			break;
 		}
 	}
-	up(&dir->d_inode->i_sem);
+	mutex_unlock(&dir->d_inode->i_mutex);
 }
 
 
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index a86ac4a..d4f1a2c 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -146,7 +146,7 @@
 	}
 
 	*dentry = NULL;
-	down(&parent->d_inode->i_sem);
+	mutex_lock(&parent->d_inode->i_mutex);
 	*dentry = lookup_one_len(name, parent, strlen(name));
 	if (!IS_ERR(dentry)) {
 		if ((mode & S_IFMT) == S_IFDIR)
@@ -155,7 +155,7 @@
 			error = debugfs_create(parent->d_inode, *dentry, mode);
 	} else
 		error = PTR_ERR(dentry);
-	up(&parent->d_inode->i_sem);
+	mutex_unlock(&parent->d_inode->i_mutex);
 
 	return error;
 }
@@ -273,7 +273,7 @@
 	if (!parent || !parent->d_inode)
 		return;
 
-	down(&parent->d_inode->i_sem);
+	mutex_lock(&parent->d_inode->i_mutex);
 	if (debugfs_positive(dentry)) {
 		if (dentry->d_inode) {
 			if (S_ISDIR(dentry->d_inode->i_mode))
@@ -283,7 +283,7 @@
 		dput(dentry);
 		}
 	}
-	up(&parent->d_inode->i_sem);
+	mutex_unlock(&parent->d_inode->i_mutex);
 	simple_release_fs(&debugfs_mount, &debugfs_mount_count);
 }
 EXPORT_SYMBOL_GPL(debugfs_remove);
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index 1274422..b621521 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -2162,27 +2162,27 @@
 	 *
 	 * make sure that
 	 *   d_instantiate always runs under lock
-	 *   we release i_sem lock before going to sleep
+	 *   we release i_mutex lock before going to sleep
 	 *
 	 * unfortunately sometimes d_revalidate is called with
-	 * and sometimes without i_sem lock held. The following checks
+	 * and sometimes without i_mutex lock held. The following checks
 	 * attempt to deduce when we need to add (and drop resp.) lock
 	 * here. This relies on current (2.6.2) calling coventions:
 	 *
-	 *   lookup_hash is always run under i_sem and is passing NULL
+	 *   lookup_hash is always run under i_mutex and is passing NULL
 	 *   as nd
 	 *
-	 *   open(...,O_CREATE,...) calls _lookup_hash under i_sem
+	 *   open(...,O_CREATE,...) calls _lookup_hash under i_mutex
 	 *   and sets flags to LOOKUP_OPEN|LOOKUP_CREATE
 	 *
 	 *   all other invocations of ->d_revalidate seem to happen
-	 *   outside of i_sem
+	 *   outside of i_mutex
 	 */
 	need_lock = nd &&
 	    (!(nd->flags & LOOKUP_CREATE) || (nd->flags & LOOKUP_PARENT));
 
 	if (need_lock)
-		down(&dir->i_sem);
+		mutex_lock(&dir->i_mutex);
 
 	if (is_devfsd_or_child(fs_info)) {
 		devfs_handle_t de = lookup_info->de;
@@ -2221,9 +2221,9 @@
 		add_wait_queue(&lookup_info->wait_queue, &wait);
 		read_unlock(&parent->u.dir.lock);
 		/* at this point it is always (hopefully) locked */
-		up(&dir->i_sem);
+		mutex_unlock(&dir->i_mutex);
 		schedule();
-		down(&dir->i_sem);
+		mutex_lock(&dir->i_mutex);
 		/*
 		 * This does not need nor should remove wait from wait_queue.
 		 * Wait queue head is never reused - nothing is ever added to it
@@ -2238,7 +2238,7 @@
 
       out:
 	if (need_lock)
-		up(&dir->i_sem);
+		mutex_unlock(&dir->i_mutex);
 	return 1;
 }				/*  End Function devfs_d_revalidate_wait  */
 
@@ -2284,9 +2284,9 @@
 	/*  Unlock directory semaphore, which will release any waiters. They
 	   will get the hashed dentry, and may be forced to wait for
 	   revalidation  */
-	up(&dir->i_sem);
+	mutex_unlock(&dir->i_mutex);
 	wait_for_devfsd_finished(fs_info);	/*  If I'm not devfsd, must wait  */
-	down(&dir->i_sem);	/*  Grab it again because them's the rules  */
+	mutex_lock(&dir->i_mutex);	/*  Grab it again because them's the rules  */
 	de = lookup_info.de;
 	/*  If someone else has been so kind as to make the inode, we go home
 	   early  */
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index f2be44d..bfb8a23 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -130,7 +130,7 @@
 {
 	char s[12];
 	struct dentry *root = devpts_root;
-	down(&root->d_inode->i_sem);
+	mutex_lock(&root->d_inode->i_mutex);
 	return lookup_one_len(s, root, sprintf(s, "%d", num));
 }
 
@@ -161,7 +161,7 @@
 	if (!IS_ERR(dentry) && !dentry->d_inode)
 		d_instantiate(dentry, inode);
 
-	up(&devpts_root->d_inode->i_sem);
+	mutex_unlock(&devpts_root->d_inode->i_mutex);
 
 	return 0;
 }
@@ -178,7 +178,7 @@
 		dput(dentry);
 	}
 
-	up(&devpts_root->d_inode->i_sem);
+	mutex_unlock(&devpts_root->d_inode->i_mutex);
 
 	return tty;
 }
@@ -196,7 +196,7 @@
 		}
 		dput(dentry);
 	}
-	up(&devpts_root->d_inode->i_sem);
+	mutex_unlock(&devpts_root->d_inode->i_mutex);
 }
 
 static int __init init_devpts_fs(void)
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 3931e7f..30dbbd1 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -56,7 +56,7 @@
  * lock_type is DIO_LOCKING for regular files on direct-IO-naive filesystems.
  * This determines whether we need to do the fancy locking which prevents
  * direct-IO from being able to read uninitialised disk blocks.  If its zero
- * (blockdev) this locking is not done, and if it is DIO_OWN_LOCKING i_sem is
+ * (blockdev) this locking is not done, and if it is DIO_OWN_LOCKING i_mutex is
  * not held for the entire direct write (taken briefly, initially, during a
  * direct read though, but its never held for the duration of a direct-IO).
  */
@@ -930,7 +930,7 @@
 }
 
 /*
- * Releases both i_sem and i_alloc_sem
+ * Releases both i_mutex and i_alloc_sem
  */
 static ssize_t
 direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, 
@@ -1062,11 +1062,11 @@
 
 	/*
 	 * All block lookups have been performed. For READ requests
-	 * we can let i_sem go now that its achieved its purpose
+	 * we can let i_mutex go now that its achieved its purpose
 	 * of protecting us from looking up uninitialized blocks.
 	 */
 	if ((rw == READ) && (dio->lock_type == DIO_LOCKING))
-		up(&dio->inode->i_sem);
+		mutex_unlock(&dio->inode->i_mutex);
 
 	/*
 	 * OK, all BIOs are submitted, so we can decrement bio_count to truly
@@ -1145,18 +1145,18 @@
  * The locking rules are governed by the dio_lock_type parameter.
  *
  * DIO_NO_LOCKING (no locking, for raw block device access)
- * For writes, i_sem is not held on entry; it is never taken.
+ * For writes, i_mutex is not held on entry; it is never taken.
  *
  * DIO_LOCKING (simple locking for regular files)
- * For writes we are called under i_sem and return with i_sem held, even though
+ * For writes we are called under i_mutex and return with i_mutex held, even though
  * it is internally dropped.
- * For reads, i_sem is not held on entry, but it is taken and dropped before
+ * For reads, i_mutex is not held on entry, but it is taken and dropped before
  * returning.
  *
  * DIO_OWN_LOCKING (filesystem provides synchronisation and handling of
  *	uninitialised data, allowing parallel direct readers and writers)
- * For writes we are called without i_sem, return without it, never touch it.
- * For reads, i_sem is held on entry and will be released before returning.
+ * For writes we are called without i_mutex, return without it, never touch it.
+ * For reads, i_mutex is held on entry and will be released before returning.
  *
  * Additional i_alloc_sem locking requirements described inline below.
  */
@@ -1214,11 +1214,11 @@
 	 * For block device access DIO_NO_LOCKING is used,
 	 *	neither readers nor writers do any locking at all
 	 * For regular files using DIO_LOCKING,
-	 *	readers need to grab i_sem and i_alloc_sem
-	 *	writers need to grab i_alloc_sem only (i_sem is already held)
+	 *	readers need to grab i_mutex and i_alloc_sem
+	 *	writers need to grab i_alloc_sem only (i_mutex is already held)
 	 * For regular files using DIO_OWN_LOCKING,
 	 *	neither readers nor writers take any locks here
-	 *	(i_sem is already held and release for writers here)
+	 *	(i_mutex is already held and release for writers here)
 	 */
 	dio->lock_type = dio_lock_type;
 	if (dio_lock_type != DIO_NO_LOCKING) {
@@ -1228,7 +1228,7 @@
 
 			mapping = iocb->ki_filp->f_mapping;
 			if (dio_lock_type != DIO_OWN_LOCKING) {
-				down(&inode->i_sem);
+				mutex_lock(&inode->i_mutex);
 				reader_with_isem = 1;
 			}
 
@@ -1240,7 +1240,7 @@
 			}
 
 			if (dio_lock_type == DIO_OWN_LOCKING) {
-				up(&inode->i_sem);
+				mutex_unlock(&inode->i_mutex);
 				reader_with_isem = 0;
 			}
 		}
@@ -1266,7 +1266,7 @@
 
 out:
 	if (reader_with_isem)
-		up(&inode->i_sem);
+		mutex_unlock(&inode->i_mutex);
 	if (rw & WRITE)
 		current->flags &= ~PF_SYNCWRITE;
 	return retval;
diff --git a/fs/dquot.c b/fs/dquot.c
index 2a62b3d..cb6d5bf 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -100,7 +100,7 @@
  * operation is just reading pointers from inode (or not using them at all) the
  * read lock is enough. If pointers are altered function must hold write lock
  * (these locking rules also apply for S_NOQUOTA flag in the inode - note that
- * for altering the flag i_sem is also needed).  If operation is holding
+ * for altering the flag i_mutex is also needed).  If operation is holding
  * reference to dquot in other way (e.g. quotactl ops) it must be guarded by
  * dqonoff_sem.
  * This locking assures that:
@@ -117,9 +117,9 @@
  * spinlock to internal buffers before writing.
  *
  * Lock ordering (including related VFS locks) is the following:
- *   i_sem > dqonoff_sem > iprune_sem > journal_lock > dqptr_sem >
+ *   i_mutex > dqonoff_sem > iprune_sem > journal_lock > dqptr_sem >
  *   > dquot->dq_lock > dqio_sem
- * i_sem on quota files is special (it's below dqio_sem)
+ * i_mutex on quota files is special (it's below dqio_sem)
  */
 
 static DEFINE_SPINLOCK(dq_list_lock);
@@ -1369,11 +1369,11 @@
 			/* If quota was reenabled in the meantime, we have
 			 * nothing to do */
 			if (!sb_has_quota_enabled(sb, cnt)) {
-				down(&toputinode[cnt]->i_sem);
+				mutex_lock(&toputinode[cnt]->i_mutex);
 				toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
 				  S_NOATIME | S_NOQUOTA);
 				truncate_inode_pages(&toputinode[cnt]->i_data, 0);
-				up(&toputinode[cnt]->i_sem);
+				mutex_unlock(&toputinode[cnt]->i_mutex);
 				mark_inode_dirty(toputinode[cnt]);
 				iput(toputinode[cnt]);
 			}
@@ -1417,7 +1417,7 @@
 	write_inode_now(inode, 1);
 	/* And now flush the block cache so that kernel sees the changes */
 	invalidate_bdev(sb->s_bdev, 0);
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	down(&dqopt->dqonoff_sem);
 	if (sb_has_quota_enabled(sb, type)) {
 		error = -EBUSY;
@@ -1449,7 +1449,7 @@
 		goto out_file_init;
 	}
 	up(&dqopt->dqio_sem);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	set_enable_flags(dqopt, type);
 
 	add_dquot_ref(sb, type);
@@ -1470,7 +1470,7 @@
 		inode->i_flags |= oldflags;
 		up_write(&dqopt->dqptr_sem);
 	}
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 out_fmt:
 	put_quota_format(fmt);
 
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index c49d625..5bfe400 100644
--- a/fs/exportfs/expfs.c
+++ b/fs/exportfs/expfs.c
@@ -177,9 +177,9 @@
 			struct dentry *ppd;
 			struct dentry *npd;
 
-			down(&pd->d_inode->i_sem);
+			mutex_lock(&pd->d_inode->i_mutex);
 			ppd = CALL(nops,get_parent)(pd);
-			up(&pd->d_inode->i_sem);
+			mutex_unlock(&pd->d_inode->i_mutex);
 
 			if (IS_ERR(ppd)) {
 				err = PTR_ERR(ppd);
@@ -201,9 +201,9 @@
 				break;
 			}
 			dprintk("find_exported_dentry: found name: %s\n", nbuf);
-			down(&ppd->d_inode->i_sem);
+			mutex_lock(&ppd->d_inode->i_mutex);
 			npd = lookup_one_len(nbuf, ppd, strlen(nbuf));
-			up(&ppd->d_inode->i_sem);
+			mutex_unlock(&ppd->d_inode->i_mutex);
 			if (IS_ERR(npd)) {
 				err = PTR_ERR(npd);
 				dprintk("find_exported_dentry: lookup failed: %d\n", err);
@@ -242,9 +242,9 @@
 		struct dentry *nresult;
 		err = CALL(nops,get_name)(target_dir, nbuf, result);
 		if (!err) {
-			down(&target_dir->d_inode->i_sem);
+			mutex_lock(&target_dir->d_inode->i_mutex);
 			nresult = lookup_one_len(nbuf, target_dir, strlen(nbuf));
-			up(&target_dir->d_inode->i_sem);
+			mutex_unlock(&target_dir->d_inode->i_mutex);
 			if (!IS_ERR(nresult)) {
 				if (nresult->d_inode) {
 					dput(result);
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c
index 6af2f41..239133d 100644
--- a/fs/ext2/acl.c
+++ b/fs/ext2/acl.c
@@ -149,7 +149,7 @@
 }
 
 /*
- * inode->i_sem: don't care
+ * inode->i_mutex: don't care
  */
 static struct posix_acl *
 ext2_get_acl(struct inode *inode, int type)
@@ -211,7 +211,7 @@
 }
 
 /*
- * inode->i_sem: down
+ * inode->i_mutex: down
  */
 static int
 ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
@@ -301,8 +301,8 @@
 /*
  * Initialize the ACLs of a new inode. Called from ext2_new_inode.
  *
- * dir->i_sem: down
- * inode->i_sem: up (access to inode is still exclusive)
+ * dir->i_mutex: down
+ * inode->i_mutex: up (access to inode is still exclusive)
  */
 int
 ext2_init_acl(struct inode *inode, struct inode *dir)
@@ -361,7 +361,7 @@
  * for directories) are added. There are no more bits available in the
  * file mode.
  *
- * inode->i_sem: down
+ * inode->i_mutex: down
  */
 int
 ext2_acl_chmod(struct inode *inode)
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index e977f85..00de0a7 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -53,7 +53,7 @@
 #ifdef CONFIG_EXT2_FS_XATTR
 	/*
 	 * Extended attributes can be read independently of the main file
-	 * data. Taking i_sem even when reading would cause contention
+	 * data. Taking i_mutex even when reading would cause contention
 	 * between readers of EAs and writers of regular file data, so
 	 * instead we synchronize on xattr_sem when reading or changing
 	 * EAs.
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 522fa70..8d68198 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -1152,7 +1152,7 @@
 	struct buffer_head tmp_bh;
 	struct buffer_head *bh;
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	while (towrite > 0) {
 		tocopy = sb->s_blocksize - offset < towrite ?
 				sb->s_blocksize - offset : towrite;
@@ -1189,7 +1189,7 @@
 	inode->i_version++;
 	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 	mark_inode_dirty(inode);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	return len - towrite;
 }
 
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c
index 0099462..f7a3b5f 100644
--- a/fs/ext2/xattr.c
+++ b/fs/ext2/xattr.c
@@ -325,7 +325,7 @@
 /*
  * Inode operation listxattr()
  *
- * dentry->d_inode->i_sem: don't care
+ * dentry->d_inode->i_mutex: don't care
  */
 ssize_t
 ext2_listxattr(struct dentry *dentry, char *buffer, size_t size)
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
index 3ac3826..9ed132c 100644
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -152,7 +152,7 @@
 /*
  * Inode operation get_posix_acl().
  *
- * inode->i_sem: don't care
+ * inode->i_mutex: don't care
  */
 static struct posix_acl *
 ext3_get_acl(struct inode *inode, int type)
@@ -216,7 +216,7 @@
 /*
  * Set the access or default ACL of an inode.
  *
- * inode->i_sem: down unless called from ext3_new_inode
+ * inode->i_mutex: down unless called from ext3_new_inode
  */
 static int
 ext3_set_acl(handle_t *handle, struct inode *inode, int type,
@@ -306,8 +306,8 @@
 /*
  * Initialize the ACLs of a new inode. Called from ext3_new_inode.
  *
- * dir->i_sem: down
- * inode->i_sem: up (access to inode is still exclusive)
+ * dir->i_mutex: down
+ * inode->i_mutex: up (access to inode is still exclusive)
  */
 int
 ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
@@ -368,7 +368,7 @@
  * for directories) are added. There are no more bits available in the
  * file mode.
  *
- * inode->i_sem: down
+ * inode->i_mutex: down
  */
 int
 ext3_acl_chmod(struct inode *inode)
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 7c45acf..56bf765 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -2150,7 +2150,7 @@
 
 static void ext3_write_super (struct super_block * sb)
 {
-	if (down_trylock(&sb->s_lock) == 0)
+	if (mutex_trylock(&sb->s_lock) != 0)
 		BUG();
 	sb->s_dirt = 0;
 }
@@ -2601,7 +2601,7 @@
 	struct buffer_head *bh;
 	handle_t *handle = journal_current_handle();
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	while (towrite > 0) {
 		tocopy = sb->s_blocksize - offset < towrite ?
 				sb->s_blocksize - offset : towrite;
@@ -2644,7 +2644,7 @@
 	inode->i_version++;
 	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 	ext3_mark_inode_dirty(handle, inode);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	return len - towrite;
 }
 
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index 430de9f..238199d 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -140,7 +140,7 @@
 /*
  * Inode operation listxattr()
  *
- * dentry->d_inode->i_sem: don't care
+ * dentry->d_inode->i_mutex: don't care
  */
 ssize_t
 ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index eef1b81..db0de5c 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -729,13 +729,13 @@
 
 	buf.dirent = d1;
 	buf.result = 0;
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	ret = -ENOENT;
 	if (!IS_DEADDIR(inode)) {
 		ret = __fat_readdir(inode, filp, &buf, fat_ioctl_filldir,
 				    short_only, both);
 	}
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	if (ret >= 0)
 		ret = buf.result;
 	return ret;
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 9b07c32..d30876c 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -41,7 +41,7 @@
 		if (err)
 			return err;
 
-		down(&inode->i_sem);
+		mutex_lock(&inode->i_mutex);
 
 		if (IS_RDONLY(inode)) {
 			err = -EROFS;
@@ -103,7 +103,7 @@
 		MSDOS_I(inode)->i_attrs = attr & ATTR_UNUSED;
 		mark_inode_dirty(inode);
 	up:
-		up(&inode->i_sem);
+		mutex_unlock(&inode->i_mutex);
 		return err;
 	}
 	default:
diff --git a/fs/fifo.c b/fs/fifo.c
index 5455916..923371b 100644
--- a/fs/fifo.c
+++ b/fs/fifo.c
@@ -35,7 +35,7 @@
 	int ret;
 
 	ret = -ERESTARTSYS;
-	if (down_interruptible(PIPE_SEM(*inode)))
+	if (mutex_lock_interruptible(PIPE_MUTEX(*inode)))
 		goto err_nolock_nocleanup;
 
 	if (!inode->i_pipe) {
@@ -119,7 +119,7 @@
 	}
 
 	/* Ok! */
-	up(PIPE_SEM(*inode));
+	mutex_unlock(PIPE_MUTEX(*inode));
 	return 0;
 
 err_rd:
@@ -139,7 +139,7 @@
 		free_pipe_info(inode);
 
 err_nocleanup:
-	up(PIPE_SEM(*inode));
+	mutex_unlock(PIPE_MUTEX(*inode));
 
 err_nolock_nocleanup:
 	return ret;
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 05deddd..63d2980 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -560,9 +560,9 @@
 	struct inode *inode = file->f_dentry->d_inode;
 	ssize_t res;
 	/* Don't allow parallel writes to the same file */
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	res = fuse_direct_io(file, buf, count, ppos, 1);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	return res;
 }
 
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index d499393a..050a492 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -547,13 +547,13 @@
 	if (atomic_read(&file->f_count) != 0)
 		return 0;
 	if (atomic_dec_and_test(&HFS_I(inode)->opencnt)) {
-		down(&inode->i_sem);
+		mutex_lock(&inode->i_mutex);
 		hfs_file_truncate(inode);
 		//if (inode->i_flags & S_DEAD) {
 		//	hfs_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL);
 		//	hfs_delete_inode(inode);
 		//}
-		up(&inode->i_sem);
+		mutex_unlock(&inode->i_mutex);
 	}
 	return 0;
 }
diff --git a/fs/hfsplus/bitmap.c b/fs/hfsplus/bitmap.c
index c7d3164..9fb5163 100644
--- a/fs/hfsplus/bitmap.c
+++ b/fs/hfsplus/bitmap.c
@@ -29,7 +29,7 @@
 		return size;
 
 	dprint(DBG_BITMAP, "block_allocate: %u,%u,%u\n", size, offset, len);
-	down(&HFSPLUS_SB(sb).alloc_file->i_sem);
+	mutex_lock(&HFSPLUS_SB(sb).alloc_file->i_mutex);
 	mapping = HFSPLUS_SB(sb).alloc_file->i_mapping;
 	page = read_cache_page(mapping, offset / PAGE_CACHE_BITS,
 			       (filler_t *)mapping->a_ops->readpage, NULL);
@@ -143,7 +143,7 @@
 	sb->s_dirt = 1;
 	dprint(DBG_BITMAP, "-> %u,%u\n", start, *max);
 out:
-	up(&HFSPLUS_SB(sb).alloc_file->i_sem);
+	mutex_unlock(&HFSPLUS_SB(sb).alloc_file->i_mutex);
 	return start;
 }
 
@@ -164,7 +164,7 @@
 	if ((offset + count) > HFSPLUS_SB(sb).total_blocks)
 		return -2;
 
-	down(&HFSPLUS_SB(sb).alloc_file->i_sem);
+	mutex_lock(&HFSPLUS_SB(sb).alloc_file->i_mutex);
 	mapping = HFSPLUS_SB(sb).alloc_file->i_mapping;
 	pnr = offset / PAGE_CACHE_BITS;
 	page = read_cache_page(mapping, pnr, (filler_t *)mapping->a_ops->readpage, NULL);
@@ -215,7 +215,7 @@
 	kunmap(page);
 	HFSPLUS_SB(sb).free_blocks += len;
 	sb->s_dirt = 1;
-	up(&HFSPLUS_SB(sb).alloc_file->i_sem);
+	mutex_unlock(&HFSPLUS_SB(sb).alloc_file->i_mutex);
 
 	return 0;
 }
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index fc98583..983bcd0 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -276,13 +276,13 @@
 	if (atomic_read(&file->f_count) != 0)
 		return 0;
 	if (atomic_dec_and_test(&HFSPLUS_I(inode).opencnt)) {
-		down(&inode->i_sem);
+		mutex_lock(&inode->i_mutex);
 		hfsplus_file_truncate(inode);
 		if (inode->i_flags & S_DEAD) {
 			hfsplus_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL);
 			hfsplus_delete_inode(inode);
 		}
-		up(&inode->i_sem);
+		mutex_unlock(&inode->i_mutex);
 	}
 	return 0;
 }
diff --git a/fs/hpfs/dir.c b/fs/hpfs/dir.c
index 0217c3a..5591f96 100644
--- a/fs/hpfs/dir.c
+++ b/fs/hpfs/dir.c
@@ -32,19 +32,19 @@
 
 	/*printk("dir lseek\n");*/
 	if (new_off == 0 || new_off == 1 || new_off == 11 || new_off == 12 || new_off == 13) goto ok;
-	down(&i->i_sem);
+	mutex_lock(&i->i_mutex);
 	pos = ((loff_t) hpfs_de_as_down_as_possible(s, hpfs_inode->i_dno) << 4) + 1;
 	while (pos != new_off) {
 		if (map_pos_dirent(i, &pos, &qbh)) hpfs_brelse4(&qbh);
 		else goto fail;
 		if (pos == 12) goto fail;
 	}
-	up(&i->i_sem);
+	mutex_unlock(&i->i_mutex);
 ok:
 	unlock_kernel();
 	return filp->f_pos = new_off;
 fail:
-	up(&i->i_sem);
+	mutex_unlock(&i->i_mutex);
 	/*printk("illegal lseek: %016llx\n", new_off);*/
 	unlock_kernel();
 	return -ESPIPE;
diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c
index 5293091..a44dc58 100644
--- a/fs/hppfs/hppfs_kern.c
+++ b/fs/hppfs/hppfs_kern.c
@@ -171,12 +171,12 @@
 
 	err = -ENOMEM;
 	parent = HPPFS_I(ino)->proc_dentry;
-	down(&parent->d_inode->i_sem);
+	mutex_lock(&parent->d_inode->i_mutex);
 	proc_dentry = d_lookup(parent, &dentry->d_name);
 	if(proc_dentry == NULL){
 		proc_dentry = d_alloc(parent, &dentry->d_name);
 		if(proc_dentry == NULL){
-			up(&parent->d_inode->i_sem);
+			mutex_unlock(&parent->d_inode->i_mutex);
 			goto out;
 		}
 		new = (*parent->d_inode->i_op->lookup)(parent->d_inode,
@@ -186,7 +186,7 @@
 			proc_dentry = new;
 		}
 	}
-	up(&parent->d_inode->i_sem);
+	mutex_unlock(&parent->d_inode->i_mutex);
 
 	if(IS_ERR(proc_dentry))
 		return(proc_dentry);
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 8c41315..ff1b7d1 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -118,7 +118,7 @@
 
 	vma_len = (loff_t)(vma->vm_end - vma->vm_start);
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	file_accessed(file);
 	vma->vm_flags |= VM_HUGETLB | VM_RESERVED;
 	vma->vm_ops = &hugetlb_vm_ops;
@@ -133,7 +133,7 @@
 	if (inode->i_size < len)
 		inode->i_size = len;
 out:
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 
 	return ret;
 }
diff --git a/fs/inode.c b/fs/inode.c
index fd568ca..e08767f 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -192,7 +192,7 @@
 	INIT_HLIST_NODE(&inode->i_hash);
 	INIT_LIST_HEAD(&inode->i_dentry);
 	INIT_LIST_HEAD(&inode->i_devices);
-	sema_init(&inode->i_sem, 1);
+	mutex_init(&inode->i_mutex);
 	init_rwsem(&inode->i_alloc_sem);
 	INIT_RADIX_TREE(&inode->i_data.page_tree, GFP_ATOMIC);
 	rwlock_init(&inode->i_data.tree_lock);
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index 2559ee1..fc3855a 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -1415,7 +1415,7 @@
 	 * This will never trigger with sane page sizes.  leave it in
 	 * anyway, since I'm thinking about how to merge larger writes
 	 * (the current idea is to poke a thread that does the actual
-	 * I/O and starts by doing a down(&inode->i_sem).  then we
+	 * I/O and starts by doing a mutex_lock(&inode->i_mutex).  then we
 	 * would need to get the page cache pages and have a list of
 	 * I/O requests and do write-merging here.
 	 * -- prumpf
diff --git a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h
index c0fd7b3..dc21a5b 100644
--- a/fs/jfs/jfs_incore.h
+++ b/fs/jfs/jfs_incore.h
@@ -58,7 +58,7 @@
 	/*
 	 * rdwrlock serializes xtree between reads & writes and synchronizes
 	 * changes to special inodes.  It's use would be redundant on
-	 * directories since the i_sem taken in the VFS is sufficient.
+	 * directories since the i_mutex taken in the VFS is sufficient.
 	 */
 	struct rw_semaphore rdwrlock;
 	/*
@@ -68,7 +68,7 @@
 	 * inode is blocked in txBegin or TxBeginAnon
 	 */
 	struct semaphore commit_sem;
-	/* xattr_sem allows us to access the xattrs without taking i_sem */
+	/* xattr_sem allows us to access the xattrs without taking i_mutex */
 	struct rw_semaphore xattr_sem;
 	lid_t	xtlid;		/* lid of xtree lock on directory */
 #ifdef CONFIG_JFS_POSIX_ACL
diff --git a/fs/libfs.c b/fs/libfs.c
index 9c50523..63c020e 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -74,7 +74,7 @@
 
 loff_t dcache_dir_lseek(struct file *file, loff_t offset, int origin)
 {
-	down(&file->f_dentry->d_inode->i_sem);
+	mutex_lock(&file->f_dentry->d_inode->i_mutex);
 	switch (origin) {
 		case 1:
 			offset += file->f_pos;
@@ -82,7 +82,7 @@
 			if (offset >= 0)
 				break;
 		default:
-			up(&file->f_dentry->d_inode->i_sem);
+			mutex_unlock(&file->f_dentry->d_inode->i_mutex);
 			return -EINVAL;
 	}
 	if (offset != file->f_pos) {
@@ -106,7 +106,7 @@
 			spin_unlock(&dcache_lock);
 		}
 	}
-	up(&file->f_dentry->d_inode->i_sem);
+	mutex_unlock(&file->f_dentry->d_inode->i_mutex);
 	return offset;
 }
 
@@ -356,7 +356,7 @@
 
 	/*
 	 * No need to use i_size_read() here, the i_size
-	 * cannot change under us because we hold the i_sem.
+	 * cannot change under us because we hold the i_mutex.
 	 */
 	if (pos > inode->i_size)
 		i_size_write(inode, pos);
diff --git a/fs/namei.c b/fs/namei.c
index 300eae0..0a8f073 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -438,7 +438,7 @@
 	struct dentry * result;
 	struct inode *dir = parent->d_inode;
 
-	down(&dir->i_sem);
+	mutex_lock(&dir->i_mutex);
 	/*
 	 * First re-do the cached lookup just in case it was created
 	 * while we waited for the directory semaphore..
@@ -464,7 +464,7 @@
 			else
 				result = dentry;
 		}
-		up(&dir->i_sem);
+		mutex_unlock(&dir->i_mutex);
 		return result;
 	}
 
@@ -472,7 +472,7 @@
 	 * Uhhuh! Nasty case: the cache was re-populated while
 	 * we waited on the semaphore. Need to revalidate.
 	 */
-	up(&dir->i_sem);
+	mutex_unlock(&dir->i_mutex);
 	if (result->d_op && result->d_op->d_revalidate) {
 		if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) {
 			dput(result);
@@ -1366,7 +1366,7 @@
 	struct dentry *p;
 
 	if (p1 == p2) {
-		down(&p1->d_inode->i_sem);
+		mutex_lock(&p1->d_inode->i_mutex);
 		return NULL;
 	}
 
@@ -1374,30 +1374,30 @@
 
 	for (p = p1; p->d_parent != p; p = p->d_parent) {
 		if (p->d_parent == p2) {
-			down(&p2->d_inode->i_sem);
-			down(&p1->d_inode->i_sem);
+			mutex_lock(&p2->d_inode->i_mutex);
+			mutex_lock(&p1->d_inode->i_mutex);
 			return p;
 		}
 	}
 
 	for (p = p2; p->d_parent != p; p = p->d_parent) {
 		if (p->d_parent == p1) {
-			down(&p1->d_inode->i_sem);
-			down(&p2->d_inode->i_sem);
+			mutex_lock(&p1->d_inode->i_mutex);
+			mutex_lock(&p2->d_inode->i_mutex);
 			return p;
 		}
 	}
 
-	down(&p1->d_inode->i_sem);
-	down(&p2->d_inode->i_sem);
+	mutex_lock(&p1->d_inode->i_mutex);
+	mutex_lock(&p2->d_inode->i_mutex);
 	return NULL;
 }
 
 void unlock_rename(struct dentry *p1, struct dentry *p2)
 {
-	up(&p1->d_inode->i_sem);
+	mutex_unlock(&p1->d_inode->i_mutex);
 	if (p1 != p2) {
-		up(&p2->d_inode->i_sem);
+		mutex_unlock(&p2->d_inode->i_mutex);
 		up(&p1->d_inode->i_sb->s_vfs_rename_sem);
 	}
 }
@@ -1563,14 +1563,14 @@
 
 	dir = nd->dentry;
 	nd->flags &= ~LOOKUP_PARENT;
-	down(&dir->d_inode->i_sem);
+	mutex_lock(&dir->d_inode->i_mutex);
 	path.dentry = lookup_hash(nd);
 	path.mnt = nd->mnt;
 
 do_last:
 	error = PTR_ERR(path.dentry);
 	if (IS_ERR(path.dentry)) {
-		up(&dir->d_inode->i_sem);
+		mutex_unlock(&dir->d_inode->i_mutex);
 		goto exit;
 	}
 
@@ -1579,7 +1579,7 @@
 		if (!IS_POSIXACL(dir->d_inode))
 			mode &= ~current->fs->umask;
 		error = vfs_create(dir->d_inode, path.dentry, mode, nd);
-		up(&dir->d_inode->i_sem);
+		mutex_unlock(&dir->d_inode->i_mutex);
 		dput(nd->dentry);
 		nd->dentry = path.dentry;
 		if (error)
@@ -1593,7 +1593,7 @@
 	/*
 	 * It already exists.
 	 */
-	up(&dir->d_inode->i_sem);
+	mutex_unlock(&dir->d_inode->i_mutex);
 
 	error = -EEXIST;
 	if (flag & O_EXCL)
@@ -1665,7 +1665,7 @@
 		goto exit;
 	}
 	dir = nd->dentry;
-	down(&dir->d_inode->i_sem);
+	mutex_lock(&dir->d_inode->i_mutex);
 	path.dentry = lookup_hash(nd);
 	path.mnt = nd->mnt;
 	__putname(nd->last.name);
@@ -1680,13 +1680,13 @@
  * Simple function to lookup and return a dentry and create it
  * if it doesn't exist.  Is SMP-safe.
  *
- * Returns with nd->dentry->d_inode->i_sem locked.
+ * Returns with nd->dentry->d_inode->i_mutex locked.
  */
 struct dentry *lookup_create(struct nameidata *nd, int is_dir)
 {
 	struct dentry *dentry = ERR_PTR(-EEXIST);
 
-	down(&nd->dentry->d_inode->i_sem);
+	mutex_lock(&nd->dentry->d_inode->i_mutex);
 	/*
 	 * Yucky last component or no last component at all?
 	 * (foo/., foo/.., /////)
@@ -1784,7 +1784,7 @@
 		}
 		dput(dentry);
 	}
-	up(&nd.dentry->d_inode->i_sem);
+	mutex_unlock(&nd.dentry->d_inode->i_mutex);
 	path_release(&nd);
 out:
 	putname(tmp);
@@ -1836,7 +1836,7 @@
 			error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
 			dput(dentry);
 		}
-		up(&nd.dentry->d_inode->i_sem);
+		mutex_unlock(&nd.dentry->d_inode->i_mutex);
 		path_release(&nd);
 out:
 		putname(tmp);
@@ -1885,7 +1885,7 @@
 
 	DQUOT_INIT(dir);
 
-	down(&dentry->d_inode->i_sem);
+	mutex_lock(&dentry->d_inode->i_mutex);
 	dentry_unhash(dentry);
 	if (d_mountpoint(dentry))
 		error = -EBUSY;
@@ -1897,7 +1897,7 @@
 				dentry->d_inode->i_flags |= S_DEAD;
 		}
 	}
-	up(&dentry->d_inode->i_sem);
+	mutex_unlock(&dentry->d_inode->i_mutex);
 	if (!error) {
 		d_delete(dentry);
 	}
@@ -1932,14 +1932,14 @@
 			error = -EBUSY;
 			goto exit1;
 	}
-	down(&nd.dentry->d_inode->i_sem);
+	mutex_lock(&nd.dentry->d_inode->i_mutex);
 	dentry = lookup_hash(&nd);
 	error = PTR_ERR(dentry);
 	if (!IS_ERR(dentry)) {
 		error = vfs_rmdir(nd.dentry->d_inode, dentry);
 		dput(dentry);
 	}
-	up(&nd.dentry->d_inode->i_sem);
+	mutex_unlock(&nd.dentry->d_inode->i_mutex);
 exit1:
 	path_release(&nd);
 exit:
@@ -1959,7 +1959,7 @@
 
 	DQUOT_INIT(dir);
 
-	down(&dentry->d_inode->i_sem);
+	mutex_lock(&dentry->d_inode->i_mutex);
 	if (d_mountpoint(dentry))
 		error = -EBUSY;
 	else {
@@ -1967,7 +1967,7 @@
 		if (!error)
 			error = dir->i_op->unlink(dir, dentry);
 	}
-	up(&dentry->d_inode->i_sem);
+	mutex_unlock(&dentry->d_inode->i_mutex);
 
 	/* We don't d_delete() NFS sillyrenamed files--they still exist. */
 	if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) {
@@ -1979,7 +1979,7 @@
 
 /*
  * Make sure that the actual truncation of the file will occur outside its
- * directory's i_sem.  Truncate can take a long time if there is a lot of
+ * directory's i_mutex.  Truncate can take a long time if there is a lot of
  * writeout happening, and we don't want to prevent access to the directory
  * while waiting on the I/O.
  */
@@ -2001,7 +2001,7 @@
 	error = -EISDIR;
 	if (nd.last_type != LAST_NORM)
 		goto exit1;
-	down(&nd.dentry->d_inode->i_sem);
+	mutex_lock(&nd.dentry->d_inode->i_mutex);
 	dentry = lookup_hash(&nd);
 	error = PTR_ERR(dentry);
 	if (!IS_ERR(dentry)) {
@@ -2015,7 +2015,7 @@
 	exit2:
 		dput(dentry);
 	}
-	up(&nd.dentry->d_inode->i_sem);
+	mutex_unlock(&nd.dentry->d_inode->i_mutex);
 	if (inode)
 		iput(inode);	/* truncate the inode here */
 exit1:
@@ -2075,7 +2075,7 @@
 			error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
 			dput(dentry);
 		}
-		up(&nd.dentry->d_inode->i_sem);
+		mutex_unlock(&nd.dentry->d_inode->i_mutex);
 		path_release(&nd);
 out:
 		putname(to);
@@ -2113,10 +2113,10 @@
 	if (error)
 		return error;
 
-	down(&old_dentry->d_inode->i_sem);
+	mutex_lock(&old_dentry->d_inode->i_mutex);
 	DQUOT_INIT(dir);
 	error = dir->i_op->link(old_dentry, dir, new_dentry);
-	up(&old_dentry->d_inode->i_sem);
+	mutex_unlock(&old_dentry->d_inode->i_mutex);
 	if (!error)
 		fsnotify_create(dir, new_dentry->d_name.name);
 	return error;
@@ -2157,7 +2157,7 @@
 		error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
 		dput(new_dentry);
 	}
-	up(&nd.dentry->d_inode->i_sem);
+	mutex_unlock(&nd.dentry->d_inode->i_mutex);
 out_release:
 	path_release(&nd);
 out:
@@ -2178,7 +2178,7 @@
  *	   sb->s_vfs_rename_sem. We might be more accurate, but that's another
  *	   story.
  *	c) we have to lock _three_ objects - parents and victim (if it exists).
- *	   And that - after we got ->i_sem on parents (until then we don't know
+ *	   And that - after we got ->i_mutex on parents (until then we don't know
  *	   whether the target exists).  Solution: try to be smart with locking
  *	   order for inodes.  We rely on the fact that tree topology may change
  *	   only under ->s_vfs_rename_sem _and_ that parent of the object we
@@ -2195,9 +2195,9 @@
  *	   stuff into VFS), but the former is not going away. Solution: the same
  *	   trick as in rmdir().
  *	e) conversion from fhandle to dentry may come in the wrong moment - when
- *	   we are removing the target. Solution: we will have to grab ->i_sem
+ *	   we are removing the target. Solution: we will have to grab ->i_mutex
  *	   in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on
- *	   ->i_sem on parents, which works but leads to some truely excessive
+ *	   ->i_mutex on parents, which works but leads to some truely excessive
  *	   locking].
  */
 static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
@@ -2222,7 +2222,7 @@
 
 	target = new_dentry->d_inode;
 	if (target) {
-		down(&target->i_sem);
+		mutex_lock(&target->i_mutex);
 		dentry_unhash(new_dentry);
 	}
 	if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
@@ -2232,7 +2232,7 @@
 	if (target) {
 		if (!error)
 			target->i_flags |= S_DEAD;
-		up(&target->i_sem);
+		mutex_unlock(&target->i_mutex);
 		if (d_unhashed(new_dentry))
 			d_rehash(new_dentry);
 		dput(new_dentry);
@@ -2255,7 +2255,7 @@
 	dget(new_dentry);
 	target = new_dentry->d_inode;
 	if (target)
-		down(&target->i_sem);
+		mutex_lock(&target->i_mutex);
 	if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
 		error = -EBUSY;
 	else
@@ -2266,7 +2266,7 @@
 			d_move(old_dentry, new_dentry);
 	}
 	if (target)
-		up(&target->i_sem);
+		mutex_unlock(&target->i_mutex);
 	dput(new_dentry);
 	return error;
 }
diff --git a/fs/namespace.c b/fs/namespace.c
index 3e8fb61..f0e353f 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -814,7 +814,7 @@
 		return -ENOTDIR;
 
 	err = -ENOENT;
-	down(&nd->dentry->d_inode->i_sem);
+	mutex_lock(&nd->dentry->d_inode->i_mutex);
 	if (IS_DEADDIR(nd->dentry->d_inode))
 		goto out_unlock;
 
@@ -826,7 +826,7 @@
 	if (IS_ROOT(nd->dentry) || !d_unhashed(nd->dentry))
 		err = attach_recursive_mnt(mnt, nd, NULL);
 out_unlock:
-	up(&nd->dentry->d_inode->i_sem);
+	mutex_unlock(&nd->dentry->d_inode->i_mutex);
 	if (!err)
 		security_sb_post_addmount(mnt, nd);
 	return err;
@@ -962,7 +962,7 @@
 		goto out;
 
 	err = -ENOENT;
-	down(&nd->dentry->d_inode->i_sem);
+	mutex_lock(&nd->dentry->d_inode->i_mutex);
 	if (IS_DEADDIR(nd->dentry->d_inode))
 		goto out1;
 
@@ -1004,7 +1004,7 @@
 	list_del_init(&old_nd.mnt->mnt_expire);
 	spin_unlock(&vfsmount_lock);
 out1:
-	up(&nd->dentry->d_inode->i_sem);
+	mutex_unlock(&nd->dentry->d_inode->i_mutex);
 out:
 	up_write(&namespace_sem);
 	if (!err)
@@ -1573,7 +1573,7 @@
 	user_nd.dentry = dget(current->fs->root);
 	read_unlock(&current->fs->lock);
 	down_write(&namespace_sem);
-	down(&old_nd.dentry->d_inode->i_sem);
+	mutex_lock(&old_nd.dentry->d_inode->i_mutex);
 	error = -EINVAL;
 	if (IS_MNT_SHARED(old_nd.mnt) ||
 		IS_MNT_SHARED(new_nd.mnt->mnt_parent) ||
@@ -1626,7 +1626,7 @@
 	path_release(&root_parent);
 	path_release(&parent_nd);
 out2:
-	up(&old_nd.dentry->d_inode->i_sem);
+	mutex_unlock(&old_nd.dentry->d_inode->i_mutex);
 	up_write(&namespace_sem);
 	path_release(&user_nd);
 	path_release(&old_nd);
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index e925519..a1554be 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -194,7 +194,7 @@
 	spin_unlock(&inode->i_lock);
 	/* Ensure consistent page alignment of the data.
 	 * Note: assumes we have exclusive access to this mapping either
-	 *	 through inode->i_sem or some other mechanism.
+	 *	 through inode->i_mutex or some other mechanism.
 	 */
 	if (page->index == 0)
 		invalidate_inode_pages2_range(inode->i_mapping, PAGE_CACHE_SIZE, -1);
@@ -573,7 +573,7 @@
 
 loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin)
 {
-	down(&filp->f_dentry->d_inode->i_sem);
+	mutex_lock(&filp->f_dentry->d_inode->i_mutex);
 	switch (origin) {
 		case 1:
 			offset += filp->f_pos;
@@ -589,7 +589,7 @@
 		((struct nfs_open_context *)filp->private_data)->dir_cookie = 0;
 	}
 out:
-	up(&filp->f_dentry->d_inode->i_sem);
+	mutex_unlock(&filp->f_dentry->d_inode->i_mutex);
 	return offset;
 }
 
@@ -1001,7 +1001,7 @@
 	openflags &= ~(O_CREAT|O_TRUNC);
 
 	/*
-	 * Note: we're not holding inode->i_sem and so may be racing with
+	 * Note: we're not holding inode->i_mutex and so may be racing with
 	 * operations that change the directory. We therefore save the
 	 * change attribute *before* we do the RPC call.
 	 */
@@ -1051,7 +1051,7 @@
 		return dentry;
 	if (!desc->plus || !(entry->fattr->valid & NFS_ATTR_FATTR))
 		return NULL;
-	/* Note: caller is already holding the dir->i_sem! */
+	/* Note: caller is already holding the dir->i_mutex! */
 	dentry = d_alloc(parent, &name);
 	if (dentry == NULL)
 		return NULL;
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 954cf89..be963a1 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -121,9 +121,9 @@
 static void
 nfsd4_sync_rec_dir(void)
 {
-	down(&rec_dir.dentry->d_inode->i_sem);
+	mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
 	nfsd_sync_dir(rec_dir.dentry);
-	up(&rec_dir.dentry->d_inode->i_sem);
+	mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
 }
 
 int
@@ -143,7 +143,7 @@
 	nfs4_save_user(&uid, &gid);
 
 	/* lock the parent */
-	down(&rec_dir.dentry->d_inode->i_sem);
+	mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
 
 	dentry = lookup_one_len(dname, rec_dir.dentry, HEXDIR_LEN-1);
 	if (IS_ERR(dentry)) {
@@ -159,7 +159,7 @@
 out_put:
 	dput(dentry);
 out_unlock:
-	up(&rec_dir.dentry->d_inode->i_sem);
+	mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
 	if (status == 0) {
 		clp->cl_firststate = 1;
 		nfsd4_sync_rec_dir();
@@ -259,9 +259,9 @@
 		printk("nfsd4: non-file found in client recovery directory\n");
 		return -EINVAL;
 	}
-	down(&dir->d_inode->i_sem);
+	mutex_lock(&dir->d_inode->i_mutex);
 	status = vfs_unlink(dir->d_inode, dentry);
-	up(&dir->d_inode->i_sem);
+	mutex_unlock(&dir->d_inode->i_mutex);
 	return status;
 }
 
@@ -274,9 +274,9 @@
 	 * any regular files anyway, just in case the directory was created by
 	 * a kernel from the future.... */
 	nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file);
-	down(&dir->d_inode->i_sem);
+	mutex_lock(&dir->d_inode->i_mutex);
 	status = vfs_rmdir(dir->d_inode, dentry);
-	up(&dir->d_inode->i_sem);
+	mutex_unlock(&dir->d_inode->i_mutex);
 	return status;
 }
 
@@ -288,9 +288,9 @@
 
 	dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);
 
-	down(&rec_dir.dentry->d_inode->i_sem);
+	mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
 	dentry = lookup_one_len(name, rec_dir.dentry, namlen);
-	up(&rec_dir.dentry->d_inode->i_sem);
+	mutex_unlock(&rec_dir.dentry->d_inode->i_mutex);
 	if (IS_ERR(dentry)) {
 		status = PTR_ERR(dentry);
 		return status;
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index df4019f..bb36b43 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -390,12 +390,12 @@
 
 	error = -EOPNOTSUPP;
 	if (inode->i_op && inode->i_op->setxattr) {
-		down(&inode->i_sem);
+		mutex_lock(&inode->i_mutex);
 		security_inode_setxattr(dentry, key, buf, len, 0);
 		error = inode->i_op->setxattr(dentry, key, buf, len, 0);
 		if (!error)
 			security_inode_post_setxattr(dentry, key, buf, len, 0);
-		up(&inode->i_sem);
+		mutex_unlock(&inode->i_mutex);
 	}
 out:
 	kfree(buf);
@@ -739,9 +739,9 @@
         int err;
 	struct inode *inode = filp->f_dentry->d_inode;
 	dprintk("nfsd: sync file %s\n", filp->f_dentry->d_name.name);
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	err=nfsd_dosync(filp, filp->f_dentry, filp->f_op);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 
 	return err;
 }
@@ -885,9 +885,9 @@
 	struct iattr	ia;
 	ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID;
 
-	down(&dentry->d_inode->i_sem);
+	mutex_lock(&dentry->d_inode->i_mutex);
 	notify_change(dentry, &ia);
-	up(&dentry->d_inode->i_sem);
+	mutex_unlock(&dentry->d_inode->i_mutex);
 }
 
 static inline int
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index eda056b..9480a05 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -1532,7 +1532,7 @@
  * NOTE to self: No changes in the attribute list are required to move from
  *		 a resident to a non-resident attribute.
  *
- * Locking: - The caller must hold i_sem on the inode.
+ * Locking: - The caller must hold i_mutex on the inode.
  */
 int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size)
 {
@@ -1728,7 +1728,7 @@
 	/*
 	 * This needs to be last since the address space operations ->readpage
 	 * and ->writepage can run concurrently with us as they are not
-	 * serialized on i_sem.  Note, we are not allowed to fail once we flip
+	 * serialized on i_mutex.  Note, we are not allowed to fail once we flip
 	 * this switch, which is another reason to do this last.
 	 */
 	NInoSetNonResident(ni);
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c
index 795c3d1..b0690d4 100644
--- a/fs/ntfs/dir.c
+++ b/fs/ntfs/dir.c
@@ -69,7 +69,7 @@
  * work but we don't care for how quickly one can access them. This also fixes
  * the dcache aliasing issues.
  *
- * Locking:  - Caller must hold i_sem on the directory.
+ * Locking:  - Caller must hold i_mutex on the directory.
  *	     - Each page cache page in the index allocation mapping must be
  *	       locked whilst being accessed otherwise we may find a corrupt
  *	       page due to it being under ->writepage at the moment which
@@ -1085,11 +1085,11 @@
  * While this will return the names in random order this doesn't matter for
  * ->readdir but OTOH results in a faster ->readdir.
  *
- * VFS calls ->readdir without BKL but with i_sem held. This protects the VFS
+ * VFS calls ->readdir without BKL but with i_mutex held. This protects the VFS
  * parts (e.g. ->f_pos and ->i_size, and it also protects against directory
  * modifications).
  *
- * Locking:  - Caller must hold i_sem on the directory.
+ * Locking:  - Caller must hold i_mutex on the directory.
  *	     - Each page cache page in the index allocation mapping must be
  *	       locked whilst being accessed otherwise we may find a corrupt
  *	       page due to it being under ->writepage at the moment which
@@ -1520,7 +1520,7 @@
  * Note: In the past @filp could be NULL so we ignore it as we don't need it
  * anyway.
  *
- * Locking: Caller must hold i_sem on the inode.
+ * Locking: Caller must hold i_mutex on the inode.
  *
  * TODO: We should probably also write all attribute/index inodes associated
  * with this inode but since we have no simple way of getting to them we ignore
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index 7275338..30f71ac 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -106,7 +106,7 @@
  * this is the case, the necessary zeroing will also have happened and that all
  * metadata is self-consistent.
  *
- * Locking: i_sem on the vfs inode corrseponsind to the ntfs inode @ni must be
+ * Locking: i_mutex on the vfs inode corrseponsind to the ntfs inode @ni must be
  *	    held by the caller.
  */
 static int ntfs_attr_extend_initialized(ntfs_inode *ni, const s64 new_init_size,
@@ -473,7 +473,7 @@
  * @bytes:	number of bytes to be written
  *
  * This is called for non-resident attributes from ntfs_file_buffered_write()
- * with i_sem held on the inode (@pages[0]->mapping->host).  There are
+ * with i_mutex held on the inode (@pages[0]->mapping->host).  There are
  * @nr_pages pages in @pages which are locked but not kmap()ped.  The source
  * data has not yet been copied into the @pages.
  * 
@@ -1637,7 +1637,7 @@
  * @pos:	byte position in file at which the write begins
  * @bytes:	number of bytes to be written
  *
- * This is called from ntfs_file_buffered_write() with i_sem held on the inode
+ * This is called from ntfs_file_buffered_write() with i_mutex held on the inode
  * (@pages[0]->mapping->host).  There are @nr_pages pages in @pages which are
  * locked but not kmap()ped.  The source data has already been copied into the
  * @page.  ntfs_prepare_pages_for_non_resident_write() has been called before
@@ -1814,7 +1814,7 @@
 /**
  * ntfs_file_buffered_write -
  *
- * Locking: The vfs is holding ->i_sem on the inode.
+ * Locking: The vfs is holding ->i_mutex on the inode.
  */
 static ssize_t ntfs_file_buffered_write(struct kiocb *iocb,
 		const struct iovec *iov, unsigned long nr_segs,
@@ -2196,9 +2196,9 @@
 
 	BUG_ON(iocb->ki_pos != pos);
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	ret = ntfs_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
 		int err = sync_page_range(inode, mapping, pos, ret);
 		if (err < 0)
@@ -2221,12 +2221,12 @@
 	struct kiocb kiocb;
 	ssize_t ret;
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	init_sync_kiocb(&kiocb, file);
 	ret = ntfs_file_aio_write_nolock(&kiocb, iov, nr_segs, ppos);
 	if (ret == -EIOCBQUEUED)
 		ret = wait_on_sync_kiocb(&kiocb);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
 		int err = sync_page_range(inode, mapping, *ppos - ret, ret);
 		if (err < 0)
@@ -2269,7 +2269,7 @@
  * Note: In the past @filp could be NULL so we ignore it as we don't need it
  * anyway.
  *
- * Locking: Caller must hold i_sem on the inode.
+ * Locking: Caller must hold i_mutex on the inode.
  *
  * TODO: We should probably also write all attribute/index inodes associated
  * with this inode but since we have no simple way of getting to them we ignore
diff --git a/fs/ntfs/index.c b/fs/ntfs/index.c
index 8f2d572..9f5427c 100644
--- a/fs/ntfs/index.c
+++ b/fs/ntfs/index.c
@@ -32,7 +32,7 @@
  * Allocate a new index context, initialize it with @idx_ni and return it.
  * Return NULL if allocation failed.
  *
- * Locking:  Caller must hold i_sem on the index inode.
+ * Locking:  Caller must hold i_mutex on the index inode.
  */
 ntfs_index_context *ntfs_index_ctx_get(ntfs_inode *idx_ni)
 {
@@ -50,7 +50,7 @@
  *
  * Release the index context @ictx, releasing all associated resources.
  *
- * Locking:  Caller must hold i_sem on the index inode.
+ * Locking:  Caller must hold i_mutex on the index inode.
  */
 void ntfs_index_ctx_put(ntfs_index_context *ictx)
 {
@@ -106,7 +106,7 @@
  * or ntfs_index_entry_write() before the call to ntfs_index_ctx_put() to
  * ensure that the changes are written to disk.
  *
- * Locking:  - Caller must hold i_sem on the index inode.
+ * Locking:  - Caller must hold i_mutex on the index inode.
  *	     - Each page cache page in the index allocation mapping must be
  *	       locked whilst being accessed otherwise we may find a corrupt
  *	       page due to it being under ->writepage at the moment which
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index b24f4c4..bda7a08 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -2125,13 +2125,13 @@
 		ntfs_inode *ni = NTFS_I(vi);
 		if (NInoIndexAllocPresent(ni)) {
 			struct inode *bvi = NULL;
-			down(&vi->i_sem);
+			mutex_lock(&vi->i_mutex);
 			if (atomic_read(&vi->i_count) == 2) {
 				bvi = ni->itype.index.bmp_ino;
 				if (bvi)
 					ni->itype.index.bmp_ino = NULL;
 			}
-			up(&vi->i_sem);
+			mutex_unlock(&vi->i_mutex);
 			if (bvi)
 				iput(bvi);
 		}
@@ -2311,7 +2311,7 @@
  *
  * Returns 0 on success or -errno on error.
  *
- * Called with ->i_sem held.  In all but one case ->i_alloc_sem is held for
+ * Called with ->i_mutex held.  In all but one case ->i_alloc_sem is held for
  * writing.  The only case in the kernel where ->i_alloc_sem is not held is
  * mm/filemap.c::generic_file_buffered_write() where vmtruncate() is called
  * with the current i_size as the offset.  The analogous place in NTFS is in
@@ -2831,7 +2831,7 @@
  * We also abort all changes of user, group, and mode as we do not implement
  * the NTFS ACLs yet.
  *
- * Called with ->i_sem held.  For the ATTR_SIZE (i.e. ->truncate) case, also
+ * Called with ->i_mutex held.  For the ATTR_SIZE (i.e. ->truncate) case, also
  * called with ->i_alloc_sem held for writing.
  *
  * Basically this is a copy of generic notify_change() and inode_setattr()
diff --git a/fs/ntfs/namei.c b/fs/ntfs/namei.c
index 351dbc3..5ea9eb9 100644
--- a/fs/ntfs/namei.c
+++ b/fs/ntfs/namei.c
@@ -96,7 +96,7 @@
  *    name. We then convert the name to the current NLS code page, and proceed
  *    searching for a dentry with this name, etc, as in case 2), above.
  *
- * Locking: Caller must hold i_sem on the directory.
+ * Locking: Caller must hold i_mutex on the directory.
  */
 static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent,
 		struct nameidata *nd)
@@ -254,7 +254,7 @@
 	nls_name.hash = full_name_hash(nls_name.name, nls_name.len);
 
 	/*
-	 * Note: No need for dent->d_lock lock as i_sem is held on the
+	 * Note: No need for dent->d_lock lock as i_mutex is held on the
 	 * parent inode.
 	 */
 
@@ -374,7 +374,7 @@
  * The code is based on the ext3 ->get_parent() implementation found in
  * fs/ext3/namei.c::ext3_get_parent().
  *
- * Note: ntfs_get_parent() is called with @child_dent->d_inode->i_sem down.
+ * Note: ntfs_get_parent() is called with @child_dent->d_inode->i_mutex down.
  *
  * Return the dentry of the parent directory on success or the error code on
  * error (IS_ERR() is true).
diff --git a/fs/ntfs/quota.c b/fs/ntfs/quota.c
index 833df2a..d0ef418 100644
--- a/fs/ntfs/quota.c
+++ b/fs/ntfs/quota.c
@@ -48,7 +48,7 @@
 		ntfs_error(vol->sb, "Quota inodes are not open.");
 		return FALSE;
 	}
-	down(&vol->quota_q_ino->i_sem);
+	mutex_lock(&vol->quota_q_ino->i_mutex);
 	ictx = ntfs_index_ctx_get(NTFS_I(vol->quota_q_ino));
 	if (!ictx) {
 		ntfs_error(vol->sb, "Failed to get index context.");
@@ -98,7 +98,7 @@
 	ntfs_index_entry_mark_dirty(ictx);
 set_done:
 	ntfs_index_ctx_put(ictx);
-	up(&vol->quota_q_ino->i_sem);
+	mutex_unlock(&vol->quota_q_ino->i_mutex);
 	/*
 	 * We set the flag so we do not try to mark the quotas out of date
 	 * again on remount.
@@ -110,7 +110,7 @@
 err_out:
 	if (ictx)
 		ntfs_index_ctx_put(ictx);
-	up(&vol->quota_q_ino->i_sem);
+	mutex_unlock(&vol->quota_q_ino->i_mutex);
 	return FALSE;
 }
 
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 6c16db9..280e383 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1213,10 +1213,10 @@
 	 * Find the inode number for the hibernation file by looking up the
 	 * filename hiberfil.sys in the root directory.
 	 */
-	down(&vol->root_ino->i_sem);
+	mutex_lock(&vol->root_ino->i_mutex);
 	mref = ntfs_lookup_inode_by_name(NTFS_I(vol->root_ino), hiberfil, 12,
 			&name);
-	up(&vol->root_ino->i_sem);
+	mutex_unlock(&vol->root_ino->i_mutex);
 	if (IS_ERR_MREF(mref)) {
 		ret = MREF_ERR(mref);
 		/* If the file does not exist, Windows is not hibernated. */
@@ -1307,10 +1307,10 @@
 	 * Find the inode number for the quota file by looking up the filename
 	 * $Quota in the extended system files directory $Extend.
 	 */
-	down(&vol->extend_ino->i_sem);
+	mutex_lock(&vol->extend_ino->i_mutex);
 	mref = ntfs_lookup_inode_by_name(NTFS_I(vol->extend_ino), Quota, 6,
 			&name);
-	up(&vol->extend_ino->i_sem);
+	mutex_unlock(&vol->extend_ino->i_mutex);
 	if (IS_ERR_MREF(mref)) {
 		/*
 		 * If the file does not exist, quotas are disabled and have
@@ -1390,10 +1390,10 @@
 	 * Find the inode number for the transaction log file by looking up the
 	 * filename $UsnJrnl in the extended system files directory $Extend.
 	 */
-	down(&vol->extend_ino->i_sem);
+	mutex_lock(&vol->extend_ino->i_mutex);
 	mref = ntfs_lookup_inode_by_name(NTFS_I(vol->extend_ino), UsnJrnl, 8,
 			&name);
-	up(&vol->extend_ino->i_sem);
+	mutex_unlock(&vol->extend_ino->i_mutex);
 	if (IS_ERR_MREF(mref)) {
 		/*
 		 * If the file does not exist, transaction logging is disabled,
@@ -2312,9 +2312,9 @@
 	if (!list_empty(&sb->s_dirty)) {
 		const char *s1, *s2;
 
-		down(&vol->mft_ino->i_sem);
+		mutex_lock(&vol->mft_ino->i_mutex);
 		truncate_inode_pages(vol->mft_ino->i_mapping, 0);
-		up(&vol->mft_ino->i_sem);
+		mutex_unlock(&vol->mft_ino->i_mutex);
 		write_inode_now(vol->mft_ino, 1);
 		if (!list_empty(&sb->s_dirty)) {
 			static const char *_s1 = "inodes";
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 465f797..6b9812d 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -966,7 +966,7 @@
 	mlog_entry("start_blk = %"MLFu64", num_clusters = %u\n", start_blk,
 		   num_clusters);
 
-	BUG_ON(!down_trylock(&tl_inode->i_sem));
+	BUG_ON(mutex_trylock(&tl_inode->i_mutex));
 
 	start_cluster = ocfs2_blocks_to_clusters(osb->sb, start_blk);
 
@@ -1108,7 +1108,7 @@
 	return status;
 }
 
-/* Expects you to already be holding tl_inode->i_sem */
+/* Expects you to already be holding tl_inode->i_mutex */
 static int __ocfs2_flush_truncate_log(struct ocfs2_super *osb)
 {
 	int status;
@@ -1123,7 +1123,7 @@
 
 	mlog_entry_void();
 
-	BUG_ON(!down_trylock(&tl_inode->i_sem));
+	BUG_ON(mutex_trylock(&tl_inode->i_mutex));
 
 	di = (struct ocfs2_dinode *) tl_bh->b_data;
 	tl = &di->id2.i_dealloc;
@@ -1198,9 +1198,9 @@
 	int status;
 	struct inode *tl_inode = osb->osb_tl_inode;
 
-	down(&tl_inode->i_sem);
+	mutex_lock(&tl_inode->i_mutex);
 	status = __ocfs2_flush_truncate_log(osb);
-	up(&tl_inode->i_sem);
+	mutex_unlock(&tl_inode->i_mutex);
 
 	return status;
 }
@@ -1363,7 +1363,7 @@
 	mlog(0, "cleanup %u records from %"MLFu64"\n", num_recs,
 	     tl_copy->i_blkno);
 
-	down(&tl_inode->i_sem);
+	mutex_lock(&tl_inode->i_mutex);
 	for(i = 0; i < num_recs; i++) {
 		if (ocfs2_truncate_log_needs_flush(osb)) {
 			status = __ocfs2_flush_truncate_log(osb);
@@ -1395,7 +1395,7 @@
 	}
 
 bail_up:
-	up(&tl_inode->i_sem);
+	mutex_unlock(&tl_inode->i_mutex);
 
 	mlog_exit(status);
 	return status;
@@ -1840,7 +1840,7 @@
 
 	mlog(0, "clusters_to_del = %u in this pass\n", clusters_to_del);
 
-	down(&tl_inode->i_sem);
+	mutex_lock(&tl_inode->i_mutex);
 	tl_sem = 1;
 	/* ocfs2_truncate_log_needs_flush guarantees us at least one
 	 * record is free for use. If there isn't any, we flush to get
@@ -1875,7 +1875,7 @@
 		goto bail;
 	}
 
-	up(&tl_inode->i_sem);
+	mutex_unlock(&tl_inode->i_mutex);
 	tl_sem = 0;
 
 	ocfs2_commit_trans(handle);
@@ -1890,7 +1890,7 @@
 	ocfs2_schedule_truncate_log_flush(osb, 1);
 
 	if (tl_sem)
-		up(&tl_inode->i_sem);
+		mutex_unlock(&tl_inode->i_mutex);
 
 	if (handle)
 		ocfs2_commit_trans(handle);
@@ -1994,7 +1994,7 @@
 			goto bail;
 		}
 
-		down(&ext_alloc_inode->i_sem);
+		mutex_lock(&ext_alloc_inode->i_mutex);
 		(*tc)->tc_ext_alloc_inode = ext_alloc_inode;
 
 		status = ocfs2_meta_lock(ext_alloc_inode,
@@ -2026,7 +2026,7 @@
 		if (tc->tc_ext_alloc_locked)
 			ocfs2_meta_unlock(tc->tc_ext_alloc_inode, 1);
 
-		up(&tc->tc_ext_alloc_inode->i_sem);
+		mutex_unlock(&tc->tc_ext_alloc_inode->i_mutex);
 		iput(tc->tc_ext_alloc_inode);
 	}
 
diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c
index 5fd60c1..cf7828f 100644
--- a/fs/ocfs2/cluster/nodemanager.c
+++ b/fs/ocfs2/cluster/nodemanager.c
@@ -653,7 +653,7 @@
 	struct config_group *o2hb_group = NULL, *ret = NULL;
 	void *defs = NULL;
 
-	/* this runs under the parent dir's i_sem; there can be only
+	/* this runs under the parent dir's i_mutex; there can be only
 	 * one caller in here at a time */
 	if (o2nm_single_cluster)
 		goto out; /* ENOSPC */
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index 856e20a..57158fa 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -202,7 +202,7 @@
 }
 
 /*
- * NOTE: this should always be called with parent dir i_sem taken.
+ * NOTE: this should always be called with parent dir i_mutex taken.
  */
 int ocfs2_find_files_on_disk(const char *name,
 			     int namelen,
@@ -245,7 +245,7 @@
  * Return 0 if the name does not exist
  * Return -EEXIST if the directory contains the name
  *
- * Callers should have i_sem + a cluster lock on dir
+ * Callers should have i_mutex + a cluster lock on dir
  */
 int ocfs2_check_dir_for_entry(struct inode *dir,
 			      const char *name,
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 72ae9e3..ca5f9f9 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -492,7 +492,7 @@
 	}
 
 	/* blocks peope in read/write from reading our allocation
-	 * until we're done changing it. We depend on i_sem to block
+	 * until we're done changing it. We depend on i_mutex to block
 	 * other extend/truncate calls while we're here. Ordering wrt
 	 * start_trans is important here -- always do it before! */
 	down_write(&OCFS2_I(inode)->ip_alloc_sem);
@@ -958,8 +958,8 @@
 		filp->f_flags &= ~O_DIRECT;
 #endif
 
-	down(&inode->i_sem);
-	/* to match setattr's i_sem -> i_alloc_sem -> rw_lock ordering */
+	mutex_lock(&inode->i_mutex);
+	/* to match setattr's i_mutex -> i_alloc_sem -> rw_lock ordering */
 	if (filp->f_flags & O_DIRECT) {
 		have_alloc_sem = 1;
 		down_read(&inode->i_alloc_sem);
@@ -1123,7 +1123,7 @@
 		up_read(&inode->i_alloc_sem);
 	if (rw_level != -1) 
 		ocfs2_rw_unlock(inode, rw_level);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 
 	mlog_exit(ret);
 	return ret;
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index a91ba4d..d4ecc06 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -485,10 +485,10 @@
 		goto bail;
 	}
 
-	down(&inode_alloc_inode->i_sem);
+	mutex_lock(&inode_alloc_inode->i_mutex);
 	status = ocfs2_meta_lock(inode_alloc_inode, NULL, &inode_alloc_bh, 1);
 	if (status < 0) {
-		up(&inode_alloc_inode->i_sem);
+		mutex_unlock(&inode_alloc_inode->i_mutex);
 
 		mlog_errno(status);
 		goto bail;
@@ -536,7 +536,7 @@
 	ocfs2_commit_trans(handle);
 bail_unlock:
 	ocfs2_meta_unlock(inode_alloc_inode, 1);
-	up(&inode_alloc_inode->i_sem);
+	mutex_unlock(&inode_alloc_inode->i_mutex);
 	brelse(inode_alloc_bh);
 bail:
 	iput(inode_alloc_inode);
@@ -567,10 +567,10 @@
 	/* Lock the orphan dir. The lock will be held for the entire
 	 * delete_inode operation. We do this now to avoid races with
 	 * recovery completion on other nodes. */
-	down(&orphan_dir_inode->i_sem);
+	mutex_lock(&orphan_dir_inode->i_mutex);
 	status = ocfs2_meta_lock(orphan_dir_inode, NULL, &orphan_dir_bh, 1);
 	if (status < 0) {
-		up(&orphan_dir_inode->i_sem);
+		mutex_unlock(&orphan_dir_inode->i_mutex);
 
 		mlog_errno(status);
 		goto bail;
@@ -593,7 +593,7 @@
 
 bail_unlock_dir:
 	ocfs2_meta_unlock(orphan_dir_inode, 1);
-	up(&orphan_dir_inode->i_sem);
+	mutex_unlock(&orphan_dir_inode->i_mutex);
 	brelse(orphan_dir_bh);
 bail:
 	iput(orphan_dir_inode);
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index 0442804..303c8d9 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -216,7 +216,7 @@
 	atomic_inc(&inode->i_count);
 
 	/* we're obviously changing it... */
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 
 	/* sanity check */
 	BUG_ON(OCFS2_I(inode)->ip_handle);
@@ -241,7 +241,7 @@
 		OCFS2_I(inode)->ip_handle = NULL;
 		list_del_init(&OCFS2_I(inode)->ip_handle_list);
 
-		up(&inode->i_sem);
+		mutex_unlock(&inode->i_mutex);
 		iput(inode);
 	}
 }
@@ -1433,10 +1433,10 @@
 		goto out;
 	}
 
-	down(&orphan_dir_inode->i_sem);
+	mutex_lock(&orphan_dir_inode->i_mutex);
 	status = ocfs2_meta_lock(orphan_dir_inode, NULL, NULL, 0);
 	if (status < 0) {
-		up(&orphan_dir_inode->i_sem);
+		mutex_unlock(&orphan_dir_inode->i_mutex);
 		mlog_errno(status);
 		goto out;
 	}
@@ -1451,7 +1451,7 @@
 		if (!bh)
 			status = -EINVAL;
 		if (status < 0) {
-			up(&orphan_dir_inode->i_sem);
+			mutex_unlock(&orphan_dir_inode->i_mutex);
 			if (bh)
 				brelse(bh);
 			mlog_errno(status);
@@ -1465,7 +1465,7 @@
 
 			if (!ocfs2_check_dir_entry(orphan_dir_inode,
 						  de, bh, local)) {
-				up(&orphan_dir_inode->i_sem);
+				mutex_unlock(&orphan_dir_inode->i_mutex);
 				status = -EINVAL;
 				mlog_errno(status);
 				brelse(bh);
@@ -1509,7 +1509,7 @@
 		}
 		brelse(bh);
 	}
-	up(&orphan_dir_inode->i_sem);
+	mutex_unlock(&orphan_dir_inode->i_mutex);
 
 	ocfs2_meta_unlock(orphan_dir_inode, 0);
 	have_disk_lock = 0;
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c
index fe373a2..149b351 100644
--- a/fs/ocfs2/localalloc.c
+++ b/fs/ocfs2/localalloc.c
@@ -334,7 +334,7 @@
 		goto bail;
 	}
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 
 	status = ocfs2_read_block(osb, OCFS2_I(inode)->ip_blkno,
 				  &alloc_bh, 0, inode);
@@ -367,7 +367,7 @@
 		brelse(alloc_bh);
 
 	if (inode) {
-		up(&inode->i_sem);
+		mutex_unlock(&inode->i_mutex);
 		iput(inode);
 	}
 
@@ -446,7 +446,7 @@
 
 /*
  * make sure we've got at least bitswanted contiguous bits in the
- * local alloc. You lose them when you drop i_sem.
+ * local alloc. You lose them when you drop i_mutex.
  *
  * We will add ourselves to the transaction passed in, but may start
  * our own in order to shift windows.
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 48bf7f0..364d64b 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -169,7 +169,7 @@
  */
 static void ocfs2_write_super(struct super_block *sb)
 {
-	if (down_trylock(&sb->s_lock) == 0)
+	if (mutex_trylock(&sb->s_lock) != 0)
 		BUG();
 	sb->s_dirt = 0;
 }
diff --git a/fs/open.c b/fs/open.c
index 75f3329..a3b3a9b 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -211,9 +211,9 @@
 		newattrs.ia_valid |= ATTR_FILE;
 	}
 
-	down(&dentry->d_inode->i_sem);
+	mutex_lock(&dentry->d_inode->i_mutex);
 	err = notify_change(dentry, &newattrs);
-	up(&dentry->d_inode->i_sem);
+	mutex_unlock(&dentry->d_inode->i_mutex);
 	return err;
 }
 
@@ -398,9 +398,9 @@
 		    (error = vfs_permission(&nd, MAY_WRITE)) != 0)
 			goto dput_and_out;
 	}
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	error = notify_change(nd.dentry, &newattrs);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 dput_and_out:
 	path_release(&nd);
 out:
@@ -451,9 +451,9 @@
 		    (error = vfs_permission(&nd, MAY_WRITE)) != 0)
 			goto dput_and_out;
 	}
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	error = notify_change(nd.dentry, &newattrs);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 dput_and_out:
 	path_release(&nd);
 out:
@@ -620,13 +620,13 @@
 	err = -EPERM;
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 		goto out_putf;
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	if (mode == (mode_t) -1)
 		mode = inode->i_mode;
 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
 	err = notify_change(dentry, &newattrs);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 
 out_putf:
 	fput(file);
@@ -654,13 +654,13 @@
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 		goto dput_and_out;
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	if (mode == (mode_t) -1)
 		mode = inode->i_mode;
 	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
 	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
 	error = notify_change(nd.dentry, &newattrs);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 
 dput_and_out:
 	path_release(&nd);
@@ -696,9 +696,9 @@
 	}
 	if (!S_ISDIR(inode->i_mode))
 		newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID;
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	error = notify_change(dentry, &newattrs);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 out:
 	return error;
 }
diff --git a/fs/partitions/Kconfig b/fs/partitions/Kconfig
index e227a04..7490cc9 100644
--- a/fs/partitions/Kconfig
+++ b/fs/partitions/Kconfig
@@ -21,26 +21,30 @@
 	  Support hard disks partitioned under Acorn operating systems.
 
 config ACORN_PARTITION_CUMANA
-	bool "Cumana partition support" if PARTITION_ADVANCED && ACORN_PARTITION
+	bool "Cumana partition support" if PARTITION_ADVANCED
 	default y if ARCH_ACORN
+	depends on ACORN_PARTITION
 	help
 	  Say Y here if you would like to use hard disks under Linux which
 	  were partitioned using the Cumana interface on Acorn machines.
 
 config ACORN_PARTITION_EESOX
-	bool "EESOX partition support" if PARTITION_ADVANCED && ACORN_PARTITION
+	bool "EESOX partition support" if PARTITION_ADVANCED
 	default y if ARCH_ACORN
+	depends on ACORN_PARTITION
 
 config ACORN_PARTITION_ICS
-	bool "ICS partition support" if PARTITION_ADVANCED && ACORN_PARTITION
+	bool "ICS partition support" if PARTITION_ADVANCED
 	default y if ARCH_ACORN
+	depends on ACORN_PARTITION
 	help
 	  Say Y here if you would like to use hard disks under Linux which
 	  were partitioned using the ICS interface on Acorn machines.
 
 config ACORN_PARTITION_ADFS
-	bool "Native filecore partition support" if PARTITION_ADVANCED && ACORN_PARTITION
+	bool "Native filecore partition support" if PARTITION_ADVANCED
 	default y if ARCH_ACORN
+	depends on ACORN_PARTITION
 	help
 	  The Acorn Disc Filing System is the standard file system of the
 	  RiscOS operating system which runs on Acorn's ARM-based Risc PC
@@ -48,15 +52,17 @@
 	  `Y' here, Linux will support disk partitions created under ADFS.
 
 config ACORN_PARTITION_POWERTEC
-	bool "PowerTec partition support" if PARTITION_ADVANCED && ACORN_PARTITION
+	bool "PowerTec partition support" if PARTITION_ADVANCED
 	default y if ARCH_ACORN
+	depends on ACORN_PARTITION
 	help
 	  Support reading partition tables created on Acorn machines using
 	  the PowerTec SCSI drive.
 
 config ACORN_PARTITION_RISCIX
-	bool "RISCiX partition support" if PARTITION_ADVANCED && ACORN_PARTITION
+	bool "RISCiX partition support" if PARTITION_ADVANCED
 	default y if ARCH_ACORN
+	depends on ACORN_PARTITION
 	help
 	  Once upon a time, there was a native Unix port for the Acorn series
 	  of machines called RISCiX.  If you say 'Y' here, Linux will be able
@@ -224,5 +230,3 @@
 	  Say Y here if you would like to use hard disks under Linux which
 	  were partitioned using EFI GPT.  Presently only useful on the
 	  IA-64 platform.
-
-#      define_bool CONFIG_ACORN_PARTITION_CUMANA y
diff --git a/fs/pipe.c b/fs/pipe.c
index 66aa0b9..acb030b 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -44,10 +44,10 @@
 	 * is considered a noninteractive wait:
 	 */
 	prepare_to_wait(PIPE_WAIT(*inode), &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE);
-	up(PIPE_SEM(*inode));
+	mutex_unlock(PIPE_MUTEX(*inode));
 	schedule();
 	finish_wait(PIPE_WAIT(*inode), &wait);
-	down(PIPE_SEM(*inode));
+	mutex_lock(PIPE_MUTEX(*inode));
 }
 
 static inline int
@@ -136,7 +136,7 @@
 
 	do_wakeup = 0;
 	ret = 0;
-	down(PIPE_SEM(*inode));
+	mutex_lock(PIPE_MUTEX(*inode));
 	info = inode->i_pipe;
 	for (;;) {
 		int bufs = info->nrbufs;
@@ -200,7 +200,7 @@
 		}
 		pipe_wait(inode);
 	}
-	up(PIPE_SEM(*inode));
+	mutex_unlock(PIPE_MUTEX(*inode));
 	/* Signal writers asynchronously that there is more room.  */
 	if (do_wakeup) {
 		wake_up_interruptible(PIPE_WAIT(*inode));
@@ -237,7 +237,7 @@
 
 	do_wakeup = 0;
 	ret = 0;
-	down(PIPE_SEM(*inode));
+	mutex_lock(PIPE_MUTEX(*inode));
 	info = inode->i_pipe;
 
 	if (!PIPE_READERS(*inode)) {
@@ -341,7 +341,7 @@
 		PIPE_WAITING_WRITERS(*inode)--;
 	}
 out:
-	up(PIPE_SEM(*inode));
+	mutex_unlock(PIPE_MUTEX(*inode));
 	if (do_wakeup) {
 		wake_up_interruptible(PIPE_WAIT(*inode));
 		kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN);
@@ -381,7 +381,7 @@
 
 	switch (cmd) {
 		case FIONREAD:
-			down(PIPE_SEM(*inode));
+			mutex_lock(PIPE_MUTEX(*inode));
 			info =  inode->i_pipe;
 			count = 0;
 			buf = info->curbuf;
@@ -390,7 +390,7 @@
 				count += info->bufs[buf].len;
 				buf = (buf+1) & (PIPE_BUFFERS-1);
 			}
-			up(PIPE_SEM(*inode));
+			mutex_unlock(PIPE_MUTEX(*inode));
 			return put_user(count, (int __user *)arg);
 		default:
 			return -EINVAL;
@@ -433,7 +433,7 @@
 static int
 pipe_release(struct inode *inode, int decr, int decw)
 {
-	down(PIPE_SEM(*inode));
+	mutex_lock(PIPE_MUTEX(*inode));
 	PIPE_READERS(*inode) -= decr;
 	PIPE_WRITERS(*inode) -= decw;
 	if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) {
@@ -443,7 +443,7 @@
 		kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN);
 		kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT);
 	}
-	up(PIPE_SEM(*inode));
+	mutex_unlock(PIPE_MUTEX(*inode));
 
 	return 0;
 }
@@ -454,9 +454,9 @@
 	struct inode *inode = filp->f_dentry->d_inode;
 	int retval;
 
-	down(PIPE_SEM(*inode));
+	mutex_lock(PIPE_MUTEX(*inode));
 	retval = fasync_helper(fd, filp, on, PIPE_FASYNC_READERS(*inode));
-	up(PIPE_SEM(*inode));
+	mutex_unlock(PIPE_MUTEX(*inode));
 
 	if (retval < 0)
 		return retval;
@@ -471,9 +471,9 @@
 	struct inode *inode = filp->f_dentry->d_inode;
 	int retval;
 
-	down(PIPE_SEM(*inode));
+	mutex_lock(PIPE_MUTEX(*inode));
 	retval = fasync_helper(fd, filp, on, PIPE_FASYNC_WRITERS(*inode));
-	up(PIPE_SEM(*inode));
+	mutex_unlock(PIPE_MUTEX(*inode));
 
 	if (retval < 0)
 		return retval;
@@ -488,14 +488,14 @@
 	struct inode *inode = filp->f_dentry->d_inode;
 	int retval;
 
-	down(PIPE_SEM(*inode));
+	mutex_lock(PIPE_MUTEX(*inode));
 
 	retval = fasync_helper(fd, filp, on, PIPE_FASYNC_READERS(*inode));
 
 	if (retval >= 0)
 		retval = fasync_helper(fd, filp, on, PIPE_FASYNC_WRITERS(*inode));
 
-	up(PIPE_SEM(*inode));
+	mutex_unlock(PIPE_MUTEX(*inode));
 
 	if (retval < 0)
 		return retval;
@@ -534,9 +534,9 @@
 {
 	/* We could have perhaps used atomic_t, but this and friends
 	   below are the only places.  So it doesn't seem worthwhile.  */
-	down(PIPE_SEM(*inode));
+	mutex_lock(PIPE_MUTEX(*inode));
 	PIPE_READERS(*inode)++;
-	up(PIPE_SEM(*inode));
+	mutex_unlock(PIPE_MUTEX(*inode));
 
 	return 0;
 }
@@ -544,9 +544,9 @@
 static int
 pipe_write_open(struct inode *inode, struct file *filp)
 {
-	down(PIPE_SEM(*inode));
+	mutex_lock(PIPE_MUTEX(*inode));
 	PIPE_WRITERS(*inode)++;
-	up(PIPE_SEM(*inode));
+	mutex_unlock(PIPE_MUTEX(*inode));
 
 	return 0;
 }
@@ -554,12 +554,12 @@
 static int
 pipe_rdwr_open(struct inode *inode, struct file *filp)
 {
-	down(PIPE_SEM(*inode));
+	mutex_lock(PIPE_MUTEX(*inode));
 	if (filp->f_mode & FMODE_READ)
 		PIPE_READERS(*inode)++;
 	if (filp->f_mode & FMODE_WRITE)
 		PIPE_WRITERS(*inode)++;
-	up(PIPE_SEM(*inode));
+	mutex_unlock(PIPE_MUTEX(*inode));
 
 	return 0;
 }
diff --git a/fs/quota.c b/fs/quota.c
index 612e04d..d14d872 100644
--- a/fs/quota.c
+++ b/fs/quota.c
@@ -168,7 +168,7 @@
 	sync_blockdev(sb->s_bdev);
 
 	/* Now when everything is written we can discard the pagecache so
-	 * that userspace sees the changes. We need i_sem and so we could
+	 * that userspace sees the changes. We need i_mutex and so we could
 	 * not do it inside dqonoff_sem. Moreover we need to be carefull
 	 * about races with quotaoff() (that is the reason why we have own
 	 * reference to inode). */
@@ -184,9 +184,9 @@
 	up(&sb_dqopt(sb)->dqonoff_sem);
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		if (discard[cnt]) {
-			down(&discard[cnt]->i_sem);
+			mutex_lock(&discard[cnt]->i_mutex);
 			truncate_inode_pages(&discard[cnt]->i_data, 0);
-			up(&discard[cnt]->i_sem);
+			mutex_unlock(&discard[cnt]->i_mutex);
 			iput(discard[cnt]);
 		}
 	}
diff --git a/fs/read_write.c b/fs/read_write.c
index df3468a..3f7a1a6 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -33,7 +33,7 @@
 	long long retval;
 	struct inode *inode = file->f_mapping->host;
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	switch (origin) {
 		case 2:
 			offset += inode->i_size;
@@ -49,7 +49,7 @@
 		}
 		retval = offset;
 	}
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	return retval;
 }
 
diff --git a/fs/readdir.c b/fs/readdir.c
index b03579b..b610932 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -30,13 +30,13 @@
 	if (res)
 		goto out;
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	res = -ENOENT;
 	if (!IS_DEADDIR(inode)) {
 		res = file->f_op->readdir(file, buf, filler);
 		file_accessed(file);
 	}
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 out:
 	return res;
 }
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index 7892a86..127e7d2 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -49,7 +49,7 @@
 	}
 
 	reiserfs_write_lock(inode->i_sb);
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	/* freeing preallocation only involves relogging blocks that
 	 * are already in the current transaction.  preallocation gets
 	 * freed at the end of each transaction, so it is impossible for
@@ -100,7 +100,7 @@
 		err = reiserfs_truncate_file(inode, 0);
 	}
       out:
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	reiserfs_write_unlock(inode->i_sb);
 	return err;
 }
@@ -1342,7 +1342,7 @@
 	if (unlikely(!access_ok(VERIFY_READ, buf, count)))
 		return -EFAULT;
 
-	down(&inode->i_sem);	// locks the entire file for just us
+	mutex_lock(&inode->i_mutex);	// locks the entire file for just us
 
 	pos = *ppos;
 
@@ -1532,12 +1532,12 @@
 		    generic_osync_inode(inode, file->f_mapping,
 					OSYNC_METADATA | OSYNC_DATA);
 
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	reiserfs_async_progress_wait(inode->i_sb);
 	return (already_written != 0) ? already_written : res;
 
       out:
-	up(&inode->i_sem);	// unlock the file on exit.
+	mutex_unlock(&inode->i_mutex);	// unlock the file on exit.
 	return res;
 }
 
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index a5e3a0d..ffa34b8 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -40,12 +40,12 @@
 
 	/* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */
 	if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) {	/* also handles bad_inode case */
-		down(&inode->i_sem);
+		mutex_lock(&inode->i_mutex);
 
 		reiserfs_delete_xattrs(inode);
 
 		if (journal_begin(&th, inode->i_sb, jbegin_count)) {
-			up(&inode->i_sem);
+			mutex_unlock(&inode->i_mutex);
 			goto out;
 		}
 		reiserfs_update_inode_transaction(inode);
@@ -59,11 +59,11 @@
 			DQUOT_FREE_INODE(inode);
 
 		if (journal_end(&th, inode->i_sb, jbegin_count)) {
-			up(&inode->i_sem);
+			mutex_unlock(&inode->i_mutex);
 			goto out;
 		}
 
-		up(&inode->i_sem);
+		mutex_unlock(&inode->i_mutex);
 
 		/* check return value from reiserfs_delete_object after
 		 * ending the transaction
@@ -551,7 +551,7 @@
 
 	/* we don't have to make sure the conversion did not happen while
 	 ** we were locking the page because anyone that could convert
-	 ** must first take i_sem.
+	 ** must first take i_mutex.
 	 **
 	 ** We must fix the tail page for writing because it might have buffers
 	 ** that are mapped, but have a block number of 0.  This indicates tail
@@ -586,7 +586,7 @@
 	BUG_ON(!th->t_trans_id);
 
 #ifdef REISERFS_PREALLOCATE
-	if (!(flags & GET_BLOCK_NO_ISEM)) {
+	if (!(flags & GET_BLOCK_NO_IMUX)) {
 		return reiserfs_new_unf_blocknrs2(th, inode, allocated_block_nr,
 						  path, block);
 	}
@@ -2318,7 +2318,7 @@
 	/* this is where we fill in holes in the file. */
 	if (use_get_block) {
 		retval = reiserfs_get_block(inode, block, bh_result,
-					    GET_BLOCK_CREATE | GET_BLOCK_NO_ISEM
+					    GET_BLOCK_CREATE | GET_BLOCK_NO_IMUX
 					    | GET_BLOCK_NO_DANGLE);
 		if (!retval) {
 			if (!buffer_mapped(bh_result)
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
index 81fc002..ba8bf8d 100644
--- a/fs/reiserfs/ioctl.c
+++ b/fs/reiserfs/ioctl.c
@@ -120,7 +120,7 @@
 	/* we need to make sure nobody is changing the file size beneath
 	 ** us
 	 */
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 
 	write_from = inode->i_size & (blocksize - 1);
 	/* if we are on a block boundary, we are already unpacked.  */
@@ -156,7 +156,7 @@
 	page_cache_release(page);
 
       out:
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	reiserfs_write_unlock(inode->i_sb);
 	return retval;
 }
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 42afb5b..397d959 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -2211,7 +2211,7 @@
 	size_t towrite = len;
 	struct buffer_head tmp_bh, *bh;
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	while (towrite > 0) {
 		tocopy = sb->s_blocksize - offset < towrite ?
 		    sb->s_blocksize - offset : towrite;
@@ -2250,7 +2250,7 @@
 	inode->i_version++;
 	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 	mark_inode_dirty(inode);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	return len - towrite;
 }
 
diff --git a/fs/reiserfs/tail_conversion.c b/fs/reiserfs/tail_conversion.c
index c92e124..196e971 100644
--- a/fs/reiserfs/tail_conversion.c
+++ b/fs/reiserfs/tail_conversion.c
@@ -205,7 +205,7 @@
 					 1) * p_s_sb->s_blocksize;
 	pos1 = pos;
 
-	// we are protected by i_sem. The tail can not disapper, not
+	// we are protected by i_mutex. The tail can not disapper, not
 	// append can be done either
 	// we are in truncate or packing tail in file_release
 
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index 02091ea..f1895f0 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -67,11 +67,11 @@
 		goto out;
 	} else if (!xaroot->d_inode) {
 		int err;
-		down(&privroot->d_inode->i_sem);
+		mutex_lock(&privroot->d_inode->i_mutex);
 		err =
 		    privroot->d_inode->i_op->mkdir(privroot->d_inode, xaroot,
 						   0700);
-		up(&privroot->d_inode->i_sem);
+		mutex_unlock(&privroot->d_inode->i_mutex);
 
 		if (err) {
 			dput(xaroot);
@@ -219,7 +219,7 @@
 	} else if (flags & XATTR_REPLACE || flags & FL_READONLY) {
 		goto out;
 	} else {
-		/* inode->i_sem is down, so nothing else can try to create
+		/* inode->i_mutex is down, so nothing else can try to create
 		 * the same xattr */
 		err = xadir->d_inode->i_op->create(xadir->d_inode, xafile,
 						   0700 | S_IFREG, NULL);
@@ -268,7 +268,7 @@
  * and don't mess with f->f_pos, but the idea is the same.  Do some
  * action on each and every entry in the directory.
  *
- * we're called with i_sem held, so there are no worries about the directory
+ * we're called with i_mutex held, so there are no worries about the directory
  * changing underneath us.
  */
 static int __xattr_readdir(struct file *filp, void *dirent, filldir_t filldir)
@@ -426,7 +426,7 @@
 	int res = -ENOTDIR;
 	if (!file->f_op || !file->f_op->readdir)
 		goto out;
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 //        down(&inode->i_zombie);
 	res = -ENOENT;
 	if (!IS_DEADDIR(inode)) {
@@ -435,7 +435,7 @@
 		unlock_kernel();
 	}
 //        up(&inode->i_zombie);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
       out:
 	return res;
 }
@@ -480,7 +480,7 @@
 /* Generic extended attribute operations that can be used by xa plugins */
 
 /*
- * inode->i_sem: down
+ * inode->i_mutex: down
  */
 int
 reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
@@ -535,7 +535,7 @@
 	/* Resize it so we're ok to write there */
 	newattrs.ia_size = buffer_size;
 	newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
-	down(&xinode->i_sem);
+	mutex_lock(&xinode->i_mutex);
 	err = notify_change(fp->f_dentry, &newattrs);
 	if (err)
 		goto out_filp;
@@ -598,7 +598,7 @@
 	}
 
       out_filp:
-	up(&xinode->i_sem);
+	mutex_unlock(&xinode->i_mutex);
 	fput(fp);
 
       out:
@@ -606,7 +606,7 @@
 }
 
 /*
- * inode->i_sem: down
+ * inode->i_mutex: down
  */
 int
 reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer,
@@ -793,7 +793,7 @@
 
 }
 
-/* This is called w/ inode->i_sem downed */
+/* This is called w/ inode->i_mutex downed */
 int reiserfs_delete_xattrs(struct inode *inode)
 {
 	struct file *fp;
@@ -946,7 +946,7 @@
 
 /*
  * Inode operation getxattr()
- * Preliminary locking: we down dentry->d_inode->i_sem
+ * Preliminary locking: we down dentry->d_inode->i_mutex
  */
 ssize_t
 reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer,
@@ -970,7 +970,7 @@
 /*
  * Inode operation setxattr()
  *
- * dentry->d_inode->i_sem down
+ * dentry->d_inode->i_mutex down
  */
 int
 reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value,
@@ -1008,7 +1008,7 @@
 /*
  * Inode operation removexattr()
  *
- * dentry->d_inode->i_sem down
+ * dentry->d_inode->i_mutex down
  */
 int reiserfs_removexattr(struct dentry *dentry, const char *name)
 {
@@ -1091,7 +1091,7 @@
 /*
  * Inode operation listxattr()
  *
- * Preliminary locking: we down dentry->d_inode->i_sem
+ * Preliminary locking: we down dentry->d_inode->i_mutex
  */
 ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size)
 {
@@ -1289,9 +1289,9 @@
 		if (!IS_ERR(dentry)) {
 			if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) {
 				struct inode *inode = dentry->d_parent->d_inode;
-				down(&inode->i_sem);
+				mutex_lock(&inode->i_mutex);
 				err = inode->i_op->mkdir(inode, dentry, 0700);
-				up(&inode->i_sem);
+				mutex_unlock(&inode->i_mutex);
 				if (err) {
 					dput(dentry);
 					dentry = NULL;
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
index a47ac9a..2dc9535 100644
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -174,7 +174,7 @@
 /*
  * Inode operation get_posix_acl().
  *
- * inode->i_sem: down
+ * inode->i_mutex: down
  * BKL held [before 2.5.x]
  */
 struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)
@@ -237,7 +237,7 @@
 /*
  * Inode operation set_posix_acl().
  *
- * inode->i_sem: down
+ * inode->i_mutex: down
  * BKL held [before 2.5.x]
  */
 static int
@@ -312,7 +312,7 @@
 	return error;
 }
 
-/* dir->i_sem: down,
+/* dir->i_mutex: locked,
  * inode is new and not released into the wild yet */
 int
 reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry,
diff --git a/fs/relayfs/inode.c b/fs/relayfs/inode.c
index 7b7f2cb..3835230 100644
--- a/fs/relayfs/inode.c
+++ b/fs/relayfs/inode.c
@@ -109,7 +109,7 @@
 	}
 
 	parent = dget(parent);
-	down(&parent->d_inode->i_sem);
+	mutex_lock(&parent->d_inode->i_mutex);
 	d = lookup_one_len(name, parent, strlen(name));
 	if (IS_ERR(d)) {
 		d = NULL;
@@ -139,7 +139,7 @@
 	simple_release_fs(&relayfs_mount, &relayfs_mount_count);
 
 exit:
-	up(&parent->d_inode->i_sem);
+	mutex_unlock(&parent->d_inode->i_mutex);
 	dput(parent);
 	return d;
 }
@@ -204,7 +204,7 @@
 		return -EINVAL;
 
 	parent = dget(parent);
-	down(&parent->d_inode->i_sem);
+	mutex_lock(&parent->d_inode->i_mutex);
 	if (dentry->d_inode) {
 		if (S_ISDIR(dentry->d_inode->i_mode))
 			error = simple_rmdir(parent->d_inode, dentry);
@@ -215,7 +215,7 @@
 	}
 	if (!error)
 		dput(dentry);
-	up(&parent->d_inode->i_sem);
+	mutex_unlock(&parent->d_inode->i_mutex);
 	dput(parent);
 
 	if (!error)
@@ -476,7 +476,7 @@
 	ssize_t ret = 0;
 	void *from;
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	if(!relay_file_read_avail(buf, *ppos))
 		goto out;
 
@@ -494,7 +494,7 @@
 	relay_file_read_consume(buf, read_start, count);
 	*ppos = relay_file_read_end_pos(buf, read_start, count);
 out:
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	return ret;
 }
 
diff --git a/fs/super.c b/fs/super.c
index 0a30e51..c177b92 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -72,7 +72,7 @@
 		INIT_HLIST_HEAD(&s->s_anon);
 		INIT_LIST_HEAD(&s->s_inodes);
 		init_rwsem(&s->s_umount);
-		sema_init(&s->s_lock, 1);
+		mutex_init(&s->s_lock);
 		down_write(&s->s_umount);
 		s->s_count = S_BIAS;
 		atomic_set(&s->s_active, 1);
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index d367803..49bd219 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -99,7 +99,7 @@
 	int error;
 	umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
 
-	down(&p->d_inode->i_sem);
+	mutex_lock(&p->d_inode->i_mutex);
 	*d = lookup_one_len(n, p, strlen(n));
 	if (!IS_ERR(*d)) {
 		error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, SYSFS_DIR);
@@ -122,7 +122,7 @@
 		dput(*d);
 	} else
 		error = PTR_ERR(*d);
-	up(&p->d_inode->i_sem);
+	mutex_unlock(&p->d_inode->i_mutex);
 	return error;
 }
 
@@ -246,7 +246,7 @@
 	struct dentry * parent = dget(d->d_parent);
 	struct sysfs_dirent * sd;
 
-	down(&parent->d_inode->i_sem);
+	mutex_lock(&parent->d_inode->i_mutex);
 	d_delete(d);
 	sd = d->d_fsdata;
  	list_del_init(&sd->s_sibling);
@@ -257,7 +257,7 @@
 	pr_debug(" o %s removing done (%d)\n",d->d_name.name,
 		 atomic_read(&d->d_count));
 
-	up(&parent->d_inode->i_sem);
+	mutex_unlock(&parent->d_inode->i_mutex);
 	dput(parent);
 }
 
@@ -286,7 +286,7 @@
 		return;
 
 	pr_debug("sysfs %s: removing dir\n",dentry->d_name.name);
-	down(&dentry->d_inode->i_sem);
+	mutex_lock(&dentry->d_inode->i_mutex);
 	parent_sd = dentry->d_fsdata;
 	list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) {
 		if (!sd->s_element || !(sd->s_type & SYSFS_NOT_PINNED))
@@ -295,7 +295,7 @@
 		sysfs_drop_dentry(sd, dentry);
 		sysfs_put(sd);
 	}
-	up(&dentry->d_inode->i_sem);
+	mutex_unlock(&dentry->d_inode->i_mutex);
 
 	remove_dir(dentry);
 	/**
@@ -318,7 +318,7 @@
 	down_write(&sysfs_rename_sem);
 	parent = kobj->parent->dentry;
 
-	down(&parent->d_inode->i_sem);
+	mutex_lock(&parent->d_inode->i_mutex);
 
 	new_dentry = lookup_one_len(new_name, parent, strlen(new_name));
 	if (!IS_ERR(new_dentry)) {
@@ -334,7 +334,7 @@
 			error = -EEXIST;
 		dput(new_dentry);
 	}
-	up(&parent->d_inode->i_sem);	
+	mutex_unlock(&parent->d_inode->i_mutex);
 	up_write(&sysfs_rename_sem);
 
 	return error;
@@ -345,9 +345,9 @@
 	struct dentry * dentry = file->f_dentry;
 	struct sysfs_dirent * parent_sd = dentry->d_fsdata;
 
-	down(&dentry->d_inode->i_sem);
+	mutex_lock(&dentry->d_inode->i_mutex);
 	file->private_data = sysfs_new_dirent(parent_sd, NULL);
-	up(&dentry->d_inode->i_sem);
+	mutex_unlock(&dentry->d_inode->i_mutex);
 
 	return file->private_data ? 0 : -ENOMEM;
 
@@ -358,9 +358,9 @@
 	struct dentry * dentry = file->f_dentry;
 	struct sysfs_dirent * cursor = file->private_data;
 
-	down(&dentry->d_inode->i_sem);
+	mutex_lock(&dentry->d_inode->i_mutex);
 	list_del_init(&cursor->s_sibling);
-	up(&dentry->d_inode->i_sem);
+	mutex_unlock(&dentry->d_inode->i_mutex);
 
 	release_sysfs_dirent(cursor);
 
@@ -436,7 +436,7 @@
 {
 	struct dentry * dentry = file->f_dentry;
 
-	down(&dentry->d_inode->i_sem);
+	mutex_lock(&dentry->d_inode->i_mutex);
 	switch (origin) {
 		case 1:
 			offset += file->f_pos;
@@ -444,7 +444,7 @@
 			if (offset >= 0)
 				break;
 		default:
-			up(&file->f_dentry->d_inode->i_sem);
+			mutex_unlock(&file->f_dentry->d_inode->i_mutex);
 			return -EINVAL;
 	}
 	if (offset != file->f_pos) {
@@ -468,7 +468,7 @@
 			list_add_tail(&cursor->s_sibling, p);
 		}
 	}
-	up(&dentry->d_inode->i_sem);
+	mutex_unlock(&dentry->d_inode->i_mutex);
 	return offset;
 }
 
@@ -483,4 +483,3 @@
 EXPORT_SYMBOL_GPL(sysfs_create_dir);
 EXPORT_SYMBOL_GPL(sysfs_remove_dir);
 EXPORT_SYMBOL_GPL(sysfs_rename_dir);
-
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 4013d79..d0e3d84 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -364,9 +364,9 @@
 	umode_t mode = (attr->mode & S_IALLUGO) | S_IFREG;
 	int error = 0;
 
-	down(&dir->d_inode->i_sem);
+	mutex_lock(&dir->d_inode->i_mutex);
 	error = sysfs_make_dirent(parent_sd, NULL, (void *) attr, mode, type);
-	up(&dir->d_inode->i_sem);
+	mutex_unlock(&dir->d_inode->i_mutex);
 
 	return error;
 }
@@ -398,7 +398,7 @@
 	struct dentry * victim;
 	int res = -ENOENT;
 
-	down(&dir->d_inode->i_sem);
+	mutex_lock(&dir->d_inode->i_mutex);
 	victim = lookup_one_len(attr->name, dir, strlen(attr->name));
 	if (!IS_ERR(victim)) {
 		/* make sure dentry is really there */
@@ -420,7 +420,7 @@
 		 */
 		dput(victim);
 	}
-	up(&dir->d_inode->i_sem);
+	mutex_unlock(&dir->d_inode->i_mutex);
 
 	return res;
 }
@@ -441,22 +441,22 @@
 	struct iattr newattrs;
 	int res = -ENOENT;
 
-	down(&dir->d_inode->i_sem);
+	mutex_lock(&dir->d_inode->i_mutex);
 	victim = lookup_one_len(attr->name, dir, strlen(attr->name));
 	if (!IS_ERR(victim)) {
 		if (victim->d_inode &&
 		    (victim->d_parent->d_inode == dir->d_inode)) {
 			inode = victim->d_inode;
-			down(&inode->i_sem);
+			mutex_lock(&inode->i_mutex);
 			newattrs.ia_mode = (mode & S_IALLUGO) |
 						(inode->i_mode & ~S_IALLUGO);
 			newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
 			res = notify_change(victim, &newattrs);
-			up(&inode->i_sem);
+			mutex_unlock(&inode->i_mutex);
 		}
 		dput(victim);
 	}
-	up(&dir->d_inode->i_sem);
+	mutex_unlock(&dir->d_inode->i_mutex);
 
 	return res;
 }
@@ -480,4 +480,3 @@
 EXPORT_SYMBOL_GPL(sysfs_create_file);
 EXPORT_SYMBOL_GPL(sysfs_remove_file);
 EXPORT_SYMBOL_GPL(sysfs_update_file);
-
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 970a33f..c313321 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -201,7 +201,7 @@
 
 /*
  * Unhashes the dentry corresponding to given sysfs_dirent
- * Called with parent inode's i_sem held.
+ * Called with parent inode's i_mutex held.
  */
 void sysfs_drop_dentry(struct sysfs_dirent * sd, struct dentry * parent)
 {
@@ -232,7 +232,7 @@
 		/* no inode means this hasn't been made visible yet */
 		return;
 
-	down(&dir->d_inode->i_sem);
+	mutex_lock(&dir->d_inode->i_mutex);
 	list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
 		if (!sd->s_element)
 			continue;
@@ -243,7 +243,5 @@
 			break;
 		}
 	}
-	up(&dir->d_inode->i_sem);
+	mutex_unlock(&dir->d_inode->i_mutex);
 }
-
-
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index de402fa..e38d633 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -86,9 +86,9 @@
 
 	BUG_ON(!kobj || !kobj->dentry || !name);
 
-	down(&dentry->d_inode->i_sem);
+	mutex_lock(&dentry->d_inode->i_mutex);
 	error = sysfs_add_link(dentry, name, target);
-	up(&dentry->d_inode->i_sem);
+	mutex_unlock(&dentry->d_inode->i_mutex);
 	return error;
 }
 
@@ -177,4 +177,3 @@
 
 EXPORT_SYMBOL_GPL(sysfs_create_link);
 EXPORT_SYMBOL_GPL(sysfs_remove_link);
-
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 2ba11a9..e9a42c7 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -1275,7 +1275,7 @@
 	size_t towrite = len;
 	struct buffer_head *bh;
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	while (towrite > 0) {
 		tocopy = sb->s_blocksize - offset < towrite ?
 				sb->s_blocksize - offset : towrite;
@@ -1297,7 +1297,7 @@
 	}
 out:
 	if (len == towrite) {
-		up(&inode->i_sem);
+		mutex_unlock(&inode->i_mutex);
 		return err;
 	}
 	if (inode->i_size < off+len-towrite)
@@ -1305,7 +1305,7 @@
 	inode->i_version++;
 	inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	return len - towrite;
 }
 
diff --git a/fs/xattr.c b/fs/xattr.c
index bcc2156..386a532 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -51,7 +51,7 @@
 		}
 	}
 
-	down(&d->d_inode->i_sem);
+	mutex_lock(&d->d_inode->i_mutex);
 	error = security_inode_setxattr(d, kname, kvalue, size, flags);
 	if (error)
 		goto out;
@@ -73,7 +73,7 @@
 			fsnotify_xattr(d);
 	}
 out:
-	up(&d->d_inode->i_sem);
+	mutex_unlock(&d->d_inode->i_mutex);
 	kfree(kvalue);
 	return error;
 }
@@ -323,9 +323,9 @@
 		error = security_inode_removexattr(d, kname);
 		if (error)
 			goto out;
-		down(&d->d_inode->i_sem);
+		mutex_lock(&d->d_inode->i_mutex);
 		error = d->d_inode->i_op->removexattr(d, kname);
-		up(&d->d_inode->i_sem);
+		mutex_unlock(&d->d_inode->i_mutex);
 		if (!error)
 			fsnotify_xattr(d);
 	}
diff --git a/fs/xfs/linux-2.6/mutex.h b/fs/xfs/linux-2.6/mutex.h
index ce773d8..d3369b6 100644
--- a/fs/xfs/linux-2.6/mutex.h
+++ b/fs/xfs/linux-2.6/mutex.h
@@ -19,7 +19,7 @@
 #define __XFS_SUPPORT_MUTEX_H__
 
 #include <linux/spinlock.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 
 /*
  * Map the mutex'es from IRIX to Linux semaphores.
@@ -28,12 +28,8 @@
  * callers.
  */
 #define MUTEX_DEFAULT		0x0
-typedef struct semaphore	mutex_t;
 
-#define mutex_init(lock, type, name)		sema_init(lock, 1)
-#define mutex_destroy(lock)			sema_init(lock, -99)
-#define mutex_lock(lock, num)			down(lock)
-#define mutex_trylock(lock)			(down_trylock(lock) ? 0 : 1)
-#define mutex_unlock(lock)			up(lock)
+typedef struct mutex		mutex_t;
+//#define mutex_destroy(lock)			do{}while(0)
 
 #endif /* __XFS_SUPPORT_MUTEX_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 14215a7..41c478b 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -203,7 +203,7 @@
 		ip->i_nlink = va.va_nlink;
 		ip->i_blocks = va.va_nblocks;
 
-		/* we're under i_sem so i_size can't change under us */
+		/* we're under i_mutex so i_size can't change under us */
 		if (i_size_read(ip) != va.va_size)
 			i_size_write(ip, va.va_size);
 	}
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 279e9bc..5675117 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -254,7 +254,7 @@
 	}
 
 	if (unlikely(ioflags & IO_ISDIRECT))
-		down(&inode->i_sem);
+		mutex_lock(&inode->i_mutex);
 	xfs_ilock(ip, XFS_IOLOCK_SHARED);
 
 	if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
@@ -286,7 +286,7 @@
 
 unlock_isem:
 	if (unlikely(ioflags & IO_ISDIRECT))
-		up(&inode->i_sem);
+		mutex_unlock(&inode->i_mutex);
 	return ret;
 }
 
@@ -655,7 +655,7 @@
 		iolock = XFS_IOLOCK_EXCL;
 		locktype = VRWLOCK_WRITE;
 
-		down(&inode->i_sem);
+		mutex_lock(&inode->i_mutex);
 	} else {
 		iolock = XFS_IOLOCK_SHARED;
 		locktype = VRWLOCK_WRITE_DIRECT;
@@ -686,7 +686,7 @@
 		int		dmflags = FILP_DELAY_FLAG(file);
 
 		if (need_isem)
-			dmflags |= DM_FLAGS_ISEM;
+			dmflags |= DM_FLAGS_IMUX;
 
 		xfs_iunlock(xip, XFS_ILOCK_EXCL);
 		error = XFS_SEND_DATA(xip->i_mount, DM_EVENT_WRITE, vp,
@@ -772,7 +772,7 @@
 		if (need_isem) {
 			/* demote the lock now the cached pages are gone */
 			XFS_ILOCK_DEMOTE(mp, io, XFS_IOLOCK_EXCL);
-			up(&inode->i_sem);
+			mutex_unlock(&inode->i_mutex);
 
 			iolock = XFS_IOLOCK_SHARED;
 			locktype = VRWLOCK_WRITE_DIRECT;
@@ -817,14 +817,14 @@
 
 		xfs_rwunlock(bdp, locktype);
 		if (need_isem)
-			up(&inode->i_sem);
+			mutex_unlock(&inode->i_mutex);
 		error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp,
 				DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL,
 				0, 0, 0); /* Delay flag intentionally  unused */
 		if (error)
 			goto out_nounlocks;
 		if (need_isem)
-			down(&inode->i_sem);
+			mutex_lock(&inode->i_mutex);
 		xfs_rwlock(bdp, locktype);
 		pos = xip->i_d.di_size;
 		ret = 0;
@@ -926,7 +926,7 @@
 	
 		xfs_rwunlock(bdp, locktype);
 		if (need_isem)
-			up(&inode->i_sem);
+			mutex_unlock(&inode->i_mutex);
 
 		error = sync_page_range(inode, mapping, pos, ret);
 		if (!error)
@@ -938,7 +938,7 @@
 	xfs_rwunlock(bdp, locktype);
  out_unlock_isem:
 	if (need_isem)
-		up(&inode->i_sem);
+		mutex_unlock(&inode->i_mutex);
  out_nounlocks:
 	return -error;
 }
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c
index 00b5043..772ac48 100644
--- a/fs/xfs/quota/xfs_dquot.c
+++ b/fs/xfs/quota/xfs_dquot.c
@@ -104,7 +104,7 @@
 	 */
 	if (brandnewdquot) {
 		dqp->dq_flnext = dqp->dq_flprev = dqp;
-		mutex_init(&dqp->q_qlock,  MUTEX_DEFAULT, "xdq");
+		mutex_init(&dqp->q_qlock);
 		initnsema(&dqp->q_flock, 1, "fdq");
 		sv_init(&dqp->q_pinwait, SV_DEFAULT, "pdq");
 
@@ -1382,7 +1382,7 @@
 xfs_dqlock(
 	xfs_dquot_t *dqp)
 {
-	mutex_lock(&(dqp->q_qlock), PINOD);
+	mutex_lock(&(dqp->q_qlock));
 }
 
 void
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 5328a293..bb6991a 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -167,7 +167,7 @@
 	xqm->qm_dqfree_ratio = XFS_QM_DQFREE_RATIO;
 	xqm->qm_nrefs = 0;
 #ifdef DEBUG
-	mutex_init(&qcheck_lock, MUTEX_DEFAULT, "qchk");
+	xfs_mutex_init(&qcheck_lock, MUTEX_DEFAULT, "qchk");
 #endif
 	return xqm;
 }
@@ -1166,7 +1166,7 @@
 	qinf->qi_dqreclaims = 0;
 
 	/* mutex used to serialize quotaoffs */
-	mutex_init(&qinf->qi_quotaofflock, MUTEX_DEFAULT, "qoff");
+	mutex_init(&qinf->qi_quotaofflock);
 
 	/* Precalc some constants */
 	qinf->qi_dqchunklen = XFS_FSB_TO_BB(mp, XFS_DQUOT_CLUSTER_SIZE_FSB);
@@ -1285,7 +1285,7 @@
 	char		*str,
 	int		n)
 {
-	mutex_init(&list->qh_lock, MUTEX_DEFAULT, str);
+	mutex_init(&list->qh_lock);
 	list->qh_next = NULL;
 	list->qh_version = 0;
 	list->qh_nelems = 0;
@@ -2762,7 +2762,7 @@
 xfs_qm_freelist_init(xfs_frlist_t *ql)
 {
 	ql->qh_next = ql->qh_prev = (xfs_dquot_t *) ql;
-	mutex_init(&ql->qh_lock, MUTEX_DEFAULT, "dqf");
+	mutex_init(&ql->qh_lock);
 	ql->qh_version = 0;
 	ql->qh_nelems = 0;
 }
@@ -2772,7 +2772,7 @@
 {
 	xfs_dquot_t	*dqp, *nextdqp;
 
-	mutex_lock(&ql->qh_lock, PINOD);
+	mutex_lock(&ql->qh_lock);
 	for (dqp = ql->qh_next;
 	     dqp != (xfs_dquot_t *)ql; ) {
 		xfs_dqlock(dqp);
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h
index 12da259..4568deb 100644
--- a/fs/xfs/quota/xfs_qm.h
+++ b/fs/xfs/quota/xfs_qm.h
@@ -165,7 +165,7 @@
 #define XFS_QM_IWARNLIMIT	5
 #define XFS_QM_RTBWARNLIMIT	5
 
-#define XFS_QM_LOCK(xqm)	(mutex_lock(&xqm##_lock, PINOD))
+#define XFS_QM_LOCK(xqm)	(mutex_lock(&xqm##_lock))
 #define XFS_QM_UNLOCK(xqm)	(mutex_unlock(&xqm##_lock))
 #define XFS_QM_HOLD(xqm)	((xqm)->qm_nrefs++)
 #define XFS_QM_RELE(xqm)	((xqm)->qm_nrefs--)
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c
index d9d2993..90402a1 100644
--- a/fs/xfs/quota/xfs_qm_bhv.c
+++ b/fs/xfs/quota/xfs_qm_bhv.c
@@ -363,7 +363,7 @@
 		KERN_INFO "SGI XFS Quota Management subsystem\n";
 
 	printk(message);
-	mutex_init(&xfs_Gqm_lock, MUTEX_DEFAULT, "xfs_qmlock");
+	mutex_init(&xfs_Gqm_lock);
 	vfs_bhv_set_custom(&xfs_qmops, &xfs_qmcore_xfs);
 	xfs_qm_init_procfs();
 }
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index 24690e1..86a1d09 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -233,7 +233,7 @@
 	 */
 	ASSERT(mp->m_quotainfo);
 	if (mp->m_quotainfo)
-		mutex_lock(&(XFS_QI_QOFFLOCK(mp)), PINOD);
+		mutex_lock(&(XFS_QI_QOFFLOCK(mp)));
 
 	ASSERT(mp->m_quotainfo);
 
@@ -508,7 +508,7 @@
 	/*
 	 * Switch on quota enforcement in core.
 	 */
-	mutex_lock(&(XFS_QI_QOFFLOCK(mp)), PINOD);
+	mutex_lock(&(XFS_QI_QOFFLOCK(mp)));
 	mp->m_qflags |= (flags & XFS_ALL_QUOTA_ENFD);
 	mutex_unlock(&(XFS_QI_QOFFLOCK(mp)));
 
@@ -617,7 +617,7 @@
 	 * a quotaoff from happening). (XXXThis doesn't currently happen
 	 * because we take the vfslock before calling xfs_qm_sysent).
 	 */
-	mutex_lock(&(XFS_QI_QOFFLOCK(mp)), PINOD);
+	mutex_lock(&(XFS_QI_QOFFLOCK(mp)));
 
 	/*
 	 * Get the dquot (locked), and join it to the transaction.
@@ -1426,7 +1426,7 @@
 	xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE | XFS_LOG_SYNC);
 	XFS_bflush(mp->m_ddev_targp);
 
-	mutex_lock(&qcheck_lock, PINOD);
+	mutex_lock(&qcheck_lock);
 	/* There should be absolutely no quota activity while this
 	   is going on. */
 	qmtest_udqtab = kmem_zalloc(qmtest_hashmask *
diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h
index 7a9f3be..b7ddd04 100644
--- a/fs/xfs/quota/xfs_quota_priv.h
+++ b/fs/xfs/quota/xfs_quota_priv.h
@@ -51,7 +51,7 @@
 #define XFS_QI_MPLNEXT(mp)	((mp)->m_quotainfo->qi_dqlist.qh_next)
 #define XFS_QI_MPLNDQUOTS(mp)	((mp)->m_quotainfo->qi_dqlist.qh_nelems)
 
-#define XQMLCK(h)			(mutex_lock(&((h)->qh_lock), PINOD))
+#define XQMLCK(h)			(mutex_lock(&((h)->qh_lock)))
 #define XQMUNLCK(h)			(mutex_unlock(&((h)->qh_lock)))
 #ifdef DEBUG
 struct xfs_dqhash;
diff --git a/fs/xfs/support/uuid.c b/fs/xfs/support/uuid.c
index 70ce409..69ec4f5 100644
--- a/fs/xfs/support/uuid.c
+++ b/fs/xfs/support/uuid.c
@@ -24,7 +24,7 @@
 void
 uuid_init(void)
 {
-	mutex_init(&uuid_monitor, MUTEX_DEFAULT, "uuid_monitor");
+	mutex_init(&uuid_monitor);
 }
 
 /*
@@ -94,7 +94,7 @@
 {
 	int	i, hole;
 
-	mutex_lock(&uuid_monitor, PVFS);
+	mutex_lock(&uuid_monitor);
 	for (i = 0, hole = -1; i < uuid_table_size; i++) {
 		if (uuid_is_nil(&uuid_table[i])) {
 			hole = i;
@@ -122,7 +122,7 @@
 {
 	int	i;
 
-	mutex_lock(&uuid_monitor, PVFS);
+	mutex_lock(&uuid_monitor);
 	for (i = 0; i < uuid_table_size; i++) {
 		if (uuid_is_nil(&uuid_table[i]))
 			continue;
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h
index 864bf69..b4c7f2b 100644
--- a/fs/xfs/xfs_dmapi.h
+++ b/fs/xfs/xfs_dmapi.h
@@ -152,7 +152,7 @@
 
 #define DM_FLAGS_NDELAY		0x001	/* return EAGAIN after dm_pending() */
 #define DM_FLAGS_UNWANTED	0x002	/* event not in fsys dm_eventset_t */
-#define DM_FLAGS_ISEM		0x004	/* thread holds i_sem */
+#define DM_FLAGS_IMUX		0x004	/* thread holds i_mutex */
 #define DM_FLAGS_IALLOCSEM_RD	0x010	/* thread holds i_alloc_sem rd */
 #define DM_FLAGS_IALLOCSEM_WR	0x020	/* thread holds i_alloc_sem wr */
 
@@ -161,21 +161,21 @@
  */
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
 #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
-			      DM_FLAGS_ISEM : 0)
-#define DM_SEM_FLAG_WR	(DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_ISEM)
+			      DM_FLAGS_IMUX : 0)
+#define DM_SEM_FLAG_WR	(DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_IMUX)
 #endif
 
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) && \
     (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22))
 #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
-			      DM_FLAGS_IALLOCSEM_RD : DM_FLAGS_ISEM)
-#define DM_SEM_FLAG_WR	(DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_ISEM)
+			      DM_FLAGS_IALLOCSEM_RD : DM_FLAGS_IMUX)
+#define DM_SEM_FLAG_WR	(DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_IMUX)
 #endif
 
 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,21)
 #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
-			      0 : DM_FLAGS_ISEM)
-#define DM_SEM_FLAG_WR	(DM_FLAGS_ISEM)
+			      0 : DM_FLAGS_IMUX)
+#define DM_SEM_FLAG_WR	(DM_FLAGS_IMUX)
 #endif
 
 
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 541d5dd..303af86 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -117,7 +117,7 @@
 
 	AIL_LOCKINIT(&mp->m_ail_lock, "xfs_ail");
 	spinlock_init(&mp->m_sb_lock, "xfs_sb");
-	mutex_init(&mp->m_ilock, MUTEX_DEFAULT, "xfs_ilock");
+	mutex_init(&mp->m_ilock);
 	initnsema(&mp->m_growlock, 1, "xfs_grow");
 	/*
 	 * Initialize the AIL.
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 08b2e0a..3432fd5 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -533,7 +533,7 @@
 	int		msb_delta;	/* Change to make to specified field */
 } xfs_mod_sb_t;
 
-#define	XFS_MOUNT_ILOCK(mp)	mutex_lock(&((mp)->m_ilock), PINOD)
+#define	XFS_MOUNT_ILOCK(mp)	mutex_lock(&((mp)->m_ilock))
 #define	XFS_MOUNT_IUNLOCK(mp)	mutex_unlock(&((mp)->m_ilock))
 #define	XFS_SB_LOCK(mp)		mutex_spinlock(&(mp)->m_sb_lock)
 #define	XFS_SB_UNLOCK(mp,s)	mutex_spinunlock(&(mp)->m_sb_lock,(s))
diff --git a/include/asm-alpha/atomic.h b/include/asm-alpha/atomic.h
index cb03bbe..fc77f74 100644
--- a/include/asm-alpha/atomic.h
+++ b/include/asm-alpha/atomic.h
@@ -176,6 +176,7 @@
 }
 
 #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
 #define atomic_add_unless(v, a, u)				\
 ({								\
diff --git a/include/asm-alpha/mutex.h b/include/asm-alpha/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/include/asm-alpha/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200.h b/include/asm-arm/arch-at91rm9200/at91rm9200.h
new file mode 100644
index 0000000..58f4093
--- /dev/null
+++ b/include/asm-arm/arch-at91rm9200/at91rm9200.h
@@ -0,0 +1,261 @@
+/*
+ * include/asm-arm/arch-at91rm9200/at91rm9200.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * Common definitions.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * 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.
+ */
+
+#ifndef AT91RM9200_H
+#define AT91RM9200_H
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define AT91_ID_FIQ	0	/* Advanced Interrupt Controller (FIQ) */
+#define AT91_ID_SYS	1	/* System Peripheral */
+#define AT91_ID_PIOA	2	/* Parallel IO Controller A */
+#define AT91_ID_PIOB	3	/* Parallel IO Controller B */
+#define AT91_ID_PIOC	4	/* Parallel IO Controller C */
+#define AT91_ID_PIOD	5	/* Parallel IO Controller D */
+#define AT91_ID_US0	6	/* USART 0 */
+#define AT91_ID_US1	7	/* USART 1 */
+#define AT91_ID_US2	8	/* USART 2 */
+#define AT91_ID_US3	9	/* USART 3 */
+#define AT91_ID_MCI	10	/* Multimedia Card Interface */
+#define AT91_ID_UDP	11	/* USB Device Port */
+#define AT91_ID_TWI	12	/* Two-Wire Interface */
+#define AT91_ID_SPI	13	/* Serial Peripheral Interface */
+#define AT91_ID_SSC0	14	/* Serial Synchronous Controller 0 */
+#define AT91_ID_SSC1	15	/* Serial Synchronous Controller 1 */
+#define AT91_ID_SSC2	16	/* Serial Synchronous Controller 2 */
+#define AT91_ID_TC0	17	/* Timer Counter 0 */
+#define AT91_ID_TC1	18	/* Timer Counter 1 */
+#define AT91_ID_TC2	19	/* Timer Counter 2 */
+#define AT91_ID_TC3	20	/* Timer Counter 3 */
+#define AT91_ID_TC4	21	/* Timer Counter 4 */
+#define AT91_ID_TC5	22	/* Timer Counter 5 */
+#define AT91_ID_UHP	23	/* USB Host port */
+#define AT91_ID_EMAC	24	/* Ethernet MAC */
+#define AT91_ID_IRQ0	25	/* Advanced Interrupt Controller (IRQ0) */
+#define AT91_ID_IRQ1	26	/* Advanced Interrupt Controller (IRQ1) */
+#define AT91_ID_IRQ2	27	/* Advanced Interrupt Controller (IRQ2) */
+#define AT91_ID_IRQ3	28	/* Advanced Interrupt Controller (IRQ3) */
+#define AT91_ID_IRQ4	29	/* Advanced Interrupt Controller (IRQ4) */
+#define AT91_ID_IRQ5	30	/* Advanced Interrupt Controller (IRQ5) */
+#define AT91_ID_IRQ6	31	/* Advanced Interrupt Controller (IRQ6) */
+
+
+/*
+ * Peripheral physical base addresses.
+ */
+#define AT91_BASE_TCB0		0xfffa0000
+#define AT91_BASE_TC0		0xfffa0000
+#define AT91_BASE_TC1		0xfffa0040
+#define AT91_BASE_TC2		0xfffa0080
+#define AT91_BASE_TCB1		0xfffa4000
+#define AT91_BASE_TC3		0xfffa4000
+#define AT91_BASE_TC4		0xfffa4040
+#define AT91_BASE_TC5		0xfffa4080
+#define AT91_BASE_UDP		0xfffb0000
+#define AT91_BASE_MCI		0xfffb4000
+#define AT91_BASE_TWI		0xfffb8000
+#define AT91_BASE_EMAC		0xfffbc000
+#define AT91_BASE_US0		0xfffc0000
+#define AT91_BASE_US1		0xfffc4000
+#define AT91_BASE_US2		0xfffc8000
+#define AT91_BASE_US3		0xfffcc000
+#define AT91_BASE_SSC0		0xfffd0000
+#define AT91_BASE_SSC1		0xfffd4000
+#define AT91_BASE_SSC2		0xfffd8000
+#define AT91_BASE_SPI		0xfffe0000
+#define AT91_BASE_SYS		0xfffff000
+
+
+/*
+ * PIO pin definitions (peripheral A/B multiplexing).
+ */
+#define AT91_PA0_MISO		(1 <<  0)	/* A: SPI Master-In Slave-Out */
+#define AT91_PA0_PCK3		(1 <<  0)	/* B: PMC Programmable Clock Output 3 */
+#define AT91_PA1_MOSI		(1 <<  1)	/* A: SPI Master-Out Slave-In */
+#define AT91_PA1_PCK0		(1 <<  1)	/* B: PMC Programmable Clock Output 0 */
+#define AT91_PA2_SPCK		(1 <<  2)	/* A: SPI Serial Clock */
+#define AT91_PA2_IRQ4		(1 <<  2)	/* B: External Interrupt 4 */
+#define AT91_PA3_NPCS0		(1 <<  3)	/* A: SPI Peripheral Chip Select 0 */
+#define AT91_PA3_IRQ5		(1 <<  3)	/* B: External Interrupt 5 */
+#define AT91_PA4_NPCS1		(1 <<  4)	/* A: SPI Peripheral Chip Select 1 */
+#define AT91_PA4_PCK1		(1 <<  4)	/* B: PMC Programmable Clock Output 1 */
+#define AT91_PA5_NPCS2		(1 <<  5)	/* A: SPI Peripheral Chip Select 2 */
+#define AT91_PA5_TXD3		(1 <<  5)	/* B: USART Transmit Data 3 */
+#define AT91_PA6_NPCS3		(1 <<  6)	/* A: SPI Peripheral Chip Select 3 */
+#define AT91_PA6_RXD3		(1 <<  6)	/* B: USART Receive Data 3 */
+#define AT91_PA7_ETXCK_EREFCK	(1 <<  7)	/* A: Ethernet Reference Clock / Transmit Clock */
+#define AT91_PA7_PCK2		(1 <<  7)	/* B: PMC Programmable Clock Output 2 */
+#define AT91_PA8_ETXEN		(1 <<  8)	/* A: Ethernet Transmit Enable */
+#define AT91_PA8_MCCDB		(1 <<  8)	/* B: MMC Multimedia Card B Command */
+#define AT91_PA9_ETX0		(1 <<  9)	/* A: Ethernet Transmit Data 0 */
+#define AT91_PA9_MCDB0		(1 <<  9)	/* B: MMC Multimedia Card B Data 0 */
+#define AT91_PA10_ETX1		(1 << 10)	/* A: Ethernet Transmit Data 1 */
+#define AT91_PA10_MCDB1		(1 << 10)	/* B: MMC Multimedia Card B Data 1 */
+#define AT91_PA11_ECRS_ECRSDV	(1 << 11)	/* A: Ethernet Carrier Sense / Data Valid */
+#define AT91_PA11_MCDB2		(1 << 11)	/* B: MMC Multimedia Card B Data 2 */
+#define AT91_PA12_ERX0		(1 << 12)	/* A: Ethernet Receive Data 0 */
+#define AT91_PA12_MCDB3		(1 << 12)	/* B: MMC Multimedia Card B Data 3 */
+#define AT91_PA13_ERX1		(1 << 13)	/* A: Ethernet Receive Data 1 */
+#define AT91_PA13_TCLK0		(1 << 13)	/* B: TC External Clock Input 0 */
+#define AT91_PA14_ERXER		(1 << 14)	/* A: Ethernet Receive Error */
+#define AT91_PA14_TCLK1		(1 << 14)	/* B: TC External Clock Input 1 */
+#define AT91_PA15_EMDC		(1 << 15)	/* A: Ethernet Management Data Clock */
+#define AT91_PA15_TCLK2		(1 << 15)	/* B: TC External Clock Input 2 */
+#define AT91_PA16_EMDIO		(1 << 16)	/* A: Ethernet Management Data I/O */
+#define AT91_PA16_IRQ6		(1 << 16)	/* B: External Interrupt 6 */
+#define AT91_PA17_TXD0		(1 << 17)	/* A: USART Transmit Data 0 */
+#define AT91_PA17_TIOA0		(1 << 17)	/* B: TC I/O Line A 0 */
+#define AT91_PA18_RXD0		(1 << 18)	/* A: USART Receive Data 0 */
+#define AT91_PA18_TIOB0		(1 << 18)	/* B: TC I/O Line B 0 */
+#define AT91_PA19_SCK0		(1 << 19)	/* A: USART Serial Clock 0 */
+#define AT91_PA19_TIOA1		(1 << 19)	/* B: TC I/O Line A 1 */
+#define AT91_PA20_CTS0		(1 << 20)	/* A: USART Clear To Send 0 */
+#define AT91_PA20_TIOB1		(1 << 20)	/* B: TC I/O Line B 1 */
+#define AT91_PA21_RTS0		(1 << 21)	/* A: USART Ready To Send 0 */
+#define AT91_PA21_TIOA2		(1 << 21)	/* B: TC I/O Line A 2 */
+#define AT91_PA22_RXD2		(1 << 22)	/* A: USART Receive Data 2 */
+#define AT91_PA22_TIOB2		(1 << 22)	/* B: TC I/O Line B 2 */
+#define AT91_PA23_TXD2		(1 << 23)	/* A: USART Transmit Data 2 */
+#define AT91_PA23_IRQ3		(1 << 23)	/* B: External Interrupt 3 */
+#define AT91_PA24_SCK2		(1 << 24)	/* A: USART Serial Clock 2 */
+#define AT91_PA24_PCK1		(1 << 24)	/* B: PMC Programmable Clock Output 1 */
+#define AT91_PA25_TWD		(1 << 25)	/* A: TWI Two-wire Serial Data */
+#define AT91_PA25_IRQ2		(1 << 25)	/* B: External Interrupt 2 */
+#define AT91_PA26_TWCK		(1 << 26)	/* A: TWI Two-wire Serial Clock */
+#define AT91_PA26_IRQ1		(1 << 26)	/* B: External Interrupt 1 */
+#define AT91_PA27_MCCK		(1 << 27)	/* A: MMC Multimedia Card Clock */
+#define AT91_PA27_TCLK3		(1 << 27)	/* B: TC External Clock Input 3 */
+#define AT91_PA28_MCCDA		(1 << 28)	/* A: MMC Multimedia Card A Command */
+#define AT91_PA28_TCLK4		(1 << 28)	/* B: TC External Clock Input 4 */
+#define AT91_PA29_MCDA0		(1 << 29)	/* A: MMC Multimedia Card A Data 0 */
+#define AT91_PA29_TCLK5		(1 << 29)	/* B: TC External Clock Input 5 */
+#define AT91_PA30_DRXD		(1 << 30)	/* A: DBGU Receive Data */
+#define AT91_PA30_CTS2		(1 << 30)	/* B: USART Clear To Send 2 */
+#define AT91_PA31_DTXD		(1 << 31)	/* A: DBGU Transmit Data */
+#define AT91_PA31_RTS2		(1 << 31)	/* B: USART Ready To Send 2 */
+
+#define AT91_PB0_TF0		(1 <<  0)	/* A: SSC Transmit Frame Sync 0 */
+#define AT91_PB0_RTS3		(1 <<  0)	/* B: USART Ready To Send 3 */
+#define AT91_PB1_TK0		(1 <<  1)	/* A: SSC Transmit Clock 0 */
+#define AT91_PB1_CTS3		(1 <<  1)	/* B: USART Clear To Send 3 */
+#define AT91_PB2_TD0		(1 <<  2)	/* A: SSC Transmit Data 0 */
+#define AT91_PB2_SCK3		(1 <<  2)	/* B: USART Serial Clock 3 */
+#define AT91_PB3_RD0		(1 <<  3)	/* A: SSC Receive Data 0 */
+#define AT91_PB3_MCDA1		(1 <<  3)	/* B: MMC Multimedia Card A Data 1 */
+#define AT91_PB4_RK0		(1 <<  4)	/* A: SSC Receive Clock 0 */
+#define AT91_PB4_MCDA2		(1 <<  4)	/* B: MMC Multimedia Card A Data 2 */
+#define AT91_PB5_RF0		(1 <<  5)	/* A: SSC Receive Frame Sync 0 */
+#define AT91_PB5_MCDA3		(1 <<  5)	/* B: MMC Multimedia Card A Data 3 */
+#define AT91_PB6_TF1		(1 <<  6)	/* A: SSC Transmit Frame Sync 1 */
+#define AT91_PB6_TIOA3		(1 <<  6)	/* B: TC I/O Line A 3 */
+#define AT91_PB7_TK1		(1 <<  7)	/* A: SSC Transmit Clock 1 */
+#define AT91_PB7_TIOB3		(1 <<  7)	/* B: TC I/O Line B 3 */
+#define AT91_PB8_TD1		(1 <<  8)	/* A: SSC Transmit Data 1 */
+#define AT91_PB8_TIOA4		(1 <<  8)	/* B: TC I/O Line A 4 */
+#define AT91_PB9_RD1		(1 <<  9)	/* A: SSC Receive Data 1 */
+#define AT91_PB9_TIOB4		(1 <<  9)	/* B: TC I/O Line B 4 */
+#define AT91_PB10_RK1		(1 << 10)	/* A: SSC Receive Clock 1 */
+#define AT91_PB10_TIOA5		(1 << 10)	/* B: TC I/O Line A 5 */
+#define AT91_PB11_RF1		(1 << 11)	/* A: SSC Receive Frame Sync 1 */
+#define AT91_PB11_TIOB5		(1 << 11)	/* B: TC I/O Line B 5 */
+#define AT91_PB12_TF2		(1 << 12)	/* A: SSC Transmit Frame Sync 2 */
+#define AT91_PB12_ETX2		(1 << 12)	/* B: Ethernet Transmit Data 2 */
+#define AT91_PB13_TK2		(1 << 13)	/* A: SSC Transmit Clock 3 */
+#define AT91_PB13_ETX3		(1 << 13)	/* B: Ethernet Transmit Data 3 */
+#define AT91_PB14_TD2		(1 << 14)	/* A: SSC Transmit Data 2 */
+#define AT91_PB14_ETXER		(1 << 14)	/* B: Ethernet Transmit Coding Error */
+#define AT91_PB15_RD2		(1 << 15)	/* A: SSC Receive Data 2 */
+#define AT91_PB15_ERX2		(1 << 15)	/* B: Ethernet Receive Data 2 */
+#define AT91_PB16_RK2		(1 << 16)	/* A: SSC Receive Clock 2 */
+#define AT91_PB16_ERX3		(1 << 16)	/* B: Ethernet Receive Data 3 */
+#define AT91_PB17_RF2		(1 << 17)	/* A: SSC Receive Frame Sync 2 */
+#define AT91_PB17_ERXDV		(1 << 17)	/* B: Ethernet Receive Data Valid */
+#define AT91_PB18_RI1		(1 << 18)	/* A: USART Ring Indicator 1 */
+#define AT91_PB18_ECOL		(1 << 18)	/* B: Ethernet Collision Detected */
+#define AT91_PB19_DTR1		(1 << 19)	/* A: USART Data Terminal Ready 1 */
+#define AT91_PB19_ERXCK		(1 << 19)	/* B: Ethernet Receive Clock */
+#define AT91_PB20_TXD1		(1 << 20)	/* A: USART Transmit Data 1 */
+#define AT91_PB21_RXD1		(1 << 21)	/* A: USART Receive Data 1 */
+#define AT91_PB22_SCK1		(1 << 22)	/* A: USART Serial Clock 1 */
+#define AT91_PB23_DCD1		(1 << 23)	/* A: USART Data Carrier Detect 1 */
+#define AT91_PB24_CTS1		(1 << 24)	/* A: USART Clear To Send 1 */
+#define AT91_PB25_DSR1		(1 << 25)	/* A: USART Data Set Ready 1 */
+#define AT91_PB25_EF100		(1 << 25)	/* B: Ethernet Force 100 Mbit */
+#define AT91_PB26_RTS1		(1 << 26)	/* A: USART Ready To Send 1 */
+#define AT91_PB27_PCK0		(1 << 27)	/* B: PMC Programmable Clock Output 0 */
+#define AT91_PB28_FIQ		(1 << 28)	/* A: Fast Interrupt */
+#define AT91_PB29_IRQ0		(1 << 29)	/* A: External Interrupt 0 */
+
+#define AT91_PC0_BFCK		(1 <<  0)	/* A: Burst Flash Clock */
+#define AT91_PC1_BFRDY_SMOE	(1 <<  1)	/* A: Burst Flash Ready / SmartMedia Output Enable */
+#define AT91_PC2_BFAVD		(1 <<  2)	/* A: Burst Flash Address Valid */
+#define AT91_PC3_BFBAA_SMWE	(1 <<  3)	/* A: Burst Flash Address Advance / SmartMedia Write Enable */
+#define AT91_PC4_BFOE		(1 <<  4)	/* A: Burst Flash Output Enable */
+#define AT91_PC5_BFWE		(1 <<  5)	/* A: Burst Flash Write Enable */
+#define AT91_PC6_NWAIT		(1 <<  6)	/* A: SMC Wait Signal */
+#define AT91_PC7_A23		(1 <<  7)	/* A: Address Bus 23 */
+#define AT91_PC8_A24		(1 <<  8)	/* A: Address Bus 24 */
+#define AT91_PC9_A25_CFRNW	(1 <<  9)	/* A: Address Bus 25 / Compact Flash Read Not Write */
+#define AT91_PC10_NCS4_CFCS	(1 << 10)	/* A: SMC Chip Select 4 / Compact Flash Chip Select */
+#define AT91_PC11_NCS5_CFCE1	(1 << 11)	/* A: SMC Chip Select 5 / Compact Flash Chip Enable 1 */
+#define AT91_PC12_NCS6_CFCE2	(1 << 12)	/* A: SMC Chip Select 6 / Compact Flash Chip Enable 2 */
+#define AT91_PC13_NCS7		(1 << 13)	/* A: Chip Select 7 */
+
+#define AT91_PD0_ETX0		(1 <<  0)	/* A: Ethernet Transmit Data 0 */
+#define AT91_PD1_ETX1		(1 <<  1)	/* A: Ethernet Transmit Data 1 */
+#define AT91_PD2_ETX2		(1 <<  2)	/* A: Ethernet Transmit Data 2 */
+#define AT91_PD3_ETX3		(1 <<  3)	/* A: Ethernet Transmit Data 3 */
+#define AT91_PD4_ETXEN		(1 <<  4)	/* A: Ethernet Transmit Enable */
+#define AT91_PD5_ETXER		(1 <<  5)	/* A: Ethernet Transmit Coding Error */
+#define AT91_PD6_DTXD		(1 <<  6)	/* A: DBGU Transmit Data */
+#define AT91_PD7_PCK0		(1 <<  7)	/* A: PMC Programmable Clock Output 0 */
+#define AT91_PD7_TSYNC		(1 <<  7)	/* B: ETM Trace Synchronization Signal */
+#define AT91_PD8_PCK1		(1 <<  8)	/* A: PMC Programmable Clock Output 1 */
+#define AT91_PD8_TCLK		(1 <<  8)	/* B: ETM Trace Clock */
+#define AT91_PD9_PCK2		(1 <<  9)	/* A: PMC Programmable Clock Output 2 */
+#define AT91_PD9_TPS0		(1 <<  9)	/* B: ETM Trace ARM Pipeline Status 0 */
+#define AT91_PD10_PCK3		(1 << 10)	/* A: PMC Programmable Clock Output 3 */
+#define AT91_PD10_TPS1		(1 << 10)	/* B: ETM Trace ARM Pipeline Status 1 */
+#define AT91_PD11_TPS2		(1 << 11)	/* B: ETM Trace ARM Pipeline Status 2 */
+#define AT91_PD12_TPK0		(1 << 12)	/* B: ETM Trace Packet Port 0 */
+#define AT91_PD13_TPK1		(1 << 13)	/* B: ETM Trace Packet Port 1 */
+#define AT91_PD14_TPK2		(1 << 14)	/* B: ETM Trace Packet Port 2 */
+#define AT91_PD15_TD0		(1 << 15)	/* A: SSC Transmit Data 0 */
+#define AT91_PD15_TPK3		(1 << 15)	/* B: ETM Trace Packet Port 3 */
+#define AT91_PD16_TD1		(1 << 16)	/* A: SSC Transmit Data 1 */
+#define AT91_PD16_TPK4		(1 << 16)	/* B: ETM Trace Packet Port 4 */
+#define AT91_PD17_TD2		(1 << 17)	/* A: SSC Transmit Data 2 */
+#define AT91_PD17_TPK5		(1 << 17)	/* B: ETM Trace Packet Port 5 */
+#define AT91_PD18_NPCS1		(1 << 18)	/* A: SPI Peripheral Chip Select 1 */
+#define AT91_PD18_TPK6		(1 << 18)	/* B: ETM Trace Packet Port 6 */
+#define AT91_PD19_NPCS2		(1 << 19)	/* A: SPI Peripheral Chip Select 2 */
+#define AT91_PD19_TPK7		(1 << 19)	/* B: ETM Trace Packet Port 7 */
+#define AT91_PD20_NPCS3		(1 << 20)	/* A: SPI Peripheral Chip Select 3 */
+#define AT91_PD20_TPK8		(1 << 20)	/* B: ETM Trace Packet Port 8 */
+#define AT91_PD21_RTS0		(1 << 21)  	/* A: USART Ready To Send 0 */
+#define AT91_PD21_TPK9		(1 << 21)	/* B: ETM Trace Packet Port 9 */
+#define AT91_PD22_RTS1		(1 << 22)	/* A: USART Ready To Send 1 */
+#define AT91_PD22_TPK10		(1 << 22)	/* B: ETM Trace Packet Port 10 */
+#define AT91_PD23_RTS2		(1 << 23)	/* A: USART Ready To Send 2 */
+#define AT91_PD23_TPK11		(1 << 23)	/* B: ETM Trace Packet Port 11 */
+#define AT91_PD24_RTS3		(1 << 24)	/* A: USART Ready To Send 3 */
+#define AT91_PD24_TPK12		(1 << 24)	/* B: ETM Trace Packet Port 12 */
+#define AT91_PD25_DTR1		(1 << 25)	/* A: USART Data Terminal Ready 1 */
+#define AT91_PD25_TPK13		(1 << 25)	/* B: ETM Trace Packet Port 13 */
+#define AT91_PD26_TPK14		(1 << 26)	/* B: ETM Trace Packet Port 14 */
+#define AT91_PD27_TPK15		(1 << 27)	/* B: ETM Trace Packet Port 15 */
+
+#endif
diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200_sys.h b/include/asm-arm/arch-at91rm9200/at91rm9200_sys.h
new file mode 100644
index 0000000..9bfffdb
--- /dev/null
+++ b/include/asm-arm/arch-at91rm9200/at91rm9200_sys.h
@@ -0,0 +1,328 @@
+/*
+ * include/asm-arm/arch-at91rm9200/at91rm9200_sys.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * System peripherals registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * 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.
+ */
+
+#ifndef AT91RM9200_SYS_H
+#define AT91RM9200_SYS_H
+
+/*
+ * Advanced Interrupt Controller.
+ */
+#define AT91_AIC	0x000
+
+#define AT91_AIC_SMR(n)		(AT91_AIC + ((n) * 4))	/* Source Mode Registers 0-31 */
+#define		AT91_AIC_PRIOR		(7 << 0)		/* Priority Level */
+#define		AT91_AIC_SRCTYPE	(3 << 5)		/* Interrupt Source Type */
+#define			AT91_AIC_SRCTYPE_LOW		(0 << 5)
+#define			AT91_AIC_SRCTYPE_FALLING	(1 << 5)
+#define			AT91_AIC_SRCTYPE_HIGH		(2 << 5)
+#define			AT91_AIC_SRCTYPE_RISING		(3 << 5)
+
+#define AT91_AIC_SVR(n)		(AT91_AIC + 0x80 + ((n) * 4))	/* Source Vector Registers 0-31 */
+#define AT91_AIC_IVR		(AT91_AIC + 0x100)	/* Interrupt Vector Register */
+#define AT91_AIC_FVR		(AT91_AIC + 0x104)	/* Fast Interrupt Vector Register */
+#define AT91_AIC_ISR		(AT91_AIC + 0x108)	/* Interrupt Status Register */
+#define		AT91_AIC_IRQID		(0x1f << 0)		/* Current Interrupt Identifier */
+
+#define AT91_AIC_IPR		(AT91_AIC + 0x10c)	/* Interrupt Pending Register */
+#define AT91_AIC_IMR		(AT91_AIC + 0x110)	/* Interrupt Mask Register */
+#define AT91_AIC_CISR		(AT91_AIC + 0x114)	/* Core Interrupt Status Register */
+#define		AT91_AIC_NFIQ		(1 << 0)		/* nFIQ Status */
+#define		AT91_AIC_NIRQ		(1 << 1)		/* nIRQ Status */
+
+#define AT91_AIC_IECR		(AT91_AIC + 0x120)	/* Interrupt Enable Command Register */
+#define AT91_AIC_IDCR		(AT91_AIC + 0x124)	/* Interrupt Disable Command Register */
+#define AT91_AIC_ICCR		(AT91_AIC + 0x128)	/* Interrupt Clear Command Register */
+#define AT91_AIC_ISCR		(AT91_AIC + 0x12c)	/* Interrupt Set Command Register */
+#define AT91_AIC_EOICR		(AT91_AIC + 0x130)	/* End of Interrupt Command Register */
+#define AT91_AIC_SPU		(AT91_AIC + 0x134)	/* Spurious Interrupt Vector Register */
+#define AT91_AIC_DCR		(AT91_AIC + 0x138)	/* Debug Control Register */
+#define		AT91_AIC_DCR_PROT	(1 << 0)		/* Protection Mode */
+#define		AT91_AIC_DCR_GMSK	(1 << 1)		/* General Mask */
+
+
+/*
+ * Debug Unit.
+ */
+#define AT91_DBGU	0x200
+
+#define AT91_DBGU_CR		(AT91_DBGU + 0x00)	/* Control Register */
+#define AT91_DBGU_MR		(AT91_DBGU + 0x04)	/* Mode Register */
+#define AT91_DBGU_IER		(AT91_DBGU + 0x08)	/* Interrupt Enable Register */
+#define		AT91_DBGU_TXRDY		(1 << 1)		/* Transmitter Ready */
+#define		AT91_DBGU_TXEMPTY	(1 << 9)		/* Transmitter Empty */
+#define AT91_DBGU_IDR		(AT91_DBGU + 0x0c)	/* Interrupt Disable Register */
+#define AT91_DBGU_IMR		(AT91_DBGU + 0x10)	/* Interrupt Mask Register */
+#define AT91_DBGU_SR		(AT91_DBGU + 0x14)	/* Status Register */
+#define AT91_DBGU_RHR		(AT91_DBGU + 0x18)	/* Receiver Holding Register */
+#define AT91_DBGU_THR		(AT91_DBGU + 0x1c)	/* Transmitter Holding Register */
+#define AT91_DBGU_BRGR		(AT91_DBGU + 0x20)	/* Baud Rate Generator Register */
+#define AT91_DBGU_CIDR		(AT91_DBGU + 0x40)	/* Chip ID Register */
+#define AT91_DBGU_EXID		(AT91_DBGU + 0x44)	/* Chip ID Extension Register */
+
+
+/*
+ * PIO Controllers.
+ */
+#define AT91_PIOA	0x400
+#define AT91_PIOB	0x600
+#define AT91_PIOC	0x800
+#define AT91_PIOD	0xa00
+
+#define PIO_PER		0x00	/* Enable Register */
+#define PIO_PDR		0x04	/* Disable Register */
+#define PIO_PSR		0x08	/* Status Register */
+#define PIO_OER		0x10	/* Output Enable Register */
+#define PIO_ODR		0x14	/* Output Disable Register */
+#define PIO_OSR		0x18	/* Output Status Register */
+#define PIO_IFER	0x20	/* Glitch Input Filter Enable */
+#define PIO_IFDR	0x24	/* Glitch Input Filter Disable */
+#define PIO_IFSR	0x28	/* Glitch Input Filter Status */
+#define PIO_SODR	0x30	/* Set Output Data Register */
+#define PIO_CODR	0x34	/* Clear Output Data Register */
+#define PIO_ODSR	0x38	/* Output Data Status Register */
+#define PIO_PDSR	0x3c	/* Pin Data Status Register */
+#define PIO_IER		0x40	/* Interrupt Enable Register */
+#define PIO_IDR		0x44	/* Interrupt Disable Register */
+#define PIO_IMR		0x48	/* Interrupt Mask Register */
+#define PIO_ISR		0x4c	/* Interrupt Status Register */
+#define PIO_MDER	0x50	/* Multi-driver Enable Register */
+#define PIO_MDDR	0x54	/* Multi-driver Disable Register */
+#define PIO_MDSR	0x58	/* Multi-driver Status Register */
+#define PIO_PUDR	0x60	/* Pull-up Disable Register */
+#define PIO_PUER	0x64	/* Pull-up Enable Register */
+#define PIO_PUSR	0x68	/* Pull-up Status Register */
+#define PIO_ASR		0x70	/* Peripheral A Select Register */
+#define PIO_BSR		0x74	/* Peripheral B Select Register */
+#define PIO_ABSR	0x78	/* AB Status Register */
+#define PIO_OWER	0xa0	/* Output Write Enable Register */
+#define PIO_OWDR	0xa4	/* Output Write Disable Register */
+#define PIO_OWSR	0xa8	/* Output Write Status Register */
+
+#define AT91_PIO_P(n)	(1 << (n))
+
+
+/*
+ * Power Management Controller.
+ */
+#define	AT91_PMC	0xc00
+
+#define	AT91_PMC_SCER		(AT91_PMC + 0x00)	/* System Clock Enable Register */
+#define	AT91_PMC_SCDR		(AT91_PMC + 0x04)	/* System Clock Disable Register */
+
+#define	AT91_PMC_SCSR		(AT91_PMC + 0x08)	/* System Clock Status Register */
+#define		AT91_PMC_PCK		(1 <<  0)		/* Processor Clock */
+#define		AT91_PMC_UDP		(1 <<  1)		/* USB Devcice Port Clock */
+#define		AT91_PMC_MCKUDP		(1 <<  2)		/* USB Device Port Master Clock Automatic Disable on Suspend */
+#define		AT91_PMC_UHP		(1 <<  4)		/* USB Host Port Clock */
+#define		AT91_PMC_PCK0		(1 <<  8)		/* Programmable Clock 0 */
+#define		AT91_PMC_PCK1		(1 <<  9)		/* Programmable Clock 1 */
+#define		AT91_PMC_PCK2		(1 << 10)		/* Programmable Clock 2 */
+#define		AT91_PMC_PCK3		(1 << 11)		/* Programmable Clock 3 */
+
+#define	AT91_PMC_PCER		(AT91_PMC + 0x10)	/* Peripheral Clock Enable Register */
+#define	AT91_PMC_PCDR		(AT91_PMC + 0x14)	/* Peripheral Clock Disable Register */
+#define	AT91_PMC_PCSR		(AT91_PMC + 0x18)	/* Peripheral Clock Status Register */
+
+#define	AT91_CKGR_MOR		(AT91_PMC + 0x20)	/* Main Oscillator Register */
+#define		AT91_PMC_MOSCEN		(1    << 0)		/* Main Oscillator Enable */
+#define		AT91_PMC_OSCOUNT	(0xff << 8)		/* Main Oscillator Start-up Time */
+
+#define	AT91_CKGR_MCFR		(AT91_PMC + 0x24)	/* Main Clock Frequency Register */
+#define		AT91_PMC_MAINF		(0xffff <<  0)		/* Main Clock Frequency */
+#define		AT91_PMC_MAINRDY	(1	<< 16)		/* Main Clock Ready */
+
+#define	AT91_CKGR_PLLAR		(AT91_PMC + 0x28)	/* PLL A Register */
+#define	AT91_CKGR_PLLBR		(AT91_PMC + 0x2c)	/* PLL B Register */
+#define		AT91_PMC_DIV		(0xff  <<  0)		/* Divider */
+#define		AT91_PMC_PLLCOUNT	(0x3f  <<  8)		/* PLL Counter */
+#define		AT91_PMC_OUT		(3     << 14)		/* PLL Clock Frequency Range */
+#define		AT91_PMC_MUL		(0x7ff << 16)		/* PLL Multiplier */
+#define		AT91_PMC_USB96M		(1     << 28)		/* Divider by 2 Enable (PLLB only) */
+
+#define	AT91_PMC_MCKR		(AT91_PMC + 0x30)	/* Master Clock Register */
+#define		AT91_PMC_CSS		(3 <<  0)		/* Master Clock Selection */
+#define			AT91_PMC_CSS_SLOW		(0 << 0)
+#define			AT91_PMC_CSS_MAIN		(1 << 0)
+#define			AT91_PMC_CSS_PLLA		(2 << 0)
+#define			AT91_PMC_CSS_PLLB		(3 << 0)
+#define		AT91_PMC_PRES		(7 <<  2)		/* Master Clock Prescaler */
+#define 		AT91_PMC_PRES_1			(0 << 2)
+#define			AT91_PMC_PRES_2			(1 << 2)
+#define			AT91_PMC_PRES_4			(2 << 2)
+#define			AT91_PMC_PRES_8			(3 << 2)
+#define			AT91_PMC_PRES_16		(4 << 2)
+#define			AT91_PMC_PRES_32		(5 << 2)
+#define			AT91_PMC_PRES_64		(6 << 2)
+#define		AT91_PMC_MDIV		(3 <<  8)		/* Master Clock Division */
+#define			AT91_PMC_MDIV_1			(0 << 8)
+#define			AT91_PMC_MDIV_2			(1 << 8)
+#define			AT91_PMC_MDIV_3			(2 << 8)
+#define			AT91_PMC_MDIV_4			(3 << 8)
+
+#define	AT91_PMC_PCKR(n)	(AT91_PMC + 0x40 + ((n) * 4))	/* Programmable Clock 0-3 Registers */
+#define	AT91_PMC_IER		(AT91_PMC + 0x60)	/* Interrupt Enable Register */
+#define	AT91_PMC_IDR		(AT91_PMC + 0x64)	/* Interrupt Disable Register */
+#define	AT91_PMC_SR		(AT91_PMC + 0x68)	/* Status Register */
+#define		AT91_PMC_MOSCS		(1 <<  0)		/* MOSCS Flag */
+#define		AT91_PMC_LOCKA		(1 <<  1)		/* PLLA Lock */
+#define		AT91_PMC_LOCKB		(1 <<  2)		/* PLLB Lock */
+#define		AT91_PMC_MCKRDY		(1 <<  3)		/* Master Clock */
+#define		AT91_PMC_PCK0RDY	(1 <<  8)		/* Programmable Clock 0 */
+#define		AT91_PMC_PCK1RDY	(1 <<  9)		/* Programmable Clock 1 */
+#define		AT91_PMC_PCK2RDY	(1 << 10)		/* Programmable Clock 2 */
+#define		AT91_PMC_PCK3RDY	(1 << 11)		/* Programmable Clock 3 */
+#define	AT91_PMC_IMR		(AT91_PMC + 0x6c)	/* Interrupt Mask Register */
+
+
+/*
+ * System Timer.
+ */
+#define	AT91_ST		0xd00
+
+#define	AT91_ST_CR		(AT91_ST + 0x00)	/* Control Register */
+#define 	AT91_ST_WDRST		(1 << 0)		/* Watchdog Timer Restart */
+#define	AT91_ST_PIMR		(AT91_ST + 0x04)	/* Period Interval Mode Register */
+#define		AT91_ST_PIV		(0xffff <<  0)		/* Period Interval Value */
+#define	AT91_ST_WDMR		(AT91_ST + 0x08)	/* Watchdog Mode Register */
+#define		AT91_ST_WDV		(0xffff <<  0)		/* Watchdog Counter Value */
+#define		AT91_ST_RSTEN		(1	<< 16)		/* Reset Enable */
+#define		AT91_ST_EXTEN		(1	<< 17)		/* External Signal Assertion Enable */
+#define	AT91_ST_RTMR		(AT91_ST + 0x0c)	/* Real-time Mode Register */
+#define		AT91_ST_RTPRES		(0xffff <<  0)		/* Real-time Prescalar Value */
+#define	AT91_ST_SR		(AT91_ST + 0x10)	/* Status Register */
+#define		AT91_ST_PITS		(1 << 0)		/* Period Interval Timer Status */
+#define		AT91_ST_WDOVF		(1 << 1) 		/* Watchdog Overflow */
+#define		AT91_ST_RTTINC		(1 << 2) 		/* Real-time Timer Increment */
+#define		AT91_ST_ALMS		(1 << 3) 		/* Alarm Status */
+#define	AT91_ST_IER		(AT91_ST + 0x14)	/* Interrupt Enable Register */
+#define	AT91_ST_IDR		(AT91_ST + 0x18)	/* Interrupt Disable Register */
+#define	AT91_ST_IMR		(AT91_ST + 0x1c)	/* Interrupt Mask Register */
+#define	AT91_ST_RTAR		(AT91_ST + 0x20)	/* Real-time Alarm Register */
+#define		AT91_ST_ALMV		(0xfffff << 0)		/* Alarm Value */
+#define	AT91_ST_CRTR		(AT91_ST + 0x24)	/* Current Real-time Register */
+#define		AT91_ST_CRTV		(0xfffff << 0)		/* Current Real-Time Value */
+
+
+/*
+ * Real-time Clock.
+ */
+#define	AT91_RTC	0xe00
+
+#define	AT91_RTC_CR		(AT91_RTC + 0x00)	/* Control Register */
+#define		AT91_RTC_UPDTIM		(1 <<  0)		/* Update Request Time Register */
+#define		AT91_RTC_UPDCAL		(1 <<  1)		/* Update Request Calendar Register */
+#define		AT91_RTC_TIMEVSEL	(3 <<  8)		/* Time Event Selection */
+#define			AT91_RTC_TIMEVSEL_MINUTE	(0 << 8)
+#define 		AT91_RTC_TIMEVSEL_HOUR		(1 << 8)
+#define 		AT91_RTC_TIMEVSEL_DAY24		(2 << 8)
+#define 		AT91_RTC_TIMEVSEL_DAY12		(3 << 8)
+#define		AT91_RTC_CALEVSEL	(3 << 16)		/* Calendar Event Selection */
+#define 		AT91_RTC_CALEVSEL_WEEK		(0 << 16)
+#define 		AT91_RTC_CALEVSEL_MONTH		(1 << 16)
+#define 		AT91_RTC_CALEVSEL_YEAR		(2 << 16)
+
+#define	AT91_RTC_MR		(AT91_RTC + 0x04)	/* Mode Register */
+#define 	AT91_RTC_HRMOD		(1 <<  0)		/* 12/24 Hour Mode */
+
+#define	AT91_RTC_TIMR		(AT91_RTC + 0x08)	/* Time Register */
+#define		AT91_RTC_SEC		(0x7f <<  0)		/* Current Second */
+#define		AT91_RTC_MIN		(0x7f <<  8)		/* Current Minute */
+#define		AT91_RTC_HOUR 		(0x3f << 16)		/* Current Hour */
+#define		At91_RTC_AMPM		(1    << 22)		/* Ante Meridiem Post Meridiem Indicator */
+
+#define	AT91_RTC_CALR		(AT91_RTC + 0x0c)	/* Calendar Register */
+#define		AT91_RTC_CENT		(0x7f <<  0)		/* Current Century */
+#define		AT91_RTC_YEAR		(0xff <<  8)		/* Current Year */
+#define		AT91_RTC_MONTH		(0x1f << 16)		/* Current Month */
+#define		AT91_RTC_DAY		(7    << 21)		/* Current Day */
+#define		AT91_RTC_DATE		(0x3f << 24)		/* Current Date */
+
+#define	AT91_RTC_TIMALR		(AT91_RTC + 0x10)	/* Time Alarm Register */
+#define		AT91_RTC_SECEN		(1 <<  7)		/* Second Alarm Enable */
+#define		AT91_RTC_MINEN		(1 << 15)		/* Minute Alarm Enable */
+#define		AT91_RTC_HOUREN		(1 << 23)		/* Hour Alarm Enable */
+
+#define	AT91_RTC_CALALR		(AT91_RTC + 0x14)	/* Calendar Alarm Register */
+#define		AT91_RTC_MTHEN		(1 << 23)		/* Month Alarm Enable */
+#define		AT91_RTC_DATEEN		(1 << 31)		/* Date Alarm Enable */
+
+#define	AT91_RTC_SR		(AT91_RTC + 0x18)	/* Status Register */
+#define		AT91_RTC_ACKUPD		(1 <<  0)		/* Acknowledge for Update */
+#define		AT91_RTC_ALARM		(1 <<  1)		/* Alarm Flag */
+#define		AT91_RTC_SECEV		(1 <<  2)		/* Second Event */
+#define		AT91_RTC_TIMEV		(1 <<  3)		/* Time Event */
+#define		AT91_RTC_CALEV		(1 <<  4)		/* Calendar Event */
+
+#define	AT91_RTC_SCCR		(AT91_RTC + 0x1c)	/* Status Clear Command Register */
+#define	AT91_RTC_IER		(AT91_RTC + 0x20)	/* Interrupt Enable Register */
+#define	AT91_RTC_IDR		(AT91_RTC + 0x24)	/* Interrupt Disable Register */
+#define	AT91_RTC_IMR		(AT91_RTC + 0x28)	/* Interrupt Mask Register */
+
+#define	AT91_RTC_VER		(AT91_RTC + 0x2c)	/* Valid Entry Register */
+#define		AT91_RTC_NVTIM		(1 <<  0)		/* Non valid Time */
+#define		AT91_RTC_NVCAL		(1 <<  1)		/* Non valid Calendar */
+#define		AT91_RTC_NVTIMALR	(1 <<  2)		/* Non valid Time Alarm */
+#define		AT91_RTC_NVCALALR	(1 <<  3)		/* Non valid Calendar Alarm */
+
+
+/*
+ * Memory Controller.
+ */
+#define AT91_MC		0xf00
+
+#define AT91_MC_RCR		(AT91_MC + 0x00)	/* MC Remap Control Register */
+#define		AT91_MC_RCB		(1 <<  0)		/* Remap Command Bit */
+
+#define AT91_MC_ASR		(AT91_MC + 0x04)	/* MC Abort Status Register */
+#define AT91_MC_AASR		(AT91_MC + 0x08)	/* MC Abort Address Status Register */
+#define AT91_MC_MPR		(AT91_MC + 0x0c)	/* MC Master Priority Register */
+
+/* External Bus Interface (EBI) registers */
+#define AT91_EBI_CSA		(AT91_MC + 0x60)	/* Chip Select Assignment Register */
+#define		AT91_EBI_CS0A		(1 << 0)		/* Chip Select 0 Assignment */
+#define			AT91_EBI_CS0A_SMC		(0 << 0)
+#define			AT91_EBI_CS0A_BFC		(1 << 0)
+#define		AT91_EBI_CS1A		(1 << 1)		/* Chip Select 1 Assignment */
+#define			AT91_EBI_CS1A_SMC		(0 << 1)
+#define			AT91_EBI_CS1A_SDRAMC		(1 << 1)
+#define		AT91_EBI_CS3A		(1 << 3)		/* Chip Select 2 Assignment */
+#define			AT91_EBI_CS3A_SMC		(0 << 3)
+#define			AT91_EBI_CS3A_SMC_SMARTMEDIA	(1 << 3)
+#define		AT91_EBI_CS4A		(1 << 4)		/* Chip Select 3 Assignment */
+#define			AT91_EBI_CS4A_SMC		(0 << 4)
+#define			AT91_EBI_CS4A_SMC_COMPACTFLASH	(1 << 4)
+#define AT91_EBI_CFGR		(AT91_MC + 0x64)	/* Configuration Register */
+#define		AT91_EBI_DBPUC		(1 << 0)		/* Data Bus Pull-Up Configuration */
+
+/* Static Memory Controller (SMC) registers */
+#define	AT91_SMC_CSR(n)		(AT91_MC + 0x70 + ((n) * 4))/* SMC Chip Select Register */
+#define		AT91_SMC_NWS		(0x7f <<  0)		/* Number of Wait States */
+#define		AT91_SMC_WSEN		(1    <<  7)		/* Wait State Enable */
+#define		AT91_SMC_TDF		(0xf  <<  8)		/* Data Float Time */
+#define		AT91_SMC_BAT		(1    << 12)		/* Byte Access Type */
+#define		AT91_SMC_DBW		(3    << 13)		/* Data Bus Width */
+#define			AT91_SMC_DBW_16		(1 << 13)
+#define			AT91_SMC_DBW_8		(2 << 13)
+#define		AT91_SMC_DPR		(1 << 15)		/* Data Read Protocol */
+#define		AT91_SMC_ACSS		(3 << 16)		/* Address to Chip Select Setup */
+#define			AT91_SMC_ACSS_STD	(0 << 16)
+#define			AT91_SMC_ACSS_1		(1 << 16)
+#define			AT91_SMC_ACSS_2		(2 << 16)
+#define			AT91_SMC_ACSS_3		(3 << 16)
+#define		AT91_SMC_RWSETUP	(7 << 24)		/* Read & Write Signal Time Setup */
+#define		AT91_SMC_RWHOLD		(7 << 28)		/* Read & Write Signal Hold Time */
+
+
+#endif
diff --git a/include/asm-arm/arch-at91rm9200/board.h b/include/asm-arm/arch-at91rm9200/board.h
new file mode 100644
index 0000000..2e7d113
--- /dev/null
+++ b/include/asm-arm/arch-at91rm9200/board.h
@@ -0,0 +1,80 @@
+/*
+ * include/asm-arm/arch-at91rm9200/board.h
+ *
+ *  Copyright (C) 2005 HP Labs
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * These are data structures found in platform_device.dev.platform_data,
+ * and describing board-specfic data needed by drivers.  For example,
+ * which pin is used for a given GPIO role.
+ *
+ * In 2.6, drivers should strongly avoid board-specific knowledge so
+ * that supporting new boards normally won't require driver patches.
+ * Most board-specific knowledge should be in arch/.../board-*.c files.
+ */
+
+#ifndef __ASM_ARCH_BOARD_H
+#define __ASM_ARCH_BOARD_H
+
+ /* Clocks */
+extern unsigned long at91_master_clock;
+
+ /* Serial Port */
+extern int at91_serial_map[AT91_NR_UART];
+extern int at91_console_port;
+
+ /* USB Device */
+struct at91_udc_data {
+	u8	vbus_pin;		/* high == host powering us */
+	u8	pullup_pin;		/* high == D+ pulled up */
+};
+extern void __init at91_add_device_udc(struct at91_udc_data *data);
+
+ /* Compact Flash */
+struct at91_cf_data {
+	u8	irq_pin;		/* I/O IRQ */
+	u8	det_pin;		/* Card detect */
+	u8	vcc_pin;		/* power switching */
+	u8	rst_pin;		/* card reset */
+};
+extern void __init at91_add_device_cf(struct at91_cf_data *data);
+
+ /* MMC / SD */
+struct at91_mmc_data {
+	u8		det_pin;	/* card detect IRQ */
+	unsigned	is_b:1;		/* uses B side (vs A) */
+	unsigned	wire4:1;	/* (SD) supports DAT0..DAT3 */
+	u8		wp_pin;		/* (SD) writeprotect detect */
+	u8		vcc_pin;	/* power switching (high == on) */
+};
+extern void __init at91_add_device_mmc(struct at91_mmc_data *data);
+
+ /* Ethernet */
+struct at91_eth_data {
+	u8		phy_irq_pin;	/* PHY IRQ */
+	u8		is_rmii;	/* using RMII interface? */
+};
+extern void __init at91_add_device_eth(struct at91_eth_data *data);
+
+ /* USB Host */
+struct at91_usbh_data {
+	u8		ports;		/* number of ports on root hub */
+};
+extern void __init at91_add_device_usbh(struct at91_usbh_data *data);
+
+#endif
diff --git a/include/asm-arm/arch-at91rm9200/debug-macro.S b/include/asm-arm/arch-at91rm9200/debug-macro.S
new file mode 100644
index 0000000..f496b54
--- /dev/null
+++ b/include/asm-arm/arch-at91rm9200/debug-macro.S
@@ -0,0 +1,38 @@
+/*
+ * include/asm-arm/arch-at91rm9200/debug-macro.S
+ *
+ *  Copyright (C) 2003-2005 SAN People
+ *
+ * Debugging macro include header
+ *
+ * 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 <asm/hardware.h>
+
+	.macro	addruart,rx
+	mrc	p15, 0, \rx, c1, c0
+	tst	\rx, #1				@ MMU enabled?
+	ldreq	\rx, =AT91_BASE_SYS		@ System peripherals (phys address)
+	ldrne	\rx, =AT91_VA_BASE_SYS		@ System peripherals (virt address)
+	.endm
+
+	.macro	senduart,rd,rx
+	strb	\rd, [\rx, #AT91_DBGU_THR]	@ Write to Transmitter Holding Register
+	.endm
+
+	.macro	waituart,rd,rx
+1001:	ldr	\rd, [\rx, #AT91_DBGU_SR]	@ Read Status Register
+	tst	\rd, #AT91_DBGU_TXRDY		@ DBGU_TXRDY = 1 when ready to transmit
+	beq	1001b
+	.endm
+
+	.macro	busyuart,rd,rx
+1001:	ldr	\rd, [\rx, #AT91_DBGU_SR]	@ Read Status Register
+	tst	\rd, #AT91_DBGU_TXEMPTY		@ DBGU_TXEMPTY = 1 when transmission complete
+	beq	1001b
+	.endm
+
diff --git a/include/asm-arm/arch-epxa10db/param.h b/include/asm-arm/arch-at91rm9200/dma.h
similarity index 89%
rename from include/asm-arm/arch-epxa10db/param.h
rename to include/asm-arm/arch-at91rm9200/dma.h
index 783dedd..22c1dfd 100644
--- a/include/asm-arm/arch-epxa10db/param.h
+++ b/include/asm-arm/arch-at91rm9200/dma.h
@@ -1,7 +1,7 @@
 /*
- *  linux/include/asm-arm/arch-epxa10db/param.h
+ * include/asm-arm/arch-at91rm9200/dma.h
  *
- *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2003 SAN People
  *
  * 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
diff --git a/include/asm-arm/arch-at91rm9200/entry-macro.S b/include/asm-arm/arch-at91rm9200/entry-macro.S
new file mode 100644
index 0000000..61a326e
--- /dev/null
+++ b/include/asm-arm/arch-at91rm9200/entry-macro.S
@@ -0,0 +1,25 @@
+/*
+ * include/asm-arm/arch-at91rm9200/entry-macro.S
+ *
+ *  Copyright (C) 2003-2005 SAN People
+ *
+ * Low-level IRQ helper macros for AT91RM9200 platforms
+ *
+ * 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 <asm/hardware.h>
+
+	.macro	disable_fiq
+	.endm
+
+	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+	ldr	\base, =(AT91_VA_BASE_SYS)		@ base virtual address of SYS peripherals
+	ldr	\irqnr, [\base, #AT91_AIC_IVR]		@ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt)
+	ldr	\irqstat, [\base, #AT91_AIC_ISR]	@ read interrupt source number
+	teq	\irqstat, #0				@ ISR is 0 when no current interrupt, or spurious interrupt
+	streq	\tmp, [\base, #AT91_AIC_EOICR]		@ not going to be handled further, then ACK it now.
+	.endm
+
diff --git a/include/asm-arm/arch-at91rm9200/gpio.h b/include/asm-arm/arch-at91rm9200/gpio.h
new file mode 100644
index 0000000..0f0a61e
--- /dev/null
+++ b/include/asm-arm/arch-at91rm9200/gpio.h
@@ -0,0 +1,193 @@
+/*
+ * include/asm-arm/arch-at91rm9200/gpio.h
+ *
+ *  Copyright (C) 2005 HP Labs
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_ARCH_AT91RM9200_GPIO_H
+#define __ASM_ARCH_AT91RM9200_GPIO_H
+
+#define PIN_BASE		NR_AIC_IRQS
+
+#define PQFP_GPIO_BANKS		3	/* PQFP package has 3 banks */
+#define BGA_GPIO_BANKS		4	/* BGA package has 4 banks */
+
+/* these pin numbers double as IRQ numbers, like AT91_ID_* values */
+
+#define	AT91_PIN_PA0	(PIN_BASE + 0x00 + 0)
+#define	AT91_PIN_PA1	(PIN_BASE + 0x00 + 1)
+#define	AT91_PIN_PA2	(PIN_BASE + 0x00 + 2)
+#define	AT91_PIN_PA3	(PIN_BASE + 0x00 + 3)
+#define	AT91_PIN_PA4	(PIN_BASE + 0x00 + 4)
+
+#define	AT91_PIN_PA5	(PIN_BASE + 0x00 + 5)
+#define	AT91_PIN_PA6	(PIN_BASE + 0x00 + 6)
+#define	AT91_PIN_PA7	(PIN_BASE + 0x00 + 7)
+#define	AT91_PIN_PA8	(PIN_BASE + 0x00 + 8)
+#define	AT91_PIN_PA9	(PIN_BASE + 0x00 + 9)
+
+#define	AT91_PIN_PA10	(PIN_BASE + 0x00 + 10)
+#define	AT91_PIN_PA11	(PIN_BASE + 0x00 + 11)
+#define	AT91_PIN_PA12	(PIN_BASE + 0x00 + 12)
+#define	AT91_PIN_PA13	(PIN_BASE + 0x00 + 13)
+#define	AT91_PIN_PA14	(PIN_BASE + 0x00 + 14)
+
+#define	AT91_PIN_PA15	(PIN_BASE + 0x00 + 15)
+#define	AT91_PIN_PA16	(PIN_BASE + 0x00 + 16)
+#define	AT91_PIN_PA17	(PIN_BASE + 0x00 + 17)
+#define	AT91_PIN_PA18	(PIN_BASE + 0x00 + 18)
+#define	AT91_PIN_PA19	(PIN_BASE + 0x00 + 19)
+
+#define	AT91_PIN_PA20	(PIN_BASE + 0x00 + 20)
+#define	AT91_PIN_PA21	(PIN_BASE + 0x00 + 21)
+#define	AT91_PIN_PA22	(PIN_BASE + 0x00 + 22)
+#define	AT91_PIN_PA23	(PIN_BASE + 0x00 + 23)
+#define	AT91_PIN_PA24	(PIN_BASE + 0x00 + 24)
+
+#define	AT91_PIN_PA25	(PIN_BASE + 0x00 + 25)
+#define	AT91_PIN_PA26	(PIN_BASE + 0x00 + 26)
+#define	AT91_PIN_PA27	(PIN_BASE + 0x00 + 27)
+#define	AT91_PIN_PA28	(PIN_BASE + 0x00 + 28)
+#define	AT91_PIN_PA29	(PIN_BASE + 0x00 + 29)
+
+#define	AT91_PIN_PA30	(PIN_BASE + 0x00 + 30)
+#define	AT91_PIN_PA31	(PIN_BASE + 0x00 + 31)
+
+#define	AT91_PIN_PB0	(PIN_BASE + 0x20 + 0)
+#define	AT91_PIN_PB1	(PIN_BASE + 0x20 + 1)
+#define	AT91_PIN_PB2	(PIN_BASE + 0x20 + 2)
+#define	AT91_PIN_PB3	(PIN_BASE + 0x20 + 3)
+#define	AT91_PIN_PB4	(PIN_BASE + 0x20 + 4)
+
+#define	AT91_PIN_PB5	(PIN_BASE + 0x20 + 5)
+#define	AT91_PIN_PB6	(PIN_BASE + 0x20 + 6)
+#define	AT91_PIN_PB7	(PIN_BASE + 0x20 + 7)
+#define	AT91_PIN_PB8	(PIN_BASE + 0x20 + 8)
+#define	AT91_PIN_PB9	(PIN_BASE + 0x20 + 9)
+
+#define	AT91_PIN_PB10	(PIN_BASE + 0x20 + 10)
+#define	AT91_PIN_PB11	(PIN_BASE + 0x20 + 11)
+#define	AT91_PIN_PB12	(PIN_BASE + 0x20 + 12)
+#define	AT91_PIN_PB13	(PIN_BASE + 0x20 + 13)
+#define	AT91_PIN_PB14	(PIN_BASE + 0x20 + 14)
+
+#define	AT91_PIN_PB15	(PIN_BASE + 0x20 + 15)
+#define	AT91_PIN_PB16	(PIN_BASE + 0x20 + 16)
+#define	AT91_PIN_PB17	(PIN_BASE + 0x20 + 17)
+#define	AT91_PIN_PB18	(PIN_BASE + 0x20 + 18)
+#define	AT91_PIN_PB19	(PIN_BASE + 0x20 + 19)
+
+#define	AT91_PIN_PB20	(PIN_BASE + 0x20 + 20)
+#define	AT91_PIN_PB21	(PIN_BASE + 0x20 + 21)
+#define	AT91_PIN_PB22	(PIN_BASE + 0x20 + 22)
+#define	AT91_PIN_PB23	(PIN_BASE + 0x20 + 23)
+#define	AT91_PIN_PB24	(PIN_BASE + 0x20 + 24)
+
+#define	AT91_PIN_PB25	(PIN_BASE + 0x20 + 25)
+#define	AT91_PIN_PB26	(PIN_BASE + 0x20 + 26)
+#define	AT91_PIN_PB27	(PIN_BASE + 0x20 + 27)
+#define	AT91_PIN_PB28	(PIN_BASE + 0x20 + 28)
+#define	AT91_PIN_PB29	(PIN_BASE + 0x20 + 29)
+
+#define	AT91_PIN_PB30	(PIN_BASE + 0x20 + 30)
+#define	AT91_PIN_PB31	(PIN_BASE + 0x20 + 31)
+
+#define	AT91_PIN_PC0	(PIN_BASE + 0x40 + 0)
+#define	AT91_PIN_PC1	(PIN_BASE + 0x40 + 1)
+#define	AT91_PIN_PC2	(PIN_BASE + 0x40 + 2)
+#define	AT91_PIN_PC3	(PIN_BASE + 0x40 + 3)
+#define	AT91_PIN_PC4	(PIN_BASE + 0x40 + 4)
+
+#define	AT91_PIN_PC5	(PIN_BASE + 0x40 + 5)
+#define	AT91_PIN_PC6	(PIN_BASE + 0x40 + 6)
+#define	AT91_PIN_PC7	(PIN_BASE + 0x40 + 7)
+#define	AT91_PIN_PC8	(PIN_BASE + 0x40 + 8)
+#define	AT91_PIN_PC9	(PIN_BASE + 0x40 + 9)
+
+#define	AT91_PIN_PC10	(PIN_BASE + 0x40 + 10)
+#define	AT91_PIN_PC11	(PIN_BASE + 0x40 + 11)
+#define	AT91_PIN_PC12	(PIN_BASE + 0x40 + 12)
+#define	AT91_PIN_PC13	(PIN_BASE + 0x40 + 13)
+#define	AT91_PIN_PC14	(PIN_BASE + 0x40 + 14)
+
+#define	AT91_PIN_PC15	(PIN_BASE + 0x40 + 15)
+#define	AT91_PIN_PC16	(PIN_BASE + 0x40 + 16)
+#define	AT91_PIN_PC17	(PIN_BASE + 0x40 + 17)
+#define	AT91_PIN_PC18	(PIN_BASE + 0x40 + 18)
+#define	AT91_PIN_PC19	(PIN_BASE + 0x40 + 19)
+
+#define	AT91_PIN_PC20	(PIN_BASE + 0x40 + 20)
+#define	AT91_PIN_PC21	(PIN_BASE + 0x40 + 21)
+#define	AT91_PIN_PC22	(PIN_BASE + 0x40 + 22)
+#define	AT91_PIN_PC23	(PIN_BASE + 0x40 + 23)
+#define	AT91_PIN_PC24	(PIN_BASE + 0x40 + 24)
+
+#define	AT91_PIN_PC25	(PIN_BASE + 0x40 + 25)
+#define	AT91_PIN_PC26	(PIN_BASE + 0x40 + 26)
+#define	AT91_PIN_PC27	(PIN_BASE + 0x40 + 27)
+#define	AT91_PIN_PC28	(PIN_BASE + 0x40 + 28)
+#define	AT91_PIN_PC29	(PIN_BASE + 0x40 + 29)
+
+#define	AT91_PIN_PC30	(PIN_BASE + 0x40 + 30)
+#define	AT91_PIN_PC31	(PIN_BASE + 0x40 + 31)
+
+#define	AT91_PIN_PD0	(PIN_BASE + 0x60 + 0)
+#define	AT91_PIN_PD1	(PIN_BASE + 0x60 + 1)
+#define	AT91_PIN_PD2	(PIN_BASE + 0x60 + 2)
+#define	AT91_PIN_PD3	(PIN_BASE + 0x60 + 3)
+#define	AT91_PIN_PD4	(PIN_BASE + 0x60 + 4)
+
+#define	AT91_PIN_PD5	(PIN_BASE + 0x60 + 5)
+#define	AT91_PIN_PD6	(PIN_BASE + 0x60 + 6)
+#define	AT91_PIN_PD7	(PIN_BASE + 0x60 + 7)
+#define	AT91_PIN_PD8	(PIN_BASE + 0x60 + 8)
+#define	AT91_PIN_PD9	(PIN_BASE + 0x60 + 9)
+
+#define	AT91_PIN_PD10	(PIN_BASE + 0x60 + 10)
+#define	AT91_PIN_PD11	(PIN_BASE + 0x60 + 11)
+#define	AT91_PIN_PD12	(PIN_BASE + 0x60 + 12)
+#define	AT91_PIN_PD13	(PIN_BASE + 0x60 + 13)
+#define	AT91_PIN_PD14	(PIN_BASE + 0x60 + 14)
+
+#define	AT91_PIN_PD15	(PIN_BASE + 0x60 + 15)
+#define	AT91_PIN_PD16	(PIN_BASE + 0x60 + 16)
+#define	AT91_PIN_PD17	(PIN_BASE + 0x60 + 17)
+#define	AT91_PIN_PD18	(PIN_BASE + 0x60 + 18)
+#define	AT91_PIN_PD19	(PIN_BASE + 0x60 + 19)
+
+#define	AT91_PIN_PD20	(PIN_BASE + 0x60 + 20)
+#define	AT91_PIN_PD21	(PIN_BASE + 0x60 + 21)
+#define	AT91_PIN_PD22	(PIN_BASE + 0x60 + 22)
+#define	AT91_PIN_PD23	(PIN_BASE + 0x60 + 23)
+#define	AT91_PIN_PD24	(PIN_BASE + 0x60 + 24)
+
+#define	AT91_PIN_PD25	(PIN_BASE + 0x60 + 25)
+#define	AT91_PIN_PD26	(PIN_BASE + 0x60 + 26)
+#define	AT91_PIN_PD27	(PIN_BASE + 0x60 + 27)
+#define	AT91_PIN_PD28	(PIN_BASE + 0x60 + 28)
+#define	AT91_PIN_PD29	(PIN_BASE + 0x60 + 29)
+
+#define	AT91_PIN_PD30	(PIN_BASE + 0x60 + 30)
+#define	AT91_PIN_PD31	(PIN_BASE + 0x60 + 31)
+
+#ifndef __ASSEMBLY__
+/* setup setup routines, called from board init or driver probe() */
+extern int at91_set_A_periph(unsigned pin, int use_pullup);
+extern int at91_set_B_periph(unsigned pin, int use_pullup);
+extern int at91_set_gpio_input(unsigned pin, int use_pullup);
+extern int at91_set_gpio_output(unsigned pin, int value);
+extern int at91_set_deglitch(unsigned pin, int is_on);
+
+/* callable at any time */
+extern int at91_set_gpio_value(unsigned pin, int value);
+extern int at91_get_gpio_value(unsigned pin);
+#endif
+
+#endif
+
diff --git a/include/asm-arm/arch-at91rm9200/hardware.h b/include/asm-arm/arch-at91rm9200/hardware.h
new file mode 100644
index 0000000..2646c01
--- /dev/null
+++ b/include/asm-arm/arch-at91rm9200/hardware.h
@@ -0,0 +1,92 @@
+/*
+ * include/asm-arm/arch-at91rm9200/hardware.h
+ *
+ *  Copyright (C) 2003 SAN People
+ *  Copyright (C) 2003 ATMEL
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+
+#include <asm/arch/at91rm9200.h>
+#include <asm/arch/at91rm9200_sys.h>
+
+/*
+ * Remap the peripherals from address 0xFFFA0000 .. 0xFFFFFFFF
+ * to 0xFEFA0000 .. 0xFF000000.  (384Kb)
+ */
+#define AT91_IO_PHYS_BASE	0xFFFA0000
+#define AT91_IO_SIZE		(0xFFFFFFFF - AT91_IO_PHYS_BASE + 1)
+#define AT91_IO_VIRT_BASE	(0xFF000000 - AT91_IO_SIZE)
+
+ /* Convert a physical IO address to virtual IO address */
+#define AT91_IO_P2V(x)	((x) - AT91_IO_PHYS_BASE + AT91_IO_VIRT_BASE)
+
+/*
+ * Virtual to Physical Address mapping for IO devices.
+ */
+#define AT91_VA_BASE_SYS	AT91_IO_P2V(AT91_BASE_SYS)
+#define AT91_VA_BASE_SPI	AT91_IO_P2V(AT91_BASE_SPI)
+#define AT91_VA_BASE_SSC2	AT91_IO_P2V(AT91_BASE_SSC2)
+#define AT91_VA_BASE_SSC1	AT91_IO_P2V(AT91_BASE_SSC1)
+#define AT91_VA_BASE_SSC0	AT91_IO_P2V(AT91_BASE_SSC0)
+#define AT91_VA_BASE_US3	AT91_IO_P2V(AT91_BASE_US3)
+#define AT91_VA_BASE_US2	AT91_IO_P2V(AT91_BASE_US2)
+#define AT91_VA_BASE_US1	AT91_IO_P2V(AT91_BASE_US1)
+#define AT91_VA_BASE_US0	AT91_IO_P2V(AT91_BASE_US0)
+#define AT91_VA_BASE_EMAC	AT91_IO_P2V(AT91_BASE_EMAC)
+#define AT91_VA_BASE_TWI	AT91_IO_P2V(AT91_BASE_TWI)
+#define AT91_VA_BASE_MCI	AT91_IO_P2V(AT91_BASE_MCI)
+#define AT91_VA_BASE_UDP	AT91_IO_P2V(AT91_BASE_UDP)
+#define AT91_VA_BASE_TCB1	AT91_IO_P2V(AT91_BASE_TCB1)
+#define AT91_VA_BASE_TCB0	AT91_IO_P2V(AT91_BASE_TCB0)
+
+/* Internal SRAM */
+#define AT91_BASE_SRAM		0x00200000	/* Internal SRAM base address */
+#define AT91_SRAM_SIZE		0x00004000	/* Internal SRAM SIZE (16Kb) */
+
+/* Serial ports */
+#define AT91_NR_UART		5		/* 4 USART3's and one DBGU port */
+
+/* FLASH */
+#define AT91_FLASH_BASE		0x10000000	/* NCS0: Flash physical base address */
+
+/* SDRAM */
+#define AT91_SDRAM_BASE		0x20000000	/* NCS1: SDRAM physical base address */
+
+/* SmartMedia */
+#define AT91_SMARTMEDIA_BASE	0x40000000	/* NCS3: Smartmedia physical base address */
+
+/* Multi-Master Memory controller */
+#define AT91_UHP_BASE		0x00300000	/* USB Host controller */
+
+/* Clocks */
+#define AT91_SLOW_CLOCK		32768		/* slow clock */
+
+#ifndef __ASSEMBLY__
+#include <asm/io.h>
+
+static inline unsigned int at91_sys_read(unsigned int reg_offset)
+{
+	void __iomem *addr = (void __iomem *)AT91_VA_BASE_SYS;
+
+	return readl(addr + reg_offset);
+}
+
+static inline void at91_sys_write(unsigned int reg_offset, unsigned long value)
+{
+	void __iomem *addr = (void __iomem *)AT91_VA_BASE_SYS;
+
+	writel(value, addr + reg_offset);
+}
+#endif
+
+#endif
diff --git a/include/asm-arm/arch-epxa10db/timex.h b/include/asm-arm/arch-at91rm9200/io.h
similarity index 71%
copy from include/asm-arm/arch-epxa10db/timex.h
copy to include/asm-arm/arch-at91rm9200/io.h
index b87a75f..23e670d 100644
--- a/include/asm-arm/arch-epxa10db/timex.h
+++ b/include/asm-arm/arch-at91rm9200/io.h
@@ -1,9 +1,7 @@
 /*
- *  linux/include/asm-arm/arch-epxa10db/timex.h
+ * include/asm-arm/arch-at91rm9200/io.h
  *
- *  Excalibur timex specifications
- *
- *  Copyright (C) 2001 Altera Corporation
+ *  Copyright (C) 2003 SAN People
  *
  * 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
@@ -20,7 +18,16 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-/*
- * ??
- */
-#define CLOCK_TICK_RATE		(50000000 / 16)
+#ifndef __ASM_ARCH_IO_H
+#define __ASM_ARCH_IO_H
+
+#include <asm/arch/at91rm9200.h>
+#include <asm/io.h>
+
+#define IO_SPACE_LIMIT		0xFFFFFFFF
+
+#define __io(a)			((void __iomem *)(a))
+#define __mem_pci(a)		(a)
+
+
+#endif
diff --git a/include/asm-arm/arch-at91rm9200/irqs.h b/include/asm-arm/arch-at91rm9200/irqs.h
new file mode 100644
index 0000000..27b0497
--- /dev/null
+++ b/include/asm-arm/arch-at91rm9200/irqs.h
@@ -0,0 +1,52 @@
+/*
+ * include/asm-arm/arch-at91rm9200/irqs.h
+ *
+ *  Copyright (C) 2004 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#define NR_AIC_IRQS 32
+
+
+/*
+ * Acknowledge interrupt with AIC after interrupt has been handled.
+ *   (by kernel/irq.c)
+ */
+#define irq_finish(irq) do { at91_sys_write(AT91_AIC_EOICR, 0); } while (0)
+
+
+/*
+ * IRQ interrupt symbols are the AT91_ID_* symbols in at91rm9200.h
+ * for IRQs handled directly through the AIC, or else the AT91_PIN_*
+ * symbols in gpio.h for ones handled indirectly as GPIOs.
+ * We make provision for 4 banks of GPIO.
+ */
+#include <asm/arch/gpio.h>
+
+#define	NR_IRQS		(NR_AIC_IRQS + (4 * 32))
+
+
+#ifndef __ASSEMBLY__
+/*
+ * Initialize the IRQ controller.
+ */
+extern void at91rm9200_init_irq(unsigned int priority[]);
+#endif
+
+#endif
diff --git a/include/asm-arm/arch-epxa10db/memory.h b/include/asm-arm/arch-at91rm9200/memory.h
similarity index 78%
rename from include/asm-arm/arch-epxa10db/memory.h
rename to include/asm-arm/arch-at91rm9200/memory.h
index 999541b..462f1f0 100644
--- a/include/asm-arm/arch-epxa10db/memory.h
+++ b/include/asm-arm/arch-at91rm9200/memory.h
@@ -1,7 +1,7 @@
 /*
- *  linux/include/asm-arm/arch-epxa10/memory.h
+ * include/asm-arm/arch-at91rm9200/memory.h
  *
- *  Copyright (C) 2001 Altera Corporation
+ *  Copyright (C) 2004 SAN People
  *
  * 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
@@ -17,13 +17,14 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+
 #ifndef __ASM_ARCH_MEMORY_H
 #define __ASM_ARCH_MEMORY_H
 
-/*
- * Physical DRAM offset.
- */
-#define PHYS_OFFSET	UL(0x00000000)
+#include <asm/arch/hardware.h>
+
+#define PHYS_OFFSET	(AT91_SDRAM_BASE)
+
 
 /*
  * Virtual view <-> DMA view memory address translations
@@ -32,7 +33,9 @@
  * bus_to_virt: Used to convert an address for DMA operations
  *              to an address that the kernel can use.
  */
-#define __virt_to_bus(x)	(x - PAGE_OFFSET + /*SDRAM_BASE*/0)
-#define __bus_to_virt(x)	(x - /*SDRAM_BASE*/0 + PAGE_OFFSET)
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x) __virt_to_phys(x)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x) __phys_to_virt(x)
 
 #endif
diff --git a/include/asm-arm/arch-epxa10db/timex.h b/include/asm-arm/arch-at91rm9200/param.h
similarity index 80%
rename from include/asm-arm/arch-epxa10db/timex.h
rename to include/asm-arm/arch-at91rm9200/param.h
index b87a75f..9480f84 100644
--- a/include/asm-arm/arch-epxa10db/timex.h
+++ b/include/asm-arm/arch-at91rm9200/param.h
@@ -1,9 +1,7 @@
 /*
- *  linux/include/asm-arm/arch-epxa10db/timex.h
+ * include/asm-arm/arch-at91rm9200/param.h
  *
- *  Excalibur timex specifications
- *
- *  Copyright (C) 2001 Altera Corporation
+ *  Copyright (C) 2003 SAN People
  *
  * 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
@@ -20,7 +18,11 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef __ASM_ARCH_PARAM_H
+#define __ASM_ARCH_PARAM_H
+
 /*
- * ??
+ * We use default params
  */
-#define CLOCK_TICK_RATE		(50000000 / 16)
+
+#endif
diff --git a/include/asm-arm/arch-at91rm9200/pio.h b/include/asm-arm/arch-at91rm9200/pio.h
new file mode 100644
index 0000000..a89501b
--- /dev/null
+++ b/include/asm-arm/arch-at91rm9200/pio.h
@@ -0,0 +1,115 @@
+/*
+ * include/asm-arm/arch-at91rm9200/pio.h
+ *
+ *  Copyright (C) 2003 SAN People
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_ARCH_PIO_H
+#define __ASM_ARCH_PIO_H
+
+#include <asm/arch/hardware.h>
+
+static inline void AT91_CfgPIO_USART0(void) {
+	at91_sys_write(AT91_PIOA + PIO_PDR, AT91_PA17_TXD0 | AT91_PA18_RXD0 | AT91_PA20_CTS0);
+
+	/*
+	 * Errata #39 - RTS0 is not internally connected to PA21.  We need to drive
+	 *  the pin manually.  Default is off (RTS is active low).
+	 */
+	at91_sys_write(AT91_PIOA + PIO_PER, AT91_PA21_RTS0);
+	at91_sys_write(AT91_PIOA + PIO_OER, AT91_PA21_RTS0);
+	at91_sys_write(AT91_PIOA + PIO_SODR, AT91_PA21_RTS0);
+}
+
+static inline void AT91_CfgPIO_USART1(void) {
+	at91_sys_write(AT91_PIOB + PIO_PDR, AT91_PB18_RI1 | AT91_PB19_DTR1
+			| AT91_PB20_TXD1 | AT91_PB21_RXD1 | AT91_PB23_DCD1
+			| AT91_PB24_CTS1 | AT91_PB25_DSR1 | AT91_PB26_RTS1);
+}
+
+static inline void AT91_CfgPIO_USART2(void) {
+	at91_sys_write(AT91_PIOA + PIO_PDR, AT91_PA22_RXD2 | AT91_PA23_TXD2);
+}
+
+static inline void AT91_CfgPIO_USART3(void) {
+	at91_sys_write(AT91_PIOA + PIO_PDR, AT91_PA5_TXD3 | AT91_PA6_RXD3);
+	at91_sys_write(AT91_PIOA + PIO_BSR, AT91_PA5_TXD3 | AT91_PA6_RXD3);
+}
+
+static inline void AT91_CfgPIO_DBGU(void) {
+	at91_sys_write(AT91_PIOA + PIO_PDR, AT91_PA31_DTXD | AT91_PA30_DRXD);
+}
+
+/*
+ * Enable the Two-Wire interface.
+ */
+static inline void AT91_CfgPIO_TWI(void) {
+	at91_sys_write(AT91_PIOA + PIO_PDR, AT91_PA25_TWD | AT91_PA26_TWCK);
+	at91_sys_write(AT91_PIOA + PIO_ASR, AT91_PA25_TWD | AT91_PA26_TWCK);
+	at91_sys_write(AT91_PIOA + PIO_MDER, AT91_PA25_TWD | AT91_PA26_TWCK);		/* open drain */
+}
+
+/*
+ * Enable the Serial Peripheral Interface.
+ */
+static inline void AT91_CfgPIO_SPI(void) {
+	at91_sys_write(AT91_PIOA + PIO_PDR, AT91_PA0_MISO | AT91_PA1_MOSI | AT91_PA2_SPCK);
+}
+
+static inline void AT91_CfgPIO_SPI_CS0(void) {
+	at91_sys_write(AT91_PIOA + PIO_PDR, AT91_PA3_NPCS0);
+}
+
+static inline void AT91_CfgPIO_SPI_CS1(void) {
+	at91_sys_write(AT91_PIOA + PIO_PDR, AT91_PA4_NPCS1);
+}
+
+static inline void AT91_CfgPIO_SPI_CS2(void) {
+	at91_sys_write(AT91_PIOA + PIO_PDR, AT91_PA5_NPCS2);
+}
+
+static inline void AT91_CfgPIO_SPI_CS3(void) {
+	at91_sys_write(AT91_PIOA + PIO_PDR, AT91_PA6_NPCS3);
+}
+
+/*
+ * Select the DataFlash card.
+ */
+static inline void AT91_CfgPIO_DataFlashCard(void) {
+	at91_sys_write(AT91_PIOB + PIO_PER, AT91_PIO_P(7));
+	at91_sys_write(AT91_PIOB + PIO_OER, AT91_PIO_P(7));
+	at91_sys_write(AT91_PIOB + PIO_CODR, AT91_PIO_P(7));
+}
+
+/*
+ * Enable NAND Flash (SmartMedia) interface.
+ */
+static inline void AT91_CfgPIO_SmartMedia(void) {
+	/* enable PC0=SMCE, PC1=SMOE, PC3=SMWE, A21=CLE, A22=ALE */
+	at91_sys_write(AT91_PIOC + PIO_ASR, AT91_PC0_BFCK | AT91_PC1_BFRDY_SMOE | AT91_PC3_BFBAA_SMWE);
+	at91_sys_write(AT91_PIOC + PIO_PDR, AT91_PC0_BFCK | AT91_PC1_BFRDY_SMOE | AT91_PC3_BFBAA_SMWE);
+
+	/* Configure PC2 as input (signal READY of the SmartMedia) */
+	at91_sys_write(AT91_PIOC + PIO_PER, AT91_PC2_BFAVD);	/* enable direct output enable */
+	at91_sys_write(AT91_PIOC + PIO_ODR, AT91_PC2_BFAVD);	/* disable output */
+
+	/* Configure PB1 as input (signal Card Detect of the SmartMedia) */
+	at91_sys_write(AT91_PIOB + PIO_PER, AT91_PIO_P(1));	/* enable direct output enable */
+	at91_sys_write(AT91_PIOB + PIO_ODR, AT91_PIO_P(1));	/* disable output */
+}
+
+static inline int AT91_PIO_SmartMedia_RDY(void) {
+	return (at91_sys_read(AT91_PIOC + PIO_PDSR) & AT91_PIO_P(2)) ? 1 : 0;
+}
+
+static inline int AT91_PIO_SmartMedia_CardDetect(void) {
+	return (at91_sys_read(AT91_PIOB + PIO_PDSR) & AT91_PIO_P(1)) ? 1 : 0;
+}
+
+#endif
diff --git a/include/asm-arm/arch-at91rm9200/system.h b/include/asm-arm/arch-at91rm9200/system.h
new file mode 100644
index 0000000..29c4265
--- /dev/null
+++ b/include/asm-arm/arch-at91rm9200/system.h
@@ -0,0 +1,51 @@
+/*
+ * include/asm-arm/arch-at91rm9200/system.h
+ *
+ *  Copyright (C) 2003 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <asm/arch/hardware.h>
+
+static inline void arch_idle(void)
+{
+	/*
+	 * Disable the processor clock.  The processor will be automatically
+	 * re-enabled by an interrupt or by a reset.
+	 */
+//	at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+
+	/*
+	 * Set the processor (CP15) into 'Wait for Interrupt' mode.
+	 * Unlike disabling the processor clock via the PMC (above)
+	 *  this allows the processor to be woken via JTAG.
+	 */
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode)
+{
+	/*
+	 * Perform a hardware reset with the use of the Watchdog timer.
+	 */
+	at91_sys_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1);
+	at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
+}
+
+#endif
diff --git a/include/asm-arm/arch-epxa10db/timex.h b/include/asm-arm/arch-at91rm9200/timex.h
similarity index 77%
copy from include/asm-arm/arch-epxa10db/timex.h
copy to include/asm-arm/arch-at91rm9200/timex.h
index b87a75f..3f112dd 100644
--- a/include/asm-arm/arch-epxa10db/timex.h
+++ b/include/asm-arm/arch-at91rm9200/timex.h
@@ -1,9 +1,7 @@
 /*
- *  linux/include/asm-arm/arch-epxa10db/timex.h
+ * include/asm-arm/arch-at91rm9200/timex.h
  *
- *  Excalibur timex specifications
- *
- *  Copyright (C) 2001 Altera Corporation
+ *  Copyright (C) 2003 SAN People
  *
  * 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
@@ -20,7 +18,11 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-/*
- * ??
- */
-#define CLOCK_TICK_RATE		(50000000 / 16)
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+#include <asm/arch/hardware.h>
+
+#define CLOCK_TICK_RATE		(AT91_SLOW_CLOCK)
+
+#endif
diff --git a/include/asm-arm/arch-at91rm9200/uncompress.h b/include/asm-arm/arch-at91rm9200/uncompress.h
new file mode 100644
index 0000000..b30dd55
--- /dev/null
+++ b/include/asm-arm/arch-at91rm9200/uncompress.h
@@ -0,0 +1,55 @@
+/*
+ * include/asm-arm/arch-at91rm9200/uncompress.h
+ *
+ *  Copyright (C) 2003 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <asm/arch/hardware.h>
+
+/*
+ * The following code assumes the serial port has already been
+ * initialized by the bootloader.  We search for the first enabled
+ * port in the most probable order.  If you didn't setup a port in
+ * your bootloader then nothing will appear (which might be desired).
+ *
+ * This does not append a newline
+ */
+static void putstr(const char *s)
+{
+	void __iomem *sys = (void __iomem *) AT91_BASE_SYS;	/* physical address */
+
+	while (*s) {
+		while (!(__raw_readl(sys + AT91_DBGU_SR) & AT91_DBGU_TXRDY)) { barrier(); }
+		__raw_writel(*s, sys + AT91_DBGU_THR);
+		if (*s == '\n')	{
+			while (!(__raw_readl(sys + AT91_DBGU_SR) & AT91_DBGU_TXRDY)) { barrier(); }
+			__raw_writel('\r', sys + AT91_DBGU_THR);
+		}
+		s++;
+	}
+	/* wait for transmission to complete */
+	while (!(__raw_readl(sys + AT91_DBGU_SR) & AT91_DBGU_TXEMPTY)) { barrier(); }
+}
+
+#define arch_decomp_setup()
+
+#define arch_decomp_wdog()
+
+#endif
diff --git a/include/asm-arm/arch-epxa10db/vmalloc.h b/include/asm-arm/arch-at91rm9200/vmalloc.h
similarity index 78%
rename from include/asm-arm/arch-epxa10db/vmalloc.h
rename to include/asm-arm/arch-at91rm9200/vmalloc.h
index 546fb7d..34d9718 100644
--- a/include/asm-arm/arch-epxa10db/vmalloc.h
+++ b/include/asm-arm/arch-at91rm9200/vmalloc.h
@@ -1,7 +1,7 @@
 /*
- *  linux/include/asm-arm/arch-epxa10db/vmalloc.h
+ * include/asm-arm/arch-at91rm9200/vmalloc.h
  *
- *  Copyright (C) 2000 Russell King.
+ *  Copyright (C) 2003 SAN People
  *
  * 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
@@ -17,4 +17,10 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END		(AT91_IO_VIRT_BASE & PGDIR_MASK)
+
+#endif
diff --git a/include/asm-arm/arch-epxa10db/debug-macro.S b/include/asm-arm/arch-epxa10db/debug-macro.S
deleted file mode 100644
index 1d11c51..0000000
--- a/include/asm-arm/arch-epxa10db/debug-macro.S
+++ /dev/null
@@ -1,41 +0,0 @@
-/* linux/include/asm-arm/arch-epxa10db/debug-macro.S
- *
- * Debugging macro include header
- *
- *  Copyright (C) 1994-1999 Russell King
- *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
- *
- * 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 <asm/arch/excalibur.h>
-#define UART00_TYPE
-#include <asm/arch/uart00.h>
-
-		.macro	addruart,rx
-		mrc	p15, 0, \rx, c1, c0
-		tst	\rx, #1			@ MMU enabled?
-		ldr	\rx, =EXC_UART00_BASE	@ physical base address
-		orrne	\rx, \rx, #0xff000000	@ virtual base
-		orrne	\rx, \rx, #0x00f00000
-		.endm
-
-		.macro	senduart,rd,rx
-		str	\rd, [\rx, #UART_TD(0)]
-		.endm
-
-		.macro	waituart,rd,rx
-1001:		ldr	\rd, [\rx, #UART_TSR(0)]
-		and 	\rd, \rd,  #UART_TSR_TX_LEVEL_MSK
-		cmp	\rd, #15
-		beq	1001b
-		.endm
-
-		.macro	busyuart,rd,rx
-1001:		ldr	\rd, [\rx, #UART_TSR(0)]
-		ands 	\rd, \rd,  #UART_TSR_TX_LEVEL_MSK
-		bne	1001b
-		.endm
diff --git a/include/asm-arm/arch-epxa10db/dma.h b/include/asm-arm/arch-epxa10db/dma.h
deleted file mode 100644
index de20ec8..0000000
--- a/include/asm-arm/arch-epxa10db/dma.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-camelot/dma.h
- *
- *  Copyright (C) 1997,1998 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
diff --git a/include/asm-arm/arch-epxa10db/entry-macro.S b/include/asm-arm/arch-epxa10db/entry-macro.S
deleted file mode 100644
index de6ae08..0000000
--- a/include/asm-arm/arch-epxa10db/entry-macro.S
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * include/asm-arm/arch-epxa10db/entry-macro.S
- *
- * Low-level IRQ helper macros for epxa10db platform
- *
- * 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 <asm/arch/platform.h>
-#undef IRQ_MODE /* same name defined in asm/proc/ptrace.h */
-#include <asm/arch/int_ctrl00.h>
-
-		.macro	disable_fiq
-		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-
-		ldr	\irqstat, =INT_ID(IO_ADDRESS(EXC_INT_CTRL00_BASE))
-		ldr	\irqnr,[\irqstat]
-		cmp	\irqnr,#0
-		subne	\irqnr,\irqnr,#1
-
-		.endm
-
diff --git a/include/asm-arm/arch-epxa10db/ether00.h b/include/asm-arm/arch-epxa10db/ether00.h
deleted file mode 100644
index b737b8a..0000000
--- a/include/asm-arm/arch-epxa10db/ether00.h
+++ /dev/null
@@ -1,482 +0,0 @@
-#ifndef __ETHER00_H
-#define __ETHER00_H
-
-
-
-/*
- * Register definitions for the Ethernet MAC
- */
-
-/*
- * Copyright (c) Altera Corporation 2000.
- * All rights reserved.
- */
-
-/*
-*	Structures for the DMA controller
-*/
-typedef struct fda_desc
-	{
-	struct fda_desc *	FDNext;
-	long				FDSystem;
-	long				FDStat;
-	short				FDLength;
-	short				FDCtl;
-	}FDA_DESC;
-
-typedef struct buf_desc
-	{
-	char *	BuffData;
-	short	BuffLength;
-	char	BDStat;
-	char	BDCtl;
-	}BUF_DESC;
-
-/*
-*	Control masks for the DMA controller
-*/
-#define FDCTL_BDCOUNT_MSK						(0x1F)
-#define FDCTL_BDCOUNT_OFST						(0)
-#define FDCTL_FRMOPT_MSK						(0x7C00)
-#define FDCTL_FRMOPT_OFST						(10)
-#define	FDCTL_COWNSFD_MSK						(0x8000)
-#define	FDCTL_COWNSFD_OFST						(15)
-
-#define BDCTL_RXBDSEQN_MSK						(0x7F)
-#define BDCTL_RXBDSEQN_OFST						(0)
-#define	BDCTL_COWNSBD_MSK						(0x80)
-#define	BDCTL_COWNSBD_OFST						(7)
-
-#define FDNEXT_EOL_MSK							(0x1)
-#define FDNEXT_EOL_OFST							(0)
-#define FDNEXT_EOL_POINTER_MSK					(0xFFFFFFF0)
-#define FDNEXT_EOL_POINTER_OFST					(4)
-
-#define ETHER_ARC_SIZE         (21)
-
-/*
-*	Register definitions and masks
-*/
-#define ETHER_DMA_CTL(base)							(ETHER00_TYPE (base + 0x100))
-#define ETHER_DMA_CTL_DMBURST_OFST				(2)
-#define ETHER_DMA_CTL_DMBURST_MSK				(0x1FC)
-#define ETHER_DMA_CTL_POWRMGMNT_OFST			(11)
-#define ETHER_DMA_CTL_POWRMGMNT_MSK				(0x1000)
-#define ETHER_DMA_CTL_TXBIGE_OFST				(14)
-#define ETHER_DMA_CTL_TXBIGE_MSK				(0x4000)
-#define ETHER_DMA_CTL_RXBIGE_OFST				(15)
-#define ETHER_DMA_CTL_RXBIGE_MSK				(0x8000)
-#define ETHER_DMA_CTL_TXWAKEUP_OFST				(16)
-#define ETHER_DMA_CTL_TXWAKEUP_MSK				(0x10000)
-#define ETHER_DMA_CTL_SWINTREQ_OFST				(17)
-#define ETHER_DMA_CTL_SWINTREQ_MSK				(0x20000)
-#define ETHER_DMA_CTL_INTMASK_OFST				(18)
-#define ETHER_DMA_CTL_INTMASK_MSK				(0x40000)
-#define ETHER_DMA_CTL_M66ENSTAT_OFST			(19)
-#define ETHER_DMA_CTL_M66ENSTAT_MSK				(0x80000)
-#define ETHER_DMA_CTL_RMTXINIT_OFST				(20)
-#define ETHER_DMA_CTL_RMTXINIT_MSK				(0x100000)
-#define ETHER_DMA_CTL_RMRXINIT_OFST				(21)
-#define ETHER_DMA_CTL_RMRXINIT_MSK				(0x200000)
-#define ETHER_DMA_CTL_RXALIGN_OFST				(22)
-#define ETHER_DMA_CTL_RXALIGN_MSK				(0xC00000)
-#define ETHER_DMA_CTL_RMSWRQ_OFST				(24)
-#define ETHER_DMA_CTL_RMSWRQ_MSK				(0x1000000)
-#define ETHER_DMA_CTL_RMEMBANK_OFST				(25)
-#define ETHER_DMA_CTL_RMEMBANK_MSK				(0x2000000)
-
-#define ETHER_TXFRMPTR(base)							(ETHER00_TYPE (base + 0x104))
-
-#define ETHER_TXTHRSH(base)							(ETHER00_TYPE (base + 0x308))
-
-#define ETHER_TXPOLLCTR(base)							(ETHER00_TYPE (base + 0x30c))
-
-#define	ETHER_BLFRMPTR(base)							(ETHER00_TYPE (base + 0x110))
-#define ETHER_BLFFRMPTR_EOL_OFST				(0)
-#define ETHER_BLFFRMPTR_EOL_MSK					(0x1)
-#define ETHER_BLFFRMPTR_ADDRESS_OFST			(4)
-#define ETHER_BLFFRMPTR_ADDRESS_MSK				(0xFFFFFFF0)
-
-#define ETHER_RXFRAGSIZE(base)						(ETHER00_TYPE (base + 0x114))
-#define	ETHER_RXFRAGSIZE_MINFRAG_OFST			(2)
-#define	ETHER_RXFRAGSIZE_MINFRAG_MSK			(0xFFC)
-#define	ETHER_RXFRAGSIZE_ENPACK_OFST			(15)
-#define	ETHER_RXFRAGSIZE_ENPACK_MSK				(0x8000)
-
-#define ETHER_INT_EN(base)							(ETHER00_TYPE (base + 0x118))
-#define ETHER_INT_EN_FDAEXEN_OFST				(0)
-#define ETHER_INT_EN_FDAEXEN_MSK				(0x1)
-#define ETHER_INT_EN_BLEXEN_OFST				(1)
-#define ETHER_INT_EN_BLEXN_MSK					(0x2)
-#define ETHER_INT_EN_STARGABTEN_OFST			(2)
-#define ETHER_INT_EN_STARGABTEN_MSK				(0x4)
-#define ETHER_INT_EN_RTARGABTEN_OFST			(3)
-#define ETHER_INT_EN_RTARGABTEN_MSK				(0x8)
-#define ETHER_INT_EN_RMASABTEN_OFST				(4)
-#define ETHER_INT_EN_RMASABTEN_MSK				(0x10)
-#define ETHER_INT_EN_SSYSERREN_OFST				(5)
-#define ETHER_INT_EN_SSYSERREN_MSK				(0x20)
-#define ETHER_INT_EN_DPARERREN_OFST				(6)
-#define ETHER_INT_EN_DPARERREN_MSK				(0x40)
-#define ETHER_INT_EN_EARNOTEN_OFST				(7)
-#define ETHER_INT_EN_EARNOTEN_MSK				(0x80)
-#define ETHER_INT_EN_DPARDEN_OFST				(8)
-#define ETHER_INT_EN_DPARDEN_MSK				(0x100)
-#define ETHER_INT_EN_DMPARERREN_OFST			(9)
-#define ETHER_INT_EN_DMPARERREN_MSK				(0x200)
-#define ETHER_INT_EN_TXCTLCMPEN_OFST			(10)
-#define ETHER_INT_EN_TXCTLCMPEN_MSK				(0x400)
-#define ETHER_INT_EN_NRABTEN_OFST				(11)
-#define ETHER_INT_EN_NRABTEN_MSK				(0x800)
-
-#define	ETHER_FDA_BAS(base)							(ETHER00_TYPE (base + 0x11C))
-#define ETHER_FDA_BAS_ADDRESS_OFST				(4)
-#define ETHER_FDA_BAS_ADDRESS_MSK				(0xFFFFFFF0)
-
-#define ETHER_FDA_LIM(base)							(ETHER00_TYPE (base + 0x120))
-#define ETHER_FDA_LIM_COUNT_OFST				(4)
-#define ETHER_FDA_LIM_COUNT_MSK					(0xFFF0)
-
-#define ETHER_INT_SRC(base)							(ETHER00_TYPE (base + 0x124))
-#define ETHER_INT_SRC_INTMACTX_OFST				(0)
-#define ETHER_INT_SRC_INTMACTX_MSK				(0x1)
-#define ETHER_INT_SRC_INTMACRX_OFST				(1)
-#define ETHER_INT_SRC_INTMACRX_MSK				(0x2)
-#define ETHER_INT_SRC_INTSBUS_OFST				(2)
-#define ETHER_INT_SRC_INTSBUS_MSK				(0x4)
-#define ETHER_INT_SRC_INTFDAEX_OFST				(3)
-#define ETHER_INT_SRC_INTFDAEX_MSK				(0x8)
-#define ETHER_INT_SRC_INTBLEX_OFST				(4)
-#define ETHER_INT_SRC_INTBLEX_MSK				(0x10)
-#define ETHER_INT_SRC_SWINT_OFST				(5)
-#define ETHER_INT_SRC_SWINT_MSK					(0x20)
-#define ETHER_INT_SRC_INTEARNOT_OFST			(6)
-#define ETHER_INT_SRC_INTEARNOT_MSK				(0x40)
-#define ETHER_INT_SRC_DMPARERR_OFST				(7)
-#define ETHER_INT_SRC_DMPARERR_MSK				(0x80)
-#define ETHER_INT_SRC_INTEXBD_OFST				(8)
-#define ETHER_INT_SRC_INTEXBD_MSK				(0x100)
-#define ETHER_INT_SRC_INTTXCTLCMP_OFST			(9)
-#define ETHER_INT_SRC_INTTXCTLCMP_MSK			(0x200)
-#define ETHER_INT_SRC_INTNRABT_OFST				(10)
-#define ETHER_INT_SRC_INTNRABT_MSK				(0x400)
-#define ETHER_INT_SRC_FDAEX_OFST				(11)
-#define ETHER_INT_SRC_FDAEX_MSK					(0x800)
-#define ETHER_INT_SRC_BLEX_OFST					(12)
-#define ETHER_INT_SRC_BLEX_MSK					(0x1000)
-#define ETHER_INT_SRC_DMPARERRSTAT_OFST			(13)
-#define ETHER_INT_SRC_DMPARERRSTAT_MSK			(0x2000)
-#define ETHER_INT_SRC_NRABT_OFST				(14)
-#define ETHER_INT_SRC_NRABT_MSK					(0x4000)
-#define ETHER_INT_SRC_INTLINK_OFST				(15)
-#define ETHER_INT_SRC_INTLINK_MSK				(0x8000)
-#define ETHER_INT_SRC_INTEXDEFER_OFST			(16)
-#define ETHER_INT_SRC_INTEXDEFER_MSK			(0x10000)
-#define ETHER_INT_SRC_INTRMON_OFST				(17)
-#define ETHER_INT_SRC_INTRMON_MSK				(0x20000)
-#define ETHER_INT_SRC_IRQ_MSK					(0x83FF)
-
-#define ETHER_PAUSECNT(base)							(ETHER00_TYPE (base + 0x40))
-#define ETHER_PAUSECNT_COUNT_OFST				(0)
-#define ETHER_PAUSECNT_COUNT_MSK				(0xFFFF)
-
-#define ETHER_REMPAUCNT(base)							(ETHER00_TYPE (base + 0x44))
-#define ETHER_REMPAUCNT_COUNT_OFST				(0)
-#define ETHER_REMPAUCNT_COUNT_MSK				(0xFFFF)
-
-#define ETHER_TXCONFRMSTAT(base)						(ETHER00_TYPE (base + 0x348))
-#define ETHER_TXCONFRMSTAT_TS_STAT_VALUE_OFST	(0)
-#define ETHER_TXCONFRMSTAT_TS_STAT_VALUE_MSK	(0x3FFFFF)
-
-#define ETHER_MAC_CTL(base)							(ETHER00_TYPE (base + 0))
-#define ETHER_MAC_CTL_HALTREQ_OFST				(0)
-#define ETHER_MAC_CTL_HALTREQ_MSK				(0x1)
-#define ETHER_MAC_CTL_HALTIMM_OFST				(1)
-#define ETHER_MAC_CTL_HALTIMM_MSK				(0x2)
-#define ETHER_MAC_CTL_RESET_OFST				(2)
-#define ETHER_MAC_CTL_RESET_MSK					(0x4)
-#define ETHER_MAC_CTL_FULLDUP_OFST				(3)
-#define ETHER_MAC_CTL_FULLDUP_MSK				(0x8)
-#define ETHER_MAC_CTL_MACLOOP_OFST				(4)
-#define ETHER_MAC_CTL_MACLOOP_MSK				(0x10)
-#define ETHER_MAC_CTL_CONN_OFST					(5)
-#define ETHER_MAC_CTL_CONN_MSK					(0x60)
-#define ETHER_MAC_CTL_LOOP10_OFST				(7)
-#define ETHER_MAC_CTL_LOOP10_MSK				(0x80)
-#define ETHER_MAC_CTL_LNKCHG_OFST				(8)
-#define ETHER_MAC_CTL_LNKCHG_MSK				(0x100)
-#define ETHER_MAC_CTL_MISSROLL_OFST				(10)
-#define ETHER_MAC_CTL_MISSROLL_MSK				(0x400)
-#define ETHER_MAC_CTL_ENMISSROLL_OFST			(13)
-#define ETHER_MAC_CTL_ENMISSROLL_MSK			(0x2000)
-#define ETHER_MAC_CTL_LINK10_OFST				(15)
-#define ETHER_MAC_CTL_LINK10_MSK				(0x8000)
-
-#define ETHER_ARC_CTL(base)							(ETHER00_TYPE (base + 0x4))
-#define	ETHER_ARC_CTL_STATIONACC_OFST			(0)
-#define	ETHER_ARC_CTL_STATIONACC_MSK			(0x1)
-#define	ETHER_ARC_CTL_GROUPACC_OFST				(1)
-#define	ETHER_ARC_CTL_GROUPACC_MSK				(0x2)
-#define	ETHER_ARC_CTL_BROADACC_OFST				(2)
-#define	ETHER_ARC_CTL_BROADACC_MSK				(0x4)
-#define	ETHER_ARC_CTL_NEGARC_OFST				(3)
-#define	ETHER_ARC_CTL_NEGARC_MSK				(0x8)
-#define	ETHER_ARC_CTL_COMPEN_OFST				(4)
-#define	ETHER_ARC_CTL_COMPEN_MSK				(0x10)
-
-#define ETHER_TX_CTL(base)							(ETHER00_TYPE (base + 0x8))
-#define ETHER_TX_CTL_TXEN_OFST					(0)
-#define ETHER_TX_CTL_TXEN_MSK					(0x1)
-#define ETHER_TX_CTL_TXHALT_OFST				(1)
-#define ETHER_TX_CTL_TXHALT_MSK					(0x2)
-#define ETHER_TX_CTL_NOPAD_OFST					(2)
-#define ETHER_TX_CTL_NOPAD_MSK					(0x4)
-#define ETHER_TX_CTL_NOCRC_OFST					(3)
-#define ETHER_TX_CTL_NOCRC_MSK					(0x8)
-#define ETHER_TX_CTL_FBACK_OFST					(4)
-#define ETHER_TX_CTL_FBACK_MSK					(0x10)
-#define ETHER_TX_CTL_NOEXDEF_OFST				(5)
-#define ETHER_TX_CTL_NOEXDEF_MSK				(0x20)
-#define ETHER_TX_CTL_SDPAUSE_OFST				(6)
-#define ETHER_TX_CTL_SDPAUSE_MSK				(0x40)
-#define ETHER_TX_CTL_MII10_OFST					(7)
-#define ETHER_TX_CTL_MII10_MSK					(0x80)
-#define ETHER_TX_CTL_ENUNDER_OFST				(8)
-#define ETHER_TX_CTL_ENUNDER_MSK				(0x100)
-#define ETHER_TX_CTL_ENEXDEFER_OFST				(9)
-#define ETHER_TX_CTL_ENEXDEFER_MSK				(0x200)
-#define ETHER_TX_CTL_ENLCARR_OFST				(10)
-#define ETHER_TX_CTL_ENLCARR_MSK				(0x400)
-#define ETHER_TX_CTL_ENEXCOLL_OFST				(11)
-#define ETHER_TX_CTL_ENEXCOLL_MSK				(0x800)
-#define ETHER_TX_CTL_ENLATECOLL_OFST				(12)
-#define ETHER_TX_CTL_ENLATECOLL_MSK				(0x1000)
-#define ETHER_TX_CTL_ENTXPAR_OFST				(13)
-#define ETHER_TX_CTL_ENTXPAR_MSK				(0x2000)
-#define ETHER_TX_CTL_ENCOMP_OFST				(14)
-#define ETHER_TX_CTL_ENCOMP_MSK					(0x4000)
-
-#define ETHER_TX_STAT(base)							(ETHER00_TYPE (base + 0xc))
-#define ETHER_TX_STAT_TXCOLL_OFST				(0)
-#define ETHER_TX_STAT_TXCOLL_MSK				(0xF)
-#define ETHER_TX_STAT_EXCOLL_OFST				(4)
-#define ETHER_TX_STAT_EXCOLL_MSK				(0x10)
-#define ETHER_TX_STAT_TXDEFER_OFST				(5)
-#define ETHER_TX_STAT_TXDEFER_MSK				(0x20)
-#define ETHER_TX_STAT_PAUSED_OFST				(6)
-#define ETHER_TX_STAT_PAUSED_MSK				(0x40)
-#define ETHER_TX_STAT_INTTX_OFST				(7)
-#define ETHER_TX_STAT_INTTX_MSK					(0x80)
-#define ETHER_TX_STAT_UNDER_OFST				(8)
-#define ETHER_TX_STAT_UNDER_MSK					(0x100)
-#define ETHER_TX_STAT_EXDEFER_OFST				(9)
-#define ETHER_TX_STAT_EXDEFER_MSK				(0x200)
-#define ETHER_TX_STAT_LCARR_OFST				(10)
-#define ETHER_TX_STAT_LCARR_MSK					(0x400)
-#define ETHER_TX_STAT_TX10STAT_OFST				(11)
-#define ETHER_TX_STAT_TX10STAT_MSK				(0x800)
-#define ETHER_TX_STAT_LATECOLL_OFST				(12)
-#define ETHER_TX_STAT_LATECOLL_MSK				(0x1000)
-#define ETHER_TX_STAT_TXPAR_OFST				(13)
-#define ETHER_TX_STAT_TXPAR_MSK					(0x2000)
-#define ETHER_TX_STAT_COMP_OFST					(14)
-#define ETHER_TX_STAT_COMP_MSK					(0x4000)
-#define ETHER_TX_STAT_TXHALTED_OFST				(15)
-#define ETHER_TX_STAT_TXHALTED_MSK				(0x8000)
-#define ETHER_TX_STAT_SQERR_OFST				(16)
-#define ETHER_TX_STAT_SQERR_MSK					(0x10000)
-#define ETHER_TX_STAT_TXMCAST_OFST				(17)
-#define ETHER_TX_STAT_TXMCAST_MSK				(0x20000)
-#define ETHER_TX_STAT_TXBCAST_OFST				(18)
-#define ETHER_TX_STAT_TXBCAST_MSK				(0x40000)
-#define ETHER_TX_STAT_VLAN_OFST					(19)
-#define ETHER_TX_STAT_VLAN_MSK					(0x80000)
-#define ETHER_TX_STAT_MACC_OFST					(20)
-#define ETHER_TX_STAT_MACC_MSK					(0x100000)
-#define ETHER_TX_STAT_TXPAUSE_OFST				(21)
-#define ETHER_TX_STAT_TXPAUSE_MSK				(0x200000)
-
-#define ETHER_RX_CTL(base)							(ETHER00_TYPE (base + 0x10))
-#define ETHER_RX_CTL_RXEN_OFST					(0)
-#define ETHER_RX_CTL_RXEN_MSK					(0x1)
-#define ETHER_RX_CTL_RXHALT_OFST				(1)
-#define ETHER_RX_CTL_RXHALT_MSK					(0x2)
-#define ETHER_RX_CTL_LONGEN_OFST				(2)
-#define ETHER_RX_CTL_LONGEN_MSK					(0x4)
-#define ETHER_RX_CTL_SHORTEN_OFST				(3)
-#define ETHER_RX_CTL_SHORTEN_MSK				(0x8)
-#define ETHER_RX_CTL_STRIPCRC_OFST				(4)
-#define ETHER_RX_CTL_STRIPCRC_MSK				(0x10)
-#define ETHER_RX_CTL_PASSCTL_OFST				(5)
-#define ETHER_RX_CTL_PASSCTL_MSK				(0x20)
-#define ETHER_RX_CTL_IGNORECRC_OFST				(6)
-#define ETHER_RX_CTL_IGNORECRC_MSK				(0x40)
-#define ETHER_RX_CTL_ENALIGN_OFST				(8)
-#define ETHER_RX_CTL_ENALIGN_MSK				(0x100)
-#define ETHER_RX_CTL_ENCRCERR_OFST				(9)
-#define ETHER_RX_CTL_ENCRCERR_MSK				(0x200)
-#define ETHER_RX_CTL_ENOVER_OFST				(10)
-#define ETHER_RX_CTL_ENOVER_MSK					(0x400)
-#define ETHER_RX_CTL_ENLONGERR_OFST				(11)
-#define ETHER_RX_CTL_ENLONGERR_MSK				(0x800)
-#define ETHER_RX_CTL_ENRXPAR_OFST				(13)
-#define ETHER_RX_CTL_ENRXPAR_MSK				(0x2000)
-#define ETHER_RX_CTL_ENGOOD_OFST				(14)
-#define ETHER_RX_CTL_ENGOOD_MSK					(0x4000)
-
-#define ETHER_RX_STAT(base)							(ETHER00_TYPE (base + 0x14))
-#define ETHER_RX_STAT_LENERR_OFST				(4)
-#define ETHER_RX_STAT_LENERR_MSK				(0x10)
-#define ETHER_RX_STAT_CTLRECD_OFST				(5)
-#define ETHER_RX_STAT_CTLRECD_MSK				(0x20)
-#define ETHER_RX_STAT_INTRX_OFST				(6)
-#define ETHER_RX_STAT_INTRX_MSK					(0x40)
-#define ETHER_RX_STAT_RX10STAT_OFST				(7)
-#define ETHER_RX_STAT_RX10STAT_MSK				(0x80)
-#define ETHER_RX_STAT_ALIGNERR_OFST				(8)
-#define ETHER_RX_STAT_ALIGNERR_MSK				(0x100)
-#define ETHER_RX_STAT_CRCERR_OFST				(9)
-#define ETHER_RX_STAT_CRCERR_MSK				(0x200)
-#define ETHER_RX_STAT_OVERFLOW_OFST				(10)
-#define ETHER_RX_STAT_OVERFLOW_MSK				(0x400)
-#define ETHER_RX_STAT_LONGERR_OFST				(11)
-#define ETHER_RX_STAT_LONGERR_MSK				(0x800)
-#define ETHER_RX_STAT_RXPAR_OFST				(13)
-#define ETHER_RX_STAT_RXPAR_MSK					(0x2000)
-#define ETHER_RX_STAT_GOOD_OFST					(14)
-#define ETHER_RX_STAT_GOOD_MSK					(0x4000)
-#define ETHER_RX_STAT_RXHALTED_OFST				(15)
-#define ETHER_RX_STAT_RXHALTED_MSK				(0x8000)
-#define ETHER_RX_STAT_RXMCAST_OFST				(17)
-#define ETHER_RX_STAT_RXMCAST_MSK				(0x10000)
-#define ETHER_RX_STAT_RXBCAST_OFST				(18)
-#define ETHER_RX_STAT_RXBCAST_MSK				(0x20000)
-#define ETHER_RX_STAT_RXVLAN_OFST				(19)
-#define ETHER_RX_STAT_RXVLAN_MSK				(0x40000)
-#define ETHER_RX_STAT_RXPAUSE_OFST				(20)
-#define ETHER_RX_STAT_RXPAUSE_MSK				(0x80000)
-#define ETHER_RX_STAT_ARCSTATUS_OFST				(21)
-#define ETHER_RX_STAT_ARCSTATUS_MSK				(0xF00000)
-#define ETHER_RX_STAT_ARCENT_OFST				(25)
-#define ETHER_RX_STAT_ARCENT_MSK				(0x1F000000)
-
-#define ETHER_MD_DATA(base)							(ETHER00_TYPE (base + 0x18))
-
-#define ETHER_MD_CA(base)								(ETHER00_TYPE (base + 0x1c))
-#define ETHER_MD_CA_ADDR_OFST					(0)
-#define ETHER_MD_CA_ADDR_MSK					(0x1F)
-#define ETHER_MD_CA_PHY_OFST					(5)
-#define ETHER_MD_CA_PHY_MSK					(0x3E0)
-#define ETHER_MD_CA_WR_OFST					(10)
-#define ETHER_MD_CA_WR_MSK					(0x400)
-#define ETHER_MD_CA_BUSY_OFST					(11)
-#define ETHER_MD_CA_BUSY_MSK					(0x800)
-#define ETHER_MD_CA_PRESUPP_OFST				(12)
-#define ETHER_MD_CA_PRESUPP_MSK					(0x1000)
-
-#define ETHER_ARC_ADR(base)	      (ETHER00_TYPE (base + 0x160))
-#define ETHER_ARC_ADR_ARC_LOC_OFST				(2)
-#define ETHER_ARC_ADR_ARC_LOC_MSK				(0xFFC)
-
-#define ETHER_ARC_DATA(base)  (ETHER00_TYPE (base + 0x364))
-
-#define ETHER_ARC_ENA(base)   (ETHER00_TYPE (base + 0x28))
-#define ETHER_ARC_ENA_MSK					(0x1FFFFF)
-
-#define ETHER_PROM_CTL(base)							(ETHER00_TYPE (base + 0x2c))
-#define ETHER_PROM_CTL_PROM_ADDR_OFST			(0)
-#define ETHER_PROM_CTL_PROM_ADDR_MSK			(0x3F)
-#define ETHER_PROM_CTL_OPCODE_OFST				(13)
-#define ETHER_PROM_CTL_OPCODE_MSK				(0x6000)
-#define ETHER_PROM_CTL_OPCODE_READ_MSK			(0x4000)
-#define ETHER_PROM_CTL_OPCODE_WRITE_MSK			(0x2000)
-#define ETHER_PROM_CTL_OPCODE_ERASE_MSK			(0x6000)
-#define ETHER_PROM_CTL_ENABLE_MSK				(0x0030)
-#define ETHER_PROM_CTL_DISABLE_MSK				(0x0000)
-#define ETHER_PROM_CTL_BUSY_OFST				(15)
-#define ETHER_PROM_CTL_BUSY_MSK					(0x8000)
-
-#define ETHER_PROM_DATA(base)							(ETHER00_TYPE (base + 0x30))
-
-#define ETHER_MISS_CNT(base)							(ETHER00_TYPE (base + 0x3c))
-#define ETHER_MISS_CNT_COUNT_OFST				(0)
-#define ETHER_MISS_CNT_COUNT_MSK				(0xFFFF)
-
-#define ETHER_CNTDATA(base)							(ETHER00_TYPE (base + 0x80))
-
-#define ETHER_CNTACC(base)							(ETHER00_TYPE (base + 0x84))
-#define ETHER_CNTACC_ADDR_OFST					(0)
-#define ETHER_CNTACC_ADDR_MSK					(0xFF)
-#define ETHER_CNTACC_WRRDN_OFST					(8)
-#define ETHER_CNTACC_WRRDN_MSK					(0x100)
-#define ETHER_CNTACC_CLEAR_OFST					(9)
-#define ETHER_CNTACC_CLEAR_MSK					(0x200)
-
-#define ETHER_TXRMINTEN(base)							(ETHER00_TYPE (base + 0x88))
-#define ETHER_TXRMINTEN_MSK						(0x3FFFFFFF)
-
-#define ETHER_RXRMINTEN(base)							(ETHER00_TYPE (base + 0x8C))
-#define ETHER_RXRMINTEN_MSK						(0xFFFFFF)
-
-/*
-*	RMON Registers
-*/
-#define		RMON_COLLISION0						0x0
-#define		RMON_COLLISION1						0x1
-#define		RMON_COLLISION2						0x2
-#define		RMON_COLLISION3						0x3
-#define		RMON_COLLISION4						0x4
-#define		RMON_COLLISION5						0x5
-#define		RMON_COLLISION6						0x6
-#define		RMON_COLLISION7						0x7
-#define		RMON_COLLISION8						0x8
-#define		RMON_COLLISION9						0x9
-#define		RMON_COLLISION10					0xa
-#define		RMON_COLLISION11					0xb
-#define		RMON_COLLISION12					0xc
-#define		RMON_COLLISION13					0xd
-#define		RMON_COLLISION14					0xe
-#define		RMON_COLLISION15					0xf
-#define		RMON_COLLISION16					0x10
-#define		RMON_FRAMES_WITH_DEFERRED_XMISSIONS	0x11
-#define		RMON_LATE_COLLISIONS				0x12
-#define		RMON_FRAMES_LOST_DUE_TO_MAC_XMIT	0x13
-#define		RMON_CARRIER_SENSE_ERRORS			0x14
-#define		RMON_FRAMES_WITH_EXCESSIVE_DEFERAL	0x15
-#define		RMON_UNICAST_FRAMES_TRANSMITTED_OK	0x16
-#define		RMON_MULTICAST_FRAMES_XMITTED_OK	0x17
-#define		RMON_BROADCAST_FRAMES_XMITTED_OK	0x18
-#define		RMON_SQE_TEST_ERRORS				0x19
-#define		RMON_PAUSE_MACCTRL_FRAMES_XMITTED	0x1A
-#define		RMON_MACCTRL_FRAMES_XMITTED			0x1B
-#define		RMON_VLAN_FRAMES_XMITTED			0x1C
-#define		RMON_OCTETS_XMITTED_OK				0x1D
-#define		RMON_OCTETS_XMITTED_OK_HI			0x1E
-
-#define		RMON_RX_PACKET_SIZES0				0x40
-#define		RMON_RX_PACKET_SIZES1				0x41
-#define		RMON_RX_PACKET_SIZES2				0x42
-#define		RMON_RX_PACKET_SIZES3				0x43
-#define		RMON_RX_PACKET_SIZES4				0x44
-#define		RMON_RX_PACKET_SIZES5				0x45
-#define		RMON_RX_PACKET_SIZES6				0x46
-#define		RMON_RX_PACKET_SIZES7				0x47
-#define		RMON_FRAME_CHECK_SEQUENCE_ERRORS	0x48
-#define		RMON_ALIGNMENT_ERRORS				0x49
-#define		RMON_FRAGMENTS						0x4A
-#define		RMON_JABBERS						0x4B
-#define		RMON_FRAMES_LOST_TO_INTMACRCVERR	0x4C
-#define		RMON_UNICAST_FRAMES_RCVD_OK			0x4D
-#define		RMON_MULTICAST_FRAMES_RCVD_OK		0x4E
-#define		RMON_BROADCAST_FRAMES_RCVD_OK		0x4F
-#define		RMON_IN_RANGE_LENGTH_ERRORS			0x50
-#define		RMON_OUT_OF_RANGE_LENGTH_ERRORS		0x51
-#define		RMON_VLAN_FRAMES_RCVD				0x52
-#define		RMON_PAUSE_MAC_CTRL_FRAMES_RCVD		0x53
-#define		RMON_MAC_CTRL_FRAMES_RCVD			0x54
-#define		RMON_OCTETS_RCVD_OK					0x55
-#define		RMON_OCTETS_RCVD_OK_HI				0x56
-#define		RMON_OCTETS_RCVD_OTHER				0x57
-#define		RMON_OCTETS_RCVD_OTHER_HI			0x58
-
-#endif /* __ETHER00_H */
diff --git a/include/asm-arm/arch-epxa10db/excalibur.h b/include/asm-arm/arch-epxa10db/excalibur.h
deleted file mode 100644
index 5c91dd6..0000000
--- a/include/asm-arm/arch-epxa10db/excalibur.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* megafunction wizard: %ARM-Based Excalibur%
-   GENERATION: STANDARD
-   VERSION: WM1.0
-   MODULE: ARM-Based Excalibur
-   PROJECT: excalibur
-   ============================================================
-   File Name: v:\embedded\linux\bootldr\excalibur.h
-   Megafunction Name(s): ARM-Based Excalibur
-   ============================================================
-
-   ************************************************************
-   THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
-   ************************************************************/
-
-#ifndef	EXCALIBUR_H_INCLUDED
-#define	EXCALIBUR_H_INCLUDED
-
-#define EXC_DEFINE_PROCESSOR_LITTLE_ENDIAN
-#define EXC_DEFINE_BOOT_FROM_FLASH
-
-#define	EXC_INPUT_CLK_FREQUENCY (50000000)
-#define	EXC_AHB1_CLK_FREQUENCY (150000000)
-#define	EXC_AHB2_CLK_FREQUENCY (75000000)
-#define	EXC_SDRAM_CLK_FREQUENCY (75000000)
-
-/* Registers Block */
-#define	EXC_REGISTERS_BASE (0x7fffc000)
-#define	EXC_MODE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x000)
-#define	EXC_IO_CTRL00_BASE (EXC_REGISTERS_BASE + 0x040)
-#define	EXC_MMAP00_BASE (EXC_REGISTERS_BASE + 0x080)
-#define	EXC_PLD_CONFIG00_BASE (EXC_REGISTERS_BASE + 0x140)
-#define	EXC_TIMER00_BASE (EXC_REGISTERS_BASE + 0x200)
-#define	EXC_INT_CTRL00_BASE (EXC_REGISTERS_BASE + 0xc00)
-#define	EXC_CLOCK_CTRL00_BASE (EXC_REGISTERS_BASE + 0x300)
-#define	EXC_WATCHDOG00_BASE (EXC_REGISTERS_BASE + 0xa00)
-#define	EXC_UART00_BASE (EXC_REGISTERS_BASE + 0x280)
-#define	EXC_EBI00_BASE (EXC_REGISTERS_BASE + 0x380)
-#define	EXC_SDRAM00_BASE (EXC_REGISTERS_BASE + 0x400)
-#define	EXC_AHB12_BRIDGE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x800)
-#define	EXC_PLD_STRIPE_BRIDGE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x100)
-#define	EXC_STRIPE_PLD_BRIDGE_CTRL00_BASE (EXC_REGISTERS_BASE + 0x100)
-
-#define	EXC_REGISTERS_SIZE (0x00004000)
-
-/* EBI Block(s) */
-#define	EXC_EBI_BLOCK0_BASE (0x40000000)
-#define	EXC_EBI_BLOCK0_SIZE (0x00400000)
-#define	EXC_EBI_BLOCK0_WIDTH (8)
-#define	EXC_EBI_BLOCK0_NON_CACHEABLE
-#define	EXC_EBI_BLOCK1_BASE (0x40400000)
-#define	EXC_EBI_BLOCK1_SIZE (0x00400000)
-#define	EXC_EBI_BLOCK1_WIDTH (16)
-#define	EXC_EBI_BLOCK1_NON_CACHEABLE
-#define	EXC_EBI_BLOCK2_BASE (0x40800000)
-#define	EXC_EBI_BLOCK2_SIZE (0x00400000)
-#define	EXC_EBI_BLOCK2_WIDTH (16)
-#define	EXC_EBI_BLOCK2_NON_CACHEABLE
-#define	EXC_EBI_BLOCK3_BASE (0x40c00000)
-#define	EXC_EBI_BLOCK3_SIZE (0x00400000)
-#define	EXC_EBI_BLOCK3_WIDTH (16)
-#define	EXC_EBI_BLOCK3_NON_CACHEABLE
-
-/* SDRAM Block(s) */
-#define	EXC_SDRAM_BLOCK0_BASE (0x00000000)
-#define	EXC_SDRAM_BLOCK0_SIZE (0x04000000)
-#define	EXC_SDRAM_BLOCK0_WIDTH (32)
-#define	EXC_SDRAM_BLOCK1_BASE (0x04000000)
-#define	EXC_SDRAM_BLOCK1_SIZE (0x04000000)
-#define	EXC_SDRAM_BLOCK1_WIDTH (32)
-
-/* Single Port SRAM Block(s) */
-#define	EXC_SPSRAM_BLOCK0_BASE (0x08000000)
-#define	EXC_SPSRAM_BLOCK0_SIZE (0x00020000)
-#define	EXC_SPSRAM_BLOCK1_BASE (0x08020000)
-#define	EXC_SPSRAM_BLOCK1_SIZE (0x00020000)
-
-/* PLD Block(s) */
-#define	EXC_PLD_BLOCK0_BASE (0x80000000)
-#define	EXC_PLD_BLOCK0_SIZE (0x00004000)
-#define	EXC_PLD_BLOCK0_NON_CACHEABLE
-#define	EXC_PLD_BLOCK1_BASE (0xf000000)
-#define	EXC_PLD_BLOCK1_SIZE (0x00004000)
-#define	EXC_PLD_BLOCK1_NON_CACHEABLE
-#define	EXC_PLD_BLOCK2_BASE (0x80008000)
-#define	EXC_PLD_BLOCK2_SIZE (0x00004000)
-#define	EXC_PLD_BLOCK2_NON_CACHEABLE
-#define	EXC_PLD_BLOCK3_BASE (0x8000c000)
-#define	EXC_PLD_BLOCK3_SIZE (0x00004000)
-#define	EXC_PLD_BLOCK3_NON_CACHEABLE
-
-#endif
diff --git a/include/asm-arm/arch-epxa10db/hardware.h b/include/asm-arm/arch-epxa10db/hardware.h
deleted file mode 100644
index b992c29..0000000
--- a/include/asm-arm/arch-epxa10db/hardware.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-epxa10/hardware.h
- *
- *  This file contains the hardware definitions of the Integrator.
- *
- *  Copyright (C) 1999 ARM Limited.
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-#include <asm/arch/platform.h>
-
-/*
- * Where in virtual memory the IO devices (timers, system controllers
- * and so on)
- */
-#define IO_BASE			0xf0000000                 // VA of IO 
-#define IO_SIZE			0x10000000                 // How much?
-#define IO_START		EXC_REGISTERS_BASE              // PA of IO
-/* macro to get at IO space when running virtually */
-#define IO_ADDRESS(x) ((x) | 0xf0000000) 
-
-#define FLASH_VBASE             0xFE000000
-#define FLASH_SIZE              0x01000000
-#define FLASH_START             EXC_EBI_BLOCK0_BASE
-#define FLASH_VADDR(x) ((x)|0xFE000000)
-/*
- * Similar to above, but for PCI addresses (memory, IO, Config and the
- * V3 chip itself).  WARNING: this has to mirror definitions in platform.h
- */
-#if 0
-#define PCI_MEMORY_VADDR        0xe8000000
-#define PCI_CONFIG_VADDR        0xec000000
-#define PCI_V3_VADDR            0xed000000
-#define PCI_IO_VADDR            0xee000000
-
-#define PCIO_BASE		PCI_IO_VADDR
-#define PCIMEM_BASE		PCI_MEMORY_VADDR
-
-
-#define pcibios_assign_all_busses()	1
-
-#define PCIBIOS_MIN_IO		0x6000
-#define PCIBIOS_MIN_MEM 	0x00100000
-#endif
-
-
-#endif
-
diff --git a/include/asm-arm/arch-epxa10db/int_ctrl00.h b/include/asm-arm/arch-epxa10db/int_ctrl00.h
deleted file mode 100644
index 23ec864..0000000
--- a/include/asm-arm/arch-epxa10db/int_ctrl00.h
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- *  
- *  This file contains the register definitions for the Excalibur
- *  Timer TIMER00.
- *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef __INT_CTRL00_H
-#define __INT_CTRL00_H
-
-#define INT_MS(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x00 ))
-#define INT_MS_FC_MSK (0x10000)
-#define INT_MS_FC_OFST (16)
-#define INT_MS_M1_MSK (0x8000)
-#define INT_MS_M1_OFST (15)
-#define INT_MS_M0_MSK (0x4000)
-#define INT_MS_M0_OFST (14)
-#define INT_MS_AE_MSK (0x2000)
-#define INT_MS_AE_OFST (13)
-#define INT_MS_PE_MSK (0x1000)
-#define INT_MS_PE_OFST (12)
-#define INT_MS_EE_MSK (0x0800)
-#define INT_MS_EE_OFST (11)
-#define INT_MS_PS_MSK (0x0400)
-#define INT_MS_PS_OFST (10)
-#define INT_MS_T1_MSK (0x0200)
-#define INT_MS_T1_OFST (9)
-#define INT_MS_T0_MSK (0x0100)
-#define INT_MS_T0_OFST (8)
-#define INT_MS_UA_MSK (0x0080)
-#define INT_MS_UA_OFST (7)
-#define INT_MS_IP_MSK (0x0040)
-#define INT_MS_IP_OFST (6)
-#define INT_MS_P5_MSK (0x0020)
-#define INT_MS_P5_OFST (5)
-#define INT_MS_P4_MSK (0x0010)
-#define INT_MS_P4_OFST (4)
-#define INT_MS_P3_MSK (0x0008)
-#define INT_MS_P3_OFST (3)
-#define INT_MS_P2_MSK (0x0004)
-#define INT_MS_P2_OFST (2)
-#define INT_MS_P1_MSK (0x0002)
-#define INT_MS_P1_OFST (1)
-#define INT_MS_P0_MSK (0x0001)
-#define INT_MS_P0_OFST (0)
-
-#define INT_MC(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x04 ))
-#define INT_MC_FC_MSK (0x10000)
-#define INT_MC_FC_OFST (16)
-#define INT_MC_M1_MSK (0x8000)
-#define INT_MC_M1_OFST (15)
-#define INT_MC_M0_MSK (0x4000)
-#define INT_MC_M0_OFST (14)
-#define INT_MC_AE_MSK (0x2000)
-#define INT_MC_AE_OFST (13)
-#define INT_MC_PE_MSK (0x1000)
-#define INT_MC_PE_OFST (12)
-#define INT_MC_EE_MSK (0x0800)
-#define INT_MC_EE_OFST (11)
-#define INT_MC_PS_MSK (0x0400)
-#define INT_MC_PS_OFST (10)
-#define INT_MC_T1_MSK (0x0200)
-#define INT_MC_T1_OFST (9)
-#define INT_MC_T0_MSK (0x0100)
-#define INT_MC_T0_OFST (8)
-#define INT_MC_UA_MSK (0x0080)
-#define INT_MC_UA_OFST (7)
-#define INT_MC_IP_MSK (0x0040)
-#define INT_MC_IP_OFST (6)
-#define INT_MC_P5_MSK (0x0020)
-#define INT_MC_P5_OFST (5)
-#define INT_MC_P4_MSK (0x0010)
-#define INT_MC_P4_OFST (4)
-#define INT_MC_P3_MSK (0x0008)
-#define INT_MC_P3_OFST (3)
-#define INT_MC_P2_MSK (0x0004)
-#define INT_MC_P2_OFST (2)
-#define INT_MC_P1_MSK (0x0002)
-#define INT_MC_P1_OFST (1)
-#define INT_MC_P0_MSK (0x0001)
-#define INT_MC_P0_OFST (0)
-
-#define INT_SS(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x08 ))
-#define INT_SS_FC_SSK (0x8000)
-#define INT_SS_FC_OFST (15)
-#define INT_SS_M1_SSK (0x8000)
-#define INT_SS_M1_OFST (15)
-#define INT_SS_M0_SSK (0x4000)
-#define INT_SS_M0_OFST (14)
-#define INT_SS_AE_SSK (0x2000)
-#define INT_SS_AE_OFST (13)
-#define INT_SS_PE_SSK (0x1000)
-#define INT_SS_PE_OFST (12)
-#define INT_SS_EE_SSK (0x0800)
-#define INT_SS_EE_OFST (11)
-#define INT_SS_PS_SSK (0x0400)
-#define INT_SS_PS_OFST (10)
-#define INT_SS_T1_SSK (0x0200)
-#define INT_SS_T1_OFST (9)
-#define INT_SS_T0_SSK (0x0100)
-#define INT_SS_T0_OFST (8)
-#define INT_SS_UA_SSK (0x0080)
-#define INT_SS_UA_OFST (7)
-#define INT_SS_IP_SSK (0x0040)
-#define INT_SS_IP_OFST (6)
-#define INT_SS_P5_SSK (0x0020)
-#define INT_SS_P5_OFST (5)
-#define INT_SS_P4_SSK (0x0010)
-#define INT_SS_P4_OFST (4)
-#define INT_SS_P3_SSK (0x0008)
-#define INT_SS_P3_OFST (3)
-#define INT_SS_P2_SSK (0x0004)
-#define INT_SS_P2_OFST (2)
-#define INT_SS_P1_SSK (0x0002)
-#define INT_SS_P1_OFST (1)
-#define INT_SS_P0_SSK (0x0001)
-#define INT_SS_P0_OFST (0)
-
-#define INT_RS(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x0C ))
-#define INT_RS_FC_RSK (0x10000)
-#define INT_RS_FC_OFST (16)
-#define INT_RS_M1_RSK (0x8000)
-#define INT_RS_M1_OFST (15)
-#define INT_RS_M0_RSK (0x4000)
-#define INT_RS_M0_OFST (14)
-#define INT_RS_AE_RSK (0x2000)
-#define INT_RS_AE_OFST (13)
-#define INT_RS_PE_RSK (0x1000)
-#define INT_RS_PE_OFST (12)
-#define INT_RS_EE_RSK (0x0800)
-#define INT_RS_EE_OFST (11)
-#define INT_RS_PS_RSK (0x0400)
-#define INT_RS_PS_OFST (10)
-#define INT_RS_T1_RSK (0x0200)
-#define INT_RS_T1_OFST (9)
-#define INT_RS_T0_RSK (0x0100)
-#define INT_RS_T0_OFST (8)
-#define INT_RS_UA_RSK (0x0080)
-#define INT_RS_UA_OFST (7)
-#define INT_RS_IP_RSK (0x0040)
-#define INT_RS_IP_OFST (6)
-#define INT_RS_P5_RSK (0x0020)
-#define INT_RS_P5_OFST (5)
-#define INT_RS_P4_RSK (0x0010)
-#define INT_RS_P4_OFST (4)
-#define INT_RS_P3_RSK (0x0008)
-#define INT_RS_P3_OFST (3)
-#define INT_RS_P2_RSK (0x0004)
-#define INT_RS_P2_OFST (2)
-#define INT_RS_P1_RSK (0x0002)
-#define INT_RS_P1_OFST (1)
-#define INT_RS_P0_RSK (0x0001)
-#define INT_RS_P0_OFST (0)
-
-#define INT_ID(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x10 ))
-#define INT_ID_ID_MSK (0x3F)
-#define INT_ID_ID_OFST (0)
-
-#define INT_PLD_PRIORITY(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x14 ))
-#define INT_PLD_PRIORITY_PRI_MSK (0x3F)
-#define INT_PLD_PRIORITY_PRI_OFST (0)
-#define INT_PLD_PRIORITY_GA_MSK (0x40)
-#define INT_PLD_PRIORITY_GA_OFST (6)
-
-#define INT_MODE(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x18 ))
-#define INT_MODE_MODE_MSK (0x3)
-#define INT_MODE_MODE_OFST (0)
-
-#define INT_PRIORITY_P0(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x80 ))
-#define INT_PRIORITY_P0_PRI_MSK (0x3F)
-#define INT_PRIORITY_P0_PRI_OFST (0)
-#define INT_PRIORITY_P0_FQ_MSK (0x40)
-#define INT_PRIORITY_P0_FQ_OFST (6)
-
-#define INT_PRIORITY_P1(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x84 ))
-#define INT_PRIORITY_P1_PRI_MSK (0x3F)
-#define INT_PRIORITY_P1_PRI_OFST (0)
-#define INT_PRIORITY_P1_FQ_MSK (0x40)
-#define INT_PRIORITY_P1_FQ_OFST (6)
-
-#define INT_PRIORITY_P2(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x88 ))
-#define INT_PRIORITY_P2_PRI_MSK (0x3F)
-#define INT_PRIORITY_P2_PRI_OFST (0)
-#define INT_PRIORITY_P2_FQ_MSK (0x40)
-#define INT_PRIORITY_P2_FQ_OFST (6)
-
-#define INT_PRIORITY_P3(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x8C ))
-#define INT_PRIORITY_P3_PRI_MSK (0x3F)
-#define INT_PRIORITY_P3_PRI_OFST (0)
-#define INT_PRIORITY_P3_FQ_MSK (0x40)
-#define INT_PRIORITY_P3_FQ_OFST (6)
-
-#define INT_PRIORITY_P4(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x90 ))
-#define INT_PRIORITY_P4_PRI_MSK (0x3F)
-#define INT_PRIORITY_P4_PRI_OFST (0)
-#define INT_PRIORITY_P4_FQ_MSK (0x40)
-#define INT_PRIORITY_P4_FQ_OFST (6)
-
-#define INT_PRIORITY_P5(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x94 ))
-#define INT_PRIORITY_P5_PRI_MSK (0x3F)
-#define INT_PRIORITY_P5_PRI_OFST (0)
-#define INT_PRIORITY_P5_FQ_MSK (0x40)
-#define INT_PRIORITY_P5_FQ_OFST (6)
-
-#define INT_PRIORITY_IP(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x94 ))
-#define INT_PRIORITY_IP_PRI_MSK (0x3F)
-#define INT_PRIORITY_IP_PRI_OFST (0)
-#define INT_PRIORITY_IP_FQ_MSK (0x40)
-#define INT_PRIORITY_IP_FQ_OFST (6)
-
-#define INT_PRIORITY_UA(base_addr) (INT_CTRL00_TYPE (base_addr  + 0x9C ))
-#define INT_PRIORITY_UA_PRI_MSK (0x3F)
-#define INT_PRIORITY_UA_PRI_OFST (0)
-#define INT_PRIORITY_UA_FQ_MSK (0x40)
-#define INT_PRIORITY_UA_FQ_OFST (6)
-
-#define INT_PRIORITY_T0(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xA0 ))
-#define INT_PRIORITY_T0_PRI_MSK (0x3F)
-#define INT_PRIORITY_T0_PRI_OFST (0)
-#define INT_PRIORITY_T0_FQ_MSK (0x40)
-#define INT_PRIORITY_T0_FQ_OFST (6)
-
-#define INT_PRIORITY_T1(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xA4 ))
-#define INT_PRIORITY_T1_PRI_MSK (0x3F)
-#define INT_PRIORITY_T1_PRI_OFST (0)
-#define INT_PRIORITY_T1_FQ_MSK (0x40)
-#define INT_PRIORITY_T1_FQ_OFST (6)
-
-#define INT_PRIORITY_PS(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xA8 ))
-#define INT_PRIORITY_PS_PRI_MSK (0x3F)
-#define INT_PRIORITY_PS_PRI_OFST (0)
-#define INT_PRIORITY_PS_FQ_MSK (0x40)
-#define INT_PRIORITY_PS_FQ_OFST (6)
-
-#define INT_PRIORITY_EE(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xAC ))
-#define INT_PRIORITY_EE_PRI_MSK (0x3F)
-#define INT_PRIORITY_EE_PRI_OFST (0)
-#define INT_PRIORITY_EE_FQ_MSK (0x40)
-#define INT_PRIORITY_EE_FQ_OFST (6)
-
-#define INT_PRIORITY_PE(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xB0 ))
-#define INT_PRIORITY_PE_PRI_MSK (0x3F)
-#define INT_PRIORITY_PE_PRI_OFST (0)
-#define INT_PRIORITY_PE_FQ_MSK (0x40)
-#define INT_PRIORITY_PE_FQ_OFST (6)
-
-#define INT_PRIORITY_AE(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xB4 ))
-#define INT_PRIORITY_AE_PRI_MSK (0x3F)
-#define INT_PRIORITY_AE_PRI_OFST (0)
-#define INT_PRIORITY_AE_FQ_MSK (0x40)
-#define INT_PRIORITY_AE_FQ_OFST (6)
-
-#define INT_PRIORITY_M0(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xB8 ))
-#define INT_PRIORITY_M0_PRI_MSK (0x3F)
-#define INT_PRIORITY_M0_PRI_OFST (0)
-#define INT_PRIORITY_M0_FQ_MSK (0x40)
-#define INT_PRIORITY_M0_FQ_OFST (6)
-
-#define INT_PRIORITY_M1(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xBC ))
-#define INT_PRIORITY_M1_PRI_MSK (0x3F)
-#define INT_PRIORITY_M1_PRI_OFST (0)
-#define INT_PRIORITY_M1_FQ_MSK (0x40)
-#define INT_PRIORITY_M1_FQ_OFST (6)
-
-#define INT_PRIORITY_FC(base_addr) (INT_CTRL00_TYPE (base_addr  + 0xC0 ))
-#define INT_PRIORITY_FC_PRI_MSK (0x3F)
-#define INT_PRIORITY_FC_PRI_OFST (0)
-#define INT_PRIORITY_FC_FQ_MSK (0x40)
-#define INT_PRIORITY_FC_FQ_OFST (6)
-
-#endif /* __INT_CTRL00_H */
-
-
diff --git a/include/asm-arm/arch-epxa10db/io.h b/include/asm-arm/arch-epxa10db/io.h
deleted file mode 100644
index 9fe100c..0000000
--- a/include/asm-arm/arch-epxa10db/io.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-epxa10db/io.h
- *
- *  Copyright (C) 1999 ARM Limited
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
-
-#include <asm/hardware.h>
-
-#define IO_SPACE_LIMIT 0xffff
-
-
-/*
- * Generic virtual read/write
- */
-/*#define outsw   __arch_writesw
-#define outsl   __arch_writesl
-#define outsb   __arch_writesb
-#define insb    __arch_readsb
-#define insw    __arch_readsw
-#define insl    __arch_readsl*/
-
-#define __io(a)			((void __iomem *)(a))
-#define __mem_pci(a)            (a) 
-
-#endif
diff --git a/include/asm-arm/arch-epxa10db/irqs.h b/include/asm-arm/arch-epxa10db/irqs.h
deleted file mode 100644
index c3758a3..0000000
--- a/include/asm-arm/arch-epxa10db/irqs.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-camelot/irqs.h
- *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/* Use the Excalibur chip definitions */
-#define INT_CTRL00_TYPE
-#include "asm/arch/int_ctrl00.h"
-
-
-#define IRQ_PLD0                     INT_MS_P0_OFST
-#define IRQ_PLD1                     INT_MS_P1_OFST
-#define IRQ_PLD2                     INT_MS_P2_OFST
-#define IRQ_PLD3                     INT_MS_P3_OFST
-#define IRQ_PLD4                     INT_MS_P4_OFST
-#define IRQ_PLD5                     INT_MS_P5_OFST
-#define IRQ_EXT                      INT_MS_IP_OFST
-#define IRQ_UART                     INT_MS_UA_OFST
-#define IRQ_TIMER0                   INT_MS_T0_OFST
-#define IRQ_TIMER1                   INT_MS_T1_OFST
-#define IRQ_PLL                      INT_MS_PLL_OFST
-#define IRQ_EBI                      INT_MS_EBI_OFST
-#define IRQ_STRIPE_BRIDGE            INT_MS_PLL_OFST
-#define IRQ_AHB_BRIDGE               INT_MS_PLL_OFST
-#define IRQ_COMMRX                   INT_MS_CR_OFST
-#define IRQ_COMMTX                   INT_MS_CT_OFST
-#define IRQ_FAST_COMM                INT_MS_FC_OFST
-
-#define NR_IRQS                         (INT_MS_FC_OFST + 1)
-
diff --git a/include/asm-arm/arch-epxa10db/mode_ctrl00.h b/include/asm-arm/arch-epxa10db/mode_ctrl00.h
deleted file mode 100644
index d8a7efa..0000000
--- a/include/asm-arm/arch-epxa10db/mode_ctrl00.h
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef __MODE_CTRL00_H
-#define __MODE_CTRL00_H
-
-/*
- * Register definitions for the reset and mode control
- */
-
-/*
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-
-#define BOOT_CR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  ))
-#define BOOT_CR_BF_MSK (0x1)
-#define BOOT_CR_BF_OFST (0)
-#define BOOT_CR_HM_MSK (0x2)
-#define BOOT_CR_HM_OFST (1)
-#define BOOT_CR_RE_MSK (0x4)
-#define BOOT_CR_RE_OFST (2)
-
-#define RESET_SR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x4 ))
-#define RESET_SR_WR_MSK (0x1)
-#define RESET_SR_WR_OFST (0)
-#define RESET_SR_CR_MSK (0x2)
-#define RESET_SR_CR_OFST (1)
-#define RESET_SR_JT_MSK (0x4)
-#define RESET_SR_JT_OFST (2)
-#define RESET_SR_ER_MSK (0x8)
-#define RESET_SR_ER_OFST (3)
-
-#define ID_CODE(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x08 ))
-
-#define SRAM0_SR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x20 ))
-#define SRAM0_SR_SIZE_MSK (0xFFFFF000)
-#define SRAM0_SR_SIZE_OFST (12)
-
-#define SRAM1_SR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x24 ))
-#define SRAM1_SR_SIZE_MSK (0xFFFFF000)
-#define SRAM1_SR_SIZE_OFST (12)
-
-#define DPSRAM0_SR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x30 ))
-
-#define DPSRAM0_SR_MODE_MSK (0xF)
-#define DPSRAM0_SR_MODE_OFST (0)
-#define DPSRAM0_SR_GLBL_MSK (0x30)
-#define DPSRAM0_SR_SIZE_MSK (0xFFFFF000)
-#define DPSRAM0_SR_SIZE_OFST (12)
-
-#define DPSRAM0_LCR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x34 ))
-#define DPSRAM0_LCR_LCKADDR_MSK (0x1FFE0)
-#define DPSRAM0_LCR_LCKADDR_OFST (4)
-
-#define DPSRAM1_SR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x38 ))
-#define DPSRAM1_SR_MODE_MSK (0xF)
-#define DPSRAM1_SR_MODE_OFST (0)
-#define DPSRAM1_SR_GLBL_MSK (0x30)
-#define DPSRAM1_SR_GLBL_OFST (4)
-#define DPSRAM1_SR_SIZE_MSK (0xFFFFF000)
-#define DPSRAM1_SR_SIZE_OFST (12)
-
-#define DPSRAM1_LCR(BASE_ADDR) (MODE_CTRL00_TYPE (BASE_ADDR  + 0x3C ))
-#define DPSRAM1_LCR_LCKADDR_MSK (0x1FFE0)
-#define DPSRAM1_LCR_LCKADDR_OFST (4)
-
-#endif /* __MODE_CTRL00_H */
diff --git a/include/asm-arm/arch-epxa10db/platform.h b/include/asm-arm/arch-epxa10db/platform.h
deleted file mode 100644
index 129bb0f..0000000
--- a/include/asm-arm/arch-epxa10db/platform.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef PLATFORM_H
-#define PLATFORM_H
-#include "excalibur.h"
-
-#define MAXIRQNUM 15 
-#endif
-
diff --git a/include/asm-arm/arch-epxa10db/pld_conf00.h b/include/asm-arm/arch-epxa10db/pld_conf00.h
deleted file mode 100644
index 7af2c38..0000000
--- a/include/asm-arm/arch-epxa10db/pld_conf00.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef __PLD_CONF00_H
-#define __PLD_CONF00_H
-
-/*
- * Register definitions for the PLD Configuration Logic
- */
-
-/*
- *  
- *  This file contains the register definitions for the Excalibur
- *  Interrupt controller INT_CTRL00.
- *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
- 
-#define CONFIG_CONTROL(BASE_ADDR) (PLD_CONF00_TYPE (BASE_ADDR))  
-#define CONFIG_CONTROL_LK_MSK (0x1)
-#define CONFIG_CONTROL_LK_OFST (0)
-#define CONFIG_CONTROL_CO_MSK (0x2)
-#define CONFIG_CONTROL_CO_OFST (1)
-#define CONFIG_CONTROL_B_MSK  (0x4)
-#define CONFIG_CONTROL_B_OFST (2)
-#define CONFIG_CONTROL_PC_MSK (0x8)
-#define CONFIG_CONTROL_PC_OFST (3)
-#define CONFIG_CONTROL_E_MSK (0x10)
-#define CONFIG_CONTROL_E_OFST (4)
-#define CONFIG_CONTROL_ES_MSK (0xE0)
-#define CONFIG_CONTROL_ES_OFST (5)
-#define CONFIG_CONTROL_ES_0_MSK (0x20)
-#define CONFIG_CONTROL_ES_1_MSK (0x40)
-#define CONFIG_CONTROL_ES_2_MSK (0x80)
-
-#define CONFIG_CONTROL_CLOCK(BASE_ADDR) (PLD_CONF00_TYPE (BASE_ADDR  + 0x4 ))
-#define CONFIG_CONTROL_CLOCK_RATIO_MSK (0xFFFF)
-#define CONFIG_CONTROL_CLOCK_RATIO_OFST (0)
-
-#define CONFIG_CONTROL_DATA(BASE_ADDR) (PLD_CONF00_TYPE (BASE_ADDR  + 0x8 ))
-#define CONFIG_CONTROL_DATA_MSK (0xFFFFFFFF)
-#define CONFIG_CONTROL_DATA_OFST (0)
-
-#define CONFIG_UNLOCK(BASE_ADDR) (PLD_CONF00_TYPE (BASE_ADDR  + 0xC )) 
-#define CONFIG_UNLOCK_MSK (0xFFFFFFFF)
-#define CONFIG_UNLOCK_OFST (0)
-
-#define CONFIG_UNLOCK_MAGIC (0x554E4C4B)
-
-#endif /* __PLD_CONF00_H */
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/include/asm-arm/arch-epxa10db/system.h b/include/asm-arm/arch-epxa10db/system.h
deleted file mode 100644
index 345b092..0000000
--- a/include/asm-arm/arch-epxa10db/system.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-epxa10db/system.h
- *
- *  Copyright (C) 1999 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-#include <asm/arch/platform.h>
-
-static inline void arch_idle(void)
-{
-	/*
-	 * This should do all the clock switching
-	 * and wait for interrupt tricks
-	 */
-	cpu_do_idle();
-}
-
-extern __inline__ void arch_reset(char mode)
-{
-	/* Hmm... We can probably do something with the watchdog... */
-}
-
-#endif
diff --git a/include/asm-arm/arch-epxa10db/tdkphy.h b/include/asm-arm/arch-epxa10db/tdkphy.h
deleted file mode 100644
index 5e107bd..0000000
--- a/include/asm-arm/arch-epxa10db/tdkphy.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- *  linux/drivers/tdkphy.h
- *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef __TDKPHY_H
-#define __TDKPHY_H
-
-/*
- * Register definitions for the TDK 78Q2120 PHY 
- * which is on the Camelot board
- */
-
-/*
- * Copyright (c) Altera Corporation 2000.
- * All rights reserved.
- */
-#define PHY_CONTROL                                                                                     (0)
-#define PHY_CONTROL_COLT_MSK                                                            (0x80)
-#define PHY_CONTROL_COLT_OFST                                                           (7)
-#define PHY_CONTROL_DUPLEX_MSK                                                          (0x100)
-#define PHY_CONTROL_DUPLEX_OFST                                                         (8)
-#define PHY_CONTROL_RANEG_MSK                                                           (0x200)
-#define PHY_CONTROL_RANEG_OFST                                                          (9)
-#define PHY_CONTROL_ISO_MSK                                                                     (0x400)
-#define PHY_CONTROL_ISO_OFST                                                            (10)
-#define PHY_CONTROL_PWRDN_MSK                                                           (0x800)
-#define PHY_CONTROL_PWRDN_OFST                                                          (11)
-#define PHY_CONTROL_ANEGEN_MSK                                                          (0x1000)
-#define PHY_CONTROL_ANEGEN_OFST                                                         (12)
-#define PHY_CONTROL_SPEEDSL_MSK                                                         (0x2000)
-#define PHY_CONTROL_SPEEDSL_OFST                                                        (13)
-#define PHY_CONTROL_LOOPBK_MSK                                                          (0x4000)
-#define PHY_CONTROL_LOOPBK_OFST                                                         (14)
-#define PHY_CONTROL_RESET_MSK                                                           (0x8000)
-#define PHY_CONTROL_RESET_OFST                                                          (15)
-
-#define PHY_STATUS                                                                                      (1)
-#define PHY_STATUS_ETXD_MSK                                                                     (0x1)
-#define PHY_STATUS_EXTD_OFST                                                            (0)
-#define PHY_STATUS_JAB_MSK                                                                      (0x2)
-#define PHY_STATUS_JAB_OFST                                                                     (1)
-#define PHY_STATUS_LINK_MSK                                                                     (0x4)
-#define PHY_STATUS_LINK_OFST                                                            (2)
-#define PHY_STATUS_ANEGA_MSK                                                            (0x8)
-#define PHY_STATUS_ANEGA_OFST                                                           (3)
-#define PHY_STATUS_RFAULT_MSK                                                           (0x10)
-#define PHY_STATUS_RFAULT_OFST                                                          (4)
-#define PHY_STATUS_ANEGC_MSK                                                            (0x20)
-#define PHY_STATUS_ANEGC_OFST                                                           (5)
-#define PHY_STATUS_10T_H_MSK                                                            (0x800)
-#define PHY_STATUS_10T_H_OFST                                                           (11)
-#define PHY_STATUS_10T_F_MSK                                                            (0x1000)
-#define PHY_STATUS_10T_F_OFST                                                           (12)
-#define PHY_STATUS_100_X_H_MSK                                                          (0x2000)
-#define PHY_STATUS_100_X_H_OFST                                                         (13)
-#define PHY_STATUS_100_X_F_MSK                                                          (0x4000)
-#define PHY_STATUS_100_X_F_OFST                                                         (14)
-#define PHY_STATUS_100T4_MSK                                                            (0x8000)
-#define PHY_STATUS_100T4_OFST                                                           (15)
-
-#define PHY_ID1                                                                                         (2)
-#define PHY_ID1_OUI_MSK                                                                         (0xFFFF)
-#define PHY_ID1_OUI_OFST                                                                        (0)
-
-#define PHY_ID2                                                                                         (3)
-#define PHY_ID2_RN_MSK                                                                          (0xF)
-#define PHY_ID2_RN_OFST                                                                         (0)
-#define PHY_ID2_MN_MSK                                                                          (0x3F0)
-#define PHY_ID2_MN_OFST                                                                         (4)
-#define PHY_ID2_OUI_MSK                                                                         (0xFC00)
-#define PHY_ID2_OUI_OFST                                                                        (10)
-
-#define PHY_AUTO_NEG_ADVERTISEMENT                                                      (4)
-#define PHY_AUTO_NEG_ADVERTISEMENT_SELECTOR_MSK                         (0x1F)
-#define PHY_AUTO_NEG_ADVERTISEMENT_SELECTOR_OFST                        (0)
-#define PHY_AUTO_NEG_ADVERTISEMENT_A0_MSK                                       (0x20)
-#define PHY_AUTO_NEG_ADVERTISEMENT_A0_OFST                                      (5)
-#define PHY_AUTO_NEG_ADVERTISEMENT_A1_MSK                                       (0x40)
-#define PHY_AUTO_NEG_ADVERTISEMENT_A1_OFST                                      (6)
-#define PHY_AUTO_NEG_ADVERTISEMENT_A2_MSK                                       (0x80)
-#define PHY_AUTO_NEG_ADVERTISEMENT_A2_OFST                                      (7)
-#define PHY_AUTO_NEG_ADVERTISEMENT_A3_MSK                                       (0x100)
-#define PHY_AUTO_NEG_ADVERTISEMENT_A3_OFST                                      (8)
-#define PHY_AUTO_NEG_ADVERTISEMENT_A4_MSK                                       (0x200)
-#define PHY_AUTO_NEG_ADVERTISEMENT_A4_OFST                                      (9)
-#define PHY_AUTO_NEG_ADVERTISEMENT_TAF_MSK                                      (0x1FE0)
-#define PHY_AUTO_NEG_ADVERTISEMENT_TAF_OFST                                     (5)
-#define PHY_AUTO_NEG_ADVERTISEMENT_RF_MSK                                       (0x2000)
-#define PHY_AUTO_NEG_ADVERTISEMENT_RF_OFST                                      (13)
-#define PHY_AUTO_NEG_ADVERTISEMENT_RSVD_MSK                                     (0x4000)
-#define PHY_AUTO_NEG_ADVERTISEMENT_RVSD_OFST                            (14)
-#define PHY_AUTO_NEG_ADVERTISEMENT_NP_MSK                                       (0x8000)
-#define PHY_AUTO_NEG_ADVERTISEMENT_NP_OFST                                      (15)
-
-#define PHY_AUTO_NEG_LINK_PARTNER                                                       (5)
-#define PHY_AUTO_NEG_LINK_PARTNER_S4_MSK                                        (0x1F)
-#define PHY_AUTO_NEG_LINK_PARTNER_S4_OFST                                       (0)
-#define PHY_AUTO_NEG_LINK_PARTNER_A7_MSK                                        (0x1FE0)
-#define PHY_AUTO_NEG_LINK_PARTNER_A7_OFST                                       (5)
-#define PHY_AUTO_NEG_LINK_PARTNER_RF_MSK                                        (0x2000)
-#define PHY_AUTO_NEG_LINK_PARTNER_RF_OFST                                       (13)
-#define PHY_AUTO_NEG_LINK_PARTNER_ACK_MSK                                       (0x4000)
-#define PHY_AUTO_NEG_LINK_PARTNER_ACK_OFST                                      (14)
-#define PHY_AUTO_NEG_LINK_PARTNER_NP_MSK                                        (0x8000)
-#define PHY_AUTO_NEG_LINK_PARTNER_NP_OFST                                       (15)
-
-#define PHY_AUTO_NEG_EXPANSION                                                          (6)
-#define PHY_AUTO_NEG_EXPANSION_LPANEGA_MSK                                      (0x1)
-#define PHY_AUTO_NEG_EXPANSION_LPANEGA_OFST                                     (0)
-#define PHY_AUTO_NEG_EXPANSION_PRX_MSK                                          (0x2)
-#define PHY_AUTO_NEG_EXPANSION_PRX_OFST                                         (1)
-#define PHY_AUTO_NEG_EXPANSION_NPA_MSK                                          (0x4)
-#define PHY_AUTO_NEG_EXPANSION_NPA_OFST                                         (2)
-#define PHY_AUTO_NEG_EXPANSION_LPNPA_MSK                                        (0x8)
-#define PHY_AUTO_NEG_EXPANSION_LPNPA_OFST                                       (3)
-#define PHY_AUTO_NEG_EXPANSION_PDF_MSK                                          (0x10)
-#define PHY_AUTO_NEG_EXPANSION_PDF_OFST                                         (4)
-
-#define PHY_VENDOR_SPECIFIC                                                                     (16)
-#define PHY_VENDOR_SPECIFIC_RXCC_MSK                                            (0x1)
-#define PHY_VENDOR_SPECIFIC_RXCC_OFST                                           (0)
-#define PHY_VENDOR_SPECIFIC_PCSBP_MSK                                           (0x2)
-#define PHY_VENDOR_SPECIFIC_PCSBP_OFST                                          (1)
-#define PHY_VENDOR_SPECIFIC_RVSPOL_MSK                                          (0x10)
-#define PHY_VENDOR_SPECIFIC_RVSPOL_OFST                                         (4)
-#define PHY_VENDOR_SPECIFIC_APOL_MSK                                            (0x20)  
-#define PHY_VENDOR_SPECIFIC_APOL_OFST                                           (5)
-#define PHY_VENDOR_SPECIFIC_GPIO0_DIR_MSK                                       (0x40)
-#define PHY_VENDOR_SPECIFIC_GPIO0_DIR_OFST                                      (6)
-#define PHY_VENDOR_SPECIFIC_GPIO0_DAT_MSK                                       (0x80)
-#define PHY_VENDOR_SPECIFIC_GPIO0_DAT_OFST                                      (7)
-#define PHY_VENDOR_SPECIFIC_GPIO1_DIR_MSK                                       (0x100)
-#define PHY_VENDOR_SPECIFIC_GPIO1_DIR_OFST                                      (8)
-#define PHY_VENDOR_SPECIFIC_GPIO1_DAT_MSK                                       (0x200)
-#define PHY_VENDOR_SPECIFIC_GPIO1_DAT_OFST                                      (9)
-#define PHY_VENDOR_SPECIFIC_10BT_NATURAL_LOOPBACK_DAT_MSK       (0x400)
-#define PHY_VENDOR_SPECIFIC_10BT_NATURAL_LOOPBACK_DAT_OFST      (10)
-#define PHY_VENDOR_SPECIFIC_10BT_SQE_TEST_INHIBIT_MSK           (0x800)
-#define PHY_VENDOR_SPECIFIC_10BT_SQE_TEST_INHIBIT_OFST          (11)
-#define PHY_VENDOR_SPECIFIC_TXHIM_MSK                                           (0x1000)
-#define PHY_VENDOR_SPECIFIC_TXHIM_OFST                                          (12)
-#define PHY_VENDOR_SPECIFIC_INT_LEVEL_MSK                                       (0x4000)
-#define PHY_VENDOR_SPECIFIC_INT_LEVEL_OFST                                      (14)
-#define PHY_VENDOR_SPECIFIC_RPTR_MSK                                            (0x8000)
-#define PHY_VENDOR_SPECIFIC_RPTR_OFST                                           (15)
-
-#define PHY_IRQ_CONTROL                                                                         (17)
-#define PHY_IRQ_CONTROL_ANEG_COMP_INT_MSK                                       (0x1)
-#define PHY_IRQ_CONTROL_ANEG_COMP_INT_OFST                                      (0)
-#define PHY_IRQ_CONTROL_RFAULT_INT_MSK                                          (0x2)
-#define PHY_IRQ_CONTROL_RFAULT_INT_OFST                                         (1)
-#define PHY_IRQ_CONTROL_LS_CHG_INT_MSK                                          (0x4)
-#define PHY_IRQ_CONTROL_LS_CHG_INT_OFST                                         (2)
-#define PHY_IRQ_CONTROL_LP_ACK_INT_MSK                                          (0x8)
-#define PHY_IRQ_CONTROL_LP_ACK_INT_OFST                                         (3)
-#define PHY_IRQ_CONTROL_PDF_INT_MSK                                                     (0x10)
-#define PHY_IRQ_CONTROL_PDF_INT_OFST                                            (4)
-#define PHY_IRQ_CONTROL_PRX_INT_MSK                                                     (0x20)
-#define PHY_IRQ_CONTROL_PRX_INT_OFST                                            (5)
-#define PHY_IRQ_CONTROL_RXER_INT_MSK                                            (0x40)
-#define PHY_IRQ_CONTROL_RXER_INT_OFST                                           (6)
-#define PHY_IRQ_CONTROL_JABBER_INT_MSK                                          (0x80)
-#define PHY_IRQ_CONTROL_JABBER_INT_OFST                                         (7)
-#define PHY_IRQ_CONTROL_ANEG_COMP_IE_MSK                                        (0x100)
-#define PHY_IRQ_CONTROL_ANEG_COMP_IE_OFST                                       (8)
-#define PHY_IRQ_CONTROL_RFAULT_IE_MSK                                           (0x200)
-#define PHY_IRQ_CONTROL_RFAULT_IE_OFST                                          (9)
-#define PHY_IRQ_CONTROL_LS_CHG_IE_MSK                                           (0x400)
-#define PHY_IRQ_CONTROL_LS_CHG_IE_OFST                                          (10)
-#define PHY_IRQ_CONTROL_LP_ACK_IE_MSK                                           (0x800)
-#define PHY_IRQ_CONTROL_LP_ACK_IE_OFST                                          (11)
-#define PHY_IRQ_CONTROL_PDF_IE_MSK                                                      (0x1000)
-#define PHY_IRQ_CONTROL_PDF_IE_OFST                                                     (12)
-#define PHY_IRQ_CONTROL_PRX_IE_MSK                                                      (0x2000)
-#define PHY_IRQ_CONTROL_PRX_IE_OFST                                                     (13)
-#define PHY_IRQ_CONTROL_RXER_IE_MSK                                                     (0x4000)
-#define PHY_IRQ_CONTROL_RXER_IE_OFST                                            (14)
-#define PHY_IRQ_CONTROL_JABBER_IE_MSK                                           (0x8000)
-#define PHY_IRQ_CONTROL_JABBER_IE_OFST                                          (15)
-
-#define PHY_DIAGNOSTIC                                                                          (18)
-#define PHY_DIAGNOSTIC_RX_LOCK_MSK                                                      (0x100)
-#define PHY_DIAGNOSTIC_RX_LOCK_OFST                                                     (8)
-#define PHY_DIAGNOSTIC_RX_PASS_MSK                                                      (0x200)
-#define PHY_DIAGNOSTIC_RX_PASS_OFST                                                     (9)
-#define PHY_DIAGNOSTIC_RATE_MSK                                                         (0x400)
-#define PHY_DIAGNOSTIC_RATE_OFST                                                        (10)
-#define PHY_DIAGNOSTIC_DPLX_MSK                                                         (0x800)
-#define PHY_DIAGNOSTIC_DPLX_OFST                                                        (11)
-#define PHY_DIAGNOSTIC_ANEGF_MSK                                                        (0x1000)
-#define PHY_DIAGNOSTIC_ANEGF_OFST                                                       (12)
-
-#endif /* __TDKPHY_H */
diff --git a/include/asm-arm/arch-epxa10db/timer00.h b/include/asm-arm/arch-epxa10db/timer00.h
deleted file mode 100644
index 52a3fb5..0000000
--- a/include/asm-arm/arch-epxa10db/timer00.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- *  
- *  This file contains the register definitions for the Excalibur
- *  Timer TIMER00.
- *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __TIMER00_H
-#define __TIMER00_H
-
-/*
- * Register definitions for the timers
- */
-
-
-#define TIMER0_CR(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x00 ))
-#define TIMER0_CR_B_MSK (0x20)
-#define TIMER0_CR_B_OFST (0x5)
-#define TIMER0_CR_S_MSK  (0x10)
-#define TIMER0_CR_S_OFST (0x4)
-#define TIMER0_CR_CI_MSK (0x08)
-#define TIMER0_CR_CI_OFST (0x3)
-#define TIMER0_CR_IE_MSK (0x04)
-#define TIMER0_CR_IE_OFST (0x2)
-#define TIMER0_CR_MODE_MSK (0x3)
-#define TIMER0_CR_MODE_OFST (0)
-#define TIMER0_CR_MODE_FREE (0)
-#define TIMER0_CR_MODE_ONE  (1)
-#define TIMER0_CR_MODE_INTVL (2)
-
-#define TIMER0_SR(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x00 ))
-#define TIMER0_SR_B_MSK (0x20)
-#define TIMER0_SR_B_OFST (0x5)
-#define TIMER0_SR_S_MSK  (0x10)
-#define TIMER0_SR_S_OFST (0x4)
-#define TIMER0_SR_CI_MSK (0x08)
-#define TIMER0_SR_CI_OFST (0x3)
-#define TIMER0_SR_IE_MSK (0x04)
-#define TIMER0_SR_IE_OFST (0x2)
-#define TIMER0_SR_MODE_MSK (0x3)
-#define TIMER0_SR_MODE_OFST (0)
-#define TIMER0_SR_MODE_FREE (0)
-#define TIMER0_SR_MODE_ONE  (1)
-#define TIMER0_SR_MODE_INTVL (2)
-
-#define TIMER0_PRESCALE(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x010 ))
-#define TIMER0_LIMIT(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x020 ))
-#define TIMER0_READ(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x030 ))
-
-#define TIMER1_CR(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x40 ))
-#define TIMER1_CR_B_MSK (0x20)
-#define TIMER1_CR_B_OFST (0x5)
-#define TIMER1_CR_S_MSK  (0x10)
-#define TIMER1_CR_S_OFST (0x4)
-#define TIMER1_CR_CI_MSK (0x08)
-#define TIMER1_CR_CI_OFST (0x3)
-#define TIMER1_CR_IE_MSK (0x04)
-#define TIMER1_CR_IE_OFST (0x2)
-#define TIMER1_CR_MODE_MSK (0x3)
-#define TIMER1_CR_MODE_OFST (0)
-#define TIMER1_CR_MODE_FREE (0)
-#define TIMER1_CR_MODE_ONE  (1)
-#define TIMER1_CR_MODE_INTVL (2)
-
-#define TIMER1_SR(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x40 ))
-#define TIMER1_SR_B_MSK (0x20)
-#define TIMER1_SR_B_OFST (0x5)
-#define TIMER1_SR_S_MSK  (0x10)
-#define TIMER1_SR_S_OFST (0x4)
-#define TIMER1_SR_CI_MSK (0x08)
-#define TIMER1_SR_CI_OFST (0x3)
-#define TIMER1_SR_IE_MSK (0x04)
-#define TIMER1_SR_IE_OFST (0x2)
-#define TIMER1_SR_MODE_MSK (0x3)
-#define TIMER1_SR_MODE_OFST (0)
-#define TIMER1_SR_MODE_FREE (0)
-#define TIMER1_SR_MODE_ONE  (1)
-#define TIMER1_SR_MODE_INTVL (2)
-
-#define TIMER1_PRESCALE(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x050 ))
-#define TIMER1_LIMIT(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x060 ))
-#define TIMER1_READ(BASE_ADDR) (TIMER00_TYPE (BASE_ADDR  + 0x070 ))
-
-#endif /* __TIMER00_H */
diff --git a/include/asm-arm/arch-epxa10db/uart00.h b/include/asm-arm/arch-epxa10db/uart00.h
deleted file mode 100644
index 5abd891..0000000
--- a/include/asm-arm/arch-epxa10db/uart00.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/* *
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __UART00_H
-#define __UART00_H
-
-/*
- * Register definitions for the UART
- */
-
-#define UART_TX_FIFO_SIZE      (15)
-
-#define UART_RSR(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x00 ))
-#define UART_RSR_RX_LEVEL_MSK (0x1f)
-#define UART_RSR_RX_LEVEL_OFST (0)
-#define UART_RSR_RE_MSK (0x80)
-#define UART_RSR_RE_OFST (7)
-
-#define UART_RDS(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x04 ))
-#define UART_RDS_BI_MSK (0x8)
-#define UART_RDS_BI_OFST (4)
-#define UART_RDS_FE_MSK (0x4)
-#define UART_RDS_FE_OFST (2)
-#define UART_RDS_PE_MSK (0x2)
-#define UART_RDS_PE_OFST (1)
-#define UART_RDS_OE_MSK (0x1)
-#define UART_RDS_OE_OFST (0)
-
-#define UART_RD(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x08 ))
-#define UART_RD_RX_DATA_MSK (0xff)
-#define UART_RD_RX_DATA_OFST (0)
-
-#define UART_TSR(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x0c ))
-#define UART_TSR_TX_LEVEL_MSK (0x1f)
-#define UART_TSR_TX_LEVEL_OFST (0)
-#define UART_TSR_TXI_MSK (0x80)
-#define UART_TSR_TXI_OFST (7)
-
-#define UART_TD(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x10 ))
-#define UART_TD_TX_DATA_MSK (0xff)
-#define UART_TD_TX_DATA_OFST (0)
-
-#define UART_FCR(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x14 ))
-#define UART_FCR_RX_THR_MSK (0xd0)
-#define UART_FCR_RX_THR_OFST (5)
-#define UART_FCR_RX_THR_1 (0x00)
-#define UART_FCR_RX_THR_2 (0x20)
-#define UART_FCR_RX_THR_4 (0x40)
-#define UART_FCR_RX_THR_6 (0x60)
-#define UART_FCR_RX_THR_8 (0x80)
-#define UART_FCR_RX_THR_10 (0xa0)
-#define UART_FCR_RX_THR_12 (0xc0)
-#define UART_FCR_RX_THR_14 (0xd0)
-#define UART_FCR_TX_THR_MSK (0x1c)
-#define UART_FCR_TX_THR_OFST (2)
-#define UART_FCR_TX_THR_0 (0x00)
-#define UART_FCR_TX_THR_2 (0x04)
-#define UART_FCR_TX_THR_4 (0x08)
-#define UART_FCR_TX_THR_8 (0x0c)
-#define UART_FCR_TX_THR_10 (0x10)
-#define UART_FCR_TX_THR_12 (0x14)
-#define UART_FCR_TX_THR_14 (0x18)
-#define UART_FCR_TX_THR_15 (0x1c)
-#define UART_FCR_RC_MSK (0x02)
-#define UART_FCR_RC_OFST (1)
-#define UART_FCR_TC_MSK (0x01)
-#define UART_FCR_TC_OFST (0)
-
-#define UART_IES(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x18 ))
-#define UART_IES_ME_MSK (0x8)
-#define UART_IES_ME_OFST (3)
-#define UART_IES_TIE_MSK (0x4)
-#define UART_IES_TIE_OFST (2)
-#define UART_IES_TE_MSK (0x2)
-#define UART_IES_TE_OFST (1)
-#define UART_IES_RE_MSK (0x1)
-#define UART_IES_RE_OFST (0)
-
-#define UART_IEC(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x1c ))
-#define UART_IEC_ME_MSK (0x8)
-#define UART_IEC_ME_OFST (3)
-#define UART_IEC_TIE_MSK (0x4)
-#define UART_IEC_TIE_OFST (2)
-#define UART_IEC_TE_MSK (0x2)
-#define UART_IEC_TE_OFST (1)
-#define UART_IEC_RE_MSK (0x1)
-#define UART_IEC_RE_OFST (0)
-
-#define UART_ISR(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x20 ))
-#define UART_ISR_MI_MSK (0x8)
-#define UART_ISR_MI_OFST (3)
-#define UART_ISR_TII_MSK (0x4)
-#define UART_ISR_TII_OFST (2)
-#define UART_ISR_TI_MSK (0x2)
-#define UART_ISR_TI_OFST (1)
-#define UART_ISR_RI_MSK (0x1)
-#define UART_ISR_RI_OFST (0)
-
-#define UART_IID(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x24 ))
-#define UART_IID_IID_MSK (0x7)
-#define UART_IID_IID_OFST (0)
-
-#define UART_MC(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x28 ))
-#define UART_MC_OE_MSK (0x40)
-#define UART_MC_OE_OFST (6)
-#define UART_MC_SP_MSK (0x20)
-#define UART_MC_SP_OFST (5)
-#define UART_MC_EP_MSK (0x10)
-#define UART_MC_EP_OFST (4)
-#define UART_MC_PE_MSK (0x08)
-#define UART_MC_PE_OFST (3)
-#define UART_MC_ST_MSK (0x04)
-#define UART_MC_ST_ONE (0x0)
-#define UART_MC_ST_TWO (0x04)
-#define UART_MC_ST_OFST (2)
-#define UART_MC_CLS_MSK (0x03)
-#define UART_MC_CLS_OFST (0)
-#define UART_MC_CLS_CHARLEN_5 (0)
-#define UART_MC_CLS_CHARLEN_6 (1)
-#define UART_MC_CLS_CHARLEN_7 (2)
-#define UART_MC_CLS_CHARLEN_8 (3)
-
-#define UART_MCR(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x2c ))
-#define UART_MCR_AC_MSK (0x80)
-#define UART_MCR_AC_OFST (7)
-#define UART_MCR_AR_MSK (0x40)
-#define UART_MCR_AR_OFST (6)
-#define UART_MCR_BR_MSK (0x20)
-#define UART_MCR_BR_OFST (5)
-#define UART_MCR_LB_MSK (0x10)
-#define UART_MCR_LB_OFST (4)
-#define UART_MCR_DCD_MSK (0x08)
-#define UART_MCR_DCD_OFST (3)
-#define UART_MCR_RI_MSK (0x04)
-#define UART_MCR_RI_OFST (2)
-#define UART_MCR_DTR_MSK (0x02)
-#define UART_MCR_DTR_OFST (1)
-#define UART_MCR_RTS_MSK (0x01)
-#define UART_MCR_RTS_OFST (0)
-
-#define UART_MSR(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x30 ))
-#define UART_MSR_DCD_MSK (0x80)
-#define UART_MSR_DCD_OFST (7)
-#define UART_MSR_RI_MSK (0x40)
-#define UART_MSR_RI_OFST (6)
-#define UART_MSR_DSR_MSK (0x20)
-#define UART_MSR_DSR_OFST (5)
-#define UART_MSR_CTS_MSK (0x10)
-#define UART_MSR_CTS_OFST (4)
-#define UART_MSR_DDCD_MSK (0x08)
-#define UART_MSR_DDCD_OFST (3)
-#define UART_MSR_TERI_MSK (0x04)
-#define UART_MSR_TERI_OFST (2)
-#define UART_MSR_DDSR_MSK (0x02)
-#define UART_MSR_DDSR_OFST (1)
-#define UART_MSR_DCTS_MSK (0x01)
-#define UART_MSR_DCTS_OFST (0)
-
-#define UART_DIV_LO(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x34 ))
-#define UART_DIV_LO_DIV_MSK (0xff)
-#define UART_DIV_LO_DIV_OFST (0)
-
-#define UART_DIV_HI(BASE_ADDR) (UART00_TYPE (BASE_ADDR  + 0x38 ))
-#define UART_DIV_HI_DIV_MSK (0xff)
-#define UART_DIV_HI_DIV_OFST (0)
-
-#endif /* __UART00_H */
diff --git a/include/asm-arm/arch-epxa10db/uncompress.h b/include/asm-arm/arch-epxa10db/uncompress.h
deleted file mode 100644
index fdfe0e6..0000000
--- a/include/asm-arm/arch-epxa10db/uncompress.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  linux/include/asm-arm/arch-epxa10db/uncompress.h
- *
- *  Copyright (C) 1999 ARM Limited
- *  Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include "asm/arch/platform.h"
-#include "asm/hardware.h"
-#define UART00_TYPE (volatile unsigned int*)
-#include "asm/arch/uart00.h"
-
-/*
- * This does not append a newline
- */
-static void putstr(const char *s)
-{
-	while (*s) {
-		while ((*UART_TSR(EXC_UART00_BASE) &
-		       UART_TSR_TX_LEVEL_MSK)==15)
-			barrier();
-
-		*UART_TD(EXC_UART00_BASE) = *s;
-
-		if (*s == '\n') {
-			while ((*UART_TSR(EXC_UART00_BASE) &
-			       UART_TSR_TX_LEVEL_MSK)==15)
-				barrier();
-
-			*UART_TD(EXC_UART00_BASE) = '\r';
-		}
-		s++;
-	}
-}
-
-/*
- * nothing to do
- */
-#define arch_decomp_setup()
-
-#define arch_decomp_wdog()
diff --git a/include/asm-arm/atomic.h b/include/asm-arm/atomic.h
index f72b633..3d7283d 100644
--- a/include/asm-arm/atomic.h
+++ b/include/asm-arm/atomic.h
@@ -175,6 +175,8 @@
 
 #endif /* __LINUX_ARM_ARCH__ */
 
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
 static inline int atomic_add_unless(atomic_t *v, int a, int u)
 {
 	int c, old;
diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h
index 0cf4d4f..fd0147e 100644
--- a/include/asm-arm/io.h
+++ b/include/asm-arm/io.h
@@ -56,7 +56,12 @@
 
 /*
  * Architecture ioremap implementation.
+ *
+ * __ioremap takes CPU physical address.
+ *
+ * __ioremap_pfn takes a Page Frame Number and an offset into that page
  */
+extern void __iomem * __ioremap_pfn(unsigned long, unsigned long, size_t, unsigned long);
 extern void __iomem * __ioremap(unsigned long, size_t, unsigned long);
 extern void __iounmap(void __iomem *addr);
 
@@ -261,6 +266,7 @@
  *
  * ioremap takes a PCI memory address, as specified in
  * Documentation/IO-mapping.txt.
+ *
  */
 #ifndef __arch_ioremap
 #define ioremap(cookie,size)		__ioremap(cookie,size,0)
diff --git a/include/asm-arm/mach/map.h b/include/asm-arm/mach/map.h
index b338936..3351b77 100644
--- a/include/asm-arm/mach/map.h
+++ b/include/asm-arm/mach/map.h
@@ -27,9 +27,6 @@
 #define MT_ROM			6
 #define MT_IXP2000_DEVICE	7
 
-#define	__phys_to_pfn(paddr)	((paddr) >> PAGE_SHIFT)
-#define	__pfn_to_phys(pfn)	((pfn) << PAGE_SHIFT)
-
 extern void create_memmap_holes(struct meminfo *);
 extern void memtable_init(struct meminfo *);
 extern void iotable_init(struct map_desc *, int);
diff --git a/include/asm-arm/memory.h b/include/asm-arm/memory.h
index 3e57236..3d7f08b 100644
--- a/include/asm-arm/memory.h
+++ b/include/asm-arm/memory.h
@@ -58,6 +58,12 @@
 #endif
 
 /*
+ * Convert a physical address to a Page Frame Number and back
+ */
+#define	__phys_to_pfn(paddr)	((paddr) >> PAGE_SHIFT)
+#define	__pfn_to_phys(pfn)	((pfn) << PAGE_SHIFT)
+
+/*
  * The module space lives between the addresses given by TASK_SIZE
  * and PAGE_OFFSET - it must be within 32MB of the kernel text.
  */
diff --git a/include/asm-arm/mutex.h b/include/asm-arm/mutex.h
new file mode 100644
index 0000000..6caa59f
--- /dev/null
+++ b/include/asm-arm/mutex.h
@@ -0,0 +1,128 @@
+/*
+ * include/asm-arm/mutex.h
+ *
+ * ARM optimized mutex locking primitives
+ *
+ * Please look into asm-generic/mutex-xchg.h for a formal definition.
+ */
+#ifndef _ASM_MUTEX_H
+#define _ASM_MUTEX_H
+
+#if __LINUX_ARM_ARCH__ < 6
+/* On pre-ARMv6 hardware the swp based implementation is the most efficient. */
+# include <asm-generic/mutex-xchg.h>
+#else
+
+/*
+ * Attempting to lock a mutex on ARMv6+ can be done with a bastardized
+ * atomic decrement (it is not a reliable atomic decrement but it satisfies
+ * the defined semantics for our purpose, while being smaller and faster
+ * than a real atomic decrement or atomic swap.  The idea is to attempt
+ * decrementing the lock value only once.  If once decremented it isn't zero,
+ * or if its store-back fails due to a dispute on the exclusive store, we
+ * simply bail out immediately through the slow path where the lock will be
+ * reattempted until it succeeds.
+ */
+#define __mutex_fastpath_lock(count, fail_fn)				\
+do {									\
+	int __ex_flag, __res;						\
+									\
+	typecheck(atomic_t *, count);					\
+	typecheck_fn(fastcall void (*)(atomic_t *), fail_fn);		\
+									\
+	__asm__ (							\
+		"ldrex	%0, [%2]	\n"				\
+		"sub	%0, %0, #1	\n"				\
+		"strex	%1, %0, [%2]	\n"				\
+									\
+		: "=&r" (__res), "=&r" (__ex_flag)			\
+		: "r" (&(count)->counter)				\
+		: "cc","memory" );					\
+									\
+	if (unlikely(__res || __ex_flag))				\
+		fail_fn(count);						\
+} while (0)
+
+#define __mutex_fastpath_lock_retval(count, fail_fn)			\
+({									\
+	int __ex_flag, __res;						\
+									\
+	typecheck(atomic_t *, count);					\
+	typecheck_fn(fastcall int (*)(atomic_t *), fail_fn);		\
+									\
+	__asm__ (							\
+		"ldrex	%0, [%2]	\n"				\
+		"sub	%0, %0, #1	\n"				\
+		"strex	%1, %0, [%2]	\n"				\
+									\
+		: "=&r" (__res), "=&r" (__ex_flag)			\
+		: "r" (&(count)->counter)				\
+		: "cc","memory" );					\
+									\
+	__res |= __ex_flag;						\
+	if (unlikely(__res != 0))					\
+		__res = fail_fn(count);					\
+	__res;								\
+})
+
+/*
+ * Same trick is used for the unlock fast path. However the original value,
+ * rather than the result, is used to test for success in order to have
+ * better generated assembly.
+ */
+#define __mutex_fastpath_unlock(count, fail_fn)				\
+do {									\
+	int __ex_flag, __res, __orig;					\
+									\
+	typecheck(atomic_t *, count);					\
+	typecheck_fn(fastcall void (*)(atomic_t *), fail_fn);		\
+									\
+	__asm__ (							\
+		"ldrex	%0, [%3]	\n"				\
+		"add	%1, %0, #1	\n"				\
+		"strex	%2, %1, [%3]	\n"				\
+									\
+		: "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag)	\
+		: "r" (&(count)->counter)				\
+		: "cc","memory" );					\
+									\
+	if (unlikely(__orig || __ex_flag))				\
+		fail_fn(count);						\
+} while (0)
+
+/*
+ * If the unlock was done on a contended lock, or if the unlock simply fails
+ * then the mutex remains locked.
+ */
+#define __mutex_slowpath_needs_to_unlock()	1
+
+/*
+ * For __mutex_fastpath_trylock we use another construct which could be
+ * described as a "single value cmpxchg".
+ *
+ * This provides the needed trylock semantics like cmpxchg would, but it is
+ * lighter and less generic than a true cmpxchg implementation.
+ */
+static inline int
+__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
+{
+	int __ex_flag, __res, __orig;
+
+	__asm__ (
+
+		"1: ldrex	%0, [%3]	\n"
+		"subs		%1, %0, #1	\n"
+		"strexeq	%2, %1, [%3]	\n"
+		"movlt		%0, #0		\n"
+		"cmpeq		%2, #0		\n"
+		"bgt		1b		\n"
+
+		: "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag)
+		: "r" (&count->counter)
+		: "cc", "memory" );
+
+	return __orig;
+}
+
+#endif
+#endif
diff --git a/include/asm-arm26/atomic.h b/include/asm-arm26/atomic.h
index 3074b0e..1552c86 100644
--- a/include/asm-arm26/atomic.h
+++ b/include/asm-arm26/atomic.h
@@ -76,6 +76,8 @@
 	return ret;
 }
 
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
 static inline int atomic_add_unless(atomic_t *v, int a, int u)
 {
 	int ret;
diff --git a/include/asm-cris/atomic.h b/include/asm-cris/atomic.h
index 2df2c7a..0b51a87 100644
--- a/include/asm-cris/atomic.h
+++ b/include/asm-cris/atomic.h
@@ -136,6 +136,8 @@
 	return ret;
 }
 
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
 static inline int atomic_add_unless(atomic_t *v, int a, int u)
 {
 	int ret;
diff --git a/include/asm-cris/mutex.h b/include/asm-cris/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/include/asm-cris/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/include/asm-frv/atomic.h b/include/asm-frv/atomic.h
index 9c9e949..a59f684 100644
--- a/include/asm-frv/atomic.h
+++ b/include/asm-frv/atomic.h
@@ -328,6 +328,7 @@
 #endif
 
 #define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
 #define atomic_add_unless(v, a, u)				\
 ({								\
diff --git a/include/asm-frv/mutex.h b/include/asm-frv/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/include/asm-frv/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/include/asm-generic/mutex-dec.h b/include/asm-generic/mutex-dec.h
new file mode 100644
index 0000000..74b18cd
--- /dev/null
+++ b/include/asm-generic/mutex-dec.h
@@ -0,0 +1,110 @@
+/*
+ * asm-generic/mutex-dec.h
+ *
+ * Generic implementation of the mutex fastpath, based on atomic
+ * decrement/increment.
+ */
+#ifndef _ASM_GENERIC_MUTEX_DEC_H
+#define _ASM_GENERIC_MUTEX_DEC_H
+
+/**
+ *  __mutex_fastpath_lock - try to take the lock by moving the count
+ *                          from 1 to a 0 value
+ *  @count: pointer of type atomic_t
+ *  @fail_fn: function to call if the original value was not 1
+ *
+ * Change the count from 1 to a value lower than 1, and call <fail_fn> if
+ * it wasn't 1 originally. This function MUST leave the value lower than
+ * 1 even when the "1" assertion wasn't true.
+ */
+#define __mutex_fastpath_lock(count, fail_fn)				\
+do {									\
+	if (unlikely(atomic_dec_return(count) < 0))			\
+		fail_fn(count);						\
+	else								\
+		smp_mb();						\
+} while (0)
+
+/**
+ *  __mutex_fastpath_lock_retval - try to take the lock by moving the count
+ *                                 from 1 to a 0 value
+ *  @count: pointer of type atomic_t
+ *  @fail_fn: function to call if the original value was not 1
+ *
+ * Change the count from 1 to a value lower than 1, and call <fail_fn> if
+ * it wasn't 1 originally. This function returns 0 if the fastpath succeeds,
+ * or anything the slow path function returns.
+ */
+static inline int
+__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
+{
+	if (unlikely(atomic_dec_return(count) < 0))
+		return fail_fn(count);
+	else {
+		smp_mb();
+		return 0;
+	}
+}
+
+/**
+ *  __mutex_fastpath_unlock - try to promote the count from 0 to 1
+ *  @count: pointer of type atomic_t
+ *  @fail_fn: function to call if the original value was not 0
+ *
+ * Try to promote the count from 0 to 1. If it wasn't 0, call <fail_fn>.
+ * In the failure case, this function is allowed to either set the value to
+ * 1, or to set it to a value lower than 1.
+ *
+ * If the implementation sets it to a value of lower than 1, then the
+ * __mutex_slowpath_needs_to_unlock() macro needs to return 1, it needs
+ * to return 0 otherwise.
+ */
+#define __mutex_fastpath_unlock(count, fail_fn)				\
+do {									\
+	smp_mb();							\
+	if (unlikely(atomic_inc_return(count) <= 0))			\
+		fail_fn(count);						\
+} while (0)
+
+#define __mutex_slowpath_needs_to_unlock()		1
+
+/**
+ * __mutex_fastpath_trylock - try to acquire the mutex, without waiting
+ *
+ *  @count: pointer of type atomic_t
+ *  @fail_fn: fallback function
+ *
+ * Change the count from 1 to a value lower than 1, and return 0 (failure)
+ * if it wasn't 1 originally, or return 1 (success) otherwise. This function
+ * MUST leave the value lower than 1 even when the "1" assertion wasn't true.
+ * Additionally, if the value was < 0 originally, this function must not leave
+ * it to 0 on failure.
+ *
+ * If the architecture has no effective trylock variant, it should call the
+ * <fail_fn> spinlock-based trylock variant unconditionally.
+ */
+static inline int
+__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
+{
+	/*
+	 * We have two variants here. The cmpxchg based one is the best one
+	 * because it never induce a false contention state.  It is included
+	 * here because architectures using the inc/dec algorithms over the
+	 * xchg ones are much more likely to support cmpxchg natively.
+	 *
+	 * If not we fall back to the spinlock based variant - that is
+	 * just as efficient (and simpler) as a 'destructive' probing of
+	 * the mutex state would be.
+	 */
+#ifdef __HAVE_ARCH_CMPXCHG
+	if (likely(atomic_cmpxchg(count, 1, 0)) == 1) {
+		smp_mb();
+		return 1;
+	}
+	return 0;
+#else
+	return fail_fn(count);
+#endif
+}
+
+#endif
diff --git a/include/asm-generic/mutex-null.h b/include/asm-generic/mutex-null.h
new file mode 100644
index 0000000..5cf8b7c
--- /dev/null
+++ b/include/asm-generic/mutex-null.h
@@ -0,0 +1,24 @@
+/*
+ * asm-generic/mutex-null.h
+ *
+ * Generic implementation of the mutex fastpath, based on NOP :-)
+ *
+ * This is used by the mutex-debugging infrastructure, but it can also
+ * be used by architectures that (for whatever reason) want to use the
+ * spinlock based slowpath.
+ */
+#ifndef _ASM_GENERIC_MUTEX_NULL_H
+#define _ASM_GENERIC_MUTEX_NULL_H
+
+/* extra parameter only needed for mutex debugging: */
+#ifndef __IP__
+# define __IP__
+#endif
+
+#define __mutex_fastpath_lock(count, fail_fn)	      fail_fn(count __RET_IP__)
+#define __mutex_fastpath_lock_retval(count, fail_fn)  fail_fn(count __RET_IP__)
+#define __mutex_fastpath_unlock(count, fail_fn)       fail_fn(count __RET_IP__)
+#define __mutex_fastpath_trylock(count, fail_fn)      fail_fn(count)
+#define __mutex_slowpath_needs_to_unlock()	      1
+
+#endif
diff --git a/include/asm-generic/mutex-xchg.h b/include/asm-generic/mutex-xchg.h
new file mode 100644
index 0000000..1d24f47
--- /dev/null
+++ b/include/asm-generic/mutex-xchg.h
@@ -0,0 +1,117 @@
+/*
+ * asm-generic/mutex-xchg.h
+ *
+ * Generic implementation of the mutex fastpath, based on xchg().
+ *
+ * NOTE: An xchg based implementation is less optimal than an atomic
+ *       decrement/increment based implementation. If your architecture
+ *       has a reasonable atomic dec/inc then you should probably use
+ *	 asm-generic/mutex-dec.h instead, or you could open-code an
+ *	 optimized version in asm/mutex.h.
+ */
+#ifndef _ASM_GENERIC_MUTEX_XCHG_H
+#define _ASM_GENERIC_MUTEX_XCHG_H
+
+/**
+ *  __mutex_fastpath_lock - try to take the lock by moving the count
+ *                          from 1 to a 0 value
+ *  @count: pointer of type atomic_t
+ *  @fail_fn: function to call if the original value was not 1
+ *
+ * Change the count from 1 to a value lower than 1, and call <fail_fn> if it
+ * wasn't 1 originally. This function MUST leave the value lower than 1
+ * even when the "1" assertion wasn't true.
+ */
+#define __mutex_fastpath_lock(count, fail_fn)				\
+do {									\
+	if (unlikely(atomic_xchg(count, 0) != 1))			\
+		fail_fn(count);						\
+	else								\
+		smp_mb();						\
+} while (0)
+
+
+/**
+ *  __mutex_fastpath_lock_retval - try to take the lock by moving the count
+ *                                 from 1 to a 0 value
+ *  @count: pointer of type atomic_t
+ *  @fail_fn: function to call if the original value was not 1
+ *
+ * Change the count from 1 to a value lower than 1, and call <fail_fn> if it
+ * wasn't 1 originally. This function returns 0 if the fastpath succeeds,
+ * or anything the slow path function returns
+ */
+static inline int
+__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
+{
+	if (unlikely(atomic_xchg(count, 0) != 1))
+		return fail_fn(count);
+	else {
+		smp_mb();
+		return 0;
+	}
+}
+
+/**
+ *  __mutex_fastpath_unlock - try to promote the mutex from 0 to 1
+ *  @count: pointer of type atomic_t
+ *  @fail_fn: function to call if the original value was not 0
+ *
+ * try to promote the mutex from 0 to 1. if it wasn't 0, call <function>
+ * In the failure case, this function is allowed to either set the value to
+ * 1, or to set it to a value lower than one.
+ * If the implementation sets it to a value of lower than one, the
+ * __mutex_slowpath_needs_to_unlock() macro needs to return 1, it needs
+ * to return 0 otherwise.
+ */
+#define __mutex_fastpath_unlock(count, fail_fn)				\
+do {									\
+	smp_mb();							\
+	if (unlikely(atomic_xchg(count, 1) != 0))			\
+		fail_fn(count);						\
+} while (0)
+
+#define __mutex_slowpath_needs_to_unlock()		0
+
+/**
+ * __mutex_fastpath_trylock - try to acquire the mutex, without waiting
+ *
+ *  @count: pointer of type atomic_t
+ *  @fail_fn: spinlock based trylock implementation
+ *
+ * Change the count from 1 to a value lower than 1, and return 0 (failure)
+ * if it wasn't 1 originally, or return 1 (success) otherwise. This function
+ * MUST leave the value lower than 1 even when the "1" assertion wasn't true.
+ * Additionally, if the value was < 0 originally, this function must not leave
+ * it to 0 on failure.
+ *
+ * If the architecture has no effective trylock variant, it should call the
+ * <fail_fn> spinlock-based trylock variant unconditionally.
+ */
+static inline int
+__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
+{
+	int prev = atomic_xchg(count, 0);
+
+	if (unlikely(prev < 0)) {
+		/*
+		 * The lock was marked contended so we must restore that
+		 * state. If while doing so we get back a prev value of 1
+		 * then we just own it.
+		 *
+		 * [ In the rare case of the mutex going to 1, to 0, to -1
+		 *   and then back to 0 in this few-instructions window,
+		 *   this has the potential to trigger the slowpath for the
+		 *   owner's unlock path needlessly, but that's not a problem
+		 *   in practice. ]
+		 */
+		prev = atomic_xchg(count, prev);
+		if (prev < 0)
+			prev = 0;
+	}
+	smp_mb();
+
+	return prev;
+}
+
+#endif
diff --git a/include/asm-h8300/atomic.h b/include/asm-h8300/atomic.h
index d891541..21f5442 100644
--- a/include/asm-h8300/atomic.h
+++ b/include/asm-h8300/atomic.h
@@ -95,6 +95,8 @@
 	return ret;
 }
 
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
 static inline int atomic_add_unless(atomic_t *v, int a, int u)
 {
 	int ret;
diff --git a/include/asm-h8300/mutex.h b/include/asm-h8300/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/include/asm-h8300/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/include/asm-i386/atomic.h b/include/asm-i386/atomic.h
index 7a5472d..de649d3 100644
--- a/include/asm-i386/atomic.h
+++ b/include/asm-i386/atomic.h
@@ -216,6 +216,7 @@
 }
 
 #define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
 /**
  * atomic_add_unless - add unless the number is a given value
diff --git a/include/asm-i386/mutex.h b/include/asm-i386/mutex.h
new file mode 100644
index 0000000..4e5e3de
--- /dev/null
+++ b/include/asm-i386/mutex.h
@@ -0,0 +1,124 @@
+/*
+ * Assembly implementation of the mutex fastpath, based on atomic
+ * decrement/increment.
+ *
+ * started by Ingo Molnar:
+ *
+ *  Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ */
+#ifndef _ASM_MUTEX_H
+#define _ASM_MUTEX_H
+
+/**
+ *  __mutex_fastpath_lock - try to take the lock by moving the count
+ *                          from 1 to a 0 value
+ *  @count: pointer of type atomic_t
+ *  @fn: function to call if the original value was not 1
+ *
+ * Change the count from 1 to a value lower than 1, and call <fn> if it
+ * wasn't 1 originally. This function MUST leave the value lower than 1
+ * even when the "1" assertion wasn't true.
+ */
+#define __mutex_fastpath_lock(count, fail_fn)				\
+do {									\
+	unsigned int dummy;						\
+									\
+	typecheck(atomic_t *, count);					\
+	typecheck_fn(fastcall void (*)(atomic_t *), fail_fn);		\
+									\
+	__asm__ __volatile__(						\
+		LOCK	"   decl (%%eax)	\n"			\
+			"   js "#fail_fn"	\n"			\
+									\
+		:"=a" (dummy)						\
+		: "a" (count)						\
+		: "memory", "ecx", "edx");				\
+} while (0)
+
+
+/**
+ *  __mutex_fastpath_lock_retval - try to take the lock by moving the count
+ *                                 from 1 to a 0 value
+ *  @count: pointer of type atomic_t
+ *  @fail_fn: function to call if the original value was not 1
+ *
+ * Change the count from 1 to a value lower than 1, and call <fail_fn> if it
+ * wasn't 1 originally. This function returns 0 if the fastpath succeeds,
+ * or anything the slow path function returns
+ */
+static inline int
+__mutex_fastpath_lock_retval(atomic_t *count,
+			     int fastcall (*fail_fn)(atomic_t *))
+{
+	if (unlikely(atomic_dec_return(count) < 0))
+		return fail_fn(count);
+	else
+		return 0;
+}
+
+/**
+ *  __mutex_fastpath_unlock - try to promote the mutex from 0 to 1
+ *  @count: pointer of type atomic_t
+ *  @fail_fn: function to call if the original value was not 0
+ *
+ * try to promote the mutex from 0 to 1. if it wasn't 0, call <fail_fn>.
+ * In the failure case, this function is allowed to either set the value
+ * to 1, or to set it to a value lower than 1.
+ *
+ * If the implementation sets it to a value of lower than 1, the
+ * __mutex_slowpath_needs_to_unlock() macro needs to return 1, it needs
+ * to return 0 otherwise.
+ */
+#define __mutex_fastpath_unlock(count, fail_fn)				\
+do {									\
+	unsigned int dummy;						\
+									\
+	typecheck(atomic_t *, count);					\
+	typecheck_fn(fastcall void (*)(atomic_t *), fail_fn);		\
+									\
+	__asm__ __volatile__(						\
+		LOCK	"   incl (%%eax)	\n"			\
+			"   jle "#fail_fn"	\n"			\
+									\
+		:"=a" (dummy)						\
+		: "a" (count)						\
+		: "memory", "ecx", "edx");				\
+} while (0)
+
+#define __mutex_slowpath_needs_to_unlock()	1
+
+/**
+ * __mutex_fastpath_trylock - try to acquire the mutex, without waiting
+ *
+ *  @count: pointer of type atomic_t
+ *  @fail_fn: fallback function
+ *
+ * Change the count from 1 to a value lower than 1, and return 0 (failure)
+ * if it wasn't 1 originally, or return 1 (success) otherwise. This function
+ * MUST leave the value lower than 1 even when the "1" assertion wasn't true.
+ * Additionally, if the value was < 0 originally, this function must not leave
+ * it to 0 on failure.
+ */
+static inline int
+__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
+{
+	/*
+	 * We have two variants here. The cmpxchg based one is the best one
+	 * because it never induce a false contention state.  It is included
+	 * here because architectures using the inc/dec algorithms over the
+	 * xchg ones are much more likely to support cmpxchg natively.
+	 *
+	 * If not we fall back to the spinlock based variant - that is
+	 * just as efficient (and simpler) as a 'destructive' probing of
+	 * the mutex state would be.
+	 */
+#ifdef __HAVE_ARCH_CMPXCHG
+	if (likely(atomic_cmpxchg(count, 1, 0)) == 1)
+		return 1;
+	return 0;
+#else
+	return fail_fn(count);
+#endif
+}
+
+#endif
diff --git a/include/asm-ia64/atomic.h b/include/asm-ia64/atomic.h
index 15cf798..d3e0dfa 100644
--- a/include/asm-ia64/atomic.h
+++ b/include/asm-ia64/atomic.h
@@ -89,6 +89,7 @@
 }
 
 #define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
 #define atomic_add_unless(v, a, u)				\
 ({								\
diff --git a/include/asm-ia64/mutex.h b/include/asm-ia64/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/include/asm-ia64/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/include/asm-m32r/atomic.h b/include/asm-m32r/atomic.h
index 7076127..3122fe1 100644
--- a/include/asm-m32r/atomic.h
+++ b/include/asm-m32r/atomic.h
@@ -243,6 +243,7 @@
 #define atomic_add_negative(i,v) (atomic_add_return((i), (v)) < 0)
 
 #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
 /**
  * atomic_add_unless - add unless the number is a given value
diff --git a/include/asm-m32r/mutex.h b/include/asm-m32r/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/include/asm-m32r/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/include/asm-m68k/atomic.h b/include/asm-m68k/atomic.h
index b8a4e75..a4a84d5 100644
--- a/include/asm-m68k/atomic.h
+++ b/include/asm-m68k/atomic.h
@@ -140,6 +140,7 @@
 }
 
 #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
 #define atomic_add_unless(v, a, u)				\
 ({								\
diff --git a/include/asm-m68k/mutex.h b/include/asm-m68k/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/include/asm-m68k/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/include/asm-m68knommu/atomic.h b/include/asm-m68knommu/atomic.h
index 1702dbe..6c4e4b6 100644
--- a/include/asm-m68knommu/atomic.h
+++ b/include/asm-m68knommu/atomic.h
@@ -129,6 +129,7 @@
 }
 
 #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
 #define atomic_add_unless(v, a, u)				\
 ({								\
diff --git a/include/asm-m68knommu/mutex.h b/include/asm-m68knommu/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/include/asm-m68knommu/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h
index 92256e4..94a9587 100644
--- a/include/asm-mips/atomic.h
+++ b/include/asm-mips/atomic.h
@@ -289,6 +289,7 @@
 }
 
 #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
 /**
  * atomic_add_unless - add unless the number is a given value
diff --git a/include/asm-mips/mutex.h b/include/asm-mips/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/include/asm-mips/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/include/asm-parisc/atomic.h b/include/asm-parisc/atomic.h
index 64ebd08..2ca56d3 100644
--- a/include/asm-parisc/atomic.h
+++ b/include/asm-parisc/atomic.h
@@ -165,6 +165,7 @@
 
 /* exported interface */
 #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
 /**
  * atomic_add_unless - add unless the number is a given value
diff --git a/include/asm-parisc/mutex.h b/include/asm-parisc/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/include/asm-parisc/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/include/asm-powerpc/atomic.h b/include/asm-powerpc/atomic.h
index ae395a0..248f9ae 100644
--- a/include/asm-powerpc/atomic.h
+++ b/include/asm-powerpc/atomic.h
@@ -165,6 +165,7 @@
 }
 
 #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
 /**
  * atomic_add_unless - add unless the number is a given value
diff --git a/include/asm-powerpc/mutex.h b/include/asm-powerpc/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/include/asm-powerpc/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/include/asm-powerpc/smu.h b/include/asm-powerpc/smu.h
index 134c2b5..82ce476 100644
--- a/include/asm-powerpc/smu.h
+++ b/include/asm-powerpc/smu.h
@@ -22,7 +22,7 @@
 /*
  * Partition info commands
  *
- * These commands are used to retreive the sdb-partition-XX datas from
+ * These commands are used to retrieve the sdb-partition-XX datas from
  * the SMU. The lenght is always 2. First byte is the subcommand code
  * and second byte is the partition ID.
  *
@@ -225,7 +225,7 @@
  *
  * SMU_CMD_MISC_ee_GET_DATABLOCK_REC is used, among others, to
  * transfer blocks of data from the SMU. So far, I've decrypted it's
- * usage to retreive partition data. In order to do that, you have to
+ * usage to retrieve partition data. In order to do that, you have to
  * break your transfer in "chunks" since that command cannot transfer
  * more than a chunk at a time. The chunk size used by OF is 0xe bytes,
  * but it seems that the darwin driver will let you do 0x1e bytes if
@@ -556,7 +556,7 @@
 	__u32		cmdtype;
 #define SMU_CMDTYPE_SMU			0	/* SMU command */
 #define SMU_CMDTYPE_WANTS_EVENTS	1	/* switch fd to events mode */
-#define SMU_CMDTYPE_GET_PARTITION	2	/* retreive an sdb partition */
+#define SMU_CMDTYPE_GET_PARTITION	2	/* retrieve an sdb partition */
 
 	__u8		cmd;			/* SMU command byte */
 	__u8		pad[3];			/* padding */
diff --git a/include/asm-s390/atomic.h b/include/asm-s390/atomic.h
index d82aedf..be6fefe 100644
--- a/include/asm-s390/atomic.h
+++ b/include/asm-s390/atomic.h
@@ -75,6 +75,8 @@
 	       __CS_LOOP(v, mask, "or");
 }
 
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
 static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new)
 {
 	__asm__ __volatile__("  cs   %0,%3,0(%2)\n"
diff --git a/include/asm-s390/mutex.h b/include/asm-s390/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/include/asm-s390/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/include/asm-sh/atomic.h b/include/asm-sh/atomic.h
index 618d8e0..fb627de 100644
--- a/include/asm-sh/atomic.h
+++ b/include/asm-sh/atomic.h
@@ -101,6 +101,8 @@
 	return ret;
 }
 
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
 static inline int atomic_add_unless(atomic_t *v, int a, int u)
 {
 	int ret;
diff --git a/include/asm-sh/mutex.h b/include/asm-sh/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/include/asm-sh/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/include/asm-sh64/atomic.h b/include/asm-sh64/atomic.h
index f3ce5c0..28f2ea9 100644
--- a/include/asm-sh64/atomic.h
+++ b/include/asm-sh64/atomic.h
@@ -113,6 +113,8 @@
 	return ret;
 }
 
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
 static inline int atomic_add_unless(atomic_t *v, int a, int u)
 {
 	int ret;
diff --git a/include/asm-sh64/mutex.h b/include/asm-sh64/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/include/asm-sh64/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/include/asm-sparc/atomic.h b/include/asm-sparc/atomic.h
index accb496..e103317 100644
--- a/include/asm-sparc/atomic.h
+++ b/include/asm-sparc/atomic.h
@@ -20,6 +20,7 @@
 
 extern int __atomic_add_return(int, atomic_t *);
 extern int atomic_cmpxchg(atomic_t *, int, int);
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 extern int atomic_add_unless(atomic_t *, int, int);
 extern void atomic_set(atomic_t *, int);
 
diff --git a/include/asm-sparc/mutex.h b/include/asm-sparc/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/include/asm-sparc/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/include/asm-sparc64/atomic.h b/include/asm-sparc64/atomic.h
index 11f5aa5..25256bd 100644
--- a/include/asm-sparc64/atomic.h
+++ b/include/asm-sparc64/atomic.h
@@ -72,6 +72,7 @@
 #define atomic64_add_negative(i, v) (atomic64_add_ret(i, v) < 0)
 
 #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
 #define atomic_add_unless(v, a, u)				\
 ({								\
diff --git a/include/asm-sparc64/mutex.h b/include/asm-sparc64/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/include/asm-sparc64/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/include/asm-um/mutex.h b/include/asm-um/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/include/asm-um/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/include/asm-v850/atomic.h b/include/asm-v850/atomic.h
index f5b9ab6..166df00 100644
--- a/include/asm-v850/atomic.h
+++ b/include/asm-v850/atomic.h
@@ -104,6 +104,8 @@
 	return ret;
 }
 
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
 static inline int atomic_add_unless(atomic_t *v, int a, int u)
 {
 	int ret;
diff --git a/include/asm-v850/mutex.h b/include/asm-v850/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/include/asm-v850/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/include/asm-x86_64/atomic.h b/include/asm-x86_64/atomic.h
index 72eb071..6b54023 100644
--- a/include/asm-x86_64/atomic.h
+++ b/include/asm-x86_64/atomic.h
@@ -389,6 +389,7 @@
 #define atomic64_dec_return(v)  (atomic64_sub_return(1,v))
 
 #define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
 /**
  * atomic_add_unless - add unless the number is a given value
diff --git a/include/asm-x86_64/mutex.h b/include/asm-x86_64/mutex.h
new file mode 100644
index 0000000..818abfd
--- /dev/null
+++ b/include/asm-x86_64/mutex.h
@@ -0,0 +1,113 @@
+/*
+ * Assembly implementation of the mutex fastpath, based on atomic
+ * decrement/increment.
+ *
+ * started by Ingo Molnar:
+ *
+ *  Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ */
+#ifndef _ASM_MUTEX_H
+#define _ASM_MUTEX_H
+
+/**
+ * __mutex_fastpath_lock - decrement and call function if negative
+ * @v: pointer of type atomic_t
+ * @fail_fn: function to call if the result is negative
+ *
+ * Atomically decrements @v and calls <fail_fn> if the result is negative.
+ */
+#define __mutex_fastpath_lock(v, fail_fn)				\
+do {									\
+	unsigned long dummy;						\
+									\
+	typecheck(atomic_t *, v);					\
+	typecheck_fn(fastcall void (*)(atomic_t *), fail_fn);		\
+									\
+	__asm__ __volatile__(						\
+		LOCK	"   decl (%%rdi)	\n"			\
+			"   js 2f		\n"			\
+			"1:			\n"			\
+									\
+		LOCK_SECTION_START("")					\
+			"2: call "#fail_fn"	\n"			\
+			"   jmp 1b		\n"			\
+		LOCK_SECTION_END					\
+									\
+		:"=D" (dummy)						\
+		: "D" (v)						\
+		: "rax", "rsi", "rdx", "rcx",				\
+		  "r8", "r9", "r10", "r11", "memory");			\
+} while (0)
+
+/**
+ *  __mutex_fastpath_lock_retval - try to take the lock by moving the count
+ *                                 from 1 to a 0 value
+ *  @count: pointer of type atomic_t
+ *  @fail_fn: function to call if the original value was not 1
+ *
+ * Change the count from 1 to a value lower than 1, and call <fail_fn> if
+ * it wasn't 1 originally. This function returns 0 if the fastpath succeeds,
+ * or anything the slow path function returns
+ */
+static inline int
+__mutex_fastpath_lock_retval(atomic_t *count,
+			     int fastcall (*fail_fn)(atomic_t *))
+{
+	if (unlikely(atomic_dec_return(count) < 0))
+		return fail_fn(count);
+	else
+		return 0;
+}
+
+/**
+ * __mutex_fastpath_unlock - increment and call function if nonpositive
+ * @v: pointer of type atomic_t
+ * @fail_fn: function to call if the result is nonpositive
+ *
+ * Atomically increments @v and calls <fail_fn> if the result is nonpositive.
+ */
+#define __mutex_fastpath_unlock(v, fail_fn)				\
+do {									\
+	unsigned long dummy;						\
+									\
+	typecheck(atomic_t *, v);					\
+	typecheck_fn(fastcall void (*)(atomic_t *), fail_fn);		\
+									\
+	__asm__ __volatile__(						\
+		LOCK	"   incl (%%rdi)	\n"			\
+			"   jle 2f		\n"			\
+			"1:			\n"			\
+									\
+		LOCK_SECTION_START("")					\
+			"2: call "#fail_fn"	\n"			\
+			"   jmp 1b		\n"			\
+		LOCK_SECTION_END					\
+									\
+		:"=D" (dummy)						\
+		: "D" (v)						\
+		: "rax", "rsi", "rdx", "rcx",				\
+		  "r8", "r9", "r10", "r11", "memory");			\
+} while (0)
+
+#define __mutex_slowpath_needs_to_unlock()	1
+
+/**
+ * __mutex_fastpath_trylock - try to acquire the mutex, without waiting
+ *
+ *  @count: pointer of type atomic_t
+ *  @fail_fn: fallback function
+ *
+ * Change the count from 1 to 0 and return 1 (success), or return 0 (failure)
+ * if it wasn't 1 originally. [the fallback function is never used on
+ * x86_64, because all x86_64 CPUs have a CMPXCHG instruction.]
+ */
+static inline int
+__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
+{
+	if (likely(atomic_cmpxchg(count, 1, 0)) == 1)
+		return 1;
+	else
+		return 0;
+}
+
+#endif
diff --git a/include/asm-xtensa/atomic.h b/include/asm-xtensa/atomic.h
index e2ce06b..fe105a1 100644
--- a/include/asm-xtensa/atomic.h
+++ b/include/asm-xtensa/atomic.h
@@ -224,6 +224,7 @@
 #define atomic_add_negative(i,v) (atomic_add_return((i),(v)) < 0)
 
 #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
 /**
  * atomic_add_unless - add unless the number is a given value
diff --git a/include/asm-xtensa/mutex.h b/include/asm-xtensa/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/include/asm-xtensa/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h
index 119f9d0..3398789 100644
--- a/include/linux/compat_ioctl.h
+++ b/include/linux/compat_ioctl.h
@@ -218,32 +218,6 @@
 COMPATIBLE_IOCTL(VT_RESIZEX)
 COMPATIBLE_IOCTL(VT_LOCKSWITCH)
 COMPATIBLE_IOCTL(VT_UNLOCKSWITCH)
-/* Little v */
-/* Little v, the video4linux ioctls (conflict?) */
-COMPATIBLE_IOCTL(VIDIOCGCAP)
-COMPATIBLE_IOCTL(VIDIOCGCHAN)
-COMPATIBLE_IOCTL(VIDIOCSCHAN)
-COMPATIBLE_IOCTL(VIDIOCGPICT)
-COMPATIBLE_IOCTL(VIDIOCSPICT)
-COMPATIBLE_IOCTL(VIDIOCCAPTURE)
-COMPATIBLE_IOCTL(VIDIOCKEY)
-COMPATIBLE_IOCTL(VIDIOCGAUDIO)
-COMPATIBLE_IOCTL(VIDIOCSAUDIO)
-COMPATIBLE_IOCTL(VIDIOCSYNC)
-COMPATIBLE_IOCTL(VIDIOCMCAPTURE)
-COMPATIBLE_IOCTL(VIDIOCGMBUF)
-COMPATIBLE_IOCTL(VIDIOCGUNIT)
-COMPATIBLE_IOCTL(VIDIOCGCAPTURE)
-COMPATIBLE_IOCTL(VIDIOCSCAPTURE)
-/* BTTV specific... */
-COMPATIBLE_IOCTL(_IOW('v',  BASE_VIDIOCPRIVATE+0, char [256]))
-COMPATIBLE_IOCTL(_IOR('v',  BASE_VIDIOCPRIVATE+1, char [256]))
-COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int))
-COMPATIBLE_IOCTL(_IOW('v' , BASE_VIDIOCPRIVATE+3, char [16])) /* struct bttv_pll_info */
-COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+4, int))
-COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+5, int))
-COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+6, int))
-COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+7, int))
 /* Little p (/dev/rtc, /dev/envctrl, etc.) */
 COMPATIBLE_IOCTL(RTC_AIE_ON)
 COMPATIBLE_IOCTL(RTC_AIE_OFF)
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 3c89df6..d88bf8a 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -3,6 +3,7 @@
  *
  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
  * Copyright (c) 2002 David S. Miller (davem@redhat.com)
+ * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
  *
  * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
  * and Nettle, by Niels Möller.
@@ -126,7 +127,11 @@
 	unsigned int cra_blocksize;
 	unsigned int cra_ctxsize;
 	unsigned int cra_alignmask;
+
+	int cra_priority;
+
 	const char cra_name[CRYPTO_MAX_ALG_NAME];
+	const char cra_driver_name[CRYPTO_MAX_ALG_NAME];
 
 	union {
 		struct cipher_alg cipher;
diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h
index d41df70..c8cbd90 100644
--- a/include/linux/dvb/frontend.h
+++ b/include/linux/dvb/frontend.h
@@ -240,6 +240,15 @@
 };
 
 
+/**
+ * When set, this flag will disable any zigzagging or other "normal" tuning
+ * behaviour. Additionally, there will be no automatic monitoring of the lock
+ * status, and hence no frontend events will be generated. If a frontend device
+ * is closed, this flag will be automatically turned off when the device is
+ * reopened read-write.
+ */
+#define FE_TUNE_MODE_ONESHOT 0x01
+
 
 #define FE_GET_INFO		   _IOR('o', 61, struct dvb_frontend_info)
 
@@ -260,6 +269,7 @@
 
 #define FE_SET_FRONTEND		   _IOW('o', 76, struct dvb_frontend_parameters)
 #define FE_GET_FRONTEND		   _IOR('o', 77, struct dvb_frontend_parameters)
+#define FE_SET_FRONTEND_TUNE_MODE  _IO('o', 81) /* unsigned int */
 #define FE_GET_EVENT		   _IOR('o', 78, struct dvb_frontend_event)
 
 #define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80) /* unsigned int */
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index 4a6f50e..23fe746 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -66,7 +66,7 @@
 };
 
 /*
- * each queue has an elevator_queue assoicated with it
+ * each queue has an elevator_queue associated with it
  */
 struct elevator_queue
 {
diff --git a/include/linux/ext3_fs_i.h b/include/linux/ext3_fs_i.h
index 2914f7b..e71dd98 100644
--- a/include/linux/ext3_fs_i.h
+++ b/include/linux/ext3_fs_i.h
@@ -87,7 +87,7 @@
 #ifdef CONFIG_EXT3_FS_XATTR
 	/*
 	 * Extended attributes can be read independently of the main file
-	 * data. Taking i_sem even when reading would cause contention
+	 * data. Taking i_mutex even when reading would cause contention
 	 * between readers of EAs and writers of regular file data, so
 	 * instead we synchronize on xattr_sem when reading or changing
 	 * EAs.
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 4c82219..92ae3e2 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -219,6 +219,7 @@
 #include <linux/prio_tree.h>
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/mutex.h>
 
 #include <asm/atomic.h>
 #include <asm/semaphore.h>
@@ -484,7 +485,7 @@
 	unsigned long		i_blocks;
 	unsigned short          i_bytes;
 	spinlock_t		i_lock;	/* i_blocks, i_bytes, maybe i_size */
-	struct semaphore	i_sem;
+	struct mutex		i_mutex;
 	struct rw_semaphore	i_alloc_sem;
 	struct inode_operations	*i_op;
 	struct file_operations	*i_fop;	/* former ->i_op->default_file_ops */
@@ -820,7 +821,7 @@
 	unsigned long		s_magic;
 	struct dentry		*s_root;
 	struct rw_semaphore	s_umount;
-	struct semaphore	s_lock;
+	struct mutex		s_lock;
 	int			s_count;
 	int			s_syncing;
 	int			s_need_sync_fs;
@@ -892,13 +893,13 @@
 static inline void lock_super(struct super_block * sb)
 {
 	get_fs_excl();
-	down(&sb->s_lock);
+	mutex_lock(&sb->s_lock);
 }
 
 static inline void unlock_super(struct super_block * sb)
 {
 	put_fs_excl();
-	up(&sb->s_lock);
+	mutex_unlock(&sb->s_lock);
 }
 
 /*
@@ -1191,7 +1192,7 @@
  *    directory.  The name should be stored in the @name (with the
  *    understanding that it is already pointing to a a %NAME_MAX+1 sized
  *    buffer.   get_name() should return %0 on success, a negative error code
- *    or error.  @get_name will be called without @parent->i_sem held.
+ *    or error.  @get_name will be called without @parent->i_mutex held.
  *
  * get_parent:
  *    @get_parent should find the parent directory for the given @child which
@@ -1213,7 +1214,7 @@
  *    nfsd_find_fh_dentry() in either the @obj or @parent parameters.
  *
  * Locking rules:
- *    get_parent is called with child->d_inode->i_sem down
+ *    get_parent is called with child->d_inode->i_mutex down
  *    get_name is not (which is possibly inconsistent)
  */
 
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index fb46f8d..6ff2d36 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -103,6 +103,7 @@
 #define I2C_DRIVERID_SAA711X	73	/* saa711x video encoders	*/
 #define I2C_DRIVERID_AKITAIOEXP	74	/* IO Expander on Sharp SL-C1000 */
 #define I2C_DRIVERID_INFRARED	75	/* I2C InfraRed on Video boards */
+#define I2C_DRIVERID_TVP5150	76	/* TVP5150 video decoder        */
 
 #define I2C_DRIVERID_I2CDEV	900
 #define I2C_DRIVERID_ARP        902    /* SMBus ARP Client              */
diff --git a/include/linux/ide.h b/include/linux/ide.h
index ef8d0cb..9a8c05d 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -18,6 +18,7 @@
 #include <linux/bio.h>
 #include <linux/device.h>
 #include <linux/pci.h>
+#include <linux/completion.h>
 #include <asm/byteorder.h>
 #include <asm/system.h>
 #include <asm/io.h>
@@ -638,7 +639,7 @@
 	int		crc_count;	/* crc counter to reduce drive speed */
 	struct list_head list;
 	struct device	gendev;
-	struct semaphore gendev_rel_sem;	/* to deal with device release() */
+	struct completion gendev_rel_comp;	/* to deal with device release() */
 } ide_drive_t;
 
 #define to_ide_device(dev)container_of(dev, ide_drive_t, gendev)
@@ -794,7 +795,7 @@
 	unsigned	sg_mapped  : 1;	/* sg_table and sg_nents are ready */
 
 	struct device	gendev;
-	struct semaphore gendev_rel_sem; /* To deal with device release() */
+	struct completion gendev_rel_comp; /* To deal with device release() */
 
 	void		*hwif_data;	/* extra hwif data */
 
diff --git a/include/linux/jffs2_fs_i.h b/include/linux/jffs2_fs_i.h
index ef85ab5..ad565bf 100644
--- a/include/linux/jffs2_fs_i.h
+++ b/include/linux/jffs2_fs_i.h
@@ -8,11 +8,11 @@
 #include <asm/semaphore.h>
 
 struct jffs2_inode_info {
-	/* We need an internal semaphore similar to inode->i_sem.
+	/* We need an internal mutex similar to inode->i_mutex.
 	   Unfortunately, we can't used the existing one, because
 	   either the GC would deadlock, or we'd have to release it
 	   before letting GC proceed. Or we'd have to put ugliness
-	   into the GC code so it didn't attempt to obtain the i_sem
+	   into the GC code so it didn't attempt to obtain the i_mutex
 	   for the inode(s) which are already locked */
 	struct semaphore sem;
 
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index ca7ff8f..d0e6ca3 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -286,6 +286,15 @@
 	1; \
 })
 
+/*
+ * Check at compile time that 'function' is a certain type, or is a pointer
+ * to that type (needs to use typedef for the function type.)
+ */
+#define typecheck_fn(type,function) \
+({	typeof(type) __tmp = function; \
+	(void)__tmp; \
+})
+
 #endif /* __KERNEL__ */
 
 #define SI_LOAD_SHIFT	16
diff --git a/include/linux/loop.h b/include/linux/loop.h
index 40f63c9..f965067 100644
--- a/include/linux/loop.h
+++ b/include/linux/loop.h
@@ -58,9 +58,9 @@
 	struct bio 		*lo_bio;
 	struct bio		*lo_biotail;
 	int			lo_state;
-	struct semaphore	lo_sem;
+	struct completion	lo_done;
+	struct completion	lo_bh_done;
 	struct semaphore	lo_ctl_mutex;
-	struct semaphore	lo_bh_mutex;
 	int			lo_pending;
 
 	request_queue_t		*lo_queue;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index df80e63..3f1fafc 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -13,6 +13,7 @@
 #include <linux/rbtree.h>
 #include <linux/prio_tree.h>
 #include <linux/fs.h>
+#include <linux/mutex.h>
 
 struct mempolicy;
 struct anon_vma;
@@ -1024,6 +1025,9 @@
 static inline void
 kernel_map_pages(struct page *page, int numpages, int enable)
 {
+	if (!PageHighMem(page) && !enable)
+		mutex_debug_check_no_locks_freed(page_address(page),
+						 page_address(page + numpages));
 }
 #endif
 
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index aef6042..ccd3e13 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -27,14 +27,15 @@
 #define MMC_RSP_MASK	(3 << 0)
 #define MMC_RSP_CRC	(1 << 3)		/* expect valid crc */
 #define MMC_RSP_BUSY	(1 << 4)		/* card may send busy */
+#define MMC_RSP_OPCODE	(1 << 5)		/* response contains opcode */
 
 /*
  * These are the response types, and correspond to valid bit
  * patterns of the above flags.  One additional valid pattern
  * is all zeros, which means we don't expect a response.
  */
-#define MMC_RSP_R1	(MMC_RSP_SHORT|MMC_RSP_CRC)
-#define MMC_RSP_R1B	(MMC_RSP_SHORT|MMC_RSP_CRC|MMC_RSP_BUSY)
+#define MMC_RSP_R1	(MMC_RSP_SHORT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+#define MMC_RSP_R1B	(MMC_RSP_SHORT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
 #define MMC_RSP_R2	(MMC_RSP_LONG|MMC_RSP_CRC)
 #define MMC_RSP_R3	(MMC_RSP_SHORT)
 #define MMC_RSP_R6	(MMC_RSP_SHORT|MMC_RSP_CRC)
@@ -64,6 +65,7 @@
 #define MMC_DATA_WRITE	(1 << 8)
 #define MMC_DATA_READ	(1 << 9)
 #define MMC_DATA_STREAM	(1 << 10)
+#define MMC_DATA_MULTI	(1 << 11)
 
 	unsigned int		bytes_xfered;
 
diff --git a/include/linux/mutex-debug.h b/include/linux/mutex-debug.h
new file mode 100644
index 0000000..0ccd8f9
--- /dev/null
+++ b/include/linux/mutex-debug.h
@@ -0,0 +1,21 @@
+#ifndef __LINUX_MUTEX_DEBUG_H
+#define __LINUX_MUTEX_DEBUG_H
+
+/*
+ * Mutexes - debugging helpers:
+ */
+
+#define __DEBUG_MUTEX_INITIALIZER(lockname) \
+	, .held_list = LIST_HEAD_INIT(lockname.held_list), \
+	  .name = #lockname , .magic = &lockname
+
+#define mutex_init(sem)		__mutex_init(sem, __FUNCTION__)
+
+extern void FASTCALL(mutex_destroy(struct mutex *lock));
+
+extern void mutex_debug_show_all_locks(void);
+extern void mutex_debug_show_held_locks(struct task_struct *filter);
+extern void mutex_debug_check_no_locks_held(struct task_struct *task);
+extern void mutex_debug_check_no_locks_freed(const void *from, const void *to);
+
+#endif
diff --git a/include/linux/mutex.h b/include/linux/mutex.h
new file mode 100644
index 0000000..9bce0fe
--- /dev/null
+++ b/include/linux/mutex.h
@@ -0,0 +1,119 @@
+/*
+ * Mutexes: blocking mutual exclusion locks
+ *
+ * started by Ingo Molnar:
+ *
+ *  Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *
+ * This file contains the main data structure and API definitions.
+ */
+#ifndef __LINUX_MUTEX_H
+#define __LINUX_MUTEX_H
+
+#include <linux/list.h>
+#include <linux/spinlock_types.h>
+
+#include <asm/atomic.h>
+
+/*
+ * Simple, straightforward mutexes with strict semantics:
+ *
+ * - only one task can hold the mutex at a time
+ * - only the owner can unlock the mutex
+ * - multiple unlocks are not permitted
+ * - recursive locking is not permitted
+ * - a mutex object must be initialized via the API
+ * - a mutex object must not be initialized via memset or copying
+ * - task may not exit with mutex held
+ * - memory areas where held locks reside must not be freed
+ * - held mutexes must not be reinitialized
+ * - mutexes may not be used in irq contexts
+ *
+ * These semantics are fully enforced when DEBUG_MUTEXES is
+ * enabled. Furthermore, besides enforcing the above rules, the mutex
+ * debugging code also implements a number of additional features
+ * that make lock debugging easier and faster:
+ *
+ * - uses symbolic names of mutexes, whenever they are printed in debug output
+ * - point-of-acquire tracking, symbolic lookup of function names
+ * - list of all locks held in the system, printout of them
+ * - owner tracking
+ * - detects self-recursing locks and prints out all relevant info
+ * - detects multi-task circular deadlocks and prints out all affected
+ *   locks and tasks (and only those tasks)
+ */
+struct mutex {
+	/* 1: unlocked, 0: locked, negative: locked, possible waiters */
+	atomic_t		count;
+	spinlock_t		wait_lock;
+	struct list_head	wait_list;
+#ifdef CONFIG_DEBUG_MUTEXES
+	struct thread_info	*owner;
+	struct list_head	held_list;
+	unsigned long		acquire_ip;
+	const char 		*name;
+	void			*magic;
+#endif
+};
+
+/*
+ * This is the control structure for tasks blocked on mutex,
+ * which resides on the blocked task's kernel stack:
+ */
+struct mutex_waiter {
+	struct list_head	list;
+	struct task_struct	*task;
+#ifdef CONFIG_DEBUG_MUTEXES
+	struct mutex		*lock;
+	void			*magic;
+#endif
+};
+
+#ifdef CONFIG_DEBUG_MUTEXES
+# include <linux/mutex-debug.h>
+#else
+# define __DEBUG_MUTEX_INITIALIZER(lockname)
+# define mutex_init(mutex)			__mutex_init(mutex, NULL)
+# define mutex_destroy(mutex)				do { } while (0)
+# define mutex_debug_show_all_locks()			do { } while (0)
+# define mutex_debug_show_held_locks(p)			do { } while (0)
+# define mutex_debug_check_no_locks_held(task)		do { } while (0)
+# define mutex_debug_check_no_locks_freed(from, to)	do { } while (0)
+#endif
+
+#define __MUTEX_INITIALIZER(lockname) \
+		{ .count = ATOMIC_INIT(1) \
+		, .wait_lock = SPIN_LOCK_UNLOCKED \
+		, .wait_list = LIST_HEAD_INIT(lockname.wait_list) \
+		__DEBUG_MUTEX_INITIALIZER(lockname) }
+
+#define DEFINE_MUTEX(mutexname) \
+	struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
+
+extern void fastcall __mutex_init(struct mutex *lock, const char *name);
+
+/***
+ * mutex_is_locked - is the mutex locked
+ * @lock: the mutex to be queried
+ *
+ * Returns 1 if the mutex is locked, 0 if unlocked.
+ */
+static inline int fastcall mutex_is_locked(struct mutex *lock)
+{
+	return atomic_read(&lock->count) != 1;
+}
+
+/*
+ * See kernel/mutex.c for detailed documentation of these APIs.
+ * Also see Documentation/mutex-design.txt.
+ */
+extern void fastcall mutex_lock(struct mutex *lock);
+extern int fastcall mutex_lock_interruptible(struct mutex *lock);
+/*
+ * NOTE: mutex_trylock() follows the spin_trylock() convention,
+ *       not the down_trylock() convention!
+ */
+extern int fastcall mutex_trylock(struct mutex *lock);
+extern void fastcall mutex_unlock(struct mutex *lock);
+
+#endif
diff --git a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h
index bb842ea..0798b77 100644
--- a/include/linux/nfsd/nfsfh.h
+++ b/include/linux/nfsd/nfsfh.h
@@ -294,7 +294,7 @@
 /*
  * Lock a file handle/inode
  * NOTE: both fh_lock and fh_unlock are done "by hand" in
- * vfs.c:nfsd_rename as it needs to grab 2 i_sem's at once
+ * vfs.c:nfsd_rename as it needs to grab 2 i_mutex's at once
  * so, any changes here should be reflected there.
  */
 static inline void
@@ -317,7 +317,7 @@
 	}
 
 	inode = dentry->d_inode;
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	fill_pre_wcc(fhp);
 	fhp->fh_locked = 1;
 }
@@ -333,7 +333,7 @@
 
 	if (fhp->fh_locked) {
 		fill_post_wcc(fhp);
-		up(&fhp->fh_dentry->d_inode->i_sem);
+		mutex_unlock(&fhp->fh_dentry->d_inode->i_mutex);
 		fhp->fh_locked = 0;
 	}
 }
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index 1767073..b12e59c 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -37,7 +37,7 @@
    memory allocation, whereas PIPE_BUF makes atomicity guarantees.  */
 #define PIPE_SIZE		PAGE_SIZE
 
-#define PIPE_SEM(inode)		(&(inode).i_sem)
+#define PIPE_MUTEX(inode)	(&(inode).i_mutex)
 #define PIPE_WAIT(inode)	(&(inode).i_pipe->wait)
 #define PIPE_READERS(inode)	((inode).i_pipe->readers)
 #define PIPE_WRITERS(inode)	((inode).i_pipe->writers)
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index 001ab82..e276c5b 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -1857,7 +1857,7 @@
 #define GET_BLOCK_CREATE 1	/* add anything you need to find block */
 #define GET_BLOCK_NO_HOLE 2	/* return -ENOENT for file holes */
 #define GET_BLOCK_READ_DIRECT 4	/* read the tail if indirect item not found */
-#define GET_BLOCK_NO_ISEM     8	/* i_sem is not held, don't preallocate */
+#define GET_BLOCK_NO_IMUX     8	/* i_mutex is not held, don't preallocate */
 #define GET_BLOCK_NO_DANGLE   16	/* don't leave any transactions running */
 
 int restart_transaction(struct reiserfs_transaction_handle *th,
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 78eb92a..85b53f8 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -817,6 +817,11 @@
 /* Protection of proc_dentry: nesting proc_lock, dcache_lock, write_lock_irq(&tasklist_lock); */
 	spinlock_t proc_lock;
 
+#ifdef CONFIG_DEBUG_MUTEXES
+	/* mutex deadlock detection */
+	struct mutex_waiter *blocked_on;
+#endif
+
 /* journalling filesystem info */
 	void *journal_info;
 
diff --git a/include/linux/video_decoder.h b/include/linux/video_decoder.h
index 0e9e48b..121e26d 100644
--- a/include/linux/video_decoder.h
+++ b/include/linux/video_decoder.h
@@ -1,6 +1,8 @@
 #ifndef _LINUX_VIDEO_DECODER_H
 #define _LINUX_VIDEO_DECODER_H
 
+#define HAVE_VIDEO_DECODER 1
+
 struct video_decoder_capability { /* this name is too long */
 	__u32	flags;
 #define	VIDEO_DECODER_PAL	1	/* can decode PAL signal */
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 1cded68..ce40675 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -642,6 +642,12 @@
 #define V4L2_STD_ATSC_8_VSB     ((v4l2_std_id)0x01000000)
 #define V4L2_STD_ATSC_16_VSB    ((v4l2_std_id)0x02000000)
 
+/* some merged standards */
+#define V4L2_STD_MN	(V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC)
+#define V4L2_STD_B	(V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B)
+#define V4L2_STD_GH	(V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H)
+#define V4L2_STD_DK	(V4L2_STD_PAL_DK|V4L2_STD_SECAM_DK)
+
 /* some common needed stuff */
 #define V4L2_STD_PAL_BG		(V4L2_STD_PAL_B		|\
 				 V4L2_STD_PAL_B1	|\
@@ -662,7 +668,8 @@
 				 V4L2_STD_SECAM_G	|\
 				 V4L2_STD_SECAM_H	|\
 				 V4L2_STD_SECAM_DK	|\
-				 V4L2_STD_SECAM_L)
+				 V4L2_STD_SECAM_L       |\
+				 V4L2_STD_SECAM_LC)
 
 #define V4L2_STD_525_60		(V4L2_STD_PAL_M		|\
 				 V4L2_STD_PAL_60	|\
@@ -888,7 +895,6 @@
 
 /*  Flags for the 'mode' field */
 #define V4L2_AUDMODE_AVL		0x00001
-#define V4L2_AUDMODE_32BITS		0x00002
 
 struct v4l2_audioout
 {
@@ -1110,7 +1116,6 @@
 /* names for fancy debug output */
 extern char *v4l2_field_names[];
 extern char *v4l2_type_names[];
-extern char *v4l2_ioctl_names[];
 
 /*  Compatibility layer interface  --  v4l1-compat module */
 typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file,
@@ -1118,6 +1123,11 @@
 int v4l_compat_translate_ioctl(struct inode *inode, struct file *file,
 			       int cmd, void *arg, v4l2_kioctl driver_ioctl);
 
+/* 32 Bits compatibility layer for 64 bits processors */
+extern long v4l_compat_ioctl32(struct file *file, unsigned int cmd,
+				unsigned long arg);
+
+
 #endif /* __KERNEL__ */
 #endif /* __LINUX_VIDEODEV2_H */
 
diff --git a/include/media/audiochip.h b/include/media/audiochip.h
index b7d4b09..295d256 100644
--- a/include/media/audiochip.h
+++ b/include/media/audiochip.h
@@ -23,11 +23,6 @@
 
 /* ---------------------------------------------------------------------- */
 
-/* v4l device was opened in Radio mode */
-#define AUDC_SET_RADIO        _IO('m',2)
-/* select from TV,radio,extern,MUTE */
-#define AUDC_SET_INPUT        _IOW('m',17,int)
-
 /* audio inputs */
 #define AUDIO_TUNER        0x00
 #define AUDIO_RADIO        0x01
@@ -40,15 +35,4 @@
 #define AUDIO_MUTE         0x80
 #define AUDIO_UNMUTE       0x81
 
-/* all the stuff below is obsolete and just here for reference.  I'll
- * remove it once the driver is tested and works fine.
- *
- * Instead creating alot of tiny API's for all kinds of different
- * chips, we'll just pass throuth the v4l ioctl structs (v4l2 not
- * yet...).  It is a bit less flexible, but most/all used i2c chips
- * make sense in v4l context only.  So I think that's acceptable...
- */
-
-/* misc stuff to pass around config info to i2c chips */
-#define AUDC_CONFIG_PINNACLE  _IOW('m',32,int)
 #endif /* AUDIOCHIP_H */
diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h
index 16af929..e5e749e 100644
--- a/include/media/saa7146_vv.h
+++ b/include/media/saa7146_vv.h
@@ -178,6 +178,8 @@
 
 	struct saa7146_extension_ioctls *ioctls;
 	int (*ioctl)(struct saa7146_fh*, unsigned int cmd, void *arg);
+
+	struct file_operations vbi_fops;
 };
 
 struct saa7146_use_ops  {
diff --git a/include/media/tuner.h b/include/media/tuner.h
index b37cde6..7674b12 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -82,9 +82,9 @@
 #define TUNER_PHILIPS_FM1236_MK3	43
 
 #define TUNER_PHILIPS_4IN1		44	/* ATI TV Wonder Pro - Conexant */
-/* Microtune mergeged with Temic 12/31/1999 partially financed by Alps - these may be similar to Temic */
+/* Microtune merged with Temic 12/31/1999 partially financed by Alps - these may be similar to Temic */
 #define TUNER_MICROTUNE_4049FM5 	45
-#define TUNER_MICROTUNE_4042_FI5	46
+#define TUNER_PANASONIC_VP27		46
 #define TUNER_LG_NTSC_TAPE		47
 
 #define TUNER_TNF_8831BGFF		48
@@ -102,7 +102,7 @@
 #define TUNER_YMEC_TVF_8531MF		58
 #define TUNER_YMEC_TVF_5533MF		59	/* Pixelview Pro Ultra NTSC */
 
-#define TUNER_THOMSON_DTT7611		60	/* DViCO FusionHDTV 3 Gold-T */
+#define TUNER_THOMSON_DTT761X		60	/* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */
 #define TUNER_TENA_9533_DI		61
 #define TUNER_TEA5767			62	/* Only FM Radio Tuner */
 #define TUNER_PHILIPS_FMD1216ME_MK3	63
@@ -115,47 +115,26 @@
 #define TUNER_PHILIPS_TUV1236D		68	/* ATI HDTV Wonder */
 #define TUNER_TNF_5335MF                69	/* Sabrent Bt848   */
 
-#define NOTUNER 0
-#define PAL     1	/* PAL_BG */
-#define PAL_I   2
-#define NTSC    3
-#define SECAM   4
-#define ATSC    5
-#define RADIO   6
-
-#define NoTuner 0
-#define Philips 1
-#define TEMIC   2
-#define Sony    3
-#define Alps    4
-#define LGINNOTEK 5
-#define SHARP   6
-#define Samsung 7
-#define Microtune 8
-#define HITACHI 9
-#define Panasonic 10
-#define TCL     11
-#define THOMSON 12
-
-#define TUNER_SET_TYPE_ADDR          _IOW('T',3,int)
-#define TUNER_SET_STANDBY            _IOW('T',4,int)
-#define TDA9887_SET_CONFIG           _IOW('t',5,int)
-
 /* tv card specific */
-# define TDA9887_PRESENT             (1<<0)
-# define TDA9887_PORT1_INACTIVE      (1<<1)
-# define TDA9887_PORT2_INACTIVE      (1<<2)
-# define TDA9887_QSS                 (1<<3)
-# define TDA9887_INTERCARRIER        (1<<4)
-# define TDA9887_PORT1_ACTIVE        (1<<5)
-# define TDA9887_PORT2_ACTIVE        (1<<6)
-# define TDA9887_INTERCARRIER_NTSC   (1<<7)
+#define TDA9887_PRESENT 		(1<<0)
+#define TDA9887_PORT1_INACTIVE 		(1<<1)
+#define TDA9887_PORT2_INACTIVE 		(1<<2)
+#define TDA9887_QSS 			(1<<3)
+#define TDA9887_INTERCARRIER 		(1<<4)
+#define TDA9887_PORT1_ACTIVE 		(1<<5)
+#define TDA9887_PORT2_ACTIVE 		(1<<6)
+#define TDA9887_INTERCARRIER_NTSC 	(1<<7)
+/* Tuner takeover point adjustment, in dB, -16 <= top <= 15 */
+#define TDA9887_TOP_MASK 		(0x3f << 8)
+#define TDA9887_TOP_SET 		(1 << 13)
+#define TDA9887_TOP(top) 		(TDA9887_TOP_SET | (((16 + (top)) & 0x1f) << 8))
+
 /* config options */
-# define TDA9887_DEEMPHASIS_MASK     (3<<16)
-# define TDA9887_DEEMPHASIS_NONE     (1<<16)
-# define TDA9887_DEEMPHASIS_50       (2<<16)
-# define TDA9887_DEEMPHASIS_75       (3<<16)
-# define TDA9887_AUTOMUTE            (1<<18)
+#define TDA9887_DEEMPHASIS_MASK 	(3<<16)
+#define TDA9887_DEEMPHASIS_NONE 	(1<<16)
+#define TDA9887_DEEMPHASIS_50 		(2<<16)
+#define TDA9887_DEEMPHASIS_75 		(3<<16)
+#define TDA9887_AUTOMUTE 		(1<<18)
 
 #ifdef __KERNEL__
 
@@ -167,10 +146,26 @@
 	T_STANDBY	= 1 << 31
 };
 
+/* Older boards only had a single tuner device. Nowadays multiple tuner
+   devices may be present on a single board. Using TUNER_SET_TYPE_ADDR
+   to pass the tuner_setup structure it is possible to setup each tuner
+   device in turn.
+
+   Since multiple devices may be present it is no longer sufficient to
+   send a command to a single i2c device. Instead you should broadcast
+   the command to all i2c devices.
+
+   By setting the mode_mask correctly you can select which commands are
+   accepted by a specific tuner device. For example, set mode_mask to
+   T_RADIO if the device is a radio-only tuner. That specific tuner will
+   only accept commands when the tuner is in radio mode and ignore them
+   when the tuner is set to TV mode.
+ */
+
 struct tuner_setup {
-	unsigned short	addr;
-	unsigned int	type;
-	unsigned int	mode_mask;
+	unsigned short	addr; 	/* I2C address */
+	unsigned int	type;   /* Tuner type */
+	unsigned int	mode_mask;  /* Allowed tuner modes */
 };
 
 struct tuner {
@@ -207,7 +202,6 @@
 	void (*standby)(struct i2c_client *c);
 };
 
-extern unsigned int tuner_debug;
 extern unsigned const int tuner_count;
 
 extern int microtune_init(struct i2c_client *c);
@@ -219,15 +213,15 @@
 
 #define tuner_warn(fmt, arg...) do {\
 	printk(KERN_WARNING "%s %d-%04x: " fmt, t->i2c.driver->driver.name, \
-			t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
+			i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0)
 #define tuner_info(fmt, arg...) do {\
 	printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.driver->driver.name, \
-			t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
+			i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0)
 #define tuner_dbg(fmt, arg...) do {\
-	if (tuner_debug) \
-		printk(KERN_DEBUG "%s %d-%04x: " fmt, \
-			t->i2c.driver->driver.name, \
-			t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
+	extern int debug; \
+	if (debug) \
+		printk(KERN_DEBUG "%s %d-%04x: " fmt, t->i2c.driver->driver.name, \
+			i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0)
 
 #endif /* __KERNEL__ */
 
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index d3fd481..3cc3132 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -26,12 +26,57 @@
 #ifndef V4L2_COMMON_H_
 #define V4L2_COMMON_H_
 
-/* VIDIOC_INT_AUDIO_CLOCK_FREQ */
-enum v4l2_audio_clock_freq {
-	V4L2_AUDCLK_32_KHZ  = 32000,
-	V4L2_AUDCLK_441_KHZ = 44100,
-	V4L2_AUDCLK_48_KHZ  = 48000,
-};
+/* v4l debugging and diagnostics */
+
+/* Common printk constucts for v4l-i2c drivers. These macros create a unique
+   prefix consisting of the driver name, the adapter number and the i2c
+   address. */
+#define v4l_printk(level, name, adapter, addr, fmt, arg...) \
+	printk(level "%s %d-%04x: " fmt, name, i2c_adapter_id(adapter), addr , ## arg)
+
+#define v4l_client_printk(level, client, fmt, arg...)			    \
+	v4l_printk(level, (client)->driver->driver.name, (client)->adapter, \
+		   (client)->addr, fmt , ## arg)
+
+#define v4l_err(client, fmt, arg...) \
+	v4l_client_printk(KERN_ERR, client, fmt , ## arg)
+
+#define v4l_warn(client, fmt, arg...) \
+	v4l_client_printk(KERN_WARNING, client, fmt , ## arg)
+
+#define v4l_info(client, fmt, arg...) \
+	v4l_client_printk(KERN_INFO, client, fmt , ## arg)
+
+/* These three macros assume that the debug level is set with a module
+   parameter called 'debug'. */
+#define v4l_dbg(level, client, fmt, arg...)				     \
+	do { 								     \
+		extern int debug;					     \
+		if (debug >= (level))					     \
+			v4l_client_printk(KERN_DEBUG, client, fmt , ## arg); \
+	} while (0)
+
+/* Prints the ioctl in a human-readable format */
+extern void v4l_printk_ioctl(unsigned int cmd);
+
+/* Use this macro for non-I2C drivers. Pass the driver name as the first arg. */
+#define v4l_print_ioctl(name, cmd)  		 \
+	do {  					 \
+		printk(KERN_DEBUG "%s: ", name); \
+		v4l_printk_ioctl(cmd);		 \
+	} while (0)
+
+/* Use this macro in I2C drivers where 'client' is the struct i2c_client
+   pointer */
+#define v4l_i2c_print_ioctl(client, cmd) 		   \
+	do {      					   \
+		v4l_client_printk(KERN_DEBUG, client, ""); \
+		v4l_printk_ioctl(cmd);			   \
+	} while (0)
+
+/* ------------------------------------------------------------------------- */
+
+/* Internal ioctls */
 
 /* VIDIOC_INT_G_REGISTER and VIDIOC_INT_S_REGISTER */
 struct v4l2_register {
@@ -70,6 +115,20 @@
 	V4L2_IDENT_CX25843 = 243,
 };
 
+/* audio ioctls */
+/* v4l device was opened in Radio mode */
+#define AUDC_SET_RADIO        _IO('d',88)
+/* select from TV,radio,extern,MUTE */
+#define AUDC_SET_INPUT        _IOW('d',89,int)
+
+/* tuner ioctls */
+/* Sets tuner type and its I2C addr */
+#define TUNER_SET_TYPE_ADDR          _IOW('d',90,int)
+/* Puts tuner on powersaving state, disabling it, except for i2c */
+#define TUNER_SET_STANDBY            _IOW('d',91,int)
+/* Sets tda9887 specific stuff, like port1, port2 and qss */
+#define TDA9887_SET_CONFIG           _IOW('d',92,int)
+
 /* only implemented if CONFIG_VIDEO_ADV_DEBUG is defined */
 #define	VIDIOC_INT_S_REGISTER 		_IOR ('d', 100, struct v4l2_register)
 #define	VIDIOC_INT_G_REGISTER 		_IOWR('d', 101, struct v4l2_register)
@@ -77,10 +136,12 @@
 /* Reset the I2C chip */
 #define VIDIOC_INT_RESET            	_IO  ('d', 102)
 
-/* Set the frequency of the audio clock output.
+/* Set the frequency (in Hz) of the audio clock output.
    Used to slave an audio processor to the video decoder, ensuring that audio
-   and video remain synchronized. */
-#define VIDIOC_INT_AUDIO_CLOCK_FREQ 	_IOR ('d', 103, enum v4l2_audio_clock_freq)
+   and video remain synchronized.
+   Usual values for the frequency are 48000, 44100 or 32000 Hz.
+   If the frequency is not supported, then -EINVAL is returned. */
+#define VIDIOC_INT_AUDIO_CLOCK_FREQ 	_IOW ('d', 103, u32)
 
 /* Video decoders that support sliced VBI need to implement this ioctl.
    Field p of the v4l2_sliced_vbi_line struct is set to the start of the VBI
@@ -107,4 +168,10 @@
    be made. */
 #define VIDIOC_INT_G_CHIP_IDENT		_IOR ('d', 107, enum v4l2_chip_ident *)
 
+/* Sets I2S speed in bps. This is used to provide a standard way to select I2S
+   clock used by driving digital audio streams at some board designs.
+   Usual values for the frequency are 1024000 and 2048000.
+   If the frequency is not supported, then -EINVAL is returned. */
+#define VIDIOC_INT_I2S_CLOCK_FREQ 	_IOW ('d', 108, u32)
+
 #endif /* V4L2_COMMON_H_ */
diff --git a/include/net/act_api.h b/include/net/act_api.h
index b55eb7c..11e9eaf 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -63,7 +63,7 @@
 	__u32   type; /* TBD to match kind */
 	__u32 	capab;  /* capabilities includes 4 bit version */
 	struct module		*owner;
-	int     (*act)(struct sk_buff **, struct tc_action *, struct tcf_result *);
+	int     (*act)(struct sk_buff *, struct tc_action *, struct tcf_result *);
 	int     (*get_stats)(struct sk_buff *, struct tc_action *);
 	int     (*dump)(struct sk_buff *, struct tc_action *,int , int);
 	int     (*cleanup)(struct tc_action *, int bind);
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index 6492e73..b94d1ad 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -1,6 +1,7 @@
 #ifndef __NET_PKT_SCHED_H
 #define __NET_PKT_SCHED_H
 
+#include <linux/jiffies.h>
 #include <net/sch_generic.h>
 
 struct qdisc_walker
@@ -59,8 +60,8 @@
 typedef long		psched_tdiff_t;
 
 #define PSCHED_GET_TIME(stamp) do_gettimeofday(&(stamp))
-#define PSCHED_US2JIFFIE(usecs) (((usecs)+(1000000/HZ-1))/(1000000/HZ))
-#define PSCHED_JIFFIE2US(delay) ((delay)*(1000000/HZ))
+#define PSCHED_US2JIFFIE(usecs) usecs_to_jiffies(usecs)
+#define PSCHED_JIFFIE2US(delay) jiffies_to_usecs(delay)
 
 #else /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */
 
@@ -123,9 +124,9 @@
 		   default: \
 			   __delta = 0; \
 		   case 2: \
-			   __delta += 1000000; \
+			   __delta += USEC_PER_SEC; \
 		   case 1: \
-			   __delta += 1000000; \
+			   __delta += USEC_PER_SEC; \
 	           } \
 	   } \
 	   __delta; \
@@ -136,9 +137,9 @@
 {
 	int delta;
 
-	if (bound <= 1000000 || delta_sec > (0x7FFFFFFF/1000000)-1)
+	if (bound <= USEC_PER_SEC || delta_sec > (0x7FFFFFFF/USEC_PER_SEC)-1)
 		return bound;
-	delta = delta_sec * 1000000;
+	delta = delta_sec * USEC_PER_SEC;
 	if (delta > bound || delta < 0)
 		delta = bound;
 	return delta;
@@ -152,9 +153,9 @@
 	   default: \
 		   __delta = psched_tod_diff(__delta_sec, bound);  break; \
 	   case 2: \
-		   __delta += 1000000; \
+		   __delta += USEC_PER_SEC; \
 	   case 1: \
-		   __delta += 1000000; \
+		   __delta += USEC_PER_SEC; \
 	   case 0: \
  		   if (__delta > bound || __delta < 0) \
  			__delta = bound; \
@@ -170,15 +171,15 @@
 ({ \
 	   int __delta = (tv).tv_usec + (delta); \
 	   (tv_res).tv_sec = (tv).tv_sec; \
-	   if (__delta > 1000000) { (tv_res).tv_sec++; __delta -= 1000000; } \
+	   if (__delta > USEC_PER_SEC) { (tv_res).tv_sec++; __delta -= USEC_PER_SEC; } \
 	   (tv_res).tv_usec = __delta; \
 })
 
 #define PSCHED_TADD(tv, delta) \
 ({ \
 	   (tv).tv_usec += (delta); \
-	   if ((tv).tv_usec > 1000000) { (tv).tv_sec++; \
-		 (tv).tv_usec -= 1000000; } \
+	   if ((tv).tv_usec > USEC_PER_SEC) { (tv).tv_sec++; \
+		 (tv).tv_usec -= USEC_PER_SEC; } \
 })
 
 /* Set/check that time is in the "past perfect";
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index c8943b5..a8aa615 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -660,7 +660,7 @@
 	if (fd < 0)
 		goto out_putname;
 
-	down(&mqueue_mnt->mnt_root->d_inode->i_sem);
+	mutex_lock(&mqueue_mnt->mnt_root->d_inode->i_mutex);
 	dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name));
 	if (IS_ERR(dentry)) {
 		error = PTR_ERR(dentry);
@@ -697,7 +697,7 @@
 out_err:
 	fd = error;
 out_upsem:
-	up(&mqueue_mnt->mnt_root->d_inode->i_sem);
+	mutex_unlock(&mqueue_mnt->mnt_root->d_inode->i_mutex);
 out_putname:
 	putname(name);
 	return fd;
@@ -714,7 +714,7 @@
 	if (IS_ERR(name))
 		return PTR_ERR(name);
 
-	down(&mqueue_mnt->mnt_root->d_inode->i_sem);
+	mutex_lock(&mqueue_mnt->mnt_root->d_inode->i_mutex);
 	dentry = lookup_one_len(name, mqueue_mnt->mnt_root, strlen(name));
 	if (IS_ERR(dentry)) {
 		err = PTR_ERR(dentry);
@@ -735,7 +735,7 @@
 	dput(dentry);
 
 out_unlock:
-	up(&mqueue_mnt->mnt_root->d_inode->i_sem);
+	mutex_unlock(&mqueue_mnt->mnt_root->d_inode->i_mutex);
 	putname(name);
 	if (inode)
 		iput(inode);
diff --git a/kernel/Makefile b/kernel/Makefile
index 4f5a145..a940bac 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -7,8 +7,9 @@
 	    sysctl.o capability.o ptrace.o timer.o user.o \
 	    signal.o sys.o kmod.o workqueue.o pid.o \
 	    rcupdate.o intermodule.o extable.o params.o posix-timers.o \
-	    kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o
+	    kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o
 
+obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o
 obj-$(CONFIG_FUTEX) += futex.o
 obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
 obj-$(CONFIG_SMP) += cpu.o spinlock.o
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index eab64e2..2a75e44 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -1513,7 +1513,7 @@
 	struct dentry *dentry;
 	int error;
 
-	down(&dir->d_inode->i_sem);
+	mutex_lock(&dir->d_inode->i_mutex);
 	dentry = cpuset_get_dentry(dir, cft->name);
 	if (!IS_ERR(dentry)) {
 		error = cpuset_create_file(dentry, 0644 | S_IFREG);
@@ -1522,7 +1522,7 @@
 		dput(dentry);
 	} else
 		error = PTR_ERR(dentry);
-	up(&dir->d_inode->i_sem);
+	mutex_unlock(&dir->d_inode->i_mutex);
 	return error;
 }
 
@@ -1793,7 +1793,7 @@
 
 	/*
 	 * Release manage_sem before cpuset_populate_dir() because it
-	 * will down() this new directory's i_sem and if we race with
+	 * will down() this new directory's i_mutex and if we race with
 	 * another mkdir, we might deadlock.
 	 */
 	up(&manage_sem);
@@ -1812,7 +1812,7 @@
 {
 	struct cpuset *c_parent = dentry->d_parent->d_fsdata;
 
-	/* the vfs holds inode->i_sem already */
+	/* the vfs holds inode->i_mutex already */
 	return cpuset_create(c_parent, dentry->d_name.name, mode | S_IFDIR);
 }
 
@@ -1823,7 +1823,7 @@
 	struct cpuset *parent;
 	char *pathbuf = NULL;
 
-	/* the vfs holds both inode->i_sem already */
+	/* the vfs holds both inode->i_mutex already */
 
 	down(&manage_sem);
 	cpuset_update_task_memory_state();
diff --git a/kernel/exit.c b/kernel/exit.c
index caceabf..309a46f 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -29,6 +29,7 @@
 #include <linux/syscalls.h>
 #include <linux/signal.h>
 #include <linux/cn_proc.h>
+#include <linux/mutex.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -869,6 +870,10 @@
 	mpol_free(tsk->mempolicy);
 	tsk->mempolicy = NULL;
 #endif
+	/*
+	 * If DEBUG_MUTEXES is on, make sure we are holding no locks:
+	 */
+	mutex_debug_check_no_locks_held(tsk);
 
 	/* PF_DEAD causes final put_task_struct after we schedule. */
 	preempt_disable();
diff --git a/kernel/fork.c b/kernel/fork.c
index 72e3252..b18d645 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -979,6 +979,10 @@
  	}
 #endif
 
+#ifdef CONFIG_DEBUG_MUTEXES
+	p->blocked_on = NULL; /* not blocked yet */
+#endif
+
 	p->tgid = p->pid;
 	if (clone_flags & CLONE_THREAD)
 		p->tgid = current->tgid;
diff --git a/kernel/mutex-debug.c b/kernel/mutex-debug.c
new file mode 100644
index 0000000..4fcb051
--- /dev/null
+++ b/kernel/mutex-debug.c
@@ -0,0 +1,464 @@
+/*
+ * kernel/mutex-debug.c
+ *
+ * Debugging code for mutexes
+ *
+ * Started by Ingo Molnar:
+ *
+ *  Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *
+ * lock debugging, locking tree, deadlock detection started by:
+ *
+ *  Copyright (C) 2004, LynuxWorks, Inc., Igor Manyilov, Bill Huey
+ *  Released under the General Public License (GPL).
+ */
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/kallsyms.h>
+#include <linux/interrupt.h>
+
+#include <asm/mutex.h>
+
+#include "mutex-debug.h"
+
+/*
+ * We need a global lock when we walk through the multi-process
+ * lock tree. Only used in the deadlock-debugging case.
+ */
+DEFINE_SPINLOCK(debug_mutex_lock);
+
+/*
+ * All locks held by all tasks, in a single global list:
+ */
+LIST_HEAD(debug_mutex_held_locks);
+
+/*
+ * In the debug case we carry the caller's instruction pointer into
+ * other functions, but we dont want the function argument overhead
+ * in the nondebug case - hence these macros:
+ */
+#define __IP_DECL__		, unsigned long ip
+#define __IP__			, ip
+#define __RET_IP__		, (unsigned long)__builtin_return_address(0)
+
+/*
+ * "mutex debugging enabled" flag. We turn it off when we detect
+ * the first problem because we dont want to recurse back
+ * into the tracing code when doing error printk or
+ * executing a BUG():
+ */
+int debug_mutex_on = 1;
+
+static void printk_task(struct task_struct *p)
+{
+	if (p)
+		printk("%16s:%5d [%p, %3d]", p->comm, p->pid, p, p->prio);
+	else
+		printk("<none>");
+}
+
+static void printk_ti(struct thread_info *ti)
+{
+	if (ti)
+		printk_task(ti->task);
+	else
+		printk("<none>");
+}
+
+static void printk_task_short(struct task_struct *p)
+{
+	if (p)
+		printk("%s/%d [%p, %3d]", p->comm, p->pid, p, p->prio);
+	else
+		printk("<none>");
+}
+
+static void printk_lock(struct mutex *lock, int print_owner)
+{
+	printk(" [%p] {%s}\n", lock, lock->name);
+
+	if (print_owner && lock->owner) {
+		printk(".. held by:  ");
+		printk_ti(lock->owner);
+		printk("\n");
+	}
+	if (lock->owner) {
+		printk("... acquired at:               ");
+		print_symbol("%s\n", lock->acquire_ip);
+	}
+}
+
+/*
+ * printk locks held by a task:
+ */
+static void show_task_locks(struct task_struct *p)
+{
+	switch (p->state) {
+	case TASK_RUNNING:		printk("R"); break;
+	case TASK_INTERRUPTIBLE:	printk("S"); break;
+	case TASK_UNINTERRUPTIBLE:	printk("D"); break;
+	case TASK_STOPPED:		printk("T"); break;
+	case EXIT_ZOMBIE:		printk("Z"); break;
+	case EXIT_DEAD:			printk("X"); break;
+	default:			printk("?"); break;
+	}
+	printk_task(p);
+	if (p->blocked_on) {
+		struct mutex *lock = p->blocked_on->lock;
+
+		printk(" blocked on mutex:");
+		printk_lock(lock, 1);
+	} else
+		printk(" (not blocked on mutex)\n");
+}
+
+/*
+ * printk all locks held in the system (if filter == NULL),
+ * or all locks belonging to a single task (if filter != NULL):
+ */
+void show_held_locks(struct task_struct *filter)
+{
+	struct list_head *curr, *cursor = NULL;
+	struct mutex *lock;
+	struct thread_info *t;
+	unsigned long flags;
+	int count = 0;
+
+	if (filter) {
+		printk("------------------------------\n");
+		printk("| showing all locks held by: |  (");
+		printk_task_short(filter);
+		printk("):\n");
+		printk("------------------------------\n");
+	} else {
+		printk("---------------------------\n");
+		printk("| showing all locks held: |\n");
+		printk("---------------------------\n");
+	}
+
+	/*
+	 * Play safe and acquire the global trace lock. We
+	 * cannot printk with that lock held so we iterate
+	 * very carefully:
+	 */
+next:
+	debug_spin_lock_save(&debug_mutex_lock, flags);
+	list_for_each(curr, &debug_mutex_held_locks) {
+		if (cursor && curr != cursor)
+			continue;
+		lock = list_entry(curr, struct mutex, held_list);
+		t = lock->owner;
+		if (filter && (t != filter->thread_info))
+			continue;
+		count++;
+		cursor = curr->next;
+		debug_spin_lock_restore(&debug_mutex_lock, flags);
+
+		printk("\n#%03d:            ", count);
+		printk_lock(lock, filter ? 0 : 1);
+		goto next;
+	}
+	debug_spin_lock_restore(&debug_mutex_lock, flags);
+	printk("\n");
+}
+
+void mutex_debug_show_all_locks(void)
+{
+	struct task_struct *g, *p;
+	int count = 10;
+	int unlock = 1;
+
+	printk("\nShowing all blocking locks in the system:\n");
+
+	/*
+	 * Here we try to get the tasklist_lock as hard as possible,
+	 * if not successful after 2 seconds we ignore it (but keep
+	 * trying). This is to enable a debug printout even if a
+	 * tasklist_lock-holding task deadlocks or crashes.
+	 */
+retry:
+	if (!read_trylock(&tasklist_lock)) {
+		if (count == 10)
+			printk("hm, tasklist_lock locked, retrying... ");
+		if (count) {
+			count--;
+			printk(" #%d", 10-count);
+			mdelay(200);
+			goto retry;
+		}
+		printk(" ignoring it.\n");
+		unlock = 0;
+	}
+	if (count != 10)
+		printk(" locked it.\n");
+
+	do_each_thread(g, p) {
+		show_task_locks(p);
+		if (!unlock)
+			if (read_trylock(&tasklist_lock))
+				unlock = 1;
+	} while_each_thread(g, p);
+
+	printk("\n");
+	show_held_locks(NULL);
+	printk("=============================================\n\n");
+
+	if (unlock)
+		read_unlock(&tasklist_lock);
+}
+
+static void report_deadlock(struct task_struct *task, struct mutex *lock,
+			    struct mutex *lockblk, unsigned long ip)
+{
+	printk("\n%s/%d is trying to acquire this lock:\n",
+		current->comm, current->pid);
+	printk_lock(lock, 1);
+	printk("... trying at:                 ");
+	print_symbol("%s\n", ip);
+	show_held_locks(current);
+
+	if (lockblk) {
+		printk("but %s/%d is deadlocking current task %s/%d!\n\n",
+			task->comm, task->pid, current->comm, current->pid);
+		printk("\n%s/%d is blocked on this lock:\n",
+			task->comm, task->pid);
+		printk_lock(lockblk, 1);
+
+		show_held_locks(task);
+
+		printk("\n%s/%d's [blocked] stackdump:\n\n",
+			task->comm, task->pid);
+		show_stack(task, NULL);
+	}
+
+	printk("\n%s/%d's [current] stackdump:\n\n",
+		current->comm, current->pid);
+	dump_stack();
+	mutex_debug_show_all_locks();
+	printk("[ turning off deadlock detection. Please report this. ]\n\n");
+	local_irq_disable();
+}
+
+/*
+ * Recursively check for mutex deadlocks:
+ */
+static int check_deadlock(struct mutex *lock, int depth,
+			  struct thread_info *ti, unsigned long ip)
+{
+	struct mutex *lockblk;
+	struct task_struct *task;
+
+	if (!debug_mutex_on)
+		return 0;
+
+	ti = lock->owner;
+	if (!ti)
+		return 0;
+
+	task = ti->task;
+	lockblk = NULL;
+	if (task->blocked_on)
+		lockblk = task->blocked_on->lock;
+
+	/* Self-deadlock: */
+	if (current == task) {
+		DEBUG_OFF();
+		if (depth)
+			return 1;
+		printk("\n==========================================\n");
+		printk(  "[ BUG: lock recursion deadlock detected! |\n");
+		printk(  "------------------------------------------\n");
+		report_deadlock(task, lock, NULL, ip);
+		return 0;
+	}
+
+	/* Ugh, something corrupted the lock data structure? */
+	if (depth > 20) {
+		DEBUG_OFF();
+		printk("\n===========================================\n");
+		printk(  "[ BUG: infinite lock dependency detected!? |\n");
+		printk(  "-------------------------------------------\n");
+		report_deadlock(task, lock, lockblk, ip);
+		return 0;
+	}
+
+	/* Recursively check for dependencies: */
+	if (lockblk && check_deadlock(lockblk, depth+1, ti, ip)) {
+		printk("\n============================================\n");
+		printk(  "[ BUG: circular locking deadlock detected! ]\n");
+		printk(  "--------------------------------------------\n");
+		report_deadlock(task, lock, lockblk, ip);
+		return 0;
+	}
+	return 0;
+}
+
+/*
+ * Called when a task exits, this function checks whether the
+ * task is holding any locks, and reports the first one if so:
+ */
+void mutex_debug_check_no_locks_held(struct task_struct *task)
+{
+	struct list_head *curr, *next;
+	struct thread_info *t;
+	unsigned long flags;
+	struct mutex *lock;
+
+	if (!debug_mutex_on)
+		return;
+
+	debug_spin_lock_save(&debug_mutex_lock, flags);
+	list_for_each_safe(curr, next, &debug_mutex_held_locks) {
+		lock = list_entry(curr, struct mutex, held_list);
+		t = lock->owner;
+		if (t != task->thread_info)
+			continue;
+		list_del_init(curr);
+		DEBUG_OFF();
+		debug_spin_lock_restore(&debug_mutex_lock, flags);
+
+		printk("BUG: %s/%d, lock held at task exit time!\n",
+			task->comm, task->pid);
+		printk_lock(lock, 1);
+		if (lock->owner != task->thread_info)
+			printk("exiting task is not even the owner??\n");
+		return;
+	}
+	debug_spin_lock_restore(&debug_mutex_lock, flags);
+}
+
+/*
+ * Called when kernel memory is freed (or unmapped), or if a mutex
+ * is destroyed or reinitialized - this code checks whether there is
+ * any held lock in the memory range of <from> to <to>:
+ */
+void mutex_debug_check_no_locks_freed(const void *from, const void *to)
+{
+	struct list_head *curr, *next;
+	unsigned long flags;
+	struct mutex *lock;
+	void *lock_addr;
+
+	if (!debug_mutex_on)
+		return;
+
+	debug_spin_lock_save(&debug_mutex_lock, flags);
+	list_for_each_safe(curr, next, &debug_mutex_held_locks) {
+		lock = list_entry(curr, struct mutex, held_list);
+		lock_addr = lock;
+		if (lock_addr < from || lock_addr >= to)
+			continue;
+		list_del_init(curr);
+		DEBUG_OFF();
+		debug_spin_lock_restore(&debug_mutex_lock, flags);
+
+		printk("BUG: %s/%d, active lock [%p(%p-%p)] freed!\n",
+			current->comm, current->pid, lock, from, to);
+		dump_stack();
+		printk_lock(lock, 1);
+		if (lock->owner != current_thread_info())
+			printk("freeing task is not even the owner??\n");
+		return;
+	}
+	debug_spin_lock_restore(&debug_mutex_lock, flags);
+}
+
+/*
+ * Must be called with lock->wait_lock held.
+ */
+void debug_mutex_set_owner(struct mutex *lock,
+			   struct thread_info *new_owner __IP_DECL__)
+{
+	lock->owner = new_owner;
+	DEBUG_WARN_ON(!list_empty(&lock->held_list));
+	if (debug_mutex_on) {
+		list_add_tail(&lock->held_list, &debug_mutex_held_locks);
+		lock->acquire_ip = ip;
+	}
+}
+
+void debug_mutex_init_waiter(struct mutex_waiter *waiter)
+{
+	memset(waiter, 0x11, sizeof(*waiter));
+	waiter->magic = waiter;
+	INIT_LIST_HEAD(&waiter->list);
+}
+
+void debug_mutex_wake_waiter(struct mutex *lock, struct mutex_waiter *waiter)
+{
+	SMP_DEBUG_WARN_ON(!spin_is_locked(&lock->wait_lock));
+	DEBUG_WARN_ON(list_empty(&lock->wait_list));
+	DEBUG_WARN_ON(waiter->magic != waiter);
+	DEBUG_WARN_ON(list_empty(&waiter->list));
+}
+
+void debug_mutex_free_waiter(struct mutex_waiter *waiter)
+{
+	DEBUG_WARN_ON(!list_empty(&waiter->list));
+	memset(waiter, 0x22, sizeof(*waiter));
+}
+
+void debug_mutex_add_waiter(struct mutex *lock, struct mutex_waiter *waiter,
+			    struct thread_info *ti __IP_DECL__)
+{
+	SMP_DEBUG_WARN_ON(!spin_is_locked(&lock->wait_lock));
+	check_deadlock(lock, 0, ti, ip);
+	/* Mark the current thread as blocked on the lock: */
+	ti->task->blocked_on = waiter;
+	waiter->lock = lock;
+}
+
+void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter,
+			 struct thread_info *ti)
+{
+	DEBUG_WARN_ON(list_empty(&waiter->list));
+	DEBUG_WARN_ON(waiter->task != ti->task);
+	DEBUG_WARN_ON(ti->task->blocked_on != waiter);
+	ti->task->blocked_on = NULL;
+
+	list_del_init(&waiter->list);
+	waiter->task = NULL;
+}
+
+void debug_mutex_unlock(struct mutex *lock)
+{
+	DEBUG_WARN_ON(lock->magic != lock);
+	DEBUG_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next);
+	DEBUG_WARN_ON(lock->owner != current_thread_info());
+	if (debug_mutex_on) {
+		DEBUG_WARN_ON(list_empty(&lock->held_list));
+		list_del_init(&lock->held_list);
+	}
+}
+
+void debug_mutex_init(struct mutex *lock, const char *name)
+{
+	/*
+	 * Make sure we are not reinitializing a held lock:
+	 */
+	mutex_debug_check_no_locks_freed((void *)lock, (void *)(lock + 1));
+	lock->owner = NULL;
+	INIT_LIST_HEAD(&lock->held_list);
+	lock->name = name;
+	lock->magic = lock;
+}
+
+/***
+ * mutex_destroy - mark a mutex unusable
+ * @lock: the mutex to be destroyed
+ *
+ * This function marks the mutex uninitialized, and any subsequent
+ * use of the mutex is forbidden. The mutex must not be locked when
+ * this function is called.
+ */
+void fastcall mutex_destroy(struct mutex *lock)
+{
+	DEBUG_WARN_ON(mutex_is_locked(lock));
+	lock->magic = NULL;
+}
+
+EXPORT_SYMBOL_GPL(mutex_destroy);
+
diff --git a/kernel/mutex-debug.h b/kernel/mutex-debug.h
new file mode 100644
index 0000000..fd38405
--- /dev/null
+++ b/kernel/mutex-debug.h
@@ -0,0 +1,134 @@
+/*
+ * Mutexes: blocking mutual exclusion locks
+ *
+ * started by Ingo Molnar:
+ *
+ *  Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *
+ * This file contains mutex debugging related internal declarations,
+ * prototypes and inline functions, for the CONFIG_DEBUG_MUTEXES case.
+ * More details are in kernel/mutex-debug.c.
+ */
+
+extern spinlock_t debug_mutex_lock;
+extern struct list_head debug_mutex_held_locks;
+extern int debug_mutex_on;
+
+/*
+ * In the debug case we carry the caller's instruction pointer into
+ * other functions, but we dont want the function argument overhead
+ * in the nondebug case - hence these macros:
+ */
+#define __IP_DECL__		, unsigned long ip
+#define __IP__			, ip
+#define __RET_IP__		, (unsigned long)__builtin_return_address(0)
+
+/*
+ * This must be called with lock->wait_lock held.
+ */
+extern void debug_mutex_set_owner(struct mutex *lock,
+				  struct thread_info *new_owner __IP_DECL__);
+
+static inline void debug_mutex_clear_owner(struct mutex *lock)
+{
+	lock->owner = NULL;
+}
+
+extern void debug_mutex_init_waiter(struct mutex_waiter *waiter);
+extern void debug_mutex_wake_waiter(struct mutex *lock,
+				    struct mutex_waiter *waiter);
+extern void debug_mutex_free_waiter(struct mutex_waiter *waiter);
+extern void debug_mutex_add_waiter(struct mutex *lock,
+				   struct mutex_waiter *waiter,
+				   struct thread_info *ti __IP_DECL__);
+extern void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter,
+				struct thread_info *ti);
+extern void debug_mutex_unlock(struct mutex *lock);
+extern void debug_mutex_init(struct mutex *lock, const char *name);
+
+#define debug_spin_lock(lock)				\
+	do {						\
+		local_irq_disable();			\
+		if (debug_mutex_on)			\
+			spin_lock(lock);		\
+	} while (0)
+
+#define debug_spin_unlock(lock)				\
+	do {						\
+		if (debug_mutex_on)			\
+			spin_unlock(lock);		\
+		local_irq_enable();			\
+		preempt_check_resched();		\
+	} while (0)
+
+#define debug_spin_lock_save(lock, flags)		\
+	do {						\
+		local_irq_save(flags);			\
+		if (debug_mutex_on)			\
+			spin_lock(lock);		\
+	} while (0)
+
+#define debug_spin_lock_restore(lock, flags)		\
+	do {						\
+		if (debug_mutex_on)			\
+			spin_unlock(lock);		\
+		local_irq_restore(flags);		\
+		preempt_check_resched();		\
+	} while (0)
+
+#define spin_lock_mutex(lock)				\
+	do {						\
+		struct mutex *l = container_of(lock, struct mutex, wait_lock); \
+							\
+		DEBUG_WARN_ON(in_interrupt());		\
+		debug_spin_lock(&debug_mutex_lock);	\
+		spin_lock(lock);			\
+		DEBUG_WARN_ON(l->magic != l);		\
+	} while (0)
+
+#define spin_unlock_mutex(lock)				\
+	do {						\
+		spin_unlock(lock);			\
+		debug_spin_unlock(&debug_mutex_lock);	\
+	} while (0)
+
+#define DEBUG_OFF()					\
+do {							\
+	if (debug_mutex_on) {				\
+		debug_mutex_on = 0;			\
+		console_verbose();			\
+		if (spin_is_locked(&debug_mutex_lock))	\
+			spin_unlock(&debug_mutex_lock);	\
+	}						\
+} while (0)
+
+#define DEBUG_BUG()					\
+do {							\
+	if (debug_mutex_on) {				\
+		DEBUG_OFF();				\
+		BUG();					\
+	}						\
+} while (0)
+
+#define DEBUG_WARN_ON(c)				\
+do {							\
+	if (unlikely(c && debug_mutex_on)) {		\
+		DEBUG_OFF();				\
+		WARN_ON(1);				\
+	}						\
+} while (0)
+
+# define DEBUG_BUG_ON(c)				\
+do {							\
+	if (unlikely(c))				\
+		DEBUG_BUG();				\
+} while (0)
+
+#ifdef CONFIG_SMP
+# define SMP_DEBUG_WARN_ON(c)			DEBUG_WARN_ON(c)
+# define SMP_DEBUG_BUG_ON(c)			DEBUG_BUG_ON(c)
+#else
+# define SMP_DEBUG_WARN_ON(c)			do { } while (0)
+# define SMP_DEBUG_BUG_ON(c)			do { } while (0)
+#endif
+
diff --git a/kernel/mutex.c b/kernel/mutex.c
new file mode 100644
index 0000000..7eb9606
--- /dev/null
+++ b/kernel/mutex.c
@@ -0,0 +1,325 @@
+/*
+ * kernel/mutex.c
+ *
+ * Mutexes: blocking mutual exclusion locks
+ *
+ * Started by Ingo Molnar:
+ *
+ *  Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *
+ * Many thanks to Arjan van de Ven, Thomas Gleixner, Steven Rostedt and
+ * David Howells for suggestions and improvements.
+ *
+ * Also see Documentation/mutex-design.txt.
+ */
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+
+/*
+ * In the DEBUG case we are using the "NULL fastpath" for mutexes,
+ * which forces all calls into the slowpath:
+ */
+#ifdef CONFIG_DEBUG_MUTEXES
+# include "mutex-debug.h"
+# include <asm-generic/mutex-null.h>
+#else
+# include "mutex.h"
+# include <asm/mutex.h>
+#endif
+
+/***
+ * mutex_init - initialize the mutex
+ * @lock: the mutex to be initialized
+ *
+ * Initialize the mutex to unlocked state.
+ *
+ * It is not allowed to initialize an already locked mutex.
+ */
+void fastcall __mutex_init(struct mutex *lock, const char *name)
+{
+	atomic_set(&lock->count, 1);
+	spin_lock_init(&lock->wait_lock);
+	INIT_LIST_HEAD(&lock->wait_list);
+
+	debug_mutex_init(lock, name);
+}
+
+EXPORT_SYMBOL(__mutex_init);
+
+/*
+ * We split the mutex lock/unlock logic into separate fastpath and
+ * slowpath functions, to reduce the register pressure on the fastpath.
+ * We also put the fastpath first in the kernel image, to make sure the
+ * branch is predicted by the CPU as default-untaken.
+ */
+static void fastcall noinline __sched
+__mutex_lock_slowpath(atomic_t *lock_count __IP_DECL__);
+
+/***
+ * mutex_lock - acquire the mutex
+ * @lock: the mutex to be acquired
+ *
+ * Lock the mutex exclusively for this task. If the mutex is not
+ * available right now, it will sleep until it can get it.
+ *
+ * The mutex must later on be released by the same task that
+ * acquired it. Recursive locking is not allowed. The task
+ * may not exit without first unlocking the mutex. Also, kernel
+ * memory where the mutex resides mutex must not be freed with
+ * the mutex still locked. The mutex must first be initialized
+ * (or statically defined) before it can be locked. memset()-ing
+ * the mutex to 0 is not allowed.
+ *
+ * ( The CONFIG_DEBUG_MUTEXES .config option turns on debugging
+ *   checks that will enforce the restrictions and will also do
+ *   deadlock debugging. )
+ *
+ * This function is similar to (but not equivalent to) down().
+ */
+void fastcall __sched mutex_lock(struct mutex *lock)
+{
+	/*
+	 * The locking fastpath is the 1->0 transition from
+	 * 'unlocked' into 'locked' state.
+	 *
+	 * NOTE: if asm/mutex.h is included, then some architectures
+	 * rely on mutex_lock() having _no other code_ here but this
+	 * fastpath. That allows the assembly fastpath to do
+	 * tail-merging optimizations. (If you want to put testcode
+	 * here, do it under #ifndef CONFIG_MUTEX_DEBUG.)
+	 */
+	__mutex_fastpath_lock(&lock->count, __mutex_lock_slowpath);
+}
+
+EXPORT_SYMBOL(mutex_lock);
+
+static void fastcall noinline __sched
+__mutex_unlock_slowpath(atomic_t *lock_count __IP_DECL__);
+
+/***
+ * mutex_unlock - release the mutex
+ * @lock: the mutex to be released
+ *
+ * Unlock a mutex that has been locked by this task previously.
+ *
+ * This function must not be used in interrupt context. Unlocking
+ * of a not locked mutex is not allowed.
+ *
+ * This function is similar to (but not equivalent to) up().
+ */
+void fastcall __sched mutex_unlock(struct mutex *lock)
+{
+	/*
+	 * The unlocking fastpath is the 0->1 transition from 'locked'
+	 * into 'unlocked' state:
+	 *
+	 * NOTE: no other code must be here - see mutex_lock() .
+	 */
+	__mutex_fastpath_unlock(&lock->count, __mutex_unlock_slowpath);
+}
+
+EXPORT_SYMBOL(mutex_unlock);
+
+/*
+ * Lock a mutex (possibly interruptible), slowpath:
+ */
+static inline int __sched
+__mutex_lock_common(struct mutex *lock, long state __IP_DECL__)
+{
+	struct task_struct *task = current;
+	struct mutex_waiter waiter;
+	unsigned int old_val;
+
+	debug_mutex_init_waiter(&waiter);
+
+	spin_lock_mutex(&lock->wait_lock);
+
+	debug_mutex_add_waiter(lock, &waiter, task->thread_info, ip);
+
+	/* add waiting tasks to the end of the waitqueue (FIFO): */
+	list_add_tail(&waiter.list, &lock->wait_list);
+	waiter.task = task;
+
+	for (;;) {
+		/*
+		 * Lets try to take the lock again - this is needed even if
+		 * we get here for the first time (shortly after failing to
+		 * acquire the lock), to make sure that we get a wakeup once
+		 * it's unlocked. Later on, if we sleep, this is the
+		 * operation that gives us the lock. We xchg it to -1, so
+		 * that when we release the lock, we properly wake up the
+		 * other waiters:
+		 */
+		old_val = atomic_xchg(&lock->count, -1);
+		if (old_val == 1)
+			break;
+
+		/*
+		 * got a signal? (This code gets eliminated in the
+		 * TASK_UNINTERRUPTIBLE case.)
+		 */
+		if (unlikely(state == TASK_INTERRUPTIBLE &&
+						signal_pending(task))) {
+			mutex_remove_waiter(lock, &waiter, task->thread_info);
+			spin_unlock_mutex(&lock->wait_lock);
+
+			debug_mutex_free_waiter(&waiter);
+			return -EINTR;
+		}
+		__set_task_state(task, state);
+
+		/* didnt get the lock, go to sleep: */
+		spin_unlock_mutex(&lock->wait_lock);
+		schedule();
+		spin_lock_mutex(&lock->wait_lock);
+	}
+
+	/* got the lock - rejoice! */
+	mutex_remove_waiter(lock, &waiter, task->thread_info);
+	debug_mutex_set_owner(lock, task->thread_info __IP__);
+
+	/* set it to 0 if there are no waiters left: */
+	if (likely(list_empty(&lock->wait_list)))
+		atomic_set(&lock->count, 0);
+
+	spin_unlock_mutex(&lock->wait_lock);
+
+	debug_mutex_free_waiter(&waiter);
+
+	DEBUG_WARN_ON(list_empty(&lock->held_list));
+	DEBUG_WARN_ON(lock->owner != task->thread_info);
+
+	return 0;
+}
+
+static void fastcall noinline __sched
+__mutex_lock_slowpath(atomic_t *lock_count __IP_DECL__)
+{
+	struct mutex *lock = container_of(lock_count, struct mutex, count);
+
+	__mutex_lock_common(lock, TASK_UNINTERRUPTIBLE __IP__);
+}
+
+/*
+ * Release the lock, slowpath:
+ */
+static fastcall noinline void
+__mutex_unlock_slowpath(atomic_t *lock_count __IP_DECL__)
+{
+        struct mutex *lock = container_of(lock_count, struct mutex, count);
+
+	DEBUG_WARN_ON(lock->owner != current_thread_info());
+
+	spin_lock_mutex(&lock->wait_lock);
+
+	/*
+	 * some architectures leave the lock unlocked in the fastpath failure
+	 * case, others need to leave it locked. In the later case we have to
+	 * unlock it here
+	 */
+	if (__mutex_slowpath_needs_to_unlock())
+		atomic_set(&lock->count, 1);
+
+	debug_mutex_unlock(lock);
+
+	if (!list_empty(&lock->wait_list)) {
+		/* get the first entry from the wait-list: */
+		struct mutex_waiter *waiter =
+				list_entry(lock->wait_list.next,
+					   struct mutex_waiter, list);
+
+		debug_mutex_wake_waiter(lock, waiter);
+
+		wake_up_process(waiter->task);
+	}
+
+	debug_mutex_clear_owner(lock);
+
+	spin_unlock_mutex(&lock->wait_lock);
+}
+
+/*
+ * Here come the less common (and hence less performance-critical) APIs:
+ * mutex_lock_interruptible() and mutex_trylock().
+ */
+static int fastcall noinline __sched
+__mutex_lock_interruptible_slowpath(atomic_t *lock_count __IP_DECL__);
+
+/***
+ * mutex_lock_interruptible - acquire the mutex, interruptable
+ * @lock: the mutex to be acquired
+ *
+ * Lock the mutex like mutex_lock(), and return 0 if the mutex has
+ * been acquired or sleep until the mutex becomes available. If a
+ * signal arrives while waiting for the lock then this function
+ * returns -EINTR.
+ *
+ * This function is similar to (but not equivalent to) down_interruptible().
+ */
+int fastcall __sched mutex_lock_interruptible(struct mutex *lock)
+{
+	/* NOTE: no other code must be here - see mutex_lock() */
+	return __mutex_fastpath_lock_retval
+			(&lock->count, __mutex_lock_interruptible_slowpath);
+}
+
+EXPORT_SYMBOL(mutex_lock_interruptible);
+
+static int fastcall noinline __sched
+__mutex_lock_interruptible_slowpath(atomic_t *lock_count __IP_DECL__)
+{
+	struct mutex *lock = container_of(lock_count, struct mutex, count);
+
+	return __mutex_lock_common(lock, TASK_INTERRUPTIBLE __IP__);
+}
+
+/*
+ * Spinlock based trylock, we take the spinlock and check whether we
+ * can get the lock:
+ */
+static inline int __mutex_trylock_slowpath(atomic_t *lock_count)
+{
+	struct mutex *lock = container_of(lock_count, struct mutex, count);
+	int prev;
+
+	spin_lock_mutex(&lock->wait_lock);
+
+	prev = atomic_xchg(&lock->count, -1);
+	if (likely(prev == 1))
+		debug_mutex_set_owner(lock, current_thread_info() __RET_IP__);
+	/* Set it back to 0 if there are no waiters: */
+	if (likely(list_empty(&lock->wait_list)))
+		atomic_set(&lock->count, 0);
+
+	spin_unlock_mutex(&lock->wait_lock);
+
+	return prev == 1;
+}
+
+/***
+ * mutex_trylock - try acquire the mutex, without waiting
+ * @lock: the mutex to be acquired
+ *
+ * Try to acquire the mutex atomically. Returns 1 if the mutex
+ * has been acquired successfully, and 0 on contention.
+ *
+ * NOTE: this function follows the spin_trylock() convention, so
+ * it is negated to the down_trylock() return values! Be careful
+ * about this when converting semaphore users to mutexes.
+ *
+ * This function must not be used in interrupt context. The
+ * mutex must be released by the same task that acquired it.
+ */
+int fastcall mutex_trylock(struct mutex *lock)
+{
+	return __mutex_fastpath_trylock(&lock->count,
+					__mutex_trylock_slowpath);
+}
+
+EXPORT_SYMBOL(mutex_trylock);
+
+
+
diff --git a/kernel/mutex.h b/kernel/mutex.h
new file mode 100644
index 0000000..00fe84e
--- /dev/null
+++ b/kernel/mutex.h
@@ -0,0 +1,35 @@
+/*
+ * Mutexes: blocking mutual exclusion locks
+ *
+ * started by Ingo Molnar:
+ *
+ *  Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *
+ * This file contains mutex debugging related internal prototypes, for the
+ * !CONFIG_DEBUG_MUTEXES case. Most of them are NOPs:
+ */
+
+#define spin_lock_mutex(lock)			spin_lock(lock)
+#define spin_unlock_mutex(lock)			spin_unlock(lock)
+#define mutex_remove_waiter(lock, waiter, ti) \
+		__list_del((waiter)->list.prev, (waiter)->list.next)
+
+#define DEBUG_WARN_ON(c)				do { } while (0)
+#define debug_mutex_set_owner(lock, new_owner)		do { } while (0)
+#define debug_mutex_clear_owner(lock)			do { } while (0)
+#define debug_mutex_init_waiter(waiter)			do { } while (0)
+#define debug_mutex_wake_waiter(lock, waiter)		do { } while (0)
+#define debug_mutex_free_waiter(waiter)			do { } while (0)
+#define debug_mutex_add_waiter(lock, waiter, ti, ip)	do { } while (0)
+#define debug_mutex_unlock(lock)			do { } while (0)
+#define debug_mutex_init(lock, name)			do { } while (0)
+
+/*
+ * Return-address parameters/declarations. They are very useful for
+ * debugging, but add overhead in the !DEBUG case - so we go the
+ * trouble of using this not too elegant but zero-cost solution:
+ */
+#define __IP_DECL__
+#define __IP__
+#define __RET_IP__
+
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index ccc45d4..05ee483 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -236,12 +236,8 @@
  * active batch and the batch to be registered has not already occurred.
  * Caller must hold rcu_state.lock.
  */
-static void rcu_start_batch(struct rcu_ctrlblk *rcp, struct rcu_state *rsp,
-				int next_pending)
+static void rcu_start_batch(struct rcu_ctrlblk *rcp, struct rcu_state *rsp)
 {
-	if (next_pending)
-		rcp->next_pending = 1;
-
 	if (rcp->next_pending &&
 			rcp->completed == rcp->cur) {
 		rcp->next_pending = 0;
@@ -275,7 +271,7 @@
 	if (cpus_empty(rsp->cpumask)) {
 		/* batch completed ! */
 		rcp->completed = rcp->cur;
-		rcu_start_batch(rcp, rsp, 0);
+		rcu_start_batch(rcp, rsp);
 	}
 }
 
@@ -410,7 +406,8 @@
 		if (!rcp->next_pending) {
 			/* and start it/schedule start if it's a new batch */
 			spin_lock(&rsp->lock);
-			rcu_start_batch(rcp, rsp, 1);
+			rcp->next_pending = 1;
+			rcu_start_batch(rcp, rsp);
 			spin_unlock(&rsp->lock);
 		}
 	} else {
diff --git a/kernel/sched.c b/kernel/sched.c
index 9273309..34a945b 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4386,6 +4386,7 @@
 	} while_each_thread(g, p);
 
 	read_unlock(&tasklist_lock);
+	mutex_debug_show_all_locks();
 }
 
 /**
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index c48260f..1fcd856 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -95,6 +95,14 @@
 	  if kernel code uses it in a preemption-unsafe way. Also, the kernel
 	  will detect preemption count underflows.
 
+config DEBUG_MUTEXES
+	bool "Mutex debugging, deadlock detection"
+	default y
+	depends on DEBUG_KERNEL
+	help
+	 This allows mutex semantics violations and mutex related deadlocks
+	 (lockups) to be detected and reported automatically.
+
 config DEBUG_SPINLOCK
 	bool "Spinlock debugging"
 	depends on DEBUG_KERNEL
diff --git a/mm/filemap.c b/mm/filemap.c
index 478f4c7..5fca273 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -61,7 +61,7 @@
  *      ->swap_lock		(exclusive_swap_page, others)
  *        ->mapping->tree_lock
  *
- *  ->i_sem
+ *  ->i_mutex
  *    ->i_mmap_lock		(truncate->unmap_mapping_range)
  *
  *  ->mmap_sem
@@ -73,9 +73,9 @@
  *    ->lock_page		(access_process_vm)
  *
  *  ->mmap_sem
- *    ->i_sem			(msync)
+ *    ->i_mutex			(msync)
  *
- *  ->i_sem
+ *  ->i_mutex
  *    ->i_alloc_sem             (various)
  *
  *  ->inode_lock
@@ -276,7 +276,7 @@
  * integrity" operation.  It waits upon in-flight writeout before starting and
  * waiting upon new writeout.  If there was an IO error, return it.
  *
- * We need to re-take i_sem during the generic_osync_inode list walk because
+ * We need to re-take i_mutex during the generic_osync_inode list walk because
  * it is otherwise livelockable.
  */
 int sync_page_range(struct inode *inode, struct address_space *mapping,
@@ -290,9 +290,9 @@
 		return 0;
 	ret = filemap_fdatawrite_range(mapping, pos, pos + count - 1);
 	if (ret == 0) {
-		down(&inode->i_sem);
+		mutex_lock(&inode->i_mutex);
 		ret = generic_osync_inode(inode, mapping, OSYNC_METADATA);
-		up(&inode->i_sem);
+		mutex_unlock(&inode->i_mutex);
 	}
 	if (ret == 0)
 		ret = wait_on_page_writeback_range(mapping, start, end);
@@ -301,7 +301,7 @@
 EXPORT_SYMBOL(sync_page_range);
 
 /*
- * Note: Holding i_sem across sync_page_range_nolock is not a good idea
+ * Note: Holding i_mutex across sync_page_range_nolock is not a good idea
  * as it forces O_SYNC writers to different parts of the same file
  * to be serialised right until io completion.
  */
@@ -1892,7 +1892,7 @@
 	/*
 	 * Sync the fs metadata but not the minor inode changes and
 	 * of course not the data as we did direct DMA for the IO.
-	 * i_sem is held, which protects generic_osync_inode() from
+	 * i_mutex is held, which protects generic_osync_inode() from
 	 * livelocking.
 	 */
 	if (written >= 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
@@ -2195,10 +2195,10 @@
 
 	BUG_ON(iocb->ki_pos != pos);
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	ret = __generic_file_aio_write_nolock(iocb, &local_iov, 1,
 						&iocb->ki_pos);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 
 	if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
 		ssize_t err;
@@ -2220,9 +2220,9 @@
 	struct iovec local_iov = { .iov_base = (void __user *)buf,
 					.iov_len = count };
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	ret = __generic_file_write_nolock(file, &local_iov, 1, ppos);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 
 	if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
 		ssize_t err;
@@ -2256,9 +2256,9 @@
 	struct inode *inode = mapping->host;
 	ssize_t ret;
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	ret = __generic_file_write_nolock(file, iov, nr_segs, ppos);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 
 	if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
 		int err;
@@ -2272,7 +2272,7 @@
 EXPORT_SYMBOL(generic_file_writev);
 
 /*
- * Called under i_sem for writes to S_ISREG files.   Returns -EIO if something
+ * Called under i_mutex for writes to S_ISREG files.   Returns -EIO if something
  * went wrong during pagecache shootdown.
  */
 static ssize_t
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
index 9cf687e..e2b34e9 100644
--- a/mm/filemap_xip.c
+++ b/mm/filemap_xip.c
@@ -338,7 +338,7 @@
 	*ppos = pos;
 	/*
 	 * No need to use i_size_read() here, the i_size
-	 * cannot change under us because we hold i_sem.
+	 * cannot change under us because we hold i_mutex.
 	 */
 	if (pos > inode->i_size) {
 		i_size_write(inode, pos);
@@ -358,7 +358,7 @@
 	loff_t pos;
 	ssize_t ret;
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 
 	if (!access_ok(VERIFY_READ, buf, len)) {
 		ret=-EFAULT;
@@ -390,7 +390,7 @@
  out_backing:
 	current->backing_dev_info = NULL;
  out_up:
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(xip_file_write);
diff --git a/mm/memory.c b/mm/memory.c
index 3944fec..7a11ddd 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1784,13 +1784,13 @@
 	if (!inode->i_op || !inode->i_op->truncate_range)
 		return -ENOSYS;
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	down_write(&inode->i_alloc_sem);
 	unmap_mapping_range(mapping, offset, (end - offset), 1);
 	truncate_inode_pages_range(mapping, offset, end);
 	inode->i_op->truncate_range(inode, offset, end);
 	up_write(&inode->i_alloc_sem);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 
 	return 0;
 }
diff --git a/mm/msync.c b/mm/msync.c
index 1b5b6f6..3563a56 100644
--- a/mm/msync.c
+++ b/mm/msync.c
@@ -137,7 +137,7 @@
 			ret = filemap_fdatawrite(mapping);
 			if (file->f_op && file->f_op->fsync) {
 				/*
-				 * We don't take i_sem here because mmap_sem
+				 * We don't take i_mutex here because mmap_sem
 				 * is already held.
 				 */
 				err = file->f_op->fsync(file,file->f_dentry,1);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index e0e8492..a5e6891 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -415,6 +415,9 @@
 	int reserved = 0;
 
 	arch_free_page(page, order);
+	if (!PageHighMem(page))
+		mutex_debug_check_no_locks_freed(page_address(page),
+			page_address(page+(1<<order)));
 
 #ifndef CONFIG_MMU
 	for (i = 1 ; i < (1 << order) ; ++i)
diff --git a/mm/rmap.c b/mm/rmap.c
index 66ec430..dfbb89f 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -20,13 +20,13 @@
 /*
  * Lock ordering in mm:
  *
- * inode->i_sem	(while writing or truncating, not reading or faulting)
+ * inode->i_mutex	(while writing or truncating, not reading or faulting)
  *   inode->i_alloc_sem
  *
  * When a page fault occurs in writing from user to file, down_read
- * of mmap_sem nests within i_sem; in sys_msync, i_sem nests within
- * down_read of mmap_sem; i_sem and down_write of mmap_sem are never
- * taken together; in truncation, i_sem is taken outermost.
+ * of mmap_sem nests within i_mutex; in sys_msync, i_mutex nests within
+ * down_read of mmap_sem; i_mutex and down_write of mmap_sem are never
+ * taken together; in truncation, i_mutex is taken outermost.
  *
  * mm->mmap_sem
  *   page->flags PG_locked (lock_page)
diff --git a/mm/shmem.c b/mm/shmem.c
index a1f2f02..343b3c0 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1370,7 +1370,7 @@
 	if (!access_ok(VERIFY_READ, buf, count))
 		return -EFAULT;
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 
 	pos = *ppos;
 	written = 0;
@@ -1455,7 +1455,7 @@
 	if (written)
 		err = written;
 out:
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	return err;
 }
 
@@ -1491,7 +1491,7 @@
 
 		/*
 		 * We must evaluate after, since reads (unlike writes)
-		 * are called without i_sem protection against truncate
+		 * are called without i_mutex protection against truncate
 		 */
 		nr = PAGE_CACHE_SIZE;
 		i_size = i_size_read(inode);
diff --git a/mm/slab.c b/mm/slab.c
index 1c46c63..33aab34 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3071,6 +3071,7 @@
 	local_irq_save(flags);
 	kfree_debugcheck(objp);
 	c = page_get_cache(virt_to_page(objp));
+	mutex_debug_check_no_locks_freed(objp, objp+obj_reallen(c));
 	__cache_free(c, (void *)objp);
 	local_irq_restore(flags);
 }
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 80f948a..6544565 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1187,9 +1187,9 @@
 		set_blocksize(bdev, p->old_block_size);
 		bd_release(bdev);
 	} else {
-		down(&inode->i_sem);
+		mutex_lock(&inode->i_mutex);
 		inode->i_flags &= ~S_SWAPFILE;
-		up(&inode->i_sem);
+		mutex_unlock(&inode->i_mutex);
 	}
 	filp_close(swap_file, NULL);
 	err = 0;
@@ -1406,7 +1406,7 @@
 		p->bdev = bdev;
 	} else if (S_ISREG(inode->i_mode)) {
 		p->bdev = inode->i_sb->s_bdev;
-		down(&inode->i_sem);
+		mutex_lock(&inode->i_mutex);
 		did_down = 1;
 		if (IS_SWAPFILE(inode)) {
 			error = -EBUSY;
@@ -1596,7 +1596,7 @@
 	if (did_down) {
 		if (!error)
 			inode->i_flags |= S_SWAPFILE;
-		up(&inode->i_sem);
+		mutex_unlock(&inode->i_mutex);
 	}
 	return error;
 }
diff --git a/mm/truncate.c b/mm/truncate.c
index b1a463d..6cb3fff 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -196,7 +196,7 @@
  * @mapping: mapping to truncate
  * @lstart: offset from which to truncate
  *
- * Called under (and serialised by) inode->i_sem.
+ * Called under (and serialised by) inode->i_mutex.
  */
 void truncate_inode_pages(struct address_space *mapping, loff_t lstart)
 {
diff --git a/net/core/dev.c b/net/core/dev.c
index 5081287..bf66b11 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1092,15 +1092,12 @@
 			goto out;
 	}
 
-	if (offset > (int)skb->len)
-		BUG();
+	BUG_ON(offset > (int)skb->len);
 	csum = skb_checksum(skb, offset, skb->len-offset, 0);
 
 	offset = skb->tail - skb->h.raw;
-	if (offset <= 0)
-		BUG();
-	if (skb->csum + 2 > offset)
-		BUG();
+	BUG_ON(offset <= 0);
+	BUG_ON(skb->csum + 2 > offset);
 
 	*(u16*)(skb->h.raw + skb->csum) = csum_fold(csum);
 	skb->ip_summed = CHECKSUM_NONE;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 070f91c..d0732e9 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -791,8 +791,7 @@
 		int end = offset + skb_shinfo(skb)->frags[i].size;
 		if (end > len) {
 			if (skb_cloned(skb)) {
-				if (!realloc)
-					BUG();
+				BUG_ON(!realloc);
 				if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
 					return -ENOMEM;
 			}
@@ -894,8 +893,7 @@
 		struct sk_buff *insp = NULL;
 
 		do {
-			if (!list)
-				BUG();
+			BUG_ON(!list);
 
 			if (list->len <= eat) {
 				/* Eaten as whole. */
@@ -1199,8 +1197,7 @@
 			start = end;
 		}
 	}
-	if (len)
-		BUG();
+	BUG_ON(len);
 
 	return csum;
 }
@@ -1282,8 +1279,7 @@
 			start = end;
 		}
 	}
-	if (len)
-		BUG();
+	BUG_ON(len);
 	return csum;
 }
 
@@ -1297,8 +1293,7 @@
 	else
 		csstart = skb_headlen(skb);
 
-	if (csstart > skb_headlen(skb))
-		BUG();
+	BUG_ON(csstart > skb_headlen(skb));
 
 	memcpy(to, skb->data, csstart);
 
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index be5a519..105039e 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -899,8 +899,7 @@
 		u32 _mask, *mp;
 
 		mp = skb_header_pointer(skb, 0, sizeof(_mask), &_mask);
-		if (mp == NULL)
-			BUG();
+		BUG_ON(mp == NULL);
 		for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
 			if (*mp == ifa->ifa_mask &&
 			    inet_ifa_match(rt->rt_src, ifa))
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index c499081..457db99 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -50,9 +50,10 @@
 #define INET_DIAG_PUT(skb, attrtype, attrlen) \
 	RTA_DATA(__RTA_PUT(skb, attrtype, attrlen))
 
-static int inet_diag_fill(struct sk_buff *skb, struct sock *sk,
-			int ext, u32 pid, u32 seq, u16 nlmsg_flags,
-			const struct nlmsghdr *unlh)
+static int inet_csk_diag_fill(struct sock *sk,
+			      struct sk_buff *skb,
+			      int ext, u32 pid, u32 seq, u16 nlmsg_flags,
+			      const struct nlmsghdr *unlh)
 {
 	const struct inet_sock *inet = inet_sk(sk);
 	const struct inet_connection_sock *icsk = inet_csk(sk);
@@ -70,20 +71,22 @@
 	nlh->nlmsg_flags = nlmsg_flags;
 
 	r = NLMSG_DATA(nlh);
-	if (sk->sk_state != TCP_TIME_WAIT) {
-		if (ext & (1 << (INET_DIAG_MEMINFO - 1)))
-			minfo = INET_DIAG_PUT(skb, INET_DIAG_MEMINFO,
-					      sizeof(*minfo));
-		if (ext & (1 << (INET_DIAG_INFO - 1)))
-			info = INET_DIAG_PUT(skb, INET_DIAG_INFO,
-					   handler->idiag_info_size);
-		
-		if ((ext & (1 << (INET_DIAG_CONG - 1))) && icsk->icsk_ca_ops) {
-			size_t len = strlen(icsk->icsk_ca_ops->name);
-			strcpy(INET_DIAG_PUT(skb, INET_DIAG_CONG, len + 1),
-			       icsk->icsk_ca_ops->name);
-		}
+	BUG_ON(sk->sk_state == TCP_TIME_WAIT);
+
+	if (ext & (1 << (INET_DIAG_MEMINFO - 1)))
+		minfo = INET_DIAG_PUT(skb, INET_DIAG_MEMINFO, sizeof(*minfo));
+
+	if (ext & (1 << (INET_DIAG_INFO - 1)))
+		info = INET_DIAG_PUT(skb, INET_DIAG_INFO,
+				     handler->idiag_info_size);
+
+	if ((ext & (1 << (INET_DIAG_CONG - 1))) && icsk->icsk_ca_ops) {
+		const size_t len = strlen(icsk->icsk_ca_ops->name);
+
+		strcpy(INET_DIAG_PUT(skb, INET_DIAG_CONG, len + 1),
+		       icsk->icsk_ca_ops->name);
 	}
+
 	r->idiag_family = sk->sk_family;
 	r->idiag_state = sk->sk_state;
 	r->idiag_timer = 0;
@@ -93,37 +96,6 @@
 	r->id.idiag_cookie[0] = (u32)(unsigned long)sk;
 	r->id.idiag_cookie[1] = (u32)(((unsigned long)sk >> 31) >> 1);
 
-	if (r->idiag_state == TCP_TIME_WAIT) {
-		const struct inet_timewait_sock *tw = inet_twsk(sk);
-		long tmo = tw->tw_ttd - jiffies;
-		if (tmo < 0)
-			tmo = 0;
-
-		r->id.idiag_sport = tw->tw_sport;
-		r->id.idiag_dport = tw->tw_dport;
-		r->id.idiag_src[0] = tw->tw_rcv_saddr;
-		r->id.idiag_dst[0] = tw->tw_daddr;
-		r->idiag_state = tw->tw_substate;
-		r->idiag_timer = 3;
-		r->idiag_expires = (tmo * 1000 + HZ - 1) / HZ;
-		r->idiag_rqueue = 0;
-		r->idiag_wqueue = 0;
-		r->idiag_uid = 0;
-		r->idiag_inode = 0;
-#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-		if (r->idiag_family == AF_INET6) {
-			const struct inet6_timewait_sock *tw6 = inet6_twsk(sk);
-
-			ipv6_addr_copy((struct in6_addr *)r->id.idiag_src,
-				       &tw6->tw_v6_rcv_saddr);
-			ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst,
-				       &tw6->tw_v6_daddr);
-		}
-#endif
-		nlh->nlmsg_len = skb->tail - b;
-		return skb->len;
-	}
-
 	r->id.idiag_sport = inet->sport;
 	r->id.idiag_dport = inet->dport;
 	r->id.idiag_src[0] = inet->rcv_saddr;
@@ -185,7 +157,75 @@
 	return -1;
 }
 
-static int inet_diag_get_exact(struct sk_buff *in_skb, const struct nlmsghdr *nlh)
+static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
+			       struct sk_buff *skb, int ext, u32 pid,
+			       u32 seq, u16 nlmsg_flags,
+			       const struct nlmsghdr *unlh)
+{
+	long tmo;
+	struct inet_diag_msg *r;
+	const unsigned char *previous_tail = skb->tail;
+	struct nlmsghdr *nlh = NLMSG_PUT(skb, pid, seq,
+					 unlh->nlmsg_type, sizeof(*r));
+
+	r = NLMSG_DATA(nlh);
+	BUG_ON(tw->tw_state != TCP_TIME_WAIT);
+
+	nlh->nlmsg_flags = nlmsg_flags;
+
+	tmo = tw->tw_ttd - jiffies;
+	if (tmo < 0)
+		tmo = 0;
+
+	r->idiag_family	      = tw->tw_family;
+	r->idiag_state	      = tw->tw_state;
+	r->idiag_timer	      = 0;
+	r->idiag_retrans      = 0;
+	r->id.idiag_if	      = tw->tw_bound_dev_if;
+	r->id.idiag_cookie[0] = (u32)(unsigned long)tw;
+	r->id.idiag_cookie[1] = (u32)(((unsigned long)tw >> 31) >> 1);
+	r->id.idiag_sport     = tw->tw_sport;
+	r->id.idiag_dport     = tw->tw_dport;
+	r->id.idiag_src[0]    = tw->tw_rcv_saddr;
+	r->id.idiag_dst[0]    = tw->tw_daddr;
+	r->idiag_state	      = tw->tw_substate;
+	r->idiag_timer	      = 3;
+	r->idiag_expires      = (tmo * 1000 + HZ - 1) / HZ;
+	r->idiag_rqueue	      = 0;
+	r->idiag_wqueue	      = 0;
+	r->idiag_uid	      = 0;
+	r->idiag_inode	      = 0;
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+	if (tw->tw_family == AF_INET6) {
+		const struct inet6_timewait_sock *tw6 =
+						inet6_twsk((struct sock *)tw);
+
+		ipv6_addr_copy((struct in6_addr *)r->id.idiag_src,
+			       &tw6->tw_v6_rcv_saddr);
+		ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst,
+			       &tw6->tw_v6_daddr);
+	}
+#endif
+	nlh->nlmsg_len = skb->tail - previous_tail;
+	return skb->len;
+nlmsg_failure:
+	skb_trim(skb, previous_tail - skb->data);
+	return -1;
+}
+
+static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
+			int ext, u32 pid, u32 seq, u16 nlmsg_flags,
+			const struct nlmsghdr *unlh)
+{
+	if (sk->sk_state == TCP_TIME_WAIT)
+		return inet_twsk_diag_fill((struct inet_timewait_sock *)sk,
+					   skb, ext, pid, seq, nlmsg_flags,
+					   unlh);
+	return inet_csk_diag_fill(sk, skb, ext, pid, seq, nlmsg_flags, unlh);
+}
+
+static int inet_diag_get_exact(struct sk_buff *in_skb,
+			       const struct nlmsghdr *nlh)
 {
 	int err;
 	struct sock *sk;
@@ -235,7 +275,7 @@
 	if (!rep)
 		goto out;
 
-	if (inet_diag_fill(rep, sk, req->idiag_ext,
+	if (sk_diag_fill(sk, rep, req->idiag_ext,
 			 NETLINK_CB(in_skb).pid,
 			 nlh->nlmsg_seq, 0, nlh) <= 0)
 		BUG();
@@ -283,7 +323,7 @@
 
 
 static int inet_diag_bc_run(const void *bc, int len,
-			  const struct inet_diag_entry *entry)
+			    const struct inet_diag_entry *entry)
 {
 	while (len > 0) {
 		int yes = 1;
@@ -322,7 +362,7 @@
 				yes = 0;
 				break;
 			}
-			
+
 			if (cond->prefix_len == 0)
 				break;
 
@@ -331,7 +371,8 @@
 			else
 				addr = entry->daddr;
 
-			if (bitstring_match(addr, cond->addr, cond->prefix_len))
+			if (bitstring_match(addr, cond->addr,
+					    cond->prefix_len))
 				break;
 			if (entry->family == AF_INET6 &&
 			    cond->family == AF_INET) {
@@ -346,7 +387,7 @@
 		}
 		}
 
-		if (yes) { 
+		if (yes) {
 			len -= op->yes;
 			bc += op->yes;
 		} else {
@@ -407,14 +448,15 @@
 		default:
 			return -EINVAL;
 		}
-		bc += op->yes;
+		bc  += op->yes;
 		len -= op->yes;
 	}
 	return len == 0 ? 0 : -EINVAL;
 }
 
-static int inet_diag_dump_sock(struct sk_buff *skb, struct sock *sk,
-			     struct netlink_callback *cb)
+static int inet_csk_diag_dump(struct sock *sk,
+			      struct sk_buff *skb,
+			      struct netlink_callback *cb)
 {
 	struct inet_diag_req *r = NLMSG_DATA(cb->nlh);
 
@@ -444,14 +486,50 @@
 			return 0;
 	}
 
-	return inet_diag_fill(skb, sk, r->idiag_ext, NETLINK_CB(cb->skb).pid,
-			    cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
+	return inet_csk_diag_fill(sk, skb, r->idiag_ext,
+				  NETLINK_CB(cb->skb).pid,
+				  cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
+}
+
+static int inet_twsk_diag_dump(struct inet_timewait_sock *tw,
+			       struct sk_buff *skb,
+			       struct netlink_callback *cb)
+{
+	struct inet_diag_req *r = NLMSG_DATA(cb->nlh);
+
+	if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) {
+		struct inet_diag_entry entry;
+		struct rtattr *bc = (struct rtattr *)(r + 1);
+
+		entry.family = tw->tw_family;
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+		if (tw->tw_family == AF_INET6) {
+			struct inet6_timewait_sock *tw6 =
+						inet6_twsk((struct sock *)tw);
+			entry.saddr = tw6->tw_v6_rcv_saddr.s6_addr32;
+			entry.daddr = tw6->tw_v6_daddr.s6_addr32;
+		} else
+#endif
+		{
+			entry.saddr = &tw->tw_rcv_saddr;
+			entry.daddr = &tw->tw_daddr;
+		}
+		entry.sport = tw->tw_num;
+		entry.dport = ntohs(tw->tw_dport);
+		entry.userlocks = 0; 
+
+		if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry))
+			return 0;
+	}
+
+	return inet_twsk_diag_fill(tw, skb, r->idiag_ext,
+				   NETLINK_CB(cb->skb).pid,
+				   cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh);
 }
 
 static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk,
-			    struct request_sock *req,
-			    u32 pid, u32 seq,
-			    const struct nlmsghdr *unlh)
+			      struct request_sock *req, u32 pid, u32 seq,
+			      const struct nlmsghdr *unlh)
 {
 	const struct inet_request_sock *ireq = inet_rsk(req);
 	struct inet_sock *inet = inet_sk(sk);
@@ -504,7 +582,7 @@
 }
 
 static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk,
-			     struct netlink_callback *cb)
+			       struct netlink_callback *cb)
 {
 	struct inet_diag_entry entry;
 	struct inet_diag_req *r = NLMSG_DATA(cb->nlh);
@@ -556,7 +634,7 @@
 					inet6_rsk(req)->loc_addr.s6_addr32 :
 #endif
 					&ireq->loc_addr;
-				entry.daddr = 
+				entry.daddr =
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
 					(entry.family == AF_INET6) ?
 					inet6_rsk(req)->rmt_addr.s6_addr32 :
@@ -599,7 +677,7 @@
 	handler = inet_diag_table[cb->nlh->nlmsg_type];
 	BUG_ON(handler == NULL);
 	hashinfo = handler->idiag_hashinfo;
-		
+
 	s_i = cb->args[1];
 	s_num = num = cb->args[2];
 
@@ -630,7 +708,7 @@
 				    cb->args[3] > 0)
 					goto syn_recv;
 
-				if (inet_diag_dump_sock(skb, sk, cb) < 0) {
+				if (inet_csk_diag_dump(sk, skb, cb) < 0) {
 					inet_listen_unlock(hashinfo);
 					goto done;
 				}
@@ -672,7 +750,6 @@
 			s_num = 0;
 
 		read_lock_bh(&head->lock);
-
 		num = 0;
 		sk_for_each(sk, node, &head->chain) {
 			struct inet_sock *inet = inet_sk(sk);
@@ -684,9 +761,10 @@
 			if (r->id.idiag_sport != inet->sport &&
 			    r->id.idiag_sport)
 				goto next_normal;
-			if (r->id.idiag_dport != inet->dport && r->id.idiag_dport)
+			if (r->id.idiag_dport != inet->dport &&
+			    r->id.idiag_dport)
 				goto next_normal;
-			if (inet_diag_dump_sock(skb, sk, cb) < 0) {
+			if (inet_csk_diag_dump(sk, skb, cb) < 0) {
 				read_unlock_bh(&head->lock);
 				goto done;
 			}
@@ -695,19 +773,20 @@
 		}
 
 		if (r->idiag_states & TCPF_TIME_WAIT) {
-			sk_for_each(sk, node,
+			struct inet_timewait_sock *tw;
+
+			inet_twsk_for_each(tw, node,
 				    &hashinfo->ehash[i + hashinfo->ehash_size].chain) {
-				struct inet_sock *inet = inet_sk(sk);
 
 				if (num < s_num)
 					goto next_dying;
-				if (r->id.idiag_sport != inet->sport &&
+				if (r->id.idiag_sport != tw->tw_sport &&
 				    r->id.idiag_sport)
 					goto next_dying;
-				if (r->id.idiag_dport != inet->dport &&
+				if (r->id.idiag_dport != tw->tw_dport &&
 				    r->id.idiag_dport)
 					goto next_dying;
-				if (inet_diag_dump_sock(skb, sk, cb) < 0) {
+				if (inet_twsk_diag_dump(tw, skb, cb) < 0) {
 					read_unlock_bh(&head->lock);
 					goto done;
 				}
@@ -724,8 +803,7 @@
 	return skb->len;
 }
 
-static __inline__ int
-inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+static inline int inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
 	if (!(nlh->nlmsg_flags&NLM_F_REQUEST))
 		return 0;
@@ -755,9 +833,8 @@
 		}
 		return netlink_dump_start(idiagnl, skb, nlh,
 					  inet_diag_dump, NULL);
-	} else {
+	} else
 		return inet_diag_get_exact(skb, nlh);
-	}
 
 err_inval:
 	return -EINVAL;
@@ -766,15 +843,15 @@
 
 static inline void inet_diag_rcv_skb(struct sk_buff *skb)
 {
-	int err;
-	struct nlmsghdr * nlh;
-
 	if (skb->len >= NLMSG_SPACE(0)) {
-		nlh = (struct nlmsghdr *)skb->data;
-		if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
+		int err;
+		struct nlmsghdr *nlh = (struct nlmsghdr *)skb->data;
+
+		if (nlh->nlmsg_len < sizeof(*nlh) ||
+		    skb->len < nlh->nlmsg_len)
 			return;
 		err = inet_diag_rcv_msg(skb, nlh);
-		if (err || nlh->nlmsg_flags & NLM_F_ACK) 
+		if (err || nlh->nlmsg_flags & NLM_F_ACK)
 			netlink_ack(skb, nlh, err);
 	}
 }
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index ce5fe3f..2160874 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -304,8 +304,7 @@
 			/* look for a node to insert instead of p */
 			struct inet_peer *t;
 			t = lookup_rightempty(p);
-			if (*stackptr[-1] != t)
-				BUG();
+			BUG_ON(*stackptr[-1] != t);
 			**--stackptr = t->avl_left;
 			/* t is removed, t->v4daddr > x->v4daddr for any
 			 * x in p->avl_left subtree.
@@ -314,8 +313,7 @@
 			t->avl_left = p->avl_left;
 			t->avl_right = p->avl_right;
 			t->avl_height = p->avl_height;
-			if (delp[1] != &p->avl_left)
-				BUG();
+			BUG_ON(delp[1] != &p->avl_left);
 			delp[1] = &t->avl_left; /* was &p->avl_left */
 		}
 		peer_avl_rebalance(stack, stackptr);
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index de16e94..1e93eaf 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -188,7 +188,7 @@
 	}
 
 	if (ipgre_fb_tunnel_dev->flags&IFF_UP)
-		return ipgre_fb_tunnel_dev->priv;
+		return netdev_priv(ipgre_fb_tunnel_dev);
 	return NULL;
 }
 
@@ -278,7 +278,7 @@
 	  return NULL;
 
 	dev->init = ipgre_tunnel_init;
-	nt = dev->priv;
+	nt = netdev_priv(dev);
 	nt->parms = *parms;
 
 	if (register_netdevice(dev) < 0) {
@@ -286,9 +286,6 @@
 		goto failed;
 	}
 
-	nt = dev->priv;
-	nt->parms = *parms;
-
 	dev_hold(dev);
 	ipgre_tunnel_link(nt);
 	return nt;
@@ -299,7 +296,7 @@
 
 static void ipgre_tunnel_uninit(struct net_device *dev)
 {
-	ipgre_tunnel_unlink((struct ip_tunnel*)dev->priv);
+	ipgre_tunnel_unlink(netdev_priv(dev));
 	dev_put(dev);
 }
 
@@ -518,7 +515,7 @@
 		skb2->dst->ops->update_pmtu(skb2->dst, rel_info);
 		rel_info = htonl(rel_info);
 	} else if (type == ICMP_TIME_EXCEEDED) {
-		struct ip_tunnel *t = (struct ip_tunnel*)skb2->dev->priv;
+		struct ip_tunnel *t = netdev_priv(skb2->dev);
 		if (t->parms.iph.ttl) {
 			rel_type = ICMP_DEST_UNREACH;
 			rel_code = ICMP_HOST_UNREACH;
@@ -669,7 +666,7 @@
 
 static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv;
+	struct ip_tunnel *tunnel = netdev_priv(dev);
 	struct net_device_stats *stats = &tunnel->stat;
 	struct iphdr  *old_iph = skb->nh.iph;
 	struct iphdr  *tiph;
@@ -915,7 +912,7 @@
 			t = ipgre_tunnel_locate(&p, 0);
 		}
 		if (t == NULL)
-			t = (struct ip_tunnel*)dev->priv;
+			t = netdev_priv(dev);
 		memcpy(&p, &t->parms, sizeof(p));
 		if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
 			err = -EFAULT;
@@ -955,7 +952,7 @@
 			} else {
 				unsigned nflags=0;
 
-				t = (struct ip_tunnel*)dev->priv;
+				t = netdev_priv(dev);
 
 				if (MULTICAST(p.iph.daddr))
 					nflags = IFF_BROADCAST;
@@ -1004,7 +1001,7 @@
 			if ((t = ipgre_tunnel_locate(&p, 0)) == NULL)
 				goto done;
 			err = -EPERM;
-			if (t == ipgre_fb_tunnel_dev->priv)
+			if (t == netdev_priv(ipgre_fb_tunnel_dev))
 				goto done;
 			dev = t->dev;
 		}
@@ -1021,12 +1018,12 @@
 
 static struct net_device_stats *ipgre_tunnel_get_stats(struct net_device *dev)
 {
-	return &(((struct ip_tunnel*)dev->priv)->stat);
+	return &(((struct ip_tunnel*)netdev_priv(dev))->stat);
 }
 
 static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu)
 {
-	struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv;
+	struct ip_tunnel *tunnel = netdev_priv(dev);
 	if (new_mtu < 68 || new_mtu > 0xFFF8 - tunnel->hlen)
 		return -EINVAL;
 	dev->mtu = new_mtu;
@@ -1066,7 +1063,7 @@
 static int ipgre_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
 			void *daddr, void *saddr, unsigned len)
 {
-	struct ip_tunnel *t = (struct ip_tunnel*)dev->priv;
+	struct ip_tunnel *t = netdev_priv(dev);
 	struct iphdr *iph = (struct iphdr *)skb_push(skb, t->hlen);
 	u16 *p = (u16*)(iph+1);
 
@@ -1093,7 +1090,7 @@
 
 static int ipgre_open(struct net_device *dev)
 {
-	struct ip_tunnel *t = (struct ip_tunnel*)dev->priv;
+	struct ip_tunnel *t = netdev_priv(dev);
 
 	if (MULTICAST(t->parms.iph.daddr)) {
 		struct flowi fl = { .oif = t->parms.link,
@@ -1117,7 +1114,7 @@
 
 static int ipgre_close(struct net_device *dev)
 {
-	struct ip_tunnel *t = (struct ip_tunnel*)dev->priv;
+	struct ip_tunnel *t = netdev_priv(dev);
 	if (MULTICAST(t->parms.iph.daddr) && t->mlink) {
 		struct in_device *in_dev = inetdev_by_index(t->mlink);
 		if (in_dev) {
@@ -1157,7 +1154,7 @@
 	int mtu = ETH_DATA_LEN;
 	int addend = sizeof(struct iphdr) + 4;
 
-	tunnel = (struct ip_tunnel*)dev->priv;
+	tunnel = netdev_priv(dev);
 	iph = &tunnel->parms.iph;
 
 	tunnel->dev = dev;
@@ -1221,7 +1218,7 @@
 
 static int __init ipgre_fb_tunnel_init(struct net_device *dev)
 {
-	struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv;
+	struct ip_tunnel *tunnel = netdev_priv(dev);
 	struct iphdr *iph = &tunnel->parms.iph;
 
 	tunnel->dev = dev;
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index c2169b4..3324fbf 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -69,6 +69,7 @@
 #include <net/ip.h>
 #include <net/protocol.h>
 #include <net/route.h>
+#include <net/xfrm.h>
 #include <linux/skbuff.h>
 #include <net/sock.h>
 #include <net/arp.h>
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index bbd85f5..bc5ca23 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -244,7 +244,7 @@
 	if (dev == NULL)
 		return NULL;
 
-	nt = dev->priv;
+	nt = netdev_priv(dev);
 	SET_MODULE_OWNER(dev);
 	dev->init = ipip_tunnel_init;
 	nt->parms = *parms;
@@ -269,7 +269,7 @@
 		tunnels_wc[0] = NULL;
 		write_unlock_bh(&ipip_lock);
 	} else
-		ipip_tunnel_unlink((struct ip_tunnel*)dev->priv);
+		ipip_tunnel_unlink(netdev_priv(dev));
 	dev_put(dev);
 }
 
@@ -443,7 +443,7 @@
 		skb2->dst->ops->update_pmtu(skb2->dst, rel_info);
 		rel_info = htonl(rel_info);
 	} else if (type == ICMP_TIME_EXCEEDED) {
-		struct ip_tunnel *t = (struct ip_tunnel*)skb2->dev->priv;
+		struct ip_tunnel *t = netdev_priv(skb2->dev);
 		if (t->parms.iph.ttl) {
 			rel_type = ICMP_DEST_UNREACH;
 			rel_code = ICMP_HOST_UNREACH;
@@ -514,7 +514,7 @@
 
 static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv;
+	struct ip_tunnel *tunnel = netdev_priv(dev);
 	struct net_device_stats *stats = &tunnel->stat;
 	struct iphdr  *tiph = &tunnel->parms.iph;
 	u8     tos = tunnel->parms.iph.tos;
@@ -674,7 +674,7 @@
 			t = ipip_tunnel_locate(&p, 0);
 		}
 		if (t == NULL)
-			t = (struct ip_tunnel*)dev->priv;
+			t = netdev_priv(dev);
 		memcpy(&p, &t->parms, sizeof(p));
 		if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
 			err = -EFAULT;
@@ -711,7 +711,7 @@
 					err = -EINVAL;
 					break;
 				}
-				t = (struct ip_tunnel*)dev->priv;
+				t = netdev_priv(dev);
 				ipip_tunnel_unlink(t);
 				t->parms.iph.saddr = p.iph.saddr;
 				t->parms.iph.daddr = p.iph.daddr;
@@ -765,7 +765,7 @@
 
 static struct net_device_stats *ipip_tunnel_get_stats(struct net_device *dev)
 {
-	return &(((struct ip_tunnel*)dev->priv)->stat);
+	return &(((struct ip_tunnel*)netdev_priv(dev))->stat);
 }
 
 static int ipip_tunnel_change_mtu(struct net_device *dev, int new_mtu)
@@ -800,7 +800,7 @@
 	struct ip_tunnel *tunnel;
 	struct iphdr *iph;
 
-	tunnel = (struct ip_tunnel*)dev->priv;
+	tunnel = netdev_priv(dev);
 	iph = &tunnel->parms.iph;
 
 	tunnel->dev = dev;
@@ -838,7 +838,7 @@
 
 static int __init ipip_fb_tunnel_init(struct net_device *dev)
 {
-	struct ip_tunnel *tunnel = dev->priv;
+	struct ip_tunnel *tunnel = netdev_priv(dev);
 	struct iphdr *iph = &tunnel->parms.iph;
 
 	tunnel->dev = dev;
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 9a5c0ce..f58ac98 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -178,8 +178,8 @@
 static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	read_lock(&mrt_lock);
-	((struct net_device_stats*)dev->priv)->tx_bytes += skb->len;
-	((struct net_device_stats*)dev->priv)->tx_packets++;
+	((struct net_device_stats*)netdev_priv(dev))->tx_bytes += skb->len;
+	((struct net_device_stats*)netdev_priv(dev))->tx_packets++;
 	ipmr_cache_report(skb, reg_vif_num, IGMPMSG_WHOLEPKT);
 	read_unlock(&mrt_lock);
 	kfree_skb(skb);
@@ -188,7 +188,7 @@
 
 static struct net_device_stats *reg_vif_get_stats(struct net_device *dev)
 {
-	return (struct net_device_stats*)dev->priv;
+	return (struct net_device_stats*)netdev_priv(dev);
 }
 
 static void reg_vif_setup(struct net_device *dev)
@@ -1149,8 +1149,8 @@
 	if (vif->flags & VIFF_REGISTER) {
 		vif->pkt_out++;
 		vif->bytes_out+=skb->len;
-		((struct net_device_stats*)vif->dev->priv)->tx_bytes += skb->len;
-		((struct net_device_stats*)vif->dev->priv)->tx_packets++;
+		((struct net_device_stats*)netdev_priv(vif->dev))->tx_bytes += skb->len;
+		((struct net_device_stats*)netdev_priv(vif->dev))->tx_packets++;
 		ipmr_cache_report(skb, vifi, IGMPMSG_WHOLEPKT);
 		kfree_skb(skb);
 		return;
@@ -1210,8 +1210,8 @@
 	if (vif->flags & VIFF_TUNNEL) {
 		ip_encap(skb, vif->local, vif->remote);
 		/* FIXME: extra output firewall step used to be here. --RR */
-		((struct ip_tunnel *)vif->dev->priv)->stat.tx_packets++;
-		((struct ip_tunnel *)vif->dev->priv)->stat.tx_bytes+=skb->len;
+		((struct ip_tunnel *)netdev_priv(vif->dev))->stat.tx_packets++;
+		((struct ip_tunnel *)netdev_priv(vif->dev))->stat.tx_bytes+=skb->len;
 	}
 
 	IPCB(skb)->flags |= IPSKB_FORWARDED;
@@ -1467,8 +1467,8 @@
 	skb->pkt_type = PACKET_HOST;
 	dst_release(skb->dst);
 	skb->dst = NULL;
-	((struct net_device_stats*)reg_dev->priv)->rx_bytes += skb->len;
-	((struct net_device_stats*)reg_dev->priv)->rx_packets++;
+	((struct net_device_stats*)netdev_priv(reg_dev))->rx_bytes += skb->len;
+	((struct net_device_stats*)netdev_priv(reg_dev))->rx_packets++;
 	nf_reset(skb);
 	netif_rx(skb);
 	dev_put(reg_dev);
@@ -1522,8 +1522,8 @@
 	skb->ip_summed = 0;
 	skb->pkt_type = PACKET_HOST;
 	dst_release(skb->dst);
-	((struct net_device_stats*)reg_dev->priv)->rx_bytes += skb->len;
-	((struct net_device_stats*)reg_dev->priv)->rx_packets++;
+	((struct net_device_stats*)netdev_priv(reg_dev))->rx_bytes += skb->len;
+	((struct net_device_stats*)netdev_priv(reg_dev))->rx_packets++;
 	skb->dst = NULL;
 	nf_reset(skb);
 	netif_rx(skb);
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index e7fa29e..77f3046 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -995,7 +995,7 @@
 		        || (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
 		            && conntrack->proto.tcp.last_index == TCP_ACK_SET))
 		    && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) {
-			/* RST sent to invalid SYN or ACK we had let trough
+			/* RST sent to invalid SYN or ACK we had let through
 			 * at a) and c) above:
 			 *
 			 * a) SYN was in window then
@@ -1006,7 +1006,7 @@
 			 * segments we ignored. */
 			goto in_window;
 		}
-		/* Just fall trough */
+		/* Just fall through */
 	default:
 		/* Keep compilers happy. */
 		break;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 0a46123..a97ed54 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3347,7 +3347,7 @@
 			int offset = start - TCP_SKB_CB(skb)->seq;
 			int size = TCP_SKB_CB(skb)->end_seq - start;
 
-			if (offset < 0) BUG();
+			BUG_ON(offset < 0);
 			if (size > 0) {
 				size = min(copy, size);
 				if (skb_copy_bits(skb, offset, skb_put(nskb, size), size))
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index b4c4beb..efa3e72 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -226,6 +226,8 @@
 	ipv6_addr_copy(&hdr->saddr, &fl->fl6_src);
 	ipv6_addr_copy(&hdr->daddr, first_hop);
 
+	skb->priority = sk->sk_priority;
+
 	mtu = dst_mtu(dst);
 	if ((skb->len <= mtu) || ipfragok) {
 		IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
@@ -1182,6 +1184,8 @@
 	ipv6_addr_copy(&hdr->saddr, &fl->fl6_src);
 	ipv6_addr_copy(&hdr->daddr, final_dst);
 
+	skb->priority = sk->sk_priority;
+
 	skb->dst = dst_clone(&rt->u.dst);
 	IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);	
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index f079621..c3c2bf6 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -243,7 +243,7 @@
 	if (dev == NULL)
 		return -ENOMEM;
 
-	t = dev->priv;
+	t = netdev_priv(dev);
 	dev->init = ip6ip6_tnl_dev_init;
 	t->parms = *p;
 
@@ -308,7 +308,7 @@
 static void
 ip6ip6_tnl_dev_uninit(struct net_device *dev)
 {
-	struct ip6_tnl *t = dev->priv;
+	struct ip6_tnl *t = netdev_priv(dev);
 
 	if (dev == ip6ip6_fb_tnl_dev) {
 		write_lock_bh(&ip6ip6_lock);
@@ -623,7 +623,7 @@
 static int 
 ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct ip6_tnl *t = (struct ip6_tnl *) dev->priv;
+	struct ip6_tnl *t = netdev_priv(dev);
 	struct net_device_stats *stats = &t->stat;
 	struct ipv6hdr *ipv6h = skb->nh.ipv6h;
 	struct ipv6_txoptions *opt = NULL;
@@ -933,11 +933,11 @@
 				break;
 			}
 			if ((err = ip6ip6_tnl_locate(&p, &t, 0)) == -ENODEV)
-				t = (struct ip6_tnl *) dev->priv;
+				t = netdev_priv(dev);
 			else if (err)
 				break;
 		} else
-			t = (struct ip6_tnl *) dev->priv;
+			t = netdev_priv(dev);
 
 		memcpy(&p, &t->parms, sizeof (p));
 		if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof (p))) {
@@ -955,7 +955,7 @@
 			break;
 		}
 		if (!create && dev != ip6ip6_fb_tnl_dev) {
-			t = (struct ip6_tnl *) dev->priv;
+			t = netdev_priv(dev);
 		}
 		if (!t && (err = ip6ip6_tnl_locate(&p, &t, create))) {
 			break;
@@ -991,12 +991,12 @@
 			err = ip6ip6_tnl_locate(&p, &t, 0);
 			if (err)
 				break;
-			if (t == ip6ip6_fb_tnl_dev->priv) {
+			if (t == netdev_priv(ip6ip6_fb_tnl_dev)) {
 				err = -EPERM;
 				break;
 			}
 		} else {
-			t = (struct ip6_tnl *) dev->priv;
+			t = netdev_priv(dev);
 		}
 		err = unregister_netdevice(t->dev);
 		break;
@@ -1016,7 +1016,7 @@
 static struct net_device_stats *
 ip6ip6_tnl_get_stats(struct net_device *dev)
 {
-	return &(((struct ip6_tnl *) dev->priv)->stat);
+	return &(((struct ip6_tnl *)netdev_priv(dev))->stat);
 }
 
 /**
@@ -1073,7 +1073,7 @@
 static inline void
 ip6ip6_tnl_dev_init_gen(struct net_device *dev)
 {
-	struct ip6_tnl *t = (struct ip6_tnl *) dev->priv;
+	struct ip6_tnl *t = netdev_priv(dev);
 	t->fl.proto = IPPROTO_IPV6;
 	t->dev = dev;
 	strcpy(t->parms.name, dev->name);
@@ -1087,7 +1087,7 @@
 static int
 ip6ip6_tnl_dev_init(struct net_device *dev)
 {
-	struct ip6_tnl *t = (struct ip6_tnl *) dev->priv;
+	struct ip6_tnl *t = netdev_priv(dev);
 	ip6ip6_tnl_dev_init_gen(dev);
 	ip6ip6_tnl_link_config(t);
 	return 0;
@@ -1103,7 +1103,7 @@
 static int 
 ip6ip6_fb_tnl_dev_init(struct net_device *dev)
 {
-	struct ip6_tnl *t = dev->priv;
+	struct ip6_tnl *t = netdev_priv(dev);
 	ip6ip6_tnl_dev_init_gen(dev);
 	dev_hold(dev);
 	tnls_wc[0] = t;
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 02872ae..0dae48a 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -184,7 +184,7 @@
 	if (dev == NULL)
 		return NULL;
 
-	nt = dev->priv;
+	nt = netdev_priv(dev);
 	dev->init = ipip6_tunnel_init;
 	nt->parms = *parms;
 
@@ -210,7 +210,7 @@
 		write_unlock_bh(&ipip6_lock);
 		dev_put(dev);
 	} else {
-		ipip6_tunnel_unlink((struct ip_tunnel*)dev->priv);
+		ipip6_tunnel_unlink(netdev_priv(dev));
 		dev_put(dev);
 	}
 }
@@ -346,7 +346,7 @@
 		rt6i = rt6_lookup(&iph6->daddr, &iph6->saddr, NULL, 0);
 
 		if (rt6i && rt6i->rt6i_dev && rt6i->rt6i_dev->type == ARPHRD_SIT) {
-			struct ip_tunnel * t = (struct ip_tunnel*)rt6i->rt6i_dev->priv;
+			struct ip_tunnel *t = netdev_priv(rt6i->rt6i_dev);
 			if (rel_type == ICMPV6_TIME_EXCEED && t->parms.iph.ttl) {
 				rel_type = ICMPV6_DEST_UNREACH;
 				rel_code = ICMPV6_ADDR_UNREACH;
@@ -424,7 +424,7 @@
 
 static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv;
+	struct ip_tunnel *tunnel = netdev_priv(dev);
 	struct net_device_stats *stats = &tunnel->stat;
 	struct iphdr  *tiph = &tunnel->parms.iph;
 	struct ipv6hdr *iph6 = skb->nh.ipv6h;
@@ -610,7 +610,7 @@
 			t = ipip6_tunnel_locate(&p, 0);
 		}
 		if (t == NULL)
-			t = (struct ip_tunnel*)dev->priv;
+			t = netdev_priv(dev);
 		memcpy(&p, &t->parms, sizeof(p));
 		if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
 			err = -EFAULT;
@@ -647,7 +647,7 @@
 					err = -EINVAL;
 					break;
 				}
-				t = (struct ip_tunnel*)dev->priv;
+				t = netdev_priv(dev);
 				ipip6_tunnel_unlink(t);
 				t->parms.iph.saddr = p.iph.saddr;
 				t->parms.iph.daddr = p.iph.daddr;
@@ -683,7 +683,7 @@
 			if ((t = ipip6_tunnel_locate(&p, 0)) == NULL)
 				goto done;
 			err = -EPERM;
-			if (t == ipip6_fb_tunnel_dev->priv)
+			if (t == netdev_priv(ipip6_fb_tunnel_dev))
 				goto done;
 			dev = t->dev;
 		}
@@ -700,7 +700,7 @@
 
 static struct net_device_stats *ipip6_tunnel_get_stats(struct net_device *dev)
 {
-	return &(((struct ip_tunnel*)dev->priv)->stat);
+	return &(((struct ip_tunnel*)netdev_priv(dev))->stat);
 }
 
 static int ipip6_tunnel_change_mtu(struct net_device *dev, int new_mtu)
@@ -735,7 +735,7 @@
 	struct ip_tunnel *tunnel;
 	struct iphdr *iph;
 
-	tunnel = (struct ip_tunnel*)dev->priv;
+	tunnel = netdev_priv(dev);
 	iph = &tunnel->parms.iph;
 
 	tunnel->dev = dev;
@@ -775,7 +775,7 @@
 
 static int __init ipip6_fb_tunnel_init(struct net_device *dev)
 {
-	struct ip_tunnel *tunnel = dev->priv;
+	struct ip_tunnel *tunnel = netdev_priv(dev);
 	struct iphdr *iph = &tunnel->parms.iph;
 
 	tunnel->dev = dev;
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 52efd04..4c2f6d6 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -297,8 +297,7 @@
 		err = EINTR;
 	if (err >= 512)
 		err = EINVAL;
-	if (err <= 0 || err >= 256)
-		BUG();
+	BUG_ON(err <= 0 || err >= 256);
 
 	hdr = (struct sadb_msg *) skb_put(skb, sizeof(struct sadb_msg));
 	pfkey_hdr_dup(hdr, orig);
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 6167137..9a1348a 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -988,7 +988,7 @@
 		        || (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
 		            && conntrack->proto.tcp.last_index == TCP_ACK_SET))
 		    && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) {
-			/* RST sent to invalid SYN or ACK we had let trough
+			/* RST sent to invalid SYN or ACK we had let through
 			 * at a) and c) above:
 			 *
 			 * a) SYN was in window then
@@ -999,7 +999,7 @@
 			 * segments we ignored. */
 			goto in_window;
 		}
-		/* Just fall trough */
+		/* Just fall through */
 	default:
 		/* Keep compilers happy. */
 		break;
diff --git a/net/sched/Makefile b/net/sched/Makefile
index e48d0d4..0f06aec 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -7,13 +7,13 @@
 obj-$(CONFIG_NET_SCHED)		+= sch_api.o sch_fifo.o sch_blackhole.o
 obj-$(CONFIG_NET_CLS)		+= cls_api.o
 obj-$(CONFIG_NET_CLS_ACT)	+= act_api.o
-obj-$(CONFIG_NET_ACT_POLICE)	+= police.o
-obj-$(CONFIG_NET_CLS_POLICE)	+= police.o
-obj-$(CONFIG_NET_ACT_GACT)	+= gact.o
-obj-$(CONFIG_NET_ACT_MIRRED)	+= mirred.o
-obj-$(CONFIG_NET_ACT_IPT)	+= ipt.o
-obj-$(CONFIG_NET_ACT_PEDIT)	+= pedit.o
-obj-$(CONFIG_NET_ACT_SIMP)	+= simple.o
+obj-$(CONFIG_NET_ACT_POLICE)	+= act_police.o
+obj-$(CONFIG_NET_CLS_POLICE)	+= act_police.o
+obj-$(CONFIG_NET_ACT_GACT)	+= act_gact.o
+obj-$(CONFIG_NET_ACT_MIRRED)	+= act_mirred.o
+obj-$(CONFIG_NET_ACT_IPT)	+= act_ipt.o
+obj-$(CONFIG_NET_ACT_PEDIT)	+= act_pedit.o
+obj-$(CONFIG_NET_ACT_SIMP)	+= act_simple.o
 obj-$(CONFIG_NET_SCH_CBQ)	+= sch_cbq.o
 obj-$(CONFIG_NET_SCH_HTB)	+= sch_htb.o
 obj-$(CONFIG_NET_SCH_HPFQ)	+= sch_hpfq.o
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 2ce1cb2..792ce59 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -165,7 +165,7 @@
 	while ((a = act) != NULL) {
 repeat:
 		if (a->ops && a->ops->act) {
-			ret = a->ops->act(&skb, a, res);
+			ret = a->ops->act(skb, a, res);
 			if (TC_MUNGED & skb->tc_verd) {
 				/* copied already, allow trampling */
 				skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
@@ -290,7 +290,7 @@
 	if (a_o == NULL) {
 #ifdef CONFIG_KMOD
 		rtnl_unlock();
-		request_module(act_name);
+		request_module("act_%s", act_name);
 		rtnl_lock();
 
 		a_o = tc_lookup_action_n(act_name);
diff --git a/net/sched/gact.c b/net/sched/act_gact.c
similarity index 97%
rename from net/sched/gact.c
rename to net/sched/act_gact.c
index d1c6d54..a1e68f7 100644
--- a/net/sched/gact.c
+++ b/net/sched/act_gact.c
@@ -135,10 +135,9 @@
 }
 
 static int
-tcf_gact(struct sk_buff **pskb, struct tc_action *a, struct tcf_result *res)
+tcf_gact(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
 {
 	struct tcf_gact *p = PRIV(a, gact);
-	struct sk_buff *skb = *pskb;
 	int action = TC_ACT_SHOT;
 
 	spin_lock(&p->lock);
diff --git a/net/sched/ipt.c b/net/sched/act_ipt.c
similarity index 96%
rename from net/sched/ipt.c
rename to net/sched/act_ipt.c
index f50136e..b500193 100644
--- a/net/sched/ipt.c
+++ b/net/sched/act_ipt.c
@@ -201,11 +201,10 @@
 }
 
 static int
-tcf_ipt(struct sk_buff **pskb, struct tc_action *a, struct tcf_result *res)
+tcf_ipt(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
 {
 	int ret = 0, result = 0;
 	struct tcf_ipt *p = PRIV(a, ipt);
-	struct sk_buff *skb = *pskb;
 
 	if (skb_cloned(skb)) {
 		if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
@@ -222,6 +221,9 @@
 	 worry later - danger - this API seems to have changed
 	 from earlier kernels */
 
+	/* iptables targets take a double skb pointer in case the skb
+	 * needs to be replaced. We don't own the skb, so this must not
+	 * happen. The pskb_expand_head above should make sure of this */
 	ret = p->t->u.kernel.target->target(&skb, skb->dev, NULL,
 					    p->hook, p->t->data, NULL);
 	switch (ret) {
diff --git a/net/sched/mirred.c b/net/sched/act_mirred.c
similarity index 98%
rename from net/sched/mirred.c
rename to net/sched/act_mirred.c
index 20d0691..4fcccbd 100644
--- a/net/sched/mirred.c
+++ b/net/sched/act_mirred.c
@@ -158,12 +158,11 @@
 }
 
 static int
-tcf_mirred(struct sk_buff **pskb, struct tc_action *a, struct tcf_result *res)
+tcf_mirred(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
 {
 	struct tcf_mirred *p = PRIV(a, mirred);
 	struct net_device *dev;
 	struct sk_buff *skb2 = NULL;
-	struct sk_buff *skb = *pskb;
 	u32 at = G_TC_AT(skb->tc_verd);
 
 	spin_lock(&p->lock);
diff --git a/net/sched/pedit.c b/net/sched/act_pedit.c
similarity index 98%
rename from net/sched/pedit.c
rename to net/sched/act_pedit.c
index 767d24f..1742a68 100644
--- a/net/sched/pedit.c
+++ b/net/sched/act_pedit.c
@@ -130,10 +130,9 @@
 }
 
 static int
-tcf_pedit(struct sk_buff **pskb, struct tc_action *a, struct tcf_result *res)
+tcf_pedit(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
 {
 	struct tcf_pedit *p = PRIV(a, pedit);
-	struct sk_buff *skb = *pskb;
 	int i, munged = 0;
 	u8 *pptr;
 
@@ -246,10 +245,12 @@
 	t.lastuse = jiffies_to_clock_t(jiffies - p->tm.lastuse);
 	t.expires = jiffies_to_clock_t(p->tm.expires);
 	RTA_PUT(skb, TCA_PEDIT_TM, sizeof(t), &t);
+	kfree(opt);
 	return skb->len;
 
 rtattr_failure:
 	skb_trim(skb, b - skb->data);
+	kfree(opt);
 	return -1;
 }
 
diff --git a/net/sched/police.c b/net/sched/act_police.c
similarity index 97%
rename from net/sched/police.c
rename to net/sched/act_police.c
index eb39fb2..fa877f8 100644
--- a/net/sched/police.c
+++ b/net/sched/act_police.c
@@ -284,11 +284,10 @@
 	return 0;
 }
 
-static int tcf_act_police(struct sk_buff **pskb, struct tc_action *a,
+static int tcf_act_police(struct sk_buff *skb, struct tc_action *a,
                           struct tcf_result *res)
 {
 	psched_time_t now;
-	struct sk_buff *skb = *pskb;
 	struct tcf_police *p = PRIV(a);
 	long toks;
 	long ptoks = 0;
@@ -408,7 +407,7 @@
 module_init(police_init_module);
 module_exit(police_cleanup_module);
 
-#endif
+#else /* CONFIG_NET_CLS_ACT */
 
 struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est)
 {
@@ -545,6 +544,7 @@
 	spin_unlock(&p->lock);
 	return p->action;
 }
+EXPORT_SYMBOL(tcf_police);
 
 int tcf_police_dump(struct sk_buff *skb, struct tcf_police *p)
 {
@@ -601,13 +601,4 @@
 	return -1;
 }
 
-
-EXPORT_SYMBOL(tcf_police);
-EXPORT_SYMBOL(tcf_police_destroy);
-EXPORT_SYMBOL(tcf_police_dump);
-EXPORT_SYMBOL(tcf_police_dump_stats);
-EXPORT_SYMBOL(tcf_police_hash);
-EXPORT_SYMBOL(tcf_police_ht);
-EXPORT_SYMBOL(tcf_police_locate);
-EXPORT_SYMBOL(tcf_police_lookup);
-EXPORT_SYMBOL(tcf_police_new_index);
+#endif /* CONFIG_NET_CLS_ACT */
diff --git a/net/sched/simple.c b/net/sched/act_simple.c
similarity index 94%
rename from net/sched/simple.c
rename to net/sched/act_simple.c
index 8a6ae4f..e5f2e1f 100644
--- a/net/sched/simple.c
+++ b/net/sched/act_simple.c
@@ -44,9 +44,8 @@
 #include <net/pkt_act.h>
 #include <net/act_generic.h>
 
-static int tcf_simp(struct sk_buff **pskb, struct tc_action *a, struct tcf_result *res)
+static int tcf_simp(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
 {
-	struct sk_buff *skb = *pskb;
 	struct tcf_defact *p = PRIV(a, defact);
 
 	spin_lock(&p->lock);
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 09453f9..6cd8170 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -257,7 +257,7 @@
 	    (cl = cbq_class_lookup(q, prio)) != NULL)
 		return cl;
 
-	*qerr = NET_XMIT_DROP;
+	*qerr = NET_XMIT_BYPASS;
 	for (;;) {
 		int result = 0;
 		defmap = head->defaults;
@@ -413,7 +413,7 @@
 	q->rx_class = cl;
 #endif
 	if (cl == NULL) {
-		if (ret == NET_XMIT_DROP)
+		if (ret == NET_XMIT_BYPASS)
 			sch->qstats.drops++;
 		kfree_skb(skb);
 		return ret;
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index c26764b..91132f6 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -208,7 +208,7 @@
 do {									\
 	struct timeval tv;						\
 	do_gettimeofday(&tv);						\
-	(stamp) = 1000000ULL * tv.tv_sec + tv.tv_usec;			\
+	(stamp) = 1ULL * USEC_PER_SEC * tv.tv_sec + tv.tv_usec;		\
 } while (0)
 #endif
 
@@ -502,8 +502,8 @@
 	u64 dx;
 
 	dx = ((u64)d * PSCHED_JIFFIE2US(HZ));
-	dx += 1000000 - 1;
-	do_div(dx, 1000000);
+	dx += USEC_PER_SEC - 1;
+	do_div(dx, USEC_PER_SEC);
 	return dx;
 }
 
@@ -523,7 +523,7 @@
 {
 	u64 d;
 
-	d = dx * 1000000;
+	d = dx * USEC_PER_SEC;
 	do_div(d, PSCHED_JIFFIE2US(HZ));
 	return (u32)d;
 }
@@ -1227,7 +1227,7 @@
 		if (cl->level == 0)
 			return cl;
 
-	*qerr = NET_XMIT_DROP;
+	*qerr = NET_XMIT_BYPASS;
 	tcf = q->root.filter_list;
 	while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) {
 #ifdef CONFIG_NET_CLS_ACT
@@ -1643,7 +1643,7 @@
 
 	cl = hfsc_classify(skb, sch, &err);
 	if (cl == NULL) {
-		if (err == NET_XMIT_DROP)
+		if (err == NET_XMIT_BYPASS)
 			sch->qstats.drops++;
 		kfree_skb(skb);
 		return err;
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 558cc08..3ec95df 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -321,7 +321,7 @@
 	if ((cl = htb_find(skb->priority,sch)) != NULL && cl->level == 0) 
 		return cl;
 
-	*qerr = NET_XMIT_DROP;
+	*qerr = NET_XMIT_BYPASS;
 	tcf = q->filter_list;
 	while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) {
 #ifdef CONFIG_NET_CLS_ACT
@@ -724,7 +724,7 @@
 	}
 #ifdef CONFIG_NET_CLS_ACT
     } else if (!cl) {
-	if (ret == NET_XMIT_DROP)
+	if (ret == NET_XMIT_BYPASS)
 		sch->qstats.drops++;
 	kfree_skb (skb);
 	return ret;
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 3ac0f49..5b3a3e4 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -54,7 +54,7 @@
 	u32 band = skb->priority;
 	struct tcf_result res;
 
-	*qerr = NET_XMIT_DROP;
+	*qerr = NET_XMIT_BYPASS;
 	if (TC_H_MAJ(skb->priority) != sch->handle) {
 #ifdef CONFIG_NET_CLS_ACT
 		switch (tc_classify(skb, q->filter_list, &res)) {
@@ -91,7 +91,8 @@
 	qdisc = prio_classify(skb, sch, &ret);
 #ifdef CONFIG_NET_CLS_ACT
 	if (qdisc == NULL) {
-		if (ret == NET_XMIT_DROP)
+
+		if (ret == NET_XMIT_BYPASS)
 			sch->qstats.drops++;
 		kfree_skb(skb);
 		return ret;
@@ -118,7 +119,7 @@
 	qdisc = prio_classify(skb, sch, &ret);
 #ifdef CONFIG_NET_CLS_ACT
 	if (qdisc == NULL) {
-		if (ret == NET_XMIT_DROP)
+		if (ret == NET_XMIT_BYPASS)
 			sch->qstats.drops++;
 		kfree_skb(skb);
 		return ret;
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index c4a2a8c..79b8ef3 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -274,7 +274,7 @@
 
 static int teql_master_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct teql_master *master = (void*)dev->priv;
+	struct teql_master *master = netdev_priv(dev);
 	struct Qdisc *start, *q;
 	int busy;
 	int nores;
@@ -350,7 +350,7 @@
 static int teql_master_open(struct net_device *dev)
 {
 	struct Qdisc * q;
-	struct teql_master *m = (void*)dev->priv;
+	struct teql_master *m = netdev_priv(dev);
 	int mtu = 0xFFFE;
 	unsigned flags = IFF_NOARP|IFF_MULTICAST;
 
@@ -397,13 +397,13 @@
 
 static struct net_device_stats *teql_master_stats(struct net_device *dev)
 {
-	struct teql_master *m = (void*)dev->priv;
+	struct teql_master *m = netdev_priv(dev);
 	return &m->stats;
 }
 
 static int teql_master_mtu(struct net_device *dev, int new_mtu)
 {
-	struct teql_master *m = (void*)dev->priv;
+	struct teql_master *m = netdev_priv(dev);
 	struct Qdisc *q;
 
 	if (new_mtu < 68)
@@ -423,7 +423,7 @@
 
 static __init void teql_master_setup(struct net_device *dev)
 {
-	struct teql_master *master = dev->priv;
+	struct teql_master *master = netdev_priv(dev);
 	struct Qdisc_ops *ops = &master->qops;
 
 	master->dev	= dev;
@@ -476,7 +476,7 @@
 			break;
 		}
 
-		master = dev->priv;
+		master = netdev_priv(dev);
 
 		strlcpy(master->qops.id, dev->name, IFNAMSIZ);
 		err = register_qdisc(&master->qops);
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 2d7d8a5..b8b38ab 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1250,8 +1250,7 @@
 		case SCTP_CMD_TIMER_START:
 			timer = &asoc->timers[cmd->obj.to];
 			timeout = asoc->timeouts[cmd->obj.to];
-			if (!timeout)
-				BUG();
+			BUG_ON(!timeout);
 
 			timer->expires = jiffies + timeout;
 			sctp_association_hold(asoc);
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index f509e99..dcaa0c4 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -575,12 +575,11 @@
 	if (rp->q.list.next == &cd->queue) {
 		spin_unlock(&queue_lock);
 		up(&queue_io_sem);
-		if (rp->offset)
-			BUG();
+		BUG_ON(rp->offset);
 		return 0;
 	}
 	rq = container_of(rp->q.list.next, struct cache_request, q.list);
-	if (rq->q.reader) BUG();
+	BUG_ON(rq->q.reader);
 	if (rp->offset == 0)
 		rq->readers++;
 	spin_unlock(&queue_lock);
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index e14c1cae..9764c80 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -69,13 +69,13 @@
 	struct rpc_inode *rpci = (struct rpc_inode *)data;
 	struct inode *inode = &rpci->vfs_inode;
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	if (rpci->ops == NULL)
 		goto out;
 	if (rpci->nreaders == 0 && !list_empty(&rpci->pipe))
 		__rpc_purge_upcall(inode, -ETIMEDOUT);
 out:
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 }
 
 int
@@ -84,7 +84,7 @@
 	struct rpc_inode *rpci = RPC_I(inode);
 	int res = -EPIPE;
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	if (rpci->ops == NULL)
 		goto out;
 	if (rpci->nreaders) {
@@ -100,7 +100,7 @@
 		res = 0;
 	}
 out:
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	wake_up(&rpci->waitq);
 	return res;
 }
@@ -116,7 +116,7 @@
 {
 	struct rpc_inode *rpci = RPC_I(inode);
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	if (rpci->ops != NULL) {
 		rpci->nreaders = 0;
 		__rpc_purge_list(rpci, &rpci->in_upcall, -EPIPE);
@@ -127,7 +127,7 @@
 		rpci->ops = NULL;
 	}
 	rpc_inode_setowner(inode, NULL);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	cancel_delayed_work(&rpci->queue_timeout);
 	flush_scheduled_work();
 }
@@ -154,7 +154,7 @@
 	struct rpc_inode *rpci = RPC_I(inode);
 	int res = -ENXIO;
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	if (rpci->ops != NULL) {
 		if (filp->f_mode & FMODE_READ)
 			rpci->nreaders ++;
@@ -162,7 +162,7 @@
 			rpci->nwriters ++;
 		res = 0;
 	}
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	return res;
 }
 
@@ -172,7 +172,7 @@
 	struct rpc_inode *rpci = RPC_I(inode);
 	struct rpc_pipe_msg *msg;
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	if (rpci->ops == NULL)
 		goto out;
 	msg = (struct rpc_pipe_msg *)filp->private_data;
@@ -190,7 +190,7 @@
 	if (rpci->ops->release_pipe)
 		rpci->ops->release_pipe(inode);
 out:
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	return 0;
 }
 
@@ -202,7 +202,7 @@
 	struct rpc_pipe_msg *msg;
 	int res = 0;
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	if (rpci->ops == NULL) {
 		res = -EPIPE;
 		goto out_unlock;
@@ -229,7 +229,7 @@
 		rpci->ops->destroy_msg(msg);
 	}
 out_unlock:
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	return res;
 }
 
@@ -240,11 +240,11 @@
 	struct rpc_inode *rpci = RPC_I(inode);
 	int res;
 
-	down(&inode->i_sem);
+	mutex_lock(&inode->i_mutex);
 	res = -EPIPE;
 	if (rpci->ops != NULL)
 		res = rpci->ops->downcall(filp, buf, len);
-	up(&inode->i_sem);
+	mutex_unlock(&inode->i_mutex);
 	return res;
 }
 
@@ -322,7 +322,7 @@
 
 	if (!ret) {
 		struct seq_file *m = file->private_data;
-		down(&inode->i_sem);
+		mutex_lock(&inode->i_mutex);
 		clnt = RPC_I(inode)->private;
 		if (clnt) {
 			atomic_inc(&clnt->cl_users);
@@ -331,7 +331,7 @@
 			single_release(inode, file);
 			ret = -EINVAL;
 		}
-		up(&inode->i_sem);
+		mutex_unlock(&inode->i_mutex);
 	}
 	return ret;
 }
@@ -491,7 +491,7 @@
 	struct dentry *dentry, *dvec[10];
 	int n = 0;
 
-	down(&dir->i_sem);
+	mutex_lock(&dir->i_mutex);
 repeat:
 	spin_lock(&dcache_lock);
 	list_for_each_safe(pos, next, &parent->d_subdirs) {
@@ -519,7 +519,7 @@
 		} while (n);
 		goto repeat;
 	}
-	up(&dir->i_sem);
+	mutex_unlock(&dir->i_mutex);
 }
 
 static int
@@ -532,7 +532,7 @@
 	struct dentry *dentry;
 	int mode, i;
 
-	down(&dir->i_sem);
+	mutex_lock(&dir->i_mutex);
 	for (i = start; i < eof; i++) {
 		dentry = d_alloc_name(parent, files[i].name);
 		if (!dentry)
@@ -552,10 +552,10 @@
 			dir->i_nlink++;
 		d_add(dentry, inode);
 	}
-	up(&dir->i_sem);
+	mutex_unlock(&dir->i_mutex);
 	return 0;
 out_bad:
-	up(&dir->i_sem);
+	mutex_unlock(&dir->i_mutex);
 	printk(KERN_WARNING "%s: %s failed to populate directory %s\n",
 			__FILE__, __FUNCTION__, parent->d_name.name);
 	return -ENOMEM;
@@ -609,7 +609,7 @@
 	if ((error = rpc_lookup_parent(path, nd)) != 0)
 		return ERR_PTR(error);
 	dir = nd->dentry->d_inode;
-	down(&dir->i_sem);
+	mutex_lock(&dir->i_mutex);
 	dentry = lookup_hash(nd);
 	if (IS_ERR(dentry))
 		goto out_err;
@@ -620,7 +620,7 @@
 	}
 	return dentry;
 out_err:
-	up(&dir->i_sem);
+	mutex_unlock(&dir->i_mutex);
 	rpc_release_path(nd);
 	return dentry;
 }
@@ -646,7 +646,7 @@
 	if (error)
 		goto err_depopulate;
 out:
-	up(&dir->i_sem);
+	mutex_unlock(&dir->i_mutex);
 	rpc_release_path(&nd);
 	return dentry;
 err_depopulate:
@@ -671,7 +671,7 @@
 	if ((error = rpc_lookup_parent(path, &nd)) != 0)
 		return error;
 	dir = nd.dentry->d_inode;
-	down(&dir->i_sem);
+	mutex_lock(&dir->i_mutex);
 	dentry = lookup_hash(&nd);
 	if (IS_ERR(dentry)) {
 		error = PTR_ERR(dentry);
@@ -681,7 +681,7 @@
 	error = __rpc_rmdir(dir, dentry);
 	dput(dentry);
 out_release:
-	up(&dir->i_sem);
+	mutex_unlock(&dir->i_mutex);
 	rpc_release_path(&nd);
 	return error;
 }
@@ -710,7 +710,7 @@
 	rpci->ops = ops;
 	inode_dir_notify(dir, DN_CREATE);
 out:
-	up(&dir->i_sem);
+	mutex_unlock(&dir->i_mutex);
 	rpc_release_path(&nd);
 	return dentry;
 err_dput:
@@ -732,7 +732,7 @@
 	if ((error = rpc_lookup_parent(path, &nd)) != 0)
 		return error;
 	dir = nd.dentry->d_inode;
-	down(&dir->i_sem);
+	mutex_lock(&dir->i_mutex);
 	dentry = lookup_hash(&nd);
 	if (IS_ERR(dentry)) {
 		error = PTR_ERR(dentry);
@@ -746,7 +746,7 @@
 	dput(dentry);
 	inode_dir_notify(dir, DN_DELETE);
 out_release:
-	up(&dir->i_sem);
+	mutex_unlock(&dir->i_mutex);
 	rpc_release_path(&nd);
 	return error;
 }
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index e4296c8..b19cc26 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -122,8 +122,7 @@
 	rqstp->rq_argused = 0;
 	rqstp->rq_resused = 0;
 	arghi = 0;
-	if (pages > RPCSVC_MAXPAGES)
-		BUG();
+	BUG_ON(pages > RPCSVC_MAXPAGES);
 	while (pages) {
 		struct page *p = alloc_page(GFP_KERNEL);
 		if (!p)
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 5f6ae79..1b5989b 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -784,7 +784,7 @@
 		err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
 		if (err)
 			goto out_mknod_dput;
-		up(&nd.dentry->d_inode->i_sem);
+		mutex_unlock(&nd.dentry->d_inode->i_mutex);
 		dput(nd.dentry);
 		nd.dentry = dentry;
 
@@ -823,7 +823,7 @@
 out_mknod_dput:
 	dput(dentry);
 out_mknod_unlock:
-	up(&nd.dentry->d_inode->i_sem);
+	mutex_unlock(&nd.dentry->d_inode->i_mutex);
 	path_release(&nd);
 out_mknod_parent:
 	if (err==-EEXIST)
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 2f4531f..6ed3302 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -540,8 +540,7 @@
 			start = end;
 		}
 	}
-	if (len)
-		BUG();
+	BUG_ON(len);
 }
 EXPORT_SYMBOL_GPL(skb_icv_walk);
 
@@ -610,8 +609,7 @@
 			start = end;
 		}
 	}
-	if (len)
-		BUG();
+	BUG_ON(len);
 	return elt;
 }
 EXPORT_SYMBOL_GPL(skb_to_sgvec);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 59614a9..077bbf9 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -248,11 +248,9 @@
 
 void __xfrm_policy_destroy(struct xfrm_policy *policy)
 {
-	if (!policy->dead)
-		BUG();
+	BUG_ON(!policy->dead);
 
-	if (policy->bundles)
-		BUG();
+	BUG_ON(policy->bundles);
 
 	if (del_timer(&policy->timer))
 		BUG();
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 0c4f3a9..bf96a61 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -30,7 +30,7 @@
 #     - See include/linux/module.h for more details
 
 # Step 4 is solely used to allow module versioning in external modules,
-# where the CRC of each module is retreived from the Module.symers file.
+# where the CRC of each module is retrieved from the Module.symers file.
 
 .PHONY: _modpost
 _modpost: __modpost
diff --git a/scripts/mksysmap b/scripts/mksysmap
index a6430e0..4390fab 100644
--- a/scripts/mksysmap
+++ b/scripts/mksysmap
@@ -1,7 +1,7 @@
 #!/bin/sh -x
 # Based on the vmlinux file create the System.map file
 # System.map is used by module-init tools and some debugging
-# tools to retreive the actual addresses of symbols in the kernel.
+# tools to retrieve the actual addresses of symbols in the kernel.
 #
 # Usage
 # mksysmap vmlinux System.map
diff --git a/security/inode.c b/security/inode.c
index a596450..0f77b02 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -172,7 +172,7 @@
 		return -EFAULT;
 	}
 
-	down(&parent->d_inode->i_sem);
+	mutex_lock(&parent->d_inode->i_mutex);
 	*dentry = lookup_one_len(name, parent, strlen(name));
 	if (!IS_ERR(dentry)) {
 		if ((mode & S_IFMT) == S_IFDIR)
@@ -181,7 +181,7 @@
 			error = create(parent->d_inode, *dentry, mode);
 	} else
 		error = PTR_ERR(dentry);
-	up(&parent->d_inode->i_sem);
+	mutex_unlock(&parent->d_inode->i_mutex);
 
 	return error;
 }
@@ -302,7 +302,7 @@
 	if (!parent || !parent->d_inode)
 		return;
 
-	down(&parent->d_inode->i_sem);
+	mutex_lock(&parent->d_inode->i_mutex);
 	if (positive(dentry)) {
 		if (dentry->d_inode) {
 			if (S_ISDIR(dentry->d_inode->i_mode))
@@ -312,7 +312,7 @@
 			dput(dentry);
 		}
 	}
-	up(&parent->d_inode->i_sem);
+	mutex_unlock(&parent->d_inode->i_mutex);
 	simple_release_fs(&mount, &mount_count);
 }
 EXPORT_SYMBOL_GPL(securityfs_remove);
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 16df124..7fd0723 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -2135,9 +2135,7 @@
 	substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
 	if (substream == NULL)
 		return -ENXIO;
-	up(&file->f_dentry->d_inode->i_sem);
 	result = snd_pcm_oss_write1(substream, buf, count);
-	down(&file->f_dentry->d_inode->i_sem);
 #ifdef OSS_DEBUG
 	printk("pcm_oss: write %li bytes (wrote %li bytes)\n", (long)count, (long)result);
 #endif
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
index 9ee6c17..40b4f67 100644
--- a/sound/core/seq/seq_memory.c
+++ b/sound/core/seq/seq_memory.c
@@ -32,10 +32,6 @@
 #include "seq_info.h"
 #include "seq_lock.h"
 
-/* semaphore in struct file record */
-#define semaphore_of(fp)	((fp)->f_dentry->d_inode->i_sem)
-
-
 static inline int snd_seq_pool_available(struct snd_seq_pool *pool)
 {
 	return pool->total_elements - atomic_read(&pool->counter);
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
index 09cb250..962e6d5 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
@@ -209,7 +209,7 @@
 	case SNDRV_PCM_FORMAT_S24_3LE:
 	case SNDRV_PCM_FORMAT_S24_3BE:
 		chip->pcm_sample = 3;
-		/* fall trough */
+		/* fall through */
 	default: /* 24-bit */
 		aval = AK4117_DIF_24R;
 		chip->pcm_frame = 3;