aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/Kconfig8
-rw-r--r--drivers/acpi/dock.c6
-rw-r--r--drivers/acpi/osl.c3
-rw-r--r--drivers/acpi/thermal.c2
-rw-r--r--drivers/acpi/utils.c3
-rw-r--r--drivers/acpi/video.c8
-rw-r--r--drivers/base/power/domain.c13
-rw-r--r--drivers/cpufreq/Kconfig.arm6
-rw-r--r--drivers/cpufreq/Kconfig.powerpc8
-rw-r--r--drivers/cpufreq/Makefile1
-rw-r--r--drivers/cpufreq/acpi-cpufreq.c2
-rw-r--r--drivers/cpufreq/at32ap-cpufreq.c2
-rw-r--r--drivers/cpufreq/cris-artpec3-cpufreq.c6
-rw-r--r--drivers/cpufreq/cris-etraxfs-cpufreq.c6
-rw-r--r--drivers/cpufreq/elanfreq.c18
-rw-r--r--drivers/cpufreq/exynos4210-cpufreq.c12
-rw-r--r--drivers/cpufreq/exynos4x12-cpufreq.c30
-rw-r--r--drivers/cpufreq/exynos5250-cpufreq.c34
-rw-r--r--drivers/cpufreq/freq_table.c11
-rw-r--r--drivers/cpufreq/ia64-acpi-cpufreq.c3
-rw-r--r--drivers/cpufreq/kirkwood-cpufreq.c6
-rw-r--r--drivers/cpufreq/longhaul.c2
-rw-r--r--drivers/cpufreq/loongson2_cpufreq.c2
-rw-r--r--drivers/cpufreq/maple-cpufreq.c6
-rw-r--r--drivers/cpufreq/p4-clockmod.c20
-rw-r--r--drivers/cpufreq/pasemi-cpufreq.c12
-rw-r--r--drivers/cpufreq/pmac32-cpufreq.c6
-rw-r--r--drivers/cpufreq/pmac64-cpufreq.c6
-rw-r--r--drivers/cpufreq/powernow-k6.c18
-rw-r--r--drivers/cpufreq/powernow-k8.c5
-rw-r--r--drivers/cpufreq/powernv-cpufreq.c341
-rw-r--r--drivers/cpufreq/ppc-corenet-cpufreq.c1
-rw-r--r--drivers/cpufreq/ppc_cbe_cpufreq.c18
-rw-r--r--drivers/cpufreq/s3c2416-cpufreq.c20
-rw-r--r--drivers/cpufreq/s3c24xx-cpufreq.c4
-rw-r--r--drivers/cpufreq/s3c64xx-cpufreq.c26
-rw-r--r--drivers/cpufreq/s5pv210-cpufreq.c12
-rw-r--r--drivers/cpufreq/sc520_freq.c6
-rw-r--r--drivers/cpufreq/spear-cpufreq.c7
-rw-r--r--drivers/cpufreq/speedstep-ich.c6
-rw-r--r--drivers/cpufreq/speedstep-smi.c6
-rw-r--r--drivers/cpufreq/unicore2-cpufreq.c2
-rw-r--r--drivers/cpuidle/sysfs.c3
-rw-r--r--drivers/idle/intel_idle.c204
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
39if ACPI 43if 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
54static const struct acpi_device_id dock_device_ids[] = {
55 {"LNXDOCK", 0},
56 {"", 0},
57};
58MODULE_DEVICE_TABLE(acpi, dock_device_ids);
59
60struct dock_station { 54struct 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
708static bool pd_ignore_unused;
709static 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
31config ARM_EXYNOS4210_CPUFREQ 31config 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
42config ARM_EXYNOS4X12_CPUFREQ 42config 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
53config ARM_EXYNOS5250_CPUFREQ 53config 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
58config 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
86obj-$(CONFIG_CPU_FREQ_PMAC) += pmac32-cpufreq.o 86obj-$(CONFIG_CPU_FREQ_PMAC) += pmac32-cpufreq.o
87obj-$(CONFIG_CPU_FREQ_PMAC64) += pmac64-cpufreq.o 87obj-$(CONFIG_CPU_FREQ_PMAC64) += pmac64-cpufreq.o
88obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += pasemi-cpufreq.o 88obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += pasemi-cpufreq.o
89obj-$(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)
52static int at32_cpufreq_driver_init(struct cpufreq_policy *policy) 52static 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
17static struct cpufreq_frequency_table cris_freq_table[] = { 17static 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
23static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu) 23static 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
17static struct cpufreq_frequency_table cris_freq_table[] = { 17static 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
23static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu) 23static 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
58static struct cpufreq_frequency_table elanfreq_table[] = { 58static 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
31static struct cpufreq_frequency_table exynos4210_freq_table[] = { 31static 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
40static struct apll_freq apll_freq_4210[] = { 40static 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
32static struct cpufreq_frequency_table exynos4x12_freq_table[] = { 32static 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
50static struct apll_freq *apll_freq_4x12; 50static 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
36static struct cpufreq_frequency_table exynos5250_freq_table[] = { 36static 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
56static struct apll_freq apll_freq_5250[] = { 56static 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 */
45static struct cpufreq_frequency_table kirkwood_freq_table[] = { 45static 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
51static unsigned int kirkwood_cpufreq_get_cpu_frequency(unsigned int cpu) 51static 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
70static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy) 70static 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
61static struct cpufreq_frequency_table maple_cpu_freqs[] = { 61static 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
94static struct cpufreq_frequency_table p4clockmod_table[] = { 94static 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 */
62static struct cpufreq_frequency_table pas_freqs[] = { 62static 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
83static struct cpufreq_frequency_table pmac_cpu_freqs[] = { 83static 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
89static inline void local_delay(unsigned long ms) 89static 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
67static struct cpufreq_frequency_table g5_cpu_freqs[] = { 67static 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 */
39static struct cpufreq_frequency_table clock_ratio[] = { 39static 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
51static const u8 index_to_register[8] = { 6, 3, 1, 0, 2, 7, 5, 4 }; 51static 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
35static 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 */
45static 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 */
56static 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. */
128static 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 */
142static 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
149struct freq_attr cpufreq_freq_attr_cpuinfo_nominal_freq =
150 __ATTR_RO(cpuinfo_nominal_freq);
151
152static 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
162static 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
177static 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 */
195struct 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 */
211static 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 */
237unsigned 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 */
256static 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 */
280static 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
297static 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
309static 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
319static 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}
332module_init(powernv_cpufreq_init);
333
334static void __exit powernv_cpufreq_exit(void)
335{
336 cpufreq_unregister_driver(&powernv_cpufreq_driver);
337}
338module_exit(powernv_cpufreq_exit);
339
340MODULE_LICENSE("GPL");
341MODULE_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 */
34static struct cpufreq_frequency_table cbe_freqs[] = { 34static 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
74static struct cpufreq_frequency_table s3c2416_freq_table[] = { 74static 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
82static struct cpufreq_frequency_table s3c2450_freq_table[] = { 82static 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
90static unsigned int s3c2416_cpufreq_get_speed(unsigned int cpu) 90static 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
39static struct cpufreq_frequency_table s3c64xx_freq_table[] = { 39static 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
66static struct cpufreq_frequency_table s5pv210_freq_table[] = { 66static 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
75static struct regulator *arm_regulator; 75static 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
35static struct cpufreq_frequency_table sc520_freq_table[] = { 35static 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
41static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu) 41static 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 */
51static struct cpufreq_frequency_table speedstep_freqs[] = { 51static 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 */
44static struct cpufreq_frequency_table speedstep_freqs[] = { 44static 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
295define_show_state_function(exit_latency) 295define_show_state_function(exit_latency)
296define_show_state_function(target_residency)
296define_show_state_function(power_usage) 297define_show_state_function(power_usage)
297define_show_state_ull_function(usage) 298define_show_state_ull_function(usage)
298define_show_state_ull_function(time) 299define_show_state_ull_function(time)
@@ -304,6 +305,7 @@ define_store_state_ull_function(disable)
304define_one_state_ro(name, show_state_name); 305define_one_state_ro(name, show_state_name);
305define_one_state_ro(desc, show_state_desc); 306define_one_state_ro(desc, show_state_desc);
306define_one_state_ro(latency, show_state_exit_latency); 307define_one_state_ro(latency, show_state_exit_latency);
308define_one_state_ro(residency, show_state_target_residency);
307define_one_state_ro(power, show_state_power_usage); 309define_one_state_ro(power, show_state_power_usage);
308define_one_state_ro(usage, show_state_usage); 310define_one_state_ro(usage, show_state_usage);
309define_one_state_ro(time, show_state_time); 311define_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
199static 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
199static struct cpuidle_state ivb_cstates[] = { 246static 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
286static 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
319static 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
352static 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
239static struct cpuidle_state hsw_cstates[] = { 385static 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
613static const struct idle_cpu idle_cpu_byt = {
614 .state_table = byt_cstates,
615 .disable_promotion_to_c1e = true,
616};
617
467static const struct idle_cpu idle_cpu_ivb = { 618static 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
623static const struct idle_cpu idle_cpu_ivt = {
624 .state_table = ivt_cstates,
625 .disable_promotion_to_c1e = true,
626};
627
472static const struct idle_cpu idle_cpu_hsw = { 628static 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 */
742void 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) &&