mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-31 04:01:48 -04:00
Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 apic updates from Ingo Molnar:
"The main changes are:
- Persistent CPU/node numbering across CPU hotplug/unplug events.
This is a pretty involved series of changes that first fetches all
the information during bootup and then uses it for the various
hotplug/unplug methods. (Gu Zheng, Dou Liyang)
- IO-APIC hot-add/remove fixes and enhancements. (Rui Wang)
- ... various fixes, cleanups and enhancements"
* 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (22 commits)
x86/apic: Fix silent & fatal merge conflict in __generic_processor_info()
acpi: Fix broken error check in map_processor()
acpi: Validate processor id when mapping the processor
acpi: Provide mechanism to validate processors in the ACPI tables
x86/acpi: Set persistent cpuid <-> nodeid mapping when booting
x86/acpi: Enable MADT APIs to return disabled apicids
x86/acpi: Introduce persistent storage for cpuid <-> apicid mapping
x86/acpi: Enable acpi to register all possible cpus at boot time
x86/numa: Online memory-less nodes at boot time
x86/apic: Get rid of apic_version[] array
x86/apic: Order irq_enter/exit() calls correctly vs. ack_APIC_irq()
x86/ioapic: Ignore root bridges without a companion ACPI device
x86/apic: Update comment about disabling processor focus
x86/smpboot: Check APIC ID before setting up default routing
x86/ioapic: Fix IOAPIC failing to request resource
x86/ioapic: Fix lost IOAPIC resource after hot-removal and hotadd
x86/ioapic: Fix setup_res() failing to get resource
x86/ioapic: Support hot-removal of IOAPICs present during boot
x86/ioapic: Change prototype of acpi_ioapic_add()
x86/apic, ACPI: Fix incorrect assignment when handling apic/x2apic entries
...
This commit is contained in:
commit
110a9e42b6
20 changed files with 391 additions and 137 deletions
|
|
@ -182,6 +182,11 @@ int __weak arch_register_cpu(int cpu)
|
|||
|
||||
void __weak arch_unregister_cpu(int cpu) {}
|
||||
|
||||
int __weak acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int acpi_processor_hotadd_init(struct acpi_processor *pr)
|
||||
{
|
||||
unsigned long long sta;
|
||||
|
|
@ -300,8 +305,11 @@ static int acpi_processor_get_info(struct acpi_device *device)
|
|||
* Extra Processor objects may be enumerated on MP systems with
|
||||
* less than the max # of CPUs. They should be ignored _iff
|
||||
* they are physically not present.
|
||||
*
|
||||
* NOTE: Even if the processor has a cpuid, it may not be present
|
||||
* because cpuid <-> apicid mapping is persistent now.
|
||||
*/
|
||||
if (invalid_logical_cpuid(pr->id)) {
|
||||
if (invalid_logical_cpuid(pr->id) || !cpu_present(pr->id)) {
|
||||
int ret = acpi_processor_hotadd_init(pr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
@ -573,8 +581,102 @@ static struct acpi_scan_handler processor_container_handler = {
|
|||
.attach = acpi_processor_container_attach,
|
||||
};
|
||||
|
||||
/* The number of the unique processor IDs */
|
||||
static int nr_unique_ids __initdata;
|
||||
|
||||
/* The number of the duplicate processor IDs */
|
||||
static int nr_duplicate_ids __initdata;
|
||||
|
||||
/* Used to store the unique processor IDs */
|
||||
static int unique_processor_ids[] __initdata = {
|
||||
[0 ... NR_CPUS - 1] = -1,
|
||||
};
|
||||
|
||||
/* Used to store the duplicate processor IDs */
|
||||
static int duplicate_processor_ids[] __initdata = {
|
||||
[0 ... NR_CPUS - 1] = -1,
|
||||
};
|
||||
|
||||
static void __init processor_validated_ids_update(int proc_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (nr_unique_ids == NR_CPUS||nr_duplicate_ids == NR_CPUS)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Firstly, compare the proc_id with duplicate IDs, if the proc_id is
|
||||
* already in the IDs, do nothing.
|
||||
*/
|
||||
for (i = 0; i < nr_duplicate_ids; i++) {
|
||||
if (duplicate_processor_ids[i] == proc_id)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Secondly, compare the proc_id with unique IDs, if the proc_id is in
|
||||
* the IDs, put it in the duplicate IDs.
|
||||
*/
|
||||
for (i = 0; i < nr_unique_ids; i++) {
|
||||
if (unique_processor_ids[i] == proc_id) {
|
||||
duplicate_processor_ids[nr_duplicate_ids] = proc_id;
|
||||
nr_duplicate_ids++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Lastly, the proc_id is a unique ID, put it in the unique IDs.
|
||||
*/
|
||||
unique_processor_ids[nr_unique_ids] = proc_id;
|
||||
nr_unique_ids++;
|
||||
}
|
||||
|
||||
static acpi_status __init acpi_processor_ids_walk(acpi_handle handle,
|
||||
u32 lvl,
|
||||
void *context,
|
||||
void **rv)
|
||||
{
|
||||
acpi_status status;
|
||||
union acpi_object object = { 0 };
|
||||
struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
|
||||
|
||||
status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
|
||||
if (ACPI_FAILURE(status))
|
||||
acpi_handle_info(handle, "Not get the processor object\n");
|
||||
else
|
||||
processor_validated_ids_update(object.processor.proc_id);
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static void __init acpi_processor_check_duplicates(void)
|
||||
{
|
||||
/* Search all processor nodes in ACPI namespace */
|
||||
acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
|
||||
ACPI_UINT32_MAX,
|
||||
acpi_processor_ids_walk,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
bool __init acpi_processor_validate_proc_id(int proc_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* compare the proc_id with duplicate IDs, if the proc_id is already
|
||||
* in the duplicate IDs, return true, otherwise, return false.
|
||||
*/
|
||||
for (i = 0; i < nr_duplicate_ids; i++) {
|
||||
if (duplicate_processor_ids[i] == proc_id)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void __init acpi_processor_init(void)
|
||||
{
|
||||
acpi_processor_check_duplicates();
|
||||
acpi_scan_add_handler_with_hotplug(&processor_handler, "processor");
|
||||
acpi_scan_add_handler(&processor_container_handler);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1195,6 +1195,7 @@ static int __init acpi_init(void)
|
|||
acpi_wakeup_device_init();
|
||||
acpi_debugger_init();
|
||||
acpi_setup_sb_notify_handler();
|
||||
acpi_set_processor_mapping();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,10 +40,8 @@ int acpi_sysfs_init(void);
|
|||
void acpi_container_init(void);
|
||||
void acpi_memory_hotplug_init(void);
|
||||
#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
|
||||
int acpi_ioapic_add(struct acpi_pci_root *root);
|
||||
int acpi_ioapic_remove(struct acpi_pci_root *root);
|
||||
#else
|
||||
static inline int acpi_ioapic_add(struct acpi_pci_root *root) { return 0; }
|
||||
static inline int acpi_ioapic_remove(struct acpi_pci_root *root) { return 0; }
|
||||
#endif
|
||||
#ifdef CONFIG_ACPI_DOCK
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ static acpi_status setup_res(struct acpi_resource *acpi_res, void *data)
|
|||
struct resource_win win;
|
||||
|
||||
res->flags = 0;
|
||||
if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM) == 0)
|
||||
if (acpi_dev_filter_resource_type(acpi_res, IORESOURCE_MEM))
|
||||
return AE_OK;
|
||||
|
||||
if (!acpi_dev_resource_memory(acpi_res, res)) {
|
||||
|
|
@ -97,7 +97,7 @@ static acpi_status handle_ioapic_add(acpi_handle handle, u32 lvl,
|
|||
unsigned long long gsi_base;
|
||||
struct acpi_pci_ioapic *ioapic;
|
||||
struct pci_dev *dev = NULL;
|
||||
struct resource *res = NULL;
|
||||
struct resource *res = NULL, *pci_res = NULL, *crs_res;
|
||||
char *type = NULL;
|
||||
|
||||
if (!acpi_is_ioapic(handle, &type))
|
||||
|
|
@ -137,23 +137,30 @@ static acpi_status handle_ioapic_add(acpi_handle handle, u32 lvl,
|
|||
pci_set_master(dev);
|
||||
if (pci_request_region(dev, 0, type))
|
||||
goto exit_disable;
|
||||
res = &dev->resource[0];
|
||||
pci_res = &dev->resource[0];
|
||||
ioapic->pdev = dev;
|
||||
} else {
|
||||
pci_dev_put(dev);
|
||||
dev = NULL;
|
||||
|
||||
res = &ioapic->res;
|
||||
acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, res);
|
||||
if (res->flags == 0) {
|
||||
acpi_handle_warn(handle, "failed to get resource\n");
|
||||
goto exit_free;
|
||||
} else if (request_resource(&iomem_resource, res)) {
|
||||
acpi_handle_warn(handle, "failed to insert resource\n");
|
||||
goto exit_free;
|
||||
}
|
||||
}
|
||||
|
||||
crs_res = &ioapic->res;
|
||||
acpi_walk_resources(handle, METHOD_NAME__CRS, setup_res, crs_res);
|
||||
crs_res->name = type;
|
||||
crs_res->flags |= IORESOURCE_BUSY;
|
||||
if (crs_res->flags == 0) {
|
||||
acpi_handle_warn(handle, "failed to get resource\n");
|
||||
goto exit_release;
|
||||
} else if (insert_resource(&iomem_resource, crs_res)) {
|
||||
acpi_handle_warn(handle, "failed to insert resource\n");
|
||||
goto exit_release;
|
||||
}
|
||||
|
||||
/* try pci resource first, then "_CRS" resource */
|
||||
res = pci_res;
|
||||
if (!res || !res->flags)
|
||||
res = crs_res;
|
||||
|
||||
if (acpi_register_ioapic(handle, res->start, (u32)gsi_base)) {
|
||||
acpi_handle_warn(handle, "failed to register IOAPIC\n");
|
||||
goto exit_release;
|
||||
|
|
@ -174,14 +181,13 @@ done:
|
|||
exit_release:
|
||||
if (dev)
|
||||
pci_release_region(dev, 0);
|
||||
else
|
||||
release_resource(res);
|
||||
if (ioapic->res.flags && ioapic->res.parent)
|
||||
release_resource(&ioapic->res);
|
||||
exit_disable:
|
||||
if (dev)
|
||||
pci_disable_device(dev);
|
||||
exit_put:
|
||||
pci_dev_put(dev);
|
||||
exit_free:
|
||||
kfree(ioapic);
|
||||
exit:
|
||||
mutex_unlock(&ioapic_list_lock);
|
||||
|
|
@ -189,13 +195,13 @@ exit:
|
|||
return AE_OK;
|
||||
}
|
||||
|
||||
int acpi_ioapic_add(struct acpi_pci_root *root)
|
||||
int acpi_ioapic_add(acpi_handle root_handle)
|
||||
{
|
||||
acpi_status status, retval = AE_OK;
|
||||
|
||||
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root->device->handle,
|
||||
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, root_handle,
|
||||
UINT_MAX, handle_ioapic_add, NULL,
|
||||
root->device->handle, (void **)&retval);
|
||||
root_handle, (void **)&retval);
|
||||
|
||||
return ACPI_SUCCESS(status) && ACPI_SUCCESS(retval) ? 0 : -ENODEV;
|
||||
}
|
||||
|
|
@ -217,9 +223,9 @@ int acpi_ioapic_remove(struct acpi_pci_root *root)
|
|||
pci_release_region(ioapic->pdev, 0);
|
||||
pci_disable_device(ioapic->pdev);
|
||||
pci_dev_put(ioapic->pdev);
|
||||
} else if (ioapic->res.flags && ioapic->res.parent) {
|
||||
release_resource(&ioapic->res);
|
||||
}
|
||||
if (ioapic->res.flags && ioapic->res.parent)
|
||||
release_resource(&ioapic->res);
|
||||
list_del(&ioapic->list);
|
||||
kfree(ioapic);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -614,7 +614,17 @@ static int acpi_pci_root_add(struct acpi_device *device,
|
|||
if (hotadd) {
|
||||
pcibios_resource_survey_bus(root->bus);
|
||||
pci_assign_unassigned_root_bus_resources(root->bus);
|
||||
acpi_ioapic_add(root);
|
||||
/*
|
||||
* This is only called for the hotadd case. For the boot-time
|
||||
* case, we need to wait until after PCI initialization in
|
||||
* order to deal with IOAPICs mapped in on a PCI BAR.
|
||||
*
|
||||
* This is currently x86-specific, because acpi_ioapic_add()
|
||||
* is an empty function without CONFIG_ACPI_HOTPLUG_IOAPIC.
|
||||
* And CONFIG_ACPI_HOTPLUG_IOAPIC depends on CONFIG_X86_IO_APIC
|
||||
* (see drivers/acpi/Kconfig).
|
||||
*/
|
||||
acpi_ioapic_add(root->device->handle);
|
||||
}
|
||||
|
||||
pci_lock_rescan_remove();
|
||||
|
|
|
|||
|
|
@ -32,12 +32,12 @@ static struct acpi_table_madt *get_madt_table(void)
|
|||
}
|
||||
|
||||
static int map_lapic_id(struct acpi_subtable_header *entry,
|
||||
u32 acpi_id, phys_cpuid_t *apic_id)
|
||||
u32 acpi_id, phys_cpuid_t *apic_id, bool ignore_disabled)
|
||||
{
|
||||
struct acpi_madt_local_apic *lapic =
|
||||
container_of(entry, struct acpi_madt_local_apic, header);
|
||||
|
||||
if (!(lapic->lapic_flags & ACPI_MADT_ENABLED))
|
||||
if (ignore_disabled && !(lapic->lapic_flags & ACPI_MADT_ENABLED))
|
||||
return -ENODEV;
|
||||
|
||||
if (lapic->processor_id != acpi_id)
|
||||
|
|
@ -48,12 +48,13 @@ static int map_lapic_id(struct acpi_subtable_header *entry,
|
|||
}
|
||||
|
||||
static int map_x2apic_id(struct acpi_subtable_header *entry,
|
||||
int device_declaration, u32 acpi_id, phys_cpuid_t *apic_id)
|
||||
int device_declaration, u32 acpi_id, phys_cpuid_t *apic_id,
|
||||
bool ignore_disabled)
|
||||
{
|
||||
struct acpi_madt_local_x2apic *apic =
|
||||
container_of(entry, struct acpi_madt_local_x2apic, header);
|
||||
|
||||
if (!(apic->lapic_flags & ACPI_MADT_ENABLED))
|
||||
if (ignore_disabled && !(apic->lapic_flags & ACPI_MADT_ENABLED))
|
||||
return -ENODEV;
|
||||
|
||||
if (device_declaration && (apic->uid == acpi_id)) {
|
||||
|
|
@ -65,12 +66,13 @@ static int map_x2apic_id(struct acpi_subtable_header *entry,
|
|||
}
|
||||
|
||||
static int map_lsapic_id(struct acpi_subtable_header *entry,
|
||||
int device_declaration, u32 acpi_id, phys_cpuid_t *apic_id)
|
||||
int device_declaration, u32 acpi_id, phys_cpuid_t *apic_id,
|
||||
bool ignore_disabled)
|
||||
{
|
||||
struct acpi_madt_local_sapic *lsapic =
|
||||
container_of(entry, struct acpi_madt_local_sapic, header);
|
||||
|
||||
if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED))
|
||||
if (ignore_disabled && !(lsapic->lapic_flags & ACPI_MADT_ENABLED))
|
||||
return -ENODEV;
|
||||
|
||||
if (device_declaration) {
|
||||
|
|
@ -87,12 +89,13 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
|
|||
* Retrieve the ARM CPU physical identifier (MPIDR)
|
||||
*/
|
||||
static int map_gicc_mpidr(struct acpi_subtable_header *entry,
|
||||
int device_declaration, u32 acpi_id, phys_cpuid_t *mpidr)
|
||||
int device_declaration, u32 acpi_id, phys_cpuid_t *mpidr,
|
||||
bool ignore_disabled)
|
||||
{
|
||||
struct acpi_madt_generic_interrupt *gicc =
|
||||
container_of(entry, struct acpi_madt_generic_interrupt, header);
|
||||
|
||||
if (!(gicc->flags & ACPI_MADT_ENABLED))
|
||||
if (ignore_disabled && !(gicc->flags & ACPI_MADT_ENABLED))
|
||||
return -ENODEV;
|
||||
|
||||
/* device_declaration means Device object in DSDT, in the
|
||||
|
|
@ -109,7 +112,7 @@ static int map_gicc_mpidr(struct acpi_subtable_header *entry,
|
|||
}
|
||||
|
||||
static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt,
|
||||
int type, u32 acpi_id)
|
||||
int type, u32 acpi_id, bool ignore_disabled)
|
||||
{
|
||||
unsigned long madt_end, entry;
|
||||
phys_cpuid_t phys_id = PHYS_CPUID_INVALID; /* CPU hardware ID */
|
||||
|
|
@ -127,16 +130,20 @@ static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt,
|
|||
struct acpi_subtable_header *header =
|
||||
(struct acpi_subtable_header *)entry;
|
||||
if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
|
||||
if (!map_lapic_id(header, acpi_id, &phys_id))
|
||||
if (!map_lapic_id(header, acpi_id, &phys_id,
|
||||
ignore_disabled))
|
||||
break;
|
||||
} else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) {
|
||||
if (!map_x2apic_id(header, type, acpi_id, &phys_id))
|
||||
if (!map_x2apic_id(header, type, acpi_id, &phys_id,
|
||||
ignore_disabled))
|
||||
break;
|
||||
} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
|
||||
if (!map_lsapic_id(header, type, acpi_id, &phys_id))
|
||||
if (!map_lsapic_id(header, type, acpi_id, &phys_id,
|
||||
ignore_disabled))
|
||||
break;
|
||||
} else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
|
||||
if (!map_gicc_mpidr(header, type, acpi_id, &phys_id))
|
||||
if (!map_gicc_mpidr(header, type, acpi_id, &phys_id,
|
||||
ignore_disabled))
|
||||
break;
|
||||
}
|
||||
entry += header->length;
|
||||
|
|
@ -156,14 +163,15 @@ phys_cpuid_t __init acpi_map_madt_entry(u32 acpi_id)
|
|||
if (!madt)
|
||||
return PHYS_CPUID_INVALID;
|
||||
|
||||
rv = map_madt_entry(madt, 1, acpi_id);
|
||||
rv = map_madt_entry(madt, 1, acpi_id, true);
|
||||
|
||||
early_acpi_os_unmap_memory(madt, tbl_size);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
|
||||
static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id,
|
||||
bool ignore_disabled)
|
||||
{
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
union acpi_object *obj;
|
||||
|
|
@ -184,30 +192,38 @@ static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
|
|||
|
||||
header = (struct acpi_subtable_header *)obj->buffer.pointer;
|
||||
if (header->type == ACPI_MADT_TYPE_LOCAL_APIC)
|
||||
map_lapic_id(header, acpi_id, &phys_id);
|
||||
map_lapic_id(header, acpi_id, &phys_id, ignore_disabled);
|
||||
else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC)
|
||||
map_lsapic_id(header, type, acpi_id, &phys_id);
|
||||
map_lsapic_id(header, type, acpi_id, &phys_id, ignore_disabled);
|
||||
else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC)
|
||||
map_x2apic_id(header, type, acpi_id, &phys_id);
|
||||
map_x2apic_id(header, type, acpi_id, &phys_id, ignore_disabled);
|
||||
else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT)
|
||||
map_gicc_mpidr(header, type, acpi_id, &phys_id);
|
||||
map_gicc_mpidr(header, type, acpi_id, &phys_id,
|
||||
ignore_disabled);
|
||||
|
||||
exit:
|
||||
kfree(buffer.pointer);
|
||||
return phys_id;
|
||||
}
|
||||
|
||||
phys_cpuid_t acpi_get_phys_id(acpi_handle handle, int type, u32 acpi_id)
|
||||
static phys_cpuid_t __acpi_get_phys_id(acpi_handle handle, int type,
|
||||
u32 acpi_id, bool ignore_disabled)
|
||||
{
|
||||
phys_cpuid_t phys_id;
|
||||
|
||||
phys_id = map_mat_entry(handle, type, acpi_id);
|
||||
phys_id = map_mat_entry(handle, type, acpi_id, ignore_disabled);
|
||||
if (invalid_phys_cpuid(phys_id))
|
||||
phys_id = map_madt_entry(get_madt_table(), type, acpi_id);
|
||||
phys_id = map_madt_entry(get_madt_table(), type, acpi_id,
|
||||
ignore_disabled);
|
||||
|
||||
return phys_id;
|
||||
}
|
||||
|
||||
phys_cpuid_t acpi_get_phys_id(acpi_handle handle, int type, u32 acpi_id)
|
||||
{
|
||||
return __acpi_get_phys_id(handle, type, acpi_id, true);
|
||||
}
|
||||
|
||||
int acpi_map_cpuid(phys_cpuid_t phys_id, u32 acpi_id)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
|
|
@ -264,6 +280,79 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_get_cpuid);
|
||||
|
||||
#ifdef CONFIG_ACPI_HOTPLUG_CPU
|
||||
static bool __init
|
||||
map_processor(acpi_handle handle, phys_cpuid_t *phys_id, int *cpuid)
|
||||
{
|
||||
int type, id;
|
||||
u32 acpi_id;
|
||||
acpi_status status;
|
||||
acpi_object_type acpi_type;
|
||||
unsigned long long tmp;
|
||||
union acpi_object object = { 0 };
|
||||
struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
|
||||
|
||||
status = acpi_get_type(handle, &acpi_type);
|
||||
if (ACPI_FAILURE(status))
|
||||
return false;
|
||||
|
||||
switch (acpi_type) {
|
||||
case ACPI_TYPE_PROCESSOR:
|
||||
status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
|
||||
if (ACPI_FAILURE(status))
|
||||
return false;
|
||||
acpi_id = object.processor.proc_id;
|
||||
|
||||
/* validate the acpi_id */
|
||||
if(acpi_processor_validate_proc_id(acpi_id))
|
||||
return false;
|
||||
break;
|
||||
case ACPI_TYPE_DEVICE:
|
||||
status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp);
|
||||
if (ACPI_FAILURE(status))
|
||||
return false;
|
||||
acpi_id = tmp;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
|
||||
|
||||
*phys_id = __acpi_get_phys_id(handle, type, acpi_id, false);
|
||||
id = acpi_map_cpuid(*phys_id, acpi_id);
|
||||
|
||||
if (id < 0)
|
||||
return false;
|
||||
*cpuid = id;
|
||||
return true;
|
||||
}
|
||||
|
||||
static acpi_status __init
|
||||
set_processor_node_mapping(acpi_handle handle, u32 lvl, void *context,
|
||||
void **rv)
|
||||
{
|
||||
phys_cpuid_t phys_id;
|
||||
int cpu_id;
|
||||
|
||||
if (!map_processor(handle, &phys_id, &cpu_id))
|
||||
return AE_ERROR;
|
||||
|
||||
acpi_map_cpu2node(handle, cpu_id, phys_id);
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
void __init acpi_set_processor_mapping(void)
|
||||
{
|
||||
/* Set persistent cpu <-> node mapping for all processors. */
|
||||
acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
|
||||
ACPI_UINT32_MAX, set_processor_node_mapping,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
#else
|
||||
void __init acpi_set_processor_mapping(void) {}
|
||||
#endif /* CONFIG_ACPI_HOTPLUG_CPU */
|
||||
|
||||
#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
|
||||
static int get_ioapic_id(struct acpi_subtable_header *entry, u32 gsi_base,
|
||||
u64 *phys_addr, int *ioapic_id)
|
||||
|
|
|
|||
Loading…
Reference in a new issue