diff options
author | Lukas Wunner <lukas@wunner.de> | 2020-02-18 15:08:00 +0300 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2020-02-21 16:50:36 +0300 |
commit | 138c9c32f090894614899eca15e0bb7279f59865 (patch) | |
tree | 18d9d16b9fa2b80237666a4b6c67d906f2017ba0 /drivers/spi/spidev.c | |
parent | 136b5cd2e2f97581ae560cff0db2a3b5369112da (diff) | |
download | linux-138c9c32f090894614899eca15e0bb7279f59865.tar.xz |
spi: spidev: Fix CS polarity if GPIO descriptors are used
Commit f3186dd87669 ("spi: Optionally use GPIO descriptors for CS GPIOs")
amended of_spi_parse_dt() to always set SPI_CS_HIGH for SPI slaves whose
Chip Select is defined by a "cs-gpios" devicetree property.
This change broke userspace applications which issue an SPI_IOC_WR_MODE
ioctl() to an spidev: Chip Select polarity will be incorrect unless the
application is changed to set SPI_CS_HIGH. And once changed, it will be
incompatible with kernels not containing the commit.
Fix by setting SPI_CS_HIGH in spidev_ioctl() (under the same conditions
as in of_spi_parse_dt()).
Fixes: f3186dd87669 ("spi: Optionally use GPIO descriptors for CS GPIOs")
Reported-by: Simon Han <z.han@kunbus.com>
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/fca3ba7cdc930cd36854666ceac4fbcf01b89028.1582027457.git.lukas@wunner.de
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: stable@vger.kernel.org # v5.1+
Diffstat (limited to 'drivers/spi/spidev.c')
-rw-r--r-- | drivers/spi/spidev.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 1e217e3e9486..2ab6e782f14c 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -396,6 +396,7 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) else retval = get_user(tmp, (u32 __user *)arg); if (retval == 0) { + struct spi_controller *ctlr = spi->controller; u32 save = spi->mode; if (tmp & ~SPI_MODE_MASK) { @@ -403,6 +404,10 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) break; } + if (ctlr->use_gpio_descriptors && ctlr->cs_gpiods && + ctlr->cs_gpiods[spi->chip_select]) + tmp |= SPI_CS_HIGH; + tmp |= spi->mode & ~SPI_MODE_MASK; spi->mode = (u16)tmp; retval = spi_setup(spi); |