Adaptation/GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita
changeset 15 307f4279f433
equal deleted inserted replaced
14:578be2adaf3e 15:307f4279f433
       
     1 <?xml version="1.0" encoding="utf-8"?>
       
     2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
       
     3 <!-- This component and the accompanying materials are made available under the terms of the License 
       
     4 "Eclipse Public License v1.0" which accompanies this distribution, 
       
     5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
       
     6 <!-- Initial Contributors:
       
     7     Nokia Corporation - initial contribution.
       
     8 Contributors: 
       
     9 -->
       
    10 <!DOCTYPE concept
       
    11   PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
       
    12 <concept id="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE" xml:lang="en"><title>Power
       
    13 Resource Manager (PRM)</title><shortdesc>Describes the Power Resource Manager.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    14 <ul>
       
    15 <li id="GUID-16097C0C-7354-5B9E-B405-1785F7511878"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-2F312E19-71BC-5396-996F-EA48EAEDF2F2">Introduction</xref>  </p> </li>
       
    16 <li id="GUID-9780C08F-CBA2-5C72-B6D2-C751F3CF18C7"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-F830F456-A436-5025-821D-21855C7AE056">Concepts</xref>  </p> </li>
       
    17 <li id="GUID-FBAB865C-C003-504A-A8DB-058C9BCA2D20"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-5C3F684C-D4F6-5343-AFFC-009B70210F9C">User-side</xref>  </p> </li>
       
    18 <li id="GUID-6FE7DE11-1781-5F85-99B6-83B544148D3A"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-DE8EE84C-D46F-504A-8254-C212B7C5D5C1">Kernel-side</xref>  </p> </li>
       
    19 </ul>
       
    20 <section id="GUID-2F312E19-71BC-5396-996F-EA48EAEDF2F2"><title>Introduction</title> <p>The
       
    21 Power Resource Manager (PRM) integrates the Symbian device driver with existing
       
    22 power control and functions used for resource state changing and querying.
       
    23 It defines an exported API that device drivers and other users of power resources
       
    24 (represented by kernel-side components) can use to control the state of power
       
    25 resources. The PRM assists the development of device drivers by removing the
       
    26 need to understand the complexities of platform specific power resource management
       
    27 by providing a simple to use generic framework. </p> <p>The PRM also allows
       
    28 user-side clients to gain access to the services. Clients of the PRM can: </p> <ul>
       
    29 <li id="GUID-1F23255C-A662-5755-A4C7-387A57FEB2C3"><p>request information
       
    30 on the clients and resources registered with PRM </p> </li>
       
    31 <li id="GUID-3E6406A9-757A-53EE-AE1C-839CA87C1120"><p>get the current state
       
    32 of the resources </p> </li>
       
    33 <li id="GUID-4FD981E6-EA1E-5E49-83D1-CC017BB753FE"><p>request changes to the
       
    34 state of power resources </p> </li>
       
    35 <li id="GUID-3ED36326-E905-53A1-907F-51DD6846B5BC"><p>request notification
       
    36 of changes (i.e. power-down or change clock frequency) to the power resources
       
    37 that they depend on. </p> </li>
       
    38 </ul> <p>The following diagram shows the generic and customisable parts of
       
    39 the framework: </p> <ul>
       
    40 <li id="GUID-D4A341D5-84C4-543E-A392-426B6E9905FB"><p>exported kernel level
       
    41 API (<xref href="GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00.dita"><apiname>PowerResourceManager</apiname></xref>) </p> </li>
       
    42 <li id="GUID-D0A636FF-9520-5CA1-82EF-E7B7AF645063"><p>base virtual class for
       
    43 Power Resource Controller (<xref href="GUID-46F2174F-0206-345B-8C5D-F8B5763652E0.dita"><apiname>DPowerResourceController</apiname></xref>) </p> </li>
       
    44 <li id="GUID-C7C11053-E43B-5A1F-B5E7-6BBE36C02C1D"><p>PDD required for user-side
       
    45 proxy client </p> </li>
       
    46 <li id="GUID-404A1110-40E3-5E28-8C04-19232FB047B5"><p>platform specific implementation
       
    47 of resource control at the level of register interface to hardware resource
       
    48 controller (<codeph>DXXXPowerResourceController</codeph>) </p> </li>
       
    49 </ul> <fig id="GUID-72B93745-2089-526F-8AF5-0E7522CADBEC">
       
    50 <image href="GUID-99C4FCCC-9E8B-51CC-85F8-F03BE18DF19E_d0e82580_href.png" placement="inline"/>
       
    51 </fig> </section>
       
    52 <section id="GUID-F830F456-A436-5025-821D-21855C7AE056"><title>Concepts</title> <ul>
       
    53 <li id="GUID-3F2C2733-A287-5AB8-A695-4863EBA1FF52"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-4CC0C003-1952-5CAD-A7C5-163C5DDA52C8">Power resources</xref> </p> </li>
       
    54 <li id="GUID-D4CDE568-00CA-50BD-A3CD-C12523B81180"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-8BBC100D-BB97-5675-AA2F-E730A0DF4B26">Clients</xref>  </p> </li>
       
    55 </ul> <p id="GUID-4CC0C003-1952-5CAD-A7C5-163C5DDA52C8"><b>Power resources</b> </p> <p>A
       
    56 power resource is anything that has an effect on power consumption. These
       
    57 are typically platform specific and either physical or logical. Physical power
       
    58 resources are provided by hardware: for example, clocks, outputs from voltage
       
    59 regulators, switched power domains and performance levels. Logical power resources
       
    60 do not directly map to hardware components, but their state has an effect
       
    61 on overall power consumption. In this category we include, for example, shared
       
    62 buses and devices that provide services to other components. </p> <p>Power
       
    63 resources can be further categorised based on: </p> <ul>
       
    64 <li id="GUID-CF16C658-A90F-5378-825B-CEC9C8D2DF1B"><p>Number of <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-8BBC100D-BB97-5675-AA2F-E730A0DF4B26">clients</xref>  </p> <p>A power resource can have a single user or it can
       
    65 be shared. There is no limit to the number of clients sharing a resource.
       
    66 If the resource is shared, then a request system is used. This comprises a
       
    67 list of <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-F47D2098-16A7-5590-A68A-7AE4B2DAB462">client
       
    68 level objects</xref>, one for each client requesting a level on the resource.
       
    69 The resource level is determined by a set of rules which govern whether a
       
    70 request is accepted or declined. </p> </li>
       
    71 <li id="GUID-B5BBF273-19B4-5A3B-9B85-792837D70258"><p>States </p> <p>The <xref href="GUID-1D3E61BD-C09D-51FD-A10B-22392FDAEFEC.dita#GUID-1D3E61BD-C09D-51FD-A10B-22392FDAEFEC/GUID-1817A738-2351-526F-881D-7EB479E93C4C">resource
       
    72 state</xref> may be binary, multi-level or multi-property. A binary state
       
    73 is either On or Off and a multi-level state can change either discretely or
       
    74 continuously between a minimum (which could be Off) and a maximum value (which
       
    75 could be fully On). </p> <p>A multi-property resource has different properties
       
    76 across different portions of the operating curve. For example, the level may
       
    77 be controllable within the ‘operational’ part of that curve but have different
       
    78 discrete fixed states for the ‘idle’ or ‘sleep’ modes of operation. </p> </li>
       
    79 <li id="GUID-FC70680E-1595-54FC-A611-295688470176"><p>Execution time </p> <p>The
       
    80 execution time of a resource can be either instantaneous or long latency.
       
    81 An instantaneous resource can be operated almost immediately (no longer than
       
    82 a few system clock cycles, comparable to a CPU instruction execution time).
       
    83 Operations on long latency resources take a significant time to complete (a
       
    84 non-negligible amount of CPU clock cycles). </p> <p>Power resources may be
       
    85 long latency for state change operations and instantaneous for obtaining the
       
    86 current state. This is typically the case of a PLL (Phase Locked Loop) device
       
    87 (<xref href="http://en.wikipedia.org/wiki/Phase-locked_loop" scope="external">definition
       
    88 from Wikipedia</xref>), which requires time to stabilise after a frequency
       
    89 change is initiated but whose current output frequency can be read from a
       
    90 register. <b>Note</b>: instantaneous operations may pre-empt operations on
       
    91 long latency resources, and requests to get the state of a shared resource
       
    92 may be issued while a state change is underway. If the read operation is instantaneous
       
    93 and the change is long latency, care must be taken (at the PSL level) to not
       
    94 return inconsistent values. </p> <p>Other power resources may be long latency
       
    95 on both state change and state read operations. This is typically the case
       
    96 for any resources accessed through an inter-IC bus (even if their operation
       
    97 is instantaneous). </p> </li>
       
    98 <li id="GUID-8ABE5ED4-C2CB-557E-BF53-9630567AE7DC"><p>Resource <i>sense</i>  </p> <p>Each
       
    99 client sharing a resource may have a different requirement on its state. The
       
   100 resource <i>sense</i> is used to determine whose requirement prevails. </p> <table id="GUID-BECBC606-95E8-5C6F-BC71-2DA2AA838C88">
       
   101 <tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>
       
   102 <tbody>
       
   103 <row>
       
   104 <entry><p>Positive sense </p> </entry>
       
   105 <entry><p>Can have their value increased without affecting their sharers. </p> <p>The
       
   106 level is set to the highest level that is requested. The highest requirement
       
   107 for binary resources is the On state. </p> </entry>
       
   108 </row>
       
   109 <row>
       
   110 <entry><p>Negative sense </p> </entry>
       
   111 <entry><p>Can have their value decreased without affecting their sharers. </p> <p>The
       
   112 level is set to the lowest level that is requested. The lowest requirement
       
   113 for binary resources is the Off state. </p> </entry>
       
   114 </row>
       
   115 <row>
       
   116 <entry><p>Custom sense </p> </entry>
       
   117 <entry><p>May be increased or decreased freely by some privileged sharers
       
   118 but not by others, which are bound by the requirement of the privileged sharers. </p> <p>The
       
   119 decision to change the prevailing level (or binary state) depends on the privileges
       
   120 of the client and past usage of the resource. This decision is made by the
       
   121 PSL <xref href="GUID-B1CE51BC-B452-5FC9-9C00-35447AF40671.dita#GUID-B1CE51BC-B452-5FC9-9C00-35447AF40671/GUID-9526B472-00ED-583A-8BFC-C02363D4DFA2">custom
       
   122 function</xref> implementation. </p> </entry>
       
   123 </row>
       
   124 </tbody>
       
   125 </tgroup>
       
   126 </table> </li>
       
   127 <li id="GUID-CF996934-F142-5A79-BE7B-D91FE3109D95"><p>Static or Dynamic </p> <p>Most
       
   128 power resources are known at device creation time, so their control should
       
   129 be addressed by such components as the Variant or ASSP. These resources are
       
   130 registered during the creation of the Resource Controller; these are static
       
   131 resources. Resources controlled by device drivers (internal or external) are
       
   132 only registered at driver-creation time using the registration and deregistration
       
   133 API provided by the PRM; these are known as dynamic resources. </p> <p> <b>Note</b>:
       
   134 Dynamic resources are only available when you use the extended library. See <xref href="GUID-2ECF13A1-9D56-5740-A09F-8267E6A45DD9.dita#GUID-2ECF13A1-9D56-5740-A09F-8267E6A45DD9/GUID-0F328055-DBCE-5B2B-A1EB-77F73BA1FC82">setup
       
   135 and configuration</xref>. </p> </li>
       
   136 </ul> <p>Physical resources may belong to one or more of these categories,
       
   137 for example, a multilevel resource may be shared between different clients
       
   138 and take a significant time to change state (long latency). </p> <p>External
       
   139 devices may include and control their own power resources. In some cases,
       
   140 an external device can function as a bus expander, allowing other devices
       
   141 to be connected, and eventually share the power resources it controls. </p> <p id="GUID-121C14E3-D446-565E-AAAE-C43C131ACD3C"><b>Caching the prevailing level</b> </p> <p>The
       
   142 PRM caches the prevailing level of each resource as well as the client that
       
   143 requested it. The cached state is guaranteed to be the state that the resource
       
   144 was in when the last request to change or read the state from its hardware
       
   145 was issued. </p> <p>On resource state read operations, the PRM allows clients
       
   146 to select the cached state instead of the current state of the hardware resource.
       
   147 A cached state read is always an instantaneous operation executed in the context
       
   148 of the calling client thread (even for long latency resources). </p> <p>However,
       
   149 care must be taken as the cached state may not be the state the resource is
       
   150 at that moment. For example, a resource can be non-sticky: when it is turned
       
   151 on it stays on during an operation but then automatically switches itself
       
   152 off. </p> <p>The consistency of the cached state relies on all resource state
       
   153 operations being requested through the <xref href="GUID-4804B6E0-9199-5F3E-984A-4B00B3984E45.dita">Power
       
   154 Resource Controller</xref>. </p> <p><b>Dynamic
       
   155 resources</b> </p> <p>A generic layer provides basic functionality for static
       
   156 resources an extended version of the PRM provides APIs for dynamic resources
       
   157 and resource dependencies. These dynamic resource and resource dependent APIs
       
   158 are only available through the extended library <filepath>resmanextended.lib</filepath>. </p> <p>A
       
   159 dynamic resource is registered with the PRM using <xref href="GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00.dita#GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00/GUID-1AB3CD4A-2BD3-366A-9359-791B3BBC9127"><apiname>PowerResourceManager::RegisterDynamicResource()</apiname></xref>.
       
   160 This function is also used to register a dynamic resource that supports dependencies
       
   161 between resources. </p> <codeblock id="GUID-0325A795-F99E-5098-947E-24A10C5D5416" xml:space="preserve">TInt RegisterDynamicResource(TUint aClientId, DDynamicPowerResource* aResource, TUint&amp; aResourceId)</codeblock> <p>Pass the ID of the client that requests the dynamic resource and the
       
   162 dynamic resource (<xref href="GUID-CA01041D-8FD6-3B5B-BB5D-A5159DF7C9AB.dita"><apiname>DDynamicPowerResource</apiname></xref>) to register. The
       
   163 PRM sets <codeph>aResourceId</codeph> to the resource ID of this resource.
       
   164 Dynamic resources that support dependencies are derived from the class <xref href="GUID-6B224A9F-D2B9-3289-922D-766EF093FCD6.dita"><apiname>DDynamicPowerResourceD</apiname></xref>. </p> <p><b>Deregistering a dynamic resource</b> </p> <p>Use <xref href="GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00.dita#GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00/GUID-8E388C73-F26D-30F7-9CA9-5ED0439E4C4D"><apiname>PowerResourceManager::DeRegisterDynamicResource()</apiname></xref> to
       
   165 deregister a dynamic resource from the PRM. You can also use the function
       
   166 to deregister a dynamic resource that supports a dependency. </p> <codeblock id="GUID-89FC49A8-FC66-5B8C-A82C-18987E2BA0E7" xml:space="preserve">TInt DeRegisterDynamicResource(TUint aClientId, TUint aResourceId, TInt* aState)</codeblock> <p> <codeph>aState</codeph> is a pointer to the final state that the resource is set
       
   167 to before deregistration if this value is NULL the state of the resource is
       
   168 changed to its default. </p> <p><b>Changing resource state on a dynamic resource </b> </p> <p>Because a dynamic
       
   169 resource can deregister from the PRM it is necessary to indicate to clients
       
   170 that this has happened. Any remaining notification requests are completed
       
   171 with a -2 in the client field of the callback function. This indicates that
       
   172 this notification is because the resource has been deregistered and not because
       
   173 the notification conditions have been met. When a client recieves a notification
       
   174 of this type the request notification should be cancelled using <xref href="GUID-51CAD2A1-C978-3EBD-984F-4C5C59D68885.dita"><apiname>CancelNotification()</apiname></xref>. </p> <p id="GUID-473BBE32-6831-52BE-8752-CB6DBBBABD2C"><b>Resource dependencies</b> </p> <p>A
       
   175 resource may register a dependency on another resource. At least one of the
       
   176 resources must be a dynamic resource. Request a dependency between resources
       
   177 with <xref href="GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00.dita#GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00/GUID-9C1BF3D5-6F5D-3BEF-9DF0-A5FED85CC718"><apiname>PowerResourceManager::RegisterResourceDependency()</apiname></xref>. </p> <codeblock id="GUID-EC9D5125-BC25-5196-88E7-3245B3B62AF4" xml:space="preserve">TInt RegisterResourceDependency(TUint aClientId, SResourceDependencyInfo* aResDependecyInfo1, SResourceDependencyInfo* aResDependencyInfo2)</codeblock> <p>This function is passed the ID of the client that sets the resource dependency
       
   178 and the dependency information of the resource (<xref href="GUID-88FE83B0-35A1-3913-B38F-1FB925FFE96C.dita"><apiname>SResourceDependencyInfo</apiname></xref>). <codeph>SResourceDependencyInfo</codeph> contains
       
   179 the resource ID and the priority of the dependency. </p> <p>The kernel will
       
   180 panic if a closed loop dependency is found for the specified dependency or
       
   181 if a resource with same dependency priority is already registered. </p> <p>Use <xref href="GUID-A3D65EA0-70B1-35E9-998D-EC4C1A294AB8.dita"><apiname>GetNumDependentsForResource()</apiname></xref> to
       
   182 retrieve the number of resources that depend on the specified resource directly
       
   183 and <xref href="GUID-9C582DAB-2C0B-331D-BA8D-CED067289055.dita"><apiname>GetDependentsIdForResource()</apiname></xref> to return the IDs of all
       
   184 the dependent resources. </p> <p><b>Deregistering
       
   185 resource dependencies</b> </p> <p>Use <xref href="GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00.dita#GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00/GUID-127E979F-F540-36E2-A759-8ED408E89F38"><apiname>PowerResourceManager::DeRegisterResourceDependency()</apiname></xref> to
       
   186 remove a dependency. This function takes the ID of the client that requests
       
   187 the deregistration of the resource dependency and the IDs of the linked resources. </p> <codeblock id="GUID-561502A3-2603-5090-98F3-6BF714C8514B" xml:space="preserve">TInt DeRegisterResourceDependency(TUint aClientId, TUint aResourceId1, TUint aResourceId2)</codeblock> <p> <b>Note</b>: These functions are only available when you use the extended
       
   188 library. </p> <p><b>Changing
       
   189 resource state on a dependent resource</b> </p> <p>A resource state can change
       
   190 when the state of any of its dependent resources changes. A state change causes
       
   191 a notification if the requested conditions are met. The client ID in the callback
       
   192 function is updated with the ID of the resource that triggered this resource
       
   193 change (bit 16 of the ID is set for dependency resource; this is used to distinguish
       
   194 between a resource ID and a client ID). </p> <p id="GUID-8BBC100D-BB97-5675-AA2F-E730A0DF4B26"><b>Clients</b> </p> <p>The
       
   195 PRM has both user and kernel-side clients. Kernel-side clients are: </p> <ul>
       
   196 <li id="GUID-7DDBF8D2-80AD-5248-9C8A-2F215E98513E"><p>device drivers </p> </li>
       
   197 <li id="GUID-914A7E0F-9FE5-579A-AEB5-35163D89E450"><p>performance scaling
       
   198 and/or performance monitoring and prediction components </p> </li>
       
   199 </ul> <p>User-side clients are: </p> <ul>
       
   200 <li id="GUID-E1A4D6C3-9EEC-54EB-BEF4-90C3DD65E4A3"><p>user-side system-wide
       
   201 power management framework </p> </li>
       
   202 <li id="GUID-08B28DD8-107E-5142-A887-F685A17915DC"><p>other power-aware servers
       
   203 and power-aware applications </p> </li>
       
   204 </ul> <p>Clients register with the PRM by name. Clients can request to allocate
       
   205 and reserve client level objects and request message objects after registering
       
   206 with PRM. </p> <p id="GUID-F47D2098-16A7-5590-A68A-7AE4B2DAB462"><b>Client level objects</b> </p> <p>Client
       
   207 level objects represent a client requesting a level on a resource. They are
       
   208 used by resources to set the current level of the resource and the current
       
   209 owner of the resource level. </p> <p>Each resource has a doubly linked list
       
   210 on which client level objects are held. When a client requests a level for
       
   211 the first time, a new client level object is added to the list; however, if
       
   212 the client already has an object on the list, this object is adjusted to reflect
       
   213 the change in the required level. </p> <p>The following rules determine whether
       
   214 the change is allowed on positive and negative sense resources: </p> <ul>
       
   215 <li id="GUID-18D734C9-F01A-53D8-9B2B-9DED288F8968"><p>If the requested change
       
   216 is in the direction permitted by the resource sense and would result in exceeding
       
   217 the prevailing level, the change is allowed. </p> <p>The new prevailing level
       
   218 is recorded, and the previous prevailing level and the requirements other
       
   219 clients have on the resource remain on record. </p> </li>
       
   220 <li id="GUID-9901C6DC-D91F-5CB4-BA68-10E941486BBF"><p>If the requested change
       
   221 is not in the direction permitted by the resource sense, but the client requesting
       
   222 the change is the owner of the prevailing level, the resource state changes
       
   223 up to next highest for a positive sense resource, or lowest for a negative
       
   224 sense resource. </p> <p>This value is now the prevailing level and the client
       
   225 that requested it remains the owner of the prevailing level. </p> </li>
       
   226 <li id="GUID-643C8DE3-322C-5C2A-840F-80F02DDFB60D"><p>If the requested change
       
   227 is not in the direction permitted by the resource sense, and the client requesting
       
   228 the change is not the owner of the prevailing level, the change is not allowed. </p> <p>Even
       
   229 though the request was rejected, the client's existing requirement is adjusted
       
   230 to reflect the request. </p> </li>
       
   231 </ul> <p>Prevailing levels are recorded by either adjusting the previous requirement
       
   232 for the client that requested it or, if it is the first time this client requests
       
   233 a level, a new requirement is created. </p> <p id="GUID-8FE4BD6A-6A69-5233-88E2-32837A42A544"><b>Notifications</b> </p> <p>A
       
   234 client may request a state change notification from a resource. Notifications
       
   235 can be conditional or unconditional; conditional notifications specify a threshold
       
   236 on the resources state, which when crossed in the direction specified, triggers
       
   237 the notification. </p> <p>Notifications are always issued post resource change
       
   238 and invoke callback functions executed in the context of the requesting client
       
   239 thread. The process of notifying a client involves queuing a DFC in that clients'
       
   240 thread. The notification object encapsulating the DFC must be created in kernel
       
   241 heap and passed to the notification API by the client that requested the notification.
       
   242 The client may share the same callback function between several notifications,
       
   243 but a unique DFC must be created and queued per notification. </p> <p>Because
       
   244 notifications result in DFCs being queued, it is not possible to guarantee
       
   245 that all changes of resource state are notified. If the resource state changes
       
   246 again before the first DFC runs, a separate notification cannot be generated.
       
   247 It is also not possible to guarantee that by the time the notification callback
       
   248 runs, the resource state is still the same as the state that caused the notification
       
   249 to be issued: it is the responsibility of the driver to read the resource
       
   250 state after receiving a notification. </p> </section>
       
   251 <section id="GUID-5C3F684C-D4F6-5343-AFFC-009B70210F9C"> <title>User-side</title> <ul>
       
   252 <li id="GUID-80696301-3BF7-5DBC-84DB-5961FB6D2F0E"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-B33A80C1-6079-556E-89D7-BC1F2304384D">Introduction</xref>  </p> </li>
       
   253 <li id="GUID-E8D832DE-1879-5508-841D-90D87EE34E02"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-A5D4981F-4B16-5174-A41A-E9EEC70EA62C">Initialisation</xref>  </p> </li>
       
   254 <li id="GUID-59F352F4-2602-59F5-BC3A-71544A092361"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-1DC958F3-7952-56C0-A8BC-F52B2A83BE3C">Getting power resource information</xref>  </p> </li>
       
   255 <li id="GUID-8437EDA3-1E1E-588C-B25D-719EE6921350"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-8BDF9B79-BC05-593C-B39E-C6B8BD26AA2D">Requesting notifications</xref>  </p> </li>
       
   256 <li id="GUID-465111CA-8F3B-52C9-85E9-F81CC0AB87FA"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-ACA22305-8990-54F5-8098-80716F4A5AAE">Changing the state of power resources</xref>  </p> </li>
       
   257 </ul> <p id="GUID-B33A80C1-6079-556E-89D7-BC1F2304384D"><b>Introduction</b> </p> <p>The <xref href="GUID-FD3DEFC1-DA39-3A1A-8E00-A46B34B78899.dita"><apiname>RBusDevResManUs</apiname></xref> user-side
       
   258 API makes relevant PRM functionality available to user-side applications that
       
   259 have power-aware features. </p> <p> <codeph>RBusDevResManUs</codeph> is derived
       
   260 from <xref href="GUID-6FBFA078-8253-3E24-B1F8-5F75E86C3066.dita"><apiname>RBusLogicalChannel</apiname></xref>, the user-side handle to a logical
       
   261 channel base class, and presents the user-side interface to a kernel-side
       
   262 LDD. The LDD is built as <filepath>resman.ldd</filepath>. </p> <p>The API
       
   263 enables concurrent access by multiple clients, with one channel supported
       
   264 for each. Sharing of channels between threads is not supported. </p> <p> <note> To
       
   265 open a channel on the user-side API a client must exhibit the <xref href="GUID-4BFEDD79-9502-526A-BA7B-97550A6F0601.dita">PlatSec</xref> capability <codeph>PowerMgt</codeph>.</note></p><p> If a client wishes to access information
       
   266 on kernel-side clients of the Resource Controller, it must also exhibit the <codeph>ReadDeviceData</codeph> capability. </p> <p id="GUID-A5D4981F-4B16-5174-A41A-E9EEC70EA62C"><b>Initialisation</b> </p> <p>Clients
       
   267 do not need to explicitly load the kernel-side LDD, as this is a kernel extension
       
   268 and so is loaded and initialised during kernel initialisation (attempts to
       
   269 re-load it returns the error code <codeph>KErrAlreadyExists</codeph> but initialistation
       
   270 otherwise appears successful). </p> <p>Clients open a channel on the LDD by
       
   271 calling the <xref href="GUID-FD3DEFC1-DA39-3A1A-8E00-A46B34B78899.dita#GUID-FD3DEFC1-DA39-3A1A-8E00-A46B34B78899/GUID-505CFB46-E77B-38D2-AE50-B088D5D2B0F1"><apiname>RBusDevResManUs::Open()</apiname></xref> method. The client
       
   272 passes a name to the method - ideally, this is the client’s component name.
       
   273 It is the client’s responsibility to ensure the name is unique even if multiple
       
   274 channels are opened. </p> <p>The client then needs to call the <xref href="GUID-E735AB4A-E9D5-33C7-ACEC-815013C0777A.dita"><apiname>Initialise()</apiname></xref> method
       
   275 specifying the number of request objects required. The numbers passed to <codeph>Initialise()</codeph> determine
       
   276 the extent of memory allocation required (in part by the LDD and in addition
       
   277 by request to the Resource Controller) and also the maximum number of concurrent
       
   278 client requests supported. </p> <p>The number of request objects created at
       
   279 initialisation should be the maximum number of concurrent (asynchronous) requests
       
   280 that the client expects to have outstanding at any time. </p> <p id="GUID-1DC958F3-7952-56C0-A8BC-F52B2A83BE3C"><b>Getting power resource information</b> </p> <p> <xref href="GUID-FD3DEFC1-DA39-3A1A-8E00-A46B34B78899.dita#GUID-FD3DEFC1-DA39-3A1A-8E00-A46B34B78899/GUID-778D2DB8-A3B4-3F70-BFF0-3EB7B4D68866"><apiname>RBusDevResManUs::GetResourceInfo()</apiname></xref> is a method to retrieve the information for a specified resource, which
       
   281 it returns in a <xref href="GUID-A1DDD3E3-C009-3C02-895B-0B2D0EE67A9D.dita"><apiname>TResourceInfo</apiname></xref> object. There is also a method
       
   282 to get all the information for all the resources (<xref href="GUID-CF17E4E8-CFBC-31C2-B1CC-84D78006D046.dita"><apiname>GetAllResourcesInfo()</apiname></xref>).
       
   283 This function requires the allocation of buffer memory in which the information
       
   284 for all the resources is returned. <xref href="GUID-D3AB721D-35AB-36F9-B08D-10E44B6B8129.dita"><apiname>GetNoOfResources()</apiname></xref> returns
       
   285 the total number of resources available for access. </p> <p>The example below
       
   286 shows these functions in use. The amount of resources available are returned
       
   287 by <codeph>GetNoOfResources</codeph>. This figure is used to calculate the
       
   288 size of the buffer that is populated with the resource information by the <codeph>GetAllResourcesInfo</codeph> method. </p> <codeblock id="GUID-BB6AC0F1-DC41-51EE-ADA3-1402B3C3E90E" xml:space="preserve"> TInt r = KErrNone;
       
   289  TUint numResources=0;
       
   290     if((r=gChannel.GetNoOfResources(numResources))!=KErrNone)
       
   291         {
       
   292         // Failed
       
   293         return r;
       
   294         }
       
   295 
       
   296     RBuf buffer;
       
   297     if((buffer.Create(numResources*sizeof(TResourceInfo)))!=KErrNone)
       
   298         {
       
   299         // Failed
       
   300         return KErrGeneral;
       
   301         }
       
   302 
       
   303     buffer.SetLength(numResources*sizeof(TResourceInfo));
       
   304 
       
   305     if((r=gChannel.GetAllResourcesInfo(buffer,numResources))!=KErrNone)
       
   306         {
       
   307         // Failed
       
   308         return r;
       
   309         }</codeblock> <p>Get the current resource state with <xref href="GUID-79CC3D60-3B7B-3FC2-8067-205165281E28.dita"><apiname>GetResourceState()</apiname></xref>.
       
   310 Passing <codeph>ETrue</codeph> results in the cached state being read rather
       
   311 than the current hardware state. The cached state is guaranteed to be the
       
   312 state that the resource was in when it was last changed or read from hardware.
       
   313 This is why it is important that all change requests are carried out through
       
   314 the Resource Controller. <codeph>readValue</codeph> returns the current prevailing
       
   315 level and <codeph>levelOwnerId</codeph> the ID of the client that owns the
       
   316 prevailing level. <codeph>GetResourceState()</codeph> can be cancelled using <xref href="GUID-BD242DA6-1D09-3770-94BF-CCCB396AEBE4.dita"><apiname>CancelGetResourceState()</apiname></xref> passing
       
   317 the resource ID of the resource that the original request was on. Use the
       
   318 method <xref href="GUID-2306456B-6502-3E49-B707-885D994E01C5.dita"><apiname>GetResourceIdByName()</apiname></xref> to get the ID of a resource
       
   319 from the resource's name. </p> <codeblock id="GUID-FA4561F7-9223-542E-9B3C-2E03AB06FE28" xml:space="preserve">// Get initial state
       
   320 TRequestStatus status;
       
   321 TBool cached = EFalse;
       
   322 TInt readValue;
       
   323 TInt levelOwnerId = 0;
       
   324 
       
   325 gChannel.GetResourceState(status, gSharedResource, cached, &amp;readValue, &amp;levelOwnerId);
       
   326 User::WaitForRequest(status);</codeblock> <p> <xref href="GUID-EABEB759-9BF4-3278-B14C-8B887007C1D3.dita"><apiname>GetNumClientsUsingResource()</apiname></xref> and <xref href="GUID-000DC2CE-9C7B-3C0C-AABF-2D5B2C2EFA1D.dita"><apiname>GetNumResourcesInUseByClient()</apiname></xref> are used to retrieve the numbers of clients using a resource and the number
       
   327 of resources in use by a client, respectively. <xref href="GUID-EADA4695-1058-34B6-963C-42BFC794C296.dita"><apiname>GetInfoOnClientsUsingResource()</apiname></xref> and <xref href="GUID-8C32B87E-0EBB-34EF-8C6B-6AB159B4CB09.dita"><apiname>GetInfoOnResourcesInUseByClient()</apiname></xref> complement the last two methods by retrieving the resource information for
       
   328 each resource that is in use by a specified client or retrieving the client
       
   329 information for each client using the specified resource. </p> <p>The API
       
   330 supports receiving a number of concurrent (asynchronous) requests from a client;
       
   331 the maximum number is determined by the number of resources that were specified
       
   332 at initialisation. If a client issues a request that exceeds its allocation,
       
   333 the error code <codeph>KErrUnderflow</codeph> is returned. </p> <p>Some synchronous
       
   334 methods take a binary value, <codeph>aIncludeKern</codeph>, which defaults
       
   335 to <codeph>EFalse</codeph>. If this parameter is set to <codeph>ETrue</codeph>,
       
   336 the API attempts to return information that includes kernel-side clients. </p> <p id="GUID-8BDF9B79-BC05-593C-B39E-C6B8BD26AA2D"><b>Requesting notifications</b> </p> <p>Clients
       
   337 can request to be notified when a resource changes its state using the <xref href="GUID-FD3DEFC1-DA39-3A1A-8E00-A46B34B78899.dita#GUID-FD3DEFC1-DA39-3A1A-8E00-A46B34B78899/GUID-E1EE8324-E39F-3094-9BF1-932706B35DC1"><apiname>RBusDevResManUs::RequestNotification()</apiname></xref> method.
       
   338 Clients can also request to be notified when a resource reaches a specified
       
   339 threshold in a specified direction (positive or negative <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-4CC0C003-1952-5CAD-A7C5-163C5DDA52C8">resource sense</xref>) using the same method but also passing it threshold
       
   340 and direction values. </p> <p>To cancel a notification, use <xref href="GUID-51CAD2A1-C978-3EBD-984F-4C5C59D68885.dita"><apiname>CancelNotification()</apiname></xref> passing
       
   341 the resource ID from which the notification was requested. <b>Note</b>: Any
       
   342 notifications issued by a client must be cancelled before the client deregisters. </p> <p>It
       
   343 is not guaranteed that all changes of resource state result in a notification
       
   344 – a resource may change state more than once before a notification request
       
   345 is completed. In addition, it is not guaranteed that a resource is in the
       
   346 same state as it was when the notification was generated. For these reasons,
       
   347 it is the responsibility of the user-side client to read the state of a resource
       
   348 after receiving a notification. </p> <p id="GUID-ACA22305-8990-54F5-8098-80716F4A5AAE"><b>Changing the state of power
       
   349 resources</b> </p> <p>To change a resource state call the asynchronous <xref href="GUID-9E260255-90BB-3D17-9A23-F02C8FCD3D72.dita"><apiname>ChangeResourceState()</apiname></xref> method
       
   350 passing the ID of the resource on which the change is being requested and
       
   351 the requested state. </p> <p> <xref href="GUID-181BB8BF-EA17-3A5E-8B70-94265CBD15E1.dita"><apiname>CancelChangeResourceState()</apiname></xref> cancels
       
   352 all the <codeph>ChangeResourceState()</codeph> outstanding requests from the
       
   353 client on the specified power resource. For each outstanding request, the
       
   354 request object is removed from the doubly linked list within the Resource
       
   355 Controller and returned to the request object pool. </p> </section>
       
   356 <section id="GUID-DE8EE84C-D46F-504A-8254-C212B7C5D5C1"> <title>Kernel-side</title> <p>The Power Resource Manager component is implemented
       
   357 as a kernel extension. It has an exported public interface accessible to kernel-side
       
   358 components. Kernel components link to the resource manager kernel extension
       
   359 DLL (<filepath>resman.lib</filepath>). Extended features are compiled and
       
   360 exported in an additional library (<filepath>resmanextended.lib</filepath>).
       
   361 The export library is built from the generic layer. </p> <p>To ease the development
       
   362 of the PRM including the functionality provided by the generic layer and the
       
   363 mandatory PSL implementation, the generic layer is compiled into a kernel
       
   364 library (klib) (<filepath>resmanpsl.lib</filepath> for the basic version and <filepath>resmanextendedpsl.lib</filepath> for
       
   365 the extended version) which is included by the PSL to produce the kernel extension. </p> <ul>
       
   366 <li id="GUID-5D5302A9-1C1B-5B75-A203-64526CDDEB3E"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-F5E775AB-F428-5800-8844-20A1BA41380D">Concepts</xref>  </p> </li>
       
   367 <li id="GUID-2A6C1709-1DE5-5A2F-B925-E81763B85EB0"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-7745C72D-DBFA-5E96-B0EB-497329A5A77D">Registration and initialisation</xref>  </p> </li>
       
   368 <li id="GUID-8B1D1CF6-06D0-5C95-8C86-747EAE9C80E8"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-A20D5070-99F1-5B1E-9D3E-D8769030BDEE">Deregistration</xref>  </p> </li>
       
   369 <li id="GUID-4D39457D-6193-5C0A-9858-B8BAF957D0CA"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-7F518094-4B91-5EA7-AAFA-8ABC8D7F77CE">Requesting power resource information</xref>  </p> </li>
       
   370 <li id="GUID-4B572D4B-EEA9-53A5-A260-01DE4853B5CE"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-AA2EABEC-477F-54BD-AD1A-F2EF7B6BA5B7">Changing the state of power resources</xref>  </p> </li>
       
   371 <li id="GUID-6768FCC6-3FC2-532E-9BB9-16BE4C4EE44C"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-198CE312-343E-535D-8EE5-D615A7AC9265">Requesting notifications</xref>  </p> </li>
       
   372 </ul> <p id="GUID-F5E775AB-F428-5800-8844-20A1BA41380D"><b>Concepts</b> </p> <ul>
       
   373 <li id="GUID-646E0C0A-6E4D-5FA0-83CD-6BE04B08E4BC"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-E8F3AF8E-387C-5285-A2B2-0B067F01BC3A">Requests</xref>  </p> </li>
       
   374 <li id="GUID-9D5A30A8-7214-5D82-A819-B5594339A71C"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-0A8C9B3F-C96B-589C-819C-07D4C167BFCD">Callbacks</xref>  </p> </li>
       
   375 </ul> <p id="GUID-E8F3AF8E-387C-5285-A2B2-0B067F01BC3A"><b>Request messages</b> </p> <p>Request
       
   376 message objects represent a request for an operation on a resource by a client.
       
   377 For example a request to change a resource's level or notification if a resource's
       
   378 level changes. </p> <p>The client may attempt to increase its quota by requesting
       
   379 the allocation of request messages, but this may fail with <xref href="GUID-64F6761A-4716-37C3-8984-FF18FC8B7B7D.dita"><apiname>KErrNoMemory</apiname></xref>.
       
   380 A long latency resource request on may fail with <xref href="GUID-3673F75F-655F-3561-BD56-F7E1C6980810.dita"><apiname>KErrUnderflow</apiname></xref> if
       
   381 the number of request messages pre-allocated by the client has been exceeded
       
   382 and no more messages are left in the free pool to satisfy the request. </p> <p>The
       
   383 pre-allocation and reservation of <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-F47D2098-16A7-5590-A68A-7AE4B2DAB462">client
       
   384 levels</xref> and request messages is synchronously serviced in the context
       
   385 of the calling client, although this may result in memory allocation that
       
   386 is not time bound. </p> <p>See <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-2DE84E1F-C466-5631-A007-EEF046905388">Pre-allocating
       
   387 client level and request message objects</xref> for implementation guidelines. </p> <p id="GUID-0A8C9B3F-C96B-589C-819C-07D4C167BFCD"><b>Callbacks</b> </p> <p>A
       
   388 callback object is a customised DFC that is used to signal the completion
       
   389 of notifications and the PRM's asynchronous APIs. Use the class <xref href="GUID-9B43C51D-56F7-35E0-BDD5-5D2F27924383.dita"><apiname>TPowerResourceCb</apiname></xref> to
       
   390 create a resource callback object that encapsulates callback functions. </p> <p>The
       
   391 resource callback object is initialised with a callback function <xref href="GUID-F42CE2D1-6859-352A-89A7-01DFBB1FE249.dita"><apiname>TPowerResourceCbFn</apiname></xref>,
       
   392 a pointer to data passed to the callback function, the priority of the DFC
       
   393 within the queue (0 to 7, where 7 is highest) and optionally, a pointer to
       
   394 the DFC queue that this DFC should use. </p> <codeblock id="GUID-11947A50-7639-550D-BFB0-3B6320088065" xml:space="preserve">inline TPowerResourceCb(TPowerResourceCbFn aFn, TAny* aPtr, TInt aPriority)</codeblock> <p>This one specifies the DFC queue: </p> <codeblock id="GUID-21FE792B-24A2-502C-AA9E-EE8092573DA7" xml:space="preserve">inline TPowerResourceCb(TPowerResourceCbFn aFn, TAny* aPtr, TDfcQue* aQue, TInt aPriority)</codeblock> <p>The user specified callback function is invoked with five arguments: </p> <ul>
       
   395 <li id="GUID-0912EE6D-A1DC-528D-8AEE-423D703C12CA"><p>the ID of the client
       
   396 is: </p> <ul>
       
   397 <li id="GUID-27C7A49B-BFCB-5D96-A129-7AE19A1CB430"><p>the client that issued
       
   398 an asynchronous operation - if the callback function is called as a result
       
   399 of an asynchronous resource state read operation </p> </li>
       
   400 <li id="GUID-F4181885-29F6-53DB-8555-EB735EF83F81"><p>the client that is currently
       
   401 holding the resource - if the callback function is called as a result of an
       
   402 asynchronous resource state change operation or resource state change notification. </p> </li>
       
   403 <li id="GUID-E8720BBB-BF9A-53FB-A123-AACA62A4F435"><p> <b>Note</b>: </p> <ul>
       
   404 <li id="GUID-87393CD1-684C-503C-9A2A-982961FC8169"><p>If -1 is passed as the
       
   405 client ID this specifies that no client is currently holding the resource. </p> </li>
       
   406 <li id="GUID-A3AB501B-004A-538E-B811-6733C76D213C"><p>In the extended version
       
   407 of PRM (see Dynamic and Dependant resources) if -2 is passed as the client
       
   408 ID in the callback function it signifies that the dynamic resource is deregistering.
       
   409 With dependency resources, the ID of the dependent resource is passed as the
       
   410 client ID if the state of the resource (specified in <codeph>aResourceId</codeph>)
       
   411 changes as a result of the dependant resources stage changing (whose ID is
       
   412 specified in <codeph>aClientId</codeph>). </p> </li>
       
   413 </ul> </li>
       
   414 </ul> <ul>
       
   415 <li id="GUID-A38B31E5-DB85-561A-A256-CF6FF025D9B0"><p>issued an asynchronous
       
   416 API (state read or change) which leads to the callback function being called </p> </li>
       
   417 <li id="GUID-F58DA60D-CA0E-5F82-9655-F1FF4D53D8B5"><p>requested the resource
       
   418 state change that leads to queuing a notification, which then leads to the
       
   419 callback function being called. </p> </li>
       
   420 </ul> </li>
       
   421 <li id="GUID-7ABBA59B-71A0-55CC-9722-5A569F95A881"><p>the resource ID - a
       
   422 client may have multiple notifications pending on different resources and
       
   423 a single callback function. The resource ID can be used to specify which resource
       
   424 change is being notified </p> </li>
       
   425 <li id="GUID-D18973A1-1E60-5335-BF98-1CCEB229730E"><p>the level of the resource
       
   426 when either: </p> <ul>
       
   427 <li id="GUID-9AC96325-FA2E-552F-A306-B0CCDA95B5BD"><p>the callback is called
       
   428 as a result of a notification of state change </p> </li>
       
   429 <li id="GUID-3886E475-28C5-5410-8801-0F4E9B273F13"><p>when the callback is
       
   430 called as a result of a non-blocking form of <xref href="GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00.dita#GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00/GUID-318F8627-AB72-3AA9-93A8-F8131117FF90"><apiname>PowerResourceManager::GetResourceState()</apiname></xref>. </p> </li>
       
   431 <li id="GUID-5C65D90E-A9C8-5439-A8FE-B077AC00F4AF"><p>the requested level
       
   432 for the resource when the callback is called as a result of a non-blocking
       
   433 form of <xref href="GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00.dita#GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00/GUID-9E89A793-A838-3E48-AC24-17367E36EC05"><apiname>PowerResourceManager::ChangeResourceState()</apiname></xref>  </p> </li>
       
   434 </ul> </li>
       
   435 <li id="GUID-56181048-98E7-57BB-81D9-D863663F44C2"><p>the ID of the resource
       
   436 level owner </p> </li>
       
   437 <li id="GUID-5924CF16-4493-5845-ADB0-615968D9D8C7"><p>the error code returned
       
   438 when the callback is called as a result of an asynchronous request to change
       
   439 the state of the resource. This is not relevant when the callback is called
       
   440 as a result of a notification of state change </p> </li>
       
   441 <li id="GUID-8BAD3C01-7AA1-5C42-A52F-05C1BF5957D0"><p>a user defined argument
       
   442 that is passed to the constructor. </p> </li>
       
   443 </ul> <p>Cancel an asynchronous request, or its callback, by calling <xref href="GUID-98C67010-FAD0-3D09-BFBF-EE240ADB95E7.dita"><apiname>CancelAsyncRequestCallback()</apiname></xref>. </p> <p id="GUID-7745C72D-DBFA-5E96-B0EB-497329A5A77D"><b> Registration and initialisation</b> </p> <p>Clients
       
   444 need to register with the PRM using <xref href="GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00.dita#GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00/GUID-4F932142-C551-3DBB-8DC8-F697B92E8168"><apiname>PowerResourceManager::RegisterClient()</apiname></xref> before
       
   445 they can request operations on resources. </p> <p>Registration happens at
       
   446 different times for different clients: </p> <ul>
       
   447 <li id="GUID-491C4B9C-86BC-5AC2-870A-0FA46FDE3CA9"><p>kernel extensions register
       
   448 from their entry point during kernel boot </p> </li>
       
   449 <li id="GUID-8A6D66CC-DD34-5CC2-9AD3-BEEC7B540BA8"><p>device drivers for internal
       
   450 or external devices register on opening a channel. </p> </li>
       
   451 </ul> <p>When a client registers with the PRM, a client link object is removed
       
   452 from the free pool, populated with the relevant information, and a pointer
       
   453 to it is added to a container of clients within the PRM. If no free link exists
       
   454 within the pool, a number of client links are created in kernel heap. As a
       
   455 result, client registration may fail in out of memory situations. Client links
       
   456 are never destroyed after the client deregisters, but are released back into
       
   457 the free pool. </p> <p>Clients are registered by name; the PRM does not check
       
   458 that a name is unique unless the <codeph>DEBUG_VERSION</codeph> macro is enabled.
       
   459 The component registering the client should check that the name is unique.
       
   460 The ID returned is a handle to the client link object that represents the
       
   461 client in the PRM. </p> <p>On registration, a client also specifies the type
       
   462 of ownership (<xref href="GUID-19F111C8-00AC-3A2E-85A6-755DC322C870.dita"><apiname>TOwnerType</apiname></xref>) that applies. This is either: </p> <ul>
       
   463 <li id="GUID-E7A9ADE9-8590-5CB0-ADE9-8354BADCE77D"><p> <codeph>EOwnerThread</codeph> -
       
   464 the client ID is only used by the thread that registered the client to call
       
   465 the PRM APIs </p> </li>
       
   466 <li id="GUID-9EED259E-E339-59E0-BE96-8A33EA01AE98"><p> <codeph>EOwnerProcess</codeph> -
       
   467 the client ID is used by all threads in the process to call the PRM APIs. </p> </li>
       
   468 </ul> <p>The default is <codeph>EOwnerProcess</codeph>. </p> <p id="GUID-2DE84E1F-C466-5631-A007-EEF046905388"><b>Pre-allocating client level
       
   469 and request message objects </b> </p> <p>The controller has an initial pool
       
   470 of free client levels and request messages whose size can be configured at
       
   471 build time by the PSL. After registering with the PRM, a client can request
       
   472 the pre-allocation of a number of client levels and request messages to guarantee
       
   473 deterministic behaviour (to avoid out of memory failure) of the resource state
       
   474 change operation using <xref href="GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00.dita#GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00/GUID-F787A2A2-8860-3145-97FB-46D6B8D6E5AC"><apiname>PowerResourceManager::AllocReserve()</apiname></xref>.
       
   475 This allocation remains reserved to the specified client until the client
       
   476 is deregistered from the PRM. The number of client level objects reserved
       
   477 by a client depends on the number of resources on which a resource state change
       
   478 will be requested. </p> <p>A client may issue more than one request, possibly
       
   479 to the same resource, before the previous one completes, it is therefore more
       
   480 difficult to determine how many objects to pre-allocate. </p> <p>It is recommended
       
   481 that as many request messages as asynchronous long latency resources the client
       
   482 expects to use are pre-allocated. The free pool should be relied on for the
       
   483 situations when a resource is requested more than once before the first request
       
   484 completes. </p> <p id="GUID-A20D5070-99F1-5B1E-9D3E-D8769030BDEE"><b>Deregistration</b> </p> <p>All
       
   485 notifications and asynchronous requests must be cancelled before the client
       
   486 is deregistered, otherwise the kernel will panic. Use the <xref href="GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00.dita#GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00/GUID-C076174C-D16A-3A8B-825C-F7BE2424EA3D"><apiname>PowerResourceManager::CancelNotification()</apiname></xref> and <xref href="GUID-98C67010-FAD0-3D09-BFBF-EE240ADB95E7.dita"><apiname>CancelAsyncRequestCallback()</apiname></xref> methods to cancel all pending notifications and asynchronous requests. Notifications
       
   487 that have been registered with the Controller should be deregistered before
       
   488 they are deleted as the Controller may attempt to issue them. Deleting a notification
       
   489 that is still registered with the Controller results in the kernel panicking. </p> <p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-F47D2098-16A7-5590-A68A-7AE4B2DAB462">Client
       
   490 level objects</xref> and request objects reserved by the client remain reserved
       
   491 for that client until it deregisters. When the client is deregistering these
       
   492 objects are moved to free pool by the PRM. </p> <p>Client deregistration can
       
   493 result in a resource state change: </p> <ul>
       
   494 <li id="GUID-8C4B2F9D-7B4D-5BC4-8B8C-02D1AEFDF1C5"><p>If the resource is shared
       
   495 and the deregistering client owned the prevailing level, the resource state
       
   496 is moved to the next level according to its sense. If it is a custom sense
       
   497 resource, the resource state is changed as a result of calling a custom function. </p> </li>
       
   498 <li id="GUID-DE1341E0-C392-5982-8A0D-3CCE9A8DC950"><p>If the resource is not
       
   499 shared or if it is shared but the client is the only one using it at the time
       
   500 of deregistration, the resource is moved to the <i>default</i> state. The
       
   501 default state is only known by the PSL. </p> </li>
       
   502 </ul> <p>A deregistering client can have a number of active requirements on
       
   503 a number of resources and more than one of these resources may need to change
       
   504 state as a result of the client deregistering. The combined operation of deregistering
       
   505 the client and adjusting the state of all resources it shares executes synchronously.
       
   506 That is, the client thread is blocked throughout whether the resources whose
       
   507 state needs to change is instantaneous or long latency. </p>  <p id="GUID-7F518094-4B91-5EA7-AAFA-8ABC8D7F77CE"><b>Getting power resource information</b> </p> <p>The
       
   508 resource information can be retrieved using the method <xref href="GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00.dita#GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00/GUID-AFD3385B-362B-3F8B-B7EF-262CB21C0EE2"><apiname>PowerResourceManager::GetResourceInfo()</apiname></xref>,
       
   509 information can also be retrieved for all of the resources used by the specified
       
   510 client using <xref href="GUID-8C32B87E-0EBB-34EF-8C6B-6AB159B4CB09.dita"><apiname>GetInfoOnResourcesInUseByClient()</apiname></xref>. This function
       
   511 takes a buffer that must be the size of the information structure multipled
       
   512 by the number of resources in use by the client, this figure can be retrieved
       
   513 using the method <xref href="GUID-000DC2CE-9C7B-3C0C-AABF-2D5B2C2EFA1D.dita"><apiname>GetNumResourcesInUseByClient()</apiname></xref>. Specify
       
   514 the resource ID as zero to retrieve all information from all the clients registered
       
   515 with PRM. </p> <p>To get information about clients using a resource, use the
       
   516 method <xref href="GUID-EADA4695-1058-34B6-963C-42BFC794C296.dita"><apiname>GetInfoOnClientsUsingResource()</apiname></xref>. Use the number
       
   517 of clients using a resource using <xref href="GUID-EABEB759-9BF4-3278-B14C-8B887007C1D3.dita"><apiname>GetNumClientsUsingResource()</apiname></xref>.
       
   518 Specify the client ID as zero to retrieve all information from all the resources
       
   519 registered with PRM. </p> <p>Use <xref href="GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00.dita#GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00/GUID-318F8627-AB72-3AA9-93A8-F8131117FF90"><apiname>PowerResourceManager::GetResourceState()</apiname></xref> to
       
   520 retrieve resource state information. This function can be called synchronously
       
   521 or asynchronously. Asynchronous calls require the client to create a callback
       
   522 object in the kernel heap or data section. The synchronous <codeph>GetResourceState()</codeph> call. </p> <codeblock id="GUID-00E075BB-E38B-5B15-A7DA-56C032A678C2" xml:space="preserve">TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TInt&amp; aState, TInt&amp; aLevelOwnerId);</codeblock> <p>The asynchronous <codeph>GetResourceState()</codeph> call. </p> <codeblock id="GUID-20C6EB70-1CF2-5FDD-85F8-577361E6CA86" xml:space="preserve">TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TPowerResourceCb&amp; aCb);</codeblock> <p>If executing asynchronously, the callback function encapsulated in the
       
   523 callback object (called in the client’s context) is invoked when the state
       
   524 of the resource is available. The third argument of the callback function
       
   525 carries the resource state. If this function is called with <codeph>aCached</codeph> set
       
   526 as <codeph>ETrue</codeph>, then the callback function is called in the context
       
   527 of the calling thread both for instantaneous and long latency resources, thus
       
   528 blocking the calling thread throughout. </p> <p>For instantaneous resources, <xref href="GUID-79CC3D60-3B7B-3FC2-8067-205165281E28.dita"><apiname>GetResourceState()</apiname></xref> executes
       
   529 in the context of the calling thread and, if specified, the callback function
       
   530 is called after getting the state of the requested resource. The calling thread
       
   531 is blocked throughout. </p> <p> <codeph>GetResourceState()</codeph> takes
       
   532 a boolean value that determines from where the requested resource state information
       
   533 is retrieved: </p> <ul>
       
   534 <li id="GUID-21044D5D-142F-5E05-9743-3218E99DD7DC"><p>ETrue - the resource
       
   535 state is the cached value, this value is returned faster but is not guaranteed
       
   536 to be correct </p> </li>
       
   537 <li id="GUID-A221B599-2EB3-5E0E-9D3E-E2333BF0AD0F"><p>EFalse - the resource
       
   538 state is read from the resource, this value takes longer to return, but is
       
   539 much more likely to be correct. </p> </li>
       
   540 </ul> <p id="GUID-AA2EABEC-477F-54BD-AD1A-F2EF7B6BA5B7"><b>Changing the state of power
       
   541 resources</b> </p> <p>The <xref href="GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00.dita#GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00/GUID-9E89A793-A838-3E48-AC24-17367E36EC05"><apiname>PowerResourceManager::ChangeResourceState()</apiname></xref> method
       
   542 is used to request a change on a resource. When a state change is requested
       
   543 on a shared resource, only the minimum state change that satisfies the request
       
   544 is guaranteed. </p> <codeblock id="GUID-48C3E903-398D-5592-8F21-2CE22D824330" xml:space="preserve">TInt ChangeResourceState(TUint aClientId, TUint aResourceId, TInt aNewState, TPowerResourceCb* aCb=NULL);</codeblock> <p>The values passed to the method are: </p> <ul>
       
   545 <li id="GUID-5F6B6127-BA40-51BC-829E-90936A8B3FB3"><p>the ID of the client
       
   546 requesting the change </p> </li>
       
   547 <li id="GUID-5FF24DB5-CA57-571A-846E-6BECB91025A9"><p>the ID of the resource
       
   548 that the change is to take place </p> </li>
       
   549 <li id="GUID-6764FB93-36D4-56FC-85EC-8EA015ED6F9C"><p>the new state of the
       
   550 resource </p> </li>
       
   551 <li id="GUID-77092FD0-044D-528B-B62F-56166F21CB3B"><p>a pointer to the resource
       
   552 callback object. </p> </li>
       
   553 </ul> <p>The requested state is either a binary value for a binary resource,
       
   554 an integer level for a multilevel resource or some platform specific token
       
   555 for a multi-property resource. The pointer to the callback object is defined
       
   556 by the class <xref href="GUID-9B43C51D-56F7-35E0-BDD5-5D2F27924383.dita"><apiname>TPowerResourceCb</apiname></xref>; its use is optional and
       
   557 is treated by synchronous and asynchronous resources as described below. </p> <p><b>Changing resource state on a long latency resource </b> </p> <p>If the
       
   558 callback object is specified, then <codeph>ChangeResourceState()</codeph> is
       
   559 executed asynchronously and returns immediately. The actual resource change
       
   560 happens in the resource controller thread and the callback function encapsulated
       
   561 in the callback object is called after the resource is changed. </p> <p>If
       
   562 the callback object is NULL, then <codeph>ChangeResourceState()</codeph> executes
       
   563 synchronously, meaning the client thread is blocked until the resource state
       
   564 has changed. The PRM panics if the synchronous version of this API for long
       
   565 latency resources is called from DFC thread 0. </p> <p><b>Changing resource state on an instantaneous resource </b> </p> <p>On an
       
   566 instantaneous resource <codeph>ChangeResourceState()</codeph> always executes
       
   567 synchronously. </p> <p>If a callback object is specified, then the callback
       
   568 function encapsulated in the callback object is called from the client thread
       
   569 after the resource change and before returning from the function. </p> <p>Use <xref href="GUID-1C044392-213A-3920-93CE-6CAEBBC17D3F.dita"><apiname>CancelAsyncRequestCallBack()</apiname></xref> to
       
   570 cancel change requests on a resource. When the client no longer requires a
       
   571 level on a resource use the method <xref href="GUID-54784583-DB6D-3847-800E-65DE7ADB8DC6.dita"><apiname>DeRegisterClientLevelFromResource()</apiname></xref> to
       
   572 remove a client level object from a resource. </p> <p id="GUID-198CE312-343E-535D-8EE5-D615A7AC9265"><b>Requesting notifications</b> </p> <p>Clients
       
   573 can request notification of a state change on a resource. Notifications are
       
   574 issued post resource change and invoke the callback function encapsulated
       
   575 in a notification object. The callback is executed in the context of the requesting
       
   576 client thread. </p> <p>The parameters passed to <xref href="GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00.dita#GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00/GUID-316A2B0A-8E58-3D21-B068-5FD228BE0305"><apiname>PowerResourceManager::RequestNotification()</apiname></xref> are: </p> <ul>
       
   577 <li id="GUID-DC4C6378-A8A3-564D-8255-F4A91CD498AF"><p>the ID of the client
       
   578 requesting the notification </p> </li>
       
   579 <li id="GUID-8D08E63E-EEC4-5812-8E42-0A5DAD5DB718"><p>the ID of the resource
       
   580 for which notification of state changes is being requested </p> </li>
       
   581 <li id="GUID-3C3E2C2F-29B7-5D86-B7A6-A03B814A6C14"><p>a reference to a notification
       
   582 object encapsulating a callback function called whenever a resource state
       
   583 change takes place. </p> </li>
       
   584 </ul> <p>A notification may be unconditional or conditional. An unconditional
       
   585 notification request notifies the client each time the state changes. A conditional
       
   586 notification request notifies the client when a threshold has been met in
       
   587 the direction specified. A conditional notification has these additional parameters: </p> <ul>
       
   588 <li id="GUID-0734A09A-010A-57B4-A822-25D709CA55E9"><p>aThreshold - the level
       
   589 of the resource state that triggers the notification </p> </li>
       
   590 <li id="GUID-FCE1EE43-C431-5967-B778-A7B701CF4983"><p>aDirection - the direction
       
   591 the resource state change that triggers a notification: </p> <ul>
       
   592 <li id="GUID-3E49268F-EF11-5F18-AC23-16CD26FFA37E"><p>EFalse - the resource
       
   593 state is equal to or below the threshold </p> </li>
       
   594 <li id="GUID-7FA60FF1-890D-5726-A0CB-3D866504E11F"><p>ETrue - the resource
       
   595 state is equal to or above the threshold. </p> </li>
       
   596 </ul> </li>
       
   597 </ul> <p>The client must create the notification object (<xref href="GUID-80CA4C5E-9575-3EE9-A983-AC74B9DBE351.dita"><apiname>DPowerResourceNotification</apiname></xref>)
       
   598 in the kernel heap or data section. <b>Note</b>: The client may share the
       
   599 same callback function between several notifications but a unique DFC must
       
   600 be created and queued for each notification. </p> <p>Because notifications
       
   601 result in DFCs being queued, it is not possible to guarantee that all resource
       
   602 state changes are notified. If the resource state changes again, before the
       
   603 first DFC runs, it does not generate a separate notification. It is also not
       
   604 possible to guarantee that by the time the notification callback runs the
       
   605 resource state is still the same state that caused the notification to be
       
   606 issued. The client should read the resource state after receiving a notification. </p> <p>Use <xref href="GUID-5E058C0F-39E8-3640-9451-72645567FB04.dita"><apiname>CancelRequestNotification()</apiname></xref> to
       
   607 cancel a notification request. It takes a reference to the notification object
       
   608 associated with the original notification request that is being cancelled. </p> </section>
       
   609 </conbody></concept>