aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorHanjun Guo <hanjun.guo@linaro.org>2015-03-24 10:02:47 -0400
committerWill Deacon <will.deacon@arm.com>2015-03-26 11:13:07 -0400
commit020295b4cb5b7d510ea1f4531a502c3f8a2380c5 (patch)
treedf7ab24becf82a0494ed4e4db883908bfdda3bca /drivers/acpi
parent828aef376d7a129547bc4ebb949965040177e3da (diff)
ACPI / processor: Make it possible to get CPU hardware ID via GICC
Introduce a new function map_gicc_mpidr() to allow MPIDRs to be obtained from the GICC Structure introduced by ACPI 5.1, since MPIDR for ARM64 is 64-bit, so typedef u64 for phys_cpuid_t. The ARM architecture defines the MPIDR register as the CPU hardware identifier. This patch adds the code infrastructure to retrieve the MPIDR values from the ARM ACPI GICC structure in order to look-up the kernel CPU hardware ids required by the ACPI core code to identify CPUs. CC: Rafael J. Wysocki <rjw@rjwysocki.net> CC: Catalin Marinas <catalin.marinas@arm.com> CC: Will Deacon <will.deacon@arm.com> Tested-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com> Tested-by: Yijing Wang <wangyijing@huawei.com> Tested-by: Mark Langsdorf <mlangsdo@redhat.com> Tested-by: Jon Masters <jcm@redhat.com> Tested-by: Timur Tabi <timur@codeaurora.org> Tested-by: Robert Richter <rrichter@cavium.com> Acked-by: Robert Richter <rrichter@cavium.com> Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Grant Likely <grant.likely@linaro.org> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/processor_core.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 51cc29909e08..b1ec78b8a645 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -83,6 +83,31 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
83 return 0; 83 return 0;
84} 84}
85 85
86/*
87 * Retrieve the ARM CPU physical identifier (MPIDR)
88 */
89static int map_gicc_mpidr(struct acpi_subtable_header *entry,
90 int device_declaration, u32 acpi_id, phys_cpuid_t *mpidr)
91{
92 struct acpi_madt_generic_interrupt *gicc =
93 container_of(entry, struct acpi_madt_generic_interrupt, header);
94
95 if (!(gicc->flags & ACPI_MADT_ENABLED))
96 return -ENODEV;
97
98 /* device_declaration means Device object in DSDT, in the
99 * GIC interrupt model, logical processors are required to
100 * have a Processor Device object in the DSDT, so we should
101 * check device_declaration here
102 */
103 if (device_declaration && (gicc->uid == acpi_id)) {
104 *mpidr = gicc->arm_mpidr;
105 return 0;
106 }
107
108 return -EINVAL;
109}
110
86static phys_cpuid_t map_madt_entry(int type, u32 acpi_id) 111static phys_cpuid_t map_madt_entry(int type, u32 acpi_id)
87{ 112{
88 unsigned long madt_end, entry; 113 unsigned long madt_end, entry;
@@ -111,6 +136,9 @@ static phys_cpuid_t map_madt_entry(int type, u32 acpi_id)
111 } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { 136 } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
112 if (!map_lsapic_id(header, type, acpi_id, &phys_id)) 137 if (!map_lsapic_id(header, type, acpi_id, &phys_id))
113 break; 138 break;
139 } else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
140 if (!map_gicc_mpidr(header, type, acpi_id, &phys_id))
141 break;
114 } 142 }
115 entry += header->length; 143 entry += header->length;
116 } 144 }
@@ -143,6 +171,8 @@ static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
143 map_lsapic_id(header, type, acpi_id, &phys_id); 171 map_lsapic_id(header, type, acpi_id, &phys_id);
144 else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) 172 else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC)
145 map_x2apic_id(header, type, acpi_id, &phys_id); 173 map_x2apic_id(header, type, acpi_id, &phys_id);
174 else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT)
175 map_gicc_mpidr(header, type, acpi_id, &phys_id);
146 176
147exit: 177exit:
148 kfree(buffer.pointer); 178 kfree(buffer.pointer);