i80321_wdog.c revision 308325
1/* $NetBSD: i80321_wdog.c,v 1.6 2003/07/15 00:24:54 lukem Exp $ */ 2 3/*- 4 * Copyright (c) 2005 Olivier Houchard 5 * Copyright (c) 2002 Wasabi Systems, Inc. 6 * All rights reserved. 7 * 8 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed for the NetBSD Project by 21 * Wasabi Systems, Inc. 22 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 23 * or promote products derived from this software without specific prior 24 * written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39/* 40 * Watchdog timer support for the Intel i80321 I/O processor. 41 */ 42 43#include <sys/cdefs.h> 44__FBSDID("$FreeBSD: stable/11/sys/arm/xscale/i8134x/i80321_wdog.c 308325 2016-11-05 04:30:44Z mmel $"); 45 46#include <sys/param.h> 47#include <sys/systm.h> 48#include <sys/watchdog.h> 49#include <sys/bus.h> 50#include <sys/kernel.h> 51#include <sys/module.h> 52 53#include <machine/bus.h> 54#include <machine/machdep.h> 55 56#include <arm/xscale/i8134x/i80321reg.h> 57#include <arm/xscale/i8134x/i80321var.h> 58 59 60struct iopwdog_softc { 61 device_t dev; 62 int armed; 63 int wdog_period; 64}; 65 66static __inline void 67wdtcr_write(uint32_t val) 68{ 69 70#ifdef CPU_XSCALE_81342 71 __asm __volatile("mcr p6, 0, %0, c7, c9, 0" 72#else 73 __asm __volatile("mcr p6, 0, %0, c7, c1, 0" 74#endif 75 : 76 : "r" (val)); 77} 78 79static void 80iopwdog_tickle(void *arg) 81{ 82 struct iopwdog_softc *sc = arg; 83 84 if (!sc->armed) 85 return; 86 wdtcr_write(WDTCR_ENABLE1); 87 wdtcr_write(WDTCR_ENABLE2); 88} 89 90static int 91iopwdog_probe(device_t dev) 92{ 93 struct iopwdog_softc *sc = device_get_softc(dev); 94 char buf[128]; 95 96 /* 97 * XXX Should compute the period based on processor speed. 98 * For a 600MHz XScale core, the wdog must be tickled approx. 99 * every 7 seconds. 100 */ 101 102 sc->wdog_period = 7; 103 sprintf(buf, "i80321 Watchdog, must be tickled every %d seconds", 104 sc->wdog_period); 105 device_set_desc_copy(dev, buf); 106 107 return (0); 108} 109 110static void 111iopwdog_watchdog_fn(void *private, u_int cmd, int *error) 112{ 113 struct iopwdog_softc *sc = private; 114 115 cmd &= WD_INTERVAL; 116 if (cmd > 0 && cmd <= 63 117 && (uint64_t)1<<cmd <= (uint64_t)sc->wdog_period * 1000000000) { 118 /* Valid value -> Enable watchdog */ 119 iopwdog_tickle(sc); 120 sc->armed = 1; 121 *error = 0; 122 } else { 123 /* Can't disable this watchdog! */ 124 if (sc->armed) 125 *error = EOPNOTSUPP; 126 } 127} 128 129static int 130iopwdog_attach(device_t dev) 131{ 132 struct iopwdog_softc *sc = device_get_softc(dev); 133 134 sc->dev = dev; 135 sc->armed = 0; 136 EVENTHANDLER_REGISTER(watchdog_list, iopwdog_watchdog_fn, sc, 0); 137 return (0); 138} 139 140static device_method_t iopwdog_methods[] = { 141 DEVMETHOD(device_probe, iopwdog_probe), 142 DEVMETHOD(device_attach, iopwdog_attach), 143 {0, 0}, 144}; 145 146static driver_t iopwdog_driver = { 147 "iopwdog", 148 iopwdog_methods, 149 sizeof(struct iopwdog_softc), 150}; 151static devclass_t iopwdog_devclass; 152 153DRIVER_MODULE(iopwdog, iq, iopwdog_driver, iopwdog_devclass, 0, 0); 154