summaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-pl022.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-pl022.c')
-rw-r--r--drivers/spi/spi-pl022.c80
1 files changed, 25 insertions, 55 deletions
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index 2789b452e711..51d99779682f 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -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 = {