aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/spi/spi-cadence-quadspi.c42
-rw-r--r--drivers/spi/spi-tegra20-slink.c2
-rw-r--r--drivers/spi/spidev.c24
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;