X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fvideo%2Fbw2.c;h=b0b147cb4cb3aae5a0090e38145f8b48d1b0e25b;hb=a3059b12adae868c42629ecf058a94195ef1e958;hp=9248fe1fbb1a45e36e650058c566971f9aa232d3;hpb=806f7bf605bdb0f2ea2253f832943890edb85d83;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c index 9248fe1..b0b147c 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/bw2.c @@ -1,6 +1,6 @@ /* bw2.c: BWTWO frame buffer driver * - * Copyright (C) 2003 David S. Miller (davem@redhat.com) + * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net) * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -17,16 +17,11 @@ #include #include #include +#include #include -#include -#include #include -#ifdef CONFIG_SPARC32 -#include -#endif - #include "sbuslib.h" /* @@ -35,9 +30,8 @@ static int bw2_blank(int, struct fb_info *); -static int bw2_mmap(struct fb_info *, struct file *, struct vm_area_struct *); -static int bw2_ioctl(struct inode *, struct file *, unsigned int, - unsigned long, struct fb_info *); +static int bw2_mmap(struct fb_info *, struct vm_area_struct *); +static int bw2_ioctl(struct fb_info *, unsigned int, unsigned long); /* * Frame buffer operations @@ -60,30 +54,30 @@ static struct fb_ops bw2_ops = { #define BWTWO_REGISTER_OFFSET 0x400000 struct bt_regs { - volatile u32 addr; - volatile u32 color_map; - volatile u32 control; - volatile u32 cursor; + u32 addr; + u32 color_map; + u32 control; + u32 cursor; }; struct bw2_regs { struct bt_regs cmap; - volatile u8 control; - volatile u8 status; - volatile u8 cursor_start; - volatile u8 cursor_end; - volatile u8 h_blank_start; - volatile u8 h_blank_end; - volatile u8 h_sync_start; - volatile u8 h_sync_end; - volatile u8 comp_sync_end; - volatile u8 v_blank_start_high; - volatile u8 v_blank_start_low; - volatile u8 v_blank_end; - volatile u8 v_sync_start; - volatile u8 v_sync_end; - volatile u8 xfer_holdoff_start; - volatile u8 xfer_holdoff_end; + u8 control; + u8 status; + u8 cursor_start; + u8 cursor_end; + u8 h_blank_start; + u8 h_blank_end; + u8 h_sync_start; + u8 h_sync_end; + u8 comp_sync_end; + u8 v_blank_start_high; + u8 v_blank_start_low; + u8 v_blank_end; + u8 v_sync_start; + u8 v_sync_end; + u8 xfer_holdoff_start; + u8 xfer_holdoff_end; }; /* Status Register Constants */ @@ -117,10 +111,7 @@ struct bw2_par { u32 flags; #define BW2_FLAG_BLANKED 0x00000001 - unsigned long physbase; - unsigned long fbsize; - - struct sbus_dev *sdev; + unsigned long which_io; }; /** @@ -169,33 +160,27 @@ static struct sbus_mmap_map bw2_mmap_map[] = { { .size = 0 } }; -static int bw2_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma) +static int bw2_mmap(struct fb_info *info, struct vm_area_struct *vma) { struct bw2_par *par = (struct bw2_par *)info->par; return sbusfb_mmap_helper(bw2_mmap_map, - par->physbase, par->fbsize, - (par->sdev ? - par->sdev->reg_addrs[0].which_io : - 0), + info->fix.smem_start, info->fix.smem_len, + par->which_io, vma); } -static int bw2_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg, struct fb_info *info) +static int bw2_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) { - struct bw2_par *par = (struct bw2_par *) info->par; - return sbusfb_ioctl_helper(cmd, arg, info, - FBTYPE_SUN2BW, 1, par->fbsize); + FBTYPE_SUN2BW, 1, info->fix.smem_len); } /* * Initialisation */ -static void -bw2_init_fix(struct fb_info *info, int linebytes) +static void __devinit bw2_init_fix(struct fb_info *info, int linebytes) { strlcpy(info->fix.id, "bwtwo", sizeof(info->fix.id)); @@ -207,43 +192,44 @@ bw2_init_fix(struct fb_info *info, int linebytes) info->fix.accel = FB_ACCEL_SUN_BWTWO; } -static u8 bw2regs_1600[] __initdata = { +static u8 bw2regs_1600[] __devinitdata = { 0x14, 0x8b, 0x15, 0x28, 0x16, 0x03, 0x17, 0x13, 0x18, 0x7b, 0x19, 0x05, 0x1a, 0x34, 0x1b, 0x2e, 0x1c, 0x00, 0x1d, 0x0a, 0x1e, 0xff, 0x1f, 0x01, 0x10, 0x21, 0 }; -static u8 bw2regs_ecl[] __initdata = { +static u8 bw2regs_ecl[] __devinitdata = { 0x14, 0x65, 0x15, 0x1e, 0x16, 0x04, 0x17, 0x0c, 0x18, 0x5e, 0x19, 0x03, 0x1a, 0xa7, 0x1b, 0x23, 0x1c, 0x00, 0x1d, 0x08, 0x1e, 0xff, 0x1f, 0x01, 0x10, 0x20, 0 }; -static u8 bw2regs_analog[] __initdata = { +static u8 bw2regs_analog[] __devinitdata = { 0x14, 0xbb, 0x15, 0x2b, 0x16, 0x03, 0x17, 0x13, 0x18, 0xb0, 0x19, 0x03, 0x1a, 0xa6, 0x1b, 0x22, 0x1c, 0x01, 0x1d, 0x05, 0x1e, 0xff, 0x1f, 0x01, 0x10, 0x20, 0 }; -static u8 bw2regs_76hz[] __initdata = { +static u8 bw2regs_76hz[] __devinitdata = { 0x14, 0xb7, 0x15, 0x27, 0x16, 0x03, 0x17, 0x0f, 0x18, 0xae, 0x19, 0x03, 0x1a, 0xae, 0x1b, 0x2a, 0x1c, 0x01, 0x1d, 0x09, 0x1e, 0xff, 0x1f, 0x01, 0x10, 0x24, 0 }; -static u8 bw2regs_66hz[] __initdata = { +static u8 bw2regs_66hz[] __devinitdata = { 0x14, 0xbb, 0x15, 0x2b, 0x16, 0x04, 0x17, 0x14, 0x18, 0xae, 0x19, 0x03, 0x1a, 0xa8, 0x1b, 0x24, 0x1c, 0x01, 0x1d, 0x05, 0x1e, 0xff, 0x1f, 0x01, 0x10, 0x20, 0 }; -static void bw2_do_default_mode(struct bw2_par *par, struct fb_info *info, - int *linebytes) +static int __devinit bw2_do_default_mode(struct bw2_par *par, + struct fb_info *info, + int *linebytes) { u8 status, mon; u8 *p; @@ -274,156 +260,146 @@ static void bw2_do_default_mode(struct bw2_par *par, struct fb_info *info, break; case BWTWO_SR_ID_NOCONN: - return; + return 0; default: - prom_printf("bw2: can't handle SR %02x\n", - status); - prom_halt(); + printk(KERN_ERR "bw2: can't handle SR %02x\n", + status); + return -EINVAL; } for ( ; *p; p += 2) { u8 __iomem *regp = &((u8 __iomem *)par->regs)[p[0]]; sbus_writeb(p[1], regp); } + return 0; } -struct all_info { - struct fb_info info; - struct bw2_par par; - struct list_head list; -}; -static LIST_HEAD(bw2_list); - -static void bw2_init_one(struct sbus_dev *sdev) +static int __devinit bw2_probe(struct of_device *op, const struct of_device_id *match) { - struct all_info *all; - struct resource *resp; -#ifdef CONFIG_SUN4 - struct resource res; -#endif - int linebytes; + struct device_node *dp = op->node; + struct fb_info *info; + struct bw2_par *par; + int linebytes, err; - all = kmalloc(sizeof(*all), GFP_KERNEL); - if (!all) { - printk(KERN_ERR "bw2: Cannot allocate memory.\n"); - return; - } - memset(all, 0, sizeof(*all)); - - INIT_LIST_HEAD(&all->list); - - spin_lock_init(&all->par.lock); - all->par.sdev = sdev; - -#ifdef CONFIG_SUN4 - if (!sdev) { - all->par.physbase = sun4_bwtwo_physaddr; - res.start = sun4_bwtwo_physaddr; - res.end = res.start + BWTWO_REGISTER_OFFSET + sizeof(struct bw2_regs) - 1; - res.flags = IORESOURCE_IO; - resp = &res; - all->info.var.xres = all->info.var.xres_virtual = 1152; - all->info.var.yres = all->info.var.yres_virtual = 900; - all->info.var.bits_per_pixel = 1; - linebytes = 1152 / 8; - } else -#else - { - if (!sdev) - BUG(); - all->par.physbase = sdev->reg_addrs[0].phys_addr; - resp = &sdev->resource[0]; - sbusfb_fill_var(&all->info.var, (sdev ? sdev->prom_node : 0), 1); - linebytes = prom_getintdefault(sdev->prom_node, "linebytes", - all->info.var.xres); - } -#endif - all->info.var.red.length = all->info.var.green.length = - all->info.var.blue.length = all->info.var.bits_per_pixel; - all->info.var.red.offset = all->info.var.green.offset = - all->info.var.blue.offset = 0; + info = framebuffer_alloc(sizeof(struct bw2_par), &op->dev); - all->par.regs = sbus_ioremap(resp, BWTWO_REGISTER_OFFSET, - sizeof(struct bw2_regs), "bw2 regs"); + err = -ENOMEM; + if (!info) + goto out_err; + par = info->par; - if (sdev && !prom_getbool(sdev->prom_node, "width")) - bw2_do_default_mode(&all->par, &all->info, &linebytes); + spin_lock_init(&par->lock); - all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); + info->fix.smem_start = op->resource[0].start; + par->which_io = op->resource[0].flags & IORESOURCE_BITS; - all->info.flags = FBINFO_DEFAULT; - all->info.fbops = &bw2_ops; -#if defined(CONFIG_SPARC32) - if (sdev) - all->info.screen_base = (char __iomem *) - prom_getintdefault(sdev->prom_node, "address", 0); -#endif - if (!all->info.screen_base) - all->info.screen_base = - sbus_ioremap(resp, 0, all->par.fbsize, "bw2 ram"); - all->info.par = &all->par; + sbusfb_fill_var(&info->var, dp, 1); + linebytes = of_getintprop_default(dp, "linebytes", + info->var.xres); - bw2_blank(0, &all->info); + info->var.red.length = info->var.green.length = + info->var.blue.length = info->var.bits_per_pixel; + info->var.red.offset = info->var.green.offset = + info->var.blue.offset = 0; - bw2_init_fix(&all->info, linebytes); + par->regs = of_ioremap(&op->resource[0], BWTWO_REGISTER_OFFSET, + sizeof(struct bw2_regs), "bw2 regs"); + if (!par->regs) + goto out_release_fb; - if (register_framebuffer(&all->info) < 0) { - printk(KERN_ERR "bw2: Could not register framebuffer.\n"); - kfree(all); - return; + if (!of_find_property(dp, "width", NULL)) { + err = bw2_do_default_mode(par, info, &linebytes); + if (err) + goto out_unmap_regs; } - list_add(&all->list, &bw2_list); + info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres); + + info->flags = FBINFO_DEFAULT; + info->fbops = &bw2_ops; + + info->screen_base = of_ioremap(&op->resource[0], 0, + info->fix.smem_len, "bw2 ram"); + if (!info->screen_base) + goto out_unmap_regs; + + bw2_blank(FB_BLANK_UNBLANK, info); + + bw2_init_fix(info, linebytes); + + err = register_framebuffer(info); + if (err < 0) + goto out_unmap_screen; + + dev_set_drvdata(&op->dev, info); + + printk(KERN_INFO "%s: bwtwo at %lx:%lx\n", + dp->full_name, par->which_io, info->fix.smem_start); + + return 0; - printk("bw2: bwtwo at %lx:%lx\n", - (long) (sdev ? sdev->reg_addrs[0].which_io : 0), - (long) all->par.physbase); +out_unmap_screen: + of_iounmap(&op->resource[0], info->screen_base, info->fix.smem_len); + +out_unmap_regs: + of_iounmap(&op->resource[0], par->regs, sizeof(struct bw2_regs)); + +out_release_fb: + framebuffer_release(info); + +out_err: + return err; } -int __init bw2_init(void) +static int __devexit bw2_remove(struct of_device *op) { - struct sbus_bus *sbus; - struct sbus_dev *sdev; + struct fb_info *info = dev_get_drvdata(&op->dev); + struct bw2_par *par = info->par; - if (fb_get_options("bw2fb", NULL)) - return -ENODEV; + unregister_framebuffer(info); -#ifdef CONFIG_SUN4 - bw2_init_one(NULL); -#endif - for_all_sbusdev(sdev, sbus) { - if (!strcmp(sdev->prom_name, "bwtwo")) - bw2_init_one(sdev); - } + of_iounmap(&op->resource[0], par->regs, sizeof(struct bw2_regs)); + of_iounmap(&op->resource[0], info->screen_base, info->fix.smem_len); + + framebuffer_release(info); + + dev_set_drvdata(&op->dev, NULL); return 0; } -void __exit bw2_exit(void) -{ - struct list_head *pos, *tmp; +static const struct of_device_id bw2_match[] = { + { + .name = "bwtwo", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, bw2_match); - list_for_each_safe(pos, tmp, &bw2_list) { - struct all_info *all = list_entry(pos, typeof(*all), list); +static struct of_platform_driver bw2_driver = { + .name = "bw2", + .match_table = bw2_match, + .probe = bw2_probe, + .remove = __devexit_p(bw2_remove), +}; - unregister_framebuffer(&all->info); - kfree(all); - } +static int __init bw2_init(void) +{ + if (fb_get_options("bw2fb", NULL)) + return -ENODEV; + + return of_register_driver(&bw2_driver, &of_bus_type); } -int __init -bw2_setup(char *arg) +static void __exit bw2_exit(void) { - /* No cmdline options yet... */ - return 0; + of_unregister_driver(&bw2_driver); } module_init(bw2_init); - -#ifdef MODULE module_exit(bw2_exit); -#endif MODULE_DESCRIPTION("framebuffer driver for BWTWO chipsets"); -MODULE_AUTHOR("David S. Miller "); +MODULE_AUTHOR("David S. Miller "); +MODULE_VERSION("2.0"); MODULE_LICENSE("GPL");