aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-s3c2410.c
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2007-05-01 17:26:35 -0400
committerJean Delvare <khali@hyperion.delvare>2007-05-01 17:26:35 -0400
commit5b68790cd5e2879067bcbc45b01eeb6081e7d731 (patch)
tree89b5a557a665a124df3a0941d65de111231bba0b /drivers/i2c/busses/i2c-s3c2410.c
parente00a8cdf325346c531c841ee85c803792db60157 (diff)
i2c-s3c2410: Fix bug in releasing driver
When compiled as a module, the i2c-s3c2410 driver does not free either the IRQ or the i2c adapter it attached to the system. As part of this fix, move to the usual kernel style of freeing items as part of the probe error path making the remove process easier. Signed-off-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/i2c/busses/i2c-s3c2410.c')
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c70
1 files changed, 34 insertions, 36 deletions
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index e8395be0d92c..e68a96f589fd 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -745,26 +745,6 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
745 return 0; 745 return 0;
746} 746}
747 747
748static void s3c24xx_i2c_free(struct s3c24xx_i2c *i2c)
749{
750 if (i2c->clk != NULL && !IS_ERR(i2c->clk)) {
751 clk_disable(i2c->clk);
752 clk_put(i2c->clk);
753 i2c->clk = NULL;
754 }
755
756 if (i2c->regs != NULL) {
757 iounmap(i2c->regs);
758 i2c->regs = NULL;
759 }
760
761 if (i2c->ioarea != NULL) {
762 release_resource(i2c->ioarea);
763 kfree(i2c->ioarea);
764 i2c->ioarea = NULL;
765 }
766}
767
768/* s3c24xx_i2c_probe 748/* s3c24xx_i2c_probe
769 * 749 *
770 * called by the bus driver when a suitable device is found 750 * called by the bus driver when a suitable device is found
@@ -783,7 +763,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
783 if (IS_ERR(i2c->clk)) { 763 if (IS_ERR(i2c->clk)) {
784 dev_err(&pdev->dev, "cannot get clock\n"); 764 dev_err(&pdev->dev, "cannot get clock\n");
785 ret = -ENOENT; 765 ret = -ENOENT;
786 goto out; 766 goto err_noclk;
787 } 767 }
788 768
789 dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk); 769 dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk);
@@ -796,7 +776,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
796 if (res == NULL) { 776 if (res == NULL) {
797 dev_err(&pdev->dev, "cannot find IO resource\n"); 777 dev_err(&pdev->dev, "cannot find IO resource\n");
798 ret = -ENOENT; 778 ret = -ENOENT;
799 goto out; 779 goto err_clk;
800 } 780 }
801 781
802 i2c->ioarea = request_mem_region(res->start, (res->end-res->start)+1, 782 i2c->ioarea = request_mem_region(res->start, (res->end-res->start)+1,
@@ -805,7 +785,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
805 if (i2c->ioarea == NULL) { 785 if (i2c->ioarea == NULL) {
806 dev_err(&pdev->dev, "cannot request IO\n"); 786 dev_err(&pdev->dev, "cannot request IO\n");
807 ret = -ENXIO; 787 ret = -ENXIO;
808 goto out; 788 goto err_clk;
809 } 789 }
810 790
811 i2c->regs = ioremap(res->start, (res->end-res->start)+1); 791 i2c->regs = ioremap(res->start, (res->end-res->start)+1);
@@ -813,7 +793,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
813 if (i2c->regs == NULL) { 793 if (i2c->regs == NULL) {
814 dev_err(&pdev->dev, "cannot map IO\n"); 794 dev_err(&pdev->dev, "cannot map IO\n");
815 ret = -ENXIO; 795 ret = -ENXIO;
816 goto out; 796 goto err_ioarea;
817 } 797 }
818 798
819 dev_dbg(&pdev->dev, "registers %p (%p, %p)\n", i2c->regs, i2c->ioarea, res); 799 dev_dbg(&pdev->dev, "registers %p (%p, %p)\n", i2c->regs, i2c->ioarea, res);
@@ -827,7 +807,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
827 807
828 ret = s3c24xx_i2c_init(i2c); 808 ret = s3c24xx_i2c_init(i2c);
829 if (ret != 0) 809 if (ret != 0)
830 goto out; 810 goto err_iomap;
831 811
832 /* find the IRQ for this unit (note, this relies on the init call to 812 /* find the IRQ for this unit (note, this relies on the init call to
833 * ensure no current IRQs pending 813 * ensure no current IRQs pending
@@ -837,7 +817,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
837 if (res == NULL) { 817 if (res == NULL) {
838 dev_err(&pdev->dev, "cannot find IRQ\n"); 818 dev_err(&pdev->dev, "cannot find IRQ\n");
839 ret = -ENOENT; 819 ret = -ENOENT;
840 goto out; 820 goto err_iomap;
841 } 821 }
842 822
843 ret = request_irq(res->start, s3c24xx_i2c_irq, IRQF_DISABLED, 823 ret = request_irq(res->start, s3c24xx_i2c_irq, IRQF_DISABLED,
@@ -845,7 +825,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
845 825
846 if (ret != 0) { 826 if (ret != 0) {
847 dev_err(&pdev->dev, "cannot claim IRQ\n"); 827 dev_err(&pdev->dev, "cannot claim IRQ\n");
848 goto out; 828 goto err_iomap;
849 } 829 }
850 830
851 i2c->irq = res; 831 i2c->irq = res;
@@ -855,17 +835,29 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
855 ret = i2c_add_adapter(&i2c->adap); 835 ret = i2c_add_adapter(&i2c->adap);
856 if (ret < 0) { 836 if (ret < 0) {
857 dev_err(&pdev->dev, "failed to add bus to i2c core\n"); 837 dev_err(&pdev->dev, "failed to add bus to i2c core\n");
858 goto out; 838 goto err_irq;
859 } 839 }
860 840
861 platform_set_drvdata(pdev, i2c); 841 platform_set_drvdata(pdev, i2c);
862 842
863 dev_info(&pdev->dev, "%s: S3C I2C adapter\n", i2c->adap.dev.bus_id); 843 dev_info(&pdev->dev, "%s: S3C I2C adapter\n", i2c->adap.dev.bus_id);
844 return 0;
864 845
865 out: 846 err_irq:
866 if (ret < 0) 847 free_irq(i2c->irq->start, i2c);
867 s3c24xx_i2c_free(i2c); 848
849 err_iomap:
850 iounmap(i2c->regs);
851
852 err_ioarea:
853 release_resource(i2c->ioarea);
854 kfree(i2c->ioarea);
855
856 err_clk:
857 clk_disable(i2c->clk);
858 clk_put(i2c->clk);
868 859
860 err_noclk:
869 return ret; 861 return ret;
870} 862}
871 863
@@ -877,11 +869,17 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
877static int s3c24xx_i2c_remove(struct platform_device *pdev) 869static int s3c24xx_i2c_remove(struct platform_device *pdev)
878{ 870{
879 struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); 871 struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
880 872
881 if (i2c != NULL) { 873 i2c_del_adapter(&i2c->adap);
882 s3c24xx_i2c_free(i2c); 874 free_irq(i2c->irq->start, i2c);
883 platform_set_drvdata(pdev, NULL); 875
884 } 876 clk_disable(i2c->clk);
877 clk_put(i2c->clk);
878
879 iounmap(i2c->regs);
880
881 release_resource(i2c->ioarea);
882 kfree(i2c->ioarea);
885 883
886 return 0; 884 return 0;
887} 885}