void __iomem *ptr)
 {
        u64 typer = gic_read_typer(ptr + GICR_TYPER);
+
        gic_data.rdists.has_vlpis &= !!(typer & GICR_TYPER_VLPIS);
-       gic_data.rdists.has_direct_lpi &= !!(typer & GICR_TYPER_DirectLPIS);
+
+       /* RVPEID implies some form of DirectLPI, no matter what the doc says... :-/ */
+       gic_data.rdists.has_rvpeid &= !!(typer & GICR_TYPER_RVPEID);
+       gic_data.rdists.has_direct_lpi &= (!!(typer & GICR_TYPER_DirectLPIS) |
+                                          gic_data.rdists.has_rvpeid);
+
+       /* Detect non-sensical configurations */
+       if (WARN_ON_ONCE(gic_data.rdists.has_rvpeid && !gic_data.rdists.has_vlpis)) {
+               gic_data.rdists.has_direct_lpi = false;
+               gic_data.rdists.has_vlpis = false;
+               gic_data.rdists.has_rvpeid = false;
+       }
+
        gic_data.ppi_nr = min(GICR_TYPER_NR_PPIS(typer), gic_data.ppi_nr);
 
        return 1;
        if (WARN_ON(gic_data.ppi_nr == UINT_MAX))
                gic_data.ppi_nr = 0;
        pr_info("%d PPIs implemented\n", gic_data.ppi_nr);
-       pr_info("%sVLPI support, %sdirect LPI support\n",
+       pr_info("%sVLPI support, %sdirect LPI support, %sRVPEID support\n",
                !gic_data.rdists.has_vlpis ? "no " : "",
-               !gic_data.rdists.has_direct_lpi ? "no " : "");
+               !gic_data.rdists.has_direct_lpi ? "no " : "",
+               !gic_data.rdists.has_rvpeid ? "no " : "");
 }
 
 /* Check whether it's single security state view */
                                                 &gic_data);
        irq_domain_update_bus_token(gic_data.domain, DOMAIN_BUS_WIRED);
        gic_data.rdists.rdist = alloc_percpu(typeof(*gic_data.rdists.rdist));
+       gic_data.rdists.has_rvpeid = true;
        gic_data.rdists.has_vlpis = true;
        gic_data.rdists.has_direct_lpi = true;