Exemple #1
0
/**
 * acpi_suspend - OS-agnostic system suspend/resume support (S? states)
 * @state:	state we're entering
 *
 */
acpi_status
acpi_suspend (
	u32			state)
{
	acpi_status status;

	/* only support S1 and S5 on kernel 2.4 */
	if (state != ACPI_STATE_S1 && state != ACPI_STATE_S4
	    && state != ACPI_STATE_S5)
		return AE_ERROR;


	if (ACPI_STATE_S4 == state) {
		/* For s4bios, we need a wakeup address. */
		if (1 == acpi_gbl_FACS->S4bios_f &&
		    0 != acpi_gbl_FADT->smi_cmd) {
			if (!acpi_wakeup_address)
				return AE_ERROR;
			acpi_set_firmware_waking_vector((acpi_physical_address) acpi_wakeup_address);
		} else
			/* We don't support S4 under 2.4.  Give up */
			return AE_ERROR;
	}

	status = acpi_system_save_state(state);
	if (!ACPI_SUCCESS(status) && state != ACPI_STATE_S5)
		return status;

	acpi_enter_sleep_state_prep(state);

	/* disable interrupts and flush caches */
	ACPI_DISABLE_IRQS();
	ACPI_FLUSH_CPU_CACHE();

	/* perform OS-specific sleep actions */
	status = acpi_system_suspend(state);

	/* Even if we failed to go to sleep, all of the devices are in an suspended
	 * mode. So, we run these unconditionaly to make sure we have a usable system
	 * no matter what.
	 */
	acpi_leave_sleep_state(state);
	acpi_system_restore_state(state);

	/* make sure interrupts are enabled */
	ACPI_ENABLE_IRQS();

	/* reset firmware waking vector */
	acpi_set_firmware_waking_vector((acpi_physical_address) 0);

	return status;
}
Exemple #2
0
/****************************************************************************
 *
 * FUNCTION:    sm_osl_suspend
 *
 * PARAMETERS:  %state: Sleep state to enter. Assumed that caller has filtered
 *              out bogus values, so it's one of S1, S2, S3 or S4
 *
 * RETURN:      ACPI_STATUS, whether or not we successfully entered and
 *              exited sleep.
 *
 * DESCRIPTION:
 * This function is the meat of the sleep routine, as far as the ACPI-CA is
 * concerned.
 *
 * See Chapter 9 of the ACPI 2.0 spec for details concerning the methodology here.
 *
 * It will do the following things:
 * - Call arch-specific routines to save the processor and kernel state
 * - Call acpi_enter_sleep_state to actually go to sleep
 * ....
 * When we wake back up, we will:
 * - Restore the processor and kernel state
 * - Return to the user
 *
 * By having this routine in here, it hides it from every part of the CA,
 * so it can remain OS-independent. The only function that calls this is
 * sm_proc_write_sleep, which gets the sleep state to enter from the user.
 *
 ****************************************************************************/
static acpi_status
sm_osl_suspend(u32 state)
{
	acpi_status status = AE_ERROR;
	unsigned long wakeup_address;

	/* get out if state is invalid */
	if (state < ACPI_S1 || state > ACPI_S5) 
		goto acpi_sleep_done;

	/* make sure we don't get any suprises */
	disable();

	/* TODO: save device state and suspend them */
	
	/* save the processor state to memory if going into S2 or S3;
	 * save it to disk if going into S4.
	 * Also, set the FWV if going into an STR state
	 */
	if (state == ACPI_S2 || state == ACPI_S3) {
#ifdef DONT_USE_UNTIL_LOWLEVEL_CODE_EXISTS
		/* That && trick is *not going to work*. Read gcc
		   specs. That explicitely says: jumping from other
		   function is *not allowed*. */ 
		wakeup_address = acpi_save_state_mem((unsigned long)&&acpi_sleep_done);

		if (!wakeup_address) goto acpi_sleep_done;

		acpi_set_firmware_waking_vector(
			(ACPI_PHYSICAL_ADDRESS)wakeup_address);
#endif
	} else if (state == ACPI_S4)
Exemple #3
0
static void acpi_hibernation_finish(void)
{
	acpi_disable_wakeup_device(ACPI_STATE_S4);
	acpi_leave_sleep_state(ACPI_STATE_S4);

	/* reset firmware waking vector */
	acpi_set_firmware_waking_vector((acpi_physical_address) 0);

	acpi_target_sleep_state = ACPI_STATE_S0;
}
Exemple #4
0
static int acpi_pm_finish(suspend_state_t pm_state)
{
	u32 acpi_state = acpi_suspend_states[pm_state];

	acpi_leave_sleep_state(acpi_state);
	acpi_disable_wakeup_device(acpi_state);

	/* reset firmware waking vector */
	acpi_set_firmware_waking_vector((acpi_physical_address) 0);

	if (init_8259A_after_S1) {
		printk("Broken toshiba laptop -> kicking interrupts\n");
		init_8259A(0);
	}
	return 0;
}
Exemple #5
0
/**
 *	acpi_pm_finish - Instruct the platform to leave a sleep state.
 *
 *	This is called after we wake back up (or if entering the sleep state
 *	failed).
 */
static void acpi_pm_finish(void)
{
    u32 acpi_state = acpi_target_sleep_state;

    if (acpi_state == ACPI_STATE_S0)
        return;

    printk(KERN_INFO PREFIX "Waking up from system sleep state S%d\n",
           acpi_state);
    acpi_disable_wakeup_device(acpi_state);
    acpi_leave_sleep_state(acpi_state);

    /* reset firmware waking vector */
    acpi_set_firmware_waking_vector((acpi_physical_address) 0);

    acpi_target_sleep_state = ACPI_STATE_S0;
}
Exemple #6
0
int acpi_sleep_prepare(u32 acpi_state)
{
#ifdef CONFIG_ACPI_SLEEP
	/* do we have a wakeup address for S2 and S3? */
	if (acpi_state == ACPI_STATE_S3) {
		if (!acpi_wakeup_address) {
			return -EFAULT;
		}
		acpi_set_firmware_waking_vector((acpi_physical_address)
						virt_to_phys((void *)
							     acpi_wakeup_address));

	}
	ACPI_FLUSH_CPU_CACHE();
	acpi_enable_wakeup_device_prep(acpi_state);
#endif
	acpi_enter_sleep_state_prep(acpi_state);
	return 0;
}
Exemple #7
0
static void acpi_pm_finish(void)
{
	u32 acpi_state = acpi_target_sleep_state;

	acpi_disable_wakeup_device(acpi_state);
	acpi_leave_sleep_state(acpi_state);

	/* reset firmware waking vector */
	acpi_set_firmware_waking_vector((acpi_physical_address) 0);

	acpi_target_sleep_state = ACPI_STATE_S0;

#ifdef CONFIG_X86
	if (init_8259A_after_S1) {
		printk("Broken toshiba laptop -> kicking interrupts\n");
		init_8259A(0);
	}
#endif
}
Exemple #8
0
static int acpi_sleep_prepare(u32 acpi_state)
{
#ifdef CONFIG_ACPI_SLEEP
    /* do we have a wakeup address for S2 and S3? */
    if (acpi_state == ACPI_STATE_S3) {
        if (!acpi_wakeup_address) {
            return -EFAULT;
        }
        acpi_set_firmware_waking_vector(
            (acpi_physical_address)acpi_wakeup_address);

    }
    ACPI_FLUSH_CPU_CACHE();
    acpi_enable_wakeup_device_prep(acpi_state);
#endif
    printk(KERN_INFO PREFIX "Preparing to enter system sleep state S%d\n",
           acpi_state);
    acpi_enter_sleep_state_prep(acpi_state);
    return 0;
}