summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAxel Haslam <ahaslam@baylibre.com>2016-07-14 15:13:00 -0500
committerAlex Elder <elder@linaro.org>2016-07-14 16:53:55 -0500
commit4c615dcc6a9d910f8f68e4b57889b628e80165d4 (patch)
tree539525646534ef8b25c78c6a47477e66288b539c
parentafa807b8ba23952b471abb70716076bb3c98657c (diff)
downloadop-kernel-dev-4c615dcc6a9d910f8f68e4b57889b628e80165d4.zip
op-kernel-dev-4c615dcc6a9d910f8f68e4b57889b628e80165d4.tar.gz
greybus: spi: Add runtime_pm support
Add runtime operations to the spi driver so that the module is woken up when an spi transfer is started and put back to sleep when the transfer is done. Testing Done: Let the module enter standby and initiate an spi operation. The operation wakes up the module and succeeds. Signed-off-by: Axel Haslam <ahaslam@baylibre.com> Signed-off-by: David Lin <dtwlin@google.com> Reviewed-by: Rui Miguel Silva <rui.silva@linaro.org> Signed-off-by: Alex Elder <elder@linaro.org>
-rw-r--r--drivers/staging/greybus/kernel_ver.h5
-rw-r--r--drivers/staging/greybus/spi.c6
-rw-r--r--drivers/staging/greybus/spilib.c29
3 files changed, 40 insertions, 0 deletions
diff --git a/drivers/staging/greybus/kernel_ver.h b/drivers/staging/greybus/kernel_ver.h
index 84beb2f..24d5bcd 100644
--- a/drivers/staging/greybus/kernel_ver.h
+++ b/drivers/staging/greybus/kernel_ver.h
@@ -313,6 +313,11 @@ static inline bool led_sysfs_is_disabled(struct led_classdev *led_cdev)
#define SPI_NOR_MODALIAS "m25p80"
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)
+/* Starting from this version, the spi core handles runtime pm automatically */
+#define SPI_CORE_SUPPORT_PM
+#endif
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
/**
* reinit_completion - reinitialize a completion structure
diff --git a/drivers/staging/greybus/spi.c b/drivers/staging/greybus/spi.c
index a823379..2e6e328 100644
--- a/drivers/staging/greybus/spi.c
+++ b/drivers/staging/greybus/spi.c
@@ -35,6 +35,7 @@ static int gb_spi_probe(struct gbphy_device *gbphy_dev,
gb_gbphy_set_data(gbphy_dev, connection);
+ gbphy_runtime_put_autosuspend(gbphy_dev);
return 0;
exit_connection_disable:
@@ -48,6 +49,11 @@ exit_connection_destroy:
static void gb_spi_remove(struct gbphy_device *gbphy_dev)
{
struct gb_connection *connection = gb_gbphy_get_data(gbphy_dev);
+ int ret;
+
+ ret = gbphy_runtime_get_sync(gbphy_dev);
+ if (ret)
+ gbphy_runtime_get_noresume(gbphy_dev);
gb_spilib_master_exit(connection);
gb_connection_disable(connection);
diff --git a/drivers/staging/greybus/spilib.c b/drivers/staging/greybus/spilib.c
index 527909b..e4c82e0 100644
--- a/drivers/staging/greybus/spilib.c
+++ b/drivers/staging/greybus/spilib.c
@@ -15,6 +15,7 @@
#include "greybus.h"
#include "spilib.h"
+#include "gbphy.h"
struct gb_spilib {
struct gb_connection *connection;
@@ -372,6 +373,26 @@ out:
return ret;
}
+#ifndef SPI_CORE_SUPPORT_PM
+static int gb_spi_prepare_transfer_hardware(struct spi_master *master)
+{
+ struct gb_spilib *spi = spi_master_get_devdata(master);
+ struct gbphy_device *gbphy_dev = to_gbphy_dev(spi->parent);
+
+ return gbphy_runtime_get_sync(gbphy_dev);
+}
+
+static int gb_spi_unprepare_transfer_hardware(struct spi_master *master)
+{
+ struct gb_spilib *spi = spi_master_get_devdata(master);
+ struct gbphy_device *gbphy_dev = to_gbphy_dev(spi->parent);
+
+ gbphy_runtime_put_autosuspend(gbphy_dev);
+
+ return 0;
+}
+#endif
+
static int gb_spi_setup(struct spi_device *spi)
{
/* Nothing to do for now */
@@ -497,6 +518,14 @@ int gb_spilib_master_init(struct gb_connection *connection, struct device *dev)
master->setup = gb_spi_setup;
master->transfer_one_message = gb_spi_transfer_one_message;
+#ifndef SPI_CORE_SUPPORT_PM
+ master->prepare_transfer_hardware = gb_spi_prepare_transfer_hardware;
+ master->unprepare_transfer_hardware =
+ gb_spi_unprepare_transfer_hardware;
+#else
+ master->auto_runtime_pm = true;
+#endif
+
ret = spi_register_master(master);
if (ret < 0)
goto exit_spi_put;
OpenPOWER on IntegriCloud