[cpufreq] ondemand: make shutdown sequence more robust

Shutting down the ondemand policy was fraught with potential
problems, causing issues for SMP suspend (which wants to hot-
unplug) all but the last CPU.

This should fix at least the worst problems (divide-by-zero
and infinite wait for the workqueue to shut down).

Signed-off-by: Linus Torvalds <torvalds@osdl.org>

+10 -6
+10 -6
drivers/cpufreq/cpufreq_ondemand.c
··· 239 total_ticks = (unsigned int) cputime64_sub(cur_jiffies, 240 this_dbs_info->prev_cpu_wall); 241 this_dbs_info->prev_cpu_wall = cur_jiffies; 242 /* 243 * Every sampling_rate, we check, if current idle time is less 244 * than 20% (default), then we try to increase frequency ··· 306 unsigned int cpu = smp_processor_id(); 307 struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); 308 309 dbs_check_cpu(dbs_info); 310 queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, 311 usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); ··· 324 return; 325 } 326 327 - static inline void dbs_timer_exit(unsigned int cpu) 328 { 329 - struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); 330 - 331 - cancel_rearming_delayed_workqueue(kondemand_wq, &dbs_info->work); 332 } 333 334 static int cpufreq_governor_dbs(struct cpufreq_policy *policy, ··· 401 402 case CPUFREQ_GOV_STOP: 403 mutex_lock(&dbs_mutex); 404 - dbs_timer_exit(policy->cpu); 405 - this_dbs_info->enable = 0; 406 sysfs_remove_group(&policy->kobj, &dbs_attr_group); 407 dbs_enable--; 408 if (dbs_enable == 0)
··· 239 total_ticks = (unsigned int) cputime64_sub(cur_jiffies, 240 this_dbs_info->prev_cpu_wall); 241 this_dbs_info->prev_cpu_wall = cur_jiffies; 242 + if (!total_ticks) 243 + return; 244 /* 245 * Every sampling_rate, we check, if current idle time is less 246 * than 20% (default), then we try to increase frequency ··· 304 unsigned int cpu = smp_processor_id(); 305 struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); 306 307 + if (!dbs_info->enable) 308 + return; 309 + 310 dbs_check_cpu(dbs_info); 311 queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, 312 usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); ··· 319 return; 320 } 321 322 + static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) 323 { 324 + dbs_info->enable = 0; 325 + cancel_delayed_work(&dbs_info->work); 326 + flush_workqueue(kondemand_wq); 327 } 328 329 static int cpufreq_governor_dbs(struct cpufreq_policy *policy, ··· 396 397 case CPUFREQ_GOV_STOP: 398 mutex_lock(&dbs_mutex); 399 + dbs_timer_exit(this_dbs_info); 400 sysfs_remove_group(&policy->kobj, &dbs_attr_group); 401 dbs_enable--; 402 if (dbs_enable == 0)