spi: fsl-espi: add (un)prepare_transfer_hardware calls to save power if SPI is not...
authorHeiner Kallweit <hkallweit1@gmail.com>
Wed, 3 Dec 2014 06:56:19 +0000 (07:56 +0100)
committerMark Brown <broonie@kernel.org>
Wed, 3 Dec 2014 13:05:47 +0000 (13:05 +0000)
Use (un)prepare_transfer_hardware calls to set fsl-espi to
low-power idle if not in use. Reference manual states:

"The eSPI is in a idle state and consumes minimal power.
The eSPI BRG is not functioning and the input clock is disabled"

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-fsl-espi.c

index 90be6405e789130e408917798458e47b610c7f18..56cadf13519e55413a17fe2ea266f4865cb703db 100644 (file)
@@ -588,6 +588,38 @@ static void fsl_espi_remove(struct mpc8xxx_spi *mspi)
        iounmap(mspi->reg_base);
 }
 
+static int fsl_espi_suspend(struct spi_master *master)
+{
+       struct mpc8xxx_spi *mpc8xxx_spi;
+       struct fsl_espi_reg *reg_base;
+       u32 regval;
+
+       mpc8xxx_spi = spi_master_get_devdata(master);
+       reg_base = mpc8xxx_spi->reg_base;
+
+       regval = mpc8xxx_spi_read_reg(&reg_base->mode);
+       regval &= ~SPMODE_ENABLE;
+       mpc8xxx_spi_write_reg(&reg_base->mode, regval);
+
+       return 0;
+}
+
+static int fsl_espi_resume(struct spi_master *master)
+{
+       struct mpc8xxx_spi *mpc8xxx_spi;
+       struct fsl_espi_reg *reg_base;
+       u32 regval;
+
+       mpc8xxx_spi = spi_master_get_devdata(master);
+       reg_base = mpc8xxx_spi->reg_base;
+
+       regval = mpc8xxx_spi_read_reg(&reg_base->mode);
+       regval |= SPMODE_ENABLE;
+       mpc8xxx_spi_write_reg(&reg_base->mode, regval);
+
+       return 0;
+}
+
 static struct spi_master * fsl_espi_probe(struct device *dev,
                struct resource *mem, unsigned int irq)
 {
@@ -614,6 +646,8 @@ static struct spi_master * fsl_espi_probe(struct device *dev,
        master->setup = fsl_espi_setup;
        master->cleanup = fsl_espi_cleanup;
        master->transfer_one_message = fsl_espi_do_one_msg;
+       master->prepare_transfer_hardware = fsl_espi_resume;
+       master->unprepare_transfer_hardware = fsl_espi_suspend;
 
        mpc8xxx_spi = spi_master_get_devdata(master);
        mpc8xxx_spi->spi_remove = fsl_espi_remove;
@@ -761,25 +795,15 @@ static int of_fsl_espi_remove(struct platform_device *dev)
 static int of_fsl_espi_suspend(struct device *dev)
 {
        struct spi_master *master = dev_get_drvdata(dev);
-       struct mpc8xxx_spi *mpc8xxx_spi;
-       struct fsl_espi_reg *reg_base;
-       u32 regval;
        int ret;
 
-       mpc8xxx_spi = spi_master_get_devdata(master);
-       reg_base = mpc8xxx_spi->reg_base;
-
        ret = spi_master_suspend(master);
        if (ret) {
                dev_warn(dev, "cannot suspend master\n");
                return ret;
        }
 
-       regval = mpc8xxx_spi_read_reg(&reg_base->mode);
-       regval &= ~SPMODE_ENABLE;
-       mpc8xxx_spi_write_reg(&reg_base->mode, regval);
-
-       return 0;
+       return fsl_espi_suspend(master);
 }
 
 static int of_fsl_espi_resume(struct device *dev)