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>
This commit is contained in:
parent
41682e03d4
commit
7d520d28dd
|
@ -586,7 +586,6 @@ static int __devinit mxs_spi_probe(struct platform_device *pdev)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_free_dma:
|
out_free_dma:
|
||||||
platform_set_drvdata(pdev, NULL);
|
|
||||||
dma_release_channel(ssp->dmach);
|
dma_release_channel(ssp->dmach);
|
||||||
clk_disable_unprepare(ssp->clk);
|
clk_disable_unprepare(ssp->clk);
|
||||||
out_master_free:
|
out_master_free:
|
||||||
|
@ -600,14 +599,12 @@ static int __devexit mxs_spi_remove(struct platform_device *pdev)
|
||||||
struct mxs_spi *spi;
|
struct mxs_spi *spi;
|
||||||
struct mxs_ssp *ssp;
|
struct mxs_ssp *ssp;
|
||||||
|
|
||||||
master = platform_get_drvdata(pdev);
|
master = spi_master_get(platform_get_drvdata(pdev));
|
||||||
spi = spi_master_get_devdata(master);
|
spi = spi_master_get_devdata(master);
|
||||||
ssp = &spi->ssp;
|
ssp = &spi->ssp;
|
||||||
|
|
||||||
spi_unregister_master(master);
|
spi_unregister_master(master);
|
||||||
|
|
||||||
platform_set_drvdata(pdev, NULL);
|
|
||||||
|
|
||||||
dma_release_channel(ssp->dmach);
|
dma_release_channel(ssp->dmach);
|
||||||
|
|
||||||
clk_disable_unprepare(ssp->clk);
|
clk_disable_unprepare(ssp->clk);
|
||||||
|
|
Loading…
Reference in New Issue