From e14538e0db8d880291064348bda7d52ec8322675 Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Fri, 2 Aug 2013 16:40:45 +0200 Subject: watchdog: Add MOXA ART watchdog driver This patch adds a watchdog driver for the main hardware watchdog timer found on MOXA ART SoCs. The MOXA ART SoC provides one writable timer register, restarting the hardware once it reaches zero. The register is auto decremented every APB clock cycle. Signed-off-by: Jonas Jensen Reviewed-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- .../devicetree/bindings/watchdog/moxa,moxart-watchdog.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 Documentation/devicetree/bindings/watchdog/moxa,moxart-watchdog.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/watchdog/moxa,moxart-watchdog.txt b/Documentation/devicetree/bindings/watchdog/moxa,moxart-watchdog.txt new file mode 100644 index 000000000000..1169857d1d12 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/moxa,moxart-watchdog.txt @@ -0,0 +1,15 @@ +MOXA ART Watchdog timer + +Required properties: + +- compatible : Must be "moxa,moxart-watchdog" +- reg : Should contain registers location and length +- clocks : Should contain phandle for the clock that drives the counter + +Example: + + watchdog: watchdog@98500000 { + compatible = "moxa,moxart-watchdog"; + reg = <0x98500000 0x10>; + clocks = <&coreclk>; + }; -- cgit v1.2.3 From 473cf939ff3442dc86d531f3bb152a2f129ea9d1 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 8 Aug 2013 11:31:43 +0200 Subject: watchdog: add ralink watchdog driver Add a driver for the watchdog timer found on Ralink SoC Signed-off-by: John Crispin Signed-off-by: Gabor Juhos Reviewed-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Cc: linux-watchdog@vger.kernel.org Cc: linux-mips@linux-mips.org Cc: devicetree-discuss@lists.ozlabs.org --- .../devicetree/bindings/watchdog/rt2880-wdt.txt | 19 ++ drivers/watchdog/Kconfig | 7 + drivers/watchdog/Makefile | 1 + drivers/watchdog/rt2880_wdt.c | 208 +++++++++++++++++++++ 4 files changed, 235 insertions(+) create mode 100644 Documentation/devicetree/bindings/watchdog/rt2880-wdt.txt create mode 100644 drivers/watchdog/rt2880_wdt.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/watchdog/rt2880-wdt.txt b/Documentation/devicetree/bindings/watchdog/rt2880-wdt.txt new file mode 100644 index 000000000000..d7bab3db9d1f --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/rt2880-wdt.txt @@ -0,0 +1,19 @@ +Ralink Watchdog Timers + +Required properties: +- compatible: must be "ralink,rt2880-wdt" +- reg: physical base address of the controller and length of the register range + +Optional properties: +- interrupt-parent: phandle to the INTC device node +- interrupts: Specify the INTC interrupt number + +Example: + + watchdog@120 { + compatible = "ralink,rt2880-wdt"; + reg = <0x120 0x10>; + + interrupt-parent = <&intc>; + interrupts = <1>; + }; diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 7fc6e101923a..4327b48a35a3 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1135,6 +1135,13 @@ config LANTIQ_WDT help Hardware driver for the Lantiq SoC Watchdog Timer. +config RALINK_WDT + tristate "Ralink SoC watchdog" + select WATCHDOG_CORE + depends on RALINK + help + Hardware driver for the Ralink SoC Watchdog Timer. + # PARISC Architecture # POWERPC Architecture diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 40c36ccdd0d4..89fd3288cd7b 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -135,6 +135,7 @@ obj-$(CONFIG_TXX9_WDT) += txx9wdt.o obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o obj-$(CONFIG_LANTIQ_WDT) += lantiq_wdt.o +obj-$(CONFIG_RALINK_WDT) += rt2880_wdt.o # PARISC Architecture diff --git a/drivers/watchdog/rt2880_wdt.c b/drivers/watchdog/rt2880_wdt.c new file mode 100644 index 000000000000..4d07964aeae3 --- /dev/null +++ b/drivers/watchdog/rt2880_wdt.c @@ -0,0 +1,208 @@ +/* + * Ralink RT288x/RT3xxx/MT76xx built-in hardware watchdog timer + * + * Copyright (C) 2011 Gabor Juhos + * Copyright (C) 2013 John Crispin + * + * This driver was based on: drivers/watchdog/softdog.c + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define SYSC_RSTSTAT 0x38 +#define WDT_RST_CAUSE BIT(1) + +#define RALINK_WDT_TIMEOUT 30 +#define RALINK_WDT_PRESCALE 65536 + +#define TIMER_REG_TMR1LOAD 0x00 +#define TIMER_REG_TMR1CTL 0x08 + +#define TMRSTAT_TMR1RST BIT(5) + +#define TMR1CTL_ENABLE BIT(7) +#define TMR1CTL_MODE_SHIFT 4 +#define TMR1CTL_MODE_MASK 0x3 +#define TMR1CTL_MODE_FREE_RUNNING 0x0 +#define TMR1CTL_MODE_PERIODIC 0x1 +#define TMR1CTL_MODE_TIMEOUT 0x2 +#define TMR1CTL_MODE_WDT 0x3 +#define TMR1CTL_PRESCALE_MASK 0xf +#define TMR1CTL_PRESCALE_65536 0xf + +static struct clk *rt288x_wdt_clk; +static unsigned long rt288x_wdt_freq; +static void __iomem *rt288x_wdt_base; + +static bool nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, bool, 0); +MODULE_PARM_DESC(nowayout, + "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + +static inline void rt_wdt_w32(unsigned reg, u32 val) +{ + iowrite32(val, rt288x_wdt_base + reg); +} + +static inline u32 rt_wdt_r32(unsigned reg) +{ + return ioread32(rt288x_wdt_base + reg); +} + +static int rt288x_wdt_ping(struct watchdog_device *w) +{ + rt_wdt_w32(TIMER_REG_TMR1LOAD, w->timeout * rt288x_wdt_freq); + + return 0; +} + +static int rt288x_wdt_start(struct watchdog_device *w) +{ + u32 t; + + t = rt_wdt_r32(TIMER_REG_TMR1CTL); + t &= ~(TMR1CTL_MODE_MASK << TMR1CTL_MODE_SHIFT | + TMR1CTL_PRESCALE_MASK); + t |= (TMR1CTL_MODE_WDT << TMR1CTL_MODE_SHIFT | + TMR1CTL_PRESCALE_65536); + rt_wdt_w32(TIMER_REG_TMR1CTL, t); + + rt288x_wdt_ping(w); + + t = rt_wdt_r32(TIMER_REG_TMR1CTL); + t |= TMR1CTL_ENABLE; + rt_wdt_w32(TIMER_REG_TMR1CTL, t); + + return 0; +} + +static int rt288x_wdt_stop(struct watchdog_device *w) +{ + u32 t; + + rt288x_wdt_ping(w); + + t = rt_wdt_r32(TIMER_REG_TMR1CTL); + t &= ~TMR1CTL_ENABLE; + rt_wdt_w32(TIMER_REG_TMR1CTL, t); + + return 0; +} + +static int rt288x_wdt_set_timeout(struct watchdog_device *w, unsigned int t) +{ + w->timeout = t; + rt288x_wdt_ping(w); + + return 0; +} + +static int rt288x_wdt_bootcause(void) +{ + if (rt_sysc_r32(SYSC_RSTSTAT) & WDT_RST_CAUSE) + return WDIOF_CARDRESET; + + return 0; +} + +static struct watchdog_info rt288x_wdt_info = { + .identity = "Ralink Watchdog", + .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, +}; + +static struct watchdog_ops rt288x_wdt_ops = { + .owner = THIS_MODULE, + .start = rt288x_wdt_start, + .stop = rt288x_wdt_stop, + .ping = rt288x_wdt_ping, + .set_timeout = rt288x_wdt_set_timeout, +}; + +static struct watchdog_device rt288x_wdt_dev = { + .info = &rt288x_wdt_info, + .ops = &rt288x_wdt_ops, + .min_timeout = 1, +}; + +static int rt288x_wdt_probe(struct platform_device *pdev) +{ + struct resource *res; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + rt288x_wdt_base = devm_request_and_ioremap(&pdev->dev, res); + if (IS_ERR(rt288x_wdt_base)) + return PTR_ERR(rt288x_wdt_base); + + rt288x_wdt_clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(rt288x_wdt_clk)) + return PTR_ERR(rt288x_wdt_clk); + + device_reset(&pdev->dev); + + rt288x_wdt_freq = clk_get_rate(rt288x_wdt_clk) / RALINK_WDT_PRESCALE; + + rt288x_wdt_dev.dev = &pdev->dev; + rt288x_wdt_dev.bootstatus = rt288x_wdt_bootcause(); + + rt288x_wdt_dev.max_timeout = (0xfffful / rt288x_wdt_freq); + rt288x_wdt_dev.timeout = rt288x_wdt_dev.max_timeout; + + watchdog_set_nowayout(&rt288x_wdt_dev, nowayout); + + ret = watchdog_register_device(&rt288x_wdt_dev); + if (!ret) + dev_info(&pdev->dev, "Initialized\n"); + + return 0; +} + +static int rt288x_wdt_remove(struct platform_device *pdev) +{ + watchdog_unregister_device(&rt288x_wdt_dev); + + return 0; +} + +static void rt288x_wdt_shutdown(struct platform_device *pdev) +{ + rt288x_wdt_stop(&rt288x_wdt_dev); +} + +static const struct of_device_id rt288x_wdt_match[] = { + { .compatible = "ralink,rt2880-wdt" }, + {}, +}; +MODULE_DEVICE_TABLE(of, rt288x_wdt_match); + +static struct platform_driver rt288x_wdt_driver = { + .probe = rt288x_wdt_probe, + .remove = rt288x_wdt_remove, + .shutdown = rt288x_wdt_shutdown, + .driver = { + .name = KBUILD_MODNAME, + .owner = THIS_MODULE, + .of_match_table = rt288x_wdt_match, + }, +}; + +module_platform_driver(rt288x_wdt_driver); + +MODULE_DESCRIPTION("MediaTek/Ralink RT288x/RT3xxx hardware watchdog driver"); +MODULE_AUTHOR("Gabor Juhos Date: Wed, 21 Aug 2013 14:42:09 +0200 Subject: documentation/devicetree: Move DT bindings from gpio to watchdog I accidently put the devicetree bindings for the MEN A21 watchdog driver in Documentation/devicetree/bindings/gpio instead of Documentation/devicetree/bindings/watchdog, this patch addresses this error. Signed-off-by: Johannes Thumshirn Acked-by: Stephen Warren Reviewed-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Cc: Rob Herring Cc: Pawel Moll Cc: Mark Rutland Cc: Ian Campbell Cc: Rob Landley --- .../devicetree/bindings/gpio/men-a021-wdt.txt | 25 ---------------------- .../devicetree/bindings/watchdog/men-a021-wdt.txt | 25 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 25 deletions(-) delete mode 100644 Documentation/devicetree/bindings/gpio/men-a021-wdt.txt create mode 100644 Documentation/devicetree/bindings/watchdog/men-a021-wdt.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/gpio/men-a021-wdt.txt b/Documentation/devicetree/bindings/gpio/men-a021-wdt.txt deleted file mode 100644 index 370dee3226d9..000000000000 --- a/Documentation/devicetree/bindings/gpio/men-a021-wdt.txt +++ /dev/null @@ -1,25 +0,0 @@ -Bindings for MEN A21 Watchdog device connected to GPIO lines - -Required properties: -- compatible: "men,a021-wdt" -- gpios: Specifies the pins that control the Watchdog, order: - 1: Watchdog enable - 2: Watchdog fast-mode - 3: Watchdog trigger - 4: Watchdog reset cause bit 0 - 5: Watchdog reset cause bit 1 - 6: Watchdog reset cause bit 2 - -Optional properties: -- None - -Example: - watchdog { - compatible ="men,a021-wdt"; - gpios = <&gpio3 9 1 /* WD_EN */ - &gpio3 10 1 /* WD_FAST */ - &gpio3 11 1 /* WD_TRIG */ - &gpio3 6 1 /* RST_CAUSE[0] */ - &gpio3 7 1 /* RST_CAUSE[1] */ - &gpio3 8 1>; /* RST_CAUSE[2] */ - }; diff --git a/Documentation/devicetree/bindings/watchdog/men-a021-wdt.txt b/Documentation/devicetree/bindings/watchdog/men-a021-wdt.txt new file mode 100644 index 000000000000..370dee3226d9 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/men-a021-wdt.txt @@ -0,0 +1,25 @@ +Bindings for MEN A21 Watchdog device connected to GPIO lines + +Required properties: +- compatible: "men,a021-wdt" +- gpios: Specifies the pins that control the Watchdog, order: + 1: Watchdog enable + 2: Watchdog fast-mode + 3: Watchdog trigger + 4: Watchdog reset cause bit 0 + 5: Watchdog reset cause bit 1 + 6: Watchdog reset cause bit 2 + +Optional properties: +- None + +Example: + watchdog { + compatible ="men,a021-wdt"; + gpios = <&gpio3 9 1 /* WD_EN */ + &gpio3 10 1 /* WD_FAST */ + &gpio3 11 1 /* WD_TRIG */ + &gpio3 6 1 /* RST_CAUSE[0] */ + &gpio3 7 1 /* RST_CAUSE[1] */ + &gpio3 8 1>; /* RST_CAUSE[2] */ + }; -- cgit v1.2.3 From f0fcbdbf202e2be36c8eb6d1f5c01f95805777de Mon Sep 17 00:00:00 2001 From: Xianglong Du Date: Wed, 2 Oct 2013 08:13:49 +0800 Subject: watchdog: sirf: add watchdog driver of CSR SiRFprimaII and SiRFatlasVI On CSR SiRFprimaII and SiRFatlasVI, the 6th timer can act as a watchdog timer when the Watchdog mode is enabled. watchdog occur when TIMER watchdog counter matches the value software pre-set, when this event occurs, the effect is the same as the system software reset. Signed-off-by: Xianglong Du Signed-off-by: Barry Song Cc: Romain Izard Reviewed-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- .../devicetree/bindings/watchdog/sirfsoc_wdt.txt | 14 ++ arch/arm/configs/prima2_defconfig | 1 + drivers/watchdog/Kconfig | 9 + drivers/watchdog/Makefile | 1 + drivers/watchdog/sirfsoc_wdt.c | 224 +++++++++++++++++++++ 5 files changed, 249 insertions(+) create mode 100644 Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt create mode 100644 drivers/watchdog/sirfsoc_wdt.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt b/Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt new file mode 100644 index 000000000000..9cbc76c89b2b --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/sirfsoc_wdt.txt @@ -0,0 +1,14 @@ +SiRFSoC Timer and Watchdog Timer(WDT) Controller + +Required properties: +- compatible: "sirf,prima2-tick" +- reg: Address range of tick timer/WDT register set +- interrupts: interrupt number to the cpu + +Example: + +timer@b0020000 { + compatible = "sirf,prima2-tick"; + reg = <0xb0020000 0x1000>; + interrupts = <0>; +}; diff --git a/arch/arm/configs/prima2_defconfig b/arch/arm/configs/prima2_defconfig index 002a1ceadceb..23591dba47a0 100644 --- a/arch/arm/configs/prima2_defconfig +++ b/arch/arm/configs/prima2_defconfig @@ -39,6 +39,7 @@ CONFIG_SPI=y CONFIG_SPI_SIRF=y CONFIG_SPI_SPIDEV=y # CONFIG_HWMON is not set +CONFIG_WATCHDOG=y CONFIG_USB_GADGET=y CONFIG_USB_MASS_STORAGE=m CONFIG_MMC=y diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 4327b48a35a3..74f29a2fc51c 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -402,6 +402,15 @@ config MOXART_WDT To compile this driver as a module, choose M here: the module will be called moxart_wdt. +config SIRFSOC_WATCHDOG + tristate "SiRFSOC watchdog" + depends on ARCH_SIRF + select WATCHDOG_CORE + default y + help + Support for CSR SiRFprimaII and SiRFatlasVI watchdog. When + the watchdog triggers the system will be reset. + # AVR32 Architecture config AT32AP700X_WDT diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 89fd3288cd7b..91bd95a64baf 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -56,6 +56,7 @@ obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o obj-$(CONFIG_RETU_WATCHDOG) += retu_wdt.o obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o obj-$(CONFIG_MOXART_WDT) += moxart_wdt.o +obj-$(CONFIG_SIRFSOC_WATCHDOG) += sirfsoc_wdt.o # AVR32 Architecture obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o diff --git a/drivers/watchdog/sirfsoc_wdt.c b/drivers/watchdog/sirfsoc_wdt.c new file mode 100644 index 000000000000..3b8d7397e001 --- /dev/null +++ b/drivers/watchdog/sirfsoc_wdt.c @@ -0,0 +1,224 @@ +/* + * Watchdog driver for CSR SiRFprimaII and SiRFatlasVI + * + * Copyright (c) 2013 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define SIRFSOC_TIMER_COUNTER_LO 0x0000 +#define SIRFSOC_TIMER_MATCH_0 0x0008 +#define SIRFSOC_TIMER_INT_EN 0x0024 +#define SIRFSOC_TIMER_WATCHDOG_EN 0x0028 +#define SIRFSOC_TIMER_LATCH 0x0030 +#define SIRFSOC_TIMER_LATCHED_LO 0x0034 + +#define SIRFSOC_TIMER_WDT_INDEX 5 + +#define SIRFSOC_WDT_MIN_TIMEOUT 30 /* 30 secs */ +#define SIRFSOC_WDT_MAX_TIMEOUT (10 * 60) /* 10 mins */ +#define SIRFSOC_WDT_DEFAULT_TIMEOUT 30 /* 30 secs */ + +static unsigned int timeout = SIRFSOC_WDT_DEFAULT_TIMEOUT; +static bool nowayout = WATCHDOG_NOWAYOUT; + +module_param(timeout, uint, 0); +module_param(nowayout, bool, 0); + +MODULE_PARM_DESC(timeout, "Default watchdog timeout (in seconds)"); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + +static unsigned int sirfsoc_wdt_gettimeleft(struct watchdog_device *wdd) +{ + u32 counter, match; + void __iomem *wdt_base; + int time_left; + + wdt_base = watchdog_get_drvdata(wdd); + counter = readl(wdt_base + SIRFSOC_TIMER_COUNTER_LO); + match = readl(wdt_base + + SIRFSOC_TIMER_MATCH_0 + (SIRFSOC_TIMER_WDT_INDEX << 2)); + + time_left = match - counter; + + return time_left / CLOCK_TICK_RATE; +} + +static int sirfsoc_wdt_updatetimeout(struct watchdog_device *wdd) +{ + u32 counter, timeout_ticks; + void __iomem *wdt_base; + + timeout_ticks = wdd->timeout * CLOCK_TICK_RATE; + wdt_base = watchdog_get_drvdata(wdd); + + /* Enable the latch before reading the LATCH_LO register */ + writel(1, wdt_base + SIRFSOC_TIMER_LATCH); + + /* Set the TO value */ + counter = readl(wdt_base + SIRFSOC_TIMER_LATCHED_LO); + + counter += timeout_ticks; + + writel(counter, wdt_base + + SIRFSOC_TIMER_MATCH_0 + (SIRFSOC_TIMER_WDT_INDEX << 2)); + + return 0; +} + +static int sirfsoc_wdt_enable(struct watchdog_device *wdd) +{ + void __iomem *wdt_base = watchdog_get_drvdata(wdd); + sirfsoc_wdt_updatetimeout(wdd); + + /* + * NOTE: If interrupt is not enabled + * then WD-Reset doesn't get generated at all. + */ + writel(readl(wdt_base + SIRFSOC_TIMER_INT_EN) + | (1 << SIRFSOC_TIMER_WDT_INDEX), + wdt_base + SIRFSOC_TIMER_INT_EN); + writel(1, wdt_base + SIRFSOC_TIMER_WATCHDOG_EN); + + return 0; +} + +static int sirfsoc_wdt_disable(struct watchdog_device *wdd) +{ + void __iomem *wdt_base = watchdog_get_drvdata(wdd); + + writel(0, wdt_base + SIRFSOC_TIMER_WATCHDOG_EN); + writel(readl(wdt_base + SIRFSOC_TIMER_INT_EN) + & (~(1 << SIRFSOC_TIMER_WDT_INDEX)), + wdt_base + SIRFSOC_TIMER_INT_EN); + + return 0; +} + +static int sirfsoc_wdt_settimeout(struct watchdog_device *wdd, unsigned int to) +{ + wdd->timeout = to; + sirfsoc_wdt_updatetimeout(wdd); + + return 0; +} + +#define OPTIONS (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE) + +static const struct watchdog_info sirfsoc_wdt_ident = { + .options = OPTIONS, + .firmware_version = 0, + .identity = "SiRFSOC Watchdog", +}; + +static struct watchdog_ops sirfsoc_wdt_ops = { + .owner = THIS_MODULE, + .start = sirfsoc_wdt_enable, + .stop = sirfsoc_wdt_disable, + .get_timeleft = sirfsoc_wdt_gettimeleft, + .ping = sirfsoc_wdt_updatetimeout, + .set_timeout = sirfsoc_wdt_settimeout, +}; + +static struct watchdog_device sirfsoc_wdd = { + .info = &sirfsoc_wdt_ident, + .ops = &sirfsoc_wdt_ops, + .timeout = SIRFSOC_WDT_DEFAULT_TIMEOUT, + .min_timeout = SIRFSOC_WDT_MIN_TIMEOUT, + .max_timeout = SIRFSOC_WDT_MAX_TIMEOUT, +}; + +static int sirfsoc_wdt_probe(struct platform_device *pdev) +{ + struct resource *res; + int ret; + void __iomem *base; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + watchdog_set_drvdata(&sirfsoc_wdd, base); + + watchdog_init_timeout(&sirfsoc_wdd, timeout, &pdev->dev); + watchdog_set_nowayout(&sirfsoc_wdd, nowayout); + + ret = watchdog_register_device(&sirfsoc_wdd); + if (ret) + return ret; + + platform_set_drvdata(pdev, &sirfsoc_wdd); + + return 0; +} + +static void sirfsoc_wdt_shutdown(struct platform_device *pdev) +{ + struct watchdog_device *wdd = platform_get_drvdata(pdev); + + sirfsoc_wdt_disable(wdd); +} + +static int sirfsoc_wdt_remove(struct platform_device *pdev) +{ + sirfsoc_wdt_shutdown(pdev); + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int sirfsoc_wdt_suspend(struct device *dev) +{ + return 0; +} + +static int sirfsoc_wdt_resume(struct device *dev) +{ + struct watchdog_device *wdd = dev_get_drvdata(dev); + + /* + * NOTE: Since timer controller registers settings are saved + * and restored back by the timer-prima2.c, so we need not + * update WD settings except refreshing timeout. + */ + sirfsoc_wdt_updatetimeout(wdd); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(sirfsoc_wdt_pm_ops, + sirfsoc_wdt_suspend, sirfsoc_wdt_resume); + +static const struct of_device_id sirfsoc_wdt_of_match[] = { + { .compatible = "sirf,prima2-tick"}, + {}, +}; +MODULE_DEVICE_TABLE(of, sirfsoc_wdt_of_match); + +static struct platform_driver sirfsoc_wdt_driver = { + .driver = { + .name = "sirfsoc-wdt", + .owner = THIS_MODULE, + .pm = &sirfsoc_wdt_pm_ops, + .of_match_table = of_match_ptr(sirfsoc_wdt_of_match), + }, + .probe = sirfsoc_wdt_probe, + .remove = sirfsoc_wdt_remove, + .shutdown = sirfsoc_wdt_shutdown, +}; +module_platform_driver(sirfsoc_wdt_driver); + +MODULE_DESCRIPTION("SiRF SoC watchdog driver"); +MODULE_AUTHOR("Xianglong Du "); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:sirfsoc-wdt"); -- cgit v1.2.3 From 58e5637333afc2bb024ff8aef212311be0614d47 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Tue, 22 Oct 2013 11:59:12 -0500 Subject: watchdog: dw: Enable OF support for DW watchdog timer Add device tree support to the DW watchdog timer. Signed-off-by: Dinh Nguyen Acked-by: Jamie Iles Acked-by: Mark Rutland Reviewed-by: Pavel Machek Reviewed-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Cc: Viresh Kumar Cc: Rob Herring Cc: Pawel Moll Cc: Stephen Warren Cc: Ian Campbell Cc: devicetree@vger.kernel.org Cc: linux-watchdog@vger.kernel.org --- .../devicetree/bindings/watchdog/dw_wdt.txt | 21 +++++++++++++++++++++ drivers/watchdog/dw_wdt.c | 10 ++++++++++ 2 files changed, 31 insertions(+) create mode 100644 Documentation/devicetree/bindings/watchdog/dw_wdt.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/watchdog/dw_wdt.txt b/Documentation/devicetree/bindings/watchdog/dw_wdt.txt new file mode 100644 index 000000000000..08e16f684f2d --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/dw_wdt.txt @@ -0,0 +1,21 @@ +Synopsys Designware Watchdog Timer + +Required Properties: + +- compatible : Should contain "snps,dw-wdt" +- reg : Base address and size of the watchdog timer registers. +- clocks : phandle + clock-specifier for the clock that drives the + watchdog timer. + +Optional Properties: + +- interrupts : The interrupt used for the watchdog timeout warning. + +Example: + + watchdog0: wd@ffd02000 { + compatible = "snps,dw-wdt"; + reg = <0xffd02000 0x1000>; + interrupts = <0 171 4>; + clocks = <&per_base_clk>; + }; diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c index 42cfd79edf2a..a46f5c7ee7ff 100644 --- a/drivers/watchdog/dw_wdt.c +++ b/drivers/watchdog/dw_wdt.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -337,12 +338,21 @@ static int dw_wdt_drv_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_OF +static const struct of_device_id dw_wdt_of_match[] = { + { .compatible = "snps,dw-wdt", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, dw_wdt_of_match); +#endif + static struct platform_driver dw_wdt_driver = { .probe = dw_wdt_drv_probe, .remove = dw_wdt_drv_remove, .driver = { .name = "dw_wdt", .owner = THIS_MODULE, + .of_match_table = of_match_ptr(dw_wdt_of_match), .pm = &dw_wdt_pm_ops, }, }; -- cgit v1.2.3