电源管理

3733阅读 0评论2012-08-29 wibnmo
分类:LINUX

内核源码的帮助文档:
Documentation/power/
    freezing-of-tasks.txt    //关于休眠时如何把任务冻结,以及为什么要冻结,讲的很详细
  
关于[Documentation/power/freezing-of-tasks.txt 我们为什么要冻结]文档中的意思应该是这样的:
1. 在hibernation的时候,会创建一个hibernation image,等系统resume的时候会根据这个image恢复hibernation之前的状态.
   但是在创建hibernation image之后,有些进程有可能会修改on-disk data and metadata,这样的话,resume时,hibernation
   之前和之后的状态就不一致了.所以为了防止这种情况发生,引入了冻结机制,要做的工作就是把这些要修改on-disk data and metadata
   的进程冻结掉. 但这里有个问题,就是创建hibernation image之后系统是休眠了还是没休眠?如果休眠了,那所有进程也不再运行,disk
   上的数据也不会被破坏掉;或者是在创建hibernation image之后到系统休眠还有一小段时间,在这一小段时间内有可能还有进程在运行?

2. hibernation和suspend的区别是,前者挂起到磁盘,后者挂起到内存.在创建hibernation image时,需要大量内存,为了防止某些进程
   在hibernation时分配内存,我们需要把它们冻结掉.

3. 在SMP系统下,CPU0上我们要执行hibernation的操作,CPU1上还有一进程在运行,这时有可能会发生竞争条件,冻结在这时就起了作用,如果
   没有冻结,我们则需要一些保护机制防止竞争条件的发生.
 
android休眠/唤醒流程
此文介绍的很详细,不再赘述。
--------------------------------------------------------------------------------
唯一不同的是文章中介绍的是MTK相关的,下面简单说下高通平台休眠流程:
文件路径:
arch/arm/mach-msm/pm-8x60.c --> arch/arm/mach-msm/idle-v7.S
首先查看配置的休眠机制:
arch/arm/mach-msm/board-xxx.c
static struct msm_pm_platform_data msm_pm_data[MSM_PM_SLEEP_MODE_NR * 2] = {
    ...
};
  
static void __init msm8x60_init(struct msm_board_data *board_data)
{
    ...
    /* 在pm-8x60.c文件中会用到 msm_pm_data */
    msm_pm_set_platform_data(msm_pm_data, ARRAY_SIZE(msm_pm_data));
    ...
}
  
接着上面网址的分析,流程会走到 msm_pm_enter,在这个函数中会根据board中配置的休眠机制来调用不同的休眠流程。
根据目前的代码配置会调用到 msm_pm_swfi()-->msm_arch_idle()
--------------------------------------------------------------------------------
msm_arch_idle的实现在arch/arm/mach-msm/idle-v7.S中:
  
ENTRY(msm_arch_idle)
        stmfd   sp!, {lr}         //LR内容入栈,LR寄存器是Link Register,保存调用代码返回路径的指针
#ifdef CONFIG_MSM_JTAG_V7         //此宏未配置
        bl      msm_save_jtag_debug
#endif
#ifdef CONFIG_MSM_ETM             //这个宏配置了,会执行etm_save_reg_check
        bl      etm_save_reg_check
#endif
        wfi      //Wait For Interrupt 这句就是进入low power mode,设备走到这里不再运行,等待中断或reset来唤醒
#ifdef CONFIG_MSM_ETM
        bl      etm_restore_reg_check   //唤醒后会执行接下来的流程
#endif
#ifdef CONFIG_MSM_JTAG_V7
        bl      msm_restore_jtag_debug
#endif
        ldmfd   sp!, {lr}        //出栈
        bx      lr               //返回调用处继续执行
  
ETM:Embedded trace macrocell(可能是trace32,供跟踪调试用)
从上面代码可以看出,msm_arch_idle很简单,在进入wfi之前只保存了ETM相关的内容。
  
可以对比一下msm_pm_collapse,两种不同的休眠级别。
--------------------------------------------------------------------------------
ENTRY(msm_pm_collapse)
#if defined(CONFIG_MSM_FIQ_SUPPORT)
    cpsid   f
#endif
  
    ldr     r0, =saved_state
#if (NR_CPUS >= 2)
    mrc p15, 0, r1, c0, c0, 5   /* MPIDR */
    ands    r1, r1, #15     /* What CPU am I */
    addne   r0, r0, #CPU_SAVED_STATE_SIZE
#endif
  
    stmia   r0!, {r4-r14}
    mrc     p15, 0, r1, c1, c0, 0 /* MMU control */
    mrc     p15, 0, r2, c2, c0, 0 /* TTBR0 */
    mrc     p15, 0, r3, c3, c0, 0 /* dacr */
    mrc     p15, 3, r4, c15, c0, 3 /* L2CR1 is the L2 cache control reg 1 */
    mrc     p15, 0, r5, c10, c2, 0 /* PRRR */
    mrc     p15, 0, r6, c10, c2, 1 /* NMRR */
    mrc     p15, 0, r7, c1, c0, 1 /* ACTLR */
    mrc     p15, 0, r8, c2, c0, 1 /* TTBR1 */
    mrc     p15, 0, r9, c13, c0, 3 /* TPIDRURO */
    mrc     p15, 0, ip, c13, c0, 1 /* context ID */
    stmia   r0!, {r1-r9, ip}
#ifdef CONFIG_MSM_CPU_AVS
    mrc     p15, 7, r1, c15, c1, 7 /* AVSCSR is the Adaptive Voltage Scaling
                                    * Control and Status Register */
    mrc     p15, 7, r2, c15, c0, 6 /* AVSDSCR is the Adaptive Voltage
                                    * Scaling Delay Synthesizer Control
                    * Register */
    mrc     p15, 7, r3, c15, c1, 0 /* TSCSR is the Temperature Status and
                                    * Control Register
                    */
    stmia   r0!, {r1-r3}
#endif
  
#ifdef CONFIG_MSM_JTAG_V7
    bl      msm_save_jtag_debug
#endif
#ifdef CONFIG_MSM_ETM
    bl      etm_save_reg_check
#endif
    bl      v7_flush_dcache_all
  
    mrc     p15, 0, r1, c1, c0, 0    /* read current CR    */
    bic     r0, r1, #(1 << 2)        /* clear dcache bit   */
    bic     r0, r0, #(1 << 12)       /* clear icache bit   */
    mcr     p15, 0, r0, c1, c0, 0    /* disable d/i cache  */
  
    dsb
    wfi
  
    mcr     p15, 0, r1, c1, c0, 0    /* restore d/i cache  */
    isb
  
#if defined(CONFIG_MSM_FIQ_SUPPORT)
    cpsie   f
#endif
#ifdef CONFIG_MSM_ETM
    bl  etm_restore_reg_check
#endif
#ifdef CONFIG_MSM_JTAG_V7
    bl  msm_restore_jtag_debug
#endif
    ldr     r0, =saved_state        /* restore registers */
#if (NR_CPUS >= 2)
    mrc p15, 0, r1, c0, c0, 5   /* MPIDR */
    ands    r1, r1, #15     /* What CPU am I */
    addne   r0, r0, #CPU_SAVED_STATE_SIZE
#endif
  
    ldmfd   r0, {r4-r14}
    mov     r0, #0                   /* return power collapse failed */
    bx      lr
--------------------------------------------------------------------------------
高通的几个休眠级别:
Power modes supported
■ Running
■ Sleep
– Suspend power collapse for apps through SPM/RPM
– Idle power collapse for apps through SPM/RPM
– SWFI (only) – Apps execute SWFI instruction; no apps power collapse
 
1. Suspend power collapse for apps through SPM/RPM
   Apps suspend power collapse + modem PXO shutdown + off state for all
   hardware devices
2. Idle power collapse for apps through SPM/RPM
   Apps power collapse based on kernel timer event, driver interrupt latencies, etc.
   More frequent/faster than suspend power collapse
   All hardware devices may not be in Low Power mode
3. SWFI (only) – Apps execute SWFI instruction; no apps power collapse
   顾名思义,不用解释
上一篇:input子系统
下一篇:usb2uart 焊接方法