diff options
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-s3c2410.c | 70 |
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 | ||
748 | static 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) | |||
877 | static int s3c24xx_i2c_remove(struct platform_device *pdev) | 869 | static 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 | } |