1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun============================================================= 4*4882a593SmuzhiyunGeneral description of the CPUFreq core and CPUFreq notifiers 5*4882a593Smuzhiyun============================================================= 6*4882a593Smuzhiyun 7*4882a593SmuzhiyunAuthors: 8*4882a593Smuzhiyun - Dominik Brodowski <linux@brodo.de> 9*4882a593Smuzhiyun - David Kimdon <dwhedon@debian.org> 10*4882a593Smuzhiyun - Rafael J. Wysocki <rafael.j.wysocki@intel.com> 11*4882a593Smuzhiyun - Viresh Kumar <viresh.kumar@linaro.org> 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun.. Contents: 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun 1. CPUFreq core and interfaces 16*4882a593Smuzhiyun 2. CPUFreq notifiers 17*4882a593Smuzhiyun 3. CPUFreq Table Generation with Operating Performance Point (OPP) 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun1. General Information 20*4882a593Smuzhiyun====================== 21*4882a593Smuzhiyun 22*4882a593SmuzhiyunThe CPUFreq core code is located in drivers/cpufreq/cpufreq.c. This 23*4882a593Smuzhiyuncpufreq code offers a standardized interface for the CPUFreq 24*4882a593Smuzhiyunarchitecture drivers (those pieces of code that do actual 25*4882a593Smuzhiyunfrequency transitions), as well as to "notifiers". These are device 26*4882a593Smuzhiyundrivers or other part of the kernel that need to be informed of 27*4882a593Smuzhiyunpolicy changes (ex. thermal modules like ACPI) or of all 28*4882a593Smuzhiyunfrequency changes (ex. timing code) or even need to force certain 29*4882a593Smuzhiyunspeed limits (like LCD drivers on ARM architecture). Additionally, the 30*4882a593Smuzhiyunkernel "constant" loops_per_jiffy is updated on frequency changes 31*4882a593Smuzhiyunhere. 32*4882a593Smuzhiyun 33*4882a593SmuzhiyunReference counting of the cpufreq policies is done by cpufreq_cpu_get 34*4882a593Smuzhiyunand cpufreq_cpu_put, which make sure that the cpufreq driver is 35*4882a593Smuzhiyuncorrectly registered with the core, and will not be unloaded until 36*4882a593Smuzhiyuncpufreq_put_cpu is called. That also ensures that the respective cpufreq 37*4882a593Smuzhiyunpolicy doesn't get freed while being used. 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun2. CPUFreq notifiers 40*4882a593Smuzhiyun==================== 41*4882a593Smuzhiyun 42*4882a593SmuzhiyunCPUFreq notifiers conform to the standard kernel notifier interface. 43*4882a593SmuzhiyunSee linux/include/linux/notifier.h for details on notifiers. 44*4882a593Smuzhiyun 45*4882a593SmuzhiyunThere are two different CPUFreq notifiers - policy notifiers and 46*4882a593Smuzhiyuntransition notifiers. 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun2.1 CPUFreq policy notifiers 50*4882a593Smuzhiyun---------------------------- 51*4882a593Smuzhiyun 52*4882a593SmuzhiyunThese are notified when a new policy is created or removed. 53*4882a593Smuzhiyun 54*4882a593SmuzhiyunThe phase is specified in the second argument to the notifier. The phase is 55*4882a593SmuzhiyunCPUFREQ_CREATE_POLICY when the policy is first created and it is 56*4882a593SmuzhiyunCPUFREQ_REMOVE_POLICY when the policy is removed. 57*4882a593Smuzhiyun 58*4882a593SmuzhiyunThe third argument, a ``void *pointer``, points to a struct cpufreq_policy 59*4882a593Smuzhiyunconsisting of several values, including min, max (the lower and upper 60*4882a593Smuzhiyunfrequencies (in kHz) of the new policy). 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun2.2 CPUFreq transition notifiers 64*4882a593Smuzhiyun-------------------------------- 65*4882a593Smuzhiyun 66*4882a593SmuzhiyunThese are notified twice for each online CPU in the policy, when the 67*4882a593SmuzhiyunCPUfreq driver switches the CPU core frequency and this change has no 68*4882a593Smuzhiyunany external implications. 69*4882a593Smuzhiyun 70*4882a593SmuzhiyunThe second argument specifies the phase - CPUFREQ_PRECHANGE or 71*4882a593SmuzhiyunCPUFREQ_POSTCHANGE. 72*4882a593Smuzhiyun 73*4882a593SmuzhiyunThe third argument is a struct cpufreq_freqs with the following 74*4882a593Smuzhiyunvalues: 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun===== =========================== 77*4882a593Smuzhiyuncpu number of the affected CPU 78*4882a593Smuzhiyunold old frequency 79*4882a593Smuzhiyunnew new frequency 80*4882a593Smuzhiyunflags flags of the cpufreq driver 81*4882a593Smuzhiyun===== =========================== 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun3. CPUFreq Table Generation with Operating Performance Point (OPP) 84*4882a593Smuzhiyun================================================================== 85*4882a593SmuzhiyunFor details about OPP, see Documentation/power/opp.rst 86*4882a593Smuzhiyun 87*4882a593Smuzhiyundev_pm_opp_init_cpufreq_table - 88*4882a593Smuzhiyun This function provides a ready to use conversion routine to translate 89*4882a593Smuzhiyun the OPP layer's internal information about the available frequencies 90*4882a593Smuzhiyun into a format readily providable to cpufreq. 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun .. Warning:: 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun Do not use this function in interrupt context. 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun Example:: 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun soc_pm_init() 99*4882a593Smuzhiyun { 100*4882a593Smuzhiyun /* Do things */ 101*4882a593Smuzhiyun r = dev_pm_opp_init_cpufreq_table(dev, &freq_table); 102*4882a593Smuzhiyun if (!r) 103*4882a593Smuzhiyun policy->freq_table = freq_table; 104*4882a593Smuzhiyun /* Do other things */ 105*4882a593Smuzhiyun } 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun .. note:: 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun This function is available only if CONFIG_CPU_FREQ is enabled in 110*4882a593Smuzhiyun addition to CONFIG_PM_OPP. 111*4882a593Smuzhiyun 112*4882a593Smuzhiyundev_pm_opp_free_cpufreq_table 113*4882a593Smuzhiyun Free up the table allocated by dev_pm_opp_init_cpufreq_table 114