diff options
author | Amelie Delaunay <amelie.delaunay@st.com> | 2017-06-27 11:45:18 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2017-06-28 15:00:54 -0400 |
commit | 038ac869c9d27fceb6197e775d780ad6aeb45b1f (patch) | |
tree | 934b1e41f40bbbcaa1c5393dcd55a318fb1fcfeb | |
parent | 128ebb89c50e5452704de82d78845baeb3333c24 (diff) |
spi: stm32: add runtime PM support
This patch reworks suspend and resume callbacks and add runtime_suspend
and runtime_resume callbacks.
Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | drivers/spi/spi-stm32.c | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c index 123529a1b40d..392c9453c2e6 100644 --- a/drivers/spi/spi-stm32.c +++ b/drivers/spi/spi-stm32.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/iopoll.h> | 27 | #include <linux/iopoll.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/of_platform.h> | 29 | #include <linux/of_platform.h> |
30 | #include <linux/pm_runtime.h> | ||
30 | #include <linux/reset.h> | 31 | #include <linux/reset.h> |
31 | #include <linux/spi/spi.h> | 32 | #include <linux/spi/spi.h> |
32 | 33 | ||
@@ -1164,6 +1165,9 @@ static int stm32_spi_probe(struct platform_device *pdev) | |||
1164 | if (spi->dma_tx || spi->dma_rx) | 1165 | if (spi->dma_tx || spi->dma_rx) |
1165 | master->can_dma = stm32_spi_can_dma; | 1166 | master->can_dma = stm32_spi_can_dma; |
1166 | 1167 | ||
1168 | pm_runtime_set_active(&pdev->dev); | ||
1169 | pm_runtime_enable(&pdev->dev); | ||
1170 | |||
1167 | ret = devm_spi_register_master(&pdev->dev, master); | 1171 | ret = devm_spi_register_master(&pdev->dev, master); |
1168 | if (ret) { | 1172 | if (ret) { |
1169 | dev_err(&pdev->dev, "spi master registration failed: %d\n", | 1173 | dev_err(&pdev->dev, "spi master registration failed: %d\n", |
@@ -1203,6 +1207,8 @@ err_dma_release: | |||
1203 | dma_release_channel(spi->dma_tx); | 1207 | dma_release_channel(spi->dma_tx); |
1204 | if (spi->dma_rx) | 1208 | if (spi->dma_rx) |
1205 | dma_release_channel(spi->dma_rx); | 1209 | dma_release_channel(spi->dma_rx); |
1210 | |||
1211 | pm_runtime_disable(&pdev->dev); | ||
1206 | err_clk_disable: | 1212 | err_clk_disable: |
1207 | clk_disable_unprepare(spi->clk); | 1213 | clk_disable_unprepare(spi->clk); |
1208 | err_master_put: | 1214 | err_master_put: |
@@ -1225,23 +1231,42 @@ static int stm32_spi_remove(struct platform_device *pdev) | |||
1225 | 1231 | ||
1226 | clk_disable_unprepare(spi->clk); | 1232 | clk_disable_unprepare(spi->clk); |
1227 | 1233 | ||
1234 | pm_runtime_disable(&pdev->dev); | ||
1235 | |||
1228 | return 0; | 1236 | return 0; |
1229 | } | 1237 | } |
1230 | 1238 | ||
1239 | #ifdef CONFIG_PM | ||
1240 | static int stm32_spi_runtime_suspend(struct device *dev) | ||
1241 | { | ||
1242 | struct spi_master *master = dev_get_drvdata(dev); | ||
1243 | struct stm32_spi *spi = spi_master_get_devdata(master); | ||
1244 | |||
1245 | clk_disable_unprepare(spi->clk); | ||
1246 | |||
1247 | return 0; | ||
1248 | } | ||
1249 | |||
1250 | static int stm32_spi_runtime_resume(struct device *dev) | ||
1251 | { | ||
1252 | struct spi_master *master = dev_get_drvdata(dev); | ||
1253 | struct stm32_spi *spi = spi_master_get_devdata(master); | ||
1254 | |||
1255 | return clk_prepare_enable(spi->clk); | ||
1256 | } | ||
1257 | #endif | ||
1258 | |||
1231 | #ifdef CONFIG_PM_SLEEP | 1259 | #ifdef CONFIG_PM_SLEEP |
1232 | static int stm32_spi_suspend(struct device *dev) | 1260 | static int stm32_spi_suspend(struct device *dev) |
1233 | { | 1261 | { |
1234 | struct spi_master *master = dev_get_drvdata(dev); | 1262 | struct spi_master *master = dev_get_drvdata(dev); |
1235 | struct stm32_spi *spi = spi_master_get_devdata(master); | ||
1236 | int ret; | 1263 | int ret; |
1237 | 1264 | ||
1238 | ret = spi_master_suspend(master); | 1265 | ret = spi_master_suspend(master); |
1239 | if (ret) | 1266 | if (ret) |
1240 | return ret; | 1267 | return ret; |
1241 | 1268 | ||
1242 | clk_disable_unprepare(spi->clk); | 1269 | return pm_runtime_force_suspend(dev); |
1243 | |||
1244 | return ret; | ||
1245 | } | 1270 | } |
1246 | 1271 | ||
1247 | static int stm32_spi_resume(struct device *dev) | 1272 | static int stm32_spi_resume(struct device *dev) |
@@ -1250,9 +1275,10 @@ static int stm32_spi_resume(struct device *dev) | |||
1250 | struct stm32_spi *spi = spi_master_get_devdata(master); | 1275 | struct stm32_spi *spi = spi_master_get_devdata(master); |
1251 | int ret; | 1276 | int ret; |
1252 | 1277 | ||
1253 | ret = clk_prepare_enable(spi->clk); | 1278 | ret = pm_runtime_force_resume(dev); |
1254 | if (ret) | 1279 | if (ret) |
1255 | return ret; | 1280 | return ret; |
1281 | |||
1256 | ret = spi_master_resume(master); | 1282 | ret = spi_master_resume(master); |
1257 | if (ret) | 1283 | if (ret) |
1258 | clk_disable_unprepare(spi->clk); | 1284 | clk_disable_unprepare(spi->clk); |
@@ -1261,8 +1287,11 @@ static int stm32_spi_resume(struct device *dev) | |||
1261 | } | 1287 | } |
1262 | #endif | 1288 | #endif |
1263 | 1289 | ||
1264 | static SIMPLE_DEV_PM_OPS(stm32_spi_pm_ops, | 1290 | static const struct dev_pm_ops stm32_spi_pm_ops = { |
1265 | stm32_spi_suspend, stm32_spi_resume); | 1291 | SET_SYSTEM_SLEEP_PM_OPS(stm32_spi_suspend, stm32_spi_resume) |
1292 | SET_RUNTIME_PM_OPS(stm32_spi_runtime_suspend, | ||
1293 | stm32_spi_runtime_resume, NULL) | ||
1294 | }; | ||
1266 | 1295 | ||
1267 | static struct platform_driver stm32_spi_driver = { | 1296 | static struct platform_driver stm32_spi_driver = { |
1268 | .probe = stm32_spi_probe, | 1297 | .probe = stm32_spi_probe, |