Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | CPU frequency and voltage scaling code in the Linux(TM) kernel |
| 2 | |
| 3 | |
| 4 | L i n u x C P U F r e q |
| 5 | |
| 6 | C P U F r e q C o r e |
| 7 | |
| 8 | |
| 9 | Dominik Brodowski <linux@brodo.de> |
| 10 | David Kimdon <dwhedon@debian.org> |
| 11 | |
| 12 | |
| 13 | |
| 14 | Clock scaling allows you to change the clock speed of the CPUs on the |
| 15 | fly. This is a nice method to save battery power, because the lower |
| 16 | the clock speed, the less power the CPU consumes. |
| 17 | |
| 18 | |
| 19 | Contents: |
| 20 | --------- |
| 21 | 1. CPUFreq core and interfaces |
| 22 | 2. CPUFreq notifiers |
| 23 | |
| 24 | 1. General Information |
| 25 | ======================= |
| 26 | |
| 27 | The CPUFreq core code is located in linux/kernel/cpufreq.c. This |
| 28 | cpufreq code offers a standardized interface for the CPUFreq |
| 29 | architecture drivers (those pieces of code that do actual |
| 30 | frequency transitions), as well as to "notifiers". These are device |
| 31 | drivers or other part of the kernel that need to be informed of |
| 32 | policy changes (ex. thermal modules like ACPI) or of all |
| 33 | frequency changes (ex. timing code) or even need to force certain |
| 34 | speed limits (like LCD drivers on ARM architecture). Additionally, the |
| 35 | kernel "constant" loops_per_jiffy is updated on frequency changes |
| 36 | here. |
| 37 | |
| 38 | Reference counting is done by cpufreq_get_cpu and cpufreq_put_cpu, |
| 39 | which make sure that the cpufreq processor driver is correctly |
| 40 | registered with the core, and will not be unloaded until |
| 41 | cpufreq_put_cpu is called. |
| 42 | |
| 43 | 2. CPUFreq notifiers |
| 44 | ==================== |
| 45 | |
| 46 | CPUFreq notifiers conform to the standard kernel notifier interface. |
| 47 | See linux/include/linux/notifier.h for details on notifiers. |
| 48 | |
| 49 | There are two different CPUFreq notifiers - policy notifiers and |
| 50 | transition notifiers. |
| 51 | |
| 52 | |
| 53 | 2.1 CPUFreq policy notifiers |
| 54 | ---------------------------- |
| 55 | |
| 56 | These are notified when a new policy is intended to be set. Each |
| 57 | CPUFreq policy notifier is called three times for a policy transition: |
| 58 | |
| 59 | 1.) During CPUFREQ_ADJUST all CPUFreq notifiers may change the limit if |
| 60 | they see a need for this - may it be thermal considerations or |
| 61 | hardware limitations. |
| 62 | |
| 63 | 2.) During CPUFREQ_INCOMPATIBLE only changes may be done in order to avoid |
| 64 | hardware failure. |
| 65 | |
| 66 | 3.) And during CPUFREQ_NOTIFY all notifiers are informed of the new policy |
| 67 | - if two hardware drivers failed to agree on a new policy before this |
| 68 | stage, the incompatible hardware shall be shut down, and the user |
| 69 | informed of this. |
| 70 | |
| 71 | The phase is specified in the second argument to the notifier. |
| 72 | |
| 73 | The third argument, a void *pointer, points to a struct cpufreq_policy |
| 74 | consisting of five values: cpu, min, max, policy and max_cpu_freq. min |
| 75 | and max are the lower and upper frequencies (in kHz) of the new |
| 76 | policy, policy the new policy, cpu the number of the affected CPU; and |
| 77 | max_cpu_freq the maximum supported CPU frequency. This value is given |
| 78 | for informational purposes only. |
| 79 | |
| 80 | |
| 81 | 2.2 CPUFreq transition notifiers |
| 82 | -------------------------------- |
| 83 | |
| 84 | These are notified twice when the CPUfreq driver switches the CPU core |
| 85 | frequency and this change has any external implications. |
| 86 | |
| 87 | The second argument specifies the phase - CPUFREQ_PRECHANGE or |
| 88 | CPUFREQ_POSTCHANGE. |
| 89 | |
| 90 | The third argument is a struct cpufreq_freqs with the following |
| 91 | values: |
| 92 | cpu - number of the affected CPU |
| 93 | old - old frequency |
| 94 | new - new frequency |
| 95 | |
| 96 | If the cpufreq core detects the frequency has changed while the system |
| 97 | was suspended, these notifiers are called with CPUFREQ_RESUMECHANGE as |
| 98 | second argument. |