From: Alexander Sverdlin <alexander.sverdlin@xxxxxxxxxxx> Commit f3186dd87669 ("spi: Optionally use GPIO descriptors for CS GPIOs") has changed the user-space interface so that bogus SPI_CS_HIGH started to appear in the mask returned by SPI_IOC_RD_MODE even for active-low CS pins. Commit 138c9c32f090 ("spi: spidev: Fix CS polarity if GPIO descriptors are used") fixed only SPI_IOC_WR_MODE part of the problem. Let's fix SPI_IOC_RD_MODE symmetrically. Test case: #include <sys/ioctl.h> #include <fcntl.h> #include <linux/spi/spidev.h> int main(int argc, char **argv) { char modew = SPI_CPHA; char moder; int f = open("/dev/spidev0.0", O_RDWR); if (f < 0) return 1; ioctl(f, SPI_IOC_WR_MODE, &modew); ioctl(f, SPI_IOC_RD_MODE, &moder); return moder == modew ? 0 : 2; } Fixes: f3186dd87669 ("spi: Optionally use GPIO descriptors for CS GPIOs") Signed-off-by: Alexander Sverdlin <alexander.sverdlin@xxxxxxxxxxx> --- drivers/spi/spidev.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index b2775d82d2d7b..23177a7c916c3 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -377,8 +377,17 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) switch (cmd) { /* read requests */ case SPI_IOC_RD_MODE: - retval = put_user(spi->mode & SPI_MODE_MASK, - (__u8 __user *)arg); + tmp = spi->mode; + + { + struct spi_controller *ctlr = spi->controller; + + if (ctlr->use_gpio_descriptors && ctlr->cs_gpiods && + ctlr->cs_gpiods[spi->chip_select]) + tmp &= ~SPI_CS_HIGH; + } + + retval = put_user(tmp & SPI_MODE_MASK, (__u8 __user *)arg); break; case SPI_IOC_RD_MODE32: retval = put_user(spi->mode & SPI_MODE_MASK, -- 2.34.1