Changeset View
Changeset View
Standalone View
Standalone View
head/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 intr_map_data_mips_pic { | |||||
struct intr_map_data hdr; | |||||
u_int irq; | |||||
}; | |||||
struct mips_pic_irqsrc { | struct mips_pic_irqsrc { | ||||
struct intr_irqsrc isrc; | struct intr_irqsrc isrc; | ||||
struct resource *res; | struct resource *res; | ||||
u_int irq; | u_int irq; | ||||
}; | }; | ||||
struct mips_pic_softc { | struct mips_pic_softc { | ||||
device_t pic_dev; | device_t pic_dev; | ||||
▲ Show 20 Lines • Show All 217 Lines • ▼ Show 20 Lines | mips_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc) | ||||
irq = ((struct mips_pic_irqsrc *)isrc)->irq; | irq = ((struct mips_pic_irqsrc *)isrc)->irq; | ||||
pic_irq_unmask(device_get_softc(dev), irq); | pic_irq_unmask(device_get_softc(dev), irq); | ||||
} | } | ||||
static int | static int | ||||
mips_pic_map_intr(device_t dev, struct intr_map_data *data, | mips_pic_map_intr(device_t dev, struct intr_map_data *data, | ||||
struct intr_irqsrc **isrcp) | struct intr_irqsrc **isrcp) | ||||
{ | { | ||||
#ifdef FDT | |||||
struct intr_map_data_fdt *daf; | |||||
struct mips_pic_softc *sc; | struct mips_pic_softc *sc; | ||||
int res; | |||||
if (data->type != INTR_MAP_DATA_FDT) | |||||
return (ENOTSUP); | |||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
res = 0; | |||||
#ifdef FDT | |||||
if (data->type == INTR_MAP_DATA_FDT) { | |||||
struct intr_map_data_fdt *daf; | |||||
daf = (struct intr_map_data_fdt *)data; | daf = (struct intr_map_data_fdt *)data; | ||||
if (daf->ncells != 1 || daf->cells[0] >= sc->nirqs) | if (daf->ncells != 1 || daf->cells[0] >= sc->nirqs) | ||||
return (EINVAL); | return (EINVAL); | ||||
*isrcp = PIC_INTR_ISRC(sc, daf->cells[0]); | *isrcp = PIC_INTR_ISRC(sc, daf->cells[0]); | ||||
return (0); | } else | ||||
#else | |||||
return (ENOTSUP); | |||||
#endif | #endif | ||||
if (data->type == INTR_MAP_DATA_PLAT_1) { | |||||
struct intr_map_data_mips_pic *mpd; | |||||
mpd = (struct intr_map_data_mips_pic *)data; | |||||
if (mpd->irq < 0 || mpd->irq >= sc->nirqs) | |||||
return (EINVAL); | |||||
*isrcp = PIC_INTR_ISRC(sc, mpd->irq); | |||||
} else { | |||||
res = ENOTSUP; | |||||
} | } | ||||
return (res); | |||||
} | |||||
static void | 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_intr(dev, isrc); | mips_pic_disable_intr(dev, isrc); | ||||
} | } | ||||
static void | static void | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | EARLY_DRIVER_MODULE(cpupic, nexus, mips_pic_driver, mips_pic_devclass, 0, 0, | ||||
BUS_PASS_INTERRUPT); | BUS_PASS_INTERRUPT); | ||||
#endif | #endif | ||||
void | void | ||||
cpu_init_interrupts(void) | cpu_init_interrupts(void) | ||||
{ | { | ||||
} | } | ||||
int | |||||
cpu_create_intr_map(int irq) | |||||
{ | |||||
struct intr_map_data_mips_pic *mips_pic_data; | |||||
intptr_t iparent; | |||||
size_t len; | |||||
u_int new_irq; | |||||
len = sizeof(*mips_pic_data); | |||||
iparent = pic_xref(pic_sc->pic_dev); | |||||
/* Allocate mips_pic data and fill it in */ | |||||
mips_pic_data = (struct intr_map_data_mips_pic *)intr_alloc_map_data( | |||||
INTR_MAP_DATA_PLAT_1, len, M_WAITOK | M_ZERO); | |||||
mips_pic_data->irq = irq; | |||||
/* Get the new irq number */ | |||||
new_irq = intr_map_irq(pic_sc->pic_dev, iparent, | |||||
(struct intr_map_data *)mips_pic_data); | |||||
/* Adjust the resource accordingly */ | |||||
rman_set_start(pic_sc->pic_irqs[irq].res, new_irq); | |||||
rman_set_end(pic_sc->pic_irqs[irq].res, new_irq); | |||||
/* Activate the new irq */ | |||||
return (intr_activate_irq(pic_sc->pic_dev, pic_sc->pic_irqs[irq].res)); | |||||
} | |||||
struct resource * | |||||
cpu_get_irq_resource(int irq) | |||||
{ | |||||
KASSERT(pic_sc != NULL, ("%s: no pic", __func__)); | |||||
if (irq < 0 || irq >= pic_sc->nirqs) | |||||
panic("%s called for unknown irq %d", __func__, irq); | |||||
return pic_sc->pic_irqs[irq].res; | |||||
} | |||||
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) | ||||
{ | { | ||||
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__)); | ||||
irq += NSOFT_IRQS; | irq += NSOFT_IRQS; | ||||
res = cpu_create_intr_map(irq); | |||||
if (res != 0) panic("Unable to create map for hard IRQ %d", irq); | |||||
res = intr_setup_irq(pic_sc->pic_dev, pic_sc->pic_irqs[irq].res, filt, | res = intr_setup_irq(pic_sc->pic_dev, pic_sc->pic_irqs[irq].res, filt, | ||||
handler, arg, flags, cookiep); | 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 | 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) | ||||
{ | { | ||||
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__)); | ||||
res = cpu_create_intr_map(irq); | |||||
if (res != 0) panic("Unable to create map for soft IRQ %d", irq); | |||||
res = intr_setup_irq(pic_sc->pic_dev, pic_sc->pic_irqs[irq].res, filt, | res = intr_setup_irq(pic_sc->pic_dev, pic_sc->pic_irqs[irq].res, filt, | ||||
handler, arg, 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); | ||||
} | } | ||||