Adaptation/GUID-66FD040B-133E-57CF-80DD-9369F62709C6.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-66FD040B-133E-57CF-80DD-9369F62709C6" xml:lang="en"><title>Implement
       
    13 the PSL for the target</title><shortdesc>This document describes how to implement the Platform Specific
       
    14 Layer for the Power Resource Manager.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    15 <section id="GUID-AA174659-DAC6-47C2-A308-63C72E4C4C29"><title>Purpose</title> <p>The PSL must be implemented in order for
       
    16 the PRM and the hardware to be able to communicate. </p> <p><b>Introduction</b> </p> <p>The
       
    17 PSL side of the Resource Controller should be derived from the class <xref href="GUID-46F2174F-0206-345B-8C5D-F8B5763652E0.dita"><apiname>DPowerResourceController</apiname></xref>. </p> </section>
       
    18 <section id="GUID-E744193B-0A9F-4E43-905A-E62414D75816"><title> Implementing the PSL </title> <p>The following tasks are
       
    19 covered in this tutorial: </p> <ul>
       
    20 <li id="GUID-2D247D75-FAB8-5ACA-895F-9F5EE58E70F6"><p> <xref href="GUID-66FD040B-133E-57CF-80DD-9369F62709C6.dita#GUID-66FD040B-133E-57CF-80DD-9369F62709C6/GUID-2919DA2A-22EF-5DA7-8B90-EC70BFEAC04A">Create an entry point</xref>, </p> </li>
       
    21 <li id="GUID-920C5334-D4A2-53E6-9381-F00F31EFE3E4"><p> <xref href="GUID-66FD040B-133E-57CF-80DD-9369F62709C6.dita#GUID-66FD040B-133E-57CF-80DD-9369F62709C6/GUID-E1119981-C3E9-5EED-90FA-5196A60A8E57">Override the pure virtual functions</xref>, </p> </li>
       
    22 <li id="GUID-DD00864E-83A8-5D39-9A74-257A980B97A1"><p> <xref href="GUID-66FD040B-133E-57CF-80DD-9369F62709C6.dita#GUID-66FD040B-133E-57CF-80DD-9369F62709C6/GUID-9E18F595-D826-5244-89CC-A76871120287">Create static resources that support dependencies</xref>, </p> </li>
       
    23 <li id="GUID-E3745946-B84D-556D-8A1C-62D32F117EEB"><p> <xref href="GUID-66FD040B-133E-57CF-80DD-9369F62709C6.dita#GUID-66FD040B-133E-57CF-80DD-9369F62709C6/GUID-252E7413-D8A9-575C-858F-E4F4E238A7B0">Initialise the pools</xref>, </p> </li>
       
    24 <li id="GUID-15313D5D-5CEB-52A7-A8BA-7C6BC0EF5973"><p> <xref href="GUID-66FD040B-133E-57CF-80DD-9369F62709C6.dita#GUID-66FD040B-133E-57CF-80DD-9369F62709C6/GUID-08BFCAF4-9AF0-5999-A1C4-7BBD107C9354">Registering with the Power Controller</xref>. </p> </li>
       
    25 </ul> <p id="GUID-2919DA2A-22EF-5DA7-8B90-EC70BFEAC04A"><b>Create an entry
       
    26 Point</b> </p> <p>The PIL layer of the PRM offers the following macro. This
       
    27 needs to be invoked from the PSL. The macro calls the <xref href="GUID-C0788D78-2700-3094-BDE2-F1ABC93CE433.dita"><apiname>DoInitController()</apiname></xref> and <xref href="GUID-616D2132-0676-3CAD-9FF4-41CE147E8DF0.dita"><apiname>DoInitResources()</apiname></xref> functions
       
    28 implemented by the PSL. </p> <codeblock id="GUID-3040AB12-1884-5967-AEA6-27B1162172D8" xml:space="preserve">/**
       
    29 Extension entry point
       
    30 */
       
    31 DECLARE_RESOURCE_MANAGER_EXTENSION()
       
    32     {
       
    33     __KTRACE_OPT(KBOOT, Kern::Printf("CreateController called"));
       
    34     return new DH4PowerResourceController;
       
    35     }</codeblock> <p>If the PRM is a <keyword>PDD</keyword> the entry point
       
    36 is as follows: </p> <codeblock id="GUID-DE03EEAB-BC7E-57F4-9E28-A16028A86F24" xml:space="preserve">static DH4PowerResourceController TheController;
       
    37 DECLARE_STANDARD_PDD()
       
    38     {
       
    39     TInt r = DPowerResourceController::InitController();     
       
    40     if® == KErrNone)
       
    41         r = TheController-&gt;InitResources();
       
    42     if® == KErrNone)
       
    43         return new DResConPddFactory;
       
    44     return NULL;                            
       
    45     }</codeblock> <p id="GUID-E1119981-C3E9-5EED-90FA-5196A60A8E57"><b>Override
       
    46 the pure virtual functions</b> </p> <p>Override the virtual functions of the <xref href="GUID-46F2174F-0206-345B-8C5D-F8B5763652E0.dita"><apiname>DPowerResourceController</apiname></xref> base
       
    47 class: </p> <ul>
       
    48 <li id="GUID-F81D44B9-97A4-52D1-859D-80E11CC86B86"><p> <xref href="GUID-66FD040B-133E-57CF-80DD-9369F62709C6.dita#GUID-66FD040B-133E-57CF-80DD-9369F62709C6/GUID-67C338A7-E163-5253-B495-B9E081340F1A">DoInitController()</xref>, </p> </li>
       
    49 <li id="GUID-6D167188-8750-5E2C-952B-E61D18400298"><p> <xref href="GUID-66FD040B-133E-57CF-80DD-9369F62709C6.dita#GUID-66FD040B-133E-57CF-80DD-9369F62709C6/GUID-61471315-14E1-5A0F-A164-92CF928C3604">DoRegisterStaticResources()</xref>. </p> </li>
       
    50 </ul> <p>Here is an example H4 HRP implementation: </p> <codeblock id="GUID-90F8FCCA-8A95-50D8-AF16-9CA974E04CDE" xml:space="preserve">class DH4PowerResourceController : DPowerResourceController
       
    51    {
       
    52 public:
       
    53    DH4PowerResourceController();
       
    54    TInt DoInitController();
       
    55    TInt DoRegisterStaticResources(DStaticPowerResource**&amp; aStaticResourceArray, TUint16&amp; aStaticResourceCount);
       
    56 private:
       
    57    static DStaticPowerResource* iResources[];</codeblock> <p id="GUID-67C338A7-E163-5253-B495-B9E081340F1A"><b>DoInitController()</b> </p> <p>Override <xref href="GUID-46F2174F-0206-345B-8C5D-F8B5763652E0.dita#GUID-46F2174F-0206-345B-8C5D-F8B5763652E0/GUID-58713E4F-DB41-3DD9-B180-ECA5DAA830D4"><apiname>DPowerResourceController::DoInitController()</apiname></xref> so that it creates
       
    58 a DFC queue and then invokes the base class function <xref href="GUID-46F2174F-0206-345B-8C5D-F8B5763652E0.dita#GUID-46F2174F-0206-345B-8C5D-F8B5763652E0/GUID-A3E9F7E9-885E-37CB-9077-CBC686B46E15"><apiname>DPowerResourceController::SetDfcQ()</apiname></xref>. <codeph>DoInitController()</codeph> should
       
    59 also initialise the pools by invoking <xref href="GUID-46F2174F-0206-345B-8C5D-F8B5763652E0.dita#GUID-46F2174F-0206-345B-8C5D-F8B5763652E0/GUID-0CAA5314-F418-31F8-863E-0082C5A617A5"><apiname>DPowerResourceController::InitPools()</apiname></xref> passing
       
    60 the platform defined sizes for the pools of clients, <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 <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-E8F3AF8E-387C-5285-A2B2-0B067F01BC3A">request
       
    61 objects</xref>. <xref href="GUID-C0788D78-2700-3094-BDE2-F1ABC93CE433.dita"><apiname>DoInitController()</apiname></xref> is called by the PSL
       
    62 during its initialisation. Below is the reference implementation code. </p> <codeblock id="GUID-06466787-59E3-5C0F-9E14-2144BEF3CBBB" xml:space="preserve">#define KERNEL_CLIENTS 0x2 // Expected number of kernel clients (MMC and Sound_SC)
       
    63 #define USER_CLIENTS   0x0 // No user side clients expected.
       
    64 #define CLIENT_LEVELS  0x8 // Expected resource state change of 8 resources 
       
    65 #define REQUESTS       0x0 // No asynchronous operation (state change or read) expected. 
       
    66 
       
    67 TInt DH4PowerResourceController::DoInitController()
       
    68     {
       
    69     // Create a DFC queue and then invoke SetDfcQ()
       
    70 __KTRACE_OPT(KRESMANAGER, Kern::Printf("&gt;DH4PowerResourceController::DoInitController\n"));
       
    71 
       
    72     // NKern::ThreadEnterCS(); // Not needed, as this is executed during kernel boot which is done within a critical section.
       
    73     TInt r = Kern::DfcQCreate(iDfcQ,28,&amp;KResThreadName);
       
    74 
       
    75     // NKern::ThreadLeaveCS();
       
    76     if (KErrNone!=r) return r;
       
    77     SetDfcQ(iDfcQ);
       
    78     r = InitPools(KERNEL_CLIENTS,USER_CLIENTS,CLIENT_LEVELS,REQUESTS);
       
    79 __KTRACE_OPT(KRESMANAGER, Kern::Printf("&lt;DH4PowerResourceController::DoInitController\n"));
       
    80     return r;
       
    81     }</codeblock> <p id="GUID-61471315-14E1-5A0F-A164-92CF928C3604"><b> DoRegisterStaticResources()</b> </p> <p> <codeph>DoRegisterStaticResources()</codeph> is called by the PIL during its initialisation. Override the pure virtual
       
    82 function <xref href="GUID-46F2174F-0206-345B-8C5D-F8B5763652E0.dita#GUID-46F2174F-0206-345B-8C5D-F8B5763652E0/GUID-E76A1967-CED5-341C-9B29-015C8AD2B54D"><apiname>DPowerResourceController::DoRegisterStaticResources()</apiname></xref> so
       
    83 that it: </p> <ul>
       
    84 <li id="GUID-274C20C9-C8C1-5E04-916C-32D8AEA06F66"><p>creates all the static
       
    85 resources in the kernel heap, </p> </li>
       
    86 <li id="GUID-FDD08EF6-78E4-5583-987B-E27D6B160554"><p>creates an array of
       
    87 pointers to the static resources (indexed by their id), </p> </li>
       
    88 <li id="GUID-F85D8EA4-44CF-577A-A423-6A60A5C55DDD"><p>sets the passed pointer
       
    89 (<codeph>aStaticResourceArray</codeph>) to point to the created array of pointers, </p> </li>
       
    90 <li id="GUID-A129EA68-9942-54CF-85A5-C5F9507B1447"><p>updates the count of
       
    91 the static resources (in <codeph>aStaticResourceCount</codeph>). </p> </li>
       
    92 </ul> <p>The reference implementation is below: </p> <codeblock id="GUID-81F2F9EB-A42E-5FBF-BDB2-091AA2C56096" xml:space="preserve">TInt DH4PowerResourceController::DoRegisterStaticResources(DStaticPowerResource**&amp; aStaticResourceArray, TUint16&amp; aStaticResourceCount)
       
    93     {
       
    94     aStaticResourceCount = 0;
       
    95    __KTRACE_OPT(KRESMANAGER, Kern::Printf("&gt;DH4PowerResourceController::DoRegisterStaticResources\n"));
       
    96    aStaticResourceArray = (DStaticPowerResource**) new (DStaticPowerResource*[EH4ResourceCount]);
       
    97    if(!aStaticResourceArray)
       
    98       return KErrNoMemory;
       
    99 
       
   100    DH4MmcFclkResource *pMmcFclk = new (DH4MmcFclkResource);
       
   101    if (!pMmcFclk) 
       
   102       return KErrNoMemory;
       
   103    aStaticResourceArray[EMmcFclkRes] = pMmcFclk;
       
   104 
       
   105    DH4MmcIclkResource *pMmcIclk = new (DH4MmcIclkResource);
       
   106    if (!pMmcIclk)
       
   107       CLEAN_AND_RETURN(KErrNoMemory, EMmcIclkRes)
       
   108    aStaticResourceArray[EMmcIclkRes] = pMmcIclk;
       
   109 
       
   110    DH4MmcClkResource *pMmcBusClk = new (DH4MmcClkResource);
       
   111    if (!pMmcBusClk)
       
   112       CLEAN_AND_RETURN(KErrNoMemory, EMmcClkRes)
       
   113    aStaticResourceArray[EMmcClkRes] = pMmcBusClk;
       
   114 
       
   115    DH4MmcCtrllerPwrResource *pMmcCtrlrPwr = new (DH4MmcCtrllerPwrResource);
       
   116    if (!pMmcCtrlrPwr)
       
   117       CLEAN_AND_RETURN(KErrNoMemory, EMmcCtrlrPwrRes)
       
   118    aStaticResourceArray[EMmcCtrlrPwrRes] = pMmcCtrlrPwr;
       
   119     
       
   120    DH4MmcPowerResource *pMmcPwr = new (DH4MmcPowerResource);
       
   121    if (!pMmcPwr)
       
   122       CLEAN_AND_RETURN(KErrNoMemory, EMmcPwrRes)
       
   123    aStaticResourceArray[EMmcPwrRes] = pMmcPwr;
       
   124     
       
   125    DH4SndFclkResource *pSndFclk = new (DH4SndFclkResource);
       
   126    if (!pSndFclk)
       
   127       CLEAN_AND_RETURN(KErrNoMemory, ESndFclkRes)
       
   128    aStaticResourceArray[ESndFclkRes] = pSndFclk;
       
   129 
       
   130    DH4SndIclkResource *pSndIclk = new (DH4SndIclkResource);
       
   131    if (!pSndIclk)
       
   132       CLEAN_AND_RETURN(KErrNoMemory ,ESndIclkRes)
       
   133    aStaticResourceArray[ESndIclkRes] = pSndIclk;
       
   134 
       
   135    DH4SndMClkResource *pSndMclk = new (DH4SndMClkResource);
       
   136    if (!pSndMclk)
       
   137       CLEAN_AND_RETURN(KErrNoMemory, ESndMClkRes)
       
   138    aStaticResourceArray[ESndMClkRes] = pSndMclk;
       
   139 
       
   140    aStaticResourceCount = EH4ResourceCount;
       
   141 
       
   142    __KTRACE_OPT(KRESMANAGER, Kern::Printf("&lt;DH4PowerResourceController::DoRegisterStaticResources, Total resources:%d\n", EH4ResourceCount));
       
   143 
       
   144    return KErrNone;
       
   145    }</codeblock> <p id="GUID-9E18F595-D826-5244-89CC-A76871120287"><b>Create
       
   146 static resources that support dependencies</b> </p> <p>If there are static
       
   147 resources that support dependencies then the PSL must implement the function <xref href="GUID-46F2174F-0206-345B-8C5D-F8B5763652E0.dita#GUID-46F2174F-0206-345B-8C5D-F8B5763652E0/GUID-933848C2-2589-3EBC-9765-6BD215F09E1C"><apiname>DPowerResourceController::DoRegisterStaticResourcesDependency()</apiname></xref>. <b>Note</b>: Static resources that support dependencies are only available
       
   148 in the extended version of the library. See <xref href="GUID-2ECF13A1-9D56-5740-A09F-8267E6A45DD9.dita#GUID-2ECF13A1-9D56-5740-A09F-8267E6A45DD9/GUID-0F328055-DBCE-5B2B-A1EB-77F73BA1FC82">setup
       
   149 and configuration</xref>. </p> <p>The function <codeph>DoRegisterStaticResourcesDependency()</codeph>: </p> <ul>
       
   150 <li id="GUID-8AA323AF-92D9-5217-8BC5-86E879F30475"><p>creates all static resources
       
   151 that support dependencies in kernel heap, </p> </li>
       
   152 <li id="GUID-904B8533-FA65-5958-88BF-307385D06BF6"><p>creates an array of
       
   153 pointers to them, </p> </li>
       
   154 <li id="GUID-ABC35D75-FA42-5627-A0B4-4F407AD08AC8"><p>establishes the dependencies
       
   155 between them (using the resource's <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),
       
   156 See <xref href="GUID-66FD040B-133E-57CF-80DD-9369F62709C6.dita#GUID-66FD040B-133E-57CF-80DD-9369F62709C6/GUID-A912A328-D646-5516-9731-FFA7F3B2EDDA">creating
       
   157 dependencies between static resources</xref> for a description of <codeph>AddNode()</codeph> and
       
   158 the <xref href="GUID-D44EF8E9-19EF-320A-8935-3E068C1097DB.dita"><apiname>SNode</apiname></xref> structure. </p> </li>
       
   159 <li id="GUID-B83ED866-7BB2-5227-A9B0-DE7CBFA92AA8"><p>sets the passed pointer
       
   160 (<codeph>aStaticResourceDArray</codeph>) to point to the array of pointers
       
   161 to static resource with dependency, </p> </li>
       
   162 <li id="GUID-62E7421E-9816-556F-ACF9-BEC02F9AF530"><p>updates the count of
       
   163 the static resource that supports dependency in <codeph>aStaticResourceDCount</codeph>. </p> </li>
       
   164 </ul> <p>This function is called by the PIL during PRM initialisation. Below
       
   165 is an example: </p> <codeblock id="GUID-2E044CAC-24E3-530F-8595-049D6512153F" xml:space="preserve">/** 
       
   166 This function creates all static resources that support dependencies and establishes the dependencies between them. This is called by the PIL.
       
   167 This is the dependency tree input:
       
   168    ResourceA &lt;---------&gt; ResourceD &lt;-------&gt; ResourceE &lt;--------&gt; ResourceC
       
   169                              |                   |
       
   170                              |                   |
       
   171                              |                   |
       
   172                          ResourceF           ResourceG       
       
   173 */
       
   174 TInt DSimulatedPowerResourceController::DoRegisterStaticResourcesDependency(DStaticPowerResourceD**&amp; aStaticResourceDArray, TUint16&amp; aStaticResourceDCount)
       
   175    {
       
   176    aStaticResourceDArray = (DStaticPowerResourceD**) new (DStaticPowerResourceD*[MAX_DEPENDENT_RESOURCE_COUNT]);
       
   177    if(!aStaticResourceDArray)
       
   178      return KErrNoMemory;
       
   179 
       
   180    DStaticPowerResourceD* pR = NULL;
       
   181 
       
   182    pR = new DMLSLGLSPDependResource();
       
   183    if(!pR)
       
   184      CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory)
       
   185    aStaticResourceDArray[iStaticResDependencyCount++] = pR;
       
   186 
       
   187    pR = new DMLSIGLSNDependResource();
       
   188    if(!pR)
       
   189      CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory)
       
   190    aStaticResourceDArray[iStaticResDependencyCount++] = pR;
       
   191     
       
   192    pR = new DBSIGLSPDependResource();
       
   193    if(!pR)
       
   194      CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory)
       
   195    aStaticResourceDArray[iStaticResDependencyCount++] = pR;
       
   196 
       
   197    pR = new DMLSHIGLSPDependResource();
       
   198    if(!pR)
       
   199      CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory)
       
   200    aStaticResourceDArray[iStaticResDependencyCount++] = pR;
       
   201 
       
   202    pR = new DBSHLGLSNDependResource();
       
   203    if(!pR)
       
   204      CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory)
       
   205    aStaticResourceDArray[iStaticResDependencyCount++] = pR;
       
   206 
       
   207    pR = new DMLSHLGLSNDependResource();
       
   208    if(!pR)
       
   209      CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory)
       
   210    aStaticResourceDArray[iStaticResDependencyCount++] = pR;
       
   211 
       
   212    // Establish resource dependencies
       
   213    if(CreateResourceDependency(aStaticResourceDArray))
       
   214      CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory)
       
   215 
       
   216    iDependencyResources = aStaticResourceDArray;
       
   217 
       
   218    aStaticResourceDCount = iStaticResDependencyCount;
       
   219    return KErrNone;
       
   220    }    
       
   221 
       
   222 // This function establishes above dependency between static dependent resource
       
   223 TInt DSimulatedPowerResourceController::CreateResourceDependency(DStaticPowerResourceD** pResArray)
       
   224    {
       
   225    iNodeArray = new SNode[10];
       
   226    SNode* pN1;
       
   227    SNode* pN2;
       
   228    iNodeCount = 0;
       
   229 
       
   230    if(!iNodeArray)
       
   231      return KErrNoMemory; 
       
   232    // Create Dependency between Resource A and Resource D 
       
   233    pN1 = &amp;iNodeArray[iNodeCount++];
       
   234    pN2 = &amp;iNodeArray[iNodeCount++];
       
   235    CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pResArray[0], pResArray[1], 1, 1)
       
   236 
       
   237    // Create Dependency between Resource D and Resource F
       
   238    pN1 = &amp;iNodeArray[iNodeCount++];
       
   239    pN2 = &amp;iNodeArray[iNodeCount++];
       
   240    CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pResArray[0], pResArray[2], 1, 3)
       
   241 
       
   242    // Create Dependency between Resource D and Resource E
       
   243    pN1 = &amp;iNodeArray[iNodeCount++];
       
   244    pN2 = &amp;iNodeArray[iNodeCount++];
       
   245    CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pResArray[0], pResArray[3], 3, 2)
       
   246 
       
   247    // Create Dependency between Resource E and Resource C
       
   248    pN1 = &amp;iNodeArray[iNodeCount++];
       
   249    pN2 = &amp;iNodeArray[iNodeCount++];
       
   250    CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pResArray[3], pResArray[4], 1, 1)
       
   251 
       
   252    // Create Dependency between Resource E and Resource G
       
   253    pN1 = &amp;iNodeArray[iNodeCount++];
       
   254    pN2 = &amp;iNodeArray[iNodeCount++];
       
   255    CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pResArray[3], pResArray[5], 1, 2)
       
   256 
       
   257    return KErrNone;
       
   258    }
       
   259 
       
   260 #define CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pRes1, pRes2, priRes1, priRes2)    \
       
   261         pN1-&gt;iPriority = priRes1;                                                 \
       
   262         pN1-&gt;iResource = pRes1;                                                   \
       
   263         pN1-&gt;iPropagatedLevel = 0;                                                \
       
   264         pN1-&gt;iVisited = EFalse;                                                   \
       
   265         pN2-&gt;iPriority = priRes2;                                                 \
       
   266         pN2-&gt;iResource = pRes2;                                                   \
       
   267         pN2-&gt;iPropagatedLevel = 0;                                                \
       
   268         pN2-&gt;iVisited = EFalse;                                                   \
       
   269         pN1-&gt;iResource-&gt;AddNode(pN2);                                             \
       
   270         pN2-&gt;iResource-&gt;AddNode(pN1);</codeblock> <p id="GUID-A912A328-D646-5516-9731-FFA7F3B2EDDA"><b>Creating
       
   271 dependencies between static resources</b> </p> <p> <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> is
       
   272 used to establish a dependency between static resources. Dependencies between
       
   273 static resources cannot be removed. </p> <p> <codeph>AddNode()</codeph> takes
       
   274 a pointer to an <xref href="GUID-D44EF8E9-19EF-320A-8935-3E068C1097DB.dita"><apiname>SNode</apiname></xref> object that contains the dependent
       
   275 resource information. This passed node pointed is added to the resource dependency
       
   276 list within the class <codeph>DStaticPowerResourceD</codeph>. <b>Note</b>:
       
   277 the kernel panics if the specified dependency priority is already in use. </p> <p>Information
       
   278 within <codeph>SNode</codeph> includes: </p> <ul>
       
   279 <li id="GUID-9A0E98EA-6510-5C71-B0AD-013E77BD94C0"><p> <codeph>iResource</codeph> is
       
   280 a pointer to dependent resource, </p> </li>
       
   281 <li id="GUID-0C62E787-DEA9-5A2A-BFA1-DFB7A30A6AE7"><p> <codeph>iPriority</codeph> is
       
   282 the priority of the dependency resource. This is used by the PRM when propagating
       
   283 the resource change, </p> </li>
       
   284 <li id="GUID-F1E5C122-E38D-5D0D-B1E6-6808DAF5631C"><p> <codeph>iSpare</codeph> is
       
   285 reserved for future use, </p> </li>
       
   286 <li id="GUID-DD0AA8A3-F301-5996-907E-F35BCD38840D"><p> <codeph>iNext</codeph> is
       
   287 a pointer to next node in the list. </p> </li>
       
   288 </ul> <p>The members <codeph>iPropagatedLevel</codeph>, <codeph>iRequiresChange</codeph> and <codeph>iVisited</codeph> are
       
   289 used internally by the PRM. </p> <p>To link to dynamic resources that support
       
   290 dependency use the PRM function <xref href="GUID-5EC9C7EB-3E69-3DAE-B777-C0952F949CF3.dita"><apiname>RegisterResourceDependency()</apiname></xref> as
       
   291 described in <xref href="GUID-B1CE51BC-B452-5FC9-9C00-35447AF40671.dita#GUID-B1CE51BC-B452-5FC9-9C00-35447AF40671/GUID-A5D57D89-4499-5C85-80D5-5A7DC5644983">creating
       
   292 resource dependencies</xref>. </p> <p id="GUID-252E7413-D8A9-575C-858F-E4F4E238A7B0"><b>Initialise
       
   293 the pools</b> </p> <p>Pools are implemented as singly linked lists during
       
   294 the initialisation of the PRM. The PSL initialises the pools by invoking <xref href="GUID-46F2174F-0206-345B-8C5D-F8B5763652E0.dita#GUID-46F2174F-0206-345B-8C5D-F8B5763652E0/GUID-0CAA5314-F418-31F8-863E-0082C5A617A5"><apiname>DPowerResourceController::InitPools()</apiname></xref> and
       
   295 passing the platform defined sizes for the pools of kernel side clients, user
       
   296 side clients, client levels and requests. See the <xref href="GUID-66FD040B-133E-57CF-80DD-9369F62709C6.dita#GUID-66FD040B-133E-57CF-80DD-9369F62709C6/GUID-67C338A7-E163-5253-B495-B9E081340F1A">example DoInitController() implementation</xref>. </p> <p>The PRM has three
       
   297 types of pools: </p> <ul>
       
   298 <li id="GUID-BB2EE131-0010-51BE-BD56-716D62D29E87"><p>client pools to store
       
   299 client information, </p> </li>
       
   300 <li id="GUID-C75A9188-7105-5F22-95AA-27B29E6A55FD"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-E8F3AF8E-387C-5285-A2B2-0B067F01BC3A">request pools</xref> to send requests for operation on long latency resource
       
   301 to the Resource Controller thread, </p> </li>
       
   302 <li id="GUID-7204C320-5150-5FF1-99C7-CD4868D106E1"><p> <xref href="GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita#GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE/GUID-F47D2098-16A7-5590-A68A-7AE4B2DAB462">client level</xref> pools to capture the resource level request by each client
       
   303 for a resource. </p> </li>
       
   304 </ul> <p>If the client pool is set to zero, then the PRM will not allow a
       
   305 client of that type to register. For example, if the kernel side clients pool
       
   306 is set to zero, then the PIL will not allow any kernel side clients to register.
       
   307 The size of the client pools to specify depends on how many kernel side device
       
   308 drivers (clients) and user side clients will access PRM and size of request
       
   309 pool depends on the number of long latency resource available in the system.
       
   310 Size of client level pool depends on number of clients that will request a
       
   311 resource state change. If the client pools are exhausted the PIL will try
       
   312 to increase the size of the pool. The size of the pool never decreases. </p> <p id="GUID-08BFCAF4-9AF0-5999-A1C4-7BBD107C9354"><b>Registering with the Power
       
   313 Controller</b> </p> <p>The Resource Controller must call <xref href="GUID-B3D1C422-6A82-3C6E-9123-1E4F598F0366.dita#GUID-B3D1C422-6A82-3C6E-9123-1E4F598F0366/GUID-42896B4D-9F77-3D91-82BD-50102A8F3DA4"><apiname>DPowerController::RegisterResourceController()</apiname></xref> to
       
   314 register itself with the Power Controller. <codeph>RegisterResourceController()</codeph> sets
       
   315 the <codeph>iResourceControllerData.iResourceController</codeph> data member
       
   316 within <xref href="GUID-B3D1C422-6A82-3C6E-9123-1E4F598F0366.dita"><apiname>DPowerController</apiname></xref> to the passed Resource Controller
       
   317 pointer and sets <codeph>iResouceControllerData.iClientId</codeph> to the
       
   318 client ID used by the Power Controller when calling the Resource Controller's
       
   319 APIs. </p> <p>The platform specific implementation of the Power Controller
       
   320 overrides the <codeph>RegisterResourceController()</codeph> function. See <xref href="GUID-34D1D0BF-20DE-5677-A067-8FF9DD72E703.dita#GUID-34D1D0BF-20DE-5677-A067-8FF9DD72E703/GUID-DCD91EBA-CB0E-5EA9-84E0-8F8FED6FC91E">DPowerController::RegisterResourceController()</xref>. </p> <p><b> Idle power management</b> </p> <p>The resource controller's APIs
       
   321 cannot be called from a NULL thread. However, the PSL may need to know the
       
   322 state of the resources from a NULL thread to take the system to appropriate
       
   323 power states. To allow access to this information the PRM provides the virtual
       
   324 function <xref href="GUID-46F2174F-0206-345B-8C5D-F8B5763652E0.dita#GUID-46F2174F-0206-345B-8C5D-F8B5763652E0/GUID-52DC308A-9DF1-3BDE-A905-A4DD3B692638"><apiname>DPowerResourceController::RegisterResourcesForIdle()</apiname></xref>. </p> </section>
       
   325 </conbody><related-links>
       
   326 <link href="GUID-2ECF13A1-9D56-5740-A09F-8267E6A45DD9.dita"><linktext>Porting the
       
   327 Power Resource Manager</linktext></link>
       
   328 <link href="GUID-B1CE51BC-B452-5FC9-9C00-35447AF40671.dita"><linktext>Implement
       
   329 the  controllable power resources</linktext></link>
       
   330 <link href="GUID-E7F91A65-235D-589C-9A8C-0B207D19A24B.dita"><linktext>Port client
       
   331 drivers to use the PRM</linktext></link>
       
   332 <link href="GUID-C8DF0CB0-92F4-5F9E-A8F1-7DE50954C4F1.dita"><linktext>Debugging
       
   333 the PRM</linktext></link>
       
   334 <link href="GUID-66E5F769-1156-54CA-94BC-8912159A1240.dita"><linktext>Testing the
       
   335 PRM PSL</linktext></link>
       
   336 </related-links></concept>