diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-30 14:06:55 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-30 14:06:55 -0400 |
| commit | 9c837fb692b005203765d8a569a2fe43fdff9df1 (patch) | |
| tree | 914146eb36c92c929bf32af69052e7d9fa28beb1 /drivers/video/leo.c | |
| parent | 63332a9d16e7dede26d252af3f9c4304b51e7974 (diff) | |
| parent | c1f193a7aed1b468617bb26075777c0c2f4f597a (diff) | |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6:
[SPARC64]: Fix show_stack() when stack argument is NULL.
[SPARC]: Fix serial console node string creation.
[SPARC]: Mark SBUS framebuffer ioctls as IGNORE in compat_ioctl.c
[SPARC64]: asm-sparc64/floppy.h needs linux/pci.h
[SPARC64]: Fix conflicts in SBUS/PCI/EBUS/ISA DMA handling.
[VIDEO]: Fix OOPS in all SBUS framebuffer drivers.
[SPARC64]: Handle mostek clock type in mini_rtc driver.
[PARTITION]: Sun/Solaris VTOC table corrections
[SPARC]: Fix floppy on some sun4c systems.
[SPARC64]: Fix sun4u PCI config space accesses on sun4u.
[PARTITION] MSDOS: Fix Sun num_partitions handling.
[SPARC]: Update defconfig.
Diffstat (limited to 'drivers/video/leo.c')
| -rw-r--r-- | drivers/video/leo.c | 147 |
1 files changed, 70 insertions, 77 deletions
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 | ||
| 528 | struct all_info { | 528 | static 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 | |||
| 533 | static 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 | ||
| 550 | static int __devinit leo_init_one(struct of_device *op) | 546 | static 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 | ||
| 635 | static int __devinit leo_probe(struct of_device *dev, const struct of_device_id *match) | 623 | out_dealloc_cmap: |
| 636 | { | 624 | fb_dealloc_cmap(&info->cmap); |
| 637 | struct of_device *op = to_of_device(&dev->dev); | 625 | |
| 626 | out_unmap_regs: | ||
| 627 | leo_unmap_regs(op, info, par); | ||
| 628 | framebuffer_release(info); | ||
| 638 | 629 | ||
| 639 | return leo_init_one(op); | 630 | out_err: |
| 631 | return err; | ||
| 640 | } | 632 | } |
| 641 | 633 | ||
| 642 | static int __devexit leo_remove(struct of_device *op) | 634 | static 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 | ||
