+ * We adjust to current frequency first, and need to clean up later. So either call
+ * to cpufreq_update_policy() or schedule handle_update()).
+ */
+static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, unsigned int new_freq)
+{
+ struct cpufreq_freqs freqs;
+
+ if (cpufreq_driver->flags & CPUFREQ_PANIC_OUTOFSYNC)
+ panic("CPU Frequency is out of sync.");
+
+ printk(KERN_WARNING "Warning: CPU frequency out of sync: cpufreq and timing "
+ "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
+
+ freqs.cpu = cpu;
+ freqs.old = old_freq;
+ freqs.new = new_freq;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+}
+
+
+/**
+ * cpufreq_get - get the current CPU frequency (in kHz)
+ * @cpu: CPU number
+ *
+ * Get the CPU current (static) CPU frequency
+ */
+unsigned int cpufreq_get(unsigned int cpu)
+{
+ struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
+ unsigned int ret = 0;
+
+ if (!policy)
+ return 0;
+
+ if (!cpufreq_driver->get)
+ goto out;
+
+ down(&policy->lock);
+
+ ret = cpufreq_driver->get(cpu);
+
+ if (ret && policy->cur && !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS))
+ {
+ /* verify no discrepancy between actual and saved value exists */
+ if (unlikely(ret != policy->cur)) {
+ cpufreq_out_of_sync(cpu, policy->cur, ret);
+ schedule_work(&policy->update);
+ }
+ }
+
+ up(&policy->lock);
+
+ out:
+ cpufreq_cpu_put(policy);
+
+ return (ret);
+}
+EXPORT_SYMBOL(cpufreq_get);
+
+
+/**
+ * cpufreq_resume - restore proper CPU frequency handling after resume
+ *
+ * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
+ * 2.) if ->target and !CPUFREQ_CONST_LOOPS: verify we're in sync
+ * 3.) schedule call cpufreq_update_policy() ASAP as interrupts are restored.