summaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi.c
diff options
context:
space:
mode:
authorStefan Brüns <stefan.bruens@rwth-aachen.de>2015-08-23 16:06:30 +0200
committerMark Brown <broonie@kernel.org>2015-08-26 18:58:29 +0100
commit63ab645f4d8b2dc1351c41751e7ebb1b3f1c99d3 (patch)
tree8188f47312a99fd8c04ee233c1f94d7c943cfd1e /drivers/spi/spi.c
parent7dc9fbc342deb2e2658ebdecb5ffd7ff57945a66 (diff)
downloadop-kernel-dev-63ab645f4d8b2dc1351c41751e7ebb1b3f1c99d3.zip
op-kernel-dev-63ab645f4d8b2dc1351c41751e7ebb1b3f1c99d3.tar.gz
spi: check bits_per_word in spi_setup
This allows drivers for devices connected via SPI to check if the controller supports a given bits_per_word value during setup. Currently any BPW value is accepted durings setup, and transfers are rejected later. Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r--drivers/spi/spi.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 637d892..829323ce 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1740,6 +1740,20 @@ EXPORT_SYMBOL_GPL(spi_busnum_to_master);
* other core methods are currently defined as inline functions.
*/
+static int __spi_validate_bits_per_word(struct spi_master *master, u8 bits_per_word)
+{
+ if (master->bits_per_word_mask) {
+ /* Only 32 bits fit in the mask */
+ if (bits_per_word > 32)
+ return -EINVAL;
+ if (!(master->bits_per_word_mask &
+ SPI_BPW_MASK(bits_per_word)))
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
/**
* spi_setup - setup SPI mode and clock rate
* @spi: the device whose settings are being modified
@@ -1798,6 +1812,9 @@ int spi_setup(struct spi_device *spi)
if (!spi->bits_per_word)
spi->bits_per_word = 8;
+ if (__spi_validate_bits_per_word(spi->master, spi->bits_per_word))
+ return -EINVAL;
+
if (!spi->max_speed_hz)
spi->max_speed_hz = spi->master->max_speed_hz;
@@ -1867,14 +1884,8 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
xfer->speed_hz > master->max_speed_hz)
xfer->speed_hz = master->max_speed_hz;
- if (master->bits_per_word_mask) {
- /* Only 32 bits fit in the mask */
- if (xfer->bits_per_word > 32)
- return -EINVAL;
- if (!(master->bits_per_word_mask &
- BIT(xfer->bits_per_word - 1)))
- return -EINVAL;
- }
+ if (__spi_validate_bits_per_word(master, xfer->bits_per_word))
+ return -EINVAL;
/*
* SPI transfer length should be multiple of SPI word size
OpenPOWER on IntegriCloud