Adaptation/GUID-B1CE51BC-B452-5FC9-9C00-35447AF40671.dita
changeset 15 307f4279f433
equal deleted inserted replaced
14:578be2adaf3e 15:307f4279f433
       
     1 <?xml version="1.0" encoding="utf-8"?>
       
     2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
       
     3 <!-- This component and the accompanying materials are made available under the terms of the License 
       
     4 "Eclipse Public License v1.0" which accompanies this distribution, 
       
     5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
       
     6 <!-- Initial Contributors:
       
     7     Nokia Corporation - initial contribution.
       
     8 Contributors: 
       
     9 -->
       
    10 <!DOCTYPE concept
       
    11   PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
       
    12 <concept id="GUID-B1CE51BC-B452-5FC9-9C00-35447AF40671" xml:lang="en"><title> Implement
       
    13 the controllable power resources</title><shortdesc>This document describes how to write and use power resources. </shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    14 <section id="GUID-7E91DB93-F9D6-4B93-8BAF-E25642F63C57"><title>Purpose</title> <p>Implement your power resource according
       
    15 to the type of resource you wish to support. </p> <p><b>Introduction</b> </p> <p>Power
       
    16 resources controlled by the PRM can be turned on, off and varied with software. </p> <p>See
       
    17 the <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-4CC0C003-1952-5CAD-A7C5-163C5DDA52C8">Power
       
    18 resources</xref> section for detailed information about resources. There are
       
    19 five main types of resource that can be implemented: </p> <ul>
       
    20 <li id="GUID-C67FB012-A1D6-5047-AD5A-18CF62971B2B"><p>static resources - derived
       
    21 from the <xref href="GUID-DB7DDF4C-57EF-34FF-B3CD-13C5CD51A125.dita"><apiname>DStaticPowerResource</apiname></xref> base class, </p> </li>
       
    22 <li id="GUID-6170B4D1-2AAD-52C7-88E0-D6BBE8CAFF63"><p>static resource that
       
    23 support dependancy - derived from the <xref href="GUID-88C28976-67DF-3109-8D35-FA30A733C581.dita"><apiname>DStaticpowerResourceD</apiname></xref> base
       
    24 class, </p> </li>
       
    25 <li id="GUID-FAE7BFE3-7C2D-5DB7-A8FF-B7E4F37F5BAF"><p>dynamic resources -
       
    26 derived from the <xref href="GUID-CA01041D-8FD6-3B5B-BB5D-A5159DF7C9AB.dita"><apiname>DDynamicPowerResource</apiname></xref> base class. Create
       
    27 dynamic resources in the kernel data section or in the heap, </p> </li>
       
    28 <li id="GUID-9586824D-FB68-5DC1-B743-9ED551FA286D"><p>dynamic resource that
       
    29 support dependancy - derived from the <xref href="GUID-6B224A9F-D2B9-3289-922D-766EF093FCD6.dita"><apiname>DDynamicPowerResourceD</apiname></xref>. </p> </li>
       
    30 <li id="GUID-AF8A571A-2AB6-5063-BFA5-3FF8509C95C7"><p>custom sense resources
       
    31 - when shared the power level of this resource may be increased or decreased
       
    32 freely by some privileged clients but not by others, which are bound by the
       
    33 requirement of the privileged clients. </p> </li>
       
    34 </ul> <p> <b>Note</b>: dynamic resources and resource dependancies are only
       
    35 supported in the extended version of the PRM. 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 requirements</xref>. </p> </section>
       
    36 <section id="GUID-D50E75DC-115E-42FD-9111-7A70E3087F33"><title> Implementing power resources </title> <p>The following tasks
       
    37 are covered in this tutorial: </p> <ul>
       
    38 <li id="GUID-2C4FDE84-401B-5520-B050-9FD475A63863">Create your resource by <p> <xref href="GUID-B1CE51BC-B452-5FC9-9C00-35447AF40671.dita#GUID-B1CE51BC-B452-5FC9-9C00-35447AF40671/GUID-3021B2EA-9829-515C-9074-2D2D0D7A5510">Override
       
    39 the pure virtual functions</xref>, </p> </li>
       
    40 <li id="GUID-6492CDEF-524E-5A3A-82AB-1D0E0B8E9D28"><p> <xref href="GUID-B1CE51BC-B452-5FC9-9C00-35447AF40671.dita#GUID-B1CE51BC-B452-5FC9-9C00-35447AF40671/GUID-A5D57D89-4499-5C85-80D5-5A7DC5644983">Create resource dependencies</xref>, </p> </li>
       
    41 <li id="GUID-56A63835-D0B5-5C32-95D0-623A0D21AEF4"><p> <xref href="GUID-B1CE51BC-B452-5FC9-9C00-35447AF40671.dita#GUID-B1CE51BC-B452-5FC9-9C00-35447AF40671/GUID-9526B472-00ED-583A-8BFC-C02363D4DFA2">Create custom resources</xref>. </p> </li>
       
    42 </ul> <p id="GUID-3021B2EA-9829-515C-9074-2D2D0D7A5510"><b>Override the pure
       
    43 virtual functions</b> </p> <p>The pure virtual functions of <xref href="GUID-DB7DDF4C-57EF-34FF-B3CD-13C5CD51A125.dita"><apiname>DStaticPowerResource</apiname></xref> or <xref href="GUID-CA01041D-8FD6-3B5B-BB5D-A5159DF7C9AB.dita"><apiname>DDynamicPowerResource</apiname></xref> must
       
    44 be implemented. </p> <p><b>Constructor</b> </p> <p>Information about the resource
       
    45 based on the resources category must be set in the <codeph>iFlags</codeph> bit
       
    46 mask. Static variables that define a resources classification can be found
       
    47 within <filepath>32\include\drivers\resource.h</filepath>. </p> <p>Each resource
       
    48 is classified based on: </p> <ul>
       
    49 <li id="GUID-08E6311D-6403-56CB-B91B-57C93F8CA208"><p>usage, </p> </li>
       
    50 <li id="GUID-55F93FDB-137F-51D3-A1E3-F048B279425E"><p>operating levels, </p> </li>
       
    51 <li id="GUID-4DD3D8E1-273A-5BFE-8A65-11B9DDE84E4D"><p>latency, </p> </li>
       
    52 <li id="GUID-9B00B021-E620-50EA-B2D2-2F18111F5C1E"><p>resource sense. </p> </li>
       
    53 </ul> <p>Below is the example implementation of derived class constructor </p> <codeblock id="GUID-1DE1E1CA-7212-5E30-85BF-C67578F9CEC8" xml:space="preserve">// multilevel, shared, long latency, read and write, positive resource. 
       
    54 DMLSHLGLSPResource::DMLSHLGLSPResource() : DStaticPowerResource(KDBSHLGLSPResource, E_ON), 
       
    55                      iMinLevel(E_OFF), iMaxLevel(E_ON), iCurrentLevel(E_ON), iPolled(ETrue)
       
    56     {
       
    57     iFlags = EMultilevel | KShared | KLongLatencySet | KLongLatencyGet;
       
    58     . . .   
       
    59     }</codeblock> <p><b> GetInfo()</b> </p> <p>The PIL uses <xref href="GUID-66D96ADA-1C26-3293-9F92-FD65E08D6158.dita"><apiname>GetInfo()</apiname></xref> to
       
    60 get resource information. The default implementation of this function provides
       
    61 generic information about the resource by updating the passed descriptor that
       
    62 contains an information structure <xref href="GUID-FA4D9A07-041C-303C-BF96-2E444DD47024.dita"><apiname>TPowerResourceInfoV01</apiname></xref>.
       
    63 Derived implementations must fill in all the PSL specific fields and call
       
    64 the base class implementation. Below is an example implementation. </p> <codeblock id="GUID-EB61E8FF-146C-5825-8F16-869FE4DD5B44" xml:space="preserve">TInt DH4SndFclkResource::GetInfo(TDes8* info) const
       
    65     {
       
    66     __KTRACE_OPT(KRESMANAGER, Kern::Printf("&gt;DH4SndFclkResource::GetInfo\n"));
       
    67 
       
    68     /** Call base class implementation to fill generic details */
       
    69     DStaticPowerResource::GetInfo((TDes8*) info);
       
    70     TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*) info;
       
    71     buf1-&gt;iMinLevel = iMinLevel;
       
    72     buf1-&gt;iMaxLevel = iMaxLevel;
       
    73     __KTRACE_OPT(KRESMANAGER, Kern::Printf("&lt;DH4SndFclkResource::GetInfo\n"));
       
    74     return KErrNone;
       
    75     }</codeblock> <p>The member variables of the <codeph>TPowerResourceInfoV01</codeph> structure
       
    76 are reserved for PSL information. These can be used to return resource specific
       
    77 information to clients. </p> <p><b>DoRequest()</b> </p> <p> <xref href="GUID-9D910016-5611-30DD-A139-EE46705A4912.dita"><apiname>DoRequest()</apiname></xref> is
       
    78 used by the PIL to control resources. For example, to change and read the
       
    79 state of resources. <codeph>DoRequest()</codeph> takes a <xref href="GUID-D204F4A7-8CC8-3EB2-8371-1D1BFD903390.dita"><apiname>TPowerRequest</apiname></xref> object
       
    80 that contains all the request information. <b>Note</b>: This function needs
       
    81 to be implemented for all resources. </p> <p>Below is an example <xref href="GUID-9D910016-5611-30DD-A139-EE46705A4912.dita"><apiname>DoRequest()</apiname></xref> function
       
    82 implementation for a binary, instantaneous resource. </p> <codeblock id="GUID-D5AE04C1-7A9D-5270-840F-6CD662FB46A2" xml:space="preserve">TInt DH4MmcCtrllerPwrResource::DoRequest(TPowerRequest&amp; aRequest)
       
    83     {
       
    84     TInt retVal = KErrNone;
       
    85     TUint16 config;
       
    86     /** Enable/disable the MMC controller by programming the MMC controller 'CON' register- 'POW' bit */
       
    87     if (aRequest.ReqType()==TPowerRequest::EGet) 
       
    88         {
       
    89         PRM_PSL_RESOURCE_GET_STATE_START_TRACE
       
    90         config = OMAPMMC_GET_REG(KHoMMC_Con_Reg);
       
    91         if(config &amp; KHtMMC_PowerUp)
       
    92             {
       
    93             aRequest.Level() = 1;
       
    94             iCurLevel = 1;
       
    95             }
       
    96         else
       
    97             {
       
    98             aRequest.Level() = 0;
       
    99             iCurLevel = 0;
       
   100             }
       
   101         PRM_PSL_RESOURCE_GET_STATE_END_TRACE
       
   102         }
       
   103     else if(aRequest.ReqType()==TPowerRequest::ESetDefaultLevel)
       
   104         {
       
   105         PRM_PSL_RESOURCE_CHANGE_STATE_START_TRACE
       
   106         OMAPMMC_MOD_REG(KHoMMC_Con_Reg, KHtMMC_PowerUp, KClear32);
       
   107         iCurLevel = iDefaultLevel;
       
   108         aRequest.Level() = iDefaultLevel;
       
   109         PRM_PSL_RESOURCE_CHANGE_STATE_END_TRACE
       
   110         }
       
   111     else 
       
   112         {
       
   113         PRM_PSL_RESOURCE_CHANGE_STATE_START_TRACE
       
   114         if(aRequest.Level() == 1)
       
   115             {
       
   116             OMAPMMC_MOD_REG(KHoMMC_Con_Reg, KClear32, KHtMMC_PowerUp);
       
   117             }
       
   118         else
       
   119             {
       
   120             OMAPMMC_MOD_REG(KHoMMC_Con_Reg, KHtMMC_PowerUp, KClear32);
       
   121             }
       
   122         iCurLevel = aRequest.Level();
       
   123         PRM_PSL_RESOURCE_CHANGE_STATE_END_TRACE
       
   124         }
       
   125     return retVal;
       
   126     }</codeblock><p>The DoRequest function implementation should take care
       
   127 of blocking the Resource Controller thread as operations on a long latency
       
   128 resource take a significant amount of time to complete (in hardware). Usually
       
   129 the request completion is notified either through an ISR (interrupt driven)
       
   130 or through register setting (polling wait) by hardware. </p><p>Below is an
       
   131 example <codeph>DoRequest()</codeph> implementation for a long latency resource. </p> <codeblock xml:space="preserve"> TInt DH4MmcPowerResource::DoRequest(TPowerRequest&amp; aRequest)
       
   132     {
       
   133     TUint8 iMenelausConf;
       
   134     TInt retVal = KErrNone;
       
   135 
       
   136     /** Access to Menelaus registers is over I2C bus. This is a long latency synchronous operation.
       
   137     Create a Menelaus Request structure and send it to Menelaus chip, Wait until a response is received */
       
   138 
       
   139     if (aRequest.ReqType()==TPowerRequest::EGet)
       
   140         {
       
   141         // Frame the request
       
   142         ... 
       
   143         }
       
   144 				// Default level is off.
       
   145     else if (aRequest.ReqType() == TPowerRequest::ESetDefaultLevel)
       
   146         {
       
   147         // Frame request to move the resource to default state
       
   148         ... 
       
   149         }
       
   150 				// EChange
       
   151     else 
       
   152        {
       
   153        // Frame request to set the requested resource state
       
   154        ...     
       
   155        }
       
   156     
       
   157     // Request the operation on the hardware
       
   158     retVal = Menelaus::AccessRegister(iMenelausReq);
       
   159     
       
   160     // Wait for the request to complete  
       
   161     __KTRACE_OPT(KPBUS1, Kern::Printf("Waiting for menelaus req to signal sem\n"));
       
   162     NKern::FSSetOwner(&amp;iSemaphore,NULL);
       
   163     iSemaphore.iCount = 0;	
       
   164 
       
   165     // This will be signalled in Menelaus access functions callback below
       
   166     NKern::FSWait(&amp;(iSemaphore)); 
       
   167 	
       
   168     // Menelaus chip has responded
       
   169     if(iMenelausAccessErr == KErrNone)
       
   170         {
       
   171         switch(iMenelausState)
       
   172             {
       
   173             case EMenelausRead:
       
   174                 // Return 0/1 depending on the value set
       
   175                 iMenelausConf = (*(iRdBuffer.Ptr())) &amp; KHoMenelausVmmcModeMask;		                    
       
   176                 if(iMenelausConf == 3)
       
   177                     {
       
   178                     iCurLevel=aRequest.Level()=1; 
       
   179                     }
       
   180                 else 
       
   181                     {
       
   182                     iCurLevel=aRequest.Level()=0;
       
   183                     }
       
   184                 PRM_PSL_RESOURCE_GET_STATE_END_TRACE
       
   185                 break;
       
   186 
       
   187             case EMenelausSingleWrite:
       
   188                 iCurLevel = aRequest.Level();
       
   189                 PRM_PSL_RESOURCE_CHANGE_STATE_END_TRACE
       
   190                 break;
       
   191             }
       
   192         }
       
   193         return iMenelausAccessErr;
       
   194     }
       
   195 
       
   196 /** Below is the Menelaus access functions callback where the semaphore is signalled. */
       
   197 void DH4MmcPowerResource::MenelausAccessDone(TAny* aPtr, TInt aResult)
       
   198     {
       
   199     DH4MmcPowerResource* ptr = reinterpret_cast&lt;DH4MmcPowerResource*&gt;(aPtr);
       
   200     ptr-&gt;iMenelausAccessErr = aResult;
       
   201     if(aResult != KErrNone)
       
   202         {
       
   203         __KTRACE_OPT(KRESMANAGER, 
       
   204         Kern::Printf("Menelaus::MenelausAccessRegister ERR(%d)\n", aResult));
       
   205         }
       
   206 				// Signal the waiting thread
       
   207     NKern::FSSignal(&amp;(ptr-&gt;iSemaphore)); 
       
   208     return;
       
   209     }</codeblock><p id="GUID-A5D57D89-4499-5C85-80D5-5A7DC5644983"><b>Create
       
   210 resource dependencies</b> </p> <p>A resource has a dependency if the state
       
   211 of the resource depends on the state of one or more resources. For example,
       
   212 a clock whose frequency is derived from another clock or voltage is a dependent
       
   213 resource. The PSL usually handles resource dependencies transparently. However,
       
   214 if the resources have public users (clients of the PRM), then these resources
       
   215 should be registered with the PRM as <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-473BBE32-6831-52BE-8752-CB6DBBBABD2C">Resource
       
   216 dependencies</xref> that are linked. </p> <p>Each dependency must be assigned
       
   217 a priority value. The priority is used by the PIL when propagating the change
       
   218 and propagating the request for notifications. Each link stemming from a resource
       
   219 must have a unique priority value. </p> <p> <b>Note</b>: Resource dependencies
       
   220 are only supported in the extended version of the PRM. Only long latency resources
       
   221 are allowed to have dependents and no closed loop dependencies are allowed. </p> <p><b> Register
       
   222 resource dependencies for dynamic and static resources</b> </p> <p>Static
       
   223 resources that support dependencies are created and registered with the PRM
       
   224 during resource controller creation time and are derived from <codeph>DStaticPowerResourceD</codeph>: </p> <codeblock id="GUID-1C7E2D5F-8C76-5D4D-84FA-259DE943742E" xml:space="preserve">DXXXStaticPowerResourceD : public DStaticPowerResourceD
       
   225     {
       
   226 public:
       
   227     DXXXStaticPowerResourceD();
       
   228     TInt DoRequest(TPowerRequest &amp;req);
       
   229     TInt GetInfo(TDes8* aInfo) const;
       
   230     TChangePropagationStatus TranslateDependentState(TInt aDepId, TInt aDepState, TInt&amp; aResState);
       
   231 private:
       
   232     TInt iMinLevel;
       
   233     TInt iMaxLevel;
       
   234     TInt iCurrentLevel;
       
   235     ...
       
   236     };</codeblock> <p>Dependencies between static resources should be established
       
   237 by the PSL before registering these resources with the PIL. Use the <xref href="GUID-1CD49D40-1FF9-301C-8160-02A007485ADE.dita#GUID-1CD49D40-1FF9-301C-8160-02A007485ADE/GUID-806D0179-FC98-3106-BCBA-0D3634B43815"><apiname>DStaticPowerResourceD::AddNode()</apiname></xref> function
       
   238 provided in the base class to establish a dependency link between static resources.
       
   239 See <xref href="GUID-66FD040B-133E-57CF-80DD-9369F62709C6.dita#GUID-66FD040B-133E-57CF-80DD-9369F62709C6/GUID-A912A328-D646-5516-9731-FFA7F3B2EDDA">Creating
       
   240 dependencies between static resources</xref>. </p> <p>Dynamic resources that
       
   241 support dependency are derived from <xref href="GUID-6B224A9F-D2B9-3289-922D-766EF093FCD6.dita"><apiname>DDynamicPowerResourceD</apiname></xref>.
       
   242 These can be registered and deregistered from the PRM at any time after the
       
   243 PRM is fully initialised. Dependencies between resources are established by
       
   244 the client using <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-30B2271B-FA2A-53FE-A1F1-0A3E36B95883" xml:space="preserve">DXXXDynamicPowerResourceD : public DDynamicPowerResourceD
       
   245     {
       
   246 public:
       
   247     DXXXDynamicPowerResourceD();
       
   248     TInt DoRequest(TPowerRequest &amp;req);
       
   249     TInt GetInfo(TDes8* aInfo) const;
       
   250     TChangePropagationStatus TranslateDependentState(TInt aDepId, TInt aDepState, TInt&amp; aResState);
       
   251 private:
       
   252     TInt iMinLevel;
       
   253     TInt iMaxLevel;
       
   254     TInt iCurrentLevel;
       
   255     ...
       
   256     };</codeblock> <p>Dependencies can be established between a dynamic resource
       
   257 and a static (dependency enabled) resource using the same API. A client can
       
   258 deregister dependencies between a pair of dynamic resource (or between a dynamic
       
   259 and static resource) using <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>.
       
   260 When a dynamic resource that supports dependency deregisters from the PRM,
       
   261 dependencies are removed automatically by the PIL. </p> <p><b>Change the state
       
   262 of dependent resources</b> </p> <p>When a state change is requested by a client
       
   263 on any resource in a dependency tree before proceeding with the change the
       
   264 PIL must check if the change is allowed by its dependents and the ones it
       
   265 depends on. The PIL does this by calling the <xref href="GUID-E71F94F6-A4BB-3C85-8E2E-8E3ABAA85897.dita"><apiname>TranslateDependentState()</apiname></xref> function
       
   266 on each resource. This is a pure virtual function in the base class and must
       
   267 be implemented in the derived class. </p> <p>This function is called by the
       
   268 PIL prior to a resource change on any of its dependents. The function returns
       
   269 one of these values: </p> <ul>
       
   270 <li id="GUID-CEABEBE0-34BB-5CD0-861E-CDB87A066C8B"><p> <codeph>EChange</codeph> -
       
   271 If the resource accepts the state change of the dependent resource and, as
       
   272 a result of the dependent resources state change this resource needs to change
       
   273 its own state. The new state of this resource is updated in <codeph>aResState</codeph>, </p> </li>
       
   274 <li id="GUID-A22403B9-38C9-571E-9E14-C7BD1CB032F2"><p> <codeph>ENoChange</codeph> -
       
   275 if the resource accepts the dependent resources state change and this resource
       
   276 does not need to change its state, </p> </li>
       
   277 <li id="GUID-EE30E093-85A0-5205-B1C7-6C36A5410BB1"><p> <codeph>ENotAllowed</codeph> -
       
   278 if the resource does not accept the dependent resources state change. </p> </li>
       
   279 </ul> <codeblock id="GUID-453D7F61-4187-50DC-B641-34A06AEB722B" xml:space="preserve">TChangePropagationStatus DXXDependResource::TranslateDependentState(TInt /*aDepId*/, TInt aDepState,
       
   280    TInt&amp; aResState)
       
   281     {
       
   282     /* Switch ON if the dependent resource is ON */
       
   283     if((aDepState == 1) &amp;&amp; (iCurrentLevel == 0)
       
   284         {
       
   285         aResState = iMaxLevel;
       
   286            return EChange;
       
   287            }
       
   288 
       
   289     /* Don’t allow dependent to OFF, if this is still ON */
       
   290     else if (aDepState == 0) &amp;&amp; (iCurrentLevel == 1)
       
   291         {
       
   292         return ENotAllowed;
       
   293         }
       
   294 
       
   295     return ENoChange;
       
   296     }</codeblock> <p id="GUID-9526B472-00ED-583A-8BFC-C02363D4DFA2"><b>Create
       
   297 custom resources</b> </p> <p>Clients on a shared resource may have different
       
   298 requirements on the state of a shared resource. The resource sense is used
       
   299 by the PIL to determine whose requirement prevails: </p> <ul>
       
   300 <li id="GUID-495628CC-D257-598F-B420-2784749B1083"><p>positive sense resources
       
   301 - when shared can have their value increased without prejudice to their clients, </p> </li>
       
   302 <li id="GUID-D4D7CB6D-F99B-568E-9F38-429196599F4F"><p>negative sense resources
       
   303 - when shared can have their value decreased without prejudice to their clients, </p> </li>
       
   304 <li id="GUID-0BB26EA3-F22B-5C7D-8999-14DB75D066CA"><p>custom sense resources
       
   305 - when shared may be increased or decreased freely by some privileged clients
       
   306 but not by others, which are bound by the requirement of the privileged clients. </p> </li>
       
   307 </ul> <p>A custom function must be supplied for every <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-4CC0C003-1952-5CAD-A7C5-163C5DDA52C8">Power resources</xref> resource. This function is called by the PIL every
       
   308 time a change request is issued to determine if the change requested by the
       
   309 client is allowed as a decision to allow the resource change is determined
       
   310 solely by the PSL. The resource object contains a pointer that must be set
       
   311 at construction for custom sense resources by calling this function: </p> <codeblock id="GUID-31716524-4902-5E87-A51F-2EF63DA6D500" xml:space="preserve">inline void SetCustomFunction(TCustomFunction aCustomFunction)</codeblock> <p>This
       
   312 function sets the custom function for the resource. If a custom function is
       
   313 not supplied for a custom sense resource the PIL panics during a resource
       
   314 state change. An example of a custom sense resource is a shared domain clock
       
   315 when a domain client uses it as a bit clock. </p> <p> <xref href="GUID-5FDBF9F8-9BC4-3E3B-9A28-5046C65788E2.dita"><apiname>TCustomFunction</apiname></xref> is
       
   316 a function pointer: </p> <codeblock id="GUID-A0ECC7F5-A410-50DA-9723-09C1C080927C" xml:space="preserve">typedef TBool (*TCustomFunction) (TInt&amp; /*aClientId*/,
       
   317                                   TUint /*aResourceId*/,
       
   318                                   TInt&amp; /*aLevel*/,
       
   319                                   TAny* /*aLevelList*/);</codeblock> <p>The
       
   320 values held in TCustomFunction are: </p> <ul>
       
   321 <li id="GUID-5E1EF546-098D-5940-8BD0-4AF2B70861E4"><p>the Id of the client
       
   322 requesting the change, </p> </li>
       
   323 <li id="GUID-A8E1B48A-C36C-5D88-9388-BE40902832AE"><p>the Id of the resource
       
   324 on which the change is requested (this allows a single function to handle
       
   325 multiple resources), </p> </li>
       
   326 <li id="GUID-CDC2D3F7-2E82-5E56-864B-E0901B57FE83"><p>the level the client
       
   327 is requesting, </p> </li>
       
   328 <li id="GUID-57C1C8CC-411D-54B7-9548-2D0C5DFB6B3F"><p>a pointer to the list
       
   329 of the resource’s <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-F47D2098-16A7-5590-A68A-7AE4B2DAB462">client
       
   330 levels</xref>. </p> </li>
       
   331 </ul> <p>Custom functions can be set at any time before a resource state change
       
   332 is requested on a resource. Ideally a custom function is set at resource creation
       
   333 time in the resource's constructor. </p> <codeblock id="GUID-6B688BFC-8D7A-5D7C-B17D-B4D3579230F4" xml:space="preserve">DBSHLGLSCResource::DBSHLGLSCResource() : DStaticPowerResource(KDBSHLGLSCResource, E_ON), iMinLevel(E_OFF), iMaxLevel(E_ON), iCurrentLevel(E_ON), iPolled(EFalse)
       
   334     {
       
   335     iFlags = KMultiLevel | KShared | KLongLatencySet | KSenseCustom;
       
   336     SetCustomFunction(CustomFunction);
       
   337  ...
       
   338     }</codeblock> <p>The decision to allow the requested resource state change
       
   339 is specified in the custom function return value. This is <codeph>ETrue</codeph> if
       
   340 the change is allowed and <codeph>EFalse</codeph> if the change is not allowed. </p> <p>The
       
   341 function can change the state of the resource to a level other than the one
       
   342 requested and can choose a client other than the passed client to hold the <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-121C14E3-D446-565E-AAAE-C43C131ACD3C">Caching
       
   343 the prevailing level</xref> of the resource. </p> <p><b>Supporting dependencies </b> </p> <p>If
       
   344 the custom sense resource supports dependencies then use the function pointer <xref href="GUID-60A17842-3E3B-3748-8F91-F5ED912E642A.dita"><apiname>TDependencyCustomFunction</apiname></xref>.
       
   345 This takes an additional parameter that specifies the resource <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>. </p> </section>
       
   346 </conbody><related-links>
       
   347 <link href="GUID-2ECF13A1-9D56-5740-A09F-8267E6A45DD9.dita"><linktext>Porting the
       
   348 Power Resource Manager</linktext></link>
       
   349 <link href="GUID-66FD040B-133E-57CF-80DD-9369F62709C6.dita"><linktext>Implement
       
   350 the PSL for the target</linktext></link>
       
   351 <link href="GUID-E7F91A65-235D-589C-9A8C-0B207D19A24B.dita"><linktext>Port the
       
   352 client drivers to use the PRM</linktext></link>
       
   353 <link href="GUID-C8DF0CB0-92F4-5F9E-A8F1-7DE50954C4F1.dita"><linktext>Debugging
       
   354 the PRM</linktext></link>
       
   355 <link href="GUID-66E5F769-1156-54CA-94BC-8912159A1240.dita"><linktext>Testing the
       
   356 PRM PSL</linktext></link>
       
   357 </related-links></concept>