Adaptation/GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita
author Graeme Price <GRAEME.PRICE@NOKIA.COM>
Fri, 15 Oct 2010 14:32:18 +0100
changeset 15 307f4279f433
permissions -rw-r--r--
Initial contribution of the Adaptation Documentation.

<?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>