Commit 59846793 authored by Alan Cox's avatar Alan Cox Committed by Wim Van Sebroeck

[WATCHDOG 46/57] smsc37b787_wdt: coding style, switch to unlocked_ioctl

Review and switch to unlocked_ioctl
Signed-off-by: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarWim Van Sebroeck <wim@iguana.be>
parent 70b814ec
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* History: * History:
* 2003 - Created version 1.0 for Linux 2.4.x. * 2003 - Created version 1.0 for Linux 2.4.x.
* 2006 - Ported to Linux 2.6, added nowayout and MAGICCLOSE * 2006 - Ported to Linux 2.6, added nowayout and MAGICCLOSE
* features. Released version 1.1 * features. Released version 1.1
* *
* Theory of operation: * Theory of operation:
* *
...@@ -55,9 +55,9 @@ ...@@ -55,9 +55,9 @@
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h> #include <asm/system.h>
/* enable support for minutes as units? */ /* enable support for minutes as units? */
...@@ -71,15 +71,15 @@ ...@@ -71,15 +71,15 @@
#define UNIT_MINUTE 1 #define UNIT_MINUTE 1
#define MODNAME "smsc37b787_wdt: " #define MODNAME "smsc37b787_wdt: "
#define VERSION "1.1" #define VERSION "1.1"
#define IOPORT 0x3F0 #define IOPORT 0x3F0
#define IOPORT_SIZE 2 #define IOPORT_SIZE 2
#define IODEV_NO 8 #define IODEV_NO 8
static int unit = UNIT_SECOND; /* timer's unit */ static int unit = UNIT_SECOND; /* timer's unit */
static int timeout = 60; /* timeout value: default is 60 "units" */ static int timeout = 60; /* timeout value: default is 60 "units" */
static unsigned long timer_enabled = 0; /* is the timer enabled? */ static unsigned long timer_enabled; /* is the timer enabled? */
static char expect_close; /* is the close expected? */ static char expect_close; /* is the close expected? */
...@@ -93,114 +93,121 @@ static int nowayout = WATCHDOG_NOWAYOUT; ...@@ -93,114 +93,121 @@ static int nowayout = WATCHDOG_NOWAYOUT;
static inline void open_io_config(void) static inline void open_io_config(void)
{ {
outb(0x55, IOPORT); outb(0x55, IOPORT);
mdelay(1); mdelay(1);
outb(0x55, IOPORT); outb(0x55, IOPORT);
} }
/* lock the IO chip */ /* lock the IO chip */
static inline void close_io_config(void) static inline void close_io_config(void)
{ {
outb(0xAA, IOPORT); outb(0xAA, IOPORT);
} }
/* select the IO device */ /* select the IO device */
static inline void select_io_device(unsigned char devno) static inline void select_io_device(unsigned char devno)
{ {
outb(0x07, IOPORT); outb(0x07, IOPORT);
outb(devno, IOPORT+1); outb(devno, IOPORT+1);
} }
/* write to the control register */ /* write to the control register */
static inline void write_io_cr(unsigned char reg, unsigned char data) static inline void write_io_cr(unsigned char reg, unsigned char data)
{ {
outb(reg, IOPORT); outb(reg, IOPORT);
outb(data, IOPORT+1); outb(data, IOPORT+1);
} }
/* read from the control register */ /* read from the control register */
static inline char read_io_cr(unsigned char reg) static inline char read_io_cr(unsigned char reg)
{ {
outb(reg, IOPORT); outb(reg, IOPORT);
return inb(IOPORT+1); return inb(IOPORT+1);
} }
/* -- Medium level functions ------------------------------------*/ /* -- Medium level functions ------------------------------------*/
static inline void gpio_bit12(unsigned char reg) static inline void gpio_bit12(unsigned char reg)
{ {
// -- General Purpose I/O Bit 1.2 -- /* -- General Purpose I/O Bit 1.2 --
// Bit 0, In/Out: 0 = Output, 1 = Input * Bit 0, In/Out: 0 = Output, 1 = Input
// Bit 1, Polarity: 0 = No Invert, 1 = Invert * Bit 1, Polarity: 0 = No Invert, 1 = Invert
// Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable * Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable
// Bit 3/4, Function select: 00 = GPI/O, 01 = WDT, 10 = P17, * Bit 3/4, Function select: 00 = GPI/O, 01 = WDT, 10 = P17,
// 11 = Either Edge Triggered Intr. 2 * 11 = Either Edge Triggered Intr. 2
// Bit 5/6 (Reserved) * Bit 5/6 (Reserved)
// Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain * Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain
write_io_cr(0xE2, reg); */
write_io_cr(0xE2, reg);
} }
static inline void gpio_bit13(unsigned char reg) static inline void gpio_bit13(unsigned char reg)
{ {
// -- General Purpose I/O Bit 1.3 -- /* -- General Purpose I/O Bit 1.3 --
// Bit 0, In/Out: 0 = Output, 1 = Input * Bit 0, In/Out: 0 = Output, 1 = Input
// Bit 1, Polarity: 0 = No Invert, 1 = Invert * Bit 1, Polarity: 0 = No Invert, 1 = Invert
// Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable * Bit 2, Group Enable Intr.: 0 = Disable, 1 = Enable
// Bit 3, Function select: 0 = GPI/O, 1 = LED * Bit 3, Function select: 0 = GPI/O, 1 = LED
// Bit 4-6 (Reserved) * Bit 4-6 (Reserved)
// Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain * Bit 7, Output Type: 0 = Push Pull Bit, 1 = Open Drain
write_io_cr(0xE3, reg); */
write_io_cr(0xE3, reg);
} }
static inline void wdt_timer_units(unsigned char new_units) static inline void wdt_timer_units(unsigned char new_units)
{ {
// -- Watchdog timer units -- /* -- Watchdog timer units --
// Bit 0-6 (Reserved) * Bit 0-6 (Reserved)
// Bit 7, WDT Time-out Value Units Select * Bit 7, WDT Time-out Value Units Select
// (0 = Minutes, 1 = Seconds) * (0 = Minutes, 1 = Seconds)
write_io_cr(0xF1, new_units); */
write_io_cr(0xF1, new_units);
} }
static inline void wdt_timeout_value(unsigned char new_timeout) static inline void wdt_timeout_value(unsigned char new_timeout)
{ {
// -- Watchdog Timer Time-out Value -- /* -- Watchdog Timer Time-out Value --
// Bit 0-7 Binary coded units (0=Disabled, 1..255) * Bit 0-7 Binary coded units (0=Disabled, 1..255)
write_io_cr(0xF2, new_timeout); */
write_io_cr(0xF2, new_timeout);
} }
static inline void wdt_timer_conf(unsigned char conf) static inline void wdt_timer_conf(unsigned char conf)
{ {
// -- Watchdog timer configuration -- /* -- Watchdog timer configuration --
// Bit 0 Joystick enable: 0* = No Reset, 1 = Reset WDT upon Gameport I/O * Bit 0 Joystick enable: 0* = No Reset, 1 = Reset WDT upon
// Bit 1 Keyboard enable: 0* = No Reset, 1 = Reset WDT upon KBD Intr. * Gameport I/O
// Bit 2 Mouse enable: 0* = No Reset, 1 = Reset WDT upon Mouse Intr. * Bit 1 Keyboard enable: 0* = No Reset, 1 = Reset WDT upon KBD Intr.
// Bit 3 Reset the timer * Bit 2 Mouse enable: 0* = No Reset, 1 = Reset WDT upon Mouse Intr
// (Wrong in SMsC documentation? Given as: PowerLED Timout Enabled) * Bit 3 Reset the timer
// Bit 4-7 WDT Interrupt Mapping: (0000* = Disabled, * (Wrong in SMsC documentation? Given as: PowerLED Timout
// 0001=IRQ1, 0010=(Invalid), 0011=IRQ3 to 1111=IRQ15) * Enabled)
write_io_cr(0xF3, conf); * Bit 4-7 WDT Interrupt Mapping: (0000* = Disabled,
* 0001=IRQ1, 0010=(Invalid), 0011=IRQ3 to 1111=IRQ15)
*/
write_io_cr(0xF3, conf);
} }
static inline void wdt_timer_ctrl(unsigned char reg) static inline void wdt_timer_ctrl(unsigned char reg)
{ {
// -- Watchdog timer control -- /* -- Watchdog timer control --
// Bit 0 Status Bit: 0 = Timer counting, 1 = Timeout occured * Bit 0 Status Bit: 0 = Timer counting, 1 = Timeout occured
// Bit 1 Power LED Toggle: 0 = Disable Toggle, 1 = Toggle at 1 Hz * Bit 1 Power LED Toggle: 0 = Disable Toggle, 1 = Toggle at 1 Hz
// Bit 2 Force Timeout: 1 = Forces WD timeout event (self-cleaning) * Bit 2 Force Timeout: 1 = Forces WD timeout event (self-cleaning)
// Bit 3 P20 Force Timeout enabled: * Bit 3 P20 Force Timeout enabled:
// 0 = P20 activity does not generate the WD timeout event * 0 = P20 activity does not generate the WD timeout event
// 1 = P20 Allows rising edge of P20, from the keyboard * 1 = P20 Allows rising edge of P20, from the keyboard
// controller, to force the WD timeout event. * controller, to force the WD timeout event.
// Bit 4 (Reserved) * Bit 4 (Reserved)
// -- Soft power management -- * -- Soft power management --
// Bit 5 Stop Counter: 1 = Stop software power down counter * Bit 5 Stop Counter: 1 = Stop software power down counter
// set via register 0xB8, (self-cleaning) * set via register 0xB8, (self-cleaning)
// (Upon read: 0 = Counter running, 1 = Counter stopped) * (Upon read: 0 = Counter running, 1 = Counter stopped)
// Bit 6 Restart Counter: 1 = Restart software power down counter * Bit 6 Restart Counter: 1 = Restart software power down counter
// set via register 0xB8, (self-cleaning) * set via register 0xB8, (self-cleaning)
// Bit 7 SPOFF: 1 = Force software power down (self-cleaning) * Bit 7 SPOFF: 1 = Force software power down (self-cleaning)
*/
write_io_cr(0xF4, reg); write_io_cr(0xF4, reg);
} }
/* -- Higher level functions ------------------------------------*/ /* -- Higher level functions ------------------------------------*/
...@@ -209,33 +216,34 @@ static inline void wdt_timer_ctrl(unsigned char reg) ...@@ -209,33 +216,34 @@ static inline void wdt_timer_ctrl(unsigned char reg)
static void wb_smsc_wdt_initialize(void) static void wb_smsc_wdt_initialize(void)
{ {
unsigned char old; unsigned char old;
spin_lock(&io_lock); spin_lock(&io_lock);
open_io_config(); open_io_config();
select_io_device(IODEV_NO); select_io_device(IODEV_NO);
// enable the watchdog /* enable the watchdog */
gpio_bit13(0x08); // Select pin 80 = LED not GPIO gpio_bit13(0x08); /* Select pin 80 = LED not GPIO */
gpio_bit12(0x0A); // Set pin 79 = WDT not GPIO/Output/Polarity=Invert gpio_bit12(0x0A); /* Set pin 79 = WDT not
GPIO/Output/Polarity=Invert */
/* disable the timeout */
wdt_timeout_value(0);
// disable the timeout /* reset control register */
wdt_timeout_value(0); wdt_timer_ctrl(0x00);
// reset control register /* reset configuration register */
wdt_timer_ctrl(0x00);
// reset configuration register
wdt_timer_conf(0x00); wdt_timer_conf(0x00);
// read old (timer units) register /* read old (timer units) register */
old = read_io_cr(0xF1) & 0x7F; old = read_io_cr(0xF1) & 0x7F;
if (unit == UNIT_SECOND) old |= 0x80; // set to seconds if (unit == UNIT_SECOND)
old |= 0x80; /* set to seconds */
// set the watchdog timer units /* set the watchdog timer units */
wdt_timer_units(old); wdt_timer_units(old);
close_io_config(); close_io_config();
spin_unlock(&io_lock); spin_unlock(&io_lock);
} }
...@@ -244,23 +252,23 @@ static void wb_smsc_wdt_initialize(void) ...@@ -244,23 +252,23 @@ static void wb_smsc_wdt_initialize(void)
static void wb_smsc_wdt_shutdown(void) static void wb_smsc_wdt_shutdown(void)
{ {
spin_lock(&io_lock); spin_lock(&io_lock);
open_io_config(); open_io_config();
select_io_device(IODEV_NO); select_io_device(IODEV_NO);
// disable the watchdog /* disable the watchdog */
gpio_bit13(0x09); gpio_bit13(0x09);
gpio_bit12(0x09); gpio_bit12(0x09);
// reset watchdog config register /* reset watchdog config register */
wdt_timer_conf(0x00); wdt_timer_conf(0x00);
// reset watchdog control register /* reset watchdog control register */
wdt_timer_ctrl(0x00); wdt_timer_ctrl(0x00);
// disable timeout /* disable timeout */
wdt_timeout_value(0x00); wdt_timeout_value(0x00);
close_io_config(); close_io_config();
spin_unlock(&io_lock); spin_unlock(&io_lock);
} }
...@@ -269,16 +277,16 @@ static void wb_smsc_wdt_shutdown(void) ...@@ -269,16 +277,16 @@ static void wb_smsc_wdt_shutdown(void)
static void wb_smsc_wdt_set_timeout(unsigned char new_timeout) static void wb_smsc_wdt_set_timeout(unsigned char new_timeout)
{ {
spin_lock(&io_lock); spin_lock(&io_lock);
open_io_config(); open_io_config();
select_io_device(IODEV_NO); select_io_device(IODEV_NO);
// set Power LED to blink, if we enable the timeout /* set Power LED to blink, if we enable the timeout */
wdt_timer_ctrl((new_timeout == 0) ? 0x00 : 0x02); wdt_timer_ctrl((new_timeout == 0) ? 0x00 : 0x02);
// set timeout value /* set timeout value */
wdt_timeout_value(new_timeout); wdt_timeout_value(new_timeout);
close_io_config(); close_io_config();
spin_unlock(&io_lock); spin_unlock(&io_lock);
} }
...@@ -286,32 +294,32 @@ static void wb_smsc_wdt_set_timeout(unsigned char new_timeout) ...@@ -286,32 +294,32 @@ static void wb_smsc_wdt_set_timeout(unsigned char new_timeout)
static unsigned char wb_smsc_wdt_get_timeout(void) static unsigned char wb_smsc_wdt_get_timeout(void)
{ {
unsigned char set_timeout; unsigned char set_timeout;
spin_lock(&io_lock); spin_lock(&io_lock);
open_io_config(); open_io_config();
select_io_device(IODEV_NO); select_io_device(IODEV_NO);
set_timeout = read_io_cr(0xF2); set_timeout = read_io_cr(0xF2);
close_io_config(); close_io_config();
spin_unlock(&io_lock); spin_unlock(&io_lock);
return set_timeout; return set_timeout;
} }
/* disable watchdog */ /* disable watchdog */
static void wb_smsc_wdt_disable(void) static void wb_smsc_wdt_disable(void)
{ {
// set the timeout to 0 to disable the watchdog /* set the timeout to 0 to disable the watchdog */
wb_smsc_wdt_set_timeout(0); wb_smsc_wdt_set_timeout(0);
} }
/* enable watchdog by setting the current timeout */ /* enable watchdog by setting the current timeout */
static void wb_smsc_wdt_enable(void) static void wb_smsc_wdt_enable(void)
{ {
// set the current timeout... /* set the current timeout... */
wb_smsc_wdt_set_timeout(timeout); wb_smsc_wdt_set_timeout(timeout);
} }
/* reset the timer */ /* reset the timer */
...@@ -319,14 +327,14 @@ static void wb_smsc_wdt_enable(void) ...@@ -319,14 +327,14 @@ static void wb_smsc_wdt_enable(void)
static void wb_smsc_wdt_reset_timer(void) static void wb_smsc_wdt_reset_timer(void)
{ {
spin_lock(&io_lock); spin_lock(&io_lock);
open_io_config(); open_io_config();
select_io_device(IODEV_NO); select_io_device(IODEV_NO);
// reset the timer /* reset the timer */
wdt_timeout_value(timeout); wdt_timeout_value(timeout);
wdt_timer_conf(0x08); wdt_timer_conf(0x08);
close_io_config(); close_io_config();
spin_unlock(&io_lock); spin_unlock(&io_lock);
} }
...@@ -355,7 +363,9 @@ static int wb_smsc_wdt_open(struct inode *inode, struct file *file) ...@@ -355,7 +363,9 @@ static int wb_smsc_wdt_open(struct inode *inode, struct file *file)
/* Reload and activate timer */ /* Reload and activate timer */
wb_smsc_wdt_enable(); wb_smsc_wdt_enable();
printk(KERN_INFO MODNAME "Watchdog enabled. Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); printk(KERN_INFO MODNAME
"Watchdog enabled. Timeout set to %d %s.\n",
timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)");
return nonseekable_open(inode, file); return nonseekable_open(inode, file);
} }
...@@ -367,10 +377,12 @@ static int wb_smsc_wdt_release(struct inode *inode, struct file *file) ...@@ -367,10 +377,12 @@ static int wb_smsc_wdt_release(struct inode *inode, struct file *file)
/* Shut off the timer. */ /* Shut off the timer. */
if (expect_close == 42) { if (expect_close == 42) {
wb_smsc_wdt_disable(); wb_smsc_wdt_disable();
printk(KERN_INFO MODNAME "Watchdog disabled, sleeping again...\n"); printk(KERN_INFO MODNAME
"Watchdog disabled, sleeping again...\n");
} else { } else {
printk(KERN_CRIT MODNAME "Unexpected close, not stopping watchdog!\n"); printk(KERN_CRIT MODNAME
"Unexpected close, not stopping watchdog!\n");
wb_smsc_wdt_reset_timer(); wb_smsc_wdt_reset_timer();
} }
...@@ -392,7 +404,8 @@ static ssize_t wb_smsc_wdt_write(struct file *file, const char __user *data, ...@@ -392,7 +404,8 @@ static ssize_t wb_smsc_wdt_write(struct file *file, const char __user *data,
/* reset expect flag */ /* reset expect flag */
expect_close = 0; expect_close = 0;
/* scan to see whether or not we got the magic character */ /* scan to see whether or not we got the
magic character */
for (i = 0; i != len; i++) { for (i = 0; i != len; i++) {
char c; char c;
if (get_user(c, data+i)) if (get_user(c, data+i))
...@@ -410,8 +423,8 @@ static ssize_t wb_smsc_wdt_write(struct file *file, const char __user *data, ...@@ -410,8 +423,8 @@ static ssize_t wb_smsc_wdt_write(struct file *file, const char __user *data,
/* ioctl => control interface */ /* ioctl => control interface */
static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file, static long wb_smsc_wdt_ioctl(struct file *file,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
int new_timeout; int new_timeout;
...@@ -420,9 +433,9 @@ static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file, ...@@ -420,9 +433,9 @@ static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file,
int __user *i; int __user *i;
} uarg; } uarg;
static struct watchdog_info ident = { static const struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING | .options = WDIOF_KEEPALIVEPING |
WDIOF_SETTIMEOUT | WDIOF_SETTIMEOUT |
WDIOF_MAGICCLOSE, WDIOF_MAGICCLOSE,
.firmware_version = 0, .firmware_version = 0,
.identity = "SMsC 37B787 Watchdog" .identity = "SMsC 37B787 Watchdog"
...@@ -431,78 +444,62 @@ static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file, ...@@ -431,78 +444,62 @@ static int wb_smsc_wdt_ioctl(struct inode *inode, struct file *file,
uarg.i = (int __user *)arg; uarg.i = (int __user *)arg;
switch (cmd) { switch (cmd) {
default: case WDIOC_GETSUPPORT:
return -ENOTTY; return copy_to_user(uarg.ident, &ident, sizeof(ident))
? -EFAULT : 0;
case WDIOC_GETSUPPORT: case WDIOC_GETSTATUS:
return copy_to_user(uarg.ident, &ident, return put_user(wb_smsc_wdt_status(), uarg.i);
sizeof(ident)) ? -EFAULT : 0; case WDIOC_GETBOOTSTATUS:
return put_user(0, uarg.i);
case WDIOC_GETSTATUS: case WDIOC_KEEPALIVE:
return put_user(wb_smsc_wdt_status(), uarg.i); wb_smsc_wdt_reset_timer();
return 0;
case WDIOC_GETBOOTSTATUS: case WDIOC_SETTIMEOUT:
return put_user(0, uarg.i); if (get_user(new_timeout, uarg.i))
return -EFAULT;
case WDIOC_KEEPALIVE: /* the API states this is given in secs */
wb_smsc_wdt_reset_timer(); if (unit == UNIT_MINUTE)
return 0; new_timeout /= 60;
if (new_timeout < 0 || new_timeout > MAX_TIMEOUT)
case WDIOC_SETTIMEOUT: return -EINVAL;
if (get_user(new_timeout, uarg.i)) timeout = new_timeout;
return -EFAULT; wb_smsc_wdt_set_timeout(timeout);
/* fall through and return the new timeout... */
// the API states this is given in secs case WDIOC_GETTIMEOUT:
if (unit == UNIT_MINUTE) new_timeout = timeout;
new_timeout /= 60; if (unit == UNIT_MINUTE)
if (new_timeout < 0 || new_timeout > MAX_TIMEOUT)
return -EINVAL;
timeout = new_timeout;
wb_smsc_wdt_set_timeout(timeout);
// fall through and return the new timeout...
case WDIOC_GETTIMEOUT:
new_timeout = timeout;
if (unit == UNIT_MINUTE)
new_timeout *= 60; new_timeout *= 60;
return put_user(new_timeout, uarg.i);
case WDIOC_SETOPTIONS:
{
int options, retval = -EINVAL;
return put_user(new_timeout, uarg.i); if (get_user(options, uarg.i))
return -EFAULT;
case WDIOC_SETOPTIONS:
{
int options, retval = -EINVAL;
if (get_user(options, uarg.i))
return -EFAULT;
if (options & WDIOS_DISABLECARD) {
wb_smsc_wdt_disable();
retval = 0;
}
if (options & WDIOS_ENABLECARD) {
wb_smsc_wdt_enable();
retval = 0;
}
return retval; if (options & WDIOS_DISABLECARD) {
wb_smsc_wdt_disable();
retval = 0;
} }
if (options & WDIOS_ENABLECARD) {
wb_smsc_wdt_enable();
retval = 0;
}
return retval;
}
default:
return -ENOTTY;
} }
} }
/* -- Notifier funtions -----------------------------------------*/ /* -- Notifier funtions -----------------------------------------*/
static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) static int wb_smsc_wdt_notify_sys(struct notifier_block *this,
unsigned long code, void *unused)
{ {
if (code == SYS_DOWN || code == SYS_HALT) if (code == SYS_DOWN || code == SYS_HALT) {
{ /* set timeout to 0, to avoid possible race-condition */
// set timeout to 0, to avoid possible race-condition timeout = 0;
timeout = 0;
wb_smsc_wdt_disable(); wb_smsc_wdt_disable();
} }
return NOTIFY_DONE; return NOTIFY_DONE;
...@@ -510,23 +507,20 @@ static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long cod ...@@ -510,23 +507,20 @@ static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long cod
/* -- Module's structures ---------------------------------------*/ /* -- Module's structures ---------------------------------------*/
static const struct file_operations wb_smsc_wdt_fops = static const struct file_operations wb_smsc_wdt_fops = {
{ .owner = THIS_MODULE,
.owner = THIS_MODULE,
.llseek = no_llseek, .llseek = no_llseek,
.write = wb_smsc_wdt_write, .write = wb_smsc_wdt_write,
.ioctl = wb_smsc_wdt_ioctl, .unlocked_ioctl = wb_smsc_wdt_ioctl,
.open = wb_smsc_wdt_open, .open = wb_smsc_wdt_open,
.release = wb_smsc_wdt_release, .release = wb_smsc_wdt_release,
}; };
static struct notifier_block wb_smsc_wdt_notifier = static struct notifier_block wb_smsc_wdt_notifier = {
{
.notifier_call = wb_smsc_wdt_notify_sys, .notifier_call = wb_smsc_wdt_notify_sys,
}; };
static struct miscdevice wb_smsc_wdt_miscdev = static struct miscdevice wb_smsc_wdt_miscdev = {
{
.minor = WATCHDOG_MINOR, .minor = WATCHDOG_MINOR,
.name = "watchdog", .name = "watchdog",
.fops = &wb_smsc_wdt_fops, .fops = &wb_smsc_wdt_fops,
...@@ -540,39 +534,44 @@ static int __init wb_smsc_wdt_init(void) ...@@ -540,39 +534,44 @@ static int __init wb_smsc_wdt_init(void)
{ {
int ret; int ret;
printk("SMsC 37B787 watchdog component driver " VERSION " initialising...\n"); printk(KERN_INFO "SMsC 37B787 watchdog component driver "
VERSION " initialising...\n");
if (!request_region(IOPORT, IOPORT_SIZE, "SMsC 37B787 watchdog")) { if (!request_region(IOPORT, IOPORT_SIZE, "SMsC 37B787 watchdog")) {
printk(KERN_ERR MODNAME "Unable to register IO port %#x\n", IOPORT); printk(KERN_ERR MODNAME "Unable to register IO port %#x\n",
IOPORT);
ret = -EBUSY; ret = -EBUSY;
goto out_pnp; goto out_pnp;
} }
// set new maximum, if it's too big /* set new maximum, if it's too big */
if (timeout > MAX_TIMEOUT) if (timeout > MAX_TIMEOUT)
timeout = MAX_TIMEOUT; timeout = MAX_TIMEOUT;
// init the watchdog timer /* init the watchdog timer */
wb_smsc_wdt_initialize(); wb_smsc_wdt_initialize();
ret = register_reboot_notifier(&wb_smsc_wdt_notifier); ret = register_reboot_notifier(&wb_smsc_wdt_notifier);
if (ret) { if (ret) {
printk(KERN_ERR MODNAME "Unable to register reboot notifier err = %d\n", ret); printk(KERN_ERR MODNAME
"Unable to register reboot notifier err = %d\n", ret);
goto out_io; goto out_io;
} }
ret = misc_register(&wb_smsc_wdt_miscdev); ret = misc_register(&wb_smsc_wdt_miscdev);
if (ret) { if (ret) {
printk(KERN_ERR MODNAME "Unable to register miscdev on minor %d\n", WATCHDOG_MINOR); printk(KERN_ERR MODNAME
"Unable to register miscdev on minor %d\n",
WATCHDOG_MINOR);
goto out_rbt; goto out_rbt;
} }
// output info /* output info */
printk(KERN_INFO MODNAME "Timeout set to %d %s.\n", timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)"); printk(KERN_INFO MODNAME "Timeout set to %d %s.\n",
printk(KERN_INFO MODNAME "Watchdog initialized and sleeping (nowayout=%d)...\n", nowayout); timeout, (unit == UNIT_SECOND) ? "second(s)" : "minute(s)");
printk(KERN_INFO MODNAME
// ret = 0 "Watchdog initialized and sleeping (nowayout=%d)...\n",
nowayout);
out_clean: out_clean:
return ret; return ret;
...@@ -591,8 +590,7 @@ static int __init wb_smsc_wdt_init(void) ...@@ -591,8 +590,7 @@ static int __init wb_smsc_wdt_init(void)
static void __exit wb_smsc_wdt_exit(void) static void __exit wb_smsc_wdt_exit(void)
{ {
/* Stop the timer before we leave */ /* Stop the timer before we leave */
if (!nowayout) if (!nowayout) {
{
wb_smsc_wdt_shutdown(); wb_smsc_wdt_shutdown();
printk(KERN_INFO MODNAME "Watchdog disabled.\n"); printk(KERN_INFO MODNAME "Watchdog disabled.\n");
} }
...@@ -601,25 +599,29 @@ static void __exit wb_smsc_wdt_exit(void) ...@@ -601,25 +599,29 @@ static void __exit wb_smsc_wdt_exit(void)
unregister_reboot_notifier(&wb_smsc_wdt_notifier); unregister_reboot_notifier(&wb_smsc_wdt_notifier);
release_region(IOPORT, IOPORT_SIZE); release_region(IOPORT, IOPORT_SIZE);
printk("SMsC 37B787 watchdog component driver removed.\n"); printk(KERN_INFO "SMsC 37B787 watchdog component driver removed.\n");
} }
module_init(wb_smsc_wdt_init); module_init(wb_smsc_wdt_init);
module_exit(wb_smsc_wdt_exit); module_exit(wb_smsc_wdt_exit);
MODULE_AUTHOR("Sven Anders <anders@anduras.de>"); MODULE_AUTHOR("Sven Anders <anders@anduras.de>");
MODULE_DESCRIPTION("Driver for SMsC 37B787 watchdog component (Version " VERSION ")"); MODULE_DESCRIPTION("Driver for SMsC 37B787 watchdog component (Version "
VERSION ")");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
#ifdef SMSC_SUPPORT_MINUTES #ifdef SMSC_SUPPORT_MINUTES
module_param(unit, int, 0); module_param(unit, int, 0);
MODULE_PARM_DESC(unit, "set unit to use, 0=seconds or 1=minutes, default is 0"); MODULE_PARM_DESC(unit,
"set unit to use, 0=seconds or 1=minutes, default is 0");
#endif #endif
module_param(timeout, int, 0); module_param(timeout, int, 0);
MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60"); MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60");
module_param(nowayout, int, 0); module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); MODULE_PARM_DESC(nowayout,
"Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
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