aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/cpufreq/cpufreq.c65
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/** 1144static 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 */
1151static 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
1211static 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 */
1301static 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
1275static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) 1315static 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: