diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-12-29 00:01:32 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-31 17:06:05 -0500 |
commit | e3a411a3dfc1d633504aa63efab32b7e00318454 (patch) | |
tree | 2ba6117448edd7056c8fa48cc6a696ae73a6c21a /drivers/video/cg6.c | |
parent | 6fc5bae797a6632bbccdd49a1b6a96121368a4b9 (diff) |
[SPARC64]: Fix of_iounmap() region release.
We need to pass in the resource otherwise we cannot
release the region properly. We must know whether it is
an I/O or MEM resource.
Spotted by Eric Brower.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/video/cg6.c')
-rw-r--r-- | drivers/video/cg6.c | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index 64146be2eeb0..4dad23a28f58 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c | |||
@@ -658,21 +658,26 @@ struct all_info { | |||
658 | struct cg6_par par; | 658 | struct cg6_par par; |
659 | }; | 659 | }; |
660 | 660 | ||
661 | static void cg6_unmap_regs(struct all_info *all) | 661 | static void cg6_unmap_regs(struct of_device *op, struct all_info *all) |
662 | { | 662 | { |
663 | if (all->par.fbc) | 663 | if (all->par.fbc) |
664 | of_iounmap(all->par.fbc, 4096); | 664 | of_iounmap(&op->resource[0], all->par.fbc, 4096); |
665 | if (all->par.tec) | 665 | if (all->par.tec) |
666 | of_iounmap(all->par.tec, sizeof(struct cg6_tec)); | 666 | of_iounmap(&op->resource[0], |
667 | all->par.tec, sizeof(struct cg6_tec)); | ||
667 | if (all->par.thc) | 668 | if (all->par.thc) |
668 | of_iounmap(all->par.thc, sizeof(struct cg6_thc)); | 669 | of_iounmap(&op->resource[0], |
670 | all->par.thc, sizeof(struct cg6_thc)); | ||
669 | if (all->par.bt) | 671 | if (all->par.bt) |
670 | of_iounmap(all->par.bt, sizeof(struct bt_regs)); | 672 | of_iounmap(&op->resource[0], |
673 | all->par.bt, sizeof(struct bt_regs)); | ||
671 | if (all->par.fhc) | 674 | if (all->par.fhc) |
672 | of_iounmap(all->par.fhc, sizeof(u32)); | 675 | of_iounmap(&op->resource[0], |
676 | all->par.fhc, sizeof(u32)); | ||
673 | 677 | ||
674 | if (all->info.screen_base) | 678 | if (all->info.screen_base) |
675 | of_iounmap(all->info.screen_base, all->par.fbsize); | 679 | of_iounmap(&op->resource[0], |
680 | all->info.screen_base, all->par.fbsize); | ||
676 | } | 681 | } |
677 | 682 | ||
678 | static int __devinit cg6_init_one(struct of_device *op) | 683 | static int __devinit cg6_init_one(struct of_device *op) |
@@ -720,7 +725,7 @@ static int __devinit cg6_init_one(struct of_device *op) | |||
720 | all->par.fbsize, "cgsix ram"); | 725 | all->par.fbsize, "cgsix ram"); |
721 | if (!all->par.fbc || !all->par.tec || !all->par.thc || | 726 | if (!all->par.fbc || !all->par.tec || !all->par.thc || |
722 | !all->par.bt || !all->par.fhc || !all->info.screen_base) { | 727 | !all->par.bt || !all->par.fhc || !all->info.screen_base) { |
723 | cg6_unmap_regs(all); | 728 | cg6_unmap_regs(op, all); |
724 | kfree(all); | 729 | kfree(all); |
725 | return -ENOMEM; | 730 | return -ENOMEM; |
726 | } | 731 | } |
@@ -734,7 +739,7 @@ static int __devinit cg6_init_one(struct of_device *op) | |||
734 | cg6_blank(0, &all->info); | 739 | cg6_blank(0, &all->info); |
735 | 740 | ||
736 | if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { | 741 | if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { |
737 | cg6_unmap_regs(all); | 742 | cg6_unmap_regs(op, all); |
738 | kfree(all); | 743 | kfree(all); |
739 | return -ENOMEM; | 744 | return -ENOMEM; |
740 | } | 745 | } |
@@ -744,7 +749,7 @@ static int __devinit cg6_init_one(struct of_device *op) | |||
744 | 749 | ||
745 | err = register_framebuffer(&all->info); | 750 | err = register_framebuffer(&all->info); |
746 | if (err < 0) { | 751 | if (err < 0) { |
747 | cg6_unmap_regs(all); | 752 | cg6_unmap_regs(op, all); |
748 | fb_dealloc_cmap(&all->info.cmap); | 753 | fb_dealloc_cmap(&all->info.cmap); |
749 | kfree(all); | 754 | kfree(all); |
750 | return err; | 755 | return err; |
@@ -767,18 +772,18 @@ static int __devinit cg6_probe(struct of_device *dev, const struct of_device_id | |||
767 | return cg6_init_one(op); | 772 | return cg6_init_one(op); |
768 | } | 773 | } |
769 | 774 | ||
770 | static int __devexit cg6_remove(struct of_device *dev) | 775 | static int __devexit cg6_remove(struct of_device *op) |
771 | { | 776 | { |
772 | struct all_info *all = dev_get_drvdata(&dev->dev); | 777 | struct all_info *all = dev_get_drvdata(&op->dev); |
773 | 778 | ||
774 | unregister_framebuffer(&all->info); | 779 | unregister_framebuffer(&all->info); |
775 | fb_dealloc_cmap(&all->info.cmap); | 780 | fb_dealloc_cmap(&all->info.cmap); |
776 | 781 | ||
777 | cg6_unmap_regs(all); | 782 | cg6_unmap_regs(op, all); |
778 | 783 | ||
779 | kfree(all); | 784 | kfree(all); |
780 | 785 | ||
781 | dev_set_drvdata(&dev->dev, NULL); | 786 | dev_set_drvdata(&op->dev, NULL); |
782 | 787 | ||
783 | return 0; | 788 | return 0; |
784 | } | 789 | } |