aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/cpufreq/cpufreq.c5
-rw-r--r--drivers/cpufreq/cpufreq_stats.c24
-rw-r--r--include/linux/cpufreq.h2
3 files changed, 24 insertions, 7 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 3509ca04b5bb..1afbe52d6782 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -943,6 +943,9 @@ static void cpufreq_policy_put_kobj(struct cpufreq_policy *policy)
943 struct kobject *kobj; 943 struct kobject *kobj;
944 struct completion *cmp; 944 struct completion *cmp;
945 945
946 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
947 CPUFREQ_REMOVE_POLICY, policy);
948
946 down_read(&policy->rwsem); 949 down_read(&policy->rwsem);
947 kobj = &policy->kobj; 950 kobj = &policy->kobj;
948 cmp = &policy->kobj_unregister; 951 cmp = &policy->kobj_unregister;
@@ -1148,6 +1151,8 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
1148 ret = cpufreq_add_dev_interface(policy, dev); 1151 ret = cpufreq_add_dev_interface(policy, dev);
1149 if (ret) 1152 if (ret)
1150 goto err_out_unregister; 1153 goto err_out_unregister;
1154 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1155 CPUFREQ_CREATE_POLICY, policy);
1151 } 1156 }
1152 1157
1153 write_lock_irqsave(&cpufreq_driver_lock, flags); 1158 write_lock_irqsave(&cpufreq_driver_lock, flags);
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index 4cf0d2805cb2..0f7156252453 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -277,7 +277,7 @@ static void cpufreq_stats_update_policy_cpu(struct cpufreq_policy *policy)
277static int cpufreq_stat_notifier_policy(struct notifier_block *nb, 277static int cpufreq_stat_notifier_policy(struct notifier_block *nb,
278 unsigned long val, void *data) 278 unsigned long val, void *data)
279{ 279{
280 int ret; 280 int ret = 0;
281 struct cpufreq_policy *policy = data; 281 struct cpufreq_policy *policy = data;
282 struct cpufreq_frequency_table *table; 282 struct cpufreq_frequency_table *table;
283 unsigned int cpu = policy->cpu; 283 unsigned int cpu = policy->cpu;
@@ -287,15 +287,21 @@ static int cpufreq_stat_notifier_policy(struct notifier_block *nb,
287 return 0; 287 return 0;
288 } 288 }
289 289
290 if (val != CPUFREQ_NOTIFY)
291 return 0;
292 table = cpufreq_frequency_get_table(cpu); 290 table = cpufreq_frequency_get_table(cpu);
293 if (!table) 291 if (!table)
294 return 0; 292 return 0;
295 ret = cpufreq_stats_create_table(policy, table); 293
296 if (ret) 294 if (val == CPUFREQ_CREATE_POLICY)
297 return ret; 295 ret = cpufreq_stats_create_table(policy, table);
298 return 0; 296 else if (val == CPUFREQ_REMOVE_POLICY) {
297 /* This might already be freed by cpu hotplug notifier */
298 if (per_cpu(cpufreq_stats_table, cpu)) {
299 cpufreq_stats_free_sysfs(cpu);
300 cpufreq_stats_free_table(cpu);
301 }
302 }
303
304 return ret;
299} 305}
300 306
301static int cpufreq_stat_notifier_trans(struct notifier_block *nb, 307static int cpufreq_stat_notifier_trans(struct notifier_block *nb,
@@ -340,6 +346,10 @@ static int cpufreq_stat_cpu_callback(struct notifier_block *nfb,
340{ 346{
341 unsigned int cpu = (unsigned long)hcpu; 347 unsigned int cpu = (unsigned long)hcpu;
342 348
349 /* Don't free/allocate stats during suspend/resume */
350 if (action & CPU_TASKS_FROZEN)
351 return 0;
352
343 switch (action) { 353 switch (action) {
344 case CPU_DOWN_PREPARE: 354 case CPU_DOWN_PREPARE:
345 cpufreq_stats_free_sysfs(cpu); 355 cpufreq_stats_free_sysfs(cpu);
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index aaf800eb9dd2..bb727eb98ed5 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -308,6 +308,8 @@ cpufreq_verify_within_cpu_limits(struct cpufreq_policy *policy)
308#define CPUFREQ_NOTIFY (2) 308#define CPUFREQ_NOTIFY (2)
309#define CPUFREQ_START (3) 309#define CPUFREQ_START (3)
310#define CPUFREQ_UPDATE_POLICY_CPU (4) 310#define CPUFREQ_UPDATE_POLICY_CPU (4)
311#define CPUFREQ_CREATE_POLICY (5)
312#define CPUFREQ_REMOVE_POLICY (6)
311 313
312#ifdef CONFIG_CPU_FREQ 314#ifdef CONFIG_CPU_FREQ
313int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list); 315int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list);