spi: Fixes for v4.4

There's one fix for the core here, we weren't reinitialising the actual
 transferred length in messages when they get reused which meant that
 we'd just keep adding to the length if a message is reused.  This has
 limited impact since it's only used in error handling cases but will
 really mess anything that tries to use it up when it triggers.
 
 As ever there's a small collection of driver specific fixes too.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJWXaUPAAoJECTWi3JdVIfQLPAH/1A6xgPcS2HnBu43ezzQu9JY
 gd22gYN1+klyKhOzWv86zG0vbT/sVo2YCTb8nbnGfMCc5ghwlxF1fl2mCVXRTr2F
 7dP2n43TmTNsuXQjO4tv2iJTkCXXuhoEr3DTrOu3+ywm+HNn1gUPgOl0i7zZpuIJ
 AcQ0uuh33k5nQW3elj/gFcdjlVdHIq5oNpP4JBJeOn+ijsd/6DzVyW+TBiGnImWX
 50XCuM+gUvj762y77T3rgORkWwkmJSQIjV+TNKXD/hIDvVWQK9OvtyMpGBOTe7nH
 emEiy7BJnVIdpknUUVf0ZqjNpprxpLwU+ryQhVC9orP0dL64GlsbPkFOtIgxkDs=
 =NlLa
 -----END PGP SIGNATURE-----

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

Pull spi fixes from Mark Brown:
 "There's one fix for the core here, we weren't reinitialising the
  actual transferred length in messages when they get reused which meant
  that we'd just keep adding to the length if a message is reused.  This
  has limited impact since it's only used in error handling cases but
  will really mess anything that tries to use it up when it triggers.

  As ever there's a small collection of driver specific fixes too"

* tag 'spi-fix-v4.4-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: bugfix: spi_message.transfer_length does not get reset
  spi: pl022: handle EPROBE_DEFER for dma
  spi: bcm63xx: use correct format string for printing a resource
  spi: mediatek: single device does not require cs_gpios
  spi: Add missing kerneldoc description for parameter
This commit is contained in:
Linus Torvalds 2015-12-02 16:45:56 -08:00
commit e69be8c2de
4 changed files with 44 additions and 16 deletions

View File

@ -562,8 +562,8 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
goto out_clk_disable; goto out_clk_disable;
} }
dev_info(dev, "at 0x%08x (irq %d, FIFOs size %d)\n", dev_info(dev, "at %pr (irq %d, FIFOs size %d)\n",
r->start, irq, bs->fifo_size); r, irq, bs->fifo_size);
return 0; return 0;

View File

@ -410,7 +410,7 @@ static int mtk_spi_setup(struct spi_device *spi)
if (!spi->controller_data) if (!spi->controller_data)
spi->controller_data = (void *)&mtk_default_chip_info; spi->controller_data = (void *)&mtk_default_chip_info;
if (mdata->dev_comp->need_pad_sel) if (mdata->dev_comp->need_pad_sel && gpio_is_valid(spi->cs_gpio))
gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH));
return 0; return 0;
@ -632,8 +632,17 @@ static int mtk_spi_probe(struct platform_device *pdev)
goto err_put_master; goto err_put_master;
} }
if (!master->cs_gpios && master->num_chipselect > 1) {
dev_err(&pdev->dev,
"cs_gpios not specified and num_chipselect > 1\n");
ret = -EINVAL;
goto err_put_master;
}
if (master->cs_gpios) {
for (i = 0; i < master->num_chipselect; i++) { for (i = 0; i < master->num_chipselect; i++) {
ret = devm_gpio_request(&pdev->dev, master->cs_gpios[i], ret = devm_gpio_request(&pdev->dev,
master->cs_gpios[i],
dev_name(&pdev->dev)); dev_name(&pdev->dev));
if (ret) { if (ret) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
@ -642,6 +651,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
} }
} }
} }
}
return 0; return 0;

View File

@ -1171,19 +1171,31 @@ err_no_rxchan:
static int pl022_dma_autoprobe(struct pl022 *pl022) static int pl022_dma_autoprobe(struct pl022 *pl022)
{ {
struct device *dev = &pl022->adev->dev; struct device *dev = &pl022->adev->dev;
struct dma_chan *chan;
int err;
/* automatically configure DMA channels from platform, normally using DT */ /* automatically configure DMA channels from platform, normally using DT */
pl022->dma_rx_channel = dma_request_slave_channel(dev, "rx"); chan = dma_request_slave_channel_reason(dev, "rx");
if (!pl022->dma_rx_channel) if (IS_ERR(chan)) {
err = PTR_ERR(chan);
goto err_no_rxchan; goto err_no_rxchan;
}
pl022->dma_tx_channel = dma_request_slave_channel(dev, "tx"); pl022->dma_rx_channel = chan;
if (!pl022->dma_tx_channel)
chan = dma_request_slave_channel_reason(dev, "tx");
if (IS_ERR(chan)) {
err = PTR_ERR(chan);
goto err_no_txchan; goto err_no_txchan;
}
pl022->dma_tx_channel = chan;
pl022->dummypage = kmalloc(PAGE_SIZE, GFP_KERNEL); pl022->dummypage = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!pl022->dummypage) if (!pl022->dummypage) {
err = -ENOMEM;
goto err_no_dummypage; goto err_no_dummypage;
}
return 0; return 0;
@ -1194,7 +1206,7 @@ err_no_txchan:
dma_release_channel(pl022->dma_rx_channel); dma_release_channel(pl022->dma_rx_channel);
pl022->dma_rx_channel = NULL; pl022->dma_rx_channel = NULL;
err_no_rxchan: err_no_rxchan:
return -ENODEV; return err;
} }
static void terminate_dma(struct pl022 *pl022) static void terminate_dma(struct pl022 *pl022)
@ -2236,6 +2248,10 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
/* Get DMA channels, try autoconfiguration first */ /* Get DMA channels, try autoconfiguration first */
status = pl022_dma_autoprobe(pl022); status = pl022_dma_autoprobe(pl022);
if (status == -EPROBE_DEFER) {
dev_dbg(dev, "deferring probe to get DMA channel\n");
goto err_no_irq;
}
/* If that failed, use channels from platform_info */ /* If that failed, use channels from platform_info */
if (status == 0) if (status == 0)

View File

@ -376,6 +376,7 @@ static void spi_drv_shutdown(struct device *dev)
/** /**
* __spi_register_driver - register a SPI driver * __spi_register_driver - register a SPI driver
* @owner: owner module of the driver to register
* @sdrv: the driver to register * @sdrv: the driver to register
* Context: can sleep * Context: can sleep
* *
@ -2130,6 +2131,7 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
* Set transfer tx_nbits and rx_nbits as single transfer default * Set transfer tx_nbits and rx_nbits as single transfer default
* (SPI_NBITS_SINGLE) if it is not set for this transfer. * (SPI_NBITS_SINGLE) if it is not set for this transfer.
*/ */
message->frame_length = 0;
list_for_each_entry(xfer, &message->transfers, transfer_list) { list_for_each_entry(xfer, &message->transfers, transfer_list) {
message->frame_length += xfer->len; message->frame_length += xfer->len;
if (!xfer->bits_per_word) if (!xfer->bits_per_word)