aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/ffb.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2006-06-29 17:35:52 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-29 19:37:18 -0400
commit50312ce9dd794eef3df9e64194ba95ca730d82c8 (patch)
tree15703fd98b8b757197d43e11f8de791bbc3b8f00 /drivers/video/ffb.c
parent3ca9fab410fbef6fc3a13284f5c26faccade21d1 (diff)
[SPARC]: Convert all FB SBUS drivers to of_driver framework.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/video/ffb.c')
-rw-r--r--drivers/video/ffb.c466
1 files changed, 217 insertions, 249 deletions
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 7633e41adda1..2a0e8210d398 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -1,6 +1,6 @@
1/* ffb.c: Creator/Elite3D frame buffer driver 1/* ffb.c: Creator/Elite3D frame buffer driver
2 * 2 *
3 * Copyright (C) 2003 David S. Miller (davem@redhat.com) 3 * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net)
4 * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz) 4 * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz)
5 * 5 *
6 * Driver layout based loosely on tgafb.c, see that file for credits. 6 * Driver layout based loosely on tgafb.c, see that file for credits.
@@ -19,7 +19,8 @@
19 19
20#include <asm/io.h> 20#include <asm/io.h>
21#include <asm/upa.h> 21#include <asm/upa.h>
22#include <asm/oplib.h> 22#include <asm/prom.h>
23#include <asm/of_device.h>
23#include <asm/fbio.h> 24#include <asm/fbio.h>
24 25
25#include "sbuslib.h" 26#include "sbuslib.h"
@@ -184,161 +185,161 @@ static struct fb_ops ffb_ops = {
184 185
185struct ffb_fbc { 186struct ffb_fbc {
186 /* Next vertex registers */ 187 /* Next vertex registers */
187 u32 xxx1[3]; 188 u32 xxx1[3];
188 volatile u32 alpha; 189 u32 alpha;
189 volatile u32 red; 190 u32 red;
190 volatile u32 green; 191 u32 green;
191 volatile u32 blue; 192 u32 blue;
192 volatile u32 depth; 193 u32 depth;
193 volatile u32 y; 194 u32 y;
194 volatile u32 x; 195 u32 x;
195 u32 xxx2[2]; 196 u32 xxx2[2];
196 volatile u32 ryf; 197 u32 ryf;
197 volatile u32 rxf; 198 u32 rxf;
198 u32 xxx3[2]; 199 u32 xxx3[2];
199 200
200 volatile u32 dmyf; 201 u32 dmyf;
201 volatile u32 dmxf; 202 u32 dmxf;
202 u32 xxx4[2]; 203 u32 xxx4[2];
203 volatile u32 ebyi; 204 u32 ebyi;
204 volatile u32 ebxi; 205 u32 ebxi;
205 u32 xxx5[2]; 206 u32 xxx5[2];
206 volatile u32 by; 207 u32 by;
207 volatile u32 bx; 208 u32 bx;
208 u32 dy; 209 u32 dy;
209 u32 dx; 210 u32 dx;
210 volatile u32 bh; 211 u32 bh;
211 volatile u32 bw; 212 u32 bw;
212 u32 xxx6[2]; 213 u32 xxx6[2];
213 214
214 u32 xxx7[32]; 215 u32 xxx7[32];
215 216
216 /* Setup unit vertex state register */ 217 /* Setup unit vertex state register */
217 volatile u32 suvtx; 218 u32 suvtx;
218 u32 xxx8[63]; 219 u32 xxx8[63];
219 220
220 /* Control registers */ 221 /* Control registers */
221 volatile u32 ppc; 222 u32 ppc;
222 volatile u32 wid; 223 u32 wid;
223 volatile u32 fg; 224 u32 fg;
224 volatile u32 bg; 225 u32 bg;
225 volatile u32 consty; 226 u32 consty;
226 volatile u32 constz; 227 u32 constz;
227 volatile u32 xclip; 228 u32 xclip;
228 volatile u32 dcss; 229 u32 dcss;
229 volatile u32 vclipmin; 230 u32 vclipmin;
230 volatile u32 vclipmax; 231 u32 vclipmax;
231 volatile u32 vclipzmin; 232 u32 vclipzmin;
232 volatile u32 vclipzmax; 233 u32 vclipzmax;
233 volatile u32 dcsf; 234 u32 dcsf;
234 volatile u32 dcsb; 235 u32 dcsb;
235 volatile u32 dczf; 236 u32 dczf;
236 volatile u32 dczb; 237 u32 dczb;
237 238
238 u32 xxx9; 239 u32 xxx9;
239 volatile u32 blendc; 240 u32 blendc;
240 volatile u32 blendc1; 241 u32 blendc1;
241 volatile u32 blendc2; 242 u32 blendc2;
242 volatile u32 fbramitc; 243 u32 fbramitc;
243 volatile u32 fbc; 244 u32 fbc;
244 volatile u32 rop; 245 u32 rop;
245 volatile u32 cmp; 246 u32 cmp;
246 volatile u32 matchab; 247 u32 matchab;
247 volatile u32 matchc; 248 u32 matchc;
248 volatile u32 magnab; 249 u32 magnab;
249 volatile u32 magnc; 250 u32 magnc;
250 volatile u32 fbcfg0; 251 u32 fbcfg0;
251 volatile u32 fbcfg1; 252 u32 fbcfg1;
252 volatile u32 fbcfg2; 253 u32 fbcfg2;
253 volatile u32 fbcfg3; 254 u32 fbcfg3;
254 255
255 u32 ppcfg; 256 u32 ppcfg;
256 volatile u32 pick; 257 u32 pick;
257 volatile u32 fillmode; 258 u32 fillmode;
258 volatile u32 fbramwac; 259 u32 fbramwac;
259 volatile u32 pmask; 260 u32 pmask;
260 volatile u32 xpmask; 261 u32 xpmask;
261 volatile u32 ypmask; 262 u32 ypmask;
262 volatile u32 zpmask; 263 u32 zpmask;
263 volatile u32 clip0min; 264 u32 clip0min;
264 volatile u32 clip0max; 265 u32 clip0max;
265 volatile u32 clip1min; 266 u32 clip1min;
266 volatile u32 clip1max; 267 u32 clip1max;
267 volatile u32 clip2min; 268 u32 clip2min;
268 volatile u32 clip2max; 269 u32 clip2max;
269 volatile u32 clip3min; 270 u32 clip3min;
270 volatile u32 clip3max; 271 u32 clip3max;
271 272
272 /* New 3dRAM III support regs */ 273 /* New 3dRAM III support regs */
273 volatile u32 rawblend2; 274 u32 rawblend2;
274 volatile u32 rawpreblend; 275 u32 rawpreblend;
275 volatile u32 rawstencil; 276 u32 rawstencil;
276 volatile u32 rawstencilctl; 277 u32 rawstencilctl;
277 volatile u32 threedram1; 278 u32 threedram1;
278 volatile u32 threedram2; 279 u32 threedram2;
279 volatile u32 passin; 280 u32 passin;
280 volatile u32 rawclrdepth; 281 u32 rawclrdepth;
281 volatile u32 rawpmask; 282 u32 rawpmask;
282 volatile u32 rawcsrc; 283 u32 rawcsrc;
283 volatile u32 rawmatch; 284 u32 rawmatch;
284 volatile u32 rawmagn; 285 u32 rawmagn;
285 volatile u32 rawropblend; 286 u32 rawropblend;
286 volatile u32 rawcmp; 287 u32 rawcmp;
287 volatile u32 rawwac; 288 u32 rawwac;
288 volatile u32 fbramid; 289 u32 fbramid;
289 290
290 volatile u32 drawop; 291 u32 drawop;
291 u32 xxx10[2]; 292 u32 xxx10[2];
292 volatile u32 fontlpat; 293 u32 fontlpat;
293 u32 xxx11; 294 u32 xxx11;
294 volatile u32 fontxy; 295 u32 fontxy;
295 volatile u32 fontw; 296 u32 fontw;
296 volatile u32 fontinc; 297 u32 fontinc;
297 volatile u32 font; 298 u32 font;
298 u32 xxx12[3]; 299 u32 xxx12[3];
299 volatile u32 blend2; 300 u32 blend2;
300 volatile u32 preblend; 301 u32 preblend;
301 volatile u32 stencil; 302 u32 stencil;
302 volatile u32 stencilctl; 303 u32 stencilctl;
303 304
304 u32 xxx13[4]; 305 u32 xxx13[4];
305 volatile u32 dcss1; 306 u32 dcss1;
306 volatile u32 dcss2; 307 u32 dcss2;
307 volatile u32 dcss3; 308 u32 dcss3;
308 volatile u32 widpmask; 309 u32 widpmask;
309 volatile u32 dcs2; 310 u32 dcs2;
310 volatile u32 dcs3; 311 u32 dcs3;
311 volatile u32 dcs4; 312 u32 dcs4;
312 u32 xxx14; 313 u32 xxx14;
313 volatile u32 dcd2; 314 u32 dcd2;
314 volatile u32 dcd3; 315 u32 dcd3;
315 volatile u32 dcd4; 316 u32 dcd4;
316 u32 xxx15; 317 u32 xxx15;
317 318
318 volatile u32 pattern[32]; 319 u32 pattern[32];
319 320
320 u32 xxx16[256]; 321 u32 xxx16[256];
321 322
322 volatile u32 devid; 323 u32 devid;
323 u32 xxx17[63]; 324 u32 xxx17[63];
324 325
325 volatile u32 ucsr; 326 u32 ucsr;
326 u32 xxx18[31]; 327 u32 xxx18[31];
327 328
328 volatile u32 mer; 329 u32 mer;
329}; 330};
330 331
331struct ffb_dac { 332struct ffb_dac {
332 volatile u32 type; 333 u32 type;
333 volatile u32 value; 334 u32 value;
334 volatile u32 type2; 335 u32 type2;
335 volatile u32 value2; 336 u32 value2;
336}; 337};
337 338
338struct ffb_par { 339struct ffb_par {
339 spinlock_t lock; 340 spinlock_t lock;
340 struct ffb_fbc *fbc; 341 struct ffb_fbc __iomem *fbc;
341 struct ffb_dac *dac; 342 struct ffb_dac __iomem *dac;
342 343
343 u32 flags; 344 u32 flags;
344#define FFB_FLAG_AFB 0x00000001 345#define FFB_FLAG_AFB 0x00000001
@@ -353,16 +354,13 @@ struct ffb_par {
353 unsigned long physbase; 354 unsigned long physbase;
354 unsigned long fbsize; 355 unsigned long fbsize;
355 356
356 char name[64];
357 int prom_node;
358 int prom_parent_node;
359 int dac_rev; 357 int dac_rev;
360 int board_type; 358 int board_type;
361}; 359};
362 360
363static void FFBFifo(struct ffb_par *par, int n) 361static void FFBFifo(struct ffb_par *par, int n)
364{ 362{
365 struct ffb_fbc *fbc; 363 struct ffb_fbc __iomem *fbc;
366 int cache = par->fifo_cache; 364 int cache = par->fifo_cache;
367 365
368 if (cache - n < 0) { 366 if (cache - n < 0) {
@@ -375,7 +373,7 @@ static void FFBFifo(struct ffb_par *par, int n)
375 373
376static void FFBWait(struct ffb_par *par) 374static void FFBWait(struct ffb_par *par)
377{ 375{
378 struct ffb_fbc *fbc; 376 struct ffb_fbc __iomem *fbc;
379 int limit = 10000; 377 int limit = 10000;
380 378
381 fbc = par->fbc; 379 fbc = par->fbc;
@@ -408,8 +406,8 @@ static __inline__ void ffb_rop(struct ffb_par *par, u32 rop)
408 406
409static void ffb_switch_from_graph(struct ffb_par *par) 407static void ffb_switch_from_graph(struct ffb_par *par)
410{ 408{
411 struct ffb_fbc *fbc = par->fbc; 409 struct ffb_fbc __iomem *fbc = par->fbc;
412 struct ffb_dac *dac = par->dac; 410 struct ffb_dac __iomem *dac = par->dac;
413 unsigned long flags; 411 unsigned long flags;
414 412
415 spin_lock_irqsave(&par->lock, flags); 413 spin_lock_irqsave(&par->lock, flags);
@@ -462,7 +460,7 @@ static int ffb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
462static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 460static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
463{ 461{
464 struct ffb_par *par = (struct ffb_par *) info->par; 462 struct ffb_par *par = (struct ffb_par *) info->par;
465 struct ffb_fbc *fbc = par->fbc; 463 struct ffb_fbc __iomem *fbc = par->fbc;
466 unsigned long flags; 464 unsigned long flags;
467 u32 fg; 465 u32 fg;
468 466
@@ -505,7 +503,7 @@ static void
505ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area) 503ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
506{ 504{
507 struct ffb_par *par = (struct ffb_par *) info->par; 505 struct ffb_par *par = (struct ffb_par *) info->par;
508 struct ffb_fbc *fbc = par->fbc; 506 struct ffb_fbc __iomem *fbc = par->fbc;
509 unsigned long flags; 507 unsigned long flags;
510 508
511 if (area->dx != area->sx || 509 if (area->dx != area->sx ||
@@ -541,7 +539,7 @@ ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
541static void ffb_imageblit(struct fb_info *info, const struct fb_image *image) 539static void ffb_imageblit(struct fb_info *info, const struct fb_image *image)
542{ 540{
543 struct ffb_par *par = (struct ffb_par *) info->par; 541 struct ffb_par *par = (struct ffb_par *) info->par;
544 struct ffb_fbc *fbc = par->fbc; 542 struct ffb_fbc __iomem *fbc = par->fbc;
545 const u8 *data = image->data; 543 const u8 *data = image->data;
546 unsigned long flags; 544 unsigned long flags;
547 u32 fg, bg, xy; 545 u32 fg, bg, xy;
@@ -664,7 +662,7 @@ static int
664ffb_blank(int blank, struct fb_info *info) 662ffb_blank(int blank, struct fb_info *info)
665{ 663{
666 struct ffb_par *par = (struct ffb_par *) info->par; 664 struct ffb_par *par = (struct ffb_par *) info->par;
667 struct ffb_dac *dac = par->dac; 665 struct ffb_dac __iomem *dac = par->dac;
668 unsigned long flags; 666 unsigned long flags;
669 u32 tmp; 667 u32 tmp;
670 668
@@ -883,78 +881,42 @@ ffb_init_fix(struct fb_info *info)
883 info->fix.accel = FB_ACCEL_SUN_CREATOR; 881 info->fix.accel = FB_ACCEL_SUN_CREATOR;
884} 882}
885 883
886static int ffb_apply_upa_parent_ranges(int parent,
887 struct linux_prom64_registers *regs)
888{
889 struct linux_prom64_ranges ranges[PROMREG_MAX];
890 char name[128];
891 int len, i;
892
893 prom_getproperty(parent, "name", name, sizeof(name));
894 if (strcmp(name, "upa") != 0)
895 return 0;
896
897 len = prom_getproperty(parent, "ranges", (void *) ranges, sizeof(ranges));
898 if (len <= 0)
899 return 1;
900
901 len /= sizeof(struct linux_prom64_ranges);
902 for (i = 0; i < len; i++) {
903 struct linux_prom64_ranges *rng = &ranges[i];
904 u64 phys_addr = regs->phys_addr;
905
906 if (phys_addr >= rng->ot_child_base &&
907 phys_addr < (rng->ot_child_base + rng->or_size)) {
908 regs->phys_addr -= rng->ot_child_base;
909 regs->phys_addr += rng->ot_parent_base;
910 return 0;
911 }
912 }
913
914 return 1;
915}
916
917struct all_info { 884struct all_info {
918 struct fb_info info; 885 struct fb_info info;
919 struct ffb_par par; 886 struct ffb_par par;
920 u32 pseudo_palette[256]; 887 u32 pseudo_palette[256];
921 struct list_head list;
922}; 888};
923static LIST_HEAD(ffb_list);
924 889
925static void ffb_init_one(int node, int parent) 890static int ffb_init_one(struct of_device *op)
926{ 891{
927 struct linux_prom64_registers regs[2*PROMREG_MAX]; 892 struct device_node *dp = op->node;
928 struct ffb_fbc *fbc; 893 struct ffb_fbc __iomem *fbc;
929 struct ffb_dac *dac; 894 struct ffb_dac __iomem *dac;
930 struct all_info *all; 895 struct all_info *all;
896 int err;
931 897
932 if (prom_getproperty(node, "reg", (void *) regs, sizeof(regs)) <= 0) { 898 all = kzalloc(sizeof(*all), GFP_KERNEL);
933 printk("ffb: Cannot get reg device node property.\n"); 899 if (!all)
934 return; 900 return -ENOMEM;
935 }
936 901
937 if (ffb_apply_upa_parent_ranges(parent, &regs[0])) { 902 spin_lock_init(&all->par.lock);
938 printk("ffb: Cannot apply parent ranges to regs.\n"); 903 all->par.fbc = of_ioremap(&op->resource[2], 0,
939 return; 904 sizeof(struct ffb_fbc), "ffb fbc");
905 if (!all->par.fbc) {
906 kfree(all);
907 return -ENOMEM;
940 } 908 }
941 909
942 all = kmalloc(sizeof(*all), GFP_KERNEL); 910 all->par.dac = of_ioremap(&op->resource[1], 0,
943 if (!all) { 911 sizeof(struct ffb_dac), "ffb dac");
944 printk(KERN_ERR "ffb: Cannot allocate memory.\n"); 912 if (!all->par.dac) {
945 return; 913 of_iounmap(all->par.fbc, sizeof(struct ffb_fbc));
914 kfree(all);
915 return -ENOMEM;
946 } 916 }
947 memset(all, 0, sizeof(*all));
948
949 INIT_LIST_HEAD(&all->list);
950 917
951 spin_lock_init(&all->par.lock);
952 all->par.fbc = (struct ffb_fbc *)(regs[0].phys_addr + FFB_FBC_REGS_POFF);
953 all->par.dac = (struct ffb_dac *)(regs[0].phys_addr + FFB_DAC_POFF);
954 all->par.rop_cache = FFB_ROP_NEW; 918 all->par.rop_cache = FFB_ROP_NEW;
955 all->par.physbase = regs[0].phys_addr; 919 all->par.physbase = op->resource[0].start;
956 all->par.prom_node = node;
957 all->par.prom_parent_node = parent;
958 920
959 /* Don't mention copyarea, so SCROLL_REDRAW is always 921 /* Don't mention copyarea, so SCROLL_REDRAW is always
960 * used. It is the fastest on this chip. 922 * used. It is the fastest on this chip.
@@ -968,7 +930,7 @@ static void ffb_init_one(int node, int parent)
968 all->info.par = &all->par; 930 all->info.par = &all->par;
969 all->info.pseudo_palette = all->pseudo_palette; 931 all->info.pseudo_palette = all->pseudo_palette;
970 932
971 sbusfb_fill_var(&all->info.var, all->par.prom_node, 32); 933 sbusfb_fill_var(&all->info.var, dp->node, 32);
972 all->par.fbsize = PAGE_ALIGN(all->info.var.xres * 934 all->par.fbsize = PAGE_ALIGN(all->info.var.xres *
973 all->info.var.yres * 935 all->info.var.yres *
974 4); 936 4);
@@ -976,14 +938,13 @@ static void ffb_init_one(int node, int parent)
976 938
977 all->info.var.accel_flags = FB_ACCELF_TEXT; 939 all->info.var.accel_flags = FB_ACCELF_TEXT;
978 940
979 prom_getstring(node, "name", all->par.name, sizeof(all->par.name)); 941 if (!strcmp(dp->name, "SUNW,afb"))
980 if (!strcmp(all->par.name, "SUNW,afb"))
981 all->par.flags |= FFB_FLAG_AFB; 942 all->par.flags |= FFB_FLAG_AFB;
982 943
983 all->par.board_type = prom_getintdefault(node, "board_type", 0); 944 all->par.board_type = of_getintprop_default(dp, "board_type", 0);
984 945
985 fbc = all->par.fbc; 946 fbc = all->par.fbc;
986 if((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0) 947 if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0)
987 upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr); 948 upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr);
988 949
989 ffb_switch_from_graph(&all->par); 950 ffb_switch_from_graph(&all->par);
@@ -1008,81 +969,88 @@ static void ffb_init_one(int node, int parent)
1008 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 969 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
1009 printk(KERN_ERR "ffb: Could not allocate color map.\n"); 970 printk(KERN_ERR "ffb: Could not allocate color map.\n");
1010 kfree(all); 971 kfree(all);
1011 return; 972 return -ENOMEM;
1012 } 973 }
1013 974
1014 ffb_init_fix(&all->info); 975 ffb_init_fix(&all->info);
1015 976
1016 if (register_framebuffer(&all->info) < 0) { 977 err = register_framebuffer(&all->info);
978 if (err < 0) {
1017 printk(KERN_ERR "ffb: Could not register framebuffer.\n"); 979 printk(KERN_ERR "ffb: Could not register framebuffer.\n");
1018 fb_dealloc_cmap(&all->info.cmap); 980 fb_dealloc_cmap(&all->info.cmap);
1019 kfree(all); 981 kfree(all);
1020 return; 982 return err;
1021 } 983 }
1022 984
1023 list_add(&all->list, &ffb_list); 985 dev_set_drvdata(&op->dev, all);
1024 986
1025 printk("ffb: %s at %016lx type %d DAC %d\n", 987 printk("%s: %s at %016lx, type %d, DAC revision %d\n",
988 dp->full_name,
1026 ((all->par.flags & FFB_FLAG_AFB) ? "AFB" : "FFB"), 989 ((all->par.flags & FFB_FLAG_AFB) ? "AFB" : "FFB"),
1027 regs[0].phys_addr, all->par.board_type, all->par.dac_rev); 990 all->par.physbase, all->par.board_type, all->par.dac_rev);
991
992 return 0;
1028} 993}
1029 994
1030static void ffb_scan_siblings(int root) 995static int __devinit ffb_probe(struct of_device *dev, const struct of_device_id *match)
1031{ 996{
1032 int node, child; 997 struct of_device *op = to_of_device(&dev->dev);
1033 998
1034 child = prom_getchild(root); 999 return ffb_init_one(op);
1035 for (node = prom_searchsiblings(child, "SUNW,ffb"); node;
1036 node = prom_searchsiblings(prom_getsibling(node), "SUNW,ffb"))
1037 ffb_init_one(node, root);
1038 for (node = prom_searchsiblings(child, "SUNW,afb"); node;
1039 node = prom_searchsiblings(prom_getsibling(node), "SUNW,afb"))
1040 ffb_init_one(node, root);
1041} 1000}
1042 1001
1043int __init ffb_init(void) 1002static int __devexit ffb_remove(struct of_device *dev)
1044{ 1003{
1045 int root; 1004 struct all_info *all = dev_get_drvdata(&dev->dev);
1046 1005
1047 if (fb_get_options("ffb", NULL)) 1006 unregister_framebuffer(&all->info);
1048 return -ENODEV; 1007 fb_dealloc_cmap(&all->info.cmap);
1049 1008
1050 ffb_scan_siblings(prom_root_node); 1009 of_iounmap(all->par.fbc, sizeof(struct ffb_fbc));
1010 of_iounmap(all->par.dac, sizeof(struct ffb_dac));
1051 1011
1052 root = prom_getchild(prom_root_node); 1012 kfree(all);
1053 for (root = prom_searchsiblings(root, "upa"); root; 1013
1054 root = prom_searchsiblings(prom_getsibling(root), "upa")) 1014 dev_set_drvdata(&dev->dev, NULL);
1055 ffb_scan_siblings(root);
1056 1015
1057 return 0; 1016 return 0;
1058} 1017}
1059 1018
1060void __exit ffb_exit(void) 1019static struct of_device_id ffb_match[] = {
1061{ 1020 {
1062 struct list_head *pos, *tmp; 1021 .name = "SUNW,ffb",
1022 },
1023 {
1024 .name = "SUNW,afb",
1025 },
1026 {},
1027};
1028MODULE_DEVICE_TABLE(of, ffb_match);
1029
1030static struct of_platform_driver ffb_driver = {
1031 .name = "ffb",
1032 .match_table = ffb_match,
1033 .probe = ffb_probe,
1034 .remove = __devexit_p(ffb_remove),
1035};
1063 1036
1064 list_for_each_safe(pos, tmp, &ffb_list) { 1037int __init ffb_init(void)
1065 struct all_info *all = list_entry(pos, typeof(*all), list); 1038{
1039 if (fb_get_options("ffb", NULL))
1040 return -ENODEV;
1066 1041
1067 unregister_framebuffer(&all->info); 1042 return of_register_driver(&ffb_driver, &of_bus_type);
1068 fb_dealloc_cmap(&all->info.cmap);
1069 kfree(all);
1070 }
1071} 1043}
1072 1044
1073int __init 1045void __exit ffb_exit(void)
1074ffb_setup(char *arg)
1075{ 1046{
1076 /* No cmdline options yet... */ 1047 of_unregister_driver(&ffb_driver);
1077 return 0;
1078} 1048}
1079 1049
1080module_init(ffb_init); 1050module_init(ffb_init);
1081
1082#ifdef MODULE
1083module_exit(ffb_exit); 1051module_exit(ffb_exit);
1084#endif
1085 1052
1086MODULE_DESCRIPTION("framebuffer driver for Creator/Elite3D chipsets"); 1053MODULE_DESCRIPTION("framebuffer driver for Creator/Elite3D chipsets");
1087MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); 1054MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
1055MODULE_VERSION("2.0");
1088MODULE_LICENSE("GPL"); 1056MODULE_LICENSE("GPL");