Module Name: src Committed By: jmcneill Date: Thu Jan 10 02:23:26 UTC 2013
Modified Files: src/sys/arch/arm/broadcom: bcm2835_pm.c files.bcm2835 Log Message: bcm2835 watchdog timer support To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/broadcom/bcm2835_pm.c cvs rdiff -u -r1.12 -r1.13 src/sys/arch/arm/broadcom/files.bcm2835 Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/broadcom/bcm2835_pm.c diff -u src/sys/arch/arm/broadcom/bcm2835_pm.c:1.1 src/sys/arch/arm/broadcom/bcm2835_pm.c:1.2 --- src/sys/arch/arm/broadcom/bcm2835_pm.c:1.1 Thu Jul 26 06:21:57 2012 +++ src/sys/arch/arm/broadcom/bcm2835_pm.c Thu Jan 10 02:23:26 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: bcm2835_pm.c,v 1.1 2012/07/26 06:21:57 skrll Exp $ */ +/* $NetBSD: bcm2835_pm.c,v 1.2 2013/01/10 02:23:26 jmcneill Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bcm2835_pm.c,v 1.1 2012/07/26 06:21:57 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bcm2835_pm.c,v 1.2 2013/01/10 02:23:26 jmcneill Exp $"); #include <sys/param.h> @@ -38,13 +38,20 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_pm.c #include <sys/device.h> #include <sys/kernel.h> #include <sys/timetc.h> +#include <sys/wdog.h> #include <sys/bus.h> +#include <dev/sysmon/sysmonvar.h> + #include <arm/broadcom/bcm_amba.h> #include <arm/broadcom/bcm2835reg.h> #include <arm/broadcom/bcm2835_intr.h> #include <arm/broadcom/bcm2835_pmvar.h> +#ifndef BCM2835_PM_DEFAULT_PERIOD +#define BCM2835_PM_DEFAULT_PERIOD 15 /* seconds */ +#endif + #define BCM2835_PM_PASSWORD 0x5a000000 #define BCM2835_PM_RSTC 0x1c @@ -60,6 +67,8 @@ struct bcm2835pm_softc { bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; + + struct sysmon_wdog sc_smw; }; static struct bcm2835pm_softc *bcm2835pm_sc; @@ -67,6 +76,11 @@ static struct bcm2835pm_softc *bcm2835pm static int bcmpm_match(device_t, cfdata_t, void *); static void bcmpm_attach(device_t, device_t, void *); +static void bcmpm_wdog_set_timeout(struct bcm2835pm_softc *, uint32_t); + +static int bcmpm_wdog_setmode(struct sysmon_wdog *); +static int bcmpm_wdog_tickle(struct sysmon_wdog *); + CFATTACH_DECL_NEW(bcmpm_amba, sizeof(struct bcm2835pm_softc), bcmpm_match, bcmpm_attach, NULL, NULL); @@ -102,14 +116,21 @@ bcmpm_attach(device_t parent, device_t s aprint_error_dev(sc->sc_dev, "unable to map device\n"); return; } + + /* watchdog */ + sc->sc_smw.smw_name = device_xname(sc->sc_dev); + sc->sc_smw.smw_cookie = sc; + sc->sc_smw.smw_setmode = bcmpm_wdog_setmode; + sc->sc_smw.smw_tickle = bcmpm_wdog_tickle; + sc->sc_smw.smw_period = BCM2835_PM_DEFAULT_PERIOD; + if (sysmon_wdog_register(&sc->sc_smw) != 0) + aprint_error_dev(self, "couldn't register watchdog\n"); } -void -bcm2835_system_reset(void) +static void +bcmpm_wdog_set_timeout(struct bcm2835pm_softc *sc, uint32_t ticks) { - struct bcm2835pm_softc *sc = bcm2835pm_sc; uint32_t tmp, rstc, wdog; - uint32_t timeout = 10; tmp = bus_space_read_4(sc->sc_iot, sc->sc_ioh, BCM2835_PM_RSTC); @@ -118,8 +139,48 @@ bcm2835_system_reset(void) rstc |= tmp & ~BCM2835_PM_RSTC_CONFIGMASK; rstc |= BCM2835_PM_RSTC_FULL_RESET; - wdog |= timeout & BCM2835_PM_WDOG_TIMEMASK; + wdog |= ticks & BCM2835_PM_WDOG_TIMEMASK; bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCM2835_PM_WDOG, wdog); bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCM2835_PM_RSTC, rstc); } + +static int +bcmpm_wdog_setmode(struct sysmon_wdog *smw) +{ + struct bcm2835pm_softc *sc = smw->smw_cookie; + int error = 0; + + if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) { + bus_space_write_4(sc->sc_iot, sc->sc_ioh, BCM2835_PM_RSTC, + BCM2835_PM_PASSWORD | BCM2835_PM_RSTC_RESET); + } else { + if (smw->smw_period == WDOG_PERIOD_DEFAULT) + smw->smw_period = BCM2835_PM_DEFAULT_PERIOD; + if (smw->smw_period > (BCM2835_PM_WDOG_TIMEMASK >> 16)) + return EINVAL; + error = bcmpm_wdog_tickle(smw); + } + + return error; +} + +static int +bcmpm_wdog_tickle(struct sysmon_wdog *smw) +{ + struct bcm2835pm_softc *sc = smw->smw_cookie; + uint32_t timeout = smw->smw_period << 16; + + bcmpm_wdog_set_timeout(sc, timeout); + + return 0; +} + +void +bcm2835_system_reset(void) +{ + struct bcm2835pm_softc *sc = bcm2835pm_sc; + uint32_t timeout = 10; + + bcmpm_wdog_set_timeout(sc, timeout); +} Index: src/sys/arch/arm/broadcom/files.bcm2835 diff -u src/sys/arch/arm/broadcom/files.bcm2835:1.12 src/sys/arch/arm/broadcom/files.bcm2835:1.13 --- src/sys/arch/arm/broadcom/files.bcm2835:1.12 Wed Jan 9 22:23:44 2013 +++ src/sys/arch/arm/broadcom/files.bcm2835 Thu Jan 10 02:23:26 2013 @@ -1,4 +1,4 @@ -# $NetBSD: files.bcm2835,v 1.12 2013/01/09 22:23:44 skrll Exp $ +# $NetBSD: files.bcm2835,v 1.13 2013/01/10 02:23:26 jmcneill Exp $ # # Configuration info for Broadcom BCM2835 ARM Peripherals # @@ -38,7 +38,7 @@ attach bcmtmr at obio with bcmtmr_amba file arch/arm/broadcom/bcm2835_tmr.c bcmtmr # Power Management, Reset Controller, and Watchdog (BCM2835_PM_BASE) -device bcmpm +device bcmpm: sysmon_wdog attach bcmpm at obio with bcmpm_amba file arch/arm/broadcom/bcm2835_pm.c bcmpm