Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm/arm/gic.c
Show First 20 Lines • Show All 829 Lines • ▼ Show 20 Lines | if (ncells == 3) { | ||||
*trigp = tripol & 0x03 ? INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL; | *trigp = tripol & 0x03 ? INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL; | ||||
return (0); | return (0); | ||||
} | } | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
#endif | #endif | ||||
static int | static int | ||||
gic_map_msi(device_t dev, struct intr_map_data_msi *msi_data, u_int *irqp, | |||||
enum intr_polarity *polp, enum intr_trigger *trigp) | |||||
{ | |||||
struct gic_irqsrc *gi; | |||||
/* Map a non-GICv2m MSI */ | |||||
gi = (struct gic_irqsrc *)msi_data->isrc; | |||||
if (gi == NULL) | |||||
return (ENXIO); | |||||
*irqp = gi->gi_irq; | |||||
/* MSI/MSI-X interrupts are always edge triggered with high polarity */ | |||||
*polp = INTR_POLARITY_HIGH; | |||||
*trigp = INTR_TRIGGER_EDGE; | |||||
return (0); | |||||
} | |||||
static int | |||||
gic_map_intr(device_t dev, struct intr_map_data *data, u_int *irqp, | gic_map_intr(device_t dev, struct intr_map_data *data, u_int *irqp, | ||||
enum intr_polarity *polp, enum intr_trigger *trigp) | enum intr_polarity *polp, enum intr_trigger *trigp) | ||||
{ | { | ||||
u_int irq; | u_int irq; | ||||
enum intr_polarity pol; | enum intr_polarity pol; | ||||
enum intr_trigger trig; | enum intr_trigger trig; | ||||
struct arm_gic_softc *sc; | struct arm_gic_softc *sc; | ||||
struct intr_map_data_msi *dam; | |||||
#ifdef FDT | #ifdef FDT | ||||
struct intr_map_data_fdt *daf; | struct intr_map_data_fdt *daf; | ||||
#endif | #endif | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
switch (data->type) { | switch (data->type) { | ||||
#ifdef FDT | #ifdef FDT | ||||
case INTR_MAP_DATA_FDT: | case INTR_MAP_DATA_FDT: | ||||
daf = (struct intr_map_data_fdt *)data; | daf = (struct intr_map_data_fdt *)data; | ||||
if (gic_map_fdt(dev, daf->ncells, daf->cells, &irq, &pol, | if (gic_map_fdt(dev, daf->ncells, daf->cells, &irq, &pol, | ||||
&trig) != 0) | &trig) != 0) | ||||
return (EINVAL); | return (EINVAL); | ||||
KASSERT(irq >= sc->nirqs || | KASSERT(irq >= sc->nirqs || | ||||
(sc->gic_irqs[irq].gi_flags & GI_FLAG_MSI) == 0, | (sc->gic_irqs[irq].gi_flags & GI_FLAG_MSI) == 0, | ||||
("%s: Attempting to map a MSI interrupt from FDT", | ("%s: Attempting to map a MSI interrupt from FDT", | ||||
__func__)); | __func__)); | ||||
break; | break; | ||||
#endif | #endif | ||||
case INTR_MAP_DATA_MSI: | |||||
/* Non-GICv2m MSI */ | |||||
dam = (struct intr_map_data_msi *)data; | |||||
if (gic_map_msi(dev, dam, &irq, &pol, &trig) != 0) | |||||
return (EINVAL); | |||||
break; | |||||
default: | default: | ||||
return (ENOTSUP); | return (ENOTSUP); | ||||
} | } | ||||
if (irq >= sc->nirqs) | if (irq >= sc->nirqs) | ||||
return (EINVAL); | return (EINVAL); | ||||
if (pol != INTR_POLARITY_CONFORM && pol != INTR_POLARITY_LOW && | if (pol != INTR_POLARITY_CONFORM && pol != INTR_POLARITY_LOW && | ||||
pol != INTR_POLARITY_HIGH) | pol != INTR_POLARITY_HIGH) | ||||
Show All 31 Lines | arm_gic_setup_intr(device_t dev, struct intr_irqsrc *isrc, | ||||
struct resource *res, struct intr_map_data *data) | struct resource *res, struct intr_map_data *data) | ||||
{ | { | ||||
struct arm_gic_softc *sc = device_get_softc(dev); | struct arm_gic_softc *sc = device_get_softc(dev); | ||||
struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc; | struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc; | ||||
enum intr_trigger trig; | enum intr_trigger trig; | ||||
enum intr_polarity pol; | enum intr_polarity pol; | ||||
if ((gi->gi_flags & GI_FLAG_MSI) == GI_FLAG_MSI) { | if ((gi->gi_flags & GI_FLAG_MSI) == GI_FLAG_MSI) { | ||||
/* GICv2m MSI */ | |||||
pol = gi->gi_pol; | pol = gi->gi_pol; | ||||
trig = gi->gi_trig; | trig = gi->gi_trig; | ||||
KASSERT(pol == INTR_POLARITY_HIGH, | KASSERT(pol == INTR_POLARITY_HIGH, | ||||
("%s: MSI interrupts must be active-high", __func__)); | ("%s: MSI interrupts must be active-high", __func__)); | ||||
KASSERT(trig == INTR_TRIGGER_EDGE, | KASSERT(trig == INTR_TRIGGER_EDGE, | ||||
("%s: MSI interrupts must be edge triggered", __func__)); | ("%s: MSI interrupts must be edge triggered", __func__)); | ||||
} else if (data != NULL) { | } else if (data != NULL) { | ||||
u_int irq; | u_int irq; | ||||
▲ Show 20 Lines • Show All 629 Lines • Show Last 20 Lines |