/*
 * drivers/char/watchdog/booke_wdt.c
 *
 * Watchdog timer for PowerPC Book-E systems
 *
 * Author: Matthew McClintock
 * Maintainer: Kumar Gala <galak@kernel.crashing.org>
 *
 * Copyright 2005 Freescale Semiconductor Inc.
 *
 * 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.
 */

#include <linux/config.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/notifier.h>
#include <linux/watchdog.h>

#include <asm/reg_booke.h>
#include <asm/uaccess.h>
#include <asm/system.h>

/* If the kernel parameter wdt_enable=1, the watchdog will be enabled at boot.
 * Also, the wdt_period sets the watchdog timer period timeout.
 * For E500 cpus the wdt_period sets which bit changing from 0->1 will
 * trigger a watchog timeout. This watchdog timeout will occur 3 times, the
 * first time nothing will happen, the second time a watchdog exception will
 * occur, and the final time the board will reset.
 */

#ifdef	CONFIG_FSL_BOOKE
#define WDT_PERIOD_DEFAULT 63	/* Ex. wdt_period=28 bus=333Mhz , reset=~40sec */
#else
#define WDT_PERIOD_DEFAULT 4	/* Refer to the PPC40x and PPC4xx manuals */
#endif				/* for timing information */

u32 booke_wdt_enabled = 0;
u32 booke_wdt_period = WDT_PERIOD_DEFAULT;

#ifdef	CONFIG_FSL_BOOKE
#define WDTP(x)		((((63-x)&0x3)<<30)|(((63-x)&0x3c)<<15))
#else
#define WDTP(x)		(TCR_WP(x))
#endif

/*
 * booke_wdt_enable:
 */
static __inline__ void booke_wdt_enable(void)
{
	u32 val;

	val = mfspr(SPRN_TCR);
	val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period));

	mtspr(SPRN_TCR, val);
}

/*
 * booke_wdt_ping:
 */
static __inline__ void booke_wdt_ping(void)
{
	mtspr(SPRN_TSR, TSR_ENW|TSR_WIS);
}

/*
 * booke_wdt_write:
 */
static ssize_t booke_wdt_write (struct file *file, const char *buf,
				size_t count, loff_t *ppos)
{
	booke_wdt_ping();
	return count;
}

static struct watchdog_info ident = {
  .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
  .firmware_version = 0,
  .identity = "PowerPC Book-E Watchdog",
};

/*
 * booke_wdt_ioctl:
 */
static int booke_wdt_ioctl (struct inode *inode, struct file *file,
			    unsigned int cmd, unsigned long arg)
{
	u32 tmp = 0;

	switch (cmd) {
	case WDIOC_GETSUPPORT:
		if (copy_to_user ((struct watchdog_info *) arg, &ident,
				sizeof(struct watchdog_info)))
			return -EFAULT;
	case WDIOC_GETSTATUS:
		return put_user(ident.options, (u32 *) arg);
	case WDIOC_GETBOOTSTATUS:
		/* XXX: something is clearing TSR */
		tmp = mfspr(SPRN_TSR) & TSR_WRS(3);
		/* returns 1 if last reset was caused by the WDT */
		return (tmp ? 1 : 0);
	case WDIOC_KEEPALIVE:
		booke_wdt_ping();
		return 0;
	case WDIOC_SETTIMEOUT:
		if (get_user(booke_wdt_period, (u32 *) arg))
			return -EFAULT;
		mtspr(SPRN_TCR, (mfspr(SPRN_TCR)&~WDTP(0))|WDTP(booke_wdt_period));
		return 0;
	case WDIOC_GETTIMEOUT:
		return put_user(booke_wdt_period, (u32 *) arg);
	case WDIOC_SETOPTIONS:
		if (get_user(tmp, (u32 *) arg))
			return -EINVAL;
		if (tmp == WDIOS_ENABLECARD) {
			booke_wdt_ping();
			break;
		} else
			return -EINVAL;
		return 0;
	default:
		return -ENOIOCTLCMD;
	}

	return 0;
}
/*
 * booke_wdt_open:
 */
static int booke_wdt_open (struct inode *inode, struct file *file)
{
	if (booke_wdt_enabled == 0) {
		booke_wdt_enabled = 1;
		booke_wdt_enable();
		printk (KERN_INFO "PowerPC Book-E Watchdog Timer Enabled (wdt_period=%d)\n",
				booke_wdt_period);
	}

	return 0;
}

static struct file_operations booke_wdt_fops = {
  .owner = THIS_MODULE,
  .llseek = no_llseek,
  .write = booke_wdt_write,
  .ioctl = booke_wdt_ioctl,
  .open = booke_wdt_open,
};

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

static void __exit booke_wdt_exit(void)
{
	misc_deregister(&booke_wdt_miscdev);
}

/*
 * booke_wdt_init:
 */
static int __init booke_wdt_init(void)
{
	int ret = 0;

	printk (KERN_INFO "PowerPC Book-E Watchdog Timer Loaded\n");
	ident.firmware_version = cpu_specs[0].pvr_value;

	ret = misc_register(&booke_wdt_miscdev);
	if (ret) {
		printk (KERN_CRIT "Cannot register miscdev on minor=%d (err=%d)\n",
				WATCHDOG_MINOR, ret);
		return ret;
	}

	if (booke_wdt_enabled == 1) {
		printk (KERN_INFO "PowerPC Book-E Watchdog Timer Enabled (wdt_period=%d)\n",
				booke_wdt_period);
		booke_wdt_enable();
	}

	return ret;
}
device_initcall(booke_wdt_init);
