Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/marvell Add support for the watchdog timer in m...
details: https://anonhg.NetBSD.org/src/rev/8ebb3d2ba7dc
branches: trunk
changeset: 779800:8ebb3d2ba7dc
user: hans <hans%NetBSD.org@localhost>
date: Tue Jun 19 16:50:44 2012 +0000
description:
Add support for the watchdog timer in mvsoctmr.
Tested on DreamPlug system.
diffstat:
sys/arch/arm/marvell/files.marvell | 4 +-
sys/arch/arm/marvell/mvsoctmr.c | 103 ++++++++++++++++++++++++++++++++++++-
2 files changed, 103 insertions(+), 4 deletions(-)
diffs (178 lines):
diff -r affe6bac083e -r 8ebb3d2ba7dc sys/arch/arm/marvell/files.marvell
--- a/sys/arch/arm/marvell/files.marvell Tue Jun 19 14:19:46 2012 +0000
+++ b/sys/arch/arm/marvell/files.marvell Tue Jun 19 16:50:44 2012 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.marvell,v 1.4 2011/03/12 22:34:52 nonaka Exp $
+# $NetBSD: files.marvell,v 1.5 2012/06/19 16:50:44 hans Exp $
#
# Configuration info for Marvell System on Chip support
#
@@ -24,7 +24,7 @@
include "dev/marvell/files.discovery"
# Timers
-device mvsoctmr
+device mvsoctmr: sysmon_wdog
attach mvsoctmr at mvsoc
file arch/arm/marvell/mvsoctmr.c mvsoctmr
diff -r affe6bac083e -r 8ebb3d2ba7dc sys/arch/arm/marvell/mvsoctmr.c
--- a/sys/arch/arm/marvell/mvsoctmr.c Tue Jun 19 14:19:46 2012 +0000
+++ b/sys/arch/arm/marvell/mvsoctmr.c Tue Jun 19 16:50:44 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: mvsoctmr.c,v 1.3 2012/02/12 16:34:07 matt Exp $ */
+/* $NetBSD: mvsoctmr.c,v 1.4 2012/06/19 16:50:44 hans Exp $ */
/*
* Copyright (c) 2007, 2008 KIYOHARA Takashi
* All rights reserved.
@@ -25,7 +25,9 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mvsoctmr.c,v 1.3 2012/02/12 16:34:07 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mvsoctmr.c,v 1.4 2012/06/19 16:50:44 hans Exp $");
+
+#include "opt_ddb.h"
#include <sys/param.h>
#include <sys/atomic.h>
@@ -36,6 +38,7 @@
#include <sys/time.h>
#include <sys/timetc.h>
#include <sys/systm.h>
+#include <sys/wdog.h>
#include <machine/intr.h>
@@ -47,10 +50,21 @@
#include <dev/marvell/marvellvar.h>
+#include <dev/sysmon/sysmonvar.h>
+
+#ifdef DDB
+#include <machine/db_machdep.h>
+#include <ddb/db_extern.h>
+#endif
+
struct mvsoctmr_softc {
device_t sc_dev;
+ struct sysmon_wdog sc_wdog;
+ uint32_t sc_wdog_period;
+ uint32_t sc_wdog_armed;
+
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
};
@@ -65,6 +79,16 @@
static void mvsoctmr_cntl(struct mvsoctmr_softc *, int, u_int, int, int);
+static int mvsoctmr_wdog_tickle(struct sysmon_wdog *);
+static int mvsoctmr_wdog_setmode(struct sysmon_wdog *);
+
+#ifdef DDB
+static struct mvsoctmr_softc *mvsoctmr_softc;
+static void mvsoctmr_wdog_ddb_trap(int);
+#endif
+
+#define MVSOC_WDOG_MAX_PERIOD 21
+
static struct mvsoctmr_softc *mvsoctmr_sc;
static struct timecounter mvsoctmr_timecounter = {
mvsoctmr_get_timecount, /* get_timecount */
@@ -102,6 +126,7 @@
{
struct mvsoctmr_softc *sc = device_private(self);
struct marvell_attach_args *mva = aux;
+ uint32_t rstoutn;
aprint_naive("\n");
aprint_normal(": Marvell SoC Timer\n");
@@ -117,6 +142,29 @@
mvsoctmr_timecounter.tc_name = device_xname(self);
mvsoctmr_cntl(sc, MVSOCTMR_TIMER1, 0xffffffff, 1, 1);
+
+ /*
+ * stop watchdog timer, enable watchdog timer resets
+ */
+ mvsoctmr_cntl(sc, MVSOCTMR_WATCHDOG, 0, 0, 0);
+ rstoutn = read_mlmbreg(MVSOC_MLMB_RSTOUTNMASKR);
+ write_mlmbreg(MVSOC_MLMB_RSTOUTNMASKR,
+ rstoutn | MVSOC_MLMB_RSTOUTNMASKR_WDRSTOUTEN);
+
+#ifdef DDB
+ mvsoctmr_softc = sc;
+ db_trap_callback = mvsoctmr_wdog_ddb_trap;
+#endif
+
+ sc->sc_wdog.smw_name = device_xname(self);
+ sc->sc_wdog.smw_cookie = sc;
+ sc->sc_wdog.smw_setmode = mvsoctmr_wdog_setmode;
+ sc->sc_wdog.smw_tickle = mvsoctmr_wdog_tickle;
+ sc->sc_wdog.smw_period = MVSOC_WDOG_MAX_PERIOD;
+
+ if (sysmon_wdog_register(&sc->sc_wdog) != 0)
+ aprint_error_dev(self,
+ "unable to register watchdog with sysmon\n");
}
/*
@@ -257,3 +305,54 @@
ctrl &= ~MVSOCTMR_CTCR_CPUTIMERAUTO(num);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVSOCTMR_CTCR, ctrl);
}
+
+static int
+mvsoctmr_wdog_setmode(struct sysmon_wdog *smw)
+{
+ struct mvsoctmr_softc *sc = smw->smw_cookie;
+
+ if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) {
+ sc->sc_wdog_armed = 0;
+ mvsoctmr_cntl(sc, MVSOCTMR_WATCHDOG, 0, 0, 0);
+ } else {
+ sc->sc_wdog_armed = 1;
+ if (smw->smw_period == WDOG_PERIOD_DEFAULT)
+ smw->smw_period = MVSOC_WDOG_MAX_PERIOD;
+ else if (smw->smw_period > MVSOC_WDOG_MAX_PERIOD ||
+ smw->smw_period <= 0)
+ return (EOPNOTSUPP);
+ sc->sc_wdog_period = smw->smw_period * mvTclk;
+ mvsoctmr_cntl(sc, MVSOCTMR_WATCHDOG, sc->sc_wdog_period, 1, 0);
+ }
+
+ return (0);
+}
+
+static int
+mvsoctmr_wdog_tickle(struct sysmon_wdog *smw)
+{
+ struct mvsoctmr_softc *sc = smw->smw_cookie;
+
+ mvsoctmr_cntl(sc, MVSOCTMR_WATCHDOG, sc->sc_wdog_period, 1, 0);
+
+ return (0);
+}
+
+#ifdef DDB
+static void
+mvsoctmr_wdog_ddb_trap(int enter)
+{
+ struct mvsoctmr_softc *sc = mvsoctmr_softc;
+
+ if (sc == NULL)
+ return;
+
+ if (sc->sc_wdog_armed) {
+ if (enter)
+ mvsoctmr_cntl(sc, MVSOCTMR_WATCHDOG, 0, 0, 0);
+ else
+ mvsoctmr_cntl(sc, MVSOCTMR_WATCHDOG,
+ sc->sc_wdog_period, 1, 0);
+ }
+}
+#endif
Home |
Main Index |
Thread Index |
Old Index