Changeset View
Standalone View
sys/mips/mips/mips_pic.c
Show First 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | |||||
#include "pic_if.h" | #include "pic_if.h" | ||||
#define NHARD_IRQS 6 | #define NHARD_IRQS 6 | ||||
#define NSOFT_IRQS 2 | #define NSOFT_IRQS 2 | ||||
#define NREAL_IRQS (NHARD_IRQS + NSOFT_IRQS) | #define NREAL_IRQS (NHARD_IRQS + NSOFT_IRQS) | ||||
static int mips_pic_intr(void *); | static int mips_pic_intr(void *); | ||||
struct mips_pic_irqsrc { | |||||
struct intr_irqsrc isrc; | |||||
struct resource *res; | |||||
u_int irq; | |||||
}; | |||||
struct mips_pic_softc { | struct mips_pic_softc { | ||||
device_t pic_dev; | device_t pic_dev; | ||||
struct intr_irqsrc * pic_irqs[NREAL_IRQS]; | struct mips_pic_irqsrc pic_irqs[NREAL_IRQS]; | ||||
struct rman pic_irq_rman; | |||||
kan: Come to think of it, what is the purpose of rman here? It serves to useful purpose but to… | |||||
skraUnsubmitted Not Done Inline ActionsAnother solution is to change interrupt number argument to struct resource pointer in cpu_establish_hardintr() and cpu_establish_softintr(). And whoever wants to use these functions should get a struct resource by call to bus_allocate_resource(). BTW, INTRNG doesn't plug into resource allocation properly only for interrupt numbers get from ofw_bus_map_intr(). And it should be fixed soon. skra: Another solution is to change interrupt number argument to struct resource pointer in… | |||||
sgalabovAuthorUnsubmitted Not Done Inline ActionsThat's true, but I couldn't think of a cleaner way to satisfy intr_setup_irq()'s requirement for a struct resource * parameter. And although I could go and change all users of cpu_establish_*_intr, this seems even more troublesome at the moment. sgalabov: That's true, but I couldn't think of a cleaner way to satisfy intr_setup_irq()'s requirement… | |||||
skraUnsubmitted Not Done Inline ActionsI'm okay with it, even if it's quite weird. It was just a note from me. However, INTRNG is meant to be used by bus drivers in their bus methods where struct resource is always present. So if it's used another way, curious things come. skra: I'm okay with it, even if it's quite weird. It was just a note from me. However, INTRNG is… | |||||
struct mtx mutex; | struct mtx mutex; | ||||
uint32_t nirqs; | uint32_t nirqs; | ||||
}; | }; | ||||
static struct mips_pic_softc *pic_sc; | static struct mips_pic_softc *pic_sc; | ||||
#define PIC_INTR_ISRC(sc, irq) (&(sc)->pic_irqs[(irq)].isrc) | |||||
#ifdef FDT | #ifdef FDT | ||||
static struct ofw_compat_data compat_data[] = { | static struct ofw_compat_data compat_data[] = { | ||||
{"mti,cpu-interrupt-controller", true}, | {"mti,cpu-interrupt-controller", true}, | ||||
{NULL, false} | {NULL, false} | ||||
}; | }; | ||||
#endif | #endif | ||||
#ifndef FDT | #ifndef FDT | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | |||||
#ifdef FDT | #ifdef FDT | ||||
return (OF_xref_from_node(ofw_bus_get_node(dev))); | return (OF_xref_from_node(ofw_bus_get_node(dev))); | ||||
#else | #else | ||||
return (0); | return (0); | ||||
#endif | #endif | ||||
} | } | ||||
static int | static int | ||||
mips_pic_register_isrcs(struct mips_pic_softc *sc) | |||||
{ | |||||
int error; | |||||
uint32_t irq, i; | |||||
struct intr_irqsrc *isrc; | |||||
const char *name; | |||||
name = device_get_nameunit(sc->pic_dev); | |||||
for (irq = 0; irq < sc->nirqs; irq++) { | |||||
sc->pic_irqs[irq].irq = irq; | |||||
sc->pic_irqs[irq].res = rman_reserve_resource(&sc->pic_irq_rman, | |||||
irq, irq, 1, RF_ACTIVE, sc->pic_dev); | |||||
if (sc->pic_irqs[irq].res == NULL) { | |||||
device_printf(sc->pic_dev, | |||||
"%s failed to alloc resource for irq %d", | |||||
__func__, irq); | |||||
return (ENOMEM); | |||||
} | |||||
isrc = PIC_INTR_ISRC(sc, irq); | |||||
error = intr_isrc_register(isrc, sc->pic_dev, 0, "%s", name); | |||||
if (error != 0) { | |||||
for (i = 0; i < irq; i++) { | |||||
Done Inline ActionsThis needs to be addressed before commit? kan: This needs to be addressed before commit?
| |||||
intr_isrc_deregister(PIC_INTR_ISRC(sc, i)); | |||||
} | |||||
device_printf(sc->pic_dev, "%s failed", __func__); | |||||
return (error); | |||||
} | |||||
} | |||||
return (0); | |||||
} | |||||
static int | |||||
mips_pic_attach(device_t dev) | mips_pic_attach(device_t dev) | ||||
{ | { | ||||
struct mips_pic_softc *sc; | struct mips_pic_softc *sc; | ||||
intptr_t xref = pic_xref(dev); | intptr_t xref = pic_xref(dev); | ||||
if (pic_sc) | if (pic_sc) | ||||
return (ENXIO); | return (ENXIO); | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
sc->pic_dev = dev; | sc->pic_dev = dev; | ||||
pic_sc = sc; | pic_sc = sc; | ||||
/* Initialize mutex */ | /* Initialize mutex */ | ||||
mtx_init(&sc->mutex, "PIC lock", "", MTX_SPIN); | mtx_init(&sc->mutex, "PIC lock", "", MTX_SPIN); | ||||
/* Set the number of interrupts */ | /* Set the number of interrupts */ | ||||
sc->nirqs = nitems(sc->pic_irqs); | sc->nirqs = nitems(sc->pic_irqs); | ||||
/* Init the IRQ rman */ | |||||
sc->pic_irq_rman.rm_type = RMAN_ARRAY; | |||||
sc->pic_irq_rman.rm_descr = "MIPS PIC IRQs"; | |||||
if (rman_init(&sc->pic_irq_rman) != 0 || | |||||
rman_manage_region(&sc->pic_irq_rman, 0, sc->nirqs - 1) != 0) { | |||||
Done Inline Actions0, sc->nirqs - 1 ? kan: 0, sc->nirqs - 1 ? | |||||
device_printf(dev, "failed to setup IRQ rman\n"); | |||||
goto cleanup; | |||||
} | |||||
/* Register the interrupts */ | |||||
if (mips_pic_register_isrcs(sc) != 0) { | |||||
device_printf(dev, "could not register PIC ISRCs\n"); | |||||
goto cleanup; | |||||
} | |||||
/* | /* | ||||
* Now, when everything is initialized, it's right time to | * Now, when everything is initialized, it's right time to | ||||
* register interrupt controller to interrupt framefork. | * register interrupt controller to interrupt framefork. | ||||
*/ | */ | ||||
if (intr_pic_register(dev, xref) != 0) { | if (intr_pic_register(dev, xref) != 0) { | ||||
device_printf(dev, "could not register PIC\n"); | device_printf(dev, "could not register PIC\n"); | ||||
goto cleanup; | goto cleanup; | ||||
} | } | ||||
/* Claim our root controller role */ | /* Claim our root controller role */ | ||||
if (intr_pic_claim_root(dev, xref, mips_pic_intr, sc, 0) != 0) { | if (intr_pic_claim_root(dev, xref, mips_pic_intr, sc, 0) != 0) { | ||||
device_printf(dev, "could not set PIC as a root\n"); | device_printf(dev, "could not set PIC as a root\n"); | ||||
intr_pic_unregister(dev, xref); | intr_pic_deregister(dev, xref); | ||||
goto cleanup; | goto cleanup; | ||||
} | } | ||||
return (0); | return (0); | ||||
cleanup: | cleanup: | ||||
return(ENXIO); | return(ENXIO); | ||||
} | } | ||||
int | int | ||||
mips_pic_intr(void *arg) | mips_pic_intr(void *arg) | ||||
{ | { | ||||
struct mips_pic_softc *sc = arg; | struct mips_pic_softc *sc = arg; | ||||
register_t cause, status; | register_t cause, status; | ||||
struct intr_irqsrc *isrc; | |||||
int i, intr; | int i, intr; | ||||
cause = mips_rd_cause(); | cause = mips_rd_cause(); | ||||
status = mips_rd_status(); | status = mips_rd_status(); | ||||
intr = (cause & MIPS_INT_MASK) >> 8; | intr = (cause & MIPS_INT_MASK) >> 8; | ||||
/* | /* | ||||
* Do not handle masked interrupts. They were masked by | * Do not handle masked interrupts. They were masked by | ||||
* pre_ithread function (mips_mask_XXX_intr) and will be | * pre_ithread function (mips_mask_XXX_intr) and will be | ||||
* unmasked once ithread is through with handler | * unmasked once ithread is through with handler | ||||
*/ | */ | ||||
intr &= (status & MIPS_INT_MASK) >> 8; | intr &= (status & MIPS_INT_MASK) >> 8; | ||||
while ((i = fls(intr)) != 0) { | while ((i = fls(intr)) != 0) { | ||||
i--; /* Get a 0-offset interrupt. */ | i--; /* Get a 0-offset interrupt. */ | ||||
intr &= ~(1 << i); | intr &= ~(1 << i); | ||||
isrc = sc->pic_irqs[i]; | if (intr_isrc_dispatch(PIC_INTR_ISRC(sc, i), | ||||
if (isrc == NULL) { | curthread->td_intr_frame) != 0) { | ||||
device_printf(sc->pic_dev, | device_printf(sc->pic_dev, | ||||
"Stray interrupt %u detected\n", i); | "Stray interrupt %u detected\n", i); | ||||
pic_irq_mask(sc, i); | pic_irq_mask(sc, i); | ||||
continue; | continue; | ||||
} | } | ||||
intr_irq_dispatch(isrc, curthread->td_intr_frame); | |||||
} | } | ||||
KASSERT(i == 0, ("all interrupts handled")); | KASSERT(i == 0, ("all interrupts handled")); | ||||
#ifdef HWPMC_HOOKS | #ifdef HWPMC_HOOKS | ||||
if (pmc_hook && (PCPU_GET(curthread)->td_pflags & TDP_CALLCHAIN)) { | if (pmc_hook && (PCPU_GET(curthread)->td_pflags & TDP_CALLCHAIN)) { | ||||
struct trapframe *tf = PCPU_GET(curthread)->td_intr_frame; | struct trapframe *tf = PCPU_GET(curthread)->td_intr_frame; | ||||
pmc_hook(PCPU_GET(curthread), PMC_FN_USER_CALLCHAIN, tf); | pmc_hook(PCPU_GET(curthread), PMC_FN_USER_CALLCHAIN, tf); | ||||
} | } | ||||
#endif | #endif | ||||
return (FILTER_HANDLED); | return (FILTER_HANDLED); | ||||
} | } | ||||
static int | static void | ||||
pic_attach_isrc(struct mips_pic_softc *sc, struct intr_irqsrc *isrc, u_int irq) | mips_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc) | ||||
{ | { | ||||
u_int irq; | |||||
/* | irq = ((struct mips_pic_irqsrc *)isrc)->irq; | ||||
* 1. The link between ISRC and controller must be set atomically. | pic_irq_mask(device_get_softc(dev), irq); | ||||
* 2. Just do things only once in rare case when consumers | |||||
* of shared interrupt came here at the same moment. | |||||
*/ | |||||
mtx_lock_spin(&sc->mutex); | |||||
if (sc->pic_irqs[irq] != NULL) { | |||||
mtx_unlock_spin(&sc->mutex); | |||||
return (sc->pic_irqs[irq] == isrc ? 0 : EEXIST); | |||||
} | } | ||||
sc->pic_irqs[irq] = isrc; | |||||
isrc->isrc_data = irq; | |||||
mtx_unlock_spin(&sc->mutex); | |||||
if (irq < NSOFT_IRQS) | static void | ||||
intr_irq_set_name(isrc, "sint%u", irq); | mips_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc) | ||||
else if (irq < NREAL_IRQS) | |||||
intr_irq_set_name(isrc, "int%u", irq - NSOFT_IRQS); | |||||
else | |||||
panic("Invalid irq %u", irq); | |||||
return (0); | |||||
} | |||||
static int | |||||
pic_detach_isrc(struct mips_pic_softc *sc, struct intr_irqsrc *isrc, u_int irq) | |||||
{ | { | ||||
u_int irq; | |||||
mtx_lock_spin(&sc->mutex); | irq = ((struct mips_pic_irqsrc *)isrc)->irq; | ||||
if (sc->pic_irqs[irq] != isrc) { | pic_irq_unmask(device_get_softc(dev), irq); | ||||
mtx_unlock_spin(&sc->mutex); | |||||
return (sc->pic_irqs[irq] == NULL ? 0 : EINVAL); | |||||
} | } | ||||
sc->pic_irqs[irq] = NULL; | |||||
isrc->isrc_data = 0; | |||||
mtx_unlock_spin(&sc->mutex); | |||||
intr_irq_set_name(isrc, "%s", ""); | |||||
return (0); | |||||
} | |||||
static int | static int | ||||
pic_irq_from_nspc(struct mips_pic_softc *sc, u_int type, u_int num, u_int *irqp) | mips_pic_map_intr(device_t dev, struct intr_map_data *data, | ||||
struct intr_irqsrc **isrcp) | |||||
{ | { | ||||
switch (type) { | |||||
case INTR_IRQ_NSPC_PLAIN: | |||||
*irqp = num; | |||||
return (*irqp < sc->nirqs ? 0 : EINVAL); | |||||
case INTR_IRQ_NSPC_SWI: | |||||
*irqp = num; | |||||
return (num < NSOFT_IRQS ? 0 : EINVAL); | |||||
case INTR_IRQ_NSPC_IRQ: | |||||
*irqp = num + NSOFT_IRQS; | |||||
return (num < NHARD_IRQS ? 0 : EINVAL); | |||||
default: | |||||
return (EINVAL); | |||||
} | |||||
} | |||||
static int | |||||
pic_map_nspc(struct mips_pic_softc *sc, struct intr_irqsrc *isrc, u_int *irqp) | |||||
{ | |||||
int error; | |||||
error = pic_irq_from_nspc(sc, isrc->isrc_nspc_type, isrc->isrc_nspc_num, | |||||
irqp); | |||||
if (error != 0) | |||||
return (error); | |||||
return (pic_attach_isrc(sc, isrc, *irqp)); | |||||
} | |||||
#ifdef FDT | #ifdef FDT | ||||
static int | struct mips_pic_softc *sc; | ||||
pic_map_fdt(struct mips_pic_softc *sc, struct intr_irqsrc *isrc, u_int *irqp) | |||||
{ | |||||
u_int irq; | |||||
int error; | |||||
irq = isrc->isrc_cells[0]; | sc = device_get_softc(dev); | ||||
if (irq >= sc->nirqs) | if (data == NULL || data->type != INTR_MAP_DATA_FDT || | ||||
data->fdt.ncells != 1 || data->fdt.cells[0] >= sc->nirqs) | |||||
return (EINVAL); | return (EINVAL); | ||||
error = pic_attach_isrc(sc, isrc, irq); | *isrcp = PIC_INTR_ISRC(sc, data->fdt.cells[0]); | ||||
if (error != 0) | |||||
return (error); | |||||
isrc->isrc_nspc_type = INTR_IRQ_NSPC_PLAIN; | |||||
isrc->isrc_nspc_num = irq; | |||||
isrc->isrc_trig = INTR_TRIGGER_CONFORM; | |||||
isrc->isrc_pol = INTR_POLARITY_CONFORM; | |||||
*irqp = irq; | |||||
return (0); | return (0); | ||||
} | #else | ||||
#endif | |||||
static int | |||||
mips_pic_register(device_t dev, struct intr_irqsrc *isrc, boolean_t *is_percpu) | |||||
{ | |||||
struct mips_pic_softc *sc = device_get_softc(dev); | |||||
u_int irq; | |||||
int error; | |||||
if (isrc->isrc_type == INTR_ISRCT_NAMESPACE) | |||||
error = pic_map_nspc(sc, isrc, &irq); | |||||
#ifdef FDT | |||||
else if (isrc->isrc_type == INTR_ISRCT_FDT) | |||||
error = pic_map_fdt(sc, isrc, &irq); | |||||
#endif | |||||
else | |||||
return (EINVAL); | return (EINVAL); | ||||
#endif | |||||
if (error == 0) | |||||
*is_percpu = TRUE; | |||||
return (error); | |||||
} | } | ||||
static void | static void | ||||
mips_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc) | |||||
{ | |||||
if (isrc->isrc_trig == INTR_TRIGGER_CONFORM) | |||||
isrc->isrc_trig = INTR_TRIGGER_LEVEL; | |||||
} | |||||
static void | |||||
mips_pic_enable_source(device_t dev, struct intr_irqsrc *isrc) | |||||
{ | |||||
struct mips_pic_softc *sc = device_get_softc(dev); | |||||
u_int irq = isrc->isrc_data; | |||||
pic_irq_unmask(sc, irq); | |||||
} | |||||
static void | |||||
mips_pic_disable_source(device_t dev, struct intr_irqsrc *isrc) | |||||
{ | |||||
struct mips_pic_softc *sc = device_get_softc(dev); | |||||
u_int irq = isrc->isrc_data; | |||||
pic_irq_mask(sc, irq); | |||||
} | |||||
static int | |||||
mips_pic_unregister(device_t dev, struct intr_irqsrc *isrc) | |||||
{ | |||||
struct mips_pic_softc *sc = device_get_softc(dev); | |||||
u_int irq = isrc->isrc_data; | |||||
return (pic_detach_isrc(sc, isrc, irq)); | |||||
} | |||||
static void | |||||
mips_pic_pre_ithread(device_t dev, struct intr_irqsrc *isrc) | mips_pic_pre_ithread(device_t dev, struct intr_irqsrc *isrc) | ||||
{ | { | ||||
mips_pic_disable_source(dev, isrc); | mips_pic_disable_intr(dev, isrc); | ||||
} | } | ||||
static void | static void | ||||
mips_pic_post_ithread(device_t dev, struct intr_irqsrc *isrc) | mips_pic_post_ithread(device_t dev, struct intr_irqsrc *isrc) | ||||
{ | { | ||||
mips_pic_enable_source(dev, isrc); | mips_pic_enable_intr(dev, isrc); | ||||
} | } | ||||
static void | static void | ||||
mips_pic_post_filter(device_t dev, struct intr_irqsrc *isrc) | mips_pic_post_filter(device_t dev, struct intr_irqsrc *isrc) | ||||
{ | { | ||||
} | } | ||||
#ifdef SMP | |||||
static int | |||||
mips_pic_bind(device_t dev, struct intr_irqsrc *isrc) | |||||
{ | |||||
return (EOPNOTSUPP); | |||||
} | |||||
static void | |||||
mips_pic_ipi_send(device_t dev, struct intr_irqsrc *isrc, cpuset_t cpus) | |||||
{ | |||||
} | |||||
#endif | |||||
static device_method_t mips_pic_methods[] = { | static device_method_t mips_pic_methods[] = { | ||||
/* Device interface */ | /* Device interface */ | ||||
#ifndef FDT | #ifndef FDT | ||||
DEVMETHOD(device_identify, mips_pic_identify), | DEVMETHOD(device_identify, mips_pic_identify), | ||||
#endif | #endif | ||||
DEVMETHOD(device_probe, mips_pic_probe), | DEVMETHOD(device_probe, mips_pic_probe), | ||||
DEVMETHOD(device_attach, mips_pic_attach), | DEVMETHOD(device_attach, mips_pic_attach), | ||||
/* Interrupt controller interface */ | /* Interrupt controller interface */ | ||||
DEVMETHOD(pic_disable_source, mips_pic_disable_source), | DEVMETHOD(pic_disable_intr, mips_pic_disable_intr), | ||||
DEVMETHOD(pic_enable_intr, mips_pic_enable_intr), | DEVMETHOD(pic_enable_intr, mips_pic_enable_intr), | ||||
DEVMETHOD(pic_enable_source, mips_pic_enable_source), | DEVMETHOD(pic_map_intr, mips_pic_map_intr), | ||||
DEVMETHOD(pic_post_filter, mips_pic_post_filter), | |||||
DEVMETHOD(pic_post_ithread, mips_pic_post_ithread), | |||||
DEVMETHOD(pic_pre_ithread, mips_pic_pre_ithread), | DEVMETHOD(pic_pre_ithread, mips_pic_pre_ithread), | ||||
DEVMETHOD(pic_register, mips_pic_register), | DEVMETHOD(pic_post_ithread, mips_pic_post_ithread), | ||||
DEVMETHOD(pic_unregister, mips_pic_unregister), | DEVMETHOD(pic_post_filter, mips_pic_post_filter), | ||||
#ifdef SMP | |||||
DEVMETHOD(pic_bind, mips_pic_bind), | |||||
DEVMETHOD(pic_init_secondary, mips_pic_init_secondary), | |||||
DEVMETHOD(pic_ipi_send, mips_pic_ipi_send), | |||||
#endif | |||||
{ 0, 0 } | { 0, 0 } | ||||
}; | }; | ||||
static driver_t mips_pic_driver = { | static driver_t mips_pic_driver = { | ||||
"cpupic", | "cpupic", | ||||
mips_pic_methods, | mips_pic_methods, | ||||
sizeof(struct mips_pic_softc), | sizeof(struct mips_pic_softc), | ||||
}; | }; | ||||
Show All 12 Lines | |||||
cpu_init_interrupts(void) | cpu_init_interrupts(void) | ||||
{ | { | ||||
} | } | ||||
void | void | ||||
cpu_establish_hardintr(const char *name, driver_filter_t *filt, | cpu_establish_hardintr(const char *name, driver_filter_t *filt, | ||||
void (*handler)(void*), void *arg, int irq, int flags, void **cookiep) | void (*handler)(void*), void *arg, int irq, int flags, void **cookiep) | ||||
{ | { | ||||
u_int vec; | |||||
int res; | int res; | ||||
/* | /* | ||||
* We have 6 levels, but thats 0 - 5 (not including 6) | * We have 6 levels, but thats 0 - 5 (not including 6) | ||||
*/ | */ | ||||
if (irq < 0 || irq >= NHARD_IRQS) | if (irq < 0 || irq >= NHARD_IRQS) | ||||
panic("%s called for unknown hard intr %d", __func__, irq); | panic("%s called for unknown hard intr %d", __func__, irq); | ||||
KASSERT(pic_sc != NULL, ("%s: no pic", __func__)); | KASSERT(pic_sc != NULL, ("%s: no pic", __func__)); | ||||
vec = intr_namespace_map_irq(pic_sc->pic_dev, INTR_IRQ_NSPC_IRQ, irq); | |||||
KASSERT(vec != NIRQ, ("Unable to map hard IRQ %d\n", irq)); | |||||
res = intr_irq_add_handler(pic_sc->pic_dev, filt, handler, arg, vec, | irq += NSOFT_IRQS; | ||||
flags, cookiep); | res = intr_setup_irq(pic_sc->pic_dev, pic_sc->pic_irqs[irq].res, filt, | ||||
handler, arg, flags, cookiep); | |||||
if (res != 0) panic("Unable to add hard IRQ %d handler", irq); | if (res != 0) panic("Unable to add hard IRQ %d handler", irq); | ||||
(void)pic_irq_from_nspc(pic_sc, INTR_IRQ_NSPC_IRQ, irq, &vec); | |||||
KASSERT(pic_sc->pic_irqs[vec] != NULL, | |||||
("Hard IRQ %d not registered\n", irq)); | |||||
intr_irq_set_name(pic_sc->pic_irqs[vec], "%s", name); | |||||
} | } | ||||
void | void | ||||
cpu_establish_softintr(const char *name, driver_filter_t *filt, | cpu_establish_softintr(const char *name, driver_filter_t *filt, | ||||
void (*handler)(void*), void *arg, int irq, int flags, | void (*handler)(void*), void *arg, int irq, int flags, | ||||
void **cookiep) | void **cookiep) | ||||
{ | { | ||||
u_int vec; | |||||
int res; | int res; | ||||
if (irq < 0 || irq > NSOFT_IRQS) | if (irq < 0 || irq > NSOFT_IRQS) | ||||
panic("%s called for unknown soft intr %d", __func__, irq); | panic("%s called for unknown soft intr %d", __func__, irq); | ||||
KASSERT(pic_sc != NULL, ("%s: no pic", __func__)); | KASSERT(pic_sc != NULL, ("%s: no pic", __func__)); | ||||
vec = intr_namespace_map_irq(pic_sc->pic_dev, INTR_IRQ_NSPC_SWI, irq); | |||||
KASSERT(vec <= NIRQ, ("Unable to map soft IRQ %d\n", irq)); | |||||
intr_irq_add_handler(pic_sc->pic_dev, filt, handler, arg, vec, | res = intr_setup_irq(pic_sc->pic_dev, pic_sc->pic_irqs[irq].res, filt, | ||||
flags, cookiep); | handler, arg, flags, cookiep); | ||||
if (res != 0) panic("Unable to add soft IRQ %d handler", irq); | if (res != 0) panic("Unable to add soft IRQ %d handler", irq); | ||||
(void)pic_irq_from_nspc(pic_sc, INTR_IRQ_NSPC_SWI, irq, &vec); | |||||
KASSERT(pic_sc->pic_irqs[vec] != NULL, | |||||
("Soft IRQ %d not registered\n", irq)); | |||||
intr_irq_set_name(pic_sc->pic_irqs[vec], "%s", name); | |||||
} | } | ||||
Come to think of it, what is the purpose of rman here? It serves to useful purpose but to provide a fake struct resource for cpu_establish_hard|soft_intr. I would just kill it off for now - it does not look like INTRNG plugs into resource allocation properly anyway.