diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 05ee05f012ad..8b5bf91dc070 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include <plat/control.h> | 29 | #include <plat/control.h> |
30 | #include <plat/serial.h> | 30 | #include <plat/serial.h> |
31 | 31 | ||
32 | #include <asm/tlbflush.h> | ||
33 | |||
32 | #include "cm.h" | 34 | #include "cm.h" |
33 | #include "cm-regbits-34xx.h" | 35 | #include "cm-regbits-34xx.h" |
34 | #include "prm-regbits-34xx.h" | 36 | #include "prm-regbits-34xx.h" |
@@ -164,6 +166,35 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) | |||
164 | return IRQ_HANDLED; | 166 | return IRQ_HANDLED; |
165 | } | 167 | } |
166 | 168 | ||
169 | static void restore_control_register(u32 val) | ||
170 | { | ||
171 | __asm__ __volatile__ ("mcr p15, 0, %0, c1, c0, 0" : : "r" (val)); | ||
172 | } | ||
173 | |||
174 | /* Function to restore the table entry that was modified for enabling MMU */ | ||
175 | static void restore_table_entry(void) | ||
176 | { | ||
177 | u32 *scratchpad_address; | ||
178 | u32 previous_value, control_reg_value; | ||
179 | u32 *address; | ||
180 | |||
181 | scratchpad_address = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD); | ||
182 | |||
183 | /* Get address of entry that was modified */ | ||
184 | address = (u32 *)__raw_readl(scratchpad_address + | ||
185 | OMAP343X_TABLE_ADDRESS_OFFSET); | ||
186 | /* Get the previous value which needs to be restored */ | ||
187 | previous_value = __raw_readl(scratchpad_address + | ||
188 | OMAP343X_TABLE_VALUE_OFFSET); | ||
189 | address = __va(address); | ||
190 | *address = previous_value; | ||
191 | flush_tlb_all(); | ||
192 | control_reg_value = __raw_readl(scratchpad_address | ||
193 | + OMAP343X_CONTROL_REG_VALUE_OFFSET); | ||
194 | /* This will enable caches and prediction */ | ||
195 | restore_control_register(control_reg_value); | ||
196 | } | ||
197 | |||
167 | static void omap_sram_idle(void) | 198 | static void omap_sram_idle(void) |
168 | { | 199 | { |
169 | /* Variable to tell what needs to be saved and restored | 200 | /* Variable to tell what needs to be saved and restored |
@@ -220,6 +251,10 @@ static void omap_sram_idle(void) | |||
220 | _omap_sram_idle(NULL, save_state); | 251 | _omap_sram_idle(NULL, save_state); |
221 | cpu_init(); | 252 | cpu_init(); |
222 | 253 | ||
254 | /* Restore table entry modified during MMU restoration */ | ||
255 | if (pwrdm_read_prev_pwrst(mpu_pwrdm) == PWRDM_POWER_OFF) | ||
256 | restore_table_entry(); | ||
257 | |||
223 | if (core_next_state < PWRDM_POWER_ON) { | 258 | if (core_next_state < PWRDM_POWER_ON) { |
224 | if (per_next_state < PWRDM_POWER_ON) | 259 | if (per_next_state < PWRDM_POWER_ON) |
225 | omap_uart_resume_idle(2); | 260 | omap_uart_resume_idle(2); |