diff options
-rw-r--r-- | drivers/spi/spi-cadence-quadspi.c | 42 | ||||
-rw-r--r-- | drivers/spi/spi-tegra20-slink.c | 2 | ||||
-rw-r--r-- | drivers/spi/spidev.c | 24 |
3 files changed, 44 insertions, 24 deletions
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index b50db71ac4cc..4828da4587c5 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -116,6 +116,9 @@ struct cqspi_driver_platdata { #define CQSPI_TIMEOUT_MS 500 #define CQSPI_READ_TIMEOUT_MS 10 +/* Runtime_pm autosuspend delay */ +#define CQSPI_AUTOSUSPEND_TIMEOUT 2000 + #define CQSPI_DUMMY_CLKS_PER_BYTE 8 #define CQSPI_DUMMY_BYTES_MAX 4 #define CQSPI_DUMMY_CLKS_MAX 31 @@ -1407,8 +1410,20 @@ static int cqspi_mem_process(struct spi_mem *mem, const struct spi_mem_op *op) static int cqspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) { int ret; + struct cqspi_st *cqspi = spi_master_get_devdata(mem->spi->master); + struct device *dev = &cqspi->pdev->dev; + + ret = pm_runtime_resume_and_get(dev); + if (ret) { + dev_err(&mem->spi->dev, "resume failed with %d\n", ret); + return ret; + } ret = cqspi_mem_process(mem, op); + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + if (ret) dev_err(&mem->spi->dev, "operation failed with %d\n", ret); @@ -1753,10 +1768,10 @@ static int cqspi_probe(struct platform_device *pdev) if (irq < 0) return -ENXIO; - pm_runtime_enable(dev); - ret = pm_runtime_resume_and_get(dev); - if (ret < 0) - goto probe_pm_failed; + ret = pm_runtime_set_active(dev); + if (ret) + return ret; + ret = clk_prepare_enable(cqspi->clk); if (ret) { @@ -1862,21 +1877,29 @@ static int cqspi_probe(struct platform_device *pdev) goto probe_setup_failed; } + ret = devm_pm_runtime_enable(dev); + if (ret) + return ret; + + pm_runtime_set_autosuspend_delay(dev, CQSPI_AUTOSUSPEND_TIMEOUT); + pm_runtime_use_autosuspend(dev); + pm_runtime_get_noresume(dev); + ret = spi_register_controller(host); if (ret) { dev_err(&pdev->dev, "failed to register SPI ctlr %d\n", ret); goto probe_setup_failed; } + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + return 0; probe_setup_failed: cqspi_controller_enable(cqspi, 0); probe_reset_failed: clk_disable_unprepare(cqspi->clk); probe_clk_failed: - pm_runtime_put_sync(dev); -probe_pm_failed: - pm_runtime_disable(dev); return ret; } @@ -1928,7 +1951,8 @@ static int cqspi_resume(struct device *dev) return spi_controller_resume(host); } -static DEFINE_SIMPLE_DEV_PM_OPS(cqspi_dev_pm_ops, cqspi_suspend, cqspi_resume); +static DEFINE_RUNTIME_DEV_PM_OPS(cqspi_dev_pm_ops, cqspi_suspend, + cqspi_resume, NULL); static const struct cqspi_driver_platdata cdns_qspi = { .quirks = CQSPI_DISABLE_DAC_MODE, @@ -2012,7 +2036,7 @@ static struct platform_driver cqspi_platform_driver = { .remove_new = cqspi_remove, .driver = { .name = CQSPI_NAME, - .pm = &cqspi_dev_pm_ops, + .pm = pm_ptr(&cqspi_dev_pm_ops), .of_match_table = cqspi_dt_ids, }, }; diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index 4d6db6182c5e..f5cd365c913a 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c @@ -1086,6 +1086,8 @@ static int tegra_slink_probe(struct platform_device *pdev) reset_control_deassert(tspi->rst); spi_irq = platform_get_irq(pdev, 0); + if (spi_irq < 0) + return spi_irq; tspi->irq = spi_irq; ret = request_threaded_irq(tspi->irq, tegra_slink_isr, tegra_slink_isr_thread, IRQF_ONESHOT, diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index d13dc15cc191..c5450217528b 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -357,6 +357,7 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) int retval = 0; struct spidev_data *spidev; struct spi_device *spi; + struct spi_controller *ctlr; u32 tmp; unsigned n_ioc; struct spi_ioc_transfer *ioc; @@ -376,6 +377,8 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return -ESHUTDOWN; } + ctlr = spi->controller; + /* use the buffer lock here for triple duty: * - prevent I/O (from us) so calling spi_setup() is safe; * - prevent concurrent SPI_IOC_WR_* from morphing @@ -388,22 +391,15 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) /* read requests */ case SPI_IOC_RD_MODE: case SPI_IOC_RD_MODE32: - tmp = spi->mode; - - { - struct spi_controller *ctlr = spi->controller; + tmp = spi->mode & SPI_MODE_MASK; - if (ctlr->use_gpio_descriptors && ctlr->cs_gpiods && - ctlr->cs_gpiods[spi_get_chipselect(spi, 0)]) - tmp &= ~SPI_CS_HIGH; - } + if (ctlr->use_gpio_descriptors && spi_get_csgpiod(spi, 0)) + tmp &= ~SPI_CS_HIGH; if (cmd == SPI_IOC_RD_MODE) - retval = put_user(tmp & SPI_MODE_MASK, - (__u8 __user *)arg); + retval = put_user(tmp, (__u8 __user *)arg); else - retval = put_user(tmp & SPI_MODE_MASK, - (__u32 __user *)arg); + retval = put_user(tmp, (__u32 __user *)arg); break; case SPI_IOC_RD_LSB_FIRST: retval = put_user((spi->mode & SPI_LSB_FIRST) ? 1 : 0, @@ -424,7 +420,6 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) else retval = get_user(tmp, (u32 __user *)arg); if (retval == 0) { - struct spi_controller *ctlr = spi->controller; u32 save = spi->mode; if (tmp & ~SPI_MODE_MASK) { @@ -432,8 +427,7 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) break; } - if (ctlr->use_gpio_descriptors && ctlr->cs_gpiods && - ctlr->cs_gpiods[spi_get_chipselect(spi, 0)]) + if (ctlr->use_gpio_descriptors && spi_get_csgpiod(spi, 0)) tmp |= SPI_CS_HIGH; tmp |= spi->mode & ~SPI_MODE_MASK; |