[CPUFREQ] Re-enable cpufreq suspend and resume code
authorDominik Brodowski <linux@dominikbrodowski.net>
Fri, 7 Aug 2009 20:58:51 +0000 (22:58 +0200)
committerDave Jones <davej@redhat.com>
Tue, 1 Sep 2009 16:45:08 +0000 (12:45 -0400)
commitce6c3997c2fce74d12e6d8887a1d8cdf024fa850
tree047d8577b12e9c5dbcf147f4a76bca537d775b4a
parent37d0892c5a94e208cf863e3b7bac014edee4346d
[CPUFREQ] Re-enable cpufreq suspend and resume code

Commit 4bc5d3413503 is broken and causes regressions:

(1) cpufreq_driver->resume() and ->suspend() were only called on
__powerpc__, but you could set them on all architectures. In fact,
->resume() was defined and used before the PPC-related commit
42d4dc3f4e1e complained about in 4bc5d3413503.

(2) Therfore, the resume functions in acpi_cpufreq and speedstep-smi
would never be called.

(3) This means speedstep-smi would be unusuable after suspend or resume.

The _real_ problem was calling cpufreq_driver->get() with interrupts
off, but it re-enabling interrupts on some platforms. Why is ->get()
necessary?

Some systems like to change the CPU frequency behind our
back, especially during BIOS-intensive operations like suspend or
resume. If such systems also use a CPU frequency-dependant timing loop,
delays might be off by large factors. Therefore, we need to ascertain
as soon as possible that the CPU frequency is indeed at the speed we
think it is. You can do this two ways: either setting it anew, or trying
to get it. The latter is what was done, the former also has the same IRQ
issue.

So, let's try something different: defer the checking to after interrupts
are re-enabled, by calling cpufreq_update_policy() (via schedule_work()).
Timings may be off until this later stage, so let's watch out for
resume regressions caused by the deferred handling of frequency changes
behind the kernel's back.

Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Dave Jones <davej@redhat.com>
drivers/cpufreq/cpufreq.c