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