Commit 58f533f9 authored by Antonino Daplas's avatar Antonino Daplas Committed by Linus Torvalds

[PATCH] w100fb: Make blanking function interrupt safe

w100fb bugfix: The blanking function used vmalloc/vfree which isn't interrupt
safe.  To avoid problems, switch to kmalloc/kfree and use several buffers to
avoid kmalloc size limitations.
Signed-off-by: default avatarRichard Purdie <rpurdie@rpsys.net>
Signed-off-by: default avatarAntonino Daplas <adaplas@pol.net>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 117738c4
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/vmalloc.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <video/w100fb.h> #include <video/w100fb.h>
...@@ -90,8 +89,6 @@ struct w100fb_par { ...@@ -90,8 +89,6 @@ struct w100fb_par {
static struct w100fb_par *current_par; static struct w100fb_par *current_par;
static u16 *gSaveImagePtr = NULL;
/* Remapped addresses for base cfg, memmapped regs and the frame buffer itself */ /* Remapped addresses for base cfg, memmapped regs and the frame buffer itself */
static void *remapped_base; static void *remapped_base;
static void *remapped_regs; static void *remapped_regs;
...@@ -494,42 +491,56 @@ static void w100fb_clear_screen(u32 mode, long int offset) ...@@ -494,42 +491,56 @@ 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) static void w100fb_save_buffer(void)
{ {
int i; int i, j, bufsize;
if (gSaveImagePtr != NULL) { bufsize=(current_par->xres * current_par->yres * BITS_PER_PIXEL / 8) / W100_BUF_NUM;
vfree(gSaveImagePtr); for (i = 0; i < W100_BUF_NUM; i++) {
gSaveImagePtr = NULL; 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;
} }
gSaveImagePtr = vmalloc(current_par->xres * current_par->yres * BITS_PER_PIXEL / 8); for (j = 0; j < bufsize/4; j++)
if (gSaveImagePtr != NULL) { *(gSaveImagePtr[i] + j) = readl(remapped_fbuf + (bufsize*i) + j*4);
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");
} }
} }
static void w100fb_restore_buffer(void) static void w100fb_restore_buffer(void)
{ {
int i; int i, j, bufsize;
if (gSaveImagePtr != NULL) { bufsize=(current_par->xres * current_par->yres * BITS_PER_PIXEL / 8) / W100_BUF_NUM;
for (i = 0; i < (current_par->xres * current_par->yres); i++) { for (i = 0; i < W100_BUF_NUM; i++) {
writew(*(gSaveImagePtr + i),remapped_fbuf + (2*i)); if (gSaveImagePtr[i] == NULL) {
printk(KERN_WARNING "can't find pre-off image buffer %d\n", i);
w100fb_clear_buffer();
break;
} }
vfree(gSaveImagePtr); for (j = 0; j < (bufsize/4); j++)
gSaveImagePtr = NULL; writel(*(gSaveImagePtr[i] + j),remapped_fbuf + (bufsize*i) + (j*4));
kfree(gSaveImagePtr[i]);
gSaveImagePtr[i] = NULL;
} }
} }
static void w100fb_clear_buffer(void) static void w100fb_clear_buffer(void)
{ {
if (gSaveImagePtr != NULL) { int i;
vfree(gSaveImagePtr); for (i = 0; i < W100_BUF_NUM; i++) {
gSaveImagePtr = NULL; if (gSaveImagePtr[i] != NULL) {
kfree(gSaveImagePtr[i]);
gSaveImagePtr[i] = NULL;
}
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment