Loading drivers/cpufreq/cpufreq.c +21 −17 Original line number Diff line number Diff line Loading @@ -918,11 +918,19 @@ static struct kobj_type ktype_cpufreq = { .release = cpufreq_sysfs_release, }; static int add_cpu_dev_symlink(struct cpufreq_policy *policy, struct device *dev) static void add_cpu_dev_symlink(struct cpufreq_policy *policy, unsigned int cpu) { 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__); 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, Loading Loading @@ -1180,10 +1188,10 @@ static int cpufreq_online(unsigned int cpu) policy->user_policy.min = policy->min; 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; write_unlock_irqrestore(&cpufreq_driver_lock, flags); add_cpu_dev_symlink(policy, j); } } else { policy->min = policy->user_policy.min; policy->max = policy->user_policy.max; Loading Loading @@ -1275,13 +1283,15 @@ static int cpufreq_online(unsigned int cpu) if (cpufreq_driver->exit) cpufreq_driver->exit(policy); for_each_cpu(j, policy->real_cpus) remove_cpu_dev_symlink(policy, get_cpu_device(j)); out_free_policy: cpufreq_policy_free(policy); return ret; } static int cpufreq_offline(unsigned int cpu); /** * cpufreq_add_dev - the cpufreq interface for a CPU device. * @dev: CPU device. Loading @@ -1303,16 +1313,10 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) /* Create sysfs link on CPU registration */ policy = per_cpu(cpufreq_cpu_data, cpu); if (!policy || cpumask_test_and_set_cpu(cpu, policy->real_cpus)) return 0; ret = add_cpu_dev_symlink(policy, dev); if (ret) { cpumask_clear_cpu(cpu, policy->real_cpus); cpufreq_offline(cpu); } if (policy) add_cpu_dev_symlink(policy, cpu); return ret; return 0; } static int cpufreq_offline(unsigned int cpu) Loading drivers/cpuidle/cpuidle-powernv.c +18 −0 Original line number Diff line number Diff line Loading @@ -175,6 +175,24 @@ static int powernv_cpuidle_driver_init(void) 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; } Loading Loading
drivers/cpufreq/cpufreq.c +21 −17 Original line number Diff line number Diff line Loading @@ -918,11 +918,19 @@ static struct kobj_type ktype_cpufreq = { .release = cpufreq_sysfs_release, }; static int add_cpu_dev_symlink(struct cpufreq_policy *policy, struct device *dev) static void add_cpu_dev_symlink(struct cpufreq_policy *policy, unsigned int cpu) { 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__); 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, Loading Loading @@ -1180,10 +1188,10 @@ static int cpufreq_online(unsigned int cpu) policy->user_policy.min = policy->min; 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; write_unlock_irqrestore(&cpufreq_driver_lock, flags); add_cpu_dev_symlink(policy, j); } } else { policy->min = policy->user_policy.min; policy->max = policy->user_policy.max; Loading Loading @@ -1275,13 +1283,15 @@ static int cpufreq_online(unsigned int cpu) if (cpufreq_driver->exit) cpufreq_driver->exit(policy); for_each_cpu(j, policy->real_cpus) remove_cpu_dev_symlink(policy, get_cpu_device(j)); out_free_policy: cpufreq_policy_free(policy); return ret; } static int cpufreq_offline(unsigned int cpu); /** * cpufreq_add_dev - the cpufreq interface for a CPU device. * @dev: CPU device. Loading @@ -1303,16 +1313,10 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) /* Create sysfs link on CPU registration */ policy = per_cpu(cpufreq_cpu_data, cpu); if (!policy || cpumask_test_and_set_cpu(cpu, policy->real_cpus)) return 0; ret = add_cpu_dev_symlink(policy, dev); if (ret) { cpumask_clear_cpu(cpu, policy->real_cpus); cpufreq_offline(cpu); } if (policy) add_cpu_dev_symlink(policy, cpu); return ret; return 0; } static int cpufreq_offline(unsigned int cpu) Loading
drivers/cpuidle/cpuidle-powernv.c +18 −0 Original line number Diff line number Diff line Loading @@ -175,6 +175,24 @@ static int powernv_cpuidle_driver_init(void) 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; } Loading