diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2017-02-25 16:53:10 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2017-02-25 16:53:10 +0000 |
commit | 3f9cdfb0e749a8ee3a5e441fb752b55bbec3509c (patch) | |
tree | 235af1d9db0c4f490a861aeec2174869ee649108 /sys | |
parent | 2b5bdee33543957e19ded870b22ddcc8086c432f (diff) |
MSI interrupts are established in a different way as well. Instead of
simply hooking up the interrupt handler and returning an MD cookie, we
need to pass back information for the PCI controller to configure its
interrupt correctly. For this, add another establish routine into the
FDT-based interrupt API which looks up msi-controller nodes and calls
their MSI-specific establish function if requested.
ok kettenis@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/arm64/arm64/intr.c | 46 | ||||
-rw-r--r-- | sys/arch/arm64/include/intr.h | 6 |
2 files changed, 49 insertions, 3 deletions
diff --git a/sys/arch/arm64/arm64/intr.c b/sys/arch/arm64/arm64/intr.c index 4eadea2bc73..53ab09c2266 100644 --- a/sys/arch/arm64/arm64/intr.c +++ b/sys/arch/arm64/arm64/intr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.c,v 1.4 2017/02/24 17:16:41 patrick Exp $ */ +/* $OpenBSD: intr.c,v 1.5 2017/02/25 16:53:09 patrick Exp $ */ /* * Copyright (c) 2011 Dale Rahn <drahn@openbsd.org> * @@ -28,6 +28,7 @@ #include <dev/ofw/openfirm.h> uint32_t arm_intr_get_parent(int); +uint32_t arm_intr_msi_get_parent(int); void *arm_intr_prereg_establish_fdt(void *, int *, int, int (*)(void *), void *, char *); @@ -81,6 +82,19 @@ arm_intr_get_parent(int node) return phandle; } +uint32_t +arm_intr_msi_get_parent(int node) +{ + uint32_t phandle = 0; + + while (node && !phandle) { + phandle = OF_getpropint(node, "msi-parent", 0); + node = OF_parent(node); + } + + return phandle; +} + /* * Interrupt pre-registration. * @@ -187,7 +201,7 @@ arm_intr_register_fdt(struct interrupt_controller *ic) ic->ic_cells = OF_getpropint(ic->ic_node, "#interrupt-cells", 0); ic->ic_phandle = OF_getpropint(ic->ic_node, "phandle", 0); - if (ic->ic_cells == 0 || ic->ic_phandle == 0) + if (ic->ic_phandle == 0) return; KASSERT(ic->ic_cells <= MAX_INTERRUPT_CELLS); @@ -364,6 +378,34 @@ arm_intr_establish_fdt_imap(int node, int *reg, int nreg, int acells, return ih; } +void * +arm_intr_establish_fdt_msi(int node, uint64_t *addr, uint64_t *data, + int level, int (*func)(void *), void *cookie, char *name) +{ + struct interrupt_controller *ic; + struct arm_intr_handle *ih; + uint32_t phandle; + void *val = NULL; + + phandle = arm_intr_msi_get_parent(node); + LIST_FOREACH(ic, &interrupt_controllers, ic_list) { + if (ic->ic_phandle == phandle) + break; + } + + if (ic == NULL || ic->ic_establish_msi == NULL) + return NULL; + + val = ic->ic_establish_msi(ic->ic_cookie, addr, data, + level, func, cookie, name); + + ih = malloc(sizeof(*ih), M_DEVBUF, M_WAITOK); + ih->ih_ic = ic; + ih->ih_ih = val; + + return ih; +} + void arm_intr_disestablish_fdt(void *cookie) { diff --git a/sys/arch/arm64/include/intr.h b/sys/arch/arm64/include/intr.h index a4f2a65a463..ef788d965e9 100644 --- a/sys/arch/arm64/include/intr.h +++ b/sys/arch/arm64/include/intr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.h,v 1.3 2017/02/24 17:16:41 patrick Exp $ */ +/* $OpenBSD: intr.h,v 1.4 2017/02/25 16:53:09 patrick Exp $ */ /* * Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com) @@ -134,6 +134,8 @@ struct interrupt_controller { void *ic_cookie; void *(*ic_establish)(void *, int *, int, int (*)(void *), void *, char *); + void *(*ic_establish_msi)(void *, uint64_t *, uint64_t *, int, + int (*)(void *), void *, char *); void (*ic_disestablish)(void *); LIST_ENTRY(interrupt_controller) ic_list; @@ -149,6 +151,8 @@ void *arm_intr_establish_fdt_idx(int, int, int, int (*)(void *), void *, char *); void *arm_intr_establish_fdt_imap(int, int *, int, int, int, int (*)(void *), void *, char *); +void *arm_intr_establish_fdt_msi(int, uint64_t *, uint64_t *, int , + int (*)(void *), void *, char *); void arm_intr_disestablish_fdt(void *); void *arm_intr_parent_establish_fdt(void *, int *, int, |