X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fvideo%2Fhgafb.c;h=fb9e67228543b05a1cb6cd7f62703fbd4f032596;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=617734e46688f182e049df70f6d5e74607729f20;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/video/hgafb.c b/drivers/video/hgafb.c index 617734e46..fb9e67228 100644 --- a/drivers/video/hgafb.c +++ b/drivers/video/hgafb.c @@ -36,12 +36,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include @@ -59,16 +59,16 @@ /* Description of the hardware layout */ -static unsigned long hga_vram_base; /* Base of video memory */ +static void __iomem *hga_vram; /* Base of video memory */ static unsigned long hga_vram_len; /* Size of video memory */ #define HGA_ROWADDR(row) ((row%4)*8192 + (row>>2)*90) #define HGA_TXT 0 #define HGA_GFX 1 -static inline u8* rowaddr(struct fb_info *info, u_int row) +static inline u8 __iomem * rowaddr(struct fb_info *info, u_int row) { - return info->screen_base + HGA_ROWADDR(row); + return info->screen_base + HGA_ROWADDR(row); } static int hga_mode = -1; /* 0 = txt, 1 = gfx mode */ @@ -103,11 +103,11 @@ static char *hga_type_name; /* Global locks */ -static spinlock_t hga_reg_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(hga_reg_lock); /* Framebuffer driver structures */ -static struct fb_var_screeninfo hga_default_var = { +static struct fb_var_screeninfo __initdata hga_default_var = { .xres = 720, .yres = 348, .xres_virtual = 720, @@ -121,7 +121,7 @@ static struct fb_var_screeninfo hga_default_var = { .width = -1, }; -static struct fb_fix_screeninfo hga_fix = { +static struct fb_fix_screeninfo __initdata hga_fix = { .id = "HGA", .type = FB_TYPE_PACKED_PIXELS, /* (not sure) */ .visual = FB_VISUAL_MONO10, @@ -131,8 +131,6 @@ static struct fb_fix_screeninfo hga_fix = { .accel = FB_ACCEL_NONE }; -static struct fb_info fb_info; - /* Don't assume that tty1 will be the initial current console. */ static int release_io_port = 0; static int release_io_ports = 0; @@ -176,7 +174,7 @@ static void hga_clear_screen(void) fillchar = 0x00; spin_unlock_irqrestore(&hga_reg_lock, flags); if (fillchar != 0xbf) - isa_memset_io(hga_vram_base, fillchar, hga_vram_len); + memset_io(hga_vram, fillchar, hga_vram_len); } static void hga_txt_mode(void) @@ -244,13 +242,13 @@ static void hga_gfx_mode(void) static void hga_show_logo(struct fb_info *info) { /* - unsigned long dest = hga_vram_base; + void __iomem *dest = hga_vram; char *logo = linux_logo_bw; int x, y; for (y = 134; y < 134 + 80 ; y++) * this needs some cleanup * for (x = 0; x < 10 ; x++) - isa_writeb(~*(logo++),(dest + HGA_ROWADDR(y) + x + 40)); + writeb(~*(logo++),(dest + HGA_ROWADDR(y) + x + 40)); */ } @@ -282,12 +280,13 @@ static void hga_blank(int blank_mode) static int __init hga_card_detect(void) { int count=0; - unsigned long p, q; + void __iomem *p, *q; unsigned short p_save, q_save; - hga_vram_base = 0xb0000; hga_vram_len = 0x08000; + hga_vram = ioremap(0xb0000, hga_vram_len); + if (request_region(0x3b0, 12, "hgafb")) release_io_ports = 1; if (request_region(0x3bf, 1, "hgafb")) @@ -295,14 +294,14 @@ static int __init hga_card_detect(void) /* do a memory check */ - p = hga_vram_base; - q = hga_vram_base + 0x01000; + p = hga_vram; + q = hga_vram + 0x01000; - p_save = isa_readw(p); q_save = isa_readw(q); + p_save = readw(p); q_save = readw(q); - isa_writew(0xaa55, p); if (isa_readw(p) == 0xaa55) count++; - isa_writew(0x55aa, p); if (isa_readw(p) == 0x55aa) count++; - isa_writew(p_save, p); + writew(0xaa55, p); if (readw(p) == 0xaa55) count++; + writew(0x55aa, p); if (readw(p) == 0x55aa) count++; + writew(p_save, p); if (count != 2) { return 0; @@ -411,7 +410,8 @@ static int hgafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, * A zero is returned on success and %-EINVAL for failure. */ -int hgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) +static int hgafb_pan_display(struct fb_var_screeninfo *var, + struct fb_info *info) { if (var->vmode & FB_VMODE_YWRAP) { if (var->yoffset < 0 || @@ -448,10 +448,14 @@ static int hgafb_blank(int blank_mode, struct fb_info *info) return 0; } +/* + * Accel functions + */ +#ifdef CONFIG_FB_HGA_ACCEL static void hgafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { u_int rows, y; - u8 *dest; + u8 __iomem *dest; y = rect->dy; @@ -462,7 +466,7 @@ static void hgafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) //fb_memset(dest, rect->color, (rect->width >> 3)); break; case ROP_XOR: - *dest = ~*dest; + fb_writeb(~(fb_readb(dest)), dest); break; } } @@ -471,7 +475,8 @@ static void hgafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) static void hgafb_copyarea(struct fb_info *info, const struct fb_copyarea *area) { u_int rows, y1, y2; - u8 *src, *dest; + u8 __iomem *src; + u8 __iomem *dest; if (area->dy <= area->sy) { y1 = area->sy; @@ -500,16 +505,22 @@ static void hgafb_copyarea(struct fb_info *info, const struct fb_copyarea *area) static void hgafb_imageblit(struct fb_info *info, const struct fb_image *image) { - u8 *dest, *cdat = (u8 *) image->data; + u8 __iomem *dest; + u8 *cdat = (u8 *) image->data; u_int rows, y = image->dy; u8 d; for (rows = image->height; rows--; y++) { d = *cdat++; dest = rowaddr(info, y) + (image->dx >> 3); - *dest = d; + fb_writeb(d, dest); } } +#else /* !CONFIG_FB_HGA_ACCEL */ +#define hgafb_fillrect cfb_fillrect +#define hgafb_copyarea cfb_copyarea +#define hgafb_imageblit cfb_imageblit +#endif /* CONFIG_FB_HGA_ACCEL */ static struct fb_ops hgafb_ops = { @@ -519,9 +530,9 @@ static struct fb_ops hgafb_ops = { .fb_setcolreg = hgafb_setcolreg, .fb_pan_display = hgafb_pan_display, .fb_blank = hgafb_blank, - .fb_fillrect = cfb_fillrect, //hgafb_fillrect, - .fb_copyarea = cfb_copyarea, //hgafb_copyarea, - .fb_imageblit = cfb_imageblit,//hgafb_imageblit, + .fb_fillrect = hgafb_fillrect, + .fb_copyarea = hgafb_copyarea, + .fb_imageblit = hgafb_imageblit, }; /* ------------------------------------------------------------------------- * @@ -536,57 +547,109 @@ static struct fb_ops hgafb_ops = { * Initialization */ -int __init hgafb_init(void) +static int __init hgafb_probe(struct device *device) { + struct fb_info *info; + if (! hga_card_detect()) { printk(KERN_INFO "hgafb: HGA card not detected.\n"); + if (hga_vram) + iounmap(hga_vram); return -EINVAL; } printk(KERN_INFO "hgafb: %s with %ldK of memory detected.\n", hga_type_name, hga_vram_len/1024); - hga_fix.smem_start = VGA_MAP_MEM(hga_vram_base); - hga_fix.smem_len = hga_vram_len; + info = framebuffer_alloc(0, NULL); + if (!info) { + iounmap(hga_vram); + return -ENOMEM; + } - fb_info.flags = FBINFO_FLAG_DEFAULT; - fb_info.var = hga_default_var; - fb_info.fix = hga_fix; - fb_info.monspecs.hfmin = 0; - fb_info.monspecs.hfmax = 0; - fb_info.monspecs.vfmin = 10000; - fb_info.monspecs.vfmax = 10000; - fb_info.monspecs.dpms = 0; - fb_info.fbops = &hgafb_ops; - fb_info.screen_base = (char *)hga_fix.smem_start; + hga_fix.smem_start = (unsigned long)hga_vram; + hga_fix.smem_len = hga_vram_len; - if (register_framebuffer(&fb_info) < 0) - return -EINVAL; + info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; + info->var = hga_default_var; + info->fix = hga_fix; + info->monspecs.hfmin = 0; + info->monspecs.hfmax = 0; + info->monspecs.vfmin = 10000; + info->monspecs.vfmax = 10000; + info->monspecs.dpms = 0; + info->fbops = &hgafb_ops; + info->screen_base = hga_vram; + + if (register_framebuffer(info) < 0) { + framebuffer_release(info); + iounmap(hga_vram); + return -EINVAL; + } printk(KERN_INFO "fb%d: %s frame buffer device\n", - fb_info.node, fb_info.fix.id); + info->node, info->fix.id); + dev_set_drvdata(device, info); return 0; } - /* - * Setup - */ - -int __init hgafb_setup(char *options) +static int hgafb_remove(struct device *device) { + struct fb_info *info = dev_get_drvdata(device); + + hga_txt_mode(); + hga_clear_screen(); + + if (info) { + unregister_framebuffer(info); + framebuffer_release(info); + } + + iounmap(hga_vram); + + if (release_io_ports) + release_region(0x3b0, 12); + + if (release_io_port) + release_region(0x3bf, 1); + return 0; } -#ifdef MODULE +static struct device_driver hgafb_driver = { + .name = "hgafb", + .bus = &platform_bus_type, + .probe = hgafb_probe, + .remove = hgafb_remove, +}; + +static struct platform_device hgafb_device = { + .name = "hgafb", +}; + +static int __init hgafb_init(void) +{ + int ret; + + if (fb_get_options("hgafb", NULL)) + return -ENODEV; + + ret = driver_register(&hgafb_driver); + + if (!ret) { + ret = platform_device_register(&hgafb_device); + if (ret) + driver_unregister(&hgafb_driver); + } + + return ret; +} + static void __exit hgafb_exit(void) { - hga_txt_mode(); - hga_clear_screen(); - unregister_framebuffer(&fb_info); - if (release_io_ports) release_region(0x3b0, 12); - if (release_io_port) release_region(0x3bf, 1); + platform_device_unregister(&hgafb_device); + driver_unregister(&hgafb_driver); } -#endif /* ------------------------------------------------------------------------- * @@ -598,10 +661,7 @@ MODULE_AUTHOR("Ferenc Bakonyi (fero@drama.obuda.kando.hu)"); MODULE_DESCRIPTION("FBDev driver for Hercules Graphics Adaptor"); MODULE_LICENSE("GPL"); -MODULE_PARM(nologo, "i"); +module_param(nologo, bool, 0); MODULE_PARM_DESC(nologo, "Disables startup logo if != 0 (default=0)"); - -#ifdef MODULE module_init(hgafb_init); module_exit(hgafb_exit); -#endif