|
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(">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->iMinLevel = iMinLevel; |
|
72 buf1->iMaxLevel = iMaxLevel; |
|
73 __KTRACE_OPT(KRESMANAGER, Kern::Printf("<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& 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 & 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& 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(&iSemaphore,NULL); |
|
163 iSemaphore.iCount = 0; |
|
164 |
|
165 // This will be signalled in Menelaus access functions callback below |
|
166 NKern::FSWait(&(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())) & 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<DH4MmcPowerResource*>(aPtr); |
|
200 ptr->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(&(ptr->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 &req); |
|
229 TInt GetInfo(TDes8* aInfo) const; |
|
230 TChangePropagationStatus TranslateDependentState(TInt aDepId, TInt aDepState, TInt& 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 &req); |
|
249 TInt GetInfo(TDes8* aInfo) const; |
|
250 TChangePropagationStatus TranslateDependentState(TInt aDepId, TInt aDepState, TInt& 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& aResState) |
|
281 { |
|
282 /* Switch ON if the dependent resource is ON */ |
|
283 if((aDepState == 1) && (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) && (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& /*aClientId*/, |
|
317 TUint /*aResourceId*/, |
|
318 TInt& /*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> |