aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/cpufreq/cpufreq.c76
1 files changed, 49 insertions, 27 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 0611ae48e767..1d041aff4d48 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -903,7 +903,7 @@ static void cpufreq_init_policy(struct cpufreq_policy *policy)
903 903
904#ifdef CONFIG_HOTPLUG_CPU 904#ifdef CONFIG_HOTPLUG_CPU
905static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling, 905static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling,
906 struct device *dev) 906 struct device *dev, bool frozen)
907{ 907{
908 struct cpufreq_policy *policy; 908 struct cpufreq_policy *policy;
909 int ret = 0, has_target = !!cpufreq_driver->target; 909 int ret = 0, has_target = !!cpufreq_driver->target;
@@ -931,13 +931,18 @@ static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling,
931 __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); 931 __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
932 } 932 }
933 933
934 ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq"); 934 /* Don't touch sysfs links during light-weight init */
935 if (ret) { 935 if (frozen) {
936 /* Drop the extra refcount that we took above */
936 cpufreq_cpu_put(policy); 937 cpufreq_cpu_put(policy);
937 return ret; 938 return 0;
938 } 939 }
939 940
940 return 0; 941 ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
942 if (ret)
943 cpufreq_cpu_put(policy);
944
945 return ret;
941} 946}
942#endif 947#endif
943 948
@@ -972,16 +977,8 @@ static void cpufreq_policy_free(struct cpufreq_policy *policy)
972 kfree(policy); 977 kfree(policy);
973} 978}
974 979
975/** 980static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
976 * cpufreq_add_dev - add a CPU device 981 bool frozen)
977 *
978 * Adds the cpufreq interface for a CPU device.
979 *
980 * The Oracle says: try running cpufreq registration/unregistration concurrently
981 * with with cpu hotplugging and all hell will break loose. Tried to clean this
982 * mess up, but more thorough testing is needed. - Mathieu
983 */
984static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
985{ 982{
986 unsigned int j, cpu = dev->id; 983 unsigned int j, cpu = dev->id;
987 int ret = -ENOMEM; 984 int ret = -ENOMEM;
@@ -1013,7 +1010,8 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
1013 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling); 1010 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
1014 if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) { 1011 if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) {
1015 read_unlock_irqrestore(&cpufreq_driver_lock, flags); 1012 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
1016 return cpufreq_add_policy_cpu(cpu, sibling, dev); 1013 return cpufreq_add_policy_cpu(cpu, sibling, dev,
1014 frozen);
1017 } 1015 }
1018 } 1016 }
1019 read_unlock_irqrestore(&cpufreq_driver_lock, flags); 1017 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
@@ -1079,9 +1077,11 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
1079 } 1077 }
1080 write_unlock_irqrestore(&cpufreq_driver_lock, flags); 1078 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
1081 1079
1082 ret = cpufreq_add_dev_interface(cpu, policy, dev); 1080 if (!frozen) {
1083 if (ret) 1081 ret = cpufreq_add_dev_interface(cpu, policy, dev);
1084 goto err_out_unregister; 1082 if (ret)
1083 goto err_out_unregister;
1084 }
1085 1085
1086 cpufreq_init_policy(policy); 1086 cpufreq_init_policy(policy);
1087 1087
@@ -1112,6 +1112,20 @@ module_out:
1112 return ret; 1112 return ret;
1113} 1113}
1114 1114
1115/**
1116 * cpufreq_add_dev - add a CPU device
1117 *
1118 * Adds the cpufreq interface for a CPU device.
1119 *
1120 * The Oracle says: try running cpufreq registration/unregistration concurrently
1121 * with with cpu hotplugging and all hell will break loose. Tried to clean this
1122 * mess up, but more thorough testing is needed. - Mathieu
1123 */
1124static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
1125{
1126 return __cpufreq_add_dev(dev, sif, false);
1127}
1128
1115static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) 1129static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
1116{ 1130{
1117 int j; 1131 int j;
@@ -1130,7 +1144,7 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
1130} 1144}
1131 1145
1132static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *data, 1146static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *data,
1133 unsigned int old_cpu) 1147 unsigned int old_cpu, bool frozen)
1134{ 1148{
1135 struct device *cpu_dev; 1149 struct device *cpu_dev;
1136 unsigned long flags; 1150 unsigned long flags;
@@ -1138,6 +1152,11 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *data,
1138 1152
1139 /* first sibling now owns the new sysfs dir */ 1153 /* first sibling now owns the new sysfs dir */
1140 cpu_dev = get_cpu_device(cpumask_first(data->cpus)); 1154 cpu_dev = get_cpu_device(cpumask_first(data->cpus));
1155
1156 /* Don't touch sysfs files during light-weight tear-down */
1157 if (frozen)
1158 return cpu_dev->id;
1159
1141 sysfs_remove_link(&cpu_dev->kobj, "cpufreq"); 1160 sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
1142 ret = kobject_move(&data->kobj, &cpu_dev->kobj); 1161 ret = kobject_move(&data->kobj, &cpu_dev->kobj);
1143 if (ret) { 1162 if (ret) {
@@ -1169,7 +1188,7 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *data,
1169 * This routine frees the rwsem before returning. 1188 * This routine frees the rwsem before returning.
1170 */ 1189 */
1171static int __cpufreq_remove_dev(struct device *dev, 1190static int __cpufreq_remove_dev(struct device *dev,
1172 struct subsys_interface *sif) 1191 struct subsys_interface *sif, bool frozen)
1173{ 1192{
1174 unsigned int cpu = dev->id, cpus; 1193 unsigned int cpu = dev->id, cpus;
1175 int new_cpu; 1194 int new_cpu;
@@ -1208,17 +1227,20 @@ static int __cpufreq_remove_dev(struct device *dev,
1208 cpumask_clear_cpu(cpu, data->cpus); 1227 cpumask_clear_cpu(cpu, data->cpus);
1209 unlock_policy_rwsem_write(cpu); 1228 unlock_policy_rwsem_write(cpu);
1210 1229
1211 if (cpu != data->cpu) { 1230 if (cpu != data->cpu && !frozen) {
1212 sysfs_remove_link(&dev->kobj, "cpufreq"); 1231 sysfs_remove_link(&dev->kobj, "cpufreq");
1213 } else if (cpus > 1) { 1232 } else if (cpus > 1) {
1214 1233
1215 new_cpu = cpufreq_nominate_new_policy_cpu(data, cpu); 1234 new_cpu = cpufreq_nominate_new_policy_cpu(data, cpu, frozen);
1216 if (new_cpu >= 0) { 1235 if (new_cpu >= 0) {
1217 WARN_ON(lock_policy_rwsem_write(cpu)); 1236 WARN_ON(lock_policy_rwsem_write(cpu));
1218 update_policy_cpu(data, new_cpu); 1237 update_policy_cpu(data, new_cpu);
1219 unlock_policy_rwsem_write(cpu); 1238 unlock_policy_rwsem_write(cpu);
1220 pr_debug("%s: policy Kobject moved to cpu: %d " 1239
1221 "from: %d\n",__func__, new_cpu, cpu); 1240 if (!frozen) {
1241 pr_debug("%s: policy Kobject moved to cpu: %d "
1242 "from: %d\n",__func__, new_cpu, cpu);
1243 }
1222 } 1244 }
1223 } 1245 }
1224 1246
@@ -1266,7 +1288,7 @@ static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
1266 if (cpu_is_offline(cpu)) 1288 if (cpu_is_offline(cpu))
1267 return 0; 1289 return 0;
1268 1290
1269 retval = __cpufreq_remove_dev(dev, sif); 1291 retval = __cpufreq_remove_dev(dev, sif, false);
1270 return retval; 1292 return retval;
1271} 1293}
1272 1294
@@ -1992,7 +2014,7 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb,
1992 break; 2014 break;
1993 case CPU_DOWN_PREPARE: 2015 case CPU_DOWN_PREPARE:
1994 case CPU_DOWN_PREPARE_FROZEN: 2016 case CPU_DOWN_PREPARE_FROZEN:
1995 __cpufreq_remove_dev(dev, NULL); 2017 __cpufreq_remove_dev(dev, NULL, false);
1996 break; 2018 break;
1997 case CPU_DOWN_FAILED: 2019 case CPU_DOWN_FAILED:
1998 case CPU_DOWN_FAILED_FROZEN: 2020 case CPU_DOWN_FAILED_FROZEN: