Skip to content

Commit

Permalink
Merge tag 'spi-fix-v4.19-rc5' of https://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/broonie/spi

Mark writes:
  "spi: Fixes for v4.19

   Quite a few fixes for the Renesas drivers in here, plus a fix for the
   Tegra driver and some documentation fixes for the recently added
   spi-mem code.  The Tegra fix is relatively large but fairly
   straightforward and mechanical, it runs on probe so it's been
   reasonably well covered in -next testing."

* tag 'spi-fix-v4.19-rc5' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: spi-mem: Move the DMA-able constraint doc to the kerneldoc header
  spi: spi-mem: Add missing description for data.nbytes field
  spi: rspi: Fix interrupted DMA transfers
  spi: rspi: Fix invalid SPI use during system suspend
  spi: sh-msiof: Fix handling of write value for SISTR register
  spi: sh-msiof: Fix invalid SPI use during system suspend
  spi: gpio: Fix copy-and-paste error
  spi: tegra20-slink: explicitly enable/disable clock
  • Loading branch information
gregkh committed Sep 29, 2018
2 parents 8f05661 + c949a8e commit 2f19e7a
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 18 deletions.
4 changes: 2 additions & 2 deletions drivers/spi/spi-gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,8 @@ static int spi_gpio_request(struct device *dev,
*mflags |= SPI_MASTER_NO_RX;

spi_gpio->sck = devm_gpiod_get(dev, "sck", GPIOD_OUT_LOW);
if (IS_ERR(spi_gpio->mosi))
return PTR_ERR(spi_gpio->mosi);
if (IS_ERR(spi_gpio->sck))
return PTR_ERR(spi_gpio->sck);

for (i = 0; i < num_chipselects; i++) {
spi_gpio->cs_gpios[i] = devm_gpiod_get_index(dev, "cs",
Expand Down
34 changes: 30 additions & 4 deletions drivers/spi/spi-rspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -598,11 +598,13 @@ static int rspi_dma_transfer(struct rspi_data *rspi, struct sg_table *tx,

ret = wait_event_interruptible_timeout(rspi->wait,
rspi->dma_callbacked, HZ);
if (ret > 0 && rspi->dma_callbacked)
if (ret > 0 && rspi->dma_callbacked) {
ret = 0;
else if (!ret) {
dev_err(&rspi->master->dev, "DMA timeout\n");
ret = -ETIMEDOUT;
} else {
if (!ret) {
dev_err(&rspi->master->dev, "DMA timeout\n");
ret = -ETIMEDOUT;
}
if (tx)
dmaengine_terminate_all(rspi->master->dma_tx);
if (rx)
Expand Down Expand Up @@ -1350,12 +1352,36 @@ static const struct platform_device_id spi_driver_ids[] = {

MODULE_DEVICE_TABLE(platform, spi_driver_ids);

#ifdef CONFIG_PM_SLEEP
static int rspi_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct rspi_data *rspi = platform_get_drvdata(pdev);

return spi_master_suspend(rspi->master);
}

static int rspi_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct rspi_data *rspi = platform_get_drvdata(pdev);

return spi_master_resume(rspi->master);
}

static SIMPLE_DEV_PM_OPS(rspi_pm_ops, rspi_suspend, rspi_resume);
#define DEV_PM_OPS &rspi_pm_ops
#else
#define DEV_PM_OPS NULL
#endif /* CONFIG_PM_SLEEP */

static struct platform_driver rspi_driver = {
.probe = rspi_probe,
.remove = rspi_remove,
.id_table = spi_driver_ids,
.driver = {
.name = "renesas_spi",
.pm = DEV_PM_OPS,
.of_match_table = of_match_ptr(rspi_of_match),
},
};
Expand Down
28 changes: 27 additions & 1 deletion drivers/spi/spi-sh-msiof.c
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,8 @@ static void sh_msiof_spi_set_mode_regs(struct sh_msiof_spi_priv *p,

static void sh_msiof_reset_str(struct sh_msiof_spi_priv *p)
{
sh_msiof_write(p, STR, sh_msiof_read(p, STR));
sh_msiof_write(p, STR,
sh_msiof_read(p, STR) & ~(STR_TDREQ | STR_RDREQ));
}

static void sh_msiof_spi_write_fifo_8(struct sh_msiof_spi_priv *p,
Expand Down Expand Up @@ -1426,12 +1427,37 @@ static const struct platform_device_id spi_driver_ids[] = {
};
MODULE_DEVICE_TABLE(platform, spi_driver_ids);

#ifdef CONFIG_PM_SLEEP
static int sh_msiof_spi_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct sh_msiof_spi_priv *p = platform_get_drvdata(pdev);

return spi_master_suspend(p->master);
}

static int sh_msiof_spi_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct sh_msiof_spi_priv *p = platform_get_drvdata(pdev);

return spi_master_resume(p->master);
}

static SIMPLE_DEV_PM_OPS(sh_msiof_spi_pm_ops, sh_msiof_spi_suspend,
sh_msiof_spi_resume);
#define DEV_PM_OPS &sh_msiof_spi_pm_ops
#else
#define DEV_PM_OPS NULL
#endif /* CONFIG_PM_SLEEP */

static struct platform_driver sh_msiof_spi_drv = {
.probe = sh_msiof_spi_probe,
.remove = sh_msiof_spi_remove,
.id_table = spi_driver_ids,
.driver = {
.name = "spi_sh_msiof",
.pm = DEV_PM_OPS,
.of_match_table = of_match_ptr(sh_msiof_match),
},
};
Expand Down
31 changes: 23 additions & 8 deletions drivers/spi/spi-tegra20-slink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1063,6 +1063,24 @@ static int tegra_slink_probe(struct platform_device *pdev)
goto exit_free_master;
}

/* disabled clock may cause interrupt storm upon request */
tspi->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(tspi->clk)) {
ret = PTR_ERR(tspi->clk);
dev_err(&pdev->dev, "Can not get clock %d\n", ret);
goto exit_free_master;
}
ret = clk_prepare(tspi->clk);
if (ret < 0) {
dev_err(&pdev->dev, "Clock prepare failed %d\n", ret);
goto exit_free_master;
}
ret = clk_enable(tspi->clk);
if (ret < 0) {
dev_err(&pdev->dev, "Clock enable failed %d\n", ret);
goto exit_free_master;
}

spi_irq = platform_get_irq(pdev, 0);
tspi->irq = spi_irq;
ret = request_threaded_irq(tspi->irq, tegra_slink_isr,
Expand All @@ -1071,14 +1089,7 @@ static int tegra_slink_probe(struct platform_device *pdev)
if (ret < 0) {
dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n",
tspi->irq);
goto exit_free_master;
}

tspi->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(tspi->clk)) {
dev_err(&pdev->dev, "can not get clock\n");
ret = PTR_ERR(tspi->clk);
goto exit_free_irq;
goto exit_clk_disable;
}

tspi->rst = devm_reset_control_get_exclusive(&pdev->dev, "spi");
Expand Down Expand Up @@ -1138,6 +1149,8 @@ static int tegra_slink_probe(struct platform_device *pdev)
tegra_slink_deinit_dma_param(tspi, true);
exit_free_irq:
free_irq(spi_irq, tspi);
exit_clk_disable:
clk_disable(tspi->clk);
exit_free_master:
spi_master_put(master);
return ret;
Expand All @@ -1150,6 +1163,8 @@ static int tegra_slink_remove(struct platform_device *pdev)

free_irq(tspi->irq, tspi);

clk_disable(tspi->clk);

if (tspi->tx_dma_chan)
tegra_slink_deinit_dma_param(tspi, false);

Expand Down
7 changes: 4 additions & 3 deletions include/linux/spi/spi-mem.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,10 @@ enum spi_mem_data_dir {
* @dummy.buswidth: number of IO lanes used to transmit the dummy bytes
* @data.buswidth: number of IO lanes used to send/receive the data
* @data.dir: direction of the transfer
* @data.buf.in: input buffer
* @data.buf.out: output buffer
* @data.nbytes: number of data bytes to send/receive. Can be zero if the
* operation does not involve transferring data
* @data.buf.in: input buffer (must be DMA-able)
* @data.buf.out: output buffer (must be DMA-able)
*/
struct spi_mem_op {
struct {
Expand All @@ -105,7 +107,6 @@ struct spi_mem_op {
u8 buswidth;
enum spi_mem_data_dir dir;
unsigned int nbytes;
/* buf.{in,out} must be DMA-able. */
union {
void *in;
const void *out;
Expand Down

0 comments on commit 2f19e7a

Please sign in to comment.