diff options
author | Louis Yung-Chieh Lo <yjlou@chromium.org> | 2013-11-15 15:49:56 -0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2013-11-19 06:06:52 +0000 |
commit | 082d8b2e2d992b12a5eded68ce7723c85e7b9318 (patch) | |
tree | 7672af22c0a781031247fdace3dfb452a7800bd7 /power | |
parent | 02995b2d6fd089b74b773b47fd10c4bff779ce4b (diff) | |
download | chrome-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.c | 41 |
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; |