summaryrefslogtreecommitdiff
path: root/drivers/spi/spi-s3c64xx.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-11-05 21:15:12 (GMT)
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-05 21:15:12 (GMT)
commit75f5db39ff14ed95056f2cca3ad98c3cae97170c (patch)
treef265bdbda7dc9fab1bc07bca2449f9fc79c99f25 /drivers/spi/spi-s3c64xx.c
parent52787e91bf5375e68e90f381bd157bd92e1f4a77 (diff)
parentc70efb85153162295dc80099e95dab93d486a3ed (diff)
downloadlinux-75f5db39ff14ed95056f2cca3ad98c3cae97170c.tar.xz
Merge tag 'spi-v4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi updates from Mark Brown: "Quite a lot of activity in SPI this cycle, almost all of it in drivers with a few minor improvements and tweaks in the core. - Updates to pxa2xx to support Intel Broxton and multiple chip selects. - Support for big endian in the bcm63xx driver. - Multiple slave support for the mt8173 - New driver for the auxiliary SPI controller in bcm2835 SoCs. - Support for Layerscale SoCs in the Freescale DSPI driver" * tag 'spi-v4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (87 commits) spi: pxa2xx: Rework self-initiated platform data creation for non-ACPI spi: pxa2xx: Add support for Intel Broxton spi: pxa2xx: Detect number of enabled Intel LPSS SPI chip select signals spi: pxa2xx: Add output control for multiple Intel LPSS chip selects spi: pxa2xx: Use LPSS prefix for defines that are Intel LPSS specific spi: Add DSPI support for layerscape family spi: ti-qspi: improve ->remove() callback spi/spi-xilinx: Fix race condition on last word read spi: Drop owner assignment from spi_drivers spi: Add THIS_MODULE to spi_driver in SPI core spi: Setup the master controller driver before setting the chipselect spi: dw: replace magic constant by DW_SPI_DR spi: mediatek: mt8173 spi multiple devices support spi: mediatek: handle controller_data in mtk_spi_setup spi: mediatek: remove mtk_spi_config spi: mediatek: Update document devicetree bindings to support multiple devices spi: fix kernel-doc warnings about missing return desc in spi.c spi: fix kernel-doc warnings about missing return desc in spi.h spi: pxa2xx: Align a few defines spi: pxa2xx: Save other reg_cs_ctrl bits when configuring chip select ...
Diffstat (limited to 'drivers/spi/spi-s3c64xx.c')
-rw-r--r--drivers/spi/spi-s3c64xx.c46
1 files changed, 31 insertions, 15 deletions
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index cd1cfac..8e86e7f 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -32,6 +32,7 @@
#define MAX_SPI_PORTS 6
#define S3C64XX_SPI_QUIRK_POLL (1 << 0)
#define S3C64XX_SPI_QUIRK_CS_AUTO (1 << 1)
+#define AUTOSUSPEND_TIMEOUT 2000
/* Registers and bit-fields */
@@ -682,7 +683,7 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
/* Only BPW and Speed may change across transfers */
bpw = xfer->bits_per_word;
- speed = xfer->speed_hz ? : spi->max_speed_hz;
+ speed = xfer->speed_hz;
if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) {
sdd->cur_bpw = bpw;
@@ -859,13 +860,15 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
}
}
- pm_runtime_put(&sdd->pdev->dev);
+ pm_runtime_mark_last_busy(&sdd->pdev->dev);
+ pm_runtime_put_autosuspend(&sdd->pdev->dev);
if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO))
writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
return 0;
setup_exit:
- pm_runtime_put(&sdd->pdev->dev);
+ pm_runtime_mark_last_busy(&sdd->pdev->dev);
+ pm_runtime_put_autosuspend(&sdd->pdev->dev);
/* setup() returns with device de-selected */
if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_CS_AUTO))
writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
@@ -1162,6 +1165,12 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
goto err2;
}
+ pm_runtime_set_autosuspend_delay(&pdev->dev, AUTOSUSPEND_TIMEOUT);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_set_active(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+
/* Setup Deufult Mode */
s3c64xx_spi_hwinit(sdd, sdd->port_id);
@@ -1180,9 +1189,6 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN,
sdd->regs + S3C64XX_SPI_INT_EN);
- pm_runtime_set_active(&pdev->dev);
- pm_runtime_enable(&pdev->dev);
-
ret = devm_spi_register_master(&pdev->dev, master);
if (ret != 0) {
dev_err(&pdev->dev, "cannot register SPI master: %d\n", ret);
@@ -1195,9 +1201,16 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
mem_res, (FIFO_LVL_MASK(sdd) >> 1) + 1,
sdd->rx_dma.dmach, sdd->tx_dma.dmach);
+ pm_runtime_mark_last_busy(&pdev->dev);
+ pm_runtime_put_autosuspend(&pdev->dev);
+
return 0;
err3:
+ pm_runtime_put_noidle(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
+
clk_disable_unprepare(sdd->src_clk);
err2:
clk_disable_unprepare(sdd->clk);
@@ -1212,7 +1225,7 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
- pm_runtime_disable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
writel(0, sdd->regs + S3C64XX_SPI_INT_EN);
@@ -1220,6 +1233,10 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
clk_disable_unprepare(sdd->clk);
+ pm_runtime_put_noidle(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
+
return 0;
}
@@ -1233,10 +1250,9 @@ static int s3c64xx_spi_suspend(struct device *dev)
if (ret)
return ret;
- if (!pm_runtime_suspended(dev)) {
- clk_disable_unprepare(sdd->clk);
- clk_disable_unprepare(sdd->src_clk);
- }
+ ret = pm_runtime_force_suspend(dev);
+ if (ret < 0)
+ return ret;
sdd->cur_speed = 0; /* Output Clock is stopped */
@@ -1248,14 +1264,14 @@ static int s3c64xx_spi_resume(struct device *dev)
struct spi_master *master = dev_get_drvdata(dev);
struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
+ int ret;
if (sci->cfg_gpio)
sci->cfg_gpio();
- if (!pm_runtime_suspended(dev)) {
- clk_prepare_enable(sdd->src_clk);
- clk_prepare_enable(sdd->clk);
- }
+ ret = pm_runtime_force_resume(dev);
+ if (ret < 0)
+ return ret;
s3c64xx_spi_hwinit(sdd, sdd->port_id);