diff options
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 65 |
1 files changed, 53 insertions, 12 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 7e6baa58a7f2..a33174e324d1 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -1141,22 +1141,14 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy, | |||
1141 | return cpu_dev->id; | 1141 | return cpu_dev->id; |
1142 | } | 1142 | } |
1143 | 1143 | ||
1144 | /** | 1144 | static int __cpufreq_remove_dev_prepare(struct device *dev, |
1145 | * __cpufreq_remove_dev - remove a CPU device | 1145 | struct subsys_interface *sif, |
1146 | * | 1146 | bool frozen) |
1147 | * Removes the cpufreq interface for a CPU device. | ||
1148 | * Caller should already have policy_rwsem in write mode for this CPU. | ||
1149 | * This routine frees the rwsem before returning. | ||
1150 | */ | ||
1151 | static int __cpufreq_remove_dev(struct device *dev, | ||
1152 | struct subsys_interface *sif, bool frozen) | ||
1153 | { | 1147 | { |
1154 | unsigned int cpu = dev->id, cpus; | 1148 | unsigned int cpu = dev->id, cpus; |
1155 | int new_cpu, ret; | 1149 | int new_cpu, ret; |
1156 | unsigned long flags; | 1150 | unsigned long flags; |
1157 | struct cpufreq_policy *policy; | 1151 | struct cpufreq_policy *policy; |
1158 | struct kobject *kobj; | ||
1159 | struct completion *cmp; | ||
1160 | 1152 | ||
1161 | pr_debug("%s: unregistering CPU %u\n", __func__, cpu); | 1153 | pr_debug("%s: unregistering CPU %u\n", __func__, cpu); |
1162 | 1154 | ||
@@ -1213,6 +1205,33 @@ static int __cpufreq_remove_dev(struct device *dev, | |||
1213 | } | 1205 | } |
1214 | } | 1206 | } |
1215 | 1207 | ||
1208 | return 0; | ||
1209 | } | ||
1210 | |||
1211 | static int __cpufreq_remove_dev_finish(struct device *dev, | ||
1212 | struct subsys_interface *sif, | ||
1213 | bool frozen) | ||
1214 | { | ||
1215 | unsigned int cpu = dev->id, cpus; | ||
1216 | int ret; | ||
1217 | unsigned long flags; | ||
1218 | struct cpufreq_policy *policy; | ||
1219 | struct kobject *kobj; | ||
1220 | struct completion *cmp; | ||
1221 | |||
1222 | read_lock_irqsave(&cpufreq_driver_lock, flags); | ||
1223 | policy = per_cpu(cpufreq_cpu_data, cpu); | ||
1224 | read_unlock_irqrestore(&cpufreq_driver_lock, flags); | ||
1225 | |||
1226 | if (!policy) { | ||
1227 | pr_debug("%s: No cpu_data found\n", __func__); | ||
1228 | return -EINVAL; | ||
1229 | } | ||
1230 | |||
1231 | lock_policy_rwsem_read(cpu); | ||
1232 | cpus = cpumask_weight(policy->cpus); | ||
1233 | unlock_policy_rwsem_read(cpu); | ||
1234 | |||
1216 | /* If cpu is last user of policy, free policy */ | 1235 | /* If cpu is last user of policy, free policy */ |
1217 | if (cpus == 1) { | 1236 | if (cpus == 1) { |
1218 | if (cpufreq_driver->target) { | 1237 | if (cpufreq_driver->target) { |
@@ -1272,6 +1291,27 @@ static int __cpufreq_remove_dev(struct device *dev, | |||
1272 | return 0; | 1291 | return 0; |
1273 | } | 1292 | } |
1274 | 1293 | ||
1294 | /** | ||
1295 | * __cpufreq_remove_dev - remove a CPU device | ||
1296 | * | ||
1297 | * Removes the cpufreq interface for a CPU device. | ||
1298 | * Caller should already have policy_rwsem in write mode for this CPU. | ||
1299 | * This routine frees the rwsem before returning. | ||
1300 | */ | ||
1301 | static inline int __cpufreq_remove_dev(struct device *dev, | ||
1302 | struct subsys_interface *sif, | ||
1303 | bool frozen) | ||
1304 | { | ||
1305 | int ret; | ||
1306 | |||
1307 | ret = __cpufreq_remove_dev_prepare(dev, sif, frozen); | ||
1308 | |||
1309 | if (!ret) | ||
1310 | ret = __cpufreq_remove_dev_finish(dev, sif, frozen); | ||
1311 | |||
1312 | return ret; | ||
1313 | } | ||
1314 | |||
1275 | static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) | 1315 | static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) |
1276 | { | 1316 | { |
1277 | unsigned int cpu = dev->id; | 1317 | unsigned int cpu = dev->id; |
@@ -2000,7 +2040,8 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, | |||
2000 | break; | 2040 | break; |
2001 | 2041 | ||
2002 | case CPU_DOWN_PREPARE: | 2042 | case CPU_DOWN_PREPARE: |
2003 | __cpufreq_remove_dev(dev, NULL, frozen); | 2043 | __cpufreq_remove_dev_prepare(dev, NULL, frozen); |
2044 | __cpufreq_remove_dev_finish(dev, NULL, frozen); | ||
2004 | break; | 2045 | break; |
2005 | 2046 | ||
2006 | case CPU_DOWN_FAILED: | 2047 | case CPU_DOWN_FAILED: |