[SPARC]: Convert all FB SBUS drivers to of_driver framework.

Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 7633e41..2a0e821 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -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 @@
 
 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	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];	
-	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	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 @@
 	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 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 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 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 @@
 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 @@
 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 @@
 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 @@
 	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;
-	}
-
-	if (ffb_apply_upa_parent_ranges(parent, &regs[0])) {
-		printk("ffb: Cannot apply parent ranges to regs.\n");
-		return;
-	}
-
-	all = kmalloc(sizeof(*all), GFP_KERNEL);
-	if (!all) {
-		printk(KERN_ERR "ffb: 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.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.fbc = of_ioremap(&op->resource[2], 0,
+				  sizeof(struct ffb_fbc), "ffb fbc");
+	if (!all->par.fbc) {
+		kfree(all);
+		return -ENOMEM;
+	}
+
+	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;
+	}
+
 	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 @@
 	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 @@
 
 	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 @@
 	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;
+	struct of_device *op = to_of_device(&dev->dev);
 
-	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);
+	return ffb_init_one(op);
 }
 
+static int __devexit ffb_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.fbc, sizeof(struct ffb_fbc));
+	of_iounmap(all->par.dac, sizeof(struct ffb_dac));
+
+	kfree(all);
+
+	dev_set_drvdata(&dev->dev, NULL);
+
+	return 0;
+}
+
+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),
+};
+
 int __init ffb_init(void)
 {
-	int root;
-
 	if (fb_get_options("ffb", NULL))
 		return -ENODEV;
 
-	ffb_scan_siblings(prom_root_node);
-
-	root = prom_getchild(prom_root_node);
-	for (root = prom_searchsiblings(root, "upa"); root;
-	     root = prom_searchsiblings(prom_getsibling(root), "upa"))
-		ffb_scan_siblings(root);
-
-	return 0;
+	return of_register_driver(&ffb_driver, &of_bus_type);
 }
 
 void __exit ffb_exit(void)
 {
-	struct list_head *pos, *tmp;
-
-	list_for_each_safe(pos, tmp, &ffb_list) {
-		struct all_info *all = list_entry(pos, typeof(*all), list);
-
-		unregister_framebuffer(&all->info);
-		fb_dealloc_cmap(&all->info.cmap);
-		kfree(all);
-	}
-}
-
-int __init
-ffb_setup(char *arg)
-{
-	/* 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");