extern int acpi_disabled;
extern int acpi_noirq;
extern int acpi_pci_disabled;
+extern int acpi_gic_ver;
static inline void disable_acpi(void)
{
void __init acpi_init_cpus(void);
#else
+#define acpi_gic_ver 0
static inline void acpi_init_cpus(void) { }
#endif /* CONFIG_ACPI */
int acpi_pci_disabled = 1; /* skip ACPI PCI scan and IRQ initialization */
EXPORT_SYMBOL(acpi_pci_disabled);
+int acpi_gic_ver;
+
static bool param_acpi_off __initdata;
static bool param_acpi_force __initdata;
}
}
+static int __init
+gic_acpi_find_ver(struct acpi_subtable_header *header,
+ const unsigned long end)
+{
+ struct acpi_madt_generic_distributor *dist;
+
+ dist = (struct acpi_madt_generic_distributor *)header;
+
+ if (BAD_MADT_ENTRY(dist, end))
+ return -EINVAL;
+
+ acpi_gic_ver = dist->gic_version;
+ return 0;
+}
+
void __init acpi_gic_init(void)
{
struct acpi_table_header *table;
acpi_status status;
acpi_size tbl_size;
- int err;
+ int err, count;;
if (acpi_disabled)
return;
return;
}
- err = gic_v2_acpi_init(table);
+ count = acpi_parse_entries(ACPI_SIG_MADT,
+ sizeof(struct acpi_table_madt),
+ gic_acpi_find_ver, table,
+ ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
+ if (count <= 0) {
+ pr_info("Error during GICD entries parsing, assuming GICv2\n");
+ acpi_gic_ver = ACPI_MADT_GIC_VER_V2;
+ }
+
+ err = acpi_gic_ver < ACPI_MADT_GIC_VER_V3 ?
+ gic_v2_acpi_init(table) : -ENXIO;
if (err)
pr_err("Failed to initialize GIC IRQ controller");
#define ACPI_MADT_PERFORMANCE_IRQ_MODE (1<<1) /* 01: Performance Interrupt Mode */
#define ACPI_MADT_VGIC_IRQ_MODE (1<<2) /* 02: VGIC Maintenance Interrupt mode */
+enum acpi_madt_gic_ver_type
+{
+ ACPI_MADT_GIC_VER_UNKNOWN = 0,
+ ACPI_MADT_GIC_VER_V2 = 1,
+ ACPI_MADT_GIC_VER_V2m = 2,
+ ACPI_MADT_GIC_VER_V3 = 3,
+ ACPI_MADT_GIC_VER_V4 = 4,
+ ACPI_MADT_GIC_VER_RESERVED = 5 /* 15 and greater are reserved */
+};
+
/* 12: Generic Distributor (ACPI 5.0 + ACPI 6.0 changes) */
struct acpi_madt_generic_distributor {
u32 gic_id;
u64 base_address;
u32 global_irq_base;
- u8 version;
+ u8 gic_version;
u8 reserved2[3]; /* reserved - must be zero */
};