diff options
Diffstat (limited to 'drivers')
44 files changed, 738 insertions, 183 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index c205653e9644..ab686b310100 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
| @@ -31,10 +31,14 @@ menuconfig ACPI | |||
| 31 | ACPI CA, see: | 31 | ACPI CA, see: |
| 32 | <http://acpica.org/> | 32 | <http://acpica.org/> |
| 33 | 33 | ||
| 34 | ACPI is an open industry specification co-developed by | 34 | ACPI is an open industry specification originally co-developed by |
| 35 | Hewlett-Packard, Intel, Microsoft, Phoenix, and Toshiba. | 35 | Hewlett-Packard, Intel, Microsoft, Phoenix, and Toshiba. Currently, |
| 36 | it is developed by the ACPI Specification Working Group (ASWG) under | ||
| 37 | the UEFI Forum and any UEFI member can join the ASWG and contribute | ||
| 38 | to the ACPI specification. | ||
| 36 | The specification is available at: | 39 | The specification is available at: |
| 37 | <http://www.acpi.info> | 40 | <http://www.acpi.info> |
| 41 | <http://www.uefi.org/acpi/specs> | ||
| 38 | 42 | ||
| 39 | if ACPI | 43 | if ACPI |
| 40 | 44 | ||
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index f0fc6260266b..d9339b442a4e 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
| @@ -51,12 +51,6 @@ MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to " | |||
| 51 | " the driver to wait for userspace to write the undock sysfs file " | 51 | " the driver to wait for userspace to write the undock sysfs file " |
| 52 | " before undocking"); | 52 | " before undocking"); |
| 53 | 53 | ||
| 54 | static const struct acpi_device_id dock_device_ids[] = { | ||
| 55 | {"LNXDOCK", 0}, | ||
| 56 | {"", 0}, | ||
| 57 | }; | ||
| 58 | MODULE_DEVICE_TABLE(acpi, dock_device_ids); | ||
| 59 | |||
| 60 | struct dock_station { | 54 | struct dock_station { |
| 61 | acpi_handle handle; | 55 | acpi_handle handle; |
| 62 | unsigned long last_dock_time; | 56 | unsigned long last_dock_time; |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index f7fd72ac69cf..6776c599816f 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
| @@ -1219,10 +1219,9 @@ acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle) | |||
| 1219 | { | 1219 | { |
| 1220 | struct semaphore *sem = NULL; | 1220 | struct semaphore *sem = NULL; |
| 1221 | 1221 | ||
| 1222 | sem = acpi_os_allocate(sizeof(struct semaphore)); | 1222 | sem = acpi_os_allocate_zeroed(sizeof(struct semaphore)); |
| 1223 | if (!sem) | 1223 | if (!sem) |
| 1224 | return AE_NO_MEMORY; | 1224 | return AE_NO_MEMORY; |
| 1225 | memset(sem, 0, sizeof(struct semaphore)); | ||
| 1226 | 1225 | ||
| 1227 | sema_init(sem, initial_units); | 1226 | sema_init(sem, initial_units); |
| 1228 | 1227 | ||
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 964068553334..c1e31a41f949 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
| @@ -344,7 +344,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
| 344 | tz->trips.hot.flags.valid = 1; | 344 | tz->trips.hot.flags.valid = 1; |
| 345 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 345 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
| 346 | "Found hot threshold [%lu]\n", | 346 | "Found hot threshold [%lu]\n", |
| 347 | tz->trips.critical.temperature)); | 347 | tz->trips.hot.temperature)); |
| 348 | } | 348 | } |
| 349 | } | 349 | } |
| 350 | 350 | ||
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 0f5f78fa6545..bba526148583 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
| @@ -164,11 +164,10 @@ acpi_extract_package(union acpi_object *package, | |||
| 164 | * Validate output buffer. | 164 | * Validate output buffer. |
| 165 | */ | 165 | */ |
| 166 | if (buffer->length == ACPI_ALLOCATE_BUFFER) { | 166 | if (buffer->length == ACPI_ALLOCATE_BUFFER) { |
| 167 | buffer->pointer = ACPI_ALLOCATE(size_required); | 167 | buffer->pointer = ACPI_ALLOCATE_ZEROED(size_required); |
| 168 | if (!buffer->pointer) | 168 | if (!buffer->pointer) |
| 169 | return AE_NO_MEMORY; | 169 | return AE_NO_MEMORY; |
| 170 | buffer->length = size_required; | 170 | buffer->length = size_required; |
| 171 | memset(buffer->pointer, 0, size_required); | ||
| 172 | } else { | 171 | } else { |
| 173 | if (buffer->length < size_required) { | 172 | if (buffer->length < size_required) { |
| 174 | buffer->length = size_required; | 173 | buffer->length = size_required; |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 48c7e8af9c96..8b6990e417ec 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
| @@ -488,6 +488,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
| 488 | }, | 488 | }, |
| 489 | }, | 489 | }, |
| 490 | { | 490 | { |
| 491 | .callback = video_set_use_native_backlight, | ||
| 492 | .ident = "Thinkpad Helix", | ||
| 493 | .matches = { | ||
| 494 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 495 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Helix"), | ||
| 496 | }, | ||
| 497 | }, | ||
| 498 | { | ||
| 491 | .callback = video_set_use_native_backlight, | 499 | .callback = video_set_use_native_backlight, |
| 492 | .ident = "Dell Inspiron 7520", | 500 | .ident = "Dell Inspiron 7520", |
| 493 | .matches = { | 501 | .matches = { |
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 6f54962aae1d..ae098a261fcd 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
| @@ -705,6 +705,14 @@ static int pm_genpd_runtime_resume(struct device *dev) | |||
| 705 | return 0; | 705 | return 0; |
| 706 | } | 706 | } |
| 707 | 707 | ||
| 708 | static bool pd_ignore_unused; | ||
| 709 | static int __init pd_ignore_unused_setup(char *__unused) | ||
| 710 | { | ||
| 711 | pd_ignore_unused = true; | ||
| 712 | return 1; | ||
| 713 | } | ||
| 714 | __setup("pd_ignore_unused", pd_ignore_unused_setup); | ||
| 715 | |||
| 708 | /** | 716 | /** |
| 709 | * pm_genpd_poweroff_unused - Power off all PM domains with no devices in use. | 717 | * pm_genpd_poweroff_unused - Power off all PM domains with no devices in use. |
| 710 | */ | 718 | */ |
| @@ -712,6 +720,11 @@ void pm_genpd_poweroff_unused(void) | |||
| 712 | { | 720 | { |
| 713 | struct generic_pm_domain *genpd; | 721 | struct generic_pm_domain *genpd; |
| 714 | 722 | ||
| 723 | if (pd_ignore_unused) { | ||
| 724 | pr_warn("genpd: Not disabling unused power domains\n"); | ||
| 725 | return; | ||
| 726 | } | ||
| 727 | |||
| 715 | mutex_lock(&gpd_list_lock); | 728 | mutex_lock(&gpd_list_lock); |
| 716 | 729 | ||
| 717 | list_for_each_entry(genpd, &gpd_list, gpd_list_node) | 730 | list_for_each_entry(genpd, &gpd_list, gpd_list_node) |
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index 1e2b9db563ec..0e9cce82844b 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm | |||
| @@ -30,7 +30,7 @@ config ARM_EXYNOS_CPUFREQ | |||
| 30 | 30 | ||
| 31 | config ARM_EXYNOS4210_CPUFREQ | 31 | config ARM_EXYNOS4210_CPUFREQ |
| 32 | bool "SAMSUNG EXYNOS4210" | 32 | bool "SAMSUNG EXYNOS4210" |
| 33 | depends on CPU_EXYNOS4210 | 33 | depends on CPU_EXYNOS4210 && !ARCH_MULTIPLATFORM |
| 34 | default y | 34 | default y |
| 35 | select ARM_EXYNOS_CPUFREQ | 35 | select ARM_EXYNOS_CPUFREQ |
| 36 | help | 36 | help |
| @@ -41,7 +41,7 @@ config ARM_EXYNOS4210_CPUFREQ | |||
| 41 | 41 | ||
| 42 | config ARM_EXYNOS4X12_CPUFREQ | 42 | config ARM_EXYNOS4X12_CPUFREQ |
| 43 | bool "SAMSUNG EXYNOS4x12" | 43 | bool "SAMSUNG EXYNOS4x12" |
| 44 | depends on (SOC_EXYNOS4212 || SOC_EXYNOS4412) | 44 | depends on (SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM |
| 45 | default y | 45 | default y |
| 46 | select ARM_EXYNOS_CPUFREQ | 46 | select ARM_EXYNOS_CPUFREQ |
| 47 | help | 47 | help |
| @@ -52,7 +52,7 @@ config ARM_EXYNOS4X12_CPUFREQ | |||
| 52 | 52 | ||
| 53 | config ARM_EXYNOS5250_CPUFREQ | 53 | config ARM_EXYNOS5250_CPUFREQ |
| 54 | bool "SAMSUNG EXYNOS5250" | 54 | bool "SAMSUNG EXYNOS5250" |
| 55 | depends on SOC_EXYNOS5250 | 55 | depends on SOC_EXYNOS5250 && !ARCH_MULTIPLATFORM |
| 56 | default y | 56 | default y |
| 57 | select ARM_EXYNOS_CPUFREQ | 57 | select ARM_EXYNOS_CPUFREQ |
| 58 | help | 58 | help |
diff --git a/drivers/cpufreq/Kconfig.powerpc b/drivers/cpufreq/Kconfig.powerpc index ca0021a96e19..72564b701b4a 100644 --- a/drivers/cpufreq/Kconfig.powerpc +++ b/drivers/cpufreq/Kconfig.powerpc | |||
| @@ -54,3 +54,11 @@ config PPC_PASEMI_CPUFREQ | |||
| 54 | help | 54 | help |
| 55 | This adds the support for frequency switching on PA Semi | 55 | This adds the support for frequency switching on PA Semi |
| 56 | PWRficient processors. | 56 | PWRficient processors. |
| 57 | |||
| 58 | config POWERNV_CPUFREQ | ||
| 59 | tristate "CPU frequency scaling for IBM POWERNV platform" | ||
| 60 | depends on PPC_POWERNV | ||
| 61 | default y | ||
| 62 | help | ||
| 63 | This adds support for CPU frequency switching on IBM POWERNV | ||
| 64 | platform | ||
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 74945652dd7a..0dbb963c1aef 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile | |||
| @@ -86,6 +86,7 @@ obj-$(CONFIG_PPC_CORENET_CPUFREQ) += ppc-corenet-cpufreq.o | |||
| 86 | obj-$(CONFIG_CPU_FREQ_PMAC) += pmac32-cpufreq.o | 86 | obj-$(CONFIG_CPU_FREQ_PMAC) += pmac32-cpufreq.o |
| 87 | obj-$(CONFIG_CPU_FREQ_PMAC64) += pmac64-cpufreq.o | 87 | obj-$(CONFIG_CPU_FREQ_PMAC64) += pmac64-cpufreq.o |
| 88 | obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += pasemi-cpufreq.o | 88 | obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += pasemi-cpufreq.o |
| 89 | obj-$(CONFIG_POWERNV_CPUFREQ) += powernv-cpufreq.o | ||
| 89 | 90 | ||
| 90 | ################################################################################## | 91 | ################################################################################## |
| 91 | # Other platform drivers | 92 | # Other platform drivers |
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index d5eaedbe464f..000e4e0afd7e 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c | |||
| @@ -754,7 +754,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
| 754 | goto err_unreg; | 754 | goto err_unreg; |
| 755 | } | 755 | } |
| 756 | 756 | ||
| 757 | data->freq_table = kmalloc(sizeof(*data->freq_table) * | 757 | data->freq_table = kzalloc(sizeof(*data->freq_table) * |
| 758 | (perf->state_count+1), GFP_KERNEL); | 758 | (perf->state_count+1), GFP_KERNEL); |
| 759 | if (!data->freq_table) { | 759 | if (!data->freq_table) { |
| 760 | result = -ENOMEM; | 760 | result = -ENOMEM; |
diff --git a/drivers/cpufreq/at32ap-cpufreq.c b/drivers/cpufreq/at32ap-cpufreq.c index a1c79f549edb..7b612c8bb09e 100644 --- a/drivers/cpufreq/at32ap-cpufreq.c +++ b/drivers/cpufreq/at32ap-cpufreq.c | |||
| @@ -52,7 +52,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index) | |||
| 52 | static int at32_cpufreq_driver_init(struct cpufreq_policy *policy) | 52 | static int at32_cpufreq_driver_init(struct cpufreq_policy *policy) |
| 53 | { | 53 | { |
| 54 | unsigned int frequency, rate, min_freq; | 54 | unsigned int frequency, rate, min_freq; |
| 55 | static struct clk *cpuclk; | 55 | struct clk *cpuclk; |
| 56 | int retval, steps, i; | 56 | int retval, steps, i; |
| 57 | 57 | ||
| 58 | if (policy->cpu != 0) | 58 | if (policy->cpu != 0) |
diff --git a/drivers/cpufreq/cris-artpec3-cpufreq.c b/drivers/cpufreq/cris-artpec3-cpufreq.c index d4573032cbbc..601b88c490cf 100644 --- a/drivers/cpufreq/cris-artpec3-cpufreq.c +++ b/drivers/cpufreq/cris-artpec3-cpufreq.c | |||
| @@ -15,9 +15,9 @@ static struct notifier_block cris_sdram_freq_notifier_block = { | |||
| 15 | }; | 15 | }; |
| 16 | 16 | ||
| 17 | static struct cpufreq_frequency_table cris_freq_table[] = { | 17 | static struct cpufreq_frequency_table cris_freq_table[] = { |
| 18 | {0x01, 6000}, | 18 | {0, 0x01, 6000}, |
| 19 | {0x02, 200000}, | 19 | {0, 0x02, 200000}, |
| 20 | {0, CPUFREQ_TABLE_END}, | 20 | {0, 0, CPUFREQ_TABLE_END}, |
| 21 | }; | 21 | }; |
| 22 | 22 | ||
| 23 | static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu) | 23 | static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu) |
diff --git a/drivers/cpufreq/cris-etraxfs-cpufreq.c b/drivers/cpufreq/cris-etraxfs-cpufreq.c index 13c3361437f7..22b2cdde74d9 100644 --- a/drivers/cpufreq/cris-etraxfs-cpufreq.c +++ b/drivers/cpufreq/cris-etraxfs-cpufreq.c | |||
| @@ -15,9 +15,9 @@ static struct notifier_block cris_sdram_freq_notifier_block = { | |||
| 15 | }; | 15 | }; |
| 16 | 16 | ||
| 17 | static struct cpufreq_frequency_table cris_freq_table[] = { | 17 | static struct cpufreq_frequency_table cris_freq_table[] = { |
| 18 | {0x01, 6000}, | 18 | {0, 0x01, 6000}, |
| 19 | {0x02, 200000}, | 19 | {0, 0x02, 200000}, |
| 20 | {0, CPUFREQ_TABLE_END}, | 20 | {0, 0, CPUFREQ_TABLE_END}, |
| 21 | }; | 21 | }; |
| 22 | 22 | ||
| 23 | static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu) | 23 | static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu) |
diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c index c987e94708f5..7f5d2a68c353 100644 --- a/drivers/cpufreq/elanfreq.c +++ b/drivers/cpufreq/elanfreq.c | |||
| @@ -56,15 +56,15 @@ static struct s_elan_multiplier elan_multiplier[] = { | |||
| 56 | }; | 56 | }; |
| 57 | 57 | ||
| 58 | static struct cpufreq_frequency_table elanfreq_table[] = { | 58 | static struct cpufreq_frequency_table elanfreq_table[] = { |
| 59 | {0, 1000}, | 59 | {0, 0, 1000}, |
| 60 | {1, 2000}, | 60 | {0, 1, 2000}, |
| 61 | {2, 4000}, | 61 | {0, 2, 4000}, |
| 62 | {3, 8000}, | 62 | {0, 3, 8000}, |
| 63 | {4, 16000}, | 63 | {0, 4, 16000}, |
| 64 | {5, 33000}, | 64 | {0, 5, 33000}, |
| 65 | {6, 66000}, | 65 | {0, 6, 66000}, |
| 66 | {7, 99000}, | 66 | {0, 7, 99000}, |
| 67 | {0, CPUFREQ_TABLE_END}, | 67 | {0, 0, CPUFREQ_TABLE_END}, |
| 68 | }; | 68 | }; |
| 69 | 69 | ||
| 70 | 70 | ||
diff --git a/drivers/cpufreq/exynos4210-cpufreq.c b/drivers/cpufreq/exynos4210-cpufreq.c index 40d84c43d8f4..6384e5b9a347 100644 --- a/drivers/cpufreq/exynos4210-cpufreq.c +++ b/drivers/cpufreq/exynos4210-cpufreq.c | |||
| @@ -29,12 +29,12 @@ static unsigned int exynos4210_volt_table[] = { | |||
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| 31 | static struct cpufreq_frequency_table exynos4210_freq_table[] = { | 31 | static struct cpufreq_frequency_table exynos4210_freq_table[] = { |
| 32 | {L0, 1200 * 1000}, | 32 | {0, L0, 1200 * 1000}, |
| 33 | {L1, 1000 * 1000}, | 33 | {0, L1, 1000 * 1000}, |
| 34 | {L2, 800 * 1000}, | 34 | {0, L2, 800 * 1000}, |
| 35 | {L3, 500 * 1000}, | 35 | {0, L3, 500 * 1000}, |
| 36 | {L4, 200 * 1000}, | 36 | {0, L4, 200 * 1000}, |
| 37 | {0, CPUFREQ_TABLE_END}, | 37 | {0, 0, CPUFREQ_TABLE_END}, |
| 38 | }; | 38 | }; |
| 39 | 39 | ||
| 40 | static struct apll_freq apll_freq_4210[] = { | 40 | static struct apll_freq apll_freq_4210[] = { |
diff --git a/drivers/cpufreq/exynos4x12-cpufreq.c b/drivers/cpufreq/exynos4x12-cpufreq.c index 7c11ace3b3fc..466c76ad335b 100644 --- a/drivers/cpufreq/exynos4x12-cpufreq.c +++ b/drivers/cpufreq/exynos4x12-cpufreq.c | |||
| @@ -30,21 +30,21 @@ static unsigned int exynos4x12_volt_table[] = { | |||
| 30 | }; | 30 | }; |
| 31 | 31 | ||
| 32 | static struct cpufreq_frequency_table exynos4x12_freq_table[] = { | 32 | static struct cpufreq_frequency_table exynos4x12_freq_table[] = { |
| 33 | {CPUFREQ_BOOST_FREQ, 1500 * 1000}, | 33 | {CPUFREQ_BOOST_FREQ, L0, 1500 * 1000}, |
| 34 | {L1, 1400 * 1000}, | 34 | {0, L1, 1400 * 1000}, |
| 35 | {L2, 1300 * 1000}, | 35 | {0, L2, 1300 * 1000}, |
| 36 | {L3, 1200 * 1000}, | 36 | {0, L3, 1200 * 1000}, |
| 37 | {L4, 1100 * 1000}, | 37 | {0, L4, 1100 * 1000}, |
| 38 | {L5, 1000 * 1000}, | 38 | {0, L5, 1000 * 1000}, |
| 39 | {L6, 900 * 1000}, | 39 | {0, L6, 900 * 1000}, |
| 40 | {L7, 800 * 1000}, | 40 | {0, L7, 800 * 1000}, |
| 41 | {L8, 700 * 1000}, | 41 | {0, L8, 700 * 1000}, |
| 42 | {L9, 600 * 1000}, | 42 | {0, L9, 600 * 1000}, |
| 43 | {L10, 500 * 1000}, | 43 | {0, L10, 500 * 1000}, |
| 44 | {L11, 400 * 1000}, | 44 | {0, L11, 400 * 1000}, |
| 45 | {L12, 300 * 1000}, | 45 | {0, L12, 300 * 1000}, |
| 46 | {L13, 200 * 1000}, | 46 | {0, L13, 200 * 1000}, |
| 47 | {0, CPUFREQ_TABLE_END}, | 47 | {0, 0, CPUFREQ_TABLE_END}, |
| 48 | }; | 48 | }; |
| 49 | 49 | ||
| 50 | static struct apll_freq *apll_freq_4x12; | 50 | static struct apll_freq *apll_freq_4x12; |
diff --git a/drivers/cpufreq/exynos5250-cpufreq.c b/drivers/cpufreq/exynos5250-cpufreq.c index 5f90b82a4082..363a0b3fe1b1 100644 --- a/drivers/cpufreq/exynos5250-cpufreq.c +++ b/drivers/cpufreq/exynos5250-cpufreq.c | |||
| @@ -34,23 +34,23 @@ static unsigned int exynos5250_volt_table[] = { | |||
| 34 | }; | 34 | }; |
| 35 | 35 | ||
| 36 | static struct cpufreq_frequency_table exynos5250_freq_table[] = { | 36 | static struct cpufreq_frequency_table exynos5250_freq_table[] = { |
| 37 | {L0, 1700 * 1000}, | 37 | {0, L0, 1700 * 1000}, |
| 38 | {L1, 1600 * 1000}, | 38 | {0, L1, 1600 * 1000}, |
| 39 | {L2, 1500 * 1000}, | 39 | {0, L2, 1500 * 1000}, |
| 40 | {L3, 1400 * 1000}, | 40 | {0, L3, 1400 * 1000}, |
| 41 | {L4, 1300 * 1000}, | 41 | {0, L4, 1300 * 1000}, |
| 42 | {L5, 1200 * 1000}, | 42 | {0, L5, 1200 * 1000}, |
| 43 | {L6, 1100 * 1000}, | 43 | {0, L6, 1100 * 1000}, |
| 44 | {L7, 1000 * 1000}, | 44 | {0, L7, 1000 * 1000}, |
| 45 | {L8, 900 * 1000}, | 45 | {0, L8, 900 * 1000}, |
| 46 | {L9, 800 * 1000}, | 46 | {0, L9, 800 * 1000}, |
| 47 | {L10, 700 * 1000}, | 47 | {0, L10, 700 * 1000}, |
| 48 | {L11, 600 * 1000}, | 48 | {0, L11, 600 * 1000}, |
| 49 | {L12, 500 * 1000}, | 49 | {0, L12, 500 * 1000}, |
| 50 | {L13, 400 * 1000}, | 50 | {0, L13, 400 * 1000}, |
| 51 | {L14, 300 * 1000}, | 51 | {0, L14, 300 * 1000}, |
| 52 | {L15, 200 * 1000}, | 52 | {0, L15, 200 * 1000}, |
| 53 | {0, CPUFREQ_TABLE_END}, | 53 | {0, 0, CPUFREQ_TABLE_END}, |
| 54 | }; | 54 | }; |
| 55 | 55 | ||
| 56 | static struct apll_freq apll_freq_5250[] = { | 56 | static struct apll_freq apll_freq_5250[] = { |
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index 65a477075b3f..08e7bbcf6d73 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c | |||
| @@ -33,11 +33,10 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, | |||
| 33 | continue; | 33 | continue; |
| 34 | } | 34 | } |
| 35 | if (!cpufreq_boost_enabled() | 35 | if (!cpufreq_boost_enabled() |
| 36 | && table[i].driver_data == CPUFREQ_BOOST_FREQ) | 36 | && (table[i].flags & CPUFREQ_BOOST_FREQ)) |
| 37 | continue; | 37 | continue; |
| 38 | 38 | ||
| 39 | pr_debug("table entry %u: %u kHz, %u driver_data\n", | 39 | pr_debug("table entry %u: %u kHz\n", i, freq); |
| 40 | i, freq, table[i].driver_data); | ||
| 41 | if (freq < min_freq) | 40 | if (freq < min_freq) |
| 42 | min_freq = freq; | 41 | min_freq = freq; |
| 43 | if (freq > max_freq) | 42 | if (freq > max_freq) |
| @@ -175,8 +174,8 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, | |||
| 175 | } else | 174 | } else |
| 176 | *index = optimal.driver_data; | 175 | *index = optimal.driver_data; |
| 177 | 176 | ||
| 178 | pr_debug("target is %u (%u kHz, %u)\n", *index, table[*index].frequency, | 177 | pr_debug("target index is %u, freq is:%u kHz\n", *index, |
| 179 | table[*index].driver_data); | 178 | table[*index].frequency); |
| 180 | 179 | ||
| 181 | return 0; | 180 | return 0; |
| 182 | } | 181 | } |
| @@ -230,7 +229,7 @@ static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf, | |||
| 230 | * show_boost = false and driver_data != BOOST freq | 229 | * show_boost = false and driver_data != BOOST freq |
| 231 | * display NON BOOST freqs | 230 | * display NON BOOST freqs |
| 232 | */ | 231 | */ |
| 233 | if (show_boost ^ (table[i].driver_data == CPUFREQ_BOOST_FREQ)) | 232 | if (show_boost ^ (table[i].flags & CPUFREQ_BOOST_FREQ)) |
| 234 | continue; | 233 | continue; |
| 235 | 234 | ||
| 236 | count += sprintf(&buf[count], "%d ", table[i].frequency); | 235 | count += sprintf(&buf[count], "%d ", table[i].frequency); |
diff --git a/drivers/cpufreq/ia64-acpi-cpufreq.c b/drivers/cpufreq/ia64-acpi-cpufreq.c index a22b5d182e0e..c30aaa6a54e8 100644 --- a/drivers/cpufreq/ia64-acpi-cpufreq.c +++ b/drivers/cpufreq/ia64-acpi-cpufreq.c | |||
| @@ -254,7 +254,7 @@ acpi_cpufreq_cpu_init ( | |||
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | /* alloc freq_table */ | 256 | /* alloc freq_table */ |
| 257 | data->freq_table = kmalloc(sizeof(*data->freq_table) * | 257 | data->freq_table = kzalloc(sizeof(*data->freq_table) * |
| 258 | (data->acpi_data.state_count + 1), | 258 | (data->acpi_data.state_count + 1), |
| 259 | GFP_KERNEL); | 259 | GFP_KERNEL); |
| 260 | if (!data->freq_table) { | 260 | if (!data->freq_table) { |
| @@ -275,7 +275,6 @@ acpi_cpufreq_cpu_init ( | |||
| 275 | /* table init */ | 275 | /* table init */ |
| 276 | for (i = 0; i <= data->acpi_data.state_count; i++) | 276 | for (i = 0; i <= data->acpi_data.state_count; i++) |
| 277 | { | 277 | { |
| 278 | data->freq_table[i].driver_data = i; | ||
| 279 | if (i < data->acpi_data.state_count) { | 278 | if (i < data->acpi_data.state_count) { |
| 280 | data->freq_table[i].frequency = | 279 | data->freq_table[i].frequency = |
| 281 | data->acpi_data.states[i].core_frequency * 1000; | 280 | data->acpi_data.states[i].core_frequency * 1000; |
diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c index 3d114bc5a97a..37a480680cd0 100644 --- a/drivers/cpufreq/kirkwood-cpufreq.c +++ b/drivers/cpufreq/kirkwood-cpufreq.c | |||
| @@ -43,9 +43,9 @@ static struct priv | |||
| 43 | * table. | 43 | * table. |
| 44 | */ | 44 | */ |
| 45 | static struct cpufreq_frequency_table kirkwood_freq_table[] = { | 45 | static struct cpufreq_frequency_table kirkwood_freq_table[] = { |
| 46 | {STATE_CPU_FREQ, 0}, /* CPU uses cpuclk */ | 46 | {0, STATE_CPU_FREQ, 0}, /* CPU uses cpuclk */ |
| 47 | {STATE_DDR_FREQ, 0}, /* CPU uses ddrclk */ | 47 | {0, STATE_DDR_FREQ, 0}, /* CPU uses ddrclk */ |
| 48 | {0, CPUFREQ_TABLE_END}, | 48 | {0, 0, CPUFREQ_TABLE_END}, |
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | static unsigned int kirkwood_cpufreq_get_cpu_frequency(unsigned int cpu) | 51 | static unsigned int kirkwood_cpufreq_get_cpu_frequency(unsigned int cpu) |
diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index 5c440f87ba8a..d00e5d1abd25 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c | |||
| @@ -475,7 +475,7 @@ static int longhaul_get_ranges(void) | |||
| 475 | return -EINVAL; | 475 | return -EINVAL; |
| 476 | } | 476 | } |
| 477 | 477 | ||
| 478 | longhaul_table = kmalloc((numscales + 1) * sizeof(*longhaul_table), | 478 | longhaul_table = kzalloc((numscales + 1) * sizeof(*longhaul_table), |
| 479 | GFP_KERNEL); | 479 | GFP_KERNEL); |
| 480 | if (!longhaul_table) | 480 | if (!longhaul_table) |
| 481 | return -ENOMEM; | 481 | return -ENOMEM; |
diff --git a/drivers/cpufreq/loongson2_cpufreq.c b/drivers/cpufreq/loongson2_cpufreq.c index a3588d61d933..f0bc31f5db27 100644 --- a/drivers/cpufreq/loongson2_cpufreq.c +++ b/drivers/cpufreq/loongson2_cpufreq.c | |||
| @@ -69,7 +69,7 @@ static int loongson2_cpufreq_target(struct cpufreq_policy *policy, | |||
| 69 | 69 | ||
| 70 | static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy) | 70 | static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy) |
| 71 | { | 71 | { |
| 72 | static struct clk *cpuclk; | 72 | struct clk *cpuclk; |
| 73 | int i; | 73 | int i; |
| 74 | unsigned long rate; | 74 | unsigned long rate; |
| 75 | int ret; | 75 | int ret; |
diff --git a/drivers/cpufreq/maple-cpufreq.c b/drivers/cpufreq/maple-cpufreq.c index c4dfa42a75ac..cc3408fc073f 100644 --- a/drivers/cpufreq/maple-cpufreq.c +++ b/drivers/cpufreq/maple-cpufreq.c | |||
| @@ -59,9 +59,9 @@ | |||
| 59 | #define CPUFREQ_LOW 1 | 59 | #define CPUFREQ_LOW 1 |
| 60 | 60 | ||
| 61 | static struct cpufreq_frequency_table maple_cpu_freqs[] = { | 61 | static struct cpufreq_frequency_table maple_cpu_freqs[] = { |
| 62 | {CPUFREQ_HIGH, 0}, | 62 | {0, CPUFREQ_HIGH, 0}, |
| 63 | {CPUFREQ_LOW, 0}, | 63 | {0, CPUFREQ_LOW, 0}, |
| 64 | {0, CPUFREQ_TABLE_END}, | 64 | {0, 0, CPUFREQ_TABLE_END}, |
| 65 | }; | 65 | }; |
| 66 | 66 | ||
| 67 | /* Power mode data is an array of the 32 bits PCR values to use for | 67 | /* Power mode data is an array of the 32 bits PCR values to use for |
diff --git a/drivers/cpufreq/p4-clockmod.c b/drivers/cpufreq/p4-clockmod.c index 74f593e70e19..529cfd92158f 100644 --- a/drivers/cpufreq/p4-clockmod.c +++ b/drivers/cpufreq/p4-clockmod.c | |||
| @@ -92,16 +92,16 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) | |||
| 92 | 92 | ||
| 93 | 93 | ||
| 94 | static struct cpufreq_frequency_table p4clockmod_table[] = { | 94 | static struct cpufreq_frequency_table p4clockmod_table[] = { |
| 95 | {DC_RESV, CPUFREQ_ENTRY_INVALID}, | 95 | {0, DC_RESV, CPUFREQ_ENTRY_INVALID}, |
| 96 | {DC_DFLT, 0}, | 96 | {0, DC_DFLT, 0}, |
| 97 | {DC_25PT, 0}, | 97 | {0, DC_25PT, 0}, |
| 98 | {DC_38PT, 0}, | 98 | {0, DC_38PT, 0}, |
| 99 | {DC_50PT, 0}, | 99 | {0, DC_50PT, 0}, |
| 100 | {DC_64PT, 0}, | 100 | {0, DC_64PT, 0}, |
| 101 | {DC_75PT, 0}, | 101 | {0, DC_75PT, 0}, |
| 102 | {DC_88PT, 0}, | 102 | {0, DC_88PT, 0}, |
| 103 | {DC_DISABLE, 0}, | 103 | {0, DC_DISABLE, 0}, |
| 104 | {DC_RESV, CPUFREQ_TABLE_END}, | 104 | {0, DC_RESV, CPUFREQ_TABLE_END}, |
| 105 | }; | 105 | }; |
| 106 | 106 | ||
| 107 | 107 | ||
diff --git a/drivers/cpufreq/pasemi-cpufreq.c b/drivers/cpufreq/pasemi-cpufreq.c index 6a2b7d3e85a7..84c84b5f0f3a 100644 --- a/drivers/cpufreq/pasemi-cpufreq.c +++ b/drivers/cpufreq/pasemi-cpufreq.c | |||
| @@ -60,12 +60,12 @@ static int current_astate; | |||
| 60 | 60 | ||
| 61 | /* We support 5(A0-A4) power states excluding turbo(A5-A6) modes */ | 61 | /* We support 5(A0-A4) power states excluding turbo(A5-A6) modes */ |
| 62 | static struct cpufreq_frequency_table pas_freqs[] = { | 62 | static struct cpufreq_frequency_table pas_freqs[] = { |
| 63 | {0, 0}, | 63 | {0, 0, 0}, |
| 64 | {1, 0}, | 64 | {0, 1, 0}, |
| 65 | {2, 0}, | 65 | {0, 2, 0}, |
| 66 | {3, 0}, | 66 | {0, 3, 0}, |
| 67 | {4, 0}, | 67 | {0, 4, 0}, |
| 68 | {0, CPUFREQ_TABLE_END}, | 68 | {0, 0, CPUFREQ_TABLE_END}, |
| 69 | }; | 69 | }; |
| 70 | 70 | ||
| 71 | /* | 71 | /* |
diff --git a/drivers/cpufreq/pmac32-cpufreq.c b/drivers/cpufreq/pmac32-cpufreq.c index cf55d202f332..7615180d7ee3 100644 --- a/drivers/cpufreq/pmac32-cpufreq.c +++ b/drivers/cpufreq/pmac32-cpufreq.c | |||
| @@ -81,9 +81,9 @@ static int is_pmu_based; | |||
| 81 | #define CPUFREQ_LOW 1 | 81 | #define CPUFREQ_LOW 1 |
| 82 | 82 | ||
| 83 | static struct cpufreq_frequency_table pmac_cpu_freqs[] = { | 83 | static struct cpufreq_frequency_table pmac_cpu_freqs[] = { |
| 84 | {CPUFREQ_HIGH, 0}, | 84 | {0, CPUFREQ_HIGH, 0}, |
| 85 | {CPUFREQ_LOW, 0}, | 85 | {0, CPUFREQ_LOW, 0}, |
| 86 | {0, CPUFREQ_TABLE_END}, | 86 | {0, 0, CPUFREQ_TABLE_END}, |
| 87 | }; | 87 | }; |
| 88 | 88 | ||
| 89 | static inline void local_delay(unsigned long ms) | 89 | static inline void local_delay(unsigned long ms) |
diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c index 6a338f8c3860..8bc422977b5b 100644 --- a/drivers/cpufreq/pmac64-cpufreq.c +++ b/drivers/cpufreq/pmac64-cpufreq.c | |||
| @@ -65,9 +65,9 @@ | |||
| 65 | #define CPUFREQ_LOW 1 | 65 | #define CPUFREQ_LOW 1 |
| 66 | 66 | ||
| 67 | static struct cpufreq_frequency_table g5_cpu_freqs[] = { | 67 | static struct cpufreq_frequency_table g5_cpu_freqs[] = { |
| 68 | {CPUFREQ_HIGH, 0}, | 68 | {0, CPUFREQ_HIGH, 0}, |
| 69 | {CPUFREQ_LOW, 0}, | 69 | {0, CPUFREQ_LOW, 0}, |
| 70 | {0, CPUFREQ_TABLE_END}, | 70 | {0, 0, CPUFREQ_TABLE_END}, |
| 71 | }; | 71 | }; |
| 72 | 72 | ||
| 73 | /* Power mode data is an array of the 32 bits PCR values to use for | 73 | /* Power mode data is an array of the 32 bits PCR values to use for |
diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c index 62c6f2e5afce..49f120e1bc7b 100644 --- a/drivers/cpufreq/powernow-k6.c +++ b/drivers/cpufreq/powernow-k6.c | |||
| @@ -37,15 +37,15 @@ MODULE_PARM_DESC(bus_frequency, "Bus frequency in kHz"); | |||
| 37 | 37 | ||
| 38 | /* Clock ratio multiplied by 10 - see table 27 in AMD#23446 */ | 38 | /* Clock ratio multiplied by 10 - see table 27 in AMD#23446 */ |
| 39 | static struct cpufreq_frequency_table clock_ratio[] = { | 39 | static struct cpufreq_frequency_table clock_ratio[] = { |
| 40 | {60, /* 110 -> 6.0x */ 0}, | 40 | {0, 60, /* 110 -> 6.0x */ 0}, |
| 41 | {55, /* 011 -> 5.5x */ 0}, | 41 | {0, 55, /* 011 -> 5.5x */ 0}, |
| 42 | {50, /* 001 -> 5.0x */ 0}, | 42 | {0, 50, /* 001 -> 5.0x */ 0}, |
| 43 | {45, /* 000 -> 4.5x */ 0}, | 43 | {0, 45, /* 000 -> 4.5x */ 0}, |
| 44 | {40, /* 010 -> 4.0x */ 0}, | 44 | {0, 40, /* 010 -> 4.0x */ 0}, |
| 45 | {35, /* 111 -> 3.5x */ 0}, | 45 | {0, 35, /* 111 -> 3.5x */ 0}, |
| 46 | {30, /* 101 -> 3.0x */ 0}, | 46 | {0, 30, /* 101 -> 3.0x */ 0}, |
| 47 | {20, /* 100 -> 2.0x */ 0}, | 47 | {0, 20, /* 100 -> 2.0x */ 0}, |
| 48 | {0, CPUFREQ_TABLE_END} | 48 | {0, 0, CPUFREQ_TABLE_END} |
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | static const u8 index_to_register[8] = { 6, 3, 1, 0, 2, 7, 5, 4 }; | 51 | static const u8 index_to_register[8] = { 6, 3, 1, 0, 2, 7, 5, 4 }; |
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index 770a9e1b3468..1b6ae6b57c11 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c | |||
| @@ -623,7 +623,7 @@ static int fill_powernow_table(struct powernow_k8_data *data, | |||
| 623 | if (check_pst_table(data, pst, maxvid)) | 623 | if (check_pst_table(data, pst, maxvid)) |
| 624 | return -EINVAL; | 624 | return -EINVAL; |
| 625 | 625 | ||
| 626 | powernow_table = kmalloc((sizeof(*powernow_table) | 626 | powernow_table = kzalloc((sizeof(*powernow_table) |
| 627 | * (data->numps + 1)), GFP_KERNEL); | 627 | * (data->numps + 1)), GFP_KERNEL); |
| 628 | if (!powernow_table) { | 628 | if (!powernow_table) { |
| 629 | printk(KERN_ERR PFX "powernow_table memory alloc failure\n"); | 629 | printk(KERN_ERR PFX "powernow_table memory alloc failure\n"); |
| @@ -793,7 +793,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
| 793 | } | 793 | } |
| 794 | 794 | ||
| 795 | /* fill in data->powernow_table */ | 795 | /* fill in data->powernow_table */ |
| 796 | powernow_table = kmalloc((sizeof(*powernow_table) | 796 | powernow_table = kzalloc((sizeof(*powernow_table) |
| 797 | * (data->acpi_data.state_count + 1)), GFP_KERNEL); | 797 | * (data->acpi_data.state_count + 1)), GFP_KERNEL); |
| 798 | if (!powernow_table) { | 798 | if (!powernow_table) { |
| 799 | pr_debug("powernow_table memory alloc failure\n"); | 799 | pr_debug("powernow_table memory alloc failure\n"); |
| @@ -810,7 +810,6 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
| 810 | 810 | ||
| 811 | powernow_table[data->acpi_data.state_count].frequency = | 811 | powernow_table[data->acpi_data.state_count].frequency = |
| 812 | CPUFREQ_TABLE_END; | 812 | CPUFREQ_TABLE_END; |
| 813 | powernow_table[data->acpi_data.state_count].driver_data = 0; | ||
| 814 | data->powernow_table = powernow_table; | 813 | data->powernow_table = powernow_table; |
| 815 | 814 | ||
| 816 | if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu) | 815 | if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu) |
diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c new file mode 100644 index 000000000000..9edccc63245d --- /dev/null +++ b/drivers/cpufreq/powernv-cpufreq.c | |||
| @@ -0,0 +1,341 @@ | |||
| 1 | /* | ||
| 2 | * POWERNV cpufreq driver for the IBM POWER processors | ||
| 3 | * | ||
| 4 | * (C) Copyright IBM 2014 | ||
| 5 | * | ||
| 6 | * Author: Vaidyanathan Srinivasan <svaidy at linux.vnet.ibm.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2, or (at your option) | ||
| 11 | * any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | */ | ||
| 19 | |||
| 20 | #define pr_fmt(fmt) "powernv-cpufreq: " fmt | ||
| 21 | |||
| 22 | #include <linux/kernel.h> | ||
| 23 | #include <linux/sysfs.h> | ||
| 24 | #include <linux/cpumask.h> | ||
| 25 | #include <linux/module.h> | ||
| 26 | #include <linux/cpufreq.h> | ||
| 27 | #include <linux/smp.h> | ||
| 28 | #include <linux/of.h> | ||
| 29 | |||
| 30 | #include <asm/cputhreads.h> | ||
| 31 | #include <asm/reg.h> | ||
| 32 | |||
| 33 | #define POWERNV_MAX_PSTATES 256 | ||
| 34 | |||
| 35 | static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1]; | ||
| 36 | |||
| 37 | /* | ||
| 38 | * Note: The set of pstates consists of contiguous integers, the | ||
| 39 | * smallest of which is indicated by powernv_pstate_info.min, the | ||
| 40 | * largest of which is indicated by powernv_pstate_info.max. | ||
| 41 | * | ||
| 42 | * The nominal pstate is the highest non-turbo pstate in this | ||
| 43 | * platform. This is indicated by powernv_pstate_info.nominal. | ||
| 44 | */ | ||
| 45 | static struct powernv_pstate_info { | ||
| 46 | int min; | ||
| 47 | int max; | ||
| 48 | int nominal; | ||
| 49 | int nr_pstates; | ||
| 50 | } powernv_pstate_info; | ||
| 51 | |||
| 52 | /* | ||
| 53 | * Initialize the freq table based on data obtained | ||
| 54 | * from the firmware passed via device-tree | ||
| 55 | */ | ||
| 56 | static int init_powernv_pstates(void) | ||
| 57 | { | ||
| 58 | struct device_node *power_mgt; | ||
| 59 | int i, pstate_min, pstate_max, pstate_nominal, nr_pstates = 0; | ||
| 60 | const __be32 *pstate_ids, *pstate_freqs; | ||
| 61 | u32 len_ids, len_freqs; | ||
| 62 | |||
| 63 | power_mgt = of_find_node_by_path("/ibm,opal/power-mgt"); | ||
| 64 | if (!power_mgt) { | ||
| 65 | pr_warn("power-mgt node not found\n"); | ||
| 66 | return -ENODEV; | ||
| 67 | } | ||
| 68 | |||
| 69 | if (of_property_read_u32(power_mgt, "ibm,pstate-min", &pstate_min)) { | ||
| 70 | pr_warn("ibm,pstate-min node not found\n"); | ||
| 71 | return -ENODEV; | ||
| 72 | } | ||
| 73 | |||
| 74 | if (of_property_read_u32(power_mgt, "ibm,pstate-max", &pstate_max)) { | ||
| 75 | pr_warn("ibm,pstate-max node not found\n"); | ||
| 76 | return -ENODEV; | ||
| 77 | } | ||
| 78 | |||
| 79 | if (of_property_read_u32(power_mgt, "ibm,pstate-nominal", | ||
| 80 | &pstate_nominal)) { | ||
| 81 | pr_warn("ibm,pstate-nominal not found\n"); | ||
| 82 | return -ENODEV; | ||
| 83 | } | ||
| 84 | pr_info("cpufreq pstate min %d nominal %d max %d\n", pstate_min, | ||
| 85 | pstate_nominal, pstate_max); | ||
| 86 | |||
| 87 | pstate_ids = of_get_property(power_mgt, "ibm,pstate-ids", &len_ids); | ||
| 88 | if (!pstate_ids) { | ||
| 89 | pr_warn("ibm,pstate-ids not found\n"); | ||
| 90 | return -ENODEV; | ||
| 91 | } | ||
| 92 | |||
| 93 | pstate_freqs = of_get_property(power_mgt, "ibm,pstate-frequencies-mhz", | ||
| 94 | &len_freqs); | ||
| 95 | if (!pstate_freqs) { | ||
| 96 | pr_warn("ibm,pstate-frequencies-mhz not found\n"); | ||
| 97 | return -ENODEV; | ||
| 98 | } | ||
| 99 | |||
| 100 | WARN_ON(len_ids != len_freqs); | ||
| 101 | nr_pstates = min(len_ids, len_freqs) / sizeof(u32); | ||
| 102 | if (!nr_pstates) { | ||
| 103 | pr_warn("No PStates found\n"); | ||
| 104 | return -ENODEV; | ||
| 105 | } | ||
| 106 | |||
| 107 | pr_debug("NR PStates %d\n", nr_pstates); | ||
| 108 | for (i = 0; i < nr_pstates; i++) { | ||
| 109 | u32 id = be32_to_cpu(pstate_ids[i]); | ||
| 110 | u32 freq = be32_to_cpu(pstate_freqs[i]); | ||
| 111 | |||
| 112 | pr_debug("PState id %d freq %d MHz\n", id, freq); | ||
| 113 | powernv_freqs[i].frequency = freq * 1000; /* kHz */ | ||
| 114 | powernv_freqs[i].driver_data = id; | ||
| 115 | } | ||
| 116 | /* End of list marker entry */ | ||
| 117 | powernv_freqs[i].frequency = CPUFREQ_TABLE_END; | ||
| 118 | |||
| 119 | powernv_pstate_info.min = pstate_min; | ||
| 120 | powernv_pstate_info.max = pstate_max; | ||
| 121 | powernv_pstate_info.nominal = pstate_nominal; | ||
| 122 | powernv_pstate_info.nr_pstates = nr_pstates; | ||
| 123 | |||
| 124 | return 0; | ||
| 125 | } | ||
| 126 | |||
| 127 | /* Returns the CPU frequency corresponding to the pstate_id. */ | ||
| 128 | static unsigned int pstate_id_to_freq(int pstate_id) | ||
| 129 | { | ||
| 130 | int i; | ||
| 131 | |||
| 132 | i = powernv_pstate_info.max - pstate_id; | ||
| 133 | BUG_ON(i >= powernv_pstate_info.nr_pstates || i < 0); | ||
| 134 | |||
| 135 | return powernv_freqs[i].frequency; | ||
| 136 | } | ||
| 137 | |||
| 138 | /* | ||
| 139 | * cpuinfo_nominal_freq_show - Show the nominal CPU frequency as indicated by | ||
| 140 | * the firmware | ||
| 141 | */ | ||
| 142 | static ssize_t cpuinfo_nominal_freq_show(struct cpufreq_policy *policy, | ||
| 143 | char *buf) | ||
| 144 | { | ||
| 145 | return sprintf(buf, "%u\n", | ||
| 146 | pstate_id_to_freq(powernv_pstate_info.nominal)); | ||
| 147 | } | ||
| 148 | |||
| 149 | struct freq_attr cpufreq_freq_attr_cpuinfo_nominal_freq = | ||
| 150 | __ATTR_RO(cpuinfo_nominal_freq); | ||
| 151 | |||
| 152 | static struct freq_attr *powernv_cpu_freq_attr[] = { | ||
| 153 | &cpufreq_freq_attr_scaling_available_freqs, | ||
| 154 | &cpufreq_freq_attr_cpuinfo_nominal_freq, | ||
| 155 | NULL, | ||
| 156 | }; | ||
| 157 | |||
| 158 | /* Helper routines */ | ||
| 159 | |||
| 160 | /* Access helpers to power mgt SPR */ | ||
| 161 | |||
| 162 | static inline unsigned long get_pmspr(unsigned long sprn) | ||
| 163 | { | ||
| 164 | switch (sprn) { | ||
| 165 | case SPRN_PMCR: | ||
| 166 | return mfspr(SPRN_PMCR); | ||
| 167 | |||
| 168 | case SPRN_PMICR: | ||
| 169 | return mfspr(SPRN_PMICR); | ||
| 170 | |||
| 171 | case SPRN_PMSR: | ||
| 172 | return mfspr(SPRN_PMSR); | ||
| 173 | } | ||
| 174 | BUG(); | ||
| 175 | } | ||
| 176 | |||
| 177 | static inline void set_pmspr(unsigned long sprn, unsigned long val) | ||
| 178 | { | ||
| 179 | switch (sprn) { | ||
| 180 | case SPRN_PMCR: | ||
| 181 | mtspr(SPRN_PMCR, val); | ||
| 182 | return; | ||
| 183 | |||
| 184 | case SPRN_PMICR: | ||
| 185 | mtspr(SPRN_PMICR, val); | ||
| 186 | return; | ||
| 187 | } | ||
| 188 | BUG(); | ||
| 189 | } | ||
| 190 | |||
| 191 | /* | ||
| 192 | * Use objects of this type to query/update | ||
| 193 | * pstates on a remote CPU via smp_call_function. | ||
| 194 | */ | ||
| 195 | struct powernv_smp_call_data { | ||
| 196 | unsigned int freq; | ||
| 197 | int pstate_id; | ||
| 198 | }; | ||
| 199 | |||
| 200 | /* | ||
| 201 | * powernv_read_cpu_freq: Reads the current frequency on this CPU. | ||
| 202 | * | ||
| 203 | * Called via smp_call_function. | ||
| 204 | * | ||
| 205 | * Note: The caller of the smp_call_function should pass an argument of | ||
| 206 | * the type 'struct powernv_smp_call_data *' along with this function. | ||
| 207 | * | ||
| 208 | * The current frequency on this CPU will be returned via | ||
| 209 | * ((struct powernv_smp_call_data *)arg)->freq; | ||
| 210 | */ | ||
| 211 | static void powernv_read_cpu_freq(void *arg) | ||
| 212 | { | ||
| 213 | unsigned long pmspr_val; | ||
| 214 | s8 local_pstate_id; | ||
| 215 | struct powernv_smp_call_data *freq_data = arg; | ||
| 216 | |||
| 217 | pmspr_val = get_pmspr(SPRN_PMSR); | ||
| 218 | |||
| 219 | /* | ||
| 220 | * The local pstate id corresponds bits 48..55 in the PMSR. | ||
| 221 | * Note: Watch out for the sign! | ||
| 222 | */ | ||
| 223 | local_pstate_id = (pmspr_val >> 48) & 0xFF; | ||
| 224 | freq_data->pstate_id = local_pstate_id; | ||
| 225 | freq_data->freq = pstate_id_to_freq(freq_data->pstate_id); | ||
| 226 | |||
| 227 | pr_debug("cpu %d pmsr %016lX pstate_id %d frequency %d kHz\n", | ||
| 228 | raw_smp_processor_id(), pmspr_val, freq_data->pstate_id, | ||
| 229 | freq_data->freq); | ||
| 230 | } | ||
| 231 | |||
| 232 | /* | ||
| 233 | * powernv_cpufreq_get: Returns the CPU frequency as reported by the | ||
| 234 | * firmware for CPU 'cpu'. This value is reported through the sysfs | ||
| 235 | * file cpuinfo_cur_freq. | ||
| 236 | */ | ||
| 237 | unsigned int powernv_cpufreq_get(unsigned int cpu) | ||
| 238 | { | ||
| 239 | struct powernv_smp_call_data freq_data; | ||
| 240 | |||
| 241 | smp_call_function_any(cpu_sibling_mask(cpu), powernv_read_cpu_freq, | ||
| 242 | &freq_data, 1); | ||
| 243 | |||
| 244 | return freq_data.freq; | ||
| 245 | } | ||
| 246 | |||
| 247 | /* | ||
| 248 | * set_pstate: Sets the pstate on this CPU. | ||
| 249 | * | ||
| 250 | * This is called via an smp_call_function. | ||
| 251 | * | ||
| 252 | * The caller must ensure that freq_data is of the type | ||
| 253 | * (struct powernv_smp_call_data *) and the pstate_id which needs to be set | ||
| 254 | * on this CPU should be present in freq_data->pstate_id. | ||
| 255 | */ | ||
| 256 | static void set_pstate(void *freq_data) | ||
| 257 | { | ||
| 258 | unsigned long val; | ||
| 259 | unsigned long pstate_ul = | ||
| 260 | ((struct powernv_smp_call_data *) freq_data)->pstate_id; | ||
| 261 | |||
| 262 | val = get_pmspr(SPRN_PMCR); | ||
| 263 | val = val & 0x0000FFFFFFFFFFFFULL; | ||
| 264 | |||
| 265 | pstate_ul = pstate_ul & 0xFF; | ||
| 266 | |||
| 267 | /* Set both global(bits 56..63) and local(bits 48..55) PStates */ | ||
| 268 | val = val | (pstate_ul << 56) | (pstate_ul << 48); | ||
| 269 | |||
| 270 | pr_debug("Setting cpu %d pmcr to %016lX\n", | ||
| 271 | raw_smp_processor_id(), val); | ||
| 272 | set_pmspr(SPRN_PMCR, val); | ||
| 273 | } | ||
| 274 | |||
| 275 | /* | ||
| 276 | * powernv_cpufreq_target_index: Sets the frequency corresponding to | ||
| 277 | * the cpufreq table entry indexed by new_index on the cpus in the | ||
| 278 | * mask policy->cpus | ||
| 279 | */ | ||
| 280 | static int powernv_cpufreq_target_index(struct cpufreq_policy *policy, | ||
| 281 | unsigned int new_index) | ||
| 282 | { | ||
| 283 | struct powernv_smp_call_data freq_data; | ||
| 284 | |||
| 285 | freq_data.pstate_id = powernv_freqs[new_index].driver_data; | ||
| 286 | |||
| 287 | /* | ||
| 288 | * Use smp_call_function to send IPI and execute the | ||
| 289 | * mtspr on target CPU. We could do that without IPI | ||
| 290 | * if current CPU is within policy->cpus (core) | ||
| 291 | */ | ||
| 292 | smp_call_function_any(policy->cpus, set_pstate, &freq_data, 1); | ||
| 293 | |||
| 294 | return 0; | ||
| 295 | } | ||
| 296 | |||
| 297 | static int powernv_cpufreq_cpu_init(struct cpufreq_policy *policy) | ||
| 298 | { | ||
| 299 | int base, i; | ||
| 300 | |||
| 301 | base = cpu_first_thread_sibling(policy->cpu); | ||
| 302 | |||
| 303 | for (i = 0; i < threads_per_core; i++) | ||
| 304 | cpumask_set_cpu(base + i, policy->cpus); | ||
| 305 | |||
| 306 | return cpufreq_table_validate_and_show(policy, powernv_freqs); | ||
| 307 | } | ||
| 308 | |||
| 309 | static struct cpufreq_driver powernv_cpufreq_driver = { | ||
| 310 | .name = "powernv-cpufreq", | ||
| 311 | .flags = CPUFREQ_CONST_LOOPS, | ||
| 312 | .init = powernv_cpufreq_cpu_init, | ||
| 313 | .verify = cpufreq_generic_frequency_table_verify, | ||
| 314 | .target_index = powernv_cpufreq_target_index, | ||
| 315 | .get = powernv_cpufreq_get, | ||
| 316 | .attr = powernv_cpu_freq_attr, | ||
| 317 | }; | ||
| 318 | |||
| 319 | static int __init powernv_cpufreq_init(void) | ||
| 320 | { | ||
| 321 | int rc = 0; | ||
| 322 | |||
| 323 | /* Discover pstates from device tree and init */ | ||
| 324 | rc = init_powernv_pstates(); | ||
| 325 | if (rc) { | ||
| 326 | pr_info("powernv-cpufreq disabled. System does not support PState control\n"); | ||
| 327 | return rc; | ||
| 328 | } | ||
| 329 | |||
| 330 | return cpufreq_register_driver(&powernv_cpufreq_driver); | ||
| 331 | } | ||
| 332 | module_init(powernv_cpufreq_init); | ||
| 333 | |||
| 334 | static void __exit powernv_cpufreq_exit(void) | ||
| 335 | { | ||
| 336 | cpufreq_unregister_driver(&powernv_cpufreq_driver); | ||
| 337 | } | ||
| 338 | module_exit(powernv_cpufreq_exit); | ||
| 339 | |||
| 340 | MODULE_LICENSE("GPL"); | ||
| 341 | MODULE_AUTHOR("Vaidyanathan Srinivasan <svaidy at linux.vnet.ibm.com>"); | ||
diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c index 3bd9123e7026..b7e677be1df0 100644 --- a/drivers/cpufreq/ppc-corenet-cpufreq.c +++ b/drivers/cpufreq/ppc-corenet-cpufreq.c | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | #include <linux/clk.h> | 13 | #include <linux/clk.h> |
| 14 | #include <linux/cpufreq.h> | 14 | #include <linux/cpufreq.h> |
| 15 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
| 16 | #include <sysdev/fsl_soc.h> | ||
| 17 | #include <linux/init.h> | 16 | #include <linux/init.h> |
| 18 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
| 19 | #include <linux/module.h> | 18 | #include <linux/module.h> |
diff --git a/drivers/cpufreq/ppc_cbe_cpufreq.c b/drivers/cpufreq/ppc_cbe_cpufreq.c index af7b1cabd1e7..5be8a48dba74 100644 --- a/drivers/cpufreq/ppc_cbe_cpufreq.c +++ b/drivers/cpufreq/ppc_cbe_cpufreq.c | |||
| @@ -32,15 +32,15 @@ | |||
| 32 | 32 | ||
| 33 | /* the CBE supports an 8 step frequency scaling */ | 33 | /* the CBE supports an 8 step frequency scaling */ |
| 34 | static struct cpufreq_frequency_table cbe_freqs[] = { | 34 | static struct cpufreq_frequency_table cbe_freqs[] = { |
| 35 | {1, 0}, | 35 | {0, 1, 0}, |
| 36 | {2, 0}, | 36 | {0, 2, 0}, |
| 37 | {3, 0}, | 37 | {0, 3, 0}, |
| 38 | {4, 0}, | 38 | {0, 4, 0}, |
| 39 | {5, 0}, | 39 | {0, 5, 0}, |
| 40 | {6, 0}, | 40 | {0, 6, 0}, |
| 41 | {8, 0}, | 41 | {0, 8, 0}, |
| 42 | {10, 0}, | 42 | {0, 10, 0}, |
| 43 | {0, CPUFREQ_TABLE_END}, | 43 | {0, 0, CPUFREQ_TABLE_END}, |
| 44 | }; | 44 | }; |
| 45 | 45 | ||
| 46 | /* | 46 | /* |
diff --git a/drivers/cpufreq/s3c2416-cpufreq.c b/drivers/cpufreq/s3c2416-cpufreq.c index 826b8be23099..4626f90559b5 100644 --- a/drivers/cpufreq/s3c2416-cpufreq.c +++ b/drivers/cpufreq/s3c2416-cpufreq.c | |||
| @@ -72,19 +72,19 @@ static struct s3c2416_dvfs s3c2416_dvfs_table[] = { | |||
| 72 | #endif | 72 | #endif |
| 73 | 73 | ||
| 74 | static struct cpufreq_frequency_table s3c2416_freq_table[] = { | 74 | static struct cpufreq_frequency_table s3c2416_freq_table[] = { |
| 75 | { SOURCE_HCLK, FREQ_DVS }, | 75 | { 0, SOURCE_HCLK, FREQ_DVS }, |
| 76 | { SOURCE_ARMDIV, 133333 }, | 76 | { 0, SOURCE_ARMDIV, 133333 }, |
| 77 | { SOURCE_ARMDIV, 266666 }, | 77 | { 0, SOURCE_ARMDIV, 266666 }, |
| 78 | { SOURCE_ARMDIV, 400000 }, | 78 | { 0, SOURCE_ARMDIV, 400000 }, |
| 79 | { 0, CPUFREQ_TABLE_END }, | 79 | { 0, 0, CPUFREQ_TABLE_END }, |
| 80 | }; | 80 | }; |
| 81 | 81 | ||
| 82 | static struct cpufreq_frequency_table s3c2450_freq_table[] = { | 82 | static struct cpufreq_frequency_table s3c2450_freq_table[] = { |
| 83 | { SOURCE_HCLK, FREQ_DVS }, | 83 | { 0, SOURCE_HCLK, FREQ_DVS }, |
| 84 | { SOURCE_ARMDIV, 133500 }, | 84 | { 0, SOURCE_ARMDIV, 133500 }, |
| 85 | { SOURCE_ARMDIV, 267000 }, | 85 | { 0, SOURCE_ARMDIV, 267000 }, |
| 86 | { SOURCE_ARMDIV, 534000 }, | 86 | { 0, SOURCE_ARMDIV, 534000 }, |
| 87 | { 0, CPUFREQ_TABLE_END }, | 87 | { 0, 0, CPUFREQ_TABLE_END }, |
| 88 | }; | 88 | }; |
| 89 | 89 | ||
| 90 | static unsigned int s3c2416_cpufreq_get_speed(unsigned int cpu) | 90 | static unsigned int s3c2416_cpufreq_get_speed(unsigned int cpu) |
diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c b/drivers/cpufreq/s3c24xx-cpufreq.c index a3dc192d21f9..be1b2b5c9753 100644 --- a/drivers/cpufreq/s3c24xx-cpufreq.c +++ b/drivers/cpufreq/s3c24xx-cpufreq.c | |||
| @@ -586,7 +586,7 @@ static int s3c_cpufreq_build_freq(void) | |||
| 586 | size = cpu_cur.info->calc_freqtable(&cpu_cur, NULL, 0); | 586 | size = cpu_cur.info->calc_freqtable(&cpu_cur, NULL, 0); |
| 587 | size++; | 587 | size++; |
| 588 | 588 | ||
| 589 | ftab = kmalloc(sizeof(*ftab) * size, GFP_KERNEL); | 589 | ftab = kzalloc(sizeof(*ftab) * size, GFP_KERNEL); |
| 590 | if (!ftab) { | 590 | if (!ftab) { |
| 591 | printk(KERN_ERR "%s: no memory for tables\n", __func__); | 591 | printk(KERN_ERR "%s: no memory for tables\n", __func__); |
| 592 | return -ENOMEM; | 592 | return -ENOMEM; |
| @@ -664,7 +664,7 @@ int __init s3c_plltab_register(struct cpufreq_frequency_table *plls, | |||
| 664 | 664 | ||
| 665 | size = sizeof(*vals) * (plls_no + 1); | 665 | size = sizeof(*vals) * (plls_no + 1); |
| 666 | 666 | ||
| 667 | vals = kmalloc(size, GFP_KERNEL); | 667 | vals = kzalloc(size, GFP_KERNEL); |
| 668 | if (vals) { | 668 | if (vals) { |
| 669 | memcpy(vals, plls, size); | 669 | memcpy(vals, plls, size); |
| 670 | pll_reg = vals; | 670 | pll_reg = vals; |
diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c index c4226de079ab..ff7d3ecb85f0 100644 --- a/drivers/cpufreq/s3c64xx-cpufreq.c +++ b/drivers/cpufreq/s3c64xx-cpufreq.c | |||
| @@ -37,19 +37,19 @@ static struct s3c64xx_dvfs s3c64xx_dvfs_table[] = { | |||
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | static struct cpufreq_frequency_table s3c64xx_freq_table[] = { | 39 | static struct cpufreq_frequency_table s3c64xx_freq_table[] = { |
| 40 | { 0, 66000 }, | 40 | { 0, 0, 66000 }, |
| 41 | { 0, 100000 }, | 41 | { 0, 0, 100000 }, |
| 42 | { 0, 133000 }, | 42 | { 0, 0, 133000 }, |
| 43 | { 1, 200000 }, | 43 | { 0, 1, 200000 }, |
| 44 | { 1, 222000 }, | 44 | { 0, 1, 222000 }, |
| 45 | { 1, 266000 }, | 45 | { 0, 1, 266000 }, |
| 46 | { 2, 333000 }, | 46 | { 0, 2, 333000 }, |
| 47 | { 2, 400000 }, | 47 | { 0, 2, 400000 }, |
| 48 | { 2, 532000 }, | 48 | { 0, 2, 532000 }, |
| 49 | { 2, 533000 }, | 49 | { 0, 2, 533000 }, |
| 50 | { 3, 667000 }, | 50 | { 0, 3, 667000 }, |
| 51 | { 4, 800000 }, | 51 | { 0, 4, 800000 }, |
| 52 | { 0, CPUFREQ_TABLE_END }, | 52 | { 0, 0, CPUFREQ_TABLE_END }, |
| 53 | }; | 53 | }; |
| 54 | #endif | 54 | #endif |
| 55 | 55 | ||
diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index 72421534fff5..ab2c1a40d437 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c | |||
| @@ -64,12 +64,12 @@ enum s5pv210_dmc_port { | |||
| 64 | }; | 64 | }; |
| 65 | 65 | ||
| 66 | static struct cpufreq_frequency_table s5pv210_freq_table[] = { | 66 | static struct cpufreq_frequency_table s5pv210_freq_table[] = { |
| 67 | {L0, 1000*1000}, | 67 | {0, L0, 1000*1000}, |
| 68 | {L1, 800*1000}, | 68 | {0, L1, 800*1000}, |
| 69 | {L2, 400*1000}, | 69 | {0, L2, 400*1000}, |
| 70 | {L3, 200*1000}, | 70 | {0, L3, 200*1000}, |
| 71 | {L4, 100*1000}, | 71 | {0, L4, 100*1000}, |
| 72 | {0, CPUFREQ_TABLE_END}, | 72 | {0, 0, CPUFREQ_TABLE_END}, |
| 73 | }; | 73 | }; |
| 74 | 74 | ||
| 75 | static struct regulator *arm_regulator; | 75 | static struct regulator *arm_regulator; |
diff --git a/drivers/cpufreq/sc520_freq.c b/drivers/cpufreq/sc520_freq.c index 69371bf0886d..ac84e4818014 100644 --- a/drivers/cpufreq/sc520_freq.c +++ b/drivers/cpufreq/sc520_freq.c | |||
| @@ -33,9 +33,9 @@ static __u8 __iomem *cpuctl; | |||
| 33 | #define PFX "sc520_freq: " | 33 | #define PFX "sc520_freq: " |
| 34 | 34 | ||
| 35 | static struct cpufreq_frequency_table sc520_freq_table[] = { | 35 | static struct cpufreq_frequency_table sc520_freq_table[] = { |
| 36 | {0x01, 100000}, | 36 | {0, 0x01, 100000}, |
| 37 | {0x02, 133000}, | 37 | {0, 0x02, 133000}, |
| 38 | {0, CPUFREQ_TABLE_END}, | 38 | {0, 0, CPUFREQ_TABLE_END}, |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu) | 41 | static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu) |
diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c index 4cfdcff8a310..38678396636d 100644 --- a/drivers/cpufreq/spear-cpufreq.c +++ b/drivers/cpufreq/spear-cpufreq.c | |||
| @@ -195,18 +195,15 @@ static int spear_cpufreq_probe(struct platform_device *pdev) | |||
| 195 | cnt = prop->length / sizeof(u32); | 195 | cnt = prop->length / sizeof(u32); |
| 196 | val = prop->value; | 196 | val = prop->value; |
| 197 | 197 | ||
| 198 | freq_tbl = kmalloc(sizeof(*freq_tbl) * (cnt + 1), GFP_KERNEL); | 198 | freq_tbl = kzalloc(sizeof(*freq_tbl) * (cnt + 1), GFP_KERNEL); |
| 199 | if (!freq_tbl) { | 199 | if (!freq_tbl) { |
| 200 | ret = -ENOMEM; | 200 | ret = -ENOMEM; |
| 201 | goto out_put_node; | 201 | goto out_put_node; |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | for (i = 0; i < cnt; i++) { | 204 | for (i = 0; i < cnt; i++) |
| 205 | freq_tbl[i].driver_data = i; | ||
| 206 | freq_tbl[i].frequency = be32_to_cpup(val++); | 205 | freq_tbl[i].frequency = be32_to_cpup(val++); |
| 207 | } | ||
| 208 | 206 | ||
| 209 | freq_tbl[i].driver_data = i; | ||
| 210 | freq_tbl[i].frequency = CPUFREQ_TABLE_END; | 207 | freq_tbl[i].frequency = CPUFREQ_TABLE_END; |
| 211 | 208 | ||
| 212 | spear_cpufreq.freq_tbl = freq_tbl; | 209 | spear_cpufreq.freq_tbl = freq_tbl; |
diff --git a/drivers/cpufreq/speedstep-ich.c b/drivers/cpufreq/speedstep-ich.c index 394ac159312a..1a07b5904ed5 100644 --- a/drivers/cpufreq/speedstep-ich.c +++ b/drivers/cpufreq/speedstep-ich.c | |||
| @@ -49,9 +49,9 @@ static u32 pmbase; | |||
| 49 | * are in kHz for the time being. | 49 | * are in kHz for the time being. |
| 50 | */ | 50 | */ |
| 51 | static struct cpufreq_frequency_table speedstep_freqs[] = { | 51 | static struct cpufreq_frequency_table speedstep_freqs[] = { |
| 52 | {SPEEDSTEP_HIGH, 0}, | 52 | {0, SPEEDSTEP_HIGH, 0}, |
| 53 | {SPEEDSTEP_LOW, 0}, | 53 | {0, SPEEDSTEP_LOW, 0}, |
| 54 | {0, CPUFREQ_TABLE_END}, | 54 | {0, 0, CPUFREQ_TABLE_END}, |
| 55 | }; | 55 | }; |
| 56 | 56 | ||
| 57 | 57 | ||
diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c index db5d274dc13a..8635eec96da5 100644 --- a/drivers/cpufreq/speedstep-smi.c +++ b/drivers/cpufreq/speedstep-smi.c | |||
| @@ -42,9 +42,9 @@ static enum speedstep_processor speedstep_processor; | |||
| 42 | * are in kHz for the time being. | 42 | * are in kHz for the time being. |
| 43 | */ | 43 | */ |
| 44 | static struct cpufreq_frequency_table speedstep_freqs[] = { | 44 | static struct cpufreq_frequency_table speedstep_freqs[] = { |
| 45 | {SPEEDSTEP_HIGH, 0}, | 45 | {0, SPEEDSTEP_HIGH, 0}, |
| 46 | {SPEEDSTEP_LOW, 0}, | 46 | {0, SPEEDSTEP_LOW, 0}, |
| 47 | {0, CPUFREQ_TABLE_END}, | 47 | {0, 0, CPUFREQ_TABLE_END}, |
| 48 | }; | 48 | }; |
| 49 | 49 | ||
| 50 | #define GET_SPEEDSTEP_OWNER 0 | 50 | #define GET_SPEEDSTEP_OWNER 0 |
diff --git a/drivers/cpufreq/unicore2-cpufreq.c b/drivers/cpufreq/unicore2-cpufreq.c index 13be802b6170..8d045afa7fb4 100644 --- a/drivers/cpufreq/unicore2-cpufreq.c +++ b/drivers/cpufreq/unicore2-cpufreq.c | |||
| @@ -45,7 +45,7 @@ static int ucv2_target(struct cpufreq_policy *policy, | |||
| 45 | freqs.new = target_freq; | 45 | freqs.new = target_freq; |
| 46 | 46 | ||
| 47 | cpufreq_freq_transition_begin(policy, &freqs); | 47 | cpufreq_freq_transition_begin(policy, &freqs); |
| 48 | ret = clk_set_rate(policy->mclk, target_freq * 1000); | 48 | ret = clk_set_rate(policy->clk, target_freq * 1000); |
| 49 | cpufreq_freq_transition_end(policy, &freqs, ret); | 49 | cpufreq_freq_transition_end(policy, &freqs, ret); |
| 50 | 50 | ||
| 51 | return ret; | 51 | return ret; |
diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index e918b6d0caf7..efe2f175168f 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c | |||
| @@ -293,6 +293,7 @@ static ssize_t show_state_##_name(struct cpuidle_state *state, \ | |||
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | define_show_state_function(exit_latency) | 295 | define_show_state_function(exit_latency) |
| 296 | define_show_state_function(target_residency) | ||
| 296 | define_show_state_function(power_usage) | 297 | define_show_state_function(power_usage) |
| 297 | define_show_state_ull_function(usage) | 298 | define_show_state_ull_function(usage) |
| 298 | define_show_state_ull_function(time) | 299 | define_show_state_ull_function(time) |
| @@ -304,6 +305,7 @@ define_store_state_ull_function(disable) | |||
| 304 | define_one_state_ro(name, show_state_name); | 305 | define_one_state_ro(name, show_state_name); |
| 305 | define_one_state_ro(desc, show_state_desc); | 306 | define_one_state_ro(desc, show_state_desc); |
| 306 | define_one_state_ro(latency, show_state_exit_latency); | 307 | define_one_state_ro(latency, show_state_exit_latency); |
| 308 | define_one_state_ro(residency, show_state_target_residency); | ||
| 307 | define_one_state_ro(power, show_state_power_usage); | 309 | define_one_state_ro(power, show_state_power_usage); |
| 308 | define_one_state_ro(usage, show_state_usage); | 310 | define_one_state_ro(usage, show_state_usage); |
| 309 | define_one_state_ro(time, show_state_time); | 311 | define_one_state_ro(time, show_state_time); |
| @@ -313,6 +315,7 @@ static struct attribute *cpuidle_state_default_attrs[] = { | |||
| 313 | &attr_name.attr, | 315 | &attr_name.attr, |
| 314 | &attr_desc.attr, | 316 | &attr_desc.attr, |
| 315 | &attr_latency.attr, | 317 | &attr_latency.attr, |
| 318 | &attr_residency.attr, | ||
| 316 | &attr_power.attr, | 319 | &attr_power.attr, |
| 317 | &attr_usage.attr, | 320 | &attr_usage.attr, |
| 318 | &attr_time.attr, | 321 | &attr_time.attr, |
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 51493ed4643b..a43220c2e3d9 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
| @@ -196,6 +196,53 @@ static struct cpuidle_state snb_cstates[] = { | |||
| 196 | .enter = NULL } | 196 | .enter = NULL } |
| 197 | }; | 197 | }; |
| 198 | 198 | ||
| 199 | static struct cpuidle_state byt_cstates[] = { | ||
| 200 | { | ||
| 201 | .name = "C1-BYT", | ||
| 202 | .desc = "MWAIT 0x00", | ||
| 203 | .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID, | ||
| 204 | .exit_latency = 1, | ||
| 205 | .target_residency = 1, | ||
| 206 | .enter = &intel_idle }, | ||
| 207 | { | ||
| 208 | .name = "C1E-BYT", | ||
| 209 | .desc = "MWAIT 0x01", | ||
| 210 | .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID, | ||
| 211 | .exit_latency = 15, | ||
| 212 | .target_residency = 30, | ||
| 213 | .enter = &intel_idle }, | ||
| 214 | { | ||
| 215 | .name = "C6N-BYT", | ||
| 216 | .desc = "MWAIT 0x58", | ||
| 217 | .flags = MWAIT2flg(0x58) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
| 218 | .exit_latency = 40, | ||
| 219 | .target_residency = 275, | ||
| 220 | .enter = &intel_idle }, | ||
| 221 | { | ||
| 222 | .name = "C6S-BYT", | ||
| 223 | .desc = "MWAIT 0x52", | ||
| 224 | .flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
| 225 | .exit_latency = 140, | ||
| 226 | .target_residency = 560, | ||
| 227 | .enter = &intel_idle }, | ||
| 228 | { | ||
| 229 | .name = "C7-BYT", | ||
| 230 | .desc = "MWAIT 0x60", | ||
| 231 | .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
| 232 | .exit_latency = 1200, | ||
| 233 | .target_residency = 1500, | ||
| 234 | .enter = &intel_idle }, | ||
| 235 | { | ||
| 236 | .name = "C7S-BYT", | ||
| 237 | .desc = "MWAIT 0x64", | ||
| 238 | .flags = MWAIT2flg(0x64) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
| 239 | .exit_latency = 10000, | ||
| 240 | .target_residency = 20000, | ||
| 241 | .enter = &intel_idle }, | ||
| 242 | { | ||
| 243 | .enter = NULL } | ||
| 244 | }; | ||
| 245 | |||
| 199 | static struct cpuidle_state ivb_cstates[] = { | 246 | static struct cpuidle_state ivb_cstates[] = { |
| 200 | { | 247 | { |
| 201 | .name = "C1-IVB", | 248 | .name = "C1-IVB", |
| @@ -236,6 +283,105 @@ static struct cpuidle_state ivb_cstates[] = { | |||
| 236 | .enter = NULL } | 283 | .enter = NULL } |
| 237 | }; | 284 | }; |
| 238 | 285 | ||
| 286 | static struct cpuidle_state ivt_cstates[] = { | ||
| 287 | { | ||
| 288 | .name = "C1-IVT", | ||
| 289 | .desc = "MWAIT 0x00", | ||
| 290 | .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID, | ||
| 291 | .exit_latency = 1, | ||
| 292 | .target_residency = 1, | ||
| 293 | .enter = &intel_idle }, | ||
| 294 | { | ||
| 295 | .name = "C1E-IVT", | ||
| 296 | .desc = "MWAIT 0x01", | ||
| 297 | .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID, | ||
| 298 | .exit_latency = 10, | ||
| 299 | .target_residency = 80, | ||
| 300 | .enter = &intel_idle }, | ||
| 301 | { | ||
| 302 | .name = "C3-IVT", | ||
| 303 | .desc = "MWAIT 0x10", | ||
| 304 | .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
| 305 | .exit_latency = 59, | ||
| 306 | .target_residency = 156, | ||
| 307 | .enter = &intel_idle }, | ||
| 308 | { | ||
| 309 | .name = "C6-IVT", | ||
| 310 | .desc = "MWAIT 0x20", | ||
| 311 | .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
| 312 | .exit_latency = 82, | ||
| 313 | .target_residency = 300, | ||
| 314 | .enter = &intel_idle }, | ||
| 315 | { | ||
| 316 | .enter = NULL } | ||
| 317 | }; | ||
| 318 | |||
| 319 | static struct cpuidle_state ivt_cstates_4s[] = { | ||
| 320 | { | ||
| 321 | .name = "C1-IVT-4S", | ||
| 322 | .desc = "MWAIT 0x00", | ||
| 323 | .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID, | ||
| 324 | .exit_latency = 1, | ||
| 325 | .target_residency = 1, | ||
| 326 | .enter = &intel_idle }, | ||
| 327 | { | ||
| 328 | .name = "C1E-IVT-4S", | ||
| 329 | .desc = "MWAIT 0x01", | ||
| 330 | .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID, | ||
| 331 | .exit_latency = 10, | ||
| 332 | .target_residency = 250, | ||
| 333 | .enter = &intel_idle }, | ||
| 334 | { | ||
| 335 | .name = "C3-IVT-4S", | ||
| 336 | .desc = "MWAIT 0x10", | ||
| 337 | .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
| 338 | .exit_latency = 59, | ||
| 339 | .target_residency = 300, | ||
| 340 | .enter = &intel_idle }, | ||
| 341 | { | ||
| 342 | .name = "C6-IVT-4S", | ||
| 343 | .desc = "MWAIT 0x20", | ||
| 344 | .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
| 345 | .exit_latency = 84, | ||
| 346 | .target_residency = 400, | ||
| 347 | .enter = &intel_idle }, | ||
| 348 | { | ||
| 349 | .enter = NULL } | ||
| 350 | }; | ||
| 351 | |||
| 352 | static struct cpuidle_state ivt_cstates_8s[] = { | ||
| 353 | { | ||
| 354 | .name = "C1-IVT-8S", | ||
| 355 | .desc = "MWAIT 0x00", | ||
| 356 | .flags = MWAIT2flg(0x00) | CPUIDLE_FLAG_TIME_VALID, | ||
| 357 | .exit_latency = 1, | ||
| 358 | .target_residency = 1, | ||
| 359 | .enter = &intel_idle }, | ||
| 360 | { | ||
| 361 | .name = "C1E-IVT-8S", | ||
| 362 | .desc = "MWAIT 0x01", | ||
| 363 | .flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_TIME_VALID, | ||
| 364 | .exit_latency = 10, | ||
| 365 | .target_residency = 500, | ||
| 366 | .enter = &intel_idle }, | ||
| 367 | { | ||
| 368 | .name = "C3-IVT-8S", | ||
| 369 | .desc = "MWAIT 0x10", | ||
| 370 | .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
| 371 | .exit_latency = 59, | ||
| 372 | .target_residency = 600, | ||
| 373 | .enter = &intel_idle }, | ||
| 374 | { | ||
| 375 | .name = "C6-IVT-8S", | ||
| 376 | .desc = "MWAIT 0x20", | ||
| 377 | .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, | ||
| 378 | .exit_latency = 88, | ||
| 379 | .target_residency = 700, | ||
| 380 | .enter = &intel_idle }, | ||
| 381 | { | ||
| 382 | .enter = NULL } | ||
| 383 | }; | ||
| 384 | |||
| 239 | static struct cpuidle_state hsw_cstates[] = { | 385 | static struct cpuidle_state hsw_cstates[] = { |
| 240 | { | 386 | { |
| 241 | .name = "C1-HSW", | 387 | .name = "C1-HSW", |
| @@ -464,11 +610,21 @@ static const struct idle_cpu idle_cpu_snb = { | |||
| 464 | .disable_promotion_to_c1e = true, | 610 | .disable_promotion_to_c1e = true, |
| 465 | }; | 611 | }; |
| 466 | 612 | ||
| 613 | static const struct idle_cpu idle_cpu_byt = { | ||
| 614 | .state_table = byt_cstates, | ||
| 615 | .disable_promotion_to_c1e = true, | ||
| 616 | }; | ||
| 617 | |||
| 467 | static const struct idle_cpu idle_cpu_ivb = { | 618 | static const struct idle_cpu idle_cpu_ivb = { |
| 468 | .state_table = ivb_cstates, | 619 | .state_table = ivb_cstates, |
| 469 | .disable_promotion_to_c1e = true, | 620 | .disable_promotion_to_c1e = true, |
| 470 | }; | 621 | }; |
| 471 | 622 | ||
| 623 | static const struct idle_cpu idle_cpu_ivt = { | ||
| 624 | .state_table = ivt_cstates, | ||
| 625 | .disable_promotion_to_c1e = true, | ||
| 626 | }; | ||
| 627 | |||
| 472 | static const struct idle_cpu idle_cpu_hsw = { | 628 | static const struct idle_cpu idle_cpu_hsw = { |
| 473 | .state_table = hsw_cstates, | 629 | .state_table = hsw_cstates, |
| 474 | .disable_promotion_to_c1e = true, | 630 | .disable_promotion_to_c1e = true, |
| @@ -494,8 +650,10 @@ static const struct x86_cpu_id intel_idle_ids[] = { | |||
| 494 | ICPU(0x2f, idle_cpu_nehalem), | 650 | ICPU(0x2f, idle_cpu_nehalem), |
| 495 | ICPU(0x2a, idle_cpu_snb), | 651 | ICPU(0x2a, idle_cpu_snb), |
| 496 | ICPU(0x2d, idle_cpu_snb), | 652 | ICPU(0x2d, idle_cpu_snb), |
| 653 | ICPU(0x36, idle_cpu_atom), | ||
| 654 | ICPU(0x37, idle_cpu_byt), | ||
| 497 | ICPU(0x3a, idle_cpu_ivb), | 655 | ICPU(0x3a, idle_cpu_ivb), |
| 498 | ICPU(0x3e, idle_cpu_ivb), | 656 | ICPU(0x3e, idle_cpu_ivt), |
| 499 | ICPU(0x3c, idle_cpu_hsw), | 657 | ICPU(0x3c, idle_cpu_hsw), |
| 500 | ICPU(0x3f, idle_cpu_hsw), | 658 | ICPU(0x3f, idle_cpu_hsw), |
| 501 | ICPU(0x45, idle_cpu_hsw), | 659 | ICPU(0x45, idle_cpu_hsw), |
| @@ -572,6 +730,39 @@ static void intel_idle_cpuidle_devices_uninit(void) | |||
| 572 | free_percpu(intel_idle_cpuidle_devices); | 730 | free_percpu(intel_idle_cpuidle_devices); |
| 573 | return; | 731 | return; |
| 574 | } | 732 | } |
| 733 | |||
| 734 | /* | ||
| 735 | * intel_idle_state_table_update() | ||
| 736 | * | ||
| 737 | * Update the default state_table for this CPU-id | ||
| 738 | * | ||
| 739 | * Currently used to access tuned IVT multi-socket targets | ||
| 740 | * Assumption: num_sockets == (max_package_num + 1) | ||
| 741 | */ | ||
| 742 | void intel_idle_state_table_update(void) | ||
| 743 | { | ||
| 744 | /* IVT uses a different table for 1-2, 3-4, and > 4 sockets */ | ||
| 745 | if (boot_cpu_data.x86_model == 0x3e) { /* IVT */ | ||
| 746 | int cpu, package_num, num_sockets = 1; | ||
| 747 | |||
| 748 | for_each_online_cpu(cpu) { | ||
| 749 | package_num = topology_physical_package_id(cpu); | ||
| 750 | if (package_num + 1 > num_sockets) { | ||
| 751 | num_sockets = package_num + 1; | ||
| 752 | |||
| 753 | if (num_sockets > 4) | ||
| 754 | cpuidle_state_table = ivt_cstates_8s; | ||
| 755 | return; | ||
| 756 | } | ||
| 757 | } | ||
| 758 | |||
| 759 | if (num_sockets > 2) | ||
| 760 | cpuidle_state_table = ivt_cstates_4s; | ||
| 761 | /* else, 1 and 2 socket systems use default ivt_cstates */ | ||
| 762 | } | ||
| 763 | return; | ||
| 764 | } | ||
| 765 | |||
| 575 | /* | 766 | /* |
| 576 | * intel_idle_cpuidle_driver_init() | 767 | * intel_idle_cpuidle_driver_init() |
| 577 | * allocate, initialize cpuidle_states | 768 | * allocate, initialize cpuidle_states |
| @@ -581,10 +772,12 @@ static int __init intel_idle_cpuidle_driver_init(void) | |||
| 581 | int cstate; | 772 | int cstate; |
| 582 | struct cpuidle_driver *drv = &intel_idle_driver; | 773 | struct cpuidle_driver *drv = &intel_idle_driver; |
| 583 | 774 | ||
| 775 | intel_idle_state_table_update(); | ||
| 776 | |||
| 584 | drv->state_count = 1; | 777 | drv->state_count = 1; |
| 585 | 778 | ||
| 586 | for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) { | 779 | for (cstate = 0; cstate < CPUIDLE_STATE_MAX; ++cstate) { |
| 587 | int num_substates, mwait_hint, mwait_cstate, mwait_substate; | 780 | int num_substates, mwait_hint, mwait_cstate; |
| 588 | 781 | ||
| 589 | if (cpuidle_state_table[cstate].enter == NULL) | 782 | if (cpuidle_state_table[cstate].enter == NULL) |
| 590 | break; | 783 | break; |
| @@ -597,14 +790,13 @@ static int __init intel_idle_cpuidle_driver_init(void) | |||
| 597 | 790 | ||
| 598 | mwait_hint = flg2MWAIT(cpuidle_state_table[cstate].flags); | 791 | mwait_hint = flg2MWAIT(cpuidle_state_table[cstate].flags); |
| 599 | mwait_cstate = MWAIT_HINT2CSTATE(mwait_hint); | 792 | mwait_cstate = MWAIT_HINT2CSTATE(mwait_hint); |
| 600 | mwait_substate = MWAIT_HINT2SUBSTATE(mwait_hint); | ||
| 601 | 793 | ||
| 602 | /* does the state exist in CPUID.MWAIT? */ | 794 | /* number of sub-states for this state in CPUID.MWAIT */ |
| 603 | num_substates = (mwait_substates >> ((mwait_cstate + 1) * 4)) | 795 | num_substates = (mwait_substates >> ((mwait_cstate + 1) * 4)) |
| 604 | & MWAIT_SUBSTATE_MASK; | 796 | & MWAIT_SUBSTATE_MASK; |
| 605 | 797 | ||
| 606 | /* if sub-state in table is not enumerated by CPUID */ | 798 | /* if NO sub-states for this state in CPUID, skip it */ |
| 607 | if ((mwait_substate + 1) > num_substates) | 799 | if (num_substates == 0) |
| 608 | continue; | 800 | continue; |
| 609 | 801 | ||
| 610 | if (((mwait_cstate + 1) > 2) && | 802 | if (((mwait_cstate + 1) > 2) && |
