|
@@ -581,8 +581,87 @@ 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);
|
|
|
+}
|
|
|
+
|
|
|
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);
|
|
|
}
|