summaryrefslogtreecommitdiff
path: root/drivers/spi/spi-sifive.c
diff options
context:
space:
mode:
authorAndy Chiu <andy.chiu@sifive.com>2022-06-10 10:44:59 +0300
committerMark Brown <broonie@kernel.org>2022-06-10 15:32:24 +0300
commita1f0161eadbd7941c09b5f4c6a210c390d2b86d6 (patch)
tree338da232914da9820c2365e443cc6f9f70a23146 /drivers/spi/spi-sifive.c
parent0356163e5883e298b518cd16517be633824987f9 (diff)
downloadlinux-a1f0161eadbd7941c09b5f4c6a210c390d2b86d6.tar.xz
spi: sifive: add PM callbacks to support suspend/resume
The patch has been tested on Unmatched using pm_test. The Unmatched board uses SD over SPI and it was tested by initiating S2RAM cycles for all devices while reading/writing files at the same time. We found no dropped connection to the card or corrupted filesystem during test cycles. Signed-off-by: Andy Chiu <andy.chiu@sifive.com> Reviewed-by: Greentime Hu <greentime.hu@sifive.com> Link: https://lore.kernel.org/r/20220610074459.3261383-2-andy.chiu@sifive.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi/spi-sifive.c')
-rw-r--r--drivers/spi/spi-sifive.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/spi/spi-sifive.c b/drivers/spi/spi-sifive.c
index f7c1e20432e0..e29e85cee88a 100644
--- a/drivers/spi/spi-sifive.c
+++ b/drivers/spi/spi-sifive.c
@@ -427,6 +427,44 @@ static int sifive_spi_remove(struct platform_device *pdev)
return 0;
}
+static int sifive_spi_suspend(struct device *dev)
+{
+ struct spi_master *master = dev_get_drvdata(dev);
+ struct sifive_spi *spi = spi_master_get_devdata(master);
+ int ret;
+
+ ret = spi_master_suspend(master);
+ if (ret)
+ return ret;
+
+ /* Disable all the interrupts just in case */
+ sifive_spi_write(spi, SIFIVE_SPI_REG_IE, 0);
+
+ clk_disable_unprepare(spi->clk);
+
+ return ret;
+}
+
+static int sifive_spi_resume(struct device *dev)
+{
+ struct spi_master *master = dev_get_drvdata(dev);
+ struct sifive_spi *spi = spi_master_get_devdata(master);
+ int ret;
+
+ ret = clk_prepare_enable(spi->clk);
+ if (ret)
+ return ret;
+ ret = spi_master_resume(master);
+ if (ret)
+ clk_disable_unprepare(spi->clk);
+
+ return ret;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(sifive_spi_pm_ops,
+ sifive_spi_suspend, sifive_spi_resume);
+
+
static const struct of_device_id sifive_spi_of_match[] = {
{ .compatible = "sifive,spi0", },
{}
@@ -438,6 +476,7 @@ static struct platform_driver sifive_spi_driver = {
.remove = sifive_spi_remove,
.driver = {
.name = SIFIVE_SPI_DRIVER_NAME,
+ .pm = &sifive_spi_pm_ops,
.of_match_table = sifive_spi_of_match,
},
};