diff -urN oldtree/Documentation/fb/00-INDEX newtree/Documentation/fb/00-INDEX
--- oldtree/Documentation/fb/00-INDEX	2006-01-03 03:21:10.000000000 +0000
+++ newtree/Documentation/fb/00-INDEX	2006-02-03 18:18:17.086732688 +0000
@@ -19,6 +19,8 @@
 	- info on the Matrox frame buffer driver
 pvr2fb.txt
 	- info on the PowerVR 2 frame buffer driver
+splash.txt
+	- info on the Framebuffer Splash
 tgafb.txt
 	- info on the TGA (DECChip 21030) frame buffer driver
 vesafb.txt
diff -urN oldtree/Documentation/fb/splash.txt newtree/Documentation/fb/splash.txt
--- oldtree/Documentation/fb/splash.txt	1970-01-01 00:00:00.000000000 +0000
+++ newtree/Documentation/fb/splash.txt	2006-02-03 18:18:17.086732688 +0000
@@ -0,0 +1,207 @@
+What is it?
+-----------
+
+The framebuffer splash is a kernel feature that allows displaying a background
+picture on selected consoles.
+
+What do I need to get it to work?
+---------------------------------
+
+To get fb splash up-and-running you will have to:
+ 1) get a copy of splashutils [1] or a similar program
+ 2) get some splash themes
+ 3) build the kernel helper program
+ 4) build your kernel with the FB_SPLASH option enabled.
+
+To get fb splash operational right after fbcon initialization is finished, you
+will have to include a theme and the kernel helper into your initramfs image.
+Please refer to splashutils documentation for instructions on how to do that.
+
+[1] The splashutils package can be downloaded from:
+    http://dev.gentoo.org/~spock/projects/splashutils/
+
+The userspace helper
+--------------------
+
+The userspace splash helper (by default: /sbin/splash_helper) is called by the
+kernel whenever an important event occurs and the kernel needs some kind of
+job to be carried out. Important events include console switches and graphic
+mode switches (the kernel requests background images and configuration
+parameters for the current console). The splash helper must be accessible at 
+all times. If it's not, fbsplash will be switched off automatically.
+
+It's possible to set path to the splash helper by writing it to 
+/proc/sys/kernel/fbsplash.
+
+*****************************************************************************
+
+The information below is mostly technical stuff. There's probably no need to 
+read it unless you plan to develop a userspace helper.
+
+The splash protocol
+-------------------
+
+The splash protocol defines a communication interface between the kernel and 
+the userspace splash helper.
+
+The kernel side is responsible for:
+
+ o rendering console text, using an image as a background (instead of a
+   standard solid color fbcon uses),
+ o accepting commands from the user via ioctls on the fbsplash device,
+ o calling the userspace helper to set things up as soon as the fb subsystem 
+   is initialized.
+
+The userspace helper is responsible for everything else, including parsing
+configuration files, decompressing the image files whenever the kernel needs
+it, and communicating with the kernel if necessary.
+
+The splash protocol specifies how communication is done in both ways:
+kernel->userspace and userspace->helper.
+  
+Kernel -> Userspace
+-------------------
+
+The kernel communicates with the userspace helper by calling it and specifying
+the task to be done in a series of arguments.
+
+The arguments follow the pattern:
+<splash protocol version> <command> <parameters>
+
+All commands defined in splash protocol v2 have the following parameters:
+ virtual console
+ framebuffer number
+ theme
+
+Splash protocol v1 specified an additional 'fbsplash mode' after the 
+framebuffer number. Splash protocol v1 is deprecated and should not be used.
+
+Splash protocol v2 specifies the following commands:
+
+getpic
+------
+ The kernel issues this command to request image data. It's up to the userspace
+ helper to find a background image appropriate for the specified theme and the 
+ current resolution. The userspace helper should respond by issuing the
+ FBIOSPLASH_SETPIC ioctl.
+
+init
+----
+ The kernel issues this command after the fbsplash device is created and
+ the fbsplash interface is initialized. Upon receiving 'init', the userspace 
+ helper should parse the kernel command line (/proc/cmdline) or otherwise
+ decide whether fbsplash is to be activated. 
+
+ To activate fbsplash on the first console the helper should issue the
+ FBIOSPLASH_SETCFG, FBIOSPLASH_SETPIC and FBIOSPLASH_SETSTATE commands,
+ in the above-mentioned order.
+
+ When the userspace helper is called in an early phase of the boot process
+ (right after the initialization of fbcon), no filesystems will be mounted.
+ The helper program should mount sysfs and then create the appropriate 
+ framebuffer, fbsplash and tty0 devices (if they don't already exist) to get 
+ current display settings and to be able to communicate with the kernel side.
+ It should probably also mount the procfs to be able to parse the kernel 
+ command line parameters.
+
+ Note that the console sem is not held when the kernel calls splash_helper
+ with the 'init' command. The splash helper should perform all ioctls with
+ origin set to FB_SPLASH_IO_ORIG_USER.
+
+modechange
+----------
+ The kernel issues this command on a mode change. The helper's response should
+ be similar to the response to the 'init' command. Note that this time the
+ console sem is held and all ioctls must be performed with origin set to
+ FB_SPLASH_IO_ORIG_KERNEL.
+
+
+Userspace -> Kernel
+-------------------
+
+Userspace programs can communicate with fbsplash via ioctls on the fbsplash 
+device. These ioctls are to be used by both the userspace helper (called 
+only by the kernel) and userspace configuration tools (run by the users).
+
+The splash helper should set the origin field to FB_SPLASH_IO_ORIG_KERNEL 
+when doing the appropriate ioctls. All userspace configuration tools should 
+use FB_SPLASH_IO_ORIG_USER. Failure to set the appropriate value in the origin
+field when performing ioctls from the kernel helper will most likely result 
+in a console deadlock.
+
+FB_SPLASH_IO_ORIG_KERNEL instructs fbsplash not to try to acquire the console
+semaphore. Not surprisingly, FB_SPLASH_IO_ORIG_USER instructs it to acquire
+the console sem.
+
+The framebuffer splash provides the following ioctls (all defined in 
+linux/fb.h):
+
+FBIOSPLASH_SETPIC
+description: loads a background picture for a virtual console
+argument: struct fb_splash_iowrapper*; data: struct fb_image*
+notes: 
+If called for consoles other than the current foreground one, the picture data 
+will be ignored.
+
+If the current virtual console is running in a 8-bpp mode, the cmap substruct
+of fb_image has to be filled appropriately: start should be set to 16 (first 
+16 colors are reserved for fbcon), len to a value <= 240 and red, green and
+blue should point to valid cmap data. The transp field is ingored. The fields
+dx, dy, bg_color, fg_color in fb_image are ignored as well.
+
+FBIOSPLASH_SETCFG
+description: sets the fbsplash config for a virtual console
+argument: struct fb_splash_iowrapper*; data: struct vc_splash*
+notes: The structure has to be filled with valid data.
+
+FBIOSPLASH_GETCFG
+description: gets the fbsplash config for a virtual console
+argument: struct fb_splash_iowrapper*; data: struct vc_splash*
+
+FBIOSPLASH_SETSTATE
+description: sets the fbsplash state for a virtual console
+argument: struct fb_splash_iowrapper*; data: unsigned int*
+	  values: 0 = disabled, 1 = enabled.
+
+FBIOSPLASH_GETSTATE
+description: gets the fbsplash state for a virtual console
+argument: struct fb_splash_iowrapper*; data: unsigned int*
+          values: as in FBIOSPLASH_SETSTATE
+
+Info on used structures:
+
+Definition of struct vc_splash can be found in linux/console_splash.h. It's
+heavily commented. Note that the 'theme' field should point to a string
+no longer than FB_SPLASH_THEME_LEN. When FBIOSPLASH_GETCFG call is 
+performed, the theme field should point to a char buffer of length
+FB_SPLASH_THEME_LEN.
+
+Definition of struct fb_splash_iowrapper can be found in linux/fb.h.
+The fields in this struct have the following meaning:
+
+vc: 
+Virtual console number.
+
+origin: 
+Specifies if the ioctl is performed as a response to a kernel request. The
+splash helper should set this field to FB_SPLASH_IO_ORIG_KERNEL, userspace
+programs should set it to FB_SPLASH_IO_ORIG_USER. This field is necessary to
+avoid console semaphore deadlocks.
+
+data: 
+Pointer to a data structure appropriate for the performed ioctl. Type of
+the data struct is specified in the ioctls description.
+
+*****************************************************************************
+
+Credit
+------
+
+Original 'bootsplash' project & implementation by:
+  Volker Poplawski <volker@poplawski.de>, Stefan Reinauer <stepan@suse.de>,
+  Steffen Winterfeldt <snwint@suse.de>, Michael Schroeder <mls@suse.de>,
+  Ken Wimer <wimer@suse.de>.
+
+Fbsplash, splash protocol design, current implementation & docs by:
+  Michael Januszewski <spock@gentoo.org>
+
diff -urN oldtree/drivers/video/Kconfig newtree/drivers/video/Kconfig
--- oldtree/drivers/video/Kconfig	2006-01-03 03:21:10.000000000 +0000
+++ newtree/drivers/video/Kconfig	2006-02-03 18:18:17.087732536 +0000
@@ -759,7 +759,6 @@
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB_TILEBLITTING
 	select FB_MACMODES if PPC_PMAC
 	---help---
 	  Say Y here if you have a Matrox Millennium, Matrox Millennium II,
@@ -1469,5 +1468,15 @@
 	source "drivers/video/backlight/Kconfig"
 endif
 
-endmenu
+config FB_SPLASH
+	bool "Support for the framebuffer splash"
+	depends on FRAMEBUFFER_CONSOLE=y && !FB_TILEBLITTING
+	default n
+	---help---
+	  This option enables support for the Linux boot-up splash screen and
+	  graphical backgrounds on consoles. Note that you will need userspace
+	  splash utilities in order to take advantage of these features. Refer 
+	  to Documentation/fb/splash.txt for more information.
 
+	  If unsure, say N.
+endmenu
diff -urN oldtree/drivers/video/Kconfig.orig newtree/drivers/video/Kconfig.orig
--- oldtree/drivers/video/Kconfig.orig	1970-01-01 00:00:00.000000000 +0000
+++ newtree/drivers/video/Kconfig.orig	2006-01-03 03:21:10.000000000 +0000
@@ -0,0 +1,1473 @@
+#
+# Video configuration
+#
+
+menu "Graphics support"
+
+config FB
+	tristate "Support for frame buffer devices"
+	---help---
+	  The frame buffer device provides an abstraction for the graphics
+	  hardware. It represents the frame buffer of some video hardware and
+	  allows application software to access the graphics hardware through
+	  a well-defined interface, so the software doesn't need to know
+	  anything about the low-level (hardware register) stuff.
+
+	  Frame buffer devices work identically across the different
+	  architectures supported by Linux and make the implementation of
+	  application programs easier and more portable; at this point, an X
+	  server exists which uses the frame buffer device exclusively.
+	  On several non-X86 architectures, the frame buffer device is the
+	  only way to use the graphics hardware.
+
+	  The device is accessed through special device nodes, usually located
+	  in the /dev directory, i.e. /dev/fb*.
+
+	  You need an utility program called fbset to make full use of frame
+	  buffer devices. Please read <file:Documentation/fb/framebuffer.txt>
+	  and the Framebuffer-HOWTO at
+	  <http://www.tahallah.demon.co.uk/programming/prog.html> for more
+	  information.
+
+	  Say Y here and to the driver for your graphics board below if you
+	  are compiling a kernel for a non-x86 architecture.
+
+	  If you are compiling for the x86 architecture, you can say Y if you
+	  want to play with it, but it is not essential. Please note that
+	  running graphical applications that directly touch the hardware
+	  (e.g. an accelerated X server) and that are not frame buffer
+	  device-aware may cause unexpected results. If unsure, say N.
+
+config FB_CFB_FILLRECT
+	tristate
+	depends on FB
+	default n
+	---help---
+	  Include the cfb_fillrect function for generic software rectangle
+	  filling. This is used by drivers that don't provide their own
+	  (accelerated) version.
+
+config FB_CFB_COPYAREA
+	tristate
+	depends on FB
+	default n
+	---help---
+	  Include the cfb_copyarea function for generic software area copying.
+	  This is used by drivers that don't provide their own (accelerated)
+	  version.
+
+config FB_CFB_IMAGEBLIT
+	tristate
+	depends on FB
+	default n
+	---help---
+	  Include the cfb_imageblit function for generic software image
+	  blitting. This is used by drivers that don't provide their own
+	  (accelerated) version.
+
+config FB_MACMODES
+       tristate
+       depends on FB
+       default n
+
+config FB_MODE_HELPERS
+        bool "Enable Video Mode Handling Helpers"
+        depends on FB
+	default n
+	---help---
+	  This enables functions for handling video modes using the
+	  Generalized Timing Formula and the EDID parser. A few drivers rely
+          on this feature such as the radeonfb, rivafb, and the i810fb. If
+	  your driver does not take advantage of this feature, choosing Y will
+	  just increase the kernel size by about 5K.
+
+config FB_TILEBLITTING
+       bool "Enable Tile Blitting Support"
+       depends on FB
+       default n
+       ---help---
+         This enables tile blitting.  Tile blitting is a drawing technique
+	 where the screen is divided into rectangular sections (tiles), whereas
+	 the standard blitting divides the screen into pixels. Because the
+	 default drawing element is a tile, drawing functions will be passed
+	 parameters in terms of number of tiles instead of number of pixels.
+	 For example, to draw a single character, instead of using bitmaps,
+	 an index to an array of bitmaps will be used.  To clear or move a
+	 rectangular section of a screen, the rectangle will be described in
+	 terms of number of tiles in the x- and y-axis.
+
+	 This is particularly important to one driver, matroxfb.  If
+	 unsure, say N.
+
+config FB_CIRRUS
+	tristate "Cirrus Logic support"
+	depends on FB && (ZORRO || PCI)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  This enables support for Cirrus Logic GD542x/543x based boards on
+	  Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum.
+
+	  If you have a PCI-based system, this enables support for these
+	  chips: GD-543x, GD-544x, GD-5480.
+
+	  Please read the file <file:Documentation/fb/cirrusfb.txt>.
+
+	  Say N unless you have such a graphics board or plan to get one
+	  before you next recompile the kernel.
+
+config FB_PM2
+	tristate "Permedia2 support"
+	depends on FB && ((AMIGA && BROKEN) || PCI)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the Permedia2 AGP frame
+	  buffer card from ASK, aka `Graphic Blaster Exxtreme'.  There is a
+	  product page at
+	  <http://www.ask.com.hk/product/Permedia%202/permedia2.htm>.
+
+config FB_PM2_FIFO_DISCONNECT
+	bool "enable FIFO disconnect feature"
+	depends on FB_PM2 && PCI
+	help
+	  Support the Permedia2 FIFO disconnect feature (see CONFIG_FB_PM2).
+
+config FB_ARMCLCD
+	tristate "ARM PrimeCell PL110 support"
+	depends on FB && ARM && ARM_AMBA
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This framebuffer device driver is for the ARM PrimeCell PL110
+	  Colour LCD controller.  ARM PrimeCells provide the building
+	  blocks for System on a Chip devices.
+
+	  If you want to compile this as a module (=code which can be
+	  inserted into and removed from the running kernel), say M
+	  here and read <file:Documentation/modules.txt>.  The module
+	  will be called amba-clcd.
+
+config FB_ACORN
+	bool "Acorn VIDC support"
+	depends on (FB = y) && ARM && (ARCH_ACORN || ARCH_CLPS7500)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the Acorn VIDC graphics
+	  hardware found in Acorn RISC PCs and other ARM-based machines.  If
+	  unsure, say N.
+
+config FB_CLPS711X
+	bool "CLPS711X LCD support"
+	depends on (FB = y) && ARM && ARCH_CLPS711X
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  Say Y to enable the Framebuffer driver for the CLPS7111 and
+	  EP7212 processors.
+
+config FB_SA1100
+	bool "SA-1100 LCD support"
+	depends on (FB = y) && ARM && ARCH_SA1100
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is a framebuffer device for the SA-1100 LCD Controller.
+	  See <http://www.linux-fbdev.org/> for information on framebuffer
+	  devices.
+
+	  If you plan to use the LCD display with your SA-1100 system, say
+	  Y here.
+
+config FB_IMX
+	tristate "Motorola i.MX LCD support"
+	depends on FB && ARM && ARCH_IMX
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+
+config FB_CYBER2000
+	tristate "CyberPro 2000/2010/5000 support"
+	depends on FB && PCI && (BROKEN || !SPARC64)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This enables support for the Integraphics CyberPro 20x0 and 5000
+	  VGA chips used in the Rebel.com Netwinder and other machines.
+	  Say Y if you have a NetWinder or a graphics card containing this
+	  device, otherwise say N.
+
+config FB_APOLLO
+	bool
+	depends on (FB = y) && APOLLO
+	default y
+	select FB_CFB_FILLRECT
+	select FB_CFB_IMAGEBLIT
+
+config FB_Q40
+	bool
+	depends on (FB = y) && Q40
+	default y
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+
+config FB_AMIGA
+	tristate "Amiga native chipset support"
+	depends on FB && AMIGA
+	help
+	  This is the frame buffer device driver for the builtin graphics
+	  chipset found in Amigas.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called amifb.
+
+config FB_AMIGA_OCS
+	bool "Amiga OCS chipset support"
+	depends on FB_AMIGA
+	help
+	  This enables support for the original Agnus and Denise video chips,
+	  found in the Amiga 1000 and most A500's and A2000's. If you intend
+	  to run Linux on any of these systems, say Y; otherwise say N.
+
+config FB_AMIGA_ECS
+	bool "Amiga ECS chipset support"
+	depends on FB_AMIGA
+	help
+	  This enables support for the Enhanced Chip Set, found in later
+	  A500's, later A2000's, the A600, the A3000, the A3000T and CDTV. If
+	  you intend to run Linux on any of these systems, say Y; otherwise
+	  say N.
+
+config FB_AMIGA_AGA
+	bool "Amiga AGA chipset support"
+	depends on FB_AMIGA
+	help
+	  This enables support for the Advanced Graphics Architecture (also
+	  known as the AGA or AA) Chip Set, found in the A1200, A4000, A4000T
+	  and CD32. If you intend to run Linux on any of these systems, say Y;
+	  otherwise say N.
+
+config FB_CYBER
+	tristate "Amiga CyberVision 64 support"
+	depends on FB && ZORRO && BROKEN
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This enables support for the Cybervision 64 graphics card from
+	  Phase5. Please note that its use is not all that intuitive (i.e. if
+	  you have any questions, be sure to ask!). Say N unless you have a
+	  Cybervision 64 or plan to get one before you next recompile the
+	  kernel. Please note that this driver DOES NOT support the
+	  Cybervision 64/3D card, as they use incompatible video chips.
+
+config FB_VIRGE
+	bool "Amiga CyberVision 64/3D support "
+	depends on (FB = y) && ZORRO && BROKEN
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This enables support for the Cybervision 64/3D graphics card from
+	  Phase5. Please note that its use is not all that intuitive (i.e. if
+	  you have any questions, be sure to ask!). Say N unless you have a
+	  Cybervision 64/3D or plan to get one before you next recompile the
+	  kernel. Please note that this driver DOES NOT support the older
+	  Cybervision 64 card, as they use incompatible video chips.
+
+config FB_RETINAZ3
+	tristate "Amiga Retina Z3 support"
+	depends on (FB = y) && ZORRO && BROKEN
+	help
+	  This enables support for the Retina Z3 graphics card. Say N unless
+	  you have a Retina Z3 or plan to get one before you next recompile
+	  the kernel.
+
+config FB_FM2
+	bool "Amiga FrameMaster II/Rainbow II support"
+	depends on (FB = y) && ZORRO
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the Amiga FrameMaster
+	  card from BSC (exhibited 1992 but not shipped as a CBM product).
+
+config FB_ARC
+	tristate "Arc Monochrome LCD board support"
+	depends on FB && X86
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This enables support for the Arc Monochrome LCD board. The board
+	  is based on the KS-108 lcd controller and is typically a matrix
+	  of 2*n chips. This driver was tested with a 128x64 panel. This
+	  driver supports it for use with x86 SBCs through a 16 bit GPIO
+	  interface (8 bit data, 8 bit control). If you anticpate using
+	  this driver, say Y or M; otherwise say N. You must specify the
+	  GPIO IO address to be used for setting control and data.
+
+config FB_ATARI
+	bool "Atari native chipset support"
+	depends on (FB = y) && ATARI && BROKEN
+	help
+	  This is the frame buffer device driver for the builtin graphics
+	  chipset found in Ataris.
+
+config FB_OF
+	bool "Open Firmware frame buffer device support"
+	depends on (FB = y) && (PPC64 || PPC_OF)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MACMODES
+	help
+	  Say Y if you want support with Open Firmware for your graphics
+	  board.
+
+config FB_CONTROL
+	bool "Apple \"control\" display support"
+	depends on (FB = y) && PPC_PMAC
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MACMODES
+	help
+	  This driver supports a frame buffer for the graphics adapter in the
+	  Power Macintosh 7300 and others.
+
+config FB_PLATINUM
+	bool "Apple \"platinum\" display support"
+	depends on (FB = y) && PPC_PMAC
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MACMODES
+	help
+	  This driver supports a frame buffer for the "platinum" graphics
+	  adapter in some Power Macintoshes.
+
+config FB_VALKYRIE
+	bool "Apple \"valkyrie\" display support"
+	depends on (FB = y) && (MAC || PPC_PMAC)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MACMODES
+	help
+	  This driver supports a frame buffer for the "valkyrie" graphics
+	  adapter in some Power Macintoshes.
+
+config FB_CT65550
+	bool "Chips 65550 display support"
+	depends on (FB = y) && PPC
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the Chips & Technologies
+	  65550 graphics chip in PowerBooks.
+
+config FB_ASILIANT
+	bool "Asiliant (Chips) 69000 display support"
+	depends on (FB = y) && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+
+config FB_IMSTT
+	bool "IMS Twin Turbo display support"
+	depends on (FB = y) && PCI
+	select FB_CFB_IMAGEBLIT
+	select FB_MACMODES if PPC
+	help
+	  The IMS Twin Turbo is a PCI-based frame buffer card bundled with
+	  many Macintosh and compatible computers.
+
+config FB_VGA16
+	tristate "VGA 16-color graphics support"
+	depends on FB && (X86 || PPC)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for VGA 16 color graphic
+	  cards. Say Y if you have such a card.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called vga16fb.
+
+config FB_STI
+	tristate "HP STI frame buffer device support"
+	depends on FB && PARISC
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	default y
+	---help---
+	  STI refers to the HP "Standard Text Interface" which is a set of
+	  BIOS routines contained in a ROM chip in HP PA-RISC based machines.
+	  Enabling this option will implement the linux framebuffer device
+	  using calls to the STI BIOS routines for initialisation.
+	
+	  If you enable this option, you will get a planar framebuffer device
+	  /dev/fb which will work on the most common HP graphic cards of the
+	  NGLE family, including the artist chips (in the 7xx and Bxxx series),
+	  HCRX, HCRX24, CRX, CRX24 and VisEG series.
+
+	  It is safe to enable this option, so you should probably say "Y".
+
+config FB_MAC
+	bool "Generic Macintosh display support"
+	depends on (FB = y) && MAC
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MACMODES
+
+#      bool '  Apple DAFB display support' CONFIG_FB_DAFB
+config FB_HP300
+	bool
+	depends on (FB = y) && HP300
+	select FB_CFB_FILLRECT
+	select FB_CFB_IMAGEBLIT
+	default y
+
+config FB_TGA
+	tristate "TGA framebuffer support"
+	depends on FB && ALPHA
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for generic TGA graphic
+	  cards. Say Y if you have one of those.
+
+config FB_VESA
+	bool "VESA VGA graphics support"
+	depends on (FB = y) && X86
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for generic VESA 2.0
+	  compliant graphic cards. The older VESA 1.2 cards are not supported.
+	  You will get a boot time penguin logo at no additional cost. Please
+	  read <file:Documentation/fb/vesafb.txt>. If unsure, say Y.
+
+config VIDEO_SELECT
+	bool
+	depends on FB_VESA
+	default y
+
+config FB_HGA
+	tristate "Hercules mono graphics support"
+	depends on FB && X86
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  Say Y here if you have a Hercules mono graphics card.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called hgafb.
+
+	  As this card technology is 15 years old, most people will answer N
+	  here.
+
+config FB_HGA_ACCEL
+	bool "Hercules mono Acceleration functions (EXPERIMENTAL)"
+	depends on FB_HGA && EXPERIMENTAL
+	---help---
+	This will compile the Hercules mono graphics with
+	acceleration functions.
+
+
+config VIDEO_SELECT
+	bool
+	depends on (FB = y) && X86
+	default y
+
+config FB_SGIVW
+	tristate "SGI Visual Workstation framebuffer support"
+	depends on FB && X86_VISWS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  SGI Visual Workstation support for framebuffer graphics.
+
+config FB_GBE
+	bool "SGI Graphics Backend frame buffer support"
+	depends on (FB = y) && (SGI_IP32 || X86_VISWS)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+ 	help
+	  This is the frame buffer device driver for SGI Graphics Backend.
+	  This chip is used in SGI O2 and Visual Workstation 320/540.
+
+config FB_GBE_MEM
+	int "Video memory size in MB"
+	depends on FB_GBE
+	default 8
+	help
+	  This is the amount of memory reserved for the framebuffer,
+	  which can be any value between 1MB and 8MB.
+
+config BUS_I2C
+	bool
+	depends on (FB = y) && VISWS
+	default y
+
+config FB_SUN3
+	bool "Sun3 framebuffer support"
+	depends on (FB = y) && (SUN3 || SUN3X) && BROKEN
+
+config FB_SBUS
+	bool "SBUS and UPA framebuffers"
+	depends on (FB = y) && SPARC
+	help
+	  Say Y if you want support for SBUS or UPA based frame buffer device.
+
+config FB_BW2
+	bool "BWtwo support"
+	depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the BWtwo frame buffer.
+
+config FB_CG3
+	bool "CGthree support"
+	depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the CGthree frame buffer.
+
+config FB_CG6
+	bool "CGsix (GX,TurboGX) support"
+	depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the CGsix (GX, TurboGX)
+	  frame buffer.
+
+config FB_PVR2
+	tristate "NEC PowerVR 2 display support"
+	depends on FB && SH_DREAMCAST
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Say Y here if you have a PowerVR 2 card in your box.  If you plan to
+	  run linux on your Dreamcast, you will have to say Y here.
+	  This driver may or may not work on other PowerVR 2 cards, but is
+	  totally untested.  Use at your own risk.  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called pvr2fb.
+
+	  You can pass several parameters to the driver at boot time or at
+	  module load time.  The parameters look like "video=pvr2:XXX", where
+	  the meaning of XXX can be found at the end of the main source file
+	  (<file:drivers/video/pvr2fb.c>). Please see the file
+	  <file:Documentation/fb/pvr2fb.txt>.
+
+config FB_EPSON1355
+	bool "Epson 1355 framebuffer support"
+	depends on (FB = y) && (SUPERH || ARCH_CEIVA)
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  Build in support for the SED1355 Epson Research Embedded RAMDAC
+	  LCD/CRT Controller (since redesignated as the S1D13505) as a
+	  framebuffer.  Product specs at
+	  <http://www.erd.epson.com/vdc/html/products.htm>.
+
+config FB_S1D13XXX
+	tristate "Epson S1D13XXX framebuffer support"
+	depends on FB
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  Support for S1D13XXX framebuffer device family (currently only
+	  working with S1D13806). Product specs at
+	  <http://www.erd.epson.com/vdc/html/legacy_13xxx.htm>
+
+config FB_NVIDIA
+	tristate "nVidia Framebuffer Support"
+	depends on FB && PCI
+	select I2C_ALGOBIT if FB_NVIDIA_I2C
+	select I2C if FB_NVIDIA_I2C
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This driver supports graphics boards with the nVidia chips, TNT
+	  and newer. For very old chipsets, such as the RIVA128, then use
+	  the rivafb.
+	  Say Y if you have such a graphics board.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called nvidiafb.
+
+config FB_NVIDIA_I2C
+       bool "Enable DDC Support"
+       depends on FB_NVIDIA
+       help
+	  This enables I2C support for nVidia Chipsets.  This is used
+	  only for getting EDID information from the attached display
+	  allowing for robust video mode handling and switching.
+
+	  Because fbdev-2.6 requires that drivers must be able to
+	  independently validate video mode parameters, you should say Y
+	  here.
+
+config FB_RIVA
+	tristate "nVidia Riva support"
+	depends on FB && PCI
+	select I2C_ALGOBIT if FB_RIVA_I2C
+	select I2C if FB_RIVA_I2C
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This driver supports graphics boards with the nVidia Riva/Geforce
+	  chips.
+	  Say Y if you have such a graphics board.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called rivafb.
+
+config FB_RIVA_I2C
+       bool "Enable DDC Support"
+       depends on FB_RIVA
+       help
+	  This enables I2C support for nVidia Chipsets.  This is used
+	  only for getting EDID information from the attached display
+	  allowing for robust video mode handling and switching.
+
+	  Because fbdev-2.6 requires that drivers must be able to
+	  independently validate video mode parameters, you should say Y
+	  here.
+
+config FB_RIVA_DEBUG
+	bool "Lots of debug output from Riva(nVidia) driver"
+	depends on FB_RIVA
+	default n
+	help
+	  Say Y here if you want the Riva driver to output all sorts
+	  of debugging informations to provide to the maintainer when
+	  something goes wrong.
+
+config FB_I810
+	tristate "Intel 810/815 support (EXPERIMENTAL)"
+	depends on FB && EXPERIMENTAL && PCI && X86_32
+	select AGP
+	select AGP_INTEL
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This driver supports the on-board graphics built in to the Intel 810 
+          and 815 chipsets.  Say Y if you have and plan to use such a board.
+
+          To compile this driver as a module, choose M here: the
+	  module will be called i810fb.
+
+          For more information, please read 
+	  <file:Documentation/fb/intel810.txt>
+
+config FB_I810_GTF
+	bool "use VESA Generalized Timing Formula"
+	depends on FB_I810
+	help
+	  If you say Y, then the VESA standard, Generalized Timing Formula 
+          or GTF, will be used to calculate the required video timing values
+	  per video mode.  Since the GTF allows nondiscrete timings 
+          (nondiscrete being a range of values as opposed to discrete being a
+          set of values), you'll be able to use any combination of horizontal 
+	  and vertical resolutions, and vertical refresh rates without having
+	  to specify your own timing parameters.  This is especially useful
+	  to maximize the performance of an aging display, or if you just 
+          have a display with nonstandard dimensions. A VESA compliant 
+	  monitor is recommended, but can still work with non-compliant ones.
+	  If you need or want this, then select this option. The timings may 
+	  not be compliant with Intel's recommended values. Use at your own 
+	  risk.
+
+          If you say N, the driver will revert to discrete video timings 
+	  using a set recommended by Intel in their documentation.
+  
+          If unsure, say N.
+
+config FB_I810_I2C
+	bool "Enable DDC Support"
+	depends on FB_I810 && FB_I810_GTF
+	select I2C
+	select I2C_ALGOBIT
+	help
+
+config FB_INTEL
+	tristate "Intel 830M/845G/852GM/855GM/865G support (EXPERIMENTAL)"
+	depends on FB && EXPERIMENTAL && PCI && X86_32
+	select AGP
+	select AGP_INTEL
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This driver supports the on-board graphics built in to the Intel
+          830M/845G/852GM/855GM/865G chipsets.
+          Say Y if you have and plan to use such a board.
+
+          To compile this driver as a module, choose M here: the
+	  module will be called intelfb.
+
+config FB_INTEL_DEBUG
+        bool "Intel driver Debug Messages"
+	depends on FB_INTEL
+	---help---
+	  Say Y here if you want the Intel driver to output all sorts
+	  of debugging informations to provide to the maintainer when
+	  something goes wrong.
+
+config FB_MATROX
+	tristate "Matrox acceleration"
+	depends on FB && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_TILEBLITTING
+	select FB_MACMODES if PPC_PMAC
+	---help---
+	  Say Y here if you have a Matrox Millennium, Matrox Millennium II,
+	  Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox
+	  Mystique G200, Matrox Millennium G200, Matrox Marvel G200 video,
+	  Matrox G400, G450 or G550 card in your box.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called matroxfb.
+
+	  You can pass several parameters to the driver at boot time or at
+	  module load time. The parameters look like "video=matrox:XXX", and
+	  are described in <file:Documentation/fb/matroxfb.txt>.
+
+config FB_MATROX_MILLENIUM
+	bool "Millennium I/II support"
+	depends on FB_MATROX
+	help
+	  Say Y here if you have a Matrox Millennium or Matrox Millennium II
+	  video card. If you select "Advanced lowlevel driver options" below,
+	  you should check 4 bpp packed pixel, 8 bpp packed pixel, 16 bpp
+	  packed pixel, 24 bpp packed pixel and 32 bpp packed pixel. You can
+	  also use font widths different from 8.
+
+config FB_MATROX_MYSTIQUE
+	bool "Mystique support"
+	depends on FB_MATROX
+	help
+	  Say Y here if you have a Matrox Mystique or Matrox Mystique 220
+	  video card. If you select "Advanced lowlevel driver options" below,
+	  you should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp
+	  packed pixel and 32 bpp packed pixel. You can also use font widths
+	  different from 8.
+
+config FB_MATROX_G
+	bool "G100/G200/G400/G450/G550 support"
+	depends on FB_MATROX
+	---help---
+	  Say Y here if you have a Matrox G100, G200, G400, G450 or G550 based
+	  video card. If you select "Advanced lowlevel driver options", you
+	  should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed
+	  pixel and 32 bpp packed pixel. You can also use font widths
+	  different from 8.
+
+	  If you need support for G400 secondary head, you must first say Y to
+	  "I2C support" in the character devices section, and then to
+	  "Matrox I2C support" and "G400 second head support" here in the
+	  framebuffer section. G450/G550 secondary head and digital output
+	  are supported without additional modules.
+
+	  The driver starts in monitor mode. You must use the matroxset tool 
+	  (available at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to 
+	  swap primary and secondary head outputs, or to change output mode.  
+	  Secondary head driver always start in 640x480 resolution and you 
+	  must use fbset to change it.
+
+	  Do not forget that second head supports only 16 and 32 bpp
+	  packed pixels, so it is a good idea to compile them into the kernel
+	  too. You can use only some font widths, as the driver uses generic
+	  painting procedures (the secondary head does not use acceleration
+	  engine).
+
+	  G450/G550 hardware can display TV picture only from secondary CRTC,
+	  and it performs no scaling, so picture must have 525 or 625 lines.
+
+config FB_MATROX_I2C
+	tristate "Matrox I2C support"
+	depends on FB_MATROX && I2C
+	select I2C_ALGOBIT
+	---help---
+	  This drivers creates I2C buses which are needed for accessing the
+	  DDC (I2C) bus present on all Matroxes, an I2C bus which
+	  interconnects Matrox optional devices, like MGA-TVO on G200 and
+	  G400, and the secondary head DDC bus, present on G400 only.
+
+	  You can say Y or M here if you want to experiment with monitor
+	  detection code. You must say Y or M here if you want to use either
+	  second head of G400 or MGA-TVO on G200 or G400.
+
+	  If you compile it as module, it will create a module named
+	  i2c-matroxfb.
+
+config FB_MATROX_MAVEN
+	tristate "G400 second head support"
+	depends on FB_MATROX_G && FB_MATROX_I2C
+	---help---
+	  WARNING !!! This support does not work with G450 !!!
+
+	  Say Y or M here if you want to use a secondary head (meaning two
+	  monitors in parallel) on G400 or MGA-TVO add-on on G200. Secondary
+	  head is not compatible with accelerated XFree 3.3.x SVGA servers -
+	  secondary head output is blanked while you are in X. With XFree
+	  3.9.17 preview you can use both heads if you use SVGA over fbdev or
+	  the fbdev driver on first head and the fbdev driver on second head.
+
+	  If you compile it as module, two modules are created,
+	  matroxfb_crtc2 and matroxfb_maven. Matroxfb_maven is needed for
+	  both G200 and G400, matroxfb_crtc2 is needed only by G400. You must
+	  also load i2c-matroxfb to get it to run.
+
+	  The driver starts in monitor mode and you must use the matroxset
+	  tool (available at
+	  <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to switch it to
+	  PAL or NTSC or to swap primary and secondary head outputs.
+	  Secondary head driver also always start in 640x480 resolution, you
+	  must use fbset to change it.
+
+	  Also do not forget that second head supports only 16 and 32 bpp
+	  packed pixels, so it is a good idea to compile them into the kernel
+	  too.  You can use only some font widths, as the driver uses generic
+	  painting procedures (the secondary head does not use acceleration
+	  engine).
+
+config FB_MATROX_MULTIHEAD
+	bool "Multihead support"
+	depends on FB_MATROX
+	---help---
+	  Say Y here if you have more than one (supported) Matrox device in
+	  your computer and you want to use all of them for different monitors
+	  ("multihead"). If you have only one device, you should say N because
+	  the driver compiled with Y is larger and a bit slower, especially on
+	  ia32 (ix86).
+
+	  If you said M to "Matrox unified accelerated driver" and N here, you
+	  will still be able to use several Matrox devices simultaneously:
+	  insert several instances of the module matroxfb into the kernel
+	  with insmod, supplying the parameter "dev=N" where N is 0, 1, etc.
+	  for the different Matrox devices. This method is slightly faster but
+	  uses 40 KB of kernel memory per Matrox card.
+
+	  There is no need for enabling 'Matrox multihead support' if you have
+	  only one Matrox card in the box.
+
+config FB_RADEON_OLD
+	tristate "ATI Radeon display support (Old driver)"
+	depends on FB && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MACMODES if PPC
+	help
+	  Choose this option if you want to use an ATI Radeon graphics card as
+	  a framebuffer device.  There are both PCI and AGP versions.  You
+	  don't need to choose this to run the Radeon in plain VGA mode.
+	  There is a product page at
+	  <http://www.ati.com/na/pages/products/pc/radeon32/index.html>.
+
+config FB_RADEON
+	tristate "ATI Radeon display support"
+	depends on FB && PCI
+	select I2C_ALGOBIT if FB_RADEON_I2C
+	select I2C if FB_RADEON_I2C
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MACMODES if PPC_OF
+	help
+	  Choose this option if you want to use an ATI Radeon graphics card as
+	  a framebuffer device.  There are both PCI and AGP versions.  You
+	  don't need to choose this to run the Radeon in plain VGA mode.
+
+	  If you say Y here and want DDC/I2C support you must first say Y to
+	  "I2C support" and "I2C bit-banging support" in the character devices
+	  section.
+
+	  If you say M here then "I2C support" and "I2C bit-banging support" 
+	  can be build either as modules or built-in.
+
+	  There is a product page at
+	  http://apps.ati.com/ATIcompare/
+config FB_RADEON_I2C
+	bool "DDC/I2C for ATI Radeon support"
+	depends on FB_RADEON
+	default y
+	help
+	  Say Y here if you want DDC/I2C support for your Radeon board. 
+
+config FB_RADEON_DEBUG
+	bool "Lots of debug output from Radeon driver"
+	depends on FB_RADEON
+	default n
+	help
+	  Say Y here if you want the Radeon driver to output all sorts
+	  of debugging informations to provide to the maintainer when
+	  something goes wrong.
+
+config FB_ATY128
+	tristate "ATI Rage128 display support"
+	depends on FB && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MACMODES if PPC_PMAC
+	help
+	  This driver supports graphics boards with the ATI Rage128 chips.
+	  Say Y if you have such a graphics board and read
+	  <file:Documentation/fb/aty128fb.txt>.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called aty128fb.
+
+config FB_ATY
+	tristate "ATI Mach64 display support" if PCI || ATARI
+	depends on FB
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_MACMODES if PPC
+	help
+	  This driver supports graphics boards with the ATI Mach64 chips.
+	  Say Y if you have such a graphics board.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called atyfb.
+
+config FB_ATY_CT
+	bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support"
+	depends on PCI && FB_ATY
+	default y if SPARC64 && FB_PCI
+	help
+	  Say Y here to support use of ATI's 64-bit Rage boards (or other
+	  boards based on the Mach64 CT, VT, GT, and LT chipsets) as a
+	  framebuffer device.  The ATI product support page for these boards
+	  is at <http://support.ati.com/products/pc/mach64/>.
+
+config FB_ATY_GENERIC_LCD
+	bool "Mach64 generic LCD support (EXPERIMENTAL)"
+	depends on FB_ATY_CT
+	help
+	  Say Y if you have a laptop with an ATI Rage LT PRO, Rage Mobility,
+	  Rage XC, or Rage XL chipset.
+
+config FB_ATY_XL_INIT
+	bool "Rage XL No-BIOS Init support"
+	depends on FB_ATY_CT
+	help
+	  Say Y here to support booting a Rage XL without BIOS support.
+
+config FB_ATY_GX
+	bool "Mach64 GX support" if PCI
+	depends on FB_ATY
+	default y if ATARI
+	help
+	  Say Y here to support use of the ATI Mach64 Graphics Expression
+	  board (or other boards based on the Mach64 GX chipset) as a
+	  framebuffer device.  The ATI product support page for these boards
+	  is at
+	  <http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
+
+config FB_S3TRIO
+	bool "S3 Trio display support"
+	depends on (FB = y) && PPC && BROKEN
+	help
+	  If you have a S3 Trio say Y. Say N for S3 Virge.
+
+config FB_SAVAGE
+	tristate "S3 Savage support"
+	depends on FB && PCI && EXPERIMENTAL
+	select I2C_ALGOBIT if FB_SAVAGE_I2C
+	select I2C if FB_SAVAGE_I2C
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This driver supports notebooks and computers with S3 Savage PCI/AGP
+	  chips.
+
+	  Say Y if you have such a graphics card.
+
+	  To compile this driver as a module, choose M here; the module
+	  will be called savagefb.
+
+config FB_SAVAGE_I2C
+       bool "Enable DDC2 Support"
+       depends on FB_SAVAGE
+       help
+	  This enables I2C support for S3 Savage Chipsets.  This is used
+	  only for getting EDID information from the attached display
+	  allowing for robust video mode handling and switching.
+
+	  Because fbdev-2.6 requires that drivers must be able to
+	  independently validate video mode parameters, you should say Y
+	  here.
+
+config FB_SAVAGE_ACCEL
+       bool "Enable Console Acceleration"
+       depends on FB_SAVAGE
+       default n
+       help
+          This option will compile in console acceleration support. If
+          the resulting framebuffer console has bothersome glitches, then
+          choose N here.
+
+config FB_SIS
+	tristate "SiS/XGI display support"
+	depends on FB && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the SiS 300, 315, 330
+	  and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets.
+	  Specs available at <http://www.sis.com> and <http://www.xgitech.com>.
+
+	  To compile this driver as a module, choose M here; the module
+	  will be called sisfb.
+
+config FB_SIS_300
+	bool "SiS 300 series support"
+	depends on FB_SIS
+	help
+	  Say Y here to support use of the SiS 300/305, 540, 630 and 730.
+
+config FB_SIS_315
+	bool "SiS 315/330/340 series and XGI support"
+	depends on FB_SIS
+	help
+	  Say Y here to support use of the SiS 315, 330 and 340 series
+	  (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well
+	  as XGI V3XT, V5, V8 and Z7.
+
+config FB_NEOMAGIC
+	tristate "NeoMagic display support"
+	depends on FB && PCI
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This driver supports notebooks with NeoMagic PCI chips.
+	  Say Y if you have such a graphics card. 
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called neofb.
+
+config FB_KYRO
+	tristate "IMG Kyro support"
+	depends on FB && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  Say Y here if you have a STG4000 / Kyro / PowerVR 3 based
+	  graphics board.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called kyrofb.
+
+config FB_3DFX
+	tristate "3Dfx Banshee/Voodoo3 display support"
+	depends on FB && PCI
+	select FB_CFB_IMAGEBLIT
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	help
+	  This driver supports graphics boards with the 3Dfx Banshee/Voodoo3
+	  chips. Say Y if you have such a graphics board.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called tdfxfb.
+
+config FB_3DFX_ACCEL
+	bool "3Dfx Banshee/Voodoo3 Acceleration functions (EXPERIMENTAL)"
+	depends on FB_3DFX && EXPERIMENTAL
+	---help---
+	This will compile the 3Dfx Banshee/Voodoo3 frame buffer device
+	with acceleration functions.
+
+
+config FB_VOODOO1
+	tristate "3Dfx Voodoo Graphics (sst1) support"
+	depends on FB && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or 
+	  Voodoo2 (cvg) based graphics card.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called sstfb.
+
+	  WARNING: Do not use any application that uses the 3D engine
+	  (namely glide) while using this driver.
+	  Please read the <file:Documentation/fb/README-sstfb.txt> for supported
+	  options and other important info  support.
+
+config FB_CYBLA
+	tristate "Cyberblade/i1 support"
+	depends on FB && PCI
+	select FB_CFB_IMAGEBLIT
+	select VIDEO_SELECT
+	---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"
+	depends on FB && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  This driver is supposed to support graphics boards with the
+	  Trident CyberXXXX/Image/CyberBlade chips mostly found in laptops
+	  but also on some motherboards. For more information, read
+	  <file:Documentation/fb/tridentfb.txt>
+
+	  Cyberblade/i1 support will be removed soon, use the cyblafb driver
+	  instead.
+
+	  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_PM3
+	tristate "Permedia3 support"
+	depends on FB && PCI && BROKEN
+	help
+	  This is the frame buffer device driver for the 3DLabs Permedia3
+	  chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 &
+	  similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000
+	  and maybe other boards.
+
+config FB_AU1100
+	bool "Au1100 LCD Driver"
+	depends on (FB = y) && EXPERIMENTAL && PCI && MIPS && MIPS_PB1100=y
+
+source "drivers/video/geode/Kconfig"
+
+config FB_FFB
+	bool "Creator/Creator3D/Elite3D support"
+	depends on FB_SBUS && SPARC64
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the Creator, Creator3D,
+	  and Elite3D graphics boards.
+
+config FB_TCX
+	bool "TCX (SS4/SS5 only) support"
+	depends on FB_SBUS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the TCX 24/8bit frame
+	  buffer.
+
+config FB_CG14
+	bool "CGfourteen (SX) support"
+	depends on FB_SBUS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the CGfourteen frame
+	  buffer on Desktop SPARCsystems with the SX graphics option.
+
+config FB_P9100
+	bool "P9100 (Sparcbook 3 only) support"
+	depends on FB_SBUS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the P9100 card
+	  supported on Sparcbook 3 machines.
+
+config FB_LEO
+	bool "Leo (ZX) support"
+	depends on FB_SBUS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the SBUS-based Sun ZX
+	  (leo) frame buffer cards.
+
+config FB_PCI
+	bool "PCI framebuffers"
+	depends on (FB = y) && PCI && SPARC
+
+config FB_IGA
+	bool "IGA 168x display support"
+	depends on SPARC32 && FB_PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the framebuffer device for the INTERGRAPHICS 1680 and
+	  successor frame buffer cards.
+
+config FB_HIT
+	tristate "HD64461 Frame Buffer support"
+	depends on FB && HD64461
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This is the frame buffer device driver for the Hitachi HD64461 LCD
+	  frame buffer card.
+
+config FB_PMAG_AA
+	bool "PMAG-AA TURBOchannel framebuffer support"
+	depends on (FB = y) && TC
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+	help
+	  Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1)
+	  used mainly in the MIPS-based DECstation series.
+
+config FB_PMAG_BA
+	bool "PMAG-BA TURBOchannel framebuffer support"
+	depends on (FB = y) && TC
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+	help
+	  Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8)
+	  used mainly in the MIPS-based DECstation series.
+
+config FB_PMAGB_B
+	bool "PMAGB-B TURBOchannel framebuffer support"
+	depends on (FB = y) && TC
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+	help
+	  Support for the PMAGB-B TURBOchannel framebuffer card used mainly
+	  in the MIPS-based DECstation series. The card is currently only
+	  supported in 1280x1024x8 mode.
+
+config FB_MAXINE
+	bool "Maxine (Personal DECstation) onboard framebuffer support"
+	depends on (FB = y) && MACH_DECSTATION
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+	help
+	  Support for the onboard framebuffer (1024x768x8) in the Personal
+	  DECstation series (Personal DECstation 5000/20, /25, /33, /50,
+	  Codename "Maxine").
+
+config FB_TX3912
+	bool "TMPTX3912/PR31700 frame buffer support"
+	depends on (FB = y) && NINO
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  The TX3912 is a Toshiba RISC processor based on the MIPS 3900 core
+	  see <http://www.toshiba.com/taec/components/Generic/risc/tx3912.htm>.
+
+	  Say Y here to enable kernel support for the on-board framebuffer.
+
+config FB_G364
+	bool "G364 frame buffer support"
+	depends on (FB = y) && (MIPS_MAGNUM_4000 || OLIVETTI_M700)
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+	help
+	  The G364 driver is the framebuffer used in MIPS Magnum 4000 and
+	  Olivetti M700-10 systems.
+
+config FB_68328
+	bool "Motorola 68328 native frame buffer support"
+	depends on FB && (M68328 || M68EZ328 || M68VZ328)
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+	help
+	  Say Y here if you want to support the built-in frame buffer of
+	  the Motorola 68328 CPU family.
+
+config FB_PXA
+	tristate "PXA LCD framebuffer support"
+	depends on FB && ARCH_PXA
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Frame buffer driver for the built-in LCD controller in the Intel
+	  PXA2x0 processor.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted and removed from the running kernel whenever you want). The
+	  module will be called vfb. If you want to compile it as a module,
+	  say M here and read <file:Documentation/modules.txt>.
+
+	  If unsure, say N.
+
+config FB_PXA_PARAMETERS
+	bool "PXA LCD command line parameters"
+	default n
+	depends on FB_PXA
+	---help---
+	  Enable the use of kernel command line or module parameters
+	  to configure the physical properties of the LCD panel when
+	  using the PXA LCD driver.
+
+	  This option allows you to override the panel parameters
+	  supplied by the platform in order to support multiple
+	  different models of flatpanel. If you will only be using a
+	  single model of flatpanel then you can safely leave this
+	  option disabled.
+
+	  <file:Documentation/fb/pxafb.txt> describes the available parameters.
+
+config FB_W100
+	tristate "W100 frame buffer support"
+	depends on FB && PXA_SHARPSL
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+	---help---
+	  Frame buffer driver for the w100 as found on the Sharp SL-Cxx series.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted and removed from the running kernel whenever you want). The
+	  module will be called vfb. If you want to compile it as a module,
+	  say M here and read <file:Documentation/modules.txt>.
+
+	  If unsure, say N.
+
+config FB_S3C2410
+	tristate "S3C2410 LCD framebuffer support"
+	depends on FB && ARCH_S3C2410
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  Frame buffer driver for the built-in LCD controller in the Samsung
+	  S3C2410 processor.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted and removed from the running kernel whenever you want). The
+	  module will be called s3c2410fb. If you want to compile it as a module,
+	  say M here and read <file:Documentation/modules.txt>.
+
+	  If unsure, say N.
+config FB_S3C2410_DEBUG
+	bool "S3C2410 lcd debug messages"
+	depends on FB_S3C2410
+	help
+	  Turn on debugging messages. Note that you can set/unset at run time
+	  through sysfs
+
+config FB_VIRTUAL
+	tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
+	depends on FB
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	---help---
+	  This is a `virtual' frame buffer device. It operates on a chunk of
+	  unswappable kernel memory instead of on the memory of a graphics
+	  board. This means you cannot see any output sent to this frame
+	  buffer device, while it does consume precious memory. The main use
+	  of this frame buffer device is testing and debugging the frame
+	  buffer subsystem. Do NOT enable it for normal systems! To protect
+	  the innocent, it has to be enabled explicitly at boot time using the
+	  kernel option `video=vfb:'.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called vfb.
+
+	  If unsure, say N.
+if VT
+	source "drivers/video/console/Kconfig"
+endif
+
+if FB || SGI_NEWPORT_CONSOLE
+	source "drivers/video/logo/Kconfig"
+endif
+
+if FB && SYSFS
+	source "drivers/video/backlight/Kconfig"
+endif
+
+endmenu
+
diff -urN oldtree/drivers/video/Makefile newtree/drivers/video/Makefile
--- oldtree/drivers/video/Makefile	2006-01-03 03:21:10.000000000 +0000
+++ newtree/drivers/video/Makefile	2006-02-03 18:18:17.088732384 +0000
@@ -7,6 +7,7 @@
 obj-$(CONFIG_VT)		  += console/
 obj-$(CONFIG_LOGO)		  += logo/
 obj-$(CONFIG_SYSFS)		  += backlight/
+obj-$(CONFIG_FB_SPLASH)           += fbsplash.o cfbsplash.o
 
 obj-$(CONFIG_FB)                  += fb.o
 fb-y                              := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
diff -urN oldtree/drivers/video/cfbsplash.c newtree/drivers/video/cfbsplash.c
--- oldtree/drivers/video/cfbsplash.c	1970-01-01 00:00:00.000000000 +0000
+++ newtree/drivers/video/cfbsplash.c	2006-02-03 18:18:17.089732232 +0000
@@ -0,0 +1,472 @@
+/*
+ *  linux/drivers/video/cfbsplash.c -- Framebuffer splash render functions
+ *  
+ *  Copyright (C) 2004 Michal Januszewski <spock@gentoo.org>
+ *
+ *  Code based upon "Bootsplash" (C) 2001-2003 
+ *       Volker Poplawski <volker@poplawski.de>,
+ *       Stefan Reinauer <stepan@suse.de>,
+ *       Steffen Winterfeldt <snwint@suse.de>,
+ *       Michael Schroeder <mls@suse.de>,
+ *       Ken Wimer <wimer@suse.de>.
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */ 
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/fb.h>
+#include <linux/selection.h>
+#include <linux/vt_kern.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include "console/fbcon.h"
+#include "fbsplash.h"
+
+#define parse_pixel(shift,bpp,type)						\
+	do {									\
+		if (d & (0x80 >> (shift)))					\
+			dd2[(shift)] = fgx;					\
+		else								\
+			dd2[(shift)] = transparent ? *(type *)splash_src : bgx;	\
+		splash_src += (bpp);						\
+	} while (0)								\
+
+extern int get_color(struct vc_data *vc, struct fb_info *info,
+		     u16 c, int is_fg);
+
+void fbsplash_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc)
+{
+	int i, j, k;
+	int minlen = min(min(info->var.red.length, info->var.green.length), 
+			     info->var.blue.length);
+	u32 col;
+	
+	for (j = i = 0; i < 16; i++) {
+		k = color_table[i];
+                      
+		col = ((vc->vc_palette[j++]  >> (8-minlen)) 
+			<< info->var.red.offset);
+		col |= ((vc->vc_palette[j++] >> (8-minlen)) 
+			<< info->var.green.offset);
+		col |= ((vc->vc_palette[j++] >> (8-minlen)) 
+			<< info->var.blue.offset);
+			((u32 *)info->pseudo_palette)[k] = col;
+	}
+}
+				
+void fbsplash_renderc(struct fb_info *info, int ypos, int xpos, int height, 
+		      int width, u8* src, u32 fgx, u32 bgx, u8 transparent)
+{	
+	unsigned int x, y;
+	u32 dd;
+	int bytespp = ((info->var.bits_per_pixel + 7) >> 3);
+	unsigned int d = ypos * info->fix.line_length + xpos * bytespp;
+	unsigned int ds = (ypos * info->var.xres + xpos) * bytespp;
+	u16 dd2[4];
+
+	u8* splash_src = (u8 *)(info->splash.data + ds);
+	u8* dst = (u8 *)(info->screen_base + d);
+
+	if ((ypos + height) > info->var.yres || (xpos + width) > info->var.xres)
+		return;
+	
+	for (y = 0; y < height; y++) {
+		switch (info->var.bits_per_pixel) {
+	
+		case 32:
+			for (x = 0; x < width; x++) {
+
+				if ((x & 7) == 0)
+					d = *src++;
+				if (d & 0x80)
+					dd = fgx;
+				else
+					dd = transparent ? 
+					     *(u32 *)splash_src : bgx;
+				
+				d <<= 1;
+				splash_src += 4;
+				fb_writel(dd, dst);
+				dst += 4;
+			}
+			break;
+		case 24:
+			for (x = 0; x < width; x++) {
+
+				if ((x & 7) == 0)
+					d = *src++;
+				if (d & 0x80)
+					dd = fgx;
+				else
+					dd = transparent ? 
+					     (*(u32 *)splash_src & 0xffffff) : bgx;
+				
+				d <<= 1;
+				splash_src += 3;
+#ifdef __LITTLE_ENDIAN
+				fb_writew(dd & 0xffff, dst);
+				dst += 2;
+				fb_writeb((dd >> 16), dst);
+#else
+				fb_writew(dd >> 8, dst);
+				dst += 2;
+				fb_writeb(dd & 0xff, dst);
+#endif
+				dst++;
+			}
+			break;
+		case 16:
+			for (x = 0; x < width; x += 2) {
+		    		if ((x & 7) == 0)
+					d = *src++;
+
+				parse_pixel(0, 2, u16);
+				parse_pixel(1, 2, u16);
+#ifdef __LITTLE_ENDIAN
+				dd = dd2[0] | (dd2[1] << 16);
+#else
+				dd = dd2[1] | (dd2[0] << 16);
+#endif
+				d <<= 2;
+				fb_writel(dd, dst);
+				dst += 4;
+			}
+			break;
+
+		case 8:
+			for (x = 0; x < width; x += 4) {
+				if ((x & 7) == 0)
+					d = *src++;
+	
+				parse_pixel(0, 1, u8);
+				parse_pixel(1, 1, u8);
+				parse_pixel(2, 1, u8);
+				parse_pixel(3, 1, u8);
+		
+#ifdef __LITTLE_ENDIAN
+				dd = dd2[0] | (dd2[1] << 8) | (dd2[2] << 16) | (dd2[3] << 24);
+#else
+				dd = dd2[3] | (dd2[2] << 8) | (dd2[1] << 16) | (dd2[0] << 24);
+#endif
+				d <<= 4;
+				fb_writel(dd, dst);
+				dst += 4;
+			}		
+		}
+
+		dst += info->fix.line_length - width * bytespp;
+		splash_src += (info->var.xres - width) * bytespp;
+    	}
+}
+
+#define cc2cx(a) 						\
+	((info->fix.visual == FB_VISUAL_TRUECOLOR || 		\
+	  info->fix.visual == FB_VISUAL_DIRECTCOLOR) ? 		\
+	 ((u32*)info->pseudo_palette)[a] : a)
+
+void fbsplash_putcs(struct vc_data *vc, struct fb_info *info,
+		   const unsigned short *s, int count, int yy, int xx)
+{
+	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+	struct fbcon_ops *ops = info->fbcon_par;
+	int fg_color, bg_color, transparent;
+	u8 *src;
+	u32 bgx, fgx;
+	u16 c = scr_readw(s);
+
+	fg_color = get_color(vc, info, c, 1);
+        bg_color = get_color(vc, info, c, 0);
+	
+	/* Don't paint the background image if console is blanked */
+	transparent = ops->blank_state ? 0 : 
+		(vc->vc_splash.bg_color == bg_color);
+
+	xx = xx * vc->vc_font.width + vc->vc_splash.tx;
+	yy = yy * vc->vc_font.height + vc->vc_splash.ty;
+
+	fgx = cc2cx(fg_color);
+	bgx = cc2cx(bg_color);
+
+	while (count--) {
+		c = scr_readw(s++);
+		src = vc->vc_font.data + (c & charmask) * vc->vc_font.height *
+		      ((vc->vc_font.width + 7) >> 3);
+
+		fbsplash_renderc(info, yy, xx, vc->vc_font.height, 
+			       vc->vc_font.width, src, fgx, bgx, transparent);
+		xx += vc->vc_font.width;
+	}
+}
+
+void fbsplash_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+	int i;
+	unsigned int dsize, s_pitch;
+	struct fbcon_ops *ops = info->fbcon_par;
+	struct vc_data* vc;	
+	u8 *src;
+
+	/* we really don't need any cursors while the console is blanked */
+	if (info->state != FBINFO_STATE_RUNNING || ops->blank_state)
+		return;
+
+	vc = vc_cons[ops->currcon].d;
+
+	src = kmalloc(64 + sizeof(struct fb_image), GFP_ATOMIC);
+	if (!src)
+		return;
+
+	s_pitch = (cursor->image.width + 7) >> 3;
+	dsize = s_pitch * cursor->image.height;
+	if (cursor->enable) {	
+		switch (cursor->rop) {
+		case ROP_XOR:
+			for (i = 0; i < dsize; i++)
+				src[i] = cursor->image.data[i] ^ cursor->mask[i];
+                        break;
+		case ROP_COPY:
+		default:
+			for (i = 0; i < dsize; i++)
+				src[i] = cursor->image.data[i] & cursor->mask[i];
+			break;
+		}
+	} else
+		memcpy(src, cursor->image.data, dsize);
+
+	fbsplash_renderc(info,
+			cursor->image.dy + vc->vc_splash.ty,
+			cursor->image.dx + vc->vc_splash.tx,
+			cursor->image.height,
+			cursor->image.width,
+			(u8*)src,
+			cc2cx(cursor->image.fg_color),
+			cc2cx(cursor->image.bg_color),
+			cursor->image.bg_color == vc->vc_splash.bg_color);
+
+	kfree(src);
+}
+
+static void splashset(u8 *dst, int height, int width, int dstbytes, 
+		        u32 bgx, int bpp)
+{
+	int i;
+	
+	if (bpp == 8)
+		bgx |= bgx << 8;
+	if (bpp == 16 || bpp == 8)
+		bgx |= bgx << 16;
+	
+	while (height-- > 0) {
+		u8 *p = dst;
+		
+		switch (bpp) {
+		
+		case 32:
+			for (i=0; i < width; i++) {
+				fb_writel(bgx, p); p += 4;
+			}
+			break;
+		case 24:	
+			for (i=0; i < width; i++) {
+#ifdef __LITTLE_ENDIAN
+				fb_writew((bgx & 0xffff),(u16*)p); p += 2;
+				fb_writeb((bgx >> 16),p++);
+#else
+				fb_writew((bgx >> 8),(u16*)p); p += 2;
+				fb_writeb((bgx & 0xff),p++);
+#endif
+			}
+		case 16:
+			for (i=0; i < width/4; i++) {
+				fb_writel(bgx,p); p += 4;
+				fb_writel(bgx,p); p += 4;
+			}
+			if (width & 2) {
+				fb_writel(bgx,p); p += 4;
+			}
+			if (width & 1)
+				fb_writew(bgx,(u16*)p);
+			break;
+		case 8:
+			for (i=0; i < width/4; i++) {
+				fb_writel(bgx,p); p += 4;
+			}
+			
+			if (width & 2) {
+				fb_writew(bgx,p); p += 2;
+			}
+			if (width & 1)
+				fb_writeb(bgx,(u8*)p);
+			break;
+
+		}		
+		dst += dstbytes;
+	}
+}
+
+void fbsplash_copy(u8 *dst, u8 *src, int height, int width, int linebytes, 
+		   int srclinebytes, int bpp)
+{
+	int i;
+
+	while (height-- > 0) {
+		u32 *p = (u32 *)dst;
+		u32 *q = (u32 *)src;
+
+		switch (bpp) {
+	
+		case 32:
+			for (i=0; i < width; i++)
+				fb_writel(*q++, p++);
+			break;	
+		case 24:	
+			for (i=0; i < (width*3/4); i++)
+				fb_writel(*q++, p++);
+			if ((width*3) % 4) {
+				if (width & 2) {
+					fb_writeb(*(u8*)q, (u8*)p);
+				} else if (width & 1) {
+					fb_writew(*(u16*)q, (u16*)p);
+					fb_writeb(*(u8*)((u16*)q+1),(u8*)((u16*)p+2));
+				}
+			}
+			break;
+		case 16:
+			for (i=0; i < width/4; i++) {
+				fb_writel(*q++, p++);
+				fb_writel(*q++, p++);
+			}
+			if (width & 2)
+				fb_writel(*q++, p++);
+			if (width & 1)
+				fb_writew(*(u16*)q, (u16*)p);
+			break;
+		case 8:
+			for (i=0; i < width/4; i++) 
+				fb_writel(*q++, p++);
+				
+			if (width & 2) {
+				fb_writew(*(u16*)q, (u16*)p); 
+				q = (u32*) ((u16*)q + 1);
+				p = (u32*) ((u16*)p + 1);
+			}
+			if (width & 1)
+				fb_writeb(*(u8*)q, (u8*)p);
+			break;
+		}
+
+		dst += linebytes;
+		src += srclinebytes;
+	}
+}
+
+static void splashfill(struct fb_info *info, int sy, int sx, int height, 
+		       int width) 
+{
+	int bytespp = ((info->var.bits_per_pixel + 7) >> 3);
+	int d  = sy * info->fix.line_length + sx * bytespp;
+	int ds = (sy * info->var.xres + sx) * bytespp;
+
+	fbsplash_copy((u8 *)(info->screen_base + d), (u8 *)(info->splash.data + ds),
+		    height, width, info->fix.line_length, info->var.xres * bytespp,
+		    info->var.bits_per_pixel);
+}
+
+void fbsplash_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, 
+		    int height, int width)
+{
+	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+	int bg_color = attr_bgcol_ec(bgshift, vc);
+	int transparent = vc->vc_splash.bg_color == bg_color;
+	struct fbcon_ops *ops = info->fbcon_par;
+	u8 *dst;
+
+	sy = sy * vc->vc_font.height + vc->vc_splash.ty;
+	sx = sx * vc->vc_font.width + vc->vc_splash.tx;
+	height *= vc->vc_font.height;
+	width *= vc->vc_font.width;
+
+	/* Don't paint the background image if console is blanked */
+	if (transparent && !ops->blank_state) {
+		splashfill(info, sy, sx, height, width);
+	} else {
+		dst = (u8 *)(info->screen_base + sy * info->fix.line_length + 
+			     sx * ((info->var.bits_per_pixel + 7) >> 3));
+		splashset(dst, height, width, info->fix.line_length, cc2cx(bg_color), 
+			  info->var.bits_per_pixel);
+	}
+}
+
+void fbsplash_clear_margins(struct vc_data *vc, struct fb_info *info, 
+			    int bottom_only)
+{
+	unsigned int tw = vc->vc_cols*vc->vc_font.width;
+	unsigned int th = vc->vc_rows*vc->vc_font.height;
+
+	if (!bottom_only) {
+		/* top margin */
+		splashfill(info, 0, 0, vc->vc_splash.ty, info->var.xres);
+		/* left margin */
+		splashfill(info, vc->vc_splash.ty, 0, th, vc->vc_splash.tx);
+		/* right margin */
+		splashfill(info, vc->vc_splash.ty, vc->vc_splash.tx + tw, th, 
+			   info->var.xres - vc->vc_splash.tx - tw);
+	}
+	splashfill(info, vc->vc_splash.ty + th, 0, 
+		   info->var.yres - vc->vc_splash.ty - th, info->var.xres);
+}
+
+void fbsplash_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, 
+			   int sx, int dx, int width)
+{
+	u16 *d = (u16 *) (vc->vc_origin + vc->vc_size_row * y + dx * 2);
+	u16 *s = d + (dx - sx);
+	u16 *start = d;
+	u16 *ls = d;
+	u16 *le = d + width;
+	u16 c;
+	int x = dx;
+	u16 attr = 1;
+
+	do {
+		c = scr_readw(d);
+		if (attr != (c & 0xff00)) {
+			attr = c & 0xff00;
+			if (d > start) {
+				fbsplash_putcs(vc, info, start, d - start, y, x);
+				x += d - start;
+				start = d;
+			}
+		}
+		if (s >= ls && s < le && c == scr_readw(s)) {
+			if (d > start) {
+				fbsplash_putcs(vc, info, start, d - start, y, x);
+				x += d - start + 1;
+				start = d + 1;
+			} else {
+				x++;
+				start++;
+			}
+		}
+		s++;
+		d++;
+	} while (d < le);
+	if (d > start)
+		fbsplash_putcs(vc, info, start, d - start, y, x);
+}
+
+void fbsplash_blank(struct vc_data *vc, struct fb_info *info, int blank)
+{
+	if (blank) {
+		splashset((u8 *)info->screen_base, info->var.yres, info->var.xres,
+			  info->fix.line_length, 0, info->var.bits_per_pixel);
+	} else {
+		update_screen(vc);
+		fbsplash_clear_margins(vc, info, 0);
+	}
+}
+
diff -urN oldtree/drivers/video/console/bitblit.c newtree/drivers/video/console/bitblit.c
--- oldtree/drivers/video/console/bitblit.c	2006-01-03 03:21:10.000000000 +0000
+++ newtree/drivers/video/console/bitblit.c	2006-02-03 18:18:17.089732232 +0000
@@ -18,6 +18,7 @@
 #include <linux/console.h>
 #include <asm/types.h>
 #include "fbcon.h"
+#include "../fbsplash.h"
 
 /*
  * Accelerated handlers.
@@ -55,6 +56,13 @@
 	area.height = height * vc->vc_font.height;
 	area.width = width * vc->vc_font.width;
 
+	if (fbsplash_active(info, vc)) {
+ 		area.sx += vc->vc_splash.tx;
+ 		area.sy += vc->vc_splash.ty;
+ 		area.dx += vc->vc_splash.tx;
+ 		area.dy += vc->vc_splash.ty;
+ 	}
+
 	info->fbops->fb_copyarea(info, &area);
 }
 
@@ -380,11 +388,15 @@
 	cursor.image.depth = 1;
 	cursor.rop = ROP_XOR;
 
-	if (info->fbops->fb_cursor)
-		err = info->fbops->fb_cursor(info, &cursor);
+	if (fbsplash_active(info, vc)) {
+		fbsplash_cursor(info, &cursor);
+	} else {
+		if (info->fbops->fb_cursor)
+			err = info->fbops->fb_cursor(info, &cursor);
 
-	if (err)
-		soft_cursor(info, &cursor);
+		if (err)
+			soft_cursor(info, &cursor);
+	}
 
 	ops->cursor_reset = 0;
 }
diff -urN oldtree/drivers/video/console/fbcon.c newtree/drivers/video/console/fbcon.c
--- oldtree/drivers/video/console/fbcon.c	2006-01-03 03:21:10.000000000 +0000
+++ newtree/drivers/video/console/fbcon.c	2006-02-03 18:18:17.095731320 +0000
@@ -93,6 +93,7 @@
 #endif
 
 #include "fbcon.h"
+#include "../fbsplash.h"
 
 #ifdef FBCONDEBUG
 #  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
@@ -108,7 +109,7 @@
 
 static struct display fb_display[MAX_NR_CONSOLES];
 
-static signed char con2fb_map[MAX_NR_CONSOLES];
+signed char con2fb_map[MAX_NR_CONSOLES];
 static signed char con2fb_map_boot[MAX_NR_CONSOLES];
 static int logo_height;
 static int logo_lines;
@@ -298,7 +299,7 @@
 		vc->vc_mode != KD_TEXT || ops->graphics);
 }
 
-static inline int get_color(struct vc_data *vc, struct fb_info *info,
+inline int get_color(struct vc_data *vc, struct fb_info *info,
 	      u16 c, int is_fg)
 {
 	int depth = fb_get_color_depth(&info->var, &info->fix);
@@ -404,6 +405,7 @@
 		CM_ERASE : CM_DRAW;
 	ops->cursor(vc, info, p, mode, softback_lines, get_color(vc, info, c, 1),
 		    get_color(vc, info, c, 0));
+	
 	release_console_sem();
 }
 
@@ -568,6 +570,8 @@
 		info_idx = -1;
 	}
 
+	fbsplash_init();
+
 	return err;
 }
 
@@ -975,6 +979,12 @@
 	rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
 	cols /= vc->vc_font.width;
 	rows /= vc->vc_font.height;
+
+	if (fbsplash_active(info, vc)) {
+		cols = vc->vc_splash.twidth / vc->vc_font.width;
+		rows = vc->vc_splash.theight / vc->vc_font.height;
+	}
+
 	vc_resize(vc, cols, rows);
 
 	DPRINTK("mode:   %s\n", info->fix.id);
@@ -1057,7 +1067,7 @@
 	cap = info->flags;
 
 	if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
-	    (info->fix.type == FB_TYPE_TEXT))
+	    (info->fix.type == FB_TYPE_TEXT) || fbsplash_active(info, vc))
 		logo = 0;
 
 	if (var_to_display(p, &info->var, info))
@@ -1197,6 +1207,11 @@
 	if (!height || !width)
 		return;
 
+ 	if (fbsplash_active(info, vc)) {
+ 		fbsplash_clear(vc, info, sy, sx, height, width);
+ 		return;
+ 	}
+ 	
 	/* Split blits that cross physical y_wrap boundary */
 
 	y_break = p->vrows - p->yscroll;
@@ -1216,10 +1231,15 @@
 	struct display *p = &fb_display[vc->vc_num];
 	struct fbcon_ops *ops = info->fbcon_par;
 
-	if (!fbcon_is_inactive(vc, info))
-		ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
-			   get_color(vc, info, scr_readw(s), 1),
-			   get_color(vc, info, scr_readw(s), 0));
+	if (!fbcon_is_inactive(vc, info)) {
+		
+		if (fbsplash_active(info, vc))
+			fbsplash_putcs(vc, info, s, count, ypos, xpos);
+		else
+			ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
+				   get_color(vc, info, scr_readw(s), 1),
+				   get_color(vc, info, scr_readw(s), 0));
+	}
 }
 
 static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
@@ -1235,8 +1255,13 @@
 	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
 	struct fbcon_ops *ops = info->fbcon_par;
 
-	if (!fbcon_is_inactive(vc, info))
-		ops->clear_margins(vc, info, bottom_only);
+	if (!fbcon_is_inactive(vc, info)) {
+	 	if (fbsplash_active(info, vc)) {
+	 		fbsplash_clear_margins(vc, info, bottom_only);
+ 		} else {
+			ops->clear_margins(vc, info, bottom_only);
+		}
+	}
 }
 
 static void fbcon_cursor(struct vc_data *vc, int mode)
@@ -1716,7 +1741,7 @@
 			count = vc->vc_rows;
 		if (softback_top)
 			fbcon_softback_note(vc, t, count);
-		if (logo_shown >= 0)
+		if (logo_shown >= 0 || fbsplash_active(info, vc))
 			goto redraw_up;
 		switch (p->scrollmode) {
 		case SCROLL_MOVE:
@@ -1804,6 +1829,8 @@
 			count = vc->vc_rows;
 		if (logo_shown >= 0)
 			goto redraw_down;
+		if (fbsplash_active(info, vc))
+			goto redraw_down;
 		switch (p->scrollmode) {
 		case SCROLL_MOVE:
 			ops->bmove(vc, info, t, 0, t + count, 0,
@@ -1946,6 +1973,13 @@
 		}
 		return;
 	}
+
+	if (fbsplash_active(info, vc) && sy == dy && height == 1) {
+ 		/* must use slower redraw bmove to keep background pic intact */
+ 		fbsplash_bmove_redraw(vc, info, sy, sx, dx, width);
+ 		return;
+ 	}
+	
 	ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
 		   height, width);
 }
@@ -2015,8 +2049,9 @@
 	var.yres = virt_h * virt_fh;
 	x_diff = info->var.xres - var.xres;
 	y_diff = info->var.yres - var.yres;
-	if (x_diff < 0 || x_diff > virt_fw ||
-	    y_diff < 0 || y_diff > virt_fh) {
+
+	if ((x_diff < 0 || x_diff > virt_fw ||
+	    y_diff < 0 || y_diff > virt_fh) && !vc->vc_splash.state) {
 		struct fb_videomode *mode;
 
 		DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
@@ -2052,7 +2087,26 @@
 
 	info = registered_fb[con2fb_map[vc->vc_num]];
 	ops = info->fbcon_par;
-
+	prev_console = ops->currcon;
+	if (prev_console != -1)
+		old_info = registered_fb[con2fb_map[prev_console]];
+	
+	if (fbsplash_active_vc(vc)) {
+		struct vc_data *vc_curr = vc_cons[prev_console].d;
+		if (!vc_curr->vc_splash.theme || strcmp(vc->vc_splash.theme, vc_curr->vc_splash.theme)) {
+			if (fbsplash_call_helper("getpic", vc->vc_num))
+				fbsplash_disable(vc, 0);
+		}
+	} else if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) { 
+		struct vc_data *vc_curr = vc_cons[prev_console].d;
+		if (vc_curr && fbsplash_active_vc(vc_curr)) {
+			/* Clear the screen to avoid displaying funky colors during
+			 * palette updates. */ 
+			memset((u8*)info->screen_base + info->fix.line_length * info->var.yoffset,
+			       0, info->var.yres * info->fix.line_length);
+		}
+	}
+	
 	if (softback_top) {
 		if (softback_lines)
 			fbcon_set_origin(vc);
@@ -2070,9 +2124,6 @@
 		logo_shown = FBCON_LOGO_CANSHOW;
 	}
 
-	prev_console = ops->currcon;
-	if (prev_console != -1)
-		old_info = registered_fb[con2fb_map[prev_console]];
 	/*
 	 * FIXME: If we have multiple fbdev's loaded, we need to
 	 * update all info->currcon.  Perhaps, we can place this
@@ -2111,6 +2162,11 @@
 		fbcon_add_cursor_timer(info);
 	}
 
+	if (fbsplash_active_nores(info, vc) && !fbsplash_active(info, vc)) {
+		if (fbsplash_call_helper("modechange", vc->vc_num))
+			fbsplash_disable(vc, 0);
+	}
+
 	set_blitting_type(vc, info, p);
 	ops->cursor_reset = 1;
 
@@ -2212,8 +2268,12 @@
 			fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
 			ops->cursor_flash = (!blank);
 
-			if (fb_blank(info, blank))
-				fbcon_generic_blank(vc, info, blank);
+			if (fb_blank(info, blank)) {
+				if (fbsplash_active(info, vc))
+					fbsplash_blank(vc, info, blank);
+				else 
+					fbcon_generic_blank(vc, info, blank);
+			}
 		}
 
 		if (!blank)
@@ -2371,13 +2431,22 @@
 	}
 
 	if (resize) {
+		/* reset wrap/pan */
 		int cols, rows;
 
 		cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
 		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+
+ 		info->var.xoffset = info->var.yoffset = p->yscroll = 0;
+		if (fbsplash_active(info, vc)) {
+			cols = vc->vc_splash.twidth;
+			rows = vc->vc_splash.theight;
+		}
 		cols /= w;
 		rows /= h;
+
 		vc_resize(vc, cols, rows);
+
 		if (CON_IS_VISIBLE(vc) && softback_buf)
 			fbcon_update_softback(vc);
 	} else if (CON_IS_VISIBLE(vc)
@@ -2495,7 +2564,7 @@
 	int i, j, k, depth;
 	u8 val;
 
-	if (fbcon_is_inactive(vc, info))
+	if (fbcon_is_inactive(vc, info) || vc->vc_num != fg_console)
 		return -EINVAL;
 
 	if (!CON_IS_VISIBLE(vc))
@@ -2521,7 +2590,49 @@
 	} else
 		fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
 
-	return fb_set_cmap(&palette_cmap, info);
+	if (fbsplash_active(info, vc_cons[fg_console].d) &&
+	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+
+		u16 *red, *green, *blue;
+		int minlen = min(min(info->var.red.length, info->var.green.length), 
+				     info->var.blue.length);
+		int h;
+
+		struct fb_cmap cmap = {
+			.start = 0,
+			.len = (1 << minlen),
+			.red = NULL,
+			.green = NULL,
+			.blue = NULL,
+			.transp = NULL
+		};
+
+		red = kmalloc(256 * sizeof(u16) * 3, GFP_KERNEL);
+	
+		if (!red)
+			goto out;		
+	
+		green = red + 256;
+		blue = green + 256;
+		cmap.red = red;
+		cmap.green = green;
+		cmap.blue = blue;
+		
+		for (i = 0; i < cmap.len; i++) {
+			red[i] = green[i] = blue[i] = (0xffff * i)/(cmap.len-1);
+		}
+
+		h = fb_set_cmap(&cmap, info);
+		fbsplash_fix_pseudo_pal(info, vc_cons[fg_console].d);
+		kfree(red);
+		
+		return h;
+		
+	} else if (fbsplash_active(info, vc_cons[fg_console].d) && 
+		   info->var.bits_per_pixel == 8 && info->splash.cmap.red != NULL) 
+		fb_set_cmap(&info->splash.cmap, info);
+		
+out:	return fb_set_cmap(&palette_cmap, info);
 }
 
 static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
@@ -2747,7 +2858,14 @@
 		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
 		cols /= vc->vc_font.width;
 		rows /= vc->vc_font.height;
-		vc_resize(vc, cols, rows);
+				
+		if (!fbsplash_active_nores(info, vc)) {
+			vc_resize(vc, cols, rows);
+		} else {
+			if (fbsplash_call_helper("modechange", vc->vc_num))
+				fbsplash_disable(vc, 0);
+		}
+
 		updatescrollmode(p, info, vc);
 		scrollback_max = 0;
 		scrollback_current = 0;
diff -urN oldtree/drivers/video/console/fbcon.c.orig newtree/drivers/video/console/fbcon.c.orig
--- oldtree/drivers/video/console/fbcon.c.orig	1970-01-01 00:00:00.000000000 +0000
+++ newtree/drivers/video/console/fbcon.c.orig	2006-01-03 03:21:10.000000000 +0000
@@ -0,0 +1,3039 @@
+/*
+ *  linux/drivers/video/fbcon.c -- Low level frame buffer based console driver
+ *
+ *	Copyright (C) 1995 Geert Uytterhoeven
+ *
+ *
+ *  This file is based on the original Amiga console driver (amicon.c):
+ *
+ *	Copyright (C) 1993 Hamish Macdonald
+ *			   Greg Harp
+ *	Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk]
+ *
+ *	      with work by William Rucklidge (wjr@cs.cornell.edu)
+ *			   Geert Uytterhoeven
+ *			   Jes Sorensen (jds@kom.auc.dk)
+ *			   Martin Apel
+ *
+ *  and on the original Atari console driver (atacon.c):
+ *
+ *	Copyright (C) 1993 Bjoern Brauel
+ *			   Roman Hodek
+ *
+ *	      with work by Guenther Kelleter
+ *			   Martin Schaller
+ *			   Andreas Schwab
+ *
+ *  Hardware cursor support added by Emmanuel Marty (core@ggi-project.org)
+ *  Smart redraw scrolling, arbitrary font width support, 512char font support
+ *  and software scrollback added by 
+ *                         Jakub Jelinek (jj@ultra.linux.cz)
+ *
+ *  Random hacking by Martin Mares <mj@ucw.cz>
+ *
+ *	2001 - Documented with DocBook
+ *	- Brad Douglas <brad@neruo.com>
+ *
+ *  The low level operations for the various display memory organizations are
+ *  now in separate source files.
+ *
+ *  Currently the following organizations are supported:
+ *
+ *    o afb			Amiga bitplanes
+ *    o cfb{2,4,8,16,24,32}	Packed pixels
+ *    o ilbm			Amiga interleaved bitplanes
+ *    o iplan2p[248]		Atari interleaved bitplanes
+ *    o mfb			Monochrome
+ *    o vga			VGA characters/attributes
+ *
+ *  To do:
+ *
+ *    - Implement 16 plane mode (iplan2p16)
+ *
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#undef FBCONDEBUG
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>	/* MSch: for IRQ probe */
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <linux/kd.h>
+#include <linux/slab.h>
+#include <linux/fb.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/font.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/crc32.h> /* For counting font checksums */
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#ifdef CONFIG_ATARI
+#include <asm/atariints.h>
+#endif
+#ifdef CONFIG_MAC
+#include <asm/macints.h>
+#endif
+#if defined(__mc68000__) || defined(CONFIG_APUS)
+#include <asm/machdep.h>
+#include <asm/setup.h>
+#endif
+
+#include "fbcon.h"
+
+#ifdef FBCONDEBUG
+#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#else
+#  define DPRINTK(fmt, args...)
+#endif
+
+enum {
+	FBCON_LOGO_CANSHOW	= -1,	/* the logo can be shown */
+	FBCON_LOGO_DRAW		= -2,	/* draw the logo to a console */
+	FBCON_LOGO_DONTSHOW	= -3	/* do not show the logo */
+};
+
+static struct display fb_display[MAX_NR_CONSOLES];
+
+static signed char con2fb_map[MAX_NR_CONSOLES];
+static signed char con2fb_map_boot[MAX_NR_CONSOLES];
+static int logo_height;
+static int logo_lines;
+/* logo_shown is an index to vc_cons when >= 0; otherwise follows FBCON_LOGO
+   enums.  */
+static int logo_shown = FBCON_LOGO_CANSHOW;
+/* Software scrollback */
+static int fbcon_softback_size = 32768;
+static unsigned long softback_buf, softback_curr;
+static unsigned long softback_in;
+static unsigned long softback_top, softback_end;
+static int softback_lines;
+/* console mappings */
+static int first_fb_vc;
+static int last_fb_vc = MAX_NR_CONSOLES - 1;
+static int fbcon_is_default = 1; 
+/* font data */
+static char fontname[40];
+
+/* current fb_info */
+static int info_idx = -1;
+
+/* console rotation */
+static int rotate;
+
+static const struct consw fb_con;
+
+#define CM_SOFTBACK	(8)
+
+#define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row)
+
+static void fbcon_free_font(struct display *);
+static int fbcon_set_origin(struct vc_data *);
+
+#define CURSOR_DRAW_DELAY		(1)
+
+/* # VBL ints between cursor state changes */
+#define ATARI_CURSOR_BLINK_RATE		(42)
+#define MAC_CURSOR_BLINK_RATE		(32)
+#define DEFAULT_CURSOR_BLINK_RATE	(20)
+
+static int vbl_cursor_cnt;
+
+#define divides(a, b)	((!(a) || (b)%(a)) ? 0 : 1)
+
+/*
+ *  Interface used by the world
+ */
+
+static const char *fbcon_startup(void);
+static void fbcon_init(struct vc_data *vc, int init);
+static void fbcon_deinit(struct vc_data *vc);
+static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
+			int width);
+static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos);
+static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
+			int count, int ypos, int xpos);
+static void fbcon_clear_margins(struct vc_data *vc, int bottom_only);
+static void fbcon_cursor(struct vc_data *vc, int mode);
+static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
+			int count);
+static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,
+			int height, int width);
+static int fbcon_switch(struct vc_data *vc);
+static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch);
+static int fbcon_set_palette(struct vc_data *vc, unsigned char *table);
+static int fbcon_scrolldelta(struct vc_data *vc, int lines);
+
+/*
+ *  Internal routines
+ */
+static __inline__ void ywrap_up(struct vc_data *vc, int count);
+static __inline__ void ywrap_down(struct vc_data *vc, int count);
+static __inline__ void ypan_up(struct vc_data *vc, int count);
+static __inline__ void ypan_down(struct vc_data *vc, int count);
+static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx,
+			    int dy, int dx, int height, int width, u_int y_break);
+static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
+			   struct vc_data *vc);
+static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *var,
+			      int unit);
+static void fbcon_redraw_move(struct vc_data *vc, struct display *p,
+			      int line, int count, int dy);
+static void fbcon_modechanged(struct fb_info *info);
+static void fbcon_set_all_vcs(struct fb_info *info);
+
+#ifdef CONFIG_MAC
+/*
+ * On the Macintoy, there may or may not be a working VBL int. We need to probe
+ */
+static int vbl_detected;
+
+static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
+{
+	vbl_detected++;
+	return IRQ_HANDLED;
+}
+#endif
+
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
+static inline void fbcon_set_rotation(struct fb_info *info, struct display *p)
+{
+	struct fbcon_ops *ops = info->fbcon_par;
+
+	if (!(info->flags & FBINFO_MISC_TILEBLITTING) &&
+	    p->con_rotate < 4)
+		ops->rotate = p->con_rotate;
+	else
+		ops->rotate = 0;
+}
+
+static void fbcon_rotate(struct fb_info *info, u32 rotate)
+{
+	struct fbcon_ops *ops= info->fbcon_par;
+	struct fb_info *fb_info;
+
+	if (!ops || ops->currcon == -1)
+		return;
+
+	fb_info = registered_fb[con2fb_map[ops->currcon]];
+
+	if (info == fb_info) {
+		struct display *p = &fb_display[ops->currcon];
+
+		if (rotate < 4)
+			p->con_rotate = rotate;
+		else
+			p->con_rotate = 0;
+
+		fbcon_modechanged(info);
+	}
+}
+
+static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
+{
+	struct fbcon_ops *ops = info->fbcon_par;
+	struct vc_data *vc;
+	struct display *p;
+	int i;
+
+	if (!ops || ops->currcon < 0 || rotate > 3)
+		return;
+
+	for (i = 0; i < MAX_NR_CONSOLES; i++) {
+		vc = vc_cons[i].d;
+		if (!vc || vc->vc_mode != KD_TEXT ||
+		    registered_fb[con2fb_map[i]] != info)
+			continue;
+
+		p = &fb_display[vc->vc_num];
+		p->con_rotate = rotate;
+	}
+
+	fbcon_set_all_vcs(info);
+}
+#else
+static inline void fbcon_set_rotation(struct fb_info *info, struct display *p)
+{
+	struct fbcon_ops *ops = info->fbcon_par;
+
+	ops->rotate = FB_ROTATE_UR;
+}
+
+static void fbcon_rotate(struct fb_info *info, u32 rotate)
+{
+	return;
+}
+
+static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
+{
+	return;
+}
+#endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
+
+static int fbcon_get_rotate(struct fb_info *info)
+{
+	struct fbcon_ops *ops = info->fbcon_par;
+
+	return (ops) ? ops->rotate : 0;
+}
+
+static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
+{
+	struct fbcon_ops *ops = info->fbcon_par;
+
+	return (info->state != FBINFO_STATE_RUNNING ||
+		vc->vc_mode != KD_TEXT || ops->graphics);
+}
+
+static inline int get_color(struct vc_data *vc, struct fb_info *info,
+	      u16 c, int is_fg)
+{
+	int depth = fb_get_color_depth(&info->var, &info->fix);
+	int color = 0;
+
+	if (console_blanked) {
+		unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+
+		c = vc->vc_video_erase_char & charmask;
+	}
+
+	if (depth != 1)
+		color = (is_fg) ? attr_fgcol((vc->vc_hi_font_mask) ? 9 : 8, c)
+			: attr_bgcol((vc->vc_hi_font_mask) ? 13 : 12, c);
+
+	switch (depth) {
+	case 1:
+	{
+		int col = ~(0xfff << (max(info->var.green.length,
+					  max(info->var.red.length,
+					      info->var.blue.length)))) & 0xff;
+
+		/* 0 or 1 */
+		int fg = (info->fix.visual != FB_VISUAL_MONO01) ? col : 0;
+		int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : col;
+
+		if (console_blanked)
+			fg = bg;
+
+		color = (is_fg) ? fg : bg;
+		break;
+	}
+	case 2:
+		/*
+		 * Scale down 16-colors to 4 colors. Default 4-color palette
+		 * is grayscale. However, simply dividing the values by 4
+		 * will not work, as colors 1, 2 and 3 will be scaled-down
+		 * to zero rendering them invisible.  So empirically convert
+		 * colors to a sane 4-level grayscale.
+		 */
+		switch (color) {
+		case 0:
+			color = 0; /* black */
+			break;
+		case 1 ... 6:
+			color = 2; /* white */
+			break;
+		case 7 ... 8:
+			color = 1; /* gray */
+			break;
+		default:
+			color = 3; /* intense white */
+			break;
+		}
+		break;
+	case 3:
+		/*
+		 * Last 8 entries of default 16-color palette is a more intense
+		 * version of the first 8 (i.e., same chrominance, different
+		 * luminance).
+		 */
+		color &= 7;
+		break;
+	}
+
+
+	return color;
+}
+
+static void fbcon_update_softback(struct vc_data *vc)
+{
+	int l = fbcon_softback_size / vc->vc_size_row;
+
+	if (l > 5)
+		softback_end = softback_buf + l * vc->vc_size_row;
+	else
+		/* Smaller scrollback makes no sense, and 0 would screw
+		   the operation totally */
+		softback_top = 0;
+}
+
+static void fb_flashcursor(void *private)
+{
+	struct fb_info *info = private;
+	struct fbcon_ops *ops = info->fbcon_par;
+	struct display *p;
+	struct vc_data *vc = NULL;
+	int c;
+	int mode;
+
+	if (ops->currcon != -1)
+		vc = vc_cons[ops->currcon].d;
+
+	if (!vc || !CON_IS_VISIBLE(vc) ||
+	    fbcon_is_inactive(vc, info) ||
+ 	    registered_fb[con2fb_map[vc->vc_num]] != info ||
+	    vc_cons[ops->currcon].d->vc_deccm != 1)
+		return;
+	acquire_console_sem();
+	p = &fb_display[vc->vc_num];
+	c = scr_readw((u16 *) vc->vc_pos);
+	mode = (!ops->cursor_flash || ops->cursor_state.enable) ?
+		CM_ERASE : CM_DRAW;
+	ops->cursor(vc, info, p, mode, softback_lines, get_color(vc, info, c, 1),
+		    get_color(vc, info, c, 0));
+	release_console_sem();
+}
+
+#if defined(CONFIG_ATARI) || defined(CONFIG_MAC)
+static int cursor_blink_rate;
+static irqreturn_t fb_vbl_handler(int irq, void *dev_id, struct pt_regs *fp)
+{
+	struct fb_info *info = dev_id;
+
+	if (vbl_cursor_cnt && --vbl_cursor_cnt == 0) {
+		schedule_work(&info->queue);	
+		vbl_cursor_cnt = cursor_blink_rate; 
+	}
+	return IRQ_HANDLED;
+}
+#endif
+	
+static void cursor_timer_handler(unsigned long dev_addr)
+{
+	struct fb_info *info = (struct fb_info *) dev_addr;
+	struct fbcon_ops *ops = info->fbcon_par;
+
+	schedule_work(&info->queue);
+	mod_timer(&ops->cursor_timer, jiffies + HZ/5);
+}
+
+static void fbcon_add_cursor_timer(struct fb_info *info)
+{
+	struct fbcon_ops *ops = info->fbcon_par;
+
+	if ((!info->queue.func || info->queue.func == fb_flashcursor) &&
+	    !(ops->flags & FBCON_FLAGS_CURSOR_TIMER)) {
+		if (!info->queue.func)
+			INIT_WORK(&info->queue, fb_flashcursor, info);
+
+		init_timer(&ops->cursor_timer);
+		ops->cursor_timer.function = cursor_timer_handler;
+		ops->cursor_timer.expires = jiffies + HZ / 5;
+		ops->cursor_timer.data = (unsigned long ) info;
+		add_timer(&ops->cursor_timer);
+		ops->flags |= FBCON_FLAGS_CURSOR_TIMER;
+	}
+}
+
+static void fbcon_del_cursor_timer(struct fb_info *info)
+{
+	struct fbcon_ops *ops = info->fbcon_par;
+
+	if (info->queue.func == fb_flashcursor &&
+	    ops->flags & FBCON_FLAGS_CURSOR_TIMER) {
+		del_timer_sync(&ops->cursor_timer);
+		ops->flags &= ~FBCON_FLAGS_CURSOR_TIMER;
+	}
+}
+
+#ifndef MODULE
+static int __init fb_console_setup(char *this_opt)
+{
+	char *options;
+	int i, j;
+
+	if (!this_opt || !*this_opt)
+		return 0;
+
+	while ((options = strsep(&this_opt, ",")) != NULL) {
+		if (!strncmp(options, "font:", 5))
+			strcpy(fontname, options + 5);
+		
+		if (!strncmp(options, "scrollback:", 11)) {
+			options += 11;
+			if (*options) {
+				fbcon_softback_size = simple_strtoul(options, &options, 0);
+				if (*options == 'k' || *options == 'K') {
+					fbcon_softback_size *= 1024;
+					options++;
+				}
+				if (*options != ',')
+					return 0;
+				options++;
+			} else
+				return 0;
+		}
+		
+		if (!strncmp(options, "map:", 4)) {
+			options += 4;
+			if (*options)
+				for (i = 0, j = 0; i < MAX_NR_CONSOLES; i++) {
+					if (!options[j])
+						j = 0;
+					con2fb_map_boot[i] =
+						(options[j++]-'0') % FB_MAX;
+				}
+			return 0;
+		}
+
+		if (!strncmp(options, "vc:", 3)) {
+			options += 3;
+			if (*options)
+				first_fb_vc = simple_strtoul(options, &options, 10) - 1;
+			if (first_fb_vc < 0)
+				first_fb_vc = 0;
+			if (*options++ == '-')
+				last_fb_vc = simple_strtoul(options, &options, 10) - 1;
+			fbcon_is_default = 0; 
+		}	
+
+		if (!strncmp(options, "rotate:", 7)) {
+			options += 7;
+			if (*options)
+				rotate = simple_strtoul(options, &options, 0);
+			if (rotate > 3)
+				rotate = 0;
+		}
+	}
+	return 0;
+}
+
+__setup("fbcon=", fb_console_setup);
+#endif
+
+static int search_fb_in_map(int idx)
+{
+	int i, retval = 0;
+
+	for (i = 0; i < MAX_NR_CONSOLES; i++) {
+		if (con2fb_map[i] == idx)
+			retval = 1;
+	}
+	return retval;
+}
+
+static int search_for_mapped_con(void)
+{
+	int i, retval = 0;
+
+	for (i = 0; i < MAX_NR_CONSOLES; i++) {
+		if (con2fb_map[i] != -1)
+			retval = 1;
+	}
+	return retval;
+}
+
+static int fbcon_takeover(int show_logo)
+{
+	int err, i;
+
+	if (!num_registered_fb)
+		return -ENODEV;
+
+	if (!show_logo)
+		logo_shown = FBCON_LOGO_DONTSHOW;
+
+	for (i = first_fb_vc; i <= last_fb_vc; i++)
+		con2fb_map[i] = info_idx;
+
+	err = take_over_console(&fb_con, first_fb_vc, last_fb_vc,
+				fbcon_is_default);
+	if (err) {
+		for (i = first_fb_vc; i <= last_fb_vc; i++) {
+			con2fb_map[i] = -1;
+		}
+		info_idx = -1;
+	}
+
+	return err;
+}
+
+static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
+			       int cols, int rows, int new_cols, int new_rows)
+{
+	/* Need to make room for the logo */
+	struct fbcon_ops *ops = info->fbcon_par;
+	int cnt, erase = vc->vc_video_erase_char, step;
+	unsigned short *save = NULL, *r, *q;
+
+	/*
+	 * remove underline attribute from erase character
+	 * if black and white framebuffer.
+	 */
+	if (fb_get_color_depth(&info->var, &info->fix) == 1)
+		erase &= ~0x400;
+	logo_height = fb_prepare_logo(info, ops->rotate);
+	logo_lines = (logo_height + vc->vc_font.height - 1) /
+		vc->vc_font.height;
+	q = (unsigned short *) (vc->vc_origin +
+				vc->vc_size_row * rows);
+	step = logo_lines * cols;
+	for (r = q - logo_lines * cols; r < q; r++)
+		if (scr_readw(r) != vc->vc_video_erase_char)
+			break;
+	if (r != q && new_rows >= rows + logo_lines) {
+		save = kmalloc(logo_lines * new_cols * 2, GFP_KERNEL);
+		if (save) {
+			int i = cols < new_cols ? cols : new_cols;
+			scr_memsetw(save, erase, logo_lines * new_cols * 2);
+			r = q - step;
+			for (cnt = 0; cnt < logo_lines; cnt++, r += i)
+				scr_memcpyw(save + cnt * new_cols, r, 2 * i);
+			r = q;
+		}
+	}
+	if (r == q) {
+		/* We can scroll screen down */
+		r = q - step - cols;
+		for (cnt = rows - logo_lines; cnt > 0; cnt--) {
+			scr_memcpyw(r + step, r, vc->vc_size_row);
+			r -= cols;
+		}
+		if (!save) {
+			vc->vc_y += logo_lines;
+			vc->vc_pos += logo_lines * vc->vc_size_row;
+		}
+	}
+	scr_memsetw((unsigned short *) vc->vc_origin,
+		    erase,
+		    vc->vc_size_row * logo_lines);
+
+	if (CON_IS_VISIBLE(vc) && vc->vc_mode == KD_TEXT) {
+		fbcon_clear_margins(vc, 0);
+		update_screen(vc);
+	}
+
+	if (save) {
+		q = (unsigned short *) (vc->vc_origin +
+					vc->vc_size_row *
+					rows);
+		scr_memcpyw(q, save, logo_lines * new_cols * 2);
+		vc->vc_y += logo_lines;
+		vc->vc_pos += logo_lines * vc->vc_size_row;
+		kfree(save);
+	}
+
+	if (logo_lines > vc->vc_bottom) {
+		logo_shown = FBCON_LOGO_CANSHOW;
+		printk(KERN_INFO
+		       "fbcon_init: disable boot-logo (boot-logo bigger than screen).\n");
+	} else if (logo_shown != FBCON_LOGO_DONTSHOW) {
+		logo_shown = FBCON_LOGO_DRAW;
+		vc->vc_top = logo_lines;
+	}
+}
+
+#ifdef CONFIG_FB_TILEBLITTING
+static void set_blitting_type(struct vc_data *vc, struct fb_info *info,
+			      struct display *p)
+{
+	struct fbcon_ops *ops = info->fbcon_par;
+
+	ops->p = (p) ? p : &fb_display[vc->vc_num];
+
+	if ((info->flags & FBINFO_MISC_TILEBLITTING))
+		fbcon_set_tileops(vc, info, p, ops);
+	else {
+		fbcon_set_rotation(info, ops->p);
+		fbcon_set_bitops(ops);
+	}
+}
+#else
+static void set_blitting_type(struct vc_data *vc, struct fb_info *info,
+			      struct display *p)
+{
+	struct fbcon_ops *ops = info->fbcon_par;
+
+	info->flags &= ~FBINFO_MISC_TILEBLITTING;
+	ops->p = (p) ? p : &fb_display[vc->vc_num];
+	fbcon_set_rotation(info, ops->p);
+	fbcon_set_bitops(ops);
+}
+#endif /* CONFIG_MISC_TILEBLITTING */
+
+
+static int con2fb_acquire_newinfo(struct vc_data *vc, struct fb_info *info,
+				  int unit, int oldidx)
+{
+	struct fbcon_ops *ops = NULL;
+	int err = 0;
+
+	if (!try_module_get(info->fbops->owner))
+		err = -ENODEV;
+
+	if (!err && info->fbops->fb_open &&
+	    info->fbops->fb_open(info, 0))
+		err = -ENODEV;
+
+	if (!err) {
+		ops = kmalloc(sizeof(struct fbcon_ops), GFP_KERNEL);
+		if (!ops)
+			err = -ENOMEM;
+	}
+
+	if (!err) {
+		memset(ops, 0, sizeof(struct fbcon_ops));
+		info->fbcon_par = ops;
+		set_blitting_type(vc, info, NULL);
+	}
+
+	if (err) {
+		con2fb_map[unit] = oldidx;
+		module_put(info->fbops->owner);
+	}
+
+	return err;
+}
+
+static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,
+				  struct fb_info *newinfo, int unit,
+				  int oldidx, int found)
+{
+	struct fbcon_ops *ops = oldinfo->fbcon_par;
+	int err = 0;
+
+	if (oldinfo->fbops->fb_release &&
+	    oldinfo->fbops->fb_release(oldinfo, 0)) {
+		con2fb_map[unit] = oldidx;
+		if (!found && newinfo->fbops->fb_release)
+			newinfo->fbops->fb_release(newinfo, 0);
+		if (!found)
+			module_put(newinfo->fbops->owner);
+		err = -ENODEV;
+	}
+
+	if (!err) {
+		fbcon_del_cursor_timer(oldinfo);
+		kfree(ops->cursor_state.mask);
+		kfree(ops->cursor_data);
+		kfree(ops->fontbuffer);
+		kfree(oldinfo->fbcon_par);
+		oldinfo->fbcon_par = NULL;
+		module_put(oldinfo->fbops->owner);
+		/*
+		  If oldinfo and newinfo are driving the same hardware,
+		  the fb_release() method of oldinfo may attempt to
+		  restore the hardware state.  This will leave the
+		  newinfo in an undefined state. Thus, a call to
+		  fb_set_par() may be needed for the newinfo.
+		*/
+		if (newinfo->fbops->fb_set_par)
+			newinfo->fbops->fb_set_par(newinfo);
+	}
+
+	return err;
+}
+
+static void con2fb_init_display(struct vc_data *vc, struct fb_info *info,
+				int unit, int show_logo)
+{
+	struct fbcon_ops *ops = info->fbcon_par;
+
+	ops->currcon = fg_console;
+
+	if (info->fbops->fb_set_par && !(ops->flags & FBCON_FLAGS_INIT))
+		info->fbops->fb_set_par(info);
+
+	ops->flags |= FBCON_FLAGS_INIT;
+	ops->graphics = 0;
+
+	if (vc)
+		fbcon_set_disp(info, &info->var, vc);
+	else
+		fbcon_preset_disp(info, &info->var, unit);
+
+	if (show_logo) {
+		struct vc_data *fg_vc = vc_cons[fg_console].d;
+		struct fb_info *fg_info =
+			registered_fb[con2fb_map[fg_console]];
+
+		fbcon_prepare_logo(fg_vc, fg_info, fg_vc->vc_cols,
+				   fg_vc->vc_rows, fg_vc->vc_cols,
+				   fg_vc->vc_rows);
+	}
+
+	update_screen(vc_cons[fg_console].d);
+}
+
+/**
+ *	set_con2fb_map - map console to frame buffer device
+ *	@unit: virtual console number to map
+ *	@newidx: frame buffer index to map virtual console to
+ *      @user: user request
+ *
+ *	Maps a virtual console @unit to a frame buffer device
+ *	@newidx.
+ */
+static int set_con2fb_map(int unit, int newidx, int user)
+{
+	struct vc_data *vc = vc_cons[unit].d;
+	int oldidx = con2fb_map[unit];
+	struct fb_info *info = registered_fb[newidx];
+	struct fb_info *oldinfo = NULL;
+ 	int found, err = 0;
+
+	if (oldidx == newidx)
+		return 0;
+
+	if (!info)
+ 		err =  -EINVAL;
+
+ 	if (!err && !search_for_mapped_con()) {
+		info_idx = newidx;
+		return fbcon_takeover(0);
+	}
+
+	if (oldidx != -1)
+		oldinfo = registered_fb[oldidx];
+
+	found = search_fb_in_map(newidx);
+
+	acquire_console_sem();
+	con2fb_map[unit] = newidx;
+	if (!err && !found)
+ 		err = con2fb_acquire_newinfo(vc, info, unit, oldidx);
+
+
+	/*
+	 * If old fb is not mapped to any of the consoles,
+	 * fbcon should release it.
+	 */
+ 	if (!err && oldinfo && !search_fb_in_map(oldidx))
+ 		err = con2fb_release_oldinfo(vc, oldinfo, info, unit, oldidx,
+ 					     found);
+
+ 	if (!err) {
+ 		int show_logo = (fg_console == 0 && !user &&
+ 				 logo_shown != FBCON_LOGO_DONTSHOW);
+
+ 		if (!found)
+ 			fbcon_add_cursor_timer(info);
+ 		con2fb_map_boot[unit] = newidx;
+ 		con2fb_init_display(vc, info, unit, show_logo);
+	}
+
+	release_console_sem();
+ 	return err;
+}
+
+/*
+ *  Low Level Operations
+ */
+/* NOTE: fbcon cannot be __init: it may be called from take_over_console later */
+static int var_to_display(struct display *disp,
+			  struct fb_var_screeninfo *var,
+			  struct fb_info *info)
+{
+	disp->xres_virtual = var->xres_virtual;
+	disp->yres_virtual = var->yres_virtual;
+	disp->bits_per_pixel = var->bits_per_pixel;
+	disp->grayscale = var->grayscale;
+	disp->nonstd = var->nonstd;
+	disp->accel_flags = var->accel_flags;
+	disp->height = var->height;
+	disp->width = var->width;
+	disp->red = var->red;
+	disp->green = var->green;
+	disp->blue = var->blue;
+	disp->transp = var->transp;
+	disp->rotate = var->rotate;
+	disp->mode = fb_match_mode(var, &info->modelist);
+	if (disp->mode == NULL)
+		/* This should not happen */
+		return -EINVAL;
+	return 0;
+}
+
+static void display_to_var(struct fb_var_screeninfo *var,
+			   struct display *disp)
+{
+	fb_videomode_to_var(var, disp->mode);
+	var->xres_virtual = disp->xres_virtual;
+	var->yres_virtual = disp->yres_virtual;
+	var->bits_per_pixel = disp->bits_per_pixel;
+	var->grayscale = disp->grayscale;
+	var->nonstd = disp->nonstd;
+	var->accel_flags = disp->accel_flags;
+	var->height = disp->height;
+	var->width = disp->width;
+	var->red = disp->red;
+	var->green = disp->green;
+	var->blue = disp->blue;
+	var->transp = disp->transp;
+	var->rotate = disp->rotate;
+}
+
+static const char *fbcon_startup(void)
+{
+	const char *display_desc = "frame buffer device";
+	struct display *p = &fb_display[fg_console];
+	struct vc_data *vc = vc_cons[fg_console].d;
+	const struct font_desc *font = NULL;
+	struct module *owner;
+	struct fb_info *info = NULL;
+	struct fbcon_ops *ops;
+	int rows, cols;
+	int irqres;
+
+	irqres = 1;
+	/*
+	 *  If num_registered_fb is zero, this is a call for the dummy part.
+	 *  The frame buffer devices weren't initialized yet.
+	 */
+	if (!num_registered_fb || info_idx == -1)
+		return display_desc;
+	/*
+	 * Instead of blindly using registered_fb[0], we use info_idx, set by
+	 * fb_console_init();
+	 */
+	info = registered_fb[info_idx];
+	if (!info)
+		return NULL;
+	
+	owner = info->fbops->owner;
+	if (!try_module_get(owner))
+		return NULL;
+	if (info->fbops->fb_open && info->fbops->fb_open(info, 0)) {
+		module_put(owner);
+		return NULL;
+	}
+
+	ops = kmalloc(sizeof(struct fbcon_ops), GFP_KERNEL);
+	if (!ops) {
+		module_put(owner);
+		return NULL;
+	}
+
+	memset(ops, 0, sizeof(struct fbcon_ops));
+	ops->currcon = -1;
+	ops->graphics = 1;
+	ops->cur_rotate = -1;
+	info->fbcon_par = ops;
+	p->con_rotate = rotate;
+	set_blitting_type(vc, info, NULL);
+
+	if (info->fix.type != FB_TYPE_TEXT) {
+		if (fbcon_softback_size) {
+			if (!softback_buf) {
+				softback_buf =
+				    (unsigned long)
+				    kmalloc(fbcon_softback_size,
+					    GFP_KERNEL);
+				if (!softback_buf) {
+					fbcon_softback_size = 0;
+					softback_top = 0;
+				}
+			}
+		} else {
+			if (softback_buf) {
+				kfree((void *) softback_buf);
+				softback_buf = 0;
+				softback_top = 0;
+			}
+		}
+		if (softback_buf)
+			softback_in = softback_top = softback_curr =
+			    softback_buf;
+		softback_lines = 0;
+	}
+
+	/* Setup default font */
+	if (!p->fontdata) {
+		if (!fontname[0] || !(font = find_font(fontname)))
+			font = get_default_font(info->var.xres,
+						info->var.yres);
+		vc->vc_font.width = font->width;
+		vc->vc_font.height = font->height;
+		vc->vc_font.data = (void *)(p->fontdata = font->data);
+		vc->vc_font.charcount = 256; /* FIXME  Need to support more fonts */
+	}
+
+	cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
+	rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+	cols /= vc->vc_font.width;
+	rows /= vc->vc_font.height;
+	vc_resize(vc, cols, rows);
+
+	DPRINTK("mode:   %s\n", info->fix.id);
+	DPRINTK("visual: %d\n", info->fix.visual);
+	DPRINTK("res:    %dx%d-%d\n", info->var.xres,
+		info->var.yres,
+		info->var.bits_per_pixel);
+
+#ifdef CONFIG_ATARI
+	if (MACH_IS_ATARI) {
+		cursor_blink_rate = ATARI_CURSOR_BLINK_RATE;
+		irqres =
+		    request_irq(IRQ_AUTO_4, fb_vbl_handler,
+				IRQ_TYPE_PRIO, "framebuffer vbl",
+				info);
+	}
+#endif				/* CONFIG_ATARI */
+
+#ifdef CONFIG_MAC
+	/*
+	 * On a Macintoy, the VBL interrupt may or may not be active. 
+	 * As interrupt based cursor is more reliable and race free, we 
+	 * probe for VBL interrupts.
+	 */
+	if (MACH_IS_MAC) {
+		int ct = 0;
+		/*
+		 * Probe for VBL: set temp. handler ...
+		 */
+		irqres = request_irq(IRQ_MAC_VBL, fb_vbl_detect, 0,
+				     "framebuffer vbl", info);
+		vbl_detected = 0;
+
+		/*
+		 * ... and spin for 20 ms ...
+		 */
+		while (!vbl_detected && ++ct < 1000)
+			udelay(20);
+
+		if (ct == 1000)
+			printk
+			    ("fbcon_startup: No VBL detected, using timer based cursor.\n");
+
+		free_irq(IRQ_MAC_VBL, fb_vbl_detect);
+
+		if (vbl_detected) {
+			/*
+			 * interrupt based cursor ok
+			 */
+			cursor_blink_rate = MAC_CURSOR_BLINK_RATE;
+			irqres =
+			    request_irq(IRQ_MAC_VBL, fb_vbl_handler, 0,
+					"framebuffer vbl", info);
+		} else {
+			/*
+			 * VBL not detected: fall through, use timer based cursor
+			 */
+			irqres = 1;
+		}
+	}
+#endif				/* CONFIG_MAC */
+
+	fbcon_add_cursor_timer(info);
+	return display_desc;
+}
+
+static void fbcon_init(struct vc_data *vc, int init)
+{
+	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+	struct fbcon_ops *ops;
+	struct vc_data **default_mode = vc->vc_display_fg;
+	struct vc_data *svc = *default_mode;
+	struct display *t, *p = &fb_display[vc->vc_num];
+	int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256;
+	int cap;
+
+	if (info_idx == -1 || info == NULL)
+	    return;
+
+	cap = info->flags;
+
+	if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
+	    (info->fix.type == FB_TYPE_TEXT))
+		logo = 0;
+
+	if (var_to_display(p, &info->var, info))
+		return;
+
+	/* If we are not the first console on this
+	   fb, copy the font from that console */
+	t = &fb_display[svc->vc_num];
+	if (!vc->vc_font.data) {
+		vc->vc_font.data = (void *)(p->fontdata = t->fontdata);
+		vc->vc_font.width = (*default_mode)->vc_font.width;
+		vc->vc_font.height = (*default_mode)->vc_font.height;
+		p->userfont = t->userfont;
+		if (p->userfont)
+			REFCOUNT(p->fontdata)++;
+	}
+	if (p->userfont)
+		charcnt = FNTCHARCNT(p->fontdata);
+	vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
+	vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
+	if (charcnt == 256) {
+		vc->vc_hi_font_mask = 0;
+	} else {
+		vc->vc_hi_font_mask = 0x100;
+		if (vc->vc_can_do_color)
+			vc->vc_complement_mask <<= 1;
+	}
+
+	if (!*svc->vc_uni_pagedir_loc)
+		con_set_default_unimap(svc);
+	if (!*vc->vc_uni_pagedir_loc)
+		con_copy_unimap(vc, svc);
+
+	ops = info->fbcon_par;
+	p->con_rotate = rotate;
+	set_blitting_type(vc, info, NULL);
+
+	cols = vc->vc_cols;
+	rows = vc->vc_rows;
+	new_cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
+	new_rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+	new_cols /= vc->vc_font.width;
+	new_rows /= vc->vc_font.height;
+	vc_resize(vc, new_cols, new_rows);
+
+	/*
+	 * We must always set the mode. The mode of the previous console
+	 * driver could be in the same resolution but we are using different
+	 * hardware so we have to initialize the hardware.
+	 *
+	 * We need to do it in fbcon_init() to prevent screen corruption.
+	 */
+	if (CON_IS_VISIBLE(vc)) {
+		if (info->fbops->fb_set_par &&
+		    !(ops->flags & FBCON_FLAGS_INIT))
+			info->fbops->fb_set_par(info);
+		ops->flags |= FBCON_FLAGS_INIT;
+	}
+
+	ops->graphics = 0;
+
+	if ((cap & FBINFO_HWACCEL_COPYAREA) &&
+	    !(cap & FBINFO_HWACCEL_DISABLED))
+		p->scrollmode = SCROLL_MOVE;
+	else /* default to something safe */
+		p->scrollmode = SCROLL_REDRAW;
+
+	/*
+	 *  ++guenther: console.c:vc_allocate() relies on initializing
+	 *  vc_{cols,rows}, but we must not set those if we are only
+	 *  resizing the console.
+	 */
+	if (!init) {
+		vc->vc_cols = new_cols;
+		vc->vc_rows = new_rows;
+	}
+
+	if (logo)
+		fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows);
+
+	if (vc == svc && softback_buf)
+		fbcon_update_softback(vc);
+
+	if (ops->rotate_font && ops->rotate_font(info, vc, p)) {
+		ops->rotate = FB_ROTATE_UR;
+		set_blitting_type(vc, info, p);
+	}
+
+}
+
+static void fbcon_deinit(struct vc_data *vc)
+{
+	struct display *p = &fb_display[vc->vc_num];
+
+	if (info_idx != -1)
+	    return;
+	fbcon_free_font(p);
+}
+
+/* ====================================================================== */
+
+/*  fbcon_XXX routines - interface used by the world
+ *
+ *  This system is now divided into two levels because of complications
+ *  caused by hardware scrolling. Top level functions:
+ *
+ *	fbcon_bmove(), fbcon_clear(), fbcon_putc(), fbcon_clear_margins()
+ *
+ *  handles y values in range [0, scr_height-1] that correspond to real
+ *  screen positions. y_wrap shift means that first line of bitmap may be
+ *  anywhere on this display. These functions convert lineoffsets to
+ *  bitmap offsets and deal with the wrap-around case by splitting blits.
+ *
+ *	fbcon_bmove_physical_8()    -- These functions fast implementations
+ *	fbcon_clear_physical_8()    -- of original fbcon_XXX fns.
+ *	fbcon_putc_physical_8()	    -- (font width != 8) may be added later
+ *
+ *  WARNING:
+ *
+ *  At the moment fbcon_putc() cannot blit across vertical wrap boundary
+ *  Implies should only really hardware scroll in rows. Only reason for
+ *  restriction is simplicity & efficiency at the moment.
+ */
+
+static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
+			int width)
+{
+	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+	struct fbcon_ops *ops = info->fbcon_par;
+
+	struct display *p = &fb_display[vc->vc_num];
+	u_int y_break;
+
+	if (fbcon_is_inactive(vc, info))
+		return;
+
+	if (!height || !width)
+		return;
+
+	/* Split blits that cross physical y_wrap boundary */
+
+	y_break = p->vrows - p->yscroll;
+	if (sy < y_break && sy + height - 1 >= y_break) {
+		u_int b = y_break - sy;
+		ops->clear(vc, info, real_y(p, sy), sx, b, width);
+		ops->clear(vc, info, real_y(p, sy + b), sx, height - b,
+				 width);
+	} else
+		ops->clear(vc, info, real_y(p, sy), sx, height, width);
+}
+
+static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
+			int count, int ypos, int xpos)
+{
+	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+	struct display *p = &fb_display[vc->vc_num];
+	struct fbcon_ops *ops = info->fbcon_par;
+
+	if (!fbcon_is_inactive(vc, info))
+		ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
+			   get_color(vc, info, scr_readw(s), 1),
+			   get_color(vc, info, scr_readw(s), 0));
+}
+
+static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
+{
+	unsigned short chr;
+
+	scr_writew(c, &chr);
+	fbcon_putcs(vc, &chr, 1, ypos, xpos);
+}
+
+static void fbcon_clear_margins(struct vc_data *vc, int bottom_only)
+{
+	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+	struct fbcon_ops *ops = info->fbcon_par;
+
+	if (!fbcon_is_inactive(vc, info))
+		ops->clear_margins(vc, info, bottom_only);
+}
+
+static void fbcon_cursor(struct vc_data *vc, int mode)
+{
+	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+	struct fbcon_ops *ops = info->fbcon_par;
+	struct display *p = &fb_display[vc->vc_num];
+	int y;
+ 	int c = scr_readw((u16 *) vc->vc_pos);
+
+	if (fbcon_is_inactive(vc, info))
+		return;
+
+	ops->cursor_flash = (mode == CM_ERASE) ? 0 : 1;
+	if (mode & CM_SOFTBACK) {
+		mode &= ~CM_SOFTBACK;
+		y = softback_lines;
+	} else {
+		if (softback_lines)
+			fbcon_set_origin(vc);
+		y = 0;
+	}
+
+	ops->cursor(vc, info, p, mode, y, get_color(vc, info, c, 1),
+		    get_color(vc, info, c, 0));
+	vbl_cursor_cnt = CURSOR_DRAW_DELAY;
+}
+
+static int scrollback_phys_max = 0;
+static int scrollback_max = 0;
+static int scrollback_current = 0;
+
+/*
+ * If no vc is existent yet, just set struct display
+ */
+static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *var,
+			      int unit)
+{
+	struct display *p = &fb_display[unit];
+	struct display *t = &fb_display[fg_console];
+
+	if (var_to_display(p, var, info))
+		return;
+
+	p->fontdata = t->fontdata;
+	p->userfont = t->userfont;
+	if (p->userfont)
+		REFCOUNT(p->fontdata)++;
+}
+
+static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
+			   struct vc_data *vc)
+{
+	struct display *p = &fb_display[vc->vc_num], *t;
+	struct vc_data **default_mode = vc->vc_display_fg;
+	struct vc_data *svc = *default_mode;
+	struct fbcon_ops *ops = info->fbcon_par;
+	int rows, cols, charcnt = 256;
+
+	if (var_to_display(p, var, info))
+		return;
+	t = &fb_display[svc->vc_num];
+	if (!vc->vc_font.data) {
+		vc->vc_font.data = (void *)(p->fontdata = t->fontdata);
+		vc->vc_font.width = (*default_mode)->vc_font.width;
+		vc->vc_font.height = (*default_mode)->vc_font.height;
+		p->userfont = t->userfont;
+		if (p->userfont)
+			REFCOUNT(p->fontdata)++;
+	}
+	if (p->userfont)
+		charcnt = FNTCHARCNT(p->fontdata);
+
+	var->activate = FB_ACTIVATE_NOW;
+	info->var.activate = var->activate;
+	var->yoffset = info->var.yoffset;
+	var->xoffset = info->var.xoffset;
+	fb_set_var(info, var);
+	ops->var = info->var;
+	vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
+	vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
+	if (charcnt == 256) {
+		vc->vc_hi_font_mask = 0;
+	} else {
+		vc->vc_hi_font_mask = 0x100;
+		if (vc->vc_can_do_color)
+			vc->vc_complement_mask <<= 1;
+	}
+
+	if (!*svc->vc_uni_pagedir_loc)
+		con_set_default_unimap(svc);
+	if (!*vc->vc_uni_pagedir_loc)
+		con_copy_unimap(vc, svc);
+
+	cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
+	rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+	cols /= vc->vc_font.width;
+	rows /= vc->vc_font.height;
+	vc_resize(vc, cols, rows);
+
+	if (CON_IS_VISIBLE(vc)) {
+		update_screen(vc);
+		if (softback_buf)
+			fbcon_update_softback(vc);
+	}
+}
+
+static __inline__ void ywrap_up(struct vc_data *vc, int count)
+{
+	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+	struct fbcon_ops *ops = info->fbcon_par;
+	struct display *p = &fb_display[vc->vc_num];
+	
+	p->yscroll += count;
+	if (p->yscroll >= p->vrows)	/* Deal with wrap */
+		p->yscroll -= p->vrows;
+	ops->var.xoffset = 0;
+	ops->var.yoffset = p->yscroll * vc->vc_font.height;
+	ops->var.vmode |= FB_VMODE_YWRAP;
+	ops->update_start(info);
+	scrollback_max += count;
+	if (scrollback_max > scrollback_phys_max)
+		scrollback_max = scrollback_phys_max;
+	scrollback_current = 0;
+}
+
+static __inline__ void ywrap_down(struct vc_data *vc, int count)
+{
+	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+	struct fbcon_ops *ops = info->fbcon_par;
+	struct display *p = &fb_display[vc->vc_num];
+	
+	p->yscroll -= count;
+	if (p->yscroll < 0)	/* Deal with wrap */
+		p->yscroll += p->vrows;
+	ops->var.xoffset = 0;
+	ops->var.yoffset = p->yscroll * vc->vc_font.height;
+	ops->var.vmode |= FB_VMODE_YWRAP;
+	ops->update_start(info);
+	scrollback_max -= count;
+	if (scrollback_max < 0)
+		scrollback_max = 0;
+	scrollback_current = 0;
+}
+
+static __inline__ void ypan_up(struct vc_data *vc, int count)
+{
+	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+	struct display *p = &fb_display[vc->vc_num];
+	struct fbcon_ops *ops = info->fbcon_par;
+
+	p->yscroll += count;
+	if (p->yscroll > p->vrows - vc->vc_rows) {
+		ops->bmove(vc, info, p->vrows - vc->vc_rows,
+			    0, 0, 0, vc->vc_rows, vc->vc_cols);
+		p->yscroll -= p->vrows - vc->vc_rows;
+	}
+
+	ops->var.xoffset = 0;
+	ops->var.yoffset = p->yscroll * vc->vc_font.height;
+	ops->var.vmode &= ~FB_VMODE_YWRAP;
+	ops->update_start(info);
+	fbcon_clear_margins(vc, 1);
+	scrollback_max += count;
+	if (scrollback_max > scrollback_phys_max)
+		scrollback_max = scrollback_phys_max;
+	scrollback_current = 0;
+}
+
+static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count)
+{
+	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+	struct fbcon_ops *ops = info->fbcon_par;
+	struct display *p = &fb_display[vc->vc_num];
+	int redraw = 0;
+
+	p->yscroll += count;
+	if (p->yscroll > p->vrows - vc->vc_rows) {
+		p->yscroll -= p->vrows - vc->vc_rows;
+		redraw = 1;
+	}
+
+	if (redraw)
+		fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t);
+
+	ops->var.xoffset = 0;
+	ops->var.yoffset = p->yscroll * vc->vc_font.height;
+	ops->var.vmode &= ~FB_VMODE_YWRAP;
+	ops->update_start(info);
+	fbcon_clear_margins(vc, 1);
+	scrollback_max += count;
+	if (scrollback_max > scrollback_phys_max)
+		scrollback_max = scrollback_phys_max;
+	scrollback_current = 0;
+}
+
+static __inline__ void ypan_down(struct vc_data *vc, int count)
+{
+	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+	struct display *p = &fb_display[vc->vc_num];
+	struct fbcon_ops *ops = info->fbcon_par;
+	
+	p->yscroll -= count;
+	if (p->yscroll < 0) {
+		ops->bmove(vc, info, 0, 0, p->vrows - vc->vc_rows,
+			    0, vc->vc_rows, vc->vc_cols);
+		p->yscroll += p->vrows - vc->vc_rows;
+	}
+
+	ops->var.xoffset = 0;
+	ops->var.yoffset = p->yscroll * vc->vc_font.height;
+	ops->var.vmode &= ~FB_VMODE_YWRAP;
+	ops->update_start(info);
+	fbcon_clear_margins(vc, 1);
+	scrollback_max -= count;
+	if (scrollback_max < 0)
+		scrollback_max = 0;
+	scrollback_current = 0;
+}
+
+static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count)
+{
+	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+	struct fbcon_ops *ops = info->fbcon_par;
+	struct display *p = &fb_display[vc->vc_num];
+	int redraw = 0;
+
+	p->yscroll -= count;
+	if (p->yscroll < 0) {
+		p->yscroll += p->vrows - vc->vc_rows;
+		redraw = 1;
+	}
+
+	if (redraw)
+		fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count);
+
+	ops->var.xoffset = 0;
+	ops->var.yoffset = p->yscroll * vc->vc_font.height;
+	ops->var.vmode &= ~FB_VMODE_YWRAP;
+	ops->update_start(info);
+	fbcon_clear_margins(vc, 1);
+	scrollback_max -= count;
+	if (scrollback_max < 0)
+		scrollback_max = 0;
+	scrollback_current = 0;
+}
+
+static void fbcon_redraw_softback(struct vc_data *vc, struct display *p,
+				  long delta)
+{
+	int count = vc->vc_rows;
+	unsigned short *d, *s;
+	unsigned long n;
+	int line = 0;
+
+	d = (u16 *) softback_curr;
+	if (d == (u16 *) softback_in)
+		d = (u16 *) vc->vc_origin;
+	n = softback_curr + delta * vc->vc_size_row;
+	softback_lines -= delta;
+	if (delta < 0) {
+		if (softback_curr < softback_top && n < softback_buf) {
+			n += softback_end - softback_buf;
+			if (n < softback_top) {
+				softback_lines -=
+				    (softback_top - n) / vc->vc_size_row;
+				n = softback_top;
+			}
+		} else if (softback_curr >= softback_top
+			   && n < softback_top) {
+			softback_lines -=
+			    (softback_top - n) / vc->vc_size_row;
+			n = softback_top;
+		}
+	} else {
+		if (softback_curr > softback_in && n >= softback_end) {
+			n += softback_buf - softback_end;
+			if (n > softback_in) {
+				n = softback_in;
+				softback_lines = 0;
+			}
+		} else if (softback_curr <= softback_in && n > softback_in) {
+			n = softback_in;
+			softback_lines = 0;
+		}
+	}
+	if (n == softback_curr)
+		return;
+	softback_curr = n;
+	s = (u16 *) softback_curr;
+	if (s == (u16 *) softback_in)
+		s = (u16 *) vc->vc_origin;
+	while (count--) {
+		unsigned short *start;
+		unsigned short *le;
+		unsigned short c;
+		int x = 0;
+		unsigned short attr = 1;
+
+		start = s;
+		le = advance_row(s, 1);
+		do {
+			c = scr_readw(s);
+			if (attr != (c & 0xff00)) {
+				attr = c & 0xff00;
+				if (s > start) {
+					fbcon_putcs(vc, start, s - start,
+						    line, x);
+					x += s - start;
+					start = s;
+				}
+			}
+			if (c == scr_readw(d)) {
+				if (s > start) {
+					fbcon_putcs(vc, start, s - start,
+						    line, x);
+					x += s - start + 1;
+					start = s + 1;
+				} else {
+					x++;
+					start++;
+				}
+			}
+			s++;
+			d++;
+		} while (s < le);
+		if (s > start)
+			fbcon_putcs(vc, start, s - start, line, x);
+		line++;
+		if (d == (u16 *) softback_end)
+			d = (u16 *) softback_buf;
+		if (d == (u16 *) softback_in)
+			d = (u16 *) vc->vc_origin;
+		if (s == (u16 *) softback_end)
+			s = (u16 *) softback_buf;
+		if (s == (u16 *) softback_in)
+			s = (u16 *) vc->vc_origin;
+	}
+}
+
+static void fbcon_redraw_move(struct vc_data *vc, struct display *p,
+			      int line, int count, int dy)
+{
+	unsigned short *s = (unsigned short *)
+		(vc->vc_origin + vc->vc_size_row * line);
+
+	while (count--) {
+		unsigned short *start = s;
+		unsigned short *le = advance_row(s, 1);
+		unsigned short c;
+		int x = 0;
+		unsigned short attr = 1;
+
+		do {
+			c = scr_readw(s);
+			if (attr != (c & 0xff00)) {
+				attr = c & 0xff00;
+				if (s > start) {
+					fbcon_putcs(vc, start, s - start,
+						    dy, x);
+					x += s - start;
+					start = s;
+				}
+			}
+			console_conditional_schedule();
+			s++;
+		} while (s < le);
+		if (s > start)
+			fbcon_putcs(vc, start, s - start, dy, x);
+		console_conditional_schedule();
+		dy++;
+	}
+}
+
+static void fbcon_redraw(struct vc_data *vc, struct display *p,
+			 int line, int count, int offset)
+{
+	unsigned short *d = (unsigned short *)
+	    (vc->vc_origin + vc->vc_size_row * line);
+	unsigned short *s = d + offset;
+
+	while (count--) {
+		unsigned short *start = s;
+		unsigned short *le = advance_row(s, 1);
+		unsigned short c;
+		int x = 0;
+		unsigned short attr = 1;
+
+		do {
+			c = scr_readw(s);
+			if (attr != (c & 0xff00)) {
+				attr = c & 0xff00;
+				if (s > start) {
+					fbcon_putcs(vc, start, s - start,
+						    line, x);
+					x += s - start;
+					start = s;
+				}
+			}
+			if (c == scr_readw(d)) {
+				if (s > start) {
+					fbcon_putcs(vc, start, s - start,
+						     line, x);
+					x += s - start + 1;
+					start = s + 1;
+				} else {
+					x++;
+					start++;
+				}
+			}
+			scr_writew(c, d);
+			console_conditional_schedule();
+			s++;
+			d++;
+		} while (s < le);
+		if (s > start)
+			fbcon_putcs(vc, start, s - start, line, x);
+		console_conditional_schedule();
+		if (offset > 0)
+			line++;
+		else {
+			line--;
+			/* NOTE: We subtract two lines from these pointers */
+			s -= vc->vc_size_row;
+			d -= vc->vc_size_row;
+		}
+	}
+}
+
+static inline void fbcon_softback_note(struct vc_data *vc, int t,
+				       int count)
+{
+	unsigned short *p;
+
+	if (vc->vc_num != fg_console)
+		return;
+	p = (unsigned short *) (vc->vc_origin + t * vc->vc_size_row);
+
+	while (count) {
+		scr_memcpyw((u16 *) softback_in, p, vc->vc_size_row);
+		count--;
+		p = advance_row(p, 1);
+		softback_in += vc->vc_size_row;
+		if (softback_in == softback_end)
+			softback_in = softback_buf;
+		if (softback_in == softback_top) {
+			softback_top += vc->vc_size_row;
+			if (softback_top == softback_end)
+				softback_top = softback_buf;
+		}
+	}
+	softback_curr = softback_in;
+}
+
+static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
+			int count)
+{
+	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+	struct display *p = &fb_display[vc->vc_num];
+	struct fbcon_ops *ops = info->fbcon_par;
+	int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK;
+
+	if (fbcon_is_inactive(vc, info))
+		return -EINVAL;
+
+	fbcon_cursor(vc, CM_ERASE);
+
+	/*
+	 * ++Geert: Only use ywrap/ypan if the console is in text mode
+	 * ++Andrew: Only use ypan on hardware text mode when scrolling the
+	 *           whole screen (prevents flicker).
+	 */
+
+	switch (dir) {
+	case SM_UP:
+		if (count > vc->vc_rows)	/* Maximum realistic size */
+			count = vc->vc_rows;
+		if (softback_top)
+			fbcon_softback_note(vc, t, count);
+		if (logo_shown >= 0)
+			goto redraw_up;
+		switch (p->scrollmode) {
+		case SCROLL_MOVE:
+			ops->bmove(vc, info, t + count, 0, t, 0,
+				    b - t - count, vc->vc_cols);
+			ops->clear(vc, info, b - count, 0, count,
+				  vc->vc_cols);
+			break;
+
+		case SCROLL_WRAP_MOVE:
+			if (b - t - count > 3 * vc->vc_rows >> 2) {
+				if (t > 0)
+					fbcon_bmove(vc, 0, 0, count, 0, t,
+						    vc->vc_cols);
+				ywrap_up(vc, count);
+				if (vc->vc_rows - b > 0)
+					fbcon_bmove(vc, b - count, 0, b, 0,
+						    vc->vc_rows - b,
+						    vc->vc_cols);
+			} else if (info->flags & FBINFO_READS_FAST)
+				fbcon_bmove(vc, t + count, 0, t, 0,
+					    b - t - count, vc->vc_cols);
+			else
+				goto redraw_up;
+			fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
+			break;
+
+		case SCROLL_PAN_REDRAW:
+			if ((p->yscroll + count <=
+			     2 * (p->vrows - vc->vc_rows))
+			    && ((!scroll_partial && (b - t == vc->vc_rows))
+				|| (scroll_partial
+				    && (b - t - count >
+					3 * vc->vc_rows >> 2)))) {
+				if (t > 0)
+					fbcon_redraw_move(vc, p, 0, t, count);
+				ypan_up_redraw(vc, t, count);
+				if (vc->vc_rows - b > 0)
+					fbcon_redraw_move(vc, p, b - count,
+							  vc->vc_rows - b, b);
+			} else
+				fbcon_redraw_move(vc, p, t + count, b - t - count, t);
+			fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
+			break;
+
+		case SCROLL_PAN_MOVE:
+			if ((p->yscroll + count <=
+			     2 * (p->vrows - vc->vc_rows))
+			    && ((!scroll_partial && (b - t == vc->vc_rows))
+				|| (scroll_partial
+				    && (b - t - count >
+					3 * vc->vc_rows >> 2)))) {
+				if (t > 0)
+					fbcon_bmove(vc, 0, 0, count, 0, t,
+						    vc->vc_cols);
+				ypan_up(vc, count);
+				if (vc->vc_rows - b > 0)
+					fbcon_bmove(vc, b - count, 0, b, 0,
+						    vc->vc_rows - b,
+						    vc->vc_cols);
+			} else if (info->flags & FBINFO_READS_FAST)
+				fbcon_bmove(vc, t + count, 0, t, 0,
+					    b - t - count, vc->vc_cols);
+			else
+				goto redraw_up;
+			fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
+			break;
+
+		case SCROLL_REDRAW:
+		      redraw_up:
+			fbcon_redraw(vc, p, t, b - t - count,
+				     count * vc->vc_cols);
+			fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
+			scr_memsetw((unsigned short *) (vc->vc_origin +
+							vc->vc_size_row *
+							(b - count)),
+				    vc->vc_video_erase_char,
+				    vc->vc_size_row * count);
+			return 1;
+		}
+		break;
+
+	case SM_DOWN:
+		if (count > vc->vc_rows)	/* Maximum realistic size */
+			count = vc->vc_rows;
+		if (logo_shown >= 0)
+			goto redraw_down;
+		switch (p->scrollmode) {
+		case SCROLL_MOVE:
+			ops->bmove(vc, info, t, 0, t + count, 0,
+				    b - t - count, vc->vc_cols);
+			ops->clear(vc, info, t, 0, count, vc->vc_cols);
+			break;
+
+		case SCROLL_WRAP_MOVE:
+			if (b - t - count > 3 * vc->vc_rows >> 2) {
+				if (vc->vc_rows - b > 0)
+					fbcon_bmove(vc, b, 0, b - count, 0,
+						    vc->vc_rows - b,
+						    vc->vc_cols);
+				ywrap_down(vc, count);
+				if (t > 0)
+					fbcon_bmove(vc, count, 0, 0, 0, t,
+						    vc->vc_cols);
+			} else if (info->flags & FBINFO_READS_FAST)
+				fbcon_bmove(vc, t, 0, t + count, 0,
+					    b - t - count, vc->vc_cols);
+			else
+				goto redraw_down;
+			fbcon_clear(vc, t, 0, count, vc->vc_cols);
+			break;
+
+		case SCROLL_PAN_MOVE:
+			if ((count - p->yscroll <= p->vrows - vc->vc_rows)
+			    && ((!scroll_partial && (b - t == vc->vc_rows))
+				|| (scroll_partial
+				    && (b - t - count >
+					3 * vc->vc_rows >> 2)))) {
+				if (vc->vc_rows - b > 0)
+					fbcon_bmove(vc, b, 0, b - count, 0,
+						    vc->vc_rows - b,
+						    vc->vc_cols);
+				ypan_down(vc, count);
+				if (t > 0)
+					fbcon_bmove(vc, count, 0, 0, 0, t,
+						    vc->vc_cols);
+			} else if (info->flags & FBINFO_READS_FAST)
+				fbcon_bmove(vc, t, 0, t + count, 0,
+					    b - t - count, vc->vc_cols);
+			else
+				goto redraw_down;
+			fbcon_clear(vc, t, 0, count, vc->vc_cols);
+			break;
+
+		case SCROLL_PAN_REDRAW:
+			if ((count - p->yscroll <= p->vrows - vc->vc_rows)
+			    && ((!scroll_partial && (b - t == vc->vc_rows))
+				|| (scroll_partial
+				    && (b - t - count >
+					3 * vc->vc_rows >> 2)))) {
+				if (vc->vc_rows - b > 0)
+					fbcon_redraw_move(vc, p, b, vc->vc_rows - b,
+							  b - count);
+				ypan_down_redraw(vc, t, count);
+				if (t > 0)
+					fbcon_redraw_move(vc, p, count, t, 0);
+			} else
+				fbcon_redraw_move(vc, p, t, b - t - count, t + count);
+			fbcon_clear(vc, t, 0, count, vc->vc_cols);
+			break;
+
+		case SCROLL_REDRAW:
+		      redraw_down:
+			fbcon_redraw(vc, p, b - 1, b - t - count,
+				     -count * vc->vc_cols);
+			fbcon_clear(vc, t, 0, count, vc->vc_cols);
+			scr_memsetw((unsigned short *) (vc->vc_origin +
+							vc->vc_size_row *
+							t),
+				    vc->vc_video_erase_char,
+				    vc->vc_size_row * count);
+			return 1;
+		}
+	}
+	return 0;
+}
+
+
+static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,
+			int height, int width)
+{
+	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+	struct display *p = &fb_display[vc->vc_num];
+	
+	if (fbcon_is_inactive(vc, info))
+		return;
+
+	if (!width || !height)
+		return;
+
+	/*  Split blits that cross physical y_wrap case.
+	 *  Pathological case involves 4 blits, better to use recursive
+	 *  code rather than unrolled case
+	 *
+	 *  Recursive invocations don't need to erase the cursor over and
+	 *  over again, so we use fbcon_bmove_rec()
+	 */
+	fbcon_bmove_rec(vc, p, sy, sx, dy, dx, height, width,
+			p->vrows - p->yscroll);
+}
+
+static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx, 
+			    int dy, int dx, int height, int width, u_int y_break)
+{
+	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+	struct fbcon_ops *ops = info->fbcon_par;
+	u_int b;
+
+	if (sy < y_break && sy + height > y_break) {
+		b = y_break - sy;
+		if (dy < sy) {	/* Avoid trashing self */
+			fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
+					y_break);
+			fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
+					height - b, width, y_break);
+		} else {
+			fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
+					height - b, width, y_break);
+			fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
+					y_break);
+		}
+		return;
+	}
+
+	if (dy < y_break && dy + height > y_break) {
+		b = y_break - dy;
+		if (dy < sy) {	/* Avoid trashing self */
+			fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
+					y_break);
+			fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
+					height - b, width, y_break);
+		} else {
+			fbcon_bmove_rec(vc, p, sy + b, sx, dy + b, dx,
+					height - b, width, y_break);
+			fbcon_bmove_rec(vc, p, sy, sx, dy, dx, b, width,
+					y_break);
+		}
+		return;
+	}
+	ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
+		   height, width);
+}
+
+static __inline__ void updatescrollmode(struct display *p,
+					struct fb_info *info,
+					struct vc_data *vc)
+{
+	struct fbcon_ops *ops = info->fbcon_par;
+	int fh = vc->vc_font.height;
+	int cap = info->flags;
+	u16 t = 0;
+	int ypan = FBCON_SWAP(ops->rotate, info->fix.ypanstep,
+				  info->fix.xpanstep);
+	int ywrap = FBCON_SWAP(ops->rotate, info->fix.ywrapstep, t);
+	int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+	int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual,
+				   info->var.xres_virtual);
+	int good_pan = (cap & FBINFO_HWACCEL_YPAN) &&
+		divides(ypan, vc->vc_font.height) && vyres > yres;
+	int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) &&
+		divides(ywrap, vc->vc_font.height) &&
+		divides(vc->vc_font.height, vyres);
+	int reading_fast = cap & FBINFO_READS_FAST;
+	int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) &&
+		!(cap & FBINFO_HWACCEL_DISABLED);
+	int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) &&
+		!(cap & FBINFO_HWACCEL_DISABLED);
+
+	p->vrows = vyres/fh;
+	if (yres > (fh * (vc->vc_rows + 1)))
+		p->vrows -= (yres - (fh * vc->vc_rows)) / fh;
+	if ((yres % fh) && (vyres % fh < yres % fh))
+		p->vrows--;
+
+	if (good_wrap || good_pan) {
+		if (reading_fast || fast_copyarea)
+			p->scrollmode = good_wrap ?
+				SCROLL_WRAP_MOVE : SCROLL_PAN_MOVE;
+		else
+			p->scrollmode = good_wrap ? SCROLL_REDRAW :
+				SCROLL_PAN_REDRAW;
+	} else {
+		if (reading_fast || (fast_copyarea && !fast_imageblit))
+			p->scrollmode = SCROLL_MOVE;
+		else
+			p->scrollmode = SCROLL_REDRAW;
+	}
+}
+
+static int fbcon_resize(struct vc_data *vc, unsigned int width, 
+			unsigned int height)
+{
+	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+	struct fbcon_ops *ops = info->fbcon_par;
+	struct display *p = &fb_display[vc->vc_num];
+	struct fb_var_screeninfo var = info->var;
+	int x_diff, y_diff, virt_w, virt_h, virt_fw, virt_fh;
+
+	virt_w = FBCON_SWAP(ops->rotate, width, height);
+	virt_h = FBCON_SWAP(ops->rotate, height, width);
+	virt_fw = FBCON_SWAP(ops->rotate, vc->vc_font.width,
+				 vc->vc_font.height);
+	virt_fh = FBCON_SWAP(ops->rotate, vc->vc_font.height,
+				 vc->vc_font.width);
+	var.xres = virt_w * virt_fw;
+	var.yres = virt_h * virt_fh;
+	x_diff = info->var.xres - var.xres;
+	y_diff = info->var.yres - var.yres;
+	if (x_diff < 0 || x_diff > virt_fw ||
+	    y_diff < 0 || y_diff > virt_fh) {
+		struct fb_videomode *mode;
+
+		DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
+		mode = fb_find_best_mode(&var, &info->modelist);
+		if (mode == NULL)
+			return -EINVAL;
+		display_to_var(&var, p);
+		fb_videomode_to_var(&var, mode);
+
+		if (virt_w > var.xres/virt_fw || virt_h > var.yres/virt_fh)
+			return -EINVAL;
+
+		DPRINTK("resize now %ix%i\n", var.xres, var.yres);
+		if (CON_IS_VISIBLE(vc)) {
+			var.activate = FB_ACTIVATE_NOW |
+				FB_ACTIVATE_FORCE;
+			fb_set_var(info, &var);
+		}
+		var_to_display(p, &info->var, info);
+		ops->var = info->var;
+	}
+	updatescrollmode(p, info, vc);
+	return 0;
+}
+
+static int fbcon_switch(struct vc_data *vc)
+{
+	struct fb_info *info, *old_info = NULL;
+	struct fbcon_ops *ops;
+	struct display *p = &fb_display[vc->vc_num];
+	struct fb_var_screeninfo var;
+	int i, prev_console, charcnt = 256;
+
+	info = registered_fb[con2fb_map[vc->vc_num]];
+	ops = info->fbcon_par;
+
+	if (softback_top) {
+		if (softback_lines)
+			fbcon_set_origin(vc);
+		softback_top = softback_curr = softback_in = softback_buf;
+		softback_lines = 0;
+		fbcon_update_softback(vc);
+	}
+
+	if (logo_shown >= 0) {
+		struct vc_data *conp2 = vc_cons[logo_shown].d;
+
+		if (conp2->vc_top == logo_lines
+		    && conp2->vc_bottom == conp2->vc_rows)
+			conp2->vc_top = 0;
+		logo_shown = FBCON_LOGO_CANSHOW;
+	}
+
+	prev_console = ops->currcon;
+	if (prev_console != -1)
+		old_info = registered_fb[con2fb_map[prev_console]];
+	/*
+	 * FIXME: If we have multiple fbdev's loaded, we need to
+	 * update all info->currcon.  Perhaps, we can place this
+	 * in a centralized structure, but this might break some
+	 * drivers.
+	 *
+	 * info->currcon = vc->vc_num;
+	 */
+	for (i = 0; i < FB_MAX; i++) {
+		if (registered_fb[i] != NULL && registered_fb[i]->fbcon_par) {
+			struct fbcon_ops *o = registered_fb[i]->fbcon_par;
+
+			o->currcon = vc->vc_num;
+		}
+	}
+	memset(&var, 0, sizeof(struct fb_var_screeninfo));
+	display_to_var(&var, p);
+	var.activate = FB_ACTIVATE_NOW;
+
+	/*
+	 * make sure we don't unnecessarily trip the memcmp()
+	 * in fb_set_var()
+	 */
+	info->var.activate = var.activate;
+	var.yoffset = info->var.yoffset;
+	var.xoffset = info->var.xoffset;
+	var.vmode = info->var.vmode;
+	fb_set_var(info, &var);
+	ops->var = info->var;
+
+	if (old_info != NULL && (old_info != info ||
+				 info->flags & FBINFO_MISC_ALWAYS_SETPAR)) {
+		if (info->fbops->fb_set_par)
+			info->fbops->fb_set_par(info);
+		fbcon_del_cursor_timer(old_info);
+		fbcon_add_cursor_timer(info);
+	}
+
+	set_blitting_type(vc, info, p);
+	ops->cursor_reset = 1;
+
+	if (ops->rotate_font && ops->rotate_font(info, vc, p)) {
+		ops->rotate = FB_ROTATE_UR;
+		set_blitting_type(vc, info, p);
+	}
+
+	vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
+	vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
+
+	if (p->userfont)
+		charcnt = FNTCHARCNT(vc->vc_font.data);
+
+	if (charcnt > 256)
+		vc->vc_complement_mask <<= 1;
+
+	updatescrollmode(p, info, vc);
+
+	switch (p->scrollmode) {
+	case SCROLL_WRAP_MOVE:
+		scrollback_phys_max = p->vrows - vc->vc_rows;
+		break;
+	case SCROLL_PAN_MOVE:
+	case SCROLL_PAN_REDRAW:
+		scrollback_phys_max = p->vrows - 2 * vc->vc_rows;
+		if (scrollback_phys_max < 0)
+			scrollback_phys_max = 0;
+		break;
+	default:
+		scrollback_phys_max = 0;
+		break;
+	}
+
+	scrollback_max = 0;
+	scrollback_current = 0;
+
+	if (!fbcon_is_inactive(vc, info)) {
+	    ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
+	    ops->update_start(info);
+	}
+
+	fbcon_set_palette(vc, color_table); 	
+	fbcon_clear_margins(vc, 0);
+
+	if (logo_shown == FBCON_LOGO_DRAW) {
+
+		logo_shown = fg_console;
+		/* This is protected above by initmem_freed */
+		fb_show_logo(info, ops->rotate);
+		update_region(vc,
+			      vc->vc_origin + vc->vc_size_row * vc->vc_top,
+			      vc->vc_size_row * (vc->vc_bottom -
+						 vc->vc_top) / 2);
+		return 0;
+	}
+	return 1;
+}
+
+static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info,
+				int blank)
+{
+	if (blank) {
+		unsigned short charmask = vc->vc_hi_font_mask ?
+			0x1ff : 0xff;
+		unsigned short oldc;
+
+		oldc = vc->vc_video_erase_char;
+		vc->vc_video_erase_char &= charmask;
+		fbcon_clear(vc, 0, 0, vc->vc_rows, vc->vc_cols);
+		vc->vc_video_erase_char = oldc;
+	}
+}
+
+static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
+{
+	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+	struct fbcon_ops *ops = info->fbcon_par;
+
+	if (mode_switch) {
+		struct fb_var_screeninfo var = info->var;
+
+		ops->graphics = 1;
+
+		if (!blank) {
+			if (info->fbops->fb_save_state)
+				info->fbops->fb_save_state(info);
+			var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
+			fb_set_var(info, &var);
+			ops->graphics = 0;
+			ops->var = info->var;
+		} else if (info->fbops->fb_restore_state)
+			info->fbops->fb_restore_state(info);
+	}
+
+ 	if (!fbcon_is_inactive(vc, info)) {
+		if (ops->blank_state != blank) {
+			ops->blank_state = blank;
+			fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
+			ops->cursor_flash = (!blank);
+
+			if (fb_blank(info, blank))
+				fbcon_generic_blank(vc, info, blank);
+		}
+
+		if (!blank)
+			update_screen(vc);
+	}
+
+	if (!blank)
+		fbcon_add_cursor_timer(info);
+	else
+		fbcon_del_cursor_timer(info);
+
+	return 0;
+}
+
+static void fbcon_free_font(struct display *p)
+{
+	if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0))
+		kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int));
+	p->fontdata = NULL;
+	p->userfont = 0;
+}
+
+static int fbcon_get_font(struct vc_data *vc, struct console_font *font)
+{
+	u8 *fontdata = vc->vc_font.data;
+	u8 *data = font->data;
+	int i, j;
+
+	font->width = vc->vc_font.width;
+	font->height = vc->vc_font.height;
+	font->charcount = vc->vc_hi_font_mask ? 512 : 256;
+	if (!font->data)
+		return 0;
+
+	if (font->width <= 8) {
+		j = vc->vc_font.height;
+		for (i = 0; i < font->charcount; i++) {
+			memcpy(data, fontdata, j);
+			memset(data + j, 0, 32 - j);
+			data += 32;
+			fontdata += j;
+		}
+	} else if (font->width <= 16) {
+		j = vc->vc_font.height * 2;
+		for (i = 0; i < font->charcount; i++) {
+			memcpy(data, fontdata, j);
+			memset(data + j, 0, 64 - j);
+			data += 64;
+			fontdata += j;
+		}
+	} else if (font->width <= 24) {
+		for (i = 0; i < font->charcount; i++) {
+			for (j = 0; j < vc->vc_font.height; j++) {
+				*data++ = fontdata[0];
+				*data++ = fontdata[1];
+				*data++ = fontdata[2];
+				fontdata += sizeof(u32);
+			}
+			memset(data, 0, 3 * (32 - j));
+			data += 3 * (32 - j);
+		}
+	} else {
+		j = vc->vc_font.height * 4;
+		for (i = 0; i < font->charcount; i++) {
+			memcpy(data, fontdata, j);
+			memset(data + j, 0, 128 - j);
+			data += 128;
+			fontdata += j;
+		}
+	}
+	return 0;
+}
+
+static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
+			     const u8 * data, int userfont)
+{
+	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+	struct fbcon_ops *ops = info->fbcon_par;
+	struct display *p = &fb_display[vc->vc_num];
+	int resize;
+	int cnt;
+	char *old_data = NULL;
+
+	if (CON_IS_VISIBLE(vc) && softback_lines)
+		fbcon_set_origin(vc);
+
+	resize = (w != vc->vc_font.width) || (h != vc->vc_font.height);
+	if (p->userfont)
+		old_data = vc->vc_font.data;
+	if (userfont)
+		cnt = FNTCHARCNT(data);
+	else
+		cnt = 256;
+	vc->vc_font.data = (void *)(p->fontdata = data);
+	if ((p->userfont = userfont))
+		REFCOUNT(data)++;
+	vc->vc_font.width = w;
+	vc->vc_font.height = h;
+	if (vc->vc_hi_font_mask && cnt == 256) {
+		vc->vc_hi_font_mask = 0;
+		if (vc->vc_can_do_color) {
+			vc->vc_complement_mask >>= 1;
+			vc->vc_s_complement_mask >>= 1;
+		}
+			
+		/* ++Edmund: reorder the attribute bits */
+		if (vc->vc_can_do_color) {
+			unsigned short *cp =
+			    (unsigned short *) vc->vc_origin;
+			int count = vc->vc_screenbuf_size / 2;
+			unsigned short c;
+			for (; count > 0; count--, cp++) {
+				c = scr_readw(cp);
+				scr_writew(((c & 0xfe00) >> 1) |
+					   (c & 0xff), cp);
+			}
+			c = vc->vc_video_erase_char;
+			vc->vc_video_erase_char =
+			    ((c & 0xfe00) >> 1) | (c & 0xff);
+			vc->vc_attr >>= 1;
+		}
+	} else if (!vc->vc_hi_font_mask && cnt == 512) {
+		vc->vc_hi_font_mask = 0x100;
+		if (vc->vc_can_do_color) {
+			vc->vc_complement_mask <<= 1;
+			vc->vc_s_complement_mask <<= 1;
+		}
+			
+		/* ++Edmund: reorder the attribute bits */
+		{
+			unsigned short *cp =
+			    (unsigned short *) vc->vc_origin;
+			int count = vc->vc_screenbuf_size / 2;
+			unsigned short c;
+			for (; count > 0; count--, cp++) {
+				unsigned short newc;
+				c = scr_readw(cp);
+				if (vc->vc_can_do_color)
+					newc =
+					    ((c & 0xff00) << 1) | (c &
+								   0xff);
+				else
+					newc = c & ~0x100;
+				scr_writew(newc, cp);
+			}
+			c = vc->vc_video_erase_char;
+			if (vc->vc_can_do_color) {
+				vc->vc_video_erase_char =
+				    ((c & 0xff00) << 1) | (c & 0xff);
+				vc->vc_attr <<= 1;
+			} else
+				vc->vc_video_erase_char = c & ~0x100;
+		}
+
+	}
+
+	if (resize) {
+		int cols, rows;
+
+		cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
+		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+		cols /= w;
+		rows /= h;
+		vc_resize(vc, cols, rows);
+		if (CON_IS_VISIBLE(vc) && softback_buf)
+			fbcon_update_softback(vc);
+	} else if (CON_IS_VISIBLE(vc)
+		   && vc->vc_mode == KD_TEXT) {
+		fbcon_clear_margins(vc, 0);
+		update_screen(vc);
+	}
+
+	if (old_data && (--REFCOUNT(old_data) == 0))
+		kfree(old_data - FONT_EXTRA_WORDS * sizeof(int));
+	return 0;
+}
+
+static int fbcon_copy_font(struct vc_data *vc, int con)
+{
+	struct display *od = &fb_display[con];
+	struct console_font *f = &vc->vc_font;
+
+	if (od->fontdata == f->data)
+		return 0;	/* already the same font... */
+	return fbcon_do_set_font(vc, f->width, f->height, od->fontdata, od->userfont);
+}
+
+/*
+ *  User asked to set font; we are guaranteed that
+ *	a) width and height are in range 1..32
+ *	b) charcount does not exceed 512
+ *  but lets not assume that, since someone might someday want to use larger
+ *  fonts. And charcount of 512 is small for unicode support.
+ *
+ *  However, user space gives the font in 32 rows , regardless of
+ *  actual font height. So a new API is needed if support for larger fonts
+ *  is ever implemented.
+ */
+
+static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigned flags)
+{
+	unsigned charcount = font->charcount;
+	int w = font->width;
+	int h = font->height;
+	int size;
+	int i, csum;
+	u8 *new_data, *data = font->data;
+	int pitch = (font->width+7) >> 3;
+
+	/* Is there a reason why fbconsole couldn't handle any charcount >256?
+	 * If not this check should be changed to charcount < 256 */
+	if (charcount != 256 && charcount != 512)
+		return -EINVAL;
+
+	size = h * pitch * charcount;
+
+	new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size, GFP_USER);
+
+	if (!new_data)
+		return -ENOMEM;
+
+	new_data += FONT_EXTRA_WORDS * sizeof(int);
+	FNTSIZE(new_data) = size;
+	FNTCHARCNT(new_data) = charcount;
+	REFCOUNT(new_data) = 0;	/* usage counter */
+	for (i=0; i< charcount; i++) {
+		memcpy(new_data + i*h*pitch, data +  i*32*pitch, h*pitch);
+	}
+
+	/* Since linux has a nice crc32 function use it for counting font
+	 * checksums. */
+	csum = crc32(0, new_data, size);
+
+	FNTSUM(new_data) = csum;
+	/* Check if the same font is on some other console already */
+	for (i = 0; i < MAX_NR_CONSOLES; i++) {
+		struct vc_data *tmp = vc_cons[i].d;
+		
+		if (fb_display[i].userfont &&
+		    fb_display[i].fontdata &&
+		    FNTSUM(fb_display[i].fontdata) == csum &&
+		    FNTSIZE(fb_display[i].fontdata) == size &&
+		    tmp->vc_font.width == w &&
+		    !memcmp(fb_display[i].fontdata, new_data, size)) {
+			kfree(new_data - FONT_EXTRA_WORDS * sizeof(int));
+			new_data = (u8 *)fb_display[i].fontdata;
+			break;
+		}
+	}
+	return fbcon_do_set_font(vc, font->width, font->height, new_data, 1);
+}
+
+static int fbcon_set_def_font(struct vc_data *vc, struct console_font *font, char *name)
+{
+	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+	const struct font_desc *f;
+
+	if (!name)
+		f = get_default_font(info->var.xres, info->var.yres);
+	else if (!(f = find_font(name)))
+		return -ENOENT;
+
+	font->width = f->width;
+	font->height = f->height;
+	return fbcon_do_set_font(vc, f->width, f->height, f->data, 0);
+}
+
+static u16 palette_red[16];
+static u16 palette_green[16];
+static u16 palette_blue[16];
+
+static struct fb_cmap palette_cmap = {
+	0, 16, palette_red, palette_green, palette_blue, NULL
+};
+
+static int fbcon_set_palette(struct vc_data *vc, unsigned char *table)
+{
+	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+	int i, j, k, depth;
+	u8 val;
+
+	if (fbcon_is_inactive(vc, info))
+		return -EINVAL;
+
+	if (!CON_IS_VISIBLE(vc))
+		return 0;
+
+	depth = fb_get_color_depth(&info->var, &info->fix);
+	if (depth > 3) {
+		for (i = j = 0; i < 16; i++) {
+			k = table[i];
+			val = vc->vc_palette[j++];
+			palette_red[k] = (val << 8) | val;
+			val = vc->vc_palette[j++];
+			palette_green[k] = (val << 8) | val;
+			val = vc->vc_palette[j++];
+			palette_blue[k] = (val << 8) | val;
+		}
+		palette_cmap.len = 16;
+		palette_cmap.start = 0;
+	/*
+	 * If framebuffer is capable of less than 16 colors,
+	 * use default palette of fbcon.
+	 */
+	} else
+		fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
+
+	return fb_set_cmap(&palette_cmap, info);
+}
+
+static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
+{
+	unsigned long p;
+	int line;
+	
+	if (vc->vc_num != fg_console || !softback_lines)
+		return (u16 *) (vc->vc_origin + offset);
+	line = offset / vc->vc_size_row;
+	if (line >= softback_lines)
+		return (u16 *) (vc->vc_origin + offset -
+				softback_lines * vc->vc_size_row);
+	p = softback_curr + offset;
+	if (p >= softback_end)
+		p += softback_buf - softback_end;
+	return (u16 *) p;
+}
+
+static unsigned long fbcon_getxy(struct vc_data *vc, unsigned long pos,
+				 int *px, int *py)
+{
+	unsigned long ret;
+	int x, y;
+
+	if (pos >= vc->vc_origin && pos < vc->vc_scr_end) {
+		unsigned long offset = (pos - vc->vc_origin) / 2;
+
+		x = offset % vc->vc_cols;
+		y = offset / vc->vc_cols;
+		if (vc->vc_num == fg_console)
+			y += softback_lines;
+		ret = pos + (vc->vc_cols - x) * 2;
+	} else if (vc->vc_num == fg_console && softback_lines) {
+		unsigned long offset = pos - softback_curr;
+
+		if (pos < softback_curr)
+			offset += softback_end - softback_buf;
+		offset /= 2;
+		x = offset % vc->vc_cols;
+		y = offset / vc->vc_cols;
+		ret = pos + (vc->vc_cols - x) * 2;
+		if (ret == softback_end)
+			ret = softback_buf;
+		if (ret == softback_in)
+			ret = vc->vc_origin;
+	} else {
+		/* Should not happen */
+		x = y = 0;
+		ret = vc->vc_origin;
+	}
+	if (px)
+		*px = x;
+	if (py)
+		*py = y;
+	return ret;
+}
+
+/* As we might be inside of softback, we may work with non-contiguous buffer,
+   that's why we have to use a separate routine. */
+static void fbcon_invert_region(struct vc_data *vc, u16 * p, int cnt)
+{
+	while (cnt--) {
+		u16 a = scr_readw(p);
+		if (!vc->vc_can_do_color)
+			a ^= 0x0800;
+		else if (vc->vc_hi_font_mask == 0x100)
+			a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) |
+			    (((a) & 0x0e00) << 4);
+		else
+			a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) |
+			    (((a) & 0x0700) << 4);
+		scr_writew(a, p++);
+		if (p == (u16 *) softback_end)
+			p = (u16 *) softback_buf;
+		if (p == (u16 *) softback_in)
+			p = (u16 *) vc->vc_origin;
+	}
+}
+
+static int fbcon_scrolldelta(struct vc_data *vc, int lines)
+{
+	struct fb_info *info = registered_fb[con2fb_map[fg_console]];
+	struct fbcon_ops *ops = info->fbcon_par;
+	struct display *p = &fb_display[fg_console];
+	int offset, limit, scrollback_old;
+
+	if (softback_top) {
+		if (vc->vc_num != fg_console)
+			return 0;
+		if (vc->vc_mode != KD_TEXT || !lines)
+			return 0;
+		if (logo_shown >= 0) {
+			struct vc_data *conp2 = vc_cons[logo_shown].d;
+
+			if (conp2->vc_top == logo_lines
+			    && conp2->vc_bottom == conp2->vc_rows)
+				conp2->vc_top = 0;
+			if (logo_shown == vc->vc_num) {
+				unsigned long p, q;
+				int i;
+
+				p = softback_in;
+				q = vc->vc_origin +
+				    logo_lines * vc->vc_size_row;
+				for (i = 0; i < logo_lines; i++) {
+					if (p == softback_top)
+						break;
+					if (p == softback_buf)
+						p = softback_end;
+					p -= vc->vc_size_row;
+					q -= vc->vc_size_row;
+					scr_memcpyw((u16 *) q, (u16 *) p,
+						    vc->vc_size_row);
+				}
+				softback_in = p;
+				update_region(vc, vc->vc_origin,
+					      logo_lines * vc->vc_cols);
+			}
+			logo_shown = FBCON_LOGO_CANSHOW;
+		}
+		fbcon_cursor(vc, CM_ERASE | CM_SOFTBACK);
+		fbcon_redraw_softback(vc, p, lines);
+		fbcon_cursor(vc, CM_DRAW | CM_SOFTBACK);
+		return 0;
+	}
+
+	if (!scrollback_phys_max)
+		return -ENOSYS;
+
+	scrollback_old = scrollback_current;
+	scrollback_current -= lines;
+	if (scrollback_current < 0)
+		scrollback_current = 0;
+	else if (scrollback_current > scrollback_max)
+		scrollback_current = scrollback_max;
+	if (scrollback_current == scrollback_old)
+		return 0;
+
+	if (fbcon_is_inactive(vc, info))
+		return 0;
+
+	fbcon_cursor(vc, CM_ERASE);
+
+	offset = p->yscroll - scrollback_current;
+	limit = p->vrows;
+	switch (p->scrollmode) {
+	case SCROLL_WRAP_MOVE:
+		info->var.vmode |= FB_VMODE_YWRAP;
+		break;
+	case SCROLL_PAN_MOVE:
+	case SCROLL_PAN_REDRAW:
+		limit -= vc->vc_rows;
+		info->var.vmode &= ~FB_VMODE_YWRAP;
+		break;
+	}
+	if (offset < 0)
+		offset += limit;
+	else if (offset >= limit)
+		offset -= limit;
+
+	ops->var.xoffset = 0;
+	ops->var.yoffset = offset * vc->vc_font.height;
+	ops->update_start(info);
+
+	if (!scrollback_current)
+		fbcon_cursor(vc, CM_DRAW);
+	return 0;
+}
+
+static int fbcon_set_origin(struct vc_data *vc)
+{
+	if (softback_lines)
+		fbcon_scrolldelta(vc, softback_lines);
+	return 0;
+}
+
+static void fbcon_suspended(struct fb_info *info)
+{
+	struct vc_data *vc = NULL;
+	struct fbcon_ops *ops = info->fbcon_par;
+
+	if (!ops || ops->currcon < 0)
+		return;
+	vc = vc_cons[ops->currcon].d;
+
+	/* Clear cursor, restore saved data */
+	fbcon_cursor(vc, CM_ERASE);
+}
+
+static void fbcon_resumed(struct fb_info *info)
+{
+	struct vc_data *vc;
+	struct fbcon_ops *ops = info->fbcon_par;
+
+	if (!ops || ops->currcon < 0)
+		return;
+	vc = vc_cons[ops->currcon].d;
+
+	update_screen(vc);
+}
+
+static void fbcon_modechanged(struct fb_info *info)
+{
+	struct fbcon_ops *ops = info->fbcon_par;
+	struct vc_data *vc;
+	struct display *p;
+	int rows, cols;
+
+	if (!ops || ops->currcon < 0)
+		return;
+	vc = vc_cons[ops->currcon].d;
+	if (vc->vc_mode != KD_TEXT ||
+	    registered_fb[con2fb_map[ops->currcon]] != info)
+		return;
+
+	p = &fb_display[vc->vc_num];
+	set_blitting_type(vc, info, p);
+
+	if (CON_IS_VISIBLE(vc)) {
+		var_to_display(p, &info->var, info);
+		cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
+		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+		cols /= vc->vc_font.width;
+		rows /= vc->vc_font.height;
+		vc_resize(vc, cols, rows);
+		updatescrollmode(p, info, vc);
+		scrollback_max = 0;
+		scrollback_current = 0;
+
+		if (!fbcon_is_inactive(vc, info)) {
+		    ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
+		    ops->update_start(info);
+		}
+
+		fbcon_set_palette(vc, color_table);
+		update_screen(vc);
+		if (softback_buf)
+			fbcon_update_softback(vc);
+	}
+}
+
+static void fbcon_set_all_vcs(struct fb_info *info)
+{
+	struct fbcon_ops *ops = info->fbcon_par;
+	struct vc_data *vc;
+	struct display *p;
+	int i, rows, cols;
+
+	if (!ops || ops->currcon < 0)
+		return;
+
+	for (i = 0; i < MAX_NR_CONSOLES; i++) {
+		vc = vc_cons[i].d;
+		if (!vc || vc->vc_mode != KD_TEXT ||
+		    registered_fb[con2fb_map[i]] != info)
+			continue;
+
+		p = &fb_display[vc->vc_num];
+		set_blitting_type(vc, info, p);
+		var_to_display(p, &info->var, info);
+		cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
+		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+		cols /= vc->vc_font.width;
+		rows /= vc->vc_font.height;
+		vc_resize(vc, cols, rows);
+
+		if (CON_IS_VISIBLE(vc)) {
+			updatescrollmode(p, info, vc);
+			scrollback_max = 0;
+			scrollback_current = 0;
+
+			if (!fbcon_is_inactive(vc, info)) {
+			    ops->var.xoffset = ops->var.yoffset =
+				p->yscroll = 0;
+			    ops->update_start(info);
+			}
+
+			fbcon_set_palette(vc, color_table);
+			update_screen(vc);
+			if (softback_buf)
+				fbcon_update_softback(vc);
+		}
+	}
+}
+
+static int fbcon_mode_deleted(struct fb_info *info,
+			      struct fb_videomode *mode)
+{
+	struct fb_info *fb_info;
+	struct display *p;
+	int i, j, found = 0;
+
+	/* before deletion, ensure that mode is not in use */
+	for (i = first_fb_vc; i <= last_fb_vc; i++) {
+		j = con2fb_map[i];
+		if (j == -1)
+			continue;
+		fb_info = registered_fb[j];
+		if (fb_info != info)
+			continue;
+		p = &fb_display[i];
+		if (!p || !p->mode)
+			continue;
+		if (fb_mode_is_equal(p->mode, mode)) {
+			found = 1;
+			break;
+		}
+	}
+	return found;
+}
+
+static int fbcon_fb_registered(int idx)
+{
+	int ret = 0, i;
+
+	if (info_idx == -1) {
+		for (i = 0; i < MAX_NR_CONSOLES; i++) {
+			if (con2fb_map_boot[i] == idx) {
+				info_idx = idx;
+				break;
+			}
+		}
+		if (info_idx != -1)
+			ret = fbcon_takeover(1);
+	} else {
+		for (i = 0; i < MAX_NR_CONSOLES; i++) {
+			if (con2fb_map_boot[i] == idx)
+				set_con2fb_map(i, idx, 0);
+		}
+	}
+
+	return ret;
+}
+
+static void fbcon_fb_blanked(struct fb_info *info, int blank)
+{
+	struct fbcon_ops *ops = info->fbcon_par;
+	struct vc_data *vc;
+
+	if (!ops || ops->currcon < 0)
+		return;
+
+	vc = vc_cons[ops->currcon].d;
+	if (vc->vc_mode != KD_TEXT ||
+			registered_fb[con2fb_map[ops->currcon]] != info)
+		return;
+
+	if (CON_IS_VISIBLE(vc)) {
+		if (blank)
+			do_blank_screen(0);
+		else
+			do_unblank_screen(0);
+	}
+	ops->blank_state = blank;
+}
+
+static void fbcon_new_modelist(struct fb_info *info)
+{
+	int i;
+	struct vc_data *vc;
+	struct fb_var_screeninfo var;
+	struct fb_videomode *mode;
+
+	for (i = 0; i < MAX_NR_CONSOLES; i++) {
+		if (registered_fb[con2fb_map[i]] != info)
+			continue;
+		if (!fb_display[i].mode)
+			continue;
+		vc = vc_cons[i].d;
+		display_to_var(&var, &fb_display[i]);
+		mode = fb_find_nearest_mode(fb_display[i].mode,
+					    &info->modelist);
+		fb_videomode_to_var(&var, mode);
+
+		if (vc)
+			fbcon_set_disp(info, &var, vc);
+		else
+			fbcon_preset_disp(info, &var, i);
+
+	}
+}
+
+static int fbcon_event_notify(struct notifier_block *self, 
+			      unsigned long action, void *data)
+{
+	struct fb_event *event = data;
+	struct fb_info *info = event->info;
+	struct fb_videomode *mode;
+	struct fb_con2fbmap *con2fb;
+	int ret = 0;
+
+	switch(action) {
+	case FB_EVENT_SUSPEND:
+		fbcon_suspended(info);
+		break;
+	case FB_EVENT_RESUME:
+		fbcon_resumed(info);
+		break;
+	case FB_EVENT_MODE_CHANGE:
+		fbcon_modechanged(info);
+		break;
+	case FB_EVENT_MODE_CHANGE_ALL:
+		fbcon_set_all_vcs(info);
+		break;
+	case FB_EVENT_MODE_DELETE:
+		mode = event->data;
+		ret = fbcon_mode_deleted(info, mode);
+		break;
+	case FB_EVENT_FB_REGISTERED:
+		ret = fbcon_fb_registered(info->node);
+		break;
+	case FB_EVENT_SET_CONSOLE_MAP:
+		con2fb = event->data;
+		ret = set_con2fb_map(con2fb->console - 1,
+				     con2fb->framebuffer, 1);
+		break;
+	case FB_EVENT_GET_CONSOLE_MAP:
+		con2fb = event->data;
+		con2fb->framebuffer = con2fb_map[con2fb->console - 1];
+		break;
+	case FB_EVENT_BLANK:
+		fbcon_fb_blanked(info, *(int *)event->data);
+		break;
+	case FB_EVENT_NEW_MODELIST:
+		fbcon_new_modelist(info);
+		break;
+	case FB_EVENT_SET_CON_ROTATE:
+		fbcon_rotate(info, *(int *)event->data);
+		break;
+	case FB_EVENT_GET_CON_ROTATE:
+		ret = fbcon_get_rotate(info);
+		break;
+	case FB_EVENT_SET_CON_ROTATE_ALL:
+		fbcon_rotate_all(info, *(int *)event->data);
+	}
+
+	return ret;
+}
+
+/*
+ *  The console `switch' structure for the frame buffer based console
+ */
+
+static const struct consw fb_con = {
+	.owner			= THIS_MODULE,
+	.con_startup 		= fbcon_startup,
+	.con_init 		= fbcon_init,
+	.con_deinit 		= fbcon_deinit,
+	.con_clear 		= fbcon_clear,
+	.con_putc 		= fbcon_putc,
+	.con_putcs 		= fbcon_putcs,
+	.con_cursor 		= fbcon_cursor,
+	.con_scroll 		= fbcon_scroll,
+	.con_bmove 		= fbcon_bmove,
+	.con_switch 		= fbcon_switch,
+	.con_blank 		= fbcon_blank,
+	.con_font_set 		= fbcon_set_font,
+	.con_font_get 		= fbcon_get_font,
+	.con_font_default	= fbcon_set_def_font,
+	.con_font_copy 		= fbcon_copy_font,
+	.con_set_palette 	= fbcon_set_palette,
+	.con_scrolldelta 	= fbcon_scrolldelta,
+	.con_set_origin 	= fbcon_set_origin,
+	.con_invert_region 	= fbcon_invert_region,
+	.con_screen_pos 	= fbcon_screen_pos,
+	.con_getxy 		= fbcon_getxy,
+	.con_resize             = fbcon_resize,
+};
+
+static struct notifier_block fbcon_event_notifier = {
+	.notifier_call	= fbcon_event_notify,
+};
+
+static int __init fb_console_init(void)
+{
+	int i;
+
+	acquire_console_sem();
+	fb_register_client(&fbcon_event_notifier);
+	release_console_sem();
+
+	for (i = 0; i < MAX_NR_CONSOLES; i++)
+		con2fb_map[i] = -1;
+
+	if (num_registered_fb) {
+		for (i = 0; i < FB_MAX; i++) {
+			if (registered_fb[i] != NULL) {
+				info_idx = i;
+				break;
+			}
+		}
+		fbcon_takeover(0);
+	}
+
+	return 0;
+}
+
+module_init(fb_console_init);
+
+#ifdef MODULE
+
+static void __exit fb_console_exit(void)
+{
+	acquire_console_sem();
+	fb_unregister_client(&fbcon_event_notifier);
+	release_console_sem();
+	give_up_console(&fb_con);
+}	
+
+module_exit(fb_console_exit);
+
+#endif
+
+MODULE_LICENSE("GPL");
diff -urN oldtree/drivers/video/fbcmap.c newtree/drivers/video/fbcmap.c
--- oldtree/drivers/video/fbcmap.c	2006-01-03 03:21:10.000000000 +0000
+++ newtree/drivers/video/fbcmap.c	2006-02-03 18:18:17.095731320 +0000
@@ -16,6 +16,7 @@
 #include <linux/tty.h>
 #include <linux/fb.h>
 #include <linux/slab.h>
+#include "fbsplash.h"
 
 #include <asm/uaccess.h>
 
@@ -235,14 +236,17 @@
 			if (transp)
 				htransp = *transp++;
 			if (info->fbops->fb_setcolreg(start++,
-						      hred, hgreen, hblue,
+						      hred, hgreen, hblue, 
 						      htransp, info))
 				break;
 		}
 	}
-	if (rc == 0)
+	if (rc == 0) {
 		fb_copy_cmap(cmap, &info->cmap);
-
+		if (fbsplash_active(info, vc_cons[fg_console].d) &&
+		    info->fix.visual == FB_VISUAL_DIRECTCOLOR)
+			fbsplash_fix_pseudo_pal(info, vc_cons[fg_console].d);
+	}
 	return rc;
 }
 
@@ -250,7 +254,7 @@
 {
 	int rc, size = cmap->len * sizeof(u16);
 	struct fb_cmap umap;
-
+	
 	if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
 			        !info->fbops->fb_setcmap))
 		return -EINVAL;
diff -urN oldtree/drivers/video/fbsplash.c newtree/drivers/video/fbsplash.c
--- oldtree/drivers/video/fbsplash.c	1970-01-01 00:00:00.000000000 +0000
+++ newtree/drivers/video/fbsplash.c	2006-02-03 18:18:17.096731168 +0000
@@ -0,0 +1,406 @@
+/* 
+ *  linux/drivers/video/fbsplash.c -- Framebuffer splash routines
+ *
+ *  Copyright (C) 2004 Michal Januszewski <spock@gentoo.org>
+ *
+ *  Code based upon "Bootsplash" (C) 2001-2003 
+ *       Volker Poplawski <volker@poplawski.de>,
+ *       Stefan Reinauer <stepan@suse.de>,
+ *       Steffen Winterfeldt <snwint@suse.de>,
+ *       Michael Schroeder <mls@suse.de>,
+ *       Ken Wimer <wimer@suse.de>.
+ *
+ *  Splash render routines are located in /linux/drivers/video/cfbsplash.c
+ * 
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ * 
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/fb.h>
+#include <linux/vt_kern.h>
+#include <linux/vmalloc.h>
+#include <linux/unistd.h>
+#include <linux/syscalls.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/workqueue.h>
+#include <linux/kmod.h>
+#include <linux/miscdevice.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+
+#include <asm/uaccess.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include "console/fbcon.h"
+#include "fbsplash.h"
+
+#define SPLASH_VERSION 		"0.9.2"
+
+extern signed char con2fb_map[];
+static int fbsplash_enable(struct vc_data *vc);
+char fbsplash_path[KMOD_PATH_LEN] = "/sbin/splash_helper";
+
+int fbsplash_call_helper(char* cmd, unsigned short vc)
+{
+	char *envp[] = {
+		"HOME=/",
+		"PATH=/sbin:/bin",
+		NULL
+	};
+
+	char tfb[5];
+	char tcons[5];
+	unsigned char fb = (int) con2fb_map[vc];
+
+	char *argv[] = {
+		fbsplash_path,
+		"2",
+		cmd,
+		tcons,
+		tfb,
+		vc_cons[vc].d->vc_splash.theme,
+		NULL
+	};
+
+	snprintf(tfb,5,"%d",fb);
+	snprintf(tcons,5,"%d",vc);
+
+	return call_usermodehelper(fbsplash_path, argv, envp, 1);
+}
+
+/* Disables fbsplash on a virtual console; called with console sem held. */
+int fbsplash_disable(struct vc_data *vc, unsigned char redraw)
+{
+	struct fb_info* info;
+
+	if (!vc->vc_splash.state)
+		return -EINVAL;
+
+	info = registered_fb[(int) con2fb_map[vc->vc_num]];
+
+	if (info == NULL)
+		return -EINVAL;
+
+	vc->vc_splash.state = 0; 
+	vc_resize(vc, info->var.xres / vc->vc_font.width, 
+		  info->var.yres / vc->vc_font.height);
+
+	if (fg_console == vc->vc_num && redraw) {
+		redraw_screen(vc, 0);
+		update_region(vc, vc->vc_origin + 
+			      vc->vc_size_row * vc->vc_top, 
+			      vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
+	}
+
+	printk(KERN_INFO "fbsplash: switched splash state to 'off' on console %d\n", 
+			 vc->vc_num);
+
+	return 0;
+}
+
+/* Enables fbsplash on a virtual console; called with console sem held. */
+static int fbsplash_enable(struct vc_data *vc)
+{
+	struct fb_info* info;
+
+	info = registered_fb[(int) con2fb_map[vc->vc_num]];
+		
+	if (vc->vc_splash.twidth == 0 || vc->vc_splash.theight == 0 || 
+	    info == NULL || vc->vc_splash.state || (!info->splash.data &&
+	    vc->vc_num == fg_console))
+		return -EINVAL;
+	
+	vc->vc_splash.state = 1;
+	vc_resize(vc, vc->vc_splash.twidth / vc->vc_font.width, 
+		  vc->vc_splash.theight / vc->vc_font.height);
+
+	if (fg_console == vc->vc_num) {
+		redraw_screen(vc, 0);
+		update_region(vc, vc->vc_origin + 
+			      vc->vc_size_row * vc->vc_top, 
+			      vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
+		fbsplash_clear_margins(vc, info, 0);
+	}
+
+	printk(KERN_INFO "fbsplash: switched splash state to 'on' on console %d\n", 
+			 vc->vc_num);
+
+	return 0;
+}
+
+static inline int fbsplash_ioctl_dosetstate(struct vc_data *vc, unsigned int __user* state, unsigned char origin)
+{
+	int tmp, ret;
+
+	if (get_user(tmp, state))
+		return -EFAULT;
+
+	if (origin == FB_SPLASH_IO_ORIG_USER)
+		acquire_console_sem();
+	if (!tmp)
+		ret = fbsplash_disable(vc, 1);
+	else
+		ret = fbsplash_enable(vc);
+	if (origin == FB_SPLASH_IO_ORIG_USER)
+		release_console_sem();
+
+	return ret;
+}
+
+static inline int fbsplash_ioctl_dogetstate(struct vc_data *vc, unsigned int __user *state)
+{
+	return put_user(vc->vc_splash.state, (unsigned int __user*) state);
+}
+
+static int fbsplash_ioctl_dosetcfg(struct vc_data *vc, struct vc_splash __user *arg, unsigned char origin)
+{
+	struct vc_splash cfg;
+	struct fb_info *info;
+	int len;
+	char *tmp;
+	
+	info = registered_fb[(int) con2fb_map[vc->vc_num]];
+
+	if (copy_from_user(&cfg, arg, sizeof(struct vc_splash)))
+		return -EFAULT;
+	if (info == NULL || !cfg.twidth || !cfg.theight || 
+	    cfg.tx + cfg.twidth  > info->var.xres ||
+	    cfg.ty + cfg.theight > info->var.yres)
+		return -EINVAL;
+
+	len = strlen_user(cfg.theme);
+	if (!len || len > FB_SPLASH_THEME_LEN)
+		return -EINVAL;
+	tmp = kmalloc(len, GFP_KERNEL);
+	if (!tmp)
+		return -ENOMEM;
+	if (copy_from_user(tmp, (void __user *)cfg.theme, len))
+		return -EFAULT;
+	cfg.theme = tmp;
+	cfg.state = 0;
+
+	/* If this ioctl is a response to a request from kernel, the console sem
+	 * is already held; we also don't need to disable splash because either the
+	 * new config and background picture will be successfully loaded, and the 
+	 * splash will stay on, or in case of a failure it'll be turned off in fbcon. */
+	if (origin == FB_SPLASH_IO_ORIG_USER) {
+		acquire_console_sem();
+		if (vc->vc_splash.state)
+			fbsplash_disable(vc, 1);
+	}
+
+	if (vc->vc_splash.theme)
+		kfree(vc->vc_splash.theme);
+
+	vc->vc_splash = cfg;
+
+	if (origin == FB_SPLASH_IO_ORIG_USER)
+		release_console_sem();
+
+	printk(KERN_INFO "fbsplash: console %d using theme '%s'\n", 
+			 vc->vc_num, vc->vc_splash.theme);
+	return 0;	
+}
+
+static int fbsplash_ioctl_dogetcfg(struct vc_data *vc, struct vc_splash __user *arg)
+{
+	struct vc_splash splash;
+	char __user *tmp;
+
+	if (get_user(tmp, &arg->theme))
+		return -EFAULT;
+	
+	splash = vc->vc_splash;
+	splash.theme = tmp;
+
+	if (vc->vc_splash.theme) {
+		if (copy_to_user(tmp, vc->vc_splash.theme, strlen(vc->vc_splash.theme) + 1))
+			return -EFAULT;
+	} else
+		if (put_user(0, tmp))
+			return -EFAULT;
+
+	if (copy_to_user(arg, &splash, sizeof(struct vc_splash)))
+		return -EFAULT;
+
+	return 0;
+}
+
+static int fbsplash_ioctl_dosetpic(struct vc_data *vc, struct fb_image __user *arg, unsigned char origin)
+{
+	struct fb_image img;
+	struct fb_info *info;
+	int len;
+	u8 *tmp;
+	
+	if (vc->vc_num != fg_console) 
+		return -EINVAL;
+
+	info = registered_fb[(int) con2fb_map[vc->vc_num]];
+	
+	if (info == NULL)
+		return -EINVAL;
+	
+	if (copy_from_user(&img, arg, sizeof(struct fb_image)))
+		return -EFAULT;
+	
+	if (img.width != info->var.xres || img.height != info->var.yres) {
+		printk(KERN_ERR "fbsplash: picture dimensions mismatch\n");
+		return -EINVAL;
+	}
+
+	if (img.depth != info->var.bits_per_pixel) {
+		printk(KERN_ERR "fbsplash: picture depth mismatch\n");
+		return -EINVAL;
+	}
+		
+	if (img.depth == 8) {
+		if (!img.cmap.len || !img.cmap.red || !img.cmap.green || 
+		    !img.cmap.blue)
+			return -EINVAL;
+		
+		tmp = vmalloc(img.cmap.len * 3 * 2);
+		if (!tmp)
+			return -ENOMEM;
+
+		if (copy_from_user(tmp, (void __user*)img.cmap.red, img.cmap.len * 2) ||
+		    copy_from_user(tmp + (img.cmap.len << 1),
+			    	   (void __user*)img.cmap.green, (img.cmap.len << 1)) ||
+		    copy_from_user(tmp + (img.cmap.len << 2),
+			    	   (void __user*)img.cmap.blue, (img.cmap.len << 1))) {
+			vfree(tmp);
+			return -EFAULT;
+		}
+			
+		img.cmap.transp = NULL;
+		img.cmap.red = (u16*)tmp;
+		img.cmap.green = img.cmap.red + img.cmap.len;
+		img.cmap.blue = img.cmap.green + img.cmap.len;
+	} else {
+		img.cmap.red = NULL;
+	}
+		
+	len = ((img.depth + 7) >> 3) * img.width * img.height;
+	tmp = vmalloc(len);
+
+	if (!tmp)
+		goto out;
+
+	if (copy_from_user(tmp, (void __user*)img.data, len))
+		goto out;
+		
+	img.data = tmp;
+
+	/* If this ioctl is a response to a request from kernel, the console sem
+	 * is already held. */
+	if (origin == FB_SPLASH_IO_ORIG_USER)
+		acquire_console_sem();
+	
+	if (info->splash.data)
+		vfree((u8*)info->splash.data);
+	if (info->splash.cmap.red)
+		vfree(info->splash.cmap.red);
+	
+	info->splash = img;
+
+	if (origin == FB_SPLASH_IO_ORIG_USER)
+		release_console_sem();
+
+	return 0;
+
+out:	if (img.cmap.red)
+		vfree(img.cmap.red);
+	if (tmp)
+		vfree(tmp);
+	return -ENOMEM;
+}
+
+static int splash_ioctl(struct inode * inode, struct file *filp, u_int cmd, 
+			u_long arg)
+{
+	struct fb_splash_iowrapper __user *wrapper = (void __user*) arg;
+	struct vc_data *vc = NULL;
+	unsigned short vc_num = 0;
+	unsigned char origin = 0;
+	void __user *data = NULL;
+	
+	if (!access_ok(VERIFY_READ, wrapper, 
+			sizeof(struct fb_splash_iowrapper)))
+		return -EFAULT;
+	
+	__get_user(vc_num, &wrapper->vc);
+	__get_user(origin, &wrapper->origin);
+	__get_user(data, &wrapper->data);
+		
+	if (!vc_cons_allocated(vc_num))
+		return -EINVAL;
+
+	vc = vc_cons[vc_num].d;
+	
+	switch (cmd) {
+	case FBIOSPLASH_SETPIC:
+		return fbsplash_ioctl_dosetpic(vc, (struct fb_image __user*)data, origin);
+	case FBIOSPLASH_SETCFG:
+		return fbsplash_ioctl_dosetcfg(vc, (struct vc_splash*)data, origin);
+	case FBIOSPLASH_GETCFG:
+		return fbsplash_ioctl_dogetcfg(vc, (struct vc_splash*)data);
+	case FBIOSPLASH_SETSTATE:
+		return fbsplash_ioctl_dosetstate(vc, (unsigned int *)data, origin);
+	case FBIOSPLASH_GETSTATE:
+		return fbsplash_ioctl_dogetstate(vc, (unsigned int *)data);
+	default:
+		return -ENOIOCTLCMD;
+	}	
+}
+
+static struct file_operations splash_ops = {
+	.owner = THIS_MODULE,
+	.ioctl = splash_ioctl
+};
+
+static struct miscdevice splash_dev = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "fbsplash",
+	.fops = &splash_ops
+};
+
+int fbsplash_init(void)
+{
+	struct fb_info *info;
+	struct vc_data *vc;
+	int i;
+	
+	vc = vc_cons[0].d;
+	info = registered_fb[0];
+
+	for (i = 0; i < num_registered_fb; i++) {
+		registered_fb[i]->splash.data = NULL;
+		registered_fb[i]->splash.cmap.red = NULL;
+	}
+
+	for (i = 0; i < MAX_NR_CONSOLES && vc_cons[i].d; i++) {
+		vc_cons[i].d->vc_splash.state = vc_cons[i].d->vc_splash.twidth = 
+						vc_cons[i].d->vc_splash.theight = 0;
+		vc_cons[i].d->vc_splash.theme = NULL;
+	}
+
+	i = misc_register(&splash_dev);
+	if (i) {
+		printk(KERN_ERR "fbsplash: failed to register device\n");
+		return i;
+	}
+
+	fbsplash_call_helper("init", 0);
+	
+	return 0;
+}
+
+EXPORT_SYMBOL(fbsplash_path);
diff -urN oldtree/drivers/video/fbsplash.h newtree/drivers/video/fbsplash.h
--- oldtree/drivers/video/fbsplash.h	1970-01-01 00:00:00.000000000 +0000
+++ newtree/drivers/video/fbsplash.h	2006-02-03 18:18:17.096731168 +0000
@@ -0,0 +1,76 @@
+/* 
+ *  linux/drivers/video/fbsplash.h -- Framebuffer splash headers
+ *
+ *  Copyright (C) 2004 Michal Januszewski <spock@gentoo.org>
+ *
+ */
+
+#ifndef __FB_SPLASH_H
+#define __FB_SPLASH_H
+
+#ifndef _LINUX_FB_H
+#include <linux/fb.h>
+#endif
+
+/* This is needed for vc_cons in fbcmap.c */
+#include <linux/vt_kern.h>
+
+struct fb_cursor;
+struct fb_info;
+struct vc_data;
+
+#ifdef CONFIG_FB_SPLASH
+/* fbsplash.c */
+int fbsplash_init(void);
+int fbsplash_call_helper(char* cmd, unsigned short cons);
+int fbsplash_disable(struct vc_data *vc, unsigned char redraw);
+
+/* cfbsplash.c */
+void fbsplash_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx);
+void fbsplash_cursor(struct fb_info *info, struct fb_cursor *cursor);
+void fbsplash_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width);
+void fbsplash_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only);
+void fbsplash_blank(struct vc_data *vc, struct fb_info *info, int blank);
+void fbsplash_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width);
+void fbsplash_copy(u8 *dst, u8 *src, int height, int width, int linebytes, int srclinesbytes, int bpp);
+void fbsplash_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc);
+
+/* vt.c */
+void acquire_console_sem(void);
+void release_console_sem(void);
+void do_unblank_screen(int entering_gfx);
+
+/* struct vc_data *y */
+#define fbsplash_active_vc(y) (y->vc_splash.state && y->vc_splash.theme) 
+
+/* struct fb_info *x, struct vc_data *y */
+#define fbsplash_active_nores(x,y) (x->splash.data && fbsplash_active_vc(y))
+
+/* struct fb_info *x, struct vc_data *y */
+#define fbsplash_active(x,y) (fbsplash_active_nores(x,y) &&		\
+			      x->splash.width == x->var.xres && 	\
+			      x->splash.height == x->var.yres &&	\
+			      x->splash.depth == x->var.bits_per_pixel)
+
+
+#else /* CONFIG_FB_SPLASH */
+
+static inline void fbsplash_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx) {}
+static inline void fbsplash_putc(struct vc_data *vc, struct fb_info *info, int c, int ypos, int xpos) {}
+static inline void fbsplash_cursor(struct fb_info *info, struct fb_cursor *cursor) {}
+static inline void fbsplash_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width) {}
+static inline void fbsplash_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only) {}
+static inline void fbsplash_blank(struct vc_data *vc, struct fb_info *info, int blank) {}
+static inline void fbsplash_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width) {}
+static inline void fbsplash_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc) {}
+static inline int fbsplash_call_helper(char* cmd, unsigned short cons) { return 0; }
+static inline int fbsplash_init(void) { return 0; }
+static inline int fbsplash_disable(struct vc_data *vc, unsigned char redraw) { return 0; }
+
+#define fbsplash_active_vc(y) (0)
+#define fbsplash_active_nores(x,y) (0)
+#define fbsplash_active(x,y) (0)
+
+#endif /* CONFIG_FB_SPLASH */
+
+#endif /* __FB_SPLASH_H */
diff -urN oldtree/include/linux/console_splash.h newtree/include/linux/console_splash.h
--- oldtree/include/linux/console_splash.h	1970-01-01 00:00:00.000000000 +0000
+++ newtree/include/linux/console_splash.h	2006-02-03 18:18:17.097731016 +0000
@@ -0,0 +1,13 @@
+#ifndef _LINUX_CONSOLE_SPLASH_H_
+#define _LINUX_CONSOLE_SPLASH_H_ 1
+
+/* A structure used by the framebuffer splash code (drivers/video/fbsplash.c) */
+struct vc_splash {
+	__u8 bg_color;				/* The color that is to be treated as transparent */
+	__u8 state;				/* Current splash state: 0 = off, 1 = on */
+	__u16 tx, ty;				/* Top left corner coordinates of the text field */
+	__u16 twidth, theight;			/* Width and height of the text field */
+	char* theme;
+};
+
+#endif
diff -urN oldtree/include/linux/console_struct.h newtree/include/linux/console_struct.h
--- oldtree/include/linux/console_struct.h	2006-01-03 03:21:10.000000000 +0000
+++ newtree/include/linux/console_struct.h	2006-02-03 18:18:17.097731016 +0000
@@ -14,6 +14,7 @@
 struct vt_struct;
 
 #define NPAR 16
+#include <linux/console_splash.h>
 
 struct vc_data {
 	unsigned short	vc_num;			/* Console number */
@@ -97,6 +98,8 @@
 	struct vc_data **vc_display_fg;		/* [!] Ptr to var holding fg console for this display */
 	unsigned long	vc_uni_pagedir;
 	unsigned long	*vc_uni_pagedir_loc;  /* [!] Location of uni_pagedir variable for this console */
+
+	struct vc_splash vc_splash;
 	/* additional information is in vt_kern.h */
 };
 
diff -urN oldtree/include/linux/fb.h newtree/include/linux/fb.h
--- oldtree/include/linux/fb.h	2006-01-03 03:21:10.000000000 +0000
+++ newtree/include/linux/fb.h	2006-02-03 18:18:17.098730864 +0000
@@ -8,6 +8,13 @@
 #define FB_MAJOR		29
 #define FB_MAX			32	/* sufficient for now */
 
+struct fb_splash_iowrapper
+{
+	unsigned short vc;		/* Virtual console */
+	unsigned char origin;		/* Point of origin of the request */
+	void *data;
+};
+
 /* ioctls
    0x46 is 'F'								*/
 #define FBIOGET_VSCREENINFO	0x4600
@@ -35,7 +42,15 @@
 #define FBIOGET_HWCINFO         0x4616
 #define FBIOPUT_MODEINFO        0x4617
 #define FBIOGET_DISPINFO        0x4618
-
+#define FBIOSPLASH_SETCFG	_IOWR('F', 0x19, struct fb_splash_iowrapper)
+#define FBIOSPLASH_GETCFG	_IOR('F', 0x1A, struct fb_splash_iowrapper)
+#define FBIOSPLASH_SETSTATE	_IOWR('F', 0x1B, struct fb_splash_iowrapper)
+#define FBIOSPLASH_GETSTATE	_IOR('F', 0x1C, struct fb_splash_iowrapper)
+#define FBIOSPLASH_SETPIC 	_IOWR('F', 0x1D, struct fb_splash_iowrapper)
+
+#define FB_SPLASH_THEME_LEN		128	/* Maximum lenght of a theme name */
+#define FB_SPLASH_IO_ORIG_KERNEL	0	/* Kernel ioctl origin */
+#define FB_SPLASH_IO_ORIG_USER		1 	/* User ioctl origin */
 
 #define FB_TYPE_PACKED_PIXELS		0	/* Packed Pixels	*/
 #define FB_TYPE_PLANES			1	/* Non interleaved planes */
@@ -769,6 +784,9 @@
 #define FBINFO_STATE_SUSPENDED	1
 	u32 state;			/* Hardware state i.e suspend */
 	void *fbcon_par;                /* fbcon use-only private area */
+
+	struct fb_image splash;
+
 	/* From here on everything is device dependent */
 	void *par;	
 };
diff -urN oldtree/include/linux/fb.h.orig newtree/include/linux/fb.h.orig
--- oldtree/include/linux/fb.h.orig	1970-01-01 00:00:00.000000000 +0000
+++ newtree/include/linux/fb.h.orig	2006-01-03 03:21:10.000000000 +0000
@@ -0,0 +1,996 @@
+#ifndef _LINUX_FB_H
+#define _LINUX_FB_H
+
+#include <asm/types.h>
+
+/* Definitions of frame buffers						*/
+
+#define FB_MAJOR		29
+#define FB_MAX			32	/* sufficient for now */
+
+/* ioctls
+   0x46 is 'F'								*/
+#define FBIOGET_VSCREENINFO	0x4600
+#define FBIOPUT_VSCREENINFO	0x4601
+#define FBIOGET_FSCREENINFO	0x4602
+#define FBIOGETCMAP		0x4604
+#define FBIOPUTCMAP		0x4605
+#define FBIOPAN_DISPLAY		0x4606
+#ifdef __KERNEL__
+#define FBIO_CURSOR            _IOWR('F', 0x08, struct fb_cursor_user)
+#else
+#define FBIO_CURSOR            _IOWR('F', 0x08, struct fb_cursor)
+#endif
+/* 0x4607-0x460B are defined below */
+/* #define FBIOGET_MONITORSPEC	0x460C */
+/* #define FBIOPUT_MONITORSPEC	0x460D */
+/* #define FBIOSWITCH_MONIBIT	0x460E */
+#define FBIOGET_CON2FBMAP	0x460F
+#define FBIOPUT_CON2FBMAP	0x4610
+#define FBIOBLANK		0x4611		/* arg: 0 or vesa level + 1 */
+#define FBIOGET_VBLANK		_IOR('F', 0x12, struct fb_vblank)
+#define FBIO_ALLOC              0x4613
+#define FBIO_FREE               0x4614
+#define FBIOGET_GLYPH           0x4615
+#define FBIOGET_HWCINFO         0x4616
+#define FBIOPUT_MODEINFO        0x4617
+#define FBIOGET_DISPINFO        0x4618
+
+
+#define FB_TYPE_PACKED_PIXELS		0	/* Packed Pixels	*/
+#define FB_TYPE_PLANES			1	/* Non interleaved planes */
+#define FB_TYPE_INTERLEAVED_PLANES	2	/* Interleaved planes	*/
+#define FB_TYPE_TEXT			3	/* Text/attributes	*/
+#define FB_TYPE_VGA_PLANES		4	/* EGA/VGA planes	*/
+
+#define FB_AUX_TEXT_MDA		0	/* Monochrome text */
+#define FB_AUX_TEXT_CGA		1	/* CGA/EGA/VGA Color text */
+#define FB_AUX_TEXT_S3_MMIO	2	/* S3 MMIO fasttext */
+#define FB_AUX_TEXT_MGA_STEP16	3	/* MGA Millenium I: text, attr, 14 reserved bytes */
+#define FB_AUX_TEXT_MGA_STEP8	4	/* other MGAs:      text, attr,  6 reserved bytes */
+
+#define FB_AUX_VGA_PLANES_VGA4		0	/* 16 color planes (EGA/VGA) */
+#define FB_AUX_VGA_PLANES_CFB4		1	/* CFB4 in planes (VGA) */
+#define FB_AUX_VGA_PLANES_CFB8		2	/* CFB8 in planes (VGA) */
+
+#define FB_VISUAL_MONO01		0	/* Monochr. 1=Black 0=White */
+#define FB_VISUAL_MONO10		1	/* Monochr. 1=White 0=Black */
+#define FB_VISUAL_TRUECOLOR		2	/* True color	*/
+#define FB_VISUAL_PSEUDOCOLOR		3	/* Pseudo color (like atari) */
+#define FB_VISUAL_DIRECTCOLOR		4	/* Direct color */
+#define FB_VISUAL_STATIC_PSEUDOCOLOR	5	/* Pseudo color readonly */
+
+#define FB_ACCEL_NONE		0	/* no hardware accelerator	*/
+#define FB_ACCEL_ATARIBLITT	1	/* Atari Blitter		*/
+#define FB_ACCEL_AMIGABLITT	2	/* Amiga Blitter                */
+#define FB_ACCEL_S3_TRIO64	3	/* Cybervision64 (S3 Trio64)    */
+#define FB_ACCEL_NCR_77C32BLT	4	/* RetinaZ3 (NCR 77C32BLT)      */
+#define FB_ACCEL_S3_VIRGE	5	/* Cybervision64/3D (S3 ViRGE)	*/
+#define FB_ACCEL_ATI_MACH64GX	6	/* ATI Mach 64GX family		*/
+#define FB_ACCEL_DEC_TGA	7	/* DEC 21030 TGA		*/
+#define FB_ACCEL_ATI_MACH64CT	8	/* ATI Mach 64CT family		*/
+#define FB_ACCEL_ATI_MACH64VT	9	/* ATI Mach 64CT family VT class */
+#define FB_ACCEL_ATI_MACH64GT	10	/* ATI Mach 64CT family GT class */
+#define FB_ACCEL_SUN_CREATOR	11	/* Sun Creator/Creator3D	*/
+#define FB_ACCEL_SUN_CGSIX	12	/* Sun cg6			*/
+#define FB_ACCEL_SUN_LEO	13	/* Sun leo/zx			*/
+#define FB_ACCEL_IMS_TWINTURBO	14	/* IMS Twin Turbo		*/
+#define FB_ACCEL_3DLABS_PERMEDIA2 15	/* 3Dlabs Permedia 2		*/
+#define FB_ACCEL_MATROX_MGA2064W 16	/* Matrox MGA2064W (Millenium)	*/
+#define FB_ACCEL_MATROX_MGA1064SG 17	/* Matrox MGA1064SG (Mystique)	*/
+#define FB_ACCEL_MATROX_MGA2164W 18	/* Matrox MGA2164W (Millenium II) */
+#define FB_ACCEL_MATROX_MGA2164W_AGP 19	/* Matrox MGA2164W (Millenium II) */
+#define FB_ACCEL_MATROX_MGAG100	20	/* Matrox G100 (Productiva G100) */
+#define FB_ACCEL_MATROX_MGAG200	21	/* Matrox G200 (Myst, Mill, ...) */
+#define FB_ACCEL_SUN_CG14	22	/* Sun cgfourteen		 */
+#define FB_ACCEL_SUN_BWTWO	23	/* Sun bwtwo			*/
+#define FB_ACCEL_SUN_CGTHREE	24	/* Sun cgthree			*/
+#define FB_ACCEL_SUN_TCX	25	/* Sun tcx			*/
+#define FB_ACCEL_MATROX_MGAG400	26	/* Matrox G400			*/
+#define FB_ACCEL_NV3		27	/* nVidia RIVA 128              */
+#define FB_ACCEL_NV4		28	/* nVidia RIVA TNT		*/
+#define FB_ACCEL_NV5		29	/* nVidia RIVA TNT2		*/
+#define FB_ACCEL_CT_6555x	30	/* C&T 6555x			*/
+#define FB_ACCEL_3DFX_BANSHEE	31	/* 3Dfx Banshee			*/
+#define FB_ACCEL_ATI_RAGE128	32	/* ATI Rage128 family		*/
+#define FB_ACCEL_IGS_CYBER2000	33	/* CyberPro 2000		*/
+#define FB_ACCEL_IGS_CYBER2010	34	/* CyberPro 2010		*/
+#define FB_ACCEL_IGS_CYBER5000	35	/* CyberPro 5000		*/
+#define FB_ACCEL_SIS_GLAMOUR    36	/* SiS 300/630/540              */
+#define FB_ACCEL_3DLABS_PERMEDIA3 37	/* 3Dlabs Permedia 3		*/
+#define FB_ACCEL_ATI_RADEON	38	/* ATI Radeon family		*/
+#define FB_ACCEL_I810           39      /* Intel 810/815                */
+#define FB_ACCEL_SIS_GLAMOUR_2  40	/* SiS 315, 650, 740		*/
+#define FB_ACCEL_SIS_XABRE      41	/* SiS 330 ("Xabre")		*/
+#define FB_ACCEL_I830           42      /* Intel 830M/845G/85x/865G     */
+#define FB_ACCEL_NV_10          43      /* nVidia Arch 10               */
+#define FB_ACCEL_NV_20          44      /* nVidia Arch 20               */
+#define FB_ACCEL_NV_30          45      /* nVidia Arch 30               */
+#define FB_ACCEL_NV_40          46      /* nVidia Arch 40               */
+#define FB_ACCEL_XGI_VOLARI_V	47	/* XGI Volari V3XT, V5, V8      */
+#define FB_ACCEL_XGI_VOLARI_Z	48	/* XGI Volari Z7                */
+#define FB_ACCEL_NEOMAGIC_NM2070 90	/* NeoMagic NM2070              */
+#define FB_ACCEL_NEOMAGIC_NM2090 91	/* NeoMagic NM2090              */
+#define FB_ACCEL_NEOMAGIC_NM2093 92	/* NeoMagic NM2093              */
+#define FB_ACCEL_NEOMAGIC_NM2097 93	/* NeoMagic NM2097              */
+#define FB_ACCEL_NEOMAGIC_NM2160 94	/* NeoMagic NM2160              */
+#define FB_ACCEL_NEOMAGIC_NM2200 95	/* NeoMagic NM2200              */
+#define FB_ACCEL_NEOMAGIC_NM2230 96	/* NeoMagic NM2230              */
+#define FB_ACCEL_NEOMAGIC_NM2360 97	/* NeoMagic NM2360              */
+#define FB_ACCEL_NEOMAGIC_NM2380 98	/* NeoMagic NM2380              */
+
+#define FB_ACCEL_SAVAGE4        0x80	/* S3 Savage4                   */
+#define FB_ACCEL_SAVAGE3D       0x81	/* S3 Savage3D                  */
+#define FB_ACCEL_SAVAGE3D_MV    0x82	/* S3 Savage3D-MV               */
+#define FB_ACCEL_SAVAGE2000     0x83	/* S3 Savage2000                */
+#define FB_ACCEL_SAVAGE_MX_MV   0x84	/* S3 Savage/MX-MV              */
+#define FB_ACCEL_SAVAGE_MX      0x85	/* S3 Savage/MX                 */
+#define FB_ACCEL_SAVAGE_IX_MV   0x86	/* S3 Savage/IX-MV              */
+#define FB_ACCEL_SAVAGE_IX      0x87	/* S3 Savage/IX                 */
+#define FB_ACCEL_PROSAVAGE_PM   0x88	/* S3 ProSavage PM133           */
+#define FB_ACCEL_PROSAVAGE_KM   0x89	/* S3 ProSavage KM133           */
+#define FB_ACCEL_S3TWISTER_P    0x8a	/* S3 Twister                   */
+#define FB_ACCEL_S3TWISTER_K    0x8b	/* S3 TwisterK                  */
+#define FB_ACCEL_SUPERSAVAGE    0x8c    /* S3 Supersavage               */
+#define FB_ACCEL_PROSAVAGE_DDR  0x8d	/* S3 ProSavage DDR             */
+#define FB_ACCEL_PROSAVAGE_DDRK 0x8e	/* S3 ProSavage DDR-K           */
+
+struct fb_fix_screeninfo {
+	char id[16];			/* identification string eg "TT Builtin" */
+	unsigned long smem_start;	/* Start of frame buffer mem */
+					/* (physical address) */
+	__u32 smem_len;			/* Length of frame buffer mem */
+	__u32 type;			/* see FB_TYPE_*		*/
+	__u32 type_aux;			/* Interleave for interleaved Planes */
+	__u32 visual;			/* see FB_VISUAL_*		*/ 
+	__u16 xpanstep;			/* zero if no hardware panning  */
+	__u16 ypanstep;			/* zero if no hardware panning  */
+	__u16 ywrapstep;		/* zero if no hardware ywrap    */
+	__u32 line_length;		/* length of a line in bytes    */
+	unsigned long mmio_start;	/* Start of Memory Mapped I/O   */
+					/* (physical address) */
+	__u32 mmio_len;			/* Length of Memory Mapped I/O  */
+	__u32 accel;			/* Indicate to driver which	*/
+					/*  specific chip/card we have	*/
+	__u16 reserved[3];		/* Reserved for future compatibility */
+};
+
+/* Interpretation of offset for color fields: All offsets are from the right,
+ * inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you
+ * can use the offset as right argument to <<). A pixel afterwards is a bit
+ * stream and is written to video memory as that unmodified. This implies
+ * big-endian byte order if bits_per_pixel is greater than 8.
+ */
+struct fb_bitfield {
+	__u32 offset;			/* beginning of bitfield	*/
+	__u32 length;			/* length of bitfield		*/
+	__u32 msb_right;		/* != 0 : Most significant bit is */ 
+					/* right */ 
+};
+
+#define FB_NONSTD_HAM		1	/* Hold-And-Modify (HAM)        */
+
+#define FB_ACTIVATE_NOW		0	/* set values immediately (or vbl)*/
+#define FB_ACTIVATE_NXTOPEN	1	/* activate on next open	*/
+#define FB_ACTIVATE_TEST	2	/* don't set, round up impossible */
+#define FB_ACTIVATE_MASK       15
+					/* values			*/
+#define FB_ACTIVATE_VBL	       16	/* activate values on next vbl  */
+#define FB_CHANGE_CMAP_VBL     32	/* change colormap on vbl	*/
+#define FB_ACTIVATE_ALL	       64	/* change all VCs on this fb	*/
+#define FB_ACTIVATE_FORCE     128	/* force apply even when no change*/
+#define FB_ACTIVATE_INV_MODE  256       /* invalidate videomode */
+
+#define FB_ACCELF_TEXT		1	/* (OBSOLETE) see fb_info.flags and vc_mode */
+
+#define FB_SYNC_HOR_HIGH_ACT	1	/* horizontal sync high active	*/
+#define FB_SYNC_VERT_HIGH_ACT	2	/* vertical sync high active	*/
+#define FB_SYNC_EXT		4	/* external sync		*/
+#define FB_SYNC_COMP_HIGH_ACT	8	/* composite sync high active   */
+#define FB_SYNC_BROADCAST	16	/* broadcast video timings      */
+					/* vtotal = 144d/288n/576i => PAL  */
+					/* vtotal = 121d/242n/484i => NTSC */
+#define FB_SYNC_ON_GREEN	32	/* sync on green */
+
+#define FB_VMODE_NONINTERLACED  0	/* non interlaced */
+#define FB_VMODE_INTERLACED	1	/* interlaced	*/
+#define FB_VMODE_DOUBLE		2	/* double scan */
+#define FB_VMODE_MASK		255
+
+#define FB_VMODE_YWRAP		256	/* ywrap instead of panning     */
+#define FB_VMODE_SMOOTH_XPAN	512	/* smooth xpan possible (internally used) */
+#define FB_VMODE_CONUPDATE	512	/* don't update x/yoffset	*/
+
+/*
+ * Display rotation support
+ */
+#define FB_ROTATE_UR      0
+#define FB_ROTATE_CW      1
+#define FB_ROTATE_UD      2
+#define FB_ROTATE_CCW     3
+
+#define PICOS2KHZ(a) (1000000000UL/(a))
+#define KHZ2PICOS(a) (1000000000UL/(a))
+
+struct fb_var_screeninfo {
+	__u32 xres;			/* visible resolution		*/
+	__u32 yres;
+	__u32 xres_virtual;		/* virtual resolution		*/
+	__u32 yres_virtual;
+	__u32 xoffset;			/* offset from virtual to visible */
+	__u32 yoffset;			/* resolution			*/
+
+	__u32 bits_per_pixel;		/* guess what			*/
+	__u32 grayscale;		/* != 0 Graylevels instead of colors */
+
+	struct fb_bitfield red;		/* bitfield in fb mem if true color, */
+	struct fb_bitfield green;	/* else only length is significant */
+	struct fb_bitfield blue;
+	struct fb_bitfield transp;	/* transparency			*/	
+
+	__u32 nonstd;			/* != 0 Non standard pixel format */
+
+	__u32 activate;			/* see FB_ACTIVATE_*		*/
+
+	__u32 height;			/* height of picture in mm    */
+	__u32 width;			/* width of picture in mm     */
+
+	__u32 accel_flags;		/* (OBSOLETE) see fb_info.flags */
+
+	/* Timing: All values in pixclocks, except pixclock (of course) */
+	__u32 pixclock;			/* pixel clock in ps (pico seconds) */
+	__u32 left_margin;		/* time from sync to picture	*/
+	__u32 right_margin;		/* time from picture to sync	*/
+	__u32 upper_margin;		/* time from sync to picture	*/
+	__u32 lower_margin;
+	__u32 hsync_len;		/* length of horizontal sync	*/
+	__u32 vsync_len;		/* length of vertical sync	*/
+	__u32 sync;			/* see FB_SYNC_*		*/
+	__u32 vmode;			/* see FB_VMODE_*		*/
+	__u32 rotate;			/* angle we rotate counter clockwise */
+	__u32 reserved[5];		/* Reserved for future compatibility */
+};
+
+struct fb_cmap {
+	__u32 start;			/* First entry	*/
+	__u32 len;			/* Number of entries */
+	__u16 *red;			/* Red values	*/
+	__u16 *green;
+	__u16 *blue;
+	__u16 *transp;			/* transparency, can be NULL */
+};
+
+struct fb_con2fbmap {
+	__u32 console;
+	__u32 framebuffer;
+};
+
+/* VESA Blanking Levels */
+#define VESA_NO_BLANKING        0
+#define VESA_VSYNC_SUSPEND      1
+#define VESA_HSYNC_SUSPEND      2
+#define VESA_POWERDOWN          3
+
+
+enum {
+	/* screen: unblanked, hsync: on,  vsync: on */
+	FB_BLANK_UNBLANK       = VESA_NO_BLANKING,
+
+	/* screen: blanked,   hsync: on,  vsync: on */
+	FB_BLANK_NORMAL        = VESA_NO_BLANKING + 1,
+
+	/* screen: blanked,   hsync: on,  vsync: off */
+	FB_BLANK_VSYNC_SUSPEND = VESA_VSYNC_SUSPEND + 1,
+
+	/* screen: blanked,   hsync: off, vsync: on */
+	FB_BLANK_HSYNC_SUSPEND = VESA_HSYNC_SUSPEND + 1,
+
+	/* screen: blanked,   hsync: off, vsync: off */
+	FB_BLANK_POWERDOWN     = VESA_POWERDOWN + 1
+};
+
+#define FB_VBLANK_VBLANKING	0x001	/* currently in a vertical blank */
+#define FB_VBLANK_HBLANKING	0x002	/* currently in a horizontal blank */
+#define FB_VBLANK_HAVE_VBLANK	0x004	/* vertical blanks can be detected */
+#define FB_VBLANK_HAVE_HBLANK	0x008	/* horizontal blanks can be detected */
+#define FB_VBLANK_HAVE_COUNT	0x010	/* global retrace counter is available */
+#define FB_VBLANK_HAVE_VCOUNT	0x020	/* the vcount field is valid */
+#define FB_VBLANK_HAVE_HCOUNT	0x040	/* the hcount field is valid */
+#define FB_VBLANK_VSYNCING	0x080	/* currently in a vsync */
+#define FB_VBLANK_HAVE_VSYNC	0x100	/* verical syncs can be detected */
+
+struct fb_vblank {
+	__u32 flags;			/* FB_VBLANK flags */
+	__u32 count;			/* counter of retraces since boot */
+	__u32 vcount;			/* current scanline position */
+	__u32 hcount;			/* current scandot position */
+	__u32 reserved[4];		/* reserved for future compatibility */
+};
+
+/* Internal HW accel */
+#define ROP_COPY 0
+#define ROP_XOR  1
+
+struct fb_copyarea {
+	__u32 dx;
+	__u32 dy;
+	__u32 width;
+	__u32 height;
+	__u32 sx;
+	__u32 sy;
+};
+
+struct fb_fillrect {
+	__u32 dx;	/* screen-relative */
+	__u32 dy;
+	__u32 width;
+	__u32 height;
+	__u32 color;
+	__u32 rop;
+};
+
+struct fb_image {
+	__u32 dx;		/* Where to place image */
+	__u32 dy;
+	__u32 width;		/* Size of image */
+	__u32 height;
+	__u32 fg_color;		/* Only used when a mono bitmap */
+	__u32 bg_color;
+	__u8  depth;		/* Depth of the image */
+	const char *data;	/* Pointer to image data */
+	struct fb_cmap cmap;	/* color map info */
+};
+
+/*
+ * hardware cursor control
+ */
+
+#define FB_CUR_SETIMAGE 0x01
+#define FB_CUR_SETPOS   0x02
+#define FB_CUR_SETHOT   0x04
+#define FB_CUR_SETCMAP  0x08
+#define FB_CUR_SETSHAPE 0x10
+#define FB_CUR_SETSIZE	0x20
+#define FB_CUR_SETALL   0xFF
+
+struct fbcurpos {
+	__u16 x, y;
+};
+
+struct fb_cursor {
+	__u16 set;		/* what to set */
+	__u16 enable;		/* cursor on/off */
+	__u16 rop;		/* bitop operation */
+	const char *mask;	/* cursor mask bits */
+	struct fbcurpos hot;	/* cursor hot spot */
+	struct fb_image	image;	/* Cursor image */
+};
+
+#ifdef __KERNEL__
+
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/device.h>
+#include <linux/workqueue.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/notifier.h>
+#include <linux/list.h>
+#include <asm/io.h>
+
+struct vm_area_struct;
+struct fb_info;
+struct device;
+struct file;
+
+/* Definitions below are used in the parsed monitor specs */
+#define FB_DPMS_ACTIVE_OFF	1
+#define FB_DPMS_SUSPEND		2
+#define FB_DPMS_STANDBY		4
+
+#define FB_DISP_DDI		1
+#define FB_DISP_ANA_700_300	2
+#define FB_DISP_ANA_714_286	4
+#define FB_DISP_ANA_1000_400	8
+#define FB_DISP_ANA_700_000	16
+
+#define FB_DISP_MONO		32
+#define FB_DISP_RGB		64
+#define FB_DISP_MULTI		128
+#define FB_DISP_UNKNOWN		256
+
+#define FB_SIGNAL_NONE		0
+#define FB_SIGNAL_BLANK_BLANK	1
+#define FB_SIGNAL_SEPARATE	2
+#define FB_SIGNAL_COMPOSITE	4
+#define FB_SIGNAL_SYNC_ON_GREEN	8
+#define FB_SIGNAL_SERRATION_ON	16
+
+#define FB_MISC_PRIM_COLOR	1
+#define FB_MISC_1ST_DETAIL	2	/* First Detailed Timing is preferred */
+struct fb_chroma {
+	__u32 redx;	/* in fraction of 1024 */
+	__u32 greenx;
+	__u32 bluex;
+	__u32 whitex;
+	__u32 redy;
+	__u32 greeny;
+	__u32 bluey;
+	__u32 whitey;
+};
+
+struct fb_monspecs {
+	struct fb_chroma chroma;
+	struct fb_videomode *modedb;	/* mode database */
+	__u8  manufacturer[4];		/* Manufacturer */
+	__u8  monitor[14];		/* Monitor String */
+	__u8  serial_no[14];		/* Serial Number */
+	__u8  ascii[14];		/* ? */
+	__u32 modedb_len;		/* mode database length */
+	__u32 model;			/* Monitor Model */
+	__u32 serial;			/* Serial Number - Integer */
+	__u32 year;			/* Year manufactured */
+	__u32 week;			/* Week Manufactured */
+	__u32 hfmin;			/* hfreq lower limit (Hz) */
+	__u32 hfmax;			/* hfreq upper limit (Hz) */
+	__u32 dclkmin;			/* pixelclock lower limit (Hz) */
+	__u32 dclkmax;			/* pixelclock upper limit (Hz) */
+	__u16 input;			/* display type - see FB_DISP_* */
+	__u16 dpms;			/* DPMS support - see FB_DPMS_ */
+	__u16 signal;			/* Signal Type - see FB_SIGNAL_* */
+	__u16 vfmin;			/* vfreq lower limit (Hz) */
+	__u16 vfmax;			/* vfreq upper limit (Hz) */
+	__u16 gamma;			/* Gamma - in fractions of 100 */
+	__u16 gtf	: 1;		/* supports GTF */
+	__u16 misc;			/* Misc flags - see FB_MISC_* */
+	__u8  version;			/* EDID version... */
+	__u8  revision;			/* ...and revision */
+	__u8  max_x;			/* Maximum horizontal size (cm) */
+	__u8  max_y;			/* Maximum vertical size (cm) */
+};
+
+struct fb_cmap_user {
+	__u32 start;			/* First entry	*/
+	__u32 len;			/* Number of entries */
+	__u16 __user *red;		/* Red values	*/
+	__u16 __user *green;
+	__u16 __user *blue;
+	__u16 __user *transp;		/* transparency, can be NULL */
+};
+
+struct fb_image_user {
+	__u32 dx;			/* Where to place image */
+	__u32 dy;
+	__u32 width;			/* Size of image */
+	__u32 height;
+	__u32 fg_color;			/* Only used when a mono bitmap */
+	__u32 bg_color;
+	__u8  depth;			/* Depth of the image */
+	const char __user *data;	/* Pointer to image data */
+	struct fb_cmap_user cmap;	/* color map info */
+};
+
+struct fb_cursor_user {
+	__u16 set;			/* what to set */
+	__u16 enable;			/* cursor on/off */
+	__u16 rop;			/* bitop operation */
+	const char __user *mask;	/* cursor mask bits */
+	struct fbcurpos hot;		/* cursor hot spot */
+	struct fb_image_user image;	/* Cursor image */
+};
+
+/*
+ * Register/unregister for framebuffer events
+ */
+
+/*	The resolution of the passed in fb_info about to change */ 
+#define FB_EVENT_MODE_CHANGE		0x01
+/*	The display on this fb_info is beeing suspended, no access to the
+ *	framebuffer is allowed any more after that call returns
+ */
+#define FB_EVENT_SUSPEND		0x02
+/*	The display on this fb_info was resumed, you can restore the display
+ *	if you own it
+ */
+#define FB_EVENT_RESUME			0x03
+/*      An entry from the modelist was removed */
+#define FB_EVENT_MODE_DELETE            0x04
+/*      A driver registered itself */
+#define FB_EVENT_FB_REGISTERED          0x05
+/*      CONSOLE-SPECIFIC: get console to framebuffer mapping */
+#define FB_EVENT_GET_CONSOLE_MAP        0x06
+/*      CONSOLE-SPECIFIC: set console to framebuffer mapping */
+#define FB_EVENT_SET_CONSOLE_MAP        0x07
+/*      A display blank is requested       */
+#define FB_EVENT_BLANK                  0x08
+/*      Private modelist is to be replaced */
+#define FB_EVENT_NEW_MODELIST           0x09
+/*	The resolution of the passed in fb_info about to change and
+        all vc's should be changed         */
+#define FB_EVENT_MODE_CHANGE_ALL	0x0A
+/*      CONSOLE-SPECIFIC: set console rotation */
+#define FB_EVENT_SET_CON_ROTATE         0x0B
+/*      CONSOLE-SPECIFIC: get console rotation */
+#define FB_EVENT_GET_CON_ROTATE         0x0C
+/*      CONSOLE-SPECIFIC: rotate all consoles */
+#define FB_EVENT_SET_CON_ROTATE_ALL     0x0D
+
+struct fb_event {
+	struct fb_info *info;
+	void *data;
+};
+
+
+extern int fb_register_client(struct notifier_block *nb);
+extern int fb_unregister_client(struct notifier_block *nb);
+
+/*
+ * Pixmap structure definition
+ *
+ * The purpose of this structure is to translate data
+ * from the hardware independent format of fbdev to what
+ * format the hardware needs.
+ */
+
+#define FB_PIXMAP_DEFAULT 1     /* used internally by fbcon */
+#define FB_PIXMAP_SYSTEM  2     /* memory is in system RAM  */
+#define FB_PIXMAP_IO      4     /* memory is iomapped       */
+#define FB_PIXMAP_SYNC    256   /* set if GPU can DMA       */
+
+struct fb_pixmap {
+	u8  *addr;		/* pointer to memory			*/
+	u32 size;		/* size of buffer in bytes		*/
+	u32 offset;		/* current offset to buffer		*/
+	u32 buf_align;		/* byte alignment of each bitmap	*/
+	u32 scan_align;		/* alignment per scanline		*/
+	u32 access_align;	/* alignment per read/write (bits)	*/
+	u32 flags;		/* see FB_PIXMAP_*			*/
+	/* access methods */
+	void (*writeio)(struct fb_info *info, void __iomem *dst, void *src, unsigned int size);
+	void (*readio) (struct fb_info *info, void *dst, void __iomem *src, unsigned int size);
+};
+
+
+/*
+ * Frame buffer operations
+ *
+ * LOCKING NOTE: those functions must _ALL_ be called with the console
+ * semaphore held, this is the only suitable locking mecanism we have
+ * in 2.6. Some may be called at interrupt time at this point though.
+ */
+
+struct fb_ops {
+	/* open/release and usage marking */
+	struct module *owner;
+	int (*fb_open)(struct fb_info *info, int user);
+	int (*fb_release)(struct fb_info *info, int user);
+
+	/* For framebuffers with strange non linear layouts or that do not
+	 * work with normal memory mapped access
+	 */
+	ssize_t (*fb_read)(struct file *file, char __user *buf, size_t count, loff_t *ppos);
+	ssize_t (*fb_write)(struct file *file, const char __user *buf, size_t count, loff_t *ppos);
+
+	/* checks var and eventually tweaks it to something supported,
+	 * DO NOT MODIFY PAR */
+	int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);
+
+	/* set the video mode according to info->var */
+	int (*fb_set_par)(struct fb_info *info);
+
+	/* set color register */
+	int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
+			    unsigned blue, unsigned transp, struct fb_info *info);
+
+	/* set color registers in batch */
+	int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);
+
+	/* blank display */
+	int (*fb_blank)(int blank, struct fb_info *info);
+
+	/* pan display */
+	int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);
+
+	/* Draws a rectangle */
+	void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
+	/* Copy data from area to another */
+	void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
+	/* Draws a image to the display */
+	void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);
+
+	/* Draws cursor */
+	int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);
+
+	/* Rotates the display */
+	void (*fb_rotate)(struct fb_info *info, int angle);
+
+	/* wait for blit idle, optional */
+	int (*fb_sync)(struct fb_info *info);
+
+	/* perform fb specific ioctl (optional) */
+	int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd,
+			unsigned long arg, struct fb_info *info);
+
+	/* Handle 32bit compat ioctl (optional) */
+	long (*fb_compat_ioctl)(struct file *f, unsigned cmd, unsigned long arg,
+			       struct fb_info *info);
+
+	/* perform fb specific mmap */
+	int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
+
+	/* save current hardware state */
+	void (*fb_save_state)(struct fb_info *info);
+
+	/* restore saved state */
+	void (*fb_restore_state)(struct fb_info *info);
+};
+
+#ifdef CONFIG_FB_TILEBLITTING
+
+#define FB_TILE_CURSOR_NONE        0
+#define FB_TILE_CURSOR_UNDERLINE   1
+#define FB_TILE_CURSOR_LOWER_THIRD 2
+#define FB_TILE_CURSOR_LOWER_HALF  3
+#define FB_TILE_CURSOR_TWO_THIRDS  4
+#define FB_TILE_CURSOR_BLOCK       5
+
+struct fb_tilemap {
+	__u32 width;                /* width of each tile in pixels */
+	__u32 height;               /* height of each tile in scanlines */
+	__u32 depth;                /* color depth of each tile */
+	__u32 length;               /* number of tiles in the map */
+	const __u8 *data;           /* actual tile map: a bitmap array, packed
+				       to the nearest byte */
+};
+
+struct fb_tilerect {
+	__u32 sx;                   /* origin in the x-axis */
+	__u32 sy;                   /* origin in the y-axis */
+	__u32 width;                /* number of tiles in the x-axis */
+	__u32 height;               /* number of tiles in the y-axis */
+	__u32 index;                /* what tile to use: index to tile map */
+	__u32 fg;                   /* foreground color */
+	__u32 bg;                   /* background color */
+	__u32 rop;                  /* raster operation */
+};
+
+struct fb_tilearea {
+	__u32 sx;                   /* source origin in the x-axis */
+	__u32 sy;                   /* source origin in the y-axis */
+	__u32 dx;                   /* destination origin in the x-axis */
+	__u32 dy;                   /* destination origin in the y-axis */
+	__u32 width;                /* number of tiles in the x-axis */
+	__u32 height;               /* number of tiles in the y-axis */
+};
+
+struct fb_tileblit {
+	__u32 sx;                   /* origin in the x-axis */
+	__u32 sy;                   /* origin in the y-axis */
+	__u32 width;                /* number of tiles in the x-axis */
+	__u32 height;               /* number of tiles in the y-axis */
+	__u32 fg;                   /* foreground color */
+	__u32 bg;                   /* background color */
+	__u32 length;               /* number of tiles to draw */
+	__u32 *indices;             /* array of indices to tile map */
+};
+
+struct fb_tilecursor {
+	__u32 sx;                   /* cursor position in the x-axis */
+	__u32 sy;                   /* cursor position in the y-axis */
+	__u32 mode;                 /* 0 = erase, 1 = draw */
+	__u32 shape;                /* see FB_TILE_CURSOR_* */
+	__u32 fg;                   /* foreground color */
+	__u32 bg;                   /* background color */
+};
+
+struct fb_tile_ops {
+	/* set tile characteristics */
+	void (*fb_settile)(struct fb_info *info, struct fb_tilemap *map);
+
+	/* all dimensions from hereon are in terms of tiles */
+
+	/* move a rectangular region of tiles from one area to another*/
+	void (*fb_tilecopy)(struct fb_info *info, struct fb_tilearea *area);
+	/* fill a rectangular region with a tile */
+	void (*fb_tilefill)(struct fb_info *info, struct fb_tilerect *rect);
+	/* copy an array of tiles */
+	void (*fb_tileblit)(struct fb_info *info, struct fb_tileblit *blit);
+	/* cursor */
+	void (*fb_tilecursor)(struct fb_info *info,
+			      struct fb_tilecursor *cursor);
+};
+#endif /* CONFIG_FB_TILEBLITTING */
+
+/* FBINFO_* = fb_info.flags bit flags */
+#define FBINFO_MODULE		0x0001	/* Low-level driver is a module */
+#define FBINFO_HWACCEL_DISABLED	0x0002
+	/* When FBINFO_HWACCEL_DISABLED is set:
+	 *  Hardware acceleration is turned off.  Software implementations
+	 *  of required functions (copyarea(), fillrect(), and imageblit())
+	 *  takes over; acceleration engine should be in a quiescent state */
+
+/* hints */
+#define FBINFO_PARTIAL_PAN_OK	0x0040 /* otw use pan only for double-buffering */
+#define FBINFO_READS_FAST	0x0080 /* soft-copy faster than rendering */
+
+/* hardware supported ops */
+/*  semantics: when a bit is set, it indicates that the operation is
+ *   accelerated by hardware.
+ *  required functions will still work even if the bit is not set.
+ *  optional functions may not even exist if the flag bit is not set.
+ */
+#define FBINFO_HWACCEL_NONE		0x0000
+#define FBINFO_HWACCEL_COPYAREA		0x0100 /* required */
+#define FBINFO_HWACCEL_FILLRECT		0x0200 /* required */
+#define FBINFO_HWACCEL_IMAGEBLIT	0x0400 /* required */
+#define FBINFO_HWACCEL_ROTATE		0x0800 /* optional */
+#define FBINFO_HWACCEL_XPAN		0x1000 /* optional */
+#define FBINFO_HWACCEL_YPAN		0x2000 /* optional */
+#define FBINFO_HWACCEL_YWRAP		0x4000 /* optional */
+
+#define FBINFO_MISC_USEREVENT          0x10000 /* event request
+						  from userspace */
+#define FBINFO_MISC_TILEBLITTING       0x20000 /* use tile blitting */
+
+/* A driver may set this flag to indicate that it does want a set_par to be
+ * called every time when fbcon_switch is executed. The advantage is that with
+ * this flag set you can really be shure that set_par is always called before
+ * any of the functions dependant on the correct hardware state or altering
+ * that state, even if you are using some broken X releases. The disadvantage
+ * is that it introduces unwanted delays to every console switch if set_par
+ * is slow. It is a good idea to try this flag in the drivers initialization
+ * code whenever there is a bug report related to switching between X and the
+ * framebuffer console.
+ */
+#define FBINFO_MISC_ALWAYS_SETPAR   0x40000
+
+struct fb_info {
+	int node;
+	int flags;
+	struct fb_var_screeninfo var;	/* Current var */
+	struct fb_fix_screeninfo fix;	/* Current fix */
+	struct fb_monspecs monspecs;	/* Current Monitor specs */
+	struct work_struct queue;	/* Framebuffer event queue */
+	struct fb_pixmap pixmap;	/* Image hardware mapper */
+	struct fb_pixmap sprite;	/* Cursor hardware mapper */
+	struct fb_cmap cmap;		/* Current cmap */
+	struct list_head modelist;      /* mode list */
+	struct fb_videomode *mode;	/* current mode */
+	struct fb_ops *fbops;
+	struct device *device;
+	struct class_device *class_device; /* sysfs per device attrs */
+#ifdef CONFIG_FB_TILEBLITTING
+	struct fb_tile_ops *tileops;    /* Tile Blitting */
+#endif
+	char __iomem *screen_base;	/* Virtual address */
+	unsigned long screen_size;	/* Amount of ioremapped VRAM or 0 */ 
+	void *pseudo_palette;		/* Fake palette of 16 colors */ 
+#define FBINFO_STATE_RUNNING	0
+#define FBINFO_STATE_SUSPENDED	1
+	u32 state;			/* Hardware state i.e suspend */
+	void *fbcon_par;                /* fbcon use-only private area */
+	/* From here on everything is device dependent */
+	void *par;	
+};
+
+#ifdef MODULE
+#define FBINFO_DEFAULT	FBINFO_MODULE
+#else
+#define FBINFO_DEFAULT	0
+#endif
+
+// This will go away
+#define FBINFO_FLAG_MODULE	FBINFO_MODULE
+#define FBINFO_FLAG_DEFAULT	FBINFO_DEFAULT
+
+/* This will go away
+ * fbset currently hacks in FB_ACCELF_TEXT into var.accel_flags
+ * when it wants to turn the acceleration engine on.  This is
+ * really a separate operation, and should be modified via sysfs.
+ *  But for now, we leave it broken with the following define
+ */
+#define STUPID_ACCELF_TEXT_SHIT
+
+// This will go away
+#if defined(__sparc__)
+
+/* We map all of our framebuffers such that big-endian accesses
+ * are what we want, so the following is sufficient.
+ */
+
+// This will go away
+#define fb_readb sbus_readb
+#define fb_readw sbus_readw
+#define fb_readl sbus_readl
+#define fb_readq sbus_readq
+#define fb_writeb sbus_writeb
+#define fb_writew sbus_writew
+#define fb_writel sbus_writel
+#define fb_writeq sbus_writeq
+#define fb_memset sbus_memset_io
+
+#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || (defined(__sh__) && !defined(__SH5__)) || defined(__powerpc__)
+
+#define fb_readb __raw_readb
+#define fb_readw __raw_readw
+#define fb_readl __raw_readl
+#define fb_readq __raw_readq
+#define fb_writeb __raw_writeb
+#define fb_writew __raw_writew
+#define fb_writel __raw_writel
+#define fb_writeq __raw_writeq
+#define fb_memset memset_io
+
+#else
+
+#define fb_readb(addr) (*(volatile u8 *) (addr))
+#define fb_readw(addr) (*(volatile u16 *) (addr))
+#define fb_readl(addr) (*(volatile u32 *) (addr))
+#define fb_readq(addr) (*(volatile u64 *) (addr))
+#define fb_writeb(b,addr) (*(volatile u8 *) (addr) = (b))
+#define fb_writew(b,addr) (*(volatile u16 *) (addr) = (b))
+#define fb_writel(b,addr) (*(volatile u32 *) (addr) = (b))
+#define fb_writeq(b,addr) (*(volatile u64 *) (addr) = (b))
+#define fb_memset memset
+
+#endif
+
+#if defined (__BIG_ENDIAN)
+#define FB_LEFT_POS(bpp)          (32 - bpp)
+#define FB_SHIFT_HIGH(val, bits)  ((val) >> (bits))
+#define FB_SHIFT_LOW(val, bits)   ((val) << (bits))
+#define FB_BIT_NR(b)              (7 - (b))
+#else
+#define FB_LEFT_POS(bpp)          (0)
+#define FB_SHIFT_HIGH(val, bits)  ((val) << (bits))
+#define FB_SHIFT_LOW(val, bits)   ((val) >> (bits))
+#define FB_BIT_NR(b)              (b)
+#endif
+
+    /*
+     *  `Generic' versions of the frame buffer device operations
+     */
+
+extern int fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var); 
+extern int fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var); 
+extern int fb_blank(struct fb_info *info, int blank);
+extern void cfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect); 
+extern void cfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); 
+extern void cfb_imageblit(struct fb_info *info, const struct fb_image *image);
+
+/* drivers/video/fbmem.c */
+extern int register_framebuffer(struct fb_info *fb_info);
+extern int unregister_framebuffer(struct fb_info *fb_info);
+extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);
+extern int fb_show_logo(struct fb_info *fb_info, int rotate);
+extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
+extern void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx,
+				u32 height, u32 shift_high, u32 shift_low, u32 mod);
+extern void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height);
+extern void fb_set_suspend(struct fb_info *info, int state);
+extern int fb_get_color_depth(struct fb_var_screeninfo *var,
+			      struct fb_fix_screeninfo *fix);
+extern int fb_get_options(char *name, char **option);
+extern int fb_new_modelist(struct fb_info *info);
+extern int fb_con_duit(struct fb_info *info, int event, void *data);
+
+extern struct fb_info *registered_fb[FB_MAX];
+extern int num_registered_fb;
+
+static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch,
+					   u8 *src, u32 s_pitch, u32 height)
+{
+	int i, j;
+
+	d_pitch -= s_pitch;
+
+	for (i = height; i--; ) {
+		/* s_pitch is a few bytes at the most, memcpy is suboptimal */
+		for (j = 0; j < s_pitch; j++)
+			*dst++ = *src++;
+		dst += d_pitch;
+	}
+}
+
+/* drivers/video/fbsysfs.c */
+extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev);
+extern void framebuffer_release(struct fb_info *info);
+extern int fb_init_class_device(struct fb_info *fb_info);
+extern void fb_cleanup_class_device(struct fb_info *head);
+
+/* drivers/video/fbmon.c */
+#define FB_MAXTIMINGS		0
+#define FB_VSYNCTIMINGS		1
+#define FB_HSYNCTIMINGS		2
+#define FB_DCLKTIMINGS		3
+#define FB_IGNOREMON		0x100
+
+#define FB_MODE_IS_UNKNOWN	0
+#define FB_MODE_IS_DETAILED	1
+#define FB_MODE_IS_STANDARD	2
+#define FB_MODE_IS_VESA		4
+#define FB_MODE_IS_CALCULATED	8
+#define FB_MODE_IS_FIRST	16
+#define FB_MODE_IS_FROM_VAR     32
+
+extern int fbmon_valid_timings(u_int pixclock, u_int htotal, u_int vtotal,
+			       const struct fb_info *fb_info);
+extern int fbmon_dpms(const struct fb_info *fb_info);
+extern int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var,
+		       struct fb_info *info);
+extern int fb_validate_mode(const struct fb_var_screeninfo *var,
+			    struct fb_info *info);
+extern int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var);
+extern const unsigned char *fb_firmware_edid(struct device *device);
+extern void fb_edid_to_monspecs(unsigned char *edid,
+				struct fb_monspecs *specs);
+extern void fb_destroy_modedb(struct fb_videomode *modedb);
+extern int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb);
+
+/* drivers/video/modedb.c */
+#define VESA_MODEDB_SIZE 34
+extern void fb_var_to_videomode(struct fb_videomode *mode,
+				struct fb_var_screeninfo *var);
+extern void fb_videomode_to_var(struct fb_var_screeninfo *var,
+				struct fb_videomode *mode);
+extern int fb_mode_is_equal(struct fb_videomode *mode1,
+			    struct fb_videomode *mode2);
+extern int fb_add_videomode(struct fb_videomode *mode, struct list_head *head);
+extern void fb_delete_videomode(struct fb_videomode *mode,
+				struct list_head *head);
+extern struct fb_videomode *fb_match_mode(struct fb_var_screeninfo *var,
+					  struct list_head *head);
+extern struct fb_videomode *fb_find_best_mode(struct fb_var_screeninfo *var,
+					      struct list_head *head);
+extern struct fb_videomode *fb_find_nearest_mode(struct fb_videomode *mode,
+						 struct list_head *head);
+extern void fb_destroy_modelist(struct list_head *head);
+extern void fb_videomode_to_modelist(struct fb_videomode *modedb, int num,
+				     struct list_head *head);
+extern struct fb_videomode *fb_find_best_display(struct fb_monspecs *specs,
+						 struct list_head *head);
+
+/* drivers/video/fbcmap.c */
+extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);
+extern void fb_dealloc_cmap(struct fb_cmap *cmap);
+extern int fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to);
+extern int fb_cmap_to_user(struct fb_cmap *from, struct fb_cmap_user *to);
+extern int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *fb_info);
+extern int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *fb_info);
+extern struct fb_cmap *fb_default_cmap(int len);
+extern void fb_invert_cmaps(void);
+
+struct fb_videomode {
+	const char *name;	/* optional */
+	u32 refresh;		/* optional */
+	u32 xres;
+	u32 yres;
+	u32 pixclock;
+	u32 left_margin;
+	u32 right_margin;
+	u32 upper_margin;
+	u32 lower_margin;
+	u32 hsync_len;
+	u32 vsync_len;
+	u32 sync;
+	u32 vmode;
+	u32 flag;
+};
+
+extern const struct fb_videomode vesa_modes[];
+
+struct fb_modelist {
+	struct list_head list;
+	struct fb_videomode mode;
+};
+
+extern int fb_find_mode(struct fb_var_screeninfo *var,
+			struct fb_info *info, const char *mode_option,
+			const struct fb_videomode *db,
+			unsigned int dbsize,
+			const struct fb_videomode *default_mode,
+			unsigned int default_bpp);
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_FB_H */
diff -urN oldtree/include/linux/sysctl.h newtree/include/linux/sysctl.h
--- oldtree/include/linux/sysctl.h	2006-01-03 03:21:10.000000000 +0000
+++ newtree/include/linux/sysctl.h	2006-02-03 18:18:17.100730560 +0000
@@ -146,6 +146,7 @@
 	KERN_RANDOMIZE=68, /* int: randomize virtual address space */
 	KERN_SETUID_DUMPABLE=69, /* int: behaviour of dumps for setuid core */
 	KERN_SPIN_RETRY=70,	/* int: number of spinlock retries */
+	KERN_FBSPLASH=71,	/* string: path to fbsplash helper */
 };
 
 
diff -urN oldtree/include/linux/sysctl.h.orig newtree/include/linux/sysctl.h.orig
--- oldtree/include/linux/sysctl.h.orig	1970-01-01 00:00:00.000000000 +0000
+++ newtree/include/linux/sysctl.h.orig	2006-01-03 03:21:10.000000000 +0000
@@ -0,0 +1,983 @@
+/*
+ * sysctl.h: General linux system control interface
+ *
+ * Begun 24 March 1995, Stephen Tweedie
+ *
+ ****************************************************************
+ ****************************************************************
+ **
+ **  The values in this file are exported to user space via 
+ **  the sysctl() binary interface.  However this interface
+ **  is unstable and deprecated and will be removed in the future. 
+ **  For a stable interface use /proc/sys.
+ **
+ ****************************************************************
+ ****************************************************************
+ */
+
+#ifndef _LINUX_SYSCTL_H
+#define _LINUX_SYSCTL_H
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/compiler.h>
+
+struct file;
+struct completion;
+
+#define CTL_MAXNAME 10		/* how many path components do we allow in a
+				   call to sysctl?   In other words, what is
+				   the largest acceptable value for the nlen
+				   member of a struct __sysctl_args to have? */
+
+struct __sysctl_args {
+	int __user *name;
+	int nlen;
+	void __user *oldval;
+	size_t __user *oldlenp;
+	void __user *newval;
+	size_t newlen;
+	unsigned long __unused[4];
+};
+
+/* Define sysctl names first */
+
+/* Top-level names: */
+
+/* For internal pattern-matching use only: */
+#ifdef __KERNEL__
+#define CTL_ANY		-1	/* Matches any name */
+#define CTL_NONE	0
+#endif
+
+enum
+{
+	CTL_KERN=1,		/* General kernel info and control */
+	CTL_VM=2,		/* VM management */
+	CTL_NET=3,		/* Networking */
+	CTL_PROC=4,		/* Process info */
+	CTL_FS=5,		/* Filesystems */
+	CTL_DEBUG=6,		/* Debugging */
+	CTL_DEV=7,		/* Devices */
+	CTL_BUS=8,		/* Busses */
+	CTL_ABI=9,		/* Binary emulation */
+	CTL_CPU=10		/* CPU stuff (speed scaling, etc) */
+};
+
+/* CTL_BUS names: */
+enum
+{
+	CTL_BUS_ISA=1		/* ISA */
+};
+
+/* /proc/sys/fs/inotify/ */
+enum
+{
+	INOTIFY_MAX_USER_INSTANCES=1,	/* max instances per user */
+	INOTIFY_MAX_USER_WATCHES=2,	/* max watches per user */
+	INOTIFY_MAX_QUEUED_EVENTS=3	/* max queued events per instance */
+};
+
+/* CTL_KERN names: */
+enum
+{
+	KERN_OSTYPE=1,		/* string: system version */
+	KERN_OSRELEASE=2,	/* string: system release */
+	KERN_OSREV=3,		/* int: system revision */
+	KERN_VERSION=4,		/* string: compile time info */
+	KERN_SECUREMASK=5,	/* struct: maximum rights mask */
+	KERN_PROF=6,		/* table: profiling information */
+	KERN_NODENAME=7,
+	KERN_DOMAINNAME=8,
+
+	KERN_CAP_BSET=14,	/* int: capability bounding set */
+	KERN_PANIC=15,		/* int: panic timeout */
+	KERN_REALROOTDEV=16,	/* real root device to mount after initrd */
+
+	KERN_SPARC_REBOOT=21,	/* reboot command on Sparc */
+	KERN_CTLALTDEL=22,	/* int: allow ctl-alt-del to reboot */
+	KERN_PRINTK=23,		/* struct: control printk logging parameters */
+	KERN_NAMETRANS=24,	/* Name translation */
+	KERN_PPC_HTABRECLAIM=25, /* turn htab reclaimation on/off on PPC */
+	KERN_PPC_ZEROPAGED=26,	/* turn idle page zeroing on/off on PPC */
+	KERN_PPC_POWERSAVE_NAP=27, /* use nap mode for power saving */
+	KERN_MODPROBE=28,
+	KERN_SG_BIG_BUFF=29,
+	KERN_ACCT=30,		/* BSD process accounting parameters */
+	KERN_PPC_L2CR=31,	/* l2cr register on PPC */
+
+	KERN_RTSIGNR=32,	/* Number of rt sigs queued */
+	KERN_RTSIGMAX=33,	/* Max queuable */
+	
+	KERN_SHMMAX=34,         /* long: Maximum shared memory segment */
+	KERN_MSGMAX=35,         /* int: Maximum size of a messege */
+	KERN_MSGMNB=36,         /* int: Maximum message queue size */
+	KERN_MSGPOOL=37,        /* int: Maximum system message pool size */
+	KERN_SYSRQ=38,		/* int: Sysreq enable */
+	KERN_MAX_THREADS=39,	/* int: Maximum nr of threads in the system */
+ 	KERN_RANDOM=40,		/* Random driver */
+ 	KERN_SHMALL=41,		/* int: Maximum size of shared memory */
+ 	KERN_MSGMNI=42,		/* int: msg queue identifiers */
+ 	KERN_SEM=43,		/* struct: sysv semaphore limits */
+ 	KERN_SPARC_STOP_A=44,	/* int: Sparc Stop-A enable */
+ 	KERN_SHMMNI=45,		/* int: shm array identifiers */
+	KERN_OVERFLOWUID=46,	/* int: overflow UID */
+	KERN_OVERFLOWGID=47,	/* int: overflow GID */
+	KERN_SHMPATH=48,	/* string: path to shm fs */
+	KERN_HOTPLUG=49,	/* string: path to hotplug policy agent */
+	KERN_IEEE_EMULATION_WARNINGS=50, /* int: unimplemented ieee instructions */
+	KERN_S390_USER_DEBUG_LOGGING=51,  /* int: dumps of user faults */
+	KERN_CORE_USES_PID=52,		/* int: use core or core.%pid */
+	KERN_TAINTED=53,	/* int: various kernel tainted flags */
+	KERN_CADPID=54,		/* int: PID of the process to notify on CAD */
+	KERN_PIDMAX=55,		/* int: PID # limit */
+  	KERN_CORE_PATTERN=56,	/* string: pattern for core-file names */
+	KERN_PANIC_ON_OOPS=57,  /* int: whether we will panic on an oops */
+	KERN_HPPA_PWRSW=58,	/* int: hppa soft-power enable */
+	KERN_HPPA_UNALIGNED=59,	/* int: hppa unaligned-trap enable */
+	KERN_PRINTK_RATELIMIT=60, /* int: tune printk ratelimiting */
+	KERN_PRINTK_RATELIMIT_BURST=61,	/* int: tune printk ratelimiting */
+	KERN_PTY=62,		/* dir: pty driver */
+	KERN_NGROUPS_MAX=63,	/* int: NGROUPS_MAX */
+	KERN_SPARC_SCONS_PWROFF=64, /* int: serial console power-off halt */
+	KERN_HZ_TIMER=65,	/* int: hz timer on or off */
+	KERN_UNKNOWN_NMI_PANIC=66, /* int: unknown nmi panic flag */
+	KERN_BOOTLOADER_TYPE=67, /* int: boot loader type */
+	KERN_RANDOMIZE=68, /* int: randomize virtual address space */
+	KERN_SETUID_DUMPABLE=69, /* int: behaviour of dumps for setuid core */
+	KERN_SPIN_RETRY=70,	/* int: number of spinlock retries */
+};
+
+
+/* CTL_VM names: */
+enum
+{
+	VM_UNUSED1=1,		/* was: struct: Set vm swapping control */
+	VM_UNUSED2=2,		/* was; int: Linear or sqrt() swapout for hogs */
+	VM_UNUSED3=3,		/* was: struct: Set free page thresholds */
+	VM_UNUSED4=4,		/* Spare */
+	VM_OVERCOMMIT_MEMORY=5,	/* Turn off the virtual memory safety limit */
+	VM_UNUSED5=6,		/* was: struct: Set buffer memory thresholds */
+	VM_UNUSED7=7,		/* was: struct: Set cache memory thresholds */
+	VM_UNUSED8=8,		/* was: struct: Control kswapd behaviour */
+	VM_UNUSED9=9,		/* was: struct: Set page table cache parameters */
+	VM_PAGE_CLUSTER=10,	/* int: set number of pages to swap together */
+	VM_DIRTY_BACKGROUND=11,	/* dirty_background_ratio */
+	VM_DIRTY_RATIO=12,	/* dirty_ratio */
+	VM_DIRTY_WB_CS=13,	/* dirty_writeback_centisecs */
+	VM_DIRTY_EXPIRE_CS=14,	/* dirty_expire_centisecs */
+	VM_NR_PDFLUSH_THREADS=15, /* nr_pdflush_threads */
+	VM_OVERCOMMIT_RATIO=16, /* percent of RAM to allow overcommit in */
+	VM_PAGEBUF=17,		/* struct: Control pagebuf parameters */
+	VM_HUGETLB_PAGES=18,	/* int: Number of available Huge Pages */
+	VM_SWAPPINESS=19,	/* Tendency to steal mapped memory */
+	VM_LOWMEM_RESERVE_RATIO=20,/* reservation ratio for lower memory zones */
+	VM_MIN_FREE_KBYTES=21,	/* Minimum free kilobytes to maintain */
+	VM_MAX_MAP_COUNT=22,	/* int: Maximum number of mmaps/address-space */
+	VM_LAPTOP_MODE=23,	/* vm laptop mode */
+	VM_BLOCK_DUMP=24,	/* block dump mode */
+	VM_HUGETLB_GROUP=25,	/* permitted hugetlb group */
+	VM_VFS_CACHE_PRESSURE=26, /* dcache/icache reclaim pressure */
+	VM_LEGACY_VA_LAYOUT=27, /* legacy/compatibility virtual address space layout */
+	VM_SWAP_TOKEN_TIMEOUT=28, /* default time for token time out */
+};
+
+
+/* CTL_NET names: */
+enum
+{
+	NET_CORE=1,
+	NET_ETHER=2,
+	NET_802=3,
+	NET_UNIX=4,
+	NET_IPV4=5,
+	NET_IPX=6,
+	NET_ATALK=7,
+	NET_NETROM=8,
+	NET_AX25=9,
+	NET_BRIDGE=10,
+	NET_ROSE=11,
+	NET_IPV6=12,
+	NET_X25=13,
+	NET_TR=14,
+	NET_DECNET=15,
+	NET_ECONET=16,
+	NET_SCTP=17,
+	NET_LLC=18,
+	NET_NETFILTER=19,
+};
+
+/* /proc/sys/kernel/random */
+enum
+{
+	RANDOM_POOLSIZE=1,
+	RANDOM_ENTROPY_COUNT=2,
+	RANDOM_READ_THRESH=3,
+	RANDOM_WRITE_THRESH=4,
+	RANDOM_BOOT_ID=5,
+	RANDOM_UUID=6
+};
+
+/* /proc/sys/kernel/pty */
+enum
+{
+	PTY_MAX=1,
+	PTY_NR=2
+};
+
+/* /proc/sys/bus/isa */
+enum
+{
+	BUS_ISA_MEM_BASE=1,
+	BUS_ISA_PORT_BASE=2,
+	BUS_ISA_PORT_SHIFT=3
+};
+
+/* /proc/sys/net/core */
+enum
+{
+	NET_CORE_WMEM_MAX=1,
+	NET_CORE_RMEM_MAX=2,
+	NET_CORE_WMEM_DEFAULT=3,
+	NET_CORE_RMEM_DEFAULT=4,
+/* was	NET_CORE_DESTROY_DELAY */
+	NET_CORE_MAX_BACKLOG=6,
+	NET_CORE_FASTROUTE=7,
+	NET_CORE_MSG_COST=8,
+	NET_CORE_MSG_BURST=9,
+	NET_CORE_OPTMEM_MAX=10,
+	NET_CORE_HOT_LIST_LENGTH=11,
+	NET_CORE_DIVERT_VERSION=12,
+	NET_CORE_NO_CONG_THRESH=13,
+	NET_CORE_NO_CONG=14,
+	NET_CORE_LO_CONG=15,
+	NET_CORE_MOD_CONG=16,
+	NET_CORE_DEV_WEIGHT=17,
+	NET_CORE_SOMAXCONN=18,
+	NET_CORE_BUDGET=19,
+};
+
+/* /proc/sys/net/ethernet */
+
+/* /proc/sys/net/802 */
+
+/* /proc/sys/net/unix */
+
+enum
+{
+	NET_UNIX_DESTROY_DELAY=1,
+	NET_UNIX_DELETE_DELAY=2,
+	NET_UNIX_MAX_DGRAM_QLEN=3,
+};
+
+/* /proc/sys/net/netfilter */
+enum
+{
+	NET_NF_CONNTRACK_MAX=1,
+	NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT=2,
+	NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV=3,
+	NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED=4,
+	NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT=5,
+	NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT=6,
+	NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK=7,
+	NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT=8,
+	NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE=9,
+	NET_NF_CONNTRACK_UDP_TIMEOUT=10,
+	NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM=11,
+	NET_NF_CONNTRACK_ICMP_TIMEOUT=12,
+	NET_NF_CONNTRACK_GENERIC_TIMEOUT=13,
+	NET_NF_CONNTRACK_BUCKETS=14,
+	NET_NF_CONNTRACK_LOG_INVALID=15,
+	NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS=16,
+	NET_NF_CONNTRACK_TCP_LOOSE=17,
+	NET_NF_CONNTRACK_TCP_BE_LIBERAL=18,
+	NET_NF_CONNTRACK_TCP_MAX_RETRANS=19,
+	NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED=20,
+	NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT=21,
+	NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED=22,
+	NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED=23,
+	NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT=24,
+	NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD=25,
+	NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT=26,
+	NET_NF_CONNTRACK_COUNT=27,
+	NET_NF_CONNTRACK_ICMPV6_TIMEOUT=28,
+	NET_NF_CONNTRACK_FRAG6_TIMEOUT=29,
+	NET_NF_CONNTRACK_FRAG6_LOW_THRESH=30,
+	NET_NF_CONNTRACK_FRAG6_HIGH_THRESH=31,
+};
+
+/* /proc/sys/net/ipv4 */
+enum
+{
+	/* v2.0 compatibile variables */
+	NET_IPV4_FORWARD=8,
+	NET_IPV4_DYNADDR=9,
+
+	NET_IPV4_CONF=16,
+	NET_IPV4_NEIGH=17,
+	NET_IPV4_ROUTE=18,
+	NET_IPV4_FIB_HASH=19,
+	NET_IPV4_NETFILTER=20,
+
+	NET_IPV4_TCP_TIMESTAMPS=33,
+	NET_IPV4_TCP_WINDOW_SCALING=34,
+	NET_IPV4_TCP_SACK=35,
+	NET_IPV4_TCP_RETRANS_COLLAPSE=36,
+	NET_IPV4_DEFAULT_TTL=37,
+	NET_IPV4_AUTOCONFIG=38,
+	NET_IPV4_NO_PMTU_DISC=39,
+	NET_IPV4_TCP_SYN_RETRIES=40,
+	NET_IPV4_IPFRAG_HIGH_THRESH=41,
+	NET_IPV4_IPFRAG_LOW_THRESH=42,
+	NET_IPV4_IPFRAG_TIME=43,
+	NET_IPV4_TCP_MAX_KA_PROBES=44,
+	NET_IPV4_TCP_KEEPALIVE_TIME=45,
+	NET_IPV4_TCP_KEEPALIVE_PROBES=46,
+	NET_IPV4_TCP_RETRIES1=47,
+	NET_IPV4_TCP_RETRIES2=48,
+	NET_IPV4_TCP_FIN_TIMEOUT=49,
+	NET_IPV4_IP_MASQ_DEBUG=50,
+	NET_TCP_SYNCOOKIES=51,
+	NET_TCP_STDURG=52,
+	NET_TCP_RFC1337=53,
+	NET_TCP_SYN_TAILDROP=54,
+	NET_TCP_MAX_SYN_BACKLOG=55,
+	NET_IPV4_LOCAL_PORT_RANGE=56,
+	NET_IPV4_ICMP_ECHO_IGNORE_ALL=57,
+	NET_IPV4_ICMP_ECHO_IGNORE_BROADCASTS=58,
+	NET_IPV4_ICMP_SOURCEQUENCH_RATE=59,
+	NET_IPV4_ICMP_DESTUNREACH_RATE=60,
+	NET_IPV4_ICMP_TIMEEXCEED_RATE=61,
+	NET_IPV4_ICMP_PARAMPROB_RATE=62,
+	NET_IPV4_ICMP_ECHOREPLY_RATE=63,
+	NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES=64,
+	NET_IPV4_IGMP_MAX_MEMBERSHIPS=65,
+	NET_TCP_TW_RECYCLE=66,
+	NET_IPV4_ALWAYS_DEFRAG=67,
+	NET_IPV4_TCP_KEEPALIVE_INTVL=68,
+	NET_IPV4_INET_PEER_THRESHOLD=69,
+	NET_IPV4_INET_PEER_MINTTL=70,
+	NET_IPV4_INET_PEER_MAXTTL=71,
+	NET_IPV4_INET_PEER_GC_MINTIME=72,
+	NET_IPV4_INET_PEER_GC_MAXTIME=73,
+	NET_TCP_ORPHAN_RETRIES=74,
+	NET_TCP_ABORT_ON_OVERFLOW=75,
+	NET_TCP_SYNACK_RETRIES=76,
+	NET_TCP_MAX_ORPHANS=77,
+	NET_TCP_MAX_TW_BUCKETS=78,
+	NET_TCP_FACK=79,
+	NET_TCP_REORDERING=80,
+	NET_TCP_ECN=81,
+	NET_TCP_DSACK=82,
+	NET_TCP_MEM=83,
+	NET_TCP_WMEM=84,
+	NET_TCP_RMEM=85,
+	NET_TCP_APP_WIN=86,
+	NET_TCP_ADV_WIN_SCALE=87,
+	NET_IPV4_NONLOCAL_BIND=88,
+	NET_IPV4_ICMP_RATELIMIT=89,
+	NET_IPV4_ICMP_RATEMASK=90,
+	NET_TCP_TW_REUSE=91,
+	NET_TCP_FRTO=92,
+	NET_TCP_LOW_LATENCY=93,
+	NET_IPV4_IPFRAG_SECRET_INTERVAL=94,
+	NET_IPV4_IGMP_MAX_MSF=96,
+	NET_TCP_NO_METRICS_SAVE=97,
+	NET_TCP_DEFAULT_WIN_SCALE=105,
+	NET_TCP_MODERATE_RCVBUF=106,
+	NET_TCP_TSO_WIN_DIVISOR=107,
+	NET_TCP_BIC_BETA=108,
+	NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109,
+	NET_TCP_CONG_CONTROL=110,
+	NET_TCP_ABC=111,
+};
+
+enum {
+	NET_IPV4_ROUTE_FLUSH=1,
+	NET_IPV4_ROUTE_MIN_DELAY=2,
+	NET_IPV4_ROUTE_MAX_DELAY=3,
+	NET_IPV4_ROUTE_GC_THRESH=4,
+	NET_IPV4_ROUTE_MAX_SIZE=5,
+	NET_IPV4_ROUTE_GC_MIN_INTERVAL=6,
+	NET_IPV4_ROUTE_GC_TIMEOUT=7,
+	NET_IPV4_ROUTE_GC_INTERVAL=8,
+	NET_IPV4_ROUTE_REDIRECT_LOAD=9,
+	NET_IPV4_ROUTE_REDIRECT_NUMBER=10,
+	NET_IPV4_ROUTE_REDIRECT_SILENCE=11,
+	NET_IPV4_ROUTE_ERROR_COST=12,
+	NET_IPV4_ROUTE_ERROR_BURST=13,
+	NET_IPV4_ROUTE_GC_ELASTICITY=14,
+	NET_IPV4_ROUTE_MTU_EXPIRES=15,
+	NET_IPV4_ROUTE_MIN_PMTU=16,
+	NET_IPV4_ROUTE_MIN_ADVMSS=17,
+	NET_IPV4_ROUTE_SECRET_INTERVAL=18,
+	NET_IPV4_ROUTE_GC_MIN_INTERVAL_MS=19,
+};
+
+enum
+{
+	NET_PROTO_CONF_ALL=-2,
+	NET_PROTO_CONF_DEFAULT=-3
+
+	/* And device ifindices ... */
+};
+
+enum
+{
+	NET_IPV4_CONF_FORWARDING=1,
+	NET_IPV4_CONF_MC_FORWARDING=2,
+	NET_IPV4_CONF_PROXY_ARP=3,
+	NET_IPV4_CONF_ACCEPT_REDIRECTS=4,
+	NET_IPV4_CONF_SECURE_REDIRECTS=5,
+	NET_IPV4_CONF_SEND_REDIRECTS=6,
+	NET_IPV4_CONF_SHARED_MEDIA=7,
+	NET_IPV4_CONF_RP_FILTER=8,
+	NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE=9,
+	NET_IPV4_CONF_BOOTP_RELAY=10,
+	NET_IPV4_CONF_LOG_MARTIANS=11,
+	NET_IPV4_CONF_TAG=12,
+	NET_IPV4_CONF_ARPFILTER=13,
+	NET_IPV4_CONF_MEDIUM_ID=14,
+	NET_IPV4_CONF_NOXFRM=15,
+	NET_IPV4_CONF_NOPOLICY=16,
+	NET_IPV4_CONF_FORCE_IGMP_VERSION=17,
+	NET_IPV4_CONF_ARP_ANNOUNCE=18,
+	NET_IPV4_CONF_ARP_IGNORE=19,
+	NET_IPV4_CONF_PROMOTE_SECONDARIES=20,
+	__NET_IPV4_CONF_MAX
+};
+
+/* /proc/sys/net/ipv4/netfilter */
+enum
+{
+	NET_IPV4_NF_CONNTRACK_MAX=1,
+	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT=2,
+	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV=3,
+	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED=4,
+	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT=5,
+	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT=6,
+	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK=7,
+	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT=8,
+	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE=9,
+	NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT=10,
+	NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM=11,
+	NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT=12,
+	NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT=13,
+	NET_IPV4_NF_CONNTRACK_BUCKETS=14,
+	NET_IPV4_NF_CONNTRACK_LOG_INVALID=15,
+	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS=16,
+	NET_IPV4_NF_CONNTRACK_TCP_LOOSE=17,
+	NET_IPV4_NF_CONNTRACK_TCP_BE_LIBERAL=18,
+	NET_IPV4_NF_CONNTRACK_TCP_MAX_RETRANS=19,
+ 	NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED=20,
+ 	NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT=21,
+ 	NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED=22,
+ 	NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED=23,
+ 	NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT=24,
+ 	NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD=25,
+ 	NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT=26,
+	NET_IPV4_NF_CONNTRACK_COUNT=27,
+};
+ 
+/* /proc/sys/net/ipv6 */
+enum {
+	NET_IPV6_CONF=16,
+	NET_IPV6_NEIGH=17,
+	NET_IPV6_ROUTE=18,
+	NET_IPV6_ICMP=19,
+	NET_IPV6_BINDV6ONLY=20,
+	NET_IPV6_IP6FRAG_HIGH_THRESH=21,
+	NET_IPV6_IP6FRAG_LOW_THRESH=22,
+	NET_IPV6_IP6FRAG_TIME=23,
+	NET_IPV6_IP6FRAG_SECRET_INTERVAL=24,
+	NET_IPV6_MLD_MAX_MSF=25,
+};
+
+enum {
+	NET_IPV6_ROUTE_FLUSH=1,
+	NET_IPV6_ROUTE_GC_THRESH=2,
+	NET_IPV6_ROUTE_MAX_SIZE=3,
+	NET_IPV6_ROUTE_GC_MIN_INTERVAL=4,
+	NET_IPV6_ROUTE_GC_TIMEOUT=5,
+	NET_IPV6_ROUTE_GC_INTERVAL=6,
+	NET_IPV6_ROUTE_GC_ELASTICITY=7,
+	NET_IPV6_ROUTE_MTU_EXPIRES=8,
+	NET_IPV6_ROUTE_MIN_ADVMSS=9,
+	NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS=10
+};
+
+enum {
+	NET_IPV6_FORWARDING=1,
+	NET_IPV6_HOP_LIMIT=2,
+	NET_IPV6_MTU=3,
+	NET_IPV6_ACCEPT_RA=4,
+	NET_IPV6_ACCEPT_REDIRECTS=5,
+	NET_IPV6_AUTOCONF=6,
+	NET_IPV6_DAD_TRANSMITS=7,
+	NET_IPV6_RTR_SOLICITS=8,
+	NET_IPV6_RTR_SOLICIT_INTERVAL=9,
+	NET_IPV6_RTR_SOLICIT_DELAY=10,
+	NET_IPV6_USE_TEMPADDR=11,
+	NET_IPV6_TEMP_VALID_LFT=12,
+	NET_IPV6_TEMP_PREFERED_LFT=13,
+	NET_IPV6_REGEN_MAX_RETRY=14,
+	NET_IPV6_MAX_DESYNC_FACTOR=15,
+	NET_IPV6_MAX_ADDRESSES=16,
+	NET_IPV6_FORCE_MLD_VERSION=17,
+	__NET_IPV6_MAX
+};
+
+/* /proc/sys/net/ipv6/icmp */
+enum {
+	NET_IPV6_ICMP_RATELIMIT=1
+};
+
+/* /proc/sys/net/<protocol>/neigh/<dev> */
+enum {
+	NET_NEIGH_MCAST_SOLICIT=1,
+	NET_NEIGH_UCAST_SOLICIT=2,
+	NET_NEIGH_APP_SOLICIT=3,
+	NET_NEIGH_RETRANS_TIME=4,
+	NET_NEIGH_REACHABLE_TIME=5,
+	NET_NEIGH_DELAY_PROBE_TIME=6,
+	NET_NEIGH_GC_STALE_TIME=7,
+	NET_NEIGH_UNRES_QLEN=8,
+	NET_NEIGH_PROXY_QLEN=9,
+	NET_NEIGH_ANYCAST_DELAY=10,
+	NET_NEIGH_PROXY_DELAY=11,
+	NET_NEIGH_LOCKTIME=12,
+	NET_NEIGH_GC_INTERVAL=13,
+	NET_NEIGH_GC_THRESH1=14,
+	NET_NEIGH_GC_THRESH2=15,
+	NET_NEIGH_GC_THRESH3=16,
+	NET_NEIGH_RETRANS_TIME_MS=17,
+	NET_NEIGH_REACHABLE_TIME_MS=18,
+	__NET_NEIGH_MAX
+};
+
+/* /proc/sys/net/ipx */
+enum {
+	NET_IPX_PPROP_BROADCASTING=1,
+	NET_IPX_FORWARDING=2
+};
+
+/* /proc/sys/net/llc */
+enum {
+	NET_LLC2=1,
+	NET_LLC_STATION=2,
+};
+
+/* /proc/sys/net/llc/llc2 */
+enum {
+	NET_LLC2_TIMEOUT=1,
+};
+
+/* /proc/sys/net/llc/station */
+enum {
+	NET_LLC_STATION_ACK_TIMEOUT=1,
+};
+
+/* /proc/sys/net/llc/llc2/timeout */
+enum {
+	NET_LLC2_ACK_TIMEOUT=1,
+	NET_LLC2_P_TIMEOUT=2,
+	NET_LLC2_REJ_TIMEOUT=3,
+	NET_LLC2_BUSY_TIMEOUT=4,
+};
+
+/* /proc/sys/net/appletalk */
+enum {
+	NET_ATALK_AARP_EXPIRY_TIME=1,
+	NET_ATALK_AARP_TICK_TIME=2,
+	NET_ATALK_AARP_RETRANSMIT_LIMIT=3,
+	NET_ATALK_AARP_RESOLVE_TIME=4
+};
+
+
+/* /proc/sys/net/netrom */
+enum {
+	NET_NETROM_DEFAULT_PATH_QUALITY=1,
+	NET_NETROM_OBSOLESCENCE_COUNT_INITIALISER=2,
+	NET_NETROM_NETWORK_TTL_INITIALISER=3,
+	NET_NETROM_TRANSPORT_TIMEOUT=4,
+	NET_NETROM_TRANSPORT_MAXIMUM_TRIES=5,
+	NET_NETROM_TRANSPORT_ACKNOWLEDGE_DELAY=6,
+	NET_NETROM_TRANSPORT_BUSY_DELAY=7,
+	NET_NETROM_TRANSPORT_REQUESTED_WINDOW_SIZE=8,
+	NET_NETROM_TRANSPORT_NO_ACTIVITY_TIMEOUT=9,
+	NET_NETROM_ROUTING_CONTROL=10,
+	NET_NETROM_LINK_FAILS_COUNT=11,
+	NET_NETROM_RESET=12
+};
+
+/* /proc/sys/net/ax25 */
+enum {
+	NET_AX25_IP_DEFAULT_MODE=1,
+	NET_AX25_DEFAULT_MODE=2,
+	NET_AX25_BACKOFF_TYPE=3,
+	NET_AX25_CONNECT_MODE=4,
+	NET_AX25_STANDARD_WINDOW=5,
+	NET_AX25_EXTENDED_WINDOW=6,
+	NET_AX25_T1_TIMEOUT=7,
+	NET_AX25_T2_TIMEOUT=8,
+	NET_AX25_T3_TIMEOUT=9,
+	NET_AX25_IDLE_TIMEOUT=10,
+	NET_AX25_N2=11,
+	NET_AX25_PACLEN=12,
+	NET_AX25_PROTOCOL=13,
+	NET_AX25_DAMA_SLAVE_TIMEOUT=14
+};
+
+/* /proc/sys/net/rose */
+enum {
+	NET_ROSE_RESTART_REQUEST_TIMEOUT=1,
+	NET_ROSE_CALL_REQUEST_TIMEOUT=2,
+	NET_ROSE_RESET_REQUEST_TIMEOUT=3,
+	NET_ROSE_CLEAR_REQUEST_TIMEOUT=4,
+	NET_ROSE_ACK_HOLD_BACK_TIMEOUT=5,
+	NET_ROSE_ROUTING_CONTROL=6,
+	NET_ROSE_LINK_FAIL_TIMEOUT=7,
+	NET_ROSE_MAX_VCS=8,
+	NET_ROSE_WINDOW_SIZE=9,
+	NET_ROSE_NO_ACTIVITY_TIMEOUT=10
+};
+
+/* /proc/sys/net/x25 */
+enum {
+	NET_X25_RESTART_REQUEST_TIMEOUT=1,
+	NET_X25_CALL_REQUEST_TIMEOUT=2,
+	NET_X25_RESET_REQUEST_TIMEOUT=3,
+	NET_X25_CLEAR_REQUEST_TIMEOUT=4,
+	NET_X25_ACK_HOLD_BACK_TIMEOUT=5
+};
+
+/* /proc/sys/net/token-ring */
+enum
+{
+	NET_TR_RIF_TIMEOUT=1
+};
+
+/* /proc/sys/net/decnet/ */
+enum {
+	NET_DECNET_NODE_TYPE = 1,
+	NET_DECNET_NODE_ADDRESS = 2,
+	NET_DECNET_NODE_NAME = 3,
+	NET_DECNET_DEFAULT_DEVICE = 4,
+	NET_DECNET_TIME_WAIT = 5,
+	NET_DECNET_DN_COUNT = 6,
+	NET_DECNET_DI_COUNT = 7,
+	NET_DECNET_DR_COUNT = 8,
+	NET_DECNET_DST_GC_INTERVAL = 9,
+	NET_DECNET_CONF = 10,
+	NET_DECNET_NO_FC_MAX_CWND = 11,
+	NET_DECNET_MEM = 12,
+	NET_DECNET_RMEM = 13,
+	NET_DECNET_WMEM = 14,
+	NET_DECNET_DEBUG_LEVEL = 255
+};
+
+/* /proc/sys/net/decnet/conf/<dev> */
+enum {
+	NET_DECNET_CONF_LOOPBACK = -2,
+	NET_DECNET_CONF_DDCMP = -3,
+	NET_DECNET_CONF_PPP = -4,
+	NET_DECNET_CONF_X25 = -5,
+	NET_DECNET_CONF_GRE = -6,
+	NET_DECNET_CONF_ETHER = -7
+
+	/* ... and ifindex of devices */
+};
+
+/* /proc/sys/net/decnet/conf/<dev>/ */
+enum {
+	NET_DECNET_CONF_DEV_PRIORITY = 1,
+	NET_DECNET_CONF_DEV_T1 = 2,
+	NET_DECNET_CONF_DEV_T2 = 3,
+	NET_DECNET_CONF_DEV_T3 = 4,
+	NET_DECNET_CONF_DEV_FORWARDING = 5,
+	NET_DECNET_CONF_DEV_BLKSIZE = 6,
+	NET_DECNET_CONF_DEV_STATE = 7
+};
+
+/* /proc/sys/net/sctp */
+enum {
+	NET_SCTP_RTO_INITIAL = 1,
+	NET_SCTP_RTO_MIN     = 2,
+	NET_SCTP_RTO_MAX     = 3,
+	NET_SCTP_RTO_ALPHA   = 4,
+	NET_SCTP_RTO_BETA    = 5,
+	NET_SCTP_VALID_COOKIE_LIFE       =  6,
+	NET_SCTP_ASSOCIATION_MAX_RETRANS =  7,
+	NET_SCTP_PATH_MAX_RETRANS        =  8,
+	NET_SCTP_MAX_INIT_RETRANSMITS    =  9,
+	NET_SCTP_HB_INTERVAL             = 10,
+	NET_SCTP_PRESERVE_ENABLE         = 11,
+	NET_SCTP_MAX_BURST               = 12,
+	NET_SCTP_ADDIP_ENABLE		 = 13,
+	NET_SCTP_PRSCTP_ENABLE		 = 14,
+	NET_SCTP_SNDBUF_POLICY		 = 15,
+	NET_SCTP_SACK_TIMEOUT		 = 16,
+	NET_SCTP_RCVBUF_POLICY		 = 17,
+};
+
+/* /proc/sys/net/bridge */
+enum {
+	NET_BRIDGE_NF_CALL_ARPTABLES = 1,
+	NET_BRIDGE_NF_CALL_IPTABLES = 2,
+	NET_BRIDGE_NF_CALL_IP6TABLES = 3,
+	NET_BRIDGE_NF_FILTER_VLAN_TAGGED = 4,
+};
+
+/* CTL_PROC names: */
+
+/* CTL_FS names: */
+enum
+{
+	FS_NRINODE=1,	/* int:current number of allocated inodes */
+	FS_STATINODE=2,
+	FS_MAXINODE=3,	/* int:maximum number of inodes that can be allocated */
+	FS_NRDQUOT=4,	/* int:current number of allocated dquots */
+	FS_MAXDQUOT=5,	/* int:maximum number of dquots that can be allocated */
+	FS_NRFILE=6,	/* int:current number of allocated filedescriptors */
+	FS_MAXFILE=7,	/* int:maximum number of filedescriptors that can be allocated */
+	FS_DENTRY=8,
+	FS_NRSUPER=9,	/* int:current number of allocated super_blocks */
+	FS_MAXSUPER=10,	/* int:maximum number of super_blocks that can be allocated */
+	FS_OVERFLOWUID=11,	/* int: overflow UID */
+	FS_OVERFLOWGID=12,	/* int: overflow GID */
+	FS_LEASES=13,	/* int: leases enabled */
+	FS_DIR_NOTIFY=14,	/* int: directory notification enabled */
+	FS_LEASE_TIME=15,	/* int: maximum time to wait for a lease break */
+	FS_DQSTATS=16,	/* disc quota usage statistics and control */
+	FS_XFS=17,	/* struct: control xfs parameters */
+	FS_AIO_NR=18,	/* current system-wide number of aio requests */
+	FS_AIO_MAX_NR=19,	/* system-wide maximum number of aio requests */
+	FS_INOTIFY=20,	/* inotify submenu */
+};
+
+/* /proc/sys/fs/quota/ */
+enum {
+	FS_DQ_LOOKUPS = 1,
+	FS_DQ_DROPS = 2,
+	FS_DQ_READS = 3,
+	FS_DQ_WRITES = 4,
+	FS_DQ_CACHE_HITS = 5,
+	FS_DQ_ALLOCATED = 6,
+	FS_DQ_FREE = 7,
+	FS_DQ_SYNCS = 8,
+	FS_DQ_WARNINGS = 9,
+};
+
+/* CTL_DEBUG names: */
+
+/* CTL_DEV names: */
+enum {
+	DEV_CDROM=1,
+	DEV_HWMON=2,
+	DEV_PARPORT=3,
+	DEV_RAID=4,
+	DEV_MAC_HID=5,
+	DEV_SCSI=6,
+	DEV_IPMI=7,
+};
+
+/* /proc/sys/dev/cdrom */
+enum {
+	DEV_CDROM_INFO=1,
+	DEV_CDROM_AUTOCLOSE=2,
+	DEV_CDROM_AUTOEJECT=3,
+	DEV_CDROM_DEBUG=4,
+	DEV_CDROM_LOCK=5,
+	DEV_CDROM_CHECK_MEDIA=6
+};
+
+/* /proc/sys/dev/parport */
+enum {
+	DEV_PARPORT_DEFAULT=-3
+};
+
+/* /proc/sys/dev/raid */
+enum {
+	DEV_RAID_SPEED_LIMIT_MIN=1,
+	DEV_RAID_SPEED_LIMIT_MAX=2
+};
+
+/* /proc/sys/dev/parport/default */
+enum {
+	DEV_PARPORT_DEFAULT_TIMESLICE=1,
+	DEV_PARPORT_DEFAULT_SPINTIME=2
+};
+
+/* /proc/sys/dev/parport/parport n */
+enum {
+	DEV_PARPORT_SPINTIME=1,
+	DEV_PARPORT_BASE_ADDR=2,
+	DEV_PARPORT_IRQ=3,
+	DEV_PARPORT_DMA=4,
+	DEV_PARPORT_MODES=5,
+	DEV_PARPORT_DEVICES=6,
+	DEV_PARPORT_AUTOPROBE=16
+};
+
+/* /proc/sys/dev/parport/parport n/devices/ */
+enum {
+	DEV_PARPORT_DEVICES_ACTIVE=-3,
+};
+
+/* /proc/sys/dev/parport/parport n/devices/device n */
+enum {
+	DEV_PARPORT_DEVICE_TIMESLICE=1,
+};
+
+/* /proc/sys/dev/mac_hid */
+enum {
+	DEV_MAC_HID_KEYBOARD_SENDS_LINUX_KEYCODES=1,
+	DEV_MAC_HID_KEYBOARD_LOCK_KEYCODES=2,
+	DEV_MAC_HID_MOUSE_BUTTON_EMULATION=3,
+	DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE=4,
+	DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE=5,
+	DEV_MAC_HID_ADB_MOUSE_SENDS_KEYCODES=6
+};
+
+/* /proc/sys/dev/scsi */
+enum {
+	DEV_SCSI_LOGGING_LEVEL=1,
+};
+
+/* /proc/sys/dev/ipmi */
+enum {
+	DEV_IPMI_POWEROFF_POWERCYCLE=1,
+};
+
+/* /proc/sys/abi */
+enum
+{
+	ABI_DEFHANDLER_COFF=1,	/* default handler for coff binaries */
+	ABI_DEFHANDLER_ELF=2, 	/* default handler for ELF binaries */
+	ABI_DEFHANDLER_LCALL7=3,/* default handler for procs using lcall7 */
+	ABI_DEFHANDLER_LIBCSO=4,/* default handler for an libc.so ELF interp */
+	ABI_TRACE=5,		/* tracing flags */
+	ABI_FAKE_UTSNAME=6,	/* fake target utsname information */
+};
+
+#ifdef __KERNEL__
+#include <linux/list.h>
+
+extern void sysctl_init(void);
+
+typedef struct ctl_table ctl_table;
+
+typedef int ctl_handler (ctl_table *table, int __user *name, int nlen,
+			 void __user *oldval, size_t __user *oldlenp,
+			 void __user *newval, size_t newlen, 
+			 void **context);
+
+typedef int proc_handler (ctl_table *ctl, int write, struct file * filp,
+			  void __user *buffer, size_t *lenp, loff_t *ppos);
+
+extern int proc_dostring(ctl_table *, int, struct file *,
+			 void __user *, size_t *, loff_t *);
+extern int proc_dointvec(ctl_table *, int, struct file *,
+			 void __user *, size_t *, loff_t *);
+extern int proc_dointvec_bset(ctl_table *, int, struct file *,
+			      void __user *, size_t *, loff_t *);
+extern int proc_dointvec_minmax(ctl_table *, int, struct file *,
+				void __user *, size_t *, loff_t *);
+extern int proc_dointvec_jiffies(ctl_table *, int, struct file *,
+				 void __user *, size_t *, loff_t *);
+extern int proc_dointvec_userhz_jiffies(ctl_table *, int, struct file *,
+					void __user *, size_t *, loff_t *);
+extern int proc_dointvec_ms_jiffies(ctl_table *, int, struct file *,
+				    void __user *, size_t *, loff_t *);
+extern int proc_doulongvec_minmax(ctl_table *, int, struct file *,
+				  void __user *, size_t *, loff_t *);
+extern int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int,
+				      struct file *, void __user *, size_t *, loff_t *);
+
+extern int do_sysctl (int __user *name, int nlen,
+		      void __user *oldval, size_t __user *oldlenp,
+		      void __user *newval, size_t newlen);
+
+extern int do_sysctl_strategy (ctl_table *table, 
+			       int __user *name, int nlen,
+			       void __user *oldval, size_t __user *oldlenp,
+			       void __user *newval, size_t newlen, void ** context);
+
+extern ctl_handler sysctl_string;
+extern ctl_handler sysctl_intvec;
+extern ctl_handler sysctl_jiffies;
+extern ctl_handler sysctl_ms_jiffies;
+
+
+/*
+ * Register a set of sysctl names by calling register_sysctl_table
+ * with an initialised array of ctl_table's.  An entry with zero
+ * ctl_name terminates the table.  table->de will be set up by the
+ * registration and need not be initialised in advance.
+ *
+ * sysctl names can be mirrored automatically under /proc/sys.  The
+ * procname supplied controls /proc naming.
+ *
+ * The table's mode will be honoured both for sys_sysctl(2) and
+ * proc-fs access.
+ *
+ * Leaf nodes in the sysctl tree will be represented by a single file
+ * under /proc; non-leaf nodes will be represented by directories.  A
+ * null procname disables /proc mirroring at this node.
+ * 
+ * sysctl(2) can automatically manage read and write requests through
+ * the sysctl table.  The data and maxlen fields of the ctl_table
+ * struct enable minimal validation of the values being written to be
+ * performed, and the mode field allows minimal authentication.
+ * 
+ * More sophisticated management can be enabled by the provision of a
+ * strategy routine with the table entry.  This will be called before
+ * any automatic read or write of the data is performed.
+ * 
+ * The strategy routine may return:
+ * <0: Error occurred (error is passed to user process)
+ * 0:  OK - proceed with automatic read or write.
+ * >0: OK - read or write has been done by the strategy routine, so 
+ *     return immediately.
+ * 
+ * There must be a proc_handler routine for any terminal nodes
+ * mirrored under /proc/sys (non-terminals are handled by a built-in
+ * directory handler).  Several default handlers are available to
+ * cover common cases.
+ */
+
+/* A sysctl table is an array of struct ctl_table: */
+struct ctl_table 
+{
+	int ctl_name;			/* Binary ID */
+	const char *procname;		/* Text ID for /proc/sys, or zero */
+	void *data;
+	int maxlen;
+	mode_t mode;
+	ctl_table *child;
+	proc_handler *proc_handler;	/* Callback for text formatting */
+	ctl_handler *strategy;		/* Callback function for all r/w */
+	struct proc_dir_entry *de;	/* /proc control block */
+	void *extra1;
+	void *extra2;
+};
+
+/* struct ctl_table_header is used to maintain dynamic lists of
+   ctl_table trees. */
+struct ctl_table_header
+{
+	ctl_table *ctl_table;
+	struct list_head ctl_entry;
+	int used;
+	struct completion *unregistering;
+};
+
+struct ctl_table_header * register_sysctl_table(ctl_table * table, 
+						int insert_at_head);
+void unregister_sysctl_table(struct ctl_table_header * table);
+
+#else /* __KERNEL__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_SYSCTL_H */
diff -urN oldtree/kernel/sysctl.c newtree/kernel/sysctl.c
--- oldtree/kernel/sysctl.c	2006-01-03 03:21:10.000000000 +0000
+++ newtree/kernel/sysctl.c	2006-02-03 18:18:17.102730256 +0000
@@ -86,6 +86,9 @@
 #ifdef CONFIG_HOTPLUG
 extern char hotplug_path[];
 #endif
+#ifdef CONFIG_FB_SPLASH
+extern char fbsplash_path[];
+#endif
 #ifdef CONFIG_CHR_DEV_SG
 extern int sg_big_buff;
 #endif
@@ -404,6 +407,17 @@
 		.strategy	= &sysctl_string,
 	},
 #endif
+#ifdef CONFIG_FB_SPLASH
+	{
+		.ctl_name	= KERN_FBSPLASH,
+		.procname	= "fbsplash",
+		.data		= &fbsplash_path,
+		.maxlen		= KMOD_PATH_LEN,
+		.mode		= 0644,
+		.proc_handler	= &proc_dostring,
+		.strategy	= &sysctl_string,
+	},
+#endif
 #ifdef CONFIG_CHR_DEV_SG
 	{
 		.ctl_name	= KERN_SG_BIG_BUFF,
