Mauro Carvalho Chehab | c460f97 | 2020-03-03 14:52:04 +0100 | [diff] [blame] | 1 | .. SPDX-License-Identifier: GPL-2.0 |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2 | |
Mauro Carvalho Chehab | c460f97 | 2020-03-03 14:52:04 +0100 | [diff] [blame] | 3 | ============================================================= |
| 4 | General description of the CPUFreq core and CPUFreq notifiers |
| 5 | ============================================================= |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 6 | |
Mauro Carvalho Chehab | c460f97 | 2020-03-03 14:52:04 +0100 | [diff] [blame] | 7 | Authors: |
| 8 | - Dominik Brodowski <linux@brodo.de> |
| 9 | - David Kimdon <dwhedon@debian.org> |
| 10 | - Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| 11 | - Viresh Kumar <viresh.kumar@linaro.org> |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 12 | |
Mauro Carvalho Chehab | c460f97 | 2020-03-03 14:52:04 +0100 | [diff] [blame] | 13 | .. Contents: |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 14 | |
Mauro Carvalho Chehab | c460f97 | 2020-03-03 14:52:04 +0100 | [diff] [blame] | 15 | 1. CPUFreq core and interfaces |
| 16 | 2. CPUFreq notifiers |
| 17 | 3. CPUFreq Table Generation with Operating Performance Point (OPP) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 18 | |
| 19 | 1. General Information |
Mauro Carvalho Chehab | c460f97 | 2020-03-03 14:52:04 +0100 | [diff] [blame] | 20 | ====================== |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 21 | |
Dominik Brodowski | eff0df6 | 2006-10-02 19:26:47 -0400 | [diff] [blame] | 22 | The CPUFreq core code is located in drivers/cpufreq/cpufreq.c. This |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 23 | cpufreq code offers a standardized interface for the CPUFreq |
| 24 | architecture drivers (those pieces of code that do actual |
| 25 | frequency transitions), as well as to "notifiers". These are device |
| 26 | drivers or other part of the kernel that need to be informed of |
| 27 | policy changes (ex. thermal modules like ACPI) or of all |
| 28 | frequency changes (ex. timing code) or even need to force certain |
| 29 | speed limits (like LCD drivers on ARM architecture). Additionally, the |
| 30 | kernel "constant" loops_per_jiffy is updated on frequency changes |
| 31 | here. |
| 32 | |
Viresh Kumar | 7de962c | 2017-01-06 11:08:05 +0530 | [diff] [blame] | 33 | Reference counting of the cpufreq policies is done by cpufreq_cpu_get |
| 34 | and cpufreq_cpu_put, which make sure that the cpufreq driver is |
| 35 | correctly registered with the core, and will not be unloaded until |
| 36 | cpufreq_put_cpu is called. That also ensures that the respective cpufreq |
| 37 | policy doesn't get freed while being used. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 38 | |
| 39 | 2. CPUFreq notifiers |
| 40 | ==================== |
| 41 | |
| 42 | CPUFreq notifiers conform to the standard kernel notifier interface. |
| 43 | See linux/include/linux/notifier.h for details on notifiers. |
| 44 | |
| 45 | There are two different CPUFreq notifiers - policy notifiers and |
| 46 | transition notifiers. |
| 47 | |
| 48 | |
| 49 | 2.1 CPUFreq policy notifiers |
| 50 | ---------------------------- |
| 51 | |
Viresh Kumar | c27c38a | 2019-07-23 11:44:10 +0530 | [diff] [blame] | 52 | These are notified when a new policy is created or removed. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 53 | |
Viresh Kumar | c27c38a | 2019-07-23 11:44:10 +0530 | [diff] [blame] | 54 | The phase is specified in the second argument to the notifier. The phase is |
| 55 | CPUFREQ_CREATE_POLICY when the policy is first created and it is |
| 56 | CPUFREQ_REMOVE_POLICY when the policy is removed. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 57 | |
Mauro Carvalho Chehab | c460f97 | 2020-03-03 14:52:04 +0100 | [diff] [blame] | 58 | The third argument, a ``void *pointer``, points to a struct cpufreq_policy |
Viresh Kumar | 7de962c | 2017-01-06 11:08:05 +0530 | [diff] [blame] | 59 | consisting of several values, including min, max (the lower and upper |
| 60 | frequencies (in kHz) of the new policy). |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 61 | |
| 62 | |
| 63 | 2.2 CPUFreq transition notifiers |
| 64 | -------------------------------- |
| 65 | |
Viresh Kumar | 7de962c | 2017-01-06 11:08:05 +0530 | [diff] [blame] | 66 | These are notified twice for each online CPU in the policy, when the |
| 67 | CPUfreq driver switches the CPU core frequency and this change has no |
| 68 | any external implications. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 69 | |
| 70 | The second argument specifies the phase - CPUFREQ_PRECHANGE or |
| 71 | CPUFREQ_POSTCHANGE. |
| 72 | |
| 73 | The third argument is a struct cpufreq_freqs with the following |
| 74 | values: |
Mauro Carvalho Chehab | c460f97 | 2020-03-03 14:52:04 +0100 | [diff] [blame] | 75 | |
Tang Yizhou | a15b8cd | 2021-12-01 15:40:21 +0800 | [diff] [blame] | 76 | ====== ====================================== |
| 77 | policy a pointer to the struct cpufreq_policy |
Mauro Carvalho Chehab | c460f97 | 2020-03-03 14:52:04 +0100 | [diff] [blame] | 78 | old old frequency |
| 79 | new new frequency |
| 80 | flags flags of the cpufreq driver |
Tang Yizhou | a15b8cd | 2021-12-01 15:40:21 +0800 | [diff] [blame] | 81 | ====== ====================================== |
Nishanth Menon | a0dd7b7 | 2014-05-05 08:33:50 -0500 | [diff] [blame] | 82 | |
| 83 | 3. CPUFreq Table Generation with Operating Performance Point (OPP) |
| 84 | ================================================================== |
Mauro Carvalho Chehab | 151f4e2 | 2019-06-13 07:10:36 -0300 | [diff] [blame] | 85 | For details about OPP, see Documentation/power/opp.rst |
Nishanth Menon | a0dd7b7 | 2014-05-05 08:33:50 -0500 | [diff] [blame] | 86 | |
Viresh Kumar | 2dd0df8 | 2018-04-03 15:37:39 +0530 | [diff] [blame] | 87 | dev_pm_opp_init_cpufreq_table - |
| 88 | This function provides a ready to use conversion routine to translate |
| 89 | the OPP layer's internal information about the available frequencies |
| 90 | into a format readily providable to cpufreq. |
Nishanth Menon | a0dd7b7 | 2014-05-05 08:33:50 -0500 | [diff] [blame] | 91 | |
Mauro Carvalho Chehab | c460f97 | 2020-03-03 14:52:04 +0100 | [diff] [blame] | 92 | .. Warning:: |
Nishanth Menon | a0dd7b7 | 2014-05-05 08:33:50 -0500 | [diff] [blame] | 93 | |
Mauro Carvalho Chehab | c460f97 | 2020-03-03 14:52:04 +0100 | [diff] [blame] | 94 | Do not use this function in interrupt context. |
| 95 | |
| 96 | Example:: |
| 97 | |
Nishanth Menon | a0dd7b7 | 2014-05-05 08:33:50 -0500 | [diff] [blame] | 98 | soc_pm_init() |
| 99 | { |
| 100 | /* Do things */ |
| 101 | r = dev_pm_opp_init_cpufreq_table(dev, &freq_table); |
| 102 | if (!r) |
Viresh Kumar | 2dd0df8 | 2018-04-03 15:37:39 +0530 | [diff] [blame] | 103 | policy->freq_table = freq_table; |
Nishanth Menon | a0dd7b7 | 2014-05-05 08:33:50 -0500 | [diff] [blame] | 104 | /* Do other things */ |
| 105 | } |
| 106 | |
Mauro Carvalho Chehab | c460f97 | 2020-03-03 14:52:04 +0100 | [diff] [blame] | 107 | .. note:: |
Nishanth Menon | a0dd7b7 | 2014-05-05 08:33:50 -0500 | [diff] [blame] | 108 | |
Mauro Carvalho Chehab | c460f97 | 2020-03-03 14:52:04 +0100 | [diff] [blame] | 109 | This function is available only if CONFIG_CPU_FREQ is enabled in |
| 110 | addition to CONFIG_PM_OPP. |
| 111 | |
| 112 | dev_pm_opp_free_cpufreq_table |
| 113 | Free up the table allocated by dev_pm_opp_init_cpufreq_table |