[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <52C79FDB.7000106@roeck-us.net>
Date: Fri, 03 Jan 2014 21:44:59 -0800
From: Guenter Roeck <linux@...ck-us.net>
To: eric.ernst@...ux.intel.com, wim@...ana.be,
linux-watchdog@...r.kernel.org, linux-kernel@...r.kernel.org
CC: Gabriel Touzeau <gabrielx.touzeau@...el.com>,
Yann Puech <yann.puech@...el.com>,
Jeremy Compostella <jeremy.compostella@...el.com>,
David Cohen <david.a.cohen@...ux.intel.com>
Subject: Re: [PATCH 1/1] watchdog: Adding Merrifield watchdog driver support
On 01/02/2014 04:56 PM, eric.ernst@...ux.intel.com wrote:
> From: Gabriel Touzeau <gabrielx.touzeau@...el.com>
>
> Added Merrifield watchdog driver support.
>
> Based on initial implementation from prior Intel SCU-based platforms, this
> driver has several changes specific to the Tangier SoC / Merrifield platform.
>
New watchdog drivers should be implemented using the watchdog subsystem.
> Signed-off-by: Eric Ernst <eric.ernst@...ux.intel.com>
> Signed-off-by: Yann Puech <yann.puech@...el.com>
> Signed-off-by: Jeremy Compostella <jeremy.compostella@...el.com>
> Signed-off-by: Gabriel Touzeau <gabrielx.touzeau@...el.com>
> Cc: David Cohen <david.a.cohen@...ux.intel.com>
> ---
> drivers/watchdog/Kconfig | 12 +
> drivers/watchdog/Makefile | 1 +
> drivers/watchdog/intel_scu_watchdog_evo.c | 587 +++++++++++++++++++++++++++++
> drivers/watchdog/intel_scu_watchdog_evo.h | 54 +++
> 4 files changed, 654 insertions(+)
> create mode 100644 drivers/watchdog/intel_scu_watchdog_evo.c
> create mode 100644 drivers/watchdog/intel_scu_watchdog_evo.h
>
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index d1d53f301de7..bb3ef92d2788 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -616,6 +616,18 @@ config INTEL_SCU_WATCHDOG
>
> To compile this driver as a module, choose M here.
>
> +config INTEL_SCU_WATCHDOG_EVO
> + bool "Intel SCU Watchdog Evolution for Mobile Platforms"
> + depends on X86_INTEL_MID
> + ---help---
> + Hardware driver evolution for the watchdog timer built into the Intel
> + SCU for Intel Mobile Platforms.
> +
> + This driver supports the watchdog evolution implementation in SCU,
"watchdog evolution" ... odd terminology.
> + available for Merrifield generation.
> +
> + To compile this driver as a module, choose M here.
> +
> config ITCO_WDT
> tristate "Intel TCO Timer/Watchdog"
> depends on (X86 || IA64) && PCI
> diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> index 6c5bb274d3cd..e4b150efa938 100644
> --- a/drivers/watchdog/Makefile
> +++ b/drivers/watchdog/Makefile
> @@ -112,6 +112,7 @@ obj-$(CONFIG_W83977F_WDT) += w83977f_wdt.o
> obj-$(CONFIG_MACHZ_WDT) += machzwd.o
> obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o
> obj-$(CONFIG_INTEL_SCU_WATCHDOG) += intel_scu_watchdog.o
> +obj-$(CONFIG_INTEL_SCU_WATCHDOG_EVO) += intel_scu_watchdog_evo.o
>
> # M32R Architecture
>
> diff --git a/drivers/watchdog/intel_scu_watchdog_evo.c b/drivers/watchdog/intel_scu_watchdog_evo.c
> new file mode 100644
> index 000000000000..fc9a37a33ddd
> --- /dev/null
> +++ b/drivers/watchdog/intel_scu_watchdog_evo.c
> @@ -0,0 +1,587 @@
> +/*
> + * intel_scu_watchdog_evo: An Intel SCU IOH Based Watchdog Device
> + * for Tangier SoC (Merrifield platform)
> + *
> + * Based on previous intel_scu based watchdog driver, intel_scu_watchdog.
> + *
> + * Copyright (C) 2009-2013 Intel Corporation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of version 2 of the GNU General
> + * Public License as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be
> + * useful, but WITHOUT ANY WARRANTY; without even the implied
> + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
> + * PURPOSE. See the GNU General Public License for more details.
> + * You should have received a copy of the GNU General Public
> + * License along with this program; if not, write to the Free
> + * Software Foundation, Inc., 59 Temple Place - Suite 330,
> + * Boston, MA 02111-1307, USA.
> + * The full GNU General Public License is included in this
> + * distribution in the file called COPYING.
> + *
Providing the FSF address is discouraged, and using it results in checkpatch errors.
> + */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> +#include <linux/interrupt.h>
> +#include <linux/kernel_stat.h>
> +#include <linux/miscdevice.h>
> +#include <linux/module.h>
> +#include <linux/nmi.h>
> +#include <linux/reboot.h>
> +#include <linux/fs.h>
> +#include <linux/watchdog.h>
> +#include <asm/intel-mid.h>
> +#include <asm/intel_scu_ipc.h>
> +
> +#include "intel_scu_watchdog_evo.h"
> +
> +/* Defines */
> +#define STRING_RESET_TYPE_MAX_LEN 11
> +#define STRING_COLD_OFF "COLD_OFF"
> +#define STRING_COLD_RESET "COLD_RESET"
> +#define STRING_COLD_BOOT "COLD_BOOT"
> +
> +#define EXT_TIMER0_MSI 15
> +
> +#define IPC_WATCHDOG 0xf8
> +
> +/* watchdog message options */
> +enum {
> + SCU_WATCHDOG_START = 0,
> + SCU_WATCHDOG_STOP,
> + SCU_WATCHDOG_KEEPALIVE,
> + SCU_WATCHDOG_SET_ACTION_ON_TIMEOUT
> +};
> +
> +/* watchdog reset options */
> +enum {
> + SCU_COLD_OFF_ON_TIMEOUT = 0,
> + SCU_COLD_RESET_ON_TIMEOUT,
> + SCU_COLD_BOOT_ON_TIMEOUT,
> + SCU_DO_NOTHING_ON_TIMEOUT
> +};
> +
> +/* Statics */
> +static struct intel_scu_watchdog_dev watchdog_device;
> +
> +/* Module params */
> +static bool disable_kernel_watchdog;
> +module_param(disable_kernel_watchdog, bool, S_IRUGO);
> +MODULE_PARM_DESC(disable_kernel_watchdog,
> + "Disable kernel watchdog"
> + "Set to 0, watchdog started at boot"
> + "and left running; Set to 1; watchdog"
> + "is not started until user space"
> + "watchdog daemon is started; also if the"
> + "timer is started by the iafw firmware, it"
> + "will be disabled upon initialization of this"
> + "driver if disable_kernel_watchdog is set");
> +
> +static int pre_timeout = DEFAULT_PRETIMEOUT;
> +module_param(pre_timeout, int, S_IRUGO | S_IWUSR);
> +MODULE_PARM_DESC(pre_timeout,
> + "Watchdog pre timeout"
> + "Time between interrupt and resetting the system"
> + "The range is from 1 to 160");
> +
> +static int timeout = DEFAULT_TIMEOUT;
> +module_param(timeout, int, S_IRUGO | S_IWUSR);
> +MODULE_PARM_DESC(timeout,
> + "Default Watchdog timer setting"
> + "Complete cycle time"
> + "The range is from 1 to 170"
> + "This is the time for all keep alives to arrive");
> +
> +/* Setting reset_on_release will cause an immediate reset when the watchdog
> + * is released. If false, the watchdog timer is refreshed for one more
> + * interval. At the end of that interval, the watchdog timer will reset the
> + * system.
> + */
> +static bool reset_on_release = true;
> +
> +/* Check current timeouts */
> +static int check_timeouts(int pre_timeout_time, int timeout_time)
> +{
> + if (pre_timeout_time < timeout_time)
> + return 0;
> +
> + return -EINVAL;
> +}
> +
> +/* Set the different timeouts needed by the SCU FW and start the
> + * kernel watchdog */
> +static int watchdog_set_timeouts_and_start(int pretimeout,
> + int timeout)
> +{
> + int ret, input_size;
> + struct ipc_wd_start {
> + u32 pretimeout;
> + u32 timeout;
> + } ipc_wd_start = { pretimeout, timeout };
> +
> + /* SCU expects the input size for watchdog IPC to
> + * be based on double-word */
> + input_size = (sizeof(ipc_wd_start) + 3) / 4;
> +
> + ret = intel_scu_ipc_command(IPC_WATCHDOG,
> + SCU_WATCHDOG_START, (u32 *)&ipc_wd_start,
> + input_size, NULL, 0);
> + if (ret) {
> + pr_crit("Error configuring and starting watchdog: %d\n",
> + ret);
> + return -EIO;
> + }
> +
> + return 0;
> +}
> +
> +/* Provisioning function for future enhancement : allow to fine tune timing
> + according to watchdog action settings */
> +static int watchdog_set_appropriate_timeouts(void)
> +{
> + pr_debug("Setting shutdown timeouts\n");
> + return watchdog_set_timeouts_and_start(pre_timeout, timeout);
> +}
> +
> +/* Keep alive */
> +static int watchdog_keepalive(void)
> +{
> + int ret;
> +
> + /* Pet the watchdog */
> + ret = intel_scu_ipc_command(IPC_WATCHDOG,
> + SCU_WATCHDOG_KEEPALIVE, NULL, 0, NULL, 0);
> + if (ret) {
> + pr_crit("Error executing keepalive: %x\n", ret);
> + return -EIO;
> + }
> +
> + return 0;
> +}
> +
> +/* stops the timer */
> +static int watchdog_stop(void)
> +{
> + int ret;
> +
> + watchdog_device.started = false;
> +
> + ret = intel_scu_ipc_command(IPC_WATCHDOG,
> + SCU_WATCHDOG_STOP, NULL, 0, NULL, 0);
> + if (ret) {
> + pr_crit("Error stopping watchdog: %x\n", ret);
> + return -EIO;
> + }
> + return 0;
> +}
> +
> +/* warning interrupt handler */
> +static irqreturn_t watchdog_warning_interrupt(int irq, void *dev_id)
> +{
> + pr_warn("[SHTDWN] %s, WATCHDOG TIMEOUT!\n", __func__);
> +
> + /* Let's reset the platform after dumping some data */
> + trigger_all_cpu_backtrace();
> + panic("Kernel Watchdog");
> +
> + /* This code should not be reached */
> + return IRQ_HANDLED;
> +}
> +
> +/* Program and starts the timer */
> +static int watchdog_config_and_start(u32 newtimeout, u32 newpretimeout)
> +{
> + int ret;
> +
> + timeout = newtimeout;
> + pre_timeout = newpretimeout;
> +
> + pr_info("timeout=%ds, pre_timeout=%ds\n", timeout, pre_timeout);
> +
> + /* Configure the watchdog */
> + ret = watchdog_set_timeouts_and_start(pre_timeout, timeout);
> + if (ret) {
> + pr_err("%s: Cannot configure the watchdog\n", __func__);
> +
> + /* Make sure the watchdog timer is stopped */
> + watchdog_stop();
> + return ret;
> + }
> +
> + watchdog_device.started = true;
> +
> + return 0;
> +}
> +
> +/* Open */
> +static int intel_scu_open(struct inode *inode, struct file *file)
> +{
> + /* Set flag to indicate that watchdog device is open */
> + if (test_and_set_bit(0, &watchdog_device.driver_open)) {
> + pr_err("watchdog device is busy\n");
> + return -EBUSY;
> + }
> +
> + return nonseekable_open(inode, file);
> +}
> +
> +/* Release */
> +static int intel_scu_release(struct inode *inode, struct file *file)
> +{
> + /*
> + * This watchdog should not be closed after the timer
> + * is started with the WDIPC_SETTIMEOUT ioctl.
> + * If reset_on_release is set this will cause an
> + * immediate reset. If reset_on_release is not set, the watchdog
> + * timer is refreshed for one more interval. At the end
> + * of that interval, the watchdog timer will reset the system.
> + */
> +
> + if (!test_bit(0, &watchdog_device.driver_open)) {
> + pr_err("intel_scu_release, without open\n");
> + return -ENOTTY;
> + }
> +
> + if (!watchdog_device.started) {
> + /* Just close, since timer has not been started */
> + pr_err("Closed, without starting timer\n");
> + return 0;
> + }
> +
> + /* The watchdog should not be closed after the timer is started */
> + pr_crit("Unexpected close of /dev/watchdog!\n");
> +
> + /* Refresh the timer for one more interval */
> + watchdog_keepalive();
> +
> + /* Reboot system if requested */
> + if (reset_on_release) {
> + pr_crit("Initiating system reboot.\n");
> + emergency_restart();
> + }
> +
> + pr_crit("Immediate Reboot Disabled\n");
> + pr_crit("System will reset when watchdog timer expire!\n");
> +
> + return 0;
> +}
> +
> +/* Write */
> +static ssize_t intel_scu_write(struct file *file, char const *data, size_t len,
> + loff_t *ppos)
> +{
> + if (watchdog_device.shutdown_flag == true)
> + /* do nothing if we are shutting down */
> + return len;
> +
> + if (watchdog_device.started) {
> + /* Watchdog already started, keep it alive */
> + watchdog_keepalive();
> + }
> +
> + return len;
> +}
> +
> +/* ioctl */
> +static long intel_scu_ioctl(struct file *file, unsigned int cmd,
> + unsigned long arg)
> +{
> + void __user *argp = (void __user *)arg;
> + u32 __user *p = argp;
> + u32 val;
> + int options;
> +
> + static const struct watchdog_info ident = {
> + .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
> + /* @todo Get from SCU via ipc_get_scu_fw_version */
> + .firmware_version = 0,
> + /* len < 32 */
> + .identity = "Intel_SCU IOH Watchdog"
> + };
> +
> + 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:
> + if (!watchdog_device.started)
> + return -EINVAL;
> +
> + watchdog_keepalive();
> + return 0;
> + case WDIOC_SETPRETIMEOUT:
> + pr_info("%s: setpretimeout ioctl\n", __func__);
> +
> + if (watchdog_device.started)
> + return -EBUSY;
> +
> + /* Timeout to warn */
> + if (get_user(val, p))
> + return -EFAULT;
> +
> + pre_timeout = val;
> + return 0;
> + case WDIOC_SETTIMEOUT:
> + pr_info("%s: settimeout ioctl\n", __func__);
> +
> + if (watchdog_device.started)
> + return -EBUSY;
> +
> + if (get_user(val, p))
> + return -EFAULT;
> +
> + timeout = val;
> + return 0;
> + case WDIOC_GETTIMEOUT:
> + return put_user(timeout, p);
> + case WDIOC_SETOPTIONS:
> + if (get_user(options, p))
> + return -EFAULT;
> +
> + if (options & WDIOS_DISABLECARD) {
> + pr_info("%s: Stopping the watchdog\n", __func__);
> + watchdog_stop();
> + return 0;
> + }
> +
> + if (options & WDIOS_ENABLECARD) {
> + pr_info("%s: Starting the watchdog\n", __func__);
> +
> + if (watchdog_device.started)
> + return -EBUSY;
> +
> + if (check_timeouts(pre_timeout, timeout)) {
> + pr_warn("%s: Invalid thresholds\n",
> + __func__);
> + return -EINVAL;
> + }
> + if (watchdog_config_and_start(timeout, pre_timeout))
> + return -EINVAL;
> + return 0;
> + }
> + return 0;
> + default:
> + return -ENOTTY;
> + }
> +}
> +
> +static int watchdog_set_reset_type(int reset_type)
> +{
> + int ret, input_size;
> + u32 ipc_wd_on_timeout = reset_type;
> +
> + /* SCU expects the input size for watchdog IPC to
> + * be based on double-word */
> + input_size = (sizeof(ipc_wd_on_timeout) + 3) / 4;
> +
> + ret = intel_scu_ipc_command(IPC_WATCHDOG,
> + SCU_WATCHDOG_SET_ACTION_ON_TIMEOUT,
> + (u32 *)&ipc_wd_on_timeout,
> + input_size, NULL, 0);
> + if (ret) {
> + pr_crit("Error setting watchdog action: %d\n", ret);
> + return -EIO;
> + }
> +
> + watchdog_device.normal_wd_action = reset_type;
> +
> + return 0;
> +}
> +
> +/* Reboot notifier */
> +static int reboot_notifier(struct notifier_block *this,
> + unsigned long code,
> + void *another_unused)
> +{
> + int ret;
> +
> + if (code == SYS_RESTART || code == SYS_HALT || code == SYS_POWER_OFF) {
> + pr_warn("Reboot notifier\n");
> +
> + if (watchdog_set_appropriate_timeouts())
> + pr_crit("reboot notifier can't set time\n");
> +
> + switch (code) {
> + case SYS_RESTART:
> + ret = watchdog_set_reset_type(
> + watchdog_device.reboot_wd_action);
> + break;
> +
> + case SYS_HALT:
> + case SYS_POWER_OFF:
> + ret = watchdog_set_reset_type(
> + watchdog_device.shutdown_wd_action);
> + break;
> + }
> + if (ret)
> + pr_err("%s: could not set reset type\n", __func__);
> +
> + /* Don't do instant reset on close */
> + reset_on_release = false;
> +
> + /* Kick once again */
> + if (disable_kernel_watchdog == false) {
> + ret = watchdog_keepalive();
> + if (ret)
> + pr_warn("%s: no keep alive\n", __func__);
> +
> + /* Don't allow any more keep-alives */
> + watchdog_device.shutdown_flag = true;
> + }
> + }
> + return NOTIFY_DONE;
> +}
> +
> +
> +/* Kernel Interfaces */
> +static const struct file_operations intel_scu_fops = {
> + .owner = THIS_MODULE,
> + .llseek = no_llseek,
> + .write = intel_scu_write,
> + .unlocked_ioctl = intel_scu_ioctl,
> +#ifdef CONFIG_COMPAT
> + .compat_ioctl = intel_scu_ioctl,
> +#endif
> + .open = intel_scu_open,
> + .release = intel_scu_release,
> +};
> +
> +static int handle_mrfl_dev_ioapic(int irq)
> +{
> + int ioapic;
> + struct io_apic_irq_attr irq_attr;
> +
> + ioapic = mp_find_ioapic(irq);
> + if (ioapic >= 0) {
> + irq_attr.ioapic = ioapic;
> + irq_attr.ioapic_pin = irq;
> + irq_attr.trigger = 1;
> + irq_attr.polarity = 0; /* Active high */
> + io_apic_set_pci_routing(NULL, irq, &irq_attr);
> + } else {
> + pr_err("cannot find interrupt %d in ioapic\n", irq);
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +/* Init code */
> +static int __init intel_scu_watchdog_init(void)
> +{
> + int ret = 0;
> +
> + /*
> + * This is only valid for Merrifield based platforms
> + */
> + if (intel_mid_identify_cpu() != INTEL_MID_CPU_CHIP_TANGIER)
> + return -ENODEV;
> +
> + watchdog_device.normal_wd_action = SCU_COLD_RESET_ON_TIMEOUT;
> + watchdog_device.reboot_wd_action = SCU_COLD_RESET_ON_TIMEOUT;
> + watchdog_device.shutdown_wd_action = SCU_COLD_OFF_ON_TIMEOUT;
> +
> + /* Initially, we are not in shutdown mode */
> + watchdog_device.shutdown_flag = false;
> +
> + /* Check timeouts boot parameter */
> + if (check_timeouts(pre_timeout, timeout)) {
> + pr_err("%s: Invalid timeouts\n", __func__);
> + return -EINVAL;
> + }
> +
> + /* Reboot notifier */
> + watchdog_device.reboot_notifier.notifier_call = reboot_notifier;
> + watchdog_device.reboot_notifier.priority = 1;
> + ret = register_reboot_notifier(&watchdog_device.reboot_notifier);
> + if (ret) {
> + pr_crit("cannot register reboot notifier %d\n", ret);
> + goto error_stop_timer;
> + }
> +
> + /* Do not publish the watchdog device when disabled */
> + if (!disable_kernel_watchdog) {
> + watchdog_device.miscdev.minor = WATCHDOG_MINOR;
> + watchdog_device.miscdev.name = "watchdog";
> + watchdog_device.miscdev.fops = &intel_scu_fops;
> +
> + ret = misc_register(&watchdog_device.miscdev);
> + if (ret) {
> + pr_crit("Cannot register miscdev %d err =%d\n",
> + WATCHDOG_MINOR, ret);
> + goto error_reboot_notifier;
> + }
> + }
> +
> + /* MSI #15 handler to dump registers */
> + handle_mrfl_dev_ioapic(EXT_TIMER0_MSI);
> + ret = request_irq((unsigned int)EXT_TIMER0_MSI,
> + watchdog_warning_interrupt,
> + IRQF_SHARED|IRQF_NO_SUSPEND, "watchdog",
> + &watchdog_device);
> + if (ret) {
> + pr_err("error requesting warning irq %d\n",
> + EXT_TIMER0_MSI);
> + pr_err("error value returned is %d\n", ret);
> + goto error_misc_register;
> + }
> +
> + if (disable_kernel_watchdog) {
> + pr_info("%s: Disable kernel watchdog\n", __func__);
> +
> + /* Make sure timer is stopped */
> + ret = watchdog_stop();
> + if (ret != 0)
> + pr_warn("can't disable timer\n");
> + }
> +
> +
> + watchdog_device.started = false;
> +
> + return ret;
> +
> +error_misc_register:
> + misc_deregister(&watchdog_device.miscdev);
> +
> +error_reboot_notifier:
> + unregister_reboot_notifier(&watchdog_device.reboot_notifier);
> +
> +error_stop_timer:
> + watchdog_stop();
> +
> + return ret;
> +}
> +
> +static void __exit intel_scu_watchdog_exit(void)
> +{
> + int ret = 0;
> +
> + ret = watchdog_stop();
> + if (ret != 0)
> + pr_err("cant disable timer\n");
> +
> + misc_deregister(&watchdog_device.miscdev);
> + unregister_reboot_notifier(&watchdog_device.reboot_notifier);
> +}
> +
> +#ifdef MODULE
> +module_init(intel_scu_watchdog_init);
> +#else
> +rootfs_initcall(intel_scu_watchdog_init);
> +#endif
> +module_exit(intel_scu_watchdog_exit);
> +
> +MODULE_AUTHOR("Intel Corporation");
> +MODULE_AUTHOR("Gabriel Touzeau <gabrielx.touzeau@...el.com>");
> +MODULE_AUTHOR("Jeremy Compostella <jeremy.compostella@...el.com");
> +MODULE_AUTHOR("Eric Ernst <eric.ernst@...ux.intel.com>");
> +MODULE_DESCRIPTION("Intel SCU Watchdog Device Driver for Merrifield platform");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
> +MODULE_VERSION(WDT_VER);
> diff --git a/drivers/watchdog/intel_scu_watchdog_evo.h b/drivers/watchdog/intel_scu_watchdog_evo.h
> new file mode 100644
> index 000000000000..d53c568f65a5
> --- /dev/null
> +++ b/drivers/watchdog/intel_scu_watchdog_evo.h
> @@ -0,0 +1,54 @@
> +/*
> + * Intel_SCU 0.3: An Intel SCU IOH Based Watchdog Device
> + * for Intel's Tangier SoC / Merrifield platform
> + *
> + * Copyright (C) 2009-2013 Intel Corporation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of version 2 of the GNU General
> + * Public License as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be
> + * useful, but WITHOUT ANY WARRANTY; without even the implied
> + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
> + * PURPOSE. See the GNU General Public License for more details.
> + * You should have received a copy of the GNU General Public
> + * License along with this program; if not, write to the Free
> + * Software Foundation, Inc., 59 Temple Place - Suite 330,
> + * Boston, MA 02111-1307, USA.
> + * The full GNU General Public License is included in this
> + * distribution in the file called COPYING.
> + *
> + */
> +
> +#ifndef __INTEL_SCU_WATCHDOG_H
> +#define __INTEL_SCU_WATCHDOG_H
> +
> +#include <linux/miscdevice.h>
> +#include <linux/types.h>
> +#include <linux/notifier.h>
> +
> +#ifdef CONFIG_COMPAT
> +#include <linux/compat.h>
> +#endif
> +
> +#define PFX "intel_scu_watchdog: "
> +#define WDT_VER "0.3"
> +
> +#define DEFAULT_PRETIMEOUT 75
> +#define DEFAULT_TIMEOUT 90
> +
> +struct intel_scu_watchdog_dev {
> + ulong driver_open;
> + ulong driver_closed;
> + bool started;
> + struct notifier_block reboot_notifier;
> + struct miscdevice miscdev;
> + bool shutdown_flag;
> + int reset_type;
> + int normal_wd_action;
> + int reboot_wd_action;
> + int shutdown_wd_action;
> +};
> +
> +#endif /* __INTEL_SCU_WATCHDOG_H */
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists