From 38853979e6dce8466a1f611cadebc0f00adb901b Mon Sep 17 00:00:00 2001 From: Dave Gerlach Date: Tue, 26 Jun 2018 10:05:17 -0700 Subject: 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 Signed-off-by: Keerthy Signed-off-by: Santosh Shilimkar --- drivers/memory/ti-emif-pm.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'drivers/memory') 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); -- cgit From 1662dd641f596e5517c7b7a23e4f8ddf36741b5f Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Sat, 26 May 2018 17:20:35 +0300 Subject: memory: tegra: Correct driver probe order The Reset Controller should be registered in the end of probe, otherwise Memory Controller device goes away if IRQ requesting fails and the Reset Controller stays registered. To avoid having to unwind the MC probing in a case of SMMU probe failure, let's simply print the error message without failing the MC probe. This allows us to just move the Reset Controller registering before the SMMU registration, reducing code churning. Also let's not fail MC probe in a case of Reset Controller registration failure as it doesn't prevent the MC driver to work. Signed-off-by: Dmitry Osipenko Signed-off-by: Thierry Reding --- drivers/memory/tegra/mc.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'drivers/memory') diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c index bb93cc53554e..bd25faf6d13d 100644 --- a/drivers/memory/tegra/mc.c +++ b/drivers/memory/tegra/mc.c @@ -672,13 +672,6 @@ static int tegra_mc_probe(struct platform_device *pdev) return err; } - err = tegra_mc_reset_setup(mc); - if (err < 0) { - dev_err(&pdev->dev, "failed to register reset controller: %d\n", - err); - return err; - } - mc->irq = platform_get_irq(pdev, 0); if (mc->irq < 0) { dev_err(&pdev->dev, "interrupt not specified\n"); @@ -697,13 +690,16 @@ static int tegra_mc_probe(struct platform_device *pdev) return err; } + err = tegra_mc_reset_setup(mc); + if (err < 0) + dev_err(&pdev->dev, "failed to register reset controller: %d\n", + err); + if (IS_ENABLED(CONFIG_TEGRA_IOMMU_SMMU)) { mc->smmu = tegra_smmu_probe(&pdev->dev, mc->soc->smmu, mc); - if (IS_ERR(mc->smmu)) { + if (IS_ERR(mc->smmu)) dev_err(&pdev->dev, "failed to probe SMMU: %ld\n", PTR_ERR(mc->smmu)); - return PTR_ERR(mc->smmu); - } } return 0; -- cgit