diff options
| -rw-r--r-- | drivers/acpi/Makefile | 1 | ||||
| -rw-r--r-- | drivers/acpi/bus.c | 2 | ||||
| -rw-r--r-- | drivers/acpi/internal.h | 1 | ||||
| -rw-r--r-- | drivers/acpi/processor_core.c | 69 | ||||
| -rw-r--r-- | drivers/acpi/processor_pdc.c | 108 | ||||
| -rw-r--r-- | include/acpi/processor.h | 3 |
6 files changed, 115 insertions, 69 deletions
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index c7b10b4298e9..66cc3f36a954 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
| @@ -32,6 +32,7 @@ acpi-$(CONFIG_ACPI_SLEEP) += proc.o | |||
| 32 | # | 32 | # |
| 33 | acpi-y += bus.o glue.o | 33 | acpi-y += bus.o glue.o |
| 34 | acpi-y += scan.o | 34 | acpi-y += scan.o |
| 35 | acpi-y += processor_pdc.o | ||
| 35 | acpi-y += ec.o | 36 | acpi-y += ec.o |
| 36 | acpi-$(CONFIG_ACPI_DOCK) += dock.o | 37 | acpi-$(CONFIG_ACPI_DOCK) += dock.o |
| 37 | acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o | 38 | acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 65f7e335f122..0bdf24a6fd01 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
| @@ -888,6 +888,8 @@ static int __init acpi_bus_init(void) | |||
| 888 | goto error1; | 888 | goto error1; |
| 889 | } | 889 | } |
| 890 | 890 | ||
| 891 | acpi_early_processor_set_pdc(); | ||
| 892 | |||
| 891 | /* | 893 | /* |
| 892 | * Maybe EC region is required at bus_scan/acpi_get_devices. So it | 894 | * Maybe EC region is required at bus_scan/acpi_get_devices. So it |
| 893 | * is necessary to enable it as early as possible. | 895 | * is necessary to enable it as early as possible. |
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 074cf8682d52..cb28e0502acc 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
| @@ -43,6 +43,7 @@ int acpi_power_transition(struct acpi_device *device, int state); | |||
| 43 | extern int acpi_power_nocheck; | 43 | extern int acpi_power_nocheck; |
| 44 | 44 | ||
| 45 | int acpi_wakeup_device_init(void); | 45 | int acpi_wakeup_device_init(void); |
| 46 | void acpi_early_processor_set_pdc(void); | ||
| 46 | 47 | ||
| 47 | /* -------------------------------------------------------------------------- | 48 | /* -------------------------------------------------------------------------- |
| 48 | Embedded Controller | 49 | Embedded Controller |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 41731236f9a1..a19a4ff962ea 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
| @@ -124,29 +124,6 @@ static const struct file_operations acpi_processor_info_fops = { | |||
| 124 | 124 | ||
| 125 | DEFINE_PER_CPU(struct acpi_processor *, processors); | 125 | DEFINE_PER_CPU(struct acpi_processor *, processors); |
| 126 | struct acpi_processor_errata errata __read_mostly; | 126 | struct acpi_processor_errata errata __read_mostly; |
| 127 | static int set_no_mwait(const struct dmi_system_id *id) | ||
| 128 | { | ||
| 129 | printk(KERN_NOTICE PREFIX "%s detected - " | ||
| 130 | "disabling mwait for CPU C-states\n", id->ident); | ||
| 131 | idle_nomwait = 1; | ||
| 132 | return 0; | ||
| 133 | } | ||
| 134 | |||
| 135 | static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { | ||
| 136 | { | ||
| 137 | set_no_mwait, "IFL91 board", { | ||
| 138 | DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), | ||
| 139 | DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"), | ||
| 140 | DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"), | ||
| 141 | DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL}, | ||
| 142 | { | ||
| 143 | set_no_mwait, "Extensa 5220", { | ||
| 144 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), | ||
| 145 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
| 146 | DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), | ||
| 147 | DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL}, | ||
| 148 | {}, | ||
| 149 | }; | ||
| 150 | 127 | ||
| 151 | /* -------------------------------------------------------------------------- | 128 | /* -------------------------------------------------------------------------- |
| 152 | Errata Handling | 129 | Errata Handling |
| @@ -277,45 +254,6 @@ static int acpi_processor_errata(struct acpi_processor *pr) | |||
| 277 | } | 254 | } |
| 278 | 255 | ||
| 279 | /* -------------------------------------------------------------------------- | 256 | /* -------------------------------------------------------------------------- |
| 280 | Common ACPI processor functions | ||
| 281 | -------------------------------------------------------------------------- */ | ||
| 282 | |||
| 283 | /* | ||
| 284 | * _PDC is required for a BIOS-OS handshake for most of the newer | ||
| 285 | * ACPI processor features. | ||
| 286 | */ | ||
| 287 | static int acpi_processor_set_pdc(struct acpi_processor *pr) | ||
| 288 | { | ||
| 289 | struct acpi_object_list *pdc_in = pr->pdc; | ||
| 290 | acpi_status status = AE_OK; | ||
| 291 | |||
| 292 | |||
| 293 | if (!pdc_in) | ||
| 294 | return status; | ||
| 295 | if (idle_nomwait) { | ||
| 296 | /* | ||
| 297 | * If mwait is disabled for CPU C-states, the C2C3_FFH access | ||
| 298 | * mode will be disabled in the parameter of _PDC object. | ||
| 299 | * Of course C1_FFH access mode will also be disabled. | ||
| 300 | */ | ||
| 301 | union acpi_object *obj; | ||
| 302 | u32 *buffer = NULL; | ||
| 303 | |||
| 304 | obj = pdc_in->pointer; | ||
| 305 | buffer = (u32 *)(obj->buffer.pointer); | ||
| 306 | buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); | ||
| 307 | |||
| 308 | } | ||
| 309 | status = acpi_evaluate_object(pr->handle, "_PDC", pdc_in, NULL); | ||
| 310 | |||
| 311 | if (ACPI_FAILURE(status)) | ||
| 312 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
| 313 | "Could not evaluate _PDC, using legacy perf. control...\n")); | ||
| 314 | |||
| 315 | return status; | ||
| 316 | } | ||
| 317 | |||
| 318 | /* -------------------------------------------------------------------------- | ||
| 319 | FS Interface (/proc) | 257 | FS Interface (/proc) |
| 320 | -------------------------------------------------------------------------- */ | 258 | -------------------------------------------------------------------------- */ |
| 321 | 259 | ||
| @@ -825,9 +763,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) | |||
| 825 | } | 763 | } |
| 826 | 764 | ||
| 827 | /* _PDC call should be done before doing anything else (if reqd.). */ | 765 | /* _PDC call should be done before doing anything else (if reqd.). */ |
| 828 | arch_acpi_processor_init_pdc(pr); | ||
| 829 | acpi_processor_set_pdc(pr); | 766 | acpi_processor_set_pdc(pr); |
| 830 | arch_acpi_processor_cleanup_pdc(pr); | ||
| 831 | 767 | ||
| 832 | #ifdef CONFIG_CPU_FREQ | 768 | #ifdef CONFIG_CPU_FREQ |
| 833 | acpi_processor_ppc_has_changed(pr, 0); | 769 | acpi_processor_ppc_has_changed(pr, 0); |
| @@ -1145,11 +1081,6 @@ static int __init acpi_processor_init(void) | |||
| 1145 | if (!acpi_processor_dir) | 1081 | if (!acpi_processor_dir) |
| 1146 | return -ENOMEM; | 1082 | return -ENOMEM; |
| 1147 | #endif | 1083 | #endif |
| 1148 | /* | ||
| 1149 | * Check whether the system is DMI table. If yes, OSPM | ||
| 1150 | * should not use mwait for CPU-states. | ||
| 1151 | */ | ||
| 1152 | dmi_check_system(processor_idle_dmi_table); | ||
| 1153 | result = cpuidle_register_driver(&acpi_idle_driver); | 1084 | result = cpuidle_register_driver(&acpi_idle_driver); |
| 1154 | if (result < 0) | 1085 | if (result < 0) |
| 1155 | goto out_proc; | 1086 | goto out_proc; |
diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c new file mode 100644 index 000000000000..b416c32dda04 --- /dev/null +++ b/drivers/acpi/processor_pdc.c | |||
| @@ -0,0 +1,108 @@ | |||
| 1 | #include <linux/dmi.h> | ||
| 2 | |||
| 3 | #include <acpi/acpi_drivers.h> | ||
| 4 | #include <acpi/processor.h> | ||
| 5 | |||
| 6 | #include "internal.h" | ||
| 7 | |||
| 8 | #define PREFIX "ACPI: " | ||
| 9 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | ||
| 10 | ACPI_MODULE_NAME("processor_pdc"); | ||
| 11 | |||
| 12 | static int set_no_mwait(const struct dmi_system_id *id) | ||
| 13 | { | ||
| 14 | printk(KERN_NOTICE PREFIX "%s detected - " | ||
| 15 | "disabling mwait for CPU C-states\n", id->ident); | ||
| 16 | idle_nomwait = 1; | ||
| 17 | return 0; | ||
| 18 | } | ||
| 19 | |||
| 20 | static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { | ||
| 21 | { | ||
| 22 | set_no_mwait, "IFL91 board", { | ||
| 23 | DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), | ||
| 24 | DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"), | ||
| 25 | DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"), | ||
| 26 | DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL}, | ||
| 27 | { | ||
| 28 | set_no_mwait, "Extensa 5220", { | ||
| 29 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), | ||
| 30 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
| 31 | DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), | ||
| 32 | DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL}, | ||
| 33 | {}, | ||
| 34 | }; | ||
| 35 | |||
| 36 | /* | ||
| 37 | * _PDC is required for a BIOS-OS handshake for most of the newer | ||
| 38 | * ACPI processor features. | ||
| 39 | */ | ||
| 40 | static int acpi_processor_eval_pdc(struct acpi_processor *pr) | ||
| 41 | { | ||
| 42 | struct acpi_object_list *pdc_in = pr->pdc; | ||
| 43 | acpi_status status = AE_OK; | ||
| 44 | |||
| 45 | if (!pdc_in) | ||
| 46 | return status; | ||
| 47 | if (idle_nomwait) { | ||
| 48 | /* | ||
| 49 | * If mwait is disabled for CPU C-states, the C2C3_FFH access | ||
| 50 | * mode will be disabled in the parameter of _PDC object. | ||
| 51 | * Of course C1_FFH access mode will also be disabled. | ||
| 52 | */ | ||
| 53 | union acpi_object *obj; | ||
| 54 | u32 *buffer = NULL; | ||
| 55 | |||
| 56 | obj = pdc_in->pointer; | ||
| 57 | buffer = (u32 *)(obj->buffer.pointer); | ||
| 58 | buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); | ||
| 59 | |||
| 60 | } | ||
| 61 | status = acpi_evaluate_object(pr->handle, "_PDC", pdc_in, NULL); | ||
| 62 | |||
| 63 | if (ACPI_FAILURE(status)) | ||
| 64 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
| 65 | "Could not evaluate _PDC, using legacy perf. control.\n")); | ||
| 66 | |||
| 67 | return status; | ||
| 68 | } | ||
| 69 | |||
| 70 | void acpi_processor_set_pdc(struct acpi_processor *pr) | ||
| 71 | { | ||
| 72 | arch_acpi_processor_init_pdc(pr); | ||
| 73 | acpi_processor_eval_pdc(pr); | ||
| 74 | arch_acpi_processor_cleanup_pdc(pr); | ||
| 75 | } | ||
| 76 | EXPORT_SYMBOL_GPL(acpi_processor_set_pdc); | ||
| 77 | |||
| 78 | static acpi_status | ||
| 79 | early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
| 80 | { | ||
| 81 | struct acpi_processor pr; | ||
| 82 | |||
| 83 | pr.handle = handle; | ||
| 84 | |||
| 85 | /* x86 implementation looks at pr.id to determine some | ||
| 86 | * CPU capabilites. We can just hard code to 0 since we're | ||
| 87 | * assuming the CPUs in the system are homogenous and all | ||
| 88 | * have the same capabilities. | ||
| 89 | */ | ||
| 90 | pr.id = 0; | ||
| 91 | |||
| 92 | acpi_processor_set_pdc(&pr); | ||
| 93 | |||
| 94 | return AE_OK; | ||
| 95 | } | ||
| 96 | |||
| 97 | void acpi_early_processor_set_pdc(void) | ||
| 98 | { | ||
| 99 | /* | ||
| 100 | * Check whether the system is DMI table. If yes, OSPM | ||
| 101 | * should not use mwait for CPU-states. | ||
| 102 | */ | ||
| 103 | dmi_check_system(processor_idle_dmi_table); | ||
| 104 | |||
| 105 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, | ||
| 106 | ACPI_UINT32_MAX, | ||
| 107 | early_init_pdc, NULL, NULL, NULL); | ||
| 108 | } | ||
diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 29245c6b5c0e..a1b748a7a766 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h | |||
| @@ -325,6 +325,9 @@ static inline int acpi_processor_get_bios_limit(int cpu, unsigned int *limit) | |||
| 325 | 325 | ||
| 326 | #endif /* CONFIG_CPU_FREQ */ | 326 | #endif /* CONFIG_CPU_FREQ */ |
| 327 | 327 | ||
| 328 | /* in processor_pdc.c */ | ||
| 329 | void acpi_processor_set_pdc(struct acpi_processor *pr); | ||
| 330 | |||
| 328 | /* in processor_throttling.c */ | 331 | /* in processor_throttling.c */ |
| 329 | int acpi_processor_tstate_has_changed(struct acpi_processor *pr); | 332 | int acpi_processor_tstate_has_changed(struct acpi_processor *pr); |
| 330 | int acpi_processor_get_throttling_info(struct acpi_processor *pr); | 333 | int acpi_processor_get_throttling_info(struct acpi_processor *pr); |
