diff options
| -rw-r--r-- | drivers/cpufreq/cpufreq.c | 5 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_stats.c | 24 | ||||
| -rw-r--r-- | include/linux/cpufreq.h | 2 |
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) | |||
| 277 | static int cpufreq_stat_notifier_policy(struct notifier_block *nb, | 277 | static 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 | ||
| 301 | static int cpufreq_stat_notifier_trans(struct notifier_block *nb, | 307 | static 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 |
| 313 | int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list); | 315 | int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list); |
