watchdog: bcm2835_wdt: Use watchdog core to install restart handler
Use the infrastructure provided by the watchdog core to install the restart handler. Acked-by: Eric Anholt <eric@anholt.net> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
parent
55dbe8f325
commit
71e9b2f0bf
|
@ -14,7 +14,6 @@
|
|||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/io.h>
|
||||
|
@ -49,7 +48,6 @@
|
|||
struct bcm2835_wdt {
|
||||
void __iomem *base;
|
||||
spinlock_t lock;
|
||||
struct notifier_block restart_handler;
|
||||
};
|
||||
|
||||
static unsigned int heartbeat;
|
||||
|
@ -99,11 +97,37 @@ static unsigned int bcm2835_wdt_get_timeleft(struct watchdog_device *wdog)
|
|||
return WDOG_TICKS_TO_SECS(ret & PM_WDOG_TIME_SET);
|
||||
}
|
||||
|
||||
static void __bcm2835_restart(struct bcm2835_wdt *wdt)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
/* use a timeout of 10 ticks (~150us) */
|
||||
writel_relaxed(10 | PM_PASSWORD, wdt->base + PM_WDOG);
|
||||
val = readl_relaxed(wdt->base + PM_RSTC);
|
||||
val &= PM_RSTC_WRCFG_CLR;
|
||||
val |= PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET;
|
||||
writel_relaxed(val, wdt->base + PM_RSTC);
|
||||
|
||||
/* No sleeping, possibly atomic. */
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
static int bcm2835_restart(struct watchdog_device *wdog,
|
||||
unsigned long action, void *data)
|
||||
{
|
||||
struct bcm2835_wdt *wdt = watchdog_get_drvdata(wdog);
|
||||
|
||||
__bcm2835_restart(wdt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct watchdog_ops bcm2835_wdt_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.start = bcm2835_wdt_start,
|
||||
.stop = bcm2835_wdt_stop,
|
||||
.get_timeleft = bcm2835_wdt_get_timeleft,
|
||||
.restart = bcm2835_restart,
|
||||
};
|
||||
|
||||
static const struct watchdog_info bcm2835_wdt_info = {
|
||||
|
@ -120,26 +144,6 @@ static struct watchdog_device bcm2835_wdt_wdd = {
|
|||
.timeout = WDOG_TICKS_TO_SECS(PM_WDOG_TIME_SET),
|
||||
};
|
||||
|
||||
static int
|
||||
bcm2835_restart(struct notifier_block *this, unsigned long mode, void *cmd)
|
||||
{
|
||||
struct bcm2835_wdt *wdt = container_of(this, struct bcm2835_wdt,
|
||||
restart_handler);
|
||||
u32 val;
|
||||
|
||||
/* use a timeout of 10 ticks (~150us) */
|
||||
writel_relaxed(10 | PM_PASSWORD, wdt->base + PM_WDOG);
|
||||
val = readl_relaxed(wdt->base + PM_RSTC);
|
||||
val &= PM_RSTC_WRCFG_CLR;
|
||||
val |= PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET;
|
||||
writel_relaxed(val, wdt->base + PM_RSTC);
|
||||
|
||||
/* No sleeping, possibly atomic. */
|
||||
mdelay(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We can't really power off, but if we do the normal reset scheme, and
|
||||
* indicate to bootcode.bin not to reboot, then most of the chip will be
|
||||
|
@ -163,7 +167,7 @@ static void bcm2835_power_off(void)
|
|||
writel_relaxed(val, wdt->base + PM_RSTS);
|
||||
|
||||
/* Continue with normal reset mechanism */
|
||||
bcm2835_restart(&wdt->restart_handler, REBOOT_HARD, NULL);
|
||||
__bcm2835_restart(wdt);
|
||||
}
|
||||
|
||||
static int bcm2835_wdt_probe(struct platform_device *pdev)
|
||||
|
@ -201,6 +205,9 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
|
|||
*/
|
||||
set_bit(WDOG_HW_RUNNING, &bcm2835_wdt_wdd.status);
|
||||
}
|
||||
|
||||
watchdog_set_restart_priority(&bcm2835_wdt_wdd, 128);
|
||||
|
||||
err = watchdog_register_device(&bcm2835_wdt_wdd);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to register watchdog device");
|
||||
|
@ -208,9 +215,6 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
|
|||
return err;
|
||||
}
|
||||
|
||||
wdt->restart_handler.notifier_call = bcm2835_restart;
|
||||
wdt->restart_handler.priority = 128;
|
||||
register_restart_handler(&wdt->restart_handler);
|
||||
if (pm_power_off == NULL)
|
||||
pm_power_off = bcm2835_power_off;
|
||||
|
||||
|
@ -222,7 +226,6 @@ static int bcm2835_wdt_remove(struct platform_device *pdev)
|
|||
{
|
||||
struct bcm2835_wdt *wdt = platform_get_drvdata(pdev);
|
||||
|
||||
unregister_restart_handler(&wdt->restart_handler);
|
||||
if (pm_power_off == bcm2835_power_off)
|
||||
pm_power_off = NULL;
|
||||
watchdog_unregister_device(&bcm2835_wdt_wdd);
|
||||
|
|
Loading…
Reference in a new issue