Linux driver Power management standard Linux hibernation and wake-up Mechanism Analysis (ii)

Source: Internet
Author: User
Tags sprintf

Third, Pm_test property file Read and write

int pm_test_level = Test_none;

static const char * Const PM_TESTS[__TEST_AFTER_LAST] = {

[Test_none] = "NONE",

[Test_core] = "CORE",

[Test_cpus] = "processors",

[Test_platform] = "PLATFORM",

[Test_devices] = "DEVICES",

[Test_freezer] = "Freezer",

};

Core >> processors >> platform >> devices >> freezer, control range schematic

The cat Pm_test will eventually call the function pm_test_show (), print the string in the above array on the terminal, and the current pattern is represented by [].

echo Devices > Pm_test will eventually call into the function Pm_test_store (), which sets the value of the global variable Pm_test_level, which can be 0-5, representing none to freezer. The global variable is referenced in the following suspend and resume.

MEMCHR Function Description:

Prototype: extern void *memchr (void *buf, char ch, unsigned int count);

Usage: #include <string.h>

Function: Finds the character Ch from the first count byte of the memory area referred to by BUF.

Description: Stops searching when the character Ch is encountered for the first time. Returns a pointer to the character CH if successful, otherwise returns NULL.

Iv. State Property File

The Power_attr (state) macro defines a struct kobj_attribute struct state_attr:

static struct Kobj_attribute state_attr = {

. attr = {

. Name = __stringify (state),

. Mode = 0644,

},

. Show = State_show,

. store = State_store,

}

The kobj_attribute structure encapsulates the struct attribute structure, and the new property file is based on the struct attribute structure. Finally, the function kobj_attr_show and Kobj_attr_store callbacks to the actual show and store functions (KOBJECT.C).

The State_show () function mainly shows which power-saving modes are supported by the current system.

Static ssize_t state_show (struct kobject *kobj, struct kobj_attribute *attr, char *buf)

{

char *s = BUF;

#ifdef Config_suspend//def

int i;

for (i = 0; i < Pm_suspend_max; i++) {

if (Pm_states[i] && valid_state (i))

s + = sprintf (S, "%s", Pm_states[i]);

}

#endif

#ifdef config_hibernation//undef, don ' t support STD mode

s + = sprintf (S, "%s/n", "Disk");

#else

if (s! = buf)

/* Convert the last space to a newline */

* (s-1) = '/n ';

#endif

return (S-BUF);

}

@ kernel/include/linux/suspend.h

#define PM_SUSPEND_ON ((__force suspend_state_t) 0)

#define Pm_suspend_standby ((__force suspend_state_t) 1)

#define PM_SUSPEND_MEM ((__force suspend_state_t) 3)

#define Pm_suspend_disk ((__force suspend_state_t) 4)

#define PM_SUSPEND_MAX ((__force suspend_state_t) 5)

@ kernel/kernel/power/suspend.c

const char *const Pm_states[pm_suspend_max] = {

#ifdef Config_earlysuspend//Android modifies the sleep wake mechanism of standard Linux, adding the Eraly suspend and late resume mechanisms, which are required to be defined if the Android kernel.

[pm_suspend_on] = "on",

#endif

[Pm_suspend_standby] = "STANDBY",

[Pm_suspend_mem] = "MEM",

};

The notable place in this function is valid_state (i), which is a user-configured validation function that supports power-saving mode, and if this verification process is not available, the mode that the cat prints out is the on standby mem, which can be confusing for the upper user.

Where is this valid_state () function defined? Generally defined in file kernel/kernel/power/suspend.c

static struct Platform_suspend_ops *suspend_ops;

void Suspend_set_ops (struct platform_suspend_ops *ops)//The function call is shown in the following

{

Mutex_lock (&pm_mutex);

Suspend_ops = OPS;

Mutex_unlock (&pm_mutex);

}

BOOL Valid_state (suspend_state_t State)

{

return suspend_ops && suspend_ops->valid && suspend_ops->valid (state);

}

The actual platform of the PLATFORM_SUSPEND_OPS structure is generally defined in the file arch/arm/mach-xxxx/pm.c, for the MTK platform is the file mtkpm.c, as follows:

@ kernel/include/linux/suspend.h

struct Platform_suspend_ops {

Int (*valid) (suspend_state_t state);

Int (*begin) (suspend_state_t state);

Int (*prepare) (void);

Int (*prepare_late) (void);

Int (*enter) (suspend_state_t state);

void (*wake) (void);

void (*finish) (void);

void (*end) (void);

void (*recover) (void);

};

After the code analysis, the following conclusions are drawn:

The function that the hibernate wake process executes in turn is: begin,prepare,prepare_late,enter,wake, Finish, end. The same color function performs exactly the opposite work. During hibernation, the code execution is stuck in the function enter, and the wake continues to run after the suspend.

The Recover function appears to be called only if the pm_test is in devices mode.

@ kernel/arch/arm/mach-mt6516/mtkpm.c

static struct Platform_suspend_ops Mtk_pm_ops = {

. valid = Mtk_pm_state_valid,

. Begin = Mtk_pm_begin,

. Prepare = Mtk_pm_prepare,

. Enter = Mtk_pm_enter,

. finish = Mtk_pm_finish,

. end = Mtk_pm_end,

};

static int mtk_pm_state_valid (suspend_state_t pm_state)

{

return pm_state = = Pm_suspend_mem;

}

void Mtk_pm_init (void)

{

_chip_pm_init ();

/* Register and set suspend operation */

Suspend_set_ops (&mtk_pm_ops);

}

The function Mtk_pm_init () is called in the function Mt6516_init_irq (). It can be seen that the platform supports only Mem's power-down mode.

State_store () function:

Static ssize_t State_store (struct kobject *kobj, struct Kobj_attribute *attr,

const char *buf, size_t N)

{

#ifdef config_suspend//Set

#ifdef Config_earlysuspend//For standard Linux, this macro does not exist

suspend_state_t state = pm_suspend_on;

#else

suspend_state_t state = Pm_suspend_standby;

#endif

const char * const *S;

#endif

Char *p;

int Len;

int error =-einval;

p = memchr (buf, '/n ', n);

Len = P? P-buf:n;

/* First, check if we are requested to hibernate */

if (len = = 4 &&!strncmp (buf, "Disk", Len)) {

Error = Hibernate (); If the value is disk, then enter STD mode, the mode is not discussed

Goto Exit;

}

#ifdef config_suspend//def

for (s = &pm_states[state]; State < Pm_suspend_max; s++, state++) {

if (*s && len = strlen (*s) &&!strncmp (buf, *s, Len))

Break

}

if (State < Pm_suspend_max && *s)

#ifdef Config_earlysuspend

The Android Linux kernel defines the macro, first entering eraly suspend mode

if (state = = Pm_suspend_on | | valid_state (state)) {

Error = 0;

Request_suspend_state (state);

}

#else//Standard Linux kernel Direct enter_state () function

Error = Enter_state (state); Kernel/kernel/power/suspend.c

#endif

#endif

Exit:

return error? error:n;

}

Linux driver Power management standard Linux hibernation and wake-up Mechanism Analysis (ii)

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.