* interface and Solaris-compatible ioctls as best it is
* able.
*
- * NOTE: CP1400 systems appear to have a defective intr_mask
- * register on the PLD, preventing the disabling of
- * timer interrupts. We use a timer to periodically
- * reset 'stopped' watchdogs on affected platforms.
+ * NOTE: CP1400 systems appear to have a defective intr_mask
+ * register on the PLD, preventing the disabling of
+ * timer interrupts. We use a timer to periodically
+ * reset 'stopped' watchdogs on affected platforms.
*
* Copyright (c) 2000 Eric Brower (ebrower@usa.net)
* Copyright (C) 2008 David S. Miller <davem@davemloft.net>
#include <linux/ioport.h>
#include <linux/timer.h>
#include <linux/slab.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
} devs[WD_NUMDEVS];
};
+static DEFINE_MUTEX(cpwd_mutex);
static struct cpwd *cpwd_device;
/* Sun uses Altera PLD EPF8820ATC144-4
* -------------------
* |- counter val -|
* -------------------
- * dcntr - Current 16-bit downcounter value.
- * When downcounter reaches '0' watchdog expires.
- * Reading this register resets downcounter with
- * 'limit' value.
- * limit - 16-bit countdown value in 1/10th second increments.
- * Writing this register begins countdown with input value.
- * Reading from this register does not affect counter.
+ * dcntr - Current 16-bit downcounter value.
+ * When downcounter reaches '0' watchdog expires.
+ * Reading this register resets downcounter with
+ * 'limit' value.
+ * limit - 16-bit countdown value in 1/10th second increments.
+ * Writing this register begins countdown with input value.
+ * Reading from this register does not affect counter.
* NOTES: After watchdog reset, dcntr and limit contain '1'
*
* status register (byte access):
* |- UNUSED -| EXP | RUN |
* ---------------------------
* status- Bit 0 - Watchdog is running
- * Bit 1 - Watchdog has expired
+ * Bit 1 - Watchdog has expired
*
*** PLD register block definition (struct wd_pld_regblk)
*
* Because of the CP1400 defect this should only be
* called during initialzation or by wd_[start|stop]timer()
*
- * index - sub-device index, or -1 for 'all'
+ * index - sub-device index, or -1 for 'all'
* enable - non-zero to enable interrupts, zero to disable
*/
static void cpwd_toggleintr(struct cpwd *p, int index, int enable)
} else {
/* Fudge WD_EXPIRED status for defective CP1400--
* IF timer is running
- * AND brokenstop is set
- * AND an interrupt has been serviced
+ * AND brokenstop is set
+ * AND an interrupt has been serviced
* we are WD_EXPIRED.
*
* IF timer is running
- * AND brokenstop is set
- * AND no interrupt has been serviced
+ * AND brokenstop is set
+ * AND no interrupt has been serviced
* we are WD_FREERUN.
*/
if (p->broken &&
{
struct cpwd *p = cpwd_device;
- lock_kernel();
+ mutex_lock(&cpwd_mutex);
switch (iminor(inode)) {
case WD0_MINOR:
case WD1_MINOR:
break;
default:
- unlock_kernel();
+ mutex_unlock(&cpwd_mutex);
return -ENODEV;
}
IRQF_SHARED, DRIVER_NAME, p)) {
printk(KERN_ERR PFX "Cannot register IRQ %d\n",
p->irq);
- unlock_kernel();
+ mutex_unlock(&cpwd_mutex);
return -EBUSY;
}
p->initialized = true;
}
- unlock_kernel();
+ mutex_unlock(&cpwd_mutex);
return nonseekable_open(inode, f);
}
case WIOCSTART:
case WIOCSTOP:
case WIOCGSTAT:
- lock_kernel();
+ mutex_lock(&cpwd_mutex);
rval = cpwd_ioctl(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&cpwd_mutex);
break;
/* everything else is handled by the generic compat layer */
.write = cpwd_write,
.read = cpwd_read,
.release = cpwd_release,
+ .llseek = no_llseek,
};
-static int __devinit cpwd_probe(struct of_device *op,
- const struct of_device_id *match)
+static int __devinit cpwd_probe(struct platform_device *op)
{
struct device_node *options;
const char *str_prop;
if (p->broken) {
init_timer(&cpwd_timer);
- cpwd_timer.function = cpwd_brokentimer;
+ cpwd_timer.function = cpwd_brokentimer;
cpwd_timer.data = (unsigned long) p;
cpwd_timer.expires = WD_BTIMEOUT;
goto out;
}
-static int __devexit cpwd_remove(struct of_device *op)
+static int __devexit cpwd_remove(struct platform_device *op)
{
struct cpwd *p = dev_get_drvdata(&op->dev);
int i;
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < WD_NUMDEVS; i++) {
misc_deregister(&p->devs[i].misc);
if (!p->enabled) {
};
MODULE_DEVICE_TABLE(of, cpwd_match);
-static struct of_platform_driver cpwd_driver = {
+static struct platform_driver cpwd_driver = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
.remove = __devexit_p(cpwd_remove),
};
-static int __init cpwd_init(void)
-{
- return of_register_platform_driver(&cpwd_driver);
-}
-
-static void __exit cpwd_exit(void)
-{
- of_unregister_platform_driver(&cpwd_driver);
-}
-
-module_init(cpwd_init);
-module_exit(cpwd_exit);
+module_platform_driver(cpwd_driver);