#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/uaccess.h>
#include <linux/watchdog.h>
#include <linux/jiffies.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/resource.h>
#include <linux/platform_device.h>
#include <bcm63xx_regs.h>
#include <bcm63xx_timer.h>
#define PFX KBUILD_MODNAME
#define WDT_DEFAULT_TIME 30
static int wdt_time = WDT_DEFAULT_TIME;
static bool nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
static void bcm63xx_wdt_hw_start(void)
bcm_writel(0xfffffffe, bcm63xx_wdt_device.regs + WDT_DEFVAL_REG);
bcm_writel(WDT_START_1, bcm63xx_wdt_device.regs + WDT_CTL_REG);
bcm_writel(WDT_START_2, bcm63xx_wdt_device.regs + WDT_CTL_REG);
static void bcm63xx_wdt_hw_stop(void)
bcm_writel(WDT_STOP_1, bcm63xx_wdt_device.regs + WDT_CTL_REG);
bcm_writel(WDT_STOP_2, bcm63xx_wdt_device.regs + WDT_CTL_REG);
static void bcm63xx_wdt_isr(void *data)
struct pt_regs *regs = get_irq_regs();
static void bcm63xx_timer_tick(struct timer_list *unused)
if (!atomic_dec_and_test(&bcm63xx_wdt_device.ticks)) {
mod_timer(&bcm63xx_wdt_device.timer, jiffies + HZ);
pr_crit("watchdog will restart system\n");
static void bcm63xx_wdt_pet(void)
atomic_set(&bcm63xx_wdt_device.ticks, wdt_time);
static void bcm63xx_wdt_start(void)