Commit a8cd2e50 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog

parents 0160f53e c315b7e8
...@@ -84,6 +84,17 @@ config 977_WATCHDOG ...@@ -84,6 +84,17 @@ config 977_WATCHDOG
Not sure? It's safe to say N. Not sure? It's safe to say N.
config IXP2000_WATCHDOG
tristate "IXP2000 Watchdog"
depends on WATCHDOG && ARCH_IXP2000
help
Say Y here if to include support for the watchdog timer
in the Intel IXP2000(2400, 2800, 2850) network processors.
This driver can be built as a module by choosing M. The module
will be called ixp2000_wdt.
Say N if you are unsure.
config IXP4XX_WATCHDOG config IXP4XX_WATCHDOG
tristate "IXP4xx Watchdog" tristate "IXP4xx Watchdog"
depends on WATCHDOG && ARCH_IXP4XX depends on WATCHDOG && ARCH_IXP4XX
...@@ -100,17 +111,6 @@ config IXP4XX_WATCHDOG ...@@ -100,17 +111,6 @@ config IXP4XX_WATCHDOG
Say N if you are unsure. Say N if you are unsure.
config IXP2000_WATCHDOG
tristate "IXP2000 Watchdog"
depends on WATCHDOG && ARCH_IXP2000
help
Say Y here if to include support for the watchdog timer
in the Intel IXP2000(2400, 2800, 2850) network processors.
This driver can be built as a module by choosing M. The module
will be called ixp2000_wdt.
Say N if you are unsure.
config S3C2410_WATCHDOG config S3C2410_WATCHDOG
tristate "S3C2410 Watchdog" tristate "S3C2410 Watchdog"
depends on WATCHDOG && ARCH_S3C2410 depends on WATCHDOG && ARCH_S3C2410
...@@ -233,6 +233,16 @@ config IB700_WDT ...@@ -233,6 +233,16 @@ config IB700_WDT
Most people will say N. Most people will say N.
config IBMASR
tristate "IBM Automatic Server Restart"
depends on WATCHDOG && X86
help
This is the driver for the IBM Automatic Server Restart watchdog
timer builtin into some eServer xSeries machines.
To compile this driver as a module, choose M here: the
module will be called ibmasr.
config WAFER_WDT config WAFER_WDT
tristate "ICP Wafer 5823 Single Board Computer Watchdog" tristate "ICP Wafer 5823 Single Board Computer Watchdog"
depends on WATCHDOG && X86 depends on WATCHDOG && X86
...@@ -243,6 +253,16 @@ config WAFER_WDT ...@@ -243,6 +253,16 @@ config WAFER_WDT
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called wafer5823wdt. module will be called wafer5823wdt.
config I6300ESB_WDT
tristate "Intel 6300ESB Timer/Watchdog"
depends on WATCHDOG && X86 && PCI
---help---
Hardware driver for the watchdog timer built into the Intel
6300ESB controller hub.
To compile this driver as a module, choose M here: the
module will be called i6300esb.
config I8XX_TCO config I8XX_TCO
tristate "Intel i8xx TCO Timer/Watchdog" tristate "Intel i8xx TCO Timer/Watchdog"
depends on WATCHDOG && (X86 || IA64) && PCI depends on WATCHDOG && (X86 || IA64) && PCI
...@@ -298,6 +318,19 @@ config 60XX_WDT ...@@ -298,6 +318,19 @@ config 60XX_WDT
You can compile this driver directly into the kernel, or use You can compile this driver directly into the kernel, or use
it as a module. The module will be called sbc60xxwdt. it as a module. The module will be called sbc60xxwdt.
config SBC8360_WDT
tristate "SBC8360 Watchdog Timer"
depends on WATCHDOG && X86
---help---
This is the driver for the hardware watchdog on the SBC8360 Single
Board Computer produced by Axiomtek Co., Ltd. (www.axiomtek.com).
To compile this driver as a module, choose M here: the
module will be called sbc8360.ko.
Most people will say N.
config CPU5_WDT config CPU5_WDT
tristate "SMA CPU5 Watchdog" tristate "SMA CPU5 Watchdog"
depends on WATCHDOG && X86 depends on WATCHDOG && X86
...@@ -336,6 +369,19 @@ config W83877F_WDT ...@@ -336,6 +369,19 @@ config W83877F_WDT
Most people will say N. Most people will say N.
config W83977F_WDT
tristate "W83977F (PCM-5335) Watchdog Timer"
depends on WATCHDOG && X86
---help---
This is the driver for the hardware watchdog on the W83977F I/O chip
as used in AAEON's PCM-5335 SBC (and likely others). This
watchdog simply watches your kernel to make sure it doesn't freeze,
and if it does, it reboots your computer after a certain amount of
time.
To compile this driver as a module, choose M here: the
module will be called w83977f_wdt.
config MACHZ_WDT config MACHZ_WDT
tristate "ZF MachZ Watchdog" tristate "ZF MachZ Watchdog"
depends on WATCHDOG && X86 depends on WATCHDOG && X86
...@@ -355,6 +401,10 @@ config 8xx_WDT ...@@ -355,6 +401,10 @@ config 8xx_WDT
tristate "MPC8xx Watchdog Timer" tristate "MPC8xx Watchdog Timer"
depends on WATCHDOG && 8xx depends on WATCHDOG && 8xx
config MV64X60_WDT
tristate "MV64X60 (Marvell Discovery) Watchdog Timer"
depends on WATCHDOG && MV64X60
config BOOKE_WDT config BOOKE_WDT
tristate "PowerPC Book-E Watchdog Timer" tristate "PowerPC Book-E Watchdog Timer"
depends on WATCHDOG && (BOOKE || 4xx) depends on WATCHDOG && (BOOKE || 4xx)
...@@ -362,6 +412,17 @@ config BOOKE_WDT ...@@ -362,6 +412,17 @@ config BOOKE_WDT
Please see Documentation/watchdog/watchdog-api.txt for Please see Documentation/watchdog/watchdog-api.txt for
more information. more information.
# PPC64 Architecture
config WATCHDOG_RTAS
tristate "RTAS watchdog"
depends on WATCHDOG && PPC_RTAS
help
This driver adds watchdog support for the RTAS watchdog.
To compile this driver as a module, choose M here. The module
will be called wdrtas.
# MIPS Architecture # MIPS Architecture
config INDYDOG config INDYDOG
...@@ -430,16 +491,6 @@ config WATCHDOG_RIO ...@@ -430,16 +491,6 @@ config WATCHDOG_RIO
machines. The watchdog timeout period is normally one minute but machines. The watchdog timeout period is normally one minute but
can be changed with a boot-time parameter. can be changed with a boot-time parameter.
# ppc64 RTAS watchdog
config WATCHDOG_RTAS
tristate "RTAS watchdog"
depends on WATCHDOG && PPC_RTAS
help
This driver adds watchdog support for the RTAS watchdog.
To compile this driver as a module, choose M here. The module
will be called wdrtas.
# #
# ISA-based Watchdog Cards # ISA-based Watchdog Cards
# #
......
...@@ -39,22 +39,27 @@ obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o ...@@ -39,22 +39,27 @@ obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
obj-$(CONFIG_SC520_WDT) += sc520_wdt.o obj-$(CONFIG_SC520_WDT) += sc520_wdt.o
obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o
obj-$(CONFIG_IB700_WDT) += ib700wdt.o obj-$(CONFIG_IB700_WDT) += ib700wdt.o
obj-$(CONFIG_IBMASR) += ibmasr.o
obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o
obj-$(CONFIG_I8XX_TCO) += i8xx_tco.o obj-$(CONFIG_I8XX_TCO) += i8xx_tco.o
obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
obj-$(CONFIG_SBC8360_WDT) += sbc8360.o
obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o
obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o
obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o
obj-$(CONFIG_W83977F_WDT) += w83977f_wdt.o
obj-$(CONFIG_MACHZ_WDT) += machzwd.o obj-$(CONFIG_MACHZ_WDT) += machzwd.o
# PowerPC Architecture # PowerPC Architecture
obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o
obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o
# PPC64 Architecture # PPC64 Architecture
obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o
obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o
# MIPS Architecture # MIPS Architecture
obj-$(CONFIG_INDYDOG) += indydog.o obj-$(CONFIG_INDYDOG) += indydog.o
......
This diff is collapsed.
/*
* IBM Automatic Server Restart driver.
*
* Copyright (c) 2005 Andrey Panin <pazke@donpac.ru>
*
* Based on driver written by Pete Reynolds.
* Copyright (c) IBM Corporation, 1998-2004.
*
* This software may be used and distributed according to the terms
* of the GNU Public License, incorporated herein by reference.
*/
#include <linux/config.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/timer.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/dmi.h>
#include <asm/io.h>
#include <asm/uaccess.h>
enum {
ASMTYPE_UNKNOWN,
ASMTYPE_TOPAZ,
ASMTYPE_JASPER,
ASMTYPE_PEARL,
ASMTYPE_JUNIPER,
ASMTYPE_SPRUCE,
};
#define PFX "ibmasr: "
#define TOPAZ_ASR_REG_OFFSET 4
#define TOPAZ_ASR_TOGGLE 0x40
#define TOPAZ_ASR_DISABLE 0x80
/* PEARL ASR S/W REGISTER SUPERIO PORT ADDRESSES */
#define PEARL_BASE 0xe04
#define PEARL_WRITE 0xe06
#define PEARL_READ 0xe07
#define PEARL_ASR_DISABLE_MASK 0x80 /* bit 7: disable = 1, enable = 0 */
#define PEARL_ASR_TOGGLE_MASK 0x40 /* bit 6: 0, then 1, then 0 */
/* JASPER OFFSET FROM SIO BASE ADDR TO ASR S/W REGISTERS. */
#define JASPER_ASR_REG_OFFSET 0x38
#define JASPER_ASR_DISABLE_MASK 0x01 /* bit 0: disable = 1, enable = 0 */
#define JASPER_ASR_TOGGLE_MASK 0x02 /* bit 1: 0, then 1, then 0 */
#define JUNIPER_BASE_ADDRESS 0x54b /* Base address of Juniper ASR */
#define JUNIPER_ASR_DISABLE_MASK 0x01 /* bit 0: disable = 1 enable = 0 */
#define JUNIPER_ASR_TOGGLE_MASK 0x02 /* bit 1: 0, then 1, then 0 */
#define SPRUCE_BASE_ADDRESS 0x118e /* Base address of Spruce ASR */
#define SPRUCE_ASR_DISABLE_MASK 0x01 /* bit 1: disable = 1 enable = 0 */
#define SPRUCE_ASR_TOGGLE_MASK 0x02 /* bit 0: 0, then 1, then 0 */
static int nowayout = WATCHDOG_NOWAYOUT;
static unsigned long asr_is_open;
static char asr_expect_close;
static unsigned int asr_type, asr_base, asr_length;
static unsigned int asr_read_addr, asr_write_addr;
static unsigned char asr_toggle_mask, asr_disable_mask;
static void asr_toggle(void)
{
unsigned char reg = inb(asr_read_addr);
outb(reg & ~asr_toggle_mask, asr_write_addr);
reg = inb(asr_read_addr);
outb(reg | asr_toggle_mask, asr_write_addr);
reg = inb(asr_read_addr);
outb(reg & ~asr_toggle_mask, asr_write_addr);
reg = inb(asr_read_addr);
}
static void asr_enable(void)
{
unsigned char reg;
if (asr_type == ASMTYPE_TOPAZ) {
/* asr_write_addr == asr_read_addr */
reg = inb(asr_read_addr);
outb(reg & ~(TOPAZ_ASR_TOGGLE | TOPAZ_ASR_DISABLE),
asr_read_addr);
} else {
/*
* First make sure the hardware timer is reset by toggling
* ASR hardware timer line.
*/
asr_toggle();
reg = inb(asr_read_addr);
outb(reg & ~asr_disable_mask, asr_write_addr);
}
reg = inb(asr_read_addr);
}
static void asr_disable(void)
{
unsigned char reg = inb(asr_read_addr);
if (asr_type == ASMTYPE_TOPAZ)
/* asr_write_addr == asr_read_addr */
outb(reg | TOPAZ_ASR_TOGGLE | TOPAZ_ASR_DISABLE,
asr_read_addr);
else {
outb(reg | asr_toggle_mask, asr_write_addr);
reg = inb(asr_read_addr);
outb(reg | asr_disable_mask, asr_write_addr);
}
reg = inb(asr_read_addr);
}
static int __init asr_get_base_address(void)
{
unsigned char low, high;
const char *type = "";
asr_length = 1;
switch (asr_type) {
case ASMTYPE_TOPAZ:
/* SELECT SuperIO CHIP FOR QUERYING (WRITE 0x07 TO BOTH 0x2E and 0x2F) */
outb(0x07, 0x2e);
outb(0x07, 0x2f);
/* SELECT AND READ THE HIGH-NIBBLE OF THE GPIO BASE ADDRESS */
outb(0x60, 0x2e);
high = inb(0x2f);
/* SELECT AND READ THE LOW-NIBBLE OF THE GPIO BASE ADDRESS */
outb(0x61, 0x2e);
low = inb(0x2f);
asr_base = (high << 16) | low;
asr_read_addr = asr_write_addr =
asr_base + TOPAZ_ASR_REG_OFFSET;
asr_length = 5;
break;
case ASMTYPE_JASPER:
type = "Jaspers ";
/* FIXME: need to use pci_config_lock here, but it's not exported */
/* spin_lock_irqsave(&pci_config_lock, flags);*/
/* Select the SuperIO chip in the PCI I/O port register */
outl(0x8000f858, 0xcf8);
/*
* Read the base address for the SuperIO chip.
* Only the lower 16 bits are valid, but the address is word
* aligned so the last bit must be masked off.
*/
asr_base = inl(0xcfc) & 0xfffe;
/* spin_unlock_irqrestore(&pci_config_lock, flags);*/
asr_read_addr = asr_write_addr =
asr_base + JASPER_ASR_REG_OFFSET;
asr_toggle_mask = JASPER_ASR_TOGGLE_MASK;
asr_disable_mask = JASPER_ASR_DISABLE_MASK;
asr_length = JASPER_ASR_REG_OFFSET + 1;
break;
case ASMTYPE_PEARL:
type = "Pearls ";
asr_base = PEARL_BASE;
asr_read_addr = PEARL_READ;
asr_write_addr = PEARL_WRITE;
asr_toggle_mask = PEARL_ASR_TOGGLE_MASK;
asr_disable_mask = PEARL_ASR_DISABLE_MASK;
asr_length = 4;
break;
case ASMTYPE_JUNIPER:
type = "Junipers ";
asr_base = JUNIPER_BASE_ADDRESS;
asr_read_addr = asr_write_addr = asr_base;
asr_toggle_mask = JUNIPER_ASR_TOGGLE_MASK;
asr_disable_mask = JUNIPER_ASR_DISABLE_MASK;
break;
case ASMTYPE_SPRUCE:
type = "Spruce's ";
asr_base = SPRUCE_BASE_ADDRESS;
asr_read_addr = asr_write_addr = asr_base;
asr_toggle_mask = SPRUCE_ASR_TOGGLE_MASK;
asr_disable_mask = SPRUCE_ASR_DISABLE_MASK;
break;
}
if (!request_region(asr_base, asr_length, "ibmasr")) {
printk(KERN_ERR PFX "address %#x already in use\n",
asr_base);
return -EBUSY;
}
printk(KERN_INFO PFX "found %sASR @ addr %#x\n", type, asr_base);
return 0;
}
static ssize_t asr_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 */
asr_expect_close = 0;
for (i = 0; i != count; i++) {
char c;
if (get_user(c, buf + i))
return -EFAULT;
if (c == 'V')
asr_expect_close = 42;
}
}
asr_toggle();
}
return count;
}
static int asr_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
static const struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING |
WDIOF_MAGICCLOSE,
.identity = "IBM ASR"
};
void __user *argp = (void __user *)arg;
int __user *p = argp;
int heartbeat;
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:
asr_toggle();
return 0;
/*
* The hardware has a fixed timeout value, so no WDIOC_SETTIMEOUT
* and WDIOC_GETTIMEOUT always returns 256.
*/
case WDIOC_GETTIMEOUT:
heartbeat = 256;
return put_user(heartbeat, p);
case WDIOC_SETOPTIONS: {
int new_options, retval = -EINVAL;
if (get_user(new_options, p))
return -EFAULT;
if (new_options & WDIOS_DISABLECARD) {
asr_disable();
retval = 0;
}
if (new_options & WDIOS_ENABLECARD) {
asr_enable();
asr_toggle();
retval = 0;
}
return retval;
}
}
return -ENOIOCTLCMD;
}
static int asr_open(struct inode *inode, struct file *file)
{
if(test_and_set_bit(0, &asr_is_open))
return -EBUSY;
asr_toggle();
asr_enable();
return nonseekable_open(inode, file);
}
static int asr_release(struct inode *inode, struct file *file)
{
if (asr_expect_close == 42)
asr_disable();
else {
printk(KERN_CRIT PFX "unexpected close, not stopping watchdog!\n");
asr_toggle();
}
clear_bit(0, &asr_is_open);
asr_expect_close = 0;
return 0;
}
static struct file_operations asr_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.write = asr_write,
.ioctl = asr_ioctl,
.open = asr_open,
.release = asr_release,
};
static struct miscdevice asr_miscdev = {
.minor = WATCHDOG_MINOR,
.name = "watchdog",
.fops = &asr_fops,
};
struct ibmasr_id {
const char *desc;
int type;
};
static struct ibmasr_id __initdata ibmasr_id_table[] = {
{ "IBM Automatic Server Restart - eserver xSeries 220", ASMTYPE_TOPAZ },
{ "IBM Automatic Server Restart - Machine Type 8673", ASMTYPE_PEARL },
{ "IBM Automatic Server Restart - Machine Type 8480", ASMTYPE_JASPER },
{ "IBM Automatic Server Restart - Machine Type 8482", ASMTYPE_JUNIPER },
{ "IBM Automatic Server Restart - Machine Type 8648", ASMTYPE_SPRUCE },
{ NULL }
};
static int __init ibmasr_init(void)
{
struct ibmasr_id *id;
int rc;
for (id = ibmasr_id_table; id->desc; id++) {
if (dmi_find_device(DMI_DEV_TYPE_OTHER, id->desc, NULL)) {
asr_type = id->type;
break;
}
}
if (!asr_type)
return -ENODEV;
rc = misc_register(&asr_miscdev);
if (rc < 0) {
printk(KERN_ERR PFX "failed to register misc device\n");
return rc;
}
rc = asr_get_base_address();
if (rc) {
misc_deregister(&asr_miscdev);
return rc;
}
return 0;
}
static void __exit ibmasr_exit(void)
{
if (!nowayout)
asr_disable();
misc_deregister(&asr_miscdev);
release_region(asr_base, asr_length);
}
module_init(ibmasr_init);
module_exit(ibmasr_exit);
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
MODULE_DESCRIPTION("IBM Automatic Server Restart driver");
MODULE_AUTHOR("Andrey Panin");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
/*
* mv64x60_wdt.c - MV64X60 (Marvell Discovery) watchdog userspace interface
*
* Author: James Chapman <jchapman@katalix.com>
*
* Platform-specific setup code should configure the dog to generate
* interrupt or reset as required. This code only enables/disables
* and services the watchdog.
*
* Derived from mpc8xx_wdt.c, with the following copyright.
*
* 2002 (c) Florian Schirmer <jolt@tuxbox.org> This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/config.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/watchdog.h>
#include <asm/mv64x60.h>
#include <asm/uaccess.h>
#include <asm/io.h>
/* MV64x60 WDC (config) register access definitions */
#define MV64x60_WDC_CTL1_MASK (3 << 24)
#define MV64x60_WDC_CTL1(val) ((val & 3) << 24)
#define MV64x60_WDC_CTL2_MASK (3 << 26)
#define MV64x60_WDC_CTL2(val) ((val & 3) << 26)
/* Flags bits */
#define MV64x60_WDOG_FLAG_OPENED 0
#define MV64x60_WDOG_FLAG_ENABLED 1
static unsigned long wdt_flags;
static int wdt_status;
static void __iomem *mv64x60_regs;
static int mv64x60_wdt_timeout;
static void mv64x60_wdt_reg_write(u32 val)
{
/* Allow write only to CTL1 / CTL2 fields, retaining values in
* other fields.
*/
u32 data = readl(mv64x60_regs + MV64x60_WDT_WDC);
data &= ~(MV64x60_WDC_CTL1_MASK | MV64x60_WDC_CTL2_MASK);
data |= val;
writel(data, mv64x60_regs + MV64x60_WDT_WDC);
}
static void mv64x60_wdt_service(void)
{
/* Write 01 followed by 10 to CTL2 */
mv64x60_wdt_reg_write(MV64x60_WDC_CTL2(0x01));
mv64x60_wdt_reg_write(MV64x60_WDC_CTL2(0x02));
}
static void mv64x60_wdt_handler_disable(void)
{
if (test_and_clear_bit(MV64x60_WDOG_FLAG_ENABLED, &wdt_flags)) {
/* Write 01 followed by 10 to CTL1 */
mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x01));
mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x02));
printk(KERN_NOTICE "mv64x60_wdt: watchdog deactivated\n");
}
}
static void mv64x60_wdt_handler_enable(void)
{
if (!test_and_set_bit(MV64x60_WDOG_FLAG_ENABLED, &wdt_flags)) {
/* Write 01 followed by 10 to CTL1 */
mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x01));
mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x02));
printk(KERN_NOTICE "mv64x60_wdt: watchdog activated\n");
}
}
static int mv64x60_wdt_open(struct inode *inode, struct file *file)
{
if (test_and_set_bit(MV64x60_WDOG_FLAG_OPENED, &wdt_flags))
return -EBUSY;
mv64x60_wdt_service();
mv64x60_wdt_handler_enable();
return 0;
}
static int mv64x60_wdt_release(struct inode *inode, struct file *file)
{
mv64x60_wdt_service();
#if !defined(CONFIG_WATCHDOG_NOWAYOUT)
mv64x60_wdt_handler_disable();
#endif
clear_bit(MV64x60_WDOG_FLAG_OPENED, &wdt_flags);
return 0;
}
static ssize_t mv64x60_wdt_write(struct file *file, const char *data,
size_t len, loff_t * ppos)
{
if (*ppos != file->f_pos)
return -ESPIPE;
if (len)
mv64x60_wdt_service();
return len;
}
static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
int timeout;
static struct watchdog_info info = {
.options = WDIOF_KEEPALIVEPING,
.firmware_version = 0,
.identity = "MV64x60 watchdog",
};
switch (cmd) {
case WDIOC_GETSUPPORT:
if (copy_to_user((void *)arg, &info, sizeof(info)))
return -EFAULT;
break;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
if (put_user(wdt_status, (int *)arg))
return -EFAULT;
wdt_status &= ~WDIOF_KEEPALIVEPING;
break;
case WDIOC_GETTEMP:
return -EOPNOTSUPP;
case WDIOC_SETOPTIONS:
return -EOPNOTSUPP;
case WDIOC_KEEPALIVE:
mv64x60_wdt_service();
wdt_status |= WDIOF_KEEPALIVEPING;
break;
case WDIOC_SETTIMEOUT:
return -EOPNOTSUPP;
case WDIOC_GETTIMEOUT:
timeout = mv64x60_wdt_timeout * HZ;
if (put_user(timeout, (int *)arg))
return -EFAULT;
break;
default:
return -ENOIOCTLCMD;
}
return 0;
}
static struct file_operations mv64x60_wdt_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.write = mv64x60_wdt_write,
.ioctl = mv64x60_wdt_ioctl,
.open = mv64x60_wdt_open,
.release = mv64x60_wdt_release,
};
static struct miscdevice mv64x60_wdt_miscdev = {
.minor = WATCHDOG_MINOR,
.name = "watchdog",
.fops = &mv64x60_wdt_fops,
};
static int __devinit mv64x60_wdt_probe(struct device *dev)
{
struct platform_device *pd = to_platform_device(dev);
struct mv64x60_wdt_pdata *pdata = pd->dev.platform_data;
int bus_clk = 133;
mv64x60_wdt_timeout = 10;
if (pdata) {
mv64x60_wdt_timeout = pdata->timeout;
bus_clk = pdata->bus_clk;
}
mv64x60_regs = mv64x60_get_bridge_vbase();
writel((mv64x60_wdt_timeout * (bus_clk * 1000000)) >> 8,
mv64x60_regs + MV64x60_WDT_WDC);
return misc_register(&mv64x60_wdt_miscdev);
}
static int __devexit mv64x60_wdt_remove(struct device *dev)
{
misc_deregister(&mv64x60_wdt_miscdev);
mv64x60_wdt_service();
mv64x60_wdt_handler_disable();
return 0;
}
static struct device_driver mv64x60_wdt_driver = {
.name = MV64x60_WDT_NAME,
.bus = &platform_bus_type,
.probe = mv64x60_wdt_probe,
.remove = __devexit_p(mv64x60_wdt_remove),
};
static struct platform_device *mv64x60_wdt_dev;
static int __init mv64x60_wdt_init(void)
{
int ret;
printk(KERN_INFO "MV64x60 watchdog driver\n");
mv64x60_wdt_dev = platform_device_register_simple(MV64x60_WDT_NAME,
-1, NULL, 0);
if (IS_ERR(mv64x60_wdt_dev)) {
ret = PTR_ERR(mv64x60_wdt_dev);
goto out;
}
ret = driver_register(&mv64x60_wdt_driver);
out:
return ret;
}
static void __exit mv64x60_wdt_exit(void)
{
driver_unregister(&mv64x60_wdt_driver);
platform_device_unregister(mv64x60_wdt_dev);
}
module_init(mv64x60_wdt_init);
module_exit(mv64x60_wdt_exit);
MODULE_AUTHOR("James Chapman <jchapman@katalix.com>");
MODULE_DESCRIPTION("MV64x60 watchdog driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
...@@ -29,27 +29,29 @@ ...@@ -29,27 +29,29 @@
* Includes, defines, variables, module parameters, ... * Includes, defines, variables, module parameters, ...
*/ */
#include <linux/config.h> #include <linux/config.h> /* For CONFIG_WATCHDOG_NOWAYOUT/... */
#include <linux/module.h> #include <linux/module.h> /* For module specific items */
#include <linux/moduleparam.h> #include <linux/moduleparam.h> /* For new moduleparam's */
#include <linux/types.h> #include <linux/types.h> /* For standard types (like size_t) */
#include <linux/delay.h> #include <linux/errno.h> /* For the -ENODEV/... values */
#include <linux/miscdevice.h> #include <linux/kernel.h> /* For printk/panic/... */
#include <linux/watchdog.h> #include <linux/delay.h> /* For mdelay function */
#include <linux/notifier.h> #include <linux/miscdevice.h> /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */
#include <linux/reboot.h> #include <linux/watchdog.h> /* For the watchdog specific items */
#include <linux/init.h> #include <linux/notifier.h> /* For notifier support */
#include <linux/fs.h> #include <linux/reboot.h> /* For reboot_notifier stuff */
#include <linux/pci.h> #include <linux/init.h> /* For __init/__exit/... */
#include <linux/ioport.h> #include <linux/fs.h> /* For file operations */
#include <linux/spinlock.h> #include <linux/pci.h> /* For pci functions */
#include <linux/ioport.h> /* For io-port access */
#include <asm/uaccess.h> #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */
#include <asm/io.h>
#include <asm/uaccess.h> /* For copy_to_user/put_user/... */
#include <asm/io.h> /* For inb/outb/... */
/* Module and version information */ /* Module and version information */
#define WATCHDOG_VERSION "1.01" #define WATCHDOG_VERSION "1.01"
#define WATCHDOG_DATE "15 Mar 2005" #define WATCHDOG_DATE "02 Sep 2005"
#define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog" #define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog"
#define WATCHDOG_NAME "pcwd_pci" #define WATCHDOG_NAME "pcwd_pci"
#define PFX WATCHDOG_NAME ": " #define PFX WATCHDOG_NAME ": "
...@@ -335,12 +337,14 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file, ...@@ -335,12 +337,14 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file,
return -EFAULT; return -EFAULT;
if (new_options & WDIOS_DISABLECARD) { if (new_options & WDIOS_DISABLECARD) {
pcipcwd_stop(); if (pcipcwd_stop())
return -EIO;
retval = 0; retval = 0;
} }
if (new_options & WDIOS_ENABLECARD) { if (new_options & WDIOS_ENABLECARD) {
pcipcwd_start(); if (pcipcwd_start())
return -EIO;
retval = 0; retval = 0;
} }
......
...@@ -464,7 +464,7 @@ static void s3c2410wdt_shutdown(struct device *dev) ...@@ -464,7 +464,7 @@ static void s3c2410wdt_shutdown(struct device *dev)
static unsigned long wtcon_save; static unsigned long wtcon_save;
static unsigned long wtdat_save; static unsigned long wtdat_save;
static int s3c2410wdt_suspend(struct device *dev, u32 state, u32 level) static int s3c2410wdt_suspend(struct device *dev, pm_message_t state, u32 level)
{ {
if (level == SUSPEND_POWER_DOWN) { if (level == SUSPEND_POWER_DOWN) {
/* Save watchdog state, and turn it off. */ /* Save watchdog state, and turn it off. */
......
This diff is collapsed.
This diff is collapsed.
...@@ -119,6 +119,14 @@ extern spinlock_t mv64x60_lock; ...@@ -119,6 +119,14 @@ extern spinlock_t mv64x60_lock;
#define MV64x60_64BIT_WIN_COUNT 24 #define MV64x60_64BIT_WIN_COUNT 24
/* Watchdog Platform Device, Driver Data */
#define MV64x60_WDT_NAME "wdt"
struct mv64x60_wdt_pdata {
int timeout; /* watchdog expiry in seconds, default 10 */
int bus_clk; /* bus clock in MHz, default 133 */
};
/* /*
* Define a structure that's used to pass in config information to the * Define a structure that's used to pass in config information to the
* core routines. * core routines.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment