]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/ti/omap4/omap4_wugen.c
Integrate capsicum-test into the FreeBSD test suite
[FreeBSD/FreeBSD.git] / sys / arm / ti / omap4 / omap4_wugen.c
1 /*-
2  * Copyright (c) 2016 Svatopluk Kraus
3  * Copyright (c) 2016 Michal Meloun
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, 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 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include <sys/param.h>
32 #include <sys/bus.h>
33 #include <sys/conf.h>
34 #include <sys/kernel.h>
35 #include <sys/module.h>
36 #include <sys/rman.h>
37 #include <sys/systm.h>
38
39 #include <machine/fdt.h>
40 #include <machine/intr.h>
41 #include <machine/resource.h>
42
43 #include <dev/ofw/ofw_bus.h>
44 #include <dev/ofw/ofw_bus_subr.h>
45
46 #include "pic_if.h"
47
48 static struct ofw_compat_data compat_data[] = {
49         {"ti,omap4-wugen-mpu",  1},
50         {NULL,                  0}
51 };
52
53 struct omap4_wugen_sc {
54         device_t                sc_dev;
55         struct resource         *sc_mem_res;
56         device_t                sc_parent;
57 };
58
59 static int
60 omap4_wugen_activate_intr(device_t dev, struct intr_irqsrc *isrc,
61     struct resource *res, struct intr_map_data *data)
62 {
63         struct omap4_wugen_sc *sc = device_get_softc(dev);
64
65         return (PIC_ACTIVATE_INTR(sc->sc_parent, isrc, res, data));
66 }
67
68 static void
69 omap4_wugen_disable_intr(device_t dev, struct intr_irqsrc *isrc)
70 {
71         struct omap4_wugen_sc *sc = device_get_softc(dev);
72
73         PIC_DISABLE_INTR(sc->sc_parent, isrc);
74 }
75
76 static void
77 omap4_wugen_enable_intr(device_t dev, struct intr_irqsrc *isrc)
78 {
79         struct omap4_wugen_sc *sc = device_get_softc(dev);
80
81         PIC_ENABLE_INTR(sc->sc_parent, isrc);
82 }
83
84 static int
85 omap4_wugen_map_intr(device_t dev, struct intr_map_data *data,
86     struct intr_irqsrc **isrcp)
87 {
88         struct omap4_wugen_sc *sc = device_get_softc(dev);
89
90         return (PIC_MAP_INTR(sc->sc_parent, data, isrcp));
91 }
92
93 static int
94 omap4_wugen_deactivate_intr(device_t dev, struct intr_irqsrc *isrc,
95     struct resource *res, struct intr_map_data *data)
96 {
97         struct omap4_wugen_sc *sc = device_get_softc(dev);
98
99         return (PIC_DEACTIVATE_INTR(sc->sc_parent, isrc, res, data));
100 }
101
102 static int
103 omap4_wugen_setup_intr(device_t dev, struct intr_irqsrc *isrc,
104     struct resource *res, struct intr_map_data *data)
105 {
106         struct omap4_wugen_sc *sc = device_get_softc(dev);
107
108         return (PIC_SETUP_INTR(sc->sc_parent, isrc, res, data));
109 }
110
111 static int
112 omap4_wugen_teardown_intr(device_t dev, struct intr_irqsrc *isrc,
113     struct resource *res, struct intr_map_data *data)
114 {
115         struct omap4_wugen_sc *sc = device_get_softc(dev);
116
117         return (PIC_TEARDOWN_INTR(sc->sc_parent, isrc, res, data));
118 }
119
120 static void
121 omap4_wugen_pre_ithread(device_t dev, struct intr_irqsrc *isrc)
122 {
123         struct omap4_wugen_sc *sc = device_get_softc(dev);
124
125         PIC_PRE_ITHREAD(sc->sc_parent, isrc);
126 }
127
128
129 static void
130 omap4_wugen_post_ithread(device_t dev, struct intr_irqsrc *isrc)
131 {
132         struct omap4_wugen_sc *sc = device_get_softc(dev);
133
134         PIC_POST_ITHREAD(sc->sc_parent, isrc);
135 }
136
137 static void
138 omap4_wugen_post_filter(device_t dev, struct intr_irqsrc *isrc)
139 {
140         struct omap4_wugen_sc *sc = device_get_softc(dev);
141
142         PIC_POST_FILTER(sc->sc_parent, isrc);
143 }
144
145 #ifdef SMP
146 static int
147 omap4_wugen_bind_intr(device_t dev, struct intr_irqsrc *isrc)
148 {
149         struct omap4_wugen_sc *sc = device_get_softc(dev);
150
151         return (PIC_BIND_INTR(sc->sc_parent, isrc));
152 }
153 #endif
154
155 static int
156 omap4_wugen_probe(device_t dev)
157 {
158
159         if (!ofw_bus_status_okay(dev))
160                 return (ENXIO);
161
162         if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
163                 return (ENXIO);
164
165         return (BUS_PROBE_DEFAULT);
166 }
167
168 static int
169 omap4_wugen_detach(device_t dev)
170 {
171         struct omap4_wugen_sc *sc;
172
173         sc = device_get_softc(dev);
174         if (sc->sc_mem_res != NULL) {
175                 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
176                 sc->sc_mem_res = NULL;
177         }
178         return (0);
179 }
180
181 static int
182 omap4_wugen_attach(device_t dev)
183 {
184         struct omap4_wugen_sc *sc;
185         phandle_t node;
186         phandle_t parent_xref;
187         int rid, rv;
188
189         sc = device_get_softc(dev);
190         sc->sc_dev = dev;
191         node = ofw_bus_get_node(dev);
192
193         rv = OF_getencprop(node, "interrupt-parent", &parent_xref,
194             sizeof(parent_xref));
195         if (rv <= 0) {
196                 device_printf(dev, "can't read parent node property\n");
197                 goto fail;
198         }
199         sc->sc_parent = OF_device_from_xref(parent_xref);
200         if (sc->sc_parent == NULL) {
201                 device_printf(dev, "can't find parent controller\n");
202                 goto fail;
203         }
204
205         rid = 0;
206         sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
207             RF_ACTIVE);
208         if (sc->sc_mem_res == NULL) {
209                 device_printf(dev, "can't allocate resources\n");
210                 return (ENXIO);
211         }
212
213         if (intr_pic_register(dev, OF_xref_from_node(node)) == NULL) {
214                 device_printf(dev, "can't register PIC\n");
215                 goto fail;
216         }
217         return (0);
218
219 fail:
220         omap4_wugen_detach(dev);
221         return (ENXIO);
222 }
223
224 static device_method_t omap4_wugen_methods[] = {
225         DEVMETHOD(device_probe,         omap4_wugen_probe),
226         DEVMETHOD(device_attach,        omap4_wugen_attach),
227         DEVMETHOD(device_detach,        omap4_wugen_detach),
228
229         /* Interrupt controller interface */
230         DEVMETHOD(pic_activate_intr,    omap4_wugen_activate_intr),
231         DEVMETHOD(pic_disable_intr,     omap4_wugen_disable_intr),
232         DEVMETHOD(pic_enable_intr,      omap4_wugen_enable_intr),
233         DEVMETHOD(pic_map_intr,         omap4_wugen_map_intr),
234         DEVMETHOD(pic_deactivate_intr,  omap4_wugen_deactivate_intr),
235         DEVMETHOD(pic_setup_intr,       omap4_wugen_setup_intr),
236         DEVMETHOD(pic_teardown_intr,    omap4_wugen_teardown_intr),
237         DEVMETHOD(pic_pre_ithread,      omap4_wugen_pre_ithread),
238         DEVMETHOD(pic_post_ithread,     omap4_wugen_post_ithread),
239         DEVMETHOD(pic_post_filter,      omap4_wugen_post_filter),
240 #ifdef SMP
241         DEVMETHOD(pic_bind_intr,        omap4_wugen_bind_intr),
242 #endif
243         DEVMETHOD_END
244 };
245 devclass_t omap4_wugen_devclass;
246 DEFINE_CLASS_0(omap4_wugen, omap4_wugen_driver, omap4_wugen_methods,
247     sizeof(struct omap4_wugen_sc));
248 EARLY_DRIVER_MODULE(omap4_wugen, simplebus, omap4_wugen_driver,
249     omap4_wugen_devclass, NULL, NULL,
250     BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE + 1);