ARM: LPC32xx: Power management mem suspend/resume enhancements
authorKevin Wells <wellsk40@gmail.com>
Tue, 18 Jan 2011 19:06:48 +0000 (11:06 -0800)
committerKevin Wells <wellsk40@gmail.com>
Tue, 18 Jan 2011 19:06:48 +0000 (11:06 -0800)
Add a data cache flush prior to icache invalidation after moving the
system suspend image to IRAM. Move the allocation of the IRAM backup
buffer out of the suspend function to prevent possible blocking
issues with kmalloc().

arch/arm/mach-lpc32xx/pm.c

index ba1094a..733329b 100644 (file)
@@ -76,6 +76,8 @@
 #include "clock.h"
 
 #define TEMP_IRAM_AREA  IO_ADDRESS(LPC32XX_IRAM_BASE)
+static void *iram_swap_area;
+static int (*lpc32xx_suspend_ptr) (void);
 
 /*
  * Both STANDBY and MEM suspend states are handled the same with no
  */
 static int lpc32xx_pm_enter(suspend_state_t state)
 {
-       int (*lpc32xx_suspend_ptr) (void);
-       void *iram_swap_area;
-
-       /* Allocate some space for temporary IRAM storage */
-       iram_swap_area = kmalloc(lpc32xx_sys_suspend_sz, GFP_KERNEL);
-       if (!iram_swap_area) {
-               printk(KERN_ERR
-                      "PM Suspend: cannot allocate memory to save portion "
-                       "of SRAM\n");
-               return -ENOMEM;
-       }
-
        /* Backup a small area of IRAM used for the suspend code */
        memcpy(iram_swap_area, (void *) TEMP_IRAM_AREA,
                lpc32xx_sys_suspend_sz);
@@ -106,20 +96,17 @@ static int lpc32xx_pm_enter(suspend_state_t state)
         */
        memcpy((void *) TEMP_IRAM_AREA, &lpc32xx_sys_suspend,
                lpc32xx_sys_suspend_sz);
+       flush_cache_all();
        flush_icache_range((unsigned long)TEMP_IRAM_AREA,
                (unsigned long)(TEMP_IRAM_AREA) + lpc32xx_sys_suspend_sz);
 
        /* Transfer to suspend code in IRAM */
-       lpc32xx_suspend_ptr = (void *) TEMP_IRAM_AREA;
-       flush_cache_all();
        (void) lpc32xx_suspend_ptr();
 
        /* Restore original IRAM contents */
        memcpy((void *) TEMP_IRAM_AREA, iram_swap_area,
                lpc32xx_sys_suspend_sz);
 
-       kfree(iram_swap_area);
-
        return 0;
 }
 
@@ -139,6 +126,17 @@ static int __init lpc32xx_pm_init(void)
         */
        __raw_writel(__raw_readl(EMC_CTRL_REG) | EMC_SRMMC, EMC_CTRL_REG);
 
+       /* Allocate some space for temporary IRAM storage */
+       iram_swap_area = kmalloc(lpc32xx_sys_suspend_sz, GFP_KERNEL);
+       if (!iram_swap_area) {
+               printk(KERN_ERR
+                      "PM Suspend: cannot allocate memory to save portion "
+                       "of SRAM\n");
+               return -ENOMEM;
+       }
+
+       lpc32xx_suspend_ptr = (void *) TEMP_IRAM_AREA;
+
        suspend_set_ops(&lpc32xx_pm_ops);
 
        return 0;