[PATCH v4 2/8] watchdog/at91sam9_wdt: Remove at91wdt_private and add at91wdt_drvdata struct

Wenyou Yang wenyou.yang at atmel.com
Fri Feb 1 02:06:20 EST 2013


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.yang at atmel.com>
Cc: wim at iguana.be
Cc: linux-watchdog at vger.kernel.org
Cc: linux-kernel at 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 61129fc..66d3afb 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




More information about the linux-arm-kernel mailing list