vserver 2.0 rc7
[linux-2.6.git] / drivers / video / w100fb.c
index e118285..58cd2ad 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/device.h>
 #include <linux/string.h>
 #include <linux/proc_fs.h>
-#include <linux/vmalloc.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <video/w100fb.h>
@@ -90,8 +89,6 @@ struct w100fb_par {
 
 static struct w100fb_par *current_par;
 
-static u16 *gSaveImagePtr = NULL;
-
 /* Remapped addresses for base cfg, memmapped regs and the frame buffer itself */
 static void *remapped_base;
 static void *remapped_regs;
@@ -494,48 +491,60 @@ static void w100fb_clear_screen(u32 mode, long int offset)
 }
 
 
+/* Need to split up the buffers to stay within the limits of kmalloc */
+#define W100_BUF_NUM   6
+static uint32_t *gSaveImagePtr[W100_BUF_NUM] = { NULL };
+
 static void w100fb_save_buffer(void)
 {
-       int i;
-
-       if (gSaveImagePtr != NULL) {
-               vfree(gSaveImagePtr);
-               gSaveImagePtr = NULL;
-       }
-       gSaveImagePtr = vmalloc(current_par->xres * current_par->yres * BITS_PER_PIXEL / 8);
-       if (gSaveImagePtr != NULL) {
-               for (i = 0; i < (current_par->xres * current_par->yres); i++)
-                       *(gSaveImagePtr + i) = readw(remapped_fbuf + (2*i));
-       } else {
-               printk(KERN_WARNING "can't alloc pre-off image buffer\n");
+       int i, j, bufsize;
+
+       bufsize=(current_par->xres * current_par->yres * BITS_PER_PIXEL / 8) / W100_BUF_NUM;
+       for (i = 0; i < W100_BUF_NUM; i++) {
+               if (gSaveImagePtr[i] == NULL)
+                       gSaveImagePtr[i] = kmalloc(bufsize, GFP_KERNEL);
+               if (gSaveImagePtr[i] == NULL) {
+                       w100fb_clear_buffer();
+                       printk(KERN_WARNING "can't alloc pre-off image buffer %d\n", i);
+                       break;
+               }
+               for (j = 0; j < bufsize/4; j++)
+                       *(gSaveImagePtr[i] + j) = readl(remapped_fbuf + (bufsize*i) + j*4);
        }
 }
 
 
 static void w100fb_restore_buffer(void)
 {
-       int i;
+       int i, j, bufsize;
 
-       if (gSaveImagePtr != NULL) {
-               for (i = 0; i < (current_par->xres * current_par->yres); i++) {
-                               writew(*(gSaveImagePtr + i),remapped_fbuf + (2*i));
-                       }
-               vfree(gSaveImagePtr);
-               gSaveImagePtr = NULL;
+       bufsize=(current_par->xres * current_par->yres * BITS_PER_PIXEL / 8) / W100_BUF_NUM;
+       for (i = 0; i < W100_BUF_NUM; i++) {
+               if (gSaveImagePtr[i] == NULL) {
+                       printk(KERN_WARNING "can't find pre-off image buffer %d\n", i);
+                       w100fb_clear_buffer();
+                       break;
+               }
+               for (j = 0; j < (bufsize/4); j++)
+                       writel(*(gSaveImagePtr[i] + j),remapped_fbuf + (bufsize*i) + (j*4));
+               kfree(gSaveImagePtr[i]);
+               gSaveImagePtr[i] = NULL;
        }
 }
 
+
 static void w100fb_clear_buffer(void)
 {
-       if (gSaveImagePtr != NULL) {
-               vfree(gSaveImagePtr);
-               gSaveImagePtr = NULL;
+       int i;
+       for (i = 0; i < W100_BUF_NUM; i++) {
+               kfree(gSaveImagePtr[i]);
+               gSaveImagePtr[i] = NULL;
        }
 }
 
 
 #ifdef CONFIG_PM
-static int w100fb_suspend(struct device *dev, u32 state, u32 level)
+static int w100fb_suspend(struct device *dev, pm_message_t state, u32 level)
 {
        if (level == SUSPEND_POWER_DOWN) {
                struct fb_info *info = dev_get_drvdata(dev);