include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / video / geode / gxfb_core.c
index 151d964..76e7dac 100644 (file)
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/console.h>
+#include <linux/suspend.h>
 #include <linux/init.h>
 #include <linux/pci.h>
-#include <asm/geode.h>
+#include <linux/cs5535.h>
 
 #include "gxfb.h"
 
 static char *mode_option;
 static int vram;
+static int vt_switch;
 
 /* Modes relevant to the GX (taken from modedb.c) */
-static const struct fb_videomode gx_modedb[] __initdata = {
+static struct fb_videomode gx_modedb[] __initdata = {
        /* 640x480-60 VESA */
        { NULL, 60, 640, 480, 39682,  48, 16, 33, 10, 96, 2,
          0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
@@ -106,6 +107,35 @@ static const struct fb_videomode gx_modedb[] __initdata = {
          FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
 };
 
+#ifdef CONFIG_OLPC
+#include <asm/olpc.h>
+
+static struct fb_videomode gx_dcon_modedb[] __initdata = {
+       /* The only mode the DCON has is 1200x900 */
+       { NULL, 50, 1200, 900, 17460, 24, 8, 4, 5, 8, 3,
+         FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+         FB_VMODE_NONINTERLACED, 0 }
+};
+
+static void __init get_modedb(struct fb_videomode **modedb, unsigned int *size)
+{
+       if (olpc_has_dcon()) {
+               *modedb = (struct fb_videomode *) gx_dcon_modedb;
+               *size = ARRAY_SIZE(gx_dcon_modedb);
+       } else {
+               *modedb = (struct fb_videomode *) gx_modedb;
+               *size = ARRAY_SIZE(gx_modedb);
+       }
+}
+
+#else
+static void __init get_modedb(struct fb_videomode **modedb, unsigned int *size)
+{
+       *modedb = (struct fb_videomode *) gx_modedb;
+       *size = ARRAY_SIZE(gx_modedb);
+}
+#endif
+
 static int gxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
        if (var->xres > 1600 || var->yres > 1200)
@@ -140,13 +170,10 @@ static int gxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 
 static int gxfb_set_par(struct fb_info *info)
 {
-       if (info->var.bits_per_pixel > 8) {
+       if (info->var.bits_per_pixel > 8)
                info->fix.visual = FB_VISUAL_TRUECOLOR;
-               fb_dealloc_cmap(&info->cmap);
-       } else {
+       else
                info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
-               fb_alloc_cmap(&info->cmap, 1<<info->var.bits_per_pixel, 0);
-       }
 
        info->fix.line_length = gx_line_delta(info->var.xres, info->var.bits_per_pixel);
 
@@ -211,23 +238,21 @@ static int __init gxfb_map_video_memory(struct fb_info *info, struct pci_dev *de
        ret = pci_request_region(dev, 3, "gxfb (video processor)");
        if (ret < 0)
                return ret;
-       par->vid_regs = ioremap(pci_resource_start(dev, 3),
-                               pci_resource_len(dev, 3));
+       par->vid_regs = pci_ioremap_bar(dev, 3);
        if (!par->vid_regs)
                return -ENOMEM;
 
        ret = pci_request_region(dev, 2, "gxfb (display controller)");
        if (ret < 0)
                return ret;
-       par->dc_regs = ioremap(pci_resource_start(dev, 2), pci_resource_len(dev, 2));
+       par->dc_regs = pci_ioremap_bar(dev, 2);
        if (!par->dc_regs)
                return -ENOMEM;
 
        ret = pci_request_region(dev, 1, "gxfb (graphics processor)");
        if (ret < 0)
                return ret;
-       par->gp_regs = ioremap(pci_resource_start(dev, 1),
-       pci_resource_len(dev, 1));
+       par->gp_regs = pci_ioremap_bar(dev, 1);
 
        if (!par->gp_regs)
                return -ENOMEM;
@@ -302,6 +327,11 @@ static struct fb_info * __init gxfb_init_fbinfo(struct device *dev)
 
        info->var.grayscale     = 0;
 
+       if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
+               framebuffer_release(info);
+               return NULL;
+       }
+
        return info;
 }
 
@@ -348,6 +378,9 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
        int ret;
        unsigned long val;
 
+       struct fb_videomode *modedb_ptr;
+       unsigned int modedb_size;
+
        info = gxfb_init_fbinfo(&pdev->dev);
        if (!info)
                return -ENOMEM;
@@ -367,8 +400,9 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
        else
                par->enable_crt = 1;
 
+       get_modedb(&modedb_ptr, &modedb_size);
        ret = fb_find_mode(&info->var, info, mode_option,
-                          gx_modedb, ARRAY_SIZE(gx_modedb), NULL, 16);
+                          modedb_ptr, modedb_size, NULL, 16);
        if (ret == 0 || ret == 4) {
                dev_err(&pdev->dev, "could not find valid video mode\n");
                ret = -EINVAL;
@@ -382,6 +416,8 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
        gxfb_check_var(&info->var, info);
        gxfb_set_par(info);
 
+       pm_set_vt_switch(vt_switch);
+
        if (register_framebuffer(info) < 0) {
                ret = -EINVAL;
                goto err;
@@ -408,8 +444,10 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
                pci_release_region(pdev, 1);
        }
 
-       if (info)
+       if (info) {
+               fb_dealloc_cmap(&info->cmap);
                framebuffer_release(info);
+       }
        return ret;
 }
 
@@ -432,6 +470,7 @@ static void gxfb_remove(struct pci_dev *pdev)
        iounmap(par->gp_regs);
        pci_release_region(pdev, 1);
 
+       fb_dealloc_cmap(&info->cmap);
        pci_set_drvdata(pdev, NULL);
 
        framebuffer_release(info);
@@ -502,5 +541,8 @@ MODULE_PARM_DESC(mode_option, "video mode (<x>x<y>[-<bpp>][@<refr>])");
 module_param(vram, int, 0);
 MODULE_PARM_DESC(vram, "video memory size");
 
+module_param(vt_switch, int, 0);
+MODULE_PARM_DESC(vt_switch, "enable VT switch during suspend/resume");
+
 MODULE_DESCRIPTION("Framebuffer driver for the AMD Geode GX");
 MODULE_LICENSE("GPL");