* or implied.
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
+#include <linux/spinlock.h>
#include <asm/hardware.h>
#include <asm/uaccess.h>
#define WDOG_COUNTER_RATE 13000000 /*the counter clock is 13 MHz fixed */
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
+static int nowayout = WATCHDOG_NOWAYOUT;
static int heartbeat = DEFAULT_HEARTBEAT;
+static spinlock_t io_lock;
static unsigned long wdt_status;
#define WDT_IN_USE 0
#define WDT_OK_TO_CLOSE 1
static void wdt_enable(void)
{
+ spin_lock(&io_lock);
+
if (wdt_clk)
clk_set_rate(wdt_clk, 1);
/* stop counter, initiate counter reset */
__raw_writel(RESET_COUNT, WDTIM_CTRL(wdt_base));
/*wait for reset to complete. 100% guarantee event */
- while (__raw_readl(WDTIM_COUNTER(wdt_base)));
+ while (__raw_readl(WDTIM_COUNTER(wdt_base)))
+ cpu_relax();
/* internal and external reset, stop after that */
__raw_writel(M_RES2 | STOP_COUNT0 | RESET_COUNT0,
WDTIM_MCTRL(wdt_base));
__raw_writel(heartbeat * WDOG_COUNTER_RATE, WDTIM_MATCH0(wdt_base));
/*enable counter, stop when debugger active */
__raw_writel(COUNT_ENAB | DEBUG_EN, WDTIM_CTRL(wdt_base));
+
+ spin_unlock(&io_lock);
}
static void wdt_disable(void)
{
+ spin_lock(&io_lock);
+
__raw_writel(0, WDTIM_CTRL(wdt_base)); /*stop counter */
if (wdt_clk)
clk_set_rate(wdt_clk, 0);
+
+ spin_unlock(&io_lock);
}
static int pnx4008_wdt_open(struct inode *inode, struct file *file)
pnx4008_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
- int ret = -ENOIOCTLCMD;
+ int ret = -ENOTTY;
int time;
switch (cmd) {
return 0;
}
-static struct file_operations pnx4008_wdt_fops = {
+static const struct file_operations pnx4008_wdt_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.write = pnx4008_wdt_write,
int ret = 0, size;
struct resource *res;
+ spin_lock_init(&io_lock);
+
if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT)
heartbeat = DEFAULT_HEARTBEAT;
static int pnx4008_wdt_remove(struct platform_device *pdev)
{
- if (wdt_mem) {
- release_resource(wdt_mem);
- kfree(wdt_mem);
- wdt_mem = NULL;
- }
+ misc_deregister(&pnx4008_wdt_miscdev);
if (wdt_clk) {
clk_set_rate(wdt_clk, 0);
clk_put(wdt_clk);
wdt_clk = NULL;
}
- misc_deregister(&pnx4008_wdt_miscdev);
+ if (wdt_mem) {
+ release_resource(wdt_mem);
+ kfree(wdt_mem);
+ wdt_mem = NULL;
+ }
return 0;
}