| From 138c9c32f090894614899eca15e0bb7279f59865 Mon Sep 17 00:00:00 2001 |
| From: Lukas Wunner <lukas@wunner.de> |
| Date: Tue, 18 Feb 2020 13:08:00 +0100 |
| Subject: spi: spidev: Fix CS polarity if GPIO descriptors are used |
| |
| 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.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> |
| |
| --- |
| drivers/spi/spidev.c | 5 +++++ |
| 1 file changed, 5 insertions(+) |
| |
| --- a/drivers/spi/spidev.c |
| +++ b/drivers/spi/spidev.c |
| @@ -396,6 +396,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) { |
| @@ -403,6 +404,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); |