Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linux suspend/resume code flow (on android phone)

Does anyone know any good reading on how the whole process and code flow are for android/linux suspend/resume (after pressing the end key on the phone)? I am trying to understand and read the related code and files.

Or, maybe if somebody can point me to the code to look at...

like image 663
user1804788 Avatar asked Nov 07 '12 01:11

user1804788


2 Answers

I hope i help.

Android is based on Linux, so the base is more or less same as that of Linux Suspend Resume. There are few additional functionality, most important being Wakelocks and Early Suspend which are added to make the mobiles, PDA more power efficient as they have limited battery.

Now let us start with what you are asking: As soon as you press the power button then obviously interrupt is triggered which initiates the sequence.

Difference: You should have noted that as soon as power button is pressed then LCD and touch goes to sleep. They are early_suspend. Device might be up, just the most power consuming LCD, touch are gone to sleep. Then in background Wakelocks are checked, whether anyone is acquiring, as if anyone is acquiring then those pending task are performed.

Common: Then File system is synced(RAM--> NAND) and the processes are freezed. Then device are suspended and then CPU state is saved and then it sleeps. Sequence is common in both Linux and Android.

After Android receice event.POWER and affirm no wake_lock exist, Android trigger the suspend flow in kernel by echo mem > /sys/power/state:

state_store >> pm_suspend >> enter_state >> suspend_prepare >> suspend_devices_and_enter >> dpm_suspend_start >> dpm_suspend >> device_suspend >> __device_suspend ---> suspend_enter (called by suspend_device_and_enter after __device_suspend is completed)

The above sequence is present in both Linux and Android.

Files: suspend.c, (kernel/power/) wakelock.c, main.c (drivers/base/power).

Note: All the SoC specific suspend callbacks like enter, valid, begin are present in pm.c present in arch/arm/< folder.

like image 153
shingaridavesh Avatar answered Nov 15 '22 20:11

shingaridavesh


It is a big topic about suspend/resume code flow (on android phone).The code flow in kernel have been inlustrated by shingaridavesh.

What's more, kernel private interface(mechanism) to suspend system to Android. But most of the control logic(policy) is in PowerManagerService of Android system. I hope this much help you to understand what system really do after press the Power Key.

1. Report the PowerKey

  1. report the power key event by input system in kernel, maybe like this:(up to what SoC platform you are)

    input_report_key(powerkeydev,KEY_POWER, 1); input_sync(powerkeydev); msleep(1); input_report_key(powerkeydev,KEY_POWER, 1); input_sync(powerkeydev);

    KEY_POWER = 116 define in include/uapi/linux/input.h

  2. key code mapping in android android/frameworks/base/data/keyboards/Generic.kl android/frameworks/native/include/input/KeycodeLables.h

  3. intercept the Key event android/frameworks/base/services/core/java/com/anroid/server/policy/PhoneWindowManager.java interceptKeyBeforeQueueing() >> interceptPowerKeyUp() >> powerPress() >> powerPress >> case SHORT_PRESS_POWER_GO_TO_SLEEP >> mPowerManager.goToSleep

  4. manage the wake locks in PowerManagerService: PowerManager.java: goToSleep() -> mService.goToSleep() PowerManagerService.java: goToSleep() -> goToSleepInternal -> goToSleepNoUpdateLocked() -> updatePowerStateLocked() -> updateSuspendBlockerLocked() (clear the wake locks)

2. libsuspend trigger the suspend

  1. suspend_thread_func check should suspend per 100ms. After all the wake lock clear:

    android/system/core/libsuspend/autosuspend.c: suspend_thread_func() -> write(state_fd, sleep_state, strlen(sleep_state))

This menes: echo "mem" > /sys/power/state, which trigger the suspend flow in kernel.

3. how to setup autosuspend thread?

Thread suspend_thread_func() was create by:

  1. init autosuspend

    android/system/core/libsuspend/autosuspend.c: int autosuspend_enable(void)

  2. call autosuspend in jni

    android/frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp: autosuspend_enable() -> nativeSetAutoSuspend()

  3. init by PowerManagerService

    android/services/core/java/com/android/server/power/PowerManagerService.java: nativeSetAutoSuspend(boolean enable);

like image 42
jack guan Avatar answered Nov 15 '22 21:11

jack guan