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

Wenyou Yang
2013-02-01T07:06:20Z

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@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