diff options
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/fbmem.c | 6 | ||||
-rw-r--r-- | drivers/video/fbsysfs.c | 14 | ||||
-rw-r--r-- | drivers/video/vesafb.c | 47 |
3 files changed, 47 insertions, 20 deletions
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 40784a944d0..d2e19f6dd72 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -80,10 +80,12 @@ EXPORT_SYMBOL(fb_get_color_depth); */ void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height) { - int i; + int i, j; for (i = height; i--; ) { - memcpy(dst, src, s_pitch); + /* s_pitch is a few bytes at the most, memcpy is suboptimal */ + for (j = 0; j < s_pitch; j++) + dst[j] = src[j]; src += s_pitch; dst += d_pitch; } diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index 63b505cce4e..ed1d4d1ac4f 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c @@ -244,15 +244,15 @@ static ssize_t show_virtual(struct class_device *class_device, char *buf) /* Format for cmap is "%02x%c%4x%4x%4x\n" */ /* %02x entry %c transp %4x red %4x blue %4x green \n */ -/* 255 rows at 16 chars equals 4096 */ -/* PAGE_SIZE can be 4096 or larger */ +/* 256 rows at 16 chars equals 4096, the normal page size */ +/* the code will automatically adjust for different page sizes */ static ssize_t store_cmap(struct class_device *class_device, const char *buf, size_t count) { struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); int rc, i, start, length, transp = 0; - if ((count > 4096) || ((count % 16) != 0) || (PAGE_SIZE < 4096)) + if ((count > PAGE_SIZE) || ((count % 16) != 0)) return -EINVAL; if (!fb_info->fbops->fb_setcolreg && !fb_info->fbops->fb_setcmap) @@ -317,18 +317,18 @@ static ssize_t show_cmap(struct class_device *class_device, char *buf) !fb_info->cmap.green) return -EINVAL; - if (PAGE_SIZE < 4096) + if (fb_info->cmap.len > PAGE_SIZE / 16) return -EINVAL; /* don't mess with the format, the buffer is PAGE_SIZE */ - /* 255 entries at 16 chars per line equals 4096 = PAGE_SIZE */ + /* 256 entries at 16 chars per line equals 4096 = PAGE_SIZE */ for (i = 0; i < fb_info->cmap.len; i++) { - sprintf(&buf[ i * 16], "%02x%c%4x%4x%4x\n", i + fb_info->cmap.start, + snprintf(&buf[ i * 16], PAGE_SIZE - i * 16, "%02x%c%4x%4x%4x\n", i + fb_info->cmap.start, ((fb_info->cmap.transp && fb_info->cmap.transp[i]) ? '*' : ' '), fb_info->cmap.red[i], fb_info->cmap.blue[i], fb_info->cmap.green[i]); } - return 4096; + return 16 * fb_info->cmap.len; } static ssize_t store_blank(struct class_device *class_device, const char * buf, diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index 9ed1a931dd3..a272592b037 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c @@ -45,7 +45,7 @@ static struct fb_fix_screeninfo vesafb_fix __initdata = { }; static int inverse = 0; -static int mtrr = 1; +static int mtrr = 3; /* default to write-combining */ 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 ??? */ @@ -204,8 +204,8 @@ static int __init vesafb_setup(char *options) pmi_setpal=0; else if (! strcmp(this_opt, "pmipal")) pmi_setpal=1; - else if (! strcmp(this_opt, "mtrr")) - mtrr=1; + else if (! strncmp(this_opt, "mtrr:", 5)) + mtrr = simple_strtoul(this_opt+5, NULL, 0); else if (! strcmp(this_opt, "nomtrr")) mtrr=0; else if (! strncmp(this_opt, "vtotal:", 7)) @@ -387,14 +387,39 @@ static int __init vesafb_probe(struct device *device) if (mtrr) { unsigned int temp_size = size_total; - /* Find the largest power-of-two */ - while (temp_size & (temp_size - 1)) - temp_size &= (temp_size - 1); - - /* Try and find a power of two to add */ - while (temp_size > PAGE_SIZE && - mtrr_add(vesafb_fix.smem_start, temp_size, MTRR_TYPE_WRCOMB, 1)==-EINVAL) { - temp_size >>= 1; + unsigned int type = 0; + + switch (mtrr) { + case 1: + type = MTRR_TYPE_UNCACHABLE; + break; + case 2: + type = MTRR_TYPE_WRBACK; + break; + case 3: + type = MTRR_TYPE_WRCOMB; + break; + case 4: + type = MTRR_TYPE_WRTHROUGH; + break; + default: + type = 0; + break; + } + + if (type) { + int rc; + + /* Find the largest power-of-two */ + while (temp_size & (temp_size - 1)) + temp_size &= (temp_size - 1); + + /* Try and find a power of two to add */ + do { + rc = mtrr_add(vesafb_fix.smem_start, temp_size, + type, 1); + temp_size >>= 1; + } while (temp_size >= PAGE_SIZE && rc == -EINVAL); } } |