|
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->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**& aStaticResourceArray, TUint16& 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(">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,&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("<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**& aStaticResourceArray, TUint16& aStaticResourceCount) |
|
93 { |
|
94 aStaticResourceCount = 0; |
|
95 __KTRACE_OPT(KRESMANAGER, Kern::Printf(">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("<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 <---------> ResourceD <-------> ResourceE <--------> ResourceC |
|
169 | | |
|
170 | | |
|
171 | | |
|
172 ResourceF ResourceG |
|
173 */ |
|
174 TInt DSimulatedPowerResourceController::DoRegisterStaticResourcesDependency(DStaticPowerResourceD**& aStaticResourceDArray, TUint16& 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 = &iNodeArray[iNodeCount++]; |
|
234 pN2 = &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 = &iNodeArray[iNodeCount++]; |
|
239 pN2 = &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 = &iNodeArray[iNodeCount++]; |
|
244 pN2 = &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 = &iNodeArray[iNodeCount++]; |
|
249 pN2 = &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 = &iNodeArray[iNodeCount++]; |
|
254 pN2 = &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->iPriority = priRes1; \ |
|
262 pN1->iResource = pRes1; \ |
|
263 pN1->iPropagatedLevel = 0; \ |
|
264 pN1->iVisited = EFalse; \ |
|
265 pN2->iPriority = priRes2; \ |
|
266 pN2->iResource = pRes2; \ |
|
267 pN2->iPropagatedLevel = 0; \ |
|
268 pN2->iVisited = EFalse; \ |
|
269 pN1->iResource->AddNode(pN2); \ |
|
270 pN2->iResource->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> |