haswell: fix driving of WAKE# pin on power button press

The WAKE# pin was being driven low when the power button was
pressed and no other events were occuring. This causes a PCIE
wake event to be observed on the host. This is incorrect. Therefore
only assert the WAKE# pin when any other event but the power button
has occured.

The implementation introduces a board-specific callback,
board_process_wake_events(), which handles the specific logic
for the wake events.

BUG=chrome-os-partner:19810
BRANCH=None
TEST=Manual. Both power button wakeup and lid events were tested. The
     presence of PCIE Wake no longer exists for S5->S0 transitions.

Change-Id: If1311ccc36629b04d2d9e021c3e103e379836a3a
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/56970
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
This commit is contained in:
Aaron Durbin
2013-05-29 11:54:47 -05:00
committed by ChromeBot
parent 7abe696281
commit 72a69f6669
6 changed files with 75 additions and 5 deletions

View File

@@ -11,6 +11,7 @@
#include "ec_commands.h"
#include "extpower.h"
#include "gpio.h"
#include "host_command.h"
#include "i2c.h"
#include "keyboard_scan.h"
#include "lid_switch.h"
@@ -179,3 +180,20 @@ void board_enable_wireless(uint8_t enabled)
gpio_set_level(GPIO_PP3300_LTE_EN,
enabled & EC_WIRELESS_SWITCH_WWAN);
}
/**
* Perform necessary actions on host wake events.
*/
void board_process_wake_events(uint32_t active_wake_events)
{
uint32_t power_button_mask;
power_button_mask = EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON);
/* If there are other events aside from the power button press drive
* the wake pin. Otherwise ensure it is high. */
if (active_wake_events & ~power_button_mask)
gpio_set_level(GPIO_PCH_WAKE_L, 0);
else
gpio_set_level(GPIO_PCH_WAKE_L, 1);
}

View File

@@ -215,3 +215,15 @@ void board_enable_wireless(uint8_t enabled)
gpio_set_level(GPIO_RADIO_ENABLE_BT,
enabled & EC_WIRELESS_SWITCH_BLUETOOTH);
}
/**
* Perform necessary actions on host events.
*/
void board_process_wake_events(uint32_t active_wake_events)
{
/* Update level-sensitive wake signal */
if (active_wake_events)
gpio_set_level(GPIO_PCH_WAKE_L, 0);
else
gpio_set_level(GPIO_PCH_WAKE_L, 1);
}

View File

@@ -11,6 +11,7 @@
#include "ec_commands.h"
#include "extpower.h"
#include "gpio.h"
#include "host_command.h"
#include "i2c.h"
#include "keyboard_scan.h"
#include "lid_switch.h"
@@ -185,3 +186,20 @@ void board_enable_wireless(uint8_t enabled)
gpio_set_level(GPIO_PP3300_LTE_EN,
enabled & EC_WIRELESS_SWITCH_WWAN);
}
/**
* Perform necessary actions on host wake events.
*/
void board_process_wake_events(uint32_t active_wake_events)
{
uint32_t power_button_mask;
power_button_mask = EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON);
/* If there are other events aside from the power button press drive
* the wake pin. Otherwise ensure it is high. */
if (active_wake_events & ~power_button_mask)
gpio_set_level(GPIO_PCH_WAKE_L, 0);
else
gpio_set_level(GPIO_PCH_WAKE_L, 1);
}

View File

@@ -11,6 +11,7 @@
#include "ec_commands.h"
#include "extpower.h"
#include "gpio.h"
#include "host_command.h"
#include "i2c.h"
#include "keyboard_scan.h"
#include "lid_switch.h"
@@ -182,3 +183,20 @@ void board_enable_wireless(uint8_t enabled)
gpio_set_level(GPIO_PP3300_LTE_EN,
enabled & EC_WIRELESS_SWITCH_WWAN);
}
/**
* Perform necessary actions on host wake events.
*/
void board_process_wake_events(uint32_t active_wake_events)
{
uint32_t power_button_mask;
power_button_mask = EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON);
/* If there are other events aside from the power button press drive
* the wake pin. Otherwise ensure it is high. */
if (active_wake_events & ~power_button_mask)
gpio_set_level(GPIO_PCH_WAKE_L, 0);
else
gpio_set_level(GPIO_PCH_WAKE_L, 1);
}

View File

@@ -284,6 +284,7 @@ void lpc_comx_put_char(int c)
static void update_host_event_status(void) {
int need_sci = 0;
int need_smi = 0;
uint32_t active_wake_events;
if (!init_done)
return;
@@ -311,11 +312,9 @@ static void update_host_event_status(void) {
task_enable_irq(LM4_IRQ_LPC);
/* Update level-sensitive wake signal */
if (host_events & event_mask[LPC_HOST_EVENT_WAKE])
gpio_set_level(GPIO_PCH_WAKE_L, 0);
else
gpio_set_level(GPIO_PCH_WAKE_L, 1);
/* Process the wake events. */
active_wake_events = host_events & event_mask[LPC_HOST_EVENT_WAKE];
board_process_wake_events(active_wake_events);
/* Send pulse on SMI signal if needed */
if (need_smi)

View File

@@ -114,6 +114,11 @@ void host_clear_events(uint32_t mask);
*/
uint32_t host_get_events(void);
/**
* Perform necessary actions on host wake events.
*/
void board_process_wake_events(uint32_t active_wake_events);
/**
* Send a response to the relevent driver for transmission
*