diff options
author | Axel Lin <axel.lin@ingics.com> | 2013-09-10 03:43:41 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-09-17 07:56:14 -0400 |
commit | 94c69f765f1b4a658d96905ec59928e3e3e07e6a (patch) | |
tree | cfa1fffd3906bff17eed2e9771f2c33fd55877af /drivers/spi/spi-davinci.c | |
parent | 272b98c6455f00884f0350f775c5342358ebb73f (diff) |
spi: bitbang: Let spi_bitbang_start() take a reference to master
Many drivers that use bitbang library have a leak on probe error paths.
This is because once a spi_master_get() call succeeds, we need an additional
spi_master_put() call to free the memory.
Fix this issue by moving the code taking a reference to master to
spi_bitbang_start(), so spi_bitbang_start() will take a reference to master on
success. With this change, the caller is responsible for calling
spi_bitbang_stop() to decrement the reference and spi_master_put() as
counterpart of spi_alloc_master() to prevent a memory leak.
So now we have below patten for drivers using bitbang library:
probe:
spi_alloc_master -> Init reference count to 1
spi_bitbang_start -> Increment reference count
remove:
spi_bitbang_stop -> Decrement reference count
spi_master_put -> Decrement reference count (reference count reaches 0)
Fixup all users accordingly.
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Suggested-by: Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
Acked-by: Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi-davinci.c')
-rw-r--r-- | drivers/spi/spi-davinci.c | 10 |
1 files changed, 4 insertions, 6 deletions
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 8fbfe2483ffd..af2bb73d0168 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c | |||
@@ -916,7 +916,7 @@ static int davinci_spi_probe(struct platform_device *pdev) | |||
916 | if (ret) | 916 | if (ret) |
917 | goto unmap_io; | 917 | goto unmap_io; |
918 | 918 | ||
919 | dspi->bitbang.master = spi_master_get(master); | 919 | dspi->bitbang.master = master; |
920 | if (dspi->bitbang.master == NULL) { | 920 | if (dspi->bitbang.master == NULL) { |
921 | ret = -ENODEV; | 921 | ret = -ENODEV; |
922 | goto irq_free; | 922 | goto irq_free; |
@@ -925,7 +925,7 @@ static int davinci_spi_probe(struct platform_device *pdev) | |||
925 | dspi->clk = clk_get(&pdev->dev, NULL); | 925 | dspi->clk = clk_get(&pdev->dev, NULL); |
926 | if (IS_ERR(dspi->clk)) { | 926 | if (IS_ERR(dspi->clk)) { |
927 | ret = -ENODEV; | 927 | ret = -ENODEV; |
928 | goto put_master; | 928 | goto irq_free; |
929 | } | 929 | } |
930 | clk_prepare_enable(dspi->clk); | 930 | clk_prepare_enable(dspi->clk); |
931 | 931 | ||
@@ -1015,8 +1015,6 @@ free_dma: | |||
1015 | free_clk: | 1015 | free_clk: |
1016 | clk_disable_unprepare(dspi->clk); | 1016 | clk_disable_unprepare(dspi->clk); |
1017 | clk_put(dspi->clk); | 1017 | clk_put(dspi->clk); |
1018 | put_master: | ||
1019 | spi_master_put(master); | ||
1020 | irq_free: | 1018 | irq_free: |
1021 | free_irq(dspi->irq, dspi); | 1019 | free_irq(dspi->irq, dspi); |
1022 | unmap_io: | 1020 | unmap_io: |
@@ -1024,7 +1022,7 @@ unmap_io: | |||
1024 | release_region: | 1022 | release_region: |
1025 | release_mem_region(dspi->pbase, resource_size(r)); | 1023 | release_mem_region(dspi->pbase, resource_size(r)); |
1026 | free_master: | 1024 | free_master: |
1027 | kfree(master); | 1025 | spi_master_put(master); |
1028 | err: | 1026 | err: |
1029 | return ret; | 1027 | return ret; |
1030 | } | 1028 | } |
@@ -1051,11 +1049,11 @@ static int davinci_spi_remove(struct platform_device *pdev) | |||
1051 | 1049 | ||
1052 | clk_disable_unprepare(dspi->clk); | 1050 | clk_disable_unprepare(dspi->clk); |
1053 | clk_put(dspi->clk); | 1051 | clk_put(dspi->clk); |
1054 | spi_master_put(master); | ||
1055 | free_irq(dspi->irq, dspi); | 1052 | free_irq(dspi->irq, dspi); |
1056 | iounmap(dspi->base); | 1053 | iounmap(dspi->base); |
1057 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1054 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1058 | release_mem_region(dspi->pbase, resource_size(r)); | 1055 | release_mem_region(dspi->pbase, resource_size(r)); |
1056 | spi_master_put(master); | ||
1059 | 1057 | ||
1060 | return 0; | 1058 | return 0; |
1061 | } | 1059 | } |