summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Wunner <lukas@wunner.de>2020-02-18 13:08:00 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-03-12 13:00:22 +0100
commit83b2a8fe43bda0c11981ad6afa5dd0104d78be28 (patch)
tree635d6738c0418048a39fb6f9065b36104816550b
parentfc73ded13f161b01066e3bbdf1a203bcd76fd28c (diff)
downloadlinux-83b2a8fe43bda0c11981ad6afa5dd0104d78be28.tar.gz
linux-83b2a8fe43bda0c11981ad6afa5dd0104d78be28.tar.bz2
linux-83b2a8fe43bda0c11981ad6afa5dd0104d78be28.zip
spi: spidev: Fix CS polarity if GPIO descriptors are used
commit 138c9c32f090894614899eca15e0bb7279f59865 upstream. 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+ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/spi/spidev.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index 3ea9d8a3e6e8..ab2c3848f5bf 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -394,6 +394,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) {
@@ -401,6 +402,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);