Annotation of sys/arch/sparc64/dev/pmc.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: pmc.c,v 1.1 2007/04/10 19:03:10 kettenis Exp $ */
2:
3: /*
4: * Copyright (c) 2007 Mark Kettenis
5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18:
19: /*
20: * Driver for watchdog device on Blade 1000, Fire 280R, Fire V480 etc.
21: */
22:
23: #include <sys/param.h>
24: #include <sys/kernel.h>
25: #include <sys/device.h>
26: #include <sys/malloc.h>
27: #include <sys/systm.h>
28:
29: #include <machine/bus.h>
30: #include <machine/autoconf.h>
31:
32: #include <sparc64/dev/ebusreg.h>
33: #include <sparc64/dev/ebusvar.h>
34:
35: /*
36: * Register access is indirect, through an address and data port.
37: */
38:
39: #define PMC_ADDR 0
40: #define PMC_DATA 1
41:
42: /* Watchdog time-out register. */
43: #define PMC_WDTO 0x05
44:
45: struct pmc_softc {
46: struct device sc_dv;
47: bus_space_tag_t sc_iot;
48: bus_space_handle_t sc_ioh;
49: };
50:
51: int pmc_match(struct device *, void *, void *);
52: void pmc_attach(struct device *, struct device *, void *);
53: int pmc_wdog_cb(void *, int);
54:
55: struct cfattach pmc_ca = {
56: sizeof(struct pmc_softc), pmc_match, pmc_attach
57: };
58:
59: struct cfdriver pmc_cd = {
60: NULL, "pmc", DV_DULL
61: };
62:
63: int
64: pmc_match(struct device *parent, void *cf, void *aux)
65: {
66: struct ebus_attach_args *ea = aux;
67:
68: if (strcmp("pmc", ea->ea_name) == 0)
69: return (1);
70: return (0);
71: }
72:
73: void
74: pmc_attach(struct device *parent, struct device *self, void *aux)
75: {
76: struct pmc_softc *sc = (void *)self;
77: struct ebus_attach_args *ea = aux;
78:
79: /* Use prom address if available, otherwise map it. */
80: if (ea->ea_nvaddrs) {
81: if (bus_space_map(ea->ea_memtag, ea->ea_vaddrs[0], 0,
82: BUS_SPACE_MAP_PROMADDRESS, &sc->sc_ioh)) {
83: printf(": can't map PROM register space\n");
84: return;
85: }
86: sc->sc_iot = ea->ea_memtag;
87: } else if (ebus_bus_map(ea->ea_iotag, 0,
88: EBUS_PADDR_FROM_REG(&ea->ea_regs[0]),
89: ea->ea_regs[0].size, 0, 0, &sc->sc_ioh) == 0) {
90: sc->sc_iot = ea->ea_iotag;
91: } else if (ebus_bus_map(ea->ea_memtag, 0,
92: EBUS_PADDR_FROM_REG(&ea->ea_regs[0]),
93: ea->ea_regs[0].size, 0, 0, &sc->sc_ioh) == 0) {
94: sc->sc_iot = ea->ea_memtag;
95: } else {
96: printf("%s: can't map register space\n", self->dv_xname);
97: return;
98: }
99:
100: printf("\n");
101:
102: wdog_register(sc, pmc_wdog_cb);
103: }
104:
105: int
106: pmc_wdog_cb(void *arg, int period)
107: {
108: struct pmc_softc *sc = arg;
109: int mins;
110:
111: mins = (period + 59) / 60;
112: if (mins > 255)
113: mins = 255;
114:
115: bus_space_write_1(sc->sc_iot, sc->sc_ioh, PMC_ADDR, PMC_WDTO);
116: bus_space_write_1(sc->sc_iot, sc->sc_ioh, PMC_DATA, mins);
117:
118: return (mins * 60);
119: }
CVSweb