diff options
author | Mark Brown | 2016-07-21 23:53:31 +0100 |
---|---|---|
committer | Mark Brown | 2016-07-25 11:47:52 +0100 |
commit | ef4d96ec4ad947360f48677b6007a4c77953b090 (patch) | |
tree | 3596ca87c41742a64b444d8c129389298fc30921 /include | |
parent | f4502dd1da9b060a49d539eb754ff86cb97b89f0 (diff) |
spi: Split bus and I/O locking
The current SPI code attempts to use bus_lock_mutex for two purposes. One
is to implement spi_bus_lock() which grants exclusive access to the bus.
The other is to serialize access to the physical hardware. This duplicate
purpose causes confusion which leads to cases where access is not locked
when a caller holds the bus lock mutex. Fix this by splitting out the I/O
functionality into a new io_mutex.
This means taking both mutexes in the DMA path, replacing the existing
mutex with the new I/O one in the message pump (the mutex now always
being taken in the message pump) and taking the bus lock mutex in
spi_sync(), allowing __spi_sync() to have no mutex handling.
While we're at it hoist the mutex further up the message pump before we
power up the device so that all power up/down of the block is covered by
it and there are no races with in-line pumping of messages.
Reported-by: Rich Felker <dalias@libc.org>
Tested-by: Rich Felker <dalias@libc.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/spi/spi.h | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 7b53af4ba5f8..072cb2aa2413 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -312,8 +312,9 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * @flags: other constraints relevant to this driver * @max_transfer_size: function that returns the max transfer size for * a &spi_device; may be %NULL, so the default %SIZE_MAX will be used. + * @io_mutex: mutex for physical bus access * @bus_lock_spinlock: spinlock for SPI bus locking - * @bus_lock_mutex: mutex for SPI bus locking + * @bus_lock_mutex: mutex for exclusion of multiple callers * @bus_lock_flag: indicates that the SPI bus is locked for exclusive use * @setup: updates the device mode and clocking records used by a * device's SPI controller; protocol code may call this. This @@ -446,6 +447,9 @@ struct spi_master { */ size_t (*max_transfer_size)(struct spi_device *spi); + /* I/O mutex */ + struct mutex io_mutex; + /* lock and mutex for SPI bus locking */ spinlock_t bus_lock_spinlock; struct mutex bus_lock_mutex; |