Sync usage with man page.
[netbsd-mini2440.git] / sys / arch / arm / gemini / gemini_wdt.c
blob41b5ab9265acda21082238a750b88dfd2a83956d
1 /* $NetBSD: gemini_wdt.c,v 1.1 2008/10/24 04:23:18 matt Exp $ */
3 /*
4 * OMAP watchdog timers, common code
6 * Copyright (c) 2007 Microsoft
7 * All rights reserved.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by Microsoft
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #include <sys/cdefs.h>
36 #include <sys/param.h>
37 #include <sys/callout.h>
38 #include <sys/cdefs.h>
39 #include <sys/device.h>
40 #include <sys/kernel.h>
41 #include <sys/systm.h>
42 #include <sys/wdog.h>
44 #include <machine/param.h>
45 #include <machine/bus.h>
46 #include <dev/sysmon/sysmonvar.h>
48 #include <arm/gemini/gemini_wdtvar.h>
49 #include <arm/gemini/gemini_reg.h>
51 geminiwdt_softc_t *geminiwdt_sc;
53 #define WATCHDOG_COUNT(nsec) \
54 (GEMINI_WDT_CLOCK_FREQ * (nsec))
57 static void
58 geminiwdt_start(void)
60 geminiwdt_softc_t *sc = geminiwdt_sc;
61 uint32_t r;
63 r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GEMINI_WDT_WDCR);
64 r |= (WDT_WDCR_RESET_ENB
65 |WDT_WDCR_ENB);
66 bus_space_write_4(sc->sc_iot, sc->sc_ioh, GEMINI_WDT_WDCR, r);
69 static void
70 geminiwdt_stop(void)
72 geminiwdt_softc_t *sc = geminiwdt_sc;
73 uint32_t r;
75 r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GEMINI_WDT_WDCR);
76 r &= ~(WDT_WDCR_EXTSIG_ENB
77 |WDT_WDCR_RESET_ENB
78 |WDT_WDCR_INTR_ENB
79 |WDT_WDCR_ENB);
80 bus_space_write_4(sc->sc_iot, sc->sc_ioh, GEMINI_WDT_WDCR, r);
81 bus_space_write_4(sc->sc_iot, sc->sc_ioh,
82 GEMINI_WDT_WDCLEAR, WDT_WDCLEAR_CLEAR);
85 static void
86 geminiwdt_do_set_timeout(void)
88 geminiwdt_softc_t *sc = geminiwdt_sc;
89 uint32_t r;
92 * Disable the watchdog timer
94 if (sc->sc_armed)
95 geminiwdt_stop();
98 * Set WdLoad register
100 r = (sc->sc_smw.smw_period != 0) ?
101 WATCHDOG_COUNT(sc->sc_smw.smw_period) : WDT_WDLOAD_DFLT;
102 bus_space_write_4(sc->sc_iot, sc->sc_ioh, GEMINI_WDT_WDLOAD, r);
105 * feed MAGIC treat to dog
107 bus_space_write_4(sc->sc_iot, sc->sc_ioh,
108 GEMINI_WDT_WDRESTART, WDT_WDRESTART_MAGIC);
111 * Select PCLK clock source
113 r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GEMINI_WDT_WDCR);
114 r &= ~WDCR_CLKSRC_5MHZ;
115 bus_space_write_4(sc->sc_iot, sc->sc_ioh, GEMINI_WDT_WDCR, r);
118 * Enable the timer
120 if (sc->sc_armed)
121 geminiwdt_start();
124 void
125 geminiwdt_set_timeout(unsigned int period)
127 geminiwdt_softc_t *sc = geminiwdt_sc;
128 int s = splhigh();
130 if (period != sc->sc_smw.smw_period) {
131 sc->sc_smw.smw_period = period;
132 geminiwdt_do_set_timeout();
135 splx(s);
139 geminiwdt_enable(int enable)
141 geminiwdt_softc_t *sc = geminiwdt_sc;
142 int s;
143 int prev_state = geminiwdt_sc->sc_armed;
145 /* Normalize the int to a boolean so we can compare values directly.
147 enable = !!enable;
149 s = splhigh();
151 if (enable != sc->sc_armed) {
152 if (enable) {
153 /* Make sure that the watchdog timeout is up to date.
155 geminiwdt_do_set_timeout();
156 geminiwdt_start();
157 } else {
158 geminiwdt_stop();
160 sc->sc_armed = enable;
163 splx(s);
164 return prev_state;
168 geminiwdt_setmode(struct sysmon_wdog *smw)
170 geminiwdt_softc_t *sc = smw->smw_cookie;
171 int error = 0;
173 if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) {
174 geminiwdt_enable(0);
175 } else {
176 if (smw->smw_period == WDOG_PERIOD_DEFAULT)
177 sc->sc_smw.smw_period = WDT_WDLOAD_DFLT;
178 else
179 sc->sc_smw.smw_period = smw->smw_period;
180 geminiwdt_set_timeout(sc->sc_smw.smw_period);
181 geminiwdt_enable(1);
183 return error;
187 geminiwdt_tickle(struct sysmon_wdog *smw)
189 geminiwdt_softc_t *sc = geminiwdt_sc;
190 int s = splhigh();
193 * feed the dog a MAGIC treat
195 bus_space_write_4(sc->sc_iot, sc->sc_ioh,
196 GEMINI_WDT_WDRESTART, WDT_WDRESTART_MAGIC);
198 splx(s);
199 return 0;