diff options
author | Stephen Warren <swarren@wwwdotorg.org> | 2013-03-26 22:37:57 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-04-01 09:14:32 -0400 |
commit | 543bb255a1987836e64f5b7a63664ead8b32b042 (patch) | |
tree | 818ee5b60f8d24ccfd495ebdb50ea0a175c340b1 | |
parent | 5c725b34d438fdd3c528673a5f53f4b07f879c68 (diff) |
spi: add ability to validate xfer->bits_per_word in SPI core
Allow SPI masters to define the set of bits_per_word values they support.
If they do this, then the SPI core will reject transfers that attempt to
use an unsupported bits_per_word value. This eliminates the need for each
SPI driver to implement this checking in most cases.
Signed-off-by: Stephen Warren <swarren@wwwdotorg.org>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r-- | drivers/spi/spi.c | 8 | ||||
-rw-r--r-- | include/linux/spi/spi.h | 8 |
2 files changed, 16 insertions, 0 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index f996c600eb8c..0cabf1560550 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -1377,6 +1377,14 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message) | |||
1377 | xfer->bits_per_word = spi->bits_per_word; | 1377 | xfer->bits_per_word = spi->bits_per_word; |
1378 | if (!xfer->speed_hz) | 1378 | if (!xfer->speed_hz) |
1379 | xfer->speed_hz = spi->max_speed_hz; | 1379 | xfer->speed_hz = spi->max_speed_hz; |
1380 | if (master->bits_per_word_mask) { | ||
1381 | /* Only 32 bits fit in the mask */ | ||
1382 | if (xfer->bits_per_word > 32) | ||
1383 | return -EINVAL; | ||
1384 | if (!(master->bits_per_word_mask & | ||
1385 | BIT(xfer->bits_per_word - 1))) | ||
1386 | return -EINVAL; | ||
1387 | } | ||
1380 | } | 1388 | } |
1381 | 1389 | ||
1382 | message->spi = spi; | 1390 | message->spi = spi; |
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 38c2b925923d..733eb5ee31c5 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h | |||
@@ -228,6 +228,11 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) | |||
228 | * every chipselect is connected to a slave. | 228 | * every chipselect is connected to a slave. |
229 | * @dma_alignment: SPI controller constraint on DMA buffers alignment. | 229 | * @dma_alignment: SPI controller constraint on DMA buffers alignment. |
230 | * @mode_bits: flags understood by this controller driver | 230 | * @mode_bits: flags understood by this controller driver |
231 | * @bits_per_word_mask: A mask indicating which values of bits_per_word are | ||
232 | * supported by the driver. Bit n indicates that a bits_per_word n+1 is | ||
233 | * suported. If set, the SPI core will reject any transfer with an | ||
234 | * unsupported bits_per_word. If not set, this value is simply ignored, | ||
235 | * and it's up to the individual driver to perform any validation. | ||
231 | * @flags: other constraints relevant to this driver | 236 | * @flags: other constraints relevant to this driver |
232 | * @bus_lock_spinlock: spinlock for SPI bus locking | 237 | * @bus_lock_spinlock: spinlock for SPI bus locking |
233 | * @bus_lock_mutex: mutex for SPI bus locking | 238 | * @bus_lock_mutex: mutex for SPI bus locking |
@@ -301,6 +306,9 @@ struct spi_master { | |||
301 | /* spi_device.mode flags understood by this controller driver */ | 306 | /* spi_device.mode flags understood by this controller driver */ |
302 | u16 mode_bits; | 307 | u16 mode_bits; |
303 | 308 | ||
309 | /* bitmask of supported bits_per_word for transfers */ | ||
310 | u32 bits_per_word_mask; | ||
311 | |||
304 | /* other constraints relevant to this driver */ | 312 | /* other constraints relevant to this driver */ |
305 | u16 flags; | 313 | u16 flags; |
306 | #define SPI_MASTER_HALF_DUPLEX BIT(0) /* can't do full duplex */ | 314 | #define SPI_MASTER_HALF_DUPLEX BIT(0) /* can't do full duplex */ |