diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-04 11:34:06 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-04 11:34:06 -0700 |
commit | cfd12db4f12383506ca81fddd0f20921f166afd0 (patch) | |
tree | f67810e15bd956ac05bf5c96209c1cd4562ebe68 /drivers/spi/spi-omap2-mcspi.c | |
parent | 910470e03f343c48500a5619bb14bb8df51c3a72 (diff) | |
parent | 16c10b3bf84df5564683c704039f6199b8359b16 (diff) |
Merge tag 'spi-v4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi updates from Mark Brown:
"Quite a busy release for SPI, mainly as a result of Boris Brezillon's
work on improving the integration with MTD for accelerated SPI flash
controllers. He's added a new spi_mem interface which works a lot
better with general hardware and converted the users over to it, as a
result of this work we've got some MTD changes in here as well.
Other highlights include:
- Lots of spring cleaning for the s3c64xx driver.
- Removal of the bcm53xx, the hardware is also supported by the mspi
driver but SoC naming had caused people to miss the duplication.
- Conversion of the pxa2xx driver to use the standard message
processing loop rather than open coding.
- A bunch of improvements to the runtime PM of the OMAP McSPI driver"
* tag 'spi-v4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (47 commits)
spi: Fix typo on SPI_MEM help text
spi: sh-msiof: Fix setting SIRMDR1.SYNCAC to match SITMDR1.SYNCAC
mtd: devices: m25p80: Use spi_mem_set_drvdata() instead of spi_set_drvdata()
spi: omap2-mcspi: Remove unnecessary pm_runtime_force_suspend()
spi: Add missing pm_runtime_put_noidle() after failed get
spi: ti-qspi: Make sure res_mmap != NULL before dereferencing it
spi: spi-s3c64xx: Fix system resume support
spi: bcm-qspi: Fix build failure caused by spi_flash_read() API removal
spi: Get rid of the spi_flash_read() API
mtd: spi-nor: Use the spi_mem_xx() API
spi: ti-qspi: Implement the spi_mem interface
spi: bcm-qspi: Implement the spi_mem interface
spi: Make support for regular transfers optional when ->mem_ops != NULL
spi: Extend the core to ease integration of SPI memory controllers
spi: remove forgotten CONFIG_SPI_BCM53XX
spi: remove the older/duplicated bcm53xx driver
spi: pxa2xx: check clk_prepare_enable() return value
spi: lpspi: Switch to SPDX identifier
spi: mxs: Switch to SPDX identifier
spi: imx: Switch to SPDX identifier
...
Diffstat (limited to 'drivers/spi/spi-omap2-mcspi.c')
-rw-r--r-- | drivers/spi/spi-omap2-mcspi.c | 111 |
1 files changed, 56 insertions, 55 deletions
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 9bf64e6eca9b..6c628a54e946 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -255,6 +255,7 @@ static void omap2_mcspi_set_cs(struct spi_device *spi, bool enable) if (spi->controller_state) { int err = pm_runtime_get_sync(mcspi->dev); if (err < 0) { + pm_runtime_put_noidle(mcspi->dev); dev_err(mcspi->dev, "failed to get sync: %d\n", err); return; } @@ -350,20 +351,6 @@ disable_fifo: mcspi->fifo_depth = 0; } -static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi) -{ - struct spi_master *spi_cntrl = mcspi->master; - struct omap2_mcspi_regs *ctx = &mcspi->ctx; - struct omap2_mcspi_cs *cs; - - /* McSPI: context restore */ - mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL, ctx->modulctrl); - mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE, ctx->wakeupenable); - - list_for_each_entry(cs, &ctx->cs, node) - writel_relaxed(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); -} - static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit) { unsigned long timeout; @@ -1065,8 +1052,11 @@ static int omap2_mcspi_setup(struct spi_device *spi) } ret = pm_runtime_get_sync(mcspi->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_noidle(mcspi->dev); + return ret; + } ret = omap2_mcspi_setup_transfer(spi, NULL); pm_runtime_mark_last_busy(mcspi->dev); @@ -1284,8 +1274,11 @@ static int omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) int ret = 0; ret = pm_runtime_get_sync(mcspi->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_noidle(mcspi->dev); + return ret; + } mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, OMAP2_MCSPI_WAKEUPENABLE_WKEN); @@ -1297,14 +1290,39 @@ static int omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) return 0; } +/* + * When SPI wake up from off-mode, CS is in activate state. If it was in + * inactive state when driver was suspend, then force it to inactive state at + * wake up. + */ static int omap_mcspi_runtime_resume(struct device *dev) { - struct omap2_mcspi *mcspi; - struct spi_master *master; + struct spi_master *master = dev_get_drvdata(dev); + struct omap2_mcspi *mcspi = spi_master_get_devdata(master); + struct omap2_mcspi_regs *ctx = &mcspi->ctx; + struct omap2_mcspi_cs *cs; - master = dev_get_drvdata(dev); - mcspi = spi_master_get_devdata(master); - omap2_mcspi_restore_ctx(mcspi); + /* McSPI: context restore */ + mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, ctx->modulctrl); + mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, ctx->wakeupenable); + + list_for_each_entry(cs, &ctx->cs, node) { + /* + * We need to toggle CS state for OMAP take this + * change in account. + */ + if ((cs->chconf0 & OMAP2_MCSPI_CHCONF_FORCE) == 0) { + cs->chconf0 |= OMAP2_MCSPI_CHCONF_FORCE; + writel_relaxed(cs->chconf0, + cs->base + OMAP2_MCSPI_CHCONF0); + cs->chconf0 &= ~OMAP2_MCSPI_CHCONF_FORCE; + writel_relaxed(cs->chconf0, + cs->base + OMAP2_MCSPI_CHCONF0); + } else { + writel_relaxed(cs->chconf0, + cs->base + OMAP2_MCSPI_CHCONF0); + } + } return 0; } @@ -1447,50 +1465,33 @@ static int omap2_mcspi_remove(struct platform_device *pdev) MODULE_ALIAS("platform:omap2_mcspi"); #ifdef CONFIG_SUSPEND -/* - * When SPI wake up from off-mode, CS is in activate state. If it was in - * unactive state when driver was suspend, then force it to unactive state at - * wake up. - */ -static int omap2_mcspi_resume(struct device *dev) +static int omap2_mcspi_suspend_noirq(struct device *dev) { - struct spi_master *master = dev_get_drvdata(dev); - struct omap2_mcspi *mcspi = spi_master_get_devdata(master); - struct omap2_mcspi_regs *ctx = &mcspi->ctx; - struct omap2_mcspi_cs *cs; - - pm_runtime_get_sync(mcspi->dev); - list_for_each_entry(cs, &ctx->cs, node) { - if ((cs->chconf0 & OMAP2_MCSPI_CHCONF_FORCE) == 0) { - /* - * We need to toggle CS state for OMAP take this - * change in account. - */ - cs->chconf0 |= OMAP2_MCSPI_CHCONF_FORCE; - writel_relaxed(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); - cs->chconf0 &= ~OMAP2_MCSPI_CHCONF_FORCE; - writel_relaxed(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); - } - } - pm_runtime_mark_last_busy(mcspi->dev); - pm_runtime_put_autosuspend(mcspi->dev); - - return pinctrl_pm_select_default_state(dev); + return pinctrl_pm_select_sleep_state(dev); } -static int omap2_mcspi_suspend(struct device *dev) +static int omap2_mcspi_resume_noirq(struct device *dev) { - return pinctrl_pm_select_sleep_state(dev); + struct spi_master *master = dev_get_drvdata(dev); + struct omap2_mcspi *mcspi = spi_master_get_devdata(master); + int error; + + error = pinctrl_pm_select_default_state(dev); + if (error) + dev_warn(mcspi->dev, "%s: failed to set pins: %i\n", + __func__, error); + + return 0; } #else -#define omap2_mcspi_suspend NULL -#define omap2_mcspi_resume NULL +#define omap2_mcspi_suspend_noirq NULL +#define omap2_mcspi_resume_noirq NULL #endif static const struct dev_pm_ops omap2_mcspi_pm_ops = { - .resume = omap2_mcspi_resume, - .suspend = omap2_mcspi_suspend, + .suspend_noirq = omap2_mcspi_suspend_noirq, + .resume_noirq = omap2_mcspi_resume_noirq, .runtime_resume = omap_mcspi_runtime_resume, }; |