* [PATCH 1/2] watchdog: i.MX: add soc_reset operation
@ 2017-01-19 15:03 Sascha Hauer
2017-01-19 15:03 ` [PATCH 2/2] watchdog: i.MX: Fix internal/external reset Sascha Hauer
2017-01-20 5:39 ` [PATCH 1/2] watchdog: i.MX: add soc_reset operation Sam Ravnborg
0 siblings, 2 replies; 5+ messages in thread
From: Sascha Hauer @ 2017-01-19 15:03 UTC (permalink / raw)
To: Barebox List
On i.MX21 watchdog type the reset operation is really different
from the watchdog enable/set timeout operation, so create an
extra callback for this instead of folding both things together.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/watchdog/imxwd.c | 32 +++++++++++++++++++++-----------
1 file changed, 21 insertions(+), 11 deletions(-)
diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c
index 03e116ea2..c736fdaa3 100644
--- a/drivers/watchdog/imxwd.c
+++ b/drivers/watchdog/imxwd.c
@@ -26,6 +26,7 @@ struct imx_wd;
struct imx_wd_ops {
int (*set_timeout)(struct imx_wd *, int);
+ void (*soc_reset)(struct imx_wd *);
int (*init)(struct imx_wd *);
};
@@ -76,10 +77,7 @@ static int imx1_watchdog_set_timeout(struct imx_wd *priv, int timeout)
return 0;
}
- if (timeout > 0)
- val = (timeout * 2 - 1) << 8;
- else
- val = 0;
+ val = (timeout * 2 - 1) << 8;
writew(val, priv->base + IMX1_WDOG_WCR);
writew(IMX1_WDOG_WCR_WDE | val, priv->base + IMX1_WDOG_WCR);
@@ -91,6 +89,11 @@ static int imx1_watchdog_set_timeout(struct imx_wd *priv, int timeout)
return 0;
}
+static void imx1_soc_reset(struct imx_wd *priv)
+{
+ writew(IMX1_WDOG_WCR_WDE, priv->base + IMX1_WDOG_WCR);
+}
+
static int imx21_watchdog_set_timeout(struct imx_wd *priv, int timeout)
{
u16 val;
@@ -103,13 +106,9 @@ static int imx21_watchdog_set_timeout(struct imx_wd *priv, int timeout)
if (timeout == 0) /* bit 2 (WDE) cannot be set to 0 again */
return -ENOSYS;
- if (timeout > 0)
- val = ((timeout * 2 - 1) << 8) | IMX21_WDOG_WCR_SRS |
- IMX21_WDOG_WCR_WDA;
- else
- val = 0;
+ val = ((timeout * 2 - 1) << 8) | IMX21_WDOG_WCR_SRS |
+ IMX21_WDOG_WCR_WDA;
- writew(val, priv->base + IMX21_WDOG_WCR);
writew(IMX21_WDOG_WCR_WDE | val, priv->base + IMX21_WDOG_WCR);
/* Write Service Sequence */
@@ -119,6 +118,15 @@ static int imx21_watchdog_set_timeout(struct imx_wd *priv, int timeout)
return 0;
}
+static void imx21_soc_reset(struct imx_wd *priv)
+{
+ u16 val;
+
+ val = IMX21_WDOG_WCR_SRS | IMX21_WDOG_WCR_WDA;
+
+ writew(val, priv->base + IMX21_WDOG_WCR);
+}
+
static int imx_watchdog_set_timeout(struct watchdog *wd, unsigned timeout)
{
struct imx_wd *priv = (struct imx_wd *)to_imx_wd(wd);
@@ -130,7 +138,7 @@ static void __noreturn imxwd_force_soc_reset(struct restart_handler *rst)
{
struct imx_wd *priv = container_of(rst, struct imx_wd, restart);
- priv->ops->set_timeout(priv, -1);
+ priv->ops->soc_reset(priv);
mdelay(1000);
@@ -227,11 +235,13 @@ on_error:
static const struct imx_wd_ops imx21_wd_ops = {
.set_timeout = imx21_watchdog_set_timeout,
+ .soc_reset = imx21_soc_reset,
.init = imx21_wd_init,
};
static const struct imx_wd_ops imx1_wd_ops = {
.set_timeout = imx1_watchdog_set_timeout,
+ .soc_reset = imx1_soc_reset,
};
static __maybe_unused struct of_device_id imx_wdt_dt_ids[] = {
--
2.11.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/2] watchdog: i.MX: Fix internal/external reset
2017-01-19 15:03 [PATCH 1/2] watchdog: i.MX: add soc_reset operation Sascha Hauer
@ 2017-01-19 15:03 ` Sascha Hauer
2017-01-20 5:39 ` [PATCH 1/2] watchdog: i.MX: add soc_reset operation Sam Ravnborg
1 sibling, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2017-01-19 15:03 UTC (permalink / raw)
To: Barebox List
The watchdog can either reset only the SoC or assert the WDOG_B
output signal instead. On some boards it's necessary to use the
external WDOG_B output to make sure that external devices like the
PMIC are also properly resetted. This has been fixed in the Linux
driver which honours a fsl,ext-reset-output device tree property
to select between both ways. Do the same in the barebox driver.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/watchdog/imxwd.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c
index c736fdaa3..84dea802b 100644
--- a/drivers/watchdog/imxwd.c
+++ b/drivers/watchdog/imxwd.c
@@ -36,6 +36,7 @@ struct imx_wd {
struct device_d *dev;
const struct imx_wd_ops *ops;
struct restart_handler restart;
+ bool ext_reset;
};
#define to_imx_wd(h) container_of(h, struct imx_wd, wd)
@@ -51,6 +52,7 @@ struct imx_wd {
#define IMX21_WDOG_WSTR 0x04 /* Watchdog Status Register */
#define IMX21_WDOG_WMCR 0x08 /* Misc Register */
#define IMX21_WDOG_WCR_WDE (1 << 2)
+#define IMX21_WDOG_WCR_WDT (1 << 3)
#define IMX21_WDOG_WCR_SRS (1 << 4)
#define IMX21_WDOG_WCR_WDA (1 << 5)
@@ -109,6 +111,9 @@ static int imx21_watchdog_set_timeout(struct imx_wd *priv, int timeout)
val = ((timeout * 2 - 1) << 8) | IMX21_WDOG_WCR_SRS |
IMX21_WDOG_WCR_WDA;
+ if (priv->ext_reset)
+ val |= IMX21_WDOG_WCR_WDT;
+
writew(IMX21_WDOG_WCR_WDE | val, priv->base + IMX21_WDOG_WCR);
/* Write Service Sequence */
@@ -120,9 +125,13 @@ static int imx21_watchdog_set_timeout(struct imx_wd *priv, int timeout)
static void imx21_soc_reset(struct imx_wd *priv)
{
- u16 val;
+ u16 val = 0;
- val = IMX21_WDOG_WCR_SRS | IMX21_WDOG_WCR_WDA;
+ /* Use internal reset or external - not both */
+ if (priv->ext_reset)
+ val |= IMX21_WDOG_WCR_SRS; /* do not assert int reset */
+ else
+ val |= IMX21_WDOG_WCR_WDA; /* do not assert ext-reset */
writew(val, priv->base + IMX21_WDOG_WCR);
}
@@ -202,6 +211,9 @@ static int imx_wd_probe(struct device_d *dev)
priv->wd.dev = dev;
priv->dev = dev;
+ priv->ext_reset = of_property_read_bool(dev->device_node,
+ "fsl,ext-reset-output");
+
if (IS_ENABLED(CONFIG_WATCHDOG_IMX)) {
ret = watchdog_register(&priv->wd);
if (ret)
--
2.11.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] watchdog: i.MX: add soc_reset operation
2017-01-19 15:03 [PATCH 1/2] watchdog: i.MX: add soc_reset operation Sascha Hauer
2017-01-19 15:03 ` [PATCH 2/2] watchdog: i.MX: Fix internal/external reset Sascha Hauer
@ 2017-01-20 5:39 ` Sam Ravnborg
2017-01-20 5:44 ` Sam Ravnborg
1 sibling, 1 reply; 5+ messages in thread
From: Sam Ravnborg @ 2017-01-20 5:39 UTC (permalink / raw)
To: Sascha Hauer; +Cc: Barebox List
On Thu, Jan 19, 2017 at 04:03:51PM +0100, Sascha Hauer wrote:
> On i.MX21 watchdog type the reset operation is really different
> from the watchdog enable/set timeout operation, so create an
> extra callback for this instead of folding both things together.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> drivers/watchdog/imxwd.c | 32 +++++++++++++++++++++-----------
> 1 file changed, 21 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c
> index 03e116ea2..c736fdaa3 100644
> --- a/drivers/watchdog/imxwd.c
> +++ b/drivers/watchdog/imxwd.c
> @@ -26,6 +26,7 @@ struct imx_wd;
>
> struct imx_wd_ops {
> int (*set_timeout)(struct imx_wd *, int);
With this change the timeout argument could be unsigned int.
> + void (*soc_reset)(struct imx_wd *);
> int (*init)(struct imx_wd *);
> };
>
> @@ -76,10 +77,7 @@ static int imx1_watchdog_set_timeout(struct imx_wd *priv, int timeout)
> return 0;
> }
>
> - if (timeout > 0)
> - val = (timeout * 2 - 1) << 8;
> - else
> - val = 0;
> + val = (timeout * 2 - 1) << 8;
>
> writew(val, priv->base + IMX1_WDOG_WCR);
> writew(IMX1_WDOG_WCR_WDE | val, priv->base + IMX1_WDOG_WCR);
Otherwise the timeout < 0 should somehow be handled here.
> @@ -91,6 +89,11 @@ static int imx1_watchdog_set_timeout(struct imx_wd *priv, int timeout)
> return 0;
> }
>
> +static void imx1_soc_reset(struct imx_wd *priv)
> +{
> + writew(IMX1_WDOG_WCR_WDE, priv->base + IMX1_WDOG_WCR);
> +}
> +
> static int imx21_watchdog_set_timeout(struct imx_wd *priv, int timeout)
> {
> u16 val;
> @@ -103,13 +106,9 @@ static int imx21_watchdog_set_timeout(struct imx_wd *priv, int timeout)
> if (timeout == 0) /* bit 2 (WDE) cannot be set to 0 again */
> return -ENOSYS;
>
> - if (timeout > 0)
> - val = ((timeout * 2 - 1) << 8) | IMX21_WDOG_WCR_SRS |
> - IMX21_WDOG_WCR_WDA;
> - else
> - val = 0;
> + val = ((timeout * 2 - 1) << 8) | IMX21_WDOG_WCR_SRS |
> + IMX21_WDOG_WCR_WDA;
Likewise.
Sam
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] watchdog: i.MX: add soc_reset operation
2017-01-20 5:39 ` [PATCH 1/2] watchdog: i.MX: add soc_reset operation Sam Ravnborg
@ 2017-01-20 5:44 ` Sam Ravnborg
2017-01-20 8:10 ` Sascha Hauer
0 siblings, 1 reply; 5+ messages in thread
From: Sam Ravnborg @ 2017-01-20 5:44 UTC (permalink / raw)
To: Sascha Hauer; +Cc: Barebox List
On Fri, Jan 20, 2017 at 06:39:03AM +0100, Sam Ravnborg wrote:
> On Thu, Jan 19, 2017 at 04:03:51PM +0100, Sascha Hauer wrote:
> > On i.MX21 watchdog type the reset operation is really different
> > from the watchdog enable/set timeout operation, so create an
> > extra callback for this instead of folding both things together.
> >
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > ---
> > drivers/watchdog/imxwd.c | 32 +++++++++++++++++++++-----------
> > 1 file changed, 21 insertions(+), 11 deletions(-)
> >
> > diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c
> > index 03e116ea2..c736fdaa3 100644
> > --- a/drivers/watchdog/imxwd.c
> > +++ b/drivers/watchdog/imxwd.c
> > @@ -26,6 +26,7 @@ struct imx_wd;
> >
> > struct imx_wd_ops {
> > int (*set_timeout)(struct imx_wd *, int);
>
> With this change the timeout argument could be unsigned int.
>
> > + void (*soc_reset)(struct imx_wd *);
> > int (*init)(struct imx_wd *);
> > };
> >
> > @@ -76,10 +77,7 @@ static int imx1_watchdog_set_timeout(struct imx_wd *priv, int timeout)
> > return 0;
> > }
> >
> > - if (timeout > 0)
> > - val = (timeout * 2 - 1) << 8;
> > - else
> > - val = 0;
> > + val = (timeout * 2 - 1) << 8;
> >
> > writew(val, priv->base + IMX1_WDOG_WCR);
> > writew(IMX1_WDOG_WCR_WDE | val, priv->base + IMX1_WDOG_WCR);
>
> Otherwise the timeout < 0 should somehow be handled here.
Unless we do not bother because this is all local to the file
and we know the two call sites.
Sam
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] watchdog: i.MX: add soc_reset operation
2017-01-20 5:44 ` Sam Ravnborg
@ 2017-01-20 8:10 ` Sascha Hauer
0 siblings, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2017-01-20 8:10 UTC (permalink / raw)
To: Sam Ravnborg; +Cc: Barebox List
Hi Sam,
On Fri, Jan 20, 2017 at 06:44:00AM +0100, Sam Ravnborg wrote:
> On Fri, Jan 20, 2017 at 06:39:03AM +0100, Sam Ravnborg wrote:
> > On Thu, Jan 19, 2017 at 04:03:51PM +0100, Sascha Hauer wrote:
> > > On i.MX21 watchdog type the reset operation is really different
> > > from the watchdog enable/set timeout operation, so create an
> > > extra callback for this instead of folding both things together.
> > >
> > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > > ---
> > > drivers/watchdog/imxwd.c | 32 +++++++++++++++++++++-----------
> > > 1 file changed, 21 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c
> > > index 03e116ea2..c736fdaa3 100644
> > > --- a/drivers/watchdog/imxwd.c
> > > +++ b/drivers/watchdog/imxwd.c
> > > @@ -26,6 +26,7 @@ struct imx_wd;
> > >
> > > struct imx_wd_ops {
> > > int (*set_timeout)(struct imx_wd *, int);
> >
> > With this change the timeout argument could be unsigned int.
> >
> > > + void (*soc_reset)(struct imx_wd *);
> > > int (*init)(struct imx_wd *);
> > > };
> > >
> > > @@ -76,10 +77,7 @@ static int imx1_watchdog_set_timeout(struct imx_wd *priv, int timeout)
> > > return 0;
> > > }
> > >
> > > - if (timeout > 0)
> > > - val = (timeout * 2 - 1) << 8;
> > > - else
> > > - val = 0;
> > > + val = (timeout * 2 - 1) << 8;
> > >
> > > writew(val, priv->base + IMX1_WDOG_WCR);
> > > writew(IMX1_WDOG_WCR_WDE | val, priv->base + IMX1_WDOG_WCR);
> >
> > Otherwise the timeout < 0 should somehow be handled here.
>
> Unless we do not bother because this is all local to the file
> and we know the two call sites.
I changed it to unsigned and also removed another check for negative
values.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-01-20 8:12 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-19 15:03 [PATCH 1/2] watchdog: i.MX: add soc_reset operation Sascha Hauer
2017-01-19 15:03 ` [PATCH 2/2] watchdog: i.MX: Fix internal/external reset Sascha Hauer
2017-01-20 5:39 ` [PATCH 1/2] watchdog: i.MX: add soc_reset operation Sam Ravnborg
2017-01-20 5:44 ` Sam Ravnborg
2017-01-20 8:10 ` Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox