@@ -27,6 +27,7 @@
#include <xen/softirq.h>
#include <xen/list.h>
#include <xen/device_tree.h>
+#include <xen/acpi.h>
#include <asm/p2m.h>
#include <asm/domain.h>
#include <asm/platform.h>
@@ -34,6 +35,7 @@
#include <asm/io.h>
#include <asm/gic.h>
#include <asm/vgic.h>
+#include <asm/acpi.h>
static void gic_restore_pending_irqs(struct vcpu *v);
@@ -228,10 +230,7 @@ int gic_irq_xlate(const u32 *intspec, unsigned int intsize,
return 0;
}
-/* Find the interrupt controller and set up the callback to translate
- * device tree IRQ.
- */
-void __init gic_preinit(void)
+static void __init gic_dt_preinit(void)
{
int rc;
struct dt_device_node *node;
@@ -261,6 +260,36 @@ void __init gic_preinit(void)
dt_device_set_used_by(node, DOMID_XEN);
}
+#ifdef CONFIG_ACPI
+static void __init gic_acpi_preinit(void)
+{
+ struct acpi_subtable_header *header;
+ struct acpi_madt_generic_distributor *dist;
+
+ header = acpi_table_get_entry_madt(ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
+ if ( !header )
+ panic("No valid GICD entries exists");
+
+ dist = container_of(header, struct acpi_madt_generic_distributor, header);
+
+ if ( acpi_device_init(DEVICE_GIC, NULL, dist->version) )
+ panic("Unable to find compatible GIC in the ACPI table");
+}
+#else
+static void __init gic_acpi_preinit(void) { }
+#endif
+
+/* Find the interrupt controller and set up the callback to translate
+ * device tree or ACPI IRQ.
+ */
+void __init gic_preinit(void)
+{
+ if ( acpi_disabled )
+ gic_dt_preinit();
+ else
+ gic_acpi_preinit();
+}
+
/* Set up the GIC */
void __init gic_init(void)
{