Remove the global variable at91wdt_private, add the struct at91wdt_drvdata
as a substitute, and set it as the driver data of the at91wdt_wdd.

Signed-off-by: Wenyou Yang <wenyou.y...@atmel.com>
Cc: w...@iguana.be
Cc: linux-watch...@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/watchdog/at91sam9_wdt.c |   88 +++++++++++++++++++++------------------
 1 file changed, 47 insertions(+), 41 deletions(-)

diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index d864dc4..f10a897 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -38,11 +38,6 @@
 
 #define DRV_NAME "AT91SAM9 Watchdog"
 
-#define wdt_read(field) \
-       __raw_readl(at91wdt_private.base + field)
-#define wdt_write(field, val) \
-       __raw_writel((val), at91wdt_private.base + field)
-
 /* AT91SAM9 watchdog runs a 12bit counter @ 256Hz,
  * use this to convert a watchdog
  * value from/to milliseconds.
@@ -72,23 +67,33 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once 
started "
 
 static void at91_ping(unsigned long data);
 
-static struct {
-       void __iomem *base;
-       unsigned long next_heartbeat;   /* the next_heartbeat for the timer */
-       unsigned long open;
-       char expect_close;
-       struct timer_list timer;        /* The timer that pings the watchdog */
-} at91wdt_private;
+struct at91wdt_drvdata {
+       void __iomem    *phybase;
+       bool            is_enable;      /* indicate if the watchdog is eabled */
+       unsigned long   next_heartbeat; /* the next_heartbeat for the timer */
+       struct timer_list       timer;  /* The timer that pings the watchdog */
+};
 
 /* ......................................................................... */
 
+static inline unsigned int wdt_read(struct at91wdt_drvdata *driver_data,
+                                       unsigned int field)
+{
+       return readl_relaxed(driver_data->phybase + field);
+}
+
+static inline void wdt_write(struct at91wdt_drvdata *driver_data,
+                               unsigned int field, unsigned int val)
+{
+       writel_relaxed((val), driver_data->phybase + field);
+}
 
 /*
  * Reload the watchdog timer.  (ie, pat the watchdog)
  */
-static inline void at91_wdt_reset(void)
+static inline void at91_wdt_reset(struct at91wdt_drvdata *driver_data)
 {
-       wdt_write(AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT);
+       wdt_write(driver_data, AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT);
 }
 
 /*
@@ -96,10 +101,12 @@ static inline void at91_wdt_reset(void)
  */
 static void at91_ping(unsigned long data)
 {
-       if (time_before(jiffies, at91wdt_private.next_heartbeat) ||
-                       (!nowayout && !at91wdt_private.open)) {
-               at91_wdt_reset();
-               mod_timer(&at91wdt_private.timer, jiffies + WDT_TIMEOUT);
+       struct watchdog_device *wddev = (struct watchdog_device *)data;
+       struct at91wdt_drvdata *driver_data = watchdog_get_drvdata(wddev);
+
+       if (time_before(jiffies, driver_data->next_heartbeat)) {
+               at91_wdt_reset(driver_data);
+               mod_timer(&driver_data->timer, jiffies + WDT_TIMEOUT);
        } else
                pr_crit("I will reset your machine !\n");
 }
@@ -109,11 +116,8 @@ static void at91_ping(unsigned long data)
  */
 static int at91_wdt_open(struct inode *inode, struct file *file)
 {
-       if (test_and_set_bit(0, &at91wdt_private.open))
-               return -EBUSY;
-
-       at91wdt_private.next_heartbeat = jiffies + heartbeat * HZ;
-       mod_timer(&at91wdt_private.timer, jiffies + WDT_TIMEOUT);
+       driver_data->next_heartbeat = jiffies + heartbeat * HZ;
+       mod_timer(&driver_data->timer, jiffies + WDT_TIMEOUT);
 
        return nonseekable_open(inode, file);
 }
@@ -123,13 +127,8 @@ static int at91_wdt_open(struct inode *inode, struct file 
*file)
  */
 static int at91_wdt_close(struct inode *inode, struct file *file)
 {
-       clear_bit(0, &at91wdt_private.open);
+       del_timer(&driver_data->timer);
 
-       /* stop internal ping */
-       if (!at91wdt_private.expect_close)
-               del_timer(&at91wdt_private.timer);
-
-       at91wdt_private.expect_close = 0;
        return 0;
 }
 
@@ -191,7 +190,7 @@ static long at91_wdt_ioctl(struct file *file,
                return put_user(0, p);
 
        case WDIOC_KEEPALIVE:
-               at91wdt_private.next_heartbeat = jiffies + heartbeat * HZ;
+               driver_data->next_heartbeat = jiffies + heartbeat * HZ;
                return 0;
 
        case WDIOC_SETTIMEOUT:
@@ -199,7 +198,7 @@ static long at91_wdt_ioctl(struct file *file,
                        return -EFAULT;
 
                heartbeat = new_value;
-               at91wdt_private.next_heartbeat = jiffies + heartbeat * HZ;
+               driver_data->next_heartbeat = jiffies + heartbeat * HZ;
 
                return put_user(new_value, p);  /* return current value */
 
@@ -222,20 +221,16 @@ static ssize_t at91_wdt_write(struct file *file, const 
char *data, size_t len,
        if (!nowayout) {
                size_t i;
 
-               at91wdt_private.expect_close = 0;
 
                for (i = 0; i < len; i++) {
                        char c;
                        if (get_user(c, data + i))
                                return -EFAULT;
-                       if (c == 'V') {
-                               at91wdt_private.expect_close = 42;
-                               break;
                        }
                }
        }
 
-       at91wdt_private.next_heartbeat = jiffies + heartbeat * HZ;
+       driver_data->next_heartbeat = jiffies + heartbeat * HZ;
 
        return len;
 }
@@ -265,9 +260,19 @@ static struct watchdog_device at91wdt_wdd __initdata = {
 
 static int __init at91wdt_probe(struct platform_device *pdev)
 {
+       struct at91wdt_drvdata *driver_data;
        struct resource *r;
        int res;
 
+       driver_data = devm_kzalloc(&pdev->dev,
+                               sizeof(*driver_data), GFP_KERNEL);
+       if (!driver_data) {
+               dev_err(&pdev->dev, "Unable to alloacate watchdog device\n");
+               return -ENOMEM;
+       }
+
+       watchdog_set_drvdata(&at91wdt_wdd, driver_data);
+
        if (at91wdt_miscdev.parent)
                return -EBUSY;
        at91wdt_miscdev.parent = &pdev->dev;
@@ -275,8 +280,8 @@ static int __init at91wdt_probe(struct platform_device 
*pdev)
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!r)
                return -ENODEV;
-       at91wdt_private.base = ioremap(r->start, resource_size(r));
-       if (!at91wdt_private.base) {
+       driver_data->phybase = ioremap(r->start, resource_size(r));
+       if (!driver_data->phybase) {
                dev_err(&pdev->dev, "failed to map registers, aborting.\n");
                return -ENOMEM;
        }
@@ -292,9 +297,10 @@ static int __init at91wdt_probe(struct platform_device 
*pdev)
        if (res)
                return res;
 
-       at91wdt_private.next_heartbeat = jiffies + at91wdt_wdd.timeout * HZ;
-       setup_timer(&at91wdt_private.timer, at91_ping, 0);
-       mod_timer(&at91wdt_private.timer, jiffies + WDT_TIMEOUT);
+       driver_data->next_heartbeat = jiffies + at91wdt_wdd.timeout * HZ;
+       setup_timer(&driver_data->timer, at91_ping,
+                                       (unsigned long)&at91wdt_wdd);
+       mod_timer(&driver_data->timer, jiffies + WDT_TIMEOUT);
 
        pr_info("enabled (heartbeat=%d sec, nowayout=%d)\n",
                at91wdt_wdd.timeout, nowayout);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to