sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}(hhparenthuba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget/translations/zh_CN/power/oppmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}(hhhh2ubah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget/translations/zh_TW/power/oppmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}(hhhhFubah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget/translations/it_IT/power/oppmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}(hhhhZubah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget/translations/ja_JP/power/oppmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}(hhhhnubah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget/translations/ko_KR/power/oppmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}(hhhhubah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget/translations/sp_SP/power/oppmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhsection)}(hhh](htitle)}(h*Operating Performance Points (OPP) Libraryh]h*Operating Performance Points (OPP) Library}(hhhhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhh7/var/lib/git/docbuild/linux/Documentation/power/opp.rsthKubhenumerated_list)}(hhh]h list_item)}(hE2009-2010 Nishanth Menon , Texas Instruments Incorporated h]h paragraph)}(hD2009-2010 Nishanth Menon , Texas Instruments Incorporatedh](h2009-2010 Nishanth Menon <}(h2009-2010 Nishanth Menon , Texas Instruments Incorporated}(h!>, Texas Instruments IncorporatedhhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubah}(h]h ]h"]h$]h&]enumtype upperalphaprefix(suffix)startKuh1hhhhhhhhKubhcomment)}(hContents 1. Introduction 2. Initial OPP List Registration 3. OPP Search Functions 4. OPP Availability Control Functions 5. OPP Data Retrieval Functions 6. Data Structuresh]hContents 1. Introduction 2. Initial OPP List Registration 3. OPP Search Functions 4. OPP Availability Control Functions 5. OPP Data Retrieval Functions 6. Data Structures}(hhhhubah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhhhKubh)}(hhh](h)}(h1. Introductionh]h1. Introduction}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hhh](h)}(h11.1 What is an Operating Performance Point (OPP)?h]h11.1 What is an Operating Performance Point (OPP)?}(hj%hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKubh)}(hXComplex SoCs of today consists of a multiple sub-modules working in conjunction. In an operational system executing varied use cases, not all modules in the SoC need to function at their highest performing frequency all the time. To facilitate this, sub-modules in a SoC are grouped into domains, allowing some domains to run at lower voltage and frequency while other domains run at voltage/frequency pairs that are higher.h]hXComplex SoCs of today consists of a multiple sub-modules working in conjunction. In an operational system executing varied use cases, not all modules in the SoC need to function at their highest performing frequency all the time. To facilitate this, sub-modules in a SoC are grouped into domains, allowing some domains to run at lower voltage and frequency while other domains run at voltage/frequency pairs that are higher.}(hj3hj1hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubh)}(hThe set of discrete tuples consisting of frequency and voltage pairs that the device will support per domain are called Operating Performance Points or OPPs.h]hThe set of discrete tuples consisting of frequency and voltage pairs that the device will support per domain are called Operating Performance Points or OPPs.}(hjAhj?hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubh)}(hAs an example:h]hAs an example:}(hjOhjMhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK!hj hhubh)}(hLet us consider an MPU device which supports the following: {300MHz at minimum voltage of 1V}, {800MHz at minimum voltage of 1.2V}, {1GHz at minimum voltage of 1.3V}h]hLet us consider an MPU device which supports the following: {300MHz at minimum voltage of 1V}, {800MHz at minimum voltage of 1.2V}, {1GHz at minimum voltage of 1.3V}}(hj]hj[hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK#hj hhubh)}(hFWe can represent these as three OPPs as the following {Hz, uV} tuples:h]hFWe can represent these as three OPPs as the following {Hz, uV} tuples:}(hjkhjihhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK'hj hhubh bullet_list)}(hhh](h)}(h{300000000, 1000000}h]h)}(hj~h]h{300000000, 1000000}}(hj~hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK)hj|ubah}(h]h ]h"]h$]h&]uh1hhjyhhhhhNubh)}(h{800000000, 1200000}h]h)}(hjh]h{800000000, 1200000}}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK*hjubah}(h]h ]h"]h$]h&]uh1hhjyhhhhhNubh)}(h{1000000000, 1300000} h]h)}(h{1000000000, 1300000}h]h{1000000000, 1300000}}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK+hjubah}(h]h ]h"]h$]h&]uh1hhjyhhhhhNubeh}(h]h ]h"]h$]h&]bullet-uh1jwhhhK)hj hhubeh}(h]*what-is-an-operating-performance-point-oppah ]h"]11.1 what is an operating performance point (opp)?ah$]h&]uh1hhjhhhhhKubh)}(hhh](h)}(h(1.2 Operating Performance Points Libraryh]h(1.2 Operating Performance Points Library}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK.ubh)}(hXOPP library provides a set of helper functions to organize and query the OPP information. The library is located in drivers/opp/ directory and the header is located in include/linux/pm_opp.h. OPP library can be enabled by enabling CONFIG_PM_OPP from power management menuconfig menu. Certain SoCs such as Texas Instrument's OMAP framework allows to optionally boot at a certain OPP without needing cpufreq.h]hXOPP library provides a set of helper functions to organize and query the OPP information. The library is located in drivers/opp/ directory and the header is located in include/linux/pm_opp.h. OPP library can be enabled by enabling CONFIG_PM_OPP from power management menuconfig menu. Certain SoCs such as Texas Instrument’s OMAP framework allows to optionally boot at a certain OPP without needing cpufreq.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK0hjhhubh)}(h0Typical usage of the OPP library is as follows::h]h/Typical usage of the OPP library is as follows:}(h/Typical usage of the OPP library is as follows:hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK7hjhhubh literal_block)}(h(users) -> registers a set of default OPPs -> (library) SoC framework -> modifies on required cases certain OPPs -> OPP layer -> queries to search/retrieve information ->h]h(users) -> registers a set of default OPPs -> (library) SoC framework -> modifies on required cases certain OPPs -> OPP layer -> queries to search/retrieve information ->}(hhhjubah}(h]h ]h"]h$]h&]j juh1jhhhK9hjhhubh)}(hX`OPP layer expects each domain to be represented by a unique device pointer. SoC framework registers a set of initial OPPs per device with the OPP layer. This list is expected to be an optimally small number typically around 5 per device. This initial list contains a set of OPPs that the framework expects to be safely enabled by default in the system.h]hX`OPP layer expects each domain to be represented by a unique device pointer. SoC framework registers a set of initial OPPs per device with the OPP layer. This list is expected to be an optimally small number typically around 5 per device. This initial list contains a set of OPPs that the framework expects to be safely enabled by default in the system.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK=hjhhubh)}(hhh](h)}(hNote on OPP Availabilityh]hNote on OPP Availability}(hj#hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKDubh)}(hXpAs the system proceeds to operate, SoC framework may choose to make certain OPPs available or not available on each device based on various external factors. Example usage: Thermal management or other exceptional situations where SoC framework might choose to disable a higher frequency OPP to safely continue operations until that OPP could be re-enabled if possible.h]hXpAs the system proceeds to operate, SoC framework may choose to make certain OPPs available or not available on each device based on various external factors. Example usage: Thermal management or other exceptional situations where SoC framework might choose to disable a higher frequency OPP to safely continue operations until that OPP could be re-enabled if possible.}(hj1hj/hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKFhjhhubh)}(hOPP library facilitates this concept in its implementation. The following operational functions operate only on available opps: dev_pm_opp_find_freq_{ceil, floor}, dev_pm_opp_get_voltage, dev_pm_opp_get_freq, dev_pm_opp_get_opp_count.h]hOPP library facilitates this concept in its implementation. The following operational functions operate only on available opps: dev_pm_opp_find_freq_{ceil, floor}, dev_pm_opp_get_voltage, dev_pm_opp_get_freq, dev_pm_opp_get_opp_count.}(hj?hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKLhjhhubh)}(hdev_pm_opp_find_freq_exact is meant to be used to find the opp pointer which can then be used for dev_pm_opp_enable/disable functions to make an opp available as required.h]hdev_pm_opp_find_freq_exact is meant to be used to find the opp pointer which can then be used for dev_pm_opp_enable/disable functions to make an opp available as required.}(hjMhjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKQhjhhubh)}(hXWARNING: Users of OPP library should refresh their availability count using get_opp_count if dev_pm_opp_enable/disable functions are invoked for a device, the exact mechanism to trigger these or the notification mechanism to other dependent subsystems such as cpufreq are left to the discretion of the SoC specific framework which uses the OPP library. Similar care needs to be taken care to refresh the cpufreq table in cases of these operations.h]hXWARNING: Users of OPP library should refresh their availability count using get_opp_count if dev_pm_opp_enable/disable functions are invoked for a device, the exact mechanism to trigger these or the notification mechanism to other dependent subsystems such as cpufreq are left to the discretion of the SoC specific framework which uses the OPP library. Similar care needs to be taken care to refresh the cpufreq table in cases of these operations.}(hj[hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKUhjhhubeh}(h]note-on-opp-availabilityah ]h"]note on opp availabilityah$]h&]uh1hhjhhhhhKDubeh}(h]$operating-performance-points-libraryah ]h"](1.2 operating performance points libraryah$]h&]uh1hhjhhhhhK.ubeh}(h] introductionah ]h"]1. introductionah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h 2. Initial OPP List Registrationh]h 2. Initial OPP List Registration}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK]ubh)}(hXThe SoC implementation calls dev_pm_opp_add function iteratively to add OPPs per device. It is expected that the SoC framework will register the OPP entries optimally- typical numbers range to be less than 5. The list generated by registering the OPPs is maintained by OPP library throughout the device operation. The SoC framework can subsequently control the availability of the OPPs dynamically using the dev_pm_opp_enable / disable functions.h]hXThe SoC implementation calls dev_pm_opp_add function iteratively to add OPPs per device. It is expected that the SoC framework will register the OPP entries optimally- typical numbers range to be less than 5. The list generated by registering the OPPs is maintained by OPP library throughout the device operation. The SoC framework can subsequently control the availability of the OPPs dynamically using the dev_pm_opp_enable / disable functions.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK^hjhhubhdefinition_list)}(hhh]hdefinition_list_item)}(hXXdev_pm_opp_add Add a new OPP for a specific domain represented by the device pointer. The OPP is defined using the frequency and voltage. Once added, the OPP is assumed to be available and control of its availability can be done with the dev_pm_opp_enable/disable functions. OPP library internally stores and manages this information in the dev_pm_opp struct. This function may be used by SoC framework to define a optimal list as per the demands of SoC usage environment. WARNING: Do not use this function in interrupt context. Example:: soc_pm_init() { /* Do things */ r = dev_pm_opp_add(mpu_dev, 1000000, 900000); if (!r) { pr_err("%s: unable to register mpu opp(%d)\n", r); goto no_cpufreq; } /* Do cpufreq things */ no_cpufreq: /* Do remaining things */ } h](hterm)}(hdev_pm_opp_addh]hdev_pm_opp_add}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhK~hjubh definition)}(hhh](h)}(hXAdd a new OPP for a specific domain represented by the device pointer. The OPP is defined using the frequency and voltage. Once added, the OPP is assumed to be available and control of its availability can be done with the dev_pm_opp_enable/disable functions. OPP library internally stores and manages this information in the dev_pm_opp struct. This function may be used by SoC framework to define a optimal list as per the demands of SoC usage environment.h]hXAdd a new OPP for a specific domain represented by the device pointer. The OPP is defined using the frequency and voltage. Once added, the OPP is assumed to be available and control of its availability can be done with the dev_pm_opp_enable/disable functions. OPP library internally stores and manages this information in the dev_pm_opp struct. This function may be used by SoC framework to define a optimal list as per the demands of SoC usage environment.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKfhjubj)}(hhh]j)}(h8WARNING: Do not use this function in interrupt context. h](j)}(hWARNING:h]hWARNING:}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKohjubj)}(hhh]h)}(h.Do not use this function in interrupt context.h]h.Do not use this function in interrupt context.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKohjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhKohjubah}(h]h ]h"]h$]h&]uh1jhjubh)}(h Example::h]hExample:}(hExample:hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKqhjubj)}(hX%soc_pm_init() { /* Do things */ r = dev_pm_opp_add(mpu_dev, 1000000, 900000); if (!r) { pr_err("%s: unable to register mpu opp(%d)\n", r); goto no_cpufreq; } /* Do cpufreq things */ no_cpufreq: /* Do remaining things */ }h]hX%soc_pm_init() { /* Do things */ r = dev_pm_opp_add(mpu_dev, 1000000, 900000); if (!r) { pr_err("%s: unable to register mpu opp(%d)\n", r); goto no_cpufreq; } /* Do cpufreq things */ no_cpufreq: /* Do remaining things */ }}(hhhjubah}(h]h ]h"]h$]h&]j juh1jhhhKshjubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhK~hjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]initial-opp-list-registrationah ]h"] 2. initial opp list registrationah$]h&]uh1hhhhhhhhK]ubh)}(hhh](h)}(h3. OPP Search Functionsh]h3. OPP Search Functions}(hj@hj>hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj;hhhhhKubh)}(hXHigh level framework such as cpufreq operates on frequencies. To map the frequency back to the corresponding OPP, OPP library provides handy functions to search the OPP list that OPP library internally manages. These search functions return the matching pointer representing the opp if a match is found, else returns error. These errors are expected to be handled by standard error checks such as IS_ERR() and appropriate actions taken by the caller.h]hXHigh level framework such as cpufreq operates on frequencies. To map the frequency back to the corresponding OPP, OPP library provides handy functions to search the OPP list that OPP library internally manages. These search functions return the matching pointer representing the opp if a match is found, else returns error. These errors are expected to be handled by standard error checks such as IS_ERR() and appropriate actions taken by the caller.}(hjNhjLhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj;hhubh)}(hCallers of these functions shall call dev_pm_opp_put() after they have used the OPP. Otherwise the memory for the OPP will never get freed and result in memleak.h]hCallers of these functions shall call dev_pm_opp_put() after they have used the OPP. Otherwise the memory for the OPP will never get freed and result in memleak.}(hj\hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj;hhubj)}(hhh](j)}(hXdev_pm_opp_find_freq_exact Search for an OPP based on an *exact* frequency and availability. This function is especially useful to enable an OPP which is not available by default. Example: In a case when SoC framework detects a situation where a higher frequency could be made available, it can use this function to find the OPP prior to call the dev_pm_opp_enable to actually make it available:: opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false); dev_pm_opp_put(opp); /* dont operate on the pointer.. just do a sanity check.. */ if (IS_ERR(opp)) { pr_err("frequency not disabled!\n"); /* trigger appropriate actions.. */ } else { dev_pm_opp_enable(dev,1000000000); } NOTE: This is the only search function that operates on OPPs which are not available. h](j)}(hdev_pm_opp_find_freq_exacth]hdev_pm_opp_find_freq_exact}(hjqhjohhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhjkubj)}(hhh](h)}(hXqSearch for an OPP based on an *exact* frequency and availability. This function is especially useful to enable an OPP which is not available by default. Example: In a case when SoC framework detects a situation where a higher frequency could be made available, it can use this function to find the OPP prior to call the dev_pm_opp_enable to actually make it available::h](hSearch for an OPP based on an }(hSearch for an OPP based on an hjhhhNhNubhemphasis)}(h*exact*h]hexact}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhXK frequency and availability. This function is especially useful to enable an OPP which is not available by default. Example: In a case when SoC framework detects a situation where a higher frequency could be made available, it can use this function to find the OPP prior to call the dev_pm_opp_enable to actually make it available:}(hXK frequency and availability. This function is especially useful to enable an OPP which is not available by default. Example: In a case when SoC framework detects a situation where a higher frequency could be made available, it can use this function to find the OPP prior to call the dev_pm_opp_enable to actually make it available:hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj}ubj)}(hX*opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false); dev_pm_opp_put(opp); /* dont operate on the pointer.. just do a sanity check.. */ if (IS_ERR(opp)) { pr_err("frequency not disabled!\n"); /* trigger appropriate actions.. */ } else { dev_pm_opp_enable(dev,1000000000); }h]hX*opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false); dev_pm_opp_put(opp); /* dont operate on the pointer.. just do a sanity check.. */ if (IS_ERR(opp)) { pr_err("frequency not disabled!\n"); /* trigger appropriate actions.. */ } else { dev_pm_opp_enable(dev,1000000000); }}(hhhjubah}(h]h ]h"]h$]h&]j juh1jhhhKhj}ubj)}(hhh]j)}(hVNOTE: This is the only search function that operates on OPPs which are not available. h](j)}(hNOTE:h]hNOTE:}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhjubj)}(hhh]h)}(hOThis is the only search function that operates on OPPs which are not available.h]hOThis is the only search function that operates on OPPs which are not available.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhKhjubah}(h]h ]h"]h$]h&]uh1jhj}ubeh}(h]h ]h"]h$]h&]uh1jhjkubeh}(h]h ]h"]h$]h&]uh1jhhhKhjhubj)}(hXldev_pm_opp_find_freq_floor Search for an available OPP which is *at most* the provided frequency. This function is useful while searching for a lesser match OR operating on OPP information in the order of decreasing frequency. Example: To find the highest opp for a device:: freq = ULONG_MAX; opp = dev_pm_opp_find_freq_floor(dev, &freq); dev_pm_opp_put(opp); h](j)}(hdev_pm_opp_find_freq_floorh]hdev_pm_opp_find_freq_floor}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhjubj)}(hhh](h)}(hSearch for an available OPP which is *at most* the provided frequency. This function is useful while searching for a lesser match OR operating on OPP information in the order of decreasing frequency. Example: To find the highest opp for a device::h](h%Search for an available OPP which is }(h%Search for an available OPP which is hj hhhNhNubj)}(h *at most*h]hat most}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh the provided frequency. This function is useful while searching for a lesser match OR operating on OPP information in the order of decreasing frequency. Example: To find the highest opp for a device:}(h the provided frequency. This function is useful while searching for a lesser match OR operating on OPP information in the order of decreasing frequency. Example: To find the highest opp for a device:hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubj)}(hTfreq = ULONG_MAX; opp = dev_pm_opp_find_freq_floor(dev, &freq); dev_pm_opp_put(opp);h]hTfreq = ULONG_MAX; opp = dev_pm_opp_find_freq_floor(dev, &freq); dev_pm_opp_put(opp);}(hhhj-ubah}(h]h ]h"]h$]h&]j juh1jhhhKhjubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhKhjhhhubj)}(hX=dev_pm_opp_find_freq_ceil Search for an available OPP which is *at least* the provided frequency. This function is useful while searching for a higher match OR operating on OPP information in the order of increasing frequency. Example 1: To find the lowest opp for a device:: freq = 0; opp = dev_pm_opp_find_freq_ceil(dev, &freq); dev_pm_opp_put(opp); Example 2: A simplified implementation of a SoC cpufreq_driver->target:: soc_cpufreq_target(..) { /* Do stuff like policy checks etc. */ /* Find the best frequency match for the req */ opp = dev_pm_opp_find_freq_ceil(dev, &freq); dev_pm_opp_put(opp); if (!IS_ERR(opp)) soc_switch_to_freq_voltage(freq); else /* do something when we can't satisfy the req */ /* do other stuff */ } h](j)}(hdev_pm_opp_find_freq_ceilh]hdev_pm_opp_find_freq_ceil}(hjMhjKhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhjGubj)}(hhh](h)}(hSearch for an available OPP which is *at least* the provided frequency. This function is useful while searching for a higher match OR operating on OPP information in the order of increasing frequency. Example 1: To find the lowest opp for a device::h](h%Search for an available OPP which is }(h%Search for an available OPP which is hj\hhhNhNubj)}(h *at least*h]hat least}(hhhjehhhNhNubah}(h]h ]h"]h$]h&]uh1jhj\ubh the provided frequency. This function is useful while searching for a higher match OR operating on OPP information in the order of increasing frequency. Example 1: To find the lowest opp for a device:}(h the provided frequency. This function is useful while searching for a higher match OR operating on OPP information in the order of increasing frequency. Example 1: To find the lowest opp for a device:hj\hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjYubj)}(hKfreq = 0; opp = dev_pm_opp_find_freq_ceil(dev, &freq); dev_pm_opp_put(opp);h]hKfreq = 0; opp = dev_pm_opp_find_freq_ceil(dev, &freq); dev_pm_opp_put(opp);}(hhhj~ubah}(h]h ]h"]h$]h&]j juh1jhhhKhjYubh)}(hHExample 2: A simplified implementation of a SoC cpufreq_driver->target::h]hGExample 2: A simplified implementation of a SoC cpufreq_driver->target:}(hGExample 2: A simplified implementation of a SoC cpufreq_driver->target:hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjYubj)}(hXsoc_cpufreq_target(..) { /* Do stuff like policy checks etc. */ /* Find the best frequency match for the req */ opp = dev_pm_opp_find_freq_ceil(dev, &freq); dev_pm_opp_put(opp); if (!IS_ERR(opp)) soc_switch_to_freq_voltage(freq); else /* do something when we can't satisfy the req */ /* do other stuff */ }h]hXsoc_cpufreq_target(..) { /* Do stuff like policy checks etc. */ /* Find the best frequency match for the req */ opp = dev_pm_opp_find_freq_ceil(dev, &freq); dev_pm_opp_put(opp); if (!IS_ERR(opp)) soc_switch_to_freq_voltage(freq); else /* do something when we can't satisfy the req */ /* do other stuff */ }}(hhhjubah}(h]h ]h"]h$]h&]j juh1jhhhKhjYubeh}(h]h ]h"]h$]h&]uh1jhjGubeh}(h]h ]h"]h$]h&]uh1jhhhKhjhhhubeh}(h]h ]h"]h$]h&]uh1jhj;hhhNhNubeh}(h]opp-search-functionsah ]h"]3. opp search functionsah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h%4. OPP Availability Control Functionsh]h%4. OPP Availability Control Functions}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hXA default OPP list registered with the OPP library may not cater to all possible situation. The OPP library provides a set of functions to modify the availability of a OPP within the OPP list. This allows SoC frameworks to have fine grained dynamic control of which sets of OPPs are operationally available. These functions are intended to *temporarily* remove an OPP in conditions such as thermal considerations (e.g. don't use OPPx until the temperature drops).h](hXTA default OPP list registered with the OPP library may not cater to all possible situation. The OPP library provides a set of functions to modify the availability of a OPP within the OPP list. This allows SoC frameworks to have fine grained dynamic control of which sets of OPPs are operationally available. These functions are intended to }(hXTA default OPP list registered with the OPP library may not cater to all possible situation. The OPP library provides a set of functions to modify the availability of a OPP within the OPP list. This allows SoC frameworks to have fine grained dynamic control of which sets of OPPs are operationally available. These functions are intended to hjhhhNhNubj)}(h *temporarily*h]h temporarily}(hhhjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhp remove an OPP in conditions such as thermal considerations (e.g. don’t use OPPx until the temperature drops).}(hn remove an OPP in conditions such as thermal considerations (e.g. don't use OPPx until the temperature drops).hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(hhh](j)}(h:WARNING: Do not use these functions in interrupt context. h](j)}(hWARNING:h]hWARNING:}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhjubj)}(hhh]h)}(h0Do not use these functions in interrupt context.h]h0Do not use these functions in interrupt context.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhKhjubj)}(hXTdev_pm_opp_enable Make a OPP available for operation. Example: Lets say that 1GHz OPP is to be made available only if the SoC temperature is lower than a certain threshold. The SoC framework implementation might choose to do something as follows:: if (cur_temp < temp_low_thresh) { /* Enable 1GHz if it was disabled */ opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false); dev_pm_opp_put(opp); /* just error check */ if (!IS_ERR(opp)) ret = dev_pm_opp_enable(dev, 1000000000); else goto try_something_else; } h](j)}(hdev_pm_opp_enableh]hdev_pm_opp_enable}(hj.hj,hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhj(ubj)}(hhh](h)}(hMake a OPP available for operation. Example: Lets say that 1GHz OPP is to be made available only if the SoC temperature is lower than a certain threshold. The SoC framework implementation might choose to do something as follows::h]hMake a OPP available for operation. Example: Lets say that 1GHz OPP is to be made available only if the SoC temperature is lower than a certain threshold. The SoC framework implementation might choose to do something as follows:}(hMake a OPP available for operation. Example: Lets say that 1GHz OPP is to be made available only if the SoC temperature is lower than a certain threshold. The SoC framework implementation might choose to do something as follows:hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj:ubj)}(hXPif (cur_temp < temp_low_thresh) { /* Enable 1GHz if it was disabled */ opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false); dev_pm_opp_put(opp); /* just error check */ if (!IS_ERR(opp)) ret = dev_pm_opp_enable(dev, 1000000000); else goto try_something_else; }h]hXPif (cur_temp < temp_low_thresh) { /* Enable 1GHz if it was disabled */ opp = dev_pm_opp_find_freq_exact(dev, 1000000000, false); dev_pm_opp_put(opp); /* just error check */ if (!IS_ERR(opp)) ret = dev_pm_opp_enable(dev, 1000000000); else goto try_something_else; }}(hhhjLubah}(h]h ]h"]h$]h&]j juh1jhhhKhj:ubeh}(h]h ]h"]h$]h&]uh1jhj(ubeh}(h]h ]h"]h$]h&]uh1jhhhKhjhhubj)}(hXIdev_pm_opp_disable Make an OPP to be not available for operation Example: Lets say that 1GHz OPP is to be disabled if the temperature exceeds a threshold value. The SoC framework implementation might choose to do something as follows:: if (cur_temp > temp_high_thresh) { /* Disable 1GHz if it was enabled */ opp = dev_pm_opp_find_freq_exact(dev, 1000000000, true); dev_pm_opp_put(opp); /* just error check */ if (!IS_ERR(opp)) ret = dev_pm_opp_disable(dev, 1000000000); else goto try_something_else; } h](j)}(hdev_pm_opp_disableh]hdev_pm_opp_disable}(hjlhjjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhjfubj)}(hhh](h)}(hMake an OPP to be not available for operation Example: Lets say that 1GHz OPP is to be disabled if the temperature exceeds a threshold value. The SoC framework implementation might choose to do something as follows::h]hMake an OPP to be not available for operation Example: Lets say that 1GHz OPP is to be disabled if the temperature exceeds a threshold value. The SoC framework implementation might choose to do something as follows:}(hMake an OPP to be not available for operation Example: Lets say that 1GHz OPP is to be disabled if the temperature exceeds a threshold value. The SoC framework implementation might choose to do something as follows:hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjxubj)}(hXQif (cur_temp > temp_high_thresh) { /* Disable 1GHz if it was enabled */ opp = dev_pm_opp_find_freq_exact(dev, 1000000000, true); dev_pm_opp_put(opp); /* just error check */ if (!IS_ERR(opp)) ret = dev_pm_opp_disable(dev, 1000000000); else goto try_something_else; }h]hXQif (cur_temp > temp_high_thresh) { /* Disable 1GHz if it was enabled */ opp = dev_pm_opp_find_freq_exact(dev, 1000000000, true); dev_pm_opp_put(opp); /* just error check */ if (!IS_ERR(opp)) ret = dev_pm_opp_disable(dev, 1000000000); else goto try_something_else; }}(hhhjubah}(h]h ]h"]h$]h&]j juh1jhhhKhjxubeh}(h]h ]h"]h$]h&]uh1jhjfubeh}(h]h ]h"]h$]h&]uh1jhhhKhjhhubeh}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]"opp-availability-control-functionsah ]h"]%4. opp availability control functionsah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h5. OPP Data Retrieval Functionsh]h5. OPP Data Retrieval Functions}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hX8Since OPP library abstracts away the OPP information, a set of functions to pull information from the dev_pm_opp structure is necessary. Once an OPP pointer is retrieved using the search functions, the following functions can be used by SoC framework to retrieve the information represented inside the OPP layer.h]hX8Since OPP library abstracts away the OPP information, a set of functions to pull information from the dev_pm_opp structure is necessary. Once an OPP pointer is retrieved using the search functions, the following functions can be used by SoC framework to retrieve the information represented inside the OPP layer.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(hhh](j)}(hX2dev_pm_opp_get_voltage Retrieve the voltage represented by the opp pointer. Example: At a cpufreq transition to a different frequency, SoC framework requires to set the voltage represented by the OPP using the regulator framework to the Power Management chip providing the voltage:: soc_switch_to_freq_voltage(freq) { /* do things */ opp = dev_pm_opp_find_freq_ceil(dev, &freq); v = dev_pm_opp_get_voltage(opp); dev_pm_opp_put(opp); if (v) regulator_set_voltage(.., v); /* do other things */ } h](j)}(hdev_pm_opp_get_voltageh]hdev_pm_opp_get_voltage}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhMhjubj)}(hhh](h)}(hXRetrieve the voltage represented by the opp pointer. Example: At a cpufreq transition to a different frequency, SoC framework requires to set the voltage represented by the OPP using the regulator framework to the Power Management chip providing the voltage::h]hXRetrieve the voltage represented by the opp pointer. Example: At a cpufreq transition to a different frequency, SoC framework requires to set the voltage represented by the OPP using the regulator framework to the Power Management chip providing the voltage:}(hXRetrieve the voltage represented by the opp pointer. Example: At a cpufreq transition to a different frequency, SoC framework requires to set the voltage represented by the OPP using the regulator framework to the Power Management chip providing the voltage:hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubj)}(hX soc_switch_to_freq_voltage(freq) { /* do things */ opp = dev_pm_opp_find_freq_ceil(dev, &freq); v = dev_pm_opp_get_voltage(opp); dev_pm_opp_put(opp); if (v) regulator_set_voltage(.., v); /* do other things */ }h]hX soc_switch_to_freq_voltage(freq) { /* do things */ opp = dev_pm_opp_find_freq_ceil(dev, &freq); v = dev_pm_opp_get_voltage(opp); dev_pm_opp_put(opp); if (v) regulator_set_voltage(.., v); /* do other things */ }}(hhhjubah}(h]h ]h"]h$]h&]j juh1jhhhMhjubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhMhjubj)}(hXdev_pm_opp_get_freq Retrieve the freq represented by the opp pointer. Example: Lets say the SoC framework uses a couple of helper functions we could pass opp pointers instead of doing additional parameters to handle quiet a bit of data parameters:: soc_cpufreq_target(..) { /* do things.. */ max_freq = ULONG_MAX; max_opp = dev_pm_opp_find_freq_floor(dev,&max_freq); requested_opp = dev_pm_opp_find_freq_ceil(dev,&freq); if (!IS_ERR(max_opp) && !IS_ERR(requested_opp)) r = soc_test_validity(max_opp, requested_opp); dev_pm_opp_put(max_opp); dev_pm_opp_put(requested_opp); /* do other things */ } soc_test_validity(..) { if(dev_pm_opp_get_voltage(max_opp) < dev_pm_opp_get_voltage(requested_opp)) return -EINVAL; if(dev_pm_opp_get_freq(max_opp) < dev_pm_opp_get_freq(requested_opp)) return -EINVAL; /* do things.. */ } h](j)}(hdev_pm_opp_get_freqh]hdev_pm_opp_get_freq}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhM)hjubj)}(hhh](h)}(hRetrieve the freq represented by the opp pointer. Example: Lets say the SoC framework uses a couple of helper functions we could pass opp pointers instead of doing additional parameters to handle quiet a bit of data parameters::h]hRetrieve the freq represented by the opp pointer. Example: Lets say the SoC framework uses a couple of helper functions we could pass opp pointers instead of doing additional parameters to handle quiet a bit of data parameters:}(hRetrieve the freq represented by the opp pointer. Example: Lets say the SoC framework uses a couple of helper functions we could pass opp pointers instead of doing additional parameters to handle quiet a bit of data parameters:hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj$ubj)}(hXsoc_cpufreq_target(..) { /* do things.. */ max_freq = ULONG_MAX; max_opp = dev_pm_opp_find_freq_floor(dev,&max_freq); requested_opp = dev_pm_opp_find_freq_ceil(dev,&freq); if (!IS_ERR(max_opp) && !IS_ERR(requested_opp)) r = soc_test_validity(max_opp, requested_opp); dev_pm_opp_put(max_opp); dev_pm_opp_put(requested_opp); /* do other things */ } soc_test_validity(..) { if(dev_pm_opp_get_voltage(max_opp) < dev_pm_opp_get_voltage(requested_opp)) return -EINVAL; if(dev_pm_opp_get_freq(max_opp) < dev_pm_opp_get_freq(requested_opp)) return -EINVAL; /* do things.. */ }h]hXsoc_cpufreq_target(..) { /* do things.. */ max_freq = ULONG_MAX; max_opp = dev_pm_opp_find_freq_floor(dev,&max_freq); requested_opp = dev_pm_opp_find_freq_ceil(dev,&freq); if (!IS_ERR(max_opp) && !IS_ERR(requested_opp)) r = soc_test_validity(max_opp, requested_opp); dev_pm_opp_put(max_opp); dev_pm_opp_put(requested_opp); /* do other things */ } soc_test_validity(..) { if(dev_pm_opp_get_voltage(max_opp) < dev_pm_opp_get_voltage(requested_opp)) return -EINVAL; if(dev_pm_opp_get_freq(max_opp) < dev_pm_opp_get_freq(requested_opp)) return -EINVAL; /* do things.. */ }}(hhhj6ubah}(h]h ]h"]h$]h&]j juh1jhhhMhj$ubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhM)hjhhubj)}(hX dev_pm_opp_get_opp_count Retrieve the number of available opps for a device Example: Lets say a co-processor in the SoC needs to know the available frequencies in a table, the main processor can notify as following:: soc_notify_coproc_available_frequencies() { /* Do things */ num_available = dev_pm_opp_get_opp_count(dev); speeds = kcalloc(num_available, sizeof(u32), GFP_KERNEL); /* populate the table in increasing order */ freq = 0; while (!IS_ERR(opp = dev_pm_opp_find_freq_ceil(dev, &freq))) { speeds[i] = freq; freq++; i++; dev_pm_opp_put(opp); } soc_notify_coproc(AVAILABLE_FREQs, speeds, num_available); /* Do other things */ } h](j)}(hdev_pm_opp_get_opp_counth]hdev_pm_opp_get_opp_count}(hjVhjThhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhM@hjPubj)}(hhh](h)}(hRetrieve the number of available opps for a device Example: Lets say a co-processor in the SoC needs to know the available frequencies in a table, the main processor can notify as following::h]hRetrieve the number of available opps for a device Example: Lets say a co-processor in the SoC needs to know the available frequencies in a table, the main processor can notify as following:}(hRetrieve the number of available opps for a device Example: Lets say a co-processor in the SoC needs to know the available frequencies in a table, the main processor can notify as following:hjehhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM,hjbubj)}(hXsoc_notify_coproc_available_frequencies() { /* Do things */ num_available = dev_pm_opp_get_opp_count(dev); speeds = kcalloc(num_available, sizeof(u32), GFP_KERNEL); /* populate the table in increasing order */ freq = 0; while (!IS_ERR(opp = dev_pm_opp_find_freq_ceil(dev, &freq))) { speeds[i] = freq; freq++; i++; dev_pm_opp_put(opp); } soc_notify_coproc(AVAILABLE_FREQs, speeds, num_available); /* Do other things */ }h]hXsoc_notify_coproc_available_frequencies() { /* Do things */ num_available = dev_pm_opp_get_opp_count(dev); speeds = kcalloc(num_available, sizeof(u32), GFP_KERNEL); /* populate the table in increasing order */ freq = 0; while (!IS_ERR(opp = dev_pm_opp_find_freq_ceil(dev, &freq))) { speeds[i] = freq; freq++; i++; dev_pm_opp_put(opp); } soc_notify_coproc(AVAILABLE_FREQs, speeds, num_available); /* Do other things */ }}(hhhjtubah}(h]h ]h"]h$]h&]j juh1jhhhM0hjbubeh}(h]h ]h"]h$]h&]uh1jhjPubeh}(h]h ]h"]h$]h&]uh1jhhhM@hjhhubeh}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]opp-data-retrieval-functionsah ]h"]5. opp data retrieval functionsah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h6. Data Structuresh]h6. Data Structures}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMCubh)}(hTypically an SoC contains multiple voltage domains which are variable. Each domain is represented by a device pointer. The relationship to OPP can be represented as follows::h]hTypically an SoC contains multiple voltage domains which are variable. Each domain is represented by a device pointer. The relationship to OPP can be represented as follows:}(hTypically an SoC contains multiple voltage domains which are variable. Each domain is represented by a device pointer. The relationship to OPP can be represented as follows:hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMDhjhhubj)}(hSoC |- device 1 | |- opp 1 (availability, freq, voltage) | |- opp 2 .. ... ... | `- opp n .. |- device 2 ... `- device mh]hSoC |- device 1 | |- opp 1 (availability, freq, voltage) | |- opp 2 .. ... ... | `- opp n .. |- device 2 ... `- device m}(hhhjubah}(h]h ]h"]h$]h&]j juh1jhhhMHhjhhubh)}(hXOPP library maintains a internal list that the SoC framework populates and accessed by various functions as described above. However, the structures representing the actual OPPs and domains are internal to the OPP library itself to allow for suitable abstraction reusable across systems.h]hXOPP library maintains a internal list that the SoC framework populates and accessed by various functions as described above. However, the structures representing the actual OPPs and domains are internal to the OPP library itself to allow for suitable abstraction reusable across systems.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMRhjhhubj)}(hhh](j)}(hXstruct dev_pm_opp The internal data structure of OPP library which is used to represent an OPP. In addition to the freq, voltage, availability information, it also contains internal book keeping information required for the OPP library to operate on. Pointer to this structure is provided back to the users such as SoC framework to be used as a identifier for OPP in the interactions with OPP layer. WARNING: The struct dev_pm_opp pointer should not be parsed or modified by the users. The defaults of for an instance is populated by dev_pm_opp_add, but the availability of the OPP can be modified by dev_pm_opp_enable/disable functions. h](j)}(hstruct dev_pm_opph]hstruct dev_pm_opp}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhMchjubj)}(hhh](h)}(hX~The internal data structure of OPP library which is used to represent an OPP. In addition to the freq, voltage, availability information, it also contains internal book keeping information required for the OPP library to operate on. Pointer to this structure is provided back to the users such as SoC framework to be used as a identifier for OPP in the interactions with OPP layer.h]hX~The internal data structure of OPP library which is used to represent an OPP. In addition to the freq, voltage, availability information, it also contains internal book keeping information required for the OPP library to operate on. Pointer to this structure is provided back to the users such as SoC framework to be used as a identifier for OPP in the interactions with OPP layer.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMXhjubj)}(hhh]j)}(hWARNING: The struct dev_pm_opp pointer should not be parsed or modified by the users. The defaults of for an instance is populated by dev_pm_opp_add, but the availability of the OPP can be modified by dev_pm_opp_enable/disable functions. h](j)}(hWARNING:h]hWARNING:}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhMchjubj)}(hhh]h)}(hThe struct dev_pm_opp pointer should not be parsed or modified by the users. The defaults of for an instance is populated by dev_pm_opp_add, but the availability of the OPP can be modified by dev_pm_opp_enable/disable functions.h]hThe struct dev_pm_opp pointer should not be parsed or modified by the users. The defaults of for an instance is populated by dev_pm_opp_add, but the availability of the OPP can be modified by dev_pm_opp_enable/disable functions.}(hjhjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM`hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhMchjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhhhMchjubj)}(hstruct device This is used to identify a domain to the OPP layer. The nature of the device and its implementation is left to the user of OPP library such as the SoC framework. h](j)}(h struct deviceh]h struct device}(hjHhjFhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhMhhjBubj)}(hhh]h)}(hThis is used to identify a domain to the OPP layer. The nature of the device and its implementation is left to the user of OPP library such as the SoC framework.h]hThis is used to identify a domain to the OPP layer. The nature of the device and its implementation is left to the user of OPP library such as the SoC framework.}(hjYhjWhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMfhjTubah}(h]h ]h"]h$]h&]uh1jhjBubeh}(h]h ]h"]h$]h&]uh1jhhhMhhjhhubeh}(h]h ]h"]h$]h&]uh1jhjhhhNhNubh)}(hZOverall, in a simplistic view, the data structure operations is represented as following::h]hYOverall, in a simplistic view, the data structure operations is represented as following:}(hYOverall, in a simplistic view, the data structure operations is represented as following:hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMjhjhhubj)}(hXInitialization / modification: +-----+ /- dev_pm_opp_enable dev_pm_opp_add --> | opp | <------- | +-----+ \- dev_pm_opp_disable \-------> domain_info(device) Search functions: /-- dev_pm_opp_find_freq_ceil ---\ +-----+ domain_info<---- dev_pm_opp_find_freq_exact -----> | opp | \-- dev_pm_opp_find_freq_floor ---/ +-----+ Retrieval functions: +-----+ /- dev_pm_opp_get_voltage | opp | <--- +-----+ \- dev_pm_opp_get_freq domain_info <- dev_pm_opp_get_opp_counth]hXInitialization / modification: +-----+ /- dev_pm_opp_enable dev_pm_opp_add --> | opp | <------- | +-----+ \- dev_pm_opp_disable \-------> domain_info(device) Search functions: /-- dev_pm_opp_find_freq_ceil ---\ +-----+ domain_info<---- dev_pm_opp_find_freq_exact -----> | opp | \-- dev_pm_opp_find_freq_floor ---/ +-----+ Retrieval functions: +-----+ /- dev_pm_opp_get_voltage | opp | <--- +-----+ \- dev_pm_opp_get_freq domain_info <- dev_pm_opp_get_opp_count}(hhhjubah}(h]h ]h"]h$]h&]j juh1jhhhMmhjhhubeh}(h]data-structuresah ]h"]6. data structuresah$]h&]uh1hhhhhhhhMCubeh}(h](operating-performance-points-opp-libraryah ]h"]*operating performance points (opp) libraryah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjerror_encodingUTF-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confapep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacefile_insertion_enabled raw_enabledKline_length_limitM'syntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_link embed_imagesenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(jjj|jyjjjtjqjljij8j5jjjjjjjju nametypes}(jNj|NjNjtNjlNj8NjNjNjNjNuh}(jhjyjjj jqjjijj5jjj;jjjjjju footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages]hsystem_message)}(hhh]h)}(h:Enumerated list start value not ordinal-1: "C" (ordinal 3)h]h>Enumerated list start value not ordinal-1: “C” (ordinal 3)}(hhhj/hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj,ubah}(h]h ]h"]h$]h&]levelKtypeINFOsourcehlineKuh1j*hhhhhhhKubatransform_messages] transformerN include_log] decorationNhhub.