diff options
-rw-r--r-- | drivers/acpi/processor_core.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 4d91b32423a9..f1dd404463aa 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -71,6 +71,28 @@ static int map_lsapic_id(struct acpi_subtable_header *entry, | |||
71 | return 0; | 71 | return 0; |
72 | } | 72 | } |
73 | 73 | ||
74 | static int map_gic_id(struct acpi_subtable_header *entry, | ||
75 | int device_declaration, u32 acpi_id, int *apic_id) | ||
76 | { | ||
77 | struct acpi_madt_generic_interrupt *gic = | ||
78 | (struct acpi_madt_generic_interrupt *)entry; | ||
79 | |||
80 | if (!(gic->flags & ACPI_MADT_ENABLED)) | ||
81 | return -ENODEV; | ||
82 | |||
83 | /* | ||
84 | * In the GIC interrupt model, logical processors are | ||
85 | * required to have a Processor Device object in the DSDT, | ||
86 | * so we should check device_declaration here | ||
87 | */ | ||
88 | if (device_declaration && (gic->uid == acpi_id)) { | ||
89 | *apic_id = gic->gic_id; | ||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | return -EINVAL; | ||
94 | } | ||
95 | |||
74 | static int map_madt_entry(int type, u32 acpi_id) | 96 | static int map_madt_entry(int type, u32 acpi_id) |
75 | { | 97 | { |
76 | unsigned long madt_end, entry; | 98 | unsigned long madt_end, entry; |
@@ -106,6 +128,9 @@ static int map_madt_entry(int type, u32 acpi_id) | |||
106 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { | 128 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { |
107 | if (!map_lsapic_id(header, type, acpi_id, &apic_id)) | 129 | if (!map_lsapic_id(header, type, acpi_id, &apic_id)) |
108 | break; | 130 | break; |
131 | } else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) { | ||
132 | if (!map_gic_id(header, type, acpi_id, &apic_id)) | ||
133 | break; | ||
109 | } | 134 | } |
110 | entry += header->length; | 135 | entry += header->length; |
111 | } | 136 | } |
@@ -136,6 +161,8 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) | |||
136 | map_lapic_id(header, acpi_id, &apic_id); | 161 | map_lapic_id(header, acpi_id, &apic_id); |
137 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { | 162 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { |
138 | map_lsapic_id(header, type, acpi_id, &apic_id); | 163 | map_lsapic_id(header, type, acpi_id, &apic_id); |
164 | } else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) { | ||
165 | map_gic_id(header, type, acpi_id, &apic_id); | ||
139 | } | 166 | } |
140 | 167 | ||
141 | exit: | 168 | exit: |