提交 3c73a2dd 编写于 作者: L Linus Torvalds

Merge tag 'spi-fix-v4.4-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

Pull spi fixes from Mark Brown:
 "A couple of reference counting bugs here, one in spidev and one with
  holding an extra reference in the core that we never freed if we
  removed a device, plus a driver specific fix.  Both of the refcounting
  bugs are very old but they've only been found by observation so
  hopefully their impact has been low"

* tag 'spi-fix-v4.4-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: fix parent-device reference leak
  spi: spidev: Hold spi_lock over all defererences of spi in release()
  spi-fsl-dspi: Fix CTAR Register access
...@@ -167,7 +167,7 @@ static inline int is_double_byte_mode(struct fsl_dspi *dspi) ...@@ -167,7 +167,7 @@ static inline int is_double_byte_mode(struct fsl_dspi *dspi)
{ {
unsigned int val; 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; 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) ...@@ -257,7 +257,7 @@ static u32 dspi_data_to_pushr(struct fsl_dspi *dspi, int tx_word)
return SPI_PUSHR_TXDATA(d16) | return SPI_PUSHR_TXDATA(d16) |
SPI_PUSHR_PCS(dspi->cs) | SPI_PUSHR_PCS(dspi->cs) |
SPI_PUSHR_CTAS(dspi->cs) | SPI_PUSHR_CTAS(0) |
SPI_PUSHR_CONT; SPI_PUSHR_CONT;
} }
...@@ -290,7 +290,7 @@ static int dspi_eoq_write(struct fsl_dspi *dspi) ...@@ -290,7 +290,7 @@ static int dspi_eoq_write(struct fsl_dspi *dspi)
*/ */
if (tx_word && (dspi->len == 1)) { if (tx_word && (dspi->len == 1)) {
dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM; 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)); SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8));
tx_word = 0; tx_word = 0;
} }
...@@ -339,7 +339,7 @@ static int dspi_tcfq_write(struct fsl_dspi *dspi) ...@@ -339,7 +339,7 @@ static int dspi_tcfq_write(struct fsl_dspi *dspi)
if (tx_word && (dspi->len == 1)) { if (tx_word && (dspi->len == 1)) {
dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM; 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)); SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8));
tx_word = 0; tx_word = 0;
} }
...@@ -407,7 +407,7 @@ static int dspi_transfer_one_message(struct spi_master *master, ...@@ -407,7 +407,7 @@ static int dspi_transfer_one_message(struct spi_master *master,
regmap_update_bits(dspi->regmap, SPI_MCR, regmap_update_bits(dspi->regmap, SPI_MCR,
SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF, SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF,
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); dspi->cur_chip->ctar_val);
trans_mode = dspi->devtype_data->trans_mode; trans_mode = dspi->devtype_data->trans_mode;
...@@ -566,7 +566,7 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id) ...@@ -566,7 +566,7 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id)
if (!dspi->len) { if (!dspi->len) {
if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM) { if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM) {
regmap_update_bits(dspi->regmap, regmap_update_bits(dspi->regmap,
SPI_CTAR(dspi->cs), SPI_CTAR(0),
SPI_FRAME_BITS_MASK, SPI_FRAME_BITS_MASK,
SPI_FRAME_BITS(16)); SPI_FRAME_BITS(16));
dspi->dataflags &= ~TRAN_STATE_WORD_ODD_NUM; dspi->dataflags &= ~TRAN_STATE_WORD_ODD_NUM;
......
...@@ -1705,7 +1705,7 @@ struct spi_master *spi_alloc_master(struct device *dev, unsigned size) ...@@ -1705,7 +1705,7 @@ struct spi_master *spi_alloc_master(struct device *dev, unsigned size)
master->bus_num = -1; master->bus_num = -1;
master->num_chipselect = 1; master->num_chipselect = 1;
master->dev.class = &spi_master_class; master->dev.class = &spi_master_class;
master->dev.parent = get_device(dev); master->dev.parent = dev;
spi_master_set_devdata(master, &master[1]); spi_master_set_devdata(master, &master[1]);
return master; return master;
......
...@@ -651,11 +651,11 @@ static int spidev_release(struct inode *inode, struct file *filp) ...@@ -651,11 +651,11 @@ static int spidev_release(struct inode *inode, struct file *filp)
kfree(spidev->rx_buffer); kfree(spidev->rx_buffer);
spidev->rx_buffer = NULL; spidev->rx_buffer = NULL;
spin_lock_irq(&spidev->spi_lock);
if (spidev->spi) if (spidev->spi)
spidev->speed_hz = spidev->spi->max_speed_hz; spidev->speed_hz = spidev->spi->max_speed_hz;
/* ... after we unbound from the underlying device? */ /* ... after we unbound from the underlying device? */
spin_lock_irq(&spidev->spi_lock);
dofree = (spidev->spi == NULL); dofree = (spidev->spi == NULL);
spin_unlock_irq(&spidev->spi_lock); spin_unlock_irq(&spidev->spi_lock);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册