Loading drivers/watchdog/shwdt.c +19 −15 Original line number Original line Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <linux/platform_device.h> #include <linux/platform_device.h> #include <linux/init.h> #include <linux/init.h> #include <linux/types.h> #include <linux/types.h> #include <linux/spinlock.h> #include <linux/miscdevice.h> #include <linux/miscdevice.h> #include <linux/watchdog.h> #include <linux/watchdog.h> #include <linux/fs.h> #include <linux/fs.h> Loading Loading @@ -65,8 +66,6 @@ static int clock_division_ratio = WTCSR_CKS_4096; static int clock_division_ratio = WTCSR_CKS_4096; #define next_ping_period(cks) (jiffies + msecs_to_jiffies(cks - 4)) #define next_ping_period(cks) (jiffies + msecs_to_jiffies(cks - 4)) static DEFINE_SPINLOCK(shwdt_lock); #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ static bool nowayout = WATCHDOG_NOWAYOUT; static bool nowayout = WATCHDOG_NOWAYOUT; Loading @@ -75,6 +74,7 @@ static unsigned long next_heartbeat; struct sh_wdt { struct sh_wdt { void __iomem *base; void __iomem *base; struct device *dev; struct device *dev; spinlock_t lock; struct timer_list timer; struct timer_list timer; Loading @@ -88,7 +88,7 @@ static int sh_wdt_start(struct watchdog_device *wdt_dev) unsigned long flags; unsigned long flags; u8 csr; u8 csr; spin_lock_irqsave(&shwdt_lock, flags); spin_lock_irqsave(&wdt->lock, flags); next_heartbeat = jiffies + (heartbeat * HZ); next_heartbeat = jiffies + (heartbeat * HZ); mod_timer(&wdt->timer, next_ping_period(clock_division_ratio)); mod_timer(&wdt->timer, next_ping_period(clock_division_ratio)); Loading Loading @@ -117,7 +117,7 @@ static int sh_wdt_start(struct watchdog_device *wdt_dev) csr &= ~RSTCSR_RSTS; csr &= ~RSTCSR_RSTS; sh_wdt_write_rstcsr(csr); sh_wdt_write_rstcsr(csr); #endif #endif spin_unlock_irqrestore(&shwdt_lock, flags); spin_unlock_irqrestore(&wdt->lock, flags); return 0; return 0; } } Loading @@ -128,7 +128,7 @@ static int sh_wdt_stop(struct watchdog_device *wdt_dev) unsigned long flags; unsigned long flags; u8 csr; u8 csr; spin_lock_irqsave(&shwdt_lock, flags); spin_lock_irqsave(&wdt->lock, flags); del_timer(&wdt->timer); del_timer(&wdt->timer); Loading @@ -136,33 +136,35 @@ static int sh_wdt_stop(struct watchdog_device *wdt_dev) csr &= ~WTCSR_TME; csr &= ~WTCSR_TME; sh_wdt_write_csr(csr); sh_wdt_write_csr(csr); spin_unlock_irqrestore(&shwdt_lock, flags); spin_unlock_irqrestore(&wdt->lock, flags); return 0; return 0; } } static int sh_wdt_keepalive(struct watchdog_device *wdt_dev) static int sh_wdt_keepalive(struct watchdog_device *wdt_dev) { { struct sh_wdt *wdt = watchdog_get_drvdata(wdt_dev); unsigned long flags; unsigned long flags; spin_lock_irqsave(&shwdt_lock, flags); spin_lock_irqsave(&wdt->lock, flags); next_heartbeat = jiffies + (heartbeat * HZ); next_heartbeat = jiffies + (heartbeat * HZ); spin_unlock_irqrestore(&shwdt_lock, flags); spin_unlock_irqrestore(&wdt->lock, flags); return 0; return 0; } } static int sh_wdt_set_heartbeat(struct watchdog_device *wdt_dev, unsigned t) static int sh_wdt_set_heartbeat(struct watchdog_device *wdt_dev, unsigned t) { { struct sh_wdt *wdt = watchdog_get_drvdata(wdt_dev); unsigned long flags; unsigned long flags; if (unlikely(t < 1 || t > 3600)) /* arbitrary upper limit */ if (unlikely(t < 1 || t > 3600)) /* arbitrary upper limit */ return -EINVAL; return -EINVAL; spin_lock_irqsave(&shwdt_lock, flags); spin_lock_irqsave(&wdt->lock, flags); heartbeat = t; heartbeat = t; wdt_dev->timeout = t; wdt_dev->timeout = t; spin_unlock_irqrestore(&shwdt_lock, flags); spin_unlock_irqrestore(&wdt->lock, flags); return 0; return 0; } } Loading @@ -172,7 +174,7 @@ static void sh_wdt_ping(unsigned long data) struct sh_wdt *wdt = (struct sh_wdt *)data; struct sh_wdt *wdt = (struct sh_wdt *)data; unsigned long flags; unsigned long flags; spin_lock_irqsave(&shwdt_lock, flags); spin_lock_irqsave(&wdt->lock, flags); if (time_before(jiffies, next_heartbeat)) { if (time_before(jiffies, next_heartbeat)) { u8 csr; u8 csr; Loading @@ -186,7 +188,7 @@ static void sh_wdt_ping(unsigned long data) } else } else dev_warn(wdt->dev, "Heartbeat lost! Will not ping " dev_warn(wdt->dev, "Heartbeat lost! Will not ping " "the watchdog\n"); "the watchdog\n"); spin_unlock_irqrestore(&shwdt_lock, flags); spin_unlock_irqrestore(&wdt->lock, flags); } } static const struct watchdog_info sh_wdt_info = { static const struct watchdog_info sh_wdt_info = { Loading Loading @@ -238,12 +240,17 @@ static int __devinit sh_wdt_probe(struct platform_device *pdev) wdt->dev = &pdev->dev; wdt->dev = &pdev->dev; watchdog_set_nowayout(&sh_wdt_dev, nowayout); watchdog_set_drvdata(&sh_wdt_dev, wdt); wdt->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); wdt->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (unlikely(!wdt->base)) { if (unlikely(!wdt->base)) { rc = -ENXIO; rc = -ENXIO; goto out_err; goto out_err; } } spin_lock_init(&wdt->lock); rc = sh_wdt_set_heartbeat(&sh_wdt_dev, heartbeat); rc = sh_wdt_set_heartbeat(&sh_wdt_dev, heartbeat); if (unlikely(rc)) { if (unlikely(rc)) { /* Default timeout if invalid */ /* Default timeout if invalid */ Loading @@ -257,9 +264,6 @@ static int __devinit sh_wdt_probe(struct platform_device *pdev) dev_info(&pdev->dev, "configured with heartbeat=%d sec (nowayout=%d)\n", dev_info(&pdev->dev, "configured with heartbeat=%d sec (nowayout=%d)\n", sh_wdt_dev.timeout, nowayout); sh_wdt_dev.timeout, nowayout); watchdog_set_nowayout(&sh_wdt_dev, nowayout); watchdog_set_drvdata(&sh_wdt_dev, wdt); rc = watchdog_register_device(&sh_wdt_dev); rc = watchdog_register_device(&sh_wdt_dev); if (unlikely(rc)) { if (unlikely(rc)) { dev_err(&pdev->dev, "Can't register watchdog (err=%d)\n", rc); dev_err(&pdev->dev, "Can't register watchdog (err=%d)\n", rc); Loading Loading
drivers/watchdog/shwdt.c +19 −15 Original line number Original line Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <linux/platform_device.h> #include <linux/platform_device.h> #include <linux/init.h> #include <linux/init.h> #include <linux/types.h> #include <linux/types.h> #include <linux/spinlock.h> #include <linux/miscdevice.h> #include <linux/miscdevice.h> #include <linux/watchdog.h> #include <linux/watchdog.h> #include <linux/fs.h> #include <linux/fs.h> Loading Loading @@ -65,8 +66,6 @@ static int clock_division_ratio = WTCSR_CKS_4096; static int clock_division_ratio = WTCSR_CKS_4096; #define next_ping_period(cks) (jiffies + msecs_to_jiffies(cks - 4)) #define next_ping_period(cks) (jiffies + msecs_to_jiffies(cks - 4)) static DEFINE_SPINLOCK(shwdt_lock); #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ static bool nowayout = WATCHDOG_NOWAYOUT; static bool nowayout = WATCHDOG_NOWAYOUT; Loading @@ -75,6 +74,7 @@ static unsigned long next_heartbeat; struct sh_wdt { struct sh_wdt { void __iomem *base; void __iomem *base; struct device *dev; struct device *dev; spinlock_t lock; struct timer_list timer; struct timer_list timer; Loading @@ -88,7 +88,7 @@ static int sh_wdt_start(struct watchdog_device *wdt_dev) unsigned long flags; unsigned long flags; u8 csr; u8 csr; spin_lock_irqsave(&shwdt_lock, flags); spin_lock_irqsave(&wdt->lock, flags); next_heartbeat = jiffies + (heartbeat * HZ); next_heartbeat = jiffies + (heartbeat * HZ); mod_timer(&wdt->timer, next_ping_period(clock_division_ratio)); mod_timer(&wdt->timer, next_ping_period(clock_division_ratio)); Loading Loading @@ -117,7 +117,7 @@ static int sh_wdt_start(struct watchdog_device *wdt_dev) csr &= ~RSTCSR_RSTS; csr &= ~RSTCSR_RSTS; sh_wdt_write_rstcsr(csr); sh_wdt_write_rstcsr(csr); #endif #endif spin_unlock_irqrestore(&shwdt_lock, flags); spin_unlock_irqrestore(&wdt->lock, flags); return 0; return 0; } } Loading @@ -128,7 +128,7 @@ static int sh_wdt_stop(struct watchdog_device *wdt_dev) unsigned long flags; unsigned long flags; u8 csr; u8 csr; spin_lock_irqsave(&shwdt_lock, flags); spin_lock_irqsave(&wdt->lock, flags); del_timer(&wdt->timer); del_timer(&wdt->timer); Loading @@ -136,33 +136,35 @@ static int sh_wdt_stop(struct watchdog_device *wdt_dev) csr &= ~WTCSR_TME; csr &= ~WTCSR_TME; sh_wdt_write_csr(csr); sh_wdt_write_csr(csr); spin_unlock_irqrestore(&shwdt_lock, flags); spin_unlock_irqrestore(&wdt->lock, flags); return 0; return 0; } } static int sh_wdt_keepalive(struct watchdog_device *wdt_dev) static int sh_wdt_keepalive(struct watchdog_device *wdt_dev) { { struct sh_wdt *wdt = watchdog_get_drvdata(wdt_dev); unsigned long flags; unsigned long flags; spin_lock_irqsave(&shwdt_lock, flags); spin_lock_irqsave(&wdt->lock, flags); next_heartbeat = jiffies + (heartbeat * HZ); next_heartbeat = jiffies + (heartbeat * HZ); spin_unlock_irqrestore(&shwdt_lock, flags); spin_unlock_irqrestore(&wdt->lock, flags); return 0; return 0; } } static int sh_wdt_set_heartbeat(struct watchdog_device *wdt_dev, unsigned t) static int sh_wdt_set_heartbeat(struct watchdog_device *wdt_dev, unsigned t) { { struct sh_wdt *wdt = watchdog_get_drvdata(wdt_dev); unsigned long flags; unsigned long flags; if (unlikely(t < 1 || t > 3600)) /* arbitrary upper limit */ if (unlikely(t < 1 || t > 3600)) /* arbitrary upper limit */ return -EINVAL; return -EINVAL; spin_lock_irqsave(&shwdt_lock, flags); spin_lock_irqsave(&wdt->lock, flags); heartbeat = t; heartbeat = t; wdt_dev->timeout = t; wdt_dev->timeout = t; spin_unlock_irqrestore(&shwdt_lock, flags); spin_unlock_irqrestore(&wdt->lock, flags); return 0; return 0; } } Loading @@ -172,7 +174,7 @@ static void sh_wdt_ping(unsigned long data) struct sh_wdt *wdt = (struct sh_wdt *)data; struct sh_wdt *wdt = (struct sh_wdt *)data; unsigned long flags; unsigned long flags; spin_lock_irqsave(&shwdt_lock, flags); spin_lock_irqsave(&wdt->lock, flags); if (time_before(jiffies, next_heartbeat)) { if (time_before(jiffies, next_heartbeat)) { u8 csr; u8 csr; Loading @@ -186,7 +188,7 @@ static void sh_wdt_ping(unsigned long data) } else } else dev_warn(wdt->dev, "Heartbeat lost! Will not ping " dev_warn(wdt->dev, "Heartbeat lost! Will not ping " "the watchdog\n"); "the watchdog\n"); spin_unlock_irqrestore(&shwdt_lock, flags); spin_unlock_irqrestore(&wdt->lock, flags); } } static const struct watchdog_info sh_wdt_info = { static const struct watchdog_info sh_wdt_info = { Loading Loading @@ -238,12 +240,17 @@ static int __devinit sh_wdt_probe(struct platform_device *pdev) wdt->dev = &pdev->dev; wdt->dev = &pdev->dev; watchdog_set_nowayout(&sh_wdt_dev, nowayout); watchdog_set_drvdata(&sh_wdt_dev, wdt); wdt->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); wdt->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (unlikely(!wdt->base)) { if (unlikely(!wdt->base)) { rc = -ENXIO; rc = -ENXIO; goto out_err; goto out_err; } } spin_lock_init(&wdt->lock); rc = sh_wdt_set_heartbeat(&sh_wdt_dev, heartbeat); rc = sh_wdt_set_heartbeat(&sh_wdt_dev, heartbeat); if (unlikely(rc)) { if (unlikely(rc)) { /* Default timeout if invalid */ /* Default timeout if invalid */ Loading @@ -257,9 +264,6 @@ static int __devinit sh_wdt_probe(struct platform_device *pdev) dev_info(&pdev->dev, "configured with heartbeat=%d sec (nowayout=%d)\n", dev_info(&pdev->dev, "configured with heartbeat=%d sec (nowayout=%d)\n", sh_wdt_dev.timeout, nowayout); sh_wdt_dev.timeout, nowayout); watchdog_set_nowayout(&sh_wdt_dev, nowayout); watchdog_set_drvdata(&sh_wdt_dev, wdt); rc = watchdog_register_device(&sh_wdt_dev); rc = watchdog_register_device(&sh_wdt_dev); if (unlikely(rc)) { if (unlikely(rc)) { dev_err(&pdev->dev, "Can't register watchdog (err=%d)\n", rc); dev_err(&pdev->dev, "Can't register watchdog (err=%d)\n", rc); Loading