Merge remote-tracking branches 'spi/topic/omap-uwire', 'spi/topic/omap100k', 'spi...
[cascardo/linux.git] / drivers / spi / spi-pl022.c
index 2789b45..51d9977 100644 (file)
@@ -459,9 +459,8 @@ static void giveback(struct pl022 *pl022)
        struct spi_transfer *last_transfer;
        pl022->next_msg_cs_active = false;
 
-       last_transfer = list_entry(pl022->cur_msg->transfers.prev,
-                                       struct spi_transfer,
-                                       transfer_list);
+       last_transfer = list_last_entry(&pl022->cur_msg->transfers,
+                                       struct spi_transfer, transfer_list);
 
        /* Delay if requested before any change in chip select */
        if (last_transfer->delay_usecs)
@@ -2109,8 +2108,6 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
        pl022->chipselects = devm_kzalloc(dev, num_cs * sizeof(int),
                                          GFP_KERNEL);
 
-       pinctrl_pm_select_default_state(dev);
-
        /*
         * Bus Number Which has been Assigned to this SSP controller
         * on this board
@@ -2183,13 +2180,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
                goto err_no_clk;
        }
 
-       status = clk_prepare(pl022->clk);
-       if (status) {
-               dev_err(&adev->dev, "could not prepare SSP/SPI bus clock\n");
-               goto  err_clk_prep;
-       }
-
-       status = clk_enable(pl022->clk);
+       status = clk_prepare_enable(pl022->clk);
        if (status) {
                dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n");
                goto err_no_clk_en;
@@ -2250,10 +2241,8 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
        if (platform_info->enable_dma)
                pl022_dma_remove(pl022);
  err_no_irq:
-       clk_disable(pl022->clk);
+       clk_disable_unprepare(pl022->clk);
  err_no_clk_en:
-       clk_unprepare(pl022->clk);
- err_clk_prep:
  err_no_clk:
  err_no_ioremap:
        amba_release_regions(adev);
@@ -2281,42 +2270,13 @@ pl022_remove(struct amba_device *adev)
        if (pl022->master_info->enable_dma)
                pl022_dma_remove(pl022);
 
-       clk_disable(pl022->clk);
-       clk_unprepare(pl022->clk);
+       clk_disable_unprepare(pl022->clk);
        amba_release_regions(adev);
        tasklet_disable(&pl022->pump_transfers);
        return 0;
 }
 
-#if defined(CONFIG_SUSPEND) || defined(CONFIG_PM_RUNTIME)
-/*
- * These two functions are used from both suspend/resume and
- * the runtime counterparts to handle external resources like
- * clocks, pins and regulators when going to sleep.
- */
-static void pl022_suspend_resources(struct pl022 *pl022, bool runtime)
-{
-       clk_disable(pl022->clk);
-
-       if (runtime)
-               pinctrl_pm_select_idle_state(&pl022->adev->dev);
-       else
-               pinctrl_pm_select_sleep_state(&pl022->adev->dev);
-}
-
-static void pl022_resume_resources(struct pl022 *pl022, bool runtime)
-{
-       /* First go to the default state */
-       pinctrl_pm_select_default_state(&pl022->adev->dev);
-       if (!runtime)
-               /* Then let's idle the pins until the next transfer happens */
-               pinctrl_pm_select_idle_state(&pl022->adev->dev);
-
-       clk_enable(pl022->clk);
-}
-#endif
-
-#ifdef CONFIG_SUSPEND
+#ifdef CONFIG_PM_SLEEP
 static int pl022_suspend(struct device *dev)
 {
        struct pl022 *pl022 = dev_get_drvdata(dev);
@@ -2328,8 +2288,13 @@ static int pl022_suspend(struct device *dev)
                return ret;
        }
 
-       pm_runtime_get_sync(dev);
-       pl022_suspend_resources(pl022, false);
+       ret = pm_runtime_force_suspend(dev);
+       if (ret) {
+               spi_master_resume(pl022->master);
+               return ret;
+       }
+
+       pinctrl_pm_select_sleep_state(dev);
 
        dev_dbg(dev, "suspended\n");
        return 0;
@@ -2340,8 +2305,9 @@ static int pl022_resume(struct device *dev)
        struct pl022 *pl022 = dev_get_drvdata(dev);
        int ret;
 
-       pl022_resume_resources(pl022, false);
-       pm_runtime_put(dev);
+       ret = pm_runtime_force_resume(dev);
+       if (ret)
+               dev_err(dev, "problem resuming\n");
 
        /* Start the queue running */
        ret = spi_master_resume(pl022->master);
@@ -2352,14 +2318,16 @@ static int pl022_resume(struct device *dev)
 
        return ret;
 }
-#endif /* CONFIG_PM */
+#endif
 
-#ifdef CONFIG_PM_RUNTIME
+#ifdef CONFIG_PM
 static int pl022_runtime_suspend(struct device *dev)
 {
        struct pl022 *pl022 = dev_get_drvdata(dev);
 
-       pl022_suspend_resources(pl022, true);
+       clk_disable_unprepare(pl022->clk);
+       pinctrl_pm_select_idle_state(dev);
+
        return 0;
 }
 
@@ -2367,14 +2335,16 @@ static int pl022_runtime_resume(struct device *dev)
 {
        struct pl022 *pl022 = dev_get_drvdata(dev);
 
-       pl022_resume_resources(pl022, true);
+       pinctrl_pm_select_default_state(dev);
+       clk_prepare_enable(pl022->clk);
+
        return 0;
 }
 #endif
 
 static const struct dev_pm_ops pl022_dev_pm_ops = {
        SET_SYSTEM_SLEEP_PM_OPS(pl022_suspend, pl022_resume)
-       SET_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL)
+       SET_PM_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL)
 };
 
 static struct vendor_data vendor_arm = {