summaryrefslogtreecommitdiff
path: root/power
diff options
context:
space:
mode:
authorLouis Yung-Chieh Lo <yjlou@chromium.org>2013-11-15 15:49:56 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2013-11-19 06:06:52 +0000
commit082d8b2e2d992b12a5eded68ce7723c85e7b9318 (patch)
tree7672af22c0a781031247fdace3dfb452a7800bd7 /power
parent02995b2d6fd089b74b773b47fd10c4bff779ce4b (diff)
downloadchrome-ec-082d8b2e2d992b12a5eded68ce7723c85e7b9318.tar.gz
nyan: supports immediate 'power off'.
Poll down AP_RESET_L pin to shutdown AP immediately, instead of press the power button for 8 secs. BRANCH=nyan BUG=chrome-os-partner:23895 TEST=verified on nyan board 2.0 with follwoing tests: power off / power on: PASS. Tested 5+ times. lid close / power off / lid open: PASS. Tested 5+ times. button on / off: PASS. Test 5+ times. ~20% not boot (HOLD=1). power off / button on: PASS. Tested 5+ times. button off / power on: PASS. Test 5+ times. ~60% not boot (HOLD=1) button off / lid open: PASS. Test 5+ times. ~40% not boot (HOLD=1) Change-Id: Iecc97f38ac7bd923745994594356029836d7b4e6 Signed-off-by: Louis Yung-Chieh Lo <yjlou@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/177241
Diffstat (limited to 'power')
-rw-r--r--power/tegra.c41
1 files changed, 30 insertions, 11 deletions
diff --git a/power/tegra.c b/power/tegra.c
index 18b39ea7fe..ed756ed843 100644
--- a/power/tegra.c
+++ b/power/tegra.c
@@ -144,6 +144,18 @@ static void set_pmic_pwrok(int asserted)
}
/**
+ * Set the AP RESET signal.
+ *
+ * @param asserted Assert (=1) or deassert (=0) the signal. This is the
+ * logical level of the pin, not the physical level.
+ */
+static void set_ap_reset(int asserted)
+{
+ /* Signal is active-low */
+ gpio_set_level(GPIO_AP_RESET_L, asserted ? 0 : 1);
+}
+
+/**
* Check for some event triggering the shutdown.
*
* It can be either a long power button press or a shutdown triggered from the
@@ -158,19 +170,14 @@ static int check_for_power_off_event(void)
/*
* Check for power button press.
- *
- * If power_request is POWER_REQ_OFF, simulate the requst as power
- * button is pressed. This will casue GPIO_PMIC_PWRON_L to be driven
- * low (by set_pmic_pwrok(1)) until PMIC automatically turns off power.
- * (PMIC turns off power if GPIO_PMIC_PWRON_L is low for >=9 seconds.)
*/
if (gpio_get_level(GPIO_KB_PWR_ON_L) == 0) {
udelay(KB_PWR_ON_DEBOUNCE);
if (gpio_get_level(GPIO_KB_PWR_ON_L) == 0)
pressed = 1;
} else if (power_request == POWER_REQ_OFF) {
- pressed = 1;
power_request = POWER_REQ_NONE;
+ return 4; /* return non-zero for shudown down */
}
#ifdef HAS_TASK_KEYSCAN
@@ -334,6 +341,10 @@ void chipset_reset(int is_cold)
void chipset_force_shutdown(void)
{
+ /* Assert AP reset to shutdown immediately */
+ set_ap_reset(1);
+
+ /* Release the power button, if it was asserted */
set_pmic_pwrok(0);
}
@@ -349,8 +360,13 @@ void chipset_force_shutdown(void)
*/
static int check_for_power_on_event(void)
{
- /* check if system is already ON */
- if (gpio_get_level(GPIO_SOC1V8_XPSHOLD)) {
+ /*
+ * check if system is already ON:
+ * 1. XPSHOLD is high (power is supplied), and
+ * 2. AP_RESET_L is high (not a force shutdown).
+ */
+ if (gpio_get_level(GPIO_SOC1V8_XPSHOLD) &&
+ gpio_get_level(GPIO_AP_RESET_L)) {
CPRINTF("[%T system is on, thus clear auto_power_on]\n");
auto_power_on = 0; /* no need to arrange another power on */
return 1;
@@ -390,11 +406,14 @@ static int check_for_power_on_event(void)
*/
static int power_on(void)
{
- gpio_set_level(GPIO_AP_RESET_L, 1);
+ /* Make sure we de-assert the AP_RESET_L pin. */
+ set_ap_reset(0);
+
+ /* Push the power button */
set_pmic_pwrok(1);
- if (gpio_get_level(GPIO_SOC1V8_XPSHOLD) == 0)
- /* Initialize non-AP components */
+ /* Initialize non-AP components if the AP is off. */
+ if (!ap_on)
hook_notify(HOOK_CHIPSET_PRE_INIT);
ap_on = 1;