Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6

* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6:
  [S390] cio: online_store - trigger recognition for boxed devices
  [S390] cio: disallow online setting of device in transient state
  [S390] cio: introduce notifier for boxed state
  [S390] cio: introduce ccw_device_schedule_sch_unregister
  [S390] cio: wake up on failed recognition
  [S390] fix hypfs build failure
  [PATCH] sysrq: include interrupt.h instead of irq.h
diff --git a/Documentation/fb/00-INDEX b/Documentation/fb/00-INDEX
index caabbd3..a618fd9 100644
--- a/Documentation/fb/00-INDEX
+++ b/Documentation/fb/00-INDEX
@@ -11,8 +11,6 @@
 	- info on the ATI Rage128 frame buffer driver.
 cirrusfb.txt
 	- info on the driver for Cirrus Logic chipsets.
-cyblafb/
-	- directory with documentation files related to the cyblafb driver.
 deferred_io.txt
 	- an introduction to deferred IO.
 fbcon.txt
diff --git a/Documentation/fb/cyblafb/bugs b/Documentation/fb/cyblafb/bugs
deleted file mode 100644
index 9443a6d..0000000
--- a/Documentation/fb/cyblafb/bugs
+++ /dev/null
@@ -1,13 +0,0 @@
-Bugs
-====
-
-I currently don't know of any bug. Please do send reports to:
- - linux-fbdev-devel@lists.sourceforge.net
- - Knut_Petersen@t-online.de.
-
-
-Untested features
-=================
-
-All LCD stuff is untested. If it worked in tridentfb, it should work in
-cyblafb. Please test and report the results to Knut_Petersen@t-online.de.
diff --git a/Documentation/fb/cyblafb/credits b/Documentation/fb/cyblafb/credits
deleted file mode 100644
index 0eb3b44..0000000
--- a/Documentation/fb/cyblafb/credits
+++ /dev/null
@@ -1,7 +0,0 @@
-Thanks to
-=========
-   * 	Alan Hourihane, for writing the X trident driver
-   *	Jani Monoses, for writing the tridentfb driver
-   *	Antonino A. Daplas, for review of the first published
-	version of cyblafb and some code
-   *	Jochen Hein, for testing and a helpfull bug report
diff --git a/Documentation/fb/cyblafb/documentation b/Documentation/fb/cyblafb/documentation
deleted file mode 100644
index bb1aac0..0000000
--- a/Documentation/fb/cyblafb/documentation
+++ /dev/null
@@ -1,17 +0,0 @@
-Available Documentation
-=======================
-
-Apollo PLE 133 Chipset VT8601A North Bridge Datasheet, Rev. 1.82, October 22,
-2001, available from VIA:
-
-	http://www.viavpsd.com/product/6/15/DS8601A182.pdf
-
-The datasheet is incomplete, some registers that need to be programmed are not
-explained at all and important bits are listed as "reserved". But you really
-need the datasheet to understand the code.  "p. xxx" comments refer to page
-numbers of this document.
-
-XFree/XOrg drivers are available and of good quality, looking at the code
-there is a good idea if the datasheet does not provide enough information
-or if the datasheet seems to be wrong.
-
diff --git a/Documentation/fb/cyblafb/fb.modes b/Documentation/fb/cyblafb/fb.modes
deleted file mode 100644
index fe0e522..0000000
--- a/Documentation/fb/cyblafb/fb.modes
+++ /dev/null
@@ -1,154 +0,0 @@
-#
-#   Sample fb.modes file
-#
-#	Provides an incomplete list of working modes for
-#	the cyberblade/i1 graphics core.
-#
-#	The value 4294967256 is used instead of -40. Of course, -40 is not
-#	a really reasonable value, but chip design does not always follow
-#	logic. Believe me, it's ok, and it's the way the BIOS does it.
-#
-#	fbset requires 4294967256 in fb.modes and -40 as an argument to
-#	the -t parameter. That's also not too reasonable, and it might change
-#	in the future or might even be differt for your current version.
-#
-
-mode "640x480-50"
-    geometry 640 480 2048 4096 8
-    timings 47619 4294967256 24 17 0 216 3
-endmode
-
-mode "640x480-60"
-    geometry 640 480 2048 4096 8
-    timings 39682 4294967256 24 17 0 216 3
-endmode
-
-mode "640x480-70"
-    geometry 640 480 2048 4096 8
-    timings 34013 4294967256 24 17 0 216 3
-endmode
-
-mode "640x480-72"
-    geometry 640 480 2048 4096 8
-    timings 33068 4294967256 24 17 0 216 3
-endmode
-
-mode "640x480-75"
-    geometry 640 480 2048 4096 8
-    timings 31746 4294967256 24 17 0 216 3
-endmode
-
-mode "640x480-80"
-    geometry 640 480 2048 4096 8
-    timings 29761 4294967256 24 17 0 216 3
-endmode
-
-mode "640x480-85"
-    geometry 640 480 2048 4096 8
-    timings 28011 4294967256 24 17 0 216 3
-endmode
-
-mode "800x600-50"
-    geometry 800 600 2048 4096 8
-    timings 30303 96 24 14 0 136 11
-endmode
-
-mode "800x600-60"
-    geometry 800 600 2048 4096 8
-    timings 25252 96 24 14 0 136 11
-endmode
-
-mode "800x600-70"
-    geometry 800 600 2048 4096 8
-    timings 21645 96 24 14 0 136 11
-endmode
-
-mode "800x600-72"
-    geometry 800 600 2048 4096 8
-    timings 21043 96 24 14 0 136 11
-endmode
-
-mode "800x600-75"
-    geometry 800 600 2048 4096 8
-    timings 20202 96 24 14 0 136 11
-endmode
-
-mode "800x600-80"
-    geometry 800 600 2048 4096 8
-    timings 18939 96 24 14 0 136 11
-endmode
-
-mode "800x600-85"
-    geometry 800 600 2048 4096 8
-    timings 17825 96 24 14 0 136 11
-endmode
-
-mode "1024x768-50"
-    geometry 1024 768 2048 4096 8
-    timings 19054 144 24 29 0 120 3
-endmode
-
-mode "1024x768-60"
-    geometry 1024 768 2048 4096 8
-    timings 15880 144 24 29 0 120 3
-endmode
-
-mode "1024x768-70"
-    geometry 1024 768 2048 4096 8
-    timings 13610 144 24 29 0 120 3
-endmode
-
-mode "1024x768-72"
-    geometry 1024 768 2048 4096 8
-    timings 13232 144 24 29 0 120 3
-endmode
-
-mode "1024x768-75"
-    geometry 1024 768 2048 4096 8
-    timings 12703 144 24 29 0 120 3
-endmode
-
-mode "1024x768-80"
-    geometry 1024 768 2048 4096 8
-    timings 11910 144 24 29 0 120 3
-endmode
-
-mode "1024x768-85"
-    geometry 1024 768 2048 4096 8
-    timings 11209 144 24 29 0 120 3
-endmode
-
-mode "1280x1024-50"
-    geometry 1280 1024 2048 4096 8
-    timings 11114 232 16 39 0 160 3
-endmode
-
-mode "1280x1024-60"
-    geometry 1280 1024 2048 4096 8
-    timings 9262 232 16 39 0 160 3
-endmode
-
-mode "1280x1024-70"
-    geometry 1280 1024 2048 4096 8
-    timings 7939 232 16 39 0 160 3
-endmode
-
-mode "1280x1024-72"
-    geometry 1280 1024 2048 4096 8
-    timings 7719 232 16 39 0 160 3
-endmode
-
-mode "1280x1024-75"
-    geometry 1280 1024 2048 4096 8
-    timings 7410 232 16 39 0 160 3
-endmode
-
-mode "1280x1024-80"
-    geometry 1280 1024 2048 4096 8
-    timings 6946 232 16 39 0 160 3
-endmode
-
-mode "1280x1024-85"
-    geometry 1280 1024 2048 4096 8
-    timings 6538 232 16 39 0 160 3
-endmode
diff --git a/Documentation/fb/cyblafb/performance b/Documentation/fb/cyblafb/performance
deleted file mode 100644
index 8d15d5d..0000000
--- a/Documentation/fb/cyblafb/performance
+++ /dev/null
@@ -1,79 +0,0 @@
-Speed
-=====
-
-CyBlaFB is much faster than tridentfb and vesafb. Compare the performance data
-for mode 1280x1024-[8,16,32]@61 Hz.
-
-Test 1: Cat a file with 2000 lines of 0 characters.
-Test 2: Cat a file with 2000 lines of 80 characters.
-Test 3: Cat a file with 2000 lines of 160 characters.
-
-All values show system time use in seconds, kernel 2.6.12 was used for
-the measurements. 2.6.13 is a bit slower, 2.6.14 hopefully will include a
-patch that speeds up kernel bitblitting a lot ( > 20%).
-
-+-----------+-----------------------------------------------------+
-|	    |			not accelerated 		  |
-| TRIDENTFB +-----------------+-----------------+-----------------+
-| of 2.6.12 |	   8 bpp      |     16 bpp	|     32 bpp	  |
-|	    | noypan |	 ypan | noypan |   ypan | noypan |   ypan |
-+-----------+--------+--------+--------+--------+--------+--------+
-|    Test 1 |	4.31 |	 4.33 |   6.05 |  12.81 |  ----  |  ----  |
-|    Test 2 |  67.94 |	 5.44 | 123.16 |  14.79 |  ----  |  ----  |
-|    Test 3 | 131.36 |	 6.55 | 240.12 |  16.76 |  ----  |  ----  |
-+-----------+--------+--------+--------+--------+--------+--------+
-|  Comments |		      | 		| completely bro- |
-|	    |		      | 		| ken, monitor	  |
-|	    |		      | 		| switches off	  |
-+-----------+-----------------+-----------------+-----------------+
-
-
-+-----------+-----------------------------------------------------+
-|	    |			  accelerated			  |
-| TRIDENTFB +-----------------+-----------------+-----------------+
-| of 2.6.12 |	   8 bpp      |     16 bpp	|     32 bpp	  |
-|	    | noypan |	 ypan | noypan |   ypan | noypan |   ypan |
-+-----------+--------+--------+--------+--------+--------+--------+
-|    Test 1 |  ----  |	----  |  20.62 |   1.22 |  ----  |  ----  |
-|    Test 2 |  ----  |	----  |  22.61 |   3.19 |  ----  |  ----  |
-|    Test 3 |  ----  |	----  |  24.59 |   5.16 |  ----  |  ----  |
-+-----------+--------+--------+--------+--------+--------+--------+
-|  Comments | broken, writing | broken, ok only | completely bro- |
-|	    | to wrong places | if bgcolor is	| ken, monitor	  |
-|	    | on screen + bug | black, bug in	| switches off	  |
-|	    | in fillrect()   | fillrect()	|		  |
-+-----------+-----------------+-----------------+-----------------+
-
-
-+-----------+-----------------------------------------------------+
-|	    |			not accelerated 		  |
-|   VESAFB  +-----------------+-----------------+-----------------+
-| of 2.6.12 |	   8 bpp      |     16 bpp	|     32 bpp	  |
-|	    | noypan |	 ypan | noypan |   ypan | noypan |   ypan |
-+-----------+--------+--------+--------+--------+--------+--------+
-|    Test 1 |	4.26 |	 3.76 |   5.99 |   7.23 |  ----  |  ----  |
-|    Test 2 |  65.65 |	 4.89 | 120.88 |   9.08 |  ----  |  ----  |
-|    Test 3 | 126.91 |	 5.94 | 235.77 |  11.03 |  ----  |  ----  |
-+-----------+--------+--------+--------+--------+--------+--------+
-|  Comments | vga=0x307       | vga=0x31a	| vga=0x31b not   |
-|	    | fh=80kHz	      | fh=80kHz	| supported by	  |
-|	    | fv=75kHz	      | fv=75kHz	| video BIOS and  |
-|	    |		      | 		| hardware	  |
-+-----------+-----------------+-----------------+-----------------+
-
-
-+-----------+-----------------------------------------------------+
-|	    |			  accelerated			  |
-|  CYBLAFB  +-----------------+-----------------+-----------------+
-|	    |	   8 bpp      |     16 bpp	|     32 bpp	  |
-|	    | noypan |	 ypan | noypan |   ypan | noypan |   ypan |
-+-----------+--------+--------+--------+--------+--------+--------+
-|    Test 1 |	8.02 |	 0.23 |  19.04 |   0.61 |  57.12 |   2.74 |
-|    Test 2 |	8.38 |	 0.55 |  19.39 |   0.92 |  57.54 |   3.13 |
-|    Test 3 |	8.73 |	 0.86 |  19.74 |   1.24 |  57.95 |   3.51 |
-+-----------+--------+--------+--------+--------+--------+--------+
-|  Comments |		      | 		|		  |
-|	    |		      | 		|		  |
-|	    |		      | 		|		  |
-|	    |		      | 		|		  |
-+-----------+-----------------+-----------------+-----------------+
diff --git a/Documentation/fb/cyblafb/todo b/Documentation/fb/cyblafb/todo
deleted file mode 100644
index c5f6d0e..0000000
--- a/Documentation/fb/cyblafb/todo
+++ /dev/null
@@ -1,31 +0,0 @@
-TODO / Missing features
-=======================
-
-Verify LCD stuff		"stretch" and "center" options are
-				completely untested ... this code needs to be
-				verified. As I don't have access to such
-				hardware, please contact me if you are
-				willing run some tests.
-
-Interlaced video modes		The reason that interleaved
-				modes are disabled is that I do not know
-				the meaning of the vertical interlace
-				parameter. Also the datasheet mentions a
-				bit d8 of a horizontal interlace parameter,
-				but nowhere the lower 8 bits. Please help
-				if you can.
-
-low-res double scan modes	Who needs it?
-
-accelerated color blitting	Who needs it? The console driver does use color
-				blitting for nothing but drawing the penguine,
-				everything else is done using color expanding
-				blitting of 1bpp character bitmaps.
-
-ioctls				Who needs it?
-
-TV-out				Will be done later. Use "vga= " at boot time
-				to set a suitable video mode.
-
-???				Feel free to contact me if you have any
-				feature requests
diff --git a/Documentation/fb/cyblafb/usage b/Documentation/fb/cyblafb/usage
deleted file mode 100644
index a39bb3d..0000000
--- a/Documentation/fb/cyblafb/usage
+++ /dev/null
@@ -1,217 +0,0 @@
-CyBlaFB is a framebuffer driver for the Cyberblade/i1 graphics core integrated
-into the VIA Apollo PLE133 (aka vt8601) south bridge. It is developed and
-tested using a VIA EPIA 5000 board.
-
-Cyblafb - compiled into the kernel or as a module?
-==================================================
-
-You might compile cyblafb either as a module or compile it permanently into the
-kernel.
-
-Unless you have a real reason to do so you should not compile both vesafb and
-cyblafb permanently into the kernel. It's possible and it helps during the
-developement cycle, but it's useless and will at least block some otherwise
-usefull memory for ordinary users.
-
-Selecting Modes
-===============
-
-	Startup Mode
-	============
-
-	First of all, you might use the "vga=???" boot parameter as it is
-	documented in vesafb.txt and svga.txt. Cyblafb will detect the video
-	mode selected and will use the geometry and timings found by
-	inspecting the hardware registers.
-
-		video=cyblafb vga=0x317
-
-	Alternatively you might use a combination of the mode, ref and bpp
-	parameters. If you compiled the driver into the kernel, add something
-	like this to the kernel command line:
-
-		video=cyblafb:1280x1024,bpp=16,ref=50 ...
-
-	If you compiled the driver as a module, the same mode would be
-	selected by the following command:
-
-		modprobe cyblafb mode=1280x1024 bpp=16 ref=50 ...
-
-	None of the modes possible to select as startup modes are affected by
-	the problems described at the end of the next subsection.
-
-	For all startup modes cyblafb chooses a virtual x resolution of 2048,
-	the only exception is mode 1280x1024 in combination with 32 bpp. This
-	allows ywrap scrolling for all those modes if rotation is 0 or 2, and
-	also fast scrolling if rotation is 1 or 3. The default virtual y reso-
-	lution is 4096 for bpp == 8, 2048 for bpp==16 and 1024 for bpp == 32,
-	again with the only exception of 1280x1024 at 32 bpp.
-
-	Please do set your video memory size to 8 Mb in the Bios setup. Other
-	values will work, but performace is decreased for a lot of modes.
-
-	Mode changes using fbset
-	========================
-
-	You might use fbset to change the video mode, see "man fbset". Cyblafb
-	generally does assume that you know what you are doing. But it does
-	some checks, especially those that are needed to prevent you from
-	damaging your hardware.
-
-		- only 8, 16, 24 and 32 bpp video modes are accepted
-		- interlaced video modes are not accepted
-		- double scan video modes are not accepted
-		- if a flat panel is found, cyblafb does not allow you
-		  to program a resolution higher than the physical
-		  resolution of the flat panel monitor
-		- cyblafb does not allow vclk to exceed 230 MHz. As 32 bpp
-		  and (currently) 24 bit modes use a doubled vclk internally,
-		  the dotclock limit as seen by fbset is 115 MHz for those
-		  modes and 230 MHz for 8 and 16 bpp modes.
-		- cyblafb will allow you to select very high resolutions as
-		  long as the hardware can be programmed to these modes. The
-		  documented limit 1600x1200 is not enforced, but don't expect
-		  perfect signal quality.
-
-	Any request that violates the rules given above will be either changed
-	to something the hardware supports or an error value will be returned.
-
-	If you program a virtual y resolution higher than the hardware limit,
-	cyblafb will silently decrease that value to the highest possible
-	value. The same is true for a virtual x resolution that is not
-	supported by the hardware. Cyblafb tries to adapt vyres first because
-	vxres decides if ywrap scrolling is possible or not.
-
-	Attempts to disable acceleration are ignored, I believe that this is
-	safe.
-
-	Some video modes that should work do not work as expected. If you use
-	the standard fb.modes, fbset 640x480-60 will program that mode, but
-	you will see a vertical area, about two characters wide, with only
-	much darker characters than the other characters on the screen.
-	Cyblafb does allow that mode to be set, as it does not violate the
-	official specifications. It would need a lot of code to reliably sort
-	out all invalid modes, playing around with the margin values will
-	give a valid mode quickly. And if cyblafb would detect such an invalid
-	mode, should it silently alter the requested values or should it
-	report an error? Both options have some pros and cons. As stated
-	above, none of the startup modes are affected, and if you set
-	verbosity to 1 or higher, cyblafb will print the fbset command that
-	would be needed to program that mode using fbset.
-
-
-Other Parameters
-================
-
-
-crt		don't autodetect, assume monitor connected to
-		standard VGA connector
-
-fp		don't autodetect, assume flat panel display
-		connected to flat panel monitor interface
-
-nativex 	inform driver about native x resolution of
-		flat panel monitor connected to special
-		interface (should be autodetected)
-
-stretch 	stretch image to adapt low resolution modes to
-		higer resolutions of flat panel monitors
-		connected to special interface
-
-center		center image to adapt low resolution modes to
-		higer resolutions of flat panel monitors
-		connected to special interface
-
-memsize 	use if autodetected memsize is wrong ...
-		should never be necessary
-
-nopcirr 	disable PCI read retry
-nopciwr 	disable PCI write retry
-nopcirb 	disable PCI read bursts
-nopciwb 	disable PCI write bursts
-
-bpp		bpp for specified modes
-		valid values: 8 || 16 || 24 || 32
-
-ref		refresh rate for specified mode
-		valid values: 50 <= ref <= 85
-
-mode		640x480 or 800x600 or 1024x768 or 1280x1024
-		if not specified, the startup mode will be detected
-		and used, so you might also use the vga=??? parameter
-		described in vesafb.txt. If you do not specify a mode,
-		bpp and ref parameters are ignored.
-
-verbosity	0 is the default, increase to at least 2 for every
-		bug report!
-
-Development hints
-=================
-
-It's much faster do compile a module and to load the new version after
-unloading the old module than to compile a new kernel and to reboot. So if you
-try to work on cyblafb, it might be a good idea to use cyblafb as a module.
-In real life, fast often means dangerous, and that's also the case here. If
-you introduce a serious bug when cyblafb is compiled into the kernel, the
-kernel will lock or oops with a high probability before the file system is
-mounted, and the danger for your data is low. If you load a broken own version
-of cyblafb on a running system, the danger for the integrity of the file
-system is much higher as you might need a hard reset afterwards. Decide
-yourself.
-
-Module unloading, the vfb method
-================================
-
-If you want to unload/reload cyblafb using the virtual framebuffer, you need
-to enable vfb support in the kernel first. After that, load the modules as
-shown below:
-
-	modprobe vfb vfb_enable=1
-	modprobe fbcon
-	modprobe cyblafb
-	fbset -fb /dev/fb1 1280x1024-60 -vyres 2662
-	con2fb /dev/fb1 /dev/tty1
-	...
-
-If you now made some changes to cyblafb and want to reload it, you might do it
-as show below:
-
-	con2fb /dev/fb0 /dev/tty1
-	...
-	rmmod cyblafb
-	modprobe cyblafb
-	con2fb /dev/fb1 /dev/tty1
-	...
-
-Of course, you might choose another mode, and most certainly you also want to
-map some other /dev/tty* to the real framebuffer device. You might also choose
-to compile fbcon as a kernel module or place it permanently in the kernel.
-
-I do not know of any way to unload fbcon, and fbcon will prevent the
-framebuffer device loaded first from unloading. [If there is a way, then
-please add a description here!]
-
-Module unloading, the vesafb method
-===================================
-
-Configure the kernel:
-
-	<*> Support for frame buffer devices
-	[*]   VESA VGA graphics support
-	<M>   Cyberblade/i1 support
-
-Add e.g. "video=vesafb:ypan vga=0x307" to the kernel parameters. The ypan
-parameter is important, choose any vga parameter you like as long as it is
-a graphics mode.
-
-After booting, load cyblafb without any mode and bpp parameter and assign
-cyblafb to individual ttys using con2fb, e.g.:
-
-	modprobe cyblafb
-	con2fb /dev/fb1 /dev/tty1
-
-Unloading cyblafb works without problems after you assign vesafb to all
-ttys again, e.g.:
-
-	con2fb /dev/fb0 /dev/tty1
-	rmmod cyblafb
diff --git a/Documentation/fb/cyblafb/whatsnew b/Documentation/fb/cyblafb/whatsnew
deleted file mode 100644
index 76c07a2..0000000
--- a/Documentation/fb/cyblafb/whatsnew
+++ /dev/null
@@ -1,29 +0,0 @@
-0.62
-====
-
-      - the vesafb parameter has been removed as I decided to allow the
-      	feature without any special parameter.
-
-      - Cyblafb does not use the vga style of panning any longer, now the
-      	"right view" register in the graphics engine IO space is used. Without
-	that change it was impossible to use all available memory, and without
-	access to all available memory it is impossible to ywrap.
-
-      - The imageblit function now uses hardware acceleration for all font
-        widths. Hardware blitting across pixel column 2048 is broken in the
-	cyberblade/i1 graphics core, but we work around that hardware bug.
-
-      - modes with vxres != xres are supported now.
-
-      - ywrap scrolling is supported now and the default. This is a big
-        performance gain.
-
-      - default video modes use vyres > yres and vxres > xres to allow
-        almost optimal scrolling speed for normal and rotated screens
-
-      - some features mainly usefull for debugging the upper layers of the
-        framebuffer system have been added, have a look at the code
-
-      - fixed: Oops after unloading cyblafb when reading /proc/io*
-
-      - we work around some bugs of the higher framebuffer layers.
diff --git a/Documentation/fb/cyblafb/whycyblafb b/Documentation/fb/cyblafb/whycyblafb
deleted file mode 100644
index a123bc1..0000000
--- a/Documentation/fb/cyblafb/whycyblafb
+++ /dev/null
@@ -1,85 +0,0 @@
-I tried the following framebuffer drivers:
-
-	- TRIDENTFB is full of bugs. Acceleration is broken for Blade3D
-	  graphics cores like the cyberblade/i1. It claims to support a great
-	  number of devices, but documentation for most of these devices is
-	  unfortunately not available. There is _no_ reason to use tridentfb
-	  for cyberblade/i1 + CRT users. VESAFB is faster, and the one
-	  advantage, mode switching, is broken in tridentfb.
-
-	- VESAFB is used by many distributions as a standard. Vesafb does
-	  not support mode switching. VESAFB is a bit faster than the working
-	  configurations of TRIDENTFB, but it is still too slow, even if you
-	  use ypan.
-
-	- EPIAFB (you'll find it on sourceforge) supports the Cyberblade/i1
-	  graphics core, but it still has serious bugs and developement seems
-	  to have stopped. This is the one driver with TV-out support. If you
-	  do need this feature, try epiafb.
-
-None of these drivers was a real option for me.
-
-I believe that is unreasonable to change code that announces to support 20
-devices if I only have more or less sufficient documentation for exactly one
-of these. The risk of breaking device foo while fixing device bar is too high.
-
-So I decided to start CyBlaFB as a stripped down tridentfb.
-
-All code specific to other Trident chips has been removed. After that there
-were a lot of cosmetic changes to increase the readability of the code. All
-register names were changed to those mnemonics used in the datasheet. Function
-and macro names were changed if they hindered easy understanding of the code.
-
-After that I debugged the code and implemented some new features. I'll try to
-give a little summary of the main changes:
-
-	- calculation of vertical and horizontal timings was fixed
-
-	- video signal quality has been improved dramatically
-
-	- acceleration:
-
-		- fillrect and copyarea were fixed and reenabled
-
-		- color expanding imageblit was newly implemented, color
-		  imageblit (only used to draw the penguine) still uses the
-		  generic code.
-
-		- init of the acceleration engine was improved and moved to a
-		  place where it really works ...
-
-		- sync function has a timeout now and tries to reset and
-		  reinit the accel engine if necessary
-
-		- fewer slow copyarea calls when doing ypan scrolling by using
-		  undocumented bit d21 of screen start address stored in
-		  CR2B[5]. BIOS does use it also, so this should be safe.
-
-	- cyblafb rejects any attempt to set modes that would cause vclk
-	  values above reasonable 230 MHz. 32bit modes use a clock
-	  multiplicator of 2, so fbset does show the correct values for
-	  pixclock but not for vclk in this case. The fbset limit is 115 MHz
-	  for 32 bpp modes.
-
-	- cyblafb rejects modes known to be broken or unimplemented (all
-	  interlaced modes, all doublescan modes for now)
-
-	- cyblafb now works independant of the video mode in effect at startup
-	  time (tridentfb does not init all needed registers to reasonable
-	  values)
-
-	- switching between video modes does work reliably now
-
-	- the first video mode now is the one selected on startup using the
-	  vga=???? mechanism or any of
-		- 640x480, 800x600, 1024x768, 1280x1024
-		- 8, 16, 24 or 32 bpp
-		- refresh between 50 Hz and 85 Hz, 1 Hz steps (1280x1024-32
-		  is limited to 63Hz)
-
-	- pci retry and pci burst mode are settable (try to disable if you
-	  experience latency problems)
-
-	- built as a module cyblafb might be unloaded and reloaded using
-	  the vfb module and con2vt or might be used together with vesafb
-
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 5e02b83..ea7d1bd 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -311,6 +311,18 @@
 
 ---------------------------
 
+What:	Ability for non root users to shm_get hugetlb pages based on mlock
+	resource limits
+When:	2.6.31
+Why:	Non root users need to be part of /proc/sys/vm/hugetlb_shm_group or
+	have CAP_IPC_LOCK to be able to allocate shm segments backed by
+	huge pages.  The mlock based rlimit check to allow shm hugetlb is
+	inconsistent with mmap based allocations.  Hence it is being
+	deprecated.
+Who:	Ravikiran Thirumalai <kiran@scalex86.org>
+
+---------------------------
+
 What:	CONFIG_THERMAL_HWMON
 When:	January 2009
 Why:	This option was introduced just to allow older lm-sensors userspace
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 4e78ce6..76efe5b 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -505,7 +505,7 @@
 	void (*open)(struct vm_area_struct*);
 	void (*close)(struct vm_area_struct*);
 	int (*fault)(struct vm_area_struct*, struct vm_fault *);
-	int (*page_mkwrite)(struct vm_area_struct *, struct page *);
+	int (*page_mkwrite)(struct vm_area_struct *, struct vm_fault *);
 	int (*access)(struct vm_area_struct *, unsigned long, void*, int, int);
 
 locking rules:
diff --git a/Documentation/hwmon/lis3lv02d b/Documentation/hwmon/lis3lv02d
index 287f8c9..effe949 100644
--- a/Documentation/hwmon/lis3lv02d
+++ b/Documentation/hwmon/lis3lv02d
@@ -1,11 +1,11 @@
 Kernel driver lis3lv02d
-==================
+=======================
 
 Supported chips:
 
   * STMicroelectronics LIS3LV02DL and LIS3LV02DQ
 
-Author:
+Authors:
         Yan Burman <burman.yan@gmail.com>
 	Eric Piel <eric.piel@tremplin-utc.net>
 
@@ -15,7 +15,7 @@
 
 This driver provides support for the accelerometer found in various HP
 laptops sporting the feature officially called "HP Mobile Data
-Protection System 3D" or "HP 3D DriveGuard". It detect automatically
+Protection System 3D" or "HP 3D DriveGuard". It detects automatically
 laptops with this sensor. Known models (for now the HP 2133, nc6420,
 nc2510, nc8510, nc84x0, nw9440 and nx9420) will have their axis
 automatically oriented on standard way (eg: you can directly play
@@ -27,7 +27,7 @@
 calibrate - read: values (x, y, z) that are used as the base for input
 		  class device operation.
             write: forces the base to be recalibrated with the current
-		  position.
+		   position.
 rate - reports the sampling rate of the accelerometer device in HZ
 
 This driver also provides an absolute input class device, allowing
@@ -48,7 +48,7 @@
 the accelerometer are converted into a "standard" organisation of the axes
 (aka "can play neverball out of the box"):
  * When the laptop is horizontal the position reported is about 0 for X and Y
-and a positive value for Z
+	and a positive value for Z
  * If the left side is elevated, X increases (becomes positive)
  * If the front side (where the touchpad is) is elevated, Y decreases
 	(becomes negative)
@@ -59,3 +59,13 @@
 laptop, please include the output of "dmidecode" plus the value of
 /sys/devices/platform/lis3lv02d/position in these four cases.
 
+Q&A
+---
+
+Q: How do I safely simulate freefall? I have an HP "portable
+workstation" which has about 3.5kg and a plastic case, so letting it
+fall to the ground is out of question...
+
+A: The sensor is pretty sensitive, so your hands can do it. Lift it
+into free space, follow the fall with your hands for like 10
+centimeters. That should be enough to trigger the detection.
diff --git a/Documentation/hwmon/ltc4215 b/Documentation/hwmon/ltc4215
new file mode 100644
index 0000000..2e6a21e
--- /dev/null
+++ b/Documentation/hwmon/ltc4215
@@ -0,0 +1,50 @@
+Kernel driver ltc4215
+=====================
+
+Supported chips:
+  * Linear Technology LTC4215
+    Prefix: 'ltc4215'
+    Addresses scanned: 0x44
+    Datasheet:
+        http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1003,C1006,C1163,P17572,D12697
+
+Author: Ira W. Snyder <iws@ovro.caltech.edu>
+
+
+Description
+-----------
+
+The LTC4215 controller allows a board to be safely inserted and removed
+from a live backplane.
+
+
+Usage Notes
+-----------
+
+This driver does not probe for LTC4215 devices, due to the fact that some
+of the possible addresses are unfriendly to probing. You will need to use
+the "force" parameter to tell the driver where to find the device.
+
+Example: the following will load the driver for an LTC4215 at address 0x44
+on I2C bus #0:
+$ modprobe ltc4215 force=0,0x44
+
+
+Sysfs entries
+-------------
+
+The LTC4215 has built-in limits for overvoltage, undervoltage, and
+undercurrent warnings. This makes it very likely that the reference
+circuit will be used.
+
+in1_input		input voltage
+in2_input		output voltage
+
+in1_min_alarm		input undervoltage alarm
+in1_max_alarm		input overvoltage alarm
+
+curr1_input		current
+curr1_max_alarm		overcurrent alarm
+
+power1_input		power usage
+power1_alarm		power bad alarm
diff --git a/Documentation/misc-devices/isl29003 b/Documentation/misc-devices/isl29003
new file mode 100644
index 0000000..c4ff5f3
--- /dev/null
+++ b/Documentation/misc-devices/isl29003
@@ -0,0 +1,62 @@
+Kernel driver isl29003
+=====================
+
+Supported chips:
+* Intersil ISL29003
+Prefix: 'isl29003'
+Addresses scanned: none
+Datasheet:
+http://www.intersil.com/data/fn/fn7464.pdf
+
+Author: Daniel Mack <daniel@caiaq.de>
+
+
+Description
+-----------
+The ISL29003 is an integrated light sensor with a 16-bit integrating type
+ADC, I2C user programmable lux range select for optimized counts/lux, and
+I2C multi-function control and monitoring capabilities. The internal ADC
+provides 16-bit resolution while rejecting 50Hz and 60Hz flicker caused by
+artificial light sources.
+
+The driver allows to set the lux range, the bit resolution, the operational
+mode (see below) and the power state of device and can read the current lux
+value, of course.
+
+
+Detection
+---------
+
+The ISL29003 does not have an ID register which could be used to identify
+it, so the detection routine will just try to read from the configured I2C
+addess and consider the device to be present as soon as it ACKs the
+transfer.
+
+
+Sysfs entries
+-------------
+
+range:
+	0: 0 lux to 1000 lux (default)
+	1: 0 lux to 4000 lux
+	2: 0 lux to 16,000 lux
+	3: 0 lux to 64,000 lux
+
+resolution:
+	0: 2^16 cycles (default)
+	1: 2^12 cycles
+	2: 2^8 cycles
+	3: 2^4 cycles
+
+mode:
+	0: diode1's current (unsigned 16bit) (default)
+	1: diode1's current (unsigned 16bit)
+	2: difference between diodes (l1 - l2, signed 15bit)
+
+power_state:
+	0: device is disabled (default)
+	1: device is enabled
+
+lux (read only):
+	returns the value from the last sensor reading
+
diff --git a/Documentation/powerpc/dts-bindings/mmc-spi-slot.txt b/Documentation/powerpc/dts-bindings/mmc-spi-slot.txt
new file mode 100644
index 0000000..c39ac28
--- /dev/null
+++ b/Documentation/powerpc/dts-bindings/mmc-spi-slot.txt
@@ -0,0 +1,23 @@
+MMC/SD/SDIO slot directly connected to a SPI bus
+
+Required properties:
+- compatible : should be "mmc-spi-slot".
+- reg : should specify SPI address (chip-select number).
+- spi-max-frequency : maximum frequency for this device (Hz).
+- voltage-ranges : two cells are required, first cell specifies minimum
+  slot voltage (mV), second cell specifies maximum slot voltage (mV).
+  Several ranges could be specified.
+- gpios : (optional) may specify GPIOs in this order: Card-Detect GPIO,
+  Write-Protect GPIO.
+
+Example:
+
+	mmc-slot@0 {
+		compatible = "fsl,mpc8323rdb-mmc-slot",
+			     "mmc-spi-slot";
+		reg = <0>;
+		gpios = <&qe_pio_d 14 1
+			 &qe_pio_d 15 0>;
+		voltage-ranges = <3300 3300>;
+		spi-max-frequency = <50000000>;
+	};
diff --git a/Documentation/sysrq.txt b/Documentation/sysrq.txt
index 9e592c7..afa2946 100644
--- a/Documentation/sysrq.txt
+++ b/Documentation/sysrq.txt
@@ -81,6 +81,8 @@
 
 'i'     - Send a SIGKILL to all processes, except for init.
 
+'j'     - Forcibly "Just thaw it" - filesystems frozen by the FIFREEZE ioctl.
+
 'k'     - Secure Access Key (SAK) Kills all programs on the current virtual
           console. NOTE: See important comments below in SAK section.
 
@@ -160,6 +162,9 @@
 are unable to kill any other way, especially if it's spawning other
 processes.
 
+"'J'ust thaw it" is useful if your system becomes unresponsive due to a frozen
+(probably root) filesystem via the FIFREEZE ioctl.
+
 *  Sometimes SysRq seems to get 'stuck' after using it, what can I do?
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 That happens to me, also. I've found that tapping shift, alt, and control
diff --git a/MAINTAINERS b/MAINTAINERS
index c5f4e9d..a64f292 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -357,6 +357,7 @@
 P:	Ivan Kokshaysky
 M:	ink@jurassic.park.msu.ru
 S:	Maintained for 2.4; PCI support for 2.6.
+L:	linux-alpha@vger.kernel.org
 
 AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER
 P:	Thomas Dahlmann
diff --git a/arch/alpha/include/asm/machvec.h b/arch/alpha/include/asm/machvec.h
index fea4ea7..13cd427 100644
--- a/arch/alpha/include/asm/machvec.h
+++ b/arch/alpha/include/asm/machvec.h
@@ -80,7 +80,7 @@
 	void (*update_irq_hw)(unsigned long, unsigned long, int);
 	void (*ack_irq)(unsigned long);
 	void (*device_interrupt)(unsigned long vector);
-	void (*machine_check)(u64 vector, u64 la);
+	void (*machine_check)(unsigned long vector, unsigned long la);
 
 	void (*smp_callin)(void);
 	void (*init_arch)(void);
diff --git a/arch/alpha/include/asm/system.h b/arch/alpha/include/asm/system.h
index afe20fa..5aa40cc 100644
--- a/arch/alpha/include/asm/system.h
+++ b/arch/alpha/include/asm/system.h
@@ -309,519 +309,72 @@
 #define tbia()		__tbi(-2, /* no second argument */)
 
 /*
- * Atomic exchange.
- * Since it can be used to implement critical sections
- * it must clobber "memory" (also for interrupts in UP).
+ * Atomic exchange routines.
  */
 
-static inline unsigned long
-__xchg_u8(volatile char *m, unsigned long val)
-{
-	unsigned long ret, tmp, addr64;
+#define __ASM__MB
+#define ____xchg(type, args...)		__xchg ## type ## _local(args)
+#define ____cmpxchg(type, args...)	__cmpxchg ## type ## _local(args)
+#include <asm/xchg.h>
 
-	__asm__ __volatile__(
-	"	andnot	%4,7,%3\n"
-	"	insbl	%1,%4,%1\n"
-	"1:	ldq_l	%2,0(%3)\n"
-	"	extbl	%2,%4,%0\n"
-	"	mskbl	%2,%4,%2\n"
-	"	or	%1,%2,%2\n"
-	"	stq_c	%2,0(%3)\n"
-	"	beq	%2,2f\n"
-#ifdef CONFIG_SMP
-	"	mb\n"
-#endif
-	".subsection 2\n"
-	"2:	br	1b\n"
-	".previous"
-	: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
-	: "r" ((long)m), "1" (val) : "memory");
-
-	return ret;
-}
-
-static inline unsigned long
-__xchg_u16(volatile short *m, unsigned long val)
-{
-	unsigned long ret, tmp, addr64;
-
-	__asm__ __volatile__(
-	"	andnot	%4,7,%3\n"
-	"	inswl	%1,%4,%1\n"
-	"1:	ldq_l	%2,0(%3)\n"
-	"	extwl	%2,%4,%0\n"
-	"	mskwl	%2,%4,%2\n"
-	"	or	%1,%2,%2\n"
-	"	stq_c	%2,0(%3)\n"
-	"	beq	%2,2f\n"
-#ifdef CONFIG_SMP
-	"	mb\n"
-#endif
-	".subsection 2\n"
-	"2:	br	1b\n"
-	".previous"
-	: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
-	: "r" ((long)m), "1" (val) : "memory");
-
-	return ret;
-}
-
-static inline unsigned long
-__xchg_u32(volatile int *m, unsigned long val)
-{
-	unsigned long dummy;
-
-	__asm__ __volatile__(
-	"1:	ldl_l %0,%4\n"
-	"	bis $31,%3,%1\n"
-	"	stl_c %1,%2\n"
-	"	beq %1,2f\n"
-#ifdef CONFIG_SMP
-	"	mb\n"
-#endif
-	".subsection 2\n"
-	"2:	br 1b\n"
-	".previous"
-	: "=&r" (val), "=&r" (dummy), "=m" (*m)
-	: "rI" (val), "m" (*m) : "memory");
-
-	return val;
-}
-
-static inline unsigned long
-__xchg_u64(volatile long *m, unsigned long val)
-{
-	unsigned long dummy;
-
-	__asm__ __volatile__(
-	"1:	ldq_l %0,%4\n"
-	"	bis $31,%3,%1\n"
-	"	stq_c %1,%2\n"
-	"	beq %1,2f\n"
-#ifdef CONFIG_SMP
-	"	mb\n"
-#endif
-	".subsection 2\n"
-	"2:	br 1b\n"
-	".previous"
-	: "=&r" (val), "=&r" (dummy), "=m" (*m)
-	: "rI" (val), "m" (*m) : "memory");
-
-	return val;
-}
-
-/* This function doesn't exist, so you'll get a linker error
-   if something tries to do an invalid xchg().  */
-extern void __xchg_called_with_bad_pointer(void);
-
-#define __xchg(ptr, x, size) \
-({ \
-	unsigned long __xchg__res; \
-	volatile void *__xchg__ptr = (ptr); \
-	switch (size) { \
-		case 1: __xchg__res = __xchg_u8(__xchg__ptr, x); break; \
-		case 2: __xchg__res = __xchg_u16(__xchg__ptr, x); break; \
-		case 4: __xchg__res = __xchg_u32(__xchg__ptr, x); break; \
-		case 8: __xchg__res = __xchg_u64(__xchg__ptr, x); break; \
-		default: __xchg_called_with_bad_pointer(); __xchg__res = x; \
-	} \
-	__xchg__res; \
-})
-
-#define xchg(ptr,x)							     \
-  ({									     \
-     __typeof__(*(ptr)) _x_ = (x);					     \
-     (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
+#define xchg_local(ptr,x)						\
+  ({									\
+     __typeof__(*(ptr)) _x_ = (x);					\
+     (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_,	\
+				       sizeof(*(ptr)));			\
   })
 
-static inline unsigned long
-__xchg_u8_local(volatile char *m, unsigned long val)
-{
-	unsigned long ret, tmp, addr64;
-
-	__asm__ __volatile__(
-	"	andnot	%4,7,%3\n"
-	"	insbl	%1,%4,%1\n"
-	"1:	ldq_l	%2,0(%3)\n"
-	"	extbl	%2,%4,%0\n"
-	"	mskbl	%2,%4,%2\n"
-	"	or	%1,%2,%2\n"
-	"	stq_c	%2,0(%3)\n"
-	"	beq	%2,2f\n"
-	".subsection 2\n"
-	"2:	br	1b\n"
-	".previous"
-	: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
-	: "r" ((long)m), "1" (val) : "memory");
-
-	return ret;
-}
-
-static inline unsigned long
-__xchg_u16_local(volatile short *m, unsigned long val)
-{
-	unsigned long ret, tmp, addr64;
-
-	__asm__ __volatile__(
-	"	andnot	%4,7,%3\n"
-	"	inswl	%1,%4,%1\n"
-	"1:	ldq_l	%2,0(%3)\n"
-	"	extwl	%2,%4,%0\n"
-	"	mskwl	%2,%4,%2\n"
-	"	or	%1,%2,%2\n"
-	"	stq_c	%2,0(%3)\n"
-	"	beq	%2,2f\n"
-	".subsection 2\n"
-	"2:	br	1b\n"
-	".previous"
-	: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
-	: "r" ((long)m), "1" (val) : "memory");
-
-	return ret;
-}
-
-static inline unsigned long
-__xchg_u32_local(volatile int *m, unsigned long val)
-{
-	unsigned long dummy;
-
-	__asm__ __volatile__(
-	"1:	ldl_l %0,%4\n"
-	"	bis $31,%3,%1\n"
-	"	stl_c %1,%2\n"
-	"	beq %1,2f\n"
-	".subsection 2\n"
-	"2:	br 1b\n"
-	".previous"
-	: "=&r" (val), "=&r" (dummy), "=m" (*m)
-	: "rI" (val), "m" (*m) : "memory");
-
-	return val;
-}
-
-static inline unsigned long
-__xchg_u64_local(volatile long *m, unsigned long val)
-{
-	unsigned long dummy;
-
-	__asm__ __volatile__(
-	"1:	ldq_l %0,%4\n"
-	"	bis $31,%3,%1\n"
-	"	stq_c %1,%2\n"
-	"	beq %1,2f\n"
-	".subsection 2\n"
-	"2:	br 1b\n"
-	".previous"
-	: "=&r" (val), "=&r" (dummy), "=m" (*m)
-	: "rI" (val), "m" (*m) : "memory");
-
-	return val;
-}
-
-#define __xchg_local(ptr, x, size) \
-({ \
-	unsigned long __xchg__res; \
-	volatile void *__xchg__ptr = (ptr); \
-	switch (size) { \
-		case 1: __xchg__res = __xchg_u8_local(__xchg__ptr, x); break; \
-		case 2: __xchg__res = __xchg_u16_local(__xchg__ptr, x); break; \
-		case 4: __xchg__res = __xchg_u32_local(__xchg__ptr, x); break; \
-		case 8: __xchg__res = __xchg_u64_local(__xchg__ptr, x); break; \
-		default: __xchg_called_with_bad_pointer(); __xchg__res = x; \
-	} \
-	__xchg__res; \
-})
-
-#define xchg_local(ptr,x)						     \
-  ({									     \
-     __typeof__(*(ptr)) _x_ = (x);					     \
-     (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_,	     \
-     		sizeof(*(ptr))); \
+#define cmpxchg_local(ptr, o, n)					\
+  ({									\
+     __typeof__(*(ptr)) _o_ = (o);					\
+     __typeof__(*(ptr)) _n_ = (n);					\
+     (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_,	\
+					  (unsigned long)_n_,		\
+					  sizeof(*(ptr)));		\
   })
 
-/* 
- * Atomic compare and exchange.  Compare OLD with MEM, if identical,
- * store NEW in MEM.  Return the initial value in MEM.  Success is
- * indicated by comparing RETURN with OLD.
- *
- * The memory barrier should be placed in SMP only when we actually
- * make the change. If we don't change anything (so if the returned
- * prev is equal to old) then we aren't acquiring anything new and
- * we don't need any memory barrier as far I can tell.
- */
+#define cmpxchg64_local(ptr, o, n)					\
+  ({									\
+	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				\
+	cmpxchg_local((ptr), (o), (n));					\
+  })
+
+#ifdef CONFIG_SMP
+#undef __ASM__MB
+#define __ASM__MB	"\tmb\n"
+#endif
+#undef ____xchg
+#undef ____cmpxchg
+#define ____xchg(type, args...)		__xchg ##type(args)
+#define ____cmpxchg(type, args...)	__cmpxchg ##type(args)
+#include <asm/xchg.h>
+
+#define xchg(ptr,x)							\
+  ({									\
+     __typeof__(*(ptr)) _x_ = (x);					\
+     (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_,		\
+				 sizeof(*(ptr)));			\
+  })
+
+#define cmpxchg(ptr, o, n)						\
+  ({									\
+     __typeof__(*(ptr)) _o_ = (o);					\
+     __typeof__(*(ptr)) _n_ = (n);					\
+     (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,		\
+				    (unsigned long)_n_,	sizeof(*(ptr)));\
+  })
+
+#define cmpxchg64(ptr, o, n)						\
+  ({									\
+	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				\
+	cmpxchg((ptr), (o), (n));					\
+  })
+
+#undef __ASM__MB
+#undef ____cmpxchg
 
 #define __HAVE_ARCH_CMPXCHG 1
 
-static inline unsigned long
-__cmpxchg_u8(volatile char *m, long old, long new)
-{
-	unsigned long prev, tmp, cmp, addr64;
-
-	__asm__ __volatile__(
-	"	andnot	%5,7,%4\n"
-	"	insbl	%1,%5,%1\n"
-	"1:	ldq_l	%2,0(%4)\n"
-	"	extbl	%2,%5,%0\n"
-	"	cmpeq	%0,%6,%3\n"
-	"	beq	%3,2f\n"
-	"	mskbl	%2,%5,%2\n"
-	"	or	%1,%2,%2\n"
-	"	stq_c	%2,0(%4)\n"
-	"	beq	%2,3f\n"
-#ifdef CONFIG_SMP
-	"	mb\n"
-#endif
-	"2:\n"
-	".subsection 2\n"
-	"3:	br	1b\n"
-	".previous"
-	: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
-	: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
-
-	return prev;
-}
-
-static inline unsigned long
-__cmpxchg_u16(volatile short *m, long old, long new)
-{
-	unsigned long prev, tmp, cmp, addr64;
-
-	__asm__ __volatile__(
-	"	andnot	%5,7,%4\n"
-	"	inswl	%1,%5,%1\n"
-	"1:	ldq_l	%2,0(%4)\n"
-	"	extwl	%2,%5,%0\n"
-	"	cmpeq	%0,%6,%3\n"
-	"	beq	%3,2f\n"
-	"	mskwl	%2,%5,%2\n"
-	"	or	%1,%2,%2\n"
-	"	stq_c	%2,0(%4)\n"
-	"	beq	%2,3f\n"
-#ifdef CONFIG_SMP
-	"	mb\n"
-#endif
-	"2:\n"
-	".subsection 2\n"
-	"3:	br	1b\n"
-	".previous"
-	: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
-	: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
-
-	return prev;
-}
-
-static inline unsigned long
-__cmpxchg_u32(volatile int *m, int old, int new)
-{
-	unsigned long prev, cmp;
-
-	__asm__ __volatile__(
-	"1:	ldl_l %0,%5\n"
-	"	cmpeq %0,%3,%1\n"
-	"	beq %1,2f\n"
-	"	mov %4,%1\n"
-	"	stl_c %1,%2\n"
-	"	beq %1,3f\n"
-#ifdef CONFIG_SMP
-	"	mb\n"
-#endif
-	"2:\n"
-	".subsection 2\n"
-	"3:	br 1b\n"
-	".previous"
-	: "=&r"(prev), "=&r"(cmp), "=m"(*m)
-	: "r"((long) old), "r"(new), "m"(*m) : "memory");
-
-	return prev;
-}
-
-static inline unsigned long
-__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
-{
-	unsigned long prev, cmp;
-
-	__asm__ __volatile__(
-	"1:	ldq_l %0,%5\n"
-	"	cmpeq %0,%3,%1\n"
-	"	beq %1,2f\n"
-	"	mov %4,%1\n"
-	"	stq_c %1,%2\n"
-	"	beq %1,3f\n"
-#ifdef CONFIG_SMP
-	"	mb\n"
-#endif
-	"2:\n"
-	".subsection 2\n"
-	"3:	br 1b\n"
-	".previous"
-	: "=&r"(prev), "=&r"(cmp), "=m"(*m)
-	: "r"((long) old), "r"(new), "m"(*m) : "memory");
-
-	return prev;
-}
-
-/* This function doesn't exist, so you'll get a linker error
-   if something tries to do an invalid cmpxchg().  */
-extern void __cmpxchg_called_with_bad_pointer(void);
-
-static __always_inline unsigned long
-__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
-{
-	switch (size) {
-		case 1:
-			return __cmpxchg_u8(ptr, old, new);
-		case 2:
-			return __cmpxchg_u16(ptr, old, new);
-		case 4:
-			return __cmpxchg_u32(ptr, old, new);
-		case 8:
-			return __cmpxchg_u64(ptr, old, new);
-	}
-	__cmpxchg_called_with_bad_pointer();
-	return old;
-}
-
-#define cmpxchg(ptr, o, n)						 \
-  ({									 \
-     __typeof__(*(ptr)) _o_ = (o);					 \
-     __typeof__(*(ptr)) _n_ = (n);					 \
-     (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,		 \
-				    (unsigned long)_n_, sizeof(*(ptr))); \
-  })
-#define cmpxchg64(ptr, o, n)						 \
-  ({									 \
-	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				 \
-	cmpxchg((ptr), (o), (n));					 \
-  })
-
-static inline unsigned long
-__cmpxchg_u8_local(volatile char *m, long old, long new)
-{
-	unsigned long prev, tmp, cmp, addr64;
-
-	__asm__ __volatile__(
-	"	andnot	%5,7,%4\n"
-	"	insbl	%1,%5,%1\n"
-	"1:	ldq_l	%2,0(%4)\n"
-	"	extbl	%2,%5,%0\n"
-	"	cmpeq	%0,%6,%3\n"
-	"	beq	%3,2f\n"
-	"	mskbl	%2,%5,%2\n"
-	"	or	%1,%2,%2\n"
-	"	stq_c	%2,0(%4)\n"
-	"	beq	%2,3f\n"
-	"2:\n"
-	".subsection 2\n"
-	"3:	br	1b\n"
-	".previous"
-	: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
-	: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
-
-	return prev;
-}
-
-static inline unsigned long
-__cmpxchg_u16_local(volatile short *m, long old, long new)
-{
-	unsigned long prev, tmp, cmp, addr64;
-
-	__asm__ __volatile__(
-	"	andnot	%5,7,%4\n"
-	"	inswl	%1,%5,%1\n"
-	"1:	ldq_l	%2,0(%4)\n"
-	"	extwl	%2,%5,%0\n"
-	"	cmpeq	%0,%6,%3\n"
-	"	beq	%3,2f\n"
-	"	mskwl	%2,%5,%2\n"
-	"	or	%1,%2,%2\n"
-	"	stq_c	%2,0(%4)\n"
-	"	beq	%2,3f\n"
-	"2:\n"
-	".subsection 2\n"
-	"3:	br	1b\n"
-	".previous"
-	: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
-	: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
-
-	return prev;
-}
-
-static inline unsigned long
-__cmpxchg_u32_local(volatile int *m, int old, int new)
-{
-	unsigned long prev, cmp;
-
-	__asm__ __volatile__(
-	"1:	ldl_l %0,%5\n"
-	"	cmpeq %0,%3,%1\n"
-	"	beq %1,2f\n"
-	"	mov %4,%1\n"
-	"	stl_c %1,%2\n"
-	"	beq %1,3f\n"
-	"2:\n"
-	".subsection 2\n"
-	"3:	br 1b\n"
-	".previous"
-	: "=&r"(prev), "=&r"(cmp), "=m"(*m)
-	: "r"((long) old), "r"(new), "m"(*m) : "memory");
-
-	return prev;
-}
-
-static inline unsigned long
-__cmpxchg_u64_local(volatile long *m, unsigned long old, unsigned long new)
-{
-	unsigned long prev, cmp;
-
-	__asm__ __volatile__(
-	"1:	ldq_l %0,%5\n"
-	"	cmpeq %0,%3,%1\n"
-	"	beq %1,2f\n"
-	"	mov %4,%1\n"
-	"	stq_c %1,%2\n"
-	"	beq %1,3f\n"
-	"2:\n"
-	".subsection 2\n"
-	"3:	br 1b\n"
-	".previous"
-	: "=&r"(prev), "=&r"(cmp), "=m"(*m)
-	: "r"((long) old), "r"(new), "m"(*m) : "memory");
-
-	return prev;
-}
-
-static __always_inline unsigned long
-__cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
-		int size)
-{
-	switch (size) {
-		case 1:
-			return __cmpxchg_u8_local(ptr, old, new);
-		case 2:
-			return __cmpxchg_u16_local(ptr, old, new);
-		case 4:
-			return __cmpxchg_u32_local(ptr, old, new);
-		case 8:
-			return __cmpxchg_u64_local(ptr, old, new);
-	}
-	__cmpxchg_called_with_bad_pointer();
-	return old;
-}
-
-#define cmpxchg_local(ptr, o, n)					 \
-  ({									 \
-     __typeof__(*(ptr)) _o_ = (o);					 \
-     __typeof__(*(ptr)) _n_ = (n);					 \
-     (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_,	 \
-				    (unsigned long)_n_, sizeof(*(ptr))); \
-  })
-#define cmpxchg64_local(ptr, o, n)					 \
-  ({									 \
-	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				 \
-	cmpxchg_local((ptr), (o), (n));					 \
-  })
-
-
 #endif /* __ASSEMBLY__ */
 
 #define arch_align_stack(x) (x)
diff --git a/arch/alpha/include/asm/types.h b/arch/alpha/include/asm/types.h
index c154135..f072f34 100644
--- a/arch/alpha/include/asm/types.h
+++ b/arch/alpha/include/asm/types.h
@@ -8,7 +8,12 @@
  * not a major issue.  However, for interoperability, libraries still
  * need to be careful to avoid a name clashes.
  */
+
+#ifdef __KERNEL__
+#include <asm-generic/int-ll64.h>
+#else
 #include <asm-generic/int-l64.h>
+#endif
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/alpha/include/asm/uaccess.h b/arch/alpha/include/asm/uaccess.h
index 22de3b4..163f305 100644
--- a/arch/alpha/include/asm/uaccess.h
+++ b/arch/alpha/include/asm/uaccess.h
@@ -498,13 +498,13 @@
 };
 
 /* Returns the new pc */
-#define fixup_exception(map_reg, fixup, pc)			\
+#define fixup_exception(map_reg, _fixup, pc)			\
 ({								\
-	if ((fixup)->fixup.bits.valreg != 31)			\
-		map_reg((fixup)->fixup.bits.valreg) = 0;	\
-	if ((fixup)->fixup.bits.errreg != 31)			\
-		map_reg((fixup)->fixup.bits.errreg) = -EFAULT;	\
-	(pc) + (fixup)->fixup.bits.nextinsn;			\
+	if ((_fixup)->fixup.bits.valreg != 31)			\
+		map_reg((_fixup)->fixup.bits.valreg) = 0;	\
+	if ((_fixup)->fixup.bits.errreg != 31)			\
+		map_reg((_fixup)->fixup.bits.errreg) = -EFAULT;	\
+	(pc) + (_fixup)->fixup.bits.nextinsn;			\
 })
 
 
diff --git a/arch/alpha/include/asm/xchg.h b/arch/alpha/include/asm/xchg.h
new file mode 100644
index 0000000..beba1b8
--- /dev/null
+++ b/arch/alpha/include/asm/xchg.h
@@ -0,0 +1,258 @@
+#ifndef __ALPHA_SYSTEM_H
+#error Do not include xchg.h directly!
+#else
+/*
+ * xchg/xchg_local and cmpxchg/cmpxchg_local share the same code
+ * except that local version do not have the expensive memory barrier.
+ * So this file is included twice from asm/system.h.
+ */
+
+/*
+ * Atomic exchange.
+ * Since it can be used to implement critical sections
+ * it must clobber "memory" (also for interrupts in UP).
+ */
+
+static inline unsigned long
+____xchg(_u8, volatile char *m, unsigned long val)
+{
+	unsigned long ret, tmp, addr64;
+
+	__asm__ __volatile__(
+	"	andnot	%4,7,%3\n"
+	"	insbl	%1,%4,%1\n"
+	"1:	ldq_l	%2,0(%3)\n"
+	"	extbl	%2,%4,%0\n"
+	"	mskbl	%2,%4,%2\n"
+	"	or	%1,%2,%2\n"
+	"	stq_c	%2,0(%3)\n"
+	"	beq	%2,2f\n"
+		__ASM__MB
+	".subsection 2\n"
+	"2:	br	1b\n"
+	".previous"
+	: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
+	: "r" ((long)m), "1" (val) : "memory");
+
+	return ret;
+}
+
+static inline unsigned long
+____xchg(_u16, volatile short *m, unsigned long val)
+{
+	unsigned long ret, tmp, addr64;
+
+	__asm__ __volatile__(
+	"	andnot	%4,7,%3\n"
+	"	inswl	%1,%4,%1\n"
+	"1:	ldq_l	%2,0(%3)\n"
+	"	extwl	%2,%4,%0\n"
+	"	mskwl	%2,%4,%2\n"
+	"	or	%1,%2,%2\n"
+	"	stq_c	%2,0(%3)\n"
+	"	beq	%2,2f\n"
+		__ASM__MB
+	".subsection 2\n"
+	"2:	br	1b\n"
+	".previous"
+	: "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
+	: "r" ((long)m), "1" (val) : "memory");
+
+	return ret;
+}
+
+static inline unsigned long
+____xchg(_u32, volatile int *m, unsigned long val)
+{
+	unsigned long dummy;
+
+	__asm__ __volatile__(
+	"1:	ldl_l %0,%4\n"
+	"	bis $31,%3,%1\n"
+	"	stl_c %1,%2\n"
+	"	beq %1,2f\n"
+		__ASM__MB
+	".subsection 2\n"
+	"2:	br 1b\n"
+	".previous"
+	: "=&r" (val), "=&r" (dummy), "=m" (*m)
+	: "rI" (val), "m" (*m) : "memory");
+
+	return val;
+}
+
+static inline unsigned long
+____xchg(_u64, volatile long *m, unsigned long val)
+{
+	unsigned long dummy;
+
+	__asm__ __volatile__(
+	"1:	ldq_l %0,%4\n"
+	"	bis $31,%3,%1\n"
+	"	stq_c %1,%2\n"
+	"	beq %1,2f\n"
+		__ASM__MB
+	".subsection 2\n"
+	"2:	br 1b\n"
+	".previous"
+	: "=&r" (val), "=&r" (dummy), "=m" (*m)
+	: "rI" (val), "m" (*m) : "memory");
+
+	return val;
+}
+
+/* This function doesn't exist, so you'll get a linker error
+   if something tries to do an invalid xchg().  */
+extern void __xchg_called_with_bad_pointer(void);
+
+static __always_inline unsigned long
+____xchg(, volatile void *ptr, unsigned long x, int size)
+{
+	switch (size) {
+		case 1:
+			return ____xchg(_u8, ptr, x);
+		case 2:
+			return ____xchg(_u16, ptr, x);
+		case 4:
+			return ____xchg(_u32, ptr, x);
+		case 8:
+			return ____xchg(_u64, ptr, x);
+	}
+	__xchg_called_with_bad_pointer();
+	return x;
+}
+
+/*
+ * Atomic compare and exchange.  Compare OLD with MEM, if identical,
+ * store NEW in MEM.  Return the initial value in MEM.  Success is
+ * indicated by comparing RETURN with OLD.
+ *
+ * The memory barrier should be placed in SMP only when we actually
+ * make the change. If we don't change anything (so if the returned
+ * prev is equal to old) then we aren't acquiring anything new and
+ * we don't need any memory barrier as far I can tell.
+ */
+
+static inline unsigned long
+____cmpxchg(_u8, volatile char *m, unsigned char old, unsigned char new)
+{
+	unsigned long prev, tmp, cmp, addr64;
+
+	__asm__ __volatile__(
+	"	andnot	%5,7,%4\n"
+	"	insbl	%1,%5,%1\n"
+	"1:	ldq_l	%2,0(%4)\n"
+	"	extbl	%2,%5,%0\n"
+	"	cmpeq	%0,%6,%3\n"
+	"	beq	%3,2f\n"
+	"	mskbl	%2,%5,%2\n"
+	"	or	%1,%2,%2\n"
+	"	stq_c	%2,0(%4)\n"
+	"	beq	%2,3f\n"
+		__ASM__MB
+	"2:\n"
+	".subsection 2\n"
+	"3:	br	1b\n"
+	".previous"
+	: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
+	: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
+
+	return prev;
+}
+
+static inline unsigned long
+____cmpxchg(_u16, volatile short *m, unsigned short old, unsigned short new)
+{
+	unsigned long prev, tmp, cmp, addr64;
+
+	__asm__ __volatile__(
+	"	andnot	%5,7,%4\n"
+	"	inswl	%1,%5,%1\n"
+	"1:	ldq_l	%2,0(%4)\n"
+	"	extwl	%2,%5,%0\n"
+	"	cmpeq	%0,%6,%3\n"
+	"	beq	%3,2f\n"
+	"	mskwl	%2,%5,%2\n"
+	"	or	%1,%2,%2\n"
+	"	stq_c	%2,0(%4)\n"
+	"	beq	%2,3f\n"
+		__ASM__MB
+	"2:\n"
+	".subsection 2\n"
+	"3:	br	1b\n"
+	".previous"
+	: "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
+	: "r" ((long)m), "Ir" (old), "1" (new) : "memory");
+
+	return prev;
+}
+
+static inline unsigned long
+____cmpxchg(_u32, volatile int *m, int old, int new)
+{
+	unsigned long prev, cmp;
+
+	__asm__ __volatile__(
+	"1:	ldl_l %0,%5\n"
+	"	cmpeq %0,%3,%1\n"
+	"	beq %1,2f\n"
+	"	mov %4,%1\n"
+	"	stl_c %1,%2\n"
+	"	beq %1,3f\n"
+		__ASM__MB
+	"2:\n"
+	".subsection 2\n"
+	"3:	br 1b\n"
+	".previous"
+	: "=&r"(prev), "=&r"(cmp), "=m"(*m)
+	: "r"((long) old), "r"(new), "m"(*m) : "memory");
+
+	return prev;
+}
+
+static inline unsigned long
+____cmpxchg(_u64, volatile long *m, unsigned long old, unsigned long new)
+{
+	unsigned long prev, cmp;
+
+	__asm__ __volatile__(
+	"1:	ldq_l %0,%5\n"
+	"	cmpeq %0,%3,%1\n"
+	"	beq %1,2f\n"
+	"	mov %4,%1\n"
+	"	stq_c %1,%2\n"
+	"	beq %1,3f\n"
+		__ASM__MB
+	"2:\n"
+	".subsection 2\n"
+	"3:	br 1b\n"
+	".previous"
+	: "=&r"(prev), "=&r"(cmp), "=m"(*m)
+	: "r"((long) old), "r"(new), "m"(*m) : "memory");
+
+	return prev;
+}
+
+/* This function doesn't exist, so you'll get a linker error
+   if something tries to do an invalid cmpxchg().  */
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+static __always_inline unsigned long
+____cmpxchg(, volatile void *ptr, unsigned long old, unsigned long new,
+	      int size)
+{
+	switch (size) {
+		case 1:
+			return ____cmpxchg(_u8, ptr, old, new);
+		case 2:
+			return ____cmpxchg(_u16, ptr, old, new);
+		case 4:
+			return ____cmpxchg(_u32, ptr, old, new);
+		case 8:
+			return ____cmpxchg(_u64, ptr, old, new);
+	}
+	__cmpxchg_called_with_bad_pointer();
+	return old;
+}
+
+#endif
diff --git a/arch/alpha/kernel/err_ev6.c b/arch/alpha/kernel/err_ev6.c
index 11aee01..985e5c1 100644
--- a/arch/alpha/kernel/err_ev6.c
+++ b/arch/alpha/kernel/err_ev6.c
@@ -157,8 +157,8 @@
 		       err_print_prefix,
 		       streamname[stream], bitsname[bits], sourcename[source]);
 
-	printk("%s    Address: 0x%016lx\n"
-	         "    Syndrome[upper.lower]: %02lx.%02lx\n", 
+	printk("%s    Address: 0x%016llx\n"
+	         "    Syndrome[upper.lower]: %02llx.%02llx\n",
 	       err_print_prefix,
 	       c_addr,
 	       c2_syn, c1_syn);
diff --git a/arch/alpha/kernel/err_ev7.c b/arch/alpha/kernel/err_ev7.c
index 68cd493..73770c6 100644
--- a/arch/alpha/kernel/err_ev7.c
+++ b/arch/alpha/kernel/err_ev7.c
@@ -246,13 +246,13 @@
 
 	switch(header->type) {
 	case EL_TYPE__PAL__LOGOUT_FRAME:
-		printk("%s*** MCHK occurred on LPID %ld (RBOX %lx)\n",
+		printk("%s*** MCHK occurred on LPID %ld (RBOX %llx)\n",
 		       err_print_prefix,
 		       packet->by_type.logout.whami, 
 		       packet->by_type.logout.rbox_whami);
 		el_print_timestamp(&packet->by_type.logout.timestamp);
-		printk("%s  EXC_ADDR: %016lx\n"
-		         "  HALT_CODE: %lx\n", 
+		printk("%s  EXC_ADDR: %016llx\n"
+		         "  HALT_CODE: %llx\n",
 		       err_print_prefix,
 		       packet->by_type.logout.exc_addr,
 		       packet->by_type.logout.halt_code);
diff --git a/arch/alpha/kernel/err_marvel.c b/arch/alpha/kernel/err_marvel.c
index 413bf37..6bfd243 100644
--- a/arch/alpha/kernel/err_marvel.c
+++ b/arch/alpha/kernel/err_marvel.c
@@ -129,7 +129,7 @@
 
 
 	printk("%s      Correctable Error Symptoms:\n"
-	       "%s        Syndrome: 0x%lx\n",
+	       "%s        Syndrome: 0x%llx\n",
 	       err_print_prefix,
 	       err_print_prefix, EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__SYN));
 	marvel_print_err_cyc(EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__ERR_CYC));
@@ -186,7 +186,7 @@
 	uncrr_sym &= valid_mask;
 
 	if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__SYN))
-		printk("%s        Syndrome: 0x%lx\n",
+		printk("%s        Syndrome: 0x%llx\n",
 		       err_print_prefix, 
 		       EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__SYN));
 
@@ -307,7 +307,7 @@
 		sprintf(opcode_str, "BlkIO");
 		break;
 	default:
-		sprintf(opcode_str, "0x%lx\n", 
+		sprintf(opcode_str, "0x%llx\n",
 			EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE));
 		break;
 	}
@@ -321,7 +321,7 @@
 	       opcode_str);
 
 	if (0xC5 != EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE))
-		printk("%s        Packet Offset 0x%08lx\n",
+		printk("%s        Packet Offset 0x%08llx\n",
 		       err_print_prefix,
 		       EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_PKT_OFF));
 }
@@ -480,8 +480,8 @@
 		printk("%s    Lost Error\n", err_print_prefix);
 
 	printk("%s    Failing Packet:\n"
-	       "%s      Cycle 1: %016lx\n"
-	       "%s      Cycle 2: %016lx\n",
+	       "%s      Cycle 1: %016llx\n"
+	       "%s      Cycle 2: %016llx\n",
 	       err_print_prefix,
 	       err_print_prefix, io->po7_err_pkt0,
 	       err_print_prefix, io->po7_err_pkt1);
@@ -515,9 +515,9 @@
 	if (!(tlb_err & IO7__POX_TLBERR__ERR_VALID))
 		return;
 
-	printk("%s      TLB Error on index 0x%lx:\n"
+	printk("%s      TLB Error on index 0x%llx:\n"
 	       "%s        - %s\n"
-	       "%s        - Addr: 0x%016lx\n",
+	       "%s        - Addr: 0x%016llx\n",
 	       err_print_prefix,
 	       EXTRACT(tlb_err, IO7__POX_TLBERR__ERR_TLB_PTR),
 	       err_print_prefix,
@@ -579,7 +579,7 @@
 		sprintf(message, "Uncorrectable Split Write Data Error");
 		break;
 	default:
-		sprintf(message, "%08lx\n", 
+		sprintf(message, "%08llx\n",
 			EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__MESSAGE));
 		break;
 	}
@@ -620,9 +620,9 @@
 		return;
 
 	printk("%s      Transaction Summary:\n"
-	       "%s        Command: 0x%lx - %s\n"
-	       "%s        Address: 0x%016lx%s\n"
-	       "%s        PCI-X Master Slot: 0x%lx\n",
+	       "%s        Command: 0x%llx - %s\n"
+	       "%s        Address: 0x%016llx%s\n"
+	       "%s        PCI-X Master Slot: 0x%llx\n",
 	       err_print_prefix, 
 	       err_print_prefix, 
 	       EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_CMD),
@@ -964,12 +964,12 @@
 
 #if 0
 		printk("%s  PORT 7 ERROR:\n"
-		       "%s    PO7_ERROR_SUM: %016lx\n"
-		       "%s    PO7_UNCRR_SYM: %016lx\n"
-		       "%s    PO7_CRRCT_SYM: %016lx\n"
-		       "%s    PO7_UGBGE_SYM: %016lx\n"
-		       "%s    PO7_ERR_PKT0:  %016lx\n"
-		       "%s    PO7_ERR_PKT1:  %016lx\n",
+		       "%s    PO7_ERROR_SUM: %016llx\n"
+		       "%s    PO7_UNCRR_SYM: %016llx\n"
+		       "%s    PO7_CRRCT_SYM: %016llx\n"
+		       "%s    PO7_UGBGE_SYM: %016llx\n"
+		       "%s    PO7_ERR_PKT0:  %016llx\n"
+		       "%s    PO7_ERR_PKT1:  %016llx\n",
 		       err_print_prefix,
 		       err_print_prefix, io->po7_error_sum,
 		       err_print_prefix, io->po7_uncrr_sym,
@@ -987,12 +987,12 @@
 		if (!MARVEL_IO_ERR_VALID(io->ports[i].pox_err_sum))
 			continue;
 
-		printk("%s  PID %u PORT %d POx_ERR_SUM: %016lx\n", 
+		printk("%s  PID %u PORT %d POx_ERR_SUM: %016llx\n",
 		       err_print_prefix, 
 		       lf_subpackets->io_pid, i, io->ports[i].pox_err_sum);
 		marvel_print_pox_err(io->ports[i].pox_err_sum, &io->ports[i]);
 
-		printk("%s  [ POx_FIRST_ERR: %016lx ]\n", 
+		printk("%s  [ POx_FIRST_ERR: %016llx ]\n",
 		       err_print_prefix, io->ports[i].pox_first_err);
 		marvel_print_pox_err(io->ports[i].pox_first_err, 
 				     &io->ports[i]);
diff --git a/arch/alpha/kernel/err_titan.c b/arch/alpha/kernel/err_titan.c
index 257449e..c7e28a8 100644
--- a/arch/alpha/kernel/err_titan.c
+++ b/arch/alpha/kernel/err_titan.c
@@ -107,12 +107,12 @@
 	if (!print)
 		return status;
 
-	printk("%s  PChip %d SERROR: %016lx\n", 
+	printk("%s  PChip %d SERROR: %016llx\n",
 	       err_print_prefix, which, serror);
 	if (serror & TITAN__PCHIP_SERROR__ECCMASK) {
 		printk("%s    %sorrectable ECC Error:\n"
 		       "      Source: %-6s  Command: %-8s  Syndrome: 0x%08x\n"
-		       "      Address: 0x%lx\n", 
+		       "      Address: 0x%llx\n",
 		       err_print_prefix,
 		       (serror & TITAN__PCHIP_SERROR__UECC) ? "Unc" : "C",
 		       serror_src[EXTRACT(serror, TITAN__PCHIP_SERROR__SRC)],
@@ -223,7 +223,7 @@
 	if (!print) 
 		return status;
 
-	printk("%s  PChip %d %cPERROR: %016lx\n", 
+	printk("%s  PChip %d %cPERROR: %016llx\n",
 	       err_print_prefix, which, 
 	       port ? 'A' : 'G', perror);
 	if (perror & TITAN__PCHIP_PERROR__IPTPW)
@@ -316,7 +316,7 @@
 	addr = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__ADDR) << 3;
 	len = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__LEN);
 
-	printk("%s  PChip %d AGPERROR: %016lx\n", err_print_prefix,
+	printk("%s  PChip %d AGPERROR: %016llx\n", err_print_prefix,
 	       which, agperror);
 	if (agperror & TITAN__PCHIP_AGPERROR__NOWINDOW)
 		printk("%s    No Window\n", err_print_prefix);
@@ -597,16 +597,16 @@
 		return status;
 
 	/* TODO - decode instead of just dumping... */
-	printk("%s  Summary Flags:         %016lx\n"
- 	         "  CChip DIRx:            %016lx\n"
-		 "  System Management IR:  %016lx\n"
-		 "  CPU IR:                %016lx\n"
-		 "  Power Supply IR:       %016lx\n"
-		 "  LM78 Fault Status:     %016lx\n"
-		 "  System Doors:          %016lx\n"
-		 "  Temperature Warning:   %016lx\n"
-		 "  Fan Control:           %016lx\n"
-		 "  Fatal Power Down Code: %016lx\n",
+	printk("%s  Summary Flags:         %016llx\n"
+ 	         "  CChip DIRx:            %016llx\n"
+		 "  System Management IR:  %016llx\n"
+		 "  CPU IR:                %016llx\n"
+		 "  Power Supply IR:       %016llx\n"
+		 "  LM78 Fault Status:     %016llx\n"
+		 "  System Doors:          %016llx\n"
+		 "  Temperature Warning:   %016llx\n"
+		 "  Fan Control:           %016llx\n"
+		 "  Fatal Power Down Code: %016llx\n",
 	       err_print_prefix,
 	       emchk->summary,
 	       emchk->c_dirx,
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index a3b9388..a91ba28 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -168,7 +168,7 @@
 		 */
 
 		/* Align to multiple of size of minimum base.  */
-		alignto = max(0x1000UL, align);
+		alignto = max_t(resource_size_t, 0x1000, align);
 		start = ALIGN(start, alignto);
 		if (hose->sparse_mem_base && size <= 7 * 16*MB) {
 			if (((start / (16*MB)) & 0x7) == 0) {
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index b9094da..bfb880a 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -247,7 +247,7 @@
 	    && paddr + size <= __direct_map_size) {
 		ret = paddr + __direct_map_base;
 
-		DBGA2("pci_map_single: [%p,%lx] -> direct %lx from %p\n",
+		DBGA2("pci_map_single: [%p,%zx] -> direct %llx from %p\n",
 		      cpu_addr, size, ret, __builtin_return_address(0));
 
 		return ret;
@@ -258,7 +258,7 @@
 	if (dac_allowed) {
 		ret = paddr + alpha_mv.pci_dac_offset;
 
-		DBGA2("pci_map_single: [%p,%lx] -> DAC %lx from %p\n",
+		DBGA2("pci_map_single: [%p,%zx] -> DAC %llx from %p\n",
 		      cpu_addr, size, ret, __builtin_return_address(0));
 
 		return ret;
@@ -299,7 +299,7 @@
 	ret = arena->dma_base + dma_ofs * PAGE_SIZE;
 	ret += (unsigned long)cpu_addr & ~PAGE_MASK;
 
-	DBGA2("pci_map_single: [%p,%lx] np %ld -> sg %lx from %p\n",
+	DBGA2("pci_map_single: [%p,%zx] np %ld -> sg %llx from %p\n",
 	      cpu_addr, size, npages, ret, __builtin_return_address(0));
 
 	return ret;
@@ -355,14 +355,14 @@
 	    && dma_addr < __direct_map_base + __direct_map_size) {
 		/* Nothing to do.  */
 
-		DBGA2("pci_unmap_single: direct [%lx,%lx] from %p\n",
+		DBGA2("pci_unmap_single: direct [%llx,%zx] from %p\n",
 		      dma_addr, size, __builtin_return_address(0));
 
 		return;
 	}
 
 	if (dma_addr > 0xffffffff) {
-		DBGA2("pci64_unmap_single: DAC [%lx,%lx] from %p\n",
+		DBGA2("pci64_unmap_single: DAC [%llx,%zx] from %p\n",
 		      dma_addr, size, __builtin_return_address(0));
 		return;
 	}
@@ -373,9 +373,9 @@
 
 	dma_ofs = (dma_addr - arena->dma_base) >> PAGE_SHIFT;
 	if (dma_ofs * PAGE_SIZE >= arena->size) {
-		printk(KERN_ERR "Bogus pci_unmap_single: dma_addr %lx "
-		       " base %lx size %x\n", dma_addr, arena->dma_base,
-		       arena->size);
+		printk(KERN_ERR "Bogus pci_unmap_single: dma_addr %llx "
+		       " base %llx size %x\n",
+		       dma_addr, arena->dma_base, arena->size);
 		return;
 		BUG();
 	}
@@ -394,7 +394,7 @@
 
 	spin_unlock_irqrestore(&arena->lock, flags);
 
-	DBGA2("pci_unmap_single: sg [%lx,%lx] np %ld from %p\n",
+	DBGA2("pci_unmap_single: sg [%llx,%zx] np %ld from %p\n",
 	      dma_addr, size, npages, __builtin_return_address(0));
 }
 EXPORT_SYMBOL(pci_unmap_single);
@@ -444,7 +444,7 @@
 		goto try_again;
 	}
 		
-	DBGA2("pci_alloc_consistent: %lx -> [%p,%x] from %p\n",
+	DBGA2("pci_alloc_consistent: %zx -> [%p,%llx] from %p\n",
 	      size, cpu_addr, *dma_addrp, __builtin_return_address(0));
 
 	return cpu_addr;
@@ -464,7 +464,7 @@
 	pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL);
 	free_pages((unsigned long)cpu_addr, get_order(size));
 
-	DBGA2("pci_free_consistent: [%x,%lx] from %p\n",
+	DBGA2("pci_free_consistent: [%llx,%zx] from %p\n",
 	      dma_addr, size, __builtin_return_address(0));
 }
 EXPORT_SYMBOL(pci_free_consistent);
@@ -551,7 +551,7 @@
 		out->dma_address = paddr + __direct_map_base;
 		out->dma_length = size;
 
-		DBGA("    sg_fill: [%p,%lx] -> direct %lx\n",
+		DBGA("    sg_fill: [%p,%lx] -> direct %llx\n",
 		     __va(paddr), size, out->dma_address);
 
 		return 0;
@@ -563,7 +563,7 @@
 		out->dma_address = paddr + alpha_mv.pci_dac_offset;
 		out->dma_length = size;
 
-		DBGA("    sg_fill: [%p,%lx] -> DAC %lx\n",
+		DBGA("    sg_fill: [%p,%lx] -> DAC %llx\n",
 		     __va(paddr), size, out->dma_address);
 
 		return 0;
@@ -589,7 +589,7 @@
 	out->dma_address = arena->dma_base + dma_ofs*PAGE_SIZE + paddr;
 	out->dma_length = size;
 
-	DBGA("    sg_fill: [%p,%lx] -> sg %lx np %ld\n",
+	DBGA("    sg_fill: [%p,%lx] -> sg %llx np %ld\n",
 	     __va(paddr), size, out->dma_address, npages);
 
 	/* All virtually contiguous.  We need to find the length of each
@@ -752,7 +752,7 @@
 
 		if (addr > 0xffffffff) {
 			/* It's a DAC address -- nothing to do.  */
-			DBGA("    (%ld) DAC [%lx,%lx]\n",
+			DBGA("    (%ld) DAC [%llx,%zx]\n",
 			      sg - end + nents, addr, size);
 			continue;
 		}
@@ -760,12 +760,12 @@
 		if (addr >= __direct_map_base
 		    && addr < __direct_map_base + __direct_map_size) {
 			/* Nothing to do.  */
-			DBGA("    (%ld) direct [%lx,%lx]\n",
+			DBGA("    (%ld) direct [%llx,%zx]\n",
 			      sg - end + nents, addr, size);
 			continue;
 		}
 
-		DBGA("    (%ld) sg [%lx,%lx]\n",
+		DBGA("    (%ld) sg [%llx,%zx]\n",
 		     sg - end + nents, addr, size);
 
 		npages = iommu_num_pages(addr, size, PAGE_SIZE);
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
index fe14c67..567f259 100644
--- a/arch/alpha/kernel/proto.h
+++ b/arch/alpha/kernel/proto.h
@@ -20,7 +20,7 @@
 extern struct pci_ops apecs_pci_ops;
 extern void apecs_init_arch(void);
 extern void apecs_pci_clr_err(void);
-extern void apecs_machine_check(u64, u64);
+extern void apecs_machine_check(unsigned long vector, unsigned long la_ptr);
 extern void apecs_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
 /* core_cia.c */
@@ -29,7 +29,7 @@
 extern void cia_init_arch(void);
 extern void pyxis_init_arch(void);
 extern void cia_kill_arch(int);
-extern void cia_machine_check(u64, u64);
+extern void cia_machine_check(unsigned long vector, unsigned long la_ptr);
 extern void cia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
 /* core_irongate.c */
@@ -42,7 +42,7 @@
 /* core_lca.c */
 extern struct pci_ops lca_pci_ops;
 extern void lca_init_arch(void);
-extern void lca_machine_check(u64, u64);
+extern void lca_machine_check(unsigned long vector, unsigned long la_ptr);
 extern void lca_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
 /* core_marvel.c */
@@ -64,7 +64,7 @@
 extern struct pci_ops mcpcia_pci_ops;
 extern void mcpcia_init_arch(void);
 extern void mcpcia_init_hoses(void);
-extern void mcpcia_machine_check(u64, u64);
+extern void mcpcia_machine_check(unsigned long vector, unsigned long la_ptr);
 extern void mcpcia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
 /* core_polaris.c */
@@ -72,14 +72,14 @@
 extern int polaris_read_config_dword(struct pci_dev *, int, u32 *);
 extern int polaris_write_config_dword(struct pci_dev *, int, u32);
 extern void polaris_init_arch(void);
-extern void polaris_machine_check(u64, u64);
+extern void polaris_machine_check(unsigned long vector, unsigned long la_ptr);
 #define polaris_pci_tbi ((void *)0)
 
 /* core_t2.c */
 extern struct pci_ops t2_pci_ops;
 extern void t2_init_arch(void);
 extern void t2_kill_arch(int);
-extern void t2_machine_check(u64, u64);
+extern void t2_machine_check(unsigned long vector, unsigned long la_ptr);
 extern void t2_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
 /* core_titan.c */
@@ -94,14 +94,14 @@
 extern struct pci_ops tsunami_pci_ops;
 extern void tsunami_init_arch(void);
 extern void tsunami_kill_arch(int);
-extern void tsunami_machine_check(u64, u64);
+extern void tsunami_machine_check(unsigned long vector, unsigned long la_ptr);
 extern void tsunami_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
 /* core_wildfire.c */
 extern struct pci_ops wildfire_pci_ops;
 extern void wildfire_init_arch(void);
 extern void wildfire_kill_arch(int);
-extern void wildfire_machine_check(u64, u64);
+extern void wildfire_machine_check(unsigned long vector, unsigned long la_ptr);
 extern void wildfire_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 extern int wildfire_pa_to_nid(unsigned long);
 extern int wildfire_cpuid_to_nid(int);
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index 02bee69..80df86c 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -1255,7 +1255,7 @@
 		       platform_string(), nr_processors);
 
 #ifdef CONFIG_SMP
-	seq_printf(f, "cpus active\t\t: %d\n"
+	seq_printf(f, "cpus active\t\t: %u\n"
 		      "cpu active mask\t\t: %016lx\n",
 		       num_online_cpus(), cpus_addr(cpu_possible_map)[0]);
 #endif
diff --git a/arch/alpha/kernel/smc37c669.c b/arch/alpha/kernel/smc37c669.c
index fd467b2..bca5bda 100644
--- a/arch/alpha/kernel/smc37c669.c
+++ b/arch/alpha/kernel/smc37c669.c
@@ -2542,8 +2542,8 @@
         SMC37c669_display_device_info( );
 #endif
 	local_irq_restore(flags);
-        printk( "SMC37c669 Super I/O Controller found @ 0x%lx\n",
-		(unsigned long) SMC_base );
+        printk( "SMC37c669 Super I/O Controller found @ 0x%p\n",
+		SMC_base );
     }
     else {
 	local_irq_restore(flags);
diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c
index e2516f9..2b5caf3 100644
--- a/arch/alpha/kernel/sys_jensen.c
+++ b/arch/alpha/kernel/sys_jensen.c
@@ -244,12 +244,11 @@
 }
 
 static void
-jensen_machine_check (u64 vector, u64 la)
+jensen_machine_check(unsigned long vector, unsigned long la)
 {
 	printk(KERN_CRIT "Machine check\n");
 }
 
-
 /*
  * The System Vector
  */
diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c
index d232e42..9e26325 100644
--- a/arch/alpha/kernel/sys_sable.c
+++ b/arch/alpha/kernel/sys_sable.c
@@ -453,7 +453,7 @@
 	sable_lynx_irq_swizzle->update_irq_hw(bit, mask);
 	spin_unlock(&sable_lynx_irq_lock);
 #if 0
-	printk("%s: mask 0x%lx bit 0x%x irq 0x%x\n",
+	printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n",
 	       __func__, mask, bit, irq);
 #endif
 }
@@ -469,7 +469,7 @@
 	sable_lynx_irq_swizzle->update_irq_hw(bit, mask);
 	spin_unlock(&sable_lynx_irq_lock);
 #if 0
-	printk("%s: mask 0x%lx bit 0x%x irq 0x%x\n",
+	printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n",
 	       __func__, mask, bit, irq);
 #endif
 }
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index cefc5a3..6ee7655 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -623,7 +623,7 @@
 	}
 
 	lock_kernel();
-	printk("Bad unaligned kernel access at %016lx: %p %lx %ld\n",
+	printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n",
 		pc, va, opcode, reg);
 	do_exit(SIGSEGV);
 
diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
index ce4e429..62d4abb 100644
--- a/arch/avr32/mm/fault.c
+++ b/arch/avr32/mm/fault.c
@@ -250,21 +250,3 @@
 	dump_dtlb();
 	die("Bus Error", regs, SIGKILL);
 }
-
-/*
- * This functionality is currently not possible to implement because
- * we're using segmentation to ensure a fixed mapping of the kernel
- * virtual address space.
- *
- * It would be possible to implement this, but it would require us to
- * disable segmentation at startup and load the kernel mappings into
- * the TLB like any other pages. There will be lots of trickery to
- * avoid recursive invocation of the TLB miss handler, though...
- */
-#ifdef CONFIG_DEBUG_PAGEALLOC
-void kernel_map_pages(struct page *page, int numpages, int enable)
-{
-
-}
-EXPORT_SYMBOL(kernel_map_pages);
-#endif
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
index 24b1ad5..2bef526 100644
--- a/arch/ia64/hp/sim/simserial.c
+++ b/arch/ia64/hp/sim/simserial.c
@@ -24,6 +24,7 @@
 #include <linux/major.h>
 #include <linux/fcntl.h>
 #include <linux/mm.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/capability.h>
 #include <linux/console.h>
@@ -848,38 +849,36 @@
  * /proc fs routines....
  */
 
-static inline int line_info(char *buf, struct serial_state *state)
+static inline void line_info(struct seq_file *m, struct serial_state *state)
 {
-	return sprintf(buf, "%d: uart:%s port:%lX irq:%d\n",
+	seq_printf(m, "%d: uart:%s port:%lX irq:%d\n",
 		       state->line, uart_config[state->type].name,
 		       state->port, state->irq);
 }
 
-static int rs_read_proc(char *page, char **start, off_t off, int count,
-		 int *eof, void *data)
+static int rs_proc_show(struct seq_file *m, void *v)
 {
-	int i, len = 0, l;
-	off_t	begin = 0;
+	int i;
 
-	len += sprintf(page, "simserinfo:1.0 driver:%s\n", serial_version);
-	for (i = 0; i < NR_PORTS && len < 4000; i++) {
-		l = line_info(page + len, &rs_table[i]);
-		len += l;
-		if (len+begin > off+count)
-			goto done;
-		if (len+begin < off) {
-			begin += len;
-			len = 0;
-		}
-	}
-	*eof = 1;
-done:
-	if (off >= len+begin)
-		return 0;
-	*start = page + (begin-off);
-	return ((count < begin+len-off) ? count : begin+len-off);
+	seq_printf(m, "simserinfo:1.0 driver:%s\n", serial_version);
+	for (i = 0; i < NR_PORTS; i++)
+		line_info(m, &rs_table[i]);
+	return 0;
 }
 
+static int rs_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, rs_proc_show, NULL);
+}
+
+static const struct file_operations rs_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= rs_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /*
  * ---------------------------------------------------------------------
  * rs_init() and friends
@@ -917,7 +916,7 @@
 	.start = rs_start,
 	.hangup = rs_hangup,
 	.wait_until_sent = rs_wait_until_sent,
-	.read_proc = rs_read_proc,
+	.proc_fops = &rs_proc_fops,
 };
 
 /*
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index f0ebb34..d6747ba 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -20,6 +20,7 @@
 #include <linux/efi.h>
 #include <linux/timex.h>
 #include <linux/clocksource.h>
+#include <linux/platform_device.h>
 
 #include <asm/machvec.h>
 #include <asm/delay.h>
@@ -405,6 +406,21 @@
 	.name =		"timer"
 };
 
+static struct platform_device rtc_efi_dev = {
+	.name = "rtc-efi",
+	.id = -1,
+};
+
+static int __init rtc_init(void)
+{
+	if (platform_device_register(&rtc_efi_dev) < 0)
+		printk(KERN_ERR "unable to register rtc device...\n");
+
+	/* not necessarily an error */
+	return 0;
+}
+module_init(rtc_init);
+
 void __init
 time_init (void)
 {
diff --git a/arch/mips/include/asm/mach-bcm47xx/gpio.h b/arch/mips/include/asm/mach-bcm47xx/gpio.h
index d8ff4cd..1784fde 100644
--- a/arch/mips/include/asm/mach-bcm47xx/gpio.h
+++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h
@@ -31,24 +31,28 @@
 
 static inline int gpio_direction_input(unsigned gpio)
 {
-	return ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 0);
+	ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 0);
+	return 0;
 }
 
 static inline int gpio_direction_output(unsigned gpio, int value)
 {
-	return ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio);
+	ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio);
+	return 0;
 }
 
-static int gpio_intmask(unsigned gpio, int value)
+static inline int gpio_intmask(unsigned gpio, int value)
 {
-	return ssb_gpio_intmask(&ssb_bcm47xx, 1 << gpio,
-				value ? 1 << gpio : 0);
+	ssb_gpio_intmask(&ssb_bcm47xx, 1 << gpio,
+			 value ? 1 << gpio : 0);
+	return 0;
 }
 
-static int gpio_polarity(unsigned gpio, int value)
+static inline int gpio_polarity(unsigned gpio, int value)
 {
-	return ssb_gpio_polarity(&ssb_bcm47xx, 1 << gpio,
-				 value ? 1 << gpio : 0);
+	ssb_gpio_polarity(&ssb_bcm47xx, 1 << gpio,
+			  value ? 1 << gpio : 0);
+	return 0;
 }
 
 
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
index 060d28d..4481656 100644
--- a/arch/mips/mm/highmem.c
+++ b/arch/mips/mm/highmem.c
@@ -42,6 +42,7 @@
 	if (!PageHighMem(page))
 		return page_address(page);
 
+	debug_kmap_atomic(type);
 	idx = type + KM_TYPE_NR*smp_processor_id();
 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
 #ifdef CONFIG_DEBUG_HIGHMEM
@@ -88,6 +89,7 @@
 
 	pagefault_disable();
 
+	debug_kmap_atomic(type);
 	idx = type + KM_TYPE_NR*smp_processor_id();
 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
 	set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index 9d46c43..e75cae6 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -216,17 +216,14 @@
 	per_cpu(cpu_data, cpu).it_value = next_tick;
 }
 
-struct platform_device rtc_parisc_dev = {
+static struct platform_device rtc_parisc_dev = {
 	.name = "rtc-parisc",
 	.id = -1,
 };
 
 static int __init rtc_init(void)
 {
-	int ret;
-
-	ret = platform_device_register(&rtc_parisc_dev);
-	if (ret < 0)
+	if (platform_device_register(&rtc_parisc_dev) < 0)
 		printk(KERN_ERR "unable to register rtc device...\n");
 
 	/* not necessarily an error */
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index ad6b1c0..45192dc 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -228,6 +228,9 @@
 	depends on PPC64 # not supported on 32 bits yet
 	default n
 
+config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+	def_bool y
+
 source "init/Kconfig"
 
 source "kernel/Kconfig.freezer"
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 22091bb..6aa0b5e 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -30,6 +30,7 @@
 config DEBUG_PAGEALLOC
         bool "Debug page memory allocations"
         depends on DEBUG_KERNEL && !HIBERNATION
+	depends on ARCH_SUPPORTS_DEBUG_PAGEALLOC
         help
           Unmap pages from the kernel linear mapping after free_pages().
           This results in a large slowdown, but helps to find certain types
diff --git a/arch/powerpc/boot/dts/mpc832x_rdb.dts b/arch/powerpc/boot/dts/mpc832x_rdb.dts
index dea3091..4319bd7 100644
--- a/arch/powerpc/boot/dts/mpc832x_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts
@@ -152,10 +152,21 @@
 		};
 
 		par_io@1400 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			reg = <0x1400 0x100>;
+			ranges = <3 0x1448 0x18>;
+			compatible = "fsl,mpc8323-qe-pario";
 			device_type = "par_io";
 			num-ports = <7>;
 
+			qe_pio_d: gpio-controller@1448 {
+				#gpio-cells = <2>;
+				compatible = "fsl,mpc8323-qe-pario-bank";
+				reg = <3 0x18>;
+				gpio-controller;
+			};
+
 			ucc2pio:ucc_pin@02 {
 				pio-map = <
 			/* port  pin  dir  open_drain  assignment  has_irq */
@@ -225,12 +236,25 @@
 		};
 
 		spi@4c0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
 			cell-index = <0>;
 			compatible = "fsl,spi";
 			reg = <0x4c0 0x40>;
 			interrupts = <2>;
 			interrupt-parent = <&qeic>;
+			gpios = <&qe_pio_d 13 0>;
 			mode = "cpu-qe";
+
+			mmc-slot@0 {
+				compatible = "fsl,mpc8323rdb-mmc-slot",
+					     "mmc-spi-slot";
+				reg = <0>;
+				gpios = <&qe_pio_d 14 1
+					 &qe_pio_d 15 0>;
+				voltage-ranges = <3300 3300>;
+				spi-max-frequency = <50000000>;
+			};
 		};
 
 		spi@500 {
diff --git a/arch/powerpc/include/asm/highmem.h b/arch/powerpc/include/asm/highmem.h
index 545028f..684a73f 100644
--- a/arch/powerpc/include/asm/highmem.h
+++ b/arch/powerpc/include/asm/highmem.h
@@ -24,6 +24,7 @@
 
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/highmem.h>
 #include <asm/kmap_types.h>
 #include <asm/tlbflush.h>
 #include <asm/page.h>
@@ -94,6 +95,7 @@
 	if (!PageHighMem(page))
 		return page_address(page);
 
+	debug_kmap_atomic(type);
 	idx = type + KM_TYPE_NR*smp_processor_id();
 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
 #ifdef CONFIG_DEBUG_HIGHMEM
diff --git a/arch/powerpc/include/asm/suspend.h b/arch/powerpc/include/asm/suspend.h
index cbf2c94..c6efc34 100644
--- a/arch/powerpc/include/asm/suspend.h
+++ b/arch/powerpc/include/asm/suspend.h
@@ -3,7 +3,4 @@
 
 static inline int arch_prepare_suspend(void) { return 0; }
 
-void save_processor_state(void);
-void restore_processor_state(void);
-
 #endif /* __ASM_POWERPC_SUSPEND_H */
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index 2a1295f..567ded7 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -20,6 +20,7 @@
 #include <linux/spi/mmc_spi.h>
 #include <linux/mmc/host.h>
 #include <linux/of_platform.h>
+#include <linux/fsl_devices.h>
 
 #include <asm/time.h>
 #include <asm/ipic.h>
@@ -39,16 +40,116 @@
 #endif
 
 #ifdef CONFIG_QUICC_ENGINE
-static void mpc83xx_spi_activate_cs(u8 cs, u8 polarity)
+static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk,
+				   struct spi_board_info *board_infos,
+				   unsigned int num_board_infos,
+				   void (*cs_control)(struct spi_device *dev,
+						      bool on))
 {
-	pr_debug("%s %d %d\n", __func__, cs, polarity);
-	par_io_data_set(3, 13, polarity);
+	struct device_node *np;
+	unsigned int i = 0;
+
+	for_each_compatible_node(np, type, compatible) {
+		int ret;
+		unsigned int j;
+		const void *prop;
+		struct resource res[2];
+		struct platform_device *pdev;
+		struct fsl_spi_platform_data pdata = {
+			.cs_control = cs_control,
+		};
+
+		memset(res, 0, sizeof(res));
+
+		pdata.sysclk = sysclk;
+
+		prop = of_get_property(np, "reg", NULL);
+		if (!prop)
+			goto err;
+		pdata.bus_num = *(u32 *)prop;
+
+		prop = of_get_property(np, "cell-index", NULL);
+		if (prop)
+			i = *(u32 *)prop;
+
+		prop = of_get_property(np, "mode", NULL);
+		if (prop && !strcmp(prop, "cpu-qe"))
+			pdata.qe_mode = 1;
+
+		for (j = 0; j < num_board_infos; j++) {
+			if (board_infos[j].bus_num == pdata.bus_num)
+				pdata.max_chipselect++;
+		}
+
+		if (!pdata.max_chipselect)
+			continue;
+
+		ret = of_address_to_resource(np, 0, &res[0]);
+		if (ret)
+			goto err;
+
+		ret = of_irq_to_resource(np, 0, &res[1]);
+		if (ret == NO_IRQ)
+			goto err;
+
+		pdev = platform_device_alloc("mpc83xx_spi", i);
+		if (!pdev)
+			goto err;
+
+		ret = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+		if (ret)
+			goto unreg;
+
+		ret = platform_device_add_resources(pdev, res,
+						    ARRAY_SIZE(res));
+		if (ret)
+			goto unreg;
+
+		ret = platform_device_add(pdev);
+		if (ret)
+			goto unreg;
+
+		goto next;
+unreg:
+		platform_device_del(pdev);
+err:
+		pr_err("%s: registration failed\n", np->full_name);
+next:
+		i++;
+	}
+
+	return i;
 }
 
-static void mpc83xx_spi_deactivate_cs(u8 cs, u8 polarity)
+static int __init fsl_spi_init(struct spi_board_info *board_infos,
+			       unsigned int num_board_infos,
+			       void (*cs_control)(struct spi_device *spi,
+						  bool on))
 {
-	pr_debug("%s %d %d\n", __func__, cs, polarity);
-	par_io_data_set(3, 13, !polarity);
+	u32 sysclk = -1;
+	int ret;
+
+	/* SPI controller is either clocked from QE or SoC clock */
+	sysclk = get_brgfreq();
+	if (sysclk == -1) {
+		sysclk = fsl_get_sys_freq();
+		if (sysclk == -1)
+			return -ENODEV;
+	}
+
+	ret = of_fsl_spi_probe(NULL, "fsl,spi", sysclk, board_infos,
+			       num_board_infos, cs_control);
+	if (!ret)
+		of_fsl_spi_probe("spi", "fsl_spi", sysclk, board_infos,
+				 num_board_infos, cs_control);
+
+	return spi_register_board_info(board_infos, num_board_infos);
+}
+
+static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on)
+{
+	pr_debug("%s %d %d\n", __func__, spi->chip_select, on);
+	par_io_data_set(3, 13, on);
 }
 
 static struct mmc_spi_platform_data mpc832x_mmc_pdata = {
@@ -74,9 +175,13 @@
 	par_io_config_pin(3, 14, 2, 0, 0, 0); /* SD_INSERT, I */
 	par_io_config_pin(3, 15, 2, 0, 0, 0); /* SD_PROTECT,I */
 
-	return fsl_spi_init(&mpc832x_spi_boardinfo, 1,
-			    mpc83xx_spi_activate_cs,
-			    mpc83xx_spi_deactivate_cs);
+	/*
+	 * Don't bother with legacy stuff when device tree contains
+	 * mmc-spi-slot node.
+	 */
+	if (of_find_compatible_node(NULL, NULL, "mmc-spi-slot"))
+		return 0;
+	return fsl_spi_init(&mpc832x_spi_boardinfo, 1, mpc83xx_spi_cs_control);
 }
 machine_device_initcall(mpc832x_rdb, mpc832x_spi_init);
 #endif /* CONFIG_QUICC_ENGINE */
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index a01c89d..afe8dbc 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -417,115 +417,6 @@
 
 arch_initcall(fsl_usb_of_init);
 
-static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk,
-				   struct spi_board_info *board_infos,
-				   unsigned int num_board_infos,
-				   void (*activate_cs)(u8 cs, u8 polarity),
-				   void (*deactivate_cs)(u8 cs, u8 polarity))
-{
-	struct device_node *np;
-	unsigned int i = 0;
-
-	for_each_compatible_node(np, type, compatible) {
-		int ret;
-		unsigned int j;
-		const void *prop;
-		struct resource res[2];
-		struct platform_device *pdev;
-		struct fsl_spi_platform_data pdata = {
-			.activate_cs = activate_cs,
-			.deactivate_cs = deactivate_cs,
-		};
-
-		memset(res, 0, sizeof(res));
-
-		pdata.sysclk = sysclk;
-
-		prop = of_get_property(np, "reg", NULL);
-		if (!prop)
-			goto err;
-		pdata.bus_num = *(u32 *)prop;
-
-		prop = of_get_property(np, "cell-index", NULL);
-		if (prop)
-			i = *(u32 *)prop;
-
-		prop = of_get_property(np, "mode", NULL);
-		if (prop && !strcmp(prop, "cpu-qe"))
-			pdata.qe_mode = 1;
-
-		for (j = 0; j < num_board_infos; j++) {
-			if (board_infos[j].bus_num == pdata.bus_num)
-				pdata.max_chipselect++;
-		}
-
-		if (!pdata.max_chipselect)
-			continue;
-
-		ret = of_address_to_resource(np, 0, &res[0]);
-		if (ret)
-			goto err;
-
-		ret = of_irq_to_resource(np, 0, &res[1]);
-		if (ret == NO_IRQ)
-			goto err;
-
-		pdev = platform_device_alloc("mpc83xx_spi", i);
-		if (!pdev)
-			goto err;
-
-		ret = platform_device_add_data(pdev, &pdata, sizeof(pdata));
-		if (ret)
-			goto unreg;
-
-		ret = platform_device_add_resources(pdev, res,
-						    ARRAY_SIZE(res));
-		if (ret)
-			goto unreg;
-
-		ret = platform_device_add(pdev);
-		if (ret)
-			goto unreg;
-
-		goto next;
-unreg:
-		platform_device_del(pdev);
-err:
-		pr_err("%s: registration failed\n", np->full_name);
-next:
-		i++;
-	}
-
-	return i;
-}
-
-int __init fsl_spi_init(struct spi_board_info *board_infos,
-			unsigned int num_board_infos,
-			void (*activate_cs)(u8 cs, u8 polarity),
-			void (*deactivate_cs)(u8 cs, u8 polarity))
-{
-	u32 sysclk = -1;
-	int ret;
-
-#ifdef CONFIG_QUICC_ENGINE
-	/* SPI controller is either clocked from QE or SoC clock */
-	sysclk = get_brgfreq();
-#endif
-	if (sysclk == -1) {
-		sysclk = fsl_get_sys_freq();
-		if (sysclk == -1)
-			return -ENODEV;
-	}
-
-	ret = of_fsl_spi_probe(NULL, "fsl,spi", sysclk, board_infos,
-			       num_board_infos, activate_cs, deactivate_cs);
-	if (!ret)
-		of_fsl_spi_probe("spi", "fsl_spi", sysclk, board_infos,
-				 num_board_infos, activate_cs, deactivate_cs);
-
-	return spi_register_board_info(board_infos, num_board_infos);
-}
-
 #if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx)
 static __be32 __iomem *rstcr;
 
diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h
index 9c744e4..42381bb 100644
--- a/arch/powerpc/sysdev/fsl_soc.h
+++ b/arch/powerpc/sysdev/fsl_soc.h
@@ -4,6 +4,8 @@
 
 #include <asm/mmu.h>
 
+struct spi_device;
+
 extern phys_addr_t get_immrbase(void);
 #if defined(CONFIG_CPM2) || defined(CONFIG_QUICC_ENGINE) || defined(CONFIG_8xx)
 extern u32 get_brgfreq(void);
@@ -17,11 +19,6 @@
 struct spi_board_info;
 struct device_node;
 
-extern int fsl_spi_init(struct spi_board_info *board_infos,
-			unsigned int num_board_infos,
-			void (*activate_cs)(u8 cs, u8 polarity),
-			void (*deactivate_cs)(u8 cs, u8 polarity));
-
 extern void fsl_rstcr_restart(char *cmd);
 
 #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 2a8af5e..dcb667c 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -72,6 +72,9 @@
 config VIRT_CPU_ACCOUNTING
 	def_bool y
 
+config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+	def_bool y
+
 mainmenu "Linux Kernel Configuration"
 
 config S390
diff --git a/arch/s390/Kconfig.debug b/arch/s390/Kconfig.debug
index 4599fa0..7e297a3 100644
--- a/arch/s390/Kconfig.debug
+++ b/arch/s390/Kconfig.debug
@@ -9,6 +9,7 @@
 config DEBUG_PAGEALLOC
 	bool "Debug page memory allocations"
 	depends on DEBUG_KERNEL
+	depends on ARCH_SUPPORTS_DEBUG_PAGEALLOC
 	help
 	  Unmap pages from the kernel linear mapping after free_pages().
 	  This results in a slowdown, but helps to find certain types of
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index c3ea215..cc12cd4 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -124,6 +124,9 @@
 config OF
 	def_bool y
 
+config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+	def_bool y if SPARC64
+
 source "init/Kconfig"
 
 source "kernel/Kconfig.freezer"
diff --git a/arch/sparc/Kconfig.debug b/arch/sparc/Kconfig.debug
index b8a15e2..d001b42 100644
--- a/arch/sparc/Kconfig.debug
+++ b/arch/sparc/Kconfig.debug
@@ -24,7 +24,8 @@
 
 config DEBUG_PAGEALLOC
 	bool "Debug page memory allocations"
-	depends on SPARC64 && DEBUG_KERNEL && !HIBERNATION
+	depends on DEBUG_KERNEL && !HIBERNATION
+	depends on ARCH_SUPPORTS_DEBUG_PAGEALLOC
 	help
 	  Unmap pages from the kernel linear mapping after free_pages().
 	  This results in a large slowdown, but helps to find certain types
diff --git a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c
index 752d0c9..7916feb 100644
--- a/arch/sparc/mm/highmem.c
+++ b/arch/sparc/mm/highmem.c
@@ -39,6 +39,7 @@
 	if (!PageHighMem(page))
 		return page_address(page);
 
+	debug_kmap_atomic(type);
 	idx = type + KM_TYPE_NR*smp_processor_id();
 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
 
diff --git a/arch/um/drivers/pcap_user.h b/arch/um/drivers/pcap_user.h
index 96b80b5..d8ba615 100644
--- a/arch/um/drivers/pcap_user.h
+++ b/arch/um/drivers/pcap_user.h
@@ -19,13 +19,3 @@
 
 extern int pcap_user_read(int fd, void *buf, int len, struct pcap_data *pri);
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/port.h b/arch/um/drivers/port.h
index 9117609..372a80c 100644
--- a/arch/um/drivers/port.h
+++ b/arch/um/drivers/port.h
@@ -18,13 +18,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/ssl.h b/arch/um/drivers/ssl.h
index 98412aa..314d177 100644
--- a/arch/um/drivers/ssl.h
+++ b/arch/um/drivers/ssl.h
@@ -11,13 +11,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/stdio_console.h b/arch/um/drivers/stdio_console.h
index 505a3d5..6d8275f 100644
--- a/arch/um/drivers/stdio_console.h
+++ b/arch/um/drivers/stdio_console.h
@@ -9,13 +9,3 @@
 extern void save_console_flags(void);
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 0a86811..d42f826 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -17,7 +17,6 @@
  * James McMechan
  */
 
-#define MAJOR_NR UBD_MAJOR
 #define UBD_SHIFT 4
 
 #include "linux/kernel.h"
@@ -115,7 +114,7 @@
 };
 
 /* Protected by ubd_lock */
-static int fake_major = MAJOR_NR;
+static int fake_major = UBD_MAJOR;
 static struct gendisk *ubd_gendisk[MAX_DEV];
 static struct gendisk *fake_gendisk[MAX_DEV];
 
@@ -299,7 +298,7 @@
 		}
 
 		mutex_lock(&ubd_lock);
-		if(fake_major != MAJOR_NR){
+		if (fake_major != UBD_MAJOR) {
 			*error_out = "Can't assign a fake major twice";
 			goto out1;
 		}
@@ -818,13 +817,13 @@
 	disk->first_minor = unit << UBD_SHIFT;
 	disk->fops = &ubd_blops;
 	set_capacity(disk, size / 512);
-	if(major == MAJOR_NR)
+	if (major == UBD_MAJOR)
 		sprintf(disk->disk_name, "ubd%c", 'a' + unit);
 	else
 		sprintf(disk->disk_name, "ubd_fake%d", unit);
 
 	/* sysfs register (not for ide fake devices) */
-	if (major == MAJOR_NR) {
+	if (major == UBD_MAJOR) {
 		ubd_devs[unit].pdev.id   = unit;
 		ubd_devs[unit].pdev.name = DRIVER_NAME;
 		ubd_devs[unit].pdev.dev.release = ubd_device_release;
@@ -871,13 +870,13 @@
 	ubd_dev->queue->queuedata = ubd_dev;
 
 	blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG);
-	err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]);
+	err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]);
 	if(err){
 		*error_out = "Failed to register device";
 		goto out_cleanup;
 	}
 
-	if(fake_major != MAJOR_NR)
+	if (fake_major != UBD_MAJOR)
 		ubd_disk_register(fake_major, ubd_dev->size, n,
 				  &fake_gendisk[n]);
 
@@ -1059,10 +1058,10 @@
 	char *error;
 	int i, err;
 
-	if (register_blkdev(MAJOR_NR, "ubd"))
+	if (register_blkdev(UBD_MAJOR, "ubd"))
 		return -1;
 
-	if (fake_major != MAJOR_NR) {
+	if (fake_major != UBD_MAJOR) {
 		char name[sizeof("ubd_nnn\0")];
 
 		snprintf(name, sizeof(name), "ubd_%d", fake_major);
diff --git a/arch/um/drivers/xterm.h b/arch/um/drivers/xterm.h
index f33a6e7..56b9c4a 100644
--- a/arch/um/drivers/xterm.h
+++ b/arch/um/drivers/xterm.h
@@ -10,13 +10,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/asm/irq_vectors.h b/arch/um/include/asm/irq_vectors.h
index 62ddba6..272a81e 100644
--- a/arch/um/include/asm/irq_vectors.h
+++ b/arch/um/include/asm/irq_vectors.h
@@ -8,13 +8,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/asm/mmu.h b/arch/um/include/asm/mmu.h
index 2cf35c2..cf259de 100644
--- a/arch/um/include/asm/mmu.h
+++ b/arch/um/include/asm/mmu.h
@@ -10,13 +10,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/asm/pda.h b/arch/um/include/asm/pda.h
index 0d8bf33..ddcd774 100644
--- a/arch/um/include/asm/pda.h
+++ b/arch/um/include/asm/pda.h
@@ -19,13 +19,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/asm/pgalloc.h b/arch/um/include/asm/pgalloc.h
index 9062a6e..7189843 100644
--- a/arch/um/include/asm/pgalloc.h
+++ b/arch/um/include/asm/pgalloc.h
@@ -60,13 +60,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/asm/pgtable-3level.h b/arch/um/include/asm/pgtable-3level.h
index 0446f45..084de4a 100644
--- a/arch/um/include/asm/pgtable-3level.h
+++ b/arch/um/include/asm/pgtable-3level.h
@@ -134,13 +134,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/shared/frame_kern.h b/arch/um/include/shared/frame_kern.h
index ce9514f..7607849 100644
--- a/arch/um/include/shared/frame_kern.h
+++ b/arch/um/include/shared/frame_kern.h
@@ -20,13 +20,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/shared/initrd.h b/arch/um/include/shared/initrd.h
index 439b9a8..22673bc 100644
--- a/arch/um/include/shared/initrd.h
+++ b/arch/um/include/shared/initrd.h
@@ -10,13 +10,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/shared/irq_kern.h b/arch/um/include/shared/irq_kern.h
index fba3895..b05d22f 100644
--- a/arch/um/include/shared/irq_kern.h
+++ b/arch/um/include/shared/irq_kern.h
@@ -16,13 +16,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/shared/mem_kern.h b/arch/um/include/shared/mem_kern.h
index cb7e196..69be0fd 100644
--- a/arch/um/include/shared/mem_kern.h
+++ b/arch/um/include/shared/mem_kern.h
@@ -18,13 +18,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/shared/ubd_user.h b/arch/um/include/shared/ubd_user.h
index bb66517..3845051 100644
--- a/arch/um/include/shared/ubd_user.h
+++ b/arch/um/include/shared/ubd_user.h
@@ -14,13 +14,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 499e5e9..388ec0a 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -28,7 +28,7 @@
 	$(call if_changed,quote1)
 
 quiet_cmd_quote1 = QUOTE   $@
-      cmd_quote1 = sed -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/\\n"/' \
+      cmd_quote1 = sed -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/\\n",/' \
 		   $< > $@
 
 $(obj)/config.c: $(src)/config.c.in $(obj)/config.tmp FORCE
@@ -36,9 +36,9 @@
 
 quiet_cmd_quote2 = QUOTE   $@
       cmd_quote2 = sed -e '/CONFIG/{'          \
-		  -e 's/"CONFIG"\;/""/'        \
+		  -e 's/"CONFIG"//'            \
 		  -e 'r $(obj)/config.tmp'     \
 		  -e 'a \'                     \
-		  -e '""\;'                    \
+		  -e '""'                      \
 		  -e '}'                       \
 		  $< > $@
diff --git a/arch/um/kernel/config.c.in b/arch/um/kernel/config.c.in
index c062cbf..b7a43fe 100644
--- a/arch/um/kernel/config.c.in
+++ b/arch/um/kernel/config.c.in
@@ -7,11 +7,15 @@
 #include <stdlib.h>
 #include "init.h"
 
-static __initdata char *config = "CONFIG";
+static __initdata const char *config[] = {
+"CONFIG"
+};
 
 static int __init print_config(char *line, int *add)
 {
-	printf("%s", config);
+	int i;
+	for (i = 0; i < sizeof(config)/sizeof(config[0]); i++)
+		printf("%s", config[i]);
 	exit(0);
 }
 
@@ -20,13 +24,3 @@
 "    Prints the config file that this UML binary was generated from.\n\n"
 );
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 183db26..02ee9ad 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -244,7 +244,7 @@
 
 	if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
 		   (void *) PTRACE_O_TRACESYSGOOD) < 0))
-		fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed");
+		fatal_perror("check_sysemu: PTRACE_OLDSETOPTIONS failed");
 
 	while (1) {
 		count++;
@@ -252,12 +252,12 @@
 			goto fail;
 		CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
 		if (n < 0)
-			fatal_perror("check_ptrace : wait failed");
+			fatal_perror("check_sysemu: wait failed");
 
 		if (WIFSTOPPED(status) &&
 		    (WSTOPSIG(status) == (SIGTRAP|0x80))) {
 			if (!count) {
-				non_fatal("check_ptrace : SYSEMU_SINGLESTEP "
+				non_fatal("check_sysemu: SYSEMU_SINGLESTEP "
 					  "doesn't singlestep");
 				goto fail;
 			}
@@ -271,7 +271,7 @@
 		else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP))
 			count++;
 		else {
-			non_fatal("check_ptrace : expected SIGTRAP or "
+			non_fatal("check_sysemu: expected SIGTRAP or "
 				  "(SIGTRAP | 0x80), got status = %d\n",
 				  status);
 			goto fail;
diff --git a/arch/um/sys-i386/asm/archparam.h b/arch/um/sys-i386/asm/archparam.h
index 93fd723..2a18a88 100644
--- a/arch/um/sys-i386/asm/archparam.h
+++ b/arch/um/sys-i386/asm/archparam.h
@@ -14,13 +14,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-i386/shared/sysdep/checksum.h b/arch/um/sys-i386/shared/sysdep/checksum.h
index 0cb4645..ed47445 100644
--- a/arch/um/sys-i386/shared/sysdep/checksum.h
+++ b/arch/um/sys-i386/shared/sysdep/checksum.h
@@ -199,13 +199,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-ia64/sysdep/ptrace.h b/arch/um/sys-ia64/sysdep/ptrace.h
index 42dd8fb..0f0f4e6 100644
--- a/arch/um/sys-ia64/sysdep/ptrace.h
+++ b/arch/um/sys-ia64/sysdep/ptrace.h
@@ -14,13 +14,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-ia64/sysdep/sigcontext.h b/arch/um/sys-ia64/sysdep/sigcontext.h
index f15fb25..76b4316 100644
--- a/arch/um/sys-ia64/sysdep/sigcontext.h
+++ b/arch/um/sys-ia64/sysdep/sigcontext.h
@@ -8,13 +8,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-ia64/sysdep/syscalls.h b/arch/um/sys-ia64/sysdep/syscalls.h
index 4a1f46e..5f6700c 100644
--- a/arch/um/sys-ia64/sysdep/syscalls.h
+++ b/arch/um/sys-ia64/sysdep/syscalls.h
@@ -8,13 +8,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-ppc/miscthings.c b/arch/um/sys-ppc/miscthings.c
index 373061c..1c11aed 100644
--- a/arch/um/sys-ppc/miscthings.c
+++ b/arch/um/sys-ppc/miscthings.c
@@ -40,14 +40,3 @@
 }
 /* END stuff taken from arch/ppc/kernel/process.c */
 
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-ppc/ptrace.c b/arch/um/sys-ppc/ptrace.c
index 8e71b47..66ef155 100644
--- a/arch/um/sys-ppc/ptrace.c
+++ b/arch/um/sys-ppc/ptrace.c
@@ -56,13 +56,3 @@
 	return put_user(tmp, (unsigned long *) data);
 }
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-ppc/ptrace_user.c b/arch/um/sys-ppc/ptrace_user.c
index ff0b9c0..224d240 100644
--- a/arch/um/sys-ppc/ptrace_user.c
+++ b/arch/um/sys-ppc/ptrace_user.c
@@ -27,13 +27,3 @@
     }
     return 0;
 }
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-ppc/shared/sysdep/ptrace.h b/arch/um/sys-ppc/shared/sysdep/ptrace.h
index df2397d..0e3230e 100644
--- a/arch/um/sys-ppc/shared/sysdep/ptrace.h
+++ b/arch/um/sys-ppc/shared/sysdep/ptrace.h
@@ -91,13 +91,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-ppc/shared/sysdep/sigcontext.h b/arch/um/sys-ppc/shared/sysdep/sigcontext.h
index f20d965..b7286f0 100644
--- a/arch/um/sys-ppc/shared/sysdep/sigcontext.h
+++ b/arch/um/sys-ppc/shared/sysdep/sigcontext.h
@@ -50,13 +50,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-ppc/shared/sysdep/syscalls.h b/arch/um/sys-ppc/shared/sysdep/syscalls.h
index 679df35..1ff8155 100644
--- a/arch/um/sys-ppc/shared/sysdep/syscalls.h
+++ b/arch/um/sys-ppc/shared/sysdep/syscalls.h
@@ -41,13 +41,3 @@
 
 #define LAST_ARCH_SYSCALL __NR_fadvise64
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-ppc/sigcontext.c b/arch/um/sys-ppc/sigcontext.c
index 4bdc15c..40694d0 100644
--- a/arch/um/sys-ppc/sigcontext.c
+++ b/arch/um/sys-ppc/sigcontext.c
@@ -2,13 +2,3 @@
 #include "asm/sigcontext.h"
 #include "sysdep/ptrace.h"
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-x86_64/asm/archparam.h b/arch/um/sys-x86_64/asm/archparam.h
index 270ed95..6c08366 100644
--- a/arch/um/sys-x86_64/asm/archparam.h
+++ b/arch/um/sys-x86_64/asm/archparam.h
@@ -14,13 +14,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-x86_64/asm/module.h b/arch/um/sys-x86_64/asm/module.h
index 35b5491..8eb79c2 100644
--- a/arch/um/sys-x86_64/asm/module.h
+++ b/arch/um/sys-x86_64/asm/module.h
@@ -18,13 +18,3 @@
 
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-x86_64/mem.c b/arch/um/sys-x86_64/mem.c
index 3f59a0a..3f8df8a 100644
--- a/arch/um/sys-x86_64/mem.c
+++ b/arch/um/sys-x86_64/mem.c
@@ -14,12 +14,3 @@
 unsigned long vm_data_default_flags32 = __VM_DATA_DEFAULT_FLAGS;
 unsigned long vm_force_exec32 = PROT_EXEC;
 
-/* Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 45161b8..748e50a 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -165,6 +165,9 @@
 config ARCH_SUPPORTS_OPTIMIZED_INLINING
 	def_bool y
 
+config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+	def_bool y
+
 # Use the generic interrupt handling code in kernel/irq/:
 config GENERIC_HARDIRQS
 	bool
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index fdb45df..a345cb5 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -75,6 +75,7 @@
 config DEBUG_PAGEALLOC
 	bool "Debug page memory allocations"
 	depends on DEBUG_KERNEL
+	depends on ARCH_SUPPORTS_DEBUG_PAGEALLOC
 	---help---
 	  Unmap pages from the kernel linear mapping after free_pages().
 	  This results in a large slowdown, but helps to find certain types
diff --git a/arch/x86/include/asm/suspend_32.h b/arch/x86/include/asm/suspend_32.h
index a5074bd..48dcfa6 100644
--- a/arch/x86/include/asm/suspend_32.h
+++ b/arch/x86/include/asm/suspend_32.h
@@ -24,28 +24,4 @@
 	unsigned long return_address;
 } __attribute__((packed));
 
-#ifdef CONFIG_ACPI
-extern unsigned long saved_eip;
-extern unsigned long saved_esp;
-extern unsigned long saved_ebp;
-extern unsigned long saved_ebx;
-extern unsigned long saved_esi;
-extern unsigned long saved_edi;
-
-static inline void acpi_save_register_state(unsigned long return_point)
-{
-	saved_eip = return_point;
-	asm volatile("movl %%esp,%0" : "=m" (saved_esp));
-	asm volatile("movl %%ebp,%0" : "=m" (saved_ebp));
-	asm volatile("movl %%ebx,%0" : "=m" (saved_ebx));
-	asm volatile("movl %%edi,%0" : "=m" (saved_edi));
-	asm volatile("movl %%esi,%0" : "=m" (saved_esi));
-}
-
-#define acpi_restore_register_state()  do {} while (0)
-
-/* routines for saving/restoring kernel state */
-extern int acpi_save_state_mem(void);
-#endif
-
 #endif /* _ASM_X86_SUSPEND_32_H */
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
index fbf2f33..5a6aa1c 100644
--- a/arch/x86/kernel/asm-offsets_32.c
+++ b/arch/x86/kernel/asm-offsets_32.c
@@ -18,6 +18,7 @@
 #include <asm/thread_info.h>
 #include <asm/bootparam.h>
 #include <asm/elf.h>
+#include <asm/suspend.h>
 
 #include <xen/interface/xen.h>
 
diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c
index 8793ab3..e72f062 100644
--- a/arch/x86/kernel/asm-offsets_64.c
+++ b/arch/x86/kernel/asm-offsets_64.c
@@ -16,6 +16,7 @@
 #include <asm/thread_info.h>
 #include <asm/ia32.h>
 #include <asm/bootparam.h>
+#include <asm/suspend.h>
 
 #include <xen/interface/xen.h>
 
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
index 522db5e..5bc5d16 100644
--- a/arch/x86/mm/highmem_32.c
+++ b/arch/x86/mm/highmem_32.c
@@ -19,49 +19,6 @@
 	kunmap_high(page);
 }
 
-static void debug_kmap_atomic_prot(enum km_type type)
-{
-#ifdef CONFIG_DEBUG_HIGHMEM
-	static unsigned warn_count = 10;
-
-	if (unlikely(warn_count == 0))
-		return;
-
-	if (unlikely(in_interrupt())) {
-		if (in_irq()) {
-			if (type != KM_IRQ0 && type != KM_IRQ1 &&
-			    type != KM_BIO_SRC_IRQ && type != KM_BIO_DST_IRQ &&
-			    type != KM_BOUNCE_READ) {
-				WARN_ON(1);
-				warn_count--;
-			}
-		} else if (!irqs_disabled()) {	/* softirq */
-			if (type != KM_IRQ0 && type != KM_IRQ1 &&
-			    type != KM_SOFTIRQ0 && type != KM_SOFTIRQ1 &&
-			    type != KM_SKB_SUNRPC_DATA &&
-			    type != KM_SKB_DATA_SOFTIRQ &&
-			    type != KM_BOUNCE_READ) {
-				WARN_ON(1);
-				warn_count--;
-			}
-		}
-	}
-
-	if (type == KM_IRQ0 || type == KM_IRQ1 || type == KM_BOUNCE_READ ||
-			type == KM_BIO_SRC_IRQ || type == KM_BIO_DST_IRQ) {
-		if (!irqs_disabled()) {
-			WARN_ON(1);
-			warn_count--;
-		}
-	} else if (type == KM_SOFTIRQ0 || type == KM_SOFTIRQ1) {
-		if (irq_count() == 0 && !irqs_disabled()) {
-			WARN_ON(1);
-			warn_count--;
-		}
-	}
-#endif
-}
-
 /*
  * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because
  * no global lock is needed and because the kmap code must perform a global TLB
@@ -81,8 +38,9 @@
 	if (!PageHighMem(page))
 		return page_address(page);
 
-	debug_kmap_atomic_prot(type);
+	debug_kmap_atomic(type);
 
+	debug_kmap_atomic(type);
 	idx = type + KM_TYPE_NR*smp_processor_id();
 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
 	BUG_ON(!pte_none(*(kmap_pte-idx)));
diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c
index 699c9b2..bff0c90 100644
--- a/arch/x86/mm/iomap_32.c
+++ b/arch/x86/mm/iomap_32.c
@@ -19,6 +19,7 @@
 #include <asm/iomap.h>
 #include <asm/pat.h>
 #include <linux/module.h>
+#include <linux/highmem.h>
 
 int is_io_mapping_possible(resource_size_t base, unsigned long size)
 {
@@ -71,6 +72,7 @@
 	unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
 	enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
 
+	debug_kmap_atomic(type);
 	/*
 	 * Force other mappings to Oops if they'll try to access this pte
 	 * without first remap it.  Keeping stale mappings around is a bad idea
diff --git a/arch/x86/power/cpu_32.c b/arch/x86/power/cpu_32.c
index 274d060..ce702c5 100644
--- a/arch/x86/power/cpu_32.c
+++ b/arch/x86/power/cpu_32.c
@@ -12,6 +12,7 @@
 #include <asm/mtrr.h>
 #include <asm/mce.h>
 #include <asm/xcr.h>
+#include <asm/suspend.h>
 
 static struct saved_context saved_context;
 
diff --git a/arch/x86/power/cpu_64.c b/arch/x86/power/cpu_64.c
index e3b6cf7..5343540 100644
--- a/arch/x86/power/cpu_64.c
+++ b/arch/x86/power/cpu_64.c
@@ -15,6 +15,7 @@
 #include <asm/pgtable.h>
 #include <asm/mtrr.h>
 #include <asm/xcr.h>
+#include <asm/suspend.h>
 
 static void fix_processor_context(void);
 
diff --git a/arch/x86/power/hibernate_64.c b/arch/x86/power/hibernate_64.c
index 6dd000d..65fdc86 100644
--- a/arch/x86/power/hibernate_64.c
+++ b/arch/x86/power/hibernate_64.c
@@ -14,6 +14,7 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/mtrr.h>
+#include <asm/suspend.h>
 
 /* References to section boundaries */
 extern const void __nosave_begin, __nosave_end;
diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c
index 25d46c8..4c559cf 100644
--- a/arch/xtensa/platforms/iss/console.c
+++ b/arch/xtensa/platforms/iss/console.c
@@ -18,6 +18,7 @@
 #include <linux/mm.h>
 #include <linux/major.h>
 #include <linux/param.h>
+#include <linux/seq_file.h>
 #include <linux/serial.h>
 #include <linux/serialP.h>
 
@@ -176,22 +177,24 @@
 	/* Stub, once again.. */
 }
 
-static int rs_read_proc(char *page, char **start, off_t off, int count,
-			int *eof, void *data)
+static int rs_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0;
-	off_t begin = 0;
-
-	len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
-	*eof = 1;
-
-	if (off >= len + begin)
-		return 0;
-
-	*start = page + (off - begin);
-	return ((count < begin + len - off) ? count : begin + len - off);
+	seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version);
+	return 0;
 }
 
+static int rs_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, rs_proc_show, NULL);
+}
+
+static const struct file_operations rs_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= rs_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 
 static struct tty_operations serial_ops = {
 	.open = rs_open,
@@ -203,7 +206,7 @@
 	.chars_in_buffer = rs_chars_in_buffer,
 	.hangup = rs_hangup,
 	.wait_until_sent = rs_wait_until_sent,
-	.read_proc = rs_read_proc
+	.proc_fops = &rs_proc_fops,
 };
 
 int __init rs_init(void)
diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig
index 14b9d5f..c07e725 100644
--- a/drivers/auxdisplay/Kconfig
+++ b/drivers/auxdisplay/Kconfig
@@ -6,7 +6,6 @@
 #
 
 menuconfig AUXDISPLAY
-	depends on PARPORT
 	bool "Auxiliary Display support"
 	---help---
 	  Say Y here to get to see options for auxiliary display drivers.
@@ -14,7 +13,7 @@
 
 	  If you say N, all options in this submenu will be skipped and disabled.
 
-if AUXDISPLAY && PARPORT
+if AUXDISPLAY
 
 config KS0108
 	tristate "KS0108 LCD Controller"
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 2621ed2..40b17d3 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1192,6 +1192,30 @@
 	return err;
 }
 
+static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev)
+{
+	int err;
+	sector_t sec;
+	loff_t sz;
+
+	err = -ENXIO;
+	if (unlikely(lo->lo_state != Lo_bound))
+		goto out;
+	err = figure_loop_size(lo);
+	if (unlikely(err))
+		goto out;
+	sec = get_capacity(lo->lo_disk);
+	/* the width of sector_t may be narrow for bit-shift */
+	sz = sec;
+	sz <<= 9;
+	mutex_lock(&bdev->bd_mutex);
+	bd_set_size(bdev, sz);
+	mutex_unlock(&bdev->bd_mutex);
+
+ out:
+	return err;
+}
+
 static int lo_ioctl(struct block_device *bdev, fmode_t mode,
 	unsigned int cmd, unsigned long arg)
 {
@@ -1224,6 +1248,11 @@
 	case LOOP_GET_STATUS64:
 		err = loop_get_status64(lo, (struct loop_info64 __user *) arg);
 		break;
+	case LOOP_SET_CAPACITY:
+		err = -EPERM;
+		if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN))
+			err = loop_set_capacity(lo, bdev);
+		break;
 	default:
 		err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
 	}
@@ -1371,6 +1400,7 @@
 			lo, (struct compat_loop_info __user *) arg);
 		mutex_unlock(&lo->lo_ctl_mutex);
 		break;
+	case LOOP_SET_CAPACITY:
 	case LOOP_CLR_FD:
 	case LOOP_GET_STATUS64:
 	case LOOP_SET_STATUS64:
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index a58869e..fd3ebd1 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -79,6 +79,7 @@
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
@@ -1825,14 +1826,13 @@
  * /proc fs routines....
  */
 
-static inline int line_info(char *buf, struct serial_state *state)
+static inline void line_info(struct seq_file *m, struct serial_state *state)
 {
 	struct async_struct *info = state->info, scr_info;
 	char	stat_buf[30], control, status;
-	int	ret;
 	unsigned long flags;
 
-	ret = sprintf(buf, "%d: uart:amiga_builtin",state->line);
+	seq_printf(m, "%d: uart:amiga_builtin",state->line);
 
 	/*
 	 * Figure out the current RS-232 lines
@@ -1864,55 +1864,49 @@
 		strcat(stat_buf, "|CD");
 
 	if (info->quot) {
-		ret += sprintf(buf+ret, " baud:%d",
-			       state->baud_base / info->quot);
+		seq_printf(m, " baud:%d", state->baud_base / info->quot);
 	}
 
-	ret += sprintf(buf+ret, " tx:%d rx:%d",
-		      state->icount.tx, state->icount.rx);
+	seq_printf(m, " tx:%d rx:%d", state->icount.tx, state->icount.rx);
 
 	if (state->icount.frame)
-		ret += sprintf(buf+ret, " fe:%d", state->icount.frame);
+		seq_printf(m, " fe:%d", state->icount.frame);
 
 	if (state->icount.parity)
-		ret += sprintf(buf+ret, " pe:%d", state->icount.parity);
+		seq_printf(m, " pe:%d", state->icount.parity);
 
 	if (state->icount.brk)
-		ret += sprintf(buf+ret, " brk:%d", state->icount.brk);
+		seq_printf(m, " brk:%d", state->icount.brk);
 
 	if (state->icount.overrun)
-		ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
+		seq_printf(m, " oe:%d", state->icount.overrun);
 
 	/*
 	 * Last thing is the RS-232 status lines
 	 */
-	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
-	return ret;
+	seq_printf(m, " %s\n", stat_buf+1);
 }
 
-static int rs_read_proc(char *page, char **start, off_t off, int count,
-			int *eof, void *data)
+static int rs_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0, l;
-	off_t	begin = 0;
-
-	len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
-	l = line_info(page + len, &rs_table[0]);
-	len += l;
-	if (len+begin > off+count)
-	  goto done;
-	if (len+begin < off) {
-	  begin += len;
-	  len = 0;
-	}
-	*eof = 1;
-done:
-	if (off >= len+begin)
-		return 0;
-	*start = page + (off-begin);
-	return ((count < begin+len-off) ? count : begin+len-off);
+	seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version);
+	line_info(m, &rs_table[0]);
+	return 0;
 }
 
+static int rs_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, rs_proc_show, NULL);
+}
+
+static const struct file_operations rs_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= rs_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /*
  * ---------------------------------------------------------------------
  * rs_init() and friends
@@ -1951,9 +1945,9 @@
 	.break_ctl = rs_break,
 	.send_xchar = rs_send_xchar,
 	.wait_until_sent = rs_wait_until_sent,
-	.read_proc = rs_read_proc,
 	.tiocmget = rs_tiocmget,
 	.tiocmset = rs_tiocmset,
+	.proc_fops = &rs_proc_fops,
 };
 
 /*
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 6a59f72..272db0e 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -657,6 +657,7 @@
 
 #include <linux/stat.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 
 static void cy_throttle(struct tty_struct *tty);
 static void cy_send_xchar(struct tty_struct *tty, char ch);
@@ -868,8 +869,6 @@
 static unsigned detect_isa_irq(void __iomem *);
 #endif				/* CONFIG_ISA */
 
-static int cyclades_get_proc_info(char *, char **, off_t, int, int *, void *);
-
 #ifndef CONFIG_CYZ_INTR
 static void cyz_poll(unsigned long);
 
@@ -5216,31 +5215,22 @@
 };
 #endif
 
-static int
-cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
-		int *eof, void *data)
+static int cyclades_proc_show(struct seq_file *m, void *v)
 {
 	struct cyclades_port *info;
 	unsigned int i, j;
-	int len = 0;
-	off_t begin = 0;
-	off_t pos = 0;
-	int size;
 	__u32 cur_jifs = jiffies;
 
-	size = sprintf(buf, "Dev TimeOpen   BytesOut  IdleOut    BytesIn   "
+	seq_puts(m, "Dev TimeOpen   BytesOut  IdleOut    BytesIn   "
 			"IdleIn  Overruns  Ldisc\n");
 
-	pos += size;
-	len += size;
-
 	/* Output one line for each known port */
 	for (i = 0; i < NR_CARDS; i++)
 		for (j = 0; j < cy_card[i].nports; j++) {
 			info = &cy_card[i].ports[j];
 
 			if (info->port.count)
-				size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
+				seq_printf(m, "%3d %8lu %10lu %8lu "
 					"%10lu %8lu %9lu %6ld\n", info->line,
 					(cur_jifs - info->idle_stats.in_use) /
 					HZ, info->idle_stats.xmit_bytes,
@@ -5251,30 +5241,26 @@
 					/* FIXME: double check locking */
 					(long)info->port.tty->ldisc.ops->num);
 			else
-				size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
+				seq_printf(m, "%3d %8lu %10lu %8lu "
 					"%10lu %8lu %9lu %6ld\n",
 					info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
-			len += size;
-			pos = begin + len;
-
-			if (pos < offset) {
-				len = 0;
-				begin = pos;
-			}
-			if (pos > offset + length)
-				goto done;
 		}
-	*eof = 1;
-done:
-	*start = buf + (offset - begin);	/* Start of wanted data */
-	len -= (offset - begin);	/* Start slop */
-	if (len > length)
-		len = length;	/* Ending slop */
-	if (len < 0)
-		len = 0;
-	return len;
+	return 0;
 }
 
+static int cyclades_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, cyclades_proc_show, NULL);
+}
+
+static const struct file_operations cyclades_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= cyclades_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /* The serial driver boot-time initialization code!
     Hardware I/O ports are mapped to character special devices on a
     first found, first allocated manner.  That is, this code searches
@@ -5311,9 +5297,9 @@
 	.hangup = cy_hangup,
 	.break_ctl = cy_break,
 	.wait_until_sent = cy_wait_until_sent,
-	.read_proc = cyclades_get_proc_info,
 	.tiocmget = cy_tiocmget,
 	.tiocmset = cy_tiocmset,
+	.proc_fops = &cyclades_proc_fops,
 };
 
 static int __init cy_init(void)
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 70e0ebc..afd9247 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -139,7 +139,7 @@
 #include <linux/seq_file.h>
 
 static const struct file_operations ip2mem_proc_fops;
-static int ip2_read_proc(char *, char **, off_t, int, int *, void * );
+static const struct file_operations ip2_proc_fops;
 
 /********************/
 /* Type Definitions */
@@ -446,9 +446,9 @@
 	.stop            = ip2_stop,
 	.start           = ip2_start,
 	.hangup          = ip2_hangup,
-	.read_proc       = ip2_read_proc,
 	.tiocmget	 = ip2_tiocmget,
 	.tiocmset	 = ip2_tiocmset,
+	.proc_fops	 = &ip2_proc_fops,
 };
 
 /******************************************************************************/
@@ -3029,19 +3029,17 @@
  * different sources including ip2mkdev.c and a couple of other drivers.
  * The bugs are all mine.  :-)	=mhw=
  */
-static int ip2_read_proc(char *page, char **start, off_t off,
-				int count, int *eof, void *data)
+static int ip2_proc_show(struct seq_file *m, void *v)
 {
 	int	i, j, box;
-	int	len = 0;
 	int	boxes = 0;
 	int	ports = 0;
 	int	tports = 0;
-	off_t	begin = 0;
 	i2eBordStrPtr  pB;
+	char *sep;
 
-	len += sprintf(page, "ip2info: 1.0 driver: %s\n", pcVersion );
-	len += sprintf(page+len, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
+	seq_printf(m, "ip2info: 1.0 driver: %s\n", pcVersion);
+	seq_printf(m, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
 			IP2_TTY_MAJOR, IP2_CALLOUT_MAJOR, IP2_IPL_MAJOR,
 			IP2_MAX_BOARDS, ABS_MAX_BOXES, ABS_BIGGEST_BOX);
 
@@ -3053,7 +3051,8 @@
 			switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) 
 			{
 			case POR_ID_FIIEX:
-				len += sprintf( page+len, "Board %d: EX ports=", i );
+				seq_printf(m, "Board %d: EX ports=", i);
+				sep = "";
 				for( box = 0; box < ABS_MAX_BOXES; ++box )
 				{
 					ports = 0;
@@ -3065,79 +3064,74 @@
 							++ports;
 						}
 					}
-					len += sprintf( page+len, "%d,", ports );
+					seq_printf(m, "%s%d", sep, ports);
+					sep = ",";
 					tports += ports;
 				}
-
-				--len;	/* Backup over that last comma */
-
-				len += sprintf( page+len, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8 );
+				seq_printf(m, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8);
 				break;
 
 			case POR_ID_II_4:
-				len += sprintf(page+len, "Board %d: ISA-4 ports=4 boxes=1", i );
+				seq_printf(m, "Board %d: ISA-4 ports=4 boxes=1", i);
 				tports = ports = 4;
 				break;
 
 			case POR_ID_II_8:
-				len += sprintf(page+len, "Board %d: ISA-8-std ports=8 boxes=1", i );
+				seq_printf(m, "Board %d: ISA-8-std ports=8 boxes=1", i);
 				tports = ports = 8;
 				break;
 
 			case POR_ID_II_8R:
-				len += sprintf(page+len, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i );
+				seq_printf(m, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i);
 				tports = ports = 8;
 				break;
 
 			default:
-				len += sprintf(page+len, "Board %d: unknown", i );
+				seq_printf(m, "Board %d: unknown", i);
 				/* Don't try and probe for minor numbers */
 				tports = ports = 0;
 			}
 
 		} else {
 			/* Don't try and probe for minor numbers */
-			len += sprintf(page+len, "Board %d: vacant", i );
+			seq_printf(m, "Board %d: vacant", i);
 			tports = ports = 0;
 		}
 
 		if( tports ) {
-			len += sprintf(page+len, " minors=" );
-
+			seq_puts(m, " minors=");
+			sep = "";
 			for ( box = 0; box < ABS_MAX_BOXES; ++box )
 			{
 				for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
 				{
 					if ( pB->i2eChannelMap[box] & (1 << j) )
 					{
-						len += sprintf (page+len,"%d,",
+						seq_printf(m, "%s%d", sep,
 							j + ABS_BIGGEST_BOX *
 							(box+i*ABS_MAX_BOXES));
+						sep = ",";
 					}
 				}
 			}
-
-			page[ len - 1 ] = '\n';	/* Overwrite that last comma */
-		} else {
-			len += sprintf (page+len,"\n" );
 		}
-
-		if (len+begin > off+count)
-			break;
-		if (len+begin < off) {
-			begin += len;
-			len = 0;
-		}
+		seq_putc(m, '\n');
 	}
-
-	if (i >= IP2_MAX_BOARDS)
-		*eof = 1;
-	if (off >= len+begin)
-		return 0;
-
-	*start = page + (off-begin);
-	return ((count < begin+len-off) ? count : begin+len-off);
+	return 0;
  }
+
+static int ip2_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, ip2_proc_show, NULL);
+}
+
+static const struct file_operations ip2_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ip2_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
  
 /******************************************************************************/
 /* Function:   ip2trace()                                                     */
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 5c3dc6b..fff19f7 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -24,6 +24,7 @@
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/serial.h>
+#include <linux/seq_file.h>
 #include <linux/cdk.h>
 #include <linux/comstats.h>
 #include <linux/istallion.h>
@@ -613,7 +614,6 @@
 static void	stli_waituntilsent(struct tty_struct *tty, int timeout);
 static void	stli_sendxchar(struct tty_struct *tty, char ch);
 static void	stli_hangup(struct tty_struct *tty);
-static int	stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portnr, char *pos);
 
 static int	stli_brdinit(struct stlibrd *brdp);
 static int	stli_startbrd(struct stlibrd *brdp);
@@ -1893,20 +1893,10 @@
 	stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0);
 }
 
-/*****************************************************************************/
-
-#define	MAXLINE		80
-
-/*
- *	Format info for a specified port. The line is deliberately limited
- *	to 80 characters. (If it is too long it will be truncated, if too
- *	short then padded with spaces).
- */
-
-static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portnr, char *pos)
+static void stli_portinfo(struct seq_file *m, struct stlibrd *brdp, struct stliport *portp, int portnr)
 {
-	char *sp, *uart;
-	int rc, cnt;
+	char *uart;
+	int rc;
 
 	rc = stli_portcmdstats(NULL, portp);
 
@@ -1918,44 +1908,50 @@
 		default:uart = "CD1400"; break;
 		}
 	}
-
-	sp = pos;
-	sp += sprintf(sp, "%d: uart:%s ", portnr, uart);
+	seq_printf(m, "%d: uart:%s ", portnr, uart);
 
 	if ((brdp->state & BST_STARTED) && (rc >= 0)) {
-		sp += sprintf(sp, "tx:%d rx:%d", (int) stli_comstats.txtotal,
+		char sep;
+
+		seq_printf(m, "tx:%d rx:%d", (int) stli_comstats.txtotal,
 			(int) stli_comstats.rxtotal);
 
 		if (stli_comstats.rxframing)
-			sp += sprintf(sp, " fe:%d",
+			seq_printf(m, " fe:%d",
 				(int) stli_comstats.rxframing);
 		if (stli_comstats.rxparity)
-			sp += sprintf(sp, " pe:%d",
+			seq_printf(m, " pe:%d",
 				(int) stli_comstats.rxparity);
 		if (stli_comstats.rxbreaks)
-			sp += sprintf(sp, " brk:%d",
+			seq_printf(m, " brk:%d",
 				(int) stli_comstats.rxbreaks);
 		if (stli_comstats.rxoverrun)
-			sp += sprintf(sp, " oe:%d",
+			seq_printf(m, " oe:%d",
 				(int) stli_comstats.rxoverrun);
 
-		cnt = sprintf(sp, "%s%s%s%s%s ",
-			(stli_comstats.signals & TIOCM_RTS) ? "|RTS" : "",
-			(stli_comstats.signals & TIOCM_CTS) ? "|CTS" : "",
-			(stli_comstats.signals & TIOCM_DTR) ? "|DTR" : "",
-			(stli_comstats.signals & TIOCM_CD) ? "|DCD" : "",
-			(stli_comstats.signals & TIOCM_DSR) ? "|DSR" : "");
-		*sp = ' ';
-		sp += cnt;
+		sep = ' ';
+		if (stli_comstats.signals & TIOCM_RTS) {
+			seq_printf(m, "%c%s", sep, "RTS");
+			sep = '|';
+		}
+		if (stli_comstats.signals & TIOCM_CTS) {
+			seq_printf(m, "%c%s", sep, "CTS");
+			sep = '|';
+		}
+		if (stli_comstats.signals & TIOCM_DTR) {
+			seq_printf(m, "%c%s", sep, "DTR");
+			sep = '|';
+		}
+		if (stli_comstats.signals & TIOCM_CD) {
+			seq_printf(m, "%c%s", sep, "DCD");
+			sep = '|';
+		}
+		if (stli_comstats.signals & TIOCM_DSR) {
+			seq_printf(m, "%c%s", sep, "DSR");
+			sep = '|';
+		}
 	}
-
-	for (cnt = (sp - pos); (cnt < (MAXLINE - 1)); cnt++)
-		*sp++ = ' ';
-	if (cnt >= MAXLINE)
-		pos[(MAXLINE - 2)] = '+';
-	pos[(MAXLINE - 1)] = '\n';
-
-	return(MAXLINE);
+	seq_putc(m, '\n');
 }
 
 /*****************************************************************************/
@@ -1964,26 +1960,15 @@
  *	Port info, read from the /proc file system.
  */
 
-static int stli_readproc(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int stli_proc_show(struct seq_file *m, void *v)
 {
 	struct stlibrd *brdp;
 	struct stliport *portp;
 	unsigned int brdnr, portnr, totalport;
-	int curoff, maxoff;
-	char *pos;
 
-	pos = page;
 	totalport = 0;
-	curoff = 0;
 
-	if (off == 0) {
-		pos += sprintf(pos, "%s: version %s", stli_drvtitle,
-			stli_drvversion);
-		while (pos < (page + MAXLINE - 1))
-			*pos++ = ' ';
-		*pos++ = '\n';
-	}
-	curoff =  MAXLINE;
+	seq_printf(m, "%s: version %s\n", stli_drvtitle, stli_drvversion);
 
 /*
  *	We scan through for each board, panel and port. The offset is
@@ -1996,33 +1981,31 @@
 		if (brdp->state == 0)
 			continue;
 
-		maxoff = curoff + (brdp->nrports * MAXLINE);
-		if (off >= maxoff) {
-			curoff = maxoff;
-			continue;
-		}
-
 		totalport = brdnr * STL_MAXPORTS;
 		for (portnr = 0; (portnr < brdp->nrports); portnr++,
 		    totalport++) {
 			portp = brdp->ports[portnr];
 			if (portp == NULL)
 				continue;
-			if (off >= (curoff += MAXLINE))
-				continue;
-			if ((pos - page + MAXLINE) > count)
-				goto stli_readdone;
-			pos += stli_portinfo(brdp, portp, totalport, pos);
+			stli_portinfo(m, brdp, portp, totalport);
 		}
 	}
-
-	*eof = 1;
-
-stli_readdone:
-	*start = page;
-	return(pos - page);
+	return 0;
 }
 
+static int stli_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, stli_proc_show, NULL);
+}
+
+static const struct file_operations stli_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= stli_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /*****************************************************************************/
 
 /*
@@ -4427,9 +4410,9 @@
 	.break_ctl = stli_breakctl,
 	.wait_until_sent = stli_waituntilsent,
 	.send_xchar = stli_sendxchar,
-	.read_proc = stli_readproc,
 	.tiocmget = stli_tiocmget,
 	.tiocmset = stli_tiocmset,
+	.proc_fops = &stli_proc_fops,
 };
 
 static const struct tty_port_operations stli_port_ops = {
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 5608a1e..19d79fc 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -51,6 +51,7 @@
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
@@ -2619,13 +2620,12 @@
  * /proc fs routines....
  */
 
-static inline int line_info(char *buf, MGSLPC_INFO *info)
+static inline void line_info(struct seq_file *m, MGSLPC_INFO *info)
 {
 	char	stat_buf[30];
-	int	ret;
 	unsigned long flags;
 
-	ret = sprintf(buf, "%s:io:%04X irq:%d",
+	seq_printf(m, "%s:io:%04X irq:%d",
 		      info->device_name, info->io_base, info->irq_level);
 
 	/* output current serial signal states */
@@ -2649,75 +2649,70 @@
 		strcat(stat_buf, "|RI");
 
 	if (info->params.mode == MGSL_MODE_HDLC) {
-		ret += sprintf(buf+ret, " HDLC txok:%d rxok:%d",
+		seq_printf(m, " HDLC txok:%d rxok:%d",
 			      info->icount.txok, info->icount.rxok);
 		if (info->icount.txunder)
-			ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+			seq_printf(m, " txunder:%d", info->icount.txunder);
 		if (info->icount.txabort)
-			ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+			seq_printf(m, " txabort:%d", info->icount.txabort);
 		if (info->icount.rxshort)
-			ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);
+			seq_printf(m, " rxshort:%d", info->icount.rxshort);
 		if (info->icount.rxlong)
-			ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+			seq_printf(m, " rxlong:%d", info->icount.rxlong);
 		if (info->icount.rxover)
-			ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+			seq_printf(m, " rxover:%d", info->icount.rxover);
 		if (info->icount.rxcrc)
-			ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc);
+			seq_printf(m, " rxcrc:%d", info->icount.rxcrc);
 	} else {
-		ret += sprintf(buf+ret, " ASYNC tx:%d rx:%d",
+		seq_printf(m, " ASYNC tx:%d rx:%d",
 			      info->icount.tx, info->icount.rx);
 		if (info->icount.frame)
-			ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+			seq_printf(m, " fe:%d", info->icount.frame);
 		if (info->icount.parity)
-			ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+			seq_printf(m, " pe:%d", info->icount.parity);
 		if (info->icount.brk)
-			ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
+			seq_printf(m, " brk:%d", info->icount.brk);
 		if (info->icount.overrun)
-			ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+			seq_printf(m, " oe:%d", info->icount.overrun);
 	}
 
 	/* Append serial signal status to end */
-	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+	seq_printf(m, " %s\n", stat_buf+1);
 
-	ret += sprintf(buf+ret, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+	seq_printf(m, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
 		       info->tx_active,info->bh_requested,info->bh_running,
 		       info->pending_bh);
-
-	return ret;
 }
 
 /* Called to print information about devices
  */
-static int mgslpc_read_proc(char *page, char **start, off_t off, int count,
-		 int *eof, void *data)
+static int mgslpc_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0, l;
-	off_t	begin = 0;
 	MGSLPC_INFO *info;
 
-	len += sprintf(page, "synclink driver:%s\n", driver_version);
+	seq_printf(m, "synclink driver:%s\n", driver_version);
 
 	info = mgslpc_device_list;
 	while( info ) {
-		l = line_info(page + len, info);
-		len += l;
-		if (len+begin > off+count)
-			goto done;
-		if (len+begin < off) {
-			begin += len;
-			len = 0;
-		}
+		line_info(m, info);
 		info = info->next_device;
 	}
-
-	*eof = 1;
-done:
-	if (off >= len+begin)
-		return 0;
-	*start = page + (off-begin);
-	return ((count < begin+len-off) ? count : begin+len-off);
+	return 0;
 }
 
+static int mgslpc_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mgslpc_proc_show, NULL);
+}
+
+static const struct file_operations mgslpc_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= mgslpc_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static int rx_alloc_buffers(MGSLPC_INFO *info)
 {
 	/* each buffer has header and data */
@@ -2861,13 +2856,13 @@
 	.send_xchar = mgslpc_send_xchar,
 	.break_ctl = mgslpc_break,
 	.wait_until_sent = mgslpc_wait_until_sent,
-	.read_proc = mgslpc_read_proc,
 	.set_termios = mgslpc_set_termios,
 	.stop = tx_pause,
 	.start = tx_release,
 	.hangup = mgslpc_hangup,
 	.tiocmget = tiocmget,
 	.tiocmset = tiocmset,
+	.proc_fops = &mgslpc_proc_fops,
 };
 
 static void synclink_cs_cleanup(void)
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index e1e0dd8..2ad813a 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -32,6 +32,7 @@
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/serial.h>
+#include <linux/seq_file.h>
 #include <linux/cd1400.h>
 #include <linux/sc26198.h>
 #include <linux/comstats.h>
@@ -1379,52 +1380,47 @@
 		stl_putchar(tty, ch);
 }
 
-/*****************************************************************************/
-
-#define	MAXLINE		80
-
-/*
- *	Format info for a specified port. The line is deliberately limited
- *	to 80 characters. (If it is too long it will be truncated, if too
- *	short then padded with spaces).
- */
-
-static int stl_portinfo(struct stlport *portp, int portnr, char *pos)
+static void stl_portinfo(struct seq_file *m, struct stlport *portp, int portnr)
 {
-	char	*sp;
-	int	sigs, cnt;
+	int	sigs;
+	char sep;
 
-	sp = pos;
-	sp += sprintf(sp, "%d: uart:%s tx:%d rx:%d",
+	seq_printf(m, "%d: uart:%s tx:%d rx:%d",
 		portnr, (portp->hwid == 1) ? "SC26198" : "CD1400",
 		(int) portp->stats.txtotal, (int) portp->stats.rxtotal);
 
 	if (portp->stats.rxframing)
-		sp += sprintf(sp, " fe:%d", (int) portp->stats.rxframing);
+		seq_printf(m, " fe:%d", (int) portp->stats.rxframing);
 	if (portp->stats.rxparity)
-		sp += sprintf(sp, " pe:%d", (int) portp->stats.rxparity);
+		seq_printf(m, " pe:%d", (int) portp->stats.rxparity);
 	if (portp->stats.rxbreaks)
-		sp += sprintf(sp, " brk:%d", (int) portp->stats.rxbreaks);
+		seq_printf(m, " brk:%d", (int) portp->stats.rxbreaks);
 	if (portp->stats.rxoverrun)
-		sp += sprintf(sp, " oe:%d", (int) portp->stats.rxoverrun);
+		seq_printf(m, " oe:%d", (int) portp->stats.rxoverrun);
 
 	sigs = stl_getsignals(portp);
-	cnt = sprintf(sp, "%s%s%s%s%s ",
-		(sigs & TIOCM_RTS) ? "|RTS" : "",
-		(sigs & TIOCM_CTS) ? "|CTS" : "",
-		(sigs & TIOCM_DTR) ? "|DTR" : "",
-		(sigs & TIOCM_CD) ? "|DCD" : "",
-		(sigs & TIOCM_DSR) ? "|DSR" : "");
-	*sp = ' ';
-	sp += cnt;
-
-	for (cnt = sp - pos; cnt < (MAXLINE - 1); cnt++)
-		*sp++ = ' ';
-	if (cnt >= MAXLINE)
-		pos[(MAXLINE - 2)] = '+';
-	pos[(MAXLINE - 1)] = '\n';
-
-	return MAXLINE;
+	sep = ' ';
+	if (sigs & TIOCM_RTS) {
+		seq_printf(m, "%c%s", sep, "RTS");
+		sep = '|';
+	}
+	if (sigs & TIOCM_CTS) {
+		seq_printf(m, "%c%s", sep, "CTS");
+		sep = '|';
+	}
+	if (sigs & TIOCM_DTR) {
+		seq_printf(m, "%c%s", sep, "DTR");
+		sep = '|';
+	}
+	if (sigs & TIOCM_CD) {
+		seq_printf(m, "%c%s", sep, "DCD");
+		sep = '|';
+	}
+	if (sigs & TIOCM_DSR) {
+		seq_printf(m, "%c%s", sep, "DSR");
+		sep = '|';
+	}
+	seq_putc(m, '\n');
 }
 
 /*****************************************************************************/
@@ -1433,30 +1429,17 @@
  *	Port info, read from the /proc file system.
  */
 
-static int stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int stl_proc_show(struct seq_file *m, void *v)
 {
 	struct stlbrd	*brdp;
 	struct stlpanel	*panelp;
 	struct stlport	*portp;
 	unsigned int	brdnr, panelnr, portnr;
-	int		totalport, curoff, maxoff;
-	char		*pos;
+	int		totalport;
 
-	pr_debug("stl_readproc(page=%p,start=%p,off=%lx,count=%d,eof=%p,"
-		"data=%p\n", page, start, off, count, eof, data);
-
-	pos = page;
 	totalport = 0;
-	curoff = 0;
 
-	if (off == 0) {
-		pos += sprintf(pos, "%s: version %s", stl_drvtitle,
-			stl_drvversion);
-		while (pos < (page + MAXLINE - 1))
-			*pos++ = ' ';
-		*pos++ = '\n';
-	}
-	curoff =  MAXLINE;
+	seq_printf(m, "%s: version %s\n", stl_drvtitle, stl_drvversion);
 
 /*
  *	We scan through for each board, panel and port. The offset is
@@ -1469,46 +1452,37 @@
 		if (brdp->state == 0)
 			continue;
 
-		maxoff = curoff + (brdp->nrports * MAXLINE);
-		if (off >= maxoff) {
-			curoff = maxoff;
-			continue;
-		}
-
 		totalport = brdnr * STL_MAXPORTS;
 		for (panelnr = 0; panelnr < brdp->nrpanels; panelnr++) {
 			panelp = brdp->panels[panelnr];
 			if (panelp == NULL)
 				continue;
 
-			maxoff = curoff + (panelp->nrports * MAXLINE);
-			if (off >= maxoff) {
-				curoff = maxoff;
-				totalport += panelp->nrports;
-				continue;
-			}
-
 			for (portnr = 0; portnr < panelp->nrports; portnr++,
 			    totalport++) {
 				portp = panelp->ports[portnr];
 				if (portp == NULL)
 					continue;
-				if (off >= (curoff += MAXLINE))
-					continue;
-				if ((pos - page + MAXLINE) > count)
-					goto stl_readdone;
-				pos += stl_portinfo(portp, totalport, pos);
+				stl_portinfo(m, portp, totalport);
 			}
 		}
 	}
-
-	*eof = 1;
-
-stl_readdone:
-	*start = page;
-	return pos - page;
+	return 0;
 }
 
+static int stl_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, stl_proc_show, NULL);
+}
+
+static const struct file_operations stl_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= stl_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /*****************************************************************************/
 
 /*
@@ -2566,9 +2540,9 @@
 	.break_ctl = stl_breakctl,
 	.wait_until_sent = stl_waituntilsent,
 	.send_xchar = stl_sendxchar,
-	.read_proc = stl_readproc,
 	.tiocmget = stl_tiocmget,
 	.tiocmset = stl_tiocmset,
+	.proc_fops = &stl_proc_fops,
 };
 
 static const struct tty_port_operations stl_port_ops = {
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 0057a8f..afd0b26 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -79,6 +79,7 @@
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
@@ -3459,18 +3460,17 @@
  * /proc fs routines....
  */
 
-static inline int line_info(char *buf, struct mgsl_struct *info)
+static inline void line_info(struct seq_file *m, struct mgsl_struct *info)
 {
 	char	stat_buf[30];
-	int	ret;
 	unsigned long flags;
 
 	if (info->bus_type == MGSL_BUS_TYPE_PCI) {
-		ret = sprintf(buf, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X",
+		seq_printf(m, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X",
 			info->device_name, info->io_base, info->irq_level,
 			info->phys_memory_base, info->phys_lcr_base);
 	} else {
-		ret = sprintf(buf, "%s:(E)ISA io:%04X irq:%d dma:%d",
+		seq_printf(m, "%s:(E)ISA io:%04X irq:%d dma:%d",
 			info->device_name, info->io_base, 
 			info->irq_level, info->dma_level);
 	}
@@ -3497,37 +3497,37 @@
 
 	if (info->params.mode == MGSL_MODE_HDLC ||
 	    info->params.mode == MGSL_MODE_RAW ) {
-		ret += sprintf(buf+ret, " HDLC txok:%d rxok:%d",
+		seq_printf(m, " HDLC txok:%d rxok:%d",
 			      info->icount.txok, info->icount.rxok);
 		if (info->icount.txunder)
-			ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+			seq_printf(m, " txunder:%d", info->icount.txunder);
 		if (info->icount.txabort)
-			ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+			seq_printf(m, " txabort:%d", info->icount.txabort);
 		if (info->icount.rxshort)
-			ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);	
+			seq_printf(m, " rxshort:%d", info->icount.rxshort);
 		if (info->icount.rxlong)
-			ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+			seq_printf(m, " rxlong:%d", info->icount.rxlong);
 		if (info->icount.rxover)
-			ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+			seq_printf(m, " rxover:%d", info->icount.rxover);
 		if (info->icount.rxcrc)
-			ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc);
+			seq_printf(m, " rxcrc:%d", info->icount.rxcrc);
 	} else {
-		ret += sprintf(buf+ret, " ASYNC tx:%d rx:%d",
+		seq_printf(m, " ASYNC tx:%d rx:%d",
 			      info->icount.tx, info->icount.rx);
 		if (info->icount.frame)
-			ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+			seq_printf(m, " fe:%d", info->icount.frame);
 		if (info->icount.parity)
-			ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+			seq_printf(m, " pe:%d", info->icount.parity);
 		if (info->icount.brk)
-			ret += sprintf(buf+ret, " brk:%d", info->icount.brk);	
+			seq_printf(m, " brk:%d", info->icount.brk);
 		if (info->icount.overrun)
-			ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+			seq_printf(m, " oe:%d", info->icount.overrun);
 	}
 	
 	/* Append serial signal status to end */
-	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+	seq_printf(m, " %s\n", stat_buf+1);
 	
-	ret += sprintf(buf+ret, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+	seq_printf(m, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
 	 info->tx_active,info->bh_requested,info->bh_running,
 	 info->pending_bh);
 	 
@@ -3544,60 +3544,40 @@
 	u16 Tmr = usc_InReg( info, TMR );
 	u16 Tccr = usc_InReg( info, TCCR );
 	u16 Ccar = inw( info->io_base + CCAR );
-	ret += sprintf(buf+ret, "tcsr=%04X tdmr=%04X ticr=%04X rcsr=%04X rdmr=%04X\n"
+	seq_printf(m, "tcsr=%04X tdmr=%04X ticr=%04X rcsr=%04X rdmr=%04X\n"
                         "ricr=%04X icr =%04X dccr=%04X tmr=%04X tccr=%04X ccar=%04X\n",
 	 		Tcsr,Tdmr,Ticr,Rscr,Rdmr,Ricr,Icr,Dccr,Tmr,Tccr,Ccar );
 	}
 	spin_unlock_irqrestore(&info->irq_spinlock,flags);
-	
-	return ret;
-	
-}	/* end of line_info() */
+}
 
-/* mgsl_read_proc()
- * 
- * Called to print information about devices
- * 
- * Arguments:
- * 	page	page of memory to hold returned info
- * 	start	
- * 	off
- * 	count
- * 	eof
- * 	data
- * 	
- * Return Value:
- */
-static int mgsl_read_proc(char *page, char **start, off_t off, int count,
-		 int *eof, void *data)
+/* Called to print information about devices */
+static int mgsl_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0, l;
-	off_t	begin = 0;
 	struct mgsl_struct *info;
 	
-	len += sprintf(page, "synclink driver:%s\n", driver_version);
+	seq_printf(m, "synclink driver:%s\n", driver_version);
 	
 	info = mgsl_device_list;
 	while( info ) {
-		l = line_info(page + len, info);
-		len += l;
-		if (len+begin > off+count)
-			goto done;
-		if (len+begin < off) {
-			begin += len;
-			len = 0;
-		}
+		line_info(m, info);
 		info = info->next_device;
 	}
+	return 0;
+}
 
-	*eof = 1;
-done:
-	if (off >= len+begin)
-		return 0;
-	*start = page + (off-begin);
-	return ((count < begin+len-off) ? count : begin+len-off);
-	
-}	/* end of mgsl_read_proc() */
+static int mgsl_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mgsl_proc_show, NULL);
+}
+
+static const struct file_operations mgsl_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= mgsl_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 
 /* mgsl_allocate_dma_buffers()
  * 
@@ -4335,13 +4315,13 @@
 	.send_xchar = mgsl_send_xchar,
 	.break_ctl = mgsl_break,
 	.wait_until_sent = mgsl_wait_until_sent,
- 	.read_proc = mgsl_read_proc,
 	.set_termios = mgsl_set_termios,
 	.stop = mgsl_stop,
 	.start = mgsl_start,
 	.hangup = mgsl_hangup,
 	.tiocmget = tiocmget,
 	.tiocmset = tiocmset,
+	.proc_fops = &mgsl_proc_fops,
 };
 
 /*
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index efb3dc9..6ec6e13 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -60,6 +60,7 @@
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
@@ -154,7 +155,6 @@
 static void tx_release(struct tty_struct *tty);
 
 static int  ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
-static int  read_proc(char *page, char **start, off_t off, int count,int *eof, void *data);
 static int  chars_in_buffer(struct tty_struct *tty);
 static void throttle(struct tty_struct * tty);
 static void unthrottle(struct tty_struct * tty);
@@ -1229,13 +1229,12 @@
 /*
  * proc fs support
  */
-static inline int line_info(char *buf, struct slgt_info *info)
+static inline void line_info(struct seq_file *m, struct slgt_info *info)
 {
 	char stat_buf[30];
-	int ret;
 	unsigned long flags;
 
-	ret = sprintf(buf, "%s: IO=%08X IRQ=%d MaxFrameSize=%u\n",
+	seq_printf(m, "%s: IO=%08X IRQ=%d MaxFrameSize=%u\n",
 		      info->device_name, info->phys_reg_addr,
 		      info->irq_level, info->max_frame_size);
 
@@ -1260,75 +1259,70 @@
 		strcat(stat_buf, "|RI");
 
 	if (info->params.mode != MGSL_MODE_ASYNC) {
-		ret += sprintf(buf+ret, "\tHDLC txok:%d rxok:%d",
+		seq_printf(m, "\tHDLC txok:%d rxok:%d",
 			       info->icount.txok, info->icount.rxok);
 		if (info->icount.txunder)
-			ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+			seq_printf(m, " txunder:%d", info->icount.txunder);
 		if (info->icount.txabort)
-			ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+			seq_printf(m, " txabort:%d", info->icount.txabort);
 		if (info->icount.rxshort)
-			ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);
+			seq_printf(m, " rxshort:%d", info->icount.rxshort);
 		if (info->icount.rxlong)
-			ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+			seq_printf(m, " rxlong:%d", info->icount.rxlong);
 		if (info->icount.rxover)
-			ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+			seq_printf(m, " rxover:%d", info->icount.rxover);
 		if (info->icount.rxcrc)
-			ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc);
+			seq_printf(m, " rxcrc:%d", info->icount.rxcrc);
 	} else {
-		ret += sprintf(buf+ret, "\tASYNC tx:%d rx:%d",
+		seq_printf(m, "\tASYNC tx:%d rx:%d",
 			       info->icount.tx, info->icount.rx);
 		if (info->icount.frame)
-			ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+			seq_printf(m, " fe:%d", info->icount.frame);
 		if (info->icount.parity)
-			ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+			seq_printf(m, " pe:%d", info->icount.parity);
 		if (info->icount.brk)
-			ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
+			seq_printf(m, " brk:%d", info->icount.brk);
 		if (info->icount.overrun)
-			ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+			seq_printf(m, " oe:%d", info->icount.overrun);
 	}
 
 	/* Append serial signal status to end */
-	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+	seq_printf(m, " %s\n", stat_buf+1);
 
-	ret += sprintf(buf+ret, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+	seq_printf(m, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
 		       info->tx_active,info->bh_requested,info->bh_running,
 		       info->pending_bh);
-
-	return ret;
 }
 
 /* Called to print information about devices
  */
-static int read_proc(char *page, char **start, off_t off, int count,
-		     int *eof, void *data)
+static int synclink_gt_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0, l;
-	off_t	begin = 0;
 	struct slgt_info *info;
 
-	len += sprintf(page, "synclink_gt driver\n");
+	seq_puts(m, "synclink_gt driver\n");
 
 	info = slgt_device_list;
 	while( info ) {
-		l = line_info(page + len, info);
-		len += l;
-		if (len+begin > off+count)
-			goto done;
-		if (len+begin < off) {
-			begin += len;
-			len = 0;
-		}
+		line_info(m, info);
 		info = info->next_device;
 	}
-
-	*eof = 1;
-done:
-	if (off >= len+begin)
-		return 0;
-	*start = page + (off-begin);
-	return ((count < begin+len-off) ? count : begin+len-off);
+	return 0;
 }
 
+static int synclink_gt_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, synclink_gt_proc_show, NULL);
+}
+
+static const struct file_operations synclink_gt_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= synclink_gt_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /*
  * return count of bytes in transmit buffer
  */
@@ -3562,13 +3556,13 @@
 	.send_xchar = send_xchar,
 	.break_ctl = set_break,
 	.wait_until_sent = wait_until_sent,
- 	.read_proc = read_proc,
 	.set_termios = set_termios,
 	.stop = tx_hold,
 	.start = tx_release,
 	.hangup = hangup,
 	.tiocmget = tiocmget,
 	.tiocmset = tiocmset,
+	.proc_fops = &synclink_gt_proc_fops,
 };
 
 static void slgt_cleanup(void)
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 8eb6c89..26de60e 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -50,6 +50,7 @@
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/mm.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
@@ -520,7 +521,6 @@
 static void tx_release(struct tty_struct *tty);
 
 static int  ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
-static int  read_proc(char *page, char **start, off_t off, int count,int *eof, void *data);
 static int  chars_in_buffer(struct tty_struct *tty);
 static void throttle(struct tty_struct * tty);
 static void unthrottle(struct tty_struct * tty);
@@ -1354,13 +1354,12 @@
  * /proc fs routines....
  */
 
-static inline int line_info(char *buf, SLMP_INFO *info)
+static inline void line_info(struct seq_file *m, SLMP_INFO *info)
 {
 	char	stat_buf[30];
-	int	ret;
 	unsigned long flags;
 
-	ret = sprintf(buf, "%s: SCABase=%08x Mem=%08X StatusControl=%08x LCR=%08X\n"
+	seq_printf(m, "%s: SCABase=%08x Mem=%08X StatusControl=%08x LCR=%08X\n"
 		       "\tIRQ=%d MaxFrameSize=%u\n",
 		info->device_name,
 		info->phys_sca_base,
@@ -1391,75 +1390,70 @@
 		strcat(stat_buf, "|RI");
 
 	if (info->params.mode == MGSL_MODE_HDLC) {
-		ret += sprintf(buf+ret, "\tHDLC txok:%d rxok:%d",
+		seq_printf(m, "\tHDLC txok:%d rxok:%d",
 			      info->icount.txok, info->icount.rxok);
 		if (info->icount.txunder)
-			ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+			seq_printf(m, " txunder:%d", info->icount.txunder);
 		if (info->icount.txabort)
-			ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+			seq_printf(m, " txabort:%d", info->icount.txabort);
 		if (info->icount.rxshort)
-			ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);
+			seq_printf(m, " rxshort:%d", info->icount.rxshort);
 		if (info->icount.rxlong)
-			ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+			seq_printf(m, " rxlong:%d", info->icount.rxlong);
 		if (info->icount.rxover)
-			ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+			seq_printf(m, " rxover:%d", info->icount.rxover);
 		if (info->icount.rxcrc)
-			ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxcrc);
+			seq_printf(m, " rxlong:%d", info->icount.rxcrc);
 	} else {
-		ret += sprintf(buf+ret, "\tASYNC tx:%d rx:%d",
+		seq_printf(m, "\tASYNC tx:%d rx:%d",
 			      info->icount.tx, info->icount.rx);
 		if (info->icount.frame)
-			ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+			seq_printf(m, " fe:%d", info->icount.frame);
 		if (info->icount.parity)
-			ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+			seq_printf(m, " pe:%d", info->icount.parity);
 		if (info->icount.brk)
-			ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
+			seq_printf(m, " brk:%d", info->icount.brk);
 		if (info->icount.overrun)
-			ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+			seq_printf(m, " oe:%d", info->icount.overrun);
 	}
 
 	/* Append serial signal status to end */
-	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+	seq_printf(m, " %s\n", stat_buf+1);
 
-	ret += sprintf(buf+ret, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+	seq_printf(m, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
 	 info->tx_active,info->bh_requested,info->bh_running,
 	 info->pending_bh);
-
-	return ret;
 }
 
 /* Called to print information about devices
  */
-static int read_proc(char *page, char **start, off_t off, int count,
-	      int *eof, void *data)
+static int synclinkmp_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0, l;
-	off_t	begin = 0;
 	SLMP_INFO *info;
 
-	len += sprintf(page, "synclinkmp driver:%s\n", driver_version);
+	seq_printf(m, "synclinkmp driver:%s\n", driver_version);
 
 	info = synclinkmp_device_list;
 	while( info ) {
-		l = line_info(page + len, info);
-		len += l;
-		if (len+begin > off+count)
-			goto done;
-		if (len+begin < off) {
-			begin += len;
-			len = 0;
-		}
+		line_info(m, info);
 		info = info->next_device;
 	}
-
-	*eof = 1;
-done:
-	if (off >= len+begin)
-		return 0;
-	*start = page + (off-begin);
-	return ((count < begin+len-off) ? count : begin+len-off);
+	return 0;
 }
 
+static int synclinkmp_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, synclinkmp_proc_show, NULL);
+}
+
+static const struct file_operations synclinkmp_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= synclinkmp_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /* Return the count of bytes in transmit buffer
  */
 static int chars_in_buffer(struct tty_struct *tty)
@@ -3905,13 +3899,13 @@
 	.send_xchar = send_xchar,
 	.break_ctl = set_break,
 	.wait_until_sent = wait_until_sent,
- 	.read_proc = read_proc,
 	.set_termios = set_termios,
 	.stop = tx_hold,
 	.start = tx_release,
 	.hangup = hangup,
 	.tiocmget = tiocmget,
 	.tiocmset = tiocmset,
+	.proc_fops = &synclinkmp_proc_fops,
 };
 
 
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 3df694e..ebea9b2 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -346,6 +346,19 @@
 	.enable_mask	= SYSRQ_ENABLE_SIGNAL,
 };
 
+#ifdef CONFIG_BLOCK
+static void sysrq_handle_thaw(int key, struct tty_struct *tty)
+{
+	emergency_thaw_all();
+}
+static struct sysrq_key_op sysrq_thaw_op = {
+	.handler	= sysrq_handle_thaw,
+	.help_msg	= "thaw-filesystems(J)",
+	.action_msg	= "Emergency Thaw of all frozen filesystems",
+	.enable_mask	= SYSRQ_ENABLE_SIGNAL,
+};
+#endif
+
 static void sysrq_handle_kill(int key, struct tty_struct *tty)
 {
 	send_sig_all(SIGKILL);
@@ -396,9 +409,13 @@
 	&sysrq_moom_op,			/* f */
 	/* g: May be registered by ppc for kgdb */
 	NULL,				/* g */
-	NULL,				/* h */
+	NULL,				/* h - reserved for help */
 	&sysrq_kill_op,			/* i */
+#ifdef CONFIG_BLOCK
+	&sysrq_thaw_op,			/* j */
+#else
 	NULL,				/* j */
+#endif
 	&sysrq_SAK_op,			/* k */
 #ifdef CONFIG_SMP
 	&sysrq_showallcpus_op,		/* l */
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 224f271..33dac94 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -464,7 +464,7 @@
 			tty_ldisc_deref(ld);
 		}
 	}
-	wake_up_interruptible(&tty->write_wait);
+	wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
 }
 
 EXPORT_SYMBOL_GPL(tty_wakeup);
@@ -587,8 +587,8 @@
 	 * FIXME: Once we trust the LDISC code better we can wait here for
 	 * ldisc completion and fix the driver call race
 	 */
-	wake_up_interruptible(&tty->write_wait);
-	wake_up_interruptible(&tty->read_wait);
+	wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
+	wake_up_interruptible_poll(&tty->read_wait, POLLIN);
 	/*
 	 * Shutdown the current line discipline, and reset it to
 	 * N_TTY.
@@ -879,7 +879,7 @@
 	if (tty->link && tty->link->packet) {
 		tty->ctrl_status &= ~TIOCPKT_START;
 		tty->ctrl_status |= TIOCPKT_STOP;
-		wake_up_interruptible(&tty->link->read_wait);
+		wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
 	}
 	spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 	if (tty->ops->stop)
@@ -913,7 +913,7 @@
 	if (tty->link && tty->link->packet) {
 		tty->ctrl_status &= ~TIOCPKT_STOP;
 		tty->ctrl_status |= TIOCPKT_START;
-		wake_up_interruptible(&tty->link->read_wait);
+		wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
 	}
 	spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 	if (tty->ops->start)
@@ -970,7 +970,7 @@
 void tty_write_unlock(struct tty_struct *tty)
 {
 	mutex_unlock(&tty->atomic_write_lock);
-	wake_up_interruptible(&tty->write_wait);
+	wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
 }
 
 int tty_write_lock(struct tty_struct *tty, int ndelay)
@@ -1623,21 +1623,21 @@
 
 		if (tty_closing) {
 			if (waitqueue_active(&tty->read_wait)) {
-				wake_up(&tty->read_wait);
+				wake_up_poll(&tty->read_wait, POLLIN);
 				do_sleep++;
 			}
 			if (waitqueue_active(&tty->write_wait)) {
-				wake_up(&tty->write_wait);
+				wake_up_poll(&tty->write_wait, POLLOUT);
 				do_sleep++;
 			}
 		}
 		if (o_tty_closing) {
 			if (waitqueue_active(&o_tty->read_wait)) {
-				wake_up(&o_tty->read_wait);
+				wake_up_poll(&o_tty->read_wait, POLLIN);
 				do_sleep++;
 			}
 			if (waitqueue_active(&o_tty->write_wait)) {
-				wake_up(&o_tty->write_wait);
+				wake_up_poll(&o_tty->write_wait, POLLOUT);
 				do_sleep++;
 			}
 		}
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 51ff9b3..ce52bf2 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -571,6 +571,17 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called lm93.
 
+config SENSORS_LTC4215
+	tristate "Linear Technology LTC4215"
+	depends on I2C && EXPERIMENTAL
+	default n
+	help
+	  If you say yes here you get support for Linear Technology LTC4215
+	  Hot Swap Controller I2C interface.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called ltc4215.
+
 config SENSORS_LTC4245
 	tristate "Linear Technology LTC4245"
 	depends on I2C && EXPERIMENTAL
@@ -582,6 +593,15 @@
 	  This driver can also be built as a module. If so, the module will
 	  be called ltc4245.
 
+config SENSORS_LM95241
+	tristate "National Semiconductor LM95241 sensor chip"
+	depends on I2C
+	help
+	  If you say yes here you get support for LM95241 sensor chip.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called lm95241.
+
 config SENSORS_MAX1111
 	tristate "Maxim MAX1111 Multichannel, Serial 8-bit ADC chip"
 	depends on SPI_MASTER
@@ -912,6 +932,22 @@
 	  Say Y here if you have an applicable laptop and want to experience
 	  the awesome power of lis3lv02d.
 
+config SENSORS_LIS3_SPI
+	tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)"
+	depends on !ACPI && SPI_MASTER && INPUT
+	default n
+	help
+	  This driver provides support for the LIS3LV02Dx accelerometer connected
+	  via SPI. The accelerometer data is readable via
+	  /sys/devices/platform/lis3lv02d.
+
+	  This driver also provides an absolute input class device, allowing
+	  the laptop to act as a pinball machine-esque joystick.
+
+	  This driver can also be built as modules.  If so, the core module
+	  will be called lis3lv02d and a specific module for the SPI transport
+	  is called lis3lv02d_spi.
+
 config SENSORS_APPLESMC
 	tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)"
 	depends on INPUT && X86
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index e332d62..3a6b1f0 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -52,6 +52,7 @@
 obj-$(CONFIG_SENSORS_IT87)	+= it87.o
 obj-$(CONFIG_SENSORS_K8TEMP)	+= k8temp.o
 obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o hp_accel.o
+obj-$(CONFIG_SENSORS_LIS3_SPI)	+= lis3lv02d.o lis3lv02d_spi.o
 obj-$(CONFIG_SENSORS_LM63)	+= lm63.o
 obj-$(CONFIG_SENSORS_LM70)	+= lm70.o
 obj-$(CONFIG_SENSORS_LM75)	+= lm75.o
@@ -64,6 +65,8 @@
 obj-$(CONFIG_SENSORS_LM90)	+= lm90.o
 obj-$(CONFIG_SENSORS_LM92)	+= lm92.o
 obj-$(CONFIG_SENSORS_LM93)	+= lm93.o
+obj-$(CONFIG_SENSORS_LM95241)	+= lm95241.o
+obj-$(CONFIG_SENSORS_LTC4215)	+= ltc4215.o
 obj-$(CONFIG_SENSORS_LTC4245)	+= ltc4245.o
 obj-$(CONFIG_SENSORS_MAX1111)	+= max1111.o
 obj-$(CONFIG_SENSORS_MAX1619)	+= max1619.o
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c
index 29c83b5..55d3dc5 100644
--- a/drivers/hwmon/hp_accel.c
+++ b/drivers/hwmon/hp_accel.c
@@ -85,25 +85,31 @@
 
 /**
  * lis3lv02d_acpi_init - ACPI _INI method: initialize the device.
- * @handle: the handle of the device
+ * @lis3: pointer to the device struct
  *
- * Returns AE_OK on success.
+ * Returns 0 on success.
  */
-acpi_status lis3lv02d_acpi_init(acpi_handle handle)
+int lis3lv02d_acpi_init(struct lis3lv02d *lis3)
 {
-	return acpi_evaluate_object(handle, METHOD_NAME__INI, NULL, NULL);
+	struct acpi_device *dev = lis3->bus_priv;
+	if (acpi_evaluate_object(dev->handle, METHOD_NAME__INI,
+				 NULL, NULL) != AE_OK)
+		return -EINVAL;
+
+	return 0;
 }
 
 /**
  * lis3lv02d_acpi_read - ACPI ALRD method: read a register
- * @handle: the handle of the device
+ * @lis3: pointer to the device struct
  * @reg:    the register to read
  * @ret:    result of the operation
  *
- * Returns AE_OK on success.
+ * Returns 0 on success.
  */
-acpi_status lis3lv02d_acpi_read(acpi_handle handle, int reg, u8 *ret)
+int lis3lv02d_acpi_read(struct lis3lv02d *lis3, int reg, u8 *ret)
 {
+	struct acpi_device *dev = lis3->bus_priv;
 	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
 	struct acpi_object_list args = { 1, &arg0 };
 	unsigned long long lret;
@@ -111,21 +117,22 @@
 
 	arg0.integer.value = reg;
 
-	status = acpi_evaluate_integer(handle, "ALRD", &args, &lret);
+	status = acpi_evaluate_integer(dev->handle, "ALRD", &args, &lret);
 	*ret = lret;
-	return status;
+	return (status != AE_OK) ? -EINVAL : 0;
 }
 
 /**
  * lis3lv02d_acpi_write - ACPI ALWR method: write to a register
- * @handle: the handle of the device
+ * @lis3: pointer to the device struct
  * @reg:    the register to write to
  * @val:    the value to write
  *
- * Returns AE_OK on success.
+ * Returns 0 on success.
  */
-acpi_status lis3lv02d_acpi_write(acpi_handle handle, int reg, u8 val)
+int lis3lv02d_acpi_write(struct lis3lv02d *lis3, int reg, u8 val)
 {
+	struct acpi_device *dev = lis3->bus_priv;
 	unsigned long long ret; /* Not used when writting */
 	union acpi_object in_obj[2];
 	struct acpi_object_list args = { 2, in_obj };
@@ -135,12 +142,15 @@
 	in_obj[1].type          = ACPI_TYPE_INTEGER;
 	in_obj[1].integer.value = val;
 
-	return acpi_evaluate_integer(handle, "ALWR", &args, &ret);
+	if (acpi_evaluate_integer(dev->handle, "ALWR", &args, &ret) != AE_OK)
+		return -EINVAL;
+
+	return 0;
 }
 
 static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi)
 {
-	adev.ac = *((struct axis_conversion *)dmi->driver_data);
+	lis3_dev.ac = *((struct axis_conversion *)dmi->driver_data);
 	printk(KERN_INFO DRIVER_NAME ": hardware type %s found.\n", dmi->ident);
 
 	return 1;
@@ -187,6 +197,7 @@
 	AXIS_DMI_MATCH("NC2510", "HP Compaq 2510", y_inverted),
 	AXIS_DMI_MATCH("NC8510", "HP Compaq 8510", xy_swap_inverted),
 	AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left),
+	AXIS_DMI_MATCH("HP2140", "HP 2140", xy_swap_inverted),
 	AXIS_DMI_MATCH("NC653x", "HP Compaq 653", xy_rotated_left_usd),
 	AXIS_DMI_MATCH("NC673x", "HP Compaq 673", xy_rotated_left_usd),
 	AXIS_DMI_MATCH("NC651xx", "HP Compaq 651", xy_rotated_right),
@@ -201,6 +212,8 @@
 			PRODUCT_NAME, "HP Pavilion dv5",
 			BOARD_NAME, "3600",
 			y_inverted),
+	AXIS_DMI_MATCH("DV7", "HP Pavilion dv7", x_inverted),
+	AXIS_DMI_MATCH("HP8710", "HP Compaq 8710", y_inverted),
 	{ NULL, }
 /* Laptop models without axis info (yet):
  * "NC6910" "HP Compaq 6910"
@@ -214,7 +227,7 @@
 
 static void hpled_set(struct delayed_led_classdev *led_cdev, enum led_brightness value)
 {
-	acpi_handle handle = adev.device->handle;
+	struct acpi_device *dev = lis3_dev.bus_priv;
 	unsigned long long ret; /* Not used when writing */
 	union acpi_object in_obj[1];
 	struct acpi_object_list args = { 1, in_obj };
@@ -222,7 +235,7 @@
 	in_obj[0].type          = ACPI_TYPE_INTEGER;
 	in_obj[0].integer.value = !!value;
 
-	acpi_evaluate_integer(handle, "ALED", &args, &ret);
+	acpi_evaluate_integer(dev->handle, "ALED", &args, &ret);
 }
 
 static struct delayed_led_classdev hpled_led = {
@@ -254,28 +267,11 @@
 	acpi_status status;
 
 	status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
-					lis3lv02d_get_resource, &adev.irq);
+					lis3lv02d_get_resource, &lis3_dev.irq);
 	if (ACPI_FAILURE(status))
 		printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n");
 }
 
-static s16 lis3lv02d_read_16(acpi_handle handle, int reg)
-{
-	u8 lo, hi;
-
-	adev.read(handle, reg - 1, &lo);
-	adev.read(handle, reg, &hi);
-	/* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
-	return (s16)((hi << 8) | lo);
-}
-
-static s16 lis3lv02d_read_8(acpi_handle handle, int reg)
-{
-	s8 lo;
-	adev.read(handle, reg, &lo);
-	return lo;
-}
-
 static int lis3lv02d_add(struct acpi_device *device)
 {
 	int ret;
@@ -283,51 +279,35 @@
 	if (!device)
 		return -EINVAL;
 
-	adev.device = device;
-	adev.init = lis3lv02d_acpi_init;
-	adev.read = lis3lv02d_acpi_read;
-	adev.write = lis3lv02d_acpi_write;
+	lis3_dev.bus_priv = device;
+	lis3_dev.init = lis3lv02d_acpi_init;
+	lis3_dev.read = lis3lv02d_acpi_read;
+	lis3_dev.write = lis3lv02d_acpi_write;
 	strcpy(acpi_device_name(device), DRIVER_NAME);
 	strcpy(acpi_device_class(device), ACPI_MDPS_CLASS);
-	device->driver_data = &adev;
+	device->driver_data = &lis3_dev;
 
-	lis3lv02d_acpi_read(device->handle, WHO_AM_I, &adev.whoami);
-	switch (adev.whoami) {
-	case LIS_DOUBLE_ID:
-		printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n");
-		adev.read_data = lis3lv02d_read_16;
-		adev.mdps_max_val = 2048;
-		break;
-	case LIS_SINGLE_ID:
-		printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n");
-		adev.read_data = lis3lv02d_read_8;
-		adev.mdps_max_val = 128;
-		break;
-	default:
-		printk(KERN_ERR DRIVER_NAME
-			": unknown sensor type 0x%X\n", adev.whoami);
-		return -EINVAL;
-	}
+	/* obtain IRQ number of our device from ACPI */
+	lis3lv02d_enum_resources(device);
 
 	/* If possible use a "standard" axes order */
 	if (dmi_check_system(lis3lv02d_dmi_ids) == 0) {
 		printk(KERN_INFO DRIVER_NAME ": laptop model unknown, "
 				 "using default axes configuration\n");
-		adev.ac = lis3lv02d_axis_normal;
+		lis3_dev.ac = lis3lv02d_axis_normal;
 	}
 
-	INIT_WORK(&hpled_led.work, delayed_set_status_worker);
-	ret = led_classdev_register(NULL, &hpled_led.led_classdev);
+	/* call the core layer do its init */
+	ret = lis3lv02d_init_device(&lis3_dev);
 	if (ret)
 		return ret;
 
-	/* obtain IRQ number of our device from ACPI */
-	lis3lv02d_enum_resources(adev.device);
-
-	ret = lis3lv02d_init_device(&adev);
+	INIT_WORK(&hpled_led.work, delayed_set_status_worker);
+	ret = led_classdev_register(NULL, &hpled_led.led_classdev);
 	if (ret) {
+		lis3lv02d_joystick_disable();
+		lis3lv02d_poweroff(&lis3_dev);
 		flush_work(&hpled_led.work);
-		led_classdev_unregister(&hpled_led.led_classdev);
 		return ret;
 	}
 
@@ -340,7 +320,7 @@
 		return -EINVAL;
 
 	lis3lv02d_joystick_disable();
-	lis3lv02d_poweroff(device->handle);
+	lis3lv02d_poweroff(&lis3_dev);
 
 	flush_work(&hpled_led.work);
 	led_classdev_unregister(&hpled_led.led_classdev);
@@ -353,19 +333,19 @@
 static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state)
 {
 	/* make sure the device is off when we suspend */
-	lis3lv02d_poweroff(device->handle);
+	lis3lv02d_poweroff(&lis3_dev);
 	return 0;
 }
 
 static int lis3lv02d_resume(struct acpi_device *device)
 {
 	/* put back the device in the right state (ACPI might turn it on) */
-	mutex_lock(&adev.lock);
-	if (adev.usage > 0)
-		lis3lv02d_poweron(device->handle);
+	mutex_lock(&lis3_dev.lock);
+	if (lis3_dev.usage > 0)
+		lis3lv02d_poweron(&lis3_dev);
 	else
-		lis3lv02d_poweroff(device->handle);
-	mutex_unlock(&adev.lock);
+		lis3lv02d_poweroff(&lis3_dev);
+	mutex_unlock(&lis3_dev.lock);
 	return 0;
 }
 #else
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index 8bb2158..778eb77 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -36,7 +36,6 @@
 #include <linux/freezer.h>
 #include <linux/uaccess.h>
 #include <linux/miscdevice.h>
-#include <acpi/acpi_drivers.h>
 #include <asm/atomic.h>
 #include "lis3lv02d.h"
 
@@ -53,13 +52,30 @@
  * joystick.
  */
 
-struct acpi_lis3lv02d adev = {
-	.misc_wait   = __WAIT_QUEUE_HEAD_INITIALIZER(adev.misc_wait),
+struct lis3lv02d lis3_dev = {
+	.misc_wait   = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait),
 };
 
-EXPORT_SYMBOL_GPL(adev);
+EXPORT_SYMBOL_GPL(lis3_dev);
 
-static int lis3lv02d_add_fs(struct acpi_device *device);
+static s16 lis3lv02d_read_8(struct lis3lv02d *lis3, int reg)
+{
+	s8 lo;
+	if (lis3->read(lis3, reg, &lo) < 0)
+		return 0;
+
+	return lo;
+}
+
+static s16 lis3lv02d_read_16(struct lis3lv02d *lis3, int reg)
+{
+	u8 lo, hi;
+
+	lis3->read(lis3, reg - 1, &lo);
+	lis3->read(lis3, reg, &hi);
+	/* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
+	return (s16)((hi << 8) | lo);
+}
 
 /**
  * lis3lv02d_get_axis - For the given axis, give the value converted
@@ -78,36 +94,36 @@
 
 /**
  * lis3lv02d_get_xyz - Get X, Y and Z axis values from the accelerometer
- * @handle: the handle to the device
- * @x:      where to store the X axis value
- * @y:      where to store the Y axis value
- * @z:      where to store the Z axis value
+ * @lis3: pointer to the device struct
+ * @x:    where to store the X axis value
+ * @y:    where to store the Y axis value
+ * @z:    where to store the Z axis value
  *
  * Note that 40Hz input device can eat up about 10% CPU at 800MHZ
  */
-static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z)
+static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
 {
 	int position[3];
 
-	position[0] = adev.read_data(handle, OUTX);
-	position[1] = adev.read_data(handle, OUTY);
-	position[2] = adev.read_data(handle, OUTZ);
+	position[0] = lis3_dev.read_data(lis3, OUTX);
+	position[1] = lis3_dev.read_data(lis3, OUTY);
+	position[2] = lis3_dev.read_data(lis3, OUTZ);
 
-	*x = lis3lv02d_get_axis(adev.ac.x, position);
-	*y = lis3lv02d_get_axis(adev.ac.y, position);
-	*z = lis3lv02d_get_axis(adev.ac.z, position);
+	*x = lis3lv02d_get_axis(lis3_dev.ac.x, position);
+	*y = lis3lv02d_get_axis(lis3_dev.ac.y, position);
+	*z = lis3lv02d_get_axis(lis3_dev.ac.z, position);
 }
 
-void lis3lv02d_poweroff(acpi_handle handle)
+void lis3lv02d_poweroff(struct lis3lv02d *lis3)
 {
-	adev.is_on = 0;
+	lis3_dev.is_on = 0;
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_poweroff);
 
-void lis3lv02d_poweron(acpi_handle handle)
+void lis3lv02d_poweron(struct lis3lv02d *lis3)
 {
-	adev.is_on = 1;
-	adev.init(handle);
+	lis3_dev.is_on = 1;
+	lis3_dev.init(lis3);
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
 
@@ -116,13 +132,13 @@
  * device will always be on until a call to lis3lv02d_decrease_use(). Not to be
  * used from interrupt context.
  */
-static void lis3lv02d_increase_use(struct acpi_lis3lv02d *dev)
+static void lis3lv02d_increase_use(struct lis3lv02d *dev)
 {
 	mutex_lock(&dev->lock);
 	dev->usage++;
 	if (dev->usage == 1) {
 		if (!dev->is_on)
-			lis3lv02d_poweron(dev->device->handle);
+			lis3lv02d_poweron(dev);
 	}
 	mutex_unlock(&dev->lock);
 }
@@ -131,12 +147,12 @@
  * To be called whenever a usage of the device is stopped.
  * It will make sure to turn off the device when there is not usage.
  */
-static void lis3lv02d_decrease_use(struct acpi_lis3lv02d *dev)
+static void lis3lv02d_decrease_use(struct lis3lv02d *dev)
 {
 	mutex_lock(&dev->lock);
 	dev->usage--;
 	if (dev->usage == 0)
-		lis3lv02d_poweroff(dev->device->handle);
+		lis3lv02d_poweroff(dev);
 	mutex_unlock(&dev->lock);
 }
 
@@ -147,10 +163,10 @@
 	 * the lid is closed. This leads to interrupts as soon as a little move
 	 * is done.
 	 */
-	atomic_inc(&adev.count);
+	atomic_inc(&lis3_dev.count);
 
-	wake_up_interruptible(&adev.misc_wait);
-	kill_fasync(&adev.async_queue, SIGIO, POLL_IN);
+	wake_up_interruptible(&lis3_dev.misc_wait);
+	kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN);
 	return IRQ_HANDLED;
 }
 
@@ -158,10 +174,10 @@
 {
 	int ret;
 
-	if (test_and_set_bit(0, &adev.misc_opened))
+	if (test_and_set_bit(0, &lis3_dev.misc_opened))
 		return -EBUSY; /* already open */
 
-	atomic_set(&adev.count, 0);
+	atomic_set(&lis3_dev.count, 0);
 
 	/*
 	 * The sensor can generate interrupts for free-fall and direction
@@ -174,25 +190,25 @@
 	 * io-apic is not configurable (and generates a warning) but I keep it
 	 * in case of support for other hardware.
 	 */
-	ret = request_irq(adev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING,
-			  DRIVER_NAME, &adev);
+	ret = request_irq(lis3_dev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING,
+			  DRIVER_NAME, &lis3_dev);
 
 	if (ret) {
-		clear_bit(0, &adev.misc_opened);
-		printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", adev.irq);
+		clear_bit(0, &lis3_dev.misc_opened);
+		printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", lis3_dev.irq);
 		return -EBUSY;
 	}
-	lis3lv02d_increase_use(&adev);
-	printk("lis3: registered interrupt %d\n", adev.irq);
+	lis3lv02d_increase_use(&lis3_dev);
+	printk("lis3: registered interrupt %d\n", lis3_dev.irq);
 	return 0;
 }
 
 static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
 {
-	fasync_helper(-1, file, 0, &adev.async_queue);
-	lis3lv02d_decrease_use(&adev);
-	free_irq(adev.irq, &adev);
-	clear_bit(0, &adev.misc_opened); /* release the device */
+	fasync_helper(-1, file, 0, &lis3_dev.async_queue);
+	lis3lv02d_decrease_use(&lis3_dev);
+	free_irq(lis3_dev.irq, &lis3_dev);
+	clear_bit(0, &lis3_dev.misc_opened); /* release the device */
 	return 0;
 }
 
@@ -207,10 +223,10 @@
 	if (count < 1)
 		return -EINVAL;
 
-	add_wait_queue(&adev.misc_wait, &wait);
+	add_wait_queue(&lis3_dev.misc_wait, &wait);
 	while (true) {
 		set_current_state(TASK_INTERRUPTIBLE);
-		data = atomic_xchg(&adev.count, 0);
+		data = atomic_xchg(&lis3_dev.count, 0);
 		if (data)
 			break;
 
@@ -240,22 +256,22 @@
 
 out:
 	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(&adev.misc_wait, &wait);
+	remove_wait_queue(&lis3_dev.misc_wait, &wait);
 
 	return retval;
 }
 
 static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait)
 {
-	poll_wait(file, &adev.misc_wait, wait);
-	if (atomic_read(&adev.count))
+	poll_wait(file, &lis3_dev.misc_wait, wait);
+	if (atomic_read(&lis3_dev.count))
 		return POLLIN | POLLRDNORM;
 	return 0;
 }
 
 static int lis3lv02d_misc_fasync(int fd, struct file *file, int on)
 {
-	return fasync_helper(fd, file, on, &adev.async_queue);
+	return fasync_helper(fd, file, on, &lis3_dev.async_queue);
 }
 
 static const struct file_operations lis3lv02d_misc_fops = {
@@ -283,12 +299,12 @@
 	int x, y, z;
 
 	while (!kthread_should_stop()) {
-		lis3lv02d_get_xyz(adev.device->handle, &x, &y, &z);
-		input_report_abs(adev.idev, ABS_X, x - adev.xcalib);
-		input_report_abs(adev.idev, ABS_Y, y - adev.ycalib);
-		input_report_abs(adev.idev, ABS_Z, z - adev.zcalib);
+		lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
+		input_report_abs(lis3_dev.idev, ABS_X, x - lis3_dev.xcalib);
+		input_report_abs(lis3_dev.idev, ABS_Y, y - lis3_dev.ycalib);
+		input_report_abs(lis3_dev.idev, ABS_Z, z - lis3_dev.zcalib);
 
-		input_sync(adev.idev);
+		input_sync(lis3_dev.idev);
 
 		try_to_freeze();
 		msleep_interruptible(MDPS_POLL_INTERVAL);
@@ -299,11 +315,11 @@
 
 static int lis3lv02d_joystick_open(struct input_dev *input)
 {
-	lis3lv02d_increase_use(&adev);
-	adev.kthread = kthread_run(lis3lv02d_joystick_kthread, NULL, "klis3lv02d");
-	if (IS_ERR(adev.kthread)) {
-		lis3lv02d_decrease_use(&adev);
-		return PTR_ERR(adev.kthread);
+	lis3lv02d_increase_use(&lis3_dev);
+	lis3_dev.kthread = kthread_run(lis3lv02d_joystick_kthread, NULL, "klis3lv02d");
+	if (IS_ERR(lis3_dev.kthread)) {
+		lis3lv02d_decrease_use(&lis3_dev);
+		return PTR_ERR(lis3_dev.kthread);
 	}
 
 	return 0;
@@ -311,45 +327,46 @@
 
 static void lis3lv02d_joystick_close(struct input_dev *input)
 {
-	kthread_stop(adev.kthread);
-	lis3lv02d_decrease_use(&adev);
+	kthread_stop(lis3_dev.kthread);
+	lis3lv02d_decrease_use(&lis3_dev);
 }
 
 static inline void lis3lv02d_calibrate_joystick(void)
 {
-	lis3lv02d_get_xyz(adev.device->handle, &adev.xcalib, &adev.ycalib, &adev.zcalib);
+	lis3lv02d_get_xyz(&lis3_dev,
+		&lis3_dev.xcalib, &lis3_dev.ycalib, &lis3_dev.zcalib);
 }
 
 int lis3lv02d_joystick_enable(void)
 {
 	int err;
 
-	if (adev.idev)
+	if (lis3_dev.idev)
 		return -EINVAL;
 
-	adev.idev = input_allocate_device();
-	if (!adev.idev)
+	lis3_dev.idev = input_allocate_device();
+	if (!lis3_dev.idev)
 		return -ENOMEM;
 
 	lis3lv02d_calibrate_joystick();
 
-	adev.idev->name       = "ST LIS3LV02DL Accelerometer";
-	adev.idev->phys       = DRIVER_NAME "/input0";
-	adev.idev->id.bustype = BUS_HOST;
-	adev.idev->id.vendor  = 0;
-	adev.idev->dev.parent = &adev.pdev->dev;
-	adev.idev->open       = lis3lv02d_joystick_open;
-	adev.idev->close      = lis3lv02d_joystick_close;
+	lis3_dev.idev->name       = "ST LIS3LV02DL Accelerometer";
+	lis3_dev.idev->phys       = DRIVER_NAME "/input0";
+	lis3_dev.idev->id.bustype = BUS_HOST;
+	lis3_dev.idev->id.vendor  = 0;
+	lis3_dev.idev->dev.parent = &lis3_dev.pdev->dev;
+	lis3_dev.idev->open       = lis3lv02d_joystick_open;
+	lis3_dev.idev->close      = lis3lv02d_joystick_close;
 
-	set_bit(EV_ABS, adev.idev->evbit);
-	input_set_abs_params(adev.idev, ABS_X, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
-	input_set_abs_params(adev.idev, ABS_Y, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
-	input_set_abs_params(adev.idev, ABS_Z, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
+	set_bit(EV_ABS, lis3_dev.idev->evbit);
+	input_set_abs_params(lis3_dev.idev, ABS_X, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3);
+	input_set_abs_params(lis3_dev.idev, ABS_Y, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3);
+	input_set_abs_params(lis3_dev.idev, ABS_Z, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3);
 
-	err = input_register_device(adev.idev);
+	err = input_register_device(lis3_dev.idev);
 	if (err) {
-		input_free_device(adev.idev);
-		adev.idev = NULL;
+		input_free_device(lis3_dev.idev);
+		lis3_dev.idev = NULL;
 	}
 
 	return err;
@@ -358,71 +375,40 @@
 
 void lis3lv02d_joystick_disable(void)
 {
-	if (!adev.idev)
+	if (!lis3_dev.idev)
 		return;
 
 	misc_deregister(&lis3lv02d_misc_device);
-	input_unregister_device(adev.idev);
-	adev.idev = NULL;
+	input_unregister_device(lis3_dev.idev);
+	lis3_dev.idev = NULL;
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable);
 
-/*
- * Initialise the accelerometer and the various subsystems.
- * Should be rather independant of the bus system.
- */
-int lis3lv02d_init_device(struct acpi_lis3lv02d *dev)
-{
-	mutex_init(&dev->lock);
-	lis3lv02d_add_fs(dev->device);
-	lis3lv02d_increase_use(dev);
-
-	if (lis3lv02d_joystick_enable())
-		printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
-
-	printk("lis3_init_device: irq %d\n", dev->irq);
-
-	/* if we did not get an IRQ from ACPI - we have nothing more to do */
-	if (!dev->irq) {
-		printk(KERN_ERR DRIVER_NAME
-			": No IRQ in ACPI. Disabling /dev/freefall\n");
-		goto out;
-	}
-
-	printk("lis3: registering device\n");
-	if (misc_register(&lis3lv02d_misc_device))
-		printk(KERN_ERR DRIVER_NAME ": misc_register failed\n");
-out:
-	lis3lv02d_decrease_use(dev);
-	return 0;
-}
-EXPORT_SYMBOL_GPL(lis3lv02d_init_device);
-
 /* Sysfs stuff */
 static ssize_t lis3lv02d_position_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
 	int x, y, z;
 
-	lis3lv02d_increase_use(&adev);
-	lis3lv02d_get_xyz(adev.device->handle, &x, &y, &z);
-	lis3lv02d_decrease_use(&adev);
+	lis3lv02d_increase_use(&lis3_dev);
+	lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
+	lis3lv02d_decrease_use(&lis3_dev);
 	return sprintf(buf, "(%d,%d,%d)\n", x, y, z);
 }
 
 static ssize_t lis3lv02d_calibrate_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
-	return sprintf(buf, "(%d,%d,%d)\n", adev.xcalib, adev.ycalib, adev.zcalib);
+	return sprintf(buf, "(%d,%d,%d)\n", lis3_dev.xcalib, lis3_dev.ycalib, lis3_dev.zcalib);
 }
 
 static ssize_t lis3lv02d_calibrate_store(struct device *dev,
 				struct device_attribute *attr,
 				const char *buf, size_t count)
 {
-	lis3lv02d_increase_use(&adev);
+	lis3lv02d_increase_use(&lis3_dev);
 	lis3lv02d_calibrate_joystick();
-	lis3lv02d_decrease_use(&adev);
+	lis3lv02d_decrease_use(&lis3_dev);
 	return count;
 }
 
@@ -434,9 +420,9 @@
 	u8 ctrl;
 	int val;
 
-	lis3lv02d_increase_use(&adev);
-	adev.read(adev.device->handle, CTRL_REG1, &ctrl);
-	lis3lv02d_decrease_use(&adev);
+	lis3lv02d_increase_use(&lis3_dev);
+	lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl);
+	lis3lv02d_decrease_use(&lis3_dev);
 	val = (ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4;
 	return sprintf(buf, "%d\n", lis3lv02dl_df_val[val]);
 }
@@ -458,23 +444,73 @@
 };
 
 
-static int lis3lv02d_add_fs(struct acpi_device *device)
+static int lis3lv02d_add_fs(struct lis3lv02d *lis3)
 {
-	adev.pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
-	if (IS_ERR(adev.pdev))
-		return PTR_ERR(adev.pdev);
+	lis3_dev.pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
+	if (IS_ERR(lis3_dev.pdev))
+		return PTR_ERR(lis3_dev.pdev);
 
-	return sysfs_create_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group);
+	return sysfs_create_group(&lis3_dev.pdev->dev.kobj, &lis3lv02d_attribute_group);
 }
 
 int lis3lv02d_remove_fs(void)
 {
-	sysfs_remove_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group);
-	platform_device_unregister(adev.pdev);
+	sysfs_remove_group(&lis3_dev.pdev->dev.kobj, &lis3lv02d_attribute_group);
+	platform_device_unregister(lis3_dev.pdev);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
 
+/*
+ * Initialise the accelerometer and the various subsystems.
+ * Should be rather independant of the bus system.
+ */
+int lis3lv02d_init_device(struct lis3lv02d *dev)
+{
+	dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I);
+
+	switch (dev->whoami) {
+	case LIS_DOUBLE_ID:
+		printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n");
+		dev->read_data = lis3lv02d_read_16;
+		dev->mdps_max_val = 2048;
+		break;
+	case LIS_SINGLE_ID:
+		printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n");
+		dev->read_data = lis3lv02d_read_8;
+		dev->mdps_max_val = 128;
+		break;
+	default:
+		printk(KERN_ERR DRIVER_NAME
+			": unknown sensor type 0x%X\n", lis3_dev.whoami);
+		return -EINVAL;
+	}
+
+	mutex_init(&dev->lock);
+	lis3lv02d_add_fs(dev);
+	lis3lv02d_increase_use(dev);
+
+	if (lis3lv02d_joystick_enable())
+		printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
+
+	printk("lis3_init_device: irq %d\n", dev->irq);
+
+	/* bail if we did not get an IRQ from the bus layer */
+	if (!dev->irq) {
+		printk(KERN_ERR DRIVER_NAME
+			": No IRQ. Disabling /dev/freefall\n");
+		goto out;
+	}
+
+	printk("lis3: registering device\n");
+	if (misc_register(&lis3lv02d_misc_device))
+		printk(KERN_ERR DRIVER_NAME ": misc_register failed\n");
+out:
+	lis3lv02d_decrease_use(dev);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(lis3lv02d_init_device);
+
 MODULE_DESCRIPTION("ST LIS3LV02Dx three-axis digital accelerometer driver");
 MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek");
 MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 75972bf..745ec96 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -159,14 +159,14 @@
 	s8	z;
 };
 
-struct acpi_lis3lv02d {
-	struct acpi_device	*device;   /* The ACPI device */
-	acpi_status (*init) (acpi_handle handle);
-	acpi_status (*write) (acpi_handle handle, int reg, u8 val);
-	acpi_status (*read) (acpi_handle handle, int reg, u8 *ret);
+struct lis3lv02d {
+	void			*bus_priv; /* used by the bus layer only */
+	int (*init) (struct lis3lv02d *lis3);
+	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
+	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
 
 	u8			whoami;    /* 3Ah: 2-byte registries, 3Bh: 1-byte registries */
-	s16 (*read_data) (acpi_handle handle, int reg);
+	s16 (*read_data) (struct lis3lv02d *lis3, int reg);
 	int			mdps_max_val;
 
 	struct input_dev	*idev;     /* input device */
@@ -187,11 +187,11 @@
 	unsigned long		misc_opened; /* bit0: whether the device is open */
 };
 
-int lis3lv02d_init_device(struct acpi_lis3lv02d *dev);
+int lis3lv02d_init_device(struct lis3lv02d *lis3);
 int lis3lv02d_joystick_enable(void);
 void lis3lv02d_joystick_disable(void);
-void lis3lv02d_poweroff(acpi_handle handle);
-void lis3lv02d_poweron(acpi_handle handle);
+void lis3lv02d_poweroff(struct lis3lv02d *lis3);
+void lis3lv02d_poweron(struct lis3lv02d *lis3);
 int lis3lv02d_remove_fs(void);
 
-extern struct acpi_lis3lv02d adev;
+extern struct lis3lv02d lis3_dev;
diff --git a/drivers/hwmon/lis3lv02d_spi.c b/drivers/hwmon/lis3lv02d_spi.c
new file mode 100644
index 0000000..07ae74b
--- /dev/null
+++ b/drivers/hwmon/lis3lv02d_spi.c
@@ -0,0 +1,114 @@
+/*
+ * lis3lv02d_spi - SPI glue layer for lis3lv02d
+ *
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/spi/spi.h>
+
+#include "lis3lv02d.h"
+
+#define DRV_NAME 	"lis3lv02d_spi"
+#define LIS3_SPI_READ	0x80
+
+static int lis3_spi_read(struct lis3lv02d *lis3, int reg, u8 *v)
+{
+	struct spi_device *spi = lis3->bus_priv;
+	int ret = spi_w8r8(spi, reg | LIS3_SPI_READ);
+	if (ret < 0)
+		return -EINVAL;
+
+	*v = (u8) ret;
+	return 0;
+}
+
+static int lis3_spi_write(struct lis3lv02d *lis3, int reg, u8 val)
+{
+	u8 tmp[2] = { reg, val };
+	struct spi_device *spi = lis3->bus_priv;
+	return spi_write(spi, tmp, sizeof(tmp));
+}
+
+static int lis3_spi_init(struct lis3lv02d *lis3)
+{
+	u8 reg;
+	int ret;
+
+	/* power up the device */
+	ret = lis3->read(lis3, CTRL_REG1, &reg);
+	if (ret < 0)
+		return ret;
+
+	reg |= CTRL1_PD0;
+	return lis3->write(lis3, CTRL_REG1, reg);
+}
+
+static struct axis_conversion lis3lv02d_axis_normal = { 1, 2, 3 };
+
+static int __devinit lis302dl_spi_probe(struct spi_device *spi)
+{
+	int ret;
+
+	spi->bits_per_word = 8;
+	spi->mode = SPI_MODE_0;
+	ret = spi_setup(spi);
+	if (ret < 0)
+		return ret;
+
+	lis3_dev.bus_priv = spi;
+	lis3_dev.init = lis3_spi_init;
+	lis3_dev.read = lis3_spi_read;
+	lis3_dev.write = lis3_spi_write;
+	lis3_dev.irq = spi->irq;
+	lis3_dev.ac = lis3lv02d_axis_normal;
+	spi_set_drvdata(spi, &lis3_dev);
+
+	ret = lis3lv02d_init_device(&lis3_dev);
+	return ret;
+}
+
+static int __devexit lis302dl_spi_remove(struct spi_device *spi)
+{
+	struct lis3lv02d *lis3 = spi_get_drvdata(spi);
+	lis3lv02d_joystick_disable();
+	lis3lv02d_poweroff(lis3);
+	return 0;
+}
+
+static struct spi_driver lis302dl_spi_driver = {
+	.driver	 = {
+		.name   = DRV_NAME,
+		.owner  = THIS_MODULE,
+	},
+	.probe	= lis302dl_spi_probe,
+	.remove	= __devexit_p(lis302dl_spi_remove),
+};
+
+static int __init lis302dl_init(void)
+{
+	return spi_register_driver(&lis302dl_spi_driver);
+}
+
+static void __exit lis302dl_exit(void)
+{
+	spi_unregister_driver(&lis302dl_spi_driver);
+}
+
+module_init(lis302dl_init);
+module_exit(lis302dl_exit);
+
+MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
+MODULE_DESCRIPTION("lis3lv02d SPI glue layer");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c
new file mode 100644
index 0000000..091d95f
--- /dev/null
+++ b/drivers/hwmon/lm95241.c
@@ -0,0 +1,527 @@
+/*
+ * lm95241.c - Part of lm_sensors, Linux kernel modules for hardware
+ *             monitoring
+ * Copyright (C) 2008 Davide Rizzo <elpa-rizzo@gmail.com>
+ *
+ * Based on the max1619 driver. The LM95241 is a sensor chip made by National
+ *   Semiconductors.
+ * It reports up to three temperatures (its own plus up to
+ * two external ones). Complete datasheet can be
+ * obtained from National's website at:
+ *   http://www.national.com/ds.cgi/LM/LM95241.pdf
+ *
+ * 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/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/sysfs.h>
+
+static const unsigned short normal_i2c[] = {
+	0x19, 0x2a, 0x2b, I2C_CLIENT_END};
+
+/* Insmod parameters */
+I2C_CLIENT_INSMOD_1(lm95241);
+
+/* LM95241 registers */
+#define LM95241_REG_R_MAN_ID		0xFE
+#define LM95241_REG_R_CHIP_ID		0xFF
+#define LM95241_REG_R_STATUS		0x02
+#define LM95241_REG_RW_CONFIG		0x03
+#define LM95241_REG_RW_REM_FILTER	0x06
+#define LM95241_REG_RW_TRUTHERM		0x07
+#define LM95241_REG_W_ONE_SHOT  	0x0F
+#define LM95241_REG_R_LOCAL_TEMPH	0x10
+#define LM95241_REG_R_REMOTE1_TEMPH	0x11
+#define LM95241_REG_R_REMOTE2_TEMPH	0x12
+#define LM95241_REG_R_LOCAL_TEMPL	0x20
+#define LM95241_REG_R_REMOTE1_TEMPL	0x21
+#define LM95241_REG_R_REMOTE2_TEMPL	0x22
+#define LM95241_REG_RW_REMOTE_MODEL	0x30
+
+/* LM95241 specific bitfields */
+#define CFG_STOP 0x40
+#define CFG_CR0076 0x00
+#define CFG_CR0182 0x10
+#define CFG_CR1000 0x20
+#define CFG_CR2700 0x30
+#define R1MS_SHIFT 0
+#define R2MS_SHIFT 2
+#define R1MS_MASK (0x01 << (R1MS_SHIFT))
+#define R2MS_MASK (0x01 << (R2MS_SHIFT))
+#define R1DF_SHIFT 1
+#define R2DF_SHIFT 2
+#define R1DF_MASK (0x01 << (R1DF_SHIFT))
+#define R2DF_MASK (0x01 << (R2DF_SHIFT))
+#define R1FE_MASK 0x01
+#define R2FE_MASK 0x05
+#define TT1_SHIFT 0
+#define TT2_SHIFT 4
+#define TT_OFF 0
+#define TT_ON 1
+#define TT_MASK 7
+#define MANUFACTURER_ID 0x01
+#define DEFAULT_REVISION 0xA4
+
+/* Conversions and various macros */
+#define TEMP_FROM_REG(val_h, val_l) (((val_h) & 0x80 ? (val_h) - 0x100 : \
+    (val_h)) * 1000 + (val_l) * 1000 / 256)
+
+/* Functions declaration */
+static int lm95241_attach_adapter(struct i2c_adapter *adapter);
+static int lm95241_detect(struct i2c_adapter *adapter, int address,
+			  int kind);
+static void lm95241_init_client(struct i2c_client *client);
+static int lm95241_detach_client(struct i2c_client *client);
+static struct lm95241_data *lm95241_update_device(struct device *dev);
+
+/* Driver data (common to all clients) */
+static struct i2c_driver lm95241_driver = {
+	.driver = {
+		.name   = "lm95241",
+	},
+	.attach_adapter = lm95241_attach_adapter,
+	.detach_client  = lm95241_detach_client,
+};
+
+/* Client data (each client gets its own) */
+struct lm95241_data {
+	struct i2c_client client;
+	struct device *hwmon_dev;
+	struct mutex update_lock;
+	unsigned long last_updated, rate; /* in jiffies */
+	char valid; /* zero until following fields are valid */
+	/* registers values */
+	u8 local_h, local_l; /* local */
+	u8 remote1_h, remote1_l; /* remote1 */
+	u8 remote2_h, remote2_l; /* remote2 */
+	u8 config, model, trutherm;
+};
+
+/* Sysfs stuff */
+#define show_temp(value) \
+static ssize_t show_##value(struct device *dev, \
+    struct device_attribute *attr, char *buf) \
+{ \
+	struct lm95241_data *data = lm95241_update_device(dev); \
+	snprintf(buf, PAGE_SIZE - 1, "%d\n", \
+		TEMP_FROM_REG(data->value##_h, data->value##_l)); \
+	return strlen(buf); \
+}
+show_temp(local);
+show_temp(remote1);
+show_temp(remote2);
+
+static ssize_t show_rate(struct device *dev, struct device_attribute *attr,
+			 char *buf)
+{
+	struct lm95241_data *data = lm95241_update_device(dev);
+
+	snprintf(buf, PAGE_SIZE - 1, "%lu\n", 1000 * data->rate / HZ);
+	return strlen(buf);
+}
+
+static ssize_t set_rate(struct device *dev, struct device_attribute *attr,
+			const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm95241_data *data = i2c_get_clientdata(client);
+
+	strict_strtol(buf, 10, &data->rate);
+	data->rate = data->rate * HZ / 1000;
+
+	return count;
+}
+
+#define show_type(flag) \
+static ssize_t show_type##flag(struct device *dev, \
+				   struct device_attribute *attr, char *buf) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+	snprintf(buf, PAGE_SIZE - 1, \
+		data->model & R##flag##MS_MASK ? "1\n" : "2\n"); \
+	return strlen(buf); \
+}
+show_type(1);
+show_type(2);
+
+#define show_min(flag) \
+static ssize_t show_min##flag(struct device *dev, \
+    struct device_attribute *attr, char *buf) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+	snprintf(buf, PAGE_SIZE - 1, \
+		data->config & R##flag##DF_MASK ?	\
+		"-127000\n" : "0\n"); \
+	return strlen(buf); \
+}
+show_min(1);
+show_min(2);
+
+#define show_max(flag) \
+static ssize_t show_max##flag(struct device *dev, \
+    struct device_attribute *attr, char *buf) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+	snprintf(buf, PAGE_SIZE - 1, \
+		data->config & R##flag##DF_MASK ? \
+		"127000\n" : "255000\n"); \
+	return strlen(buf); \
+}
+show_max(1);
+show_max(2);
+
+#define set_type(flag) \
+static ssize_t set_type##flag(struct device *dev, \
+				  struct device_attribute *attr, \
+				  const char *buf, size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+	long val; \
+	strict_strtol(buf, 10, &val); \
+\
+	if ((val == 1) || (val == 2)) { \
+\
+		mutex_lock(&data->update_lock); \
+\
+		data->trutherm &= ~(TT_MASK << TT##flag##_SHIFT); \
+		if (val == 1) { \
+			data->model |= R##flag##MS_MASK; \
+			data->trutherm |= (TT_ON << TT##flag##_SHIFT); \
+		} \
+		else { \
+			data->model &= ~R##flag##MS_MASK; \
+			data->trutherm |= (TT_OFF << TT##flag##_SHIFT); \
+		} \
+\
+		data->valid = 0; \
+\
+		i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL, \
+					  data->model); \
+		i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM, \
+					  data->trutherm); \
+\
+		mutex_unlock(&data->update_lock); \
+\
+	} \
+	return count; \
+}
+set_type(1);
+set_type(2);
+
+#define set_min(flag) \
+static ssize_t set_min##flag(struct device *dev, \
+	struct device_attribute *devattr, const char *buf, size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+	long val; \
+	strict_strtol(buf, 10, &val); \
+\
+	mutex_lock(&data->update_lock); \
+\
+	if (val < 0) \
+		data->config |= R##flag##DF_MASK; \
+	else \
+		data->config &= ~R##flag##DF_MASK; \
+\
+	data->valid = 0; \
+\
+	i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, \
+		data->config); \
+\
+	mutex_unlock(&data->update_lock); \
+\
+	return count; \
+}
+set_min(1);
+set_min(2);
+
+#define set_max(flag) \
+static ssize_t set_max##flag(struct device *dev, \
+	struct device_attribute *devattr, const char *buf, size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+	long val; \
+	strict_strtol(buf, 10, &val); \
+\
+	mutex_lock(&data->update_lock); \
+\
+	if (val <= 127000) \
+		data->config |= R##flag##DF_MASK; \
+	else \
+		data->config &= ~R##flag##DF_MASK; \
+\
+	data->valid = 0; \
+\
+	i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, \
+		data->config); \
+\
+	mutex_unlock(&data->update_lock); \
+\
+	return count; \
+}
+set_max(1);
+set_max(2);
+
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_local, NULL);
+static DEVICE_ATTR(temp2_input, S_IRUGO, show_remote1, NULL);
+static DEVICE_ATTR(temp3_input, S_IRUGO, show_remote2, NULL);
+static DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type1, set_type1);
+static DEVICE_ATTR(temp3_type, S_IWUSR | S_IRUGO, show_type2, set_type2);
+static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_min1, set_min1);
+static DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min2, set_min2);
+static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_max1, set_max1);
+static DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max2, set_max2);
+static DEVICE_ATTR(rate, S_IWUSR | S_IRUGO, show_rate, set_rate);
+
+static struct attribute *lm95241_attributes[] = {
+	&dev_attr_temp1_input.attr,
+	&dev_attr_temp2_input.attr,
+	&dev_attr_temp3_input.attr,
+	&dev_attr_temp2_type.attr,
+	&dev_attr_temp3_type.attr,
+	&dev_attr_temp2_min.attr,
+	&dev_attr_temp3_min.attr,
+	&dev_attr_temp2_max.attr,
+	&dev_attr_temp3_max.attr,
+	&dev_attr_rate.attr,
+	NULL
+};
+
+static const struct attribute_group lm95241_group = {
+	.attrs = lm95241_attributes,
+};
+
+/* Init/exit code */
+static int lm95241_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_probe(adapter, &addr_data, lm95241_detect);
+}
+
+/*
+ * The following function does more than just detection. If detection
+ * succeeds, it also registers the new chip.
+ */
+static int lm95241_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	struct lm95241_data *data;
+	int err = 0;
+	const char *name = "";
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		goto exit;
+
+	data = kzalloc(sizeof(struct lm95241_data), GFP_KERNEL);
+	if (!data) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	/* The common I2C client data is placed right before the
+	   LM95241-specific data. */
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &lm95241_driver;
+	new_client->flags = 0;
+
+	/*
+	 * Now we do the remaining detection. A negative kind means that
+	 * the driver was loaded with no force parameter (default), so we
+	 * must both detect and identify the chip. A zero kind means that
+	 * the driver was loaded with the force parameter, the detection
+	 * step shall be skipped. A positive kind means that the driver
+	 * was loaded with the force parameter and a given kind of chip is
+	 * requested, so both the detection and the identification steps
+	 * are skipped.
+	 */
+	if (kind < 0) {	/* detection */
+		if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
+		     != MANUFACTURER_ID)
+		|| (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
+		    < DEFAULT_REVISION)) {
+			dev_dbg(&adapter->dev,
+				"LM95241 detection failed at 0x%02x.\n",
+				address);
+			goto exit_free;
+		}
+	}
+
+	if (kind <= 0) { /* identification */
+		if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
+		     == MANUFACTURER_ID)
+		&& (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
+		    >= DEFAULT_REVISION)) {
+
+			kind = lm95241;
+
+			if (kind <= 0) { /* identification failed */
+				dev_info(&adapter->dev, "Unsupported chip\n");
+				goto exit_free;
+			}
+		}
+	}
+
+	if (kind == lm95241)
+		name = "lm95241";
+
+	/* We can fill in the remaining client fields */
+	strlcpy(new_client->name, name, I2C_NAME_SIZE);
+	data->valid = 0;
+	mutex_init(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	err = i2c_attach_client(new_client);
+	if (err)
+		goto exit_free;
+
+	/* Initialize the LM95241 chip */
+	lm95241_init_client(new_client);
+
+	/* Register sysfs hooks */
+	err = sysfs_create_group(&new_client->dev.kobj, &lm95241_group);
+	if (err)
+		goto exit_detach;
+
+	data->hwmon_dev = hwmon_device_register(&new_client->dev);
+	if (IS_ERR(data->hwmon_dev)) {
+		err = PTR_ERR(data->hwmon_dev);
+		goto exit_remove_files;
+	}
+
+	return 0;
+
+exit_remove_files:
+	sysfs_remove_group(&new_client->dev.kobj, &lm95241_group);
+exit_detach:
+	i2c_detach_client(new_client);
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static void lm95241_init_client(struct i2c_client *client)
+{
+	struct lm95241_data *data = i2c_get_clientdata(client);
+
+	data->rate = HZ;    /* 1 sec default */
+	data->valid = 0;
+	data->config = CFG_CR0076;
+	data->model = 0;
+	data->trutherm = (TT_OFF << TT1_SHIFT) | (TT_OFF << TT2_SHIFT);
+
+	i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG,
+				  data->config);
+	i2c_smbus_write_byte_data(client, LM95241_REG_RW_REM_FILTER,
+				  R1FE_MASK | R2FE_MASK);
+	i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM,
+				  data->trutherm);
+	i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL,
+				  data->model);
+}
+
+static int lm95241_detach_client(struct i2c_client *client)
+{
+	struct lm95241_data *data = i2c_get_clientdata(client);
+	int err;
+
+	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&client->dev.kobj, &lm95241_group);
+
+	err = i2c_detach_client(client);
+	if (err)
+		return err;
+
+	kfree(data);
+	return 0;
+}
+
+static struct lm95241_data *lm95241_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm95241_data *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + data->rate) ||
+	    !data->valid) {
+		dev_dbg(&client->dev, "Updating lm95241 data.\n");
+		data->local_h =
+			i2c_smbus_read_byte_data(client,
+						 LM95241_REG_R_LOCAL_TEMPH);
+		data->local_l =
+			i2c_smbus_read_byte_data(client,
+						 LM95241_REG_R_LOCAL_TEMPL);
+		data->remote1_h =
+			i2c_smbus_read_byte_data(client,
+						 LM95241_REG_R_REMOTE1_TEMPH);
+		data->remote1_l =
+			i2c_smbus_read_byte_data(client,
+						 LM95241_REG_R_REMOTE1_TEMPL);
+		data->remote2_h =
+			i2c_smbus_read_byte_data(client,
+						 LM95241_REG_R_REMOTE2_TEMPH);
+		data->remote2_l =
+			i2c_smbus_read_byte_data(client,
+						 LM95241_REG_R_REMOTE2_TEMPL);
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
+
+static int __init sensors_lm95241_init(void)
+{
+	return i2c_add_driver(&lm95241_driver);
+}
+
+static void __exit sensors_lm95241_exit(void)
+{
+	i2c_del_driver(&lm95241_driver);
+}
+
+MODULE_AUTHOR("Davide Rizzo <elpa-rizzo@gmail.com>");
+MODULE_DESCRIPTION("LM95241 sensor driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_lm95241_init);
+module_exit(sensors_lm95241_exit);
diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c
new file mode 100644
index 0000000..9386e2a
--- /dev/null
+++ b/drivers/hwmon/ltc4215.c
@@ -0,0 +1,364 @@
+/*
+ * Driver for Linear Technology LTC4215 I2C Hot Swap Controller
+ *
+ * Copyright (C) 2009 Ira W. Snyder <iws@ovro.caltech.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * Datasheet:
+ * http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1003,C1006,C1163,P17572,D12697
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+
+static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
+
+/* Insmod parameters */
+I2C_CLIENT_INSMOD_1(ltc4215);
+
+/* Here are names of the chip's registers (a.k.a. commands) */
+enum ltc4215_cmd {
+	LTC4215_CONTROL			= 0x00, /* rw */
+	LTC4215_ALERT			= 0x01, /* rw */
+	LTC4215_STATUS			= 0x02, /* ro */
+	LTC4215_FAULT			= 0x03, /* rw */
+	LTC4215_SENSE			= 0x04, /* rw */
+	LTC4215_SOURCE			= 0x05, /* rw */
+	LTC4215_ADIN			= 0x06, /* rw */
+};
+
+struct ltc4215_data {
+	struct device *hwmon_dev;
+
+	struct mutex update_lock;
+	bool valid;
+	unsigned long last_updated; /* in jiffies */
+
+	/* Registers */
+	u8 regs[7];
+};
+
+static struct ltc4215_data *ltc4215_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct ltc4215_data *data = i2c_get_clientdata(client);
+	s32 val;
+	int i;
+
+	mutex_lock(&data->update_lock);
+
+	/* The chip's A/D updates 10 times per second */
+	if (time_after(jiffies, data->last_updated + HZ / 10) || !data->valid) {
+
+		dev_dbg(&client->dev, "Starting ltc4215 update\n");
+
+		/* Read all registers */
+		for (i = 0; i < ARRAY_SIZE(data->regs); i++) {
+			val = i2c_smbus_read_byte_data(client, i);
+			if (unlikely(val < 0))
+				data->regs[i] = 0;
+			else
+				data->regs[i] = val;
+		}
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
+
+/* Return the voltage from the given register in millivolts */
+static int ltc4215_get_voltage(struct device *dev, u8 reg)
+{
+	struct ltc4215_data *data = ltc4215_update_device(dev);
+	const u8 regval = data->regs[reg];
+	u32 voltage = 0;
+
+	switch (reg) {
+	case LTC4215_SENSE:
+		/* 151 uV per increment */
+		voltage = regval * 151 / 1000;
+		break;
+	case LTC4215_SOURCE:
+		/* 60.5 mV per increment */
+		voltage = regval * 605 / 10;
+		break;
+	case LTC4215_ADIN:
+		/* The ADIN input is divided by 12.5, and has 4.82 mV
+		 * per increment, so we have the additional multiply */
+		voltage = regval * 482 * 125 / 1000;
+		break;
+	default:
+		/* If we get here, the developer messed up */
+		WARN_ON_ONCE(1);
+		break;
+	}
+
+	return voltage;
+}
+
+/* Return the current from the sense resistor in mA */
+static unsigned int ltc4215_get_current(struct device *dev)
+{
+	struct ltc4215_data *data = ltc4215_update_device(dev);
+
+	/* The strange looking conversions that follow are fixed-point
+	 * math, since we cannot do floating point in the kernel.
+	 *
+	 * Step 1: convert sense register to microVolts
+	 * Step 2: convert voltage to milliAmperes
+	 *
+	 * If you play around with the V=IR equation, you come up with
+	 * the following: X uV / Y mOhm == Z mA
+	 *
+	 * With the resistors that are fractions of a milliOhm, we multiply
+	 * the voltage and resistance by 10, to shift the decimal point.
+	 * Now we can use the normal division operator again.
+	 */
+
+	/* Calculate voltage in microVolts (151 uV per increment) */
+	const unsigned int voltage = data->regs[LTC4215_SENSE] * 151;
+
+	/* Calculate current in milliAmperes (4 milliOhm sense resistor) */
+	const unsigned int curr = voltage / 4;
+
+	return curr;
+}
+
+static ssize_t ltc4215_show_voltage(struct device *dev,
+				    struct device_attribute *da,
+				    char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+	const int voltage = ltc4215_get_voltage(dev, attr->index);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", voltage);
+}
+
+static ssize_t ltc4215_show_current(struct device *dev,
+				    struct device_attribute *da,
+				    char *buf)
+{
+	const unsigned int curr = ltc4215_get_current(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%u\n", curr);
+}
+
+static ssize_t ltc4215_show_power(struct device *dev,
+				  struct device_attribute *da,
+				  char *buf)
+{
+	const unsigned int curr = ltc4215_get_current(dev);
+	const int output_voltage = ltc4215_get_voltage(dev, LTC4215_ADIN);
+
+	/* current in mA * voltage in mV == power in uW */
+	const unsigned int power = abs(output_voltage * curr);
+
+	return snprintf(buf, PAGE_SIZE, "%u\n", power);
+}
+
+static ssize_t ltc4215_show_alarm(struct device *dev,
+					  struct device_attribute *da,
+					  char *buf)
+{
+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(da);
+	struct ltc4215_data *data = ltc4215_update_device(dev);
+	const u8 reg = data->regs[attr->index];
+	const u32 mask = attr->nr;
+
+	return snprintf(buf, PAGE_SIZE, "%u\n", (reg & mask) ? 1 : 0);
+}
+
+/* These macros are used below in constructing device attribute objects
+ * for use with sysfs_create_group() to make a sysfs device file
+ * for each register.
+ */
+
+#define LTC4215_VOLTAGE(name, ltc4215_cmd_idx) \
+	static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
+	ltc4215_show_voltage, NULL, ltc4215_cmd_idx)
+
+#define LTC4215_CURRENT(name) \
+	static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
+	ltc4215_show_current, NULL, 0);
+
+#define LTC4215_POWER(name) \
+	static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
+	ltc4215_show_power, NULL, 0);
+
+#define LTC4215_ALARM(name, mask, reg) \
+	static SENSOR_DEVICE_ATTR_2(name, S_IRUGO, \
+	ltc4215_show_alarm, NULL, (mask), reg)
+
+/* Construct a sensor_device_attribute structure for each register */
+
+/* Current */
+LTC4215_CURRENT(curr1_input);
+LTC4215_ALARM(curr1_max_alarm,	(1 << 2),	LTC4215_STATUS);
+
+/* Power (virtual) */
+LTC4215_POWER(power1_input);
+LTC4215_ALARM(power1_alarm,	(1 << 3),	LTC4215_STATUS);
+
+/* Input Voltage */
+LTC4215_VOLTAGE(in1_input,			LTC4215_ADIN);
+LTC4215_ALARM(in1_max_alarm,	(1 << 0),	LTC4215_STATUS);
+LTC4215_ALARM(in1_min_alarm,	(1 << 1),	LTC4215_STATUS);
+
+/* Output Voltage */
+LTC4215_VOLTAGE(in2_input,			LTC4215_SOURCE);
+
+/* Finally, construct an array of pointers to members of the above objects,
+ * as required for sysfs_create_group()
+ */
+static struct attribute *ltc4215_attributes[] = {
+	&sensor_dev_attr_curr1_input.dev_attr.attr,
+	&sensor_dev_attr_curr1_max_alarm.dev_attr.attr,
+
+	&sensor_dev_attr_power1_input.dev_attr.attr,
+	&sensor_dev_attr_power1_alarm.dev_attr.attr,
+
+	&sensor_dev_attr_in1_input.dev_attr.attr,
+	&sensor_dev_attr_in1_max_alarm.dev_attr.attr,
+	&sensor_dev_attr_in1_min_alarm.dev_attr.attr,
+
+	&sensor_dev_attr_in2_input.dev_attr.attr,
+
+	NULL,
+};
+
+static const struct attribute_group ltc4215_group = {
+	.attrs = ltc4215_attributes,
+};
+
+static int ltc4215_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct ltc4215_data *data;
+	int ret;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data) {
+		ret = -ENOMEM;
+		goto out_kzalloc;
+	}
+
+	i2c_set_clientdata(client, data);
+	mutex_init(&data->update_lock);
+
+	/* Initialize the LTC4215 chip */
+	/* TODO */
+
+	/* Register sysfs hooks */
+	ret = sysfs_create_group(&client->dev.kobj, &ltc4215_group);
+	if (ret)
+		goto out_sysfs_create_group;
+
+	data->hwmon_dev = hwmon_device_register(&client->dev);
+	if (IS_ERR(data->hwmon_dev)) {
+		ret = PTR_ERR(data->hwmon_dev);
+		goto out_hwmon_device_register;
+	}
+
+	return 0;
+
+out_hwmon_device_register:
+	sysfs_remove_group(&client->dev.kobj, &ltc4215_group);
+out_sysfs_create_group:
+	kfree(data);
+out_kzalloc:
+	return ret;
+}
+
+static int ltc4215_remove(struct i2c_client *client)
+{
+	struct ltc4215_data *data = i2c_get_clientdata(client);
+
+	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&client->dev.kobj, &ltc4215_group);
+
+	kfree(data);
+
+	return 0;
+}
+
+static int ltc4215_detect(struct i2c_client *client,
+			  int kind,
+			  struct i2c_board_info *info)
+{
+	struct i2c_adapter *adapter = client->adapter;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	if (kind < 0) {		/* probed detection - check the chip type */
+		s32 v;		/* 8 bits from the chip, or -ERRNO */
+
+		/*
+		 * Register 0x01 bit b7 is reserved, expect 0
+		 * Register 0x03 bit b6 and b7 are reserved, expect 0
+		 */
+		v = i2c_smbus_read_byte_data(client, LTC4215_ALERT);
+		if (v < 0 || (v & (1 << 7)) != 0)
+			return -ENODEV;
+
+		v = i2c_smbus_read_byte_data(client, LTC4215_FAULT);
+		if (v < 0 || (v & ((1 << 6) | (1 << 7))) != 0)
+				return -ENODEV;
+	}
+
+	strlcpy(info->type, "ltc4215", I2C_NAME_SIZE);
+	dev_info(&adapter->dev, "ltc4215 %s at address 0x%02x\n",
+			kind < 0 ? "probed" : "forced",
+			client->addr);
+
+	return 0;
+}
+
+static const struct i2c_device_id ltc4215_id[] = {
+	{ "ltc4215", ltc4215 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ltc4215_id);
+
+/* This is the driver that will be inserted */
+static struct i2c_driver ltc4215_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "ltc4215",
+	},
+	.probe		= ltc4215_probe,
+	.remove		= ltc4215_remove,
+	.id_table	= ltc4215_id,
+	.detect		= ltc4215_detect,
+	.address_data	= &addr_data,
+};
+
+static int __init ltc4215_init(void)
+{
+	return i2c_add_driver(&ltc4215_driver);
+}
+
+static void __exit ltc4215_exit(void)
+{
+	i2c_del_driver(&ltc4215_driver);
+}
+
+MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>");
+MODULE_DESCRIPTION("LTC4215 driver");
+MODULE_LICENSE("GPL");
+
+module_init(ltc4215_init);
+module_exit(ltc4215_exit);
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 3e468d2..2d83524 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -1331,12 +1331,6 @@
 #endif
 }
 
-static int capinc_tty_read_proc(char *page, char **start, off_t off,
-				int count, int *eof, void *data)
-{
-	return 0;
-}
-
 static struct tty_driver *capinc_tty_driver;
 
 static const struct tty_operations capinc_ops = {
@@ -1358,7 +1352,6 @@
 	.flush_buffer = capinc_tty_flush_buffer,
 	.set_ldisc = capinc_tty_set_ldisc,
 	.send_xchar = capinc_tty_send_xchar,
-	.read_proc = capinc_tty_read_proc,
 };
 
 static int capinc_tty_init(void)
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 1c48408..5f3bff4 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -223,6 +223,16 @@
 	This driver adds support for rfkill and backlight control to Dell
 	laptops.
 
+config ISL29003
+	tristate "Intersil ISL29003 ambient light sensor"
+	depends on I2C && SYSFS
+	help
+	  If you say yes here you get support for the Intersil ISL29003
+	  ambient light sensor.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called isl29003.
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index bc11998..7871f05 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -18,5 +18,6 @@
 obj-$(CONFIG_SGI_XP)		+= sgi-xp/
 obj-$(CONFIG_SGI_GRU)		+= sgi-gru/
 obj-$(CONFIG_HP_ILO)		+= hpilo.o
+obj-$(CONFIG_ISL29003)		+= isl29003.o
 obj-$(CONFIG_C2PORT)		+= c2port/
 obj-y				+= eeprom/
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c
index cf99185..880ccf3 100644
--- a/drivers/misc/hpilo.c
+++ b/drivers/misc/hpilo.c
@@ -209,7 +209,7 @@
 	/* give iLO some time to process stop request */
 	for (retries = MAX_WAIT; retries > 0; retries--) {
 		doorbell_set(driver_ccb);
-		udelay(1);
+		udelay(WAIT_TIME);
 		if (!(ioread32(&device_ccb->send_ctrl) & (1 << CTRL_BITPOS_A))
 		    &&
 		    !(ioread32(&device_ccb->recv_ctrl) & (1 << CTRL_BITPOS_A)))
@@ -312,7 +312,7 @@
 	for (i = MAX_WAIT; i > 0; i--) {
 		if (ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, NULL, NULL))
 			break;
-		udelay(1);
+		udelay(WAIT_TIME);
 	}
 
 	if (i) {
@@ -759,7 +759,7 @@
 	class_destroy(ilo_class);
 }
 
-MODULE_VERSION("1.0");
+MODULE_VERSION("1.1");
 MODULE_ALIAS(ILO_NAME);
 MODULE_DESCRIPTION(ILO_NAME);
 MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>");
diff --git a/drivers/misc/hpilo.h b/drivers/misc/hpilo.h
index b64a20e..03a14c8 100644
--- a/drivers/misc/hpilo.h
+++ b/drivers/misc/hpilo.h
@@ -19,8 +19,12 @@
 #define MAX_ILO_DEV	1
 /* max number of files */
 #define MAX_OPEN	(MAX_CCB * MAX_ILO_DEV)
+/* total wait time in usec */
+#define MAX_WAIT_TIME	10000
+/* per spin wait time in usec */
+#define WAIT_TIME	10
 /* spin counter for open/close delay */
-#define MAX_WAIT	10000
+#define MAX_WAIT	(MAX_WAIT_TIME / WAIT_TIME)
 
 /*
  * Per device, used to track global memory allocations.
diff --git a/drivers/misc/isl29003.c b/drivers/misc/isl29003.c
new file mode 100644
index 0000000..2e2a592
--- /dev/null
+++ b/drivers/misc/isl29003.c
@@ -0,0 +1,470 @@
+/*
+ *  isl29003.c - Linux kernel module for
+ * 	Intersil ISL29003 ambient light sensor
+ *
+ *  See file:Documentation/misc-devices/isl29003
+ *
+ *  Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ *  Based on code written by
+ *  	Rodolfo Giometti <giometti@linux.it>
+ *  	Eurotech S.p.A. <info@eurotech.it>
+ *
+ *  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/slab.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+
+#define ISL29003_DRV_NAME	"isl29003"
+#define DRIVER_VERSION		"1.0"
+
+#define ISL29003_REG_COMMAND		0x00
+#define ISL29003_ADC_ENABLED		(1 << 7)
+#define ISL29003_ADC_PD			(1 << 6)
+#define ISL29003_TIMING_INT		(1 << 5)
+#define ISL29003_MODE_SHIFT		(2)
+#define ISL29003_MODE_MASK		(0x3 << ISL29003_MODE_SHIFT)
+#define ISL29003_RES_SHIFT		(0)
+#define ISL29003_RES_MASK		(0x3 << ISL29003_RES_SHIFT)
+
+#define ISL29003_REG_CONTROL		0x01
+#define ISL29003_INT_FLG		(1 << 5)
+#define ISL29003_RANGE_SHIFT		(2)
+#define ISL29003_RANGE_MASK		(0x3 << ISL29003_RANGE_SHIFT)
+#define ISL29003_INT_PERSISTS_SHIFT	(0)
+#define ISL29003_INT_PERSISTS_MASK	(0xf << ISL29003_INT_PERSISTS_SHIFT)
+
+#define ISL29003_REG_IRQ_THRESH_HI	0x02
+#define ISL29003_REG_IRQ_THRESH_LO	0x03
+#define ISL29003_REG_LSB_SENSOR		0x04
+#define ISL29003_REG_MSB_SENSOR		0x05
+#define ISL29003_REG_LSB_TIMER		0x06
+#define ISL29003_REG_MSB_TIMER		0x07
+
+#define ISL29003_NUM_CACHABLE_REGS	4
+
+struct isl29003_data {
+	struct i2c_client *client;
+	struct mutex lock;
+	u8 reg_cache[ISL29003_NUM_CACHABLE_REGS];
+};
+
+static int gain_range[] = {
+	1000, 4000, 16000, 64000
+};
+
+/*
+ * register access helpers
+ */
+
+static int __isl29003_read_reg(struct i2c_client *client,
+			       u32 reg, u8 mask, u8 shift)
+{
+	struct isl29003_data *data = i2c_get_clientdata(client);
+	return (data->reg_cache[reg] & mask) >> shift;
+}
+
+static int __isl29003_write_reg(struct i2c_client *client,
+				u32 reg, u8 mask, u8 shift, u8 val)
+{
+	struct isl29003_data *data = i2c_get_clientdata(client);
+	int ret = 0;
+	u8 tmp;
+
+	if (reg >= ISL29003_NUM_CACHABLE_REGS)
+		return -EINVAL;
+
+	mutex_lock(&data->lock);
+
+	tmp = data->reg_cache[reg];
+	tmp &= ~mask;
+	tmp |= val << shift;
+
+	ret = i2c_smbus_write_byte_data(client, reg, tmp);
+	if (!ret)
+		data->reg_cache[reg] = tmp;
+
+	mutex_unlock(&data->lock);
+	return ret;
+}
+
+/*
+ * internally used functions
+ */
+
+/* range */
+static int isl29003_get_range(struct i2c_client *client)
+{
+	return __isl29003_read_reg(client, ISL29003_REG_CONTROL,
+		ISL29003_RANGE_MASK, ISL29003_RANGE_SHIFT);
+}
+
+static int isl29003_set_range(struct i2c_client *client, int range)
+{
+	return __isl29003_write_reg(client, ISL29003_REG_CONTROL,
+		ISL29003_RANGE_MASK, ISL29003_RANGE_SHIFT, range);
+}
+
+/* resolution */
+static int isl29003_get_resolution(struct i2c_client *client)
+{
+	return __isl29003_read_reg(client, ISL29003_REG_COMMAND,
+		ISL29003_RES_MASK, ISL29003_RES_SHIFT);
+}
+
+static int isl29003_set_resolution(struct i2c_client *client, int res)
+{
+	return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
+		ISL29003_RES_MASK, ISL29003_RES_SHIFT, res);
+}
+
+/* mode */
+static int isl29003_get_mode(struct i2c_client *client)
+{
+	return __isl29003_read_reg(client, ISL29003_REG_COMMAND,
+		ISL29003_RES_MASK, ISL29003_RES_SHIFT);
+}
+
+static int isl29003_set_mode(struct i2c_client *client, int mode)
+{
+	return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
+		ISL29003_RES_MASK, ISL29003_RES_SHIFT, mode);
+}
+
+/* power_state */
+static int isl29003_set_power_state(struct i2c_client *client, int state)
+{
+	return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
+				ISL29003_ADC_ENABLED | ISL29003_ADC_PD, 0,
+				state ? ISL29003_ADC_ENABLED : ISL29003_ADC_PD);
+}
+
+static int isl29003_get_power_state(struct i2c_client *client)
+{
+	struct isl29003_data *data = i2c_get_clientdata(client);
+	u8 cmdreg = data->reg_cache[ISL29003_REG_COMMAND];
+	return ~cmdreg & ISL29003_ADC_PD;
+}
+
+static int isl29003_get_adc_value(struct i2c_client *client)
+{
+	struct isl29003_data *data = i2c_get_clientdata(client);
+	int lsb, msb, range, bitdepth;
+
+	mutex_lock(&data->lock);
+	lsb = i2c_smbus_read_byte_data(client, ISL29003_REG_LSB_SENSOR);
+
+	if (lsb < 0) {
+		mutex_unlock(&data->lock);
+		return lsb;
+	}
+
+	msb = i2c_smbus_read_byte_data(client, ISL29003_REG_MSB_SENSOR);
+	mutex_unlock(&data->lock);
+
+	if (msb < 0)
+		return msb;
+
+	range = isl29003_get_range(client);
+	bitdepth = (4 - isl29003_get_resolution(client)) * 4;
+	return (((msb << 8) | lsb) * gain_range[range]) >> bitdepth;
+}
+
+/*
+ * sysfs layer
+ */
+
+/* range */
+static ssize_t isl29003_show_range(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	return sprintf(buf, "%i\n", isl29003_get_range(client));
+}
+
+static ssize_t isl29003_store_range(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	unsigned long val;
+	int ret;
+
+	if ((strict_strtoul(buf, 10, &val) < 0) || (val > 3))
+		return -EINVAL;
+
+	ret = isl29003_set_range(client, val);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static DEVICE_ATTR(range, S_IWUSR | S_IRUGO,
+		   isl29003_show_range, isl29003_store_range);
+
+
+/* resolution */
+static ssize_t isl29003_show_resolution(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	return sprintf(buf, "%d\n", isl29003_get_resolution(client));
+}
+
+static ssize_t isl29003_store_resolution(struct device *dev,
+					 struct device_attribute *attr,
+					 const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	unsigned long val;
+	int ret;
+
+	if ((strict_strtoul(buf, 10, &val) < 0) || (val > 3))
+		return -EINVAL;
+
+	ret = isl29003_set_resolution(client, val);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static DEVICE_ATTR(resolution, S_IWUSR | S_IRUGO,
+		   isl29003_show_resolution, isl29003_store_resolution);
+
+/* mode */
+static ssize_t isl29003_show_mode(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	return sprintf(buf, "%d\n", isl29003_get_mode(client));
+}
+
+static ssize_t isl29003_store_mode(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	unsigned long val;
+	int ret;
+
+	if ((strict_strtoul(buf, 10, &val) < 0) || (val > 2))
+		return -EINVAL;
+
+	ret = isl29003_set_mode(client, val);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO,
+		   isl29003_show_mode, isl29003_store_mode);
+
+
+/* power state */
+static ssize_t isl29003_show_power_state(struct device *dev,
+					 struct device_attribute *attr,
+					 char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	return sprintf(buf, "%d\n", isl29003_get_power_state(client));
+}
+
+static ssize_t isl29003_store_power_state(struct device *dev,
+					  struct device_attribute *attr,
+					  const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	unsigned long val;
+	int ret;
+
+	if ((strict_strtoul(buf, 10, &val) < 0) || (val > 1))
+		return -EINVAL;
+
+	ret = isl29003_set_power_state(client, val);
+	return ret ? ret : count;
+}
+
+static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
+		   isl29003_show_power_state, isl29003_store_power_state);
+
+
+/* lux */
+static ssize_t isl29003_show_lux(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+
+	/* No LUX data if not operational */
+	if (!isl29003_get_power_state(client))
+		return -EBUSY;
+
+	return sprintf(buf, "%d\n", isl29003_get_adc_value(client));
+}
+
+static DEVICE_ATTR(lux, S_IRUGO, isl29003_show_lux, NULL);
+
+static struct attribute *isl29003_attributes[] = {
+	&dev_attr_range.attr,
+	&dev_attr_resolution.attr,
+	&dev_attr_mode.attr,
+	&dev_attr_power_state.attr,
+	&dev_attr_lux.attr,
+	NULL
+};
+
+static const struct attribute_group isl29003_attr_group = {
+	.attrs = isl29003_attributes,
+};
+
+static int isl29003_init_client(struct i2c_client *client)
+{
+	struct isl29003_data *data = i2c_get_clientdata(client);
+	int i;
+
+	/* read all the registers once to fill the cache.
+	 * if one of the reads fails, we consider the init failed */
+	for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++) {
+		int v = i2c_smbus_read_byte_data(client, i);
+		if (v < 0)
+			return -ENODEV;
+
+		data->reg_cache[i] = v;
+	}
+
+	/* set defaults */
+	isl29003_set_range(client, 0);
+	isl29003_set_resolution(client, 0);
+	isl29003_set_mode(client, 0);
+	isl29003_set_power_state(client, 0);
+
+	return 0;
+}
+
+/*
+ * I2C layer
+ */
+
+static int __devinit isl29003_probe(struct i2c_client *client,
+				    const struct i2c_device_id *id)
+{
+	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+	struct isl29003_data *data;
+	int err = 0;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
+		return -EIO;
+
+	data = kzalloc(sizeof(struct isl29003_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->client = client;
+	i2c_set_clientdata(client, data);
+	mutex_init(&data->lock);
+
+	/* initialize the ISL29003 chip */
+	err = isl29003_init_client(client);
+	if (err)
+		goto exit_kfree;
+
+	/* register sysfs hooks */
+	err = sysfs_create_group(&client->dev.kobj, &isl29003_attr_group);
+	if (err)
+		goto exit_kfree;
+
+	dev_info(&client->dev, "driver version %s enabled\n", DRIVER_VERSION);
+	return 0;
+
+exit_kfree:
+	kfree(data);
+	return err;
+}
+
+static int __devexit isl29003_remove(struct i2c_client *client)
+{
+	sysfs_remove_group(&client->dev.kobj, &isl29003_attr_group);
+	isl29003_set_power_state(client, 0);
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int isl29003_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+	return isl29003_set_power_state(client, 0);
+}
+
+static int isl29003_resume(struct i2c_client *client)
+{
+	int i;
+	struct isl29003_data *data = i2c_get_clientdata(client);
+
+	/* restore registers from cache */
+	for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++)
+		if (!i2c_smbus_write_byte_data(client, i, data->reg_cache[i]))
+			return -EIO;
+
+	return 0;
+}
+
+#else
+#define isl29003_suspend	NULL
+#define isl29003_resume		NULL
+#endif /* CONFIG_PM */
+
+static const struct i2c_device_id isl29003_id[] = {
+	{ "isl29003", 0 },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, isl29003_id);
+
+static struct i2c_driver isl29003_driver = {
+	.driver = {
+		.name	= ISL29003_DRV_NAME,
+		.owner	= THIS_MODULE,
+	},
+	.suspend = isl29003_suspend,
+	.resume	= isl29003_resume,
+	.probe	= isl29003_probe,
+	.remove	= __devexit_p(isl29003_remove),
+	.id_table = isl29003_id,
+};
+
+static int __init isl29003_init(void)
+{
+	return i2c_add_driver(&isl29003_driver);
+}
+
+static void __exit isl29003_exit(void)
+{
+	i2c_del_driver(&isl29003_driver);
+}
+
+MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
+MODULE_DESCRIPTION("ISL29003 ambient light sensor driver");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(DRIVER_VERSION);
+
+module_init(isl29003_init);
+module_exit(isl29003_exit);
+
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
index 78ad487..36a8d53 100644
--- a/drivers/mmc/card/sdio_uart.c
+++ b/drivers/mmc/card/sdio_uart.c
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mutex.h>
+#include <linux/seq_file.h>
 #include <linux/serial_reg.h>
 #include <linux/circ_buf.h>
 #include <linux/gfp.h>
@@ -933,67 +934,64 @@
 	return result;
 }
 
-static int sdio_uart_read_proc(char *page, char **start, off_t off,
-			       int count, int *eof, void *data)
+static int sdio_uart_proc_show(struct seq_file *m, void *v)
 {
-	int i, len = 0;
-	off_t begin = 0;
+	int i;
 
-	len += sprintf(page, "serinfo:1.0 driver%s%s revision:%s\n",
+	seq_printf(m, "serinfo:1.0 driver%s%s revision:%s\n",
 		       "", "", "");
-	for (i = 0; i < UART_NR && len < PAGE_SIZE - 96; i++) {
+	for (i = 0; i < UART_NR; i++) {
 		struct sdio_uart_port *port = sdio_uart_port_get(i);
 		if (port) {
-			len += sprintf(page+len, "%d: uart:SDIO", i);
+			seq_printf(m, "%d: uart:SDIO", i);
 			if(capable(CAP_SYS_ADMIN)) {
-				len += sprintf(page + len, " tx:%d rx:%d",
+				seq_printf(m, " tx:%d rx:%d",
 					       port->icount.tx, port->icount.rx);
 				if (port->icount.frame)
-					len += sprintf(page + len, " fe:%d",
+					seq_printf(m, " fe:%d",
 						       port->icount.frame);
 				if (port->icount.parity)
-					len += sprintf(page + len, " pe:%d",
+					seq_printf(m, " pe:%d",
 						       port->icount.parity);
 				if (port->icount.brk)
-					len += sprintf(page + len, " brk:%d",
+					seq_printf(m, " brk:%d",
 						       port->icount.brk);
 				if (port->icount.overrun)
-					len += sprintf(page + len, " oe:%d",
+					seq_printf(m, " oe:%d",
 						       port->icount.overrun);
 				if (port->icount.cts)
-					len += sprintf(page + len, " cts:%d",
+					seq_printf(m, " cts:%d",
 						       port->icount.cts);
 				if (port->icount.dsr)
-					len += sprintf(page + len, " dsr:%d",
+					seq_printf(m, " dsr:%d",
 						       port->icount.dsr);
 				if (port->icount.rng)
-					len += sprintf(page + len, " rng:%d",
+					seq_printf(m, " rng:%d",
 						       port->icount.rng);
 				if (port->icount.dcd)
-					len += sprintf(page + len, " dcd:%d",
+					seq_printf(m, " dcd:%d",
 						       port->icount.dcd);
 			}
-			strcat(page, "\n");
-			len++;
 			sdio_uart_port_put(port);
-		}
-
-		if (len + begin > off + count)
-			goto done;
-		if (len + begin < off) {
-			begin += len;
-			len = 0;
+			seq_putc(m, '\n');
 		}
 	}
-	*eof = 1;
-
-done:
-	if (off >= len + begin)
-		return 0;
-	*start = page + (off - begin);
-	return (count < begin + len - off) ? count : (begin + len - off);
+	return 0;
 }
 
+static int sdio_uart_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, sdio_uart_proc_show, NULL);
+}
+
+static const struct file_operations sdio_uart_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= sdio_uart_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static const struct tty_operations sdio_uart_ops = {
 	.open			= sdio_uart_open,
 	.close			= sdio_uart_close,
@@ -1007,7 +1005,7 @@
 	.break_ctl		= sdio_uart_break_ctl,
 	.tiocmget		= sdio_uart_tiocmget,
 	.tiocmset		= sdio_uart_tiocmset,
-	.read_proc		= sdio_uart_read_proc,
+	.proc_fops		= &sdio_uart_proc_fops,
 };
 
 static struct tty_driver *sdio_uart_tty_driver;
diff --git a/drivers/of/base.c b/drivers/of/base.c
index cd17092..41c5dfd 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -446,6 +446,7 @@
 };
 static struct of_modalias_table of_modalias_table[] = {
 	{ "fsl,mcu-mpc8349emitx", "mcu-mpc8349emitx" },
+	{ "mmc-spi-slot", "mmc_spi" },
 };
 
 /**
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 81450fb..09d5cd3 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -129,13 +129,14 @@
 if I2C
 
 config RTC_DRV_DS1307
-	tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00"
+	tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025"
 	help
 	  If you say yes here you get support for various compatible RTC
 	  chips (often with battery backup) connected with I2C. This driver
 	  should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00,
-	  and probably other chips. In some cases the RTC must already
-	  have been initialized (by manufacturing or a bootloader).
+	  EPSON RX-8025 and probably other chips. In some cases the RTC
+	  must already have been initialized (by manufacturing or a
+	  bootloader).
 
 	  The first seven registers on these chips hold an RTC, and other
 	  registers may add features such as NVRAM, a trickle charger for
@@ -440,6 +441,16 @@
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-ds1742.
 
+config RTC_DRV_EFI
+	tristate "EFI RTC"
+	depends on IA64
+	help
+	  If you say yes here you will get support for the EFI
+	  Real Time Clock.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-efi.
+
 config RTC_DRV_STK17TA8
 	tristate "Simtek STK17TA8"
 	depends on RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 0e697aa..e7b0998 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -36,6 +36,7 @@
 obj-$(CONFIG_RTC_DRV_DS1672)	+= rtc-ds1672.o
 obj-$(CONFIG_RTC_DRV_DS1742)	+= rtc-ds1742.o
 obj-$(CONFIG_RTC_DRV_DS3234)	+= rtc-ds3234.o
+obj-$(CONFIG_RTC_DRV_EFI)	+= rtc-efi.o
 obj-$(CONFIG_RTC_DRV_EP93XX)	+= rtc-ep93xx.o
 obj-$(CONFIG_RTC_DRV_FM3130)	+= rtc-fm3130.o
 obj-$(CONFIG_RTC_DRV_ISL1208)	+= rtc-isl1208.o
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 7e5155e..2c4a653 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -3,6 +3,7 @@
  *
  *  Copyright (C) 2005 James Chapman (ds1337 core)
  *  Copyright (C) 2006 David Brownell
+ *  Copyright (C) 2009 Matthias Fuchs (rx8025 support)
  *
  * 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
@@ -31,6 +32,7 @@
 	ds_1339,
 	ds_1340,
 	m41t00,
+	rx_8025,
 	// rs5c372 too?  different address...
 };
 
@@ -83,6 +85,12 @@
 #define DS1339_REG_ALARM1_SECS	0x07
 #define DS1339_REG_TRICKLE	0x10
 
+#define RX8025_REG_CTRL1	0x0e
+#	define RX8025_BIT_2412		0x20
+#define RX8025_REG_CTRL2	0x0f
+#	define RX8025_BIT_PON		0x10
+#	define RX8025_BIT_VDET		0x40
+#	define RX8025_BIT_XST		0x20
 
 
 struct ds1307 {
@@ -94,6 +102,10 @@
 	struct i2c_client	*client;
 	struct rtc_device	*rtc;
 	struct work_struct	work;
+	s32 (*read_block_data)(struct i2c_client *client, u8 command,
+			       u8 length, u8 *values);
+	s32 (*write_block_data)(struct i2c_client *client, u8 command,
+				u8 length, const u8 *values);
 };
 
 struct chip_desc {
@@ -117,6 +129,8 @@
 [ds_1340] = {
 },
 [m41t00] = {
+},
+[rx_8025] = {
 }, };
 
 static const struct i2c_device_id ds1307_id[] = {
@@ -126,12 +140,86 @@
 	{ "ds1339", ds_1339 },
 	{ "ds1340", ds_1340 },
 	{ "m41t00", m41t00 },
+	{ "rx8025", rx_8025 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, ds1307_id);
 
 /*----------------------------------------------------------------------*/
 
+#define BLOCK_DATA_MAX_TRIES 10
+
+static s32 ds1307_read_block_data_once(struct i2c_client *client, u8 command,
+				  u8 length, u8 *values)
+{
+	s32 i, data;
+
+	for (i = 0; i < length; i++) {
+		data = i2c_smbus_read_byte_data(client, command + i);
+		if (data < 0)
+			return data;
+		values[i] = data;
+	}
+	return i;
+}
+
+static s32 ds1307_read_block_data(struct i2c_client *client, u8 command,
+				  u8 length, u8 *values)
+{
+	u8 oldvalues[I2C_SMBUS_BLOCK_MAX];
+	s32 ret;
+	int tries = 0;
+
+	dev_dbg(&client->dev, "ds1307_read_block_data (length=%d)\n", length);
+	ret = ds1307_read_block_data_once(client, command, length, values);
+	if (ret < 0)
+		return ret;
+	do {
+		if (++tries > BLOCK_DATA_MAX_TRIES) {
+			dev_err(&client->dev,
+				"ds1307_read_block_data failed\n");
+			return -EIO;
+		}
+		memcpy(oldvalues, values, length);
+		ret = ds1307_read_block_data_once(client, command, length,
+						  values);
+		if (ret < 0)
+			return ret;
+	} while (memcmp(oldvalues, values, length));
+	return length;
+}
+
+static s32 ds1307_write_block_data(struct i2c_client *client, u8 command,
+				   u8 length, const u8 *values)
+{
+	u8 currvalues[I2C_SMBUS_BLOCK_MAX];
+	int tries = 0;
+
+	dev_dbg(&client->dev, "ds1307_write_block_data (length=%d)\n", length);
+	do {
+		s32 i, ret;
+
+		if (++tries > BLOCK_DATA_MAX_TRIES) {
+			dev_err(&client->dev,
+				"ds1307_write_block_data failed\n");
+			return -EIO;
+		}
+		for (i = 0; i < length; i++) {
+			ret = i2c_smbus_write_byte_data(client, command + i,
+							values[i]);
+			if (ret < 0)
+				return ret;
+		}
+		ret = ds1307_read_block_data_once(client, command, length,
+						  currvalues);
+		if (ret < 0)
+			return ret;
+	} while (memcmp(currvalues, values, length));
+	return length;
+}
+
+/*----------------------------------------------------------------------*/
+
 /*
  * The IRQ logic includes a "real" handler running in IRQ context just
  * long enough to schedule this workqueue entry.   We need a task context
@@ -202,7 +290,7 @@
 	int		tmp;
 
 	/* read the RTC date and time registers all at once */
-	tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
+	tmp = ds1307->read_block_data(ds1307->client,
 		DS1307_REG_SECS, 7, ds1307->regs);
 	if (tmp != 7) {
 		dev_err(dev, "%s error %d\n", "read", tmp);
@@ -279,7 +367,7 @@
 		"write", buf[0], buf[1], buf[2], buf[3],
 		buf[4], buf[5], buf[6]);
 
-	result = i2c_smbus_write_i2c_block_data(ds1307->client, 0, 7, buf);
+	result = ds1307->write_block_data(ds1307->client, 0, 7, buf);
 	if (result < 0) {
 		dev_err(dev, "%s error %d\n", "write", result);
 		return result;
@@ -297,7 +385,7 @@
 		return -EINVAL;
 
 	/* read all ALARM1, ALARM2, and status registers at once */
-	ret = i2c_smbus_read_i2c_block_data(client,
+	ret = ds1307->read_block_data(client,
 			DS1339_REG_ALARM1_SECS, 9, ds1307->regs);
 	if (ret != 9) {
 		dev_err(dev, "%s error %d\n", "alarm read", ret);
@@ -356,7 +444,7 @@
 		t->enabled, t->pending);
 
 	/* read current status of both alarms and the chip */
-	ret = i2c_smbus_read_i2c_block_data(client,
+	ret = ds1307->read_block_data(client,
 			DS1339_REG_ALARM1_SECS, 9, buf);
 	if (ret != 9) {
 		dev_err(dev, "%s error %d\n", "alarm write", ret);
@@ -391,7 +479,7 @@
 	}
 	buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I);
 
-	ret = i2c_smbus_write_i2c_block_data(client,
+	ret = ds1307->write_block_data(client,
 			DS1339_REG_ALARM1_SECS, 9, buf);
 	if (ret < 0) {
 		dev_err(dev, "can't set alarm time\n");
@@ -479,7 +567,7 @@
 	if (unlikely(!count))
 		return count;
 
-	result = i2c_smbus_read_i2c_block_data(client, 8 + off, count, buf);
+	result = ds1307->read_block_data(client, 8 + off, count, buf);
 	if (result < 0)
 		dev_err(&client->dev, "%s error %d\n", "nvram read", result);
 	return result;
@@ -490,9 +578,11 @@
 		char *buf, loff_t off, size_t count)
 {
 	struct i2c_client	*client;
+	struct ds1307		*ds1307;
 	int			result;
 
 	client = kobj_to_i2c_client(kobj);
+	ds1307 = i2c_get_clientdata(client);
 
 	if (unlikely(off >= NVRAM_SIZE))
 		return -EFBIG;
@@ -501,7 +591,7 @@
 	if (unlikely(!count))
 		return count;
 
-	result = i2c_smbus_write_i2c_block_data(client, 8 + off, count, buf);
+	result = ds1307->write_block_data(client, 8 + off, count, buf);
 	if (result < 0) {
 		dev_err(&client->dev, "%s error %d\n", "nvram write", result);
 		return result;
@@ -535,9 +625,8 @@
 	int			want_irq = false;
 	unsigned char		*buf;
 
-	if (!i2c_check_functionality(adapter,
-			I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
-			I2C_FUNC_SMBUS_I2C_BLOCK))
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)
+	    && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
 		return -EIO;
 
 	if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL)))
@@ -547,6 +636,13 @@
 	i2c_set_clientdata(client, ds1307);
 	ds1307->type = id->driver_data;
 	buf = ds1307->regs;
+	if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
+		ds1307->read_block_data = i2c_smbus_read_i2c_block_data;
+		ds1307->write_block_data = i2c_smbus_write_i2c_block_data;
+	} else {
+		ds1307->read_block_data = ds1307_read_block_data;
+		ds1307->write_block_data = ds1307_write_block_data;
+	}
 
 	switch (ds1307->type) {
 	case ds_1337:
@@ -557,7 +653,7 @@
 			want_irq = true;
 		}
 		/* get registers that the "rtc" read below won't read... */
-		tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
+		tmp = ds1307->read_block_data(ds1307->client,
 				DS1337_REG_CONTROL, 2, buf);
 		if (tmp != 2) {
 			pr_debug("read error %d\n", tmp);
@@ -589,13 +685,79 @@
 			dev_warn(&client->dev, "SET TIME!\n");
 		}
 		break;
+
+	case rx_8025:
+		tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
+				RX8025_REG_CTRL1 << 4 | 0x08, 2, buf);
+		if (tmp != 2) {
+			pr_debug("read error %d\n", tmp);
+			err = -EIO;
+			goto exit_free;
+		}
+
+		/* oscillator off?  turn it on, so clock can tick. */
+		if (!(ds1307->regs[1] & RX8025_BIT_XST)) {
+			ds1307->regs[1] |= RX8025_BIT_XST;
+			i2c_smbus_write_byte_data(client,
+						  RX8025_REG_CTRL2 << 4 | 0x08,
+						  ds1307->regs[1]);
+			dev_warn(&client->dev,
+				 "oscillator stop detected - SET TIME!\n");
+		}
+
+		if (ds1307->regs[1] & RX8025_BIT_PON) {
+			ds1307->regs[1] &= ~RX8025_BIT_PON;
+			i2c_smbus_write_byte_data(client,
+						  RX8025_REG_CTRL2 << 4 | 0x08,
+						  ds1307->regs[1]);
+			dev_warn(&client->dev, "power-on detected\n");
+		}
+
+		if (ds1307->regs[1] & RX8025_BIT_VDET) {
+			ds1307->regs[1] &= ~RX8025_BIT_VDET;
+			i2c_smbus_write_byte_data(client,
+						  RX8025_REG_CTRL2 << 4 | 0x08,
+						  ds1307->regs[1]);
+			dev_warn(&client->dev, "voltage drop detected\n");
+		}
+
+		/* make sure we are running in 24hour mode */
+		if (!(ds1307->regs[0] & RX8025_BIT_2412)) {
+			u8 hour;
+
+			/* switch to 24 hour mode */
+			i2c_smbus_write_byte_data(client,
+						  RX8025_REG_CTRL1 << 4 | 0x08,
+						  ds1307->regs[0] |
+						  RX8025_BIT_2412);
+
+			tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
+					RX8025_REG_CTRL1 << 4 | 0x08, 2, buf);
+			if (tmp != 2) {
+				pr_debug("read error %d\n", tmp);
+				err = -EIO;
+				goto exit_free;
+			}
+
+			/* correct hour */
+			hour = bcd2bin(ds1307->regs[DS1307_REG_HOUR]);
+			if (hour == 12)
+				hour = 0;
+			if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
+				hour += 12;
+
+			i2c_smbus_write_byte_data(client,
+						  DS1307_REG_HOUR << 4 | 0x08,
+						  hour);
+		}
+		break;
 	default:
 		break;
 	}
 
 read_rtc:
 	/* read RTC registers */
-	tmp = i2c_smbus_read_i2c_block_data(ds1307->client, 0, 8, buf);
+	tmp = ds1307->read_block_data(ds1307->client, 0, 8, buf);
 	if (tmp != 8) {
 		pr_debug("read error %d\n", tmp);
 		err = -EIO;
@@ -649,6 +811,7 @@
 			dev_warn(&client->dev, "SET TIME!\n");
 		}
 		break;
+	case rx_8025:
 	case ds_1337:
 	case ds_1339:
 		break;
@@ -662,6 +825,8 @@
 		 * systems that will run through year 2100.
 		 */
 		break;
+	case rx_8025:
+		break;
 	default:
 		if (!(tmp & DS1307_BIT_12HR))
 			break;
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index a5b0fc0..4d32e32 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -222,16 +222,16 @@
 	rtc_tm_to_time(&alarm->time, &new_alarm);
 	rtc_tm_to_time(&now, &itime);
 
-	new_alarm -= itime;
-
 	/* This can happen due to races, in addition to dates that are
 	 * truly in the past.  To avoid requiring the caller to check for
 	 * races, dates in the past are assumed to be in the recent past
 	 * (i.e. not something that we'd rather the caller know about via
 	 * an error), and the alarm is set to go off as soon as possible.
 	 */
-	if (new_alarm <= 0)
+	if (time_before_eq(new_alarm, itime))
 		new_alarm = 1;
+	else
+		new_alarm -= itime;
 
 	mutex_lock(&ds1374->mutex);
 
diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c
new file mode 100644
index 0000000..5502923
--- /dev/null
+++ b/drivers/rtc/rtc-efi.c
@@ -0,0 +1,235 @@
+/*
+ * rtc-efi: RTC Class Driver for EFI-based systems
+ *
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
+ *
+ * Author: dann frazier <dannf@hp.com>
+ * Based on efirtc.c by Stephane Eranian
+ *
+ *  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/kernel.h>
+#include <linux/module.h>
+#include <linux/time.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/efi.h>
+
+#define EFI_ISDST (EFI_TIME_ADJUST_DAYLIGHT|EFI_TIME_IN_DAYLIGHT)
+/*
+ * EFI Epoch is 1/1/1998
+ */
+#define EFI_RTC_EPOCH		1998
+
+/*
+ * returns day of the year [0-365]
+ */
+static inline int
+compute_yday(efi_time_t *eft)
+{
+	/* efi_time_t.month is in the [1-12] so, we need -1 */
+	return rtc_year_days(eft->day - 1, eft->month - 1, eft->year);
+}
+/*
+ * returns day of the week [0-6] 0=Sunday
+ *
+ * Don't try to provide a year that's before 1998, please !
+ */
+static int
+compute_wday(efi_time_t *eft)
+{
+	int y;
+	int ndays = 0;
+
+	if (eft->year < 1998) {
+		printk(KERN_ERR "efirtc: EFI year < 1998, invalid date\n");
+		return -1;
+	}
+
+	for (y = EFI_RTC_EPOCH; y < eft->year; y++)
+		ndays += 365 + (is_leap_year(y) ? 1 : 0);
+
+	ndays += compute_yday(eft);
+
+	/*
+	 * 4=1/1/1998 was a Thursday
+	 */
+	return (ndays + 4) % 7;
+}
+
+static void
+convert_to_efi_time(struct rtc_time *wtime, efi_time_t *eft)
+{
+	eft->year	= wtime->tm_year + 1900;
+	eft->month	= wtime->tm_mon + 1;
+	eft->day	= wtime->tm_mday;
+	eft->hour	= wtime->tm_hour;
+	eft->minute	= wtime->tm_min;
+	eft->second 	= wtime->tm_sec;
+	eft->nanosecond = 0;
+	eft->daylight	= wtime->tm_isdst ? EFI_ISDST : 0;
+	eft->timezone	= EFI_UNSPECIFIED_TIMEZONE;
+}
+
+static void
+convert_from_efi_time(efi_time_t *eft, struct rtc_time *wtime)
+{
+	memset(wtime, 0, sizeof(*wtime));
+	wtime->tm_sec  = eft->second;
+	wtime->tm_min  = eft->minute;
+	wtime->tm_hour = eft->hour;
+	wtime->tm_mday = eft->day;
+	wtime->tm_mon  = eft->month - 1;
+	wtime->tm_year = eft->year - 1900;
+
+	/* day of the week [0-6], Sunday=0 */
+	wtime->tm_wday = compute_wday(eft);
+
+	/* day in the year [1-365]*/
+	wtime->tm_yday = compute_yday(eft);
+
+
+	switch (eft->daylight & EFI_ISDST) {
+	case EFI_ISDST:
+		wtime->tm_isdst = 1;
+		break;
+	case EFI_TIME_ADJUST_DAYLIGHT:
+		wtime->tm_isdst = 0;
+		break;
+	default:
+		wtime->tm_isdst = -1;
+	}
+}
+
+static int efi_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
+{
+	efi_time_t eft;
+	efi_status_t status;
+
+	/*
+	 * As of EFI v1.10, this call always returns an unsupported status
+	 */
+	status = efi.get_wakeup_time((efi_bool_t *)&wkalrm->enabled,
+				     (efi_bool_t *)&wkalrm->pending, &eft);
+
+	if (status != EFI_SUCCESS)
+		return -EINVAL;
+
+	convert_from_efi_time(&eft, &wkalrm->time);
+
+	return rtc_valid_tm(&wkalrm->time);
+}
+
+static int efi_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
+{
+	efi_time_t eft;
+	efi_status_t status;
+
+	convert_to_efi_time(&wkalrm->time, &eft);
+
+	/*
+	 * XXX Fixme:
+	 * As of EFI 0.92 with the firmware I have on my
+	 * machine this call does not seem to work quite
+	 * right
+	 *
+	 * As of v1.10, this call always returns an unsupported status
+	 */
+	status = efi.set_wakeup_time((efi_bool_t)wkalrm->enabled, &eft);
+
+	printk(KERN_WARNING "write status is %d\n", (int)status);
+
+	return status == EFI_SUCCESS ? 0 : -EINVAL;
+}
+
+static int efi_read_time(struct device *dev, struct rtc_time *tm)
+{
+	efi_status_t status;
+	efi_time_t eft;
+	efi_time_cap_t cap;
+
+	status = efi.get_time(&eft, &cap);
+
+	if (status != EFI_SUCCESS) {
+		/* should never happen */
+		printk(KERN_ERR "efitime: can't read time\n");
+		return -EINVAL;
+	}
+
+	convert_from_efi_time(&eft, tm);
+
+	return rtc_valid_tm(tm);
+}
+
+static int efi_set_time(struct device *dev, struct rtc_time *tm)
+{
+	efi_status_t status;
+	efi_time_t eft;
+
+	convert_to_efi_time(tm, &eft);
+
+	status = efi.set_time(&eft);
+
+	return status == EFI_SUCCESS ? 0 : -EINVAL;
+}
+
+static const struct rtc_class_ops efi_rtc_ops = {
+	.read_time = efi_read_time,
+	.set_time = efi_set_time,
+	.read_alarm = efi_read_alarm,
+	.set_alarm = efi_set_alarm,
+};
+
+static int __init efi_rtc_probe(struct platform_device *dev)
+{
+	struct rtc_device *rtc;
+
+	rtc = rtc_device_register("rtc-efi", &dev->dev, &efi_rtc_ops,
+					THIS_MODULE);
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
+
+	platform_set_drvdata(dev, rtc);
+
+	return 0;
+}
+
+static int __exit efi_rtc_remove(struct platform_device *dev)
+{
+	struct rtc_device *rtc = platform_get_drvdata(dev);
+
+	rtc_device_unregister(rtc);
+
+	return 0;
+}
+
+static struct platform_driver efi_rtc_driver = {
+	.driver = {
+		.name = "rtc-efi",
+		.owner = THIS_MODULE,
+	},
+	.probe = efi_rtc_probe,
+	.remove = __exit_p(efi_rtc_remove),
+};
+
+static int __init efi_rtc_init(void)
+{
+	return platform_driver_probe(&efi_rtc_driver, efi_rtc_probe);
+}
+
+static void __exit efi_rtc_exit(void)
+{
+	platform_driver_unregister(&efi_rtc_driver);
+}
+
+module_init(efi_rtc_init);
+module_exit(efi_rtc_exit);
+
+MODULE_AUTHOR("dann frazier <dannf@hp.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("EFI RTC driver");
diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c
index dd70bf7..773851f 100644
--- a/drivers/rtc/rtc-lib.c
+++ b/drivers/rtc/rtc-lib.c
@@ -26,14 +26,13 @@
 };
 
 #define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400)
-#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400))
 
 /*
  * The number of days in the month.
  */
 int rtc_month_days(unsigned int month, unsigned int year)
 {
-	return rtc_days_in_month[month] + (LEAP_YEAR(year) && month == 1);
+	return rtc_days_in_month[month] + (is_leap_year(year) && month == 1);
 }
 EXPORT_SYMBOL(rtc_month_days);
 
@@ -42,7 +41,7 @@
  */
 int rtc_year_days(unsigned int day, unsigned int month, unsigned int year)
 {
-	return rtc_ydays[LEAP_YEAR(year)][month] + day-1;
+	return rtc_ydays[is_leap_year(year)][month] + day-1;
 }
 EXPORT_SYMBOL(rtc_year_days);
 
@@ -66,7 +65,7 @@
 		- LEAPS_THRU_END_OF(1970 - 1);
 	if (days < 0) {
 		year -= 1;
-		days += 365 + LEAP_YEAR(year);
+		days += 365 + is_leap_year(year);
 	}
 	tm->tm_year = year - 1900;
 	tm->tm_yday = days + 1;
diff --git a/drivers/rtc/rtc-parisc.c b/drivers/rtc/rtc-parisc.c
index c6bfa6f..b966f56 100644
--- a/drivers/rtc/rtc-parisc.c
+++ b/drivers/rtc/rtc-parisc.c
@@ -7,41 +7,25 @@
 #include <linux/module.h>
 #include <linux/time.h>
 #include <linux/platform_device.h>
+#include <linux/rtc.h>
 
 #include <asm/rtc.h>
 
-/* as simple as can be, and no simpler. */
-struct parisc_rtc {
-	struct rtc_device *rtc;
-	spinlock_t lock;
-};
-
 static int parisc_get_time(struct device *dev, struct rtc_time *tm)
 {
-	struct parisc_rtc *p = dev_get_drvdata(dev);
-	unsigned long flags, ret;
+	unsigned long ret;
 
-	spin_lock_irqsave(&p->lock, flags);
 	ret = get_rtc_time(tm);
-	spin_unlock_irqrestore(&p->lock, flags);
 
 	if (ret & RTC_BATT_BAD)
 		return -EOPNOTSUPP;
 
-	return 0;
+	return rtc_valid_tm(tm);
 }
 
 static int parisc_set_time(struct device *dev, struct rtc_time *tm)
 {
-	struct parisc_rtc *p = dev_get_drvdata(dev);
-	unsigned long flags;
-	int ret;
-
-	spin_lock_irqsave(&p->lock, flags);
-	ret = set_rtc_time(tm);
-	spin_unlock_irqrestore(&p->lock, flags);
-
-	if (ret < 0)
+	if (set_rtc_time(tm) < 0)
 		return -EOPNOTSUPP;
 
 	return 0;
@@ -52,35 +36,25 @@
 	.set_time = parisc_set_time,
 };
 
-static int __devinit parisc_rtc_probe(struct platform_device *dev)
+static int __init parisc_rtc_probe(struct platform_device *dev)
 {
-	struct parisc_rtc *p;
+	struct rtc_device *rtc;
 
-	p = kzalloc(sizeof (*p), GFP_KERNEL);
-	if (!p)
-		return -ENOMEM;
+	rtc = rtc_device_register("rtc-parisc", &dev->dev, &parisc_rtc_ops,
+				  THIS_MODULE);
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
 
-	spin_lock_init(&p->lock);
-
-	p->rtc = rtc_device_register("rtc-parisc", &dev->dev, &parisc_rtc_ops,
-					THIS_MODULE);
-	if (IS_ERR(p->rtc)) {
-		int err = PTR_ERR(p->rtc);
-		kfree(p);
-		return err;
-	}
-
-	platform_set_drvdata(dev, p);
+	platform_set_drvdata(dev, rtc);
 
 	return 0;
 }
 
-static int __devexit parisc_rtc_remove(struct platform_device *dev)
+static int __exit parisc_rtc_remove(struct platform_device *dev)
 {
-	struct parisc_rtc *p = platform_get_drvdata(dev);
+	struct rtc_device *rtc = platform_get_drvdata(dev);
 
-	rtc_device_unregister(p->rtc);
-	kfree(p);
+	rtc_device_unregister(rtc);
 
 	return 0;
 }
@@ -96,7 +70,7 @@
 
 static int __init parisc_rtc_init(void)
 {
-	return platform_driver_register(&parisc_rtc_driver);
+	return platform_driver_probe(&parisc_rtc_driver, parisc_rtc_probe);
 }
 
 static void __exit parisc_rtc_fini(void)
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c
index 14d4f03..66955cc 100644
--- a/drivers/rtc/rtc-v3020.c
+++ b/drivers/rtc/rtc-v3020.c
@@ -28,7 +28,7 @@
 #include <linux/rtc-v3020.h>
 #include <linux/delay.h>
 
-#include <asm/io.h>
+#include <linux/io.h>
 
 #undef DEBUG
 
@@ -63,7 +63,7 @@
 
 static unsigned char v3020_get_reg(struct v3020 *chip, unsigned char address)
 {
-	unsigned int data=0;
+	unsigned int data = 0;
 	int i;
 
 	for (i = 0; i < 4; i++) {
@@ -106,16 +106,14 @@
 	tmp = v3020_get_reg(chip, V3020_YEAR);
 	dt->tm_year = bcd2bin(tmp)+100;
 
-#ifdef DEBUG
-	printk("\n%s : Read RTC values\n",__func__);
-	printk("tm_hour: %i\n",dt->tm_hour);
-	printk("tm_min : %i\n",dt->tm_min);
-	printk("tm_sec : %i\n",dt->tm_sec);
-	printk("tm_year: %i\n",dt->tm_year);
-	printk("tm_mon : %i\n",dt->tm_mon);
-	printk("tm_mday: %i\n",dt->tm_mday);
-	printk("tm_wday: %i\n",dt->tm_wday);
-#endif
+	dev_dbg(dev, "\n%s : Read RTC values\n", __func__);
+	dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour);
+	dev_dbg(dev, "tm_min : %i\n", dt->tm_min);
+	dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec);
+	dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
+	dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon);
+	dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday);
+	dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday);
 
 	return 0;
 }
@@ -125,15 +123,13 @@
 {
 	struct v3020 *chip = dev_get_drvdata(dev);
 
-#ifdef DEBUG
-	printk("\n%s : Setting RTC values\n",__func__);
-	printk("tm_sec : %i\n",dt->tm_sec);
-	printk("tm_min : %i\n",dt->tm_min);
-	printk("tm_hour: %i\n",dt->tm_hour);
-	printk("tm_mday: %i\n",dt->tm_mday);
-	printk("tm_wday: %i\n",dt->tm_wday);
-	printk("tm_year: %i\n",dt->tm_year);
-#endif
+	dev_dbg(dev, "\n%s : Setting RTC values\n", __func__);
+	dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec);
+	dev_dbg(dev, "tm_min : %i\n", dt->tm_min);
+	dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour);
+	dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday);
+	dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday);
+	dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
 
 	/* Write all the values to ram... */
 	v3020_set_reg(chip, V3020_SECONDS, 	bin2bcd(dt->tm_sec));
@@ -191,7 +187,7 @@
 	/* Test chip by doing a write/read sequence
 	 * to the chip ram */
 	v3020_set_reg(chip, V3020_SECONDS, 0x33);
-	if(v3020_get_reg(chip, V3020_SECONDS) != 0x33) {
+	if (v3020_get_reg(chip, V3020_SECONDS) != 0x33) {
 		retval = -ENODEV;
 		goto err_io;
 	}
diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c
index 5c5e3aa..c91edc5 100644
--- a/drivers/rtc/rtc-wm8350.c
+++ b/drivers/rtc/rtc-wm8350.c
@@ -122,7 +122,7 @@
 	do {
 		rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL);
 		schedule_timeout_uninterruptible(msecs_to_jiffies(1));
-	} while (retries-- && !(rtc_ctrl & WM8350_RTC_STS));
+	} while (--retries && !(rtc_ctrl & WM8350_RTC_STS));
 
 	if (!retries) {
 		dev_err(dev, "timed out on set confirmation\n");
@@ -236,6 +236,17 @@
 	return 0;
 }
 
+static int wm8350_rtc_alarm_irq_enable(struct device *dev,
+				       unsigned int enabled)
+{
+	struct wm8350 *wm8350 = dev_get_drvdata(dev);
+
+	if (enabled)
+		return wm8350_rtc_start_alarm(wm8350);
+	else
+		return wm8350_rtc_stop_alarm(wm8350);
+}
+
 static int wm8350_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
 	struct wm8350 *wm8350 = dev_get_drvdata(dev);
@@ -291,30 +302,15 @@
 	return ret;
 }
 
-/*
- * Handle commands from user-space
- */
-static int wm8350_rtc_ioctl(struct device *dev, unsigned int cmd,
-			    unsigned long arg)
+static int wm8350_rtc_update_irq_enable(struct device *dev,
+					unsigned int enabled)
 {
 	struct wm8350 *wm8350 = dev_get_drvdata(dev);
 
-	switch (cmd) {
-	case RTC_AIE_OFF:
-		return wm8350_rtc_stop_alarm(wm8350);
-	case RTC_AIE_ON:
-		return wm8350_rtc_start_alarm(wm8350);
-
-	case RTC_UIE_OFF:
-		wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
-		break;
-	case RTC_UIE_ON:
+	if (enabled)
 		wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC);
-		break;
-
-	default:
-		return -ENOIOCTLCMD;
-	}
+	else
+		wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
 
 	return 0;
 }
@@ -345,11 +341,12 @@
 }
 
 static const struct rtc_class_ops wm8350_rtc_ops = {
-	.ioctl = wm8350_rtc_ioctl,
 	.read_time = wm8350_rtc_readtime,
 	.set_time = wm8350_rtc_settime,
 	.read_alarm = wm8350_rtc_readalarm,
 	.set_alarm = wm8350_rtc_setalarm,
+	.alarm_irq_enable = wm8350_rtc_alarm_irq_enable,
+	.update_irq_enable = wm8350_rtc_update_irq_enable,
 };
 
 #ifdef CONFIG_PM
@@ -440,7 +437,7 @@
 		do {
 			timectl = wm8350_reg_read(wm8350,
 						  WM8350_RTC_TIME_CONTROL);
-		} while (timectl & WM8350_RTC_STS && retries--);
+		} while (timectl & WM8350_RTC_STS && --retries);
 
 		if (retries == 0) {
 			dev_err(&pdev->dev, "failed to start: timeout\n");
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 42f4e66..bf3c0e3 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -27,6 +27,8 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/console.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/serial_core.h>
 #include <linux/smp_lock.h>
 #include <linux/device.h>
@@ -1682,20 +1684,20 @@
 
 #ifdef CONFIG_PROC_FS
 
-static int uart_line_info(char *buf, struct uart_driver *drv, int i)
+static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i)
 {
 	struct uart_state *state = drv->state + i;
 	int pm_state;
 	struct uart_port *port = state->port;
 	char stat_buf[32];
 	unsigned int status;
-	int mmio, ret;
+	int mmio;
 
 	if (!port)
-		return 0;
+		return;
 
 	mmio = port->iotype >= UPIO_MEM;
-	ret = sprintf(buf, "%d: uart:%s %s%08llX irq:%d",
+	seq_printf(m, "%d: uart:%s %s%08llX irq:%d",
 			port->line, uart_type(port),
 			mmio ? "mmio:0x" : "port:",
 			mmio ? (unsigned long long)port->mapbase
@@ -1703,8 +1705,8 @@
 			port->irq);
 
 	if (port->type == PORT_UNKNOWN) {
-		strcat(buf, "\n");
-		return ret + 1;
+		seq_putc(m, '\n');
+		return;
 	}
 
 	if (capable(CAP_SYS_ADMIN)) {
@@ -1719,19 +1721,19 @@
 			uart_change_pm(state, pm_state);
 		mutex_unlock(&state->mutex);
 
-		ret += sprintf(buf + ret, " tx:%d rx:%d",
+		seq_printf(m, " tx:%d rx:%d",
 				port->icount.tx, port->icount.rx);
 		if (port->icount.frame)
-			ret += sprintf(buf + ret, " fe:%d",
+			seq_printf(m, " fe:%d",
 				port->icount.frame);
 		if (port->icount.parity)
-			ret += sprintf(buf + ret, " pe:%d",
+			seq_printf(m, " pe:%d",
 				port->icount.parity);
 		if (port->icount.brk)
-			ret += sprintf(buf + ret, " brk:%d",
+			seq_printf(m, " brk:%d",
 				port->icount.brk);
 		if (port->icount.overrun)
-			ret += sprintf(buf + ret, " oe:%d",
+			seq_printf(m, " oe:%d",
 				port->icount.overrun);
 
 #define INFOBIT(bit, str) \
@@ -1753,45 +1755,39 @@
 		STATBIT(TIOCM_RNG, "|RI");
 		if (stat_buf[0])
 			stat_buf[0] = ' ';
-		strcat(stat_buf, "\n");
 
-		ret += sprintf(buf + ret, stat_buf);
-	} else {
-		strcat(buf, "\n");
-		ret++;
+		seq_puts(m, stat_buf);
 	}
+	seq_putc(m, '\n');
 #undef STATBIT
 #undef INFOBIT
-	return ret;
 }
 
-static int uart_read_proc(char *page, char **start, off_t off,
-			  int count, int *eof, void *data)
+static int uart_proc_show(struct seq_file *m, void *v)
 {
-	struct tty_driver *ttydrv = data;
+	struct tty_driver *ttydrv = v;
 	struct uart_driver *drv = ttydrv->driver_state;
-	int i, len = 0, l;
-	off_t begin = 0;
+	int i;
 
-	len += sprintf(page, "serinfo:1.0 driver%s%s revision:%s\n",
+	seq_printf(m, "serinfo:1.0 driver%s%s revision:%s\n",
 			"", "", "");
-	for (i = 0; i < drv->nr && len < PAGE_SIZE - 96; i++) {
-		l = uart_line_info(page + len, drv, i);
-		len += l;
-		if (len + begin > off + count)
-			goto done;
-		if (len + begin < off) {
-			begin += len;
-			len = 0;
-		}
-	}
-	*eof = 1;
- done:
-	if (off >= len + begin)
-		return 0;
-	*start = page + (off - begin);
-	return (count < begin + len - off) ? count : (begin + len - off);
+	for (i = 0; i < drv->nr; i++)
+		uart_line_info(m, drv, i);
+	return 0;
 }
+
+static int uart_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, uart_proc_show, PDE(inode)->data);
+}
+
+static const struct file_operations uart_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= uart_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 #endif
 
 #if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(CONFIG_CONSOLE_POLL)
@@ -2299,7 +2295,7 @@
 	.break_ctl	= uart_break_ctl,
 	.wait_until_sent= uart_wait_until_sent,
 #ifdef CONFIG_PROC_FS
-	.read_proc	= uart_read_proc,
+	.proc_fops	= &uart_proc_fops,
 #endif
 	.tiocmget	= uart_tiocmget,
 	.tiocmset	= uart_tiocmset,
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index 44a2b46..f4573a9 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -14,6 +14,8 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/completion.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
@@ -23,7 +25,13 @@
 #include <linux/spi/spi_bitbang.h>
 #include <linux/platform_device.h>
 #include <linux/fsl_devices.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/of_spi.h>
 
+#include <sysdev/fsl_soc.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 
@@ -79,7 +87,7 @@
 	u32(*get_tx) (struct mpc83xx_spi *);
 
 	unsigned int count;
-	int irq;
+	unsigned int irq;
 
 	unsigned nsecs;		/* (clock cycle time)/2 */
 
@@ -89,9 +97,6 @@
 
 	bool qe_mode;
 
-	void (*activate_cs) (u8 cs, u8 polarity);
-	void (*deactivate_cs) (u8 cs, u8 polarity);
-
 	u8 busy;
 
 	struct workqueue_struct *workqueue;
@@ -123,6 +128,7 @@
 }
 
 #define MPC83XX_SPI_RX_BUF(type) 					  \
+static									  \
 void mpc83xx_spi_rx_buf_##type(u32 data, struct mpc83xx_spi *mpc83xx_spi) \
 {									  \
 	type * rx = mpc83xx_spi->rx;					  \
@@ -131,6 +137,7 @@
 }
 
 #define MPC83XX_SPI_TX_BUF(type)				\
+static								\
 u32 mpc83xx_spi_tx_buf_##type(struct mpc83xx_spi *mpc83xx_spi)	\
 {								\
 	u32 data;						\
@@ -151,15 +158,14 @@
 
 static void mpc83xx_spi_chipselect(struct spi_device *spi, int value)
 {
-	struct mpc83xx_spi *mpc83xx_spi;
-	u8 pol = spi->mode & SPI_CS_HIGH ? 1 : 0;
+	struct mpc83xx_spi *mpc83xx_spi = spi_master_get_devdata(spi->master);
+	struct fsl_spi_platform_data *pdata = spi->dev.parent->platform_data;
+	bool pol = spi->mode & SPI_CS_HIGH;
 	struct spi_mpc83xx_cs	*cs = spi->controller_state;
 
-	mpc83xx_spi = spi_master_get_devdata(spi->master);
-
 	if (value == BITBANG_CS_INACTIVE) {
-		if (mpc83xx_spi->deactivate_cs)
-			mpc83xx_spi->deactivate_cs(spi->chip_select, pol);
+		if (pdata->cs_control)
+			pdata->cs_control(spi, !pol);
 	}
 
 	if (value == BITBANG_CS_ACTIVE) {
@@ -172,7 +178,7 @@
 
 		if (cs->hw_mode != regval) {
 			unsigned long flags;
-			void *tmp_ptr = &mpc83xx_spi->base->mode;
+			__be32 __iomem *mode = &mpc83xx_spi->base->mode;
 
 			regval = cs->hw_mode;
 			/* Turn off IRQs locally to minimize time that
@@ -180,12 +186,12 @@
 			 */
 			local_irq_save(flags);
 			/* Turn off SPI unit prior changing mode */
-			mpc83xx_spi_write_reg(tmp_ptr, regval & ~SPMODE_ENABLE);
-			mpc83xx_spi_write_reg(tmp_ptr, regval);
+			mpc83xx_spi_write_reg(mode, regval & ~SPMODE_ENABLE);
+			mpc83xx_spi_write_reg(mode, regval);
 			local_irq_restore(flags);
 		}
-		if (mpc83xx_spi->activate_cs)
-			mpc83xx_spi->activate_cs(spi->chip_select, pol);
+		if (pdata->cs_control)
+			pdata->cs_control(spi, pol);
 	}
 }
 
@@ -284,7 +290,7 @@
 	regval =  mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
 	if (cs->hw_mode != regval) {
 		unsigned long flags;
-		void *tmp_ptr = &mpc83xx_spi->base->mode;
+		__be32 __iomem *mode = &mpc83xx_spi->base->mode;
 
 		regval = cs->hw_mode;
 		/* Turn off IRQs locally to minimize time
@@ -292,8 +298,8 @@
 		 */
 		local_irq_save(flags);
 		/* Turn off SPI unit prior changing mode */
-		mpc83xx_spi_write_reg(tmp_ptr, regval & ~SPMODE_ENABLE);
-		mpc83xx_spi_write_reg(tmp_ptr, regval);
+		mpc83xx_spi_write_reg(mode, regval & ~SPMODE_ENABLE);
+		mpc83xx_spi_write_reg(mode, regval);
 		local_irq_restore(flags);
 	}
 	return 0;
@@ -483,7 +489,7 @@
 	return 0;
 }
 
-irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data)
+static irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data)
 {
 	struct mpc83xx_spi *mpc83xx_spi = context_data;
 	u32 event;
@@ -545,43 +551,28 @@
 	kfree(spi->controller_state);
 }
 
-static int __init mpc83xx_spi_probe(struct platform_device *dev)
+static struct spi_master * __devinit
+mpc83xx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq)
 {
+	struct fsl_spi_platform_data *pdata = dev->platform_data;
 	struct spi_master *master;
 	struct mpc83xx_spi *mpc83xx_spi;
-	struct fsl_spi_platform_data *pdata;
-	struct resource *r;
 	u32 regval;
 	int ret = 0;
 
-	/* Get resources(memory, IRQ) associated with the device */
-	master = spi_alloc_master(&dev->dev, sizeof(struct mpc83xx_spi));
-
+	master = spi_alloc_master(dev, sizeof(struct mpc83xx_spi));
 	if (master == NULL) {
 		ret = -ENOMEM;
 		goto err;
 	}
 
-	platform_set_drvdata(dev, master);
-	pdata = dev->dev.platform_data;
+	dev_set_drvdata(dev, master);
 
-	if (pdata == NULL) {
-		ret = -ENODEV;
-		goto free_master;
-	}
-
-	r = platform_get_resource(dev, IORESOURCE_MEM, 0);
-	if (r == NULL) {
-		ret = -ENODEV;
-		goto free_master;
-	}
 	master->setup = mpc83xx_spi_setup;
 	master->transfer = mpc83xx_spi_transfer;
 	master->cleanup = mpc83xx_spi_cleanup;
 
 	mpc83xx_spi = spi_master_get_devdata(master);
-	mpc83xx_spi->activate_cs = pdata->activate_cs;
-	mpc83xx_spi->deactivate_cs = pdata->deactivate_cs;
 	mpc83xx_spi->qe_mode = pdata->qe_mode;
 	mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8;
 	mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8;
@@ -596,18 +587,13 @@
 
 	init_completion(&mpc83xx_spi->done);
 
-	mpc83xx_spi->base = ioremap(r->start, r->end - r->start + 1);
+	mpc83xx_spi->base = ioremap(mem->start, mem->end - mem->start + 1);
 	if (mpc83xx_spi->base == NULL) {
 		ret = -ENOMEM;
 		goto put_master;
 	}
 
-	mpc83xx_spi->irq = platform_get_irq(dev, 0);
-
-	if (mpc83xx_spi->irq < 0) {
-		ret = -ENXIO;
-		goto unmap_io;
-	}
+	mpc83xx_spi->irq = irq;
 
 	/* Register for SPI Interrupt */
 	ret = request_irq(mpc83xx_spi->irq, mpc83xx_spi_irq,
@@ -649,9 +635,9 @@
 
 	printk(KERN_INFO
 	       "%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n",
-	       dev_name(&dev->dev), mpc83xx_spi->base, mpc83xx_spi->irq);
+	       dev_name(dev), mpc83xx_spi->base, mpc83xx_spi->irq);
 
-	return ret;
+	return master;
 
 unreg_master:
 	destroy_workqueue(mpc83xx_spi->workqueue);
@@ -661,18 +647,16 @@
 	iounmap(mpc83xx_spi->base);
 put_master:
 	spi_master_put(master);
-free_master:
-	kfree(master);
 err:
-	return ret;
+	return ERR_PTR(ret);
 }
 
-static int __exit mpc83xx_spi_remove(struct platform_device *dev)
+static int __devexit mpc83xx_spi_remove(struct device *dev)
 {
 	struct mpc83xx_spi *mpc83xx_spi;
 	struct spi_master *master;
 
-	master = platform_get_drvdata(dev);
+	master = dev_get_drvdata(dev);
 	mpc83xx_spi = spi_master_get_devdata(master);
 
 	flush_workqueue(mpc83xx_spi->workqueue);
@@ -685,23 +669,293 @@
 	return 0;
 }
 
+struct mpc83xx_spi_probe_info {
+	struct fsl_spi_platform_data pdata;
+	int *gpios;
+	bool *alow_flags;
+};
+
+static struct mpc83xx_spi_probe_info *
+to_of_pinfo(struct fsl_spi_platform_data *pdata)
+{
+	return container_of(pdata, struct mpc83xx_spi_probe_info, pdata);
+}
+
+static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on)
+{
+	struct device *dev = spi->dev.parent;
+	struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(dev->platform_data);
+	u16 cs = spi->chip_select;
+	int gpio = pinfo->gpios[cs];
+	bool alow = pinfo->alow_flags[cs];
+
+	gpio_set_value(gpio, on ^ alow);
+}
+
+static int of_mpc83xx_spi_get_chipselects(struct device *dev)
+{
+	struct device_node *np = dev_archdata_get_node(&dev->archdata);
+	struct fsl_spi_platform_data *pdata = dev->platform_data;
+	struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(pdata);
+	unsigned int ngpios;
+	int i = 0;
+	int ret;
+
+	ngpios = of_gpio_count(np);
+	if (!ngpios) {
+		/*
+		 * SPI w/o chip-select line. One SPI device is still permitted
+		 * though.
+		 */
+		pdata->max_chipselect = 1;
+		return 0;
+	}
+
+	pinfo->gpios = kmalloc(ngpios * sizeof(pinfo->gpios), GFP_KERNEL);
+	if (!pinfo->gpios)
+		return -ENOMEM;
+	memset(pinfo->gpios, -1, ngpios * sizeof(pinfo->gpios));
+
+	pinfo->alow_flags = kzalloc(ngpios * sizeof(pinfo->alow_flags),
+				    GFP_KERNEL);
+	if (!pinfo->alow_flags) {
+		ret = -ENOMEM;
+		goto err_alloc_flags;
+	}
+
+	for (; i < ngpios; i++) {
+		int gpio;
+		enum of_gpio_flags flags;
+
+		gpio = of_get_gpio_flags(np, i, &flags);
+		if (!gpio_is_valid(gpio)) {
+			dev_err(dev, "invalid gpio #%d: %d\n", i, gpio);
+			goto err_loop;
+		}
+
+		ret = gpio_request(gpio, dev_name(dev));
+		if (ret) {
+			dev_err(dev, "can't request gpio #%d: %d\n", i, ret);
+			goto err_loop;
+		}
+
+		pinfo->gpios[i] = gpio;
+		pinfo->alow_flags[i] = flags & OF_GPIO_ACTIVE_LOW;
+
+		ret = gpio_direction_output(pinfo->gpios[i],
+					    pinfo->alow_flags[i]);
+		if (ret) {
+			dev_err(dev, "can't set output direction for gpio "
+				"#%d: %d\n", i, ret);
+			goto err_loop;
+		}
+	}
+
+	pdata->max_chipselect = ngpios;
+	pdata->cs_control = mpc83xx_spi_cs_control;
+
+	return 0;
+
+err_loop:
+	while (i >= 0) {
+		if (gpio_is_valid(pinfo->gpios[i]))
+			gpio_free(pinfo->gpios[i]);
+		i--;
+	}
+
+	kfree(pinfo->alow_flags);
+	pinfo->alow_flags = NULL;
+err_alloc_flags:
+	kfree(pinfo->gpios);
+	pinfo->gpios = NULL;
+	return ret;
+}
+
+static int of_mpc83xx_spi_free_chipselects(struct device *dev)
+{
+	struct fsl_spi_platform_data *pdata = dev->platform_data;
+	struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(pdata);
+	int i;
+
+	if (!pinfo->gpios)
+		return 0;
+
+	for (i = 0; i < pdata->max_chipselect; i++) {
+		if (gpio_is_valid(pinfo->gpios[i]))
+			gpio_free(pinfo->gpios[i]);
+	}
+
+	kfree(pinfo->gpios);
+	kfree(pinfo->alow_flags);
+	return 0;
+}
+
+static int __devinit of_mpc83xx_spi_probe(struct of_device *ofdev,
+					  const struct of_device_id *ofid)
+{
+	struct device *dev = &ofdev->dev;
+	struct device_node *np = ofdev->node;
+	struct mpc83xx_spi_probe_info *pinfo;
+	struct fsl_spi_platform_data *pdata;
+	struct spi_master *master;
+	struct resource mem;
+	struct resource irq;
+	const void *prop;
+	int ret = -ENOMEM;
+
+	pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL);
+	if (!pinfo)
+		return -ENOMEM;
+
+	pdata = &pinfo->pdata;
+	dev->platform_data = pdata;
+
+	/* Allocate bus num dynamically. */
+	pdata->bus_num = -1;
+
+	/* SPI controller is either clocked from QE or SoC clock. */
+	pdata->sysclk = get_brgfreq();
+	if (pdata->sysclk == -1) {
+		pdata->sysclk = fsl_get_sys_freq();
+		if (pdata->sysclk == -1) {
+			ret = -ENODEV;
+			goto err_clk;
+		}
+	}
+
+	prop = of_get_property(np, "mode", NULL);
+	if (prop && !strcmp(prop, "cpu-qe"))
+		pdata->qe_mode = 1;
+
+	ret = of_mpc83xx_spi_get_chipselects(dev);
+	if (ret)
+		goto err;
+
+	ret = of_address_to_resource(np, 0, &mem);
+	if (ret)
+		goto err;
+
+	ret = of_irq_to_resource(np, 0, &irq);
+	if (!ret) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	master = mpc83xx_spi_probe(dev, &mem, irq.start);
+	if (IS_ERR(master)) {
+		ret = PTR_ERR(master);
+		goto err;
+	}
+
+	of_register_spi_devices(master, np);
+
+	return 0;
+
+err:
+	of_mpc83xx_spi_free_chipselects(dev);
+err_clk:
+	kfree(pinfo);
+	return ret;
+}
+
+static int __devexit of_mpc83xx_spi_remove(struct of_device *ofdev)
+{
+	int ret;
+
+	ret = mpc83xx_spi_remove(&ofdev->dev);
+	if (ret)
+		return ret;
+	of_mpc83xx_spi_free_chipselects(&ofdev->dev);
+	return 0;
+}
+
+static const struct of_device_id of_mpc83xx_spi_match[] = {
+	{ .compatible = "fsl,spi" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, of_mpc83xx_spi_match);
+
+static struct of_platform_driver of_mpc83xx_spi_driver = {
+	.name		= "mpc83xx_spi",
+	.match_table	= of_mpc83xx_spi_match,
+	.probe		= of_mpc83xx_spi_probe,
+	.remove		= __devexit_p(of_mpc83xx_spi_remove),
+};
+
+#ifdef CONFIG_MPC832x_RDB
+/*
+ * 				XXX XXX XXX
+ * This is "legacy" platform driver, was used by the MPC8323E-RDB boards
+ * only. The driver should go away soon, since newer MPC8323E-RDB's device
+ * tree can work with OpenFirmware driver. But for now we support old trees
+ * as well.
+ */
+static int __devinit plat_mpc83xx_spi_probe(struct platform_device *pdev)
+{
+	struct resource *mem;
+	unsigned int irq;
+	struct spi_master *master;
+
+	if (!pdev->dev.platform_data)
+		return -EINVAL;
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem)
+		return -EINVAL;
+
+	irq = platform_get_irq(pdev, 0);
+	if (!irq)
+		return -EINVAL;
+
+	master = mpc83xx_spi_probe(&pdev->dev, mem, irq);
+	if (IS_ERR(master))
+		return PTR_ERR(master);
+	return 0;
+}
+
+static int __devexit plat_mpc83xx_spi_remove(struct platform_device *pdev)
+{
+	return mpc83xx_spi_remove(&pdev->dev);
+}
+
 MODULE_ALIAS("platform:mpc83xx_spi");
 static struct platform_driver mpc83xx_spi_driver = {
-	.remove = __exit_p(mpc83xx_spi_remove),
+	.probe = plat_mpc83xx_spi_probe,
+	.remove = __exit_p(plat_mpc83xx_spi_remove),
 	.driver = {
 		.name = "mpc83xx_spi",
 		.owner = THIS_MODULE,
 	},
 };
 
+static bool legacy_driver_failed;
+
+static void __init legacy_driver_register(void)
+{
+	legacy_driver_failed = platform_driver_register(&mpc83xx_spi_driver);
+}
+
+static void __exit legacy_driver_unregister(void)
+{
+	if (legacy_driver_failed)
+		return;
+	platform_driver_unregister(&mpc83xx_spi_driver);
+}
+#else
+static void __init legacy_driver_register(void) {}
+static void __exit legacy_driver_unregister(void) {}
+#endif /* CONFIG_MPC832x_RDB */
+
 static int __init mpc83xx_spi_init(void)
 {
-	return platform_driver_probe(&mpc83xx_spi_driver, mpc83xx_spi_probe);
+	legacy_driver_register();
+	return of_register_platform_driver(&of_mpc83xx_spi_driver);
 }
 
 static void __exit mpc83xx_spi_exit(void)
 {
-	platform_driver_unregister(&mpc83xx_spi_driver);
+	of_unregister_platform_driver(&of_mpc83xx_spi_driver);
+	legacy_driver_unregister();
 }
 
 module_init(mpc83xx_spi_init);
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 742a5bc..2a70563 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -26,6 +26,7 @@
 #include <linux/tty_flip.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/seq_file.h>
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
 #include <linux/list.h>
@@ -421,57 +422,52 @@
 	return 0;
 }
 
-static int serial_read_proc(char *page, char **start, off_t off, int count,
-							int *eof, void *data)
+static int serial_proc_show(struct seq_file *m, void *v)
 {
 	struct usb_serial *serial;
-	int length = 0;
 	int i;
-	off_t begin = 0;
 	char tmp[40];
 
 	dbg("%s", __func__);
-	length += sprintf(page, "usbserinfo:1.0 driver:2.0\n");
-	for (i = 0; i < SERIAL_TTY_MINORS && length < PAGE_SIZE; ++i) {
+	seq_puts(m, "usbserinfo:1.0 driver:2.0\n");
+	for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
 		serial = usb_serial_get_by_index(i);
 		if (serial == NULL)
 			continue;
 
-		length += sprintf(page+length, "%d:", i);
+		seq_printf(m, "%d:", i);
 		if (serial->type->driver.owner)
-			length += sprintf(page+length, " module:%s",
+			seq_printf(m, " module:%s",
 				module_name(serial->type->driver.owner));
-		length += sprintf(page+length, " name:\"%s\"",
+		seq_printf(m, " name:\"%s\"",
 				serial->type->description);
-		length += sprintf(page+length, " vendor:%04x product:%04x",
+		seq_printf(m, " vendor:%04x product:%04x",
 			le16_to_cpu(serial->dev->descriptor.idVendor),
 			le16_to_cpu(serial->dev->descriptor.idProduct));
-		length += sprintf(page+length, " num_ports:%d",
-							serial->num_ports);
-		length += sprintf(page+length, " port:%d",
-							i - serial->minor + 1);
+		seq_printf(m, " num_ports:%d", serial->num_ports);
+		seq_printf(m, " port:%d", i - serial->minor + 1);
 		usb_make_path(serial->dev, tmp, sizeof(tmp));
-		length += sprintf(page+length, " path:%s", tmp);
+		seq_printf(m, " path:%s", tmp);
 
-		length += sprintf(page+length, "\n");
-		if ((length + begin) > (off + count)) {
-			usb_serial_put(serial);
-			goto done;
-		}
-		if ((length + begin) < off) {
-			begin += length;
-			length = 0;
-		}
+		seq_putc(m, '\n');
 		usb_serial_put(serial);
 	}
-	*eof = 1;
-done:
-	if (off >= (length + begin))
-		return 0;
-	*start = page + (off-begin);
-	return (count < begin+length-off) ? count : begin+length-off;
+	return 0;
 }
 
+static int serial_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, serial_proc_show, NULL);
+}
+
+static const struct file_operations serial_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= serial_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static int serial_tiocmget(struct tty_struct *tty, struct file *file)
 {
 	struct usb_serial_port *port = tty->driver_data;
@@ -1113,9 +1109,9 @@
 	.unthrottle =		serial_unthrottle,
 	.break_ctl =		serial_break,
 	.chars_in_buffer =	serial_chars_in_buffer,
-	.read_proc =		serial_read_proc,
 	.tiocmget =		serial_tiocmget,
 	.tiocmset =		serial_tiocmset,
+	.proc_fops =		&serial_proc_fops,
 };
 
 struct tty_driver *usb_serial_tty_driver;
diff --git a/drivers/video/68328fb.c b/drivers/video/68328fb.c
index 7f907fb..0b17824 100644
--- a/drivers/video/68328fb.c
+++ b/drivers/video/68328fb.c
@@ -471,9 +471,11 @@
 	fb_info.pseudo_palette = &mc68x328fb_pseudo_palette;
 	fb_info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
 
-	fb_alloc_cmap(&fb_info.cmap, 256, 0);
+	if (fb_alloc_cmap(&fb_info.cmap, 256, 0))
+		return -ENOMEM;
 
 	if (register_framebuffer(&fb_info) < 0) {
+		fb_dealloc_cmap(&fb_info.cmap);
 		return -EINVAL;
 	}
 
@@ -494,6 +496,7 @@
 static void __exit mc68x328fb_cleanup(void)
 {
 	unregister_framebuffer(&fb_info);
+	fb_dealloc_cmap(&fb_info.cmap);
 }
 
 module_exit(mc68x328fb_cleanup);
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 41c27a4..ffe2f27 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1597,32 +1597,8 @@
 	  Driver for CastleRock integrated graphics core in the
 	  VIA VT8623 [Apollo CLE266] chipset.
 
-config FB_CYBLA
-	tristate "Cyberblade/i1 support"
-	depends on FB && PCI && X86_32 && !64BIT
-	select FB_CFB_IMAGEBLIT
-	---help---
-	  This driver is supposed to support the Trident Cyberblade/i1
-	  graphics core integrated in the VIA VT8601A North Bridge,
-	  also known as VIA Apollo PLE133.
-
-	  Status:
-	   - Developed, tested and working on EPIA 5000 and EPIA 800.
-	   - Does work reliable on all systems with CRT/LCD connected to
-	     normal VGA ports.
-	   - Should work on systems that do use the internal LCD port, but
-	     this is absolutely not tested.
-
-	  Character imageblit, copyarea and rectangle fill are hw accelerated,
-	  ypan scrolling is used by default.
-
-	  Please do read <file:Documentation/fb/cyblafb/*>.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called cyblafb.
-
 config FB_TRIDENT
-	tristate "Trident support"
+	tristate "Trident/CyberXXX/CyberBlade support"
 	depends on FB && PCI
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
@@ -1633,21 +1609,14 @@
 	  and Blade XP.
 	  There are also integrated versions of these chips called CyberXXXX,
 	  CyberImage or CyberBlade. These chips are mostly found in laptops
-	  but also on some motherboards. For more information, read
-	  <file:Documentation/fb/tridentfb.txt>
+	  but also on some motherboards including early VIA EPIA motherboards.
+	  For more information, read <file:Documentation/fb/tridentfb.txt>
 
 	  Say Y if you have such a graphics board.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called tridentfb.
 
-config FB_TRIDENT_ACCEL
-	bool "Trident Acceleration functions (EXPERIMENTAL)"
-	depends on FB_TRIDENT && EXPERIMENTAL
-	---help---
-	This will compile the Trident frame buffer device with
-	acceleration functions.
-
 config FB_ARK
 	tristate "ARK 2000PV support"
 	depends on FB && PCI
@@ -1920,6 +1889,30 @@
 	depends on FB_TMIO
 	default y
 
+config FB_S3C
+	tristate "Samsung S3C framebuffer support"
+	depends on FB && ARCH_S3C64XX
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Frame buffer driver for the built-in FB controller in the Samsung
+	  SoC line from the S3C2443 onwards, including the S3C2416, S3C2450,
+	  and the S3C64XX series such as the S3C6400 and S3C6410.
+
+	  These chips all have the same basic framebuffer design with the
+	  actual capabilities depending on the chip. For instance the S3C6400
+	  and S3C6410 support 4 hardware windows whereas the S3C24XX series
+	  currently only have two.
+
+	  Currently the support is only for the S3C6400 and S3C6410 SoCs.
+
+config FB_S3C_DEBUG_REGWRITE
+       bool "Debug register writes"
+       depends on FB_S3C
+       ---help---
+         Show all register writes via printk(KERN_DEBUG)
+
 config FB_S3C2410
 	tristate "S3C2410 LCD framebuffer support"
 	depends on FB && ARCH_S3C2410
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index bb265ec..0dbd6c6 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -76,6 +76,7 @@
                                      atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o
 obj-$(CONFIG_FB_MAC)              += macfb.o
 obj-$(CONFIG_FB_HECUBA)           += hecubafb.o
+obj-$(CONFIG_FB_N411)             += n411.o
 obj-$(CONFIG_FB_HGA)              += hgafb.o
 obj-$(CONFIG_FB_XVR500)           += sunxvr500.o
 obj-$(CONFIG_FB_XVR2500)          += sunxvr2500.o
@@ -110,6 +111,7 @@
 obj-$(CONFIG_FB_S1D13XXX)	  += s1d13xxxfb.o
 obj-$(CONFIG_FB_SH7760)		  += sh7760fb.o
 obj-$(CONFIG_FB_IMX)              += imxfb.o
+obj-$(CONFIG_FB_S3C)		  += s3c-fb.o
 obj-$(CONFIG_FB_S3C2410)	  += s3c2410fb.o
 obj-$(CONFIG_FB_FSL_DIU)	  += fsl-diu-fb.o
 obj-$(CONFIG_FB_COBALT)           += cobalt_lcdfb.o
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index 4e046fe..61050ab 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -408,7 +408,9 @@
 	/*
 	 * Allocate colourmap.
 	 */
-	fb_alloc_cmap(&fb->fb.cmap, 256, 0);
+	ret = fb_alloc_cmap(&fb->fb.cmap, 256, 0);
+	if (ret)
+		goto unmap;
 
 	/*
 	 * Ensure interrupts are disabled.
@@ -426,6 +428,8 @@
 
 	printk(KERN_ERR "CLCD: cannot register framebuffer (%d)\n", ret);
 
+	fb_dealloc_cmap(&fb->fb.cmap);
+ unmap:
 	iounmap(fb->regs);
  free_clk:
 	clk_put(fb->clk);
@@ -485,6 +489,8 @@
 
 	clcdfb_disable(fb);
 	unregister_framebuffer(&fb->fb);
+	if (fb->fb.cmap.len)
+		fb_dealloc_cmap(&fb->fb.cmap);
 	iounmap(fb->regs);
 	clk_put(fb->clk);
 
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 100f236..82bedd7 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -2437,7 +2437,9 @@
 		goto amifb_error;
 	}
 
-	fb_alloc_cmap(&fb_info.cmap, 1<<fb_info.var.bits_per_pixel, 0);
+	err = fb_alloc_cmap(&fb_info.cmap, 1<<fb_info.var.bits_per_pixel, 0);
+	if (err)
+		goto amifb_error;
 
 	if (register_framebuffer(&fb_info) < 0) {
 		err = -EINVAL;
@@ -2456,7 +2458,8 @@
 
 static void amifb_deinit(void)
 {
-	fb_dealloc_cmap(&fb_info.cmap);
+	if (fb_info.cmap.len)
+		fb_dealloc_cmap(&fb_info.cmap);
 	chipfree();
 	if (videomemory)
 		iounmap((void*)videomemory);
diff --git a/drivers/video/arkfb.c b/drivers/video/arkfb.c
index 314d186..d583bea 100644
--- a/drivers/video/arkfb.c
+++ b/drivers/video/arkfb.c
@@ -470,7 +470,7 @@
 
 	while (count != 0)
 	{
-		vga_wseq(NULL, 0x1C, regval | (code[0] & 4) ? 0x80 : 0);
+		vga_wseq(NULL, 0x1C, regval | (code[0] & 4 ? 0x80 : 0));
 		code[1] = vga_r(NULL, dac_regs[code[0] & 3]);
 		count--;
 		code += 2;
@@ -485,7 +485,7 @@
 
 	while (count != 0)
 	{
-		vga_wseq(NULL, 0x1C, regval | (code[0] & 4) ? 0x80 : 0);
+		vga_wseq(NULL, 0x1C, regval | (code[0] & 4 ? 0x80 : 0));
 		vga_w(NULL, dac_regs[code[0] & 3], code[1]);
 		count--;
 		code += 2;
diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c
index 1fd22f4..1a1f946 100644
--- a/drivers/video/asiliantfb.c
+++ b/drivers/video/asiliantfb.c
@@ -505,19 +505,27 @@
 	.vsync_len 	= 2,
 };
 
-static void __devinit init_asiliant(struct fb_info *p, unsigned long addr)
+static int __devinit init_asiliant(struct fb_info *p, unsigned long addr)
 {
+	int err;
+
 	p->fix			= asiliantfb_fix;
 	p->fix.smem_start	= addr;
 	p->var			= asiliantfb_var;
 	p->fbops		= &asiliantfb_ops;
 	p->flags		= FBINFO_DEFAULT;
 
-	fb_alloc_cmap(&p->cmap, 256, 0);
+	err = fb_alloc_cmap(&p->cmap, 256, 0);
+	if (err) {
+		printk(KERN_ERR "C&T 69000 fb failed to alloc cmap memory\n");
+		return err;
+	}
 
-	if (register_framebuffer(p) < 0) {
+	err = register_framebuffer(p);
+	if (err < 0) {
 		printk(KERN_ERR "C&T 69000 framebuffer failed to register\n");
-		return;
+		fb_dealloc_cmap(&p->cmap);
+		return err;
 	}
 
 	printk(KERN_INFO "fb%d: Asiliant 69000 frame buffer (%dK RAM detected)\n",
@@ -532,6 +540,7 @@
 {
 	unsigned long addr, size;
 	struct fb_info *p;
+	int err;
 
 	if ((dp->resource[0].flags & IORESOURCE_MEM) == 0)
 		return -ENODEV;
@@ -560,7 +569,13 @@
 	pci_write_config_dword(dp, 4, 0x02800083);
 	writeb(3, p->screen_base + 0x400784);
 
-	init_asiliant(p, addr);
+	err = init_asiliant(p, addr);
+	if (err) {
+		iounmap(p->screen_base);
+		release_mem_region(addr, size);
+		framebuffer_release(p);
+		return err;
+	}
 
 	pci_set_drvdata(dp, p);
 	return 0;
@@ -571,6 +586,7 @@
 	struct fb_info *p = pci_get_drvdata(dp);
 
 	unregister_framebuffer(p);
+	fb_dealloc_cmap(&p->cmap);
 	iounmap(p->screen_base);
 	release_mem_region(pci_resource_start(dp, 0), pci_resource_len(dp, 0));
 	pci_set_drvdata(dp, NULL);
diff --git a/drivers/video/aty/mach64_accel.c b/drivers/video/aty/mach64_accel.c
index a8f60c3..0cc9724 100644
--- a/drivers/video/aty/mach64_accel.c
+++ b/drivers/video/aty/mach64_accel.c
@@ -39,7 +39,8 @@
 {
 	/* reset engine */
 	aty_st_le32(GEN_TEST_CNTL,
-		aty_ld_le32(GEN_TEST_CNTL, par) & ~GUI_ENGINE_ENABLE, par);
+		aty_ld_le32(GEN_TEST_CNTL, par) &
+		~(GUI_ENGINE_ENABLE | HWCURSOR_ENABLE), par);
 	/* enable engine */
 	aty_st_le32(GEN_TEST_CNTL,
 		aty_ld_le32(GEN_TEST_CNTL, par) | GUI_ENGINE_ENABLE, par);
diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/aty/mach64_cursor.c
index faf95da..04c710804 100644
--- a/drivers/video/aty/mach64_cursor.c
+++ b/drivers/video/aty/mach64_cursor.c
@@ -77,9 +77,13 @@
 	if (par->asleep)
 		return -EPERM;
 
-	/* Hide cursor */
 	wait_for_fifo(1, par);
-	aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par) & ~HWCURSOR_ENABLE, par);
+	if (cursor->enable)
+		aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par)
+			    | HWCURSOR_ENABLE, par);
+	else
+		aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par)
+				& ~HWCURSOR_ENABLE, par);
 
 	/* set position */
 	if (cursor->set & FB_CUR_SETPOS) {
@@ -109,7 +113,7 @@
 			y<<=1;
 			h<<=1;
 		}
-		wait_for_fifo(4, par);
+		wait_for_fifo(3, par);
 		aty_st_le32(CUR_OFFSET, (info->fix.smem_len >> 3) + (yoff << 1), par);
 		aty_st_le32(CUR_HORZ_VERT_OFF,
 			    ((u32) (64 - h + yoff) << 16) | xoff, par);
@@ -177,11 +181,6 @@
 	    }
 	}
 
-	if (cursor->enable) {
-		wait_for_fifo(1, par);
-		aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par)
-			    | HWCURSOR_ENABLE, par);
-	}
 	return 0;
 }
 
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index 1de0c00..97a1f09 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -89,6 +89,9 @@
 	BUGFIX("Acer Aspire 2010",
 	       PCI_VENDOR_ID_AI, 0x0061,
 	       radeon_pm_off, radeon_reinitialize_M10),
+	BUGFIX("Acer Travelmate 290D/292LMi",
+	       PCI_VENDOR_ID_AI, 0x005a,
+	       radeon_pm_off, radeon_reinitialize_M10),
 	{ .ident = NULL }
 };
 
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 157057c..dd37cbc 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -35,6 +35,8 @@
 		return 0;
 
 	bd = container_of(self, struct backlight_device, fb_notif);
+	if (!lock_fb_info(evdata->info))
+		return -ENODEV;
 	mutex_lock(&bd->ops_lock);
 	if (bd->ops)
 		if (!bd->ops->check_fb ||
@@ -47,6 +49,7 @@
 			backlight_update_status(bd);
 		}
 	mutex_unlock(&bd->ops_lock);
+	unlock_fb_info(evdata->info);
 	return 0;
 }
 
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index b6449470..0bb13df 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -40,6 +40,8 @@
 	if (!ld->ops)
 		return 0;
 
+	if (!lock_fb_info(evdata->info))
+		return -ENODEV;
 	mutex_lock(&ld->ops_lock);
 	if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) {
 		if (event == FB_EVENT_BLANK) {
@@ -51,6 +53,7 @@
 		}
 	}
 	mutex_unlock(&ld->ops_lock);
+	unlock_fb_info(evdata->info);
 	return 0;
 }
 
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index a2aa6dd..d42e385 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -34,8 +34,6 @@
  *
  */
 
-#define CIRRUSFB_VERSION "2.0-pre2"
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -72,20 +70,9 @@
  *
  */
 
-/* enable debug output? */
-/* #define CIRRUSFB_DEBUG 1 */
-
 /* disable runtime assertions? */
 /* #define CIRRUSFB_NDEBUG */
 
-/* debug output */
-#ifdef CIRRUSFB_DEBUG
-#define DPRINTK(fmt, args...) \
-	printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
-#else
-#define DPRINTK(fmt, args...)
-#endif
-
 /* debugging assertions */
 #ifndef CIRRUSFB_NDEBUG
 #define assert(expr) \
@@ -108,14 +95,15 @@
 /* board types */
 enum cirrus_board {
 	BT_NONE = 0,
-	BT_SD64,
-	BT_PICCOLO,
-	BT_PICASSO,
-	BT_SPECTRUM,
+	BT_SD64,	/* GD5434 */
+	BT_PICCOLO,	/* GD5426 */
+	BT_PICASSO,	/* GD5426 or GD5428 */
+	BT_SPECTRUM,	/* GD5426 or GD5428 */
 	BT_PICASSO4,	/* GD5446 */
 	BT_ALPINE,	/* GD543x/4x */
 	BT_GD5480,
-	BT_LAGUNA,	/* GD546x */
+	BT_LAGUNA,	/* GD5462/64 */
+	BT_LAGUNAB,	/* GD5465 */
 };
 
 /*
@@ -150,15 +138,17 @@
 		.maxclock		= {
 			/* guess */
 			/* the SD64/P4 have a higher max. videoclock */
-			140000, 140000, 140000, 140000, 140000,
+			135100, 135100, 85500, 85500, 0
 		},
 		.init_sr07		= true,
 		.init_sr1f		= true,
 		.scrn_start_bit19	= true,
 		.sr07			= 0xF0,
 		.sr07_1bpp		= 0xF0,
+		.sr07_1bpp_mux		= 0xF6,
 		.sr07_8bpp		= 0xF1,
-		.sr1f			= 0x20
+		.sr07_8bpp_mux		= 0xF7,
+		.sr1f			= 0x1E
 	},
 	[BT_PICCOLO] = {
 		.name			= "CL Piccolo",
@@ -210,9 +200,11 @@
 		.init_sr07		= true,
 		.init_sr1f		= false,
 		.scrn_start_bit19	= true,
-		.sr07			= 0x20,
-		.sr07_1bpp		= 0x20,
-		.sr07_8bpp		= 0x21,
+		.sr07			= 0xA0,
+		.sr07_1bpp		= 0xA0,
+		.sr07_1bpp_mux		= 0xA6,
+		.sr07_8bpp		= 0xA1,
+		.sr07_8bpp_mux		= 0xA7,
 		.sr1f			= 0
 	},
 	[BT_ALPINE] = {
@@ -225,8 +217,8 @@
 		.init_sr1f		= true,
 		.scrn_start_bit19	= true,
 		.sr07			= 0xA0,
-		.sr07_1bpp		= 0xA1,
-		.sr07_1bpp_mux		= 0xA7,
+		.sr07_1bpp		= 0xA0,
+		.sr07_1bpp_mux		= 0xA6,
 		.sr07_8bpp		= 0xA1,
 		.sr07_8bpp_mux		= 0xA7,
 		.sr1f			= 0x1C
@@ -247,8 +239,18 @@
 	[BT_LAGUNA] = {
 		.name			= "CL Laguna",
 		.maxclock		= {
-			/* guess */
-			135100, 135100, 135100, 135100, 135100,
+			/* taken from X11 code */
+			170000, 170000, 170000, 170000, 135100,
+		},
+		.init_sr07		= false,
+		.init_sr1f		= false,
+		.scrn_start_bit19	= true,
+	},
+	[BT_LAGUNAB] = {
+		.name			= "CL Laguna AGP",
+		.maxclock		= {
+			/* taken from X11 code */
+			170000, 250000, 170000, 170000, 135100,
 		},
 		.init_sr07		= false,
 		.init_sr1f		= false,
@@ -262,8 +264,8 @@
 
 static struct pci_device_id cirrusfb_pci_table[] = {
 	CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE),
-	CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE),
-	CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE),
+	CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_SD64),
+	CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_SD64),
 	CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */
 	CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE),
 	CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE),
@@ -271,7 +273,7 @@
 	CHIP(PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4), /* Picasso 4 is 5446 */
 	CHIP(PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA), /* CL Laguna */
 	CHIP(PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA), /* CL Laguna 3D */
-	CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNA), /* CL Laguna 3DA*/
+	CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNAB), /* CL Laguna 3DA*/
 	{ 0, }
 };
 MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
@@ -326,10 +328,6 @@
 };
 #endif /* CONFIG_ZORRO */
 
-struct cirrusfb_regs {
-	int multiplexing;
-};
-
 #ifdef CIRRUSFB_DEBUG
 enum cirrusfb_dbg_reg_class {
 	CRT,
@@ -340,10 +338,12 @@
 /* info about board */
 struct cirrusfb_info {
 	u8 __iomem *regbase;
+	u8 __iomem *laguna_mmio;
 	enum cirrus_board btype;
 	unsigned char SFR;	/* Shadow of special function register */
 
-	struct cirrusfb_regs currentmode;
+	int multiplexing;
+	int doubleVCLK;
 	int blank_mode;
 	u32 pseudo_palette[16];
 
@@ -357,43 +357,8 @@
 /**** BEGIN PROTOTYPES ******************************************************/
 
 /*--- Interface used by the world ------------------------------------------*/
-static int cirrusfb_init(void);
-#ifndef MODULE
-static int cirrusfb_setup(char *options);
-#endif
-
-static int cirrusfb_open(struct fb_info *info, int user);
-static int cirrusfb_release(struct fb_info *info, int user);
-static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
-			      unsigned blue, unsigned transp,
-			      struct fb_info *info);
-static int cirrusfb_check_var(struct fb_var_screeninfo *var,
-			      struct fb_info *info);
-static int cirrusfb_set_par(struct fb_info *info);
 static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
 				struct fb_info *info);
-static int cirrusfb_blank(int blank_mode, struct fb_info *info);
-static void cirrusfb_fillrect(struct fb_info *info,
-			      const struct fb_fillrect *region);
-static void cirrusfb_copyarea(struct fb_info *info,
-			      const struct fb_copyarea *area);
-static void cirrusfb_imageblit(struct fb_info *info,
-			       const struct fb_image *image);
-
-/* function table of the above functions */
-static struct fb_ops cirrusfb_ops = {
-	.owner		= THIS_MODULE,
-	.fb_open	= cirrusfb_open,
-	.fb_release	= cirrusfb_release,
-	.fb_setcolreg	= cirrusfb_setcolreg,
-	.fb_check_var	= cirrusfb_check_var,
-	.fb_set_par	= cirrusfb_set_par,
-	.fb_pan_display = cirrusfb_pan_display,
-	.fb_blank	= cirrusfb_blank,
-	.fb_fillrect	= cirrusfb_fillrect,
-	.fb_copyarea	= cirrusfb_copyarea,
-	.fb_imageblit	= cirrusfb_imageblit,
-};
 
 /*--- Internal routines ----------------------------------------------------*/
 static void init_vgachip(struct fb_info *info);
@@ -421,22 +386,27 @@
 static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
 			      u_short x, u_short y,
 			      u_short width, u_short height,
-			      u_char color, u_short line_length);
+			      u32 fg_color, u32 bg_color,
+			      u_short line_length, u_char blitmode);
 
 static void bestclock(long freq, int *nom, int *den, int *div);
 
 #ifdef CIRRUSFB_DEBUG
-static void cirrusfb_dump(void);
-static void cirrusfb_dbg_reg_dump(caddr_t regbase);
-static void cirrusfb_dbg_print_regs(caddr_t regbase,
+static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase);
+static void cirrusfb_dbg_print_regs(struct fb_info *info,
+				    caddr_t regbase,
 				    enum cirrusfb_dbg_reg_class reg_class, ...);
-static void cirrusfb_dbg_print_byte(const char *name, unsigned char val);
 #endif /* CIRRUSFB_DEBUG */
 
 /*** END   PROTOTYPES ********************************************************/
 /*****************************************************************************/
 /*** BEGIN Interface Used by the World ***************************************/
 
+static inline int is_laguna(const struct cirrusfb_info *cinfo)
+{
+	return cinfo->btype == BT_LAGUNA || cinfo->btype == BT_LAGUNAB;
+}
+
 static int opencount;
 
 /*--- Open /dev/fbx ---------------------------------------------------------*/
@@ -460,85 +430,94 @@
 /**** BEGIN Hardware specific Routines **************************************/
 
 /* Check if the MCLK is not a better clock source */
-static int cirrusfb_check_mclk(struct cirrusfb_info *cinfo, long freq)
+static int cirrusfb_check_mclk(struct fb_info *info, long freq)
 {
+	struct cirrusfb_info *cinfo = info->par;
 	long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f;
 
 	/* Read MCLK value */
 	mclk = (14318 * mclk) >> 3;
-	DPRINTK("Read MCLK of %ld kHz\n", mclk);
+	dev_dbg(info->device, "Read MCLK of %ld kHz\n", mclk);
 
 	/* Determine if we should use MCLK instead of VCLK, and if so, what we
 	 * should divide it by to get VCLK
 	 */
 
 	if (abs(freq - mclk) < 250) {
-		DPRINTK("Using VCLK = MCLK\n");
+		dev_dbg(info->device, "Using VCLK = MCLK\n");
 		return 1;
 	} else if (abs(freq - (mclk / 2)) < 250) {
-		DPRINTK("Using VCLK = MCLK/2\n");
+		dev_dbg(info->device, "Using VCLK = MCLK/2\n");
 		return 2;
 	}
 
 	return 0;
 }
 
+static int cirrusfb_check_pixclock(const struct fb_var_screeninfo *var,
+				   struct fb_info *info)
+{
+	long freq;
+	long maxclock;
+	struct cirrusfb_info *cinfo = info->par;
+	unsigned maxclockidx = var->bits_per_pixel >> 3;
+
+	/* convert from ps to kHz */
+	freq = PICOS2KHZ(var->pixclock);
+
+	dev_dbg(info->device, "desired pixclock: %ld kHz\n", freq);
+
+	maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
+	cinfo->multiplexing = 0;
+
+	/* If the frequency is greater than we can support, we might be able
+	 * to use multiplexing for the video mode */
+	if (freq > maxclock) {
+		dev_err(info->device,
+			"Frequency greater than maxclock (%ld kHz)\n",
+			maxclock);
+		return -EINVAL;
+	}
+	/*
+	 * Additional constraint: 8bpp uses DAC clock doubling to allow maximum
+	 * pixel clock
+	 */
+	if (var->bits_per_pixel == 8) {
+		switch (cinfo->btype) {
+		case BT_ALPINE:
+		case BT_SD64:
+		case BT_PICASSO4:
+			if (freq > 85500)
+				cinfo->multiplexing = 1;
+			break;
+		case BT_GD5480:
+			if (freq > 135100)
+				cinfo->multiplexing = 1;
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	/* If we have a 1MB 5434, we need to put ourselves in a mode where
+	 * the VCLK is double the pixel clock. */
+	cinfo->doubleVCLK = 0;
+	if (cinfo->btype == BT_SD64 && info->fix.smem_len <= MB_ &&
+	    var->bits_per_pixel == 16) {
+		cinfo->doubleVCLK = 1;
+	}
+
+	return 0;
+}
+
 static int cirrusfb_check_var(struct fb_var_screeninfo *var,
 			      struct fb_info *info)
 {
 	int yres;
 	/* memory size in pixels */
 	unsigned pixels = info->screen_size * 8 / var->bits_per_pixel;
-
-	switch (var->bits_per_pixel) {
-	case 1:
-		pixels /= 4;
-		break;		/* 8 pixel per byte, only 1/4th of mem usable */
-	case 8:
-	case 16:
-	case 32:
-		break;		/* 1 pixel == 1 byte */
-	default:
-		printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected..."
-			"color depth not supported.\n",
-			var->xres, var->yres, var->bits_per_pixel);
-		DPRINTK("EXIT - EINVAL error\n");
-		return -EINVAL;
-	}
-
-	if (var->xres_virtual < var->xres)
-		var->xres_virtual = var->xres;
-	/* use highest possible virtual resolution */
-	if (var->yres_virtual == -1) {
-		var->yres_virtual = pixels / var->xres_virtual;
-
-		printk(KERN_INFO "cirrusfb: virtual resolution set to "
-			"maximum of %dx%d\n", var->xres_virtual,
-			var->yres_virtual);
-	}
-	if (var->yres_virtual < var->yres)
-		var->yres_virtual = var->yres;
-
-	if (var->xres_virtual * var->yres_virtual > pixels) {
-		printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected... "
-		      "virtual resolution too high to fit into video memory!\n",
-			var->xres_virtual, var->yres_virtual,
-			var->bits_per_pixel);
-		DPRINTK("EXIT - EINVAL error\n");
-		return -EINVAL;
-	}
-
-
-	if (var->xoffset < 0)
-		var->xoffset = 0;
-	if (var->yoffset < 0)
-		var->yoffset = 0;
-
-	/* truncate xoffset and yoffset to maximum if too high */
-	if (var->xoffset > var->xres_virtual - var->xres)
-		var->xoffset = var->xres_virtual - var->xres - 1;
-	if (var->yoffset > var->yres_virtual - var->yres)
-		var->yoffset = var->yres_virtual - var->yres - 1;
+	struct cirrusfb_info *cinfo = info->par;
 
 	switch (var->bits_per_pixel) {
 	case 1:
@@ -550,7 +529,7 @@
 
 	case 8:
 		var->red.offset = 0;
-		var->red.length = 6;
+		var->red.length = 8;
 		var->green = var->red;
 		var->blue = var->red;
 		break;
@@ -561,20 +540,20 @@
 			var->green.offset = -3;
 			var->blue.offset = 8;
 		} else {
-			var->red.offset = 10;
+			var->red.offset = 11;
 			var->green.offset = 5;
 			var->blue.offset = 0;
 		}
 		var->red.length = 5;
-		var->green.length = 5;
+		var->green.length = 6;
 		var->blue.length = 5;
 		break;
 
-	case 32:
+	case 24:
 		if (isPReP) {
-			var->red.offset = 8;
-			var->green.offset = 16;
-			var->blue.offset = 24;
+			var->red.offset = 0;
+			var->green.offset = 8;
+			var->blue.offset = 16;
 		} else {
 			var->red.offset = 16;
 			var->green.offset = 8;
@@ -586,12 +565,45 @@
 		break;
 
 	default:
-		DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel);
+		dev_dbg(info->device,
+			"Unsupported bpp size: %d\n", var->bits_per_pixel);
 		assert(false);
 		/* should never occur */
 		break;
 	}
 
+	if (var->xres_virtual < var->xres)
+		var->xres_virtual = var->xres;
+	/* use highest possible virtual resolution */
+	if (var->yres_virtual == -1) {
+		var->yres_virtual = pixels / var->xres_virtual;
+
+		dev_info(info->device,
+			 "virtual resolution set to maximum of %dx%d\n",
+			 var->xres_virtual, var->yres_virtual);
+	}
+	if (var->yres_virtual < var->yres)
+		var->yres_virtual = var->yres;
+
+	if (var->xres_virtual * var->yres_virtual > pixels) {
+		dev_err(info->device, "mode %dx%dx%d rejected... "
+		      "virtual resolution too high to fit into video memory!\n",
+			var->xres_virtual, var->yres_virtual,
+			var->bits_per_pixel);
+		return -EINVAL;
+	}
+
+	if (var->xoffset < 0)
+		var->xoffset = 0;
+	if (var->yoffset < 0)
+		var->yoffset = 0;
+
+	/* truncate xoffset and yoffset to maximum if too high */
+	if (var->xoffset > var->xres_virtual - var->xres)
+		var->xoffset = var->xres_virtual - var->xres - 1;
+	if (var->yoffset > var->yres_virtual - var->yres)
+		var->yoffset = var->yres_virtual - var->yres - 1;
+
 	var->red.msb_right =
 	    var->green.msb_right =
 	    var->blue.msb_right =
@@ -606,99 +618,31 @@
 		yres = (yres + 1) / 2;
 
 	if (yres >= 1280) {
-		printk(KERN_ERR "cirrusfb: ERROR: VerticalTotal >= 1280; "
+		dev_err(info->device, "ERROR: VerticalTotal >= 1280; "
 			"special treatment required! (TODO)\n");
-		DPRINTK("EXIT - EINVAL error\n");
 		return -EINVAL;
 	}
 
+	if (cirrusfb_check_pixclock(var, info))
+		return -EINVAL;
+
+	if (!is_laguna(cinfo))
+		var->accel_flags = FB_ACCELF_TEXT;
+
 	return 0;
 }
 
-static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
-				struct cirrusfb_regs *regs,
-				struct fb_info *info)
+static void cirrusfb_set_mclk_as_source(const struct fb_info *info, int div)
 {
-	long freq;
-	long maxclock;
-	int maxclockidx = var->bits_per_pixel >> 3;
 	struct cirrusfb_info *cinfo = info->par;
-
-	switch (var->bits_per_pixel) {
-	case 1:
-		info->fix.line_length = var->xres_virtual / 8;
-		info->fix.visual = FB_VISUAL_MONO10;
-		break;
-
-	case 8:
-		info->fix.line_length = var->xres_virtual;
-		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
-		break;
-
-	case 16:
-	case 32:
-		info->fix.line_length = var->xres_virtual * maxclockidx;
-		info->fix.visual = FB_VISUAL_TRUECOLOR;
-		break;
-
-	default:
-		DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel);
-		assert(false);
-		/* should never occur */
-		break;
-	}
-
-	info->fix.type = FB_TYPE_PACKED_PIXELS;
-
-	/* convert from ps to kHz */
-	freq = PICOS2KHZ(var->pixclock);
-
-	DPRINTK("desired pixclock: %ld kHz\n", freq);
-
-	maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
-	regs->multiplexing = 0;
-
-	/* If the frequency is greater than we can support, we might be able
-	 * to use multiplexing for the video mode */
-	if (freq > maxclock) {
-		switch (cinfo->btype) {
-		case BT_ALPINE:
-		case BT_GD5480:
-			regs->multiplexing = 1;
-			break;
-
-		default:
-			printk(KERN_ERR "cirrusfb: Frequency greater "
-				"than maxclock (%ld kHz)\n", maxclock);
-			DPRINTK("EXIT - return -EINVAL\n");
-			return -EINVAL;
-		}
-	}
-#if 0
-	/* TODO: If we have a 1MB 5434, we need to put ourselves in a mode where
-	 * the VCLK is double the pixel clock. */
-	switch (var->bits_per_pixel) {
-	case 16:
-	case 32:
-		if (var->xres <= 800)
-			/* Xbh has this type of clock for 32-bit */
-			freq /= 2;
-		break;
-	}
-#endif
-	return 0;
-}
-
-static void cirrusfb_set_mclk_as_source(const struct cirrusfb_info *cinfo,
-					int div)
-{
 	unsigned char old1f, old1e;
+
 	assert(cinfo != NULL);
 	old1f = vga_rseq(cinfo->regbase, CL_SEQR1F) & ~0x40;
 
 	if (div) {
-		DPRINTK("Set %s as pixclock source.\n",
-					(div == 2) ? "MCLK/2" : "MCLK");
+		dev_dbg(info->device, "Set %s as pixclock source.\n",
+			(div == 2) ? "MCLK/2" : "MCLK");
 		old1f |= 0x40;
 		old1e = vga_rseq(cinfo->regbase, CL_SEQR1E) & ~0x1;
 		if (div == 2)
@@ -718,101 +662,119 @@
 {
 	struct cirrusfb_info *cinfo = info->par;
 	struct fb_var_screeninfo *var = &info->var;
-	struct cirrusfb_regs regs;
 	u8 __iomem *regbase = cinfo->regbase;
 	unsigned char tmp;
-	int offset = 0, err;
+	int pitch;
 	const struct cirrusfb_board_info_rec *bi;
 	int hdispend, hsyncstart, hsyncend, htotal;
 	int yres, vdispend, vsyncstart, vsyncend, vtotal;
 	long freq;
 	int nom, den, div;
+	unsigned int control = 0, format = 0, threshold = 0;
 
-	DPRINTK("ENTER\n");
-	DPRINTK("Requested mode: %dx%dx%d\n",
+	dev_dbg(info->device, "Requested mode: %dx%dx%d\n",
 	       var->xres, var->yres, var->bits_per_pixel);
-	DPRINTK("pixclock: %d\n", var->pixclock);
+
+	switch (var->bits_per_pixel) {
+	case 1:
+		info->fix.line_length = var->xres_virtual / 8;
+		info->fix.visual = FB_VISUAL_MONO10;
+		break;
+
+	case 8:
+		info->fix.line_length = var->xres_virtual;
+		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+		break;
+
+	case 16:
+	case 24:
+		info->fix.line_length = var->xres_virtual *
+					var->bits_per_pixel >> 3;
+		info->fix.visual = FB_VISUAL_TRUECOLOR;
+		break;
+	}
+	info->fix.type = FB_TYPE_PACKED_PIXELS;
 
 	init_vgachip(info);
 
-	err = cirrusfb_decode_var(var, &regs, info);
-	if (err) {
-		/* should never happen */
-		DPRINTK("mode change aborted.  invalid var.\n");
-		return -EINVAL;
-	}
-
 	bi = &cirrusfb_board_info[cinfo->btype];
 
 	hsyncstart = var->xres + var->right_margin;
 	hsyncend = hsyncstart + var->hsync_len;
-	htotal = (hsyncend + var->left_margin) / 8 - 5;
-	hdispend = var->xres / 8 - 1;
-	hsyncstart = hsyncstart / 8 + 1;
-	hsyncend = hsyncend / 8 + 1;
+	htotal = (hsyncend + var->left_margin) / 8;
+	hdispend = var->xres / 8;
+	hsyncstart = hsyncstart / 8;
+	hsyncend = hsyncend / 8;
 
-	yres = var->yres;
-	vsyncstart = yres + var->lower_margin;
+	vdispend = var->yres;
+	vsyncstart = vdispend + var->lower_margin;
 	vsyncend = vsyncstart + var->vsync_len;
 	vtotal = vsyncend + var->upper_margin;
-	vdispend = yres - 1;
 
 	if (var->vmode & FB_VMODE_DOUBLE) {
-		yres *= 2;
+		vdispend *= 2;
 		vsyncstart *= 2;
 		vsyncend *= 2;
 		vtotal *= 2;
 	} else if (var->vmode & FB_VMODE_INTERLACED) {
-		yres = (yres + 1) / 2;
+		vdispend = (vdispend + 1) / 2;
 		vsyncstart = (vsyncstart + 1) / 2;
 		vsyncend = (vsyncend + 1) / 2;
 		vtotal = (vtotal + 1) / 2;
 	}
-
-	vtotal -= 2;
-	vsyncstart -= 1;
-	vsyncend -= 1;
-
+	yres = vdispend;
 	if (yres >= 1024) {
 		vtotal /= 2;
 		vsyncstart /= 2;
 		vsyncend /= 2;
 		vdispend /= 2;
 	}
-	if (regs.multiplexing) {
+
+	vdispend -= 1;
+	vsyncstart -= 1;
+	vsyncend -= 1;
+	vtotal -= 2;
+
+	if (cinfo->multiplexing) {
 		htotal /= 2;
 		hsyncstart /= 2;
 		hsyncend /= 2;
 		hdispend /= 2;
 	}
+
+	htotal -= 5;
+	hdispend -= 1;
+	hsyncstart += 1;
+	hsyncend += 1;
+
 	/* unlock register VGA_CRTC_H_TOTAL..CRT7 */
 	vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20);	/* previously: 0x00) */
 
 	/* if debugging is enabled, all parameters get output before writing */
-	DPRINTK("CRT0: %d\n", htotal);
+	dev_dbg(info->device, "CRT0: %d\n", htotal);
 	vga_wcrt(regbase, VGA_CRTC_H_TOTAL, htotal);
 
-	DPRINTK("CRT1: %d\n", hdispend);
+	dev_dbg(info->device, "CRT1: %d\n", hdispend);
 	vga_wcrt(regbase, VGA_CRTC_H_DISP, hdispend);
 
-	DPRINTK("CRT2: %d\n", var->xres / 8);
+	dev_dbg(info->device, "CRT2: %d\n", var->xres / 8);
 	vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, var->xres / 8);
 
 	/*  + 128: Compatible read */
-	DPRINTK("CRT3: 128+%d\n", (htotal + 5) % 32);
+	dev_dbg(info->device, "CRT3: 128+%d\n", (htotal + 5) % 32);
 	vga_wcrt(regbase, VGA_CRTC_H_BLANK_END,
 		 128 + ((htotal + 5) % 32));
 
-	DPRINTK("CRT4: %d\n", hsyncstart);
+	dev_dbg(info->device, "CRT4: %d\n", hsyncstart);
 	vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, hsyncstart);
 
 	tmp = hsyncend % 32;
 	if ((htotal + 5) & 32)
 		tmp += 128;
-	DPRINTK("CRT5: %d\n", tmp);
+	dev_dbg(info->device, "CRT5: %d\n", tmp);
 	vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp);
 
-	DPRINTK("CRT6: %d\n", vtotal & 0xff);
+	dev_dbg(info->device, "CRT6: %d\n", vtotal & 0xff);
 	vga_wcrt(regbase, VGA_CRTC_V_TOTAL, vtotal & 0xff);
 
 	tmp = 16;		/* LineCompare bit #9 */
@@ -830,7 +792,7 @@
 		tmp |= 64;
 	if (vsyncstart & 512)
 		tmp |= 128;
-	DPRINTK("CRT7: %d\n", tmp);
+	dev_dbg(info->device, "CRT7: %d\n", tmp);
 	vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp);
 
 	tmp = 0x40;		/* LineCompare bit #8 */
@@ -838,25 +800,25 @@
 		tmp |= 0x20;
 	if (var->vmode & FB_VMODE_DOUBLE)
 		tmp |= 0x80;
-	DPRINTK("CRT9: %d\n", tmp);
+	dev_dbg(info->device, "CRT9: %d\n", tmp);
 	vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp);
 
-	DPRINTK("CRT10: %d\n", vsyncstart & 0xff);
+	dev_dbg(info->device, "CRT10: %d\n", vsyncstart & 0xff);
 	vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, vsyncstart & 0xff);
 
-	DPRINTK("CRT11: 64+32+%d\n", vsyncend % 16);
+	dev_dbg(info->device, "CRT11: 64+32+%d\n", vsyncend % 16);
 	vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, vsyncend % 16 + 64 + 32);
 
-	DPRINTK("CRT12: %d\n", vdispend & 0xff);
+	dev_dbg(info->device, "CRT12: %d\n", vdispend & 0xff);
 	vga_wcrt(regbase, VGA_CRTC_V_DISP_END, vdispend & 0xff);
 
-	DPRINTK("CRT15: %d\n", (vdispend + 1) & 0xff);
+	dev_dbg(info->device, "CRT15: %d\n", (vdispend + 1) & 0xff);
 	vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, (vdispend + 1) & 0xff);
 
-	DPRINTK("CRT16: %d\n", vtotal & 0xff);
+	dev_dbg(info->device, "CRT16: %d\n", vtotal & 0xff);
 	vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, vtotal & 0xff);
 
-	DPRINTK("CRT18: 0xff\n");
+	dev_dbg(info->device, "CRT18: 0xff\n");
 	vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff);
 
 	tmp = 0;
@@ -871,41 +833,75 @@
 	if (vtotal & 512)
 		tmp |= 128;
 
-	DPRINTK("CRT1a: %d\n", tmp);
+	dev_dbg(info->device, "CRT1a: %d\n", tmp);
 	vga_wcrt(regbase, CL_CRT1A, tmp);
 
 	freq = PICOS2KHZ(var->pixclock);
+	if (var->bits_per_pixel == 24)
+		if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64)
+			freq *= 3;
+	if (cinfo->multiplexing)
+		freq /= 2;
+	if (cinfo->doubleVCLK)
+		freq *= 2;
+
 	bestclock(freq, &nom, &den, &div);
 
+	dev_dbg(info->device, "VCLK freq: %ld kHz  nom: %d  den: %d  div: %d\n",
+		freq, nom, den, div);
+
 	/* set VCLK0 */
 	/* hardware RefClock: 14.31818 MHz */
 	/* formula: VClk = (OSC * N) / (D * (1+P)) */
 	/* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
 
-	if (cinfo->btype == BT_ALPINE) {
+	if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_PICASSO4 ||
+	    cinfo->btype == BT_SD64) {
 		/* if freq is close to mclk or mclk/2 select mclk
 		 * as clock source
 		 */
-		int divMCLK = cirrusfb_check_mclk(cinfo, freq);
-		if (divMCLK)  {
+		int divMCLK = cirrusfb_check_mclk(info, freq);
+		if (divMCLK)
 			nom = 0;
-			cirrusfb_set_mclk_as_source(cinfo, divMCLK);
+		cirrusfb_set_mclk_as_source(info, divMCLK);
+	}
+	if (is_laguna(cinfo)) {
+		long pcifc = fb_readl(cinfo->laguna_mmio + 0x3fc);
+		unsigned char tile = fb_readb(cinfo->laguna_mmio + 0x407);
+		unsigned short tile_control;
+
+		if (cinfo->btype == BT_LAGUNAB) {
+			tile_control = fb_readw(cinfo->laguna_mmio + 0x2c4);
+			tile_control &= ~0x80;
+			fb_writew(tile_control, cinfo->laguna_mmio + 0x2c4);
 		}
+
+		fb_writel(pcifc | 0x10000000l, cinfo->laguna_mmio + 0x3fc);
+		fb_writeb(tile & 0x3f, cinfo->laguna_mmio + 0x407);
+		control = fb_readw(cinfo->laguna_mmio + 0x402);
+		threshold = fb_readw(cinfo->laguna_mmio + 0xea);
+		control &= ~0x6800;
+		format = 0;
+		threshold &= 0xffc0 & 0x3fbf;
 	}
 	if (nom) {
-		vga_wseq(regbase, CL_SEQRB, nom);
 		tmp = den << 1;
 		if (div != 0)
 			tmp |= 1;
-
 		/* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
 		if ((cinfo->btype == BT_SD64) ||
 		    (cinfo->btype == BT_ALPINE) ||
 		    (cinfo->btype == BT_GD5480))
 			tmp |= 0x80;
 
-		DPRINTK("CL_SEQR1B: %ld\n", (long) tmp);
-		vga_wseq(regbase, CL_SEQR1B, tmp);
+		/* Laguna chipset has reversed clock registers */
+		if (is_laguna(cinfo)) {
+			vga_wseq(regbase, CL_SEQRE, tmp);
+			vga_wseq(regbase, CL_SEQR1E, nom);
+		} else {
+			vga_wseq(regbase, CL_SEQRE, nom);
+			vga_wseq(regbase, CL_SEQR1E, tmp);
+		}
 	}
 
 	if (yres >= 1024)
@@ -916,9 +912,6 @@
 		 * address wrap, no compat. */
 		vga_wcrt(regbase, VGA_CRTC_MODE, 0xc3);
 
-/* HAEH?	vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20);
- * previously: 0x00  unlock VGA_CRTC_H_TOTAL..CRT7 */
-
 	/* don't know if it would hurt to also program this if no interlaced */
 	/* mode is used, but I feel better this way.. :-) */
 	if (var->vmode & FB_VMODE_INTERLACED)
@@ -926,19 +919,15 @@
 	else
 		vga_wcrt(regbase, VGA_CRTC_REGS, 0x00);	/* interlace control */
 
-	vga_wseq(regbase, VGA_SEQ_CHARACTER_MAP, 0);
-
-	/* adjust horizontal/vertical sync type (low/high) */
+	/* adjust horizontal/vertical sync type (low/high), use VCLK3 */
 	/* enable display memory & CRTC I/O address for color mode */
-	tmp = 0x03;
+	tmp = 0x03 | 0xc;
 	if (var->sync & FB_SYNC_HOR_HIGH_ACT)
 		tmp |= 0x40;
 	if (var->sync & FB_SYNC_VERT_HIGH_ACT)
 		tmp |= 0x80;
 	WGen(cinfo, VGA_MIS_W, tmp);
 
-	/* Screen A Preset Row-Scan register */
-	vga_wcrt(regbase, VGA_CRTC_PRESET_ROW, 0);
 	/* text cursor on and start line */
 	vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0);
 	/* text cursor end line */
@@ -952,7 +941,7 @@
 
 	/* programming for different color depths */
 	if (var->bits_per_pixel == 1) {
-		DPRINTK("cirrusfb: preparing for 1 bit deep display\n");
+		dev_dbg(info->device, "preparing for 1 bit deep display\n");
 		vga_wgfx(regbase, VGA_GFX_MODE, 0);	/* mode register */
 
 		/* SR07 */
@@ -964,68 +953,53 @@
 		case BT_PICASSO4:
 		case BT_ALPINE:
 		case BT_GD5480:
-			DPRINTK(" (for GD54xx)\n");
 			vga_wseq(regbase, CL_SEQR7,
-				  regs.multiplexing ?
+				 cinfo->multiplexing ?
 					bi->sr07_1bpp_mux : bi->sr07_1bpp);
 			break;
 
 		case BT_LAGUNA:
-			DPRINTK(" (for GD546x)\n");
+		case BT_LAGUNAB:
 			vga_wseq(regbase, CL_SEQR7,
 				vga_rseq(regbase, CL_SEQR7) & ~0x01);
 			break;
 
 		default:
-			printk(KERN_WARNING "cirrusfb: unknown Board\n");
+			dev_warn(info->device, "unknown Board\n");
 			break;
 		}
 
 		/* Extended Sequencer Mode */
 		switch (cinfo->btype) {
-		case BT_SD64:
-			/* setting the SEQRF on SD64 is not necessary
-			 * (only during init)
-			 */
-			DPRINTK("(for SD64)\n");
-			/*  MCLK select */
-			vga_wseq(regbase, CL_SEQR1F, 0x1a);
-			break;
 
 		case BT_PICCOLO:
 		case BT_SPECTRUM:
-			DPRINTK("(for Piccolo/Spectrum)\n");
-			/* ### ueberall 0x22? */
-			/* ##vorher 1c MCLK select */
-			vga_wseq(regbase, CL_SEQR1F, 0x22);
 			/* evtl d0 bei 1 bit? avoid FIFO underruns..? */
 			vga_wseq(regbase, CL_SEQRF, 0xb0);
 			break;
 
 		case BT_PICASSO:
-			DPRINTK("(for Picasso)\n");
-			/* ##vorher 22 MCLK select */
-			vga_wseq(regbase, CL_SEQR1F, 0x22);
 			/* ## vorher d0 avoid FIFO underruns..? */
 			vga_wseq(regbase, CL_SEQRF, 0xd0);
 			break;
 
+		case BT_SD64:
 		case BT_PICASSO4:
 		case BT_ALPINE:
 		case BT_GD5480:
 		case BT_LAGUNA:
-			DPRINTK(" (for GD54xx)\n");
+		case BT_LAGUNAB:
 			/* do nothing */
 			break;
 
 		default:
-			printk(KERN_WARNING "cirrusfb: unknown Board\n");
+			dev_warn(info->device, "unknown Board\n");
 			break;
 		}
 
 		/* pixel mask: pass-through for first plane */
 		WGen(cinfo, VGA_PEL_MSK, 0x01);
-		if (regs.multiplexing)
+		if (cinfo->multiplexing)
 			/* hidden dac reg: 1280x1024 */
 			WHDR(cinfo, 0x4a);
 		else
@@ -1035,7 +1009,6 @@
 		vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x06);
 		/* plane mask: only write to first plane */
 		vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x01);
-		offset = var->xres_virtual / 16;
 	}
 
 	/******************************************************
@@ -1045,7 +1018,7 @@
 	 */
 
 	else if (var->bits_per_pixel == 8) {
-		DPRINTK("cirrusfb: preparing for 8 bit deep display\n");
+		dev_dbg(info->device, "preparing for 8 bit deep display\n");
 		switch (cinfo->btype) {
 		case BT_SD64:
 		case BT_PICCOLO:
@@ -1054,34 +1027,27 @@
 		case BT_PICASSO4:
 		case BT_ALPINE:
 		case BT_GD5480:
-			DPRINTK(" (for GD54xx)\n");
 			vga_wseq(regbase, CL_SEQR7,
-				  regs.multiplexing ?
+				  cinfo->multiplexing ?
 					bi->sr07_8bpp_mux : bi->sr07_8bpp);
 			break;
 
 		case BT_LAGUNA:
-			DPRINTK(" (for GD546x)\n");
+		case BT_LAGUNAB:
 			vga_wseq(regbase, CL_SEQR7,
 				vga_rseq(regbase, CL_SEQR7) | 0x01);
+			threshold |= 0x10;
 			break;
 
 		default:
-			printk(KERN_WARNING "cirrusfb: unknown Board\n");
+			dev_warn(info->device, "unknown Board\n");
 			break;
 		}
 
 		switch (cinfo->btype) {
-		case BT_SD64:
-			/* MCLK select */
-			vga_wseq(regbase, CL_SEQR1F, 0x1d);
-			break;
-
 		case BT_PICCOLO:
 		case BT_PICASSO:
 		case BT_SPECTRUM:
-			/* ### vorher 1c MCLK select */
-			vga_wseq(regbase, CL_SEQR1F, 0x22);
 			/* Fast Page-Mode writes */
 			vga_wseq(regbase, CL_SEQRF, 0xb0);
 			break;
@@ -1091,40 +1057,27 @@
 			/* ### INCOMPLETE!! */
 			vga_wseq(regbase, CL_SEQRF, 0xb8);
 #endif
-/*	  		vga_wseq(regbase, CL_SEQR1F, 0x1c); */
-			break;
-
 		case BT_ALPINE:
-			DPRINTK(" (for GD543x)\n");
-			/* We already set SRF and SR1F */
-			break;
-
+		case BT_SD64:
 		case BT_GD5480:
 		case BT_LAGUNA:
-			DPRINTK(" (for GD54xx)\n");
+		case BT_LAGUNAB:
 			/* do nothing */
 			break;
 
 		default:
-			printk(KERN_WARNING "cirrusfb: unknown Board\n");
+			dev_warn(info->device, "unknown board\n");
 			break;
 		}
 
 		/* mode register: 256 color mode */
 		vga_wgfx(regbase, VGA_GFX_MODE, 64);
-		/* pixel mask: pass-through all planes */
-		WGen(cinfo, VGA_PEL_MSK, 0xff);
-		if (regs.multiplexing)
+		if (cinfo->multiplexing)
 			/* hidden dac reg: 1280x1024 */
 			WHDR(cinfo, 0x4a);
 		else
 			/* hidden dac: nothing */
 			WHDR(cinfo, 0);
-		/* memory mode: chain4, ext. memory */
-		vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
-		/* plane mask: enable writing to all 4 planes */
-		vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
-		offset = var->xres_virtual / 8;
 	}
 
 	/******************************************************
@@ -1134,147 +1087,110 @@
 	 */
 
 	else if (var->bits_per_pixel == 16) {
-		DPRINTK("cirrusfb: preparing for 16 bit deep display\n");
+		dev_dbg(info->device, "preparing for 16 bit deep display\n");
 		switch (cinfo->btype) {
-		case BT_SD64:
-			/* Extended Sequencer Mode: 256c col. mode */
-			vga_wseq(regbase, CL_SEQR7, 0xf7);
-			/* MCLK select */
-			vga_wseq(regbase, CL_SEQR1F, 0x1e);
-			break;
-
 		case BT_PICCOLO:
 		case BT_SPECTRUM:
 			vga_wseq(regbase, CL_SEQR7, 0x87);
 			/* Fast Page-Mode writes */
 			vga_wseq(regbase, CL_SEQRF, 0xb0);
-			/* MCLK select */
-			vga_wseq(regbase, CL_SEQR1F, 0x22);
 			break;
 
 		case BT_PICASSO:
 			vga_wseq(regbase, CL_SEQR7, 0x27);
 			/* Fast Page-Mode writes */
 			vga_wseq(regbase, CL_SEQRF, 0xb0);
-			/* MCLK select */
-			vga_wseq(regbase, CL_SEQR1F, 0x22);
 			break;
 
+		case BT_SD64:
 		case BT_PICASSO4:
-			vga_wseq(regbase, CL_SEQR7, 0x27);
-/*			vga_wseq(regbase, CL_SEQR1F, 0x1c);  */
-			break;
-
 		case BT_ALPINE:
-			DPRINTK(" (for GD543x)\n");
-			vga_wseq(regbase, CL_SEQR7, 0xa7);
+			/* Extended Sequencer Mode: 256c col. mode */
+			vga_wseq(regbase, CL_SEQR7,
+					cinfo->doubleVCLK ? 0xa3 : 0xa7);
 			break;
 
 		case BT_GD5480:
-			DPRINTK(" (for GD5480)\n");
 			vga_wseq(regbase, CL_SEQR7, 0x17);
 			/* We already set SRF and SR1F */
 			break;
 
 		case BT_LAGUNA:
-			DPRINTK(" (for GD546x)\n");
+		case BT_LAGUNAB:
 			vga_wseq(regbase, CL_SEQR7,
 				vga_rseq(regbase, CL_SEQR7) & ~0x01);
+			control |= 0x2000;
+			format |= 0x1400;
+			threshold |= 0x10;
 			break;
 
 		default:
-			printk(KERN_WARNING "CIRRUSFB: unknown Board\n");
+			dev_warn(info->device, "unknown Board\n");
 			break;
 		}
 
 		/* mode register: 256 color mode */
 		vga_wgfx(regbase, VGA_GFX_MODE, 64);
-		/* pixel mask: pass-through all planes */
-		WGen(cinfo, VGA_PEL_MSK, 0xff);
 #ifdef CONFIG_PCI
-		WHDR(cinfo, 0xc0);	/* Copy Xbh */
+		WHDR(cinfo, cinfo->doubleVCLK ? 0xe1 : 0xc1);
 #elif defined(CONFIG_ZORRO)
 		/* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */
 		WHDR(cinfo, 0xa0);	/* hidden dac reg: nothing special */
 #endif
-		/* memory mode: chain4, ext. memory */
-		vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
-		/* plane mask: enable writing to all 4 planes */
-		vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
-		offset = var->xres_virtual / 4;
 	}
 
 	/******************************************************
 	 *
-	 * 32 bpp
+	 * 24 bpp
 	 *
 	 */
 
-	else if (var->bits_per_pixel == 32) {
-		DPRINTK("cirrusfb: preparing for 32 bit deep display\n");
+	else if (var->bits_per_pixel == 24) {
+		dev_dbg(info->device, "preparing for 24 bit deep display\n");
 		switch (cinfo->btype) {
-		case BT_SD64:
-			/* Extended Sequencer Mode: 256c col. mode */
-			vga_wseq(regbase, CL_SEQR7, 0xf9);
-			/* MCLK select */
-			vga_wseq(regbase, CL_SEQR1F, 0x1e);
-			break;
-
 		case BT_PICCOLO:
 		case BT_SPECTRUM:
 			vga_wseq(regbase, CL_SEQR7, 0x85);
 			/* Fast Page-Mode writes */
 			vga_wseq(regbase, CL_SEQRF, 0xb0);
-			/* MCLK select */
-			vga_wseq(regbase, CL_SEQR1F, 0x22);
 			break;
 
 		case BT_PICASSO:
 			vga_wseq(regbase, CL_SEQR7, 0x25);
 			/* Fast Page-Mode writes */
 			vga_wseq(regbase, CL_SEQRF, 0xb0);
-			/* MCLK select */
-			vga_wseq(regbase, CL_SEQR1F, 0x22);
 			break;
 
+		case BT_SD64:
 		case BT_PICASSO4:
-			vga_wseq(regbase, CL_SEQR7, 0x25);
-/*			vga_wseq(regbase, CL_SEQR1F, 0x1c);  */
-			break;
-
 		case BT_ALPINE:
-			DPRINTK(" (for GD543x)\n");
-			vga_wseq(regbase, CL_SEQR7, 0xa9);
+			/* Extended Sequencer Mode: 256c col. mode */
+			vga_wseq(regbase, CL_SEQR7, 0xa5);
 			break;
 
 		case BT_GD5480:
-			DPRINTK(" (for GD5480)\n");
-			vga_wseq(regbase, CL_SEQR7, 0x19);
+			vga_wseq(regbase, CL_SEQR7, 0x15);
 			/* We already set SRF and SR1F */
 			break;
 
 		case BT_LAGUNA:
-			DPRINTK(" (for GD546x)\n");
+		case BT_LAGUNAB:
 			vga_wseq(regbase, CL_SEQR7,
 				vga_rseq(regbase, CL_SEQR7) & ~0x01);
+			control |= 0x4000;
+			format |= 0x2400;
+			threshold |= 0x20;
 			break;
 
 		default:
-			printk(KERN_WARNING "cirrusfb: unknown Board\n");
+			dev_warn(info->device, "unknown Board\n");
 			break;
 		}
 
 		/* mode register: 256 color mode */
 		vga_wgfx(regbase, VGA_GFX_MODE, 64);
-		/* pixel mask: pass-through all planes */
-		WGen(cinfo, VGA_PEL_MSK, 0xff);
 		/* hidden dac reg: 8-8-8 mode (24 or 32) */
 		WHDR(cinfo, 0xc5);
-		/* memory mode: chain4, ext. memory */
-		vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
-		/* plane mask: enable writing to all 4 planes */
-		vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
-		offset = var->xres_virtual / 4;
 	}
 
 	/******************************************************
@@ -1284,67 +1200,55 @@
 	 */
 
 	else
-		printk(KERN_ERR "cirrusfb: What's this?? "
-			" requested color depth == %d.\n",
+		dev_err(info->device,
+			"What's this? requested color depth == %d.\n",
 			var->bits_per_pixel);
 
-	vga_wcrt(regbase, VGA_CRTC_OFFSET, offset & 0xff);
+	pitch = info->fix.line_length >> 3;
+	vga_wcrt(regbase, VGA_CRTC_OFFSET, pitch & 0xff);
 	tmp = 0x22;
-	if (offset & 0x100)
+	if (pitch & 0x100)
 		tmp |= 0x10;	/* offset overflow bit */
 
 	/* screen start addr #16-18, fastpagemode cycles */
 	vga_wcrt(regbase, CL_CRT1B, tmp);
 
-	if (cinfo->btype == BT_SD64 ||
-	    cinfo->btype == BT_PICASSO4 ||
-	    cinfo->btype == BT_ALPINE ||
-	    cinfo->btype == BT_GD5480)
-		/* screen start address bit 19 */
-		vga_wcrt(regbase, CL_CRT1D, 0x00);
+	/* screen start address bit 19 */
+	if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
+		vga_wcrt(regbase, CL_CRT1D, (pitch >> 9) & 1);
 
-	/* text cursor location high */
-	vga_wcrt(regbase, VGA_CRTC_CURSOR_HI, 0);
-	/* text cursor location low */
-	vga_wcrt(regbase, VGA_CRTC_CURSOR_LO, 0);
-	/* underline row scanline = at very bottom */
-	vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0);
+	if (is_laguna(cinfo)) {
+		tmp = 0;
+		if ((htotal + 5) & 256)
+			tmp |= 128;
+		if (hdispend & 256)
+			tmp |= 64;
+		if (hsyncstart & 256)
+			tmp |= 48;
+		if (vtotal & 1024)
+			tmp |= 8;
+		if (vdispend & 1024)
+			tmp |= 4;
+		if (vsyncstart & 1024)
+			tmp |= 3;
 
-	/* controller mode */
-	vga_wattr(regbase, VGA_ATC_MODE, 1);
-	/* overscan (border) color */
-	vga_wattr(regbase, VGA_ATC_OVERSCAN, 0);
-	/* color plane enable */
-	vga_wattr(regbase, VGA_ATC_PLANE_ENABLE, 15);
+		vga_wcrt(regbase, CL_CRT1E, tmp);
+		dev_dbg(info->device, "CRT1e: %d\n", tmp);
+	}
+
 	/* pixel panning */
 	vga_wattr(regbase, CL_AR33, 0);
-	/* color select */
-	vga_wattr(regbase, VGA_ATC_COLOR_PAGE, 0);
 
 	/* [ EGS: SetOffset(); ] */
 	/* From SetOffset(): Turn on VideoEnable bit in Attribute controller */
 	AttrOn(cinfo);
 
-	/* set/reset register */
-	vga_wgfx(regbase, VGA_GFX_SR_VALUE, 0);
-	/* set/reset enable */
-	vga_wgfx(regbase, VGA_GFX_SR_ENABLE, 0);
-	/* color compare */
-	vga_wgfx(regbase, VGA_GFX_COMPARE_VALUE, 0);
-	/* data rotate */
-	vga_wgfx(regbase, VGA_GFX_DATA_ROTATE, 0);
-	/* read map select */
-	vga_wgfx(regbase, VGA_GFX_PLANE_READ, 0);
-	/* miscellaneous register */
-	vga_wgfx(regbase, VGA_GFX_MISC, 1);
-	/* color don't care */
-	vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 15);
-	/* bit mask */
-	vga_wgfx(regbase, VGA_GFX_BIT_MASK, 255);
-
-	/* graphics cursor attributes: nothing special */
-	vga_wseq(regbase, CL_SEQR12, 0x0);
-
+	if (is_laguna(cinfo)) {
+		/* no tiles */
+		fb_writew(control | 0x1000, cinfo->laguna_mmio + 0x402);
+		fb_writew(format, cinfo->laguna_mmio + 0xc0);
+		fb_writew(threshold, cinfo->laguna_mmio + 0xea);
+	}
 	/* finally, turn on everything - turn off "FullBandwidth" bit */
 	/* also, set "DotClock%2" bit where requested */
 	tmp = 0x01;
@@ -1355,18 +1259,12 @@
 */
 
 	vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp);
-	DPRINTK("CL_SEQR1: %d\n", tmp);
-
-	cinfo->currentmode = regs;
-
-	/* pan to requested offset */
-	cirrusfb_pan_display(var, info);
+	dev_dbg(info->device, "CL_SEQR1: %d\n", tmp);
 
 #ifdef CIRRUSFB_DEBUG
-	cirrusfb_dump();
+	cirrusfb_dbg_reg_dump(info, NULL);
 #endif
 
-	DPRINTK("EXIT\n");
 	return 0;
 }
 
@@ -1418,27 +1316,19 @@
 static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
 				struct fb_info *info)
 {
-	int xoffset = 0;
-	int yoffset = 0;
+	int xoffset;
 	unsigned long base;
-	unsigned char tmp = 0, tmp2 = 0, xpix;
+	unsigned char tmp, xpix;
 	struct cirrusfb_info *cinfo = info->par;
 
-	DPRINTK("ENTER\n");
-	DPRINTK("virtual offset: (%d,%d)\n", var->xoffset, var->yoffset);
-
 	/* no range checks for xoffset and yoffset,   */
 	/* as fb_pan_display has already done this */
 	if (var->vmode & FB_VMODE_YWRAP)
 		return -EINVAL;
 
-	info->var.xoffset = var->xoffset;
-	info->var.yoffset = var->yoffset;
-
 	xoffset = var->xoffset * info->var.bits_per_pixel / 8;
-	yoffset = var->yoffset;
 
-	base = yoffset * info->fix.line_length + xoffset;
+	base = var->yoffset * info->fix.line_length + xoffset;
 
 	if (info->var.bits_per_pixel == 1) {
 		/* base is already correct */
@@ -1448,14 +1338,15 @@
 		xpix = (unsigned char) ((xoffset % 4) * 2);
 	}
 
-	cirrusfb_WaitBLT(cinfo->regbase); /* make sure all the BLT's are done */
+	if (!is_laguna(cinfo))
+		cirrusfb_WaitBLT(cinfo->regbase);
 
 	/* lower 8 + 8 bits of screen start address */
-	vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO,
-		 (unsigned char) (base & 0xff));
-	vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI,
-		 (unsigned char) (base >> 8));
+	vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, base & 0xff);
+	vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, (base >> 8) & 0xff);
 
+	/* 0xf2 is %11110010, exclude tmp bits */
+	tmp = vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2;
 	/* construct bits 16, 17 and 18 of screen start address */
 	if (base & 0x10000)
 		tmp |= 0x01;
@@ -1464,13 +1355,17 @@
 	if (base & 0x40000)
 		tmp |= 0x08;
 
-	/* 0xf2 is %11110010, exclude tmp bits */
-	tmp2 = (vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2) | tmp;
-	vga_wcrt(cinfo->regbase, CL_CRT1B, tmp2);
+	vga_wcrt(cinfo->regbase, CL_CRT1B, tmp);
 
 	/* construct bit 19 of screen start address */
-	if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
-		vga_wcrt(cinfo->regbase, CL_CRT1D, (base >> 12) & 0x80);
+	if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) {
+		tmp = vga_rcrt(cinfo->regbase, CL_CRT1D);
+		if (is_laguna(cinfo))
+			tmp = (tmp & ~0x18) | ((base >> 16) & 0x18);
+		else
+			tmp = (tmp & ~0x80) | ((base >> 12) & 0x80);
+		vga_wcrt(cinfo->regbase, CL_CRT1D, tmp);
+	}
 
 	/* write pixel panning value to AR33; this does not quite work in 8bpp
 	 *
@@ -1479,9 +1374,6 @@
 	if (info->var.bits_per_pixel == 1)
 		vga_wattr(cinfo->regbase, CL_AR33, xpix);
 
-	cirrusfb_WaitBLT(cinfo->regbase);
-
-	DPRINTK("EXIT\n");
 	return 0;
 }
 
@@ -1502,57 +1394,54 @@
 	struct cirrusfb_info *cinfo = info->par;
 	int current_mode = cinfo->blank_mode;
 
-	DPRINTK("ENTER, blank mode = %d\n", blank_mode);
+	dev_dbg(info->device, "ENTER, blank mode = %d\n", blank_mode);
 
 	if (info->state != FBINFO_STATE_RUNNING ||
 	    current_mode == blank_mode) {
-		DPRINTK("EXIT, returning 0\n");
+		dev_dbg(info->device, "EXIT, returning 0\n");
 		return 0;
 	}
 
 	/* Undo current */
 	if (current_mode == FB_BLANK_NORMAL ||
-	    current_mode == FB_BLANK_UNBLANK) {
-		/* unblank the screen */
-		val = vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE);
+	    current_mode == FB_BLANK_UNBLANK)
 		/* clear "FullBandwidth" bit */
-		vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val & 0xdf);
-		/* and undo VESA suspend trickery */
-		vga_wgfx(cinfo->regbase, CL_GRE, 0x00);
-	}
-
-	/* set new */
-	if (blank_mode > FB_BLANK_NORMAL) {
-		/* blank the screen */
-		val = vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE);
+		val = 0;
+	else
 		/* set "FullBandwidth" bit */
-		vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val | 0x20);
-	}
+		val = 0x20;
+
+	val |= vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE) & 0xdf;
+	vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val);
 
 	switch (blank_mode) {
 	case FB_BLANK_UNBLANK:
 	case FB_BLANK_NORMAL:
+		val = 0x00;
 		break;
 	case FB_BLANK_VSYNC_SUSPEND:
-		vga_wgfx(cinfo->regbase, CL_GRE, 0x04);
+		val = 0x04;
 		break;
 	case FB_BLANK_HSYNC_SUSPEND:
-		vga_wgfx(cinfo->regbase, CL_GRE, 0x02);
+		val = 0x02;
 		break;
 	case FB_BLANK_POWERDOWN:
-		vga_wgfx(cinfo->regbase, CL_GRE, 0x06);
+		val = 0x06;
 		break;
 	default:
-		DPRINTK("EXIT, returning 1\n");
+		dev_dbg(info->device, "EXIT, returning 1\n");
 		return 1;
 	}
 
+	vga_wgfx(cinfo->regbase, CL_GRE, val);
+
 	cinfo->blank_mode = blank_mode;
-	DPRINTK("EXIT, returning 0\n");
+	dev_dbg(info->device, "EXIT, returning 0\n");
 
 	/* Let fbcon do a soft blank for us */
 	return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
 }
+
 /**** END   Hardware specific Routines **************************************/
 /****************************************************************************/
 /**** BEGIN Internal Routines ***********************************************/
@@ -1562,8 +1451,6 @@
 	struct cirrusfb_info *cinfo = info->par;
 	const struct cirrusfb_board_info_rec *bi;
 
-	DPRINTK("ENTER\n");
-
 	assert(cinfo != NULL);
 
 	bi = &cirrusfb_board_info[cinfo->btype];
@@ -1591,25 +1478,23 @@
 		/* disable flickerfixer */
 		vga_wcrt(cinfo->regbase, CL_CRT51, 0x00);
 		mdelay(100);
-		/* from Klaus' NetBSD driver: */
-		vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
-		/* put blitter into 542x compat */
-		vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
 		/* mode */
 		vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
-		break;
-
-	case BT_GD5480:
+	case BT_GD5480:  /* fall through */
 		/* from Klaus' NetBSD driver: */
 		vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
+	case BT_ALPINE:  /* fall through */
+		/* put blitter into 542x compat */
+		vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
 		break;
 
-	case BT_ALPINE:
+	case BT_LAGUNA:
+	case BT_LAGUNAB:
 		/* Nothing to do to reset the board. */
 		break;
 
 	default:
-		printk(KERN_ERR "cirrusfb: Warning: Unknown board type\n");
+		dev_err(info->device, "Warning: Unknown board type\n");
 		break;
 	}
 
@@ -1629,31 +1514,28 @@
 			WGen(cinfo, CL_VSSM2, 0x01);
 
 		/* reset sequencer logic */
-		vga_wseq(cinfo->regbase, CL_SEQR0, 0x03);
+		vga_wseq(cinfo->regbase, VGA_SEQ_RESET, 0x03);
 
 		/* FullBandwidth (video off) and 8/9 dot clock */
 		vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21);
-		/* polarity (-/-), disable access to display memory,
-		 * VGA_CRTC_START_HI base address: color
-		 */
-		WGen(cinfo, VGA_MIS_W, 0xc1);
 
 		/* "magic cookie" - doesn't make any sense to me.. */
 /*      vga_wgfx(cinfo->regbase, CL_GRA, 0xce);   */
 		/* unlock all extension registers */
 		vga_wseq(cinfo->regbase, CL_SEQR6, 0x12);
 
-		/* reset blitter */
-		vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
-
 		switch (cinfo->btype) {
 		case BT_GD5480:
 			vga_wseq(cinfo->regbase, CL_SEQRF, 0x98);
 			break;
 		case BT_ALPINE:
+		case BT_LAGUNA:
+		case BT_LAGUNAB:
 			break;
 		case BT_SD64:
+#ifdef CONFIG_ZORRO
 			vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8);
+#endif
 			break;
 		default:
 			vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f);
@@ -1665,8 +1547,8 @@
 	vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff);
 	/* character map select: doesn't even matter in gx mode */
 	vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
-	/* memory mode: chain-4, no odd/even, ext. memory */
-	vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0e);
+	/* memory mode: chain4, ext. memory */
+	vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
 
 	/* controller-internal base address of video memory */
 	if (bi->init_sr07)
@@ -1692,20 +1574,12 @@
 		vga_wseq(cinfo->regbase, CL_SEQR18, 0x02);
 	}
 
-	/* MCLK select etc. */
-	if (bi->init_sr1f)
-		vga_wseq(cinfo->regbase, CL_SEQR1F, bi->sr1f);
-
 	/* Screen A preset row scan: none */
 	vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00);
 	/* Text cursor start: disable text cursor */
 	vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20);
 	/* Text cursor end: - */
 	vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00);
-	/* Screen start address high: 0 */
-	vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, 0x00);
-	/* Screen start address low: 0 */
-	vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, 0x00);
 	/* text cursor location high: 0 */
 	vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00);
 	/* text cursor location low: 0 */
@@ -1713,10 +1587,6 @@
 
 	/* Underline Row scanline: - */
 	vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00);
-	/* mode control: timing enable, byte mode, no compat modes */
-	vga_wcrt(cinfo->regbase, VGA_CRTC_MODE, 0xc3);
-	/* Line Compare: not needed */
-	vga_wcrt(cinfo->regbase, VGA_CRTC_LINE_COMPARE, 0x00);
 	/* ### add 0x40 for text modes with > 30 MHz pixclock */
 	/* ext. display controls: ext.adr. wrap */
 	vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02);
@@ -1739,7 +1609,9 @@
 	vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f);
 	/* Bit Mask: no mask at all */
 	vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff);
-	if (cinfo->btype == BT_ALPINE)
+
+	if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64 ||
+	    is_laguna(cinfo))
 		/* (5434 can't have bit 3 set for bitblt) */
 		vga_wgfx(cinfo->regbase, CL_GRB, 0x20);
 	else
@@ -1779,18 +1651,11 @@
 	vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00);
 	/* Color Plane enable: Enable all 4 planes */
 	vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f);
-/* ###  vga_wattr(cinfo->regbase, CL_AR33, 0x00); * Pixel Panning: - */
 	/* Color Select: - */
 	vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00);
 
 	WGen(cinfo, VGA_PEL_MSK, 0xff);	/* Pixel mask: no mask */
 
-	if (cinfo->btype != BT_ALPINE && cinfo->btype != BT_GD5480)
-	/* polarity (-/-), enable display mem,
-	 * VGA_CRTC_START_HI i/o base = color
-	 */
-		WGen(cinfo, VGA_MIS_W, 0xc3);
-
 	/* BLT Start/status: Blitter reset */
 	vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
 	/* - " -	   : "end-of-reset" */
@@ -1798,8 +1663,6 @@
 
 	/* misc... */
 	WHDR(cinfo, 0);	/* Hidden DAC register: - */
-
-	DPRINTK("EXIT\n");
 	return;
 }
 
@@ -1808,8 +1671,6 @@
 #ifdef CONFIG_ZORRO /* only works on Zorro boards */
 	static int IsOn = 0;	/* XXX not ok for multiple boards */
 
-	DPRINTK("ENTER\n");
-
 	if (cinfo->btype == BT_PICASSO4)
 		return;		/* nothing to switch */
 	if (cinfo->btype == BT_ALPINE)
@@ -1819,8 +1680,6 @@
 	if (cinfo->btype == BT_PICASSO) {
 		if ((on && !IsOn) || (!on && IsOn))
 			WSFR(cinfo, 0xff);
-
-		DPRINTK("EXIT\n");
 		return;
 	}
 	if (on) {
@@ -1847,11 +1706,10 @@
 		case BT_SPECTRUM:
 			WSFR(cinfo, 0x4f);
 			break;
-		default: /* do nothing */ break;
+		default: /* do nothing */
+			break;
 		}
 	}
-
-	DPRINTK("EXIT\n");
 #endif /* CONFIG_ZORRO */
 }
 
@@ -1859,6 +1717,17 @@
 /* Linux 2.6-style  accelerated functions */
 /******************************************/
 
+static int cirrusfb_sync(struct fb_info *info)
+{
+	struct cirrusfb_info *cinfo = info->par;
+
+	if (!is_laguna(cinfo)) {
+		while (vga_rgfx(cinfo->regbase, CL_GR31) & 0x03)
+			cpu_relax();
+	}
+	return 0;
+}
+
 static void cirrusfb_fillrect(struct fb_info *info,
 			      const struct fb_fillrect *region)
 {
@@ -1894,8 +1763,8 @@
 			  info->var.bits_per_pixel,
 			  (region->dx * m) / 8, region->dy,
 			  (region->width * m) / 8, region->height,
-			  color,
-			  info->fix.line_length);
+			  color, color,
+			  info->fix.line_length, 0x40);
 }
 
 static void cirrusfb_copyarea(struct fb_info *info,
@@ -1943,9 +1812,46 @@
 			       const struct fb_image *image)
 {
 	struct cirrusfb_info *cinfo = info->par;
+	unsigned char op = (info->var.bits_per_pixel == 24) ? 0xc : 0x4;
 
-	cirrusfb_WaitBLT(cinfo->regbase);
-	cfb_imageblit(info, image);
+	if (info->state != FBINFO_STATE_RUNNING)
+		return;
+	/* Alpine/SD64 does not work at 24bpp ??? */
+	if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1)
+		cfb_imageblit(info, image);
+	else if ((cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64) &&
+		  op == 0xc)
+		cfb_imageblit(info, image);
+	else {
+		unsigned size = ((image->width + 7) >> 3) * image->height;
+		int m = info->var.bits_per_pixel;
+		u32 fg, bg;
+
+		if (info->var.bits_per_pixel == 8) {
+			fg = image->fg_color;
+			bg = image->bg_color;
+		} else {
+			fg = ((u32 *)(info->pseudo_palette))[image->fg_color];
+			bg = ((u32 *)(info->pseudo_palette))[image->bg_color];
+		}
+		if (info->var.bits_per_pixel == 24) {
+			/* clear background first */
+			cirrusfb_RectFill(cinfo->regbase,
+					  info->var.bits_per_pixel,
+					  (image->dx * m) / 8, image->dy,
+					  (image->width * m) / 8,
+					  image->height,
+					  bg, bg,
+					  info->fix.line_length, 0x40);
+		}
+		cirrusfb_RectFill(cinfo->regbase,
+				  info->var.bits_per_pixel,
+				  (image->dx * m) / 8, image->dy,
+				  (image->width * m) / 8, image->height,
+				  fg, bg,
+				  info->fix.line_length, op);
+		memcpy(info->screen_base, image->data, size);
+	}
 }
 
 #ifdef CONFIG_PPC_PREP
@@ -1953,12 +1859,8 @@
 #define PREP_IO_BASE    ((volatile unsigned char *) 0x80000000)
 static void get_prep_addrs(unsigned long *display, unsigned long *registers)
 {
-	DPRINTK("ENTER\n");
-
 	*display = PREP_VIDEO_BASE;
 	*registers = (unsigned long) PREP_IO_BASE;
-
-	DPRINTK("EXIT\n");
 }
 
 #endif				/* CONFIG_PPC_PREP */
@@ -1970,40 +1872,43 @@
  * based on the DRAM bandwidth bit and DRAM bank switching bit.  This
  * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
  * seem to have. */
-static unsigned int __devinit cirrusfb_get_memsize(u8 __iomem *regbase)
+static unsigned int __devinit cirrusfb_get_memsize(struct fb_info *info,
+						   u8 __iomem *regbase)
 {
 	unsigned long mem;
-	unsigned char SRF;
+	struct cirrusfb_info *cinfo = info->par;
 
-	DPRINTK("ENTER\n");
+	if (is_laguna(cinfo)) {
+		unsigned char SR14 = vga_rseq(regbase, CL_SEQR14);
 
-	SRF = vga_rseq(regbase, CL_SEQRF);
-	switch ((SRF & 0x18)) {
-	case 0x08:
-		mem = 512 * 1024;
-		break;
-	case 0x10:
-		mem = 1024 * 1024;
-		break;
-	/* 64-bit DRAM data bus width; assume 2MB. Also indicates 2MB memory
-	 * on the 5430.
-	 */
-	case 0x18:
-		mem = 2048 * 1024;
-		break;
-	default:
-		printk(KERN_WARNING "CLgenfb: Unknown memory size!\n");
-		mem = 1024 * 1024;
+		mem = ((SR14 & 7) + 1) << 20;
+	} else {
+		unsigned char SRF = vga_rseq(regbase, CL_SEQRF);
+		switch ((SRF & 0x18)) {
+		case 0x08:
+			mem = 512 * 1024;
+			break;
+		case 0x10:
+			mem = 1024 * 1024;
+			break;
+		/* 64-bit DRAM data bus width; assume 2MB.
+		 * Also indicates 2MB memory on the 5430.
+		 */
+		case 0x18:
+			mem = 2048 * 1024;
+			break;
+		default:
+			dev_warn(info->device, "Unknown memory size!\n");
+			mem = 1024 * 1024;
+		}
+		/* If DRAM bank switching is enabled, there must be
+		 * twice as much memory installed. (4MB on the 5434)
+		 */
+		if (cinfo->btype != BT_ALPINE && (SRF & 0x80) != 0)
+			mem *= 2;
 	}
-	if (SRF & 0x80)
-	/* If DRAM bank switching is enabled, there must be twice as much
-	 * memory installed. (4MB on the 5434)
-	 */
-		mem *= 2;
 
 	/* TODO: Handling of GD5446/5480 (see XF86 sources ...) */
-
-	DPRINTK("EXIT\n");
 	return mem;
 }
 
@@ -2014,8 +1919,6 @@
 	assert(display != NULL);
 	assert(registers != NULL);
 
-	DPRINTK("ENTER\n");
-
 	*display = 0;
 	*registers = 0;
 
@@ -2030,14 +1933,15 @@
 	}
 
 	assert(*display != 0);
-
-	DPRINTK("EXIT\n");
 }
 
 static void cirrusfb_pci_unmap(struct fb_info *info)
 {
 	struct pci_dev *pdev = to_pci_dev(info->device);
+	struct cirrusfb_info *cinfo = info->par;
 
+	if (cinfo->laguna_mmio == NULL)
+		iounmap(cinfo->laguna_mmio);
 	iounmap(info->screen_base);
 #if 0 /* if system didn't claim this region, we would... */
 	release_mem_region(0xA0000, 65535);
@@ -2067,6 +1971,22 @@
 }
 #endif /* CONFIG_ZORRO */
 
+/* function table of the above functions */
+static struct fb_ops cirrusfb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_open	= cirrusfb_open,
+	.fb_release	= cirrusfb_release,
+	.fb_setcolreg	= cirrusfb_setcolreg,
+	.fb_check_var	= cirrusfb_check_var,
+	.fb_set_par	= cirrusfb_set_par,
+	.fb_pan_display = cirrusfb_pan_display,
+	.fb_blank	= cirrusfb_blank,
+	.fb_fillrect	= cirrusfb_fillrect,
+	.fb_copyarea	= cirrusfb_copyarea,
+	.fb_sync	= cirrusfb_sync,
+	.fb_imageblit	= cirrusfb_imageblit,
+};
+
 static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
 {
 	struct cirrusfb_info *cinfo = info->par;
@@ -2077,10 +1997,16 @@
 		    | FBINFO_HWACCEL_XPAN
 		    | FBINFO_HWACCEL_YPAN
 		    | FBINFO_HWACCEL_FILLRECT
+		    | FBINFO_HWACCEL_IMAGEBLIT
 		    | FBINFO_HWACCEL_COPYAREA;
-	if (noaccel)
+	if (noaccel || is_laguna(cinfo)) {
 		info->flags |= FBINFO_HWACCEL_DISABLED;
+		info->fix.accel = FB_ACCEL_NONE;
+	} else
+		info->fix.accel = FB_ACCEL_CIRRUS_ALPINE;
+
 	info->fbops = &cirrusfb_ops;
+
 	if (cinfo->btype == BT_GD5480) {
 		if (var->bits_per_pixel == 16)
 			info->screen_base += 1 * MB_;
@@ -2104,7 +2030,6 @@
 
 	/* FIXME: map region at 0xB8000 if available, fill in here */
 	info->fix.mmio_len   = 0;
-	info->fix.accel = FB_ACCEL_NONE;
 
 	fb_alloc_cmap(&info->cmap, 256, 0);
 
@@ -2115,70 +2040,56 @@
 {
 	struct cirrusfb_info *cinfo = info->par;
 	int err;
-	enum cirrus_board btype;
-
-	DPRINTK("ENTER\n");
-
-	printk(KERN_INFO "cirrusfb: Driver for Cirrus Logic based "
-		"graphic boards, v" CIRRUSFB_VERSION "\n");
-
-	btype = cinfo->btype;
 
 	/* sanity checks */
-	assert(btype != BT_NONE);
+	assert(cinfo->btype != BT_NONE);
 
 	/* set all the vital stuff */
 	cirrusfb_set_fbinfo(info);
 
-	DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base);
+	dev_dbg(info->device, "(RAM start set to: 0x%p)\n", info->screen_base);
 
 	err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
 	if (!err) {
-		DPRINTK("wrong initial video mode\n");
+		dev_dbg(info->device, "wrong initial video mode\n");
 		err = -EINVAL;
 		goto err_dealloc_cmap;
 	}
 
 	info->var.activate = FB_ACTIVATE_NOW;
 
-	err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info);
+	err = cirrusfb_check_var(&info->var, info);
 	if (err < 0) {
 		/* should never happen */
-		DPRINTK("choking on default var... umm, no good.\n");
+		dev_dbg(info->device,
+			"choking on default var... umm, no good.\n");
 		goto err_dealloc_cmap;
 	}
 
 	err = register_framebuffer(info);
 	if (err < 0) {
-		printk(KERN_ERR "cirrusfb: could not register "
-			"fb device; err = %d!\n", err);
+		dev_err(info->device,
+			"could not register fb device; err = %d!\n", err);
 		goto err_dealloc_cmap;
 	}
 
-	DPRINTK("EXIT, returning 0\n");
 	return 0;
 
 err_dealloc_cmap:
 	fb_dealloc_cmap(&info->cmap);
-	cinfo->unmap(info);
-	framebuffer_release(info);
 	return err;
 }
 
 static void __devexit cirrusfb_cleanup(struct fb_info *info)
 {
 	struct cirrusfb_info *cinfo = info->par;
-	DPRINTK("ENTER\n");
 
 	switch_monitor(cinfo, 0);
-
 	unregister_framebuffer(info);
 	fb_dealloc_cmap(&info->cmap);
-	printk("Framebuffer unregistered\n");
+	dev_dbg(info->device, "Framebuffer unregistered\n");
 	cinfo->unmap(info);
 	framebuffer_release(info);
-
-	DPRINTK("EXIT\n");
 }
 
 #ifdef CONFIG_PCI
@@ -2187,7 +2098,6 @@
 {
 	struct cirrusfb_info *cinfo;
 	struct fb_info *info;
-	enum cirrus_board btype;
 	unsigned long board_addr, board_size;
 	int ret;
 
@@ -2201,15 +2111,17 @@
 	if (!info) {
 		printk(KERN_ERR "cirrusfb: could not allocate memory\n");
 		ret = -ENOMEM;
-		goto err_disable;
+		goto err_out;
 	}
 
 	cinfo = info->par;
-	cinfo->btype = btype = (enum cirrus_board) ent->driver_data;
+	cinfo->btype = (enum cirrus_board) ent->driver_data;
 
-	DPRINTK(" Found PCI device, base address 0 is 0x%x, btype set to %d\n",
-		pdev->resource[0].start, btype);
-	DPRINTK(" base address 1 is 0x%x\n", pdev->resource[1].start);
+	dev_dbg(info->device,
+		" Found PCI device, base address 0 is 0x%Lx, btype set to %d\n",
+		(unsigned long long)pdev->resource[0].start,  cinfo->btype);
+	dev_dbg(info->device, " base address 1 is 0x%Lx\n",
+		(unsigned long long)pdev->resource[1].start);
 
 	if (isPReP) {
 		pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, 0x00000000);
@@ -2219,30 +2131,30 @@
 	/* PReP dies if we ioremap the IO registers, but it works w/out... */
 		cinfo->regbase = (char __iomem *) info->fix.mmio_start;
 	} else {
-		DPRINTK("Attempt to get PCI info for Cirrus Graphics Card\n");
+		dev_dbg(info->device,
+			"Attempt to get PCI info for Cirrus Graphics Card\n");
 		get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
 		/* FIXME: this forces VGA.  alternatives? */
 		cinfo->regbase = NULL;
+		cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000);
 	}
 
-	DPRINTK("Board address: 0x%lx, register address: 0x%lx\n",
+	dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n",
 		board_addr, info->fix.mmio_start);
 
-	board_size = (btype == BT_GD5480) ?
-		32 * MB_ : cirrusfb_get_memsize(cinfo->regbase);
+	board_size = (cinfo->btype == BT_GD5480) ?
+		32 * MB_ : cirrusfb_get_memsize(info, cinfo->regbase);
 
 	ret = pci_request_regions(pdev, "cirrusfb");
 	if (ret < 0) {
-		printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, "
-		       "abort\n",
-		       board_addr);
+		dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
+			board_addr);
 		goto err_release_fb;
 	}
 #if 0 /* if the system didn't claim this region, we would... */
 	if (!request_mem_region(0xA0000, 65535, "cirrusfb")) {
-		printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, abort\n"
-,
-		       0xA0000L);
+		dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
+			0xA0000L);
 		ret = -EBUSY;
 		goto err_release_regions;
 	}
@@ -2260,16 +2172,17 @@
 	info->screen_size = board_size;
 	cinfo->unmap = cirrusfb_pci_unmap;
 
-	printk(KERN_INFO "RAM (%lu kB) at 0x%lx, Cirrus "
-			"Logic chipset on PCI bus\n",
-			info->screen_size >> 10, board_addr);
+	dev_info(info->device,
+		 "Cirrus Logic chipset on PCI bus, RAM (%lu kB) at 0x%lx\n",
+		 info->screen_size >> 10, board_addr);
 	pci_set_drvdata(pdev, info);
 
 	ret = cirrusfb_register(info);
-	if (ret)
-		iounmap(info->screen_base);
-	return ret;
+	if (!ret)
+		return 0;
 
+	pci_set_drvdata(pdev, NULL);
+	iounmap(info->screen_base);
 err_release_legacy:
 	if (release_io_ports)
 		release_region(0x3C0, 32);
@@ -2279,8 +2192,9 @@
 #endif
 	pci_release_regions(pdev);
 err_release_fb:
+	if (cinfo->laguna_mmio != NULL)
+		iounmap(cinfo->laguna_mmio);
 	framebuffer_release(info);
-err_disable:
 err_out:
 	return ret;
 }
@@ -2288,11 +2202,8 @@
 static void __devexit cirrusfb_pci_unregister(struct pci_dev *pdev)
 {
 	struct fb_info *info = pci_get_drvdata(pdev);
-	DPRINTK("ENTER\n");
 
 	cirrusfb_cleanup(info);
-
-	DPRINTK("EXIT\n");
 }
 
 static struct pci_driver cirrusfb_pci_driver = {
@@ -2324,8 +2235,6 @@
 	if (cirrusfb_zorro_table2[btype].id2)
 		z2 = zorro_find_device(cirrusfb_zorro_table2[btype].id2, NULL);
 	size = cirrusfb_zorro_table2[btype].size;
-	printk(KERN_INFO "cirrusfb: %s board detected; ",
-	       cirrusfb_board_info[btype].name);
 
 	info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
 	if (!info) {
@@ -2334,6 +2243,9 @@
 		goto err_out;
 	}
 
+	dev_info(info->device, "%s board detected\n",
+		 cirrusfb_board_info[btype].name);
+
 	cinfo = info->par;
 	cinfo->btype = btype;
 
@@ -2345,19 +2257,16 @@
 	info->screen_size = size;
 
 	if (!zorro_request_device(z, "cirrusfb")) {
-		printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, "
-		       "abort\n",
-		       board_addr);
+		dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
+			board_addr);
 		ret = -EBUSY;
 		goto err_release_fb;
 	}
 
-	printk(" RAM (%lu MB) at $%lx, ", board_size / MB_, board_addr);
-
 	ret = -EIO;
 
 	if (btype == BT_PICASSO4) {
-		printk(KERN_INFO " REG at $%lx\n", board_addr + 0x600000);
+		dev_info(info->device, " REG at $%lx\n", board_addr + 0x600000);
 
 		/* To be precise, for the P4 this is not the */
 		/* begin of the board, but the begin of RAM. */
@@ -2367,7 +2276,7 @@
 		if (!cinfo->regbase)
 			goto err_release_region;
 
-		DPRINTK("cirrusfb: Virtual address for board set to: $%p\n",
+		dev_dbg(info->device, "Virtual address for board set to: $%p\n",
 			cinfo->regbase);
 		cinfo->regbase += 0x600000;
 		info->fix.mmio_start = board_addr + 0x600000;
@@ -2377,8 +2286,8 @@
 		if (!info->screen_base)
 			goto err_unmap_regbase;
 	} else {
-		printk(KERN_INFO " REG at $%lx\n",
-			(unsigned long) z2->resource.start);
+		dev_info(info->device, " REG at $%lx\n",
+			 (unsigned long) z2->resource.start);
 
 		info->fix.smem_start = board_addr;
 		if (board_addr > 0x01000000)
@@ -2392,27 +2301,32 @@
 		cinfo->regbase = (caddr_t) ZTWO_VADDR(z2->resource.start);
 		info->fix.mmio_start = z2->resource.start;
 
-		DPRINTK("cirrusfb: Virtual address for board set to: $%p\n",
+		dev_dbg(info->device, "Virtual address for board set to: $%p\n",
 			cinfo->regbase);
 	}
 	cinfo->unmap = cirrusfb_zorro_unmap;
 
-	printk(KERN_INFO "Cirrus Logic chipset on Zorro bus\n");
+	dev_info(info->device,
+		 "Cirrus Logic chipset on Zorro bus, RAM (%lu MB) at $%lx\n",
+		 board_size / MB_, board_addr);
+
 	zorro_set_drvdata(z, info);
 
+	/* MCLK select etc. */
+	if (cirrusfb_board_info[btype].init_sr1f)
+		vga_wseq(cinfo->regbase, CL_SEQR1F,
+			 cirrusfb_board_info[btype].sr1f);
+
 	ret = cirrusfb_register(info);
-	if (ret) {
-		if (btype == BT_PICASSO4) {
-			iounmap(info->screen_base);
-			iounmap(cinfo->regbase - 0x600000);
-		} else if (board_addr > 0x01000000)
-			iounmap(info->screen_base);
-	}
-	return ret;
+	if (!ret)
+		return 0;
+
+	if (btype == BT_PICASSO4 || board_addr > 0x01000000)
+		iounmap(info->screen_base);
 
 err_unmap_regbase:
-	/* Parental advisory: explicit hack */
-	iounmap(cinfo->regbase - 0x600000);
+	if (btype == BT_PICASSO4)
+		iounmap(cinfo->regbase - 0x600000);
 err_release_region:
 	release_region(board_addr, board_size);
 err_release_fb:
@@ -2424,11 +2338,8 @@
 void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
 {
 	struct fb_info *info = zorro_get_drvdata(z);
-	DPRINTK("ENTER\n");
 
 	cirrusfb_cleanup(info);
-
-	DPRINTK("EXIT\n");
 }
 
 static struct zorro_driver cirrusfb_zorro_driver = {
@@ -2439,6 +2350,37 @@
 };
 #endif /* CONFIG_ZORRO */
 
+#ifndef MODULE
+static int __init cirrusfb_setup(char *options)
+{
+	char *this_opt;
+
+	if (!options || !*options)
+		return 0;
+
+	while ((this_opt = strsep(&options, ",")) != NULL) {
+		if (!*this_opt)
+			continue;
+
+		if (!strcmp(this_opt, "noaccel"))
+			noaccel = 1;
+		else if (!strncmp(this_opt, "mode:", 5))
+			mode_option = this_opt + 5;
+		else
+			mode_option = this_opt;
+	}
+	return 0;
+}
+#endif
+
+    /*
+     *  Modularization
+     */
+
+MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
+MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
+MODULE_LICENSE("GPL");
+
 static int __init cirrusfb_init(void)
 {
 	int error = 0;
@@ -2460,40 +2402,6 @@
 	return error;
 }
 
-#ifndef MODULE
-static int __init cirrusfb_setup(char *options) {
-	char *this_opt;
-
-	DPRINTK("ENTER\n");
-
-	if (!options || !*options)
-		return 0;
-
-	while ((this_opt = strsep(&options, ",")) != NULL) {
-		if (!*this_opt)
-			continue;
-
-		DPRINTK("cirrusfb_setup: option '%s'\n", this_opt);
-
-		if (!strcmp(this_opt, "noaccel"))
-			noaccel = 1;
-		else if (!strncmp(this_opt, "mode:", 5))
-			mode_option = this_opt + 5;
-		else
-			mode_option = this_opt;
-	}
-	return 0;
-}
-#endif
-
-    /*
-     *  Modularization
-     */
-
-MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
-MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
-MODULE_LICENSE("GPL");
-
 static void __exit cirrusfb_exit(void)
 {
 #ifdef CONFIG_PCI
@@ -2560,8 +2468,6 @@
 {
 	assert(cinfo != NULL);
 
-	DPRINTK("ENTER\n");
-
 	if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) {
 		/* if we're just in "write value" mode, write back the */
 		/* same value as before to not modify anything */
@@ -2574,8 +2480,6 @@
 
 	/* dummy write on Reg0 to be on "write index" mode next time */
 	vga_w(cinfo->regbase, VGA_ATT_IW, 0x00);
-
-	DPRINTK("EXIT\n");
 }
 
 /*** WHDR() - write into the Hidden DAC register ***/
@@ -2588,6 +2492,8 @@
 {
 	unsigned char dummy;
 
+	if (is_laguna(cinfo))
+		return;
 	if (cinfo->btype == BT_PICASSO) {
 		/* Klaus' hint for correct access to HDR on some boards */
 		/* first write 0 to pixel mask (3c6) */
@@ -2655,7 +2561,8 @@
 	vga_w(cinfo->regbase, VGA_PEL_IW, regnum);
 
 	if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
-	    cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
+	    cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 ||
+	    cinfo->btype == BT_SD64 || is_laguna(cinfo)) {
 		/* but DAC data register IS, at least for Picasso II */
 		if (cinfo->btype == BT_PICASSO)
 			data += 0xfff;
@@ -2702,9 +2609,8 @@
 /* FIXME: use interrupts instead */
 static void cirrusfb_WaitBLT(u8 __iomem *regbase)
 {
-	/* now busy-wait until we're done */
 	while (vga_rgfx(regbase, CL_GR31) & 0x08)
-		/* do nothing */ ;
+		cpu_relax();
 }
 
 /*******************************************************************
@@ -2713,60 +2619,12 @@
 	perform accelerated "scrolling"
 ********************************************************************/
 
-static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
-			    u_short curx, u_short cury,
-			    u_short destx, u_short desty,
-			    u_short width, u_short height,
-			    u_short line_length)
+static void cirrusfb_set_blitter(u8 __iomem *regbase,
+			    u_short nwidth, u_short nheight,
+			    u_long nsrc, u_long ndest,
+			    u_short bltmode, u_short line_length)
+
 {
-	u_short nwidth, nheight;
-	u_long nsrc, ndest;
-	u_char bltmode;
-
-	DPRINTK("ENTER\n");
-
-	nwidth = width - 1;
-	nheight = height - 1;
-
-	bltmode = 0x00;
-	/* if source adr < dest addr, do the Blt backwards */
-	if (cury <= desty) {
-		if (cury == desty) {
-			/* if src and dest are on the same line, check x */
-			if (curx < destx)
-				bltmode |= 0x01;
-		} else
-			bltmode |= 0x01;
-	}
-	if (!bltmode) {
-		/* standard case: forward blitting */
-		nsrc = (cury * line_length) + curx;
-		ndest = (desty * line_length) + destx;
-	} else {
-		/* this means start addresses are at the end,
-		 * counting backwards
-		 */
-		nsrc = cury * line_length + curx +
-			nheight * line_length + nwidth;
-		ndest = desty * line_length + destx +
-			nheight * line_length + nwidth;
-	}
-
-	/*
-	   run-down of registers to be programmed:
-	   destination pitch
-	   source pitch
-	   BLT width/height
-	   source start
-	   destination start
-	   BLT mode
-	   BLT ROP
-	   VGA_GFX_SR_VALUE / VGA_GFX_SR_ENABLE: "fill color"
-	   start/stop
-	 */
-
-	cirrusfb_WaitBLT(regbase);
-
 	/* pitch: set to line_length */
 	/* dest pitch low */
 	vga_wgfx(regbase, CL_GR24, line_length & 0xff);
@@ -2813,8 +2671,50 @@
 
 	/* and finally: GO! */
 	vga_wgfx(regbase, CL_GR31, 0x02);	/* BLT Start/status */
+}
 
-	DPRINTK("EXIT\n");
+/*******************************************************************
+	cirrusfb_BitBLT()
+
+	perform accelerated "scrolling"
+********************************************************************/
+
+static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
+			    u_short curx, u_short cury,
+			    u_short destx, u_short desty,
+			    u_short width, u_short height,
+			    u_short line_length)
+{
+	u_short nwidth = width - 1;
+	u_short nheight = height - 1;
+	u_long nsrc, ndest;
+	u_char bltmode;
+
+	bltmode = 0x00;
+	/* if source adr < dest addr, do the Blt backwards */
+	if (cury <= desty) {
+		if (cury == desty) {
+			/* if src and dest are on the same line, check x */
+			if (curx < destx)
+				bltmode |= 0x01;
+		} else
+			bltmode |= 0x01;
+	}
+	/* standard case: forward blitting */
+	nsrc = (cury * line_length) + curx;
+	ndest = (desty * line_length) + destx;
+	if (bltmode) {
+		/* this means start addresses are at the end,
+		 * counting backwards
+		 */
+		nsrc += nheight * line_length + nwidth;
+		ndest += nheight * line_length + nwidth;
+	}
+
+	cirrusfb_WaitBLT(regbase);
+
+	cirrusfb_set_blitter(regbase, nwidth, nheight,
+			    nsrc, ndest, bltmode, line_length);
 }
 
 /*******************************************************************
@@ -2825,79 +2725,37 @@
 
 static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
 		     u_short x, u_short y, u_short width, u_short height,
-		     u_char color, u_short line_length)
+		     u32 fg_color, u32 bg_color, u_short line_length,
+		     u_char blitmode)
 {
-	u_short nwidth, nheight;
-	u_long ndest;
+	u_long ndest = (y * line_length) + x;
 	u_char op;
 
-	DPRINTK("ENTER\n");
-
-	nwidth = width - 1;
-	nheight = height - 1;
-
-	ndest = (y * line_length) + x;
-
 	cirrusfb_WaitBLT(regbase);
 
-	/* pitch: set to line_length */
-	vga_wgfx(regbase, CL_GR24, line_length & 0xff);	/* dest pitch low */
-	vga_wgfx(regbase, CL_GR25, line_length >> 8);	/* dest pitch hi */
-	vga_wgfx(regbase, CL_GR26, line_length & 0xff);	/* source pitch low */
-	vga_wgfx(regbase, CL_GR27, line_length >> 8);	/* source pitch hi */
-
-	/* BLT width: actual number of pixels - 1 */
-	vga_wgfx(regbase, CL_GR20, nwidth & 0xff);	/* BLT width low */
-	vga_wgfx(regbase, CL_GR21, nwidth >> 8);	/* BLT width hi */
-
-	/* BLT height: actual number of lines -1 */
-	vga_wgfx(regbase, CL_GR22, nheight & 0xff);	/* BLT height low */
-	vga_wgfx(regbase, CL_GR23, nheight >> 8);	/* BLT width hi */
-
-	/* BLT destination */
-	/* BLT dest low */
-	vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
-	/* BLT dest mid */
-	vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
-	/* BLT dest hi */
-	vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
-
-	/* BLT source: set to 0 (is a dummy here anyway) */
-	vga_wgfx(regbase, CL_GR2C, 0x00);	/* BLT src low */
-	vga_wgfx(regbase, CL_GR2D, 0x00);	/* BLT src mid */
-	vga_wgfx(regbase, CL_GR2E, 0x00);	/* BLT src hi */
-
 	/* This is a ColorExpand Blt, using the */
 	/* same color for foreground and background */
-	vga_wgfx(regbase, VGA_GFX_SR_VALUE, color);	/* foreground color */
-	vga_wgfx(regbase, VGA_GFX_SR_ENABLE, color);	/* background color */
+	vga_wgfx(regbase, VGA_GFX_SR_VALUE, bg_color);
+	vga_wgfx(regbase, VGA_GFX_SR_ENABLE, fg_color);
 
-	op = 0xc0;
-	if (bits_per_pixel == 16) {
-		vga_wgfx(regbase, CL_GR10, color);	/* foreground color */
-		vga_wgfx(regbase, CL_GR11, color);	/* background color */
-		op = 0x50;
-		op = 0xd0;
-	} else if (bits_per_pixel == 32) {
-		vga_wgfx(regbase, CL_GR10, color);	/* foreground color */
-		vga_wgfx(regbase, CL_GR11, color);	/* background color */
-		vga_wgfx(regbase, CL_GR12, color);	/* foreground color */
-		vga_wgfx(regbase, CL_GR13, color);	/* background color */
-		vga_wgfx(regbase, CL_GR14, 0);	/* foreground color */
-		vga_wgfx(regbase, CL_GR15, 0);	/* background color */
-		op = 0x50;
-		op = 0xf0;
+	op = 0x80;
+	if (bits_per_pixel >= 16) {
+		vga_wgfx(regbase, CL_GR10, bg_color >> 8);
+		vga_wgfx(regbase, CL_GR11, fg_color >> 8);
+		op = 0x90;
 	}
-	/* BLT mode: color expand, Enable 8x8 copy (faster?) */
-	vga_wgfx(regbase, CL_GR30, op);	/* BLT mode */
-
-	/* BLT ROP: SrcCopy */
-	vga_wgfx(regbase, CL_GR32, 0x0d);	/* BLT ROP */
-
-	/* and finally: GO! */
-	vga_wgfx(regbase, CL_GR31, 0x02);	/* BLT Start/status */
-
-	DPRINTK("EXIT\n");
+	if (bits_per_pixel >= 24) {
+		vga_wgfx(regbase, CL_GR12, bg_color >> 16);
+		vga_wgfx(regbase, CL_GR13, fg_color >> 16);
+		op = 0xa0;
+	}
+	if (bits_per_pixel == 32) {
+		vga_wgfx(regbase, CL_GR14, bg_color >> 24);
+		vga_wgfx(regbase, CL_GR15, fg_color >> 24);
+		op = 0xb0;
+	}
+	cirrusfb_set_blitter(regbase, width - 1, height - 1,
+			    0, ndest, op | blitmode, line_length);
 }
 
 /**************************************************************************
@@ -2917,8 +2775,6 @@
 	*den = 0;
 	*div = 0;
 
-	DPRINTK("ENTER\n");
-
 	if (freq < 8000)
 		freq = 8000;
 
@@ -2960,12 +2816,6 @@
 			}
 		}
 	}
-
-	DPRINTK("Best possible values for given frequency:\n");
-	DPRINTK("	freq: %ld kHz  nom: %d  den: %d  div: %d\n",
-		freq, *nom, *den, *div);
-
-	DPRINTK("EXIT\n");
 }
 
 /* -------------------------------------------------------------------------
@@ -2978,32 +2828,6 @@
 #ifdef CIRRUSFB_DEBUG
 
 /**
- * cirrusfb_dbg_print_byte
- * @name: name associated with byte value to be displayed
- * @val: byte value to be displayed
- *
- * DESCRIPTION:
- * Display an indented string, along with a hexidecimal byte value, and
- * its decoded bits.  Bits 7 through 0 are listed in left-to-right
- * order.
- */
-
-static
-void cirrusfb_dbg_print_byte(const char *name, unsigned char val)
-{
-	DPRINTK("%8s = 0x%02X (bits 7-0: %c%c%c%c%c%c%c%c)\n",
-		name, val,
-		val & 0x80 ? '1' : '0',
-		val & 0x40 ? '1' : '0',
-		val & 0x20 ? '1' : '0',
-		val & 0x10 ? '1' : '0',
-		val & 0x08 ? '1' : '0',
-		val & 0x04 ? '1' : '0',
-		val & 0x02 ? '1' : '0',
-		val & 0x01 ? '1' : '0');
-}
-
-/**
  * cirrusfb_dbg_print_regs
  * @base: If using newmmio, the newmmio base address, otherwise %NULL
  * @reg_class: type of registers to read: %CRT, or %SEQ
@@ -3014,9 +2838,9 @@
  * used at the given @base address to query the information.
  */
 
-static
-void cirrusfb_dbg_print_regs(caddr_t regbase,
-			     enum cirrusfb_dbg_reg_class reg_class, ...)
+static void cirrusfb_dbg_print_regs(struct fb_info *info,
+				    caddr_t regbase,
+				    enum cirrusfb_dbg_reg_class reg_class, ...)
 {
 	va_list list;
 	unsigned char val = 0;
@@ -3042,7 +2866,7 @@
 			break;
 		}
 
-		cirrusfb_dbg_print_byte(name, val);
+		dev_dbg(info->device, "%8s = 0x%02X\n", name, val);
 
 		name = va_arg(list, char *);
 	}
@@ -3051,18 +2875,6 @@
 }
 
 /**
- * cirrusfb_dump
- * @cirrusfbinfo:
- *
- * DESCRIPTION:
- */
-
-static void cirrusfb_dump(void)
-{
-	cirrusfb_dbg_reg_dump(NULL);
-}
-
-/**
  * cirrusfb_dbg_reg_dump
  * @base: If using newmmio, the newmmio base address, otherwise %NULL
  *
@@ -3072,12 +2884,11 @@
  * used at the given @base address to query the information.
  */
 
-static
-void cirrusfb_dbg_reg_dump(caddr_t regbase)
+static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase)
 {
-	DPRINTK("CIRRUSFB VGA CRTC register dump:\n");
+	dev_dbg(info->device, "VGA CRTC register dump:\n");
 
-	cirrusfb_dbg_print_regs(regbase, CRT,
+	cirrusfb_dbg_print_regs(info, regbase, CRT,
 			   "CR00", 0x00,
 			   "CR01", 0x01,
 			   "CR02", 0x02,
@@ -3127,11 +2938,11 @@
 			   "CR3F", 0x3F,
 			   NULL);
 
-	DPRINTK("\n");
+	dev_dbg(info->device, "\n");
 
-	DPRINTK("CIRRUSFB VGA SEQ register dump:\n");
+	dev_dbg(info->device, "VGA SEQ register dump:\n");
 
-	cirrusfb_dbg_print_regs(regbase, SEQ,
+	cirrusfb_dbg_print_regs(info, regbase, SEQ,
 			   "SR00", 0x00,
 			   "SR01", 0x01,
 			   "SR02", 0x02,
@@ -3160,7 +2971,7 @@
 			   "SR1F", 0x1F,
 			   NULL);
 
-	DPRINTK("\n");
+	dev_dbg(info->device, "\n");
 }
 
 #endif				/* CIRRUSFB_DEBUG */
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 1657b96..2cd500a 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -2954,8 +2954,11 @@
 
 static int fbcon_fb_unregistered(struct fb_info *info)
 {
-	int i, idx = info->node;
+	int i, idx;
 
+	if (!lock_fb_info(info))
+		return -ENODEV;
+	idx = info->node;
 	for (i = first_fb_vc; i <= last_fb_vc; i++) {
 		if (con2fb_map[i] == idx)
 			con2fb_map[i] = -1;
@@ -2979,13 +2982,14 @@
 		}
 	}
 
-	if (!num_registered_fb)
-		unregister_con_driver(&fb_con);
-
-
 	if (primary_device == idx)
 		primary_device = -1;
 
+	unlock_fb_info(info);
+
+	if (!num_registered_fb)
+		unregister_con_driver(&fb_con);
+
 	return 0;
 }
 
@@ -3021,9 +3025,13 @@
 
 static int fbcon_fb_registered(struct fb_info *info)
 {
-	int ret = 0, i, idx = info->node;
+	int ret = 0, i, idx;
 
+	if (!lock_fb_info(info))
+		return -ENODEV;
+	idx = info->node;
 	fbcon_select_primary(info);
+	unlock_fb_info(info);
 
 	if (info_idx == -1) {
 		for (i = first_fb_vc; i <= last_fb_vc; i++) {
@@ -3124,7 +3132,7 @@
 	}
 }
 
-static int fbcon_event_notify(struct notifier_block *self, 
+static int fbcon_event_notify(struct notifier_block *self,
 			      unsigned long action, void *data)
 {
 	struct fb_event *event = data;
@@ -3132,7 +3140,7 @@
 	struct fb_videomode *mode;
 	struct fb_con2fbmap *con2fb;
 	struct fb_blit_caps *caps;
-	int ret = 0;
+	int idx, ret = 0;
 
 	/*
 	 * ignore all events except driver registration and deregistration
@@ -3144,23 +3152,54 @@
 
 	switch(action) {
 	case FB_EVENT_SUSPEND:
+		if (!lock_fb_info(info)) {
+			ret = -ENODEV;
+			goto done;
+		}
 		fbcon_suspended(info);
+		unlock_fb_info(info);
 		break;
 	case FB_EVENT_RESUME:
+		if (!lock_fb_info(info)) {
+			ret = -ENODEV;
+			goto done;
+		}
 		fbcon_resumed(info);
+		unlock_fb_info(info);
 		break;
 	case FB_EVENT_MODE_CHANGE:
+		if (!lock_fb_info(info)) {
+			ret = -ENODEV;
+			goto done;
+		}
 		fbcon_modechanged(info);
+		unlock_fb_info(info);
 		break;
 	case FB_EVENT_MODE_CHANGE_ALL:
+		if (!lock_fb_info(info)) {
+			ret = -ENODEV;
+			goto done;
+		}
 		fbcon_set_all_vcs(info);
+		unlock_fb_info(info);
 		break;
 	case FB_EVENT_MODE_DELETE:
 		mode = event->data;
+		if (!lock_fb_info(info)) {
+			ret = -ENODEV;
+			goto done;
+		}
 		ret = fbcon_mode_deleted(info, mode);
+		unlock_fb_info(info);
 		break;
 	case FB_EVENT_FB_UNBIND:
-		ret = fbcon_fb_unbind(info->node);
+		if (!lock_fb_info(info)) {
+			ret = -ENODEV;
+			goto done;
+		}
+		idx = info->node;
+		unlock_fb_info(info);
+		ret = fbcon_fb_unbind(idx);
 		break;
 	case FB_EVENT_FB_REGISTERED:
 		ret = fbcon_fb_registered(info);
@@ -3178,17 +3217,31 @@
 		con2fb->framebuffer = con2fb_map[con2fb->console - 1];
 		break;
 	case FB_EVENT_BLANK:
+		if (!lock_fb_info(info)) {
+			ret = -ENODEV;
+			goto done;
+		}
 		fbcon_fb_blanked(info, *(int *)event->data);
+		unlock_fb_info(info);
 		break;
 	case FB_EVENT_NEW_MODELIST:
+		if (!lock_fb_info(info)) {
+			ret = -ENODEV;
+			goto done;
+		}
 		fbcon_new_modelist(info);
+		unlock_fb_info(info);
 		break;
 	case FB_EVENT_GET_REQ:
 		caps = event->data;
+		if (!lock_fb_info(info)) {
+			ret = -ENODEV;
+			goto done;
+		}
 		fbcon_get_requirement(info, caps);
+		unlock_fb_info(info);
 		break;
 	}
-
 done:
 	return ret;
 }
diff --git a/drivers/video/cyblafb.c b/drivers/video/cyblafb.c
deleted file mode 100644
index 9704b73..0000000
--- a/drivers/video/cyblafb.c
+++ /dev/null
@@ -1,1683 +0,0 @@
-/*
- * Frame buffer driver for Trident Cyberblade/i1 graphics core
- *
- * Copyright 2005 Knut Petersen <Knut_Petersen@t-online.de>
- *
- * CREDITS:
- *	tridentfb.c by Jani Monoses
- *	see files above for further credits
- *
- */
-
-#define CYBLAFB_DEBUG 0
-#define CYBLAFB_KD_GRAPHICS_QUIRK 1
-
-#define CYBLAFB_PIXMAPSIZE 8192
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <asm/types.h>
-#include <video/cyblafb.h>
-
-#define VERSION "0.62"
-
-struct cyblafb_par {
-	u32 pseudo_pal[16];
-	struct fb_ops ops;
-};
-
-static struct fb_fix_screeninfo cyblafb_fix __devinitdata = {
-	.id = "CyBla",
-	.type = FB_TYPE_PACKED_PIXELS,
-	.xpanstep = 1,
-	.ypanstep = 1,
-	.ywrapstep = 1,
-	.visual = FB_VISUAL_PSEUDOCOLOR,
-	.accel = FB_ACCEL_NONE,
-};
-
-static char *mode __devinitdata = NULL;
-static int bpp __devinitdata = 8;
-static int ref __devinitdata = 75;
-static int fp __devinitdata;
-static int crt __devinitdata;
-static int memsize __devinitdata;
-
-static int basestride;
-static int vesafb;
-static int nativex;
-static int center;
-static int stretch;
-static int pciwb = 1;
-static int pcirb = 1;
-static int pciwr = 1;
-static int pcirr = 1;
-static int disabled;
-static int verbosity;
-static int displaytype;
-
-static void __iomem *io_virt;	// iospace virtual memory address
-
-module_param(mode, charp, 0);
-module_param(bpp, int, 0);
-module_param(ref, int, 0);
-module_param(fp, int, 0);
-module_param(crt, int, 0);
-module_param(nativex, int, 0);
-module_param(center, int, 0);
-module_param(stretch, int, 0);
-module_param(pciwb, int, 0);
-module_param(pcirb, int, 0);
-module_param(pciwr, int, 0);
-module_param(pcirr, int, 0);
-module_param(memsize, int, 0);
-module_param(verbosity, int, 0);
-
-//=========================================
-//
-// Well, we have to fix the upper layers.
-// Until this has been done, we work around
-// the bugs.
-//
-//=========================================
-
-#if (CYBLAFB_KD_GRAPHICS_QUIRK && CYBLAFB_DEBUG)
-	if (disabled) { \
-		printk("********\n");\
-		dump_stack();\
-		return val;\
-	}
-
-#elif CYBLAFB_KD_GRAPHICS_QUIRK
-#define KD_GRAPHICS_RETURN(val)\
-	if (disabled) {\
-		return val;\
-	}
-#else
-#define KD_GRAPHICS_RETURN(val)
-#endif
-
-//=========================================
-//
-// Port access macros for memory mapped io
-//
-//=========================================
-
-#define out8(r, v) writeb(v, io_virt + r)
-#define out32(r, v) writel(v, io_virt + r)
-#define in8(r) readb(io_virt + r)
-#define in32(r) readl(io_virt + r)
-
-//======================================
-//
-// Hardware access inline functions
-//
-//======================================
-
-static inline u8 read3X4(u32 reg)
-{
-	out8(0x3D4, reg);
-	return in8(0x3D5);
-}
-
-static inline u8 read3C4(u32 reg)
-{
-	out8(0x3C4, reg);
-	return in8(0x3C5);
-}
-
-static inline u8 read3CE(u32 reg)
-{
-	out8(0x3CE, reg);
-	return in8(0x3CF);
-}
-
-static inline void write3X4(u32 reg, u8 val)
-{
-	out8(0x3D4, reg);
-	out8(0x3D5, val);
-}
-
-static inline void write3C4(u32 reg, u8 val)
-{
-	out8(0x3C4, reg);
-	out8(0x3C5, val);
-}
-
-static inline void write3CE(u32 reg, u8 val)
-{
-	out8(0x3CE, reg);
-	out8(0x3CF, val);
-}
-
-static inline void write3C0(u32 reg, u8 val)
-{
-	in8(0x3DA);		// read to reset index
-	out8(0x3C0, reg);
-	out8(0x3C0, val);
-}
-
-//=================================================
-//
-// Enable memory mapped io and unprotect registers
-//
-//=================================================
-
-static void enable_mmio(void)
-{
-	u8 tmp;
-
-	outb(0x0B, 0x3C4);
-	inb(0x3C5);		// Set NEW mode
-	outb(SR0E, 0x3C4);	// write enable a lot of extended ports
-	outb(0x80, 0x3C5);
-
-	outb(SR11, 0x3C4);	// write enable those extended ports that
-	outb(0x87, 0x3C5);	// are not affected by SR0E_New
-
-	outb(CR1E, 0x3d4);	// clear write protect bit for port 0x3c2
-	tmp = inb(0x3d5) & 0xBF;
-	outb(CR1E, 0x3d4);
-	outb(tmp, 0x3d5);
-
-	outb(CR39, 0x3D4);
-	outb(inb(0x3D5) | 0x01, 0x3D5); // Enable mmio
-}
-
-//=================================================
-//
-// Set pixel clock VCLK1
-// - multipliers set elswhere
-// - freq in units of 0.01 MHz
-//
-// Hardware bug: SR18 >= 250 is broken for the
-//		 cyberblade/i1
-//
-//=================================================
-
-static void set_vclk(struct cyblafb_par *par, int freq)
-{
-	u32 m, n, k;
-	int f, fi, d, di;
-	u8 lo = 0, hi = 0;
-
-	d = 2000;
-	k = freq >= 10000 ? 0 : freq >= 5000 ? 1 : freq >= 2500 ? 2 : 3;
-	for (m = 0; m < 64; m++)
-		for (n = 0; n < 250; n++) {
-			fi = (int)(((5864727 * (n + 8)) /
-				    ((m + 2) * (1 << k))) >> 12);
-			if ((di = abs(fi - freq)) < d) {
-				d = di;
-				f = fi;
-				lo = (u8) n;
-				hi = (u8) ((k << 6) | m);
-			}
-		}
-	write3C4(SR19, hi);
-	write3C4(SR18, lo);
-	if (verbosity > 0)
-		output("pixclock = %d.%02d MHz, k/m/n %x %x %x\n",
-		       freq / 100, freq % 100, (hi & 0xc0) >> 6, hi & 0x3f, lo);
-}
-
-//================================================
-//
-// Cyberblade specific Graphics Engine (GE) setup
-//
-//================================================
-
-static void cyblafb_setup_GE(int pitch, int bpp)
-{
-	KD_GRAPHICS_RETURN();
-
-	switch (bpp) {
-	case 8:
-		basestride = ((pitch >> 3) << 20) | (0 << 29);
-		break;
-	case 15:
-		basestride = ((pitch >> 3) << 20) | (5 << 29);
-		break;
-	case 16:
-		basestride = ((pitch >> 3) << 20) | (1 << 29);
-		break;
-	case 24:
-	case 32:
-		basestride = ((pitch >> 3) << 20) | (2 << 29);
-		break;
-	}
-
-	write3X4(CR36, 0x90);	// reset GE
-	write3X4(CR36, 0x80);	// enable GE
-	out32(GE24, 1 << 7);	// reset all GE pointers by toggling
-	out32(GE24, 0); 	//   d7 of GE24
-	write3X4(CR2D, 0x00);	// GE Timinigs, no delays
-	out32(GE6C, 0); 	// Pattern and Style, p 129, ok
-}
-
-//=====================================================================
-//
-// Cyberblade specific syncing
-//
-//   A timeout might be caused by disabled mmio.
-//   Cause:
-//     - bit CR39 & 1 == 0 upon return, X trident driver bug
-//     - kdm bug (KD_GRAPHICS not set on first switch)
-//     - kernel design flaw (it believes in the correctness
-//	 of kdm/X
-//   First we try to sync ignoring that problem, as most of the
-//   time that will succeed immediately and the enable_mmio()
-//   would only degrade performance.
-//
-//=====================================================================
-
-static int cyblafb_sync(struct fb_info *info)
-{
-	u32 status, i = 100000;
-
-	KD_GRAPHICS_RETURN(0);
-
-	while (((status = in32(GE20)) & 0xFe800000) && i != 0)
-		i--;
-
-	if (i == 0) {
-		enable_mmio();
-		i = 1000000;
-		while (((status = in32(GE20)) & 0xFA800000) && i != 0)
-			i--;
-		if (i == 0) {
-			output("GE Timeout, status: %x\n", status);
-			if (status & 0x80000000)
-				output("Bresenham Engine : Busy\n");
-			if (status & 0x40000000)
-				output("Setup Engine     : Busy\n");
-			if (status & 0x20000000)
-				output("SP / DPE         : Busy\n");
-			if (status & 0x10000000)
-				output("Memory Interface : Busy\n");
-			if (status & 0x08000000)
-				output("Com Lst Proc     : Busy\n");
-			if (status & 0x04000000)
-				output("Block Write      : Busy\n");
-			if (status & 0x02000000)
-				output("Command Buffer   : Full\n");
-			if (status & 0x01000000)
-				output("RESERVED         : Busy\n");
-			if (status & 0x00800000)
-				output("PCI Write Buffer : Busy\n");
-			cyblafb_setup_GE(info->var.xres,
-					 info->var.bits_per_pixel);
-		}
-	}
-
-	return 0;
-}
-
-//==============================
-//
-// Cyberblade specific fillrect
-//
-//==============================
-
-static void cyblafb_fillrect(struct fb_info *info, const struct fb_fillrect *fr)
-{
-	u32 bpp = info->var.bits_per_pixel, col, desty, height;
-
-	KD_GRAPHICS_RETURN();
-
-	switch (bpp) {
-	default:
-	case 8:
-		col = fr->color;
-		col |= col << 8;
-		col |= col << 16;
-		break;
-	case 16:
-		col = ((u32 *) (info->pseudo_palette))[fr->color];
-		col |= col << 16;
-		break;
-	case 32:
-		col = ((u32 *) (info->pseudo_palette))[fr->color];
-		break;
-	}
-
-	desty = fr->dy;
-	height = fr->height;
-	while (height) {
-		out32(GEB8, basestride | ((desty * info->var.xres_virtual *
-					   bpp) >> 6));
-		out32(GE60, col);
-		out32(GE48, fr->rop ? 0x66 : ROP_S);
-		out32(GE44, 0x20000000 | 1 << 19 | 1 << 4 | 2 << 2);
-		out32(GE08, point(fr->dx, 0));
-		out32(GE0C, point(fr->dx + fr->width - 1,
-				  height > 4096 ? 4095 : height - 1));
-		if (likely(height <= 4096))
-			return;
-		desty += 4096;
-		height -= 4096;
-	}
-}
-
-//================================================
-//
-// Cyberblade specific copyarea
-//
-// This function silently assumes that it never
-// will be called with width or height exceeding
-// 4096.
-//
-//================================================
-
-static void cyblafb_copyarea(struct fb_info *info, const struct fb_copyarea *ca)
-{
-	u32 s1, s2, d1, d2, direction;
-
-	KD_GRAPHICS_RETURN();
-
-	s1 = point(ca->sx, 0);
-	s2 = point(ca->sx + ca->width - 1, ca->height - 1);
-	d1 = point(ca->dx, 0);
-	d2 = point(ca->dx + ca->width - 1, ca->height - 1);
-
-	if ((ca->sy > ca->dy) || ((ca->sy == ca->dy) && (ca->sx > ca->dx)))
-		direction = 0;
-	else
-		direction = 2;
-
-	out32(GEB8, basestride | ((ca->dy * info->var.xres_virtual *
-				   info->var.bits_per_pixel) >> 6));
-	out32(GEC8, basestride | ((ca->sy * info->var.xres_virtual *
-				   info->var.bits_per_pixel) >> 6));
-	out32(GE44, 0xa0000000 | 1 << 19 | 1 << 2 | direction);
-	out32(GE00, direction ? s2 : s1);
-	out32(GE04, direction ? s1 : s2);
-	out32(GE08, direction ? d2 : d1);
-	out32(GE0C, direction ? d1 : d2);
-}
-
-//=======================================================================
-//
-// Cyberblade specific imageblit
-//
-// Accelerated for the most usual case, blitting 1 - bit deep
-// character images. Everything else is passed to the generic imageblit
-// unless it is so insane that it is better to printk an alert.
-//
-// Hardware bug: _Never_ blit across pixel column 2048, that will lock
-// the system. We split those blit requests into three blitting
-// operations.
-//
-//=======================================================================
-
-static void cyblafb_imageblit(struct fb_info *info,
-			      const struct fb_image *image)
-{
-	u32 fgcol, bgcol;
-	u32 *pd = (u32 *) image->data;
-	u32 bpp = info->var.bits_per_pixel;
-
-	KD_GRAPHICS_RETURN();
-
-	// Used only for drawing the penguine (image->depth > 1)
-	if (image->depth != 1) {
-		cfb_imageblit(info, image);
-		return;
-	}
-	// That should never happen, but it would be fatal
-	if (image->width == 0 || image->height == 0) {
-		output("imageblit: width/height 0 detected\n");
-		return;
-	}
-
-	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
-	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
-		fgcol = ((u32 *) (info->pseudo_palette))[image->fg_color];
-		bgcol = ((u32 *) (info->pseudo_palette))[image->bg_color];
-	} else {
-		fgcol = image->fg_color;
-		bgcol = image->bg_color;
-	}
-
-	switch (bpp) {
-	case 8:
-		fgcol |= fgcol << 8;
-		bgcol |= bgcol << 8;
-	case 16:
-		fgcol |= fgcol << 16;
-		bgcol |= bgcol << 16;
-	default:
-		break;
-	}
-
-	out32(GEB8, basestride | ((image->dy * info->var.xres_virtual *
-				   bpp) >> 6));
-	out32(GE60, fgcol);
-	out32(GE64, bgcol);
-
-	if (!(image->dx < 2048 && (image->dx + image->width - 1) >= 2048)) {
-		u32 dds = ((image->width + 31) >> 5) * image->height;
-		out32(GE44, 0xa0000000 | 1 << 20 | 1 << 19);
-		out32(GE08, point(image->dx, 0));
-		out32(GE0C, point(image->dx + image->width - 1,
-				  image->height - 1));
-		while (dds--)
-			out32(GE9C, *pd++);
-	} else {
-		int i, j;
-		u32 ddstotal = (image->width + 31) >> 5;
-		u32 ddsleft = (2048 - image->dx + 31) >> 5;
-		u32 skipleft = ddstotal - ddsleft;
-
-		out32(GE44, 0xa0000000 | 1 << 20 | 1 << 19);
-		out32(GE08, point(image->dx, 0));
-		out32(GE0C, point(2048 - 1, image->height - 1));
-		for (i = 0; i < image->height; i++) {
-			for (j = 0; j < ddsleft; j++)
-				out32(GE9C, *pd++);
-			pd += skipleft;
-		}
-
-		if (image->dx % 32) {
-			out32(GE44, 0xa0000000 | 1 << 20 | 1 << 19);
-			out32(GE08, point(2048, 0));
-			if (image->width > ddsleft << 5)
-				out32(GE0C, point(image->dx + (ddsleft << 5) -
-						  1, image->height - 1));
-			else
-				out32(GE0C, point(image->dx + image->width - 1,
-						  image->height - 1));
-			pd = ((u32 *) image->data) + ddstotal - skipleft - 1;
-			for (i = 0; i < image->height; i++) {
-				out32(GE9C, swab32(swab32(*pd) << ((32 -
-					    (image->dx & 31)) & 31)));
-				pd += ddstotal;
-			}
-		}
-
-		if (skipleft) {
-			out32(GE44, 0xa0000000 | 1 << 20 | 1 << 19);
-			out32(GE08, point(image->dx + (ddsleft << 5), 0));
-			out32(GE0C, point(image->dx + image->width - 1,
-					  image->height - 1));
-			pd = (u32 *) image->data;
-			for (i = 0; i < image->height; i++) {
-				pd += ddsleft;
-				for (j = 0; j < skipleft; j++)
-					out32(GE9C, *pd++);
-			}
-		}
-	}
-}
-
-//==========================================================
-//
-// Check if video mode is acceptable. We change var->??? if
-// video mode is slightly off or return error otherwise.
-// info->??? must not be changed!
-//
-//==========================================================
-
-static int cyblafb_check_var(struct fb_var_screeninfo *var,
-			     struct fb_info *info)
-{
-	int bpp = var->bits_per_pixel;
-
-	//
-	// we try to support 8, 16, 24 and 32 bpp modes,
-	// default to 8
-	//
-	// there is a 24 bpp mode, but for now we change requests to 32 bpp
-	// (This is what tridentfb does ... will be changed in the future)
-	//
-	//
-	if (bpp % 8 != 0 || bpp < 8 || bpp > 32)
-		bpp = 8;
-	if (bpp == 24)
-		bpp = var->bits_per_pixel = 32;
-
-	//
-	// interlaced modes are broken, fail if one is requested
-	//
-	if (var->vmode & FB_VMODE_INTERLACED)
-		return -EINVAL;
-
-	//
-	// fail if requested resolution is higher than physical
-	// flatpanel resolution
-	//
-	if ((displaytype == DISPLAY_FP) && nativex && var->xres > nativex)
-		return -EINVAL;
-
-	//
-	// we do not allow vclk to exceed 230 MHz. If the requested
-	// vclk is too high, we default to 200 MHz
-	//
-	if ((bpp == 32 ? 200000000 : 100000000) / var->pixclock > 23000)
-		var->pixclock = (bpp == 32 ? 200000000 : 100000000) / 20000;
-
-	//
-	// enforce (h|v)sync_len limits
-	//
-	var->hsync_len &= ~7;
-	if(var->hsync_len > 248)
-		var->hsync_len = 248;
-
-	var->vsync_len &= 15;
-
-	//
-	// Enforce horizontal and vertical hardware limits.
-	// 1600x1200 is mentioned as a maximum, but higher resolutions could
-	// work with slow refresh, small margins and short sync.
-	//
-	var->xres &= ~7;
-
-	if (((var->xres + var->left_margin + var->right_margin +
-			var->hsync_len) > (bpp == 32 ? 2040 : 4088)) ||
-			((var->yres + var->upper_margin + var->lower_margin +
-			var->vsync_len) > 2047))
-		return -EINVAL;
-
-	if ((var->xres > 1600) || (var->yres > 1200))
-		output("Mode %dx%d exceeds documented limits.\n",
-					   var->xres, var->yres);
-	//
-	// try to be smart about (x|y)res_virtual problems.
-	//
-	if (var->xres > var->xres_virtual)
-		var->xres_virtual = var->xres;
-	if (var->yres > var->yres_virtual)
-		var->yres_virtual = var->yres;
-
-	if (bpp == 8 || bpp == 16) {
-		if (var->xres_virtual > 4088)
-			var->xres_virtual = 4088;
-	} else {
-		if (var->xres_virtual > 2040)
-			var->xres_virtual = 2040;
-	}
-	var->xres_virtual &= ~7;
-	while (var->xres_virtual * var->yres_virtual * bpp / 8 >
-	       info->fix.smem_len) {
-		if (var->yres_virtual > var->yres)
-			var->yres_virtual--;
-		else if (var->xres_virtual > var->xres)
-			var->xres_virtual -= 8;
-		else
-			return -EINVAL;
-	}
-
-	switch (bpp) {
-	case 8:
-		var->red.offset = 0;
-		var->green.offset = 0;
-		var->blue.offset = 0;
-		var->red.length = 6;
-		var->green.length = 6;
-		var->blue.length = 6;
-		break;
-	case 16:
-		var->red.offset = 11;
-		var->green.offset = 5;
-		var->blue.offset = 0;
-		var->red.length = 5;
-		var->green.length = 6;
-		var->blue.length = 5;
-		break;
-	case 32:
-		var->red.offset = 16;
-		var->green.offset = 8;
-		var->blue.offset = 0;
-		var->red.length = 8;
-		var->green.length = 8;
-		var->blue.length = 8;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-//=====================================================================
-//
-// Pan the display
-//
-// The datasheets defines crt start address to be 20 bits wide and
-// to be programmed to CR0C, CR0D, CR1E and CR27. Actually there is
-// CR2B[5] as an undocumented extension bit. Epia BIOS 2.07 does use
-// it, so it is also safe to be used here. BTW: datasheet CR0E on page
-// 90 really is CR1E, the real CRE is documented on page 72.
-//
-// BUT:
-//
-// As of internal version 0.60 we do not use vga panning any longer.
-// Vga panning did not allow us the use of all available video memory
-// and thus prevented ywrap scrolling. We do use the "right view"
-// register now.
-//
-//
-//=====================================================================
-
-static int cyblafb_pan_display(struct fb_var_screeninfo *var,
-			       struct fb_info *info)
-{
-	KD_GRAPHICS_RETURN(0);
-
-	info->var.xoffset = var->xoffset;
-	info->var.yoffset = var->yoffset;
-	out32(GE10, 0x80000000 | ((var->xoffset + (var->yoffset *
-		    var->xres_virtual)) * var->bits_per_pixel / 32));
-	return 0;
-}
-
-//============================================
-//
-// This will really help in case of a bug ...
-// dump most gaphics core registers.
-//
-//============================================
-
-static void regdump(struct cyblafb_par *par)
-{
-	int i;
-
-	if (verbosity < 2)
-		return;
-
-	printk("\n");
-	for (i = 0; i <= 0xff; i++) {
-		outb(i, 0x3d4);
-		printk("CR%02x=%02x ", i, inb(0x3d5));
-		if (i % 16 == 15)
-			printk("\n");
-	}
-
-	outb(0x30, 0x3ce);
-	outb(inb(0x3cf) | 0x40, 0x3cf);
-	for (i = 0; i <= 0x1f; i++) {
-		if (i == 0 || (i > 2 && i < 8) || i == 0x10 || i == 0x11
-		    || i == 0x16) {
-			outb(i, 0x3d4);
-			printk("CR%02x=%02x ", i, inb(0x3d5));
-		} else
-			printk("------- ");
-		if (i % 16 == 15)
-			printk("\n");
-	}
-	outb(0x30, 0x3ce);
-	outb(inb(0x3cf) & 0xbf, 0x3cf);
-
-	printk("\n");
-	for (i = 0; i <= 0x7f; i++) {
-		outb(i, 0x3ce);
-		printk("GR%02x=%02x ", i, inb(0x3cf));
-		if (i % 16 == 15)
-			printk("\n");
-	}
-
-	printk("\n");
-	for (i = 0; i <= 0xff; i++) {
-		outb(i, 0x3c4);
-		printk("SR%02x=%02x ", i, inb(0x3c5));
-		if (i % 16 == 15)
-			printk("\n");
-	}
-
-	printk("\n");
-	for (i = 0; i <= 0x1F; i++) {
-		inb(0x3da);	// next access is index!
-		outb(i, 0x3c0);
-		printk("AR%02x=%02x ", i, inb(0x3c1));
-		if (i % 16 == 15)
-			printk("\n");
-	}
-	printk("\n");
-
-	inb(0x3DA);		// reset internal flag to 3c0 index
-	outb(0x20, 0x3C0);	// enable attr
-
-	return;
-}
-
-//=======================================================================
-//
-// Save State
-//
-// This function is called while a switch to KD_TEXT is in progress,
-// before any of the other functions are called.
-//
-//=======================================================================
-
-static void cyblafb_save_state(struct fb_info *info)
-{
-	struct cyblafb_par *par = info->par;
-	if (verbosity > 0)
-		output("Switching to KD_TEXT\n");
-	disabled = 0;
-	regdump(par);
-	enable_mmio();
-	return;
-}
-
-//=======================================================================
-//
-// Restore State
-//
-// This function is called while a switch to KD_GRAPHICS is in progress,
-// We have to turn on vga style panning registers again because the
-// trident driver of X does not know about GE10.
-//
-//=======================================================================
-
-static void cyblafb_restore_state(struct fb_info *info)
-{
-	if (verbosity > 0)
-		output("Switching to KD_GRAPHICS\n");
-	out32(GE10, 0);
-	disabled = 1;
-	return;
-}
-
-//======================================
-//
-// Set hardware to requested video mode
-//
-//======================================
-
-static int cyblafb_set_par(struct fb_info *info)
-{
-	struct cyblafb_par *par = info->par;
-	u32 htotal, hdispend, hsyncstart, hsyncend, hblankstart,
-	    hblankend, preendfetch, vtotal, vdispend, vsyncstart,
-	    vsyncend, vblankstart, vblankend;
-	struct fb_var_screeninfo *var = &info->var;
-	int bpp = var->bits_per_pixel;
-	int i;
-
-	KD_GRAPHICS_RETURN(0);
-
-	if (verbosity > 0)
-		output("Switching to new mode: "
-		       "fbset -g %d %d %d %d %d -t %d %d %d %d %d %d %d\n",
-		       var->xres, var->yres, var->xres_virtual,
-		       var->yres_virtual, var->bits_per_pixel, var->pixclock,
-		       var->left_margin, var->right_margin, var->upper_margin,
-		       var->lower_margin, var->hsync_len, var->vsync_len);
-
-	htotal = (var->xres + var->left_margin + var->right_margin +
-		  var->hsync_len) / 8 - 5;
-	hdispend = var->xres / 8 - 1;
-	hsyncstart = (var->xres + var->right_margin) / 8;
-	hsyncend = var->hsync_len / 8;
-	hblankstart = hdispend + 1;
-	hblankend = htotal + 3; // should be htotal + 5, bios does it this way
-	preendfetch = ((var->xres >> 3) + 1) * ((bpp + 1) >> 3);
-
-	vtotal = var->yres + var->upper_margin + var->lower_margin +
-							var->vsync_len - 2;
-	vdispend = var->yres - 1;
-	vsyncstart = var->yres + var->lower_margin;
-	vblankstart = var->yres;
-	vblankend = vtotal; // should be vtotal + 2, but bios does it this way
-	vsyncend = var->vsync_len;
-
-	enable_mmio();		// necessary! ... check X ...
-
-	write3X4(CR11, read3X4(CR11) & 0x7F);	// unlock cr00 .. cr07
-
-	write3CE(GR30, 8);
-
-	if ((displaytype == DISPLAY_FP) && var->xres < nativex) {
-
-		// stretch or center ?
-
-		out8(0x3C2, 0xEB);
-
-		write3CE(GR30, read3CE(GR30) | 0x81);	// shadow mode on
-
-		if (center) {
-			write3CE(GR52, (read3CE(GR52) & 0x7C) | 0x80);
-			write3CE(GR53, (read3CE(GR53) & 0x7C) | 0x80);
-		} else if (stretch) {
-			write3CE(GR5D, 0);
-			write3CE(GR52, (read3CE(GR52) & 0x7C) | 1);
-			write3CE(GR53, (read3CE(GR53) & 0x7C) | 1);
-		}
-
-	} else {
-		out8(0x3C2, 0x2B);
-		write3CE(GR30, 8);
-	}
-
-	//
-	// Setup CRxx regs
-	//
-
-	write3X4(CR00, htotal & 0xFF);
-	write3X4(CR01, hdispend & 0xFF);
-	write3X4(CR02, hblankstart & 0xFF);
-	write3X4(CR03, hblankend & 0x1F);
-	write3X4(CR04, hsyncstart & 0xFF);
-	write3X4(CR05, (hsyncend & 0x1F) | ((hblankend & 0x20) << 2));
-	write3X4(CR06, vtotal & 0xFF);
-	write3X4(CR07, (vtotal & 0x100) >> 8 |
-		       (vdispend & 0x100) >> 7 |
-		       (vsyncstart & 0x100) >> 6 |
-		       (vblankstart & 0x100) >> 5 |
-		       0x10 |
-		       (vtotal & 0x200) >> 4 |
-		       (vdispend & 0x200) >> 3 | (vsyncstart & 0x200) >> 2);
-	write3X4(CR08, 0);
-	write3X4(CR09, (vblankstart & 0x200) >> 4 | 0x40 |	// FIX !!!
-		       ((info->var.vmode & FB_VMODE_DOUBLE) ? 0x80 : 0));
-	write3X4(CR0A, 0);	// Init to some reasonable default
-	write3X4(CR0B, 0);	// Init to some reasonable default
-	write3X4(CR0C, 0);	// Offset 0
-	write3X4(CR0D, 0);	// Offset 0
-	write3X4(CR0E, 0);	// Init to some reasonable default
-	write3X4(CR0F, 0);	// Init to some reasonable default
-	write3X4(CR10, vsyncstart & 0xFF);
-	write3X4(CR11, (vsyncend & 0x0F));
-	write3X4(CR12, vdispend & 0xFF);
-	write3X4(CR13, ((info->var.xres_virtual * bpp) / (4 * 16)) & 0xFF);
-	write3X4(CR14, 0x40);	// double word mode
-	write3X4(CR15, vblankstart & 0xFF);
-	write3X4(CR16, vblankend & 0xFF);
-	write3X4(CR17, 0xE3);
-	write3X4(CR18, 0xFF);
-	//	 CR19: needed for interlaced modes ... ignore it for now
-	write3X4(CR1A, 0x07);	// Arbitration Control Counter 1
-	write3X4(CR1B, 0x07);	// Arbitration Control Counter 2
-	write3X4(CR1C, 0x07);	// Arbitration Control Counter 3
-	write3X4(CR1D, 0x00);	// Don't know, doesn't hurt ; -)
-	write3X4(CR1E, (info->var.vmode & FB_VMODE_INTERLACED) ? 0x84 : 0x80);
-	//	 CR1F: do not set, contains BIOS info about memsize
-	write3X4(CR20, 0x20);	// enabe wr buf, disable 16bit planar mode
-	write3X4(CR21, 0x20);	// enable linear memory access
-	//	 CR22: RO cpu latch readback
-	//	 CR23: ???
-	//	 CR24: RO AR flag state
-	//	 CR25: RAMDAC rw timing, pclk buffer tristate control ????
-	//	 CR26: ???
-	write3X4(CR27, (vdispend & 0x400) >> 6 |
-		       (vsyncstart & 0x400) >> 5 |
-		       (vblankstart & 0x400) >> 4 |
-		       (vtotal & 0x400) >> 3 |
-		       0x8);
-	//	 CR28: ???
-	write3X4(CR29, (read3X4(CR29) & 0xCF) | ((((info->var.xres_virtual *
-			bpp) / (4 * 16)) & 0x300) >> 4));
-	write3X4(CR2A, read3X4(CR2A) | 0x40);
-	write3X4(CR2B, (htotal & 0x100) >> 8 |
-		       (hdispend & 0x100) >> 7 |
-		       // (0x00 & 0x100) >> 6 |   hinterlace para bit 8 ???
-		       (hsyncstart & 0x100) >> 5 |
-		       (hblankstart & 0x100) >> 4);
-	//	 CR2C: ???
-	//	 CR2D: initialized in cyblafb_setup_GE()
-	write3X4(CR2F, 0x92);	// conservative, better signal quality
-	//	 CR30: reserved
-	//	 CR31: reserved
-	//	 CR32: reserved
-	//	 CR33: reserved
-	//	 CR34: disabled in CR36
-	//	 CR35: disabled in CR36
-	//	 CR36: initialized in cyblafb_setup_GE
-	//	 CR37: i2c, ignore for now
-	write3X4(CR38, (bpp == 8) ? 0x00 :	//
-		       (bpp == 16) ? 0x05 :	// highcolor
-		       (bpp == 24) ? 0x29 :	// packed 24bit truecolor
-		       (bpp == 32) ? 0x09 : 0); // truecolor, 16 bit pixelbus
-	write3X4(CR39, 0x01 |	// MMIO enable
-		       (pcirb ? 0x02 : 0) |	// pci read burst enable
-		       (pciwb ? 0x04 : 0));	// pci write burst enable
-	write3X4(CR55, 0x1F | // pci clocks * 2 for STOP# during 1st data phase
-		       (pcirr ? 0x40 : 0) |	// pci read retry enable
-		       (pciwr ? 0x80 : 0));	// pci write retry enable
-	write3X4(CR56, preendfetch >> 8 < 2 ? (preendfetch >> 8 & 0x01) | 2
-					    : 0);
-	write3X4(CR57, preendfetch >> 8 < 2 ? preendfetch & 0xff : 0);
-	write3X4(CR58, 0x82);	// Bios does this .... don't know more
-	//
-	// Setup SRxx regs
-	//
-	write3C4(SR00, 3);
-	write3C4(SR01, 1);	//set char clock 8 dots wide
-	write3C4(SR02, 0x0F);	//enable 4 maps needed in chain4 mode
-	write3C4(SR03, 0);	//no character map select
-	write3C4(SR04, 0x0E);	//memory mode: ext mem, even, chain4
-
-	out8(0x3C4, 0x0b);
-	in8(0x3C5);		// Set NEW mode
-	write3C4(SR0D, 0x00);	// test ... check
-
-	set_vclk(par, (bpp == 32 ? 200000000 : 100000000)
-					/ info->var.pixclock);	//SR18, SR19
-
-	//
-	// Setup GRxx regs
-	//
-	write3CE(GR00, 0x00);	// test ... check
-	write3CE(GR01, 0x00);	// test ... check
-	write3CE(GR02, 0x00);	// test ... check
-	write3CE(GR03, 0x00);	// test ... check
-	write3CE(GR04, 0x00);	// test ... check
-	write3CE(GR05, 0x40);	// no CGA compat, allow 256 col
-	write3CE(GR06, 0x05);	// graphics mode
-	write3CE(GR07, 0x0F);	// planes?
-	write3CE(GR08, 0xFF);	// test ... check
-	write3CE(GR0F, (bpp == 32) ? 0x1A : 0x12); // vclk / 2 if 32bpp, chain4
-	write3CE(GR20, 0xC0);	// test ... check
-	write3CE(GR2F, 0xA0);	// PCLK = VCLK, no skew,
-
-	//
-	// Setup ARxx regs
-	//
-	for (i = 0; i < 0x10; i++)	// set AR00 .. AR0f
-		write3C0(i, i);
-	write3C0(AR10, 0x41);	// graphics mode and support 256 color modes
-	write3C0(AR12, 0x0F);	// planes
-	write3C0(AR13, 0);	// horizontal pel panning
-	in8(0x3DA);		// reset internal flag to 3c0 index
-	out8(0x3C0, 0x20);	// enable attr
-
-	//
-	// Setup hidden RAMDAC command register
-	//
-	in8(0x3C8);		// these reads are
-	in8(0x3C6);		// necessary to
-	in8(0x3C6);		// unmask the RAMDAC
-	in8(0x3C6);		// command reg, otherwise
-	in8(0x3C6);		// we would write the pixelmask reg!
-	out8(0x3C6, (bpp == 8) ? 0x00 : // 256 colors
-	     (bpp == 15) ? 0x10 :	//
-	     (bpp == 16) ? 0x30 :	// hicolor
-	     (bpp == 24) ? 0xD0 :	// truecolor
-	     (bpp == 32) ? 0xD0 : 0);	// truecolor
-	in8(0x3C8);
-
-	//
-	// GR31 is not mentioned in the datasheet
-	//
-	if (displaytype == DISPLAY_FP)
-		write3CE(GR31, (read3CE(GR31) & 0x8F) |
-			 ((info->var.yres > 1024) ? 0x50 :
-			  (info->var.yres > 768) ? 0x30 :
-			  (info->var.yres > 600) ? 0x20 :
-			  (info->var.yres > 480) ? 0x10 : 0));
-
-	info->fix.visual = (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR
-				      : FB_VISUAL_TRUECOLOR;
-	info->fix.line_length = info->var.xres_virtual * (bpp >> 3);
-	info->cmap.len = (bpp == 8) ? 256 : 16;
-
-	//
-	// init acceleration engine
-	//
-	cyblafb_setup_GE(info->var.xres_virtual, info->var.bits_per_pixel);
-
-	//
-	// Set/clear flags to allow proper scroll mode selection.
-	//
-	if (var->xres == var->xres_virtual)
-		info->flags &= ~FBINFO_HWACCEL_XPAN;
-	else
-		info->flags |= FBINFO_HWACCEL_XPAN;
-
-	if (var->yres == var->yres_virtual)
-		info->flags &= ~FBINFO_HWACCEL_YPAN;
-	else
-		info->flags |= FBINFO_HWACCEL_YPAN;
-
-	if (info->fix.smem_len !=
-	    var->xres_virtual * var->yres_virtual * bpp / 8)
-		info->flags &= ~FBINFO_HWACCEL_YWRAP;
-	else
-		info->flags |= FBINFO_HWACCEL_YWRAP;
-
-	regdump(par);
-
-	return 0;
-}
-
-//========================
-//
-// Set one color register
-//
-//========================
-
-static int cyblafb_setcolreg(unsigned regno, unsigned red, unsigned green,
-			     unsigned blue, unsigned transp,
-			     struct fb_info *info)
-{
-	int bpp = info->var.bits_per_pixel;
-
-	KD_GRAPHICS_RETURN(0);
-
-	if (regno >= info->cmap.len)
-		return 1;
-
-	if (bpp == 8) {
-		out8(0x3C6, 0xFF);
-		out8(0x3C8, regno);
-		out8(0x3C9, red >> 10);
-		out8(0x3C9, green >> 10);
-		out8(0x3C9, blue >> 10);
-
-	} else if (regno < 16) {
-		if (bpp == 16)	// RGB 565
-			((u32 *) info->pseudo_palette)[regno] =
-				(red & 0xF800) |
-				((green & 0xFC00) >> 5) |
-				((blue & 0xF800) >> 11);
-		else if (bpp == 32)	// ARGB 8888
-			((u32 *) info->pseudo_palette)[regno] =
-				((transp & 0xFF00) << 16) |
-				((red & 0xFF00) << 8) |
-				((green & 0xFF00)) | ((blue & 0xFF00) >> 8);
-	}
-
-	return 0;
-}
-
-//==========================================================
-//
-// Try blanking the screen. For flat panels it does nothing
-//
-//==========================================================
-
-static int cyblafb_blank(int blank_mode, struct fb_info *info)
-{
-	unsigned char PMCont, DPMSCont;
-
-	KD_GRAPHICS_RETURN(0);
-
-	if (displaytype == DISPLAY_FP)
-		return 0;
-
-	out8(0x83C8, 0x04);	// DPMS Control
-	PMCont = in8(0x83C6) & 0xFC;
-
-	DPMSCont = read3CE(GR23) & 0xFC;
-
-	switch (blank_mode) {
-	case FB_BLANK_UNBLANK:	// Screen: On, HSync: On, VSync: On
-	case FB_BLANK_NORMAL:	// Screen: Off, HSync: On, VSync: On
-		PMCont |= 0x03;
-		DPMSCont |= 0x00;
-		break;
-	case FB_BLANK_HSYNC_SUSPEND:	// Screen: Off, HSync: Off, VSync: On
-		PMCont |= 0x02;
-		DPMSCont |= 0x01;
-		break;
-	case FB_BLANK_VSYNC_SUSPEND:	// Screen: Off, HSync: On, VSync: Off
-		PMCont |= 0x02;
-		DPMSCont |= 0x02;
-		break;
-	case FB_BLANK_POWERDOWN:	// Screen: Off, HSync: Off, VSync: Off
-		PMCont |= 0x00;
-		DPMSCont |= 0x03;
-		break;
-	}
-
-	write3CE(GR23, DPMSCont);
-	out8(0x83C8, 4);
-	out8(0x83C6, PMCont);
-	//
-	// let fbcon do a softblank for us
-	//
-	return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
-}
-
-static struct fb_ops cyblafb_ops __devinitdata = {
-	.owner = THIS_MODULE,
-	.fb_setcolreg = cyblafb_setcolreg,
-	.fb_pan_display = cyblafb_pan_display,
-	.fb_blank = cyblafb_blank,
-	.fb_check_var = cyblafb_check_var,
-	.fb_set_par = cyblafb_set_par,
-	.fb_fillrect = cyblafb_fillrect,
-	.fb_copyarea = cyblafb_copyarea,
-	.fb_imageblit = cyblafb_imageblit,
-	.fb_sync = cyblafb_sync,
-	.fb_restore_state = cyblafb_restore_state,
-	.fb_save_state = cyblafb_save_state,
-};
-
-//==========================================================================
-//
-// getstartupmode() decides about the inital video mode
-//
-// There is no reason to use modedb, a lot of video modes there would
-// need altered timings to display correctly. So I decided that it is much
-// better to provide a limited optimized set of modes plus the option of
-// using the mode in effect at startup time (might be selected using the
-// vga=??? parameter). After that the user might use fbset to select any
-// mode he likes, check_var will not try to alter geometry parameters as
-// it would be necessary otherwise.
-//
-//==========================================================================
-
-static int __devinit getstartupmode(struct fb_info *info)
-{
-	u32 htotal, hdispend, hsyncstart, hsyncend, hblankstart, hblankend,
-	    vtotal, vdispend, vsyncstart, vsyncend, vblankstart, vblankend,
-	    cr00, cr01, cr02, cr03, cr04, cr05, cr2b,
-	    cr06, cr07, cr09, cr10, cr11, cr12, cr15, cr16, cr27,
-	    cr38, sr0d, sr18, sr19, gr0f, fi, pxclkdiv, vclkdiv, tmp, i;
-
-	struct modus {
-		int xres; int vxres; int yres; int vyres;
-		int bpp; int pxclk;
-		int left_margin; int right_margin;
-		int upper_margin; int lower_margin;
-		int hsync_len; int vsync_len;
-	} modedb[5] = {
-		{
-		0, 2048, 0, 4096, 0, 0, 0, 0, 0, 0, 0, 0}, {
-		640, 2048, 480, 4096, 0, 0, -40, 24, 17, 0, 216, 3}, {
-		800, 2048, 600, 4096, 0, 0, 96, 24, 14, 0, 136, 11}, {
-		1024, 2048, 768, 4096, 0, 0, 144, 24, 29, 0, 120, 3}, {
-		1280, 2048, 1024, 4096, 0, 0, 232, 16, 39, 0, 160, 3}
-	};
-
-	outb(0x00, 0x3d4); cr00 = inb(0x3d5);
-	outb(0x01, 0x3d4); cr01 = inb(0x3d5);
-	outb(0x02, 0x3d4); cr02 = inb(0x3d5);
-	outb(0x03, 0x3d4); cr03 = inb(0x3d5);
-	outb(0x04, 0x3d4); cr04 = inb(0x3d5);
-	outb(0x05, 0x3d4); cr05 = inb(0x3d5);
-	outb(0x06, 0x3d4); cr06 = inb(0x3d5);
-	outb(0x07, 0x3d4); cr07 = inb(0x3d5);
-	outb(0x09, 0x3d4); cr09 = inb(0x3d5);
-	outb(0x10, 0x3d4); cr10 = inb(0x3d5);
-	outb(0x11, 0x3d4); cr11 = inb(0x3d5);
-	outb(0x12, 0x3d4); cr12 = inb(0x3d5);
-	outb(0x15, 0x3d4); cr15 = inb(0x3d5);
-	outb(0x16, 0x3d4); cr16 = inb(0x3d5);
-	outb(0x27, 0x3d4); cr27 = inb(0x3d5);
-	outb(0x2b, 0x3d4); cr2b = inb(0x3d5);
-	outb(0x38, 0x3d4); cr38 = inb(0x3d5);
-
-	outb(0x0b, 0x3c4);
-	inb(0x3c5);
-
-	outb(0x0d, 0x3c4); sr0d = inb(0x3c5);
-	outb(0x18, 0x3c4); sr18 = inb(0x3c5);
-	outb(0x19, 0x3c4); sr19 = inb(0x3c5);
-	outb(0x0f, 0x3ce); gr0f = inb(0x3cf);
-
-	htotal = cr00 | (cr2b & 0x01) << 8;
-	hdispend = cr01 | (cr2b & 0x02) << 7;
-	hblankstart = cr02 | (cr2b & 0x10) << 4;
-	hblankend = (cr03 & 0x1f) | (cr05 & 0x80) >> 2;
-	hsyncstart = cr04 | (cr2b & 0x08) << 5;
-	hsyncend = cr05 & 0x1f;
-
-	modedb[0].xres = hblankstart * 8;
-	modedb[0].hsync_len = hsyncend * 8;
-	modedb[0].right_margin = hsyncstart * 8 - modedb[0].xres;
-	modedb[0].left_margin = (htotal + 5) * 8 - modedb[0].xres -
-	    modedb[0].right_margin - modedb[0].hsync_len;
-
-	vtotal = cr06 | (cr07 & 0x01) << 8 | (cr07 & 0x20) << 4
-	    | (cr27 & 0x80) << 3;
-	vdispend = cr12 | (cr07 & 0x02) << 7 | (cr07 & 0x40) << 3
-	    | (cr27 & 0x10) << 6;
-	vsyncstart = cr10 | (cr07 & 0x04) << 6 | (cr07 & 0x80) << 2
-	    | (cr27 & 0x20) << 5;
-	vsyncend = cr11 & 0x0f;
-	vblankstart = cr15 | (cr07 & 0x08) << 5 | (cr09 & 0x20) << 4
-	    | (cr27 & 0x40) << 4;
-	vblankend = cr16;
-
-	modedb[0].yres = vdispend + 1;
-	modedb[0].vsync_len = vsyncend;
-	modedb[0].lower_margin = vsyncstart - modedb[0].yres;
-	modedb[0].upper_margin = vtotal - modedb[0].yres -
-	    modedb[0].lower_margin - modedb[0].vsync_len + 2;
-
-	tmp = cr38 & 0x3c;
-	modedb[0].bpp = tmp == 0 ? 8 : tmp == 4 ? 16 : tmp == 28 ? 24 :
-	    tmp == 8 ? 32 : 8;
-
-	fi = ((5864727 * (sr18 + 8)) /
-	      (((sr19 & 0x3f) + 2) * (1 << ((sr19 & 0xc0) >> 6)))) >> 12;
-	pxclkdiv = ((gr0f & 0x08) >> 3 | (gr0f & 0x40) >> 5) + 1;
-	tmp = sr0d & 0x06;
-	vclkdiv = tmp == 0 ? 2 : tmp == 2 ? 4 : tmp == 4 ? 8 : 3; // * 2 !
-	modedb[0].pxclk = ((100000000 * pxclkdiv * vclkdiv) >> 1) / fi;
-
-	if (verbosity > 0)
-		output("detected startup mode: "
-		       "fbset -g %d %d %d ??? %d -t %d %d %d %d %d %d %d\n",
-		       modedb[0].xres, modedb[0].yres, modedb[0].xres,
-		       modedb[0].bpp, modedb[0].pxclk, modedb[0].left_margin,
-		       modedb[0].right_margin, modedb[0].upper_margin,
-		       modedb[0].lower_margin, modedb[0].hsync_len,
-		       modedb[0].vsync_len);
-
-	//
-	// We use this goto target in case of a failed check_var. No, I really
-	// do not want to do it in another way!
-	//
-
-      tryagain:
-
-	i = (mode == NULL) ? 0 :
-	    !strncmp(mode, "640x480", 7) ? 1 :
-	    !strncmp(mode, "800x600", 7) ? 2 :
-	    !strncmp(mode, "1024x768", 8) ? 3 :
-	    !strncmp(mode, "1280x1024", 9) ? 4 : 0;
-
-	ref = (ref < 50) ? 50 : (ref > 85) ? 85 : ref;
-
-	if (i == 0) {
-		info->var.pixclock = modedb[i].pxclk;
-		info->var.bits_per_pixel = modedb[i].bpp;
-	} else {
-		info->var.pixclock = (100000000 /
-				      ((modedb[i].left_margin +
-					modedb[i].xres +
-					modedb[i].right_margin +
-					modedb[i].hsync_len) *
-				       (modedb[i].upper_margin +
-					modedb[i].yres +
-					modedb[i].lower_margin +
-					modedb[i].vsync_len) * ref / 10000));
-		info->var.bits_per_pixel = bpp;
-	}
-
-	info->var.left_margin = modedb[i].left_margin;
-	info->var.right_margin = modedb[i].right_margin;
-	info->var.xres = modedb[i].xres;
-	if (!(modedb[i].yres == 1280 && modedb[i].bpp == 32))
-		info->var.xres_virtual = modedb[i].vxres;
-	else
-		info->var.xres_virtual = modedb[i].xres;
-	info->var.xoffset = 0;
-	info->var.hsync_len = modedb[i].hsync_len;
-	info->var.upper_margin = modedb[i].upper_margin;
-	info->var.yres = modedb[i].yres;
-	info->var.yres_virtual = modedb[i].vyres;
-	info->var.yoffset = 0;
-	info->var.lower_margin = modedb[i].lower_margin;
-	info->var.vsync_len = modedb[i].vsync_len;
-	info->var.sync = 0;
-	info->var.vmode = FB_VMODE_NONINTERLACED;
-
-	if (cyblafb_check_var(&info->var, info)) {
-		// 640x480 - 8@75 should really never fail. One case would
-		// be fp == 1 and nativex < 640 ... give up then
-		if (i == 1 && bpp == 8 && ref == 75) {
-			output("Can't find a valid mode :-(\n");
-			return -EINVAL;
-		}
-		// Our detected mode is unlikely to fail. If it does,
-		// try 640x480 - 8@75 ...
-		if (i == 0) {
-			mode = "640x480";
-			bpp = 8;
-			ref = 75;
-			output("Detected mode failed check_var! "
-			       "Trying 640x480 - 8@75\n");
-			goto tryagain;
-		}
-		// A specified video mode failed for some reason.
-		// Try the startup mode first
-		output("Specified mode '%s' failed check! "
-		       "Falling back to startup mode.\n", mode);
-		mode = NULL;
-		goto tryagain;
-	}
-
-	return 0;
-}
-
-//========================================================
-//
-// Detect activated memory size. Undefined values require
-// memsize parameter.
-//
-//========================================================
-
-static unsigned int __devinit get_memsize(void)
-{
-	unsigned char tmp;
-	unsigned int k;
-
-	if (memsize)
-		k = memsize * Kb;
-	else {
-		tmp = read3X4(CR1F) & 0x0F;
-		switch (tmp) {
-		case 0x03:
-			k = 1 * 1024 * 1024;
-			break;
-		case 0x07:
-			k = 2 * 1024 * 1024;
-			break;
-		case 0x0F:
-			k = 4 * 1024 * 1024;
-			break;
-		case 0x04:
-			k = 8 * 1024 * 1024;
-			break;
-		default:
-			k = 1 * 1024 * 1024;
-			output("Unknown memory size code %x in CR1F."
-			       " We default to 1 Mb for now, please"
-			       " do provide a memsize parameter!\n", tmp);
-		}
-	}
-
-	if (verbosity > 0)
-		output("framebuffer size = %d Kb\n", k / Kb);
-	return k;
-}
-
-//=========================================================
-//
-// Detect if a flat panel monitor connected to the special
-// interface is active. Override is possible by fp and crt
-// parameters.
-//
-//=========================================================
-
-static unsigned int __devinit get_displaytype(void)
-{
-	if (fp)
-		return DISPLAY_FP;
-	if (crt)
-		return DISPLAY_CRT;
-	return (read3CE(GR33) & 0x10) ? DISPLAY_FP : DISPLAY_CRT;
-}
-
-//=====================================
-//
-// Get native resolution of flat panel
-//
-//=====================================
-
-static int __devinit get_nativex(void)
-{
-	int x, y, tmp;
-
-	if (nativex)
-		return nativex;
-
-	tmp = (read3CE(GR52) >> 4) & 3;
-
-	switch (tmp) {
-	case 0: x = 1280; y = 1024;
-		break;
-	case 2: x = 1024; y = 768;
-		break;
-	case 3: x = 800;  y = 600;
-		break;
-	case 4: x = 1400; y = 1050;
-		break;
-	case 1:
-	default:
-		x = 640; y = 480;
-		break;
-	}
-
-	if (verbosity > 0)
-		output("%dx%d flat panel found\n", x, y);
-	return x;
-}
-
-static int __devinit cybla_pci_probe(struct pci_dev *dev,
-				     const struct pci_device_id *id)
-{
-	struct fb_info *info;
-	struct cyblafb_par *par;
-
-	info = framebuffer_alloc(sizeof(struct cyblafb_par), &dev->dev);
-	if (!info)
-		goto errout_alloc_info;
-
-	info->pixmap.addr = kzalloc(CYBLAFB_PIXMAPSIZE, GFP_KERNEL);
-	if (!info->pixmap.addr) {
-		output("allocation of pixmap buffer failed!\n");
-		goto errout_alloc_pixmap;
-	}
-	info->pixmap.size = CYBLAFB_PIXMAPSIZE - 4;
-	info->pixmap.buf_align = 4;
-	info->pixmap.access_align = 32;
-	info->pixmap.flags = FB_PIXMAP_SYSTEM;
-	info->pixmap.scan_align = 4;
-
-	par = info->par;
-	par->ops = cyblafb_ops;
-
-	info->fix = cyblafb_fix;
-	info->fbops = &par->ops;
-	info->fix = cyblafb_fix;
-
-	if (pci_enable_device(dev)) {
-		output("could not enable device!\n");
-		goto errout_enable;
-	}
-	// might already be requested by vga console or vesafb,
-	// so we do care about success
-	if (!request_region(0x3c0, 0x20, "cyblafb")) {
-		output("region 0x3c0/0x20 already reserved\n");
-		vesafb |= 1;
-
-	}
-	//
-	// Graphics Engine Registers
-	//
-	if (!request_region(GEBase, 0x100, "cyblafb")) {
-		output("region %#x/0x100 already reserved\n", GEBase);
-		vesafb |= 2;
-	}
-
-	regdump(par);
-
-	enable_mmio();
-
-	// setup MMIO region
-	info->fix.mmio_start = pci_resource_start(dev, 1);
-	info->fix.mmio_len = 0x20000;
-
-	if (!request_mem_region(info->fix.mmio_start,
-				info->fix.mmio_len, "cyblafb")) {
-		output("request_mem_region failed for mmio region!\n");
-		goto errout_mmio_reqmem;
-	}
-
-	io_virt = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
-
-	if (!io_virt) {
-		output("ioremap failed for mmio region\n");
-		goto errout_mmio_remap;
-	}
-	// setup framebuffer memory ... might already be requested
-	// by vesafb. Not to fail in case of an unsuccessful request
-	// is useful if both are loaded.
-	info->fix.smem_start = pci_resource_start(dev, 0);
-	info->fix.smem_len = get_memsize();
-
-	if (!request_mem_region(info->fix.smem_start,
-				info->fix.smem_len, "cyblafb")) {
-		output("region %#lx/%#x already reserved\n",
-		       info->fix.smem_start, info->fix.smem_len);
-		vesafb |= 4;
-	}
-
-	info->screen_base = ioremap_nocache(info->fix.smem_start,
-					    info->fix.smem_len);
-
-	if (!info->screen_base) {
-		output("ioremap failed for smem region\n");
-		goto errout_smem_remap;
-	}
-
-	displaytype = get_displaytype();
-
-	if (displaytype == DISPLAY_FP)
-		nativex = get_nativex();
-
-	info->flags = FBINFO_DEFAULT
-		    | FBINFO_HWACCEL_COPYAREA
-		    | FBINFO_HWACCEL_FILLRECT
-		    | FBINFO_HWACCEL_IMAGEBLIT
-		    | FBINFO_READS_FAST
-//		    | FBINFO_PARTIAL_PAN_OK
-		    | FBINFO_MISC_ALWAYS_SETPAR;
-
-	info->pseudo_palette = par->pseudo_pal;
-
-	if (getstartupmode(info))
-		goto errout_findmode;
-
-	fb_alloc_cmap(&info->cmap, 256, 0);
-
-	if (register_framebuffer(info)) {
-		output("Could not register CyBla framebuffer\n");
-		goto errout_register;
-	}
-
-	pci_set_drvdata(dev, info);
-
-	//
-	// normal exit and error paths
-	//
-
-	return 0;
-
-      errout_register:
-      errout_findmode:
-	iounmap(info->screen_base);
-      errout_smem_remap:
-	if (!(vesafb & 4))
-		release_mem_region(info->fix.smem_start, info->fix.smem_len);
-	iounmap(io_virt);
-      errout_mmio_remap:
-	release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
-      errout_mmio_reqmem:
-	if (!(vesafb & 1))
-		release_region(0x3c0, 32);
-      errout_enable:
-	kfree(info->pixmap.addr);
-      errout_alloc_pixmap:
-	framebuffer_release(info);
-      errout_alloc_info:
-	output("CyblaFB version %s aborting init.\n", VERSION);
-	return -ENODEV;
-}
-
-static void __devexit cybla_pci_remove(struct pci_dev *dev)
-{
-	struct fb_info *info = pci_get_drvdata(dev);
-
-	unregister_framebuffer(info);
-	iounmap(io_virt);
-	iounmap(info->screen_base);
-	if (!(vesafb & 4))
-		release_mem_region(info->fix.smem_start, info->fix.smem_len);
-	release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
-	fb_dealloc_cmap(&info->cmap);
-	if (!(vesafb & 2))
-		release_region(GEBase, 0x100);
-	if (!(vesafb & 1))
-		release_region(0x3c0, 32);
-	kfree(info->pixmap.addr);
-	framebuffer_release(info);
-	output("CyblaFB version %s normal exit.\n", VERSION);
-}
-
-//
-// List of boards that we are trying to support
-//
-static struct pci_device_id cybla_devices[] = {
-	{PCI_VENDOR_ID_TRIDENT, CYBERBLADEi1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0,}
-};
-
-MODULE_DEVICE_TABLE(pci, cybla_devices);
-
-static struct pci_driver cyblafb_pci_driver = {
-	.name = "cyblafb",
-	.id_table = cybla_devices,
-	.probe = cybla_pci_probe,
-	.remove = __devexit_p(cybla_pci_remove)
-};
-
-//=============================================================
-//
-// kernel command line example:
-//
-//	video=cyblafb:1280x1024, bpp=16, ref=50 ...
-//
-// modprobe command line example:
-//
-//	modprobe cyblafb mode=1280x1024 bpp=16 ref=50 ...
-//
-//=============================================================
-
-static int __devinit cyblafb_init(void)
-{
-#ifndef MODULE
-	char *options = NULL;
-	char *opt;
-
-	if (fb_get_options("cyblafb", &options))
-		return -ENODEV;
-
-	if (options && *options)
-		while ((opt = strsep(&options, ",")) != NULL) {
-			if (!*opt)
-				continue;
-			else if (!strncmp(opt, "bpp=", 4))
-				bpp = simple_strtoul(opt + 4, NULL, 0);
-			else if (!strncmp(opt, "ref=", 4))
-				ref = simple_strtoul(opt + 4, NULL, 0);
-			else if (!strncmp(opt, "fp", 2))
-				displaytype = DISPLAY_FP;
-			else if (!strncmp(opt, "crt", 3))
-				displaytype = DISPLAY_CRT;
-			else if (!strncmp(opt, "nativex=", 8))
-				nativex = simple_strtoul(opt + 8, NULL, 0);
-			else if (!strncmp(opt, "center", 6))
-				center = 1;
-			else if (!strncmp(opt, "stretch", 7))
-				stretch = 1;
-			else if (!strncmp(opt, "pciwb=", 6))
-				pciwb = simple_strtoul(opt + 6, NULL, 0);
-			else if (!strncmp(opt, "pcirb=", 6))
-				pcirb = simple_strtoul(opt + 6, NULL, 0);
-			else if (!strncmp(opt, "pciwr=", 6))
-				pciwr = simple_strtoul(opt + 6, NULL, 0);
-			else if (!strncmp(opt, "pcirr=", 6))
-				pcirr = simple_strtoul(opt + 6, NULL, 0);
-			else if (!strncmp(opt, "memsize=", 8))
-				memsize = simple_strtoul(opt + 8, NULL, 0);
-			else if (!strncmp(opt, "verbosity=", 10))
-				verbosity = simple_strtoul(opt + 10, NULL, 0);
-			else
-				mode = opt;
-		}
-#endif
-	output("CyblaFB version %s initializing\n", VERSION);
-	return pci_register_driver(&cyblafb_pci_driver);
-}
-
-static void __exit cyblafb_exit(void)
-{
-	pci_unregister_driver(&cyblafb_pci_driver);
-}
-
-module_init(cyblafb_init);
-module_exit(cyblafb_exit);
-
-MODULE_AUTHOR("Knut Petersen <knut_petersen@t-online.de>");
-MODULE_DESCRIPTION("Framebuffer driver for Cyberblade/i1 graphics core");
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index daf9b81..0c5b9a9 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -129,6 +129,8 @@
 		screen_info.lfb_width = info->width;
 	if (screen_info.lfb_height == 0)
 		screen_info.lfb_height = info->height;
+	if (screen_info.orig_video_isVGA == 0)
+		screen_info.orig_video_isVGA = VIDEO_TYPE_EFI;
 
 	return 0;
 }
@@ -374,9 +376,10 @@
 	int ret;
 	char *option = NULL;
 
+	dmi_check_system(dmi_system_table);
+
 	if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
 		return -ENODEV;
-	dmi_check_system(dmi_system_table);
 
 	if (fb_get_options("efifb", &option))
 		return -ENODEV;
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 0820265..0a7a667 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -85,8 +85,9 @@
 
 /* vm_ops->page_mkwrite handler */
 static int fb_deferred_io_mkwrite(struct vm_area_struct *vma,
-				  struct page *page)
+				  struct vm_fault *vmf)
 {
+	struct page *page = vmf->page;
 	struct fb_info *info = vma->vm_private_data;
 	struct fb_deferred_io *fbdefio = info->fbdefio;
 	struct page *cur;
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index cfd9dce..2ac32e6 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -46,6 +46,17 @@
 struct fb_info *registered_fb[FB_MAX] __read_mostly;
 int num_registered_fb __read_mostly;
 
+int lock_fb_info(struct fb_info *info)
+{
+	mutex_lock(&info->lock);
+	if (!info->fbops) {
+		mutex_unlock(&info->lock);
+		return 0;
+	}
+	return 1;
+}
+EXPORT_SYMBOL(lock_fb_info);
+
 /*
  * Helpers
  */
@@ -1086,13 +1097,8 @@
 			return -EINVAL;
 		con2fb.framebuffer = -1;
 		event.data = &con2fb;
-
-		if (!lock_fb_info(info))
-			return -ENODEV;
 		event.info = info;
 		fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event);
-		unlock_fb_info(info);
-
 		ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0;
 		break;
 	case FBIOPUT_CON2FBMAP:
@@ -1109,12 +1115,8 @@
 			break;
 		}
 		event.data = &con2fb;
-		if (!lock_fb_info(info))
-			return -ENODEV;
 		event.info = info;
-		ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP,
-					      &event);
-		unlock_fb_info(info);
+		ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event);
 		break;
 	case FBIOBLANK:
 		if (!lock_fb_info(info))
diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/nvidia/nv_type.h
index f132aab..c03f7f5 100644
--- a/drivers/video/nvidia/nv_type.h
+++ b/drivers/video/nvidia/nv_type.h
@@ -5,7 +5,6 @@
 #include <linux/types.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
-#include <linux/mutex.h>
 #include <video/vga.h>
 
 #define NV_ARCH_04  0x04
@@ -99,7 +98,6 @@
 	RIVA_HW_STATE initial_state;
 	RIVA_HW_STATE *CurrentState;
 	struct vgastate vgastate;
-	struct mutex open_lock;
 	u32 pseudo_palette[16];
 	struct pci_dev *pci_dev;
 	u32 Architecture;
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 9dbb5a5..efe10ff 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -1004,15 +1004,12 @@
 {
 	struct nvidia_par *par = info->par;
 
-	mutex_lock(&par->open_lock);
-
 	if (!par->open_count) {
 		save_vga_x86(par);
 		nvidia_save_vga(par, &par->initial_state);
 	}
 
 	par->open_count++;
-	mutex_unlock(&par->open_lock);
 	return 0;
 }
 
@@ -1021,8 +1018,6 @@
 	struct nvidia_par *par = info->par;
 	int err = 0;
 
-	mutex_lock(&par->open_lock);
-
 	if (!par->open_count) {
 		err = -EINVAL;
 		goto done;
@@ -1035,7 +1030,6 @@
 
 	par->open_count--;
 done:
-	mutex_unlock(&par->open_lock);
 	return err;
 }
 
@@ -1300,7 +1294,6 @@
 
 	par = info->par;
 	par->pci_dev = pd;
-	mutex_init(&par->open_lock);
 	info->pixmap.addr = kzalloc(8 * 1024, GFP_KERNEL);
 
 	if (info->pixmap.addr == NULL)
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c
index f24df0b..8aa6e47 100644
--- a/drivers/video/omap/hwa742.c
+++ b/drivers/video/omap/hwa742.c
@@ -742,7 +742,7 @@
 		if (calc_reg_timing(sysclk, div) == 0)
 			break;
 	}
-	if (div > max_clk_div)
+	if (div >= max_clk_div)
 		goto err;
 
 	*extif_mem_div = div;
@@ -752,7 +752,7 @@
 			break;
 	}
 
-	if (div > max_clk_div)
+	if (div >= max_clk_div)
 		goto err;
 
 	return 0;
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 1a49519..060d72f 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -338,7 +338,7 @@
 
 	omapfb_rqueue_lock(fbdev);
 	switch (blank) {
-	case VESA_NO_BLANKING:
+	case FB_BLANK_UNBLANK:
 		if (fbdev->state == OMAPFB_SUSPENDED) {
 			if (fbdev->ctrl->resume)
 				fbdev->ctrl->resume();
@@ -349,7 +349,7 @@
 				do_update = 1;
 		}
 		break;
-	case VESA_POWERDOWN:
+	case FB_BLANK_POWERDOWN:
 		if (fbdev->state == OMAPFB_ACTIVE) {
 			fbdev->panel->disable(fbdev->panel);
 			if (fbdev->ctrl->suspend)
@@ -1818,7 +1818,7 @@
 {
 	struct omapfb_device *fbdev = platform_get_drvdata(pdev);
 
-	omapfb_blank(VESA_POWERDOWN, fbdev->fb_info[0]);
+	omapfb_blank(FB_BLANK_POWERDOWN, fbdev->fb_info[0]);
 
 	return 0;
 }
@@ -1828,7 +1828,7 @@
 {
 	struct omapfb_device *fbdev = platform_get_drvdata(pdev);
 
-	omapfb_blank(VESA_NO_BLANKING, fbdev->fb_info[0]);
+	omapfb_blank(FB_BLANK_UNBLANK, fbdev->fb_info[0]);
 	return 0;
 }
 
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
index a7b01d2..0726aec 100644
--- a/drivers/video/s1d13xxxfb.c
+++ b/drivers/video/s1d13xxxfb.c
@@ -50,9 +50,22 @@
 #define dbg(fmt, args...) do { } while (0)
 #endif
 
-static const int __devinitconst s1d13xxxfb_revisions[] = {
-	S1D13506_CHIP_REV,	/* Rev.4 on HP Jornada 7xx S1D13506 */
-	S1D13806_CHIP_REV,	/* Rev.7 on .. */
+/*
+ * List of card production ids
+ */
+static const int s1d13xxxfb_prod_ids[] = {
+	S1D13505_PROD_ID,
+	S1D13506_PROD_ID,
+	S1D13806_PROD_ID,
+};
+
+/*
+ * List of card strings
+ */
+static const char *s1d13xxxfb_prod_names[] = {
+	"S1D13505",
+	"S1D13506",
+	"S1D13806",
 };
 
 /*
@@ -377,7 +390,6 @@
 	return 0;
 }
 
-
 /* framebuffer information structures */
 
 static struct fb_ops s1d13xxxfb_fbops = {
@@ -544,7 +556,7 @@
 	struct s1d13xxxfb_pdata *pdata = NULL;
 	int ret = 0;
 	int i;
-	u8 revision;
+	u8 revision, prod_id;
 
 	dbg("probe called: device is %p\n", pdev);
 
@@ -613,19 +625,31 @@
 		goto bail;
 	}
 
-	revision = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE) >> 2;
-
+	/* production id is top 6 bits */
+	prod_id = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE) >> 2;
+	/* revision id is lower 2 bits */
+	revision = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE) & 0x3;
 	ret = -ENODEV;
 
-	for (i = 0; i < ARRAY_SIZE(s1d13xxxfb_revisions); i++) {
-		if (revision == s1d13xxxfb_revisions[i])
+	for (i = 0; i < ARRAY_SIZE(s1d13xxxfb_prod_ids); i++) {
+		if (prod_id == s1d13xxxfb_prod_ids[i]) {
+			/* looks like we got it in our list */
+			default_par->prod_id = prod_id;
+			default_par->revision = revision;
 			ret = 0;
+			break;
+		}
 	}
 
-	if (!ret)
+	if (!ret) {
+		printk(KERN_INFO PFX "chip production id %i = %s\n",
+			prod_id, s1d13xxxfb_prod_names[i]);
 		printk(KERN_INFO PFX "chip revision %i\n", revision);
-	else {
-		printk(KERN_INFO PFX "unknown chip revision %i\n", revision);
+	} else {
+		printk(KERN_INFO PFX
+			"unknown chip production id %i, revision %i\n",
+			prod_id, revision);
+		printk(KERN_INFO PFX "please contant maintainer\n");
 		goto bail;
 	}
 
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
new file mode 100644
index 0000000..5e9c630
--- /dev/null
+++ b/drivers/video/s3c-fb.c
@@ -0,0 +1,1036 @@
+/* linux/drivers/video/s3c-fb.c
+ *
+ * Copyright 2008 Openmoko Inc.
+ * Copyright 2008 Simtec Electronics
+ *      Ben Dooks <ben@simtec.co.uk>
+ *      http://armlinux.simtec.co.uk/
+ *
+ * Samsung SoC Framebuffer driver
+ *
+ * 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/module.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/gfp.h>
+#include <linux/clk.h>
+#include <linux/fb.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <mach/regs-fb.h>
+#include <plat/fb.h>
+
+/* This driver will export a number of framebuffer interfaces depending
+ * on the configuration passed in via the platform data. Each fb instance
+ * maps to a hardware window. Currently there is no support for runtime
+ * setting of the alpha-blending functions that each window has, so only
+ * window 0 is actually useful.
+ *
+ * Window 0 is treated specially, it is used for the basis of the LCD
+ * output timings and as the control for the output power-down state.
+*/
+
+/* note, some of the functions that get called are derived from including
+ * <mach/regs-fb.h> as they are specific to the architecture that the code
+ * is being built for.
+*/
+
+#ifdef CONFIG_FB_S3C_DEBUG_REGWRITE
+#undef writel
+#define writel(v, r) do { \
+	printk(KERN_DEBUG "%s: %08x => %p\n", __func__, (unsigned int)v, r); \
+	__raw_writel(v, r); } while(0)
+#endif /* FB_S3C_DEBUG_REGWRITE */
+
+struct s3c_fb;
+
+/**
+ * struct s3c_fb_win - per window private data for each framebuffer.
+ * @windata: The platform data supplied for the window configuration.
+ * @parent: The hardware that this window is part of.
+ * @fbinfo: Pointer pack to the framebuffer info for this window.
+ * @palette_buffer: Buffer/cache to hold palette entries.
+ * @pseudo_palette: For use in TRUECOLOUR modes for entries 0..15/
+ * @index: The window number of this window.
+ * @palette: The bitfields for changing r/g/b into a hardware palette entry.
+ */
+struct s3c_fb_win {
+	struct s3c_fb_pd_win	*windata;
+	struct s3c_fb		*parent;
+	struct fb_info		*fbinfo;
+	struct s3c_fb_palette	 palette;
+
+	u32			*palette_buffer;
+	u32			 pseudo_palette[16];
+	unsigned int		 index;
+};
+
+/**
+ * struct s3c_fb - overall hardware state of the hardware
+ * @dev: The device that we bound to, for printing, etc.
+ * @regs_res: The resource we claimed for the IO registers.
+ * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk.
+ * @regs: The mapped hardware registers.
+ * @enabled: A bitmask of enabled hardware windows.
+ * @pdata: The platform configuration data passed with the device.
+ * @windows: The hardware windows that have been claimed.
+ */
+struct s3c_fb {
+	struct device		*dev;
+	struct resource		*regs_res;
+	struct clk		*bus_clk;
+	void __iomem		*regs;
+
+	unsigned char		 enabled;
+
+	struct s3c_fb_platdata	*pdata;
+	struct s3c_fb_win	*windows[S3C_FB_MAX_WIN];
+};
+
+/**
+ * s3c_fb_win_has_palette() - determine if a mode has a palette
+ * @win: The window number being queried.
+ * @bpp: The number of bits per pixel to test.
+ *
+ * Work out if the given window supports palletised data at the specified bpp.
+ */
+static int s3c_fb_win_has_palette(unsigned int win, unsigned int bpp)
+{
+	return s3c_fb_win_pal_size(win) <= (1 << bpp);
+}
+
+/**
+ * s3c_fb_check_var() - framebuffer layer request to verify a given mode.
+ * @var: The screen information to verify.
+ * @info: The framebuffer device.
+ *
+ * Framebuffer layer call to verify the given information and allow us to
+ * update various information depending on the hardware capabilities.
+ */
+static int s3c_fb_check_var(struct fb_var_screeninfo *var,
+			    struct fb_info *info)
+{
+	struct s3c_fb_win *win = info->par;
+	struct s3c_fb_pd_win *windata = win->windata;
+	struct s3c_fb *sfb = win->parent;
+
+	dev_dbg(sfb->dev, "checking parameters\n");
+
+	var->xres_virtual = max((unsigned int)windata->virtual_x, var->xres);
+	var->yres_virtual = max((unsigned int)windata->virtual_y, var->yres);
+
+	if (!s3c_fb_validate_win_bpp(win->index, var->bits_per_pixel)) {
+		dev_dbg(sfb->dev, "win %d: unsupported bpp %d\n",
+			win->index, var->bits_per_pixel);
+		return -EINVAL;
+	}
+
+	/* always ensure these are zero, for drop through cases below */
+	var->transp.offset = 0;
+	var->transp.length = 0;
+
+	switch (var->bits_per_pixel) {
+	case 1:
+	case 2:
+	case 4:
+	case 8:
+		if (!s3c_fb_win_has_palette(win->index, var->bits_per_pixel)) {
+			/* non palletised, A:1,R:2,G:3,B:2 mode */
+			var->red.offset		= 4;
+			var->green.offset	= 2;
+			var->blue.offset	= 0;
+			var->red.length		= 5;
+			var->green.length	= 3;
+			var->blue.length	= 2;
+			var->transp.offset	= 7;
+			var->transp.length	= 1;
+		} else {
+			var->red.offset	= 0;
+			var->red.length	= var->bits_per_pixel;
+			var->green	= var->red;
+			var->blue	= var->red;
+		}
+		break;
+
+	case 19:
+		/* 666 with one bit alpha/transparency */
+		var->transp.offset	= 18;
+		var->transp.length	= 1;
+	case 18:
+		var->bits_per_pixel	= 32;
+
+		/* 666 format */
+		var->red.offset		= 12;
+		var->green.offset	= 6;
+		var->blue.offset	= 0;
+		var->red.length		= 6;
+		var->green.length	= 6;
+		var->blue.length	= 6;
+		break;
+
+	case 16:
+		/* 16 bpp, 565 format */
+		var->red.offset		= 11;
+		var->green.offset	= 5;
+		var->blue.offset	= 0;
+		var->red.length		= 5;
+		var->green.length	= 6;
+		var->blue.length	= 5;
+		break;
+
+	case 28:
+	case 25:
+		var->transp.length	= var->bits_per_pixel - 24;
+		var->transp.offset	= 24;
+		/* drop through */
+	case 24:
+		/* our 24bpp is unpacked, so 32bpp */
+		var->bits_per_pixel	= 32;
+	case 32:
+		var->red.offset		= 16;
+		var->red.length		= 8;
+		var->green.offset	= 8;
+		var->green.length	= 8;
+		var->blue.offset	= 0;
+		var->blue.length	= 8;
+		break;
+
+	default:
+		dev_err(sfb->dev, "invalid bpp\n");
+	}
+
+	dev_dbg(sfb->dev, "%s: verified parameters\n", __func__);
+	return 0;
+}
+
+/**
+ * s3c_fb_calc_pixclk() - calculate the divider to create the pixel clock.
+ * @sfb: The hardware state.
+ * @pixclock: The pixel clock wanted, in picoseconds.
+ *
+ * Given the specified pixel clock, work out the necessary divider to get
+ * close to the output frequency.
+ */
+static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk)
+{
+	unsigned long clk = clk_get_rate(sfb->bus_clk);
+	unsigned long long tmp;
+	unsigned int result;
+
+	tmp = (unsigned long long)clk;
+	tmp *= pixclk;
+
+	do_div(tmp, 1000000000UL);
+	result = (unsigned int)tmp / 1000;
+
+	dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n",
+		pixclk, clk, result, clk / result);
+
+	return result;
+}
+
+/**
+ * s3c_fb_align_word() - align pixel count to word boundary
+ * @bpp: The number of bits per pixel
+ * @pix: The value to be aligned.
+ *
+ * Align the given pixel count so that it will start on an 32bit word
+ * boundary.
+ */
+static int s3c_fb_align_word(unsigned int bpp, unsigned int pix)
+{
+	int pix_per_word;
+
+	if (bpp > 16)
+		return pix;
+
+	pix_per_word = (8 * 32) / bpp;
+	return ALIGN(pix, pix_per_word);
+}
+
+/**
+ * s3c_fb_set_par() - framebuffer request to set new framebuffer state.
+ * @info: The framebuffer to change.
+ *
+ * Framebuffer layer request to set a new mode for the specified framebuffer
+ */
+static int s3c_fb_set_par(struct fb_info *info)
+{
+	struct fb_var_screeninfo *var = &info->var;
+	struct s3c_fb_win *win = info->par;
+	struct s3c_fb *sfb = win->parent;
+	void __iomem *regs = sfb->regs;
+	int win_no = win->index;
+	u32 data;
+	u32 pagewidth;
+	int clkdiv;
+
+	dev_dbg(sfb->dev, "setting framebuffer parameters\n");
+
+	switch (var->bits_per_pixel) {
+	case 32:
+	case 24:
+	case 16:
+	case 12:
+		info->fix.visual = FB_VISUAL_TRUECOLOR;
+		break;
+	case 8:
+		if (s3c_fb_win_has_palette(win_no, 8))
+			info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+		else
+			info->fix.visual = FB_VISUAL_TRUECOLOR;
+		break;
+	case 1:
+		info->fix.visual = FB_VISUAL_MONO01;
+		break;
+	default:
+		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+		break;
+	}
+
+	info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8;
+
+	/* disable the window whilst we update it */
+	writel(0, regs + WINCON(win_no));
+
+	/* use window 0 as the basis for the lcd output timings */
+
+	if (win_no == 0) {
+		clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock);
+
+		data = sfb->pdata->vidcon0;
+		data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR);
+
+		if (clkdiv > 1)
+			data |= VIDCON0_CLKVAL_F(clkdiv-1) | VIDCON0_CLKDIR;
+		else
+			data &= ~VIDCON0_CLKDIR;	/* 1:1 clock */
+
+		/* write the timing data to the panel */
+
+		data |= VIDCON0_ENVID | VIDCON0_ENVID_F;
+		writel(data, regs + VIDCON0);
+
+		data = VIDTCON0_VBPD(var->upper_margin - 1) |
+		       VIDTCON0_VFPD(var->lower_margin - 1) |
+		       VIDTCON0_VSPW(var->vsync_len - 1);
+
+		writel(data, regs + VIDTCON0);
+
+		data = VIDTCON1_HBPD(var->left_margin - 1) |
+		       VIDTCON1_HFPD(var->right_margin - 1) |
+		       VIDTCON1_HSPW(var->hsync_len - 1);
+
+		writel(data, regs + VIDTCON1);
+
+		data = VIDTCON2_LINEVAL(var->yres - 1) |
+		       VIDTCON2_HOZVAL(var->xres - 1);
+		writel(data, regs + VIDTCON2);
+	}
+
+	/* write the buffer address */
+
+	writel(info->fix.smem_start, regs + VIDW_BUF_START(win_no));
+
+	data = info->fix.smem_start + info->fix.line_length * var->yres;
+	writel(data, regs + VIDW_BUF_END(win_no));
+
+	pagewidth = (var->xres * var->bits_per_pixel) >> 3;
+	data = VIDW_BUF_SIZE_OFFSET(info->fix.line_length - pagewidth) |
+	       VIDW_BUF_SIZE_PAGEWIDTH(pagewidth);
+	writel(data, regs + VIDW_BUF_SIZE(win_no));
+
+	/* write 'OSD' registers to control position of framebuffer */
+
+	data = VIDOSDxA_TOPLEFT_X(0) | VIDOSDxA_TOPLEFT_Y(0);
+	writel(data, regs + VIDOSD_A(win_no));
+
+	data = VIDOSDxB_BOTRIGHT_X(s3c_fb_align_word(var->bits_per_pixel,
+						     var->xres - 1)) |
+	       VIDOSDxB_BOTRIGHT_Y(var->yres - 1);
+
+	writel(data, regs + VIDOSD_B(win_no));
+
+	data = var->xres * var->yres;
+	if (s3c_fb_has_osd_d(win_no)) {
+		writel(data, regs + VIDOSD_D(win_no));
+		writel(0, regs + VIDOSD_C(win_no));
+	} else
+		writel(data, regs + VIDOSD_C(win_no));
+
+	data = WINCONx_ENWIN;
+
+	/* note, since we have to round up the bits-per-pixel, we end up
+	 * relying on the bitfield information for r/g/b/a to work out
+	 * exactly which mode of operation is intended. */
+
+	switch (var->bits_per_pixel) {
+	case 1:
+		data |= WINCON0_BPPMODE_1BPP;
+		data |= WINCONx_BITSWP;
+		data |= WINCONx_BURSTLEN_4WORD;
+		break;
+	case 2:
+		data |= WINCON0_BPPMODE_2BPP;
+		data |= WINCONx_BITSWP;
+		data |= WINCONx_BURSTLEN_8WORD;
+		break;
+	case 4:
+		data |= WINCON0_BPPMODE_4BPP;
+		data |= WINCONx_BITSWP;
+		data |= WINCONx_BURSTLEN_8WORD;
+		break;
+	case 8:
+		if (var->transp.length != 0)
+			data |= WINCON1_BPPMODE_8BPP_1232;
+		else
+			data |= WINCON0_BPPMODE_8BPP_PALETTE;
+		data |= WINCONx_BURSTLEN_8WORD;
+		data |= WINCONx_BYTSWP;
+		break;
+	case 16:
+		if (var->transp.length != 0)
+			data |= WINCON1_BPPMODE_16BPP_A1555;
+		else
+			data |= WINCON0_BPPMODE_16BPP_565;
+		data |= WINCONx_HAWSWP;
+		data |= WINCONx_BURSTLEN_16WORD;
+		break;
+	case 24:
+	case 32:
+		if (var->red.length == 6) {
+			if (var->transp.length != 0)
+				data |= WINCON1_BPPMODE_19BPP_A1666;
+			else
+				data |= WINCON1_BPPMODE_18BPP_666;
+		} else if (var->transp.length != 0)
+			data |= WINCON1_BPPMODE_25BPP_A1888;
+		else
+			data |= WINCON0_BPPMODE_24BPP_888;
+
+		data |= WINCONx_BURSTLEN_16WORD;
+		break;
+	}
+
+	writel(data, regs + WINCON(win_no));
+	writel(0x0, regs + WINxMAP(win_no));
+
+	return 0;
+}
+
+/**
+ * s3c_fb_update_palette() - set or schedule a palette update.
+ * @sfb: The hardware information.
+ * @win: The window being updated.
+ * @reg: The palette index being changed.
+ * @value: The computed palette value.
+ *
+ * Change the value of a palette register, either by directly writing to
+ * the palette (this requires the palette RAM to be disconnected from the
+ * hardware whilst this is in progress) or schedule the update for later.
+ *
+ * At the moment, since we have no VSYNC interrupt support, we simply set
+ * the palette entry directly.
+ */
+static void s3c_fb_update_palette(struct s3c_fb *sfb,
+				  struct s3c_fb_win *win,
+				  unsigned int reg,
+				  u32 value)
+{
+	void __iomem *palreg;
+	u32 palcon;
+
+	palreg = sfb->regs + s3c_fb_pal_reg(win->index, reg);
+
+	dev_dbg(sfb->dev, "%s: win %d, reg %d (%p): %08x\n",
+		__func__, win->index, reg, palreg, value);
+
+	win->palette_buffer[reg] = value;
+
+	palcon = readl(sfb->regs + WPALCON);
+	writel(palcon | WPALCON_PAL_UPDATE, sfb->regs + WPALCON);
+
+	if (s3c_fb_pal_is16(win->index))
+		writew(value, palreg);
+	else
+		writel(value, palreg);
+
+	writel(palcon, sfb->regs + WPALCON);
+}
+
+static inline unsigned int chan_to_field(unsigned int chan,
+					 struct fb_bitfield *bf)
+{
+	chan &= 0xffff;
+	chan >>= 16 - bf->length;
+	return chan << bf->offset;
+}
+
+/**
+ * s3c_fb_setcolreg() - framebuffer layer request to change palette.
+ * @regno: The palette index to change.
+ * @red: The red field for the palette data.
+ * @green: The green field for the palette data.
+ * @blue: The blue field for the palette data.
+ * @trans: The transparency (alpha) field for the palette data.
+ * @info: The framebuffer being changed.
+ */
+static int s3c_fb_setcolreg(unsigned regno,
+			    unsigned red, unsigned green, unsigned blue,
+			    unsigned transp, struct fb_info *info)
+{
+	struct s3c_fb_win *win = info->par;
+	struct s3c_fb *sfb = win->parent;
+	unsigned int val;
+
+	dev_dbg(sfb->dev, "%s: win %d: %d => rgb=%d/%d/%d\n",
+		__func__, win->index, regno, red, green, blue);
+
+	switch (info->fix.visual) {
+	case FB_VISUAL_TRUECOLOR:
+		/* true-colour, use pseudo-palette */
+
+		if (regno < 16) {
+			u32 *pal = info->pseudo_palette;
+
+			val  = chan_to_field(red,   &info->var.red);
+			val |= chan_to_field(green, &info->var.green);
+			val |= chan_to_field(blue,  &info->var.blue);
+
+			pal[regno] = val;
+		}
+		break;
+
+	case FB_VISUAL_PSEUDOCOLOR:
+		if (regno < s3c_fb_win_pal_size(win->index)) {
+			val  = chan_to_field(red, &win->palette.r);
+			val |= chan_to_field(green, &win->palette.g);
+			val |= chan_to_field(blue, &win->palette.b);
+
+			s3c_fb_update_palette(sfb, win, regno, val);
+		}
+
+		break;
+
+	default:
+		return 1;	/* unknown type */
+	}
+
+	return 0;
+}
+
+/**
+ * s3c_fb_enable() - Set the state of the main LCD output
+ * @sfb: The main framebuffer state.
+ * @enable: The state to set.
+ */
+static void s3c_fb_enable(struct s3c_fb *sfb, int enable)
+{
+	u32 vidcon0 = readl(sfb->regs + VIDCON0);
+
+	if (enable)
+		vidcon0 |= VIDCON0_ENVID | VIDCON0_ENVID_F;
+	else {
+		/* see the note in the framebuffer datasheet about
+		 * why you cannot take both of these bits down at the
+		 * same time. */
+
+		if (!(vidcon0 & VIDCON0_ENVID))
+			return;
+
+		vidcon0 |= VIDCON0_ENVID;
+		vidcon0 &= ~VIDCON0_ENVID_F;
+	}
+
+	writel(vidcon0, sfb->regs + VIDCON0);
+}
+
+/**
+ * s3c_fb_blank() - blank or unblank the given window
+ * @blank_mode: The blank state from FB_BLANK_*
+ * @info: The framebuffer to blank.
+ *
+ * Framebuffer layer request to change the power state.
+ */
+static int s3c_fb_blank(int blank_mode, struct fb_info *info)
+{
+	struct s3c_fb_win *win = info->par;
+	struct s3c_fb *sfb = win->parent;
+	unsigned int index = win->index;
+	u32 wincon;
+
+	dev_dbg(sfb->dev, "blank mode %d\n", blank_mode);
+
+	wincon = readl(sfb->regs + WINCON(index));
+
+	switch (blank_mode) {
+	case FB_BLANK_POWERDOWN:
+		wincon &= ~WINCONx_ENWIN;
+		sfb->enabled &= ~(1 << index);
+		/* fall through to FB_BLANK_NORMAL */
+
+	case FB_BLANK_NORMAL:
+		/* disable the DMA and display 0x0 (black) */
+		writel(WINxMAP_MAP | WINxMAP_MAP_COLOUR(0x0),
+		       sfb->regs + WINxMAP(index));
+		break;
+
+	case FB_BLANK_UNBLANK:
+		writel(0x0, sfb->regs + WINxMAP(index));
+		wincon |= WINCONx_ENWIN;
+		sfb->enabled |= (1 << index);
+		break;
+
+	case FB_BLANK_VSYNC_SUSPEND:
+	case FB_BLANK_HSYNC_SUSPEND:
+	default:
+		return 1;
+	}
+
+	writel(wincon, sfb->regs + WINCON(index));
+
+	/* Check the enabled state to see if we need to be running the
+	 * main LCD interface, as if there are no active windows then
+	 * it is highly likely that we also do not need to output
+	 * anything.
+	 */
+
+	/* We could do something like the following code, but the current
+	 * system of using framebuffer events means that we cannot make
+	 * the distinction between just window 0 being inactive and all
+	 * the windows being down.
+	 *
+	 * s3c_fb_enable(sfb, sfb->enabled ? 1 : 0);
+	*/
+
+	/* we're stuck with this until we can do something about overriding
+	 * the power control using the blanking event for a single fb.
+	 */
+	if (index == 0)
+		s3c_fb_enable(sfb, blank_mode != FB_BLANK_POWERDOWN ? 1 : 0);
+
+	return 0;
+}
+
+static struct fb_ops s3c_fb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_check_var	= s3c_fb_check_var,
+	.fb_set_par	= s3c_fb_set_par,
+	.fb_blank	= s3c_fb_blank,
+	.fb_setcolreg	= s3c_fb_setcolreg,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
+};
+
+/**
+ * s3c_fb_alloc_memory() - allocate display memory for framebuffer window
+ * @sfb: The base resources for the hardware.
+ * @win: The window to initialise memory for.
+ *
+ * Allocate memory for the given framebuffer.
+ */
+static int __devinit s3c_fb_alloc_memory(struct s3c_fb *sfb,
+					 struct s3c_fb_win *win)
+{
+	struct s3c_fb_pd_win *windata = win->windata;
+	unsigned int real_size, virt_size, size;
+	struct fb_info *fbi = win->fbinfo;
+	dma_addr_t map_dma;
+
+	dev_dbg(sfb->dev, "allocating memory for display\n");
+
+	real_size = windata->win_mode.xres * windata->win_mode.yres;
+	virt_size = windata->virtual_x * windata->virtual_y;
+
+	dev_dbg(sfb->dev, "real_size=%u (%u.%u), virt_size=%u (%u.%u)\n",
+		real_size, windata->win_mode.xres, windata->win_mode.yres,
+		virt_size, windata->virtual_x, windata->virtual_y);
+
+	size = (real_size > virt_size) ? real_size : virt_size;
+	size *= (windata->max_bpp > 16) ? 32 : windata->max_bpp;
+	size /= 8;
+
+	fbi->fix.smem_len = size;
+	size = PAGE_ALIGN(size);
+
+	dev_dbg(sfb->dev, "want %u bytes for window\n", size);
+
+	fbi->screen_base = dma_alloc_writecombine(sfb->dev, size,
+						  &map_dma, GFP_KERNEL);
+	if (!fbi->screen_base)
+		return -ENOMEM;
+
+	dev_dbg(sfb->dev, "mapped %x to %p\n",
+		(unsigned int)map_dma, fbi->screen_base);
+
+	memset(fbi->screen_base, 0x0, size);
+	fbi->fix.smem_start = map_dma;
+
+	return 0;
+}
+
+/**
+ * s3c_fb_free_memory() - free the display memory for the given window
+ * @sfb: The base resources for the hardware.
+ * @win: The window to free the display memory for.
+ *
+ * Free the display memory allocated by s3c_fb_alloc_memory().
+ */
+static void s3c_fb_free_memory(struct s3c_fb *sfb, struct s3c_fb_win *win)
+{
+	struct fb_info *fbi = win->fbinfo;
+
+	dma_free_writecombine(sfb->dev, PAGE_ALIGN(fbi->fix.smem_len),
+			      fbi->screen_base, fbi->fix.smem_start);
+}
+
+/**
+ * s3c_fb_release_win() - release resources for a framebuffer window.
+ * @win: The window to cleanup the resources for.
+ *
+ * Release the resources that where claimed for the hardware window,
+ * such as the framebuffer instance and any memory claimed for it.
+ */
+static void s3c_fb_release_win(struct s3c_fb *sfb, struct s3c_fb_win *win)
+{
+	fb_dealloc_cmap(&win->fbinfo->cmap);
+	unregister_framebuffer(win->fbinfo);
+	s3c_fb_free_memory(sfb, win);
+}
+
+/**
+ * s3c_fb_probe_win() - register an hardware window
+ * @sfb: The base resources for the hardware
+ * @res: Pointer to where to place the resultant window.
+ *
+ * Allocate and do the basic initialisation for one of the hardware's graphics
+ * windows.
+ */
+static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
+				      struct s3c_fb_win **res)
+{
+	struct fb_var_screeninfo *var;
+	struct fb_videomode *initmode;
+	struct s3c_fb_pd_win *windata;
+	struct s3c_fb_win *win;
+	struct fb_info *fbinfo;
+	int palette_size;
+	int ret;
+
+	dev_dbg(sfb->dev, "probing window %d\n", win_no);
+
+	palette_size = s3c_fb_win_pal_size(win_no);
+
+	fbinfo = framebuffer_alloc(sizeof(struct s3c_fb_win) +
+				   palette_size * sizeof(u32), sfb->dev);
+	if (!fbinfo) {
+		dev_err(sfb->dev, "failed to allocate framebuffer\n");
+		return -ENOENT;
+	}
+
+	windata = sfb->pdata->win[win_no];
+	initmode = &windata->win_mode;
+
+	WARN_ON(windata->max_bpp == 0);
+	WARN_ON(windata->win_mode.xres == 0);
+	WARN_ON(windata->win_mode.yres == 0);
+
+	win = fbinfo->par;
+	var = &fbinfo->var;
+	win->fbinfo = fbinfo;
+	win->parent = sfb;
+	win->windata = windata;
+	win->index = win_no;
+	win->palette_buffer = (u32 *)(win + 1);
+
+	ret = s3c_fb_alloc_memory(sfb, win);
+	if (ret) {
+		dev_err(sfb->dev, "failed to allocate display memory\n");
+		goto err_framebuffer;
+	}
+
+	/* setup the r/b/g positions for the window's palette */
+	s3c_fb_init_palette(win_no, &win->palette);
+
+	/* setup the initial video mode from the window */
+	fb_videomode_to_var(&fbinfo->var, initmode);
+
+	fbinfo->fix.type	= FB_TYPE_PACKED_PIXELS;
+	fbinfo->fix.accel	= FB_ACCEL_NONE;
+	fbinfo->var.activate	= FB_ACTIVATE_NOW;
+	fbinfo->var.vmode	= FB_VMODE_NONINTERLACED;
+	fbinfo->var.bits_per_pixel = windata->default_bpp;
+	fbinfo->fbops		= &s3c_fb_ops;
+	fbinfo->flags		= FBINFO_FLAG_DEFAULT;
+	fbinfo->pseudo_palette  = &win->pseudo_palette;
+
+	/* prepare to actually start the framebuffer */
+
+	ret = s3c_fb_check_var(&fbinfo->var, fbinfo);
+	if (ret < 0) {
+		dev_err(sfb->dev, "check_var failed on initial video params\n");
+		goto err_alloc_mem;
+	}
+
+	/* create initial colour map */
+
+	ret = fb_alloc_cmap(&fbinfo->cmap, s3c_fb_win_pal_size(win_no), 1);
+	if (ret == 0)
+		fb_set_cmap(&fbinfo->cmap, fbinfo);
+	else
+		dev_err(sfb->dev, "failed to allocate fb cmap\n");
+
+	s3c_fb_set_par(fbinfo);
+
+	dev_dbg(sfb->dev, "about to register framebuffer\n");
+
+	/* run the check_var and set_par on our configuration. */
+
+	ret = register_framebuffer(fbinfo);
+	if (ret < 0) {
+		dev_err(sfb->dev, "failed to register framebuffer\n");
+		goto err_alloc_mem;
+	}
+
+	*res = win;
+	dev_info(sfb->dev, "window %d: fb %s\n", win_no, fbinfo->fix.id);
+
+	return 0;
+
+err_alloc_mem:
+	s3c_fb_free_memory(sfb, win);
+
+err_framebuffer:
+	unregister_framebuffer(fbinfo);
+	return ret;
+}
+
+/**
+ * s3c_fb_clear_win() - clear hardware window registers.
+ * @sfb: The base resources for the hardware.
+ * @win: The window to process.
+ *
+ * Reset the specific window registers to a known state.
+ */
+static void s3c_fb_clear_win(struct s3c_fb *sfb, int win)
+{
+	void __iomem *regs = sfb->regs;
+
+	writel(0, regs + WINCON(win));
+	writel(0xffffff, regs + WxKEYCONy(win, 0));
+	writel(0xffffff, regs + WxKEYCONy(win, 1));
+
+	writel(0, regs + VIDOSD_A(win));
+	writel(0, regs + VIDOSD_B(win));
+	writel(0, regs + VIDOSD_C(win));
+}
+
+static int __devinit s3c_fb_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct s3c_fb_platdata *pd;
+	struct s3c_fb *sfb;
+	struct resource *res;
+	int win;
+	int ret = 0;
+
+	pd = pdev->dev.platform_data;
+	if (!pd) {
+		dev_err(dev, "no platform data specified\n");
+		return -EINVAL;
+	}
+
+	sfb = kzalloc(sizeof(struct s3c_fb), GFP_KERNEL);
+	if (!sfb) {
+		dev_err(dev, "no memory for framebuffers\n");
+		return -ENOMEM;
+	}
+
+	sfb->dev = dev;
+	sfb->pdata = pd;
+
+	sfb->bus_clk = clk_get(dev, "lcd");
+	if (IS_ERR(sfb->bus_clk)) {
+		dev_err(dev, "failed to get bus clock\n");
+		goto err_sfb;
+	}
+
+	clk_enable(sfb->bus_clk);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "failed to find registers\n");
+		ret = -ENOENT;
+		goto err_clk;
+	}
+
+	sfb->regs_res = request_mem_region(res->start, resource_size(res),
+					   dev_name(dev));
+	if (!sfb->regs_res) {
+		dev_err(dev, "failed to claim register region\n");
+		ret = -ENOENT;
+		goto err_clk;
+	}
+
+	sfb->regs = ioremap(res->start, resource_size(res));
+	if (!sfb->regs) {
+		dev_err(dev, "failed to map registers\n");
+		ret = -ENXIO;
+		goto err_req_region;
+	}
+
+	dev_dbg(dev, "got resources (regs %p), probing windows\n", sfb->regs);
+
+	/* setup gpio and output polarity controls */
+
+	pd->setup_gpio();
+
+	writel(pd->vidcon1, sfb->regs + VIDCON1);
+
+	/* zero all windows before we do anything */
+
+	for (win = 0; win < S3C_FB_MAX_WIN; win++)
+		s3c_fb_clear_win(sfb, win);
+
+	/* we have the register setup, start allocating framebuffers */
+
+	for (win = 0; win < S3C_FB_MAX_WIN; win++) {
+		if (!pd->win[win])
+			continue;
+
+		ret = s3c_fb_probe_win(sfb, win, &sfb->windows[win]);
+		if (ret < 0) {
+			dev_err(dev, "failed to create window %d\n", win);
+			for (; win >= 0; win--)
+				s3c_fb_release_win(sfb, sfb->windows[win]);
+			goto err_ioremap;
+		}
+	}
+
+	platform_set_drvdata(pdev, sfb);
+
+	return 0;
+
+err_ioremap:
+	iounmap(sfb->regs);
+
+err_req_region:
+	release_resource(sfb->regs_res);
+	kfree(sfb->regs_res);
+
+err_clk:
+	clk_disable(sfb->bus_clk);
+	clk_put(sfb->bus_clk);
+
+err_sfb:
+	kfree(sfb);
+	return ret;
+}
+
+/**
+ * s3c_fb_remove() - Cleanup on module finalisation
+ * @pdev: The platform device we are bound to.
+ *
+ * Shutdown and then release all the resources that the driver allocated
+ * on initialisation.
+ */
+static int __devexit s3c_fb_remove(struct platform_device *pdev)
+{
+	struct s3c_fb *sfb = platform_get_drvdata(pdev);
+	int win;
+
+	for (win = 0; win <= S3C_FB_MAX_WIN; win++)
+		s3c_fb_release_win(sfb, sfb->windows[win]);
+
+	iounmap(sfb->regs);
+
+	clk_disable(sfb->bus_clk);
+	clk_put(sfb->bus_clk);
+
+	release_resource(sfb->regs_res);
+	kfree(sfb->regs_res);
+
+	kfree(sfb);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int s3c_fb_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct s3c_fb *sfb = platform_get_drvdata(pdev);
+	struct s3c_fb_win *win;
+	int win_no;
+
+	for (win_no = S3C_FB_MAX_WIN; win_no >= 0; win_no--) {
+		win = sfb->windows[win_no];
+		if (!win)
+			continue;
+
+		/* use the blank function to push into power-down */
+		s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo);
+	}
+
+	clk_disable(sfb->bus_clk);
+	return 0;
+}
+
+static int s3c_fb_resume(struct platform_device *pdev)
+{
+	struct s3c_fb *sfb = platform_get_drvdata(pdev);
+	struct s3c_fb_win *win;
+	int win_no;
+
+	clk_enable(sfb->bus_clk);
+
+	for (win_no = 0; win_no < S3C_FB_MAX_WIN; win_no++) {
+		win = sfb->windows[win_no];
+		if (!win)
+			continue;
+
+		dev_dbg(&pdev->dev, "resuming window %d\n", win_no);
+		s3c_fb_set_par(win->fbinfo);
+	}
+
+	return 0;
+}
+#else
+#define s3c_fb_suspend NULL
+#define s3c_fb_resume  NULL
+#endif
+
+static struct platform_driver s3c_fb_driver = {
+	.probe		= s3c_fb_probe,
+	.remove		= s3c_fb_remove,
+	.suspend	= s3c_fb_suspend,
+	.resume		= s3c_fb_resume,
+	.driver		= {
+		.name	= "s3c-fb",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init s3c_fb_init(void)
+{
+	return platform_driver_register(&s3c_fb_driver);
+}
+
+static void __exit s3c_fb_cleanup(void)
+{
+	platform_driver_unregister(&s3c_fb_driver);
+}
+
+module_init(s3c_fb_init);
+module_exit(s3c_fb_cleanup);
+
+MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
+MODULE_DESCRIPTION("Samsung S3C SoC Framebuffer driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:s3c-fb");
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
index f5252c2..bba5371 100644
--- a/drivers/video/sgivwfb.c
+++ b/drivers/video/sgivwfb.c
@@ -837,6 +837,8 @@
 		iounmap(par->regs);
 		iounmap(info->screen_base);
 		release_mem_region(DBE_REG_PHYS, DBE_REG_SIZE);
+		fb_dealloc_cmap(&info->cmap);
+		framebuffer_release(info);
 	}
 	return 0;
 }
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index df53365..a439159 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -795,8 +795,9 @@
     if (!retval || retval == 4)
 	return -EINVAL;			
 
-    /* This has to been done !!! */	
-    fb_alloc_cmap(&info->cmap, cmap_len, 0);
+    /* This has to be done! */
+    if (fb_alloc_cmap(&info->cmap, cmap_len, 0))
+	return -ENOMEM;
 	
     /* 
      * The following is done in the case of having hardware with a static 
@@ -820,8 +821,10 @@
      */
     /* xxxfb_set_par(info); */
 
-    if (register_framebuffer(info) < 0)
+    if (register_framebuffer(info) < 0) {
+	fb_dealloc_cmap(&info->cmap);
 	return -EINVAL;
+    }
     printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
 	   info->fix.id);
     pci_set_drvdata(dev, info); /* or platform_set_drvdata(pdev, info) */
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index dcd9879..eb5d73a 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -1525,7 +1525,10 @@
 	}
 
 	/* initialise and set the palette */
-	fb_alloc_cmap(&fb->cmap, NR_PALETTE, 0);
+	if (fb_alloc_cmap(&fb->cmap, NR_PALETTE, 0)) {
+		dev_err(info->dev, "failed to allocate cmap memory\n");
+		return -ENOMEM;
+	}
 	fb_set_cmap(&fb->cmap, fb);
 
 	ret = (fb->fbops->fb_check_var)(&fb->var, fb);
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index 5b11a00..609d0a5 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -1421,13 +1421,16 @@
 		goto fail;
 	}
 	
-	fb_alloc_cmap(&info->cmap, 256, 0);
+	if (fb_alloc_cmap(&info->cmap, 256, 0)) {
+		printk(KERN_ERR "sstfb: can't alloc cmap memory.\n");
+		goto fail;
+	}
 
 	/* register fb */
 	info->device = &pdev->dev;
 	if (register_framebuffer(info) < 0) {
 		printk(KERN_ERR "sstfb: can't register framebuffer.\n");
-		goto fail;
+		goto fail_register;
 	}
 
 	sstfb_clear_screen(info);
@@ -1441,8 +1444,9 @@
 
 	return 0;
 
-fail:
+fail_register:
 	fb_dealloc_cmap(&info->cmap);
+fail:
 	iounmap(info->screen_base);
 fail_fb_remap:
 	iounmap(par->mmio_vbase);
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c
index 1664814..eabaad7 100644
--- a/drivers/video/stifb.c
+++ b/drivers/video/stifb.c
@@ -1262,24 +1262,25 @@
 	info->flags = FBINFO_DEFAULT;
 	info->pseudo_palette = &fb->pseudo_palette;
 
-	/* This has to been done !!! */
-	fb_alloc_cmap(&info->cmap, NR_PALETTE, 0);
+	/* This has to be done !!! */
+	if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0))
+		goto out_err1;
 	stifb_init_display(fb);
 
 	if (!request_mem_region(fix->smem_start, fix->smem_len, "stifb fb")) {
 		printk(KERN_ERR "stifb: cannot reserve fb region 0x%04lx-0x%04lx\n",
 				fix->smem_start, fix->smem_start+fix->smem_len);
-		goto out_err1;
+		goto out_err2;
 	}
 		
 	if (!request_mem_region(fix->mmio_start, fix->mmio_len, "stifb mmio")) {
 		printk(KERN_ERR "stifb: cannot reserve sti mmio region 0x%04lx-0x%04lx\n",
 				fix->mmio_start, fix->mmio_start+fix->mmio_len);
-		goto out_err2;
+		goto out_err3;
 	}
 
 	if (register_framebuffer(&fb->info) < 0)
-		goto out_err3;
+		goto out_err4;
 
 	sti->info = info; /* save for unregister_framebuffer() */
 
@@ -1297,13 +1298,14 @@
 	return 0;
 
 
-out_err3:
+out_err4:
 	release_mem_region(fix->mmio_start, fix->mmio_len);
-out_err2:
+out_err3:
 	release_mem_region(fix->smem_start, fix->smem_len);
+out_err2:
+	fb_dealloc_cmap(&info->cmap);
 out_err1:
 	iounmap(info->screen_base);
-	fb_dealloc_cmap(&info->cmap);
 out_err0:
 	kfree(fb);
 	return -ENXIO;
diff --git a/drivers/video/sunxvr500.c b/drivers/video/sunxvr500.c
index c2ba51b..18b9507 100644
--- a/drivers/video/sunxvr500.c
+++ b/drivers/video/sunxvr500.c
@@ -349,11 +349,14 @@
 	if (err < 0) {
 		printk(KERN_ERR "e3d: Could not register framebuffer %s\n",
 		       pci_name(pdev));
-		goto err_unmap_fb;
+		goto err_free_cmap;
 	}
 
 	return 0;
 
+err_free_cmap:
+	fb_dealloc_cmap(&info->cmap);
+
 err_unmap_fb:
 	iounmap(ep->fb_base);
 
@@ -389,6 +392,7 @@
 	pci_release_region(pdev, 0);
 	pci_release_region(pdev, 1);
 
+	fb_dealloc_cmap(&info->cmap);
         framebuffer_release(info);
 
 	pci_disable_device(pdev);
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 14bd3f3..ee64771 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -1393,6 +1393,7 @@
 	release_mem_region(pci_resource_start(pdev, 0),
 			   pci_resource_len(pdev, 0));
 	pci_set_drvdata(pdev, NULL);
+	fb_dealloc_cmap(&info->cmap);
 	framebuffer_release(info);
 }
 
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 680642c..a86046f 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -1663,7 +1663,7 @@
 	if (register_framebuffer(info) < 0) {
 		printk(KERN_ERR "tgafb: Could not register framebuffer\n");
 		ret = -EINVAL;
-		goto err1;
+		goto err2;
 	}
 
 	if (tga_bus_pci) {
@@ -1682,6 +1682,8 @@
 
 	return 0;
 
+ err2:
+	fb_dealloc_cmap(&info->cmap);
  err1:
 	if (mem_base)
 		iounmap(mem_base);
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index 479b2e7..03a9c35 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -2,7 +2,7 @@
  * Frame buffer driver for Trident TGUI, Blade and Image series
  *
  * Copyright 2001, 2002 - Jani Monoses   <jani@iv.ro>
- *
+ * Copyright 2009 Krzysztof Helt <krzysztof.h1@wp.pl>
  *
  * CREDITS:(in order of appearance)
  *	skeletonfb.c by Geert Uytterhoeven and other fb code in drivers/video
@@ -490,7 +490,6 @@
 /*
  * Accel functions called by the upper layers
  */
-#ifdef CONFIG_FB_TRIDENT_ACCEL
 static void tridentfb_fillrect(struct fb_info *info,
 			       const struct fb_fillrect *fr)
 {
@@ -565,11 +564,6 @@
 		par->wait_engine(par);
 	return 0;
 }
-#else
-#define tridentfb_fillrect cfb_fillrect
-#define tridentfb_copyarea cfb_copyarea
-#define tridentfb_imageblit cfb_imageblit
-#endif /* CONFIG_FB_TRIDENT_ACCEL */
 
 /*
  * Hardware access functions
@@ -1333,9 +1327,7 @@
 	.fb_fillrect = tridentfb_fillrect,
 	.fb_copyarea = tridentfb_copyarea,
 	.fb_imageblit = tridentfb_imageblit,
-#ifdef CONFIG_FB_TRIDENT_ACCEL
 	.fb_sync = tridentfb_sync,
-#endif
 };
 
 static int __devinit trident_pci_probe(struct pci_dev *dev,
@@ -1359,10 +1351,6 @@
 
 	chip_id = id->device;
 
-#ifndef CONFIG_FB_TRIDENT_ACCEL
-	noaccel = 1;
-#endif
-
 	/* If PCI id is 0x9660 then further detect chip type */
 
 	if (chip_id == TGUI9660) {
@@ -1490,6 +1478,9 @@
 	} else
 		info->flags |= FBINFO_HWACCEL_DISABLED;
 
+	if (is_blade(chip_id) && chip_id != BLADE3D)
+		info->flags |= FBINFO_READS_FAST;
+
 	info->pixmap.addr = kmalloc(4096, GFP_KERNEL);
 	if (!info->pixmap.addr) {
 		err = -ENOMEM;
@@ -1563,6 +1554,7 @@
 	release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);
 	pci_set_drvdata(dev, NULL);
 	kfree(info->pixmap.addr);
+	fb_dealloc_cmap(&info->cmap);
 	framebuffer_release(info);
 }
 
@@ -1663,4 +1655,5 @@
 MODULE_AUTHOR("Jani Monoses <jani@iv.ro>");
 MODULE_DESCRIPTION("Framebuffer driver for Trident cards");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("cyblafb");
 
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 74ae758..0b370ae 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -189,7 +189,7 @@
 	uvfb_tasks[seq] = task;
 	mutex_unlock(&uvfb_lock);
 
-	err = cn_netlink_send(m, 0, gfp_any());
+	err = cn_netlink_send(m, 0, GFP_KERNEL);
 	if (err == -ESRCH) {
 		/*
 		 * Try to start the userspace helper if sending
@@ -850,14 +850,16 @@
 	if (vbemode) {
 		for (i = 0; i < par->vbe_modes_cnt; i++) {
 			if (par->vbe_modes[i].mode_id == vbemode) {
+				modeid = i;
+				uvesafb_setup_var(&info->var, info,
+						&par->vbe_modes[modeid]);
 				fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
-							&info->var, info);
+						&info->var, info);
 				/*
 				 * With pixclock set to 0, the default BIOS
 				 * timings will be used in set_par().
 				 */
 				info->var.pixclock = 0;
-				modeid = i;
 				goto gotmode;
 			}
 		}
@@ -904,8 +906,11 @@
 			fb_videomode_to_var(&info->var, mode);
 		} else {
 			modeid = par->vbe_modes[0].mode_id;
+			uvesafb_setup_var(&info->var, info,
+					&par->vbe_modes[modeid]);
 			fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
-				    &info->var, info);
+					&info->var, info);
+
 			goto gotmode;
 		}
 	}
@@ -917,9 +922,9 @@
 	if (modeid == -1)
 		return -EINVAL;
 
-gotmode:
 	uvesafb_setup_var(&info->var, info, &par->vbe_modes[modeid]);
 
+gotmode:
 	/*
 	 * If we are not VBE3.0+ compliant, we're done -- the BIOS will
 	 * ignore our timings anyway.
@@ -1552,7 +1557,7 @@
 	}
 
 	info->flags = FBINFO_FLAG_DEFAULT |
-			(par->ypan) ? FBINFO_HWACCEL_YPAN : 0;
+			(par->ypan ? FBINFO_HWACCEL_YPAN : 0);
 
 	if (!par->ypan)
 		info->fbops->fb_pan_display = NULL;
diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c
index 7b0cef9..4bb9a0b 100644
--- a/drivers/video/valkyriefb.c
+++ b/drivers/video/valkyriefb.c
@@ -119,7 +119,7 @@
 static int valkyrie_var_to_par(struct fb_var_screeninfo *var,
 	struct fb_par_valkyrie *par, const struct fb_info *fb_info);
 
-static void valkyrie_init_info(struct fb_info *info, struct fb_info_valkyrie *p);
+static int valkyrie_init_info(struct fb_info *info, struct fb_info_valkyrie *p);
 static void valkyrie_par_to_fix(struct fb_par_valkyrie *par, struct fb_fix_screeninfo *fix);
 static void valkyrie_init_fix(struct fb_fix_screeninfo *fix, struct fb_info_valkyrie *p);
 
@@ -381,18 +381,22 @@
 
 	valkyrie_choose_mode(p);
 	mac_vmode_to_var(default_vmode, default_cmode, &p->info.var);
-	valkyrie_init_info(&p->info, p);
+	err = valkyrie_init_info(&p->info, p);
+	if (err < 0)
+		goto out_free;
 	valkyrie_init_fix(&p->info.fix, p);
 	if (valkyriefb_set_par(&p->info))
 		/* "can't happen" */
 		printk(KERN_ERR "valkyriefb: can't set default video mode\n");
 
 	if ((err = register_framebuffer(&p->info)) != 0)
-		goto out_free;
+		goto out_cmap_free;
 
 	printk(KERN_INFO "fb%d: valkyrie frame buffer device\n", p->info.node);
 	return 0;
 
+ out_cmap_free:
+	fb_dealloc_cmap(&p->info.cmap);
  out_free:
 	if (p->frame_buffer)
 		iounmap(p->frame_buffer);
@@ -538,14 +542,15 @@
 		/* ywrapstep, xpanstep, ypanstep */
 }
 
-static void __init valkyrie_init_info(struct fb_info *info, struct fb_info_valkyrie *p)
+static int __init valkyrie_init_info(struct fb_info *info,
+		struct fb_info_valkyrie *p)
 {
 	info->fbops = &valkyriefb_ops;
 	info->screen_base = p->frame_buffer + 0x1000;
 	info->flags = FBINFO_DEFAULT;
 	info->pseudo_palette = p->pseudo_palette;
-	fb_alloc_cmap(&info->cmap, 256, 0);
 	info->par = &p->par;
+	return fb_alloc_cmap(&info->cmap, 256, 0);
 }
 
 
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index e16322d..d6856f4 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -438,7 +438,7 @@
 	info->var = vesafb_defined;
 	info->fix = vesafb_fix;
 	info->flags = FBINFO_FLAG_DEFAULT |
-		(ypan) ? FBINFO_HWACCEL_YPAN : 0;
+		(ypan ? FBINFO_HWACCEL_YPAN : 0);
 
 	if (!ypan)
 		info->fbops->fb_pan_display = NULL;
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index 93fe08d..cc919ae 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -543,6 +543,7 @@
 	if (info) {
 		unregister_framebuffer(info);
 		rvfree(videomemory, videomemorysize);
+		fb_dealloc_cmap(&info->cmap);
 		framebuffer_release(info);
 	}
 	return 0;
diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c
index 632523f..45c54bf 100644
--- a/drivers/video/via/accel.c
+++ b/drivers/video/via/accel.c
@@ -267,13 +267,17 @@
 	int loop = 0;
 
 	while (!(readl(viaparinfo->io_virt + VIA_REG_STATUS) &
-			VIA_VR_QUEUE_BUSY) && (loop++ < MAXLOOP))
+			VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) {
+		loop++;
 		cpu_relax();
+	}
 
 	while ((readl(viaparinfo->io_virt + VIA_REG_STATUS) &
 		    (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
-		    (loop++ < MAXLOOP))
+		    (loop < MAXLOOP)) {
+		loop++;
 		cpu_relax();
+	}
 
 	return loop >= MAXLOOP;
 }
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index a768031..b7ff33c 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -186,6 +186,8 @@
 int autofs4_expire_run(struct super_block *, struct vfsmount *,
 			struct autofs_sb_info *,
 			struct autofs_packet_expire __user *);
+int autofs4_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,
+			    struct autofs_sb_info *sbi, int when);
 int autofs4_expire_multi(struct super_block *, struct vfsmount *,
 			struct autofs_sb_info *, int __user *);
 struct dentry *autofs4_expire_direct(struct super_block *sb,
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c
index 025e105..9e5ae8a 100644
--- a/fs/autofs4/dev-ioctl.c
+++ b/fs/autofs4/dev-ioctl.c
@@ -525,40 +525,13 @@
 				   struct autofs_sb_info *sbi,
 				   struct autofs_dev_ioctl *param)
 {
-	struct dentry *dentry;
 	struct vfsmount *mnt;
-	int err = -EAGAIN;
 	int how;
 
 	how = param->expire.how;
 	mnt = fp->f_path.mnt;
 
-	if (autofs_type_trigger(sbi->type))
-		dentry = autofs4_expire_direct(sbi->sb, mnt, sbi, how);
-	else
-		dentry = autofs4_expire_indirect(sbi->sb, mnt, sbi, how);
-
-	if (dentry) {
-		struct autofs_info *ino = autofs4_dentry_ino(dentry);
-
-		/*
-		 * This is synchronous because it makes the daemon a
-		 * little easier
-		*/
-		err = autofs4_wait(sbi, dentry, NFY_EXPIRE);
-
-		spin_lock(&sbi->fs_lock);
-		if (ino->flags & AUTOFS_INF_MOUNTPOINT) {
-			ino->flags &= ~AUTOFS_INF_MOUNTPOINT;
-			sbi->sb->s_root->d_mounted++;
-		}
-		ino->flags &= ~AUTOFS_INF_EXPIRING;
-		complete_all(&ino->expire_complete);
-		spin_unlock(&sbi->fs_lock);
-		dput(dentry);
-	}
-
-	return err;
+	return autofs4_do_expire_multi(sbi->sb, mnt, sbi, how);
 }
 
 /* Check if autofs mount point is in use */
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index e3bd507..75f7dda 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -478,22 +478,16 @@
 	return ret;
 }
 
-/* Call repeatedly until it returns -EAGAIN, meaning there's nothing
-   more to be done */
-int autofs4_expire_multi(struct super_block *sb, struct vfsmount *mnt,
-			struct autofs_sb_info *sbi, int __user *arg)
+int autofs4_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,
+			    struct autofs_sb_info *sbi, int when)
 {
 	struct dentry *dentry;
 	int ret = -EAGAIN;
-	int do_now = 0;
-
-	if (arg && get_user(do_now, arg))
-		return -EFAULT;
 
 	if (autofs_type_trigger(sbi->type))
-		dentry = autofs4_expire_direct(sb, mnt, sbi, do_now);
+		dentry = autofs4_expire_direct(sb, mnt, sbi, when);
 	else
-		dentry = autofs4_expire_indirect(sb, mnt, sbi, do_now);
+		dentry = autofs4_expire_indirect(sb, mnt, sbi, when);
 
 	if (dentry) {
 		struct autofs_info *ino = autofs4_dentry_ino(dentry);
@@ -516,3 +510,16 @@
 	return ret;
 }
 
+/* Call repeatedly until it returns -EAGAIN, meaning there's nothing
+   more to be done */
+int autofs4_expire_multi(struct super_block *sb, struct vfsmount *mnt,
+			struct autofs_sb_info *sbi, int __user *arg)
+{
+	int do_now = 0;
+
+	if (arg && get_user(do_now, arg))
+		return -EFAULT;
+
+	return autofs4_do_expire_multi(sb, mnt, sbi, do_now);
+}
+
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 74b1469..e383bf0 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -485,22 +485,6 @@
 	DPRINTK("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d",
 		 current->pid, task_pgrp_nr(current), sbi->catatonic, oz_mode);
 
-	expiring = autofs4_lookup_expiring(sbi, dentry->d_parent, &dentry->d_name);
-	if (expiring) {
-		/*
-		 * If we are racing with expire the request might not
-		 * be quite complete but the directory has been removed
-		 * so it must have been successful, so just wait for it.
-		 */
-		ino = autofs4_dentry_ino(expiring);
-		autofs4_expire_wait(expiring);
-		spin_lock(&sbi->lookup_lock);
-		if (!list_empty(&ino->expiring))
-			list_del_init(&ino->expiring);
-		spin_unlock(&sbi->lookup_lock);
-		dput(expiring);
-	}
-
 	unhashed = autofs4_lookup_active(sbi, dentry->d_parent, &dentry->d_name);
 	if (unhashed)
 		dentry = unhashed;
@@ -538,14 +522,31 @@
 	}
 
 	if (!oz_mode) {
+		mutex_unlock(&dir->i_mutex);
+		expiring = autofs4_lookup_expiring(sbi,
+						   dentry->d_parent,
+						   &dentry->d_name);
+		if (expiring) {
+			/*
+			 * If we are racing with expire the request might not
+			 * be quite complete but the directory has been removed
+			 * so it must have been successful, so just wait for it.
+			 */
+			ino = autofs4_dentry_ino(expiring);
+			autofs4_expire_wait(expiring);
+			spin_lock(&sbi->lookup_lock);
+			if (!list_empty(&ino->expiring))
+				list_del_init(&ino->expiring);
+			spin_unlock(&sbi->lookup_lock);
+			dput(expiring);
+		}
+
 		spin_lock(&dentry->d_lock);
 		dentry->d_flags |= DCACHE_AUTOFS_PENDING;
 		spin_unlock(&dentry->d_lock);
-		if (dentry->d_op && dentry->d_op->d_revalidate) {
-			mutex_unlock(&dir->i_mutex);
+		if (dentry->d_op && dentry->d_op->d_revalidate)
 			(dentry->d_op->d_revalidate)(dentry, nd);
-			mutex_lock(&dir->i_mutex);
-		}
+		mutex_lock(&dir->i_mutex);
 	}
 
 	/*
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 5e1d4e3..7dd1b6d 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2060,7 +2060,7 @@
 unsigned long btrfs_force_ra(struct address_space *mapping,
 			      struct file_ra_state *ra, struct file *file,
 			      pgoff_t offset, pgoff_t last_index);
-int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page);
+int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
 int btrfs_readpage(struct file *file, struct page *page);
 void btrfs_delete_inode(struct inode *inode);
 void btrfs_put_inode(struct inode *inode);
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 7d4f948..17e608c 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -4292,8 +4292,9 @@
  * beyond EOF, then the page is guaranteed safe against truncation until we
  * unlock the page.
  */
-int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page)
+int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
+	struct page *page = vmf->page;
 	struct inode *inode = fdentry(vma->vm_file)->d_inode;
 	struct btrfs_root *root = BTRFS_I(inode)->root;
 	struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
@@ -4306,10 +4307,15 @@
 	u64 page_end;
 
 	ret = btrfs_check_data_free_space(root, inode, PAGE_CACHE_SIZE);
-	if (ret)
+	if (ret) {
+		if (ret == -ENOMEM)
+			ret = VM_FAULT_OOM;
+		else /* -ENOSPC, -EIO, etc */
+			ret = VM_FAULT_SIGBUS;
 		goto out;
+	}
 
-	ret = -EINVAL;
+	ret = VM_FAULT_NOPAGE; /* make the VM retry the fault */
 again:
 	lock_page(page);
 	size = i_size_read(inode);
diff --git a/fs/buffer.c b/fs/buffer.c
index a2fd743..f5f8b15 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -290,7 +290,7 @@
 						&zone);
 		if (zone)
 			try_to_free_pages(node_zonelist(nid, GFP_NOFS), 0,
-						GFP_NOFS);
+						GFP_NOFS, NULL);
 	}
 }
 
@@ -547,6 +547,39 @@
 	return err;
 }
 
+void do_thaw_all(unsigned long unused)
+{
+	struct super_block *sb;
+	char b[BDEVNAME_SIZE];
+
+	spin_lock(&sb_lock);
+restart:
+	list_for_each_entry(sb, &super_blocks, s_list) {
+		sb->s_count++;
+		spin_unlock(&sb_lock);
+		down_read(&sb->s_umount);
+		while (sb->s_bdev && !thaw_bdev(sb->s_bdev, sb))
+			printk(KERN_WARNING "Emergency Thaw on %s\n",
+			       bdevname(sb->s_bdev, b));
+		up_read(&sb->s_umount);
+		spin_lock(&sb_lock);
+		if (__put_super_and_need_restart(sb))
+			goto restart;
+	}
+	spin_unlock(&sb_lock);
+	printk(KERN_WARNING "Emergency Thaw complete\n");
+}
+
+/**
+ * emergency_thaw_all -- forcibly thaw every frozen filesystem
+ *
+ * Used for emergency unfreeze of all filesystems via SysRq
+ */
+void emergency_thaw_all(void)
+{
+	pdflush_operation(do_thaw_all, 0);
+}
+
 /**
  * sync_mapping_buffers - write out & wait upon a mapping's "associated" buffers
  * @mapping: the mapping which wants those buffers written
@@ -621,14 +654,7 @@
 	spin_lock_irq(&mapping->tree_lock);
 	if (page->mapping) {	/* Race with truncate? */
 		WARN_ON_ONCE(warn && !PageUptodate(page));
-
-		if (mapping_cap_account_dirty(mapping)) {
-			__inc_zone_page_state(page, NR_FILE_DIRTY);
-			__inc_bdi_stat(mapping->backing_dev_info,
-					BDI_RECLAIMABLE);
-			task_dirty_inc(current);
-			task_io_account_write(PAGE_CACHE_SIZE);
-		}
+		account_page_dirtied(page, mapping);
 		radix_tree_tag_set(&mapping->page_tree,
 				page_index(page), PAGECACHE_TAG_DIRTY);
 	}
@@ -2320,13 +2346,14 @@
  * unlock the page.
  */
 int
-block_page_mkwrite(struct vm_area_struct *vma, struct page *page,
+block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
 		   get_block_t get_block)
 {
+	struct page *page = vmf->page;
 	struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
 	unsigned long end;
 	loff_t size;
-	int ret = -EINVAL;
+	int ret = VM_FAULT_NOPAGE; /* make the VM retry the fault */
 
 	lock_page(page);
 	size = i_size_read(inode);
@@ -2346,6 +2373,13 @@
 	if (!ret)
 		ret = block_commit_write(page, 0, end);
 
+	if (unlikely(ret)) {
+		if (ret == -ENOMEM)
+			ret = VM_FAULT_OOM;
+		else /* -ENOSPC, -EIO, etc */
+			ret = VM_FAULT_SIGBUS;
+	}
+
 out_unlock:
 	unlock_page(page);
 	return ret;
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index e4a6223..af737bb 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -740,8 +740,7 @@
 out_release_free_unlock:
 	crypto_free_hash(s->hash_desc.tfm);
 out_free_unlock:
-	memset(s->block_aligned_filename, 0, s->block_aligned_filename_size);
-	kfree(s->block_aligned_filename);
+	kzfree(s->block_aligned_filename);
 out_unlock:
 	mutex_unlock(s->tfm_mutex);
 out:
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c
index 96ef514..295e7fa 100644
--- a/fs/ecryptfs/messaging.c
+++ b/fs/ecryptfs/messaging.c
@@ -291,8 +291,7 @@
 	if (daemon->user_ns)
 		put_user_ns(daemon->user_ns);
 	mutex_unlock(&daemon->mux);
-	memset(daemon, 0, sizeof(*daemon));
-	kfree(daemon);
+	kzfree(daemon);
 out:
 	return rc;
 }
diff --git a/fs/eventfd.c b/fs/eventfd.c
index 5de2c2d..2a701d5 100644
--- a/fs/eventfd.c
+++ b/fs/eventfd.c
@@ -28,6 +28,7 @@
 	 * issue a wakeup.
 	 */
 	__u64 count;
+	unsigned int flags;
 };
 
 /*
@@ -50,7 +51,7 @@
 		n = (int) (ULLONG_MAX - ctx->count);
 	ctx->count += n;
 	if (waitqueue_active(&ctx->wqh))
-		wake_up_locked(&ctx->wqh);
+		wake_up_locked_poll(&ctx->wqh, POLLIN);
 	spin_unlock_irqrestore(&ctx->wqh.lock, flags);
 
 	return n;
@@ -87,22 +88,20 @@
 {
 	struct eventfd_ctx *ctx = file->private_data;
 	ssize_t res;
-	__u64 ucnt;
+	__u64 ucnt = 0;
 	DECLARE_WAITQUEUE(wait, current);
 
 	if (count < sizeof(ucnt))
 		return -EINVAL;
 	spin_lock_irq(&ctx->wqh.lock);
 	res = -EAGAIN;
-	ucnt = ctx->count;
-	if (ucnt > 0)
+	if (ctx->count > 0)
 		res = sizeof(ucnt);
 	else if (!(file->f_flags & O_NONBLOCK)) {
 		__add_wait_queue(&ctx->wqh, &wait);
 		for (res = 0;;) {
 			set_current_state(TASK_INTERRUPTIBLE);
 			if (ctx->count > 0) {
-				ucnt = ctx->count;
 				res = sizeof(ucnt);
 				break;
 			}
@@ -117,10 +116,11 @@
 		__remove_wait_queue(&ctx->wqh, &wait);
 		__set_current_state(TASK_RUNNING);
 	}
-	if (res > 0) {
-		ctx->count = 0;
+	if (likely(res > 0)) {
+		ucnt = (ctx->flags & EFD_SEMAPHORE) ? 1 : ctx->count;
+		ctx->count -= ucnt;
 		if (waitqueue_active(&ctx->wqh))
-			wake_up_locked(&ctx->wqh);
+			wake_up_locked_poll(&ctx->wqh, POLLOUT);
 	}
 	spin_unlock_irq(&ctx->wqh.lock);
 	if (res > 0 && put_user(ucnt, (__u64 __user *) buf))
@@ -166,10 +166,10 @@
 		__remove_wait_queue(&ctx->wqh, &wait);
 		__set_current_state(TASK_RUNNING);
 	}
-	if (res > 0) {
+	if (likely(res > 0)) {
 		ctx->count += ucnt;
 		if (waitqueue_active(&ctx->wqh))
-			wake_up_locked(&ctx->wqh);
+			wake_up_locked_poll(&ctx->wqh, POLLIN);
 	}
 	spin_unlock_irq(&ctx->wqh.lock);
 
@@ -207,7 +207,7 @@
 	BUILD_BUG_ON(EFD_CLOEXEC != O_CLOEXEC);
 	BUILD_BUG_ON(EFD_NONBLOCK != O_NONBLOCK);
 
-	if (flags & ~(EFD_CLOEXEC | EFD_NONBLOCK))
+	if (flags & ~EFD_FLAGS_SET)
 		return -EINVAL;
 
 	ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
@@ -216,13 +216,14 @@
 
 	init_waitqueue_head(&ctx->wqh);
 	ctx->count = count;
+	ctx->flags = flags;
 
 	/*
 	 * When we call this, the initialization must be complete, since
 	 * anon_inode_getfd() will install the fd.
 	 */
 	fd = anon_inode_getfd("[eventfd]", &eventfd_fops, ctx,
-			      flags & (O_CLOEXEC | O_NONBLOCK));
+			      flags & EFD_SHARED_FCNTL_FLAGS);
 	if (fd < 0)
 		kfree(ctx);
 	return fd;
@@ -232,3 +233,4 @@
 {
 	return sys_eventfd2(count, 0);
 }
+
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index c5c424f..a89f370 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -1,6 +1,6 @@
 /*
- *  fs/eventpoll.c (Efficent event polling implementation)
- *  Copyright (C) 2001,...,2007	 Davide Libenzi
+ *  fs/eventpoll.c (Efficient event retrieval implementation)
+ *  Copyright (C) 2001,...,2009	 Davide Libenzi
  *
  *  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
@@ -71,29 +71,11 @@
  * a better scalability.
  */
 
-#define DEBUG_EPOLL 0
-
-#if DEBUG_EPOLL > 0
-#define DPRINTK(x) printk x
-#define DNPRINTK(n, x) do { if ((n) <= DEBUG_EPOLL) printk x; } while (0)
-#else /* #if DEBUG_EPOLL > 0 */
-#define DPRINTK(x) (void) 0
-#define DNPRINTK(n, x) (void) 0
-#endif /* #if DEBUG_EPOLL > 0 */
-
-#define DEBUG_EPI 0
-
-#if DEBUG_EPI != 0
-#define EPI_SLAB_DEBUG (SLAB_DEBUG_FREE | SLAB_RED_ZONE /* | SLAB_POISON */)
-#else /* #if DEBUG_EPI != 0 */
-#define EPI_SLAB_DEBUG 0
-#endif /* #if DEBUG_EPI != 0 */
-
 /* Epoll private bits inside the event mask */
 #define EP_PRIVATE_BITS (EPOLLONESHOT | EPOLLET)
 
-/* Maximum number of poll wake up nests we are allowing */
-#define EP_MAX_POLLWAKE_NESTS 4
+/* Maximum number of nesting allowed inside epoll sets */
+#define EP_MAX_NESTS 4
 
 /* Maximum msec timeout value storeable in a long int */
 #define EP_MAX_MSTIMEO min(1000ULL * MAX_SCHEDULE_TIMEOUT / HZ, (LONG_MAX - 999ULL) / HZ)
@@ -110,24 +92,21 @@
 };
 
 /*
- * Node that is linked into the "wake_task_list" member of the "struct poll_safewake".
- * It is used to keep track on all tasks that are currently inside the wake_up() code
- * to 1) short-circuit the one coming from the same task and same wait queue head
- * (loop) 2) allow a maximum number of epoll descriptors inclusion nesting
- * 3) let go the ones coming from other tasks.
+ * Structure used to track possible nested calls, for too deep recursions
+ * and loop cycles.
  */
-struct wake_task_node {
+struct nested_call_node {
 	struct list_head llink;
-	struct task_struct *task;
-	wait_queue_head_t *wq;
+	void *cookie;
+	int cpu;
 };
 
 /*
- * This is used to implement the safe poll wake up avoiding to reenter
- * the poll callback from inside wake_up().
+ * This structure is used as collector for nested calls, to check for
+ * maximum recursion dept and loop cycles.
  */
-struct poll_safewake {
-	struct list_head wake_task_list;
+struct nested_calls {
+	struct list_head tasks_call_list;
 	spinlock_t lock;
 };
 
@@ -213,7 +192,7 @@
 	struct list_head llink;
 
 	/* The "base" pointer is set to the container "struct epitem" */
-	void *base;
+	struct epitem *base;
 
 	/*
 	 * Wait queue item that will be linked to the target file wait
@@ -231,6 +210,12 @@
 	struct epitem *epi;
 };
 
+/* Used by the ep_send_events() function as callback private data */
+struct ep_send_events_data {
+	int maxevents;
+	struct epoll_event __user *events;
+};
+
 /*
  * Configuration options available inside /proc/sys/fs/epoll/
  */
@@ -242,8 +227,11 @@
  */
 static DEFINE_MUTEX(epmutex);
 
-/* Safe wake up implementation */
-static struct poll_safewake psw;
+/* Used for safe wake up implementation */
+static struct nested_calls poll_safewake_ncalls;
+
+/* Used to call file's f_op->poll() under the nested calls boundaries */
+static struct nested_calls poll_readywalk_ncalls;
 
 /* Slab cache used to allocate "struct epitem" */
 static struct kmem_cache *epi_cache __read_mostly;
@@ -312,11 +300,100 @@
 }
 
 /* Initialize the poll safe wake up structure */
-static void ep_poll_safewake_init(struct poll_safewake *psw)
+static void ep_nested_calls_init(struct nested_calls *ncalls)
 {
+	INIT_LIST_HEAD(&ncalls->tasks_call_list);
+	spin_lock_init(&ncalls->lock);
+}
 
-	INIT_LIST_HEAD(&psw->wake_task_list);
-	spin_lock_init(&psw->lock);
+/**
+ * ep_call_nested - Perform a bound (possibly) nested call, by checking
+ *                  that the recursion limit is not exceeded, and that
+ *                  the same nested call (by the meaning of same cookie) is
+ *                  no re-entered.
+ *
+ * @ncalls: Pointer to the nested_calls structure to be used for this call.
+ * @max_nests: Maximum number of allowed nesting calls.
+ * @nproc: Nested call core function pointer.
+ * @priv: Opaque data to be passed to the @nproc callback.
+ * @cookie: Cookie to be used to identify this nested call.
+ *
+ * Returns: Returns the code returned by the @nproc callback, or -1 if
+ *          the maximum recursion limit has been exceeded.
+ */
+static int ep_call_nested(struct nested_calls *ncalls, int max_nests,
+			  int (*nproc)(void *, void *, int), void *priv,
+			  void *cookie)
+{
+	int error, call_nests = 0;
+	unsigned long flags;
+	int this_cpu = get_cpu();
+	struct list_head *lsthead = &ncalls->tasks_call_list;
+	struct nested_call_node *tncur;
+	struct nested_call_node tnode;
+
+	spin_lock_irqsave(&ncalls->lock, flags);
+
+	/*
+	 * Try to see if the current task is already inside this wakeup call.
+	 * We use a list here, since the population inside this set is always
+	 * very much limited.
+	 */
+	list_for_each_entry(tncur, lsthead, llink) {
+		if (tncur->cpu == this_cpu &&
+		    (tncur->cookie == cookie || ++call_nests > max_nests)) {
+			/*
+			 * Ops ... loop detected or maximum nest level reached.
+			 * We abort this wake by breaking the cycle itself.
+			 */
+			error = -1;
+			goto out_unlock;
+		}
+	}
+
+	/* Add the current task and cookie to the list */
+	tnode.cpu = this_cpu;
+	tnode.cookie = cookie;
+	list_add(&tnode.llink, lsthead);
+
+	spin_unlock_irqrestore(&ncalls->lock, flags);
+
+	/* Call the nested function */
+	error = (*nproc)(priv, cookie, call_nests);
+
+	/* Remove the current task from the list */
+	spin_lock_irqsave(&ncalls->lock, flags);
+	list_del(&tnode.llink);
+ out_unlock:
+	spin_unlock_irqrestore(&ncalls->lock, flags);
+
+	put_cpu();
+	return error;
+}
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+static inline void ep_wake_up_nested(wait_queue_head_t *wqueue,
+				     unsigned long events, int subclass)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave_nested(&wqueue->lock, flags, subclass);
+	wake_up_locked_poll(wqueue, events);
+	spin_unlock_irqrestore(&wqueue->lock, flags);
+}
+#else
+static inline void ep_wake_up_nested(wait_queue_head_t *wqueue,
+				     unsigned long events, int subclass)
+{
+	wake_up_poll(wqueue, events);
+}
+#endif
+
+static int ep_poll_wakeup_proc(void *priv, void *cookie, int call_nests)
+{
+	ep_wake_up_nested((wait_queue_head_t *) cookie, POLLIN,
+			  1 + call_nests);
+	return 0;
 }
 
 /*
@@ -324,79 +401,131 @@
  * with the new callback'd wake up system, it is possible that the
  * poll callback is reentered from inside the call to wake_up() done
  * on the poll wait queue head. The rule is that we cannot reenter the
- * wake up code from the same task more than EP_MAX_POLLWAKE_NESTS times,
+ * wake up code from the same task more than EP_MAX_NESTS times,
  * and we cannot reenter the same wait queue head at all. This will
  * enable to have a hierarchy of epoll file descriptor of no more than
- * EP_MAX_POLLWAKE_NESTS deep. We need the irq version of the spin lock
- * because this one gets called by the poll callback, that in turn is called
- * from inside a wake_up(), that might be called from irq context.
+ * EP_MAX_NESTS deep.
  */
-static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq)
+static void ep_poll_safewake(wait_queue_head_t *wq)
 {
-	int wake_nests = 0;
-	unsigned long flags;
-	struct task_struct *this_task = current;
-	struct list_head *lsthead = &psw->wake_task_list;
-	struct wake_task_node *tncur;
-	struct wake_task_node tnode;
-
-	spin_lock_irqsave(&psw->lock, flags);
-
-	/* Try to see if the current task is already inside this wakeup call */
-	list_for_each_entry(tncur, lsthead, llink) {
-
-		if (tncur->wq == wq ||
-		    (tncur->task == this_task && ++wake_nests > EP_MAX_POLLWAKE_NESTS)) {
-			/*
-			 * Ops ... loop detected or maximum nest level reached.
-			 * We abort this wake by breaking the cycle itself.
-			 */
-			spin_unlock_irqrestore(&psw->lock, flags);
-			return;
-		}
-	}
-
-	/* Add the current task to the list */
-	tnode.task = this_task;
-	tnode.wq = wq;
-	list_add(&tnode.llink, lsthead);
-
-	spin_unlock_irqrestore(&psw->lock, flags);
-
-	/* Do really wake up now */
-	wake_up_nested(wq, 1 + wake_nests);
-
-	/* Remove the current task from the list */
-	spin_lock_irqsave(&psw->lock, flags);
-	list_del(&tnode.llink);
-	spin_unlock_irqrestore(&psw->lock, flags);
+	ep_call_nested(&poll_safewake_ncalls, EP_MAX_NESTS,
+		       ep_poll_wakeup_proc, NULL, wq);
 }
 
 /*
- * This function unregister poll callbacks from the associated file descriptor.
- * Since this must be called without holding "ep->lock" the atomic exchange trick
- * will protect us from multiple unregister.
+ * This function unregisters poll callbacks from the associated file
+ * descriptor.  Must be called with "mtx" held (or "epmutex" if called from
+ * ep_free).
  */
 static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi)
 {
-	int nwait;
 	struct list_head *lsthead = &epi->pwqlist;
 	struct eppoll_entry *pwq;
 
-	/* This is called without locks, so we need the atomic exchange */
-	nwait = xchg(&epi->nwait, 0);
+	while (!list_empty(lsthead)) {
+		pwq = list_first_entry(lsthead, struct eppoll_entry, llink);
 
-	if (nwait) {
-		while (!list_empty(lsthead)) {
-			pwq = list_first_entry(lsthead, struct eppoll_entry, llink);
-
-			list_del_init(&pwq->llink);
-			remove_wait_queue(pwq->whead, &pwq->wait);
-			kmem_cache_free(pwq_cache, pwq);
-		}
+		list_del(&pwq->llink);
+		remove_wait_queue(pwq->whead, &pwq->wait);
+		kmem_cache_free(pwq_cache, pwq);
 	}
 }
 
+/**
+ * ep_scan_ready_list - Scans the ready list in a way that makes possible for
+ *                      the scan code, to call f_op->poll(). Also allows for
+ *                      O(NumReady) performance.
+ *
+ * @ep: Pointer to the epoll private data structure.
+ * @sproc: Pointer to the scan callback.
+ * @priv: Private opaque data passed to the @sproc callback.
+ *
+ * Returns: The same integer error code returned by the @sproc callback.
+ */
+static int ep_scan_ready_list(struct eventpoll *ep,
+			      int (*sproc)(struct eventpoll *,
+					   struct list_head *, void *),
+			      void *priv)
+{
+	int error, pwake = 0;
+	unsigned long flags;
+	struct epitem *epi, *nepi;
+	LIST_HEAD(txlist);
+
+	/*
+	 * We need to lock this because we could be hit by
+	 * eventpoll_release_file() and epoll_ctl().
+	 */
+	mutex_lock(&ep->mtx);
+
+	/*
+	 * Steal the ready list, and re-init the original one to the
+	 * empty list. Also, set ep->ovflist to NULL so that events
+	 * happening while looping w/out locks, are not lost. We cannot
+	 * have the poll callback to queue directly on ep->rdllist,
+	 * because we want the "sproc" callback to be able to do it
+	 * in a lockless way.
+	 */
+	spin_lock_irqsave(&ep->lock, flags);
+	list_splice_init(&ep->rdllist, &txlist);
+	ep->ovflist = NULL;
+	spin_unlock_irqrestore(&ep->lock, flags);
+
+	/*
+	 * Now call the callback function.
+	 */
+	error = (*sproc)(ep, &txlist, priv);
+
+	spin_lock_irqsave(&ep->lock, flags);
+	/*
+	 * During the time we spent inside the "sproc" callback, some
+	 * other events might have been queued by the poll callback.
+	 * We re-insert them inside the main ready-list here.
+	 */
+	for (nepi = ep->ovflist; (epi = nepi) != NULL;
+	     nepi = epi->next, epi->next = EP_UNACTIVE_PTR) {
+		/*
+		 * We need to check if the item is already in the list.
+		 * During the "sproc" callback execution time, items are
+		 * queued into ->ovflist but the "txlist" might already
+		 * contain them, and the list_splice() below takes care of them.
+		 */
+		if (!ep_is_linked(&epi->rdllink))
+			list_add_tail(&epi->rdllink, &ep->rdllist);
+	}
+	/*
+	 * We need to set back ep->ovflist to EP_UNACTIVE_PTR, so that after
+	 * releasing the lock, events will be queued in the normal way inside
+	 * ep->rdllist.
+	 */
+	ep->ovflist = EP_UNACTIVE_PTR;
+
+	/*
+	 * Quickly re-inject items left on "txlist".
+	 */
+	list_splice(&txlist, &ep->rdllist);
+
+	if (!list_empty(&ep->rdllist)) {
+		/*
+		 * Wake up (if active) both the eventpoll wait list and
+		 * the ->poll() wait list (delayed after we release the lock).
+		 */
+		if (waitqueue_active(&ep->wq))
+			wake_up_locked(&ep->wq);
+		if (waitqueue_active(&ep->poll_wait))
+			pwake++;
+	}
+	spin_unlock_irqrestore(&ep->lock, flags);
+
+	mutex_unlock(&ep->mtx);
+
+	/* We have to call this outside the lock */
+	if (pwake)
+		ep_poll_safewake(&ep->poll_wait);
+
+	return error;
+}
+
 /*
  * Removes a "struct epitem" from the eventpoll RB tree and deallocates
  * all the associated resources. Must be called with "mtx" held.
@@ -434,9 +563,6 @@
 
 	atomic_dec(&ep->user->epoll_watches);
 
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_remove(%p, %p)\n",
-		     current, ep, file));
-
 	return 0;
 }
 
@@ -447,7 +573,7 @@
 
 	/* We need to release all tasks waiting for these file */
 	if (waitqueue_active(&ep->poll_wait))
-		ep_poll_safewake(&psw, &ep->poll_wait);
+		ep_poll_safewake(&ep->poll_wait);
 
 	/*
 	 * We need to lock this because we could be hit by
@@ -492,26 +618,54 @@
 	if (ep)
 		ep_free(ep);
 
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: close() ep=%p\n", current, ep));
 	return 0;
 }
 
+static int ep_read_events_proc(struct eventpoll *ep, struct list_head *head,
+			       void *priv)
+{
+	struct epitem *epi, *tmp;
+
+	list_for_each_entry_safe(epi, tmp, head, rdllink) {
+		if (epi->ffd.file->f_op->poll(epi->ffd.file, NULL) &
+		    epi->event.events)
+			return POLLIN | POLLRDNORM;
+		else {
+			/*
+			 * Item has been dropped into the ready list by the poll
+			 * callback, but it's not actually ready, as far as
+			 * caller requested events goes. We can remove it here.
+			 */
+			list_del_init(&epi->rdllink);
+		}
+	}
+
+	return 0;
+}
+
+static int ep_poll_readyevents_proc(void *priv, void *cookie, int call_nests)
+{
+	return ep_scan_ready_list(priv, ep_read_events_proc, NULL);
+}
+
 static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait)
 {
-	unsigned int pollflags = 0;
-	unsigned long flags;
+	int pollflags;
 	struct eventpoll *ep = file->private_data;
 
 	/* Insert inside our poll wait queue */
 	poll_wait(file, &ep->poll_wait, wait);
 
-	/* Check our condition */
-	spin_lock_irqsave(&ep->lock, flags);
-	if (!list_empty(&ep->rdllist))
-		pollflags = POLLIN | POLLRDNORM;
-	spin_unlock_irqrestore(&ep->lock, flags);
+	/*
+	 * Proceed to find out if wanted events are really available inside
+	 * the ready list. This need to be done under ep_call_nested()
+	 * supervision, since the call to f_op->poll() done on listed files
+	 * could re-enter here.
+	 */
+	pollflags = ep_call_nested(&poll_readywalk_ncalls, EP_MAX_NESTS,
+				   ep_poll_readyevents_proc, ep, ep);
 
-	return pollflags;
+	return pollflags != -1 ? pollflags : 0;
 }
 
 /* File callbacks that implement the eventpoll file behaviour */
@@ -541,7 +695,7 @@
 	 * We don't want to get "file->f_lock" because it is not
 	 * necessary. It is not necessary because we're in the "struct file"
 	 * cleanup path, and this means that noone is using this file anymore.
-	 * So, for example, epoll_ctl() cannot hit here sicne if we reach this
+	 * So, for example, epoll_ctl() cannot hit here since if we reach this
 	 * point, the file counter already went to zero and fget() would fail.
 	 * The only hit might come from ep_free() but by holding the mutex
 	 * will correctly serialize the operation. We do need to acquire
@@ -588,8 +742,6 @@
 
 	*pep = ep;
 
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_alloc() ep=%p\n",
-		     current, ep));
 	return 0;
 
 free_uid:
@@ -623,9 +775,6 @@
 		}
 	}
 
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_find(%p) -> %p\n",
-		     current, file, epir));
-
 	return epir;
 }
 
@@ -641,9 +790,6 @@
 	struct epitem *epi = ep_item_from_wait(wait);
 	struct eventpoll *ep = epi->ep;
 
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: poll_callback(%p) epi=%p ep=%p\n",
-		     current, epi->ffd.file, epi, ep));
-
 	spin_lock_irqsave(&ep->lock, flags);
 
 	/*
@@ -656,6 +802,15 @@
 		goto out_unlock;
 
 	/*
+	 * Check the events coming with the callback. At this stage, not
+	 * every device reports the events in the "key" parameter of the
+	 * callback. We need to be able to handle both cases here, hence the
+	 * test for "key" != NULL before the event match test.
+	 */
+	if (key && !((unsigned long) key & epi->event.events))
+		goto out_unlock;
+
+	/*
 	 * If we are trasfering events to userspace, we can hold no locks
 	 * (because we're accessing user memory, and because of linux f_op->poll()
 	 * semantics). All the events that happens during that period of time are
@@ -670,12 +825,9 @@
 	}
 
 	/* If this file is already in the ready list we exit soon */
-	if (ep_is_linked(&epi->rdllink))
-		goto is_linked;
+	if (!ep_is_linked(&epi->rdllink))
+		list_add_tail(&epi->rdllink, &ep->rdllist);
 
-	list_add_tail(&epi->rdllink, &ep->rdllist);
-
-is_linked:
 	/*
 	 * Wake up ( if active ) both the eventpoll wait list and the ->poll()
 	 * wait list.
@@ -690,7 +842,7 @@
 
 	/* We have to call this outside the lock */
 	if (pwake)
-		ep_poll_safewake(&psw, &ep->poll_wait);
+		ep_poll_safewake(&ep->poll_wait);
 
 	return 1;
 }
@@ -817,10 +969,7 @@
 
 	/* We have to call this outside the lock */
 	if (pwake)
-		ep_poll_safewake(&psw, &ep->poll_wait);
-
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: ep_insert(%p, %p, %d)\n",
-		     current, ep, tfile, fd));
+		ep_poll_safewake(&ep->poll_wait);
 
 	return 0;
 
@@ -851,15 +1000,14 @@
 {
 	int pwake = 0;
 	unsigned int revents;
-	unsigned long flags;
 
 	/*
-	 * Set the new event interest mask before calling f_op->poll(), otherwise
-	 * a potential race might occur. In fact if we do this operation inside
-	 * the lock, an event might happen between the f_op->poll() call and the
-	 * new event set registering.
+	 * Set the new event interest mask before calling f_op->poll();
+	 * otherwise we might miss an event that happens between the
+	 * f_op->poll() call and the new event set registering.
 	 */
 	epi->event.events = event->events;
+	epi->event.data = event->data; /* protected by mtx */
 
 	/*
 	 * Get current event bits. We can safely use the file* here because
@@ -867,16 +1015,12 @@
 	 */
 	revents = epi->ffd.file->f_op->poll(epi->ffd.file, NULL);
 
-	spin_lock_irqsave(&ep->lock, flags);
-
-	/* Copy the data member from inside the lock */
-	epi->event.data = event->data;
-
 	/*
 	 * If the item is "hot" and it is not registered inside the ready
 	 * list, push it inside.
 	 */
 	if (revents & event->events) {
+		spin_lock_irq(&ep->lock);
 		if (!ep_is_linked(&epi->rdllink)) {
 			list_add_tail(&epi->rdllink, &ep->rdllist);
 
@@ -886,142 +1030,84 @@
 			if (waitqueue_active(&ep->poll_wait))
 				pwake++;
 		}
+		spin_unlock_irq(&ep->lock);
 	}
-	spin_unlock_irqrestore(&ep->lock, flags);
 
 	/* We have to call this outside the lock */
 	if (pwake)
-		ep_poll_safewake(&psw, &ep->poll_wait);
+		ep_poll_safewake(&ep->poll_wait);
 
 	return 0;
 }
 
-static int ep_send_events(struct eventpoll *ep, struct epoll_event __user *events,
-			  int maxevents)
+static int ep_send_events_proc(struct eventpoll *ep, struct list_head *head,
+			       void *priv)
 {
-	int eventcnt, error = -EFAULT, pwake = 0;
+	struct ep_send_events_data *esed = priv;
+	int eventcnt;
 	unsigned int revents;
-	unsigned long flags;
-	struct epitem *epi, *nepi;
-	struct list_head txlist;
-
-	INIT_LIST_HEAD(&txlist);
+	struct epitem *epi;
+	struct epoll_event __user *uevent;
 
 	/*
-	 * We need to lock this because we could be hit by
-	 * eventpoll_release_file() and epoll_ctl(EPOLL_CTL_DEL).
+	 * We can loop without lock because we are passed a task private list.
+	 * Items cannot vanish during the loop because ep_scan_ready_list() is
+	 * holding "mtx" during this call.
 	 */
-	mutex_lock(&ep->mtx);
-
-	/*
-	 * Steal the ready list, and re-init the original one to the
-	 * empty list. Also, set ep->ovflist to NULL so that events
-	 * happening while looping w/out locks, are not lost. We cannot
-	 * have the poll callback to queue directly on ep->rdllist,
-	 * because we are doing it in the loop below, in a lockless way.
-	 */
-	spin_lock_irqsave(&ep->lock, flags);
-	list_splice(&ep->rdllist, &txlist);
-	INIT_LIST_HEAD(&ep->rdllist);
-	ep->ovflist = NULL;
-	spin_unlock_irqrestore(&ep->lock, flags);
-
-	/*
-	 * We can loop without lock because this is a task private list.
-	 * We just splice'd out the ep->rdllist in ep_collect_ready_items().
-	 * Items cannot vanish during the loop because we are holding "mtx".
-	 */
-	for (eventcnt = 0; !list_empty(&txlist) && eventcnt < maxevents;) {
-		epi = list_first_entry(&txlist, struct epitem, rdllink);
+	for (eventcnt = 0, uevent = esed->events;
+	     !list_empty(head) && eventcnt < esed->maxevents;) {
+		epi = list_first_entry(head, struct epitem, rdllink);
 
 		list_del_init(&epi->rdllink);
 
-		/*
-		 * Get the ready file event set. We can safely use the file
-		 * because we are holding the "mtx" and this will guarantee
-		 * that both the file and the item will not vanish.
-		 */
-		revents = epi->ffd.file->f_op->poll(epi->ffd.file, NULL);
-		revents &= epi->event.events;
+		revents = epi->ffd.file->f_op->poll(epi->ffd.file, NULL) &
+			epi->event.events;
 
 		/*
-		 * Is the event mask intersect the caller-requested one,
-		 * deliver the event to userspace. Again, we are holding
-		 * "mtx", so no operations coming from userspace can change
-		 * the item.
+		 * If the event mask intersect the caller-requested one,
+		 * deliver the event to userspace. Again, ep_scan_ready_list()
+		 * is holding "mtx", so no operations coming from userspace
+		 * can change the item.
 		 */
 		if (revents) {
-			if (__put_user(revents,
-				       &events[eventcnt].events) ||
-			    __put_user(epi->event.data,
-				       &events[eventcnt].data))
-				goto errxit;
+			if (__put_user(revents, &uevent->events) ||
+			    __put_user(epi->event.data, &uevent->data)) {
+				list_add(&epi->rdllink, head);
+				return eventcnt ? eventcnt : -EFAULT;
+			}
+			eventcnt++;
+			uevent++;
 			if (epi->event.events & EPOLLONESHOT)
 				epi->event.events &= EP_PRIVATE_BITS;
-			eventcnt++;
+			else if (!(epi->event.events & EPOLLET)) {
+				/*
+				 * If this file has been added with Level
+				 * Trigger mode, we need to insert back inside
+				 * the ready list, so that the next call to
+				 * epoll_wait() will check again the events
+				 * availability. At this point, noone can insert
+				 * into ep->rdllist besides us. The epoll_ctl()
+				 * callers are locked out by
+				 * ep_scan_ready_list() holding "mtx" and the
+				 * poll callback will queue them in ep->ovflist.
+				 */
+				list_add_tail(&epi->rdllink, &ep->rdllist);
+			}
 		}
-		/*
-		 * At this point, noone can insert into ep->rdllist besides
-		 * us. The epoll_ctl() callers are locked out by us holding
-		 * "mtx" and the poll callback will queue them in ep->ovflist.
-		 */
-		if (!(epi->event.events & EPOLLET) &&
-		    (revents & epi->event.events))
-			list_add_tail(&epi->rdllink, &ep->rdllist);
 	}
-	error = 0;
 
-errxit:
+	return eventcnt;
+}
 
-	spin_lock_irqsave(&ep->lock, flags);
-	/*
-	 * During the time we spent in the loop above, some other events
-	 * might have been queued by the poll callback. We re-insert them
-	 * inside the main ready-list here.
-	 */
-	for (nepi = ep->ovflist; (epi = nepi) != NULL;
-	     nepi = epi->next, epi->next = EP_UNACTIVE_PTR) {
-		/*
-		 * If the above loop quit with errors, the epoll item might still
-		 * be linked to "txlist", and the list_splice() done below will
-		 * take care of those cases.
-		 */
-		if (!ep_is_linked(&epi->rdllink))
-			list_add_tail(&epi->rdllink, &ep->rdllist);
-	}
-	/*
-	 * We need to set back ep->ovflist to EP_UNACTIVE_PTR, so that after
-	 * releasing the lock, events will be queued in the normal way inside
-	 * ep->rdllist.
-	 */
-	ep->ovflist = EP_UNACTIVE_PTR;
+static int ep_send_events(struct eventpoll *ep,
+			  struct epoll_event __user *events, int maxevents)
+{
+	struct ep_send_events_data esed;
 
-	/*
-	 * In case of error in the event-send loop, or in case the number of
-	 * ready events exceeds the userspace limit, we need to splice the
-	 * "txlist" back inside ep->rdllist.
-	 */
-	list_splice(&txlist, &ep->rdllist);
+	esed.maxevents = maxevents;
+	esed.events = events;
 
-	if (!list_empty(&ep->rdllist)) {
-		/*
-		 * Wake up (if active) both the eventpoll wait list and the ->poll()
-		 * wait list (delayed after we release the lock).
-		 */
-		if (waitqueue_active(&ep->wq))
-			wake_up_locked(&ep->wq);
-		if (waitqueue_active(&ep->poll_wait))
-			pwake++;
-	}
-	spin_unlock_irqrestore(&ep->lock, flags);
-
-	mutex_unlock(&ep->mtx);
-
-	/* We have to call this outside the lock */
-	if (pwake)
-		ep_poll_safewake(&psw, &ep->poll_wait);
-
-	return eventcnt == 0 ? error: eventcnt;
+	return ep_scan_ready_list(ep, ep_send_events_proc, &esed);
 }
 
 static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
@@ -1033,7 +1119,7 @@
 	wait_queue_t wait;
 
 	/*
-	 * Calculate the timeout by checking for the "infinite" value ( -1 )
+	 * Calculate the timeout by checking for the "infinite" value (-1)
 	 * and the overflow condition. The passed timeout is in milliseconds,
 	 * that why (t * HZ) / 1000.
 	 */
@@ -1076,9 +1162,8 @@
 
 		set_current_state(TASK_RUNNING);
 	}
-
 	/* Is it worth to try to dig for events ? */
-	eavail = !list_empty(&ep->rdllist);
+	eavail = !list_empty(&ep->rdllist) || ep->ovflist != EP_UNACTIVE_PTR;
 
 	spin_unlock_irqrestore(&ep->lock, flags);
 
@@ -1099,41 +1184,30 @@
  */
 SYSCALL_DEFINE1(epoll_create1, int, flags)
 {
-	int error, fd = -1;
-	struct eventpoll *ep;
+	int error;
+	struct eventpoll *ep = NULL;
 
 	/* Check the EPOLL_* constant for consistency.  */
 	BUILD_BUG_ON(EPOLL_CLOEXEC != O_CLOEXEC);
 
 	if (flags & ~EPOLL_CLOEXEC)
 		return -EINVAL;
-
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d)\n",
-		     current, flags));
-
 	/*
-	 * Create the internal data structure ( "struct eventpoll" ).
+	 * Create the internal data structure ("struct eventpoll").
 	 */
 	error = ep_alloc(&ep);
-	if (error < 0) {
-		fd = error;
-		goto error_return;
-	}
-
+	if (error < 0)
+		return error;
 	/*
 	 * Creates all the items needed to setup an eventpoll file. That is,
 	 * a file structure and a free file descriptor.
 	 */
-	fd = anon_inode_getfd("[eventpoll]", &eventpoll_fops, ep,
-			      flags & O_CLOEXEC);
-	if (fd < 0)
+	error = anon_inode_getfd("[eventpoll]", &eventpoll_fops, ep,
+				 flags & O_CLOEXEC);
+	if (error < 0)
 		ep_free(ep);
 
-error_return:
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n",
-		     current, flags, fd));
-
-	return fd;
+	return error;
 }
 
 SYSCALL_DEFINE1(epoll_create, int, size)
@@ -1158,9 +1232,6 @@
 	struct epitem *epi;
 	struct epoll_event epds;
 
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %p)\n",
-		     current, epfd, op, fd, event));
-
 	error = -EFAULT;
 	if (ep_op_has_event(op) &&
 	    copy_from_user(&epds, event, sizeof(struct epoll_event)))
@@ -1211,7 +1282,6 @@
 	case EPOLL_CTL_ADD:
 		if (!epi) {
 			epds.events |= POLLERR | POLLHUP;
-
 			error = ep_insert(ep, &epds, tfile, fd);
 		} else
 			error = -EEXIST;
@@ -1237,8 +1307,6 @@
 error_fput:
 	fput(file);
 error_return:
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_ctl(%d, %d, %d, %p) = %d\n",
-		     current, epfd, op, fd, event, error));
 
 	return error;
 }
@@ -1254,9 +1322,6 @@
 	struct file *file;
 	struct eventpoll *ep;
 
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_wait(%d, %p, %d, %d)\n",
-		     current, epfd, events, maxevents, timeout));
-
 	/* The maximum number of event must be greater than zero */
 	if (maxevents <= 0 || maxevents > EP_MAX_EVENTS)
 		return -EINVAL;
@@ -1293,8 +1358,6 @@
 error_fput:
 	fput(file);
 error_return:
-	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_wait(%d, %p, %d, %d) = %d\n",
-		     current, epfd, events, maxevents, timeout, error));
 
 	return error;
 }
@@ -1359,17 +1422,18 @@
 		EP_ITEM_COST;
 
 	/* Initialize the structure used to perform safe poll wait head wake ups */
-	ep_poll_safewake_init(&psw);
+	ep_nested_calls_init(&poll_safewake_ncalls);
+
+	/* Initialize the structure used to perform file's f_op->poll() calls */
+	ep_nested_calls_init(&poll_readywalk_ncalls);
 
 	/* Allocates slab cache used to allocate "struct epitem" items */
 	epi_cache = kmem_cache_create("eventpoll_epi", sizeof(struct epitem),
-			0, SLAB_HWCACHE_ALIGN|EPI_SLAB_DEBUG|SLAB_PANIC,
-			NULL);
+			0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
 
 	/* Allocates slab cache used to allocate "struct eppoll_entry" */
 	pwq_cache = kmem_cache_create("eventpoll_pwq",
-			sizeof(struct eppoll_entry), 0,
-			EPI_SLAB_DEBUG|SLAB_PANIC, NULL);
+			sizeof(struct eppoll_entry), 0, SLAB_PANIC, NULL);
 
 	return 0;
 }
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 6083bb38..990c940 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1098,7 +1098,7 @@
 extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks);
 extern int ext4_block_truncate_page(handle_t *handle,
 		struct address_space *mapping, loff_t from);
-extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page);
+extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
 extern qsize_t ext4_get_reserved_space(struct inode *inode);
 
 /* ioctl.c */
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 71d3ecd..dd82ff3 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -5146,8 +5146,9 @@
 	return !buffer_mapped(bh);
 }
 
-int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page)
+int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
+	struct page *page = vmf->page;
 	loff_t size;
 	unsigned long len;
 	int ret = -EINVAL;
@@ -5199,6 +5200,8 @@
 		goto out_unlock;
 	ret = 0;
 out_unlock:
+	if (ret)
+		ret = VM_FAULT_SIGBUS;
 	up_read(&inode->i_alloc_sem);
 	return ret;
 }
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 821d10f..4e340fe 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1234,8 +1234,9 @@
  * - sync(2)
  * - try_to_free_pages() with order > PAGE_ALLOC_COSTLY_ORDER
  */
-static int fuse_page_mkwrite(struct vm_area_struct *vma, struct page *page)
+static int fuse_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
+	struct page *page = vmf->page;
 	/*
 	 * Don't use page->mapping as it may become NULL from a
 	 * concurrent truncate.
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index 3b9e8de..70b9b85 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -337,8 +337,9 @@
  * blocks allocated on disk to back that page.
  */
 
-static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page)
+static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
+	struct page *page = vmf->page;
 	struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
 	struct gfs2_inode *ip = GFS2_I(inode);
 	struct gfs2_sbd *sdp = GFS2_SB(inode);
@@ -412,6 +413,8 @@
 	gfs2_glock_dq(&gh);
 out:
 	gfs2_holder_uninit(&gh);
+	if (ret)
+		ret = VM_FAULT_SIGBUS;
 	return ret;
 }
 
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 9b800d9..23a3c76 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -943,14 +943,13 @@
 
 static int can_do_hugetlb_shm(void)
 {
-	return likely(capable(CAP_IPC_LOCK) ||
-			in_group_p(sysctl_hugetlb_shm_group) ||
-			can_do_mlock());
+	return capable(CAP_IPC_LOCK) || in_group_p(sysctl_hugetlb_shm_group);
 }
 
 struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag)
 {
 	int error = -ENOMEM;
+	int unlock_shm = 0;
 	struct file *file;
 	struct inode *inode;
 	struct dentry *dentry, *root;
@@ -960,11 +959,14 @@
 	if (!hugetlbfs_vfsmount)
 		return ERR_PTR(-ENOENT);
 
-	if (!can_do_hugetlb_shm())
-		return ERR_PTR(-EPERM);
-
-	if (!user_shm_lock(size, user))
-		return ERR_PTR(-ENOMEM);
+	if (!can_do_hugetlb_shm()) {
+		if (user_shm_lock(size, user)) {
+			unlock_shm = 1;
+			WARN_ONCE(1,
+			  "Using mlock ulimits for SHM_HUGETLB deprecated\n");
+		} else
+			return ERR_PTR(-EPERM);
+	}
 
 	root = hugetlbfs_vfsmount->mnt_root;
 	quick_string.name = name;
@@ -1004,7 +1006,8 @@
 out_dentry:
 	dput(dentry);
 out_shm_unlock:
-	user_shm_unlock(size, user);
+	if (unlock_shm)
+		user_shm_unlock(size, user);
 	return ERR_PTR(error);
 }
 
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 90f292b..cec7939 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -451,8 +451,9 @@
 	.launder_page = nfs_launder_page,
 };
 
-static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page)
+static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
+	struct page *page = vmf->page;
 	struct file *filp = vma->vm_file;
 	struct dentry *dentry = filp->f_path.dentry;
 	unsigned pagelen;
@@ -483,6 +484,8 @@
 		ret = pagelen;
 out_unlock:
 	unlock_page(page);
+	if (ret)
+		ret = VM_FAULT_SIGBUS;
 	return ret;
 }
 
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c
index 34314b3..5a9e344 100644
--- a/fs/ntfs/dir.c
+++ b/fs/ntfs/dir.c
@@ -32,8 +32,8 @@
 /**
  * The little endian Unicode string $I30 as a global constant.
  */
-ntfschar I30[5] = { const_cpu_to_le16('$'), const_cpu_to_le16('I'),
-		const_cpu_to_le16('3'),	const_cpu_to_le16('0'), 0 };
+ntfschar I30[5] = { cpu_to_le16('$'), cpu_to_le16('I'),
+		cpu_to_le16('3'),	cpu_to_le16('0'), 0 };
 
 /**
  * ntfs_lookup_inode_by_name - find an inode in a directory given its name
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 86bef15..82c5085 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -1975,8 +1975,7 @@
 				goto em_put_err_out;
 			next_al_entry = (ATTR_LIST_ENTRY*)((u8*)al_entry +
 					le16_to_cpu(al_entry->length));
-			if (le32_to_cpu(al_entry->type) >
-					const_le32_to_cpu(AT_DATA))
+			if (le32_to_cpu(al_entry->type) > le32_to_cpu(AT_DATA))
 				goto em_put_err_out;
 			if (AT_DATA != al_entry->type)
 				continue;
diff --git a/fs/ntfs/layout.h b/fs/ntfs/layout.h
index 1e38332..50931b1 100644
--- a/fs/ntfs/layout.h
+++ b/fs/ntfs/layout.h
@@ -31,19 +31,8 @@
 
 #include "types.h"
 
-/*
- * Constant endianness conversion defines.
- */
-#define const_le16_to_cpu(x)	__constant_le16_to_cpu(x)
-#define const_le32_to_cpu(x)	__constant_le32_to_cpu(x)
-#define const_le64_to_cpu(x)	__constant_le64_to_cpu(x)
-
-#define const_cpu_to_le16(x)	__constant_cpu_to_le16(x)
-#define const_cpu_to_le32(x)	__constant_cpu_to_le32(x)
-#define const_cpu_to_le64(x)	__constant_cpu_to_le64(x)
-
 /* The NTFS oem_id "NTFS    " */
-#define magicNTFS	const_cpu_to_le64(0x202020205346544eULL)
+#define magicNTFS	cpu_to_le64(0x202020205346544eULL)
 
 /*
  * Location of bootsector on partition:
@@ -114,25 +103,25 @@
  */
 enum {
 	/* Found in $MFT/$DATA. */
-	magic_FILE = const_cpu_to_le32(0x454c4946), /* Mft entry. */
-	magic_INDX = const_cpu_to_le32(0x58444e49), /* Index buffer. */
-	magic_HOLE = const_cpu_to_le32(0x454c4f48), /* ? (NTFS 3.0+?) */
+	magic_FILE = cpu_to_le32(0x454c4946), /* Mft entry. */
+	magic_INDX = cpu_to_le32(0x58444e49), /* Index buffer. */
+	magic_HOLE = cpu_to_le32(0x454c4f48), /* ? (NTFS 3.0+?) */
 
 	/* Found in $LogFile/$DATA. */
-	magic_RSTR = const_cpu_to_le32(0x52545352), /* Restart page. */
-	magic_RCRD = const_cpu_to_le32(0x44524352), /* Log record page. */
+	magic_RSTR = cpu_to_le32(0x52545352), /* Restart page. */
+	magic_RCRD = cpu_to_le32(0x44524352), /* Log record page. */
 
 	/* Found in $LogFile/$DATA.  (May be found in $MFT/$DATA, also?) */
-	magic_CHKD = const_cpu_to_le32(0x444b4843), /* Modified by chkdsk. */
+	magic_CHKD = cpu_to_le32(0x444b4843), /* Modified by chkdsk. */
 
 	/* Found in all ntfs record containing records. */
-	magic_BAAD = const_cpu_to_le32(0x44414142), /* Failed multi sector
+	magic_BAAD = cpu_to_le32(0x44414142), /* Failed multi sector
 						       transfer was detected. */
 	/*
 	 * Found in $LogFile/$DATA when a page is full of 0xff bytes and is
 	 * thus not initialized.  Page must be initialized before using it.
 	 */
-	magic_empty = const_cpu_to_le32(0xffffffff) /* Record is empty. */
+	magic_empty = cpu_to_le32(0xffffffff) /* Record is empty. */
 };
 
 typedef le32 NTFS_RECORD_TYPE;
@@ -258,8 +247,8 @@
  * information about the mft record in which they are present.
  */
 enum {
-	MFT_RECORD_IN_USE	= const_cpu_to_le16(0x0001),
-	MFT_RECORD_IS_DIRECTORY = const_cpu_to_le16(0x0002),
+	MFT_RECORD_IN_USE	= cpu_to_le16(0x0001),
+	MFT_RECORD_IS_DIRECTORY = cpu_to_le16(0x0002),
 } __attribute__ ((__packed__));
 
 typedef le16 MFT_RECORD_FLAGS;
@@ -309,7 +298,7 @@
  * Note: The _LE versions will return a CPU endian formatted value!
  */
 #define MFT_REF_MASK_CPU 0x0000ffffffffffffULL
-#define MFT_REF_MASK_LE const_cpu_to_le64(MFT_REF_MASK_CPU)
+#define MFT_REF_MASK_LE cpu_to_le64(MFT_REF_MASK_CPU)
 
 typedef u64 MFT_REF;
 typedef le64 leMFT_REF;
@@ -477,25 +466,25 @@
  * a revealing choice of symbol I do not know what is... (-;
  */
 enum {
-	AT_UNUSED			= const_cpu_to_le32(         0),
-	AT_STANDARD_INFORMATION		= const_cpu_to_le32(      0x10),
-	AT_ATTRIBUTE_LIST		= const_cpu_to_le32(      0x20),
-	AT_FILE_NAME			= const_cpu_to_le32(      0x30),
-	AT_OBJECT_ID			= const_cpu_to_le32(      0x40),
-	AT_SECURITY_DESCRIPTOR		= const_cpu_to_le32(      0x50),
-	AT_VOLUME_NAME			= const_cpu_to_le32(      0x60),
-	AT_VOLUME_INFORMATION		= const_cpu_to_le32(      0x70),
-	AT_DATA				= const_cpu_to_le32(      0x80),
-	AT_INDEX_ROOT			= const_cpu_to_le32(      0x90),
-	AT_INDEX_ALLOCATION		= const_cpu_to_le32(      0xa0),
-	AT_BITMAP			= const_cpu_to_le32(      0xb0),
-	AT_REPARSE_POINT		= const_cpu_to_le32(      0xc0),
-	AT_EA_INFORMATION		= const_cpu_to_le32(      0xd0),
-	AT_EA				= const_cpu_to_le32(      0xe0),
-	AT_PROPERTY_SET			= const_cpu_to_le32(      0xf0),
-	AT_LOGGED_UTILITY_STREAM	= const_cpu_to_le32(     0x100),
-	AT_FIRST_USER_DEFINED_ATTRIBUTE	= const_cpu_to_le32(    0x1000),
-	AT_END				= const_cpu_to_le32(0xffffffff)
+	AT_UNUSED			= cpu_to_le32(         0),
+	AT_STANDARD_INFORMATION		= cpu_to_le32(      0x10),
+	AT_ATTRIBUTE_LIST		= cpu_to_le32(      0x20),
+	AT_FILE_NAME			= cpu_to_le32(      0x30),
+	AT_OBJECT_ID			= cpu_to_le32(      0x40),
+	AT_SECURITY_DESCRIPTOR		= cpu_to_le32(      0x50),
+	AT_VOLUME_NAME			= cpu_to_le32(      0x60),
+	AT_VOLUME_INFORMATION		= cpu_to_le32(      0x70),
+	AT_DATA				= cpu_to_le32(      0x80),
+	AT_INDEX_ROOT			= cpu_to_le32(      0x90),
+	AT_INDEX_ALLOCATION		= cpu_to_le32(      0xa0),
+	AT_BITMAP			= cpu_to_le32(      0xb0),
+	AT_REPARSE_POINT		= cpu_to_le32(      0xc0),
+	AT_EA_INFORMATION		= cpu_to_le32(      0xd0),
+	AT_EA				= cpu_to_le32(      0xe0),
+	AT_PROPERTY_SET			= cpu_to_le32(      0xf0),
+	AT_LOGGED_UTILITY_STREAM	= cpu_to_le32(     0x100),
+	AT_FIRST_USER_DEFINED_ATTRIBUTE	= cpu_to_le32(    0x1000),
+	AT_END				= cpu_to_le32(0xffffffff)
 };
 
 typedef le32 ATTR_TYPE;
@@ -539,13 +528,13 @@
  *	equal then the second le32 values would be compared, etc.
  */
 enum {
-	COLLATION_BINARY		= const_cpu_to_le32(0x00),
-	COLLATION_FILE_NAME		= const_cpu_to_le32(0x01),
-	COLLATION_UNICODE_STRING	= const_cpu_to_le32(0x02),
-	COLLATION_NTOFS_ULONG		= const_cpu_to_le32(0x10),
-	COLLATION_NTOFS_SID		= const_cpu_to_le32(0x11),
-	COLLATION_NTOFS_SECURITY_HASH	= const_cpu_to_le32(0x12),
-	COLLATION_NTOFS_ULONGS		= const_cpu_to_le32(0x13),
+	COLLATION_BINARY		= cpu_to_le32(0x00),
+	COLLATION_FILE_NAME		= cpu_to_le32(0x01),
+	COLLATION_UNICODE_STRING	= cpu_to_le32(0x02),
+	COLLATION_NTOFS_ULONG		= cpu_to_le32(0x10),
+	COLLATION_NTOFS_SID		= cpu_to_le32(0x11),
+	COLLATION_NTOFS_SECURITY_HASH	= cpu_to_le32(0x12),
+	COLLATION_NTOFS_ULONGS		= cpu_to_le32(0x13),
 };
 
 typedef le32 COLLATION_RULE;
@@ -559,25 +548,25 @@
  * NT4.
  */
 enum {
-	ATTR_DEF_INDEXABLE	= const_cpu_to_le32(0x02), /* Attribute can be
+	ATTR_DEF_INDEXABLE	= cpu_to_le32(0x02), /* Attribute can be
 					indexed. */
-	ATTR_DEF_MULTIPLE	= const_cpu_to_le32(0x04), /* Attribute type
+	ATTR_DEF_MULTIPLE	= cpu_to_le32(0x04), /* Attribute type
 					can be present multiple times in the
 					mft records of an inode. */
-	ATTR_DEF_NOT_ZERO	= const_cpu_to_le32(0x08), /* Attribute value
+	ATTR_DEF_NOT_ZERO	= cpu_to_le32(0x08), /* Attribute value
 					must contain at least one non-zero
 					byte. */
-	ATTR_DEF_INDEXED_UNIQUE	= const_cpu_to_le32(0x10), /* Attribute must be
+	ATTR_DEF_INDEXED_UNIQUE	= cpu_to_le32(0x10), /* Attribute must be
 					indexed and the attribute value must be
 					unique for the attribute type in all of
 					the mft records of an inode. */
-	ATTR_DEF_NAMED_UNIQUE	= const_cpu_to_le32(0x20), /* Attribute must be
+	ATTR_DEF_NAMED_UNIQUE	= cpu_to_le32(0x20), /* Attribute must be
 					named and the name must be unique for
 					the attribute type in all of the mft
 					records of an inode. */
-	ATTR_DEF_RESIDENT	= const_cpu_to_le32(0x40), /* Attribute must be
+	ATTR_DEF_RESIDENT	= cpu_to_le32(0x40), /* Attribute must be
 					resident. */
-	ATTR_DEF_ALWAYS_LOG	= const_cpu_to_le32(0x80), /* Always log
+	ATTR_DEF_ALWAYS_LOG	= cpu_to_le32(0x80), /* Always log
 					modifications to this attribute,
 					regardless of whether it is resident or
 					non-resident.  Without this, only log
@@ -614,12 +603,12 @@
  * Attribute flags (16-bit).
  */
 enum {
-	ATTR_IS_COMPRESSED    = const_cpu_to_le16(0x0001),
-	ATTR_COMPRESSION_MASK = const_cpu_to_le16(0x00ff), /* Compression method
+	ATTR_IS_COMPRESSED    = cpu_to_le16(0x0001),
+	ATTR_COMPRESSION_MASK = cpu_to_le16(0x00ff), /* Compression method
 							      mask.  Also, first
 							      illegal value. */
-	ATTR_IS_ENCRYPTED     = const_cpu_to_le16(0x4000),
-	ATTR_IS_SPARSE	      = const_cpu_to_le16(0x8000),
+	ATTR_IS_ENCRYPTED     = cpu_to_le16(0x4000),
+	ATTR_IS_SPARSE	      = cpu_to_le16(0x8000),
 } __attribute__ ((__packed__));
 
 typedef le16 ATTR_FLAGS;
@@ -811,32 +800,32 @@
  * flags appear in all of the above.
  */
 enum {
-	FILE_ATTR_READONLY		= const_cpu_to_le32(0x00000001),
-	FILE_ATTR_HIDDEN		= const_cpu_to_le32(0x00000002),
-	FILE_ATTR_SYSTEM		= const_cpu_to_le32(0x00000004),
-	/* Old DOS volid. Unused in NT.	= const_cpu_to_le32(0x00000008), */
+	FILE_ATTR_READONLY		= cpu_to_le32(0x00000001),
+	FILE_ATTR_HIDDEN		= cpu_to_le32(0x00000002),
+	FILE_ATTR_SYSTEM		= cpu_to_le32(0x00000004),
+	/* Old DOS volid. Unused in NT.	= cpu_to_le32(0x00000008), */
 
-	FILE_ATTR_DIRECTORY		= const_cpu_to_le32(0x00000010),
+	FILE_ATTR_DIRECTORY		= cpu_to_le32(0x00000010),
 	/* Note, FILE_ATTR_DIRECTORY is not considered valid in NT.  It is
 	   reserved for the DOS SUBDIRECTORY flag. */
-	FILE_ATTR_ARCHIVE		= const_cpu_to_le32(0x00000020),
-	FILE_ATTR_DEVICE		= const_cpu_to_le32(0x00000040),
-	FILE_ATTR_NORMAL		= const_cpu_to_le32(0x00000080),
+	FILE_ATTR_ARCHIVE		= cpu_to_le32(0x00000020),
+	FILE_ATTR_DEVICE		= cpu_to_le32(0x00000040),
+	FILE_ATTR_NORMAL		= cpu_to_le32(0x00000080),
 
-	FILE_ATTR_TEMPORARY		= const_cpu_to_le32(0x00000100),
-	FILE_ATTR_SPARSE_FILE		= const_cpu_to_le32(0x00000200),
-	FILE_ATTR_REPARSE_POINT		= const_cpu_to_le32(0x00000400),
-	FILE_ATTR_COMPRESSED		= const_cpu_to_le32(0x00000800),
+	FILE_ATTR_TEMPORARY		= cpu_to_le32(0x00000100),
+	FILE_ATTR_SPARSE_FILE		= cpu_to_le32(0x00000200),
+	FILE_ATTR_REPARSE_POINT		= cpu_to_le32(0x00000400),
+	FILE_ATTR_COMPRESSED		= cpu_to_le32(0x00000800),
 
-	FILE_ATTR_OFFLINE		= const_cpu_to_le32(0x00001000),
-	FILE_ATTR_NOT_CONTENT_INDEXED	= const_cpu_to_le32(0x00002000),
-	FILE_ATTR_ENCRYPTED		= const_cpu_to_le32(0x00004000),
+	FILE_ATTR_OFFLINE		= cpu_to_le32(0x00001000),
+	FILE_ATTR_NOT_CONTENT_INDEXED	= cpu_to_le32(0x00002000),
+	FILE_ATTR_ENCRYPTED		= cpu_to_le32(0x00004000),
 
-	FILE_ATTR_VALID_FLAGS		= const_cpu_to_le32(0x00007fb7),
+	FILE_ATTR_VALID_FLAGS		= cpu_to_le32(0x00007fb7),
 	/* Note, FILE_ATTR_VALID_FLAGS masks out the old DOS VolId and the
 	   FILE_ATTR_DEVICE and preserves everything else.  This mask is used
 	   to obtain all flags that are valid for reading. */
-	FILE_ATTR_VALID_SET_FLAGS	= const_cpu_to_le32(0x000031a7),
+	FILE_ATTR_VALID_SET_FLAGS	= cpu_to_le32(0x000031a7),
 	/* Note, FILE_ATTR_VALID_SET_FLAGS masks out the old DOS VolId, the
 	   F_A_DEVICE, F_A_DIRECTORY, F_A_SPARSE_FILE, F_A_REPARSE_POINT,
 	   F_A_COMPRESSED, and F_A_ENCRYPTED and preserves the rest.  This mask
@@ -846,11 +835,11 @@
 	 * FILENAME_ATTR attributes but not in the STANDARD_INFORMATION
 	 * attribute of an mft record.
 	 */
-	FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT	= const_cpu_to_le32(0x10000000),
+	FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT	= cpu_to_le32(0x10000000),
 	/* Note, this is a copy of the corresponding bit from the mft record,
 	   telling us whether this is a directory or not, i.e. whether it has
 	   an index root attribute or not. */
-	FILE_ATTR_DUP_VIEW_INDEX_PRESENT	= const_cpu_to_le32(0x20000000),
+	FILE_ATTR_DUP_VIEW_INDEX_PRESENT	= cpu_to_le32(0x20000000),
 	/* Note, this is a copy of the corresponding bit from the mft record,
 	   telling us whether this file has a view index present (eg. object id
 	   index, quota index, one of the security indexes or the encrypting
@@ -1446,42 +1435,42 @@
 	/* Specific rights for files and directories are as follows: */
 
 	/* Right to read data from the file. (FILE) */
-	FILE_READ_DATA			= const_cpu_to_le32(0x00000001),
+	FILE_READ_DATA			= cpu_to_le32(0x00000001),
 	/* Right to list contents of a directory. (DIRECTORY) */
-	FILE_LIST_DIRECTORY		= const_cpu_to_le32(0x00000001),
+	FILE_LIST_DIRECTORY		= cpu_to_le32(0x00000001),
 
 	/* Right to write data to the file. (FILE) */
-	FILE_WRITE_DATA			= const_cpu_to_le32(0x00000002),
+	FILE_WRITE_DATA			= cpu_to_le32(0x00000002),
 	/* Right to create a file in the directory. (DIRECTORY) */
-	FILE_ADD_FILE			= const_cpu_to_le32(0x00000002),
+	FILE_ADD_FILE			= cpu_to_le32(0x00000002),
 
 	/* Right to append data to the file. (FILE) */
-	FILE_APPEND_DATA		= const_cpu_to_le32(0x00000004),
+	FILE_APPEND_DATA		= cpu_to_le32(0x00000004),
 	/* Right to create a subdirectory. (DIRECTORY) */
-	FILE_ADD_SUBDIRECTORY		= const_cpu_to_le32(0x00000004),
+	FILE_ADD_SUBDIRECTORY		= cpu_to_le32(0x00000004),
 
 	/* Right to read extended attributes. (FILE/DIRECTORY) */
-	FILE_READ_EA			= const_cpu_to_le32(0x00000008),
+	FILE_READ_EA			= cpu_to_le32(0x00000008),
 
 	/* Right to write extended attributes. (FILE/DIRECTORY) */
-	FILE_WRITE_EA			= const_cpu_to_le32(0x00000010),
+	FILE_WRITE_EA			= cpu_to_le32(0x00000010),
 
 	/* Right to execute a file. (FILE) */
-	FILE_EXECUTE			= const_cpu_to_le32(0x00000020),
+	FILE_EXECUTE			= cpu_to_le32(0x00000020),
 	/* Right to traverse the directory. (DIRECTORY) */
-	FILE_TRAVERSE			= const_cpu_to_le32(0x00000020),
+	FILE_TRAVERSE			= cpu_to_le32(0x00000020),
 
 	/*
 	 * Right to delete a directory and all the files it contains (its
 	 * children), even if the files are read-only. (DIRECTORY)
 	 */
-	FILE_DELETE_CHILD		= const_cpu_to_le32(0x00000040),
+	FILE_DELETE_CHILD		= cpu_to_le32(0x00000040),
 
 	/* Right to read file attributes. (FILE/DIRECTORY) */
-	FILE_READ_ATTRIBUTES		= const_cpu_to_le32(0x00000080),
+	FILE_READ_ATTRIBUTES		= cpu_to_le32(0x00000080),
 
 	/* Right to change file attributes. (FILE/DIRECTORY) */
-	FILE_WRITE_ATTRIBUTES		= const_cpu_to_le32(0x00000100),
+	FILE_WRITE_ATTRIBUTES		= cpu_to_le32(0x00000100),
 
 	/*
 	 * The standard rights (bits 16 to 23).  These are independent of the
@@ -1489,27 +1478,27 @@
 	 */
 
 	/* Right to delete the object. */
-	DELETE				= const_cpu_to_le32(0x00010000),
+	DELETE				= cpu_to_le32(0x00010000),
 
 	/*
 	 * Right to read the information in the object's security descriptor,
 	 * not including the information in the SACL, i.e. right to read the
 	 * security descriptor and owner.
 	 */
-	READ_CONTROL			= const_cpu_to_le32(0x00020000),
+	READ_CONTROL			= cpu_to_le32(0x00020000),
 
 	/* Right to modify the DACL in the object's security descriptor. */
-	WRITE_DAC			= const_cpu_to_le32(0x00040000),
+	WRITE_DAC			= cpu_to_le32(0x00040000),
 
 	/* Right to change the owner in the object's security descriptor. */
-	WRITE_OWNER			= const_cpu_to_le32(0x00080000),
+	WRITE_OWNER			= cpu_to_le32(0x00080000),
 
 	/*
 	 * Right to use the object for synchronization.  Enables a process to
 	 * wait until the object is in the signalled state.  Some object types
 	 * do not support this access right.
 	 */
-	SYNCHRONIZE			= const_cpu_to_le32(0x00100000),
+	SYNCHRONIZE			= cpu_to_le32(0x00100000),
 
 	/*
 	 * The following STANDARD_RIGHTS_* are combinations of the above for
@@ -1517,25 +1506,25 @@
 	 */
 
 	/* These are currently defined to READ_CONTROL. */
-	STANDARD_RIGHTS_READ		= const_cpu_to_le32(0x00020000),
-	STANDARD_RIGHTS_WRITE		= const_cpu_to_le32(0x00020000),
-	STANDARD_RIGHTS_EXECUTE		= const_cpu_to_le32(0x00020000),
+	STANDARD_RIGHTS_READ		= cpu_to_le32(0x00020000),
+	STANDARD_RIGHTS_WRITE		= cpu_to_le32(0x00020000),
+	STANDARD_RIGHTS_EXECUTE		= cpu_to_le32(0x00020000),
 
 	/* Combines DELETE, READ_CONTROL, WRITE_DAC, and WRITE_OWNER access. */
-	STANDARD_RIGHTS_REQUIRED	= const_cpu_to_le32(0x000f0000),
+	STANDARD_RIGHTS_REQUIRED	= cpu_to_le32(0x000f0000),
 
 	/*
 	 * Combines DELETE, READ_CONTROL, WRITE_DAC, WRITE_OWNER, and
 	 * SYNCHRONIZE access.
 	 */
-	STANDARD_RIGHTS_ALL		= const_cpu_to_le32(0x001f0000),
+	STANDARD_RIGHTS_ALL		= cpu_to_le32(0x001f0000),
 
 	/*
 	 * The access system ACL and maximum allowed access types (bits 24 to
 	 * 25, bits 26 to 27 are reserved).
 	 */
-	ACCESS_SYSTEM_SECURITY		= const_cpu_to_le32(0x01000000),
-	MAXIMUM_ALLOWED			= const_cpu_to_le32(0x02000000),
+	ACCESS_SYSTEM_SECURITY		= cpu_to_le32(0x01000000),
+	MAXIMUM_ALLOWED			= cpu_to_le32(0x02000000),
 
 	/*
 	 * The generic rights (bits 28 to 31).  These map onto the standard and
@@ -1543,10 +1532,10 @@
 	 */
 
 	/* Read, write, and execute access. */
-	GENERIC_ALL			= const_cpu_to_le32(0x10000000),
+	GENERIC_ALL			= cpu_to_le32(0x10000000),
 
 	/* Execute access. */
-	GENERIC_EXECUTE			= const_cpu_to_le32(0x20000000),
+	GENERIC_EXECUTE			= cpu_to_le32(0x20000000),
 
 	/*
 	 * Write access.  For files, this maps onto:
@@ -1555,7 +1544,7 @@
 	 * For directories, the mapping has the same numerical value.  See
 	 * above for the descriptions of the rights granted.
 	 */
-	GENERIC_WRITE			= const_cpu_to_le32(0x40000000),
+	GENERIC_WRITE			= cpu_to_le32(0x40000000),
 
 	/*
 	 * Read access.  For files, this maps onto:
@@ -1564,7 +1553,7 @@
 	 * For directories, the mapping has the same numberical value.  See
 	 * above for the descriptions of the rights granted.
 	 */
-	GENERIC_READ			= const_cpu_to_le32(0x80000000),
+	GENERIC_READ			= cpu_to_le32(0x80000000),
 };
 
 typedef le32 ACCESS_MASK;
@@ -1604,8 +1593,8 @@
  * The object ACE flags (32-bit).
  */
 enum {
-	ACE_OBJECT_TYPE_PRESENT			= const_cpu_to_le32(1),
-	ACE_INHERITED_OBJECT_TYPE_PRESENT	= const_cpu_to_le32(2),
+	ACE_OBJECT_TYPE_PRESENT			= cpu_to_le32(1),
+	ACE_INHERITED_OBJECT_TYPE_PRESENT	= cpu_to_le32(2),
 };
 
 typedef le32 OBJECT_ACE_FLAGS;
@@ -1706,23 +1695,23 @@
  *	expressed as offsets from the beginning of the security descriptor.
  */
 enum {
-	SE_OWNER_DEFAULTED		= const_cpu_to_le16(0x0001),
-	SE_GROUP_DEFAULTED		= const_cpu_to_le16(0x0002),
-	SE_DACL_PRESENT			= const_cpu_to_le16(0x0004),
-	SE_DACL_DEFAULTED		= const_cpu_to_le16(0x0008),
+	SE_OWNER_DEFAULTED		= cpu_to_le16(0x0001),
+	SE_GROUP_DEFAULTED		= cpu_to_le16(0x0002),
+	SE_DACL_PRESENT			= cpu_to_le16(0x0004),
+	SE_DACL_DEFAULTED		= cpu_to_le16(0x0008),
 
-	SE_SACL_PRESENT			= const_cpu_to_le16(0x0010),
-	SE_SACL_DEFAULTED		= const_cpu_to_le16(0x0020),
+	SE_SACL_PRESENT			= cpu_to_le16(0x0010),
+	SE_SACL_DEFAULTED		= cpu_to_le16(0x0020),
 
-	SE_DACL_AUTO_INHERIT_REQ	= const_cpu_to_le16(0x0100),
-	SE_SACL_AUTO_INHERIT_REQ	= const_cpu_to_le16(0x0200),
-	SE_DACL_AUTO_INHERITED		= const_cpu_to_le16(0x0400),
-	SE_SACL_AUTO_INHERITED		= const_cpu_to_le16(0x0800),
+	SE_DACL_AUTO_INHERIT_REQ	= cpu_to_le16(0x0100),
+	SE_SACL_AUTO_INHERIT_REQ	= cpu_to_le16(0x0200),
+	SE_DACL_AUTO_INHERITED		= cpu_to_le16(0x0400),
+	SE_SACL_AUTO_INHERITED		= cpu_to_le16(0x0800),
 
-	SE_DACL_PROTECTED		= const_cpu_to_le16(0x1000),
-	SE_SACL_PROTECTED		= const_cpu_to_le16(0x2000),
-	SE_RM_CONTROL_VALID		= const_cpu_to_le16(0x4000),
-	SE_SELF_RELATIVE		= const_cpu_to_le16(0x8000)
+	SE_DACL_PROTECTED		= cpu_to_le16(0x1000),
+	SE_SACL_PROTECTED		= cpu_to_le16(0x2000),
+	SE_RM_CONTROL_VALID		= cpu_to_le16(0x4000),
+	SE_SELF_RELATIVE		= cpu_to_le16(0x8000)
 } __attribute__ ((__packed__));
 
 typedef le16 SECURITY_DESCRIPTOR_CONTROL;
@@ -1910,21 +1899,21 @@
  * Possible flags for the volume (16-bit).
  */
 enum {
-	VOLUME_IS_DIRTY			= const_cpu_to_le16(0x0001),
-	VOLUME_RESIZE_LOG_FILE		= const_cpu_to_le16(0x0002),
-	VOLUME_UPGRADE_ON_MOUNT		= const_cpu_to_le16(0x0004),
-	VOLUME_MOUNTED_ON_NT4		= const_cpu_to_le16(0x0008),
+	VOLUME_IS_DIRTY			= cpu_to_le16(0x0001),
+	VOLUME_RESIZE_LOG_FILE		= cpu_to_le16(0x0002),
+	VOLUME_UPGRADE_ON_MOUNT		= cpu_to_le16(0x0004),
+	VOLUME_MOUNTED_ON_NT4		= cpu_to_le16(0x0008),
 
-	VOLUME_DELETE_USN_UNDERWAY	= const_cpu_to_le16(0x0010),
-	VOLUME_REPAIR_OBJECT_ID		= const_cpu_to_le16(0x0020),
+	VOLUME_DELETE_USN_UNDERWAY	= cpu_to_le16(0x0010),
+	VOLUME_REPAIR_OBJECT_ID		= cpu_to_le16(0x0020),
 
-	VOLUME_CHKDSK_UNDERWAY		= const_cpu_to_le16(0x4000),
-	VOLUME_MODIFIED_BY_CHKDSK	= const_cpu_to_le16(0x8000),
+	VOLUME_CHKDSK_UNDERWAY		= cpu_to_le16(0x4000),
+	VOLUME_MODIFIED_BY_CHKDSK	= cpu_to_le16(0x8000),
 
-	VOLUME_FLAGS_MASK		= const_cpu_to_le16(0xc03f),
+	VOLUME_FLAGS_MASK		= cpu_to_le16(0xc03f),
 
 	/* To make our life easier when checking if we must mount read-only. */
-	VOLUME_MUST_MOUNT_RO_MASK	= const_cpu_to_le16(0xc027),
+	VOLUME_MUST_MOUNT_RO_MASK	= cpu_to_le16(0xc027),
 } __attribute__ ((__packed__));
 
 typedef le16 VOLUME_FLAGS;
@@ -2109,26 +2098,26 @@
  * The user quota flags.  Names explain meaning.
  */
 enum {
-	QUOTA_FLAG_DEFAULT_LIMITS	= const_cpu_to_le32(0x00000001),
-	QUOTA_FLAG_LIMIT_REACHED	= const_cpu_to_le32(0x00000002),
-	QUOTA_FLAG_ID_DELETED		= const_cpu_to_le32(0x00000004),
+	QUOTA_FLAG_DEFAULT_LIMITS	= cpu_to_le32(0x00000001),
+	QUOTA_FLAG_LIMIT_REACHED	= cpu_to_le32(0x00000002),
+	QUOTA_FLAG_ID_DELETED		= cpu_to_le32(0x00000004),
 
-	QUOTA_FLAG_USER_MASK		= const_cpu_to_le32(0x00000007),
+	QUOTA_FLAG_USER_MASK		= cpu_to_le32(0x00000007),
 	/* This is a bit mask for the user quota flags. */
 
 	/*
 	 * These flags are only present in the quota defaults index entry, i.e.
 	 * in the entry where owner_id = QUOTA_DEFAULTS_ID.
 	 */
-	QUOTA_FLAG_TRACKING_ENABLED	= const_cpu_to_le32(0x00000010),
-	QUOTA_FLAG_ENFORCEMENT_ENABLED	= const_cpu_to_le32(0x00000020),
-	QUOTA_FLAG_TRACKING_REQUESTED	= const_cpu_to_le32(0x00000040),
-	QUOTA_FLAG_LOG_THRESHOLD	= const_cpu_to_le32(0x00000080),
+	QUOTA_FLAG_TRACKING_ENABLED	= cpu_to_le32(0x00000010),
+	QUOTA_FLAG_ENFORCEMENT_ENABLED	= cpu_to_le32(0x00000020),
+	QUOTA_FLAG_TRACKING_REQUESTED	= cpu_to_le32(0x00000040),
+	QUOTA_FLAG_LOG_THRESHOLD	= cpu_to_le32(0x00000080),
 
-	QUOTA_FLAG_LOG_LIMIT		= const_cpu_to_le32(0x00000100),
-	QUOTA_FLAG_OUT_OF_DATE		= const_cpu_to_le32(0x00000200),
-	QUOTA_FLAG_CORRUPT		= const_cpu_to_le32(0x00000400),
-	QUOTA_FLAG_PENDING_DELETES	= const_cpu_to_le32(0x00000800),
+	QUOTA_FLAG_LOG_LIMIT		= cpu_to_le32(0x00000100),
+	QUOTA_FLAG_OUT_OF_DATE		= cpu_to_le32(0x00000200),
+	QUOTA_FLAG_CORRUPT		= cpu_to_le32(0x00000400),
+	QUOTA_FLAG_PENDING_DELETES	= cpu_to_le32(0x00000800),
 };
 
 typedef le32 QUOTA_FLAGS;
@@ -2172,9 +2161,9 @@
  * Predefined owner_id values (32-bit).
  */
 enum {
-	QUOTA_INVALID_ID	= const_cpu_to_le32(0x00000000),
-	QUOTA_DEFAULTS_ID	= const_cpu_to_le32(0x00000001),
-	QUOTA_FIRST_USER_ID	= const_cpu_to_le32(0x00000100),
+	QUOTA_INVALID_ID	= cpu_to_le32(0x00000000),
+	QUOTA_DEFAULTS_ID	= cpu_to_le32(0x00000001),
+	QUOTA_FIRST_USER_ID	= cpu_to_le32(0x00000100),
 };
 
 /*
@@ -2189,14 +2178,14 @@
  * Index entry flags (16-bit).
  */
 enum {
-	INDEX_ENTRY_NODE = const_cpu_to_le16(1), /* This entry contains a
+	INDEX_ENTRY_NODE = cpu_to_le16(1), /* This entry contains a
 			sub-node, i.e. a reference to an index block in form of
 			a virtual cluster number (see below). */
-	INDEX_ENTRY_END  = const_cpu_to_le16(2), /* This signifies the last
+	INDEX_ENTRY_END  = cpu_to_le16(2), /* This signifies the last
 			entry in an index block.  The index entry does not
 			represent a file but it can point to a sub-node. */
 
-	INDEX_ENTRY_SPACE_FILLER = const_cpu_to_le16(0xffff), /* gcc: Force
+	INDEX_ENTRY_SPACE_FILLER = cpu_to_le16(0xffff), /* gcc: Force
 			enum bit width to 16-bit. */
 } __attribute__ ((__packed__));
 
@@ -2334,26 +2323,26 @@
  * These are the predefined reparse point tags:
  */
 enum {
-	IO_REPARSE_TAG_IS_ALIAS		= const_cpu_to_le32(0x20000000),
-	IO_REPARSE_TAG_IS_HIGH_LATENCY	= const_cpu_to_le32(0x40000000),
-	IO_REPARSE_TAG_IS_MICROSOFT	= const_cpu_to_le32(0x80000000),
+	IO_REPARSE_TAG_IS_ALIAS		= cpu_to_le32(0x20000000),
+	IO_REPARSE_TAG_IS_HIGH_LATENCY	= cpu_to_le32(0x40000000),
+	IO_REPARSE_TAG_IS_MICROSOFT	= cpu_to_le32(0x80000000),
 
-	IO_REPARSE_TAG_RESERVED_ZERO	= const_cpu_to_le32(0x00000000),
-	IO_REPARSE_TAG_RESERVED_ONE	= const_cpu_to_le32(0x00000001),
-	IO_REPARSE_TAG_RESERVED_RANGE	= const_cpu_to_le32(0x00000001),
+	IO_REPARSE_TAG_RESERVED_ZERO	= cpu_to_le32(0x00000000),
+	IO_REPARSE_TAG_RESERVED_ONE	= cpu_to_le32(0x00000001),
+	IO_REPARSE_TAG_RESERVED_RANGE	= cpu_to_le32(0x00000001),
 
-	IO_REPARSE_TAG_NSS		= const_cpu_to_le32(0x68000005),
-	IO_REPARSE_TAG_NSS_RECOVER	= const_cpu_to_le32(0x68000006),
-	IO_REPARSE_TAG_SIS		= const_cpu_to_le32(0x68000007),
-	IO_REPARSE_TAG_DFS		= const_cpu_to_le32(0x68000008),
+	IO_REPARSE_TAG_NSS		= cpu_to_le32(0x68000005),
+	IO_REPARSE_TAG_NSS_RECOVER	= cpu_to_le32(0x68000006),
+	IO_REPARSE_TAG_SIS		= cpu_to_le32(0x68000007),
+	IO_REPARSE_TAG_DFS		= cpu_to_le32(0x68000008),
 
-	IO_REPARSE_TAG_MOUNT_POINT	= const_cpu_to_le32(0x88000003),
+	IO_REPARSE_TAG_MOUNT_POINT	= cpu_to_le32(0x88000003),
 
-	IO_REPARSE_TAG_HSM		= const_cpu_to_le32(0xa8000004),
+	IO_REPARSE_TAG_HSM		= cpu_to_le32(0xa8000004),
 
-	IO_REPARSE_TAG_SYMBOLIC_LINK	= const_cpu_to_le32(0xe8000000),
+	IO_REPARSE_TAG_SYMBOLIC_LINK	= cpu_to_le32(0xe8000000),
 
-	IO_REPARSE_TAG_VALID_VALUES	= const_cpu_to_le32(0xe000ffff),
+	IO_REPARSE_TAG_VALID_VALUES	= cpu_to_le32(0xe000ffff),
 };
 
 /*
diff --git a/fs/ntfs/logfile.h b/fs/ntfs/logfile.h
index 9468e1c..b5a6f08 100644
--- a/fs/ntfs/logfile.h
+++ b/fs/ntfs/logfile.h
@@ -104,7 +104,7 @@
  * in this particular client array.  Also inside the client records themselves,
  * this means that there are no client records preceding or following this one.
  */
-#define LOGFILE_NO_CLIENT	const_cpu_to_le16(0xffff)
+#define LOGFILE_NO_CLIENT	cpu_to_le16(0xffff)
 #define LOGFILE_NO_CLIENT_CPU	0xffff
 
 /*
@@ -112,8 +112,8 @@
  * information about the log file in which they are present.
  */
 enum {
-	RESTART_VOLUME_IS_CLEAN	= const_cpu_to_le16(0x0002),
-	RESTART_SPACE_FILLER	= const_cpu_to_le16(0xffff), /* gcc: Force enum bit width to 16. */
+	RESTART_VOLUME_IS_CLEAN	= cpu_to_le16(0x0002),
+	RESTART_SPACE_FILLER	= cpu_to_le16(0xffff), /* gcc: Force enum bit width to 16. */
 } __attribute__ ((__packed__));
 
 typedef le16 RESTART_AREA_FLAGS;
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
index 17d32ca..23bf684 100644
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -2839,7 +2839,7 @@
 	 */
 
 	/* Mark the mft record as not in use. */
-	m->flags &= const_cpu_to_le16(~const_le16_to_cpu(MFT_RECORD_IN_USE));
+	m->flags &= ~MFT_RECORD_IN_USE;
 
 	/* Increment the sequence number, skipping zero, if it is not zero. */
 	old_seq_no = m->sequence_number;
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 4a46743..f76951d 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -618,7 +618,7 @@
 	 * many BIOSes will refuse to boot from a bootsector if the magic is
 	 * incorrect, so we emit a warning.
 	 */
-	if (!silent && b->end_of_sector_marker != const_cpu_to_le16(0xaa55))
+	if (!silent && b->end_of_sector_marker != cpu_to_le16(0xaa55))
 		ntfs_warning(sb, "Invalid end of sector marker.");
 	return true;
 not_ntfs:
@@ -1242,13 +1242,13 @@
 	u32 *kaddr, *kend;
 	ntfs_name *name = NULL;
 	int ret = 1;
-	static const ntfschar hiberfil[13] = { const_cpu_to_le16('h'),
-			const_cpu_to_le16('i'), const_cpu_to_le16('b'),
-			const_cpu_to_le16('e'), const_cpu_to_le16('r'),
-			const_cpu_to_le16('f'), const_cpu_to_le16('i'),
-			const_cpu_to_le16('l'), const_cpu_to_le16('.'),
-			const_cpu_to_le16('s'), const_cpu_to_le16('y'),
-			const_cpu_to_le16('s'), 0 };
+	static const ntfschar hiberfil[13] = { cpu_to_le16('h'),
+			cpu_to_le16('i'), cpu_to_le16('b'),
+			cpu_to_le16('e'), cpu_to_le16('r'),
+			cpu_to_le16('f'), cpu_to_le16('i'),
+			cpu_to_le16('l'), cpu_to_le16('.'),
+			cpu_to_le16('s'), cpu_to_le16('y'),
+			cpu_to_le16('s'), 0 };
 
 	ntfs_debug("Entering.");
 	/*
@@ -1296,7 +1296,7 @@
 		goto iput_out;
 	}
 	kaddr = (u32*)page_address(page);
-	if (*(le32*)kaddr == const_cpu_to_le32(0x72626968)/*'hibr'*/) {
+	if (*(le32*)kaddr == cpu_to_le32(0x72626968)/*'hibr'*/) {
 		ntfs_debug("Magic \"hibr\" found in hiberfil.sys.  Windows is "
 				"hibernated on the volume.  This is the "
 				"system volume.");
@@ -1337,12 +1337,12 @@
 	MFT_REF mref;
 	struct inode *tmp_ino;
 	ntfs_name *name = NULL;
-	static const ntfschar Quota[7] = { const_cpu_to_le16('$'),
-			const_cpu_to_le16('Q'), const_cpu_to_le16('u'),
-			const_cpu_to_le16('o'), const_cpu_to_le16('t'),
-			const_cpu_to_le16('a'), 0 };
-	static ntfschar Q[3] = { const_cpu_to_le16('$'),
-			const_cpu_to_le16('Q'), 0 };
+	static const ntfschar Quota[7] = { cpu_to_le16('$'),
+			cpu_to_le16('Q'), cpu_to_le16('u'),
+			cpu_to_le16('o'), cpu_to_le16('t'),
+			cpu_to_le16('a'), 0 };
+	static ntfschar Q[3] = { cpu_to_le16('$'),
+			cpu_to_le16('Q'), 0 };
 
 	ntfs_debug("Entering.");
 	/*
@@ -1416,16 +1416,16 @@
 	struct page *page;
 	ntfs_name *name = NULL;
 	USN_HEADER *uh;
-	static const ntfschar UsnJrnl[9] = { const_cpu_to_le16('$'),
-			const_cpu_to_le16('U'), const_cpu_to_le16('s'),
-			const_cpu_to_le16('n'), const_cpu_to_le16('J'),
-			const_cpu_to_le16('r'), const_cpu_to_le16('n'),
-			const_cpu_to_le16('l'), 0 };
-	static ntfschar Max[5] = { const_cpu_to_le16('$'),
-			const_cpu_to_le16('M'), const_cpu_to_le16('a'),
-			const_cpu_to_le16('x'), 0 };
-	static ntfschar J[3] = { const_cpu_to_le16('$'),
-			const_cpu_to_le16('J'), 0 };
+	static const ntfschar UsnJrnl[9] = { cpu_to_le16('$'),
+			cpu_to_le16('U'), cpu_to_le16('s'),
+			cpu_to_le16('n'), cpu_to_le16('J'),
+			cpu_to_le16('r'), cpu_to_le16('n'),
+			cpu_to_le16('l'), 0 };
+	static ntfschar Max[5] = { cpu_to_le16('$'),
+			cpu_to_le16('M'), cpu_to_le16('a'),
+			cpu_to_le16('x'), 0 };
+	static ntfschar J[3] = { cpu_to_le16('$'),
+			cpu_to_le16('J'), 0 };
 
 	ntfs_debug("Entering.");
 	/*
diff --git a/fs/ntfs/usnjrnl.h b/fs/ntfs/usnjrnl.h
index 4087fbd..00d8e6b 100644
--- a/fs/ntfs/usnjrnl.h
+++ b/fs/ntfs/usnjrnl.h
@@ -116,27 +116,27 @@
  * documentation: http://www.linux-ntfs.org/
  */
 enum {
-	USN_REASON_DATA_OVERWRITE	= const_cpu_to_le32(0x00000001),
-	USN_REASON_DATA_EXTEND		= const_cpu_to_le32(0x00000002),
-	USN_REASON_DATA_TRUNCATION	= const_cpu_to_le32(0x00000004),
-	USN_REASON_NAMED_DATA_OVERWRITE	= const_cpu_to_le32(0x00000010),
-	USN_REASON_NAMED_DATA_EXTEND	= const_cpu_to_le32(0x00000020),
-	USN_REASON_NAMED_DATA_TRUNCATION= const_cpu_to_le32(0x00000040),
-	USN_REASON_FILE_CREATE		= const_cpu_to_le32(0x00000100),
-	USN_REASON_FILE_DELETE		= const_cpu_to_le32(0x00000200),
-	USN_REASON_EA_CHANGE		= const_cpu_to_le32(0x00000400),
-	USN_REASON_SECURITY_CHANGE	= const_cpu_to_le32(0x00000800),
-	USN_REASON_RENAME_OLD_NAME	= const_cpu_to_le32(0x00001000),
-	USN_REASON_RENAME_NEW_NAME	= const_cpu_to_le32(0x00002000),
-	USN_REASON_INDEXABLE_CHANGE	= const_cpu_to_le32(0x00004000),
-	USN_REASON_BASIC_INFO_CHANGE	= const_cpu_to_le32(0x00008000),
-	USN_REASON_HARD_LINK_CHANGE	= const_cpu_to_le32(0x00010000),
-	USN_REASON_COMPRESSION_CHANGE	= const_cpu_to_le32(0x00020000),
-	USN_REASON_ENCRYPTION_CHANGE	= const_cpu_to_le32(0x00040000),
-	USN_REASON_OBJECT_ID_CHANGE	= const_cpu_to_le32(0x00080000),
-	USN_REASON_REPARSE_POINT_CHANGE	= const_cpu_to_le32(0x00100000),
-	USN_REASON_STREAM_CHANGE	= const_cpu_to_le32(0x00200000),
-	USN_REASON_CLOSE		= const_cpu_to_le32(0x80000000),
+	USN_REASON_DATA_OVERWRITE	= cpu_to_le32(0x00000001),
+	USN_REASON_DATA_EXTEND		= cpu_to_le32(0x00000002),
+	USN_REASON_DATA_TRUNCATION	= cpu_to_le32(0x00000004),
+	USN_REASON_NAMED_DATA_OVERWRITE	= cpu_to_le32(0x00000010),
+	USN_REASON_NAMED_DATA_EXTEND	= cpu_to_le32(0x00000020),
+	USN_REASON_NAMED_DATA_TRUNCATION= cpu_to_le32(0x00000040),
+	USN_REASON_FILE_CREATE		= cpu_to_le32(0x00000100),
+	USN_REASON_FILE_DELETE		= cpu_to_le32(0x00000200),
+	USN_REASON_EA_CHANGE		= cpu_to_le32(0x00000400),
+	USN_REASON_SECURITY_CHANGE	= cpu_to_le32(0x00000800),
+	USN_REASON_RENAME_OLD_NAME	= cpu_to_le32(0x00001000),
+	USN_REASON_RENAME_NEW_NAME	= cpu_to_le32(0x00002000),
+	USN_REASON_INDEXABLE_CHANGE	= cpu_to_le32(0x00004000),
+	USN_REASON_BASIC_INFO_CHANGE	= cpu_to_le32(0x00008000),
+	USN_REASON_HARD_LINK_CHANGE	= cpu_to_le32(0x00010000),
+	USN_REASON_COMPRESSION_CHANGE	= cpu_to_le32(0x00020000),
+	USN_REASON_ENCRYPTION_CHANGE	= cpu_to_le32(0x00040000),
+	USN_REASON_OBJECT_ID_CHANGE	= cpu_to_le32(0x00080000),
+	USN_REASON_REPARSE_POINT_CHANGE	= cpu_to_le32(0x00100000),
+	USN_REASON_STREAM_CHANGE	= cpu_to_le32(0x00200000),
+	USN_REASON_CLOSE		= cpu_to_le32(0x80000000),
 };
 
 typedef le32 USN_REASON_FLAGS;
@@ -148,9 +148,9 @@
  *	http://www.linux-ntfs.org/
  */
 enum {
-	USN_SOURCE_DATA_MANAGEMENT	  = const_cpu_to_le32(0x00000001),
-	USN_SOURCE_AUXILIARY_DATA	  = const_cpu_to_le32(0x00000002),
-	USN_SOURCE_REPLICATION_MANAGEMENT = const_cpu_to_le32(0x00000004),
+	USN_SOURCE_DATA_MANAGEMENT	  = cpu_to_le32(0x00000001),
+	USN_SOURCE_AUXILIARY_DATA	  = cpu_to_le32(0x00000002),
+	USN_SOURCE_REPLICATION_MANAGEMENT = cpu_to_le32(0x00000004),
 };
 
 typedef le32 USN_SOURCE_INFO_FLAGS;
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c
index eea1d24..b606496 100644
--- a/fs/ocfs2/mmap.c
+++ b/fs/ocfs2/mmap.c
@@ -154,8 +154,9 @@
 	return ret;
 }
 
-static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page)
+static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
+	struct page *page = vmf->page;
 	struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
 	struct buffer_head *di_bh = NULL;
 	sigset_t blocked, oldset;
@@ -196,7 +197,8 @@
 	ret2 = ocfs2_vm_op_unblock_sigs(&oldset);
 	if (ret2 < 0)
 		mlog_errno(ret2);
-
+	if (ret)
+		ret = VM_FAULT_SIGBUS;
 	return ret;
 }
 
diff --git a/fs/proc/proc_tty.c b/fs/proc/proc_tty.c
index 4a9e0f6..83adcc8 100644
--- a/fs/proc/proc_tty.c
+++ b/fs/proc/proc_tty.c
@@ -144,16 +144,12 @@
 {
 	struct proc_dir_entry *ent;
 		
-	if (!driver->ops->read_proc || !driver->driver_name ||
-	    driver->proc_entry)
+	if (!driver->driver_name || driver->proc_entry ||
+	    !driver->ops->proc_fops)
 		return;
 
-	ent = create_proc_entry(driver->driver_name, 0, proc_tty_driver);
-	if (!ent)
-		return;
-	ent->read_proc = driver->ops->read_proc;
-	ent->data = driver;
-
+	ent = proc_create_data(driver->driver_name, 0, proc_tty_driver,
+			       driver->ops->proc_fops, driver);
 	driver->proc_entry = ent;
 }
 
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c
index 995ef1d..ebb2c41 100644
--- a/fs/ramfs/file-nommu.c
+++ b/fs/ramfs/file-nommu.c
@@ -59,7 +59,6 @@
  */
 int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
 {
-	struct pagevec lru_pvec;
 	unsigned long npages, xpages, loop, limit;
 	struct page *pages;
 	unsigned order;
@@ -102,24 +101,20 @@
 	memset(data, 0, newsize);
 
 	/* attach all the pages to the inode's address space */
-	pagevec_init(&lru_pvec, 0);
 	for (loop = 0; loop < npages; loop++) {
 		struct page *page = pages + loop;
 
-		ret = add_to_page_cache(page, inode->i_mapping, loop, GFP_KERNEL);
+		ret = add_to_page_cache_lru(page, inode->i_mapping, loop,
+					GFP_KERNEL);
 		if (ret < 0)
 			goto add_error;
 
-		if (!pagevec_add(&lru_pvec, page))
-			__pagevec_lru_add_file(&lru_pvec);
-
 		/* prevent the page from being discarded on memory pressure */
 		SetPageDirty(page);
 
 		unlock_page(page);
 	}
 
-	pagevec_lru_add_file(&lru_pvec);
 	return 0;
 
  fsize_exceeded:
@@ -128,10 +123,8 @@
 	return -EFBIG;
 
  add_error:
-	pagevec_lru_add_file(&lru_pvec);
-	page_cache_release(pages + loop);
-	for (loop++; loop < npages; loop++)
-		__free_page(pages + loop);
+	while (loop < npages)
+		__free_page(pages + loop++);
 	return ret;
 }
 
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index b7e6ac7..a404fb8 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -33,12 +33,15 @@
 #include <linux/backing-dev.h>
 #include <linux/ramfs.h>
 #include <linux/sched.h>
+#include <linux/parser.h>
 #include <asm/uaccess.h>
 #include "internal.h"
 
 /* some random number */
 #define RAMFS_MAGIC	0x858458f6
 
+#define RAMFS_DEFAULT_MODE	0755
+
 static const struct super_operations ramfs_ops;
 static const struct inode_operations ramfs_dir_inode_operations;
 
@@ -158,12 +161,75 @@
 static const struct super_operations ramfs_ops = {
 	.statfs		= simple_statfs,
 	.drop_inode	= generic_delete_inode,
+	.show_options	= generic_show_options,
 };
 
+struct ramfs_mount_opts {
+	umode_t mode;
+};
+
+enum {
+	Opt_mode,
+	Opt_err
+};
+
+static const match_table_t tokens = {
+	{Opt_mode, "mode=%o"},
+	{Opt_err, NULL}
+};
+
+struct ramfs_fs_info {
+	struct ramfs_mount_opts mount_opts;
+};
+
+static int ramfs_parse_options(char *data, struct ramfs_mount_opts *opts)
+{
+	substring_t args[MAX_OPT_ARGS];
+	int option;
+	int token;
+	char *p;
+
+	opts->mode = RAMFS_DEFAULT_MODE;
+
+	while ((p = strsep(&data, ",")) != NULL) {
+		if (!*p)
+			continue;
+
+		token = match_token(p, tokens, args);
+		switch (token) {
+		case Opt_mode:
+			if (match_octal(&args[0], &option))
+				return -EINVAL;
+			opts->mode = option & S_IALLUGO;
+			break;
+		default:
+			printk(KERN_ERR "ramfs: bad mount option: %s\n", p);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
 static int ramfs_fill_super(struct super_block * sb, void * data, int silent)
 {
-	struct inode * inode;
-	struct dentry * root;
+	struct ramfs_fs_info *fsi;
+	struct inode *inode = NULL;
+	struct dentry *root;
+	int err;
+
+	save_mount_options(sb, data);
+
+	fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL);
+	if (!fsi) {
+		err = -ENOMEM;
+		goto fail;
+	}
+	sb->s_fs_info = fsi;
+
+	err = ramfs_parse_options(data, &fsi->mount_opts);
+	if (err)
+		goto fail;
 
 	sb->s_maxbytes = MAX_LFS_FILESIZE;
 	sb->s_blocksize = PAGE_CACHE_SIZE;
@@ -171,17 +237,23 @@
 	sb->s_magic = RAMFS_MAGIC;
 	sb->s_op = &ramfs_ops;
 	sb->s_time_gran = 1;
-	inode = ramfs_get_inode(sb, S_IFDIR | 0755, 0);
-	if (!inode)
-		return -ENOMEM;
+	inode = ramfs_get_inode(sb, S_IFDIR | fsi->mount_opts.mode, 0);
+	if (!inode) {
+		err = -ENOMEM;
+		goto fail;
+	}
 
 	root = d_alloc_root(inode);
 	if (!root) {
-		iput(inode);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto fail;
 	}
 	sb->s_root = root;
 	return 0;
+fail:
+	kfree(fsi);
+	iput(inode);
+	return err;
 }
 
 int ramfs_get_sb(struct file_system_type *fs_type,
@@ -197,10 +269,16 @@
 			    mnt);
 }
 
+static void ramfs_kill_sb(struct super_block *sb)
+{
+	kfree(sb->s_fs_info);
+	kill_litter_super(sb);
+}
+
 static struct file_system_type ramfs_fs_type = {
 	.name		= "ramfs",
 	.get_sb		= ramfs_get_sb,
-	.kill_sb	= kill_litter_super,
+	.kill_sb	= ramfs_kill_sb,
 };
 static struct file_system_type rootfs_fs_type = {
 	.name		= "rootfs",
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index 07703d3..93e0c02 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -234,7 +234,7 @@
 	return ret;
 }
 
-static int bin_page_mkwrite(struct vm_area_struct *vma, struct page *page)
+static int bin_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
 	struct file *file = vma->vm_file;
 	struct bin_buffer *bb = file->private_data;
@@ -242,15 +242,15 @@
 	int ret;
 
 	if (!bb->vm_ops)
-		return -EINVAL;
+		return VM_FAULT_SIGBUS;
 
 	if (!bb->vm_ops->page_mkwrite)
 		return 0;
 
 	if (!sysfs_get_active_two(attr_sd))
-		return -EINVAL;
+		return VM_FAULT_SIGBUS;
 
-	ret = bb->vm_ops->page_mkwrite(vma, page);
+	ret = bb->vm_ops->page_mkwrite(vma, vmf);
 
 	sysfs_put_active_two(attr_sd);
 	return ret;
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 93b6de5..0ff89fe 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1434,8 +1434,9 @@
  * mmap()d file has taken write protection fault and is being made
  * writable. UBIFS must ensure page is budgeted for.
  */
-static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page)
+static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
+	struct page *page = vmf->page;
 	struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
 	struct ubifs_info *c = inode->i_sb->s_fs_info;
 	struct timespec now = ubifs_current_time(inode);
@@ -1447,7 +1448,7 @@
 	ubifs_assert(!(inode->i_sb->s_flags & MS_RDONLY));
 
 	if (unlikely(c->ro_media))
-		return -EROFS;
+		return VM_FAULT_SIGBUS; /* -EROFS */
 
 	/*
 	 * We have not locked @page so far so we may budget for changing the
@@ -1480,7 +1481,7 @@
 		if (err == -ENOSPC)
 			ubifs_warn("out of space for mmapped file "
 				   "(inode number %lu)", inode->i_ino);
-		return err;
+		return VM_FAULT_SIGBUS;
 	}
 
 	lock_page(page);
@@ -1520,6 +1521,8 @@
 out_unlock:
 	unlock_page(page);
 	ubifs_release_budget(c, &req);
+	if (err)
+		err = VM_FAULT_SIGBUS;
 	return err;
 }
 
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index e14c4e3..f4e2554 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -234,9 +234,9 @@
 STATIC int
 xfs_vm_page_mkwrite(
 	struct vm_area_struct	*vma,
-	struct page		*page)
+	struct vm_fault		*vmf)
 {
-	return block_page_mkwrite(vma, page, xfs_get_blocks);
+	return block_page_mkwrite(vma, vmf, xfs_get_blocks);
 }
 
 const struct file_operations xfs_file_operations = {
diff --git a/include/asm-frv/highmem.h b/include/asm-frv/highmem.h
index 26cefcd..68e4677 100644
--- a/include/asm-frv/highmem.h
+++ b/include/asm-frv/highmem.h
@@ -18,6 +18,7 @@
 #ifdef __KERNEL__
 
 #include <linux/init.h>
+#include <linux/highmem.h>
 #include <asm/mem-layout.h>
 #include <asm/spr-regs.h>
 #include <asm/mb-regs.h>
@@ -116,6 +117,7 @@
 	unsigned long paddr;
 
 	pagefault_disable();
+	debug_kmap_atomic(type);
 	paddr = page_to_phys(page);
 
 	switch (type) {
diff --git a/include/asm-generic/dma-mapping.h b/include/asm-generic/dma-mapping.h
deleted file mode 100644
index 189486c..0000000
--- a/include/asm-generic/dma-mapping.h
+++ /dev/null
@@ -1,308 +0,0 @@
-/* Copyright (C) 2002 by James.Bottomley@HansenPartnership.com 
- *
- * Implements the generic device dma API via the existing pci_ one
- * for unconverted architectures
- */
-
-#ifndef _ASM_GENERIC_DMA_MAPPING_H
-#define _ASM_GENERIC_DMA_MAPPING_H
-
-
-#ifdef CONFIG_PCI
-
-/* we implement the API below in terms of the existing PCI one,
- * so include it */
-#include <linux/pci.h>
-/* need struct page definitions */
-#include <linux/mm.h>
-
-static inline int
-dma_supported(struct device *dev, u64 mask)
-{
-	BUG_ON(dev->bus != &pci_bus_type);
-
-	return pci_dma_supported(to_pci_dev(dev), mask);
-}
-
-static inline int
-dma_set_mask(struct device *dev, u64 dma_mask)
-{
-	BUG_ON(dev->bus != &pci_bus_type);
-
-	return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
-}
-
-static inline void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
-		   gfp_t flag)
-{
-	BUG_ON(dev->bus != &pci_bus_type);
-
-	return pci_alloc_consistent(to_pci_dev(dev), size, dma_handle);
-}
-
-static inline void
-dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
-		    dma_addr_t dma_handle)
-{
-	BUG_ON(dev->bus != &pci_bus_type);
-
-	pci_free_consistent(to_pci_dev(dev), size, cpu_addr, dma_handle);
-}
-
-static inline dma_addr_t
-dma_map_single(struct device *dev, void *cpu_addr, size_t size,
-	       enum dma_data_direction direction)
-{
-	BUG_ON(dev->bus != &pci_bus_type);
-
-	return pci_map_single(to_pci_dev(dev), cpu_addr, size, (int)direction);
-}
-
-static inline void
-dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-		 enum dma_data_direction direction)
-{
-	BUG_ON(dev->bus != &pci_bus_type);
-
-	pci_unmap_single(to_pci_dev(dev), dma_addr, size, (int)direction);
-}
-
-static inline dma_addr_t
-dma_map_page(struct device *dev, struct page *page,
-	     unsigned long offset, size_t size,
-	     enum dma_data_direction direction)
-{
-	BUG_ON(dev->bus != &pci_bus_type);
-
-	return pci_map_page(to_pci_dev(dev), page, offset, size, (int)direction);
-}
-
-static inline void
-dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
-	       enum dma_data_direction direction)
-{
-	BUG_ON(dev->bus != &pci_bus_type);
-
-	pci_unmap_page(to_pci_dev(dev), dma_address, size, (int)direction);
-}
-
-static inline int
-dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-	   enum dma_data_direction direction)
-{
-	BUG_ON(dev->bus != &pci_bus_type);
-
-	return pci_map_sg(to_pci_dev(dev), sg, nents, (int)direction);
-}
-
-static inline void
-dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
-	     enum dma_data_direction direction)
-{
-	BUG_ON(dev->bus != &pci_bus_type);
-
-	pci_unmap_sg(to_pci_dev(dev), sg, nhwentries, (int)direction);
-}
-
-static inline void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
-			enum dma_data_direction direction)
-{
-	BUG_ON(dev->bus != &pci_bus_type);
-
-	pci_dma_sync_single_for_cpu(to_pci_dev(dev), dma_handle,
-				    size, (int)direction);
-}
-
-static inline void
-dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
-			   enum dma_data_direction direction)
-{
-	BUG_ON(dev->bus != &pci_bus_type);
-
-	pci_dma_sync_single_for_device(to_pci_dev(dev), dma_handle,
-				       size, (int)direction);
-}
-
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
-		    enum dma_data_direction direction)
-{
-	BUG_ON(dev->bus != &pci_bus_type);
-
-	pci_dma_sync_sg_for_cpu(to_pci_dev(dev), sg, nelems, (int)direction);
-}
-
-static inline void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
-		       enum dma_data_direction direction)
-{
-	BUG_ON(dev->bus != &pci_bus_type);
-
-	pci_dma_sync_sg_for_device(to_pci_dev(dev), sg, nelems, (int)direction);
-}
-
-static inline int
-dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
-	return pci_dma_mapping_error(to_pci_dev(dev), dma_addr);
-}
-
-
-#else
-
-static inline int
-dma_supported(struct device *dev, u64 mask)
-{
-	return 0;
-}
-
-static inline int
-dma_set_mask(struct device *dev, u64 dma_mask)
-{
-	BUG();
-	return 0;
-}
-
-static inline void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
-		   gfp_t flag)
-{
-	BUG();
-	return NULL;
-}
-
-static inline void
-dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
-		    dma_addr_t dma_handle)
-{
-	BUG();
-}
-
-static inline dma_addr_t
-dma_map_single(struct device *dev, void *cpu_addr, size_t size,
-	       enum dma_data_direction direction)
-{
-	BUG();
-	return 0;
-}
-
-static inline void
-dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-		 enum dma_data_direction direction)
-{
-	BUG();
-}
-
-static inline dma_addr_t
-dma_map_page(struct device *dev, struct page *page,
-	     unsigned long offset, size_t size,
-	     enum dma_data_direction direction)
-{
-	BUG();
-	return 0;
-}
-
-static inline void
-dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
-	       enum dma_data_direction direction)
-{
-	BUG();
-}
-
-static inline int
-dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-	   enum dma_data_direction direction)
-{
-	BUG();
-	return 0;
-}
-
-static inline void
-dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
-	     enum dma_data_direction direction)
-{
-	BUG();
-}
-
-static inline void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
-			enum dma_data_direction direction)
-{
-	BUG();
-}
-
-static inline void
-dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
-			   enum dma_data_direction direction)
-{
-	BUG();
-}
-
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
-		    enum dma_data_direction direction)
-{
-	BUG();
-}
-
-static inline void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
-		       enum dma_data_direction direction)
-{
-	BUG();
-}
-
-static inline int
-dma_error(dma_addr_t dma_addr)
-{
-	return 0;
-}
-
-#endif
-
-/* Now for the API extensions over the pci_ one */
-
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-#define dma_is_consistent(d, h)	(1)
-
-static inline int
-dma_get_cache_alignment(void)
-{
-	/* no easy way to get cache size on all processors, so return
-	 * the maximum possible, to be safe */
-	return (1 << INTERNODE_CACHE_SHIFT);
-}
-
-static inline void
-dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
-			      unsigned long offset, size_t size,
-			      enum dma_data_direction direction)
-{
-	/* just sync everything, that's all the pci API can do */
-	dma_sync_single_for_cpu(dev, dma_handle, offset+size, direction);
-}
-
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
-				 unsigned long offset, size_t size,
-				 enum dma_data_direction direction)
-{
-	/* just sync everything, that's all the pci API can do */
-	dma_sync_single_for_device(dev, dma_handle, offset+size, direction);
-}
-
-static inline void
-dma_cache_sync(struct device *dev, void *vaddr, size_t size,
-	       enum dma_data_direction direction)
-{
-	/* could define this in terms of the dma_cache ... operations,
-	 * but if you get this on a platform, you should convert the platform
-	 * to using the generic device DMA API */
-	BUG();
-}
-
-#endif
-
diff --git a/include/asm-mn10300/highmem.h b/include/asm-mn10300/highmem.h
index 5256854..90f2abb 100644
--- a/include/asm-mn10300/highmem.h
+++ b/include/asm-mn10300/highmem.h
@@ -16,6 +16,7 @@
 
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/highmem.h>
 #include <asm/kmap_types.h>
 #include <asm/pgtable.h>
 
@@ -77,6 +78,7 @@
 	if (page < highmem_start_page)
 		return page_address(page);
 
+	debug_kmap_atomic(type);
 	idx = type + KM_TYPE_NR * smp_processor_id();
 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
 #if HIGHMEM_DEBUG
diff --git a/include/linux/auto_dev-ioctl.h b/include/linux/auto_dev-ioctl.h
index 91a7739..850f39b 100644
--- a/include/linux/auto_dev-ioctl.h
+++ b/include/linux/auto_dev-ioctl.h
@@ -10,8 +10,13 @@
 #ifndef _LINUX_AUTO_DEV_IOCTL_H
 #define _LINUX_AUTO_DEV_IOCTL_H
 
+#include <linux/auto_fs.h>
+
+#ifdef __KERNEL__
 #include <linux/string.h>
-#include <linux/types.h>
+#else
+#include <string.h>
+#endif /* __KERNEL__ */
 
 #define AUTOFS_DEVICE_NAME		"autofs"
 
diff --git a/include/linux/auto_fs.h b/include/linux/auto_fs.h
index c21e597..6326585 100644
--- a/include/linux/auto_fs.h
+++ b/include/linux/auto_fs.h
@@ -17,10 +17,12 @@
 #ifdef __KERNEL__
 #include <linux/fs.h>
 #include <linux/limits.h>
-#include <asm/types.h>
-#endif /* __KERNEL__ */
-
+#include <linux/types.h>
 #include <linux/ioctl.h>
+#else
+#include <asm/types.h>
+#include <sys/ioctl.h>
+#endif /* __KERNEL__ */
 
 /* This file describes autofs v3 */
 #define AUTOFS_PROTO_VERSION	3
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
index 455d832..bc3ab70 100644
--- a/include/linux/bootmem.h
+++ b/include/linux/bootmem.h
@@ -146,10 +146,10 @@
 
 #define HASH_EARLY	0x00000001	/* Allocating during early boot? */
 
-/* Only NUMA needs hash distribution.
- * IA64 and x86_64 have sufficient vmalloc space.
+/* Only NUMA needs hash distribution. 64bit NUMA architectures have
+ * sufficient vmalloc space.
  */
-#if defined(CONFIG_NUMA) && (defined(CONFIG_IA64) || defined(CONFIG_X86_64))
+#if defined(CONFIG_NUMA) && defined(CONFIG_64BIT)
 #define HASHDIST_DEFAULT 1
 #else
 #define HASHDIST_DEFAULT 0
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index f19fd90..3d7bcde 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -216,7 +216,7 @@
 			get_block_t *, loff_t *);
 int generic_cont_expand_simple(struct inode *inode, loff_t size);
 int block_commit_write(struct page *page, unsigned from, unsigned to);
-int block_page_mkwrite(struct vm_area_struct *vma, struct page *page,
+int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
 				get_block_t get_block);
 void block_sync_page(struct page *);
 sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *);
diff --git a/include/linux/eventfd.h b/include/linux/eventfd.h
index a667637..f45a8ae 100644
--- a/include/linux/eventfd.h
+++ b/include/linux/eventfd.h
@@ -13,10 +13,20 @@
 /* For O_CLOEXEC and O_NONBLOCK */
 #include <linux/fcntl.h>
 
-/* Flags for eventfd2.  */
+/*
+ * CAREFUL: Check include/asm-generic/fcntl.h when defining
+ * new flags, since they might collide with O_* ones. We want
+ * to re-use O_* flags that couldn't possibly have a meaning
+ * from eventfd, in order to leave a free define-space for
+ * shared O_* flags.
+ */
+#define EFD_SEMAPHORE (1 << 0)
 #define EFD_CLOEXEC O_CLOEXEC
 #define EFD_NONBLOCK O_NONBLOCK
 
+#define EFD_SHARED_FCNTL_FLAGS (O_CLOEXEC | O_NONBLOCK)
+#define EFD_FLAGS_SET (EFD_SHARED_FCNTL_FLAGS | EFD_SEMAPHORE)
+
 struct file *eventfd_fget(int fd);
 int eventfd_signal(struct file *file, int n);
 
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 31527e1..f563c50 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -123,6 +123,7 @@
 #define FB_ACCEL_TRIDENT_3DIMAGE 51	/* Trident 3DImage		*/
 #define FB_ACCEL_TRIDENT_BLADE3D 52	/* Trident Blade3D		*/
 #define FB_ACCEL_TRIDENT_BLADEXP 53	/* Trident BladeXP		*/
+#define FB_ACCEL_CIRRUS_ALPINE   53	/* Cirrus Logic 543x/544x/5480	*/
 #define FB_ACCEL_NEOMAGIC_NM2070 90	/* NeoMagic NM2070              */
 #define FB_ACCEL_NEOMAGIC_NM2090 91	/* NeoMagic NM2090              */
 #define FB_ACCEL_NEOMAGIC_NM2093 92	/* NeoMagic NM2093              */
@@ -960,15 +961,7 @@
 extern int num_registered_fb;
 extern struct class *fb_class;
 
-static inline int lock_fb_info(struct fb_info *info)
-{
-	mutex_lock(&info->lock);
-	if (!info->fbops) {
-		mutex_unlock(&info->lock);
-		return 0;
-	}
-	return 1;
-}
+extern int lock_fb_info(struct fb_info *info);
 
 static inline void unlock_fb_info(struct fb_info *info)
 {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 87e7bfc..61211ad 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1878,6 +1878,7 @@
 extern void invalidate_bdev(struct block_device *);
 extern int sync_blockdev(struct block_device *bdev);
 extern struct super_block *freeze_bdev(struct block_device *);
+extern void emergency_thaw_all(void);
 extern int thaw_bdev(struct block_device *bdev, struct super_block *sb);
 extern int fsync_bdev(struct block_device *);
 extern int fsync_super(struct super_block *);
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index d9051d7..7ef1caf 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -95,14 +95,15 @@
 #define FSL_USB2_PORT0_ENABLED	0x00000001
 #define FSL_USB2_PORT1_ENABLED	0x00000002
 
+struct spi_device;
+
 struct fsl_spi_platform_data {
 	u32 	initial_spmode;	/* initial SPMODE value */
-	u16	bus_num;
+	s16	bus_num;
 	bool	qe_mode;
 	/* board specific information */
 	u16	max_chipselect;
-	void	(*activate_cs)(u8 cs, u8 polarity);
-	void	(*deactivate_cs)(u8 cs, u8 polarity);
+	void	(*cs_control)(struct spi_device *spi, bool on);
 	u32	sysclk;
 };
 
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index 13875ce..7ff5c55 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -187,4 +187,16 @@
 	kunmap_atomic(vto, KM_USER1);
 }
 
+#if defined(CONFIG_DEBUG_HIGHMEM) && defined(CONFIG_TRACE_IRQFLAGS_SUPPORT)
+
+void debug_kmap_atomic(enum km_type type);
+
+#else
+
+static inline void debug_kmap_atomic(enum km_type type)
+{
+}
+
+#endif
+
 #endif /* _LINUX_HIGHMEM_H */
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index f81d80f..e720b0d 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -353,6 +353,8 @@
         printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_info(fmt, ...) \
         printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_cont(fmt, ...) \
+	printk(KERN_CONT fmt, ##__VA_ARGS__)
 
 /* If you are writing a driver, please use dev_dbg instead */
 #if defined(DEBUG)
diff --git a/include/linux/loop.h b/include/linux/loop.h
index 6ffd6db..4072544 100644
--- a/include/linux/loop.h
+++ b/include/linux/loop.h
@@ -160,5 +160,6 @@
 #define LOOP_SET_STATUS64	0x4C04
 #define LOOP_GET_STATUS64	0x4C05
 #define LOOP_CHANGE_FD		0x4C06
+#define LOOP_SET_CAPACITY	0x4C07
 
 #endif
diff --git a/include/linux/mm.h b/include/linux/mm.h
index b1ea37f..aeabe95 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -135,6 +135,7 @@
 
 #define FAULT_FLAG_WRITE	0x01	/* Fault was a write access */
 #define FAULT_FLAG_NONLINEAR	0x02	/* Fault was via a nonlinear mapping */
+#define FAULT_FLAG_MKWRITE	0x04	/* Fault was mkwrite of existing pte */
 
 /*
  * This interface is used by x86 PAT code to identify a pfn mapping that is
@@ -187,7 +188,7 @@
 
 	/* notification that a previously read-only page is about to become
 	 * writable, if an error is returned it will cause a SIGBUS */
-	int (*page_mkwrite)(struct vm_area_struct *vma, struct page *page);
+	int (*page_mkwrite)(struct vm_area_struct *vma, struct vm_fault *vmf);
 
 	/* called by access_process_vm when get_user_pages() fails, typically
 	 * for use by special VMAs that can switch between memory and hardware
@@ -834,6 +835,7 @@
 int __set_page_dirty_no_writeback(struct page *page);
 int redirty_page_for_writepage(struct writeback_control *wbc,
 				struct page *page);
+void account_page_dirtied(struct page *page, struct address_space *mapping);
 int set_page_dirty(struct page *page);
 int set_page_dirty_lock(struct page *page);
 int clear_page_dirty_for_io(struct page *page);
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index d84feb7..ddadb4d 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -11,6 +11,7 @@
 #include <linux/rwsem.h>
 #include <linux/completion.h>
 #include <linux/cpumask.h>
+#include <linux/page-debug-flags.h>
 #include <asm/page.h>
 #include <asm/mmu.h>
 
@@ -174,6 +175,9 @@
 #ifdef CONFIG_NUMA
 	struct mempolicy *vm_policy;	/* NUMA policy for the VMA */
 #endif
+#ifdef CONFIG_WANT_PAGE_DEBUG_FLAGS
+	unsigned long debug_flags;	/* Use atomic bitops on this */
+#endif
 };
 
 struct core_thread {
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 1aca6ce..26ef240 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -806,6 +806,14 @@
 	     zone;					\
 	     zone = next_zone(zone))
 
+#define for_each_populated_zone(zone)		        \
+	for (zone = (first_online_pgdat())->node_zones; \
+	     zone;					\
+	     zone = next_zone(zone))			\
+		if (!populated_zone(zone))		\
+			; /* do nothing */		\
+		else
+
 static inline struct zone *zonelist_zone(struct zoneref *zoneref)
 {
 	return zoneref->zone;
diff --git a/include/linux/page-debug-flags.h b/include/linux/page-debug-flags.h
new file mode 100644
index 0000000..b0638fd
--- /dev/null
+++ b/include/linux/page-debug-flags.h
@@ -0,0 +1,30 @@
+#ifndef LINUX_PAGE_DEBUG_FLAGS_H
+#define  LINUX_PAGE_DEBUG_FLAGS_H
+
+/*
+ * page->debug_flags bits:
+ *
+ * PAGE_DEBUG_FLAG_POISON is set for poisoned pages. This is used to
+ * implement generic debug pagealloc feature. The pages are filled with
+ * poison patterns and set this flag after free_pages(). The poisoned
+ * pages are verified whether the patterns are not corrupted and clear
+ * the flag before alloc_pages().
+ */
+
+enum page_debug_flags {
+	PAGE_DEBUG_FLAG_POISON,		/* Page is poisoned */
+};
+
+/*
+ * Ensure that CONFIG_WANT_PAGE_DEBUG_FLAGS reliably
+ * gets turned off when no debug features are enabling it!
+ */
+
+#ifdef CONFIG_WANT_PAGE_DEBUG_FLAGS
+#if !defined(CONFIG_PAGE_POISONING) \
+/* && !defined(CONFIG_PAGE_DEBUG_SOMETHING_ELSE) && ... */
+#error WANT_PAGE_DEBUG_FLAGS is turned on with no debug features!
+#endif
+#endif /* CONFIG_WANT_PAGE_DEBUG_FLAGS */
+
+#endif /* LINUX_PAGE_DEBUG_FLAGS_H */
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 219a523..61df177 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -96,6 +96,8 @@
 	PG_swapbacked,		/* Page is backed by RAM/swap */
 #ifdef CONFIG_UNEVICTABLE_LRU
 	PG_unevictable,		/* Page is "unevictable"  */
+#endif
+#ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT
 	PG_mlocked,		/* Page is vma mlocked */
 #endif
 #ifdef CONFIG_IA64_UNCACHED_ALLOCATOR
@@ -234,22 +236,22 @@
 #ifdef CONFIG_UNEVICTABLE_LRU
 PAGEFLAG(Unevictable, unevictable) __CLEARPAGEFLAG(Unevictable, unevictable)
 	TESTCLEARFLAG(Unevictable, unevictable)
-
-#define MLOCK_PAGES 1
-PAGEFLAG(Mlocked, mlocked) __CLEARPAGEFLAG(Mlocked, mlocked)
-	TESTSCFLAG(Mlocked, mlocked)
-
 #else
-
-#define MLOCK_PAGES 0
-PAGEFLAG_FALSE(Mlocked)
-	SETPAGEFLAG_NOOP(Mlocked) TESTCLEARFLAG_FALSE(Mlocked)
-
 PAGEFLAG_FALSE(Unevictable) TESTCLEARFLAG_FALSE(Unevictable)
 	SETPAGEFLAG_NOOP(Unevictable) CLEARPAGEFLAG_NOOP(Unevictable)
 	__CLEARPAGEFLAG_NOOP(Unevictable)
 #endif
 
+#ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT
+#define MLOCK_PAGES 1
+PAGEFLAG(Mlocked, mlocked) __CLEARPAGEFLAG(Mlocked, mlocked)
+	TESTSCFLAG(Mlocked, mlocked)
+#else
+#define MLOCK_PAGES 0
+PAGEFLAG_FALSE(Mlocked)
+	SETPAGEFLAG_NOOP(Mlocked) TESTCLEARFLAG_FALSE(Mlocked)
+#endif
+
 #ifdef CONFIG_IA64_UNCACHED_ALLOCATOR
 PAGEFLAG(Uncached, uncached)
 #else
@@ -367,9 +369,13 @@
 
 #ifdef CONFIG_UNEVICTABLE_LRU
 #define __PG_UNEVICTABLE	(1 << PG_unevictable)
-#define __PG_MLOCKED		(1 << PG_mlocked)
 #else
 #define __PG_UNEVICTABLE	0
+#endif
+
+#ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT
+#define __PG_MLOCKED		(1 << PG_mlocked)
+#else
 #define __PG_MLOCKED		0
 #endif
 
diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h
index 7b2886f..bab82f4 100644
--- a/include/linux/pagevec.h
+++ b/include/linux/pagevec.h
@@ -24,7 +24,6 @@
 void __pagevec_free(struct pagevec *pvec);
 void ____pagevec_lru_add(struct pagevec *pvec, enum lru_list lru);
 void pagevec_strip(struct pagevec *pvec);
-void pagevec_swap_free(struct pagevec *pvec);
 unsigned pagevec_lookup(struct pagevec *pvec, struct address_space *mapping,
 		pgoff_t start, unsigned nr_pages);
 unsigned pagevec_lookup_tag(struct pagevec *pvec,
diff --git a/include/linux/poison.h b/include/linux/poison.h
index 9f31683..6729f7d 100644
--- a/include/linux/poison.h
+++ b/include/linux/poison.h
@@ -17,6 +17,9 @@
  */
 #define TIMER_ENTRY_STATIC	((void *) 0x74737461)
 
+/********** mm/debug-pagealloc.c **********/
+#define PAGE_POISON 0xaa
+
 /********** mm/slab.c **********/
 /*
  * Magic nums for obj red zoning.
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index 4046b75..60f88a7 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -99,6 +99,7 @@
 
 #ifdef __KERNEL__
 
+#include <linux/types.h>
 #include <linux/interrupt.h>
 
 extern int rtc_month_days(unsigned int month, unsigned int year);
@@ -232,6 +233,11 @@
 int rtc_unregister(rtc_task_t *task);
 int rtc_control(rtc_task_t *t, unsigned int cmd, unsigned long arg);
 
+static inline bool is_leap_year(unsigned int year)
+{
+	return (!(year % 4) && (year % 100)) || !(year % 400);
+}
+
 #endif /* __KERNEL__ */
 
 #endif /* _LINUX_RTC_H_ */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 29df637..481fad3 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -391,8 +391,15 @@
 		(mm)->hiwater_vm = (mm)->total_vm;	\
 } while (0)
 
-#define get_mm_hiwater_rss(mm)	max((mm)->hiwater_rss, get_mm_rss(mm))
-#define get_mm_hiwater_vm(mm)	max((mm)->hiwater_vm, (mm)->total_vm)
+static inline unsigned long get_mm_hiwater_rss(struct mm_struct *mm)
+{
+	return max(mm->hiwater_rss, get_mm_rss(mm));
+}
+
+static inline unsigned long get_mm_hiwater_vm(struct mm_struct *mm)
+{
+	return max(mm->hiwater_vm, mm->total_vm);
+}
 
 extern void set_dumpable(struct mm_struct *mm, int value);
 extern int get_dumpable(struct mm_struct *mm);
diff --git a/include/linux/string.h b/include/linux/string.h
index d18fc19..8852739 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -12,6 +12,7 @@
 #include <linux/stddef.h>	/* for NULL */
 
 extern char *strndup_user(const char __user *, long);
+extern void *memdup_user(const void __user *, size_t);
 
 /*
  * Include machine specific inline routines
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index c7d9bb18..3e3a436 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -1,9 +1,6 @@
 #ifndef _LINUX_SUSPEND_H
 #define _LINUX_SUSPEND_H
 
-#if defined(CONFIG_X86) || defined(CONFIG_FRV) || defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
-#include <asm/suspend.h>
-#endif
 #include <linux/swap.h>
 #include <linux/notifier.h>
 #include <linux/init.h>
diff --git a/include/linux/swap.h b/include/linux/swap.h
index d302155..62d8143 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -212,7 +212,7 @@
 
 /* linux/mm/vmscan.c */
 extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
-					gfp_t gfp_mask);
+					gfp_t gfp_mask, nodemask_t *mask);
 extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem,
 						  gfp_t gfp_mask, bool noswap,
 						  unsigned int swappiness);
@@ -382,6 +382,11 @@
 	return NULL;
 }
 
+static inline int swap_writepage(struct page *p, struct writeback_control *wbc)
+{
+	return 0;
+}
+
 static inline struct page *lookup_swap_cache(swp_entry_t swp)
 {
 	return NULL;
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
index 08e0883..8615d66 100644
--- a/include/linux/tty_driver.h
+++ b/include/linux/tty_driver.h
@@ -252,8 +252,6 @@
 	void (*set_ldisc)(struct tty_struct *tty);
 	void (*wait_until_sent)(struct tty_struct *tty, int timeout);
 	void (*send_xchar)(struct tty_struct *tty, char ch);
-	int (*read_proc)(char *page, char **start, off_t off,
-			  int count, int *eof, void *data);
 	int (*tiocmget)(struct tty_struct *tty, struct file *file);
 	int (*tiocmset)(struct tty_struct *tty, struct file *file,
 			unsigned int set, unsigned int clear);
@@ -264,6 +262,7 @@
 	int (*poll_get_char)(struct tty_driver *driver, int line);
 	void (*poll_put_char)(struct tty_driver *driver, int line, char ch);
 #endif
+	const struct file_operations *proc_fops;
 };
 
 struct tty_driver {
diff --git a/include/linux/wait.h b/include/linux/wait.h
index a210ede..5d631c1 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -135,8 +135,11 @@
 void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
 			int nr_exclusive, int sync, void *key);
 void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr, void *key);
-extern void __wake_up_locked(wait_queue_head_t *q, unsigned int mode);
-extern void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr);
+void __wake_up_locked_key(wait_queue_head_t *q, unsigned int mode, void *key);
+void __wake_up_sync_key(wait_queue_head_t *q, unsigned int mode, int nr,
+			void *key);
+void __wake_up_locked(wait_queue_head_t *q, unsigned int mode);
+void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr);
 void __wake_up_bit(wait_queue_head_t *, void *, int);
 int __wait_on_bit(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned);
 int __wait_on_bit_lock(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned);
@@ -155,21 +158,17 @@
 #define wake_up_interruptible_all(x)	__wake_up(x, TASK_INTERRUPTIBLE, 0, NULL)
 #define wake_up_interruptible_sync(x)	__wake_up_sync((x), TASK_INTERRUPTIBLE, 1)
 
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
 /*
- * macro to avoid include hell
+ * Wakeup macros to be used to report events to the targets.
  */
-#define wake_up_nested(x, s)						\
-do {									\
-	unsigned long flags;						\
-									\
-	spin_lock_irqsave_nested(&(x)->lock, flags, (s));		\
-	wake_up_locked(x); 						\
-	spin_unlock_irqrestore(&(x)->lock, flags);			\
-} while (0)
-#else
-#define wake_up_nested(x, s)		wake_up(x)
-#endif
+#define wake_up_poll(x, m)				\
+	__wake_up(x, TASK_NORMAL, 1, (void *) (m))
+#define wake_up_locked_poll(x, m)				\
+	__wake_up_locked_key((x), TASK_NORMAL, (void *) (m))
+#define wake_up_interruptible_poll(x, m)			\
+	__wake_up(x, TASK_INTERRUPTIBLE, 1, (void *) (m))
+#define wake_up_interruptible_sync_poll(x, m)				\
+	__wake_up_sync_key((x), TASK_INTERRUPTIBLE, 1, (void *) (m))
 
 #define __wait_event(wq, condition) 					\
 do {									\
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 7300ecd..9344547 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -109,8 +109,8 @@
 extern unsigned long dirty_background_bytes;
 extern int vm_dirty_ratio;
 extern unsigned long vm_dirty_bytes;
-extern int dirty_writeback_interval;
-extern int dirty_expire_interval;
+extern unsigned int dirty_writeback_interval;
+extern unsigned int dirty_expire_interval;
 extern int vm_highmem_is_dirtyable;
 extern int block_dump;
 extern int laptop_mode;
diff --git a/include/video/aty128.h b/include/video/aty128.h
index 51ac69f..f0851e3 100644
--- a/include/video/aty128.h
+++ b/include/video/aty128.h
@@ -415,7 +415,7 @@
 #define PWR_MGT_SLOWDOWN_MCLK			0x00002000
 
 #define PMI_PMSCR_REG				0x60
-                                                                                
+
 /* used by ATI bug fix for hardware ROM */
 #define RAGE128_MPP_TB_CONFIG                   0x01c0
 
diff --git a/include/video/cirrus.h b/include/video/cirrus.h
index b2776b6..9a5e9ee 100644
--- a/include/video/cirrus.h
+++ b/include/video/cirrus.h
@@ -32,7 +32,6 @@
 #define CL_VSSM2	0x3c3	/* Motherboard Sleep */
 
 /*** VGA Sequencer Registers ***/
-#define CL_SEQR0	0x0	/* Reset */
 /* the following are from the "extension registers" group */
 #define CL_SEQR6	0x6	/* Unlock ALL Extensions */
 #define CL_SEQR7	0x7	/* Extended Sequencer Mode */
@@ -71,6 +70,7 @@
 #define CL_CRT1B	0x1b	/* Extended Display Controls */
 #define CL_CRT1C	0x1c	/* Sync adjust and genlock register */
 #define CL_CRT1D	0x1d	/* Overlay Extended Control register */
+#define CL_CRT1E	0x1e	/* Another overflow register */
 #define CL_CRT25	0x25	/* Part Status Register */
 #define CL_CRT27	0x27	/* ID Register */
 #define CL_CRT51	0x51	/* P4 disable "flicker fixer" */
diff --git a/include/video/newport.h b/include/video/newport.h
index 1f5ebea..001b935 100644
--- a/include/video/newport.h
+++ b/include/video/newport.h
@@ -453,7 +453,7 @@
 {
 	int t = BUSY_TIMEOUT;
 
-	while (t--)
+	while (--t)
 		if (!(regs->cset.status & NPORT_STAT_GBUSY))
 			break;
 	return !t;
@@ -463,7 +463,7 @@
 {
 	int t = BUSY_TIMEOUT;
 
-	while (t--)
+	while (--t)
 		if(!(regs->cset.status & NPORT_STAT_BBUSY))
 			break;
 	return !t;
diff --git a/include/video/radeon.h b/include/video/radeon.h
index e072b16..56b188a 100644
--- a/include/video/radeon.h
+++ b/include/video/radeon.h
@@ -5,12 +5,12 @@
 #define RADEON_REGSIZE			0x4000
 
 
-#define MM_INDEX                               0x0000  
-#define MM_DATA                                0x0004  
-#define BUS_CNTL                               0x0030  
-#define HI_STAT                                0x004C  
+#define MM_INDEX                               0x0000
+#define MM_DATA                                0x0004
+#define BUS_CNTL                               0x0030
+#define HI_STAT                                0x004C
 #define BUS_CNTL1                              0x0034
-#define I2C_CNTL_1			       0x0094  
+#define I2C_CNTL_1			       0x0094
 #define CNFG_CNTL                              0x00E0
 #define CNFG_MEMSIZE                           0x00F8
 #define CNFG_APER_0_BASE                       0x0100
@@ -18,8 +18,8 @@
 #define CNFG_APER_SIZE                         0x0108
 #define CNFG_REG_1_BASE                        0x010C
 #define CNFG_REG_APER_SIZE                     0x0110
-#define PAD_AGPINPUT_DELAY                     0x0164  
-#define PAD_CTLR_STRENGTH                      0x0168  
+#define PAD_AGPINPUT_DELAY                     0x0164
+#define PAD_CTLR_STRENGTH                      0x0168
 #define PAD_CTLR_UPDATE                        0x016C
 #define PAD_CTLR_MISC                          0x0aa0
 #define AGP_CNTL                               0x0174
@@ -27,171 +27,171 @@
 #define CAP0_TRIG_CNTL			       0x0950
 #define CAP1_TRIG_CNTL		               0x09c0
 #define VIPH_CONTROL			       0x0C40
-#define VENDOR_ID                              0x0F00  
-#define DEVICE_ID                              0x0F02  
-#define COMMAND                                0x0F04  
-#define STATUS                                 0x0F06  
-#define REVISION_ID                            0x0F08  
-#define REGPROG_INF                            0x0F09  
-#define SUB_CLASS                              0x0F0A  
-#define BASE_CODE                              0x0F0B  
-#define CACHE_LINE                             0x0F0C  
-#define LATENCY                                0x0F0D  
-#define HEADER                                 0x0F0E  
-#define BIST                                   0x0F0F  
-#define REG_MEM_BASE                           0x0F10  
-#define REG_IO_BASE                            0x0F14  
+#define VENDOR_ID                              0x0F00
+#define DEVICE_ID                              0x0F02
+#define COMMAND                                0x0F04
+#define STATUS                                 0x0F06
+#define REVISION_ID                            0x0F08
+#define REGPROG_INF                            0x0F09
+#define SUB_CLASS                              0x0F0A
+#define BASE_CODE                              0x0F0B
+#define CACHE_LINE                             0x0F0C
+#define LATENCY                                0x0F0D
+#define HEADER                                 0x0F0E
+#define BIST                                   0x0F0F
+#define REG_MEM_BASE                           0x0F10
+#define REG_IO_BASE                            0x0F14
 #define REG_REG_BASE                           0x0F18
 #define ADAPTER_ID                             0x0F2C
 #define BIOS_ROM                               0x0F30
-#define CAPABILITIES_PTR                       0x0F34  
-#define INTERRUPT_LINE                         0x0F3C  
-#define INTERRUPT_PIN                          0x0F3D  
-#define MIN_GRANT                              0x0F3E  
-#define MAX_LATENCY                            0x0F3F  
-#define ADAPTER_ID_W                           0x0F4C  
-#define PMI_CAP_ID                             0x0F50  
-#define PMI_NXT_CAP_PTR                        0x0F51  
-#define PMI_PMC_REG                            0x0F52  
-#define PM_STATUS                              0x0F54  
-#define PMI_DATA                               0x0F57  
-#define AGP_CAP_ID                             0x0F58  
-#define AGP_STATUS                             0x0F5C  
-#define AGP_COMMAND                            0x0F60  
+#define CAPABILITIES_PTR                       0x0F34
+#define INTERRUPT_LINE                         0x0F3C
+#define INTERRUPT_PIN                          0x0F3D
+#define MIN_GRANT                              0x0F3E
+#define MAX_LATENCY                            0x0F3F
+#define ADAPTER_ID_W                           0x0F4C
+#define PMI_CAP_ID                             0x0F50
+#define PMI_NXT_CAP_PTR                        0x0F51
+#define PMI_PMC_REG                            0x0F52
+#define PM_STATUS                              0x0F54
+#define PMI_DATA                               0x0F57
+#define AGP_CAP_ID                             0x0F58
+#define AGP_STATUS                             0x0F5C
+#define AGP_COMMAND                            0x0F60
 #define AIC_CTRL                               0x01D0
 #define AIC_STAT                               0x01D4
 #define AIC_PT_BASE                            0x01D8
-#define AIC_LO_ADDR                            0x01DC  
-#define AIC_HI_ADDR                            0x01E0  
-#define AIC_TLB_ADDR                           0x01E4  
-#define AIC_TLB_DATA                           0x01E8  
-#define DAC_CNTL                               0x0058  
+#define AIC_LO_ADDR                            0x01DC
+#define AIC_HI_ADDR                            0x01E0
+#define AIC_TLB_ADDR                           0x01E4
+#define AIC_TLB_DATA                           0x01E8
+#define DAC_CNTL                               0x0058
 #define DAC_CNTL2                              0x007c
-#define CRTC_GEN_CNTL                          0x0050  
-#define MEM_CNTL                               0x0140  
+#define CRTC_GEN_CNTL                          0x0050
+#define MEM_CNTL                               0x0140
 #define MC_CNTL                                0x0140
-#define EXT_MEM_CNTL                           0x0144  
+#define EXT_MEM_CNTL                           0x0144
 #define MC_TIMING_CNTL                         0x0144
-#define MC_AGP_LOCATION                        0x014C  
-#define MEM_IO_CNTL_A0                         0x0178  
+#define MC_AGP_LOCATION                        0x014C
+#define MEM_IO_CNTL_A0                         0x0178
 #define MEM_REFRESH_CNTL                       0x0178
-#define MEM_INIT_LATENCY_TIMER                 0x0154  
+#define MEM_INIT_LATENCY_TIMER                 0x0154
 #define MC_INIT_GFX_LAT_TIMER                  0x0154
-#define MEM_SDRAM_MODE_REG                     0x0158  
-#define AGP_BASE                               0x0170  
-#define MEM_IO_CNTL_A1                         0x017C  
+#define MEM_SDRAM_MODE_REG                     0x0158
+#define AGP_BASE                               0x0170
+#define MEM_IO_CNTL_A1                         0x017C
 #define MC_READ_CNTL_AB                        0x017C
 #define MEM_IO_CNTL_B0                         0x0180
 #define MC_INIT_MISC_LAT_TIMER                 0x0180
 #define MEM_IO_CNTL_B1                         0x0184
 #define MC_IOPAD_CNTL                          0x0184
 #define MC_DEBUG                               0x0188
-#define MC_STATUS                              0x0150  
-#define MEM_IO_OE_CNTL                         0x018C  
+#define MC_STATUS                              0x0150
+#define MEM_IO_OE_CNTL                         0x018C
 #define MC_CHIP_IO_OE_CNTL_AB                  0x018C
-#define MC_FB_LOCATION                         0x0148  
-#define HOST_PATH_CNTL                         0x0130  
-#define MEM_VGA_WP_SEL                         0x0038  
-#define MEM_VGA_RP_SEL                         0x003C  
-#define HDP_DEBUG                              0x0138  
+#define MC_FB_LOCATION                         0x0148
+#define HOST_PATH_CNTL                         0x0130
+#define MEM_VGA_WP_SEL                         0x0038
+#define MEM_VGA_RP_SEL                         0x003C
+#define HDP_DEBUG                              0x0138
 #define SW_SEMAPHORE                           0x013C
-#define CRTC2_GEN_CNTL                         0x03f8  
+#define CRTC2_GEN_CNTL                         0x03f8
 #define CRTC2_DISPLAY_BASE_ADDR                0x033c
-#define SURFACE_CNTL                           0x0B00  
-#define SURFACE0_LOWER_BOUND                   0x0B04  
-#define SURFACE1_LOWER_BOUND                   0x0B14  
-#define SURFACE2_LOWER_BOUND                   0x0B24  
-#define SURFACE3_LOWER_BOUND                   0x0B34  
-#define SURFACE4_LOWER_BOUND                   0x0B44  
+#define SURFACE_CNTL                           0x0B00
+#define SURFACE0_LOWER_BOUND                   0x0B04
+#define SURFACE1_LOWER_BOUND                   0x0B14
+#define SURFACE2_LOWER_BOUND                   0x0B24
+#define SURFACE3_LOWER_BOUND                   0x0B34
+#define SURFACE4_LOWER_BOUND                   0x0B44
 #define SURFACE5_LOWER_BOUND                   0x0B54
 #define SURFACE6_LOWER_BOUND                   0x0B64
 #define SURFACE7_LOWER_BOUND                   0x0B74
-#define SURFACE0_UPPER_BOUND                   0x0B08  
-#define SURFACE1_UPPER_BOUND                   0x0B18  
-#define SURFACE2_UPPER_BOUND                   0x0B28  
-#define SURFACE3_UPPER_BOUND                   0x0B38  
-#define SURFACE4_UPPER_BOUND                   0x0B48  
-#define SURFACE5_UPPER_BOUND                   0x0B58  
-#define SURFACE6_UPPER_BOUND                   0x0B68  
-#define SURFACE7_UPPER_BOUND                   0x0B78  
-#define SURFACE0_INFO                          0x0B0C  
-#define SURFACE1_INFO                          0x0B1C  
-#define SURFACE2_INFO                          0x0B2C  
-#define SURFACE3_INFO                          0x0B3C  
-#define SURFACE4_INFO                          0x0B4C  
-#define SURFACE5_INFO                          0x0B5C  
+#define SURFACE0_UPPER_BOUND                   0x0B08
+#define SURFACE1_UPPER_BOUND                   0x0B18
+#define SURFACE2_UPPER_BOUND                   0x0B28
+#define SURFACE3_UPPER_BOUND                   0x0B38
+#define SURFACE4_UPPER_BOUND                   0x0B48
+#define SURFACE5_UPPER_BOUND                   0x0B58
+#define SURFACE6_UPPER_BOUND                   0x0B68
+#define SURFACE7_UPPER_BOUND                   0x0B78
+#define SURFACE0_INFO                          0x0B0C
+#define SURFACE1_INFO                          0x0B1C
+#define SURFACE2_INFO                          0x0B2C
+#define SURFACE3_INFO                          0x0B3C
+#define SURFACE4_INFO                          0x0B4C
+#define SURFACE5_INFO                          0x0B5C
 #define SURFACE6_INFO                          0x0B6C
 #define SURFACE7_INFO                          0x0B7C
 #define SURFACE_ACCESS_FLAGS                   0x0BF8
-#define SURFACE_ACCESS_CLR                     0x0BFC  
-#define GEN_INT_CNTL                           0x0040  
-#define GEN_INT_STATUS                         0x0044  
+#define SURFACE_ACCESS_CLR                     0x0BFC
+#define GEN_INT_CNTL                           0x0040
+#define GEN_INT_STATUS                         0x0044
 #define CRTC_EXT_CNTL                          0x0054
-#define RB3D_CNTL			       0x1C3C  
-#define WAIT_UNTIL                             0x1720  
-#define ISYNC_CNTL                             0x1724  
-#define RBBM_GUICNTL                           0x172C  
-#define RBBM_STATUS                            0x0E40  
-#define RBBM_STATUS_alt_1                      0x1740  
-#define RBBM_CNTL                              0x00EC  
-#define RBBM_CNTL_alt_1                        0x0E44  
-#define RBBM_SOFT_RESET                        0x00F0  
-#define RBBM_SOFT_RESET_alt_1                  0x0E48  
-#define NQWAIT_UNTIL                           0x0E50  
+#define RB3D_CNTL			       0x1C3C
+#define WAIT_UNTIL                             0x1720
+#define ISYNC_CNTL                             0x1724
+#define RBBM_GUICNTL                           0x172C
+#define RBBM_STATUS                            0x0E40
+#define RBBM_STATUS_alt_1                      0x1740
+#define RBBM_CNTL                              0x00EC
+#define RBBM_CNTL_alt_1                        0x0E44
+#define RBBM_SOFT_RESET                        0x00F0
+#define RBBM_SOFT_RESET_alt_1                  0x0E48
+#define NQWAIT_UNTIL                           0x0E50
 #define RBBM_DEBUG                             0x0E6C
 #define RBBM_CMDFIFO_ADDR                      0x0E70
 #define RBBM_CMDFIFO_DATAL                     0x0E74
-#define RBBM_CMDFIFO_DATAH                     0x0E78  
-#define RBBM_CMDFIFO_STAT                      0x0E7C  
-#define CRTC_STATUS                            0x005C  
-#define GPIO_VGA_DDC                           0x0060  
-#define GPIO_DVI_DDC                           0x0064  
-#define GPIO_MONID                             0x0068  
+#define RBBM_CMDFIFO_DATAH                     0x0E78
+#define RBBM_CMDFIFO_STAT                      0x0E7C
+#define CRTC_STATUS                            0x005C
+#define GPIO_VGA_DDC                           0x0060
+#define GPIO_DVI_DDC                           0x0064
+#define GPIO_MONID                             0x0068
 #define GPIO_CRT2_DDC                          0x006c
-#define PALETTE_INDEX                          0x00B0  
-#define PALETTE_DATA                           0x00B4  
-#define PALETTE_30_DATA                        0x00B8  
-#define CRTC_H_TOTAL_DISP                      0x0200  
-#define CRTC_H_SYNC_STRT_WID                   0x0204  
-#define CRTC_V_TOTAL_DISP                      0x0208  
-#define CRTC_V_SYNC_STRT_WID                   0x020C  
-#define CRTC_VLINE_CRNT_VLINE                  0x0210  
+#define PALETTE_INDEX                          0x00B0
+#define PALETTE_DATA                           0x00B4
+#define PALETTE_30_DATA                        0x00B8
+#define CRTC_H_TOTAL_DISP                      0x0200
+#define CRTC_H_SYNC_STRT_WID                   0x0204
+#define CRTC_V_TOTAL_DISP                      0x0208
+#define CRTC_V_SYNC_STRT_WID                   0x020C
+#define CRTC_VLINE_CRNT_VLINE                  0x0210
 #define CRTC_CRNT_FRAME                        0x0214
 #define CRTC_GUI_TRIG_VLINE                    0x0218
 #define CRTC_DEBUG                             0x021C
-#define CRTC_OFFSET_RIGHT                      0x0220  
-#define CRTC_OFFSET                            0x0224  
-#define CRTC_OFFSET_CNTL                       0x0228  
-#define CRTC_PITCH                             0x022C  
-#define OVR_CLR                                0x0230  
-#define OVR_WID_LEFT_RIGHT                     0x0234  
-#define OVR_WID_TOP_BOTTOM                     0x0238  
-#define DISPLAY_BASE_ADDR                      0x023C  
-#define SNAPSHOT_VH_COUNTS                     0x0240  
-#define SNAPSHOT_F_COUNT                       0x0244  
-#define N_VIF_COUNT                            0x0248  
-#define SNAPSHOT_VIF_COUNT                     0x024C  
-#define FP_CRTC_H_TOTAL_DISP                   0x0250  
-#define FP_CRTC_V_TOTAL_DISP                   0x0254  
+#define CRTC_OFFSET_RIGHT                      0x0220
+#define CRTC_OFFSET                            0x0224
+#define CRTC_OFFSET_CNTL                       0x0228
+#define CRTC_PITCH                             0x022C
+#define OVR_CLR                                0x0230
+#define OVR_WID_LEFT_RIGHT                     0x0234
+#define OVR_WID_TOP_BOTTOM                     0x0238
+#define DISPLAY_BASE_ADDR                      0x023C
+#define SNAPSHOT_VH_COUNTS                     0x0240
+#define SNAPSHOT_F_COUNT                       0x0244
+#define N_VIF_COUNT                            0x0248
+#define SNAPSHOT_VIF_COUNT                     0x024C
+#define FP_CRTC_H_TOTAL_DISP                   0x0250
+#define FP_CRTC_V_TOTAL_DISP                   0x0254
 #define CRT_CRTC_H_SYNC_STRT_WID               0x0258
 #define CRT_CRTC_V_SYNC_STRT_WID               0x025C
 #define CUR_OFFSET                             0x0260
-#define CUR_HORZ_VERT_POSN                     0x0264  
-#define CUR_HORZ_VERT_OFF                      0x0268  
-#define CUR_CLR0                               0x026C  
-#define CUR_CLR1                               0x0270  
-#define FP_HORZ_VERT_ACTIVE                    0x0278  
-#define CRTC_MORE_CNTL                         0x027C  
+#define CUR_HORZ_VERT_POSN                     0x0264
+#define CUR_HORZ_VERT_OFF                      0x0268
+#define CUR_CLR0                               0x026C
+#define CUR_CLR1                               0x0270
+#define FP_HORZ_VERT_ACTIVE                    0x0278
+#define CRTC_MORE_CNTL                         0x027C
 #define CRTC_H_CUTOFF_ACTIVE_EN                (1<<4)
 #define CRTC_V_CUTOFF_ACTIVE_EN                (1<<5)
-#define DAC_EXT_CNTL                           0x0280  
-#define FP_GEN_CNTL                            0x0284  
-#define FP_HORZ_STRETCH                        0x028C  
-#define FP_VERT_STRETCH                        0x0290  
-#define FP_H_SYNC_STRT_WID                     0x02C4  
-#define FP_V_SYNC_STRT_WID                     0x02C8  
-#define AUX_WINDOW_HORZ_CNTL                   0x02D8  
-#define AUX_WINDOW_VERT_CNTL                   0x02DC  
+#define DAC_EXT_CNTL                           0x0280
+#define FP_GEN_CNTL                            0x0284
+#define FP_HORZ_STRETCH                        0x028C
+#define FP_VERT_STRETCH                        0x0290
+#define FP_H_SYNC_STRT_WID                     0x02C4
+#define FP_V_SYNC_STRT_WID                     0x02C8
+#define AUX_WINDOW_HORZ_CNTL                   0x02D8
+#define AUX_WINDOW_VERT_CNTL                   0x02DC
 //#define DDA_CONFIG			       0x02e0
 //#define DDA_ON_OFF			       0x02e4
 #define DVI_I2C_CNTL_1			       0x02e4
@@ -199,192 +199,192 @@
 #define GRPH2_BUFFER_CNTL                      0x03F0
 #define VGA_BUFFER_CNTL                        0x02F4
 #define OV0_Y_X_START                          0x0400
-#define OV0_Y_X_END                            0x0404  
-#define OV0_PIPELINE_CNTL                      0x0408  
-#define OV0_REG_LOAD_CNTL                      0x0410  
-#define OV0_SCALE_CNTL                         0x0420  
-#define OV0_V_INC                              0x0424  
-#define OV0_P1_V_ACCUM_INIT                    0x0428  
-#define OV0_P23_V_ACCUM_INIT                   0x042C  
-#define OV0_P1_BLANK_LINES_AT_TOP              0x0430  
-#define OV0_P23_BLANK_LINES_AT_TOP             0x0434  
-#define OV0_BASE_ADDR                          0x043C  
-#define OV0_VID_BUF0_BASE_ADRS                 0x0440  
-#define OV0_VID_BUF1_BASE_ADRS                 0x0444  
-#define OV0_VID_BUF2_BASE_ADRS                 0x0448  
-#define OV0_VID_BUF3_BASE_ADRS                 0x044C  
+#define OV0_Y_X_END                            0x0404
+#define OV0_PIPELINE_CNTL                      0x0408
+#define OV0_REG_LOAD_CNTL                      0x0410
+#define OV0_SCALE_CNTL                         0x0420
+#define OV0_V_INC                              0x0424
+#define OV0_P1_V_ACCUM_INIT                    0x0428
+#define OV0_P23_V_ACCUM_INIT                   0x042C
+#define OV0_P1_BLANK_LINES_AT_TOP              0x0430
+#define OV0_P23_BLANK_LINES_AT_TOP             0x0434
+#define OV0_BASE_ADDR                          0x043C
+#define OV0_VID_BUF0_BASE_ADRS                 0x0440
+#define OV0_VID_BUF1_BASE_ADRS                 0x0444
+#define OV0_VID_BUF2_BASE_ADRS                 0x0448
+#define OV0_VID_BUF3_BASE_ADRS                 0x044C
 #define OV0_VID_BUF4_BASE_ADRS                 0x0450
 #define OV0_VID_BUF5_BASE_ADRS                 0x0454
 #define OV0_VID_BUF_PITCH0_VALUE               0x0460
-#define OV0_VID_BUF_PITCH1_VALUE               0x0464  
-#define OV0_AUTO_FLIP_CNTRL                    0x0470  
-#define OV0_DEINTERLACE_PATTERN                0x0474  
-#define OV0_SUBMIT_HISTORY                     0x0478  
-#define OV0_H_INC                              0x0480  
-#define OV0_STEP_BY                            0x0484  
-#define OV0_P1_H_ACCUM_INIT                    0x0488  
-#define OV0_P23_H_ACCUM_INIT                   0x048C  
-#define OV0_P1_X_START_END                     0x0494  
-#define OV0_P2_X_START_END                     0x0498  
-#define OV0_P3_X_START_END                     0x049C  
-#define OV0_FILTER_CNTL                        0x04A0  
-#define OV0_FOUR_TAP_COEF_0                    0x04B0  
-#define OV0_FOUR_TAP_COEF_1                    0x04B4  
+#define OV0_VID_BUF_PITCH1_VALUE               0x0464
+#define OV0_AUTO_FLIP_CNTRL                    0x0470
+#define OV0_DEINTERLACE_PATTERN                0x0474
+#define OV0_SUBMIT_HISTORY                     0x0478
+#define OV0_H_INC                              0x0480
+#define OV0_STEP_BY                            0x0484
+#define OV0_P1_H_ACCUM_INIT                    0x0488
+#define OV0_P23_H_ACCUM_INIT                   0x048C
+#define OV0_P1_X_START_END                     0x0494
+#define OV0_P2_X_START_END                     0x0498
+#define OV0_P3_X_START_END                     0x049C
+#define OV0_FILTER_CNTL                        0x04A0
+#define OV0_FOUR_TAP_COEF_0                    0x04B0
+#define OV0_FOUR_TAP_COEF_1                    0x04B4
 #define OV0_FOUR_TAP_COEF_2                    0x04B8
 #define OV0_FOUR_TAP_COEF_3                    0x04BC
 #define OV0_FOUR_TAP_COEF_4                    0x04C0
-#define OV0_FLAG_CNTRL                         0x04DC  
-#define OV0_SLICE_CNTL                         0x04E0  
-#define OV0_VID_KEY_CLR_LOW                    0x04E4  
-#define OV0_VID_KEY_CLR_HIGH                   0x04E8  
-#define OV0_GRPH_KEY_CLR_LOW                   0x04EC  
-#define OV0_GRPH_KEY_CLR_HIGH                  0x04F0  
-#define OV0_KEY_CNTL                           0x04F4  
-#define OV0_TEST                               0x04F8  
-#define SUBPIC_CNTL                            0x0540  
-#define SUBPIC_DEFCOLCON                       0x0544  
-#define SUBPIC_Y_X_START                       0x054C  
-#define SUBPIC_Y_X_END                         0x0550  
-#define SUBPIC_V_INC                           0x0554  
-#define SUBPIC_H_INC                           0x0558  
+#define OV0_FLAG_CNTRL                         0x04DC
+#define OV0_SLICE_CNTL                         0x04E0
+#define OV0_VID_KEY_CLR_LOW                    0x04E4
+#define OV0_VID_KEY_CLR_HIGH                   0x04E8
+#define OV0_GRPH_KEY_CLR_LOW                   0x04EC
+#define OV0_GRPH_KEY_CLR_HIGH                  0x04F0
+#define OV0_KEY_CNTL                           0x04F4
+#define OV0_TEST                               0x04F8
+#define SUBPIC_CNTL                            0x0540
+#define SUBPIC_DEFCOLCON                       0x0544
+#define SUBPIC_Y_X_START                       0x054C
+#define SUBPIC_Y_X_END                         0x0550
+#define SUBPIC_V_INC                           0x0554
+#define SUBPIC_H_INC                           0x0558
 #define SUBPIC_BUF0_OFFSET                     0x055C
 #define SUBPIC_BUF1_OFFSET                     0x0560
 #define SUBPIC_LC0_OFFSET                      0x0564
-#define SUBPIC_LC1_OFFSET                      0x0568  
-#define SUBPIC_PITCH                           0x056C  
-#define SUBPIC_BTN_HLI_COLCON                  0x0570  
-#define SUBPIC_BTN_HLI_Y_X_START               0x0574  
-#define SUBPIC_BTN_HLI_Y_X_END                 0x0578  
-#define SUBPIC_PALETTE_INDEX                   0x057C  
-#define SUBPIC_PALETTE_DATA                    0x0580  
-#define SUBPIC_H_ACCUM_INIT                    0x0584  
-#define SUBPIC_V_ACCUM_INIT                    0x0588  
-#define DISP_MISC_CNTL                         0x0D00  
-#define DAC_MACRO_CNTL                         0x0D04  
-#define DISP_PWR_MAN                           0x0D08  
-#define DISP_TEST_DEBUG_CNTL                   0x0D10  
-#define DISP_HW_DEBUG                          0x0D14  
+#define SUBPIC_LC1_OFFSET                      0x0568
+#define SUBPIC_PITCH                           0x056C
+#define SUBPIC_BTN_HLI_COLCON                  0x0570
+#define SUBPIC_BTN_HLI_Y_X_START               0x0574
+#define SUBPIC_BTN_HLI_Y_X_END                 0x0578
+#define SUBPIC_PALETTE_INDEX                   0x057C
+#define SUBPIC_PALETTE_DATA                    0x0580
+#define SUBPIC_H_ACCUM_INIT                    0x0584
+#define SUBPIC_V_ACCUM_INIT                    0x0588
+#define DISP_MISC_CNTL                         0x0D00
+#define DAC_MACRO_CNTL                         0x0D04
+#define DISP_PWR_MAN                           0x0D08
+#define DISP_TEST_DEBUG_CNTL                   0x0D10
+#define DISP_HW_DEBUG                          0x0D14
 #define DAC_CRC_SIG1                           0x0D18
 #define DAC_CRC_SIG2                           0x0D1C
 #define OV0_LIN_TRANS_A                        0x0D20
-#define OV0_LIN_TRANS_B                        0x0D24  
-#define OV0_LIN_TRANS_C                        0x0D28  
-#define OV0_LIN_TRANS_D                        0x0D2C  
-#define OV0_LIN_TRANS_E                        0x0D30  
-#define OV0_LIN_TRANS_F                        0x0D34  
-#define OV0_GAMMA_0_F                          0x0D40  
-#define OV0_GAMMA_10_1F                        0x0D44  
-#define OV0_GAMMA_20_3F                        0x0D48  
-#define OV0_GAMMA_40_7F                        0x0D4C  
-#define OV0_GAMMA_380_3BF                      0x0D50  
-#define OV0_GAMMA_3C0_3FF                      0x0D54  
-#define DISP_MERGE_CNTL                        0x0D60  
-#define DISP_OUTPUT_CNTL                       0x0D64  
-#define DISP_LIN_TRANS_GRPH_A                  0x0D80  
+#define OV0_LIN_TRANS_B                        0x0D24
+#define OV0_LIN_TRANS_C                        0x0D28
+#define OV0_LIN_TRANS_D                        0x0D2C
+#define OV0_LIN_TRANS_E                        0x0D30
+#define OV0_LIN_TRANS_F                        0x0D34
+#define OV0_GAMMA_0_F                          0x0D40
+#define OV0_GAMMA_10_1F                        0x0D44
+#define OV0_GAMMA_20_3F                        0x0D48
+#define OV0_GAMMA_40_7F                        0x0D4C
+#define OV0_GAMMA_380_3BF                      0x0D50
+#define OV0_GAMMA_3C0_3FF                      0x0D54
+#define DISP_MERGE_CNTL                        0x0D60
+#define DISP_OUTPUT_CNTL                       0x0D64
+#define DISP_LIN_TRANS_GRPH_A                  0x0D80
 #define DISP_LIN_TRANS_GRPH_B                  0x0D84
 #define DISP_LIN_TRANS_GRPH_C                  0x0D88
 #define DISP_LIN_TRANS_GRPH_D                  0x0D8C
-#define DISP_LIN_TRANS_GRPH_E                  0x0D90  
-#define DISP_LIN_TRANS_GRPH_F                  0x0D94  
-#define DISP_LIN_TRANS_VID_A                   0x0D98  
-#define DISP_LIN_TRANS_VID_B                   0x0D9C  
-#define DISP_LIN_TRANS_VID_C                   0x0DA0  
-#define DISP_LIN_TRANS_VID_D                   0x0DA4  
-#define DISP_LIN_TRANS_VID_E                   0x0DA8  
-#define DISP_LIN_TRANS_VID_F                   0x0DAC  
-#define RMX_HORZ_FILTER_0TAP_COEF              0x0DB0  
-#define RMX_HORZ_FILTER_1TAP_COEF              0x0DB4  
-#define RMX_HORZ_FILTER_2TAP_COEF              0x0DB8  
-#define RMX_HORZ_PHASE                         0x0DBC  
-#define DAC_EMBEDDED_SYNC_CNTL                 0x0DC0  
-#define DAC_BROAD_PULSE                        0x0DC4  
+#define DISP_LIN_TRANS_GRPH_E                  0x0D90
+#define DISP_LIN_TRANS_GRPH_F                  0x0D94
+#define DISP_LIN_TRANS_VID_A                   0x0D98
+#define DISP_LIN_TRANS_VID_B                   0x0D9C
+#define DISP_LIN_TRANS_VID_C                   0x0DA0
+#define DISP_LIN_TRANS_VID_D                   0x0DA4
+#define DISP_LIN_TRANS_VID_E                   0x0DA8
+#define DISP_LIN_TRANS_VID_F                   0x0DAC
+#define RMX_HORZ_FILTER_0TAP_COEF              0x0DB0
+#define RMX_HORZ_FILTER_1TAP_COEF              0x0DB4
+#define RMX_HORZ_FILTER_2TAP_COEF              0x0DB8
+#define RMX_HORZ_PHASE                         0x0DBC
+#define DAC_EMBEDDED_SYNC_CNTL                 0x0DC0
+#define DAC_BROAD_PULSE                        0x0DC4
 #define DAC_SKEW_CLKS                          0x0DC8
 #define DAC_INCR                               0x0DCC
 #define DAC_NEG_SYNC_LEVEL                     0x0DD0
-#define DAC_POS_SYNC_LEVEL                     0x0DD4  
-#define DAC_BLANK_LEVEL                        0x0DD8  
-#define CLOCK_CNTL_INDEX                       0x0008  
-#define CLOCK_CNTL_DATA                        0x000C  
-#define CP_RB_CNTL                             0x0704  
-#define CP_RB_BASE                             0x0700  
-#define CP_RB_RPTR_ADDR                        0x070C  
-#define CP_RB_RPTR                             0x0710  
-#define CP_RB_WPTR                             0x0714  
-#define CP_RB_WPTR_DELAY                       0x0718  
-#define CP_IB_BASE                             0x0738  
-#define CP_IB_BUFSZ                            0x073C  
-#define SCRATCH_REG0                           0x15E0  
-#define GUI_SCRATCH_REG0                       0x15E0  
-#define SCRATCH_REG1                           0x15E4  
-#define GUI_SCRATCH_REG1                       0x15E4  
+#define DAC_POS_SYNC_LEVEL                     0x0DD4
+#define DAC_BLANK_LEVEL                        0x0DD8
+#define CLOCK_CNTL_INDEX                       0x0008
+#define CLOCK_CNTL_DATA                        0x000C
+#define CP_RB_CNTL                             0x0704
+#define CP_RB_BASE                             0x0700
+#define CP_RB_RPTR_ADDR                        0x070C
+#define CP_RB_RPTR                             0x0710
+#define CP_RB_WPTR                             0x0714
+#define CP_RB_WPTR_DELAY                       0x0718
+#define CP_IB_BASE                             0x0738
+#define CP_IB_BUFSZ                            0x073C
+#define SCRATCH_REG0                           0x15E0
+#define GUI_SCRATCH_REG0                       0x15E0
+#define SCRATCH_REG1                           0x15E4
+#define GUI_SCRATCH_REG1                       0x15E4
 #define SCRATCH_REG2                           0x15E8
 #define GUI_SCRATCH_REG2                       0x15E8
 #define SCRATCH_REG3                           0x15EC
-#define GUI_SCRATCH_REG3                       0x15EC  
-#define SCRATCH_REG4                           0x15F0  
-#define GUI_SCRATCH_REG4                       0x15F0  
-#define SCRATCH_REG5                           0x15F4  
-#define GUI_SCRATCH_REG5                       0x15F4  
-#define SCRATCH_UMSK                           0x0770  
-#define SCRATCH_ADDR                           0x0774  
-#define DP_BRUSH_FRGD_CLR                      0x147C  
+#define GUI_SCRATCH_REG3                       0x15EC
+#define SCRATCH_REG4                           0x15F0
+#define GUI_SCRATCH_REG4                       0x15F0
+#define SCRATCH_REG5                           0x15F4
+#define GUI_SCRATCH_REG5                       0x15F4
+#define SCRATCH_UMSK                           0x0770
+#define SCRATCH_ADDR                           0x0774
+#define DP_BRUSH_FRGD_CLR                      0x147C
 #define DP_BRUSH_BKGD_CLR                      0x1478
 #define DST_LINE_START                         0x1600
-#define DST_LINE_END                           0x1604  
-#define SRC_OFFSET                             0x15AC  
+#define DST_LINE_END                           0x1604
+#define SRC_OFFSET                             0x15AC
 #define SRC_PITCH                              0x15B0
 #define SRC_TILE                               0x1704
 #define SRC_PITCH_OFFSET                       0x1428
-#define SRC_X                                  0x1414  
-#define SRC_Y                                  0x1418  
-#define SRC_X_Y                                0x1590  
-#define SRC_Y_X                                0x1434  
+#define SRC_X                                  0x1414
+#define SRC_Y                                  0x1418
+#define SRC_X_Y                                0x1590
+#define SRC_Y_X                                0x1434
 #define DST_Y_X				       0x1438
 #define DST_WIDTH_HEIGHT		       0x1598
 #define DST_HEIGHT_WIDTH		       0x143c
 #define DST_OFFSET                             0x1404
-#define SRC_CLUT_ADDRESS                       0x1780  
-#define SRC_CLUT_DATA                          0x1784  
-#define SRC_CLUT_DATA_RD                       0x1788  
-#define HOST_DATA0                             0x17C0  
-#define HOST_DATA1                             0x17C4  
-#define HOST_DATA2                             0x17C8  
-#define HOST_DATA3                             0x17CC  
-#define HOST_DATA4                             0x17D0  
-#define HOST_DATA5                             0x17D4  
-#define HOST_DATA6                             0x17D8  
+#define SRC_CLUT_ADDRESS                       0x1780
+#define SRC_CLUT_DATA                          0x1784
+#define SRC_CLUT_DATA_RD                       0x1788
+#define HOST_DATA0                             0x17C0
+#define HOST_DATA1                             0x17C4
+#define HOST_DATA2                             0x17C8
+#define HOST_DATA3                             0x17CC
+#define HOST_DATA4                             0x17D0
+#define HOST_DATA5                             0x17D4
+#define HOST_DATA6                             0x17D8
 #define HOST_DATA7                             0x17DC
 #define HOST_DATA_LAST                         0x17E0
 #define DP_SRC_ENDIAN                          0x15D4
-#define DP_SRC_FRGD_CLR                        0x15D8  
-#define DP_SRC_BKGD_CLR                        0x15DC  
-#define SC_LEFT                                0x1640  
-#define SC_RIGHT                               0x1644  
-#define SC_TOP                                 0x1648  
-#define SC_BOTTOM                              0x164C  
-#define SRC_SC_RIGHT                           0x1654  
-#define SRC_SC_BOTTOM                          0x165C  
-#define DP_CNTL                                0x16C0  
-#define DP_CNTL_XDIR_YDIR_YMAJOR               0x16D0  
-#define DP_DATATYPE                            0x16C4  
-#define DP_MIX                                 0x16C8  
-#define DP_WRITE_MSK                           0x16CC  
-#define DP_XOP                                 0x17F8  
+#define DP_SRC_FRGD_CLR                        0x15D8
+#define DP_SRC_BKGD_CLR                        0x15DC
+#define SC_LEFT                                0x1640
+#define SC_RIGHT                               0x1644
+#define SC_TOP                                 0x1648
+#define SC_BOTTOM                              0x164C
+#define SRC_SC_RIGHT                           0x1654
+#define SRC_SC_BOTTOM                          0x165C
+#define DP_CNTL                                0x16C0
+#define DP_CNTL_XDIR_YDIR_YMAJOR               0x16D0
+#define DP_DATATYPE                            0x16C4
+#define DP_MIX                                 0x16C8
+#define DP_WRITE_MSK                           0x16CC
+#define DP_XOP                                 0x17F8
 #define CLR_CMP_CLR_SRC                        0x15C4
 #define CLR_CMP_CLR_DST                        0x15C8
 #define CLR_CMP_CNTL                           0x15C0
-#define CLR_CMP_MSK                            0x15CC  
-#define DSTCACHE_MODE                          0x1710  
-#define DSTCACHE_CTLSTAT                       0x1714  
-#define DEFAULT_PITCH_OFFSET                   0x16E0  
-#define DEFAULT_SC_BOTTOM_RIGHT                0x16E8  
+#define CLR_CMP_MSK                            0x15CC
+#define DSTCACHE_MODE                          0x1710
+#define DSTCACHE_CTLSTAT                       0x1714
+#define DEFAULT_PITCH_OFFSET                   0x16E0
+#define DEFAULT_SC_BOTTOM_RIGHT                0x16E8
 #define DEFAULT_SC_TOP_LEFT                    0x16EC
 #define SRC_PITCH_OFFSET                       0x1428
 #define DST_PITCH_OFFSET                       0x142C
-#define DP_GUI_MASTER_CNTL                     0x146C  
-#define SC_TOP_LEFT                            0x16EC  
-#define SC_BOTTOM_RIGHT                        0x16F0  
-#define SRC_SC_BOTTOM_RIGHT                    0x16F4  
+#define DP_GUI_MASTER_CNTL                     0x146C
+#define SC_TOP_LEFT                            0x16EC
+#define SC_BOTTOM_RIGHT                        0x16F0
+#define SRC_SC_BOTTOM_RIGHT                    0x16F4
 #define RB2D_DSTCACHE_MODE		       0x3428
 #define RB2D_DSTCACHE_CTLSTAT_broken	       0x342C /* do not use */
 #define LVDS_GEN_CNTL			       0x02d0
@@ -686,7 +686,7 @@
 #define VERT_FP_LOOP_STRETCH			   (0x7 << 28)
 #define VERT_STRETCH_RESERVED			   0xf1000000
 
-/* DAC_CNTL bit constants */   
+/* DAC_CNTL bit constants */
 #define DAC_8BIT_EN                                0x00000100
 #define DAC_4BPP_PIX_ORDER                         0x00000200
 #define DAC_CRC_EN                                 0x00080000
@@ -700,7 +700,7 @@
 #define DAC_CMP_EN                                 (1 <<  3)
 #define DAC_CMP_OUTPUT                             (1 <<  7)
 
-/* DAC_CNTL2 bit constants */   
+/* DAC_CNTL2 bit constants */
 #define DAC2_EXPAND_MODE			   (1 << 14)
 #define DAC2_CMP_EN                                (1 << 7)
 #define DAC2_PALETTE_ACCESS_CNTL                   (1 << 5)
diff --git a/include/video/s1d13xxxfb.h b/include/video/s1d13xxxfb.h
index fe41b84..c3b2a2a 100644
--- a/include/video/s1d13xxxfb.h
+++ b/include/video/s1d13xxxfb.h
@@ -14,13 +14,16 @@
 #define	S1D13XXXFB_H
 
 #define S1D_PALETTE_SIZE		256
-#define S1D13506_CHIP_REV		4	/* expected chip revision number for s1d13506 */
-#define S1D13806_CHIP_REV		7	/* expected chip revision number for s1d13806 */
-#define S1D_FBID			"S1D13806"
-#define S1D_DEVICENAME			"s1d13806fb"
+#define S1D_FBID			"S1D13xxx"
+#define S1D_DEVICENAME			"s1d13xxxfb"
+
+/* S1DREG_REV_CODE register = prod_id (6 bits) + revision (2 bits) */
+#define S1D13505_PROD_ID		0x3	/* 000011 */
+#define S1D13506_PROD_ID		0x4	/* 000100 */
+#define S1D13806_PROD_ID		0x7	/* 000111 */
 
 /* register definitions (tested on s1d13896) */
-#define S1DREG_REV_CODE			0x0000	/* Revision Code Register */
+#define S1DREG_REV_CODE			0x0000	/* Prod + Rev Code Register */
 #define S1DREG_MISC			0x0001	/* Miscellaneous Register */
 #define S1DREG_GPIO_CNF0		0x0004	/* General IO Pins Configuration Register 0 */
 #define S1DREG_GPIO_CNF1		0x0005	/* General IO Pins Configuration Register 1 */
@@ -141,10 +144,11 @@
 	u8	value;
 };
 
-
 struct s1d13xxxfb_par {
 	void __iomem	*regs;
 	unsigned char	display;
+	unsigned char	prod_id;
+	unsigned char	revision;
 
 	unsigned int	pseudo_palette[16];
 #ifdef CONFIG_PM
diff --git a/init/main.c b/init/main.c
index d6b388f..07c8658 100644
--- a/init/main.c
+++ b/init/main.c
@@ -793,6 +793,7 @@
  * makes it inline to init() and it becomes part of init.text section
  */
 static noinline int init_post(void)
+	__releases(kernel_lock)
 {
 	/* need to finish all async __init code before freeing the memory */
 	async_synchronize_full();
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index e886d13..f3db382 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -22,6 +22,7 @@
 #include <linux/console.h>
 #include <linux/cpu.h>
 #include <linux/freezer.h>
+#include <asm/suspend.h>
 
 #include "power.h"
 
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index f5fc2d7..33e2e4a 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -321,13 +321,10 @@
 
 	INIT_LIST_HEAD(list);
 
-	for_each_zone(zone) {
+	for_each_populated_zone(zone) {
 		unsigned long zone_start, zone_end;
 		struct mem_extent *ext, *cur, *aux;
 
-		if (!populated_zone(zone))
-			continue;
-
 		zone_start = zone->zone_start_pfn;
 		zone_end = zone->zone_start_pfn + zone->spanned_pages;
 
@@ -804,8 +801,8 @@
 	struct zone *zone;
 	unsigned int cnt = 0;
 
-	for_each_zone(zone)
-		if (populated_zone(zone) && is_highmem(zone))
+	for_each_populated_zone(zone)
+		if (is_highmem(zone))
 			cnt += zone_page_state(zone, NR_FREE_PAGES);
 
 	return cnt;
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index a92c914..78c3504 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -51,6 +51,7 @@
 #include <linux/highmem.h>
 #include <linux/time.h>
 #include <linux/rbtree.h>
+#include <linux/io.h>
 
 #include "power.h"
 
@@ -229,17 +230,16 @@
 		size = count_data_pages() + PAGES_FOR_IO + SPARE_PAGES;
 		tmp = size;
 		size += highmem_size;
-		for_each_zone (zone)
-			if (populated_zone(zone)) {
-				tmp += snapshot_additional_pages(zone);
-				if (is_highmem(zone)) {
-					highmem_size -=
+		for_each_populated_zone(zone) {
+			tmp += snapshot_additional_pages(zone);
+			if (is_highmem(zone)) {
+				highmem_size -=
 					zone_page_state(zone, NR_FREE_PAGES);
-				} else {
-					tmp -= zone_page_state(zone, NR_FREE_PAGES);
-					tmp += zone->lowmem_reserve[ZONE_NORMAL];
-				}
+			} else {
+				tmp -= zone_page_state(zone, NR_FREE_PAGES);
+				tmp += zone->lowmem_reserve[ZONE_NORMAL];
 			}
+		}
 
 		if (highmem_size < 0)
 			highmem_size = 0;
diff --git a/kernel/sched.c b/kernel/sched.c
index 196d48b..73513f4 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -5196,11 +5196,17 @@
 	__wake_up_common(q, mode, 1, 0, NULL);
 }
 
+void __wake_up_locked_key(wait_queue_head_t *q, unsigned int mode, void *key)
+{
+	__wake_up_common(q, mode, 1, 0, key);
+}
+
 /**
- * __wake_up_sync - wake up threads blocked on a waitqueue.
+ * __wake_up_sync_key - wake up threads blocked on a waitqueue.
  * @q: the waitqueue
  * @mode: which threads
  * @nr_exclusive: how many wake-one or wake-many threads to wake up
+ * @key: opaque value to be passed to wakeup targets
  *
  * The sync wakeup differs that the waker knows that it will schedule
  * away soon, so while the target thread will be woken up, it will not
@@ -5209,8 +5215,8 @@
  *
  * On UP it can prevent extra preemption.
  */
-void
-__wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr_exclusive)
+void __wake_up_sync_key(wait_queue_head_t *q, unsigned int mode,
+			int nr_exclusive, void *key)
 {
 	unsigned long flags;
 	int sync = 1;
@@ -5222,9 +5228,18 @@
 		sync = 0;
 
 	spin_lock_irqsave(&q->lock, flags);
-	__wake_up_common(q, mode, nr_exclusive, sync, NULL);
+	__wake_up_common(q, mode, nr_exclusive, sync, key);
 	spin_unlock_irqrestore(&q->lock, flags);
 }
+EXPORT_SYMBOL_GPL(__wake_up_sync_key);
+
+/*
+ * __wake_up_sync - see __wake_up_sync_key()
+ */
+void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr_exclusive)
+{
+	__wake_up_sync_key(q, mode, nr_exclusive, NULL);
+}
 EXPORT_SYMBOL_GPL(__wake_up_sync);	/* For internal use only */
 
 /**
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c5ef44f..2e490a3 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1010,7 +1010,7 @@
 		.data		= &dirty_expire_interval,
 		.maxlen		= sizeof(dirty_expire_interval),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec_userhz_jiffies,
+		.proc_handler	= &proc_dointvec,
 	},
 	{
 		.ctl_name	= VM_NR_PDFLUSH_THREADS,
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 58bfe7e..9638d99 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -796,6 +796,7 @@
 	  to properly maintain and use. This enables checks that help
 	  you to keep things correct.
 
+source mm/Kconfig.debug
 source kernel/trace/Kconfig
 
 config PROVIDE_OHCI1394_DMA_INIT
diff --git a/lib/rbtree.c b/lib/rbtree.c
index 9956b99..f653659 100644
--- a/lib/rbtree.c
+++ b/lib/rbtree.c
@@ -163,17 +163,14 @@
 			{
 				if (!other->rb_right || rb_is_black(other->rb_right))
 				{
-					struct rb_node *o_left;
-					if ((o_left = other->rb_left))
-						rb_set_black(o_left);
+					rb_set_black(other->rb_left);
 					rb_set_red(other);
 					__rb_rotate_right(other, root);
 					other = parent->rb_right;
 				}
 				rb_set_color(other, rb_color(parent));
 				rb_set_black(parent);
-				if (other->rb_right)
-					rb_set_black(other->rb_right);
+				rb_set_black(other->rb_right);
 				__rb_rotate_left(parent, root);
 				node = root->rb_node;
 				break;
@@ -200,17 +197,14 @@
 			{
 				if (!other->rb_left || rb_is_black(other->rb_left))
 				{
-					register struct rb_node *o_right;
-					if ((o_right = other->rb_right))
-						rb_set_black(o_right);
+					rb_set_black(other->rb_right);
 					rb_set_red(other);
 					__rb_rotate_left(other, root);
 					other = parent->rb_left;
 				}
 				rb_set_color(other, rb_color(parent));
 				rb_set_black(parent);
-				if (other->rb_left)
-					rb_set_black(other->rb_left);
+				rb_set_black(other->rb_left);
 				__rb_rotate_right(parent, root);
 				node = root->rb_node;
 				break;
diff --git a/mm/Kconfig b/mm/Kconfig
index a5b7781..b53427a 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -206,7 +206,6 @@
 config UNEVICTABLE_LRU
 	bool "Add LRU list to track non-evictable pages"
 	default y
-	depends on MMU
 	help
 	  Keeps unevictable pages off of the active and inactive pageout
 	  lists, so kswapd will not waste CPU time or have its balancing
@@ -214,5 +213,13 @@
 	  will use one page flag and increase the code size a little,
 	  say Y unless you know what you are doing.
 
+config HAVE_MLOCK
+	bool
+	default y if MMU=y
+
+config HAVE_MLOCKED_PAGE_BIT
+	bool
+	default y if HAVE_MLOCK=y && UNEVICTABLE_LRU=y
+
 config MMU_NOTIFIER
 	bool
diff --git a/mm/Kconfig.debug b/mm/Kconfig.debug
new file mode 100644
index 0000000..c8d62d4
--- /dev/null
+++ b/mm/Kconfig.debug
@@ -0,0 +1,17 @@
+config WANT_PAGE_DEBUG_FLAGS
+	bool
+
+config PAGE_POISONING
+	bool "Debug page memory allocations"
+	depends on DEBUG_KERNEL && !ARCH_SUPPORTS_DEBUG_PAGEALLOC
+	depends on !HIBERNATION
+	select DEBUG_PAGEALLOC
+	select WANT_PAGE_DEBUG_FLAGS
+	help
+	   Fill the pages with poison patterns after free_pages() and verify
+	   the patterns before alloc_pages(). This results in a large slowdown,
+	   but helps to find certain types of memory corruptions.
+
+	   This option cannot enalbe with hibernation. Otherwise, it will get
+	   wrong messages for memory corruption because the free pages are not
+	   saved to the suspend image.
diff --git a/mm/Makefile b/mm/Makefile
index 818569b..ec73c68 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -24,6 +24,7 @@
 obj-$(CONFIG_TMPFS_POSIX_ACL) += shmem_acl.o
 obj-$(CONFIG_SLOB) += slob.o
 obj-$(CONFIG_MMU_NOTIFIER) += mmu_notifier.o
+obj-$(CONFIG_PAGE_POISONING) += debug-pagealloc.o
 obj-$(CONFIG_SLAB) += slab.o
 obj-$(CONFIG_SLUB) += slub.o
 obj-$(CONFIG_FAILSLAB) += failslab.o
diff --git a/mm/debug-pagealloc.c b/mm/debug-pagealloc.c
new file mode 100644
index 0000000..a1e3324
--- /dev/null
+++ b/mm/debug-pagealloc.c
@@ -0,0 +1,129 @@
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/page-debug-flags.h>
+#include <linux/poison.h>
+
+static inline void set_page_poison(struct page *page)
+{
+	__set_bit(PAGE_DEBUG_FLAG_POISON, &page->debug_flags);
+}
+
+static inline void clear_page_poison(struct page *page)
+{
+	__clear_bit(PAGE_DEBUG_FLAG_POISON, &page->debug_flags);
+}
+
+static inline bool page_poison(struct page *page)
+{
+	return test_bit(PAGE_DEBUG_FLAG_POISON, &page->debug_flags);
+}
+
+static void poison_highpage(struct page *page)
+{
+	/*
+	 * Page poisoning for highmem pages is not implemented.
+	 *
+	 * This can be called from interrupt contexts.
+	 * So we need to create a new kmap_atomic slot for this
+	 * application and it will need interrupt protection.
+	 */
+}
+
+static void poison_page(struct page *page)
+{
+	void *addr;
+
+	if (PageHighMem(page)) {
+		poison_highpage(page);
+		return;
+	}
+	set_page_poison(page);
+	addr = page_address(page);
+	memset(addr, PAGE_POISON, PAGE_SIZE);
+}
+
+static void poison_pages(struct page *page, int n)
+{
+	int i;
+
+	for (i = 0; i < n; i++)
+		poison_page(page + i);
+}
+
+static bool single_bit_flip(unsigned char a, unsigned char b)
+{
+	unsigned char error = a ^ b;
+
+	return error && !(error & (error - 1));
+}
+
+static void check_poison_mem(unsigned char *mem, size_t bytes)
+{
+	unsigned char *start;
+	unsigned char *end;
+
+	for (start = mem; start < mem + bytes; start++) {
+		if (*start != PAGE_POISON)
+			break;
+	}
+	if (start == mem + bytes)
+		return;
+
+	for (end = mem + bytes - 1; end > start; end--) {
+		if (*end != PAGE_POISON)
+			break;
+	}
+
+	if (!printk_ratelimit())
+		return;
+	else if (start == end && single_bit_flip(*start, PAGE_POISON))
+		printk(KERN_ERR "pagealloc: single bit error\n");
+	else
+		printk(KERN_ERR "pagealloc: memory corruption\n");
+
+	print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1, start,
+			end - start + 1, 1);
+	dump_stack();
+}
+
+static void unpoison_highpage(struct page *page)
+{
+	/*
+	 * See comment in poison_highpage().
+	 * Highmem pages should not be poisoned for now
+	 */
+	BUG_ON(page_poison(page));
+}
+
+static void unpoison_page(struct page *page)
+{
+	if (PageHighMem(page)) {
+		unpoison_highpage(page);
+		return;
+	}
+	if (page_poison(page)) {
+		void *addr = page_address(page);
+
+		check_poison_mem(addr, PAGE_SIZE);
+		clear_page_poison(page);
+	}
+}
+
+static void unpoison_pages(struct page *page, int n)
+{
+	int i;
+
+	for (i = 0; i < n; i++)
+		unpoison_page(page + i);
+}
+
+void kernel_map_pages(struct page *page, int numpages, int enable)
+{
+	if (!debug_pagealloc_enabled)
+		return;
+
+	if (enable)
+		unpoison_pages(page, numpages);
+	else
+		poison_pages(page, numpages);
+}
diff --git a/mm/highmem.c b/mm/highmem.c
index 9101980..68eb1d9 100644
--- a/mm/highmem.c
+++ b/mm/highmem.c
@@ -422,3 +422,48 @@
 }
 
 #endif	/* defined(CONFIG_HIGHMEM) && !defined(WANT_PAGE_VIRTUAL) */
+
+#if defined(CONFIG_DEBUG_HIGHMEM) && defined(CONFIG_TRACE_IRQFLAGS_SUPPORT)
+
+void debug_kmap_atomic(enum km_type type)
+{
+	static unsigned warn_count = 10;
+
+	if (unlikely(warn_count == 0))
+		return;
+
+	if (unlikely(in_interrupt())) {
+		if (in_irq()) {
+			if (type != KM_IRQ0 && type != KM_IRQ1 &&
+			    type != KM_BIO_SRC_IRQ && type != KM_BIO_DST_IRQ &&
+			    type != KM_BOUNCE_READ) {
+				WARN_ON(1);
+				warn_count--;
+			}
+		} else if (!irqs_disabled()) {	/* softirq */
+			if (type != KM_IRQ0 && type != KM_IRQ1 &&
+			    type != KM_SOFTIRQ0 && type != KM_SOFTIRQ1 &&
+			    type != KM_SKB_SUNRPC_DATA &&
+			    type != KM_SKB_DATA_SOFTIRQ &&
+			    type != KM_BOUNCE_READ) {
+				WARN_ON(1);
+				warn_count--;
+			}
+		}
+	}
+
+	if (type == KM_IRQ0 || type == KM_IRQ1 || type == KM_BOUNCE_READ ||
+			type == KM_BIO_SRC_IRQ || type == KM_BIO_DST_IRQ) {
+		if (!irqs_disabled()) {
+			WARN_ON(1);
+			warn_count--;
+		}
+	} else if (type == KM_SOFTIRQ0 || type == KM_SOFTIRQ1) {
+		if (irq_count() == 0 && !irqs_disabled()) {
+			WARN_ON(1);
+			warn_count--;
+		}
+	}
+}
+
+#endif
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 107da3d..28c655b 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -918,7 +918,7 @@
  * an instantiated the change should be committed via vma_commit_reservation.
  * No action is required on failure.
  */
-static int vma_needs_reservation(struct hstate *h,
+static long vma_needs_reservation(struct hstate *h,
 			struct vm_area_struct *vma, unsigned long addr)
 {
 	struct address_space *mapping = vma->vm_file->f_mapping;
@@ -933,7 +933,7 @@
 		return 1;
 
 	} else  {
-		int err;
+		long err;
 		pgoff_t idx = vma_hugecache_offset(h, vma, addr);
 		struct resv_map *reservations = vma_resv_map(vma);
 
@@ -969,7 +969,7 @@
 	struct page *page;
 	struct address_space *mapping = vma->vm_file->f_mapping;
 	struct inode *inode = mapping->host;
-	unsigned int chg;
+	long chg;
 
 	/*
 	 * Processes that did not create the mapping will have no reserves and
diff --git a/mm/internal.h b/mm/internal.h
index 478223b..987bb03 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -63,6 +63,7 @@
 	return page_private(page);
 }
 
+#ifdef CONFIG_HAVE_MLOCK
 extern long mlock_vma_pages_range(struct vm_area_struct *vma,
 			unsigned long start, unsigned long end);
 extern void munlock_vma_pages_range(struct vm_area_struct *vma,
@@ -71,6 +72,7 @@
 {
 	munlock_vma_pages_range(vma, vma->vm_start, vma->vm_end);
 }
+#endif
 
 #ifdef CONFIG_UNEVICTABLE_LRU
 /*
@@ -90,7 +92,7 @@
 }
 #endif
 
-#ifdef CONFIG_UNEVICTABLE_LRU
+#ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT
 /*
  * Called only in fault path via page_evictable() for a new page
  * to determine if it's being mapped into a LOCKED vma.
@@ -165,7 +167,7 @@
 	}
 }
 
-#else /* CONFIG_UNEVICTABLE_LRU */
+#else /* CONFIG_HAVE_MLOCKED_PAGE_BIT */
 static inline int is_mlocked_vma(struct vm_area_struct *v, struct page *p)
 {
 	return 0;
@@ -175,7 +177,7 @@
 static inline void mlock_migrate_page(struct page *new, struct page *old) { }
 static inline void free_page_mlock(struct page *page) { }
 
-#endif /* CONFIG_UNEVICTABLE_LRU */
+#endif /* CONFIG_HAVE_MLOCKED_PAGE_BIT */
 
 /*
  * Return the mem_map entry representing the 'offset' subpage within
diff --git a/mm/memory.c b/mm/memory.c
index 2032ad2..cf6873e 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1151,6 +1151,11 @@
 		if ((flags & FOLL_WRITE) &&
 		    !pte_dirty(pte) && !PageDirty(page))
 			set_page_dirty(page);
+		/*
+		 * pte_mkyoung() would be more correct here, but atomic care
+		 * is needed to avoid losing the dirty bit: it is easier to use
+		 * mark_page_accessed().
+		 */
 		mark_page_accessed(page);
 	}
 unlock:
@@ -1940,6 +1945,15 @@
 		 * get_user_pages(.write=1, .force=1).
 		 */
 		if (vma->vm_ops && vma->vm_ops->page_mkwrite) {
+			struct vm_fault vmf;
+			int tmp;
+
+			vmf.virtual_address = (void __user *)(address &
+								PAGE_MASK);
+			vmf.pgoff = old_page->index;
+			vmf.flags = FAULT_FLAG_WRITE|FAULT_FLAG_MKWRITE;
+			vmf.page = old_page;
+
 			/*
 			 * Notify the address space that the page is about to
 			 * become writable so that it can prohibit this or wait
@@ -1951,8 +1965,12 @@
 			page_cache_get(old_page);
 			pte_unmap_unlock(page_table, ptl);
 
-			if (vma->vm_ops->page_mkwrite(vma, old_page) < 0)
+			tmp = vma->vm_ops->page_mkwrite(vma, &vmf);
+			if (unlikely(tmp &
+					(VM_FAULT_ERROR | VM_FAULT_NOPAGE))) {
+				ret = tmp;
 				goto unwritable_page;
+			}
 
 			/*
 			 * Since we dropped the lock we need to revalidate
@@ -2101,7 +2119,7 @@
 
 unwritable_page:
 	page_cache_release(old_page);
-	return VM_FAULT_SIGBUS;
+	return ret;
 }
 
 /*
@@ -2435,8 +2453,6 @@
 		count_vm_event(PGMAJFAULT);
 	}
 
-	mark_page_accessed(page);
-
 	lock_page(page);
 	delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
 
@@ -2645,9 +2661,14 @@
 			 * to become writable
 			 */
 			if (vma->vm_ops->page_mkwrite) {
+				int tmp;
+
 				unlock_page(page);
-				if (vma->vm_ops->page_mkwrite(vma, page) < 0) {
-					ret = VM_FAULT_SIGBUS;
+				vmf.flags |= FAULT_FLAG_MKWRITE;
+				tmp = vma->vm_ops->page_mkwrite(vma, &vmf);
+				if (unlikely(tmp &
+					  (VM_FAULT_ERROR | VM_FAULT_NOPAGE))) {
+					ret = tmp;
 					anon = 1; /* no anon but release vmf.page */
 					goto out_unlocked;
 				}
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 40ba050..d3b9bac 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -55,7 +55,7 @@
 
 unsigned long badness(struct task_struct *p, unsigned long uptime)
 {
-	unsigned long points, cpu_time, run_time, s;
+	unsigned long points, cpu_time, run_time;
 	struct mm_struct *mm;
 	struct task_struct *child;
 
@@ -110,12 +110,10 @@
 	else
 		run_time = 0;
 
-	s = int_sqrt(cpu_time);
-	if (s)
-		points /= s;
-	s = int_sqrt(int_sqrt(run_time));
-	if (s)
-		points /= s;
+	if (cpu_time)
+		points /= int_sqrt(cpu_time);
+	if (run_time)
+		points /= int_sqrt(int_sqrt(run_time));
 
 	/*
 	 * Niced processes are most likely less important, so double
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 40ca7cd..30351f0 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -92,14 +92,14 @@
 unsigned long vm_dirty_bytes;
 
 /*
- * The interval between `kupdate'-style writebacks, in jiffies
+ * The interval between `kupdate'-style writebacks
  */
-int dirty_writeback_interval = 5 * HZ;
+unsigned int dirty_writeback_interval = 5 * 100; /* sentiseconds */
 
 /*
- * The longest number of jiffies for which data is allowed to remain dirty
+ * The longest time for which data is allowed to remain dirty
  */
-int dirty_expire_interval = 30 * HZ;
+unsigned int dirty_expire_interval = 30 * 100; /* sentiseconds */
 
 /*
  * Flag that makes the machine dump writes/reads and block dirtyings.
@@ -770,9 +770,9 @@
 
 	sync_supers();
 
-	oldest_jif = jiffies - dirty_expire_interval;
+	oldest_jif = jiffies - msecs_to_jiffies(dirty_expire_interval);
 	start_jif = jiffies;
-	next_jif = start_jif + dirty_writeback_interval;
+	next_jif = start_jif + msecs_to_jiffies(dirty_writeback_interval * 10);
 	nr_to_write = global_page_state(NR_FILE_DIRTY) +
 			global_page_state(NR_UNSTABLE_NFS) +
 			(inodes_stat.nr_inodes - inodes_stat.nr_unused);
@@ -801,9 +801,10 @@
 int dirty_writeback_centisecs_handler(ctl_table *table, int write,
 	struct file *file, void __user *buffer, size_t *length, loff_t *ppos)
 {
-	proc_dointvec_userhz_jiffies(table, write, file, buffer, length, ppos);
+	proc_dointvec(table, write, file, buffer, length, ppos);
 	if (dirty_writeback_interval)
-		mod_timer(&wb_timer, jiffies + dirty_writeback_interval);
+		mod_timer(&wb_timer, jiffies +
+			msecs_to_jiffies(dirty_writeback_interval * 10));
 	else
 		del_timer(&wb_timer);
 	return 0;
@@ -905,7 +906,8 @@
 {
 	int shift;
 
-	mod_timer(&wb_timer, jiffies + dirty_writeback_interval);
+	mod_timer(&wb_timer,
+		  jiffies + msecs_to_jiffies(dirty_writeback_interval * 10));
 	writeback_set_ratelimit();
 	register_cpu_notifier(&ratelimit_nb);
 
@@ -1198,6 +1200,20 @@
 }
 
 /*
+ * Helper function for set_page_dirty family.
+ * NOTE: This relies on being atomic wrt interrupts.
+ */
+void account_page_dirtied(struct page *page, struct address_space *mapping)
+{
+	if (mapping_cap_account_dirty(mapping)) {
+		__inc_zone_page_state(page, NR_FILE_DIRTY);
+		__inc_bdi_stat(mapping->backing_dev_info, BDI_RECLAIMABLE);
+		task_dirty_inc(current);
+		task_io_account_write(PAGE_CACHE_SIZE);
+	}
+}
+
+/*
  * For address_spaces which do not use buffers.  Just tag the page as dirty in
  * its radix tree.
  *
@@ -1226,13 +1242,7 @@
 		if (mapping2) { /* Race with truncate? */
 			BUG_ON(mapping2 != mapping);
 			WARN_ON_ONCE(!PagePrivate(page) && !PageUptodate(page));
-			if (mapping_cap_account_dirty(mapping)) {
-				__inc_zone_page_state(page, NR_FILE_DIRTY);
-				__inc_bdi_stat(mapping->backing_dev_info,
-						BDI_RECLAIMABLE);
-				task_dirty_inc(current);
-				task_io_account_write(PAGE_CACHE_SIZE);
-			}
+			account_page_dirtied(page, mapping);
 			radix_tree_tag_set(&mapping->page_tree,
 				page_index(page), PAGECACHE_TAG_DIRTY);
 		}
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index a3803ea..0284e52 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -922,13 +922,10 @@
 	unsigned long flags;
 	struct zone *zone;
 
-	for_each_zone(zone) {
+	for_each_populated_zone(zone) {
 		struct per_cpu_pageset *pset;
 		struct per_cpu_pages *pcp;
 
-		if (!populated_zone(zone))
-			continue;
-
 		pset = zone_pcp(zone, cpu);
 
 		pcp = &pset->pcp;
@@ -1585,7 +1582,8 @@
 	reclaim_state.reclaimed_slab = 0;
 	p->reclaim_state = &reclaim_state;
 
-	did_some_progress = try_to_free_pages(zonelist, order, gfp_mask);
+	did_some_progress = try_to_free_pages(zonelist, order,
+						gfp_mask, nodemask);
 
 	p->reclaim_state = NULL;
 	lockdep_clear_current_reclaim_state();
@@ -1879,10 +1877,7 @@
 	int cpu;
 	struct zone *zone;
 
-	for_each_zone(zone) {
-		if (!populated_zone(zone))
-			continue;
-
+	for_each_populated_zone(zone) {
 		show_node(zone);
 		printk("%s per-cpu:\n", zone->name);
 
@@ -1922,12 +1917,9 @@
 		global_page_state(NR_PAGETABLE),
 		global_page_state(NR_BOUNCE));
 
-	for_each_zone(zone) {
+	for_each_populated_zone(zone) {
 		int i;
 
-		if (!populated_zone(zone))
-			continue;
-
 		show_node(zone);
 		printk("%s"
 			" free:%lukB"
@@ -1967,12 +1959,9 @@
 		printk("\n");
 	}
 
-	for_each_zone(zone) {
+	for_each_populated_zone(zone) {
  		unsigned long nr[MAX_ORDER], flags, order, total = 0;
 
-		if (!populated_zone(zone))
-			continue;
-
 		show_node(zone);
 		printk("%s: ", zone->name);
 
@@ -2784,11 +2773,7 @@
 
 	node_set_state(node, N_CPU);	/* this node has a cpu */
 
-	for_each_zone(zone) {
-
-		if (!populated_zone(zone))
-			continue;
-
+	for_each_populated_zone(zone) {
 		zone_pcp(zone, cpu) = kmalloc_node(sizeof(struct per_cpu_pageset),
 					 GFP_KERNEL, node);
 		if (!zone_pcp(zone, cpu))
diff --git a/mm/shmem.c b/mm/shmem.c
index 7ec78e2..d94d2e9 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1068,8 +1068,7 @@
 		swap_duplicate(swap);
 		BUG_ON(page_mapped(page));
 		page_cache_release(page);	/* pagecache ref */
-		set_page_dirty(page);
-		unlock_page(page);
+		swap_writepage(page, wbc);
 		if (inode) {
 			mutex_lock(&shmem_swaplist_mutex);
 			/* move instead of add in case we're racing */
diff --git a/mm/sparse.c b/mm/sparse.c
index 083f5b6..da432d9 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -164,9 +164,7 @@
 		WARN_ON_ONCE(1);
 		*start_pfn = max_sparsemem_pfn;
 		*end_pfn = max_sparsemem_pfn;
-	}
-
-	if (*end_pfn > max_sparsemem_pfn) {
+	} else if (*end_pfn > max_sparsemem_pfn) {
 		mminit_dprintk(MMINIT_WARNING, "pfnvalidation",
 			"End of range %lu -> %lu exceeds SPARSEMEM max %lu\n",
 			*start_pfn, *end_pfn, max_sparsemem_pfn);
diff --git a/mm/swap.c b/mm/swap.c
index 8adb9fe..6e83084 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -457,29 +457,6 @@
 }
 
 /**
- * pagevec_swap_free - try to free swap space from the pages in a pagevec
- * @pvec: pagevec with swapcache pages to free the swap space of
- *
- * The caller needs to hold an extra reference to each page and
- * not hold the page lock on the pages.  This function uses a
- * trylock on the page lock so it may not always free the swap
- * space associated with a page.
- */
-void pagevec_swap_free(struct pagevec *pvec)
-{
-	int i;
-
-	for (i = 0; i < pagevec_count(pvec); i++) {
-		struct page *page = pvec->pages[i];
-
-		if (PageSwapCache(page) && trylock_page(page)) {
-			try_to_free_swap(page);
-			unlock_page(page);
-		}
-	}
-}
-
-/**
  * pagevec_lookup - gang pagecache lookup
  * @pvec:	Where the resulting pages are placed
  * @mapping:	The address_space to search
diff --git a/mm/util.c b/mm/util.c
index 37eaccd..7c122e4 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -70,6 +70,36 @@
 EXPORT_SYMBOL(kmemdup);
 
 /**
+ * memdup_user - duplicate memory region from user space
+ *
+ * @src: source address in user space
+ * @len: number of bytes to copy
+ *
+ * Returns an ERR_PTR() on failure.
+ */
+void *memdup_user(const void __user *src, size_t len)
+{
+	void *p;
+
+	/*
+	 * Always use GFP_KERNEL, since copy_from_user() can sleep and
+	 * cause pagefault, which makes it pointless to use GFP_NOFS
+	 * or GFP_ATOMIC.
+	 */
+	p = kmalloc_track_caller(len, GFP_KERNEL);
+	if (!p)
+		return ERR_PTR(-ENOMEM);
+
+	if (copy_from_user(p, src, len)) {
+		kfree(p);
+		return ERR_PTR(-EFAULT);
+	}
+
+	return p;
+}
+EXPORT_SYMBOL(memdup_user);
+
+/**
  * __krealloc - like krealloc() but don't free @p.
  * @p: object to reallocate memory for.
  * @new_size: how many bytes of memory are required.
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index af58324..fab1987 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -671,10 +671,7 @@
 	DECLARE_BITMAP(alloc_map, VMAP_BBMAP_BITS);
 	DECLARE_BITMAP(dirty_map, VMAP_BBMAP_BITS);
 	union {
-		struct {
-			struct list_head free_list;
-			struct list_head dirty_list;
-		};
+		struct list_head free_list;
 		struct rcu_head rcu_head;
 	};
 };
@@ -741,7 +738,6 @@
 	bitmap_zero(vb->alloc_map, VMAP_BBMAP_BITS);
 	bitmap_zero(vb->dirty_map, VMAP_BBMAP_BITS);
 	INIT_LIST_HEAD(&vb->free_list);
-	INIT_LIST_HEAD(&vb->dirty_list);
 
 	vb_idx = addr_to_vb_idx(va->va_start);
 	spin_lock(&vmap_block_tree_lock);
@@ -772,12 +768,7 @@
 	struct vmap_block *tmp;
 	unsigned long vb_idx;
 
-	spin_lock(&vb->vbq->lock);
-	if (!list_empty(&vb->free_list))
-		list_del(&vb->free_list);
-	if (!list_empty(&vb->dirty_list))
-		list_del(&vb->dirty_list);
-	spin_unlock(&vb->vbq->lock);
+	BUG_ON(!list_empty(&vb->free_list));
 
 	vb_idx = addr_to_vb_idx(vb->va->va_start);
 	spin_lock(&vmap_block_tree_lock);
@@ -862,11 +853,7 @@
 
 	spin_lock(&vb->lock);
 	bitmap_allocate_region(vb->dirty_map, offset >> PAGE_SHIFT, order);
-	if (!vb->dirty) {
-		spin_lock(&vb->vbq->lock);
-		list_add(&vb->dirty_list, &vb->vbq->dirty);
-		spin_unlock(&vb->vbq->lock);
-	}
+
 	vb->dirty += 1UL << order;
 	if (vb->dirty == VMAP_BBMAP_BITS) {
 		BUG_ON(vb->free || !list_empty(&vb->free_list));
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 479e467..06e7269 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -60,8 +60,8 @@
 
 	int may_writepage;
 
-	/* Can pages be swapped as part of reclaim? */
-	int may_swap;
+	/* Can mapped pages be reclaimed? */
+	int may_unmap;
 
 	/* This context's SWAP_CLUSTER_MAX. If freeing memory for
 	 * suspend, we effectively ignore SWAP_CLUSTER_MAX.
@@ -78,6 +78,12 @@
 	/* Which cgroup do we reclaim from */
 	struct mem_cgroup *mem_cgroup;
 
+	/*
+	 * Nodemask of nodes allowed by the caller. If NULL, all nodes
+	 * are scanned.
+	 */
+	nodemask_t	*nodemask;
+
 	/* Pluggable isolate pages callback */
 	unsigned long (*isolate_pages)(unsigned long nr, struct list_head *dst,
 			unsigned long *scanned, int order, int mode,
@@ -214,8 +220,9 @@
 		do_div(delta, lru_pages + 1);
 		shrinker->nr += delta;
 		if (shrinker->nr < 0) {
-			printk(KERN_ERR "%s: nr=%ld\n",
-					__func__, shrinker->nr);
+			printk(KERN_ERR "shrink_slab: %pF negative objects to "
+			       "delete nr=%ld\n",
+			       shrinker->shrink, shrinker->nr);
 			shrinker->nr = max_pass;
 		}
 
@@ -606,7 +613,7 @@
 		if (unlikely(!page_evictable(page, NULL)))
 			goto cull_mlocked;
 
-		if (!sc->may_swap && page_mapped(page))
+		if (!sc->may_unmap && page_mapped(page))
 			goto keep_locked;
 
 		/* Double the slab pressure for mapped and swapcache pages */
@@ -1298,17 +1305,11 @@
 	}
 	__mod_zone_page_state(zone, NR_LRU_BASE + lru, pgmoved);
 	pgdeactivate += pgmoved;
-	if (buffer_heads_over_limit) {
-		spin_unlock_irq(&zone->lru_lock);
-		pagevec_strip(&pvec);
-		spin_lock_irq(&zone->lru_lock);
-	}
 	__count_zone_vm_events(PGREFILL, zone, pgscanned);
 	__count_vm_events(PGDEACTIVATE, pgdeactivate);
 	spin_unlock_irq(&zone->lru_lock);
-	if (vm_swap_full())
-		pagevec_swap_free(&pvec);
-
+	if (buffer_heads_over_limit)
+		pagevec_strip(&pvec);
 	pagevec_release(&pvec);
 }
 
@@ -1543,7 +1544,8 @@
 	struct zone *zone;
 
 	sc->all_unreclaimable = 1;
-	for_each_zone_zonelist(zone, z, zonelist, high_zoneidx) {
+	for_each_zone_zonelist_nodemask(zone, z, zonelist, high_zoneidx,
+					sc->nodemask) {
 		if (!populated_zone(zone))
 			continue;
 		/*
@@ -1688,17 +1690,18 @@
 }
 
 unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
-								gfp_t gfp_mask)
+				gfp_t gfp_mask, nodemask_t *nodemask)
 {
 	struct scan_control sc = {
 		.gfp_mask = gfp_mask,
 		.may_writepage = !laptop_mode,
 		.swap_cluster_max = SWAP_CLUSTER_MAX,
-		.may_swap = 1,
+		.may_unmap = 1,
 		.swappiness = vm_swappiness,
 		.order = order,
 		.mem_cgroup = NULL,
 		.isolate_pages = isolate_pages_global,
+		.nodemask = nodemask,
 	};
 
 	return do_try_to_free_pages(zonelist, &sc);
@@ -1713,17 +1716,18 @@
 {
 	struct scan_control sc = {
 		.may_writepage = !laptop_mode,
-		.may_swap = 1,
+		.may_unmap = 1,
 		.swap_cluster_max = SWAP_CLUSTER_MAX,
 		.swappiness = swappiness,
 		.order = 0,
 		.mem_cgroup = mem_cont,
 		.isolate_pages = mem_cgroup_isolate_pages,
+		.nodemask = NULL, /* we don't care the placement */
 	};
 	struct zonelist *zonelist;
 
 	if (noswap)
-		sc.may_swap = 0;
+		sc.may_unmap = 0;
 
 	sc.gfp_mask = (gfp_mask & GFP_RECLAIM_MASK) |
 			(GFP_HIGHUSER_MOVABLE & ~GFP_RECLAIM_MASK);
@@ -1762,7 +1766,7 @@
 	struct reclaim_state *reclaim_state = current->reclaim_state;
 	struct scan_control sc = {
 		.gfp_mask = GFP_KERNEL,
-		.may_swap = 1,
+		.may_unmap = 1,
 		.swap_cluster_max = SWAP_CLUSTER_MAX,
 		.swappiness = vm_swappiness,
 		.order = order,
@@ -2050,22 +2054,19 @@
 #ifdef CONFIG_PM
 /*
  * Helper function for shrink_all_memory().  Tries to reclaim 'nr_pages' pages
- * from LRU lists system-wide, for given pass and priority, and returns the
- * number of reclaimed pages
+ * from LRU lists system-wide, for given pass and priority.
  *
  * For pass > 3 we also try to shrink the LRU lists that contain a few pages
  */
-static unsigned long shrink_all_zones(unsigned long nr_pages, int prio,
+static void shrink_all_zones(unsigned long nr_pages, int prio,
 				      int pass, struct scan_control *sc)
 {
 	struct zone *zone;
-	unsigned long ret = 0;
+	unsigned long nr_reclaimed = 0;
 
-	for_each_zone(zone) {
+	for_each_populated_zone(zone) {
 		enum lru_list l;
 
-		if (!populated_zone(zone))
-			continue;
 		if (zone_is_all_unreclaimable(zone) && prio != DEF_PRIORITY)
 			continue;
 
@@ -2084,14 +2085,16 @@
 
 				zone->lru[l].nr_scan = 0;
 				nr_to_scan = min(nr_pages, lru_pages);
-				ret += shrink_list(l, nr_to_scan, zone,
+				nr_reclaimed += shrink_list(l, nr_to_scan, zone,
 								sc, prio);
-				if (ret >= nr_pages)
-					return ret;
+				if (nr_reclaimed >= nr_pages) {
+					sc->nr_reclaimed = nr_reclaimed;
+					return;
+				}
 			}
 		}
 	}
-	return ret;
+	sc->nr_reclaimed = nr_reclaimed;
 }
 
 /*
@@ -2105,13 +2108,11 @@
 unsigned long shrink_all_memory(unsigned long nr_pages)
 {
 	unsigned long lru_pages, nr_slab;
-	unsigned long ret = 0;
 	int pass;
 	struct reclaim_state reclaim_state;
 	struct scan_control sc = {
 		.gfp_mask = GFP_KERNEL,
-		.may_swap = 0,
-		.swap_cluster_max = nr_pages,
+		.may_unmap = 0,
 		.may_writepage = 1,
 		.isolate_pages = isolate_pages_global,
 	};
@@ -2127,8 +2128,8 @@
 		if (!reclaim_state.reclaimed_slab)
 			break;
 
-		ret += reclaim_state.reclaimed_slab;
-		if (ret >= nr_pages)
+		sc.nr_reclaimed += reclaim_state.reclaimed_slab;
+		if (sc.nr_reclaimed >= nr_pages)
 			goto out;
 
 		nr_slab -= reclaim_state.reclaimed_slab;
@@ -2147,21 +2148,22 @@
 
 		/* Force reclaiming mapped pages in the passes #3 and #4 */
 		if (pass > 2)
-			sc.may_swap = 1;
+			sc.may_unmap = 1;
 
 		for (prio = DEF_PRIORITY; prio >= 0; prio--) {
-			unsigned long nr_to_scan = nr_pages - ret;
+			unsigned long nr_to_scan = nr_pages - sc.nr_reclaimed;
 
 			sc.nr_scanned = 0;
-			ret += shrink_all_zones(nr_to_scan, prio, pass, &sc);
-			if (ret >= nr_pages)
+			sc.swap_cluster_max = nr_to_scan;
+			shrink_all_zones(nr_to_scan, prio, pass, &sc);
+			if (sc.nr_reclaimed >= nr_pages)
 				goto out;
 
 			reclaim_state.reclaimed_slab = 0;
 			shrink_slab(sc.nr_scanned, sc.gfp_mask,
 					global_lru_pages());
-			ret += reclaim_state.reclaimed_slab;
-			if (ret >= nr_pages)
+			sc.nr_reclaimed += reclaim_state.reclaimed_slab;
+			if (sc.nr_reclaimed >= nr_pages)
 				goto out;
 
 			if (sc.nr_scanned && prio < DEF_PRIORITY - 2)
@@ -2170,21 +2172,23 @@
 	}
 
 	/*
-	 * If ret = 0, we could not shrink LRUs, but there may be something
-	 * in slab caches
+	 * If sc.nr_reclaimed = 0, we could not shrink LRUs, but there may be
+	 * something in slab caches
 	 */
-	if (!ret) {
+	if (!sc.nr_reclaimed) {
 		do {
 			reclaim_state.reclaimed_slab = 0;
 			shrink_slab(nr_pages, sc.gfp_mask, global_lru_pages());
-			ret += reclaim_state.reclaimed_slab;
-		} while (ret < nr_pages && reclaim_state.reclaimed_slab > 0);
+			sc.nr_reclaimed += reclaim_state.reclaimed_slab;
+		} while (sc.nr_reclaimed < nr_pages &&
+				reclaim_state.reclaimed_slab > 0);
 	}
 
+
 out:
 	current->reclaim_state = NULL;
 
-	return ret;
+	return sc.nr_reclaimed;
 }
 #endif
 
@@ -2290,11 +2294,12 @@
 	int priority;
 	struct scan_control sc = {
 		.may_writepage = !!(zone_reclaim_mode & RECLAIM_WRITE),
-		.may_swap = !!(zone_reclaim_mode & RECLAIM_SWAP),
+		.may_unmap = !!(zone_reclaim_mode & RECLAIM_SWAP),
 		.swap_cluster_max = max_t(unsigned long, nr_pages,
 					SWAP_CLUSTER_MAX),
 		.gfp_mask = gfp_mask,
 		.swappiness = vm_swappiness,
+		.order = order,
 		.isolate_pages = isolate_pages_global,
 	};
 	unsigned long slab_reclaimable;
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 8cd81ea..9826766 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -135,11 +135,7 @@
 	int cpu;
 	int threshold;
 
-	for_each_zone(zone) {
-
-		if (!zone->present_pages)
-			continue;
-
+	for_each_populated_zone(zone) {
 		threshold = calculate_threshold(zone);
 
 		for_each_online_cpu(cpu)
@@ -301,12 +297,9 @@
 	int i;
 	int global_diff[NR_VM_ZONE_STAT_ITEMS] = { 0, };
 
-	for_each_zone(zone) {
+	for_each_populated_zone(zone) {
 		struct per_cpu_pageset *p;
 
-		if (!populated_zone(zone))
-			continue;
-
 		p = zone_pcp(zone, cpu);
 
 		for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index abdc703..cab71ea 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -1093,11 +1093,6 @@
 	}
 }
 
-static int rfcomm_tty_read_proc(char *buf, char **start, off_t offset, int len, int *eof, void *unused)
-{
-	return 0;
-}
-
 static int rfcomm_tty_tiocmget(struct tty_struct *tty, struct file *filp)
 {
 	struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
@@ -1156,7 +1151,6 @@
 	.send_xchar		= rfcomm_tty_send_xchar,
 	.hangup			= rfcomm_tty_hangup,
 	.wait_until_sent	= rfcomm_tty_wait_until_sent,
-	.read_proc		= rfcomm_tty_read_proc,
 	.tiocmget		= rfcomm_tty_tiocmget,
 	.tiocmset		= rfcomm_tty_tiocmset,
 };
diff --git a/net/core/sock.c b/net/core/sock.c
index 0620046..7dbf3ff 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1677,7 +1677,7 @@
 {
 	read_lock(&sk->sk_callback_lock);
 	if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
-		wake_up_interruptible(sk->sk_sleep);
+		wake_up_interruptible_poll(sk->sk_sleep, POLLERR);
 	sk_wake_async(sk, SOCK_WAKE_IO, POLL_ERR);
 	read_unlock(&sk->sk_callback_lock);
 }
@@ -1686,7 +1686,8 @@
 {
 	read_lock(&sk->sk_callback_lock);
 	if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
-		wake_up_interruptible_sync(sk->sk_sleep);
+		wake_up_interruptible_sync_poll(sk->sk_sleep, POLLIN |
+						POLLRDNORM | POLLRDBAND);
 	sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
 	read_unlock(&sk->sk_callback_lock);
 }
@@ -1700,7 +1701,8 @@
 	 */
 	if ((atomic_read(&sk->sk_wmem_alloc) << 1) <= sk->sk_sndbuf) {
 		if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
-			wake_up_interruptible_sync(sk->sk_sleep);
+			wake_up_interruptible_sync_poll(sk->sk_sleep, POLLOUT |
+						POLLWRNORM | POLLWRBAND);
 
 		/* Should agree with poll, otherwise some programs break */
 		if (sock_writeable(sk))
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 086d5ef..811984d 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -34,6 +34,7 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
+#include <linux/seq_file.h>
 #include <linux/termios.h>
 #include <linux/tty.h>
 #include <linux/interrupt.h>
@@ -72,8 +73,7 @@
 static void ircomm_tty_flow_indication(void *instance, void *sap,
 				       LOCAL_FLOW cmd);
 #ifdef CONFIG_PROC_FS
-static int ircomm_tty_read_proc(char *buf, char **start, off_t offset, int len,
-				int *eof, void *unused);
+static const struct file_operations ircomm_tty_proc_fops;
 #endif /* CONFIG_PROC_FS */
 static struct tty_driver *driver;
 
@@ -98,7 +98,7 @@
 	.hangup          = ircomm_tty_hangup,
 	.wait_until_sent = ircomm_tty_wait_until_sent,
 #ifdef CONFIG_PROC_FS
-	.read_proc       = ircomm_tty_read_proc,
+	.proc_fops       = &ircomm_tty_proc_fops,
 #endif /* CONFIG_PROC_FS */
 };
 
@@ -1245,150 +1245,170 @@
 }
 
 #ifdef CONFIG_PROC_FS
-static int ircomm_tty_line_info(struct ircomm_tty_cb *self, char *buf)
+static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m)
 {
-	int  ret=0;
+	char sep;
 
-	ret += sprintf(buf+ret, "State: %s\n", ircomm_tty_state[self->state]);
+	seq_printf(m, "State: %s\n", ircomm_tty_state[self->state]);
 
-	ret += sprintf(buf+ret, "Service type: ");
+	seq_puts(m, "Service type: ");
 	if (self->service_type & IRCOMM_9_WIRE)
-		ret += sprintf(buf+ret, "9_WIRE");
+		seq_puts(m, "9_WIRE");
 	else if (self->service_type & IRCOMM_3_WIRE)
-		ret += sprintf(buf+ret, "3_WIRE");
+		seq_puts(m, "3_WIRE");
 	else if (self->service_type & IRCOMM_3_WIRE_RAW)
-		ret += sprintf(buf+ret, "3_WIRE_RAW");
+		seq_puts(m, "3_WIRE_RAW");
 	else
-		ret += sprintf(buf+ret, "No common service type!\n");
-	ret += sprintf(buf+ret, "\n");
+		seq_puts(m, "No common service type!\n");
+	seq_putc(m, '\n');
 
-	ret += sprintf(buf+ret, "Port name: %s\n", self->settings.port_name);
+	seq_printf(m, "Port name: %s\n", self->settings.port_name);
 
-	ret += sprintf(buf+ret, "DTE status: ");
-	if (self->settings.dte & IRCOMM_RTS)
-		ret += sprintf(buf+ret, "RTS|");
-	if (self->settings.dte & IRCOMM_DTR)
-		ret += sprintf(buf+ret, "DTR|");
-	if (self->settings.dte)
-		ret--; /* remove the last | */
-	ret += sprintf(buf+ret, "\n");
+	seq_printf(m, "DTE status:");
+	sep = ' ';
+	if (self->settings.dte & IRCOMM_RTS) {
+		seq_printf(m, "%cRTS", sep);
+		sep = '|';
+	}
+	if (self->settings.dte & IRCOMM_DTR) {
+		seq_printf(m, "%cDTR", sep);
+		sep = '|';
+	}
+	seq_putc(m, '\n');
 
-	ret += sprintf(buf+ret, "DCE status: ");
-	if (self->settings.dce & IRCOMM_CTS)
-		ret += sprintf(buf+ret, "CTS|");
-	if (self->settings.dce & IRCOMM_DSR)
-		ret += sprintf(buf+ret, "DSR|");
-	if (self->settings.dce & IRCOMM_CD)
-		ret += sprintf(buf+ret, "CD|");
-	if (self->settings.dce & IRCOMM_RI)
-		ret += sprintf(buf+ret, "RI|");
-	if (self->settings.dce)
-		ret--; /* remove the last | */
-	ret += sprintf(buf+ret, "\n");
+	seq_puts(m, "DCE status:");
+	sep = ' ';
+	if (self->settings.dce & IRCOMM_CTS) {
+		seq_printf(m, "%cCTS", sep);
+		sep = '|';
+	}
+	if (self->settings.dce & IRCOMM_DSR) {
+		seq_printf(m, "%cDSR", sep);
+		sep = '|';
+	}
+	if (self->settings.dce & IRCOMM_CD) {
+		seq_printf(m, "%cCD", sep);
+		sep = '|';
+	}
+	if (self->settings.dce & IRCOMM_RI) {
+		seq_printf(m, "%cRI", sep);
+		sep = '|';
+	}
+	seq_putc(m, '\n');
 
-	ret += sprintf(buf+ret, "Configuration: ");
+	seq_puts(m, "Configuration: ");
 	if (!self->settings.null_modem)
-		ret += sprintf(buf+ret, "DTE <-> DCE\n");
+		seq_puts(m, "DTE <-> DCE\n");
 	else
-		ret += sprintf(buf+ret,
-			       "DTE <-> DTE (null modem emulation)\n");
+		seq_puts(m, "DTE <-> DTE (null modem emulation)\n");
 
-	ret += sprintf(buf+ret, "Data rate: %d\n", self->settings.data_rate);
+	seq_printf(m, "Data rate: %d\n", self->settings.data_rate);
 
-	ret += sprintf(buf+ret, "Flow control: ");
-	if (self->settings.flow_control & IRCOMM_XON_XOFF_IN)
-		ret += sprintf(buf+ret, "XON_XOFF_IN|");
-	if (self->settings.flow_control & IRCOMM_XON_XOFF_OUT)
-		ret += sprintf(buf+ret, "XON_XOFF_OUT|");
-	if (self->settings.flow_control & IRCOMM_RTS_CTS_IN)
-		ret += sprintf(buf+ret, "RTS_CTS_IN|");
-	if (self->settings.flow_control & IRCOMM_RTS_CTS_OUT)
-		ret += sprintf(buf+ret, "RTS_CTS_OUT|");
-	if (self->settings.flow_control & IRCOMM_DSR_DTR_IN)
-		ret += sprintf(buf+ret, "DSR_DTR_IN|");
-	if (self->settings.flow_control & IRCOMM_DSR_DTR_OUT)
-		ret += sprintf(buf+ret, "DSR_DTR_OUT|");
-	if (self->settings.flow_control & IRCOMM_ENQ_ACK_IN)
-		ret += sprintf(buf+ret, "ENQ_ACK_IN|");
-	if (self->settings.flow_control & IRCOMM_ENQ_ACK_OUT)
-		ret += sprintf(buf+ret, "ENQ_ACK_OUT|");
-	if (self->settings.flow_control)
-		ret--; /* remove the last | */
-	ret += sprintf(buf+ret, "\n");
+	seq_puts(m, "Flow control:");
+	sep = ' ';
+	if (self->settings.flow_control & IRCOMM_XON_XOFF_IN) {
+		seq_printf(m, "%cXON_XOFF_IN", sep);
+		sep = '|';
+	}
+	if (self->settings.flow_control & IRCOMM_XON_XOFF_OUT) {
+		seq_printf(m, "%cXON_XOFF_OUT", sep);
+		sep = '|';
+	}
+	if (self->settings.flow_control & IRCOMM_RTS_CTS_IN) {
+		seq_printf(m, "%cRTS_CTS_IN", sep);
+		sep = '|';
+	}
+	if (self->settings.flow_control & IRCOMM_RTS_CTS_OUT) {
+		seq_printf(m, "%cRTS_CTS_OUT", sep);
+		sep = '|';
+	}
+	if (self->settings.flow_control & IRCOMM_DSR_DTR_IN) {
+		seq_printf(m, "%cDSR_DTR_IN", sep);
+		sep = '|';
+	}
+	if (self->settings.flow_control & IRCOMM_DSR_DTR_OUT) {
+		seq_printf(m, "%cDSR_DTR_OUT", sep);
+		sep = '|';
+	}
+	if (self->settings.flow_control & IRCOMM_ENQ_ACK_IN) {
+		seq_printf(m, "%cENQ_ACK_IN", sep);
+		sep = '|';
+	}
+	if (self->settings.flow_control & IRCOMM_ENQ_ACK_OUT) {
+		seq_printf(m, "%cENQ_ACK_OUT", sep);
+		sep = '|';
+	}
+	seq_putc(m, '\n');
 
-	ret += sprintf(buf+ret, "Flags: ");
-	if (self->flags & ASYNC_CTS_FLOW)
-		ret += sprintf(buf+ret, "ASYNC_CTS_FLOW|");
-	if (self->flags & ASYNC_CHECK_CD)
-		ret += sprintf(buf+ret, "ASYNC_CHECK_CD|");
-	if (self->flags & ASYNC_INITIALIZED)
-		ret += sprintf(buf+ret, "ASYNC_INITIALIZED|");
-	if (self->flags & ASYNC_LOW_LATENCY)
-		ret += sprintf(buf+ret, "ASYNC_LOW_LATENCY|");
-	if (self->flags & ASYNC_CLOSING)
-		ret += sprintf(buf+ret, "ASYNC_CLOSING|");
-	if (self->flags & ASYNC_NORMAL_ACTIVE)
-		ret += sprintf(buf+ret, "ASYNC_NORMAL_ACTIVE|");
-	if (self->flags)
-		ret--; /* remove the last | */
-	ret += sprintf(buf+ret, "\n");
+	seq_puts(m, "Flags:");
+	sep = ' ';
+	if (self->flags & ASYNC_CTS_FLOW) {
+		seq_printf(m, "%cASYNC_CTS_FLOW", sep);
+		sep = '|';
+	}
+	if (self->flags & ASYNC_CHECK_CD) {
+		seq_printf(m, "%cASYNC_CHECK_CD", sep);
+		sep = '|';
+	}
+	if (self->flags & ASYNC_INITIALIZED) {
+		seq_printf(m, "%cASYNC_INITIALIZED", sep);
+		sep = '|';
+	}
+	if (self->flags & ASYNC_LOW_LATENCY) {
+		seq_printf(m, "%cASYNC_LOW_LATENCY", sep);
+		sep = '|';
+	}
+	if (self->flags & ASYNC_CLOSING) {
+		seq_printf(m, "%cASYNC_CLOSING", sep);
+		sep = '|';
+	}
+	if (self->flags & ASYNC_NORMAL_ACTIVE) {
+		seq_printf(m, "%cASYNC_NORMAL_ACTIVE", sep);
+		sep = '|';
+	}
+	seq_putc(m, '\n');
 
-	ret += sprintf(buf+ret, "Role: %s\n", self->client ?
-		       "client" : "server");
-	ret += sprintf(buf+ret, "Open count: %d\n", self->open_count);
-	ret += sprintf(buf+ret, "Max data size: %d\n", self->max_data_size);
-	ret += sprintf(buf+ret, "Max header size: %d\n", self->max_header_size);
+	seq_printf(m, "Role: %s\n", self->client ? "client" : "server");
+	seq_printf(m, "Open count: %d\n", self->open_count);
+	seq_printf(m, "Max data size: %d\n", self->max_data_size);
+	seq_printf(m, "Max header size: %d\n", self->max_header_size);
 
 	if (self->tty)
-		ret += sprintf(buf+ret, "Hardware: %s\n",
+		seq_printf(m, "Hardware: %s\n",
 			       self->tty->hw_stopped ? "Stopped" : "Running");
-
-	ret += sprintf(buf+ret, "\n");
-	return ret;
 }
 
-
-/*
- * Function ircomm_tty_read_proc (buf, start, offset, len, eof, unused)
- *
- *
- *
- */
-static int ircomm_tty_read_proc(char *buf, char **start, off_t offset, int len,
-				int *eof, void *unused)
+static int ircomm_tty_proc_show(struct seq_file *m, void *v)
 {
 	struct ircomm_tty_cb *self;
-	int count = 0, l;
-	off_t begin = 0;
 	unsigned long flags;
 
 	spin_lock_irqsave(&ircomm_tty->hb_spinlock, flags);
 
 	self = (struct ircomm_tty_cb *) hashbin_get_first(ircomm_tty);
-	while ((self != NULL) && (count < 4000)) {
+	while (self != NULL) {
 		if (self->magic != IRCOMM_TTY_MAGIC)
 			break;
 
-		l = ircomm_tty_line_info(self, buf + count);
-		count += l;
-		if (count+begin > offset+len)
-			goto done;
-		if (count+begin < offset) {
-			begin += count;
-			count = 0;
-		}
-
+		ircomm_tty_line_info(self, m);
 		self = (struct ircomm_tty_cb *) hashbin_get_next(ircomm_tty);
 	}
-	*eof = 1;
-done:
 	spin_unlock_irqrestore(&ircomm_tty->hb_spinlock, flags);
-
-	if (offset >= count+begin)
-		return 0;
-	*start = buf + (offset-begin);
-	return ((len < begin+count-offset) ? len : begin+count-offset);
+	return 0;
 }
+
+static int ircomm_tty_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, ircomm_tty_proc_show, NULL);
+}
+
+static const struct file_operations ircomm_tty_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ircomm_tty_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 #endif /* CONFIG_PROC_FS */
 
 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");