Deleted Added
full compact
mpic.c (296893) mpic.c (297539)
1/*-
2 * Copyright (c) 2006 Benno Rice.
3 * Copyright (C) 2007-2011 MARVELL INTERNATIONAL LTD.
4 * Copyright (c) 2012 Semihalf.
5 * All rights reserved.
6 *
7 * Developed by Semihalf.
8 *

--- 17 unchanged lines hidden (view full) ---

26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * from: FreeBSD: //depot/projects/arm/src/sys/arm/xscale/pxa2x0/pxa2x0_icu.c, rev 1
30 * from: FreeBSD: src/sys/arm/mv/ic.c,v 1.5 2011/02/08 01:49:30
31 */
32
33#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2006 Benno Rice.
3 * Copyright (C) 2007-2011 MARVELL INTERNATIONAL LTD.
4 * Copyright (c) 2012 Semihalf.
5 * All rights reserved.
6 *
7 * Developed by Semihalf.
8 *

--- 17 unchanged lines hidden (view full) ---

26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * from: FreeBSD: //depot/projects/arm/src/sys/arm/xscale/pxa2x0/pxa2x0_icu.c, rev 1
30 * from: FreeBSD: src/sys/arm/mv/ic.c,v 1.5 2011/02/08 01:49:30
31 */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/arm/mv/mpic.c 296893 2016-03-15 06:06:09Z wma $");
34__FBSDID("$FreeBSD: head/sys/arm/mv/mpic.c 297539 2016-04-04 09:15:25Z skra $");
35
36#include "opt_platform.h"
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/bus.h>
41#include <sys/kernel.h>
42#include <sys/cpuset.h>

--- 50 unchanged lines hidden (view full) ---

93#define MPIC_CTP 0x40
94#define MPIC_IIACK 0x44
95#define MPIC_ISM 0x48
96#define MPIC_ICM 0x4c
97#define MPIC_ERR_MASK 0xe50
98
99#define MPIC_PPI 32
100
35
36#include "opt_platform.h"
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/bus.h>
41#include <sys/kernel.h>
42#include <sys/cpuset.h>

--- 50 unchanged lines hidden (view full) ---

93#define MPIC_CTP 0x40
94#define MPIC_IIACK 0x44
95#define MPIC_ISM 0x48
96#define MPIC_ICM 0x4c
97#define MPIC_ERR_MASK 0xe50
98
99#define MPIC_PPI 32
100
101#ifdef ARM_INTRNG
102struct mv_mpic_irqsrc {
103 struct intr_irqsrc mmi_isrc;
104 u_int mmi_irq;
105};
106#endif
107
101struct mv_mpic_softc {
102 device_t sc_dev;
103 struct resource * mpic_res[4];
104 bus_space_tag_t mpic_bst;
105 bus_space_handle_t mpic_bsh;
106 bus_space_tag_t cpu_bst;
107 bus_space_handle_t cpu_bsh;
108 bus_space_tag_t drbl_bst;
109 bus_space_handle_t drbl_bsh;
110 struct mtx mtx;
108struct mv_mpic_softc {
109 device_t sc_dev;
110 struct resource * mpic_res[4];
111 bus_space_tag_t mpic_bst;
112 bus_space_handle_t mpic_bsh;
113 bus_space_tag_t cpu_bst;
114 bus_space_handle_t cpu_bsh;
115 bus_space_tag_t drbl_bst;
116 bus_space_handle_t drbl_bsh;
117 struct mtx mtx;
111
112 struct intr_irqsrc ** mpic_isrcs;
118#ifdef ARM_INTRNG
119 struct mv_mpic_irqsrc * mpic_isrcs;
120#endif
113 int nirqs;
114 void * intr_hand;
115};
116
117static struct resource_spec mv_mpic_spec[] = {
118 { SYS_RES_MEMORY, 0, RF_ACTIVE },
119 { SYS_RES_MEMORY, 1, RF_ACTIVE },
120 { SYS_RES_MEMORY, 2, RF_ACTIVE | RF_OPTIONAL },

--- 51 unchanged lines hidden (view full) ---

172
173 if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
174 return (ENXIO);
175
176 device_set_desc(dev, "Marvell Integrated Interrupt Controller");
177 return (0);
178}
179
121 int nirqs;
122 void * intr_hand;
123};
124
125static struct resource_spec mv_mpic_spec[] = {
126 { SYS_RES_MEMORY, 0, RF_ACTIVE },
127 { SYS_RES_MEMORY, 1, RF_ACTIVE },
128 { SYS_RES_MEMORY, 2, RF_ACTIVE | RF_OPTIONAL },

--- 51 unchanged lines hidden (view full) ---

180
181 if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
182 return (ENXIO);
183
184 device_set_desc(dev, "Marvell Integrated Interrupt Controller");
185 return (0);
186}
187
188#ifdef ARM_INTRNG
180static int
189static int
190mv_mpic_register_isrcs(struct mv_mpic_softc *sc)
191{
192 int error;
193 uint32_t irq;
194 struct intr_irqsrc *isrc;
195 const char *name;
196
197 sc->mpic_isrcs = malloc(sc->nirqs * sizeof (*sc->mpic_isrcs), M_DEVBUF,
198 M_WAITOK | M_ZERO);
199
200 name = device_get_nameunit(sc->sc_dev);
201 for (irq = 0; irq < sc->nirqs; irq++) {
202 sc->mpic_isrcs[irq].mmi_irq = irq;
203
204 isrc = &sc->mpic_isrcs[irq].mmi_isrc;
205 if (irq < MPIC_PPI) {
206 error = intr_isrc_register(isrc, sc->sc_dev,
207 INTR_ISRCF_PPI, "%s", name);
208 } else {
209 error = intr_isrc_register(isrc, sc->sc_dev, 0, "%s",
210 name);
211 }
212 if (error != 0) {
213 /* XXX call intr_isrc_deregister() */
214 device_printf(sc->sc_dev, "%s failed", __func__);
215 return (error);
216 }
217 }
218 return (0);
219}
220#endif
221
222static int
181mv_mpic_attach(device_t dev)
182{
183 struct mv_mpic_softc *sc;
184 int error;
185 uint32_t val;
186
187 sc = (struct mv_mpic_softc *)device_get_softc(dev);
188

--- 33 unchanged lines hidden (view full) ---

222 bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh,
223 MPIC_CTRL, 1);
224 MPIC_CPU_WRITE(mv_mpic_sc, MPIC_CTP, 0);
225
226 val = MPIC_READ(mv_mpic_sc, MPIC_CTRL);
227 sc->nirqs = MPIC_CTRL_NIRQS(val);
228
229#ifdef ARM_INTRNG
223mv_mpic_attach(device_t dev)
224{
225 struct mv_mpic_softc *sc;
226 int error;
227 uint32_t val;
228
229 sc = (struct mv_mpic_softc *)device_get_softc(dev);
230

--- 33 unchanged lines hidden (view full) ---

264 bus_space_write_4(mv_mpic_sc->mpic_bst, mv_mpic_sc->mpic_bsh,
265 MPIC_CTRL, 1);
266 MPIC_CPU_WRITE(mv_mpic_sc, MPIC_CTP, 0);
267
268 val = MPIC_READ(mv_mpic_sc, MPIC_CTRL);
269 sc->nirqs = MPIC_CTRL_NIRQS(val);
270
271#ifdef ARM_INTRNG
230 sc->mpic_isrcs = malloc(sc->nirqs * sizeof (*sc->mpic_isrcs), M_DEVBUF,
231 M_WAITOK | M_ZERO);
232
272 if (mv_mpic_register_isrcs(sc) != 0) {
273 device_printf(dev, "could not register PIC ISRCs\n");
274 bus_release_resources(dev, mv_mpic_spec, sc->mpic_res);
275 return (ENXIO);
276 }
233 if (intr_pic_register(dev, OF_xref_from_device(dev)) != 0) {
234 device_printf(dev, "could not register PIC\n");
235 bus_release_resources(dev, mv_mpic_spec, sc->mpic_res);
236 return (ENXIO);
237 }
238#endif
239
240 mpic_unmask_msi();
241
242 return (0);
243}
244
245#ifdef ARM_INTRNG
246static int
247mpic_intr(void *arg)
248{
249 struct mv_mpic_softc *sc;
277 if (intr_pic_register(dev, OF_xref_from_device(dev)) != 0) {
278 device_printf(dev, "could not register PIC\n");
279 bus_release_resources(dev, mv_mpic_spec, sc->mpic_res);
280 return (ENXIO);
281 }
282#endif
283
284 mpic_unmask_msi();
285
286 return (0);
287}
288
289#ifdef ARM_INTRNG
290static int
291mpic_intr(void *arg)
292{
293 struct mv_mpic_softc *sc;
250 struct trapframe *tf;
251 struct intr_irqsrc *isrc;
252 uint32_t cause, irqsrc;
253 unsigned int irq;
254 u_int cpuid;
255
256 sc = arg;
294 uint32_t cause, irqsrc;
295 unsigned int irq;
296 u_int cpuid;
297
298 sc = arg;
257 tf = curthread->td_intr_frame;
258 cpuid = PCPU_GET(cpuid);
259 irq = 0;
260
261 for (cause = MPIC_CPU_READ(sc, MPIC_PPI_CAUSE); cause > 0;
262 cause >>= 1, irq++) {
263 if (cause & 1) {
264 irqsrc = MPIC_READ(sc, MPIC_INT_CTL(irq));
265 if ((irqsrc & MPIC_INT_IRQ_FIQ_MASK(cpuid)) == 0)
266 continue;
299 cpuid = PCPU_GET(cpuid);
300 irq = 0;
301
302 for (cause = MPIC_CPU_READ(sc, MPIC_PPI_CAUSE); cause > 0;
303 cause >>= 1, irq++) {
304 if (cause & 1) {
305 irqsrc = MPIC_READ(sc, MPIC_INT_CTL(irq));
306 if ((irqsrc & MPIC_INT_IRQ_FIQ_MASK(cpuid)) == 0)
307 continue;
267 isrc = sc->mpic_isrcs[irq];
268 if (isrc == NULL) {
269 device_printf(sc->sc_dev, "Stray interrupt %u detected\n", irq);
308 if (intr_isrc_dispatch(&sc->mpic_isrcs[irq].mmi_isrc,
309 curthread->td_intr_frame) != 0) {
270 mpic_mask_irq(irq);
310 mpic_mask_irq(irq);
271 continue;
311 device_printf(sc->sc_dev, "Stray irq %u "
312 "disabled\n", irq);
272 }
313 }
273 intr_irq_dispatch(isrc, tf);
274 }
275 }
276
277 return (FILTER_HANDLED);
278}
279
314 }
315 }
316
317 return (FILTER_HANDLED);
318}
319
280static int
281mpic_attach_isrc(struct mv_mpic_softc *sc, struct intr_irqsrc *isrc, u_int irq)
320static void
321mpic_disable_intr(device_t dev, struct intr_irqsrc *isrc)
282{
322{
283 const char *name;
323 u_int irq;
284
324
285 mtx_lock_spin(&sc->mtx);
286 if (sc->mpic_isrcs[irq] != NULL) {
287 mtx_unlock_spin(&sc->mtx);
288 return (sc->mpic_isrcs[irq] == isrc ? 0 : EEXIST);
289 }
290 sc->mpic_isrcs[irq] = isrc;
291 isrc->isrc_data = irq;
292 mtx_unlock_spin(&sc->mtx);
293
294 name = device_get_nameunit(sc->sc_dev);
295 intr_irq_set_name(isrc, "%s", name);
296
297 return (0);
325 irq = ((struct mv_mpic_irqsrc *)isrc)->mmi_irq;
326 mpic_mask_irq(irq);
298}
299
327}
328
300#ifdef FDT
301static int
302mpic_map_fdt(struct mv_mpic_softc *sc, struct intr_irqsrc *isrc, u_int *irqp)
329static void
330mpic_enable_intr(device_t dev, struct intr_irqsrc *isrc)
303{
304 u_int irq;
331{
332 u_int irq;
305 int error;
306
333
307 if (isrc->isrc_ncells != 1)
308 return (EINVAL);
309
310 irq = isrc->isrc_cells[0];
311
312 error = mpic_attach_isrc(sc, isrc, irq);
313 if (error != 0)
314 return (error);
315
316 isrc->isrc_nspc_num = irq;
317 isrc->isrc_trig = INTR_TRIGGER_CONFORM;
318 isrc->isrc_pol = INTR_POLARITY_CONFORM;
319 isrc->isrc_nspc_type = INTR_IRQ_NSPC_PLAIN;
320
321 *irqp = irq;
322
323 return (0);
334 irq = ((struct mv_mpic_irqsrc *)isrc)->mmi_irq;
335 mpic_unmask_irq(irq);
324}
336}
325#endif
326
327static int
337
338static int
328mpic_register(device_t dev, struct intr_irqsrc *isrc, boolean_t *is_percpu)
339mpic_map_intr(device_t dev, struct intr_map_data *data,
340 struct intr_irqsrc **isrcp)
329{
330 struct mv_mpic_softc *sc;
341{
342 struct mv_mpic_softc *sc;
331 int error;
332 u_int irq = 0;
333
334 sc = device_get_softc(dev);
335
343
344 sc = device_get_softc(dev);
345
336#ifdef FDT
337 if (isrc->isrc_type == INTR_ISRCT_FDT)
338 error = mpic_map_fdt(sc, isrc, &irq);
339 else
340#endif
341 error = EINVAL;
346 if (data->type != INTR_MAP_DATA_FDT || data->fdt.ncells !=1 ||
347 data->fdt.cells[0] >= sc->nirqs)
348 return (EINVAL);
342
349
343 if (error == 0)
344 *is_percpu = irq < MPIC_PPI;
345
346 return (error);
350 *isrcp = &sc->mpic_isrcs[data->fdt.cells[0]].mmi_isrc;
351 return (0);
347}
348
349static void
352}
353
354static void
350mpic_disable_source(device_t dev, struct intr_irqsrc *isrc)
351{
352 u_int irq;
353
354 irq = isrc->isrc_data;
355 mpic_mask_irq(irq);
356}
357
358static void
359mpic_enable_source(device_t dev, struct intr_irqsrc *isrc)
360{
361 u_int irq;
362
363 irq = isrc->isrc_data;
364 mpic_unmask_irq(irq);
365}
366static void
367mpic_pre_ithread(device_t dev, struct intr_irqsrc *isrc)
368{
369
355mpic_pre_ithread(device_t dev, struct intr_irqsrc *isrc)
356{
357
370 mpic_disable_source(dev, isrc);
358 mpic_disable_intr(dev, isrc);
371}
372
373static void
374mpic_post_ithread(device_t dev, struct intr_irqsrc *isrc)
375{
376
359}
360
361static void
362mpic_post_ithread(device_t dev, struct intr_irqsrc *isrc)
363{
364
377 mpic_enable_source(dev, isrc);
365 mpic_enable_intr(dev, isrc);
378}
379#endif
380
381static device_method_t mv_mpic_methods[] = {
382 DEVMETHOD(device_probe, mv_mpic_probe),
383 DEVMETHOD(device_attach, mv_mpic_attach),
384
385#ifdef ARM_INTRNG
366}
367#endif
368
369static device_method_t mv_mpic_methods[] = {
370 DEVMETHOD(device_probe, mv_mpic_probe),
371 DEVMETHOD(device_attach, mv_mpic_attach),
372
373#ifdef ARM_INTRNG
386 DEVMETHOD(pic_register, mpic_register),
387 DEVMETHOD(pic_disable_source, mpic_disable_source),
388 DEVMETHOD(pic_enable_source, mpic_enable_source),
374 DEVMETHOD(pic_disable_intr, mpic_disable_intr),
375 DEVMETHOD(pic_enable_intr, mpic_enable_intr),
376 DEVMETHOD(pic_map_intr, mpic_map_intr),
389 DEVMETHOD(pic_post_ithread, mpic_post_ithread),
390 DEVMETHOD(pic_pre_ithread, mpic_pre_ithread),
391#endif
392 { 0, 0 }
393};
394
395static driver_t mv_mpic_driver = {
396 "mpic",

--- 247 unchanged lines hidden ---
377 DEVMETHOD(pic_post_ithread, mpic_post_ithread),
378 DEVMETHOD(pic_pre_ithread, mpic_pre_ithread),
379#endif
380 { 0, 0 }
381};
382
383static driver_t mv_mpic_driver = {
384 "mpic",

--- 247 unchanged lines hidden ---