From owner-p4-projects@FreeBSD.ORG Mon Aug 7 19:54:08 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id D065D16A4E5; Mon, 7 Aug 2006 19:54:07 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7BBB116A4DF for ; Mon, 7 Aug 2006 19:54:07 +0000 (UTC) (envelope-from imp@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 338A543D45 for ; Mon, 7 Aug 2006 19:54:07 +0000 (GMT) (envelope-from imp@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k77Js7bQ057294 for ; Mon, 7 Aug 2006 19:54:07 GMT (envelope-from imp@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k77Js6aS057291 for perforce@freebsd.org; Mon, 7 Aug 2006 19:54:06 GMT (envelope-from imp@freebsd.org) Date: Mon, 7 Aug 2006 19:54:06 GMT Message-Id: <200608071954.k77Js6aS057291@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to imp@freebsd.org using -f From: Warner Losh To: Perforce Change Reviews Cc: Subject: PERFORCE change 103394 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 07 Aug 2006 19:54:08 -0000 http://perforce.freebsd.org/chv.cgi?CH=103394 Change 103394 by imp@imp_bugs on 2006/08/07 19:53:09 implement actual watchdog device, when present. This implementation stretches the spec a little to match the #defines in sys/watchdog.h. I think this is acceptible given the size constraints of the kernel and how watchdogs are generally used. Likely not a big deal either way... Affected files ... .. //depot/projects/arm/src/sys/arm/at91/at91_st.c#12 edit Differences ... ==== //depot/projects/arm/src/sys/arm/at91/at91_st.c#12 (text+ko) ==== @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -48,7 +49,8 @@ static struct at91st_softc { bus_space_tag_t sc_st; bus_space_handle_t sc_sh; - device_t dev; + device_t sc_dev; + eventhandler_tag sc_wet; /* watchdog event handler tag */ } *timer_softc; #define RD4(off) \ @@ -56,6 +58,8 @@ #define WR4(off, val) \ bus_space_write_4(timer_softc->sc_st, timer_softc->sc_sh, (off), (val)) +static watchdog_fn at91st_watchdog; + static inline int st_crtr(void) { @@ -97,7 +101,7 @@ timer_softc = device_get_softc(dev); timer_softc->sc_st = sc->sc_st; - timer_softc->dev = dev; + timer_softc->sc_dev = dev; if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_ST_BASE, AT91RM92_ST_SIZE, &timer_softc->sc_sh) != 0) panic("couldn't subregion timer registers"); @@ -110,6 +114,11 @@ WR4(ST_IDR, 0xffffffff); /* disable watchdog timer */ WR4(ST_WDMR, 0); + + timer_softc->sc_wet = EVENTHANDLER_REGISTER(watchdog_list, + at91st_watchdog, dev, 0); + device_printf(dev, + "watchdog registered, timeout intervall max. 64 sec\n"); return (0); } @@ -142,7 +151,34 @@ #endif } +/* + * t below is in a weird unit. The watchdog is set to 2^t + * nanoseconds. Since our watchdog timer can't really do that too + * well, we approximate it by assuming that the timeout interval for + * the lsb is 2^22 ns, which is 4.194ms. This is an overestimation of + * the actual time (3.906ms), but close enough for watchdogging. + * These approximations, though a violation of the spec, improve the + * performance of the application which typically specifies things as + * WD_TO_32SEC. In that last case, we'd wait 32s before the wdog + * reset. The spec says we should wait closer to 34s, but given how + * it is likely to be used, and the extremely coarse nature time + * interval, I think this is the best solution. + */ static void +at91st_watchdog(void *argp, u_int cmd, int *error) +{ + uint32_t wdog; + int t; + + wdog = 0; + t = cmd & WD_INTERVAL; + if (cmd != 0 && t >= 22 && t <= 37) + wdog = (1 << (t - 22)) | ST_WDMR_RSTEN; + WR4(ST_WDMR, wdog); + WR4(ST_CR, ST_CR_WDRST); +} + +static void clock_intr(void *arg) { struct trapframe *fp = arg; @@ -163,7 +199,7 @@ struct resource *irq; int rid = 0; void *ih; - device_t dev = timer_softc->dev; + device_t dev = timer_softc->sc_dev; if (32768 % hz) { printf("Cannot get %d Hz clock; using 128Hz\n", hz); @@ -231,4 +267,3 @@ cpu_stopprofclock(void) { } -