diff options
author | Guenter Roeck <linux@roeck-us.net> | 2012-08-24 14:03:02 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-08-27 14:23:52 -0400 |
commit | 7d520d28dd5287d14b5ec6cf4405a1220ca57d42 (patch) | |
tree | 608e5d27690e3053a941ee4d2e8ab92200932982 /drivers/spi | |
parent | 41682e03d4fdc947dbd22725d70f222cc7746852 (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.c | 5 |
1 files changed, 1 insertions, 4 deletions
diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c index 4e7801dd571a..10d34ebe9ca3 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 | ||
588 | out_free_dma: | 588 | out_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); |
592 | out_master_free: | 591 | out_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); |