Commit 03843248 authored by David Brownell's avatar David Brownell Committed by Tony Lindgren

[PATCH] ARM: OMAP: Watchdog

Teach the OMAP watchdog driver about the driver model, including
defining a shutdown method (to stop the timer before kexec etc)
and suspend/resume methods (for system sleep states).
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent 15b9b00c
......@@ -194,6 +194,39 @@ static void __init omap_init_mmc(void)
static inline void omap_init_mmc(void) {}
#endif
#if defined(CONFIG_OMAP16XX_WATCHDOG) || defined(CONFIG_OMAP16XX_WATCHDOG_MODULE)
#define OMAP_WDT_BASE 0xfffeb000
static struct resource wdt_resources[] = {
{
.start = OMAP_WDT_BASE,
.end = OMAP_WDT_BASE + 0x4f,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device omap_wdt_device = {
.name = "omap1610_wdt",
.id = -1,
.dev = {
.release = omap_nop_release,
},
.num_resources = ARRAY_SIZE(wdt_resources),
.resource = wdt_resources,
};
static void omap_init_wdt(void)
{
(void) platform_device_register(&omap_wdt_device);
}
#else
static inline void omap_init_wdt(void) {}
#endif
/*-------------------------------------------------------------------------*/
/*
* This gets called after board-specific INIT_MACHINE, and initializes most
* on-chip peripherals accessible on this board (except for few like USB):
......@@ -219,6 +252,7 @@ static int __init omap_init_devices(void)
omap_init_i2c();
omap_init_irda();
omap_init_mmc();
omap_init_wdt();
return 0;
}
......
......@@ -21,6 +21,9 @@
* Copyright (c) 2004 Texas Instruments.
* 1. Modified to support OMAP1610 32-KHz watchdog timer
* 2. Ported to 2.6 kernel
*
* Copyright (c) 2005 David Brownell
* Use the driver model and standard identifiers; handle bigger timeouts.
*/
#include <linux/module.h>
......@@ -35,6 +38,7 @@
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/device.h>
#include <linux/moduleparam.h>
#include <asm/io.h>
......@@ -212,12 +216,24 @@ static struct miscdevice omap_wdt_miscdev = {
};
static int __init
omap_wdt_init(void)
omap1610_wdt_probe(struct device *dev)
{
int ret;
struct platform_device *pdev = to_platform_device(dev);
struct resource *res, *mem;
int ret;
/* reserve static register mappings */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENOENT;
mem = request_mem_region(res->start, res->end - res->start + 1,
pdev->name);
if (mem == NULL)
return -EBUSY;
dev_set_drvdata(dev, mem);
omap_wdt_users = 0;
armwdt_ck = clk_get(NULL, "armwdt_ck");
armwdt_ck = clk_get(dev, "armwdt_ck");
if (IS_ERR(armwdt_ck)) {
ret = PTR_ERR(armwdt_ck);
armwdt_ck = NULL;
......@@ -227,6 +243,7 @@ omap_wdt_init(void)
omap_wdt_disable();
omap_wdt_adjust_timeout(timer_margin);
omap_wdt_miscdev.dev = dev;
ret = misc_register(&omap_wdt_miscdev);
if (ret)
goto fail;
......@@ -240,16 +257,74 @@ omap_wdt_init(void)
fail:
if (armwdt_ck)
clk_put(armwdt_ck);
release_resource(mem);
return ret;
}
static void
omap1610_wdt_shutdown(struct device *dev)
{
omap_wdt_disable();
}
static void __exit
omap_wdt_exit(void)
omap1610_wdt_remove(struct device *dev)
{
struct resource *mem = dev_get_drvdata(dev);
misc_deregister(&omap_wdt_miscdev);
release_resource(mem);
clk_put(armwdt_ck);
}
#ifdef CONFIG_PM
/* REVISIT ... not clear this is the best way to handle system suspend; and
* it's very inappropriate for selective device suspend (e.g. suspending this
* through sysfs rather than by stopping the watchdog daemon). Also, this
* may not play well enough with NOWAYOUT...
*/
static int omap1610_wdt_suspend(struct device *dev, pm_message_t mesg, u32 level)
{
if (level == SUSPEND_POWER_DOWN && omap_wdt_users)
omap_wdt_disable();
return 0;
}
static int omap1610_wdt_resume(struct device *dev, u32 level)
{
if (level == RESUME_POWER_ON && omap_wdt_users) {
omap_wdt_enable();
omap_wdt_ping();
}
return 0;
}
#else
#define omap1610_wdt_suspend NULL
#define omap1610_wdt_resume NULL
#endif
static struct device_driver omap1610_wdt_driver = {
.name = "omap1610_wdt",
.bus = &platform_bus_type,
.probe = omap1610_wdt_probe,
.shutdown = omap1610_wdt_shutdown,
.remove = __exit_p(omap1610_wdt_remove),
.suspend = omap1610_wdt_suspend,
.resume = omap1610_wdt_resume,
};
static int __init omap_wdt_init(void)
{
return driver_register(&omap1610_wdt_driver);
}
static void __exit omap_wdt_exit(void)
{
driver_unregister(&omap1610_wdt_driver);
}
module_init(omap_wdt_init);
module_exit(omap_wdt_exit);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment