summaryrefslogtreecommitdiff
path: root/chip/lm4/gpio.c
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2012-03-19 10:59:38 -0700
committerRandall Spangler <rspangler@chromium.org>2012-03-19 15:41:14 -0700
commitb2ac77b37b66ce2e6e621743d5cd1510457cc19f (patch)
tree53a66e7092d8a1fc74f04178c805ec05eb77f637 /chip/lm4/gpio.c
parent1fd7062b29c685d98be8586ded4587e5e1e169ee (diff)
downloadchrome-ec-b2ac77b37b66ce2e6e621743d5cd1510457cc19f.tar.gz
Support warm reboot from one EC image to another.
This is necessary at init-time for verified boot to jump from RO to one of the RW images. It's also used by factory EC update to update one image and then jump to the updated image to finish the update. In this case, the x86 does NOT reboot. Signed-off-by: Randall Spangler <rspangler@chromium.org> BUG=chrome-os-partner:8449 TEST=manual 1) power on x86 and log in 2) sysjump a --> system is in a; x86 has not rebooted 3) sysjump ro --> system is back in RO; x86 has not rebooted 4) reboot -> system is in RO; x86 HAS rebooted Change-Id: I9dbadcf9775e146a0718abfd4ee0758b65350a87
Diffstat (limited to 'chip/lm4/gpio.c')
-rw-r--r--chip/lm4/gpio.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/chip/lm4/gpio.c b/chip/lm4/gpio.c
index 81b7312f03..a7c4f96163 100644
--- a/chip/lm4/gpio.c
+++ b/chip/lm4/gpio.c
@@ -16,7 +16,7 @@
/* 0-terminated list of GPIO bases */
-const uint32_t gpio_bases[] = {
+static const uint32_t gpio_bases[] = {
LM4_GPIO_A, LM4_GPIO_B, LM4_GPIO_C, LM4_GPIO_D,
LM4_GPIO_E, LM4_GPIO_F, LM4_GPIO_G, LM4_GPIO_H,
LM4_GPIO_J, LM4_GPIO_K, LM4_GPIO_L, LM4_GPIO_M,
@@ -45,12 +45,18 @@ int gpio_pre_init(void)
{
volatile uint32_t scratch __attribute__((unused));
const struct gpio_info *g = gpio_list;
+ int is_warm = 0;
int i;
- /* Enable clocks to all the GPIO blocks (since we use all of them as
- * GPIOs) */
- LM4_SYSTEM_RCGCGPIO |= 0x7fff;
- scratch = LM4_SYSTEM_RCGCGPIO; /* Delay a few clocks */
+ if (LM4_SYSTEM_RCGCGPIO == 0x7fff) {
+ /* This is a warm reboot */
+ is_warm = 1;
+ } else {
+ /* Enable clocks to all the GPIO blocks (since we use all of
+ * them as GPIOs) */
+ LM4_SYSTEM_RCGCGPIO |= 0x7fff;
+ scratch = LM4_SYSTEM_RCGCGPIO; /* Delay a few clocks */
+ }
/* Disable GPIO commit control for PD7 and PF0, since we don't use the
* NMI pin function. */
@@ -64,6 +70,10 @@ int gpio_pre_init(void)
/* Clear SSI0 alternate function on PA2:5 */
LM4_GPIO_AFSEL(LM4_GPIO_A) &= ~0x3c;
+ /* Mask all GPIO interrupts */
+ for (i = 0; gpio_bases[i]; i++)
+ LM4_GPIO_IM(gpio_bases[i]) = 0;
+
/* Set all GPIOs to defaults */
for (i = 0; i < GPIO_COUNT; i++, g++) {
@@ -76,7 +86,11 @@ int gpio_pre_init(void)
LM4_GPIO_DIR(g->port) |= g->mask;
/* Must set level after direction; writes to GPIO_DATA
* before direction is output appear to be ignored. */
- gpio_set_level(i, g->flags & GPIO_HIGH);
+ /* Only set level on a cold reboot; on a warm reboot we
+ * want to leave things where they were or we'll shut
+ * off the x86. */
+ if (!is_warm)
+ gpio_set_level(i, g->flags & GPIO_HIGH);
} else {
/* Input */
if (g->flags & GPIO_PULL) {