Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / drivers / video / vesafb.c
index b0b9acf..2196448 100644 (file)
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/tty.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/screen_info.h>
 
 #include <video/vga.h>
 #include <asm/io.h>
@@ -51,7 +51,7 @@ static int             inverse   = 0;
 static int             mtrr      = 0; /* disable mtrr */
 static int            vram_remap __initdata = 0; /* Set amount of memory to be used */
 static int            vram_total __initdata = 0; /* Set total amount of memory */
-static int             pmi_setpal = 0; /* pmi for palette changes ??? */
+static int             pmi_setpal = 1; /* pmi for palette changes ??? */
 static int             ypan       = 0;  /* 0..nothing, 1..ypan, 2..ywrap */
 static unsigned short  *pmi_base  = NULL;
 static void            (*pmi_start)(void);
@@ -80,15 +80,30 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var,
        return 0;
 }
 
-static void vesa_setpalette(int regno, unsigned red, unsigned green,
+static int vesa_setpalette(int regno, unsigned red, unsigned green,
                            unsigned blue)
 {
        int shift = 16 - depth;
+       int err = -EINVAL;
+
+/*
+ * Try VGA registers first...
+ */
+       if (vga_compat) {
+               outb_p(regno,       dac_reg);
+               outb_p(red   >> shift, dac_val);
+               outb_p(green >> shift, dac_val);
+               outb_p(blue  >> shift, dac_val);
+               err = 0;
+       }
 
 #ifdef __i386__
-       struct { u_char blue, green, red, pad; } entry;
+/*
+ * Fallback to the PMI....
+ */
+       if (err && pmi_setpal) {
+               struct { u_char blue, green, red, pad; } entry;
 
-       if (pmi_setpal) {
                entry.red   = red   >> shift;
                entry.green = green >> shift;
                entry.blue  = blue  >> shift;
@@ -102,26 +117,19 @@ static void vesa_setpalette(int regno, unsigned red, unsigned green,
                   "d" (regno),          /* EDX */
                   "D" (&entry),         /* EDI */
                   "S" (&pmi_pal));      /* ESI */
-               return;
+               err = 0;
        }
 #endif
 
-/*
- * without protected mode interface and if VGA compatible,
- * try VGA registers...
- */
-       if (vga_compat) {
-               outb_p(regno,       dac_reg);
-               outb_p(red   >> shift, dac_val);
-               outb_p(green >> shift, dac_val);
-               outb_p(blue  >> shift, dac_val);
-       }
+       return err;
 }
 
 static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
                            unsigned blue, unsigned transp,
                            struct fb_info *info)
 {
+       int err = 0;
+
        /*
         *  Set a single color register. The values supplied are
         *  already rounded down to the hardware's capabilities
@@ -133,7 +141,7 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
                return 1;
 
        if (info->var.bits_per_pixel == 8)
-               vesa_setpalette(regno,red,green,blue);
+               err = vesa_setpalette(regno,red,green,blue);
        else if (regno < 16) {
                switch (info->var.bits_per_pixel) {
                case 16:
@@ -164,7 +172,7 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
                }
        }
 
-       return 0;
+       return err;
 }
 
 static struct fb_ops vesafb_ops = {
@@ -460,9 +468,7 @@ static struct platform_driver vesafb_driver = {
        },
 };
 
-static struct platform_device vesafb_device = {
-       .name   = "vesafb",
-};
+static struct platform_device *vesafb_device;
 
 static int __init vesafb_init(void)
 {
@@ -475,10 +481,19 @@ static int __init vesafb_init(void)
        ret = platform_driver_register(&vesafb_driver);
 
        if (!ret) {
-               ret = platform_device_register(&vesafb_device);
-               if (ret)
+               vesafb_device = platform_device_alloc("vesafb", 0);
+
+               if (vesafb_device)
+                       ret = platform_device_add(vesafb_device);
+               else
+                       ret = -ENOMEM;
+
+               if (ret) {
+                       platform_device_put(vesafb_device);
                        platform_driver_unregister(&vesafb_driver);
+               }
        }
+
        return ret;
 }
 module_init(vesafb_init);