diff options
Diffstat (limited to 'drivers/watchdog/i6300esb.c')
| -rw-r--r-- | drivers/watchdog/i6300esb.c | 152 |
1 files changed, 54 insertions, 98 deletions
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c index 7ba0b11ec52..d7befd58b39 100644 --- a/drivers/watchdog/i6300esb.c +++ b/drivers/watchdog/i6300esb.c @@ -27,6 +27,8 @@ * Includes, defines, variables, module parameters, ... */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/module.h> #include <linux/types.h> #include <linux/kernel.h> @@ -34,18 +36,15 @@ #include <linux/mm.h> #include <linux/miscdevice.h> #include <linux/watchdog.h> -#include <linux/platform_device.h> -#include <linux/init.h> #include <linux/pci.h> #include <linux/ioport.h> #include <linux/uaccess.h> #include <linux/io.h> /* Module and version information */ -#define ESB_VERSION "0.04" +#define ESB_VERSION "0.05" #define ESB_MODULE_NAME "i6300ESB timer" #define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION -#define PFX ESB_MODULE_NAME ": " /* PCI configuration registers */ #define ESB_CONFIG_REG 0x60 /* Config register */ @@ -65,7 +64,7 @@ /* Config register bits */ #define ESB_WDT_REBOOT (0x01 << 5) /* Enable reboot on timeout */ #define ESB_WDT_FREQ (0x01 << 2) /* Decrement frequency */ -#define ESB_WDT_INTTYPE (0x11 << 0) /* Interrupt type on timer1 timeout */ +#define ESB_WDT_INTTYPE (0x03 << 0) /* Interrupt type on timer1 timeout */ /* Reload register bits */ #define ESB_WDT_TIMEOUT (0x01 << 9) /* Watchdog timed out */ @@ -82,7 +81,9 @@ static unsigned long timer_alive; static struct pci_dev *esb_pci; static unsigned short triggered; /* The status of the watchdog upon boot */ static char esb_expect_close; -static struct platform_device *esb_platform_device; + +/* We can only use 1 card due to the /dev/watchdog restriction */ +static int cards_found; /* module parameters */ /* 30 sec default heartbeat (1 < heartbeat < 2*1023) */ @@ -93,8 +94,8 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (1<heartbeat<2046, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); -static int nowayout = WATCHDOG_NOWAYOUT; -module_param(nowayout, int, 0); +static bool nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); @@ -111,8 +112,8 @@ MODULE_PARM_DESC(nowayout, */ static inline void esb_unlock_registers(void) { - writeb(ESB_UNLOCK1, ESB_RELOAD_REG); - writeb(ESB_UNLOCK2, ESB_RELOAD_REG); + writew(ESB_UNLOCK1, ESB_RELOAD_REG); + writew(ESB_UNLOCK2, ESB_RELOAD_REG); } static int esb_timer_start(void) @@ -212,8 +213,7 @@ static int esb_release(struct inode *inode, struct file *file) if (esb_expect_close == 42) esb_timer_stop(); else { - printk(KERN_CRIT PFX - "Unexpected close, not stopping watchdog!\n"); + pr_crit("Unexpected close, not stopping watchdog!\n"); esb_timer_keepalive(); } clear_bit(0, &timer_alive); @@ -256,7 +256,7 @@ static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) int new_heartbeat; void __user *argp = (void __user *)arg; int __user *p = argp; - static struct watchdog_info ident = { + static const struct watchdog_info ident = { .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, @@ -332,13 +332,8 @@ static struct miscdevice esb_miscdev = { /* * Data for PCI driver interface - * - * This data only exists for exporting the supported - * PCI ids via MODULE_DEVICE_TABLE. We do not actually - * register a pci_driver, because someone else might one day - * want to register another driver on the same PCI id. */ -static struct pci_device_id esb_pci_tbl[] = { +static const struct pci_device_id esb_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), }, { 0, }, /* End of list */ }; @@ -348,48 +343,38 @@ MODULE_DEVICE_TABLE(pci, esb_pci_tbl); * Init & exit routines */ -static unsigned char __devinit esb_getdevice(void) +static unsigned char esb_getdevice(struct pci_dev *pdev) { - /* - * Find the PCI device - */ - - esb_pci = pci_get_device(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_ESB_9, NULL); - - if (!esb_pci) - return 0; - - if (pci_enable_device(esb_pci)) { - printk(KERN_ERR PFX "failed to enable device\n"); + if (pci_enable_device(pdev)) { + pr_err("failed to enable device\n"); goto err_devput; } - if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) { - printk(KERN_ERR PFX "failed to request region\n"); + if (pci_request_region(pdev, 0, ESB_MODULE_NAME)) { + pr_err("failed to request region\n"); goto err_disable; } - BASEADDR = pci_ioremap_bar(esb_pci, 0); + BASEADDR = pci_ioremap_bar(pdev, 0); if (BASEADDR == NULL) { /* Something's wrong here, BASEADDR has to be set */ - printk(KERN_ERR PFX "failed to get BASEADDR\n"); + pr_err("failed to get BASEADDR\n"); goto err_release; } /* Done */ + esb_pci = pdev; return 1; err_release: - pci_release_region(esb_pci, 0); + pci_release_region(pdev, 0); err_disable: - pci_disable_device(esb_pci); + pci_disable_device(pdev); err_devput: - pci_dev_put(esb_pci); return 0; } -static void __devinit esb_initdevice(void) +static void esb_initdevice(void) { u8 val1; u16 val2; @@ -411,7 +396,7 @@ static void __devinit esb_initdevice(void) /* Check that the WDT isn't already locked */ pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1); if (val1 & ESB_WDT_LOCK) - printk(KERN_WARNING PFX "nowayout already set\n"); + pr_warn("nowayout already set\n"); /* Set the timer to watchdog mode and disable it for now */ pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00); @@ -430,21 +415,31 @@ static void __devinit esb_initdevice(void) esb_timer_set_heartbeat(heartbeat); } -static int __devinit esb_probe(struct platform_device *dev) +static int esb_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) { int ret; + cards_found++; + if (cards_found == 1) + pr_info("Intel 6300ESB WatchDog Timer Driver v%s\n", + ESB_VERSION); + + if (cards_found > 1) { + pr_err("This driver only supports 1 device\n"); + return -ENODEV; + } + /* Check whether or not the hardware watchdog is there */ - if (!esb_getdevice() || esb_pci == NULL) + if (!esb_getdevice(pdev) || esb_pci == NULL) return -ENODEV; /* Check that the heartbeat value is within it's range; if not reset to the default */ if (heartbeat < 0x1 || heartbeat > 2 * 0x03ff) { heartbeat = WATCHDOG_HEARTBEAT; - printk(KERN_INFO PFX - "heartbeat value must be 1<heartbeat<2046, using %d\n", - heartbeat); + pr_info("heartbeat value must be 1<heartbeat<2046, using %d\n", + heartbeat); } /* Initialize the watchdog and make sure it does not run */ @@ -453,25 +448,23 @@ static int __devinit esb_probe(struct platform_device *dev) /* Register the watchdog so that userspace has access to it */ ret = misc_register(&esb_miscdev); if (ret != 0) { - printk(KERN_ERR PFX - "cannot register miscdev on minor=%d (err=%d)\n", - WATCHDOG_MINOR, ret); + pr_err("cannot register miscdev on minor=%d (err=%d)\n", + WATCHDOG_MINOR, ret); goto err_unmap; } - printk(KERN_INFO PFX - "initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n", - BASEADDR, heartbeat, nowayout); + pr_info("initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n", + BASEADDR, heartbeat, nowayout); return 0; err_unmap: iounmap(BASEADDR); pci_release_region(esb_pci, 0); pci_disable_device(esb_pci); - pci_dev_put(esb_pci); + esb_pci = NULL; return ret; } -static int __devexit esb_remove(struct platform_device *dev) +static void esb_remove(struct pci_dev *pdev) { /* Stop the timer before we leave */ if (!nowayout) @@ -482,61 +475,24 @@ static int __devexit esb_remove(struct platform_device *dev) iounmap(BASEADDR); pci_release_region(esb_pci, 0); pci_disable_device(esb_pci); - pci_dev_put(esb_pci); - return 0; + esb_pci = NULL; } -static void esb_shutdown(struct platform_device *dev) +static void esb_shutdown(struct pci_dev *pdev) { esb_timer_stop(); } -static struct platform_driver esb_platform_driver = { +static struct pci_driver esb_driver = { + .name = ESB_MODULE_NAME, + .id_table = esb_pci_tbl, .probe = esb_probe, - .remove = __devexit_p(esb_remove), + .remove = esb_remove, .shutdown = esb_shutdown, - .driver = { - .owner = THIS_MODULE, - .name = ESB_MODULE_NAME, - }, }; -static int __init watchdog_init(void) -{ - int err; - - printk(KERN_INFO PFX "Intel 6300ESB WatchDog Timer Driver v%s\n", - ESB_VERSION); - - err = platform_driver_register(&esb_platform_driver); - if (err) - return err; - - esb_platform_device = platform_device_register_simple(ESB_MODULE_NAME, - -1, NULL, 0); - if (IS_ERR(esb_platform_device)) { - err = PTR_ERR(esb_platform_device); - goto unreg_platform_driver; - } - - return 0; - -unreg_platform_driver: - platform_driver_unregister(&esb_platform_driver); - return err; -} - -static void __exit watchdog_cleanup(void) -{ - platform_device_unregister(esb_platform_device); - platform_driver_unregister(&esb_platform_driver); - printk(KERN_INFO PFX "Watchdog Module Unloaded.\n"); -} - -module_init(watchdog_init); -module_exit(watchdog_cleanup); +module_pci_driver(esb_driver); MODULE_AUTHOR("Ross Biro and David Härdeman"); MODULE_DESCRIPTION("Watchdog driver for Intel 6300ESB chipsets"); MODULE_LICENSE("GPL"); -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); |
