From 6adb730dc2085c16c52a2f991cc1661e4a7fd6d5 Mon Sep 17 00:00:00 2001 From: Markus Mayer Date: Fri, 22 Nov 2013 14:56:03 -0800 Subject: watchdog: bcm281xx: Watchdog Driver This commit adds support for the watchdog timer used on the BCM281xx family of SoCs. Signed-off-by: Markus Mayer Reviewed-by: Matt Porter Reviewed-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- arch/arm/configs/bcm_defconfig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/configs/bcm_defconfig b/arch/arm/configs/bcm_defconfig index 2c38fdf1951..fc3afd887a2 100644 --- a/arch/arm/configs/bcm_defconfig +++ b/arch/arm/configs/bcm_defconfig @@ -126,3 +126,5 @@ CONFIG_CRC7=y CONFIG_XZ_DEC=y CONFIG_AVERAGE=y CONFIG_PINCTRL_CAPRI=y +CONFIG_WATCHDOG=y +CONFIG_BCM_KONA_WDT=y -- cgit v1.2.3-70-g09d2 From 6e2ac20e9c47cf26a1dd5a0f05b93ef0afd3c1c5 Mon Sep 17 00:00:00 2001 From: Markus Mayer Date: Mon, 6 Jan 2014 13:56:10 -0800 Subject: watchdog: bcm281xx: Debugfs support This change introduces debugfs support for the BCM281xx watchdog driver. Signed-off-by: Markus Mayer Signed-off-by: Wim Van Sebroeck --- arch/arm/configs/bcm_defconfig | 1 + drivers/watchdog/Kconfig | 10 ++++ drivers/watchdog/bcm_kona_wdt.c | 108 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 115 insertions(+), 4 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/configs/bcm_defconfig b/arch/arm/configs/bcm_defconfig index fc3afd887a2..2519d6de064 100644 --- a/arch/arm/configs/bcm_defconfig +++ b/arch/arm/configs/bcm_defconfig @@ -128,3 +128,4 @@ CONFIG_AVERAGE=y CONFIG_PINCTRL_CAPRI=y CONFIG_WATCHDOG=y CONFIG_BCM_KONA_WDT=y +CONFIG_BCM_KONA_WDT_DEBUG=y diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 042e4521a8b..1491f0f4d41 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1151,6 +1151,16 @@ config BCM_KONA_WDT Say 'Y' or 'M' here to enable the driver. The module will be called bcm_kona_wdt. +config BCM_KONA_WDT_DEBUG + bool "DEBUGFS support for BCM Kona Watchdog" + depends on BCM_KONA_WDT + help + If enabled, adds /sys/kernel/debug/bcm_kona_wdt/info which provides + access to the driver's internal data structures as well as watchdog + timer hardware registres. + + If in doubt, say 'N'. + config LANTIQ_WDT tristate "Lantiq SoC watchdog" depends on LANTIQ diff --git a/drivers/watchdog/bcm_kona_wdt.c b/drivers/watchdog/bcm_kona_wdt.c index 7e41a83eb45..9c248099f4a 100644 --- a/drivers/watchdog/bcm_kona_wdt.c +++ b/drivers/watchdog/bcm_kona_wdt.c @@ -11,6 +11,7 @@ * GNU General Public License for more details. */ +#include #include #include #include @@ -55,9 +56,13 @@ struct bcm_kona_wdt { */ int resolution; spinlock_t lock; +#ifdef CONFIG_BCM_KONA_WDT_DEBUG + unsigned long busy_count; + struct dentry *debugfs; +#endif }; -static int secure_register_read(void __iomem *addr) +static int secure_register_read(struct bcm_kona_wdt *wdt, uint32_t offset) { uint32_t val; unsigned count = 0; @@ -70,10 +75,16 @@ static int secure_register_read(void __iomem *addr) do { if (unlikely(count > 1)) udelay(5); - val = readl_relaxed(addr); + val = readl_relaxed(wdt->base + offset); count++; } while ((val & SECWDOG_WD_LOAD_FLAG) && count < SECWDOG_MAX_TRY); +#ifdef CONFIG_BCM_KONA_WDT_DEBUG + /* Remember the maximum number iterations due to WD_LOAD_FLAG */ + if (count > wdt->busy_count) + wdt->busy_count = count; +#endif + /* This is the only place we return a negative value. */ if (val & SECWDOG_WD_LOAD_FLAG) return -ETIMEDOUT; @@ -84,6 +95,93 @@ static int secure_register_read(void __iomem *addr) return val; } +#ifdef CONFIG_BCM_KONA_WDT_DEBUG + +static int bcm_kona_wdt_dbg_show(struct seq_file *s, void *data) +{ + int ctl_val, cur_val, ret; + unsigned long flags; + struct bcm_kona_wdt *wdt = s->private; + + if (!wdt) + return seq_puts(s, "No device pointer\n"); + + spin_lock_irqsave(&wdt->lock, flags); + ctl_val = secure_register_read(wdt, SECWDOG_CTRL_REG); + cur_val = secure_register_read(wdt, SECWDOG_COUNT_REG); + spin_unlock_irqrestore(&wdt->lock, flags); + + if (ctl_val < 0 || cur_val < 0) { + ret = seq_puts(s, "Error accessing hardware\n"); + } else { + int ctl, cur, ctl_sec, cur_sec, res; + + ctl = ctl_val & SECWDOG_COUNT_MASK; + res = (ctl_val & SECWDOG_RES_MASK) >> SECWDOG_CLKS_SHIFT; + cur = cur_val & SECWDOG_COUNT_MASK; + ctl_sec = TICKS_TO_SECS(ctl, wdt); + cur_sec = TICKS_TO_SECS(cur, wdt); + ret = seq_printf(s, "Resolution: %d / %d\n" + "Control: %d s / %d (%#x) ticks\n" + "Current: %d s / %d (%#x) ticks\n" + "Busy count: %lu\n", res, + wdt->resolution, ctl_sec, ctl, ctl, cur_sec, + cur, cur, wdt->busy_count); + } + + return ret; +} + +static int bcm_kona_dbg_open(struct inode *inode, struct file *file) +{ + return single_open(file, bcm_kona_wdt_dbg_show, inode->i_private); +} + +static const struct file_operations bcm_kona_dbg_operations = { + .open = bcm_kona_dbg_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void bcm_kona_wdt_debug_init(struct platform_device *pdev) +{ + struct dentry *dir; + struct bcm_kona_wdt *wdt = platform_get_drvdata(pdev); + + if (!wdt) + return; + + wdt->debugfs = NULL; + + dir = debugfs_create_dir(BCM_KONA_WDT_NAME, NULL); + if (IS_ERR_OR_NULL(dir)) + return; + + if (debugfs_create_file("info", S_IFREG | S_IRUGO, dir, wdt, + &bcm_kona_dbg_operations)) + wdt->debugfs = dir; + else + debugfs_remove_recursive(dir); +} + +static void bcm_kona_wdt_debug_exit(struct platform_device *pdev) +{ + struct bcm_kona_wdt *wdt = platform_get_drvdata(pdev); + + if (wdt && wdt->debugfs) { + debugfs_remove_recursive(wdt->debugfs); + wdt->debugfs = NULL; + } +} + +#else + +static void bcm_kona_wdt_debug_init(struct platform_device *pdev) {} +static void bcm_kona_wdt_debug_exit(struct platform_device *pdev) {} + +#endif /* CONFIG_BCM_KONA_WDT_DEBUG */ + static int bcm_kona_wdt_ctrl_reg_modify(struct bcm_kona_wdt *wdt, unsigned mask, unsigned newval) { @@ -93,7 +191,7 @@ static int bcm_kona_wdt_ctrl_reg_modify(struct bcm_kona_wdt *wdt, spin_lock_irqsave(&wdt->lock, flags); - val = secure_register_read(wdt->base + SECWDOG_CTRL_REG); + val = secure_register_read(wdt, SECWDOG_CTRL_REG); if (val < 0) { ret = val; } else { @@ -140,7 +238,7 @@ static unsigned int bcm_kona_wdt_get_timeleft(struct watchdog_device *wdog) unsigned long flags; spin_lock_irqsave(&wdt->lock, flags); - val = secure_register_read(wdt->base + SECWDOG_COUNT_REG); + val = secure_register_read(wdt, SECWDOG_COUNT_REG); spin_unlock_irqrestore(&wdt->lock, flags); if (val < 0) @@ -229,6 +327,7 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev) return ret; } + bcm_kona_wdt_debug_init(pdev); dev_dbg(dev, "Broadcom Kona Watchdog Timer"); return 0; @@ -236,6 +335,7 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev) static int bcm_kona_wdt_remove(struct platform_device *pdev) { + bcm_kona_wdt_debug_exit(pdev); bcm_kona_wdt_shutdown(pdev); watchdog_unregister_device(&bcm_kona_wdt_wdd); dev_dbg(&pdev->dev, "Watchdog driver disabled"); -- cgit v1.2.3-70-g09d2 From fe46aa679f12c6e43039a2a3255ea47e47dcef52 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Fri, 4 Oct 2013 09:24:14 +0200 Subject: ARM: at91/dt: add sam9 watchdog default options to SoCs Set default watchdog options in every SoC compatible with the sam9 watchdog. Signed-off-by: Boris BREZILLON Acked-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- arch/arm/boot/dts/at91sam9260.dtsi | 5 +++++ arch/arm/boot/dts/at91sam9263.dtsi | 5 +++++ arch/arm/boot/dts/at91sam9g45.dtsi | 5 +++++ arch/arm/boot/dts/at91sam9n12.dtsi | 5 +++++ arch/arm/boot/dts/at91sam9x5.dtsi | 5 +++++ arch/arm/boot/dts/sama5d3.dtsi | 5 +++++ 6 files changed, 30 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index 56ee8282a7a..997901f7ed7 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -648,6 +648,11 @@ watchdog@fffffd40 { compatible = "atmel,at91sam9260-wdt"; reg = <0xfffffd40 0x10>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + atmel,watchdog-type = "hardware"; + atmel,reset-type = "all"; + atmel,dbg-halt; + atmel,idle-halt; status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index c8fa9b9f07e..0042f73068b 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -552,6 +552,11 @@ watchdog@fffffd40 { compatible = "atmel,at91sam9260-wdt"; reg = <0xfffffd40 0x10>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + atmel,watchdog-type = "hardware"; + atmel,reset-type = "all"; + atmel,dbg-halt; + atmel,idle-halt; status = "disabled"; }; diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index ef0857cb171..cbcc058b26b 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -706,6 +706,11 @@ watchdog@fffffd40 { compatible = "atmel,at91sam9260-wdt"; reg = <0xfffffd40 0x10>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + atmel,watchdog-type = "hardware"; + atmel,reset-type = "all"; + atmel,dbg-halt; + atmel,idle-halt; status = "disabled"; }; diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index 7248270a3ea..394e6ce2afb 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi @@ -541,6 +541,11 @@ watchdog@fffffe40 { compatible = "atmel,at91sam9260-wdt"; reg = <0xfffffe40 0x10>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + atmel,watchdog-type = "hardware"; + atmel,reset-type = "all"; + atmel,dbg-halt; + atmel,idle-halt; status = "disabled"; }; diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 6e5e9cfc3c4..174219de92f 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -754,6 +754,11 @@ watchdog@fffffe40 { compatible = "atmel,at91sam9260-wdt"; reg = <0xfffffe40 0x10>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + atmel,watchdog-type = "hardware"; + atmel,reset-type = "all"; + atmel,dbg-halt; + atmel,idle-halt; status = "disabled"; }; diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi index 1105558d188..52447c17537 100644 --- a/arch/arm/boot/dts/sama5d3.dtsi +++ b/arch/arm/boot/dts/sama5d3.dtsi @@ -1092,6 +1092,11 @@ watchdog@fffffe40 { compatible = "atmel,at91sam9260-wdt"; reg = <0xfffffe40 0x10>; + interrupts = <4 IRQ_TYPE_LEVEL_HIGH 7>; + atmel,watchdog-type = "hardware"; + atmel,reset-type = "all"; + atmel,dbg-halt; + atmel,idle-halt; status = "disabled"; }; -- cgit v1.2.3-70-g09d2 From 705b675db92bbbda47507205a37784d2d0ab8c0d Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Fri, 4 Oct 2013 09:24:15 +0200 Subject: ARM: at91/dt: add watchdog properties to kizbox board Add watchdog specific config for kizbox board. Signed-off-by: Boris BREZILLON Acked-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck --- arch/arm/boot/dts/kizbox.dts | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/boot/dts/kizbox.dts b/arch/arm/boot/dts/kizbox.dts index 02df1914a47..928f6eef2d5 100644 --- a/arch/arm/boot/dts/kizbox.dts +++ b/arch/arm/boot/dts/kizbox.dts @@ -53,6 +53,12 @@ status = "okay"; }; + watchdog@fffffd40 { + timeout-sec = <15>; + atmel,max-heartbeat-sec = <16>; + atmel,min-heartbeat-sec = <0>; + status = "okay"; + }; }; nand0: nand@40000000 { -- cgit v1.2.3-70-g09d2