#include "pmc.h"
 #include "apbio.h"
 #include "sleep.h"
+#include "pm.h"
 
 /*
  * Storage for debug-macro.S's state.
 static void __init tegra_init_cache(void)
 {
 #ifdef CONFIG_CACHE_L2X0
+       int ret;
        void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
        u32 aux_ctrl, cache_type;
 
        aux_ctrl = (cache_type & 0x700) << (17-8);
        aux_ctrl |= 0x7C400001;
 
-       l2x0_of_init(aux_ctrl, 0x8200c3fe);
+       ret = l2x0_of_init(aux_ctrl, 0x8200c3fe);
+       if (!ret)
+               l2x0_saved_regs_addr = virt_to_phys(&l2x0_saved_regs);
 #endif
 
 }
 
 #include <linux/init.h>
 
 #include <asm/cache.h>
+#include <asm/asm-offsets.h>
+#include <asm/hardware/cache-l2x0.h>
 
 #include "flowctrl.h"
 #include "iomap.h"
        str     r1, [r0]
 #endif
 
+       /* L2 cache resume & re-enable */
+       l2_cache_resume r0, r1, r2, l2x0_saved_regs_addr
+
        b       cpu_resume
 ENDPROC(tegra_resume)
 #endif
 
+#ifdef CONFIG_CACHE_L2X0
+       .globl  l2x0_saved_regs_addr
+l2x0_saved_regs_addr:
+       .long   0
+#endif
+
        .align L1_CACHE_SHIFT
 ENTRY(__tegra_cpu_reset_handler_start)
 
 
 #include <asm/assembler.h>
 #include <asm/cache.h>
 #include <asm/cp15.h>
+#include <asm/hardware/cache-l2x0.h>
 
 #include "iomap.h"
 
        dsb
        mcr     p15, 0, r3, c1, c0, 0
        isb
+#ifdef CONFIG_CACHE_L2X0
+       /* Disable L2 cache */
+       mov32   r4, TEGRA_ARM_PERIF_BASE + 0x3000
+       mov     r5, #0
+       str     r5, [r4, #L2X0_CTRL]
+#endif
        mov     pc, r0
 ENDPROC(tegra_shut_off_mmu)
        .popsection
 
        str     \tmp2, [\tmp1]                  @ invalidate SCU tags for CPU
        dsb
 .endm
+
+/* Macro to resume & re-enable L2 cache */
+#ifndef L2X0_CTRL_EN
+#define L2X0_CTRL_EN   1
+#endif
+
+#ifdef CONFIG_CACHE_L2X0
+.macro l2_cache_resume, tmp1, tmp2, tmp3, phys_l2x0_saved_regs
+       adr     \tmp1, \phys_l2x0_saved_regs
+       ldr     \tmp1, [\tmp1]
+       ldr     \tmp2, [\tmp1, #L2X0_R_PHY_BASE]
+       ldr     \tmp3, [\tmp2, #L2X0_CTRL]
+       tst     \tmp3, #L2X0_CTRL_EN
+       bne     exit_l2_resume
+       ldr     \tmp3, [\tmp1, #L2X0_R_TAG_LATENCY]
+       str     \tmp3, [\tmp2, #L2X0_TAG_LATENCY_CTRL]
+       ldr     \tmp3, [\tmp1, #L2X0_R_DATA_LATENCY]
+       str     \tmp3, [\tmp2, #L2X0_DATA_LATENCY_CTRL]
+       ldr     \tmp3, [\tmp1, #L2X0_R_PREFETCH_CTRL]
+       str     \tmp3, [\tmp2, #L2X0_PREFETCH_CTRL]
+       ldr     \tmp3, [\tmp1, #L2X0_R_PWR_CTRL]
+       str     \tmp3, [\tmp2, #L2X0_POWER_CTRL]
+       ldr     \tmp3, [\tmp1, #L2X0_R_AUX_CTRL]
+       str     \tmp3, [\tmp2, #L2X0_AUX_CTRL]
+       mov     \tmp3, #L2X0_CTRL_EN
+       str     \tmp3, [\tmp2, #L2X0_CTRL]
+exit_l2_resume:
+.endm
+#else /* CONFIG_CACHE_L2X0 */
+.macro l2_cache_resume, tmp1, tmp2, tmp3, phys_l2x0_saved_regs
+.endm
+#endif /* CONFIG_CACHE_L2X0 */
 #else
 void tegra_resume(void);
 int tegra_sleep_cpu_finish(unsigned long);