Adaptation/GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita
changeset 15 307f4279f433
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adaptation/GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita	Fri Oct 15 14:32:18 2010 +0100
@@ -0,0 +1,609 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
+<!-- This component and the accompanying materials are made available under the terms of the License 
+"Eclipse Public License v1.0" which accompanies this distribution, 
+and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
+<!-- Initial Contributors:
+    Nokia Corporation - initial contribution.
+Contributors: 
+-->
+<!DOCTYPE concept
+  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
+<concept id="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE" xml:lang="en"><title>Power
+Resource Manager (PRM)</title><shortdesc>Describes the Power Resource Manager.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
+<ul>
+<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>
+<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>
+<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>
+<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>
+</ul>
+<section id="GUID-2F312E19-71BC-5396-996F-EA48EAEDF2F2"><title>Introduction</title> <p>The
+Power Resource Manager (PRM) integrates the Symbian device driver with existing
+power control and functions used for resource state changing and querying.
+It defines an exported API that device drivers and other users of power resources
+(represented by kernel-side components) can use to control the state of power
+resources. The PRM assists the development of device drivers by removing the
+need to understand the complexities of platform specific power resource management
+by providing a simple to use generic framework. </p> <p>The PRM also allows
+user-side clients to gain access to the services. Clients of the PRM can: </p> <ul>
+<li id="GUID-1F23255C-A662-5755-A4C7-387A57FEB2C3"><p>request information
+on the clients and resources registered with PRM </p> </li>
+<li id="GUID-3E6406A9-757A-53EE-AE1C-839CA87C1120"><p>get the current state
+of the resources </p> </li>
+<li id="GUID-4FD981E6-EA1E-5E49-83D1-CC017BB753FE"><p>request changes to the
+state of power resources </p> </li>
+<li id="GUID-3ED36326-E905-53A1-907F-51DD6846B5BC"><p>request notification
+of changes (i.e. power-down or change clock frequency) to the power resources
+that they depend on. </p> </li>
+</ul> <p>The following diagram shows the generic and customisable parts of
+the framework: </p> <ul>
+<li id="GUID-D4A341D5-84C4-543E-A392-426B6E9905FB"><p>exported kernel level
+API (<xref href="GUID-40AB9EDA-16CB-371E-8759-1D7C99FF9C00.dita"><apiname>PowerResourceManager</apiname></xref>) </p> </li>
+<li id="GUID-D0A636FF-9520-5CA1-82EF-E7B7AF645063"><p>base virtual class for
+Power Resource Controller (<xref href="GUID-46F2174F-0206-345B-8C5D-F8B5763652E0.dita"><apiname>DPowerResourceController</apiname></xref>) </p> </li>
+<li id="GUID-C7C11053-E43B-5A1F-B5E7-6BBE36C02C1D"><p>PDD required for user-side
+proxy client </p> </li>
+<li id="GUID-404A1110-40E3-5E28-8C04-19232FB047B5"><p>platform specific implementation
+of resource control at the level of register interface to hardware resource
+controller (<codeph>DXXXPowerResourceController</codeph>) </p> </li>
+</ul> <fig id="GUID-72B93745-2089-526F-8AF5-0E7522CADBEC">
+<image href="GUID-99C4FCCC-9E8B-51CC-85F8-F03BE18DF19E_d0e82580_href.png" placement="inline"/>
+</fig> </section>
+<section id="GUID-F830F456-A436-5025-821D-21855C7AE056"><title>Concepts</title> <ul>
+<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>
+<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>
+</ul> <p id="GUID-4CC0C003-1952-5CAD-A7C5-163C5DDA52C8"><b>Power resources</b> </p> <p>A
+power resource is anything that has an effect on power consumption. These
+are typically platform specific and either physical or logical. Physical power
+resources are provided by hardware: for example, clocks, outputs from voltage
+regulators, switched power domains and performance levels. Logical power resources
+do not directly map to hardware components, but their state has an effect
+on overall power consumption. In this category we include, for example, shared
+buses and devices that provide services to other components. </p> <p>Power
+resources can be further categorised based on: </p> <ul>
+<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
+be shared. There is no limit to the number of clients sharing a resource.
+If the resource is shared, then a request system is used. This comprises a
+list of <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-F47D2098-16A7-5590-A68A-7AE4B2DAB462">client
+level objects</xref>, one for each client requesting a level on the resource.
+The resource level is determined by a set of rules which govern whether a
+request is accepted or declined. </p> </li>
+<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
+state</xref> may be binary, multi-level or multi-property. A binary state
+is either On or Off and a multi-level state can change either discretely or
+continuously between a minimum (which could be Off) and a maximum value (which
+could be fully On). </p> <p>A multi-property resource has different properties
+across different portions of the operating curve. For example, the level may
+be controllable within the ‘operational’ part of that curve but have different
+discrete fixed states for the ‘idle’ or ‘sleep’ modes of operation. </p> </li>
+<li id="GUID-FC70680E-1595-54FC-A611-295688470176"><p>Execution time </p> <p>The
+execution time of a resource can be either instantaneous or long latency.
+An instantaneous resource can be operated almost immediately (no longer than
+a few system clock cycles, comparable to a CPU instruction execution time).
+Operations on long latency resources take a significant time to complete (a
+non-negligible amount of CPU clock cycles). </p> <p>Power resources may be
+long latency for state change operations and instantaneous for obtaining the
+current state. This is typically the case of a PLL (Phase Locked Loop) device
+(<xref href="http://en.wikipedia.org/wiki/Phase-locked_loop" scope="external">definition
+from Wikipedia</xref>), which requires time to stabilise after a frequency
+change is initiated but whose current output frequency can be read from a
+register. <b>Note</b>: instantaneous operations may pre-empt operations on
+long latency resources, and requests to get the state of a shared resource
+may be issued while a state change is underway. If the read operation is instantaneous
+and the change is long latency, care must be taken (at the PSL level) to not
+return inconsistent values. </p> <p>Other power resources may be long latency
+on both state change and state read operations. This is typically the case
+for any resources accessed through an inter-IC bus (even if their operation
+is instantaneous). </p> </li>
+<li id="GUID-8ABE5ED4-C2CB-557E-BF53-9630567AE7DC"><p>Resource <i>sense</i>  </p> <p>Each
+client sharing a resource may have a different requirement on its state. The
+resource <i>sense</i> is used to determine whose requirement prevails. </p> <table id="GUID-BECBC606-95E8-5C6F-BC71-2DA2AA838C88">
+<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>
+<tbody>
+<row>
+<entry><p>Positive sense </p> </entry>
+<entry><p>Can have their value increased without affecting their sharers. </p> <p>The
+level is set to the highest level that is requested. The highest requirement
+for binary resources is the On state. </p> </entry>
+</row>
+<row>
+<entry><p>Negative sense </p> </entry>
+<entry><p>Can have their value decreased without affecting their sharers. </p> <p>The
+level is set to the lowest level that is requested. The lowest requirement
+for binary resources is the Off state. </p> </entry>
+</row>
+<row>
+<entry><p>Custom sense </p> </entry>
+<entry><p>May be increased or decreased freely by some privileged sharers
+but not by others, which are bound by the requirement of the privileged sharers. </p> <p>The
+decision to change the prevailing level (or binary state) depends on the privileges
+of the client and past usage of the resource. This decision is made by the
+PSL <xref href="GUID-B1CE51BC-B452-5FC9-9C00-35447AF40671.dita#GUID-B1CE51BC-B452-5FC9-9C00-35447AF40671/GUID-9526B472-00ED-583A-8BFC-C02363D4DFA2">custom
+function</xref> implementation. </p> </entry>
+</row>
+</tbody>
+</tgroup>
+</table> </li>
+<li id="GUID-CF996934-F142-5A79-BE7B-D91FE3109D95"><p>Static or Dynamic </p> <p>Most
+power resources are known at device creation time, so their control should
+be addressed by such components as the Variant or ASSP. These resources are
+registered during the creation of the Resource Controller; these are static
+resources. Resources controlled by device drivers (internal or external) are
+only registered at driver-creation time using the registration and deregistration
+API provided by the PRM; these are known as dynamic resources. </p> <p> <b>Note</b>:
+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
+and configuration</xref>. </p> </li>
+</ul> <p>Physical resources may belong to one or more of these categories,
+for example, a multilevel resource may be shared between different clients
+and take a significant time to change state (long latency). </p> <p>External
+devices may include and control their own power resources. In some cases,
+an external device can function as a bus expander, allowing other devices
+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
+PRM caches the prevailing level of each resource as well as the client that
+requested it. The cached state is guaranteed to be the state that the resource
+was in when the last request to change or read the state from its hardware
+was issued. </p> <p>On resource state read operations, the PRM allows clients
+to select the cached state instead of the current state of the hardware resource.
+A cached state read is always an instantaneous operation executed in the context
+of the calling client thread (even for long latency resources). </p> <p>However,
+care must be taken as the cached state may not be the state the resource is
+at that moment. For example, a resource can be non-sticky: when it is turned
+on it stays on during an operation but then automatically switches itself
+off. </p> <p>The consistency of the cached state relies on all resource state
+operations being requested through the <xref href="GUID-4804B6E0-9199-5F3E-984A-4B00B3984E45.dita">Power
+Resource Controller</xref>. </p> <p><b>Dynamic
+resources</b> </p> <p>A generic layer provides basic functionality for static
+resources an extended version of the PRM provides APIs for dynamic resources
+and resource dependencies. These dynamic resource and resource dependent APIs
+are only available through the extended library <filepath>resmanextended.lib</filepath>. </p> <p>A
+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>.
+This function is also used to register a dynamic resource that supports dependencies
+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
+dynamic resource (<xref href="GUID-CA01041D-8FD6-3B5B-BB5D-A5159DF7C9AB.dita"><apiname>DDynamicPowerResource</apiname></xref>) to register. The
+PRM sets <codeph>aResourceId</codeph> to the resource ID of this resource.
+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
+deregister a dynamic resource from the PRM. You can also use the function
+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
+to before deregistration if this value is NULL the state of the resource is
+changed to its default. </p> <p><b>Changing resource state on a dynamic resource </b> </p> <p>Because a dynamic
+resource can deregister from the PRM it is necessary to indicate to clients
+that this has happened. Any remaining notification requests are completed
+with a -2 in the client field of the callback function. This indicates that
+this notification is because the resource has been deregistered and not because
+the notification conditions have been met. When a client recieves a notification
+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
+resource may register a dependency on another resource. At least one of the
+resources must be a dynamic resource. Request a dependency between resources
+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
+and the dependency information of the resource (<xref href="GUID-88FE83B0-35A1-3913-B38F-1FB925FFE96C.dita"><apiname>SResourceDependencyInfo</apiname></xref>). <codeph>SResourceDependencyInfo</codeph> contains
+the resource ID and the priority of the dependency. </p> <p>The kernel will
+panic if a closed loop dependency is found for the specified dependency or
+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
+retrieve the number of resources that depend on the specified resource directly
+and <xref href="GUID-9C582DAB-2C0B-331D-BA8D-CED067289055.dita"><apiname>GetDependentsIdForResource()</apiname></xref> to return the IDs of all
+the dependent resources. </p> <p><b>Deregistering
+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
+remove a dependency. This function takes the ID of the client that requests
+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
+library. </p> <p><b>Changing
+resource state on a dependent resource</b> </p> <p>A resource state can change
+when the state of any of its dependent resources changes. A state change causes
+a notification if the requested conditions are met. The client ID in the callback
+function is updated with the ID of the resource that triggered this resource
+change (bit 16 of the ID is set for dependency resource; this is used to distinguish
+between a resource ID and a client ID). </p> <p id="GUID-8BBC100D-BB97-5675-AA2F-E730A0DF4B26"><b>Clients</b> </p> <p>The
+PRM has both user and kernel-side clients. Kernel-side clients are: </p> <ul>
+<li id="GUID-7DDBF8D2-80AD-5248-9C8A-2F215E98513E"><p>device drivers </p> </li>
+<li id="GUID-914A7E0F-9FE5-579A-AEB5-35163D89E450"><p>performance scaling
+and/or performance monitoring and prediction components </p> </li>
+</ul> <p>User-side clients are: </p> <ul>
+<li id="GUID-E1A4D6C3-9EEC-54EB-BEF4-90C3DD65E4A3"><p>user-side system-wide
+power management framework </p> </li>
+<li id="GUID-08B28DD8-107E-5142-A887-F685A17915DC"><p>other power-aware servers
+and power-aware applications </p> </li>
+</ul> <p>Clients register with the PRM by name. Clients can request to allocate
+and reserve client level objects and request message objects after registering
+with PRM. </p> <p id="GUID-F47D2098-16A7-5590-A68A-7AE4B2DAB462"><b>Client level objects</b> </p> <p>Client
+level objects represent a client requesting a level on a resource. They are
+used by resources to set the current level of the resource and the current
+owner of the resource level. </p> <p>Each resource has a doubly linked list
+on which client level objects are held. When a client requests a level for
+the first time, a new client level object is added to the list; however, if
+the client already has an object on the list, this object is adjusted to reflect
+the change in the required level. </p> <p>The following rules determine whether
+the change is allowed on positive and negative sense resources: </p> <ul>
+<li id="GUID-18D734C9-F01A-53D8-9B2B-9DED288F8968"><p>If the requested change
+is in the direction permitted by the resource sense and would result in exceeding
+the prevailing level, the change is allowed. </p> <p>The new prevailing level
+is recorded, and the previous prevailing level and the requirements other
+clients have on the resource remain on record. </p> </li>
+<li id="GUID-9901C6DC-D91F-5CB4-BA68-10E941486BBF"><p>If the requested change
+is not in the direction permitted by the resource sense, but the client requesting
+the change is the owner of the prevailing level, the resource state changes
+up to next highest for a positive sense resource, or lowest for a negative
+sense resource. </p> <p>This value is now the prevailing level and the client
+that requested it remains the owner of the prevailing level. </p> </li>
+<li id="GUID-643C8DE3-322C-5C2A-840F-80F02DDFB60D"><p>If the requested change
+is not in the direction permitted by the resource sense, and the client requesting
+the change is not the owner of the prevailing level, the change is not allowed. </p> <p>Even
+though the request was rejected, the client's existing requirement is adjusted
+to reflect the request. </p> </li>
+</ul> <p>Prevailing levels are recorded by either adjusting the previous requirement
+for the client that requested it or, if it is the first time this client requests
+a level, a new requirement is created. </p> <p id="GUID-8FE4BD6A-6A69-5233-88E2-32837A42A544"><b>Notifications</b> </p> <p>A
+client may request a state change notification from a resource. Notifications
+can be conditional or unconditional; conditional notifications specify a threshold
+on the resources state, which when crossed in the direction specified, triggers
+the notification. </p> <p>Notifications are always issued post resource change
+and invoke callback functions executed in the context of the requesting client
+thread. The process of notifying a client involves queuing a DFC in that clients'
+thread. The notification object encapsulating the DFC must be created in kernel
+heap and passed to the notification API by the client that requested the notification.
+The client may share the same callback function between several notifications,
+but a unique DFC must be created and queued per notification. </p> <p>Because
+notifications result in DFCs being queued, it is not possible to guarantee
+that all changes of resource state are notified. If the resource state changes
+again before the first DFC runs, a separate notification cannot be generated.
+It is also not possible to guarantee that by the time the notification callback
+runs, the resource state is still the same as the state that caused the notification
+to be issued: it is the responsibility of the driver to read the resource
+state after receiving a notification. </p> </section>
+<section id="GUID-5C3F684C-D4F6-5343-AFFC-009B70210F9C"> <title>User-side</title> <ul>
+<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>
+<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>
+<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>
+<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>
+<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>
+</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
+API makes relevant PRM functionality available to user-side applications that
+have power-aware features. </p> <p> <codeph>RBusDevResManUs</codeph> is derived
+from <xref href="GUID-6FBFA078-8253-3E24-B1F8-5F75E86C3066.dita"><apiname>RBusLogicalChannel</apiname></xref>, the user-side handle to a logical
+channel base class, and presents the user-side interface to a kernel-side
+LDD. The LDD is built as <filepath>resman.ldd</filepath>. </p> <p>The API
+enables concurrent access by multiple clients, with one channel supported
+for each. Sharing of channels between threads is not supported. </p> <p> <note> To
+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
+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
+do not need to explicitly load the kernel-side LDD, as this is a kernel extension
+and so is loaded and initialised during kernel initialisation (attempts to
+re-load it returns the error code <codeph>KErrAlreadyExists</codeph> but initialistation
+otherwise appears successful). </p> <p>Clients open a channel on the LDD by
+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
+passes a name to the method - ideally, this is the client’s component name.
+It is the client’s responsibility to ensure the name is unique even if multiple
+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
+specifying the number of request objects required. The numbers passed to <codeph>Initialise()</codeph> determine
+the extent of memory allocation required (in part by the LDD and in addition
+by request to the Resource Controller) and also the maximum number of concurrent
+client requests supported. </p> <p>The number of request objects created at
+initialisation should be the maximum number of concurrent (asynchronous) requests
+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
+it returns in a <xref href="GUID-A1DDD3E3-C009-3C02-895B-0B2D0EE67A9D.dita"><apiname>TResourceInfo</apiname></xref> object. There is also a method
+to get all the information for all the resources (<xref href="GUID-CF17E4E8-CFBC-31C2-B1CC-84D78006D046.dita"><apiname>GetAllResourcesInfo()</apiname></xref>).
+This function requires the allocation of buffer memory in which the information
+for all the resources is returned. <xref href="GUID-D3AB721D-35AB-36F9-B08D-10E44B6B8129.dita"><apiname>GetNoOfResources()</apiname></xref> returns
+the total number of resources available for access. </p> <p>The example below
+shows these functions in use. The amount of resources available are returned
+by <codeph>GetNoOfResources</codeph>. This figure is used to calculate the
+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;
+ TUint numResources=0;
+    if((r=gChannel.GetNoOfResources(numResources))!=KErrNone)
+        {
+        // Failed
+        return r;
+        }
+
+    RBuf buffer;
+    if((buffer.Create(numResources*sizeof(TResourceInfo)))!=KErrNone)
+        {
+        // Failed
+        return KErrGeneral;
+        }
+
+    buffer.SetLength(numResources*sizeof(TResourceInfo));
+
+    if((r=gChannel.GetAllResourcesInfo(buffer,numResources))!=KErrNone)
+        {
+        // Failed
+        return r;
+        }</codeblock> <p>Get the current resource state with <xref href="GUID-79CC3D60-3B7B-3FC2-8067-205165281E28.dita"><apiname>GetResourceState()</apiname></xref>.
+Passing <codeph>ETrue</codeph> results in the cached state being read rather
+than the current hardware state. The cached state is guaranteed to be the
+state that the resource was in when it was last changed or read from hardware.
+This is why it is important that all change requests are carried out through
+the Resource Controller. <codeph>readValue</codeph> returns the current prevailing
+level and <codeph>levelOwnerId</codeph> the ID of the client that owns the
+prevailing level. <codeph>GetResourceState()</codeph> can be cancelled using <xref href="GUID-BD242DA6-1D09-3770-94BF-CCCB396AEBE4.dita"><apiname>CancelGetResourceState()</apiname></xref> passing
+the resource ID of the resource that the original request was on. Use the
+method <xref href="GUID-2306456B-6502-3E49-B707-885D994E01C5.dita"><apiname>GetResourceIdByName()</apiname></xref> to get the ID of a resource
+from the resource's name. </p> <codeblock id="GUID-FA4561F7-9223-542E-9B3C-2E03AB06FE28" xml:space="preserve">// Get initial state
+TRequestStatus status;
+TBool cached = EFalse;
+TInt readValue;
+TInt levelOwnerId = 0;
+
+gChannel.GetResourceState(status, gSharedResource, cached, &amp;readValue, &amp;levelOwnerId);
+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
+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
+each resource that is in use by a specified client or retrieving the client
+information for each client using the specified resource. </p> <p>The API
+supports receiving a number of concurrent (asynchronous) requests from a client;
+the maximum number is determined by the number of resources that were specified
+at initialisation. If a client issues a request that exceeds its allocation,
+the error code <codeph>KErrUnderflow</codeph> is returned. </p> <p>Some synchronous
+methods take a binary value, <codeph>aIncludeKern</codeph>, which defaults
+to <codeph>EFalse</codeph>. If this parameter is set to <codeph>ETrue</codeph>,
+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
+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.
+Clients can also request to be notified when a resource reaches a specified
+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
+and direction values. </p> <p>To cancel a notification, use <xref href="GUID-51CAD2A1-C978-3EBD-984F-4C5C59D68885.dita"><apiname>CancelNotification()</apiname></xref> passing
+the resource ID from which the notification was requested. <b>Note</b>: Any
+notifications issued by a client must be cancelled before the client deregisters. </p> <p>It
+is not guaranteed that all changes of resource state result in a notification
+– a resource may change state more than once before a notification request
+is completed. In addition, it is not guaranteed that a resource is in the
+same state as it was when the notification was generated. For these reasons,
+it is the responsibility of the user-side client to read the state of a resource
+after receiving a notification. </p> <p id="GUID-ACA22305-8990-54F5-8098-80716F4A5AAE"><b>Changing the state of power
+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
+passing the ID of the resource on which the change is being requested and
+the requested state. </p> <p> <xref href="GUID-181BB8BF-EA17-3A5E-8B70-94265CBD15E1.dita"><apiname>CancelChangeResourceState()</apiname></xref> cancels
+all the <codeph>ChangeResourceState()</codeph> outstanding requests from the
+client on the specified power resource. For each outstanding request, the
+request object is removed from the doubly linked list within the Resource
+Controller and returned to the request object pool. </p> </section>
+<section id="GUID-DE8EE84C-D46F-504A-8254-C212B7C5D5C1"> <title>Kernel-side</title> <p>The Power Resource Manager component is implemented
+as a kernel extension. It has an exported public interface accessible to kernel-side
+components. Kernel components link to the resource manager kernel extension
+DLL (<filepath>resman.lib</filepath>). Extended features are compiled and
+exported in an additional library (<filepath>resmanextended.lib</filepath>).
+The export library is built from the generic layer. </p> <p>To ease the development
+of the PRM including the functionality provided by the generic layer and the
+mandatory PSL implementation, the generic layer is compiled into a kernel
+library (klib) (<filepath>resmanpsl.lib</filepath> for the basic version and <filepath>resmanextendedpsl.lib</filepath> for
+the extended version) which is included by the PSL to produce the kernel extension. </p> <ul>
+<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>
+<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>
+<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>
+<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>
+<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>
+<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>
+</ul> <p id="GUID-F5E775AB-F428-5800-8844-20A1BA41380D"><b>Concepts</b> </p> <ul>
+<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>
+<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>
+</ul> <p id="GUID-E8F3AF8E-387C-5285-A2B2-0B067F01BC3A"><b>Request messages</b> </p> <p>Request
+message objects represent a request for an operation on a resource by a client.
+For example a request to change a resource's level or notification if a resource's
+level changes. </p> <p>The client may attempt to increase its quota by requesting
+the allocation of request messages, but this may fail with <xref href="GUID-64F6761A-4716-37C3-8984-FF18FC8B7B7D.dita"><apiname>KErrNoMemory</apiname></xref>.
+A long latency resource request on may fail with <xref href="GUID-3673F75F-655F-3561-BD56-F7E1C6980810.dita"><apiname>KErrUnderflow</apiname></xref> if
+the number of request messages pre-allocated by the client has been exceeded
+and no more messages are left in the free pool to satisfy the request. </p> <p>The
+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
+levels</xref> and request messages is synchronously serviced in the context
+of the calling client, although this may result in memory allocation that
+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
+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
+callback object is a customised DFC that is used to signal the completion
+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
+create a resource callback object that encapsulates callback functions. </p> <p>The
+resource callback object is initialised with a callback function <xref href="GUID-F42CE2D1-6859-352A-89A7-01DFBB1FE249.dita"><apiname>TPowerResourceCbFn</apiname></xref>,
+a pointer to data passed to the callback function, the priority of the DFC
+within the queue (0 to 7, where 7 is highest) and optionally, a pointer to
+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>
+<li id="GUID-0912EE6D-A1DC-528D-8AEE-423D703C12CA"><p>the ID of the client
+is: </p> <ul>
+<li id="GUID-27C7A49B-BFCB-5D96-A129-7AE19A1CB430"><p>the client that issued
+an asynchronous operation - if the callback function is called as a result
+of an asynchronous resource state read operation </p> </li>
+<li id="GUID-F4181885-29F6-53DB-8555-EB735EF83F81"><p>the client that is currently
+holding the resource - if the callback function is called as a result of an
+asynchronous resource state change operation or resource state change notification. </p> </li>
+<li id="GUID-E8720BBB-BF9A-53FB-A123-AACA62A4F435"><p> <b>Note</b>: </p> <ul>
+<li id="GUID-87393CD1-684C-503C-9A2A-982961FC8169"><p>If -1 is passed as the
+client ID this specifies that no client is currently holding the resource. </p> </li>
+<li id="GUID-A3AB501B-004A-538E-B811-6733C76D213C"><p>In the extended version
+of PRM (see Dynamic and Dependant resources) if -2 is passed as the client
+ID in the callback function it signifies that the dynamic resource is deregistering.
+With dependency resources, the ID of the dependent resource is passed as the
+client ID if the state of the resource (specified in <codeph>aResourceId</codeph>)
+changes as a result of the dependant resources stage changing (whose ID is
+specified in <codeph>aClientId</codeph>). </p> </li>
+</ul> </li>
+</ul> <ul>
+<li id="GUID-A38B31E5-DB85-561A-A256-CF6FF025D9B0"><p>issued an asynchronous
+API (state read or change) which leads to the callback function being called </p> </li>
+<li id="GUID-F58DA60D-CA0E-5F82-9655-F1FF4D53D8B5"><p>requested the resource
+state change that leads to queuing a notification, which then leads to the
+callback function being called. </p> </li>
+</ul> </li>
+<li id="GUID-7ABBA59B-71A0-55CC-9722-5A569F95A881"><p>the resource ID - a
+client may have multiple notifications pending on different resources and
+a single callback function. The resource ID can be used to specify which resource
+change is being notified </p> </li>
+<li id="GUID-D18973A1-1E60-5335-BF98-1CCEB229730E"><p>the level of the resource
+when either: </p> <ul>
+<li id="GUID-9AC96325-FA2E-552F-A306-B0CCDA95B5BD"><p>the callback is called
+as a result of a notification of state change </p> </li>
+<li id="GUID-3886E475-28C5-5410-8801-0F4E9B273F13"><p>when the callback is
+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>
+<li id="GUID-5C65D90E-A9C8-5439-A8FE-B077AC00F4AF"><p>the requested level
+for the resource when the callback is 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-9E89A793-A838-3E48-AC24-17367E36EC05"><apiname>PowerResourceManager::ChangeResourceState()</apiname></xref>  </p> </li>
+</ul> </li>
+<li id="GUID-56181048-98E7-57BB-81D9-D863663F44C2"><p>the ID of the resource
+level owner </p> </li>
+<li id="GUID-5924CF16-4493-5845-ADB0-615968D9D8C7"><p>the error code returned
+when the callback is called as a result of an asynchronous request to change
+the state of the resource. This is not relevant when the callback is called
+as a result of a notification of state change </p> </li>
+<li id="GUID-8BAD3C01-7AA1-5C42-A52F-05C1BF5957D0"><p>a user defined argument
+that is passed to the constructor. </p> </li>
+</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
+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
+they can request operations on resources. </p> <p>Registration happens at
+different times for different clients: </p> <ul>
+<li id="GUID-491C4B9C-86BC-5AC2-870A-0FA46FDE3CA9"><p>kernel extensions register
+from their entry point during kernel boot </p> </li>
+<li id="GUID-8A6D66CC-DD34-5CC2-9AD3-BEEC7B540BA8"><p>device drivers for internal
+or external devices register on opening a channel. </p> </li>
+</ul> <p>When a client registers with the PRM, a client link object is removed
+from the free pool, populated with the relevant information, and a pointer
+to it is added to a container of clients within the PRM. If no free link exists
+within the pool, a number of client links are created in kernel heap. As a
+result, client registration may fail in out of memory situations. Client links
+are never destroyed after the client deregisters, but are released back into
+the free pool. </p> <p>Clients are registered by name; the PRM does not check
+that a name is unique unless the <codeph>DEBUG_VERSION</codeph> macro is enabled.
+The component registering the client should check that the name is unique.
+The ID returned is a handle to the client link object that represents the
+client in the PRM. </p> <p>On registration, a client also specifies the type
+of ownership (<xref href="GUID-19F111C8-00AC-3A2E-85A6-755DC322C870.dita"><apiname>TOwnerType</apiname></xref>) that applies. This is either: </p> <ul>
+<li id="GUID-E7A9ADE9-8590-5CB0-ADE9-8354BADCE77D"><p> <codeph>EOwnerThread</codeph> -
+the client ID is only used by the thread that registered the client to call
+the PRM APIs </p> </li>
+<li id="GUID-9EED259E-E339-59E0-BE96-8A33EA01AE98"><p> <codeph>EOwnerProcess</codeph> -
+the client ID is used by all threads in the process to call the PRM APIs. </p> </li>
+</ul> <p>The default is <codeph>EOwnerProcess</codeph>. </p> <p id="GUID-2DE84E1F-C466-5631-A007-EEF046905388"><b>Pre-allocating client level
+and request message objects </b> </p> <p>The controller has an initial pool
+of free client levels and request messages whose size can be configured at
+build time by the PSL. After registering with the PRM, a client can request
+the pre-allocation of a number of client levels and request messages to guarantee
+deterministic behaviour (to avoid out of memory failure) of the resource state
+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>.
+This allocation remains reserved to the specified client until the client
+is deregistered from the PRM. The number of client level objects reserved
+by a client depends on the number of resources on which a resource state change
+will be requested. </p> <p>A client may issue more than one request, possibly
+to the same resource, before the previous one completes, it is therefore more
+difficult to determine how many objects to pre-allocate. </p> <p>It is recommended
+that as many request messages as asynchronous long latency resources the client
+expects to use are pre-allocated. The free pool should be relied on for the
+situations when a resource is requested more than once before the first request
+completes. </p> <p id="GUID-A20D5070-99F1-5B1E-9D3E-D8769030BDEE"><b>Deregistration</b> </p> <p>All
+notifications and asynchronous requests must be cancelled before the client
+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
+that have been registered with the Controller should be deregistered before
+they are deleted as the Controller may attempt to issue them. Deleting a notification
+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
+level objects</xref> and request objects reserved by the client remain reserved
+for that client until it deregisters. When the client is deregistering these
+objects are moved to free pool by the PRM. </p> <p>Client deregistration can
+result in a resource state change: </p> <ul>
+<li id="GUID-8C4B2F9D-7B4D-5BC4-8B8C-02D1AEFDF1C5"><p>If the resource is shared
+and the deregistering client owned the prevailing level, the resource state
+is moved to the next level according to its sense. If it is a custom sense
+resource, the resource state is changed as a result of calling a custom function. </p> </li>
+<li id="GUID-DE1341E0-C392-5982-8A0D-3CCE9A8DC950"><p>If the resource is not
+shared or if it is shared but the client is the only one using it at the time
+of deregistration, the resource is moved to the <i>default</i> state. The
+default state is only known by the PSL. </p> </li>
+</ul> <p>A deregistering client can have a number of active requirements on
+a number of resources and more than one of these resources may need to change
+state as a result of the client deregistering. The combined operation of deregistering
+the client and adjusting the state of all resources it shares executes synchronously.
+That is, the client thread is blocked throughout whether the resources whose
+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
+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>,
+information can also be retrieved for all of the resources used by the specified
+client using <xref href="GUID-8C32B87E-0EBB-34EF-8C6B-6AB159B4CB09.dita"><apiname>GetInfoOnResourcesInUseByClient()</apiname></xref>. This function
+takes a buffer that must be the size of the information structure multipled
+by the number of resources in use by the client, this figure can be retrieved
+using the method <xref href="GUID-000DC2CE-9C7B-3C0C-AABF-2D5B2C2EFA1D.dita"><apiname>GetNumResourcesInUseByClient()</apiname></xref>. Specify
+the resource ID as zero to retrieve all information from all the clients registered
+with PRM. </p> <p>To get information about clients using a resource, use the
+method <xref href="GUID-EADA4695-1058-34B6-963C-42BFC794C296.dita"><apiname>GetInfoOnClientsUsingResource()</apiname></xref>. Use the number
+of clients using a resource using <xref href="GUID-EABEB759-9BF4-3278-B14C-8B887007C1D3.dita"><apiname>GetNumClientsUsingResource()</apiname></xref>.
+Specify the client ID as zero to retrieve all information from all the resources
+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
+retrieve resource state information. This function can be called synchronously
+or asynchronously. Asynchronous calls require the client to create a callback
+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
+callback object (called in the client’s context) is invoked when the state
+of the resource is available. The third argument of the callback function
+carries the resource state. If this function is called with <codeph>aCached</codeph> set
+as <codeph>ETrue</codeph>, then the callback function is called in the context
+of the calling thread both for instantaneous and long latency resources, thus
+blocking the calling thread throughout. </p> <p>For instantaneous resources, <xref href="GUID-79CC3D60-3B7B-3FC2-8067-205165281E28.dita"><apiname>GetResourceState()</apiname></xref> executes
+in the context of the calling thread and, if specified, the callback function
+is called after getting the state of the requested resource. The calling thread
+is blocked throughout. </p> <p> <codeph>GetResourceState()</codeph> takes
+a boolean value that determines from where the requested resource state information
+is retrieved: </p> <ul>
+<li id="GUID-21044D5D-142F-5E05-9743-3218E99DD7DC"><p>ETrue - the resource
+state is the cached value, this value is returned faster but is not guaranteed
+to be correct </p> </li>
+<li id="GUID-A221B599-2EB3-5E0E-9D3E-E2333BF0AD0F"><p>EFalse - the resource
+state is read from the resource, this value takes longer to return, but is
+much more likely to be correct. </p> </li>
+</ul> <p id="GUID-AA2EABEC-477F-54BD-AD1A-F2EF7B6BA5B7"><b>Changing the state of power
+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
+is used to request a change on a resource. When a state change is requested
+on a shared resource, only the minimum state change that satisfies the request
+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>
+<li id="GUID-5F6B6127-BA40-51BC-829E-90936A8B3FB3"><p>the ID of the client
+requesting the change </p> </li>
+<li id="GUID-5FF24DB5-CA57-571A-846E-6BECB91025A9"><p>the ID of the resource
+that the change is to take place </p> </li>
+<li id="GUID-6764FB93-36D4-56FC-85EC-8EA015ED6F9C"><p>the new state of the
+resource </p> </li>
+<li id="GUID-77092FD0-044D-528B-B62F-56166F21CB3B"><p>a pointer to the resource
+callback object. </p> </li>
+</ul> <p>The requested state is either a binary value for a binary resource,
+an integer level for a multilevel resource or some platform specific token
+for a multi-property resource. The pointer to the callback object is defined
+by the class <xref href="GUID-9B43C51D-56F7-35E0-BDD5-5D2F27924383.dita"><apiname>TPowerResourceCb</apiname></xref>; its use is optional and
+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
+callback object is specified, then <codeph>ChangeResourceState()</codeph> is
+executed asynchronously and returns immediately. The actual resource change
+happens in the resource controller thread and the callback function encapsulated
+in the callback object is called after the resource is changed. </p> <p>If
+the callback object is NULL, then <codeph>ChangeResourceState()</codeph> executes
+synchronously, meaning the client thread is blocked until the resource state
+has changed. The PRM panics if the synchronous version of this API for long
+latency resources is called from DFC thread 0. </p> <p><b>Changing resource state on an instantaneous resource </b> </p> <p>On an
+instantaneous resource <codeph>ChangeResourceState()</codeph> always executes
+synchronously. </p> <p>If a callback object is specified, then the callback
+function encapsulated in the callback object is called from the client thread
+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
+cancel change requests on a resource. When the client no longer requires a
+level on a resource use the method <xref href="GUID-54784583-DB6D-3847-800E-65DE7ADB8DC6.dita"><apiname>DeRegisterClientLevelFromResource()</apiname></xref> to
+remove a client level object from a resource. </p> <p id="GUID-198CE312-343E-535D-8EE5-D615A7AC9265"><b>Requesting notifications</b> </p> <p>Clients
+can request notification of a state change on a resource. Notifications are
+issued post resource change and invoke the callback function encapsulated
+in a notification object. The callback is executed in the context of the requesting
+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>
+<li id="GUID-DC4C6378-A8A3-564D-8255-F4A91CD498AF"><p>the ID of the client
+requesting the notification </p> </li>
+<li id="GUID-8D08E63E-EEC4-5812-8E42-0A5DAD5DB718"><p>the ID of the resource
+for which notification of state changes is being requested </p> </li>
+<li id="GUID-3C3E2C2F-29B7-5D86-B7A6-A03B814A6C14"><p>a reference to a notification
+object encapsulating a callback function called whenever a resource state
+change takes place. </p> </li>
+</ul> <p>A notification may be unconditional or conditional. An unconditional
+notification request notifies the client each time the state changes. A conditional
+notification request notifies the client when a threshold has been met in
+the direction specified. A conditional notification has these additional parameters: </p> <ul>
+<li id="GUID-0734A09A-010A-57B4-A822-25D709CA55E9"><p>aThreshold - the level
+of the resource state that triggers the notification </p> </li>
+<li id="GUID-FCE1EE43-C431-5967-B778-A7B701CF4983"><p>aDirection - the direction
+the resource state change that triggers a notification: </p> <ul>
+<li id="GUID-3E49268F-EF11-5F18-AC23-16CD26FFA37E"><p>EFalse - the resource
+state is equal to or below the threshold </p> </li>
+<li id="GUID-7FA60FF1-890D-5726-A0CB-3D866504E11F"><p>ETrue - the resource
+state is equal to or above the threshold. </p> </li>
+</ul> </li>
+</ul> <p>The client must create the notification object (<xref href="GUID-80CA4C5E-9575-3EE9-A983-AC74B9DBE351.dita"><apiname>DPowerResourceNotification</apiname></xref>)
+in the kernel heap or data section. <b>Note</b>: The client may share the
+same callback function between several notifications but a unique DFC must
+be created and queued for each notification. </p> <p>Because notifications
+result in DFCs being queued, it is not possible to guarantee that all resource
+state changes are notified. If the resource state changes again, before the
+first DFC runs, it does not generate a separate notification. It is also not
+possible to guarantee that by the time the notification callback runs the
+resource state is still the same state that caused the notification to be
+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
+cancel a notification request. It takes a reference to the notification object
+associated with the original notification request that is being cancelled. </p> </section>
+</conbody></concept>
\ No newline at end of file