aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/cpufreq/intel_pstate.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 81e0062a6d2a..3b5c5359a44b 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -25,6 +25,7 @@
25#include <linux/types.h> 25#include <linux/types.h>
26#include <linux/fs.h> 26#include <linux/fs.h>
27#include <linux/debugfs.h> 27#include <linux/debugfs.h>
28#include <linux/acpi.h>
28#include <trace/events/power.h> 29#include <trace/events/power.h>
29 30
30#include <asm/div64.h> 31#include <asm/div64.h>
@@ -779,6 +780,72 @@ static void copy_cpu_funcs(struct pstate_funcs *funcs)
779 pstate_funcs.set = funcs->set; 780 pstate_funcs.set = funcs->set;
780} 781}
781 782
783#if IS_ENABLED(CONFIG_ACPI)
784#include <acpi/processor.h>
785
786static bool intel_pstate_no_acpi_pss(void)
787{
788 int i;
789
790 for_each_possible_cpu(i) {
791 acpi_status status;
792 union acpi_object *pss;
793 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
794 struct acpi_processor *pr = per_cpu(processors, i);
795
796 if (!pr)
797 continue;
798
799 status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer);
800 if (ACPI_FAILURE(status))
801 continue;
802
803 pss = buffer.pointer;
804 if (pss && pss->type == ACPI_TYPE_PACKAGE) {
805 kfree(pss);
806 return false;
807 }
808
809 kfree(pss);
810 }
811
812 return true;
813}
814
815struct hw_vendor_info {
816 u16 valid;
817 char oem_id[ACPI_OEM_ID_SIZE];
818 char oem_table_id[ACPI_OEM_TABLE_ID_SIZE];
819};
820
821/* Hardware vendor-specific info that has its own power management modes */
822static struct hw_vendor_info vendor_info[] = {
823 {1, "HP ", "ProLiant"},
824 {0, "", ""},
825};
826
827static bool intel_pstate_platform_pwr_mgmt_exists(void)
828{
829 struct acpi_table_header hdr;
830 struct hw_vendor_info *v_info;
831
832 if (acpi_disabled
833 || ACPI_FAILURE(acpi_get_table_header(ACPI_SIG_FADT, 0, &hdr)))
834 return false;
835
836 for (v_info = vendor_info; v_info->valid; v_info++) {
837 if (!strncmp(hdr.oem_id, v_info->oem_id, ACPI_OEM_ID_SIZE)
838 && !strncmp(hdr.oem_table_id, v_info->oem_table_id, ACPI_OEM_TABLE_ID_SIZE)
839 && intel_pstate_no_acpi_pss())
840 return true;
841 }
842
843 return false;
844}
845#else /* CONFIG_ACPI not enabled */
846static inline bool intel_pstate_platform_pwr_mgmt_exists(void) { return false; }
847#endif /* CONFIG_ACPI */
848
782static int __init intel_pstate_init(void) 849static int __init intel_pstate_init(void)
783{ 850{
784 int cpu, rc = 0; 851 int cpu, rc = 0;
@@ -792,6 +859,13 @@ static int __init intel_pstate_init(void)
792 if (!id) 859 if (!id)
793 return -ENODEV; 860 return -ENODEV;
794 861
862 /*
863 * The Intel pstate driver will be ignored if the platform
864 * firmware has its own power management modes.
865 */
866 if (intel_pstate_platform_pwr_mgmt_exists())
867 return -ENODEV;
868
795 cpu_info = (struct cpu_defaults *)id->driver_data; 869 cpu_info = (struct cpu_defaults *)id->driver_data;
796 870
797 copy_pid_params(&cpu_info->pid_policy); 871 copy_pid_params(&cpu_info->pid_policy);