aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2012-08-24 14:03:02 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-08-27 14:23:52 -0400
commit7d520d28dd5287d14b5ec6cf4405a1220ca57d42 (patch)
tree608e5d27690e3053a941ee4d2e8ab92200932982 /drivers/spi
parent41682e03d4fdc947dbd22725d70f222cc7746852 (diff)
spi/mxs: Fix device remove function
The call sequence spi_alloc_master/spi_register_master/spi_unregister_master is complete; it reduces the device reference count to zero, which results in device memory being freed. The remove function accesses the freed memory after the call to spi_unregister_master(), _and_ it calls spi_master_put on the freed memory. Acquire a reference to the SPI master device and release it after cleanup is complete (with the existing spi_master_put) to solve the problem. Also, the device subsystem ensures that the remove function is only called once, and resets device driver data to NULL. Remove the unnecessaary calls to platform_set_drvdata(). Signed-off-by: Guenter Roeck <linux@roeck-us.net> Reviewed-by: Marek Vasut <marex@denx.de> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi-mxs.c5
1 files changed, 1 insertions, 4 deletions
diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c
index 4e7801dd571..10d34ebe9ca 100644
--- a/drivers/spi/spi-mxs.c
+++ b/drivers/spi/spi-mxs.c
@@ -586,7 +586,6 @@ static int __devinit mxs_spi_probe(struct platform_device *pdev)
586 return 0; 586 return 0;
587 587
588out_free_dma: 588out_free_dma:
589 platform_set_drvdata(pdev, NULL);
590 dma_release_channel(ssp->dmach); 589 dma_release_channel(ssp->dmach);
591 clk_disable_unprepare(ssp->clk); 590 clk_disable_unprepare(ssp->clk);
592out_master_free: 591out_master_free:
@@ -600,14 +599,12 @@ static int __devexit mxs_spi_remove(struct platform_device *pdev)
600 struct mxs_spi *spi; 599 struct mxs_spi *spi;
601 struct mxs_ssp *ssp; 600 struct mxs_ssp *ssp;
602 601
603 master = platform_get_drvdata(pdev); 602 master = spi_master_get(platform_get_drvdata(pdev));
604 spi = spi_master_get_devdata(master); 603 spi = spi_master_get_devdata(master);
605 ssp = &spi->ssp; 604 ssp = &spi->ssp;
606 605
607 spi_unregister_master(master); 606 spi_unregister_master(master);
608 607
609 platform_set_drvdata(pdev, NULL);
610
611 dma_release_channel(ssp->dmach); 608 dma_release_channel(ssp->dmach);
612 609
613 clk_disable_unprepare(ssp->clk); 610 clk_disable_unprepare(ssp->clk);