Ejemplo n.º 1
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;
}
Ejemplo n.º 2
0
acpi_status
acpi_system_suspend(
	u32		state)
{
	acpi_status		status = AE_ERROR;
	unsigned long		flags = 0;

	local_irq_save(flags);
	/* kernel_fpu_begin(); */

	switch (state) {
	case ACPI_STATE_S1:
	case ACPI_STATE_S5:
		barrier();
		status = acpi_enter_sleep_state(state);
		break;
	case ACPI_STATE_S4:
		do_suspend_lowlevel_s4bios(0);
		break;
	}

	/* kernel_fpu_end(); */
	local_irq_restore(flags);

	return status;
}
static void
acpi_power_off (void)
{
	printk("%s called\n",__FUNCTION__);
	/* Some SMP machines only can poweroff in boot CPU */
	set_cpus_allowed(current, cpumask_of_cpu(0));
	acpi_enter_sleep_state_prep(ACPI_STATE_S5);
	ACPI_DISABLE_IRQS();
	acpi_enter_sleep_state(ACPI_STATE_S5);
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
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);
}
Ejemplo n.º 6
0
static void
acpi_power_off (void)
{
	if (unlikely(in_interrupt())) 
		BUG();
	/* Some SMP machines only can poweroff in boot CPU */
	set_cpus_allowed(current, 1UL << cpu_logical_map(0));
	acpi_enter_sleep_state_prep(ACPI_STATE_S5);
	ACPI_DISABLE_IRQS();
	acpi_enter_sleep_state(ACPI_STATE_S5);

	printk(KERN_EMERG "ACPI: can not power off machine\n");
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
/* Main interface to do xen specific suspend/resume */
static int enter_state(u32 state)
{
    unsigned long flags;
    int error;
    unsigned long cr4;

    if ( (state <= ACPI_STATE_S0) || (state > ACPI_S_STATES_MAX) )
        return -EINVAL;

    if ( !spin_trylock(&pm_lock) )
        return -EBUSY;

    BUG_ON(system_state != SYS_STATE_active);
    system_state = SYS_STATE_suspend;

    printk(XENLOG_INFO "Preparing system for ACPI S%d state.\n", state);

    freeze_domains();

    acpi_dmar_reinstate();

    if ( (error = disable_nonboot_cpus()) )
    {
        system_state = SYS_STATE_resume;
        goto enable_cpu;
    }

    cpufreq_del_cpu(0);

    hvm_cpu_down();

    acpi_sleep_prepare(state);

    console_start_sync();
    printk("Entering ACPI S%d state.\n", state);

    local_irq_save(flags);
    spin_debug_disable();

    if ( (error = device_power_down()) )
    {
        printk(XENLOG_ERR "Some devices failed to power down.");
        system_state = SYS_STATE_resume;
        goto done;
    }

    ACPI_FLUSH_CPU_CACHE();

    switch ( state )
    {
    case ACPI_STATE_S3:
        do_suspend_lowlevel();
        system_reset_counter++;
        error = tboot_s3_resume();
        break;
    case ACPI_STATE_S5:
        acpi_enter_sleep_state(ACPI_STATE_S5);
        break;
    default:
        error = -EINVAL;
        break;
    }

    system_state = SYS_STATE_resume;

    /* Restore CR4 and EFER from cached values. */
    cr4 = read_cr4();
    write_cr4(cr4 & ~X86_CR4_MCE);
    write_efer(read_efer());

    device_power_up();

    mcheck_init(&boot_cpu_data, 0);
    write_cr4(cr4);

    printk(XENLOG_INFO "Finishing wakeup from ACPI S%d state.\n", state);

    if ( (state == ACPI_STATE_S3) && error )
        tboot_s3_error(error);

 done:
    spin_debug_enable();
    local_irq_restore(flags);
    console_end_sync();
    acpi_sleep_post(state);
    if ( hvm_cpu_up() )
        BUG();

 enable_cpu:
    cpufreq_add_cpu(0);
    microcode_resume_cpu(0);
    rcu_barrier();
    mtrr_aps_sync_begin();
    enable_nonboot_cpus();
    mtrr_aps_sync_end();
    adjust_vtd_irq_affinities();
    acpi_dmar_zap();
    thaw_domains();
    system_state = SYS_STATE_active;
    spin_unlock(&pm_lock);
    return error;
}
Ejemplo n.º 9
0
static void acpi_db_do_one_sleep_state(u8 sleep_state)
{
	acpi_status status;
	u8 sleep_type_a;
	u8 sleep_type_b;

	/* Validate parameter */

	if (sleep_state > ACPI_S_STATES_MAX) {
		acpi_os_printf("Sleep state %d out of range (%d max)\n",
			       sleep_state, ACPI_S_STATES_MAX);
		return;
	}

	acpi_os_printf("\n---- Invoking sleep state S%d (%s):\n",
		       sleep_state, acpi_gbl_sleep_state_names[sleep_state]);

	/* Get the values for the sleep type registers (for display only) */

	status =
	    acpi_get_sleep_type_data(sleep_state, &sleep_type_a, &sleep_type_b);
	if (ACPI_FAILURE(status)) {
		acpi_os_printf("Could not evaluate [%s] method, %s\n",
			       acpi_gbl_sleep_state_names[sleep_state],
			       acpi_format_exception(status));
		return;
	}

	acpi_os_printf
	    ("Register values for sleep state S%d: Sleep-A: %.2X, Sleep-B: %.2X\n",
	     sleep_state, sleep_type_a, sleep_type_b);

	/* Invoke the various sleep/wake interfaces */

	acpi_os_printf("**** Sleep: Prepare to sleep (S%d) ****\n",
		       sleep_state);
	status = acpi_enter_sleep_state_prep(sleep_state);
	if (ACPI_FAILURE(status)) {
		goto error_exit;
	}

	acpi_os_printf("**** Sleep: Going to sleep (S%d) ****\n", sleep_state);
	status = acpi_enter_sleep_state(sleep_state);
	if (ACPI_FAILURE(status)) {
		goto error_exit;
	}

	acpi_os_printf("**** Wake: Prepare to return from sleep (S%d) ****\n",
		       sleep_state);
	status = acpi_leave_sleep_state_prep(sleep_state);
	if (ACPI_FAILURE(status)) {
		goto error_exit;
	}

	acpi_os_printf("**** Wake: Return from sleep (S%d) ****\n",
		       sleep_state);
	status = acpi_leave_sleep_state(sleep_state);
	if (ACPI_FAILURE(status)) {
		goto error_exit;
	}

	return;

error_exit:
	ACPI_EXCEPTION((AE_INFO, status, "During invocation of sleep state S%d",
			sleep_state));
}
Ejemplo n.º 10
0
asmlinkage void acpi_enter_s3(void)
{
	acpi_enter_sleep_state(3, wake_sleep_flags);
}
Ejemplo n.º 11
0
/* Main interface to do xen specific suspend/resume */
static int enter_state(u32 state)
{
    unsigned long flags;
    int error;

    if ( (state <= ACPI_STATE_S0) || (state > ACPI_S_STATES_MAX) )
        return -EINVAL;

    if ( !spin_trylock(&pm_lock) )
        return -EBUSY;

    printk(XENLOG_INFO "Preparing system for ACPI S%d state.", state);

    freeze_domains();

    disable_nonboot_cpus();
    if ( num_online_cpus() != 1 )
    {
        error = -EBUSY;
        goto enable_cpu;
    }

    cpufreq_del_cpu(0);

    hvm_cpu_down();

    acpi_sleep_prepare(state);

    console_start_sync();
    printk("Entering ACPI S%d state.\n", state);

    local_irq_save(flags);
    spin_debug_disable();

    if ( (error = device_power_down()) )
    {
        printk(XENLOG_ERR "Some devices failed to power down.");
        goto done;
    }

    ACPI_FLUSH_CPU_CACHE();

    switch ( state )
    {
    case ACPI_STATE_S3:
        do_suspend_lowlevel();
        system_reset_counter++;
        error = tboot_s3_resume();
        break;
    case ACPI_STATE_S5:
        acpi_enter_sleep_state(ACPI_STATE_S5);
        break;
    default:
        error = -EINVAL;
        break;
    }

    /* Restore CR4 and EFER from cached values. */
    write_cr4(read_cr4());
    if ( cpu_has_efer )
        write_efer(read_efer());

    device_power_up();

    printk(XENLOG_INFO "Finishing wakeup from ACPI S%d state.\n", state);

    if ( (state == ACPI_STATE_S3) && error )
        panic("Memory integrity was lost on resume (%d)\n", error);

 done:
    spin_debug_enable();
    local_irq_restore(flags);
    console_end_sync();
    acpi_sleep_post(state);
    if ( !hvm_cpu_up() )
        BUG();

 enable_cpu:
    cpufreq_add_cpu(0);
    microcode_resume_cpu(0);
    enable_nonboot_cpus();
    thaw_domains();
    spin_unlock(&pm_lock);
    return error;
}
Ejemplo n.º 12
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;
}