]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - 6/sys/alpha/tlsb/mcclock_tlsb.c
merge fix for boot-time hang on centos' xen
[FreeBSD/FreeBSD.git] / 6 / sys / alpha / tlsb / mcclock_tlsb.c
1 /* $NetBSD: mcclock_tlsb.c,v 1.8 1998/05/13 02:50:29 thorpej Exp $ */
2 /*-
3  * Copyright (c) 1997, 2000 by Matthew Jacob
4  * NASA AMES Research Center.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice immediately at the beginning of the file, without modification,
12  *    this list of conditions, and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 #include <sys/param.h>
34 #include <sys/kernel.h>
35 #include <sys/systm.h>
36 #include <sys/module.h>
37 #include <sys/bus.h>
38
39 #include <machine/clockvar.h>
40 #include <dev/dec/mcclockvar.h>
41
42 #include <alpha/tlsb/gbusvar.h>
43
44 #include <alpha/tlsb/tlsbreg.h>         /* XXX */
45
46 #include <dev/dec/mc146818reg.h>
47
48 #define KV(_addr)       ((caddr_t)ALPHA_PHYS_TO_K0SEG((_addr)))
49 /*
50  * Registers are 64 bytes apart (and 1 byte wide)
51  */
52 #define REGSHIFT        6
53
54 struct mcclock_tlsb_softc {
55         unsigned long regbase;
56 };
57
58 static int      mcclock_tlsb_probe(device_t dev);
59 static int      mcclock_tlsb_attach(device_t dev);
60 static void     mcclock_tlsb_write(device_t, u_int, u_int);
61 static u_int    mcclock_tlsb_read(device_t, u_int);
62
63 static device_method_t mcclock_tlsb_methods[] = {
64         /* Device interface */
65         DEVMETHOD(device_probe,         mcclock_tlsb_probe),
66         DEVMETHOD(device_attach,        mcclock_tlsb_attach),
67
68         /* mcclock interface */
69         DEVMETHOD(mcclock_write,        mcclock_tlsb_write),
70         DEVMETHOD(mcclock_read,         mcclock_tlsb_read),
71
72         /* clock interface */
73         DEVMETHOD(clock_init,           mcclock_init),
74         DEVMETHOD(clock_get,            mcclock_get),
75         DEVMETHOD(clock_set,            mcclock_set),
76         DEVMETHOD(clock_getsecs,        mcclock_getsecs),
77
78         { 0, 0 }
79 };
80
81 static driver_t mcclock_tlsb_driver = {
82         "mcclock", mcclock_tlsb_methods, sizeof(struct mcclock_tlsb_softc),
83 };
84
85 static devclass_t mcclock_devclass;
86
87 int
88 mcclock_tlsb_probe(device_t dev)
89 {
90         device_set_desc(dev, "MC146818A real time clock");
91         return 0;
92 }
93
94 int
95 mcclock_tlsb_attach(device_t dev)
96 {
97         struct mcclock_tlsb_softc *sc = device_get_softc(dev);
98
99         /* XXX Should be bus.h'd, so we can accomodate the kn7aa. */
100
101         sc->regbase = TLSB_GBUS_BASE + gbus_get_offset(dev);
102
103         mcclock_attach(dev);
104         return 0;
105 }
106
107 static void
108 mcclock_tlsb_write(device_t dev, u_int reg, u_int val)
109 {
110         struct mcclock_tlsb_softc *sc = device_get_softc(dev);
111         unsigned char *ptr = (unsigned char *)
112                 KV(sc->regbase + (reg << REGSHIFT));
113         *ptr = val;
114 }
115
116 static u_int
117 mcclock_tlsb_read(device_t dev, u_int reg)
118 {
119         struct mcclock_tlsb_softc *sc = device_get_softc(dev);
120         unsigned char *ptr = (unsigned char *)
121                 KV(sc->regbase + (reg << REGSHIFT));
122         return *ptr;
123 }
124
125 DRIVER_MODULE(mcclock, gbus, mcclock_tlsb_driver, mcclock_devclass, 0, 0);