Armada 370/XP watchdog support
Subsystems (6)
v5 cover Armada 370/XP watchdog support
A new round, mostly fixing some minor nitpicks.
This entire series depends on latest irqchip-orion fixes by Sebastian. Namely, this one: https://lkml.org/lkml/2014/1/23/594.
How should we handle this dependency?
Changes from v4 are:
* Provided better commit subject and commit log for patch 7:
"watchdog: orion: Handle the interrupt so it's properly acked".
* Corrected the misnamed fuction try_rstout_ioremap().
* A bunch of s/interruption/interrupt fixes
* Dropped the '0' as a valid IRQ in the platform_get_irq() check, given it should return a positive virq-space number.
Changes from v3 are:
* It wasn't nice to break DT compatibility by adding a second resource requirement, so we provided a fallback to use the RSTOUT address. All in all, the solution doesn't look too bad.
* Added a full watchdog stop at driver probe time, *before* the call to request_irq().
Notice that currently the request_irq() doesn't seem to clear the pending interrupt. This means the BRIDGE_CAUSE clear removal is still not safe.
This should be fixed sooner than later and, of course, before this gets merged.
* Rework the interrupt request, to use devm_request_irq() and avoid dealing with IRQ releasing.
* Added proper clock error handling and fixed the probe() error path.
* Typos and minor issues got fixed
Changes from v2:
* Add proper error checking on clk_prepare_enable() and return PTR_ERR instead of ENODEV. Suggested by Fabio Estevam.
* After the usage of the atomic I/O and considering the watchdog core does its own serialization, the driver's spinlock was completely redundant and was removed. Also suggested by Fabio.
* Instead of making the driver dependent on PLAT_ORION, added a dependency to ARCH_MVEBU. This was proposed by Sebastian and Andrew, given we're working on PLAT_ORION removal.
Changes from v1:
* Watchdog RSTOUT enable.
While v1 enabled the RSTOUT at each machine initialization, Jason Gunthorpe later pointed out [2] that such enabling might lead to a spurious watchdog trigger, in the event of the watchdog expired event not being cleared.
Therefore, the current patchset adds RSTOUT as a second address resource (or 'reg' entry in devicetree words) to allow different platforms specify the corresponding address of the register. This change allows to build the driver on multiplatforms builds as helps remove a mach-specific header.
The drawback of this is that the DT backwards compatibility gets broken; this was timely discussed but no better solution was achieved or proposed.
* BRIDGE CAUSE clear removal
The watchdog cause clear should be done by the bridge irqchip driver, so it's fine to remove it from the watchdog driver and instead request the interrupt.
However, there are still a few platforms (orion5x, and legacy kirkwood/dove) that doesn't have this bridge irqchip support enabled. On these platforms the bridge cause clear is simply *not* done.
If we are paranoid about this, maybe we can simply add the clear on each mach-xxx/irq.c, together with the other irq is initialization.
Once again, thanks to everyone who helped reviewing this.
Ezequiel Garcia (20):
ARM: Introduce atomic MMIO modify
clocksource: orion: Use atomic access for shared registers
watchdog: orion: Add clock error handling
watchdog: orion: Use atomic access for shared registers
watchdog: orion: Remove unused macros
watchdog: orion: Make sure the watchdog is initially stopped
watchdog: orion: Handle the interrupt so it's properly acked
watchdog: orion: Make RSTOUT register a separate resource
watchdog: orion: Remove unneeded BRIDGE_CAUSE clear
watchdog: orion: Introduce an orion_watchdog device structure
watchdog: orion: Introduce per-compatible of_device_id data
watchdog: orion: Add per-compatible clock initialization
watchdog: orion: Add per-compatible watchdog start implementation
watchdog: orion: Add support for Armada 370 and Armada XP SoC
ARM: mvebu: Enable Armada 370/XP watchdog in the devicetree
ARM: kirkwood: Add RSTOUT 'reg' entry to devicetree
ARM: dove: Enable Dove watchdog in the devicetree
watchdog: orion: Enable the build on ARCH_MVEBU
ARM: mvebu: Enable watchdog support in defconfig
ARM: dove: Enable watchdog support in the defconfig
.../devicetree/bindings/watchdog/marvel.txt | 8 +- arch/arm/boot/dts/armada-370-xp.dtsi | 4 + arch/arm/boot/dts/armada-370.dtsi | 5 + arch/arm/boot/dts/armada-xp.dtsi | 6 + arch/arm/boot/dts/dove.dtsi | 8 + arch/arm/boot/dts/kirkwood.dtsi | 2 +- arch/arm/configs/dove_defconfig | 2 + arch/arm/configs/mvebu_defconfig | 2 + arch/arm/include/asm/io.h | 6 + arch/arm/kernel/io.c | 35 ++ arch/arm/mach-dove/include/mach/bridge-regs.h | 1 + arch/arm/mach-kirkwood/include/mach/bridge-regs.h | 1 + arch/arm/mach-mv78xx0/include/mach/bridge-regs.h | 1 + arch/arm/mach-orion5x/include/mach/bridge-regs.h | 1 + arch/arm/plat-orion/common.c | 10 +- drivers/clocksource/time-orion.c | 28 +- drivers/watchdog/Kconfig | 2 +- drivers/watchdog/orion_wdt.c | 369 ++++++++++++++++----- 18 files changed, 383 insertions(+), 108 deletions(-)
Signature · 1 line
1.8.1.5
PATCH v5 1/20 ARM: Introduce atomic MMIO modify
Some SoC have MMIO regions that are shared across orthogonal subsystems. This commit implements a possible solution for the thread-safe access of such regions through a spinlock-protected API.
Concurrent access is protected with a single spinlock for the entire MMIO address space. While this protects shared-registers, it also serializes access to unrelated/unshared registers.
We add relaxed and non-relaxed variants, by using writel_relaxed and writel, respectively. The rationale for this is that some users may not require register write completion but only thread-safe access to a register.
---
Russell,
Can you confirm this patch is on its way to v3.14?
arch/arm/include/asm/io.h | 6 ++++++ arch/arm/kernel/io.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+)
arch/arm/include/asm/io.h +6 -0
@@ -38,6 +38,12 @@#define isa_bus_to_virt phys_to_virt/* +* Atomic MMIO-wide IO modify +*/ +extern void atomic_io_modify (void __iomem *reg,u32 mask,u32 set); +extern void atomic_io_modify_relaxed (void __iomem *reg,u32 mask,u32 set); + +/* * Generic IO read/write. These perform native-endian accesses. Note * that some architectures will want to re-define __raw_{read,write}w. */
arch/arm/kernel/io.c +35 -0
@@ -1,6 +1,41 @@#include <linux/export.h> #include <linux/types.h> #include <linux/io.h> +#include <linux/spinlock.h> + +static DEFINE_RAW_SPINLOCK (__io_lock); + +/* +* Generic atomic MMIO modify. +* +* Allows thread-safe access to registers shared by unrelated subsystems. +* The access is protected by a single MMIO-wide lock. +*/ +void atomic_io_modify_relaxed (void __iomem *reg,u32 mask,u32 set) +{ +unsigned long flags; +u32 value; + +raw_spin_lock_irqsave (&__io_lock, flags); + value =readl_relaxed (reg) & ~mask; + value |= (set & mask); +writel_relaxed (value, reg); +raw_spin_unlock_irqrestore (&__io_lock, flags); +} +EXPORT_SYMBOL (atomic_io_modify_relaxed); + +void atomic_io_modify (void __iomem *reg,u32 mask,u32 set) +{ +unsigned long flags; +u32 value; + +raw_spin_lock_irqsave (&__io_lock, flags); + value =readl_relaxed (reg) & ~mask; + value |= (set & mask); +writel (value, reg); +raw_spin_unlock_irqrestore (&__io_lock, flags); +} +EXPORT_SYMBOL (atomic_io_modify);/* * Copy data from IO memory space to "real" memory space.
Signature · 1 line
1.8.1.5
PATCH v5 1/20 ARM: Introduce atomic MMIO modify
Quoted 12 lines · Ezequiel Garcia
Some SoC have MMIO regions that are shared across orthogonal subsystems. This commit implements a possible solution for the thread-safe access of such regions through a spinlock-protected API.
Concurrent access is protected with a single spinlock for the entire MMIO address space. While this protects shared-registers, it also serializes access to unrelated/unshared registers.
We add relaxed and non-relaxed variants, by using
writel_relaxedand writel, respectively. The rationale for this is that some users may not require register write completion but only thread-safe access to a register.
Quoted 8 lines
Cc Russell King - ARM Linux <[email protected]>Signed-off-by Ezequiel Garcia <[email protected]>---
Russell,Can you confirm this patch is on its way to v3.14?
ping?
Signature · 3 lines
Ezequiel Garc?a, Free Electrons Embedded Linux, Kernel and Android Engineering http://free-electrons.com
PATCH v5 2/20 clocksource: orion: Use atomic access for shared registers
In reply to Ezequiel GarciaReplace the driver-specific thread-safe shared register API by the recently introduced atomic_io_clear_set().
--- drivers/clocksource/time-orion.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-)
drivers/clocksource/time-orion.c +10 -18
@@ -35,20 +35,6 @@#define ORION_ONESHOT_MAX 0xfffffffestatic void __iomem *timer_base; -static DEFINE_SPINLOCK (timer_ctrl_lock); - -/* -* Thread-safe access to TIMER_CTRL register -* (shared with watchdog timer) -*/ -void orion_timer_ctrl_clrset (u32 clr,u32 set) -{ -spin_lock (&timer_ctrl_lock); -writel ((readl (timer_base +TIMER_CTRL ) & ~clr) | set, - timer_base +TIMER_CTRL ); -spin_unlock (&timer_ctrl_lock); -} -EXPORT_SYMBOL (orion_timer_ctrl_clrset);/* * Free-running clocksource handling.
@@ -68,7 +54,8 @@ static int orion_clkevt_next_event(unsigned long delta, {/* setup and enable one-shot timer */ writel (delta, timer_base +TIMER1_VAL ); -orion_timer_ctrl_clrset (TIMER1_RELOAD_EN ,TIMER1_EN ); +atomic_io_modify (timer_base +TIMER_CTRL , +TIMER1_RELOAD_EN |TIMER1_EN ,TIMER1_EN );return 0 ; }
@@ -80,10 +67,13 @@ static void orion_clkevt_mode(enum clock_event_mode mode,/* setup and enable periodic timer at 1/HZ intervals */ writel (ticks_per_jiffy -1 , timer_base +TIMER1_RELOAD );writel (ticks_per_jiffy -1 , timer_base +TIMER1_VAL ); -orion_timer_ctrl_clrset (0 ,TIMER1_RELOAD_EN |TIMER1_EN ); +atomic_io_modify (timer_base +TIMER_CTRL , +TIMER1_RELOAD_EN |TIMER1_EN , +TIMER1_RELOAD_EN |TIMER1_EN ); }else {/* disable timer */ -orion_timer_ctrl_clrset (TIMER1_RELOAD_EN |TIMER1_EN ,0 ); +atomic_io_modify (timer_base +TIMER_CTRL , +TIMER1_RELOAD_EN |TIMER1_EN ,0 ); } }
@@ -131,7 +121,9 @@ static void __init orion_timer_init(struct device_node *np)/* setup timer0 as free-running clocksource */ writel (~0 , timer_base +TIMER0_VAL );writel (~0 , timer_base +TIMER0_RELOAD ); -orion_timer_ctrl_clrset (0 ,TIMER0_RELOAD_EN |TIMER0_EN ); +atomic_io_modify (timer_base +TIMER_CTRL , +TIMER0_RELOAD_EN |TIMER0_EN , +TIMER0_RELOAD_EN |TIMER0_EN );clocksource_mmio_init (timer_base +TIMER0_VAL ,"orion_clocksource" ,clk_get_rate (clk),300 ,32 , clocksource_mmio_readl_down);
Signature · 1 line
1.8.1.5
PATCH v5 2/20 clocksource: orion: Use atomic access for shared registers
Daniel,
Quoted 9 lines · Ezequiel Garcia
Replace the driver-specific thread-safe shared register API by the recently introduced
atomic_io_clear_set().Cc Daniel Lezcano <[email protected]>Signed-off-by Ezequiel Garcia <[email protected]>--- drivers/clocksource/time-orion.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-)
The MMIO patch this depends on:
c5ca95b507c8 ARM: 7930/1: Introduce atomic MMIO modify
made it in to v3.14-rc1. It looks like this change is independent of the rest of the watchdog series, so:
thx,
Jason.
Quoted 70 lines
drivers/clocksource/time-orion.c +10
-18@@ -35,20 +35,6 @@#define ORION_ONESHOT_MAX 0xfffffffestatic void __iomem *timer_base; -static DEFINE_SPINLOCK (timer_ctrl_lock); - -/* -* Thread-safe access to TIMER_CTRL register -* (shared with watchdog timer) -*/ -void orion_timer_ctrl_clrset (u32 clr,u32 set) -{ -spin_lock (&timer_ctrl_lock); -writel ((readl (timer_base +TIMER_CTRL ) & ~clr) | set, - timer_base +TIMER_CTRL ); -spin_unlock (&timer_ctrl_lock); -} -EXPORT_SYMBOL (orion_timer_ctrl_clrset);/* * Free-running clocksource handling. @@ -68,7 +54,8 @@ static int orion_clkevt_next_event(unsigned long delta, {/* setup and enable one-shot timer */ writel (delta, timer_base +TIMER1_VAL ); -orion_timer_ctrl_clrset (TIMER1_RELOAD_EN ,TIMER1_EN ); +atomic_io_modify (timer_base +TIMER_CTRL , +TIMER1_RELOAD_EN |TIMER1_EN ,TIMER1_EN );return 0 ; }@@ -80,10 +67,13 @@ static void orion_clkevt_mode(enum clock_event_mode mode,/* setup and enable periodic timer at 1/HZ intervals */ writel (ticks_per_jiffy -1 , timer_base +TIMER1_RELOAD );writel (ticks_per_jiffy -1 , timer_base +TIMER1_VAL ); -orion_timer_ctrl_clrset (0 ,TIMER1_RELOAD_EN |TIMER1_EN ); +atomic_io_modify (timer_base +TIMER_CTRL , +TIMER1_RELOAD_EN |TIMER1_EN , +TIMER1_RELOAD_EN |TIMER1_EN ); }else {/* disable timer */ -orion_timer_ctrl_clrset (TIMER1_RELOAD_EN |TIMER1_EN ,0 ); +atomic_io_modify (timer_base +TIMER_CTRL , +TIMER1_RELOAD_EN |TIMER1_EN ,0 ); } }@@ -131,7 +121,9 @@ static void __init orion_timer_init(struct device_node *np)/* setup timer0 as free-running clocksource */ writel (~0 , timer_base +TIMER0_VAL );writel (~0 , timer_base +TIMER0_RELOAD ); -orion_timer_ctrl_clrset (0 ,TIMER0_RELOAD_EN |TIMER0_EN ); +atomic_io_modify (timer_base +TIMER_CTRL , +TIMER0_RELOAD_EN |TIMER0_EN , +TIMER0_RELOAD_EN |TIMER0_EN );clocksource_mmio_init (timer_base +TIMER0_VAL ,"orion_clocksource" ,clk_get_rate (clk),300 ,32 , clocksource_mmio_readl_down);Signature · 7 lines
1.8.1.5 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel at lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v5 2/20 clocksource: orion: Use atomic access for shared registers
Quoted 11 lines · Jason Cooper
Quoted 9 lines · Ezequiel Garcia
Replace the driver-specific thread-safe shared register API by the recently introduced
atomic_io_clear_set().Cc Daniel Lezcano <[email protected]>Signed-off-by Ezequiel Garcia <[email protected]>--- drivers/clocksource/time-orion.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-)
Quoted 9 lines
The MMIO patch this depends on:
c5ca95b507c8ARM: 7930/1: Introduce atomic MMIO modifymade it in to v3.14-rc1. It looks like this change is independent of the rest of the watchdog series, so:
Acked-by Jason Cooper <[email protected]>
Thanks, Jason.
Daniel: If you can pick this I'll drop it from the next watchdog patchset submission.
Signature · 3 lines
Ezequiel Garc?a, Free Electrons Embedded Linux, Kernel and Android Engineering http://free-electrons.com
PATCH v5 2/20 clocksource: orion: Use atomic access for shared registers
Quoted 19 lines · Ezequiel Garcia
Quoted 18 lines · Jason Cooper
Quoted 9 lines · Ezequiel Garcia
Replace the driver-specific thread-safe shared register API by the recently introduced
atomic_io_clear_set().Cc Daniel Lezcano <[email protected]>Signed-off-by Ezequiel Garcia <[email protected]>--- drivers/clocksource/time-orion.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-)The MMIO patch this depends on:
c5ca95b507c8ARM: 7930/1: Introduce atomic MMIO modifymade it in to v3.14-rc1. It looks like this change is independent of the rest of the watchdog series, so:
Quoted 7 lines
Quoted 2 lines
Acked-by Jason Cooper <[email protected]>Thanks, Jason.
Daniel: If you can pick this I'll drop it from the next watchdog patchset submission.
Yep, ok. I am out of the office for the moment, I will take care of it Monday.
Thanks
-- Daniel
Signature · 5 lines
<http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook | <http://twitter.com/#!/linaroorg> Twitter | <http://www.linaro.org/linaro-blog/> Blog
PATCH v5 3/20 watchdog: orion: Add clock error handling
In reply to Ezequiel GarciaThis commit adds a check for clk_prepare_enable success and introduces an error path to disable the clock properly.
--- drivers/watchdog/orion_wdt.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-)
drivers/watchdog/orion_wdt.c +19 -10
@@ -151,17 +151,24 @@ static int orion_wdt_probe(struct platform_device *pdev) clk =devm_clk_get (&pdev->dev,NULL );if (IS_ERR (clk)) {dev_err (&pdev->dev,"Orion Watchdog missing clock\n" ); -return -ENODEV ; +return PTR_ERR (clk); } -clk_prepare_enable (clk); + ret =clk_prepare_enable (clk); +if (ret) +return ret; wdt_tclk =clk_get_rate (clk); res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); -if (!res) -return -ENODEV ; +if (!res) { + ret = -ENODEV ; + goto disable_clk; + } + wdt_reg =devm_ioremap (&pdev->dev, res->start,resource_size (res)); -if (!wdt_reg) -return -ENOMEM ; +if (!wdt_reg) { + ret = -ENOMEM ; + goto disable_clk; + } wdt_max_duration =WDT_MAX_CYCLE_COUNT / wdt_tclk;
@@ -171,14 +178,16 @@ static int orion_wdt_probe(struct platform_device *pdev)watchdog_set_nowayout (&orion_wdt, nowayout); ret =watchdog_register_device (&orion_wdt); -if (ret) { -clk_disable_unprepare (clk); -return ret; - } +if (ret) + goto disable_clk;pr_info ("Initial timeout %d sec%s\n" , orion_wdt.timeout, nowayout ?", nowayout" :"" );return 0 ; + +disable_clk: +clk_disable_unprepare (clk); +return ret; }static int orion_wdt_remove (struct platform_device *pdev)
Signature · 1 line
1.8.1.5
PATCH v5 4/20 watchdog: orion: Use atomic access for shared registers
In reply to Ezequiel GarciaSince the timer control register is shared with the clocksource driver, use the recently introduced atomic_io_clear_set() to access such register. Given the watchdog core already provides serialization for all the watchdog ops, this commit allows to remove the spinlock entirely.
--- drivers/watchdog/orion_wdt.c | 42 +++++------------------------------------- 1 file changed, 5 insertions(+), 37 deletions(-)
drivers/watchdog/orion_wdt.c +5 -37
@@ -20,7 +20,6 @@#include <linux/watchdog.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/spinlock.h> #include <linux/clk.h> #include <linux/err.h> #include <linux/of.h>
@@ -46,25 +45,16 @@ static unsigned int wdt_max_duration; /* (seconds) */static struct clk *clk;static unsigned int wdt_tclk;static void __iomem *wdt_reg; -static DEFINE_SPINLOCK (wdt_lock);static int orion_wdt_ping (struct watchdog_device *wdt_dev) { -spin_lock (&wdt_lock); -/* Reload watchdog duration */ writel (wdt_tclk * wdt_dev->timeout, wdt_reg +WDT_VAL ); - -spin_unlock (&wdt_lock);return 0 ; }static int orion_wdt_start (struct watchdog_device *wdt_dev) { -u32 reg; - -spin_lock (&wdt_lock); -/* Set watchdog duration */ writel (wdt_tclk * wdt_dev->timeout, wdt_reg +WDT_VAL );
@@ -72,48 +62,26 @@ static int orion_wdt_start(struct watchdog_device *wdt_dev)writel (~WDT_INT_REQ ,BRIDGE_CAUSE );/* Enable watchdog timer */ - reg =readl (wdt_reg +TIMER_CTRL ); - reg |=WDT_EN ; -writel (reg, wdt_reg +TIMER_CTRL ); +atomic_io_modify (wdt_reg +TIMER_CTRL ,WDT_EN ,WDT_EN );/* Enable reset on watchdog */ - reg =readl (RSTOUTn_MASK); - reg |=WDT_RESET_OUT_EN ; -writel (reg, RSTOUTn_MASK); - -spin_unlock (&wdt_lock); +atomic_io_modify (RSTOUTn_MASK,WDT_RESET_OUT_EN ,WDT_RESET_OUT_EN );return 0 ; }static int orion_wdt_stop (struct watchdog_device *wdt_dev) { -u32 reg; - -spin_lock (&wdt_lock); -/* Disable reset on watchdog */ - reg =readl (RSTOUTn_MASK); - reg &= ~WDT_RESET_OUT_EN ; -writel (reg, RSTOUTn_MASK); +atomic_io_modify (RSTOUTn_MASK,WDT_RESET_OUT_EN ,0 );/* Disable watchdog timer */ - reg =readl (wdt_reg +TIMER_CTRL ); - reg &= ~WDT_EN ; -writel (reg, wdt_reg +TIMER_CTRL ); - -spin_unlock (&wdt_lock); +atomic_io_modify (wdt_reg +TIMER_CTRL ,WDT_EN ,0 );return 0 ; }static unsigned int orion_wdt_get_timeleft (struct watchdog_device *wdt_dev) { -unsigned int time_left; - -spin_lock (&wdt_lock); - time_left =readl (wdt_reg +WDT_VAL ) / wdt_tclk; -spin_unlock (&wdt_lock); - -return time_left; +return readl (wdt_reg +WDT_VAL ) / wdt_tclk; } static int orion_wdt_set_timeout(struct watchdog_device *wdt_dev,
Signature · 1 line
1.8.1.5
PATCH v5 5/20 watchdog: orion: Remove unused macros
In reply to Ezequiel GarciaThese are not used anywhere so it's safe to remove them.
--- drivers/watchdog/orion_wdt.c | 2 -- 1 file changed, 2 deletions(-)
drivers/watchdog/orion_wdt.c +0 -2
@@ -33,8 +33,6 @@#define WDT_VAL 0x0024#define WDT_MAX_CYCLE_COUNT 0xffffffff -#define WDT_IN_USE 0 -#define WDT_OK_TO_CLOSE 1#define WDT_RESET_OUT_EN BIT(1)#define WDT_INT_REQ BIT(3)
Signature · 1 line
1.8.1.5
PATCH v5 6/20 watchdog: orion: Make sure the watchdog is initially stopped
In reply to Ezequiel GarciaHaving the watchdog initially fully stopped is important to avoid any spurious watchdog triggers, in case the registers are not in its reset state.
--- drivers/watchdog/orion_wdt.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/watchdog/orion_wdt.c +3 -0
@@ -142,6 +142,9 @@ static int orion_wdt_probe(struct platform_device *pdev) orion_wdt.max_timeout = wdt_max_duration;watchdog_init_timeout (&orion_wdt, heartbeat, &pdev->dev); +/* Let's make sure the watchdog is fully stopped */ +orion_wdt_stop (&orion_wdt); +watchdog_set_nowayout (&orion_wdt, nowayout); ret =watchdog_register_device (&orion_wdt);if (ret)
Signature · 1 line
1.8.1.5
PATCH v5 7/20 watchdog: orion: Handle the interrupt so it's properly acked
In reply to Ezequiel GarciaDT-enabled plaforms, where the irqchip driver for the brigde interrupt controller is available, can handle the watchdog IRQ properly. Therefore, request the interrupt and add a dummy handler that merely calls panic().
This is done in order to have an initial 'ack' of the interruption, which clears the watchdog state.
Furthermore, since some platforms don't have such IRQ, this commit makes the interrupt specification optional.
---
Depends on the following irqchip-orion fix (not yet merged):
https://lkml.org/lkml/2014/1/23/594
.../devicetree/bindings/watchdog/marvel.txt | 2 ++ drivers/watchdog/orion_wdt.c | 24 +++++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/watchdog/marvel.txt +2 -0
@@ -7,6 +7,7 @@ Required Properties: Optional properties: +- interrupts : Contains the IRQ for watchdog expiration - timeout-sec : Contains the watchdog timeout in seconds Example:
@@ -14,6 +15,7 @@ Example: wdt at 20300 { compatible = "marvell,orion-wdt"; reg = <0x20300 0x28>; + interrupts = <3>; timeout-sec = <10>; status = "okay"; };
drivers/watchdog/orion_wdt.c +23 -1
@@ -19,6 +19,7 @@#include <linux/platform_device.h> #include <linux/watchdog.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/io.h> #include <linux/clk.h> #include <linux/err.h>
@@ -109,10 +110,16 @@ static struct watchdog_device orion_wdt = { .min_timeout = 1, }; +static irqreturn_t orion_wdt_irq (int irq,void *devid) +{ +panic ("Watchdog Timeout" ); +return IRQ_HANDLED ; +} +static int orion_wdt_probe (struct platform_device *pdev) {struct resource *res; -int ret; +int ret, irq; clk =devm_clk_get (&pdev->dev,NULL );if (IS_ERR (clk)) {
@@ -145,6 +152,21 @@ static int orion_wdt_probe(struct platform_device *pdev)/* Let's make sure the watchdog is fully stopped */ orion_wdt_stop (&orion_wdt); +/* The IRQ request must be done only after the watchdog is disabled */ + irq =platform_get_irq (pdev,0 ); +if (irq >0 ) { +/* +* Not all supported platforms specify an interrupt for the +* watchdog, so let's make it optional. +*/ + ret =devm_request_irq (&pdev->dev, irq, orion_wdt_irq,0 , + pdev->name, &orion_wdt); +if (ret <0 ) { +dev_err (&pdev->dev,"failed to request IRQ\n" ); + goto disable_clk; + } + } +watchdog_set_nowayout (&orion_wdt, nowayout); ret =watchdog_register_device (&orion_wdt);if (ret)
Signature · 1 line
1.8.1.5
PATCH v5 8/20 watchdog: orion: Make RSTOUT register a separate resource
In reply to Ezequiel GarciaIn order to support other SoC, it's required to distinguish the 'control' timer register, from the 'rstout' register that enables system reset on watchdog expiration.
To prevent a compatibility break, this commit adds a fallback to a hardcoded RSTOUT address.
--- .../devicetree/bindings/watchdog/marvel.txt | 6 ++- arch/arm/mach-dove/include/mach/bridge-regs.h | 1 + arch/arm/mach-kirkwood/include/mach/bridge-regs.h | 1 + arch/arm/mach-mv78xx0/include/mach/bridge-regs.h | 1 + arch/arm/mach-orion5x/include/mach/bridge-regs.h | 1 + arch/arm/plat-orion/common.c | 10 +++-- drivers/watchdog/orion_wdt.c | 45 +++++++++++++++++++++- 7 files changed, 57 insertions(+), 8 deletions(-)
Documentation/devicetree/bindings/watchdog/marvel.txt +4 -2
@@ -3,7 +3,9 @@ Required Properties: - Compatibility : "marvell,orion-wdt" -- reg : Address of the timer registers +- reg : Should contain two entries: first one with the + timer control address, second one with the + rstout enable address. Optional properties:
@@ -14,7 +16,7 @@ Example: wdt at 20300 { compatible = "marvell,orion-wdt"; - reg = <0x20300 0x28>; + reg = <0x20300 0x28>, <0x20108 0x4>; interrupts = <3>; timeout-sec = <10>; status = "okay";
arch/arm/mach-dove/include/mach/bridge-regs.h +1 -0
@@ -21,6 +21,7 @@#define CPU_CTRL_PCIE1_LINK 0x00000008#define RSTOUTn_MASK (BRIDGE_VIRT_BASE + 0x0108) +#define RSTOUTn_MASK_PHYS (BRIDGE_PHYS_BASE + 0x0108)#define SOFT_RESET_OUT_EN 0x00000004#define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE + 0x010c)
arch/arm/mach-kirkwood/include/mach/bridge-regs.h +1 -0
@@ -21,6 +21,7 @@#define CPU_RESET 0x00000002#define RSTOUTn_MASK (BRIDGE_VIRT_BASE + 0x0108) +#define RSTOUTn_MASK_PHYS (BRIDGE_PHYS_BASE + 0x0108)#define SOFT_RESET_OUT_EN 0x00000004#define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE + 0x010c)
arch/arm/mach-mv78xx0/include/mach/bridge-regs.h +1 -0
@@ -15,6 +15,7 @@#define L2_WRITETHROUGH 0x00020000#define RSTOUTn_MASK (BRIDGE_VIRT_BASE + 0x0108) +#define RSTOUTn_MASK_PHYS (BRIDGE_PHYS_BASE + 0x0108)#define SOFT_RESET_OUT_EN 0x00000004#define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE + 0x010c)
arch/arm/mach-orion5x/include/mach/bridge-regs.h +1 -0
@@ -18,6 +18,7 @@#define CPU_CTRL (ORION5X_BRIDGE_VIRT_BASE + 0x104)#define RSTOUTn_MASK (ORION5X_BRIDGE_VIRT_BASE + 0x108) +#define RSTOUTn_MASK_PHYS (ORION5X_BRIDGE_PHYS_BASE + 0x108)#define CPU_SOFT_RESET (ORION5X_BRIDGE_VIRT_BASE + 0x10c)
arch/arm/plat-orion/common.c +6 -4
@@ -594,14 +594,16 @@ void __init orion_spi_1_init(unsigned long mapbase)/***************************************************************************** * Watchdog ****************************************************************************/ -static struct resource orion_wdt_resource = -DEFINE_RES_MEM (TIMER_PHYS_BASE ,0x28 ); +static struct resource orion_wdt_resource[] = { +DEFINE_RES_MEM (TIMER_PHYS_BASE ,0x04 ), +DEFINE_RES_MEM (RSTOUTn_MASK_PHYS,0x04 ), +};static struct platform_device orion_wdt_device = { .name ="orion_wdt" , .id =-1 , - .num_resources =1 , - .resource = &orion_wdt_resource, + .num_resources =ARRAY_SIZE (orion_wdt_resource), + .resource = orion_wdt_resource, };void __init orion_wdt_init (void )
drivers/watchdog/orion_wdt.c +43 -2
81 lines not on this page · raw message
Signature · 1 line
1.8.1.5
PATCH v5 9/20 watchdog: orion: Remove unneeded BRIDGE_CAUSE clear
In reply to Ezequiel GarciaAfter adding the IRQ request, the BRIDGE_CAUSE bit should be cleared by the bridge interrupt controller. There's no longer a need to do it in the watchdog driver, so we can simply remove it.
--- drivers/watchdog/orion_wdt.c | 5 ----- 1 file changed, 5 deletions(-)
drivers/watchdog/orion_wdt.c +0 -5
@@ -24,7 +24,6 @@#include <linux/clk.h> #include <linux/err.h> #include <linux/of.h> -#include <mach/bridge-regs.h> /* RSTOUT mask register physical address for Orion5x, Kirkwood and Dove */ #define ORION_RSTOUT_MASK_OFFSET 0x20108
@@ -42,7 +41,6 @@#define WDT_MAX_CYCLE_COUNT 0xffffffff#define WDT_RESET_OUT_EN BIT(1) -#define WDT_INT_REQ BIT(3)static bool nowayout =WATCHDOG_NOWAYOUT ;static int heartbeat =-1 ;/* module parameter (seconds) */
@@ -64,9 +62,6 @@ static int orion_wdt_start(struct watchdog_device *wdt_dev)/* Set watchdog duration */ writel (wdt_tclk * wdt_dev->timeout, wdt_reg +WDT_VAL ); -/* Clear watchdog timer interrupt */ -writel (~WDT_INT_REQ ,BRIDGE_CAUSE ); -/* Enable watchdog timer */ atomic_io_modify (wdt_reg +TIMER_CTRL ,WDT_EN ,WDT_EN );
Signature · 1 line
1.8.1.5
PATCH v5 10/20 watchdog: orion: Introduce an orion_watchdog device structure
In reply to Ezequiel GarciaIn order to prepare to support multiple compatible-strings, this commit adds a device structure to hold the driver's state.
--- drivers/watchdog/orion_wdt.c | 106 ++++++++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 41 deletions(-)
drivers/watchdog/orion_wdt.c +65 -41
@@ -44,45 +44,56 @@static bool nowayout =WATCHDOG_NOWAYOUT ;static int heartbeat =-1 ;/* module parameter (seconds) */ -static unsigned int wdt_max_duration;/* (seconds) */ -static struct clk *clk; -static unsigned int wdt_tclk; -static void __iomem *wdt_reg; -static void __iomem *wdt_rstout; + +struct orion_watchdog { +struct watchdog_device wdt; +void __iomem *reg; +void __iomem *rstout; +unsigned long clk_rate; +struct clk *clk; +};static int orion_wdt_ping (struct watchdog_device *wdt_dev) { +struct orion_watchdog *dev =watchdog_get_drvdata (wdt_dev);/* Reload watchdog duration */ -writel (wdt_tclk * wdt_dev->timeout, wdt_reg +WDT_VAL ); +writel (dev->clk_rate * wdt_dev->timeout, dev->reg +WDT_VAL );return 0 ; }static int orion_wdt_start (struct watchdog_device *wdt_dev) { +struct orion_watchdog *dev =watchdog_get_drvdata (wdt_dev); +/* Set watchdog duration */ -writel (wdt_tclk * wdt_dev->timeout, wdt_reg +WDT_VAL ); +writel (dev->clk_rate * wdt_dev->timeout, dev->reg +WDT_VAL );/* Enable watchdog timer */ -atomic_io_modify (wdt_reg +TIMER_CTRL ,WDT_EN ,WDT_EN ); +atomic_io_modify (dev->reg +TIMER_CTRL ,WDT_EN ,WDT_EN );/* Enable reset on watchdog */ -atomic_io_modify (wdt_rstout,WDT_RESET_OUT_EN ,WDT_RESET_OUT_EN ); +atomic_io_modify (dev->rstout,WDT_RESET_OUT_EN ,WDT_RESET_OUT_EN ); +return 0 ; }static int orion_wdt_stop (struct watchdog_device *wdt_dev) { +struct orion_watchdog *dev =watchdog_get_drvdata (wdt_dev); +/* Disable reset on watchdog */ -atomic_io_modify (wdt_rstout,WDT_RESET_OUT_EN ,0 ); +atomic_io_modify (dev->rstout,WDT_RESET_OUT_EN ,0 );/* Disable watchdog timer */ -atomic_io_modify (wdt_reg +TIMER_CTRL ,WDT_EN ,0 ); +atomic_io_modify (dev->reg +TIMER_CTRL ,WDT_EN ,0 ); +return 0 ; }static unsigned int orion_wdt_get_timeleft (struct watchdog_device *wdt_dev) { -return readl (wdt_reg +WDT_VAL ) / wdt_tclk; +struct orion_watchdog *dev =watchdog_get_drvdata (wdt_dev); +return readl (dev->reg +WDT_VAL ) / dev->clk_rate; } static int orion_wdt_set_timeout(struct watchdog_device *wdt_dev,
@@ -106,12 +117,6 @@ static const struct watchdog_ops orion_wdt_ops = { .get_timeleft = orion_wdt_get_timeleft, }; -static struct watchdog_device orion_wdt = { - .info = &orion_wdt_info, - .ops = &orion_wdt_ops, - .min_timeout =1 , -}; -static irqreturn_t orion_wdt_irq (int irq,void *devid) {panic ("Watchdog Timeout" );
@@ -147,18 +152,29 @@ static void __iomem *orion_wdt_ioremap_rstout(struct platform_device *pdev,static int orion_wdt_probe (struct platform_device *pdev) { +struct orion_watchdog *dev; +unsigned int wdt_max_duration;/* (seconds) */ struct resource *res;int ret, irq; - clk =devm_clk_get (&pdev->dev,NULL ); -if (IS_ERR (clk)) { + dev =devm_kzalloc (&pdev->dev,sizeof (struct orion_watchdog ), +GFP_KERNEL ); +if (!dev) +return -ENOMEM ; + + dev->wdt.info = &orion_wdt_info; + dev->wdt.ops = &orion_wdt_ops; + dev->wdt.min_timeout =1 ; + + dev->clk =devm_clk_get (&pdev->dev,NULL ); +if (IS_ERR (dev->clk)) {dev_err (&pdev->dev,"Orion Watchdog missing clock\n" ); -return PTR_ERR (clk); +return PTR_ERR (dev->clk); } - ret =clk_prepare_enable (clk); + ret =clk_prepare_enable (dev->clk);if (ret)return ret; - wdt_tclk =clk_get_rate (clk); + dev->clk_rate =clk_get_rate (dev->clk); res =platform_get_resource (pdev,IORESOURCE_MEM ,0 );if (!res) {
@@ -166,27 +182,31 @@ static int orion_wdt_probe(struct platform_device *pdev) goto disable_clk; } - wdt_reg =devm_ioremap (&pdev->dev, res->start,resource_size (res)); -if (!wdt_reg) { + dev->reg =devm_ioremap (&pdev->dev, res->start, +resource_size (res)); +if (!dev->reg) { ret = -ENOMEM ; goto disable_clk; } - wdt_rstout =orion_wdt_ioremap_rstout (pdev, res->start & -INTERNAL_REGS_MASK ); -if (!wdt_rstout) { + dev->rstout =orion_wdt_ioremap_rstout (pdev, res->start & +INTERNAL_REGS_MASK ); +if (!dev->rstout) { ret = -ENODEV ; goto disable_clk; } - wdt_max_duration =WDT_MAX_CYCLE_COUNT / wdt_tclk; + wdt_max_duration =WDT_MAX_CYCLE_COUNT / dev->clk_rate; + + dev->wdt.timeout = wdt_max_duration; + dev->wdt.max_timeout = wdt_max_duration; +watchdog_init_timeout (&dev->wdt, heartbeat, &pdev->dev); - orion_wdt.timeout = wdt_max_duration; - orion_wdt.max_timeout = wdt_max_duration; -watchdog_init_timeout (&orion_wdt, heartbeat, &pdev->dev); +platform_set_drvdata (pdev, &dev->wdt); +watchdog_set_drvdata (&dev->wdt, dev);/* Let's make sure the watchdog is fully stopped */ -orion_wdt_stop (&orion_wdt); +orion_wdt_stop (&dev->wdt);/* It's important to request the IRQ only after the watchdog is disabled */ irq =platform_get_irq (pdev,0 );
@@ -196,37 +216,41 @@ static int orion_wdt_probe(struct platform_device *pdev)* watchdog, so let's make it optional. */ ret =devm_request_irq (&pdev->dev, irq, orion_wdt_irq,0 , - pdev->name, &orion_wdt); + pdev->name, dev);if (ret <0 ) {dev_err (&pdev->dev,"failed to request IRQ\n" ); goto disable_clk; } } -watchdog_set_nowayout (&orion_wdt, nowayout); - ret =watchdog_register_device (&orion_wdt); +watchdog_set_nowayout (&dev->wdt, nowayout); + ret =watchdog_register_device (&dev->wdt);if (ret) goto disable_clk;pr_info ("Initial timeout %d sec%s\n" , - orion_wdt.timeout, nowayout ?", nowayout" :"" ); + dev->wdt.timeout, nowayout ?", nowayout" :"" );return 0 ; disable_clk: -clk_disable_unprepare (clk); +clk_disable_unprepare (dev->clk);return ret; }static int orion_wdt_remove (struct platform_device *pdev) { -watchdog_unregister_device (&orion_wdt); -clk_disable_unprepare (clk); +struct watchdog_device *wdt_dev =platform_get_drvdata (pdev); +struct orion_watchdog *dev =watchdog_get_drvdata (wdt_dev); + +watchdog_unregister_device (wdt_dev); +clk_disable_unprepare (dev->clk);return 0 ; }static void orion_wdt_shutdown (struct platform_device *pdev) { -orion_wdt_stop (&orion_wdt); +struct watchdog_device *wdt_dev =platform_get_drvdata (pdev); +orion_wdt_stop (wdt_dev); }static const struct of_device_id orion_wdt_of_match_table[] = {
Signature · 1 line
1.8.1.5
PATCH v5 11/20 watchdog: orion: Introduce per-compatible of_device_id data
In reply to Ezequiel GarciaThis commit adds an orion_watchdog_data structure to hold compatible-data information. This allows to remove the driver-wide definition and to be able to add support for multiple compatible-strings in the future.
--- drivers/watchdog/orion_wdt.c | 58 +++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 17 deletions(-)
drivers/watchdog/orion_wdt.c +41 -17
@@ -24,6 +24,7 @@#include <linux/clk.h> #include <linux/err.h> #include <linux/of.h> +#include <linux/of_device.h> /* RSTOUT mask register physical address for Orion5x, Kirkwood and Dove */ #define ORION_RSTOUT_MASK_OFFSET 0x20108
@@ -35,29 +36,33 @@* Watchdog timer block registers. */ #define TIMER_CTRL 0x0000 -#define WDT_EN 0x0010 -#define WDT_VAL 0x0024#define WDT_MAX_CYCLE_COUNT 0xffffffff -#define WDT_RESET_OUT_EN BIT(1) -static bool nowayout =WATCHDOG_NOWAYOUT ;static int heartbeat =-1 ;/* module parameter (seconds) */ +struct orion_watchdog_data { +int wdt_counter_offset; +int wdt_enable_bit; +int rstout_enable_bit; +}; +struct orion_watchdog {struct watchdog_device wdt;void __iomem *reg;void __iomem *rstout;unsigned long clk_rate;struct clk *clk; +const struct orion_watchdog_data *data; };static int orion_wdt_ping (struct watchdog_device *wdt_dev) {struct orion_watchdog *dev =watchdog_get_drvdata (wdt_dev);/* Reload watchdog duration */ -writel (dev->clk_rate * wdt_dev->timeout, dev->reg +WDT_VAL ); +writel (dev->clk_rate * wdt_dev->timeout, + dev->reg + dev->data->wdt_counter_offset);return 0 ; }
@@ -66,13 +71,16 @@ static int orion_wdt_start(struct watchdog_device *wdt_dev)struct orion_watchdog *dev =watchdog_get_drvdata (wdt_dev);/* Set watchdog duration */ -writel (dev->clk_rate * wdt_dev->timeout, dev->reg +WDT_VAL ); +writel (dev->clk_rate * wdt_dev->timeout, + dev->reg + dev->data->wdt_counter_offset);/* Enable watchdog timer */ -atomic_io_modify (dev->reg +TIMER_CTRL ,WDT_EN ,WDT_EN ); +atomic_io_modify (dev->reg +TIMER_CTRL , dev->data->wdt_enable_bit, + dev->data->wdt_enable_bit);/* Enable reset on watchdog */ -atomic_io_modify (dev->rstout,WDT_RESET_OUT_EN ,WDT_RESET_OUT_EN ); +atomic_io_modify (dev->rstout, dev->data->rstout_enable_bit, + dev->data->rstout_enable_bit);return 0 ; }
@@ -82,10 +90,10 @@ static int orion_wdt_stop(struct watchdog_device *wdt_dev)struct orion_watchdog *dev =watchdog_get_drvdata (wdt_dev);/* Disable reset on watchdog */ -atomic_io_modify (dev->rstout,WDT_RESET_OUT_EN ,0 ); +atomic_io_modify (dev->rstout, dev->data->rstout_enable_bit,0 );/* Disable watchdog timer */ -atomic_io_modify (dev->reg +TIMER_CTRL ,WDT_EN ,0 ); +atomic_io_modify (dev->reg +TIMER_CTRL , dev->data->wdt_enable_bit,0 );return 0 ; }
@@ -93,7 +101,7 @@ static int orion_wdt_stop(struct watchdog_device *wdt_dev)static unsigned int orion_wdt_get_timeleft (struct watchdog_device *wdt_dev) {struct orion_watchdog *dev =watchdog_get_drvdata (wdt_dev); -return readl (dev->reg +WDT_VAL ) / dev->clk_rate; +return readl (dev->reg + dev->data->wdt_counter_offset) / dev->clk_rate; } static int orion_wdt_set_timeout(struct watchdog_device *wdt_dev,
@@ -150,9 +158,25 @@ static void __iomem *orion_wdt_ioremap_rstout(struct platform_device *pdev,return devm_ioremap (&pdev->dev, rstout,0x4 ); } +static const struct orion_watchdog_data orion_data = { + .rstout_enable_bit =BIT (1 ), + .wdt_enable_bit =BIT (4 ), + .wdt_counter_offset =0x24 , +}; + +static const struct of_device_id orion_wdt_of_match_table[] = { + { + .compatible ="marvell,orion-wdt" , + .data = &orion_data, + }, + {}, +}; +MODULE_DEVICE_TABLE (of, orion_wdt_of_match_table); +static int orion_wdt_probe (struct platform_device *pdev) {struct orion_watchdog *dev; +const struct of_device_id *match;unsigned int wdt_max_duration;/* (seconds) */ struct resource *res;int ret, irq;
@@ -162,9 +186,15 @@ static int orion_wdt_probe(struct platform_device *pdev)if (!dev)return -ENOMEM ; + match =of_match_device (orion_wdt_of_match_table, &pdev->dev); +if (!match) +/* Default legacy match */ + match = &orion_wdt_of_match_table[0 ]; + dev->wdt.info = &orion_wdt_info; dev->wdt.ops = &orion_wdt_ops; dev->wdt.min_timeout =1 ; + dev->data = match->data; dev->clk =devm_clk_get (&pdev->dev,NULL );if (IS_ERR (dev->clk)) {
@@ -253,12 +283,6 @@ static void orion_wdt_shutdown(struct platform_device *pdev)orion_wdt_stop (wdt_dev); } -static const struct of_device_id orion_wdt_of_match_table[] = { - { .compatible ="marvell,orion-wdt" , }, - {}, -}; -MODULE_DEVICE_TABLE (of, orion_wdt_of_match_table); -static struct platform_driver orion_wdt_driver = { .probe = orion_wdt_probe, .remove = orion_wdt_remove,
Signature · 1 line
1.8.1.5
PATCH v5 12/20 watchdog: orion: Add per-compatible clock initialization
In reply to Ezequiel GarciaFollowing the introduction of the compatible-data field, it's now possible to further abstract the clock initialization. This will allow to support SoC with a different clock setup.
--- drivers/watchdog/orion_wdt.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-)
drivers/watchdog/orion_wdt.c +27 -10
@@ -42,10 +42,14 @@static bool nowayout =WATCHDOG_NOWAYOUT ;static int heartbeat =-1 ;/* module parameter (seconds) */ +struct orion_watchdog ; +struct orion_watchdog_data {int wdt_counter_offset;int wdt_enable_bit;int rstout_enable_bit; +int (*clock_init) (struct platform_device *, +struct orion_watchdog *); };struct orion_watchdog {
@@ -57,6 +61,22 @@ struct orion_watchdog {const struct orion_watchdog_data *data; }; +static int orion_wdt_clock_init (struct platform_device *pdev, +struct orion_watchdog *dev) +{ +int ret; + + dev->clk =devm_clk_get (&pdev->dev,NULL ); +if (IS_ERR (dev->clk)) +return PTR_ERR (dev->clk); + ret =clk_prepare_enable (dev->clk); +if (ret) +return ret; + + dev->clk_rate =clk_get_rate (dev->clk); +return 0 ; +} +static int orion_wdt_ping (struct watchdog_device *wdt_dev) {struct orion_watchdog *dev =watchdog_get_drvdata (wdt_dev);
@@ -162,6 +182,7 @@ static const struct orion_watchdog_data orion_data = { .rstout_enable_bit = BIT(1), .wdt_enable_bit = BIT(4), .wdt_counter_offset = 0x24, + .clock_init = orion_wdt_clock_init, };static const struct of_device_id orion_wdt_of_match_table[] = {
@@ -196,16 +217,6 @@ static int orion_wdt_probe(struct platform_device *pdev) dev->wdt.min_timeout =1 ; dev->data = match->data; - dev->clk =devm_clk_get (&pdev->dev,NULL ); -if (IS_ERR (dev->clk)) { -dev_err (&pdev->dev,"Orion Watchdog missing clock\n" ); -return PTR_ERR (dev->clk); - } - ret =clk_prepare_enable (dev->clk); -if (ret) -return ret; - dev->clk_rate =clk_get_rate (dev->clk); - res =platform_get_resource (pdev,IORESOURCE_MEM ,0 );if (!res) { ret = -ENODEV ;
@@ -226,6 +237,12 @@ static int orion_wdt_probe(struct platform_device *pdev) goto disable_clk; } + ret = dev->data->clock_init (pdev, dev); +if (ret) { +dev_err (&pdev->dev,"cannot initialize clock\n" ); +return ret; + } + wdt_max_duration =WDT_MAX_CYCLE_COUNT / dev->clk_rate; dev->wdt.timeout = wdt_max_duration;
Signature · 1 line
1.8.1.5
PATCH v5 13/20 watchdog: orion: Add per-compatible watchdog start implementation
In reply to Ezequiel GarciaTo handle differences between SoCs this commit adds per-compatible string start() function for the watchdog kick-off. This is preparation work and makes no functionality changes to the current driver.
--- drivers/watchdog/orion_wdt.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/watchdog/orion_wdt.c +11 -1
@@ -50,6 +50,7 @@ struct orion_watchdog_data {int rstout_enable_bit;int (*clock_init) (struct platform_device *,struct orion_watchdog *); +int (*start) (struct watchdog_device *); };struct orion_watchdog {
@@ -86,7 +87,7 @@ static int orion_wdt_ping(struct watchdog_device *wdt_dev)return 0 ; } -static int orion_wdt_start (struct watchdog_device *wdt_dev) +static int orion_start (struct watchdog_device *wdt_dev) {struct orion_watchdog *dev =watchdog_get_drvdata (wdt_dev);
@@ -105,6 +106,14 @@ static int orion_wdt_start(struct watchdog_device *wdt_dev)return 0 ; } +static int orion_wdt_start (struct watchdog_device *wdt_dev) +{ +struct orion_watchdog *dev =watchdog_get_drvdata (wdt_dev); + +/* There are some per-SoC quirks to handle */ +return dev->data->start (wdt_dev); +} +static int orion_wdt_stop (struct watchdog_device *wdt_dev) {struct orion_watchdog *dev =watchdog_get_drvdata (wdt_dev);
@@ -183,6 +192,7 @@ static const struct orion_watchdog_data orion_data = { .wdt_enable_bit = BIT(4), .wdt_counter_offset = 0x24, .clock_init = orion_wdt_clock_init, + .start = orion_start, };static const struct of_device_id orion_wdt_of_match_table[] = {
Signature · 1 line
1.8.1.5
PATCH v5 14/20 watchdog: orion: Add support for Armada 370 and Armada XP SoC
In reply to Ezequiel GarciaUsing the added infrastructure for handling SoC differences, this commit adds support for the watchdog controller available in Armada 370 and Armada XP SoCs.
--- drivers/watchdog/orion_wdt.c | 94 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+)
drivers/watchdog/orion_wdt.c +94 -0
@@ -36,9 +36,17 @@* Watchdog timer block registers. */ #define TIMER_CTRL 0x0000 +#define TIMER_A370_STATUS 0x04#define WDT_MAX_CYCLE_COUNT 0xffffffff +#define WDT_A370_RATIO_MASK (v) ((v) << 16) +#define WDT_A370_RATIO_SHIFT 5 +#define WDT_A370_RATIO (1 << WDT_A370_RATIO_SHIFT) + +#define WDT_AXP_FIXED_ENABLE_BIT BIT(10) +#define WDT_A370_EXPIRED BIT(31) +static bool nowayout =WATCHDOG_NOWAYOUT ;static int heartbeat =-1 ;/* module parameter (seconds) */
@@ -78,6 +86,48 @@ static int orion_wdt_clock_init(struct platform_device *pdev,return 0 ; } +static int armada370_wdt_clock_init (struct platform_device *pdev, +struct orion_watchdog *dev) +{ +int ret; + + dev->clk =devm_clk_get (&pdev->dev,NULL ); +if (IS_ERR (dev->clk)) +return PTR_ERR (dev->clk); + ret =clk_prepare_enable (dev->clk); +if (ret) +return ret; + +/* Setup watchdog input clock */ +atomic_io_modify (dev->reg +TIMER_CTRL , +WDT_A370_RATIO_MASK (WDT_A370_RATIO_SHIFT ), +WDT_A370_RATIO_MASK (WDT_A370_RATIO_SHIFT )); + + dev->clk_rate =clk_get_rate (dev->clk) /WDT_A370_RATIO ; +return 0 ; +} + +static int armadaxp_wdt_clock_init (struct platform_device *pdev, +struct orion_watchdog *dev) +{ +int ret; + + dev->clk =of_clk_get_by_name (pdev->dev.of_node,"fixed" ); +if (IS_ERR (dev->clk)) +return PTR_ERR (dev->clk); + ret =clk_prepare_enable (dev->clk); +if (ret) +return ret; + +/* Enable the fixed watchdog clock input */ +atomic_io_modify (dev->reg +TIMER_CTRL , +WDT_AXP_FIXED_ENABLE_BIT , +WDT_AXP_FIXED_ENABLE_BIT ); + + dev->clk_rate =clk_get_rate (dev->clk); +return 0 ; +} +static int orion_wdt_ping (struct watchdog_device *wdt_dev) {struct orion_watchdog *dev =watchdog_get_drvdata (wdt_dev);
@@ -87,6 +137,26 @@ static int orion_wdt_ping(struct watchdog_device *wdt_dev)return 0 ; } +static int armada370_start (struct watchdog_device *wdt_dev) +{ +struct orion_watchdog *dev =watchdog_get_drvdata (wdt_dev); + +/* Set watchdog duration */ +writel (dev->clk_rate * wdt_dev->timeout, + dev->reg + dev->data->wdt_counter_offset); + +/* Clear the watchdog expiration bit */ +atomic_io_modify (dev->reg +TIMER_A370_STATUS ,WDT_A370_EXPIRED ,0 ); + +/* Enable watchdog timer */ +atomic_io_modify (dev->reg +TIMER_CTRL , dev->data->wdt_enable_bit, + dev->data->wdt_enable_bit); + +atomic_io_modify (dev->rstout, dev->data->rstout_enable_bit, + dev->data->rstout_enable_bit); +return 0 ; +} +static int orion_start (struct watchdog_device *wdt_dev) {struct orion_watchdog *dev =watchdog_get_drvdata (wdt_dev);
@@ -195,11 +265,35 @@ static const struct orion_watchdog_data orion_data = { .start = orion_start, }; +static const struct orion_watchdog_data armada370_data = { + .rstout_enable_bit =BIT (8 ), + .wdt_enable_bit =BIT (8 ), + .wdt_counter_offset =0x34 , + .clock_init = armada370_wdt_clock_init, + .start = armada370_start, +}; + +static const struct orion_watchdog_data armadaxp_data = { + .rstout_enable_bit =BIT (8 ), + .wdt_enable_bit =BIT (8 ), + .wdt_counter_offset =0x34 , + .clock_init = armadaxp_wdt_clock_init, + .start = armada370_start, +}; +static const struct of_device_id orion_wdt_of_match_table[] = { { .compatible ="marvell,orion-wdt" , .data = &orion_data, }, + { + .compatible ="marvell,armada-370-wdt" , + .data = &armada370_data, + }, + { + .compatible ="marvell,armada-xp-wdt" , + .data = &armadaxp_data, + }, {}, };MODULE_DEVICE_TABLE (of, orion_wdt_of_match_table);
Signature · 1 line
1.8.1.5
PATCH v5 14/20 watchdog: orion: Add support for Armada 370 and Armada XP SoC
Quoted 31 lines · Ezequiel Garcia
drivers/watchdog/orion_wdt.c +31
-0+static int armada370_wdt_clock_init (struct platform_device *pdev, +struct orion_watchdog *dev) +{ +int ret; + + dev->clk =devm_clk_get (&pdev->dev,NULL ); +if (IS_ERR (dev->clk)) +return PTR_ERR (dev->clk); + ret =clk_prepare_enable (dev->clk); +if (ret) +return ret; + +/* Setup watchdog input clock */ +atomic_io_modify (dev->reg +TIMER_CTRL , +WDT_A370_RATIO_MASK (WDT_A370_RATIO_SHIFT ), +WDT_A370_RATIO_MASK (WDT_A370_RATIO_SHIFT )); + + dev->clk_rate =clk_get_rate (dev->clk) /WDT_A370_RATIO ; +return 0 ; +} + +static int armadaxp_wdt_clock_init (struct platform_device *pdev, +struct orion_watchdog *dev) +{ +int ret; + + dev->clk =of_clk_get_by_name (pdev->dev.of_node,"fixed" ); +if (IS_ERR (dev->clk)) +return PTR_ERR (dev->clk); + ret =clk_prepare_enable (dev->clk); +if (ret)
drivers/watchdog/orion_wdt.c static int orion_wdt_clock_init(struct platform_device *pdev, · line 129
Quoted 10 lines
drivers/watchdog/orion_wdt.c +10
-0+return ret; + +/* Enable the fixed watchdog clock input */ +atomic_io_modify (dev->reg +TIMER_CTRL , +WDT_AXP_FIXED_ENABLE_BIT , +WDT_AXP_FIXED_ENABLE_BIT ); + + dev->clk_rate =clk_get_rate (dev->clk); +return 0 ; +}
Doesn't this result in dev->clk being leaked? Or at least a difference in the way dev->clk needs to be cleaned up between these two functions?
I think it would be better in this case to use the standard clk_get() in the first function and always use clk_put()... until there is a devm_* version of the of_clk_get* functions.
Signature · 3 lines
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up. Estimation in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad. Estimate before purchase was "up to 13.2Mbit".
PATCH v5 14/20 watchdog: orion: Add support for Armada 370 and Armada XP SoC
On Mon, Jan 27, 2014 at 05:36:24PM +0000, Russell King - ARM Linux wrote:
[..]
Quoted 15 lines
Quoted 15 lines
drivers/watchdog/orion_wdt.c +15
-0+static int armadaxp_wdt_clock_init (struct platform_device *pdev, +struct orion_watchdog *dev) +{ +int ret; + + dev->clk =of_clk_get_by_name (pdev->dev.of_node,"fixed" ); +if (IS_ERR (dev->clk)) +return PTR_ERR (dev->clk); + ret =clk_prepare_enable (dev->clk); +if (ret) +return ret; + +/* Enable the fixed watchdog clock input */ + atomic_io_modify(dev->reg + TIMER_CTRL, + WDT_AXP_FIXED_ENABLE_BIT,
Quoted 9 lines
drivers/watchdog/orion_wdt.c static int orion_wdt_clock_init(struct platform_device *pdev, · line 129
Quoted 5 lines
drivers/watchdog/orion_wdt.c +5
-0+ WDT_AXP_FIXED_ENABLE_BIT); + + dev->clk_rate =clk_get_rate (dev->clk); +return 0 ; +}Doesn't this result in
dev->clkbeing leaked? Or at least a difference in the waydev->clkneeds to be cleaned up between these two functions?
Yes, indeed.
Quoted 4 lines
I think it would be better in this case to use the standard
clk_get()in the first function and always useclk_put()... until there is a devm_* version of the of_clk_get* functions.
Sound good.
Thanks,
Signature · 7 lines
Ezequiel García, Free Electrons Embedded Linux, Kernel and Android Engineering http://free-electrons.com -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v5 15/20 ARM: mvebu: Enable Armada 370/XP watchdog in the devicetree
In reply to Ezequiel GarciaAdd the DT nodes to enable watchdog support available in Armada 370 and Armada XP SoCs.
--- arch/arm/boot/dts/armada-370-xp.dtsi | 4 ++++ arch/arm/boot/dts/armada-370.dtsi | 5 +++++ arch/arm/boot/dts/armada-xp.dtsi | 6 ++++++ 3 files changed, 15 insertions(+)
arch/arm/boot/dts/armada-370-xp.dtsi +4 -0
@@ -151,6 +151,10 @@ interrupts = <37>, <38>, <39>, <40>, <5>, <6>; }; + watchdog at 20300 { + reg = <0x20300 0x34>, <0x20704 0x4>; + }; + sata at a0000 { compatible = "marvell,orion-sata"; reg = <0xa0000 0x5000>;
arch/arm/boot/dts/armada-370.dtsi +5 -0
@@ -168,6 +168,11 @@ clocks = <&coreclk 2>; }; + watchdog at 20300 { + compatible = "marvell,armada-370-wdt"; + clocks = <&coreclk 2>; + }; + coreclk: mvebu-sar at 18230 { compatible = "marvell,armada-370-core-clock"; reg = <0x18230 0x08>;
arch/arm/boot/dts/armada-xp.dtsi +6 -0
@@ -74,6 +74,12 @@ clock-names = "nbclk", "fixed"; }; + watchdog at 20300 { + compatible = "marvell,armada-xp-wdt"; + clocks = <&coreclk 2>, <&refclk>; + clock-names = "nbclk", "fixed"; + }; + coreclk: mvebu-sar at 18230 { compatible = "marvell,armada-xp-core-clock"; reg = <0x18230 0x08>;
Signature · 1 line
1.8.1.5
PATCH v5 16/20 ARM: kirkwood: Add RSTOUT 'reg' entry to devicetree
In reply to Ezequiel GarciaIn order to support multiplatform builds the watchdog devicetree binding was modified and now the 'reg' property is specified to need two entries. This commit adds the second entry as-per the new specification.
--- arch/arm/boot/dts/kirkwood.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/kirkwood.dtsi +1 -1
@@ -165,7 +165,7 @@ wdt: watchdog-timer at 20300 { compatible = "marvell,orion-wdt"; - reg = <0x20300 0x28>; + reg = <0x20300 0x28>, <0x20108 0x4>; interrupt-parent = <&bridge_intc>; interrupts = <3>; clocks = <&gate_clk 7>;
Signature · 1 line
1.8.1.5
Andrew Lunn
maintainerPATCH v5 16/20 ARM: kirkwood: Add RSTOUT 'reg' entry to devicetree
Quoted 6 lines · Ezequiel Garcia
In order to support multiplatform builds the watchdog devicetree binding was modified and now the 'reg' property is specified to need two entries. This commit adds the second entry as-per the new specification.
Signed-off-by Ezequiel Garcia <[email protected]>
Hi Ezequiel
I tested on Kirkwood, using the standard watchdog test cases. Works great.
Thanks
Andrew
PATCH v5 17/20 ARM: dove: Enable Dove watchdog in the devicetree
In reply to Ezequiel GarciaAdd the devicetree node to enable watchdog support available in Dove SoCs.
--- arch/arm/boot/dts/dove.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+)
arch/arm/boot/dts/dove.dtsi +8 -0
@@ -120,6 +120,14 @@ clocks = <&core_clk 0>; }; + watchdog at 20300 { + compatible = "marvell,orion-wdt"; + reg = <0x20300 0x28>, <0x20108 0x4>; + interrupt-parent = <&bridge_intc>; + interrupts = <3>; + clocks = <&core_clk 0>; + }; + intc: main-interrupt-ctrl at 20200 { compatible = "marvell,orion-intc"; interrupt-controller;
Signature · 1 line
1.8.1.5
PATCH v5 18/20 watchdog: orion: Enable the build on ARCH_MVEBU
In reply to Ezequiel GarciaAfter adding support for Armada 370/XP SoC let's enable the build on these platforms.
--- drivers/watchdog/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/watchdog/Kconfig +1 -1
@@ -282,7 +282,7 @@ config DAVINCI_WATCHDOG config ORION_WATCHDOG tristate "Orion watchdog" - depends on ARCH_ORION5X || ARCH_KIRKWOOD || ARCH_DOVE + depends on ARCH_ORION5X || ARCH_KIRKWOOD || ARCH_DOVE || ARCH_MVEBU select WATCHDOG_CORE help Say Y here if to include support for the watchdog timer
Signature · 1 line
1.8.1.5
PATCH v5 19/20 ARM: mvebu: Enable watchdog support in defconfig
In reply to Ezequiel GarciaNow that we have proper support for Armada 370/XP watchdog let's enable it in the defconfig.
--- arch/arm/configs/mvebu_defconfig | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/configs/mvebu_defconfig +2 -0
@@ -60,6 +60,8 @@ CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y CONFIG_THERMAL=y CONFIG_ARMADA_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_ORION_WATCHDOG=y CONFIG_USB_SUPPORT=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y
Signature · 1 line
1.8.1.5
PATCH v5 20/20 ARM: dove: Enable watchdog support in the defconfig
In reply to Ezequiel GarciaNow that we have watchdog support, let's add it to the defconfig.
--- arch/arm/configs/dove_defconfig | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/configs/dove_defconfig +2 -0
@@ -80,6 +80,8 @@ CONFIG_SPI_ORION=y # CONFIG_HWMON is not set CONFIG_THERMAL=y CONFIG_DOVE_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_ORION_WATCHDOG=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_EHCI_HCD=y
Signature · 1 line
1.8.1.5
v5 cover Armada 370/XP watchdog support
In reply to Ezequiel GarciaQuoted 6 lines · Ezequiel Garcia
A new round, mostly fixing some minor nitpicks.
This entire series depends on latest irqchip-orion fixes by Sebastian. Namely, this one: https://lkml.org/lkml/2014/1/23/594.
How should we handle this dependency?
Sorry, I'm short on time atm. Which specific patches now depend on his changes?
I'll be doing a topic branch for tglx for that, so it shouldn't be rocket surgery. The big unknown is the MMIO patch currently in Russell's patch tracker.
We may end up waiting for MMIO and Sebastian's changes to land, then applying this during the next cycle.
thx,
Jason.
Quoted 122 lines
Changes from v4 are:
* Provided better commit subject and commit log for patch 7:
"watchdog: orion: Handle the interrupt so it's properly acked".* Corrected the misnamed fuction
try_rstout_ioremap().* A bunch of s/interruption/interrupt fixes
* Dropped the '0' as a valid IRQ in the
platform_get_irq()check, given it should return a positive virq-space number.Changes from v3 are:
* It wasn't nice to break DT compatibility by adding a second resource requirement, so we provided a fallback to use the RSTOUT address. All in all, the solution doesn't look too bad.
* Added a full watchdog stop at driver probe time, *before* the call to
request_irq().Notice that currently the
request_irq()doesn't seem to clear the pending interrupt. This means theBRIDGE_CAUSEclear removal is still not safe.This should be fixed sooner than later and, of course, before this gets merged.
* Rework the interrupt request, to use
devm_request_irq()and avoid dealing with IRQ releasing.* Added proper clock error handling and fixed the
probe()error path.* Typos and minor issues got fixed
Changes from v2:
* Add proper error checking on
clk_prepare_enable()and returnPTR_ERRinstead of ENODEV. Suggested by Fabio Estevam.* After the usage of the atomic I/O and considering the watchdog core does its own serialization, the driver's spinlock was completely redundant and was removed. Also suggested by Fabio.
* Instead of making the driver dependent on
PLAT_ORION, added a dependency toARCH_MVEBU. This was proposed by Sebastian and Andrew, given we're working onPLAT_ORIONremoval.Changes from v1:
* Watchdog RSTOUT enable.
While v1 enabled the RSTOUT at each machine initialization, Jason Gunthorpe later pointed out [2] that such enabling might lead to a spurious watchdog trigger, in the event of the watchdog expired event not being cleared.Therefore, the current patchset adds RSTOUT as a second address resource (or 'reg' entry in devicetree words) to allow different platforms specify the corresponding address of the register. This change allows to build the driver on multiplatforms builds as helps remove a mach-specific header.
The drawback of this is that the DT backwards compatibility gets broken; this was timely discussed but no better solution was achieved or proposed.
* BRIDGE CAUSE clear removal
The watchdog cause clear should be done by the bridge irqchip driver, so it's fine to remove it from the watchdog driver and instead request the interrupt.However, there are still a few platforms (orion5x, and legacy kirkwood/dove) that doesn't have this bridge irqchip support enabled. On these platforms the bridge cause clear is simply *not* done.
If we are paranoid about this, maybe we can simply add the clear on each
mach-xxx/irq.c, together with the other irq is initialization.Once again, thanks to everyone who helped reviewing this.
Ezequiel Garcia (20):
ARM: Introduce atomic MMIO modify
clocksource: orion: Use atomic access for shared registers
watchdog: orion: Add clock error handling
watchdog: orion: Use atomic access for shared registers
watchdog: orion: Remove unused macros
watchdog: orion: Make sure the watchdog is initially stopped
watchdog: orion: Handle the interrupt so it's properly acked
watchdog: orion: Make RSTOUT register a separate resource
watchdog: orion: Remove unneededBRIDGE_CAUSEclear
watchdog: orion: Introduce anorion_watchdogdevice structure
watchdog: orion: Introduce per-compatibleof_device_iddata
watchdog: orion: Add per-compatible clock initialization
watchdog: orion: Add per-compatible watchdog start implementation
watchdog: orion: Add support for Armada 370 and Armada XP SoC
ARM: mvebu: Enable Armada 370/XP watchdog in the devicetree
ARM: kirkwood: Add RSTOUT 'reg' entry to devicetree
ARM: dove: Enable Dove watchdog in the devicetree
watchdog: orion: Enable the build onARCH_MVEBU
ARM: mvebu: Enable watchdog support in defconfig
ARM: dove: Enable watchdog support in the defconfig.../devicetree/bindings/watchdog/marvel.txt | 8 +- arch/arm/boot/dts/armada-370-xp.dtsi | 4 + arch/arm/boot/dts/armada-370.dtsi | 5 + arch/arm/boot/dts/armada-xp.dtsi | 6 + arch/arm/boot/dts/dove.dtsi | 8 + arch/arm/boot/dts/kirkwood.dtsi | 2 +- arch/arm/configs/dove_defconfig | 2 + arch/arm/configs/mvebu_defconfig | 2 + arch/arm/include/asm/io.h | 6 + arch/arm/kernel/io.c | 35 ++ arch/arm/mach-dove/include/mach/bridge-regs.h | 1 + arch/arm/mach-kirkwood/include/mach/bridge-regs.h | 1 + arch/arm/mach-mv78xx0/include/mach/bridge-regs.h | 1 + arch/arm/mach-orion5x/include/mach/bridge-regs.h | 1 + arch/arm/plat-orion/common.c | 10 +- drivers/clocksource/time-orion.c | 28 +- drivers/watchdog/Kconfig | 2 +- drivers/watchdog/orion_wdt.c | 369 ++++++++++++++++----- 18 files changed, 383 insertions(+), 108 deletions(-)Signature · 1 line
1.8.1.5
v5 cover Armada 370/XP watchdog support
In reply to Ezequiel GarciaQuoted 2 lines · Ezequiel Garcia
A new round, mostly fixing some minor nitpicks.
If anyone wants to give this a test, here's a public branch:
https://github.com/MISL-EBU-System-SW/mainline-public/tree/wdt_for_v3.14_v5
I'll be resending a new v6 adressing Russell's last comment about the clock initialization, as soon as v3.14-rc1 is out.
Go, testers, go!
Signature · 3 lines
Ezequiel Garc?a, Free Electrons Embedded Linux, Kernel and Android Engineering http://free-electrons.com
v5 cover Armada 370/XP watchdog support
Ezequiel,
Quoted 7 lines · Ezequiel Garcia
Quoted 2 lines · Ezequiel Garcia
A new round, mostly fixing some minor nitpicks.
If anyone wants to give this a test, here's a public branch:
https://github.com/MISL-EBU-System-SW/mainline-public/tree/wdt_for_v3.14_v5
I just took a quick glance at this (commit oneliners/tags) and there doesn't appear to be any dependence on Sebastian's series. Did I miss something?
Also, the MMIO patch hit mainline last night.
thx,
Jason.
v5 cover Armada 370/XP watchdog support
Quoted 7 lines · Jason Cooper
Ezequiel,
Quoted 4 lines · Ezequiel Garcia
Quoted 2 lines · Ezequiel Garcia
A new round, mostly fixing some minor nitpicks.
Quoted 8 lines
Quoted 3 lines
If anyone wants to give this a test, here's a public branch:
https://github.com/MISL-EBU-System-SW/mainline-public/tree/wdt_for_v3.14_v5
I just took a quick glance at this (commit oneliners/tags) and there doesn't appear to be any dependence on Sebastian's series. Did I miss something?
True, I've completely missed that. I pushed the branch in a rush!
Let me prepare a v6, fixing the remaining issue pointed out by Russell, and push again (together with Sebastian's irqchip fixes).
Quoted 2 lines
Also, the MMIO patch hit mainline last night.
Yup, I saw it. Thanks for the notice!
Signature · 7 lines
Ezequiel García, Free Electrons Embedded Linux, Kernel and Android Engineering http://free-electrons.com -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Sebastian Hesselbarth
maintainerv5 cover Armada 370/XP watchdog support
Quoted 17 lines · Ezequiel Garcia
Quoted 7 lines · Jason Cooper
Ezequiel,
Quoted 4 lines · Ezequiel Garcia
Quoted 2 lines · Ezequiel Garcia
A new round, mostly fixing some minor nitpicks.
Quoted 8 lines
Quoted 3 lines
If anyone wants to give this a test, here's a public branch:
https://github.com/MISL-EBU-System-SW/mainline-public/tree/wdt_for_v3.14_v5
I just took a quick glance at this (commit oneliners/tags) and there doesn't appear to be any dependence on Sebastian's series. Did I miss something?
Quoted 4 lines
True, I've completely missed that. I pushed the branch in a rush!
Let me prepare a v6, fixing the remaining issue pointed out by Russell, and push again (together with Sebastian's irqchip fixes).
Umm, no. Just directly name irqchip-orion fixes. Jason will send a PR for irqchip-fixes _with-in_ v3.14 while watchdog will go into v3.15.
Or are there any plans to get watchdog in *now*?
In any way, do not include my patches into your set.
Jason: Ezequiel's watchdog patches install an irq handler that will panic(TM) on a watchdog irq. irqchip-orion does not properly clear stale bridge irqs which could signal a watchdog irq left by bootloader (or watchdog triggering between bootloader and driver probe).
Sebastian
v5 cover Armada 370/XP watchdog support
Quoted 18 lines · Sebastian Hesselbarth
Quoted 17 lines · Ezequiel Garcia
Quoted 15 lines · Jason Cooper
Ezequiel,
Quoted 7 lines · Ezequiel Garcia
Quoted 2 lines · Ezequiel Garcia
A new round, mostly fixing some minor nitpicks.
If anyone wants to give this a test, here's a public branch:
https://github.com/MISL-EBU-System-SW/mainline-public/tree/wdt_for_v3.14_v5
I just took a quick glance at this (commit oneliners/tags) and there doesn't appear to be any dependence on Sebastian's series. Did I miss something?
Quoted 7 lines
Quoted 4 lines
True, I've completely missed that. I pushed the branch in a rush!
Let me prepare a v6, fixing the remaining issue pointed out by Russell, and push again (together with Sebastian's irqchip fixes).
Umm, no. Just directly name irqchip-orion fixes. Jason will send a PR for irqchip-fixes _with-in_ v3.14 while watchdog will go into v3.15.
Yes, but I'd like to do a topic branch for that irqchip PR. That way, we don't have to wait for them to land in an -rc. We can push the watchdog changes when they are ready, and they can be based on v3.14-rc1 with irqchip/orion-fixes (or whatever) pulled in.
Quoted 1 line
In any way, do not include my patches into your set.
Agreed. I wasn't really keen on including the MMIO patch in the series since it was already in rmk's patch tracker. Listing the deps in the coverletter is enough.
Quoted 4 lines
Jason: Ezequiel's watchdog patches install an irq handler that will panic(TM) on a watchdog irq. irqchip-orion does not properly clear stale bridge irqs which could signal a watchdog irq left by bootloader (or watchdog triggering between bootloader and driver probe).
Ok. I'll look things over and get some branches setup this weekend.
thx,
Jason.
v5 cover Armada 370/XP watchdog support
In reply to Sebastian HesselbarthQuoted 18 lines · Sebastian Hesselbarth
Quoted 17 lines · Ezequiel Garcia
Quoted 15 lines · Jason Cooper
Ezequiel,
Quoted 7 lines · Ezequiel Garcia
Quoted 2 lines · Ezequiel Garcia
A new round, mostly fixing some minor nitpicks.
If anyone wants to give this a test, here's a public branch:
https://github.com/MISL-EBU-System-SW/mainline-public/tree/wdt_for_v3.14_v5
I just took a quick glance at this (commit oneliners/tags) and there doesn't appear to be any dependence on Sebastian's series. Did I miss something?
Quoted 8 lines
Quoted 4 lines
True, I've completely missed that. I pushed the branch in a rush!
Let me prepare a v6, fixing the remaining issue pointed out by Russell, and push again (together with Sebastian's irqchip fixes).
Umm, no. Just directly name irqchip-orion fixes. Jason will send a PR for irqchip-fixes _with-in_ v3.14 while watchdog will go into v3.15.
That sounds good.
Quoted 2 lines
Or are there any plans to get watchdog in *now*?
Not on my side, I'm aiming at v3.15.
Quoted 2 lines
In any way, do not include my patches into your set.
Hm, maybe I've misexpressed myself. I wasn't intending to include the patches on a submission, but just in a branch on the github repo.
Signature · 7 lines
Ezequiel García, Free Electrons Embedded Linux, Kernel and Android Engineering http://free-electrons.com -- To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
v5 cover Armada 370/XP watchdog support
In reply to Ezequiel GarciaQuoted 7 lines · Ezequiel Garcia
Quoted 2 lines · Ezequiel Garcia
A new round, mostly fixing some minor nitpicks.
If anyone wants to give this a test, here's a public branch:
https://github.com/MISL-EBU-System-SW/mainline-public/tree/wdt_for_v3.14_v5
Works like a charm on the mirabox, I've long been missing a hardware watchdog to save me from unplugging the power cord after some hangs during development.
Thanks,
Willy
v5 cover Armada 370/XP watchdog support
In reply to Ezequiel GarciaWim,
Quoted 6 lines · Ezequiel Garcia
A new round, mostly fixing some minor nitpicks.
This entire series depends on latest irqchip-orion fixes by Sebastian. Namely, this one: https://lkml.org/lkml/2014/1/23/594.
How should we handle this dependency?
As this series depends on another branch we are handling (currently mvebu-next/irqchip-fixes, destined for tglx's tree), would you mind if we took this series through arm-soc with your Ack?
thx,
Jason.
Quoted 128 lines
Changes from v4 are:
* Provided better commit subject and commit log for patch 7:
"watchdog: orion: Handle the interrupt so it's properly acked".* Corrected the misnamed fuction
try_rstout_ioremap().* A bunch of s/interruption/interrupt fixes
* Dropped the '0' as a valid IRQ in the
platform_get_irq()check, given it should return a positive virq-space number.Changes from v3 are:
* It wasn't nice to break DT compatibility by adding a second resource requirement, so we provided a fallback to use the RSTOUT address. All in all, the solution doesn't look too bad.
* Added a full watchdog stop at driver probe time, *before* the call to
request_irq().Notice that currently the
request_irq()doesn't seem to clear the pending interrupt. This means theBRIDGE_CAUSEclear removal is still not safe.This should be fixed sooner than later and, of course, before this gets merged.
* Rework the interrupt request, to use
devm_request_irq()and avoid dealing with IRQ releasing.* Added proper clock error handling and fixed the
probe()error path.* Typos and minor issues got fixed
Changes from v2:
* Add proper error checking on
clk_prepare_enable()and returnPTR_ERRinstead of ENODEV. Suggested by Fabio Estevam.* After the usage of the atomic I/O and considering the watchdog core does its own serialization, the driver's spinlock was completely redundant and was removed. Also suggested by Fabio.
* Instead of making the driver dependent on
PLAT_ORION, added a dependency toARCH_MVEBU. This was proposed by Sebastian and Andrew, given we're working onPLAT_ORIONremoval.Changes from v1:
* Watchdog RSTOUT enable.
While v1 enabled the RSTOUT at each machine initialization, Jason Gunthorpe later pointed out [2] that such enabling might lead to a spurious watchdog trigger, in the event of the watchdog expired event not being cleared.Therefore, the current patchset adds RSTOUT as a second address resource (or 'reg' entry in devicetree words) to allow different platforms specify the corresponding address of the register. This change allows to build the driver on multiplatforms builds as helps remove a mach-specific header.
The drawback of this is that the DT backwards compatibility gets broken; this was timely discussed but no better solution was achieved or proposed.
* BRIDGE CAUSE clear removal
The watchdog cause clear should be done by the bridge irqchip driver, so it's fine to remove it from the watchdog driver and instead request the interrupt.However, there are still a few platforms (orion5x, and legacy kirkwood/dove) that doesn't have this bridge irqchip support enabled. On these platforms the bridge cause clear is simply *not* done.
If we are paranoid about this, maybe we can simply add the clear on each
mach-xxx/irq.c, together with the other irq is initialization.Once again, thanks to everyone who helped reviewing this.
Ezequiel Garcia (20):
ARM: Introduce atomic MMIO modify
clocksource: orion: Use atomic access for shared registers
watchdog: orion: Add clock error handling
watchdog: orion: Use atomic access for shared registers
watchdog: orion: Remove unused macros
watchdog: orion: Make sure the watchdog is initially stopped
watchdog: orion: Handle the interrupt so it's properly acked
watchdog: orion: Make RSTOUT register a separate resource
watchdog: orion: Remove unneededBRIDGE_CAUSEclear
watchdog: orion: Introduce anorion_watchdogdevice structure
watchdog: orion: Introduce per-compatibleof_device_iddata
watchdog: orion: Add per-compatible clock initialization
watchdog: orion: Add per-compatible watchdog start implementation
watchdog: orion: Add support for Armada 370 and Armada XP SoC
ARM: mvebu: Enable Armada 370/XP watchdog in the devicetree
ARM: kirkwood: Add RSTOUT 'reg' entry to devicetree
ARM: dove: Enable Dove watchdog in the devicetree
watchdog: orion: Enable the build onARCH_MVEBU
ARM: mvebu: Enable watchdog support in defconfig
ARM: dove: Enable watchdog support in the defconfig.../devicetree/bindings/watchdog/marvel.txt | 8 +- arch/arm/boot/dts/armada-370-xp.dtsi | 4 + arch/arm/boot/dts/armada-370.dtsi | 5 + arch/arm/boot/dts/armada-xp.dtsi | 6 + arch/arm/boot/dts/dove.dtsi | 8 + arch/arm/boot/dts/kirkwood.dtsi | 2 +- arch/arm/configs/dove_defconfig | 2 + arch/arm/configs/mvebu_defconfig | 2 + arch/arm/include/asm/io.h | 6 + arch/arm/kernel/io.c | 35 ++ arch/arm/mach-dove/include/mach/bridge-regs.h | 1 + arch/arm/mach-kirkwood/include/mach/bridge-regs.h | 1 + arch/arm/mach-mv78xx0/include/mach/bridge-regs.h | 1 + arch/arm/mach-orion5x/include/mach/bridge-regs.h | 1 + arch/arm/plat-orion/common.c | 10 +- drivers/clocksource/time-orion.c | 28 +- drivers/watchdog/Kconfig | 2 +- drivers/watchdog/orion_wdt.c | 369 ++++++++++++++++----- 18 files changed, 383 insertions(+), 108 deletions(-)Signature · 7 lines
1.8.1.5 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel at lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel