/*
 * Octeon Watchdog driver
 *
 * Copyright (C) 2007, 2008, 2009, 2010 Cavium Networks
 *
 * Some parts derived from wdt.c
 *
 *	(c) Copyright 1996-1997 Alan Cox <alan@lxorguk.ukuu.org.uk>,
 *						All Rights Reserved.
 *
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License
 *	as published by the Free Software Foundation; either version
 *	2 of the License, or (at your option) any later version.
 *
 *	Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
 *	warranty for any of this software. This material is provided
 *	"AS-IS" and at no charge.
 *
 *	(c) Copyright 1995    Alan Cox <alan@lxorguk.ukuu.org.uk>
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 *
 * The OCTEON watchdog has a maximum timeout of 2^32 * io_clock.
 * For most systems this is less than 10 seconds, so to allow for
 * software to request longer watchdog heartbeats, we maintain software
 * counters to count multiples of the base rate.  If the system locks
 * up in such a manner that we can not run the software counters, the
 * only result is a watchdog reset sooner than was requested.  But
 * that is OK, because in this case userspace would likely not be able
 * to do anything anyhow.
 *
 * The hardware watchdog interval we call the period.  The OCTEON
 * watchdog goes through several stages, after the first period an
 * irq is asserted, then if it is not reset, after the next period NMI
 * is asserted, then after an additional period a chip wide soft reset.
 * So for the software counters, we reset watchdog after each period
 * and decrement the counter.  But for the last two periods we need to
 * let the watchdog progress to the NMI stage so we disable the irq
 * and let it proceed.  Once in the NMI, we print the register state
 * to the serial port and then wait for the reset.
 *
 * A watchdog is maintained for each CPU in the system, that way if
 * one CPU suffers a lockup, we also get a register dump and reset.
 * The userspace ping resets the watchdog on all CPUs.
 *
 * Before userspace opens the watchdog device, we still run the
 * watchdogs to catch any lockups that may be kernel related.
 *
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/miscdevice.h>
#include <linux/interrupt.h>
#include <linux/watchdog.h>
#include <linux/cpumask.h>
#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/cpu.h>
#include <linux/smp.h>
#include <linux/fs.h>
#include <linux/irq.h>

#include <asm/mipsregs.h>
#include <asm/uasm.h>

#include <asm/octeon/octeon.h>

/* The count needed to achieve timeout_sec. */
static unsigned int timeout_cnt;

/* The maximum period supported. */
static unsigned int max_timeout_sec;

/* The current period.  */
static unsigned int timeout_sec;

/* Set to non-zero when userspace countdown mode active */
static int do_coundown;
static unsigned int countdown_reset;
static unsigned int per_cpu_countdown[NR_CPUS];

static cpumask_t irq_enabled_cpus;

#define WD_TIMO 60			/* Default heartbeat = 60 seconds */

static int heartbeat = WD_TIMO;
module_param(heartbeat, int, S_IRUGO);
MODULE_PARM_DESC(heartbeat,
	"Watchdog heartbeat in seconds. (0 < heartbeat, default="
				__MODULE_STRING(WD_TIMO) ")");

static bool nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, bool, S_IRUGO);
MODULE_PARM_DESC(nowayout,
	"Watchdog cannot be stopped once started (default="
				__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");

static unsigned long octeon_wdt_is_open;
static char expect_close;

static u32 __initdata nmi_stage1_insns[64];
/* We need one branch and therefore one relocation per target label. */
static struct uasm_label __initdata labels[5];
static struct uasm_reloc __initdata relocs[5];

enum lable_id {
	label_enter_bootloader = 1
};

/* Some CP0 registers */
#define K0		26
#define C0_CVMMEMCTL 11, 7
#define C0_STATUS 12, 0
#define C0_EBASE 15, 1
#define C0_DESAVE 31, 0

void octeon_wdt_nmi_stage2(void);

static void __init octeon_wdt_build_stage1(void)
{
	int i;
	int len;
	u32 *p = nmi_stage1_insns;
#ifdef CONFIG_HOTPLUG_CPU
	struct uasm_label *l = labels;
	struct uasm_reloc *r = relocs;
#endif

	/*
	 * For the next few instructions running the debugger may
	 * cause corruption of k0 in the saved registers. Since we're
	 * about to crash, nobody probably cares.
	 *
	 * Save K0 into the debug scratch register
	 */
	uasm_i_dmtc0(&p, K0, C0_DESAVE);

	uasm_i_mfc0(&p, K0, C0_STATUS);
#ifdef CONFIG_HOTPLUG_CPU
	uasm_il_bbit0(&p, &r, K0, ilog2(ST0_NMI), label_enter_bootloader);
#endif
	/* Force 64-bit addressing enabled */
	uasm_i_ori(&p, K0, K0, ST0_UX | ST0_SX | ST0_KX);
	uasm_i_mtc0(&p, K0, C0_STATUS);

#ifdef CONFIG_HOTPLUG_CPU
	uasm_i_mfc0(&p, K0, C0_EBASE);
	/* Coreid number in K0 */
	uasm_i_andi(&p, K0, K0, 0xf);
	/* 8 * coreid in bits 16-31 */
	uasm_i_dsll_safe(&p, K0, K0, 3 + 16);
	uasm_i_ori(&p, K0, K0, 0x8001);
	uasm_i_dsll_safe(&p, K0, K0, 16);
	uasm_i_ori(&p, K0, K0, 0x0700);
	uasm_i_drotr_safe(&p, K0, K0, 32);
	/*
	 * Should result in: 0x8001,0700,0000,8*coreid which is
	 * CVMX_CIU_WDOGX(coreid) - 0x0500
	 *
	 * Now ld K0, CVMX_CIU_WDOGX(coreid)
	 */
	uasm_i_ld(&p, K0, 0x500, K0);
	/*
	 * If bit one set handle the NMI as a watchdog event.
	 * otherwise transfer control to bootloader.
	 */
	uasm_il_bbit0(&p, &r, K0, 1, label_enter_bootloader);
	uasm_i_nop(&p);
#endif

	/* Clear Dcache so cvmseg works right. */
	uasm_i_cache(&p, 1, 0, 0);

	/* Use K0 to do a read/modify/write of CVMMEMCTL */
	uasm_i_dmfc0(&p, K0, C0_CVMMEMCTL);
	/* Clear out the size of CVMSEG	*/
	uasm_i_dins(&p, K0, 0, 0, 6);
	/* Set CVMSEG to its largest value */
	uasm_i_ori(&p, K0, K0, 0x1c0 | 54);
	/* Store the CVMMEMCTL value */
	uasm_i_dmtc0(&p, K0, C0_CVMMEMCTL);

	/* Load the address of the second stage handler */
	UASM_i_LA(&p, K0, (long)octeon_wdt_nmi_stage2);
	uasm_i_jr(&p, K0);
	uasm_i_dmfc0(&p, K0, C0_DESAVE);

#ifdef CONFIG_HOTPLUG_CPU
	uasm_build_label(&l, p, label_enter_bootloader);
	/* Jump to the bootloader and restore K0 */
	UASM_i_LA(&p, K0, (long)octeon_bootloader_entry_addr);
	uasm_i_jr(&p, K0);
	uasm_i_dmfc0(&p, K0, C0_DESAVE);
#endif
	uasm_resolve_relocs(relocs, labels);

	len = (int)(p - nmi_stage1_insns);
	pr_debug("Synthesized NMI stage 1 handler (%d instructions)\n", len);

	pr_debug("\t.set push\n");
	pr_debug("\t.set noreorder\n");
	for (i = 0; i < len; i++)
		pr_debug("\t.word 0x%08x\n", nmi_stage1_insns[i]);
	pr_debug("\t.set pop\n");

	if (len > 32)
		panic("NMI stage 1 handler exceeds 32 instructions, was %d\n", len);
}

static int cpu2core(int cpu)
{
#ifdef CONFIG_SMP
	return cpu_logical_map(cpu);
#else
	return cvmx_get_core_num();
#endif
}

static int core2cpu(int coreid)
{
#ifdef CONFIG_SMP
	return cpu_number_map(coreid);
#else
	return 0;
#endif
}

/**
 * Poke the watchdog when an interrupt is received
 *
 * @cpl:
 * @dev_id:
 *
 * Returns
 */
static irqreturn_t octeon_wdt_poke_irq(int cpl, void *dev_id)
{
	unsigned int core = cvmx_get_core_num();
	int cpu = core2cpu(core);

	if (do_coundown) {
		if (per_cpu_countdown[cpu] > 0) {
			/* We're alive, poke the watchdog */
			cvmx_write_csr(CVMX_CIU_PP_POKEX(core), 1);
			per_cpu_countdown[cpu]--;
		} else {
			/* Bad news, you are about to reboot. */
			disable_irq_nosync(cpl);
			cpumask_clear_cpu(cpu, &irq_enabled_cpus);
		}
	} else {
		/* Not open, just ping away... */
		cvmx_write_csr(CVMX_CIU_PP_POKEX(core), 1);
	}
	return IRQ_HANDLED;
}

/* From setup.c */
extern int prom_putchar(char c);

/**
 * Write a string to the uart
 *
 * @str:        String to write
 */
static void octeon_wdt_write_string(const char *str)
{
	/* Just loop writing one byte at a time */
	while (*str)
		prom_putchar(*str++);
}

/**
 * Write a hex number out of the uart
 *
 * @value:      Number to display
 * @digits:     Number of digits to print (1 to 16)
 */
static void octeon_wdt_write_hex(u64 value, int digits)
{
	int d;
	int v;
	for (d = 0; d < digits; d++) {
		v = (value >> ((digits - d - 1) * 4)) & 0xf;
		if (v >= 10)
			prom_putchar('a' + v - 10);
		else
			prom_putchar('0' + v);
	}
}

const char *reg_name[] = {
	"$0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
	"a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
	"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
	"t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
};

/**
 * NMI stage 3 handler. NMIs are handled in the following manner:
 * 1) The first NMI handler enables CVMSEG and transfers from
 * the bootbus region into normal memory. It is careful to not
 * destroy any registers.
 * 2) The second stage handler uses CVMSEG to save the registers
 * and create a stack for C code. It then calls the third level
 * handler with one argument, a pointer to the register values.
 * 3) The third, and final, level handler is the following C
 * function that prints out some useful infomration.
 *
 * @reg:    Pointer to register state before the NMI
 */
void octeon_wdt_nmi_stage3(u64 reg[32])
{
	u64 i;

	unsigned int coreid = cvmx_get_core_num();
	/*
	 * Save status and cause early to get them before any changes
	 * might happen.
	 */
	u64 cp0_cause = read_c0_cause();
	u64 cp0_status = read_c0_status();
	u64 cp0_error_epc = read_c0_errorepc();
	u64 cp0_epc = read_c0_epc();

	/* Delay so output from all cores output is not jumbled together. */
	__delay(100000000ull * coreid);

	octeon_wdt_write_string("\r\n*** NMI Watchdog interrupt on Core 0x");
	octeon_wdt_write_hex(coreid, 1);
	octeon_wdt_write_string(" ***\r\n");
	for (i = 0; i < 32; i++) {
		octeon_wdt_write_string("\t");
		octeon_wdt_write_string(reg_name[i]);
		octeon_wdt_write_string("\t0x");
		octeon_wdt_write_hex(reg[i], 16);
		if (i & 1)
			octeon_wdt_write_string("\r\n");
	}
	octeon_wdt_write_string("\terr_epc\t0x");
	octeon_wdt_write_hex(cp0_error_epc, 16);

	octeon_wdt_write_string("\tepc\t0x");
	octeon_wdt_write_hex(cp0_epc, 16);
	octeon_wdt_write_string("\r\n");

	octeon_wdt_write_string("\tstatus\t0x");
	octeon_wdt_write_hex(cp0_status, 16);
	octeon_wdt_write_string("\tcause\t0x");
	octeon_wdt_write_hex(cp0_cause, 16);
	octeon_wdt_write_string("\r\n");

	octeon_wdt_write_string("\tsum0\t0x");
	octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU_INTX_SUM0(coreid * 2)), 16);
	octeon_wdt_write_string("\ten0\t0x");
	octeon_wdt_write_hex(cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2)), 16);
	octeon_wdt_write_string("\r\n");

	octeon_wdt_write_string("*** Chip soft reset soon ***\r\n");
}

static void octeon_wdt_disable_interrupt(int cpu)
{
	unsigned int core;
	unsigned int irq;
	union cvmx_ciu_wdogx ciu_wdog;

	core = cpu2core(cpu);

	irq = OCTEON_IRQ_WDOG0 + core;

	/* Poke the watchdog to clear out its state */
	cvmx_write_csr(CVMX_CIU_PP_POKEX(core), 1);

	/* Disable the hardware. */
	ciu_wdog.u64 = 0;
	cvmx_write_csr(CVMX_CIU_WDOGX(core), ciu_wdog.u64);

	free_irq(irq, octeon_wdt_poke_irq);
}

static void octeon_wdt_setup_interrupt(int cpu)
{
	unsigned int core;
	unsigned int irq;
	union cvmx_ciu_wdogx ciu_wdog;

	core = cpu2core(cpu);

	/* Disable it before doing anything with the interrupts. */
	ciu_wdog.u64 = 0;
	cvmx_write_csr(CVMX_CIU_WDOGX(core), ciu_wdog.u64);

	per_cpu_countdown[cpu] = countdown_reset;

	irq = OCTEON_IRQ_WDOG0 + core;

	if (request_irq(irq, octeon_wdt_poke_irq,
			IRQF_NO_THREAD, "octeon_wdt", octeon_wdt_poke_irq))
		panic("octeon_wdt: Couldn't obtain irq %d", irq);

	cpumask_set_cpu(cpu, &irq_enabled_cpus);

	/* Poke the watchdog to clear out its state */
	cvmx_write_csr(CVMX_CIU_PP_POKEX(core), 1);

	/* Finally enable the watchdog now that all handlers are installed */
	ciu_wdog.u64 = 0;
	ciu_wdog.s.len = timeout_cnt;
	ciu_wdog.s.mode = 3;	/* 3 = Interrupt + NMI + Soft-Reset */
	cvmx_write_csr(CVMX_CIU_WDOGX(core), ciu_wdog.u64);
}

static int octeon_wdt_cpu_callback(struct notifier_block *nfb,
					   unsigned long action, void *hcpu)
{
	unsigned int cpu = (unsigned long)hcpu;

	switch (action) {
	case CPU_DOWN_PREPARE:
		octeon_wdt_disable_interrupt(cpu);
		break;
	case CPU_ONLINE:
	case CPU_DOWN_FAILED:
		octeon_wdt_setup_interrupt(cpu);
		break;
	default:
		break;
	}
	return NOTIFY_OK;
}

static void octeon_wdt_ping(void)
{
	int cpu;
	int coreid;

	for_each_online_cpu(cpu) {
		coreid = cpu2core(cpu);
		cvmx_write_csr(CVMX_CIU_PP_POKEX(coreid), 1);
		per_cpu_countdown[cpu] = countdown_reset;
		if ((countdown_reset || !do_coundown) &&
		    !cpumask_test_cpu(cpu, &irq_enabled_cpus)) {
			/* We have to enable the irq */
			int irq = OCTEON_IRQ_WDOG0 + coreid;
			enable_irq(irq);
			cpumask_set_cpu(cpu, &irq_enabled_cpus);
		}
	}
}

static void octeon_wdt_calc_parameters(int t)
{
	unsigned int periods;

	timeout_sec = max_timeout_sec;


	/*
	 * Find the largest interrupt period, that can evenly divide
	 * the requested heartbeat time.
	 */
	while ((t % timeout_sec) != 0)
		timeout_sec--;

	periods = t / timeout_sec;

	/*
	 * The last two periods are after the irq is disabled, and
	 * then to the nmi, so we subtract them off.
	 */

	countdown_reset = periods > 2 ? periods - 2 : 0;
	heartbeat = t;
	timeout_cnt = ((octeon_get_io_clock_rate() >> 8) * timeout_sec) >> 8;
}

static int octeon_wdt_set_heartbeat(int t)
{
	int cpu;
	int coreid;
	union cvmx_ciu_wdogx ciu_wdog;

	if (t <= 0)
		return -1;

	octeon_wdt_calc_parameters(t);

	for_each_online_cpu(cpu) {
		coreid = cpu2core(cpu);
		cvmx_write_csr(CVMX_CIU_PP_POKEX(coreid), 1);
		ciu_wdog.u64 = 0;
		ciu_wdog.s.len = timeout_cnt;
		ciu_wdog.s.mode = 3;	/* 3 = Interrupt + NMI + Soft-Reset */
		cvmx_write_csr(CVMX_CIU_WDOGX(coreid), ciu_wdog.u64);
		cvmx_write_csr(CVMX_CIU_PP_POKEX(coreid), 1);
	}
	octeon_wdt_ping(); /* Get the irqs back on. */
	return 0;
}

/**
 *	octeon_wdt_write:
 *	@file: file handle to the watchdog
 *	@buf: buffer to write (unused as data does not matter here
 *	@count: count of bytes
 *	@ppos: pointer to the position to write. No seeks allowed
 *
 *	A write to a watchdog device is defined as a keepalive signal. Any
 *	write of data will do, as we we don't define content meaning.
 */

static ssize_t octeon_wdt_write(struct file *file, const char __user *buf,
				size_t count, loff_t *ppos)
{
	if (count) {
		if (!nowayout) {
			size_t i;

			/* In case it was set long ago */
			expect_close = 0;

			for (i = 0; i != count; i++) {
				char c;
				if (get_user(c, buf + i))
					return -EFAULT;
				if (c == 'V')
					expect_close = 1;
			}
		}
		octeon_wdt_ping();
	}
	return count;
}

/**
 *	octeon_wdt_ioctl:
 *	@file: file handle to the device
 *	@cmd: watchdog command
 *	@arg: argument pointer
 *
 *	The watchdog API defines a common set of functions for all
 *	watchdogs according to their available features. We only
 *	actually usefully support querying capabilities and setting
 *	the timeout.
 */

static long octeon_wdt_ioctl(struct file *file, unsigned int cmd,
			     unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	int __user *p = argp;
	int new_heartbeat;

	static struct watchdog_info ident = {
		.options =		WDIOF_SETTIMEOUT|
					WDIOF_MAGICCLOSE|
					WDIOF_KEEPALIVEPING,
		.firmware_version =	1,
		.identity =		"OCTEON",
	};

	switch (cmd) {
	case WDIOC_GETSUPPORT:
		return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		return put_user(0, p);
	case WDIOC_KEEPALIVE:
		octeon_wdt_ping();
		return 0;
	case WDIOC_SETTIMEOUT:
		if (get_user(new_heartbeat, p))
			return -EFAULT;
		if (octeon_wdt_set_heartbeat(new_heartbeat))
			return -EINVAL;
		/* Fall through. */
	case WDIOC_GETTIMEOUT:
		return put_user(heartbeat, p);
	default:
		return -ENOTTY;
	}
}

/**
 *	octeon_wdt_open:
 *	@inode: inode of device
 *	@file: file handle to device
 *
 *	The watchdog device has been opened. The watchdog device is single
 *	open and on opening we do a ping to reset the counters.
 */

static int octeon_wdt_open(struct inode *inode, struct file *file)
{
	if (test_and_set_bit(0, &octeon_wdt_is_open))
		return -EBUSY;
	/*
	 *	Activate
	 */
	octeon_wdt_ping();
	do_coundown = 1;
	return nonseekable_open(inode, file);
}

/**
 *	octeon_wdt_release:
 *	@inode: inode to board
 *	@file: file handle to board
 *
 *	The watchdog has a configurable API. There is a religious dispute
 *	between people who want their watchdog to be able to shut down and
 *	those who want to be sure if the watchdog manager dies the machine
 *	reboots. In the former case we disable the counters, in the latter
 *	case you have to open it again very soon.
 */

static int octeon_wdt_release(struct inode *inode, struct file *file)
{
	if (expect_close) {
		do_coundown = 0;
		octeon_wdt_ping();
	} else {
		pr_crit("WDT device closed unexpectedly.  WDT will not stop!\n");
	}
	clear_bit(0, &octeon_wdt_is_open);
	expect_close = 0;
	return 0;
}

static const struct file_operations octeon_wdt_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.write		= octeon_wdt_write,
	.unlocked_ioctl	= octeon_wdt_ioctl,
	.open		= octeon_wdt_open,
	.release	= octeon_wdt_release,
};

static struct miscdevice octeon_wdt_miscdev = {
	.minor	= WATCHDOG_MINOR,
	.name	= "watchdog",
	.fops	= &octeon_wdt_fops,
};

static struct notifier_block octeon_wdt_cpu_notifier = {
	.notifier_call = octeon_wdt_cpu_callback,
};


/**
 * Module/ driver initialization.
 *
 * Returns Zero on success
 */
static int __init octeon_wdt_init(void)
{
	int i;
	int ret;
	int cpu;
	u64 *ptr;

	/*
	 * Watchdog time expiration length = The 16 bits of LEN
	 * represent the most significant bits of a 24 bit decrementer
	 * that decrements every 256 cycles.
	 *
	 * Try for a timeout of 5 sec, if that fails a smaller number
	 * of even seconds,
	 */
	max_timeout_sec = 6;
	do {
		max_timeout_sec--;
		timeout_cnt = ((octeon_get_io_clock_rate() >> 8) * max_timeout_sec) >> 8;
	} while (timeout_cnt > 65535);

	BUG_ON(timeout_cnt == 0);

	octeon_wdt_calc_parameters(heartbeat);

	pr_info("Initial granularity %d Sec\n", timeout_sec);

	ret = misc_register(&octeon_wdt_miscdev);
	if (ret) {
		pr_err("cannot register miscdev on minor=%d (err=%d)\n",
		       WATCHDOG_MINOR, ret);
		goto out;
	}

	/* Build the NMI handler ... */
	octeon_wdt_build_stage1();

	/* ... and install it. */
	ptr = (u64 *) nmi_stage1_insns;
	for (i = 0; i < 16; i++) {
		cvmx_write_csr(CVMX_MIO_BOOT_LOC_ADR, i * 8);
		cvmx_write_csr(CVMX_MIO_BOOT_LOC_DAT, ptr[i]);
	}
	cvmx_write_csr(CVMX_MIO_BOOT_LOC_CFGX(0), 0x81fc0000);

	cpumask_clear(&irq_enabled_cpus);

	cpu_notifier_register_begin();
	for_each_online_cpu(cpu)
		octeon_wdt_setup_interrupt(cpu);

	__register_hotcpu_notifier(&octeon_wdt_cpu_notifier);
	cpu_notifier_register_done();

out:
	return ret;
}

/**
 * Module / driver shutdown
 */
static void __exit octeon_wdt_cleanup(void)
{
	int cpu;

	misc_deregister(&octeon_wdt_miscdev);

	cpu_notifier_register_begin();
	__unregister_hotcpu_notifier(&octeon_wdt_cpu_notifier);

	for_each_online_cpu(cpu) {
		int core = cpu2core(cpu);
		/* Disable the watchdog */
		cvmx_write_csr(CVMX_CIU_WDOGX(core), 0);
		/* Free the interrupt handler */
		free_irq(OCTEON_IRQ_WDOG0 + core, octeon_wdt_poke_irq);
	}

	cpu_notifier_register_done();

	/*
	 * Disable the boot-bus memory, the code it points to is soon
	 * to go missing.
	 */
	cvmx_write_csr(CVMX_MIO_BOOT_LOC_CFGX(0), 0);
}

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>");
MODULE_DESCRIPTION("Cavium Networks Octeon Watchdog driver.");
module_init(octeon_wdt_init);
module_exit(octeon_wdt_cleanup);
