From 3f4b0ef7f2899c91b1d6958779f084b44dd59d32 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 26 Oct 2008 20:52:15 +0100 Subject: ACPI hibernate: Add a mechanism to save/restore ACPI NVS memory According to the ACPI Specification 3.0b, Section 15.3.2, "OSPM will call the _PTS control method some time before entering a sleeping state, to allow the platform's AML code to update this memory image before entering the sleeping state. After the system awakes from an S4 state, OSPM will restore this memory area and call the _WAK control method to enable the BIOS to reclaim its memory image." For this reason, implement a mechanism allowing us to save the NVS memory during hibernation and to restore it during the subsequent resume. Based on a patch by Zhang Rui. Signed-off-by: Rafael J. Wysocki Acked-by: Nigel Cunningham Cc: Zhang Rui Signed-off-by: Len Brown --- include/linux/suspend.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include/linux') diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 2ce8207686e2..2b409c44db83 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -232,6 +232,11 @@ extern unsigned long get_safe_page(gfp_t gfp_mask); extern void hibernation_set_ops(struct platform_hibernation_ops *ops); extern int hibernate(void); +extern int hibernate_nvs_register(unsigned long start, unsigned long size); +extern int hibernate_nvs_alloc(void); +extern void hibernate_nvs_free(void); +extern void hibernate_nvs_save(void); +extern void hibernate_nvs_restore(void); #else /* CONFIG_HIBERNATION */ static inline int swsusp_page_is_forbidden(struct page *p) { return 0; } static inline void swsusp_set_page_free(struct page *p) {} @@ -239,6 +244,14 @@ static inline void swsusp_unset_page_free(struct page *p) {} static inline void hibernation_set_ops(struct platform_hibernation_ops *ops) {} static inline int hibernate(void) { return -ENOSYS; } +static inline int hibernate_nvs_register(unsigned long a, unsigned long b) +{ + return 0; +} +static inline int hibernate_nvs_alloc(void) { return 0; } +static inline void hibernate_nvs_free(void) {} +static inline void hibernate_nvs_save(void) {} +static inline void hibernate_nvs_restore(void) {} #endif /* CONFIG_HIBERNATION */ #ifdef CONFIG_PM_SLEEP -- cgit v1.2.3 From ba84ed9546e91348fdf3ff2bff859b0ee53b407a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 26 Oct 2008 20:56:30 +0100 Subject: ACPI hibernate: Introduce new kernel parameter acpi_sleep=s4_nonvs On some machines it may be necessary to disable the saving/restoring of the ACPI NVS memory region during hibernation/resume. For this purpose, introduce new ACPI kernel command line option acpi_sleep=s4_nonvs. Based on a patch by Zhang Rui. Signed-off-by: Rafael J. Wysocki Acked-by: Nigel Cunningham Acked-by: Pavel Machek Signed-off-by: Len Brown --- Documentation/kernel-parameters.txt | 5 ++++- arch/x86/kernel/acpi/sleep.c | 2 ++ drivers/acpi/sleep/main.c | 18 ++++++++++++++++-- include/linux/acpi.h | 1 + 4 files changed, 23 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index e0f346d201ed..1d089eeff3cf 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -149,7 +149,8 @@ and is between 256 and 4096 characters. It is defined in the file default: 0 acpi_sleep= [HW,ACPI] Sleep options - Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig, old_ordering } + Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig, + old_ordering, s4_nonvs } See Documentation/power/video.txt for s3_bios and s3_mode. s3_beep is for debugging; it makes the PC's speaker beep as soon as the kernel's real-mode entry point is called. @@ -159,6 +160,8 @@ and is between 256 and 4096 characters. It is defined in the file control method, wrt putting devices into low power states, to be enforced (the ACPI 2.0 ordering of _PTS is used by default). + s4_nonvs prevents the kernel from saving/restoring the + ACPI NVS memory during hibernation. acpi_sci= [HW,ACPI] ACPI System Control Interrupt trigger mode Format: { level | edge | high | low } diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 806b4e9051b4..707c1f6f95fa 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c @@ -159,6 +159,8 @@ static int __init acpi_sleep_setup(char *str) #endif if (strncmp(str, "old_ordering", 12) == 0) acpi_old_suspend_ordering(); + if (strncmp(str, "s4_nonvs", 8) == 0) + acpi_s4_no_nvs(); str = strchr(str, ','); if (str != NULL) str += strspn(str, ", \t"); diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index 45a8015e4217..bef41fd4c877 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c @@ -101,6 +101,19 @@ void __init acpi_old_suspend_ordering(void) * cases. */ static bool set_sci_en_on_resume; +/* + * The ACPI specification wants us to save NVS memory regions during hibernation + * and to restore them during the subsequent resume. However, it is not certain + * if this mechanism is going to work on all machines, so we allow the user to + * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line + * option. + */ +static bool s4_no_nvs; + +void __init acpi_s4_no_nvs(void) +{ + s4_no_nvs = true; +} /** * acpi_pm_disable_gpes - Disable the GPEs. @@ -396,7 +409,7 @@ static int acpi_hibernation_begin(void) { int error; - error = hibernate_nvs_alloc(); + error = s4_no_nvs ? 0 : hibernate_nvs_alloc(); if (!error) { acpi_target_sleep_state = ACPI_STATE_S4; acpi_sleep_tts_switch(acpi_target_sleep_state); @@ -494,7 +507,8 @@ static int acpi_hibernation_begin_old(void) error = acpi_sleep_prepare(ACPI_STATE_S4); if (!error) { - error = hibernate_nvs_alloc(); + if (!s4_no_nvs) + error = hibernate_nvs_alloc(); if (!error) acpi_target_sleep_state = ACPI_STATE_S4; } diff --git a/include/linux/acpi.h b/include/linux/acpi.h index fba8051fb297..dfa0a5356c53 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -270,6 +270,7 @@ int acpi_check_mem_region(resource_size_t start, resource_size_t n, #ifdef CONFIG_PM_SLEEP void __init acpi_no_s4_hw_signature(void); void __init acpi_old_suspend_ordering(void); +void __init acpi_s4_no_nvs(void); #endif /* CONFIG_PM_SLEEP */ #else /* CONFIG_ACPI */ -- cgit v1.2.3 From f748bafa3ca1fb056e63afdeecacc1c68d8104df Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Mon, 8 Dec 2008 21:30:31 -0700 Subject: ACPI: PCI: move struct acpi_prt_entry declaration out of public header file The struct acpi_prt_entry is used only in pci_irq.c, so there's no need for the declaration to be public. This patch moves it into pci_irq.c. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown --- drivers/acpi/pci_irq.c | 16 ++++++++++++++++ include/linux/acpi.h | 16 ---------------- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'include/linux') diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 9302f4bb89e2..ea003bab7ecd 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -41,6 +41,22 @@ #define _COMPONENT ACPI_PCI_COMPONENT ACPI_MODULE_NAME("pci_irq"); +struct acpi_prt_entry { + struct list_head node; + struct acpi_pci_id id; + u8 pin; + struct { + acpi_handle handle; + u32 index; + } link; + u32 irq; +}; + +struct acpi_prt_list { + int count; + struct list_head entries; +}; + static struct acpi_prt_list acpi_prt; static DEFINE_SPINLOCK(acpi_prt_lock); diff --git a/include/linux/acpi.h b/include/linux/acpi.h index fba8051fb297..813f937b3ab4 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -131,22 +131,6 @@ extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity); */ void acpi_unregister_gsi (u32 gsi); -struct acpi_prt_entry { - struct list_head node; - struct acpi_pci_id id; - u8 pin; - struct { - acpi_handle handle; - u32 index; - } link; - u32 irq; -}; - -struct acpi_prt_list { - int count; - struct list_head entries; -}; - struct pci_dev; int acpi_pci_irq_enable (struct pci_dev *dev); -- cgit v1.2.3 From ea7e96e0f2277107d9ea14c3f16c86ba82b2e560 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Tue, 16 Dec 2008 16:28:17 +0800 Subject: ACPI: remove private acpica headers from driver files External driver files should not include any private acpica headers. Signed-off-by: Lin Ming Signed-off-by: Len Brown --- arch/ia64/include/asm/acpi-ext.h | 1 - arch/ia64/include/asm/sn/acpi.h | 2 -- arch/ia64/sn/kernel/io_acpi_init.c | 1 - arch/ia64/sn/kernel/io_common.c | 1 - drivers/acpi/cm_sbs.c | 3 --- drivers/acpi/debug.c | 1 - drivers/acpi/ec.c | 1 - drivers/acpi/numa.c | 1 - drivers/acpi/sbshc.c | 1 - drivers/acpi/scan.c | 1 - drivers/acpi/sleep/wakeup.c | 1 - drivers/ata/libata-acpi.c | 6 ------ drivers/ata/pata_acpi.c | 6 ------ drivers/char/tpm/tpm_bios.c | 2 -- drivers/ide/ide-acpi.c | 6 ------ drivers/misc/tc1100-wmi.c | 1 - drivers/misc/thinkpad_acpi.c | 1 - drivers/pci/hotplug/acpi_pcihp.c | 1 - drivers/pci/hotplug/pciehp.h | 1 - drivers/pci/pci-acpi.c | 2 -- drivers/pnp/pnpacpi/core.c | 1 - include/linux/pci_hotplug.h | 1 - 22 files changed, 42 deletions(-) (limited to 'include/linux') diff --git a/arch/ia64/include/asm/acpi-ext.h b/arch/ia64/include/asm/acpi-ext.h index 734d137dda6e..7f8362b379eb 100644 --- a/arch/ia64/include/asm/acpi-ext.h +++ b/arch/ia64/include/asm/acpi-ext.h @@ -14,7 +14,6 @@ #define _ASM_IA64_ACPI_EXT_H #include -#include extern acpi_status hp_acpi_csr_space (acpi_handle, u64 *base, u64 *length); diff --git a/arch/ia64/include/asm/sn/acpi.h b/arch/ia64/include/asm/sn/acpi.h index 9ce2801cbd57..fd480db25565 100644 --- a/arch/ia64/include/asm/sn/acpi.h +++ b/arch/ia64/include/asm/sn/acpi.h @@ -9,8 +9,6 @@ #ifndef _ASM_IA64_SN_ACPI_H #define _ASM_IA64_SN_ACPI_H -#include "acpi/acglobal.h" - extern int sn_acpi_rev; #define SN_ACPI_BASE_SUPPORT() (sn_acpi_rev >= 0x20101) diff --git a/arch/ia64/sn/kernel/io_acpi_init.c b/arch/ia64/sn/kernel/io_acpi_init.c index 4c8bc8eee5ad..c5a214026a77 100644 --- a/arch/ia64/sn/kernel/io_acpi_init.c +++ b/arch/ia64/sn/kernel/io_acpi_init.c @@ -13,7 +13,6 @@ #include #include "xtalk/hubdev.h" #include -#include /* diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c index e1917ede0d60..0d4ffa4da1da 100644 --- a/arch/ia64/sn/kernel/io_common.c +++ b/arch/ia64/sn/kernel/io_common.c @@ -26,7 +26,6 @@ #include #include #include -#include "acpi/acglobal.h" extern void sn_init_cpei_timer(void); extern void register_sn_procfs(void); diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c index 307963bd1043..332fe4b21708 100644 --- a/drivers/acpi/cm_sbs.c +++ b/drivers/acpi/cm_sbs.c @@ -27,9 +27,6 @@ #include #include #include -#include -#include -#include ACPI_MODULE_NAME("cm_sbs"); #define ACPI_AC_CLASS "ac_adapter" diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c index c48396892008..20223cbd0d1c 100644 --- a/drivers/acpi/debug.c +++ b/drivers/acpi/debug.c @@ -9,7 +9,6 @@ #include #include #include -#include #define _COMPONENT ACPI_SYSTEM_COMPONENT ACPI_MODULE_NAME("debug"); diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 2cbc2c9c07ac..3105e0410e9b 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -42,7 +42,6 @@ #include #include #include -#include #define ACPI_EC_CLASS "embedded_controller" #define ACPI_EC_DEVICE_NAME "Embedded Controller" diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 25ceae9191ef..c5e292aab0e3 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c @@ -29,7 +29,6 @@ #include #include #include -#include #define ACPI_NUMA 0x80000000 #define _COMPONENT ACPI_NUMA diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c index e53e590252c0..0619734895b2 100644 --- a/drivers/acpi/sbshc.c +++ b/drivers/acpi/sbshc.c @@ -10,7 +10,6 @@ #include #include -#include #include #include #include diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 39b7233c3485..c54d7b6c4066 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -10,7 +10,6 @@ #include #include -#include /* for acpi_ex_eisa_id_to_string() */ #define _COMPONENT ACPI_BUS_COMPONENT ACPI_MODULE_NAME("scan"); diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c index db325c28a1fb..2d34806d45dd 100644 --- a/drivers/acpi/sleep/wakeup.c +++ b/drivers/acpi/sleep/wakeup.c @@ -8,7 +8,6 @@ #include #include #include -#include #include "sleep.h" #define _COMPONENT ACPI_SYSTEM_COMPONENT diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index c012307d0ba6..246987f0b88c 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -19,12 +19,6 @@ #include "libata.h" #include -#include -#include -#include -#include -#include -#include enum { ATA_ACPI_FILTER_SETXFER = 1 << 0, diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c index e2e332d8ff95..8b77a9802df1 100644 --- a/drivers/ata/pata_acpi.c +++ b/drivers/ata/pata_acpi.c @@ -13,12 +13,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include #include #include diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c index 68f052b42ed7..ed306eb1057f 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_bios.c @@ -23,8 +23,6 @@ #include #include #include -#include -#include #include "tpm.h" #define TCG_EVENT_NAME_LEN_MAX 255 diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index 244a8a052ce8..9e8d52a4f306 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c @@ -18,12 +18,6 @@ #include #include -#include -#include -#include -#include -#include -#include #define REGS_PER_GTF 7 struct taskfile_array { diff --git a/drivers/misc/tc1100-wmi.c b/drivers/misc/tc1100-wmi.c index f25e4c974dcf..b4a4aa9ee482 100644 --- a/drivers/misc/tc1100-wmi.c +++ b/drivers/misc/tc1100-wmi.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 899766e16fa8..3478453eba7a 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -76,7 +76,6 @@ #include #include -#include #include diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index e17ef54f0efc..2c981cbb0719 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c @@ -33,7 +33,6 @@ #include #include #include -#include #define MY_NAME "acpi_pcihp" diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index b2801a7ee37f..7072952ea1d2 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -217,7 +217,6 @@ struct hpc_ops { #ifdef CONFIG_ACPI #include #include -#include #include static inline int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev) diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index ae5ec76dca77..9d976d51d406 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -13,8 +13,6 @@ #include #include #include -#include -#include #include #include diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 383e47c392a4..2834846a185d 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -23,7 +23,6 @@ #include #include #include -#include #include "../base.h" #include "pnpacpi.h" diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h index a00bd1a0f156..c2d1a7d1886a 100644 --- a/include/linux/pci_hotplug.h +++ b/include/linux/pci_hotplug.h @@ -223,7 +223,6 @@ struct hotplug_params { #ifdef CONFIG_ACPI #include #include -#include extern acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus, struct hotplug_params *hpp); int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags); -- cgit v1.2.3