summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorJin Qian <jqian@nvidia.com>2011-08-22 21:29:48 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:48:39 -0800
commitf93887c0760e4530d3023b7682f2322ea312f3c5 (patch)
treec6becd8335961969a95198cc78203696de7dca1b /arch
parentffc9995037e8958a081d0c598e40813a9c7513fe (diff)
ARM: tegra: power: fix cpu context save page mapping
Change-Id: Ie2bcc74d4a4fb76ee29c4a01e5dae72261da4885 Reviewed-on: http://git-master/r/48623 Reviewed-by: Jin Qian <jqian@nvidia.com> Reviewed-by: Daniel Willemsen <dwillemsen@nvidia.com> Tested-by: Daniel Willemsen <dwillemsen@nvidia.com> Rebase-Id: R5ee134042966de7a620f60095169e3aba823cd82
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-tegra/pm.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index 8717b9bf14ec..688775531fe0 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -260,9 +260,10 @@ static __init int alloc_suspend_context(void)
pgprot_t prot = __pgprot_modify(pgprot_kernel, L_PTE_MT_MASK,
L_PTE_MT_BUFFERABLE | L_PTE_XN);
struct page *ctx_page;
- unsigned long ctx_virt;
- phys_addr_t ctx_phys;
+ unsigned long ctx_virt = 0;
+ pgd_t *pgd;
pmd_t *pmd;
+ pte_t *pte;
ctx_page = alloc_pages(GFP_KERNEL, 0);
if (IS_ERR_OR_NULL(ctx_page))
@@ -274,12 +275,19 @@ static __init int alloc_suspend_context(void)
/* Add the context page to our private pgd. */
ctx_virt = (unsigned long)tegra_cpu_context;
- ctx_phys = virt_to_phys(tegra_cpu_context);
- pmd = pmd_offset(tegra_pgd + pgd_index(ctx_virt), ctx_virt);
- *pmd = __pmd((ctx_phys & PGDIR_MASK) |
- PMD_TYPE_SECT | PMD_SECT_AP_WRITE |
- PMD_SECT_XN | PMD_SECT_BUFFERED);
- flush_pmd_entry(pmd);
+
+ pgd = tegra_pgd + pgd_index(ctx_virt);
+ if (!pgd_present(*pgd))
+ goto fail;
+ pmd = pmd_offset(pgd, ctx_virt);
+ if (!pmd_none(*pmd))
+ goto fail;
+ pte = pte_alloc_kernel(pmd, ctx_virt);
+ if (!pte)
+ goto fail;
+
+ set_pte_ext(pte, mk_pte(ctx_page, prot), 0);
+
outer_clean_range(__pa(pmd), __pa(pmd + 1));
return 0;
@@ -287,6 +295,8 @@ static __init int alloc_suspend_context(void)
fail:
if (ctx_page)
__free_page(ctx_page);
+ if (ctx_virt)
+ vm_unmap_ram((void*)ctx_virt, 1);
tegra_cpu_context = NULL;
return -ENOMEM;
#else