aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-davinci.c
diff options
context:
space:
mode:
authorAxel Lin <axel.lin@ingics.com>2013-09-10 03:43:41 -0400
committerMark Brown <broonie@linaro.org>2013-09-17 07:56:14 -0400
commit94c69f765f1b4a658d96905ec59928e3e3e07e6a (patch)
treecfa1fffd3906bff17eed2e9771f2c33fd55877af /drivers/spi/spi-davinci.c
parent272b98c6455f00884f0350f775c5342358ebb73f (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.c10
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:
1015free_clk: 1015free_clk:
1016 clk_disable_unprepare(dspi->clk); 1016 clk_disable_unprepare(dspi->clk);
1017 clk_put(dspi->clk); 1017 clk_put(dspi->clk);
1018put_master:
1019 spi_master_put(master);
1020irq_free: 1018irq_free:
1021 free_irq(dspi->irq, dspi); 1019 free_irq(dspi->irq, dspi);
1022unmap_io: 1020unmap_io:
@@ -1024,7 +1022,7 @@ unmap_io:
1024release_region: 1022release_region:
1025 release_mem_region(dspi->pbase, resource_size(r)); 1023 release_mem_region(dspi->pbase, resource_size(r));
1026free_master: 1024free_master:
1027 kfree(master); 1025 spi_master_put(master);
1028err: 1026err:
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}