[PATCH] WDT Driver for Book-E [2/2] Device driver part.
Kumar Gala
kumar.gala at freescale.com
Sat Mar 5 03:02:40 EST 2005
Matt,
Do you think this really needs a config option? Should it not be
sufficient that if you enable watchdog you get this functionality on
4xx/e500?
- kumar
On Mar 4, 2005, at 3:38 AM, Takeharu KATO wrote:
> Matt and Kurmar:
>
> I post the device driver part with this mail.
>
> This is the last part of this driver.
>
> Please apply.
>
> Regards,
>
> Signed-off-by: Takeharu KATO <kato.takeharu at jp.fujitsu.com>
>
> --- linux-2.6.11/drivers/char/watchdog/Kconfig 2005-03-04
> 17:14:57.687966296 +0900
> +++ linux-2.6.11-booke-wdt/drivers/char/watchdog/Kconfig
> 2005-03-04 13:21:32.000000000 +0900
> @@ -346,6 +346,13 @@ config 8xx_WDT
> tristate "MPC8xx Watchdog Timer"
> depends on WATCHDOG && 8xx
>
> +config BOOKE_WDT
> + bool "Book E(PowerPC 4xx/e500) Watchdog Timer"
> + depends on WATCHDOG && ( 4xx || E500 )
> + ---help---
> + This is the driver for the watchdog timers on
> + PowerPC 4xx and PowerPC e500.
> +
> # MIPS Architecture
>
> config INDYDOG
> --- linux-2.6.11/drivers/char/watchdog/Makefile 2005-03-04
> 17:15:30.582965496 +0900
> +++ linux-2.6.11-booke-wdt/drivers/char/watchdog/Makefile
> 2005-03-04 13:21:32.000000000 +0900
> @@ -39,3 +39,4 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.
> obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
> obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o
> obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
> +obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o
> --- linux-2.6.11/drivers/char/watchdog/booke_wdt.c 1970-01-01
> 09:00:00.000000000 +0900
> +++ linux-2.6.11-booke-wdt/drivers/char/watchdog/booke_wdt.c
> 2005-03-04 16:38:58.000000000 +0900
> @@ -0,0 +1,664 @@
> +/*
> + * Copyright (c) 2005 Fujitsu Limited
> + *
> + * Module name: booke_wdt.c
> + * Author: Takeharu KATO<kato.takeharu at jp.fujitsu.com>
> + *
> + * 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 Takeharu KATO nor Fujitsu Ltd. admit liability nor
> provide
> + * warranty for any of this software.
> + *
> + * Description:
> + * Watchdog driver for PowerPC Book E (PowerPC 4xx series
> processors and
> + * PowerPC e500 series processors).
> + * Derived from drivers/char/watchdog/wdt.c by Alan cox
> + * and drivers/char/watchdog/ppc405_wdt.c by Armin
> Kuster.
> + * PPC4xx WDT operation is driverd from Appendix of
> + * PowerPC Embedded Processors Application Note
> + * ``PowerPC 40x Watch Dog Timer'' published from IBM.
> + * This driver is written according to ``PowerPC e500 Core
> Complex
> + * Reference Manual'' for e500 part.
> + */
> +#include <linux/config.h>
> +#include <linux/kernel.h>
> +#include <linux/types.h>
> +#include <linux/miscdevice.h>
> +#include <linux/watchdog.h>
> +#include <linux/fs.h>
> +#include <linux/reboot.h>
> +#include <linux/init.h>
> +#include <linux/capability.h>
> +#include <linux/string.h>
> +#include <linux/ptrace.h>
> +#include <asm/reg.h>
> +#include <asm/uaccess.h>
> +#include <asm/system.h>
> +#include "booke_wdt.h"
> +
> +/* micro seconds per one milli-second(used to calculatewatchdog
> + * counter to be set). */
> +#define US_PER_MS 1000
> +/* Calculate watchdog count */
> +#define calculate_wdt_count(t) ((((unsigned long)(t))*HZ)/1000)
> +
> +int wdt_enable=0; /* WDT start on boot */
> +int wdt_period=WDT_TIMO; /* Time out in ms */
> +
> +#ifdef CONFIG_WATCHDOG_NOWAYOUT
> +static int nowayout = 1;
> +#else
> +static int nowayout = 0;
> +#endif
> +
> +/*
> + * Global variables
> + */
> +static int wdt_count = 0; /* WDT intrrupt counter to be
> reloaded */
> +static volatile int wdt_heartbeat_count = 0; /* WDT intrrupt
> counter(compatible mode)*/
> +static unsigned long driver_state; /* Driver status (see:
> booke_wdt.h) */
> +/*
> + * Identifier for this watchdog
> + */
> +static struct watchdog_info ident = {
> + .options=WDIOF_SETTIMEOUT|WDIOF_KEEPALIVEPING|WDIOF_MAGICCLOSE,
> + .firmware_version = 0, /* This is filled with PVR in
> initialization. */
> + .identity = "Book E(PPC 4xx/e500) WDT",
> +};
> +
> +/*
> + * PowerPC Linux common exception handler
> + */
> +extern void _exception(int signr, struct pt_regs *regs, int code,
> unsigned long addr);
> +/* Panic notifier */
> +extern struct notifier_block *panic_notifier_list;
> +/*
> + * External linkage functions
> + */
> +void booke_wdt_heartbeat(void);
> +void booke_wdt_setup_options(char *cmd_line);
> +void booke_wdt_exception(struct pt_regs *regs);
> +/*
> + * Internal linkage functions
> + */
> +static __inline__ void __booke_wdt_setup_val(int period,int reset);
> +static __inline__ void __booke_wdt_enable(void);
> +static __inline__ void __booke_wdt_disable(void);
> +static __inline__ int __booke_wdt_is_enabled(void);
> +static __inline__ void __booke_wdt_clear_int_stat(void);
> +static __inline__ void __booke_wdt_set_timeout(int t);
> +static __inline__ void booke_wdt_init_device(void);
> +static __inline__ int booke_wdt_is_enabled(void);
> +static __inline__ int booke_wdt_start(void);
> +static __inline__ int booke_wdt_stop(void);
> +static __inline__ int booke_wdt_ping(void);
> +static __inline__ int booke_wdt_set_timeout(int t);
> +static __inline__ int booke_wdt_get_status(int *status);
> +static ssize_t booke_wdt_write(struct file *file, const char *buf,
> size_t count, loff_t *ppos);
> +static int booke_wdt_ioctl(struct inode *inode, struct file *file,
> unsigned int cmd,unsigned long arg);
> +static int booke_wdt_open(struct inode *inode, struct file *file);
> +static int booke_wdt_release(struct inode *inode, struct file *file);
> +static int booke_wdt_notify_sys(struct notifier_block *this, unsigned
> long code,void *unused);
> +static int __init booke_wdt_init(void);
> +static void __exit booke_wdt_exit(void);
> +
> +/*
> + * Watchdog operations on PPC4xx/e500 MPU
> + */
> +
> +/**
> + * __booke_wdt_setup_val
> + * Enable Watchdog, sets up passed in values for TCR[WP],
> + * TCR[WRC]
> + *
> + * @period: Input Watchdog Period - TCR[WP]
> + * 0 = 217 clocks
> + * 1 = 221 clocks
> + * 2 = 225 clocks
> + * 3 = 229 clocks
> + * @reset: Watchdog reset control - TCR[WRC]
> + * 0 = No reset
> + * 1 = PPC Core reset only
> + * 2 = PPC Chip reset
> + * 3 = System reset
> + * Note: The meaning of period number is differ PPC440GP from
> PPC440GX.
> + */
> +#if defined(CONFIG_4xx)
> +static __inline__ void
> +__booke_wdt_setup_val(int period,int reset)
> +{
> + unsigned long val;
> +
> + /* Set up TCR */
> +
> val=((period)<<WDT_TCR_WP_SHIFT|(reset)<<WDT_TCR_WRC_SHIFT)|mfspr(SPRN_
> TCR);
> + /* Disable WDT */
> + val &= ~(WDT_TCR_WDT_ENABLE);
> +
> + mtspr(SPRN_TCR,val);
> +}
> +#else
> +/* e500 */
> +static __inline__ void
> +__booke_wdt_setup_val(int period,int reset)
> +{
> + unsigned long val;
> + /* Set up TCR */
> +
> + val=(((period)&(WDT_TCR_WP_BITMSK)) << WDT_TCR_WP_SHIFT|
> + ( ( (period) >> 2 )&(WDT_TCR_WPEXT_BITMSK)) <<
> WDT_TCR_WPEXT_SHIFT|
> + (reset)<<WDT_TCR_WRC_SHIFT)|mfspr(SPRN_TCR);
> + /* Disable WDT */
> + val &= ~(WDT_TCR_WDT_ENABLE);
> +
> + mtspr(SPRN_TCR,val);
> +}
> +#endif /* CONFIG_E500 */
> +/**
> + * __booke_wdt_enable
> + * Enable Watchdog
> + */
> +static __inline__ void
> +__booke_wdt_enable(void)
> +{
> + mtspr(SPRN_TCR,(mfspr(SPRN_TCR)|WDT_TCR_WDT_ENABLE));
> +}
> +/**
> + * __booke_wdt_disable
> + * Disable Watchdog
> + */
> +static __inline__ void
> +__booke_wdt_disable(void)
> +{
> + mtspr(SPRN_TCR,(mfspr(SPRN_TCR)&(~(WDT_TCR_WDT_ENABLE))));
> +}
> +/**
> + * __booke_wdt_is_enabled
> + * Check whether Watchdog is enabled.
> + */
> +static __inline__ int
> +__booke_wdt_is_enabled(void)
> +{
> + return (mfspr(SPRN_TCR) & WDT_TCR_WDT_ENABLE);
> +}
> +/**
> + * __booke_wdt_clear_init_stat
> + * Clear interrupt status of watchdog to ping it.
> + */
> +static __inline__ void
> +__booke_wdt_clear_int_stat(void)
> +{
> + mtspr(SPRN_TSR, (TSR_ENW|TSR_WIS));
> +}
> +/**
> + * __booke_wdt_set_timeout:
> + * @t: the new time out value that needs to be set.
> + *
> + * Set a new time out value for the watchdog device.
> + *
> + */
> +static __inline__ void
> +__booke_wdt_set_timeout(int t)
> +{
> + wdt_count=calculate_wdt_count(t);
> + return;
> +}
> +
> +/*
> + * Driver specific functions
> + */
> +
> +/**
> + * booke_wdt_setup_options
> + * @cmd_line : a pointer to kernel command line.
> + *
> + */
> +void
> +booke_wdt_setup_options(char *cmd_line)
> +{
> +/*
> + * Look for wdt= option on command line
> + */
> + if (strstr(cmd_line, "wdt=")) {
> + int valid_wdt = 0;
> + char *p, *q;
> +
> + for (q = cmd_line; (p = strstr(q, "wdt=")) != 0;) {
> + q = p + 4;
> + if (p > cmd_line && p[-1] != ' ')
> + continue;
> + wdt_period = simple_strtoul(q, &q, 0);
> + valid_wdt = 1;
> + ++q;
> + }
> + wdt_enable = valid_wdt;
> + }
> + return;
> +}
> +/**
> + * booke_wdt_heartbeat:
> + * Ping routine called from kernel.
> + */
> +void
> +booke_wdt_heartbeat(void)
> +{
> + /* Disable watchdog */
> + __booke_wdt_disable();
> +
> + /* Write a watchdog value */
> + __booke_wdt_clear_int_stat();
> +
> + if (!wdt_enable)
> + goto out;
> +
> + if (wdt_heartbeat_count > 0)
> + wdt_heartbeat_count--;
> + else
> + panic(booke_mkmsg("Initiating system reboot.\n"));
> +
> + /* Enable watchdog */
> + __booke_wdt_enable();
> + out:
> + /* Reset count */
> + ppc_md.heartbeat_count = 0;
> +}
> +/**
> + * booke_wdt_exception:
> + * WatchDog Exception handler for PPC4xx/e500.
> + * @regs : A registers information.
> + */
> +void
> +booke_wdt_exception(struct pt_regs *regs)
> +{
> + wdt_enable=0;
> + __booke_wdt_disable();
> + printk("WDT Exception at PC: %lx, MSR: %lx, vector=%lx %s\n",
> + regs->nip, regs->msr, regs->trap, print_tainted());
> + panic(booke_mkmsg("Initiating system reboot.\n"));
> +}
> +/*
> + * Driver Logic functions
> + */
> +static __inline__ int
> +booke_wdt_is_enabled(void)
> +{
> + return __booke_wdt_is_enabled();
> +}
> +/**
> + * booke_wdt_start:
> + *
> + * Start the watchdog driver.
> + */
> +static __inline__ int
> +booke_wdt_start(void)
> +{
> + __booke_wdt_enable();
> + return 0;
> +}
> +
> +/**
> + * booke_wdt_stop:
> + *
> + * Stop the watchdog driver.
> + */
> +static __inline__ int
> +booke_wdt_stop (void)
> +{
> + __booke_wdt_disable();
> + return 0;
> +}
> +/**
> + * booke_wdt_ping:
> + *
> + * Reload counter one with the watchdog heartbeat. We don't
> bother reloading
> + * the cascade counter.
> + */
> +static __inline__ int
> +booke_wdt_ping(void)
> +{
> + /* Disable watchdog */
> + __booke_wdt_disable();
> + /* Write a watchdog value */
> + __booke_wdt_clear_int_stat();
> + /* Reset count */
> + wdt_heartbeat_count=wdt_count;
> + /* Enable watchdog */
> + __booke_wdt_enable();
> +
> + return 0;
> +}
> +/**
> + * booke_wdt_set_timeout:
> + * @t: the new timeout value that needs to be set.
> + *
> + * Set a new time out value for the watchdog device.
> + * If the heartbeat value is incorrect we keep the old value
> + * and return -EINVAL. If successfull we return 0.
> + */
> +static __inline__ int
> +booke_wdt_set_timeout(int t)
> +{
> + if ((t < WDT_HEARTBEAT_MIN) || (t > WDT_HEARTBEAT_MAX))
> + return -EINVAL;
> +
> + wdt_period = t;
> + __booke_wdt_set_timeout(t);
> + wdt_heartbeat_count=wdt_count;
> + booke_wdt_dbg("The WDT counter set %d.\n",wdt_count);
> +
> + return 0;
> +}
> +
> +/**
> + * booke_wdt_get_status:
> + * @status: the new status.
> + *
> + * Return the enable/disable card status.
> + */
> +static __inline__ int
> +booke_wdt_get_status(int *status)
> +{
> + if (wdt_enable)
> + *status = WDIOS_ENABLECARD;
> + else
> + *status = WDIOS_DISABLECARD;
> +
> + return 0;
> +}
> +/*
> + * Kernel Interfaces
> + */
> +/**
> + * booke_wdt_init_device:
> + *
> + * Initilize PowerPC 4xx/e500 family Watch Dog facility.
> + */
> +static void
> +booke_wdt_init_device(void)
> +{
> + /* Hardware WDT provided by the processor.
> + * So, we set firmware version as processor version number.
> + */
> + ident.firmware_version=mfspr(PVR);
> + __booke_wdt_setup_val(WDT_WP,WDT_RESET_NONE);
> +}
> +/**
> + * booke_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
> expept
> + * 'V' character. It is performed as a sign to set
> stop-on-close mode.
> + */
> +
> +static ssize_t
> +booke_wdt_write(struct file *file, const char *buf, size_t count,
> loff_t *ppos)
> +{
> + size_t i;
> +
> + if (!nowayout) {
> + /* In case it was set long ago */
> + clear_bit(WDT_STATE_STOP_ON_CLOSE, &driver_state);
> +
> + for (i = 0; i < count; i++) {
> + char c;
> +
> + if (get_user(c, buf + i))
> + return -EFAULT;
> +
> + if (c == 'V') {
> + set_bit(WDT_STATE_STOP_ON_CLOSE, &driver_state);
> + }
> + }
> + }
> + booke_wdt_ping();
> +
> + return count;
> +}
> +
> +/**
> + * booke_wdt_ioctl:
> + * @inode: inode of the device
> + * @file: file handle to the device
> + * @cmd: watchdog command
> + * @arg: argument pointer
> + *
> + */
> +static int
> +booke_wdt_ioctl(struct inode *inode, struct file *file, unsigned int
> cmd,
> + unsigned long arg)
> +{
> + int new_timeout;
> + int status;
> +
> + if (!capable(CAP_SYS_ADMIN))
> + return -EPERM; /* It may be too strict manner. */
> + switch(cmd)
> + {
> + default:
> + return -ENOIOCTLCMD;
> + case WDIOC_GETSUPPORT:
> + if (copy_to_user((struct watchdog_info *)arg, &ident,
> sizeof(struct watchdog_info)))
> + return -EFAULT;
> + else
> + break;
> + case WDIOC_GETSTATUS:
> + booke_wdt_get_status(&status);
> + return put_user(status,(int *)arg);
> + case WDIOC_KEEPALIVE:
> + booke_wdt_ping();
> + break;
> + case WDIOC_SETTIMEOUT:
> + if (get_user(new_timeout, (int *)arg))
> + return -EFAULT;
> + if (booke_wdt_set_timeout(new_timeout))
> + return -EINVAL;
> + booke_wdt_ping();
> + break;
> + case WDIOC_GETTIMEOUT:
> + return put_user(wdt_period, (int *)arg);
> + case WDIOC_SETOPTIONS:
> + if (get_user(status, (int *)arg))
> + return -EFAULT;
> + /* Return -EINVAL when the driver can not figure out
> + * what it should do. Unknown cases are just ignored.
> + */
> + if ( (status & (WDIOS_DISABLECARD|WDIOS_ENABLECARD))
> + == (WDIOS_DISABLECARD|WDIOS_ENABLECARD) )
> + return -EINVAL;
> + if (status & WDIOS_DISABLECARD) {
> + wdt_enable = 0;
> + booke_wdt_stop();
> + booke_wdt_info("Watchdog timer is disabled\n");
> + }
> + if (status & WDIOS_ENABLECARD) {
> + wdt_enable = 1;
> + booke_wdt_start();
> + booke_wdt_info("Watchdog timer is enabled\n");
> + }
> + break;
> + }
> + return 0;
> +}
> +/**
> + * booke_wdt_open:
> + * @inode: inode of device
> + * @file: file handle to device
> + *
> + * The watchdog device has been opened. The watchdog device is
> single
> + * open and start the WDT timer.
> + */
> +static int
> +booke_wdt_open(struct inode *inode, struct file *file)
> +{
> + if (!capable(CAP_SYS_ADMIN))
> + return -EPERM;
> +
> + if (test_and_set_bit(WDT_STATE_OPEN, &driver_state))
> + return -EBUSY;
> + /*
> + * Activate
> + */
> + booke_wdt_start();
> + wdt_enable=1;
> +
> + if (nowayout)
> + set_bit(WDT_STATE_STOP_ON_CLOSE, &driver_state);
> +
> + return 0;
> +}
> +
> +/**
> + * booke_wdt_release:
> + * @inode: inode to board
> + * @file: file handle to board
> + *
> + */
> +static int
> +booke_wdt_release(struct inode *inode, struct file *file)
> +{
> + if (test_bit(WDT_STATE_STOP_ON_CLOSE, &driver_state)) {
> + booke_wdt_note("WDT device is stopped.\n");
> + booke_wdt_stop();
> + wdt_enable=0;
> + } else {
> + if ( (booke_wdt_is_enabled()) && (!nowayout) ) {
> + booke_wdt_note("WDT device may be closed unexpectedly. WDT
> will not stop!\n");
> + booke_wdt_ping();
> + }
> + }
> + clear_bit(WDT_STATE_OPEN, &driver_state);
> +
> + return 0;
> +}
> +/**
> + * notify_sys:
> + * @this: our notifier block
> + * @code: the event being reported
> + * @unused: unused
> + * Note: This function assume that the panic notifier is called
> with CODE=0
> + * (see panic function in kernel/panic.c).
> + */
> +static int
> +booke_wdt_notify_sys(struct notifier_block *this, unsigned long code,
> + void *unused)
> +{
> +
> + if (code != SYS_POWER_OFF) /* Turn the card off */
> + booke_wdt_stop();
> +
> + return NOTIFY_DONE;
> +}
> +
> +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,
> + .release = booke_wdt_release,
> +};
> +
> +static struct miscdevice booke_wdt_miscdev = {
> + .minor = WATCHDOG_MINOR,
> + .name = "watchdog",
> + .fops = &booke_wdt_fops,
> +};
> +
> +/*
> + * The WDT card needs to know about shutdowns in order to
> + * turn WDT off.
> + */
> +
> +static struct notifier_block booke_wdt_notifier = {
> + .notifier_call = booke_wdt_notify_sys,
> +};
> +
> +/**
> + * cleanup_module:
> + *
> + * If your watchdog is set to continue ticking on close and you
> unload
> + * it, well it keeps ticking. You just have to load a new
> + * module in 60 seconds or reboot.
> + * This behavior(more over the comments as above) is borrowed
> from
> + * Alan cox's driver.
> + */
> +
> +static void __exit
> +booke_wdt_exit(void)
> +{
> + misc_deregister(&booke_wdt_miscdev);
> + unregister_reboot_notifier(&booke_wdt_notifier);
> +
> notifier_chain_unregister(&panic_notifier_list,&booke_wdt_notifier);
> +}
> +
> +/**
> + * booke_wdt_init:
> + *
> + * Set up the WDT relevant timer facility.
> + */
> +
> +static int __init
> +booke_wdt_init(void)
> +{
> + int ret;
> + unsigned long flags;
> +
> + ret = register_reboot_notifier(&booke_wdt_notifier);
> + if(ret) {
> + booke_wdt_err("Cannot register reboot notifier (err=%d)\n",
> ret);
> + return ret;
> + }
> +
> + /* Register panic notifier */
> + ret =
> notifier_chain_register(&panic_notifier_list,&booke_wdt_notifier);
> + if(ret) {
> + booke_wdt_err("Cannot register panic notifier (err=%d)\n",
> ret);
> + unregister_reboot_notifier(&booke_wdt_notifier);
> + return ret;
> + }
> +
> + ret = 0;
> + booke_wdt_init_device();
> + /* Check that the heartbeat value is within it's range ; if not
> reset to the default */
> + if (booke_wdt_set_timeout(wdt_period)) {
> + if (wdt_period)
> + booke_wdt_info("The heartbeat value must be %d < wdt_period
> < %d, using
> %d\n",WDT_HEARTBEAT_MIN,WDT_HEARTBEAT_MAX,WDT_TIMO);
> + booke_wdt_set_timeout(WDT_TIMO);
> + }
> +
> + local_irq_save(flags); /* Prevent timer interrupt */
> + ppc_md.heartbeat_count = 0;
> + ppc_md.heartbeat=booke_wdt_heartbeat;
> + local_irq_restore(flags);
> +
> + booke_wdt_info("Book E(PPC 4xx/e500) Watchdog Driver. period=%d
> ms (nowayout=%d)\n",wdt_period,
> nowayout);
> +
> + ret = misc_register(&booke_wdt_miscdev);
> + if (ret) {
> + booke_wdt_err("Cannot register miscdev on minor=%d (err=%d)\n",
> + WATCHDOG_MINOR, ret);
> + goto outmisc;
> + }
> +
> + if (wdt_enable) {
> + booke_wdt_info("WDT start on boot.\n");
> + booke_wdt_start();
> + }
> +out:
> + return ret;
> +outmisc:
> + unregister_reboot_notifier(&booke_wdt_notifier);
> + local_irq_save(flags);
> + ppc_md.heartbeat=NULL;
> + ppc_md.heartbeat_count = 0;
> + local_irq_restore(flags);
> + goto out;
> +}
> +
> +device_initcall(booke_wdt_init);
> --- linux-2.6.11/drivers/char/watchdog/booke_wdt.h 1970-01-01
> 09:00:00.000000000 +0900
> +++ linux-2.6.11-booke-wdt/drivers/char/watchdog/booke_wdt.h
> 2005-03-04 16:38:58.000000000 +0900
> @@ -0,0 +1,125 @@
> +/*
> + *
> + * Copyright (c) 2004 Fujitsu Limited
> + *
> + * Module name: booke_wdt.h
> + * Author: Takeharu KATO<kato.takeharu at jp.fujitsu.com>
> + * Description:
> + * Header file for PowerPC Book E(PPC 4xx/e500) watchdog driver.
> + *
> + * 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 Takeharu KATO nor Fujitsu Ltd. admit liability nor
> provide
> + * warranty for any of this software.
> + *
> + */
> +#ifndef _DRIVERS_CHAR_WATCHDOG_BOOKE_WDT_H
> +#define _DRIVERS_CHAR_WATCHDOG_BOOKE_WDT_H
> +#include <linux/config.h>
> +#include <linux/kernel.h>
> +#include <linux/ptrace.h>
> +#include <linux/watchdog.h>
> +
> +/*
> + * Driver state flags(bit position)
> + */
> +#define WDT_STATE_OPEN 0 /* driver is opend */
> +#define WDT_STATE_STOP_ON_CLOSE 1 /* Stop with close is
> expected */
> +/*
> + * Configurations
> + */
> +#define WDT_TIMO 60000 /* Default timeout = 60000
> ms(1min) */
> +#define WDT_HEARTBEAT_MIN 100 /* Minimum timeout = 100 ms
> */
> +#define WDT_HEARTBEAT_MAX 600000 /* Maximum timeout =
> 600000ms(1hour) */
> +#ifdef __KERNEL__
> +//#define BOOKE_WDT_DEBUG /* Debug switch */
> +/*
> + * Reset type
> + */
> +#define WDT_RESET_NONE 0
> +#define WDT_RESET_CORE 1
> +#define WDT_RESET_CHIP 2
> +#define WDT_RESET_SYS 3
> +/*
> + * Bit positions in TCR register on PPC4xx/e500 series.
> + */
> +#define WDT_TCR_WP_BIT 1 /* WP bit in TCR (bit[0..1]) */
> +#define WDT_TCR_WRC_BIT 3 /* WRC bit in TCR (bit[2..3]) */
> +#define WDT_TCR_WIE_BIT 4 /* WIE bit in TCR (bit[4]) */
> +/*
> + * TCR[WP] relevant definitions
> + */
> +#define WDT_TCR_WP_SHIFT (31 - WDT_TCR_WP_BIT)
> +#define WDT_TCR_WRC_SHIFT (31 - WDT_TCR_WRC_BIT)
> +#define WDT_TCR_WIE_SHIFT (31 - WDT_TCR_WIE_BIT)
> +#define WDT_TCR_WDT_ENABLE (1<<WDT_TCR_WIE_SHIFT)
> +/* MASK value to obatain TCR[WP] */
> +#define WDT_TCR_WP_MASK (3<<(WDT_TCR_WP_SHIFT))
> +
> +/* Watchdog timer periods can be set on PPC 4xx cpus. */
> +#if defined(CONFIG_4xx)
> +/*
> + * For PowerPC 4xx
> + */
> +#define WDT_WP0 0
> +#define WDT_WP1 1
> +#define WDT_WP2 2
> +#define WDT_WP3 3
> +#else
> +#if defined(CONFIG_E500)
> +/*
> + * For e500 CPU
> + * Actually, e500 can arbitrary periods can be set,
> + * But this driver uses fix period value as same as PPC440
> + * on purpose for simplicity.
> + * Following values split into WP and WP_EXT parts in booke_wdt.c.
> + */
> +#define WDT_WP0 21
> +#define WDT_WP1 25
> +#define WDT_WP2 29
> +#define WDT_WP3 33
> +#define WDT_TCR_WP_BITMSK 0x3 /* 2bit length */
> +#define WDT_TCR_WPEXT_BITMSK 0xf /* 4bit length */
> +#define WDT_TCR_WPEXT_SHIFT 17
> +#else
> +#error "Book E WDT detects invalid configuration(Unknown CPU)"
> +#endif /* CONFIG_E500 */
> +#endif /* CONFIG_4xx */
> +/*
> + * WP relevant values used in our driver.
> + * Note:WDT period must be more than HZ(Timer ticks)
> + */
> +#define WDT_WP WDT_WP3
> +
> +/*
> + * IOCTL commands for comaptiblity for old driver
> + */
> +#define WDIOC_GETPERIOD WDIOC_GETTIMEOUT
> +#define WDIOC_SETPERIOD WDIOC_SETTIMEOUT
> +
> +/*
> + * output messages
> + */
> +#define __BOOKE_WDT_MSG "BookE-WDT : "
> +#define booke_mkmsg(str) __BOOKE_WDT_MSG str
> +#define booke_wdt_info(fmt,arg...) \
> + printk(KERN_INFO __BOOKE_WDT_MSG fmt,##arg)
> +#define booke_wdt_note(fmt,arg...) \
> + printk(KERN_NOTICE __BOOKE_WDT_MSG fmt,##arg)
> +#define booke_wdt_err(fmt,arg...) \
> + printk(KERN_ALERT __BOOKE_WDT_MSG fmt,##arg)
> +#define booke_wdt_crit(fmt,arg...) \
> + printk(KERN_ALERT __BOOKE_WDT_MSG fmt,##arg)
> +#if defined(BOOKE_WDT_DEBUG)
> +#define booke_wdt_dbg(fmt,arg...) \
> + printk(KERN_ALERT __BOOKE_WDT_MSG fmt,##arg)
> +#else
> +#define booke_wdt_dbg(fmt,arg...) \
> + do{}while(0)
> +#endif /* WDT_DEBUG */
> +
> +#endif /* __KERNEL__ */
> +#endif /* _DRIVERS_CHAR_WATCHDOG_BOOKE_WDT_H */
>
>
More information about the Linuxppc-embedded
mailing list