Skip to content

Commit b9dd3f6

Browse files
l1kbroonie
authored andcommitted
spi: bcm2835aux: Fix controller unregister order
The BCM2835aux SPI driver uses devm_spi_register_master() on bind. As a consequence, on unbind, __device_release_driver() first invokes bcm2835aux_spi_remove() before unregistering the SPI controller via devres_release_all(). This order is incorrect: bcm2835aux_spi_remove() turns off the SPI controller, including its interrupts and clock. The SPI controller is thus no longer usable. When the SPI controller is subsequently unregistered, it unbinds all its slave devices. If their drivers need to access the SPI bus, e.g. to quiesce their interrupts, unbinding will fail. As a rule, devm_spi_register_master() must not be used if the ->remove() hook performs teardown steps which shall be performed after unbinding of slaves. Fix by using the non-devm variant spi_register_master(). Note that the struct spi_master as well as the driver-private data are not freed until after bcm2835aux_spi_remove() has finished, so accessing them is safe. Fixes: 1ea29b3 ("spi: bcm2835aux: add bcm2835 auxiliary spi device driver") Signed-off-by: Lukas Wunner <[email protected]> Cc: [email protected] # v4.4+ Cc: Martin Sperl <[email protected]> Link: https://lore.kernel.org/r/32f27f4d8242e4d75f9a53f7e8f1f77483b08669.1589557526.git.lukas@wunner.de Signed-off-by: Mark Brown <[email protected]>
1 parent 9dd277f commit b9dd3f6

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

drivers/spi/spi-bcm2835aux.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev)
569569
goto out_clk_disable;
570570
}
571571

572-
err = devm_spi_register_master(&pdev->dev, master);
572+
err = spi_register_master(master);
573573
if (err) {
574574
dev_err(&pdev->dev, "could not register SPI master: %d\n", err);
575575
goto out_clk_disable;
@@ -593,6 +593,8 @@ static int bcm2835aux_spi_remove(struct platform_device *pdev)
593593

594594
bcm2835aux_debugfs_remove(bs);
595595

596+
spi_unregister_master(master);
597+
596598
bcm2835aux_spi_reset_hw(bs);
597599

598600
/* disable the HW block by releasing the clock */

0 commit comments

Comments
 (0)