From c925401b6dc2229adbb15b2f3c9f0f2d9253a5d5 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 22 Aug 2007 18:44:20 -0700 Subject: [PATCH 01/10] [CPUFREQ] x86: use num_online_nodes to get physical cpus numbers for powernow_k8 [PATCH] x86: use num_online_nodes to get physical cpus numbers for powernow_k8 For opteron based system, don't assume all physical cpus have the same booted cpus even same cores. esp for downcore case. Signed-off-by: Yinghai Lu Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 34ed53a06730..372df6e67e89 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -1325,21 +1325,16 @@ static struct cpufreq_driver cpufreq_amd64_driver = { static int __cpuinit powernowk8_init(void) { unsigned int i, supported_cpus = 0; - unsigned int booted_cores = 1; for_each_online_cpu(i) { if (check_supported_cpu(i)) supported_cpus++; } -#ifdef CONFIG_SMP - booted_cores = cpu_data[0].booted_cores; -#endif - if (supported_cpus == num_online_cpus()) { printk(KERN_INFO PFX "Found %d %s " "processors (%d cpu cores) (" VERSION ")\n", - supported_cpus/booted_cores, + num_online_nodes(), boot_cpu_data.x86_model_id, supported_cpus); return cpufreq_register_driver(&cpufreq_amd64_driver); } From a09d60a622ea4a3592dc6836e709d4a7a4ed4025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Bilski?= Date: Wed, 26 Sep 2007 17:08:14 +0200 Subject: [PATCH 02/10] [CPUFREQ] Longhaul - Add support for PM133 northbridge Add support for PM133 northbridge. Tested by Sylvain Ferrand. Signed-off-by: Rafal Bilski Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/longhaul.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c index ef8f0bc3fc71..58816facc435 100644 --- a/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c @@ -665,6 +665,10 @@ static int enable_arbiter_disable(void) reg = 0x78; dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0, NULL); + /* Find PM133/VT8605 host bridge */ + if (dev == NULL) + dev = pci_get_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_8605_0, NULL); /* Find CLE266 host bridge */ if (dev == NULL) { reg = 0x76; From 8122c6cea033e8034e99d3b10a4e3f377ce23994 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Tue, 2 Oct 2007 13:28:09 -0700 Subject: [PATCH 03/10] [CPUFREQ] move policy's governor initialisation out of low-level drivers into cpufreq core Signed-off-by: Thomas Renninger Signed-off-by: Venkatesh Pallipadi Cc: Russell King Cc: Bryan Wu Cc: Andi Kleen Cc: "Luck, Tony" Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Cc: Paul Mundt Cc: "David S. Miller" Signed-off-by: Andrew Morton Signed-off-by: Dave Jones --- arch/arm/mach-imx/cpufreq.c | 1 - arch/arm/mach-sa1100/cpu-sa1110.c | 1 - arch/arm/plat-omap/cpu-omap.c | 1 - arch/blackfin/mach-bf533/cpu.c | 2 -- arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 1 - arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c | 1 - arch/i386/kernel/cpu/cpufreq/e_powersaver.c | 1 - arch/i386/kernel/cpu/cpufreq/elanfreq.c | 1 - arch/i386/kernel/cpu/cpufreq/gx-suspmod.c | 1 - arch/i386/kernel/cpu/cpufreq/longhaul.c | 1 - arch/i386/kernel/cpu/cpufreq/p4-clockmod.c | 1 - arch/i386/kernel/cpu/cpufreq/powernow-k6.c | 1 - arch/i386/kernel/cpu/cpufreq/powernow-k7.c | 2 -- arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 1 - arch/i386/kernel/cpu/cpufreq/sc520_freq.c | 1 - arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c | 1 - arch/i386/kernel/cpu/cpufreq/speedstep-ich.c | 1 - arch/i386/kernel/cpu/cpufreq/speedstep-smi.c | 1 - arch/ia64/kernel/cpufreq/acpi-cpufreq.c | 2 -- arch/powerpc/platforms/cell/cbe_cpufreq.c | 2 -- arch/powerpc/platforms/pasemi/cpufreq.c | 2 -- arch/powerpc/platforms/powermac/cpufreq_32.c | 1 - arch/powerpc/platforms/powermac/cpufreq_64.c | 1 - arch/sh/kernel/cpufreq.c | 1 - arch/sparc64/kernel/us2e_cpufreq.c | 1 - drivers/cpufreq/cpufreq.c | 2 ++ 26 files changed, 2 insertions(+), 30 deletions(-) diff --git a/arch/arm/mach-imx/cpufreq.c b/arch/arm/mach-imx/cpufreq.c index 467d899fbe75..e548ba74a4d2 100644 --- a/arch/arm/mach-imx/cpufreq.c +++ b/arch/arm/mach-imx/cpufreq.c @@ -269,7 +269,6 @@ static int __init imx_cpufreq_driver_init(struct cpufreq_policy *policy) return -EINVAL; policy->cur = policy->min = policy->max = imx_get_speed(0); - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.min_freq = 8000; policy->cpuinfo.max_freq = 200000; /* Manual states, that PLL stabilizes in two CLK32 periods */ diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c index 78f4c1346044..36b47ff5af11 100644 --- a/arch/arm/mach-sa1100/cpu-sa1110.c +++ b/arch/arm/mach-sa1100/cpu-sa1110.c @@ -331,7 +331,6 @@ static int __init sa1110_cpu_init(struct cpufreq_policy *policy) if (policy->cpu != 0) return -EINVAL; policy->cur = policy->min = policy->max = sa11x0_getspeed(0); - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.min_freq = 59000; policy->cpuinfo.max_freq = 287000; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c index a0c71dca2373..c0d63b0c61c9 100644 --- a/arch/arm/plat-omap/cpu-omap.c +++ b/arch/arm/plat-omap/cpu-omap.c @@ -108,7 +108,6 @@ static int __init omap_cpu_init(struct cpufreq_policy *policy) if (policy->cpu != 0) return -EINVAL; policy->cur = policy->min = policy->max = omap_getspeed(0); - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000; policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, VERY_HI_RATE) / 1000; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; diff --git a/arch/blackfin/mach-bf533/cpu.c b/arch/blackfin/mach-bf533/cpu.c index 6fd9cfd0a31b..b7a0e0fbd9af 100644 --- a/arch/blackfin/mach-bf533/cpu.c +++ b/arch/blackfin/mach-bf533/cpu.c @@ -118,8 +118,6 @@ static int __init __bf533_cpu_init(struct cpufreq_policy *policy) if (policy->cpu != 0) return -EINVAL; - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; /*Now ,only support one cpu */ policy->cur = bf533_getfreq(0); diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 705e13a30781..42115b609f63 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -646,7 +646,6 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) policy->cpuinfo.transition_latency = perf->states[i].transition_latency * 1000; } - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; data->max_freq = perf->states[0].core_frequency * 1000; /* table init */ diff --git a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c index 66acd5039918..32f0bda3fc95 100644 --- a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c +++ b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c @@ -363,7 +363,6 @@ static int nforce2_cpu_init(struct cpufreq_policy *policy) policy->cur = nforce2_get(policy->cpu); policy->min = policy->cpuinfo.min_freq; policy->max = policy->cpuinfo.max_freq; - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; return 0; } diff --git a/arch/i386/kernel/cpu/cpufreq/e_powersaver.c b/arch/i386/kernel/cpu/cpufreq/e_powersaver.c index f43d98e11cc7..c11baaf9f2b4 100644 --- a/arch/i386/kernel/cpu/cpufreq/e_powersaver.c +++ b/arch/i386/kernel/cpu/cpufreq/e_powersaver.c @@ -253,7 +253,6 @@ static int eps_cpu_init(struct cpufreq_policy *policy) f_table[k].frequency = CPUFREQ_TABLE_END; } - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = 140000; /* 844mV -> 700mV in ns */ policy->cur = fsb * current_multiplier; diff --git a/arch/i386/kernel/cpu/cpufreq/elanfreq.c b/arch/i386/kernel/cpu/cpufreq/elanfreq.c index f317276afa7a..1e7ae7dafcf6 100644 --- a/arch/i386/kernel/cpu/cpufreq/elanfreq.c +++ b/arch/i386/kernel/cpu/cpufreq/elanfreq.c @@ -219,7 +219,6 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy) } /* cpuinfo and default policy values */ - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->cur = elanfreq_get_cpu_frequency(0); diff --git a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c index 461dabc4e495..ed2bda127c44 100644 --- a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c +++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c @@ -420,7 +420,6 @@ static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy) policy->min = maxfreq / POLICY_MIN_DIV; policy->max = maxfreq; policy->cur = curfreq; - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.min_freq = maxfreq / max_duration; policy->cpuinfo.max_freq = maxfreq; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c index 58816facc435..a2fbfd912a08 100644 --- a/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c @@ -877,7 +877,6 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) if ((longhaul_version != TYPE_LONGHAUL_V1) && (scale_voltage != 0)) longhaul_setup_voltagescaling(); - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = 200000; /* nsec */ policy->cur = calc_speed(longhaul_get_cpu_mult()); diff --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c index 4c76b511e194..8eb414b906d2 100644 --- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c +++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c @@ -229,7 +229,6 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) cpufreq_frequency_table_get_attr(p4clockmod_table, policy->cpu); /* cpuinfo and default policy values */ - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = 1000000; /* assumed */ policy->cur = stock_freq; diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c b/arch/i386/kernel/cpu/cpufreq/powernow-k6.c index f89524051e4a..6d0285339317 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k6.c @@ -160,7 +160,6 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy) } /* cpuinfo and default policy values */ - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->cur = busfreq * max_multiplier; diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c index ca3e1d341889..7decd6a50ffa 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c @@ -637,8 +637,6 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy) printk (KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n", minimum_speed/1000, maximum_speed/1000); - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - policy->cpuinfo.transition_latency = cpufreq_scale(2000000UL, fsb, latency); policy->cur = powernow_get(0); diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 372df6e67e89..f2a65a9609f1 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -1208,7 +1208,6 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) /* run on any CPU again */ set_cpus_allowed(current, oldmask); - pol->governor = CPUFREQ_DEFAULT_GOVERNOR; if (cpu_family == CPU_HW_PSTATE) pol->cpus = cpumask_of_cpu(pol->cpu); else diff --git a/arch/i386/kernel/cpu/cpufreq/sc520_freq.c b/arch/i386/kernel/cpu/cpufreq/sc520_freq.c index b8fb4b521c62..d9f3e90a7ae0 100644 --- a/arch/i386/kernel/cpu/cpufreq/sc520_freq.c +++ b/arch/i386/kernel/cpu/cpufreq/sc520_freq.c @@ -111,7 +111,6 @@ static int sc520_freq_cpu_init(struct cpufreq_policy *policy) return -ENODEV; /* cpuinfo and default policy values */ - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = 1000000; /* 1ms */ policy->cur = sc520_freq_get_cpu_frequency(0); diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index 6c5dc2c85aeb..811d47438546 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c @@ -393,7 +393,6 @@ static int centrino_cpu_init(struct cpufreq_policy *policy) freq = get_cur_freq(policy->cpu); - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = 10000; /* 10uS transition latency */ policy->cur = freq; diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c index a5b2346faf1f..36685e8f7be1 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c @@ -348,7 +348,6 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) (speed / 1000)); /* cpuinfo and default policy values */ - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cur = speed; result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs); diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c index e1c509aa3054..f2b5a621d27b 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c @@ -290,7 +290,6 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) (speed / 1000)); /* cpuinfo and default policy values */ - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->cur = speed; diff --git a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c index 8c6ec7070844..b8498ea62068 100644 --- a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c +++ b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c @@ -321,8 +321,6 @@ acpi_cpufreq_cpu_init ( data->acpi_data.states[i].transition_latency * 1000; } } - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - policy->cur = processor_get_freq(data, policy->cpu); /* table init */ diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq.c b/arch/powerpc/platforms/cell/cbe_cpufreq.c index 0b6e8ee85ab1..c50ad22bf73e 100644 --- a/arch/powerpc/platforms/cell/cbe_cpufreq.c +++ b/arch/powerpc/platforms/cell/cbe_cpufreq.c @@ -107,8 +107,6 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy) pr_debug("%d: %d\n", i, cbe_freqs[i].frequency); } - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - /* if DEBUG is enabled set_pmode() measures the latency * of a transition */ policy->cpuinfo.transition_latency = 25000; diff --git a/arch/powerpc/platforms/pasemi/cpufreq.c b/arch/powerpc/platforms/pasemi/cpufreq.c index 3ae083851b01..1cfb8b0c8fec 100644 --- a/arch/powerpc/platforms/pasemi/cpufreq.c +++ b/arch/powerpc/platforms/pasemi/cpufreq.c @@ -195,8 +195,6 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy) pr_debug("%d: %d\n", i, pas_freqs[i].frequency); } - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - policy->cpuinfo.transition_latency = get_gizmo_latency(); cur_astate = get_cur_astate(policy->cpu); diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c index 1fe35dab0e9e..c04abcc28a7a 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_32.c +++ b/arch/powerpc/platforms/powermac/cpufreq_32.c @@ -410,7 +410,6 @@ static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy) if (policy->cpu != 0) return -ENODEV; - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->cur = cur_freq; diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c index 00f50298c342..4dfb4bc242b5 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_64.c +++ b/arch/powerpc/platforms/powermac/cpufreq_64.c @@ -357,7 +357,6 @@ static unsigned int g5_cpufreq_get_speed(unsigned int cpu) static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy) { - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->cur = g5_cpu_freqs[g5_query_freq()].frequency; /* secondary CPUs are tied to the primary one by the diff --git a/arch/sh/kernel/cpufreq.c b/arch/sh/kernel/cpufreq.c index e61890217c50..71d1c427b907 100644 --- a/arch/sh/kernel/cpufreq.c +++ b/arch/sh/kernel/cpufreq.c @@ -93,7 +93,6 @@ static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy) policy->cpuinfo.max_freq = (clk_round_rate(cpuclk, ~0UL) + 500) / 1000; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cur = sh_cpufreq_get(policy->cpu); policy->min = policy->cpuinfo.min_freq; policy->max = policy->cpuinfo.max_freq; diff --git a/arch/sparc64/kernel/us2e_cpufreq.c b/arch/sparc64/kernel/us2e_cpufreq.c index 1f83fe6a82d6..791c15138f3a 100644 --- a/arch/sparc64/kernel/us2e_cpufreq.c +++ b/arch/sparc64/kernel/us2e_cpufreq.c @@ -326,7 +326,6 @@ static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy) table[2].index = 5; table[3].frequency = CPUFREQ_TABLE_END; - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = 0; policy->cur = clock_tick; diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 2f6a73c01b71..9528bd577365 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -763,6 +763,8 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) init_completion(&policy->kobj_unregister); INIT_WORK(&policy->update, handle_update); + /* Set governor before ->init, so that driver could check it */ + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; /* call driver. From then on the cpufreq must be able * to accept all calls to ->verify and ->setpolicy for this CPU */ From 1c2562459faedc35927546cfa5273ec6c2884cce Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Tue, 2 Oct 2007 13:28:12 -0700 Subject: [PATCH 04/10] [CPUFREQ] allow ondemand and conservative cpufreq governors to be used as default Depending on the transition latency of the HW for cpufreq switches, the ondemand or conservative governor cannot be used with certain cpufreq drivers. Still the ondemand should be the default governor on a wide range of systems. This patch allows this and lets the governor fallback to the performance governor at cpufreq driver load time, if the driver does not support fast enough frequency switching. Main benefit is that on e.g. installation or other systems without userspace support a working dynamic cpufreq support can be achieved on most systems by simply loading the cpufreq driver. This is especially essential for recent x86(_64) laptop hardware which may rely on working dynamic cpufreq OS support. Signed-off-by: Thomas Renninger Signed-off-by: Venkatesh Pallipadi Cc: Russell King Cc: Bryan Wu Cc: Andi Kleen Cc: "Luck, Tony" Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Cc: Paul Mundt Cc: "David S. Miller" Signed-off-by: Andrew Morton Signed-off-by: Dave Jones --- drivers/cpufreq/Kconfig | 27 ++++++++++++++++++++++---- drivers/cpufreq/cpufreq.c | 12 ++++++++++++ drivers/cpufreq/cpufreq_conservative.c | 19 +++++++++--------- drivers/cpufreq/cpufreq_ondemand.c | 22 +++++++++------------ include/linux/cpufreq.h | 20 ++++++++++++++++--- 5 files changed, 70 insertions(+), 30 deletions(-) diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 993fa7b89253..721f86f4f008 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -56,10 +56,6 @@ config CPU_FREQ_STAT_DETAILS If in doubt, say N. -# Note that it is not currently possible to set the other governors (such as ondemand) -# as the default, since if they fail to initialise, cpufreq will be -# left in an undefined state. - choice prompt "Default CPUFreq governor" default CPU_FREQ_DEFAULT_GOV_USERSPACE if CPU_FREQ_SA1100 || CPU_FREQ_SA1110 @@ -85,6 +81,29 @@ config CPU_FREQ_DEFAULT_GOV_USERSPACE program shall be able to set the CPU dynamically without having to enable the userspace governor manually. +config CPU_FREQ_DEFAULT_GOV_ONDEMAND + bool "ondemand" + select CPU_FREQ_GOV_ONDEMAND + select CPU_FREQ_GOV_PERFORMANCE + help + Use the CPUFreq governor 'ondemand' as default. This allows + you to get a full dynamic frequency capable system by simply + loading your cpufreq low-level hardware driver. + Be aware that not all cpufreq drivers support the ondemand + governor. If unsure have a look at the help section of the + driver. Fallback governor will be the performance governor. + +config CPU_FREQ_DEFAULT_GOV_CONSERVATIVE + bool "conservative" + select CPU_FREQ_GOV_CONSERVATIVE + select CPU_FREQ_GOV_PERFORMANCE + help + Use the CPUFreq governor 'conservative' as default. This allows + you to get a full dynamic frequency capable system by simply + loading your cpufreq low-level hardware driver. + Be aware that not all cpufreq drivers support the conservative + governor. If unsure have a look at the help section of the + driver. Fallback governor will be the performance governor. endchoice config CPU_FREQ_GOV_PERFORMANCE diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 9528bd577365..418522f88f73 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1484,6 +1484,18 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) { int ret; + struct cpufreq_governor *gov = CPUFREQ_PERFORMANCE_GOVERNOR; + + if (policy->governor->max_transition_latency && + policy->cpuinfo.transition_latency > + policy->governor->max_transition_latency) { + printk(KERN_WARNING "%s governor failed, too long" + " transition latency of HW, fallback" + " to %s governor\n", + policy->governor->name, + gov->name); + policy->governor = gov; + } if (!try_module_get(policy->governor->owner)) return -EINVAL; diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 26f440ccc3fb..4bd33ce8a6f3 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -58,7 +58,7 @@ static unsigned int def_sampling_rate; #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) #define DEF_SAMPLING_DOWN_FACTOR (1) #define MAX_SAMPLING_DOWN_FACTOR (10) -#define TRANSITION_LATENCY_LIMIT (10 * 1000) +#define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000) static void do_dbs_timer(struct work_struct *work); @@ -466,9 +466,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, (!policy->cur)) return -EINVAL; - if (policy->cpuinfo.transition_latency > - (TRANSITION_LATENCY_LIMIT * 1000)) - return -EINVAL; if (this_dbs_info->enable) /* Already enabled */ break; @@ -551,15 +548,17 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, return 0; } -static struct cpufreq_governor cpufreq_gov_dbs = { - .name = "conservative", - .governor = cpufreq_governor_dbs, - .owner = THIS_MODULE, +struct cpufreq_governor cpufreq_gov_conservative = { + .name = "conservative", + .governor = cpufreq_governor_dbs, + .max_transition_latency = TRANSITION_LATENCY_LIMIT, + .owner = THIS_MODULE, }; +EXPORT_SYMBOL(cpufreq_gov_conservative); static int __init cpufreq_gov_dbs_init(void) { - return cpufreq_register_governor(&cpufreq_gov_dbs); + return cpufreq_register_governor(&cpufreq_gov_conservative); } static void __exit cpufreq_gov_dbs_exit(void) @@ -567,7 +566,7 @@ static void __exit cpufreq_gov_dbs_exit(void) /* Make sure that the scheduled work is indeed not running */ flush_scheduled_work(); - cpufreq_unregister_governor(&cpufreq_gov_dbs); + cpufreq_unregister_governor(&cpufreq_gov_conservative); } diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index e794527e4925..369f44595150 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -47,7 +47,7 @@ static unsigned int def_sampling_rate; (def_sampling_rate / MIN_SAMPLING_RATE_RATIO) #define MAX_SAMPLING_RATE (500 * def_sampling_rate) #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) -#define TRANSITION_LATENCY_LIMIT (10 * 1000) +#define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000) static void do_dbs_timer(struct work_struct *work); @@ -508,12 +508,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, if ((!cpu_online(cpu)) || (!policy->cur)) return -EINVAL; - if (policy->cpuinfo.transition_latency > - (TRANSITION_LATENCY_LIMIT * 1000)) { - printk(KERN_WARNING "ondemand governor failed to load " - "due to too long transition latency\n"); - return -EINVAL; - } if (this_dbs_info->enable) /* Already enabled */ break; @@ -585,11 +579,13 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, return 0; } -static struct cpufreq_governor cpufreq_gov_dbs = { - .name = "ondemand", - .governor = cpufreq_governor_dbs, - .owner = THIS_MODULE, +struct cpufreq_governor cpufreq_gov_ondemand = { + .name = "ondemand", + .governor = cpufreq_governor_dbs, + .max_transition_latency = TRANSITION_LATENCY_LIMIT, + .owner = THIS_MODULE, }; +EXPORT_SYMBOL(cpufreq_gov_ondemand); static int __init cpufreq_gov_dbs_init(void) { @@ -598,12 +594,12 @@ static int __init cpufreq_gov_dbs_init(void) printk(KERN_ERR "Creation of kondemand failed\n"); return -EFAULT; } - return cpufreq_register_governor(&cpufreq_gov_dbs); + return cpufreq_register_governor(&cpufreq_gov_ondemand); } static void __exit cpufreq_gov_dbs_exit(void) { - cpufreq_unregister_governor(&cpufreq_gov_dbs); + cpufreq_unregister_governor(&cpufreq_gov_ondemand); destroy_workqueue(kondemand_wq); } diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 3ec6e7ff5fbd..9e5f5d0c87f3 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -155,6 +155,9 @@ struct cpufreq_governor { char name[CPUFREQ_NAME_LEN]; int (*governor) (struct cpufreq_policy *policy, unsigned int event); + unsigned int max_transition_latency; /* HW must be able to switch to + next freq faster than this value in nano secs or we + will fallback to performance governor */ struct list_head governor_list; struct module *owner; }; @@ -279,12 +282,23 @@ static inline unsigned int cpufreq_quick_get(unsigned int cpu) *********************************************************************/ -#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE +/* + Performance governor is fallback governor if any other gov failed to + auto load due latency restrictions +*/ extern struct cpufreq_governor cpufreq_gov_performance; -#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_performance +#define CPUFREQ_PERFORMANCE_GOVERNOR (&cpufreq_gov_performance) +#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE +#define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_performance) #elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE) extern struct cpufreq_governor cpufreq_gov_userspace; -#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_userspace +#define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_userspace) +#elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND) +extern struct cpufreq_governor cpufreq_gov_ondemand; +#define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_ondemand) +#elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE) +extern struct cpufreq_governor cpufreq_gov_conservative; +#define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_conservative) #endif From 6afde10c3f58cc3ac593f5b4505b8b1cf719f5d6 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Tue, 2 Oct 2007 13:28:13 -0700 Subject: [PATCH 05/10] [CPUFREQ] Only check for transition latency on problematic governors (kconfig fix) Cc: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq.c | 27 ++++++++++++++++++++------- include/linux/cpufreq.h | 3 ++- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 418522f88f73..65ac58511228 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1484,17 +1484,30 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) { int ret; - struct cpufreq_governor *gov = CPUFREQ_PERFORMANCE_GOVERNOR; + + /* Only must be defined when default governor is known to have latency + restrictions, like e.g. conservative or ondemand. + That this is the case is already ensured in Kconfig + */ +#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE + struct cpufreq_governor *gov = &cpufreq_gov_performance; +#else + struct cpufreq_governor *gov = NULL; +#endif if (policy->governor->max_transition_latency && policy->cpuinfo.transition_latency > policy->governor->max_transition_latency) { - printk(KERN_WARNING "%s governor failed, too long" - " transition latency of HW, fallback" - " to %s governor\n", - policy->governor->name, - gov->name); - policy->governor = gov; + if (!gov) + return -EINVAL; + else { + printk(KERN_WARNING "%s governor failed, too long" + " transition latency of HW, fallback" + " to %s governor\n", + policy->governor->name, + gov->name); + policy->governor = gov; + } } if (!try_module_get(policy->governor->owner)) diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 9e5f5d0c87f3..450a841b5892 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -286,8 +286,9 @@ static inline unsigned int cpufreq_quick_get(unsigned int cpu) Performance governor is fallback governor if any other gov failed to auto load due latency restrictions */ +#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE extern struct cpufreq_governor cpufreq_gov_performance; -#define CPUFREQ_PERFORMANCE_GOVERNOR (&cpufreq_gov_performance) +#endif #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE #define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_performance) #elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE) From dd184a01b8ece6bac2f7a63de99a4a4d29552746 Mon Sep 17 00:00:00 2001 From: Satyam Sharma Date: Tue, 2 Oct 2007 13:28:14 -0700 Subject: [PATCH 06/10] [CPUFREQ] mark hotplug notifier callback as __cpuinit The notifier_block is already __cpuinitdata, thereby allowing us to safely mark the callback function as __cpuinit also, thereby saving space when HOTPLUG_CPU=n. Signed-off-by: Satyam Sharma Signed-off-by: Andrew Morton Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 65ac58511228..e027052a6604 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1730,7 +1730,7 @@ int cpufreq_update_policy(unsigned int cpu) } EXPORT_SYMBOL(cpufreq_update_policy); -static int cpufreq_cpu_callback(struct notifier_block *nfb, +static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; From 6070b5de50ab5e3f810628a9cbb04deecf30a85f Mon Sep 17 00:00:00 2001 From: Satyam Sharma Date: Tue, 2 Oct 2007 13:28:15 -0700 Subject: [PATCH 07/10] [CPUFREQ] implement !CONFIG_CPU_FREQ stub for cpufreq_unregister_notifier() Callsites such as arch/powerpc/oprofile/op_model_cell.c are having to open-code #ifdef CONFIG_CPU_FREQ only to be able to get at the full definition of cpufreq_unregister_notifier(), because no empty stub is available for the !CONFIG_CPU_FREQ case. Let's provide one, to be able to remove such #ifdef's from the rest of the kernel tree -- those will come in a subsequent patch. Signed-off-by: Satyam Sharma Signed-off-by: Andrew Morton Signed-off-by: Dave Jones --- include/linux/cpufreq.h | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 450a841b5892..23932d7741a9 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -32,12 +32,24 @@ * CPUFREQ NOTIFIER INTERFACE * *********************************************************************/ -int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list); -int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list); - #define CPUFREQ_TRANSITION_NOTIFIER (0) #define CPUFREQ_POLICY_NOTIFIER (1) +#ifdef CONFIG_CPU_FREQ +int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list); +int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list); +#else /* CONFIG_CPU_FREQ */ +static inline int cpufreq_register_notifier(struct notifier_block *nb, + unsigned int list) +{ + return 0; +} +static inline int cpufreq_unregister_notifier(struct notifier_block *nb, + unsigned int list) +{ + return 0; +} +#endif /* CONFIG_CPU_FREQ */ /* if (cpufreq_driver->target) exists, the ->governor decides what frequency * within the limits is used. If (cpufreq_driver->setpolicy> exists, these From 55395ae72b6e5ae614d28df74158c47454652583 Mon Sep 17 00:00:00 2001 From: Satyam Sharma Date: Tue, 2 Oct 2007 13:28:15 -0700 Subject: [PATCH 08/10] [CPUFREQ] cpufreq_stats: misc cpuinit section annotations * Stop referencing the callback directly from the __init and __exit functions of this driver, and instead explicitly call cpufreq_update_policy() et al. This enables the callback function to be marked as __cpuinit (and the notifier_block __cpuinitdata), thereby saving space when HOTPLUG_CPU=n. This also enables us to use other tricks to replace __cpuinit{data} in future. * cpufreq_stats_free_table() is only called from __cpuinit or __exit marked functions, making it an ideal candidate for __cpuexit. * Fix missing space in the module description Signed-off-by: Satyam Sharma Signed-off-by: Andrew Morton Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq_stats.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 917b9bab9ccb..8a45d0f93e26 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -164,8 +164,7 @@ freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq) return -1; } -static void -cpufreq_stats_free_table (unsigned int cpu) +static void __cpuexit cpufreq_stats_free_table(unsigned int cpu) { struct cpufreq_stats *stat = cpufreq_stats_table[cpu]; struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); @@ -305,8 +304,9 @@ cpufreq_stat_notifier_trans (struct notifier_block *nb, unsigned long val, return 0; } -static int cpufreq_stat_cpu_callback(struct notifier_block *nfb, - unsigned long action, void *hcpu) +static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb, + unsigned long action, + void *hcpu) { unsigned int cpu = (unsigned long)hcpu; @@ -323,7 +323,7 @@ static int cpufreq_stat_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block cpufreq_stat_cpu_notifier = +static struct notifier_block cpufreq_stat_cpu_notifier __cpuinitdata = { .notifier_call = cpufreq_stat_cpu_callback, }; @@ -356,8 +356,7 @@ __init cpufreq_stats_init(void) register_hotcpu_notifier(&cpufreq_stat_cpu_notifier); for_each_online_cpu(cpu) { - cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, - CPU_ONLINE, (void *)(long)cpu); + cpufreq_update_policy(cpu); } return 0; } @@ -372,13 +371,12 @@ __exit cpufreq_stats_exit(void) CPUFREQ_TRANSITION_NOTIFIER); unregister_hotcpu_notifier(&cpufreq_stat_cpu_notifier); for_each_online_cpu(cpu) { - cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, - CPU_DEAD, (void *)(long)cpu); + cpufreq_stats_free_table(cpu); } } MODULE_AUTHOR ("Zou Nan hai "); -MODULE_DESCRIPTION ("'cpufreq_stats' - A driver to export cpufreq stats" +MODULE_DESCRIPTION ("'cpufreq_stats' - A driver to export cpufreq stats " "through sysfs filesystem"); MODULE_LICENSE ("GPL"); From 562d94d98f7032bdc4a99d9124a78a543dbea225 Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Fri, 3 Aug 2007 14:09:05 -0500 Subject: [PATCH 09/10] [CPUFREQ] Support different families in fid/did to frequency conversion The equation to find the frequency given the fid and did is family dependant. Acked-by: Mark Langsdorf Signed-off-by: Joachim Deguara Signed-off-by: Dave Jones --- arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index f2a65a9609f1..b273b69cfddf 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -76,7 +76,10 @@ static u32 find_khz_freq_from_fid(u32 fid) /* Return a frequency in MHz, given an input fid and did */ static u32 find_freq_from_fiddid(u32 fid, u32 did) { - return 100 * (fid + 0x10) >> did; + if (current_cpu_data.x86 == 0x10) + return 100 * (fid + 0x10) >> did; + else + return 100 * (fid + 0x8) >> did; } static u32 find_khz_freq_from_fiddid(u32 fid, u32 did) From 9eb59573d4b86f347e6cd04f47a4c2082009fa58 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 10 Oct 2007 02:18:27 +0200 Subject: [PATCH 10/10] [CPUFREQ] Don't take semaphore in cpufreq_quick_get() I don't see any reason to take an expensive lock in cpufreq_quick_get() Reading policy->cur is a single atomic operation and after the lock is dropped again the state could change any time anyways. So don't take the lock in the first place. This also makes this function interrupt safe which is useful for some code of mine. Signed-off-by: Andi Kleen Cc: "Pallipadi, Venkatesh" Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index e027052a6604..f7b9d6fce123 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1111,12 +1111,7 @@ unsigned int cpufreq_quick_get(unsigned int cpu) unsigned int ret_freq = 0; if (policy) { - if (unlikely(lock_policy_rwsem_read(cpu))) - return ret_freq; - ret_freq = policy->cur; - - unlock_policy_rwsem_read(cpu); cpufreq_cpu_put(policy); }