Merge branch 'pm-cpufreq'
* pm-cpufreq: cpufreq: Fix sysfs deadlock with concurrent hotplug/frequency switch EXYNOS: bugfix on retrieving old_index from freqs.old
This commit is contained in:
commit
75a4161a58
2 changed files with 39 additions and 10 deletions
|
@ -138,7 +138,7 @@ void disable_cpufreq(void)
|
|||
static LIST_HEAD(cpufreq_governor_list);
|
||||
static DEFINE_MUTEX(cpufreq_governor_mutex);
|
||||
|
||||
struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
|
||||
static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs)
|
||||
{
|
||||
struct cpufreq_policy *data;
|
||||
unsigned long flags;
|
||||
|
@ -162,7 +162,7 @@ struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
|
|||
if (!data)
|
||||
goto err_out_put_module;
|
||||
|
||||
if (!kobject_get(&data->kobj))
|
||||
if (!sysfs && !kobject_get(&data->kobj))
|
||||
goto err_out_put_module;
|
||||
|
||||
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
|
||||
|
@ -175,16 +175,35 @@ struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
|
|||
err_out:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
|
||||
{
|
||||
return __cpufreq_cpu_get(cpu, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
|
||||
|
||||
static struct cpufreq_policy *cpufreq_cpu_get_sysfs(unsigned int cpu)
|
||||
{
|
||||
return __cpufreq_cpu_get(cpu, true);
|
||||
}
|
||||
|
||||
static void __cpufreq_cpu_put(struct cpufreq_policy *data, bool sysfs)
|
||||
{
|
||||
if (!sysfs)
|
||||
kobject_put(&data->kobj);
|
||||
module_put(cpufreq_driver->owner);
|
||||
}
|
||||
|
||||
void cpufreq_cpu_put(struct cpufreq_policy *data)
|
||||
{
|
||||
kobject_put(&data->kobj);
|
||||
module_put(cpufreq_driver->owner);
|
||||
__cpufreq_cpu_put(data, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
|
||||
|
||||
static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *data)
|
||||
{
|
||||
__cpufreq_cpu_put(data, true);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* EXTERNALLY AFFECTING FREQUENCY CHANGES *
|
||||
|
@ -617,7 +636,7 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
|
|||
struct cpufreq_policy *policy = to_policy(kobj);
|
||||
struct freq_attr *fattr = to_attr(attr);
|
||||
ssize_t ret = -EINVAL;
|
||||
policy = cpufreq_cpu_get(policy->cpu);
|
||||
policy = cpufreq_cpu_get_sysfs(policy->cpu);
|
||||
if (!policy)
|
||||
goto no_policy;
|
||||
|
||||
|
@ -631,7 +650,7 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
|
|||
|
||||
unlock_policy_rwsem_read(policy->cpu);
|
||||
fail:
|
||||
cpufreq_cpu_put(policy);
|
||||
cpufreq_cpu_put_sysfs(policy);
|
||||
no_policy:
|
||||
return ret;
|
||||
}
|
||||
|
@ -642,7 +661,7 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr,
|
|||
struct cpufreq_policy *policy = to_policy(kobj);
|
||||
struct freq_attr *fattr = to_attr(attr);
|
||||
ssize_t ret = -EINVAL;
|
||||
policy = cpufreq_cpu_get(policy->cpu);
|
||||
policy = cpufreq_cpu_get_sysfs(policy->cpu);
|
||||
if (!policy)
|
||||
goto no_policy;
|
||||
|
||||
|
@ -656,7 +675,7 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr,
|
|||
|
||||
unlock_policy_rwsem_write(policy->cpu);
|
||||
fail:
|
||||
cpufreq_cpu_put(policy);
|
||||
cpufreq_cpu_put_sysfs(policy);
|
||||
no_policy:
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -62,8 +62,18 @@ static int exynos_target(struct cpufreq_policy *policy,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (cpufreq_frequency_table_target(policy, freq_table,
|
||||
freqs.old, relation, &old_index)) {
|
||||
/*
|
||||
* The policy max have been changed so that we cannot get proper
|
||||
* old_index with cpufreq_frequency_table_target(). Thus, ignore
|
||||
* policy and get the index from the raw freqeuncy table.
|
||||
*/
|
||||
for (old_index = 0;
|
||||
freq_table[old_index].frequency != CPUFREQ_TABLE_END;
|
||||
old_index++)
|
||||
if (freq_table[old_index].frequency == freqs.old)
|
||||
break;
|
||||
|
||||
if (freq_table[old_index].frequency == CPUFREQ_TABLE_END) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue