The summary of Android dormant wake process and location awakening problem

Source: Internet
Author: User
Tags goto prepare see definition

Platform Information:

Kernel: Linux 2.6.35

android:2.3.1

CPU: Samsung S5PV210

Speaking from the EARLYSUSPEND.C, suspend is invoked after all the driver early wake_unlock are executed in early suspend, and in the Wake_unlock function, if the system has no wake-up lock, The dormant work queue is scheduled, and the queue function suspend is executed.

See definition:static declare_work (Suspend_work, suspend);

Suspend is the function that starts the Linux hibernation.

The calling relationship is as follows:

static void suspend (struct work_struct *work)
--> int Pm_suspend (suspend_state_t State)
--> int enter_state (suspend_state_t State)

Do some preparatory work in this function:

Sync file System (Sys_sync);

Allocation of consoles and freezing of all processes (Suspend_prepare);

Then call the following function;[CPP] View Plain copy print? Int suspend_devices_and_enter (suspend_state_t state)     {     int  error;     gfp_t saved_mask;     /* Determines whether the action function collection pointer to hibernation is assigned This pointer is assigned in the corresponding platform Power management module      in the s5pv210 platform is in PLAT-SAMSUNG/PM.C */     if  (! Suspend_ops)         return -ENOSYS;     if  ( Suspend_ops->begin)  {      error = suspend_ops->begin (state);       if  (Error)        goto Close;     }     suspend_console ()//suspend console subsystem, at this time PRINTK can not print information, But there are other ways to print      saved_mask = clear_gfp_allowed_mask (gfp_iofs);     suspend_test_start ();     error = dpm_suspend_start (PMSG_SUSPEND);In this function, all suspend functions are tuned to the driver registration, and if you want to know the suspend      order, you can print it inside.      if  (Error)  {      PRINTK (kern_err  "pm:  some devices failed to suspend\n ");      goto recover_ platform;     }     suspend_test_finish ("suspend devices");      if  (Suspend_test (test_devices))       goto recover_platform ;        suspend_enter (state);  //in this function will call to the system's Hibernate function, the system into sleep mode, and the system will stay in       where to sleep, and continue to execute when awakened.         resume_devices: //When the system is awakened by an external interrupt, this will be performed to       Suspend_test_start ();     dpm_resume_end (pmsg_resume);//This function executes the resume process, calling all resume functions registered in the drive.      suspend_test_finish ("resume devices");     set_gfp_allowed_ Mask (sAved_mask);     resume_console ();     Close:     if   (suspend_ops->end)       suspend_ops->end ();     return  error;        Recover_platform:     if  (suspend_ops- >recover)       suspend_ops->recover ();     goto resume_ devices;    }       static struct platform_suspend_ops s3c _pm_ops = {     .enter  = s3c_pm_enter, //Operating system registers the interface, The inside will put the system into hibernation/wake state, in which the system will retain the value of the register, set a good external wake source. After performing the S3c_cpu_save system, it enters hibernation mode.       When the system is awakened, start execution from the S3c_cpu_save function below.      .prepare = s3c_pm_prepare,//to set up CRC checksum, allocate the memory that holds CRC value.      .finish  = s3c_pm_finish,     .valid  =  suspend_valid_only_mem,    };//This is the power management interface for the platform defined in s5pv210, suspend_ops pointer to this struct variable         Static int suspend_enter (suspend_state_t state)     {      int error;        if  (suspend_ops->prepare)  {      error = suspend_ops->prepare ();      if  (Error)        return error;     }        ERROR = DPM_SUSPEND_NOIRQ (pmsg_suspend);     if  (Error)  {       PRINTK (kern_err  "pm: some devices failed to power  down\n ");      goto Platfrom_finish;     }         if  (suspend_ops->prepare_late)  {      error =  suspend_ops->prepare_late ();      if  (Error)        goto  Power_up_devices;     }        if  (suspend_test test _platform))       goto Platform_wake;        error  = disable_nonboot_cpus ();     if  (error | |  suspend_test (Test_cpus))       goto Enable_cpus;         arch_suspend_disable_irqs ();     bug_on (!irqs_disabled ());         error = sysdev_suspend (pmsg_suspend);     if  (!error)  {      if  (!suspend_test (test_core))         Error = suspend_ops->enter (state);  //call this function to hibernate       sysdev_resume ();      }       arch_suspend_enable_irqs ();     bug_on (irqs_disabled ());         Enable_cpus:     enable_nonboot_cpus ();         Platform_wake:     if  (suspend_ops->wake)        suspend_ops->wake ();        Power_up_devices:     dpm_ RESUME_NOIRQ (pmsg_resume);        Platfrom_finish:     if  (suspend_ops->finish)       suspend_ops->finish ();        return error;    }  

int Suspend_devices_and_enter (suspend_state_t state) {int error;
  gfp_t Saved_mask;
  /* To determine whether the operation function set pointer of hibernation is assigned, this pointer will be assigned in the corresponding platform power management module in the S5PV210 platform in PLAT-SAMSUNG/PM.C/if (!suspend_ops) Return-enosys;
   if (suspend_ops->begin) {error = Suspend_ops->begin (state);
  if (error) goto close; Suspend_console ();//suspend console subsystem, PRINTK cannot print information at this time, but there are other ways to print Saved_mask = Clear_gfp_allowed_mask (
  GFP_IOFS);
  Suspend_test_start ();
  Error = Dpm_suspend_start (pmsg_suspend); In this function, it will be tuned to all the suspend functions of the driver registration, and if you want to know the suspend order, you can print it inside.
   if (Error) {PRINTK (kern_err "Pm:some devices failed to suspend\n");
  Goto Recover_platform;
  } suspend_test_finish ("Suspend devices");
 
 if (Suspend_test (test_devices)) goto Recover_platform; Suspend_enter (state);
 
 In this function, the system will be called Hibernate, the system into sleep mode, and the system will stay in hibernation, when the wake up to continue to execute.
  Resume_devices://When the system is awakened by an external interrupt, this will be performed to the Suspend_test_start ();
Dpm_resume_end (Pmsg_resume);//This function executes the resume process, calling all resume functions registered in the drive.  Suspend_test_finish ("Resume devices");
  Set_gfp_allowed_mask (Saved_mask);
  Resume_console ();
  Close:if (Suspend_ops->end) suspend_ops->end ();
 
 return error;
  Recover_platform:if (Suspend_ops->recover) suspend_ops->recover ();
 Goto resume_devices; The static struct Platform_suspend_ops s3c_pm_ops = {. Enter = S3c_pm_enter,//OS register interface, which will allow the system to enter the hibernation/wake state in which the system registers are preserved Value, set a good external wake source.
  After performing the S3c_cpu_save system, it enters hibernation mode. When the system wakes up, it starts with the S3c_cpu_save function. Prepare = s3c_pm_prepare,//To set up CRC checksum, allocate memory that holds CRC value. finish = S3c_pm_finish,. VA Lid = Suspend_valid_only_mem,};//This is the power management interface for the platform defined in s5pv210, suspend_ops pointer static int suspend_enter to this struct variable (
 
 suspend_state_t state) {int error;
   if (suspend_ops->prepare) {error = Suspend_ops->prepare ();
  if (error) return error;
  Error = DPM_SUSPEND_NOIRQ (pmsg_suspend);
   if (Error) {PRINTK (kern_err "Pm:some devices failed to power down\n");
  Goto Platfrom_finish; } if (suspend_ops->Prepare_late) {error = Suspend_ops->prepare_late ();
  if (error) goto power_up_devices;
 
 } if (Suspend_test (test_platform)) goto Platform_wake;
  Error = Disable_nonboot_cpus ();
 
 if (Error | | suspend_test (TEST_CPUS)) goto Enable_cpus;
  Arch_suspend_disable_irqs ();
 
 Bug_on (!irqs_disabled ());
  Error = Sysdev_suspend (pmsg_suspend);
  if (!error) {if (!suspend_test (test_core)) error = Suspend_ops->enter (state);//Call this function to hibernate sysdev_resume ();
  } Arch_suspend_enable_irqs ();
 
 Bug_on (irqs_disabled ());
 
 Enable_cpus:enable_nonboot_cpus ();
 
 Platform_wake:if (Suspend_ops->wake) suspend_ops->wake ();
 
 POWER_UP_DEVICES:DPM_RESUME_NOIRQ (Pmsg_resume);
 
 Platfrom_finish:if (Suspend_ops->finish) suspend_ops->finish ();
 return error;
 }


How to locate a wake/dormant problem:

First to let the serial port print out, open the kernel debugging options, in the s5pv210 platform;

Kernel Hacking--->
Kernel debugging
System Type--->
s3c2410 PM Suspend Debug

After you open the two options, you can print all the information before and after hibernation/wake.

If you need to see which drive wake/hibernate is wrong, you can position it by printing.

Note: Late_resume will not be invoked until the Android setting is on to/sys/power/state.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.