Message ID | 1433448960-9257-2-git-send-email-tharvey@gateworks.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thu, Jun 4, 2015 at 3:15 PM, Tim Harvey <tharvey@gateworks.com> wrote: > + /* Generate internal chip-level reset if WDOG times out */ > + if (!wdev->ext_reset) > + val &= ~IMX2_WDT_WCR_WRE; > + /* Or if external-reset assert WDOG_B reset only on time-out */ > + else > + val |= IMX2_WDT_WCR_WRE; I think you can always enable IMX2_WDT_WCR_WRE. So needn't ext_reset. If you don't config WDOG_B pin mux, WDOG_B do nothing. best regards Frank Li
Am Donnerstag, den 04.06.2015, 13:15 -0700 schrieb Tim Harvey: > The IMX6 watchdog supports assertion of a signal (WDOG_B) which > can be pinmux'd to an external pin. This is typically used for boards that > have PMIC's in control of the IMX6 power rails. In fact, failure to use > such an external reset on boards with external PMIC's can result in various > hangs due to the IMX6 not being fully reset [1] as well as the board failing > to reset because its PMIC has not been reset to provide adequate voltage for > the CPU when coming out of reset at 800Mhz. > > This uses a new device-tree property 'ext-reset-output' to indicate the > board has such a reset and to cause the watchdog to be configured to assert > WDOG_B instead of an internal reset both on a watchdog timeout and in > system_restart. > > [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-March/333689.html > > Cc: Lucas Stach <l.stach@pengutronix.de> > Signed-off-by: Tim Harvey <tharvey@gateworks.com> Reviewed-by: Lucas Stach <l.stach@pengutronix.de> > --- > v2: > - rename property to 'ext-reset-output' based on ML feedback > - simplify setting SRS bit if external-reset > - update comments and commit msg > > Signed-off-by: Tim Harvey <tharvey@gateworks.com> > --- > .../devicetree/bindings/watchdog/fsl-imx-wdt.txt | 2 ++ > drivers/watchdog/imx2_wdt.c | 17 +++++++++++++++-- > 2 files changed, 17 insertions(+), 2 deletions(-) > > diff --git a/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt b/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt > index 8dab6fd..9b89b3a 100644 > --- a/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt > +++ b/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt > @@ -9,6 +9,8 @@ Optional property: > - big-endian: If present the watchdog device's registers are implemented > in big endian mode, otherwise in native mode(same with CPU), for more > detail please see: Documentation/devicetree/bindings/regmap/regmap.txt. > +- ext-reset-output: If present the watchdog device is configured to assert its > + external reset (WDOG_B) instead of issuing a software reset. > > Examples: > > diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c > index 5e6d808..7b8eeaf 100644 > --- a/drivers/watchdog/imx2_wdt.c > +++ b/drivers/watchdog/imx2_wdt.c > @@ -41,6 +41,7 @@ > > #define IMX2_WDT_WCR 0x00 /* Control Register */ > #define IMX2_WDT_WCR_WT (0xFF << 8) /* -> Watchdog Timeout Field */ > +#define IMX2_WDT_WCR_SRS (1 << 4) /* -> Software Reset Signal */ > #define IMX2_WDT_WCR_WRE (1 << 3) /* -> WDOG Reset Enable */ > #define IMX2_WDT_WCR_WDE (1 << 2) /* -> Watchdog Enable */ > #define IMX2_WDT_WCR_WDZST (1 << 0) /* -> Watchdog timer Suspend */ > @@ -65,6 +66,7 @@ struct imx2_wdt_device { > struct timer_list timer; /* Pings the watchdog when closed */ > struct watchdog_device wdog; > struct notifier_block restart_handler; > + bool ext_reset; > }; > > static bool nowayout = WATCHDOG_NOWAYOUT; > @@ -90,6 +92,11 @@ static int imx2_restart_handler(struct notifier_block *this, unsigned long mode, > struct imx2_wdt_device *wdev = container_of(this, > struct imx2_wdt_device, > restart_handler); > + > + /* Use external reset */ > + if (wdev->ext_reset) > + wcr_enable |= IMX2_WDT_WCR_SRS; > + > /* Assert SRS signal */ > regmap_write(wdev->regmap, 0, wcr_enable); > /* > @@ -119,8 +126,12 @@ static inline void imx2_wdt_setup(struct watchdog_device *wdog) > val |= IMX2_WDT_WCR_WDZST; > /* Strip the old watchdog Time-Out value */ > val &= ~IMX2_WDT_WCR_WT; > - /* Generate reset if WDOG times out */ > - val &= ~IMX2_WDT_WCR_WRE; > + /* Generate internal chip-level reset if WDOG times out */ > + if (!wdev->ext_reset) > + val &= ~IMX2_WDT_WCR_WRE; > + /* Or if external-reset assert WDOG_B reset only on time-out */ > + else > + val |= IMX2_WDT_WCR_WRE; > /* Keep Watchdog Disabled */ > val &= ~IMX2_WDT_WCR_WDE; > /* Set the watchdog's Time-Out value */ > @@ -262,6 +273,8 @@ static int __init imx2_wdt_probe(struct platform_device *pdev) > regmap_read(wdev->regmap, IMX2_WDT_WRSR, &val); > wdog->bootstatus = val & IMX2_WDT_WRSR_TOUT ? WDIOF_CARDRESET : 0; > > + wdev->ext_reset = of_property_read_bool(pdev->dev.of_node, > + "ext-reset-output"); > wdog->timeout = clamp_t(unsigned, timeout, 1, IMX2_WDT_MAX_TIME); > if (wdog->timeout != timeout) > dev_warn(&pdev->dev, "Initial timeout out of range! Clamped from %u to %u\n",
On Fri, Jun 5, 2015 at 9:38 AM, Zhi Li <lznuaa@gmail.com> wrote: > On Thu, Jun 4, 2015 at 3:15 PM, Tim Harvey <tharvey@gateworks.com> wrote: >> + /* Generate internal chip-level reset if WDOG times out */ >> + if (!wdev->ext_reset) >> + val &= ~IMX2_WDT_WCR_WRE; >> + /* Or if external-reset assert WDOG_B reset only on time-out */ >> + else >> + val |= IMX2_WDT_WCR_WRE; > > I think you can always enable IMX2_WDT_WCR_WRE. > So needn't ext_reset. > > If you don't config WDOG_B pin mux, WDOG_B do nothing. > > best regards > Frank Li Frank, No - If you generate both an IMX6 internal reset and an external reset, the external reset signal is released immediately after the IMX6 goes into reset which may be too quick for whatever hardware you have that routed to. Tim
On Thu, Jun 04, 2015 at 01:15:59PM -0700, Tim Harvey wrote: > The IMX6 watchdog supports assertion of a signal (WDOG_B) which > can be pinmux'd to an external pin. This is typically used for boards that > have PMIC's in control of the IMX6 power rails. In fact, failure to use > such an external reset on boards with external PMIC's can result in various > hangs due to the IMX6 not being fully reset [1] as well as the board failing > to reset because its PMIC has not been reset to provide adequate voltage for > the CPU when coming out of reset at 800Mhz. > > This uses a new device-tree property 'ext-reset-output' to indicate the > board has such a reset and to cause the watchdog to be configured to assert > WDOG_B instead of an internal reset both on a watchdog timeout and in > system_restart. > > [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-March/333689.html > > Cc: Lucas Stach <l.stach@pengutronix.de> > Signed-off-by: Tim Harvey <tharvey@gateworks.com> > --- > v2: > - rename property to 'ext-reset-output' based on ML feedback > - simplify setting SRS bit if external-reset > - update comments and commit msg > > Signed-off-by: Tim Harvey <tharvey@gateworks.com> > --- > .../devicetree/bindings/watchdog/fsl-imx-wdt.txt | 2 ++ > drivers/watchdog/imx2_wdt.c | 17 +++++++++++++++-- > 2 files changed, 17 insertions(+), 2 deletions(-) > > diff --git a/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt b/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt > index 8dab6fd..9b89b3a 100644 > --- a/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt > +++ b/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt > @@ -9,6 +9,8 @@ Optional property: > - big-endian: If present the watchdog device's registers are implemented > in big endian mode, otherwise in native mode(same with CPU), for more > detail please see: Documentation/devicetree/bindings/regmap/regmap.txt. > +- ext-reset-output: If present the watchdog device is configured to assert its > + external reset (WDOG_B) instead of issuing a software reset. This is a vendor specific binding property rather than generic one, so it should have a vendor prefix, i.e. "fsl,". Other than that, Acked-by: Shawn Guo <shawn.guo@linaro.org>
On Thu, Jun 04, 2015 at 01:15:59PM -0700, Tim Harvey wrote: > @@ -90,6 +92,11 @@ static int imx2_restart_handler(struct notifier_block *this, unsigned long mode, > struct imx2_wdt_device *wdev = container_of(this, > struct imx2_wdt_device, > restart_handler); > + > + /* Use external reset */ > + if (wdev->ext_reset) > + wcr_enable |= IMX2_WDT_WCR_SRS; > + The existing code simply writes the register with only WDE (Watchdog Enable) bit set. That said, bit WDA and SRS are cleared at the same time. What's the result of that? Both internal reset and external reset will be asserted? If this is the case, it's unsafe per your reply to Frank's comment, right? So we should only clear one bit between these two based on ext_reset flag to avoid asserting both internal and external reset? Shawn > /* Assert SRS signal */ > regmap_write(wdev->regmap, 0, wcr_enable); > /*
On Sun, Jun 28, 2015 at 6:17 PM, Shawn Guo <shawnguo@kernel.org> wrote: > On Thu, Jun 04, 2015 at 01:15:59PM -0700, Tim Harvey wrote: >> @@ -90,6 +92,11 @@ static int imx2_restart_handler(struct notifier_block *this, unsigned long mode, >> struct imx2_wdt_device *wdev = container_of(this, >> struct imx2_wdt_device, >> restart_handler); >> + >> + /* Use external reset */ >> + if (wdev->ext_reset) >> + wcr_enable |= IMX2_WDT_WCR_SRS; >> + > > The existing code simply writes the register with only WDE (Watchdog > Enable) bit set. That said, bit WDA and SRS are cleared at the same > time. What's the result of that? Both internal reset and external > reset will be asserted? If this is the case, it's unsafe per your reply > to Frank's comment, right? So we should only clear one bit between > these two based on ext_reset flag to avoid asserting both internal and > external reset? > > Shawn Shawn, Correct. Are you saying that you think we should change the above to something like the following to ensure in the internal reset case external reset is not also being asserted?: + /* Use external reset */ + if (wdev->ext_reset) + wcr_enable |= IMX2_WDT_WCR_SRS; /* do not assert internal system reset */ + else + wcr_enable |= IMX2_WDT_WCR_WDA; /* do not assert external reset */ I was not worried about the else case above because if you hit that path your device-tree is saying you are not using external reset anyway. Tim > >> /* Assert SRS signal */ >> regmap_write(wdev->regmap, 0, wcr_enable); >> /*
On Thu, Jul 02, 2015 at 09:49:20AM -0700, Tim Harvey wrote: > On Sun, Jun 28, 2015 at 6:17 PM, Shawn Guo <shawnguo@kernel.org> wrote: > > On Thu, Jun 04, 2015 at 01:15:59PM -0700, Tim Harvey wrote: > >> @@ -90,6 +92,11 @@ static int imx2_restart_handler(struct notifier_block *this, unsigned long mode, > >> struct imx2_wdt_device *wdev = container_of(this, > >> struct imx2_wdt_device, > >> restart_handler); > >> + > >> + /* Use external reset */ > >> + if (wdev->ext_reset) > >> + wcr_enable |= IMX2_WDT_WCR_SRS; > >> + > > > > The existing code simply writes the register with only WDE (Watchdog > > Enable) bit set. That said, bit WDA and SRS are cleared at the same > > time. What's the result of that? Both internal reset and external > > reset will be asserted? If this is the case, it's unsafe per your reply > > to Frank's comment, right? So we should only clear one bit between > > these two based on ext_reset flag to avoid asserting both internal and > > external reset? > > > > Shawn > > Shawn, > > Correct. > > Are you saying that you think we should change the above to something > like the following to ensure in the internal reset case external reset > is not also being asserted?: Yes, that's what I'm saying. > > + /* Use external reset */ > + if (wdev->ext_reset) > + wcr_enable |= IMX2_WDT_WCR_SRS; /* do not assert > internal system reset */ > + else > + wcr_enable |= IMX2_WDT_WCR_WDA; /* do not assert external reset */ > > I was not worried about the else case above because if you hit that > path your device-tree is saying you are not using external reset > anyway. It's a safeguard for platforms which have WDOG_B signal routed to some hardware, while their device trees haven't specified ext_reset_output property. Shawn
The IMX6 watchdog supports assertion of a signal (WDOG_B) which can be pinmux'd to an external pin. This is typically used for boards that have PMIC's in control of the IMX6 power rails. In fact, failure to use such an external reset on boards with external PMIC's can result in various hangs due to the IMX6 not being fully reset [1] as well as the board failing to reset because its PMIC has not been reset to provide adequate voltate for the CPU when comming out of reset at 800Mhz when it was at 400Mhz prior to reset. This adds a new device-tree property 'ext-reset-output' to fsl-imx-wdt in order to indicate the board has such a reset and to cause the watchdog to be configured to assert WDOG_B instead of an internal reset both on a watchdog timeout and in system_restart. The second patch adds the watchdog configuration and pinmux for Gateworks Ventana boards. I would expect that maintainers of other IMX6 boards that use PMIC's that are resettable via WDOG_B to follow-up with similar device-tree patches. I've attempted to Cc those individuals here. [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-March/333689.html Cc: Fabio Estevam <festevam@gmail.com> Cc: Lucas Stach <l.stach@pengutronix.de> Cc: Stefan Roese <sr@denx.de> Cc: Iain Paton <ipaton0@gmail.com> Cc: Sascha Hauer <s.hauer@pengutronix.de> Tim Harvey (2): watchdog: imx2_wdt: add external reset support via 'ext-reset-output' dt prop ARM: dts: ventana: Add ext-reset support .../devicetree/bindings/watchdog/fsl-imx-wdt.txt | 2 ++ arch/arm/boot/dts/imx6qdl-gw51xx.dtsi | 12 ++++++++++++ arch/arm/boot/dts/imx6qdl-gw52xx.dtsi | 12 ++++++++++++ arch/arm/boot/dts/imx6qdl-gw53xx.dtsi | 13 +++++++++++++ arch/arm/boot/dts/imx6qdl-gw54xx.dtsi | 17 +++++++++++++++++ arch/arm/boot/dts/imx6qdl-gw551x.dtsi | 12 ++++++++++++ arch/arm/boot/dts/imx6qdl-gw552x.dtsi | 12 ++++++++++++ drivers/watchdog/imx2_wdt.c | 20 ++++++++++++++++++-- 8 files changed, 98 insertions(+), 2 deletions(-)
On 07/28/2015 11:27 AM, Tim Harvey wrote: > The IMX6 watchdog supports assertion of a signal (WDOG_B) which > can be pinmux'd to an external pin. This is typically used for boards that > have PMIC's in control of the IMX6 power rails. In fact, failure to use > such an external reset on boards with external PMIC's can result in various > hangs due to the IMX6 not being fully reset [1] as well as the board failing > to reset because its PMIC has not been reset to provide adequate voltate for > the CPU when comming out of reset at 800Mhz when it was at 400Mhz prior to > reset. > > This adds a new device-tree property 'ext-reset-output' to fsl-imx-wdt in > order to indicate the board has such a reset and to cause the watchdog to be > configured to assert WDOG_B instead of an internal reset both on a > watchdog timeout and in system_restart. > Hi, was there a reason why this patch did not make it to the upstream kernel? We would like to use this feature on a Advantech/GE board and I can rebase the first patch onto the latest linux-next, resubmit if needed. Thanks, Akshay > The second patch adds the watchdog configuration and pinmux for Gateworks > Ventana boards. > > I would expect that maintainers of other IMX6 boards that use PMIC's that > are resettable via WDOG_B to follow-up with similar device-tree patches. > I've attempted to Cc those individuals here. > > [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-March/333689.html > > Cc: Fabio Estevam <festevam@gmail.com> > Cc: Lucas Stach <l.stach@pengutronix.de> > Cc: Stefan Roese <sr@denx.de> > Cc: Iain Paton <ipaton0@gmail.com> > Cc: Sascha Hauer <s.hauer@pengutronix.de> > > Tim Harvey (2): > watchdog: imx2_wdt: add external reset support via 'ext-reset-output' > dt prop > ARM: dts: ventana: Add ext-reset support > > .../devicetree/bindings/watchdog/fsl-imx-wdt.txt | 2 ++ > arch/arm/boot/dts/imx6qdl-gw51xx.dtsi | 12 ++++++++++++ > arch/arm/boot/dts/imx6qdl-gw52xx.dtsi | 12 ++++++++++++ > arch/arm/boot/dts/imx6qdl-gw53xx.dtsi | 13 +++++++++++++ > arch/arm/boot/dts/imx6qdl-gw54xx.dtsi | 17 +++++++++++++++++ > arch/arm/boot/dts/imx6qdl-gw551x.dtsi | 12 ++++++++++++ > arch/arm/boot/dts/imx6qdl-gw552x.dtsi | 12 ++++++++++++ > drivers/watchdog/imx2_wdt.c | 20 ++++++++++++++++++-- > 8 files changed, 98 insertions(+), 2 deletions(-) >
On Fri, Oct 30, 2015 at 10:00 AM, Akshay Bhat <akshay.bhat@timesys.com> wrote: > > > On 07/28/2015 11:27 AM, Tim Harvey wrote: >> >> The IMX6 watchdog supports assertion of a signal (WDOG_B) which >> can be pinmux'd to an external pin. This is typically used for boards that >> have PMIC's in control of the IMX6 power rails. In fact, failure to use >> such an external reset on boards with external PMIC's can result in >> various >> hangs due to the IMX6 not being fully reset [1] as well as the board >> failing >> to reset because its PMIC has not been reset to provide adequate voltate >> for >> the CPU when comming out of reset at 800Mhz when it was at 400Mhz prior to >> reset. >> >> This adds a new device-tree property 'ext-reset-output' to fsl-imx-wdt in >> order to indicate the board has such a reset and to cause the watchdog to >> be >> configured to assert WDOG_B instead of an internal reset both on a >> watchdog timeout and in system_restart. >> > > Hi, was there a reason why this patch did not make it to the upstream > kernel? We would like to use this feature on a Advantech/GE board and I can > rebase the first patch onto the latest linux-next, resubmit if needed. > > Thanks, Akshay > Akshay, I have no idea why it hasn't made it upstream yet. I realized a couple of weeks ago that I never sent it to Wim who is listed as the maintainer of watchdog device drivers or the linux-watchdog maillist so I did so at that time and haven't heard anything yet. The original patch was: http://lists.infradead.org/pipermail/linux-arm-kernel/2015-May/347168.html The 2nd version was: http://lists.infradead.org/pipermail/linux-arm-kernel/2015-June/348761.html It's likely that a rebase/resubmit (including the proper list) may result in a better outcome. Tim
diff --git a/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt b/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt index 8dab6fd..9b89b3a 100644 --- a/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.txt @@ -9,6 +9,8 @@ Optional property: - big-endian: If present the watchdog device's registers are implemented in big endian mode, otherwise in native mode(same with CPU), for more detail please see: Documentation/devicetree/bindings/regmap/regmap.txt. +- ext-reset-output: If present the watchdog device is configured to assert its + external reset (WDOG_B) instead of issuing a software reset. Examples: diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index 5e6d808..7b8eeaf 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c @@ -41,6 +41,7 @@ #define IMX2_WDT_WCR 0x00 /* Control Register */ #define IMX2_WDT_WCR_WT (0xFF << 8) /* -> Watchdog Timeout Field */ +#define IMX2_WDT_WCR_SRS (1 << 4) /* -> Software Reset Signal */ #define IMX2_WDT_WCR_WRE (1 << 3) /* -> WDOG Reset Enable */ #define IMX2_WDT_WCR_WDE (1 << 2) /* -> Watchdog Enable */ #define IMX2_WDT_WCR_WDZST (1 << 0) /* -> Watchdog timer Suspend */ @@ -65,6 +66,7 @@ struct imx2_wdt_device { struct timer_list timer; /* Pings the watchdog when closed */ struct watchdog_device wdog; struct notifier_block restart_handler; + bool ext_reset; }; static bool nowayout = WATCHDOG_NOWAYOUT; @@ -90,6 +92,11 @@ static int imx2_restart_handler(struct notifier_block *this, unsigned long mode, struct imx2_wdt_device *wdev = container_of(this, struct imx2_wdt_device, restart_handler); + + /* Use external reset */ + if (wdev->ext_reset) + wcr_enable |= IMX2_WDT_WCR_SRS; + /* Assert SRS signal */ regmap_write(wdev->regmap, 0, wcr_enable); /* @@ -119,8 +126,12 @@ static inline void imx2_wdt_setup(struct watchdog_device *wdog) val |= IMX2_WDT_WCR_WDZST; /* Strip the old watchdog Time-Out value */ val &= ~IMX2_WDT_WCR_WT; - /* Generate reset if WDOG times out */ - val &= ~IMX2_WDT_WCR_WRE; + /* Generate internal chip-level reset if WDOG times out */ + if (!wdev->ext_reset) + val &= ~IMX2_WDT_WCR_WRE; + /* Or if external-reset assert WDOG_B reset only on time-out */ + else + val |= IMX2_WDT_WCR_WRE; /* Keep Watchdog Disabled */ val &= ~IMX2_WDT_WCR_WDE; /* Set the watchdog's Time-Out value */ @@ -262,6 +273,8 @@ static int __init imx2_wdt_probe(struct platform_device *pdev) regmap_read(wdev->regmap, IMX2_WDT_WRSR, &val); wdog->bootstatus = val & IMX2_WDT_WRSR_TOUT ? WDIOF_CARDRESET : 0; + wdev->ext_reset = of_property_read_bool(pdev->dev.of_node, + "ext-reset-output"); wdog->timeout = clamp_t(unsigned, timeout, 1, IMX2_WDT_MAX_TIME); if (wdog->timeout != timeout) dev_warn(&pdev->dev, "Initial timeout out of range! Clamped from %u to %u\n",