xref: /netbsd-src/sys/arch/x86/pci/tcpcib.c (revision c7fb772b85b2b5d4cfb282f868f454b4701534fd)
1*c7fb772bSthorpej /*	$NetBSD: tcpcib.c,v 1.4 2021/08/07 16:19:08 thorpej Exp $	*/
20a1df220Schristos /*	$OpenBSD: tcpcib.c,v 1.4 2012/10/17 22:32:01 deraadt Exp $	*/
30a1df220Schristos 
40a1df220Schristos /*
50a1df220Schristos  * Copyright (c) 2012 Matt Dainty <matt@bodgit-n-scarper.com>
60a1df220Schristos  *
70a1df220Schristos  * Permission to use, copy, modify, and distribute this software for any
80a1df220Schristos  * purpose with or without fee is hereby granted, provided that the above
90a1df220Schristos  * copyright notice and this permission notice appear in all copies.
100a1df220Schristos  *
110a1df220Schristos  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
120a1df220Schristos  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
130a1df220Schristos  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
140a1df220Schristos  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
150a1df220Schristos  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
160a1df220Schristos  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
170a1df220Schristos  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
180a1df220Schristos  */
190a1df220Schristos 
200a1df220Schristos /*
210a1df220Schristos  * Intel Atom E600 series LPC bridge also containing HPET and watchdog
220a1df220Schristos  */
230a1df220Schristos 
240a1df220Schristos #include <sys/cdefs.h>
25*c7fb772bSthorpej __KERNEL_RCSID(0, "$NetBSD: tcpcib.c,v 1.4 2021/08/07 16:19:08 thorpej Exp $");
260a1df220Schristos 
270a1df220Schristos #include <sys/param.h>
280a1df220Schristos #include <sys/systm.h>
290a1df220Schristos #include <sys/device.h>
300a1df220Schristos #include <sys/timetc.h>
310a1df220Schristos #include <sys/bus.h>
320a1df220Schristos 
330a1df220Schristos #include <dev/pci/pcireg.h>
340a1df220Schristos #include <dev/pci/pcivar.h>
350a1df220Schristos #include <dev/pci/pcidevs.h>
360a1df220Schristos 
370a1df220Schristos #include <dev/ic/i82801lpcvar.h>
380a1df220Schristos 
390a1df220Schristos #include <dev/sysmon/sysmonvar.h>
400a1df220Schristos 
410a1df220Schristos #include "pcibvar.h"
420a1df220Schristos 
430a1df220Schristos #define	E600_LPC_SMBA		0x40		/* SMBus Base Address */
440a1df220Schristos #define	E600_LPC_GBA		0x44		/* GPIO Base Address */
450a1df220Schristos #define	E600_LPC_WDTBA		0x84		/* WDT Base Address */
460a1df220Schristos 
470a1df220Schristos #define	E600_WDT_SIZE		64		/* I/O region size */
480a1df220Schristos #define	E600_WDT_PV1		0x00		/* Preload Value 1 Register */
490a1df220Schristos #define	E600_WDT_PV2		0x04		/* Preload Value 2 Register */
500a1df220Schristos #define	E600_WDT_RR0		0x0c		/* Reload Register 0 */
510a1df220Schristos #define	E600_WDT_RR1		0x0d		/* Reload Register 1 */
520a1df220Schristos #define	E600_WDT_RR1_RELOAD	(1 << 0)	/* WDT Reload Flag */
530a1df220Schristos #define	E600_WDT_RR1_TIMEOUT	(1 << 1)	/* WDT Timeout Flag */
540a1df220Schristos #define	E600_WDT_WDTCR		0x10		/* WDT Configuration Register */
550a1df220Schristos #define	E600_WDT_WDTCR_PRE	(1 << 2)	/* WDT Prescalar Select */
560a1df220Schristos #define	E600_WDT_WDTCR_RESET	(1 << 3)	/* WDT Reset Select */
570a1df220Schristos #define	E600_WDT_WDTCR_ENABLE	(1 << 4)	/* WDT Reset Enable */
580a1df220Schristos #define	E600_WDT_WDTCR_TIMEOUT	(1 << 5)	/* WDT Timeout Output Enable */
590a1df220Schristos #define	E600_WDT_DCR		0x14		/* Down Counter Register */
600a1df220Schristos #define	E600_WDT_WDTLR		0x18		/* WDT Lock Register */
610a1df220Schristos #define	E600_WDT_WDTLR_LOCK	(1 << 0)	/* Watchdog Timer Lock */
620a1df220Schristos #define	E600_WDT_WDTLR_ENABLE	(1 << 1)	/* Watchdog Timer Enable */
630a1df220Schristos #define	E600_WDT_WDTLR_TIMEOUT	(1 << 2)	/* WDT Timeout Configuration */
640a1df220Schristos 
650a1df220Schristos #define	E600_HPET_BASE		0xfed00000	/* HPET register base */
660a1df220Schristos #define	E600_HPET_SIZE		0x00000400	/* HPET register size */
670a1df220Schristos 
680a1df220Schristos #define	E600_HPET_GCID		0x000		/* Capabilities and ID */
690a1df220Schristos #define	E600_HPET_GCID_WIDTH	(1 << 13)	/* Counter Size */
700a1df220Schristos #define	E600_HPET_PERIOD	0x004		/* Counter Tick Period */
710a1df220Schristos #define	E600_HPET_GC		0x010		/* General Configuration */
720a1df220Schristos #define	E600_HPET_GC_ENABLE	(1 << 0)	/* Overall Enable */
730a1df220Schristos #define	E600_HPET_GIS		0x020		/* General Interrupt Status */
740a1df220Schristos #define	E600_HPET_MCV		0x0f0		/* Main Counter Value */
750a1df220Schristos #define	E600_HPET_T0C		0x100		/* Timer 0 Config and Capabilities */
760a1df220Schristos #define	E600_HPET_T0CV		0x108		/* Timer 0 Comparator Value */
770a1df220Schristos #define	E600_HPET_T1C		0x120		/* Timer 1 Config and Capabilities */
780a1df220Schristos #define	E600_HPET_T1CV		0x128		/* Timer 1 Comparator Value */
790a1df220Schristos #define	E600_HPET_T2C		0x140		/* Timer 2 Config and Capabilities */
800a1df220Schristos #define	E600_HPET_T2CV		0x148		/* Timer 2 Comparator Value */
810a1df220Schristos 
820a1df220Schristos struct tcpcib_softc {
830a1df220Schristos 	/* we call pcibattach() which assumes this starts like this: */
840a1df220Schristos 	struct pcib_softc	sc_pcib;
850a1df220Schristos 
860a1df220Schristos 	/* Watchdog interface */
870a1df220Schristos 	bool sc_wdt_valid;
880a1df220Schristos 	struct sysmon_wdog sc_wdt_smw;
890a1df220Schristos 	bus_space_tag_t sc_wdt_iot;
900a1df220Schristos 	bus_space_handle_t sc_wdt_ioh;
910a1df220Schristos 
920a1df220Schristos 	/* High Precision Event Timer */
930a1df220Schristos 	device_t sc_hpetbus;
940a1df220Schristos 	bus_space_tag_t sc_hpet_memt;
950a1df220Schristos };
960a1df220Schristos 
970a1df220Schristos static int	tcpcib_match(device_t, cfdata_t, void *);
980a1df220Schristos static void	tcpcib_attach(device_t, device_t, void *);
990a1df220Schristos static int	tcpcib_detach(device_t, int);
1000a1df220Schristos static int	tcpcib_rescan(device_t, const char *, const int *);
1010a1df220Schristos static void	tcpcib_childdet(device_t, device_t);
1020a1df220Schristos static bool	tcpcib_suspend(device_t, const pmf_qual_t *);
1030a1df220Schristos static bool	tcpcib_resume(device_t, const pmf_qual_t *);
1040a1df220Schristos 
1050a1df220Schristos static int	tcpcib_wdt_setmode(struct sysmon_wdog *);
1060a1df220Schristos static int	tcpcib_wdt_tickle(struct sysmon_wdog *);
1070a1df220Schristos static void	tcpcib_wdt_init(struct tcpcib_softc *, int);
1080a1df220Schristos static void	tcpcib_wdt_start(struct tcpcib_softc *);
1090a1df220Schristos static void	tcpcib_wdt_stop(struct tcpcib_softc *);
1100a1df220Schristos 
1110a1df220Schristos CFATTACH_DECL2_NEW(tcpcib, sizeof(struct tcpcib_softc),
1120a1df220Schristos     tcpcib_match, tcpcib_attach, tcpcib_detach, NULL,
1130a1df220Schristos     tcpcib_rescan, tcpcib_childdet);
1140a1df220Schristos 
1150a1df220Schristos static struct tcpcib_device {
1160a1df220Schristos 	pcireg_t vendor, product;
1170a1df220Schristos } tcpcib_devices[] = {
1180a1df220Schristos 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_E600_LPC }
1190a1df220Schristos };
1200a1df220Schristos 
1210a1df220Schristos static void
tcpcib_wdt_unlock(struct tcpcib_softc * sc)1220a1df220Schristos tcpcib_wdt_unlock(struct tcpcib_softc *sc)
1230a1df220Schristos {
1240a1df220Schristos 	/* Register unlocking sequence */
1250a1df220Schristos 	bus_space_write_1(sc->sc_wdt_iot, sc->sc_wdt_ioh, E600_WDT_RR0, 0x80);
1260a1df220Schristos 	bus_space_write_1(sc->sc_wdt_iot, sc->sc_wdt_ioh, E600_WDT_RR0, 0x86);
1270a1df220Schristos }
1280a1df220Schristos 
1290a1df220Schristos static void
tcpcib_wdt_init(struct tcpcib_softc * sc,int period)1300a1df220Schristos tcpcib_wdt_init(struct tcpcib_softc *sc, int period)
1310a1df220Schristos {
1320a1df220Schristos 	uint32_t preload;
1330a1df220Schristos 
1340a1df220Schristos 	/* Set new timeout */
1350a1df220Schristos 	preload = (period * 33000000) >> 15;
1360a1df220Schristos 	preload--;
1370a1df220Schristos 
1380a1df220Schristos 	/*
1390a1df220Schristos 	 * Set watchdog to perform a cold reset toggling the GPIO pin and the
1400a1df220Schristos 	 * prescaler set to 1ms-10m resolution
1410a1df220Schristos 	 */
1420a1df220Schristos 	bus_space_write_1(sc->sc_wdt_iot, sc->sc_wdt_ioh, E600_WDT_WDTCR,
1430a1df220Schristos 	    E600_WDT_WDTCR_ENABLE);
1440a1df220Schristos 	tcpcib_wdt_unlock(sc);
1450a1df220Schristos 	bus_space_write_4(sc->sc_wdt_iot, sc->sc_wdt_ioh, E600_WDT_PV1, 0);
1460a1df220Schristos 	tcpcib_wdt_unlock(sc);
1470a1df220Schristos 	bus_space_write_4(sc->sc_wdt_iot, sc->sc_wdt_ioh, E600_WDT_PV2,
1480a1df220Schristos 	    preload);
1490a1df220Schristos 	tcpcib_wdt_unlock(sc);
1500a1df220Schristos 	bus_space_write_1(sc->sc_wdt_iot, sc->sc_wdt_ioh, E600_WDT_RR1,
1510a1df220Schristos 	    E600_WDT_RR1_RELOAD);
1520a1df220Schristos }
1530a1df220Schristos 
1540a1df220Schristos static void
tcpcib_wdt_start(struct tcpcib_softc * sc)1550a1df220Schristos tcpcib_wdt_start(struct tcpcib_softc *sc)
1560a1df220Schristos {
1570a1df220Schristos 	/* Enable watchdog */
1580a1df220Schristos 	bus_space_write_1(sc->sc_wdt_iot, sc->sc_wdt_ioh, E600_WDT_WDTLR,
1590a1df220Schristos 	    E600_WDT_WDTLR_ENABLE);
1600a1df220Schristos }
1610a1df220Schristos 
1620a1df220Schristos static void
tcpcib_wdt_stop(struct tcpcib_softc * sc)1630a1df220Schristos tcpcib_wdt_stop(struct tcpcib_softc *sc)
1640a1df220Schristos {
1650a1df220Schristos 	/* Disable watchdog, with a reload before for safety */
1660a1df220Schristos 	tcpcib_wdt_unlock(sc);
1670a1df220Schristos 	bus_space_write_1(sc->sc_wdt_iot, sc->sc_wdt_ioh, E600_WDT_RR1,
1680a1df220Schristos 	    E600_WDT_RR1_RELOAD);
1690a1df220Schristos 	bus_space_write_1(sc->sc_wdt_iot, sc->sc_wdt_ioh, E600_WDT_WDTLR, 0);
1700a1df220Schristos }
1710a1df220Schristos 
1720a1df220Schristos static int
tcpcib_match(device_t parent,cfdata_t match,void * aux)1730a1df220Schristos tcpcib_match(device_t parent, cfdata_t match, void *aux)
1740a1df220Schristos {
1750a1df220Schristos 	struct pci_attach_args *pa = aux;
1760a1df220Schristos 	unsigned int n;
1770a1df220Schristos 
1780a1df220Schristos 	if (PCI_CLASS(pa->pa_class) != PCI_CLASS_BRIDGE ||
1790a1df220Schristos 	    PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_BRIDGE_ISA)
1800a1df220Schristos 		return 0;
1810a1df220Schristos 
1820a1df220Schristos 	for (n = 0; n < __arraycount(tcpcib_devices); n++) {
1830a1df220Schristos 		if (PCI_VENDOR(pa->pa_id) == tcpcib_devices[n].vendor &&
1840a1df220Schristos 		    PCI_PRODUCT(pa->pa_id) == tcpcib_devices[n].product)
1850a1df220Schristos 			return 10;	/* beat pcib(4) */
1860a1df220Schristos 	}
1870a1df220Schristos 
1880a1df220Schristos 	return 0;
1890a1df220Schristos }
1900a1df220Schristos 
1910a1df220Schristos static void
tcpcib_attach(device_t parent,device_t self,void * aux)1920a1df220Schristos tcpcib_attach(device_t parent, device_t self, void *aux)
1930a1df220Schristos {
1940a1df220Schristos 	struct tcpcib_softc *sc = device_private(self);
1950a1df220Schristos 	struct pci_attach_args *pa = aux;
1960a1df220Schristos 	uint32_t reg, wdtbase;
1970a1df220Schristos 
1980a1df220Schristos 	pmf_device_register(self, tcpcib_suspend, tcpcib_resume);
1990a1df220Schristos 
2000a1df220Schristos 	/* Provide core pcib(4) functionality */
2010a1df220Schristos 	pcibattach(parent, self, aux);
2020a1df220Schristos 
2030a1df220Schristos 	/* High Precision Event Timer */
2040a1df220Schristos 	sc->sc_hpet_memt = pa->pa_memt;
2050a1df220Schristos 	tcpcib_rescan(self, "hpetichbus", NULL);
2060a1df220Schristos 
2070a1df220Schristos 	/* Map Watchdog I/O space */
2080a1df220Schristos 	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, E600_LPC_WDTBA);
2090a1df220Schristos 	wdtbase = reg & 0xffff;
2100a1df220Schristos 	sc->sc_wdt_iot = pa->pa_iot;
2110a1df220Schristos 	if (reg & (1 << 31) && wdtbase) {
2120a1df220Schristos 		if (PCI_MAPREG_IO_ADDR(wdtbase) == 0 ||
2130a1df220Schristos 		    bus_space_map(sc->sc_wdt_iot, PCI_MAPREG_IO_ADDR(wdtbase),
2140a1df220Schristos 		    E600_WDT_SIZE, 0, &sc->sc_wdt_ioh)) {
21571fbb921Smsaitoh 			aprint_error_dev(self,
21671fbb921Smsaitoh 			    "can't map watchdog I/O space\n");
2170a1df220Schristos 			return;
2180a1df220Schristos 		}
2190a1df220Schristos 		aprint_normal_dev(self, "watchdog");
2200a1df220Schristos 
2210a1df220Schristos 		/* Check for reboot on timeout */
2220a1df220Schristos 		reg = bus_space_read_1(sc->sc_wdt_iot, sc->sc_wdt_ioh,
2230a1df220Schristos 		    E600_WDT_RR1);
2240a1df220Schristos 		if (reg & E600_WDT_RR1_TIMEOUT) {
2250a1df220Schristos 			aprint_normal(", reboot on timeout");
2260a1df220Schristos 
2270a1df220Schristos 			/* Clear timeout bit */
2280a1df220Schristos 			tcpcib_wdt_unlock(sc);
2290a1df220Schristos 			bus_space_write_1(sc->sc_wdt_iot, sc->sc_wdt_ioh,
2300a1df220Schristos 			    E600_WDT_RR1, E600_WDT_RR1_TIMEOUT);
2310a1df220Schristos 		}
2320a1df220Schristos 
2330a1df220Schristos 		/* Check it's not locked already */
2340a1df220Schristos 		reg = bus_space_read_1(sc->sc_wdt_iot, sc->sc_wdt_ioh,
2350a1df220Schristos 		    E600_WDT_WDTLR);
2360a1df220Schristos 		if (reg & E600_WDT_WDTLR_LOCK) {
2370a1df220Schristos 			aprint_error(", locked\n");
2380a1df220Schristos 			return;
2390a1df220Schristos 		}
2400a1df220Schristos 
2410a1df220Schristos 		/* Disable watchdog */
2420a1df220Schristos 		tcpcib_wdt_stop(sc);
2430a1df220Schristos 
2440a1df220Schristos 		/* Register new watchdog */
2450a1df220Schristos 		sc->sc_wdt_smw.smw_name = device_xname(self);
2460a1df220Schristos 		sc->sc_wdt_smw.smw_cookie = sc;
2470a1df220Schristos 		sc->sc_wdt_smw.smw_setmode = tcpcib_wdt_setmode;
2480a1df220Schristos 		sc->sc_wdt_smw.smw_tickle = tcpcib_wdt_tickle;
2490a1df220Schristos 		sc->sc_wdt_smw.smw_period = 600; /* seconds */
2500a1df220Schristos 		if (sysmon_wdog_register(&sc->sc_wdt_smw)) {
2510a1df220Schristos 			aprint_error(", unable to register wdog timer\n");
2520a1df220Schristos 			return;
2530a1df220Schristos 		}
2540a1df220Schristos 
2550a1df220Schristos 		sc->sc_wdt_valid = true;
2560a1df220Schristos 		aprint_normal("\n");
2570a1df220Schristos 	}
2580a1df220Schristos 
2590a1df220Schristos }
2600a1df220Schristos 
2610a1df220Schristos static int
tcpcib_detach(device_t self,int flags)2620a1df220Schristos tcpcib_detach(device_t self, int flags)
2630a1df220Schristos {
2640a1df220Schristos 	return pcibdetach(self, flags);
2650a1df220Schristos }
2660a1df220Schristos 
2670a1df220Schristos static int
tcpcib_rescan(device_t self,const char * ifattr,const int * locators)2680a1df220Schristos tcpcib_rescan(device_t self, const char *ifattr, const int *locators)
2690a1df220Schristos {
2700a1df220Schristos 	struct tcpcib_softc *sc = device_private(self);
2710a1df220Schristos 
2720a1df220Schristos 	if (ifattr_match(ifattr, "hpetichbus") && sc->sc_hpetbus == NULL) {
2730a1df220Schristos 		struct lpcib_hpet_attach_args hpet_arg;
2740a1df220Schristos 		hpet_arg.hpet_mem_t = sc->sc_hpet_memt;
2750a1df220Schristos 		hpet_arg.hpet_reg = E600_HPET_BASE;
2762685996bSthorpej 		sc->sc_hpetbus =
2772685996bSthorpej 		    config_found(self, &hpet_arg, NULL,
278*c7fb772bSthorpej 				 CFARGS(.iattr = "hpetichbus"));
2790a1df220Schristos 	}
2800a1df220Schristos 
2810a1df220Schristos 	return pcibrescan(self, ifattr, locators);
2820a1df220Schristos }
2830a1df220Schristos 
2840a1df220Schristos static void
tcpcib_childdet(device_t self,device_t child)2850a1df220Schristos tcpcib_childdet(device_t self, device_t child)
2860a1df220Schristos {
2870a1df220Schristos 	struct tcpcib_softc *sc = device_private(self);
2880a1df220Schristos 
2890a1df220Schristos 	if (sc->sc_hpetbus == child) {
2900a1df220Schristos 		sc->sc_hpetbus = NULL;
2910a1df220Schristos 		return;
2920a1df220Schristos 	}
2930a1df220Schristos 
2940a1df220Schristos 	pcibchilddet(self, child);
2950a1df220Schristos }
2960a1df220Schristos 
2970a1df220Schristos static bool
tcpcib_suspend(device_t self,const pmf_qual_t * qual)2980a1df220Schristos tcpcib_suspend(device_t self, const pmf_qual_t *qual)
2990a1df220Schristos {
3000a1df220Schristos 	struct tcpcib_softc *sc = device_private(self);
3010a1df220Schristos 
3020a1df220Schristos 	if (sc->sc_wdt_valid)
3030a1df220Schristos 		tcpcib_wdt_stop(sc);
3040a1df220Schristos 
3050a1df220Schristos 	return true;
3060a1df220Schristos }
3070a1df220Schristos 
3080a1df220Schristos static bool
tcpcib_resume(device_t self,const pmf_qual_t * qual)3090a1df220Schristos tcpcib_resume(device_t self, const pmf_qual_t *qual)
3100a1df220Schristos {
3110a1df220Schristos 	struct tcpcib_softc *sc = device_private(self);
3120a1df220Schristos 	struct sysmon_wdog *smw = &sc->sc_wdt_smw;
3130a1df220Schristos 
3140a1df220Schristos 	if (sc->sc_wdt_valid) {
3150a1df220Schristos 		if ((smw->smw_mode & WDOG_MODE_MASK) != WDOG_MODE_DISARMED &&
3160a1df220Schristos 		    smw->smw_period > 0) {
3170a1df220Schristos 			tcpcib_wdt_init(sc, smw->smw_period);
3180a1df220Schristos 			tcpcib_wdt_start(sc);
3190a1df220Schristos 		} else {
3200a1df220Schristos 			tcpcib_wdt_stop(sc);
3210a1df220Schristos 		}
3220a1df220Schristos 	}
3230a1df220Schristos 
3240a1df220Schristos 	return true;
3250a1df220Schristos }
3260a1df220Schristos 
3270a1df220Schristos static int
tcpcib_wdt_setmode(struct sysmon_wdog * smw)3280a1df220Schristos tcpcib_wdt_setmode(struct sysmon_wdog *smw)
3290a1df220Schristos {
3300a1df220Schristos 	struct tcpcib_softc *sc = smw->smw_cookie;
3310a1df220Schristos 	unsigned int period;
3320a1df220Schristos 
3330a1df220Schristos 	period = smw->smw_period;
3340a1df220Schristos 	if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) {
3350a1df220Schristos 		tcpcib_wdt_stop(sc);
3360a1df220Schristos 	} else {
3370a1df220Schristos 		/* 600 seconds is the maximum supported timeout value */
3380a1df220Schristos 		if (period > 600)
3390a1df220Schristos 			return EINVAL;
3400a1df220Schristos 
3410a1df220Schristos 		tcpcib_wdt_stop(sc);
3420a1df220Schristos 		tcpcib_wdt_init(sc, period);
3430a1df220Schristos 		tcpcib_wdt_start(sc);
3440a1df220Schristos 		tcpcib_wdt_tickle(smw);
3450a1df220Schristos 	}
3460a1df220Schristos 
3470a1df220Schristos 	return 0;
3480a1df220Schristos }
3490a1df220Schristos 
3500a1df220Schristos static int
tcpcib_wdt_tickle(struct sysmon_wdog * smw)3510a1df220Schristos tcpcib_wdt_tickle(struct sysmon_wdog *smw)
3520a1df220Schristos {
3530a1df220Schristos 	struct tcpcib_softc *sc = smw->smw_cookie;
3540a1df220Schristos 
3550a1df220Schristos 	/* Reset timer */
3560a1df220Schristos 	tcpcib_wdt_unlock(sc);
3570a1df220Schristos 	bus_space_write_1(sc->sc_wdt_iot, sc->sc_wdt_ioh,
3580a1df220Schristos 	    E600_WDT_RR1, E600_WDT_RR1_RELOAD);
3590a1df220Schristos 
3600a1df220Schristos 	return 0;
3610a1df220Schristos }
362