Beispiel #1
0
/**
 *	acpi_suspend_enter - Actually enter a sleep state.
 *	@pm_state: ignored
 *
 *	Flush caches and go to sleep. For STR we have to call arch-specific
 *	assembly, which in turn call acpi_enter_sleep_state().
 *	It's unfortunate, but it works. Please fix if you're feeling frisky.
 */
static int acpi_suspend_enter(suspend_state_t pm_state)
{
    acpi_status status = AE_OK;
    unsigned long flags = 0;
    u32 acpi_state = acpi_target_sleep_state;

    ACPI_FLUSH_CPU_CACHE();

    /* Do arch specific saving of state. */
    if (acpi_state == ACPI_STATE_S3) {
        int error = acpi_save_state_mem();

        if (error)
            return error;
    }

    local_irq_save(flags);
    acpi_enable_wakeup_device(acpi_state);
    switch (acpi_state) {
    case ACPI_STATE_S1:
        barrier();
        status = acpi_enter_sleep_state(acpi_state);
        break;

    case ACPI_STATE_S3:
        do_suspend_lowlevel();
        break;
    }

    /* Reprogram control registers and execute _BFS */
    acpi_leave_sleep_state_prep(acpi_state);

    /* ACPI 3.0 specs (P62) says that it's the responsibility
     * of the OSPM to clear the status bit [ implying that the
     * POWER_BUTTON event should not reach userspace ]
     */
    if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3))
        acpi_clear_event(ACPI_EVENT_POWER_BUTTON);

    /*
     * Disable and clear GPE status before interrupt is enabled. Some GPEs
     * (like wakeup GPE) haven't handler, this can avoid such GPE misfire.
     * acpi_leave_sleep_state will reenable specific GPEs later
     */
    acpi_hw_disable_all_gpes();

    local_irq_restore(flags);
    printk(KERN_DEBUG "Back to C!\n");

    /* restore processor state */
    if (acpi_state == ACPI_STATE_S3)
        acpi_restore_state_mem();

    return ACPI_SUCCESS(status) ? 0 : -EFAULT;
}
Beispiel #2
0
void acpi_power_off(void)
{
	/* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
	printk("%s called\n", __FUNCTION__);
	local_irq_disable();
	/* Some SMP machines only can poweroff in boot CPU */
#ifdef CONFIG_ACPI_SLEEP
	acpi_enable_wakeup_device(ACPI_STATE_S5);
#endif
	acpi_enter_sleep_state(ACPI_STATE_S5);
}
Beispiel #3
0
static int acpi_pm_enter(suspend_state_t pm_state)
{
	acpi_status status = AE_OK;
	unsigned long flags = 0;
	u32 acpi_state = acpi_suspend_states[pm_state];

	ACPI_FLUSH_CPU_CACHE();

	/* Do arch specific saving of state. */
	if (pm_state > PM_SUSPEND_STANDBY) {
		int error = acpi_save_state_mem();
		if (error)
			return error;
	}

	local_irq_save(flags);
	acpi_enable_wakeup_device(acpi_state);
	switch (pm_state) {
	case PM_SUSPEND_STANDBY:
		barrier();
		status = acpi_enter_sleep_state(acpi_state);
		break;

	case PM_SUSPEND_MEM:
		do_suspend_lowlevel();
		break;

	case PM_SUSPEND_DISK:
		if (acpi_pm_ops.pm_disk_mode == PM_DISK_PLATFORM)
			status = acpi_enter_sleep_state(acpi_state);
		else
			do_suspend_lowlevel_s4bios();
		break;
	case PM_SUSPEND_MAX:
		acpi_power_off();
		break;

	default:
		return -EINVAL;
	}
	local_irq_restore(flags);
	printk(KERN_DEBUG "Back to C!\n");

	/* restore processor state
	 * We should only be here if we're coming back from STR or STD.
	 * And, in the case of the latter, the memory image should have already
	 * been loaded from disk.
	 */
	if (pm_state > PM_SUSPEND_STANDBY)
		acpi_restore_state_mem();

	return ACPI_SUCCESS(status) ? 0 : -EFAULT;
}
Beispiel #4
0
static int acpi_hibernation_enter(void)
{
    acpi_status status = AE_OK;
    unsigned long flags = 0;

    ACPI_FLUSH_CPU_CACHE();

    local_irq_save(flags);
    acpi_enable_wakeup_device(ACPI_STATE_S4);
    /* This shouldn't return.  If it returns, we have a problem */
    status = acpi_enter_sleep_state(ACPI_STATE_S4);
    /* Reprogram control registers and execute _BFS */
    acpi_leave_sleep_state_prep(ACPI_STATE_S4);
    local_irq_restore(flags);

    return ACPI_SUCCESS(status) ? 0 : -EFAULT;
}
Beispiel #5
0
static int acpi_pm_enter(suspend_state_t pm_state)
{
	acpi_status status = AE_OK;
	unsigned long flags = 0;
	u32 acpi_state = acpi_suspend_states[pm_state];

	ACPI_FLUSH_CPU_CACHE();

	/* Do arch specific saving of state. */
	if (pm_state > PM_SUSPEND_STANDBY) {
		int error = acpi_save_state_mem();
		if (error)
			return error;
	}

	local_irq_save(flags);
	acpi_enable_wakeup_device(acpi_state);
	switch (pm_state) {
	case PM_SUSPEND_STANDBY:
		barrier();
		status = acpi_enter_sleep_state(acpi_state);
		break;

	case PM_SUSPEND_MEM:
		if (unlikely(acpi_simulate_suspend_to_ram)) {
			printk(KERN_INFO "ACPI: simulating suspend-to-RAM: "
					 "not calling BIOS.\n");
		} else {
			do_suspend_lowlevel();
		}
		break;

	case PM_SUSPEND_DISK:
		if (acpi_pm_ops.pm_disk_mode == PM_DISK_PLATFORM)
			status = acpi_enter_sleep_state(acpi_state);
		break;
	case PM_SUSPEND_MAX:
		acpi_power_off();
		break;

	default:
		return -EINVAL;
	}

	/* ACPI 3.0 specs (P62) says that it's the responsabilty
	 * of the OSPM to clear the status bit [ implying that the
	 * POWER_BUTTON event should not reach userspace ]
	 */
	if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3))
		acpi_clear_event(ACPI_EVENT_POWER_BUTTON);

	local_irq_restore(flags);
	printk(KERN_DEBUG "Back to C!\n");

	/* restore processor state
	 * We should only be here if we're coming back from STR or STD.
	 * And, in the case of the latter, the memory image should have already
	 * been loaded from disk.
	 */
	if (pm_state > PM_SUSPEND_STANDBY)
		acpi_restore_state_mem();

	return ACPI_SUCCESS(status) ? 0 : -EFAULT;
}