summaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-24 08:25:15 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-24 08:25:15 -0700
commit047f61c5d16d617e1df2deea5c5d5fb2a1b41c95 (patch)
tree75d51e1813664ad54fa680a0ecfb2b756d3d4b0f /arch/x86
parent05061bf678de5d69ebaae2c0705bf106e3000b6e (diff)
parent3d26678e8009b03f27674c2f9e5b236c2f627b14 (diff)
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (42 commits) ACPI: minor printk format change in acpi_pad ACPI: make acpi_pad /sys output more readable ACPICA: Update version to 20110316 ACPICA: Header support for SLIC table ACPI: Make sure the FADT is at least rev 2 before using the reset register ACPI: Bug compatibility for Windows on the ACPI reboot vector ACPICA: Fix access width for reset vector ACPI battery: fribble sysfs files from a resume notifier ACPI button: remove unused procfs I/F ACPI, APEI, Add PCIe AER error information printing support PCIe, AER, use pre-generated prefix in error information printing ACPI, APEI, Add ERST record ID cache ACPI: Use syscore_ops instead of sysdev class and sysdev ACPI: Remove the unused EC sysdev class ACPI: use __cpuinit for the acpi_processor_set_pdc() call tree ACPI: use __init where possible in processor driver Thermal_Framework-Fix_crash_during_hwmon_unregister ACPICA: Update version to 20110211. ACPICA: Add mechanism to defer _REG methods for some installed handlers ACPICA: Add support for FunctionalFixedHW in acpi_ut_get_region_name ...
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/include/asm/acpi.h5
-rw-r--r--arch/x86/kernel/acpi/sleep.c12
-rw-r--r--arch/x86/kernel/acpi/sleep.h2
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce-apei.c42
4 files changed, 33 insertions, 28 deletions
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index 448d73a371b..12e0e7dd869 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -114,9 +114,8 @@ static inline void acpi_disable_pci(void)
acpi_noirq_set();
}
-/* routines for saving/restoring kernel state */
-extern int acpi_save_state_mem(void);
-extern void acpi_restore_state_mem(void);
+/* Low-level suspend routine. */
+extern int acpi_suspend_lowlevel(void);
extern const unsigned char acpi_wakeup_code[];
#define acpi_wakeup_address (__pa(TRAMPOLINE_SYM(acpi_wakeup_code)))
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 4572c58e66d..ff93bc1b09c 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -25,12 +25,12 @@ static char temp_stack[4096];
#endif
/**
- * acpi_save_state_mem - save kernel state
+ * acpi_suspend_lowlevel - save kernel state
*
* Create an identity mapped page table and copy the wakeup routine to
* low memory.
*/
-int acpi_save_state_mem(void)
+int acpi_suspend_lowlevel(void)
{
struct wakeup_header *header;
/* address in low memory of the wakeup routine. */
@@ -96,16 +96,10 @@ int acpi_save_state_mem(void)
saved_magic = 0x123456789abcdef0L;
#endif /* CONFIG_64BIT */
+ do_suspend_lowlevel();
return 0;
}
-/*
- * acpi_restore_state - undo effects of acpi_save_state_mem
- */
-void acpi_restore_state_mem(void)
-{
-}
-
static int __init acpi_sleep_setup(char *str)
{
while ((str != NULL) && (*str != '\0')) {
diff --git a/arch/x86/kernel/acpi/sleep.h b/arch/x86/kernel/acpi/sleep.h
index 86ba1c87165..416d4be13fe 100644
--- a/arch/x86/kernel/acpi/sleep.h
+++ b/arch/x86/kernel/acpi/sleep.h
@@ -11,3 +11,5 @@ extern int wakeup_pmode_return;
extern unsigned long acpi_copy_wakeup_routine(unsigned long);
extern void wakeup_long64(void);
+
+extern void do_suspend_lowlevel(void);
diff --git a/arch/x86/kernel/cpu/mcheck/mce-apei.c b/arch/x86/kernel/cpu/mcheck/mce-apei.c
index 8209472b27a..83930deec3c 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-apei.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-apei.c
@@ -106,24 +106,34 @@ int apei_write_mce(struct mce *m)
ssize_t apei_read_mce(struct mce *m, u64 *record_id)
{
struct cper_mce_record rcd;
- ssize_t len;
-
- len = erst_read_next(&rcd.hdr, sizeof(rcd));
- if (len <= 0)
- return len;
- /* Can not skip other records in storage via ERST unless clear them */
- else if (len != sizeof(rcd) ||
- uuid_le_cmp(rcd.hdr.creator_id, CPER_CREATOR_MCE)) {
- if (printk_ratelimit())
- pr_warning(
- "MCE-APEI: Can not skip the unknown record in ERST");
- return -EIO;
- }
-
+ int rc, pos;
+
+ rc = erst_get_record_id_begin(&pos);
+ if (rc)
+ return rc;
+retry:
+ rc = erst_get_record_id_next(&pos, record_id);
+ if (rc)
+ goto out;
+ /* no more record */
+ if (*record_id == APEI_ERST_INVALID_RECORD_ID)
+ goto out;
+ rc = erst_read(*record_id, &rcd.hdr, sizeof(rcd));
+ /* someone else has cleared the record, try next one */
+ if (rc == -ENOENT)
+ goto retry;
+ else if (rc < 0)
+ goto out;
+ /* try to skip other type records in storage */
+ else if (rc != sizeof(rcd) ||
+ uuid_le_cmp(rcd.hdr.creator_id, CPER_CREATOR_MCE))
+ goto retry;
memcpy(m, &rcd.mce, sizeof(*m));
- *record_id = rcd.hdr.record_id;
+ rc = sizeof(*m);
+out:
+ erst_get_record_id_end();
- return sizeof(*m);
+ return rc;
}
/* Check whether there is record in ERST */