aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2012-08-23 23:08:47 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-08-27 12:37:52 -0400
commit154390dcf826dc97b9d338305db14582c32cb58a (patch)
treebb26c340dfaaa81a88bc2bd0a0cc71521f1c06ac /drivers/spi
parent58ed90de3ef58a19c035355a4a0cd6dfef6d6b0c (diff)
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>
Diffstat (limited to 'drivers/spi')
-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 58e385285323..911e904b3c84 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)
594 struct stmp_spi *ss; 594 struct stmp_spi *ss;
595 struct spi_master *master; 595 struct spi_master *master;
596 596
597 master = platform_get_drvdata(dev); 597 master = spi_master_get(platform_get_drvdata(dev));
598 if (master == NULL)
599 goto out0;
600 ss = spi_master_get_devdata(master); 598 ss = spi_master_get_devdata(master);
601 599
602 spi_unregister_master(master); 600 spi_unregister_master(master);
@@ -609,8 +607,6 @@ static int __devexit stmp_spi_remove(struct platform_device *dev)
609 destroy_workqueue(ss->workqueue); 607 destroy_workqueue(ss->workqueue);
610 iounmap(ss->regs); 608 iounmap(ss->regs);
611 spi_master_put(master); 609 spi_master_put(master);
612 platform_set_drvdata(dev, NULL);
613out0:
614 return 0; 610 return 0;
615} 611}
616 612