#include <linux/watchdog.h>
#include <linux/init.h>
#include <linux/io.h>
-#include <linux/spinlock.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/of.h>
static struct clk *clk;
static unsigned int wdt_tclk;
static void __iomem *wdt_reg;
-static DEFINE_SPINLOCK(wdt_lock);
static int orion_wdt_ping(struct watchdog_device *wdt_dev)
{
- spin_lock(&wdt_lock);
-
/* Reload watchdog duration */
writel(wdt_tclk * wdt_dev->timeout, wdt_reg + WDT_VAL);
-
- spin_unlock(&wdt_lock);
return 0;
}
static int orion_wdt_start(struct watchdog_device *wdt_dev)
{
- u32 reg;
-
- spin_lock(&wdt_lock);
-
/* Set watchdog duration */
writel(wdt_tclk * wdt_dev->timeout, wdt_reg + WDT_VAL);
writel(~WDT_INT_REQ, BRIDGE_CAUSE);
/* Enable watchdog timer */
- reg = readl(wdt_reg + TIMER_CTRL);
- reg |= WDT_EN;
- writel(reg, wdt_reg + TIMER_CTRL);
+ atomic_io_modify(wdt_reg + TIMER_CTRL, WDT_EN, WDT_EN);
/* Enable reset on watchdog */
- reg = readl(RSTOUTn_MASK);
- reg |= WDT_RESET_OUT_EN;
- writel(reg, RSTOUTn_MASK);
-
- spin_unlock(&wdt_lock);
+ atomic_io_modify(RSTOUTn_MASK, WDT_RESET_OUT_EN, WDT_RESET_OUT_EN);
return 0;
}
static int orion_wdt_stop(struct watchdog_device *wdt_dev)
{
- u32 reg;
-
- spin_lock(&wdt_lock);
-
/* Disable reset on watchdog */
- reg = readl(RSTOUTn_MASK);
- reg &= ~WDT_RESET_OUT_EN;
- writel(reg, RSTOUTn_MASK);
+ atomic_io_modify(RSTOUTn_MASK, WDT_RESET_OUT_EN, 0);
/* Disable watchdog timer */
- reg = readl(wdt_reg + TIMER_CTRL);
- reg &= ~WDT_EN;
- writel(reg, wdt_reg + TIMER_CTRL);
-
- spin_unlock(&wdt_lock);
+ atomic_io_modify(wdt_reg + TIMER_CTRL, WDT_EN, 0);
return 0;
}
static unsigned int orion_wdt_get_timeleft(struct watchdog_device *wdt_dev)
{
- unsigned int time_left;
-
- spin_lock(&wdt_lock);
- time_left = readl(wdt_reg + WDT_VAL) / wdt_tclk;
- spin_unlock(&wdt_lock);
-
- return time_left;
+ return readl(wdt_reg + WDT_VAL) / wdt_tclk;
}
static int orion_wdt_set_timeout(struct watchdog_device *wdt_dev,