summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorPrashant Gaikwad <pgaikwad@nvidia.com>2011-08-03 14:41:14 +0530
committerVarun Colbert <vcolbert@nvidia.com>2011-08-19 15:40:36 -0700
commit315519d2c755f8ae206e12366eaa4a2a0cb626e7 (patch)
tree55e04364a2ff1a1da1d3b6fb7b7582a4abd46f9b /arch
parenteb1ec2fe1757c8952ef6c80c7b460dc27995a6f8 (diff)
arm: tegra: pm: Relocate lp0 vector
LP0 vector is allocated by BL and address is shared to kernel. For platform with memory less than 1GB it was allocated in the overlapping region of carveout memory. Because of it during AVP operation it gets corrupted, which prevents resume. Relocate AVP vector to some other location where overlapping will not occur. Bug 827199 Reviewed-on: http://git-master/r/42113 (cherry picked from commit 9a3993d39599d1637d7c04218e6a634f914e9f91) Change-Id: If862f6ff61a316c478806b7dc3deff70a2861410 Reviewed-on: http://git-master/r/44716 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-tegra/common.c7
-rw-r--r--arch/arm/mach-tegra/suspend.c30
2 files changed, 30 insertions, 7 deletions
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index 7918517b7156..bc43477ee1b2 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -645,13 +645,6 @@ void __init tegra_reserve(unsigned long carveout_size, unsigned long fb_size,
platform_get_resource_byname(&tegra_smmu_device,
IORESOURCE_MEM, "smmu");
#endif
- if (tegra_lp0_vec_size)
- if (memblock_reserve(tegra_lp0_vec_start, tegra_lp0_vec_size)) {
- pr_err("Failed to reserve lp0_vec %08lx@%08lx\n",
- tegra_lp0_vec_size, tegra_lp0_vec_start);
- tegra_lp0_vec_start = 0;
- tegra_lp0_vec_size = 0;
- }
if (carveout_size) {
tegra_carveout_start = memblock_end_of_DRAM() - carveout_size;
diff --git a/arch/arm/mach-tegra/suspend.c b/arch/arm/mach-tegra/suspend.c
index 957fb27099bb..0604dab04a1b 100644
--- a/arch/arm/mach-tegra/suspend.c
+++ b/arch/arm/mach-tegra/suspend.c
@@ -1182,7 +1182,37 @@ void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat)
pr_warning("Disabling LP0\n");
plat->suspend_mode = TEGRA_SUSPEND_LP1;
}
+ if (plat->suspend_mode == TEGRA_SUSPEND_LP0 && tegra_lp0_vec_size) {
+ unsigned char *reloc_lp0;
+ unsigned long tmp;
+ void __iomem *orig;
+ reloc_lp0 = kmalloc(tegra_lp0_vec_size + L1_CACHE_BYTES - 1,
+ GFP_KERNEL);
+ WARN_ON(!reloc_lp0);
+ if (!reloc_lp0) {
+ pr_err("%s: Failed to allocate reloc_lp0\n",
+ __func__);
+ goto out;
+ }
+
+ orig = ioremap(tegra_lp0_vec_start, tegra_lp0_vec_size);
+ WARN_ON(!orig);
+ if (!orig) {
+ pr_err("%s: Failed to map tegra_lp0_vec_start %08lx\n",
+ __func__, tegra_lp0_vec_start);
+ kfree(reloc_lp0);
+ goto out;
+ }
+
+ tmp = (unsigned long) reloc_lp0;
+ tmp = (tmp + L1_CACHE_BYTES - 1) & ~(L1_CACHE_BYTES - 1);
+ reloc_lp0 = (unsigned char *)tmp;
+ memcpy(reloc_lp0, orig, tegra_lp0_vec_size);
+ iounmap(orig);
+ tegra_lp0_vec_start = virt_to_phys(reloc_lp0);
+ }
+out:
if (plat->suspend_mode == TEGRA_SUSPEND_LP0) {
if (tegra_lp0_vec_size)
wb0_restore = tegra_lp0_vec_start;