diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-11-18 18:49:49 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-11-18 18:49:49 -0800 |
commit | 66b00a7c93ec782d118d2c03bd599cfd041e80a1 (patch) | |
tree | 5aefcbf687c496de317693934111010635a82d20 /drivers | |
parent | a414f01ac2899f273ef8fe98fa44158ac12793f2 (diff) | |
parent | 90e41bac100e34f955f48e7686c2fc685ac9aa30 (diff) |
Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq
* 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq:
[CPUFREQ] Fix stale cpufreq_cpu_governor pointer
[CPUFREQ] Resolve time unit thinko in ondemand/conservative govs
[CPUFREQ] speedstep-ich: fix error caused by 394122ab144dae4b276d74644a2f11c44a60ac5c
[CPUFREQ] Fix use after free on governor restore
[CPUFREQ] acpi-cpufreq: blacklist Intel 0f68: Fix HT detection and put in notification message
[CPUFREQ] powernow-k8: Fix test in get_transition_latency()
[CPUFREQ] longhaul: select Longhaul version 2 for capable CPUs
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 48 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq_conservative.c | 4 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq_ondemand.c | 4 |
3 files changed, 44 insertions, 12 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 3938c781709..ff57c40e9b8 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -41,7 +41,7 @@ static struct cpufreq_driver *cpufreq_driver; static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); #ifdef CONFIG_HOTPLUG_CPU /* This one keeps track of the previously set governor of a removed CPU */ -static DEFINE_PER_CPU(struct cpufreq_governor *, cpufreq_cpu_governor); +static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); #endif static DEFINE_SPINLOCK(cpufreq_driver_lock); @@ -774,10 +774,12 @@ int cpufreq_add_dev_policy(unsigned int cpu, struct cpufreq_policy *policy, #ifdef CONFIG_SMP unsigned long flags; unsigned int j; - #ifdef CONFIG_HOTPLUG_CPU - if (per_cpu(cpufreq_cpu_governor, cpu)) { - policy->governor = per_cpu(cpufreq_cpu_governor, cpu); + struct cpufreq_governor *gov; + + gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu)); + if (gov) { + policy->governor = gov; dprintk("Restoring governor %s for cpu %d\n", policy->governor->name, cpu); } @@ -949,10 +951,13 @@ err_out_kobj_put: static int cpufreq_add_dev(struct sys_device *sys_dev) { unsigned int cpu = sys_dev->id; - int ret = 0; + int ret = 0, found = 0; struct cpufreq_policy *policy; unsigned long flags; unsigned int j; +#ifdef CONFIG_HOTPLUG_CPU + int sibling; +#endif if (cpu_is_offline(cpu)) return 0; @@ -999,7 +1004,19 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) INIT_WORK(&policy->update, handle_update); /* Set governor before ->init, so that driver could check it */ - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; +#ifdef CONFIG_HOTPLUG_CPU + for_each_online_cpu(sibling) { + struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling); + if (cp && cp->governor && + (cpumask_test_cpu(cpu, cp->related_cpus))) { + policy->governor = cp->governor; + found = 1; + break; + } + } +#endif + if (!found) + 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 */ @@ -1111,7 +1128,8 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) #ifdef CONFIG_SMP #ifdef CONFIG_HOTPLUG_CPU - per_cpu(cpufreq_cpu_governor, cpu) = data->governor; + strncpy(per_cpu(cpufreq_cpu_governor, cpu), data->governor->name, + CPUFREQ_NAME_LEN); #endif /* if we have other CPUs still registered, we need to unlink them, @@ -1135,7 +1153,8 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) continue; dprintk("removing link for cpu %u\n", j); #ifdef CONFIG_HOTPLUG_CPU - per_cpu(cpufreq_cpu_governor, j) = data->governor; + strncpy(per_cpu(cpufreq_cpu_governor, j), + data->governor->name, CPUFREQ_NAME_LEN); #endif cpu_sys_dev = get_cpu_sysdev(j); sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq"); @@ -1606,9 +1625,22 @@ EXPORT_SYMBOL_GPL(cpufreq_register_governor); void cpufreq_unregister_governor(struct cpufreq_governor *governor) { +#ifdef CONFIG_HOTPLUG_CPU + int cpu; +#endif + if (!governor) return; +#ifdef CONFIG_HOTPLUG_CPU + for_each_present_cpu(cpu) { + if (cpu_online(cpu)) + continue; + if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name)) + strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0"); + } +#endif + mutex_lock(&cpufreq_governor_mutex); list_del(&governor->governor_list); mutex_unlock(&cpufreq_governor_mutex); diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index bc33ddc9c97..c7b081b839f 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -116,9 +116,9 @@ static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu, idle_time = cputime64_sub(cur_wall_time, busy_time); if (wall) - *wall = cur_wall_time; + *wall = (cputime64_t)jiffies_to_usecs(cur_wall_time); - return idle_time; + return (cputime64_t)jiffies_to_usecs(idle_time);; } static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 071699de50e..4b34ade2332 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -133,9 +133,9 @@ static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu, idle_time = cputime64_sub(cur_wall_time, busy_time); if (wall) - *wall = cur_wall_time; + *wall = (cputime64_t)jiffies_to_usecs(cur_wall_time); - return idle_time; + return (cputime64_t)jiffies_to_usecs(idle_time); } static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) |