Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f216cc37 authored by Alexey Starikovskiy's avatar Alexey Starikovskiy Committed by Len Brown
Browse files

ACPI: suspend: consolidate handling of Sx states.



Recent changes to sleep initialization in ACPI dropped reporting of supported Sx
states above S3. Fix that and also move S5 init into same file as other Sx.
The only functional change is adding printk() for S4 and S5 cases.

Signed-off-by: default avatarAlexey Starikovskiy <astarikovskiy@suse.de>
Acked-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 335fb8fc
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
obj-y					:= poweroff.o wakeup.o
obj-y					:= wakeup.o
obj-$(CONFIG_ACPI_SLEEP)		+= main.o
obj-$(CONFIG_ACPI_SLEEP)		+= proc.o

+48 −5
Original line number Diff line number Diff line
@@ -15,6 +15,9 @@
#include <linux/dmi.h>
#include <linux/device.h>
#include <linux/suspend.h>

#include <asm/io.h>

#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include "sleep.h"
@@ -57,6 +60,27 @@ static int acpi_pm_set_target(suspend_state_t pm_state)
	return error;
}

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_gpe_sleep_prepare(acpi_state);
	acpi_enter_sleep_state_prep(acpi_state);
	return 0;
}

/**
 *	acpi_pm_prepare - Do preliminary suspend work.
 *	@pm_state: ignored
@@ -350,6 +374,20 @@ int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p)
	return d_max;
}

static void acpi_power_off_prepare(void)
{
	/* Prepare to power off the system */
	acpi_sleep_prepare(ACPI_STATE_S5);
}

static void acpi_power_off(void)
{
	/* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
	printk("%s called\n", __FUNCTION__);
	local_irq_disable();
	acpi_enter_sleep_state(ACPI_STATE_S5);
}

int __init acpi_sleep_init(void)
{
	acpi_status status;
@@ -363,8 +401,8 @@ int __init acpi_sleep_init(void)
	if (acpi_disabled)
		return 0;

#ifdef CONFIG_SUSPEND
printk(KERN_INFO PREFIX "(supports");
#ifdef CONFIG_SUSPEND
	for (i = ACPI_STATE_S0; i < ACPI_STATE_S4; i++) {
		status = acpi_get_sleep_type_data(i, &type_a, &type_b);
		if (ACPI_SUCCESS(status)) {
@@ -372,7 +410,6 @@ int __init acpi_sleep_init(void)
			printk(" S%d", i);
		}
	}
	printk(")\n");

	pm_set_ops(&acpi_pm_ops);
#endif
@@ -382,10 +419,16 @@ int __init acpi_sleep_init(void)
	if (ACPI_SUCCESS(status)) {
		hibernation_set_ops(&acpi_hibernation_ops);
		sleep_states[ACPI_STATE_S4] = 1;
		printk(" S4");
	}
#else
	sleep_states[ACPI_STATE_S4] = 0;
#endif

	status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
	if (ACPI_SUCCESS(status)) {
		sleep_states[ACPI_STATE_S5] = 1;
		printk(" S5");
		pm_power_off_prepare = acpi_power_off_prepare;
		pm_power_off = acpi_power_off;
	}
	printk(")\n");
	return 0;
}

drivers/acpi/sleep/poweroff.c

deleted100644 → 0
+0 −75
Original line number Diff line number Diff line
/*
 * poweroff.c - ACPI handler for powering off the system.
 *
 * AKA S5, but it is independent of whether or not the kernel supports
 * any other sleep support in the system.
 *
 * Copyright (c) 2005 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
 *
 * This file is released under the GPLv2.
 */

#include <linux/pm.h>
#include <linux/init.h>
#include <acpi/acpi_bus.h>
#include <linux/sysdev.h>
#include <asm/io.h>
#include "sleep.h"

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_gpe_sleep_prepare(acpi_state);
	acpi_enter_sleep_state_prep(acpi_state);
	return 0;
}

#ifdef CONFIG_PM

static void acpi_power_off_prepare(void)
{
	/* Prepare to power off the system */
	acpi_sleep_prepare(ACPI_STATE_S5);
}

static 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 */
	acpi_enter_sleep_state(ACPI_STATE_S5);
}

static int acpi_poweroff_init(void)
{
	if (!acpi_disabled) {
		u8 type_a, type_b;
		acpi_status status;

		status =
		    acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
		if (ACPI_SUCCESS(status)) {
			pm_power_off_prepare = acpi_power_off_prepare;
			pm_power_off = acpi_power_off;
		}
	}
	return 0;
}

late_initcall(acpi_poweroff_init);

#endif				/* CONFIG_PM */