Add support for SPI-mapped MSI interrupts outside of GICv2m.
SPI-mapped MSI interrupts coming from a controller other than GICv2m need to have their trigger and polarity properly configured. This patch fixes MSI/MSI-X on Annapurna Alpine platform with GICv2. Obtained from: Semihalf Submitted by: Michal Stanek <mst@semihalf.com> Sponsored by: Annapurna Labs Reviewed by: skra, wma Differential Revision: https://reviews.freebsd.org/D7698
This commit is contained in:
parent
a134b98878
commit
0f9f40918d
@ -834,6 +834,26 @@ gic_map_fdt(device_t dev, u_int ncells, pcell_t *cells, u_int *irqp,
|
||||
}
|
||||
#endif
|
||||
|
||||
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,
|
||||
enum intr_polarity *polp, enum intr_trigger *trigp)
|
||||
@ -842,6 +862,7 @@ gic_map_intr(device_t dev, struct intr_map_data *data, u_int *irqp,
|
||||
enum intr_polarity pol;
|
||||
enum intr_trigger trig;
|
||||
struct arm_gic_softc *sc;
|
||||
struct intr_map_data_msi *dam;
|
||||
#ifdef FDT
|
||||
struct intr_map_data_fdt *daf;
|
||||
#endif
|
||||
@ -860,6 +881,12 @@ gic_map_intr(device_t dev, struct intr_map_data *data, u_int *irqp,
|
||||
__func__));
|
||||
break;
|
||||
#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:
|
||||
return (ENOTSUP);
|
||||
}
|
||||
@ -907,6 +934,7 @@ arm_gic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
|
||||
enum intr_polarity pol;
|
||||
|
||||
if ((gi->gi_flags & GI_FLAG_MSI) == GI_FLAG_MSI) {
|
||||
/* GICv2m MSI */
|
||||
pol = gi->gi_pol;
|
||||
trig = gi->gi_trig;
|
||||
KASSERT(pol == INTR_POLARITY_HIGH,
|
||||
|
Loading…
x
Reference in New Issue
Block a user