summaryrefslogtreecommitdiff
path: root/chip/lm4/watchdog.c
diff options
context:
space:
mode:
Diffstat (limited to 'chip/lm4/watchdog.c')
-rw-r--r--chip/lm4/watchdog.c120
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;
-}