[SPARC]: Convert all FB SBUS drivers to of_driver framework.
authorDavid S. Miller <davem@davemloft.net>
Thu, 29 Jun 2006 21:35:52 +0000 (14:35 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Thu, 29 Jun 2006 23:37:18 +0000 (16:37 -0700)
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/video/bw2.c
drivers/video/cg14.c
drivers/video/cg3.c
drivers/video/cg6.c
drivers/video/ffb.c
drivers/video/leo.c
drivers/video/p9100.c
drivers/video/tcx.c

index 6577fdfdfc16ac2050874318dcabc03922ef8a20..c66e3d52cbf3bac8a9c0cf74c7af5651da47cb6a 100644 (file)
@@ -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)
 #include <linux/mm.h>
 
 #include <asm/io.h>
-#include <asm/sbus.h>
 #include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/fbio.h>
 
-#ifdef CONFIG_SPARC32
-#include <asm/sun4paddr.h>
-#endif
-
 #include "sbuslib.h"
 
 /*
@@ -59,30 +56,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,9 +114,8 @@ struct bw2_par {
 #define BW2_FLAG_BLANKED       0x00000001
 
        unsigned long           physbase;
+       unsigned long           which_io;
        unsigned long           fbsize;
-
-       struct sbus_dev         *sdev;
 };
 
 /**
@@ -174,9 +170,7 @@ static int bw2_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
        return sbusfb_mmap_helper(bw2_mmap_map,
                                  par->physbase, par->fbsize,
-                                 (par->sdev ?
-                                  par->sdev->reg_addrs[0].which_io :
-                                  0),
+                                 par->which_io,
                                  vma);
 }
 
@@ -288,139 +282,124 @@ static void bw2_do_default_mode(struct bw2_par *par, struct fb_info *info,
 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_init_one(struct of_device *op)
 {
+       struct device_node *dp = op->node;
        struct all_info *all;
-       struct resource *resp;
-#ifdef CONFIG_SUN4
-       struct resource res;
-#endif
-       int linebytes;
+       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);
+       all = kzalloc(sizeof(*all), GFP_KERNEL);
+       if (!all)
+               return -ENOMEM;
 
        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
-       {
-               BUG_ON(!sdev);
-               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->par.physbase = op->resource[0].start;
+       all->par.which_io = op->resource[0].flags & IORESOURCE_BITS;
+
+       sbusfb_fill_var(&all->info.var, dp->node, 1);
+       linebytes = of_getintprop_default(dp, "linebytes",
+                                         all->info.var.xres);
+
        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;
 
-       all->par.regs = sbus_ioremap(resp, BWTWO_REGISTER_OFFSET,
-                            sizeof(struct bw2_regs), "bw2 regs");
+       all->par.regs = of_ioremap(&op->resource[0], BWTWO_REGISTER_OFFSET,
+                                  sizeof(struct bw2_regs), "bw2 regs");
 
-       if (sdev && !prom_getbool(sdev->prom_node, "width"))
+       if (!of_find_property(dp, "width", NULL))
                bw2_do_default_mode(&all->par, &all->info, &linebytes);
 
        all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
 
        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.screen_base =
+               sbus_ioremap(&op->resource[0], 0, all->par.fbsize, "bw2 ram");
        all->info.par = &all->par;
 
        bw2_blank(0, &all->info);
 
        bw2_init_fix(&all->info, linebytes);
 
-       if (register_framebuffer(&all->info) < 0) {
-               printk(KERN_ERR "bw2: Could not register framebuffer.\n");
+       err= register_framebuffer(&all->info);
+       if (err < 0) {
+               of_iounmap(all->par.regs, sizeof(struct bw2_regs));
+               of_iounmap(all->info.screen_base, all->par.fbsize);
                kfree(all);
-               return;
+               return err;
        }
 
-       list_add(&all->list, &bw2_list);
+       dev_set_drvdata(&op->dev, all);
+
+       printk("%s: bwtwo at %lx:%lx\n",
+              dp->full_name,
+              all->par.which_io, all->par.physbase);
 
-       printk("bw2: bwtwo at %lx:%lx\n",
-              (long) (sdev ? sdev->reg_addrs[0].which_io : 0),
-              (long) all->par.physbase);
+       return 0;
 }
 
-int __init bw2_init(void)
+static int __devinit bw2_probe(struct of_device *dev, const struct of_device_id *match)
 {
-       struct sbus_bus *sbus;
-       struct sbus_dev *sdev;
+       struct of_device *op = to_of_device(&dev->dev);
 
-       if (fb_get_options("bw2fb", NULL))
-               return -ENODEV;
+       return bw2_init_one(op);
+}
 
-#ifdef CONFIG_SUN4
-       bw2_init_one(NULL);
-#endif
-       for_all_sbusdev(sdev, sbus) {
-               if (!strcmp(sdev->prom_name, "bwtwo"))
-                       bw2_init_one(sdev);
-       }
+static int __devexit bw2_remove(struct of_device *dev)
+{
+       struct all_info *all = dev_get_drvdata(&dev->dev);
+
+       unregister_framebuffer(&all->info);
+
+       of_iounmap(all->par.regs, sizeof(struct bw2_regs));
+       of_iounmap(all->info.screen_base, all->par.fbsize);
+
+       kfree(all);
+
+       dev_set_drvdata(&dev->dev, NULL);
 
        return 0;
 }
 
-void __exit bw2_exit(void)
-{
-       struct list_head *pos, *tmp;
+static 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;
+       return of_unregister_driver(&bw2_driver);
 }
 
-module_init(bw2_init);
 
-#ifdef MODULE
+module_init(bw2_init);
 module_exit(bw2_exit);
-#endif
 
 MODULE_DESCRIPTION("framebuffer driver for BWTWO chipsets");
-MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_VERSION("2.0");
 MODULE_LICENSE("GPL");
index 63b6c79c8a0a98195c00a59cfed6387d57f61f15..7f926c619b61790558c53918df181477c565c3d9 100644 (file)
@@ -1,6 +1,6 @@
 /* cg14.c: CGFOURTEEN 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) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
  *
@@ -18,8 +18,8 @@
 #include <linux/mm.h>
 
 #include <asm/io.h>
-#include <asm/sbus.h>
-#include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -99,73 +99,73 @@ static struct fb_ops cg14_ops = {
 #define CG14_MCR_PIXMODE_32            3
 
 struct cg14_regs{
-       volatile u8 mcr;        /* Master Control Reg */
-       volatile u8 ppr;        /* Packed Pixel Reg */
-       volatile u8 tms[2];     /* Test Mode Status Regs */
-       volatile u8 msr;        /* Master Status Reg */
-       volatile u8 fsr;        /* Fault Status Reg */
-       volatile u8 rev;        /* Revision & Impl */
-       volatile u8 ccr;        /* Clock Control Reg */
-       volatile u32 tmr;       /* Test Mode Read Back */
-       volatile u8 mod;        /* Monitor Operation Data Reg */
-       volatile u8 acr;        /* Aux Control */
+       u8 mcr; /* Master Control Reg */
+       u8 ppr; /* Packed Pixel Reg */
+       u8 tms[2];      /* Test Mode Status Regs */
+       u8 msr; /* Master Status Reg */
+       u8 fsr; /* Fault Status Reg */
+       u8 rev; /* Revision & Impl */
+       u8 ccr; /* Clock Control Reg */
+       u32 tmr;        /* Test Mode Read Back */
+       u8 mod; /* Monitor Operation Data Reg */
+       u8 acr; /* Aux Control */
        u8 xxx0[6];
-       volatile u16 hct;       /* Hor Counter */
-       volatile u16 vct;       /* Vert Counter */
-       volatile u16 hbs;       /* Hor Blank Start */
-       volatile u16 hbc;       /* Hor Blank Clear */
-       volatile u16 hss;       /* Hor Sync Start */
-       volatile u16 hsc;       /* Hor Sync Clear */
-       volatile u16 csc;       /* Composite Sync Clear */
-       volatile u16 vbs;       /* Vert Blank Start */
-       volatile u16 vbc;       /* Vert Blank Clear */
-       volatile u16 vss;       /* Vert Sync Start */
-       volatile u16 vsc;       /* Vert Sync Clear */
-       volatile u16 xcs;
-       volatile u16 xcc;
-       volatile u16 fsa;       /* Fault Status Address */
-       volatile u16 adr;       /* Address Registers */
+       u16 hct;        /* Hor Counter */
+       u16 vct;        /* Vert Counter */
+       u16 hbs;        /* Hor Blank Start */
+       u16 hbc;        /* Hor Blank Clear */
+       u16 hss;        /* Hor Sync Start */
+       u16 hsc;        /* Hor Sync Clear */
+       u16 csc;        /* Composite Sync Clear */
+       u16 vbs;        /* Vert Blank Start */
+       u16 vbc;        /* Vert Blank Clear */
+       u16 vss;        /* Vert Sync Start */
+       u16 vsc;        /* Vert Sync Clear */
+       u16 xcs;
+       u16 xcc;
+       u16 fsa;        /* Fault Status Address */
+       u16 adr;        /* Address Registers */
        u8 xxx1[0xce];
-       volatile u8 pcg[0x100]; /* Pixel Clock Generator */
-       volatile u32 vbr;       /* Frame Base Row */
-       volatile u32 vmcr;      /* VBC Master Control */
-       volatile u32 vcr;       /* VBC refresh */
-       volatile u32 vca;       /* VBC Config */
+       u8 pcg[0x100]; /* Pixel Clock Generator */
+       u32 vbr;        /* Frame Base Row */
+       u32 vmcr;       /* VBC Master Control */
+       u32 vcr;        /* VBC refresh */
+       u32 vca;        /* VBC Config */
 };
 
 #define CG14_CCR_ENABLE        0x04
 #define CG14_CCR_SELECT 0x02   /* HW/Full screen */
 
 struct cg14_cursor {
-       volatile u32 cpl0[32];  /* Enable plane 0 */
-       volatile u32 cpl1[32];  /* Color selection plane */
-       volatile u8 ccr;        /* Cursor Control Reg */
+       u32 cpl0[32];   /* Enable plane 0 */
+       u32 cpl1[32];  /* Color selection plane */
+       u8 ccr; /* Cursor Control Reg */
        u8 xxx0[3];
-       volatile u16 cursx;     /* Cursor x,y position */
-       volatile u16 cursy;     /* Cursor x,y position */
-       volatile u32 color0;
-       volatile u32 color1;
+       u16 cursx;      /* Cursor x,y position */
+       u16 cursy;      /* Cursor x,y position */
+       u32 color0;
+       u32 color1;
        u32 xxx1[0x1bc];
-       volatile u32 cpl0i[32]; /* Enable plane 0 autoinc */
-       volatile u32 cpl1i[32]; /* Color selection autoinc */
+       u32 cpl0i[32];  /* Enable plane 0 autoinc */
+       u32 cpl1i[32]; /* Color selection autoinc */
 };
 
 struct cg14_dac {
-       volatile u8 addr;       /* Address Register */
+       u8 addr;        /* Address Register */
        u8 xxx0[255];
-       volatile u8 glut;       /* Gamma table */
+       u8 glut;        /* Gamma table */
        u8 xxx1[255];
-       volatile u8 select;     /* Register Select */
+       u8 select;      /* Register Select */
        u8 xxx2[255];
-       volatile u8 mode;       /* Mode Register */
+       u8 mode;        /* Mode Register */
 };
 
 struct cg14_xlut{
-       volatile u8 x_xlut [256];
-       volatile u8 x_xlutd [256];
+       u8 x_xlut [256];
+       u8 x_xlutd [256];
        u8 xxx0[0x600];
-       volatile u8 x_xlut_inc [256];
-       volatile u8 x_xlutd_inc [256];
+       u8 x_xlut_inc [256];
+       u8 x_xlutd_inc [256];
 };
 
 /* Color look up table (clut) */
@@ -204,7 +204,6 @@ struct cg14_par {
 
        int                     mode;
        int                     ramsize;
-       struct sbus_dev         *sdev;
 };
 
 static void __cg14_reset(struct cg14_par *par)
@@ -355,14 +354,9 @@ static int cg14_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
  *  Initialisation
  */
 
-static void cg14_init_fix(struct fb_info *info, int linebytes)
+static void cg14_init_fix(struct fb_info *info, int linebytes, struct device_node *dp)
 {
-       struct cg14_par *par = (struct cg14_par *)info->par;
-       const char *name;
-
-       name = "cgfourteen";
-       if (par->sdev)
-               name = par->sdev->prom_name;
+       const char *name = dp->name;
 
        strlcpy(info->fix.id, name, sizeof(info->fix.id));
 
@@ -456,98 +450,81 @@ static struct sbus_mmap_map __cg14_mmap_map[CG14_MMAP_ENTRIES] __initdata = {
 struct all_info {
        struct fb_info info;
        struct cg14_par par;
-       struct list_head list;
 };
-static LIST_HEAD(cg14_list);
 
-static void cg14_init_one(struct sbus_dev *sdev, int node, int parent_node)
+static void cg14_unmap_regs(struct all_info *all)
 {
-       struct all_info *all;
-       unsigned long phys, rphys;
-       u32 bases[6];
-       int is_8mb, linebytes, i;
-
-       if (!sdev) {
-               if (prom_getproperty(node, "address",
-                                    (char *) &bases[0], sizeof(bases)) <= 0
-                   || !bases[0]) {
-                       printk(KERN_ERR "cg14: Device is not mapped.\n");
-                       return;
-               }
-               if (__get_iospace(bases[0]) != __get_iospace(bases[1])) {
-                       printk(KERN_ERR "cg14: I/O spaces don't match.\n");
-                       return;
-               }
-       }
+       if (all->par.regs)
+               of_iounmap(all->par.regs, sizeof(struct cg14_regs));
+       if (all->par.clut)
+               of_iounmap(all->par.clut, sizeof(struct cg14_clut));
+       if (all->par.cursor)
+               of_iounmap(all->par.cursor, sizeof(struct cg14_cursor));
+       if (all->info.screen_base)
+               of_iounmap(all->info.screen_base, all->par.fbsize);
+}
 
-       all = kmalloc(sizeof(*all), GFP_KERNEL);
-       if (!all) {
-               printk(KERN_ERR "cg14: Cannot allocate memory.\n");
-               return;
-       }
-       memset(all, 0, sizeof(*all));
+static int __devinit cg14_init_one(struct of_device *op)
+{
+       struct device_node *dp = op->node;
+       struct all_info *all;
+       int is_8mb, linebytes, i, err;
 
-       INIT_LIST_HEAD(&all->list);
+       all = kzalloc(sizeof(*all), GFP_KERNEL);
+       if (!all)
+               return -ENOMEM;
 
        spin_lock_init(&all->par.lock);
 
-       sbusfb_fill_var(&all->info.var, node, 8);
+       sbusfb_fill_var(&all->info.var, dp->node, 8);
        all->info.var.red.length = 8;
        all->info.var.green.length = 8;
        all->info.var.blue.length = 8;
 
-       linebytes = prom_getintdefault(node, "linebytes",
-                                      all->info.var.xres);
+       linebytes = of_getintprop_default(dp, "linebytes",
+                                         all->info.var.xres);
        all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
 
-       all->par.sdev = sdev;
-       if (sdev) {
-               rphys = sdev->reg_addrs[0].phys_addr;
-               all->par.physbase = phys = sdev->reg_addrs[1].phys_addr;
-               all->par.iospace = sdev->reg_addrs[0].which_io;
-
-               all->par.regs = sbus_ioremap(&sdev->resource[0], 0,
-                                    sizeof(struct cg14_regs),
-                                    "cg14 regs");
-               all->par.clut = sbus_ioremap(&sdev->resource[0], CG14_CLUT1,
-                                    sizeof(struct cg14_clut),
-                                    "cg14 clut");
-               all->par.cursor = sbus_ioremap(&sdev->resource[0], CG14_CURSORREGS,
-                                    sizeof(struct cg14_cursor),
-                                    "cg14 cursor");
-               all->info.screen_base = sbus_ioremap(&sdev->resource[1], 0,
-                                    all->par.fbsize, "cg14 ram");
+       if (!strcmp(dp->parent->name, "sbus") ||
+           !strcmp(dp->parent->name, "sbi")) {
+               all->par.physbase = op->resource[0].start;
+               all->par.iospace = op->resource[0].flags & IORESOURCE_BITS;
        } else {
-               rphys = __get_phys(bases[0]);
-               all->par.physbase = phys = __get_phys(bases[1]);
-               all->par.iospace = __get_iospace(bases[0]);
-               all->par.regs = (struct cg14_regs __iomem *)(unsigned long)bases[0];
-               all->par.clut = (struct cg14_clut __iomem *)((unsigned long)bases[0] +
-                                                    CG14_CLUT1);
-               all->par.cursor =
-                       (struct cg14_cursor __iomem *)((unsigned long)bases[0] +
-                                              CG14_CURSORREGS);
-
-               all->info.screen_base = (char __iomem *)(unsigned long)bases[1];
+               all->par.physbase = op->resource[1].start;
+               all->par.iospace = op->resource[0].flags & IORESOURCE_BITS;
        }
 
-       prom_getproperty(node, "reg", (char *) &bases[0], sizeof(bases));
-       is_8mb = (bases[5] == 0x800000);
+       all->par.regs = of_ioremap(&op->resource[0], 0,
+                                  sizeof(struct cg14_regs), "cg14 regs");
+       all->par.clut = of_ioremap(&op->resource[0], CG14_CLUT1,
+                                  sizeof(struct cg14_clut), "cg14 clut");
+       all->par.cursor = of_ioremap(&op->resource[0], CG14_CURSORREGS,
+                                  sizeof(struct cg14_cursor), "cg14 cursor");
 
-       if (sizeof(all->par.mmap_map) != sizeof(__cg14_mmap_map)) {
-               extern void __cg14_mmap_sized_wrongly(void);
+       all->info.screen_base = of_ioremap(&op->resource[1], 0,
+                                          all->par.fbsize, "cg14 ram");
 
-               __cg14_mmap_sized_wrongly();
-       }
+       if (!all->par.regs || !all->par.clut || !all->par.cursor ||
+           !all->info.screen_base)
+               cg14_unmap_regs(all);
+
+       is_8mb = (((op->resource[1].end - op->resource[1].start) + 1) ==
+                 (8 * 1024 * 1024));
+
+       BUILD_BUG_ON(sizeof(all->par.mmap_map) != sizeof(__cg14_mmap_map));
                
-       memcpy(&all->par.mmap_map, &__cg14_mmap_map, sizeof(all->par.mmap_map));
+       memcpy(&all->par.mmap_map, &__cg14_mmap_map,
+              sizeof(all->par.mmap_map));
+
        for (i = 0; i < CG14_MMAP_ENTRIES; i++) {
                struct sbus_mmap_map *map = &all->par.mmap_map[i];
 
                if (!map->size)
                        break;
                if (map->poff & 0x80000000)
-                       map->poff = (map->poff & 0x7fffffff) + rphys - phys;
+                       map->poff = (map->poff & 0x7fffffff) +
+                               (op->resource[0].start -
+                                op->resource[1].start);
                if (is_8mb &&
                    map->size >= 0x100000 &&
                    map->size <= 0x400000)
@@ -564,84 +541,87 @@ static void cg14_init_one(struct sbus_dev *sdev, int node, int parent_node)
        __cg14_reset(&all->par);
 
        if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
-               printk(KERN_ERR "cg14: Could not allocate color map.\n");
+               cg14_unmap_regs(all);
                kfree(all);
-               return;
+               return -ENOMEM;
        }
        fb_set_cmap(&all->info.cmap, &all->info);
 
-       cg14_init_fix(&all->info, linebytes);
+       cg14_init_fix(&all->info, linebytes, dp);
 
-       if (register_framebuffer(&all->info) < 0) {
-               printk(KERN_ERR "cg14: Could not register framebuffer.\n");
+       err = register_framebuffer(&all->info);
+       if (err < 0) {
                fb_dealloc_cmap(&all->info.cmap);
+               cg14_unmap_regs(all);
                kfree(all);
-               return;
+               return err;
        }
 
-       list_add(&all->list, &cg14_list);
+       dev_set_drvdata(&op->dev, all);
 
-       printk("cg14: cgfourteen at %lx:%lx, %dMB\n",
-              all->par.iospace, all->par.physbase, all->par.ramsize >> 20);
+       printk("%s: cgfourteen at %lx:%lx, %dMB\n",
+              dp->full_name,
+              all->par.iospace, all->par.physbase,
+              all->par.ramsize >> 20);
 
+       return 0;
 }
 
-int __init cg14_init(void)
+static int __devinit cg14_probe(struct of_device *dev, const struct of_device_id *match)
 {
-       struct sbus_bus *sbus;
-       struct sbus_dev *sdev;
+       struct of_device *op = to_of_device(&dev->dev);
 
-       if (fb_get_options("cg14fb", NULL))
-               return -ENODEV;
+       return cg14_init_one(op);
+}
 
-#ifdef CONFIG_SPARC32
-       {
-               int root, node;
-
-               root = prom_getchild(prom_root_node);
-               root = prom_searchsiblings(root, "obio");
-               if (root) {
-                       node = prom_searchsiblings(prom_getchild(root),
-                                                  "cgfourteen");
-                       if (node)
-                               cg14_init_one(NULL, node, root);
-               }
-       }
-#endif
-       for_all_sbusdev(sdev, sbus) {
-               if (!strcmp(sdev->prom_name, "cgfourteen"))
-                       cg14_init_one(sdev, sdev->prom_node, sbus->prom_node);
-       }
+static int __devexit cg14_remove(struct of_device *dev)
+{
+       struct all_info *all = dev_get_drvdata(&dev->dev);
+
+       unregister_framebuffer(&all->info);
+       fb_dealloc_cmap(&all->info.cmap);
+
+       cg14_unmap_regs(all);
+
+       kfree(all);
+
+       dev_set_drvdata(&dev->dev, NULL);
 
        return 0;
 }
 
-void __exit cg14_exit(void)
-{
-       struct list_head *pos, *tmp;
+static struct of_device_id cg14_match[] = {
+       {
+               .name = "cgfourteen",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, cg14_match);
 
-       list_for_each_safe(pos, tmp, &cg14_list) {
-               struct all_info *all = list_entry(pos, typeof(*all), list);
+static struct of_platform_driver cg14_driver = {
+       .name           = "cg14",
+       .match_table    = cg14_match,
+       .probe          = cg14_probe,
+       .remove         = __devexit_p(cg14_remove),
+};
 
-               unregister_framebuffer(&all->info);
-               fb_dealloc_cmap(&all->info.cmap);
-               kfree(all);
-       }
+int __init cg14_init(void)
+{
+       if (fb_get_options("cg14fb", NULL))
+               return -ENODEV;
+
+       return of_register_driver(&cg14_driver, &of_bus_type);
 }
 
-int __init
-cg14_setup(char *arg)
+void __exit cg14_exit(void)
 {
-       /* No cmdline options yet... */
-       return 0;
+       of_unregister_driver(&cg14_driver);
 }
 
 module_init(cg14_init);
-
-#ifdef MODULE
 module_exit(cg14_exit);
-#endif
 
 MODULE_DESCRIPTION("framebuffer driver for CGfourteen chipsets");
-MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_VERSION("2.0");
 MODULE_LICENSE("GPL");
index 3de6e1b5ab2f4008efd29b32805c9e3bd874dec1..9c8c753ef4541de8710966e9c87480bc407b5faf 100644 (file)
@@ -1,6 +1,6 @@
 /* cg3.c: CGTHREE 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)
@@ -19,8 +19,9 @@
 #include <linux/mm.h>
 
 #include <asm/io.h>
-#include <asm/sbus.h>
 #include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -80,30 +81,30 @@ enum cg3_type {
 };
 
 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 cg3_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;
 };
 
 /* Offset of interesting structures in the OBIO space */
@@ -120,9 +121,8 @@ struct cg3_par {
 #define CG3_FLAG_RDI           0x00000002
 
        unsigned long           physbase;
+       unsigned long           which_io;
        unsigned long           fbsize;
-
-       struct sbus_dev         *sdev;
 };
 
 /**
@@ -235,7 +235,7 @@ static int cg3_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
        return sbusfb_mmap_helper(cg3_mmap_map,
                                  par->physbase, par->fbsize,
-                                 par->sdev->reg_addrs[0].which_io,
+                                 par->which_io,
                                  vma);
 }
 
@@ -252,11 +252,9 @@ static int cg3_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
  */
 
 static void
-cg3_init_fix(struct fb_info *info, int linebytes)
+cg3_init_fix(struct fb_info *info, int linebytes, struct device_node *dp)
 {
-       struct cg3_par *par = (struct cg3_par *)info->par;
-
-       strlcpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id));
+       strlcpy(info->fix.id, dp->name, sizeof(info->fix.id));
 
        info->fix.type = FB_TYPE_PACKED_PIXELS;
        info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
@@ -267,16 +265,15 @@ cg3_init_fix(struct fb_info *info, int linebytes)
 }
 
 static void cg3_rdi_maybe_fixup_var(struct fb_var_screeninfo *var,
-                                   struct sbus_dev *sdev)
+                                   struct device_node *dp)
 {
-       char buffer[40];
+       char *params;
        char *p;
        int ww, hh;
 
-       *buffer = 0;
-       prom_getstring(sdev->prom_node, "params", buffer, sizeof(buffer));
-       if (*buffer) {
-               ww = simple_strtoul(buffer, &p, 10);
+       params = of_get_property(dp, "params", NULL);
+       if (params) {
+               ww = simple_strtoul(params, &p, 10);
                if (ww && *p == 'x') {
                        hh = simple_strtoul(p + 1, &p, 10);
                        if (hh && *p == '-') {
@@ -348,11 +345,11 @@ static void cg3_do_default_mode(struct cg3_par *par)
                sbus_writeb(p[1], regp);
        }
        for (p = cg3_dacvals; *p; p += 2) {
-               volatile u8 __iomem *regp;
+               u8 __iomem *regp;
 
-               regp = (volatile u8 __iomem *)&par->regs->cmap.addr;
+               regp = (u8 __iomem *)&par->regs->cmap.addr;
                sbus_writeb(p[0], regp);
-               regp = (volatile u8 __iomem *)&par->regs->cmap.control;
+               regp = (u8 __iomem *)&par->regs->cmap.control;
                sbus_writeb(p[1], regp);
        }
 }
@@ -360,129 +357,137 @@ static void cg3_do_default_mode(struct cg3_par *par)
 struct all_info {
        struct fb_info info;
        struct cg3_par par;
-       struct list_head list;
 };
-static LIST_HEAD(cg3_list);
 
-static void cg3_init_one(struct sbus_dev *sdev)
+static int __devinit cg3_init_one(struct of_device *op)
 {
+       struct device_node *dp = op->node;
        struct all_info *all;
-       int linebytes;
-
-       all = kmalloc(sizeof(*all), GFP_KERNEL);
-       if (!all) {
-               printk(KERN_ERR "cg3: Cannot allocate memory.\n");
-               return;
-       }
-       memset(all, 0, sizeof(*all));
+       int linebytes, err;
 
-       INIT_LIST_HEAD(&all->list);
+       all = kzalloc(sizeof(*all), GFP_KERNEL);
+       if (!all)
+               return -ENOMEM;
 
        spin_lock_init(&all->par.lock);
-       all->par.sdev = sdev;
 
-       all->par.physbase = sdev->reg_addrs[0].phys_addr;
+       all->par.physbase = op->resource[0].start;
+       all->par.which_io = op->resource[0].flags & IORESOURCE_BITS;
 
-       sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+       sbusfb_fill_var(&all->info.var, dp->node, 8);
        all->info.var.red.length = 8;
        all->info.var.green.length = 8;
        all->info.var.blue.length = 8;
-       if (!strcmp(sdev->prom_name, "cgRDI"))
+       if (!strcmp(dp->name, "cgRDI"))
                all->par.flags |= CG3_FLAG_RDI;
        if (all->par.flags & CG3_FLAG_RDI)
-               cg3_rdi_maybe_fixup_var(&all->info.var, sdev);
+               cg3_rdi_maybe_fixup_var(&all->info.var, dp);
 
-       linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
-                                      all->info.var.xres);
+       linebytes = of_getintprop_default(dp, "linebytes",
+                                         all->info.var.xres);
        all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
 
-       all->par.regs = sbus_ioremap(&sdev->resource[0], CG3_REGS_OFFSET,
-                            sizeof(struct cg3_regs), "cg3 regs");
+       all->par.regs = of_ioremap(&op->resource[0], CG3_REGS_OFFSET,
+                                  sizeof(struct cg3_regs), "cg3 regs");
 
        all->info.flags = FBINFO_DEFAULT;
        all->info.fbops = &cg3_ops;
-#ifdef CONFIG_SPARC32
-       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(&sdev->resource[0], CG3_RAM_OFFSET,
-                                    all->par.fbsize, "cg3 ram");
+       all->info.screen_base =
+               of_ioremap(&op->resource[0], CG3_RAM_OFFSET,
+                          all->par.fbsize, "cg3 ram");
        all->info.par = &all->par;
 
        cg3_blank(0, &all->info);
 
-       if (!prom_getbool(sdev->prom_node, "width"))
+       if (!of_find_property(dp, "width", NULL))
                cg3_do_default_mode(&all->par);
 
        if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
-               printk(KERN_ERR "cg3: Could not allocate color map.\n");
+               of_iounmap(all->par.regs, sizeof(struct cg3_regs));
+               of_iounmap(all->info.screen_base, all->par.fbsize);
                kfree(all);
-               return;
+               return -ENOMEM;
        }
        fb_set_cmap(&all->info.cmap, &all->info);
 
-       cg3_init_fix(&all->info, linebytes);
+       cg3_init_fix(&all->info, linebytes, dp);
 
-       if (register_framebuffer(&all->info) < 0) {
-               printk(KERN_ERR "cg3: Could not register framebuffer.\n");
+       err = register_framebuffer(&all->info);
+       if (err < 0) {
                fb_dealloc_cmap(&all->info.cmap);
+               of_iounmap(all->par.regs, sizeof(struct cg3_regs));
+               of_iounmap(all->info.screen_base, all->par.fbsize);
                kfree(all);
-               return;
+               return err;
        }
 
-       list_add(&all->list, &cg3_list);
+       dev_set_drvdata(&op->dev, all);
+
+       printk("%s: cg3 at %lx:%lx\n",
+              dp->full_name, all->par.which_io, all->par.physbase);
 
-       printk("cg3: %s at %lx:%lx\n",
-              sdev->prom_name,
-              (long) sdev->reg_addrs[0].which_io,
-              (long) sdev->reg_addrs[0].phys_addr);
+       return 0;
 }
 
-int __init cg3_init(void)
+static int __devinit cg3_probe(struct of_device *dev, const struct of_device_id *match)
 {
-       struct sbus_bus *sbus;
-       struct sbus_dev *sdev;
+       struct of_device *op = to_of_device(&dev->dev);
 
-       if (fb_get_options("cg3fb", NULL))
-               return -ENODEV;
+       return cg3_init_one(op);
+}
 
-       for_all_sbusdev(sdev, sbus) {
-               if (!strcmp(sdev->prom_name, "cgthree") ||
-                   !strcmp(sdev->prom_name, "cgRDI"))
-                       cg3_init_one(sdev);
-       }
+static int __devexit cg3_remove(struct of_device *dev)
+{
+       struct all_info *all = dev_get_drvdata(&dev->dev);
+
+       unregister_framebuffer(&all->info);
+       fb_dealloc_cmap(&all->info.cmap);
+
+       of_iounmap(all->par.regs, sizeof(struct cg3_regs));
+       of_iounmap(all->info.screen_base, all->par.fbsize);
+
+       kfree(all);
+
+       dev_set_drvdata(&dev->dev, NULL);
 
        return 0;
 }
 
-void __exit cg3_exit(void)
-{
-       struct list_head *pos, *tmp;
+static struct of_device_id cg3_match[] = {
+       {
+               .name = "cgthree",
+       },
+       {
+               .name = "cgRDI",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, cg3_match);
 
-       list_for_each_safe(pos, tmp, &cg3_list) {
-               struct all_info *all = list_entry(pos, typeof(*all), list);
+static struct of_platform_driver cg3_driver = {
+       .name           = "cg3",
+       .match_table    = cg3_match,
+       .probe          = cg3_probe,
+       .remove         = __devexit_p(cg3_remove),
+};
 
-               unregister_framebuffer(&all->info);
-               fb_dealloc_cmap(&all->info.cmap);
-               kfree(all);
-       }
+static int __init cg3_init(void)
+{
+       if (fb_get_options("cg3fb", NULL))
+               return -ENODEV;
+
+       return of_register_driver(&cg3_driver, &of_bus_type);
 }
 
-int __init
-cg3_setup(char *arg)
+static void __exit cg3_exit(void)
 {
-       /* No cmdline options yet... */
-       return 0;
+       of_unregister_driver(&cg3_driver);
 }
 
 module_init(cg3_init);
-
-#ifdef MODULE
 module_exit(cg3_exit);
-#endif
 
 MODULE_DESCRIPTION("framebuffer driver for CGthree chipsets");
-MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_VERSION("2.0");
 MODULE_LICENSE("GPL");
index 7aab91ead6818ee70d7484aedacc001a6ecd8739..64146be2eeb0c746a65ca96799ff5850a7477794 100644 (file)
@@ -1,6 +1,6 @@
 /* cg6.c: CGSIX (GX, GXplus, TGX) 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) 1996 Eddie C. Dost (ecd@skynet.be)
@@ -19,8 +19,8 @@
 #include <linux/mm.h>
 
 #include <asm/io.h>
-#include <asm/sbus.h>
-#include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -164,89 +164,89 @@ static struct fb_ops cg6_ops = {
 
 /* The contents are unknown */
 struct cg6_tec {
-       volatile int tec_matrix;
-       volatile int tec_clip;
-       volatile int tec_vdc;
+       int tec_matrix;
+       int tec_clip;
+       int tec_vdc;
 };
 
 struct cg6_thc {
-        uint thc_pad0[512];
-       volatile uint thc_hs;           /* hsync timing */
-       volatile uint thc_hsdvs;
-       volatile uint thc_hd;
-       volatile uint thc_vs;           /* vsync timing */
-       volatile uint thc_vd;
-       volatile uint thc_refresh;
-       volatile uint thc_misc;
-       uint thc_pad1[56];
-       volatile uint thc_cursxy;       /* cursor x,y position (16 bits each) */
-       volatile uint thc_cursmask[32]; /* cursor mask bits */
-       volatile uint thc_cursbits[32]; /* what to show where mask enabled */
+        u32 thc_pad0[512];
+       u32 thc_hs;             /* hsync timing */
+       u32 thc_hsdvs;
+       u32 thc_hd;
+       u32 thc_vs;             /* vsync timing */
+       u32 thc_vd;
+       u32 thc_refresh;
+       u32 thc_misc;
+       u32 thc_pad1[56];
+       u32 thc_cursxy; /* cursor x,y position (16 bits each) */
+       u32 thc_cursmask[32];   /* cursor mask bits */
+       u32 thc_cursbits[32];   /* what to show where mask enabled */
 };
 
 struct cg6_fbc {
-       u32             xxx0[1];
-       volatile u32    mode;
-       volatile u32    clip;
-       u32             xxx1[1];            
-       volatile u32    s;
-       volatile u32    draw;
-       volatile u32    blit;
-       volatile u32    font;
-       u32             xxx2[24];
-       volatile u32    x0, y0, z0, color0;
-       volatile u32    x1, y1, z1, color1;
-       volatile u32    x2, y2, z2, color2;
-       volatile u32    x3, y3, z3, color3;
-       volatile u32    offx, offy;
-       u32             xxx3[2];
-       volatile u32    incx, incy;
-       u32             xxx4[2];
-       volatile u32    clipminx, clipminy;
-       u32             xxx5[2];
-       volatile u32    clipmaxx, clipmaxy;
-       u32             xxx6[2];
-       volatile u32    fg;
-       volatile u32    bg;
-       volatile u32    alu;
-       volatile u32    pm;
-       volatile u32    pixelm;
-       u32             xxx7[2];
-       volatile u32    patalign;
-       volatile u32    pattern[8];
-       u32             xxx8[432];
-       volatile u32    apointx, apointy, apointz;
-       u32             xxx9[1];
-       volatile u32    rpointx, rpointy, rpointz;
-       u32             xxx10[5];
-       volatile u32    pointr, pointg, pointb, pointa;
-       volatile u32    alinex, aliney, alinez;
-       u32             xxx11[1];
-       volatile u32    rlinex, rliney, rlinez;
-       u32             xxx12[5];
-       volatile u32    liner, lineg, lineb, linea;
-       volatile u32    atrix, atriy, atriz;
-       u32             xxx13[1];
-       volatile u32    rtrix, rtriy, rtriz;
-       u32             xxx14[5];
-       volatile u32    trir, trig, trib, tria;
-       volatile u32    aquadx, aquady, aquadz;
-       u32             xxx15[1];
-       volatile u32    rquadx, rquady, rquadz;
-       u32             xxx16[5];
-       volatile u32    quadr, quadg, quadb, quada;
-       volatile u32    arectx, arecty, arectz;
-       u32             xxx17[1];
-       volatile u32    rrectx, rrecty, rrectz;
-       u32             xxx18[5];
-       volatile u32    rectr, rectg, rectb, recta;
+       u32     xxx0[1];
+       u32     mode;
+       u32     clip;
+       u32     xxx1[1];            
+       u32     s;
+       u32     draw;
+       u32     blit;
+       u32     font;
+       u32     xxx2[24];
+       u32     x0, y0, z0, color0;
+       u32     x1, y1, z1, color1;
+       u32     x2, y2, z2, color2;
+       u32     x3, y3, z3, color3;
+       u32     offx, offy;
+       u32     xxx3[2];
+       u32     incx, incy;
+       u32     xxx4[2];
+       u32     clipminx, clipminy;
+       u32     xxx5[2];
+       u32     clipmaxx, clipmaxy;
+       u32     xxx6[2];
+       u32     fg;
+       u32     bg;
+       u32     alu;
+       u32     pm;
+       u32     pixelm;
+       u32     xxx7[2];
+       u32     patalign;
+       u32     pattern[8];
+       u32     xxx8[432];
+       u32     apointx, apointy, apointz;
+       u32     xxx9[1];
+       u32     rpointx, rpointy, rpointz;
+       u32     xxx10[5];
+       u32     pointr, pointg, pointb, pointa;
+       u32     alinex, aliney, alinez;
+       u32     xxx11[1];
+       u32     rlinex, rliney, rlinez;
+       u32     xxx12[5];
+       u32     liner, lineg, lineb, linea;
+       u32     atrix, atriy, atriz;
+       u32     xxx13[1];
+       u32     rtrix, rtriy, rtriz;
+       u32     xxx14[5];
+       u32     trir, trig, trib, tria;
+       u32     aquadx, aquady, aquadz;
+       u32     xxx15[1];
+       u32     rquadx, rquady, rquadz;
+       u32     xxx16[5];
+       u32     quadr, quadg, quadb, quada;
+       u32     arectx, arecty, arectz;
+       u32     xxx17[1];
+       u32     rrectx, rrecty, rrectz;
+       u32     xxx18[5];
+       u32     rectr, rectg, rectb, recta;
 };
 
 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 cg6_par {
@@ -255,15 +255,14 @@ struct cg6_par {
        struct cg6_fbc          __iomem *fbc;
        struct cg6_thc          __iomem *thc;
        struct cg6_tec          __iomem *tec;
-       volatile u32            __iomem *fhc;
+       u32                     __iomem *fhc;
 
        u32                     flags;
 #define CG6_FLAG_BLANKED       0x00000001
 
        unsigned long           physbase;
+       unsigned long           which_io;
        unsigned long           fbsize;
-
-       struct sbus_dev         *sdev;
 };
 
 static int cg6_sync(struct fb_info *info)
@@ -529,8 +528,7 @@ static int cg6_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
        return sbusfb_mmap_helper(cg6_mmap_map,
                                  par->physbase, par->fbsize,
-                                 par->sdev->reg_addrs[0].which_io,
-                                 vma);
+                                 par->which_io, vma);
 }
 
 static int cg6_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
@@ -658,62 +656,75 @@ static void cg6_chip_init(struct fb_info *info)
 struct all_info {
        struct fb_info info;
        struct cg6_par par;
-       struct list_head list;
 };
-static LIST_HEAD(cg6_list);
 
-static void cg6_init_one(struct sbus_dev *sdev)
+static void cg6_unmap_regs(struct all_info *all)
 {
-       struct all_info *all;
-       int linebytes;
+       if (all->par.fbc)
+               of_iounmap(all->par.fbc, 4096);
+       if (all->par.tec)
+               of_iounmap(all->par.tec, sizeof(struct cg6_tec));
+       if (all->par.thc)
+               of_iounmap(all->par.thc, sizeof(struct cg6_thc));
+       if (all->par.bt)
+               of_iounmap(all->par.bt, sizeof(struct bt_regs));
+       if (all->par.fhc)
+               of_iounmap(all->par.fhc, sizeof(u32));
+
+       if (all->info.screen_base)
+               of_iounmap(all->info.screen_base, all->par.fbsize);
+}
 
-       all = kmalloc(sizeof(*all), GFP_KERNEL);
-       if (!all) {
-               printk(KERN_ERR "cg6: Cannot allocate memory.\n");
-               return;
-       }
-       memset(all, 0, sizeof(*all));
+static int __devinit cg6_init_one(struct of_device *op)
+{
+       struct device_node *dp = op->node;
+       struct all_info *all;
+       int linebytes, err;
 
-       INIT_LIST_HEAD(&all->list);
+       all = kzalloc(sizeof(*all), GFP_KERNEL);
+       if (!all)
+               return -ENOMEM;
 
        spin_lock_init(&all->par.lock);
-       all->par.sdev = sdev;
 
-       all->par.physbase = sdev->reg_addrs[0].phys_addr;
+       all->par.physbase = op->resource[0].start;
+       all->par.which_io = op->resource[0].flags & IORESOURCE_BITS;
 
-       sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+       sbusfb_fill_var(&all->info.var, dp->node, 8);
        all->info.var.red.length = 8;
        all->info.var.green.length = 8;
        all->info.var.blue.length = 8;
 
-       linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
-                                      all->info.var.xres);
+       linebytes = of_getintprop_default(dp, "linebytes",
+                                         all->info.var.xres);
        all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
-       if (prom_getbool(sdev->prom_node, "dblbuf"))
+       if (of_find_property(dp, "dblbuf", NULL))
                all->par.fbsize *= 4;
 
-       all->par.fbc = sbus_ioremap(&sdev->resource[0], CG6_FBC_OFFSET,
-                            4096, "cgsix fbc");
-       all->par.tec = sbus_ioremap(&sdev->resource[0], CG6_TEC_OFFSET,
-                            sizeof(struct cg6_tec), "cgsix tec");
-       all->par.thc = sbus_ioremap(&sdev->resource[0], CG6_THC_OFFSET,
-                            sizeof(struct cg6_thc), "cgsix thc");
-       all->par.bt = sbus_ioremap(&sdev->resource[0], CG6_BROOKTREE_OFFSET,
-                            sizeof(struct bt_regs), "cgsix dac");
-       all->par.fhc = sbus_ioremap(&sdev->resource[0], CG6_FHC_OFFSET,
-                            sizeof(u32), "cgsix fhc");
+       all->par.fbc = of_ioremap(&op->resource[0], CG6_FBC_OFFSET,
+                                 4096, "cgsix fbc");
+       all->par.tec = of_ioremap(&op->resource[0], CG6_TEC_OFFSET,
+                                 sizeof(struct cg6_tec), "cgsix tec");
+       all->par.thc = of_ioremap(&op->resource[0], CG6_THC_OFFSET,
+                                 sizeof(struct cg6_thc), "cgsix thc");
+       all->par.bt = of_ioremap(&op->resource[0], CG6_BROOKTREE_OFFSET,
+                                sizeof(struct bt_regs), "cgsix dac");
+       all->par.fhc = of_ioremap(&op->resource[0], CG6_FHC_OFFSET,
+                                 sizeof(u32), "cgsix fhc");
 
        all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_IMAGEBLIT |
                           FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT;
        all->info.fbops = &cg6_ops;
-#ifdef CONFIG_SPARC32
-       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(&sdev->resource[0], CG6_RAM_OFFSET,
-                                    all->par.fbsize, "cgsix ram");
+
+       all->info.screen_base =  of_ioremap(&op->resource[0], CG6_RAM_OFFSET,
+                                           all->par.fbsize, "cgsix ram");
+       if (!all->par.fbc || !all->par.tec || !all->par.thc ||
+           !all->par.bt || !all->par.fhc || !all->info.screen_base) {
+               cg6_unmap_regs(all);
+               kfree(all);
+               return -ENOMEM;
+       }
+
        all->info.par = &all->par;
 
        all->info.var.accel_flags = FB_ACCELF_TEXT;
@@ -723,72 +734,90 @@ static void cg6_init_one(struct sbus_dev *sdev)
        cg6_blank(0, &all->info);
 
        if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
-               printk(KERN_ERR "cg6: Could not allocate color map.\n");
+               cg6_unmap_regs(all);
                kfree(all);
-               return;
+               return -ENOMEM;
        }
 
        fb_set_cmap(&all->info.cmap, &all->info);
        cg6_init_fix(&all->info, linebytes);
 
-       if (register_framebuffer(&all->info) < 0) {
-               printk(KERN_ERR "cg6: Could not register framebuffer.\n");
+       err = register_framebuffer(&all->info);
+       if (err < 0) {
+               cg6_unmap_regs(all);
                fb_dealloc_cmap(&all->info.cmap);
                kfree(all);
-               return;
+               return err;
        }
 
-       list_add(&all->list, &cg6_list);
+       dev_set_drvdata(&op->dev, all);
 
-       printk("cg6: CGsix [%s] at %lx:%lx\n",
+       printk("%s: CGsix [%s] at %lx:%lx\n",
+              dp->full_name,
               all->info.fix.id,
-              (long) sdev->reg_addrs[0].which_io,
-              (long) sdev->reg_addrs[0].phys_addr);
+              all->par.which_io, all->par.physbase);
+
+       return 0;
 }
 
-int __init cg6_init(void)
+static int __devinit cg6_probe(struct of_device *dev, const struct of_device_id *match)
 {
-       struct sbus_bus *sbus;
-       struct sbus_dev *sdev;
+       struct of_device *op = to_of_device(&dev->dev);
 
-       if (fb_get_options("cg6fb", NULL))
-               return -ENODEV;
+       return cg6_init_one(op);
+}
 
-       for_all_sbusdev(sdev, sbus) {
-               if (!strcmp(sdev->prom_name, "cgsix") ||
-                   !strcmp(sdev->prom_name, "cgthree+"))
-                       cg6_init_one(sdev);
-       }
+static int __devexit cg6_remove(struct of_device *dev)
+{
+       struct all_info *all = dev_get_drvdata(&dev->dev);
+
+       unregister_framebuffer(&all->info);
+       fb_dealloc_cmap(&all->info.cmap);
+
+       cg6_unmap_regs(all);
+
+       kfree(all);
+
+       dev_set_drvdata(&dev->dev, NULL);
 
        return 0;
 }
 
-void __exit cg6_exit(void)
-{
-       struct list_head *pos, *tmp;
+static struct of_device_id cg6_match[] = {
+       {
+               .name = "cgsix",
+       },
+       {
+               .name = "cgthree+",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, cg6_match);
 
-       list_for_each_safe(pos, tmp, &cg6_list) {
-               struct all_info *all = list_entry(pos, typeof(*all), list);
+static struct of_platform_driver cg6_driver = {
+       .name           = "cg6",
+       .match_table    = cg6_match,
+       .probe          = cg6_probe,
+       .remove         = __devexit_p(cg6_remove),
+};
 
-               unregister_framebuffer(&all->info);
-               fb_dealloc_cmap(&all->info.cmap);
-               kfree(all);
-       }
+static int __init cg6_init(void)
+{
+       if (fb_get_options("cg6fb", NULL))
+               return -ENODEV;
+
+       return of_register_driver(&cg6_driver, &of_bus_type);
 }
 
-int __init
-cg6_setup(char *arg)
+static void __exit cg6_exit(void)
 {
-       /* No cmdline options yet... */
-       return 0;
+       of_unregister_driver(&cg6_driver);
 }
 
 module_init(cg6_init);
-
-#ifdef MODULE
 module_exit(cg6_exit);
-#endif
 
 MODULE_DESCRIPTION("framebuffer driver for CGsix chipsets");
-MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_VERSION("2.0");
 MODULE_LICENSE("GPL");
index 7633e41adda158a38688c056057fd15c91bf974d..2a0e8210d398e6c964aa69028161cd3af471a44d 100644 (file)
@@ -1,6 +1,6 @@
 /* ffb.c: Creator/Elite3D frame buffer driver
  *
- * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz)
  *
  * Driver layout based loosely on tgafb.c, see that file for credits.
@@ -19,7 +19,8 @@
 
 #include <asm/io.h>
 #include <asm/upa.h>
-#include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -184,161 +185,161 @@ static struct fb_ops ffb_ops = {
 
 struct ffb_fbc {
        /* Next vertex registers */
-       u32             xxx1[3];
-       volatile u32    alpha;
-       volatile u32    red;
-       volatile u32    green;
-       volatile u32    blue;
-       volatile u32    depth;
-       volatile u32    y;
-       volatile u32    x;
-       u32             xxx2[2];
-       volatile u32    ryf;
-       volatile u32    rxf;
-       u32             xxx3[2];
+       u32     xxx1[3];
+       u32     alpha;
+       u32     red;
+       u32     green;
+       u32     blue;
+       u32     depth;
+       u32     y;
+       u32     x;
+       u32     xxx2[2];
+       u32     ryf;
+       u32     rxf;
+       u32     xxx3[2];
        
-       volatile u32    dmyf;
-       volatile u32    dmxf;
-       u32             xxx4[2];
-       volatile u32    ebyi;
-       volatile u32    ebxi;
-       u32             xxx5[2];
-       volatile u32    by;
-       volatile u32    bx;
-       u32             dy;
-       u32             dx;
-       volatile u32    bh;
-       volatile u32    bw;
-       u32             xxx6[2];
+       u32     dmyf;
+       u32     dmxf;
+       u32     xxx4[2];
+       u32     ebyi;
+       u32     ebxi;
+       u32     xxx5[2];
+       u32     by;
+       u32     bx;
+       u32     dy;
+       u32     dx;
+       u32     bh;
+       u32     bw;
+       u32     xxx6[2];
        
-       u32             xxx7[32];
+       u32     xxx7[32];
        
        /* Setup unit vertex state register */
-       volatile u32    suvtx;
-       u32             xxx8[63];
+       u32     suvtx;
+       u32     xxx8[63];
        
        /* Control registers */
-       volatile u32    ppc;
-       volatile u32    wid;
-       volatile u32    fg;
-       volatile u32    bg;
-       volatile u32    consty;
-       volatile u32    constz;
-       volatile u32    xclip;
-       volatile u32    dcss;
-       volatile u32    vclipmin;
-       volatile u32    vclipmax;
-       volatile u32    vclipzmin;
-       volatile u32    vclipzmax;
-       volatile u32    dcsf;
-       volatile u32    dcsb;
-       volatile u32    dczf;
-       volatile u32    dczb;
+       u32     ppc;
+       u32     wid;
+       u32     fg;
+       u32     bg;
+       u32     consty;
+       u32     constz;
+       u32     xclip;
+       u32     dcss;
+       u32     vclipmin;
+       u32     vclipmax;
+       u32     vclipzmin;
+       u32     vclipzmax;
+       u32     dcsf;
+       u32     dcsb;
+       u32     dczf;
+       u32     dczb;
        
-       u32             xxx9;
-       volatile u32    blendc;
-       volatile u32    blendc1;
-       volatile u32    blendc2;
-       volatile u32    fbramitc;
-       volatile u32    fbc;
-       volatile u32    rop;
-       volatile u32    cmp;
-       volatile u32    matchab;
-       volatile u32    matchc;
-       volatile u32    magnab;
-       volatile u32    magnc;
-       volatile u32    fbcfg0;
-       volatile u32    fbcfg1;
-       volatile u32    fbcfg2;
-       volatile u32    fbcfg3;
+       u32     xxx9;
+       u32     blendc;
+       u32     blendc1;
+       u32     blendc2;
+       u32     fbramitc;
+       u32     fbc;
+       u32     rop;
+       u32     cmp;
+       u32     matchab;
+       u32     matchc;
+       u32     magnab;
+       u32     magnc;
+       u32     fbcfg0;
+       u32     fbcfg1;
+       u32     fbcfg2;
+       u32     fbcfg3;
        
-       u32             ppcfg;
-       volatile u32    pick;
-       volatile u32    fillmode;
-       volatile u32    fbramwac;
-       volatile u32    pmask;
-       volatile u32    xpmask;
-       volatile u32    ypmask;
-       volatile u32    zpmask;
-       volatile u32    clip0min;
-       volatile u32    clip0max;
-       volatile u32    clip1min;
-       volatile u32    clip1max;
-       volatile u32    clip2min;
-       volatile u32    clip2max;
-       volatile u32    clip3min;
-       volatile u32    clip3max;
+       u32     ppcfg;
+       u32     pick;
+       u32     fillmode;
+       u32     fbramwac;
+       u32     pmask;
+       u32     xpmask;
+       u32     ypmask;
+       u32     zpmask;
+       u32     clip0min;
+       u32     clip0max;
+       u32     clip1min;
+       u32     clip1max;
+       u32     clip2min;
+       u32     clip2max;
+       u32     clip3min;
+       u32     clip3max;
        
        /* New 3dRAM III support regs */
-       volatile u32    rawblend2;
-       volatile u32    rawpreblend;
-       volatile u32    rawstencil;
-       volatile u32    rawstencilctl;
-       volatile u32    threedram1;
-       volatile u32    threedram2;
-       volatile u32    passin;
-       volatile u32    rawclrdepth;
-       volatile u32    rawpmask;
-       volatile u32    rawcsrc;
-       volatile u32    rawmatch;
-       volatile u32    rawmagn;
-       volatile u32    rawropblend;
-       volatile u32    rawcmp;
-       volatile u32    rawwac;
-       volatile u32    fbramid;
+       u32     rawblend2;
+       u32     rawpreblend;
+       u32     rawstencil;
+       u32     rawstencilctl;
+       u32     threedram1;
+       u32     threedram2;
+       u32     passin;
+       u32     rawclrdepth;
+       u32     rawpmask;
+       u32     rawcsrc;
+       u32     rawmatch;
+       u32     rawmagn;
+       u32     rawropblend;
+       u32     rawcmp;
+       u32     rawwac;
+       u32     fbramid;
        
-       volatile u32    drawop;
-       u32             xxx10[2];
-       volatile u32    fontlpat;
-       u32             xxx11;
-       volatile u32    fontxy;
-       volatile u32    fontw;
-       volatile u32    fontinc;
-       volatile u32    font;
-       u32             xxx12[3];
-       volatile u32    blend2;
-       volatile u32    preblend;
-       volatile u32    stencil;
-       volatile u32    stencilctl;
-
-       u32             xxx13[4];       
-       volatile u32    dcss1;
-       volatile u32    dcss2;
-       volatile u32    dcss3;
-       volatile u32    widpmask;
-       volatile u32    dcs2;
-       volatile u32    dcs3;
-       volatile u32    dcs4;
-       u32             xxx14;
-       volatile u32    dcd2;
-       volatile u32    dcd3;
-       volatile u32    dcd4;
-       u32             xxx15;
+       u32     drawop;
+       u32     xxx10[2];
+       u32     fontlpat;
+       u32     xxx11;
+       u32     fontxy;
+       u32     fontw;
+       u32     fontinc;
+       u32     font;
+       u32     xxx12[3];
+       u32     blend2;
+       u32     preblend;
+       u32     stencil;
+       u32     stencilctl;
+
+       u32     xxx13[4];       
+       u32     dcss1;
+       u32     dcss2;
+       u32     dcss3;
+       u32     widpmask;
+       u32     dcs2;
+       u32     dcs3;
+       u32     dcs4;
+       u32     xxx14;
+       u32     dcd2;
+       u32     dcd3;
+       u32     dcd4;
+       u32     xxx15;
        
-       volatile u32    pattern[32];
+       u32     pattern[32];
        
-       u32             xxx16[256];
+       u32     xxx16[256];
        
-       volatile u32    devid;
-       u32             xxx17[63];
+       u32     devid;
+       u32     xxx17[63];
        
-       volatile u32    ucsr;
-       u32             xxx18[31];
+       u32     ucsr;
+       u32     xxx18[31];
        
-       volatile u32    mer;
+       u32     mer;
 };
 
 struct ffb_dac {
-       volatile u32    type;
-       volatile u32    value;
-       volatile u32    type2;
-       volatile u32    value2;
+       u32     type;
+       u32     value;
+       u32     type2;
+       u32     value2;
 };
 
 struct ffb_par {
        spinlock_t              lock;
-       struct ffb_fbc          *fbc;
-       struct ffb_dac          *dac;
+       struct ffb_fbc __iomem  *fbc;
+       struct ffb_dac __iomem  *dac;
 
        u32                     flags;
 #define FFB_FLAG_AFB           0x00000001
@@ -353,16 +354,13 @@ struct ffb_par {
        unsigned long           physbase;
        unsigned long           fbsize;
 
-       char                    name[64];
-       int                     prom_node;
-       int                     prom_parent_node;
        int                     dac_rev;
        int                     board_type;
 };
 
 static void FFBFifo(struct ffb_par *par, int n)
 {
-       struct ffb_fbc *fbc;
+       struct ffb_fbc __iomem *fbc;
        int cache = par->fifo_cache;
 
        if (cache - n < 0) {
@@ -375,7 +373,7 @@ static void FFBFifo(struct ffb_par *par, int n)
 
 static void FFBWait(struct ffb_par *par)
 {
-       struct ffb_fbc *fbc;
+       struct ffb_fbc __iomem *fbc;
        int limit = 10000;
 
        fbc = par->fbc;
@@ -408,8 +406,8 @@ static __inline__ void ffb_rop(struct ffb_par *par, u32 rop)
 
 static void ffb_switch_from_graph(struct ffb_par *par)
 {
-       struct ffb_fbc *fbc = par->fbc;
-       struct ffb_dac *dac = par->dac;
+       struct ffb_fbc __iomem *fbc = par->fbc;
+       struct ffb_dac __iomem *dac = par->dac;
        unsigned long flags;
 
        spin_lock_irqsave(&par->lock, flags);
@@ -462,7 +460,7 @@ static int ffb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
 static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
        struct ffb_par *par = (struct ffb_par *) info->par;
-       struct ffb_fbc *fbc = par->fbc;
+       struct ffb_fbc __iomem *fbc = par->fbc;
        unsigned long flags;
        u32 fg;
 
@@ -505,7 +503,7 @@ static void
 ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area) 
 {
        struct ffb_par *par = (struct ffb_par *) info->par;
-       struct ffb_fbc *fbc = par->fbc;
+       struct ffb_fbc __iomem *fbc = par->fbc;
        unsigned long flags;
 
        if (area->dx != area->sx ||
@@ -541,7 +539,7 @@ ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 static void ffb_imageblit(struct fb_info *info, const struct fb_image *image)
 {
        struct ffb_par *par = (struct ffb_par *) info->par;
-       struct ffb_fbc *fbc = par->fbc;
+       struct ffb_fbc __iomem *fbc = par->fbc;
        const u8 *data = image->data;
        unsigned long flags;
        u32 fg, bg, xy;
@@ -664,7 +662,7 @@ static int
 ffb_blank(int blank, struct fb_info *info)
 {
        struct ffb_par *par = (struct ffb_par *) info->par;
-       struct ffb_dac *dac = par->dac;
+       struct ffb_dac __iomem *dac = par->dac;
        unsigned long flags;
        u32 tmp;
 
@@ -883,78 +881,42 @@ ffb_init_fix(struct fb_info *info)
        info->fix.accel = FB_ACCEL_SUN_CREATOR;
 }
 
-static int ffb_apply_upa_parent_ranges(int parent,
-                                      struct linux_prom64_registers *regs)
-{
-       struct linux_prom64_ranges ranges[PROMREG_MAX];
-       char name[128];
-       int len, i;
-
-       prom_getproperty(parent, "name", name, sizeof(name));
-       if (strcmp(name, "upa") != 0)
-               return 0;
-
-       len = prom_getproperty(parent, "ranges", (void *) ranges, sizeof(ranges));
-       if (len <= 0)
-               return 1;
-
-       len /= sizeof(struct linux_prom64_ranges);
-       for (i = 0; i < len; i++) {
-               struct linux_prom64_ranges *rng = &ranges[i];
-               u64 phys_addr = regs->phys_addr;
-
-               if (phys_addr >= rng->ot_child_base &&
-                   phys_addr < (rng->ot_child_base + rng->or_size)) {
-                       regs->phys_addr -= rng->ot_child_base;
-                       regs->phys_addr += rng->ot_parent_base;
-                       return 0;
-               }
-       }
-
-       return 1;
-}
-
 struct all_info {
        struct fb_info info;
        struct ffb_par par;
        u32 pseudo_palette[256];
-       struct list_head list;
 };
-static LIST_HEAD(ffb_list);
 
-static void ffb_init_one(int node, int parent)
+static int ffb_init_one(struct of_device *op)
 {
-       struct linux_prom64_registers regs[2*PROMREG_MAX];
-       struct ffb_fbc *fbc;
-       struct ffb_dac *dac;
+       struct device_node *dp = op->node;
+       struct ffb_fbc __iomem *fbc;
+       struct ffb_dac __iomem *dac;
        struct all_info *all;
+       int err;
 
-       if (prom_getproperty(node, "reg", (void *) regs, sizeof(regs)) <= 0) {
-               printk("ffb: Cannot get reg device node property.\n");
-               return;
-       }
+       all = kzalloc(sizeof(*all), GFP_KERNEL);
+       if (!all)
+               return -ENOMEM;
 
-       if (ffb_apply_upa_parent_ranges(parent, &regs[0])) {
-               printk("ffb: Cannot apply parent ranges to regs.\n");
-               return;
+       spin_lock_init(&all->par.lock);
+       all->par.fbc = of_ioremap(&op->resource[2], 0,
+                                 sizeof(struct ffb_fbc), "ffb fbc");
+       if (!all->par.fbc) {
+               kfree(all);
+               return -ENOMEM;
        }
 
-       all = kmalloc(sizeof(*all), GFP_KERNEL);
-       if (!all) {
-               printk(KERN_ERR "ffb: Cannot allocate memory.\n");
-               return;
+       all->par.dac = of_ioremap(&op->resource[1], 0,
+                                 sizeof(struct ffb_dac), "ffb dac");
+       if (!all->par.dac) {
+               of_iounmap(all->par.fbc, sizeof(struct ffb_fbc));
+               kfree(all);
+               return -ENOMEM;
        }
-       memset(all, 0, sizeof(*all));
-
-       INIT_LIST_HEAD(&all->list);     
 
-       spin_lock_init(&all->par.lock);
-       all->par.fbc = (struct ffb_fbc *)(regs[0].phys_addr + FFB_FBC_REGS_POFF);
-       all->par.dac = (struct ffb_dac *)(regs[0].phys_addr + FFB_DAC_POFF);
        all->par.rop_cache = FFB_ROP_NEW;
-       all->par.physbase = regs[0].phys_addr;
-       all->par.prom_node = node;
-       all->par.prom_parent_node = parent;
+       all->par.physbase = op->resource[0].start;
 
        /* Don't mention copyarea, so SCROLL_REDRAW is always
         * used.  It is the fastest on this chip.
@@ -968,7 +930,7 @@ static void ffb_init_one(int node, int parent)
        all->info.par = &all->par;
        all->info.pseudo_palette = all->pseudo_palette;
 
-       sbusfb_fill_var(&all->info.var, all->par.prom_node, 32);
+       sbusfb_fill_var(&all->info.var, dp->node, 32);
        all->par.fbsize = PAGE_ALIGN(all->info.var.xres *
                                     all->info.var.yres *
                                     4);
@@ -976,14 +938,13 @@ static void ffb_init_one(int node, int parent)
 
        all->info.var.accel_flags = FB_ACCELF_TEXT;
 
-       prom_getstring(node, "name", all->par.name, sizeof(all->par.name));
-       if (!strcmp(all->par.name, "SUNW,afb"))
+       if (!strcmp(dp->name, "SUNW,afb"))
                all->par.flags |= FFB_FLAG_AFB;
 
-       all->par.board_type = prom_getintdefault(node, "board_type", 0);
+       all->par.board_type = of_getintprop_default(dp, "board_type", 0);
 
        fbc = all->par.fbc;
-       if((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0)
+       if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0)
                upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr);
 
        ffb_switch_from_graph(&all->par);
@@ -1008,81 +969,88 @@ static void ffb_init_one(int node, int parent)
        if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
                printk(KERN_ERR "ffb: Could not allocate color map.\n");
                kfree(all);
-               return;
+               return -ENOMEM;
        }
 
        ffb_init_fix(&all->info);
 
-       if (register_framebuffer(&all->info) < 0) {
+       err = register_framebuffer(&all->info);
+       if (err < 0) {
                printk(KERN_ERR "ffb: Could not register framebuffer.\n");
                fb_dealloc_cmap(&all->info.cmap);
                kfree(all);
-               return;
+               return err;
        }
 
-       list_add(&all->list, &ffb_list);
+       dev_set_drvdata(&op->dev, all);
 
-       printk("ffb: %s at %016lx type %d DAC %d\n",
+       printk("%s: %s at %016lx, type %d, DAC revision %d\n",
+              dp->full_name,
               ((all->par.flags & FFB_FLAG_AFB) ? "AFB" : "FFB"),
-              regs[0].phys_addr, all->par.board_type, all->par.dac_rev);
+              all->par.physbase, all->par.board_type, all->par.dac_rev);
+
+       return 0;
 }
 
-static void ffb_scan_siblings(int root)
+static int __devinit ffb_probe(struct of_device *dev, const struct of_device_id *match)
 {
-       int node, child;
-
-       child = prom_getchild(root);
-       for (node = prom_searchsiblings(child, "SUNW,ffb"); node;
-            node = prom_searchsiblings(prom_getsibling(node), "SUNW,ffb"))
-               ffb_init_one(node, root);
-       for (node = prom_searchsiblings(child, "SUNW,afb"); node;
-            node = prom_searchsiblings(prom_getsibling(node), "SUNW,afb"))
-               ffb_init_one(node, root);
+       struct of_device *op = to_of_device(&dev->dev);
+
+       return ffb_init_one(op);
 }
 
-int __init ffb_init(void)
+static int __devexit ffb_remove(struct of_device *dev)
 {
-       int root;
+       struct all_info *all = dev_get_drvdata(&dev->dev);
 
-       if (fb_get_options("ffb", NULL))
-               return -ENODEV;
+       unregister_framebuffer(&all->info);
+       fb_dealloc_cmap(&all->info.cmap);
 
-       ffb_scan_siblings(prom_root_node);
+       of_iounmap(all->par.fbc, sizeof(struct ffb_fbc));
+       of_iounmap(all->par.dac, sizeof(struct ffb_dac));
 
-       root = prom_getchild(prom_root_node);
-       for (root = prom_searchsiblings(root, "upa"); root;
-            root = prom_searchsiblings(prom_getsibling(root), "upa"))
-               ffb_scan_siblings(root);
+       kfree(all);
+
+       dev_set_drvdata(&dev->dev, NULL);
 
        return 0;
 }
 
-void __exit ffb_exit(void)
-{
-       struct list_head *pos, *tmp;
+static struct of_device_id ffb_match[] = {
+       {
+               .name = "SUNW,ffb",
+       },
+       {
+               .name = "SUNW,afb",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, ffb_match);
+
+static struct of_platform_driver ffb_driver = {
+       .name           = "ffb",
+       .match_table    = ffb_match,
+       .probe          = ffb_probe,
+       .remove         = __devexit_p(ffb_remove),
+};
 
-       list_for_each_safe(pos, tmp, &ffb_list) {
-               struct all_info *all = list_entry(pos, typeof(*all), list);
+int __init ffb_init(void)
+{
+       if (fb_get_options("ffb", NULL))
+               return -ENODEV;
 
-               unregister_framebuffer(&all->info);
-               fb_dealloc_cmap(&all->info.cmap);
-               kfree(all);
-       }
+       return of_register_driver(&ffb_driver, &of_bus_type);
 }
 
-int __init
-ffb_setup(char *arg)
+void __exit ffb_exit(void)
 {
-       /* No cmdline options yet... */
-       return 0;
+       of_unregister_driver(&ffb_driver);
 }
 
 module_init(ffb_init);
-
-#ifdef MODULE
 module_exit(ffb_exit);
-#endif
 
 MODULE_DESCRIPTION("framebuffer driver for Creator/Elite3D chipsets");
-MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_VERSION("2.0");
 MODULE_LICENSE("GPL");
index a23cfdb9d826391ff5d4007fb33f884da0d53f1c..f3a24338d9ac830b0b67051fe5e76f09979ee611 100644 (file)
@@ -1,6 +1,6 @@
 /* leo.c: LEO 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-1999 Jakub Jelinek (jj@ultra.linux.cz)
  * Copyright (C) 1997 Michal Rehacek (Michal.Rehacek@st.mff.cuni.cz)
  *
@@ -18,8 +18,8 @@
 #include <linux/mm.h>
 
 #include <asm/io.h>
-#include <asm/sbus.h>
-#include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -80,10 +80,10 @@ static struct fb_ops leo_ops = {
 
 struct leo_cursor {
        u8              xxx0[16];
-       volatile u32    cur_type;
-       volatile u32    cur_misc;
-       volatile u32    cur_cursxy;
-       volatile u32    cur_data;
+       u32     cur_type;
+       u32     cur_misc;
+       u32     cur_cursxy;
+       u32     cur_data;
 };
 
 #define LEO_KRN_TYPE_CLUT0     0x00001000
@@ -99,27 +99,27 @@ struct leo_cursor {
 #define LEO_KRN_CSR_UNK2       0x00000001
 
 struct leo_lx_krn {
-       volatile u32    krn_type;
-       volatile u32    krn_csr;
-       volatile u32    krn_value;
+       u32     krn_type;
+       u32     krn_csr;
+       u32     krn_value;
 };
 
 struct leo_lc_ss0_krn {
-       volatile u32    misc;
+       u32     misc;
        u8              xxx0[0x800-4];
-       volatile u32    rev;
+       u32     rev;
 };
 
 struct leo_lc_ss0_usr {
-       volatile u32    csr;
-       volatile u32    addrspace;
-       volatile u32    fontmsk;
-       volatile u32    fontt;
-       volatile u32    extent;
-       volatile u32    src;
+       u32     csr;
+       u32     addrspace;
+       u32     fontmsk;
+       u32     fontt;
+       u32     extent;
+       u32     src;
        u32             dst;
-       volatile u32    copy;
-       volatile u32    fill;
+       u32     copy;
+       u32     fill;
 };
 
 struct leo_lc_ss1_krn {
@@ -132,47 +132,47 @@ struct leo_lc_ss1_usr {
 
 struct leo_ld {
        u8              xxx0[0xe00];
-       volatile u32    csr;
-       volatile u32    wid;
-       volatile u32    wmask;
-       volatile u32    widclip;
-       volatile u32    vclipmin;
-       volatile u32    vclipmax;
-       volatile u32    pickmin;        /* SS1 only */
-       volatile u32    pickmax;        /* SS1 only */
-       volatile u32    fg;
-       volatile u32    bg;
-       volatile u32    src;            /* Copy/Scroll (SS0 only) */
-       volatile u32    dst;            /* Copy/Scroll/Fill (SS0 only) */
-       volatile u32    extent;         /* Copy/Scroll/Fill size (SS0 only) */
+       u32     csr;
+       u32     wid;
+       u32     wmask;
+       u32     widclip;
+       u32     vclipmin;
+       u32     vclipmax;
+       u32     pickmin;        /* SS1 only */
+       u32     pickmax;        /* SS1 only */
+       u32     fg;
+       u32     bg;
+       u32     src;            /* Copy/Scroll (SS0 only) */
+       u32     dst;            /* Copy/Scroll/Fill (SS0 only) */
+       u32     extent;         /* Copy/Scroll/Fill size (SS0 only) */
        u32             xxx1[3];
-       volatile u32    setsem;         /* SS1 only */
-       volatile u32    clrsem;         /* SS1 only */
-       volatile u32    clrpick;        /* SS1 only */
-       volatile u32    clrdat;         /* SS1 only */
-       volatile u32    alpha;          /* SS1 only */
+       u32     setsem;         /* SS1 only */
+       u32     clrsem;         /* SS1 only */
+       u32     clrpick;        /* SS1 only */
+       u32     clrdat;         /* SS1 only */
+       u32     alpha;          /* SS1 only */
        u8              xxx2[0x2c];
-       volatile u32    winbg;
-       volatile u32    planemask;
-       volatile u32    rop;
-       volatile u32    z;
-       volatile u32    dczf;           /* SS1 only */
-       volatile u32    dczb;           /* SS1 only */
-       volatile u32    dcs;            /* SS1 only */
-       volatile u32    dczs;           /* SS1 only */
-       volatile u32    pickfb;         /* SS1 only */
-       volatile u32    pickbb;         /* SS1 only */
-       volatile u32    dcfc;           /* SS1 only */
-       volatile u32    forcecol;       /* SS1 only */
-       volatile u32    door[8];        /* SS1 only */
-       volatile u32    pick[5];        /* SS1 only */
+       u32     winbg;
+       u32     planemask;
+       u32     rop;
+       u32     z;
+       u32     dczf;           /* SS1 only */
+       u32     dczb;           /* SS1 only */
+       u32     dcs;            /* SS1 only */
+       u32     dczs;           /* SS1 only */
+       u32     pickfb;         /* SS1 only */
+       u32     pickbb;         /* SS1 only */
+       u32     dcfc;           /* SS1 only */
+       u32     forcecol;       /* SS1 only */
+       u32     door[8];        /* SS1 only */
+       u32     pick[5];        /* SS1 only */
 };
 
 #define LEO_SS1_MISC_ENABLE    0x00000001
 #define LEO_SS1_MISC_STEREO    0x00000002
 struct leo_ld_ss1 {
-       u8              xxx0[0xef4];
-       volatile u32    ss1_misc;
+       u8      xxx0[0xef4];
+       u32     ss1_misc;
 };
 
 struct leo_ld_gbl {
@@ -193,9 +193,8 @@ struct leo_par {
 #define LEO_FLAG_BLANKED       0x00000001
 
        unsigned long           physbase;
+       unsigned long           which_io;
        unsigned long           fbsize;
-
-       struct sbus_dev         *sdev;
 };
 
 static void leo_wait(struct leo_lx_krn __iomem *lx_krn)
@@ -368,8 +367,7 @@ static int leo_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
        return sbusfb_mmap_helper(leo_mmap_map,
                                  par->physbase, par->fbsize,
-                                 par->sdev->reg_addrs[0].which_io,
-                                 vma);
+                                 par->which_io, vma);
 }
 
 static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
@@ -385,11 +383,9 @@ static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
  */
 
 static void
-leo_init_fix(struct fb_info *info)
+leo_init_fix(struct fb_info *info, struct device_node *dp)
 {
-       struct leo_par *par = (struct leo_par *)info->par;
-
-       strlcpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id));
+       strlcpy(info->fix.id, dp->name, sizeof(info->fix.id));
 
        info->fix.type = FB_TYPE_PACKED_PIXELS;
        info->fix.visual = FB_VISUAL_TRUECOLOR;
@@ -532,60 +528,74 @@ static void leo_fixup_var_rgb(struct fb_var_screeninfo *var)
 struct all_info {
        struct fb_info info;
        struct leo_par par;
-       struct list_head list;
 };
-static LIST_HEAD(leo_list);
 
-static void leo_init_one(struct sbus_dev *sdev)
+static void leo_unmap_regs(struct all_info *all)
 {
-       struct all_info *all;
-       int linebytes;
+       if (all->par.lc_ss0_usr)
+               of_iounmap(all->par.lc_ss0_usr, 0x1000);
+       if (all->par.ld_ss0)
+               of_iounmap(all->par.ld_ss0, 0x1000);
+       if (all->par.ld_ss1)
+               of_iounmap(all->par.ld_ss1, 0x1000);
+       if (all->par.lx_krn)
+               of_iounmap(all->par.lx_krn, 0x1000);
+       if (all->par.cursor)
+               of_iounmap(all->par.cursor, sizeof(struct leo_cursor));
+       if (all->info.screen_base)
+               of_iounmap(all->info.screen_base, 0x800000);
+}
 
-       all = kmalloc(sizeof(*all), GFP_KERNEL);
-       if (!all) {
-               printk(KERN_ERR "leo: Cannot allocate memory.\n");
-               return;
-       }
-       memset(all, 0, sizeof(*all));
+static int __devinit leo_init_one(struct of_device *op)
+{
+       struct device_node *dp = op->node;
+       struct all_info *all;
+       int linebytes, err;
 
-       INIT_LIST_HEAD(&all->list);
+       all = kzalloc(sizeof(*all), GFP_KERNEL);
+       if (!all)
+               return -ENOMEM;
 
        spin_lock_init(&all->par.lock);
-       all->par.sdev = sdev;
 
-       all->par.physbase = sdev->reg_addrs[0].phys_addr;
+       all->par.physbase = op->resource[0].start;
+       all->par.which_io = op->resource[0].flags & IORESOURCE_BITS;
 
-       sbusfb_fill_var(&all->info.var, sdev->prom_node, 32);
+       sbusfb_fill_var(&all->info.var, dp->node, 32);
        leo_fixup_var_rgb(&all->info.var);
 
-       linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
-                                      all->info.var.xres);
+       linebytes = of_getintprop_default(dp, "linebytes",
+                                         all->info.var.xres);
        all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
 
-#ifdef CONFIG_SPARC32
-       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(&sdev->resource[0], LEO_OFF_SS0,
-                                    0x800000, "leo ram");
-
        all->par.lc_ss0_usr =
-               sbus_ioremap(&sdev->resource[0], LEO_OFF_LC_SS0_USR,
-                            0x1000, "leolc ss0usr");
+               of_ioremap(&op->resource[0], LEO_OFF_LC_SS0_USR,
+                          0x1000, "leolc ss0usr");
        all->par.ld_ss0 =
-               sbus_ioremap(&sdev->resource[0], LEO_OFF_LD_SS0,
-                            0x1000, "leold ss0");
+               of_ioremap(&op->resource[0], LEO_OFF_LD_SS0,
+                          0x1000, "leold ss0");
        all->par.ld_ss1 =
-               sbus_ioremap(&sdev->resource[0], LEO_OFF_LD_SS1,
-                            0x1000, "leold ss1");
+               of_ioremap(&op->resource[0], LEO_OFF_LD_SS1,
+                          0x1000, "leold ss1");
        all->par.lx_krn =
-               sbus_ioremap(&sdev->resource[0], LEO_OFF_LX_KRN,
-                            0x1000, "leolx krn");
+               of_ioremap(&op->resource[0], LEO_OFF_LX_KRN,
+                          0x1000, "leolx krn");
        all->par.cursor =
-               sbus_ioremap(&sdev->resource[0], LEO_OFF_LX_CURSOR,
-                            sizeof(struct leo_cursor), "leolx cursor");
+               of_ioremap(&op->resource[0], LEO_OFF_LX_CURSOR,
+                          sizeof(struct leo_cursor), "leolx cursor");
+       all->info.screen_base = 
+               of_ioremap(&op->resource[0], LEO_OFF_SS0,
+                          0x800000, "leo ram");
+       if (!all->par.lc_ss0_usr ||
+           !all->par.ld_ss0 ||
+           !all->par.ld_ss1 ||
+           !all->par.lx_krn ||
+           !all->par.cursor ||
+           !all->info.screen_base) {
+               leo_unmap_regs(all);
+               kfree(all);
+               return -ENOMEM;
+       }
 
        all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
        all->info.fbops = &leo_ops;
@@ -597,69 +607,85 @@ static void leo_init_one(struct sbus_dev *sdev)
        leo_blank(0, &all->info);
 
        if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
-               printk(KERN_ERR "leo: Could not allocate color map.\n");
+               leo_unmap_regs(all);
                kfree(all);
-               return;
+               return -ENOMEM;;
        }
 
-       leo_init_fix(&all->info);
+       leo_init_fix(&all->info, dp);
 
-       if (register_framebuffer(&all->info) < 0) {
-               printk(KERN_ERR "leo: Could not register framebuffer.\n");
+       err = register_framebuffer(&all->info);
+       if (err < 0) {
                fb_dealloc_cmap(&all->info.cmap);
+               leo_unmap_regs(all);
                kfree(all);
-               return;
+               return err;
        }
 
-       list_add(&all->list, &leo_list);
+       dev_set_drvdata(&op->dev, all);
+
+       printk("%s: leo at %lx:%lx\n",
+              dp->full_name,
+              all->par.which_io, all->par.physbase);
 
-       printk("leo: %s at %lx:%lx\n",
-              sdev->prom_name,
-              (long) sdev->reg_addrs[0].which_io,
-              (long) sdev->reg_addrs[0].phys_addr);
+       return 0;
 }
 
-int __init leo_init(void)
+static int __devinit leo_probe(struct of_device *dev, const struct of_device_id *match)
 {
-       struct sbus_bus *sbus;
-       struct sbus_dev *sdev;
+       struct of_device *op = to_of_device(&dev->dev);
 
-       if (fb_get_options("leofb", NULL))
-               return -ENODEV;
+       return leo_init_one(op);
+}
 
-       for_all_sbusdev(sdev, sbus) {
-               if (!strcmp(sdev->prom_name, "leo"))
-                       leo_init_one(sdev);
-       }
+static int __devexit leo_remove(struct of_device *dev)
+{
+       struct all_info *all = dev_get_drvdata(&dev->dev);
+
+       unregister_framebuffer(&all->info);
+       fb_dealloc_cmap(&all->info.cmap);
+
+       leo_unmap_regs(all);
+
+       kfree(all);
+
+       dev_set_drvdata(&dev->dev, NULL);
 
        return 0;
 }
 
-void __exit leo_exit(void)
-{
-       struct list_head *pos, *tmp;
+static struct of_device_id leo_match[] = {
+       {
+               .name = "leo",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, leo_match);
+
+static struct of_platform_driver leo_driver = {
+       .name           = "leo",
+       .match_table    = leo_match,
+       .probe          = leo_probe,
+       .remove         = __devexit_p(leo_remove),
+};
 
-       list_for_each_safe(pos, tmp, &leo_list) {
-               struct all_info *all = list_entry(pos, typeof(*all), list);
+static int __init leo_init(void)
+{
+       if (fb_get_options("leofb", NULL))
+               return -ENODEV;
 
-               unregister_framebuffer(&all->info);
-               fb_dealloc_cmap(&all->info.cmap);
-               kfree(all);
-       }
+       return of_register_driver(&leo_driver, &of_bus_type);
 }
 
-int __init
-leo_setup(char *arg)
+static void __exit leo_exit(void)
 {
-       /* No cmdline options yet... */
-       return 0;
+       of_unregister_driver(&leo_driver);
 }
 
 module_init(leo_init);
-#ifdef MODULE
 module_exit(leo_exit);
-#endif
 
 MODULE_DESCRIPTION("framebuffer driver for LEO chipsets");
-MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_VERSION("2.0");
 MODULE_LICENSE("GPL");
index 0d19575053598b665a6d425805672860e614bb6b..56ac51d6a7f3f0380b0a76dc7f86ed28948cf8b3 100644 (file)
@@ -1,6 +1,6 @@
 /* p9100.c: P9100 frame buffer driver
  *
- * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
  * Copyright 1999 Derrick J Brashear (shadow@dementia.org)
  *
  * Driver layout based loosely on tgafb.c, see that file for credits.
@@ -17,8 +17,8 @@
 #include <linux/mm.h>
 
 #include <asm/io.h>
-#include <asm/sbus.h>
-#include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -72,60 +72,60 @@ static struct fb_ops p9100_ops = {
 
 struct p9100_regs {
        /* Registers for the system control */
-       volatile u32 sys_base;
-       volatile u32 sys_config;
-       volatile u32 sys_intr;
-       volatile u32 sys_int_ena;
-       volatile u32 sys_alt_rd;
-       volatile u32 sys_alt_wr;
-       volatile u32 sys_xxx[58];
+       u32 sys_base;
+       u32 sys_config;
+       u32 sys_intr;
+       u32 sys_int_ena;
+       u32 sys_alt_rd;
+       u32 sys_alt_wr;
+       u32 sys_xxx[58];
 
        /* Registers for the video control */
-       volatile u32 vid_base;
-       volatile u32 vid_hcnt;
-       volatile u32 vid_htotal;
-       volatile u32 vid_hsync_rise;
-       volatile u32 vid_hblank_rise;
-       volatile u32 vid_hblank_fall;
-       volatile u32 vid_hcnt_preload;
-       volatile u32 vid_vcnt;
-       volatile u32 vid_vlen;
-       volatile u32 vid_vsync_rise;
-       volatile u32 vid_vblank_rise;
-       volatile u32 vid_vblank_fall;
-       volatile u32 vid_vcnt_preload;
-       volatile u32 vid_screenpaint_addr;
-       volatile u32 vid_screenpaint_timectl1;
-       volatile u32 vid_screenpaint_qsfcnt;
-       volatile u32 vid_screenpaint_timectl2;
-       volatile u32 vid_xxx[15];
+       u32 vid_base;
+       u32 vid_hcnt;
+       u32 vid_htotal;
+       u32 vid_hsync_rise;
+       u32 vid_hblank_rise;
+       u32 vid_hblank_fall;
+       u32 vid_hcnt_preload;
+       u32 vid_vcnt;
+       u32 vid_vlen;
+       u32 vid_vsync_rise;
+       u32 vid_vblank_rise;
+       u32 vid_vblank_fall;
+       u32 vid_vcnt_preload;
+       u32 vid_screenpaint_addr;
+       u32 vid_screenpaint_timectl1;
+       u32 vid_screenpaint_qsfcnt;
+       u32 vid_screenpaint_timectl2;
+       u32 vid_xxx[15];
 
        /* Registers for the video control */
-       volatile u32 vram_base;
-       volatile u32 vram_memcfg;
-       volatile u32 vram_refresh_pd;
-       volatile u32 vram_refresh_cnt;
-       volatile u32 vram_raslo_max;
-       volatile u32 vram_raslo_cur;
-       volatile u32 pwrup_cfg;
-       volatile u32 vram_xxx[25];
+       u32 vram_base;
+       u32 vram_memcfg;
+       u32 vram_refresh_pd;
+       u32 vram_refresh_cnt;
+       u32 vram_raslo_max;
+       u32 vram_raslo_cur;
+       u32 pwrup_cfg;
+       u32 vram_xxx[25];
 
        /* Registers for IBM RGB528 Palette */
-       volatile u32 ramdac_cmap_wridx; 
-       volatile u32 ramdac_palette_data;
-       volatile u32 ramdac_pixel_mask;
-       volatile u32 ramdac_palette_rdaddr;
-       volatile u32 ramdac_idx_lo;
-       volatile u32 ramdac_idx_hi;
-       volatile u32 ramdac_idx_data;
-       volatile u32 ramdac_idx_ctl;
-       volatile u32 ramdac_xxx[1784];
+       u32 ramdac_cmap_wridx; 
+       u32 ramdac_palette_data;
+       u32 ramdac_pixel_mask;
+       u32 ramdac_palette_rdaddr;
+       u32 ramdac_idx_lo;
+       u32 ramdac_idx_hi;
+       u32 ramdac_idx_data;
+       u32 ramdac_idx_ctl;
+       u32 ramdac_xxx[1784];
 };
 
 struct p9100_cmd_parameng {
-       volatile u32 parameng_status;
-       volatile u32 parameng_bltcmd;
-       volatile u32 parameng_quadcmd;
+       u32 parameng_status;
+       u32 parameng_bltcmd;
+       u32 parameng_quadcmd;
 };
 
 struct p9100_par {
@@ -136,9 +136,8 @@ struct p9100_par {
 #define P9100_FLAG_BLANKED     0x00000001
 
        unsigned long           physbase;
+       unsigned long           which_io;
        unsigned long           fbsize;
-
-       struct sbus_dev         *sdev;
 };
 
 /**
@@ -227,8 +226,7 @@ static int p9100_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
        return sbusfb_mmap_helper(p9100_mmap_map,
                                  par->physbase, par->fbsize,
-                                 par->sdev->reg_addrs[0].which_io,
-                                 vma);
+                                 par->which_io, vma);
 }
 
 static int p9100_ioctl(struct fb_info *info, unsigned int cmd,
@@ -245,12 +243,9 @@ static int p9100_ioctl(struct fb_info *info, unsigned int cmd,
  *  Initialisation
  */
 
-static void
-p9100_init_fix(struct fb_info *info, int linebytes)
+static void p9100_init_fix(struct fb_info *info, int linebytes, struct device_node *dp)
 {
-       struct p9100_par *par = (struct p9100_par *)info->par;
-
-       strlcpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id));
+       strlcpy(info->fix.id, dp->name, sizeof(info->fix.id));
 
        info->fix.type = FB_TYPE_PACKED_PIXELS;
        info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
@@ -263,121 +258,137 @@ p9100_init_fix(struct fb_info *info, int linebytes)
 struct all_info {
        struct fb_info info;
        struct p9100_par par;
-       struct list_head list;
 };
-static LIST_HEAD(p9100_list);
 
-static void p9100_init_one(struct sbus_dev *sdev)
+static int __devinit p9100_init_one(struct of_device *op)
 {
+       struct device_node *dp = op->node;
        struct all_info *all;
-       int linebytes;
-
-       all = kmalloc(sizeof(*all), GFP_KERNEL);
-       if (!all) {
-               printk(KERN_ERR "p9100: Cannot allocate memory.\n");
-               return;
-       }
-       memset(all, 0, sizeof(*all));
+       int linebytes, err;
 
-       INIT_LIST_HEAD(&all->list);
+       all = kzalloc(sizeof(*all), GFP_KERNEL);
+       if (!all)
+               return -ENOMEM;
 
        spin_lock_init(&all->par.lock);
-       all->par.sdev = sdev;
 
        /* This is the framebuffer and the only resource apps can mmap.  */
-       all->par.physbase = sdev->reg_addrs[2].phys_addr;
+       all->par.physbase = op->resource[2].start;
+       all->par.which_io = op->resource[2].flags & IORESOURCE_BITS;
 
-       sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+       sbusfb_fill_var(&all->info.var, dp->node, 8);
        all->info.var.red.length = 8;
        all->info.var.green.length = 8;
        all->info.var.blue.length = 8;
 
-       linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
-                                      all->info.var.xres);
+       linebytes = of_getintprop_default(dp, "linebytes",
+                                         all->info.var.xres);
        all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
 
-       all->par.regs = sbus_ioremap(&sdev->resource[0], 0,
-                            sizeof(struct p9100_regs), "p9100 regs");
+       all->par.regs = of_ioremap(&op->resource[0], 0,
+                                  sizeof(struct p9100_regs), "p9100 regs");
+       if (!all->par.regs) {
+               kfree(all);
+               return -ENOMEM;
+       }
 
        all->info.flags = FBINFO_DEFAULT;
        all->info.fbops = &p9100_ops;
-#ifdef CONFIG_SPARC32
-       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(&sdev->resource[2], 0,
-                                    all->par.fbsize, "p9100 ram");
+       all->info.screen_base = of_ioremap(&op->resource[2], 0,
+                                          all->par.fbsize, "p9100 ram");
+       if (!all->info.screen_base) {
+               of_iounmap(all->par.regs, sizeof(struct p9100_regs));
+               kfree(all);
+               return -ENOMEM;
+       }
        all->info.par = &all->par;
 
        p9100_blank(0, &all->info);
 
        if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
-               printk(KERN_ERR "p9100: Could not allocate color map.\n");
+               of_iounmap(all->par.regs, sizeof(struct p9100_regs));
+               of_iounmap(all->info.screen_base, all->par.fbsize);
                kfree(all);
-               return;
+               return -ENOMEM;
        }
 
-       p9100_init_fix(&all->info, linebytes);
+       p9100_init_fix(&all->info, linebytes, dp);
 
-       if (register_framebuffer(&all->info) < 0) {
-               printk(KERN_ERR "p9100: Could not register framebuffer.\n");
+       err = register_framebuffer(&all->info);
+       if (err < 0) {
                fb_dealloc_cmap(&all->info.cmap);
+               of_iounmap(all->par.regs, sizeof(struct p9100_regs));
+               of_iounmap(all->info.screen_base, all->par.fbsize);
                kfree(all);
-               return;
+               return err;
        }
        fb_set_cmap(&all->info.cmap, &all->info);
 
-       list_add(&all->list, &p9100_list);
+       dev_set_drvdata(&op->dev, all);
+
+       printk("%s: p9100 at %lx:%lx\n",
+              dp->full_name,
+              all->par.which_io, all->par.physbase);
 
-       printk("p9100: %s at %lx:%lx\n",
-              sdev->prom_name,
-              (long) sdev->reg_addrs[0].which_io,
-              (long) sdev->reg_addrs[0].phys_addr);
+       return 0;
 }
 
-int __init p9100_init(void)
+static int __devinit p9100_probe(struct of_device *dev, const struct of_device_id *match)
 {
-       struct sbus_bus *sbus;
-       struct sbus_dev *sdev;
+       struct of_device *op = to_of_device(&dev->dev);
 
-       if (fb_get_options("p9100fb", NULL))
-               return -ENODEV;
+       return p9100_init_one(op);
+}
 
-       for_all_sbusdev(sdev, sbus) {
-               if (!strcmp(sdev->prom_name, "p9100"))
-                       p9100_init_one(sdev);
-       }
+static int __devexit p9100_remove(struct of_device *dev)
+{
+       struct all_info *all = dev_get_drvdata(&dev->dev);
+
+       unregister_framebuffer(&all->info);
+       fb_dealloc_cmap(&all->info.cmap);
+
+       of_iounmap(all->par.regs, sizeof(struct p9100_regs));
+       of_iounmap(all->info.screen_base, all->par.fbsize);
+
+       kfree(all);
+
+       dev_set_drvdata(&dev->dev, NULL);
 
        return 0;
 }
 
-void __exit p9100_exit(void)
-{
-       struct list_head *pos, *tmp;
+static struct of_device_id p9100_match[] = {
+       {
+               .name = "p9100",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, p9100_match);
 
-       list_for_each_safe(pos, tmp, &p9100_list) {
-               struct all_info *all = list_entry(pos, typeof(*all), list);
+static struct of_platform_driver p9100_driver = {
+       .name           = "p9100",
+       .match_table    = p9100_match,
+       .probe          = p9100_probe,
+       .remove         = __devexit_p(p9100_remove),
+};
 
-               unregister_framebuffer(&all->info);
-               fb_dealloc_cmap(&all->info.cmap);
-               kfree(all);
-       }
+static int __init p9100_init(void)
+{
+       if (fb_get_options("p9100fb", NULL))
+               return -ENODEV;
+
+       return of_register_driver(&p9100_driver, &of_bus_type);
 }
 
-int __init
-p9100_setup(char *arg)
+static void __exit p9100_exit(void)
 {
-       /* No cmdline options yet... */
-       return 0;
+       of_unregister_driver(&p9100_driver);
 }
 
 module_init(p9100_init);
-
-#ifdef MODULE
 module_exit(p9100_exit);
-#endif
 
 MODULE_DESCRIPTION("framebuffer driver for P9100 chipsets");
-MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_VERSION("2.0");
 MODULE_LICENSE("GPL");
index 95b918229d9b13e6f35879d39ccc78924f43ec7c..6990ab11cd06ef184bee2ea364885ae6c7741a61 100644 (file)
@@ -1,6 +1,6 @@
 /* tcx.c: TCX 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) 1996 Eddie C. Dost (ecd@skynet.be)
@@ -19,8 +19,8 @@
 #include <linux/mm.h>
 
 #include <asm/io.h>
-#include <asm/sbus.h>
-#include <asm/oplib.h>
+#include <asm/prom.h>
+#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -77,32 +77,32 @@ static struct fb_ops tcx_ops = {
 
 /* The contents are unknown */
 struct tcx_tec {
-       volatile u32 tec_matrix;
-       volatile u32 tec_clip;
-       volatile u32 tec_vdc;
+       u32 tec_matrix;
+       u32 tec_clip;
+       u32 tec_vdc;
 };
 
 struct tcx_thc {
-       volatile u32 thc_rev;
+       u32 thc_rev;
         u32 thc_pad0[511];
-       volatile u32 thc_hs;            /* hsync timing */
-       volatile u32 thc_hsdvs;
-       volatile u32 thc_hd;
-       volatile u32 thc_vs;            /* vsync timing */
-       volatile u32 thc_vd;
-       volatile u32 thc_refresh;
-       volatile u32 thc_misc;
+       u32 thc_hs;             /* hsync timing */
+       u32 thc_hsdvs;
+       u32 thc_hd;
+       u32 thc_vs;             /* vsync timing */
+       u32 thc_vd;
+       u32 thc_refresh;
+       u32 thc_misc;
        u32 thc_pad1[56];
-       volatile u32 thc_cursxy;        /* cursor x,y position (16 bits each) */
-       volatile u32 thc_cursmask[32];  /* cursor mask bits */
-       volatile u32 thc_cursbits[32];  /* what to show where mask enabled */
+       u32 thc_cursxy; /* cursor x,y position (16 bits each) */
+       u32 thc_cursmask[32];   /* cursor mask bits */
+       u32 thc_cursbits[32];   /* what to show where mask enabled */
 };
 
 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;
 };
 
 #define TCX_MMAP_ENTRIES 14
@@ -112,24 +112,23 @@ struct tcx_par {
        struct bt_regs          __iomem *bt;
        struct tcx_thc          __iomem *thc;
        struct tcx_tec          __iomem *tec;
-       volatile u32            __iomem *cplane;
+       u32                     __iomem *cplane;
 
        u32                     flags;
 #define TCX_FLAG_BLANKED       0x00000001
 
        unsigned long           physbase;
+       unsigned long           which_io;
        unsigned long           fbsize;
 
        struct sbus_mmap_map    mmap_map[TCX_MMAP_ENTRIES];
        int                     lowdepth;
-
-       struct sbus_dev         *sdev;
 };
 
 /* Reset control plane so that WID is 8-bit plane. */
 static void __tcx_set_control_plane (struct tcx_par *par)
 {
-       volatile u32 __iomem *p, *pend;
+       u32 __iomem *p, *pend;
         
        if (par->lowdepth)
                return;
@@ -307,8 +306,7 @@ static int tcx_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
        return sbusfb_mmap_helper(par->mmap_map,
                                  par->physbase, par->fbsize,
-                                 par->sdev->reg_addrs[0].which_io,
-                                 vma);
+                                 par->which_io, vma);
 }
 
 static int tcx_ioctl(struct fb_info *info, unsigned int cmd,
@@ -350,48 +348,71 @@ tcx_init_fix(struct fb_info *info, int linebytes)
 struct all_info {
        struct fb_info info;
        struct tcx_par par;
-       struct list_head list;
 };
-static LIST_HEAD(tcx_list);
 
-static void tcx_init_one(struct sbus_dev *sdev)
+static void tcx_unmap_regs(struct all_info *all)
 {
-       struct all_info *all;
-       int linebytes, i;
+       if (all->par.tec)
+               of_iounmap(all->par.tec, sizeof(struct tcx_tec));
+       if (all->par.thc)
+               of_iounmap(all->par.thc, sizeof(struct tcx_thc));
+       if (all->par.bt)
+               of_iounmap(all->par.bt, sizeof(struct bt_regs));
+       if (all->par.cplane)
+               of_iounmap(all->par.cplane, all->par.fbsize * sizeof(u32));
+       if (all->info.screen_base)
+               of_iounmap(all->info.screen_base, all->par.fbsize);
+}
 
-       all = kmalloc(sizeof(*all), GFP_KERNEL);
-       if (!all) {
-               printk(KERN_ERR "tcx: Cannot allocate memory.\n");
-               return;
-       }
-       memset(all, 0, sizeof(*all));
+static int __devinit tcx_init_one(struct of_device *op)
+{
+       struct device_node *dp = op->node;
+       struct all_info *all;
+       int linebytes, i, err;
 
-       INIT_LIST_HEAD(&all->list);
+       all = kzalloc(sizeof(*all), GFP_KERNEL);
+       if (!all)
+               return -ENOMEM;
 
        spin_lock_init(&all->par.lock);
-       all->par.sdev = sdev;
 
-       all->par.lowdepth = prom_getbool(sdev->prom_node, "tcx-8-bit");
+       all->par.lowdepth =
+               (of_find_property(dp, "tcx-8-bit", NULL) != NULL);
 
-       sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+       sbusfb_fill_var(&all->info.var, dp->node, 8);
        all->info.var.red.length = 8;
        all->info.var.green.length = 8;
        all->info.var.blue.length = 8;
 
-       linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
-                                      all->info.var.xres);
+       linebytes = of_getintprop_default(dp, "linebytes",
+                                         all->info.var.xres);
        all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
 
-       all->par.tec = sbus_ioremap(&sdev->resource[7], 0,
-                            sizeof(struct tcx_tec), "tcx tec");
-       all->par.thc = sbus_ioremap(&sdev->resource[9], 0,
-                            sizeof(struct tcx_thc), "tcx thc");
-       all->par.bt = sbus_ioremap(&sdev->resource[8], 0,
-                            sizeof(struct bt_regs), "tcx dac");
+       all->par.tec = of_ioremap(&op->resource[7], 0,
+                                 sizeof(struct tcx_tec), "tcx tec");
+       all->par.thc = of_ioremap(&op->resource[9], 0,
+                                 sizeof(struct tcx_thc), "tcx thc");
+       all->par.bt = of_ioremap(&op->resource[8], 0,
+                                sizeof(struct bt_regs), "tcx dac");
+       all->info.screen_base = of_ioremap(&op->resource[0], 0,
+                                          all->par.fbsize, "tcx ram");
+       if (!all->par.tec || !all->par.thc ||
+           !all->par.bt || !all->info.screen_base) {
+               tcx_unmap_regs(all);
+               kfree(all);
+               return -ENOMEM;
+       }
+
        memcpy(&all->par.mmap_map, &__tcx_mmap_map, sizeof(all->par.mmap_map));
        if (!all->par.lowdepth) {
-               all->par.cplane = sbus_ioremap(&sdev->resource[4], 0,
-                                    all->par.fbsize * sizeof(u32), "tcx cplane");
+               all->par.cplane = of_ioremap(&op->resource[4], 0,
+                                            all->par.fbsize * sizeof(u32),
+                                            "tcx cplane");
+               if (!all->par.cplane) {
+                       tcx_unmap_regs(all);
+                       kfree(all);
+                       return -ENOMEM;
+               }
        } else {
                all->par.mmap_map[1].size = SBUS_MMAP_EMPTY;
                all->par.mmap_map[4].size = SBUS_MMAP_EMPTY;
@@ -400,6 +421,8 @@ static void tcx_init_one(struct sbus_dev *sdev)
        }
 
        all->par.physbase = 0;
+       all->par.which_io = op->resource[0].flags & IORESOURCE_BITS;
+
        for (i = 0; i < TCX_MMAP_ENTRIES; i++) {
                int j;
 
@@ -416,18 +439,11 @@ static void tcx_init_one(struct sbus_dev *sdev)
                        j = i;
                        break;
                };
-               all->par.mmap_map[i].poff = sdev->reg_addrs[j].phys_addr;
+               all->par.mmap_map[i].poff = op->resource[j].start;
        }
 
        all->info.flags = FBINFO_DEFAULT;
        all->info.fbops = &tcx_ops;
-#ifdef CONFIG_SPARC32
-       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(&sdev->resource[0], 0,
-                                    all->par.fbsize, "tcx ram");
        all->info.par = &all->par;
 
        /* Initialize brooktree DAC. */
@@ -445,72 +461,88 @@ static void tcx_init_one(struct sbus_dev *sdev)
        tcx_blank(FB_BLANK_UNBLANK, &all->info);
 
        if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
-               printk(KERN_ERR "tcx: Could not allocate color map.\n");
+               tcx_unmap_regs(all);
                kfree(all);
-               return;
+               return -ENOMEM;
        }
 
        fb_set_cmap(&all->info.cmap, &all->info);
        tcx_init_fix(&all->info, linebytes);
 
-       if (register_framebuffer(&all->info) < 0) {
-               printk(KERN_ERR "tcx: Could not register framebuffer.\n");
+       err = register_framebuffer(&all->info);
+       if (err < 0) {
                fb_dealloc_cmap(&all->info.cmap);
+               tcx_unmap_regs(all);
                kfree(all);
-               return;
+               return err;
        }
 
-       list_add(&all->list, &tcx_list);
+       dev_set_drvdata(&op->dev, all);
 
-       printk("tcx: %s at %lx:%lx, %s\n",
-              sdev->prom_name,
-              (long) sdev->reg_addrs[0].which_io,
-              (long) sdev->reg_addrs[0].phys_addr,
+       printk("%s: TCX at %lx:%lx, %s\n",
+              dp->full_name,
+              all->par.which_io,
+              op->resource[0].start,
               all->par.lowdepth ? "8-bit only" : "24-bit depth");
+
+       return 0;
 }
 
-int __init tcx_init(void)
+static int __devinit tcx_probe(struct of_device *dev, const struct of_device_id *match)
 {
-       struct sbus_bus *sbus;
-       struct sbus_dev *sdev;
+       struct of_device *op = to_of_device(&dev->dev);
 
-       if (fb_get_options("tcxfb", NULL))
-               return -ENODEV;
+       return tcx_init_one(op);
+}
 
-       for_all_sbusdev(sdev, sbus) {
-               if (!strcmp(sdev->prom_name, "SUNW,tcx"))
-                       tcx_init_one(sdev);
-       }
+static int __devexit tcx_remove(struct of_device *dev)
+{
+       struct all_info *all = dev_get_drvdata(&dev->dev);
+
+       unregister_framebuffer(&all->info);
+       fb_dealloc_cmap(&all->info.cmap);
+
+       tcx_unmap_regs(all);
+
+       kfree(all);
+
+       dev_set_drvdata(&dev->dev, NULL);
 
        return 0;
 }
 
-void __exit tcx_exit(void)
-{
-       struct list_head *pos, *tmp;
+static struct of_device_id tcx_match[] = {
+       {
+               .name = "SUNW,tcx",
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, tcx_match);
 
-       list_for_each_safe(pos, tmp, &tcx_list) {
-               struct all_info *all = list_entry(pos, typeof(*all), list);
+static struct of_platform_driver tcx_driver = {
+       .name           = "tcx",
+       .match_table    = tcx_match,
+       .probe          = tcx_probe,
+       .remove         = __devexit_p(tcx_remove),
+};
 
-               unregister_framebuffer(&all->info);
-               fb_dealloc_cmap(&all->info.cmap);
-               kfree(all);
-       }
+int __init tcx_init(void)
+{
+       if (fb_get_options("tcxfb", NULL))
+               return -ENODEV;
+
+       return of_register_driver(&tcx_driver, &of_bus_type);
 }
 
-int __init
-tcx_setup(char *arg)
+void __exit tcx_exit(void)
 {
-       /* No cmdline options yet... */
-       return 0;
+       of_unregister_driver(&tcx_driver);
 }
 
 module_init(tcx_init);
-
-#ifdef MODULE
 module_exit(tcx_exit);
-#endif
 
 MODULE_DESCRIPTION("framebuffer driver for TCX chipsets");
-MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
+MODULE_VERSION("2.0");
 MODULE_LICENSE("GPL");