static void hib_unplug_cores(void)
{
	int i = 0;

	hib_warn("unplug cores\n");

#ifdef CONFIG_CPU_FREQ_GOV_HOTPLUG
	mutex_lock(&hp_onoff_mutex);
#endif
	for (i = (num_possible_cpus() - 1); i > 0 && num_online_cpus() > HIB_MULTIIO_CORES; i--) {
		if (cpu_online(i)) {
			int err;
			hib_log("cpu %d down...\n", i);
			err = cpu_down(i);
			if (err < 0) {
				hib_warn("cpu %d down...failed(%d)\n", i, err);
			} else {
				hib_log("cpu %d down...done\n", i, err);
			}
		}
	}
#ifdef CONFIG_CPU_FREQ_GOV_HOTPLUG
	mutex_unlock(&hp_onoff_mutex);
#endif
}
int swsusp_helper_pm_restore_noirq(struct device *device)
{
	int id, ret = 0, retall = 0;

	hib_log("[%s] enter...\n", __func__);

	BUG_ON(!initialized);

	for (id = ID_M_BEGIN; id < ID_M_END; id++) {
		if (restore_noirq_func_table[id].func != NULL) {
			hib_warn("exec func %d:0x%p !\n", restore_noirq_func_table[id].id, restore_noirq_func_table[id].func);
			if (id != restore_noirq_func_table[id].id) {
				hib_err("exec func fail: func id miss-matched (%d/%d) !\n", id, restore_noirq_func_table[id].id);
				continue;
			}
			ret =
			    restore_noirq_func_table[id].func(restore_noirq_func_table[id].device);
			if (ret != 0) {
				hib_warn("exec func fail: func id(%d), err code %d !\n",
					 restore_noirq_func_table[id].id, ret);
				retall = ret;
			}
		}
	}

	return retall;

}
/* en: 1 enable, en: 0 disable */
static void hib_hotplug_mode(int en)
{
	static int g_hp_disable = 0;
	if (en) {
		if (1 == g_hp_disable) {
			hib_warn("enable hotplug\n");
#if defined(CONFIG_CPU_FREQ_DEFAULT_GOV_HOTPLUG) || defined(CONFIG_CPU_FREQ_DEFAULT_GOV_BALANCE)
			hp_set_dynamic_cpu_hotplug_enable(1);
#else
			hps_set_enabled(1);
#endif
			g_hp_disable = 0;
		}
	} else if (!en) {
		if (0 == g_hp_disable) {
			hib_warn("disable hotplug\n");
#if defined(CONFIG_CPU_FREQ_DEFAULT_GOV_HOTPLUG) || defined(CONFIG_CPU_FREQ_DEFAULT_GOV_BALANCE)
			hp_set_dynamic_cpu_hotplug_enable(0);
#else
			hps_set_enabled(0);
#endif
			hib_unplug_cores();
			g_hp_disable = 1;
		}
	}
}
static void hib_ftrace_buffer(int en)
{
#if defined(CONFIG_MTK_SCHED_TRACERS)
	int fterr = 0;

	hib_warn("%s ftrace mode\n", (en ? "enable" : "disable"));
	fterr = resize_ring_buffer_for_hibernation(en);
	if (fterr < 0)
		hib_warn("calling resize_ring_buffer_for_hibernation() failed (%d)\n", fterr);
#endif
}
/* NOTICE: this function MUST be called under autosleep_lock (in autosleep.c) is locked!! */
int mtk_hibernate_via_autosleep(suspend_state_t *autosleep_state)
{
	int err = 0;
	hib_log("entering hibernation state(%d)\n", *autosleep_state);
	err = hibernate();
	if (err) {
		hib_warn
		    ("@@@@@@@@@@@@@@@@@@@@@@@@@\n@@_Hibernation Failed_@@@\n@@@@@@@@@@@@@@@@@@@@@@@@@\n");
		/* enhanced error handling */
#ifdef CONFIG_TOI_ENHANCE
		if (toi_hibernate_fatalerror()) {
			kernel_power_off();
			kernel_halt();
			BUG();
		}
#endif
		if (hibernation_failed_action == HIB_FAILED_TO_SHUTDOWN) {
			kernel_power_off();
			kernel_halt();
			BUG();
		} else if (hibernation_failed_action == HIB_FAILED_TO_S2RAM) {
			hib_warn("hibernation failed: so changing state(%d->%d) err(%d)\n",
				 *autosleep_state, PM_SUSPEND_MEM, err);
			if (++hib_failed_cnt >= MAX_HIB_FAILED_CNT)
				hibernation_failed_action = HIB_FAILED_TO_SHUTDOWN;
			hibernate_recover();
			*autosleep_state = PM_SUSPEND_MEM;
			pm_wake_lock("IPOD_HIB_WAKELOCK");
			system_is_hibernating = false;
		} else {
			hib_err("@@@@@@@@@@@@@@@@@@\n@_FATAL ERROR !!!_\n@@@@@@@@@@@@@@@@@@@\n");
			BUG();
		}
	} else {
		if (hybrid_sleep_mode()) {
			hib_warn("hybrid sleep mode so changing state(%d->%d)\n", *autosleep_state,
				 PM_SUSPEND_MEM);
			*autosleep_state = PM_SUSPEND_MEM;	/* continue suspend to ram if hybrid sleep mode */
		} else {
			hib_warn("hibernation succeeded: so changing state(%d->%d) err(%d)\n",
				 *autosleep_state, PM_SUSPEND_ON, err);
			hibernate_restore();
			*autosleep_state = PM_SUSPEND_ON;	/* if this is not set, it will recursively do hibernating!! */
		}
		hib_failed_cnt = 0;
		pm_wake_lock("IPOD_HIB_WAKELOCK");
		system_is_hibernating = false;
	}

	return err;
}
int register_swsusp_restore_noirq_func(unsigned int id, swsusp_cb_func_t func,
				       struct device *device)
{
	int ret = 0;
	swsusp_cb_func_info *info_ptr;

	BUG_ON(!initialized);

	if ((id >= MAX_CB_FUNCS) || (func == NULL)) {
		hib_err("register func fail: func_id: %d!\n", id);
		return E_PARAM;
	}
	info_ptr = &(restore_noirq_func_table[id]);
	if (info_ptr->func == NULL) {
		info_ptr->id = id;
		info_ptr->func = func;
		info_ptr->device = device;
		hib_warn("reg. func %d:0x%p with device %s%p\n",
				 restore_noirq_func_table[id].id,
				 restore_noirq_func_table[id].func,
				 (device == NULL) ? " " : "0x",
				 restore_noirq_func_table[id].device);
	} else
		hib_err("register func fail: func(%d) already registered!\n", id);

	return ret;
}
static void hibernate_restore(void)
{
	hib_ftrace_buffer(1);

	hib_hotplug_mode(1);

	hib_warn("start trigger ipod\n");
}
/* en: 1 enable, en: 0 disable */
static void hib_hotplug_mode(int en)
{
	static int g_hp_disable;
	if (en) {
		if (1 == g_hp_disable) {
			hib_warn("enable hotplug\n");
			hp_set_dynamic_cpu_hotplug_enable(1);
			g_hp_disable = 0;
		}
	} else if (!en) {
		if (0 == g_hp_disable) {
			hib_warn("disable hotplug\n");
			hp_set_dynamic_cpu_hotplug_enable(0);
			hib_unplug_cores();
			g_hp_disable = 1;
		}
	}
}
/* called by echo "disk" > /sys/power/state */
int mtk_hibernate(void)
{
	int err = 0;

	hib_log("entering hibernation\n");
	err = hibernate();
	if (err) {
		hib_warn
		    ("@@@@@@@@@@@@@@@@@@@@@@@@@\n@@_Hibernation Failed_@@@\n@@@@@@@@@@@@@@@@@@@@@@@@@\n");
		/* enhanced error handling */
#ifdef CONFIG_TOI_ENHANCE
		if (toi_hibernate_fatalerror()) {
			kernel_power_off();
			kernel_halt();
			BUG();
		}
#endif
		if (hibernation_failed_action == HIB_FAILED_TO_SHUTDOWN) {
			kernel_power_off();
			kernel_halt();
			BUG();
		} else if (hibernation_failed_action == HIB_FAILED_TO_S2RAM) {
			hib_warn("hibernation failed, suspend to ram instead!\n");
			if (++hib_failed_cnt >= MAX_HIB_FAILED_CNT)
				hibernation_failed_action = HIB_FAILED_TO_SHUTDOWN;
			hibernate_recover();
			pm_wake_lock("IPOD_HIB_WAKELOCK");
			system_is_hibernating = false;
		} else {
			hib_err("@@@@@@@@@@@@@@@@@@\n@_FATAL ERROR !!!_\n@@@@@@@@@@@@@@@@@@@\n");
			BUG();
		}
	} else {
		if (!hybrid_sleep_mode()) {
			hibernate_restore();
		}
		hib_failed_cnt = 0;
		pm_wake_lock("IPOD_HIB_WAKELOCK");
		system_is_hibernating = false;
	}

	return err;
}
// NOTICE: this function MUST be called under autosleep_lock (in autosleep.c) is locked!!
int mtk_hibernate_via_autosleep(suspend_state_t *autosleep_state)
{
    int err = 0;
    hib_log("entering hibernation state(%d)\n", *autosleep_state);
    err = hibernate();
    if (err) {
        hib_warn("@@@@@@@@@@@@@@@@@@@@@@@@@\n@@_Hibernation Failed_@@@\n@@@@@@@@@@@@@@@@@@@@@@@@@\n");
        if (hibernation_failed_action == HIB_FAILED_TO_SHUTDOWN) {
            kernel_power_off();
            kernel_halt();
            BUG();
        } else if (hibernation_failed_action == HIB_FAILED_TO_S2RAM) {
            hib_warn("hibernation failed: so changing state(%d->%d) err(%d)\n", *autosleep_state, PM_SUSPEND_MEM, err);
            if (++hib_failed_cnt >= MAX_HIB_FAILED_CNT)
                hibernation_failed_action = HIB_FAILED_TO_SHUTDOWN;
            // userspace recover if hibernation failed
            usr_recover_func(NULL);
            *autosleep_state = PM_SUSPEND_MEM;
            system_is_hibernating = false;
         } else {
            hib_err("@@@@@@@@@@@@@@@@@@\n@_FATAL ERROR !!!_\n@@@@@@@@@@@@@@@@@@@\n");
            BUG();
        }
    } else {
        if (hybrid_sleep_mode()) {
            hib_warn("hybrid sleep mode so changing state(%d->%d)\n", *autosleep_state, PM_SUSPEND_MEM);
            *autosleep_state = PM_SUSPEND_MEM; //continue suspend to ram if hybrid sleep mode
        } else {
            hib_warn("hibernation succeeded: so changing state(%d->%d) err(%d) \n", *autosleep_state, PM_SUSPEND_ON, err);
            hib_warn("start trigger ipod\n");
            //usr_bootanim_start(NULL);
            //schedule_delayed_work(&usr_restore_work, HZ*0.05);
            usr_restore_func(NULL);
            *autosleep_state = PM_SUSPEND_ON; // if this is not set, it will recursively do hibernating!!
        }
        hib_failed_cnt = 0;
        pm_wake_lock("IPOD_HIB_WAKELOCK");
        system_is_hibernating = false;
    }

    return err;
}
示例#11
0
int bad_memory_status(void)
{
	struct zone *zone;
	unsigned long free_pages, min_pages;

	for_each_populated_zone(zone) {
		if (!strcmp(zone->name, "Normal")) {
			free_pages = zone_page_state(zone, NR_FREE_PAGES);
			min_pages = min_wmark_pages(zone);
			if (free_pages < (min_pages + HIB_PAGE_FREE_DELTA)) {
				hib_warn("abort hibernate due to %s memory status: (%lu:%lu)\n",
					 zone->name, free_pages, min_pages);
				return -1;
			} else {
				hib_warn("%s memory status: (%lu:%lu)\n", zone->name, free_pages,
					 min_pages);
			}
		}
	}
	return 0;
}
// called by echo "disk" > /sys/power/state
int mtk_hibernate(void)
{
    int err = 0;

    hib_log("entering hibernation\n");
    err = hibernate();
    if (err) {
        hib_warn("@@@@@@@@@@@@@@@@@@@@@@@@@\n@@_Hibernation Failed_@@@\n@@@@@@@@@@@@@@@@@@@@@@@@@\n");
        if (hibernation_failed_action == HIB_FAILED_TO_SHUTDOWN) {
            kernel_power_off();
            kernel_halt();
            BUG();
        } else if (hibernation_failed_action == HIB_FAILED_TO_S2RAM) {
            hib_warn("hibernation failed, suspend to ram instead!\n");
            if (++hib_failed_cnt >= MAX_HIB_FAILED_CNT)
                hibernation_failed_action = HIB_FAILED_TO_SHUTDOWN;
            // userspace recover if hibernation failed
            usr_recover_func(NULL);
            system_is_hibernating = false;
        } else {
            hib_err("@@@@@@@@@@@@@@@@@@\n@_FATAL ERROR !!!_\n@@@@@@@@@@@@@@@@@@@\n");
            BUG();
        }
    } else {
        if (!hybrid_sleep_mode()) {
            hib_warn("start trigger ipod\n");
            //schedule_delayed_work(&usr_bootanim_start_work, HZ*1.0);
            //schedule_delayed_work(&usr_restore_work, HZ*0.05);
            //usr_bootanim_start(NULL);
            usr_restore_func(NULL);
        }
        hib_failed_cnt = 0;
        pm_wake_lock("IPOD_HIB_WAKELOCK");
        system_is_hibernating = false;
    }

    return err;
}
示例#13
0
int unregister_swsusp_restore_noirq_func(unsigned int id)
{
    int ret = 0;
    swsusp_cb_func_info *info_ptr;

    if (id >= MAX_CB_FUNCS) {
        hib_err("register func fail: func_id: %d!\n", id);
        return E_PARAM;
    }
    info_ptr = &(restore_noirq_func_table[id]);
    if (info_ptr->func != NULL) {
        info_ptr->id = -1;
        info_ptr->func = NULL;
        info_ptr->device = NULL;
    } else
        hib_warn("register func fail: func(%d) already unregistered!\n", id);

    return ret;
}
示例#14
0
int swsusp_helper_pm_restore_noirq(struct device *device)
{
    int id, ret = 0, retall = 0;

    hib_log("[%s] enter...\n", __func__);

    for (id = ID_M_BEGIN; id < ID_M_END; id++) {
        if (restore_noirq_func_table[id].func != NULL) {
            ret =
                restore_noirq_func_table[id].func(restore_noirq_func_table[id].device);
            if (ret != 0) {
                hib_warn("exec func fail: func id(%d), err code %d !\n",
                         restore_noirq_func_table[id].id, ret);
                retall = ret;
            }
        }
    }

    return retall;

}
示例#15
0
int exec_swsusp_restore_noirq_func(unsigned int id)
{
    swsusp_cb_func_t func;
    struct device *device = NULL;
    int ret = 0;

    if (id >= MAX_CB_FUNCS) {
        hib_err("exec func fail: invalid func id(%d)!\n", id);
        return E_PARAM;
    }

    func = restore_noirq_func_table[id].func;
    device = restore_noirq_func_table[id].device;
    if (func != NULL) {
        ret = func(device);
    } else {
        ret = E_NO_EXIST;
        hib_warn("exec func fail: func id(%d) not register!\n", id);
    }

    return ret;
}
示例#16
0
int register_swsusp_restore_noirq_func(unsigned int id, swsusp_cb_func_t func,
                                       struct device *device)
{
    int ret = 0;
    swsusp_cb_func_info *info_ptr;

    if ((id >= MAX_CB_FUNCS) || (func == NULL)) {
        hib_err("register func fail: func_id: %d!\n", id);
        return E_PARAM;
    }
    info_ptr = &(restore_noirq_func_table[id]);
    if (info_ptr->func == NULL) {
        info_ptr->id = id;
        info_ptr->func = func;
        info_ptr->device = device;
        if (device == NULL)
            hib_warn("register func(%d:0x%p) with device NULL\n", id, func);
    } else
        hib_err("register func fail: func(%d) already registered!\n", id);

    return ret;
}