]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
greybus: spi: Add runtime_pm support
authorAxel Haslam <ahaslam@baylibre.com>
Thu, 14 Jul 2016 20:13:00 +0000 (15:13 -0500)
committerAlex Elder <elder@linaro.org>
Thu, 14 Jul 2016 21:53:55 +0000 (16:53 -0500)
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>
drivers/staging/greybus/kernel_ver.h
drivers/staging/greybus/spi.c
drivers/staging/greybus/spilib.c

index 84beb2f6334cd88ed729673ab0e43c5b934164cd..24d5bcd2e0ff8f5e6421ad54fdb7145c533584d5 100644 (file)
@@ -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
index a82337931c0d25af19fa4da98ae2a17da8510093..2e6e328bae9e14967ca83914dab2c8e375c8f383 100644 (file)
@@ -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 @@ static int gb_spi_probe(struct gbphy_device *gbphy_dev,
 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);
index 527909b26d79ac22a77d9546862cda755270da5d..e4c82e0a322b739a133e33e7ce597d22623c85c4 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "greybus.h"
 #include "spilib.h"
+#include "gbphy.h"
 
 struct gb_spilib {
        struct gb_connection    *connection;
@@ -372,6 +373,26 @@ static int gb_spi_transfer_one_message(struct spi_master *master,
        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;