From: Lukas Wunner lukas@wunner.de
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.158202745... Signed-off-by: Mark Brown broonie@kernel.org Cc: stable@vger.kernel.org # v5.1+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/spi/spidev.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -394,6 +394,7 @@ spidev_ioctl(struct file *filp, unsigned 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 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);