summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2012-08-23 20:08:47 -0700
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-08-27 09:37:52 -0700
commit154390dcf826dc97b9d338305db14582c32cb58a (patch)
treebb26c340dfaaa81a88bc2bd0a0cc71521f1c06ac
parent58ed90de3ef58a19c035355a4a0cd6dfef6d6b0c (diff)
downloadlinux-3.10-154390dcf826dc97b9d338305db14582c32cb58a.tar.gz
linux-3.10-154390dcf826dc97b9d338305db14582c32cb58a.tar.bz2
linux-3.10-154390dcf826dc97b9d338305db14582c32cb58a.zip
spi/stmp: 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 respective check and drop the unnecessaary call to platform_set_drvdata(). Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--drivers/spi/spi-stmp.c6
1 files changed, 1 insertions, 5 deletions
diff --git a/drivers/spi/spi-stmp.c b/drivers/spi/spi-stmp.c
index 58e38528532..911e904b3c8 100644
--- a/drivers/spi/spi-stmp.c
+++ b/drivers/spi/spi-stmp.c
@@ -594,9 +594,7 @@ static int __devexit stmp_spi_remove(struct platform_device *dev)
struct stmp_spi *ss;
struct spi_master *master;
- master = platform_get_drvdata(dev);
- if (master == NULL)
- goto out0;
+ master = spi_master_get(platform_get_drvdata(dev));
ss = spi_master_get_devdata(master);
spi_unregister_master(master);
@@ -609,8 +607,6 @@ static int __devexit stmp_spi_remove(struct platform_device *dev)
destroy_workqueue(ss->workqueue);
iounmap(ss->regs);
spi_master_put(master);
- platform_set_drvdata(dev, NULL);
-out0:
return 0;
}