lynxpoint: fix enable_pm1() function

The new enable_pm1() function was doing 2 things wrong:

1. It was doing a RMW of the pm1 register. This means we were
   keeping around the enables from the OS during S3 resume. This
   is bad in the face of the RTC alarm waking us up because it would
   cause an infinite stream of SMIs.
2. The register size of PM1_EN is 16-bits. However, the previous
   implementation was accessing it as a 32-bit register.

The PM1 enables should only be set to what we expect to handle in the
firmware before the OS changes to ACPI mode.

Change-Id: Ib1d3caf6c84a1670d9456ed159420c6cb64f555e
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/2978
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
Aaron Durbin 2013-03-27 21:13:02 -05:00 committed by Ronald G. Minnich
parent bab0a0b577
commit d6d6db3717
2 changed files with 6 additions and 6 deletions

View File

@ -139,7 +139,7 @@ void enable_pm1_control(u32 mask);
void disable_pm1_control(u32 mask); void disable_pm1_control(u32 mask);
/* PM1 */ /* PM1 */
u16 clear_pm1_status(void); u16 clear_pm1_status(void);
void enable_pm1(u32 mask); void enable_pm1(u16 events);
u32 clear_smi_status(void); u32 clear_smi_status(void);
/* SMI */ /* SMI */
void enable_smi(u32 mask); void enable_smi(u32 mask);

View File

@ -29,6 +29,7 @@
#include <device/pci.h> #include <device/pci.h>
#include <device/pci_def.h> #include <device/pci_def.h>
#include <console/console.h> #include <console/console.h>
#include <pc80/mc146818rtc.h>
#include "pch.h" #include "pch.h"
#if CONFIG_INTEL_LYNXPOINT_LP #if CONFIG_INTEL_LYNXPOINT_LP
@ -104,6 +105,7 @@ static u16 reset_pm1_status(void)
{ {
u16 pm1_sts = inw(get_pmbase() + PM1_STS); u16 pm1_sts = inw(get_pmbase() + PM1_STS);
outw(pm1_sts, get_pmbase() + PM1_STS); outw(pm1_sts, get_pmbase() + PM1_STS);
return pm1_sts; return pm1_sts;
} }
@ -137,12 +139,10 @@ u16 clear_pm1_status(void)
return print_pm1_status(reset_pm1_status()); return print_pm1_status(reset_pm1_status());
} }
/* Enable PM1 event */ /* Set the PM1 register to events */
void enable_pm1(u32 mask) void enable_pm1(u16 events)
{ {
u32 pm1_en = inl(get_pmbase() + PM1_EN); outw(events, get_pmbase() + PM1_EN);
pm1_en |= mask;
outl(pm1_en, get_pmbase() + PM1_EN);
} }