X-Git-Url: https://git.stricted.de/?a=blobdiff_plain;f=kernel%2Fpower%2Fmain.c;h=4811bd391f08ab3c8918181a2e451759c97cee0e;hb=f29ec40f359012249b26de0356211275656f5a72;hp=d77663bfedeb071370f584f2bf1e42cd8332e5a4;hpb=f53f292eeaa234615c31a1306babe703fc4263f2;p=GitHub%2Fmt8127%2Fandroid_kernel_alcatel_ttab.git diff --git a/kernel/power/main.c b/kernel/power/main.c index d77663bfedeb..4811bd391f08 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -18,35 +18,60 @@ #include "power.h" +#define HIB_PM_DEBUG 1 +#define _TAG_HIB_M "HIB/PM" +#if (HIB_PM_DEBUG) +#undef hib_log +#define hib_log(fmt, ...) pr_warn("[%s][%s]" fmt, _TAG_HIB_M, __func__, ##__VA_ARGS__); +#else +#define hib_log(fmt, ...) +#endif +#undef hib_warn +#define hib_warn(fmt, ...) pr_warn("[%s][%s]" fmt, _TAG_HIB_M, __func__, ##__VA_ARGS__); + DEFINE_MUTEX(pm_mutex); +EXPORT_SYMBOL_GPL(pm_mutex); #ifdef CONFIG_PM_SLEEP /* Routines for PM-transition notifications */ -static BLOCKING_NOTIFIER_HEAD(pm_chain_head); +BLOCKING_NOTIFIER_HEAD(pm_chain_head); +EXPORT_SYMBOL_GPL(pm_chain_head); +//<20130327> add pm_notifier_count +static unsigned int pm_notifier_count = 0; int register_pm_notifier(struct notifier_block *nb) { + //<20130327> add pm_notifier_count + ++pm_notifier_count; return blocking_notifier_chain_register(&pm_chain_head, nb); } EXPORT_SYMBOL_GPL(register_pm_notifier); int unregister_pm_notifier(struct notifier_block *nb) { + //<20130327> add pm_notifier_count + --pm_notifier_count; return blocking_notifier_chain_unregister(&pm_chain_head, nb); } EXPORT_SYMBOL_GPL(unregister_pm_notifier); int pm_notifier_call_chain(unsigned long val) { - int ret = blocking_notifier_call_chain(&pm_chain_head, val, NULL); + //<20130327> add pm_notifier_count + int ret; + pr_debug("[%s] pm_notifier_count: %u, event = %lu\n", __func__, pm_notifier_count, val); + + ret = blocking_notifier_call_chain(&pm_chain_head, val, NULL); return notifier_to_errno(ret); } +EXPORT_SYMBOL_GPL(pm_notifier_call_chain); /* If set, devices may be suspended and resumed asynchronously. */ -int pm_async_enabled = 1; +//<20130327> disable async suspend/resume, set pm_async_enabled = 0 +int pm_async_enabled = 0; static ssize_t pm_async_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) @@ -277,6 +302,7 @@ static inline void pm_print_times_init(void) {} #endif /* CONFIG_PM_SLEEP_DEBUG */ struct kobject *power_kobj; +EXPORT_SYMBOL_GPL(power_kobj); /** * state - control system power state. @@ -293,12 +319,12 @@ static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, { char *s = buf; #ifdef CONFIG_SUSPEND - int i; + suspend_state_t i; + + for (i = PM_SUSPEND_MIN; i < PM_SUSPEND_MAX; i++) + if (pm_states[i].state) + s += sprintf(s,"%s ", pm_states[i].label); - 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 s += sprintf(s, "%s\n", "disk"); @@ -314,7 +340,7 @@ static suspend_state_t decode_state(const char *buf, size_t n) { #ifdef CONFIG_SUSPEND suspend_state_t state = PM_SUSPEND_MIN; - const char * const *s; + struct pm_sleep_state *s; #endif char *p; int len; @@ -328,13 +354,16 @@ static suspend_state_t decode_state(const char *buf, size_t n) #ifdef CONFIG_SUSPEND for (s = &pm_states[state]; state < PM_SUSPEND_MAX; s++, state++) - if (*s && len == strlen(*s) && !strncmp(buf, *s, len)) - return state; + if (s->state && len == strlen(s->label) + && !strncmp(buf, s->label, len)) + return s->state; #endif return PM_SUSPEND_ON; } +//<20130327> merge android kernel 3.0 state_store function +#ifdef CONFIG_MTK_LDVT static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t n) { @@ -362,7 +391,81 @@ static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr, pm_autosleep_unlock(); return error ? error : n; } +#else //#ifdef CONFIG_MTK_LDVT +static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t n) +{ +#ifdef CONFIG_SUSPEND +#ifdef CONFIG_EARLYSUSPEND + 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; +#ifdef CONFIG_MTK_HIBERNATION + state = decode_state(buf, n); + hib_log("entry (%d)\n", state); +#endif + +#ifdef CONFIG_MTK_HIBERNATION + if (len == 8 && !strncmp(buf, "hibabort", len)) { + hib_log("abort hibernation...\n"); + error = mtk_hibernate_abort(); + goto Exit; + } +#endif + + /* First, check if we are requested to hibernate */ + if (len == 4 && !strncmp(buf, "disk", len)) { +#ifdef CONFIG_MTK_HIBERNATION + hib_log("trigger hibernation...\n"); +#ifdef CONFIG_EARLYSUSPEND + if (PM_SUSPEND_ON == get_suspend_state()) { + hib_warn("\"on\" to \"disk\" (i.e., 0->4) is not supported !!!\n"); + error = -EINVAL; + goto Exit; + } +#endif + if (!pre_hibernate()) { + error = 0; + error = mtk_hibernate(); + } +#else // !CONFIG_MTK_HIBERNATION + error = hibernate(); +#endif + goto Exit; + } + +#ifdef CONFIG_SUSPEND + 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 + if (state == PM_SUSPEND_ON || valid_state(state)) { + error = 0; + request_suspend_state(state); + } else + error = -EINVAL; +#else + error = enter_state(state); +#endif + } +#endif + + Exit: + return error ? error : n; +} +#endif power_attr(state); #ifdef CONFIG_PM_SLEEP @@ -445,8 +548,8 @@ static ssize_t autosleep_show(struct kobject *kobj, #ifdef CONFIG_SUSPEND if (state < PM_SUSPEND_MAX) - return sprintf(buf, "%s\n", valid_state(state) ? - pm_states[state] : "error"); + return sprintf(buf, "%s\n", pm_states[state].state ? + pm_states[state].label : "error"); #endif #ifdef CONFIG_HIBERNATION return sprintf(buf, "disk\n"); @@ -462,6 +565,7 @@ static ssize_t autosleep_store(struct kobject *kobj, suspend_state_t state = decode_state(buf, n); int error; + hib_log("store autosleep_state(%d)\n", state); if (state == PM_SUSPEND_ON && strcmp(buf, "off") && strcmp(buf, "off\n")) return -EINVAL;