Merge branches 'pm-cpufreq-fixes' and 'pm-cpuidle-fixes'
* pm-cpufreq-fixes: cpufreq: Fix creation of symbolic links to policy directories * pm-cpuidle-fixes: cpuidle: powernv: Pass correct drv->cpumask for registration
This commit is contained in:
Коммит
46e1d5e972
|
@ -918,11 +918,19 @@ static struct kobj_type ktype_cpufreq = {
|
||||||
.release = cpufreq_sysfs_release,
|
.release = cpufreq_sysfs_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int add_cpu_dev_symlink(struct cpufreq_policy *policy,
|
static void add_cpu_dev_symlink(struct cpufreq_policy *policy, unsigned int cpu)
|
||||||
struct device *dev)
|
|
||||||
{
|
{
|
||||||
|
struct device *dev = get_cpu_device(cpu);
|
||||||
|
|
||||||
|
if (!dev)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (cpumask_test_and_set_cpu(cpu, policy->real_cpus))
|
||||||
|
return;
|
||||||
|
|
||||||
dev_dbg(dev, "%s: Adding symlink\n", __func__);
|
dev_dbg(dev, "%s: Adding symlink\n", __func__);
|
||||||
return sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
|
if (sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq"))
|
||||||
|
dev_err(dev, "cpufreq symlink creation failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void remove_cpu_dev_symlink(struct cpufreq_policy *policy,
|
static void remove_cpu_dev_symlink(struct cpufreq_policy *policy,
|
||||||
|
@ -1180,10 +1188,10 @@ static int cpufreq_online(unsigned int cpu)
|
||||||
policy->user_policy.min = policy->min;
|
policy->user_policy.min = policy->min;
|
||||||
policy->user_policy.max = policy->max;
|
policy->user_policy.max = policy->max;
|
||||||
|
|
||||||
write_lock_irqsave(&cpufreq_driver_lock, flags);
|
for_each_cpu(j, policy->related_cpus) {
|
||||||
for_each_cpu(j, policy->related_cpus)
|
|
||||||
per_cpu(cpufreq_cpu_data, j) = policy;
|
per_cpu(cpufreq_cpu_data, j) = policy;
|
||||||
write_unlock_irqrestore(&cpufreq_driver_lock, flags);
|
add_cpu_dev_symlink(policy, j);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
policy->min = policy->user_policy.min;
|
policy->min = policy->user_policy.min;
|
||||||
policy->max = policy->user_policy.max;
|
policy->max = policy->user_policy.max;
|
||||||
|
@ -1275,13 +1283,15 @@ out_exit_policy:
|
||||||
|
|
||||||
if (cpufreq_driver->exit)
|
if (cpufreq_driver->exit)
|
||||||
cpufreq_driver->exit(policy);
|
cpufreq_driver->exit(policy);
|
||||||
|
|
||||||
|
for_each_cpu(j, policy->real_cpus)
|
||||||
|
remove_cpu_dev_symlink(policy, get_cpu_device(j));
|
||||||
|
|
||||||
out_free_policy:
|
out_free_policy:
|
||||||
cpufreq_policy_free(policy);
|
cpufreq_policy_free(policy);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cpufreq_offline(unsigned int cpu);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cpufreq_add_dev - the cpufreq interface for a CPU device.
|
* cpufreq_add_dev - the cpufreq interface for a CPU device.
|
||||||
* @dev: CPU device.
|
* @dev: CPU device.
|
||||||
|
@ -1303,16 +1313,10 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
|
||||||
|
|
||||||
/* Create sysfs link on CPU registration */
|
/* Create sysfs link on CPU registration */
|
||||||
policy = per_cpu(cpufreq_cpu_data, cpu);
|
policy = per_cpu(cpufreq_cpu_data, cpu);
|
||||||
if (!policy || cpumask_test_and_set_cpu(cpu, policy->real_cpus))
|
if (policy)
|
||||||
return 0;
|
add_cpu_dev_symlink(policy, cpu);
|
||||||
|
|
||||||
ret = add_cpu_dev_symlink(policy, dev);
|
return 0;
|
||||||
if (ret) {
|
|
||||||
cpumask_clear_cpu(cpu, policy->real_cpus);
|
|
||||||
cpufreq_offline(cpu);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cpufreq_offline(unsigned int cpu)
|
static int cpufreq_offline(unsigned int cpu)
|
||||||
|
|
|
@ -175,6 +175,24 @@ static int powernv_cpuidle_driver_init(void)
|
||||||
drv->state_count += 1;
|
drv->state_count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On the PowerNV platform cpu_present may be less than cpu_possible in
|
||||||
|
* cases when firmware detects the CPU, but it is not available to the
|
||||||
|
* OS. If CONFIG_HOTPLUG_CPU=n, then such CPUs are not hotplugable at
|
||||||
|
* run time and hence cpu_devices are not created for those CPUs by the
|
||||||
|
* generic topology_init().
|
||||||
|
*
|
||||||
|
* drv->cpumask defaults to cpu_possible_mask in
|
||||||
|
* __cpuidle_driver_init(). This breaks cpuidle on PowerNV where
|
||||||
|
* cpu_devices are not created for CPUs in cpu_possible_mask that
|
||||||
|
* cannot be hot-added later at run time.
|
||||||
|
*
|
||||||
|
* Trying cpuidle_register_device() on a CPU without a cpu_device is
|
||||||
|
* incorrect, so pass a correct CPU mask to the generic cpuidle driver.
|
||||||
|
*/
|
||||||
|
|
||||||
|
drv->cpumask = (struct cpumask *)cpu_present_mask;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче