示例#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;
}
示例#2
0
文件: main.c 项目: kzlin129/tt-gpl
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;
}
示例#3
0
/**
 * acpi_system_restore_state - OS-specific restoration of state
 * @state:	sleep state we're exiting
 *
 * Note that if we're coming back from S4, the memory image should have
 * already been loaded from the disk and is already in place.  (Otherwise how
 * else would we be here?).
 */
acpi_status
acpi_system_restore_state(
	u32			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 (state > ACPI_STATE_S1) {
		acpi_restore_state_mem();

		/* Do _early_ resume for irqs.  Required by
		 * ACPI specs.
		 */
		/* TBD: call arch dependant reinitialization of the 
		 * interrupts.
		 */
#ifdef CONFIG_X86
		init_8259A(0);
#endif
		/* wait for power to come back */
		mdelay(1000);

	}

	/* Be really sure that irqs are disabled. */
	ACPI_DISABLE_IRQS();

	/* Wait a little again, just in case... */
	mdelay(1000);

	/* enable interrupts once again */
	ACPI_ENABLE_IRQS();

	/* turn all the devices back on */
	if (state > ACPI_STATE_S1)
		pm_send_all(PM_RESUME, (void *)0);

	return AE_OK;
}
示例#4
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;
}