From ef22d1604c622d24ded69f40d40c3c6d83f71156 Mon Sep 17 00:00:00 2001 From: Bhuvanchandra DV Date: Thu, 10 Dec 2015 11:25:30 +0530 Subject: spi-fsl-dspi: Fix CTAR Register access DSPI instances in Vybrid have a different amount of chip selects and CTARs (Clock and transfer Attributes Register). In case of DSPI1 we only have 2 CTAR registers and 4 CS. In present driver implementation CTAR offset is derived from CS instance which will lead to out of bound access if chip select instance is greater than CTAR register instance, hence use single CTAR0 register for all CS instances. Since we write the CTAR register anyway before each access, there is no value in using the additional CTAR registers. Also one should not program a value in CTAS for a CTAR register that is not present, hence configure CTAS to use CTAR0. Signed-off-by: Bhuvanchandra DV Acked-by: Stefan Agner Signed-off-by: Mark Brown diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 59a1143..39412c9 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -167,7 +167,7 @@ static inline int is_double_byte_mode(struct fsl_dspi *dspi) { unsigned int val; - regmap_read(dspi->regmap, SPI_CTAR(dspi->cs), &val); + regmap_read(dspi->regmap, SPI_CTAR(0), &val); return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0 : 1; } @@ -257,7 +257,7 @@ static u32 dspi_data_to_pushr(struct fsl_dspi *dspi, int tx_word) return SPI_PUSHR_TXDATA(d16) | SPI_PUSHR_PCS(dspi->cs) | - SPI_PUSHR_CTAS(dspi->cs) | + SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT; } @@ -290,7 +290,7 @@ static int dspi_eoq_write(struct fsl_dspi *dspi) */ if (tx_word && (dspi->len == 1)) { dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM; - regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs), + regmap_update_bits(dspi->regmap, SPI_CTAR(0), SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8)); tx_word = 0; } @@ -339,7 +339,7 @@ static int dspi_tcfq_write(struct fsl_dspi *dspi) if (tx_word && (dspi->len == 1)) { dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM; - regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs), + regmap_update_bits(dspi->regmap, SPI_CTAR(0), SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8)); tx_word = 0; } @@ -407,7 +407,7 @@ static int dspi_transfer_one_message(struct spi_master *master, regmap_update_bits(dspi->regmap, SPI_MCR, SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF, SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF); - regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), + regmap_write(dspi->regmap, SPI_CTAR(0), dspi->cur_chip->ctar_val); trans_mode = dspi->devtype_data->trans_mode; @@ -566,7 +566,7 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id) if (!dspi->len) { if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM) { regmap_update_bits(dspi->regmap, - SPI_CTAR(dspi->cs), + SPI_CTAR(0), SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(16)); dspi->dataflags &= ~TRAN_STATE_WORD_ODD_NUM; -- cgit v0.10.2 From 56ea1075e7f07724cf9b91039aa0968a0c70112f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 16 Nov 2015 13:57:37 +0000 Subject: spi: spidev: Hold spi_lock over all defererences of spi in release() We use the spi_lock spinlock to protect against races between the device being removed and file operations on the spidev. This means that in the removal path all references to the device need to be done under lock as in removal we dropping references to the device. Reported-by: Vegard Nossum Signed-off-by: Mark Brown diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 91a0fcd..d0e7dfc 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -651,11 +651,11 @@ static int spidev_release(struct inode *inode, struct file *filp) kfree(spidev->rx_buffer); spidev->rx_buffer = NULL; + spin_lock_irq(&spidev->spi_lock); if (spidev->spi) spidev->speed_hz = spidev->spi->max_speed_hz; /* ... after we unbound from the underlying device? */ - spin_lock_irq(&spidev->spi_lock); dofree = (spidev->spi == NULL); spin_unlock_irq(&spidev->spi_lock); -- cgit v0.10.2