summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDave Gerlach <d-gerlach@ti.com>2018-06-26 19:05:17 +0200
committerSantosh Shilimkar <santosh.shilimkar@oracle.com>2018-06-26 19:05:17 +0200
commit38853979e6dce8466a1f611cadebc0f00adb901b (patch)
tree4e760c4ad3ecc722ab87448128e55cf2008920a9 /drivers
parentLinux 4.18-rc1 (diff)
downloadlinux-38853979e6dce8466a1f611cadebc0f00adb901b.tar.xz
linux-38853979e6dce8466a1f611cadebc0f00adb901b.zip
memory: ti-emif-sram: Add resume function to recopy sram code
After an RTC+DDR cycle we lose sram context so emif pm functions present in sram are lost. We can check if the first byte of the original code in DDR contains the same first byte as the code in sram, and if they do not match we know we have lost context and must recopy the functions to the previous address to maintain PM functionality. Signed-off-by: Dave Gerlach <d-gerlach@ti.com> Signed-off-by: Keerthy <j-keerthy@ti.com> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/memory/ti-emif-pm.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/memory/ti-emif-pm.c b/drivers/memory/ti-emif-pm.c
index 632651f4b6e8..2250d03ea17f 100644
--- a/drivers/memory/ti-emif-pm.c
+++ b/drivers/memory/ti-emif-pm.c
@@ -249,6 +249,34 @@ static const struct of_device_id ti_emif_of_match[] = {
};
MODULE_DEVICE_TABLE(of, ti_emif_of_match);
+#ifdef CONFIG_PM_SLEEP
+static int ti_emif_resume(struct device *dev)
+{
+ unsigned long tmp =
+ __raw_readl((void *)emif_instance->ti_emif_sram_virt);
+
+ /*
+ * Check to see if what we are copying is already present in the
+ * first byte at the destination, only copy if it is not which
+ * indicates we have lost context and sram no longer contains
+ * the PM code
+ */
+ if (tmp != ti_emif_sram)
+ ti_emif_push_sram(dev, emif_instance);
+
+ return 0;
+}
+
+static int ti_emif_suspend(struct device *dev)
+{
+ /*
+ * The contents will be present in DDR hence no need to
+ * explicitly save
+ */
+ return 0;
+}
+#endif /* CONFIG_PM_SLEEP */
+
static int ti_emif_probe(struct platform_device *pdev)
{
int ret;
@@ -308,12 +336,17 @@ static int ti_emif_remove(struct platform_device *pdev)
return 0;
}
+static const struct dev_pm_ops ti_emif_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(ti_emif_suspend, ti_emif_resume)
+};
+
static struct platform_driver ti_emif_driver = {
.probe = ti_emif_probe,
.remove = ti_emif_remove,
.driver = {
.name = KBUILD_MODNAME,
.of_match_table = of_match_ptr(ti_emif_of_match),
+ .pm = &ti_emif_pm_ops,
},
};
module_platform_driver(ti_emif_driver);