These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / spi / spi-s3c64xx.c
index b1c6731..8e86e7f 100644 (file)
@@ -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);
@@ -1191,13 +1197,20 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
 
        dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d with %d Slaves attached\n",
                                        sdd->port_id, master->num_chipselect);
-       dev_dbg(&pdev->dev, "\tIOmem=[%pR]\tDMA=[Rx-%d, Tx-%d]\n",
-                                       mem_res,
+       dev_dbg(&pdev->dev, "\tIOmem=[%pR]\tFIFO %dbytes\tDMA=[Rx-%d, Tx-%d]\n",
+                                       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);
 
@@ -1347,7 +1363,7 @@ static struct s3c64xx_spi_port_config exynos7_spi_port_config = {
        .quirks         = S3C64XX_SPI_QUIRK_CS_AUTO,
 };
 
-static struct platform_device_id s3c64xx_spi_driver_ids[] = {
+static const struct platform_device_id s3c64xx_spi_driver_ids[] = {
        {
                .name           = "s3c2443-spi",
                .driver_data    = (kernel_ulong_t)&s3c2443_spi_port_config,