blob: f3e7940d2994945b0b8394cf1be4beae2899c861 [file] [log] [blame]
developer8e45c532021-12-13 10:38:52 +08001drivers: spi: backport PM improvement for SPI framework
2
3Fix PM improvement for SPI framework.
4As to set_cs takes effect immediately, power spi
5is needed when setup spi.
6
7(cherry picked from commit d948e6ca189985495a21cd622c31e30e72b6b688)
8Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/spi/spi.c?h=v5.16-rc4&id=d948e6ca189985495a21cd622c31e30e72b6b688
9(cherry picked from commit 57a9460705f105e1d79d1410c5cfe285beda8986)
10Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/spi/spi.c?h=v5.16-rc4&id=57a9460705f105e1d79d1410c5cfe285beda8986
11
12--- a/drivers/spi/spi.c
13+++ b/drivers/spi/spi.c
14@@ -3170,7 +3170,29 @@ int spi_setup(struct spi_device *spi)
15 if (spi->controller->setup)
16 status = spi->controller->setup(spi);
17
18- spi_set_cs(spi, false);
19+ if (spi->controller->auto_runtime_pm && spi->controller->set_cs) {
20+ status = pm_runtime_get_sync(spi->controller->dev.parent);
21+ if (status < 0) {
22+ pm_runtime_put_noidle(spi->controller->dev.parent);
23+ dev_err(&spi->controller->dev, "Failed to power device: %d\n",
24+ status);
25+ return status;
26+ }
27+
28+ /*
29+ * We do not want to return positive value from pm_runtime_get,
30+ * there are many instances of devices calling spi_setup() and
31+ * checking for a non-zero return value instead of a negative
32+ * return value.
33+ */
34+ status = 0;
35+
36+ spi_set_cs(spi, false);
37+ pm_runtime_mark_last_busy(spi->controller->dev.parent);
38+ pm_runtime_put_autosuspend(spi->controller->dev.parent);
39+ } else {
40+ spi_set_cs(spi, false);
41+ }
42
43 if (spi->rt && !spi->controller->rt) {
44 spi->controller->rt = true;
45--
462.18.0
47