]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - 6/sys/powerpc/powermac/openpic_macio.c
Clone Kip's Xen on stable/6 tree so that I can work on improving FreeBSD/amd64
[FreeBSD/FreeBSD.git] / 6 / sys / powerpc / powermac / openpic_macio.c
1 /*-
2  * Copyright 2003 by Peter Grehan. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  *    derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
22  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  */
28
29 /*
30  * The macio attachment for the OpenPIC interrupt controller.
31  * A nexus driver is defined so the number of interrupts can be
32  * determined early in the boot sequence before the hardware
33  * is accessed - the interrupt i/f is installed at this time,
34  * and when h/w is finally accessed, interrupt sources allocated
35  * prior to this are activated
36  */
37
38 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD$");
40
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/module.h>
44 #include <sys/bus.h>
45 #include <sys/conf.h>
46 #include <sys/kernel.h>
47
48 #include <dev/ofw/ofw_bus.h>
49 #include <dev/ofw/openfirm.h>
50
51 #include <machine/bus.h>
52 #include <machine/intr.h>
53 #include <machine/intr_machdep.h>
54 #include <machine/md_var.h>
55 #include <machine/nexusvar.h>
56 #include <machine/pio.h>
57 #include <machine/resource.h>
58
59 #include <vm/vm.h>
60 #include <vm/pmap.h>
61
62 #include <sys/rman.h>
63
64 #include <machine/openpicvar.h>
65
66 #include "pic_if.h"
67
68 struct openpic_ofw_softc {
69         struct openpic_softc osc;
70         struct resource *sc_memr;       /* macio bus resource */
71         device_t        sc_ndev;        /* nexus device */
72 };
73
74 static struct openpic_ofw_softc *ofwpicsoftc;
75
76 /*
77  * MacIO interface
78  */
79 static void     openpic_ofw_identify(driver_t *, device_t);
80 static int      openpic_ofw_probe(device_t);
81 static int      openpic_ofw_attach(device_t);
82 static int      openpic_macio_probe(device_t);
83 static int      openpic_macio_attach(device_t);
84
85 /*
86  * Nexus attachment
87  */
88 static device_method_t  openpic_ofw_methods[] = {
89         /* Device interface */
90         DEVMETHOD(device_identify,      openpic_ofw_identify),
91         DEVMETHOD(device_probe,         openpic_ofw_probe),
92         DEVMETHOD(device_attach,        openpic_ofw_attach),
93
94         /* PIC interface */
95         DEVMETHOD(pic_allocate_intr,    openpic_allocate_intr),
96         DEVMETHOD(pic_setup_intr,       openpic_setup_intr),
97         DEVMETHOD(pic_teardown_intr,    openpic_teardown_intr),
98         DEVMETHOD(pic_release_intr,     openpic_release_intr),
99
100         { 0, 0 }
101 };
102
103 static driver_t openpic_ofw_driver = {
104         "openpic",
105         openpic_ofw_methods,
106         sizeof(struct openpic_ofw_softc)
107 };
108
109 static devclass_t openpic_ofw_devclass;
110
111 DRIVER_MODULE(openpic_ofw, nexus, openpic_ofw_driver, openpic_ofw_devclass,
112     0, 0);
113
114 static void
115 openpic_ofw_identify(driver_t *driver, device_t parent)
116 {
117         device_t child;
118         phandle_t pic;
119         char type[40];
120
121         pic = OF_finddevice("mpic");
122         if (pic == -1)
123                 return;
124
125         OF_getprop(pic, "device_type", type, sizeof(type));
126
127         if (strcmp(type, "open-pic") != 0)
128                 return;
129
130         child = BUS_ADD_CHILD(parent, 0, "openpic", 0);
131         if (child != NULL)
132                 nexus_set_device_type(child, "macio");
133 }
134
135 static int
136 openpic_ofw_probe(device_t dev)
137 {
138         char    *name;
139         char    *type;
140
141         name = nexus_get_name(dev);
142         type = nexus_get_device_type(dev);
143
144         if (strcmp(name, "openpic") != 0 ||
145             strcmp(type, "macio") != 0)
146                 return (ENXIO);
147
148         device_set_desc(dev, OPENPIC_DEVSTR);
149         return (0);
150 }
151
152 static int
153 openpic_ofw_attach(device_t dev)
154 {
155         KASSERT(ofwpicsoftc == NULL, ("ofw openpic: already probed"));
156         ofwpicsoftc = device_get_softc(dev);
157         ofwpicsoftc->sc_ndev = dev;
158
159         nexus_install_intcntlr(dev);
160         openpic_early_attach(dev);
161         return (0);
162 }
163
164 /*
165  * MacIO attachment
166  */
167 static device_method_t  openpic_macio_methods[] = {
168         /* Device interface */
169         DEVMETHOD(device_probe,         openpic_macio_probe),
170         DEVMETHOD(device_attach,        openpic_macio_attach),
171
172         { 0, 0 },
173 };
174
175 static driver_t openpic_macio_driver = {
176         "openpicmacio",
177         openpic_macio_methods,
178         0
179 };
180
181 static devclass_t openpic_macio_devclass;
182
183 DRIVER_MODULE(openpicmacio, macio, openpic_macio_driver,
184     openpic_macio_devclass, 0, 0);
185
186 static int
187 openpic_macio_probe(device_t dev)
188 {
189         const char *type = ofw_bus_get_type(dev);
190
191         if (strcmp(type, "open-pic") != 0)
192                 return (ENXIO);
193
194         /*
195          * The description was already printed out in the nexus
196          * probe, so don't do it again here
197          */
198         device_set_desc(dev, "OpenPIC MacIO interrupt cell");
199         if (!bootverbose)
200                 device_quiet(dev);
201         return (0);
202 }
203
204 static int
205 openpic_macio_attach(device_t dev)
206 {
207         struct openpic_ofw_softc *sc;
208         int rid;
209
210         sc = ofwpicsoftc;
211         KASSERT(sc != NULL, ("pic not nexus-probed\n"));
212
213         rid = 0;
214         sc->sc_memr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
215              RF_ACTIVE);
216
217         if (sc->sc_memr == NULL) {
218                 device_printf(dev, "Could not alloc mem resource!\n");
219                 return (ENXIO);
220         }
221
222         sc->osc.sc_bt = rman_get_bustag(sc->sc_memr);
223         sc->osc.sc_bh = rman_get_bushandle(sc->sc_memr);
224         sc->osc.sc_altdev = dev;
225
226         return (openpic_attach(sc->sc_ndev));
227 }
228
229