|
15 | 15 | #include <linux/kernel.h> |
16 | 16 | #include <linux/module.h> |
17 | 17 | #include <linux/pci.h> |
| 18 | +#include <linux/platform_device.h> |
18 | 19 |
|
19 | 20 | #include <acpi/processor.h> |
20 | 21 |
|
@@ -148,6 +149,34 @@ static int acpi_processor_errata(void) |
148 | 149 | return result; |
149 | 150 | } |
150 | 151 |
|
| 152 | +/* Create a platform device to represent a CPU frequency control mechanism. */ |
| 153 | +static void cpufreq_add_device(const char *name) |
| 154 | +{ |
| 155 | + struct platform_device *pdev; |
| 156 | + |
| 157 | + pdev = platform_device_register_simple(name, PLATFORM_DEVID_NONE, NULL, 0); |
| 158 | + if (IS_ERR(pdev)) |
| 159 | + pr_info("%s device creation failed: %ld\n", name, PTR_ERR(pdev)); |
| 160 | +} |
| 161 | + |
| 162 | +#ifdef CONFIG_X86 |
| 163 | +/* Check presence of Processor Clocking Control by searching for \_SB.PCCH. */ |
| 164 | +static void __init acpi_pcc_cpufreq_init(void) |
| 165 | +{ |
| 166 | + acpi_status status; |
| 167 | + acpi_handle handle; |
| 168 | + |
| 169 | + status = acpi_get_handle(NULL, "\\_SB", &handle); |
| 170 | + if (ACPI_FAILURE(status)) |
| 171 | + return; |
| 172 | + |
| 173 | + if (acpi_has_method(handle, "PCCH")) |
| 174 | + cpufreq_add_device("pcc-cpufreq"); |
| 175 | +} |
| 176 | +#else |
| 177 | +static void __init acpi_pcc_cpufreq_init(void) {} |
| 178 | +#endif /* CONFIG_X86 */ |
| 179 | + |
151 | 180 | /* Initialization */ |
152 | 181 | #ifdef CONFIG_ACPI_HOTPLUG_CPU |
153 | 182 | int __weak acpi_map_cpu(acpi_handle handle, |
@@ -280,14 +309,22 @@ static int acpi_processor_get_info(struct acpi_device *device) |
280 | 309 | dev_dbg(&device->dev, "Failed to get CPU physical ID.\n"); |
281 | 310 |
|
282 | 311 | pr->id = acpi_map_cpuid(pr->phys_id, pr->acpi_id); |
283 | | - if (!cpu0_initialized && !acpi_has_cpu_in_madt()) { |
| 312 | + if (!cpu0_initialized) { |
284 | 313 | cpu0_initialized = 1; |
285 | 314 | /* |
286 | 315 | * Handle UP system running SMP kernel, with no CPU |
287 | 316 | * entry in MADT |
288 | 317 | */ |
289 | | - if (invalid_logical_cpuid(pr->id) && (num_online_cpus() == 1)) |
| 318 | + if (!acpi_has_cpu_in_madt() && invalid_logical_cpuid(pr->id) && |
| 319 | + (num_online_cpus() == 1)) |
290 | 320 | pr->id = 0; |
| 321 | + /* |
| 322 | + * Check availability of Processor Performance Control by |
| 323 | + * looking at the presence of the _PCT object under the first |
| 324 | + * processor definition. |
| 325 | + */ |
| 326 | + if (acpi_has_method(pr->handle, "_PCT")) |
| 327 | + cpufreq_add_device("acpi-cpufreq"); |
291 | 328 | } |
292 | 329 |
|
293 | 330 | /* |
@@ -686,6 +723,7 @@ void __init acpi_processor_init(void) |
686 | 723 | acpi_processor_check_duplicates(); |
687 | 724 | acpi_scan_add_handler_with_hotplug(&processor_handler, "processor"); |
688 | 725 | acpi_scan_add_handler(&processor_container_handler); |
| 726 | + acpi_pcc_cpufreq_init(); |
689 | 727 | } |
690 | 728 |
|
691 | 729 | #ifdef CONFIG_ACPI_PROCESSOR_CSTATE |
|
0 commit comments