]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/ti/omap4/omap4_wugen.c
arm ti: Remove unused devclass arguments to DRIVER_MODULE.
[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 static void
129 omap4_wugen_post_ithread(device_t dev, struct intr_irqsrc *isrc)
130 {
131         struct omap4_wugen_sc *sc = device_get_softc(dev);
132
133         PIC_POST_ITHREAD(sc->sc_parent, isrc);
134 }
135
136 static void
137 omap4_wugen_post_filter(device_t dev, struct intr_irqsrc *isrc)
138 {
139         struct omap4_wugen_sc *sc = device_get_softc(dev);
140
141         PIC_POST_FILTER(sc->sc_parent, isrc);
142 }
143
144 #ifdef SMP
145 static int
146 omap4_wugen_bind_intr(device_t dev, struct intr_irqsrc *isrc)
147 {
148         struct omap4_wugen_sc *sc = device_get_softc(dev);
149
150         return (PIC_BIND_INTR(sc->sc_parent, isrc));
151 }
152 #endif
153
154 static int
155 omap4_wugen_probe(device_t dev)
156 {
157
158         if (!ofw_bus_status_okay(dev))
159                 return (ENXIO);
160
161         if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
162                 return (ENXIO);
163
164         return (BUS_PROBE_DEFAULT);
165 }
166
167 static int
168 omap4_wugen_detach(device_t dev)
169 {
170         struct omap4_wugen_sc *sc;
171
172         sc = device_get_softc(dev);
173         if (sc->sc_mem_res != NULL) {
174                 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
175                 sc->sc_mem_res = NULL;
176         }
177         return (0);
178 }
179
180 static int
181 omap4_wugen_attach(device_t dev)
182 {
183         struct omap4_wugen_sc *sc;
184         phandle_t node;
185         phandle_t parent_xref;
186         int rid, rv;
187
188         sc = device_get_softc(dev);
189         sc->sc_dev = dev;
190         node = ofw_bus_get_node(dev);
191
192         rv = OF_getencprop(node, "interrupt-parent", &parent_xref,
193             sizeof(parent_xref));
194         if (rv <= 0) {
195                 device_printf(dev, "can't read parent node property\n");
196                 goto fail;
197         }
198         sc->sc_parent = OF_device_from_xref(parent_xref);
199         if (sc->sc_parent == NULL) {
200                 device_printf(dev, "can't find parent controller\n");
201                 goto fail;
202         }
203
204         rid = 0;
205         sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
206             RF_ACTIVE);
207         if (sc->sc_mem_res == NULL) {
208                 device_printf(dev, "can't allocate resources\n");
209                 return (ENXIO);
210         }
211
212         if (intr_pic_register(dev, OF_xref_from_node(node)) == NULL) {
213                 device_printf(dev, "can't register PIC\n");
214                 goto fail;
215         }
216         return (0);
217
218 fail:
219         omap4_wugen_detach(dev);
220         return (ENXIO);
221 }
222
223 static device_method_t omap4_wugen_methods[] = {
224         DEVMETHOD(device_probe,         omap4_wugen_probe),
225         DEVMETHOD(device_attach,        omap4_wugen_attach),
226         DEVMETHOD(device_detach,        omap4_wugen_detach),
227
228         /* Interrupt controller interface */
229         DEVMETHOD(pic_activate_intr,    omap4_wugen_activate_intr),
230         DEVMETHOD(pic_disable_intr,     omap4_wugen_disable_intr),
231         DEVMETHOD(pic_enable_intr,      omap4_wugen_enable_intr),
232         DEVMETHOD(pic_map_intr,         omap4_wugen_map_intr),
233         DEVMETHOD(pic_deactivate_intr,  omap4_wugen_deactivate_intr),
234         DEVMETHOD(pic_setup_intr,       omap4_wugen_setup_intr),
235         DEVMETHOD(pic_teardown_intr,    omap4_wugen_teardown_intr),
236         DEVMETHOD(pic_pre_ithread,      omap4_wugen_pre_ithread),
237         DEVMETHOD(pic_post_ithread,     omap4_wugen_post_ithread),
238         DEVMETHOD(pic_post_filter,      omap4_wugen_post_filter),
239 #ifdef SMP
240         DEVMETHOD(pic_bind_intr,        omap4_wugen_bind_intr),
241 #endif
242         DEVMETHOD_END
243 };
244
245 DEFINE_CLASS_0(omap4_wugen, omap4_wugen_driver, omap4_wugen_methods,
246     sizeof(struct omap4_wugen_sc));
247 EARLY_DRIVER_MODULE(omap4_wugen, simplebus, omap4_wugen_driver, NULL, NULL,
248     BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE + 1);