Commit b5f86b85 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] fbdev: Vesa Fbdev update

From: James Simmons <jsimmons@infradead.org>

This patch migrates the Vesa Framebuffer driver over to the
framebuffer_alloc/framebuffer_release api.  It also fixes the error
handling paths.  The mtrr issue that Geert brought up has been fixed.
parent f5f2e754
......@@ -47,12 +47,9 @@ static struct fb_fix_screeninfo vesafb_fix __initdata = {
.accel = FB_ACCEL_NONE,
};
static struct fb_info fb_info;
static u32 pseudo_palette[17];
static int inverse = 0;
static int mtrr = 1;
static int vram __initdata = 0; /* Set amount of memory to be used */
static int pmi_setpal = 0; /* pmi for palette changes ??? */
static int ypan = 0; /* 0..nothing, 1..ypan, 2..ywrap */
static unsigned short *pmi_base = 0;
......@@ -210,14 +207,17 @@ int __init vesafb_setup(char *options)
mtrr=1;
else if (! strcmp(this_opt, "nomtrr"))
mtrr=0;
else if (! strcmp(this_opt, "vram"))
vram = simple_strtoul(this_opt+5, NULL, 0);
}
return 0;
}
int __init vesafb_init(void)
static int __init vesafb_probe(struct device *device)
{
int video_cmap_len;
int i;
struct platform_device *dev = to_platform_device(device);
struct fb_info *info;
int i, err;
if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
return -ENXIO;
......@@ -229,7 +229,18 @@ int __init vesafb_init(void)
vesafb_defined.xres = screen_info.lfb_width;
vesafb_defined.yres = screen_info.lfb_height;
vesafb_fix.line_length = screen_info.lfb_linelength;
vesafb_fix.smem_len = screen_info.lfb_size * 65536;
/* Allocate enough memory for double buffering */
vesafb_fix.smem_len = screen_info.lfb_width * screen_info.lfb_height * vesafb_defined.bits_per_pixel >> 2;
/* check that we don't remap more memory than old cards have */
if (vesafb_fix.smem_len > (screen_info.lfb_size * 65536))
vesafb_fix.smem_len = screen_info.lfb_size * 65536;
/* Set video size according to vram boot option */
if (vram && vram * 1024 * 1024 != vesafb_fix.smem_len)
vesafb_fix.smem_len = vram * 1024 * 1024;
vesafb_fix.visual = (vesafb_defined.bits_per_pixel == 8) ?
FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
......@@ -251,17 +262,25 @@ int __init vesafb_init(void)
spaces our resource handlers simply don't know about */
}
fb_info.screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
if (!fb_info.screen_base) {
info = framebuffer_alloc(sizeof(u32) * 256, &dev->dev);
if (!info) {
release_mem_region(vesafb_fix.smem_start, vesafb_fix.smem_len);
return -ENOMEM;
}
info->pseudo_palette = info->par;
info->par = NULL;
info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
if (!info->screen_base) {
printk(KERN_ERR
"vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
vesafb_fix.smem_len, vesafb_fix.smem_start);
return -EIO;
err = -EIO;
goto err;
}
printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
vesafb_fix.smem_start, fb_info.screen_base, vesafb_fix.smem_len/1024);
vesafb_fix.smem_start, info->screen_base, vesafb_fix.smem_len/1024);
printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
......@@ -331,12 +350,10 @@ int __init vesafb_init(void)
screen_info.red_pos,
screen_info.green_pos,
screen_info.blue_pos);
video_cmap_len = 16;
} else {
vesafb_defined.red.length = 6;
vesafb_defined.green.length = 6;
vesafb_defined.blue.length = 6;
video_cmap_len = 256;
}
vesafb_fix.ypanstep = ypan ? 1 : 0;
......@@ -358,20 +375,51 @@ int __init vesafb_init(void)
}
}
fb_info.fbops = &vesafb_ops;
fb_info.var = vesafb_defined;
fb_info.fix = vesafb_fix;
fb_info.pseudo_palette = pseudo_palette;
fb_info.flags = FBINFO_FLAG_DEFAULT;
info->fbops = &vesafb_ops;
info->var = vesafb_defined;
info->fix = vesafb_fix;
info->flags = FBINFO_FLAG_DEFAULT;
if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
err = -ENXIO;
goto err;
}
if (register_framebuffer(info)<0) {
err = -EINVAL;
fb_dealloc_cmap(&info->cmap);
goto err;
}
printk(KERN_INFO "fb%d: %s frame buffer device\n",
info->node, info->fix.id);
return 0;
err:
framebuffer_release(info);
release_mem_region(vesafb_fix.smem_start, vesafb_fix.smem_len);
return err;
}
fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
static struct device_driver vesafb_driver = {
.name = "vesafb",
.bus = &platform_bus_type,
.probe = vesafb_probe,
};
if (register_framebuffer(&fb_info)<0)
return -EINVAL;
static struct platform_device vesafb_device = {
.name = "vesafb",
};
printk(KERN_INFO "fb%d: %s frame buffer device\n",
fb_info.node, fb_info.fix.id);
return 0;
int __init vesafb_init(void)
{
int ret;
ret = driver_register(&vesafb_driver);
if (!ret) {
ret = platform_device_register(&vesafb_device);
if (ret)
driver_unregister(&vesafb_driver);
}
return ret;
}
/*
......
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