Currently the spi-sh-msiof driver implements a runtime PM scheme, based on
chipselect toggling. However, this is largely inefficient, since SPI
client drivers are allowed to keep the chipselect active for long periods
of time. This patch allows the driver to runtime-suspend the controller
between SPI transfers. While moving runtime-PM hooks this patch also 
removes manual PM clock manipulation.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
---

Marked as RFC, because I'm actually not sure, whether suspending after 
each transfer is actually allowed. This seems to bring problems with 
mmc-spi at least. Some commands return errors, but a retry recovers. More 
investigation is required. Any hints concerning why this is not perfectly 
functioning would be appreciated!

 drivers/spi/spi-sh-msiof.c |   30 +++++++++---------------------
 1 files changed, 9 insertions(+), 21 deletions(-)

diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
index 1f466bc..ece38c2 100644
--- a/drivers/spi/spi-sh-msiof.c
+++ b/drivers/spi/spi-sh-msiof.c
@@ -397,7 +397,6 @@ static int sh_msiof_spi_setup_transfer(struct spi_device 
*spi,
 
 static void sh_msiof_spi_chipselect(struct spi_device *spi, int is_on)
 {
-       struct sh_msiof_spi_priv *p = spi_master_get_devdata(spi->master);
        int value;
 
        /* chip select is active low unless SPI_CS_HIGH is set */
@@ -406,28 +405,8 @@ static void sh_msiof_spi_chipselect(struct spi_device 
*spi, int is_on)
        else
                value = (is_on == BITBANG_CS_ACTIVE) ? 0 : 1;
 
-       if (is_on == BITBANG_CS_ACTIVE) {
-               if (!test_and_set_bit(0, &p->flags)) {
-                       pm_runtime_get_sync(&p->pdev->dev);
-                       clk_enable(p->clk);
-               }
-
-               /* Configure pins before asserting CS */
-               sh_msiof_spi_set_pin_regs(p, !!(spi->mode & SPI_CPOL),
-                                         !!(spi->mode & SPI_CPHA),
-                                         !!(spi->mode & SPI_3WIRE),
-                                         !!(spi->mode & SPI_LSB_FIRST));
-       }
-
        /* use spi->controller data for CS (same strategy as spi_gpio) */
        gpio_set_value((unsigned)spi->controller_data, value);
-
-       if (is_on == BITBANG_CS_INACTIVE) {
-               if (test_and_clear_bit(0, &p->flags)) {
-                       clk_disable(p->clk);
-                       pm_runtime_put(&p->pdev->dev);
-               }
-       }
 }
 
 static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
@@ -560,6 +539,14 @@ static int sh_msiof_spi_txrx(struct spi_device *spi, 
struct spi_transfer *t)
                        rx_fifo = sh_msiof_spi_read_fifo_32;
        }
 
+       pm_runtime_get_sync(&p->pdev->dev);
+
+       /* Configure pins before asserting CS */
+       sh_msiof_spi_set_pin_regs(p, !!(spi->mode & SPI_CPOL),
+                                 !!(spi->mode & SPI_CPHA),
+                                 !!(spi->mode & SPI_3WIRE),
+                                 !!(spi->mode & SPI_LSB_FIRST));
+
        /* setup clocks (clock already enabled in chipselect()) */
        sh_msiof_spi_set_clk_regs(p, clk_get_rate(p->clk),
                                  sh_msiof_spi_hz(spi, t));
@@ -582,6 +569,7 @@ static int sh_msiof_spi_txrx(struct spi_device *spi, struct 
spi_transfer *t)
                words -= n;
        }
 
+       pm_runtime_put(&p->pdev->dev);
        return bytes_done;
 }
 
-- 
1.7.2.5


------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing 
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
spi-devel-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spi-devel-general

Reply via email to