aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-07-28 01:31:46 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-30 03:27:33 -0400
commitc7f439b99efbea74c70a5531f92566db5a6731f2 (patch)
tree7053ceffa23d54670862e14d0bc2eec9d5d42427 /drivers
parenta0afaa6ab12cf696d170c22a8fdfd88c3e33555c (diff)
[VIDEO]: Fix OOPS in all SBUS framebuffer drivers.
All of these drivers use a silly: struct all_info { struct fb_info info; struct foo_par par; }; struct all_info *all = kzalloc(sizeof(*all), GFP_KERNEL); all->info.par = &all->par; etc. etc. code sequence, basically replicating the provided framebuffer_alloc()/framebuffer_release(), and doing it badly. Not only is this massive code duplication, it also caused a bug in that we weren't setting the fb_info->device pointer which results in an OOPS when fb_is_primary_device() runs. Fix all of this by using framebuffer_{alloc,release}() and passing in "&of_device->dev" as the device pointer. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/bw2.c105
-rw-r--r--drivers/video/cg14.c150
-rw-r--r--drivers/video/cg3.c136
-rw-r--r--drivers/video/cg6.c161
-rw-r--r--drivers/video/ffb.c170
-rw-r--r--drivers/video/leo.c147
-rw-r--r--drivers/video/p9100.c138
-rw-r--r--drivers/video/tcx.c184
8 files changed, 567 insertions, 624 deletions
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index b0b2e40bbd9f..718b9f83736e 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -279,90 +279,91 @@ static void __devinit bw2_do_default_mode(struct bw2_par *par,
279 } 279 }
280} 280}
281 281
282struct all_info { 282static int __devinit bw2_probe(struct of_device *op, const struct of_device_id *match)
283 struct fb_info info;
284 struct bw2_par par;
285};
286
287static int __devinit bw2_init_one(struct of_device *op)
288{ 283{
289 struct device_node *dp = op->node; 284 struct device_node *dp = op->node;
290 struct all_info *all; 285 struct fb_info *info;
286 struct bw2_par *par;
291 int linebytes, err; 287 int linebytes, err;
292 288
293 all = kzalloc(sizeof(*all), GFP_KERNEL); 289 info = framebuffer_alloc(sizeof(struct bw2_par), &op->dev);
294 if (!all)
295 return -ENOMEM;
296 290
297 spin_lock_init(&all->par.lock); 291 err = -ENOMEM;
292 if (!info)
293 goto out_err;
294 par = info->par;
298 295
299 all->par.physbase = op->resource[0].start; 296 spin_lock_init(&par->lock);
300 all->par.which_io = op->resource[0].flags & IORESOURCE_BITS;
301 297
302 sbusfb_fill_var(&all->info.var, dp->node, 1); 298 par->physbase = op->resource[0].start;
299 par->which_io = op->resource[0].flags & IORESOURCE_BITS;
300
301 sbusfb_fill_var(&info->var, dp->node, 1);
303 linebytes = of_getintprop_default(dp, "linebytes", 302 linebytes = of_getintprop_default(dp, "linebytes",
304 all->info.var.xres); 303 info->var.xres);
305 304
306 all->info.var.red.length = all->info.var.green.length = 305 info->var.red.length = info->var.green.length =
307 all->info.var.blue.length = all->info.var.bits_per_pixel; 306 info->var.blue.length = info->var.bits_per_pixel;
308 all->info.var.red.offset = all->info.var.green.offset = 307 info->var.red.offset = info->var.green.offset =
309 all->info.var.blue.offset = 0; 308 info->var.blue.offset = 0;
310 309
311 all->par.regs = of_ioremap(&op->resource[0], BWTWO_REGISTER_OFFSET, 310 par->regs = of_ioremap(&op->resource[0], BWTWO_REGISTER_OFFSET,
312 sizeof(struct bw2_regs), "bw2 regs"); 311 sizeof(struct bw2_regs), "bw2 regs");
312 if (!par->regs)
313 goto out_release_fb;
313 314
314 if (!of_find_property(dp, "width", NULL)) 315 if (!of_find_property(dp, "width", NULL))
315 bw2_do_default_mode(&all->par, &all->info, &linebytes); 316 bw2_do_default_mode(par, info, &linebytes);
316 317
317 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 318 par->fbsize = PAGE_ALIGN(linebytes * info->var.yres);
318 319
319 all->info.flags = FBINFO_DEFAULT; 320 info->flags = FBINFO_DEFAULT;
320 all->info.fbops = &bw2_ops; 321 info->fbops = &bw2_ops;
321 322
322 all->info.screen_base = 323 info->screen_base = of_ioremap(&op->resource[0], 0,
323 of_ioremap(&op->resource[0], 0, all->par.fbsize, "bw2 ram"); 324 par->fbsize, "bw2 ram");
324 all->info.par = &all->par; 325 if (!info->screen_base)
326 goto out_unmap_regs;
325 327
326 bw2_blank(0, &all->info); 328 bw2_blank(0, info);
327 329
328 bw2_init_fix(&all->info, linebytes); 330 bw2_init_fix(info, linebytes);
329 331
330 err= register_framebuffer(&all->info); 332 err = register_framebuffer(info);
331 if (err < 0) { 333 if (err < 0)
332 of_iounmap(&op->resource[0], 334 goto out_unmap_screen;
333 all->par.regs, sizeof(struct bw2_regs));
334 of_iounmap(&op->resource[0],
335 all->info.screen_base, all->par.fbsize);
336 kfree(all);
337 return err;
338 }
339 335
340 dev_set_drvdata(&op->dev, all); 336 dev_set_drvdata(&op->dev, info);
341 337
342 printk("%s: bwtwo at %lx:%lx\n", 338 printk("%s: bwtwo at %lx:%lx\n",
343 dp->full_name, 339 dp->full_name, par->which_io, par->physbase);
344 all->par.which_io, all->par.physbase);
345 340
346 return 0; 341 return 0;
347}
348 342
349static int __devinit bw2_probe(struct of_device *dev, const struct of_device_id *match) 343out_unmap_screen:
350{ 344 of_iounmap(&op->resource[0], info->screen_base, par->fbsize);
351 struct of_device *op = to_of_device(&dev->dev); 345
346out_unmap_regs:
347 of_iounmap(&op->resource[0], par->regs, sizeof(struct bw2_regs));
348
349out_release_fb:
350 framebuffer_release(info);
352 351
353 return bw2_init_one(op); 352out_err:
353 return err;
354} 354}
355 355
356static int __devexit bw2_remove(struct of_device *op) 356static int __devexit bw2_remove(struct of_device *op)
357{ 357{
358 struct all_info *all = dev_get_drvdata(&op->dev); 358 struct fb_info *info = dev_get_drvdata(&op->dev);
359 struct bw2_par *par = info->par;
359 360
360 unregister_framebuffer(&all->info); 361 unregister_framebuffer(info);
361 362
362 of_iounmap(&op->resource[0], all->par.regs, sizeof(struct bw2_regs)); 363 of_iounmap(&op->resource[0], par->regs, sizeof(struct bw2_regs));
363 of_iounmap(&op->resource[0], all->info.screen_base, all->par.fbsize); 364 of_iounmap(&op->resource[0], info->screen_base, par->fbsize);
364 365
365 kfree(all); 366 framebuffer_release(info);
366 367
367 dev_set_drvdata(&op->dev, NULL); 368 dev_set_drvdata(&op->dev, NULL);
368 369
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index b071bb632b97..41f6dbf61be7 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -448,81 +448,79 @@ static struct sbus_mmap_map __cg14_mmap_map[CG14_MMAP_ENTRIES] __devinitdata = {
448 { .size = 0 } 448 { .size = 0 }
449}; 449};
450 450
451struct all_info { 451static void cg14_unmap_regs(struct of_device *op, struct fb_info *info,
452 struct fb_info info; 452 struct cg14_par *par)
453 struct cg14_par par;
454};
455
456static void cg14_unmap_regs(struct of_device *op, struct all_info *all)
457{ 453{
458 if (all->par.regs) 454 if (par->regs)
459 of_iounmap(&op->resource[0], 455 of_iounmap(&op->resource[0],
460 all->par.regs, sizeof(struct cg14_regs)); 456 par->regs, sizeof(struct cg14_regs));
461 if (all->par.clut) 457 if (par->clut)
462 of_iounmap(&op->resource[0], 458 of_iounmap(&op->resource[0],
463 all->par.clut, sizeof(struct cg14_clut)); 459 par->clut, sizeof(struct cg14_clut));
464 if (all->par.cursor) 460 if (par->cursor)
465 of_iounmap(&op->resource[0], 461 of_iounmap(&op->resource[0],
466 all->par.cursor, sizeof(struct cg14_cursor)); 462 par->cursor, sizeof(struct cg14_cursor));
467 if (all->info.screen_base) 463 if (info->screen_base)
468 of_iounmap(&op->resource[1], 464 of_iounmap(&op->resource[1],
469 all->info.screen_base, all->par.fbsize); 465 info->screen_base, par->fbsize);
470} 466}
471 467
472static int __devinit cg14_init_one(struct of_device *op) 468static int __devinit cg14_probe(struct of_device *op, const struct of_device_id *match)
473{ 469{
474 struct device_node *dp = op->node; 470 struct device_node *dp = op->node;
475 struct all_info *all; 471 struct fb_info *info;
472 struct cg14_par *par;
476 int is_8mb, linebytes, i, err; 473 int is_8mb, linebytes, i, err;
477 474
478 all = kzalloc(sizeof(*all), GFP_KERNEL); 475 info = framebuffer_alloc(sizeof(struct cg14_par), &op->dev);
479 if (!all) 476
480 return -ENOMEM; 477 err = -ENOMEM;
478 if (!info)
479 goto out_err;
480 par = info->par;
481 481
482 spin_lock_init(&all->par.lock); 482 spin_lock_init(&par->lock);
483 483
484 sbusfb_fill_var(&all->info.var, dp->node, 8); 484 sbusfb_fill_var(&info->var, dp->node, 8);
485 all->info.var.red.length = 8; 485 info->var.red.length = 8;
486 all->info.var.green.length = 8; 486 info->var.green.length = 8;
487 all->info.var.blue.length = 8; 487 info->var.blue.length = 8;
488 488
489 linebytes = of_getintprop_default(dp, "linebytes", 489 linebytes = of_getintprop_default(dp, "linebytes",
490 all->info.var.xres); 490 info->var.xres);
491 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 491 par->fbsize = PAGE_ALIGN(linebytes * info->var.yres);
492 492
493 if (!strcmp(dp->parent->name, "sbus") || 493 if (!strcmp(dp->parent->name, "sbus") ||
494 !strcmp(dp->parent->name, "sbi")) { 494 !strcmp(dp->parent->name, "sbi")) {
495 all->par.physbase = op->resource[0].start; 495 par->physbase = op->resource[0].start;
496 all->par.iospace = op->resource[0].flags & IORESOURCE_BITS; 496 par->iospace = op->resource[0].flags & IORESOURCE_BITS;
497 } else { 497 } else {
498 all->par.physbase = op->resource[1].start; 498 par->physbase = op->resource[1].start;
499 all->par.iospace = op->resource[0].flags & IORESOURCE_BITS; 499 par->iospace = op->resource[0].flags & IORESOURCE_BITS;
500 } 500 }
501 501
502 all->par.regs = of_ioremap(&op->resource[0], 0, 502 par->regs = of_ioremap(&op->resource[0], 0,
503 sizeof(struct cg14_regs), "cg14 regs"); 503 sizeof(struct cg14_regs), "cg14 regs");
504 all->par.clut = of_ioremap(&op->resource[0], CG14_CLUT1, 504 par->clut = of_ioremap(&op->resource[0], CG14_CLUT1,
505 sizeof(struct cg14_clut), "cg14 clut"); 505 sizeof(struct cg14_clut), "cg14 clut");
506 all->par.cursor = of_ioremap(&op->resource[0], CG14_CURSORREGS, 506 par->cursor = of_ioremap(&op->resource[0], CG14_CURSORREGS,
507 sizeof(struct cg14_cursor), "cg14 cursor"); 507 sizeof(struct cg14_cursor), "cg14 cursor");
508 508
509 all->info.screen_base = of_ioremap(&op->resource[1], 0, 509 info->screen_base = of_ioremap(&op->resource[1], 0,
510 all->par.fbsize, "cg14 ram"); 510 par->fbsize, "cg14 ram");
511 511
512 if (!all->par.regs || !all->par.clut || !all->par.cursor || 512 if (!par->regs || !par->clut || !par->cursor || !info->screen_base)
513 !all->info.screen_base) 513 goto out_unmap_regs;
514 cg14_unmap_regs(op, all);
515 514
516 is_8mb = (((op->resource[1].end - op->resource[1].start) + 1) == 515 is_8mb = (((op->resource[1].end - op->resource[1].start) + 1) ==
517 (8 * 1024 * 1024)); 516 (8 * 1024 * 1024));
518 517
519 BUILD_BUG_ON(sizeof(all->par.mmap_map) != sizeof(__cg14_mmap_map)); 518 BUILD_BUG_ON(sizeof(par->mmap_map) != sizeof(__cg14_mmap_map));
520 519
521 memcpy(&all->par.mmap_map, &__cg14_mmap_map, 520 memcpy(&par->mmap_map, &__cg14_mmap_map, sizeof(par->mmap_map));
522 sizeof(all->par.mmap_map));
523 521
524 for (i = 0; i < CG14_MMAP_ENTRIES; i++) { 522 for (i = 0; i < CG14_MMAP_ENTRIES; i++) {
525 struct sbus_mmap_map *map = &all->par.mmap_map[i]; 523 struct sbus_mmap_map *map = &par->mmap_map[i];
526 524
527 if (!map->size) 525 if (!map->size)
528 break; 526 break;
@@ -536,59 +534,55 @@ static int __devinit cg14_init_one(struct of_device *op)
536 map->size *= 2; 534 map->size *= 2;
537 } 535 }
538 536
539 all->par.mode = MDI_8_PIX; 537 par->mode = MDI_8_PIX;
540 all->par.ramsize = (is_8mb ? 0x800000 : 0x400000); 538 par->ramsize = (is_8mb ? 0x800000 : 0x400000);
541 539
542 all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 540 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
543 all->info.fbops = &cg14_ops; 541 info->fbops = &cg14_ops;
544 all->info.par = &all->par;
545 542
546 __cg14_reset(&all->par); 543 __cg14_reset(par);
547 544
548 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 545 if (fb_alloc_cmap(&info->cmap, 256, 0))
549 cg14_unmap_regs(op, all); 546 goto out_unmap_regs;
550 kfree(all);
551 return -ENOMEM;
552 }
553 fb_set_cmap(&all->info.cmap, &all->info);
554 547
555 cg14_init_fix(&all->info, linebytes, dp); 548 fb_set_cmap(&info->cmap, info);
556 549
557 err = register_framebuffer(&all->info); 550 cg14_init_fix(info, linebytes, dp);
558 if (err < 0) { 551
559 fb_dealloc_cmap(&all->info.cmap); 552 err = register_framebuffer(info);
560 cg14_unmap_regs(op, all); 553 if (err < 0)
561 kfree(all); 554 goto out_dealloc_cmap;
562 return err;
563 }
564 555
565 dev_set_drvdata(&op->dev, all); 556 dev_set_drvdata(&op->dev, info);
566 557
567 printk("%s: cgfourteen at %lx:%lx, %dMB\n", 558 printk("%s: cgfourteen at %lx:%lx, %dMB\n",
568 dp->full_name, 559 dp->full_name,
569 all->par.iospace, all->par.physbase, 560 par->iospace, par->physbase,
570 all->par.ramsize >> 20); 561 par->ramsize >> 20);
571 562
572 return 0; 563 return 0;
573}
574 564
575static int __devinit cg14_probe(struct of_device *dev, const struct of_device_id *match) 565out_dealloc_cmap:
576{ 566 fb_dealloc_cmap(&info->cmap);
577 struct of_device *op = to_of_device(&dev->dev); 567
568out_unmap_regs:
569 cg14_unmap_regs(op, info, par);
578 570
579 return cg14_init_one(op); 571out_err:
572 return err;
580} 573}
581 574
582static int __devexit cg14_remove(struct of_device *op) 575static int __devexit cg14_remove(struct of_device *op)
583{ 576{
584 struct all_info *all = dev_get_drvdata(&op->dev); 577 struct fb_info *info = dev_get_drvdata(&op->dev);
578 struct cg14_par *par = info->par;
585 579
586 unregister_framebuffer(&all->info); 580 unregister_framebuffer(info);
587 fb_dealloc_cmap(&all->info.cmap); 581 fb_dealloc_cmap(&info->cmap);
588 582
589 cg14_unmap_regs(op, all); 583 cg14_unmap_regs(op, info, par);
590 584
591 kfree(all); 585 framebuffer_release(info);
592 586
593 dev_set_drvdata(&op->dev, NULL); 587 dev_set_drvdata(&op->dev, NULL);
594 588
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index f042428a84f4..5741b46ade1b 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -353,104 +353,102 @@ static void __devinit cg3_do_default_mode(struct cg3_par *par)
353 } 353 }
354} 354}
355 355
356struct all_info { 356static int __devinit cg3_probe(struct of_device *op,
357 struct fb_info info; 357 const struct of_device_id *match)
358 struct cg3_par par;
359};
360
361static int __devinit cg3_init_one(struct of_device *op)
362{ 358{
363 struct device_node *dp = op->node; 359 struct device_node *dp = op->node;
364 struct all_info *all; 360 struct fb_info *info;
361 struct cg3_par *par;
365 int linebytes, err; 362 int linebytes, err;
366 363
367 all = kzalloc(sizeof(*all), GFP_KERNEL); 364 info = framebuffer_alloc(sizeof(struct cg3_par), &op->dev);
368 if (!all)
369 return -ENOMEM;
370 365
371 spin_lock_init(&all->par.lock); 366 err = -ENOMEM;
367 if (!info)
368 goto out_err;
369 par = info->par;
372 370
373 all->par.physbase = op->resource[0].start; 371 spin_lock_init(&par->lock);
374 all->par.which_io = op->resource[0].flags & IORESOURCE_BITS;
375 372
376 sbusfb_fill_var(&all->info.var, dp->node, 8); 373 par->physbase = op->resource[0].start;
377 all->info.var.red.length = 8; 374 par->which_io = op->resource[0].flags & IORESOURCE_BITS;
378 all->info.var.green.length = 8; 375
379 all->info.var.blue.length = 8; 376 sbusfb_fill_var(&info->var, dp->node, 8);
377 info->var.red.length = 8;
378 info->var.green.length = 8;
379 info->var.blue.length = 8;
380 if (!strcmp(dp->name, "cgRDI")) 380 if (!strcmp(dp->name, "cgRDI"))
381 all->par.flags |= CG3_FLAG_RDI; 381 par->flags |= CG3_FLAG_RDI;
382 if (all->par.flags & CG3_FLAG_RDI) 382 if (par->flags & CG3_FLAG_RDI)
383 cg3_rdi_maybe_fixup_var(&all->info.var, dp); 383 cg3_rdi_maybe_fixup_var(&info->var, dp);
384 384
385 linebytes = of_getintprop_default(dp, "linebytes", 385 linebytes = of_getintprop_default(dp, "linebytes",
386 all->info.var.xres); 386 info->var.xres);
387 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 387 par->fbsize = PAGE_ALIGN(linebytes * info->var.yres);
388 388
389 all->par.regs = of_ioremap(&op->resource[0], CG3_REGS_OFFSET, 389 par->regs = of_ioremap(&op->resource[0], CG3_REGS_OFFSET,
390 sizeof(struct cg3_regs), "cg3 regs"); 390 sizeof(struct cg3_regs), "cg3 regs");
391 if (!par->regs)
392 goto out_release_fb;
391 393
392 all->info.flags = FBINFO_DEFAULT; 394 info->flags = FBINFO_DEFAULT;
393 all->info.fbops = &cg3_ops; 395 info->fbops = &cg3_ops;
394 all->info.screen_base = 396 info->screen_base = of_ioremap(&op->resource[0], CG3_RAM_OFFSET,
395 of_ioremap(&op->resource[0], CG3_RAM_OFFSET, 397 par->fbsize, "cg3 ram");
396 all->par.fbsize, "cg3 ram"); 398 if (!info->screen_base)
397 all->info.par = &all->par; 399 goto out_unmap_regs;
398 400
399 cg3_blank(0, &all->info); 401 cg3_blank(0, info);
400 402
401 if (!of_find_property(dp, "width", NULL)) 403 if (!of_find_property(dp, "width", NULL))
402 cg3_do_default_mode(&all->par); 404 cg3_do_default_mode(par);
403 405
404 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 406 if (fb_alloc_cmap(&info->cmap, 256, 0))
405 of_iounmap(&op->resource[0], 407 goto out_unmap_screen;
406 all->par.regs, sizeof(struct cg3_regs)); 408
407 of_iounmap(&op->resource[0], 409 fb_set_cmap(&info->cmap, info);
408 all->info.screen_base, all->par.fbsize);
409 kfree(all);
410 return -ENOMEM;
411 }
412 fb_set_cmap(&all->info.cmap, &all->info);
413
414 cg3_init_fix(&all->info, linebytes, dp);
415
416 err = register_framebuffer(&all->info);
417 if (err < 0) {
418 fb_dealloc_cmap(&all->info.cmap);
419 of_iounmap(&op->resource[0],
420 all->par.regs, sizeof(struct cg3_regs));
421 of_iounmap(&op->resource[0],
422 all->info.screen_base, all->par.fbsize);
423 kfree(all);
424 return err;
425 }
426 410
427 dev_set_drvdata(&op->dev, all); 411 cg3_init_fix(info, linebytes, dp);
412
413 err = register_framebuffer(info);
414 if (err < 0)
415 goto out_dealloc_cmap;
416
417 dev_set_drvdata(&op->dev, info);
428 418
429 printk("%s: cg3 at %lx:%lx\n", 419 printk("%s: cg3 at %lx:%lx\n",
430 dp->full_name, all->par.which_io, all->par.physbase); 420 dp->full_name, par->which_io, par->physbase);
431 421
432 return 0; 422 return 0;
433}
434 423
435static int __devinit cg3_probe(struct of_device *dev, 424out_dealloc_cmap:
436 const struct of_device_id *match) 425 fb_dealloc_cmap(&info->cmap);
437{ 426
438 struct of_device *op = to_of_device(&dev->dev); 427out_unmap_screen:
428 of_iounmap(&op->resource[0], info->screen_base, par->fbsize);
429
430out_unmap_regs:
431 of_iounmap(&op->resource[0], par->regs, sizeof(struct cg3_regs));
432
433out_release_fb:
434 framebuffer_release(info);
439 435
440 return cg3_init_one(op); 436out_err:
437 return err;
441} 438}
442 439
443static int __devexit cg3_remove(struct of_device *op) 440static int __devexit cg3_remove(struct of_device *op)
444{ 441{
445 struct all_info *all = dev_get_drvdata(&op->dev); 442 struct fb_info *info = dev_get_drvdata(&op->dev);
443 struct cg3_par *par = info->par;
446 444
447 unregister_framebuffer(&all->info); 445 unregister_framebuffer(info);
448 fb_dealloc_cmap(&all->info.cmap); 446 fb_dealloc_cmap(&info->cmap);
449 447
450 of_iounmap(&op->resource[0], all->par.regs, sizeof(struct cg3_regs)); 448 of_iounmap(&op->resource[0], par->regs, sizeof(struct cg3_regs));
451 of_iounmap(&op->resource[0], all->info.screen_base, all->par.fbsize); 449 of_iounmap(&op->resource[0], info->screen_base, par->fbsize);
452 450
453 kfree(all); 451 framebuffer_release(info);
454 452
455 dev_set_drvdata(&op->dev, NULL); 453 dev_set_drvdata(&op->dev, NULL);
456 454
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 4dad23a28f58..87c747123538 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -653,135 +653,120 @@ static void cg6_chip_init(struct fb_info *info)
653 sbus_writel(info->var.yres - 1, &fbc->clipmaxy); 653 sbus_writel(info->var.yres - 1, &fbc->clipmaxy);
654} 654}
655 655
656struct all_info { 656static void cg6_unmap_regs(struct of_device *op, struct fb_info *info,
657 struct fb_info info; 657 struct cg6_par *par)
658 struct cg6_par par;
659};
660
661static void cg6_unmap_regs(struct of_device *op, struct all_info *all)
662{ 658{
663 if (all->par.fbc) 659 if (par->fbc)
664 of_iounmap(&op->resource[0], all->par.fbc, 4096); 660 of_iounmap(&op->resource[0], par->fbc, 4096);
665 if (all->par.tec) 661 if (par->tec)
666 of_iounmap(&op->resource[0], 662 of_iounmap(&op->resource[0], par->tec, sizeof(struct cg6_tec));
667 all->par.tec, sizeof(struct cg6_tec)); 663 if (par->thc)
668 if (all->par.thc) 664 of_iounmap(&op->resource[0], par->thc, sizeof(struct cg6_thc));
669 of_iounmap(&op->resource[0], 665 if (par->bt)
670 all->par.thc, sizeof(struct cg6_thc)); 666 of_iounmap(&op->resource[0], par->bt, sizeof(struct bt_regs));
671 if (all->par.bt) 667 if (par->fhc)
672 of_iounmap(&op->resource[0], 668 of_iounmap(&op->resource[0], par->fhc, sizeof(u32));
673 all->par.bt, sizeof(struct bt_regs)); 669
674 if (all->par.fhc) 670 if (info->screen_base)
675 of_iounmap(&op->resource[0], 671 of_iounmap(&op->resource[0], info->screen_base, par->fbsize);
676 all->par.fhc, sizeof(u32));
677
678 if (all->info.screen_base)
679 of_iounmap(&op->resource[0],
680 all->info.screen_base, all->par.fbsize);
681} 672}
682 673
683static int __devinit cg6_init_one(struct of_device *op) 674static int __devinit cg6_probe(struct of_device *op, const struct of_device_id *match)
684{ 675{
685 struct device_node *dp = op->node; 676 struct device_node *dp = op->node;
686 struct all_info *all; 677 struct fb_info *info;
678 struct cg6_par *par;
687 int linebytes, err; 679 int linebytes, err;
688 680
689 all = kzalloc(sizeof(*all), GFP_KERNEL); 681 info = framebuffer_alloc(sizeof(struct cg6_par), &op->dev);
690 if (!all) 682
691 return -ENOMEM; 683 err = -ENOMEM;
684 if (!info)
685 goto out_err;
686 par = info->par;
692 687
693 spin_lock_init(&all->par.lock); 688 spin_lock_init(&par->lock);
694 689
695 all->par.physbase = op->resource[0].start; 690 par->physbase = op->resource[0].start;
696 all->par.which_io = op->resource[0].flags & IORESOURCE_BITS; 691 par->which_io = op->resource[0].flags & IORESOURCE_BITS;
697 692
698 sbusfb_fill_var(&all->info.var, dp->node, 8); 693 sbusfb_fill_var(&info->var, dp->node, 8);
699 all->info.var.red.length = 8; 694 info->var.red.length = 8;
700 all->info.var.green.length = 8; 695 info->var.green.length = 8;
701 all->info.var.blue.length = 8; 696 info->var.blue.length = 8;
702 697
703 linebytes = of_getintprop_default(dp, "linebytes", 698 linebytes = of_getintprop_default(dp, "linebytes",
704 all->info.var.xres); 699 info->var.xres);
705 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 700 par->fbsize = PAGE_ALIGN(linebytes * info->var.yres);
706 if (of_find_property(dp, "dblbuf", NULL)) 701 if (of_find_property(dp, "dblbuf", NULL))
707 all->par.fbsize *= 4; 702 par->fbsize *= 4;
708 703
709 all->par.fbc = of_ioremap(&op->resource[0], CG6_FBC_OFFSET, 704 par->fbc = of_ioremap(&op->resource[0], CG6_FBC_OFFSET,
710 4096, "cgsix fbc"); 705 4096, "cgsix fbc");
711 all->par.tec = of_ioremap(&op->resource[0], CG6_TEC_OFFSET, 706 par->tec = of_ioremap(&op->resource[0], CG6_TEC_OFFSET,
712 sizeof(struct cg6_tec), "cgsix tec"); 707 sizeof(struct cg6_tec), "cgsix tec");
713 all->par.thc = of_ioremap(&op->resource[0], CG6_THC_OFFSET, 708 par->thc = of_ioremap(&op->resource[0], CG6_THC_OFFSET,
714 sizeof(struct cg6_thc), "cgsix thc"); 709 sizeof(struct cg6_thc), "cgsix thc");
715 all->par.bt = of_ioremap(&op->resource[0], CG6_BROOKTREE_OFFSET, 710 par->bt = of_ioremap(&op->resource[0], CG6_BROOKTREE_OFFSET,
716 sizeof(struct bt_regs), "cgsix dac"); 711 sizeof(struct bt_regs), "cgsix dac");
717 all->par.fhc = of_ioremap(&op->resource[0], CG6_FHC_OFFSET, 712 par->fhc = of_ioremap(&op->resource[0], CG6_FHC_OFFSET,
718 sizeof(u32), "cgsix fhc"); 713 sizeof(u32), "cgsix fhc");
719 714
720 all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_IMAGEBLIT | 715 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_IMAGEBLIT |
721 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT; 716 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT;
722 all->info.fbops = &cg6_ops; 717 info->fbops = &cg6_ops;
723
724 all->info.screen_base = of_ioremap(&op->resource[0], CG6_RAM_OFFSET,
725 all->par.fbsize, "cgsix ram");
726 if (!all->par.fbc || !all->par.tec || !all->par.thc ||
727 !all->par.bt || !all->par.fhc || !all->info.screen_base) {
728 cg6_unmap_regs(op, all);
729 kfree(all);
730 return -ENOMEM;
731 }
732 718
733 all->info.par = &all->par; 719 info->screen_base = of_ioremap(&op->resource[0], CG6_RAM_OFFSET,
720 par->fbsize, "cgsix ram");
721 if (!par->fbc || !par->tec || !par->thc ||
722 !par->bt || !par->fhc || !info->screen_base)
723 goto out_unmap_regs;
734 724
735 all->info.var.accel_flags = FB_ACCELF_TEXT; 725 info->var.accel_flags = FB_ACCELF_TEXT;
736 726
737 cg6_bt_init(&all->par); 727 cg6_bt_init(par);
738 cg6_chip_init(&all->info); 728 cg6_chip_init(info);
739 cg6_blank(0, &all->info); 729 cg6_blank(0, info);
740 730
741 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 731 if (fb_alloc_cmap(&info->cmap, 256, 0))
742 cg6_unmap_regs(op, all); 732 goto out_unmap_regs;
743 kfree(all);
744 return -ENOMEM;
745 }
746 733
747 fb_set_cmap(&all->info.cmap, &all->info); 734 fb_set_cmap(&info->cmap, info);
748 cg6_init_fix(&all->info, linebytes); 735 cg6_init_fix(info, linebytes);
749 736
750 err = register_framebuffer(&all->info); 737 err = register_framebuffer(info);
751 if (err < 0) { 738 if (err < 0)
752 cg6_unmap_regs(op, all); 739 goto out_dealloc_cmap;
753 fb_dealloc_cmap(&all->info.cmap);
754 kfree(all);
755 return err;
756 }
757 740
758 dev_set_drvdata(&op->dev, all); 741 dev_set_drvdata(&op->dev, info);
759 742
760 printk("%s: CGsix [%s] at %lx:%lx\n", 743 printk("%s: CGsix [%s] at %lx:%lx\n",
761 dp->full_name, 744 dp->full_name, info->fix.id,
762 all->info.fix.id, 745 par->which_io, par->physbase);
763 all->par.which_io, all->par.physbase);
764 746
765 return 0; 747 return 0;
766}
767 748
768static int __devinit cg6_probe(struct of_device *dev, const struct of_device_id *match) 749out_dealloc_cmap:
769{ 750 fb_dealloc_cmap(&info->cmap);
770 struct of_device *op = to_of_device(&dev->dev); 751
752out_unmap_regs:
753 cg6_unmap_regs(op, info, par);
771 754
772 return cg6_init_one(op); 755out_err:
756 return err;
773} 757}
774 758
775static int __devexit cg6_remove(struct of_device *op) 759static int __devexit cg6_remove(struct of_device *op)
776{ 760{
777 struct all_info *all = dev_get_drvdata(&op->dev); 761 struct fb_info *info = dev_get_drvdata(&op->dev);
762 struct cg6_par *par = info->par;
778 763
779 unregister_framebuffer(&all->info); 764 unregister_framebuffer(info);
780 fb_dealloc_cmap(&all->info.cmap); 765 fb_dealloc_cmap(&info->cmap);
781 766
782 cg6_unmap_regs(op, all); 767 cg6_unmap_regs(op, info, par);
783 768
784 kfree(all); 769 framebuffer_release(info);
785 770
786 dev_set_drvdata(&op->dev, NULL); 771 dev_set_drvdata(&op->dev, NULL);
787 772
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 3f6c98fad437..4b520b573911 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -371,6 +371,8 @@ struct ffb_par {
371 unsigned long fbsize; 371 unsigned long fbsize;
372 372
373 int board_type; 373 int board_type;
374
375 u32 pseudo_palette[16];
374}; 376};
375 377
376static void FFBFifo(struct ffb_par *par, int n) 378static void FFBFifo(struct ffb_par *par, int n)
@@ -900,75 +902,67 @@ ffb_init_fix(struct fb_info *info)
900 info->fix.accel = FB_ACCEL_SUN_CREATOR; 902 info->fix.accel = FB_ACCEL_SUN_CREATOR;
901} 903}
902 904
903struct all_info { 905static int __devinit ffb_probe(struct of_device *op, const struct of_device_id *match)
904 struct fb_info info;
905 struct ffb_par par;
906 u32 pseudo_palette[16];
907};
908
909static int ffb_init_one(struct of_device *op)
910{ 906{
911 struct device_node *dp = op->node; 907 struct device_node *dp = op->node;
912 struct ffb_fbc __iomem *fbc; 908 struct ffb_fbc __iomem *fbc;
913 struct ffb_dac __iomem *dac; 909 struct ffb_dac __iomem *dac;
914 struct all_info *all; 910 struct fb_info *info;
915 int err; 911 struct ffb_par *par;
916 u32 dac_pnum, dac_rev, dac_mrev; 912 u32 dac_pnum, dac_rev, dac_mrev;
913 int err;
917 914
918 all = kzalloc(sizeof(*all), GFP_KERNEL); 915 info = framebuffer_alloc(sizeof(struct ffb_par), &op->dev);
919 if (!all)
920 return -ENOMEM;
921 916
922 spin_lock_init(&all->par.lock); 917 err = -ENOMEM;
923 all->par.fbc = of_ioremap(&op->resource[2], 0, 918 if (!info)
924 sizeof(struct ffb_fbc), "ffb fbc"); 919 goto out_err;
925 if (!all->par.fbc) {
926 kfree(all);
927 return -ENOMEM;
928 }
929 920
930 all->par.dac = of_ioremap(&op->resource[1], 0, 921 par = info->par;
931 sizeof(struct ffb_dac), "ffb dac"); 922
932 if (!all->par.dac) { 923 spin_lock_init(&par->lock);
933 of_iounmap(&op->resource[2], 924 par->fbc = of_ioremap(&op->resource[2], 0,
934 all->par.fbc, sizeof(struct ffb_fbc)); 925 sizeof(struct ffb_fbc), "ffb fbc");
935 kfree(all); 926 if (!par->fbc)
936 return -ENOMEM; 927 goto out_release_fb;
937 } 928
929 par->dac = of_ioremap(&op->resource[1], 0,
930 sizeof(struct ffb_dac), "ffb dac");
931 if (!par->dac)
932 goto out_unmap_fbc;
938 933
939 all->par.rop_cache = FFB_ROP_NEW; 934 par->rop_cache = FFB_ROP_NEW;
940 all->par.physbase = op->resource[0].start; 935 par->physbase = op->resource[0].start;
941 936
942 /* Don't mention copyarea, so SCROLL_REDRAW is always 937 /* Don't mention copyarea, so SCROLL_REDRAW is always
943 * used. It is the fastest on this chip. 938 * used. It is the fastest on this chip.
944 */ 939 */
945 all->info.flags = (FBINFO_DEFAULT | 940 info->flags = (FBINFO_DEFAULT |
946 /* FBINFO_HWACCEL_COPYAREA | */ 941 /* FBINFO_HWACCEL_COPYAREA | */
947 FBINFO_HWACCEL_FILLRECT | 942 FBINFO_HWACCEL_FILLRECT |
948 FBINFO_HWACCEL_IMAGEBLIT); 943 FBINFO_HWACCEL_IMAGEBLIT);
949 all->info.fbops = &ffb_ops; 944
950 all->info.screen_base = (char *) all->par.physbase + FFB_DFB24_POFF; 945 info->fbops = &ffb_ops;
951 all->info.par = &all->par; 946
952 all->info.pseudo_palette = all->pseudo_palette; 947 info->screen_base = (char *) par->physbase + FFB_DFB24_POFF;
953 948 info->pseudo_palette = par->pseudo_palette;
954 sbusfb_fill_var(&all->info.var, dp->node, 32); 949
955 all->par.fbsize = PAGE_ALIGN(all->info.var.xres * 950 sbusfb_fill_var(&info->var, dp->node, 32);
956 all->info.var.yres * 951 par->fbsize = PAGE_ALIGN(info->var.xres * info->var.yres * 4);
957 4); 952 ffb_fixup_var_rgb(&info->var);
958 ffb_fixup_var_rgb(&all->info.var); 953
959 954 info->var.accel_flags = FB_ACCELF_TEXT;
960 all->info.var.accel_flags = FB_ACCELF_TEXT;
961 955
962 if (!strcmp(dp->name, "SUNW,afb")) 956 if (!strcmp(dp->name, "SUNW,afb"))
963 all->par.flags |= FFB_FLAG_AFB; 957 par->flags |= FFB_FLAG_AFB;
964 958
965 all->par.board_type = of_getintprop_default(dp, "board_type", 0); 959 par->board_type = of_getintprop_default(dp, "board_type", 0);
966 960
967 fbc = all->par.fbc; 961 fbc = par->fbc;
968 if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0) 962 if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0)
969 upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr); 963 upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr);
970 964
971 dac = all->par.dac; 965 dac = par->dac;
972 upa_writel(FFB_DAC_DID, &dac->type); 966 upa_writel(FFB_DAC_DID, &dac->type);
973 dac_pnum = upa_readl(&dac->value); 967 dac_pnum = upa_readl(&dac->value);
974 dac_rev = (dac_pnum & FFB_DAC_DID_REV) >> FFB_DAC_DID_REV_SHIFT; 968 dac_rev = (dac_pnum & FFB_DAC_DID_REV) >> FFB_DAC_DID_REV_SHIFT;
@@ -985,76 +979,70 @@ static int ffb_init_one(struct of_device *op)
985 * cursor logic. We identify Pacifica 1 as not Pacifica 2, the 979 * cursor logic. We identify Pacifica 1 as not Pacifica 2, the
986 * latter having a part number value of 0x236e. 980 * latter having a part number value of 0x236e.
987 */ 981 */
988 if ((all->par.flags & FFB_FLAG_AFB) || dac_pnum == 0x236e) { 982 if ((par->flags & FFB_FLAG_AFB) || dac_pnum == 0x236e) {
989 all->par.flags &= ~FFB_FLAG_INVCURSOR; 983 par->flags &= ~FFB_FLAG_INVCURSOR;
990 } else { 984 } else {
991 if (dac_mrev < 3) 985 if (dac_mrev < 3)
992 all->par.flags |= FFB_FLAG_INVCURSOR; 986 par->flags |= FFB_FLAG_INVCURSOR;
993 } 987 }
994 988
995 ffb_switch_from_graph(&all->par); 989 ffb_switch_from_graph(par);
996 990
997 /* Unblank it just to be sure. When there are multiple 991 /* Unblank it just to be sure. When there are multiple
998 * FFB/AFB cards in the system, or it is not the OBP 992 * FFB/AFB cards in the system, or it is not the OBP
999 * chosen console, it will have video outputs off in 993 * chosen console, it will have video outputs off in
1000 * the DAC. 994 * the DAC.
1001 */ 995 */
1002 ffb_blank(0, &all->info); 996 ffb_blank(0, info);
1003
1004 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
1005 printk(KERN_ERR "ffb: Could not allocate color map.\n");
1006 of_iounmap(&op->resource[2],
1007 all->par.fbc, sizeof(struct ffb_fbc));
1008 of_iounmap(&op->resource[1],
1009 all->par.dac, sizeof(struct ffb_dac));
1010 kfree(all);
1011 return -ENOMEM;
1012 }
1013 997
1014 ffb_init_fix(&all->info); 998 if (fb_alloc_cmap(&info->cmap, 256, 0))
1015 999 goto out_unmap_dac;
1016 err = register_framebuffer(&all->info); 1000
1017 if (err < 0) { 1001 ffb_init_fix(info);
1018 printk(KERN_ERR "ffb: Could not register framebuffer.\n");
1019 fb_dealloc_cmap(&all->info.cmap);
1020 of_iounmap(&op->resource[2],
1021 all->par.fbc, sizeof(struct ffb_fbc));
1022 of_iounmap(&op->resource[1],
1023 all->par.dac, sizeof(struct ffb_dac));
1024 kfree(all);
1025 return err;
1026 }
1027 1002
1028 dev_set_drvdata(&op->dev, all); 1003 err = register_framebuffer(info);
1004 if (err < 0)
1005 goto out_dealloc_cmap;
1006
1007 dev_set_drvdata(&op->dev, info);
1029 1008
1030 printk("%s: %s at %016lx, type %d, " 1009 printk("%s: %s at %016lx, type %d, "
1031 "DAC pnum[%x] rev[%d] manuf_rev[%d]\n", 1010 "DAC pnum[%x] rev[%d] manuf_rev[%d]\n",
1032 dp->full_name, 1011 dp->full_name,
1033 ((all->par.flags & FFB_FLAG_AFB) ? "AFB" : "FFB"), 1012 ((par->flags & FFB_FLAG_AFB) ? "AFB" : "FFB"),
1034 all->par.physbase, all->par.board_type, 1013 par->physbase, par->board_type,
1035 dac_pnum, dac_rev, dac_mrev); 1014 dac_pnum, dac_rev, dac_mrev);
1036 1015
1037 return 0; 1016 return 0;
1038}
1039 1017
1040static int __devinit ffb_probe(struct of_device *dev, const struct of_device_id *match) 1018out_dealloc_cmap:
1041{ 1019 fb_dealloc_cmap(&info->cmap);
1042 struct of_device *op = to_of_device(&dev->dev); 1020
1021out_unmap_dac:
1022 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
1023
1024out_unmap_fbc:
1025 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
1026
1027out_release_fb:
1028 framebuffer_release(info);
1043 1029
1044 return ffb_init_one(op); 1030out_err:
1031 return err;
1045} 1032}
1046 1033
1047static int __devexit ffb_remove(struct of_device *op) 1034static int __devexit ffb_remove(struct of_device *op)
1048{ 1035{
1049 struct all_info *all = dev_get_drvdata(&op->dev); 1036 struct fb_info *info = dev_get_drvdata(&op->dev);
1037 struct ffb_par *par = info->par;
1050 1038
1051 unregister_framebuffer(&all->info); 1039 unregister_framebuffer(info);
1052 fb_dealloc_cmap(&all->info.cmap); 1040 fb_dealloc_cmap(&info->cmap);
1053 1041
1054 of_iounmap(&op->resource[2], all->par.fbc, sizeof(struct ffb_fbc)); 1042 of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
1055 of_iounmap(&op->resource[1], all->par.dac, sizeof(struct ffb_dac)); 1043 of_iounmap(&op->resource[1], par->dac, sizeof(struct ffb_dac));
1056 1044
1057 kfree(all); 1045 framebuffer_release(info);
1058 1046
1059 dev_set_drvdata(&op->dev, NULL); 1047 dev_set_drvdata(&op->dev, NULL);
1060 1048
diff --git a/drivers/video/leo.c b/drivers/video/leo.c
index a038aa5a9e1c..45b9a5d55dec 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/leo.c
@@ -525,130 +525,123 @@ static void leo_fixup_var_rgb(struct fb_var_screeninfo *var)
525 var->transp.length = 0; 525 var->transp.length = 0;
526} 526}
527 527
528struct all_info { 528static void leo_unmap_regs(struct of_device *op, struct fb_info *info,
529 struct fb_info info; 529 struct leo_par *par)
530 struct leo_par par;
531};
532
533static void leo_unmap_regs(struct of_device *op, struct all_info *all)
534{ 530{
535 if (all->par.lc_ss0_usr) 531 if (par->lc_ss0_usr)
536 of_iounmap(&op->resource[0], all->par.lc_ss0_usr, 0x1000); 532 of_iounmap(&op->resource[0], par->lc_ss0_usr, 0x1000);
537 if (all->par.ld_ss0) 533 if (par->ld_ss0)
538 of_iounmap(&op->resource[0], all->par.ld_ss0, 0x1000); 534 of_iounmap(&op->resource[0], par->ld_ss0, 0x1000);
539 if (all->par.ld_ss1) 535 if (par->ld_ss1)
540 of_iounmap(&op->resource[0], all->par.ld_ss1, 0x1000); 536 of_iounmap(&op->resource[0], par->ld_ss1, 0x1000);
541 if (all->par.lx_krn) 537 if (par->lx_krn)
542 of_iounmap(&op->resource[0], all->par.lx_krn, 0x1000); 538 of_iounmap(&op->resource[0], par->lx_krn, 0x1000);
543 if (all->par.cursor) 539 if (par->cursor)
544 of_iounmap(&op->resource[0], 540 of_iounmap(&op->resource[0],
545 all->par.cursor, sizeof(struct leo_cursor)); 541 par->cursor, sizeof(struct leo_cursor));
546 if (all->info.screen_base) 542 if (info->screen_base)
547 of_iounmap(&op->resource[0], all->info.screen_base, 0x800000); 543 of_iounmap(&op->resource[0], info->screen_base, 0x800000);
548} 544}
549 545
550static int __devinit leo_init_one(struct of_device *op) 546static int __devinit leo_probe(struct of_device *op, const struct of_device_id *match)
551{ 547{
552 struct device_node *dp = op->node; 548 struct device_node *dp = op->node;
553 struct all_info *all; 549 struct fb_info *info;
550 struct leo_par *par;
554 int linebytes, err; 551 int linebytes, err;
555 552
556 all = kzalloc(sizeof(*all), GFP_KERNEL); 553 info = framebuffer_alloc(sizeof(struct leo_par), &op->dev);
557 if (!all) 554
558 return -ENOMEM; 555 err = -ENOMEM;
556 if (!info)
557 goto out_err;
558 par = info->par;
559 559
560 spin_lock_init(&all->par.lock); 560 spin_lock_init(&par->lock);
561 561
562 all->par.physbase = op->resource[0].start; 562 par->physbase = op->resource[0].start;
563 all->par.which_io = op->resource[0].flags & IORESOURCE_BITS; 563 par->which_io = op->resource[0].flags & IORESOURCE_BITS;
564 564
565 sbusfb_fill_var(&all->info.var, dp->node, 32); 565 sbusfb_fill_var(&info->var, dp->node, 32);
566 leo_fixup_var_rgb(&all->info.var); 566 leo_fixup_var_rgb(&info->var);
567 567
568 linebytes = of_getintprop_default(dp, "linebytes", 568 linebytes = of_getintprop_default(dp, "linebytes",
569 all->info.var.xres); 569 info->var.xres);
570 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 570 par->fbsize = PAGE_ALIGN(linebytes * info->var.yres);
571 571
572 all->par.lc_ss0_usr = 572 par->lc_ss0_usr =
573 of_ioremap(&op->resource[0], LEO_OFF_LC_SS0_USR, 573 of_ioremap(&op->resource[0], LEO_OFF_LC_SS0_USR,
574 0x1000, "leolc ss0usr"); 574 0x1000, "leolc ss0usr");
575 all->par.ld_ss0 = 575 par->ld_ss0 =
576 of_ioremap(&op->resource[0], LEO_OFF_LD_SS0, 576 of_ioremap(&op->resource[0], LEO_OFF_LD_SS0,
577 0x1000, "leold ss0"); 577 0x1000, "leold ss0");
578 all->par.ld_ss1 = 578 par->ld_ss1 =
579 of_ioremap(&op->resource[0], LEO_OFF_LD_SS1, 579 of_ioremap(&op->resource[0], LEO_OFF_LD_SS1,
580 0x1000, "leold ss1"); 580 0x1000, "leold ss1");
581 all->par.lx_krn = 581 par->lx_krn =
582 of_ioremap(&op->resource[0], LEO_OFF_LX_KRN, 582 of_ioremap(&op->resource[0], LEO_OFF_LX_KRN,
583 0x1000, "leolx krn"); 583 0x1000, "leolx krn");
584 all->par.cursor = 584 par->cursor =
585 of_ioremap(&op->resource[0], LEO_OFF_LX_CURSOR, 585 of_ioremap(&op->resource[0], LEO_OFF_LX_CURSOR,
586 sizeof(struct leo_cursor), "leolx cursor"); 586 sizeof(struct leo_cursor), "leolx cursor");
587 all->info.screen_base = 587 info->screen_base =
588 of_ioremap(&op->resource[0], LEO_OFF_SS0, 588 of_ioremap(&op->resource[0], LEO_OFF_SS0,
589 0x800000, "leo ram"); 589 0x800000, "leo ram");
590 if (!all->par.lc_ss0_usr || 590 if (!par->lc_ss0_usr ||
591 !all->par.ld_ss0 || 591 !par->ld_ss0 ||
592 !all->par.ld_ss1 || 592 !par->ld_ss1 ||
593 !all->par.lx_krn || 593 !par->lx_krn ||
594 !all->par.cursor || 594 !par->cursor ||
595 !all->info.screen_base) { 595 !info->screen_base)
596 leo_unmap_regs(op, all); 596 goto out_unmap_regs;
597 kfree(all);
598 return -ENOMEM;
599 }
600 597
601 all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 598 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
602 all->info.fbops = &leo_ops; 599 info->fbops = &leo_ops;
603 all->info.par = &all->par;
604 600
605 leo_init_wids(&all->info); 601 leo_init_wids(info);
606 leo_init_hw(&all->info); 602 leo_init_hw(info);
607 603
608 leo_blank(0, &all->info); 604 leo_blank(0, info);
609 605
610 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 606 if (fb_alloc_cmap(&info->cmap, 256, 0))
611 leo_unmap_regs(op, all); 607 goto out_unmap_regs;
612 kfree(all);
613 return -ENOMEM;;
614 }
615 608
616 leo_init_fix(&all->info, dp); 609 leo_init_fix(info, dp);
617 610
618 err = register_framebuffer(&all->info); 611 err = register_framebuffer(info);
619 if (err < 0) { 612 if (err < 0)
620 fb_dealloc_cmap(&all->info.cmap); 613 goto out_dealloc_cmap;
621 leo_unmap_regs(op, all);
622 kfree(all);
623 return err;
624 }
625 614
626 dev_set_drvdata(&op->dev, all); 615 dev_set_drvdata(&op->dev, info);
627 616
628 printk("%s: leo at %lx:%lx\n", 617 printk("%s: leo at %lx:%lx\n",
629 dp->full_name, 618 dp->full_name,
630 all->par.which_io, all->par.physbase); 619 par->which_io, par->physbase);
631 620
632 return 0; 621 return 0;
633}
634 622
635static int __devinit leo_probe(struct of_device *dev, const struct of_device_id *match) 623out_dealloc_cmap:
636{ 624 fb_dealloc_cmap(&info->cmap);
637 struct of_device *op = to_of_device(&dev->dev); 625
626out_unmap_regs:
627 leo_unmap_regs(op, info, par);
628 framebuffer_release(info);
638 629
639 return leo_init_one(op); 630out_err:
631 return err;
640} 632}
641 633
642static int __devexit leo_remove(struct of_device *op) 634static int __devexit leo_remove(struct of_device *op)
643{ 635{
644 struct all_info *all = dev_get_drvdata(&op->dev); 636 struct fb_info *info = dev_get_drvdata(&op->dev);
637 struct leo_par *par = info->par;
645 638
646 unregister_framebuffer(&all->info); 639 unregister_framebuffer(info);
647 fb_dealloc_cmap(&all->info.cmap); 640 fb_dealloc_cmap(&info->cmap);
648 641
649 leo_unmap_regs(op, all); 642 leo_unmap_regs(op, info, par);
650 643
651 kfree(all); 644 framebuffer_release(info);
652 645
653 dev_set_drvdata(&op->dev, NULL); 646 dev_set_drvdata(&op->dev, NULL);
654 647
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c
index 637b78bb4bf7..58496061142d 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -255,107 +255,95 @@ static void p9100_init_fix(struct fb_info *info, int linebytes, struct device_no
255 info->fix.accel = FB_ACCEL_SUN_CGTHREE; 255 info->fix.accel = FB_ACCEL_SUN_CGTHREE;
256} 256}
257 257
258struct all_info { 258static int __devinit p9100_probe(struct of_device *op, const struct of_device_id *match)
259 struct fb_info info;
260 struct p9100_par par;
261};
262
263static int __devinit p9100_init_one(struct of_device *op)
264{ 259{
265 struct device_node *dp = op->node; 260 struct device_node *dp = op->node;
266 struct all_info *all; 261 struct fb_info *info;
262 struct p9100_par *par;
267 int linebytes, err; 263 int linebytes, err;
268 264
269 all = kzalloc(sizeof(*all), GFP_KERNEL); 265 info = framebuffer_alloc(sizeof(struct p9100_par), &op->dev);
270 if (!all) 266
271 return -ENOMEM; 267 err = -ENOMEM;
268 if (!info)
269 goto out_err;
270 par = info->par;
272 271
273 spin_lock_init(&all->par.lock); 272 spin_lock_init(&par->lock);
274 273
275 /* This is the framebuffer and the only resource apps can mmap. */ 274 /* This is the framebuffer and the only resource apps can mmap. */
276 all->par.physbase = op->resource[2].start; 275 par->physbase = op->resource[2].start;
277 all->par.which_io = op->resource[2].flags & IORESOURCE_BITS; 276 par->which_io = op->resource[2].flags & IORESOURCE_BITS;
278
279 sbusfb_fill_var(&all->info.var, dp->node, 8);
280 all->info.var.red.length = 8;
281 all->info.var.green.length = 8;
282 all->info.var.blue.length = 8;
283
284 linebytes = of_getintprop_default(dp, "linebytes",
285 all->info.var.xres);
286 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
287
288 all->par.regs = of_ioremap(&op->resource[0], 0,
289 sizeof(struct p9100_regs), "p9100 regs");
290 if (!all->par.regs) {
291 kfree(all);
292 return -ENOMEM;
293 }
294 277
295 all->info.flags = FBINFO_DEFAULT; 278 sbusfb_fill_var(&info->var, dp->node, 8);
296 all->info.fbops = &p9100_ops; 279 info->var.red.length = 8;
297 all->info.screen_base = of_ioremap(&op->resource[2], 0, 280 info->var.green.length = 8;
298 all->par.fbsize, "p9100 ram"); 281 info->var.blue.length = 8;
299 if (!all->info.screen_base) {
300 of_iounmap(&op->resource[0],
301 all->par.regs, sizeof(struct p9100_regs));
302 kfree(all);
303 return -ENOMEM;
304 }
305 all->info.par = &all->par;
306 282
307 p9100_blank(0, &all->info); 283 linebytes = of_getintprop_default(dp, "linebytes", info->var.xres);
284 par->fbsize = PAGE_ALIGN(linebytes * info->var.yres);
308 285
309 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 286 par->regs = of_ioremap(&op->resource[0], 0,
310 of_iounmap(&op->resource[0], 287 sizeof(struct p9100_regs), "p9100 regs");
311 all->par.regs, sizeof(struct p9100_regs)); 288 if (!par->regs)
312 of_iounmap(&op->resource[2], 289 goto out_release_fb;
313 all->info.screen_base, all->par.fbsize);
314 kfree(all);
315 return -ENOMEM;
316 }
317 290
318 p9100_init_fix(&all->info, linebytes, dp); 291 info->flags = FBINFO_DEFAULT;
319 292 info->fbops = &p9100_ops;
320 err = register_framebuffer(&all->info); 293 info->screen_base = of_ioremap(&op->resource[2], 0,
321 if (err < 0) { 294 par->fbsize, "p9100 ram");
322 fb_dealloc_cmap(&all->info.cmap); 295 if (!info->screen_base)
323 of_iounmap(&op->resource[0], 296 goto out_unmap_regs;
324 all->par.regs, sizeof(struct p9100_regs)); 297
325 of_iounmap(&op->resource[2], 298 p9100_blank(0, info);
326 all->info.screen_base, all->par.fbsize); 299
327 kfree(all); 300 if (fb_alloc_cmap(&info->cmap, 256, 0))
328 return err; 301 goto out_unmap_screen;
329 }
330 fb_set_cmap(&all->info.cmap, &all->info);
331 302
332 dev_set_drvdata(&op->dev, all); 303 p9100_init_fix(info, linebytes, dp);
304
305 err = register_framebuffer(info);
306 if (err < 0)
307 goto out_dealloc_cmap;
308
309 fb_set_cmap(&info->cmap, info);
310
311 dev_set_drvdata(&op->dev, info);
333 312
334 printk("%s: p9100 at %lx:%lx\n", 313 printk("%s: p9100 at %lx:%lx\n",
335 dp->full_name, 314 dp->full_name,
336 all->par.which_io, all->par.physbase); 315 par->which_io, par->physbase);
337 316
338 return 0; 317 return 0;
339}
340 318
341static int __devinit p9100_probe(struct of_device *dev, const struct of_device_id *match) 319out_dealloc_cmap:
342{ 320 fb_dealloc_cmap(&info->cmap);
343 struct of_device *op = to_of_device(&dev->dev); 321
322out_unmap_screen:
323 of_iounmap(&op->resource[2], info->screen_base, par->fbsize);
324
325out_unmap_regs:
326 of_iounmap(&op->resource[0], par->regs, sizeof(struct p9100_regs));
327
328out_release_fb:
329 framebuffer_release(info);
344 330
345 return p9100_init_one(op); 331out_err:
332 return err;
346} 333}
347 334
348static int __devexit p9100_remove(struct of_device *op) 335static int __devexit p9100_remove(struct of_device *op)
349{ 336{
350 struct all_info *all = dev_get_drvdata(&op->dev); 337 struct fb_info *info = dev_get_drvdata(&op->dev);
338 struct p9100_par *par = info->par;
351 339
352 unregister_framebuffer(&all->info); 340 unregister_framebuffer(info);
353 fb_dealloc_cmap(&all->info.cmap); 341 fb_dealloc_cmap(&info->cmap);
354 342
355 of_iounmap(&op->resource[0], all->par.regs, sizeof(struct p9100_regs)); 343 of_iounmap(&op->resource[0], par->regs, sizeof(struct p9100_regs));
356 of_iounmap(&op->resource[2], all->info.screen_base, all->par.fbsize); 344 of_iounmap(&op->resource[2], info->screen_base, par->fbsize);
357 345
358 kfree(all); 346 framebuffer_release(info);
359 347
360 dev_set_drvdata(&op->dev, NULL); 348 dev_set_drvdata(&op->dev, NULL);
361 349
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index 5a99669232ce..e5a9ddb3c8be 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -345,88 +345,82 @@ tcx_init_fix(struct fb_info *info, int linebytes)
345 info->fix.accel = FB_ACCEL_SUN_TCX; 345 info->fix.accel = FB_ACCEL_SUN_TCX;
346} 346}
347 347
348struct all_info { 348static void tcx_unmap_regs(struct of_device *op, struct fb_info *info,
349 struct fb_info info; 349 struct tcx_par *par)
350 struct tcx_par par;
351};
352
353static void tcx_unmap_regs(struct of_device *op, struct all_info *all)
354{ 350{
355 if (all->par.tec) 351 if (par->tec)
356 of_iounmap(&op->resource[7], 352 of_iounmap(&op->resource[7],
357 all->par.tec, sizeof(struct tcx_tec)); 353 par->tec, sizeof(struct tcx_tec));
358 if (all->par.thc) 354 if (par->thc)
359 of_iounmap(&op->resource[9], 355 of_iounmap(&op->resource[9],
360 all->par.thc, sizeof(struct tcx_thc)); 356 par->thc, sizeof(struct tcx_thc));
361 if (all->par.bt) 357 if (par->bt)
362 of_iounmap(&op->resource[8], 358 of_iounmap(&op->resource[8],
363 all->par.bt, sizeof(struct bt_regs)); 359 par->bt, sizeof(struct bt_regs));
364 if (all->par.cplane) 360 if (par->cplane)
365 of_iounmap(&op->resource[4], 361 of_iounmap(&op->resource[4],
366 all->par.cplane, all->par.fbsize * sizeof(u32)); 362 par->cplane, par->fbsize * sizeof(u32));
367 if (all->info.screen_base) 363 if (info->screen_base)
368 of_iounmap(&op->resource[0], 364 of_iounmap(&op->resource[0],
369 all->info.screen_base, all->par.fbsize); 365 info->screen_base, par->fbsize);
370} 366}
371 367
372static int __devinit tcx_init_one(struct of_device *op) 368static int __devinit tcx_init_one(struct of_device *op)
373{ 369{
374 struct device_node *dp = op->node; 370 struct device_node *dp = op->node;
375 struct all_info *all; 371 struct fb_info *info;
372 struct tcx_par *par;
376 int linebytes, i, err; 373 int linebytes, i, err;
377 374
378 all = kzalloc(sizeof(*all), GFP_KERNEL); 375 info = framebuffer_alloc(sizeof(struct tcx_par), &op->dev);
379 if (!all)
380 return -ENOMEM;
381 376
382 spin_lock_init(&all->par.lock); 377 err = -ENOMEM;
378 if (!info)
379 goto out_err;
380 par = info->par;
383 381
384 all->par.lowdepth = 382 spin_lock_init(&par->lock);
383
384 par->lowdepth =
385 (of_find_property(dp, "tcx-8-bit", NULL) != NULL); 385 (of_find_property(dp, "tcx-8-bit", NULL) != NULL);
386 386
387 sbusfb_fill_var(&all->info.var, dp->node, 8); 387 sbusfb_fill_var(&info->var, dp->node, 8);
388 all->info.var.red.length = 8; 388 info->var.red.length = 8;
389 all->info.var.green.length = 8; 389 info->var.green.length = 8;
390 all->info.var.blue.length = 8; 390 info->var.blue.length = 8;
391 391
392 linebytes = of_getintprop_default(dp, "linebytes", 392 linebytes = of_getintprop_default(dp, "linebytes",
393 all->info.var.xres); 393 info->var.xres);
394 all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); 394 par->fbsize = PAGE_ALIGN(linebytes * info->var.yres);
395 395
396 all->par.tec = of_ioremap(&op->resource[7], 0, 396 par->tec = of_ioremap(&op->resource[7], 0,
397 sizeof(struct tcx_tec), "tcx tec"); 397 sizeof(struct tcx_tec), "tcx tec");
398 all->par.thc = of_ioremap(&op->resource[9], 0, 398 par->thc = of_ioremap(&op->resource[9], 0,
399 sizeof(struct tcx_thc), "tcx thc"); 399 sizeof(struct tcx_thc), "tcx thc");
400 all->par.bt = of_ioremap(&op->resource[8], 0, 400 par->bt = of_ioremap(&op->resource[8], 0,
401 sizeof(struct bt_regs), "tcx dac"); 401 sizeof(struct bt_regs), "tcx dac");
402 all->info.screen_base = of_ioremap(&op->resource[0], 0, 402 info->screen_base = of_ioremap(&op->resource[0], 0,
403 all->par.fbsize, "tcx ram"); 403 par->fbsize, "tcx ram");
404 if (!all->par.tec || !all->par.thc || 404 if (!par->tec || !par->thc ||
405 !all->par.bt || !all->info.screen_base) { 405 !par->bt || !info->screen_base)
406 tcx_unmap_regs(op, all); 406 goto out_unmap_regs;
407 kfree(all); 407
408 return -ENOMEM; 408 memcpy(&par->mmap_map, &__tcx_mmap_map, sizeof(par->mmap_map));
409 } 409 if (!par->lowdepth) {
410 410 par->cplane = of_ioremap(&op->resource[4], 0,
411 memcpy(&all->par.mmap_map, &__tcx_mmap_map, sizeof(all->par.mmap_map)); 411 par->fbsize * sizeof(u32),
412 if (!all->par.lowdepth) {
413 all->par.cplane = of_ioremap(&op->resource[4], 0,
414 all->par.fbsize * sizeof(u32),
415 "tcx cplane"); 412 "tcx cplane");
416 if (!all->par.cplane) { 413 if (!par->cplane)
417 tcx_unmap_regs(op, all); 414 goto out_unmap_regs;
418 kfree(all);
419 return -ENOMEM;
420 }
421 } else { 415 } else {
422 all->par.mmap_map[1].size = SBUS_MMAP_EMPTY; 416 par->mmap_map[1].size = SBUS_MMAP_EMPTY;
423 all->par.mmap_map[4].size = SBUS_MMAP_EMPTY; 417 par->mmap_map[4].size = SBUS_MMAP_EMPTY;
424 all->par.mmap_map[5].size = SBUS_MMAP_EMPTY; 418 par->mmap_map[5].size = SBUS_MMAP_EMPTY;
425 all->par.mmap_map[6].size = SBUS_MMAP_EMPTY; 419 par->mmap_map[6].size = SBUS_MMAP_EMPTY;
426 } 420 }
427 421
428 all->par.physbase = 0; 422 par->physbase = 0;
429 all->par.which_io = op->resource[0].flags & IORESOURCE_BITS; 423 par->which_io = op->resource[0].flags & IORESOURCE_BITS;
430 424
431 for (i = 0; i < TCX_MMAP_ENTRIES; i++) { 425 for (i = 0; i < TCX_MMAP_ENTRIES; i++) {
432 int j; 426 int j;
@@ -444,53 +438,54 @@ static int __devinit tcx_init_one(struct of_device *op)
444 j = i; 438 j = i;
445 break; 439 break;
446 }; 440 };
447 all->par.mmap_map[i].poff = op->resource[j].start; 441 par->mmap_map[i].poff = op->resource[j].start;
448 } 442 }
449 443
450 all->info.flags = FBINFO_DEFAULT; 444 info->flags = FBINFO_DEFAULT;
451 all->info.fbops = &tcx_ops; 445 info->fbops = &tcx_ops;
452 all->info.par = &all->par;
453 446
454 /* Initialize brooktree DAC. */ 447 /* Initialize brooktree DAC. */
455 sbus_writel(0x04 << 24, &all->par.bt->addr); /* color planes */ 448 sbus_writel(0x04 << 24, &par->bt->addr); /* color planes */
456 sbus_writel(0xff << 24, &all->par.bt->control); 449 sbus_writel(0xff << 24, &par->bt->control);
457 sbus_writel(0x05 << 24, &all->par.bt->addr); 450 sbus_writel(0x05 << 24, &par->bt->addr);
458 sbus_writel(0x00 << 24, &all->par.bt->control); 451 sbus_writel(0x00 << 24, &par->bt->control);
459 sbus_writel(0x06 << 24, &all->par.bt->addr); /* overlay plane */ 452 sbus_writel(0x06 << 24, &par->bt->addr); /* overlay plane */
460 sbus_writel(0x73 << 24, &all->par.bt->control); 453 sbus_writel(0x73 << 24, &par->bt->control);
461 sbus_writel(0x07 << 24, &all->par.bt->addr); 454 sbus_writel(0x07 << 24, &par->bt->addr);
462 sbus_writel(0x00 << 24, &all->par.bt->control); 455 sbus_writel(0x00 << 24, &par->bt->control);
463 456
464 tcx_reset(&all->info); 457 tcx_reset(info);
465
466 tcx_blank(FB_BLANK_UNBLANK, &all->info);
467
468 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
469 tcx_unmap_regs(op, all);
470 kfree(all);
471 return -ENOMEM;
472 }
473 458
474 fb_set_cmap(&all->info.cmap, &all->info); 459 tcx_blank(FB_BLANK_UNBLANK, info);
475 tcx_init_fix(&all->info, linebytes);
476 460
477 err = register_framebuffer(&all->info); 461 if (fb_alloc_cmap(&info->cmap, 256, 0))
478 if (err < 0) { 462 goto out_unmap_regs;
479 fb_dealloc_cmap(&all->info.cmap); 463
480 tcx_unmap_regs(op, all); 464 fb_set_cmap(&info->cmap, info);
481 kfree(all); 465 tcx_init_fix(info, linebytes);
482 return err; 466
483 } 467 err = register_framebuffer(info);
468 if (err < 0)
469 goto out_dealloc_cmap;
484 470
485 dev_set_drvdata(&op->dev, all); 471 dev_set_drvdata(&op->dev, info);
486 472
487 printk("%s: TCX at %lx:%lx, %s\n", 473 printk("%s: TCX at %lx:%lx, %s\n",
488 dp->full_name, 474 dp->full_name,
489 all->par.which_io, 475 par->which_io,
490 op->resource[0].start, 476 op->resource[0].start,
491 all->par.lowdepth ? "8-bit only" : "24-bit depth"); 477 par->lowdepth ? "8-bit only" : "24-bit depth");
492 478
493 return 0; 479 return 0;
480
481out_dealloc_cmap:
482 fb_dealloc_cmap(&info->cmap);
483
484out_unmap_regs:
485 tcx_unmap_regs(op, info, par);
486
487out_err:
488 return err;
494} 489}
495 490
496static int __devinit tcx_probe(struct of_device *dev, const struct of_device_id *match) 491static int __devinit tcx_probe(struct of_device *dev, const struct of_device_id *match)
@@ -502,14 +497,15 @@ static int __devinit tcx_probe(struct of_device *dev, const struct of_device_id
502 497
503static int __devexit tcx_remove(struct of_device *op) 498static int __devexit tcx_remove(struct of_device *op)
504{ 499{
505 struct all_info *all = dev_get_drvdata(&op->dev); 500 struct fb_info *info = dev_get_drvdata(&op->dev);
501 struct tcx_par *par = info->par;
506 502
507 unregister_framebuffer(&all->info); 503 unregister_framebuffer(info);
508 fb_dealloc_cmap(&all->info.cmap); 504 fb_dealloc_cmap(&info->cmap);
509 505
510 tcx_unmap_regs(op, all); 506 tcx_unmap_regs(op, info, par);
511 507
512 kfree(all); 508 framebuffer_release(info);
513 509
514 dev_set_drvdata(&op->dev, NULL); 510 dev_set_drvdata(&op->dev, NULL);
515 511