diff options
Diffstat (limited to 'chip/lm4/watchdog.c')
-rw-r--r-- | chip/lm4/watchdog.c | 120 |
1 files changed, 0 insertions, 120 deletions
diff --git a/chip/lm4/watchdog.c b/chip/lm4/watchdog.c deleted file mode 100644 index 50f122bf02..0000000000 --- a/chip/lm4/watchdog.c +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2012 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Watchdog driver */ - -#include "clock.h" -#include "common.h" -#include "registers.h" -#include "gpio.h" -#include "hooks.h" -#include "task.h" -#include "util.h" -#include "watchdog.h" - -/* - * We use watchdog 0 which is clocked on the system clock - * to avoid the penalty cycles on each write access - */ - -/* magic value to unlock the watchdog registers */ -#define LM4_WATCHDOG_MAGIC_WORD 0x1ACCE551 - -static uint32_t watchdog_period; /* Watchdog counter initial value */ - -void IRQ_HANDLER(LM4_IRQ_WATCHDOG)(void) __attribute__((naked)); -void IRQ_HANDLER(LM4_IRQ_WATCHDOG)(void) -{ - /* Naked call so we can extract raw LR and SP */ - asm volatile("mov r0, lr\n" - "mov r1, sp\n" - /* Must push registers in pairs to keep 64-bit aligned - * stack for ARM EABI. This also conveniently saves - * R0=LR so we can pass it to task_resched_if_needed. */ - "push {r0, lr}\n" - "bl watchdog_trace\n" - /* Do NOT reset the watchdog interrupt here; it will - * be done in watchdog_reload(), or reset will be - * triggered if we don't call that by the next watchdog - * period. Instead, de-activate the interrupt in the - * NVIC, so the watchdog trace will only be printed - * once. - */ - "mov r0, %[irq]\n" - "bl task_disable_irq\n" - "pop {r0, lr}\n" - "b task_resched_if_needed\n" - : : [irq] "i" (LM4_IRQ_WATCHDOG)); -} -const struct irq_priority __keep IRQ_PRIORITY(LM4_IRQ_WATCHDOG) - __attribute__((section(".rodata.irqprio"))) - = {LM4_IRQ_WATCHDOG, 0}; /* put the watchdog at the highest - priority */ - -void watchdog_reload(void) -{ - uint32_t status = LM4_WATCHDOG_RIS(0); - - /* Unlock watchdog registers */ - LM4_WATCHDOG_LOCK(0) = LM4_WATCHDOG_MAGIC_WORD; - - /* As we reboot only on the second timeout, if we have already reached - * the first timeout we need to reset the interrupt bit. */ - if (status) { - LM4_WATCHDOG_ICR(0) = status; - /* That doesn't seem to unpend the watchdog interrupt (even if - * we do writes to force the write to be committed), so - * explicitly unpend the interrupt before re-enabling it. */ - task_clear_pending_irq(LM4_IRQ_WATCHDOG); - task_enable_irq(LM4_IRQ_WATCHDOG); - } - - /* Reload the watchdog counter */ - LM4_WATCHDOG_LOAD(0) = watchdog_period; - - /* Re-lock watchdog registers */ - LM4_WATCHDOG_LOCK(0) = 0xdeaddead; -} -DECLARE_HOOK(HOOK_TICK, watchdog_reload, HOOK_PRIO_DEFAULT); - -static void watchdog_freq_changed(void) -{ - /* Set the timeout period */ - watchdog_period = CONFIG_WATCHDOG_PERIOD_MS * (clock_get_freq() / 1000); - - /* Reload the watchdog timer now */ - watchdog_reload(); -} -DECLARE_HOOK(HOOK_FREQ_CHANGE, watchdog_freq_changed, HOOK_PRIO_DEFAULT); - -int watchdog_init(void) -{ - /* Enable watchdog 0 clock in run, sleep, and deep sleep modes */ - clock_enable_peripheral(CGC_OFFSET_WD, 0x1, CGC_MODE_ALL); - - /* Set initial timeout period */ - watchdog_freq_changed(); - - /* Unlock watchdog registers */ - LM4_WATCHDOG_LOCK(0) = LM4_WATCHDOG_MAGIC_WORD; - - /* De-activate the watchdog when the JTAG stops the CPU */ - LM4_WATCHDOG_TEST(0) |= BIT(8); - - /* Reset after 2 time-out, activate the watchdog and lock the control - * register. */ - LM4_WATCHDOG_CTL(0) = 0x3; - - /* Reset watchdog interrupt bits */ - LM4_WATCHDOG_ICR(0) = LM4_WATCHDOG_RIS(0); - - /* Lock watchdog registers against unintended accesses */ - LM4_WATCHDOG_LOCK(0) = 0xdeaddead; - - /* Enable watchdog interrupt */ - task_enable_irq(LM4_IRQ_WATCHDOG); - - return EC_SUCCESS; -} |