diff options
author | Lukas Wunner <lukas@wunner.de> | 2020-12-06 13:46:00 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-12-11 13:38:00 +0100 |
commit | 0870525cf94bc27907e94ce99afb6d7239ffd2f5 (patch) | |
tree | dabb7e45f95981a8508908a7236b4cea2015749a /include/linux | |
parent | 2b8d8c968b495c3a4cb1edb5a43a4bbf9ee9587f (diff) | |
download | linux-stable-0870525cf94bc27907e94ce99afb6d7239ffd2f5.tar.gz linux-stable-0870525cf94bc27907e94ce99afb6d7239ffd2f5.tar.bz2 linux-stable-0870525cf94bc27907e94ce99afb6d7239ffd2f5.zip |
spi: Introduce device-managed SPI controller allocation
[ Upstream commit 5e844cc37a5cbaa460e68f9a989d321d63088a89 ]
SPI driver probing currently comprises two steps, whereas removal
comprises only one step:
spi_alloc_master()
spi_register_master()
spi_unregister_master()
That's because spi_unregister_master() calls device_unregister()
instead of device_del(), thereby releasing the reference on the
spi_master which was obtained by spi_alloc_master().
An SPI driver's private data is contained in the same memory allocation
as the spi_master struct. Thus, once spi_unregister_master() has been
called, the private data is inaccessible. But some drivers need to
access it after spi_unregister_master() to perform further teardown
steps.
Introduce devm_spi_alloc_master(), which releases a reference on the
spi_master struct only after the driver has unbound, thereby keeping the
memory allocation accessible. Change spi_unregister_master() to not
release a reference if the spi_master was allocated by the new devm
function.
The present commit is small enough to be backportable to stable.
It allows fixing drivers which use the private data in their ->remove()
hook after it's been freed. It also allows fixing drivers which neglect
to release a reference on the spi_master in the probe error path.
Long-term, most SPI drivers shall be moved over to the devm function
introduced herein. The few that can't shall be changed in a treewide
commit to explicitly release the last reference on the master.
That commit shall amend spi_unregister_master() to no longer release
a reference, thereby completing the migration.
As a result, the behaviour will be less surprising and more consistent
with subsystems such as IIO, which also includes the private data in the
allocation of the generic iio_dev struct, but calls device_del() in
iio_device_unregister().
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Link: https://lore.kernel.org/r/272bae2ef08abd21388c98e23729886663d19192.1605121038.git.lukas@wunner.de
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/spi/spi.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 4b743ac35396..8470695e5dd7 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -601,6 +601,8 @@ extern void spi_finalize_current_transfer(struct spi_master *master); /* the spi driver core manages memory for the spi_master classdev */ extern struct spi_master * spi_alloc_master(struct device *host, unsigned size); +extern struct spi_master * +devm_spi_alloc_master(struct device *dev, unsigned int size); extern int spi_register_master(struct spi_master *master); extern int devm_spi_register_master(struct device *dev, |